Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f9cd93c
[Spec 1280][Phase: phase_1_shared_skills] refactor: rewrite CLAUDE.md…
waleedkadous Aug 1, 2026
3f398cf
[Spec 1280][Phase: phase_1_shared_skills] Thread: Phase 1 built
waleedkadous Aug 1, 2026
cc2398c
[Spec 1280][Phase: phase_2_roles] refactor: rewrite roles/architect.m…
waleedkadous Aug 1, 2026
2056771
[Spec 1280][Phase: phase_2_roles] refactor: rewrite roles/builder.md …
waleedkadous Aug 1, 2026
5db6165
[Spec 1280][Phase: phase_2_roles] Phase 2 manifest
waleedkadous Aug 1, 2026
5914659
[Spec 1280][Phase: phase_2_roles] Thread: Phase 2 built
waleedkadous Aug 1, 2026
21ac428
[Spec 1280][Phase: phase_2_roles] fix: architect.md Gates section is …
waleedkadous Aug 1, 2026
fd10f76
[Spec 1280][Phase: phase_2_roles] Manifest + thread: record the relay…
waleedkadous Aug 1, 2026
4bb1b2d
[Spec 1280] Thread: hotfix #1321 and the approved post-Phase-3 follow-up
waleedkadous Aug 1, 2026
1efd8e3
[Spec 1280] Thread: pre-Phase-3 convention audit; three false positiv…
waleedkadous Aug 1, 2026
fbdc0f4
Merge remote-tracking branch 'origin/main' into builder/1280-rewrite
waleedkadous Aug 1, 2026
3b0b2a4
Merge remote-tracking branch 'origin/hotfix/1280-test-timeouts' into …
waleedkadous Aug 1, 2026
852d00d
[Spec 1280] Thread: merged main + unlanded hotfix; conflict kept both…
waleedkadous Aug 1, 2026
cf81a5f
[Spec 1280] Thread: two instrument PRs queued; seventh family instanc…
waleedkadous Aug 1, 2026
d7978e3
Merge remote-tracking branch 'origin/main' into builder/1280-rewrite
waleedkadous Aug 1, 2026
7b19539
[Spec 1280][Phase: phase_3_protocol_md] refactor: protocol.md x10 via…
waleedkadous Aug 1, 2026
a047f95
[Spec 1280][Phase: phase_3_protocol_md] Phase 3 manifest + thread: th…
waleedkadous Aug 1, 2026
1eac5c3
fix(test): T16 understands brace notation, and can no longer pass vac…
waleedkadous Aug 1, 2026
a8e4518
[Spec 1280] Thread: Phase 3 inspection failure — ran the suite before…
waleedkadous Aug 1, 2026
9d08ca2
chore(porch): bugfix-759 init bugfix
waleedkadous Aug 1, 2026
88beef7
chore(porch): bugfix-759 fix phase-transition
waleedkadous Aug 1, 2026
98da89b
[Bugfix #759] Fix: pr-search includes all PR states so merged PRs are…
waleedkadous Aug 1, 2026
4e92cef
[Bugfix #759] Test: regression for pr-search all-states flag
waleedkadous Aug 1, 2026
273b5b5
[Bugfix #759] Thread: investigate + fix notes
waleedkadous Aug 1, 2026
ee691b2
chore(porch): bugfix-759 pr phase-transition
waleedkadous Aug 1, 2026
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
31 changes: 31 additions & 0 deletions .claude/skills/codev/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,34 @@ codev doctor
- `codev init` creates a new directory — use `codev adopt` for existing projects
- Always run `codev adopt` and `codev update` from the project root
- `codev update` only updates framework files — it never touches specs/plans/reviews

## Local build and install (this repository)

Test changes locally before publishing. Run from the repository root:

```bash
pnpm build # builds core first, then codev (including dashboard)
pnpm -w run local-install # packs both packages, installs globally, restarts Tower
```

`local-install` (`scripts/local-install.sh`) packs `@cluesmith/codev-core` and
`@cluesmith/codev`, installs both in a single `npm install -g` (separate installs fail —
`codev-core` is not on the public registry), restores the executable bit on
`scripts/forge/**/*.sh` that `pnpm pack` strips, and restarts Tower last. Install runs while
Tower is up; only the final restart causes downtime. **Do not stop Tower first**, and do not use
`npm link` / `pnpm link` — it breaks global installs.

`pnpm build` also runs `copy-skeleton`, which copies `codev-skeleton/` into
`packages/codev/skeleton`. **Tests read that copy**, so after editing anything under
`codev-skeleton/` you must rebuild before the suite reflects your change.

### Where to run things

- `pnpm install` — repository root (installs all workspace packages)
- `pnpm build` / `pnpm test` — `packages/codev/`, or `pnpm --filter @cluesmith/codev build`
- Unit tests `packages/codev/tests/unit/` · E2E `packages/codev/tests/e2e/`
- Never run npm commands from the repository root unless told to

### Measuring code size

`tokei -e "tests/lib" -e "node_modules" -e ".git" -e ".builders" -e "dist" .`
119 changes: 119 additions & 0 deletions .claude/skills/runnable-worktrees/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
name: runnable-worktrees
description: Make builder worktrees runnable — the `.codev/config.json` `worktree` block (symlinks, postSpawn, devCommand), the `afx dev` CLI, VSCode dev controls, and per-stack config recipes. Use when configuring a repo so reviewers can run a builder's branch, when `afx dev` fails to bind or start, when a dev process is orphaned holding a port, or when asked why worktree dev uses the same ports as main.
---

# Runnable worktrees

When configured, each builder worktree (`.builders/<id>/`) becomes runnable: reviewers can run
whatever your dev command starts — a dev server, `cargo run`, `expo start`, a test watcher, a
build script — against the builder's branch without `cd`'ing, installing, or hunting for the
command. Opt-in via `.codev/config.json`; unconfigured repos see zero behavior change.

## Config: the `worktree` block

```jsonc
{
"worktree": {
"symlinks": ["..."], // globs symlinked from the workspace root into each new worktree
"postSpawn": ["..."], // shell commands run inside each new worktree after createWorktree
"devCommand": "..." // consumed by `afx dev <builder-id|main>`
}
}
```

- **`symlinks`** — globs resolve from the workspace root and link into the worktree at the same
relative path. Root `.env` and `.codev/config.json` are *always* symlinked regardless.
**Symlinks, not copies**, so edits to main's env files reflect instantly in a running dev
session. A directory match is silently skipped (a glob cannot mask the worktree's own source)
**unless** the entry ends in a slash: `".local-user-data/"` is treated as a literal path and
links the directory whole — shared with the parent, not branch-isolated. A dangling link is
fine if the source does not exist yet.
- **`postSpawn`** — commands run sequentially with `cwd` = worktree path. A non-zero exit aborts
the spawn loudly; the half-built worktree stays for inspection.
- **`devCommand`** — the foreground command that starts your dev process. Required for
`afx dev`.

**Codev does not auto-detect your stack.** Pick a recipe below.

## CLI

```bash
afx dev <builder-id> # start dev in that builder's worktree
afx dev main # start dev in the MAIN workspace (Codev-managed)
afx dev --stop # stop the running dev PTY (builder or main)
afx setup <builder-id> # re-apply symlinks + postSpawn to an existing worktree (idempotent)
```

**One dev PTY at a time**, across {main + all builders} — deliberate; see *URLs are
load-bearing*. `main` is a reserved target running `worktree.devCommand` in the main checkout as
a Codev-managed, swappable PTY, symmetric with builders. Starting a second target prompts to
swap; a same-target request prints the existing terminal URL and exits. Dev PTYs are
**non-persistent** — a Tower restart or crash kills them; re-run to restart.

**Start main's dev with `afx dev main`, not a bare `pnpm dev`.** A hand-run `pnpm dev` is
invisible to Codev (which never kills what it did not spawn), so a builder dev started while it
holds the ports either fails to bind or — worse — serves main's code under the worktree URL.
`afx dev main` makes it a managed PTY that swap-detection can stop cleanly. This only helps if
used consistently.

## VSCode

Right-click a builder row in the Codev sidebar (Builders or Needs Attention):

- **Open Builder Terminal** — that builder's AI terminal in a tab (same as left-click).
- **Open Worktree Folder** — `.builders/<id>/` in the OS file manager.
- **Run Worktree Setup** — re-applies `worktree.symlinks` and `worktree.postSpawn` to an
existing worktree (the git steps are skipped). Idempotent. Use when the lockfile changed, when
`symlinks`/`postSpawn` grew after the builder spawned, when a link was deleted, or when the
original setup aborted. Streams install output in a fresh terminal. CLI: `afx setup <id>`.
- **View Diff** — unified `main...HEAD` diff for that worktree with a file-list pane.
- **Run Dev** / **Stop Dev** — spawn or kill the dev PTY as a `Codev: <name> (dev)` tab;
prompts to swap if another dev is running.

The sidebar's **Workspace** view carries a dev control for whatever folder the window is rooted
at — the main checkout resolves to `main`, a `.builders/<id>/` window resolves to that builder.
The row tooltip names the resolved target. Commands are also in the palette (Cmd+Shift+P); no
default keybindings.

## URLs are load-bearing

The dev PTY intentionally uses **the same ports and URLs as main**. OAuth callbacks, CORS
allowlists, cookie scoping, CSP `connect-src` and webhook URLs are all keyed off origin, so
running a worktree on a different port would break them.

Consequence: stop main's dev before starting a builder's, or the spawned dev fails at bind time
with `EADDRINUSE`.

## Cleanup and orphan recovery

`afx dev --stop` and the swap path kill the entire PTY **process group** (SIGTERM, then SIGKILL
after 5s), which signals every grandchild of a monorepo orchestrator (`pnpm dev`, `turbo dev`,
`pnpm -r --parallel run dev`) at once. Ports are reclaimed by the OS as a consequence — Codev
never manipulates ports directly.

If Tower hard-crashes mid-dev and a process is left holding a port outside Codev's records:

```bash
lsof -ti :<port> | xargs kill
lsof -ti :3000,:3001,:4000 | xargs kill
```

## Recipes

**pnpm monorepo (Next.js / Turbo)**
```json
{"worktree": {"symlinks": [".env.local", ".env.development.local", "packages/*/.env", "packages/*/.env.local", "turbo.json"], "postSpawn": ["pnpm install --frozen-lockfile"], "devCommand": "pnpm dev"}}
```

**npm** — `{"symlinks": [".env.local", ".env.development"], "postSpawn": ["npm ci"], "devCommand": "npm run dev"}`

**yarn** — `{"symlinks": [".env.local"], "postSpawn": ["yarn install --frozen-lockfile"], "devCommand": "yarn dev"}`

**bun** — `{"symlinks": [".env.local"], "postSpawn": ["bun install --frozen-lockfile"], "devCommand": "bun dev"}`

**cargo** — `{"symlinks": [".env"], "postSpawn": [], "devCommand": "cargo run"}`

**poetry / uv** — `{"symlinks": [".env", ".env.local"], "postSpawn": ["uv sync"], "devCommand": "uv run python -m myapp"}`

**go mod** — `{"symlinks": [".env"], "postSpawn": ["go mod download"], "devCommand": "go run ./cmd/server"}`
31 changes: 31 additions & 0 deletions .codex/skills/codev/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,34 @@ codev doctor
- `codev init` creates a new directory — use `codev adopt` for existing projects
- Always run `codev adopt` and `codev update` from the project root
- `codev update` only updates framework files — it never touches specs/plans/reviews

## Local build and install (this repository)

Test changes locally before publishing. Run from the repository root:

```bash
pnpm build # builds core first, then codev (including dashboard)
pnpm -w run local-install # packs both packages, installs globally, restarts Tower
```

`local-install` (`scripts/local-install.sh`) packs `@cluesmith/codev-core` and
`@cluesmith/codev`, installs both in a single `npm install -g` (separate installs fail —
`codev-core` is not on the public registry), restores the executable bit on
`scripts/forge/**/*.sh` that `pnpm pack` strips, and restarts Tower last. Install runs while
Tower is up; only the final restart causes downtime. **Do not stop Tower first**, and do not use
`npm link` / `pnpm link` — it breaks global installs.

`pnpm build` also runs `copy-skeleton`, which copies `codev-skeleton/` into
`packages/codev/skeleton`. **Tests read that copy**, so after editing anything under
`codev-skeleton/` you must rebuild before the suite reflects your change.

### Where to run things

- `pnpm install` — repository root (installs all workspace packages)
- `pnpm build` / `pnpm test` — `packages/codev/`, or `pnpm --filter @cluesmith/codev build`
- Unit tests `packages/codev/tests/unit/` · E2E `packages/codev/tests/e2e/`
- Never run npm commands from the repository root unless told to

### Measuring code size

`tokei -e "tests/lib" -e "node_modules" -e ".git" -e ".builders" -e "dist" .`
119 changes: 119 additions & 0 deletions .codex/skills/runnable-worktrees/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
name: runnable-worktrees
description: Make builder worktrees runnable — the `.codev/config.json` `worktree` block (symlinks, postSpawn, devCommand), the `afx dev` CLI, VSCode dev controls, and per-stack config recipes. Use when configuring a repo so reviewers can run a builder's branch, when `afx dev` fails to bind or start, when a dev process is orphaned holding a port, or when asked why worktree dev uses the same ports as main.
---

# Runnable worktrees

When configured, each builder worktree (`.builders/<id>/`) becomes runnable: reviewers can run
whatever your dev command starts — a dev server, `cargo run`, `expo start`, a test watcher, a
build script — against the builder's branch without `cd`'ing, installing, or hunting for the
command. Opt-in via `.codev/config.json`; unconfigured repos see zero behavior change.

## Config: the `worktree` block

```jsonc
{
"worktree": {
"symlinks": ["..."], // globs symlinked from the workspace root into each new worktree
"postSpawn": ["..."], // shell commands run inside each new worktree after createWorktree
"devCommand": "..." // consumed by `afx dev <builder-id|main>`
}
}
```

- **`symlinks`** — globs resolve from the workspace root and link into the worktree at the same
relative path. Root `.env` and `.codev/config.json` are *always* symlinked regardless.
**Symlinks, not copies**, so edits to main's env files reflect instantly in a running dev
session. A directory match is silently skipped (a glob cannot mask the worktree's own source)
**unless** the entry ends in a slash: `".local-user-data/"` is treated as a literal path and
links the directory whole — shared with the parent, not branch-isolated. A dangling link is
fine if the source does not exist yet.
- **`postSpawn`** — commands run sequentially with `cwd` = worktree path. A non-zero exit aborts
the spawn loudly; the half-built worktree stays for inspection.
- **`devCommand`** — the foreground command that starts your dev process. Required for
`afx dev`.

**Codev does not auto-detect your stack.** Pick a recipe below.

## CLI

```bash
afx dev <builder-id> # start dev in that builder's worktree
afx dev main # start dev in the MAIN workspace (Codev-managed)
afx dev --stop # stop the running dev PTY (builder or main)
afx setup <builder-id> # re-apply symlinks + postSpawn to an existing worktree (idempotent)
```

**One dev PTY at a time**, across {main + all builders} — deliberate; see *URLs are
load-bearing*. `main` is a reserved target running `worktree.devCommand` in the main checkout as
a Codev-managed, swappable PTY, symmetric with builders. Starting a second target prompts to
swap; a same-target request prints the existing terminal URL and exits. Dev PTYs are
**non-persistent** — a Tower restart or crash kills them; re-run to restart.

**Start main's dev with `afx dev main`, not a bare `pnpm dev`.** A hand-run `pnpm dev` is
invisible to Codev (which never kills what it did not spawn), so a builder dev started while it
holds the ports either fails to bind or — worse — serves main's code under the worktree URL.
`afx dev main` makes it a managed PTY that swap-detection can stop cleanly. This only helps if
used consistently.

## VSCode

Right-click a builder row in the Codev sidebar (Builders or Needs Attention):

- **Open Builder Terminal** — that builder's AI terminal in a tab (same as left-click).
- **Open Worktree Folder** — `.builders/<id>/` in the OS file manager.
- **Run Worktree Setup** — re-applies `worktree.symlinks` and `worktree.postSpawn` to an
existing worktree (the git steps are skipped). Idempotent. Use when the lockfile changed, when
`symlinks`/`postSpawn` grew after the builder spawned, when a link was deleted, or when the
original setup aborted. Streams install output in a fresh terminal. CLI: `afx setup <id>`.
- **View Diff** — unified `main...HEAD` diff for that worktree with a file-list pane.
- **Run Dev** / **Stop Dev** — spawn or kill the dev PTY as a `Codev: <name> (dev)` tab;
prompts to swap if another dev is running.

The sidebar's **Workspace** view carries a dev control for whatever folder the window is rooted
at — the main checkout resolves to `main`, a `.builders/<id>/` window resolves to that builder.
The row tooltip names the resolved target. Commands are also in the palette (Cmd+Shift+P); no
default keybindings.

## URLs are load-bearing

The dev PTY intentionally uses **the same ports and URLs as main**. OAuth callbacks, CORS
allowlists, cookie scoping, CSP `connect-src` and webhook URLs are all keyed off origin, so
running a worktree on a different port would break them.

Consequence: stop main's dev before starting a builder's, or the spawned dev fails at bind time
with `EADDRINUSE`.

## Cleanup and orphan recovery

`afx dev --stop` and the swap path kill the entire PTY **process group** (SIGTERM, then SIGKILL
after 5s), which signals every grandchild of a monorepo orchestrator (`pnpm dev`, `turbo dev`,
`pnpm -r --parallel run dev`) at once. Ports are reclaimed by the OS as a consequence — Codev
never manipulates ports directly.

If Tower hard-crashes mid-dev and a process is left holding a port outside Codev's records:

```bash
lsof -ti :<port> | xargs kill
lsof -ti :3000,:3001,:4000 | xargs kill
```

## Recipes

**pnpm monorepo (Next.js / Turbo)**
```json
{"worktree": {"symlinks": [".env.local", ".env.development.local", "packages/*/.env", "packages/*/.env.local", "turbo.json"], "postSpawn": ["pnpm install --frozen-lockfile"], "devCommand": "pnpm dev"}}
```

**npm** — `{"symlinks": [".env.local", ".env.development"], "postSpawn": ["npm ci"], "devCommand": "npm run dev"}`

**yarn** — `{"symlinks": [".env.local"], "postSpawn": ["yarn install --frozen-lockfile"], "devCommand": "yarn dev"}`

**bun** — `{"symlinks": [".env.local"], "postSpawn": ["bun install --frozen-lockfile"], "devCommand": "bun dev"}`

**cargo** — `{"symlinks": [".env"], "postSpawn": [], "devCommand": "cargo run"}`

**poetry / uv** — `{"symlinks": [".env", ".env.local"], "postSpawn": ["uv sync"], "devCommand": "uv run python -m myapp"}`

**go mod** — `{"symlinks": [".env"], "postSpawn": ["go mod download"], "devCommand": "go run ./cmd/server"}`
Loading
Loading