# Ticket 0.1 — Initialise Node.js/TypeScript Project

**Phase**: 0 — Project Scaffolding
**Priority**: Critical (blocking)
**Depends on**: None

## Description

Set up the Node.js/TypeScript project with `package.json`, `tsconfig.json`, entry point, dependencies, and ignore files. This is the foundation everything else builds on. The project uses TypeScript throughout (server-side and frontend).

## Acceptance Criteria

### AC1: Package manifest exists and is valid

```gherkin
Given the project root directory
When I run `pnpm pack --dry-run`
Then it succeeds without errors
And package.json contains name "conduit"
And package.json contains a "bin" entry pointing to "dist/bin/cli.js"
And package.json has "type" set to "module"
And package.json has a "packageManager" field specifying pnpm (e.g., "pnpm@10.x.x")
And license is "MIT"
```

### AC2: Core dependencies are declared

```gherkin
Given package.json exists
When I inspect the dependencies
Then it includes "ws" (WebSocket server)
And it includes "web-push" (push notifications)
And it includes "qrcode-terminal" (QR code display)
Note: @lydell/node-pty is NOT needed — OpenCode exposes PTY via its own API
      (GET /pty/:id/connect WebSocket). The relay proxies this instead.

When I inspect the devDependencies
Then it includes "@typescript/native-preview" (TypeScript 7 — native Go compiler for ~10x faster type checking)
And it includes "typescript" (fallback compiler)
And it includes "vite" (frontend bundler with HMR dev server)
And it includes "@biomejs/biome" (unified linter + formatter)
And it includes "vitest" (test framework)
And it includes "playwright" (E2E browser testing)
And it includes "tsx" (TypeScript execution for development)
```

### AC3: TypeScript configuration exists

```gherkin
Given tsconfig.json exists
When I inspect its contents
Then it targets ES2022 or later
And it enables strict mode
And it sets module to "NodeNext" or "ESNext"
And it sets outDir to "dist/"
And it includes "src/**/*.ts"

Given tsconfig.json is used for type checking
When I run `npx tsgo --noEmit` (TypeScript 7 native compiler)
Then it type-checks the project with ~10x faster performance
And fallback `npx tsc --noEmit` also works
Note: tsgo reads the same tsconfig.json — no separate config needed.
```

### AC3b: Biome configuration exists

```gherkin
Given biome.json exists in the project root
When I inspect its contents
Then it configures the linter with recommended rules
And it configures the formatter (indent: 2 spaces, line width: 100)
And it includes "src/**/*.ts" in the scope
And it excludes "dist/", "node_modules/"
```

### AC4: Entry point is executable

```gherkin
Given src/bin/cli.ts exists (source)
When it is compiled to dist/bin/cli.js
Then the compiled output contains a Node.js shebang (#!/usr/bin/env node)
And the file has executable permissions
```

### AC5: Ignore files exclude sensitive/generated content

```gherkin
Given .gitignore exists
When I inspect its contents
Then it excludes node_modules/
And it excludes dist/ (compiled output)
And it excludes .env
And it excludes .conduit/ (local session data)
And it excludes *.pem (TLS certificates)
And it excludes .DS_Store
```

## Testable Components

| Component | Test Type | What to Assert |
|-----------|-----------|----------------|
| `package.json` | Unit | Required fields present, valid semver, correct bin path, `packageManager` field |
| `tsconfig.json` | Unit | Strict mode, correct target and module settings |
| `biome.json` | Unit | Linter and formatter rules configured correctly |
| `src/bin/cli.ts` | Unit | Compiles without errors |
| `.gitignore` | Unit | Required patterns present (including dist/) |
| `pnpm install` | Fixture | All dependencies resolve without errors |
| `tsgo --noEmit` | Fixture | TypeScript 7 native compiler type-checks cleanly |
| `tsc --noEmit` | Fixture | TypeScript fallback compiler also passes |
| `biome check` | Fixture | Linting and formatting pass with no errors |

## Files to Create

- `package.json` (with `"packageManager": "pnpm@10.x.x"`)
- `tsconfig.json` (consumed by both `tsgo` and `tsc`)
- `biome.json` (Biome linter + formatter config)
- `src/bin/cli.ts` (stub)
- `.gitignore`
- `.npmrc` (optional, for registry config)
- `.opencode-version` (pinned OpenCode git commit hash or release tag — see ticket 1.0)

## Notes

- **pnpm** via corepack — run `corepack enable` before `pnpm install`. The `packageManager` field in `package.json` pins the exact pnpm version for reproducible installs.
- **TypeScript 7** (Project Corsa) — uses the native Go-based compiler `tsgo` via `@typescript/native-preview` for ~10x faster type checking. Reads standard `tsconfig.json`. Traditional `tsc` remains available as fallback. See [TypeScript 7 blog post](https://devblogs.microsoft.com/typescript/progress-on-typescript-7-december-2025/).
- **Biome** — unified linter and formatter (replaces ESLint + Prettier). Single `biome.json` config file. Extremely fast (Rust-based).
- **TypeScript** throughout — server-side and frontend code are all `.ts` files
- Use ES modules (`"type": "module"`) to match claude-relay's approach
- Node.js 18+ minimum (for native fetch, structuredClone, etc.)
- Use `tsx` for development (fast TypeScript execution without pre-compilation)
- Consider adding `engines` field to package.json

### TypeScript 7 Risk Mitigation

`tsgo` (`@typescript/native-preview`) is bleeding edge (announced December 2025). It may have bugs, missing features, or breaking changes between preview versions. To mitigate:

- **`tsc` is the CI gatekeeper** — CI always type-checks with `tsc --noEmit` (the authoritative compiler). This ensures correctness.
- **`tsgo` is the local speed tool** — developers use `tsgo --noEmit` for fast local feedback (~10x faster), but it does not gate CI.
- If `tsgo` produces false positives or rejects valid TypeScript, **fall back to `tsc` immediately**. Do not work around `tsgo` bugs in application code.

### OpenCode Version Pinning

The relay is built against OpenCode's API, which is under active development. To prevent silent breakage:

- Create a `.opencode-version` file in the project root containing the pinned OpenCode git commit hash or release tag.
- All contract tests (ticket 1.0) run against this pinned version.
- OpenCode upgrades should be **deliberate**: bump the pin, run contract tests, fix any breakage.

### Scripts

**Scripts** to add to `package.json`:
  - `"dev"`: `tsx watch src/bin/cli.ts` — dev server with auto-reload
  - `"build"`: `tsc` — compile TypeScript to JS
  - `"check"`: `tsc --noEmit` — authoritative type checking (used in CI)
  - `"check:fast"`: `tsgo --noEmit` — fast local type checking with TS7 (~10x faster)
  - `"lint"`: `biome check .` — lint + format check
  - `"lint:fix"`: `biome check --write .` — auto-fix lint + format issues
  - `"test"`: `vitest` — run unit/fixture tests
  - `"test:e2e"`: `playwright test` — run E2E browser tests
  - `"test:contract"`: `vitest --project contract` — run API contract tests (requires running OpenCode server)
