borgmcp 1.1.15 → 2.0.2
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/CONTRIBUTING.md +15 -0
- package/LICENSE +201 -33
- package/NOTICE +2 -0
- package/README.md +85 -36
- package/SECURITY.md +7 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +63 -1
- package/dist/agent-runtime.js.map +1 -0
- package/dist/assimilate-cmd.d.ts +96 -17
- package/dist/assimilate-cmd.d.ts.map +1 -0
- package/dist/assimilate-cmd.js +1396 -48
- package/dist/assimilate-cmd.js.map +1 -0
- package/dist/assimilate-deps.d.ts.map +1 -0
- package/dist/assimilate-deps.js +384 -3
- package/dist/assimilate-deps.js.map +1 -0
- package/dist/assimilate-guard.d.ts +5 -7
- package/dist/assimilate-guard.d.ts.map +1 -0
- package/dist/assimilate-guard.js +60 -2
- package/dist/assimilate-guard.js.map +1 -0
- package/dist/assimilate-welcome.d.ts +1 -1
- package/dist/assimilate-welcome.d.ts.map +1 -0
- package/dist/assimilate-welcome.js +32 -2
- package/dist/assimilate-welcome.js.map +1 -0
- package/dist/auth-env.d.ts +7 -50
- package/dist/auth-env.d.ts.map +1 -0
- package/dist/auth-env.js +22 -1
- package/dist/auth-env.js.map +1 -0
- package/dist/backends/launch-all-pastelist.d.ts.map +1 -0
- package/dist/backends/launch-all-pastelist.js +11 -4
- package/dist/backends/launch-all-pastelist.js.map +1 -0
- package/dist/backends/launch-all-tmux.d.ts.map +1 -0
- package/dist/backends/launch-all-tmux.js +49 -1
- package/dist/backends/launch-all-tmux.js.map +1 -0
- package/dist/backends/launch-all-windows.d.ts.map +1 -0
- package/dist/backends/launch-all-windows.js +86 -12
- package/dist/backends/launch-all-windows.js.map +1 -0
- package/dist/bare-launch-menu.d.ts.map +1 -0
- package/dist/bare-launch-menu.js +83 -6
- package/dist/bare-launch-menu.js.map +1 -0
- package/dist/claude-launch-args.d.ts.map +1 -0
- package/dist/claude-launch-args.js +34 -1
- package/dist/claude-launch-args.js.map +1 -0
- package/dist/claude.d.ts.map +1 -0
- package/dist/claude.js +486 -14
- package/dist/claude.js.map +1 -0
- package/dist/cleanup-cmd.d.ts +5 -5
- package/dist/cleanup-cmd.d.ts.map +1 -0
- package/dist/cleanup-cmd.js +453 -14
- package/dist/cleanup-cmd.js.map +1 -0
- package/dist/clear-rewake-core.d.ts.map +1 -0
- package/dist/clear-rewake-core.js +23 -2
- package/dist/clear-rewake-core.js.map +1 -0
- package/dist/clear-rewake.d.ts.map +1 -0
- package/dist/clear-rewake.js +19 -1
- package/dist/clear-rewake.js.map +1 -0
- package/dist/cli-help.d.ts +5 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +104 -56
- package/dist/cli-help.js.map +1 -0
- package/dist/cli-platform.d.ts.map +1 -0
- package/dist/cli-platform.js +106 -4
- package/dist/cli-platform.js.map +1 -0
- package/dist/cli-tool-approval.d.ts +84 -0
- package/dist/cli-tool-approval.d.ts.map +1 -0
- package/dist/cli-tool-approval.js +583 -0
- package/dist/cli-tool-approval.js.map +1 -0
- package/dist/codex-app-server.d.ts.map +1 -0
- package/dist/codex-app-server.js +228 -4
- package/dist/codex-app-server.js.map +1 -0
- package/dist/codex-app-wake.d.ts +9 -11
- package/dist/codex-app-wake.d.ts.map +1 -0
- package/dist/codex-app-wake.js +436 -2
- package/dist/codex-app-wake.js.map +1 -0
- package/dist/codex-launch.d.ts.map +1 -0
- package/dist/codex-launch.js +102 -2
- package/dist/codex-launch.js.map +1 -0
- package/dist/codex-remote.d.ts +6 -1
- package/dist/codex-remote.d.ts.map +1 -0
- package/dist/codex-remote.js +394 -1
- package/dist/codex-remote.js.map +1 -0
- package/dist/codex-wake-resolve.d.ts +4 -4
- package/dist/codex-wake-resolve.d.ts.map +1 -0
- package/dist/codex-wake-resolve.js +127 -1
- package/dist/codex-wake-resolve.js.map +1 -0
- package/dist/config-utils.d.ts +2 -2
- package/dist/config-utils.d.ts.map +1 -0
- package/dist/config-utils.js +766 -3
- package/dist/config-utils.js.map +1 -0
- package/dist/config.d.ts +98 -61
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +426 -1
- package/dist/config.js.map +1 -0
- package/dist/console-prefix.d.ts.map +1 -0
- package/dist/console-prefix.js +96 -1
- package/dist/console-prefix.js.map +1 -0
- package/dist/cube-name.d.ts.map +1 -0
- package/dist/cube-name.js +67 -1
- package/dist/cube-name.js.map +1 -0
- package/dist/cubes.d.ts +126 -18
- package/dist/cubes.d.ts.map +1 -0
- package/dist/cubes.js +412 -4
- package/dist/cubes.js.map +1 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +71 -1
- package/dist/debug.js.map +1 -0
- package/dist/direct-log.d.ts.map +1 -0
- package/dist/direct-log.js +11 -1
- package/dist/direct-log.js.map +1 -0
- package/dist/docs-sections.d.ts +11 -10
- package/dist/docs-sections.d.ts.map +1 -0
- package/dist/docs-sections.js +113 -3
- package/dist/docs-sections.js.map +1 -0
- package/dist/drone-lifecycle.d.ts +5 -21
- package/dist/drone-lifecycle.d.ts.map +1 -0
- package/dist/drone-lifecycle.js +57 -8
- package/dist/drone-lifecycle.js.map +1 -0
- package/dist/drone-management.d.ts +29 -0
- package/dist/drone-management.d.ts.map +1 -0
- package/dist/drone-management.js +109 -0
- package/dist/drone-management.js.map +1 -0
- package/dist/ensure-mcp-config.d.ts.map +1 -0
- package/dist/ensure-mcp-config.js +36 -1
- package/dist/ensure-mcp-config.js.map +1 -0
- package/dist/evict-drone.d.ts +10 -2
- package/dist/evict-drone.d.ts.map +1 -0
- package/dist/evict-drone.js +60 -1
- package/dist/evict-drone.js.map +1 -0
- package/dist/gc-orphan-inboxes.d.ts.map +1 -0
- package/dist/gc-orphan-inboxes.js +177 -1
- package/dist/gc-orphan-inboxes.js.map +1 -0
- package/dist/inbox-monitor.d.ts +1 -1
- package/dist/inbox-monitor.d.ts.map +1 -0
- package/dist/inbox-monitor.js +856 -3
- package/dist/inbox-monitor.js.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1034 -37
- package/dist/index.js.map +1 -0
- package/dist/launch-all-cmd.d.ts.map +1 -0
- package/dist/launch-all-cmd.js +377 -37
- package/dist/launch-all-cmd.js.map +1 -0
- package/dist/launch-all-command.d.ts.map +1 -0
- package/dist/launch-all-command.js +24 -1
- package/dist/launch-all-command.js.map +1 -0
- package/dist/launch-all-deps.d.ts +3 -8
- package/dist/launch-all-deps.d.ts.map +1 -0
- package/dist/launch-all-deps.js +99 -1
- package/dist/launch-all-deps.js.map +1 -0
- package/dist/launch-all-discovery.d.ts +1 -0
- package/dist/launch-all-discovery.d.ts.map +1 -0
- package/dist/launch-all-discovery.js +90 -4
- package/dist/launch-all-discovery.js.map +1 -0
- package/dist/launch-all-locks.d.ts.map +1 -0
- package/dist/launch-all-locks.js +54 -1
- package/dist/launch-all-locks.js.map +1 -0
- package/dist/launch-gate.d.ts +2 -2
- package/dist/launch-gate.d.ts.map +1 -0
- package/dist/launch-gate.js +73 -1
- package/dist/launch-gate.js.map +1 -0
- package/dist/lifecycle-log-guard.d.ts.map +1 -0
- package/dist/lifecycle-log-guard.js +93 -2
- package/dist/lifecycle-log-guard.js.map +1 -0
- package/dist/list-roles-render.d.ts.map +1 -0
- package/dist/list-roles-render.js +40 -6
- package/dist/list-roles-render.js.map +1 -0
- package/dist/local-log-routing.d.ts +19 -0
- package/dist/local-log-routing.d.ts.map +1 -0
- package/dist/local-log-routing.js +67 -0
- package/dist/local-log-routing.js.map +1 -0
- package/dist/local-manage-tool-result.d.ts +8 -0
- package/dist/local-manage-tool-result.d.ts.map +1 -0
- package/dist/local-manage-tool-result.js +10 -0
- package/dist/local-manage-tool-result.js.map +1 -0
- package/dist/local-server-cursor.d.ts +34 -0
- package/dist/local-server-cursor.d.ts.map +1 -0
- package/dist/local-server-cursor.js +151 -0
- package/dist/local-server-cursor.js.map +1 -0
- package/dist/log-audit.d.ts.map +1 -0
- package/dist/log-audit.js +194 -3
- package/dist/log-audit.js.map +1 -0
- package/dist/log-stream.d.ts +35 -18
- package/dist/log-stream.d.ts.map +1 -0
- package/dist/log-stream.js +1270 -12
- package/dist/log-stream.js.map +1 -0
- package/dist/model-presets.d.ts.map +1 -0
- package/dist/model-presets.js +19 -1
- package/dist/model-presets.js.map +1 -0
- package/dist/name-validator.d.ts.map +1 -0
- package/dist/name-validator.js +22 -1
- package/dist/name-validator.js.map +1 -0
- package/dist/opencode-drone.d.ts.map +1 -0
- package/dist/opencode-drone.js +438 -4
- package/dist/opencode-drone.js.map +1 -0
- package/dist/opencode-plugin.d.ts +1 -1
- package/dist/opencode-plugin.d.ts.map +1 -0
- package/dist/opencode-plugin.js +29 -4
- package/dist/opencode-plugin.js.map +1 -0
- package/dist/parse-assimilate-args.d.ts +1 -1
- package/dist/parse-assimilate-args.d.ts.map +1 -0
- package/dist/parse-assimilate-args.js +125 -1
- package/dist/parse-assimilate-args.js.map +1 -0
- package/dist/parse-launch-all-args.d.ts.map +1 -0
- package/dist/parse-launch-all-args.js +70 -1
- package/dist/parse-launch-all-args.js.map +1 -0
- package/dist/postinstall-banner.d.ts.map +1 -0
- package/dist/postinstall-banner.js +27 -2
- package/dist/postinstall-banner.js.map +1 -0
- package/dist/postinstall.d.ts.map +1 -0
- package/dist/postinstall.js +32 -5
- package/dist/postinstall.js.map +1 -0
- package/dist/readiness-probe.d.ts.map +1 -0
- package/dist/readiness-probe.js +9 -1
- package/dist/readiness-probe.js.map +1 -0
- package/dist/regen-format.d.ts.map +1 -0
- package/dist/regen-format.js +545 -13
- package/dist/regen-format.js.map +1 -0
- package/dist/regen.d.ts.map +1 -0
- package/dist/regen.js +141 -5
- package/dist/regen.js.map +1 -0
- package/dist/remote-client.d.ts +88 -173
- package/dist/remote-client.d.ts.map +1 -0
- package/dist/remote-client.js +997 -1
- package/dist/remote-client.js.map +1 -0
- package/dist/reset-local-seat-cmd.d.ts +50 -0
- package/dist/reset-local-seat-cmd.d.ts.map +1 -0
- package/dist/reset-local-seat-cmd.js +169 -0
- package/dist/reset-local-seat-cmd.js.map +1 -0
- package/dist/role-match.d.ts.map +1 -0
- package/dist/role-match.js +23 -1
- package/dist/role-match.js.map +1 -0
- package/dist/role-resolver.d.ts.map +1 -0
- package/dist/role-resolver.js +60 -1
- package/dist/role-resolver.js.map +1 -0
- package/dist/roster-render.d.ts.map +1 -0
- package/dist/roster-render.js +121 -3
- package/dist/roster-render.js.map +1 -0
- package/dist/seat-probe.d.ts +32 -13
- package/dist/seat-probe.d.ts.map +1 -0
- package/dist/seat-probe.js +78 -1
- package/dist/seat-probe.js.map +1 -0
- package/dist/seat-store.d.ts +76 -0
- package/dist/seat-store.d.ts.map +1 -0
- package/dist/seat-store.js +309 -0
- package/dist/seat-store.js.map +1 -0
- package/dist/seats.d.ts +375 -0
- package/dist/seats.d.ts.map +1 -0
- package/dist/seats.js +670 -0
- package/dist/seats.js.map +1 -0
- package/dist/self-path.d.ts +27 -0
- package/dist/self-path.d.ts.map +1 -0
- package/dist/self-path.js +43 -0
- package/dist/self-path.js.map +1 -0
- package/dist/server-endpoint.d.ts +9 -0
- package/dist/server-endpoint.d.ts.map +1 -0
- package/dist/server-endpoint.js +38 -0
- package/dist/server-endpoint.js.map +1 -0
- package/dist/server-errors.d.ts +50 -0
- package/dist/server-errors.d.ts.map +1 -0
- package/dist/server-errors.js +79 -0
- package/dist/server-errors.js.map +1 -0
- package/dist/server-handshake.d.ts +197 -0
- package/dist/server-handshake.d.ts.map +1 -0
- package/dist/server-handshake.js +533 -0
- package/dist/server-handshake.js.map +1 -0
- package/dist/server-response.d.ts +3 -0
- package/dist/server-response.d.ts.map +1 -0
- package/dist/server-response.js +67 -0
- package/dist/server-response.js.map +1 -0
- package/dist/server-trust.d.ts +14 -0
- package/dist/server-trust.d.ts.map +1 -0
- package/dist/server-trust.js +225 -0
- package/dist/server-trust.js.map +1 -0
- package/dist/session-continuity.d.ts +33 -0
- package/dist/session-continuity.d.ts.map +1 -0
- package/dist/session-continuity.js +220 -0
- package/dist/session-continuity.js.map +1 -0
- package/dist/setup-confirm.d.ts +3 -3
- package/dist/setup-confirm.d.ts.map +1 -0
- package/dist/setup-confirm.js +126 -2
- package/dist/setup-confirm.js.map +1 -0
- package/dist/setup.d.ts +5 -3
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +169 -46
- package/dist/setup.js.map +1 -0
- package/dist/shell-escape.d.ts.map +1 -0
- package/dist/shell-escape.js +22 -1
- package/dist/shell-escape.js.map +1 -0
- package/dist/spawn.d.ts +2 -2
- package/dist/spawn.d.ts.map +1 -0
- package/dist/spawn.js +29 -10
- package/dist/spawn.js.map +1 -0
- package/dist/startup-services.d.ts +0 -1
- package/dist/startup-services.d.ts.map +1 -0
- package/dist/startup-services.js +26 -1
- package/dist/startup-services.js.map +1 -0
- package/dist/stream-owner.d.ts +6 -2
- package/dist/stream-owner.d.ts.map +1 -0
- package/dist/stream-owner.js +547 -2
- package/dist/stream-owner.js.map +1 -0
- package/dist/stream-status.d.ts +1 -1
- package/dist/stream-status.d.ts.map +1 -0
- package/dist/stream-status.js +268 -3
- package/dist/stream-status.js.map +1 -0
- package/dist/sync-roles-render.d.ts.map +1 -0
- package/dist/sync-roles-render.js +118 -3
- package/dist/sync-roles-render.js.map +1 -0
- package/dist/sync.d.ts +1 -1
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +286 -22
- package/dist/sync.js.map +1 -0
- package/dist/terminal-title.d.ts.map +1 -0
- package/dist/terminal-title.js +68 -1
- package/dist/terminal-title.js.map +1 -0
- package/dist/token-store.d.ts +17 -111
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +81 -1
- package/dist/token-store.js.map +1 -0
- package/dist/tool-manifest.d.ts +4 -8
- package/dist/tool-manifest.d.ts.map +1 -0
- package/dist/tool-manifest.js +554 -1
- package/dist/tool-manifest.js.map +1 -0
- package/dist/tool-scope.d.ts +8 -12
- package/dist/tool-scope.d.ts.map +1 -0
- package/dist/tool-scope.js +97 -1
- package/dist/tool-scope.js.map +1 -0
- package/dist/types.d.ts +1 -5
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/unknown-subcommand.d.ts +1 -1
- package/dist/unknown-subcommand.d.ts.map +1 -0
- package/dist/unknown-subcommand.js +37 -1
- package/dist/unknown-subcommand.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +78 -2
- package/dist/version.js.map +1 -0
- package/dist/working-repo.d.ts.map +1 -0
- package/dist/working-repo.js +81 -1
- package/dist/working-repo.js.map +1 -0
- package/dist/worktree-lifecycle.d.ts.map +1 -0
- package/dist/worktree-lifecycle.js +205 -2
- package/dist/worktree-lifecycle.js.map +1 -0
- package/docs/EXTRACTION_PROVENANCE.md +42 -0
- package/docs/LOCAL_SERVER.md +103 -0
- package/docs/RELEASING.md +129 -0
- package/package.json +52 -34
- package/src/agent-runtime.ts +69 -0
- package/src/assimilate-cmd.ts +1864 -0
- package/src/assimilate-deps.ts +444 -0
- package/src/assimilate-guard.ts +84 -0
- package/src/assimilate-welcome.ts +39 -0
- package/src/auth-env.ts +21 -0
- package/src/backends/launch-all-pastelist.ts +18 -0
- package/src/backends/launch-all-tmux.ts +75 -0
- package/src/backends/launch-all-windows.ts +110 -0
- package/src/bare-launch-menu.ts +148 -0
- package/src/claude-launch-args.ts +35 -0
- package/src/claude.ts +561 -0
- package/src/cleanup-cmd.ts +581 -0
- package/src/clear-rewake-core.ts +34 -0
- package/src/clear-rewake.ts +18 -0
- package/src/cli-help.ts +116 -0
- package/src/cli-platform.ts +127 -0
- package/src/cli-tool-approval.ts +716 -0
- package/src/codex-app-server.ts +238 -0
- package/src/codex-app-wake.ts +524 -0
- package/src/codex-launch.ts +140 -0
- package/src/codex-remote.ts +500 -0
- package/src/codex-wake-resolve.ts +155 -0
- package/src/config-utils.ts +811 -0
- package/src/config.ts +595 -0
- package/src/console-prefix.ts +99 -0
- package/src/cube-name.ts +69 -0
- package/src/cubes.ts +583 -0
- package/src/debug.ts +73 -0
- package/src/direct-log.ts +9 -0
- package/src/docs-sections.ts +129 -0
- package/src/drone-lifecycle.ts +62 -0
- package/src/drone-management.ts +162 -0
- package/src/ensure-mcp-config.ts +54 -0
- package/src/evict-drone.ts +82 -0
- package/src/gc-orphan-inboxes.ts +229 -0
- package/src/inbox-monitor.ts +1005 -0
- package/src/index.ts +1201 -0
- package/src/launch-all-cmd.ts +450 -0
- package/src/launch-all-command.ts +30 -0
- package/src/launch-all-deps.ts +188 -0
- package/src/launch-all-discovery.ts +118 -0
- package/src/launch-all-locks.ts +74 -0
- package/src/launch-gate.ts +80 -0
- package/src/lifecycle-log-guard.ts +144 -0
- package/src/list-roles-render.ts +52 -0
- package/src/local-log-routing.ts +106 -0
- package/src/local-manage-tool-result.ts +10 -0
- package/src/local-server-cursor.ts +188 -0
- package/src/log-audit.ts +207 -0
- package/src/log-stream.ts +1567 -0
- package/src/model-presets.ts +22 -0
- package/src/name-validator.ts +23 -0
- package/src/opencode-drone.ts +528 -0
- package/src/opencode-plugin.ts +38 -0
- package/src/parse-assimilate-args.ts +125 -0
- package/src/parse-launch-all-args.ts +100 -0
- package/src/postinstall-banner.ts +37 -0
- package/src/postinstall.ts +36 -0
- package/src/readiness-probe.ts +12 -0
- package/src/regen-format.ts +651 -0
- package/src/regen.ts +150 -0
- package/src/remote-client.ts +1457 -0
- package/src/reset-local-seat-cmd.ts +227 -0
- package/src/role-match.ts +29 -0
- package/src/role-resolver.ts +93 -0
- package/src/roster-render.ts +196 -0
- package/src/seat-probe.ts +115 -0
- package/src/seat-store.ts +333 -0
- package/src/seats.ts +911 -0
- package/src/self-path.ts +51 -0
- package/src/server-endpoint.ts +38 -0
- package/src/server-errors.ts +95 -0
- package/src/server-handshake.ts +816 -0
- package/src/server-response.ts +76 -0
- package/src/server-trust.ts +245 -0
- package/src/session-continuity.ts +280 -0
- package/src/setup-confirm.ts +171 -0
- package/src/setup.ts +186 -0
- package/src/shell-escape.ts +22 -0
- package/src/spawn.ts +31 -0
- package/src/startup-services.ts +36 -0
- package/src/stream-owner.ts +686 -0
- package/src/stream-status.ts +337 -0
- package/src/sync-roles-render.ts +163 -0
- package/src/sync.ts +363 -0
- package/src/terminal-title.ts +76 -0
- package/src/token-store.ts +102 -0
- package/src/tool-manifest.ts +610 -0
- package/src/tool-scope.ts +110 -0
- package/src/types.ts +5 -0
- package/src/unknown-subcommand.ts +35 -0
- package/src/version.ts +82 -0
- package/src/working-repo.ts +99 -0
- package/src/worktree-lifecycle.ts +254 -0
- package/dist/auth-recovery.d.ts +0 -33
- package/dist/auth-recovery.js +0 -1
- package/dist/auth.d.ts +0 -103
- package/dist/auth.js +0 -39
- package/dist/device-auth.d.ts +0 -75
- package/dist/device-auth.js +0 -1
- package/dist/drone-address.d.ts +0 -26
- package/dist/drone-address.js +0 -1
- package/dist/get-started.d.ts +0 -20
- package/dist/get-started.js +0 -2
- package/dist/health-beat.d.ts +0 -134
- package/dist/health-beat.js +0 -1
- package/dist/role-section.d.ts +0 -110
- package/dist/role-section.js +0 -8
- package/dist/setup-action.d.ts +0 -20
- package/dist/setup-action.js +0 -1
- package/dist/stale-version-check.d.ts +0 -40
- package/dist/stale-version-check.js +0 -1
- package/dist/subscription-retry.d.ts +0 -40
- package/dist/subscription-retry.js +0 -1
- package/dist/templates.d.ts +0 -107
- package/dist/templates.js +0 -359
- package/dist/token-crypto.d.ts +0 -50
- package/dist/token-crypto.js +0 -1
package/dist/cleanup-cmd.js
CHANGED
|
@@ -1,14 +1,453 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
`)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
`
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `borg cleanup` — reap orphaned worktrees for evicted drones (gh#882).
|
|
3
|
+
*
|
|
4
|
+
* An evicted drone (manual `borg_evict-drone`, watchdog
|
|
5
|
+
* `autoEvictPresumedDead`, or gh#877 graceful self-shutdown) leaves its
|
|
6
|
+
* worktree dir (`~/.borg/worktrees/<repo>/<name>`) + its `wt-<suffix>`
|
|
7
|
+
* branch on disk. Nothing reclaims them. This command finds and SAFELY
|
|
8
|
+
* removes worktrees orphaned by eviction — never destroying live,
|
|
9
|
+
* dirty, unmerged, or precious-local-state work.
|
|
10
|
+
*
|
|
11
|
+
* Pure composition over `worktree-lifecycle.ts` + the gh#877 per-seat
|
|
12
|
+
* `410 DRONE_EVICTED` discrimination (via the seat-probe seam). All git +
|
|
13
|
+
* network + filesystem effects are behind injected deps so every branch is
|
|
14
|
+
* unit-testable without a live repo, network, or $HOME.
|
|
15
|
+
*
|
|
16
|
+
* SEC gate (gh#882, S1–S5 — design entries 98e45fbf / acd76794):
|
|
17
|
+
* S1 Destructive prune authority = server 410 DRONE_EVICTED on the
|
|
18
|
+
* worktree's OWN saved-seat token, ONLY.
|
|
19
|
+
* S2 KEEP classes (any one → never prune, surface): dirty; unmerged;
|
|
20
|
+
* non-regenerable gitignored-local.
|
|
21
|
+
* S3 Report-only until gh#877 is DEPLOYED. The destructive path keys on
|
|
22
|
+
* the 410 CODE — pre-deploy the server returns 401 → probe resolves
|
|
23
|
+
* 'indeterminate' → report-only → safe. No flag / deploy coupling;
|
|
24
|
+
* --prune auto-unlocks the day 410 ships.
|
|
25
|
+
* S4 (a) gitignored-aware clean-gate, DEFAULT-DENY: block on ANY
|
|
26
|
+
* gitignored-local present UNLESS it matches a curated REGENERABLE
|
|
27
|
+
* allowlist (NOT a secret denylist — that fails open). Layered here,
|
|
28
|
+
* NOT in the shared isCleanTree/classifyDirty (those feed
|
|
29
|
+
* assimilate/sync — widening them perturbs that path).
|
|
30
|
+
* (b) fetch origin/main BEFORE the isMerged gate.
|
|
31
|
+
* S5 Auto-prune strictly under canonicalized (realpath) worktreesHome —
|
|
32
|
+
* reject symlink-escape / `..`. Report MAY widen to legacy siblings
|
|
33
|
+
* outside worktreesHome (label "legacy — manual review"); report ≠ delete.
|
|
34
|
+
*/
|
|
35
|
+
import { spawnSync } from 'node:child_process';
|
|
36
|
+
import { realpathSync } from 'node:fs';
|
|
37
|
+
import { sep, basename, dirname } from 'node:path';
|
|
38
|
+
import { homedir } from 'node:os';
|
|
39
|
+
import chalk from 'chalk';
|
|
40
|
+
import { classifyDirty, isMerged, localBranchExists, perWorktreeBranchName, worktreesHome, } from './worktree-lifecycle.js';
|
|
41
|
+
import { readAllProjectIdentities, } from './cubes.js';
|
|
42
|
+
import { defaultProbeSeat } from './seat-probe.js';
|
|
43
|
+
const DEFAULT_REF = 'origin/main';
|
|
44
|
+
// ------------------------------------------------------------------
|
|
45
|
+
// S4a — gitignored-aware clean gate (DEFAULT-DENY via regenerable allowlist)
|
|
46
|
+
// ------------------------------------------------------------------
|
|
47
|
+
/**
|
|
48
|
+
* Regenerable build/scratch artifacts that are SAFE to delete with the
|
|
49
|
+
* worktree (present in nearly every worktree; never precious). DEFAULT-DENY:
|
|
50
|
+
* an ignored path is "regenerable" ONLY if it matches this allowlist;
|
|
51
|
+
* EVERYTHING else (unknown ignored path) is assumed PRECIOUS and blocks the
|
|
52
|
+
* prune. A secret-denylist would fail OPEN on an unanticipated precious file
|
|
53
|
+
* (`data/`, `.dev.vars`, `credentials.json`, a private key) — so we allowlist
|
|
54
|
+
* the bounded disposable set instead (SEC S4a / B24 9e79b0b1).
|
|
55
|
+
*/
|
|
56
|
+
const REGENERABLE_DIRS = new Set([
|
|
57
|
+
'node_modules',
|
|
58
|
+
'dist',
|
|
59
|
+
'build',
|
|
60
|
+
'.next',
|
|
61
|
+
'coverage',
|
|
62
|
+
'.wrangler',
|
|
63
|
+
'.playwright-mcp',
|
|
64
|
+
// gh#882 follow-up: `.claude/` is Claude Code's PER-WORKTREE scaffolding
|
|
65
|
+
// (session state, scheduled-task locks, and a `settings.local.json` of
|
|
66
|
+
// worktree-local permission grants). It is present in EVERY borg worktree, so
|
|
67
|
+
// without this entry the S4a default-deny gate flagged it precious and `borg
|
|
68
|
+
// cleanup` could NEVER prune ANY worktree (0 prunable, N kept). It is a
|
|
69
|
+
// DELIBERATE, narrow carve-out: the gate only ever runs on an already-EVICTED,
|
|
70
|
+
// clean, merged worktree (410 DRONE_EVICTED stays the SOLE delete authority —
|
|
71
|
+
// S1), and `.claude/` is recreated on the next assimilate; its only
|
|
72
|
+
// arguably-precious fragment (`settings.local.json`) is worktree-local, never
|
|
73
|
+
// carries to the parent, and dies with the dead seat. git collapses an ignored
|
|
74
|
+
// dir to a single `!! .claude/` porcelain line, so segment-matching `.claude`
|
|
75
|
+
// here covers root + nested `<sub>/.claude/` and is the only expressible
|
|
76
|
+
// granularity. A truly-precious sibling (`data/`, `credentials.json`,
|
|
77
|
+
// `.env.test`, `.dev.vars`) emits its OWN `!!` line, still fails this
|
|
78
|
+
// allowlist, and still → SURVIVES-clobber (T-GITIGNORED-DEFAULTDENY intact).
|
|
79
|
+
// RESIDUAL RISK (accepted): any file hand-placed DIRECTLY under `.claude/` in an
|
|
80
|
+
// evicted worktree is sacrificial and silently removed — `git worktree remove`
|
|
81
|
+
// without `--force` does NOT refuse on ignored content, and a gitignore negation
|
|
82
|
+
// (`!.claude/keep`) is inert once the parent is excluded, so the allowlist
|
|
83
|
+
// decision here is the SOLE guard. Today `.claude/` is exclusively Claude Code
|
|
84
|
+
// scaffolding; this comment makes the assumption auditable.
|
|
85
|
+
'.claude',
|
|
86
|
+
]);
|
|
87
|
+
const REGENERABLE_FILES = new Set(['.DS_Store', 'worker-configuration.d.ts']);
|
|
88
|
+
const REGENERABLE_SUFFIXES = ['.log', '.tsbuildinfo', '.tmp'];
|
|
89
|
+
/** True iff a single gitignored path is a known-regenerable artifact. */
|
|
90
|
+
export function isRegenerableIgnored(ignoredPath) {
|
|
91
|
+
const clean = ignoredPath.replace(/\/+$/, ''); // strip trailing slash
|
|
92
|
+
const segments = clean.split('/').filter((s) => s.length > 0);
|
|
93
|
+
if (segments.some((s) => REGENERABLE_DIRS.has(s)))
|
|
94
|
+
return true;
|
|
95
|
+
const base = segments[segments.length - 1] ?? clean;
|
|
96
|
+
if (REGENERABLE_FILES.has(base))
|
|
97
|
+
return true;
|
|
98
|
+
if (REGENERABLE_SUFFIXES.some((suf) => base.endsWith(suf)))
|
|
99
|
+
return true;
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Return the gitignored-local paths in `cwd` that are NOT regenerable — i.e.
|
|
104
|
+
* the precious-local-state files (`.env`, `.env.test`, `.dev.vars`, secrets,
|
|
105
|
+
* `data/`, …) that a prune would destroy forever. Non-empty → BLOCK (S4a).
|
|
106
|
+
*
|
|
107
|
+
* `git status --porcelain --ignored` emits ignored entries with a `!!` status
|
|
108
|
+
* prefix; git collapses an ignored directory to a single `!! dir/` entry, so
|
|
109
|
+
* segment-matching the reported path against the allowlist is sufficient.
|
|
110
|
+
*/
|
|
111
|
+
export function clobberClassIgnored(runSync, cwd) {
|
|
112
|
+
const r = runSync('git', ['status', '--porcelain', '--ignored'], cwd);
|
|
113
|
+
if (r.status !== 0) {
|
|
114
|
+
// Cannot determine ignored state → fail SAFE: treat as "has precious"
|
|
115
|
+
// so the worktree survives rather than risking a clobber.
|
|
116
|
+
return ['<git status --ignored failed — cannot verify clean>'];
|
|
117
|
+
}
|
|
118
|
+
const precious = [];
|
|
119
|
+
for (const line of r.stdout.split('\n')) {
|
|
120
|
+
if (!line.startsWith('!!'))
|
|
121
|
+
continue;
|
|
122
|
+
const path = line.slice(3).trim();
|
|
123
|
+
if (path.length === 0)
|
|
124
|
+
continue;
|
|
125
|
+
if (!isRegenerableIgnored(path))
|
|
126
|
+
precious.push(path);
|
|
127
|
+
}
|
|
128
|
+
return precious;
|
|
129
|
+
}
|
|
130
|
+
// ------------------------------------------------------------------
|
|
131
|
+
// Defaults
|
|
132
|
+
// ------------------------------------------------------------------
|
|
133
|
+
const defaultDeps = {
|
|
134
|
+
runSync: (cmd, args, cwd) => {
|
|
135
|
+
const r = spawnSync(cmd, args, { cwd, encoding: 'utf-8' });
|
|
136
|
+
return { status: r.status, stdout: r.stdout ?? '', stderr: r.stderr ?? '' };
|
|
137
|
+
},
|
|
138
|
+
homeDir: () => homedir(),
|
|
139
|
+
cwd: () => process.cwd(),
|
|
140
|
+
listSeats: () => readAllProjectIdentities(),
|
|
141
|
+
probeSeat: defaultProbeSeat,
|
|
142
|
+
realpath: (p) => realpathSync(p),
|
|
143
|
+
stdout: (line) => process.stdout.write(line),
|
|
144
|
+
stderr: (line) => process.stderr.write(line),
|
|
145
|
+
};
|
|
146
|
+
// (defaultProbeSeat now lives in seat-probe.ts — imported above.)
|
|
147
|
+
// ------------------------------------------------------------------
|
|
148
|
+
// Path anchoring (S5)
|
|
149
|
+
// ------------------------------------------------------------------
|
|
150
|
+
/**
|
|
151
|
+
* True iff `child`'s canonicalized real path is STRICTLY under `parent`'s
|
|
152
|
+
* canonicalized real path — rejecting `..` traversal AND symlink escape (a
|
|
153
|
+
* symlinked worktree whose realpath is outside worktreesHome is NOT a prune
|
|
154
|
+
* candidate). Returns false (never under) if either path can't be resolved.
|
|
155
|
+
*/
|
|
156
|
+
export function isStrictlyUnder(realpath, parent, child) {
|
|
157
|
+
let rp;
|
|
158
|
+
let rc;
|
|
159
|
+
try {
|
|
160
|
+
rp = realpath(parent);
|
|
161
|
+
rc = realpath(child);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
if (rc === rp)
|
|
167
|
+
return false; // the home dir itself is not "under" itself
|
|
168
|
+
const prefix = rp.endsWith(sep) ? rp : rp + sep;
|
|
169
|
+
return rc.startsWith(prefix);
|
|
170
|
+
}
|
|
171
|
+
// ------------------------------------------------------------------
|
|
172
|
+
// Enumeration
|
|
173
|
+
// ------------------------------------------------------------------
|
|
174
|
+
/** Parse `git worktree list --porcelain` → absolute worktree paths (in order). */
|
|
175
|
+
export function parseWorktreeList(porcelain) {
|
|
176
|
+
return parseWorktreeEntries(porcelain).map((e) => e.path);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Parse `git worktree list --porcelain` into `{path, branch}` entries (in
|
|
180
|
+
* order; primary first). `branch` is the ACTUAL checked-out branch name (from
|
|
181
|
+
* the `branch refs/heads/<name>` line) or null for a detached HEAD (no branch
|
|
182
|
+
* line). This is load-bearing (gh#882 CR blocker dcdd7fca): a drone cuts
|
|
183
|
+
* `fix/…`/`feat/…` off `wt-<suffix>` INSIDE the worktree, so the checked-out
|
|
184
|
+
* HEAD is commonly a feature branch with unpushed commits while `wt-<suffix>`
|
|
185
|
+
* stays at the merged base. The merged-gate + `git branch -d` MUST key on the
|
|
186
|
+
* actual HEAD branch, not the derived `wt-<suffix>`, or unmerged feature work
|
|
187
|
+
* is misclassified PRUNABLE.
|
|
188
|
+
*/
|
|
189
|
+
export function parseWorktreeEntries(porcelain) {
|
|
190
|
+
const entries = [];
|
|
191
|
+
let cur = null;
|
|
192
|
+
for (const line of porcelain.split('\n')) {
|
|
193
|
+
if (line.startsWith('worktree ')) {
|
|
194
|
+
if (cur)
|
|
195
|
+
entries.push(cur);
|
|
196
|
+
cur = { path: line.slice('worktree '.length).trim(), branch: null };
|
|
197
|
+
}
|
|
198
|
+
else if (line.startsWith('branch ') && cur) {
|
|
199
|
+
// `branch refs/heads/<name>` → <name>. A detached worktree emits
|
|
200
|
+
// `detached` (or no branch line) → branch stays null.
|
|
201
|
+
cur.branch = line.slice('branch '.length).trim().replace(/^refs\/heads\//, '');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (cur)
|
|
205
|
+
entries.push(cur);
|
|
206
|
+
return entries;
|
|
207
|
+
}
|
|
208
|
+
// ------------------------------------------------------------------
|
|
209
|
+
// Classification (per worktree)
|
|
210
|
+
// ------------------------------------------------------------------
|
|
211
|
+
/**
|
|
212
|
+
* Classify ONE borg-managed worktree (cheap-first gate order; the FIRST
|
|
213
|
+
* KEEP-class short-circuits — a transient probe failure on a dirty/unmerged
|
|
214
|
+
* tree never even reaches the network). Only `PRUNABLE` authorizes a delete.
|
|
215
|
+
*/
|
|
216
|
+
async function classifyWorktree(deps, worktreePath, actualBranch, seat) {
|
|
217
|
+
const { runSync } = deps;
|
|
218
|
+
// (1) dirty — tracked staged/unstaged/untracked. KEEP.
|
|
219
|
+
const dirty = classifyDirty(runSync, worktreePath);
|
|
220
|
+
const dirtyCount = dirty.staged.length + dirty.unstaged.length + dirty.untracked.length;
|
|
221
|
+
if (dirtyCount > 0) {
|
|
222
|
+
return { reason: 'SURVIVES-dirty', detail: `${dirtyCount} uncommitted file(s)` };
|
|
223
|
+
}
|
|
224
|
+
// (2) S4a — gitignored precious-local present (the clobber class). KEEP.
|
|
225
|
+
const precious = clobberClassIgnored(runSync, worktreePath);
|
|
226
|
+
if (precious.length > 0) {
|
|
227
|
+
return {
|
|
228
|
+
reason: 'SURVIVES-clobber',
|
|
229
|
+
detail: `gitignored local state: ${precious.slice(0, 3).join(', ')}${precious.length > 3 ? ` (+${precious.length - 3})` : ''}`,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
// (3) detached HEAD — no branch to verify merged-state against. Cannot
|
|
233
|
+
// prove the work is safely on origin/main → KEEP (gh#882 CR blocker).
|
|
234
|
+
if (actualBranch === null) {
|
|
235
|
+
return { reason: 'SURVIVES-detached', detail: 'detached HEAD — cannot verify merged' };
|
|
236
|
+
}
|
|
237
|
+
// (4) unmerged — the worktree's ACTUAL checked-out branch has commits not on
|
|
238
|
+
// origin/main (fetch already ran ONCE globally — S4b). This MUST key on the
|
|
239
|
+
// real HEAD branch, not the derived `wt-<suffix>`: a drone cuts feature
|
|
240
|
+
// branches off wt-<suffix> inside the worktree, so checking wt-<suffix>
|
|
241
|
+
// (which stays at the merged base) would miss unpushed feature work and
|
|
242
|
+
// misclassify it PRUNABLE (gh#882 CR blocker dcdd7fca). KEEP.
|
|
243
|
+
if (!isMerged(runSync, worktreePath, actualBranch, DEFAULT_REF)) {
|
|
244
|
+
return { reason: 'SURVIVES-unmerged', detail: `${actualBranch} not merged into ${DEFAULT_REF}` };
|
|
245
|
+
}
|
|
246
|
+
// (5) ONLY now probe eviction with the worktree's OWN seat token (S1).
|
|
247
|
+
const status = await deps.probeSeat(seat.sessionToken, seat.apiUrl, seat.serverTrustIdentity);
|
|
248
|
+
switch (status) {
|
|
249
|
+
case 'evicted':
|
|
250
|
+
return { reason: 'PRUNABLE', detail: '410 DRONE_EVICTED (clean + merged)' };
|
|
251
|
+
case 'rejected':
|
|
252
|
+
return { reason: 'SURVIVES-rejected', detail: 'pin-matched 401 (revoked/taken over) — recoverable via re-enroll, never delete' };
|
|
253
|
+
case 'live':
|
|
254
|
+
return { reason: 'SURVIVES-live', detail: 'seat resolves (drone alive)' };
|
|
255
|
+
case 'indeterminate':
|
|
256
|
+
default:
|
|
257
|
+
return {
|
|
258
|
+
reason: 'UNKNOWN-indeterminate',
|
|
259
|
+
detail: 'probe returned network/transient/404/trust-mismatch (or gh#877 not yet deployed) — not deleting',
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// ------------------------------------------------------------------
|
|
264
|
+
// Orchestrator
|
|
265
|
+
// ------------------------------------------------------------------
|
|
266
|
+
/**
|
|
267
|
+
* Build the cleanup report (read-only except the single up-front
|
|
268
|
+
* `git fetch origin`). Exported separately from the prune action so tests +
|
|
269
|
+
* the dry-run path share it.
|
|
270
|
+
*/
|
|
271
|
+
export async function buildCleanupReport(deps) {
|
|
272
|
+
const { runSync, realpath } = deps;
|
|
273
|
+
const cwd = deps.cwd();
|
|
274
|
+
if (runSync('git', ['rev-parse', '--show-toplevel'], cwd).status !== 0) {
|
|
275
|
+
return { rows: [], error: `not in a git repository (cwd: ${cwd})` };
|
|
276
|
+
}
|
|
277
|
+
// S4b — fetch origin ONCE up front so every per-worktree isMerged gate runs
|
|
278
|
+
// against a fresh origin/main (the ref is shared across linked worktrees).
|
|
279
|
+
// Fatal: a stale origin/main makes an unpushed wt-branch look merged.
|
|
280
|
+
const fetch = runSync('git', ['fetch', 'origin', '--prune'], cwd);
|
|
281
|
+
if (fetch.status !== 0) {
|
|
282
|
+
return { rows: [], error: `git fetch origin failed: ${fetch.stderr.trim()}` };
|
|
283
|
+
}
|
|
284
|
+
const wtList = runSync('git', ['worktree', 'list', '--porcelain'], cwd);
|
|
285
|
+
if (wtList.status !== 0) {
|
|
286
|
+
return { rows: [], error: `git worktree list failed: ${wtList.stderr.trim()}` };
|
|
287
|
+
}
|
|
288
|
+
const wtEntries = parseWorktreeEntries(wtList.stdout);
|
|
289
|
+
const branchByPath = new Map(wtEntries.map((e) => [e.path, e.branch]));
|
|
290
|
+
const allWorktrees = wtEntries.map((e) => e.path);
|
|
291
|
+
const mainDir = allWorktrees[0]; // porcelain lists the primary worktree first
|
|
292
|
+
const home = deps.homeDir();
|
|
293
|
+
const wtHome = worktreesHome(home);
|
|
294
|
+
// Self + primary are never orphan candidates.
|
|
295
|
+
const selfReal = safeRealpath(realpath, cwd);
|
|
296
|
+
const mainReal = mainDir ? safeRealpath(realpath, mainDir) : null;
|
|
297
|
+
// Seat lookup keyed by realpath(projectPath) so symlinked/relative entries
|
|
298
|
+
// still match the enumerated worktree path.
|
|
299
|
+
const seats = await deps.listSeats();
|
|
300
|
+
const seatByReal = new Map();
|
|
301
|
+
for (const { projectPath, cube } of seats) {
|
|
302
|
+
const real = safeRealpath(realpath, projectPath);
|
|
303
|
+
if (real)
|
|
304
|
+
seatByReal.set(real, cube);
|
|
305
|
+
}
|
|
306
|
+
const rows = [];
|
|
307
|
+
for (const wt of allWorktrees) {
|
|
308
|
+
const real = safeRealpath(realpath, wt);
|
|
309
|
+
if (!real)
|
|
310
|
+
continue; // gone from disk — git will report it as prunable itself
|
|
311
|
+
if (mainReal && real === mainReal)
|
|
312
|
+
continue; // primary worktree — never a candidate
|
|
313
|
+
const seat = seatByReal.get(real);
|
|
314
|
+
const under = isStrictlyUnder(realpath, wtHome, wt);
|
|
315
|
+
// Self (the running worktree): surface but never prune (can't remove the
|
|
316
|
+
// current worktree; the seat probe would also report it live).
|
|
317
|
+
if (real === selfReal) {
|
|
318
|
+
rows.push({ worktreePath: wt, wtBranch: null, reason: 'SURVIVES-self', detail: 'current worktree' });
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (!under) {
|
|
322
|
+
// Outside worktreesHome. A seat'd worktree here is a legacy pre-gh#556
|
|
323
|
+
// sibling → REPORT for manual review, never auto-prune (S5). No seat →
|
|
324
|
+
// an arbitrary user worktree we never touch or list.
|
|
325
|
+
if (seat) {
|
|
326
|
+
rows.push({ worktreePath: wt, wtBranch: null, reason: 'LEGACY-manual-review', detail: 'borg seat outside worktreesHome (pre-gh#556 sibling)' });
|
|
327
|
+
}
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
// Under worktreesHome but no saved seat → not eviction-orphaned
|
|
331
|
+
// (pre-assimilate or hand-made). Report, never auto-prune.
|
|
332
|
+
if (!seat) {
|
|
333
|
+
rows.push({ worktreePath: wt, wtBranch: null, reason: 'UNKNOWN-no-seat', detail: 'no saved seat — manual review' });
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
// Use the worktree's ACTUAL checked-out HEAD branch (from porcelain) for
|
|
337
|
+
// BOTH the merged-gate and the eventual `git branch -d` — NOT the derived
|
|
338
|
+
// `wt-<suffix>` (gh#882 CR blocker dcdd7fca). null = detached HEAD → KEEP.
|
|
339
|
+
const actualBranch = branchByPath.get(wt) ?? null;
|
|
340
|
+
const { reason, detail } = await classifyWorktree(deps, wt, actualBranch, seat);
|
|
341
|
+
rows.push({ worktreePath: wt, wtBranch: actualBranch, reason, detail });
|
|
342
|
+
}
|
|
343
|
+
return { rows };
|
|
344
|
+
}
|
|
345
|
+
function safeRealpath(realpath, p) {
|
|
346
|
+
try {
|
|
347
|
+
return realpath(p);
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* `borg cleanup [--prune]` entry point. Returns the process exit code.
|
|
355
|
+
* Dry-run (default): print the report, delete nothing. `--prune`: additionally
|
|
356
|
+
* remove PRUNABLE worktrees via `git worktree remove` (NO --force) +
|
|
357
|
+
* `git branch -d` (NO -D) — git's own refusals are the final backstop.
|
|
358
|
+
*/
|
|
359
|
+
export async function runCleanup(deps = {}, opts = { prune: false }) {
|
|
360
|
+
const merged = { ...defaultDeps, ...deps };
|
|
361
|
+
const { stdout, stderr, runSync } = merged;
|
|
362
|
+
const { rows, error } = await buildCleanupReport(merged);
|
|
363
|
+
if (error) {
|
|
364
|
+
stderr(chalk.red(`◼ borg cleanup: ${error}\n`));
|
|
365
|
+
return 1;
|
|
366
|
+
}
|
|
367
|
+
const prunable = rows.filter((r) => r.reason === 'PRUNABLE');
|
|
368
|
+
const survivors = rows.filter((r) => r.reason !== 'PRUNABLE');
|
|
369
|
+
// --- Report (always) ---
|
|
370
|
+
if (rows.length === 0) {
|
|
371
|
+
stdout(chalk.blue('◼ borg cleanup: no borg-managed worktrees found.\n'));
|
|
372
|
+
return 0;
|
|
373
|
+
}
|
|
374
|
+
stdout(chalk.bold('◼ borg cleanup report:\n'));
|
|
375
|
+
for (const r of rows) {
|
|
376
|
+
const tag = r.reason === 'PRUNABLE' ? chalk.yellow(r.reason) : chalk.gray(r.reason);
|
|
377
|
+
stdout(` ${tag} ${r.worktreePath}${r.detail ? chalk.gray(` — ${r.detail}`) : ''}\n`);
|
|
378
|
+
}
|
|
379
|
+
stdout(chalk.gray(`◼ ${prunable.length} prunable, ${survivors.length} kept.\n`));
|
|
380
|
+
if (!opts.prune) {
|
|
381
|
+
if (prunable.length > 0) {
|
|
382
|
+
stdout(chalk.gray('◼ Dry-run — nothing deleted. Re-run with `--prune` to remove the PRUNABLE worktree(s).\n'));
|
|
383
|
+
}
|
|
384
|
+
return 0;
|
|
385
|
+
}
|
|
386
|
+
// --- Prune (PRUNABLE only) ---
|
|
387
|
+
if (prunable.length === 0) {
|
|
388
|
+
stdout(chalk.blue('◼ Nothing to prune.\n'));
|
|
389
|
+
return 0;
|
|
390
|
+
}
|
|
391
|
+
let removed = 0;
|
|
392
|
+
let failed = 0;
|
|
393
|
+
for (const r of prunable) {
|
|
394
|
+
// git worktree remove WITHOUT --force (refuses a dirty/locked worktree —
|
|
395
|
+
// backstop even past our gates).
|
|
396
|
+
const rm = runSync('git', ['worktree', 'remove', r.worktreePath], merged.cwd());
|
|
397
|
+
if (rm.status !== 0) {
|
|
398
|
+
r.prune = 'remove-failed';
|
|
399
|
+
failed++;
|
|
400
|
+
stderr(chalk.red(` ✗ worktree remove ${r.worktreePath}: ${rm.stderr.trim()}\n`));
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
// git branch -d (NOT -D) — refuses an unmerged branch (backstop).
|
|
404
|
+
if (r.wtBranch) {
|
|
405
|
+
const bd = runSync('git', ['branch', '-d', r.wtBranch], merged.cwd());
|
|
406
|
+
if (bd.status !== 0) {
|
|
407
|
+
r.prune = 'branch-delete-failed';
|
|
408
|
+
stderr(chalk.yellow(` ⚠ removed worktree but \`git branch -d ${r.wtBranch}\` refused: ${bd.stderr.trim()}\n`));
|
|
409
|
+
removed++;
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// gh#884: r.wtBranch is the worktree's ACTUAL checked-out HEAD (often a
|
|
414
|
+
// feature branch the drone cut). The DERIVED per-worktree base branch
|
|
415
|
+
// `wt-<suffix>` — created by `borg assimilate`, the base feature branches
|
|
416
|
+
// were cut from — is a SEPARATE ref left dangling once the worktree is
|
|
417
|
+
// gone. Prune it too when it still exists and is merged into origin/main
|
|
418
|
+
// (skip when it IS r.wtBranch, already deleted above). `git branch -d`
|
|
419
|
+
// (NOT -D) backstops the merged + not-checked-out guards.
|
|
420
|
+
let baseNote = '';
|
|
421
|
+
const derivedWtBranch = perWorktreeBranchName(basename(r.worktreePath), basename(dirname(r.worktreePath)));
|
|
422
|
+
if (derivedWtBranch !== r.wtBranch &&
|
|
423
|
+
localBranchExists(runSync, merged.cwd(), derivedWtBranch) &&
|
|
424
|
+
isMerged(runSync, merged.cwd(), derivedWtBranch, DEFAULT_REF)) {
|
|
425
|
+
const bdBase = runSync('git', ['branch', '-d', derivedWtBranch], merged.cwd());
|
|
426
|
+
if (bdBase.status === 0) {
|
|
427
|
+
baseNote = ` + base ${derivedWtBranch}`;
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
stderr(chalk.yellow(` ⚠ left dangling base branch ${derivedWtBranch}: \`git branch -d\` refused: ${bdBase.stderr.trim()}\n`));
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
r.prune = 'removed';
|
|
434
|
+
removed++;
|
|
435
|
+
stdout(chalk.blue(` ✓ pruned ${r.worktreePath}${r.wtBranch ? ` + branch ${r.wtBranch}` : ''}${baseNote}\n`));
|
|
436
|
+
}
|
|
437
|
+
stdout(chalk.gray(`◼ Pruned ${removed} worktree(s)${failed > 0 ? `, ${failed} failed` : ''}.\n`));
|
|
438
|
+
return failed > 0 ? 1 : 0;
|
|
439
|
+
}
|
|
440
|
+
/** Parse args after `borg cleanup`. Supports `--prune`; rejects anything else. */
|
|
441
|
+
export function parseCleanupArgs(rawArgs) {
|
|
442
|
+
let prune = false;
|
|
443
|
+
for (const arg of rawArgs) {
|
|
444
|
+
if (arg === '--prune') {
|
|
445
|
+
prune = true;
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
return { ok: false, error: `unexpected argument: ${arg}. Usage: borg cleanup [--prune]` };
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return { ok: true, options: { prune } };
|
|
452
|
+
}
|
|
453
|
+
//# sourceMappingURL=cleanup-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-cmd.js","sourceRoot":"","sources":["../src/cleanup-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear-rewake-core.d.ts","sourceRoot":"","sources":["../src/clear-rewake-core.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB,6IAC0G,CAAC;AAE7I,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,iBAAiB,CAenB"}
|
|
@@ -1,2 +1,23 @@
|
|
|
1
|
-
import{isBorgSession
|
|
2
|
-
|
|
1
|
+
import { isBorgSession } from './launch-gate.js';
|
|
2
|
+
export const CLEAR_REWAKE_REMINDER = 'Post-/clear recovery: full regen, drain the unread log; handle actionable cube entries, otherwise resume the work from before this wake.';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the Claude `/clear` async-rewake response without consulting cube
|
|
5
|
+
* state. The reminder is deliberately static: hook input can contain local
|
|
6
|
+
* paths and session metadata, none of which may cross into stderr.
|
|
7
|
+
*/
|
|
8
|
+
export function evaluateClearRewake(raw, env = process.env) {
|
|
9
|
+
if (!isBorgSession(env))
|
|
10
|
+
return { exitCode: 0, stderr: '' };
|
|
11
|
+
let input;
|
|
12
|
+
try {
|
|
13
|
+
input = raw.trim() ? JSON.parse(raw) : null;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return { exitCode: 0, stderr: '' };
|
|
17
|
+
}
|
|
18
|
+
if (input?.hook_event_name !== 'SessionStart' || input?.source !== 'clear') {
|
|
19
|
+
return { exitCode: 0, stderr: '' };
|
|
20
|
+
}
|
|
21
|
+
return { exitCode: 2, stderr: `${CLEAR_REWAKE_REMINDER}\n` };
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=clear-rewake-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear-rewake-core.js","sourceRoot":"","sources":["../src/clear-rewake-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,CAAC,MAAM,qBAAqB,GAChC,0IAA0I,CAAC;AAO7I;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAW,EACX,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAE5D,IAAI,KAAU,CAAC;IACf,IAAI,CAAC;QACH,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,KAAK,EAAE,eAAe,KAAK,cAAc,IAAI,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;QAC3E,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,qBAAqB,IAAI,EAAE,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear-rewake.d.ts","sourceRoot":"","sources":["../src/clear-rewake.ts"],"names":[],"mappings":""}
|
package/dist/clear-rewake.js
CHANGED
|
@@ -1,2 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{evaluateClearRewake
|
|
2
|
+
import { evaluateClearRewake } from './clear-rewake-core.js';
|
|
3
|
+
async function readStdin() {
|
|
4
|
+
if (process.stdin.isTTY)
|
|
5
|
+
return '';
|
|
6
|
+
try {
|
|
7
|
+
const chunks = [];
|
|
8
|
+
for await (const chunk of process.stdin)
|
|
9
|
+
chunks.push(chunk);
|
|
10
|
+
return Buffer.concat(chunks).toString('utf-8');
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const result = evaluateClearRewake(await readStdin());
|
|
17
|
+
if (result.stderr)
|
|
18
|
+
process.stderr.write(result.stderr);
|
|
19
|
+
process.exitCode = result.exitCode;
|
|
20
|
+
//# sourceMappingURL=clear-rewake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear-rewake.js","sourceRoot":"","sources":["../src/clear-rewake.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,KAAK,UAAU,SAAS;IACtB,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;QACtE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC;AACtD,IAAI,MAAM,CAAC,MAAM;IAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACvD,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC"}
|
package/dist/cli-help.d.ts
CHANGED
|
@@ -19,6 +19,11 @@ export declare function topLevelHelpText(version: string): string;
|
|
|
19
19
|
* set. Model/provider configuration belongs to the selected agent CLI.
|
|
20
20
|
*/
|
|
21
21
|
export declare function assimilateHelpText(version: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Help text for `borg reset-local-seat --help`. The offline, network-free seat
|
|
24
|
+
* reset recommended by the pin-matched SESSION_REJECTED diagnostic (#1082).
|
|
25
|
+
*/
|
|
26
|
+
export declare function resetLocalSeatHelpText(version: string): string;
|
|
22
27
|
/**
|
|
23
28
|
* Help text for `borg setup --help` (gh#520 — previously this ran the setup
|
|
24
29
|
* wizard instead of showing help). Mirrors the `borg setup` description in the
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-help.d.ts","sourceRoot":"","sources":["../src/cli-help.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAuBxD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA4B1D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkB9D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQrD"}
|