@cluesmith/codev 2.0.0-rc.8 → 2.0.0
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-4n9zpWLY.css +32 -0
- package/dashboard/dist/assets/index-b38SaXk5.js +136 -0
- package/dashboard/dist/assets/index-b38SaXk5.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 +179 -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 +70 -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-roles.d.ts +80 -0
- package/dist/agent-farm/commands/spawn-roles.d.ts.map +1 -0
- package/dist/agent-farm/commands/spawn-roles.js +278 -0
- package/dist/agent-farm/commands/spawn-roles.js.map +1 -0
- package/dist/agent-farm/commands/spawn-worktree.d.ts +96 -0
- package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -0
- package/dist/agent-farm/commands/spawn-worktree.js +305 -0
- package/dist/agent-farm/commands/spawn-worktree.js.map +1 -0
- package/dist/agent-farm/commands/spawn.d.ts +5 -1
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +242 -586
- 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 +293 -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 +301 -19
- 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/device-name.d.ts +25 -0
- package/dist/agent-farm/lib/device-name.d.ts.map +1 -0
- package/dist/agent-farm/lib/device-name.js +46 -0
- package/dist/agent-farm/lib/device-name.js.map +1 -0
- package/dist/agent-farm/lib/nonce-store.d.ts +28 -0
- package/dist/agent-farm/lib/nonce-store.d.ts.map +1 -0
- package/dist/agent-farm/lib/nonce-store.js +60 -0
- package/dist/agent-farm/lib/nonce-store.js.map +1 -0
- package/dist/agent-farm/lib/token-exchange.d.ts +18 -0
- package/dist/agent-farm/lib/token-exchange.d.ts.map +1 -0
- package/dist/agent-farm/lib/token-exchange.js +48 -0
- package/dist/agent-farm/lib/token-exchange.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-instances.d.ts +82 -0
- package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -0
- package/dist/agent-farm/servers/tower-instances.js +454 -0
- package/dist/agent-farm/servers/tower-instances.js.map +1 -0
- package/dist/agent-farm/servers/tower-routes.d.ts +34 -0
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -0
- package/dist/agent-farm/servers/tower-routes.js +1445 -0
- package/dist/agent-farm/servers/tower-routes.js.map +1 -0
- package/dist/agent-farm/servers/tower-server.d.ts +5 -2
- package/dist/agent-farm/servers/tower-server.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +157 -475
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.d.ts +119 -0
- package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -0
- package/dist/agent-farm/servers/tower-terminals.js +629 -0
- package/dist/agent-farm/servers/tower-terminals.js.map +1 -0
- package/dist/agent-farm/servers/tower-tunnel.d.ts +34 -0
- package/dist/agent-farm/servers/tower-tunnel.d.ts.map +1 -0
- package/dist/agent-farm/servers/tower-tunnel.js +473 -0
- package/dist/agent-farm/servers/tower-tunnel.js.map +1 -0
- package/dist/agent-farm/servers/tower-types.d.ts +86 -0
- package/dist/agent-farm/servers/tower-types.d.ts.map +1 -0
- package/dist/agent-farm/servers/tower-types.js +6 -0
- package/dist/agent-farm/servers/tower-types.js.map +1 -0
- package/dist/agent-farm/servers/tower-utils.d.ts +58 -0
- package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -0
- package/dist/agent-farm/servers/tower-utils.js +182 -0
- package/dist/agent-farm/servers/tower-utils.js.map +1 -0
- package/dist/agent-farm/servers/tower-websocket.d.ts +25 -0
- package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -0
- package/dist/agent-farm/servers/tower-websocket.js +171 -0
- package/dist/agent-farm/servers/tower-websocket.js.map +1 -0
- 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 +52 -3
- 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 +466 -1238
- 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/shellper-client.d.ts +66 -0
- package/dist/terminal/shellper-client.d.ts.map +1 -0
- package/dist/terminal/shellper-client.js +234 -0
- package/dist/terminal/shellper-client.js.map +1 -0
- package/dist/terminal/shellper-main.d.ts +19 -0
- package/dist/terminal/shellper-main.d.ts.map +1 -0
- package/dist/terminal/shellper-main.js +153 -0
- package/dist/terminal/shellper-main.js.map +1 -0
- package/dist/terminal/shellper-process.d.ts +75 -0
- package/dist/terminal/shellper-process.d.ts.map +1 -0
- package/dist/terminal/shellper-process.js +279 -0
- package/dist/terminal/shellper-process.js.map +1 -0
- package/dist/terminal/shellper-protocol.d.ts +115 -0
- package/dist/terminal/shellper-protocol.d.ts.map +1 -0
- package/dist/terminal/shellper-protocol.js +214 -0
- package/dist/terminal/shellper-protocol.js.map +1 -0
- package/dist/terminal/shellper-replay-buffer.d.ts +38 -0
- package/dist/terminal/shellper-replay-buffer.d.ts.map +1 -0
- package/dist/terminal/shellper-replay-buffer.js +94 -0
- package/dist/terminal/shellper-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 +60 -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 +66 -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 +120 -214
- 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 +731 -91
- 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,582 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionManager: orchestrates shellper process lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Spawn shellper processes as detached children
|
|
6
|
+
* - Connect ShellperClient to each shellper
|
|
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 shellpers after Tower restart
|
|
11
|
+
*
|
|
12
|
+
* Process start time validation prevents PID reuse reconnection.
|
|
13
|
+
*/
|
|
14
|
+
import { spawn as cpSpawn } from 'node:child_process';
|
|
15
|
+
import fs from 'node:fs';
|
|
16
|
+
import net from 'node:net';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
import { EventEmitter } from 'node:events';
|
|
19
|
+
import { execFile } from 'node:child_process';
|
|
20
|
+
import { ShellperClient } from './shellper-client.js';
|
|
21
|
+
export class SessionManager extends EventEmitter {
|
|
22
|
+
config;
|
|
23
|
+
sessions = new Map();
|
|
24
|
+
constructor(config) {
|
|
25
|
+
super();
|
|
26
|
+
this.config = config;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Spawn a new shellper process and connect to it.
|
|
30
|
+
* Returns the connected client.
|
|
31
|
+
*/
|
|
32
|
+
async createSession(opts) {
|
|
33
|
+
const socketPath = this.getSocketPath(opts.sessionId);
|
|
34
|
+
// Ensure socket directory exists with 0700 permissions
|
|
35
|
+
fs.mkdirSync(this.config.socketDir, { recursive: true, mode: 0o700 });
|
|
36
|
+
// Clean up any stale socket file
|
|
37
|
+
this.unlinkSocketIfExists(socketPath);
|
|
38
|
+
// Build config for shellper-main.js
|
|
39
|
+
const shellperConfig = JSON.stringify({
|
|
40
|
+
command: opts.command,
|
|
41
|
+
args: opts.args,
|
|
42
|
+
cwd: opts.cwd,
|
|
43
|
+
env: opts.env,
|
|
44
|
+
cols: opts.cols,
|
|
45
|
+
rows: opts.rows,
|
|
46
|
+
socketPath,
|
|
47
|
+
});
|
|
48
|
+
// Spawn shellper as detached process
|
|
49
|
+
const child = cpSpawn(this.config.nodeExecutable, [this.config.shellperScript, shellperConfig], {
|
|
50
|
+
detached: true,
|
|
51
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
52
|
+
});
|
|
53
|
+
// Read PID + startTime from stdout
|
|
54
|
+
const info = await this.readShellperInfo(child);
|
|
55
|
+
child.unref();
|
|
56
|
+
// Post-spawn setup with rollback: if anything fails after the shellper
|
|
57
|
+
// is spawned, kill the orphaned process and clean up the socket.
|
|
58
|
+
let client;
|
|
59
|
+
try {
|
|
60
|
+
// Wait briefly for socket to be ready
|
|
61
|
+
await this.waitForSocket(socketPath);
|
|
62
|
+
// Connect client
|
|
63
|
+
client = new ShellperClient(socketPath);
|
|
64
|
+
await client.connect();
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
// Rollback: kill the orphaned shellper process
|
|
68
|
+
try {
|
|
69
|
+
process.kill(info.pid, 'SIGKILL');
|
|
70
|
+
}
|
|
71
|
+
catch { /* already dead */ }
|
|
72
|
+
this.unlinkSocketIfExists(socketPath);
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
const session = {
|
|
76
|
+
client,
|
|
77
|
+
socketPath,
|
|
78
|
+
pid: info.pid,
|
|
79
|
+
startTime: info.startTime,
|
|
80
|
+
options: opts,
|
|
81
|
+
restartCount: 0,
|
|
82
|
+
restartResetTimer: null,
|
|
83
|
+
};
|
|
84
|
+
this.sessions.set(opts.sessionId, session);
|
|
85
|
+
// Set up auto-restart if configured
|
|
86
|
+
if (opts.restartOnExit) {
|
|
87
|
+
this.setupAutoRestart(session, opts.sessionId);
|
|
88
|
+
}
|
|
89
|
+
// Forward exit events and clean up dead sessions
|
|
90
|
+
client.on('exit', (exitInfo) => {
|
|
91
|
+
this.emit('session-exit', opts.sessionId, exitInfo);
|
|
92
|
+
// If not auto-restarting, remove the dead session from the map
|
|
93
|
+
// so listSessions() doesn't report it and cleanupStaleSockets()
|
|
94
|
+
// can clean its socket file.
|
|
95
|
+
if (!opts.restartOnExit) {
|
|
96
|
+
this.removeDeadSession(opts.sessionId);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
client.on('error', (err) => {
|
|
100
|
+
this.emit('session-error', opts.sessionId, err);
|
|
101
|
+
});
|
|
102
|
+
// Handle shellper crash (socket disconnects without EXIT frame)
|
|
103
|
+
client.on('close', () => {
|
|
104
|
+
// If the session is still in the map (wasn't already cleaned up by exit/kill),
|
|
105
|
+
// the shellper died without sending EXIT. Remove the dead session.
|
|
106
|
+
if (this.sessions.has(opts.sessionId)) {
|
|
107
|
+
this.removeDeadSession(opts.sessionId);
|
|
108
|
+
this.emit('session-error', opts.sessionId, new Error('Shellper disconnected unexpectedly'));
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
// Start restart reset timer if configured
|
|
112
|
+
if (opts.restartOnExit) {
|
|
113
|
+
this.startRestartResetTimer(session);
|
|
114
|
+
}
|
|
115
|
+
return client;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Reconnect to an existing shellper process after Tower restart.
|
|
119
|
+
* Validates PID is alive and start time matches.
|
|
120
|
+
* Returns connected client, or null if shellper is stale/dead.
|
|
121
|
+
*/
|
|
122
|
+
async reconnectSession(sessionId, socketPath, pid, startTime, restartOptions) {
|
|
123
|
+
// Check if process is alive
|
|
124
|
+
if (!this.isProcessAlive(pid)) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
// Validate process start time to prevent PID reuse
|
|
128
|
+
const actualStartTime = await getProcessStartTime(pid);
|
|
129
|
+
if (actualStartTime === null || Math.abs(actualStartTime - startTime) > 2000) {
|
|
130
|
+
// Start time mismatch or couldn't determine — PID was reused
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
// Check socket file exists
|
|
134
|
+
try {
|
|
135
|
+
const stat = fs.lstatSync(socketPath);
|
|
136
|
+
if (!stat.isSocket()) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
// Connect client
|
|
144
|
+
const client = new ShellperClient(socketPath);
|
|
145
|
+
try {
|
|
146
|
+
await client.connect();
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const hasRestart = !!restartOptions;
|
|
152
|
+
const session = {
|
|
153
|
+
client,
|
|
154
|
+
socketPath,
|
|
155
|
+
pid,
|
|
156
|
+
startTime,
|
|
157
|
+
options: {
|
|
158
|
+
sessionId,
|
|
159
|
+
command: restartOptions?.command ?? '',
|
|
160
|
+
args: restartOptions?.args ?? [],
|
|
161
|
+
cwd: restartOptions?.cwd ?? '',
|
|
162
|
+
env: restartOptions?.env ?? {},
|
|
163
|
+
cols: 80,
|
|
164
|
+
rows: 24,
|
|
165
|
+
restartOnExit: hasRestart,
|
|
166
|
+
restartDelay: restartOptions?.restartDelay,
|
|
167
|
+
maxRestarts: restartOptions?.maxRestarts,
|
|
168
|
+
restartResetAfter: restartOptions?.restartResetAfter,
|
|
169
|
+
},
|
|
170
|
+
restartCount: 0,
|
|
171
|
+
restartResetTimer: null,
|
|
172
|
+
};
|
|
173
|
+
this.sessions.set(sessionId, session);
|
|
174
|
+
// Set up auto-restart if configured (e.g. architect sessions after Tower restart)
|
|
175
|
+
if (hasRestart) {
|
|
176
|
+
this.setupAutoRestart(session, sessionId);
|
|
177
|
+
}
|
|
178
|
+
client.on('exit', (exitInfo) => {
|
|
179
|
+
this.emit('session-exit', sessionId, exitInfo);
|
|
180
|
+
if (!hasRestart) {
|
|
181
|
+
this.removeDeadSession(sessionId);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
client.on('error', (err) => {
|
|
185
|
+
this.emit('session-error', sessionId, err);
|
|
186
|
+
});
|
|
187
|
+
// Handle shellper crash (socket disconnects without EXIT frame)
|
|
188
|
+
client.on('close', () => {
|
|
189
|
+
if (this.sessions.has(sessionId)) {
|
|
190
|
+
this.removeDeadSession(sessionId);
|
|
191
|
+
this.emit('session-error', sessionId, new Error('Shellper disconnected unexpectedly'));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
// Start restart reset timer if auto-restart is enabled
|
|
195
|
+
if (hasRestart) {
|
|
196
|
+
this.startRestartResetTimer(session);
|
|
197
|
+
}
|
|
198
|
+
return client;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Kill a session: SIGTERM, wait 5s, SIGKILL if needed.
|
|
202
|
+
* Cleans up socket file and removes from session map.
|
|
203
|
+
*/
|
|
204
|
+
async killSession(sessionId) {
|
|
205
|
+
const session = this.sessions.get(sessionId);
|
|
206
|
+
if (!session)
|
|
207
|
+
return;
|
|
208
|
+
// Clear restart timer
|
|
209
|
+
if (session.restartResetTimer) {
|
|
210
|
+
clearTimeout(session.restartResetTimer);
|
|
211
|
+
session.restartResetTimer = null;
|
|
212
|
+
}
|
|
213
|
+
// Disable auto-restart by removing the session from the map before killing
|
|
214
|
+
this.sessions.delete(sessionId);
|
|
215
|
+
// Send SIGTERM
|
|
216
|
+
try {
|
|
217
|
+
process.kill(session.pid, 'SIGTERM');
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// Process already dead
|
|
221
|
+
}
|
|
222
|
+
// Wait up to 5s for process to die
|
|
223
|
+
const died = await this.waitForProcessExit(session.pid, 5000);
|
|
224
|
+
if (!died) {
|
|
225
|
+
// Force kill
|
|
226
|
+
try {
|
|
227
|
+
process.kill(session.pid, 'SIGKILL');
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// Already dead
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Disconnect client
|
|
234
|
+
session.client.disconnect();
|
|
235
|
+
// Clean up socket file
|
|
236
|
+
this.unlinkSocketIfExists(session.socketPath);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* List all active sessions.
|
|
240
|
+
*/
|
|
241
|
+
listSessions() {
|
|
242
|
+
const result = new Map();
|
|
243
|
+
for (const [id, session] of this.sessions) {
|
|
244
|
+
result.set(id, session.client);
|
|
245
|
+
}
|
|
246
|
+
return result;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get session metadata (pid, startTime, socketPath) for a session.
|
|
250
|
+
*/
|
|
251
|
+
getSessionInfo(sessionId) {
|
|
252
|
+
const session = this.sessions.get(sessionId);
|
|
253
|
+
if (!session)
|
|
254
|
+
return null;
|
|
255
|
+
return {
|
|
256
|
+
pid: session.pid,
|
|
257
|
+
startTime: session.startTime,
|
|
258
|
+
socketPath: session.socketPath,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Scan socket directory for stale sockets (no live process).
|
|
263
|
+
* A socket is stale if nothing is listening on it (connection refused).
|
|
264
|
+
* Returns the number of sockets cleaned up.
|
|
265
|
+
*/
|
|
266
|
+
async cleanupStaleSockets() {
|
|
267
|
+
let cleaned = 0;
|
|
268
|
+
let files;
|
|
269
|
+
try {
|
|
270
|
+
files = fs.readdirSync(this.config.socketDir);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
return 0;
|
|
274
|
+
}
|
|
275
|
+
for (const file of files) {
|
|
276
|
+
if (!file.startsWith('shellper-') || !file.endsWith('.sock'))
|
|
277
|
+
continue;
|
|
278
|
+
const fullPath = path.join(this.config.socketDir, file);
|
|
279
|
+
// Safety: reject symlinks
|
|
280
|
+
try {
|
|
281
|
+
const stat = fs.lstatSync(fullPath);
|
|
282
|
+
if (stat.isSymbolicLink())
|
|
283
|
+
continue;
|
|
284
|
+
if (!stat.isSocket())
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
// Extract session ID from filename: shellper-{sessionId}.sock
|
|
291
|
+
const sessionId = file.replace('shellper-', '').replace('.sock', '');
|
|
292
|
+
// Skip if we have an active session for this
|
|
293
|
+
if (this.sessions.has(sessionId))
|
|
294
|
+
continue;
|
|
295
|
+
// Probe the socket: try connecting to see if a shellper is alive.
|
|
296
|
+
// If connection is refused, the socket is stale and safe to delete.
|
|
297
|
+
// If connection succeeds, a shellper is still running — leave it alone.
|
|
298
|
+
const isAlive = await this.probeSocket(fullPath);
|
|
299
|
+
if (isAlive)
|
|
300
|
+
continue;
|
|
301
|
+
// No live process — it's stale
|
|
302
|
+
try {
|
|
303
|
+
fs.unlinkSync(fullPath);
|
|
304
|
+
cleaned++;
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
// Permission error or already gone
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return cleaned;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Test if a Unix socket has a listener by attempting a brief connection.
|
|
314
|
+
* Returns true if connection succeeds, false if refused/timed out.
|
|
315
|
+
*/
|
|
316
|
+
probeSocket(socketPath) {
|
|
317
|
+
return new Promise((resolve) => {
|
|
318
|
+
const socket = net.createConnection(socketPath);
|
|
319
|
+
const timeout = setTimeout(() => {
|
|
320
|
+
socket.destroy();
|
|
321
|
+
resolve(false);
|
|
322
|
+
}, 2000);
|
|
323
|
+
socket.on('connect', () => {
|
|
324
|
+
clearTimeout(timeout);
|
|
325
|
+
socket.destroy();
|
|
326
|
+
resolve(true);
|
|
327
|
+
});
|
|
328
|
+
socket.on('error', () => {
|
|
329
|
+
clearTimeout(timeout);
|
|
330
|
+
socket.destroy();
|
|
331
|
+
resolve(false);
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Disconnect from all sessions without killing shellper processes.
|
|
337
|
+
* Per spec: "When Tower intentionally stops, Tower closes its socket
|
|
338
|
+
* connections to shellpers. Shellpers continue running."
|
|
339
|
+
*/
|
|
340
|
+
shutdown() {
|
|
341
|
+
for (const [id, session] of this.sessions) {
|
|
342
|
+
if (session.restartResetTimer) {
|
|
343
|
+
clearTimeout(session.restartResetTimer);
|
|
344
|
+
session.restartResetTimer = null;
|
|
345
|
+
}
|
|
346
|
+
session.client.disconnect();
|
|
347
|
+
}
|
|
348
|
+
this.sessions.clear();
|
|
349
|
+
}
|
|
350
|
+
// --- Private helpers ---
|
|
351
|
+
/**
|
|
352
|
+
* Remove a dead session from the map, clear its timers, and clean up socket.
|
|
353
|
+
* Called when a session exits naturally (no restart) or exhausts maxRestarts.
|
|
354
|
+
*/
|
|
355
|
+
removeDeadSession(sessionId) {
|
|
356
|
+
const session = this.sessions.get(sessionId);
|
|
357
|
+
if (!session)
|
|
358
|
+
return;
|
|
359
|
+
if (session.restartResetTimer) {
|
|
360
|
+
clearTimeout(session.restartResetTimer);
|
|
361
|
+
session.restartResetTimer = null;
|
|
362
|
+
}
|
|
363
|
+
this.sessions.delete(sessionId);
|
|
364
|
+
this.unlinkSocketIfExists(session.socketPath);
|
|
365
|
+
}
|
|
366
|
+
getSocketPath(sessionId) {
|
|
367
|
+
return path.join(this.config.socketDir, `shellper-${sessionId}.sock`);
|
|
368
|
+
}
|
|
369
|
+
unlinkSocketIfExists(socketPath) {
|
|
370
|
+
try {
|
|
371
|
+
const stat = fs.lstatSync(socketPath);
|
|
372
|
+
if (stat.isSocket()) {
|
|
373
|
+
fs.unlinkSync(socketPath);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
// Doesn't exist — fine
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
readShellperInfo(child) {
|
|
381
|
+
return new Promise((resolve, reject) => {
|
|
382
|
+
let data = '';
|
|
383
|
+
const timeout = setTimeout(() => {
|
|
384
|
+
reject(new Error('Timed out reading shellper info from stdout'));
|
|
385
|
+
}, 10_000);
|
|
386
|
+
child.stdout.on('data', (chunk) => {
|
|
387
|
+
data += chunk.toString();
|
|
388
|
+
});
|
|
389
|
+
child.stdout.on('end', () => {
|
|
390
|
+
clearTimeout(timeout);
|
|
391
|
+
try {
|
|
392
|
+
const info = JSON.parse(data);
|
|
393
|
+
resolve(info);
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
reject(new Error(`Invalid shellper info JSON: ${data}`));
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
child.on('error', (err) => {
|
|
400
|
+
clearTimeout(timeout);
|
|
401
|
+
reject(err);
|
|
402
|
+
});
|
|
403
|
+
child.on('exit', (code) => {
|
|
404
|
+
if (code !== null && code !== 0 && data === '') {
|
|
405
|
+
clearTimeout(timeout);
|
|
406
|
+
reject(new Error(`Shellper exited with code ${code} before writing info`));
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
waitForSocket(socketPath, timeout = 5000) {
|
|
412
|
+
return new Promise((resolve, reject) => {
|
|
413
|
+
const start = Date.now();
|
|
414
|
+
const check = () => {
|
|
415
|
+
try {
|
|
416
|
+
fs.statSync(socketPath);
|
|
417
|
+
resolve();
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
if (Date.now() - start > timeout) {
|
|
421
|
+
reject(new Error(`Socket ${socketPath} not created within ${timeout}ms`));
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
setTimeout(check, 50);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
check();
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
isProcessAlive(pid) {
|
|
432
|
+
try {
|
|
433
|
+
process.kill(pid, 0);
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
waitForProcessExit(pid, timeout) {
|
|
441
|
+
return new Promise((resolve) => {
|
|
442
|
+
const start = Date.now();
|
|
443
|
+
const check = () => {
|
|
444
|
+
if (!this.isProcessAlive(pid)) {
|
|
445
|
+
resolve(true);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
if (Date.now() - start > timeout) {
|
|
449
|
+
resolve(false);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
setTimeout(check, 100);
|
|
453
|
+
};
|
|
454
|
+
check();
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
setupAutoRestart(session, sessionId) {
|
|
458
|
+
session.client.on('exit', () => {
|
|
459
|
+
// Check if session was removed (killed intentionally)
|
|
460
|
+
if (!this.sessions.has(sessionId))
|
|
461
|
+
return;
|
|
462
|
+
// Cancel the reset timer while the process is down — it should only
|
|
463
|
+
// run while the process is alive, preventing restartResetAfter < restartDelay
|
|
464
|
+
// from resetting the counter during downtime.
|
|
465
|
+
if (session.restartResetTimer) {
|
|
466
|
+
clearTimeout(session.restartResetTimer);
|
|
467
|
+
session.restartResetTimer = null;
|
|
468
|
+
}
|
|
469
|
+
const maxRestarts = session.options.maxRestarts ?? 50;
|
|
470
|
+
if (session.restartCount >= maxRestarts) {
|
|
471
|
+
this.emit('session-error', sessionId, new Error(`Max restarts (${maxRestarts}) exceeded`));
|
|
472
|
+
// Remove the exhausted session from the map
|
|
473
|
+
this.removeDeadSession(sessionId);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
session.restartCount++;
|
|
477
|
+
const delay = session.options.restartDelay ?? 2000;
|
|
478
|
+
this.emit('session-restart', sessionId, {
|
|
479
|
+
restartCount: session.restartCount,
|
|
480
|
+
delay,
|
|
481
|
+
});
|
|
482
|
+
setTimeout(() => {
|
|
483
|
+
// Re-check session still exists after delay
|
|
484
|
+
if (!this.sessions.has(sessionId))
|
|
485
|
+
return;
|
|
486
|
+
session.client.spawn({
|
|
487
|
+
command: session.options.command,
|
|
488
|
+
args: session.options.args,
|
|
489
|
+
cwd: session.options.cwd,
|
|
490
|
+
env: session.options.env,
|
|
491
|
+
});
|
|
492
|
+
// Only restart the reset timer after a successful spawn
|
|
493
|
+
this.startRestartResetTimer(session);
|
|
494
|
+
}, delay);
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
startRestartResetTimer(session) {
|
|
498
|
+
if (session.restartResetTimer) {
|
|
499
|
+
clearTimeout(session.restartResetTimer);
|
|
500
|
+
}
|
|
501
|
+
const restartDelay = session.options.restartDelay ?? 2000;
|
|
502
|
+
const resetAfter = session.options.restartResetAfter ?? 300_000; // 5 minutes
|
|
503
|
+
// Enforce minimum: reset window must be at least as long as restartDelay
|
|
504
|
+
// to prevent the counter from resetting while the process is restarting
|
|
505
|
+
const effectiveResetAfter = Math.max(resetAfter, restartDelay);
|
|
506
|
+
session.restartResetTimer = setTimeout(() => {
|
|
507
|
+
session.restartCount = 0;
|
|
508
|
+
}, effectiveResetAfter);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Get the start time of a process by PID.
|
|
513
|
+
* Returns epoch milliseconds, or null if the process doesn't exist or can't be queried.
|
|
514
|
+
*
|
|
515
|
+
* Platform-specific:
|
|
516
|
+
* - macOS: parse `ps -p {pid} -o lstart=`
|
|
517
|
+
* - Linux: read `/proc/{pid}/stat` field 22 (starttime in clock ticks)
|
|
518
|
+
*/
|
|
519
|
+
export function getProcessStartTime(pid) {
|
|
520
|
+
return new Promise((resolve) => {
|
|
521
|
+
try {
|
|
522
|
+
if (process.platform === 'darwin') {
|
|
523
|
+
// macOS: use ps to get launch time
|
|
524
|
+
execFile('ps', ['-p', String(pid), '-o', 'lstart='], (err, stdout) => {
|
|
525
|
+
if (err || !stdout.trim()) {
|
|
526
|
+
resolve(null);
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
const date = new Date(stdout.trim());
|
|
530
|
+
if (isNaN(date.getTime())) {
|
|
531
|
+
resolve(null);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
resolve(date.getTime());
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
else if (process.platform === 'linux') {
|
|
538
|
+
// Linux: read /proc/{pid}/stat and parse starttime (field 22)
|
|
539
|
+
fs.readFile(`/proc/${pid}/stat`, 'utf-8', (err, data) => {
|
|
540
|
+
if (err) {
|
|
541
|
+
resolve(null);
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
// Fields in /proc/PID/stat are space-separated, but field 2 (comm) may
|
|
545
|
+
// contain spaces in parentheses. Find the last ')' to skip past it.
|
|
546
|
+
const closeParenIdx = data.lastIndexOf(')');
|
|
547
|
+
if (closeParenIdx === -1) {
|
|
548
|
+
resolve(null);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
const fields = data.substring(closeParenIdx + 2).split(' ');
|
|
552
|
+
// Field 22 is starttime, but after stripping comm it's at index 19
|
|
553
|
+
// (fields 3-51, so starttime = field 22 → index 22-3 = 19)
|
|
554
|
+
const startTimeTicks = parseInt(fields[19], 10);
|
|
555
|
+
if (isNaN(startTimeTicks)) {
|
|
556
|
+
resolve(null);
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
// Convert clock ticks to ms: we need the system boot time + starttime
|
|
560
|
+
// This is complex — use a simpler approach via /proc/PID/stat creation time
|
|
561
|
+
fs.stat(`/proc/${pid}`, (statErr, stat) => {
|
|
562
|
+
if (statErr) {
|
|
563
|
+
resolve(null);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
// /proc/PID directory creation time approximates process start time
|
|
567
|
+
resolve(stat.ctimeMs);
|
|
568
|
+
});
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
resolve(null);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
catch {
|
|
576
|
+
// Defensive: if execFile/readFile throws synchronously (e.g., EPERM
|
|
577
|
+
// in restricted environments), return null instead of rejecting.
|
|
578
|
+
resolve(null);
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/terminal/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShellperClient: Tower's connection to a single shellper process.
|
|
3
|
+
*
|
|
4
|
+
* Connects to a shellper via Unix socket, performs HELLO/WELCOME handshake,
|
|
5
|
+
* and provides a typed API for sending/receiving frames. Emits events for
|
|
6
|
+
* data, exit, replay, and errors.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const client = new ShellperClient('/path/to/shellper.sock');
|
|
10
|
+
* const welcome = await client.connect();
|
|
11
|
+
* client.on('data', (buf) => { ... });
|
|
12
|
+
* client.write('ls\n');
|
|
13
|
+
* client.disconnect();
|
|
14
|
+
*/
|
|
15
|
+
import { EventEmitter } from 'node:events';
|
|
16
|
+
import { type WelcomeMessage, type SpawnMessage } from './shellper-protocol.js';
|
|
17
|
+
export interface IShellperClient extends EventEmitter {
|
|
18
|
+
connect(): Promise<WelcomeMessage>;
|
|
19
|
+
disconnect(): void;
|
|
20
|
+
write(data: string | Buffer): void;
|
|
21
|
+
resize(cols: number, rows: number): void;
|
|
22
|
+
signal(sig: number): void;
|
|
23
|
+
spawn(msg: SpawnMessage): void;
|
|
24
|
+
ping(): void;
|
|
25
|
+
getReplayData(): Buffer | null;
|
|
26
|
+
waitForReplay(timeoutMs?: number): Promise<Buffer>;
|
|
27
|
+
readonly connected: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare class ShellperClient extends EventEmitter implements IShellperClient {
|
|
30
|
+
private readonly socketPath;
|
|
31
|
+
private socket;
|
|
32
|
+
private _connected;
|
|
33
|
+
private replayData;
|
|
34
|
+
constructor(socketPath: string);
|
|
35
|
+
/**
|
|
36
|
+
* Emit an 'error' event only if listeners are attached.
|
|
37
|
+
* Prevents Node.js from throwing on unhandled 'error' events,
|
|
38
|
+
* which would crash Tower.
|
|
39
|
+
*/
|
|
40
|
+
private safeEmitError;
|
|
41
|
+
get connected(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Connect to the shellper, perform HELLO/WELCOME handshake.
|
|
44
|
+
* Resolves with the WelcomeMessage on success.
|
|
45
|
+
* Rejects on connection error or handshake failure.
|
|
46
|
+
*/
|
|
47
|
+
connect(): Promise<WelcomeMessage>;
|
|
48
|
+
private handleFrame;
|
|
49
|
+
disconnect(): void;
|
|
50
|
+
private cleanup;
|
|
51
|
+
write(data: string | Buffer): void;
|
|
52
|
+
resize(cols: number, rows: number): void;
|
|
53
|
+
signal(sig: number): void;
|
|
54
|
+
spawn(msg: SpawnMessage): void;
|
|
55
|
+
ping(): void;
|
|
56
|
+
/** Get the last received replay data, or null if none. */
|
|
57
|
+
getReplayData(): Buffer | null;
|
|
58
|
+
/**
|
|
59
|
+
* Wait for the REPLAY frame to arrive after connection.
|
|
60
|
+
* The shellper sends REPLAY immediately after WELCOME, but they may
|
|
61
|
+
* arrive in separate reads. Returns the replay data, or empty Buffer
|
|
62
|
+
* if no REPLAY arrives within the timeout (shellper had nothing to replay).
|
|
63
|
+
*/
|
|
64
|
+
waitForReplay(timeoutMs?: number): Promise<Buffer>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=shellper-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellper-client.d.ts","sourceRoot":"","sources":["../../src/terminal/shellper-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAcL,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC,UAAU,IAAI,IAAI,CAAC;IACnB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/B,IAAI,IAAI,IAAI,CAAC;IACb,aAAa,IAAI,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,qBAAa,cAAe,SAAQ,YAAa,YAAW,eAAe;IAK7D,OAAO,CAAC,QAAQ,CAAC,UAAU;IAJvC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAuB;gBAEZ,UAAU,EAAE,MAAM;IAI/C;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAMrB,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;IAgGlC,OAAO,CAAC,WAAW;IAuCnB,UAAU,IAAI,IAAI;IAIlB,OAAO,CAAC,OAAO;IAQf,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKlC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKzB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAK9B,IAAI,IAAI,IAAI;IAKZ,0DAA0D;IAC1D,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B;;;;;OAKG;IACH,aAAa,CAAC,SAAS,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,CAAC;CAgBxD"}
|