Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
32 changes: 32 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI

on:
pull_request:
push:
branches: [main]

jobs:
verify:
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout repository
uses: actions/checkout@v4
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
persist-credentials: false

- name: Enable Corepack
run: corepack enable

- name: Setup Node.js 24
uses: actions/setup-node@v4
with:
node-version: 24
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run verification gate
run: pnpm verify
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
node_modules/
dist/
coverage/
*.log
.DS_Store
*.tmp
package-lock.json
*.tsbuildinfo
.idea/
.superpowers/
.vscode/
Thumbs.db
Desktop.ini
*.swp
*.swo
*.bak
*.orig
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
dist/
coverage/
pnpm-lock.yaml
.superpowers/

7 changes: 7 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2
}
118 changes: 118 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Relay

Local task sidecar for human–AI workflows.

> **Status:** Scaffold stage (Issue #1). Task tracking, companion skills, vendor integration configs, and packaging are explicitly deferred to subsequent issues (Issue #2+).

## Prerequisites

- Node.js `24.x` LTS (`.nvmrc`)
- Supported release line as of `2026-07-25`: Node `24.x` (`26.x` is Current, `25.x` is EOL)
- pnpm `10.2.0` (managed via Corepack)

## Setup

```bash
corepack enable
nvm use
pnpm install --frozen-lockfile
```

If you use `fnm`, `asdf`, or another version manager, switch to Node `24` before running install or verification.

## Available Scripts

- `pnpm verify` — **Non-mutating** aggregate quality gate. Executes `format:check -> lint -> typecheck -> test:coverage -> build -> validate:assets -> audit --audit-level high`.
- `pnpm format` — **Mutating**. Format codebase with Prettier.
- `pnpm format:check` — **Non-mutating**. Check formatting with Prettier.
- `pnpm lint` — **Non-mutating**. Run ESLint (`--max-warnings=0`).
- `pnpm typecheck` — **Non-mutating**. Perform strict TypeScript type checking (`tsc --build --noEmit`).
- `pnpm test` — **Non-mutating**. Run Vitest unit & integration tests once.
- `pnpm test:coverage` — **Non-mutating**. Run Vitest tests with V8 coverage threshold enforcement.
- `pnpm build:node` — **Mutating (dist/)**. Build Node backend entry points (`dist/mcp/main.js`, `dist/http/main.js`).
- `pnpm build:web` — **Mutating (dist/)**. Build Vite React web UI (`dist/web`).
- `pnpm build` — **Mutating (dist/)**. Run `build:node` and `build:web`.
- `pnpm dev:mcp` — **Non-mutating**. Run MCP stdio entry point from source via `tsx`.
- `pnpm dev:http` — **Non-mutating**. Run HTTP server from source (`http://127.0.0.1:43110`).
- `pnpm dev:web` — **Non-mutating**. Run Vite development server with proxy `/api` -> `http://127.0.0.1:43110`.
- `pnpm dev:ui` — **Non-mutating**. Run HTTP server and Vite development server concurrently.
- `pnpm validate:assets` — **Non-mutating**. Validate repository assets, package `bin`, and configuration.

## Development Servers & Ports

- Default HTTP loopback address: `127.0.0.1`
- Default HTTP port: `43110` (`GET /api/health`)
- Vite dev server port: `5173` (proxies `/api` to `http://127.0.0.1:43110`)

## Configuration & Environment Variables

- `RELAY_DB_PATH`: Custom file path to SQLite database.
- Windows default: `%APPDATA%\relay\relay.db`
- macOS default: `~/Library/Application Support/relay/relay.db`
- Linux default: `${XDG_DATA_HOME:-~/.local/share}/relay/relay.db`
- `RELAY_HTTP_PORT`: Custom port for loopback HTTP server (default: `43110`).

## Database & Migrations

Relay uses `better-sqlite3` with plain SQL migrations located under `src/database/migrations/`.

On every database connection:

- `PRAGMA foreign_keys = ON;`
- `PRAGMA journal_mode = WAL;`
- `PRAGMA busy_timeout = 5000;`

Applied SQL migrations are tracked in `_relay_migrations` with SHA-256 checksums. **Applied migration SQL files are immutable**.

## Invoking Built MCP Command Locally

Build the scaffold Node entry points:

```bash
pnpm build
```

Start the MCP stdio process:

```bash
node dist/mcp/main.js
```

Or invoke via package binary entry point:

```bash
./dist/mcp/main.js
```

The process exposes one scaffold health tool: `relay_health`. Diagnostics are written exclusively to `stderr`.

## Architecture Boundaries

```text
src/
domain/ # Domain entities & rules (deferred to Issue #2+)
application/ # Application services (getHealth)
database/ # SQLite connection factory & migration runner
interfaces/
mcp/ # MCP stdio server adapter (relay_health)
http/ # Loopback HTTP server adapter (GET /api/health)
shared/ # Custom errors & package metadata
web/ # Vite React 19 UI shell
```

Boundary rules:

- `domain` and `application` layers have zero dependencies on interface protocols (`mcp`, `http`) or database implementations.
- `interfaces` call application services (`getHealth()`) and do not construct domain responses independently.
- `web/` calls loopback HTTP `/api/health` only and never imports Node modules.

## Current Limitations

- No task CRUD, task table, or product task behavior (deferred to Issue #2+).
- No companion skills, plugin manifests, or vendor MCP configs (deferred to Issue #2+).
- No remote network binding, authentication, multi-user accounts, background daemon, or desktop shell.

## Troubleshooting

- **`better-sqlite3` build issues:** Ensure Python and a C++ compiler build toolchain are installed if prebuilt binaries are unavailable.
- **Node version mismatch:** Relay supports Node.js `24.x` only. If your shell is on Node `25.x` or `26.x`, switch to Node `24` with `nvm use`, `fnm use 24`, or the equivalent command for your version manager before running `pnpm install` or `pnpm verify`.
2 changes: 1 addition & 1 deletion docs/decisions/0001-product-and-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,4 @@ TypeScript and Node.js were selected over Java because this product prioritizes

Java could provide stronger runtime performance and structure, but those advantages are not material for a low-throughput local task queue. A conventional Java framework would add idle memory, startup, and packaging costs without corresponding product value.

The architecture remains intentionally evolutionary: SQLite and the application layer are authoritative, while MCP, CLI, and UI remain replaceable interfaces.
The architecture remains intentionally evolutionary: SQLite and the application layer are authoritative, while MCP, CLI, and UI remain replaceable interfaces.
Loading
Loading