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/mcp-server.cjs
CHANGED
|
@@ -18313,7 +18313,7 @@ function verifyPrivateTempFile(fd, tempPath, label, operations) {
|
|
|
18313
18313
|
`${label} temporary file must be a private regular single-link file`
|
|
18314
18314
|
);
|
|
18315
18315
|
}
|
|
18316
|
-
if (fdStats
|
|
18316
|
+
if (!sameFileIdentity(fdStats, pathStats)) {
|
|
18317
18317
|
throw new Error(`${label} temporary file was replaced before rename`);
|
|
18318
18318
|
}
|
|
18319
18319
|
}
|
|
@@ -18325,7 +18325,7 @@ function verifyPublishedFile(fd, filePath, label, operations) {
|
|
|
18325
18325
|
} catch {
|
|
18326
18326
|
throw new Error(`${label} target was replaced at publication`);
|
|
18327
18327
|
}
|
|
18328
|
-
if (!pathStats.isFile() || fdStats
|
|
18328
|
+
if (!pathStats.isFile() || !sameFileIdentity(fdStats, pathStats)) {
|
|
18329
18329
|
throw new Error(`${label} target was replaced at publication`);
|
|
18330
18330
|
}
|
|
18331
18331
|
}
|
|
@@ -18349,6 +18349,14 @@ function preservePriorTarget(filePath, operations) {
|
|
|
18349
18349
|
return null;
|
|
18350
18350
|
}
|
|
18351
18351
|
}
|
|
18352
|
+
function sameFileIdentity(a, b) {
|
|
18353
|
+
if (a.ino !== b.ino) return false;
|
|
18354
|
+
const isWindows = process.platform === "win32";
|
|
18355
|
+
if (isWindows && (a.dev === 0 || b.dev === 0)) {
|
|
18356
|
+
return true;
|
|
18357
|
+
}
|
|
18358
|
+
return a.dev === b.dev;
|
|
18359
|
+
}
|
|
18352
18360
|
function currentFileIdentity(filePath, operations) {
|
|
18353
18361
|
try {
|
|
18354
18362
|
const stats = (operations?.lstat ?? fsSync.lstatSync)(filePath);
|
|
@@ -18369,7 +18377,7 @@ function rollbackPriorTarget(filePath, backupPath, expectedIdentity, operations)
|
|
|
18369
18377
|
if (expectedIdentity === null) return;
|
|
18370
18378
|
const current = currentFileIdentity(filePath, operations);
|
|
18371
18379
|
if (current === null) return;
|
|
18372
|
-
if (expectedIdentity !== null && (current
|
|
18380
|
+
if (expectedIdentity !== null && !sameFileIdentity(current, expectedIdentity)) {
|
|
18373
18381
|
return;
|
|
18374
18382
|
}
|
|
18375
18383
|
try {
|
|
@@ -19768,6 +19776,23 @@ function readPositiveIntEnv(name, fallback) {
|
|
|
19768
19776
|
function fileUri(filePath) {
|
|
19769
19777
|
return (0, import_url3.pathToFileURL)((0, import_path10.resolve)(filePath)).href;
|
|
19770
19778
|
}
|
|
19779
|
+
function uriKey(uri) {
|
|
19780
|
+
if (!uri.startsWith("file://")) {
|
|
19781
|
+
return uri;
|
|
19782
|
+
}
|
|
19783
|
+
let decoded;
|
|
19784
|
+
try {
|
|
19785
|
+
decoded = decodeURIComponent(uri);
|
|
19786
|
+
} catch {
|
|
19787
|
+
decoded = uri;
|
|
19788
|
+
}
|
|
19789
|
+
const match = decoded.match(/^(file:\/\/)(\/[a-zA-Z])(:.*)$/);
|
|
19790
|
+
if (match) {
|
|
19791
|
+
const driveLetter = match[2].charAt(1).toUpperCase();
|
|
19792
|
+
decoded = `${match[1]}/${driveLetter}${match[3]}`;
|
|
19793
|
+
}
|
|
19794
|
+
return decoded;
|
|
19795
|
+
}
|
|
19771
19796
|
function createCancellationSignal() {
|
|
19772
19797
|
let cancel;
|
|
19773
19798
|
const promise = new Promise((resolveCancellation) => {
|
|
@@ -20113,10 +20138,11 @@ ${content}`;
|
|
|
20113
20138
|
handleNotification(notification) {
|
|
20114
20139
|
if (notification.method === "textDocument/publishDiagnostics") {
|
|
20115
20140
|
const params = this.translateIncomingPayload(notification.params);
|
|
20116
|
-
|
|
20117
|
-
|
|
20141
|
+
const key = uriKey(params.uri);
|
|
20142
|
+
this.diagnostics.set(key, params.diagnostics);
|
|
20143
|
+
const waiters = this.diagnosticWaiters.get(key);
|
|
20118
20144
|
if (waiters && waiters.length > 0) {
|
|
20119
|
-
this.diagnosticWaiters.delete(
|
|
20145
|
+
this.diagnosticWaiters.delete(key);
|
|
20120
20146
|
for (const wake of waiters) wake();
|
|
20121
20147
|
}
|
|
20122
20148
|
}
|
|
@@ -20315,7 +20341,7 @@ ${content}`;
|
|
|
20315
20341
|
}
|
|
20316
20342
|
const content = (0, import_fs10.readFileSync)(filePath, "utf-8");
|
|
20317
20343
|
const languageId = this.getLanguageId(filePath);
|
|
20318
|
-
this.diagnostics.delete(hostUri);
|
|
20344
|
+
this.diagnostics.delete(uriKey(hostUri));
|
|
20319
20345
|
await this.notifyWithBackpressure("textDocument/didOpen", {
|
|
20320
20346
|
textDocument: {
|
|
20321
20347
|
uri,
|
|
@@ -20512,7 +20538,7 @@ ${content}`;
|
|
|
20512
20538
|
*/
|
|
20513
20539
|
getDiagnostics(filePath) {
|
|
20514
20540
|
const uri = fileUri(filePath);
|
|
20515
|
-
return this.diagnostics.get(uri) || [];
|
|
20541
|
+
return this.diagnostics.get(uriKey(uri)) || [];
|
|
20516
20542
|
}
|
|
20517
20543
|
/**
|
|
20518
20544
|
* Whether the server supports LSP 3.17 pull diagnostics (textDocument/diagnostic).
|
|
@@ -20549,24 +20575,25 @@ ${content}`;
|
|
|
20549
20575
|
*/
|
|
20550
20576
|
waitForDiagnostics(filePath, timeoutMs = 2e3) {
|
|
20551
20577
|
const uri = fileUri(filePath);
|
|
20578
|
+
const key = uriKey(uri);
|
|
20552
20579
|
try {
|
|
20553
20580
|
this.throwIfTerminal();
|
|
20554
20581
|
} catch (error2) {
|
|
20555
20582
|
return Promise.reject(error2);
|
|
20556
20583
|
}
|
|
20557
|
-
if (this.diagnostics.has(
|
|
20584
|
+
if (this.diagnostics.has(key)) {
|
|
20558
20585
|
return Promise.resolve();
|
|
20559
20586
|
}
|
|
20560
20587
|
return new Promise((resolve16, reject) => {
|
|
20561
20588
|
let resolved = false;
|
|
20562
20589
|
const removeWaiter = (waiter2) => {
|
|
20563
|
-
const waiters = this.diagnosticWaiters.get(
|
|
20590
|
+
const waiters = this.diagnosticWaiters.get(key);
|
|
20564
20591
|
if (!waiters) return;
|
|
20565
20592
|
const remaining = waiters.filter((candidate) => candidate !== waiter2);
|
|
20566
20593
|
if (remaining.length === 0) {
|
|
20567
|
-
this.diagnosticWaiters.delete(
|
|
20594
|
+
this.diagnosticWaiters.delete(key);
|
|
20568
20595
|
} else {
|
|
20569
|
-
this.diagnosticWaiters.set(
|
|
20596
|
+
this.diagnosticWaiters.set(key, remaining);
|
|
20570
20597
|
}
|
|
20571
20598
|
};
|
|
20572
20599
|
const waiter = (error2) => {
|
|
@@ -20587,9 +20614,9 @@ ${content}`;
|
|
|
20587
20614
|
resolve16();
|
|
20588
20615
|
}
|
|
20589
20616
|
}, timeoutMs);
|
|
20590
|
-
const existing = this.diagnosticWaiters.get(
|
|
20617
|
+
const existing = this.diagnosticWaiters.get(key) || [];
|
|
20591
20618
|
existing.push(waiter);
|
|
20592
|
-
this.diagnosticWaiters.set(
|
|
20619
|
+
this.diagnosticWaiters.set(key, existing);
|
|
20593
20620
|
});
|
|
20594
20621
|
}
|
|
20595
20622
|
/**
|
|
@@ -24560,9 +24587,9 @@ var pythonReplTool = {
|
|
|
24560
24587
|
|
|
24561
24588
|
// src/tools/state-tools.ts
|
|
24562
24589
|
var import_crypto10 = require("crypto");
|
|
24563
|
-
var
|
|
24590
|
+
var import_fs29 = require("fs");
|
|
24564
24591
|
var import_os4 = require("os");
|
|
24565
|
-
var
|
|
24592
|
+
var import_path32 = require("path");
|
|
24566
24593
|
|
|
24567
24594
|
// src/lib/session-id.ts
|
|
24568
24595
|
function readEnv() {
|
|
@@ -24641,10 +24668,109 @@ function validatePayload(payload, limits = {}) {
|
|
|
24641
24668
|
}
|
|
24642
24669
|
|
|
24643
24670
|
// src/lib/mode-state-io.ts
|
|
24644
|
-
var
|
|
24645
|
-
var
|
|
24671
|
+
var import_fs17 = require("fs");
|
|
24672
|
+
var import_path17 = require("path");
|
|
24646
24673
|
var import_crypto4 = require("crypto");
|
|
24647
24674
|
var import_module2 = require("module");
|
|
24675
|
+
|
|
24676
|
+
// src/lib/runs-ledger.ts
|
|
24677
|
+
var import_fs16 = require("fs");
|
|
24678
|
+
var import_path16 = require("path");
|
|
24679
|
+
var WATCHED_RUN_MODES = ["ralph", "autopilot", "team", "ultragoal"];
|
|
24680
|
+
var LEDGER_TAIL_LINES = 1e3;
|
|
24681
|
+
function isWatchedRunMode(modeName) {
|
|
24682
|
+
return WATCHED_RUN_MODES.includes(modeName);
|
|
24683
|
+
}
|
|
24684
|
+
function ledgerPath(omcRoot) {
|
|
24685
|
+
return (0, import_path16.join)(omcRoot, "state", "runs", "ledger.jsonl");
|
|
24686
|
+
}
|
|
24687
|
+
function closeoutWrittenFor(omcRoot, mode, startedAt) {
|
|
24688
|
+
if (!startedAt || !Number.isFinite(Date.parse(startedAt))) return false;
|
|
24689
|
+
const started = Date.parse(startedAt);
|
|
24690
|
+
for (const name of ["problems.md", "issues.md"]) {
|
|
24691
|
+
const notepad = (0, import_path16.join)(omcRoot, "notepads", mode, name);
|
|
24692
|
+
try {
|
|
24693
|
+
if ((0, import_fs16.existsSync)(notepad) && (0, import_fs16.statSync)(notepad).mtimeMs > started) return true;
|
|
24694
|
+
} catch {
|
|
24695
|
+
}
|
|
24696
|
+
}
|
|
24697
|
+
return false;
|
|
24698
|
+
}
|
|
24699
|
+
function appendRunLedger(omcRoot, entry) {
|
|
24700
|
+
try {
|
|
24701
|
+
const dir = (0, import_path16.join)(omcRoot, "state", "runs");
|
|
24702
|
+
(0, import_fs16.mkdirSync)(dir, { recursive: true });
|
|
24703
|
+
const path14 = ledgerPath(omcRoot);
|
|
24704
|
+
rotateIfNeeded(path14);
|
|
24705
|
+
(0, import_fs16.appendFileSync)(path14, `${JSON.stringify(entry)}
|
|
24706
|
+
`, "utf8");
|
|
24707
|
+
} catch {
|
|
24708
|
+
}
|
|
24709
|
+
}
|
|
24710
|
+
function rotateIfNeeded(path14) {
|
|
24711
|
+
try {
|
|
24712
|
+
const stat = (0, import_fs16.statSync)(path14);
|
|
24713
|
+
if (!stat.isFile()) return;
|
|
24714
|
+
const lines = (0, import_fs16.readFileSync)(path14, "utf8").split("\n").filter((line) => line.trim().length > 0);
|
|
24715
|
+
if (lines.length < LEDGER_TAIL_LINES) return;
|
|
24716
|
+
(0, import_fs16.appendFileSync)(`${path14}.1`, `${lines.join("\n")}
|
|
24717
|
+
`, "utf8");
|
|
24718
|
+
(0, import_fs16.writeFileSync)(path14, "", "utf8");
|
|
24719
|
+
} catch {
|
|
24720
|
+
}
|
|
24721
|
+
}
|
|
24722
|
+
function observeModeStateWrite(omcRoot, filePath, state) {
|
|
24723
|
+
try {
|
|
24724
|
+
const mode = modeFromStatePath(filePath);
|
|
24725
|
+
if (!mode || !isWatchedRunMode(mode)) return;
|
|
24726
|
+
if (state?.active !== true) return;
|
|
24727
|
+
const key = filePath;
|
|
24728
|
+
if (activeLoggedPaths.get(key)) return;
|
|
24729
|
+
activeLoggedPaths.set(key, true);
|
|
24730
|
+
appendRunLedger(omcRoot, {
|
|
24731
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24732
|
+
run: mode,
|
|
24733
|
+
sessionId: sessionIdFromStatePath(filePath),
|
|
24734
|
+
event: "start",
|
|
24735
|
+
outcome: "running"
|
|
24736
|
+
});
|
|
24737
|
+
} catch {
|
|
24738
|
+
}
|
|
24739
|
+
}
|
|
24740
|
+
function observeModeStateClear(omcRoot, filePath, previousState) {
|
|
24741
|
+
try {
|
|
24742
|
+
const mode = modeFromStatePath(filePath);
|
|
24743
|
+
if (!mode || !isWatchedRunMode(mode)) return;
|
|
24744
|
+
if (!previousState || previousState.active !== true) return;
|
|
24745
|
+
if (previousState.active === true) activeLoggedPaths.delete(filePath);
|
|
24746
|
+
appendRunLedger(omcRoot, {
|
|
24747
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24748
|
+
run: mode,
|
|
24749
|
+
sessionId: sessionIdFromStatePath(filePath),
|
|
24750
|
+
event: "end",
|
|
24751
|
+
outcome: typeof previousState.current_phase === "string" && /complete|done/i.test(previousState.current_phase) ? "completed" : "cancelled",
|
|
24752
|
+
closeoutWritten: closeoutWrittenFor(omcRoot, mode, typeof previousState.started_at === "string" ? previousState.started_at : void 0)
|
|
24753
|
+
});
|
|
24754
|
+
} catch {
|
|
24755
|
+
}
|
|
24756
|
+
}
|
|
24757
|
+
function modeFromStatePath(filePath) {
|
|
24758
|
+
const match = filePath.replaceAll("\\", "/").match(/\/([a-z][a-z0-9-]+)-state\.json$/);
|
|
24759
|
+
return match?.[1] ?? null;
|
|
24760
|
+
}
|
|
24761
|
+
function sessionIdFromStatePath(filePath) {
|
|
24762
|
+
const match = filePath.replaceAll("\\", "/").match(/\/state\/sessions\/([^/]+)(?:\/|$)/);
|
|
24763
|
+
return match?.[1];
|
|
24764
|
+
}
|
|
24765
|
+
var activeLoggedPaths = /* @__PURE__ */ new Map();
|
|
24766
|
+
|
|
24767
|
+
// src/lib/mode-state-io.ts
|
|
24768
|
+
function omcRootFromStatePath(filePath) {
|
|
24769
|
+
const normalized = filePath.replaceAll("\\", "/");
|
|
24770
|
+
const idx = normalized.lastIndexOf("/state/");
|
|
24771
|
+
if (idx === -1) return null;
|
|
24772
|
+
return normalized.slice(0, idx);
|
|
24773
|
+
}
|
|
24648
24774
|
var require2 = (0, import_module2.createRequire)(
|
|
24649
24775
|
importMetaUrl || (typeof __filename === "string" ? __filename : process.cwd() + "/")
|
|
24650
24776
|
);
|
|
@@ -24716,13 +24842,13 @@ function getStateMutationLockFailureMessage() {
|
|
|
24716
24842
|
return sqliteBindingLoadError;
|
|
24717
24843
|
}
|
|
24718
24844
|
function mutationDbPath(lockPath) {
|
|
24719
|
-
let current = (0,
|
|
24720
|
-
while ((0,
|
|
24721
|
-
const parent = (0,
|
|
24722
|
-
if (parent === current) return (0,
|
|
24845
|
+
let current = (0, import_path17.dirname)(lockPath);
|
|
24846
|
+
while ((0, import_path17.basename)(current) !== "state") {
|
|
24847
|
+
const parent = (0, import_path17.dirname)(current);
|
|
24848
|
+
if (parent === current) return (0, import_path17.join)((0, import_path17.dirname)(lockPath), ".state-mutation-locks.db");
|
|
24723
24849
|
current = parent;
|
|
24724
24850
|
}
|
|
24725
|
-
return (0,
|
|
24851
|
+
return (0, import_path17.join)(current, ".state-mutation-locks.db");
|
|
24726
24852
|
}
|
|
24727
24853
|
function ownerFromRow(row) {
|
|
24728
24854
|
if (!row || row.version !== 1 || !Number.isSafeInteger(row.pid) || row.pid <= 0 || typeof row.process_start !== "string" || typeof row.created_at !== "string" || typeof row.nonce !== "string") return null;
|
|
@@ -24732,15 +24858,15 @@ function writeAllSync2(fd, content, label) {
|
|
|
24732
24858
|
const bytes = Buffer.from(content, "utf8");
|
|
24733
24859
|
let offset = 0;
|
|
24734
24860
|
while (offset < bytes.length) {
|
|
24735
|
-
const written = (0,
|
|
24861
|
+
const written = (0, import_fs17.writeSync)(fd, bytes, offset, bytes.length - offset);
|
|
24736
24862
|
if (!Number.isInteger(written) || written <= 0) throw new Error(`${label} made no progress`);
|
|
24737
24863
|
offset += written;
|
|
24738
24864
|
}
|
|
24739
|
-
if ((0,
|
|
24865
|
+
if ((0, import_fs17.fstatSync)(fd).size !== bytes.length) throw new Error(`${label} size verification failed`);
|
|
24740
24866
|
}
|
|
24741
24867
|
function readLockOwner(path14) {
|
|
24742
24868
|
try {
|
|
24743
|
-
const value = JSON.parse((0,
|
|
24869
|
+
const value = JSON.parse((0, import_fs17.readFileSync)(path14, "utf8"));
|
|
24744
24870
|
const pid = value.pid;
|
|
24745
24871
|
if (value.version !== 1 || !Number.isSafeInteger(pid) || pid <= 0 || typeof value.processStart !== "string" || !/^\S+$/.test(value.processStart) || typeof value.createdAt !== "string" || !Number.isFinite(Date.parse(value.createdAt)) || typeof value.nonce !== "string" || !/^[0-9a-f-]{36}$/i.test(value.nonce)) return null;
|
|
24746
24872
|
return value;
|
|
@@ -24753,7 +24879,7 @@ function sameOwner(left, right) {
|
|
|
24753
24879
|
}
|
|
24754
24880
|
function lockArtifactIdentity(path14) {
|
|
24755
24881
|
try {
|
|
24756
|
-
const stats = (0,
|
|
24882
|
+
const stats = (0, import_fs17.statSync)(path14);
|
|
24757
24883
|
return stats.isFile() ? { dev: stats.dev, ino: stats.ino } : null;
|
|
24758
24884
|
} catch {
|
|
24759
24885
|
return null;
|
|
@@ -24762,10 +24888,10 @@ function lockArtifactIdentity(path14) {
|
|
|
24762
24888
|
function reclaimDeadLockOwner(path14, observedOwner, observedIdentity) {
|
|
24763
24889
|
const currentOwner = readLockOwner(path14);
|
|
24764
24890
|
const currentIdentity = lockArtifactIdentity(path14);
|
|
24765
|
-
if (currentOwner === "absent" || currentOwner === null || !sameOwner(currentOwner, observedOwner) || currentIdentity === null || currentIdentity
|
|
24891
|
+
if (currentOwner === "absent" || currentOwner === null || !sameOwner(currentOwner, observedOwner) || currentIdentity === null || !sameFileIdentity(currentIdentity, observedIdentity)) return "changed";
|
|
24766
24892
|
const quarantinePath = `${path14}.reclaim.${process.pid}.${(0, import_crypto4.randomUUID)()}`;
|
|
24767
24893
|
try {
|
|
24768
|
-
(0,
|
|
24894
|
+
(0, import_fs17.renameSync)(path14, quarantinePath);
|
|
24769
24895
|
} catch (error2) {
|
|
24770
24896
|
return error2.code === "ENOENT" ? "changed" : "failed";
|
|
24771
24897
|
}
|
|
@@ -24774,9 +24900,9 @@ function reclaimDeadLockOwner(path14, observedOwner, observedIdentity) {
|
|
|
24774
24900
|
try {
|
|
24775
24901
|
movedOwner = readLockOwner(quarantinePath);
|
|
24776
24902
|
movedIdentity = lockArtifactIdentity(quarantinePath);
|
|
24777
|
-
if (movedOwner !== "absent" && movedOwner !== null && movedIdentity !== null && movedIdentity
|
|
24903
|
+
if (movedOwner !== "absent" && movedOwner !== null && movedIdentity !== null && sameFileIdentity(movedIdentity, observedIdentity) && sameOwner(movedOwner, observedOwner)) {
|
|
24778
24904
|
try {
|
|
24779
|
-
(0,
|
|
24905
|
+
(0, import_fs17.unlinkSync)(quarantinePath);
|
|
24780
24906
|
return "removed";
|
|
24781
24907
|
} catch {
|
|
24782
24908
|
}
|
|
@@ -24784,9 +24910,9 @@ function reclaimDeadLockOwner(path14, observedOwner, observedIdentity) {
|
|
|
24784
24910
|
} catch {
|
|
24785
24911
|
}
|
|
24786
24912
|
try {
|
|
24787
|
-
(0,
|
|
24913
|
+
(0, import_fs17.linkSync)(quarantinePath, path14);
|
|
24788
24914
|
try {
|
|
24789
|
-
(0,
|
|
24915
|
+
(0, import_fs17.unlinkSync)(quarantinePath);
|
|
24790
24916
|
} catch {
|
|
24791
24917
|
}
|
|
24792
24918
|
} catch {
|
|
@@ -24804,14 +24930,14 @@ function publishLockOwner(path14, owner) {
|
|
|
24804
24930
|
const tempPath = `${path14}.${owner.pid}.${owner.nonce}.tmp`;
|
|
24805
24931
|
let fd;
|
|
24806
24932
|
try {
|
|
24807
|
-
fd = (0,
|
|
24933
|
+
fd = (0, import_fs17.openSync)(tempPath, "wx", 384);
|
|
24808
24934
|
writeAllSync2(fd, JSON.stringify(owner), "lock owner publication");
|
|
24809
|
-
(0,
|
|
24810
|
-
(0,
|
|
24935
|
+
(0, import_fs17.fsyncSync)(fd);
|
|
24936
|
+
(0, import_fs17.closeSync)(fd);
|
|
24811
24937
|
fd = void 0;
|
|
24812
|
-
(0,
|
|
24938
|
+
(0, import_fs17.linkSync)(tempPath, path14);
|
|
24813
24939
|
try {
|
|
24814
|
-
(0,
|
|
24940
|
+
(0, import_fs17.unlinkSync)(tempPath);
|
|
24815
24941
|
} catch (error2) {
|
|
24816
24942
|
const code = error2.code;
|
|
24817
24943
|
if (code !== "EPERM" && code !== "EBUSY") throw error2;
|
|
@@ -24819,11 +24945,11 @@ function publishLockOwner(path14, owner) {
|
|
|
24819
24945
|
return true;
|
|
24820
24946
|
} catch {
|
|
24821
24947
|
try {
|
|
24822
|
-
if (fd !== void 0) (0,
|
|
24948
|
+
if (fd !== void 0) (0, import_fs17.closeSync)(fd);
|
|
24823
24949
|
} catch {
|
|
24824
24950
|
}
|
|
24825
24951
|
try {
|
|
24826
|
-
(0,
|
|
24952
|
+
(0, import_fs17.unlinkSync)(tempPath);
|
|
24827
24953
|
} catch {
|
|
24828
24954
|
}
|
|
24829
24955
|
return false;
|
|
@@ -24837,7 +24963,7 @@ function openMutationDb(lockPath) {
|
|
|
24837
24963
|
const dbPath = mutationDbPath(lockPath);
|
|
24838
24964
|
for (const sidecar of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`, `${dbPath}-journal`]) {
|
|
24839
24965
|
try {
|
|
24840
|
-
const stat = (0,
|
|
24966
|
+
const stat = (0, import_fs17.statSync)(sidecar);
|
|
24841
24967
|
if (!stat.isFile() || stat.nlink !== 1) {
|
|
24842
24968
|
if (process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] openMutationDb sidecar-reject ${sidecar} isFile=${stat.isFile()} nlink=${stat.nlink}`);
|
|
24843
24969
|
return null;
|
|
@@ -24869,9 +24995,9 @@ function acquireFileLockAt(path14, attempts) {
|
|
|
24869
24995
|
lastMutationLockFailureDetail = null;
|
|
24870
24996
|
const key = (() => {
|
|
24871
24997
|
try {
|
|
24872
|
-
return (0,
|
|
24998
|
+
return (0, import_path17.resolve)((0, import_fs17.realpathSync)((0, import_path17.dirname)(path14)), (0, import_path17.basename)(path14));
|
|
24873
24999
|
} catch {
|
|
24874
|
-
return (0,
|
|
25000
|
+
return (0, import_path17.resolve)(path14);
|
|
24875
25001
|
}
|
|
24876
25002
|
})();
|
|
24877
25003
|
const processStart = ownProcessStartIdentity();
|
|
@@ -24891,14 +25017,14 @@ function acquireFileLockAt(path14, attempts) {
|
|
|
24891
25017
|
const tempPath = `${path14}.${owner.pid}.${owner.nonce}.tmp`;
|
|
24892
25018
|
let fd;
|
|
24893
25019
|
try {
|
|
24894
|
-
fd = (0,
|
|
25020
|
+
fd = (0, import_fs17.openSync)(tempPath, "wx", 384);
|
|
24895
25021
|
writeAllSync2(fd, JSON.stringify(owner), "lock owner publication");
|
|
24896
|
-
(0,
|
|
24897
|
-
(0,
|
|
25022
|
+
(0, import_fs17.fsyncSync)(fd);
|
|
25023
|
+
(0, import_fs17.closeSync)(fd);
|
|
24898
25024
|
fd = void 0;
|
|
24899
|
-
(0,
|
|
25025
|
+
(0, import_fs17.linkSync)(tempPath, path14);
|
|
24900
25026
|
try {
|
|
24901
|
-
(0,
|
|
25027
|
+
(0, import_fs17.unlinkSync)(tempPath);
|
|
24902
25028
|
} catch (error2) {
|
|
24903
25029
|
const code = error2.code;
|
|
24904
25030
|
if (code !== "EPERM" && code !== "EBUSY") throw error2;
|
|
@@ -24910,11 +25036,11 @@ function acquireFileLockAt(path14, attempts) {
|
|
|
24910
25036
|
return lock;
|
|
24911
25037
|
} catch (error2) {
|
|
24912
25038
|
try {
|
|
24913
|
-
if (fd !== void 0) (0,
|
|
25039
|
+
if (fd !== void 0) (0, import_fs17.closeSync)(fd);
|
|
24914
25040
|
} catch {
|
|
24915
25041
|
}
|
|
24916
25042
|
try {
|
|
24917
|
-
(0,
|
|
25043
|
+
(0, import_fs17.unlinkSync)(tempPath);
|
|
24918
25044
|
} catch {
|
|
24919
25045
|
}
|
|
24920
25046
|
const code = error2?.code;
|
|
@@ -24923,18 +25049,20 @@ function acquireFileLockAt(path14, attempts) {
|
|
|
24923
25049
|
lastMutationLockFailure = "unverifiable";
|
|
24924
25050
|
return null;
|
|
24925
25051
|
}
|
|
24926
|
-
const existing = readLockOwner(path14);
|
|
24927
|
-
if (existing === "absent") continue;
|
|
24928
|
-
if (!existing) {
|
|
24929
|
-
lastMutationLockFailure = "unverifiable";
|
|
24930
|
-
return null;
|
|
24931
|
-
}
|
|
24932
25052
|
const observedIdentity = lockArtifactIdentity(path14);
|
|
24933
25053
|
if (observedIdentity === null) {
|
|
24934
25054
|
if (readLockOwner(path14) === "absent") continue;
|
|
24935
25055
|
lastMutationLockFailure = "unverifiable";
|
|
24936
25056
|
return null;
|
|
24937
25057
|
}
|
|
25058
|
+
const existing = readLockOwner(path14);
|
|
25059
|
+
if (existing === "absent") continue;
|
|
25060
|
+
if (!existing) {
|
|
25061
|
+
lastMutationLockFailure = "unverifiable";
|
|
25062
|
+
return null;
|
|
25063
|
+
}
|
|
25064
|
+
const recheck = lockArtifactIdentity(path14);
|
|
25065
|
+
if (!recheck || !sameFileIdentity(recheck, observedIdentity)) continue;
|
|
24938
25066
|
const live = verifiedLiveOwner !== null && sameOwner(existing, verifiedLiveOwner) ? true : ownerLive(existing);
|
|
24939
25067
|
if (live === null) {
|
|
24940
25068
|
lastMutationLockFailure = "unverifiable";
|
|
@@ -24971,12 +25099,12 @@ function cachedOwnerLive(owner, verified, slot, probe) {
|
|
|
24971
25099
|
}
|
|
24972
25100
|
function acquireLockAt(path14, attempts = 50, verified = { row: null, artifact: null, dead: [] }) {
|
|
24973
25101
|
lastMutationLockFailureDetail = null;
|
|
24974
|
-
(0,
|
|
25102
|
+
(0, import_fs17.mkdirSync)((0, import_path17.dirname)(path14), { recursive: true });
|
|
24975
25103
|
const key = (() => {
|
|
24976
25104
|
try {
|
|
24977
|
-
return (0,
|
|
25105
|
+
return (0, import_path17.resolve)((0, import_fs17.realpathSync)((0, import_path17.dirname)(path14)), (0, import_path17.basename)(path14));
|
|
24978
25106
|
} catch {
|
|
24979
|
-
return (0,
|
|
25107
|
+
return (0, import_path17.resolve)(path14);
|
|
24980
25108
|
}
|
|
24981
25109
|
})();
|
|
24982
25110
|
const held = localLocks.get(key);
|
|
@@ -25165,7 +25293,7 @@ function releaseMutationLock(lock) {
|
|
|
25165
25293
|
console.error(`[omc-lock] state_mutation_lock_release_failed: ${lock.path}`);
|
|
25166
25294
|
return false;
|
|
25167
25295
|
}
|
|
25168
|
-
(0,
|
|
25296
|
+
(0, import_fs17.unlinkSync)(lock.path);
|
|
25169
25297
|
return true;
|
|
25170
25298
|
} catch (error2) {
|
|
25171
25299
|
abandonedOwnNonces.add(lock.owner.nonce);
|
|
@@ -25192,7 +25320,7 @@ function releaseMutationLock(lock) {
|
|
|
25192
25320
|
console.error(`[omc-lock] state_mutation_lock_release_failed: ${lock.path}`);
|
|
25193
25321
|
return false;
|
|
25194
25322
|
}
|
|
25195
|
-
if (artifact !== "absent") (0,
|
|
25323
|
+
if (artifact !== "absent") (0, import_fs17.unlinkSync)(lock.path);
|
|
25196
25324
|
lock.db.prepare("DELETE FROM state_mutation_locks WHERE lock_key = ?").run(lock.key);
|
|
25197
25325
|
lock.db.exec("COMMIT");
|
|
25198
25326
|
return true;
|
|
@@ -25257,6 +25385,10 @@ function writeStateFileLocked(filePath, state) {
|
|
|
25257
25385
|
} catch {
|
|
25258
25386
|
success = false;
|
|
25259
25387
|
}
|
|
25388
|
+
if (success) {
|
|
25389
|
+
const omcRoot = omcRootFromStatePath(filePath);
|
|
25390
|
+
if (omcRoot) observeModeStateWrite(omcRoot, filePath, state);
|
|
25391
|
+
}
|
|
25260
25392
|
return releaseMutationLock(lock) && success;
|
|
25261
25393
|
}
|
|
25262
25394
|
function clearStateFileLockedIf(filePath, predicate, recoveryOptions, expectedGeneration) {
|
|
@@ -25274,14 +25406,14 @@ function clearStateFileLockedIf(filePath, predicate, recoveryOptions, expectedGe
|
|
|
25274
25406
|
if (!lock) return "failed";
|
|
25275
25407
|
let result = null;
|
|
25276
25408
|
try {
|
|
25277
|
-
if (!(0,
|
|
25409
|
+
if (!(0, import_fs17.existsSync)(filePath)) {
|
|
25278
25410
|
result = "skipped";
|
|
25279
25411
|
} else if (expectedGeneration && !sameStateFileGeneration(filePath, expectedGeneration)) {
|
|
25280
25412
|
result = "skipped";
|
|
25281
25413
|
} else {
|
|
25282
25414
|
let current;
|
|
25283
25415
|
try {
|
|
25284
|
-
current = JSON.parse((0,
|
|
25416
|
+
current = JSON.parse((0, import_fs17.readFileSync)(filePath, "utf8"));
|
|
25285
25417
|
} catch {
|
|
25286
25418
|
current = void 0;
|
|
25287
25419
|
}
|
|
@@ -25296,8 +25428,10 @@ function clearStateFileLockedIf(filePath, predicate, recoveryOptions, expectedGe
|
|
|
25296
25428
|
}
|
|
25297
25429
|
if (result !== null) {
|
|
25298
25430
|
} else {
|
|
25299
|
-
(0,
|
|
25431
|
+
(0, import_fs17.unlinkSync)(filePath);
|
|
25300
25432
|
result = "cleared";
|
|
25433
|
+
const omcRoot = omcRootFromStatePath(filePath);
|
|
25434
|
+
if (omcRoot) observeModeStateClear(omcRoot, filePath, current);
|
|
25301
25435
|
}
|
|
25302
25436
|
}
|
|
25303
25437
|
}
|
|
@@ -25317,17 +25451,17 @@ function writeStateFileLockedIf(filePath, predicate, transform2) {
|
|
|
25317
25451
|
delete process.env.OMC_TEST_CONDITIONAL_WRITE_REPLACEMENT_BASE64;
|
|
25318
25452
|
}
|
|
25319
25453
|
}
|
|
25320
|
-
if (!(0,
|
|
25454
|
+
if (!(0, import_fs17.existsSync)(filePath)) return "skipped";
|
|
25321
25455
|
const lock = acquireMutationLock(filePath);
|
|
25322
25456
|
if (!lock) return "failed";
|
|
25323
25457
|
let result = "failed";
|
|
25324
25458
|
try {
|
|
25325
|
-
if (!(0,
|
|
25459
|
+
if (!(0, import_fs17.existsSync)(filePath)) {
|
|
25326
25460
|
result = "skipped";
|
|
25327
25461
|
} else {
|
|
25328
25462
|
let current;
|
|
25329
25463
|
try {
|
|
25330
|
-
current = JSON.parse((0,
|
|
25464
|
+
current = JSON.parse((0, import_fs17.readFileSync)(filePath, "utf8"));
|
|
25331
25465
|
} catch {
|
|
25332
25466
|
current = void 0;
|
|
25333
25467
|
}
|
|
@@ -25368,9 +25502,9 @@ function writeStateFileLockedCreateIf(filePath, predicate, transform2) {
|
|
|
25368
25502
|
}
|
|
25369
25503
|
let current = null;
|
|
25370
25504
|
let parseFailed = false;
|
|
25371
|
-
if ((0,
|
|
25505
|
+
if ((0, import_fs17.existsSync)(filePath)) {
|
|
25372
25506
|
try {
|
|
25373
|
-
current = JSON.parse((0,
|
|
25507
|
+
current = JSON.parse((0, import_fs17.readFileSync)(filePath, "utf8"));
|
|
25374
25508
|
} catch (error2) {
|
|
25375
25509
|
if (process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] CreateIf JSON-parse-failed ${filePath} ${error2?.message}`);
|
|
25376
25510
|
parseFailed = true;
|
|
@@ -25440,36 +25574,36 @@ function publishEmergencyFileExclusive(path14, content) {
|
|
|
25440
25574
|
let fd;
|
|
25441
25575
|
try {
|
|
25442
25576
|
if (!tempPath) return false;
|
|
25443
|
-
(0,
|
|
25444
|
-
fd = (0,
|
|
25577
|
+
(0, import_fs17.mkdirSync)((0, import_path17.dirname)(path14), { recursive: true });
|
|
25578
|
+
fd = (0, import_fs17.openSync)(tempPath, "wx", 384);
|
|
25445
25579
|
const bytes = Buffer.from(content);
|
|
25446
25580
|
let offset = 0;
|
|
25447
25581
|
while (offset < bytes.length) {
|
|
25448
|
-
const written = (0,
|
|
25582
|
+
const written = (0, import_fs17.writeSync)(fd, bytes, offset, bytes.length - offset);
|
|
25449
25583
|
if (written <= 0) throw new Error("emergency publication made no progress");
|
|
25450
25584
|
offset += written;
|
|
25451
25585
|
}
|
|
25452
|
-
(0,
|
|
25453
|
-
if ((0,
|
|
25454
|
-
(0,
|
|
25586
|
+
(0, import_fs17.fsyncSync)(fd);
|
|
25587
|
+
if ((0, import_fs17.statSync)(tempPath).size !== bytes.length) throw new Error("emergency publication truncated");
|
|
25588
|
+
(0, import_fs17.closeSync)(fd);
|
|
25455
25589
|
fd = void 0;
|
|
25456
|
-
(0,
|
|
25457
|
-
(0,
|
|
25590
|
+
(0, import_fs17.linkSync)(tempPath, path14);
|
|
25591
|
+
(0, import_fs17.unlinkSync)(tempPath);
|
|
25458
25592
|
return true;
|
|
25459
25593
|
} catch (error2) {
|
|
25460
|
-
if (process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] publishEmergencyFileExclusive failed path=${path14} tempPath=${tempPath} pathExists=${(0,
|
|
25594
|
+
if (process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] publishEmergencyFileExclusive failed path=${path14} tempPath=${tempPath} pathExists=${(0, import_fs17.existsSync)(path14)} err=${error2?.code} ${error2?.message}`);
|
|
25461
25595
|
return false;
|
|
25462
25596
|
} finally {
|
|
25463
25597
|
if (fd !== void 0) {
|
|
25464
25598
|
try {
|
|
25465
|
-
(0,
|
|
25599
|
+
(0, import_fs17.closeSync)(fd);
|
|
25466
25600
|
} catch {
|
|
25467
25601
|
}
|
|
25468
25602
|
}
|
|
25469
25603
|
if (tempPath) {
|
|
25470
25604
|
const generation = fileIdentity(tempPath);
|
|
25471
25605
|
try {
|
|
25472
|
-
if (generation && sameFile(tempPath, generation)) (0,
|
|
25606
|
+
if (generation && sameFile(tempPath, generation)) (0, import_fs17.unlinkSync)(tempPath);
|
|
25473
25607
|
} catch {
|
|
25474
25608
|
}
|
|
25475
25609
|
}
|
|
@@ -25497,7 +25631,7 @@ function acquireRecoveryClaim(path14, attempts = 50) {
|
|
|
25497
25631
|
return null;
|
|
25498
25632
|
}
|
|
25499
25633
|
try {
|
|
25500
|
-
(0,
|
|
25634
|
+
(0, import_fs17.unlinkSync)(path14);
|
|
25501
25635
|
} catch (error2) {
|
|
25502
25636
|
releaseMutationLock(lock);
|
|
25503
25637
|
if (process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] acquireRecoveryClaim existing-unlink-failed ${path14} ${error2.code}`);
|
|
@@ -25514,7 +25648,7 @@ function acquireRecoveryClaim(path14, attempts = 50) {
|
|
|
25514
25648
|
}
|
|
25515
25649
|
function readRecoveryClaim(path14) {
|
|
25516
25650
|
try {
|
|
25517
|
-
const owner = JSON.parse((0,
|
|
25651
|
+
const owner = JSON.parse((0, import_fs17.readFileSync)(path14, "utf8"));
|
|
25518
25652
|
return owner.version === 1 && Number.isSafeInteger(owner.pid) && owner.pid > 0 && typeof owner.processStart === "string" && typeof owner.createdAt === "string" && typeof owner.nonce === "string" ? owner : null;
|
|
25519
25653
|
} catch {
|
|
25520
25654
|
return null;
|
|
@@ -25527,9 +25661,9 @@ function releaseRecoveryClaim(path14, owner) {
|
|
|
25527
25661
|
const guardPath = `${path14}.recovery.guard`;
|
|
25528
25662
|
const key = (() => {
|
|
25529
25663
|
try {
|
|
25530
|
-
return (0,
|
|
25664
|
+
return (0, import_path17.resolve)((0, import_fs17.realpathSync)((0, import_path17.dirname)(guardPath)), (0, import_path17.basename)(guardPath));
|
|
25531
25665
|
} catch {
|
|
25532
|
-
return (0,
|
|
25666
|
+
return (0, import_path17.resolve)(guardPath);
|
|
25533
25667
|
}
|
|
25534
25668
|
})();
|
|
25535
25669
|
const lock = localLocks.get(key);
|
|
@@ -25539,7 +25673,7 @@ function releaseRecoveryClaim(path14, owner) {
|
|
|
25539
25673
|
if (current && sameRecoveryClaim(current, owner)) {
|
|
25540
25674
|
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
25541
25675
|
try {
|
|
25542
|
-
(0,
|
|
25676
|
+
(0, import_fs17.unlinkSync)(path14);
|
|
25543
25677
|
break;
|
|
25544
25678
|
} catch (error2) {
|
|
25545
25679
|
if (error2.code === "ENOENT") break;
|
|
@@ -25560,7 +25694,7 @@ function createEmergencyJournal(path14, journal) {
|
|
|
25560
25694
|
}
|
|
25561
25695
|
function readEmergencyJournal(path14) {
|
|
25562
25696
|
try {
|
|
25563
|
-
const journal = JSON.parse((0,
|
|
25697
|
+
const journal = JSON.parse((0, import_fs17.readFileSync)(path14, "utf8"));
|
|
25564
25698
|
if (journal.version !== 1 || typeof journal.transactionId !== "string" || !/^[0-9a-f-]{36}$/i.test(journal.transactionId) || !journal.owner || !Number.isInteger(journal.owner.pid) || journal.owner.pid <= 0 || typeof journal.owner.processStart !== "string" || typeof journal.owner.nonce !== "string" || !/^[0-9a-f-]{36}$/i.test(journal.owner.nonce) || journal.sessionOwner !== void 0 && typeof journal.sessionOwner !== "string" || journal.originalDigest !== void 0 && (typeof journal.originalDigest !== "string" || !/^[0-9a-f]{64}$/i.test(journal.originalDigest)) || journal.intendedDigest !== void 0 && (typeof journal.intendedDigest !== "string" || !/^[0-9a-f]{64}$/i.test(journal.intendedDigest)) || journal.intent !== void 0 && journal.intent !== "clear" && journal.intent !== "publish" || typeof journal.quarantinePath !== "string" || journal.phase !== "preparing" && journal.phase !== "prepared" && journal.phase !== "quarantined" && journal.phase !== "published") return null;
|
|
25565
25699
|
const complete = typeof journal.originalDigest === "string" && (journal.intent === "clear" || journal.intent === "publish" && typeof journal.intendedDigest === "string");
|
|
25566
25700
|
return journal.phase === "preparing" || complete ? journal : null;
|
|
@@ -25570,7 +25704,7 @@ function readEmergencyJournal(path14) {
|
|
|
25570
25704
|
}
|
|
25571
25705
|
function fileIdentity(path14) {
|
|
25572
25706
|
try {
|
|
25573
|
-
const stat = (0,
|
|
25707
|
+
const stat = (0, import_fs17.statSync)(path14);
|
|
25574
25708
|
return { dev: stat.dev, ino: stat.ino };
|
|
25575
25709
|
} catch {
|
|
25576
25710
|
return null;
|
|
@@ -25580,7 +25714,7 @@ function sameStateFileGeneration(path14, expected) {
|
|
|
25580
25714
|
try {
|
|
25581
25715
|
const identity = fileIdentity(path14);
|
|
25582
25716
|
if (!identity || identity.dev !== expected.dev || identity.ino !== expected.ino) return false;
|
|
25583
|
-
return stateDigest((0,
|
|
25717
|
+
return stateDigest((0, import_fs17.readFileSync)(path14, "utf8")) === expected.digest;
|
|
25584
25718
|
} catch {
|
|
25585
25719
|
return false;
|
|
25586
25720
|
}
|
|
@@ -25599,29 +25733,29 @@ function replaceGenerationForTest(path14) {
|
|
|
25599
25733
|
}
|
|
25600
25734
|
function sameFile(path14, expected) {
|
|
25601
25735
|
const actual = fileIdentity(path14);
|
|
25602
|
-
return actual !== null && actual
|
|
25736
|
+
return actual !== null && sameFileIdentity(actual, expected);
|
|
25603
25737
|
}
|
|
25604
25738
|
function reconcileEmergencyPublicationTemps(filePath, authorizeState) {
|
|
25605
|
-
const directory = (0,
|
|
25739
|
+
const directory = (0, import_path17.dirname)(filePath);
|
|
25606
25740
|
const base = filePath.slice(directory.length + 1).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
25607
25741
|
const pattern = new RegExp(`^${base}\\.emergency-(journal\\.json|recovery\\.claim|quarantine\\.[0-9a-f-]{36}\\.payload)\\.(\\d+)\\.([^.]+)\\.([0-9a-f-]{36})\\.tmp$`, "i");
|
|
25608
25742
|
let names;
|
|
25609
25743
|
try {
|
|
25610
|
-
names = (0,
|
|
25744
|
+
names = (0, import_fs17.readdirSync)(directory);
|
|
25611
25745
|
} catch (error2) {
|
|
25612
25746
|
return error2.code === "ENOENT";
|
|
25613
25747
|
}
|
|
25614
25748
|
for (const name of names) {
|
|
25615
25749
|
const match = pattern.exec(name);
|
|
25616
25750
|
if (!match) continue;
|
|
25617
|
-
const path14 = (0,
|
|
25751
|
+
const path14 = (0, import_path17.join)(directory, name);
|
|
25618
25752
|
const matchedProcessStart = decodeProcessStartFromFilename(match[3]);
|
|
25619
25753
|
const currentStart = processStartIdentity(Number(match[2]));
|
|
25620
25754
|
if (currentStart === null || currentStart === matchedProcessStart) return false;
|
|
25621
25755
|
const generation = fileIdentity(path14);
|
|
25622
25756
|
try {
|
|
25623
25757
|
if (!generation) return false;
|
|
25624
|
-
const raw = (0,
|
|
25758
|
+
const raw = (0, import_fs17.readFileSync)(path14, "utf8");
|
|
25625
25759
|
if (authorizeState) {
|
|
25626
25760
|
if (match[1] === "journal.json") {
|
|
25627
25761
|
const journal = readEmergencyJournal(path14);
|
|
@@ -25634,8 +25768,8 @@ function reconcileEmergencyPublicationTemps(filePath, authorizeState) {
|
|
|
25634
25768
|
if (!claim || claim.pid !== Number(match[2]) || claim.processStart !== matchedProcessStart || claim.nonce !== match[4]) return false;
|
|
25635
25769
|
}
|
|
25636
25770
|
}
|
|
25637
|
-
if (!sameFile(path14, generation) || stateDigest((0,
|
|
25638
|
-
(0,
|
|
25771
|
+
if (!sameFile(path14, generation) || stateDigest((0, import_fs17.readFileSync)(path14, "utf8")) !== stateDigest(raw)) return false;
|
|
25772
|
+
(0, import_fs17.unlinkSync)(path14);
|
|
25639
25773
|
} catch {
|
|
25640
25774
|
return false;
|
|
25641
25775
|
}
|
|
@@ -25644,12 +25778,12 @@ function reconcileEmergencyPublicationTemps(filePath, authorizeState) {
|
|
|
25644
25778
|
}
|
|
25645
25779
|
function captureAndUnlinkPrimary(filePath, quarantinePath, expectedDigest) {
|
|
25646
25780
|
try {
|
|
25647
|
-
(0,
|
|
25781
|
+
(0, import_fs17.linkSync)(filePath, quarantinePath);
|
|
25648
25782
|
const captured = fileIdentity(quarantinePath);
|
|
25649
|
-
if (!captured || stateDigest((0,
|
|
25783
|
+
if (!captured || stateDigest((0, import_fs17.readFileSync)(quarantinePath, "utf8")) !== expectedDigest || !sameFile(filePath, captured)) return false;
|
|
25650
25784
|
emergencyReplaceAtCaptureBoundary(filePath);
|
|
25651
|
-
if (!sameFile(filePath, captured) || stateDigest((0,
|
|
25652
|
-
(0,
|
|
25785
|
+
if (!sameFile(filePath, captured) || stateDigest((0, import_fs17.readFileSync)(filePath, "utf8")) !== expectedDigest) return false;
|
|
25786
|
+
(0, import_fs17.unlinkSync)(filePath);
|
|
25653
25787
|
return true;
|
|
25654
25788
|
} catch {
|
|
25655
25789
|
return false;
|
|
@@ -25660,16 +25794,16 @@ function removeOwnedEmergencyArtifacts(journalPath, journal, removeQuarantine) {
|
|
|
25660
25794
|
if (!journalIsOwned(journalPath, journal.transactionId, journal.owner)) return false;
|
|
25661
25795
|
if (removeQuarantine) {
|
|
25662
25796
|
try {
|
|
25663
|
-
(0,
|
|
25797
|
+
(0, import_fs17.unlinkSync)(journal.quarantinePath);
|
|
25664
25798
|
} catch {
|
|
25665
25799
|
}
|
|
25666
25800
|
}
|
|
25667
25801
|
try {
|
|
25668
|
-
(0,
|
|
25802
|
+
(0, import_fs17.unlinkSync)(`${journal.quarantinePath}.payload`);
|
|
25669
25803
|
} catch {
|
|
25670
25804
|
}
|
|
25671
25805
|
if (!journalIsOwned(journalPath, journal.transactionId, journal.owner)) return false;
|
|
25672
|
-
(0,
|
|
25806
|
+
(0, import_fs17.unlinkSync)(journalPath);
|
|
25673
25807
|
return true;
|
|
25674
25808
|
} catch {
|
|
25675
25809
|
return false;
|
|
@@ -25683,11 +25817,11 @@ function recoveryGenerationsAuthorized(filePath, journal, authorizeState) {
|
|
|
25683
25817
|
];
|
|
25684
25818
|
let authenticatedJournalGeneration = journal === null;
|
|
25685
25819
|
for (const path14 of paths) {
|
|
25686
|
-
if (!(0,
|
|
25820
|
+
if (!(0, import_fs17.existsSync)(path14)) continue;
|
|
25687
25821
|
let raw;
|
|
25688
25822
|
let state;
|
|
25689
25823
|
try {
|
|
25690
|
-
raw = (0,
|
|
25824
|
+
raw = (0, import_fs17.readFileSync)(path14, "utf8");
|
|
25691
25825
|
const parsed = JSON.parse(raw);
|
|
25692
25826
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return false;
|
|
25693
25827
|
state = parsed;
|
|
@@ -25700,16 +25834,16 @@ function recoveryGenerationsAuthorized(filePath, journal, authorizeState) {
|
|
|
25700
25834
|
return authenticatedJournalGeneration;
|
|
25701
25835
|
}
|
|
25702
25836
|
function hasUnattributableRecoveryClaimArtifact(filePath, recoveryClaim) {
|
|
25703
|
-
const directory = (0,
|
|
25837
|
+
const directory = (0, import_path17.dirname)(filePath);
|
|
25704
25838
|
const base = filePath.slice(directory.length + 1).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
25705
25839
|
const tempPattern = new RegExp(`^${base}\\.emergency-recovery\\.claim\\.\\d+\\.[^.]+\\.[0-9a-f-]{36}\\.tmp$`, "i");
|
|
25706
25840
|
try {
|
|
25707
|
-
if ((0,
|
|
25841
|
+
if ((0, import_fs17.readdirSync)(directory).some((name) => tempPattern.test(name))) {
|
|
25708
25842
|
if (process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] hasUnattributable temp-match ${filePath}`);
|
|
25709
25843
|
return true;
|
|
25710
25844
|
}
|
|
25711
25845
|
const claimPath = `${filePath}.emergency-recovery.claim`;
|
|
25712
|
-
if (!(0,
|
|
25846
|
+
if (!(0, import_fs17.existsSync)(claimPath)) {
|
|
25713
25847
|
const result2 = recoveryClaim !== void 0;
|
|
25714
25848
|
if (result2 && process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] hasUnattributable no-claim-file-but-recoveryClaim-set ${filePath}`);
|
|
25715
25849
|
return result2;
|
|
@@ -25731,10 +25865,10 @@ function sharedRecoveryArtifactsAuthorized(filePath, authorizeState, recoveryCla
|
|
|
25731
25865
|
if (!authorizeState) return true;
|
|
25732
25866
|
if (hasUnattributableRecoveryClaimArtifact(filePath, recoveryClaim)) return false;
|
|
25733
25867
|
const journalPath = emergencyJournalPath(filePath);
|
|
25734
|
-
if (!(0,
|
|
25735
|
-
if (!(0,
|
|
25868
|
+
if (!(0, import_fs17.existsSync)(journalPath)) {
|
|
25869
|
+
if (!(0, import_fs17.existsSync)(filePath)) return true;
|
|
25736
25870
|
try {
|
|
25737
|
-
const state = JSON.parse((0,
|
|
25871
|
+
const state = JSON.parse((0, import_fs17.readFileSync)(filePath, "utf8"));
|
|
25738
25872
|
return state !== null && typeof state === "object" && !Array.isArray(state) && authorizeState(state);
|
|
25739
25873
|
} catch {
|
|
25740
25874
|
return false;
|
|
@@ -25747,13 +25881,13 @@ function emergencyReplaceAtRecoveryBoundary(filePath) {
|
|
|
25747
25881
|
if (process.env.NODE_ENV !== "test" || process.env.OMC_TEST_EMERGENCY_RECOVERY_REPLACEMENT_PATH !== filePath || !process.env.OMC_TEST_EMERGENCY_RECOVERY_REPLACEMENT_BASE64) return;
|
|
25748
25882
|
try {
|
|
25749
25883
|
const replacements = JSON.parse(Buffer.from(process.env.OMC_TEST_EMERGENCY_RECOVERY_REPLACEMENT_BASE64, "base64").toString("utf8"));
|
|
25750
|
-
const directory = (0,
|
|
25751
|
-
for (const name of (0,
|
|
25752
|
-
if (name === (0,
|
|
25884
|
+
const directory = (0, import_path17.dirname)(filePath);
|
|
25885
|
+
for (const name of (0, import_fs17.readdirSync)(directory)) {
|
|
25886
|
+
if (name === (0, import_path17.basename)(filePath) || name.startsWith(`${(0, import_path17.basename)(filePath)}.emergency-`)) (0, import_fs17.unlinkSync)((0, import_path17.join)(directory, name));
|
|
25753
25887
|
}
|
|
25754
25888
|
for (const replacement of replacements) {
|
|
25755
|
-
if ((0,
|
|
25756
|
-
(0,
|
|
25889
|
+
if ((0, import_path17.dirname)(replacement.path) !== directory) throw new Error("invalid recovery replacement path");
|
|
25890
|
+
(0, import_fs17.writeFileSync)(replacement.path, replacement.content);
|
|
25757
25891
|
}
|
|
25758
25892
|
} finally {
|
|
25759
25893
|
delete process.env.OMC_TEST_EMERGENCY_RECOVERY_REPLACEMENT_PATH;
|
|
@@ -25767,12 +25901,12 @@ function recoverEmergencyStateFile(filePath, options) {
|
|
|
25767
25901
|
return owner === void 0 || owner === pathSessionId;
|
|
25768
25902
|
} : void 0);
|
|
25769
25903
|
const journalPath = emergencyJournalPath(filePath);
|
|
25770
|
-
if (!(0,
|
|
25904
|
+
if (!(0, import_fs17.existsSync)(filePath) && !(0, import_fs17.existsSync)(journalPath)) return true;
|
|
25771
25905
|
if (!sharedRecoveryArtifactsAuthorized(filePath, authorizeState)) {
|
|
25772
25906
|
if (process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] recoverEmergency prefilter-false ${filePath}`);
|
|
25773
25907
|
return false;
|
|
25774
25908
|
}
|
|
25775
|
-
if (!(0,
|
|
25909
|
+
if (!(0, import_fs17.existsSync)(journalPath)) {
|
|
25776
25910
|
if (!authorizeState) return reconcileEmergencyPublicationTemps(filePath);
|
|
25777
25911
|
const claimPath2 = `${filePath}.emergency-recovery.claim`;
|
|
25778
25912
|
const claim2 = acquireRecoveryClaim(claimPath2);
|
|
@@ -25781,7 +25915,7 @@ function recoverEmergencyStateFile(filePath, options) {
|
|
|
25781
25915
|
return false;
|
|
25782
25916
|
}
|
|
25783
25917
|
try {
|
|
25784
|
-
if ((0,
|
|
25918
|
+
if ((0, import_fs17.existsSync)(journalPath) || !sharedRecoveryArtifactsAuthorized(filePath, authorizeState, claim2)) {
|
|
25785
25919
|
if (process.env.OMC_LOCK_DEBUG) console.error(`[lock-debug] recoverEmergency no-journal-revalidate-false ${filePath}`);
|
|
25786
25920
|
return false;
|
|
25787
25921
|
}
|
|
@@ -25802,8 +25936,8 @@ function recoverEmergencyStateFile(filePath, options) {
|
|
|
25802
25936
|
const current = readEmergencyJournal(journalPath);
|
|
25803
25937
|
if (!recoveryGenerationsAuthorized(filePath, current, authorizeState)) return true;
|
|
25804
25938
|
if (!reconcileEmergencyPublicationTemps(filePath, authorizeState)) return false;
|
|
25805
|
-
if (!generation || readEmergencyJournal(journalPath) !== null || !(0,
|
|
25806
|
-
(0,
|
|
25939
|
+
if (!generation || readEmergencyJournal(journalPath) !== null || !(0, import_fs17.existsSync)(filePath) || !sameFile(journalPath, generation)) return false;
|
|
25940
|
+
(0, import_fs17.unlinkSync)(journalPath);
|
|
25807
25941
|
return true;
|
|
25808
25942
|
} catch {
|
|
25809
25943
|
return false;
|
|
@@ -25828,7 +25962,7 @@ function recoverEmergencyStateFile(filePath, options) {
|
|
|
25828
25962
|
}
|
|
25829
25963
|
function recoverDeadEmergencyStateFile(filePath, authorizeState) {
|
|
25830
25964
|
const journalPath = emergencyJournalPath(filePath);
|
|
25831
|
-
if (!(0,
|
|
25965
|
+
if (!(0, import_fs17.existsSync)(journalPath)) return true;
|
|
25832
25966
|
const journal = readEmergencyJournal(journalPath);
|
|
25833
25967
|
if (!journal || journal.quarantinePath !== `${filePath}.emergency-quarantine.${journal.transactionId}`) return false;
|
|
25834
25968
|
if (isEmergencyOwnerLive(journal.owner)) return false;
|
|
@@ -25838,7 +25972,7 @@ function recoverDeadEmergencyStateFile(filePath, authorizeState) {
|
|
|
25838
25972
|
const payloadPath = `${journal.quarantinePath}.payload`;
|
|
25839
25973
|
const digest = (path14) => {
|
|
25840
25974
|
try {
|
|
25841
|
-
return stateDigest((0,
|
|
25975
|
+
return stateDigest((0, import_fs17.readFileSync)(path14, "utf8"));
|
|
25842
25976
|
} catch {
|
|
25843
25977
|
return null;
|
|
25844
25978
|
}
|
|
@@ -25846,14 +25980,14 @@ function recoverDeadEmergencyStateFile(filePath, authorizeState) {
|
|
|
25846
25980
|
if (journal.phase === "preparing") {
|
|
25847
25981
|
const complete = typeof journal.originalDigest === "string" && (journal.intent === "clear" || journal.intent === "publish" && typeof journal.intendedDigest === "string");
|
|
25848
25982
|
if (!complete) {
|
|
25849
|
-
if ((0,
|
|
25983
|
+
if ((0, import_fs17.existsSync)(journal.quarantinePath) || (0, import_fs17.existsSync)(payloadPath)) return false;
|
|
25850
25984
|
return removeOwnedEmergencyArtifacts(journalPath, journal, false);
|
|
25851
25985
|
}
|
|
25852
|
-
const originalStillPrimary = !(0,
|
|
25986
|
+
const originalStillPrimary = !(0, import_fs17.existsSync)(journal.quarantinePath) && digest(filePath) === journal.originalDigest;
|
|
25853
25987
|
if (journal.intent === "publish" && digest(payloadPath) !== journal.intendedDigest) {
|
|
25854
25988
|
return originalStillPrimary && removeOwnedEmergencyArtifacts(journalPath, journal, false);
|
|
25855
25989
|
}
|
|
25856
|
-
if (journal.intent === "clear" && (0,
|
|
25990
|
+
if (journal.intent === "clear" && (0, import_fs17.existsSync)(payloadPath)) {
|
|
25857
25991
|
return originalStillPrimary && removeOwnedEmergencyArtifacts(journalPath, journal, false);
|
|
25858
25992
|
}
|
|
25859
25993
|
journal.phase = "prepared";
|
|
@@ -25862,8 +25996,8 @@ function recoverDeadEmergencyStateFile(filePath, authorizeState) {
|
|
|
25862
25996
|
const originalDigest = journal.originalDigest;
|
|
25863
25997
|
const intent = journal.intent;
|
|
25864
25998
|
const intendedDigest = journal.intendedDigest;
|
|
25865
|
-
const hasPrimary = (0,
|
|
25866
|
-
const hasQuarantine = (0,
|
|
25999
|
+
const hasPrimary = (0, import_fs17.existsSync)(filePath);
|
|
26000
|
+
const hasQuarantine = (0, import_fs17.existsSync)(journal.quarantinePath);
|
|
25867
26001
|
const finalize = () => removeOwnedEmergencyArtifacts(journalPath, journal, hasQuarantine);
|
|
25868
26002
|
if (hasPrimary && hasQuarantine) {
|
|
25869
26003
|
if (intent === "publish" && digest(filePath) === intendedDigest && digest(journal.quarantinePath) === originalDigest) return finalize();
|
|
@@ -25874,7 +26008,7 @@ function recoverDeadEmergencyStateFile(filePath, authorizeState) {
|
|
|
25874
26008
|
if (intent === "publish" && digest(payloadPath) !== intendedDigest) return false;
|
|
25875
26009
|
if (!owned()) return false;
|
|
25876
26010
|
if (!captureAndUnlinkPrimary(filePath, journal.quarantinePath, originalDigest)) {
|
|
25877
|
-
if (owned() && (0,
|
|
26011
|
+
if (owned() && (0, import_fs17.existsSync)(filePath) && (0, import_fs17.existsSync)(journal.quarantinePath) && digest(filePath) !== originalDigest) {
|
|
25878
26012
|
removeOwnedEmergencyArtifacts(journalPath, journal, true);
|
|
25879
26013
|
}
|
|
25880
26014
|
return false;
|
|
@@ -25890,9 +26024,9 @@ function recoverDeadEmergencyStateFile(filePath, authorizeState) {
|
|
|
25890
26024
|
if (digest(journal.quarantinePath) !== originalDigest || !owned()) return false;
|
|
25891
26025
|
try {
|
|
25892
26026
|
if (intent === "clear") return removeOwnedEmergencyArtifacts(journalPath, journal, true);
|
|
25893
|
-
const payload = (0,
|
|
26027
|
+
const payload = (0, import_fs17.readFileSync)(payloadPath, "utf8");
|
|
25894
26028
|
if (stateDigest(payload) !== intendedDigest || !owned()) return false;
|
|
25895
|
-
(0,
|
|
26029
|
+
(0, import_fs17.linkSync)(payloadPath, filePath);
|
|
25896
26030
|
journal.phase = "published";
|
|
25897
26031
|
if (!writeEmergencyJournal(journalPath, journal)) return false;
|
|
25898
26032
|
return removeOwnedEmergencyArtifacts(journalPath, journal, true);
|
|
@@ -25948,11 +26082,11 @@ function emergencyMutateStateFileIf(filePath, predicate, transform2, recoveryOpt
|
|
|
25948
26082
|
journal = { version: 1, transactionId, owner, quarantinePath, phase: "preparing" };
|
|
25949
26083
|
if (!createEmergencyJournal(journalPath, journal)) return false;
|
|
25950
26084
|
const owns = () => journal !== null && journalIsOwned(journalPath, transactionId, owner);
|
|
25951
|
-
if (!(0,
|
|
26085
|
+
if (!(0, import_fs17.existsSync)(filePath)) {
|
|
25952
26086
|
removeOwnedEmergencyArtifacts(journalPath, journal, false);
|
|
25953
26087
|
return false;
|
|
25954
26088
|
}
|
|
25955
|
-
const originalRaw = (0,
|
|
26089
|
+
const originalRaw = (0, import_fs17.readFileSync)(filePath, "utf8");
|
|
25956
26090
|
const current = JSON.parse(originalRaw);
|
|
25957
26091
|
if (!predicate(current)) {
|
|
25958
26092
|
removeOwnedEmergencyArtifacts(journalPath, journal, false);
|
|
@@ -25976,7 +26110,7 @@ function emergencyMutateStateFileIf(filePath, predicate, transform2, recoveryOpt
|
|
|
25976
26110
|
}
|
|
25977
26111
|
journal.phase = "prepared";
|
|
25978
26112
|
if (!writeEmergencyJournal(journalPath, journal)) return false;
|
|
25979
|
-
const authenticatedRaw = (0,
|
|
26113
|
+
const authenticatedRaw = (0, import_fs17.readFileSync)(filePath, "utf8");
|
|
25980
26114
|
const authenticated = JSON.parse(authenticatedRaw);
|
|
25981
26115
|
if (!owns() || stateDigest(authenticatedRaw) !== journal.originalDigest || !predicate(authenticated)) {
|
|
25982
26116
|
removeOwnedEmergencyArtifacts(journalPath, journal, false);
|
|
@@ -25999,7 +26133,7 @@ function emergencyMutateStateFileIf(filePath, predicate, transform2, recoveryOpt
|
|
|
25999
26133
|
}
|
|
26000
26134
|
if (transformedRaw !== void 0) {
|
|
26001
26135
|
if (!owns()) return false;
|
|
26002
|
-
(0,
|
|
26136
|
+
(0, import_fs17.linkSync)(payloadPath, filePath);
|
|
26003
26137
|
journal.phase = "published";
|
|
26004
26138
|
if (!writeEmergencyJournal(journalPath, journal)) return false;
|
|
26005
26139
|
if (emergencyCrashAt("after-publication")) {
|
|
@@ -26054,7 +26188,7 @@ function resolveFile(mode, directory, sessionId) {
|
|
|
26054
26188
|
}
|
|
26055
26189
|
function discoverStateFile(path14, extra = {}) {
|
|
26056
26190
|
try {
|
|
26057
|
-
const state = JSON.parse((0,
|
|
26191
|
+
const state = JSON.parse((0, import_fs17.readFileSync)(path14, "utf-8"));
|
|
26058
26192
|
return {
|
|
26059
26193
|
path: path14,
|
|
26060
26194
|
snapshot: JSON.stringify(state),
|
|
@@ -26069,7 +26203,7 @@ function discoverStateFile(path14, extra = {}) {
|
|
|
26069
26203
|
}
|
|
26070
26204
|
function hasAuthenticatedCompletionEvidence(path14, sessionId) {
|
|
26071
26205
|
try {
|
|
26072
|
-
const evidence = JSON.parse((0,
|
|
26206
|
+
const evidence = JSON.parse((0, import_fs17.readFileSync)(path14, "utf-8"));
|
|
26073
26207
|
return evidence.session_id === sessionId && typeof evidence.ended_at === "string" && evidence.ended_at.trim().length > 0 && Number.isFinite(Date.parse(evidence.ended_at));
|
|
26074
26208
|
} catch {
|
|
26075
26209
|
return false;
|
|
@@ -26095,7 +26229,7 @@ function findCompletedSessionStateCandidates(mode, directory, requesterSessionId
|
|
|
26095
26229
|
const baseDir = resolveStateRoot(directory);
|
|
26096
26230
|
for (const sid of listSessionIds(baseDir)) {
|
|
26097
26231
|
if (requesterSessionId && sid === requesterSessionId) continue;
|
|
26098
|
-
const completionEvidencePath = (0,
|
|
26232
|
+
const completionEvidencePath = (0, import_path17.join)(getOmcRoot(baseDir), "sessions", `${sid}.json`);
|
|
26099
26233
|
if (!hasAuthenticatedCompletionEvidence(completionEvidencePath, sid)) continue;
|
|
26100
26234
|
const candidatePath = resolveSessionStatePath(mode, sid, baseDir);
|
|
26101
26235
|
const candidate = discoverStateFile(candidatePath, { completedSessionId: sid, completionEvidencePath });
|
|
@@ -26140,11 +26274,11 @@ function writeModeState(mode, state, directory, sessionId) {
|
|
|
26140
26274
|
}
|
|
26141
26275
|
function readModeState(mode, directory, sessionId) {
|
|
26142
26276
|
const filePath = resolveFile(mode, directory, sessionId);
|
|
26143
|
-
if (!(0,
|
|
26277
|
+
if (!(0, import_fs17.existsSync)(filePath)) {
|
|
26144
26278
|
return null;
|
|
26145
26279
|
}
|
|
26146
26280
|
try {
|
|
26147
|
-
const content = (0,
|
|
26281
|
+
const content = (0, import_fs17.readFileSync)(filePath, "utf-8");
|
|
26148
26282
|
const parsed = JSON.parse(content);
|
|
26149
26283
|
if (sessionId && parsed && typeof parsed === "object" && !canClearStateForSession(parsed, sessionId)) {
|
|
26150
26284
|
return null;
|
|
@@ -26160,8 +26294,8 @@ function readModeState(mode, directory, sessionId) {
|
|
|
26160
26294
|
}
|
|
26161
26295
|
|
|
26162
26296
|
// src/hooks/mode-registry/index.ts
|
|
26163
|
-
var
|
|
26164
|
-
var
|
|
26297
|
+
var import_fs18 = require("fs");
|
|
26298
|
+
var import_path18 = require("path");
|
|
26165
26299
|
|
|
26166
26300
|
// src/lib/mode-names.ts
|
|
26167
26301
|
var MODE_NAMES = {
|
|
@@ -26258,26 +26392,26 @@ var MODE_CONFIGS = {
|
|
|
26258
26392
|
};
|
|
26259
26393
|
var EXCLUSIVE_MODES = [MODE_NAMES.AUTOPILOT, MODE_NAMES.AUTORESEARCH];
|
|
26260
26394
|
function getStateDir(cwd) {
|
|
26261
|
-
return (0,
|
|
26395
|
+
return (0, import_path18.join)(getOmcRoot(cwd), "state");
|
|
26262
26396
|
}
|
|
26263
26397
|
function getStateFilePath(cwd, mode, sessionId) {
|
|
26264
26398
|
const config2 = MODE_CONFIGS[mode];
|
|
26265
26399
|
if (sessionId) {
|
|
26266
26400
|
return resolveSessionStatePath(mode, sessionId, cwd);
|
|
26267
26401
|
}
|
|
26268
|
-
return (0,
|
|
26402
|
+
return (0, import_path18.join)(getStateDir(cwd), config2.stateFile);
|
|
26269
26403
|
}
|
|
26270
26404
|
function getMarkerFilePath(cwd, mode) {
|
|
26271
26405
|
const config2 = MODE_CONFIGS[mode];
|
|
26272
26406
|
if (!config2.markerFile) return null;
|
|
26273
|
-
return (0,
|
|
26407
|
+
return (0, import_path18.join)(getStateDir(cwd), config2.markerFile);
|
|
26274
26408
|
}
|
|
26275
26409
|
var WORKFLOW_SLOT_TOMBSTONE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26276
26410
|
function isWorkflowSlotTombstonedForMode(cwd, mode, sessionId, now = Date.now()) {
|
|
26277
26411
|
try {
|
|
26278
|
-
const
|
|
26279
|
-
if (!(0,
|
|
26280
|
-
const raw = JSON.parse((0,
|
|
26412
|
+
const ledgerPath2 = sessionId ? resolveSessionStatePath("skill-active", sessionId, cwd) : (0, import_path18.join)(getStateDir(cwd), "skill-active-state.json");
|
|
26413
|
+
if (!(0, import_fs18.existsSync)(ledgerPath2)) return false;
|
|
26414
|
+
const raw = JSON.parse((0, import_fs18.readFileSync)(ledgerPath2, "utf-8"));
|
|
26281
26415
|
const slots = raw.active_skills;
|
|
26282
26416
|
if (!slots || typeof slots !== "object") return false;
|
|
26283
26417
|
const slot = slots[mode];
|
|
@@ -26300,7 +26434,7 @@ function isJsonModeActive(cwd, mode, sessionId) {
|
|
|
26300
26434
|
if (sessionId) {
|
|
26301
26435
|
const sessionStateFile = resolveSessionStatePath(mode, sessionId, cwd);
|
|
26302
26436
|
try {
|
|
26303
|
-
const content = (0,
|
|
26437
|
+
const content = (0, import_fs18.readFileSync)(sessionStateFile, "utf-8");
|
|
26304
26438
|
const state = JSON.parse(content);
|
|
26305
26439
|
const ownerSessionId = getStateSessionOwner(state);
|
|
26306
26440
|
if (ownerSessionId && ownerSessionId !== sessionId) {
|
|
@@ -26319,7 +26453,7 @@ function isJsonModeActive(cwd, mode, sessionId) {
|
|
|
26319
26453
|
}
|
|
26320
26454
|
const stateFile = getStateFilePath(cwd, mode);
|
|
26321
26455
|
try {
|
|
26322
|
-
const content = (0,
|
|
26456
|
+
const content = (0, import_fs18.readFileSync)(stateFile, "utf-8");
|
|
26323
26457
|
const state = JSON.parse(content);
|
|
26324
26458
|
if (getStateSessionOwner(state)) {
|
|
26325
26459
|
return false;
|
|
@@ -26352,7 +26486,7 @@ function getAllModeStatuses(cwd, sessionId) {
|
|
|
26352
26486
|
const stateFilePath = getStateFilePath(cwd, mode, sessionId);
|
|
26353
26487
|
const raw = (() => {
|
|
26354
26488
|
try {
|
|
26355
|
-
return JSON.parse((0,
|
|
26489
|
+
return JSON.parse((0, import_fs18.readFileSync)(stateFilePath, "utf8"));
|
|
26356
26490
|
} catch {
|
|
26357
26491
|
return null;
|
|
26358
26492
|
}
|
|
@@ -26367,7 +26501,7 @@ function getAllModeStatuses(cwd, sessionId) {
|
|
|
26367
26501
|
}
|
|
26368
26502
|
function readJsonSnapshot(filePath) {
|
|
26369
26503
|
try {
|
|
26370
|
-
const state = JSON.parse((0,
|
|
26504
|
+
const state = JSON.parse((0, import_fs18.readFileSync)(filePath, "utf-8"));
|
|
26371
26505
|
return { state, snapshot: JSON.stringify(state) };
|
|
26372
26506
|
} catch {
|
|
26373
26507
|
return null;
|
|
@@ -26376,14 +26510,14 @@ function readJsonSnapshot(filePath) {
|
|
|
26376
26510
|
function clearDiscoveredJsonFile(filePath, observed, predicate = () => true) {
|
|
26377
26511
|
if (!observed) {
|
|
26378
26512
|
const result2 = clearStateFileLockedIf(filePath, predicate);
|
|
26379
|
-
return result2 !== "failed" && !(result2 === "skipped" && (0,
|
|
26513
|
+
return result2 !== "failed" && !(result2 === "skipped" && (0, import_fs18.existsSync)(filePath));
|
|
26380
26514
|
}
|
|
26381
26515
|
if (!predicate(observed.state)) return true;
|
|
26382
26516
|
const result = clearStateFileLockedIf(
|
|
26383
26517
|
filePath,
|
|
26384
26518
|
(current) => predicate(current) && JSON.stringify(current) === observed.snapshot
|
|
26385
26519
|
);
|
|
26386
|
-
return result !== "failed" && !(result === "skipped" && (0,
|
|
26520
|
+
return result !== "failed" && !(result === "skipped" && (0, import_fs18.existsSync)(filePath));
|
|
26387
26521
|
}
|
|
26388
26522
|
function clearModeState(mode, cwd, sessionId, expectedState) {
|
|
26389
26523
|
const config2 = MODE_CONFIGS[mode];
|
|
@@ -26397,7 +26531,7 @@ function clearModeState(mode, cwd, sessionId, expectedState) {
|
|
|
26397
26531
|
const sessionStateFile = resolveSessionStatePath(mode, sessionId, cwd);
|
|
26398
26532
|
try {
|
|
26399
26533
|
const result = clearStateFileLockedIf(sessionStateFile, (current) => canClearStateForSession(current, sessionId) && (!expectedState || JSON.stringify(current) === JSON.stringify(expectedState)));
|
|
26400
|
-
if (result === "failed" || result === "skipped" && (0,
|
|
26534
|
+
if (result === "failed" || result === "skipped" && (0, import_fs18.existsSync)(sessionStateFile)) throw new Error(getStateMutationLockFailureMessage());
|
|
26401
26535
|
} catch (err) {
|
|
26402
26536
|
if (err.code !== "ENOENT") {
|
|
26403
26537
|
success = false;
|
|
@@ -26414,7 +26548,7 @@ function clearModeState(mode, cwd, sessionId, expectedState) {
|
|
|
26414
26548
|
}
|
|
26415
26549
|
if (markerFile) {
|
|
26416
26550
|
try {
|
|
26417
|
-
const markerRaw = JSON.parse((0,
|
|
26551
|
+
const markerRaw = JSON.parse((0, import_fs18.readFileSync)(markerFile, "utf-8"));
|
|
26418
26552
|
const markerSessionId = markerRaw.session_id ?? markerRaw.sessionId;
|
|
26419
26553
|
if (!markerSessionId || markerSessionId === sessionId) {
|
|
26420
26554
|
try {
|
|
@@ -26440,7 +26574,7 @@ function clearModeState(mode, cwd, sessionId, expectedState) {
|
|
|
26440
26574
|
if (!isSessionScopedClear) {
|
|
26441
26575
|
try {
|
|
26442
26576
|
const result = clearStateFileLockedIf(stateFile, (current) => !expectedState || JSON.stringify(current) === JSON.stringify(expectedState));
|
|
26443
|
-
if (result === "failed" || result === "skipped" && (0,
|
|
26577
|
+
if (result === "failed" || result === "skipped" && (0, import_fs18.existsSync)(stateFile)) throw new Error(getStateMutationLockFailureMessage());
|
|
26444
26578
|
} catch (err) {
|
|
26445
26579
|
if (err.code !== "ENOENT") {
|
|
26446
26580
|
success = false;
|
|
@@ -26462,23 +26596,23 @@ function getActiveSessionsForMode(mode, cwd) {
|
|
|
26462
26596
|
}
|
|
26463
26597
|
|
|
26464
26598
|
// src/hooks/autopilot/named-workflow-resume-validator.ts
|
|
26465
|
-
var
|
|
26599
|
+
var import_fs26 = require("fs");
|
|
26466
26600
|
var import_crypto8 = require("crypto");
|
|
26467
|
-
var
|
|
26601
|
+
var import_path28 = require("path");
|
|
26468
26602
|
|
|
26469
26603
|
// src/hooks/autopilot/pipeline.ts
|
|
26470
26604
|
var import_crypto7 = require("crypto");
|
|
26471
26605
|
|
|
26472
26606
|
// src/config/plan-output.ts
|
|
26473
|
-
var
|
|
26607
|
+
var import_path19 = require("path");
|
|
26474
26608
|
|
|
26475
26609
|
// src/hooks/autopilot/state.ts
|
|
26476
|
-
var
|
|
26477
|
-
var
|
|
26610
|
+
var import_fs25 = require("fs");
|
|
26611
|
+
var import_path27 = require("path");
|
|
26478
26612
|
|
|
26479
26613
|
// src/config/loader.ts
|
|
26480
|
-
var
|
|
26481
|
-
var
|
|
26614
|
+
var import_fs19 = require("fs");
|
|
26615
|
+
var import_path20 = require("path");
|
|
26482
26616
|
|
|
26483
26617
|
// src/shared/types.ts
|
|
26484
26618
|
var CANONICAL_TEAM_ROLES = [
|
|
@@ -26761,32 +26895,32 @@ var KNOWN_AGENT_NAME_SET = new Set(KNOWN_AGENT_NAMES);
|
|
|
26761
26895
|
|
|
26762
26896
|
// src/hooks/ralph/loop.ts
|
|
26763
26897
|
var import_child_process11 = require("child_process");
|
|
26764
|
-
var
|
|
26898
|
+
var import_path25 = require("path");
|
|
26765
26899
|
|
|
26766
26900
|
// src/hooks/ralph/prd.ts
|
|
26767
26901
|
var import_crypto5 = require("crypto");
|
|
26768
|
-
var
|
|
26769
|
-
var
|
|
26902
|
+
var import_fs20 = require("fs");
|
|
26903
|
+
var import_path21 = require("path");
|
|
26770
26904
|
|
|
26771
26905
|
// src/hooks/ralph/stale-prd.ts
|
|
26772
26906
|
var import_child_process10 = require("child_process");
|
|
26773
|
-
var
|
|
26774
|
-
var
|
|
26907
|
+
var import_fs21 = require("fs");
|
|
26908
|
+
var import_path22 = require("path");
|
|
26775
26909
|
var DEFAULT_STALE_PRD_AFTER_MS = 2 * 60 * 60 * 1e3;
|
|
26776
26910
|
var GIT_MAX_BUFFER = 1024 * 1024;
|
|
26777
26911
|
|
|
26778
26912
|
// src/hooks/ralph/progress.ts
|
|
26779
|
-
var import_fs21 = require("fs");
|
|
26780
|
-
var import_path22 = require("path");
|
|
26781
|
-
|
|
26782
|
-
// src/hooks/team-canonical-state.ts
|
|
26783
26913
|
var import_fs22 = require("fs");
|
|
26784
26914
|
var import_path23 = require("path");
|
|
26785
26915
|
|
|
26916
|
+
// src/hooks/team-canonical-state.ts
|
|
26917
|
+
var import_fs23 = require("fs");
|
|
26918
|
+
var import_path24 = require("path");
|
|
26919
|
+
|
|
26786
26920
|
// src/hooks/ralph/verifier.ts
|
|
26787
26921
|
var import_crypto6 = require("crypto");
|
|
26788
|
-
var
|
|
26789
|
-
var
|
|
26922
|
+
var import_fs24 = require("fs");
|
|
26923
|
+
var import_path26 = require("path");
|
|
26790
26924
|
|
|
26791
26925
|
// src/utils/omc-cli-rendering.ts
|
|
26792
26926
|
var import_child_process12 = require("child_process");
|
|
@@ -26945,7 +27079,7 @@ function validFileIdentity(value) {
|
|
|
26945
27079
|
]) && fileId(value.device) && fileId(value.inode) && safeInteger(value.size) && typeof value.mtimeNs === "string" && /^\d+$/.test(value.mtimeNs) && typeof value.ctimeNs === "string" && /^\d+$/.test(value.ctimeNs) && typeof value.contentSha256 === "string" && /^[a-f0-9]{64}$/.test(value.contentSha256);
|
|
26946
27080
|
}
|
|
26947
27081
|
function namedWorkflowRuntimeSupported() {
|
|
26948
|
-
return typeof
|
|
27082
|
+
return typeof import_fs26.constants.O_RDONLY === "number" && process.env.OMC_TEST_FLOCK_AVAILABLE !== "0" && ((0, import_fs26.existsSync)("/usr/bin/flock") || (0, import_fs26.existsSync)("/bin/flock") || isStateMutationLockingSupported());
|
|
26949
27083
|
}
|
|
26950
27084
|
function validBoundaryShape(value, sessionId) {
|
|
26951
27085
|
if (!isRecord(value) || !exactKeys(value, [
|
|
@@ -26955,10 +27089,10 @@ function validBoundaryShape(value, sessionId) {
|
|
|
26955
27089
|
"sessionId",
|
|
26956
27090
|
"byteOffset",
|
|
26957
27091
|
"fileIdentity"
|
|
26958
|
-
]) || typeof sessionId !== "string" || value.sessionId !== sessionId || typeof value.transcriptRoot !== "string" || (0,
|
|
27092
|
+
]) || typeof sessionId !== "string" || value.sessionId !== sessionId || typeof value.transcriptRoot !== "string" || (0, import_path28.resolve)(value.transcriptRoot) !== value.transcriptRoot || typeof value.transcriptPath !== "string" || (0, import_path28.resolve)(value.transcriptPath) !== value.transcriptPath || (0, import_path28.basename)(value.transcriptPath) !== `${sessionId}.jsonl` || value.transcriptBasename !== `${sessionId}.jsonl` || !safeInteger(value.byteOffset) || !validFileIdentity(value.fileIdentity) || value.fileIdentity.size !== value.byteOffset)
|
|
26959
27093
|
return false;
|
|
26960
|
-
const relativePath = (0,
|
|
26961
|
-
return relativePath.length > 0 && relativePath !== ".." && !relativePath.startsWith(`..${
|
|
27094
|
+
const relativePath = (0, import_path28.relative)(value.transcriptRoot, value.transcriptPath);
|
|
27095
|
+
return relativePath.length > 0 && relativePath !== ".." && !relativePath.startsWith(`..${import_path28.sep}`);
|
|
26962
27096
|
}
|
|
26963
27097
|
function validateNamedWorkflowStateStructure(state, sessionId) {
|
|
26964
27098
|
if (!Object.prototype.hasOwnProperty.call(state, "workflow") || !Object.prototype.hasOwnProperty.call(state, "workflowRunId") || !Object.prototype.hasOwnProperty.call(state, "pipelineTracking")) return null;
|
|
@@ -26991,7 +27125,7 @@ function validateNamedWorkflowStateStructure(state, sessionId) {
|
|
|
26991
27125
|
if (previousObservation) {
|
|
26992
27126
|
const previousBoundary = previousObservation.activationBoundary;
|
|
26993
27127
|
const previousStable = previousObservation.stableFile;
|
|
26994
|
-
if (boundary.transcriptPath !== previousBoundary.transcriptPath || boundary.byteOffset !== previousStable.size || !
|
|
27128
|
+
if (boundary.transcriptPath !== previousBoundary.transcriptPath || boundary.byteOffset !== previousStable.size || !sameFileIdentity2(boundary.fileIdentity, previousStable)) return null;
|
|
26995
27129
|
}
|
|
26996
27130
|
previousObservation = observation;
|
|
26997
27131
|
}
|
|
@@ -26999,20 +27133,20 @@ function validateNamedWorkflowStateStructure(state, sessionId) {
|
|
|
26999
27133
|
const current = tracking.activationBoundary;
|
|
27000
27134
|
const stable = previousObservation.stableFile;
|
|
27001
27135
|
const boundary = previousObservation.activationBoundary;
|
|
27002
|
-
if (current.transcriptPath !== boundary.transcriptPath || current.byteOffset !== stable.size || !
|
|
27136
|
+
if (current.transcriptPath !== boundary.transcriptPath || current.byteOffset !== stable.size || !sameFileIdentity2(current.fileIdentity, stable)) return null;
|
|
27003
27137
|
}
|
|
27004
27138
|
if (terminal ? state.phase !== "complete" : state.phase !== workflow.stages[tracking.currentStageIndex]) return null;
|
|
27005
27139
|
return { tracking, task };
|
|
27006
27140
|
}
|
|
27007
|
-
function
|
|
27141
|
+
function sameFileIdentity2(left, right) {
|
|
27008
27142
|
if (!isRecord(left) || !isRecord(right)) return false;
|
|
27009
27143
|
return sameFileId(left.device, right.device) && sameFileId(left.inode, right.inode) && left.size === right.size && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs && left.contentSha256 === right.contentSha256;
|
|
27010
27144
|
}
|
|
27011
27145
|
|
|
27012
27146
|
// src/hooks/merge-readiness/runtime.ts
|
|
27013
27147
|
var import_child_process13 = require("child_process");
|
|
27014
|
-
var
|
|
27015
|
-
var
|
|
27148
|
+
var import_fs27 = require("fs");
|
|
27149
|
+
var import_path29 = require("path");
|
|
27016
27150
|
|
|
27017
27151
|
// src/hooks/merge-readiness/mcq.ts
|
|
27018
27152
|
var MERGE_READINESS_DIMENSIONS = [
|
|
@@ -27104,7 +27238,7 @@ function isNonEvidenceStateFile(name) {
|
|
|
27104
27238
|
}
|
|
27105
27239
|
function modeStateRecordsRun(filePath) {
|
|
27106
27240
|
try {
|
|
27107
|
-
const raw = (0,
|
|
27241
|
+
const raw = (0, import_fs27.readFileSync)(filePath, "utf-8");
|
|
27108
27242
|
const parsed = JSON.parse(raw);
|
|
27109
27243
|
if (parsed && typeof parsed === "object") {
|
|
27110
27244
|
if (parsed.active === true) return true;
|
|
@@ -27118,11 +27252,11 @@ function modeStateRecordsRun(filePath) {
|
|
|
27118
27252
|
}
|
|
27119
27253
|
function listArtifactFiles(directory, sessionId) {
|
|
27120
27254
|
const root = getOmcRoot(directory);
|
|
27121
|
-
const dirCandidates = ["plans", "artifacts", "logs", "specs", "interviews"].map((segment) => (0,
|
|
27255
|
+
const dirCandidates = ["plans", "artifacts", "logs", "specs", "interviews"].map((segment) => (0, import_path29.join)(root, segment)).filter((path14) => (0, import_fs27.existsSync)(path14));
|
|
27122
27256
|
const found = [];
|
|
27123
27257
|
const seen = /* @__PURE__ */ new Set();
|
|
27124
27258
|
const pushRelative = (full) => {
|
|
27125
|
-
const relativePath = (0,
|
|
27259
|
+
const relativePath = (0, import_path29.relative)(root, full).replace(/\\/g, "/");
|
|
27126
27260
|
if (relativePath.startsWith("artifacts/merge-readiness/")) return;
|
|
27127
27261
|
if (relativePath.includes("merge-readiness-state")) return;
|
|
27128
27262
|
if (seen.has(relativePath)) return;
|
|
@@ -27137,10 +27271,10 @@ function listArtifactFiles(directory, sessionId) {
|
|
|
27137
27271
|
const current = stack.pop();
|
|
27138
27272
|
if (!current) continue;
|
|
27139
27273
|
try {
|
|
27140
|
-
const entries = (0,
|
|
27274
|
+
const entries = (0, import_fs27.readdirSync)(current, { withFileTypes: true });
|
|
27141
27275
|
for (const entry of entries) {
|
|
27142
27276
|
if (perRoot >= MAX_PER_ROOT) break;
|
|
27143
|
-
const full = (0,
|
|
27277
|
+
const full = (0, import_path29.join)(current, entry.name);
|
|
27144
27278
|
if (entry.isDirectory()) {
|
|
27145
27279
|
stack.push(full);
|
|
27146
27280
|
} else if (entry.isFile() && /\.(md|json|txt|log)$/i.test(entry.name)) {
|
|
@@ -27153,15 +27287,15 @@ function listArtifactFiles(directory, sessionId) {
|
|
|
27153
27287
|
}
|
|
27154
27288
|
}
|
|
27155
27289
|
}
|
|
27156
|
-
const stateDir = (0,
|
|
27290
|
+
const stateDir = (0, import_path29.join)(root, "state");
|
|
27157
27291
|
const scanStateDir = (dir) => {
|
|
27158
|
-
if (!(0,
|
|
27292
|
+
if (!(0, import_fs27.existsSync)(dir)) return;
|
|
27159
27293
|
try {
|
|
27160
|
-
for (const entry of (0,
|
|
27294
|
+
for (const entry of (0, import_fs27.readdirSync)(dir, { withFileTypes: true })) {
|
|
27161
27295
|
if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
|
|
27162
27296
|
if (isNonEvidenceStateFile(entry.name)) continue;
|
|
27163
27297
|
if (!EVIDENCE_MODE_STATE_FILES.has(entry.name)) continue;
|
|
27164
|
-
const full = (0,
|
|
27298
|
+
const full = (0, import_path29.join)(dir, entry.name);
|
|
27165
27299
|
if (!modeStateRecordsRun(full)) continue;
|
|
27166
27300
|
pushRelative(full);
|
|
27167
27301
|
}
|
|
@@ -27170,7 +27304,7 @@ function listArtifactFiles(directory, sessionId) {
|
|
|
27170
27304
|
};
|
|
27171
27305
|
scanStateDir(stateDir);
|
|
27172
27306
|
if (sessionId) {
|
|
27173
|
-
scanStateDir((0,
|
|
27307
|
+
scanStateDir((0, import_path29.join)(stateDir, "sessions", sessionId));
|
|
27174
27308
|
}
|
|
27175
27309
|
return found.sort();
|
|
27176
27310
|
}
|
|
@@ -27538,8 +27672,8 @@ var import_node_crypto = require("node:crypto");
|
|
|
27538
27672
|
|
|
27539
27673
|
// src/team/team-owner-epoch.ts
|
|
27540
27674
|
var import_crypto9 = require("crypto");
|
|
27541
|
-
var
|
|
27542
|
-
var
|
|
27675
|
+
var import_fs28 = require("fs");
|
|
27676
|
+
var import_path31 = require("path");
|
|
27543
27677
|
var import_node_child_process = require("node:child_process");
|
|
27544
27678
|
|
|
27545
27679
|
// src/graph/runtime/native-contained-fs.ts
|
|
@@ -27561,7 +27695,7 @@ function getNativeContainedFs() {
|
|
|
27561
27695
|
loaded = (0, import_node_module.createRequire)(importMetaUrl)(binary);
|
|
27562
27696
|
return loaded;
|
|
27563
27697
|
} catch (cause) {
|
|
27564
|
-
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 });
|
|
27698
|
+
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 });
|
|
27565
27699
|
}
|
|
27566
27700
|
}
|
|
27567
27701
|
}
|
|
@@ -27572,7 +27706,7 @@ function getNativeContainedFs() {
|
|
|
27572
27706
|
}
|
|
27573
27707
|
|
|
27574
27708
|
// src/team/state-paths.ts
|
|
27575
|
-
var
|
|
27709
|
+
var import_path30 = require("path");
|
|
27576
27710
|
|
|
27577
27711
|
// src/team/team-owner-epoch.ts
|
|
27578
27712
|
function darwinProcessStartFromKinfo(raw, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
@@ -27583,7 +27717,7 @@ function darwinProcessStartFromKinfo(raw, nowSeconds = Math.floor(Date.now() / 1
|
|
|
27583
27717
|
return `${seconds}:${micros}`;
|
|
27584
27718
|
}
|
|
27585
27719
|
function processStartIdentityForPlatform(pid, platform = process.platform, exec = import_node_child_process.execFileSync) {
|
|
27586
|
-
return probeProcessStartIdentityForPlatform(pid, platform, exec,
|
|
27720
|
+
return probeProcessStartIdentityForPlatform(pid, platform, exec, import_fs28.readFileSync, false).identity;
|
|
27587
27721
|
}
|
|
27588
27722
|
function darwinProcessStartIdentityFromNative(pid) {
|
|
27589
27723
|
try {
|
|
@@ -27620,7 +27754,7 @@ function probeProcessStartIdentityForPlatform(pid, platform, exec, read, strict)
|
|
|
27620
27754
|
["-NoProfile", "-NonInteractive", "-Command", command],
|
|
27621
27755
|
{ encoding: "utf8", windowsHide: true }
|
|
27622
27756
|
).trim();
|
|
27623
|
-
return
|
|
27757
|
+
return /^[1-9]\d*$/.test(ticks) ? { identity: `win32:${ticks}`, precise: true } : { identity: null, precise: false };
|
|
27624
27758
|
}
|
|
27625
27759
|
if (platform === "darwin") {
|
|
27626
27760
|
if (strict) {
|
|
@@ -28037,29 +28171,29 @@ function redactMergeReadinessState(state) {
|
|
|
28037
28171
|
// src/tools/state-tools.ts
|
|
28038
28172
|
var MAX_MIGRATION_FILE_BYTES = 1048576;
|
|
28039
28173
|
function ensureMigrationDirectoryTree(root, target) {
|
|
28040
|
-
const rootResolved = (0,
|
|
28041
|
-
const targetResolved = (0,
|
|
28042
|
-
const suffix = (0,
|
|
28043
|
-
if (suffix.startsWith("..") || (0,
|
|
28174
|
+
const rootResolved = (0, import_path32.resolve)(root);
|
|
28175
|
+
const targetResolved = (0, import_path32.resolve)(target);
|
|
28176
|
+
const suffix = (0, import_path32.relative)(rootResolved, targetResolved);
|
|
28177
|
+
if (suffix.startsWith("..") || (0, import_path32.isAbsolute)(suffix)) {
|
|
28044
28178
|
throw new Error("state_migrate_non_git refuses a destination outside the canonical root");
|
|
28045
28179
|
}
|
|
28046
|
-
if (!(0,
|
|
28047
|
-
const rootStat = (0,
|
|
28180
|
+
if (!(0, import_fs29.existsSync)(rootResolved)) (0, import_fs29.mkdirSync)(rootResolved, { recursive: true });
|
|
28181
|
+
const rootStat = (0, import_fs29.lstatSync)(rootResolved);
|
|
28048
28182
|
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
|
|
28049
28183
|
throw new Error("state_migrate_non_git refuses symlinked migration roots");
|
|
28050
28184
|
}
|
|
28051
28185
|
let cursor = rootResolved;
|
|
28052
28186
|
for (const segment of suffix.split(/[\\/]+/).filter(Boolean)) {
|
|
28053
|
-
cursor = (0,
|
|
28054
|
-
if ((0,
|
|
28055
|
-
const stat = (0,
|
|
28187
|
+
cursor = (0, import_path32.join)(cursor, segment);
|
|
28188
|
+
if ((0, import_fs29.existsSync)(cursor)) {
|
|
28189
|
+
const stat = (0, import_fs29.lstatSync)(cursor);
|
|
28056
28190
|
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
28057
28191
|
throw new Error("state_migrate_non_git refuses symlinked migration roots");
|
|
28058
28192
|
}
|
|
28059
28193
|
continue;
|
|
28060
28194
|
}
|
|
28061
|
-
(0,
|
|
28062
|
-
const created = (0,
|
|
28195
|
+
(0, import_fs29.mkdirSync)(cursor);
|
|
28196
|
+
const created = (0, import_fs29.lstatSync)(cursor);
|
|
28063
28197
|
if (created.isSymbolicLink() || !created.isDirectory()) {
|
|
28064
28198
|
throw new Error("state_migrate_non_git refuses symlinked migration roots");
|
|
28065
28199
|
}
|
|
@@ -28105,7 +28239,7 @@ function getStateFileName(mode) {
|
|
|
28105
28239
|
}
|
|
28106
28240
|
function readJsonRecord(filePath) {
|
|
28107
28241
|
try {
|
|
28108
|
-
return JSON.parse((0,
|
|
28242
|
+
return JSON.parse((0, import_fs29.readFileSync)(filePath, "utf-8"));
|
|
28109
28243
|
} catch {
|
|
28110
28244
|
return null;
|
|
28111
28245
|
}
|
|
@@ -28122,7 +28256,7 @@ function teamStateLockPath(statePath) {
|
|
|
28122
28256
|
async function writeTeamState(statePath, sessionId, patch) {
|
|
28123
28257
|
return withProcessIdentityFileLock(teamStateLockPath(statePath), () => {
|
|
28124
28258
|
if (!recoverEmergencyStateFile(statePath)) {
|
|
28125
|
-
const existing = (0,
|
|
28259
|
+
const existing = (0, import_fs29.existsSync)(statePath) ? readJsonRecordStrict(statePath) : void 0;
|
|
28126
28260
|
if (existing === null) return { result: "corrupt" };
|
|
28127
28261
|
if (sessionId && existing && getStateSessionOwner(existing) !== void 0 && getStateSessionOwner(existing) !== sessionId) {
|
|
28128
28262
|
return { result: "foreign" };
|
|
@@ -28130,7 +28264,7 @@ async function writeTeamState(statePath, sessionId, patch) {
|
|
|
28130
28264
|
return { result: "failed" };
|
|
28131
28265
|
}
|
|
28132
28266
|
const transaction = withStateFileMutationLock(statePath, () => {
|
|
28133
|
-
if (!(0,
|
|
28267
|
+
if (!(0, import_fs29.existsSync)(statePath)) {
|
|
28134
28268
|
try {
|
|
28135
28269
|
atomicWriteJsonSync(statePath, patch);
|
|
28136
28270
|
return { result: "written", state: patch };
|
|
@@ -28164,7 +28298,7 @@ async function writeTeamState(statePath, sessionId, patch) {
|
|
|
28164
28298
|
}
|
|
28165
28299
|
function readJsonRecordStrict(filePath) {
|
|
28166
28300
|
try {
|
|
28167
|
-
const parsed = JSON.parse((0,
|
|
28301
|
+
const parsed = JSON.parse((0, import_fs29.readFileSync)(filePath, "utf-8"));
|
|
28168
28302
|
return isJsonRecord(parsed) ? parsed : null;
|
|
28169
28303
|
} catch {
|
|
28170
28304
|
return null;
|
|
@@ -28194,12 +28328,12 @@ function matchesNamedPauseTarget(current, sessionId, workflowRunId, stateDigest2
|
|
|
28194
28328
|
return current.active === true && current.workflowRunId === workflowRunId && hasValidatedNamedWorkflowTuple(current) && getStateSessionOwner(current) === sessionId && (stateDigest2 === void 0 || (0, import_crypto10.createHash)("sha256").update(JSON.stringify(current)).digest("hex") === stateDigest2);
|
|
28195
28329
|
}
|
|
28196
28330
|
function listSessionIdsUnderOmcRoot(omcRoot) {
|
|
28197
|
-
const sessionsDir = (0,
|
|
28198
|
-
if (!(0,
|
|
28331
|
+
const sessionsDir = (0, import_path32.join)(omcRoot, "state", "sessions");
|
|
28332
|
+
if (!(0, import_fs29.existsSync)(sessionsDir)) {
|
|
28199
28333
|
return [];
|
|
28200
28334
|
}
|
|
28201
28335
|
try {
|
|
28202
|
-
return (0,
|
|
28336
|
+
return (0, import_fs29.readdirSync)(sessionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/.test(name));
|
|
28203
28337
|
} catch {
|
|
28204
28338
|
return [];
|
|
28205
28339
|
}
|
|
@@ -28209,8 +28343,8 @@ function getConvergedOmcRoots(root) {
|
|
|
28209
28343
|
if (process.env.OMC_STATE_DIR) return [canonicalRoot];
|
|
28210
28344
|
if (probeGitTopLevel(root).status !== "ok") return [canonicalRoot];
|
|
28211
28345
|
const roots = /* @__PURE__ */ new Set([canonicalRoot]);
|
|
28212
|
-
roots.add((0,
|
|
28213
|
-
roots.add((0,
|
|
28346
|
+
roots.add((0, import_path32.join)(root, OmcPaths.ROOT));
|
|
28347
|
+
roots.add((0, import_path32.join)((0, import_os4.homedir)(), OmcPaths.ROOT));
|
|
28214
28348
|
return [...roots];
|
|
28215
28349
|
}
|
|
28216
28350
|
function getConvergedStateCandidates(mode, root, sessionId) {
|
|
@@ -28220,11 +28354,11 @@ function getConvergedStateCandidates(mode, root, sessionId) {
|
|
|
28220
28354
|
const filename = getStateFileName(mode);
|
|
28221
28355
|
const paths = /* @__PURE__ */ new Set();
|
|
28222
28356
|
for (const omcRoot of getConvergedOmcRoots(root)) {
|
|
28223
|
-
const stateDir = (0,
|
|
28357
|
+
const stateDir = (0, import_path32.join)(omcRoot, "state");
|
|
28224
28358
|
if (sessionId) {
|
|
28225
|
-
paths.add((0,
|
|
28359
|
+
paths.add((0, import_path32.join)(stateDir, "sessions", sessionId, filename));
|
|
28226
28360
|
for (const sid of listSessionIdsUnderOmcRoot(omcRoot)) {
|
|
28227
|
-
const candidatePath = (0,
|
|
28361
|
+
const candidatePath = (0, import_path32.join)(stateDir, "sessions", sid, filename);
|
|
28228
28362
|
const raw = readJsonRecord(candidatePath);
|
|
28229
28363
|
if (raw && getStateSessionOwner(raw) === sessionId) {
|
|
28230
28364
|
paths.add(candidatePath);
|
|
@@ -28232,11 +28366,11 @@ function getConvergedStateCandidates(mode, root, sessionId) {
|
|
|
28232
28366
|
}
|
|
28233
28367
|
} else {
|
|
28234
28368
|
for (const sid of listSessionIdsUnderOmcRoot(omcRoot)) {
|
|
28235
|
-
paths.add((0,
|
|
28369
|
+
paths.add((0, import_path32.join)(stateDir, "sessions", sid, filename));
|
|
28236
28370
|
}
|
|
28237
28371
|
}
|
|
28238
|
-
paths.add((0,
|
|
28239
|
-
paths.add((0,
|
|
28372
|
+
paths.add((0, import_path32.join)(stateDir, filename));
|
|
28373
|
+
paths.add((0, import_path32.join)(omcRoot, filename));
|
|
28240
28374
|
}
|
|
28241
28375
|
return [...paths];
|
|
28242
28376
|
}
|
|
@@ -28355,7 +28489,7 @@ function hasActiveConvergedState(mode, root, sessionId) {
|
|
|
28355
28489
|
return getConvergedStateCandidates(mode, root, sessionId).some((statePath) => isConvergedCandidateActiveForSession(statePath, sessionId));
|
|
28356
28490
|
}
|
|
28357
28491
|
function recordTeamClearFailure(mode, candidate, result, teamCleanup) {
|
|
28358
|
-
if (mode !== "team" || !teamCleanup || result === "cleared" || !(0,
|
|
28492
|
+
if (mode !== "team" || !teamCleanup || result === "cleared" || !(0, import_fs29.existsSync)(candidate.path)) return;
|
|
28359
28493
|
teamCleanup.blocked = true;
|
|
28360
28494
|
}
|
|
28361
28495
|
function blockForeignTeamPrimary(root, requesterSessionId, teamCleanup) {
|
|
@@ -28386,7 +28520,7 @@ function getSessionStatePath(mode, root, sessionId) {
|
|
|
28386
28520
|
function clearModePrimaryWithTeamLock(mode, statePath, clear, captured = true) {
|
|
28387
28521
|
if (mode !== "team") return clear();
|
|
28388
28522
|
try {
|
|
28389
|
-
return withProcessIdentityFileLockSync(teamStateLockPath(statePath), () => captured ? clear() : !(0,
|
|
28523
|
+
return withProcessIdentityFileLockSync(teamStateLockPath(statePath), () => captured ? clear() : !(0, import_fs29.existsSync)(statePath));
|
|
28390
28524
|
} catch {
|
|
28391
28525
|
return false;
|
|
28392
28526
|
}
|
|
@@ -28402,33 +28536,33 @@ function getLegacyStateFileCandidates(mode, root) {
|
|
|
28402
28536
|
const normalizedName = mode.endsWith("-state") ? mode : `${mode}-state`;
|
|
28403
28537
|
const candidates = [
|
|
28404
28538
|
getStatePath(mode, root),
|
|
28405
|
-
(0,
|
|
28539
|
+
(0, import_path32.join)(getOmcRoot(root), `${normalizedName}.json`)
|
|
28406
28540
|
];
|
|
28407
|
-
if (mode === "autopilot" && probeGitTopLevel(root).status === "ok") candidates.push((0,
|
|
28541
|
+
if (mode === "autopilot" && probeGitTopLevel(root).status === "ok") candidates.push((0, import_path32.join)((0, import_os4.homedir)(), ".omg", "state", "autopilot-state.json"));
|
|
28408
28542
|
return [...new Set(candidates)];
|
|
28409
28543
|
}
|
|
28410
28544
|
function isSharedHomeAutopilotCandidate(path14, root) {
|
|
28411
|
-
const sharedHomeStateRoot = (0,
|
|
28412
|
-
const candidatePath = (0,
|
|
28413
|
-
const canonicalStateRoot = (0,
|
|
28545
|
+
const sharedHomeStateRoot = (0, import_path32.resolve)((0, import_os4.homedir)(), ".omg", "state");
|
|
28546
|
+
const candidatePath = (0, import_path32.resolve)(path14);
|
|
28547
|
+
const canonicalStateRoot = (0, import_path32.resolve)(getOmcRoot(root), "state");
|
|
28414
28548
|
const isDescendant = (ancestor, descendant) => {
|
|
28415
|
-
const fromAncestor = (0,
|
|
28416
|
-
return fromAncestor === "" || !fromAncestor.startsWith(`..${
|
|
28549
|
+
const fromAncestor = (0, import_path32.relative)(ancestor, descendant);
|
|
28550
|
+
return fromAncestor === "" || !fromAncestor.startsWith(`..${import_path32.sep}`) && fromAncestor !== ".." && !(0, import_path32.isAbsolute)(fromAncestor);
|
|
28417
28551
|
};
|
|
28418
28552
|
return !isDescendant(canonicalStateRoot, candidatePath) && isDescendant(sharedHomeStateRoot, candidatePath);
|
|
28419
28553
|
}
|
|
28420
28554
|
function isStateCandidateForProject(mode, path14, state, root) {
|
|
28421
28555
|
if (mode !== "autopilot" || !isSharedHomeAutopilotCandidate(path14, root)) return true;
|
|
28422
|
-
return typeof state.project_path === "string" && (0,
|
|
28556
|
+
return typeof state.project_path === "string" && (0, import_path32.resolve)(state.project_path) === (0, import_path32.resolve)(root);
|
|
28423
28557
|
}
|
|
28424
28558
|
function isAutopilotRecoveryCandidateForProject(path14, root) {
|
|
28425
28559
|
if (!isSharedHomeAutopilotCandidate(path14, root)) return true;
|
|
28426
28560
|
const primary = readJsonRecord(path14);
|
|
28427
28561
|
if (primary) return isStateCandidateForProject("autopilot", path14, primary, root);
|
|
28428
|
-
const artifactPrefix = `${(0,
|
|
28562
|
+
const artifactPrefix = `${(0, import_path32.basename)(path14)}.emergency-quarantine.`;
|
|
28429
28563
|
let artifacts;
|
|
28430
28564
|
try {
|
|
28431
|
-
artifacts = (0,
|
|
28565
|
+
artifacts = (0, import_fs29.readdirSync)((0, import_path32.dirname)(path14)).filter(
|
|
28432
28566
|
(name) => name.startsWith(artifactPrefix) && (name.endsWith(".payload") || /^[0-9a-f-]{36}$/i.test(name.slice(artifactPrefix.length)))
|
|
28433
28567
|
);
|
|
28434
28568
|
} catch {
|
|
@@ -28436,12 +28570,12 @@ function isAutopilotRecoveryCandidateForProject(path14, root) {
|
|
|
28436
28570
|
}
|
|
28437
28571
|
if (artifacts.length === 0) return false;
|
|
28438
28572
|
return artifacts.every((name) => {
|
|
28439
|
-
const state = readJsonRecord((0,
|
|
28573
|
+
const state = readJsonRecord((0, import_path32.join)((0, import_path32.dirname)(path14), name));
|
|
28440
28574
|
return state !== null && isStateCandidateForProject("autopilot", path14, state, root);
|
|
28441
28575
|
});
|
|
28442
28576
|
}
|
|
28443
28577
|
function getWorkingDirectoryLocalOmcRoot(root) {
|
|
28444
|
-
return (0,
|
|
28578
|
+
return (0, import_path32.join)(root, OmcPaths.ROOT);
|
|
28445
28579
|
}
|
|
28446
28580
|
function shouldCheckWorkingDirectoryLocalState(root) {
|
|
28447
28581
|
if (probeGitTopLevel(root).status !== "ok") return false;
|
|
@@ -28449,13 +28583,13 @@ function shouldCheckWorkingDirectoryLocalState(root) {
|
|
|
28449
28583
|
}
|
|
28450
28584
|
function getWorkingDirectoryLocalSessionStatePath(mode, root, sessionId) {
|
|
28451
28585
|
const normalizedName = mode.endsWith("-state") ? mode : `${mode}-state`;
|
|
28452
|
-
return (0,
|
|
28586
|
+
return (0, import_path32.join)(getWorkingDirectoryLocalOmcRoot(root), "state", "sessions", sessionId, `${normalizedName}.json`);
|
|
28453
28587
|
}
|
|
28454
28588
|
function getWorkingDirectoryLocalLegacyStateFileCandidates(mode, root) {
|
|
28455
28589
|
const normalizedName = mode.endsWith("-state") ? mode : `${mode}-state`;
|
|
28456
28590
|
return [
|
|
28457
|
-
(0,
|
|
28458
|
-
(0,
|
|
28591
|
+
(0, import_path32.join)(getWorkingDirectoryLocalOmcRoot(root), "state", `${normalizedName}.json`),
|
|
28592
|
+
(0, import_path32.join)(getWorkingDirectoryLocalOmcRoot(root), `${normalizedName}.json`)
|
|
28459
28593
|
];
|
|
28460
28594
|
}
|
|
28461
28595
|
function getWorkingDirectoryLocalStateClearCandidates(mode, root, sessionId) {
|
|
@@ -28503,7 +28637,7 @@ function clearCompletedSessionStateCandidates(mode, root, requesterSessionId, di
|
|
|
28503
28637
|
return clearStateCandidates(
|
|
28504
28638
|
mode,
|
|
28505
28639
|
discovered,
|
|
28506
|
-
(candidate, current) => current.active === true && candidate.ownerSessionId === candidate.completedSessionId && getStateSessionOwner(current) === candidate.completedSessionId && Boolean(candidate.completionEvidencePath && (0,
|
|
28640
|
+
(candidate, current) => current.active === true && candidate.ownerSessionId === candidate.completedSessionId && getStateSessionOwner(current) === candidate.completedSessionId && Boolean(candidate.completionEvidencePath && (0, import_fs29.existsSync)(candidate.completionEvidencePath)),
|
|
28507
28641
|
(candidate) => emergencyRecoveryOptionsForProject(mode, candidate.path, root),
|
|
28508
28642
|
teamCleanup
|
|
28509
28643
|
);
|
|
@@ -28536,19 +28670,19 @@ ${checkedPaths.map((statePath) => ` - ${statePath}`).join("\n")}` : "";
|
|
|
28536
28670
|
return `No state found to clear for mode: ${mode}${scope}${checked}`;
|
|
28537
28671
|
}
|
|
28538
28672
|
function getModeRuntimeArtifactPaths(mode, root, sessionIds, includeLegacy = true) {
|
|
28539
|
-
const stateRoot = (0,
|
|
28673
|
+
const stateRoot = (0, import_path32.join)(getOmcRoot(root), "state");
|
|
28540
28674
|
const names = [`${mode}-stop-breaker.json`, `${mode}-last-steer-at`, `${mode}-continue-steer.lock`];
|
|
28541
28675
|
const dirs = /* @__PURE__ */ new Set([
|
|
28542
28676
|
...includeLegacy ? [stateRoot] : [],
|
|
28543
|
-
...[...sessionIds ?? listSessionIds(root)].map((sid) => (0,
|
|
28677
|
+
...[...sessionIds ?? listSessionIds(root)].map((sid) => (0, import_path32.join)(stateRoot, "sessions", sid))
|
|
28544
28678
|
]);
|
|
28545
|
-
return [...dirs].flatMap((dir) => names.map((name) => (0,
|
|
28679
|
+
return [...dirs].flatMap((dir) => names.map((name) => (0, import_path32.join)(dir, name)));
|
|
28546
28680
|
}
|
|
28547
28681
|
function captureTeamRuntimeArtifacts(root) {
|
|
28548
28682
|
const captured = /* @__PURE__ */ new Map();
|
|
28549
28683
|
for (const path14 of getModeRuntimeArtifactPaths("team", root)) try {
|
|
28550
|
-
const stat = (0,
|
|
28551
|
-
if (stat.isFile()) captured.set(path14, { bytes: (0,
|
|
28684
|
+
const stat = (0, import_fs29.lstatSync)(path14);
|
|
28685
|
+
if (stat.isFile()) captured.set(path14, { bytes: (0, import_fs29.readFileSync)(path14), identity: `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}` });
|
|
28552
28686
|
} catch {
|
|
28553
28687
|
}
|
|
28554
28688
|
return captured;
|
|
@@ -28557,17 +28691,17 @@ function clearRuntimeArtifactPaths(paths, captured) {
|
|
|
28557
28691
|
let cleared = 0, hadFailure = false;
|
|
28558
28692
|
for (const artifactPath of paths) {
|
|
28559
28693
|
const expected = captured?.get(artifactPath);
|
|
28560
|
-
if (!(0,
|
|
28694
|
+
if (!(0, import_fs29.existsSync)(artifactPath) || captured && !expected) continue;
|
|
28561
28695
|
if (expected) {
|
|
28562
28696
|
try {
|
|
28563
|
-
const stat = (0,
|
|
28564
|
-
if (!stat.isFile() || `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}` !== expected.identity || !(0,
|
|
28697
|
+
const stat = (0, import_fs29.lstatSync)(artifactPath);
|
|
28698
|
+
if (!stat.isFile() || `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}` !== expected.identity || !(0, import_fs29.readFileSync)(artifactPath).equals(expected.bytes)) continue;
|
|
28565
28699
|
} catch {
|
|
28566
28700
|
continue;
|
|
28567
28701
|
}
|
|
28568
28702
|
}
|
|
28569
28703
|
try {
|
|
28570
|
-
(0,
|
|
28704
|
+
(0, import_fs29.unlinkSync)(artifactPath);
|
|
28571
28705
|
cleared++;
|
|
28572
28706
|
} catch {
|
|
28573
28707
|
hadFailure = true;
|
|
@@ -28606,11 +28740,11 @@ function isSessionModeActive(mode, root, sessionId) {
|
|
|
28606
28740
|
return isModeActive(mode, root, sessionId);
|
|
28607
28741
|
}
|
|
28608
28742
|
const statePath = resolveSessionStatePath(mode, sessionId, root);
|
|
28609
|
-
if (!(0,
|
|
28743
|
+
if (!(0, import_fs29.existsSync)(statePath)) {
|
|
28610
28744
|
return false;
|
|
28611
28745
|
}
|
|
28612
28746
|
try {
|
|
28613
|
-
const state = JSON.parse((0,
|
|
28747
|
+
const state = JSON.parse((0, import_fs29.readFileSync)(statePath, "utf-8"));
|
|
28614
28748
|
return state.active === true;
|
|
28615
28749
|
} catch {
|
|
28616
28750
|
return false;
|
|
@@ -28695,11 +28829,11 @@ var stateReadTool = {
|
|
|
28695
28829
|
if (sessionId) {
|
|
28696
28830
|
validateSessionId(sessionId);
|
|
28697
28831
|
const statePath2 = getSessionStatePath(mode, root, sessionId);
|
|
28698
|
-
if (!(0,
|
|
28832
|
+
if (!(0, import_fs29.existsSync)(statePath2)) {
|
|
28699
28833
|
const completedSessionPaths = findCompletedSessionStateFiles(mode, root, sessionId);
|
|
28700
28834
|
if (completedSessionPaths.length > 0) {
|
|
28701
28835
|
const orphanList = completedSessionPaths.map((orphanPath) => {
|
|
28702
|
-
const sessionMarker = `${(0,
|
|
28836
|
+
const sessionMarker = `${(0, import_path32.join)("state", "sessions")}/`;
|
|
28703
28837
|
const markerIndex = orphanPath.indexOf(sessionMarker);
|
|
28704
28838
|
if (markerIndex === -1) return `- ${orphanPath}`;
|
|
28705
28839
|
const rest = orphanPath.slice(markerIndex + sessionMarker.length);
|
|
@@ -28728,7 +28862,7 @@ Expected path: ${statePath2}`
|
|
|
28728
28862
|
}]
|
|
28729
28863
|
};
|
|
28730
28864
|
}
|
|
28731
|
-
const content = (0,
|
|
28865
|
+
const content = (0, import_fs29.readFileSync)(statePath2, "utf-8");
|
|
28732
28866
|
let state;
|
|
28733
28867
|
try {
|
|
28734
28868
|
state = JSON.parse(content);
|
|
@@ -28763,12 +28897,12 @@ ${JSON.stringify(publicStateForMode(mode, state), null, 2)}
|
|
|
28763
28897
|
};
|
|
28764
28898
|
}
|
|
28765
28899
|
const statePath = getStatePath(mode, root);
|
|
28766
|
-
const legacyExists = (0,
|
|
28900
|
+
const legacyExists = (0, import_fs29.existsSync)(statePath);
|
|
28767
28901
|
const sessionIds = listSessionIds(root);
|
|
28768
28902
|
const activeSessions = [];
|
|
28769
28903
|
for (const sid of sessionIds) {
|
|
28770
28904
|
const sessionStatePath = getSessionStatePath(mode, root, sid);
|
|
28771
|
-
if ((0,
|
|
28905
|
+
if ((0, import_fs29.existsSync)(sessionStatePath)) {
|
|
28772
28906
|
activeSessions.push(sid);
|
|
28773
28907
|
}
|
|
28774
28908
|
}
|
|
@@ -28792,7 +28926,7 @@ Note: Reading from legacy/aggregate path (no session_id). This may include state
|
|
|
28792
28926
|
let teamReadError = false;
|
|
28793
28927
|
if (legacyExists) {
|
|
28794
28928
|
try {
|
|
28795
|
-
const content = (0,
|
|
28929
|
+
const content = (0, import_fs29.readFileSync)(statePath, "utf-8");
|
|
28796
28930
|
const state = JSON.parse(content);
|
|
28797
28931
|
if (mode === "team" && !isJsonRecord(state)) {
|
|
28798
28932
|
throw new Error("team state is corrupt; expected a JSON object");
|
|
@@ -28821,7 +28955,7 @@ Path: ${statePath}
|
|
|
28821
28955
|
for (const sid of activeSessions) {
|
|
28822
28956
|
const sessionStatePath = getSessionStatePath(mode, root, sid);
|
|
28823
28957
|
try {
|
|
28824
|
-
const content = (0,
|
|
28958
|
+
const content = (0, import_fs29.readFileSync)(sessionStatePath, "utf-8");
|
|
28825
28959
|
const state = JSON.parse(content);
|
|
28826
28960
|
if (mode === "team" && !isJsonRecord(state)) {
|
|
28827
28961
|
throw new Error("team state is corrupt; expected a JSON object");
|
|
@@ -28921,7 +29055,7 @@ var stateWriteTool = {
|
|
|
28921
29055
|
ensureOmcDir("state", root);
|
|
28922
29056
|
statePath = getStatePath(mode, root);
|
|
28923
29057
|
}
|
|
28924
|
-
if (mode !== "team" && sessionId && (0,
|
|
29058
|
+
if (mode !== "team" && sessionId && (0, import_fs29.existsSync)(statePath)) {
|
|
28925
29059
|
const existingState = readJsonRecord(statePath);
|
|
28926
29060
|
const ownerSessionId = existingState ? getStateSessionOwner(existingState) : void 0;
|
|
28927
29061
|
if (ownerSessionId && ownerSessionId !== sessionId) {
|
|
@@ -28975,7 +29109,7 @@ var stateWriteTool = {
|
|
|
28975
29109
|
} else if (mode === "autopilot" && builtState.active === false) {
|
|
28976
29110
|
let currentState = null;
|
|
28977
29111
|
try {
|
|
28978
|
-
currentState = JSON.parse((0,
|
|
29112
|
+
currentState = JSON.parse((0, import_fs29.readFileSync)(statePath, "utf8"));
|
|
28979
29113
|
} catch {
|
|
28980
29114
|
}
|
|
28981
29115
|
if (hasNamedWorkflowMarker(currentState ?? {})) {
|
|
@@ -29077,7 +29211,7 @@ function getAllRootSessionStatePaths(mode, root) {
|
|
|
29077
29211
|
roots.add(getOmcRoot(root));
|
|
29078
29212
|
for (const omcRoot of roots) {
|
|
29079
29213
|
for (const sid of listSessionIdsUnderOmcRoot(omcRoot)) {
|
|
29080
|
-
paths.add((0,
|
|
29214
|
+
paths.add((0, import_path32.join)(omcRoot, "state", "sessions", sid, getStateFileName(mode)));
|
|
29081
29215
|
}
|
|
29082
29216
|
}
|
|
29083
29217
|
return [...paths];
|
|
@@ -29087,9 +29221,9 @@ function discoverAllRootSessionStateCandidates(mode, root) {
|
|
|
29087
29221
|
}
|
|
29088
29222
|
function findUnresolvedTeamStatePaths(paths) {
|
|
29089
29223
|
return [...new Set(paths)].filter((path14) => {
|
|
29090
|
-
if (!(0,
|
|
29224
|
+
if (!(0, import_fs29.existsSync)(path14)) return false;
|
|
29091
29225
|
if (readJsonRecordStrict(path14) !== null) return false;
|
|
29092
|
-
return (0,
|
|
29226
|
+
return (0, import_fs29.existsSync)(path14);
|
|
29093
29227
|
});
|
|
29094
29228
|
}
|
|
29095
29229
|
function recoverAutopilotEmergencyTransactions(root, sessionId) {
|
|
@@ -29101,12 +29235,12 @@ function recoverAutopilotEmergencyTransactions(root, sessionId) {
|
|
|
29101
29235
|
if (shouldCheckWorkingDirectoryLocalState(root)) {
|
|
29102
29236
|
const localOmcRoot = getWorkingDirectoryLocalOmcRoot(root);
|
|
29103
29237
|
for (const sid of listSessionIdsUnderOmcRoot(localOmcRoot)) {
|
|
29104
|
-
broadPaths.add((0,
|
|
29238
|
+
broadPaths.add((0, import_path32.join)(localOmcRoot, "state", "sessions", sid, getStateFileName("autopilot")));
|
|
29105
29239
|
}
|
|
29106
29240
|
}
|
|
29107
29241
|
for (const omcRoot of getConvergedOmcRoots(root)) {
|
|
29108
29242
|
for (const sid of listSessionIdsUnderOmcRoot(omcRoot)) {
|
|
29109
|
-
broadPaths.add((0,
|
|
29243
|
+
broadPaths.add((0, import_path32.join)(omcRoot, "state", "sessions", sid, getStateFileName("autopilot")));
|
|
29110
29244
|
}
|
|
29111
29245
|
}
|
|
29112
29246
|
const directSessionPaths = /* @__PURE__ */ new Set();
|
|
@@ -29114,7 +29248,7 @@ function recoverAutopilotEmergencyTransactions(root, sessionId) {
|
|
|
29114
29248
|
directSessionPaths.add(resolveSessionStatePath("autopilot", sessionId, root));
|
|
29115
29249
|
if (shouldCheckWorkingDirectoryLocalState(root)) directSessionPaths.add(getWorkingDirectoryLocalSessionStatePath("autopilot", root, sessionId));
|
|
29116
29250
|
for (const omcRoot of getConvergedOmcRoots(root)) {
|
|
29117
|
-
directSessionPaths.add((0,
|
|
29251
|
+
directSessionPaths.add((0, import_path32.join)(omcRoot, "state", "sessions", sessionId, getStateFileName("autopilot")));
|
|
29118
29252
|
}
|
|
29119
29253
|
for (const path14 of directSessionPaths) broadPaths.add(path14);
|
|
29120
29254
|
}
|
|
@@ -29136,10 +29270,10 @@ function recoverAutopilotEmergencyTransactions(root, sessionId) {
|
|
|
29136
29270
|
}
|
|
29137
29271
|
if (!recoverEmergencyStateFile(path14, recoveryOptions)) throw new Error(`workflow_emergency_recovery_failed: ${path14}`);
|
|
29138
29272
|
if (recoveryOptions && !isAutopilotRecoveryCandidateForProject(path14, root)) continue;
|
|
29139
|
-
const artifactPrefix = `${(0,
|
|
29273
|
+
const artifactPrefix = `${(0, import_path32.basename)(path14)}.emergency-`;
|
|
29140
29274
|
let artifacts;
|
|
29141
29275
|
try {
|
|
29142
|
-
artifacts = (0,
|
|
29276
|
+
artifacts = (0, import_fs29.readdirSync)((0, import_path32.dirname)(path14)).filter((name) => name.startsWith(artifactPrefix) && !name.endsWith(".recovery.guard"));
|
|
29143
29277
|
} catch {
|
|
29144
29278
|
artifacts = [];
|
|
29145
29279
|
}
|
|
@@ -29162,7 +29296,7 @@ var stateClearTool = {
|
|
|
29162
29296
|
const sessionId = session_id;
|
|
29163
29297
|
if (mode === "ultrawork") {
|
|
29164
29298
|
try {
|
|
29165
|
-
if ((0,
|
|
29299
|
+
if ((0, import_fs29.lstatSync)((0, import_path32.join)((0, import_path32.resolve)(root), OmcPaths.ROOT)).isSymbolicLink()) {
|
|
29166
29300
|
return { content: [{ type: "text", text: `No state found to clear for mode: ${mode}` }] };
|
|
29167
29301
|
}
|
|
29168
29302
|
} catch {
|
|
@@ -29226,7 +29360,7 @@ var stateClearTool = {
|
|
|
29226
29360
|
let directCleared = 0;
|
|
29227
29361
|
for (const candidate of namedPrimaries) {
|
|
29228
29362
|
const success = clearAutopilotMarkerCandidate(candidate, root);
|
|
29229
|
-
if (!success || (0,
|
|
29363
|
+
if (!success || (0, import_fs29.existsSync)(candidate.path)) throw new Error(`primary state mutation failed; dependent state preserved: ${candidate.path}`);
|
|
29230
29364
|
directCleared += 1;
|
|
29231
29365
|
}
|
|
29232
29366
|
const completedSessionCleanup = clearCompletedSessionStateCandidates(
|
|
@@ -29240,11 +29374,11 @@ var stateClearTool = {
|
|
|
29240
29374
|
const sessionSignalCandidates = operationCandidates.filter((candidate) => !hasNamedWorkflowMarker(candidate.state));
|
|
29241
29375
|
const signaledCandidateDirs = /* @__PURE__ */ new Set();
|
|
29242
29376
|
for (const candidate of sessionSignalCandidates) {
|
|
29243
|
-
const signalDir = (0,
|
|
29377
|
+
const signalDir = (0, import_path32.dirname)(candidate.path);
|
|
29244
29378
|
if (signaledCandidateDirs.has(signalDir)) continue;
|
|
29245
29379
|
signaledCandidateDirs.add(signalDir);
|
|
29246
29380
|
const now = Date.now();
|
|
29247
|
-
const signalPath = (0,
|
|
29381
|
+
const signalPath = (0, import_path32.join)(signalDir, "cancel-signal-state.json");
|
|
29248
29382
|
const payload = {
|
|
29249
29383
|
active: true,
|
|
29250
29384
|
requested_at: new Date(now).toISOString(),
|
|
@@ -29286,7 +29420,7 @@ var stateClearTool = {
|
|
|
29286
29420
|
const clearPrimary = () => clearModeState(mode, root, sessionId, expectedDirectState);
|
|
29287
29421
|
const directCaptured = directCandidate?.path === directStatePath;
|
|
29288
29422
|
primarySuccess = clearModePrimaryWithTeamLock(mode, directStatePath, clearPrimary, directCaptured);
|
|
29289
|
-
if (directCaptured && primarySuccess && !(0,
|
|
29423
|
+
if (directCaptured && primarySuccess && !(0, import_fs29.existsSync)(directStatePath)) {
|
|
29290
29424
|
directCleared = 1;
|
|
29291
29425
|
if (mode === "team" && directCandidate) teamCleanup.clearedSessions.add(sessionId);
|
|
29292
29426
|
} else if (mode === "team" && directCaptured && directCandidate) {
|
|
@@ -29302,7 +29436,7 @@ var stateClearTool = {
|
|
|
29302
29436
|
const ownerNamedPrimary = mode === "autopilot" && ownerDirectCandidate && hasNamedWorkflowMarker(ownerDirectCandidate.state) ? ownerDirectCandidate : void 0;
|
|
29303
29437
|
if (ownerNamedPrimary) {
|
|
29304
29438
|
const success = clearAutopilotMarkerCandidate(ownerNamedPrimary, root);
|
|
29305
|
-
if (!success || (0,
|
|
29439
|
+
if (!success || (0, import_fs29.existsSync)(ownerNamedPrimary.path)) throw new Error("primary state mutation failed; dependent state preserved");
|
|
29306
29440
|
} else {
|
|
29307
29441
|
writeSessionCancelSignal(root, ownerSessionId, mode, ownerDirectCandidate);
|
|
29308
29442
|
clearModeState(mode, root, ownerSessionId, ownerDirectCandidate?.state);
|
|
@@ -29317,9 +29451,9 @@ var stateClearTool = {
|
|
|
29317
29451
|
}
|
|
29318
29452
|
if (mode === "team" && teamRuntimeSnapshots) {
|
|
29319
29453
|
const safeTeamSessions = new Set([...teamCleanup.clearedSessions].filter((sid) => !operationCandidates.some(
|
|
29320
|
-
(candidate) => teamSessionIdForCandidate(candidate, sessionId) === sid && (0,
|
|
29454
|
+
(candidate) => teamSessionIdForCandidate(candidate, sessionId) === sid && (0, import_fs29.existsSync)(candidate.path)
|
|
29321
29455
|
)));
|
|
29322
|
-
const eligibleTeamSessions = new Set([...safeTeamSessions].filter((sid) => !(0,
|
|
29456
|
+
const eligibleTeamSessions = new Set([...safeTeamSessions].filter((sid) => !(0, import_fs29.existsSync)(getSessionStatePath("team", root, sid))));
|
|
29323
29457
|
const teamRuntimeCleanup = clearTeamRuntimeArtifacts(root, eligibleTeamSessions, teamRuntimeSnapshots);
|
|
29324
29458
|
runtimeCleanup2.cleared += teamRuntimeCleanup.cleared;
|
|
29325
29459
|
runtimeCleanup2.hadFailure ||= teamRuntimeCleanup.hadFailure;
|
|
@@ -29336,7 +29470,7 @@ var stateClearTool = {
|
|
|
29336
29470
|
);
|
|
29337
29471
|
const clearedStateOrArtifacts = directCleared + completedSessionCleanup.cleared + sessionCleanup.cleared + legacyCleanup.cleared + convergedCleanup2.cleared + workingDirectoryLocalCleanup.cleared + ownerSessionCleanup.cleared + ownerLegacyCleanup.cleared + runtimeCleanup2.cleared;
|
|
29338
29472
|
const capturedCleanupIncomplete2 = operationCandidates.some((candidate) => {
|
|
29339
|
-
if (!(0,
|
|
29473
|
+
if (!(0, import_fs29.existsSync)(candidate.path)) return false;
|
|
29340
29474
|
if (mode === "team") return true;
|
|
29341
29475
|
const current = readJsonRecordStrict(candidate.path);
|
|
29342
29476
|
if (!current) return true;
|
|
@@ -29380,7 +29514,7 @@ var stateClearTool = {
|
|
|
29380
29514
|
const broadNamedPrimaries = mode === "autopilot" ? broadOperationCandidates.filter((candidate) => hasNamedWorkflowMarker(candidate.state)) : [];
|
|
29381
29515
|
for (const candidate of broadNamedPrimaries) {
|
|
29382
29516
|
const success = clearAutopilotMarkerCandidate(candidate, root);
|
|
29383
|
-
if (!success || (0,
|
|
29517
|
+
if (!success || (0, import_fs29.existsSync)(candidate.path)) throw new Error(`primary state mutation failed; dependent state preserved: ${candidate.path}`);
|
|
29384
29518
|
}
|
|
29385
29519
|
const broadLegacySignalCandidates = broadLegacyCandidates.filter((candidate) => !hasNamedWorkflowMarker(candidate.state));
|
|
29386
29520
|
const broadSessionSignalCandidates = broadSessionCandidates.filter((candidate) => !hasNamedWorkflowMarker(candidate.state));
|
|
@@ -29395,10 +29529,10 @@ var stateClearTool = {
|
|
|
29395
29529
|
};
|
|
29396
29530
|
const signaledLegacyDirs = /* @__PURE__ */ new Set();
|
|
29397
29531
|
for (const legacyCandidate of broadLegacySignalCandidates) {
|
|
29398
|
-
const signalDir = (0,
|
|
29532
|
+
const signalDir = (0, import_path32.dirname)(legacyCandidate.path);
|
|
29399
29533
|
if (signaledLegacyDirs.has(signalDir)) continue;
|
|
29400
29534
|
signaledLegacyDirs.add(signalDir);
|
|
29401
|
-
const legacySignalPath = (0,
|
|
29535
|
+
const legacySignalPath = (0, import_path32.join)(signalDir, "cancel-signal-state.json");
|
|
29402
29536
|
const legacyPayload = {
|
|
29403
29537
|
...cancelSignalPayload,
|
|
29404
29538
|
...legacyCandidate.workflowRunId ? { target_workflow_run_id: legacyCandidate.workflowRunId } : {},
|
|
@@ -29429,14 +29563,14 @@ var stateClearTool = {
|
|
|
29429
29563
|
if (primaryCandidate) {
|
|
29430
29564
|
const clearPrimary = () => clearModeState(mode, root, void 0, primaryCandidate.state);
|
|
29431
29565
|
const success = clearModePrimaryWithTeamLock(mode, primaryLegacyStatePath, clearPrimary);
|
|
29432
|
-
if (success && !(0,
|
|
29566
|
+
if (success && !(0, import_fs29.existsSync)(primaryCandidate.path)) {
|
|
29433
29567
|
clearedCount++;
|
|
29434
29568
|
if (mode === "team") {
|
|
29435
29569
|
teamLegacyCleared = true;
|
|
29436
29570
|
const ownerSessionId = teamSessionIdForCandidate(primaryCandidate);
|
|
29437
29571
|
if (ownerSessionId) teamCleanup.clearedSessions.add(ownerSessionId);
|
|
29438
29572
|
}
|
|
29439
|
-
} else if ((0,
|
|
29573
|
+
} else if ((0, import_fs29.existsSync)(primaryCandidate.path)) {
|
|
29440
29574
|
if (mode === "team") {
|
|
29441
29575
|
recordTeamClearFailure(mode, primaryCandidate, success ? "skipped" : "failed", teamCleanup);
|
|
29442
29576
|
}
|
|
@@ -29491,7 +29625,7 @@ var stateClearTool = {
|
|
|
29491
29625
|
const ownerSessionId = teamSessionIdForCandidate(candidate);
|
|
29492
29626
|
if (ownerSessionId) teamCleanup.clearedSessions.add(ownerSessionId);
|
|
29493
29627
|
}
|
|
29494
|
-
} else if (result === "failed" || (0,
|
|
29628
|
+
} else if (result === "failed" || (0, import_fs29.existsSync)(candidate.path)) {
|
|
29495
29629
|
recordTeamClearFailure(mode, candidate, result, teamCleanup);
|
|
29496
29630
|
errors.push(`session candidate: ${candidate.path}`);
|
|
29497
29631
|
}
|
|
@@ -29501,12 +29635,12 @@ var stateClearTool = {
|
|
|
29501
29635
|
...broadConvergedCandidates,
|
|
29502
29636
|
...broadSessionCandidates
|
|
29503
29637
|
].map((candidate) => [candidate.path, candidate])).values()];
|
|
29504
|
-
const capturedCleanupIncomplete = broadCapturedCandidates.some((candidate) => (0,
|
|
29638
|
+
const capturedCleanupIncomplete = broadCapturedCandidates.some((candidate) => (0, import_fs29.existsSync)(candidate.path));
|
|
29505
29639
|
if (mode === "team" && teamRuntimeSnapshots) {
|
|
29506
29640
|
const safeTeamSessions = new Set([...teamCleanup.clearedSessions].filter((sid) => !broadCapturedCandidates.some(
|
|
29507
|
-
(candidate) => teamSessionIdForCandidate(candidate) === sid && (0,
|
|
29641
|
+
(candidate) => teamSessionIdForCandidate(candidate) === sid && (0, import_fs29.existsSync)(candidate.path)
|
|
29508
29642
|
)));
|
|
29509
|
-
const eligibleTeamSessions = new Set([...safeTeamSessions].filter((sid) => !(0,
|
|
29643
|
+
const eligibleTeamSessions = new Set([...safeTeamSessions].filter((sid) => !(0, import_fs29.existsSync)(getSessionStatePath("team", root, sid))));
|
|
29510
29644
|
const teamRuntimeCleanup = clearTeamRuntimeArtifacts(root, eligibleTeamSessions, teamRuntimeSnapshots);
|
|
29511
29645
|
runtimeCleanup.cleared += teamRuntimeCleanup.cleared;
|
|
29512
29646
|
runtimeCleanup.hadFailure ||= teamRuntimeCleanup.hadFailure;
|
|
@@ -29520,11 +29654,11 @@ var stateClearTool = {
|
|
|
29520
29654
|
errors.push("runtime artifacts");
|
|
29521
29655
|
}
|
|
29522
29656
|
for (const candidate of broadCapturedCandidates) {
|
|
29523
|
-
if ((0,
|
|
29657
|
+
if ((0, import_fs29.existsSync)(candidate.path) && !errors.some((error2) => error2.includes(candidate.path))) {
|
|
29524
29658
|
errors.push(`captured candidate survived: ${candidate.path}`);
|
|
29525
29659
|
}
|
|
29526
29660
|
}
|
|
29527
|
-
clearedCount = broadCapturedCandidates.filter((candidate) => !(0,
|
|
29661
|
+
clearedCount = broadCapturedCandidates.filter((candidate) => !(0, import_fs29.existsSync)(candidate.path)).length + runtimeCleanup.cleared;
|
|
29528
29662
|
if (clearedCount === 0 && errors.length === 0) {
|
|
29529
29663
|
return {
|
|
29530
29664
|
content: [{
|
|
@@ -29584,8 +29718,8 @@ var stateListActiveTool = {
|
|
|
29584
29718
|
for (const mode of EXTRA_STATE_ONLY_MODES) {
|
|
29585
29719
|
try {
|
|
29586
29720
|
const statePath = resolveSessionStatePath(mode, sessionId, root);
|
|
29587
|
-
if ((0,
|
|
29588
|
-
const content = (0,
|
|
29721
|
+
if ((0, import_fs29.existsSync)(statePath)) {
|
|
29722
|
+
const content = (0, import_fs29.readFileSync)(statePath, "utf-8");
|
|
29589
29723
|
const state = JSON.parse(content);
|
|
29590
29724
|
if (state.active && canClearStateForSession(state, sessionId)) {
|
|
29591
29725
|
activeModes.push(mode);
|
|
@@ -29624,9 +29758,9 @@ ${modeList}`
|
|
|
29624
29758
|
const legacyActiveModes = [...getActiveModes(root)].filter((activeMode) => !isRetiredWorkflowMode(activeMode));
|
|
29625
29759
|
for (const mode of EXTRA_STATE_ONLY_MODES) {
|
|
29626
29760
|
const statePath = getStatePath(mode, root);
|
|
29627
|
-
if ((0,
|
|
29761
|
+
if ((0, import_fs29.existsSync)(statePath)) {
|
|
29628
29762
|
try {
|
|
29629
|
-
const content = (0,
|
|
29763
|
+
const content = (0, import_fs29.readFileSync)(statePath, "utf-8");
|
|
29630
29764
|
const state = JSON.parse(content);
|
|
29631
29765
|
if (state.active) {
|
|
29632
29766
|
legacyActiveModes.push(mode);
|
|
@@ -29653,8 +29787,8 @@ ${modeList}`
|
|
|
29653
29787
|
for (const mode of EXTRA_STATE_ONLY_MODES) {
|
|
29654
29788
|
try {
|
|
29655
29789
|
const statePath = resolveSessionStatePath(mode, sid, root);
|
|
29656
|
-
if ((0,
|
|
29657
|
-
const content = (0,
|
|
29790
|
+
if ((0, import_fs29.existsSync)(statePath)) {
|
|
29791
|
+
const content = (0, import_fs29.readFileSync)(statePath, "utf-8");
|
|
29658
29792
|
const state = JSON.parse(content);
|
|
29659
29793
|
if (state.active && canClearStateForSession(state, sid)) {
|
|
29660
29794
|
sessionActiveModes.push(mode);
|
|
@@ -29720,9 +29854,9 @@ var stateGetStatusTool = {
|
|
|
29720
29854
|
if (sessionId) {
|
|
29721
29855
|
validateSessionId(sessionId);
|
|
29722
29856
|
const statePath = getSessionStatePath(mode, root, sessionId);
|
|
29723
|
-
const active = !isRetiredWorkflowMode(mode) && (MODE_CONFIGS[mode] ? isModeActive(mode, root, sessionId) : (0,
|
|
29857
|
+
const active = !isRetiredWorkflowMode(mode) && (MODE_CONFIGS[mode] ? isModeActive(mode, root, sessionId) : (0, import_fs29.existsSync)(statePath) && (() => {
|
|
29724
29858
|
try {
|
|
29725
|
-
const content = (0,
|
|
29859
|
+
const content = (0, import_fs29.readFileSync)(statePath, "utf-8");
|
|
29726
29860
|
const state = JSON.parse(content);
|
|
29727
29861
|
return state.active === true && canClearStateForSession(state, sessionId);
|
|
29728
29862
|
} catch {
|
|
@@ -29730,9 +29864,9 @@ var stateGetStatusTool = {
|
|
|
29730
29864
|
}
|
|
29731
29865
|
})());
|
|
29732
29866
|
let statePreview = "No state file";
|
|
29733
|
-
if ((0,
|
|
29867
|
+
if ((0, import_fs29.existsSync)(statePath)) {
|
|
29734
29868
|
try {
|
|
29735
|
-
const content = (0,
|
|
29869
|
+
const content = (0, import_fs29.readFileSync)(statePath, "utf-8");
|
|
29736
29870
|
const state = JSON.parse(content);
|
|
29737
29871
|
const owner = getStateSessionOwner(state);
|
|
29738
29872
|
if (!owner || owner === sessionId) {
|
|
@@ -29744,10 +29878,10 @@ var stateGetStatusTool = {
|
|
|
29744
29878
|
}
|
|
29745
29879
|
}
|
|
29746
29880
|
lines2.push(`### Session: ${sessionId}`);
|
|
29747
|
-
const visible = !(0,
|
|
29881
|
+
const visible = !(0, import_fs29.existsSync)(statePath) || statePreview !== "No state file" && !statePreview.includes("Error reading state file");
|
|
29748
29882
|
lines2.push(`- **Active:** ${visible && active ? "Yes" : "No"}`);
|
|
29749
29883
|
lines2.push(`- **State Path:** ${statePath}`);
|
|
29750
|
-
lines2.push(`- **Exists:** ${visible && (0,
|
|
29884
|
+
lines2.push(`- **Exists:** ${visible && (0, import_fs29.existsSync)(statePath) ? "Yes" : "No"}`);
|
|
29751
29885
|
lines2.push(`
|
|
29752
29886
|
### State Preview
|
|
29753
29887
|
\`\`\`json
|
|
@@ -29761,9 +29895,9 @@ ${statePreview}
|
|
|
29761
29895
|
};
|
|
29762
29896
|
}
|
|
29763
29897
|
const legacyPath = getStatePath(mode, root);
|
|
29764
|
-
const legacyActive = !isRetiredWorkflowMode(mode) && (MODE_CONFIGS[mode] ? isModeActive(mode, root) : (0,
|
|
29898
|
+
const legacyActive = !isRetiredWorkflowMode(mode) && (MODE_CONFIGS[mode] ? isModeActive(mode, root) : (0, import_fs29.existsSync)(legacyPath) && (() => {
|
|
29765
29899
|
try {
|
|
29766
|
-
const content = (0,
|
|
29900
|
+
const content = (0, import_fs29.readFileSync)(legacyPath, "utf-8");
|
|
29767
29901
|
const state = JSON.parse(content);
|
|
29768
29902
|
return state.active === true;
|
|
29769
29903
|
} catch {
|
|
@@ -29773,13 +29907,13 @@ ${statePreview}
|
|
|
29773
29907
|
lines2.push(`### Legacy Path`);
|
|
29774
29908
|
lines2.push(`- **Active:** ${legacyActive ? "Yes" : "No"}`);
|
|
29775
29909
|
lines2.push(`- **State Path:** ${legacyPath}`);
|
|
29776
|
-
lines2.push(`- **Exists:** ${(0,
|
|
29910
|
+
lines2.push(`- **Exists:** ${(0, import_fs29.existsSync)(legacyPath) ? "Yes" : "No"}
|
|
29777
29911
|
`);
|
|
29778
29912
|
const activeSessions = isRetiredWorkflowMode(mode) ? [] : MODE_CONFIGS[mode] ? getActiveSessionsForMode(mode, root) : listSessionIds(root).filter((sid) => {
|
|
29779
29913
|
try {
|
|
29780
29914
|
const sessionPath = resolveSessionStatePath(mode, sid, root);
|
|
29781
|
-
if ((0,
|
|
29782
|
-
const content = (0,
|
|
29915
|
+
if ((0, import_fs29.existsSync)(sessionPath)) {
|
|
29916
|
+
const content = (0, import_fs29.readFileSync)(sessionPath, "utf-8");
|
|
29783
29917
|
const state = JSON.parse(content);
|
|
29784
29918
|
return state.active === true && canClearStateForSession(state, sid);
|
|
29785
29919
|
}
|
|
@@ -29823,9 +29957,9 @@ No active sessions for this mode.`);
|
|
|
29823
29957
|
for (const mode2 of EXTRA_STATE_ONLY_MODES) {
|
|
29824
29958
|
const statePath = sessionId ? resolveSessionStatePath(mode2, sessionId, root) : getStatePath(mode2, root);
|
|
29825
29959
|
let active = false;
|
|
29826
|
-
if ((0,
|
|
29960
|
+
if ((0, import_fs29.existsSync)(statePath)) {
|
|
29827
29961
|
try {
|
|
29828
|
-
const content = (0,
|
|
29962
|
+
const content = (0, import_fs29.readFileSync)(statePath, "utf-8");
|
|
29829
29963
|
const state = JSON.parse(content);
|
|
29830
29964
|
active = state.active === true && (!sessionId || canClearStateForSession(state, sessionId));
|
|
29831
29965
|
} catch {
|
|
@@ -29864,68 +29998,68 @@ var stateMigrateNonGitTool = {
|
|
|
29864
29998
|
try {
|
|
29865
29999
|
if (!args.session_id) throw new Error("session_id is required");
|
|
29866
30000
|
validateSessionId(args.session_id);
|
|
29867
|
-
const sourceRoot = (0,
|
|
29868
|
-
const trustedWorkingDirectory = (0,
|
|
29869
|
-
const sourceFromTrustedCwd = (0,
|
|
29870
|
-
if (sourceFromTrustedCwd === ".." || sourceFromTrustedCwd.startsWith(`..${
|
|
30001
|
+
const sourceRoot = (0, import_fs29.realpathSync)((0, import_path32.resolve)(args.workingDirectory || process.cwd()));
|
|
30002
|
+
const trustedWorkingDirectory = (0, import_fs29.realpathSync)((0, import_path32.resolve)(process.cwd()));
|
|
30003
|
+
const sourceFromTrustedCwd = (0, import_path32.relative)(trustedWorkingDirectory, sourceRoot);
|
|
30004
|
+
if (sourceFromTrustedCwd === ".." || sourceFromTrustedCwd.startsWith(`..${import_path32.sep}`) || (0, import_path32.isAbsolute)(sourceFromTrustedCwd)) {
|
|
29871
30005
|
throw new Error("state_migrate_non_git refuses a source outside the trusted session working directory");
|
|
29872
30006
|
}
|
|
29873
30007
|
const gitProbe = probeGitTopLevel(sourceRoot);
|
|
29874
30008
|
if (gitProbe.status === "ok") throw new Error("state_migrate_non_git only accepts a non-git source directory");
|
|
29875
30009
|
if (gitProbe.status !== "not_a_repository") throw new Error("state_migrate_non_git refused a failed Git probe");
|
|
29876
30010
|
if (findGitMetadataDir(sourceRoot)) throw new Error("state_migrate_non_git refuses a directory with Git metadata");
|
|
29877
|
-
const authorizedHome = (0,
|
|
29878
|
-
const sourceFromHome = (0,
|
|
29879
|
-
if (sourceFromHome === ".." || sourceFromHome.startsWith(`..${
|
|
30011
|
+
const authorizedHome = (0, import_fs29.realpathSync)((0, import_os4.homedir)());
|
|
30012
|
+
const sourceFromHome = (0, import_path32.relative)(authorizedHome, sourceRoot);
|
|
30013
|
+
if (sourceFromHome === ".." || sourceFromHome.startsWith(`..${import_path32.sep}`) || (0, import_path32.isAbsolute)(sourceFromHome)) {
|
|
29880
30014
|
throw new Error("state_migrate_non_git refuses a source outside the authorized home boundary");
|
|
29881
30015
|
}
|
|
29882
30016
|
if (isSensitiveStateLocation(sourceRoot)) throw new Error("state_migrate_non_git refuses sensitive source directories");
|
|
29883
30017
|
const canonicalOmc = getOmcRoot(sourceRoot);
|
|
29884
|
-
const sourceDir = (0,
|
|
29885
|
-
const destinationDir = (0,
|
|
30018
|
+
const sourceDir = (0, import_path32.join)(sourceRoot, OmcPaths.ROOT, "state", "sessions", args.session_id);
|
|
30019
|
+
const destinationDir = (0, import_path32.join)(canonicalOmc, "state", "sessions", args.session_id);
|
|
29886
30020
|
const report = { source: sourceDir, destination: destinationDir, copied: [], skipped: [], rejected: [] };
|
|
29887
|
-
const sourceOmc = (0,
|
|
29888
|
-
if (!(0,
|
|
30021
|
+
const sourceOmc = (0, import_path32.join)(sourceRoot, OmcPaths.ROOT);
|
|
30022
|
+
if (!(0, import_fs29.existsSync)(sourceOmc)) {
|
|
29889
30023
|
return { content: [{ type: "text", text: JSON.stringify(report, null, 2) }] };
|
|
29890
30024
|
}
|
|
29891
|
-
const sourceState = (0,
|
|
29892
|
-
const sourceSessions = (0,
|
|
30025
|
+
const sourceState = (0, import_path32.join)(sourceOmc, "state");
|
|
30026
|
+
const sourceSessions = (0, import_path32.join)(sourceState, "sessions");
|
|
29893
30027
|
for (const path14 of [sourceOmc, sourceState, sourceSessions]) {
|
|
29894
|
-
if (!(0,
|
|
30028
|
+
if (!(0, import_fs29.existsSync)(path14)) {
|
|
29895
30029
|
return { content: [{ type: "text", text: JSON.stringify(report, null, 2) }] };
|
|
29896
30030
|
}
|
|
29897
|
-
if ((0,
|
|
30031
|
+
if ((0, import_fs29.lstatSync)(path14).isSymbolicLink()) throw new Error("state_migrate_non_git refuses symlinked legacy state paths");
|
|
29898
30032
|
}
|
|
29899
|
-
if (!(0,
|
|
30033
|
+
if (!(0, import_fs29.existsSync)(sourceDir)) {
|
|
29900
30034
|
return { content: [{ type: "text", text: JSON.stringify(report, null, 2) }] };
|
|
29901
30035
|
}
|
|
29902
|
-
const destinationState = (0,
|
|
29903
|
-
const destinationSessions = (0,
|
|
30036
|
+
const destinationState = (0, import_path32.join)(canonicalOmc, "state");
|
|
30037
|
+
const destinationSessions = (0, import_path32.join)(destinationState, "sessions");
|
|
29904
30038
|
const migrationRoots = [canonicalOmc, destinationState, destinationSessions, destinationDir];
|
|
29905
|
-
if ((0,
|
|
30039
|
+
if ((0, import_fs29.lstatSync)(sourceDir).isSymbolicLink() || migrationRoots.some((path14) => (0, import_fs29.existsSync)(path14) && (0, import_fs29.lstatSync)(path14).isSymbolicLink())) {
|
|
29906
30040
|
throw new Error("state_migrate_non_git refuses symlinked migration roots");
|
|
29907
30041
|
}
|
|
29908
30042
|
ensureMigrationDirectoryTree(canonicalOmc, destinationDir);
|
|
29909
|
-
for (const entry of (0,
|
|
30043
|
+
for (const entry of (0, import_fs29.readdirSync)(sourceDir, { withFileTypes: true })) {
|
|
29910
30044
|
if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
|
|
29911
|
-
const sourcePath = (0,
|
|
29912
|
-
const sourceFd = (0,
|
|
30045
|
+
const sourcePath = (0, import_path32.join)(sourceDir, entry.name);
|
|
30046
|
+
const sourceFd = (0, import_fs29.openSync)(sourcePath, import_fs29.constants.O_RDONLY | (import_fs29.constants.O_NOFOLLOW ?? 0));
|
|
29913
30047
|
let sourceBytes;
|
|
29914
30048
|
try {
|
|
29915
|
-
const sourceStat = (0,
|
|
30049
|
+
const sourceStat = (0, import_fs29.fstatSync)(sourceFd);
|
|
29916
30050
|
if (!sourceStat.isFile()) throw new Error("state_migrate_non_git refuses a non-file source entry");
|
|
29917
30051
|
if (sourceStat.size > MAX_MIGRATION_FILE_BYTES) {
|
|
29918
30052
|
report.rejected.push(entry.name);
|
|
29919
30053
|
continue;
|
|
29920
30054
|
}
|
|
29921
30055
|
sourceBytes = Buffer.alloc(sourceStat.size);
|
|
29922
|
-
const bytesRead = sourceStat.size === 0 ? 0 : (0,
|
|
30056
|
+
const bytesRead = sourceStat.size === 0 ? 0 : (0, import_fs29.readSync)(sourceFd, sourceBytes, 0, sourceStat.size, 0);
|
|
29923
30057
|
if (bytesRead !== sourceStat.size) {
|
|
29924
30058
|
report.rejected.push(entry.name);
|
|
29925
30059
|
continue;
|
|
29926
30060
|
}
|
|
29927
30061
|
} finally {
|
|
29928
|
-
(0,
|
|
30062
|
+
(0, import_fs29.closeSync)(sourceFd);
|
|
29929
30063
|
}
|
|
29930
30064
|
let state = null;
|
|
29931
30065
|
try {
|
|
@@ -29936,14 +30070,14 @@ var stateMigrateNonGitTool = {
|
|
|
29936
30070
|
report.rejected.push(entry.name);
|
|
29937
30071
|
continue;
|
|
29938
30072
|
}
|
|
29939
|
-
const destinationPath = (0,
|
|
30073
|
+
const destinationPath = (0, import_path32.join)(destinationDir, entry.name);
|
|
29940
30074
|
ensureMigrationDirectoryTree(canonicalOmc, destinationDir);
|
|
29941
|
-
if ((0,
|
|
30075
|
+
if ((0, import_fs29.existsSync)(destinationPath)) {
|
|
29942
30076
|
report.skipped.push(entry.name);
|
|
29943
30077
|
continue;
|
|
29944
30078
|
}
|
|
29945
30079
|
try {
|
|
29946
|
-
(0,
|
|
30080
|
+
(0, import_fs29.writeFileSync)(destinationPath, sourceBytes, { flag: "wx", mode: 384 });
|
|
29947
30081
|
report.copied.push(entry.name);
|
|
29948
30082
|
} catch (error2) {
|
|
29949
30083
|
if (error2.code === "EEXIST") report.skipped.push(entry.name);
|
|
@@ -30087,21 +30221,21 @@ var stateTools = [
|
|
|
30087
30221
|
];
|
|
30088
30222
|
|
|
30089
30223
|
// src/hooks/notepad/index.ts
|
|
30090
|
-
var
|
|
30091
|
-
var
|
|
30224
|
+
var import_fs31 = require("fs");
|
|
30225
|
+
var import_path33 = require("path");
|
|
30092
30226
|
|
|
30093
30227
|
// src/lib/file-lock.ts
|
|
30094
|
-
var
|
|
30228
|
+
var import_fs30 = require("fs");
|
|
30095
30229
|
var path7 = __toESM(require("path"), 1);
|
|
30096
30230
|
var DEFAULT_STALE_LOCK_MS = 3e4;
|
|
30097
30231
|
var DEFAULT_RETRY_DELAY_MS = 50;
|
|
30098
30232
|
function isLockStale(lockPath, staleLockMs) {
|
|
30099
30233
|
try {
|
|
30100
|
-
const stat = (0,
|
|
30234
|
+
const stat = (0, import_fs30.statSync)(lockPath);
|
|
30101
30235
|
const ageMs = Date.now() - stat.mtimeMs;
|
|
30102
30236
|
if (ageMs < staleLockMs) return false;
|
|
30103
30237
|
try {
|
|
30104
|
-
const raw = (0,
|
|
30238
|
+
const raw = (0, import_fs30.readFileSync)(lockPath, "utf-8");
|
|
30105
30239
|
const payload = JSON.parse(raw);
|
|
30106
30240
|
if (payload.pid && isProcessAlive(payload.pid)) return false;
|
|
30107
30241
|
} catch {
|
|
@@ -30117,21 +30251,21 @@ function lockPathFor(filePath) {
|
|
|
30117
30251
|
function tryAcquireSync(lockPath, staleLockMs) {
|
|
30118
30252
|
ensureDirSync(path7.dirname(lockPath));
|
|
30119
30253
|
try {
|
|
30120
|
-
const fd = (0,
|
|
30254
|
+
const fd = (0, import_fs30.openSync)(
|
|
30121
30255
|
lockPath,
|
|
30122
|
-
|
|
30256
|
+
import_fs30.constants.O_CREAT | import_fs30.constants.O_EXCL | import_fs30.constants.O_WRONLY,
|
|
30123
30257
|
384
|
|
30124
30258
|
);
|
|
30125
30259
|
try {
|
|
30126
30260
|
const payload = JSON.stringify({ pid: process.pid, timestamp: Date.now() });
|
|
30127
|
-
(0,
|
|
30261
|
+
(0, import_fs30.writeSync)(fd, payload, null, "utf-8");
|
|
30128
30262
|
} catch (writeErr) {
|
|
30129
30263
|
try {
|
|
30130
|
-
(0,
|
|
30264
|
+
(0, import_fs30.closeSync)(fd);
|
|
30131
30265
|
} catch {
|
|
30132
30266
|
}
|
|
30133
30267
|
try {
|
|
30134
|
-
(0,
|
|
30268
|
+
(0, import_fs30.unlinkSync)(lockPath);
|
|
30135
30269
|
} catch {
|
|
30136
30270
|
}
|
|
30137
30271
|
throw writeErr;
|
|
@@ -30141,25 +30275,25 @@ function tryAcquireSync(lockPath, staleLockMs) {
|
|
|
30141
30275
|
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
30142
30276
|
if (isLockStale(lockPath, staleLockMs)) {
|
|
30143
30277
|
try {
|
|
30144
|
-
(0,
|
|
30278
|
+
(0, import_fs30.unlinkSync)(lockPath);
|
|
30145
30279
|
} catch {
|
|
30146
30280
|
}
|
|
30147
30281
|
try {
|
|
30148
|
-
const fd = (0,
|
|
30282
|
+
const fd = (0, import_fs30.openSync)(
|
|
30149
30283
|
lockPath,
|
|
30150
|
-
|
|
30284
|
+
import_fs30.constants.O_CREAT | import_fs30.constants.O_EXCL | import_fs30.constants.O_WRONLY,
|
|
30151
30285
|
384
|
|
30152
30286
|
);
|
|
30153
30287
|
try {
|
|
30154
30288
|
const payload = JSON.stringify({ pid: process.pid, timestamp: Date.now() });
|
|
30155
|
-
(0,
|
|
30289
|
+
(0, import_fs30.writeSync)(fd, payload, null, "utf-8");
|
|
30156
30290
|
} catch (writeErr) {
|
|
30157
30291
|
try {
|
|
30158
|
-
(0,
|
|
30292
|
+
(0, import_fs30.closeSync)(fd);
|
|
30159
30293
|
} catch {
|
|
30160
30294
|
}
|
|
30161
30295
|
try {
|
|
30162
|
-
(0,
|
|
30296
|
+
(0, import_fs30.unlinkSync)(lockPath);
|
|
30163
30297
|
} catch {
|
|
30164
30298
|
}
|
|
30165
30299
|
throw writeErr;
|
|
@@ -30199,11 +30333,11 @@ function acquireFileLockSync(lockPath, opts) {
|
|
|
30199
30333
|
}
|
|
30200
30334
|
function releaseFileLockSync(handle) {
|
|
30201
30335
|
try {
|
|
30202
|
-
(0,
|
|
30336
|
+
(0, import_fs30.closeSync)(handle.fd);
|
|
30203
30337
|
} catch {
|
|
30204
30338
|
}
|
|
30205
30339
|
try {
|
|
30206
|
-
(0,
|
|
30340
|
+
(0, import_fs30.unlinkSync)(handle.path);
|
|
30207
30341
|
} catch {
|
|
30208
30342
|
}
|
|
30209
30343
|
}
|
|
@@ -30281,19 +30415,19 @@ function getSectionRegexSet(header) {
|
|
|
30281
30415
|
return SECTION_REGEXES[header] ?? createSectionRegexSet(header);
|
|
30282
30416
|
}
|
|
30283
30417
|
function getNotepadPath(directory) {
|
|
30284
|
-
return (0,
|
|
30418
|
+
return (0, import_path33.join)(getOmcRoot(directory), NOTEPAD_FILENAME);
|
|
30285
30419
|
}
|
|
30286
30420
|
function initNotepad(directory) {
|
|
30287
30421
|
const omcDir = getOmcRoot(directory);
|
|
30288
|
-
if (!(0,
|
|
30422
|
+
if (!(0, import_fs31.existsSync)(omcDir)) {
|
|
30289
30423
|
try {
|
|
30290
|
-
(0,
|
|
30424
|
+
(0, import_fs31.mkdirSync)(omcDir, { recursive: true });
|
|
30291
30425
|
} catch {
|
|
30292
30426
|
return false;
|
|
30293
30427
|
}
|
|
30294
30428
|
}
|
|
30295
30429
|
const notepadPath = getNotepadPath(directory);
|
|
30296
|
-
if ((0,
|
|
30430
|
+
if ((0, import_fs31.existsSync)(notepadPath)) {
|
|
30297
30431
|
return true;
|
|
30298
30432
|
}
|
|
30299
30433
|
const content = `# Notepad
|
|
@@ -30318,11 +30452,11 @@ ${MANUAL_HEADER}
|
|
|
30318
30452
|
}
|
|
30319
30453
|
function readNotepad(directory) {
|
|
30320
30454
|
const notepadPath = getNotepadPath(directory);
|
|
30321
|
-
if (!(0,
|
|
30455
|
+
if (!(0, import_fs31.existsSync)(notepadPath)) {
|
|
30322
30456
|
return null;
|
|
30323
30457
|
}
|
|
30324
30458
|
try {
|
|
30325
|
-
return (0,
|
|
30459
|
+
return (0, import_fs31.readFileSync)(notepadPath, "utf-8");
|
|
30326
30460
|
} catch {
|
|
30327
30461
|
return null;
|
|
30328
30462
|
}
|
|
@@ -30368,7 +30502,7 @@ function getManualSection(directory) {
|
|
|
30368
30502
|
return extractSection(content, MANUAL_HEADER);
|
|
30369
30503
|
}
|
|
30370
30504
|
function setPriorityContext(directory, content, config2 = DEFAULT_CONFIG3) {
|
|
30371
|
-
if (!(0,
|
|
30505
|
+
if (!(0, import_fs31.existsSync)(getNotepadPath(directory))) {
|
|
30372
30506
|
if (!initNotepad(directory)) {
|
|
30373
30507
|
return { success: false };
|
|
30374
30508
|
}
|
|
@@ -30376,7 +30510,7 @@ function setPriorityContext(directory, content, config2 = DEFAULT_CONFIG3) {
|
|
|
30376
30510
|
const notepadPath = getNotepadPath(directory);
|
|
30377
30511
|
try {
|
|
30378
30512
|
return withFileLockSync(lockPathFor(notepadPath), () => {
|
|
30379
|
-
let notepadContent = (0,
|
|
30513
|
+
let notepadContent = (0, import_fs31.readFileSync)(notepadPath, "utf-8");
|
|
30380
30514
|
const warning = content.length > config2.priorityMaxChars ? `Priority Context exceeds ${config2.priorityMaxChars} chars (${content.length} chars). Consider condensing.` : void 0;
|
|
30381
30515
|
notepadContent = replaceSection(notepadContent, PRIORITY_HEADER, content);
|
|
30382
30516
|
atomicWriteFileSync(notepadPath, notepadContent);
|
|
@@ -30387,7 +30521,7 @@ function setPriorityContext(directory, content, config2 = DEFAULT_CONFIG3) {
|
|
|
30387
30521
|
}
|
|
30388
30522
|
}
|
|
30389
30523
|
function addWorkingMemoryEntry(directory, content) {
|
|
30390
|
-
if (!(0,
|
|
30524
|
+
if (!(0, import_fs31.existsSync)(getNotepadPath(directory))) {
|
|
30391
30525
|
if (!initNotepad(directory)) {
|
|
30392
30526
|
return false;
|
|
30393
30527
|
}
|
|
@@ -30395,7 +30529,7 @@ function addWorkingMemoryEntry(directory, content) {
|
|
|
30395
30529
|
const notepadPath = getNotepadPath(directory);
|
|
30396
30530
|
try {
|
|
30397
30531
|
return withFileLockSync(lockPathFor(notepadPath), () => {
|
|
30398
|
-
let notepadContent = (0,
|
|
30532
|
+
let notepadContent = (0, import_fs31.readFileSync)(notepadPath, "utf-8");
|
|
30399
30533
|
const currentMemory = extractSection(notepadContent, WORKING_MEMORY_HEADER) || "";
|
|
30400
30534
|
const now = /* @__PURE__ */ new Date();
|
|
30401
30535
|
const timestamp2 = now.toISOString().slice(0, 16).replace("T", " ");
|
|
@@ -30416,7 +30550,7 @@ ${content}
|
|
|
30416
30550
|
}
|
|
30417
30551
|
}
|
|
30418
30552
|
function addManualEntry(directory, content) {
|
|
30419
|
-
if (!(0,
|
|
30553
|
+
if (!(0, import_fs31.existsSync)(getNotepadPath(directory))) {
|
|
30420
30554
|
if (!initNotepad(directory)) {
|
|
30421
30555
|
return false;
|
|
30422
30556
|
}
|
|
@@ -30424,7 +30558,7 @@ function addManualEntry(directory, content) {
|
|
|
30424
30558
|
const notepadPath = getNotepadPath(directory);
|
|
30425
30559
|
try {
|
|
30426
30560
|
return withFileLockSync(lockPathFor(notepadPath), () => {
|
|
30427
|
-
let notepadContent = (0,
|
|
30561
|
+
let notepadContent = (0, import_fs31.readFileSync)(notepadPath, "utf-8");
|
|
30428
30562
|
const currentManual = extractSection(notepadContent, MANUAL_HEADER) || "";
|
|
30429
30563
|
const now = /* @__PURE__ */ new Date();
|
|
30430
30564
|
const timestamp2 = now.toISOString().slice(0, 16).replace("T", " ");
|
|
@@ -30442,12 +30576,12 @@ ${content}
|
|
|
30442
30576
|
}
|
|
30443
30577
|
function pruneOldEntries(directory, daysOld = DEFAULT_CONFIG3.workingMemoryDays) {
|
|
30444
30578
|
const notepadPath = getNotepadPath(directory);
|
|
30445
|
-
if (!(0,
|
|
30579
|
+
if (!(0, import_fs31.existsSync)(notepadPath)) {
|
|
30446
30580
|
return { pruned: 0, remaining: 0 };
|
|
30447
30581
|
}
|
|
30448
30582
|
try {
|
|
30449
30583
|
return withFileLockSync(lockPathFor(notepadPath), () => {
|
|
30450
|
-
let notepadContent = (0,
|
|
30584
|
+
let notepadContent = (0, import_fs31.readFileSync)(notepadPath, "utf-8");
|
|
30451
30585
|
const workingMemory = extractSection(notepadContent, WORKING_MEMORY_HEADER);
|
|
30452
30586
|
if (!workingMemory) {
|
|
30453
30587
|
return { pruned: 0, remaining: 0 };
|
|
@@ -30485,7 +30619,7 @@ ${entry.content}`).join("\n\n");
|
|
|
30485
30619
|
}
|
|
30486
30620
|
function getNotepadStats(directory) {
|
|
30487
30621
|
const notepadPath = getNotepadPath(directory);
|
|
30488
|
-
if (!(0,
|
|
30622
|
+
if (!(0, import_fs31.existsSync)(notepadPath)) {
|
|
30489
30623
|
return {
|
|
30490
30624
|
exists: false,
|
|
30491
30625
|
totalSize: 0,
|
|
@@ -30494,7 +30628,7 @@ function getNotepadStats(directory) {
|
|
|
30494
30628
|
oldestEntry: null
|
|
30495
30629
|
};
|
|
30496
30630
|
}
|
|
30497
|
-
const content = (0,
|
|
30631
|
+
const content = (0, import_fs31.readFileSync)(notepadPath, "utf-8");
|
|
30498
30632
|
const priorityContext = extractSection(content, PRIORITY_HEADER) || "";
|
|
30499
30633
|
const workingMemory = extractSection(content, WORKING_MEMORY_HEADER) || "";
|
|
30500
30634
|
const wmMatches = workingMemory.match(
|
|
@@ -30807,7 +30941,7 @@ var notepadTools = [
|
|
|
30807
30941
|
];
|
|
30808
30942
|
|
|
30809
30943
|
// src/hooks/project-memory/index.ts
|
|
30810
|
-
var
|
|
30944
|
+
var import_path41 = __toESM(require("path"), 1);
|
|
30811
30945
|
|
|
30812
30946
|
// src/features/context-injector/collector.ts
|
|
30813
30947
|
var PRIORITY_ORDER = {
|
|
@@ -30917,18 +31051,18 @@ var ContextCollector = class {
|
|
|
30917
31051
|
var contextCollector = new ContextCollector();
|
|
30918
31052
|
|
|
30919
31053
|
// src/hooks/rules-injector/finder.ts
|
|
30920
|
-
var
|
|
30921
|
-
var
|
|
31054
|
+
var import_fs32 = require("fs");
|
|
31055
|
+
var import_path35 = require("path");
|
|
30922
31056
|
|
|
30923
31057
|
// src/hooks/rules-injector/constants.ts
|
|
30924
|
-
var
|
|
31058
|
+
var import_path34 = require("path");
|
|
30925
31059
|
var import_os5 = require("os");
|
|
30926
|
-
var OMC_STORAGE_DIR = (0,
|
|
30927
|
-
var RULES_INJECTOR_STORAGE = (0,
|
|
31060
|
+
var OMC_STORAGE_DIR = (0, import_path34.join)((0, import_os5.homedir)(), ".omg");
|
|
31061
|
+
var RULES_INJECTOR_STORAGE = (0, import_path34.join)(OMC_STORAGE_DIR, "rules-injector");
|
|
30928
31062
|
|
|
30929
31063
|
// src/hooks/project-memory/storage.ts
|
|
30930
31064
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
30931
|
-
var
|
|
31065
|
+
var import_path36 = __toESM(require("path"), 1);
|
|
30932
31066
|
|
|
30933
31067
|
// src/hooks/project-memory/constants.ts
|
|
30934
31068
|
var CACHE_EXPIRY_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -30960,7 +31094,7 @@ async function loadProjectMemory(projectRoot) {
|
|
|
30960
31094
|
}
|
|
30961
31095
|
async function saveProjectMemory(projectRoot, memory) {
|
|
30962
31096
|
const memoryPath = getMemoryPath(projectRoot);
|
|
30963
|
-
const omcDir =
|
|
31097
|
+
const omcDir = import_path36.default.dirname(memoryPath);
|
|
30964
31098
|
try {
|
|
30965
31099
|
await import_promises2.default.mkdir(omcDir, { recursive: true });
|
|
30966
31100
|
await atomicWriteJson(memoryPath, memory);
|
|
@@ -30976,17 +31110,17 @@ async function withProjectMemoryLock(projectRoot, fn) {
|
|
|
30976
31110
|
|
|
30977
31111
|
// src/hooks/project-memory/detector.ts
|
|
30978
31112
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
30979
|
-
var
|
|
31113
|
+
var import_path38 = __toESM(require("path"), 1);
|
|
30980
31114
|
|
|
30981
31115
|
// src/hooks/project-memory/directory-mapper.ts
|
|
30982
31116
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
30983
|
-
var
|
|
31117
|
+
var import_path37 = __toESM(require("path"), 1);
|
|
30984
31118
|
|
|
30985
31119
|
// src/hooks/project-memory/formatter.ts
|
|
30986
|
-
var
|
|
31120
|
+
var import_path40 = __toESM(require("path"), 1);
|
|
30987
31121
|
|
|
30988
31122
|
// src/hooks/project-memory/hot-path-tracker.ts
|
|
30989
|
-
var
|
|
31123
|
+
var import_path39 = __toESM(require("path"), 1);
|
|
30990
31124
|
|
|
30991
31125
|
// src/hooks/project-memory/directive-detector.ts
|
|
30992
31126
|
function addDirective(directives, newDirective) {
|
|
@@ -31369,27 +31503,27 @@ var memoryTools = [
|
|
|
31369
31503
|
];
|
|
31370
31504
|
|
|
31371
31505
|
// src/tools/trace-tools.ts
|
|
31372
|
-
var
|
|
31373
|
-
var
|
|
31506
|
+
var import_fs35 = require("fs");
|
|
31507
|
+
var import_path44 = require("path");
|
|
31374
31508
|
|
|
31375
31509
|
// src/hooks/subagent-tracker/session-replay.ts
|
|
31376
|
-
var
|
|
31377
|
-
var
|
|
31510
|
+
var import_fs33 = require("fs");
|
|
31511
|
+
var import_path42 = require("path");
|
|
31378
31512
|
var REPLAY_PREFIX = "agent-replay-";
|
|
31379
31513
|
var MAX_REPLAY_SIZE_BYTES = 5 * 1024 * 1024;
|
|
31380
31514
|
function getReplayFilePath(directory, sessionId) {
|
|
31381
|
-
const stateDir = (0,
|
|
31382
|
-
if (!(0,
|
|
31383
|
-
(0,
|
|
31515
|
+
const stateDir = (0, import_path42.join)(getOmcRoot(directory), "state");
|
|
31516
|
+
if (!(0, import_fs33.existsSync)(stateDir)) {
|
|
31517
|
+
(0, import_fs33.mkdirSync)(stateDir, { recursive: true });
|
|
31384
31518
|
}
|
|
31385
31519
|
const safeId = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
31386
|
-
return (0,
|
|
31520
|
+
return (0, import_path42.join)(stateDir, `${REPLAY_PREFIX}${safeId}.jsonl`);
|
|
31387
31521
|
}
|
|
31388
31522
|
function readReplayEvents(directory, sessionId) {
|
|
31389
31523
|
const filePath = getReplayFilePath(directory, sessionId);
|
|
31390
|
-
if (!(0,
|
|
31524
|
+
if (!(0, import_fs33.existsSync)(filePath)) return [];
|
|
31391
31525
|
try {
|
|
31392
|
-
const content = (0,
|
|
31526
|
+
const content = (0, import_fs33.readFileSync)(filePath, "utf-8");
|
|
31393
31527
|
return content.split("\n").filter((line) => line.trim()).map((line) => {
|
|
31394
31528
|
try {
|
|
31395
31529
|
return JSON.parse(line);
|
|
@@ -31568,8 +31702,8 @@ function getReplaySummary(directory, sessionId) {
|
|
|
31568
31702
|
|
|
31569
31703
|
// src/features/session-history-search/index.ts
|
|
31570
31704
|
var import_child_process14 = require("child_process");
|
|
31571
|
-
var
|
|
31572
|
-
var
|
|
31705
|
+
var import_fs34 = require("fs");
|
|
31706
|
+
var import_path43 = require("path");
|
|
31573
31707
|
var import_readline = require("readline");
|
|
31574
31708
|
var DEFAULT_LIMIT = 10;
|
|
31575
31709
|
var DEFAULT_CONTEXT_CHARS = 120;
|
|
@@ -31608,22 +31742,22 @@ function getMainRepoRoot(projectRoot) {
|
|
|
31608
31742
|
stdio: ["pipe", "pipe", "pipe"],
|
|
31609
31743
|
windowsHide: true
|
|
31610
31744
|
}).trim();
|
|
31611
|
-
const absoluteCommonDir = (0,
|
|
31612
|
-
const mainRepoRoot = (0,
|
|
31745
|
+
const absoluteCommonDir = (0, import_path43.resolve)(projectRoot, gitCommonDir);
|
|
31746
|
+
const mainRepoRoot = (0, import_path43.dirname)(absoluteCommonDir);
|
|
31613
31747
|
return mainRepoRoot === projectRoot ? null : mainRepoRoot;
|
|
31614
31748
|
} catch {
|
|
31615
31749
|
return null;
|
|
31616
31750
|
}
|
|
31617
31751
|
}
|
|
31618
31752
|
function getClaudeWorktreeParent(projectRoot) {
|
|
31619
|
-
const marker = `${(0,
|
|
31620
|
-
const normalizedRoot = (0,
|
|
31753
|
+
const marker = `${(0, import_path43.normalize)("/.copilot/worktrees/")}`;
|
|
31754
|
+
const normalizedRoot = (0, import_path43.normalize)(projectRoot);
|
|
31621
31755
|
const idx = normalizedRoot.indexOf(marker);
|
|
31622
31756
|
if (idx === -1) return null;
|
|
31623
31757
|
return normalizedRoot.slice(0, idx) || null;
|
|
31624
31758
|
}
|
|
31625
31759
|
function listJsonlFiles(rootDir) {
|
|
31626
|
-
if (!(0,
|
|
31760
|
+
if (!(0, import_fs34.existsSync)(rootDir)) {
|
|
31627
31761
|
return [];
|
|
31628
31762
|
}
|
|
31629
31763
|
const files = [];
|
|
@@ -31632,12 +31766,12 @@ function listJsonlFiles(rootDir) {
|
|
|
31632
31766
|
const current = stack.pop();
|
|
31633
31767
|
let entries;
|
|
31634
31768
|
try {
|
|
31635
|
-
entries = (0,
|
|
31769
|
+
entries = (0, import_fs34.readdirSync)(current, { withFileTypes: true });
|
|
31636
31770
|
} catch {
|
|
31637
31771
|
continue;
|
|
31638
31772
|
}
|
|
31639
31773
|
for (const entry of entries) {
|
|
31640
|
-
const fullPath = (0,
|
|
31774
|
+
const fullPath = (0, import_path43.join)(current, entry.name);
|
|
31641
31775
|
if (entry.isDirectory()) {
|
|
31642
31776
|
stack.push(fullPath);
|
|
31643
31777
|
continue;
|
|
@@ -31657,8 +31791,8 @@ function uniqueSortedTargets(targets) {
|
|
|
31657
31791
|
seen.add(key);
|
|
31658
31792
|
return true;
|
|
31659
31793
|
}).sort((a, b) => {
|
|
31660
|
-
const aTime = (0,
|
|
31661
|
-
const bTime = (0,
|
|
31794
|
+
const aTime = (0, import_fs34.existsSync)(a.filePath) ? (0, import_fs34.statSync)(a.filePath).mtimeMs : 0;
|
|
31795
|
+
const bTime = (0, import_fs34.existsSync)(b.filePath) ? (0, import_fs34.statSync)(b.filePath).mtimeMs : 0;
|
|
31662
31796
|
return bTime - aTime;
|
|
31663
31797
|
});
|
|
31664
31798
|
}
|
|
@@ -31673,22 +31807,22 @@ function buildCurrentProjectTargets(projectRoot, transcriptProjectRoots = [proje
|
|
|
31673
31807
|
}
|
|
31674
31808
|
const targets = [];
|
|
31675
31809
|
for (const root of projectRoots) {
|
|
31676
|
-
const encodedDir = (0,
|
|
31810
|
+
const encodedDir = (0, import_path43.join)(claudeDir, "projects", encodeProjectPath(root));
|
|
31677
31811
|
for (const filePath of listJsonlFiles(encodedDir)) {
|
|
31678
31812
|
targets.push({ filePath, sourceType: "project-transcript" });
|
|
31679
31813
|
}
|
|
31680
31814
|
}
|
|
31681
|
-
const legacyTranscriptsDir = (0,
|
|
31815
|
+
const legacyTranscriptsDir = (0, import_path43.join)(claudeDir, "transcripts");
|
|
31682
31816
|
for (const filePath of listJsonlFiles(legacyTranscriptsDir)) {
|
|
31683
31817
|
targets.push({ filePath, sourceType: "legacy-transcript" });
|
|
31684
31818
|
}
|
|
31685
31819
|
const omcRoot = getOmcRoot(projectRoot);
|
|
31686
|
-
const sessionSummariesDir = (0,
|
|
31820
|
+
const sessionSummariesDir = (0, import_path43.join)(omcRoot, "sessions");
|
|
31687
31821
|
for (const filePath of listJsonlFiles(sessionSummariesDir)) {
|
|
31688
31822
|
targets.push({ filePath, sourceType: "omc-session-summary" });
|
|
31689
31823
|
}
|
|
31690
|
-
const replayDir = (0,
|
|
31691
|
-
if ((0,
|
|
31824
|
+
const replayDir = (0, import_path43.join)(omcRoot, "state");
|
|
31825
|
+
if ((0, import_fs34.existsSync)(replayDir)) {
|
|
31692
31826
|
for (const filePath of listJsonlFiles(replayDir)) {
|
|
31693
31827
|
if (filePath.includes("agent-replay-") && filePath.endsWith(".jsonl")) {
|
|
31694
31828
|
targets.push({ filePath, sourceType: "omc-session-replay" });
|
|
@@ -31700,10 +31834,10 @@ function buildCurrentProjectTargets(projectRoot, transcriptProjectRoots = [proje
|
|
|
31700
31834
|
function buildAllProjectTargets() {
|
|
31701
31835
|
const claudeDir = getCopilotConfigDir();
|
|
31702
31836
|
const targets = [];
|
|
31703
|
-
for (const filePath of listJsonlFiles((0,
|
|
31837
|
+
for (const filePath of listJsonlFiles((0, import_path43.join)(claudeDir, "projects"))) {
|
|
31704
31838
|
targets.push({ filePath, sourceType: "project-transcript" });
|
|
31705
31839
|
}
|
|
31706
|
-
for (const filePath of listJsonlFiles((0,
|
|
31840
|
+
for (const filePath of listJsonlFiles((0, import_path43.join)(claudeDir, "transcripts"))) {
|
|
31707
31841
|
targets.push({ filePath, sourceType: "legacy-transcript" });
|
|
31708
31842
|
}
|
|
31709
31843
|
return uniqueSortedTargets(targets);
|
|
@@ -31712,9 +31846,9 @@ function isWithinProject(projectPath, projectRoots) {
|
|
|
31712
31846
|
if (!projectPath) {
|
|
31713
31847
|
return false;
|
|
31714
31848
|
}
|
|
31715
|
-
const normalizedProjectPath = (0,
|
|
31849
|
+
const normalizedProjectPath = (0, import_path43.normalize)((0, import_path43.resolve)(projectPath)).replace(/\\/g, "/");
|
|
31716
31850
|
return projectRoots.some((root) => {
|
|
31717
|
-
const normalizedRoot = (0,
|
|
31851
|
+
const normalizedRoot = (0, import_path43.normalize)((0, import_path43.resolve)(root)).replace(/\\/g, "/");
|
|
31718
31852
|
return normalizedProjectPath === normalizedRoot || normalizedProjectPath.startsWith(`${normalizedRoot}/`);
|
|
31719
31853
|
});
|
|
31720
31854
|
}
|
|
@@ -31918,7 +32052,7 @@ function createMatchRetainer(limit) {
|
|
|
31918
32052
|
};
|
|
31919
32053
|
}
|
|
31920
32054
|
async function collectMatchesFromFile(target, options) {
|
|
31921
|
-
const fileMtime = (0,
|
|
32055
|
+
const fileMtime = (0, import_fs34.existsSync)(target.filePath) ? (0, import_fs34.statSync)(target.filePath).mtimeMs : 0;
|
|
31922
32056
|
if (target.sourceType === "omc-session-summary" && target.filePath.endsWith(".json")) {
|
|
31923
32057
|
try {
|
|
31924
32058
|
const payload = JSON.parse(await import("fs/promises").then((fs8) => fs8.readFile(target.filePath, "utf-8")));
|
|
@@ -31950,7 +32084,7 @@ async function collectMatchesFromFile(target, options) {
|
|
|
31950
32084
|
}
|
|
31951
32085
|
return;
|
|
31952
32086
|
}
|
|
31953
|
-
const stream = (0,
|
|
32087
|
+
const stream = (0, import_fs34.createReadStream)(target.filePath, { encoding: "utf-8" });
|
|
31954
32088
|
const reader = (0, import_readline.createInterface)({ input: stream, crlfDelay: Infinity });
|
|
31955
32089
|
let line = 0;
|
|
31956
32090
|
try {
|
|
@@ -32009,7 +32143,7 @@ async function searchSessionHistory(rawOptions) {
|
|
|
32009
32143
|
const currentProjectRoot = resolveToWorktreeRoot(workingDirectory);
|
|
32010
32144
|
const scopeMode = buildScopeMode(rawOptions.project);
|
|
32011
32145
|
const projectFilter = scopeMode === "project" ? rawOptions.project : void 0;
|
|
32012
|
-
const literalWorkingDirectory = rawOptions.workingDirectory ? (0,
|
|
32146
|
+
const literalWorkingDirectory = rawOptions.workingDirectory ? (0, import_path43.resolve)(rawOptions.workingDirectory) : workingDirectory;
|
|
32013
32147
|
const currentProjectRoots = [currentProjectRoot, literalWorkingDirectory].concat(getMainRepoRoot(currentProjectRoot) ?? []).concat(getClaudeWorktreeParent(currentProjectRoot) ?? []).filter((value, index, arr) => Boolean(value) && arr.indexOf(value) === index);
|
|
32014
32148
|
const transcriptProjectRoots = currentProjectRoots.filter((root) => isWithinProject(root, [currentProjectRoot]));
|
|
32015
32149
|
const targets = scopeMode === "all" ? buildAllProjectTargets() : buildCurrentProjectTargets(currentProjectRoot, transcriptProjectRoots);
|
|
@@ -32082,12 +32216,12 @@ var sessionSearchTool = {
|
|
|
32082
32216
|
// src/tools/trace-tools.ts
|
|
32083
32217
|
var REPLAY_PREFIX2 = "agent-replay-";
|
|
32084
32218
|
function findLatestSessionId(directory) {
|
|
32085
|
-
const stateDir = (0,
|
|
32219
|
+
const stateDir = (0, import_path44.join)(getOmcRoot(directory), "state");
|
|
32086
32220
|
try {
|
|
32087
|
-
const files = (0,
|
|
32221
|
+
const files = (0, import_fs35.readdirSync)(stateDir).filter((f) => f.startsWith(REPLAY_PREFIX2) && f.endsWith(".jsonl")).map((f) => ({
|
|
32088
32222
|
name: f,
|
|
32089
32223
|
sessionId: f.slice(REPLAY_PREFIX2.length, -".jsonl".length),
|
|
32090
|
-
mtime: (0,
|
|
32224
|
+
mtime: (0, import_fs35.statSync)((0, import_path44.join)(stateDir, f)).mtimeMs
|
|
32091
32225
|
})).sort((a, b) => b.mtime - a.mtime);
|
|
32092
32226
|
return files.length > 0 ? files[0].sessionId : null;
|
|
32093
32227
|
} catch {
|
|
@@ -32441,14 +32575,14 @@ No events recorded.`
|
|
|
32441
32575
|
var traceTools = [traceTimelineTool, traceSummaryTool, sessionSearchTool];
|
|
32442
32576
|
|
|
32443
32577
|
// src/lib/shared-memory.ts
|
|
32444
|
-
var
|
|
32445
|
-
var
|
|
32578
|
+
var import_fs36 = require("fs");
|
|
32579
|
+
var import_path45 = require("path");
|
|
32446
32580
|
var CONFIG_FILE_NAME = ".omc-config.json";
|
|
32447
32581
|
function isSharedMemoryEnabled() {
|
|
32448
32582
|
try {
|
|
32449
|
-
const configPath = (0,
|
|
32450
|
-
if (!(0,
|
|
32451
|
-
const raw = JSON.parse((0,
|
|
32583
|
+
const configPath = (0, import_path45.join)(getCopilotConfigDir(), CONFIG_FILE_NAME);
|
|
32584
|
+
if (!(0, import_fs36.existsSync)(configPath)) return true;
|
|
32585
|
+
const raw = JSON.parse((0, import_fs36.readFileSync)(configPath, "utf-8"));
|
|
32452
32586
|
const enabled = raw?.agents?.sharedMemory?.enabled;
|
|
32453
32587
|
if (typeof enabled === "boolean") return enabled;
|
|
32454
32588
|
return true;
|
|
@@ -32482,16 +32616,16 @@ function validateKey(key) {
|
|
|
32482
32616
|
function getNamespaceDir(namespace, worktreeRoot) {
|
|
32483
32617
|
validateNamespace(namespace);
|
|
32484
32618
|
const omcRoot = getOmcRoot(worktreeRoot);
|
|
32485
|
-
return (0,
|
|
32619
|
+
return (0, import_path45.join)(omcRoot, SHARED_MEMORY_DIR, namespace);
|
|
32486
32620
|
}
|
|
32487
32621
|
function getEntryPath(namespace, key, worktreeRoot) {
|
|
32488
32622
|
validateKey(key);
|
|
32489
|
-
return (0,
|
|
32623
|
+
return (0, import_path45.join)(getNamespaceDir(namespace, worktreeRoot), `${key}.json`);
|
|
32490
32624
|
}
|
|
32491
32625
|
function ensureNamespaceDir(namespace, worktreeRoot) {
|
|
32492
32626
|
const dir = getNamespaceDir(namespace, worktreeRoot);
|
|
32493
|
-
if (!(0,
|
|
32494
|
-
(0,
|
|
32627
|
+
if (!(0, import_fs36.existsSync)(dir)) {
|
|
32628
|
+
(0, import_fs36.mkdirSync)(dir, { recursive: true });
|
|
32495
32629
|
}
|
|
32496
32630
|
return dir;
|
|
32497
32631
|
}
|
|
@@ -32506,9 +32640,9 @@ function writeEntry(namespace, key, value, ttl, worktreeRoot) {
|
|
|
32506
32640
|
const lockPath = filePath + ".lock";
|
|
32507
32641
|
const doWrite = () => {
|
|
32508
32642
|
let existingCreatedAt = now;
|
|
32509
|
-
if ((0,
|
|
32643
|
+
if ((0, import_fs36.existsSync)(filePath)) {
|
|
32510
32644
|
try {
|
|
32511
|
-
const existing = JSON.parse((0,
|
|
32645
|
+
const existing = JSON.parse((0, import_fs36.readFileSync)(filePath, "utf-8"));
|
|
32512
32646
|
existingCreatedAt = existing.createdAt || now;
|
|
32513
32647
|
} catch {
|
|
32514
32648
|
}
|
|
@@ -32525,11 +32659,11 @@ function writeEntry(namespace, key, value, ttl, worktreeRoot) {
|
|
|
32525
32659
|
entry.expiresAt = new Date(Date.now() + ttl * 1e3).toISOString();
|
|
32526
32660
|
}
|
|
32527
32661
|
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
32528
|
-
(0,
|
|
32529
|
-
(0,
|
|
32662
|
+
(0, import_fs36.writeFileSync)(tmpPath, JSON.stringify(entry, null, 2), "utf-8");
|
|
32663
|
+
(0, import_fs36.renameSync)(tmpPath, filePath);
|
|
32530
32664
|
try {
|
|
32531
32665
|
const legacyTmp = filePath + ".tmp";
|
|
32532
|
-
if ((0,
|
|
32666
|
+
if ((0, import_fs36.existsSync)(legacyTmp)) (0, import_fs36.unlinkSync)(legacyTmp);
|
|
32533
32667
|
} catch {
|
|
32534
32668
|
}
|
|
32535
32669
|
return entry;
|
|
@@ -32544,12 +32678,12 @@ function readEntry(namespace, key, worktreeRoot) {
|
|
|
32544
32678
|
validateNamespace(namespace);
|
|
32545
32679
|
validateKey(key);
|
|
32546
32680
|
const filePath = getEntryPath(namespace, key, worktreeRoot);
|
|
32547
|
-
if (!(0,
|
|
32681
|
+
if (!(0, import_fs36.existsSync)(filePath)) return null;
|
|
32548
32682
|
try {
|
|
32549
|
-
const entry = JSON.parse((0,
|
|
32683
|
+
const entry = JSON.parse((0, import_fs36.readFileSync)(filePath, "utf-8"));
|
|
32550
32684
|
if (isExpired(entry)) {
|
|
32551
32685
|
try {
|
|
32552
|
-
(0,
|
|
32686
|
+
(0, import_fs36.unlinkSync)(filePath);
|
|
32553
32687
|
} catch {
|
|
32554
32688
|
}
|
|
32555
32689
|
return null;
|
|
@@ -32562,14 +32696,14 @@ function readEntry(namespace, key, worktreeRoot) {
|
|
|
32562
32696
|
function listEntries(namespace, worktreeRoot) {
|
|
32563
32697
|
validateNamespace(namespace);
|
|
32564
32698
|
const dir = getNamespaceDir(namespace, worktreeRoot);
|
|
32565
|
-
if (!(0,
|
|
32699
|
+
if (!(0, import_fs36.existsSync)(dir)) return [];
|
|
32566
32700
|
const items = [];
|
|
32567
32701
|
try {
|
|
32568
|
-
const files = (0,
|
|
32702
|
+
const files = (0, import_fs36.readdirSync)(dir).filter((f) => f.endsWith(".json"));
|
|
32569
32703
|
for (const file of files) {
|
|
32570
32704
|
try {
|
|
32571
|
-
const filePath = (0,
|
|
32572
|
-
const entry = JSON.parse((0,
|
|
32705
|
+
const filePath = (0, import_path45.join)(dir, file);
|
|
32706
|
+
const entry = JSON.parse((0, import_fs36.readFileSync)(filePath, "utf-8"));
|
|
32573
32707
|
if (!isExpired(entry)) {
|
|
32574
32708
|
items.push({
|
|
32575
32709
|
key: entry.key,
|
|
@@ -32588,9 +32722,9 @@ function deleteEntry(namespace, key, worktreeRoot) {
|
|
|
32588
32722
|
validateNamespace(namespace);
|
|
32589
32723
|
validateKey(key);
|
|
32590
32724
|
const filePath = getEntryPath(namespace, key, worktreeRoot);
|
|
32591
|
-
if (!(0,
|
|
32725
|
+
if (!(0, import_fs36.existsSync)(filePath)) return false;
|
|
32592
32726
|
try {
|
|
32593
|
-
(0,
|
|
32727
|
+
(0, import_fs36.unlinkSync)(filePath);
|
|
32594
32728
|
return true;
|
|
32595
32729
|
} catch {
|
|
32596
32730
|
return false;
|
|
@@ -32598,15 +32732,15 @@ function deleteEntry(namespace, key, worktreeRoot) {
|
|
|
32598
32732
|
}
|
|
32599
32733
|
function cleanupExpired(namespace, worktreeRoot) {
|
|
32600
32734
|
const omcRoot = getOmcRoot(worktreeRoot);
|
|
32601
|
-
const sharedMemDir = (0,
|
|
32602
|
-
if (!(0,
|
|
32735
|
+
const sharedMemDir = (0, import_path45.join)(omcRoot, SHARED_MEMORY_DIR);
|
|
32736
|
+
if (!(0, import_fs36.existsSync)(sharedMemDir)) return { removed: 0, namespaces: [] };
|
|
32603
32737
|
const namespacesToClean = [];
|
|
32604
32738
|
if (namespace) {
|
|
32605
32739
|
validateNamespace(namespace);
|
|
32606
32740
|
namespacesToClean.push(namespace);
|
|
32607
32741
|
} else {
|
|
32608
32742
|
try {
|
|
32609
|
-
const entries = (0,
|
|
32743
|
+
const entries = (0, import_fs36.readdirSync)(sharedMemDir, { withFileTypes: true });
|
|
32610
32744
|
for (const entry of entries) {
|
|
32611
32745
|
if (entry.isDirectory()) {
|
|
32612
32746
|
namespacesToClean.push(entry.name);
|
|
@@ -32619,17 +32753,17 @@ function cleanupExpired(namespace, worktreeRoot) {
|
|
|
32619
32753
|
let removed = 0;
|
|
32620
32754
|
const cleanedNamespaces = [];
|
|
32621
32755
|
for (const ns of namespacesToClean) {
|
|
32622
|
-
const nsDir = (0,
|
|
32623
|
-
if (!(0,
|
|
32756
|
+
const nsDir = (0, import_path45.join)(sharedMemDir, ns);
|
|
32757
|
+
if (!(0, import_fs36.existsSync)(nsDir)) continue;
|
|
32624
32758
|
let nsRemoved = 0;
|
|
32625
32759
|
try {
|
|
32626
|
-
const files = (0,
|
|
32760
|
+
const files = (0, import_fs36.readdirSync)(nsDir).filter((f) => f.endsWith(".json"));
|
|
32627
32761
|
for (const file of files) {
|
|
32628
32762
|
try {
|
|
32629
|
-
const filePath = (0,
|
|
32630
|
-
const entry = JSON.parse((0,
|
|
32763
|
+
const filePath = (0, import_path45.join)(nsDir, file);
|
|
32764
|
+
const entry = JSON.parse((0, import_fs36.readFileSync)(filePath, "utf-8"));
|
|
32631
32765
|
if (isExpired(entry)) {
|
|
32632
|
-
(0,
|
|
32766
|
+
(0, import_fs36.unlinkSync)(filePath);
|
|
32633
32767
|
nsRemoved++;
|
|
32634
32768
|
}
|
|
32635
32769
|
} catch {
|
|
@@ -32646,10 +32780,10 @@ function cleanupExpired(namespace, worktreeRoot) {
|
|
|
32646
32780
|
}
|
|
32647
32781
|
function listNamespaces(worktreeRoot) {
|
|
32648
32782
|
const omcRoot = getOmcRoot(worktreeRoot);
|
|
32649
|
-
const sharedMemDir = (0,
|
|
32650
|
-
if (!(0,
|
|
32783
|
+
const sharedMemDir = (0, import_path45.join)(omcRoot, SHARED_MEMORY_DIR);
|
|
32784
|
+
if (!(0, import_fs36.existsSync)(sharedMemDir)) return [];
|
|
32651
32785
|
try {
|
|
32652
|
-
const entries = (0,
|
|
32786
|
+
const entries = (0, import_fs36.readdirSync)(sharedMemDir, { withFileTypes: true });
|
|
32653
32787
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
|
|
32654
32788
|
} catch {
|
|
32655
32789
|
return [];
|
|
@@ -33201,25 +33335,25 @@ var DEFAULT_WIKI_CONFIG = {
|
|
|
33201
33335
|
};
|
|
33202
33336
|
|
|
33203
33337
|
// src/hooks/wiki/storage.ts
|
|
33204
|
-
var
|
|
33205
|
-
var
|
|
33338
|
+
var import_fs37 = require("fs");
|
|
33339
|
+
var import_path46 = require("path");
|
|
33206
33340
|
var WIKI_DIR = "wiki";
|
|
33207
33341
|
var INDEX_FILE = "index.md";
|
|
33208
33342
|
var LOG_FILE = "log.md";
|
|
33209
33343
|
var ENVIRONMENT_FILE = "environment.md";
|
|
33210
33344
|
var RESERVED_FILES = /* @__PURE__ */ new Set([INDEX_FILE, LOG_FILE, ENVIRONMENT_FILE]);
|
|
33211
33345
|
function getWikiDir(root) {
|
|
33212
|
-
return (0,
|
|
33346
|
+
return (0, import_path46.join)(getOmcRoot(root), WIKI_DIR);
|
|
33213
33347
|
}
|
|
33214
33348
|
function ensureWikiDir(root) {
|
|
33215
33349
|
const wikiDir = getWikiDir(root);
|
|
33216
|
-
if (!(0,
|
|
33217
|
-
(0,
|
|
33350
|
+
if (!(0, import_fs37.existsSync)(wikiDir)) {
|
|
33351
|
+
(0, import_fs37.mkdirSync)(wikiDir, { recursive: true });
|
|
33218
33352
|
}
|
|
33219
33353
|
const omcRoot = getOmcRoot(root);
|
|
33220
|
-
const gitignorePath = (0,
|
|
33221
|
-
if ((0,
|
|
33222
|
-
const content = (0,
|
|
33354
|
+
const gitignorePath = (0, import_path46.join)(omcRoot, ".gitignore");
|
|
33355
|
+
if ((0, import_fs37.existsSync)(gitignorePath)) {
|
|
33356
|
+
const content = (0, import_fs37.readFileSync)(gitignorePath, "utf-8");
|
|
33223
33357
|
if (!content.includes("wiki/")) {
|
|
33224
33358
|
atomicWriteFileSync(gitignorePath, content.trimEnd() + "\nwiki/\n");
|
|
33225
33359
|
}
|
|
@@ -33230,7 +33364,7 @@ function ensureWikiDir(root) {
|
|
|
33230
33364
|
}
|
|
33231
33365
|
function withWikiLock(root, fn, options) {
|
|
33232
33366
|
const wikiDir = ensureWikiDir(root);
|
|
33233
|
-
const lockPath = lockPathFor((0,
|
|
33367
|
+
const lockPath = lockPathFor((0, import_path46.join)(wikiDir, ".wiki-lock"));
|
|
33234
33368
|
const remainingMs = options?.deadlineAt === void 0 ? void 0 : Math.max(0, options.deadlineAt - Date.now());
|
|
33235
33369
|
const timeoutMs = Math.min(options?.timeoutMs ?? 5e3, remainingMs ?? Infinity);
|
|
33236
33370
|
return withFileLockSync(lockPath, fn, { timeoutMs, retryDelayMs: 50 });
|
|
@@ -33314,9 +33448,9 @@ function safeWikiPath(wikiDir, filename) {
|
|
|
33314
33448
|
if (filename.includes("/") || filename.includes("\\") || filename.includes("..")) {
|
|
33315
33449
|
return null;
|
|
33316
33450
|
}
|
|
33317
|
-
const filePath = (0,
|
|
33318
|
-
const resolved = (0,
|
|
33319
|
-
if (!resolved.startsWith((0,
|
|
33451
|
+
const filePath = (0, import_path46.join)(wikiDir, filename);
|
|
33452
|
+
const resolved = (0, import_path46.resolve)(filePath);
|
|
33453
|
+
if (!resolved.startsWith((0, import_path46.resolve)(wikiDir) + import_path46.sep)) {
|
|
33320
33454
|
return null;
|
|
33321
33455
|
}
|
|
33322
33456
|
return filePath;
|
|
@@ -33325,9 +33459,9 @@ function readPage(root, filename) {
|
|
|
33325
33459
|
const wikiDir = getWikiDir(root);
|
|
33326
33460
|
const filePath = safeWikiPath(wikiDir, filename);
|
|
33327
33461
|
if (!filePath) return null;
|
|
33328
|
-
if (!(0,
|
|
33462
|
+
if (!(0, import_fs37.existsSync)(filePath)) return null;
|
|
33329
33463
|
try {
|
|
33330
|
-
const raw = (0,
|
|
33464
|
+
const raw = (0, import_fs37.readFileSync)(filePath, "utf-8");
|
|
33331
33465
|
const parsed = parseFrontmatter(raw);
|
|
33332
33466
|
if (!parsed) return null;
|
|
33333
33467
|
return {
|
|
@@ -33341,16 +33475,16 @@ function readPage(root, filename) {
|
|
|
33341
33475
|
}
|
|
33342
33476
|
function listPages(root) {
|
|
33343
33477
|
const wikiDir = getWikiDir(root);
|
|
33344
|
-
if (!(0,
|
|
33345
|
-
return (0,
|
|
33478
|
+
if (!(0, import_fs37.existsSync)(wikiDir)) return [];
|
|
33479
|
+
return (0, import_fs37.readdirSync)(wikiDir).filter((f) => f.endsWith(".md") && !RESERVED_FILES.has(f)).sort();
|
|
33346
33480
|
}
|
|
33347
33481
|
function readAllPages(root) {
|
|
33348
33482
|
return listPages(root).map((f) => readPage(root, f)).filter((p) => p !== null);
|
|
33349
33483
|
}
|
|
33350
33484
|
function readIndex(root) {
|
|
33351
|
-
const indexPath = (0,
|
|
33352
|
-
if (!(0,
|
|
33353
|
-
return (0,
|
|
33485
|
+
const indexPath = (0, import_path46.join)(getWikiDir(root), INDEX_FILE);
|
|
33486
|
+
if (!(0, import_fs37.existsSync)(indexPath)) return null;
|
|
33487
|
+
return (0, import_fs37.readFileSync)(indexPath, "utf-8");
|
|
33354
33488
|
}
|
|
33355
33489
|
function writePageUnsafe(root, page) {
|
|
33356
33490
|
if (RESERVED_FILES.has(page.filename)) {
|
|
@@ -33365,8 +33499,8 @@ function deletePageUnsafe(root, filename) {
|
|
|
33365
33499
|
const wikiDir = getWikiDir(root);
|
|
33366
33500
|
const filePath = safeWikiPath(wikiDir, filename);
|
|
33367
33501
|
if (!filePath) return false;
|
|
33368
|
-
if (!(0,
|
|
33369
|
-
(0,
|
|
33502
|
+
if (!(0, import_fs37.existsSync)(filePath)) return false;
|
|
33503
|
+
(0, import_fs37.unlinkSync)(filePath);
|
|
33370
33504
|
return true;
|
|
33371
33505
|
}
|
|
33372
33506
|
function updateIndexUnsafe(root) {
|
|
@@ -33395,19 +33529,19 @@ function updateIndexUnsafe(root) {
|
|
|
33395
33529
|
lines.push("");
|
|
33396
33530
|
}
|
|
33397
33531
|
const wikiDir = ensureWikiDir(root);
|
|
33398
|
-
atomicWriteFileSync((0,
|
|
33532
|
+
atomicWriteFileSync((0, import_path46.join)(wikiDir, INDEX_FILE), lines.join("\n"));
|
|
33399
33533
|
}
|
|
33400
33534
|
function appendLogUnsafe(root, entry) {
|
|
33401
33535
|
const wikiDir = ensureWikiDir(root);
|
|
33402
|
-
const logPath = (0,
|
|
33536
|
+
const logPath = (0, import_path46.join)(wikiDir, LOG_FILE);
|
|
33403
33537
|
const logLine = `## [${entry.timestamp}] ${entry.operation}
|
|
33404
33538
|
- **Pages:** ${entry.pagesAffected.join(", ") || "none"}
|
|
33405
33539
|
- **Summary:** ${entry.summary}
|
|
33406
33540
|
|
|
33407
33541
|
`;
|
|
33408
33542
|
let existing = "";
|
|
33409
|
-
if ((0,
|
|
33410
|
-
existing = (0,
|
|
33543
|
+
if ((0, import_fs37.existsSync)(logPath)) {
|
|
33544
|
+
existing = (0, import_fs37.readFileSync)(logPath, "utf-8");
|
|
33411
33545
|
} else {
|
|
33412
33546
|
existing = "# Wiki Log\n\n";
|
|
33413
33547
|
}
|
|
@@ -34167,37 +34301,37 @@ var wikiTools = [
|
|
|
34167
34301
|
];
|
|
34168
34302
|
|
|
34169
34303
|
// src/tools/skills-tools.ts
|
|
34170
|
-
var
|
|
34304
|
+
var import_path50 = require("path");
|
|
34171
34305
|
var import_os7 = require("os");
|
|
34172
34306
|
|
|
34173
34307
|
// src/hooks/learner/loader.ts
|
|
34174
|
-
var
|
|
34308
|
+
var import_fs39 = require("fs");
|
|
34175
34309
|
var import_crypto11 = require("crypto");
|
|
34176
|
-
var
|
|
34310
|
+
var import_path49 = require("path");
|
|
34177
34311
|
|
|
34178
34312
|
// src/hooks/learner/finder.ts
|
|
34179
|
-
var
|
|
34180
|
-
var
|
|
34313
|
+
var import_fs38 = require("fs");
|
|
34314
|
+
var import_path48 = require("path");
|
|
34181
34315
|
|
|
34182
34316
|
// src/hooks/learner/constants.ts
|
|
34183
|
-
var
|
|
34317
|
+
var import_path47 = require("path");
|
|
34184
34318
|
var import_os6 = require("os");
|
|
34185
|
-
var USER_SKILLS_DIR = (0,
|
|
34186
|
-
var GLOBAL_SKILLS_DIR = (0,
|
|
34319
|
+
var USER_SKILLS_DIR = (0, import_path47.join)(getCopilotConfigDir(), "skills", "omc-learned");
|
|
34320
|
+
var GLOBAL_SKILLS_DIR = (0, import_path47.join)((0, import_os6.homedir)(), ".omg", "skills");
|
|
34187
34321
|
var PROJECT_SKILLS_SUBDIR = OmcPaths.SKILLS;
|
|
34188
|
-
var PROJECT_AGENT_SKILLS_SUBDIR = (0,
|
|
34322
|
+
var PROJECT_AGENT_SKILLS_SUBDIR = (0, import_path47.join)(".agents", "skills");
|
|
34189
34323
|
var MAX_RECURSION_DEPTH = 10;
|
|
34190
34324
|
var SKILL_EXTENSION = ".md";
|
|
34191
34325
|
var DEBUG_ENABLED = process.env.OMC_DEBUG === "1";
|
|
34192
34326
|
|
|
34193
34327
|
// src/hooks/learner/finder.ts
|
|
34194
34328
|
function findSkillFilesRecursive(dir, results, depth = 0) {
|
|
34195
|
-
if (!(0,
|
|
34329
|
+
if (!(0, import_fs38.existsSync)(dir)) return;
|
|
34196
34330
|
if (depth > MAX_RECURSION_DEPTH) return;
|
|
34197
34331
|
try {
|
|
34198
|
-
const entries = (0,
|
|
34332
|
+
const entries = (0, import_fs38.readdirSync)(dir, { withFileTypes: true });
|
|
34199
34333
|
for (const entry of entries) {
|
|
34200
|
-
const fullPath = (0,
|
|
34334
|
+
const fullPath = (0, import_path48.join)(dir, entry.name);
|
|
34201
34335
|
if (entry.isDirectory()) {
|
|
34202
34336
|
findSkillFilesRecursive(fullPath, results, depth + 1);
|
|
34203
34337
|
} else if (entry.isFile() && entry.name.endsWith(SKILL_EXTENSION)) {
|
|
@@ -34212,15 +34346,15 @@ function findSkillFilesRecursive(dir, results, depth = 0) {
|
|
|
34212
34346
|
}
|
|
34213
34347
|
function safeRealpathSync(filePath) {
|
|
34214
34348
|
try {
|
|
34215
|
-
return (0,
|
|
34349
|
+
return (0, import_fs38.realpathSync)(filePath);
|
|
34216
34350
|
} catch {
|
|
34217
34351
|
return filePath;
|
|
34218
34352
|
}
|
|
34219
34353
|
}
|
|
34220
34354
|
function isWithinBoundary(realPath, boundary) {
|
|
34221
|
-
const normalizedReal = (0,
|
|
34222
|
-
const normalizedBoundary = (0,
|
|
34223
|
-
return normalizedReal === normalizedBoundary || normalizedReal.startsWith(normalizedBoundary +
|
|
34355
|
+
const normalizedReal = (0, import_path48.normalize)(realPath);
|
|
34356
|
+
const normalizedBoundary = (0, import_path48.normalize)(safeRealpathSync(boundary));
|
|
34357
|
+
return normalizedReal === normalizedBoundary || normalizedReal.startsWith(normalizedBoundary + import_path48.sep);
|
|
34224
34358
|
}
|
|
34225
34359
|
function findSkillFiles(projectRoot, options) {
|
|
34226
34360
|
const candidates = [];
|
|
@@ -34228,8 +34362,8 @@ function findSkillFiles(projectRoot, options) {
|
|
|
34228
34362
|
const scope = options?.scope ?? "all";
|
|
34229
34363
|
if (projectRoot && (scope === "project" || scope === "all")) {
|
|
34230
34364
|
const projectSkillDirs = [
|
|
34231
|
-
(0,
|
|
34232
|
-
(0,
|
|
34365
|
+
(0, import_path48.join)(projectRoot, PROJECT_SKILLS_SUBDIR),
|
|
34366
|
+
(0, import_path48.join)(projectRoot, PROJECT_AGENT_SKILLS_SUBDIR)
|
|
34233
34367
|
];
|
|
34234
34368
|
for (const projectSkillsDir of projectSkillDirs) {
|
|
34235
34369
|
const projectFiles = [];
|
|
@@ -34438,7 +34572,7 @@ function loadAllSkills(projectRoot) {
|
|
|
34438
34572
|
const seenIds = /* @__PURE__ */ new Map();
|
|
34439
34573
|
for (const candidate of candidates) {
|
|
34440
34574
|
try {
|
|
34441
|
-
const rawContent = (0,
|
|
34575
|
+
const rawContent = (0, import_fs39.readFileSync)(candidate.path, "utf-8");
|
|
34442
34576
|
const { metadata, content, valid, errors } = parseSkillFile(rawContent);
|
|
34443
34577
|
if (!valid) {
|
|
34444
34578
|
if (DEBUG_ENABLED) {
|
|
@@ -34447,7 +34581,7 @@ function loadAllSkills(projectRoot) {
|
|
|
34447
34581
|
continue;
|
|
34448
34582
|
}
|
|
34449
34583
|
const skillId = metadata.id;
|
|
34450
|
-
const relativePath = (0,
|
|
34584
|
+
const relativePath = (0, import_path49.normalize)((0, import_path49.relative)(candidate.sourceDir, candidate.path));
|
|
34451
34585
|
const skill = {
|
|
34452
34586
|
path: candidate.path,
|
|
34453
34587
|
relativePath,
|
|
@@ -34473,13 +34607,13 @@ function loadAllSkills(projectRoot) {
|
|
|
34473
34607
|
// src/tools/skills-tools.ts
|
|
34474
34608
|
var ALLOWED_BOUNDARIES = [process.cwd(), (0, import_os7.homedir)()];
|
|
34475
34609
|
function validateProjectRoot(input) {
|
|
34476
|
-
const normalized = (0,
|
|
34610
|
+
const normalized = (0, import_path50.normalize)((0, import_path50.resolve)(input));
|
|
34477
34611
|
if (input.includes("..")) {
|
|
34478
34612
|
throw new Error("Invalid project root: path traversal not allowed");
|
|
34479
34613
|
}
|
|
34480
34614
|
const isWithinAllowed = ALLOWED_BOUNDARIES.some((boundary) => {
|
|
34481
|
-
const normalizedBoundary = (0,
|
|
34482
|
-
return normalized === normalizedBoundary || normalized.startsWith(normalizedBoundary +
|
|
34615
|
+
const normalizedBoundary = (0, import_path50.normalize)(boundary);
|
|
34616
|
+
return normalized === normalizedBoundary || normalized.startsWith(normalizedBoundary + import_path50.sep);
|
|
34483
34617
|
});
|
|
34484
34618
|
if (!isWithinAllowed) {
|
|
34485
34619
|
throw new Error("Invalid project root: path is outside allowed directories");
|