oh-my-copilot 5.5.0 → 5.6.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +1 -0
- package/bridge/__pycache__/gyoshu_bridge.cpython-312.pyc +0 -0
- package/bridge/claude-md-coordinator.cjs +2 -2
- package/bridge/cli.cjs +6290 -3436
- package/bridge/mcp-server.cjs +637 -503
- package/bridge/runtime-cli.cjs +516 -213
- package/bridge/team-bridge.cjs +141 -135
- package/bridge/team-mcp.cjs +201 -129
- package/bridge/team.js +473 -237
- package/copilot/hooks.json +43 -0
- package/dist/__tests__/chain-enqueuer-registration.test.d.ts +11 -0
- package/dist/__tests__/chain-enqueuer-registration.test.d.ts.map +1 -0
- package/dist/__tests__/chain-enqueuer-registration.test.js +122 -0
- package/dist/__tests__/chain-enqueuer-registration.test.js.map +1 -0
- package/dist/__tests__/copilot-hooks-manifest.test.js +3 -1
- package/dist/__tests__/copilot-hooks-manifest.test.js.map +1 -1
- package/dist/__tests__/directory-context-injector.test.js +41 -1
- package/dist/__tests__/directory-context-injector.test.js.map +1 -1
- package/dist/__tests__/hook-bridge-main-module.test.d.ts +2 -0
- package/dist/__tests__/hook-bridge-main-module.test.d.ts.map +1 -0
- package/dist/__tests__/hook-bridge-main-module.test.js +48 -0
- package/dist/__tests__/hook-bridge-main-module.test.js.map +1 -0
- package/dist/__tests__/ralph-prd-stale.test.js +12 -1
- package/dist/__tests__/ralph-prd-stale.test.js.map +1 -1
- package/dist/__tests__/ralph-prd.test.js +56 -0
- package/dist/__tests__/ralph-prd.test.js.map +1 -1
- package/dist/__tests__/run-cjs-graceful-fallback.test.js +2 -0
- package/dist/__tests__/run-cjs-graceful-fallback.test.js.map +1 -1
- package/dist/__tests__/session-end-forwarder-fallback.test.d.ts +2 -0
- package/dist/__tests__/session-end-forwarder-fallback.test.d.ts.map +1 -0
- package/dist/__tests__/session-end-forwarder-fallback.test.js +138 -0
- package/dist/__tests__/session-end-forwarder-fallback.test.js.map +1 -0
- package/dist/cli/__tests__/autoresearch-setup-session.test.js +67 -3
- package/dist/cli/__tests__/autoresearch-setup-session.test.js.map +1 -1
- package/dist/cli/__tests__/launch.test.js +73 -11
- package/dist/cli/__tests__/launch.test.js.map +1 -1
- package/dist/cli/__tests__/plugin-dir-capture.test.js +45 -0
- package/dist/cli/__tests__/plugin-dir-capture.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-afk.test.d.ts +2 -0
- package/dist/cli/__tests__/ralph-afk.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralph-afk.test.js +312 -0
- package/dist/cli/__tests__/ralph-afk.test.js.map +1 -0
- package/dist/cli/__tests__/team.test.js +170 -0
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/tmux-utils.test.js +132 -16
- package/dist/cli/__tests__/tmux-utils.test.js.map +1 -1
- package/dist/cli/autoresearch-setup-session.d.ts.map +1 -1
- package/dist/cli/autoresearch-setup-session.js +29 -9
- package/dist/cli/autoresearch-setup-session.js.map +1 -1
- package/dist/cli/commands/__tests__/factory-init.test.d.ts +2 -0
- package/dist/cli/commands/__tests__/factory-init.test.d.ts.map +1 -0
- package/dist/cli/commands/__tests__/factory-init.test.js +90 -0
- package/dist/cli/commands/__tests__/factory-init.test.js.map +1 -0
- package/dist/cli/commands/__tests__/intake-headless-flag.test.d.ts +2 -0
- package/dist/cli/commands/__tests__/intake-headless-flag.test.d.ts.map +1 -0
- package/dist/cli/commands/__tests__/intake-headless-flag.test.js +30 -0
- package/dist/cli/commands/__tests__/intake-headless-flag.test.js.map +1 -0
- package/dist/cli/commands/__tests__/intake.test.d.ts +2 -0
- package/dist/cli/commands/__tests__/intake.test.d.ts.map +1 -0
- package/dist/cli/commands/__tests__/intake.test.js +257 -0
- package/dist/cli/commands/__tests__/intake.test.js.map +1 -0
- package/dist/cli/commands/factory.d.ts +61 -0
- package/dist/cli/commands/factory.d.ts.map +1 -0
- package/dist/cli/commands/factory.js +190 -0
- package/dist/cli/commands/factory.js.map +1 -0
- package/dist/cli/commands/intake.d.ts +94 -0
- package/dist/cli/commands/intake.d.ts.map +1 -0
- package/dist/cli/commands/intake.js +311 -0
- package/dist/cli/commands/intake.js.map +1 -0
- package/dist/cli/commands/ralph.d.ts +88 -0
- package/dist/cli/commands/ralph.d.ts.map +1 -0
- package/dist/cli/commands/ralph.js +456 -0
- package/dist/cli/commands/ralph.js.map +1 -0
- package/dist/cli/commands/team.d.ts.map +1 -1
- package/dist/cli/commands/team.js +25 -5
- package/dist/cli/commands/team.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/launch.d.ts.map +1 -1
- package/dist/cli/launch.js +32 -7
- package/dist/cli/launch.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +61 -7
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/tmux-utils.d.ts +26 -0
- package/dist/cli/tmux-utils.d.ts.map +1 -1
- package/dist/cli/tmux-utils.js +61 -9
- package/dist/cli/tmux-utils.js.map +1 -1
- package/dist/config/__tests__/loader.test.js +138 -0
- package/dist/config/__tests__/loader.test.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +17 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/factory/__tests__/check-run.test.d.ts +2 -0
- package/dist/factory/__tests__/check-run.test.d.ts.map +1 -0
- package/dist/factory/__tests__/check-run.test.js +213 -0
- package/dist/factory/__tests__/check-run.test.js.map +1 -0
- package/dist/factory/__tests__/listener.test.d.ts +2 -0
- package/dist/factory/__tests__/listener.test.d.ts.map +1 -0
- package/dist/factory/__tests__/listener.test.js +312 -0
- package/dist/factory/__tests__/listener.test.js.map +1 -0
- package/dist/factory/__tests__/map-frontier.test.d.ts +2 -0
- package/dist/factory/__tests__/map-frontier.test.d.ts.map +1 -0
- package/dist/factory/__tests__/map-frontier.test.js +128 -0
- package/dist/factory/__tests__/map-frontier.test.js.map +1 -0
- package/dist/factory/__tests__/map-ingest.test.d.ts +2 -0
- package/dist/factory/__tests__/map-ingest.test.d.ts.map +1 -0
- package/dist/factory/__tests__/map-ingest.test.js +166 -0
- package/dist/factory/__tests__/map-ingest.test.js.map +1 -0
- package/dist/factory/__tests__/map-run.test.d.ts +2 -0
- package/dist/factory/__tests__/map-run.test.d.ts.map +1 -0
- package/dist/factory/__tests__/map-run.test.js +148 -0
- package/dist/factory/__tests__/map-run.test.js.map +1 -0
- package/dist/factory/__tests__/status.test.d.ts +2 -0
- package/dist/factory/__tests__/status.test.d.ts.map +1 -0
- package/dist/factory/__tests__/status.test.js +77 -0
- package/dist/factory/__tests__/status.test.js.map +1 -0
- package/dist/factory/listener.d.ts +98 -0
- package/dist/factory/listener.d.ts.map +1 -0
- package/dist/factory/listener.js +315 -0
- package/dist/factory/listener.js.map +1 -0
- package/dist/factory/map-frontier.d.ts +73 -0
- package/dist/factory/map-frontier.d.ts.map +1 -0
- package/dist/factory/map-frontier.js +147 -0
- package/dist/factory/map-frontier.js.map +1 -0
- package/dist/factory/map-ingest.d.ts +79 -0
- package/dist/factory/map-ingest.d.ts.map +1 -0
- package/dist/factory/map-ingest.js +232 -0
- package/dist/factory/map-ingest.js.map +1 -0
- package/dist/factory/map-run.d.ts +74 -0
- package/dist/factory/map-run.d.ts.map +1 -0
- package/dist/factory/map-run.js +229 -0
- package/dist/factory/map-run.js.map +1 -0
- package/dist/factory/status.d.ts +33 -0
- package/dist/factory/status.d.ts.map +1 -0
- package/dist/factory/status.js +93 -0
- package/dist/factory/status.js.map +1 -0
- package/dist/factory/watchdog.d.ts +46 -0
- package/dist/factory/watchdog.d.ts.map +1 -0
- package/dist/factory/watchdog.js +130 -0
- package/dist/factory/watchdog.js.map +1 -0
- package/dist/factory/watchdog.test.d.ts +2 -0
- package/dist/factory/watchdog.test.d.ts.map +1 -0
- package/dist/factory/watchdog.test.js +111 -0
- package/dist/factory/watchdog.test.js.map +1 -0
- package/dist/graph/runtime/native-contained-fs.js +1 -1
- package/dist/graph/runtime/native-contained-fs.js.map +1 -1
- package/dist/hooks/__tests__/compaction-concurrency.test.js +20 -20
- package/dist/hooks/__tests__/compaction-concurrency.test.js.map +1 -1
- package/dist/hooks/__tests__/workflow-drift-guard-script.test.js +27 -0
- package/dist/hooks/__tests__/workflow-drift-guard-script.test.js.map +1 -1
- package/dist/hooks/bridge.d.ts +8 -0
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +38 -9
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/code-simplifier/__tests__/global-config-path.test.d.ts +2 -0
- package/dist/hooks/code-simplifier/__tests__/global-config-path.test.d.ts.map +1 -0
- package/dist/hooks/code-simplifier/__tests__/global-config-path.test.js +89 -0
- package/dist/hooks/code-simplifier/__tests__/global-config-path.test.js.map +1 -0
- package/dist/hooks/code-simplifier/index.d.ts +1 -1
- package/dist/hooks/code-simplifier/index.js +1 -1
- package/dist/hooks/code-simplifier/jev-shadow.d.ts +5 -4
- package/dist/hooks/code-simplifier/jev-shadow.d.ts.map +1 -1
- package/dist/hooks/code-simplifier/jev-shadow.js +9 -4
- package/dist/hooks/code-simplifier/jev-shadow.js.map +1 -1
- package/dist/hooks/directory-readme-injector/index.d.ts.map +1 -1
- package/dist/hooks/directory-readme-injector/index.js +11 -2
- package/dist/hooks/directory-readme-injector/index.js.map +1 -1
- package/dist/hooks/jev/__tests__/active-mode.test.d.ts +9 -0
- package/dist/hooks/jev/__tests__/active-mode.test.d.ts.map +1 -0
- package/dist/hooks/jev/__tests__/active-mode.test.js +252 -0
- package/dist/hooks/jev/__tests__/active-mode.test.js.map +1 -0
- package/dist/hooks/jev/points.d.ts +3 -1
- package/dist/hooks/jev/points.d.ts.map +1 -1
- package/dist/hooks/jev/points.js +1 -0
- package/dist/hooks/jev/points.js.map +1 -1
- package/dist/hooks/jev/resolver.d.ts.map +1 -1
- package/dist/hooks/jev/resolver.js +17 -1
- package/dist/hooks/jev/resolver.js.map +1 -1
- package/dist/hooks/keyword-detector/index.d.ts +2 -0
- package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
- package/dist/hooks/keyword-detector/index.js +3 -3
- package/dist/hooks/keyword-detector/index.js.map +1 -1
- package/dist/hooks/keyword-detector/jev-shadow.d.ts +6 -4
- package/dist/hooks/keyword-detector/jev-shadow.d.ts.map +1 -1
- package/dist/hooks/keyword-detector/jev-shadow.js +18 -4
- package/dist/hooks/keyword-detector/jev-shadow.js.map +1 -1
- package/dist/hooks/learner/jev-shadow.d.ts +4 -3
- package/dist/hooks/learner/jev-shadow.d.ts.map +1 -1
- package/dist/hooks/learner/jev-shadow.js +14 -3
- package/dist/hooks/learner/jev-shadow.js.map +1 -1
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +22 -6
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/persistent-mode/jev-shadow.d.ts +7 -5
- package/dist/hooks/persistent-mode/jev-shadow.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/jev-shadow.js +28 -6
- package/dist/hooks/persistent-mode/jev-shadow.js.map +1 -1
- package/dist/hooks/preemptive-compaction/__tests__/jev-shadow.test.js +3 -3
- package/dist/hooks/preemptive-compaction/__tests__/jev-shadow.test.js.map +1 -1
- package/dist/hooks/preemptive-compaction/index.d.ts +5 -1
- package/dist/hooks/preemptive-compaction/index.d.ts.map +1 -1
- package/dist/hooks/preemptive-compaction/index.js +13 -8
- package/dist/hooks/preemptive-compaction/index.js.map +1 -1
- package/dist/hooks/preemptive-compaction/jev-shadow.d.ts +6 -5
- package/dist/hooks/preemptive-compaction/jev-shadow.d.ts.map +1 -1
- package/dist/hooks/preemptive-compaction/jev-shadow.js +18 -5
- package/dist/hooks/preemptive-compaction/jev-shadow.js.map +1 -1
- package/dist/hooks/ralph/__tests__/feedback-baseline.test.d.ts +2 -0
- package/dist/hooks/ralph/__tests__/feedback-baseline.test.d.ts.map +1 -0
- package/dist/hooks/ralph/__tests__/feedback-baseline.test.js +250 -0
- package/dist/hooks/ralph/__tests__/feedback-baseline.test.js.map +1 -0
- package/dist/hooks/ralph/feedback-baseline.d.ts +58 -0
- package/dist/hooks/ralph/feedback-baseline.d.ts.map +1 -0
- package/dist/hooks/ralph/feedback-baseline.js +141 -0
- package/dist/hooks/ralph/feedback-baseline.js.map +1 -0
- package/dist/hooks/ralph/index.d.ts +1 -1
- package/dist/hooks/ralph/index.d.ts.map +1 -1
- package/dist/hooks/ralph/index.js +1 -1
- package/dist/hooks/ralph/index.js.map +1 -1
- package/dist/hooks/ralph/jev-shadow.d.ts +4 -3
- package/dist/hooks/ralph/jev-shadow.d.ts.map +1 -1
- package/dist/hooks/ralph/jev-shadow.js +14 -4
- package/dist/hooks/ralph/jev-shadow.js.map +1 -1
- package/dist/hooks/ralph/loop.d.ts +7 -0
- package/dist/hooks/ralph/loop.d.ts.map +1 -1
- package/dist/hooks/ralph/loop.js +21 -0
- package/dist/hooks/ralph/loop.js.map +1 -1
- package/dist/hooks/ralph/prd.d.ts +17 -0
- package/dist/hooks/ralph/prd.d.ts.map +1 -1
- package/dist/hooks/ralph/prd.js +26 -1
- package/dist/hooks/ralph/prd.js.map +1 -1
- package/dist/hooks/registry/__tests__/registry.test.js +12 -4
- package/dist/hooks/registry/__tests__/registry.test.js.map +1 -1
- package/dist/hooks/rules-injector/matcher.d.ts.map +1 -1
- package/dist/hooks/rules-injector/matcher.js +35 -7
- package/dist/hooks/rules-injector/matcher.js.map +1 -1
- package/dist/hooks/rules-injector/matcher.test.d.ts +2 -0
- package/dist/hooks/rules-injector/matcher.test.d.ts.map +1 -0
- package/dist/hooks/rules-injector/matcher.test.js +58 -0
- package/dist/hooks/rules-injector/matcher.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/action-runner.test.js +51 -0
- package/dist/hooks/session-end/__tests__/action-runner.test.js.map +1 -1
- package/dist/hooks/session-end/__tests__/chain-enqueuer.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/chain-enqueuer.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/chain-enqueuer.test.js +274 -0
- package/dist/hooks/session-end/__tests__/chain-enqueuer.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/check-evidence.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/check-evidence.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/check-evidence.test.js +171 -0
- package/dist/hooks/session-end/__tests__/check-evidence.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/cleanup-manifest.test.js +21 -0
- package/dist/hooks/session-end/__tests__/cleanup-manifest.test.js.map +1 -1
- package/dist/hooks/session-end/__tests__/foreground-bootstrap.test.d.ts +10 -0
- package/dist/hooks/session-end/__tests__/foreground-bootstrap.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/foreground-bootstrap.test.js +123 -0
- package/dist/hooks/session-end/__tests__/foreground-bootstrap.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/guardrails.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/guardrails.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/guardrails.test.js +184 -0
- package/dist/hooks/session-end/__tests__/guardrails.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/process-session-end-worker-spawn.test.d.ts +9 -0
- package/dist/hooks/session-end/__tests__/process-session-end-worker-spawn.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/process-session-end-worker-spawn.test.js +96 -0
- package/dist/hooks/session-end/__tests__/process-session-end-worker-spawn.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/routing.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/routing.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/routing.test.js +135 -0
- package/dist/hooks/session-end/__tests__/routing.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/spawn-next.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/spawn-next.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/spawn-next.test.js +501 -0
- package/dist/hooks/session-end/__tests__/spawn-next.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/worker.test.js +102 -0
- package/dist/hooks/session-end/__tests__/worker.test.js.map +1 -1
- package/dist/hooks/session-end/action-runner.d.ts.map +1 -1
- package/dist/hooks/session-end/action-runner.js +24 -2
- package/dist/hooks/session-end/action-runner.js.map +1 -1
- package/dist/hooks/session-end/chain-enqueuer.d.ts +45 -0
- package/dist/hooks/session-end/chain-enqueuer.d.ts.map +1 -0
- package/dist/hooks/session-end/chain-enqueuer.js +191 -0
- package/dist/hooks/session-end/chain-enqueuer.js.map +1 -0
- package/dist/hooks/session-end/check-evidence.d.ts +29 -0
- package/dist/hooks/session-end/check-evidence.d.ts.map +1 -0
- package/dist/hooks/session-end/check-evidence.js +52 -0
- package/dist/hooks/session-end/check-evidence.js.map +1 -0
- package/dist/hooks/session-end/cleanup-manifest.d.ts +1 -1
- package/dist/hooks/session-end/cleanup-manifest.d.ts.map +1 -1
- package/dist/hooks/session-end/cleanup-manifest.js +22 -2
- package/dist/hooks/session-end/cleanup-manifest.js.map +1 -1
- package/dist/hooks/session-end/foreground-bootstrap.d.ts.map +1 -1
- package/dist/hooks/session-end/foreground-bootstrap.js +30 -4
- package/dist/hooks/session-end/foreground-bootstrap.js.map +1 -1
- package/dist/hooks/session-end/guardrails.d.ts +67 -0
- package/dist/hooks/session-end/guardrails.d.ts.map +1 -0
- package/dist/hooks/session-end/guardrails.js +149 -0
- package/dist/hooks/session-end/guardrails.js.map +1 -0
- package/dist/hooks/session-end/index.d.ts.map +1 -1
- package/dist/hooks/session-end/index.js +14 -6
- package/dist/hooks/session-end/index.js.map +1 -1
- package/dist/hooks/session-end/routing.d.ts +53 -0
- package/dist/hooks/session-end/routing.d.ts.map +1 -0
- package/dist/hooks/session-end/routing.js +75 -0
- package/dist/hooks/session-end/routing.js.map +1 -0
- package/dist/hooks/session-end/spawn-next.d.ts +117 -0
- package/dist/hooks/session-end/spawn-next.d.ts.map +1 -0
- package/dist/hooks/session-end/spawn-next.js +292 -0
- package/dist/hooks/session-end/spawn-next.js.map +1 -0
- package/dist/hooks/session-end/worker.d.ts.map +1 -1
- package/dist/hooks/session-end/worker.js +45 -5
- package/dist/hooks/session-end/worker.js.map +1 -1
- package/dist/hooks/task-size-detector/jev-shadow.d.ts +2 -1
- package/dist/hooks/task-size-detector/jev-shadow.d.ts.map +1 -1
- package/dist/hooks/task-size-detector/jev-shadow.js +19 -1
- package/dist/hooks/task-size-detector/jev-shadow.js.map +1 -1
- package/dist/installer/__tests__/hook-command-portability.test.js +57 -1
- package/dist/installer/__tests__/hook-command-portability.test.js.map +1 -1
- package/dist/installer/__tests__/mcp-registry.test.js +98 -0
- package/dist/installer/__tests__/mcp-registry.test.js.map +1 -1
- package/dist/installer/hooks.d.ts +7 -0
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +15 -0
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +12 -0
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +3 -1
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/mcp-registry.d.ts.map +1 -1
- package/dist/installer/mcp-registry.js +56 -6
- package/dist/installer/mcp-registry.js.map +1 -1
- package/dist/lib/__tests__/host-load-gate.test.d.ts +2 -0
- package/dist/lib/__tests__/host-load-gate.test.d.ts.map +1 -0
- package/dist/lib/__tests__/host-load-gate.test.js +377 -0
- package/dist/lib/__tests__/host-load-gate.test.js.map +1 -0
- package/dist/lib/__tests__/runs-ledger.test.d.ts +2 -0
- package/dist/lib/__tests__/runs-ledger.test.d.ts.map +1 -0
- package/dist/lib/__tests__/runs-ledger.test.js +99 -0
- package/dist/lib/__tests__/runs-ledger.test.js.map +1 -0
- package/dist/lib/atomic-write.d.ts +16 -0
- package/dist/lib/atomic-write.d.ts.map +1 -1
- package/dist/lib/atomic-write.js +27 -4
- package/dist/lib/atomic-write.js.map +1 -1
- package/dist/lib/host-load-gate.d.ts +110 -0
- package/dist/lib/host-load-gate.d.ts.map +1 -0
- package/dist/lib/host-load-gate.js +228 -0
- package/dist/lib/host-load-gate.js.map +1 -0
- package/dist/lib/mode-state-io.d.ts.map +1 -1
- package/dist/lib/mode-state-io.js +55 -18
- package/dist/lib/mode-state-io.js.map +1 -1
- package/dist/lib/runs-ledger.d.ts +45 -0
- package/dist/lib/runs-ledger.d.ts.map +1 -0
- package/dist/lib/runs-ledger.js +141 -0
- package/dist/lib/runs-ledger.js.map +1 -0
- package/dist/platform/executable-resolution.d.ts +13 -0
- package/dist/platform/executable-resolution.d.ts.map +1 -1
- package/dist/platform/executable-resolution.js +16 -0
- package/dist/platform/executable-resolution.js.map +1 -1
- package/dist/shared/types.d.ts +3 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/team/__tests__/model-contract.test.js +63 -1
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/stage-router.test.js +22 -0
- package/dist/team/__tests__/stage-router.test.js.map +1 -1
- package/dist/team/__tests__/team-owner-epoch.test.js +33 -0
- package/dist/team/__tests__/team-owner-epoch.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.create-team.test.js +60 -2
- package/dist/team/__tests__/tmux-session.create-team.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.psmux.test.js +12 -0
- package/dist/team/__tests__/tmux-session.psmux.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +230 -7
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-launch-ack.test.js +62 -0
- package/dist/team/__tests__/worker-launch-ack.test.js.map +1 -1
- package/dist/team/model-contract.d.ts +3 -2
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +35 -10
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/runtime-v2.d.ts +13 -0
- package/dist/team/runtime-v2.d.ts.map +1 -1
- package/dist/team/runtime-v2.js +112 -7
- package/dist/team/runtime-v2.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +4 -1
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/stage-router.d.ts.map +1 -1
- package/dist/team/stage-router.js +3 -1
- package/dist/team/stage-router.js.map +1 -1
- package/dist/team/team-owner-epoch.d.ts.map +1 -1
- package/dist/team/team-owner-epoch.js +4 -7
- package/dist/team/team-owner-epoch.js.map +1 -1
- package/dist/team/tmux-session.d.ts +8 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +71 -19
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-launch-ack.d.ts +1 -1
- package/dist/team/worker-launch-ack.d.ts.map +1 -1
- package/dist/team/worker-launch-ack.js +28 -1
- package/dist/team/worker-launch-ack.js.map +1 -1
- package/dist/tools/lsp/__tests__/client-handle-data.test.js +83 -0
- package/dist/tools/lsp/__tests__/client-handle-data.test.js.map +1 -1
- package/dist/tools/lsp/client.d.ts.map +1 -1
- package/dist/tools/lsp/client.js +41 -11
- package/dist/tools/lsp/client.js.map +1 -1
- package/docs/CLAUDE.md +1 -1
- package/docs/HOOKS.md +235 -0
- package/docs/MIGRATION.md +132 -0
- package/docs/REFERENCE.md +26 -1
- package/docs/adr/03672-env-activated-active-mode.md +18 -1
- package/docs/design/FACTORY-FINAL-DESIGN.md +114 -0
- package/docs/design/P2-RUN-LEDGER-AND-INTAKE-PLAN.md +83 -0
- package/docs/factory/t6-acceptance/acceptance-comment.md +36 -0
- package/hooks/hooks.json +22 -1
- package/package.json +6 -2
- package/plugin.json +1 -1
- package/scripts/build-contained-fs.mjs +24 -2
- package/scripts/ci/check-multirepo-paths.mjs +3 -0
- package/scripts/code-simplifier.mjs +24 -2
- package/scripts/dev/repro-state-lock.mjs +67 -0
- package/scripts/git-guardrails.mjs +581 -0
- package/scripts/keyword-detector.mjs +21 -4
- package/scripts/lib/atomic-write.mjs +31 -8
- package/scripts/lib/jev-shadow.mjs +68 -29
- package/scripts/lib/run-reaper.mjs +114 -0
- package/scripts/lib/state-lock.mjs +22 -13
- package/scripts/post-tool-verifier.mjs +8 -2
- package/scripts/postinstall-contained-fs.mjs +56 -0
- package/scripts/pre-tool-enforcer.mjs +25 -8
- package/scripts/run.cjs +18 -0
- package/scripts/runs-reconciler.mjs +103 -0
- package/scripts/stale-run-reporter.mjs +73 -0
- package/scripts/workflow-drift-guard.mjs +6 -1
- package/skills/autopilot/SKILL.md +10 -2
- package/skills/harbor/SKILL.md +8 -0
- package/skills/omc-setup/phases/04-welcome.md +1 -1
- package/skills/ralph/SKILL.md +32 -15
- package/skills/refit/SKILL.md +8 -0
- package/skills/team/SKILL.md +2 -0
- package/templates/hooks/code-simplifier.mjs +24 -2
- package/templates/hooks/lib/atomic-write.mjs +31 -8
- package/templates/hooks/session-end.mjs +99 -0
- package/templates/hooks/workflow-drift-guard.mjs +6 -1
package/bridge/team.js
CHANGED
|
@@ -1447,7 +1447,7 @@ function getNativeContainedFs() {
|
|
|
1447
1447
|
loaded = createRequire(import.meta.url)(binary);
|
|
1448
1448
|
return loaded;
|
|
1449
1449
|
} catch (cause) {
|
|
1450
|
-
throw new Error(`The contained filesystem backend is unavailable at ${binary}. Build it with node scripts/build-contained-fs.mjs before running graph commands.`, { cause });
|
|
1450
|
+
throw new Error(`The contained filesystem backend is unavailable at ${binary}. Build it with node scripts/build-contained-fs.mjs (from the installed package directory) before running graph or team commands.`, { cause });
|
|
1451
1451
|
}
|
|
1452
1452
|
}
|
|
1453
1453
|
}
|
|
@@ -1536,7 +1536,7 @@ function probeProcessStartIdentityForPlatform(pid, platform, exec2, read, strict
|
|
|
1536
1536
|
["-NoProfile", "-NonInteractive", "-Command", command],
|
|
1537
1537
|
{ encoding: "utf8", windowsHide: true }
|
|
1538
1538
|
).trim();
|
|
1539
|
-
return
|
|
1539
|
+
return /^[1-9]\d*$/.test(ticks) ? { identity: `win32:${ticks}`, precise: true } : { identity: null, precise: false };
|
|
1540
1540
|
}
|
|
1541
1541
|
if (platform === "darwin") {
|
|
1542
1542
|
if (strict) {
|
|
@@ -6661,6 +6661,7 @@ function validateTeamConfig(config) {
|
|
|
6661
6661
|
}
|
|
6662
6662
|
continue;
|
|
6663
6663
|
}
|
|
6664
|
+
const provider = spec.provider ?? "claude";
|
|
6664
6665
|
if (spec.provider !== void 0) {
|
|
6665
6666
|
if (typeof spec.provider !== "string" || !TEAM_ROLE_PROVIDERS.has(spec.provider)) {
|
|
6666
6667
|
throw new Error(
|
|
@@ -6680,6 +6681,20 @@ function validateTeamConfig(config) {
|
|
|
6680
6681
|
);
|
|
6681
6682
|
}
|
|
6682
6683
|
}
|
|
6684
|
+
if (spec.reasoningEffort !== void 0) {
|
|
6685
|
+
if (typeof spec.reasoningEffort !== "string") {
|
|
6686
|
+
throw new Error(
|
|
6687
|
+
`[OMC] team.roleRouting.${rawRoleKey}.reasoningEffort: must be a string, got ${typeof spec.reasoningEffort}`
|
|
6688
|
+
);
|
|
6689
|
+
}
|
|
6690
|
+
const allowedForProvider = REASONING_EFFORT_BY_PROVIDER[provider];
|
|
6691
|
+
if (!allowedForProvider || !allowedForProvider.has(spec.reasoningEffort)) {
|
|
6692
|
+
const allowed = allowedForProvider ? [...allowedForProvider].join("|") : "(not supported for this provider)";
|
|
6693
|
+
throw new Error(
|
|
6694
|
+
`[OMC] team.roleRouting.${rawRoleKey}.reasoningEffort: invalid value "${spec.reasoningEffort}" for provider "${provider}". Allowed: ${allowed}`
|
|
6695
|
+
);
|
|
6696
|
+
}
|
|
6697
|
+
}
|
|
6683
6698
|
}
|
|
6684
6699
|
}
|
|
6685
6700
|
function validateWorkerPermissionsConfig(config) {
|
|
@@ -6848,7 +6863,7 @@ function loadConfig() {
|
|
|
6848
6863
|
validateAutopilotConfig(config);
|
|
6849
6864
|
return config;
|
|
6850
6865
|
}
|
|
6851
|
-
var DEFAULT_CONFIG, MAX_BACKGROUND_TASKS, CANONICAL_TEAM_ROLE_SET, KNOWN_AGENT_NAME_SET, TEAM_ROLE_PROVIDERS, TEAM_ROLE_TIERS, AUTOPILOT_EXECUTION_BACKENDS, AUTOPILOT_PLANNING_MODES, AUTOPILOT_TEAM_AGENT_TYPES, AUTOPILOT_WORKFLOW_NAME, AUTOPILOT_WORKFLOW_RESERVED_NAMES, AUTOPILOT_WORKFLOW_SEQUENCES;
|
|
6866
|
+
var DEFAULT_CONFIG, MAX_BACKGROUND_TASKS, CANONICAL_TEAM_ROLE_SET, KNOWN_AGENT_NAME_SET, TEAM_ROLE_PROVIDERS, TEAM_ROLE_TIERS, REASONING_EFFORT_BY_PROVIDER, AUTOPILOT_EXECUTION_BACKENDS, AUTOPILOT_PLANNING_MODES, AUTOPILOT_TEAM_AGENT_TYPES, AUTOPILOT_WORKFLOW_NAME, AUTOPILOT_WORKFLOW_RESERVED_NAMES, AUTOPILOT_WORKFLOW_SEQUENCES;
|
|
6852
6867
|
var init_loader = __esm({
|
|
6853
6868
|
"src/config/loader.ts"() {
|
|
6854
6869
|
"use strict";
|
|
@@ -6864,6 +6879,11 @@ var init_loader = __esm({
|
|
|
6864
6879
|
KNOWN_AGENT_NAME_SET = new Set(KNOWN_AGENT_NAMES);
|
|
6865
6880
|
TEAM_ROLE_PROVIDERS = /* @__PURE__ */ new Set(["claude", "copilot", "codex", "gemini", "grok", "cursor", "antigravity"]);
|
|
6866
6881
|
TEAM_ROLE_TIERS = /* @__PURE__ */ new Set(["HIGH", "MEDIUM", "LOW"]);
|
|
6882
|
+
REASONING_EFFORT_BY_PROVIDER = {
|
|
6883
|
+
claude: /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max"]),
|
|
6884
|
+
codex: /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max", "ultra"]),
|
|
6885
|
+
antigravity: /* @__PURE__ */ new Set(["low", "medium", "high", "max"])
|
|
6886
|
+
};
|
|
6867
6887
|
AUTOPILOT_EXECUTION_BACKENDS = /* @__PURE__ */ new Set(["team", "solo"]);
|
|
6868
6888
|
AUTOPILOT_PLANNING_MODES = /* @__PURE__ */ new Set(["ralplan", "direct"]);
|
|
6869
6889
|
AUTOPILOT_TEAM_AGENT_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -8192,7 +8212,7 @@ function resolveValidatedBinaryPath(agentType) {
|
|
|
8192
8212
|
return resolveCliBinaryPath(contract.binary);
|
|
8193
8213
|
}
|
|
8194
8214
|
function buildLaunchArgs(agentType, config) {
|
|
8195
|
-
return getContract(agentType).buildLaunchArgs(config.model, config.extraFlags);
|
|
8215
|
+
return getContract(agentType).buildLaunchArgs(config.model, config.reasoningEffort, config.extraFlags);
|
|
8196
8216
|
}
|
|
8197
8217
|
function buildWorkerArgv(agentType, config) {
|
|
8198
8218
|
validateTeamName2(config.teamName);
|
|
@@ -8233,19 +8253,30 @@ function buildValidatedWorkerLaunchDescriptor(agentType, config, appendedArgs =
|
|
|
8233
8253
|
args: [...args, ...appendedArgs]
|
|
8234
8254
|
});
|
|
8235
8255
|
}
|
|
8236
|
-
function getWorkerEnv(teamName, workerName, agentType, env = process.env) {
|
|
8256
|
+
function getWorkerEnv(teamName, workerName, agentType, env = process.env, role) {
|
|
8237
8257
|
validateTeamName2(teamName);
|
|
8238
8258
|
const workerEnv = {
|
|
8239
8259
|
OMC_TEAM_WORKER: `${teamName}/${workerName}`,
|
|
8240
8260
|
OMC_TEAM_NAME: teamName,
|
|
8241
8261
|
OMC_WORKER_AGENT_TYPE: agentType
|
|
8242
8262
|
};
|
|
8263
|
+
if (role) {
|
|
8264
|
+
workerEnv.OMC_TEAM_ROLE = role;
|
|
8265
|
+
}
|
|
8243
8266
|
for (const key of WORKER_MODEL_ENV_ALLOWLIST) {
|
|
8244
8267
|
const value = env[key];
|
|
8245
8268
|
if (typeof value === "string" && value.length > 0) {
|
|
8246
8269
|
workerEnv[key] = value;
|
|
8247
8270
|
}
|
|
8248
8271
|
}
|
|
8272
|
+
if (agentType === "claude") {
|
|
8273
|
+
for (const key of CLAUDE_WORKER_ENV_ALLOWLIST) {
|
|
8274
|
+
const value = env[key];
|
|
8275
|
+
if (typeof value === "string" && value.length > 0) {
|
|
8276
|
+
workerEnv[key] = value;
|
|
8277
|
+
}
|
|
8278
|
+
}
|
|
8279
|
+
}
|
|
8249
8280
|
return workerEnv;
|
|
8250
8281
|
}
|
|
8251
8282
|
function isPromptModeAgent(agentType) {
|
|
@@ -8347,7 +8378,7 @@ function getPromptModeArgs(agentType, instruction) {
|
|
|
8347
8378
|
}
|
|
8348
8379
|
return [instruction];
|
|
8349
8380
|
}
|
|
8350
|
-
var resolvedPathCache, UNTRUSTED_PATH_PATTERNS, UNTRUSTED_WINDOWS_PATH_PATTERNS, COPILOT_WORKER_BASE_FLAGS, COPILOT_TIER_ALIAS_MODELS, CONTRACTS, WORKER_MODEL_ENV_ALLOWLIST;
|
|
8381
|
+
var resolvedPathCache, UNTRUSTED_PATH_PATTERNS, UNTRUSTED_WINDOWS_PATH_PATTERNS, COPILOT_WORKER_BASE_FLAGS, COPILOT_TIER_ALIAS_MODELS, CONTRACTS, WORKER_MODEL_ENV_ALLOWLIST, CLAUDE_WORKER_ENV_ALLOWLIST;
|
|
8351
8382
|
var init_model_contract = __esm({
|
|
8352
8383
|
"src/team/model-contract.ts"() {
|
|
8353
8384
|
"use strict";
|
|
@@ -8380,7 +8411,7 @@ var init_model_contract = __esm({
|
|
|
8380
8411
|
agentType: "claude",
|
|
8381
8412
|
binary: "claude",
|
|
8382
8413
|
installInstructions: "Install Claude CLI: https://claude.ai/download",
|
|
8383
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
8414
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
8384
8415
|
const args = ["--dangerously-skip-permissions"];
|
|
8385
8416
|
if (shouldUseClaudeBareMode() && !extraFlags.includes("--bare")) {
|
|
8386
8417
|
args.push("--bare");
|
|
@@ -8389,6 +8420,9 @@ var init_model_contract = __esm({
|
|
|
8389
8420
|
const resolved = isProviderSpecificModelId(model) ? model : normalizeToCcAlias(model);
|
|
8390
8421
|
args.push("--model", resolved);
|
|
8391
8422
|
}
|
|
8423
|
+
if (reasoningEffort) {
|
|
8424
|
+
args.push("--effort", reasoningEffort);
|
|
8425
|
+
}
|
|
8392
8426
|
return [...args, ...extraFlags];
|
|
8393
8427
|
},
|
|
8394
8428
|
parseOutput(rawOutput) {
|
|
@@ -8402,8 +8436,9 @@ var init_model_contract = __esm({
|
|
|
8402
8436
|
// Persistent interactive pane like claude (inbox + nudge); no -p prompt mode.
|
|
8403
8437
|
// Copilot rejects --dangerously-skip-permissions; the unattended pane gets an
|
|
8404
8438
|
// explicit allow set instead, and permissions.workerDenyTools/Urls arrive via
|
|
8405
|
-
// extraFlags (deny rules win over allow rules in Copilot).
|
|
8406
|
-
|
|
8439
|
+
// extraFlags (deny rules win over allow rules in Copilot). Copilot has no verified
|
|
8440
|
+
// reasoning-effort flag, so per-role reasoningEffort (upstream #4206) is not forwarded.
|
|
8441
|
+
buildLaunchArgs(model, _reasoningEffort, extraFlags = []) {
|
|
8407
8442
|
const args = [...COPILOT_WORKER_BASE_FLAGS];
|
|
8408
8443
|
if (model) args.push("--model", toCopilotModelId(model));
|
|
8409
8444
|
return [...args, ...extraFlags];
|
|
@@ -8420,9 +8455,12 @@ var init_model_contract = __esm({
|
|
|
8420
8455
|
// or positional prompt mode here; runtime dispatch writes inbox.md and nudges
|
|
8421
8456
|
// the live Codex TUI with `codex` as the worker process.
|
|
8422
8457
|
supportsPromptMode: false,
|
|
8423
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
8458
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
8424
8459
|
const args = ["--dangerously-bypass-approvals-and-sandbox"];
|
|
8425
8460
|
if (model) args.push("--model", model);
|
|
8461
|
+
if (reasoningEffort) {
|
|
8462
|
+
args.push("-c", `model_reasoning_effort="${reasoningEffort}"`);
|
|
8463
|
+
}
|
|
8426
8464
|
return [...args, ...extraFlags];
|
|
8427
8465
|
},
|
|
8428
8466
|
parseOutput(rawOutput) {
|
|
@@ -8448,7 +8486,7 @@ var init_model_contract = __esm({
|
|
|
8448
8486
|
installInstructions: "Install Gemini CLI: npm install -g @google/gemini-cli",
|
|
8449
8487
|
supportsPromptMode: true,
|
|
8450
8488
|
promptModeFlag: "-p",
|
|
8451
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
8489
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
8452
8490
|
const args = ["--approval-mode", "yolo"];
|
|
8453
8491
|
if (model) args.push("--model", model);
|
|
8454
8492
|
return [...args, ...extraFlags];
|
|
@@ -8463,7 +8501,7 @@ var init_model_contract = __esm({
|
|
|
8463
8501
|
installInstructions: "Install Grok Build: https://build.grok.com",
|
|
8464
8502
|
supportsPromptMode: true,
|
|
8465
8503
|
promptModeFlag: "-p",
|
|
8466
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
8504
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
8467
8505
|
const args = ["--always-approve"];
|
|
8468
8506
|
if (model) args.push("--model", model);
|
|
8469
8507
|
return [...args, ...extraFlags];
|
|
@@ -8478,9 +8516,12 @@ var init_model_contract = __esm({
|
|
|
8478
8516
|
installInstructions: "Install the Antigravity CLI (agy) per the official instructions at https://antigravity.google, then verify with `agy --version`.",
|
|
8479
8517
|
supportsPromptMode: true,
|
|
8480
8518
|
promptModeFlag: "-p",
|
|
8481
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
8519
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
8482
8520
|
const args = ["--dangerously-skip-permissions"];
|
|
8483
8521
|
if (model) args.push("--model", model);
|
|
8522
|
+
if (reasoningEffort) {
|
|
8523
|
+
args.push("--effort", reasoningEffort);
|
|
8524
|
+
}
|
|
8484
8525
|
return [...args, ...extraFlags];
|
|
8485
8526
|
},
|
|
8486
8527
|
parseOutput(rawOutput) {
|
|
@@ -8494,7 +8535,7 @@ var init_model_contract = __esm({
|
|
|
8494
8535
|
// Team workers must be persistent interactive panes, so the one-shot
|
|
8495
8536
|
// `-p/--print` path is deliberately unused here (same stance as codex).
|
|
8496
8537
|
supportsPromptMode: false,
|
|
8497
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
8538
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
8498
8539
|
const args = ["--force", "--trust"];
|
|
8499
8540
|
const extra = extraFlags.filter((flag) => !["--force", "-f", "--yolo", "--trust"].includes(flag));
|
|
8500
8541
|
if (model) args.push("--model", model);
|
|
@@ -8533,6 +8574,10 @@ var init_model_contract = __esm({
|
|
|
8533
8574
|
"COPILOT_HOME",
|
|
8534
8575
|
"COPILOT_MODEL"
|
|
8535
8576
|
];
|
|
8577
|
+
CLAUDE_WORKER_ENV_ALLOWLIST = [
|
|
8578
|
+
"CLAUDE_CONFIG_DIR",
|
|
8579
|
+
"CLAUDE_CODE_EFFORT_LEVEL"
|
|
8580
|
+
];
|
|
8536
8581
|
}
|
|
8537
8582
|
});
|
|
8538
8583
|
|
|
@@ -8711,11 +8756,11 @@ function tmuxEnv() {
|
|
|
8711
8756
|
function resolveEnv(opts) {
|
|
8712
8757
|
return opts?.stripTmux ? tmuxEnv() : process.env;
|
|
8713
8758
|
}
|
|
8714
|
-
function
|
|
8715
|
-
assertSafeCmdValue(
|
|
8716
|
-
if (
|
|
8717
|
-
if (!/[\s"%^&|<>()]/.test(
|
|
8718
|
-
return `"${
|
|
8759
|
+
function quoteForTmuxCmdLayer(command) {
|
|
8760
|
+
assertSafeCmdValue(command);
|
|
8761
|
+
if (command.length === 0) return '""';
|
|
8762
|
+
if (!/[\s"%^&|<>()]/.test(command)) return command;
|
|
8763
|
+
return `"${command.replace(/(["%])/g, "$1$1")}"`;
|
|
8719
8764
|
}
|
|
8720
8765
|
function assertSafeCmdValue(value) {
|
|
8721
8766
|
if (/[\0\r\n]/.test(value)) {
|
|
@@ -8726,7 +8771,7 @@ function resolveTmuxInvocation(args) {
|
|
|
8726
8771
|
const resolvedBinary = resolveTmuxBinaryPath();
|
|
8727
8772
|
if (process.platform === "win32" && /\.(cmd|bat)$/i.test(resolvedBinary)) {
|
|
8728
8773
|
const comspec = process.env.COMSPEC || "cmd.exe";
|
|
8729
|
-
const commandLine = [
|
|
8774
|
+
const commandLine = [quoteForTmuxCmdLayer(resolvedBinary), ...args.map(quoteForTmuxCmdLayer)].join(" ");
|
|
8730
8775
|
return {
|
|
8731
8776
|
command: comspec,
|
|
8732
8777
|
args: ["/d", "/s", "/c", commandLine]
|
|
@@ -9166,7 +9211,7 @@ function verifyPrivateTempFile(fd, tempPath, label, operations) {
|
|
|
9166
9211
|
`${label} temporary file must be a private regular single-link file`
|
|
9167
9212
|
);
|
|
9168
9213
|
}
|
|
9169
|
-
if (fdStats
|
|
9214
|
+
if (!sameFileIdentity(fdStats, pathStats)) {
|
|
9170
9215
|
throw new Error(`${label} temporary file was replaced before rename`);
|
|
9171
9216
|
}
|
|
9172
9217
|
}
|
|
@@ -9178,7 +9223,7 @@ function verifyPublishedFile(fd, filePath, label, operations) {
|
|
|
9178
9223
|
} catch {
|
|
9179
9224
|
throw new Error(`${label} target was replaced at publication`);
|
|
9180
9225
|
}
|
|
9181
|
-
if (!pathStats.isFile() || fdStats
|
|
9226
|
+
if (!pathStats.isFile() || !sameFileIdentity(fdStats, pathStats)) {
|
|
9182
9227
|
throw new Error(`${label} target was replaced at publication`);
|
|
9183
9228
|
}
|
|
9184
9229
|
}
|
|
@@ -9202,6 +9247,14 @@ function preservePriorTarget(filePath, operations) {
|
|
|
9202
9247
|
return null;
|
|
9203
9248
|
}
|
|
9204
9249
|
}
|
|
9250
|
+
function sameFileIdentity(a, b) {
|
|
9251
|
+
if (a.ino !== b.ino) return false;
|
|
9252
|
+
const isWindows = process.platform === "win32";
|
|
9253
|
+
if (isWindows && (a.dev === 0 || b.dev === 0)) {
|
|
9254
|
+
return true;
|
|
9255
|
+
}
|
|
9256
|
+
return a.dev === b.dev;
|
|
9257
|
+
}
|
|
9205
9258
|
function currentFileIdentity(filePath, operations) {
|
|
9206
9259
|
try {
|
|
9207
9260
|
const stats = (operations?.lstat ?? fsSync.lstatSync)(filePath);
|
|
@@ -9222,7 +9275,7 @@ function rollbackPriorTarget(filePath, backupPath, expectedIdentity, operations)
|
|
|
9222
9275
|
if (expectedIdentity === null) return;
|
|
9223
9276
|
const current = currentFileIdentity(filePath, operations);
|
|
9224
9277
|
if (current === null) return;
|
|
9225
|
-
if (expectedIdentity !== null && (current
|
|
9278
|
+
if (expectedIdentity !== null && !sameFileIdentity(current, expectedIdentity)) {
|
|
9226
9279
|
return;
|
|
9227
9280
|
}
|
|
9228
9281
|
try {
|
|
@@ -9533,11 +9586,22 @@ var init_file_lock = __esm({
|
|
|
9533
9586
|
}
|
|
9534
9587
|
});
|
|
9535
9588
|
|
|
9589
|
+
// src/lib/host-load-gate.ts
|
|
9590
|
+
import { cpus, freemem, loadavg, totalmem } from "os";
|
|
9591
|
+
import { existsSync as existsSync19, readdirSync as readdirSync7 } from "fs";
|
|
9592
|
+
import { join as join21 } from "path";
|
|
9593
|
+
var init_host_load_gate = __esm({
|
|
9594
|
+
"src/lib/host-load-gate.ts"() {
|
|
9595
|
+
"use strict";
|
|
9596
|
+
init_paths();
|
|
9597
|
+
}
|
|
9598
|
+
});
|
|
9599
|
+
|
|
9536
9600
|
// src/team/worker-launch-ack.ts
|
|
9537
9601
|
import { createHash as createHash7, randomUUID as randomUUID11 } from "node:crypto";
|
|
9538
|
-
import { constants as constants3, existsSync as
|
|
9602
|
+
import { constants as constants3, existsSync as existsSync20 } from "node:fs";
|
|
9539
9603
|
import { link as link2, lstat as lstat5, mkdir as mkdir7, mkdtemp, open as open3, readFile as readFile9, rm as rm7, unlink as unlink4, writeFile as writeFile6 } from "node:fs/promises";
|
|
9540
|
-
import { dirname as dirname19, isAbsolute as isAbsolute6, join as
|
|
9604
|
+
import { dirname as dirname19, isAbsolute as isAbsolute6, join as join22, relative as relative7, resolve as resolve8, sep as sep4 } from "node:path";
|
|
9541
9605
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
9542
9606
|
function buildWindowsSupervisorSource() {
|
|
9543
9607
|
return [
|
|
@@ -9603,7 +9667,11 @@ function normalizeProviderEnvironment(value, platform = process.platform) {
|
|
|
9603
9667
|
}
|
|
9604
9668
|
return normalized;
|
|
9605
9669
|
}
|
|
9606
|
-
function
|
|
9670
|
+
function parseEnvPassthrough(value) {
|
|
9671
|
+
if (!value || value.trim().length === 0) return [];
|
|
9672
|
+
return value.split(",").map((k) => k.trim()).filter((k) => k.length > 0);
|
|
9673
|
+
}
|
|
9674
|
+
function buildProviderEnvironment(providerEnv, sourceEnv = process.env, platform = process.platform, envPassthrough) {
|
|
9607
9675
|
const normalized = normalizeProviderEnvironment(providerEnv, platform);
|
|
9608
9676
|
const baseline = {};
|
|
9609
9677
|
for (const key of SAFE_BASELINE_ENV_KEYS) {
|
|
@@ -9624,6 +9692,14 @@ function buildProviderEnvironment(providerEnv, sourceEnv = process.env, platform
|
|
|
9624
9692
|
const homeKey = platform === "win32" ? "USERPROFILE" : "HOME";
|
|
9625
9693
|
const home = platform === "win32" ? Object.entries(sourceEnv).find(([key]) => key.toUpperCase() === homeKey)?.[1] : sourceEnv[homeKey];
|
|
9626
9694
|
if (typeof home === "string" && home.length > 0) baseline[homeKey] = home;
|
|
9695
|
+
const passthroughList = envPassthrough ?? parseEnvPassthrough(sourceEnv.OMC_TEAM_WORKER_ENV_PASSTHROUGH);
|
|
9696
|
+
for (const key of passthroughList) {
|
|
9697
|
+
if (!isValidEnvironmentKey(key)) throw new Error("worker_launch_env_passthrough_key_invalid");
|
|
9698
|
+
if (WORKER_LAUNCH_INTERNAL_ENV_KEYS.has(key)) throw new Error("worker_launch_env_passthrough_key_reserved");
|
|
9699
|
+
if (platform === "win32" && WINDOWS_RESERVED_ENV_KEYS.has(key.toUpperCase())) throw new Error("worker_launch_env_passthrough_key_reserved");
|
|
9700
|
+
const value = sourceEnv[key];
|
|
9701
|
+
if (typeof value === "string") baseline[key] = value;
|
|
9702
|
+
}
|
|
9627
9703
|
if (platform === "win32") {
|
|
9628
9704
|
for (const key of Object.keys(normalized)) {
|
|
9629
9705
|
const baselineKey = Object.keys(baseline).find((candidate) => candidate.toUpperCase() === key.toUpperCase());
|
|
@@ -9770,7 +9846,7 @@ async function prepareWorkerLaunchAttempt(input) {
|
|
|
9770
9846
|
runtimeCliPath: input.runtimeCliPath,
|
|
9771
9847
|
...input.context ? { context: input.context } : {}
|
|
9772
9848
|
};
|
|
9773
|
-
if (
|
|
9849
|
+
if (existsSync20(attempt.expectedPath) || existsSync20(attempt.ackPath) || existsSync20(attempt.decisionPath) || existsSync20(attempt.startedPath) || existsSync20(attempt.transportOwnerPath) || existsSync20(attempt.bootstrapDescriptorPath) || existsSync20(attempt.wrapperPath) || existsSync20(attempt.transportCleanupCompletePath)) {
|
|
9774
9850
|
throw new Error("worker_launch_attempt_path_conflict");
|
|
9775
9851
|
}
|
|
9776
9852
|
await writeExclusiveAtomic(attempt.expectedPath, identity);
|
|
@@ -9870,7 +9946,7 @@ function buildWorkerLaunchBootstrapSpec(attempt, providerArgv, cwd, options = {}
|
|
|
9870
9946
|
}
|
|
9871
9947
|
function attemptTransportPathsAreDeterministic(attempt) {
|
|
9872
9948
|
const expectedRoot = dirname19(attempt.expectedPath);
|
|
9873
|
-
return isDeterministicTransportPath(attempt.expectedPath, attempt.transportOwnerPath, "transport-owner.json") && isDeterministicTransportPath(attempt.expectedPath, attempt.bootstrapDescriptorPath, WORKER_LAUNCH_BOOTSTRAP_DESCRIPTOR_FILE) && isDeterministicTransportPath(attempt.expectedPath, attempt.wrapperPath, "launch.cmd") && isDeterministicTransportPath(attempt.expectedPath, attempt.transportCleanupCompletePath, "transport-cleanup-complete.json") && resolve8(attempt.expectedPath) === resolve8(
|
|
9949
|
+
return isDeterministicTransportPath(attempt.expectedPath, attempt.transportOwnerPath, "transport-owner.json") && isDeterministicTransportPath(attempt.expectedPath, attempt.bootstrapDescriptorPath, WORKER_LAUNCH_BOOTSTRAP_DESCRIPTOR_FILE) && isDeterministicTransportPath(attempt.expectedPath, attempt.wrapperPath, "launch.cmd") && isDeterministicTransportPath(attempt.expectedPath, attempt.transportCleanupCompletePath, "transport-cleanup-complete.json") && resolve8(attempt.expectedPath) === resolve8(join22(expectedRoot, "expected.json"));
|
|
9874
9950
|
}
|
|
9875
9951
|
function transportOwnerMatches(value, attempt, authorityDigest) {
|
|
9876
9952
|
if (!identityMatches(value, attempt) || typeof value !== "object" || value === null || value.kind !== WORKER_LAUNCH_TRANSPORT_OWNER_KIND) return false;
|
|
@@ -9951,7 +10027,7 @@ async function materializeWorkerLaunchTransport(input) {
|
|
|
9951
10027
|
await writeExclusiveAtomic(attempt.transportOwnerPath, owner);
|
|
9952
10028
|
ownerCreated = true;
|
|
9953
10029
|
}
|
|
9954
|
-
if (
|
|
10030
|
+
if (existsSync20(attempt.bootstrapDescriptorPath) || existsSync20(attempt.wrapperPath)) {
|
|
9955
10031
|
throw new Error("worker_launch_transport_path_conflict");
|
|
9956
10032
|
}
|
|
9957
10033
|
await writeExclusiveAtomic(attempt.bootstrapDescriptorPath, spec);
|
|
@@ -9965,19 +10041,19 @@ async function materializeWorkerLaunchTransport(input) {
|
|
|
9965
10041
|
await unlink4(attempt.wrapperPath).catch(() => {
|
|
9966
10042
|
cleanupVerified = false;
|
|
9967
10043
|
});
|
|
9968
|
-
cleanupVerified &&= !
|
|
10044
|
+
cleanupVerified &&= !existsSync20(attempt.wrapperPath);
|
|
9969
10045
|
}
|
|
9970
10046
|
if (descriptorCreated) {
|
|
9971
10047
|
await unlink4(attempt.bootstrapDescriptorPath).catch(() => {
|
|
9972
10048
|
cleanupVerified = false;
|
|
9973
10049
|
});
|
|
9974
|
-
cleanupVerified &&= !
|
|
10050
|
+
cleanupVerified &&= !existsSync20(attempt.bootstrapDescriptorPath);
|
|
9975
10051
|
}
|
|
9976
10052
|
if (ownerCreated) {
|
|
9977
10053
|
await unlink4(attempt.transportOwnerPath).catch(() => {
|
|
9978
10054
|
cleanupVerified = false;
|
|
9979
10055
|
});
|
|
9980
|
-
cleanupVerified &&= !
|
|
10056
|
+
cleanupVerified &&= !existsSync20(attempt.transportOwnerPath);
|
|
9981
10057
|
}
|
|
9982
10058
|
if (!cleanupVerified) {
|
|
9983
10059
|
const cleanupError = new Error("worker_launch_transport_partial_cleanup_unverified");
|
|
@@ -9998,7 +10074,7 @@ async function cleanupWorkerLaunchTransportUnlocked(attempt, reason) {
|
|
|
9998
10074
|
if (owner.kind === "malformed" || proof.kind === "malformed") return false;
|
|
9999
10075
|
if (owner.kind === "value" && !transportOwnerMatches(owner.value, attempt)) return false;
|
|
10000
10076
|
if (proof.kind === "value" && !cleanupProofMatches(proof.value, attempt)) return false;
|
|
10001
|
-
const hasTransportFiles =
|
|
10077
|
+
const hasTransportFiles = existsSync20(attempt.bootstrapDescriptorPath) || existsSync20(attempt.wrapperPath);
|
|
10002
10078
|
if (owner.kind === "absent") {
|
|
10003
10079
|
return !hasTransportFiles && (proof.kind === "absent" || cleanupProofMatches(proof.value, attempt));
|
|
10004
10080
|
}
|
|
@@ -10008,7 +10084,7 @@ async function cleanupWorkerLaunchTransportUnlocked(attempt, reason) {
|
|
|
10008
10084
|
await unlink4(attempt.wrapperPath).catch((error) => {
|
|
10009
10085
|
if (error.code !== "ENOENT") throw error;
|
|
10010
10086
|
});
|
|
10011
|
-
if (
|
|
10087
|
+
if (existsSync20(attempt.bootstrapDescriptorPath) || existsSync20(attempt.wrapperPath)) return false;
|
|
10012
10088
|
if (proof.kind === "absent") {
|
|
10013
10089
|
await writeExclusiveAtomic(attempt.transportCleanupCompletePath, {
|
|
10014
10090
|
...identityOf(attempt),
|
|
@@ -10018,7 +10094,7 @@ async function cleanupWorkerLaunchTransportUnlocked(attempt, reason) {
|
|
|
10018
10094
|
});
|
|
10019
10095
|
}
|
|
10020
10096
|
const completed = await readJson(attempt.transportCleanupCompletePath);
|
|
10021
|
-
return completed.kind === "value" && cleanupProofMatches(completed.value, attempt) && !
|
|
10097
|
+
return completed.kind === "value" && cleanupProofMatches(completed.value, attempt) && !existsSync20(attempt.bootstrapDescriptorPath) && !existsSync20(attempt.wrapperPath);
|
|
10022
10098
|
}
|
|
10023
10099
|
async function cleanupWorkerLaunchTransport(attempt, reason = "transport_cleanup") {
|
|
10024
10100
|
if (!attemptTransportPathsAreDeterministic(attempt)) return false;
|
|
@@ -10535,7 +10611,7 @@ async function readValidProviderStarted(attempt, options = {}) {
|
|
|
10535
10611
|
if (started.kind !== "value") return null;
|
|
10536
10612
|
if (!started.value || typeof started.value !== "object" || Array.isArray(started.value)) return null;
|
|
10537
10613
|
const record = started.value;
|
|
10538
|
-
if (!options.allowSupervisorCompletion && record.supervisor_completion_path !== void 0 && (typeof record.supervisor_completion_path !== "string" || record.supervisor_completion_path.trim().length === 0 ||
|
|
10614
|
+
if (!options.allowSupervisorCompletion && record.supervisor_completion_path !== void 0 && (typeof record.supervisor_completion_path !== "string" || record.supervisor_completion_path.trim().length === 0 || existsSync20(record.supervisor_completion_path))) return null;
|
|
10539
10615
|
if (options.allowSupervisorCompletion && record.supervisor_completion_path !== void 0 && (typeof record.supervisor_completion_path !== "string" || record.supervisor_completion_path.trim().length === 0)) return null;
|
|
10540
10616
|
return identityMatches(record, attempt) && record.kind === "worker_launch_provider_started" && Number.isSafeInteger(record.pid) && record.pid > 0 && typeof record.process_start_identity === "string" && record.process_start_identity.trim().length > 0 && (record.containment_nonce === void 0 || isExactText(record.containment_nonce)) && typeof record.written_at === "string" && Number.isFinite(Date.parse(record.written_at)) ? record : null;
|
|
10541
10617
|
}
|
|
@@ -10568,7 +10644,7 @@ async function isWorkerLaunchProviderStarted(attempt) {
|
|
|
10568
10644
|
return await readValidProviderStarted(attempt) !== null;
|
|
10569
10645
|
}
|
|
10570
10646
|
function isDeterministicTransportPath(expectedPath, candidate, fileName) {
|
|
10571
|
-
return isExactText(candidate) && resolve8(candidate) === resolve8(
|
|
10647
|
+
return isExactText(candidate) && resolve8(candidate) === resolve8(join22(dirname19(expectedPath), fileName));
|
|
10572
10648
|
}
|
|
10573
10649
|
function quoteWindowsCmdArgument(value) {
|
|
10574
10650
|
if (/[\r\n]/.test(value)) throw new Error("worker_launch_provider_argv_invalid");
|
|
@@ -10583,6 +10659,7 @@ var init_worker_launch_ack = __esm({
|
|
|
10583
10659
|
init_state_paths();
|
|
10584
10660
|
init_atomic_write();
|
|
10585
10661
|
init_file_lock();
|
|
10662
|
+
init_host_load_gate();
|
|
10586
10663
|
WORKER_LAUNCH_SCHEMA_VERSION = 1;
|
|
10587
10664
|
DEFAULT_ACK_TIMEOUT_MS = 8e3;
|
|
10588
10665
|
DEFAULT_POLL_INTERVAL_MS = 25;
|
|
@@ -10631,8 +10708,8 @@ var init_worker_launch_ack = __esm({
|
|
|
10631
10708
|
|
|
10632
10709
|
// src/team/recovery-request-store.ts
|
|
10633
10710
|
import { createHash as createHash8, randomUUID as randomUUID12 } from "crypto";
|
|
10634
|
-
import { existsSync as
|
|
10635
|
-
import { dirname as dirname20, join as
|
|
10711
|
+
import { existsSync as existsSync21, linkSync as linkSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync16, readdirSync as readdirSync8, renameSync as renameSync4, unlinkSync as unlinkSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
10712
|
+
import { dirname as dirname20, join as join23 } from "path";
|
|
10636
10713
|
function isSafeRecoveryRequestId(requestId) {
|
|
10637
10714
|
return requestId.length > 0 && requestId.length <= 128 && requestId !== "." && requestId !== ".." && /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(requestId);
|
|
10638
10715
|
}
|
|
@@ -10668,12 +10745,12 @@ function finalPath(cwd, requestId) {
|
|
|
10668
10745
|
}
|
|
10669
10746
|
function phaseDirectory(cwd, requestId) {
|
|
10670
10747
|
assertSafeRecoveryRequestId(requestId);
|
|
10671
|
-
return
|
|
10748
|
+
return join23(dirname20(reservationPath(cwd, requestId)), "phases", requestId);
|
|
10672
10749
|
}
|
|
10673
10750
|
function publishImmutable(target, value) {
|
|
10674
10751
|
const bytes = canonicalize2(value);
|
|
10675
10752
|
mkdirSync6(dirname20(target), { recursive: true, mode: 448 });
|
|
10676
|
-
const temp =
|
|
10753
|
+
const temp = join23(dirname20(target), `.${randomUUID12()}.tmp`);
|
|
10677
10754
|
writeFileSync5(temp, bytes, { encoding: "utf8", mode: 384, flush: true });
|
|
10678
10755
|
try {
|
|
10679
10756
|
linkSync4(temp, target);
|
|
@@ -10694,12 +10771,12 @@ function publishImmutable(target, value) {
|
|
|
10694
10771
|
function replaceDerivedIndex(target, value) {
|
|
10695
10772
|
const bytes = canonicalize2(value);
|
|
10696
10773
|
mkdirSync6(dirname20(target), { recursive: true, mode: 448 });
|
|
10697
|
-
const temp =
|
|
10774
|
+
const temp = join23(dirname20(target), `.${randomUUID12()}.repair.tmp`);
|
|
10698
10775
|
writeFileSync5(temp, bytes, { encoding: "utf8", mode: 384, flush: true });
|
|
10699
10776
|
try {
|
|
10700
10777
|
renameSync4(temp, target);
|
|
10701
10778
|
} finally {
|
|
10702
|
-
if (
|
|
10779
|
+
if (existsSync21(temp)) unlinkSync8(temp);
|
|
10703
10780
|
}
|
|
10704
10781
|
const repaired = parseCanonical(target);
|
|
10705
10782
|
if (!repaired || canonicalize2(repaired) !== bytes) throw new Error("immutable_recovery_record_verification_failed");
|
|
@@ -10798,7 +10875,7 @@ function resolveCanonicalRecoveryRequestId(cwd, requestId) {
|
|
|
10798
10875
|
visited.add(currentRequestId);
|
|
10799
10876
|
const reservation = readRecoveryRequestReservation(cwd, currentRequestId);
|
|
10800
10877
|
if (!reservation) {
|
|
10801
|
-
if (alias ||
|
|
10878
|
+
if (alias || existsSync21(reservationPath(cwd, currentRequestId))) return null;
|
|
10802
10879
|
return currentRequestId;
|
|
10803
10880
|
}
|
|
10804
10881
|
if (alias && !hasMatchingReservationTuple(alias, reservation)) return null;
|
|
@@ -10820,7 +10897,7 @@ function writeRecoveryPhase(cwd, phase) {
|
|
|
10820
10897
|
throw new Error("invalid_persisted_state");
|
|
10821
10898
|
}
|
|
10822
10899
|
const sequence = `${Date.now().toString().padStart(16, "0")}-${process.hrtime.bigint().toString().padStart(20, "0")}-${randomUUID12()}.json`;
|
|
10823
|
-
return publishImmutable(
|
|
10900
|
+
return publishImmutable(join23(phaseDirectory(cwd, phase.request_id), sequence), { ...phase, schema_version: 1, kind: "phase", updated_at: phase.updated_at || (/* @__PURE__ */ new Date()).toISOString() });
|
|
10824
10901
|
}
|
|
10825
10902
|
function writeRecoveryFinal(cwd, outcome) {
|
|
10826
10903
|
const reservation = readRecoveryRequestReservation(cwd, outcome.request_id);
|
|
@@ -10845,9 +10922,9 @@ function latestPhase(cwd, requestId) {
|
|
|
10845
10922
|
if (!reservation || reservation.kind !== "reservation") return null;
|
|
10846
10923
|
const directory = phaseDirectory(cwd, requestId);
|
|
10847
10924
|
try {
|
|
10848
|
-
const candidates =
|
|
10925
|
+
const candidates = readdirSync8(directory).filter((file) => file.endsWith(".json")).sort().reverse();
|
|
10849
10926
|
if (candidates.length === 0) return null;
|
|
10850
|
-
const phase = parseCanonical(
|
|
10927
|
+
const phase = parseCanonical(join23(directory, candidates[0]));
|
|
10851
10928
|
return isValidRecoveryPhase(phase, reservation) ? phase : null;
|
|
10852
10929
|
} catch {
|
|
10853
10930
|
}
|
|
@@ -10877,7 +10954,7 @@ function isValidRecoveryResult(value) {
|
|
|
10877
10954
|
}
|
|
10878
10955
|
function readRecoveryFinalState(cwd, requestId) {
|
|
10879
10956
|
const path5 = finalPath(cwd, requestId);
|
|
10880
|
-
if (!
|
|
10957
|
+
if (!existsSync21(path5)) return { kind: "missing" };
|
|
10881
10958
|
const final = parseCanonical(path5);
|
|
10882
10959
|
if (!final || final.schema_version !== 1 || final.kind !== "final" || !isMatchingRecoveryFinal(final, { requestId })) {
|
|
10883
10960
|
return { kind: "invalid" };
|
|
@@ -10887,11 +10964,11 @@ function readRecoveryFinalState(cwd, requestId) {
|
|
|
10887
10964
|
const byTeam = absPath(cwd, TeamPaths.recoveryResultByTeam(reservation.workspace_hash, final.team_name, final.recovery_id));
|
|
10888
10965
|
try {
|
|
10889
10966
|
const expectedBytes = canonicalize2(final);
|
|
10890
|
-
const indexed =
|
|
10967
|
+
const indexed = existsSync21(byTeam) ? parseCanonical(byTeam) : null;
|
|
10891
10968
|
if (!indexed || canonicalize2(indexed) !== expectedBytes) {
|
|
10892
10969
|
const lockPath = absPath(cwd, TeamPaths.recoveryFinalIndexLock(reservation.workspace_hash, final.team_name, final.recovery_id));
|
|
10893
10970
|
withProcessIdentityFileLockSync(lockPath, () => {
|
|
10894
|
-
const current =
|
|
10971
|
+
const current = existsSync21(byTeam) ? parseCanonical(byTeam) : null;
|
|
10895
10972
|
if (!current || canonicalize2(current) !== expectedBytes) replaceDerivedIndex(byTeam, final);
|
|
10896
10973
|
});
|
|
10897
10974
|
}
|
|
@@ -10991,9 +11068,9 @@ __export(runtime_owner_client_exports, {
|
|
|
10991
11068
|
});
|
|
10992
11069
|
import { spawn } from "node:child_process";
|
|
10993
11070
|
import { createHash as createHash9, randomUUID as randomUUID13 } from "node:crypto";
|
|
10994
|
-
import { existsSync as
|
|
11071
|
+
import { existsSync as existsSync22, readdirSync as readdirSync9, readFileSync as readFileSync17 } from "node:fs";
|
|
10995
11072
|
import { link as link3, mkdir as mkdir8, open as open4, readFile as readFile10, unlink as unlink5 } from "node:fs/promises";
|
|
10996
|
-
import { basename as basename11, dirname as dirname21, join as
|
|
11073
|
+
import { basename as basename11, dirname as dirname21, join as join24 } from "node:path";
|
|
10997
11074
|
function workspaceHash(cwd) {
|
|
10998
11075
|
return createHash9("sha256").update(cwd).digest("hex");
|
|
10999
11076
|
}
|
|
@@ -11045,7 +11122,7 @@ function resolveCanonicalReservation(cwd, reservation) {
|
|
|
11045
11122
|
function findActiveIdenticalReservation(cwd, payload) {
|
|
11046
11123
|
const targetHash = canonicalRecoveryPayloadHash(payload);
|
|
11047
11124
|
try {
|
|
11048
|
-
for (const name of
|
|
11125
|
+
for (const name of readdirSync9(absPath(cwd, TeamPaths.recoveryRequestsRoot()))) {
|
|
11049
11126
|
const match = /^(.+)\.pending\.json$/.exec(name);
|
|
11050
11127
|
if (!match) continue;
|
|
11051
11128
|
const reservation = readRecoveryRequestReservation(cwd, match[1]);
|
|
@@ -11133,11 +11210,11 @@ async function publishRecoveryOwnerBootstrapCandidate(input, recoveryId, expecte
|
|
|
11133
11210
|
}
|
|
11134
11211
|
function hasLiveOrUnknownBootstrapCandidate(input, recoveryId, expectedEpoch, predecessor) {
|
|
11135
11212
|
const candidateDirectory = dirname21(recoveryOwnerBootstrapCandidatePath(input.cwd, input.teamName, expectedEpoch, "candidate"));
|
|
11136
|
-
const legacyCandidate =
|
|
11137
|
-
if (
|
|
11213
|
+
const legacyCandidate = join24(dirname21(candidateDirectory), `${expectedEpoch}.json`);
|
|
11214
|
+
if (existsSync22(legacyCandidate)) return true;
|
|
11138
11215
|
let entries;
|
|
11139
11216
|
try {
|
|
11140
|
-
entries =
|
|
11217
|
+
entries = readdirSync9(candidateDirectory);
|
|
11141
11218
|
} catch {
|
|
11142
11219
|
return false;
|
|
11143
11220
|
}
|
|
@@ -11145,7 +11222,7 @@ function hasLiveOrUnknownBootstrapCandidate(input, recoveryId, expectedEpoch, pr
|
|
|
11145
11222
|
if (!entry.endsWith(".json")) continue;
|
|
11146
11223
|
let value;
|
|
11147
11224
|
try {
|
|
11148
|
-
value = JSON.parse(readFileSync17(
|
|
11225
|
+
value = JSON.parse(readFileSync17(join24(candidateDirectory, entry), "utf8"));
|
|
11149
11226
|
} catch {
|
|
11150
11227
|
return true;
|
|
11151
11228
|
}
|
|
@@ -11257,7 +11334,7 @@ function timeoutResult(input, recoveryId) {
|
|
|
11257
11334
|
}
|
|
11258
11335
|
async function teamRecoveryState(cwd, teamName) {
|
|
11259
11336
|
const configPath = absPath(cwd, TeamPaths.config(teamName));
|
|
11260
|
-
if (!
|
|
11337
|
+
if (!existsSync22(configPath)) return "team_not_found";
|
|
11261
11338
|
try {
|
|
11262
11339
|
const revisioned = await readRevisionedTeamConfig(teamName, cwd);
|
|
11263
11340
|
if (revisioned) return "v2";
|
|
@@ -11320,7 +11397,7 @@ function ownerAvailability(cwd, teamName) {
|
|
|
11320
11397
|
function resolveRuntimeCliPath() {
|
|
11321
11398
|
if (process.env.OMC_RUNTIME_CLI_PATH) return process.env.OMC_RUNTIME_CLI_PATH;
|
|
11322
11399
|
if (typeof __dirname !== "undefined" && __dirname) {
|
|
11323
|
-
return basename11(__dirname) === "bridge" ?
|
|
11400
|
+
return basename11(__dirname) === "bridge" ? join24(__dirname, "runtime-cli.cjs") : join24(__dirname, "../../bridge/runtime-cli.cjs");
|
|
11324
11401
|
}
|
|
11325
11402
|
const entry = process.argv[1];
|
|
11326
11403
|
if (entry && basename11(entry) === "runtime-cli.cjs") return entry;
|
|
@@ -11685,6 +11762,7 @@ __export(tmux_session_exports, {
|
|
|
11685
11762
|
spawnWorkerInPane: () => spawnWorkerInPane,
|
|
11686
11763
|
splitTeamWorkerPane: () => splitTeamWorkerPane,
|
|
11687
11764
|
splitTeamWorkerPaneWithEvidence: () => splitTeamWorkerPaneWithEvidence,
|
|
11765
|
+
strictIdentityUnavailableError: () => strictIdentityUnavailableError,
|
|
11688
11766
|
validateTmux: () => validateTmux,
|
|
11689
11767
|
verifyTeamTargetOwnership: () => verifyTeamTargetOwnership,
|
|
11690
11768
|
waitForPaneReady: () => waitForPaneReady,
|
|
@@ -11692,11 +11770,11 @@ __export(tmux_session_exports, {
|
|
|
11692
11770
|
workerPaneBelongsToOwnedProviderTarget: () => workerPaneBelongsToOwnedProviderTarget,
|
|
11693
11771
|
workerPaneBelongsToProviderTarget: () => workerPaneBelongsToProviderTarget
|
|
11694
11772
|
});
|
|
11695
|
-
import { existsSync as
|
|
11773
|
+
import { existsSync as existsSync23, statSync as statSync4 } from "fs";
|
|
11696
11774
|
import { createHash as createHash10, randomUUID as randomUUID14 } from "crypto";
|
|
11697
11775
|
import { execFile as execFile3 } from "child_process";
|
|
11698
11776
|
import { promisify as promisify3 } from "util";
|
|
11699
|
-
import { join as
|
|
11777
|
+
import { join as join25, basename as basename12, isAbsolute as isAbsolute7, win32 as win323 } from "path";
|
|
11700
11778
|
import { tmpdir as tmpdir3 } from "os";
|
|
11701
11779
|
function tmuxArgsForIdentity(identity, args) {
|
|
11702
11780
|
return ["-S", identity.socket_path, ...args];
|
|
@@ -11719,7 +11797,7 @@ function buildDetachedTmuxServerKeepaliveArgs(socketPath) {
|
|
|
11719
11797
|
function buildPrivateTmuxSocketPath() {
|
|
11720
11798
|
if (isPsmux()) return buildPsmuxNamespacePath();
|
|
11721
11799
|
const socketDirectory = process.platform === "darwin" || process.platform === "linux" ? "/tmp" : tmpdir3();
|
|
11722
|
-
const socketPath =
|
|
11800
|
+
const socketPath = join25(
|
|
11723
11801
|
socketDirectory,
|
|
11724
11802
|
`o-${process.pid.toString(36)}-${Date.now().toString(36)}-${randomUUID14().slice(0, 8)}.sock`
|
|
11725
11803
|
);
|
|
@@ -11751,7 +11829,7 @@ function resolveTmuxServerGuardRuntime() {
|
|
|
11751
11829
|
return { nodePath, runtimePath };
|
|
11752
11830
|
}
|
|
11753
11831
|
function isRegularFile(path5) {
|
|
11754
|
-
if (!
|
|
11832
|
+
if (!existsSync23(path5)) return false;
|
|
11755
11833
|
try {
|
|
11756
11834
|
return statSync4(path5).isFile();
|
|
11757
11835
|
} catch {
|
|
@@ -11785,6 +11863,13 @@ function parseTmuxServerFields(output2) {
|
|
|
11785
11863
|
function buildTmuxServerIdentity(socketPath, pid, processIdentity) {
|
|
11786
11864
|
const processStartedAt = processIdentity(pid);
|
|
11787
11865
|
if (!processStartedAt || !isValidStrictProcessStartIdentity(processStartedAt)) return null;
|
|
11866
|
+
if (process.platform === "win32") {
|
|
11867
|
+
try {
|
|
11868
|
+
process.kill(pid, 0);
|
|
11869
|
+
} catch {
|
|
11870
|
+
return null;
|
|
11871
|
+
}
|
|
11872
|
+
}
|
|
11788
11873
|
const identity = {
|
|
11789
11874
|
socket_path: socketPath,
|
|
11790
11875
|
server_pid: pid,
|
|
@@ -11837,17 +11922,26 @@ async function captureTmuxServerIdentity(selectedEndpoint, dependencies = {}) {
|
|
|
11837
11922
|
async function observeTmuxServerIdentity(expected, dependencies = {}) {
|
|
11838
11923
|
const deps = { ...defaultTmuxServerIdentityDependencies, ...dependencies };
|
|
11839
11924
|
if (!isValidTmuxServerIdentity(expected) || !isValidStrictProcessStartIdentity(expected.process_started_at)) return "unknown";
|
|
11840
|
-
|
|
11841
|
-
|
|
11842
|
-
|
|
11843
|
-
|
|
11844
|
-
|
|
11845
|
-
|
|
11846
|
-
|
|
11847
|
-
|
|
11925
|
+
const singleWindowsProbe = process.platform === "win32" && dependencies.processObservation === void 0;
|
|
11926
|
+
if (singleWindowsProbe) {
|
|
11927
|
+
try {
|
|
11928
|
+
process.kill(expected.server_pid, 0);
|
|
11929
|
+
} catch (error) {
|
|
11930
|
+
return error.code === "ESRCH" ? "dead" : "unknown";
|
|
11931
|
+
}
|
|
11932
|
+
} else {
|
|
11933
|
+
let processState;
|
|
11934
|
+
try {
|
|
11935
|
+
processState = deps.processObservation({
|
|
11936
|
+
server_pid: expected.server_pid,
|
|
11937
|
+
process_started_at: expected.process_started_at
|
|
11938
|
+
});
|
|
11939
|
+
} catch {
|
|
11940
|
+
return "unknown";
|
|
11941
|
+
}
|
|
11942
|
+
if (processState === "dead") return "dead";
|
|
11943
|
+
if (processState !== "matching") return "unknown";
|
|
11848
11944
|
}
|
|
11849
|
-
if (processState === "dead") return "dead";
|
|
11850
|
-
if (processState !== "matching") return "unknown";
|
|
11851
11945
|
try {
|
|
11852
11946
|
const result = await deps.tmuxQuery(
|
|
11853
11947
|
tmuxArgsForIdentity(expected, ["display-message", "-p", "#{pid}"]),
|
|
@@ -11859,7 +11953,15 @@ async function observeTmuxServerIdentity(expected, dependencies = {}) {
|
|
|
11859
11953
|
const actualPid = parseExactPositivePid(lines[0]);
|
|
11860
11954
|
if (actualPid !== expected.server_pid) return "unknown";
|
|
11861
11955
|
const actualStart = deps.processIdentity(actualPid);
|
|
11956
|
+
if (singleWindowsProbe && actualStart && isValidStrictProcessStartIdentity(actualStart) && actualStart !== expected.process_started_at) return "dead";
|
|
11862
11957
|
if (!actualStart || actualStart !== expected.process_started_at) return "unknown";
|
|
11958
|
+
if (singleWindowsProbe) {
|
|
11959
|
+
try {
|
|
11960
|
+
process.kill(actualPid, 0);
|
|
11961
|
+
} catch (error) {
|
|
11962
|
+
return error.code === "ESRCH" ? "dead" : "unknown";
|
|
11963
|
+
}
|
|
11964
|
+
}
|
|
11863
11965
|
return "matching";
|
|
11864
11966
|
} catch {
|
|
11865
11967
|
return "unknown";
|
|
@@ -12387,15 +12489,15 @@ function pathCandidateNames(candidatePath) {
|
|
|
12387
12489
|
function resolveShellFromPath(candidatePath) {
|
|
12388
12490
|
for (const dir of pathEntries(process.env.PATH)) {
|
|
12389
12491
|
for (const name of pathCandidateNames(candidatePath)) {
|
|
12390
|
-
const full =
|
|
12391
|
-
if (
|
|
12492
|
+
const full = join25(dir, name);
|
|
12493
|
+
if (existsSync23(full)) return full;
|
|
12392
12494
|
}
|
|
12393
12495
|
}
|
|
12394
12496
|
return null;
|
|
12395
12497
|
}
|
|
12396
12498
|
function resolveShellFromCandidates(paths, rcFile) {
|
|
12397
12499
|
for (const p of paths) {
|
|
12398
|
-
if (
|
|
12500
|
+
if (existsSync23(p)) return { shell: p, rcFile };
|
|
12399
12501
|
const resolvedFromPath = resolveShellFromPath(p);
|
|
12400
12502
|
if (resolvedFromPath) return { shell: resolvedFromPath, rcFile };
|
|
12401
12503
|
}
|
|
@@ -12405,7 +12507,7 @@ function resolveSupportedShellAffinity(shellPath2) {
|
|
|
12405
12507
|
if (!shellPath2) return null;
|
|
12406
12508
|
const name = basename12(shellPath2.replace(/\\/g, "/")).replace(/\.(exe|cmd|bat)$/i, "");
|
|
12407
12509
|
if (name !== "zsh" && name !== "bash") return null;
|
|
12408
|
-
if (!
|
|
12510
|
+
if (!existsSync23(shellPath2)) return null;
|
|
12409
12511
|
const home = process.env.HOME ?? "";
|
|
12410
12512
|
const rcFile = home ? `${home}/.${name}rc` : null;
|
|
12411
12513
|
return { shell: shellPath2, rcFile };
|
|
@@ -12618,11 +12720,13 @@ function buildWorkerStartCommand(config) {
|
|
|
12618
12720
|
const providerLaunchWords = getLaunchWords(config);
|
|
12619
12721
|
const launchWords = config.launchAttempt ? [process.execPath, config.launchAttempt.runtimeCliPath, "--worker-launch"] : providerLaunchWords;
|
|
12620
12722
|
const envVars = config.launchAttempt ? {
|
|
12621
|
-
...config.envVars,
|
|
12622
12723
|
// Supervised launches carry the attempt-owned bootstrap descriptor by
|
|
12623
12724
|
// path (never inline): secrets stay out of the process list and tmux
|
|
12624
12725
|
// scrollback, and the delivered command stays small. The runtime CLI
|
|
12625
12726
|
// validates and consumes the descriptor before running the provider.
|
|
12727
|
+
// Team identity (team_name, worker_name, provider, instance_id) is read
|
|
12728
|
+
// from the descriptor, not from environment vars, keeping the typed
|
|
12729
|
+
// command under 1024 bytes even with long cwd paths.
|
|
12626
12730
|
OMC_WORKER_LAUNCH_SPEC_FILE: config.launchAttempt.bootstrapDescriptorPath
|
|
12627
12731
|
} : config.envVars;
|
|
12628
12732
|
const shouldSourceRc = process.env.OMC_TEAM_NO_RC !== "1";
|
|
@@ -12912,6 +13016,17 @@ async function splitTeamWorkerPaneWithEvidence(splitTarget, direction, cwd, prov
|
|
|
12912
13016
|
async function splitTeamWorkerPane(splitTarget, direction, cwd) {
|
|
12913
13017
|
return (await splitTeamWorkerPaneWithEvidence(splitTarget, direction, cwd)).paneId;
|
|
12914
13018
|
}
|
|
13019
|
+
function strictIdentityUnavailableError(platform, loadNative = getNativeContainedFs) {
|
|
13020
|
+
if (platform === "darwin") {
|
|
13021
|
+
try {
|
|
13022
|
+
loadNative();
|
|
13023
|
+
} catch (cause) {
|
|
13024
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
13025
|
+
return new Error(`tmux_server_identity_probe_unavailable: ${detail}`, { cause });
|
|
13026
|
+
}
|
|
13027
|
+
}
|
|
13028
|
+
return new Error("tmux_server_identity_probe_unavailable");
|
|
13029
|
+
}
|
|
12915
13030
|
async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
12916
13031
|
const multiplexerContext = isPsmux() ? "none" : detectTeamMultiplexerContext();
|
|
12917
13032
|
const inTmux = multiplexerContext === "tmux";
|
|
@@ -12921,7 +13036,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
12921
13036
|
validateTmux();
|
|
12922
13037
|
}
|
|
12923
13038
|
if (!inCmux && !currentStrictProcessStartIdentity()) {
|
|
12924
|
-
throw
|
|
13039
|
+
throw strictIdentityUnavailableError(process.platform);
|
|
12925
13040
|
}
|
|
12926
13041
|
let tmuxServerIdentity;
|
|
12927
13042
|
let freshDetachedServerIdentity;
|
|
@@ -12971,7 +13086,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
12971
13086
|
"-d",
|
|
12972
13087
|
"-P",
|
|
12973
13088
|
"-F",
|
|
12974
|
-
"#S
|
|
13089
|
+
"#S:#{window_index} #{pane_id} #{socket_path} #{pid}",
|
|
12975
13090
|
"-s",
|
|
12976
13091
|
detachedSessionName,
|
|
12977
13092
|
"-c",
|
|
@@ -13665,7 +13780,7 @@ async function spawnWorkerInPane(sessionName2, paneId, config) {
|
|
|
13665
13780
|
if (config.launchAttempt) {
|
|
13666
13781
|
await revokeWorkerLaunchAttempt(config.launchAttempt, "launch_failed").catch(() => void 0);
|
|
13667
13782
|
}
|
|
13668
|
-
if (config.launchAttempt && (!materializedTransport ||
|
|
13783
|
+
if (config.launchAttempt && (!materializedTransport || existsSync23(materializedTransport.bootstrapDescriptorPath))) {
|
|
13669
13784
|
const cleaned = await cleanupWorkerLaunchTransport(config.launchAttempt, "launch_failed").catch(() => false);
|
|
13670
13785
|
if (!cleaned) {
|
|
13671
13786
|
logWorkerSpawnDiagnostic(
|
|
@@ -14486,7 +14601,7 @@ function parseDedicatedWindowTarget(sessionName2) {
|
|
|
14486
14601
|
}
|
|
14487
14602
|
function normalizeDetachedSessionTarget(sessionName2) {
|
|
14488
14603
|
const detachedTarget = sessionName2.includes(":") ? parseDedicatedWindowTarget(sessionName2) : null;
|
|
14489
|
-
const sessionTarget = detachedTarget ? detachedTarget.
|
|
14604
|
+
const sessionTarget = detachedTarget ? detachedTarget.sessionName : sessionName2;
|
|
14490
14605
|
return sessionTarget && /^[^\s:]+$/.test(sessionTarget) ? sessionTarget : null;
|
|
14491
14606
|
}
|
|
14492
14607
|
async function resolveSplitPaneWorkerPaneIds(_sessionName, recordedPaneIds, leaderPaneId) {
|
|
@@ -14652,6 +14767,7 @@ var init_tmux_session = __esm({
|
|
|
14652
14767
|
init_tmux_utils();
|
|
14653
14768
|
init_types();
|
|
14654
14769
|
init_team_owner_epoch();
|
|
14770
|
+
init_native_contained_fs();
|
|
14655
14771
|
init_pane_readiness();
|
|
14656
14772
|
init_worker_launch_ack();
|
|
14657
14773
|
init_runtime_owner_client();
|
|
@@ -14708,7 +14824,7 @@ var init_tmux_session = __esm({
|
|
|
14708
14824
|
|
|
14709
14825
|
// src/team/mcp-comm.ts
|
|
14710
14826
|
import { realpathSync as realpathSync4 } from "node:fs";
|
|
14711
|
-
import { basename as basename13, dirname as dirname22, join as
|
|
14827
|
+
import { basename as basename13, dirname as dirname22, join as join26 } from "node:path";
|
|
14712
14828
|
function isConfirmedNotification(outcome) {
|
|
14713
14829
|
if (!outcome.ok) return false;
|
|
14714
14830
|
if (outcome.transport !== "hook") return true;
|
|
@@ -14734,7 +14850,7 @@ function canonicalNotificationLockIdentity(lockPath) {
|
|
|
14734
14850
|
return realpathSync4(lockPath);
|
|
14735
14851
|
} catch {
|
|
14736
14852
|
try {
|
|
14737
|
-
return
|
|
14853
|
+
return join26(realpathSync4(dirname22(lockPath)), basename13(lockPath));
|
|
14738
14854
|
} catch {
|
|
14739
14855
|
return lockPath;
|
|
14740
14856
|
}
|
|
@@ -15199,18 +15315,18 @@ var init_mcp_comm = __esm({
|
|
|
15199
15315
|
});
|
|
15200
15316
|
|
|
15201
15317
|
// src/agents/prompt-helpers.ts
|
|
15202
|
-
import { readdirSync as
|
|
15203
|
-
import { join as
|
|
15318
|
+
import { readdirSync as readdirSync10 } from "fs";
|
|
15319
|
+
import { join as join27, dirname as dirname23, basename as basename14 } from "path";
|
|
15204
15320
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
15205
15321
|
function getPackageDir3() {
|
|
15206
15322
|
if (typeof __dirname !== "undefined" && __dirname) {
|
|
15207
15323
|
const currentDirName = basename14(__dirname);
|
|
15208
15324
|
const parentDirName = basename14(dirname23(__dirname));
|
|
15209
15325
|
if (currentDirName === "bridge") {
|
|
15210
|
-
return
|
|
15326
|
+
return join27(__dirname, "..");
|
|
15211
15327
|
}
|
|
15212
15328
|
if (currentDirName === "agents" && (parentDirName === "src" || parentDirName === "dist")) {
|
|
15213
|
-
return
|
|
15329
|
+
return join27(__dirname, "..", "..");
|
|
15214
15330
|
}
|
|
15215
15331
|
}
|
|
15216
15332
|
try {
|
|
@@ -15218,9 +15334,9 @@ function getPackageDir3() {
|
|
|
15218
15334
|
const __dirname2 = dirname23(__filename);
|
|
15219
15335
|
const currentDirName = basename14(__dirname2);
|
|
15220
15336
|
if (currentDirName === "bridge") {
|
|
15221
|
-
return
|
|
15337
|
+
return join27(__dirname2, "..");
|
|
15222
15338
|
}
|
|
15223
|
-
return
|
|
15339
|
+
return join27(__dirname2, "..", "..");
|
|
15224
15340
|
} catch {
|
|
15225
15341
|
}
|
|
15226
15342
|
return process.cwd();
|
|
@@ -15235,8 +15351,8 @@ function getValidAgentRoles() {
|
|
|
15235
15351
|
} catch {
|
|
15236
15352
|
}
|
|
15237
15353
|
try {
|
|
15238
|
-
const agentsDir =
|
|
15239
|
-
const files =
|
|
15354
|
+
const agentsDir = join27(getPackageDir3(), "agents");
|
|
15355
|
+
const files = readdirSync10(agentsDir);
|
|
15240
15356
|
_cachedRoles = files.filter((f) => f.endsWith(".md")).map((f) => basename14(f, ".md")).sort();
|
|
15241
15357
|
} catch (err) {
|
|
15242
15358
|
console.error("[prompt-injection] CRITICAL: Could not scan agents/ directory for role discovery:", err);
|
|
@@ -15269,9 +15385,9 @@ var init_prompt_helpers = __esm({
|
|
|
15269
15385
|
|
|
15270
15386
|
// src/team/worker-bootstrap.ts
|
|
15271
15387
|
import { mkdir as mkdir9, writeFile as writeFile7, appendFile as appendFile2 } from "fs/promises";
|
|
15272
|
-
import { join as
|
|
15388
|
+
import { join as join28, dirname as dirname24 } from "path";
|
|
15273
15389
|
function buildInstructionPath(...parts) {
|
|
15274
|
-
return
|
|
15390
|
+
return join28(...parts).replaceAll("\\", "/");
|
|
15275
15391
|
}
|
|
15276
15392
|
function shellPath(path5) {
|
|
15277
15393
|
if (path5.startsWith("$OMC_TEAM_STATE_ROOT/")) return `"${path5}"`;
|
|
@@ -15538,7 +15654,7 @@ ${bootstrapInstructions}
|
|
|
15538
15654
|
` : ""}`;
|
|
15539
15655
|
}
|
|
15540
15656
|
async function composeInitialInbox(teamName, workerName, content, cwd, cliOutputContract) {
|
|
15541
|
-
const inboxPath =
|
|
15657
|
+
const inboxPath = join28(teamStateRoot(cwd, sanitizeName(teamName)), "workers", sanitizeName(workerName), "inbox.md");
|
|
15542
15658
|
await mkdir9(dirname24(inboxPath), { recursive: true });
|
|
15543
15659
|
const finalContent = cliOutputContract && !content.includes(cliOutputContract) ? `${content}
|
|
15544
15660
|
${cliOutputContract}` : content;
|
|
@@ -15547,7 +15663,7 @@ ${cliOutputContract}` : content;
|
|
|
15547
15663
|
async function appendToInbox(teamName, workerName, message, cwd) {
|
|
15548
15664
|
const safeTeam = sanitizeName(teamName);
|
|
15549
15665
|
const safeWorker = sanitizeName(workerName);
|
|
15550
|
-
const inboxPath =
|
|
15666
|
+
const inboxPath = join28(teamStateRoot(cwd, safeTeam), "workers", safeWorker, "inbox.md");
|
|
15551
15667
|
validateResolvedPath(inboxPath, teamStateRoot(cwd, safeTeam));
|
|
15552
15668
|
await mkdir9(dirname24(inboxPath), { recursive: true });
|
|
15553
15669
|
await appendFile2(inboxPath, `
|
|
@@ -15557,17 +15673,17 @@ ${message}`, "utf-8");
|
|
|
15557
15673
|
}
|
|
15558
15674
|
async function ensureWorkerStateDir(teamName, workerName, cwd) {
|
|
15559
15675
|
const root = teamStateRoot(cwd, sanitizeName(teamName));
|
|
15560
|
-
const workerDir =
|
|
15676
|
+
const workerDir = join28(root, "workers", sanitizeName(workerName));
|
|
15561
15677
|
await mkdir9(workerDir, { recursive: true });
|
|
15562
|
-
const mailboxDir =
|
|
15678
|
+
const mailboxDir = join28(root, "mailbox");
|
|
15563
15679
|
await mkdir9(mailboxDir, { recursive: true });
|
|
15564
|
-
const tasksDir =
|
|
15680
|
+
const tasksDir = join28(root, "tasks");
|
|
15565
15681
|
await mkdir9(tasksDir, { recursive: true });
|
|
15566
15682
|
}
|
|
15567
15683
|
async function writeWorkerOverlay(params) {
|
|
15568
15684
|
const { teamName, workerName, cwd } = params;
|
|
15569
15685
|
const overlay = generateWorkerOverlay(params);
|
|
15570
|
-
const overlayPath =
|
|
15686
|
+
const overlayPath = join28(teamStateRoot(cwd, sanitizeName(teamName)), "workers", sanitizeName(workerName), "AGENTS.md");
|
|
15571
15687
|
await mkdir9(dirname24(overlayPath), { recursive: true });
|
|
15572
15688
|
await writeFile7(overlayPath, overlay, "utf-8");
|
|
15573
15689
|
return overlayPath;
|
|
@@ -15650,8 +15766,8 @@ var init_allocation_policy = __esm({
|
|
|
15650
15766
|
|
|
15651
15767
|
// src/team/mailbox-outstanding.ts
|
|
15652
15768
|
import { readFile as readFile11, readdir as readdir5 } from "fs/promises";
|
|
15653
|
-
import { existsSync as
|
|
15654
|
-
import { join as
|
|
15769
|
+
import { existsSync as existsSync24 } from "fs";
|
|
15770
|
+
import { join as join29 } from "path";
|
|
15655
15771
|
function safeString(value) {
|
|
15656
15772
|
return typeof value === "string" ? value : "";
|
|
15657
15773
|
}
|
|
@@ -15675,7 +15791,7 @@ function messageToWorker(message) {
|
|
|
15675
15791
|
}
|
|
15676
15792
|
async function readMailboxFileMessages(filePath) {
|
|
15677
15793
|
try {
|
|
15678
|
-
if (!
|
|
15794
|
+
if (!existsSync24(filePath)) return [];
|
|
15679
15795
|
const raw = await readFile11(filePath, "utf-8");
|
|
15680
15796
|
const parsed = JSON.parse(raw);
|
|
15681
15797
|
if (Array.isArray(parsed)) return parsed;
|
|
@@ -15689,7 +15805,7 @@ async function readMailboxFileMessages(filePath) {
|
|
|
15689
15805
|
}
|
|
15690
15806
|
async function readMailboxFileMessagesJsonl(filePath) {
|
|
15691
15807
|
try {
|
|
15692
|
-
if (!
|
|
15808
|
+
if (!existsSync24(filePath)) return [];
|
|
15693
15809
|
const raw = await readFile11(filePath, "utf-8");
|
|
15694
15810
|
const messages = [];
|
|
15695
15811
|
for (const line of raw.split("\n")) {
|
|
@@ -15719,10 +15835,10 @@ async function scanMailboxOutstanding(mailboxDir) {
|
|
|
15719
15835
|
let messages = [];
|
|
15720
15836
|
if (entry.endsWith(".json")) {
|
|
15721
15837
|
recipient = entry.slice(0, -".json".length);
|
|
15722
|
-
messages = await readMailboxFileMessages(
|
|
15838
|
+
messages = await readMailboxFileMessages(join29(mailboxDir, entry));
|
|
15723
15839
|
} else if (entry.endsWith(".jsonl")) {
|
|
15724
15840
|
recipient = entry.slice(0, -".jsonl".length);
|
|
15725
|
-
messages = await readMailboxFileMessagesJsonl(
|
|
15841
|
+
messages = await readMailboxFileMessagesJsonl(join29(mailboxDir, entry));
|
|
15726
15842
|
} else {
|
|
15727
15843
|
continue;
|
|
15728
15844
|
}
|
|
@@ -15770,7 +15886,7 @@ var init_mailbox_outstanding = __esm({
|
|
|
15770
15886
|
import { randomUUID as randomUUID15 } from "crypto";
|
|
15771
15887
|
import { dirname as dirname25 } from "path";
|
|
15772
15888
|
import { mkdir as mkdir10, readFile as readFile12, appendFile as appendFile3 } from "fs/promises";
|
|
15773
|
-
import { existsSync as
|
|
15889
|
+
import { existsSync as existsSync25 } from "fs";
|
|
15774
15890
|
async function appendTeamEvent(teamName, event, cwd) {
|
|
15775
15891
|
const full = {
|
|
15776
15892
|
event_id: randomUUID15(),
|
|
@@ -15886,9 +16002,9 @@ var init_phase_controller = __esm({
|
|
|
15886
16002
|
});
|
|
15887
16003
|
|
|
15888
16004
|
// src/lib/worktree-cleanup-safety.ts
|
|
15889
|
-
import { existsSync as
|
|
16005
|
+
import { existsSync as existsSync26, lstatSync as lstatSync5, realpathSync as realpathSync5 } from "node:fs";
|
|
15890
16006
|
import { homedir as homedir6 } from "node:os";
|
|
15891
|
-
import { isAbsolute as isAbsolute8, join as
|
|
16007
|
+
import { isAbsolute as isAbsolute8, join as join30, parse as parse3, relative as relative8, resolve as resolve9 } from "node:path";
|
|
15892
16008
|
function realpathOrResolve(path5) {
|
|
15893
16009
|
try {
|
|
15894
16010
|
return realpathSync5(path5);
|
|
@@ -15935,7 +16051,7 @@ function validateWorktreeRemovalTarget(options) {
|
|
|
15935
16051
|
throw new Error(`worktree_path_suspicious:${rawCandidate}`);
|
|
15936
16052
|
}
|
|
15937
16053
|
const lexicalPath = resolve9(rawCandidate);
|
|
15938
|
-
if (!
|
|
16054
|
+
if (!existsSync26(lexicalPath)) {
|
|
15939
16055
|
if (requireExisting) {
|
|
15940
16056
|
throw new Error(`worktree_path_missing:${lexicalPath}`);
|
|
15941
16057
|
}
|
|
@@ -15960,8 +16076,8 @@ function validateWorktreeRemovalTarget(options) {
|
|
|
15960
16076
|
throw new Error(`worktree_path_is_main_repo:${resolvedPath}`);
|
|
15961
16077
|
}
|
|
15962
16078
|
}
|
|
15963
|
-
if (
|
|
15964
|
-
const gitStat = lstatSync5(
|
|
16079
|
+
if (existsSync26(join30(resolvedPath, ".git"))) {
|
|
16080
|
+
const gitStat = lstatSync5(join30(resolvedPath, ".git"));
|
|
15965
16081
|
if (gitStat.isDirectory()) {
|
|
15966
16082
|
throw new Error(`worktree_path_is_main_repo:${resolvedPath}`);
|
|
15967
16083
|
}
|
|
@@ -15975,11 +16091,11 @@ var init_worktree_cleanup_safety = __esm({
|
|
|
15975
16091
|
});
|
|
15976
16092
|
|
|
15977
16093
|
// src/team/git-worktree.ts
|
|
15978
|
-
import { existsSync as
|
|
15979
|
-
import { join as
|
|
16094
|
+
import { existsSync as existsSync27, realpathSync as realpathSync6, readFileSync as readFileSync18, readdirSync as readdirSync11, rmSync as rmSync2, unlinkSync as unlinkSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
16095
|
+
import { join as join31, resolve as resolve10 } from "node:path";
|
|
15980
16096
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
15981
16097
|
function getWorktreePath(repoRoot, teamName, workerName) {
|
|
15982
|
-
return
|
|
16098
|
+
return join31(getOmcRoot(repoRoot), "team", sanitizeName(teamName), "worktrees", sanitizeName(workerName));
|
|
15983
16099
|
}
|
|
15984
16100
|
function getBranchName(teamName, workerName) {
|
|
15985
16101
|
return `omc-team/${sanitizeName(teamName)}/${sanitizeName(workerName)}`;
|
|
@@ -16076,20 +16192,20 @@ function isWorktreeDirtyExcept(wtPath, ignoredRootPaths = []) {
|
|
|
16076
16192
|
}
|
|
16077
16193
|
}
|
|
16078
16194
|
function getMetadataPath(repoRoot, teamName) {
|
|
16079
|
-
return
|
|
16195
|
+
return join31(getOmcRoot(repoRoot), "state", "team", sanitizeName(teamName), "worktrees.json");
|
|
16080
16196
|
}
|
|
16081
16197
|
function getLegacyMetadataPath(repoRoot, teamName) {
|
|
16082
|
-
return
|
|
16198
|
+
return join31(getOmcRoot(repoRoot), "state", "team-bridge", sanitizeName(teamName), "worktrees.json");
|
|
16083
16199
|
}
|
|
16084
16200
|
function getWorkerStateDir(repoRoot, teamName, workerName) {
|
|
16085
|
-
return
|
|
16201
|
+
return join31(getOmcRoot(repoRoot), "state", "team", sanitizeName(teamName), "workers", sanitizeName(workerName));
|
|
16086
16202
|
}
|
|
16087
16203
|
function getRootAgentsBackupPath(repoRoot, teamName, workerName) {
|
|
16088
|
-
return
|
|
16204
|
+
return join31(getWorkerStateDir(repoRoot, teamName, workerName), "worktree-root-agents.json");
|
|
16089
16205
|
}
|
|
16090
16206
|
function readRootAgentsBackup(repoRoot, teamName, workerName) {
|
|
16091
16207
|
const backupPath = getRootAgentsBackupPath(repoRoot, teamName, workerName);
|
|
16092
|
-
if (!
|
|
16208
|
+
if (!existsSync27(backupPath)) return null;
|
|
16093
16209
|
try {
|
|
16094
16210
|
return JSON.parse(readFileSync18(backupPath, "utf-8"));
|
|
16095
16211
|
} catch (err) {
|
|
@@ -16104,13 +16220,13 @@ function readRootAgentsBackup(repoRoot, teamName, workerName) {
|
|
|
16104
16220
|
function installWorktreeRootAgents(teamName, workerName, repoRoot, worktreePath, overlayContent) {
|
|
16105
16221
|
const omcRoot = getOmcRoot(repoRoot);
|
|
16106
16222
|
validateResolvedPath(worktreePath, omcRoot);
|
|
16107
|
-
const agentsPath =
|
|
16223
|
+
const agentsPath = join31(worktreePath, "AGENTS.md");
|
|
16108
16224
|
validateResolvedPath(agentsPath, worktreePath);
|
|
16109
16225
|
const backupPath = getRootAgentsBackupPath(repoRoot, teamName, workerName);
|
|
16110
16226
|
validateResolvedPath(backupPath, omcRoot);
|
|
16111
16227
|
ensureDirWithMode(getWorkerStateDir(repoRoot, teamName, workerName));
|
|
16112
16228
|
const previous = readRootAgentsBackup(repoRoot, teamName, workerName);
|
|
16113
|
-
const currentContent =
|
|
16229
|
+
const currentContent = existsSync27(agentsPath) ? readFileSync18(agentsPath, "utf-8") : void 0;
|
|
16114
16230
|
if (previous && currentContent !== void 0 && currentContent !== previous.installedContent) {
|
|
16115
16231
|
const error = new Error(`agents_dirty: preserving modified worktree root AGENTS.md at ${agentsPath}`);
|
|
16116
16232
|
error.code = "agents_dirty";
|
|
@@ -16134,23 +16250,23 @@ function restoreWorktreeRootAgents(teamName, workerName, repoRoot, worktreePath)
|
|
|
16134
16250
|
if (!backup) return { restored: false, reason: "no_backup" };
|
|
16135
16251
|
const resolvedWorktreePath = worktreePath ?? backup.worktreePath;
|
|
16136
16252
|
validateResolvedPath(resolvedWorktreePath, omcRoot);
|
|
16137
|
-
if (!
|
|
16253
|
+
if (!existsSync27(resolvedWorktreePath)) {
|
|
16138
16254
|
try {
|
|
16139
16255
|
unlinkSync9(backupPath);
|
|
16140
16256
|
} catch {
|
|
16141
16257
|
}
|
|
16142
16258
|
return { restored: false, reason: "worktree_missing" };
|
|
16143
16259
|
}
|
|
16144
|
-
const agentsPath =
|
|
16260
|
+
const agentsPath = join31(resolvedWorktreePath, "AGENTS.md");
|
|
16145
16261
|
validateResolvedPath(agentsPath, resolvedWorktreePath);
|
|
16146
|
-
const currentContent =
|
|
16262
|
+
const currentContent = existsSync27(agentsPath) ? readFileSync18(agentsPath, "utf-8") : void 0;
|
|
16147
16263
|
const isPartialInstallOriginal = backup.hadOriginal && currentContent === (backup.originalContent ?? "");
|
|
16148
16264
|
if (currentContent !== void 0 && currentContent !== backup.installedContent && !isPartialInstallOriginal) {
|
|
16149
16265
|
return { restored: false, reason: "agents_dirty" };
|
|
16150
16266
|
}
|
|
16151
16267
|
if (backup.hadOriginal) {
|
|
16152
16268
|
writeFileSync6(agentsPath, backup.originalContent ?? "", "utf-8");
|
|
16153
|
-
} else if (
|
|
16269
|
+
} else if (existsSync27(agentsPath)) {
|
|
16154
16270
|
unlinkSync9(agentsPath);
|
|
16155
16271
|
}
|
|
16156
16272
|
try {
|
|
@@ -16164,7 +16280,7 @@ function readMetadataResult(repoRoot, teamName) {
|
|
|
16164
16280
|
const byWorker = /* @__PURE__ */ new Map();
|
|
16165
16281
|
const issues = [];
|
|
16166
16282
|
for (const metaPath of paths) {
|
|
16167
|
-
if (!
|
|
16283
|
+
if (!existsSync27(metaPath)) continue;
|
|
16168
16284
|
try {
|
|
16169
16285
|
const entries = JSON.parse(readFileSync18(metaPath, "utf-8"));
|
|
16170
16286
|
for (const entry of entries) byWorker.set(entry.workerName, entry);
|
|
@@ -16181,13 +16297,13 @@ function readMetadata(repoRoot, teamName) {
|
|
|
16181
16297
|
return readMetadataResult(repoRoot, teamName).entries;
|
|
16182
16298
|
}
|
|
16183
16299
|
function listRootAgentsBackupIssues(repoRoot, teamName, entries) {
|
|
16184
|
-
const workersDir =
|
|
16185
|
-
if (!
|
|
16300
|
+
const workersDir = join31(getOmcRoot(repoRoot), "state", "team", sanitizeName(teamName), "workers");
|
|
16301
|
+
if (!existsSync27(workersDir)) return [];
|
|
16186
16302
|
const knownWorkers = new Set(entries.map((entry) => sanitizeName(entry.workerName)));
|
|
16187
16303
|
const issues = [];
|
|
16188
|
-
for (const workerName of
|
|
16189
|
-
const backupPath =
|
|
16190
|
-
if (!
|
|
16304
|
+
for (const workerName of readdirSync11(workersDir)) {
|
|
16305
|
+
const backupPath = join31(workersDir, workerName, "worktree-root-agents.json");
|
|
16306
|
+
if (!existsSync27(backupPath)) continue;
|
|
16191
16307
|
try {
|
|
16192
16308
|
JSON.parse(readFileSync18(backupPath, "utf-8"));
|
|
16193
16309
|
} catch (error) {
|
|
@@ -16206,8 +16322,8 @@ function listRootAgentsBackupIssues(repoRoot, teamName, entries) {
|
|
|
16206
16322
|
}
|
|
16207
16323
|
function writeMetadata(repoRoot, teamName, entries) {
|
|
16208
16324
|
const metaPath = getMetadataPath(repoRoot, teamName);
|
|
16209
|
-
validateResolvedPath(metaPath,
|
|
16210
|
-
ensureDirWithMode(
|
|
16325
|
+
validateResolvedPath(metaPath, join31(getOmcRoot(repoRoot), "state", "team"));
|
|
16326
|
+
ensureDirWithMode(join31(getOmcRoot(repoRoot), "state", "team", sanitizeName(teamName)));
|
|
16211
16327
|
atomicWriteJson(metaPath, entries);
|
|
16212
16328
|
}
|
|
16213
16329
|
function recordMetadata(repoRoot, teamName, info) {
|
|
@@ -16262,12 +16378,12 @@ function ensureWorkerWorktree(teamName, workerName, repoRoot, options = {}) {
|
|
|
16262
16378
|
}
|
|
16263
16379
|
const wtPath = getWorktreePath(repoRoot, teamName, workerName);
|
|
16264
16380
|
const branch = mode === "named" ? getBranchName(teamName, workerName) : "HEAD";
|
|
16265
|
-
validateResolvedPath(wtPath,
|
|
16381
|
+
validateResolvedPath(wtPath, join31(getOmcRoot(repoRoot), "team"));
|
|
16266
16382
|
try {
|
|
16267
16383
|
execFileSync5("git", ["worktree", "prune"], { cwd: repoRoot, stdio: "pipe", windowsHide: true });
|
|
16268
16384
|
} catch {
|
|
16269
16385
|
}
|
|
16270
|
-
if (
|
|
16386
|
+
if (existsSync27(wtPath)) {
|
|
16271
16387
|
assertCompatibleExistingWorktree(repoRoot, wtPath, branch, mode);
|
|
16272
16388
|
const info2 = {
|
|
16273
16389
|
path: wtPath,
|
|
@@ -16284,7 +16400,7 @@ function ensureWorkerWorktree(teamName, workerName, repoRoot, options = {}) {
|
|
|
16284
16400
|
recordMetadata(repoRoot, teamName, info2);
|
|
16285
16401
|
return info2;
|
|
16286
16402
|
}
|
|
16287
|
-
const wtDir =
|
|
16403
|
+
const wtDir = join31(getOmcRoot(repoRoot), "team", sanitizeName(teamName), "worktrees");
|
|
16288
16404
|
ensureDirWithMode(wtDir);
|
|
16289
16405
|
const args = mode === "named" ? ["worktree", "add", "-b", branch, wtPath, options.baseRef ?? "HEAD"] : ["worktree", "add", "--detach", wtPath, options.baseRef ?? "HEAD"];
|
|
16290
16406
|
execFileSync5("git", args, { cwd: repoRoot, stdio: "pipe", windowsHide: true });
|
|
@@ -16306,17 +16422,17 @@ function ensureWorkerWorktree(teamName, workerName, repoRoot, options = {}) {
|
|
|
16306
16422
|
function checkWorkerWorktreeRemovalSafety(teamName, workerName, repoRoot, worktreePath) {
|
|
16307
16423
|
const wtPath = worktreePath ?? getWorktreePath(repoRoot, teamName, workerName);
|
|
16308
16424
|
const backup = readRootAgentsBackup(repoRoot, teamName, workerName);
|
|
16309
|
-
if (!
|
|
16425
|
+
if (!existsSync27(wtPath)) return;
|
|
16310
16426
|
validateWorktreeRemovalTarget({
|
|
16311
16427
|
candidatePath: wtPath,
|
|
16312
|
-
expectedRoots: [
|
|
16428
|
+
expectedRoots: [join31(getOmcRoot(repoRoot), "team", sanitizeName(teamName), "worktrees")],
|
|
16313
16429
|
mainRepoRoots: [repoRoot]
|
|
16314
16430
|
});
|
|
16315
16431
|
let ignoreRootAgents = false;
|
|
16316
16432
|
if (backup) {
|
|
16317
|
-
const agentsPath =
|
|
16433
|
+
const agentsPath = join31(wtPath, "AGENTS.md");
|
|
16318
16434
|
validateResolvedPath(agentsPath, wtPath);
|
|
16319
|
-
const currentContent =
|
|
16435
|
+
const currentContent = existsSync27(agentsPath) ? readFileSync18(agentsPath, "utf-8") : void 0;
|
|
16320
16436
|
const isPartialInstallOriginal = backup.hadOriginal && currentContent === (backup.originalContent ?? "");
|
|
16321
16437
|
if (currentContent !== void 0 && currentContent !== backup.installedContent && !isPartialInstallOriginal) {
|
|
16322
16438
|
const error = new Error(`agents_dirty: preserving modified worktree root AGENTS.md at ${agentsPath}`);
|
|
@@ -16337,7 +16453,7 @@ function prepareWorkerWorktreeForRemoval(teamName, workerName, repoRoot, worktre
|
|
|
16337
16453
|
checkWorkerWorktreeRemovalSafety(teamName, workerName, repoRoot, wtPath);
|
|
16338
16454
|
const agentsRestore = restoreWorktreeRootAgents(teamName, workerName, repoRoot, wtPath);
|
|
16339
16455
|
if (agentsRestore.reason === "agents_dirty") {
|
|
16340
|
-
const error = new Error(`agents_dirty: preserving modified worktree root AGENTS.md at ${
|
|
16456
|
+
const error = new Error(`agents_dirty: preserving modified worktree root AGENTS.md at ${join31(wtPath, "AGENTS.md")}`);
|
|
16341
16457
|
error.code = "agents_dirty";
|
|
16342
16458
|
throw error;
|
|
16343
16459
|
}
|
|
@@ -16367,10 +16483,10 @@ function removeWorkerWorktree(teamName, workerName, repoRoot) {
|
|
|
16367
16483
|
execFileSync5("git", ["branch", "-D", branch], { cwd: repoRoot, stdio: "pipe", windowsHide: true });
|
|
16368
16484
|
} catch {
|
|
16369
16485
|
}
|
|
16370
|
-
if (
|
|
16486
|
+
if (existsSync27(wtPath) && !isRegisteredWorktreePath(repoRoot, wtPath)) {
|
|
16371
16487
|
validateWorktreeRemovalTarget({
|
|
16372
16488
|
candidatePath: wtPath,
|
|
16373
|
-
expectedRoots: [
|
|
16489
|
+
expectedRoots: [join31(getOmcRoot(repoRoot), "team", sanitizeName(teamName), "worktrees")],
|
|
16374
16490
|
mainRepoRoots: [repoRoot]
|
|
16375
16491
|
});
|
|
16376
16492
|
rmSync2(wtPath, { recursive: true, force: true });
|
|
@@ -16495,7 +16611,8 @@ function resolveRoleAssignment(role, cfg) {
|
|
|
16495
16611
|
const provider = isOrchestrator ? getHostCliType() : spec?.provider ?? getHostCliType();
|
|
16496
16612
|
const model = provider === "claude" || provider === "copilot" ? resolveClaudeModel(canonical, spec?.model, cfg) : resolveExternalModel(provider, spec?.model, cfg);
|
|
16497
16613
|
const agent = spec?.agent ?? ROLE_TO_AGENT[canonical];
|
|
16498
|
-
|
|
16614
|
+
const reasoningEffort = spec?.reasoningEffort;
|
|
16615
|
+
return { provider, model, agent, reasoningEffort };
|
|
16499
16616
|
}
|
|
16500
16617
|
function isCanonicalRole(value) {
|
|
16501
16618
|
return CANONICAL_TEAM_ROLES.includes(value);
|
|
@@ -16511,7 +16628,8 @@ function buildResolvedRoutingSnapshot(cfg) {
|
|
|
16511
16628
|
const fallback = {
|
|
16512
16629
|
provider: getHostCliType(),
|
|
16513
16630
|
model: resolveClaudeModel(role, fallbackModelInput, cfg),
|
|
16514
|
-
agent: primary.agent
|
|
16631
|
+
agent: primary.agent,
|
|
16632
|
+
reasoningEffort: spec?.reasoningEffort
|
|
16515
16633
|
};
|
|
16516
16634
|
out[role] = { primary, fallback };
|
|
16517
16635
|
}
|
|
@@ -16918,7 +17036,7 @@ var init_runtime_flags = __esm({
|
|
|
16918
17036
|
// src/team/merge-coordinator.ts
|
|
16919
17037
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
16920
17038
|
import { appendFileSync, mkdirSync as mkdirSync7, readFileSync as readFileSync19 } from "node:fs";
|
|
16921
|
-
import { isAbsolute as isAbsolute9, join as
|
|
17039
|
+
import { isAbsolute as isAbsolute9, join as join32 } from "node:path";
|
|
16922
17040
|
function validateBranchName(branch) {
|
|
16923
17041
|
if (!BRANCH_NAME_RE.test(branch)) {
|
|
16924
17042
|
throw new Error(`Invalid branch name: "${branch}" \u2014 must match ${BRANCH_NAME_RE}`);
|
|
@@ -16936,10 +17054,10 @@ function configureHarnessMergeAttributes(repoRoot) {
|
|
|
16936
17054
|
stdio: "pipe",
|
|
16937
17055
|
windowsHide: true
|
|
16938
17056
|
}).trim();
|
|
16939
|
-
const resolvedCommonDir = isAbsolute9(commonDir) ? commonDir :
|
|
16940
|
-
const infoDir =
|
|
17057
|
+
const resolvedCommonDir = isAbsolute9(commonDir) ? commonDir : join32(repoRoot, commonDir);
|
|
17058
|
+
const infoDir = join32(resolvedCommonDir, "info");
|
|
16941
17059
|
mkdirSync7(infoDir, { recursive: true });
|
|
16942
|
-
const attrPath =
|
|
17060
|
+
const attrPath = join32(infoDir, "attributes");
|
|
16943
17061
|
let existing = "";
|
|
16944
17062
|
try {
|
|
16945
17063
|
existing = readFileSync19(attrPath, "utf-8");
|
|
@@ -17063,17 +17181,17 @@ var init_merge_coordinator = __esm({
|
|
|
17063
17181
|
|
|
17064
17182
|
// src/team/leader-inbox.ts
|
|
17065
17183
|
import { appendFile as appendFile4, mkdir as mkdir11, writeFile as writeFile8 } from "fs/promises";
|
|
17066
|
-
import { existsSync as
|
|
17067
|
-
import { dirname as dirname26, join as
|
|
17184
|
+
import { existsSync as existsSync28 } from "fs";
|
|
17185
|
+
import { dirname as dirname26, join as join33 } from "path";
|
|
17068
17186
|
function leaderInboxPath(teamName, cwd) {
|
|
17069
17187
|
const safe = sanitizeName(teamName);
|
|
17070
|
-
return
|
|
17188
|
+
return join33(teamStateRoot(cwd, safe), "leader", "inbox.md");
|
|
17071
17189
|
}
|
|
17072
17190
|
async function ensureLeaderInbox(teamName, cwd) {
|
|
17073
17191
|
const inboxPath = leaderInboxPath(teamName, cwd);
|
|
17074
17192
|
validateResolvedPath(inboxPath, teamStateRoot(cwd, sanitizeName(teamName)));
|
|
17075
17193
|
await mkdir11(dirname26(inboxPath), { recursive: true });
|
|
17076
|
-
if (!
|
|
17194
|
+
if (!existsSync28(inboxPath)) {
|
|
17077
17195
|
await writeFile8(inboxPath, LEADER_INBOX_HEADER, "utf-8");
|
|
17078
17196
|
}
|
|
17079
17197
|
return inboxPath;
|
|
@@ -17089,7 +17207,7 @@ ${message}`, "utf-8");
|
|
|
17089
17207
|
}
|
|
17090
17208
|
function extendLeaderBootstrapPrompt(teamName, cwd) {
|
|
17091
17209
|
const safe = sanitizeName(teamName);
|
|
17092
|
-
const path5 = cwd ?
|
|
17210
|
+
const path5 = cwd ? join33(teamStateRoot(cwd, safe), "leader", "inbox.md") : `.omg/state/team/${safe}/leader/inbox.md`;
|
|
17093
17211
|
return `Runtime notifications appear at ${path5} \u2014 check this file periodically and after long-running operations.`;
|
|
17094
17212
|
}
|
|
17095
17213
|
var LEADER_INBOX_HEADER;
|
|
@@ -17169,9 +17287,9 @@ var init_conflict_mailbox = __esm({
|
|
|
17169
17287
|
});
|
|
17170
17288
|
|
|
17171
17289
|
// src/team/worker-commit-cadence.ts
|
|
17172
|
-
import { existsSync as
|
|
17290
|
+
import { existsSync as existsSync29, watch as fsWatch } from "fs";
|
|
17173
17291
|
import { readFile as readFile13, writeFile as writeFile9, mkdir as mkdir12, unlink as unlink6 } from "fs/promises";
|
|
17174
|
-
import { join as
|
|
17292
|
+
import { join as join34, dirname as dirname27 } from "path";
|
|
17175
17293
|
import { exec } from "child_process";
|
|
17176
17294
|
function ownsCadence(ctx) {
|
|
17177
17295
|
const current = cadenceOwners.get(ctx.worktreePath);
|
|
@@ -17229,27 +17347,27 @@ async function installPostToolUseHook(worktreePath, workerName) {
|
|
|
17229
17347
|
if (isHookPaused(worktreePath)) {
|
|
17230
17348
|
return;
|
|
17231
17349
|
}
|
|
17232
|
-
const claudeDir =
|
|
17350
|
+
const claudeDir = join34(worktreePath, ".copilot");
|
|
17233
17351
|
await mkdir12(claudeDir, { recursive: true });
|
|
17234
|
-
const settingsPath =
|
|
17352
|
+
const settingsPath = join34(claudeDir, "settings.json");
|
|
17235
17353
|
const hookCommand = buildHookCommand(workerName);
|
|
17236
17354
|
const merged = await mergeSettingsWithHook(settingsPath, hookCommand);
|
|
17237
17355
|
await writeFile9(settingsPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
17238
17356
|
}
|
|
17239
17357
|
async function pauseHookViaSentinel(worktreePath) {
|
|
17240
|
-
const sentinelPath =
|
|
17358
|
+
const sentinelPath = join34(worktreePath, SENTINEL_FILENAME);
|
|
17241
17359
|
await mkdir12(dirname27(sentinelPath), { recursive: true });
|
|
17242
17360
|
await writeFile9(sentinelPath, "", "utf-8");
|
|
17243
17361
|
}
|
|
17244
17362
|
async function resumeHookViaSentinel(worktreePath) {
|
|
17245
|
-
const sentinelPath =
|
|
17363
|
+
const sentinelPath = join34(worktreePath, SENTINEL_FILENAME);
|
|
17246
17364
|
try {
|
|
17247
17365
|
await unlink6(sentinelPath);
|
|
17248
17366
|
} catch {
|
|
17249
17367
|
}
|
|
17250
17368
|
}
|
|
17251
17369
|
function isHookPaused(worktreePath) {
|
|
17252
|
-
return
|
|
17370
|
+
return existsSync29(join34(worktreePath, SENTINEL_FILENAME));
|
|
17253
17371
|
}
|
|
17254
17372
|
function startFallbackPoller(worktreePath, workerName, opts) {
|
|
17255
17373
|
assertSafeWorkerName(workerName);
|
|
@@ -17308,7 +17426,7 @@ async function uninstallCommitCadence(ctx, io = { readFile: readFile13, writeFil
|
|
|
17308
17426
|
if (ownsRegisteredGeneration) cadenceOwners.delete(ctx.worktreePath);
|
|
17309
17427
|
return;
|
|
17310
17428
|
}
|
|
17311
|
-
const settingsPath =
|
|
17429
|
+
const settingsPath = join34(ctx.worktreePath, ".copilot", "settings.json");
|
|
17312
17430
|
let raw;
|
|
17313
17431
|
try {
|
|
17314
17432
|
raw = await io.readFile(settingsPath, "utf-8");
|
|
@@ -17347,14 +17465,14 @@ var init_worker_commit_cadence = __esm({
|
|
|
17347
17465
|
|
|
17348
17466
|
// src/team/merge-orchestrator.ts
|
|
17349
17467
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
17350
|
-
import { existsSync as
|
|
17468
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
17351
17469
|
import { mkdir as mkdir13, appendFile as appendFile5 } from "node:fs/promises";
|
|
17352
|
-
import { dirname as dirname28, join as
|
|
17470
|
+
import { dirname as dirname28, join as join35 } from "node:path";
|
|
17353
17471
|
function mergerWorktreePathFor(repoRoot, teamName) {
|
|
17354
|
-
return
|
|
17472
|
+
return join35(getOmcRoot(repoRoot), "team", sanitizeName(teamName), "merger");
|
|
17355
17473
|
}
|
|
17356
17474
|
function persistedStatePath(repoRoot, teamName) {
|
|
17357
|
-
return
|
|
17475
|
+
return join35(
|
|
17358
17476
|
getOmcRoot(repoRoot),
|
|
17359
17477
|
"state",
|
|
17360
17478
|
"team",
|
|
@@ -17363,7 +17481,7 @@ function persistedStatePath(repoRoot, teamName) {
|
|
|
17363
17481
|
);
|
|
17364
17482
|
}
|
|
17365
17483
|
function teardownAuditPath(repoRoot, teamName) {
|
|
17366
|
-
return
|
|
17484
|
+
return join35(
|
|
17367
17485
|
getOmcRoot(repoRoot),
|
|
17368
17486
|
"state",
|
|
17369
17487
|
"team",
|
|
@@ -17372,7 +17490,7 @@ function teardownAuditPath(repoRoot, teamName) {
|
|
|
17372
17490
|
);
|
|
17373
17491
|
}
|
|
17374
17492
|
function orchestratorEventLogPath(repoRoot, teamName) {
|
|
17375
|
-
return
|
|
17493
|
+
return join35(
|
|
17376
17494
|
getOmcRoot(repoRoot),
|
|
17377
17495
|
"state",
|
|
17378
17496
|
"team",
|
|
@@ -17429,10 +17547,10 @@ function gitPath(worktreePath, gitPathName) {
|
|
|
17429
17547
|
if (resolved) return resolved;
|
|
17430
17548
|
} catch {
|
|
17431
17549
|
}
|
|
17432
|
-
return
|
|
17550
|
+
return join35(worktreePath, ".git", gitPathName);
|
|
17433
17551
|
}
|
|
17434
17552
|
function isRebaseInProgress(worktreePath) {
|
|
17435
|
-
return
|
|
17553
|
+
return existsSync30(gitPath(worktreePath, "rebase-merge"));
|
|
17436
17554
|
}
|
|
17437
17555
|
function isWorktreeRegistered(repoRoot, wtPath) {
|
|
17438
17556
|
try {
|
|
@@ -17453,7 +17571,7 @@ function isWorktreeRegistered(repoRoot, wtPath) {
|
|
|
17453
17571
|
}
|
|
17454
17572
|
function ensureMergerWorktree(repoRoot, mergerPath, leaderBranch) {
|
|
17455
17573
|
ensureDirWithMode(dirname28(mergerPath));
|
|
17456
|
-
if (
|
|
17574
|
+
if (existsSync30(mergerPath) && isWorktreeRegistered(repoRoot, mergerPath)) {
|
|
17457
17575
|
return;
|
|
17458
17576
|
}
|
|
17459
17577
|
execFileSync7("git", ["worktree", "add", "--force", mergerPath, leaderBranch], {
|
|
@@ -17495,13 +17613,13 @@ async function startMergeOrchestrator(config) {
|
|
|
17495
17613
|
const pollIntervalMs = config.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
|
|
17496
17614
|
const drainTimeoutMs = config.drainTimeoutMs ?? DEFAULT_DRAIN_TIMEOUT_MS;
|
|
17497
17615
|
const mergerPath = mergerWorktreePathFor(config.repoRoot, config.teamName);
|
|
17498
|
-
validateResolvedPath(mergerPath,
|
|
17616
|
+
validateResolvedPath(mergerPath, join35(getOmcRoot(config.repoRoot), "team"));
|
|
17499
17617
|
ensureMergerWorktree(config.repoRoot, mergerPath, config.leaderBranch);
|
|
17500
17618
|
await ensureLeaderInbox(config.teamName, config.cwd);
|
|
17501
17619
|
configureHarnessMergeAttributes(config.repoRoot);
|
|
17502
17620
|
const persistedPath = persistedStatePath(config.repoRoot, config.teamName);
|
|
17503
17621
|
let persisted = { lastShas: {} };
|
|
17504
|
-
if (
|
|
17622
|
+
if (existsSync30(persistedPath)) {
|
|
17505
17623
|
try {
|
|
17506
17624
|
const { readFileSync: readFileSync23 } = await import("node:fs");
|
|
17507
17625
|
persisted = JSON.parse(readFileSync23(persistedPath, "utf-8"));
|
|
@@ -17947,7 +18065,7 @@ ${unmerged.map((u) => `- ${u.workerName}: ${u.reason}`).join("\n")}`;
|
|
|
17947
18065
|
async function recoverFromRestart(config) {
|
|
17948
18066
|
const persistedPath = persistedStatePath(config.repoRoot, config.teamName);
|
|
17949
18067
|
let persistedShasLoaded = 0;
|
|
17950
|
-
if (
|
|
18068
|
+
if (existsSync30(persistedPath)) {
|
|
17951
18069
|
try {
|
|
17952
18070
|
const { readFileSync: readFileSync23 } = await import("node:fs");
|
|
17953
18071
|
const persisted = JSON.parse(readFileSync23(persistedPath, "utf-8"));
|
|
@@ -18014,7 +18132,7 @@ var init_merge_orchestrator = __esm({
|
|
|
18014
18132
|
});
|
|
18015
18133
|
|
|
18016
18134
|
// src/team/scaling.ts
|
|
18017
|
-
import { join as
|
|
18135
|
+
import { join as join36, resolve as resolve11 } from "path";
|
|
18018
18136
|
import { mkdir as mkdir14, readFile as readFile14, rm as rm8 } from "fs/promises";
|
|
18019
18137
|
function scaleUpFenceBlocks(config) {
|
|
18020
18138
|
const attempt = config.active_scale_up;
|
|
@@ -18167,6 +18285,8 @@ var runtime_v2_exports = {};
|
|
|
18167
18285
|
__export(runtime_v2_exports, {
|
|
18168
18286
|
CircuitBreakerV2: () => CircuitBreakerV2,
|
|
18169
18287
|
claimErrorLineFromPane: () => claimErrorLineFromPane,
|
|
18288
|
+
cleanupAbandonedTeamState: () => cleanupAbandonedTeamState,
|
|
18289
|
+
cleanupStaleReservations: () => cleanupStaleReservations,
|
|
18170
18290
|
executeRecoverDeadWorkerV2Owner: () => executeRecoverDeadWorkerV2Owner,
|
|
18171
18291
|
finalizeRecoveryOwnerResult: () => finalizeRecoveryOwnerResult,
|
|
18172
18292
|
findActiveTeamsV2: () => findActiveTeamsV2,
|
|
@@ -18194,8 +18314,8 @@ __export(runtime_v2_exports, {
|
|
|
18194
18314
|
waitForStartupEvidenceBudget: () => waitForStartupEvidenceBudget,
|
|
18195
18315
|
writeWatchdogFailedMarker: () => writeWatchdogFailedMarker
|
|
18196
18316
|
});
|
|
18197
|
-
import { join as
|
|
18198
|
-
import { existsSync as
|
|
18317
|
+
import { join as join37, resolve as resolve12 } from "path";
|
|
18318
|
+
import { existsSync as existsSync31 } from "fs";
|
|
18199
18319
|
import { link as link4, lstat as lstat6, mkdir as mkdir16, open as open5, readdir as readdir6, readFile as readFile16, rm as rm9, unlink as unlink7, writeFile as writeFile11 } from "fs/promises";
|
|
18200
18320
|
import { performance } from "perf_hooks";
|
|
18201
18321
|
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
@@ -18243,7 +18363,7 @@ async function recoverDeadWorkerV2(teamName, cwd, { workerName, requestId = rand
|
|
|
18243
18363
|
try {
|
|
18244
18364
|
const requestReservationPath = absPath(cwd, TeamPaths.recoveryRequestPending(requestId));
|
|
18245
18365
|
const existing = readRecoveryRequestReservation(cwd, requestId);
|
|
18246
|
-
if (!existing &&
|
|
18366
|
+
if (!existing && existsSync31(requestReservationPath)) {
|
|
18247
18367
|
throw new Error("invalid_persisted_state");
|
|
18248
18368
|
}
|
|
18249
18369
|
if (existing) {
|
|
@@ -18521,26 +18641,27 @@ function resolveTaskAssignment(task, resolvedRouting, roleRoutingConfig, fallbac
|
|
|
18521
18641
|
const normalized = normalizeDelegationRole(rawRole);
|
|
18522
18642
|
const canonical = canonicalRoles.has(normalized) ? normalized : null;
|
|
18523
18643
|
if (!canonical) {
|
|
18524
|
-
return { agentType: fallbackAgent, model: "", role: null };
|
|
18644
|
+
return { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: null };
|
|
18525
18645
|
}
|
|
18526
18646
|
const hasConfigForRole = !!getRoleRoutingSpec(
|
|
18527
18647
|
roleRoutingConfig,
|
|
18528
18648
|
canonical
|
|
18529
18649
|
);
|
|
18530
18650
|
if (!hasExplicitRole && !hasConfigForRole) {
|
|
18531
|
-
return { agentType: fallbackAgent, model: "", role: canonical };
|
|
18651
|
+
return { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: canonical };
|
|
18532
18652
|
}
|
|
18533
18653
|
if (hasExplicitRole && !hasConfigForRole && fallbackAgent !== getHostCliType()) {
|
|
18534
|
-
return { agentType: fallbackAgent, model: "", role: canonical };
|
|
18654
|
+
return { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: canonical };
|
|
18535
18655
|
}
|
|
18536
18656
|
const pair = resolvedRouting[canonical];
|
|
18537
18657
|
if (!pair) {
|
|
18538
|
-
return { agentType: fallbackAgent, model: "", role: canonical };
|
|
18658
|
+
return { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: canonical };
|
|
18539
18659
|
}
|
|
18540
18660
|
const chosen = pair.primary;
|
|
18541
18661
|
return {
|
|
18542
18662
|
agentType: chosen.provider,
|
|
18543
18663
|
model: chosen.model,
|
|
18664
|
+
reasoningEffort: chosen.reasoningEffort,
|
|
18544
18665
|
role: canonical
|
|
18545
18666
|
};
|
|
18546
18667
|
}
|
|
@@ -18990,7 +19111,7 @@ async function spawnV2Worker(opts) {
|
|
|
18990
19111
|
);
|
|
18991
19112
|
}
|
|
18992
19113
|
const envVars = {
|
|
18993
|
-
...getWorkerEnv(opts.teamName, opts.workerName, opts.agentType),
|
|
19114
|
+
...getWorkerEnv(opts.teamName, opts.workerName, opts.agentType, process.env, opts.role),
|
|
18994
19115
|
OMC_TEAM_STATE_ROOT: teamStateRoot(opts.cwd, opts.teamName),
|
|
18995
19116
|
OMC_TEAM_LEADER_CWD: opts.cwd,
|
|
18996
19117
|
...opts.worktreePath ? { OMC_TEAM_WORKTREE_PATH: opts.worktreePath } : {},
|
|
@@ -19167,7 +19288,7 @@ async function recordRecoveryPaneRollbackFailure(input, recoveryId, pending, rea
|
|
|
19167
19288
|
const recordedAt = Date.now();
|
|
19168
19289
|
const path5 = absPath(input.cwd, TeamPaths.recoveryPaneRollbackFailure(input.teamName, recoveryId, pending.paneAttemptId, recordedAt));
|
|
19169
19290
|
const candidate = `${path5}.candidate.${process.pid}.${randomUUID16()}`;
|
|
19170
|
-
await mkdir16(
|
|
19291
|
+
await mkdir16(join37(path5, ".."), { recursive: true });
|
|
19171
19292
|
const handle = await open5(candidate, "wx", 384);
|
|
19172
19293
|
try {
|
|
19173
19294
|
await handle.writeFile(JSON.stringify({
|
|
@@ -19197,7 +19318,7 @@ async function recordUnaddressableRecoveryPaneFailure(input, recoveryId, paneAtt
|
|
|
19197
19318
|
const recordedAt = Date.now();
|
|
19198
19319
|
const path5 = absPath(input.cwd, TeamPaths.recoveryPaneRollbackFailure(input.teamName, recoveryId, paneAttemptId, recordedAt));
|
|
19199
19320
|
const candidate = `${path5}.candidate.${process.pid}.${randomUUID16()}`;
|
|
19200
|
-
await mkdir16(
|
|
19321
|
+
await mkdir16(join37(path5, ".."), { recursive: true });
|
|
19201
19322
|
const handle = await open5(candidate, "wx", 384);
|
|
19202
19323
|
const boundedSplit = split ? {
|
|
19203
19324
|
...split,
|
|
@@ -19523,7 +19644,7 @@ async function readOrCreateRecoveryAttempt(input, recoveryId, replacementGenerat
|
|
|
19523
19644
|
adoption_token: randomUUID16(),
|
|
19524
19645
|
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
19525
19646
|
};
|
|
19526
|
-
await mkdir16(
|
|
19647
|
+
await mkdir16(join37(path5, ".."), { recursive: true });
|
|
19527
19648
|
const candidate = `${path5}.candidate.${process.pid}.${randomUUID16()}`;
|
|
19528
19649
|
const candidateHandle = await open5(candidate, "wx", 384);
|
|
19529
19650
|
try {
|
|
@@ -20527,7 +20648,7 @@ async function executeRecoverDeadWorkerV2Owner(input) {
|
|
|
20527
20648
|
launch_nonce: pending.startupContext.attempt.nonce,
|
|
20528
20649
|
written_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
20529
20650
|
};
|
|
20530
|
-
await mkdir16(
|
|
20651
|
+
await mkdir16(join37(pending.gate.activatePath, ".."), { recursive: true });
|
|
20531
20652
|
await writeFile11(pending.gate.activatePath, JSON.stringify(record), "utf8");
|
|
20532
20653
|
const adoptedReady = await waitForRecoveryGateRecord(`${pending.gate.readyPath}.adoption-ready`, record, 3e4);
|
|
20533
20654
|
return adoptedReady && await isWorkerLaunchAttemptCurrent(pending.startupContext.attempt) ? { ok: true } : { ok: false, error: "worker_activation_failed" };
|
|
@@ -20654,7 +20775,7 @@ ${recoveryContract}` : ""}`;
|
|
|
20654
20775
|
let providerLive = false;
|
|
20655
20776
|
try {
|
|
20656
20777
|
const launchedRecord = JSON.parse(await readFile16(launchedPath, "utf8"));
|
|
20657
|
-
providerLive = Number.isInteger(launchedRecord.provider_pid) && typeof launchedRecord.provider_start_identity === "string" && (launchedRecord.supervisor_completion_path === void 0 || typeof launchedRecord.supervisor_completion_path === "string" && launchedRecord.supervisor_completion_path.trim().length > 0 && !
|
|
20778
|
+
providerLive = Number.isInteger(launchedRecord.provider_pid) && typeof launchedRecord.provider_start_identity === "string" && (launchedRecord.supervisor_completion_path === void 0 || typeof launchedRecord.supervisor_completion_path === "string" && launchedRecord.supervisor_completion_path.trim().length > 0 && !existsSync31(launchedRecord.supervisor_completion_path)) && await isProcessIdentityLive(
|
|
20658
20779
|
launchedRecord.provider_pid,
|
|
20659
20780
|
launchedRecord.provider_start_identity,
|
|
20660
20781
|
Date.now() + 1e3
|
|
@@ -20733,7 +20854,7 @@ async function rollbackUnpersistedNativeWorktreeStartup(teamName, cwd, cause, in
|
|
|
20733
20854
|
const recordedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20734
20855
|
const writeFailureMarker = async (extra = {}) => {
|
|
20735
20856
|
await mkdir16(teamRoot, { recursive: true });
|
|
20736
|
-
await writeFile11(
|
|
20857
|
+
await writeFile11(join37(teamRoot, "startup-failure.json"), JSON.stringify({
|
|
20737
20858
|
reason: "startup_failed_before_config_persisted",
|
|
20738
20859
|
error: errorMessage,
|
|
20739
20860
|
recorded_at: recordedAt,
|
|
@@ -20764,7 +20885,7 @@ async function rollbackUnpersistedNativeWorktreeStartup(teamName, cwd, cause, in
|
|
|
20764
20885
|
}
|
|
20765
20886
|
}
|
|
20766
20887
|
await rm9(teamRoot, { recursive: true, force: true });
|
|
20767
|
-
if (
|
|
20888
|
+
if (existsSync31(teamRoot)) {
|
|
20768
20889
|
await writeFailureMarker({ rollback_error: "startup_state_removal_unverified" });
|
|
20769
20890
|
return false;
|
|
20770
20891
|
}
|
|
@@ -20788,7 +20909,7 @@ async function rollbackUnpersistedNativeWorktreeStartup(teamName, cwd, cause, in
|
|
|
20788
20909
|
async function writeStartedStartupRollbackEvidence(args) {
|
|
20789
20910
|
const teamRoot = absPath(args.cwd, TeamPaths.root(args.teamName));
|
|
20790
20911
|
await mkdir16(teamRoot, { recursive: true });
|
|
20791
|
-
await writeFile11(
|
|
20912
|
+
await writeFile11(join37(teamRoot, "startup-failure.json"), JSON.stringify({
|
|
20792
20913
|
reason: args.markerReason ?? "startup_rollback_cleanup_incomplete",
|
|
20793
20914
|
error: args.cause instanceof Error ? args.cause.message : String(args.cause),
|
|
20794
20915
|
rollback_error: args.reason,
|
|
@@ -21038,7 +21159,7 @@ async function startTeamV2(config) {
|
|
|
21038
21159
|
const workerName = workerNames[i];
|
|
21039
21160
|
const taskIndex = startupByWorker.get(workerName);
|
|
21040
21161
|
const fallbackAgent = agentTypes[i % agentTypes.length] ?? agentTypes[0] ?? "claude";
|
|
21041
|
-
const resolvedAssignment = taskIndex === void 0 ? { agentType: fallbackAgent, model: "", role: void 0 } : resolveTaskAssignment(
|
|
21162
|
+
const resolvedAssignment = taskIndex === void 0 ? { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: void 0 } : resolveTaskAssignment(
|
|
21042
21163
|
config.tasks[taskIndex],
|
|
21043
21164
|
resolvedRouting,
|
|
21044
21165
|
pluginCfg.team?.roleRouting,
|
|
@@ -21047,6 +21168,7 @@ async function startTeamV2(config) {
|
|
|
21047
21168
|
const assignment = {
|
|
21048
21169
|
agentType: resolvedAssignment.agentType,
|
|
21049
21170
|
model: resolvedAssignment.model || resolveDefaultModel(resolvedAssignment.agentType),
|
|
21171
|
+
reasoningEffort: resolvedAssignment.reasoningEffort,
|
|
21050
21172
|
...resolvedAssignment.role ? { role: resolvedAssignment.role } : {}
|
|
21051
21173
|
};
|
|
21052
21174
|
startupAssignments.set(workerName, assignment);
|
|
@@ -21064,6 +21186,10 @@ async function startTeamV2(config) {
|
|
|
21064
21186
|
const missing = missingBinaryReasons.map(({ agentType, reason }) => `${agentType}:${reason}`).join(";");
|
|
21065
21187
|
throw new Error(`cli_binary_preflight_failed:${missing}`);
|
|
21066
21188
|
}
|
|
21189
|
+
try {
|
|
21190
|
+
await cleanupStaleReservations(sanitized, leaderCwd);
|
|
21191
|
+
} catch {
|
|
21192
|
+
}
|
|
21067
21193
|
return withTeamInstanceLifecycleLock(leaderCwd, sanitized, async () => {
|
|
21068
21194
|
const reservation = await reserveTeamInstanceUnderLock({
|
|
21069
21195
|
teamName: instance.team_name,
|
|
@@ -21087,7 +21213,7 @@ async function startTeamV2(config) {
|
|
|
21087
21213
|
try {
|
|
21088
21214
|
const pendingConfig = buildTeamInstancePendingConfig(instance);
|
|
21089
21215
|
const pendingConfigPath = absPath(leaderCwd, TeamPaths.config(sanitized));
|
|
21090
|
-
await mkdir16(
|
|
21216
|
+
await mkdir16(join37(pendingConfigPath, ".."), { recursive: true });
|
|
21091
21217
|
await writeFile11(pendingConfigPath, JSON.stringify(pendingConfig, null, 2), "utf-8");
|
|
21092
21218
|
} catch (error) {
|
|
21093
21219
|
if (!await rollbackBeforeConfig(error)) throw startupCleanupIncompleteError(error);
|
|
@@ -21098,7 +21224,7 @@ async function startTeamV2(config) {
|
|
|
21098
21224
|
try {
|
|
21099
21225
|
await mkdir16(absPath(leaderCwd, TeamPaths.tasks(sanitized)), { recursive: true });
|
|
21100
21226
|
await mkdir16(absPath(leaderCwd, TeamPaths.workers(sanitized)), { recursive: true });
|
|
21101
|
-
await mkdir16(
|
|
21227
|
+
await mkdir16(join37(getOmcRoot(leaderCwd), "state", "team", sanitized, "mailbox"), { recursive: true });
|
|
21102
21228
|
for (let i = 0; i < config.tasks.length; i++) {
|
|
21103
21229
|
const taskId = String(i + 1);
|
|
21104
21230
|
const task = config.tasks[i];
|
|
@@ -21158,6 +21284,7 @@ async function startTeamV2(config) {
|
|
|
21158
21284
|
cwd: worktree?.path ?? leaderCwd,
|
|
21159
21285
|
resolvedBinaryPath: binary,
|
|
21160
21286
|
model: assignment.model,
|
|
21287
|
+
reasoningEffort: assignment.reasoningEffort,
|
|
21161
21288
|
...permissionFlags.length > 0 ? { extraFlags: permissionFlags } : {}
|
|
21162
21289
|
}, promptArgs);
|
|
21163
21290
|
preparedLaunches.set(workerName, {
|
|
@@ -21553,7 +21680,7 @@ async function writeWatchdogFailedMarker(teamName, cwd, reason) {
|
|
|
21553
21680
|
writtenBy: "runtime-v2"
|
|
21554
21681
|
};
|
|
21555
21682
|
const root = absPath(cwd, TeamPaths.root(sanitizeTeamName(teamName)));
|
|
21556
|
-
const markerPath =
|
|
21683
|
+
const markerPath = join37(root, "watchdog-failed.json");
|
|
21557
21684
|
await mkdir16(root, { recursive: true });
|
|
21558
21685
|
await writeFile12(markerPath, JSON.stringify(marker, null, 2), "utf-8");
|
|
21559
21686
|
}
|
|
@@ -22382,6 +22509,70 @@ async function monitorTeamV2(teamName, cwd, expectedInstanceId) {
|
|
|
22382
22509
|
}
|
|
22383
22510
|
};
|
|
22384
22511
|
}
|
|
22512
|
+
async function cleanupStaleReservations(teamName, cwd) {
|
|
22513
|
+
const sanitized = sanitizeTeamName(teamName);
|
|
22514
|
+
try {
|
|
22515
|
+
await withTeamInstanceLifecycleLock(cwd, sanitized, async () => {
|
|
22516
|
+
const workspaceHash2 = teamWorkspaceHash(cwd, sanitized);
|
|
22517
|
+
const reservationPath2 = canonicalTeamStatePath(
|
|
22518
|
+
cwd,
|
|
22519
|
+
TeamPaths.teamInstanceReservation(workspaceHash2, sanitized)
|
|
22520
|
+
);
|
|
22521
|
+
if (!existsSync31(reservationPath2)) return;
|
|
22522
|
+
const contentStr = await readFile16(reservationPath2, "utf-8");
|
|
22523
|
+
const reservation = JSON.parse(contentStr);
|
|
22524
|
+
if (!(reservation && typeof reservation === "object" && !Array.isArray(reservation) && "owner" in reservation && typeof reservation.owner === "object")) {
|
|
22525
|
+
return;
|
|
22526
|
+
}
|
|
22527
|
+
const owner = reservation.owner;
|
|
22528
|
+
if (!(owner && typeof owner === "object" && !Array.isArray(owner) && "pid" in owner && "process_started_at" in owner)) {
|
|
22529
|
+
return;
|
|
22530
|
+
}
|
|
22531
|
+
const ownerRecord = owner;
|
|
22532
|
+
if (isProcessIdentityDead(ownerRecord)) {
|
|
22533
|
+
await unlink7(reservationPath2);
|
|
22534
|
+
}
|
|
22535
|
+
}, 5e3);
|
|
22536
|
+
} catch {
|
|
22537
|
+
}
|
|
22538
|
+
}
|
|
22539
|
+
async function cleanupAbandonedTeamState(teamName, cwd) {
|
|
22540
|
+
const sanitized = sanitizeTeamName(teamName);
|
|
22541
|
+
await withTeamInstanceLifecycleLock(cwd, sanitized, async () => {
|
|
22542
|
+
const workspaceHash2 = teamWorkspaceHash(cwd, sanitized);
|
|
22543
|
+
const reservationPath2 = canonicalTeamStatePath(
|
|
22544
|
+
cwd,
|
|
22545
|
+
TeamPaths.teamInstanceReservation(workspaceHash2, sanitized)
|
|
22546
|
+
);
|
|
22547
|
+
if (existsSync31(reservationPath2)) {
|
|
22548
|
+
try {
|
|
22549
|
+
const contentStr = await readFile16(reservationPath2, "utf-8");
|
|
22550
|
+
const reservation = JSON.parse(contentStr);
|
|
22551
|
+
const owner = reservation.owner;
|
|
22552
|
+
if (!owner || isProcessIdentityDead(owner) || ownerMatchesCurrent2(owner)) {
|
|
22553
|
+
await unlink7(reservationPath2);
|
|
22554
|
+
}
|
|
22555
|
+
} catch {
|
|
22556
|
+
try {
|
|
22557
|
+
await unlink7(reservationPath2);
|
|
22558
|
+
} catch {
|
|
22559
|
+
}
|
|
22560
|
+
}
|
|
22561
|
+
}
|
|
22562
|
+
const teamRoot = teamStateRoot(cwd, sanitized);
|
|
22563
|
+
if (existsSync31(teamRoot)) {
|
|
22564
|
+
try {
|
|
22565
|
+
await rm9(teamRoot, { recursive: true, force: true });
|
|
22566
|
+
} catch (error) {
|
|
22567
|
+
throw new Error(`Failed to remove team state directory at ${teamRoot}: ${error instanceof Error ? error.message : String(error)}`);
|
|
22568
|
+
}
|
|
22569
|
+
}
|
|
22570
|
+
}, 1e4);
|
|
22571
|
+
}
|
|
22572
|
+
function ownerMatchesCurrent2(owner) {
|
|
22573
|
+
const processStartedAt = currentProcessStartIdentity();
|
|
22574
|
+
return processStartedAt !== null && owner.pid === process.pid && processStartedAt === owner.process_started_at;
|
|
22575
|
+
}
|
|
22385
22576
|
async function shutdownTeamV2(teamName, cwd, options = {}) {
|
|
22386
22577
|
const logEventFailure = createSwallowedErrorLogger(
|
|
22387
22578
|
"team.runtime-v2.shutdownTeamV2 appendTeamEvent failed"
|
|
@@ -22605,7 +22796,7 @@ async function shutdownTeamV2(teamName, cwd, options = {}) {
|
|
|
22605
22796
|
};
|
|
22606
22797
|
if (!config) {
|
|
22607
22798
|
const cleanupSafety = inspectTeamWorktreeCleanupSafety(sanitized, cwd);
|
|
22608
|
-
if (cleanupSafety.hasEvidence ||
|
|
22799
|
+
if (cleanupSafety.hasEvidence || existsSync31(absPath(cwd, TeamPaths.root(sanitized)))) {
|
|
22609
22800
|
process.stderr.write("[team/runtime-v2] preserving team state because config is missing and worktree cleanup evidence remains\n");
|
|
22610
22801
|
return { outcome: "preserved", reason: "config_missing_cleanup_evidence", workers: [] };
|
|
22611
22802
|
}
|
|
@@ -22922,8 +23113,8 @@ async function resumeTeamV2(teamName, cwd) {
|
|
|
22922
23113
|
};
|
|
22923
23114
|
}
|
|
22924
23115
|
async function findActiveTeamsV2(cwd) {
|
|
22925
|
-
const root =
|
|
22926
|
-
if (!
|
|
23116
|
+
const root = join37(getOmcRoot(cwd), "state", "team");
|
|
23117
|
+
if (!existsSync31(root)) return [];
|
|
22927
23118
|
const entries = await readdir6(root, { withFileTypes: true });
|
|
22928
23119
|
const active = [];
|
|
22929
23120
|
for (const e of entries) {
|
|
@@ -23083,7 +23274,7 @@ var init_runtime_v2 = __esm({
|
|
|
23083
23274
|
import { randomUUID as randomUUID17 } from "crypto";
|
|
23084
23275
|
import { spawn as spawn2 } from "child_process";
|
|
23085
23276
|
import {
|
|
23086
|
-
existsSync as
|
|
23277
|
+
existsSync as existsSync34,
|
|
23087
23278
|
mkdirSync as mkdirSync8,
|
|
23088
23279
|
readFileSync as readFileSync22,
|
|
23089
23280
|
renameSync as renameSync5,
|
|
@@ -23091,7 +23282,7 @@ import {
|
|
|
23091
23282
|
writeFileSync as writeFileSync7
|
|
23092
23283
|
} from "fs";
|
|
23093
23284
|
import { readFile as readFile18 } from "fs/promises";
|
|
23094
|
-
import { dirname as dirname30, join as
|
|
23285
|
+
import { dirname as dirname30, join as join41, resolve as resolve13 } from "path";
|
|
23095
23286
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
23096
23287
|
|
|
23097
23288
|
// src/team/api-interop.ts
|
|
@@ -23110,8 +23301,8 @@ init_recovery_request_store();
|
|
|
23110
23301
|
init_git_worktree();
|
|
23111
23302
|
init_swallowed_error();
|
|
23112
23303
|
init_types();
|
|
23113
|
-
import { existsSync as
|
|
23114
|
-
import { dirname as dirname29, join as
|
|
23304
|
+
import { existsSync as existsSync32, readFileSync as readFileSync20 } from "node:fs";
|
|
23305
|
+
import { dirname as dirname29, join as join38, resolve as resolvePath } from "node:path";
|
|
23115
23306
|
var TEAM_UPDATE_TASK_MUTABLE_FIELDS = /* @__PURE__ */ new Set(["subject", "description", "blocked_by", "requires_code_change", "delegation"]);
|
|
23116
23307
|
var TEAM_UPDATE_TASK_REQUEST_FIELDS = /* @__PURE__ */ new Set(["team_name", "task_id", "workingDirectory", ...TEAM_UPDATE_TASK_MUTABLE_FIELDS]);
|
|
23117
23308
|
var RECOVER_WORKER_REQUEST_FIELDS = /* @__PURE__ */ new Set(["team_name", "worker", "request_id", "timeout_ms"]);
|
|
@@ -23266,8 +23457,8 @@ function parseTaskDelegationPlan(value) {
|
|
|
23266
23457
|
}
|
|
23267
23458
|
function teamStateExists(teamName, candidateCwd) {
|
|
23268
23459
|
if (!TEAM_NAME_SAFE_PATTERN.test(teamName)) return false;
|
|
23269
|
-
const teamRoot =
|
|
23270
|
-
return
|
|
23460
|
+
const teamRoot = join38(getOmcRoot(candidateCwd), "state", "team", teamName);
|
|
23461
|
+
return existsSync32(join38(teamRoot, "config.json")) || existsSync32(join38(teamRoot, "tasks")) || existsSync32(teamRoot);
|
|
23271
23462
|
}
|
|
23272
23463
|
function parseTeamWorkerEnv(raw) {
|
|
23273
23464
|
if (typeof raw !== "string" || raw.trim() === "") return null;
|
|
@@ -23329,7 +23520,7 @@ async function executeTeamCleanupViaRuntime(teamName, cwd, options = {}) {
|
|
|
23329
23520
|
if (shutdown.outcome !== "cleaned") throw new Error(`team_shutdown_${shutdown.outcome}:${shutdown.reason}`);
|
|
23330
23521
|
}
|
|
23331
23522
|
function readTeamStateRootFromFile(path5) {
|
|
23332
|
-
if (!
|
|
23523
|
+
if (!existsSync32(path5)) return null;
|
|
23333
23524
|
try {
|
|
23334
23525
|
const parsed = JSON.parse(readFileSync20(path5, "utf8"));
|
|
23335
23526
|
return typeof parsed.team_state_root === "string" && parsed.team_state_root.trim() !== "" ? parsed.team_state_root.trim() : null;
|
|
@@ -23359,16 +23550,16 @@ function stateRootToWorkingDirectory(stateRoot2) {
|
|
|
23359
23550
|
return dirname29(dirname29(absolute));
|
|
23360
23551
|
}
|
|
23361
23552
|
function resolveTeamWorkingDirectoryFromMetadata(teamName, candidateCwd, workerContext) {
|
|
23362
|
-
const teamRoot =
|
|
23363
|
-
if (!
|
|
23553
|
+
const teamRoot = join38(getOmcRoot(candidateCwd), "state", "team", teamName);
|
|
23554
|
+
if (!existsSync32(teamRoot)) return null;
|
|
23364
23555
|
if (workerContext?.teamName === teamName) {
|
|
23365
|
-
const workerRoot = readTeamStateRootFromFile(
|
|
23556
|
+
const workerRoot = readTeamStateRootFromFile(join38(teamRoot, "workers", workerContext.workerName, "identity.json"));
|
|
23366
23557
|
if (workerRoot) return stateRootToWorkingDirectory(workerRoot);
|
|
23367
23558
|
}
|
|
23368
|
-
const fromConfig = readTeamStateRootFromFile(
|
|
23559
|
+
const fromConfig = readTeamStateRootFromFile(join38(teamRoot, "config.json"));
|
|
23369
23560
|
if (fromConfig) return stateRootToWorkingDirectory(fromConfig);
|
|
23370
23561
|
for (const manifestName of ["manifest.json", "manifest.v2.json"]) {
|
|
23371
|
-
const fromManifest = readTeamStateRootFromFile(
|
|
23562
|
+
const fromManifest = readTeamStateRootFromFile(join38(teamRoot, manifestName));
|
|
23372
23563
|
if (fromManifest) return stateRootToWorkingDirectory(fromManifest);
|
|
23373
23564
|
}
|
|
23374
23565
|
return null;
|
|
@@ -24122,7 +24313,7 @@ init_tmux_session();
|
|
|
24122
24313
|
init_state_paths();
|
|
24123
24314
|
init_types();
|
|
24124
24315
|
import { readFile as readFile17 } from "fs/promises";
|
|
24125
|
-
import { join as
|
|
24316
|
+
import { join as join39 } from "path";
|
|
24126
24317
|
function stateRoot(cwd, teamName) {
|
|
24127
24318
|
validateTeamName2(teamName);
|
|
24128
24319
|
return teamStateRoot(cwd, teamName);
|
|
@@ -24135,7 +24326,7 @@ async function readJsonSafe3(filePath) {
|
|
|
24135
24326
|
}
|
|
24136
24327
|
}
|
|
24137
24328
|
function taskPath(root, taskId) {
|
|
24138
|
-
return
|
|
24329
|
+
return join39(root, "tasks", `${normalizeTaskFileStem(taskId)}.json`);
|
|
24139
24330
|
}
|
|
24140
24331
|
async function readTask(root, taskId) {
|
|
24141
24332
|
return readJsonSafe3(taskPath(root, taskId));
|
|
@@ -24148,9 +24339,9 @@ async function monitorTeam(teamName, cwd, workerPaneIds) {
|
|
|
24148
24339
|
const taskCounts = { pending: 0, inProgress: 0, completed: 0, failed: 0 };
|
|
24149
24340
|
try {
|
|
24150
24341
|
const { readdir: readdir7 } = await import("fs/promises");
|
|
24151
|
-
const taskFiles = await readdir7(
|
|
24342
|
+
const taskFiles = await readdir7(join39(root, "tasks"));
|
|
24152
24343
|
for (const f of taskFiles.filter((f2) => f2.endsWith(".json"))) {
|
|
24153
|
-
const task = await readJsonSafe3(
|
|
24344
|
+
const task = await readJsonSafe3(join39(root, "tasks", f));
|
|
24154
24345
|
if (task?.status === "pending") taskCounts.pending++;
|
|
24155
24346
|
else if (task?.status === "in_progress") taskCounts.inProgress++;
|
|
24156
24347
|
else if (task?.status === "completed") taskCounts.completed++;
|
|
@@ -24166,7 +24357,7 @@ async function monitorTeam(teamName, cwd, workerPaneIds) {
|
|
|
24166
24357
|
const wName = `worker-${i + 1}`;
|
|
24167
24358
|
const paneId = workerPaneIds[i];
|
|
24168
24359
|
const alive = await isWorkerAlive(paneId);
|
|
24169
|
-
const heartbeatPath =
|
|
24360
|
+
const heartbeatPath = join39(root, "workers", wName, "heartbeat.json");
|
|
24170
24361
|
const heartbeat = await readJsonSafe3(heartbeatPath);
|
|
24171
24362
|
let stalled = false;
|
|
24172
24363
|
if (heartbeat?.updatedAt) {
|
|
@@ -24208,7 +24399,7 @@ async function monitorTeam(teamName, cwd, workerPaneIds) {
|
|
|
24208
24399
|
}
|
|
24209
24400
|
async function resumeTeam(teamName, cwd) {
|
|
24210
24401
|
const root = stateRoot(cwd, teamName);
|
|
24211
|
-
const configData = await readJsonSafe3(
|
|
24402
|
+
const configData = await readJsonSafe3(join39(root, "config.json"));
|
|
24212
24403
|
if (!configData || !isValidTeamInstanceId(configData.instance_id)) return null;
|
|
24213
24404
|
const sName = configData.tmuxSession;
|
|
24214
24405
|
const leaderPaneId = configData.leaderPaneId;
|
|
@@ -24303,8 +24494,8 @@ init_paths();
|
|
|
24303
24494
|
|
|
24304
24495
|
// src/planning/artifacts.ts
|
|
24305
24496
|
init_worktree_paths();
|
|
24306
|
-
import { readdirSync as
|
|
24307
|
-
import { join as
|
|
24497
|
+
import { readdirSync as readdirSync12, readFileSync as readFileSync21, existsSync as existsSync33 } from "fs";
|
|
24498
|
+
import { join as join40 } from "path";
|
|
24308
24499
|
|
|
24309
24500
|
// src/planning/artifact-names.ts
|
|
24310
24501
|
import { basename as basename15 } from "path";
|
|
@@ -24431,7 +24622,7 @@ function hasRequiredSections(markdown, headings) {
|
|
|
24431
24622
|
);
|
|
24432
24623
|
}
|
|
24433
24624
|
function getPlansDirCandidates(cwd) {
|
|
24434
|
-
return [
|
|
24625
|
+
return [join40(getOmcRoot(cwd), "plans"), join40(cwd, ".omx", "plans")];
|
|
24435
24626
|
}
|
|
24436
24627
|
function sortArtifactPathsDescending(paths) {
|
|
24437
24628
|
return [...paths].sort((a, b) => comparePlanningArtifactPaths(b, a));
|
|
@@ -24458,19 +24649,19 @@ function readPlanningArtifacts(cwd) {
|
|
|
24458
24649
|
const prdPaths = [];
|
|
24459
24650
|
const testSpecPaths = [];
|
|
24460
24651
|
for (const plansDir of getPlansDirCandidates(cwd)) {
|
|
24461
|
-
if (!
|
|
24652
|
+
if (!existsSync33(plansDir)) {
|
|
24462
24653
|
continue;
|
|
24463
24654
|
}
|
|
24464
24655
|
try {
|
|
24465
|
-
entries =
|
|
24656
|
+
entries = readdirSync12(plansDir);
|
|
24466
24657
|
} catch {
|
|
24467
24658
|
continue;
|
|
24468
24659
|
}
|
|
24469
24660
|
for (const entry of entries) {
|
|
24470
24661
|
if (entry.startsWith("prd-") && entry.endsWith(".md")) {
|
|
24471
|
-
prdPaths.push(
|
|
24662
|
+
prdPaths.push(join40(plansDir, entry));
|
|
24472
24663
|
} else if (entry.startsWith("test-spec-") && entry.endsWith(".md")) {
|
|
24473
|
-
testSpecPaths.push(
|
|
24664
|
+
testSpecPaths.push(join40(plansDir, entry));
|
|
24474
24665
|
}
|
|
24475
24666
|
}
|
|
24476
24667
|
}
|
|
@@ -24646,21 +24837,21 @@ function resolveRuntimeCliPath2(env = process.env) {
|
|
|
24646
24837
|
return env.OMC_RUNTIME_CLI_PATH;
|
|
24647
24838
|
}
|
|
24648
24839
|
const moduleDir = dirname30(fileURLToPath5(import.meta.url));
|
|
24649
|
-
return
|
|
24840
|
+
return join41(moduleDir, "../../bridge/runtime-cli.cjs");
|
|
24650
24841
|
}
|
|
24651
24842
|
function ensureJobsDir(jobsDir) {
|
|
24652
|
-
if (!
|
|
24843
|
+
if (!existsSync34(jobsDir)) {
|
|
24653
24844
|
mkdirSync8(jobsDir, { recursive: true });
|
|
24654
24845
|
}
|
|
24655
24846
|
}
|
|
24656
24847
|
function jobPath(jobsDir, jobId) {
|
|
24657
|
-
return
|
|
24848
|
+
return join41(jobsDir, `${jobId}.json`);
|
|
24658
24849
|
}
|
|
24659
24850
|
function resultArtifactPath(jobsDir, jobId) {
|
|
24660
|
-
return
|
|
24851
|
+
return join41(jobsDir, `${jobId}-result.json`);
|
|
24661
24852
|
}
|
|
24662
24853
|
function panesArtifactPath(jobsDir, jobId) {
|
|
24663
|
-
return
|
|
24854
|
+
return join41(jobsDir, `${jobId}-panes.json`);
|
|
24664
24855
|
}
|
|
24665
24856
|
function validateJobId(jobId) {
|
|
24666
24857
|
if (!JOB_ID_PATTERN.test(jobId)) {
|
|
@@ -24763,7 +24954,7 @@ function formatJobReadError(jobId, result) {
|
|
|
24763
24954
|
}
|
|
24764
24955
|
}
|
|
24765
24956
|
function jobLockPath(jobsDir, jobId) {
|
|
24766
|
-
return
|
|
24957
|
+
return join41(jobsDir, `.${jobId}.lock`);
|
|
24767
24958
|
}
|
|
24768
24959
|
function writeJobToDiskUnlocked(jobId, job, jobsDir) {
|
|
24769
24960
|
ensureJobsDir(jobsDir);
|
|
@@ -25259,10 +25450,45 @@ async function teamShutdownByName(teamName, options = {}) {
|
|
|
25259
25450
|
validateTeamName2(teamName);
|
|
25260
25451
|
const cwd = options.cwd ?? process.cwd();
|
|
25261
25452
|
const runtimeV2 = await Promise.resolve().then(() => (init_runtime_v2(), runtime_v2_exports));
|
|
25453
|
+
try {
|
|
25454
|
+
await runtimeV2.cleanupStaleReservations(teamName, cwd);
|
|
25455
|
+
} catch {
|
|
25456
|
+
}
|
|
25262
25457
|
const config = await readTeamConfig(teamName, cwd);
|
|
25263
|
-
|
|
25458
|
+
if (!config) {
|
|
25459
|
+
console.log(`No team state found for ${teamName}`);
|
|
25460
|
+
return {
|
|
25461
|
+
teamName,
|
|
25462
|
+
shutdown: false,
|
|
25463
|
+
forced: Boolean(options.force),
|
|
25464
|
+
sessionFound: false
|
|
25465
|
+
};
|
|
25466
|
+
}
|
|
25467
|
+
const instanceId = config.instance_id;
|
|
25264
25468
|
if (!instanceId || !isValidTeamInstanceId(instanceId)) {
|
|
25265
|
-
|
|
25469
|
+
console.error(`Team ${teamName} has incomplete startup state (config but no valid instance_id); cleaning up...`);
|
|
25470
|
+
try {
|
|
25471
|
+
await runtimeV2.cleanupAbandonedTeamState(teamName, cwd);
|
|
25472
|
+
} catch (error) {
|
|
25473
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
25474
|
+
console.error(`Failed to clean up abandoned team state: ${detail}`);
|
|
25475
|
+
process.exitCode = 1;
|
|
25476
|
+
return {
|
|
25477
|
+
teamName,
|
|
25478
|
+
shutdown: false,
|
|
25479
|
+
forced: Boolean(options.force),
|
|
25480
|
+
sessionFound: false,
|
|
25481
|
+
error: `cleanup_failed:${detail}`
|
|
25482
|
+
};
|
|
25483
|
+
}
|
|
25484
|
+
process.exitCode = 1;
|
|
25485
|
+
return {
|
|
25486
|
+
teamName,
|
|
25487
|
+
shutdown: false,
|
|
25488
|
+
forced: Boolean(options.force),
|
|
25489
|
+
sessionFound: false,
|
|
25490
|
+
cleaned: true
|
|
25491
|
+
};
|
|
25266
25492
|
}
|
|
25267
25493
|
const shutdown = await runtimeV2.shutdownTeamV2(teamName, cwd, {
|
|
25268
25494
|
instanceId,
|
|
@@ -25835,11 +26061,21 @@ async function teamCommand(argv) {
|
|
|
25835
26061
|
}
|
|
25836
26062
|
if (command === "shutdown") {
|
|
25837
26063
|
const parsed = parseTeamTargetArgs(rest, "shutdown");
|
|
25838
|
-
|
|
25839
|
-
|
|
25840
|
-
|
|
25841
|
-
|
|
25842
|
-
|
|
26064
|
+
try {
|
|
26065
|
+
const result = await teamShutdownByName(parsed.teamName, {
|
|
26066
|
+
cwd: parsed.cwd ?? process.cwd(),
|
|
26067
|
+
force: Boolean(parsed.force)
|
|
26068
|
+
});
|
|
26069
|
+
output(result, parsed.json);
|
|
26070
|
+
} catch (err) {
|
|
26071
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
26072
|
+
if (!parsed.json) {
|
|
26073
|
+
console.error(message);
|
|
26074
|
+
process.exitCode = 1;
|
|
26075
|
+
} else {
|
|
26076
|
+
output({ ok: false, error: { message } }, parsed.json);
|
|
26077
|
+
}
|
|
26078
|
+
}
|
|
25843
26079
|
return;
|
|
25844
26080
|
}
|
|
25845
26081
|
if (command === "api") {
|