@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,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single PTY session: wraps node-pty with ring buffer, disk logging,
|
|
3
|
+
* WebSocket broadcast, and reconnection support.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { EventEmitter } from 'node:events';
|
|
8
|
+
import { RingBuffer } from './ring-buffer.js';
|
|
9
|
+
export class PtySession extends EventEmitter {
|
|
10
|
+
config;
|
|
11
|
+
id;
|
|
12
|
+
label;
|
|
13
|
+
createdAt;
|
|
14
|
+
ringBuffer;
|
|
15
|
+
pty = null;
|
|
16
|
+
shepherdClient = null;
|
|
17
|
+
_shepherdBacked = false;
|
|
18
|
+
_shepherdSessionId = null;
|
|
19
|
+
shepherdPid = -1;
|
|
20
|
+
cols;
|
|
21
|
+
rows;
|
|
22
|
+
exitCode;
|
|
23
|
+
logFd = null;
|
|
24
|
+
logBytes = 0;
|
|
25
|
+
logPath;
|
|
26
|
+
diskLogEnabled;
|
|
27
|
+
diskLogMaxBytes;
|
|
28
|
+
reconnectTimeoutMs;
|
|
29
|
+
disconnectTimer = null;
|
|
30
|
+
clients = new Set();
|
|
31
|
+
constructor(config) {
|
|
32
|
+
super();
|
|
33
|
+
this.config = config;
|
|
34
|
+
this.id = config.id;
|
|
35
|
+
this.label = config.label;
|
|
36
|
+
this.cols = config.cols;
|
|
37
|
+
this.rows = config.rows;
|
|
38
|
+
this.createdAt = new Date().toISOString();
|
|
39
|
+
this.ringBuffer = new RingBuffer(config.ringBufferLines ?? 1000);
|
|
40
|
+
this.diskLogEnabled = config.diskLogEnabled ?? true;
|
|
41
|
+
this.diskLogMaxBytes = config.diskLogMaxBytes ?? 50 * 1024 * 1024;
|
|
42
|
+
this.reconnectTimeoutMs = config.reconnectTimeoutMs ?? 300_000;
|
|
43
|
+
this.logPath = path.join(config.logDir, `${config.id}.log`);
|
|
44
|
+
}
|
|
45
|
+
/** Spawn the PTY process. Must be called after construction. */
|
|
46
|
+
async spawn() {
|
|
47
|
+
// Dynamic import to avoid hard dependency at module level
|
|
48
|
+
const nodePty = await import('node-pty');
|
|
49
|
+
// Ensure log directory exists
|
|
50
|
+
if (this.diskLogEnabled) {
|
|
51
|
+
fs.mkdirSync(path.dirname(this.logPath), { recursive: true });
|
|
52
|
+
this.logFd = fs.openSync(this.logPath, 'a');
|
|
53
|
+
}
|
|
54
|
+
this.pty = nodePty.spawn(this.config.command, this.config.args, {
|
|
55
|
+
name: 'xterm-256color',
|
|
56
|
+
cols: this.cols,
|
|
57
|
+
rows: this.rows,
|
|
58
|
+
cwd: this.config.cwd,
|
|
59
|
+
env: this.config.env,
|
|
60
|
+
});
|
|
61
|
+
this.pty.onData((data) => {
|
|
62
|
+
this.onPtyData(data);
|
|
63
|
+
});
|
|
64
|
+
this.pty.onExit(({ exitCode }) => {
|
|
65
|
+
this.exitCode = exitCode;
|
|
66
|
+
this.emit('exit', exitCode);
|
|
67
|
+
this.cleanup();
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Attach a shepherd client as the I/O backend instead of node-pty.
|
|
72
|
+
* Data flows: shepherd → ring buffer → WebSocket clients.
|
|
73
|
+
* User input flows: WebSocket → write() → shepherd.
|
|
74
|
+
*/
|
|
75
|
+
attachShepherd(client, replayData, shepherdPid, shepherdSessionId) {
|
|
76
|
+
this._shepherdBacked = true;
|
|
77
|
+
this.shepherdClient = client;
|
|
78
|
+
this.shepherdPid = shepherdPid;
|
|
79
|
+
this._shepherdSessionId = shepherdSessionId ?? null;
|
|
80
|
+
// Ensure log directory exists
|
|
81
|
+
if (this.diskLogEnabled) {
|
|
82
|
+
fs.mkdirSync(path.dirname(this.logPath), { recursive: true });
|
|
83
|
+
this.logFd = fs.openSync(this.logPath, 'a');
|
|
84
|
+
}
|
|
85
|
+
// Populate ring buffer with replay data from shepherd
|
|
86
|
+
if (replayData.length > 0) {
|
|
87
|
+
this.ringBuffer.pushData(replayData.toString('utf-8'));
|
|
88
|
+
}
|
|
89
|
+
// Forward shepherd data to ring buffer + WebSocket clients
|
|
90
|
+
client.on('data', (buf) => {
|
|
91
|
+
this.onPtyData(buf.toString('utf-8'));
|
|
92
|
+
});
|
|
93
|
+
// Handle shepherd exit (process inside shepherd exited)
|
|
94
|
+
client.on('exit', (exitInfo) => {
|
|
95
|
+
this.exitCode = exitInfo.code;
|
|
96
|
+
this.emit('exit', exitInfo.code);
|
|
97
|
+
// For shepherd-backed sessions, cleanup closes disk log and clients
|
|
98
|
+
// but doesn't clear the ring buffer (shepherd may still have replay data)
|
|
99
|
+
this.cleanupShepherd();
|
|
100
|
+
});
|
|
101
|
+
// Handle shepherd disconnect (socket closed without EXIT)
|
|
102
|
+
client.on('close', () => {
|
|
103
|
+
if (this.exitCode === undefined) {
|
|
104
|
+
// Unexpected disconnect — shepherd may have crashed
|
|
105
|
+
this.exitCode = -1;
|
|
106
|
+
this.emit('exit', -1);
|
|
107
|
+
this.cleanupShepherd();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/** Whether this session is backed by a shepherd process. */
|
|
112
|
+
get shepherdBacked() {
|
|
113
|
+
return this._shepherdBacked;
|
|
114
|
+
}
|
|
115
|
+
/** The SessionManager session ID for this shepherd-backed session, or null. */
|
|
116
|
+
get shepherdSessionId() {
|
|
117
|
+
return this._shepherdSessionId;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Detach from shepherd client during Tower shutdown.
|
|
121
|
+
* Removes all event listeners so that SessionManager.shutdown() disconnecting
|
|
122
|
+
* the client doesn't cascade into exit events and SQLite row deletion.
|
|
123
|
+
*/
|
|
124
|
+
detachShepherd() {
|
|
125
|
+
if (this.shepherdClient) {
|
|
126
|
+
this.shepherdClient.removeAllListeners();
|
|
127
|
+
this.shepherdClient = null;
|
|
128
|
+
}
|
|
129
|
+
this.cleanupShepherd();
|
|
130
|
+
}
|
|
131
|
+
cleanupShepherd() {
|
|
132
|
+
if (this.disconnectTimer) {
|
|
133
|
+
clearTimeout(this.disconnectTimer);
|
|
134
|
+
this.disconnectTimer = null;
|
|
135
|
+
}
|
|
136
|
+
this.clients.clear();
|
|
137
|
+
// Close disk log handle
|
|
138
|
+
if (this.logFd !== null) {
|
|
139
|
+
try {
|
|
140
|
+
fs.closeSync(this.logFd);
|
|
141
|
+
}
|
|
142
|
+
catch { /* ignore */ }
|
|
143
|
+
this.logFd = null;
|
|
144
|
+
}
|
|
145
|
+
// Note: ring buffer is NOT cleared — shepherd handles replay
|
|
146
|
+
// Note: shepherd client is NOT disconnected — SessionManager owns that lifecycle
|
|
147
|
+
}
|
|
148
|
+
onPtyData(data) {
|
|
149
|
+
// Store in ring buffer
|
|
150
|
+
this.ringBuffer.pushData(data);
|
|
151
|
+
// Write to disk log
|
|
152
|
+
if (this.diskLogEnabled && this.logFd !== null) {
|
|
153
|
+
const buf = Buffer.from(data, 'utf-8');
|
|
154
|
+
if (this.logBytes + buf.length <= this.diskLogMaxBytes) {
|
|
155
|
+
fs.writeSync(this.logFd, buf);
|
|
156
|
+
this.logBytes += buf.length;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
this.rotateDiskLog();
|
|
160
|
+
fs.writeSync(this.logFd, buf);
|
|
161
|
+
this.logBytes = buf.length;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Broadcast to all connected WebSocket clients
|
|
165
|
+
for (const client of this.clients) {
|
|
166
|
+
try {
|
|
167
|
+
client.send(data);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
this.clients.delete(client);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
this.emit('data', data);
|
|
174
|
+
}
|
|
175
|
+
rotateDiskLog() {
|
|
176
|
+
if (this.logFd !== null) {
|
|
177
|
+
fs.closeSync(this.logFd);
|
|
178
|
+
}
|
|
179
|
+
const rotatedPath = this.logPath + '.1';
|
|
180
|
+
// Remove old rotation if exists
|
|
181
|
+
try {
|
|
182
|
+
fs.unlinkSync(rotatedPath + '.1');
|
|
183
|
+
}
|
|
184
|
+
catch { /* ignore */ }
|
|
185
|
+
try {
|
|
186
|
+
fs.renameSync(rotatedPath, rotatedPath + '.1');
|
|
187
|
+
}
|
|
188
|
+
catch { /* ignore */ }
|
|
189
|
+
try {
|
|
190
|
+
fs.renameSync(this.logPath, rotatedPath);
|
|
191
|
+
}
|
|
192
|
+
catch { /* ignore */ }
|
|
193
|
+
this.logFd = fs.openSync(this.logPath, 'a');
|
|
194
|
+
this.logBytes = 0;
|
|
195
|
+
}
|
|
196
|
+
/** Write user input to the PTY or shepherd. */
|
|
197
|
+
write(data) {
|
|
198
|
+
if (this._shepherdBacked) {
|
|
199
|
+
if (this.shepherdClient && this.status === 'running') {
|
|
200
|
+
this.shepherdClient.write(data);
|
|
201
|
+
}
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (this.pty && this.status === 'running') {
|
|
205
|
+
this.pty.write(data);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** Resize the PTY or shepherd. */
|
|
209
|
+
resize(cols, rows) {
|
|
210
|
+
this.cols = cols;
|
|
211
|
+
this.rows = rows;
|
|
212
|
+
if (this._shepherdBacked) {
|
|
213
|
+
if (this.shepherdClient && this.status === 'running') {
|
|
214
|
+
this.shepherdClient.resize(cols, rows);
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (this.pty && this.status === 'running') {
|
|
219
|
+
this.pty.resize(cols, rows);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/** Kill the PTY process or send signal to shepherd. */
|
|
223
|
+
kill() {
|
|
224
|
+
if (this._shepherdBacked) {
|
|
225
|
+
if (this.shepherdClient && this.status === 'running') {
|
|
226
|
+
this.shepherdClient.signal(15); // SIGTERM
|
|
227
|
+
}
|
|
228
|
+
this.cleanupShepherd();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (this.pty && this.status === 'running') {
|
|
232
|
+
try {
|
|
233
|
+
// Kill process group to prevent orphans
|
|
234
|
+
process.kill(-this.pty.pid, 'SIGTERM');
|
|
235
|
+
setTimeout(() => {
|
|
236
|
+
try {
|
|
237
|
+
process.kill(-this.pty.pid, 'SIGKILL');
|
|
238
|
+
}
|
|
239
|
+
catch { /* already dead */ }
|
|
240
|
+
}, 5000);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// Process already exited
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
this.cleanup();
|
|
247
|
+
}
|
|
248
|
+
/** Attach a WebSocket client. Returns ring buffer contents for replay. */
|
|
249
|
+
attach(client) {
|
|
250
|
+
this.clients.add(client);
|
|
251
|
+
if (this.disconnectTimer) {
|
|
252
|
+
clearTimeout(this.disconnectTimer);
|
|
253
|
+
this.disconnectTimer = null;
|
|
254
|
+
}
|
|
255
|
+
return this.ringBuffer.getAll();
|
|
256
|
+
}
|
|
257
|
+
/** Attach with resume from a specific sequence number. */
|
|
258
|
+
attachResume(client, sinceSeq) {
|
|
259
|
+
this.clients.add(client);
|
|
260
|
+
if (this.disconnectTimer) {
|
|
261
|
+
clearTimeout(this.disconnectTimer);
|
|
262
|
+
this.disconnectTimer = null;
|
|
263
|
+
}
|
|
264
|
+
return this.ringBuffer.getSince(sinceSeq);
|
|
265
|
+
}
|
|
266
|
+
/** Detach a WebSocket client. Starts disconnect timer if no clients remain (non-shepherd only). */
|
|
267
|
+
detach(client) {
|
|
268
|
+
this.clients.delete(client);
|
|
269
|
+
// Shepherd-backed sessions don't need a disconnect timer — the shepherd
|
|
270
|
+
// keeps the process alive independently of WebSocket connections.
|
|
271
|
+
if (this._shepherdBacked)
|
|
272
|
+
return;
|
|
273
|
+
if (this.clients.size === 0 && this.status === 'running') {
|
|
274
|
+
this.disconnectTimer = setTimeout(() => {
|
|
275
|
+
this.emit('timeout');
|
|
276
|
+
this.kill();
|
|
277
|
+
}, this.reconnectTimeoutMs);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/** Working directory of the PTY session. */
|
|
281
|
+
get cwd() {
|
|
282
|
+
return this.config.cwd;
|
|
283
|
+
}
|
|
284
|
+
get status() {
|
|
285
|
+
return this.exitCode === undefined ? 'running' : 'exited';
|
|
286
|
+
}
|
|
287
|
+
get pid() {
|
|
288
|
+
if (this._shepherdBacked)
|
|
289
|
+
return this.shepherdPid;
|
|
290
|
+
return this.pty?.pid ?? -1;
|
|
291
|
+
}
|
|
292
|
+
get info() {
|
|
293
|
+
return {
|
|
294
|
+
id: this.id,
|
|
295
|
+
pid: this.pid,
|
|
296
|
+
cols: this.cols,
|
|
297
|
+
rows: this.rows,
|
|
298
|
+
label: this.label,
|
|
299
|
+
status: this.status,
|
|
300
|
+
createdAt: this.createdAt,
|
|
301
|
+
exitCode: this.exitCode,
|
|
302
|
+
persistent: this._shepherdBacked,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
get clientCount() {
|
|
306
|
+
return this.clients.size;
|
|
307
|
+
}
|
|
308
|
+
cleanup() {
|
|
309
|
+
if (this.disconnectTimer) {
|
|
310
|
+
clearTimeout(this.disconnectTimer);
|
|
311
|
+
this.disconnectTimer = null;
|
|
312
|
+
}
|
|
313
|
+
// Release all WebSocket clients
|
|
314
|
+
this.clients.clear();
|
|
315
|
+
// Release ring buffer memory
|
|
316
|
+
this.ringBuffer.clear();
|
|
317
|
+
// Close disk log handle
|
|
318
|
+
if (this.logFd !== null) {
|
|
319
|
+
try {
|
|
320
|
+
fs.closeSync(this.logFd);
|
|
321
|
+
}
|
|
322
|
+
catch { /* ignore */ }
|
|
323
|
+
this.logFd = null;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=pty-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-session.js","sourceRoot":"","sources":["../../src/terminal/pty-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-size circular buffer for storing terminal output lines.
|
|
3
|
+
* Used for reconnection replay — stores last N lines in memory.
|
|
4
|
+
*/
|
|
5
|
+
export declare class RingBuffer {
|
|
6
|
+
private readonly capacity;
|
|
7
|
+
private buffer;
|
|
8
|
+
private head;
|
|
9
|
+
private count;
|
|
10
|
+
private seq;
|
|
11
|
+
private partial;
|
|
12
|
+
constructor(capacity?: number);
|
|
13
|
+
/** Push a complete line into the buffer. Returns the assigned sequence number. */
|
|
14
|
+
push(line: string): number;
|
|
15
|
+
/**
|
|
16
|
+
* Push raw data, splitting on newlines. Handles partial lines across
|
|
17
|
+
* chunk boundaries: if data doesn't end with \n, the trailing fragment
|
|
18
|
+
* is held and prepended to the next pushData call.
|
|
19
|
+
*
|
|
20
|
+
* Returns last sequence number.
|
|
21
|
+
*/
|
|
22
|
+
pushData(data: string): number;
|
|
23
|
+
/** Get all stored lines in order, including any incomplete trailing line. */
|
|
24
|
+
getAll(): string[];
|
|
25
|
+
/** Get lines starting from a given sequence number (for resume). */
|
|
26
|
+
getSince(sinceSeq: number): string[];
|
|
27
|
+
/** Current sequence number (last written). */
|
|
28
|
+
get currentSeq(): number;
|
|
29
|
+
/** Number of lines currently stored. */
|
|
30
|
+
get size(): number;
|
|
31
|
+
/** Clear the buffer and release memory. */
|
|
32
|
+
clear(): void;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=ring-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/terminal/ring-buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,UAAU;IAOT,OAAO,CAAC,QAAQ,CAAC,QAAQ;IANrC,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,OAAO,CAAc;gBAEA,QAAQ,GAAE,MAAa;IAIpD,kFAAkF;IAClF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAW1B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAiB9B,6EAA6E;IAC7E,MAAM,IAAI,MAAM,EAAE;IAWlB,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAiBpC,8CAA8C;IAC9C,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,2CAA2C;IAC3C,KAAK,IAAI,IAAI;CAOd"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-size circular buffer for storing terminal output lines.
|
|
3
|
+
* Used for reconnection replay — stores last N lines in memory.
|
|
4
|
+
*/
|
|
5
|
+
export class RingBuffer {
|
|
6
|
+
capacity;
|
|
7
|
+
buffer;
|
|
8
|
+
head = 0;
|
|
9
|
+
count = 0;
|
|
10
|
+
seq = 0; // monotonically increasing sequence number
|
|
11
|
+
partial = ''; // incomplete line from previous pushData call
|
|
12
|
+
constructor(capacity = 1000) {
|
|
13
|
+
this.capacity = capacity;
|
|
14
|
+
this.buffer = new Array(capacity);
|
|
15
|
+
}
|
|
16
|
+
/** Push a complete line into the buffer. Returns the assigned sequence number. */
|
|
17
|
+
push(line) {
|
|
18
|
+
const index = (this.head + this.count) % this.capacity;
|
|
19
|
+
this.buffer[index] = line;
|
|
20
|
+
if (this.count < this.capacity) {
|
|
21
|
+
this.count++;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
this.head = (this.head + 1) % this.capacity;
|
|
25
|
+
}
|
|
26
|
+
return ++this.seq;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Push raw data, splitting on newlines. Handles partial lines across
|
|
30
|
+
* chunk boundaries: if data doesn't end with \n, the trailing fragment
|
|
31
|
+
* is held and prepended to the next pushData call.
|
|
32
|
+
*
|
|
33
|
+
* Returns last sequence number.
|
|
34
|
+
*/
|
|
35
|
+
pushData(data) {
|
|
36
|
+
const combined = this.partial + data;
|
|
37
|
+
const parts = combined.split('\n');
|
|
38
|
+
// Last element is either:
|
|
39
|
+
// - "" if data ended with \n (all lines complete)
|
|
40
|
+
// - non-empty if data ended mid-line (incomplete line)
|
|
41
|
+
// Either way, save it as the new partial.
|
|
42
|
+
this.partial = parts.pop();
|
|
43
|
+
let lastSeq = this.seq;
|
|
44
|
+
for (const line of parts) {
|
|
45
|
+
lastSeq = this.push(line);
|
|
46
|
+
}
|
|
47
|
+
return lastSeq;
|
|
48
|
+
}
|
|
49
|
+
/** Get all stored lines in order, including any incomplete trailing line. */
|
|
50
|
+
getAll() {
|
|
51
|
+
const result = [];
|
|
52
|
+
for (let i = 0; i < this.count; i++) {
|
|
53
|
+
result.push(this.buffer[(this.head + i) % this.capacity]);
|
|
54
|
+
}
|
|
55
|
+
if (this.partial) {
|
|
56
|
+
result.push(this.partial);
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
/** Get lines starting from a given sequence number (for resume). */
|
|
61
|
+
getSince(sinceSeq) {
|
|
62
|
+
const linesAvailable = this.count;
|
|
63
|
+
const oldestSeq = this.seq - linesAvailable + 1;
|
|
64
|
+
const startSeq = Math.max(sinceSeq + 1, oldestSeq);
|
|
65
|
+
if (startSeq > this.seq)
|
|
66
|
+
return [];
|
|
67
|
+
const skip = startSeq - oldestSeq;
|
|
68
|
+
const result = [];
|
|
69
|
+
for (let i = skip; i < this.count; i++) {
|
|
70
|
+
result.push(this.buffer[(this.head + i) % this.capacity]);
|
|
71
|
+
}
|
|
72
|
+
if (this.partial) {
|
|
73
|
+
result.push(this.partial);
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
/** Current sequence number (last written). */
|
|
78
|
+
get currentSeq() {
|
|
79
|
+
return this.seq;
|
|
80
|
+
}
|
|
81
|
+
/** Number of lines currently stored. */
|
|
82
|
+
get size() {
|
|
83
|
+
return this.count;
|
|
84
|
+
}
|
|
85
|
+
/** Clear the buffer and release memory. */
|
|
86
|
+
clear() {
|
|
87
|
+
this.buffer = [];
|
|
88
|
+
this.head = 0;
|
|
89
|
+
this.count = 0;
|
|
90
|
+
this.partial = '';
|
|
91
|
+
// Don't reset seq — it should be monotonic
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=ring-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-buffer.js","sourceRoot":"","sources":["../../src/terminal/ring-buffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionManager: orchestrates shepherd process lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Spawn shepherd processes as detached children
|
|
6
|
+
* - Connect ShepherdClient to each shepherd
|
|
7
|
+
* - Kill sessions (SIGTERM → wait → SIGKILL)
|
|
8
|
+
* - Detect and clean up stale sockets
|
|
9
|
+
* - Auto-restart on exit (configurable per session)
|
|
10
|
+
* - Reconnect to existing shepherds after Tower restart
|
|
11
|
+
*
|
|
12
|
+
* Process start time validation prevents PID reuse reconnection.
|
|
13
|
+
*/
|
|
14
|
+
import { EventEmitter } from 'node:events';
|
|
15
|
+
import { type IShepherdClient } from './shepherd-client.js';
|
|
16
|
+
export interface SessionManagerConfig {
|
|
17
|
+
socketDir: string;
|
|
18
|
+
shepherdScript: string;
|
|
19
|
+
nodeExecutable: string;
|
|
20
|
+
}
|
|
21
|
+
export interface CreateSessionOptions {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
command: string;
|
|
24
|
+
args: string[];
|
|
25
|
+
cwd: string;
|
|
26
|
+
env: Record<string, string>;
|
|
27
|
+
cols: number;
|
|
28
|
+
rows: number;
|
|
29
|
+
restartOnExit?: boolean;
|
|
30
|
+
restartDelay?: number;
|
|
31
|
+
maxRestarts?: number;
|
|
32
|
+
restartResetAfter?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ReconnectRestartOptions {
|
|
35
|
+
command: string;
|
|
36
|
+
args: string[];
|
|
37
|
+
cwd: string;
|
|
38
|
+
env: Record<string, string>;
|
|
39
|
+
restartDelay?: number;
|
|
40
|
+
maxRestarts?: number;
|
|
41
|
+
restartResetAfter?: number;
|
|
42
|
+
}
|
|
43
|
+
export declare class SessionManager extends EventEmitter {
|
|
44
|
+
private readonly config;
|
|
45
|
+
private sessions;
|
|
46
|
+
constructor(config: SessionManagerConfig);
|
|
47
|
+
/**
|
|
48
|
+
* Spawn a new shepherd process and connect to it.
|
|
49
|
+
* Returns the connected client.
|
|
50
|
+
*/
|
|
51
|
+
createSession(opts: CreateSessionOptions): Promise<IShepherdClient>;
|
|
52
|
+
/**
|
|
53
|
+
* Reconnect to an existing shepherd process after Tower restart.
|
|
54
|
+
* Validates PID is alive and start time matches.
|
|
55
|
+
* Returns connected client, or null if shepherd is stale/dead.
|
|
56
|
+
*/
|
|
57
|
+
reconnectSession(sessionId: string, socketPath: string, pid: number, startTime: number, restartOptions?: ReconnectRestartOptions): Promise<IShepherdClient | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Kill a session: SIGTERM, wait 5s, SIGKILL if needed.
|
|
60
|
+
* Cleans up socket file and removes from session map.
|
|
61
|
+
*/
|
|
62
|
+
killSession(sessionId: string): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* List all active sessions.
|
|
65
|
+
*/
|
|
66
|
+
listSessions(): Map<string, IShepherdClient>;
|
|
67
|
+
/**
|
|
68
|
+
* Get session metadata (pid, startTime, socketPath) for a session.
|
|
69
|
+
*/
|
|
70
|
+
getSessionInfo(sessionId: string): {
|
|
71
|
+
pid: number;
|
|
72
|
+
startTime: number;
|
|
73
|
+
socketPath: string;
|
|
74
|
+
} | null;
|
|
75
|
+
/**
|
|
76
|
+
* Scan socket directory for stale sockets (no live process).
|
|
77
|
+
* A socket is stale if nothing is listening on it (connection refused).
|
|
78
|
+
* Returns the number of sockets cleaned up.
|
|
79
|
+
*/
|
|
80
|
+
cleanupStaleSockets(): Promise<number>;
|
|
81
|
+
/**
|
|
82
|
+
* Test if a Unix socket has a listener by attempting a brief connection.
|
|
83
|
+
* Returns true if connection succeeds, false if refused/timed out.
|
|
84
|
+
*/
|
|
85
|
+
private probeSocket;
|
|
86
|
+
/**
|
|
87
|
+
* Disconnect from all sessions without killing shepherd processes.
|
|
88
|
+
* Per spec: "When Tower intentionally stops, Tower closes its socket
|
|
89
|
+
* connections to shepherds. Shepherds continue running."
|
|
90
|
+
*/
|
|
91
|
+
shutdown(): void;
|
|
92
|
+
/**
|
|
93
|
+
* Remove a dead session from the map, clear its timers, and clean up socket.
|
|
94
|
+
* Called when a session exits naturally (no restart) or exhausts maxRestarts.
|
|
95
|
+
*/
|
|
96
|
+
private removeDeadSession;
|
|
97
|
+
private getSocketPath;
|
|
98
|
+
private unlinkSocketIfExists;
|
|
99
|
+
private readShepherdInfo;
|
|
100
|
+
private waitForSocket;
|
|
101
|
+
private isProcessAlive;
|
|
102
|
+
private waitForProcessExit;
|
|
103
|
+
private setupAutoRestart;
|
|
104
|
+
private startRestartResetTimer;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get the start time of a process by PID.
|
|
108
|
+
* Returns epoch milliseconds, or null if the process doesn't exist or can't be queried.
|
|
109
|
+
*
|
|
110
|
+
* Platform-specific:
|
|
111
|
+
* - macOS: parse `ps -p {pid} -o lstart=`
|
|
112
|
+
* - Linux: read `/proc/{pid}/stat` field 22 (starttime in clock ticks)
|
|
113
|
+
*/
|
|
114
|
+
export declare function getProcessStartTime(pid: number): Promise<number | null>;
|
|
115
|
+
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/terminal/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAYD,qBAAa,cAAe,SAAQ,YAAY;IAGlC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAqC;gBAExB,MAAM,EAAE,oBAAoB;IAIzD;;;OAGG;IACG,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC;IAiGzE;;;;OAIG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,uBAAuB,GACvC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAwFlC;;;OAGG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCnD;;OAEG;IACH,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAQ5C;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAUhG;;;;OAIG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IA+C5C;;;OAGG;IACH,OAAO,CAAC,WAAW;IAsBnB;;;;OAIG;IACH,QAAQ,IAAI,IAAI;IAahB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,gBAAgB;IA8CxB,OAAO,CAAC,sBAAsB;CAc/B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2DvE"}
|