@cluesmith/codev 3.2.4 → 3.3.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.
- package/dashboard-dist/assets/index-BZRTEMtH.css +32 -0
- package/dashboard-dist/assets/{index-BZ1x7x1X.js → index-D3XaKpZW.js} +46 -44
- package/dashboard-dist/assets/index-D3XaKpZW.js.map +1 -0
- package/dashboard-dist/index.html +2 -2
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +154 -0
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
- package/dist/agent-farm/commands/cleanup.js +16 -0
- package/dist/agent-farm/commands/cleanup.js.map +1 -1
- package/dist/agent-farm/commands/inbox.d.ts +42 -0
- package/dist/agent-farm/commands/inbox.d.ts.map +1 -0
- package/dist/agent-farm/commands/inbox.js +129 -0
- package/dist/agent-farm/commands/inbox.js.map +1 -0
- package/dist/agent-farm/commands/interrupt.d.ts +20 -0
- package/dist/agent-farm/commands/interrupt.d.ts.map +1 -0
- package/dist/agent-farm/commands/interrupt.js +65 -0
- package/dist/agent-farm/commands/interrupt.js.map +1 -0
- package/dist/agent-farm/commands/reset/constants.d.ts +52 -0
- package/dist/agent-farm/commands/reset/constants.d.ts.map +1 -0
- package/dist/agent-farm/commands/reset/constants.js +52 -0
- package/dist/agent-farm/commands/reset/constants.js.map +1 -0
- package/dist/agent-farm/commands/reset/context.d.ts +230 -0
- package/dist/agent-farm/commands/reset/context.d.ts.map +1 -0
- package/dist/agent-farm/commands/reset/context.js +428 -0
- package/dist/agent-farm/commands/reset/context.js.map +1 -0
- package/dist/agent-farm/commands/reset/index.d.ts +192 -0
- package/dist/agent-farm/commands/reset/index.d.ts.map +1 -0
- package/dist/agent-farm/commands/reset/index.js +488 -0
- package/dist/agent-farm/commands/reset/index.js.map +1 -0
- package/dist/agent-farm/commands/reset/receipt.d.ts +97 -0
- package/dist/agent-farm/commands/reset/receipt.d.ts.map +1 -0
- package/dist/agent-farm/commands/reset/receipt.js +149 -0
- package/dist/agent-farm/commands/reset/receipt.js.map +1 -0
- package/dist/agent-farm/commands/reset/reorient.d.ts +117 -0
- package/dist/agent-farm/commands/reset/reorient.d.ts.map +1 -0
- package/dist/agent-farm/commands/reset/reorient.js +313 -0
- package/dist/agent-farm/commands/reset/reorient.js.map +1 -0
- package/dist/agent-farm/commands/reset.d.ts +34 -0
- package/dist/agent-farm/commands/reset.d.ts.map +1 -0
- package/dist/agent-farm/commands/reset.js +309 -0
- package/dist/agent-farm/commands/reset.js.map +1 -0
- package/dist/agent-farm/commands/send.d.ts.map +1 -1
- package/dist/agent-farm/commands/send.js +49 -8
- package/dist/agent-farm/commands/send.js.map +1 -1
- package/dist/agent-farm/commands/spawn-worktree.d.ts +105 -6
- package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn-worktree.js +289 -66
- package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +13 -1
- package/dist/agent-farm/commands/spawn.js.map +1 -1
- package/dist/agent-farm/commands/status.d.ts.map +1 -1
- package/dist/agent-farm/commands/status.js +80 -8
- package/dist/agent-farm/commands/status.js.map +1 -1
- package/dist/agent-farm/commands/tower.d.ts.map +1 -1
- package/dist/agent-farm/commands/tower.js +13 -0
- package/dist/agent-farm/commands/tower.js.map +1 -1
- package/dist/agent-farm/db/index.d.ts +1 -1
- package/dist/agent-farm/db/index.d.ts.map +1 -1
- package/dist/agent-farm/db/index.js +80 -1
- package/dist/agent-farm/db/index.js.map +1 -1
- package/dist/agent-farm/db/mailbox.d.ts +222 -0
- package/dist/agent-farm/db/mailbox.d.ts.map +1 -0
- package/dist/agent-farm/db/mailbox.js +304 -0
- package/dist/agent-farm/db/mailbox.js.map +1 -0
- package/dist/agent-farm/db/schema.d.ts +1 -1
- package/dist/agent-farm/db/schema.d.ts.map +1 -1
- package/dist/agent-farm/db/schema.js +35 -0
- package/dist/agent-farm/db/schema.js.map +1 -1
- package/dist/agent-farm/db/types.d.ts +45 -0
- package/dist/agent-farm/db/types.d.ts.map +1 -1
- package/dist/agent-farm/db/types.js.map +1 -1
- package/dist/agent-farm/lib/builder-lookup.d.ts +1 -1
- package/dist/agent-farm/lib/builder-lookup.js +2 -2
- package/dist/agent-farm/lib/builder-lookup.js.map +1 -1
- package/dist/agent-farm/lib/reconnect-backoff.d.ts +64 -0
- package/dist/agent-farm/lib/reconnect-backoff.d.ts.map +1 -0
- package/dist/agent-farm/lib/reconnect-backoff.js +57 -0
- package/dist/agent-farm/lib/reconnect-backoff.js.map +1 -0
- package/dist/agent-farm/lib/tower-client.d.ts +16 -6
- package/dist/agent-farm/lib/tower-client.d.ts.map +1 -1
- package/dist/agent-farm/lib/tower-client.js +37 -6
- package/dist/agent-farm/lib/tower-client.js.map +1 -1
- package/dist/agent-farm/lib/tunnel-client.d.ts +69 -1
- package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
- package/dist/agent-farm/lib/tunnel-client.js +225 -30
- package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
- package/dist/agent-farm/servers/canvas-relay.d.ts +60 -0
- package/dist/agent-farm/servers/canvas-relay.d.ts.map +1 -0
- package/dist/agent-farm/servers/canvas-relay.js +376 -0
- package/dist/agent-farm/servers/canvas-relay.js.map +1 -0
- package/dist/agent-farm/servers/cron-delivery.d.ts +72 -0
- package/dist/agent-farm/servers/cron-delivery.d.ts.map +1 -0
- package/dist/agent-farm/servers/cron-delivery.js +80 -0
- package/dist/agent-farm/servers/cron-delivery.js.map +1 -0
- package/dist/agent-farm/servers/delayed-send.d.ts +85 -0
- package/dist/agent-farm/servers/delayed-send.d.ts.map +1 -0
- package/dist/agent-farm/servers/delayed-send.js +165 -0
- package/dist/agent-farm/servers/delayed-send.js.map +1 -0
- package/dist/agent-farm/servers/gate-profiles.d.ts +67 -0
- package/dist/agent-farm/servers/gate-profiles.d.ts.map +1 -0
- package/dist/agent-farm/servers/gate-profiles.js +113 -0
- package/dist/agent-farm/servers/gate-profiles.js.map +1 -0
- package/dist/agent-farm/servers/mailbox-delivery.d.ts +370 -0
- package/dist/agent-farm/servers/mailbox-delivery.d.ts.map +1 -0
- package/dist/agent-farm/servers/mailbox-delivery.js +617 -0
- package/dist/agent-farm/servers/mailbox-delivery.js.map +1 -0
- package/dist/agent-farm/servers/mailbox-wiring.d.ts +125 -0
- package/dist/agent-farm/servers/mailbox-wiring.d.ts.map +1 -0
- package/dist/agent-farm/servers/mailbox-wiring.js +425 -0
- package/dist/agent-farm/servers/mailbox-wiring.js.map +1 -0
- package/dist/agent-farm/servers/message-write.d.ts +53 -1
- package/dist/agent-farm/servers/message-write.d.ts.map +1 -1
- package/dist/agent-farm/servers/message-write.js +63 -0
- package/dist/agent-farm/servers/message-write.js.map +1 -1
- package/dist/agent-farm/servers/overview.d.ts +19 -0
- package/dist/agent-farm/servers/overview.d.ts.map +1 -1
- package/dist/agent-farm/servers/overview.js +100 -4
- package/dist/agent-farm/servers/overview.js.map +1 -1
- package/dist/agent-farm/servers/render-gate.d.ts +141 -0
- package/dist/agent-farm/servers/render-gate.d.ts.map +1 -0
- package/dist/agent-farm/servers/render-gate.js +251 -0
- package/dist/agent-farm/servers/render-gate.js.map +1 -0
- package/dist/agent-farm/servers/session-submit.d.ts +90 -0
- package/dist/agent-farm/servers/session-submit.d.ts.map +1 -0
- package/dist/agent-farm/servers/session-submit.js +127 -0
- package/dist/agent-farm/servers/session-submit.js.map +1 -0
- package/dist/agent-farm/servers/tower-cron.d.ts +10 -7
- package/dist/agent-farm/servers/tower-cron.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-cron.js +58 -53
- package/dist/agent-farm/servers/tower-cron.js.map +1 -1
- package/dist/agent-farm/servers/tower-instances.d.ts +14 -2
- package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-instances.js +78 -16
- package/dist/agent-farm/servers/tower-instances.js.map +1 -1
- package/dist/agent-farm/servers/tower-messages.d.ts +38 -1
- package/dist/agent-farm/servers/tower-messages.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-messages.js +106 -1
- package/dist/agent-farm/servers/tower-messages.js.map +1 -1
- package/dist/agent-farm/servers/tower-routes.d.ts +16 -4
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-routes.js +826 -145
- package/dist/agent-farm/servers/tower-routes.js.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +188 -34
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.d.ts +23 -2
- package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.js +134 -127
- package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
- package/dist/agent-farm/servers/tower-tunnel.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-tunnel.js +63 -4
- package/dist/agent-farm/servers/tower-tunnel.js.map +1 -1
- package/dist/agent-farm/servers/tower-types.d.ts +2 -1
- package/dist/agent-farm/servers/tower-types.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-utils.d.ts +64 -1
- package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-utils.js +168 -1
- package/dist/agent-farm/servers/tower-utils.js.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.d.ts +6 -1
- package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.js +95 -57
- package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
- package/dist/agent-farm/servers/write-queue.d.ts +35 -0
- package/dist/agent-farm/servers/write-queue.d.ts.map +1 -0
- package/dist/agent-farm/servers/write-queue.js +56 -0
- package/dist/agent-farm/servers/write-queue.js.map +1 -0
- package/dist/agent-farm/types.d.ts +39 -0
- package/dist/agent-farm/types.d.ts.map +1 -1
- package/dist/agent-farm/utils/agent-names.d.ts +2 -2
- package/dist/agent-farm/utils/agent-names.d.ts.map +1 -1
- package/dist/agent-farm/utils/agent-names.js +3 -3
- package/dist/agent-farm/utils/agent-names.js.map +1 -1
- package/dist/agent-farm/utils/architect-name.d.ts +2 -2
- package/dist/agent-farm/utils/architect-name.d.ts.map +1 -1
- package/dist/agent-farm/utils/architect-name.js +3 -3
- package/dist/agent-farm/utils/architect-name.js.map +1 -1
- package/dist/agent-farm/utils/config.d.ts +13 -0
- package/dist/agent-farm/utils/config.d.ts.map +1 -1
- package/dist/agent-farm/utils/config.js +33 -1
- package/dist/agent-farm/utils/config.js.map +1 -1
- package/dist/agent-farm/utils/harness.d.ts +103 -7
- package/dist/agent-farm/utils/harness.d.ts.map +1 -1
- package/dist/agent-farm/utils/harness.js +126 -19
- package/dist/agent-farm/utils/harness.js.map +1 -1
- package/dist/agent-farm/utils/message-format.d.ts +8 -0
- package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
- package/dist/agent-farm/utils/message-format.js +20 -0
- package/dist/agent-farm/utils/message-format.js.map +1 -1
- package/dist/agent-farm/utils/server-utils.d.ts +80 -4
- package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
- package/dist/agent-farm/utils/server-utils.js +286 -5
- package/dist/agent-farm/utils/server-utils.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -32
- package/dist/cli.js.map +1 -1
- package/dist/commands/consult/cli-options.d.ts +34 -0
- package/dist/commands/consult/cli-options.d.ts.map +1 -0
- package/dist/commands/consult/cli-options.js +67 -0
- package/dist/commands/consult/cli-options.js.map +1 -0
- package/dist/commands/consult/index.d.ts +56 -2
- package/dist/commands/consult/index.d.ts.map +1 -1
- package/dist/commands/consult/index.js +272 -28
- package/dist/commands/consult/index.js.map +1 -1
- package/dist/commands/consult/metrics.d.ts +42 -0
- package/dist/commands/consult/metrics.d.ts.map +1 -1
- package/dist/commands/consult/metrics.js +129 -9
- package/dist/commands/consult/metrics.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +71 -19
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/porch/checks.d.ts +23 -0
- package/dist/commands/porch/checks.d.ts.map +1 -1
- package/dist/commands/porch/checks.js +60 -0
- package/dist/commands/porch/checks.js.map +1 -1
- package/dist/commands/porch/config.d.ts +20 -0
- package/dist/commands/porch/config.d.ts.map +1 -1
- package/dist/commands/porch/config.js +20 -0
- package/dist/commands/porch/config.js.map +1 -1
- package/dist/commands/porch/index.js +21 -28
- package/dist/commands/porch/index.js.map +1 -1
- package/dist/commands/porch/next.d.ts.map +1 -1
- package/dist/commands/porch/next.js +2 -41
- package/dist/commands/porch/next.js.map +1 -1
- package/dist/lib/config.d.ts +69 -3
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +67 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/consult-lanes.d.ts +149 -0
- package/dist/lib/consult-lanes.d.ts.map +1 -0
- package/dist/lib/consult-lanes.js +360 -0
- package/dist/lib/consult-lanes.js.map +1 -0
- package/dist/lib/forge-contracts.d.ts +9 -0
- package/dist/lib/forge-contracts.d.ts.map +1 -1
- package/dist/lib/forge-contracts.js.map +1 -1
- package/dist/lib/github.d.ts +15 -1
- package/dist/lib/github.d.ts.map +1 -1
- package/dist/lib/github.js +18 -1
- package/dist/lib/github.js.map +1 -1
- package/dist/lib/prompt-behavior-metrics.d.ts +67 -0
- package/dist/lib/prompt-behavior-metrics.d.ts.map +1 -0
- package/dist/lib/prompt-behavior-metrics.js +290 -0
- package/dist/lib/prompt-behavior-metrics.js.map +1 -0
- package/dist/lib/skeleton.d.ts +22 -1
- package/dist/lib/skeleton.d.ts.map +1 -1
- package/dist/lib/skeleton.js +120 -0
- package/dist/lib/skeleton.js.map +1 -1
- package/dist/lib/test-env.d.ts +74 -0
- package/dist/lib/test-env.d.ts.map +1 -0
- package/dist/lib/test-env.js +92 -0
- package/dist/lib/test-env.js.map +1 -0
- package/dist/terminal/attach-replay.d.ts +39 -0
- package/dist/terminal/attach-replay.d.ts.map +1 -0
- package/dist/terminal/attach-replay.js +76 -0
- package/dist/terminal/attach-replay.js.map +1 -0
- package/dist/terminal/pty-manager.d.ts +2 -0
- package/dist/terminal/pty-manager.d.ts.map +1 -1
- package/dist/terminal/pty-manager.js +51 -23
- package/dist/terminal/pty-manager.js.map +1 -1
- package/dist/terminal/pty-session.d.ts +201 -1
- package/dist/terminal/pty-session.d.ts.map +1 -1
- package/dist/terminal/pty-session.js +327 -46
- package/dist/terminal/pty-session.js.map +1 -1
- package/dist/terminal/ring-buffer.d.ts +39 -6
- package/dist/terminal/ring-buffer.d.ts.map +1 -1
- package/dist/terminal/ring-buffer.js +74 -6
- package/dist/terminal/ring-buffer.js.map +1 -1
- package/dist/terminal/session-manager.d.ts +53 -0
- package/dist/terminal/session-manager.d.ts.map +1 -1
- package/dist/terminal/session-manager.js +94 -9
- package/dist/terminal/session-manager.js.map +1 -1
- package/dist/terminal/session-screen.d.ts +116 -0
- package/dist/terminal/session-screen.d.ts.map +1 -0
- package/dist/terminal/session-screen.js +180 -0
- package/dist/terminal/session-screen.js.map +1 -0
- package/dist/terminal/shellper-main.js +2 -1
- package/dist/terminal/shellper-main.js.map +1 -1
- package/dist/terminal/shellper-process.d.ts +1 -1
- package/dist/terminal/shellper-process.d.ts.map +1 -1
- package/dist/terminal/shellper-process.js +17 -8
- package/dist/terminal/shellper-process.js.map +1 -1
- package/dist/terminal/shellper-replay-buffer.d.ts +69 -7
- package/dist/terminal/shellper-replay-buffer.d.ts.map +1 -1
- package/dist/terminal/shellper-replay-buffer.js +167 -31
- package/dist/terminal/shellper-replay-buffer.js.map +1 -1
- package/package.json +13 -8
- package/scripts/forge/gitea/pr-view.sh +4 -1
- package/scripts/forge/github/pr-view.sh +1 -1
- package/scripts/forge/gitlab/pr-view.sh +4 -1
- package/skeleton/.claude/skills/afx/SKILL.md +68 -1
- package/skeleton/.claude/skills/arch-init/SKILL.md +22 -9
- package/skeleton/.claude/skills/arch-save/SKILL.md +183 -0
- package/skeleton/.claude/skills/codev/SKILL.md +31 -0
- package/skeleton/.claude/skills/runnable-worktrees/SKILL.md +119 -0
- package/skeleton/.codex/skills/afx/SKILL.md +68 -1
- package/skeleton/.codex/skills/arch-init/SKILL.md +22 -9
- package/skeleton/.codex/skills/arch-save/SKILL.md +183 -0
- package/skeleton/.codex/skills/codev/SKILL.md +31 -0
- package/skeleton/.codex/skills/runnable-worktrees/SKILL.md +119 -0
- package/skeleton/protocols/air/builder-prompt.md +28 -47
- package/skeleton/protocols/air/consult-types/impl-review.md +17 -34
- package/skeleton/protocols/air/consult-types/pr-review.md +14 -37
- package/skeleton/protocols/air/prompts/implement.md +20 -73
- package/skeleton/protocols/air/prompts/pr.md +22 -54
- package/skeleton/protocols/air/protocol.md +40 -71
- package/skeleton/protocols/aspir/builder-prompt.md +29 -66
- package/skeleton/protocols/aspir/consult-types/impl-review.md +17 -44
- package/skeleton/protocols/aspir/consult-types/phase-review.md +17 -44
- package/skeleton/protocols/aspir/consult-types/plan-review.md +14 -38
- package/skeleton/protocols/aspir/consult-types/pr-review.md +13 -39
- package/skeleton/protocols/aspir/consult-types/spec-review.md +13 -33
- package/skeleton/protocols/aspir/prompts/implement.md +27 -196
- package/skeleton/protocols/aspir/prompts/plan.md +21 -85
- package/skeleton/protocols/aspir/prompts/review.md +29 -228
- package/skeleton/protocols/aspir/prompts/specify.md +25 -111
- package/skeleton/protocols/aspir/protocol.json +10 -0
- package/skeleton/protocols/aspir/protocol.md +36 -82
- package/skeleton/protocols/bugfix/builder-prompt.md +23 -45
- package/skeleton/protocols/bugfix/consult-types/impl-review.md +21 -45
- package/skeleton/protocols/bugfix/consult-types/pr-review.md +18 -52
- package/skeleton/protocols/bugfix/prompts/fix.md +16 -61
- package/skeleton/protocols/bugfix/prompts/investigate.md +18 -62
- package/skeleton/protocols/bugfix/prompts/pr.md +22 -57
- package/skeleton/protocols/bugfix/protocol.md +44 -50
- package/skeleton/protocols/experiment/builder-prompt.md +25 -58
- package/skeleton/protocols/experiment/protocol.md +22 -188
- package/skeleton/protocols/experiment/templates/notes.md +11 -71
- package/skeleton/protocols/maintain/builder-prompt.md +24 -45
- package/skeleton/protocols/maintain/consult-types/impl-review.md +17 -44
- package/skeleton/protocols/maintain/consult-types/pr-review.md +13 -39
- package/skeleton/protocols/maintain/prompts/maintain.md +1 -1
- package/skeleton/protocols/maintain/protocol.md +32 -266
- package/skeleton/protocols/maintain/templates/maintenance-run.md +11 -0
- package/skeleton/protocols/pir/builder-prompt.md +31 -64
- package/skeleton/protocols/pir/consult-types/impl-review.md +17 -50
- package/skeleton/protocols/pir/consult-types/pr-review.md +11 -40
- package/skeleton/protocols/pir/prompts/implement.md +2 -3
- package/skeleton/protocols/pir/prompts/plan.md +1 -4
- package/skeleton/protocols/pir/prompts/review.md +2 -2
- package/skeleton/protocols/pir/protocol.md +54 -177
- package/skeleton/protocols/research/builder-prompt.md +27 -58
- package/skeleton/protocols/research/protocol.md +28 -153
- package/skeleton/protocols/spike/builder-prompt.md +30 -48
- package/skeleton/protocols/spike/protocol.md +24 -107
- package/skeleton/protocols/spike/templates/findings.md +9 -39
- package/skeleton/protocols/spir/builder-prompt.md +33 -62
- package/skeleton/protocols/spir/consult-types/impl-review.md +17 -44
- package/skeleton/protocols/spir/consult-types/phase-review.md +17 -44
- package/skeleton/protocols/spir/consult-types/plan-review.md +14 -38
- package/skeleton/protocols/spir/consult-types/pr-review.md +13 -39
- package/skeleton/protocols/spir/consult-types/spec-review.md +13 -33
- package/skeleton/protocols/spir/prompts/implement.md +26 -195
- package/skeleton/protocols/spir/prompts/plan.md +20 -84
- package/skeleton/protocols/spir/prompts/review.md +28 -227
- package/skeleton/protocols/spir/prompts/specify.md +24 -110
- package/skeleton/protocols/spir/protocol.json +10 -0
- package/skeleton/protocols/spir/protocol.md +84 -633
- package/skeleton/protocols/spir/templates/plan.md +28 -147
- package/skeleton/protocols/spir/templates/review.md +21 -80
- package/skeleton/protocols/spir/templates/spec.md +24 -118
- package/skeleton/resources/commands/agent-farm.md +262 -0
- package/skeleton/resources/commands/consult.md +236 -8
- package/skeleton/resources/commands/overview.md +1 -0
- package/skeleton/roles/architect.md +67 -317
- package/skeleton/roles/builder.md +76 -191
- package/skeleton/templates/AGENTS.md +2 -0
- package/skeleton/templates/CLAUDE.md +2 -0
- package/templates/3d-viewer.html +32 -4
- package/templates/open.html +58 -12
- package/templates/tower.html +65 -9
- package/templates/vendor/three-3MFLoader.js +1478 -0
- package/templates/vendor/three-STLLoader.js +410 -0
- package/templates/vendor/three-TrackballControls.js +828 -0
- package/templates/vendor/three-fflate.module.js +2474 -0
- package/templates/vendor/three.module.js +53044 -0
- package/dashboard-dist/assets/index-BZ1x7x1X.js.map +0 -1
- package/dashboard-dist/assets/index-DB1KBSNE.css +0 -32
- package/dist/agent-farm/servers/send-buffer.d.ts +0 -59
- package/dist/agent-farm/servers/send-buffer.d.ts.map +0 -1
- package/dist/agent-farm/servers/send-buffer.js +0 -116
- package/dist/agent-farm/servers/send-buffer.js.map +0 -1
- package/skeleton/porch/prompts/defend.md +0 -108
- package/skeleton/porch/prompts/diagnose.md +0 -70
- package/skeleton/porch/prompts/evaluate.md +0 -132
- package/skeleton/porch/prompts/fix.md +0 -59
- package/skeleton/porch/prompts/implement.md +0 -88
- package/skeleton/porch/prompts/plan.md +0 -74
- package/skeleton/porch/prompts/pr.md +0 -84
- package/skeleton/porch/prompts/review.md +0 -249
- package/skeleton/porch/prompts/specify.md +0 -53
- package/skeleton/porch/prompts/test.md +0 -63
- package/skeleton/protocols/aspir/templates/plan.md +0 -184
- package/skeleton/protocols/aspir/templates/review.md +0 -120
- package/skeleton/protocols/aspir/templates/spec.md +0 -154
|
@@ -342,6 +342,41 @@ afx send [builder] [message] [options]
|
|
|
342
342
|
- `--interrupt` - Send Ctrl+C first
|
|
343
343
|
- `--raw` - Skip structured message formatting
|
|
344
344
|
- `--no-enter` - Do not send Enter after message
|
|
345
|
+
- `--delay <seconds>` - Deliver after N seconds instead of immediately
|
|
346
|
+
|
|
347
|
+
**Delayed delivery (`--delay`):**
|
|
348
|
+
|
|
349
|
+
Tower holds the message and delivers it after the stated delay, so the sending process is
|
|
350
|
+
free to exit in the meantime. That is the point: a session can schedule a message to
|
|
351
|
+
*itself* for after something that destroys it.
|
|
352
|
+
|
|
353
|
+
- **Authorised at request time, delivered later.** Target resolution and the
|
|
354
|
+
builder-spoofing check run when the command is issued, exactly as for an immediate send.
|
|
355
|
+
A delayed send cannot defer a check past the conditions that would fail it.
|
|
356
|
+
- **Bounds:** a whole number of seconds, 1–3600, rejected at both the CLI and server
|
|
357
|
+
boundaries — a bad value silently changes *when* (or whether) a message arrives rather
|
|
358
|
+
than failing loudly.
|
|
359
|
+
- **Persisted and durable (Spec 1313).** The message is written to Tower's durable mailbox at
|
|
360
|
+
request time with a due time (`not_before`), so a pending delayed send **survives a Tower
|
|
361
|
+
restart** — the render gate still guarantees it only lands on a clean, verified-empty prompt
|
|
362
|
+
when it comes due (this reverses Spec 1307's original drop-on-restart behaviour; the gate now
|
|
363
|
+
provides the protection that behaviour wanted). A pre-due delayed send is listable — and
|
|
364
|
+
cancellable — via `afx inbox`.
|
|
365
|
+
- **Ordering:** a delayed message never overtakes one already queued for that session — its
|
|
366
|
+
durable row is created at request time, and the mailbox delivers the oldest *eligible* row
|
|
367
|
+
first, so a pre-due message does not block a later message that is already due, and concurrent
|
|
368
|
+
deliveries to one agent do not interleave. Request order across *differing* delays is **not**
|
|
369
|
+
preserved — `--delay 30` then `--delay 5` delivers the 5-second one first, because that is what
|
|
370
|
+
`--delay` means.
|
|
371
|
+
- **Reporting:** the CLI says "scheduled", not "sent", and returns the mailbox id of the
|
|
372
|
+
persisted row.
|
|
373
|
+
- `--interrupt` is combinable (the Ctrl+C defers *with* the message); the API's `escape`
|
|
374
|
+
option is not (an ESC bypasses buffering precisely so it interrupts the *current* turn).
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# Deliver in 15 seconds; this shell can exit immediately
|
|
378
|
+
afx send architect:main --delay 15 --raw '/arch-init main'
|
|
379
|
+
```
|
|
345
380
|
|
|
346
381
|
**Description:**
|
|
347
382
|
|
|
@@ -350,6 +385,18 @@ Sends text to a builder's terminal. Useful for:
|
|
|
350
385
|
- Interrupting long-running processes
|
|
351
386
|
- Sending instructions or context
|
|
352
387
|
|
|
388
|
+
**Outcome (Spec 1313 — mailbox-first delivery):**
|
|
389
|
+
|
|
390
|
+
`afx send` reports the real first outcome instead of an unconditional "delivered":
|
|
391
|
+
|
|
392
|
+
- **delivered** — the message was written to the recipient's prompt after a clean render-gate pass (an empty, render-verified prompt).
|
|
393
|
+
- **held** — the prompt was not clear, so the message is persisted in Tower's durable mailbox and **delivers automatically** the moment the recipient's prompt is clean (after a submit, on output quiescence, or a poll backstop). The response carries a **why-held reason** and a mailbox id:
|
|
394
|
+
- `busy` — a draft, menu, dialog, or wrapper screen occupies the prompt;
|
|
395
|
+
- `no-profile` — the target app has no render-gate classifier profile (only `claude`, `codex`, and `agy` are modeled);
|
|
396
|
+
- `no-live-pty` — the recipient agent has no live terminal right now (it delivers when the agent respawns — rows address agents, not PTYs).
|
|
397
|
+
|
|
398
|
+
A held message is **never force-injected** onto a busy line: a message body is only ever written to a verified-empty prompt, so it cannot fuse with a half-typed draft, and held rows survive Tower restart/shutdown (no shutdown force-flush). See held mail with `afx inbox`, read one (including its body) with `afx inbox show <id>`, and clear one with `afx inbox dismiss <id>`. `--interrupt` is the explicit, deliberate bypass: it interrupts the agent and writes without holding (unchanged semantics).
|
|
399
|
+
|
|
353
400
|
**Examples:**
|
|
354
401
|
|
|
355
402
|
```bash
|
|
@@ -368,6 +415,167 @@ afx send 42 --file src/api.ts "Review this implementation"
|
|
|
368
415
|
|
|
369
416
|
---
|
|
370
417
|
|
|
418
|
+
### afx inbox
|
|
419
|
+
|
|
420
|
+
List, inspect, and dismiss **held** (undelivered) messages — the human-facing visibility surface for Spec 1313's mailbox. `afx send` persists a message it can't deliver immediately as a held row that delivers automatically once the recipient's prompt is clear; `afx inbox` lets a human see what is still waiting, read a specific message body, and clear rows — without reading Tower logs.
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
afx inbox [options]
|
|
424
|
+
afx inbox show <id> [options]
|
|
425
|
+
afx inbox dismiss <id> [options]
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**`afx inbox`** — list every currently-held message in the workspace. Metadata only — message bodies are never shown in the list (or in logs); use `afx inbox show <id>` to read one:
|
|
429
|
+
|
|
430
|
+
| Column | Meaning |
|
|
431
|
+
|---|---|
|
|
432
|
+
| `ID` | Mailbox row id (pass to `show` / `dismiss`) |
|
|
433
|
+
| `AGE` | How long the message has been held (`5s`, `3m`, `2h`, `1d`) |
|
|
434
|
+
| `REASON` | Why-held: `busy`, `no-profile`, or `no-live-pty`; a trailing `!` marks a row past the escalation age |
|
|
435
|
+
| `FROM → TO` | Sender → recipient agent |
|
|
436
|
+
| `WORKSPACE` | Owning workspace |
|
|
437
|
+
|
|
438
|
+
**Options:**
|
|
439
|
+
- `-w, --workspace <path>` - Workspace to list (default: current workspace — `afx inbox` is workspace-scoped, not Tower-wide)
|
|
440
|
+
- `-p, --port <port>` - Tower port (default: 4100)
|
|
441
|
+
|
|
442
|
+
**`afx inbox show <id>`** — display a single message by id, **including its body**. This is the one CLI surface that surfaces a body: the redaction rule keeps bodies out of logs, diagnostics, and telemetry — not out of this local operator view, which travels over the same local Tower connection the message already uses. `show` works on a row of **any** status (held / delivered / superseded / dismissed), so a resolved row stays inspectable by id for audit until it is pruned. Prints the metadata (status, why-held reason, from → to, workspace, timestamps) followed by the raw body.
|
|
443
|
+
|
|
444
|
+
**Options:**
|
|
445
|
+
- `-p, --port <port>` - Tower port (default: 4100)
|
|
446
|
+
|
|
447
|
+
**`afx inbox dismiss <id>`** — mark a held message dismissed. A soft, auditable transition (the row is marked `dismissed`, not deleted) that **never delivers** the message. Any workspace operator may dismiss any held row (same local-human trust level as `afx send`).
|
|
448
|
+
|
|
449
|
+
**Options:**
|
|
450
|
+
- `-p, --port <port>` - Tower port (default: 4100)
|
|
451
|
+
|
|
452
|
+
**Examples:**
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
# List held messages in the current workspace
|
|
456
|
+
afx inbox
|
|
457
|
+
|
|
458
|
+
# Show one message including its body (works for any status, held or resolved)
|
|
459
|
+
afx inbox show 5f3c9a2b-1e4d-4c7a-9f21-8b6d0e2a1c33
|
|
460
|
+
|
|
461
|
+
# Dismiss a held message by id (never delivers it)
|
|
462
|
+
afx inbox dismiss 5f3c9a2b-1e4d-4c7a-9f21-8b6d0e2a1c33
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Dismissal is CLI-only; the dashboard and VSCode held-count indicators surface the count but are read-only (Spec 1313 decision 8).
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
### afx interrupt
|
|
470
|
+
|
|
471
|
+
Interrupt a builder mid-turn by sending an ESC keystroke to its PTY.
|
|
472
|
+
|
|
473
|
+
```bash
|
|
474
|
+
afx interrupt <builder> [options]
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**Arguments:**
|
|
478
|
+
- `builder` - Target builder. Same addressing as `afx send`.
|
|
479
|
+
|
|
480
|
+
**Options:**
|
|
481
|
+
- `--no-enter` - Send ESC alone, without the trailing Enter
|
|
482
|
+
|
|
483
|
+
**Description:**
|
|
484
|
+
|
|
485
|
+
This is the only recovery that reaches a builder **mid-turn**. When a builder chains foreground waits
|
|
486
|
+
inside a single turn, every `afx send` — including your order to stop — queues unread until that turn
|
|
487
|
+
ends. ESC interrupts the running tool and ends the turn, after which the queued messages process. The
|
|
488
|
+
trailing Enter (default) is what lets them through.
|
|
489
|
+
|
|
490
|
+
Distinct from `afx send --interrupt`, which sends Ctrl+C.
|
|
491
|
+
|
|
492
|
+
**Examples:**
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
# Builder is wedged on a foreground wait and not reading messages
|
|
496
|
+
afx interrupt 0042
|
|
497
|
+
|
|
498
|
+
# Then the queued instruction lands
|
|
499
|
+
afx send 0042 "That producer died — stop waiting and report."
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
### afx refresh
|
|
505
|
+
|
|
506
|
+
Refresh a builder's context: have it save its working state, clear the conversation, then re-orient it.
|
|
507
|
+
|
|
508
|
+
```bash
|
|
509
|
+
afx refresh <builder> [options]
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
**Arguments:**
|
|
513
|
+
- `builder` - Target builder. Same addressing as `afx send`.
|
|
514
|
+
|
|
515
|
+
**Options:**
|
|
516
|
+
- `--note <text>` - Extra context appended to the re-orientation
|
|
517
|
+
- `--file <path>` - Append file content to the re-orientation (48KB max, read from *your* filesystem)
|
|
518
|
+
- `--dry-run` - Print the save request and both re-orientation payloads; write nothing to the builder
|
|
519
|
+
- `--interrupt-first` - Send ESC before the save request, for a builder already wedged mid-turn
|
|
520
|
+
- `--mode <strict|soft>` - Override the builder mode if it cannot be detected
|
|
521
|
+
- `--timeout <seconds>` - How long to wait for the save-state receipt (default 300)
|
|
522
|
+
- `--min-bytes <n>` - Minimum state-file size to accept as substantive (default 1000)
|
|
523
|
+
- `--quiet-window <ms>` - Terminal silence that counts as turn-ended (default 1500)
|
|
524
|
+
|
|
525
|
+
**Deprecated alias:** `afx reset` still runs this command and prints a one-line notice to stderr.
|
|
526
|
+
It will be removed in a future release — use `afx refresh`.
|
|
527
|
+
|
|
528
|
+
**Description:**
|
|
529
|
+
|
|
530
|
+
Long-running builders exhaust their context window. `afx spawn --resume` reattaches the *same*
|
|
531
|
+
conversation, so a deep session resumes deep — it does not give the builder a fresh window. `afx refresh`
|
|
532
|
+
does, without losing what the builder knows.
|
|
533
|
+
|
|
534
|
+
The sequence:
|
|
535
|
+
|
|
536
|
+
1. Assemble the re-orientation and write it to `.builder-reorient.md` in the worktree.
|
|
537
|
+
2. Ask the builder to write its complete working state to `.builder-state.md`, stamped with a one-time
|
|
538
|
+
nonce.
|
|
539
|
+
3. Wait for that file and **verify** it: correct nonce (not a stale file from an earlier refresh),
|
|
540
|
+
substantive size, and stable across two observations (not still being written).
|
|
541
|
+
4. Wait for the terminal to fall silent, so the clear is not typed mid-turn. If it does not settle, send
|
|
542
|
+
**one** ESC and wait again.
|
|
543
|
+
5. Send `/clear`.
|
|
544
|
+
6. Deliver the re-orientation: role, protocol, mode, project, worktree, branch, the porch re-entry
|
|
545
|
+
instruction, and a pointer to the state file.
|
|
546
|
+
|
|
547
|
+
**Every gate fails safe.** If the state file never arrives, carries the wrong nonce, is a stub, is still
|
|
548
|
+
growing, or the builder will not go quiet — the command **aborts without clearing** and exits non-zero,
|
|
549
|
+
naming the gate that failed. A builder whose context was not cleared has lost nothing.
|
|
550
|
+
|
|
551
|
+
Both worktree artifacts use the `.builder-` prefix, so `afx cleanup` still classifies the worktree as
|
|
552
|
+
clean, and both are untracked so `porch done`'s staged-file sweep cannot pick them up.
|
|
553
|
+
|
|
554
|
+
Requires a harness with in-session context reset (Claude Code). Other harnesses abort loudly rather than
|
|
555
|
+
substituting a different mechanism — use the boundary-recycle pattern instead (let the builder finish,
|
|
556
|
+
then `afx spawn <id> --resume`).
|
|
557
|
+
|
|
558
|
+
**Examples:**
|
|
559
|
+
|
|
560
|
+
```bash
|
|
561
|
+
# See exactly what would be sent, without touching the builder
|
|
562
|
+
afx refresh 0042 --dry-run
|
|
563
|
+
|
|
564
|
+
# Standard refresh
|
|
565
|
+
afx refresh 0042
|
|
566
|
+
|
|
567
|
+
# Add context that post-dates the builder's saved state
|
|
568
|
+
afx refresh 0042 --note "PR #90 merged while you were mid-phase. Rebase before continuing."
|
|
569
|
+
|
|
570
|
+
# The builder is wedged mid-turn and not reading messages
|
|
571
|
+
afx refresh 0042 --interrupt-first
|
|
572
|
+
|
|
573
|
+
# A builder that legitimately needs longer to write its state
|
|
574
|
+
afx refresh 0042 --timeout 600
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
371
579
|
### afx open
|
|
372
580
|
|
|
373
581
|
Open file annotation viewer.
|
|
@@ -537,6 +745,42 @@ afx tower status [options]
|
|
|
537
745
|
|
|
538
746
|
---
|
|
539
747
|
|
|
748
|
+
### afx cron
|
|
749
|
+
|
|
750
|
+
Manage scheduled tasks defined as YAML files in `.af-cron/` at the workspace root. The Tower scheduler loads these every tick, runs due commands, and delivers messages through the normal send pipeline.
|
|
751
|
+
|
|
752
|
+
```bash
|
|
753
|
+
afx cron list # List all cron tasks
|
|
754
|
+
afx cron status <name> # Check task status
|
|
755
|
+
afx cron run <name> # Run immediately
|
|
756
|
+
afx cron enable <name> # Enable
|
|
757
|
+
afx cron disable <name> # Disable
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
There is NO `afx cron add` — create YAML files in `.af-cron/` directly.
|
|
761
|
+
|
|
762
|
+
**Task YAML format:**
|
|
763
|
+
|
|
764
|
+
```yaml
|
|
765
|
+
name: Service Health Check # required, unique per workspace
|
|
766
|
+
schedule: "*/15 * * * *" # required, cron expression (or @hourly/@daily/@startup)
|
|
767
|
+
command: ./health-check.sh # required, run via shell
|
|
768
|
+
message: "Health alert: ${output}" # required, ${output} = trimmed command output
|
|
769
|
+
condition: "exitCode != 0" # optional JS expression, see below
|
|
770
|
+
target: architect # optional, default architect
|
|
771
|
+
timeout: 30 # optional, seconds, default 30
|
|
772
|
+
enabled: true # optional, default true
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
**Condition environment:** `condition` is a JavaScript expression evaluated with two variables in scope:
|
|
776
|
+
|
|
777
|
+
- `output` (string) — the command's trimmed output
|
|
778
|
+
- `exitCode` (number) — `0` on success, the command's exit code on non-zero exit, `124` on timeout, `-1` on spawn failure
|
|
779
|
+
|
|
780
|
+
With a `condition`, the message is delivered exactly when the expression evaluates truthy — including on failed runs, so `condition: "exitCode != 0"` alerts when the command fails. Without a `condition`, the message is delivered only when the command exits 0.
|
|
781
|
+
|
|
782
|
+
---
|
|
783
|
+
|
|
540
784
|
### afx db
|
|
541
785
|
|
|
542
786
|
Database debugging and maintenance commands.
|
|
@@ -645,6 +889,24 @@ afx workspace start --architect-cmd "claude --model opus"
|
|
|
645
889
|
afx spawn 42 --protocol spir --builder-cmd "claude --model haiku"
|
|
646
890
|
```
|
|
647
891
|
|
|
892
|
+
### Mailbox retention and escalation
|
|
893
|
+
|
|
894
|
+
`afx send`'s mailbox (Spec 1313) has two Tower-global knobs under a `mailbox` key:
|
|
895
|
+
|
|
896
|
+
```json
|
|
897
|
+
{
|
|
898
|
+
"mailbox": {
|
|
899
|
+
"retentionDays": 30,
|
|
900
|
+
"escalationSeconds": 60
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
```
|
|
904
|
+
|
|
905
|
+
- `mailbox.retentionDays` (default `30`) — how long a **terminal** mailbox row (delivered, superseded, or dismissed) is retained before Tower prunes it. **Held** rows are never pruned — they persist until they deliver, are superseded, or are dismissed via `afx inbox`.
|
|
906
|
+
- `mailbox.escalationSeconds` (default `60`) — how long a row may stay **held** before it crosses the escalation age. At that point the drainer marks the row `escalated`, emits the escalation broadcast, and moves the dashboard / VSCode held-count indicator into its attention state. This is **visibility only** — crossing the escalation age never triggers delivery (there is no force path; a held message still delivers only onto a verified-empty prompt).
|
|
907
|
+
|
|
908
|
+
Both are Tower-global (they apply to the whole Tower, not per-project) and optional — omit them to use the defaults above.
|
|
909
|
+
|
|
648
910
|
---
|
|
649
911
|
|
|
650
912
|
## Files
|
|
@@ -15,14 +15,214 @@ consult stats [options]
|
|
|
15
15
|
-m, --model <model> Model to use (required for all modes except stats)
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
## Model Selection Options
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
--model-id <id> Override the provider model id for THIS invocation
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`-m/--model` picks the **lane** (`claude`, `codex`, `gemini`, `hermes`); `--model-id` picks the
|
|
25
|
+
**model that lane runs**. The two are independent — see [Configuration](#configuration) for setting
|
|
26
|
+
an id persistently instead.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
consult -m codex --model-id gpt-5.6-sol --prompt "Review this design"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- **Precedence**: `--model-id` > `consult.models.<lane>` > the lane's shipped default.
|
|
33
|
+
- **Supported lanes**: `claude`, `codex`, `gemini`. Using it with `hermes` is an **error**, not a
|
|
34
|
+
silent no-op — `hermes chat -q` has no model selector, so accepting the flag there would mean
|
|
35
|
+
ignoring it.
|
|
36
|
+
- **Validation is syntax-only.** Whether the id exists is the provider's call; a rejection fails
|
|
37
|
+
loudly with no fallback to the default. See
|
|
38
|
+
[the fail-fast contract](#the-fail-fast-contract-and-where-it-stops).
|
|
39
|
+
|
|
18
40
|
## Models
|
|
19
41
|
|
|
20
|
-
| Model | Alias | Backend | Notes |
|
|
21
|
-
|
|
22
|
-
| `gemini` | `pro` | Antigravity CLI (`agy`) | Agentic file access (`--sandbox --add-dir`), OAuth/subscription login. Skips non-blockingly if `agy` is missing/unauthed. |
|
|
23
|
-
| `codex` | `gpt` | @openai/codex | Read-only sandbox, thorough |
|
|
24
|
-
| `claude` | `opus` | Claude Agent SDK | Balanced analysis with tool use |
|
|
25
|
-
| `hermes` | - | hermes CLI (`hermes chat -q`) | Uses Hermes agent as consult backend |
|
|
42
|
+
| Model | Alias | Backend | Shipped default model id | Notes |
|
|
43
|
+
|-------|-------|---------|--------------------------|-------|
|
|
44
|
+
| `gemini` | `pro` | Antigravity CLI (`agy`) | *(agy's own default — no pinned id)* | Agentic file access (`--sandbox --add-dir`), OAuth/subscription login. Skips non-blockingly if `agy` is missing/unauthed. |
|
|
45
|
+
| `codex` | `gpt` | @openai/codex | `gpt-5.6-sol` (medium reasoning effort) | Read-only sandbox, thorough |
|
|
46
|
+
| `claude` | `opus` | Claude Agent SDK | `claude-opus-5` | Balanced analysis with tool use |
|
|
47
|
+
| `hermes` | - | hermes CLI (`hermes chat -q`) | *(hermes' own default)* | Uses Hermes agent as consult backend |
|
|
48
|
+
|
|
49
|
+
> **The codex lane's `-sol` suffix is load-bearing.** Plain `gpt-5.6` and `gpt-5.6-codex` are both
|
|
50
|
+
> rejected by Codex when running on a ChatGPT account (`The '<id>' model is not supported when
|
|
51
|
+
> using Codex with a ChatGPT account.`). Don't "simplify" the id — a unit test pins it.
|
|
52
|
+
|
|
53
|
+
### Cost reporting
|
|
54
|
+
|
|
55
|
+
Codex consultation cost is computed from OpenAI's published per-1M-token rates for the lane's
|
|
56
|
+
model. If a model has no rates recorded in Codev, the consultation still runs and its token counts
|
|
57
|
+
are still recorded, but `cost_usd` is stored as `null` rather than billed at some other model's
|
|
58
|
+
rates. Only OpenAI's standard pricing tier is modelled — costs for consultations large enough to
|
|
59
|
+
enter the long-context tier are under-reported.
|
|
60
|
+
|
|
61
|
+
Supply rates for a model Codev doesn't know with [`consult.pricing.codex`](#consultpricingcodex).
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
Everything below lives in `.codev/config.json` and flows through the standard five-layer config
|
|
66
|
+
stack, lowest priority to highest:
|
|
67
|
+
|
|
68
|
+
1. built-in defaults
|
|
69
|
+
2. `<cache>/config.json` — remote framework base config
|
|
70
|
+
3. `~/.codev/config.json` — global, per-user, across all projects
|
|
71
|
+
4. `.codev/config.json` — project, checked in
|
|
72
|
+
5. `.codev/config.local.json` — project, per-engineer, gitignored
|
|
73
|
+
|
|
74
|
+
So any key can be set globally and narrowed per project, and an individual engineer can override
|
|
75
|
+
either without touching a checked-in file.
|
|
76
|
+
|
|
77
|
+
**Two independent axes**, easy to confuse:
|
|
78
|
+
|
|
79
|
+
| Axis | Key | Answers |
|
|
80
|
+
|------|-----|---------|
|
|
81
|
+
| *Which model* a lane runs | `consult.models` | "run `claude-opus-5` on the claude lane" |
|
|
82
|
+
| *Which lanes* run at all | `porch.consultation.*` | "review PIR with two lanes, not three" |
|
|
83
|
+
|
|
84
|
+
### `consult.models`
|
|
85
|
+
|
|
86
|
+
Per-lane model id. Absent → the shipped default in the [Models](#models) table. Outranked for a
|
|
87
|
+
single invocation by [`--model-id`](#model-selection-options).
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{ "consult": { "models": { "claude": "claude-opus-5", "codex": "gpt-5.6-sol" } } }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Valid lanes: `claude`, `codex`, `gemini`. **`hermes` is rejected** — it is invoked as
|
|
94
|
+
`hermes chat -q` and exposes no model selector, so configuring one would silently do nothing.
|
|
95
|
+
(`hermes` remains valid in `porch.consultation` lane lists; the two key spaces differ on purpose.)
|
|
96
|
+
|
|
97
|
+
The `gemini` lane passes the id to `agy --model`, so the id space is agy's, not Google's API's.
|
|
98
|
+
|
|
99
|
+
### `consult.reasoningEffort`
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{ "consult": { "reasoningEffort": { "codex": "high" } } }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Only `codex` exposes this. Values: `minimal`, `low`, `medium`, `high`, `xhigh` (default `medium`).
|
|
106
|
+
Unlike model ids, this **is** a closed set Codev validates locally — see the asymmetry below.
|
|
107
|
+
|
|
108
|
+
### `consult.pricing.codex`
|
|
109
|
+
|
|
110
|
+
Per-1M-token rates for the codex lane. Set this when Codev has no rates for the model you run
|
|
111
|
+
(otherwise `cost_usd` is `null`), or to correct rates that have gone stale.
|
|
112
|
+
|
|
113
|
+
**It outranks the shipped rate table for every model, not only unknown ones** — once set, it is
|
|
114
|
+
used for whatever the codex lane runs, so it is worth revisiting if you later change the model.
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{ "consult": { "pricing": { "codex": { "inputPer1M": 5.00, "cachedInputPer1M": 0.50, "outputPer1M": 30.00 } } } }
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
> **Take the numbers from the provider, not from here.** Those are the rates Codev ships for
|
|
121
|
+
> `gpt-5.6-sol` at the time of writing, shown so the shape is concrete — they are not right for
|
|
122
|
+
> whatever model you are configuring, and published rates change. Copying a plausible-looking wrong
|
|
123
|
+
> rate produces a confidently wrong cost, which is the exact failure this key exists to prevent;
|
|
124
|
+
> a `null` cost is the better outcome of the two.
|
|
125
|
+
|
|
126
|
+
- **`codex` is the only accepted lane.** Claude reports its own cost directly and the gemini/agy
|
|
127
|
+
lane reports no usage data at all, so a pricing override for either would be inert. Any other
|
|
128
|
+
lane key is an error.
|
|
129
|
+
- **All three rates are required together**, and each must be a finite, non-negative number. A
|
|
130
|
+
partial object is an error, not a half-priced estimate: defaulting any one rate to a stale
|
|
131
|
+
built-in would reintroduce exactly the wrong-cost problem this override exists to fix.
|
|
132
|
+
|
|
133
|
+
### `porch.consultation` — which lanes run
|
|
134
|
+
|
|
135
|
+
Lane lists accept a single name (`"codex"`), an array (`["codex", "claude"]`), or a whole-value
|
|
136
|
+
special mode: `"none"` (skip consultation) or `"parent"` (emit a gate for the architect instead).
|
|
137
|
+
An **empty array is rejected** — use `"none"`, so there is exactly one way to say it.
|
|
138
|
+
|
|
139
|
+
`models` is the workspace-wide default, `modelsByType` narrows by review type, and `byProtocol`
|
|
140
|
+
scopes either of those to one protocol:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"porch": {
|
|
145
|
+
"consultation": {
|
|
146
|
+
"models": ["gemini", "codex", "claude"],
|
|
147
|
+
"modelsByType": { "pr": ["codex", "claude"] },
|
|
148
|
+
"byProtocol": {
|
|
149
|
+
"pir": {
|
|
150
|
+
"models": ["gemini", "codex"],
|
|
151
|
+
"modelsByType": { "impl": ["codex"] }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Review-type keys are the protocol's own `verify.type` values (`spec`, `plan`, `impl`, `pr`, …);
|
|
160
|
+
protocol keys are protocol names, and aliases are canonicalized so `byProtocol.spider` matches a
|
|
161
|
+
project running as `spir`. Unknown keys in either space are **errors, not warnings** — a typo that
|
|
162
|
+
merely warned would silently leave you on the defaults you were trying to override.
|
|
163
|
+
|
|
164
|
+
#### Precedence
|
|
165
|
+
|
|
166
|
+
Highest first. The first level that is present wins outright; levels do not merge.
|
|
167
|
+
|
|
168
|
+
1. `porch.consultation.byProtocol[<protocol>].modelsByType[<type>]`
|
|
169
|
+
2. `porch.consultation.byProtocol[<protocol>].models`
|
|
170
|
+
3. `porch.consultation.modelsByType[<type>]`
|
|
171
|
+
4. `porch.consultation.models`
|
|
172
|
+
5. the protocol's own `verify.models` (i.e. no config at all)
|
|
173
|
+
|
|
174
|
+
Both `porch next` and `porch done` resolve through this one ladder, so the lanes porch asks you to
|
|
175
|
+
run are exactly the lanes it will require review files for.
|
|
176
|
+
|
|
177
|
+
#### Worked example: keeping PIR cheap while widening the default
|
|
178
|
+
|
|
179
|
+
PIR is deliberately a 2-lane (CMAP-2) protocol. A workspace-wide 3-lane default silently inflates
|
|
180
|
+
it, because config outranks protocol. Scope PIR back down explicitly:
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"porch": {
|
|
185
|
+
"consultation": {
|
|
186
|
+
"models": ["gemini", "codex", "claude"],
|
|
187
|
+
"byProtocol": { "pir": { "models": ["gemini", "codex"] } }
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`["gemini", "codex"]` is PIR's own shipped pair, so this restores exactly what the protocol declares
|
|
194
|
+
rather than substituting a different two. SPIR and ASPIR reviews run three lanes; PIR runs two.
|
|
195
|
+
Without the `byProtocol` entry, PIR would run three and cost 50% more per review with no change to
|
|
196
|
+
the protocol file.
|
|
197
|
+
|
|
198
|
+
### The fail-fast contract, and where it stops
|
|
199
|
+
|
|
200
|
+
Config errors are raised when config is **loaded** — before any consultation starts — and name the
|
|
201
|
+
offending key and the valid alternatives. Nothing falls back to a default on error.
|
|
202
|
+
|
|
203
|
+
**The asymmetry worth knowing about:** these two are validated very differently.
|
|
204
|
+
|
|
205
|
+
| | Validated by | When you find out |
|
|
206
|
+
|---|---|---|
|
|
207
|
+
| `reasoningEffort` | **Codev**, against a closed enum | Config load, before anything runs |
|
|
208
|
+
| Model ids | **The provider** | When the lane runs |
|
|
209
|
+
|
|
210
|
+
Codev checks a model id's *syntax* only (ASCII alphanumerics plus `. _ : / @ + -`, 1–200 characters,
|
|
211
|
+
no leading punctuation) — never its existence. **There is no allowlist of model ids anywhere in
|
|
212
|
+
Codev, by design**: a new model must work the day the provider ships it, without a Codev release.
|
|
213
|
+
|
|
214
|
+
So a typo'd model id is not caught at config time. It reaches the backend, which rejects it; that
|
|
215
|
+
lane exits non-zero, the provider's error text is surfaced, the config key that supplied the id is
|
|
216
|
+
named, and **no review file is written** — so porch cannot advance on a lane that never ran. What
|
|
217
|
+
you do *not* get is a silent substitution of the default model.
|
|
218
|
+
|
|
219
|
+
One deliberate exception: a `gemini` lane **with no model id resolved** still skips non-blockingly
|
|
220
|
+
when `agy` is missing or unauthenticated (consultation is best-effort there). Once an id *is*
|
|
221
|
+
resolved — from either `consult.models.gemini` **or** `--model-id` — a rejected model becomes a hard
|
|
222
|
+
failure for that lane, because you asked for a specific model and did not get it. What still skips
|
|
223
|
+
rather than fails, even with an id, are causes that are not the model's fault: `agy` absent,
|
|
224
|
+
unauthenticated, timed out, killed by a signal, or exiting **successfully** having produced no
|
|
225
|
+
output at all.
|
|
26
226
|
|
|
27
227
|
## Modes
|
|
28
228
|
|
|
@@ -78,10 +278,11 @@ consult -m codex --type integration --issue 42 --base ci
|
|
|
78
278
|
- `--base <ref>` — **`--type integration` only.** Anchor the diff on this base branch (e.g. `ci`), computed locally as `git diff origin/<base>...origin/<head>` (three-dot, merge-base anchored). Use in repos with a long-lived integration branch ahead of the default branch so the review sees only the PR's actual change, not the whole integration-over-trunk delta. Unresolvable refs fail loudly with a `git fetch` hint (no silent fallback to the local checkout). Defaults to config `consult.integrationBranch`; with neither set, the integration review uses the PR's host-recorded base (`gh pr diff`), unchanged.
|
|
79
279
|
|
|
80
280
|
**Config (`.codev/config.json`):**
|
|
81
|
-
|
|
281
|
+
`integrationBranch` is the repo-wide default base for `--type integration`, overridden by `--base`.
|
|
282
|
+
|
|
283
|
+
```json
|
|
82
284
|
{
|
|
83
285
|
"consult": {
|
|
84
|
-
// Repo-wide default base for `--type integration` (overridden by --base).
|
|
85
286
|
"integrationBranch": "ci"
|
|
86
287
|
}
|
|
87
288
|
}
|
|
@@ -196,6 +397,33 @@ through to a normal spawn.
|
|
|
196
397
|
| `CODEV_AGY_AUTH_CACHE_DIR` | `~/.cache/codev` | Cache location (mainly for tests). |
|
|
197
398
|
| `CODEV_AGY_AUTH_CACHE_DISABLE` | unset | `1` restores the always-spawn behaviour. |
|
|
198
399
|
|
|
400
|
+
#### Test isolation
|
|
401
|
+
|
|
402
|
+
The cache above protects *production* runs. It did not protect test runs: the
|
|
403
|
+
cache disables itself under `VITEST` unless a cache directory is named, and any
|
|
404
|
+
test that reached the gemini lane without pinning `CODEV_AGY_BIN` resolved the
|
|
405
|
+
real binary — so a suite run could still open a login window per spawn (#1323).
|
|
406
|
+
Consult now treats a test runner as a hard boundary. Under `VITEST` (or
|
|
407
|
+
`CODEV_TEST_ISOLATION`) it refuses to resolve an unpinned `agy` and refuses to open the
|
|
408
|
+
user-global metrics database, failing loudly instead of reaching either. Codev's
|
|
409
|
+
own suites pin a fake `agy`, a sandbox auth cache, and a sandbox metrics DB for
|
|
410
|
+
every test; spawned `codev` / `consult` children inherit the pins through the
|
|
411
|
+
environment.
|
|
412
|
+
|
|
413
|
+
| Variable | Default | Purpose |
|
|
414
|
+
|---|---|---|
|
|
415
|
+
| `CODEV_AGY_BIN` | auto-resolved | Pin the agy binary. The harness sets this to a fake for every test. |
|
|
416
|
+
| `CODEV_ALLOW_REAL_AGY` | unset | `1` opts a test run into the REAL agy binary — the guarded integration smoke and real-AI e2e runs. Expect a browser window if agy's login has lapsed. |
|
|
417
|
+
| `CODEV_METRICS_DB` | `~/.codev/metrics.db` | Redirect the consult metrics database. Required under a test runner; the harness points it at a temp dir so suite runs stop skewing `consult stats`. |
|
|
418
|
+
| `CODEV_TEST_ISOLATION` | unset | `1` applies the same guards to a harness that is not vitest. |
|
|
419
|
+
|
|
420
|
+
**Adopters:** `VITEST` is exported by *any* vitest run, including yours. If your
|
|
421
|
+
project's own suite deliberately shells out to `consult -m gemini`, that call now
|
|
422
|
+
throws until you set `CODEV_ALLOW_REAL_AGY=1` (and `CODEV_METRICS_DB` if you want
|
|
423
|
+
the metrics recorded somewhere). This is intentional — a suite reaching the real
|
|
424
|
+
agy is what #1323 was about — but it is a behaviour change, not a silent one: the
|
|
425
|
+
error names the variable to set.
|
|
426
|
+
|
|
199
427
|
### Claude auth: subscription vs. metered API
|
|
200
428
|
|
|
201
429
|
`consult -m claude` runs on the Claude Agent SDK. When `CLAUDE_CODE_OAUTH_TOKEN`
|
|
@@ -59,6 +59,7 @@ See [codev.md](codev.md) for full documentation.
|
|
|
59
59
|
| `afx status` | Show status of all agents |
|
|
60
60
|
| `afx cleanup` | Clean up a builder worktree |
|
|
61
61
|
| `afx send` | Send instructions to a builder |
|
|
62
|
+
| `afx inbox` | List/show/dismiss held (undelivered) messages |
|
|
62
63
|
| `afx open` | Open file annotation viewer |
|
|
63
64
|
| `afx shell` | Spawn a utility shell |
|
|
64
65
|
| `afx tower` | Cross-project dashboard |
|