catherd-cli 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +66 -42
  2. package/package.json +1 -1
  3. package/plugin/.claude-plugin/plugin.json +1 -1
  4. package/plugin/.mcp.json +2 -2
  5. package/plugin/bin/catherd-mcp +30 -0
  6. package/plugin/commands/catherd.md +1 -1
  7. package/plugin/skills/catherd/SKILL.md +112 -95
  8. package/plugin/skills/catherd-setup/SKILL.md +3 -3
  9. package/src/adapters/access.ts +118 -0
  10. package/src/adapters/backend.ts +19 -4
  11. package/src/adapters/claude-code/index.ts +95 -1
  12. package/src/adapters/codex/index.ts +78 -23
  13. package/src/adapters/opencode/index.ts +17 -0
  14. package/src/domain/errors.ts +2 -0
  15. package/src/domain/failover.ts +119 -0
  16. package/src/domain/lane.ts +23 -0
  17. package/src/domain/notice.ts +95 -0
  18. package/src/domain/profile-rules.ts +43 -9
  19. package/src/domain/profile.ts +12 -6
  20. package/src/domain/record.ts +2 -0
  21. package/src/domain/role-prompts.ts +33 -1
  22. package/src/domain/state.ts +18 -2
  23. package/src/entry/deps.ts +2 -1
  24. package/src/entry/doctor-command.ts +7 -1
  25. package/src/entry/glyphs.ts +2 -1
  26. package/src/entry/init-command.ts +41 -1
  27. package/src/entry/mcp/command.ts +5 -1
  28. package/src/entry/mcp/dispatch-tools.ts +10 -40
  29. package/src/entry/mcp/handshake.ts +19 -9
  30. package/src/entry/mcp/lane-tools.ts +7 -6
  31. package/src/entry/mcp/protocol-tools.ts +57 -0
  32. package/src/entry/mcp/run-tools.ts +4 -3
  33. package/src/entry/mcp/server.ts +17 -1
  34. package/src/entry/mcp/setup-tools.ts +1 -1
  35. package/src/entry/profile-command.ts +3 -5
  36. package/src/entry/runs-command.ts +64 -21
  37. package/src/entry/tui/commands.ts +1 -1
  38. package/src/entry/tui/effects.ts +98 -56
  39. package/src/entry/tui/fixtures.ts +352 -85
  40. package/src/entry/tui/profile-edits.ts +2 -2
  41. package/src/entry/tui/profile-tree.ts +2 -1
  42. package/src/entry/tui/providers/data.tsx +35 -8
  43. package/src/entry/tui/run.tsx +11 -1
  44. package/src/entry/tui/state.ts +26 -6
  45. package/src/entry/tui/stories.ts +36 -4
  46. package/src/entry/tui/text.ts +12 -0
  47. package/src/entry/tui/theme.ts +1 -0
  48. package/src/entry/tui/views/runs.tsx +409 -117
  49. package/src/entry/tui/views/status.tsx +5 -2
  50. package/src/entry/tui/widgets/list.tsx +4 -3
  51. package/src/infra/claude-session.ts +98 -0
  52. package/src/infra/dispatch-dir.ts +14 -6
  53. package/src/infra/env.ts +26 -2
  54. package/src/infra/peer-inbox.ts +92 -0
  55. package/src/infra/supervisor.ts +33 -3
  56. package/src/services/admission.ts +38 -12
  57. package/src/services/dispatch-service.ts +338 -197
  58. package/src/services/dispatches.ts +30 -1
  59. package/src/services/doctor-access.ts +231 -0
  60. package/src/services/doctor-backends.ts +3 -18
  61. package/src/services/doctor-checks.ts +46 -1
  62. package/src/services/doctor-push.ts +109 -0
  63. package/src/services/doctor.ts +59 -79
  64. package/src/services/finalize.ts +43 -25
  65. package/src/services/gate-service.ts +288 -0
  66. package/src/services/global-install.ts +99 -0
  67. package/src/services/lane-service.ts +150 -8
  68. package/src/services/milestones.ts +208 -0
  69. package/src/services/notifier.ts +296 -0
  70. package/src/services/peek.ts +103 -0
  71. package/src/services/ports.ts +7 -4
  72. package/src/services/preflight.ts +17 -3
  73. package/src/services/protocol.ts +212 -0
  74. package/src/services/questions.ts +102 -0
  75. package/src/services/reconcile.ts +40 -11
  76. package/src/services/reentry.ts +22 -0
  77. package/src/services/run-service.ts +42 -9
  78. package/src/services/run-store.ts +18 -0
  79. package/src/services/runs-page.ts +254 -0
  80. package/src/services/session-view.ts +152 -0
  81. package/src/services/sessions.ts +92 -0
  82. package/src/services/state.ts +10 -3
  83. package/src/services/summary.ts +14 -0
