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/runtime-cli.cjs
CHANGED
|
@@ -1558,6 +1558,34 @@ function getConfigDir() {
|
|
|
1558
1558
|
}
|
|
1559
1559
|
return process.env.XDG_CONFIG_HOME || (0, import_path8.join)((0, import_os3.homedir)(), ".config");
|
|
1560
1560
|
}
|
|
1561
|
+
function getStateDir() {
|
|
1562
|
+
if (process.platform === "win32") {
|
|
1563
|
+
return process.env.LOCALAPPDATA || (0, import_path8.join)((0, import_os3.homedir)(), "AppData", "Local");
|
|
1564
|
+
}
|
|
1565
|
+
return process.env.XDG_STATE_HOME || (0, import_path8.join)((0, import_os3.homedir)(), ".local", "state");
|
|
1566
|
+
}
|
|
1567
|
+
function prefersXdgOmcDirs() {
|
|
1568
|
+
return process.platform !== "win32" && process.platform !== "darwin";
|
|
1569
|
+
}
|
|
1570
|
+
function getUserHomeDir() {
|
|
1571
|
+
if (process.platform === "win32") {
|
|
1572
|
+
return process.env.USERPROFILE || process.env.HOME || (0, import_os3.homedir)();
|
|
1573
|
+
}
|
|
1574
|
+
return process.env.HOME || (0, import_os3.homedir)();
|
|
1575
|
+
}
|
|
1576
|
+
function getLegacyOmcDir() {
|
|
1577
|
+
return (0, import_path8.join)(getUserHomeDir(), ".omg");
|
|
1578
|
+
}
|
|
1579
|
+
function getGlobalOmcStateRoot() {
|
|
1580
|
+
const explicitRoot = process.env.OMC_HOME?.trim();
|
|
1581
|
+
if (explicitRoot) {
|
|
1582
|
+
return (0, import_path8.join)(explicitRoot, "state");
|
|
1583
|
+
}
|
|
1584
|
+
if (prefersXdgOmcDirs()) {
|
|
1585
|
+
return (0, import_path8.join)(getStateDir(), "omc");
|
|
1586
|
+
}
|
|
1587
|
+
return (0, import_path8.join)(getLegacyOmcDir(), "state");
|
|
1588
|
+
}
|
|
1561
1589
|
var import_path8, import_fs6, import_os3, PLUGIN_ROOT_REQUIREMENTS, OCCUPIED_CODES, STALE_THRESHOLD_MS;
|
|
1562
1590
|
var init_paths = __esm({
|
|
1563
1591
|
"src/utils/paths.ts"() {
|
|
@@ -2456,6 +2484,7 @@ function validateTeamConfig(config) {
|
|
|
2456
2484
|
}
|
|
2457
2485
|
continue;
|
|
2458
2486
|
}
|
|
2487
|
+
const provider = spec.provider ?? "claude";
|
|
2459
2488
|
if (spec.provider !== void 0) {
|
|
2460
2489
|
if (typeof spec.provider !== "string" || !TEAM_ROLE_PROVIDERS.has(spec.provider)) {
|
|
2461
2490
|
throw new Error(
|
|
@@ -2475,6 +2504,20 @@ function validateTeamConfig(config) {
|
|
|
2475
2504
|
);
|
|
2476
2505
|
}
|
|
2477
2506
|
}
|
|
2507
|
+
if (spec.reasoningEffort !== void 0) {
|
|
2508
|
+
if (typeof spec.reasoningEffort !== "string") {
|
|
2509
|
+
throw new Error(
|
|
2510
|
+
`[OMC] team.roleRouting.${rawRoleKey}.reasoningEffort: must be a string, got ${typeof spec.reasoningEffort}`
|
|
2511
|
+
);
|
|
2512
|
+
}
|
|
2513
|
+
const allowedForProvider = REASONING_EFFORT_BY_PROVIDER[provider];
|
|
2514
|
+
if (!allowedForProvider || !allowedForProvider.has(spec.reasoningEffort)) {
|
|
2515
|
+
const allowed = allowedForProvider ? [...allowedForProvider].join("|") : "(not supported for this provider)";
|
|
2516
|
+
throw new Error(
|
|
2517
|
+
`[OMC] team.roleRouting.${rawRoleKey}.reasoningEffort: invalid value "${spec.reasoningEffort}" for provider "${provider}". Allowed: ${allowed}`
|
|
2518
|
+
);
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2478
2521
|
}
|
|
2479
2522
|
}
|
|
2480
2523
|
function validateWorkerPermissionsConfig(config) {
|
|
@@ -2643,7 +2686,7 @@ function loadConfig() {
|
|
|
2643
2686
|
validateAutopilotConfig(config);
|
|
2644
2687
|
return config;
|
|
2645
2688
|
}
|
|
2646
|
-
var import_fs7, import_path9, 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;
|
|
2689
|
+
var import_fs7, import_path9, 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;
|
|
2647
2690
|
var init_loader = __esm({
|
|
2648
2691
|
"src/config/loader.ts"() {
|
|
2649
2692
|
"use strict";
|
|
@@ -2661,6 +2704,11 @@ var init_loader = __esm({
|
|
|
2661
2704
|
KNOWN_AGENT_NAME_SET = new Set(KNOWN_AGENT_NAMES);
|
|
2662
2705
|
TEAM_ROLE_PROVIDERS = /* @__PURE__ */ new Set(["claude", "copilot", "codex", "gemini", "grok", "cursor", "antigravity"]);
|
|
2663
2706
|
TEAM_ROLE_TIERS = /* @__PURE__ */ new Set(["HIGH", "MEDIUM", "LOW"]);
|
|
2707
|
+
REASONING_EFFORT_BY_PROVIDER = {
|
|
2708
|
+
claude: /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max"]),
|
|
2709
|
+
codex: /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max", "ultra"]),
|
|
2710
|
+
antigravity: /* @__PURE__ */ new Set(["low", "medium", "high", "max"])
|
|
2711
|
+
};
|
|
2664
2712
|
AUTOPILOT_EXECUTION_BACKENDS = /* @__PURE__ */ new Set(["team", "solo"]);
|
|
2665
2713
|
AUTOPILOT_PLANNING_MODES = /* @__PURE__ */ new Set(["ralplan", "direct"]);
|
|
2666
2714
|
AUTOPILOT_TEAM_AGENT_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -2812,7 +2860,7 @@ function getNativeContainedFs() {
|
|
|
2812
2860
|
loaded = (0, import_node_module.createRequire)(importMetaUrl)(binary);
|
|
2813
2861
|
return loaded;
|
|
2814
2862
|
} catch (cause) {
|
|
2815
|
-
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 });
|
|
2863
|
+
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 });
|
|
2816
2864
|
}
|
|
2817
2865
|
}
|
|
2818
2866
|
}
|
|
@@ -2901,7 +2949,7 @@ function probeProcessStartIdentityForPlatform(pid, platform, exec2, read, strict
|
|
|
2901
2949
|
["-NoProfile", "-NonInteractive", "-Command", command],
|
|
2902
2950
|
{ encoding: "utf8", windowsHide: true }
|
|
2903
2951
|
).trim();
|
|
2904
|
-
return
|
|
2952
|
+
return /^[1-9]\d*$/.test(ticks) ? { identity: `win32:${ticks}`, precise: true } : { identity: null, precise: false };
|
|
2905
2953
|
}
|
|
2906
2954
|
if (platform === "darwin") {
|
|
2907
2955
|
if (strict) {
|
|
@@ -6201,7 +6249,7 @@ function resolveValidatedBinaryPath(agentType) {
|
|
|
6201
6249
|
return resolveCliBinaryPath(contract.binary);
|
|
6202
6250
|
}
|
|
6203
6251
|
function buildLaunchArgs(agentType, config) {
|
|
6204
|
-
return getContract(agentType).buildLaunchArgs(config.model, config.extraFlags);
|
|
6252
|
+
return getContract(agentType).buildLaunchArgs(config.model, config.reasoningEffort, config.extraFlags);
|
|
6205
6253
|
}
|
|
6206
6254
|
function buildWorkerArgv(agentType, config) {
|
|
6207
6255
|
validateTeamName2(config.teamName);
|
|
@@ -6242,19 +6290,30 @@ function buildValidatedWorkerLaunchDescriptor(agentType, config, appendedArgs =
|
|
|
6242
6290
|
args: [...args, ...appendedArgs]
|
|
6243
6291
|
});
|
|
6244
6292
|
}
|
|
6245
|
-
function getWorkerEnv(teamName, workerName, agentType, env = process.env) {
|
|
6293
|
+
function getWorkerEnv(teamName, workerName, agentType, env = process.env, role) {
|
|
6246
6294
|
validateTeamName2(teamName);
|
|
6247
6295
|
const workerEnv = {
|
|
6248
6296
|
OMC_TEAM_WORKER: `${teamName}/${workerName}`,
|
|
6249
6297
|
OMC_TEAM_NAME: teamName,
|
|
6250
6298
|
OMC_WORKER_AGENT_TYPE: agentType
|
|
6251
6299
|
};
|
|
6300
|
+
if (role) {
|
|
6301
|
+
workerEnv.OMC_TEAM_ROLE = role;
|
|
6302
|
+
}
|
|
6252
6303
|
for (const key of WORKER_MODEL_ENV_ALLOWLIST) {
|
|
6253
6304
|
const value = env[key];
|
|
6254
6305
|
if (typeof value === "string" && value.length > 0) {
|
|
6255
6306
|
workerEnv[key] = value;
|
|
6256
6307
|
}
|
|
6257
6308
|
}
|
|
6309
|
+
if (agentType === "claude") {
|
|
6310
|
+
for (const key of CLAUDE_WORKER_ENV_ALLOWLIST) {
|
|
6311
|
+
const value = env[key];
|
|
6312
|
+
if (typeof value === "string" && value.length > 0) {
|
|
6313
|
+
workerEnv[key] = value;
|
|
6314
|
+
}
|
|
6315
|
+
}
|
|
6316
|
+
}
|
|
6258
6317
|
return workerEnv;
|
|
6259
6318
|
}
|
|
6260
6319
|
function isPromptModeAgent(agentType) {
|
|
@@ -6356,7 +6415,7 @@ function getPromptModeArgs(agentType, instruction) {
|
|
|
6356
6415
|
}
|
|
6357
6416
|
return [instruction];
|
|
6358
6417
|
}
|
|
6359
|
-
var import_path19, import_os5, resolvedPathCache, UNTRUSTED_PATH_PATTERNS, UNTRUSTED_WINDOWS_PATH_PATTERNS, COPILOT_WORKER_BASE_FLAGS, COPILOT_TIER_ALIAS_MODELS, CONTRACTS, WORKER_MODEL_ENV_ALLOWLIST;
|
|
6418
|
+
var import_path19, import_os5, 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;
|
|
6360
6419
|
var init_model_contract = __esm({
|
|
6361
6420
|
"src/team/model-contract.ts"() {
|
|
6362
6421
|
"use strict";
|
|
@@ -6391,7 +6450,7 @@ var init_model_contract = __esm({
|
|
|
6391
6450
|
agentType: "claude",
|
|
6392
6451
|
binary: "claude",
|
|
6393
6452
|
installInstructions: "Install Claude CLI: https://claude.ai/download",
|
|
6394
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
6453
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
6395
6454
|
const args = ["--dangerously-skip-permissions"];
|
|
6396
6455
|
if (shouldUseClaudeBareMode() && !extraFlags.includes("--bare")) {
|
|
6397
6456
|
args.push("--bare");
|
|
@@ -6400,6 +6459,9 @@ var init_model_contract = __esm({
|
|
|
6400
6459
|
const resolved = isProviderSpecificModelId(model) ? model : normalizeToCcAlias(model);
|
|
6401
6460
|
args.push("--model", resolved);
|
|
6402
6461
|
}
|
|
6462
|
+
if (reasoningEffort) {
|
|
6463
|
+
args.push("--effort", reasoningEffort);
|
|
6464
|
+
}
|
|
6403
6465
|
return [...args, ...extraFlags];
|
|
6404
6466
|
},
|
|
6405
6467
|
parseOutput(rawOutput) {
|
|
@@ -6413,8 +6475,9 @@ var init_model_contract = __esm({
|
|
|
6413
6475
|
// Persistent interactive pane like claude (inbox + nudge); no -p prompt mode.
|
|
6414
6476
|
// Copilot rejects --dangerously-skip-permissions; the unattended pane gets an
|
|
6415
6477
|
// explicit allow set instead, and permissions.workerDenyTools/Urls arrive via
|
|
6416
|
-
// extraFlags (deny rules win over allow rules in Copilot).
|
|
6417
|
-
|
|
6478
|
+
// extraFlags (deny rules win over allow rules in Copilot). Copilot has no verified
|
|
6479
|
+
// reasoning-effort flag, so per-role reasoningEffort (upstream #4206) is not forwarded.
|
|
6480
|
+
buildLaunchArgs(model, _reasoningEffort, extraFlags = []) {
|
|
6418
6481
|
const args = [...COPILOT_WORKER_BASE_FLAGS];
|
|
6419
6482
|
if (model) args.push("--model", toCopilotModelId(model));
|
|
6420
6483
|
return [...args, ...extraFlags];
|
|
@@ -6431,9 +6494,12 @@ var init_model_contract = __esm({
|
|
|
6431
6494
|
// or positional prompt mode here; runtime dispatch writes inbox.md and nudges
|
|
6432
6495
|
// the live Codex TUI with `codex` as the worker process.
|
|
6433
6496
|
supportsPromptMode: false,
|
|
6434
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
6497
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
6435
6498
|
const args = ["--dangerously-bypass-approvals-and-sandbox"];
|
|
6436
6499
|
if (model) args.push("--model", model);
|
|
6500
|
+
if (reasoningEffort) {
|
|
6501
|
+
args.push("-c", `model_reasoning_effort="${reasoningEffort}"`);
|
|
6502
|
+
}
|
|
6437
6503
|
return [...args, ...extraFlags];
|
|
6438
6504
|
},
|
|
6439
6505
|
parseOutput(rawOutput) {
|
|
@@ -6459,7 +6525,7 @@ var init_model_contract = __esm({
|
|
|
6459
6525
|
installInstructions: "Install Gemini CLI: npm install -g @google/gemini-cli",
|
|
6460
6526
|
supportsPromptMode: true,
|
|
6461
6527
|
promptModeFlag: "-p",
|
|
6462
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
6528
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
6463
6529
|
const args = ["--approval-mode", "yolo"];
|
|
6464
6530
|
if (model) args.push("--model", model);
|
|
6465
6531
|
return [...args, ...extraFlags];
|
|
@@ -6474,7 +6540,7 @@ var init_model_contract = __esm({
|
|
|
6474
6540
|
installInstructions: "Install Grok Build: https://build.grok.com",
|
|
6475
6541
|
supportsPromptMode: true,
|
|
6476
6542
|
promptModeFlag: "-p",
|
|
6477
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
6543
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
6478
6544
|
const args = ["--always-approve"];
|
|
6479
6545
|
if (model) args.push("--model", model);
|
|
6480
6546
|
return [...args, ...extraFlags];
|
|
@@ -6489,9 +6555,12 @@ var init_model_contract = __esm({
|
|
|
6489
6555
|
installInstructions: "Install the Antigravity CLI (agy) per the official instructions at https://antigravity.google, then verify with `agy --version`.",
|
|
6490
6556
|
supportsPromptMode: true,
|
|
6491
6557
|
promptModeFlag: "-p",
|
|
6492
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
6558
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
6493
6559
|
const args = ["--dangerously-skip-permissions"];
|
|
6494
6560
|
if (model) args.push("--model", model);
|
|
6561
|
+
if (reasoningEffort) {
|
|
6562
|
+
args.push("--effort", reasoningEffort);
|
|
6563
|
+
}
|
|
6495
6564
|
return [...args, ...extraFlags];
|
|
6496
6565
|
},
|
|
6497
6566
|
parseOutput(rawOutput) {
|
|
@@ -6505,7 +6574,7 @@ var init_model_contract = __esm({
|
|
|
6505
6574
|
// Team workers must be persistent interactive panes, so the one-shot
|
|
6506
6575
|
// `-p/--print` path is deliberately unused here (same stance as codex).
|
|
6507
6576
|
supportsPromptMode: false,
|
|
6508
|
-
buildLaunchArgs(model, extraFlags = []) {
|
|
6577
|
+
buildLaunchArgs(model, reasoningEffort, extraFlags = []) {
|
|
6509
6578
|
const args = ["--force", "--trust"];
|
|
6510
6579
|
const extra = extraFlags.filter((flag) => !["--force", "-f", "--yolo", "--trust"].includes(flag));
|
|
6511
6580
|
if (model) args.push("--model", model);
|
|
@@ -6544,6 +6613,10 @@ var init_model_contract = __esm({
|
|
|
6544
6613
|
"COPILOT_HOME",
|
|
6545
6614
|
"COPILOT_MODEL"
|
|
6546
6615
|
];
|
|
6616
|
+
CLAUDE_WORKER_ENV_ALLOWLIST = [
|
|
6617
|
+
"CLAUDE_CONFIG_DIR",
|
|
6618
|
+
"CLAUDE_CODE_EFFORT_LEVEL"
|
|
6619
|
+
];
|
|
6547
6620
|
}
|
|
6548
6621
|
});
|
|
6549
6622
|
|
|
@@ -6715,11 +6788,11 @@ function tmuxEnv() {
|
|
|
6715
6788
|
function resolveEnv(opts) {
|
|
6716
6789
|
return opts?.stripTmux ? tmuxEnv() : process.env;
|
|
6717
6790
|
}
|
|
6718
|
-
function
|
|
6719
|
-
assertSafeCmdValue(
|
|
6720
|
-
if (
|
|
6721
|
-
if (!/[\s"%^&|<>()]/.test(
|
|
6722
|
-
return `"${
|
|
6791
|
+
function quoteForTmuxCmdLayer(command) {
|
|
6792
|
+
assertSafeCmdValue(command);
|
|
6793
|
+
if (command.length === 0) return '""';
|
|
6794
|
+
if (!/[\s"%^&|<>()]/.test(command)) return command;
|
|
6795
|
+
return `"${command.replace(/(["%])/g, "$1$1")}"`;
|
|
6723
6796
|
}
|
|
6724
6797
|
function assertSafeCmdValue(value) {
|
|
6725
6798
|
if (/[\0\r\n]/.test(value)) {
|
|
@@ -6730,7 +6803,7 @@ function resolveTmuxInvocation(args) {
|
|
|
6730
6803
|
const resolvedBinary = resolveTmuxBinaryPath();
|
|
6731
6804
|
if (process.platform === "win32" && /\.(cmd|bat)$/i.test(resolvedBinary)) {
|
|
6732
6805
|
const comspec = process.env.COMSPEC || "cmd.exe";
|
|
6733
|
-
const commandLine = [
|
|
6806
|
+
const commandLine = [quoteForTmuxCmdLayer(resolvedBinary), ...args.map(quoteForTmuxCmdLayer)].join(" ");
|
|
6734
6807
|
return {
|
|
6735
6808
|
command: comspec,
|
|
6736
6809
|
args: ["/d", "/s", "/c", commandLine]
|
|
@@ -7284,7 +7357,7 @@ function verifyPrivateTempFile(fd, tempPath, label, operations) {
|
|
|
7284
7357
|
`${label} temporary file must be a private regular single-link file`
|
|
7285
7358
|
);
|
|
7286
7359
|
}
|
|
7287
|
-
if (fdStats
|
|
7360
|
+
if (!sameFileIdentity(fdStats, pathStats)) {
|
|
7288
7361
|
throw new Error(`${label} temporary file was replaced before rename`);
|
|
7289
7362
|
}
|
|
7290
7363
|
}
|
|
@@ -7296,7 +7369,7 @@ function verifyPublishedFile(fd, filePath, label, operations) {
|
|
|
7296
7369
|
} catch {
|
|
7297
7370
|
throw new Error(`${label} target was replaced at publication`);
|
|
7298
7371
|
}
|
|
7299
|
-
if (!pathStats.isFile() || fdStats
|
|
7372
|
+
if (!pathStats.isFile() || !sameFileIdentity(fdStats, pathStats)) {
|
|
7300
7373
|
throw new Error(`${label} target was replaced at publication`);
|
|
7301
7374
|
}
|
|
7302
7375
|
}
|
|
@@ -7320,6 +7393,14 @@ function preservePriorTarget(filePath, operations) {
|
|
|
7320
7393
|
return null;
|
|
7321
7394
|
}
|
|
7322
7395
|
}
|
|
7396
|
+
function sameFileIdentity(a, b) {
|
|
7397
|
+
if (a.ino !== b.ino) return false;
|
|
7398
|
+
const isWindows = process.platform === "win32";
|
|
7399
|
+
if (isWindows && (a.dev === 0 || b.dev === 0)) {
|
|
7400
|
+
return true;
|
|
7401
|
+
}
|
|
7402
|
+
return a.dev === b.dev;
|
|
7403
|
+
}
|
|
7323
7404
|
function currentFileIdentity(filePath, operations) {
|
|
7324
7405
|
try {
|
|
7325
7406
|
const stats = (operations?.lstat ?? fsSync.lstatSync)(filePath);
|
|
@@ -7340,7 +7421,7 @@ function rollbackPriorTarget(filePath, backupPath, expectedIdentity, operations)
|
|
|
7340
7421
|
if (expectedIdentity === null) return;
|
|
7341
7422
|
const current = currentFileIdentity(filePath, operations);
|
|
7342
7423
|
if (current === null) return;
|
|
7343
|
-
if (expectedIdentity !== null && (current
|
|
7424
|
+
if (expectedIdentity !== null && !sameFileIdentity(current, expectedIdentity)) {
|
|
7344
7425
|
return;
|
|
7345
7426
|
}
|
|
7346
7427
|
try {
|
|
@@ -7647,6 +7728,137 @@ var init_file_lock = __esm({
|
|
|
7647
7728
|
}
|
|
7648
7729
|
});
|
|
7649
7730
|
|
|
7731
|
+
// src/lib/host-load-gate.ts
|
|
7732
|
+
function getDefaultGateConfig() {
|
|
7733
|
+
return {
|
|
7734
|
+
// CPU load threshold: 80% of available cores
|
|
7735
|
+
cpuLoadThreshold: (0, import_os7.cpus)().length * 0.8,
|
|
7736
|
+
// Free memory threshold: 256 MB (allow through if more than this free)
|
|
7737
|
+
freeMemoryThreshold: 256 * 1024 * 1024,
|
|
7738
|
+
// Max sibling sessions: 8 (allow 8+ concurrent sessions)
|
|
7739
|
+
maxSiblingSessions: 8,
|
|
7740
|
+
// Gate is enabled by default
|
|
7741
|
+
enabled: !process.env["OMC_HOST_LOAD_GATE_DISABLED"],
|
|
7742
|
+
// Default timeout: 30 seconds
|
|
7743
|
+
gateTimeoutMs: 3e4,
|
|
7744
|
+
// Check interval: 2 seconds
|
|
7745
|
+
checkIntervalMs: 2e3
|
|
7746
|
+
};
|
|
7747
|
+
}
|
|
7748
|
+
function parseGateConfig(overrides) {
|
|
7749
|
+
const defaults = getDefaultGateConfig();
|
|
7750
|
+
const config = {
|
|
7751
|
+
cpuLoadThreshold: parseFloatEnv("OMC_HOST_LOAD_THRESHOLD") ?? defaults.cpuLoadThreshold,
|
|
7752
|
+
freeMemoryThreshold: parseIntEnv("OMC_FREE_MEMORY_THRESHOLD") ? parseIntEnv("OMC_FREE_MEMORY_THRESHOLD") * 1024 * 1024 : defaults.freeMemoryThreshold,
|
|
7753
|
+
maxSiblingSessions: parseIntEnv("OMC_MAX_SIBLING_SESSIONS") ?? defaults.maxSiblingSessions,
|
|
7754
|
+
enabled: defaults.enabled,
|
|
7755
|
+
gateTimeoutMs: defaults.gateTimeoutMs,
|
|
7756
|
+
checkIntervalMs: defaults.checkIntervalMs,
|
|
7757
|
+
...overrides
|
|
7758
|
+
};
|
|
7759
|
+
return config;
|
|
7760
|
+
}
|
|
7761
|
+
function parseFloatEnv(key) {
|
|
7762
|
+
const val = process.env[key];
|
|
7763
|
+
if (!val) return null;
|
|
7764
|
+
const parsed = parseFloat(val);
|
|
7765
|
+
return isNaN(parsed) ? null : parsed;
|
|
7766
|
+
}
|
|
7767
|
+
function parseIntEnv(key) {
|
|
7768
|
+
const val = process.env[key];
|
|
7769
|
+
if (!val) return null;
|
|
7770
|
+
const parsed = parseInt(val, 10);
|
|
7771
|
+
return isNaN(parsed) ? null : parsed;
|
|
7772
|
+
}
|
|
7773
|
+
function countLiveSessions() {
|
|
7774
|
+
try {
|
|
7775
|
+
const stateRoot = getGlobalOmcStateRoot();
|
|
7776
|
+
const sessionsDir = (0, import_path23.join)(stateRoot, "sessions");
|
|
7777
|
+
if (!(0, import_fs22.existsSync)(sessionsDir)) {
|
|
7778
|
+
return 0;
|
|
7779
|
+
}
|
|
7780
|
+
const entries = (0, import_fs22.readdirSync)(sessionsDir, { withFileTypes: true });
|
|
7781
|
+
return entries.filter((e) => e.isDirectory()).length;
|
|
7782
|
+
} catch {
|
|
7783
|
+
return 0;
|
|
7784
|
+
}
|
|
7785
|
+
}
|
|
7786
|
+
function getHostMetrics() {
|
|
7787
|
+
try {
|
|
7788
|
+
const loads = (0, import_os7.loadavg)();
|
|
7789
|
+
const cpuLoad = loads[0];
|
|
7790
|
+
const freeMemoryBytes = (0, import_os7.freemem)();
|
|
7791
|
+
const totalMemoryBytes = (0, import_os7.totalmem)();
|
|
7792
|
+
const freeMemoryPercent = freeMemoryBytes / totalMemoryBytes * 100;
|
|
7793
|
+
const siblingSessions = countLiveSessions();
|
|
7794
|
+
return {
|
|
7795
|
+
cpuLoad,
|
|
7796
|
+
freeMemoryBytes,
|
|
7797
|
+
totalMemoryBytes,
|
|
7798
|
+
freeMemoryPercent,
|
|
7799
|
+
siblingSessions
|
|
7800
|
+
};
|
|
7801
|
+
} catch {
|
|
7802
|
+
return {
|
|
7803
|
+
cpuLoad: 0,
|
|
7804
|
+
freeMemoryBytes: (0, import_os7.totalmem)(),
|
|
7805
|
+
totalMemoryBytes: (0, import_os7.totalmem)(),
|
|
7806
|
+
freeMemoryPercent: 100,
|
|
7807
|
+
siblingSessions: 0
|
|
7808
|
+
};
|
|
7809
|
+
}
|
|
7810
|
+
}
|
|
7811
|
+
function checkHostLoadGate(config) {
|
|
7812
|
+
const gateConfig = config ?? parseGateConfig();
|
|
7813
|
+
const metrics = getHostMetrics();
|
|
7814
|
+
if (!gateConfig.enabled) {
|
|
7815
|
+
return {
|
|
7816
|
+
allowed: true,
|
|
7817
|
+
metrics
|
|
7818
|
+
};
|
|
7819
|
+
}
|
|
7820
|
+
if (gateConfig.cpuLoadThreshold >= 0 && metrics.cpuLoad > gateConfig.cpuLoadThreshold) {
|
|
7821
|
+
return {
|
|
7822
|
+
allowed: false,
|
|
7823
|
+
reason: `CPU load (${metrics.cpuLoad.toFixed(2)}) exceeds threshold (${gateConfig.cpuLoadThreshold.toFixed(2)})`,
|
|
7824
|
+
waitMs: gateConfig.checkIntervalMs,
|
|
7825
|
+
metrics
|
|
7826
|
+
};
|
|
7827
|
+
}
|
|
7828
|
+
if (gateConfig.freeMemoryThreshold >= 0 && metrics.freeMemoryBytes < gateConfig.freeMemoryThreshold) {
|
|
7829
|
+
const freeMemMB = (metrics.freeMemoryBytes / (1024 * 1024)).toFixed(0);
|
|
7830
|
+
const thresholdMB = (gateConfig.freeMemoryThreshold / (1024 * 1024)).toFixed(0);
|
|
7831
|
+
return {
|
|
7832
|
+
allowed: false,
|
|
7833
|
+
reason: `Free memory (${freeMemMB}MB) below threshold (${thresholdMB}MB)`,
|
|
7834
|
+
waitMs: gateConfig.checkIntervalMs,
|
|
7835
|
+
metrics
|
|
7836
|
+
};
|
|
7837
|
+
}
|
|
7838
|
+
if (gateConfig.maxSiblingSessions >= 0 && metrics.siblingSessions > gateConfig.maxSiblingSessions) {
|
|
7839
|
+
return {
|
|
7840
|
+
allowed: false,
|
|
7841
|
+
reason: `Too many sibling sessions (${metrics.siblingSessions}) exceeds max (${gateConfig.maxSiblingSessions})`,
|
|
7842
|
+
waitMs: gateConfig.checkIntervalMs,
|
|
7843
|
+
metrics
|
|
7844
|
+
};
|
|
7845
|
+
}
|
|
7846
|
+
return {
|
|
7847
|
+
allowed: true,
|
|
7848
|
+
metrics
|
|
7849
|
+
};
|
|
7850
|
+
}
|
|
7851
|
+
var import_os7, import_fs22, import_path23;
|
|
7852
|
+
var init_host_load_gate = __esm({
|
|
7853
|
+
"src/lib/host-load-gate.ts"() {
|
|
7854
|
+
"use strict";
|
|
7855
|
+
import_os7 = require("os");
|
|
7856
|
+
import_fs22 = require("fs");
|
|
7857
|
+
import_path23 = require("path");
|
|
7858
|
+
init_paths();
|
|
7859
|
+
}
|
|
7860
|
+
});
|
|
7861
|
+
|
|
7650
7862
|
// src/team/worker-launch-ack.ts
|
|
7651
7863
|
function buildWindowsSupervisorSource() {
|
|
7652
7864
|
return [
|
|
@@ -7724,7 +7936,11 @@ function isValidProviderEnvironment(value, platform = process.platform) {
|
|
|
7724
7936
|
return false;
|
|
7725
7937
|
}
|
|
7726
7938
|
}
|
|
7727
|
-
function
|
|
7939
|
+
function parseEnvPassthrough(value) {
|
|
7940
|
+
if (!value || value.trim().length === 0) return [];
|
|
7941
|
+
return value.split(",").map((k) => k.trim()).filter((k) => k.length > 0);
|
|
7942
|
+
}
|
|
7943
|
+
function buildProviderEnvironment(providerEnv, sourceEnv = process.env, platform = process.platform, envPassthrough) {
|
|
7728
7944
|
const normalized = normalizeProviderEnvironment(providerEnv, platform);
|
|
7729
7945
|
const baseline = {};
|
|
7730
7946
|
for (const key of SAFE_BASELINE_ENV_KEYS) {
|
|
@@ -7745,6 +7961,14 @@ function buildProviderEnvironment(providerEnv, sourceEnv = process.env, platform
|
|
|
7745
7961
|
const homeKey = platform === "win32" ? "USERPROFILE" : "HOME";
|
|
7746
7962
|
const home = platform === "win32" ? Object.entries(sourceEnv).find(([key]) => key.toUpperCase() === homeKey)?.[1] : sourceEnv[homeKey];
|
|
7747
7963
|
if (typeof home === "string" && home.length > 0) baseline[homeKey] = home;
|
|
7964
|
+
const passthroughList = envPassthrough ?? parseEnvPassthrough(sourceEnv.OMC_TEAM_WORKER_ENV_PASSTHROUGH);
|
|
7965
|
+
for (const key of passthroughList) {
|
|
7966
|
+
if (!isValidEnvironmentKey(key)) throw new Error("worker_launch_env_passthrough_key_invalid");
|
|
7967
|
+
if (WORKER_LAUNCH_INTERNAL_ENV_KEYS.has(key)) throw new Error("worker_launch_env_passthrough_key_reserved");
|
|
7968
|
+
if (platform === "win32" && WINDOWS_RESERVED_ENV_KEYS.has(key.toUpperCase())) throw new Error("worker_launch_env_passthrough_key_reserved");
|
|
7969
|
+
const value = sourceEnv[key];
|
|
7970
|
+
if (typeof value === "string") baseline[key] = value;
|
|
7971
|
+
}
|
|
7748
7972
|
if (platform === "win32") {
|
|
7749
7973
|
for (const key of Object.keys(normalized)) {
|
|
7750
7974
|
const baselineKey = Object.keys(baseline).find((candidate) => candidate.toUpperCase() === key.toUpperCase());
|
|
@@ -8993,6 +9217,9 @@ async function runWorkerLaunchBootstrap(value) {
|
|
|
8993
9217
|
return { outcome: "provider_spawn_failed" };
|
|
8994
9218
|
}
|
|
8995
9219
|
}
|
|
9220
|
+
const gateResult = checkHostLoadGate();
|
|
9221
|
+
if (!gateResult.allowed && gateResult.reason) {
|
|
9222
|
+
}
|
|
8996
9223
|
const child = (0, import_node_child_process2.spawn)(invocation.command, invocation.args, {
|
|
8997
9224
|
cwd: spec.cwd,
|
|
8998
9225
|
env: providerEnv,
|
|
@@ -9510,6 +9737,7 @@ var init_worker_launch_ack = __esm({
|
|
|
9510
9737
|
init_state_paths();
|
|
9511
9738
|
init_atomic_write();
|
|
9512
9739
|
init_file_lock();
|
|
9740
|
+
init_host_load_gate();
|
|
9513
9741
|
WORKER_LAUNCH_SCHEMA_VERSION = 1;
|
|
9514
9742
|
DEFAULT_ACK_TIMEOUT_MS = 8e3;
|
|
9515
9743
|
DEFAULT_POLL_INTERVAL_MS = 25;
|
|
@@ -9575,7 +9803,7 @@ function sha256(value) {
|
|
|
9575
9803
|
}
|
|
9576
9804
|
function parseCanonical(path5) {
|
|
9577
9805
|
try {
|
|
9578
|
-
const text = (0,
|
|
9806
|
+
const text = (0, import_fs23.readFileSync)(path5, "utf8");
|
|
9579
9807
|
const parsed = JSON.parse(text);
|
|
9580
9808
|
return canonicalize2(parsed) === text ? parsed : null;
|
|
9581
9809
|
} catch {
|
|
@@ -9592,19 +9820,19 @@ function finalPath(cwd, requestId) {
|
|
|
9592
9820
|
}
|
|
9593
9821
|
function phaseDirectory(cwd, requestId) {
|
|
9594
9822
|
assertSafeRecoveryRequestId(requestId);
|
|
9595
|
-
return (0,
|
|
9823
|
+
return (0, import_path24.join)((0, import_path24.dirname)(reservationPath(cwd, requestId)), "phases", requestId);
|
|
9596
9824
|
}
|
|
9597
9825
|
function publishImmutable(target, value) {
|
|
9598
9826
|
const bytes = canonicalize2(value);
|
|
9599
|
-
(0,
|
|
9600
|
-
const temp = (0,
|
|
9601
|
-
(0,
|
|
9827
|
+
(0, import_fs23.mkdirSync)((0, import_path24.dirname)(target), { recursive: true, mode: 448 });
|
|
9828
|
+
const temp = (0, import_path24.join)((0, import_path24.dirname)(target), `.${(0, import_crypto6.randomUUID)()}.tmp`);
|
|
9829
|
+
(0, import_fs23.writeFileSync)(temp, bytes, { encoding: "utf8", mode: 384, flush: true });
|
|
9602
9830
|
try {
|
|
9603
|
-
(0,
|
|
9831
|
+
(0, import_fs23.linkSync)(temp, target);
|
|
9604
9832
|
} catch (error) {
|
|
9605
9833
|
const existing = parseCanonical(target);
|
|
9606
9834
|
try {
|
|
9607
|
-
(0,
|
|
9835
|
+
(0, import_fs23.unlinkSync)(temp);
|
|
9608
9836
|
} catch {
|
|
9609
9837
|
}
|
|
9610
9838
|
if (existing && canonicalize2(existing) === bytes) return existing;
|
|
@@ -9612,18 +9840,18 @@ function publishImmutable(target, value) {
|
|
|
9612
9840
|
}
|
|
9613
9841
|
const published = parseCanonical(target);
|
|
9614
9842
|
if (!published || canonicalize2(published) !== bytes) throw new Error("immutable_recovery_record_verification_failed");
|
|
9615
|
-
(0,
|
|
9843
|
+
(0, import_fs23.unlinkSync)(temp);
|
|
9616
9844
|
return published;
|
|
9617
9845
|
}
|
|
9618
9846
|
function replaceDerivedIndex(target, value) {
|
|
9619
9847
|
const bytes = canonicalize2(value);
|
|
9620
|
-
(0,
|
|
9621
|
-
const temp = (0,
|
|
9622
|
-
(0,
|
|
9848
|
+
(0, import_fs23.mkdirSync)((0, import_path24.dirname)(target), { recursive: true, mode: 448 });
|
|
9849
|
+
const temp = (0, import_path24.join)((0, import_path24.dirname)(target), `.${(0, import_crypto6.randomUUID)()}.repair.tmp`);
|
|
9850
|
+
(0, import_fs23.writeFileSync)(temp, bytes, { encoding: "utf8", mode: 384, flush: true });
|
|
9623
9851
|
try {
|
|
9624
|
-
(0,
|
|
9852
|
+
(0, import_fs23.renameSync)(temp, target);
|
|
9625
9853
|
} finally {
|
|
9626
|
-
if ((0,
|
|
9854
|
+
if ((0, import_fs23.existsSync)(temp)) (0, import_fs23.unlinkSync)(temp);
|
|
9627
9855
|
}
|
|
9628
9856
|
const repaired = parseCanonical(target);
|
|
9629
9857
|
if (!repaired || canonicalize2(repaired) !== bytes) throw new Error("immutable_recovery_record_verification_failed");
|
|
@@ -9663,7 +9891,7 @@ function resolveCanonicalRecoveryRequestId(cwd, requestId) {
|
|
|
9663
9891
|
visited.add(currentRequestId);
|
|
9664
9892
|
const reservation = readRecoveryRequestReservation(cwd, currentRequestId);
|
|
9665
9893
|
if (!reservation) {
|
|
9666
|
-
if (alias || (0,
|
|
9894
|
+
if (alias || (0, import_fs23.existsSync)(reservationPath(cwd, currentRequestId))) return null;
|
|
9667
9895
|
return currentRequestId;
|
|
9668
9896
|
}
|
|
9669
9897
|
if (alias && !hasMatchingReservationTuple(alias, reservation)) return null;
|
|
@@ -9685,7 +9913,7 @@ function writeRecoveryPhase(cwd, phase) {
|
|
|
9685
9913
|
throw new Error("invalid_persisted_state");
|
|
9686
9914
|
}
|
|
9687
9915
|
const sequence = `${Date.now().toString().padStart(16, "0")}-${process.hrtime.bigint().toString().padStart(20, "0")}-${(0, import_crypto6.randomUUID)()}.json`;
|
|
9688
|
-
return publishImmutable((0,
|
|
9916
|
+
return publishImmutable((0, import_path24.join)(phaseDirectory(cwd, phase.request_id), sequence), { ...phase, schema_version: 1, kind: "phase", updated_at: phase.updated_at || (/* @__PURE__ */ new Date()).toISOString() });
|
|
9689
9917
|
}
|
|
9690
9918
|
function writeRecoveryFinal(cwd, outcome) {
|
|
9691
9919
|
const reservation = readRecoveryRequestReservation(cwd, outcome.request_id);
|
|
@@ -9710,9 +9938,9 @@ function latestPhase(cwd, requestId) {
|
|
|
9710
9938
|
if (!reservation || reservation.kind !== "reservation") return null;
|
|
9711
9939
|
const directory = phaseDirectory(cwd, requestId);
|
|
9712
9940
|
try {
|
|
9713
|
-
const candidates = (0,
|
|
9941
|
+
const candidates = (0, import_fs23.readdirSync)(directory).filter((file) => file.endsWith(".json")).sort().reverse();
|
|
9714
9942
|
if (candidates.length === 0) return null;
|
|
9715
|
-
const phase = parseCanonical((0,
|
|
9943
|
+
const phase = parseCanonical((0, import_path24.join)(directory, candidates[0]));
|
|
9716
9944
|
return isValidRecoveryPhase(phase, reservation) ? phase : null;
|
|
9717
9945
|
} catch {
|
|
9718
9946
|
}
|
|
@@ -9742,7 +9970,7 @@ function isValidRecoveryResult(value) {
|
|
|
9742
9970
|
}
|
|
9743
9971
|
function readRecoveryFinalState(cwd, requestId) {
|
|
9744
9972
|
const path5 = finalPath(cwd, requestId);
|
|
9745
|
-
if (!(0,
|
|
9973
|
+
if (!(0, import_fs23.existsSync)(path5)) return { kind: "missing" };
|
|
9746
9974
|
const final = parseCanonical(path5);
|
|
9747
9975
|
if (!final || final.schema_version !== 1 || final.kind !== "final" || !isMatchingRecoveryFinal(final, { requestId })) {
|
|
9748
9976
|
return { kind: "invalid" };
|
|
@@ -9752,11 +9980,11 @@ function readRecoveryFinalState(cwd, requestId) {
|
|
|
9752
9980
|
const byTeam = absPath(cwd, TeamPaths.recoveryResultByTeam(reservation.workspace_hash, final.team_name, final.recovery_id));
|
|
9753
9981
|
try {
|
|
9754
9982
|
const expectedBytes = canonicalize2(final);
|
|
9755
|
-
const indexed = (0,
|
|
9983
|
+
const indexed = (0, import_fs23.existsSync)(byTeam) ? parseCanonical(byTeam) : null;
|
|
9756
9984
|
if (!indexed || canonicalize2(indexed) !== expectedBytes) {
|
|
9757
9985
|
const lockPath = absPath(cwd, TeamPaths.recoveryFinalIndexLock(reservation.workspace_hash, final.team_name, final.recovery_id));
|
|
9758
9986
|
withProcessIdentityFileLockSync(lockPath, () => {
|
|
9759
|
-
const current = (0,
|
|
9987
|
+
const current = (0, import_fs23.existsSync)(byTeam) ? parseCanonical(byTeam) : null;
|
|
9760
9988
|
if (!current || canonicalize2(current) !== expectedBytes) replaceDerivedIndex(byTeam, final);
|
|
9761
9989
|
});
|
|
9762
9990
|
}
|
|
@@ -9788,13 +10016,13 @@ function readRecoveryOutcome(cwd, requestId) {
|
|
|
9788
10016
|
if (final.kind === "invalid") return null;
|
|
9789
10017
|
return latestPhase(cwd, canonicalRequestId);
|
|
9790
10018
|
}
|
|
9791
|
-
var import_crypto6,
|
|
10019
|
+
var import_crypto6, import_fs23, import_path24, RETENTION_MS, MAX_RECOVERY_ALIAS_DEPTH, RECOVERY_ERRORS, RECOVERY_WARNINGS;
|
|
9792
10020
|
var init_recovery_request_store = __esm({
|
|
9793
10021
|
"src/team/recovery-request-store.ts"() {
|
|
9794
10022
|
"use strict";
|
|
9795
10023
|
import_crypto6 = require("crypto");
|
|
9796
|
-
|
|
9797
|
-
|
|
10024
|
+
import_fs23 = require("fs");
|
|
10025
|
+
import_path24 = require("path");
|
|
9798
10026
|
init_types3();
|
|
9799
10027
|
init_state_paths();
|
|
9800
10028
|
init_process_identity_lock();
|
|
@@ -9939,6 +10167,7 @@ __export(tmux_session_exports, {
|
|
|
9939
10167
|
spawnWorkerInPane: () => spawnWorkerInPane,
|
|
9940
10168
|
splitTeamWorkerPane: () => splitTeamWorkerPane,
|
|
9941
10169
|
splitTeamWorkerPaneWithEvidence: () => splitTeamWorkerPaneWithEvidence,
|
|
10170
|
+
strictIdentityUnavailableError: () => strictIdentityUnavailableError,
|
|
9942
10171
|
validateTmux: () => validateTmux,
|
|
9943
10172
|
verifyTeamTargetOwnership: () => verifyTeamTargetOwnership,
|
|
9944
10173
|
waitForPaneReady: () => waitForPaneReady,
|
|
@@ -9950,7 +10179,7 @@ function tmuxArgsForIdentity(identity, args) {
|
|
|
9950
10179
|
return ["-S", identity.socket_path, ...args];
|
|
9951
10180
|
}
|
|
9952
10181
|
function buildDetachedTmuxServerKeepaliveArgs(socketPath) {
|
|
9953
|
-
if (!(0,
|
|
10182
|
+
if (!(0, import_path25.isAbsolute)(socketPath) && !import_path25.win32.isAbsolute(socketPath)) {
|
|
9954
10183
|
throw new Error("tmux_private_socket_path_not_absolute");
|
|
9955
10184
|
}
|
|
9956
10185
|
return [
|
|
@@ -9966,8 +10195,8 @@ function buildDetachedTmuxServerKeepaliveArgs(socketPath) {
|
|
|
9966
10195
|
}
|
|
9967
10196
|
function buildPrivateTmuxSocketPath() {
|
|
9968
10197
|
if (isPsmux()) return buildPsmuxNamespacePath();
|
|
9969
|
-
const socketDirectory = process.platform === "darwin" || process.platform === "linux" ? "/tmp" : (0,
|
|
9970
|
-
const socketPath = (0,
|
|
10198
|
+
const socketDirectory = process.platform === "darwin" || process.platform === "linux" ? "/tmp" : (0, import_os8.tmpdir)();
|
|
10199
|
+
const socketPath = (0, import_path25.join)(
|
|
9971
10200
|
socketDirectory,
|
|
9972
10201
|
`o-${process.pid.toString(36)}-${Date.now().toString(36)}-${(0, import_crypto7.randomUUID)().slice(0, 8)}.sock`
|
|
9973
10202
|
);
|
|
@@ -9989,19 +10218,19 @@ function resolveTmuxServerGuardRuntime() {
|
|
|
9989
10218
|
} catch {
|
|
9990
10219
|
throw new Error("tmux_server_guard_runtime_path_unavailable");
|
|
9991
10220
|
}
|
|
9992
|
-
if (!(0,
|
|
10221
|
+
if (!(0, import_path25.isAbsolute)(runtimePath) && !import_path25.win32.isAbsolute(runtimePath) || !isRegularFile(runtimePath)) {
|
|
9993
10222
|
throw new Error("tmux_server_guard_runtime_path_unavailable");
|
|
9994
10223
|
}
|
|
9995
10224
|
const nodePath = process.execPath;
|
|
9996
|
-
if (!(0,
|
|
10225
|
+
if (!(0, import_path25.isAbsolute)(nodePath) && !import_path25.win32.isAbsolute(nodePath) || !isRegularFile(nodePath)) {
|
|
9997
10226
|
throw new Error("tmux_server_guard_node_path_unavailable");
|
|
9998
10227
|
}
|
|
9999
10228
|
return { nodePath, runtimePath };
|
|
10000
10229
|
}
|
|
10001
10230
|
function isRegularFile(path5) {
|
|
10002
|
-
if (!(0,
|
|
10231
|
+
if (!(0, import_fs24.existsSync)(path5)) return false;
|
|
10003
10232
|
try {
|
|
10004
|
-
return (0,
|
|
10233
|
+
return (0, import_fs24.statSync)(path5).isFile();
|
|
10005
10234
|
} catch {
|
|
10006
10235
|
return false;
|
|
10007
10236
|
}
|
|
@@ -10033,6 +10262,13 @@ function parseTmuxServerFields(output) {
|
|
|
10033
10262
|
function buildTmuxServerIdentity(socketPath, pid, processIdentity) {
|
|
10034
10263
|
const processStartedAt = processIdentity(pid);
|
|
10035
10264
|
if (!processStartedAt || !isValidStrictProcessStartIdentity(processStartedAt)) return null;
|
|
10265
|
+
if (process.platform === "win32") {
|
|
10266
|
+
try {
|
|
10267
|
+
process.kill(pid, 0);
|
|
10268
|
+
} catch {
|
|
10269
|
+
return null;
|
|
10270
|
+
}
|
|
10271
|
+
}
|
|
10036
10272
|
const identity = {
|
|
10037
10273
|
socket_path: socketPath,
|
|
10038
10274
|
server_pid: pid,
|
|
@@ -10085,17 +10321,26 @@ async function captureTmuxServerIdentity(selectedEndpoint, dependencies = {}) {
|
|
|
10085
10321
|
async function observeTmuxServerIdentity(expected, dependencies = {}) {
|
|
10086
10322
|
const deps = { ...defaultTmuxServerIdentityDependencies, ...dependencies };
|
|
10087
10323
|
if (!isValidTmuxServerIdentity(expected) || !isValidStrictProcessStartIdentity(expected.process_started_at)) return "unknown";
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10324
|
+
const singleWindowsProbe = process.platform === "win32" && dependencies.processObservation === void 0;
|
|
10325
|
+
if (singleWindowsProbe) {
|
|
10326
|
+
try {
|
|
10327
|
+
process.kill(expected.server_pid, 0);
|
|
10328
|
+
} catch (error) {
|
|
10329
|
+
return error.code === "ESRCH" ? "dead" : "unknown";
|
|
10330
|
+
}
|
|
10331
|
+
} else {
|
|
10332
|
+
let processState;
|
|
10333
|
+
try {
|
|
10334
|
+
processState = deps.processObservation({
|
|
10335
|
+
server_pid: expected.server_pid,
|
|
10336
|
+
process_started_at: expected.process_started_at
|
|
10337
|
+
});
|
|
10338
|
+
} catch {
|
|
10339
|
+
return "unknown";
|
|
10340
|
+
}
|
|
10341
|
+
if (processState === "dead") return "dead";
|
|
10342
|
+
if (processState !== "matching") return "unknown";
|
|
10096
10343
|
}
|
|
10097
|
-
if (processState === "dead") return "dead";
|
|
10098
|
-
if (processState !== "matching") return "unknown";
|
|
10099
10344
|
try {
|
|
10100
10345
|
const result = await deps.tmuxQuery(
|
|
10101
10346
|
tmuxArgsForIdentity(expected, ["display-message", "-p", "#{pid}"]),
|
|
@@ -10107,7 +10352,15 @@ async function observeTmuxServerIdentity(expected, dependencies = {}) {
|
|
|
10107
10352
|
const actualPid = parseExactPositivePid(lines[0]);
|
|
10108
10353
|
if (actualPid !== expected.server_pid) return "unknown";
|
|
10109
10354
|
const actualStart = deps.processIdentity(actualPid);
|
|
10355
|
+
if (singleWindowsProbe && actualStart && isValidStrictProcessStartIdentity(actualStart) && actualStart !== expected.process_started_at) return "dead";
|
|
10110
10356
|
if (!actualStart || actualStart !== expected.process_started_at) return "unknown";
|
|
10357
|
+
if (singleWindowsProbe) {
|
|
10358
|
+
try {
|
|
10359
|
+
process.kill(actualPid, 0);
|
|
10360
|
+
} catch (error) {
|
|
10361
|
+
return error.code === "ESRCH" ? "dead" : "unknown";
|
|
10362
|
+
}
|
|
10363
|
+
}
|
|
10111
10364
|
return "matching";
|
|
10112
10365
|
} catch {
|
|
10113
10366
|
return "unknown";
|
|
@@ -10615,7 +10868,7 @@ function getDefaultShell() {
|
|
|
10615
10868
|
return process.env.COMSPEC || "cmd.exe";
|
|
10616
10869
|
}
|
|
10617
10870
|
const shell = process.env.SHELL || "/bin/bash";
|
|
10618
|
-
const name = (0,
|
|
10871
|
+
const name = (0, import_path25.basename)(shell.replace(/\\/g, "/")).replace(/\.(exe|cmd|bat)$/i, "");
|
|
10619
10872
|
if (!SUPPORTED_POSIX_SHELLS.has(name)) {
|
|
10620
10873
|
return "/bin/sh";
|
|
10621
10874
|
}
|
|
@@ -10625,7 +10878,7 @@ function pathEntries(envPath) {
|
|
|
10625
10878
|
return (envPath ?? "").split(process.platform === "win32" ? ";" : ":").map((entry) => entry.trim()).filter(Boolean);
|
|
10626
10879
|
}
|
|
10627
10880
|
function pathCandidateNames(candidatePath) {
|
|
10628
|
-
const base = (0,
|
|
10881
|
+
const base = (0, import_path25.basename)(candidatePath.replace(/\\/g, "/"));
|
|
10629
10882
|
const bare = base.replace(/\.(exe|cmd|bat)$/i, "");
|
|
10630
10883
|
if (process.platform === "win32") {
|
|
10631
10884
|
return Array.from(/* @__PURE__ */ new Set([`${bare}.exe`, `${bare}.cmd`, `${bare}.bat`, bare]));
|
|
@@ -10635,15 +10888,15 @@ function pathCandidateNames(candidatePath) {
|
|
|
10635
10888
|
function resolveShellFromPath(candidatePath) {
|
|
10636
10889
|
for (const dir of pathEntries(process.env.PATH)) {
|
|
10637
10890
|
for (const name of pathCandidateNames(candidatePath)) {
|
|
10638
|
-
const full = (0,
|
|
10639
|
-
if ((0,
|
|
10891
|
+
const full = (0, import_path25.join)(dir, name);
|
|
10892
|
+
if ((0, import_fs24.existsSync)(full)) return full;
|
|
10640
10893
|
}
|
|
10641
10894
|
}
|
|
10642
10895
|
return null;
|
|
10643
10896
|
}
|
|
10644
10897
|
function resolveShellFromCandidates(paths, rcFile) {
|
|
10645
10898
|
for (const p of paths) {
|
|
10646
|
-
if ((0,
|
|
10899
|
+
if ((0, import_fs24.existsSync)(p)) return { shell: p, rcFile };
|
|
10647
10900
|
const resolvedFromPath = resolveShellFromPath(p);
|
|
10648
10901
|
if (resolvedFromPath) return { shell: resolvedFromPath, rcFile };
|
|
10649
10902
|
}
|
|
@@ -10651,9 +10904,9 @@ function resolveShellFromCandidates(paths, rcFile) {
|
|
|
10651
10904
|
}
|
|
10652
10905
|
function resolveSupportedShellAffinity(shellPath2) {
|
|
10653
10906
|
if (!shellPath2) return null;
|
|
10654
|
-
const name = (0,
|
|
10907
|
+
const name = (0, import_path25.basename)(shellPath2.replace(/\\/g, "/")).replace(/\.(exe|cmd|bat)$/i, "");
|
|
10655
10908
|
if (name !== "zsh" && name !== "bash") return null;
|
|
10656
|
-
if (!(0,
|
|
10909
|
+
if (!(0, import_fs24.existsSync)(shellPath2)) return null;
|
|
10657
10910
|
const home = process.env.HOME ?? "";
|
|
10658
10911
|
const rcFile = home ? `${home}/.${name}rc` : null;
|
|
10659
10912
|
return { shell: shellPath2, rcFile };
|
|
@@ -10686,7 +10939,7 @@ function logWorkerSpawnDiagnostic(message) {
|
|
|
10686
10939
|
`);
|
|
10687
10940
|
}
|
|
10688
10941
|
function paneCurrentCommandLooksReady(command) {
|
|
10689
|
-
const normalized = (0,
|
|
10942
|
+
const normalized = (0, import_path25.basename)(command.replace(/\\/g, "/")).replace(/\.(exe|cmd|bat)$/i, "").toLowerCase();
|
|
10690
10943
|
return SUPPORTED_POSIX_SHELLS.has(normalized) || ["cmd", "powershell", "pwsh", "nu", "elvish"].includes(normalized);
|
|
10691
10944
|
}
|
|
10692
10945
|
async function getPaneCurrentCommandStatus(paneId, tmuxServerIdentity) {
|
|
@@ -10820,7 +11073,7 @@ function assertSafeCmdValue2(value) {
|
|
|
10820
11073
|
if (/[\r\n\0]/.test(value)) throw new Error("Invalid Windows command value: contains CR, LF, or NUL");
|
|
10821
11074
|
}
|
|
10822
11075
|
function shellNameFromPath(shellPath2) {
|
|
10823
|
-
const shellName = (0,
|
|
11076
|
+
const shellName = (0, import_path25.basename)(shellPath2.replace(/\\/g, "/"));
|
|
10824
11077
|
return shellName.replace(/\.(exe|cmd|bat)$/i, "");
|
|
10825
11078
|
}
|
|
10826
11079
|
function shellEscape(value) {
|
|
@@ -10832,7 +11085,7 @@ function assertSafeEnvKey(key) {
|
|
|
10832
11085
|
}
|
|
10833
11086
|
}
|
|
10834
11087
|
function isAbsoluteLaunchBinaryPath(value) {
|
|
10835
|
-
return (0,
|
|
11088
|
+
return (0, import_path25.isAbsolute)(value) || import_path25.win32.isAbsolute(value);
|
|
10836
11089
|
}
|
|
10837
11090
|
function assertSafeLaunchBinary(launchBinary) {
|
|
10838
11091
|
if (launchBinary.trim().length === 0) {
|
|
@@ -10866,11 +11119,13 @@ function buildWorkerStartCommand(config) {
|
|
|
10866
11119
|
const providerLaunchWords = getLaunchWords(config);
|
|
10867
11120
|
const launchWords = config.launchAttempt ? [process.execPath, config.launchAttempt.runtimeCliPath, "--worker-launch"] : providerLaunchWords;
|
|
10868
11121
|
const envVars = config.launchAttempt ? {
|
|
10869
|
-
...config.envVars,
|
|
10870
11122
|
// Supervised launches carry the attempt-owned bootstrap descriptor by
|
|
10871
11123
|
// path (never inline): secrets stay out of the process list and tmux
|
|
10872
11124
|
// scrollback, and the delivered command stays small. The runtime CLI
|
|
10873
11125
|
// validates and consumes the descriptor before running the provider.
|
|
11126
|
+
// Team identity (team_name, worker_name, provider, instance_id) is read
|
|
11127
|
+
// from the descriptor, not from environment vars, keeping the typed
|
|
11128
|
+
// command under 1024 bytes even with long cwd paths.
|
|
10874
11129
|
OMC_WORKER_LAUNCH_SPEC_FILE: config.launchAttempt.bootstrapDescriptorPath
|
|
10875
11130
|
} : config.envVars;
|
|
10876
11131
|
const shouldSourceRc = process.env.OMC_TEAM_NO_RC !== "1";
|
|
@@ -11160,6 +11415,17 @@ async function splitTeamWorkerPaneWithEvidence(splitTarget, direction, cwd, prov
|
|
|
11160
11415
|
async function splitTeamWorkerPane(splitTarget, direction, cwd) {
|
|
11161
11416
|
return (await splitTeamWorkerPaneWithEvidence(splitTarget, direction, cwd)).paneId;
|
|
11162
11417
|
}
|
|
11418
|
+
function strictIdentityUnavailableError(platform, loadNative = getNativeContainedFs) {
|
|
11419
|
+
if (platform === "darwin") {
|
|
11420
|
+
try {
|
|
11421
|
+
loadNative();
|
|
11422
|
+
} catch (cause) {
|
|
11423
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
11424
|
+
return new Error(`tmux_server_identity_probe_unavailable: ${detail}`, { cause });
|
|
11425
|
+
}
|
|
11426
|
+
}
|
|
11427
|
+
return new Error("tmux_server_identity_probe_unavailable");
|
|
11428
|
+
}
|
|
11163
11429
|
async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
11164
11430
|
const multiplexerContext = isPsmux() ? "none" : detectTeamMultiplexerContext();
|
|
11165
11431
|
const inTmux = multiplexerContext === "tmux";
|
|
@@ -11169,7 +11435,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
11169
11435
|
validateTmux();
|
|
11170
11436
|
}
|
|
11171
11437
|
if (!inCmux && !currentStrictProcessStartIdentity()) {
|
|
11172
|
-
throw
|
|
11438
|
+
throw strictIdentityUnavailableError(process.platform);
|
|
11173
11439
|
}
|
|
11174
11440
|
let tmuxServerIdentity;
|
|
11175
11441
|
let freshDetachedServerIdentity;
|
|
@@ -11219,7 +11485,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
11219
11485
|
"-d",
|
|
11220
11486
|
"-P",
|
|
11221
11487
|
"-F",
|
|
11222
|
-
"#S
|
|
11488
|
+
"#S:#{window_index} #{pane_id} #{socket_path} #{pid}",
|
|
11223
11489
|
"-s",
|
|
11224
11490
|
detachedSessionName,
|
|
11225
11491
|
"-c",
|
|
@@ -11913,7 +12179,7 @@ async function spawnWorkerInPane(sessionName2, paneId, config) {
|
|
|
11913
12179
|
if (config.launchAttempt) {
|
|
11914
12180
|
await revokeWorkerLaunchAttempt(config.launchAttempt, "launch_failed").catch(() => void 0);
|
|
11915
12181
|
}
|
|
11916
|
-
if (config.launchAttempt && (!materializedTransport || (0,
|
|
12182
|
+
if (config.launchAttempt && (!materializedTransport || (0, import_fs24.existsSync)(materializedTransport.bootstrapDescriptorPath))) {
|
|
11917
12183
|
const cleaned = await cleanupWorkerLaunchTransport(config.launchAttempt, "launch_failed").catch(() => false);
|
|
11918
12184
|
if (!cleaned) {
|
|
11919
12185
|
logWorkerSpawnDiagnostic(
|
|
@@ -12734,7 +13000,7 @@ function parseDedicatedWindowTarget(sessionName2) {
|
|
|
12734
13000
|
}
|
|
12735
13001
|
function normalizeDetachedSessionTarget(sessionName2) {
|
|
12736
13002
|
const detachedTarget = sessionName2.includes(":") ? parseDedicatedWindowTarget(sessionName2) : null;
|
|
12737
|
-
const sessionTarget = detachedTarget ? detachedTarget.
|
|
13003
|
+
const sessionTarget = detachedTarget ? detachedTarget.sessionName : sessionName2;
|
|
12738
13004
|
return sessionTarget && /^[^\s:]+$/.test(sessionTarget) ? sessionTarget : null;
|
|
12739
13005
|
}
|
|
12740
13006
|
async function resolveSplitPaneWorkerPaneIds(_sessionName, recordedPaneIds, leaderPaneId) {
|
|
@@ -12892,20 +13158,21 @@ async function killTeamSession(sessionName2, workerPaneIds, leaderPaneId, option
|
|
|
12892
13158
|
if (result.outcome === "executed") return true;
|
|
12893
13159
|
return await observeTmuxServerIdentity(identity) === "dead";
|
|
12894
13160
|
}
|
|
12895
|
-
var
|
|
13161
|
+
var import_fs24, import_crypto7, import_child_process7, import_util3, import_path25, import_os8, sleep3, execFileAsync2, TMUX_SESSION_PREFIX, defaultTmuxServerIdentityDependencies, guardMarkerCounter, TMUX_MAILBOX_PANE_ID, TMUX_MAILBOX_TARGET, defaultMailboxTargetOwnershipDependencies, defaultDirectMailboxEffectDependencies, TeamSessionCreationError, SUPPORTED_POSIX_SHELLS, ZSH_CANDIDATES, BASH_CANDIDATES, DANGEROUS_LAUNCH_BINARY_CHARS;
|
|
12896
13162
|
var init_tmux_session = __esm({
|
|
12897
13163
|
"src/team/tmux-session.ts"() {
|
|
12898
13164
|
"use strict";
|
|
12899
|
-
|
|
13165
|
+
import_fs24 = require("fs");
|
|
12900
13166
|
import_crypto7 = require("crypto");
|
|
12901
13167
|
import_child_process7 = require("child_process");
|
|
12902
13168
|
import_util3 = require("util");
|
|
12903
|
-
|
|
12904
|
-
|
|
13169
|
+
import_path25 = require("path");
|
|
13170
|
+
import_os8 = require("os");
|
|
12905
13171
|
init_team_name();
|
|
12906
13172
|
init_tmux_utils();
|
|
12907
13173
|
init_types3();
|
|
12908
13174
|
init_team_owner_epoch();
|
|
13175
|
+
init_native_contained_fs();
|
|
12909
13176
|
init_pane_readiness();
|
|
12910
13177
|
init_worker_launch_ack();
|
|
12911
13178
|
init_runtime_owner_client();
|
|
@@ -12963,23 +13230,23 @@ var init_tmux_session = __esm({
|
|
|
12963
13230
|
// src/agents/prompt-helpers.ts
|
|
12964
13231
|
function getPackageDir3() {
|
|
12965
13232
|
if (typeof __dirname !== "undefined" && __dirname) {
|
|
12966
|
-
const currentDirName = (0,
|
|
12967
|
-
const parentDirName = (0,
|
|
13233
|
+
const currentDirName = (0, import_path26.basename)(__dirname);
|
|
13234
|
+
const parentDirName = (0, import_path26.basename)((0, import_path26.dirname)(__dirname));
|
|
12968
13235
|
if (currentDirName === "bridge") {
|
|
12969
|
-
return (0,
|
|
13236
|
+
return (0, import_path26.join)(__dirname, "..");
|
|
12970
13237
|
}
|
|
12971
13238
|
if (currentDirName === "agents" && (parentDirName === "src" || parentDirName === "dist")) {
|
|
12972
|
-
return (0,
|
|
13239
|
+
return (0, import_path26.join)(__dirname, "..", "..");
|
|
12973
13240
|
}
|
|
12974
13241
|
}
|
|
12975
13242
|
try {
|
|
12976
13243
|
const __filename = (0, import_url4.fileURLToPath)(importMetaUrl);
|
|
12977
|
-
const __dirname2 = (0,
|
|
12978
|
-
const currentDirName = (0,
|
|
13244
|
+
const __dirname2 = (0, import_path26.dirname)(__filename);
|
|
13245
|
+
const currentDirName = (0, import_path26.basename)(__dirname2);
|
|
12979
13246
|
if (currentDirName === "bridge") {
|
|
12980
|
-
return (0,
|
|
13247
|
+
return (0, import_path26.join)(__dirname2, "..");
|
|
12981
13248
|
}
|
|
12982
|
-
return (0,
|
|
13249
|
+
return (0, import_path26.join)(__dirname2, "..", "..");
|
|
12983
13250
|
} catch {
|
|
12984
13251
|
}
|
|
12985
13252
|
return process.cwd();
|
|
@@ -12994,9 +13261,9 @@ function getValidAgentRoles() {
|
|
|
12994
13261
|
} catch {
|
|
12995
13262
|
}
|
|
12996
13263
|
try {
|
|
12997
|
-
const agentsDir = (0,
|
|
12998
|
-
const files = (0,
|
|
12999
|
-
_cachedRoles = files.filter((f) => f.endsWith(".md")).map((f) => (0,
|
|
13264
|
+
const agentsDir = (0, import_path26.join)(getPackageDir3(), "agents");
|
|
13265
|
+
const files = (0, import_fs25.readdirSync)(agentsDir);
|
|
13266
|
+
_cachedRoles = files.filter((f) => f.endsWith(".md")).map((f) => (0, import_path26.basename)(f, ".md")).sort();
|
|
13000
13267
|
} catch (err) {
|
|
13001
13268
|
console.error("[prompt-injection] CRITICAL: Could not scan agents/ directory for role discovery:", err);
|
|
13002
13269
|
_cachedRoles = [];
|
|
@@ -13015,12 +13282,12 @@ function sanitizePromptContent(content, maxLength = 4e3) {
|
|
|
13015
13282
|
sanitized = sanitized.replace(/<(\/?)(system-instructions|system-reminder|TASK_SUBJECT|TASK_DESCRIPTION|INBOX_MESSAGE)(?=[\s>/])[^>]*>/gi, "[$1$2]");
|
|
13016
13283
|
return sanitized;
|
|
13017
13284
|
}
|
|
13018
|
-
var
|
|
13285
|
+
var import_fs25, import_path26, import_url4, _cachedRoles, VALID_AGENT_ROLES;
|
|
13019
13286
|
var init_prompt_helpers = __esm({
|
|
13020
13287
|
"src/agents/prompt-helpers.ts"() {
|
|
13021
13288
|
"use strict";
|
|
13022
|
-
|
|
13023
|
-
|
|
13289
|
+
import_fs25 = require("fs");
|
|
13290
|
+
import_path26 = require("path");
|
|
13024
13291
|
import_url4 = require("url");
|
|
13025
13292
|
init_utils();
|
|
13026
13293
|
init_strict_mode_guidance();
|
|
@@ -13031,54 +13298,54 @@ var init_prompt_helpers = __esm({
|
|
|
13031
13298
|
|
|
13032
13299
|
// src/team/fs-utils.ts
|
|
13033
13300
|
function atomicWriteJson2(filePath, data, mode = 384) {
|
|
13034
|
-
const dir = (0,
|
|
13035
|
-
if (!(0,
|
|
13301
|
+
const dir = (0, import_path27.dirname)(filePath);
|
|
13302
|
+
if (!(0, import_fs26.existsSync)(dir)) (0, import_fs26.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
13036
13303
|
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
13037
|
-
(0,
|
|
13038
|
-
(0,
|
|
13304
|
+
(0, import_fs26.writeFileSync)(tmpPath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode });
|
|
13305
|
+
(0, import_fs26.renameSync)(tmpPath, filePath);
|
|
13039
13306
|
}
|
|
13040
13307
|
function ensureDirWithMode(dirPath, mode = 448) {
|
|
13041
|
-
if (!(0,
|
|
13308
|
+
if (!(0, import_fs26.existsSync)(dirPath)) (0, import_fs26.mkdirSync)(dirPath, { recursive: true, mode });
|
|
13042
13309
|
}
|
|
13043
13310
|
function safeRealpath(p) {
|
|
13044
13311
|
try {
|
|
13045
|
-
return (0,
|
|
13312
|
+
return (0, import_fs26.realpathSync)(p);
|
|
13046
13313
|
} catch {
|
|
13047
13314
|
const segments = [];
|
|
13048
|
-
let current = (0,
|
|
13049
|
-
while (!(0,
|
|
13050
|
-
segments.unshift((0,
|
|
13051
|
-
const parent = (0,
|
|
13315
|
+
let current = (0, import_path27.resolve)(p);
|
|
13316
|
+
while (!(0, import_fs26.existsSync)(current)) {
|
|
13317
|
+
segments.unshift((0, import_path27.basename)(current));
|
|
13318
|
+
const parent = (0, import_path27.dirname)(current);
|
|
13052
13319
|
if (parent === current) break;
|
|
13053
13320
|
current = parent;
|
|
13054
13321
|
}
|
|
13055
13322
|
try {
|
|
13056
|
-
return (0,
|
|
13323
|
+
return (0, import_path27.join)((0, import_fs26.realpathSync)(current), ...segments);
|
|
13057
13324
|
} catch {
|
|
13058
|
-
return (0,
|
|
13325
|
+
return (0, import_path27.resolve)(p);
|
|
13059
13326
|
}
|
|
13060
13327
|
}
|
|
13061
13328
|
}
|
|
13062
13329
|
function validateResolvedPath(resolvedPath, expectedBase) {
|
|
13063
13330
|
const absResolved = safeRealpath(resolvedPath);
|
|
13064
13331
|
const absBase = safeRealpath(expectedBase);
|
|
13065
|
-
const rel = (0,
|
|
13066
|
-
if (rel.startsWith("..") || (0,
|
|
13332
|
+
const rel = (0, import_path27.relative)(absBase, absResolved);
|
|
13333
|
+
if (rel.startsWith("..") || (0, import_path27.resolve)(absBase, rel) !== absResolved) {
|
|
13067
13334
|
throw new Error(`Path traversal detected: "${resolvedPath}" escapes base "${expectedBase}"`);
|
|
13068
13335
|
}
|
|
13069
13336
|
}
|
|
13070
|
-
var
|
|
13337
|
+
var import_fs26, import_path27;
|
|
13071
13338
|
var init_fs_utils = __esm({
|
|
13072
13339
|
"src/team/fs-utils.ts"() {
|
|
13073
13340
|
"use strict";
|
|
13074
|
-
|
|
13075
|
-
|
|
13341
|
+
import_fs26 = require("fs");
|
|
13342
|
+
import_path27 = require("path");
|
|
13076
13343
|
}
|
|
13077
13344
|
});
|
|
13078
13345
|
|
|
13079
13346
|
// src/team/worker-bootstrap.ts
|
|
13080
13347
|
function buildInstructionPath(...parts) {
|
|
13081
|
-
return (0,
|
|
13348
|
+
return (0, import_path28.join)(...parts).replaceAll("\\", "/");
|
|
13082
13349
|
}
|
|
13083
13350
|
function shellPath(path5) {
|
|
13084
13351
|
if (path5.startsWith("$OMC_TEAM_STATE_ROOT/")) return `"${path5}"`;
|
|
@@ -13337,8 +13604,8 @@ ${bootstrapInstructions}
|
|
|
13337
13604
|
` : ""}`;
|
|
13338
13605
|
}
|
|
13339
13606
|
async function composeInitialInbox(teamName, workerName, content, cwd, cliOutputContract) {
|
|
13340
|
-
const inboxPath = (0,
|
|
13341
|
-
await (0, import_promises9.mkdir)((0,
|
|
13607
|
+
const inboxPath = (0, import_path28.join)(teamStateRoot(cwd, sanitizeName(teamName)), "workers", sanitizeName(workerName), "inbox.md");
|
|
13608
|
+
await (0, import_promises9.mkdir)((0, import_path28.dirname)(inboxPath), { recursive: true });
|
|
13342
13609
|
const finalContent = cliOutputContract && !content.includes(cliOutputContract) ? `${content}
|
|
13343
13610
|
${cliOutputContract}` : content;
|
|
13344
13611
|
await (0, import_promises9.writeFile)(inboxPath, finalContent, "utf-8");
|
|
@@ -13346,9 +13613,9 @@ ${cliOutputContract}` : content;
|
|
|
13346
13613
|
async function appendToInbox(teamName, workerName, message, cwd) {
|
|
13347
13614
|
const safeTeam = sanitizeName(teamName);
|
|
13348
13615
|
const safeWorker = sanitizeName(workerName);
|
|
13349
|
-
const inboxPath = (0,
|
|
13616
|
+
const inboxPath = (0, import_path28.join)(teamStateRoot(cwd, safeTeam), "workers", safeWorker, "inbox.md");
|
|
13350
13617
|
validateResolvedPath(inboxPath, teamStateRoot(cwd, safeTeam));
|
|
13351
|
-
await (0, import_promises9.mkdir)((0,
|
|
13618
|
+
await (0, import_promises9.mkdir)((0, import_path28.dirname)(inboxPath), { recursive: true });
|
|
13352
13619
|
await (0, import_promises9.appendFile)(inboxPath, `
|
|
13353
13620
|
|
|
13354
13621
|
---
|
|
@@ -13356,27 +13623,27 @@ ${message}`, "utf-8");
|
|
|
13356
13623
|
}
|
|
13357
13624
|
async function ensureWorkerStateDir(teamName, workerName, cwd) {
|
|
13358
13625
|
const root = teamStateRoot(cwd, sanitizeName(teamName));
|
|
13359
|
-
const workerDir = (0,
|
|
13626
|
+
const workerDir = (0, import_path28.join)(root, "workers", sanitizeName(workerName));
|
|
13360
13627
|
await (0, import_promises9.mkdir)(workerDir, { recursive: true });
|
|
13361
|
-
const mailboxDir = (0,
|
|
13628
|
+
const mailboxDir = (0, import_path28.join)(root, "mailbox");
|
|
13362
13629
|
await (0, import_promises9.mkdir)(mailboxDir, { recursive: true });
|
|
13363
|
-
const tasksDir = (0,
|
|
13630
|
+
const tasksDir = (0, import_path28.join)(root, "tasks");
|
|
13364
13631
|
await (0, import_promises9.mkdir)(tasksDir, { recursive: true });
|
|
13365
13632
|
}
|
|
13366
13633
|
async function writeWorkerOverlay(params) {
|
|
13367
13634
|
const { teamName, workerName, cwd } = params;
|
|
13368
13635
|
const overlay = generateWorkerOverlay(params);
|
|
13369
|
-
const overlayPath = (0,
|
|
13370
|
-
await (0, import_promises9.mkdir)((0,
|
|
13636
|
+
const overlayPath = (0, import_path28.join)(teamStateRoot(cwd, sanitizeName(teamName)), "workers", sanitizeName(workerName), "AGENTS.md");
|
|
13637
|
+
await (0, import_promises9.mkdir)((0, import_path28.dirname)(overlayPath), { recursive: true });
|
|
13371
13638
|
await (0, import_promises9.writeFile)(overlayPath, overlay, "utf-8");
|
|
13372
13639
|
return overlayPath;
|
|
13373
13640
|
}
|
|
13374
|
-
var import_promises9,
|
|
13641
|
+
var import_promises9, import_path28, DEFAULT_INSTRUCTION_STATE_ROOT;
|
|
13375
13642
|
var init_worker_bootstrap = __esm({
|
|
13376
13643
|
"src/team/worker-bootstrap.ts"() {
|
|
13377
13644
|
"use strict";
|
|
13378
13645
|
import_promises9 = require("fs/promises");
|
|
13379
|
-
|
|
13646
|
+
import_path28 = require("path");
|
|
13380
13647
|
init_prompt_helpers();
|
|
13381
13648
|
init_omc_cli_rendering();
|
|
13382
13649
|
init_tmux_session();
|
|
@@ -13408,14 +13675,14 @@ function resolveDispatchLockTimeoutMs(env = process.env) {
|
|
|
13408
13675
|
}
|
|
13409
13676
|
async function withDispatchLock(teamName, cwd, fn) {
|
|
13410
13677
|
const root = absPath(cwd, TeamPaths.root(teamName));
|
|
13411
|
-
if (!(0,
|
|
13678
|
+
if (!(0, import_fs27.existsSync)(root)) throw new Error(`Team ${teamName} not found`);
|
|
13412
13679
|
const lockDir = absPath(cwd, TeamPaths.dispatchLockDir(teamName));
|
|
13413
|
-
const ownerPath = (0,
|
|
13680
|
+
const ownerPath = (0, import_path29.join)(lockDir, "owner");
|
|
13414
13681
|
const ownerToken = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
|
|
13415
13682
|
const timeoutMs = resolveDispatchLockTimeoutMs(process.env);
|
|
13416
13683
|
const deadline = Date.now() + timeoutMs;
|
|
13417
13684
|
let pollMs = DISPATCH_LOCK_INITIAL_POLL_MS;
|
|
13418
|
-
await (0, import_promises10.mkdir)((0,
|
|
13685
|
+
await (0, import_promises10.mkdir)((0, import_path29.dirname)(lockDir), { recursive: true });
|
|
13419
13686
|
while (true) {
|
|
13420
13687
|
try {
|
|
13421
13688
|
await (0, import_promises10.mkdir)(lockDir, { recursive: false });
|
|
@@ -13462,7 +13729,7 @@ async function withDispatchLock(teamName, cwd, fn) {
|
|
|
13462
13729
|
async function readDispatchRequestsFromFile(teamName, cwd) {
|
|
13463
13730
|
const path5 = absPath(cwd, TeamPaths.dispatchRequests(teamName));
|
|
13464
13731
|
try {
|
|
13465
|
-
if (!(0,
|
|
13732
|
+
if (!(0, import_fs27.existsSync)(path5)) return [];
|
|
13466
13733
|
const raw = await (0, import_promises10.readFile)(path5, "utf8");
|
|
13467
13734
|
const parsed = JSON.parse(raw);
|
|
13468
13735
|
if (!Array.isArray(parsed)) return [];
|
|
@@ -13473,7 +13740,7 @@ async function readDispatchRequestsFromFile(teamName, cwd) {
|
|
|
13473
13740
|
}
|
|
13474
13741
|
async function writeDispatchRequestsToFile(teamName, requests, cwd) {
|
|
13475
13742
|
const path5 = absPath(cwd, TeamPaths.dispatchRequests(teamName));
|
|
13476
|
-
const dir = (0,
|
|
13743
|
+
const dir = (0, import_path29.dirname)(path5);
|
|
13477
13744
|
ensureDirWithMode(dir);
|
|
13478
13745
|
atomicWriteJson2(path5, requests);
|
|
13479
13746
|
}
|
|
@@ -13589,14 +13856,14 @@ async function markDispatchRequestNotified(teamName, requestId, patch = {}, cwd)
|
|
|
13589
13856
|
if (current.status === "notified" || current.status === "delivered") return current;
|
|
13590
13857
|
return await transitionDispatchRequest(teamName, requestId, current.status, "notified", patch, cwd);
|
|
13591
13858
|
}
|
|
13592
|
-
var import_crypto8,
|
|
13859
|
+
var import_crypto8, import_fs27, import_promises10, import_path29, OMC_DISPATCH_LOCK_TIMEOUT_ENV, DEFAULT_DISPATCH_LOCK_TIMEOUT_MS, MIN_DISPATCH_LOCK_TIMEOUT_MS, MAX_DISPATCH_LOCK_TIMEOUT_MS, DISPATCH_LOCK_INITIAL_POLL_MS, DISPATCH_LOCK_MAX_POLL_MS, LOCK_STALE_MS;
|
|
13593
13860
|
var init_dispatch_queue = __esm({
|
|
13594
13861
|
"src/team/dispatch-queue.ts"() {
|
|
13595
13862
|
"use strict";
|
|
13596
13863
|
import_crypto8 = require("crypto");
|
|
13597
|
-
|
|
13864
|
+
import_fs27 = require("fs");
|
|
13598
13865
|
import_promises10 = require("fs/promises");
|
|
13599
|
-
|
|
13866
|
+
import_path29 = require("path");
|
|
13600
13867
|
init_state_paths();
|
|
13601
13868
|
init_fs_utils();
|
|
13602
13869
|
init_contracts();
|
|
@@ -13759,7 +14026,7 @@ async function transitionTaskStatus(taskId, from, to, claimToken, terminalData,
|
|
|
13759
14026
|
return { ok: true, task: lock.value.task };
|
|
13760
14027
|
}
|
|
13761
14028
|
async function listTasks(teamName, cwd, deps) {
|
|
13762
|
-
const tasksRoot = (0,
|
|
14029
|
+
const tasksRoot = (0, import_path30.join)(deps.teamDir(teamName, cwd), "tasks");
|
|
13763
14030
|
const invalidState = (path5, cause) => deps.stateError?.(path5, cause) ?? new Error("invalid_persisted_state");
|
|
13764
14031
|
let entries;
|
|
13765
14032
|
try {
|
|
@@ -13784,7 +14051,7 @@ async function listTasks(teamName, cwd, deps) {
|
|
|
13784
14051
|
for (const [id, paths] of candidates) {
|
|
13785
14052
|
let fileName = paths.canonical ?? paths.legacy;
|
|
13786
14053
|
if (!fileName) continue;
|
|
13787
|
-
let path5 = (0,
|
|
14054
|
+
let path5 = (0, import_path30.join)(tasksRoot, fileName);
|
|
13788
14055
|
let fileStat;
|
|
13789
14056
|
try {
|
|
13790
14057
|
fileStat = await (0, import_promises11.lstat)(path5);
|
|
@@ -13792,7 +14059,7 @@ async function listTasks(teamName, cwd, deps) {
|
|
|
13792
14059
|
if (error.code === "ENOENT") {
|
|
13793
14060
|
if (fileName === paths.canonical && paths.legacy) {
|
|
13794
14061
|
fileName = paths.legacy;
|
|
13795
|
-
path5 = (0,
|
|
14062
|
+
path5 = (0, import_path30.join)(tasksRoot, fileName);
|
|
13796
14063
|
try {
|
|
13797
14064
|
fileStat = await (0, import_promises11.lstat)(path5);
|
|
13798
14065
|
} catch (legacyError) {
|
|
@@ -13816,7 +14083,7 @@ async function listTasks(teamName, cwd, deps) {
|
|
|
13816
14083
|
if (error.code === "ENOENT") {
|
|
13817
14084
|
if (fileName === paths.canonical && paths.legacy) {
|
|
13818
14085
|
fileName = paths.legacy;
|
|
13819
|
-
path5 = (0,
|
|
14086
|
+
path5 = (0, import_path30.join)(tasksRoot, fileName);
|
|
13820
14087
|
try {
|
|
13821
14088
|
const legacyStat = await (0, import_promises11.lstat)(path5);
|
|
13822
14089
|
if (legacyStat.isSymbolicLink() || !legacyStat.isFile()) {
|
|
@@ -13841,7 +14108,7 @@ async function listTasks(teamName, cwd, deps) {
|
|
|
13841
14108
|
try {
|
|
13842
14109
|
parsed = JSON.parse(raw);
|
|
13843
14110
|
} catch {
|
|
13844
|
-
throw invalidState((0,
|
|
14111
|
+
throw invalidState((0, import_path30.join)(tasksRoot, fileName), "json");
|
|
13845
14112
|
}
|
|
13846
14113
|
if (!deps.isTeamTask(parsed)) throw invalidState(path5, "schema");
|
|
13847
14114
|
const task = deps.normalizeTask(parsed);
|
|
@@ -13939,12 +14206,12 @@ async function adoptRecoveryReservations(taskIds, workerName, proof, deps) {
|
|
|
13939
14206
|
}
|
|
13940
14207
|
return results;
|
|
13941
14208
|
}
|
|
13942
|
-
var import_crypto9,
|
|
14209
|
+
var import_crypto9, import_path30, import_promises11, logEventAppendFailure, logCompletionMarkerFailure;
|
|
13943
14210
|
var init_tasks = __esm({
|
|
13944
14211
|
"src/team/state/tasks.ts"() {
|
|
13945
14212
|
"use strict";
|
|
13946
14213
|
import_crypto9 = require("crypto");
|
|
13947
|
-
|
|
14214
|
+
import_path30 = require("path");
|
|
13948
14215
|
import_promises11 = require("fs/promises");
|
|
13949
14216
|
init_contracts();
|
|
13950
14217
|
init_swallowed_error();
|
|
@@ -15198,7 +15465,8 @@ function resolveRoleAssignment(role, cfg) {
|
|
|
15198
15465
|
const provider = isOrchestrator ? getHostCliType() : spec?.provider ?? getHostCliType();
|
|
15199
15466
|
const model = provider === "claude" || provider === "copilot" ? resolveClaudeModel(canonical, spec?.model, cfg) : resolveExternalModel(provider, spec?.model, cfg);
|
|
15200
15467
|
const agent = spec?.agent ?? ROLE_TO_AGENT[canonical];
|
|
15201
|
-
|
|
15468
|
+
const reasoningEffort = spec?.reasoningEffort;
|
|
15469
|
+
return { provider, model, agent, reasoningEffort };
|
|
15202
15470
|
}
|
|
15203
15471
|
function isCanonicalRole(value) {
|
|
15204
15472
|
return CANONICAL_TEAM_ROLES.includes(value);
|
|
@@ -15214,7 +15482,8 @@ function buildResolvedRoutingSnapshot(cfg) {
|
|
|
15214
15482
|
const fallback = {
|
|
15215
15483
|
provider: getHostCliType(),
|
|
15216
15484
|
model: resolveClaudeModel(role, fallbackModelInput, cfg),
|
|
15217
|
-
agent: primary.agent
|
|
15485
|
+
agent: primary.agent,
|
|
15486
|
+
reasoningEffort: spec?.reasoningEffort
|
|
15218
15487
|
};
|
|
15219
15488
|
out[role] = { primary, fallback };
|
|
15220
15489
|
}
|
|
@@ -15767,13 +16036,13 @@ var init_merge_coordinator = __esm({
|
|
|
15767
16036
|
// src/team/leader-inbox.ts
|
|
15768
16037
|
function leaderInboxPath(teamName, cwd) {
|
|
15769
16038
|
const safe = sanitizeName(teamName);
|
|
15770
|
-
return (0,
|
|
16039
|
+
return (0, import_path31.join)(teamStateRoot(cwd, safe), "leader", "inbox.md");
|
|
15771
16040
|
}
|
|
15772
16041
|
async function ensureLeaderInbox(teamName, cwd) {
|
|
15773
16042
|
const inboxPath = leaderInboxPath(teamName, cwd);
|
|
15774
16043
|
validateResolvedPath(inboxPath, teamStateRoot(cwd, sanitizeName(teamName)));
|
|
15775
|
-
await (0, import_promises14.mkdir)((0,
|
|
15776
|
-
if (!(0,
|
|
16044
|
+
await (0, import_promises14.mkdir)((0, import_path31.dirname)(inboxPath), { recursive: true });
|
|
16045
|
+
if (!(0, import_fs28.existsSync)(inboxPath)) {
|
|
15777
16046
|
await (0, import_promises14.writeFile)(inboxPath, LEADER_INBOX_HEADER, "utf-8");
|
|
15778
16047
|
}
|
|
15779
16048
|
return inboxPath;
|
|
@@ -15781,7 +16050,7 @@ async function ensureLeaderInbox(teamName, cwd) {
|
|
|
15781
16050
|
async function appendToLeaderInbox(teamName, message, cwd) {
|
|
15782
16051
|
const inboxPath = leaderInboxPath(teamName, cwd);
|
|
15783
16052
|
validateResolvedPath(inboxPath, teamStateRoot(cwd, sanitizeName(teamName)));
|
|
15784
|
-
await (0, import_promises14.mkdir)((0,
|
|
16053
|
+
await (0, import_promises14.mkdir)((0, import_path31.dirname)(inboxPath), { recursive: true });
|
|
15785
16054
|
await (0, import_promises14.appendFile)(inboxPath, `
|
|
15786
16055
|
|
|
15787
16056
|
---
|
|
@@ -15789,16 +16058,16 @@ ${message}`, "utf-8");
|
|
|
15789
16058
|
}
|
|
15790
16059
|
function extendLeaderBootstrapPrompt(teamName, cwd) {
|
|
15791
16060
|
const safe = sanitizeName(teamName);
|
|
15792
|
-
const path5 = cwd ? (0,
|
|
16061
|
+
const path5 = cwd ? (0, import_path31.join)(teamStateRoot(cwd, safe), "leader", "inbox.md") : `.omg/state/team/${safe}/leader/inbox.md`;
|
|
15793
16062
|
return `Runtime notifications appear at ${path5} \u2014 check this file periodically and after long-running operations.`;
|
|
15794
16063
|
}
|
|
15795
|
-
var import_promises14,
|
|
16064
|
+
var import_promises14, import_fs28, import_path31, LEADER_INBOX_HEADER;
|
|
15796
16065
|
var init_leader_inbox = __esm({
|
|
15797
16066
|
"src/team/leader-inbox.ts"() {
|
|
15798
16067
|
"use strict";
|
|
15799
16068
|
import_promises14 = require("fs/promises");
|
|
15800
|
-
|
|
15801
|
-
|
|
16069
|
+
import_fs28 = require("fs");
|
|
16070
|
+
import_path31 = require("path");
|
|
15802
16071
|
init_tmux_session();
|
|
15803
16072
|
init_fs_utils();
|
|
15804
16073
|
init_state_paths();
|
|
@@ -15928,27 +16197,27 @@ async function installPostToolUseHook(worktreePath, workerName) {
|
|
|
15928
16197
|
if (isHookPaused(worktreePath)) {
|
|
15929
16198
|
return;
|
|
15930
16199
|
}
|
|
15931
|
-
const claudeDir = (0,
|
|
16200
|
+
const claudeDir = (0, import_path32.join)(worktreePath, ".copilot");
|
|
15932
16201
|
await (0, import_promises15.mkdir)(claudeDir, { recursive: true });
|
|
15933
|
-
const settingsPath = (0,
|
|
16202
|
+
const settingsPath = (0, import_path32.join)(claudeDir, "settings.json");
|
|
15934
16203
|
const hookCommand = buildHookCommand(workerName);
|
|
15935
16204
|
const merged = await mergeSettingsWithHook(settingsPath, hookCommand);
|
|
15936
16205
|
await (0, import_promises15.writeFile)(settingsPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
15937
16206
|
}
|
|
15938
16207
|
async function pauseHookViaSentinel(worktreePath) {
|
|
15939
|
-
const sentinelPath = (0,
|
|
15940
|
-
await (0, import_promises15.mkdir)((0,
|
|
16208
|
+
const sentinelPath = (0, import_path32.join)(worktreePath, SENTINEL_FILENAME);
|
|
16209
|
+
await (0, import_promises15.mkdir)((0, import_path32.dirname)(sentinelPath), { recursive: true });
|
|
15941
16210
|
await (0, import_promises15.writeFile)(sentinelPath, "", "utf-8");
|
|
15942
16211
|
}
|
|
15943
16212
|
async function resumeHookViaSentinel(worktreePath) {
|
|
15944
|
-
const sentinelPath = (0,
|
|
16213
|
+
const sentinelPath = (0, import_path32.join)(worktreePath, SENTINEL_FILENAME);
|
|
15945
16214
|
try {
|
|
15946
16215
|
await (0, import_promises15.unlink)(sentinelPath);
|
|
15947
16216
|
} catch {
|
|
15948
16217
|
}
|
|
15949
16218
|
}
|
|
15950
16219
|
function isHookPaused(worktreePath) {
|
|
15951
|
-
return (0,
|
|
16220
|
+
return (0, import_fs29.existsSync)((0, import_path32.join)(worktreePath, SENTINEL_FILENAME));
|
|
15952
16221
|
}
|
|
15953
16222
|
function startFallbackPoller(worktreePath, workerName, opts) {
|
|
15954
16223
|
assertSafeWorkerName(workerName);
|
|
@@ -15972,7 +16241,7 @@ function startFallbackPoller(worktreePath, workerName, opts) {
|
|
|
15972
16241
|
runAutoCommit();
|
|
15973
16242
|
}, debounceMs);
|
|
15974
16243
|
};
|
|
15975
|
-
const watcher = (0,
|
|
16244
|
+
const watcher = (0, import_fs29.watch)(worktreePath, { recursive: true }, (eventType, filename) => {
|
|
15976
16245
|
if (stopped) return;
|
|
15977
16246
|
if (filename && (filename.startsWith(".git") || filename.startsWith(".git/"))) return;
|
|
15978
16247
|
scheduleDebounce();
|
|
@@ -16007,7 +16276,7 @@ async function uninstallCommitCadence(ctx, io = { readFile: import_promises15.re
|
|
|
16007
16276
|
if (ownsRegisteredGeneration) cadenceOwners.delete(ctx.worktreePath);
|
|
16008
16277
|
return;
|
|
16009
16278
|
}
|
|
16010
|
-
const settingsPath = (0,
|
|
16279
|
+
const settingsPath = (0, import_path32.join)(ctx.worktreePath, ".copilot", "settings.json");
|
|
16011
16280
|
let raw;
|
|
16012
16281
|
try {
|
|
16013
16282
|
raw = await io.readFile(settingsPath, "utf-8");
|
|
@@ -16032,13 +16301,13 @@ async function uninstallCommitCadence(ctx, io = { readFile: import_promises15.re
|
|
|
16032
16301
|
await io.writeFile(settingsPath, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
16033
16302
|
if (ownsRegisteredGeneration) cadenceOwners.delete(ctx.worktreePath);
|
|
16034
16303
|
}
|
|
16035
|
-
var
|
|
16304
|
+
var import_fs29, import_promises15, import_path32, import_child_process8, cadenceOwners, SENTINEL_FILENAME, HOOK_MATCHER, DEFAULT_POLL_DEBOUNCE_MS, WORKER_NAME_RE;
|
|
16036
16305
|
var init_worker_commit_cadence = __esm({
|
|
16037
16306
|
"src/team/worker-commit-cadence.ts"() {
|
|
16038
16307
|
"use strict";
|
|
16039
|
-
|
|
16308
|
+
import_fs29 = require("fs");
|
|
16040
16309
|
import_promises15 = require("fs/promises");
|
|
16041
|
-
|
|
16310
|
+
import_path32 = require("path");
|
|
16042
16311
|
import_child_process8 = require("child_process");
|
|
16043
16312
|
cadenceOwners = /* @__PURE__ */ new Map();
|
|
16044
16313
|
SENTINEL_FILENAME = ".hook-paused";
|
|
@@ -16723,11 +16992,11 @@ function scaleUpFenceBlocks(config) {
|
|
|
16723
16992
|
if (attempt.phase === "committed") return false;
|
|
16724
16993
|
return true;
|
|
16725
16994
|
}
|
|
16726
|
-
var
|
|
16995
|
+
var import_path33, import_promises17;
|
|
16727
16996
|
var init_scaling = __esm({
|
|
16728
16997
|
"src/team/scaling.ts"() {
|
|
16729
16998
|
"use strict";
|
|
16730
|
-
|
|
16999
|
+
import_path33 = require("path");
|
|
16731
17000
|
import_promises17 = require("fs/promises");
|
|
16732
17001
|
init_model_contract();
|
|
16733
17002
|
init_loader();
|
|
@@ -17331,26 +17600,27 @@ function resolveTaskAssignment(task, resolvedRouting, roleRoutingConfig, fallbac
|
|
|
17331
17600
|
const normalized = normalizeDelegationRole(rawRole);
|
|
17332
17601
|
const canonical = canonicalRoles.has(normalized) ? normalized : null;
|
|
17333
17602
|
if (!canonical) {
|
|
17334
|
-
return { agentType: fallbackAgent, model: "", role: null };
|
|
17603
|
+
return { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: null };
|
|
17335
17604
|
}
|
|
17336
17605
|
const hasConfigForRole = !!getRoleRoutingSpec(
|
|
17337
17606
|
roleRoutingConfig,
|
|
17338
17607
|
canonical
|
|
17339
17608
|
);
|
|
17340
17609
|
if (!hasExplicitRole && !hasConfigForRole) {
|
|
17341
|
-
return { agentType: fallbackAgent, model: "", role: canonical };
|
|
17610
|
+
return { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: canonical };
|
|
17342
17611
|
}
|
|
17343
17612
|
if (hasExplicitRole && !hasConfigForRole && fallbackAgent !== getHostCliType()) {
|
|
17344
|
-
return { agentType: fallbackAgent, model: "", role: canonical };
|
|
17613
|
+
return { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: canonical };
|
|
17345
17614
|
}
|
|
17346
17615
|
const pair = resolvedRouting[canonical];
|
|
17347
17616
|
if (!pair) {
|
|
17348
|
-
return { agentType: fallbackAgent, model: "", role: canonical };
|
|
17617
|
+
return { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: canonical };
|
|
17349
17618
|
}
|
|
17350
17619
|
const chosen = pair.primary;
|
|
17351
17620
|
return {
|
|
17352
17621
|
agentType: chosen.provider,
|
|
17353
17622
|
model: chosen.model,
|
|
17623
|
+
reasoningEffort: chosen.reasoningEffort,
|
|
17354
17624
|
role: canonical
|
|
17355
17625
|
};
|
|
17356
17626
|
}
|
|
@@ -17800,7 +18070,7 @@ async function spawnV2Worker(opts) {
|
|
|
17800
18070
|
);
|
|
17801
18071
|
}
|
|
17802
18072
|
const envVars = {
|
|
17803
|
-
...getWorkerEnv(opts.teamName, opts.workerName, opts.agentType),
|
|
18073
|
+
...getWorkerEnv(opts.teamName, opts.workerName, opts.agentType, process.env, opts.role),
|
|
17804
18074
|
OMC_TEAM_STATE_ROOT: teamStateRoot(opts.cwd, opts.teamName),
|
|
17805
18075
|
OMC_TEAM_LEADER_CWD: opts.cwd,
|
|
17806
18076
|
...opts.worktreePath ? { OMC_TEAM_WORKTREE_PATH: opts.worktreePath } : {},
|
|
@@ -17977,7 +18247,7 @@ async function recordRecoveryPaneRollbackFailure(input, recoveryId, pending, rea
|
|
|
17977
18247
|
const recordedAt = Date.now();
|
|
17978
18248
|
const path5 = absPath(input.cwd, TeamPaths.recoveryPaneRollbackFailure(input.teamName, recoveryId, pending.paneAttemptId, recordedAt));
|
|
17979
18249
|
const candidate = `${path5}.candidate.${process.pid}.${(0, import_node_crypto9.randomUUID)()}`;
|
|
17980
|
-
await (0, import_promises19.mkdir)((0,
|
|
18250
|
+
await (0, import_promises19.mkdir)((0, import_path34.join)(path5, ".."), { recursive: true });
|
|
17981
18251
|
const handle = await (0, import_promises19.open)(candidate, "wx", 384);
|
|
17982
18252
|
try {
|
|
17983
18253
|
await handle.writeFile(JSON.stringify({
|
|
@@ -18007,7 +18277,7 @@ async function recordUnaddressableRecoveryPaneFailure(input, recoveryId, paneAtt
|
|
|
18007
18277
|
const recordedAt = Date.now();
|
|
18008
18278
|
const path5 = absPath(input.cwd, TeamPaths.recoveryPaneRollbackFailure(input.teamName, recoveryId, paneAttemptId, recordedAt));
|
|
18009
18279
|
const candidate = `${path5}.candidate.${process.pid}.${(0, import_node_crypto9.randomUUID)()}`;
|
|
18010
|
-
await (0, import_promises19.mkdir)((0,
|
|
18280
|
+
await (0, import_promises19.mkdir)((0, import_path34.join)(path5, ".."), { recursive: true });
|
|
18011
18281
|
const handle = await (0, import_promises19.open)(candidate, "wx", 384);
|
|
18012
18282
|
const boundedSplit = split ? {
|
|
18013
18283
|
...split,
|
|
@@ -18333,7 +18603,7 @@ async function readOrCreateRecoveryAttempt(input, recoveryId, replacementGenerat
|
|
|
18333
18603
|
adoption_token: (0, import_node_crypto9.randomUUID)(),
|
|
18334
18604
|
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
18335
18605
|
};
|
|
18336
|
-
await (0, import_promises19.mkdir)((0,
|
|
18606
|
+
await (0, import_promises19.mkdir)((0, import_path34.join)(path5, ".."), { recursive: true });
|
|
18337
18607
|
const candidate = `${path5}.candidate.${process.pid}.${(0, import_node_crypto9.randomUUID)()}`;
|
|
18338
18608
|
const candidateHandle = await (0, import_promises19.open)(candidate, "wx", 384);
|
|
18339
18609
|
try {
|
|
@@ -19337,7 +19607,7 @@ async function executeRecoverDeadWorkerV2Owner(input) {
|
|
|
19337
19607
|
launch_nonce: pending.startupContext.attempt.nonce,
|
|
19338
19608
|
written_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
19339
19609
|
};
|
|
19340
|
-
await (0, import_promises19.mkdir)((0,
|
|
19610
|
+
await (0, import_promises19.mkdir)((0, import_path34.join)(pending.gate.activatePath, ".."), { recursive: true });
|
|
19341
19611
|
await (0, import_promises19.writeFile)(pending.gate.activatePath, JSON.stringify(record), "utf8");
|
|
19342
19612
|
const adoptedReady = await waitForRecoveryGateRecord(`${pending.gate.readyPath}.adoption-ready`, record, 3e4);
|
|
19343
19613
|
return adoptedReady && await isWorkerLaunchAttemptCurrent(pending.startupContext.attempt) ? { ok: true } : { ok: false, error: "worker_activation_failed" };
|
|
@@ -19464,7 +19734,7 @@ ${recoveryContract}` : ""}`;
|
|
|
19464
19734
|
let providerLive = false;
|
|
19465
19735
|
try {
|
|
19466
19736
|
const launchedRecord = JSON.parse(await (0, import_promises19.readFile)(launchedPath, "utf8"));
|
|
19467
|
-
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 && !(0,
|
|
19737
|
+
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 && !(0, import_fs30.existsSync)(launchedRecord.supervisor_completion_path)) && await isProcessIdentityLive(
|
|
19468
19738
|
launchedRecord.provider_pid,
|
|
19469
19739
|
launchedRecord.provider_start_identity,
|
|
19470
19740
|
Date.now() + 1e3
|
|
@@ -19543,7 +19813,7 @@ async function rollbackUnpersistedNativeWorktreeStartup(teamName, cwd, cause, in
|
|
|
19543
19813
|
const recordedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19544
19814
|
const writeFailureMarker = async (extra = {}) => {
|
|
19545
19815
|
await (0, import_promises19.mkdir)(teamRoot, { recursive: true });
|
|
19546
|
-
await (0, import_promises19.writeFile)((0,
|
|
19816
|
+
await (0, import_promises19.writeFile)((0, import_path34.join)(teamRoot, "startup-failure.json"), JSON.stringify({
|
|
19547
19817
|
reason: "startup_failed_before_config_persisted",
|
|
19548
19818
|
error: errorMessage,
|
|
19549
19819
|
recorded_at: recordedAt,
|
|
@@ -19574,7 +19844,7 @@ async function rollbackUnpersistedNativeWorktreeStartup(teamName, cwd, cause, in
|
|
|
19574
19844
|
}
|
|
19575
19845
|
}
|
|
19576
19846
|
await (0, import_promises19.rm)(teamRoot, { recursive: true, force: true });
|
|
19577
|
-
if ((0,
|
|
19847
|
+
if ((0, import_fs30.existsSync)(teamRoot)) {
|
|
19578
19848
|
await writeFailureMarker({ rollback_error: "startup_state_removal_unverified" });
|
|
19579
19849
|
return false;
|
|
19580
19850
|
}
|
|
@@ -19598,7 +19868,7 @@ async function rollbackUnpersistedNativeWorktreeStartup(teamName, cwd, cause, in
|
|
|
19598
19868
|
async function writeStartedStartupRollbackEvidence(args) {
|
|
19599
19869
|
const teamRoot = absPath(args.cwd, TeamPaths.root(args.teamName));
|
|
19600
19870
|
await (0, import_promises19.mkdir)(teamRoot, { recursive: true });
|
|
19601
|
-
await (0, import_promises19.writeFile)((0,
|
|
19871
|
+
await (0, import_promises19.writeFile)((0, import_path34.join)(teamRoot, "startup-failure.json"), JSON.stringify({
|
|
19602
19872
|
reason: args.markerReason ?? "startup_rollback_cleanup_incomplete",
|
|
19603
19873
|
error: args.cause instanceof Error ? args.cause.message : String(args.cause),
|
|
19604
19874
|
rollback_error: args.reason,
|
|
@@ -19777,7 +20047,7 @@ async function startTeamV2(config) {
|
|
|
19777
20047
|
}
|
|
19778
20048
|
const instance = createTeamInstanceBinding({
|
|
19779
20049
|
teamName: sanitized,
|
|
19780
|
-
cwd: (0,
|
|
20050
|
+
cwd: (0, import_path34.resolve)(config.cwd),
|
|
19781
20051
|
...config.instanceId !== void 0 ? { instanceId: config.instanceId } : {}
|
|
19782
20052
|
});
|
|
19783
20053
|
const leaderCwd = instance.cwd;
|
|
@@ -19848,7 +20118,7 @@ async function startTeamV2(config) {
|
|
|
19848
20118
|
const workerName = workerNames[i];
|
|
19849
20119
|
const taskIndex = startupByWorker.get(workerName);
|
|
19850
20120
|
const fallbackAgent = agentTypes[i % agentTypes.length] ?? agentTypes[0] ?? "claude";
|
|
19851
|
-
const resolvedAssignment = taskIndex === void 0 ? { agentType: fallbackAgent, model: "", role: void 0 } : resolveTaskAssignment(
|
|
20121
|
+
const resolvedAssignment = taskIndex === void 0 ? { agentType: fallbackAgent, model: "", reasoningEffort: void 0, role: void 0 } : resolveTaskAssignment(
|
|
19852
20122
|
config.tasks[taskIndex],
|
|
19853
20123
|
resolvedRouting,
|
|
19854
20124
|
pluginCfg.team?.roleRouting,
|
|
@@ -19857,6 +20127,7 @@ async function startTeamV2(config) {
|
|
|
19857
20127
|
const assignment = {
|
|
19858
20128
|
agentType: resolvedAssignment.agentType,
|
|
19859
20129
|
model: resolvedAssignment.model || resolveDefaultModel(resolvedAssignment.agentType),
|
|
20130
|
+
reasoningEffort: resolvedAssignment.reasoningEffort,
|
|
19860
20131
|
...resolvedAssignment.role ? { role: resolvedAssignment.role } : {}
|
|
19861
20132
|
};
|
|
19862
20133
|
startupAssignments.set(workerName, assignment);
|
|
@@ -19874,6 +20145,10 @@ async function startTeamV2(config) {
|
|
|
19874
20145
|
const missing = missingBinaryReasons.map(({ agentType, reason }) => `${agentType}:${reason}`).join(";");
|
|
19875
20146
|
throw new Error(`cli_binary_preflight_failed:${missing}`);
|
|
19876
20147
|
}
|
|
20148
|
+
try {
|
|
20149
|
+
await cleanupStaleReservations(sanitized, leaderCwd);
|
|
20150
|
+
} catch {
|
|
20151
|
+
}
|
|
19877
20152
|
return withTeamInstanceLifecycleLock(leaderCwd, sanitized, async () => {
|
|
19878
20153
|
const reservation = await reserveTeamInstanceUnderLock({
|
|
19879
20154
|
teamName: instance.team_name,
|
|
@@ -19897,7 +20172,7 @@ async function startTeamV2(config) {
|
|
|
19897
20172
|
try {
|
|
19898
20173
|
const pendingConfig = buildTeamInstancePendingConfig(instance);
|
|
19899
20174
|
const pendingConfigPath = absPath(leaderCwd, TeamPaths.config(sanitized));
|
|
19900
|
-
await (0, import_promises19.mkdir)((0,
|
|
20175
|
+
await (0, import_promises19.mkdir)((0, import_path34.join)(pendingConfigPath, ".."), { recursive: true });
|
|
19901
20176
|
await (0, import_promises19.writeFile)(pendingConfigPath, JSON.stringify(pendingConfig, null, 2), "utf-8");
|
|
19902
20177
|
} catch (error) {
|
|
19903
20178
|
if (!await rollbackBeforeConfig(error)) throw startupCleanupIncompleteError(error);
|
|
@@ -19908,7 +20183,7 @@ async function startTeamV2(config) {
|
|
|
19908
20183
|
try {
|
|
19909
20184
|
await (0, import_promises19.mkdir)(absPath(leaderCwd, TeamPaths.tasks(sanitized)), { recursive: true });
|
|
19910
20185
|
await (0, import_promises19.mkdir)(absPath(leaderCwd, TeamPaths.workers(sanitized)), { recursive: true });
|
|
19911
|
-
await (0, import_promises19.mkdir)((0,
|
|
20186
|
+
await (0, import_promises19.mkdir)((0, import_path34.join)(getOmcRoot(leaderCwd), "state", "team", sanitized, "mailbox"), { recursive: true });
|
|
19912
20187
|
for (let i = 0; i < config.tasks.length; i++) {
|
|
19913
20188
|
const taskId = String(i + 1);
|
|
19914
20189
|
const task = config.tasks[i];
|
|
@@ -19968,6 +20243,7 @@ async function startTeamV2(config) {
|
|
|
19968
20243
|
cwd: worktree?.path ?? leaderCwd,
|
|
19969
20244
|
resolvedBinaryPath: binary,
|
|
19970
20245
|
model: assignment.model,
|
|
20246
|
+
reasoningEffort: assignment.reasoningEffort,
|
|
19971
20247
|
...permissionFlags.length > 0 ? { extraFlags: permissionFlags } : {}
|
|
19972
20248
|
}, promptArgs);
|
|
19973
20249
|
preparedLaunches.set(workerName, {
|
|
@@ -21169,6 +21445,33 @@ async function monitorTeamV2(teamName, cwd, expectedInstanceId) {
|
|
|
21169
21445
|
}
|
|
21170
21446
|
};
|
|
21171
21447
|
}
|
|
21448
|
+
async function cleanupStaleReservations(teamName, cwd) {
|
|
21449
|
+
const sanitized = sanitizeTeamName(teamName);
|
|
21450
|
+
try {
|
|
21451
|
+
await withTeamInstanceLifecycleLock(cwd, sanitized, async () => {
|
|
21452
|
+
const workspaceHash = teamWorkspaceHash(cwd, sanitized);
|
|
21453
|
+
const reservationPath2 = canonicalTeamStatePath(
|
|
21454
|
+
cwd,
|
|
21455
|
+
TeamPaths.teamInstanceReservation(workspaceHash, sanitized)
|
|
21456
|
+
);
|
|
21457
|
+
if (!(0, import_fs30.existsSync)(reservationPath2)) return;
|
|
21458
|
+
const contentStr = await (0, import_promises19.readFile)(reservationPath2, "utf-8");
|
|
21459
|
+
const reservation = JSON.parse(contentStr);
|
|
21460
|
+
if (!(reservation && typeof reservation === "object" && !Array.isArray(reservation) && "owner" in reservation && typeof reservation.owner === "object")) {
|
|
21461
|
+
return;
|
|
21462
|
+
}
|
|
21463
|
+
const owner = reservation.owner;
|
|
21464
|
+
if (!(owner && typeof owner === "object" && !Array.isArray(owner) && "pid" in owner && "process_started_at" in owner)) {
|
|
21465
|
+
return;
|
|
21466
|
+
}
|
|
21467
|
+
const ownerRecord = owner;
|
|
21468
|
+
if (isProcessIdentityDead(ownerRecord)) {
|
|
21469
|
+
await (0, import_promises19.unlink)(reservationPath2);
|
|
21470
|
+
}
|
|
21471
|
+
}, 5e3);
|
|
21472
|
+
} catch {
|
|
21473
|
+
}
|
|
21474
|
+
}
|
|
21172
21475
|
async function shutdownTeamV2(teamName, cwd, options = {}) {
|
|
21173
21476
|
const logEventFailure = createSwallowedErrorLogger(
|
|
21174
21477
|
"team.runtime-v2.shutdownTeamV2 appendTeamEvent failed"
|
|
@@ -21392,7 +21695,7 @@ async function shutdownTeamV2(teamName, cwd, options = {}) {
|
|
|
21392
21695
|
};
|
|
21393
21696
|
if (!config) {
|
|
21394
21697
|
const cleanupSafety = inspectTeamWorktreeCleanupSafety(sanitized, cwd);
|
|
21395
|
-
if (cleanupSafety.hasEvidence || (0,
|
|
21698
|
+
if (cleanupSafety.hasEvidence || (0, import_fs30.existsSync)(absPath(cwd, TeamPaths.root(sanitized)))) {
|
|
21396
21699
|
process.stderr.write("[team/runtime-v2] preserving team state because config is missing and worktree cleanup evidence remains\n");
|
|
21397
21700
|
return { outcome: "preserved", reason: "config_missing_cleanup_evidence", workers: [] };
|
|
21398
21701
|
}
|
|
@@ -21669,12 +21972,12 @@ Then exit your session.
|
|
|
21669
21972
|
return { outcome: "cleaned" };
|
|
21670
21973
|
});
|
|
21671
21974
|
}
|
|
21672
|
-
var
|
|
21975
|
+
var import_path34, import_fs30, import_promises19, import_perf_hooks, import_node_child_process7, import_node_crypto9, orchestratorByTeam, cadenceByTeam, MONITOR_SIGNAL_STALE_MS, WORKER_STARTUP_EVIDENCE_POLL_INTERVAL_MS, WORKER_STARTUP_EVIDENCE_POLICIES, ENGAGED_PANE_RECHECK_TIMEOUT_ENV, MAX_ENGAGED_PANE_RECHECK_BUDGET_MS, CLAIM_ERROR_CAPTURE_MAX, CLAIM_ERROR_JSON_LINES_MAX, CLAIM_ERROR_LINE_MAX, CLAIM_ERROR_CODES, pendingRecoveryPanes, BOOTSTRAP_RECOVERY_EVIDENCE_POLL_MS, BOOTSTRAP_RECOVERY_EVIDENCE_MAX_WAIT_MS, TEAM_INSTANCE_FINAL_DISPOSAL_AUTHORIZATION;
|
|
21673
21976
|
var init_runtime_v2 = __esm({
|
|
21674
21977
|
"src/team/runtime-v2.ts"() {
|
|
21675
21978
|
"use strict";
|
|
21676
|
-
|
|
21677
|
-
|
|
21979
|
+
import_path34 = require("path");
|
|
21980
|
+
import_fs30 = require("fs");
|
|
21678
21981
|
import_promises19 = require("fs/promises");
|
|
21679
21982
|
import_perf_hooks = require("perf_hooks");
|
|
21680
21983
|
init_state_paths();
|
|
@@ -21824,9 +22127,9 @@ __export(runtime_cli_exports, {
|
|
|
21824
22127
|
});
|
|
21825
22128
|
module.exports = __toCommonJS(runtime_cli_exports);
|
|
21826
22129
|
var import_node_crypto10 = require("node:crypto");
|
|
21827
|
-
var
|
|
22130
|
+
var import_fs31 = require("fs");
|
|
21828
22131
|
var import_promises20 = require("fs/promises");
|
|
21829
|
-
var
|
|
22132
|
+
var import_path35 = require("path");
|
|
21830
22133
|
init_events();
|
|
21831
22134
|
|
|
21832
22135
|
// src/team/leader-nudge-guidance.ts
|
|
@@ -22459,7 +22762,7 @@ function areAllAuthoritativeWorkersDead(refresh, workers) {
|
|
|
22459
22762
|
return classifyAllDeadRecoveryEvidence(refresh, workers, true) === "all_dead";
|
|
22460
22763
|
}
|
|
22461
22764
|
function validateCanonicalRecoveryIntent(teamName, cwd, pathRecoveryId, path5) {
|
|
22462
|
-
const intent = parseRecoveryIntent((0,
|
|
22765
|
+
const intent = parseRecoveryIntent((0, import_fs31.readFileSync)(path5, "utf8"));
|
|
22463
22766
|
if (intent.team_name !== teamName || intent.recovery_id !== pathRecoveryId) throw new Error("invalid_persisted_state");
|
|
22464
22767
|
const reservation = readRecoveryRequestReservation(cwd, intent.request_id);
|
|
22465
22768
|
const workspaceHash = (0, import_node_crypto10.createHash)("sha256").update(cwd).digest("hex");
|
|
@@ -22494,14 +22797,14 @@ async function processPendingRecoveryIntents(teamName, cwd, execute = handleReco
|
|
|
22494
22797
|
const root = absPath(cwd, TeamPaths.recoveryIntents(teamName));
|
|
22495
22798
|
let names;
|
|
22496
22799
|
try {
|
|
22497
|
-
names = (0,
|
|
22800
|
+
names = (0, import_fs31.readdirSync)(root).filter((name) => name.endsWith(".json")).sort();
|
|
22498
22801
|
} catch {
|
|
22499
22802
|
return;
|
|
22500
22803
|
}
|
|
22501
22804
|
for (const name of names) {
|
|
22502
|
-
const path5 = (0,
|
|
22805
|
+
const path5 = (0, import_path35.join)(root, name);
|
|
22503
22806
|
try {
|
|
22504
|
-
const pathRecoveryId = (0,
|
|
22807
|
+
const pathRecoveryId = (0, import_path35.basename)(name, ".json");
|
|
22505
22808
|
const intent = validateCanonicalRecoveryIntent(teamName, cwd, pathRecoveryId, path5);
|
|
22506
22809
|
if (intent.instance_id.toLowerCase() !== normalizedExpectedInstanceId) continue;
|
|
22507
22810
|
if (!await assertRuntimeInstance(teamName, cwd, normalizedExpectedInstanceId)) continue;
|
|
@@ -22571,17 +22874,17 @@ async function updateAllDeadRecoveryGrace(teamName, cwd, evidence, nowMs = Date.
|
|
|
22571
22874
|
}
|
|
22572
22875
|
function canonicalRecoveryIntentEntryId(name, path5) {
|
|
22573
22876
|
if (!name.endsWith(".json")) return null;
|
|
22574
|
-
const recoveryId = (0,
|
|
22877
|
+
const recoveryId = (0, import_path35.basename)(name, ".json");
|
|
22575
22878
|
if (name !== `${recoveryId}.json` || !isSafeRecoveryRequestId(recoveryId)) return null;
|
|
22576
22879
|
try {
|
|
22577
|
-
return (0,
|
|
22880
|
+
return (0, import_fs31.lstatSync)(path5).isFile() ? recoveryId : null;
|
|
22578
22881
|
} catch {
|
|
22579
22882
|
return null;
|
|
22580
22883
|
}
|
|
22581
22884
|
}
|
|
22582
22885
|
function hasVerifiedTerminalRepairForMalformedIntent(teamName, cwd, recoveryId, path5) {
|
|
22583
22886
|
try {
|
|
22584
|
-
const raw = JSON.parse((0,
|
|
22887
|
+
const raw = JSON.parse((0, import_fs31.readFileSync)(path5, "utf8"));
|
|
22585
22888
|
if (raw.team_name !== teamName || raw.recovery_id !== recoveryId || typeof raw.request_id !== "string" || !isSafeRecoveryRequestId(raw.request_id) || typeof raw.worker_name !== "string" || raw.worker_name.length === 0) return false;
|
|
22586
22889
|
const final = readRecoveryFinalState(cwd, raw.request_id);
|
|
22587
22890
|
return final.kind === "valid" && final.final.recovery_id === recoveryId && final.final.team_name === teamName && final.final.worker_name === raw.worker_name;
|
|
@@ -22591,7 +22894,7 @@ function hasVerifiedTerminalRepairForMalformedIntent(teamName, cwd, recoveryId,
|
|
|
22591
22894
|
}
|
|
22592
22895
|
function malformedIntentMayPredateDeadline(path5, deadlineAt) {
|
|
22593
22896
|
try {
|
|
22594
|
-
const metadata = (0,
|
|
22897
|
+
const metadata = (0, import_fs31.lstatSync)(path5);
|
|
22595
22898
|
if (Number.isFinite(metadata.mtimeMs) && metadata.mtimeMs <= deadlineAt) return true;
|
|
22596
22899
|
if (Number.isFinite(metadata.birthtimeMs) && metadata.birthtimeMs > 0) {
|
|
22597
22900
|
return metadata.birthtimeMs <= deadlineAt;
|
|
@@ -22606,14 +22909,14 @@ function canonicalRecoveryAdmissionEntryId(name, path5) {
|
|
|
22606
22909
|
const requestId = name.slice(0, -".pending.json".length);
|
|
22607
22910
|
if (name !== `${requestId}.pending.json` || !isSafeRecoveryRequestId(requestId)) return null;
|
|
22608
22911
|
try {
|
|
22609
|
-
return (0,
|
|
22912
|
+
return (0, import_fs31.lstatSync)(path5).isFile() ? requestId : null;
|
|
22610
22913
|
} catch {
|
|
22611
22914
|
return null;
|
|
22612
22915
|
}
|
|
22613
22916
|
}
|
|
22614
22917
|
function malformedAdmissionMayPredateDeadline(path5, deadlineAt) {
|
|
22615
22918
|
try {
|
|
22616
|
-
const metadata = (0,
|
|
22919
|
+
const metadata = (0, import_fs31.lstatSync)(path5);
|
|
22617
22920
|
if (!metadata.isFile()) return true;
|
|
22618
22921
|
if (Number.isFinite(metadata.mtimeMs) && metadata.mtimeMs <= deadlineAt) return true;
|
|
22619
22922
|
if (Number.isFinite(metadata.birthtimeMs) && metadata.birthtimeMs > 0) {
|
|
@@ -22630,12 +22933,12 @@ function hasPendingRecoveryIntentBeforeDeadline(teamName, cwd, deadlineAt, expec
|
|
|
22630
22933
|
const root = absPath(cwd, TeamPaths.recoveryIntents(teamName));
|
|
22631
22934
|
let names;
|
|
22632
22935
|
try {
|
|
22633
|
-
names = (0,
|
|
22936
|
+
names = (0, import_fs31.readdirSync)(root).filter((name) => name.endsWith(".json"));
|
|
22634
22937
|
} catch {
|
|
22635
22938
|
return false;
|
|
22636
22939
|
}
|
|
22637
22940
|
for (const name of names) {
|
|
22638
|
-
const path5 = (0,
|
|
22941
|
+
const path5 = (0, import_path35.join)(root, name);
|
|
22639
22942
|
const recoveryId = canonicalRecoveryIntentEntryId(name, path5);
|
|
22640
22943
|
if (!recoveryId) continue;
|
|
22641
22944
|
try {
|
|
@@ -22657,12 +22960,12 @@ function hasPendingRecoveryAdmissionBeforeDeadline(teamName, cwd, deadlineAt, ex
|
|
|
22657
22960
|
const root = absPath(cwd, TeamPaths.recoveryRequestsRoot());
|
|
22658
22961
|
let names;
|
|
22659
22962
|
try {
|
|
22660
|
-
names = (0,
|
|
22963
|
+
names = (0, import_fs31.readdirSync)(root).filter((name) => name.endsWith(".pending.json"));
|
|
22661
22964
|
} catch {
|
|
22662
22965
|
return false;
|
|
22663
22966
|
}
|
|
22664
22967
|
for (const name of names) {
|
|
22665
|
-
const path5 = (0,
|
|
22968
|
+
const path5 = (0, import_path35.join)(root, name);
|
|
22666
22969
|
const requestId = canonicalRecoveryAdmissionEntryId(name, path5);
|
|
22667
22970
|
if (!requestId) continue;
|
|
22668
22971
|
try {
|
|
@@ -22881,7 +23184,7 @@ async function writeResultArtifact(output, finishedAt, jobId = process.env.OMC_J
|
|
|
22881
23184
|
if (!output.instanceId || !isValidTeamInstanceId(output.instanceId)) {
|
|
22882
23185
|
throw new Error("result_artifact_instance_identity_missing");
|
|
22883
23186
|
}
|
|
22884
|
-
const resultPath = (0,
|
|
23187
|
+
const resultPath = (0, import_path35.join)(omcJobsDir, `${jobId}-result.json`);
|
|
22885
23188
|
const tmpPath = `${resultPath}.tmp`;
|
|
22886
23189
|
await (0, import_promises20.writeFile)(
|
|
22887
23190
|
tmpPath,
|
|
@@ -22956,7 +23259,7 @@ async function writePanesFile(jobId, instanceId, teamName, cwd, paneIds, leaderP
|
|
|
22956
23259
|
if (authoritativePaneIds.some((paneId) => !paneIds.includes(paneId))) {
|
|
22957
23260
|
throw new Error("pane_artifact_missing_runtime_pane");
|
|
22958
23261
|
}
|
|
22959
|
-
const panesPath = (0,
|
|
23262
|
+
const panesPath = (0, import_path35.join)(omcJobsDir, `${jobId}-panes.json`);
|
|
22960
23263
|
await (0, import_promises20.writeFile)(
|
|
22961
23264
|
panesPath + ".tmp",
|
|
22962
23265
|
JSON.stringify({
|
|
@@ -22994,7 +23297,7 @@ function isTerseFinalSummary(summary) {
|
|
|
22994
23297
|
function readTaskOutputFallback(outputsDir, teamName, taskId) {
|
|
22995
23298
|
let entries;
|
|
22996
23299
|
try {
|
|
22997
|
-
entries = (0,
|
|
23300
|
+
entries = (0, import_fs31.readdirSync)(outputsDir);
|
|
22998
23301
|
} catch {
|
|
22999
23302
|
return null;
|
|
23000
23303
|
}
|
|
@@ -23003,16 +23306,16 @@ function readTaskOutputFallback(outputsDir, teamName, taskId) {
|
|
|
23003
23306
|
if (candidates.length === 0) return null;
|
|
23004
23307
|
let newest = null;
|
|
23005
23308
|
for (const name of candidates) {
|
|
23006
|
-
const full = (0,
|
|
23309
|
+
const full = (0, import_path35.join)(outputsDir, name);
|
|
23007
23310
|
try {
|
|
23008
|
-
const mtime = (0,
|
|
23311
|
+
const mtime = (0, import_fs31.statSync)(full).mtimeMs;
|
|
23009
23312
|
if (!newest || mtime > newest.mtime) newest = { path: full, mtime };
|
|
23010
23313
|
} catch {
|
|
23011
23314
|
}
|
|
23012
23315
|
}
|
|
23013
23316
|
if (!newest) return null;
|
|
23014
23317
|
try {
|
|
23015
|
-
const content = (0,
|
|
23318
|
+
const content = (0, import_fs31.readFileSync)(newest.path, "utf-8").trim();
|
|
23016
23319
|
if (content.length === 0) return null;
|
|
23017
23320
|
return content.length > MAX_FALLBACK_SUMMARY_CHARS ? content.slice(0, MAX_FALLBACK_SUMMARY_CHARS) + "\n... (truncated)" : content;
|
|
23018
23321
|
} catch {
|
|
@@ -23020,14 +23323,14 @@ function readTaskOutputFallback(outputsDir, teamName, taskId) {
|
|
|
23020
23323
|
}
|
|
23021
23324
|
}
|
|
23022
23325
|
function collectTaskResults(stateRoot) {
|
|
23023
|
-
const tasksDir = (0,
|
|
23024
|
-
const teamName = (0,
|
|
23025
|
-
const outputsDir = (0,
|
|
23326
|
+
const tasksDir = (0, import_path35.join)(stateRoot, "tasks");
|
|
23327
|
+
const teamName = (0, import_path35.basename)(stateRoot);
|
|
23328
|
+
const outputsDir = (0, import_path35.join)(stateRoot, "..", "..", "..", "outputs");
|
|
23026
23329
|
try {
|
|
23027
|
-
const files = (0,
|
|
23330
|
+
const files = (0, import_fs31.readdirSync)(tasksDir).filter((f) => f.endsWith(".json"));
|
|
23028
23331
|
return files.map((f) => {
|
|
23029
23332
|
try {
|
|
23030
|
-
const raw = (0,
|
|
23333
|
+
const raw = (0, import_fs31.readFileSync)((0, import_path35.join)(tasksDir, f), "utf-8");
|
|
23031
23334
|
const task = JSON.parse(raw);
|
|
23032
23335
|
const taskId = task.id ?? f.replace(".json", "");
|
|
23033
23336
|
let summary = task.result ?? task.summary ?? "";
|
|
@@ -23371,7 +23674,7 @@ async function main() {
|
|
|
23371
23674
|
if (snap.allTasksTerminal) {
|
|
23372
23675
|
const hasFailures = snap.tasks.failed > 0;
|
|
23373
23676
|
if (!hasFailures) {
|
|
23374
|
-
const sentinelLogPath = (0,
|
|
23677
|
+
const sentinelLogPath = (0, import_path35.join)(cwd, "sentinel_stop.jsonl");
|
|
23375
23678
|
const gateResult = await waitForSentinelReadiness({
|
|
23376
23679
|
workspace: cwd,
|
|
23377
23680
|
logPath: sentinelLogPath,
|