@cluesmith/codev 2.0.0-rc.7 → 2.0.0-rc.71
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/bin/af.js +2 -2
- package/bin/consult.js +1 -1
- package/bin/porch.js +6 -35
- package/dashboard/dist/assets/index-C7FtNK6Y.css +32 -0
- package/dashboard/dist/assets/index-CDAINZKT.js +131 -0
- package/dashboard/dist/assets/index-CDAINZKT.js.map +1 -0
- package/dashboard/dist/index.html +14 -0
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +173 -118
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/architect.d.ts +3 -3
- package/dist/agent-farm/commands/architect.d.ts.map +1 -1
- package/dist/agent-farm/commands/architect.js +20 -147
- package/dist/agent-farm/commands/architect.js.map +1 -1
- package/dist/agent-farm/commands/attach.d.ts +13 -0
- package/dist/agent-farm/commands/attach.d.ts.map +1 -0
- package/dist/agent-farm/commands/attach.js +144 -0
- package/dist/agent-farm/commands/attach.js.map +1 -0
- package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
- package/dist/agent-farm/commands/cleanup.js +35 -19
- package/dist/agent-farm/commands/cleanup.js.map +1 -1
- package/dist/agent-farm/commands/consult.d.ts +3 -4
- package/dist/agent-farm/commands/consult.d.ts.map +1 -1
- package/dist/agent-farm/commands/consult.js +27 -37
- package/dist/agent-farm/commands/consult.js.map +1 -1
- package/dist/agent-farm/commands/index.d.ts +2 -2
- package/dist/agent-farm/commands/index.d.ts.map +1 -1
- package/dist/agent-farm/commands/index.js +2 -2
- package/dist/agent-farm/commands/index.js.map +1 -1
- package/dist/agent-farm/commands/open.d.ts +4 -2
- package/dist/agent-farm/commands/open.d.ts.map +1 -1
- package/dist/agent-farm/commands/open.js +33 -83
- package/dist/agent-farm/commands/open.js.map +1 -1
- package/dist/agent-farm/commands/send.d.ts +1 -1
- package/dist/agent-farm/commands/send.d.ts.map +1 -1
- package/dist/agent-farm/commands/send.js +60 -79
- package/dist/agent-farm/commands/send.js.map +1 -1
- package/dist/agent-farm/commands/shell.d.ts +15 -0
- package/dist/agent-farm/commands/shell.d.ts.map +1 -0
- package/dist/agent-farm/commands/shell.js +50 -0
- package/dist/agent-farm/commands/shell.js.map +1 -0
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +597 -281
- package/dist/agent-farm/commands/spawn.js.map +1 -1
- package/dist/agent-farm/commands/start.d.ts +10 -20
- package/dist/agent-farm/commands/start.d.ts.map +1 -1
- package/dist/agent-farm/commands/start.js +45 -491
- package/dist/agent-farm/commands/start.js.map +1 -1
- package/dist/agent-farm/commands/status.d.ts +2 -0
- package/dist/agent-farm/commands/status.d.ts.map +1 -1
- package/dist/agent-farm/commands/status.js +75 -24
- package/dist/agent-farm/commands/status.js.map +1 -1
- package/dist/agent-farm/commands/stop.d.ts +6 -0
- package/dist/agent-farm/commands/stop.d.ts.map +1 -1
- package/dist/agent-farm/commands/stop.js +49 -109
- package/dist/agent-farm/commands/stop.js.map +1 -1
- package/dist/agent-farm/commands/tower-cloud.d.ts +48 -0
- package/dist/agent-farm/commands/tower-cloud.d.ts.map +1 -0
- package/dist/agent-farm/commands/tower-cloud.js +329 -0
- package/dist/agent-farm/commands/tower-cloud.js.map +1 -0
- package/dist/agent-farm/commands/tower.d.ts +9 -0
- package/dist/agent-farm/commands/tower.d.ts.map +1 -1
- package/dist/agent-farm/commands/tower.js +59 -19
- package/dist/agent-farm/commands/tower.js.map +1 -1
- package/dist/agent-farm/db/index.d.ts +6 -2
- package/dist/agent-farm/db/index.d.ts.map +1 -1
- package/dist/agent-farm/db/index.js +246 -18
- package/dist/agent-farm/db/index.js.map +1 -1
- package/dist/agent-farm/db/migrate.d.ts +0 -4
- package/dist/agent-farm/db/migrate.d.ts.map +1 -1
- package/dist/agent-farm/db/migrate.js +6 -55
- package/dist/agent-farm/db/migrate.js.map +1 -1
- package/dist/agent-farm/db/schema.d.ts +3 -3
- package/dist/agent-farm/db/schema.d.ts.map +1 -1
- package/dist/agent-farm/db/schema.js +25 -19
- package/dist/agent-farm/db/schema.js.map +1 -1
- package/dist/agent-farm/db/types.d.ts +3 -13
- package/dist/agent-farm/db/types.d.ts.map +1 -1
- package/dist/agent-farm/db/types.js +3 -11
- package/dist/agent-farm/db/types.js.map +1 -1
- package/dist/agent-farm/hq-connector.d.ts +2 -6
- package/dist/agent-farm/hq-connector.d.ts.map +1 -1
- package/dist/agent-farm/hq-connector.js +2 -17
- package/dist/agent-farm/hq-connector.js.map +1 -1
- package/dist/agent-farm/lib/cloud-config.d.ts +59 -0
- package/dist/agent-farm/lib/cloud-config.d.ts.map +1 -0
- package/dist/agent-farm/lib/cloud-config.js +143 -0
- package/dist/agent-farm/lib/cloud-config.js.map +1 -0
- package/dist/agent-farm/lib/tower-client.d.ts +163 -0
- package/dist/agent-farm/lib/tower-client.d.ts.map +1 -0
- package/dist/agent-farm/lib/tower-client.js +233 -0
- package/dist/agent-farm/lib/tower-client.js.map +1 -0
- package/dist/agent-farm/lib/tunnel-client.d.ts +117 -0
- package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -0
- package/dist/agent-farm/lib/tunnel-client.js +504 -0
- package/dist/agent-farm/lib/tunnel-client.js.map +1 -0
- package/dist/agent-farm/servers/tower-server.js +2653 -185
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/agent-farm/state.d.ts +6 -12
- package/dist/agent-farm/state.d.ts.map +1 -1
- package/dist/agent-farm/state.js +34 -49
- package/dist/agent-farm/state.js.map +1 -1
- package/dist/agent-farm/types.d.ts +49 -26
- package/dist/agent-farm/types.d.ts.map +1 -1
- package/dist/agent-farm/utils/config.d.ts +0 -5
- package/dist/agent-farm/utils/config.d.ts.map +1 -1
- package/dist/agent-farm/utils/config.js +12 -44
- package/dist/agent-farm/utils/config.js.map +1 -1
- package/dist/agent-farm/utils/deps.d.ts.map +1 -1
- package/dist/agent-farm/utils/deps.js +0 -32
- package/dist/agent-farm/utils/deps.js.map +1 -1
- package/dist/agent-farm/utils/file-tabs.d.ts +27 -0
- package/dist/agent-farm/utils/file-tabs.d.ts.map +1 -0
- package/dist/agent-farm/utils/file-tabs.js +46 -0
- package/dist/agent-farm/utils/file-tabs.js.map +1 -0
- package/dist/agent-farm/utils/gate-status.d.ts +16 -0
- package/dist/agent-farm/utils/gate-status.d.ts.map +1 -0
- package/dist/agent-farm/utils/gate-status.js +79 -0
- package/dist/agent-farm/utils/gate-status.js.map +1 -0
- package/dist/agent-farm/utils/gate-watcher.d.ts +38 -0
- package/dist/agent-farm/utils/gate-watcher.d.ts.map +1 -0
- package/dist/agent-farm/utils/gate-watcher.js +122 -0
- package/dist/agent-farm/utils/gate-watcher.js.map +1 -0
- package/dist/agent-farm/utils/index.d.ts +0 -1
- package/dist/agent-farm/utils/index.d.ts.map +1 -1
- package/dist/agent-farm/utils/index.js +0 -1
- package/dist/agent-farm/utils/index.js.map +1 -1
- package/dist/agent-farm/utils/notifications.d.ts +30 -0
- package/dist/agent-farm/utils/notifications.d.ts.map +1 -0
- package/dist/agent-farm/utils/notifications.js +121 -0
- package/dist/agent-farm/utils/notifications.js.map +1 -0
- package/dist/agent-farm/utils/server-utils.d.ts +5 -5
- package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
- package/dist/agent-farm/utils/server-utils.js +5 -16
- package/dist/agent-farm/utils/server-utils.js.map +1 -1
- package/dist/agent-farm/utils/session.d.ts +32 -0
- package/dist/agent-farm/utils/session.d.ts.map +1 -0
- package/dist/agent-farm/utils/session.js +57 -0
- package/dist/agent-farm/utils/session.js.map +1 -0
- package/dist/agent-farm/utils/shell.d.ts +9 -22
- package/dist/agent-farm/utils/shell.d.ts.map +1 -1
- package/dist/agent-farm/utils/shell.js +34 -34
- package/dist/agent-farm/utils/shell.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +11 -54
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt.d.ts.map +1 -1
- package/dist/commands/adopt.js +49 -4
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/consult/index.d.ts +13 -2
- package/dist/commands/consult/index.d.ts.map +1 -1
- package/dist/commands/consult/index.js +245 -29
- package/dist/commands/consult/index.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +96 -79
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +41 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/porch/build-counter.d.ts +5 -0
- package/dist/commands/porch/build-counter.d.ts.map +1 -0
- package/dist/commands/porch/build-counter.js +5 -0
- package/dist/commands/porch/build-counter.js.map +1 -0
- package/dist/commands/porch/checks.d.ts +17 -29
- package/dist/commands/porch/checks.d.ts.map +1 -1
- package/dist/commands/porch/checks.js +96 -144
- package/dist/commands/porch/checks.js.map +1 -1
- package/dist/commands/porch/index.d.ts +25 -43
- package/dist/commands/porch/index.d.ts.map +1 -1
- package/dist/commands/porch/index.js +463 -1116
- package/dist/commands/porch/index.js.map +1 -1
- package/dist/commands/porch/next.d.ts +22 -0
- package/dist/commands/porch/next.d.ts.map +1 -0
- package/dist/commands/porch/next.js +571 -0
- package/dist/commands/porch/next.js.map +1 -0
- package/dist/commands/porch/plan.d.ts +70 -0
- package/dist/commands/porch/plan.d.ts.map +1 -0
- package/dist/commands/porch/plan.js +190 -0
- package/dist/commands/porch/plan.js.map +1 -0
- package/dist/commands/porch/prompts.d.ts +19 -0
- package/dist/commands/porch/prompts.d.ts.map +1 -0
- package/dist/commands/porch/prompts.js +277 -0
- package/dist/commands/porch/prompts.js.map +1 -0
- package/dist/commands/porch/protocol.d.ts +59 -0
- package/dist/commands/porch/protocol.d.ts.map +1 -0
- package/dist/commands/porch/protocol.js +294 -0
- package/dist/commands/porch/protocol.js.map +1 -0
- package/dist/commands/porch/state.d.ts +36 -107
- package/dist/commands/porch/state.d.ts.map +1 -1
- package/dist/commands/porch/state.js +120 -699
- package/dist/commands/porch/state.js.map +1 -1
- package/dist/commands/porch/types.d.ts +99 -164
- package/dist/commands/porch/types.d.ts.map +1 -1
- package/dist/commands/porch/types.js +2 -1
- package/dist/commands/porch/types.js.map +1 -1
- package/dist/commands/porch/verdict.d.ts +31 -0
- package/dist/commands/porch/verdict.d.ts.map +1 -0
- package/dist/commands/porch/verdict.js +59 -0
- package/dist/commands/porch/verdict.js.map +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +31 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/lib/scaffold.d.ts +37 -0
- package/dist/lib/scaffold.d.ts.map +1 -1
- package/dist/lib/scaffold.js +114 -0
- package/dist/lib/scaffold.js.map +1 -1
- package/dist/terminal/index.d.ts +8 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +5 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/pty-manager.d.ts +69 -0
- package/dist/terminal/pty-manager.d.ts.map +1 -0
- package/dist/terminal/pty-manager.js +377 -0
- package/dist/terminal/pty-manager.js.map +1 -0
- package/dist/terminal/pty-session.d.ts +104 -0
- package/dist/terminal/pty-session.d.ts.map +1 -0
- package/dist/terminal/pty-session.js +327 -0
- package/dist/terminal/pty-session.js.map +1 -0
- package/dist/terminal/ring-buffer.d.ts +34 -0
- package/dist/terminal/ring-buffer.d.ts.map +1 -0
- package/dist/terminal/ring-buffer.js +94 -0
- package/dist/terminal/ring-buffer.js.map +1 -0
- package/dist/terminal/session-manager.d.ts +115 -0
- package/dist/terminal/session-manager.d.ts.map +1 -0
- package/dist/terminal/session-manager.js +582 -0
- package/dist/terminal/session-manager.js.map +1 -0
- package/dist/terminal/shepherd-client.d.ts +66 -0
- package/dist/terminal/shepherd-client.d.ts.map +1 -0
- package/dist/terminal/shepherd-client.js +234 -0
- package/dist/terminal/shepherd-client.js.map +1 -0
- package/dist/terminal/shepherd-main.d.ts +19 -0
- package/dist/terminal/shepherd-main.d.ts.map +1 -0
- package/dist/terminal/shepherd-main.js +153 -0
- package/dist/terminal/shepherd-main.js.map +1 -0
- package/dist/terminal/shepherd-process.d.ts +75 -0
- package/dist/terminal/shepherd-process.d.ts.map +1 -0
- package/dist/terminal/shepherd-process.js +279 -0
- package/dist/terminal/shepherd-process.js.map +1 -0
- package/dist/terminal/shepherd-protocol.d.ts +115 -0
- package/dist/terminal/shepherd-protocol.d.ts.map +1 -0
- package/dist/terminal/shepherd-protocol.js +214 -0
- package/dist/terminal/shepherd-protocol.js.map +1 -0
- package/dist/terminal/shepherd-replay-buffer.d.ts +38 -0
- package/dist/terminal/shepherd-replay-buffer.d.ts.map +1 -0
- package/dist/terminal/shepherd-replay-buffer.js +94 -0
- package/dist/terminal/shepherd-replay-buffer.js.map +1 -0
- package/dist/terminal/ws-protocol.d.ts +27 -0
- package/dist/terminal/ws-protocol.d.ts.map +1 -0
- package/dist/terminal/ws-protocol.js +44 -0
- package/dist/terminal/ws-protocol.js.map +1 -0
- package/package.json +19 -5
- package/skeleton/.claude/skills/af/SKILL.md +89 -0
- package/skeleton/.claude/skills/codev/SKILL.md +41 -0
- package/skeleton/.claude/skills/consult/SKILL.md +81 -0
- package/skeleton/.claude/skills/generate-image/SKILL.md +56 -0
- package/skeleton/DEPENDENCIES.md +4 -62
- package/skeleton/builders.md +1 -1
- package/skeleton/consult-types/impl-review.md +18 -9
- package/skeleton/consult-types/integration-review.md +1 -1
- package/skeleton/consult-types/plan-review.md +1 -1
- package/skeleton/consult-types/pr-ready.md +1 -1
- package/skeleton/consult-types/spec-review.md +1 -1
- package/skeleton/porch/prompts/defend.md +1 -1
- package/skeleton/porch/prompts/evaluate.md +2 -2
- package/skeleton/porch/prompts/implement.md +1 -1
- package/skeleton/porch/prompts/plan.md +1 -1
- package/skeleton/porch/prompts/review.md +4 -4
- package/skeleton/porch/prompts/specify.md +1 -1
- package/skeleton/porch/prompts/understand.md +2 -2
- package/skeleton/protocol-schema.json +282 -0
- package/skeleton/protocols/bugfix/builder-prompt.md +54 -0
- package/skeleton/protocols/bugfix/prompts/fix.md +77 -0
- package/skeleton/protocols/bugfix/prompts/investigate.md +77 -0
- package/skeleton/protocols/bugfix/prompts/pr.md +84 -0
- package/skeleton/protocols/bugfix/protocol.json +20 -33
- package/skeleton/protocols/experiment/builder-prompt.md +52 -0
- package/skeleton/protocols/experiment/protocol.json +101 -0
- package/skeleton/protocols/experiment/protocol.md +3 -3
- package/skeleton/protocols/experiment/templates/notes.md +1 -1
- package/skeleton/protocols/maintain/builder-prompt.md +46 -0
- package/skeleton/protocols/maintain/prompts/audit.md +111 -0
- package/skeleton/protocols/maintain/prompts/clean.md +91 -0
- package/skeleton/protocols/maintain/prompts/sync.md +113 -0
- package/skeleton/protocols/maintain/prompts/verify.md +110 -0
- package/skeleton/protocols/maintain/protocol.json +141 -0
- package/skeleton/protocols/maintain/protocol.md +17 -11
- package/skeleton/protocols/protocol-schema.json +54 -1
- package/skeleton/protocols/spir/builder-prompt.md +59 -0
- package/skeleton/protocols/spir/prompts/implement.md +208 -0
- package/skeleton/protocols/{spider → spir}/prompts/plan.md +6 -70
- package/skeleton/protocols/{spider → spir}/prompts/review.md +20 -39
- package/skeleton/protocols/{spider → spir}/prompts/specify.md +33 -61
- package/skeleton/protocols/spir/protocol.json +156 -0
- package/skeleton/protocols/{spider → spir}/protocol.md +35 -21
- package/skeleton/protocols/{spider → spir}/templates/plan.md +14 -0
- package/skeleton/protocols/spir/templates/review.md +89 -0
- package/skeleton/protocols/tick/builder-prompt.md +56 -0
- package/skeleton/protocols/tick/protocol.json +7 -2
- package/skeleton/protocols/tick/protocol.md +18 -18
- package/skeleton/protocols/tick/templates/review.md +1 -1
- package/skeleton/resources/commands/agent-farm.md +63 -46
- package/skeleton/resources/commands/codev.md +0 -2
- package/skeleton/resources/commands/overview.md +7 -17
- package/skeleton/resources/workflow-reference.md +4 -4
- package/skeleton/roles/architect.md +152 -315
- package/skeleton/roles/builder.md +110 -218
- package/skeleton/roles/consultant.md +6 -6
- package/skeleton/templates/AGENTS.md +2 -2
- package/skeleton/templates/CLAUDE.md +2 -2
- package/skeleton/templates/cheatsheet.md +7 -5
- package/skeleton/templates/projectlist.md +1 -1
- package/templates/dashboard/index.html +17 -43
- package/templates/dashboard/js/dialogs.js +7 -7
- package/templates/dashboard/js/files.js +2 -2
- package/templates/dashboard/js/main.js +4 -4
- package/templates/dashboard/js/projects.js +3 -3
- package/templates/dashboard/js/tabs.js +1 -1
- package/templates/dashboard/js/utils.js +22 -87
- package/templates/open.html +26 -0
- package/templates/tower.html +642 -36
- package/dist/agent-farm/commands/kickoff.d.ts +0 -20
- package/dist/agent-farm/commands/kickoff.d.ts.map +0 -1
- package/dist/agent-farm/commands/kickoff.js +0 -337
- package/dist/agent-farm/commands/kickoff.js.map +0 -1
- package/dist/agent-farm/commands/rename.d.ts +0 -13
- package/dist/agent-farm/commands/rename.d.ts.map +0 -1
- package/dist/agent-farm/commands/rename.js +0 -33
- package/dist/agent-farm/commands/rename.js.map +0 -1
- package/dist/agent-farm/commands/tutorial.d.ts +0 -10
- package/dist/agent-farm/commands/tutorial.d.ts.map +0 -1
- package/dist/agent-farm/commands/tutorial.js +0 -49
- package/dist/agent-farm/commands/tutorial.js.map +0 -1
- package/dist/agent-farm/commands/util.d.ts +0 -15
- package/dist/agent-farm/commands/util.d.ts.map +0 -1
- package/dist/agent-farm/commands/util.js +0 -108
- package/dist/agent-farm/commands/util.js.map +0 -1
- package/dist/agent-farm/servers/dashboard-server.d.ts +0 -7
- package/dist/agent-farm/servers/dashboard-server.d.ts.map +0 -1
- package/dist/agent-farm/servers/dashboard-server.js +0 -1872
- package/dist/agent-farm/servers/dashboard-server.js.map +0 -1
- package/dist/agent-farm/servers/open-server.d.ts +0 -7
- package/dist/agent-farm/servers/open-server.d.ts.map +0 -1
- package/dist/agent-farm/servers/open-server.js +0 -315
- package/dist/agent-farm/servers/open-server.js.map +0 -1
- package/dist/agent-farm/tutorial/index.d.ts +0 -8
- package/dist/agent-farm/tutorial/index.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/index.js +0 -8
- package/dist/agent-farm/tutorial/index.js.map +0 -1
- package/dist/agent-farm/tutorial/prompts.d.ts +0 -57
- package/dist/agent-farm/tutorial/prompts.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/prompts.js +0 -147
- package/dist/agent-farm/tutorial/prompts.js.map +0 -1
- package/dist/agent-farm/tutorial/runner.d.ts +0 -52
- package/dist/agent-farm/tutorial/runner.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/runner.js +0 -204
- package/dist/agent-farm/tutorial/runner.js.map +0 -1
- package/dist/agent-farm/tutorial/state.d.ts +0 -26
- package/dist/agent-farm/tutorial/state.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/state.js +0 -89
- package/dist/agent-farm/tutorial/state.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/first-spec.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/first-spec.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/first-spec.js +0 -136
- package/dist/agent-farm/tutorial/steps/first-spec.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/implementation.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/implementation.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/implementation.js +0 -76
- package/dist/agent-farm/tutorial/steps/implementation.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/index.d.ts +0 -10
- package/dist/agent-farm/tutorial/steps/index.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/index.js +0 -10
- package/dist/agent-farm/tutorial/steps/index.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/planning.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/planning.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/planning.js +0 -143
- package/dist/agent-farm/tutorial/steps/planning.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/review.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/review.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/review.js +0 -78
- package/dist/agent-farm/tutorial/steps/review.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/setup.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/setup.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/setup.js +0 -126
- package/dist/agent-farm/tutorial/steps/setup.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/welcome.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/welcome.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/welcome.js +0 -50
- package/dist/agent-farm/tutorial/steps/welcome.js.map +0 -1
- package/dist/agent-farm/utils/orphan-handler.d.ts +0 -27
- package/dist/agent-farm/utils/orphan-handler.d.ts.map +0 -1
- package/dist/agent-farm/utils/orphan-handler.js +0 -149
- package/dist/agent-farm/utils/orphan-handler.js.map +0 -1
- package/dist/agent-farm/utils/port-registry.d.ts +0 -58
- package/dist/agent-farm/utils/port-registry.d.ts.map +0 -1
- package/dist/agent-farm/utils/port-registry.js +0 -166
- package/dist/agent-farm/utils/port-registry.js.map +0 -1
- package/dist/agent-farm/utils/terminal-ports.d.ts +0 -18
- package/dist/agent-farm/utils/terminal-ports.d.ts.map +0 -1
- package/dist/agent-farm/utils/terminal-ports.js +0 -35
- package/dist/agent-farm/utils/terminal-ports.js.map +0 -1
- package/dist/commands/pcheck/cache.d.ts +0 -48
- package/dist/commands/pcheck/cache.d.ts.map +0 -1
- package/dist/commands/pcheck/cache.js +0 -170
- package/dist/commands/pcheck/cache.js.map +0 -1
- package/dist/commands/pcheck/evaluator.d.ts +0 -15
- package/dist/commands/pcheck/evaluator.d.ts.map +0 -1
- package/dist/commands/pcheck/evaluator.js +0 -246
- package/dist/commands/pcheck/evaluator.js.map +0 -1
- package/dist/commands/pcheck/index.d.ts +0 -12
- package/dist/commands/pcheck/index.d.ts.map +0 -1
- package/dist/commands/pcheck/index.js +0 -249
- package/dist/commands/pcheck/index.js.map +0 -1
- package/dist/commands/pcheck/parser.d.ts +0 -39
- package/dist/commands/pcheck/parser.d.ts.map +0 -1
- package/dist/commands/pcheck/parser.js +0 -155
- package/dist/commands/pcheck/parser.js.map +0 -1
- package/dist/commands/pcheck/types.d.ts +0 -82
- package/dist/commands/pcheck/types.d.ts.map +0 -1
- package/dist/commands/pcheck/types.js +0 -5
- package/dist/commands/pcheck/types.js.map +0 -1
- package/dist/commands/porch/consultation.d.ts +0 -56
- package/dist/commands/porch/consultation.d.ts.map +0 -1
- package/dist/commands/porch/consultation.js +0 -330
- package/dist/commands/porch/consultation.js.map +0 -1
- package/dist/commands/porch/notifications.d.ts +0 -99
- package/dist/commands/porch/notifications.d.ts.map +0 -1
- package/dist/commands/porch/notifications.js +0 -223
- package/dist/commands/porch/notifications.js.map +0 -1
- package/dist/commands/porch/plan-parser.d.ts +0 -38
- package/dist/commands/porch/plan-parser.d.ts.map +0 -1
- package/dist/commands/porch/plan-parser.js +0 -166
- package/dist/commands/porch/plan-parser.js.map +0 -1
- package/dist/commands/porch/protocol-loader.d.ts +0 -46
- package/dist/commands/porch/protocol-loader.d.ts.map +0 -1
- package/dist/commands/porch/protocol-loader.js +0 -253
- package/dist/commands/porch/protocol-loader.js.map +0 -1
- package/dist/commands/porch/signal-parser.d.ts +0 -88
- package/dist/commands/porch/signal-parser.d.ts.map +0 -1
- package/dist/commands/porch/signal-parser.js +0 -148
- package/dist/commands/porch/signal-parser.js.map +0 -1
- package/dist/commands/tower.d.ts +0 -16
- package/dist/commands/tower.d.ts.map +0 -1
- package/dist/commands/tower.js +0 -21
- package/dist/commands/tower.js.map +0 -1
- package/skeleton/config.json +0 -7
- package/skeleton/porch/protocols/bugfix.json +0 -85
- package/skeleton/porch/protocols/spider.json +0 -135
- package/skeleton/porch/protocols/tick.json +0 -76
- package/skeleton/protocols/spider/prompts/defend.md +0 -215
- package/skeleton/protocols/spider/prompts/evaluate.md +0 -241
- package/skeleton/protocols/spider/prompts/implement.md +0 -149
- package/skeleton/protocols/spider/protocol.json +0 -210
- package/skeleton/protocols/spider/templates/review.md +0 -207
- package/templates/dashboard/css/activity.css +0 -151
- package/templates/dashboard/js/activity.js +0 -112
- /package/skeleton/protocols/{spider → spir}/templates/spec.md +0 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec 0100: Gate watcher for detecting gate transitions and sending af send notifications.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which gates have been notified (dedup) and sends `af send architect`
|
|
5
|
+
* messages when new gates appear. Uses a dual-map design:
|
|
6
|
+
* - notified: Map<key, timestamp> for dedup
|
|
7
|
+
* - projectKeys: Map<projectPath, Set<key>> for clearing on gate resolution
|
|
8
|
+
*/
|
|
9
|
+
import { execFile } from 'node:child_process';
|
|
10
|
+
import { resolve, dirname } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
// Strip ANSI escape sequences
|
|
13
|
+
const ANSI_RE = /\x1B\[[0-9;]*[A-Za-z]/g;
|
|
14
|
+
// Reject control characters that could be injected
|
|
15
|
+
const CONTROL_CHAR_RE = /[;\n\r]/;
|
|
16
|
+
/**
|
|
17
|
+
* Sanitize a string for use in af send messages.
|
|
18
|
+
* Returns null if the value contains unsafe control characters.
|
|
19
|
+
*/
|
|
20
|
+
function sanitize(value) {
|
|
21
|
+
const stripped = value.replace(ANSI_RE, '').trim();
|
|
22
|
+
if (!stripped || CONTROL_CHAR_RE.test(stripped))
|
|
23
|
+
return null;
|
|
24
|
+
return stripped;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the path to the `af` CLI binary.
|
|
28
|
+
* Works from both source (src/) and compiled (dist/) contexts.
|
|
29
|
+
*/
|
|
30
|
+
function resolveAfBinary() {
|
|
31
|
+
// From dist/agent-farm/utils/gate-watcher.js → bin/af.js
|
|
32
|
+
// From src/agent-farm/utils/gate-watcher.ts → bin/af.js
|
|
33
|
+
const thisDir = typeof __dirname !== 'undefined'
|
|
34
|
+
? __dirname
|
|
35
|
+
: dirname(fileURLToPath(import.meta.url));
|
|
36
|
+
// thisDir = .../packages/codev/dist/agent-farm/utils or .../src/agent-farm/utils
|
|
37
|
+
// Navigate up to packages/codev/bin/af.js
|
|
38
|
+
return resolve(thisDir, '../../../bin/af.js');
|
|
39
|
+
}
|
|
40
|
+
export class GateWatcher {
|
|
41
|
+
/** Dedup map: key -> ISO timestamp of first notification */
|
|
42
|
+
notified = new Map();
|
|
43
|
+
/** Index: projectPath -> set of keys in `notified` */
|
|
44
|
+
projectKeys = new Map();
|
|
45
|
+
/** Logger function */
|
|
46
|
+
log;
|
|
47
|
+
/** Path to af binary */
|
|
48
|
+
afBinary;
|
|
49
|
+
constructor(log, afBinary) {
|
|
50
|
+
this.log = log;
|
|
51
|
+
this.afBinary = afBinary ?? resolveAfBinary();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check gate status for a project and send notification if it's a new gate.
|
|
55
|
+
*/
|
|
56
|
+
async checkAndNotify(gateStatus, projectPath) {
|
|
57
|
+
if (!gateStatus.hasGate) {
|
|
58
|
+
// Gate resolved — clear all entries for this project
|
|
59
|
+
this.clearProject(projectPath);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const { builderId, gateName } = gateStatus;
|
|
63
|
+
if (!builderId || !gateName)
|
|
64
|
+
return;
|
|
65
|
+
const key = `${projectPath}:${builderId}:${gateName}`;
|
|
66
|
+
// Already notified for this exact gate
|
|
67
|
+
if (this.notified.has(key))
|
|
68
|
+
return;
|
|
69
|
+
// Gate changed for this project — clear old entries, add new one
|
|
70
|
+
this.clearProject(projectPath);
|
|
71
|
+
this.notified.set(key, new Date().toISOString());
|
|
72
|
+
const keys = new Set();
|
|
73
|
+
keys.add(key);
|
|
74
|
+
this.projectKeys.set(projectPath, keys);
|
|
75
|
+
// Sanitize before sending
|
|
76
|
+
const safeBuilderId = sanitize(builderId);
|
|
77
|
+
const safeGateName = sanitize(gateName);
|
|
78
|
+
if (!safeBuilderId || !safeGateName) {
|
|
79
|
+
this.log('WARN', `Gate watcher: skipping af send — unsafe gateName or builderId for project ${projectPath}`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const message = [
|
|
83
|
+
`GATE: ${safeGateName} (Builder ${safeBuilderId})`,
|
|
84
|
+
`Builder ${safeBuilderId} is waiting for approval.`,
|
|
85
|
+
`Run: porch approve ${safeBuilderId} ${safeGateName}`,
|
|
86
|
+
].join('\n');
|
|
87
|
+
await this.sendToArchitect(message, projectPath);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Clear all tracked keys for a project.
|
|
91
|
+
*/
|
|
92
|
+
clearProject(projectPath) {
|
|
93
|
+
const keys = this.projectKeys.get(projectPath);
|
|
94
|
+
if (keys) {
|
|
95
|
+
for (const k of keys) {
|
|
96
|
+
this.notified.delete(k);
|
|
97
|
+
}
|
|
98
|
+
this.projectKeys.delete(projectPath);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Send a message to the architect via af send.
|
|
103
|
+
*/
|
|
104
|
+
sendToArchitect(message, projectPath) {
|
|
105
|
+
return new Promise((resolve) => {
|
|
106
|
+
execFile(process.execPath, [this.afBinary, 'send', 'architect', message, '--raw', '--no-enter'], { cwd: projectPath, timeout: 10_000 }, (error) => {
|
|
107
|
+
if (error) {
|
|
108
|
+
this.log('WARN', `Gate watcher: af send failed for ${projectPath}: ${error.message}`);
|
|
109
|
+
}
|
|
110
|
+
resolve();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Reset all state (useful for testing).
|
|
116
|
+
*/
|
|
117
|
+
reset() {
|
|
118
|
+
this.notified.clear();
|
|
119
|
+
this.projectKeys.clear();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=gate-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-watcher.js","sourceRoot":"","sources":["../../../src/agent-farm/utils/gate-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent-farm/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent-farm/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push notification utilities for porch events.
|
|
3
|
+
* Sends notifications to the tower dashboard for real-time updates.
|
|
4
|
+
*/
|
|
5
|
+
export type NotificationType = 'gate' | 'blocked' | 'error' | 'info';
|
|
6
|
+
interface NotificationPayload {
|
|
7
|
+
type: NotificationType;
|
|
8
|
+
projectPath: string;
|
|
9
|
+
projectId: string;
|
|
10
|
+
details: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Send a push notification to the tower dashboard.
|
|
14
|
+
* Notifications are delivered via SSE to connected browsers.
|
|
15
|
+
*/
|
|
16
|
+
export declare function sendPushNotification(payload: NotificationPayload): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Send notification when a gate is hit.
|
|
19
|
+
*/
|
|
20
|
+
export declare function notifyGateHit(projectRoot: string, projectId: string, gateName: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Send notification when builder is blocked.
|
|
23
|
+
*/
|
|
24
|
+
export declare function notifyBlocked(projectRoot: string, projectId: string, reason: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Send notification when build fails.
|
|
27
|
+
*/
|
|
28
|
+
export declare function notifyError(projectRoot: string, projectId: string, error: string): Promise<void>;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=notifications.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/utils/notifications.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAErE,UAAU,mBAAmB;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AA+BD;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDtF;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAYf"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push notification utilities for porch events.
|
|
3
|
+
* Sends notifications to the tower dashboard for real-time updates.
|
|
4
|
+
*/
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
// Default tower port
|
|
7
|
+
const TOWER_PORT = process.env.CODEV_TOWER_PORT || '4100';
|
|
8
|
+
// Track sent notifications to avoid duplicates within short window
|
|
9
|
+
const recentNotifications = new Map();
|
|
10
|
+
const DEDUPE_WINDOW_MS = 60000; // 1 minute
|
|
11
|
+
function isDuplicate(key) {
|
|
12
|
+
const lastSent = recentNotifications.get(key);
|
|
13
|
+
if (lastSent && Date.now() - lastSent < DEDUPE_WINDOW_MS) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
recentNotifications.set(key, Date.now());
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get canonical project path from worktree path.
|
|
21
|
+
* Builder worktrees are at: <project>/.builders/<id>/<branch>
|
|
22
|
+
* Porch runs in these worktrees but notifications need the canonical path.
|
|
23
|
+
*/
|
|
24
|
+
function getCanonicalProjectPath(cwd) {
|
|
25
|
+
const builderMatch = cwd.match(/^(.+)\/.builders\/[^/]+$/);
|
|
26
|
+
if (builderMatch) {
|
|
27
|
+
return builderMatch[1]; // Return canonical project root
|
|
28
|
+
}
|
|
29
|
+
return cwd;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Send a push notification to the tower dashboard.
|
|
33
|
+
* Notifications are delivered via SSE to connected browsers.
|
|
34
|
+
*/
|
|
35
|
+
export async function sendPushNotification(payload) {
|
|
36
|
+
// Dedupe by project + type + details
|
|
37
|
+
const dedupeKey = `${payload.projectPath}:${payload.type}:${payload.details}`;
|
|
38
|
+
if (isDuplicate(dedupeKey)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const projectName = path.basename(payload.projectPath);
|
|
42
|
+
let title;
|
|
43
|
+
let body;
|
|
44
|
+
switch (payload.type) {
|
|
45
|
+
case 'gate':
|
|
46
|
+
title = `${projectName}: Gate ${payload.details}`;
|
|
47
|
+
body = `Project ${payload.projectId} needs approval`;
|
|
48
|
+
break;
|
|
49
|
+
case 'blocked':
|
|
50
|
+
title = `${projectName}: Builder Blocked`;
|
|
51
|
+
body = `${payload.projectId}: ${payload.details}`;
|
|
52
|
+
break;
|
|
53
|
+
case 'error':
|
|
54
|
+
title = `${projectName}: Build Failed`;
|
|
55
|
+
body = `${payload.projectId}: ${payload.details}`;
|
|
56
|
+
break;
|
|
57
|
+
case 'info':
|
|
58
|
+
default:
|
|
59
|
+
title = `${projectName}`;
|
|
60
|
+
body = payload.details;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const response = await fetch(`http://localhost:${TOWER_PORT}/api/notify`, {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: {
|
|
67
|
+
'Content-Type': 'application/json',
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify({
|
|
70
|
+
type: payload.type,
|
|
71
|
+
title,
|
|
72
|
+
body,
|
|
73
|
+
project: payload.projectPath,
|
|
74
|
+
}),
|
|
75
|
+
});
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
console.warn(`[notifications] Tower responded ${response.status} for ${payload.type} notification (project ${payload.projectId})`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Tower may not be running - silently ignore
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Send notification when a gate is hit.
|
|
86
|
+
*/
|
|
87
|
+
export async function notifyGateHit(projectRoot, projectId, gateName) {
|
|
88
|
+
await sendPushNotification({
|
|
89
|
+
type: 'gate',
|
|
90
|
+
projectPath: getCanonicalProjectPath(projectRoot),
|
|
91
|
+
projectId,
|
|
92
|
+
details: gateName,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Send notification when builder is blocked.
|
|
97
|
+
*/
|
|
98
|
+
export async function notifyBlocked(projectRoot, projectId, reason) {
|
|
99
|
+
await sendPushNotification({
|
|
100
|
+
type: 'blocked',
|
|
101
|
+
projectPath: getCanonicalProjectPath(projectRoot),
|
|
102
|
+
projectId,
|
|
103
|
+
details: reason,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Send notification when build fails.
|
|
108
|
+
*/
|
|
109
|
+
export async function notifyError(projectRoot, projectId, error) {
|
|
110
|
+
// Only send if CODEV_PUSH_ERRORS is enabled
|
|
111
|
+
if (process.env.CODEV_PUSH_ERRORS !== 'true') {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
await sendPushNotification({
|
|
115
|
+
type: 'error',
|
|
116
|
+
projectPath: getCanonicalProjectPath(projectRoot),
|
|
117
|
+
projectId,
|
|
118
|
+
details: error,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=notifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../../src/agent-farm/utils/notifications.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared server utilities
|
|
3
|
-
* Extracted from
|
|
3
|
+
* Extracted from tower-server.ts and open-server.ts
|
|
4
4
|
* to eliminate code duplication (Maintenance Run 0004)
|
|
5
5
|
*/
|
|
6
6
|
import type * as http from 'node:http';
|
|
@@ -15,10 +15,10 @@ export declare function escapeHtml(str: string): string;
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function parseJsonBody(req: http.IncomingMessage, maxSize?: number): Promise<Record<string, unknown>>;
|
|
17
17
|
/**
|
|
18
|
-
* Security: Validate request origin
|
|
19
|
-
*
|
|
18
|
+
* Security: Validate request origin
|
|
19
|
+
* Currently allows all requests - security is handled by the server binding to localhost only.
|
|
20
20
|
* @param req - HTTP incoming message
|
|
21
|
-
* @returns true
|
|
21
|
+
* @returns true (always allowed)
|
|
22
22
|
*/
|
|
23
|
-
export declare function isRequestAllowed(
|
|
23
|
+
export declare function isRequestAllowed(_req: http.IncomingMessage): boolean;
|
|
24
24
|
//# sourceMappingURL=server-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-utils.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/utils/server-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,SAAc,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAyBhH;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"server-utils.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/utils/server-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,SAAc,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAyBhH;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,GAAG,OAAO,CAEpE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared server utilities
|
|
3
|
-
* Extracted from
|
|
3
|
+
* Extracted from tower-server.ts and open-server.ts
|
|
4
4
|
* to eliminate code duplication (Maintenance Run 0004)
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
@@ -44,23 +44,12 @@ export function parseJsonBody(req, maxSize = 1024 * 1024) {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
* Security: Validate request origin
|
|
48
|
-
*
|
|
47
|
+
* Security: Validate request origin
|
|
48
|
+
* Currently allows all requests - security is handled by the server binding to localhost only.
|
|
49
49
|
* @param req - HTTP incoming message
|
|
50
|
-
* @returns true
|
|
50
|
+
* @returns true (always allowed)
|
|
51
51
|
*/
|
|
52
|
-
export function isRequestAllowed(
|
|
53
|
-
const host = req.headers.host;
|
|
54
|
-
const origin = req.headers.origin;
|
|
55
|
-
// Host check (prevent DNS rebinding attacks)
|
|
56
|
-
if (host && !host.startsWith('localhost') && !host.startsWith('127.0.0.1')) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
// Origin check (prevent CSRF from external sites)
|
|
60
|
-
// Note: CLI tools/curl might not send Origin, so we only block if Origin is present and invalid
|
|
61
|
-
if (origin && !origin.startsWith('http://localhost') && !origin.startsWith('http://127.0.0.1')) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
52
|
+
export function isRequestAllowed(_req) {
|
|
64
53
|
return true;
|
|
65
54
|
}
|
|
66
55
|
//# sourceMappingURL=server-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-utils.js","sourceRoot":"","sources":["../../../src/agent-farm/utils/server-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAyB,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI;IAC5E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,IAAI,GAAG,CAAC,CAAC;QAEb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YACrB,IAAI,IAAI,GAAG,OAAO,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;gBAC5C,GAAG,CAAC,OAAO,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"server-utils.js","sourceRoot":"","sources":["../../../src/agent-farm/utils/server-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAyB,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI;IAC5E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,IAAI,GAAG,CAAC,CAAC;QAEb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YACrB,IAAI,IAAI,GAAG,OAAO,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;gBAC5C,GAAG,CAAC,OAAO,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA0B;IACzD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared session-naming utilities for Agent Farm.
|
|
3
|
+
* Centralizes session name generation to prevent drift between commands.
|
|
4
|
+
*/
|
|
5
|
+
import type { Config } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Get a namespaced session name for a builder: builder-{project}-{id}
|
|
8
|
+
*/
|
|
9
|
+
export declare function getBuilderSessionName(config: Config, builderId: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Parsed metadata from a session name.
|
|
12
|
+
* Our naming convention: architect-{basename}, builder-{basename}-{specId}, shell-{basename}-{shellId}
|
|
13
|
+
*/
|
|
14
|
+
export interface ParsedSession {
|
|
15
|
+
type: 'architect' | 'builder' | 'shell';
|
|
16
|
+
projectBasename: string;
|
|
17
|
+
roleId: string | null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse a codev session name to extract type, project, and role.
|
|
21
|
+
* Returns null if the name doesn't match any known codev pattern.
|
|
22
|
+
*
|
|
23
|
+
* Examples:
|
|
24
|
+
* "architect-codev-public" → { type: 'architect', projectBasename: 'codev-public', roleId: null }
|
|
25
|
+
* "builder-codevos_ai-0001" → { type: 'builder', projectBasename: 'codevos_ai', roleId: '0001' }
|
|
26
|
+
* "builder-codev-public-bugfix-242" → { type: 'builder', projectBasename: 'codev-public', roleId: 'bugfix-242' }
|
|
27
|
+
* "builder-codev-public-task-AbCd" → { type: 'builder', projectBasename: 'codev-public', roleId: 'task-AbCd' }
|
|
28
|
+
* "builder-codev-public-worktree-QwEr" → { type: 'builder', projectBasename: 'codev-public', roleId: 'worktree-QwEr' }
|
|
29
|
+
* "shell-codev-public-shell-1" → { type: 'shell', projectBasename: 'codev-public', roleId: 'shell-1' }
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseSessionName(name: string): ParsedSession | null;
|
|
32
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/utils/session.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IACxC,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAsCnE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared session-naming utilities for Agent Farm.
|
|
3
|
+
* Centralizes session name generation to prevent drift between commands.
|
|
4
|
+
*/
|
|
5
|
+
import { basename } from 'node:path';
|
|
6
|
+
/**
|
|
7
|
+
* Get a namespaced session name for a builder: builder-{project}-{id}
|
|
8
|
+
*/
|
|
9
|
+
export function getBuilderSessionName(config, builderId) {
|
|
10
|
+
return `builder-${basename(config.projectRoot)}-${builderId}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Parse a codev session name to extract type, project, and role.
|
|
14
|
+
* Returns null if the name doesn't match any known codev pattern.
|
|
15
|
+
*
|
|
16
|
+
* Examples:
|
|
17
|
+
* "architect-codev-public" → { type: 'architect', projectBasename: 'codev-public', roleId: null }
|
|
18
|
+
* "builder-codevos_ai-0001" → { type: 'builder', projectBasename: 'codevos_ai', roleId: '0001' }
|
|
19
|
+
* "builder-codev-public-bugfix-242" → { type: 'builder', projectBasename: 'codev-public', roleId: 'bugfix-242' }
|
|
20
|
+
* "builder-codev-public-task-AbCd" → { type: 'builder', projectBasename: 'codev-public', roleId: 'task-AbCd' }
|
|
21
|
+
* "builder-codev-public-worktree-QwEr" → { type: 'builder', projectBasename: 'codev-public', roleId: 'worktree-QwEr' }
|
|
22
|
+
* "shell-codev-public-shell-1" → { type: 'shell', projectBasename: 'codev-public', roleId: 'shell-1' }
|
|
23
|
+
*/
|
|
24
|
+
export function parseSessionName(name) {
|
|
25
|
+
// architect-{basename}
|
|
26
|
+
const architectMatch = name.match(/^architect-(.+)$/);
|
|
27
|
+
if (architectMatch) {
|
|
28
|
+
return { type: 'architect', projectBasename: architectMatch[1], roleId: null };
|
|
29
|
+
}
|
|
30
|
+
// builder-{basename}-bugfix-{N} — bugfix builder (issue number)
|
|
31
|
+
const bugfixMatch = name.match(/^builder-(.+)-(bugfix-\d+)$/);
|
|
32
|
+
if (bugfixMatch) {
|
|
33
|
+
return { type: 'builder', projectBasename: bugfixMatch[1], roleId: bugfixMatch[2] };
|
|
34
|
+
}
|
|
35
|
+
// builder-{basename}-task-{shortId} — ad-hoc task builder (shortId is URL-safe base64: a-zA-Z0-9_-)
|
|
36
|
+
const taskMatch = name.match(/^builder-(.+)-(task-[a-zA-Z0-9_-]+)$/);
|
|
37
|
+
if (taskMatch) {
|
|
38
|
+
return { type: 'builder', projectBasename: taskMatch[1], roleId: taskMatch[2] };
|
|
39
|
+
}
|
|
40
|
+
// builder-{basename}-worktree-{shortId} — generic worktree builder (shortId is URL-safe base64)
|
|
41
|
+
const worktreeMatch = name.match(/^builder-(.+)-(worktree-[a-zA-Z0-9_-]+)$/);
|
|
42
|
+
if (worktreeMatch) {
|
|
43
|
+
return { type: 'builder', projectBasename: worktreeMatch[1], roleId: worktreeMatch[2] };
|
|
44
|
+
}
|
|
45
|
+
// builder-{basename}-{specId} — SPIR builder (spec ID is digits, any length)
|
|
46
|
+
const builderMatch = name.match(/^builder-(.+)-(\d+)$/);
|
|
47
|
+
if (builderMatch) {
|
|
48
|
+
return { type: 'builder', projectBasename: builderMatch[1], roleId: builderMatch[2] };
|
|
49
|
+
}
|
|
50
|
+
// shell-{basename}-{shellId} — shellId is "shell-N" (last two segments)
|
|
51
|
+
const shellMatch = name.match(/^shell-(.+)-(shell-\d+)$/);
|
|
52
|
+
if (shellMatch) {
|
|
53
|
+
return { type: 'shell', projectBasename: shellMatch[1], roleId: shellMatch[2] };
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/agent-farm/utils/session.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,SAAiB;IACrE,OAAO,WAAW,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,SAAS,EAAE,CAAC;AAChE,CAAC;AAYD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,uBAAuB;IACvB,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtD,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACjF,CAAC;IAED,gEAAgE;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC9D,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACtF,CAAC;IAED,oGAAoG;IACpG,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACrE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,CAAC;IAED,gGAAgG;IAChG,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC7E,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1F,CAAC;IAED,6EAA6E;IAC7E,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACxD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,CAAC;IAED,wEAAwE;IACxE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC1D,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -20,6 +20,7 @@ export declare function run(command: string, options?: {
|
|
|
20
20
|
export declare function spawnDetached(command: string, args: string[], options?: {
|
|
21
21
|
cwd?: string;
|
|
22
22
|
logFile?: string;
|
|
23
|
+
env?: NodeJS.ProcessEnv;
|
|
23
24
|
}): ChildProcess;
|
|
24
25
|
/**
|
|
25
26
|
* Check if a command exists
|
|
@@ -36,32 +37,18 @@ export declare function findAvailablePort(startPort: number): Promise<number>;
|
|
|
36
37
|
*/
|
|
37
38
|
export declare function isProcessRunning(pid: number): Promise<boolean>;
|
|
38
39
|
/**
|
|
39
|
-
* Kill a process
|
|
40
|
+
* Kill a single process with SIGTERM → wait → SIGKILL escalation.
|
|
41
|
+
* Does NOT walk the process tree — safe for shepherd/session processes
|
|
42
|
+
* where tree-kill could kill siblings across projects.
|
|
40
43
|
*/
|
|
41
44
|
export declare function killProcess(pid: number): Promise<void>;
|
|
42
45
|
/**
|
|
43
|
-
*
|
|
46
|
+
* Kill a process tree (all children). Use for annotation servers and
|
|
47
|
+
* dashboard servers where children must also die.
|
|
44
48
|
*/
|
|
45
|
-
export declare function
|
|
46
|
-
export interface TtydOptions {
|
|
47
|
-
/** Port to run ttyd on */
|
|
48
|
-
port: number;
|
|
49
|
-
/** tmux session name to attach to (REQUIRED - prevents attaching to wrong session) */
|
|
50
|
-
sessionName: string;
|
|
51
|
-
/** Working directory */
|
|
52
|
-
cwd?: string;
|
|
53
|
-
/** Custom index.html path for ttyd */
|
|
54
|
-
customIndexPath?: string;
|
|
55
|
-
/** Bind host (default: localhost, use 0.0.0.0 for remote access) */
|
|
56
|
-
bindHost?: string;
|
|
57
|
-
}
|
|
49
|
+
export declare function killProcessTree(pid: number): Promise<void>;
|
|
58
50
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* IMPORTANT: Always specify sessionName to prevent ttyd from attaching
|
|
62
|
-
* to the wrong tmux session. This has caused cross-project issues.
|
|
63
|
-
*
|
|
64
|
-
* @returns The spawned child process, or null if spawn failed
|
|
51
|
+
* Open a URL in the default browser
|
|
65
52
|
*/
|
|
66
|
-
export declare function
|
|
53
|
+
export declare function openBrowser(url: string): Promise<void>;
|
|
67
54
|
//# sourceMappingURL=shell.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/utils/shell.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKpE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,GAAG,CACvB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,OAAO,CAAC,UAAU,CAAC,CAgBrB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/utils/shell.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKpE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,GAAG,CACvB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,OAAO,CAAC,UAAU,CAAC,CAgBrB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,GACxE,YAAY,CA+Cd;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYrE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB1E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOpE;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5D;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAehE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5D"}
|
|
@@ -29,10 +29,12 @@ export async function run(command, options = {}) {
|
|
|
29
29
|
*/
|
|
30
30
|
export function spawnDetached(command, args, options = {}) {
|
|
31
31
|
// Always capture stderr for error reporting, even when not logging
|
|
32
|
+
// Explicitly pass environment to ensure CODEV_WEB_KEY etc. are inherited
|
|
32
33
|
const child = spawn(command, args, {
|
|
33
34
|
cwd: options.cwd,
|
|
34
35
|
detached: true,
|
|
35
36
|
stdio: ['ignore', 'pipe', 'pipe'], // Always capture stdout/stderr
|
|
37
|
+
env: options.env || process.env,
|
|
36
38
|
});
|
|
37
39
|
// Buffer stderr for error reporting (keeps last 4KB)
|
|
38
40
|
let stderrBuffer = '';
|
|
@@ -122,14 +124,44 @@ export async function isProcessRunning(pid) {
|
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
/**
|
|
125
|
-
* Kill a process
|
|
127
|
+
* Kill a single process with SIGTERM → wait → SIGKILL escalation.
|
|
128
|
+
* Does NOT walk the process tree — safe for shepherd/session processes
|
|
129
|
+
* where tree-kill could kill siblings across projects.
|
|
126
130
|
*/
|
|
127
131
|
export async function killProcess(pid) {
|
|
132
|
+
// Send SIGTERM
|
|
133
|
+
try {
|
|
134
|
+
process.kill(pid, 'SIGTERM');
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
if (err.code === 'ESRCH')
|
|
138
|
+
return; // already gone
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
// Wait up to 3s for process to exit, then escalate to SIGKILL
|
|
142
|
+
for (let i = 0; i < 6; i++) {
|
|
143
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
144
|
+
if (!(await isProcessRunning(pid)))
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
process.kill(pid, 'SIGKILL');
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
if (err.code === 'ESRCH')
|
|
152
|
+
return;
|
|
153
|
+
throw err;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Kill a process tree (all children). Use for annotation servers and
|
|
158
|
+
* dashboard servers where children must also die.
|
|
159
|
+
*/
|
|
160
|
+
export async function killProcessTree(pid) {
|
|
128
161
|
const treeKill = (await import('tree-kill')).default;
|
|
129
162
|
return new Promise((resolve, reject) => {
|
|
130
163
|
treeKill(pid, 'SIGTERM', (err) => {
|
|
131
164
|
if (err) {
|
|
132
|
-
// Try SIGKILL if SIGTERM fails
|
|
133
165
|
treeKill(pid, 'SIGKILL', (err2) => {
|
|
134
166
|
if (err2)
|
|
135
167
|
reject(err2);
|
|
@@ -150,36 +182,4 @@ export async function openBrowser(url) {
|
|
|
150
182
|
const open = (await import('open')).default;
|
|
151
183
|
await open(url);
|
|
152
184
|
}
|
|
153
|
-
/**
|
|
154
|
-
* Spawn ttyd attached to a specific tmux session.
|
|
155
|
-
*
|
|
156
|
-
* IMPORTANT: Always specify sessionName to prevent ttyd from attaching
|
|
157
|
-
* to the wrong tmux session. This has caused cross-project issues.
|
|
158
|
-
*
|
|
159
|
-
* @returns The spawned child process, or null if spawn failed
|
|
160
|
-
*/
|
|
161
|
-
export function spawnTtyd(options) {
|
|
162
|
-
const { port, sessionName, cwd, customIndexPath, bindHost } = options;
|
|
163
|
-
const ttydArgs = [
|
|
164
|
-
'-W',
|
|
165
|
-
'-p', String(port),
|
|
166
|
-
'-t', 'theme={"background":"#000000"}',
|
|
167
|
-
'-t', 'rightClickSelectsWord=true',
|
|
168
|
-
];
|
|
169
|
-
// Add bind interface if specified (default is localhost)
|
|
170
|
-
if (bindHost) {
|
|
171
|
-
ttydArgs.push('-i', bindHost);
|
|
172
|
-
}
|
|
173
|
-
// Add custom index if provided and exists
|
|
174
|
-
if (customIndexPath) {
|
|
175
|
-
ttydArgs.push('-I', customIndexPath);
|
|
176
|
-
}
|
|
177
|
-
// CRITICAL: Always specify the session name to prevent attaching to wrong session
|
|
178
|
-
ttydArgs.push('tmux', 'attach-session', '-t', sessionName);
|
|
179
|
-
const child = spawnDetached('ttyd', ttydArgs, { cwd });
|
|
180
|
-
if (!child.pid) {
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
return child;
|
|
184
|
-
}
|
|
185
185
|
//# sourceMappingURL=shell.js.map
|