package/README.md CHANGED
@@ -17,8 +17,13 @@ of work, climbing a ladder only when a cheaper rung falls short.
17
17
  opencode and headless `claude-code:` rungs run through catherd's MCP server.
18
18
  - **Survives restarts.** Workers are detached processes writing straight to disk, so a dropped
19
19
  MCP server never loses a run.
20
- - **Guard rails for autopilot.** Quota failover to a rung on another quota, a preflight check before any
21
- worker starts, per-repo knowledge carried between runs, and a run budget.
20
+ - **Results come to you.** Roles run side by side while you keep talking to Claude; each one that finishes
21
+ arrives in the session as a message, like a native subagent's notice, and `peek` shows how a run stands.
22
+ - **A protocol the tools enforce.** Every lane is routed, every brief ends with the reply contract, and a
23
+ milestone lands only after a reviewer and a verifier passed it. Workers can run their own checks (network,
24
+ loopback, Docker, the lock dir); an owner question parks one milestone, not the run.
25
+ - **Guard rails for autopilot.** Quota failover to a stand-in that clears the same bars, a preflight check
26
+ before any worker starts, per-repo knowledge carried between runs, and a run budget.
22
27
 
23
28
  ## Requirements
24
29
 
@@ -38,13 +43,18 @@ you have (`/catherd-setup` in Claude Code, or `catherd profile set roles.<role>.
38
43
  ## Install
39
44
 
40
45
  ```sh
41
- bunx catherd-cli init
46
+ bun add -g catherd-cli
47
+ catherd init
42
48
  ```
43
49
 
44
- The npm package is `catherd-cli`; the command it installs is `catherd`. `init` asks for the optional Jev key,
45
- writes the default profile and links its Claude agents, lists your backends' models, and ends with a readiness
46
- report (`--no-input` asks nothing and keeps what exists; `--profile <name>` sets up and activates that profile
47
- instead of `default`; piped, it reads one answer per line once stdin closes: the Jev key, the profile, whether to replace it, each on its own line even when a question is skipped). Then add the plugin to Claude Code:
50
+ The npm package is `catherd-cli`; the command it installs is `catherd`. `bunx catherd-cli init` works too: `init`
51
+ installs the global command at its own version (`--no-global` skips it) and says `installing catherd…` before
52
+ it does, though the first `bunx` resolve itself prints nothing for up to half a minute. `init` asks for the
53
+ optional Jev key, writes the default profile and links its Claude agents, lists your backends' models, and ends
54
+ with a readiness report (`--no-input` asks nothing and keeps what exists; `--profile <name>` sets up and activates
55
+ that profile instead of `default`; piped, it reads one answer per line once stdin closes: the Jev key, the
56
+ profile, whether to replace it, each on its own line even when a question is skipped). Then add the plugin to
57
+ Claude Code:
48
58
 
49
59
  ```sh
50
60
  claude plugin marketplace add 47vigen/catherd
@@ -52,33 +62,35 @@ claude plugin install catherd@catherd
52
62
  ```
53
63
 
54
64
  Start a new Claude Code session so the plugin, its MCP server and the agent files load, then check with
55
- `bunx catherd-cli doctor`.
65
+ `catherd doctor`. Run it once from inside that session too (ask Claude to run `catherd doctor`): its `push` row
66
+ then checks that finished roles can reach the session.
56
67
 
57
68
  ## Use
58
69
 
59
70
  In Claude Code:
60
71
 
61
- - `/catherd <task>` runs a task on autopilot; `/catherd` alone resumes the latest run.
72
+ - `/catherd <task>` runs a task on autopilot; `/catherd` alone resumes the latest run. While it runs, keep
73
+ talking: each finished role arrives as a message from catherd, and "how is it going?" gets a `peek`.
62
74
  - `/catherd-setup` tunes your profile in conversation: which models and efforts each role may
63
75
  use, cost or speed, isolation, budget and failover.
64
76
 
65
77
  In a terminal:
66
78
 
67
- | Command | What it does |
68
- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
69
- | `catherd` | The dashboard: Status, Profiles and Runs (below) |
70
- | `catherd init [--no-input] [--profile <p>]` | First-run setup |
71
- | `catherd doctor [--json]` | Readiness report, one row per check with its fix; exits 3 when not ready |
72
- | `catherd profile list\|show\|use [--repo]\|new [--from <p>]\|copy\|rm\|diff\|validate` | Profiles; `use --repo` binds one to the repo you are in |
73
- | `catherd profile use --repo --clear` | Unbinds the repo you are in; it runs on the active profile again |
74
- | `catherd profile set <path> <value> [--profile <p>]` | One field, e.g. `roles.verifier.access read-only`, `budget.usd 20` |
75
- | `catherd status [run]`, `catherd watch [--once] [--interval <s>]` | Where runs stand |
76
- | `catherd runs list [--repo <path>]\|show <id> [--debug [--name <n>]]\|cancel <id> <name>` | Past runs; `--debug` adds exit.json and the stderr and event tails, `--name` one role's |
77
- | `catherd catalog refresh\|list [--backend <b>] [--role <r>] [--text <t>] [--scored]` | The models catherd can place, filtered |
78
- | `catherd catalog treat-like <rung> <like>` | Scores an unscored rung as a scored one |
79
- | `catherd lock [--slots N] -- <cmd>` | Runs a heavy command behind the machine-wide semaphore, in its own session (no /dev/tty) |
80
- | `catherd mcp` | The MCP server on stdio; the plugin starts it, you never need to |
81
- | `catherd capture-fixtures [--backend <b>] [--out <dir>]` | Contributors: records sanitized test fixtures from real runs (see CONTRIBUTING.md) |
79
+ | Command | What it does |
80
+ | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
81
+ | `catherd` | The dashboard: Status, Profiles and Runs (below) |
82
+ | `catherd init [--no-input] [--no-global] [--profile <p>]` | First-run setup; installs the global `catherd` at its own version unless `--no-global` |
83
+ | `catherd doctor [--json]` | Readiness report, one row per check with its fix; exits 3 when not ready |
84
+ | `catherd profile list\|show\|use [--repo]\|new [--from <p>]\|copy\|rm\|diff\|validate` | Profiles; `use --repo` binds one to the repo you are in |
85
+ | `catherd profile use --repo --clear` | Unbinds the repo you are in; it runs on the active profile again |
86
+ | `catherd profile set <path> <value> [--profile <p>]` | One field, e.g. `roles.verifier.access read-only`, `roles.worker.network false`, `budget.usd 20` |
87
+ | `catherd status [run]`, `catherd watch [--once] [--interval <s>]` | Where runs stand, grouped by the Claude Code session that drove them |
88
+ | `catherd runs list [--repo <path>]\|show <id> [--debug [--name <n>]]\|cancel <id> <name>` | Past runs, by session; `--debug` adds exit.json and the stderr and event tails, `--name` one role's |
89
+ | `catherd catalog refresh\|list [--backend <b>] [--role <r>] [--text <t>] [--scored]` | The models catherd can place, filtered |
90
+ | `catherd catalog treat-like <rung> <like>` | Scores an unscored rung as a scored one |
91
+ | `catherd lock [--slots N] -- <cmd>` | Runs a heavy command behind the machine-wide semaphore, in its own session (no /dev/tty) |
92
+ | `catherd mcp` | The MCP server on stdio; the plugin starts it, you never need to |
93
+ | `catherd capture-fixtures [--backend <b>] [--out <dir>]` | Contributors: records sanitized test fixtures from real runs (see CONTRIBUTING.md) |
82
94
 
83
95
  A profile command without a profile name (`show`, `set`, `diff`, `validate`), like the MCP profile tools, acts
84
96
  on the profile the repo you are in runs on: the one bound to it, else the active one. Run them as
@@ -103,16 +115,18 @@ Run data lives in `~/.local/share/catherd/`, config in `~/.config/catherd/` (bot
103
115
  | `CATHERD_CLAUDE_AGENTS_DIR` | Where catherd links its Claude agents (default: `$CLAUDE_CONFIG_DIR/agents`, else `~/.claude/agents`) |
104
116
  | `NO_COLOR` | Drops colour (the dashboard's and `--help`'s; piped `--help` has none either) |
105
117
 
106
- For development only: `CATHERD_STORY=1` opens the dashboard's storybook, `CATHERD_TICK_MS` sets how often a blocked
107
- `wait` reports progress (default 30000), and `CATHERD_LIVE=1` enables the live tests
108
- (CONTRIBUTING.md has the rest).
118
+ For development only: `CATHERD_STORY=1` opens the dashboard's storybook, and `CATHERD_LIVE=1` enables the live
119
+ tests (CONTRIBUTING.md has the rest).
109
120
 
110
121
  ### The dashboard
111
122
 
112
123
  `catherd` opens three tabs: **1 Status** (every check with its fix; `y` copies the fix, `r` checks again),
113
124
  **2 Profiles** (one tree per profile: roles with their access, default rung, models and efforts, then routing,
114
- harness, budget, failover, timeouts and notify) and **3 Runs** (live roles, climbs, routes, the budget, landed
115
- milestones; `p` pauses). `catherd watch` opens it on Runs.
125
+ harness, budget, failover, timeouts and notify) and **3 Runs** (the Claude Code sessions that drove your runs, newest
126
+ first; a session opens on its runs, their milestones and every role with its rung, status, time and last event, live
127
+ ones first; a milestone opens on its digest (what landed, lanes and climbs, reviewer and verifier, tokens); a role
128
+ opens on its brief, reply and record; the open screen redraws as run files change; `esc` goes back,
129
+ `p` pauses). `catherd watch` opens it on Runs.
116
130
 
117
131
  - `ctrl+p` lists every command with its key and CLI twin; `?` lists the keys that work where you are.
118
132
  - `ctrl+x` is the leader: `ctrl+x 1`–`3` tabs, `ctrl+x n` new profile, `ctrl+x l` profiles, `ctrl+x u` and
@@ -131,7 +145,16 @@ milestones; `p` pauses). `catherd watch` opens it on Runs.
131
145
  (the palette shows each command by title; the ids are listed in
132
146
  [`src/entry/tui/commands.ts`](src/entry/tui/commands.ts)).
133
147
 
134
- ## Upgrading from 0.x
148
+ ## Upgrading
149
+
150
+ From 1.0: install 1.1 and run its `init` (`bun add -g catherd-cli@latest && catherd init`, or
151
+ `bunx catherd-cli@latest init`; 1.0's own `catherd init` does not upgrade), update the plugin
152
+ (`claude plugin marketplace update catherd && claude plugin update catherd@catherd`) and start a new Claude Code
153
+ session. `wait` is gone: results arrive as messages, `peek` shows a run, `result` reads a record. A profile saved
154
+ by 1.0 keeps its failover map; `catherd profile validate` says what to change. The details are in
155
+ [MIGRATION.md](MIGRATION.md).
156
+
157
+ ### From 0.x
135
158
 
136
159
  1.0 is a clean break: run `bunx catherd-cli init` once. It moves your 0.x `config.json`, `projects.json` and
137
160
  profiles into a `0.x-backup-<time>/` folder next to them (it never reads or deletes them), writes the 1.0
@@ -142,18 +165,19 @@ Code session. The details are in [MIGRATION.md](MIGRATION.md).
142
165
 
143
166
  ## Docs
144
167
 
145
- | Where | What |
146
- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
147
- | [MIGRATION.md](MIGRATION.md) | Upgrading from 0.x |
148
- | [CHANGELOG.md](CHANGELOG.md) | Releases |
149
- | [CONTRIBUTING.md](CONTRIBUTING.md) | Development setup, the checks, commits, changesets, live tests |
150
- | [SECURITY.md](SECURITY.md) | Reporting a vulnerability; what catherd stores and how |
151
- | [`docs/superpowers/specs/2026-09-25-catherd-1.0-design.md`](docs/superpowers/specs/2026-09-25-catherd-1.0-design.md) | The 1.0 design (binding) |
152
- | [`docs/dev/`](docs/dev/) | Maintainer docs: live verification, manual tests, dependencies, ideas |
153
- | [`docs/dev/live-verification.md`](docs/dev/live-verification.md) | What CI cannot run: live tests, fixture capture, the Codex sandbox |
154
- | [`docs/tui-frames.md`](docs/tui-frames.md) | Every dashboard screen as text (generated, checked in CI) |
155
- | [`docs/superpowers/`](docs/superpowers/), [`docs/research/`](docs/research/) | How 1.0 was designed and built: plans, reviews, research |
156
- | [`docs/archive/0.x/`](docs/archive/0.x/) | The 0.x design and plans, for history |
168
+ | Where | What |
169
+ | -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
170
+ | [MIGRATION.md](MIGRATION.md) | Upgrading from 1.0 and from 0.x |
171
+ | [CHANGELOG.md](CHANGELOG.md) | Releases |
172
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | Development setup, the checks, commits, changesets, live tests |
173
+ | [SECURITY.md](SECURITY.md) | Reporting a vulnerability; what catherd stores and how |
174
+ | [`docs/specs/2026-09-28-catherd-1.1-design.md`](docs/specs/2026-09-28-catherd-1.1-design.md) | The 1.1 design (binding; builds on 1.0's) |
175
+ | [`docs/specs/2026-09-25-catherd-1.0-design.md`](docs/specs/2026-09-25-catherd-1.0-design.md) | The 1.0 design |
176
+ | [`docs/dev/`](docs/dev/) | Maintainer docs: live verification, manual tests, dependencies, ideas |
177
+ | [`docs/dev/live-verification.md`](docs/dev/live-verification.md) | What CI cannot run: live tests, fixture capture, the Codex sandbox |
178
+ | [`docs/tui-frames.md`](docs/tui-frames.md) | Every dashboard screen as text (generated, checked in CI) |
179
+ | [`docs/plans/`](docs/plans/), [`docs/handoff/`](docs/handoff/), [`docs/research/`](docs/research/) | How 1.0 was designed and built: plans, reviews, research |
180
+ | [`docs/archive/0.x/`](docs/archive/0.x/) | The 0.x design and plans, for history |
157
181
 
158
182
  ## Contributing
159
183
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catherd-cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Herds coding agents: autopilot builds from your own Claude Code session.",
5
5
  "keywords": [
6
6
  "autopilot",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catherd",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Herds coding agents: Claude plans and verifies, Codex, opencode or headless Claude Code workers write the code, and Jev picks the model and effort for each piece.",
5
5
  "author": {
6
6
  "name": "47vigen",
package/plugin/.mcp.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "mcpServers": {
3
3
  "catherd": {
4
- "command": "bunx",
5
- "args": ["catherd-cli@1.0.0", "mcp"]
4
+ "command": "sh",
5
+ "args": ["${CLAUDE_PLUGIN_ROOT}/bin/catherd-mcp"]
6
6
  }
7
7
  }
8
8
  }
@@ -0,0 +1,30 @@
1
+ #!/bin/sh
2
+ # catherd's MCP launcher (spec 1.1 §12): the plugin's .mcp.json runs it. The release stamps VERSION
3
+ # (scripts/stamp-plugin-version.mjs), so the plugin always starts the server it was released with.
4
+ VERSION="1.1.1"
5
+
6
+ # a global catherd at this version (catherd init installs one): start it, no resolve at all
7
+ if command -v catherd >/dev/null 2>&1 && [ "$(catherd --version 2>/dev/null)" = "$VERSION" ]; then
8
+ # CATHERD_USER_TMPDIR is only this launcher's own hand-off to the server below; never pass on a stray one
9
+ unset CATHERD_USER_TMPDIR
10
+ exec catherd mcp
11
+ fi
12
+
13
+ # else bunx, with its cache out of $TMPDIR: macOS cleans old files there and leaves bunx a broken package.
14
+ # The server gets the user's own TMPDIR back from CATHERD_USER_TMPDIR (empty when it was unset).
15
+ if [ -n "${XDG_CACHE_HOME:-}" ]; then
16
+ cache="$XDG_CACHE_HOME"
17
+ elif [ -n "${HOME:-}" ]; then
18
+ cache="$HOME/.cache"
19
+ else
20
+ echo "catherd-mcp: HOME and XDG_CACHE_HOME are both unset, so there is no cache folder for bunx; set HOME, or install catherd globally: bun add -g catherd-cli@$VERSION" >&2
21
+ exit 1
22
+ fi
23
+ CATHERD_USER_TMPDIR="${TMPDIR:-}"
24
+ TMPDIR="$cache/catherd/bunx"
25
+ if ! mkdir -p "$TMPDIR" 2>/dev/null; then
26
+ echo "catherd-mcp: cannot create $TMPDIR for bunx's cache; fix its permissions, or install catherd globally: bun add -g catherd-cli@$VERSION" >&2
27
+ exit 1
28
+ fi
29
+ export CATHERD_USER_TMPDIR TMPDIR
30
+ exec bunx "catherd-cli@$VERSION" mcp
@@ -7,4 +7,4 @@ Use the `catherd` skill for this, and follow it exactly.
7
7
 
8
8
  Task: $ARGUMENTS
9
9
 
10
- If the task is empty, resume: call `status()`, tell the user which run it names, and continue that run from its state.md.
10
+ If the task is empty, resume: call `status()`, tell the user which run it names, call `peek(run)` once, and continue that run from its `Protocol next` step.