Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

## Project Snapshot

Throughline is a PR comprehension system: a desktop app that turns a large pull request into an ordered journey of clusters a reviewer can walk to the end. The app code is currently the Effect v4 starter it is being built into: an Electron shell supervising a local Effect server (HTTP + WebSocket RPC), with one React web build that runs in the shell and in a plain browser.
Throughline is a PR comprehension system: a desktop app that turns a large pull request into an ordered journey of clusters a reviewer can walk to the end. It is built and works end to end, on the shape the Effect v4 starter established: an Electron shell supervising a local Effect server (HTTP + WebSocket RPC), with one React web build that runs in the shell and in a plain browser.

The product on top of that shape: pull requests are read through the `gh` CLI, cloned into a per-run worktree, decomposed by a local coding-agent harness (Codex or Claude Code, read-only), validated against a coverage guarantee, and persisted as an immutable journey artifact the reviewer walks cluster by cluster. Nothing is written to GitHub and no token is ever stored.

## Documentation — read before designing or building anything

Expand Down Expand Up @@ -40,12 +42,15 @@ Long term maintainability is a core priority. If you add new functionality, firs

Unit tests live in each package's `tests/` directory, mirroring the source tree: the test for `src/state/connection.ts` is `tests/state/connection.test.ts`. Never colocate `.test.ts` files under `src/`. When adding a package, include `tests/**` in its `tsconfig.json` or the tests silently stop typechecking (see `docs/adr/0007`).

Shared test scaffolding lives under `tests/support/`, which mirrors nothing because it is not a test — `apps/server/tests/support/config.ts` builds the wide `ServerConfig` record that every server test needs. Reach for it rather than assembling a config inline: a copy per file means each new config field breaks every test file, and copies drift until two tests disagree about what a server is.

## Package Roles

- `apps/desktop`: Electron shell. Spawns and supervises the local server, owns windows/menus/updates, and exposes a schema-validated IPC bridge to the renderer.
- `apps/server`: Effect HTTP + WebSocket RPC server. Serves the built web app, handles the bearer-auth exchange, and publishes lifecycle events.
- `apps/web`: React/Vite UI. Connects to the server over WebSocket RPC; the same build runs in the shell and in a plain browser.
- `packages/contracts`: effect/Schema contracts for the WS RPC surface, the IPC bridge, and the auth/bootstrap types. Keep this package schema-only — no runtime logic.
- `packages/journey`: The domain, as pure functions over the contracts — diff parsing and hunk derivation, the coverage and partition validators, read progress, evidence-link extraction, and the plan-to-hunks materializer. No Effect services, no I/O, no React: it is the part of Throughline that can be reasoned about and tested without a server, and the coverage guarantee lives here rather than in the pipeline that calls it. Subpath exports only (`@app/journey/hunks`, `/coverage`, `/progress`, `/evidence`, `/plan`).
- `packages/shared`: Runtime utilities consumed by multiple apps. Explicit subpath exports (e.g. `@app/shared/Net`) — no barrel index.
- `packages/client-runtime`: Client transport: the connection supervisor and typed RPC client. Subpath exports only (`/connection`, `/rpc`, `/authorization`).
- `scripts`: Repo tooling — dev runner, desktop packaging, reference-repo sync.
Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,26 @@ Read them in that order; where they conflict, the vision wins.

- **[Effect](https://effect.website) v4 + Electron + React 19** — the app shell: a supervised local Effect server, typed RPC/IPC contracts, one web build that runs in the shell and the browser.
- **[`@pierre/diffs`](https://diffs.com) and [`@pierre/trees`](https://trees.software)** — the rendering foundations for every diff surface and file tree. Throughline's job is the journey, not reinventing diff viewers.
- **GitHub CLI (`gh`)** — authentication and PR access ride on your existing login.
- **GitHub CLI (`gh`)** — authentication and PR access ride on your existing login. No token is ever stored.
- **A coding agent you already pay for** — [Codex](https://developers.openai.com/codex/sdk/) or [Claude Code](https://docs.claude.com/en/api/agent-sdk/overview), run read-only against a local clone. Throughline brings no key of its own.

> **Status:** early. The documentation leads; the app code is still the starter scaffold Throughline will be built into.
> **Status:** the product is built and works end to end — pull requests are read from `gh`, analyzed by a local harness, and presented as a journey you can walk to the end. Analysis quality depends on the harness you have configured; with none available the app is still honest about it and every other surface still works.

## Development

Requires Node 24 and pnpm 11.
Requires Node 24 and pnpm 11, plus `gh` on your `PATH` and at least one of `codex` or `claude` if you want real analyses.

```bash
pnpm install
pnpm dev # server + web UI in your browser, with HMR
pnpm dev:desktop # the Electron shell
pnpm check # typecheck + lint + format
pnpm test # vitest across every package
pnpm dist:desktop # a signed, packaged app in release/dist
```

Everything the app writes — the SQLite database, cloned workspaces, materialized
diffs, logs and traces — lives in one directory: `<repo>/.logs` and a sibling data
dir in development (the dev runner prints both at startup), or
`<app-data>/throughline` when packaged. Nothing leaves your machine except the
`gh` and harness calls you would have made yourself.
4 changes: 4 additions & 0 deletions apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@
"test": "vitest run"
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "catalog:",
"@app/contracts": "workspace:*",
"@app/journey": "workspace:*",
"@app/shared": "workspace:*",
"@effect/platform-node": "catalog:",
"@effect/sql-sqlite-node": "catalog:",
"@openai/codex-sdk": "catalog:",
"effect": "catalog:"
},
"devDependencies": {
Expand Down
Loading
Loading