oh-my-codex 0.20.3 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +35 -18
- package/Cargo.toml +1 -1
- package/README.md +22 -19
- package/crates/omx-runtime/Cargo.toml +3 -0
- package/crates/omx-runtime/src/main.rs +390 -0
- package/crates/omx-runtime/tests/execution.rs +264 -0
- package/dist/adapt/__tests__/herdr-target.test.d.ts +2 -0
- package/dist/adapt/__tests__/herdr-target.test.d.ts.map +1 -0
- package/dist/adapt/__tests__/herdr-target.test.js +72 -0
- package/dist/adapt/__tests__/herdr-target.test.js.map +1 -0
- package/dist/adapt/contracts.d.ts +1 -1
- package/dist/adapt/contracts.d.ts.map +1 -1
- package/dist/adapt/contracts.js +1 -1
- package/dist/adapt/contracts.js.map +1 -1
- package/dist/adapt/herdr/__tests__/authority.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/authority.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/authority.test.js +49 -0
- package/dist/adapt/herdr/__tests__/authority.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/bridge.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/bridge.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/bridge.test.js +176 -0
- package/dist/adapt/herdr/__tests__/bridge.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.js +45 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/semantic.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/semantic.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/semantic.test.js +130 -0
- package/dist/adapt/herdr/__tests__/semantic.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.js +54 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.js +104 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/team-map.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/team-map.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/team-map.test.js +46 -0
- package/dist/adapt/herdr/__tests__/team-map.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/transport.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/transport.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/transport.test.js +160 -0
- package/dist/adapt/herdr/__tests__/transport.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/wiring.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/wiring.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/wiring.test.js +118 -0
- package/dist/adapt/herdr/__tests__/wiring.test.js.map +1 -0
- package/dist/adapt/herdr/authority.d.ts +34 -0
- package/dist/adapt/herdr/authority.d.ts.map +1 -0
- package/dist/adapt/herdr/authority.js +71 -0
- package/dist/adapt/herdr/authority.js.map +1 -0
- package/dist/adapt/herdr/bridge.d.ts +84 -0
- package/dist/adapt/herdr/bridge.d.ts.map +1 -0
- package/dist/adapt/herdr/bridge.js +222 -0
- package/dist/adapt/herdr/bridge.js.map +1 -0
- package/dist/adapt/herdr/sanitize.d.ts +20 -0
- package/dist/adapt/herdr/sanitize.d.ts.map +1 -0
- package/dist/adapt/herdr/sanitize.js +70 -0
- package/dist/adapt/herdr/sanitize.js.map +1 -0
- package/dist/adapt/herdr/semantic.d.ts +67 -0
- package/dist/adapt/herdr/semantic.d.ts.map +1 -0
- package/dist/adapt/herdr/semantic.js +170 -0
- package/dist/adapt/herdr/semantic.js.map +1 -0
- package/dist/adapt/herdr/seq-store.d.ts +32 -0
- package/dist/adapt/herdr/seq-store.d.ts.map +1 -0
- package/dist/adapt/herdr/seq-store.js +126 -0
- package/dist/adapt/herdr/seq-store.js.map +1 -0
- package/dist/adapt/herdr/team-map.d.ts +30 -0
- package/dist/adapt/herdr/team-map.d.ts.map +1 -0
- package/dist/adapt/herdr/team-map.js +37 -0
- package/dist/adapt/herdr/team-map.js.map +1 -0
- package/dist/adapt/herdr/transport.d.ts +115 -0
- package/dist/adapt/herdr/transport.d.ts.map +1 -0
- package/dist/adapt/herdr/transport.js +260 -0
- package/dist/adapt/herdr/transport.js.map +1 -0
- package/dist/adapt/herdr/wiring.d.ts +24 -0
- package/dist/adapt/herdr/wiring.d.ts.map +1 -0
- package/dist/adapt/herdr/wiring.js +62 -0
- package/dist/adapt/herdr/wiring.js.map +1 -0
- package/dist/adapt/herdr.d.ts +19 -0
- package/dist/adapt/herdr.d.ts.map +1 -0
- package/dist/adapt/herdr.js +115 -0
- package/dist/adapt/herdr.js.map +1 -0
- package/dist/adapt/index.d.ts +4 -0
- package/dist/adapt/index.d.ts.map +1 -1
- package/dist/adapt/index.js +48 -0
- package/dist/adapt/index.js.map +1 -1
- package/dist/adapt/registry.d.ts.map +1 -1
- package/dist/adapt/registry.js +11 -0
- package/dist/adapt/registry.js.map +1 -1
- package/dist/agents/__tests__/definitions.test.js +0 -27
- package/dist/agents/__tests__/definitions.test.js.map +1 -1
- package/dist/agents/__tests__/native-config.test.js +3 -8
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +0 -41
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/policy.d.ts.map +1 -1
- package/dist/agents/policy.js +0 -1
- package/dist/agents/policy.js.map +1 -1
- package/dist/auth/__tests__/hotswap.test.js +60 -1
- package/dist/auth/__tests__/hotswap.test.js.map +1 -1
- package/dist/auth/__tests__/storage.test.js +33 -1
- package/dist/auth/__tests__/storage.test.js.map +1 -1
- package/dist/auth/hotswap.d.ts +16 -2
- package/dist/auth/hotswap.d.ts.map +1 -1
- package/dist/auth/hotswap.js +22 -7
- package/dist/auth/hotswap.js.map +1 -1
- package/dist/auth/storage.js +1 -1
- package/dist/auth/storage.js.map +1 -1
- package/dist/autopilot/__tests__/completion-gate-advisory.test.d.ts +2 -0
- package/dist/autopilot/__tests__/completion-gate-advisory.test.d.ts.map +1 -0
- package/dist/autopilot/__tests__/completion-gate-advisory.test.js +383 -0
- package/dist/autopilot/__tests__/completion-gate-advisory.test.js.map +1 -0
- package/dist/autopilot/completion-gate.d.ts +6 -1
- package/dist/autopilot/completion-gate.d.ts.map +1 -1
- package/dist/autopilot/completion-gate.js +247 -7
- package/dist/autopilot/completion-gate.js.map +1 -1
- package/dist/catalog/__tests__/generator.test.js +15 -10
- package/dist/catalog/__tests__/generator.test.js.map +1 -1
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +13 -7
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +1 -1
- package/dist/catalog/__tests__/schema.test.js +3 -5
- package/dist/catalog/__tests__/schema.test.js.map +1 -1
- package/dist/catalog/schema.js +1 -1
- package/dist/catalog/schema.js.map +1 -1
- package/dist/cli/__tests__/agents-init.test.js +4 -23
- package/dist/cli/__tests__/agents-init.test.js.map +1 -1
- package/dist/cli/__tests__/api.test.js +61 -24
- package/dist/cli/__tests__/api.test.js.map +1 -1
- package/dist/cli/__tests__/auth.test.js +3 -1
- package/dist/cli/__tests__/auth.test.js.map +1 -1
- package/dist/cli/__tests__/autopilot.test.d.ts +2 -0
- package/dist/cli/__tests__/autopilot.test.d.ts.map +1 -0
- package/dist/cli/__tests__/autopilot.test.js +143 -0
- package/dist/cli/__tests__/autopilot.test.js.map +1 -0
- package/dist/cli/__tests__/codex-feature-probe.test.js +66 -1
- package/dist/cli/__tests__/codex-feature-probe.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +76 -4
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/detached-leader-teardown.test.d.ts +2 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.d.ts.map +1 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.js +473 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts +2 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts.map +1 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.js +103 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts +2 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts.map +1 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.js +206 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-team.test.js +85 -0
- package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +38 -6
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +75 -0
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +621 -460
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +1125 -143
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-parity.test.js +4 -3
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/native-assets.test.js +398 -16
- package/dist/cli/__tests__/native-assets.test.js.map +1 -1
- package/dist/cli/__tests__/native-hook-claim-journal.test.js +53 -5
- package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +5 -8
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-deslop-contract.test.js +4 -18
- package/dist/cli/__tests__/ralph-deslop-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +4 -30
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +4 -15
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +1 -1
- package/dist/cli/__tests__/ralph.test.js +2 -2
- package/dist/cli/__tests__/ralph.test.js.map +1 -1
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +57 -57
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -1
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts +2 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.js +56 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.js.map +1 -0
- package/dist/cli/__tests__/ralplan.test.js +131 -14
- package/dist/cli/__tests__/ralplan.test.js.map +1 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.js +1153 -43
- package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
- package/dist/cli/__tests__/session-search-help.test.js +65 -3
- package/dist/cli/__tests__/session-search-help.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +57 -55
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +34 -0
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js +1 -1
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +258 -26
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js +1 -1
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +3 -6
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +180 -21
- package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js +93 -41
- package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +45 -1
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +161 -2
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +73 -28
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/update.test.js +749 -177
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +32 -2
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
- package/dist/cli/api.d.ts.map +1 -1
- package/dist/cli/api.js +9 -10
- package/dist/cli/api.js.map +1 -1
- package/dist/cli/autopilot.d.ts +8 -0
- package/dist/cli/autopilot.d.ts.map +1 -0
- package/dist/cli/autopilot.js +160 -0
- package/dist/cli/autopilot.js.map +1 -0
- package/dist/cli/codex-feature-probe.d.ts +16 -0
- package/dist/cli/codex-feature-probe.d.ts.map +1 -1
- package/dist/cli/codex-feature-probe.js +44 -0
- package/dist/cli/codex-feature-probe.js.map +1 -1
- package/dist/cli/codex-home.d.ts.map +1 -1
- package/dist/cli/codex-home.js +7 -4
- package/dist/cli/codex-home.js.map +1 -1
- package/dist/cli/doctor.d.ts +29 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +433 -19
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +231 -12
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2354 -724
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-parity.d.ts.map +1 -1
- package/dist/cli/mcp-parity.js +7 -3
- package/dist/cli/mcp-parity.js.map +1 -1
- package/dist/cli/native-assets.d.ts +26 -1
- package/dist/cli/native-assets.d.ts.map +1 -1
- package/dist/cli/native-assets.js +448 -51
- package/dist/cli/native-assets.js.map +1 -1
- package/dist/cli/native-hook-claim-journal.d.ts +8 -4
- package/dist/cli/native-hook-claim-journal.d.ts.map +1 -1
- package/dist/cli/native-hook-claim-journal.js +30 -8
- package/dist/cli/native-hook-claim-journal.js.map +1 -1
- package/dist/cli/package-manager-ownership.d.ts +69 -0
- package/dist/cli/package-manager-ownership.d.ts.map +1 -0
- package/dist/cli/package-manager-ownership.js +338 -0
- package/dist/cli/package-manager-ownership.js.map +1 -0
- package/dist/cli/plugin-marketplace.d.ts +1 -0
- package/dist/cli/plugin-marketplace.d.ts.map +1 -1
- package/dist/cli/plugin-marketplace.js +123 -55
- package/dist/cli/plugin-marketplace.js.map +1 -1
- package/dist/cli/ralph.js +2 -2
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/ralplan.d.ts +6 -2
- package/dist/cli/ralplan.d.ts.map +1 -1
- package/dist/cli/ralplan.js +134 -34
- package/dist/cli/ralplan.js.map +1 -1
- package/dist/cli/session-search.d.ts.map +1 -1
- package/dist/cli/session-search.js +38 -1
- package/dist/cli/session-search.js.map +1 -1
- package/dist/cli/setup-preferences.d.ts +15 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -1
- package/dist/cli/setup-preferences.js +27 -1
- package/dist/cli/setup-preferences.js.map +1 -1
- package/dist/cli/setup.d.ts +6 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +425 -215
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/sparkshell.d.ts.map +1 -1
- package/dist/cli/sparkshell.js +52 -9
- package/dist/cli/sparkshell.js.map +1 -1
- package/dist/cli/ultragoal.d.ts +1 -1
- package/dist/cli/ultragoal.d.ts.map +1 -1
- package/dist/cli/ultragoal.js +10 -7
- package/dist/cli/ultragoal.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +27 -28
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update-worker.d.ts +2 -0
- package/dist/cli/update-worker.d.ts.map +1 -0
- package/dist/cli/update-worker.js +142 -0
- package/dist/cli/update-worker.js.map +1 -0
- package/dist/cli/update.d.ts +16 -23
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +212 -241
- package/dist/cli/update.js.map +1 -1
- package/dist/compat/__tests__/upgrade-from-0-20.test.d.ts +2 -0
- package/dist/compat/__tests__/upgrade-from-0-20.test.d.ts.map +1 -0
- package/dist/compat/__tests__/upgrade-from-0-20.test.js +109 -0
- package/dist/compat/__tests__/upgrade-from-0-20.test.js.map +1 -0
- package/dist/compat/upgrade-from-0-20.d.ts +64 -0
- package/dist/compat/upgrade-from-0-20.d.ts.map +1 -0
- package/dist/compat/upgrade-from-0-20.js +276 -0
- package/dist/compat/upgrade-from-0-20.js.map +1 -0
- package/dist/config/__tests__/generator-idempotent.test.js +173 -29
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +3 -1
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/generator.d.ts +25 -3
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +113 -35
- package/dist/config/generator.js.map +1 -1
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +25 -0
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.d.ts +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.js +2 -0
- package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +3 -1
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/analyze-skill-contract.test.js +24 -31
- package/dist/hooks/__tests__/analyze-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/anti-slop-workflow.test.js +66 -135
- package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +47 -106
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/code-review-skill-contract.test.js +16 -18
- package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +2 -14
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts.map +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js +56 -234
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +1 -3
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/design-skill.test.js +18 -16
- package/dist/hooks/__tests__/design-skill.test.js.map +1 -1
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js +24 -20
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts +2 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js +164 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js.map +1 -0
- package/dist/hooks/__tests__/issue-3497-hook-simplification.test.d.ts +2 -0
- package/dist/hooks/__tests__/issue-3497-hook-simplification.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/issue-3497-hook-simplification.test.js +169 -0
- package/dist/hooks/__tests__/issue-3497-hook-simplification.test.js.map +1 -0
- package/dist/hooks/__tests__/keyword-detector.test.js +226 -858
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +176 -14
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +1 -0
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +33 -21
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +27 -0
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +10 -118
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +14 -904
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +7 -0
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +5 -5
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +7 -7
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +11 -8
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +7 -6
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +2 -1
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +1 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js +19 -21
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js +23 -3
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +23 -28
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
- package/dist/hooks/__tests__/research-workflow-boundaries.test.js +9 -8
- package/dist/hooks/__tests__/research-workflow-boundaries.test.js.map +1 -1
- package/dist/hooks/__tests__/session.test.js +3656 -656
- package/dist/hooks/__tests__/session.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.js +13 -22
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-guidance-contract.test.js +3 -13
- package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/sunset-routing-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/sunset-routing-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/sunset-routing-contract.test.js +172 -0
- package/dist/hooks/__tests__/sunset-routing-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js +2 -2
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.js +18 -3
- package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-ralph-skill.test.js +20 -17
- package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-verdict-loop.test.js +17 -18
- package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +1 -1
- package/dist/hooks/agents-overlay.js +1 -1
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js +108 -2
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.js +151 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js +20 -3
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/extensibility/plugin-runner.js +1 -0
- package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
- package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
- package/dist/hooks/extensibility/runtime.js.map +1 -1
- package/dist/hooks/extensibility/sdk/paths.d.ts +1 -1
- package/dist/hooks/extensibility/sdk/paths.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/paths.js +2 -2
- package/dist/hooks/extensibility/sdk/paths.js.map +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.d.ts +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.js +55 -15
- package/dist/hooks/extensibility/sdk/runtime-state.js.map +1 -1
- package/dist/hooks/extensibility/sdk.d.ts +1 -0
- package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk.js +1 -1
- package/dist/hooks/extensibility/sdk.js.map +1 -1
- package/dist/hooks/extensibility/types.d.ts +7 -0
- package/dist/hooks/extensibility/types.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +6 -47
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +156 -268
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +14 -26
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hooks/native/capability-warnings.d.ts +16 -0
- package/dist/hooks/native/capability-warnings.d.ts.map +1 -0
- package/dist/hooks/native/capability-warnings.js +40 -0
- package/dist/hooks/native/capability-warnings.js.map +1 -0
- package/dist/hooks/native/index.d.ts +17 -0
- package/dist/hooks/native/index.d.ts.map +1 -0
- package/dist/hooks/native/index.js +17 -0
- package/dist/hooks/native/index.js.map +1 -0
- package/dist/hooks/native/pre-tool-use-advisory.d.ts +17 -0
- package/dist/hooks/native/pre-tool-use-advisory.d.ts.map +1 -0
- package/dist/hooks/native/pre-tool-use-advisory.js +112 -0
- package/dist/hooks/native/pre-tool-use-advisory.js.map +1 -0
- package/dist/hooks/native/types.d.ts +30 -0
- package/dist/hooks/native/types.d.ts.map +1 -0
- package/dist/hooks/native/types.js +22 -0
- package/dist/hooks/native/types.js.map +1 -0
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +46 -93
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hooks/session.d.ts +197 -18
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +1939 -271
- package/dist/hooks/session.js.map +1 -1
- package/dist/hooks/sunset-stub.d.ts +17 -0
- package/dist/hooks/sunset-stub.d.ts.map +1 -0
- package/dist/hooks/sunset-stub.js +125 -0
- package/dist/hooks/sunset-stub.js.map +1 -0
- package/dist/hud/__tests__/hud-tmux-injection.test.js +6 -6
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
- package/dist/hud/__tests__/index.test.js +26 -16
- package/dist/hud/__tests__/index.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +83 -78
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +36 -31
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/tmux-split-realtmux.test.d.ts +2 -0
- package/dist/hud/__tests__/tmux-split-realtmux.test.d.ts.map +1 -0
- package/dist/hud/__tests__/tmux-split-realtmux.test.js +112 -0
- package/dist/hud/__tests__/tmux-split-realtmux.test.js.map +1 -0
- package/dist/hud/__tests__/tmux.test.js +217 -198
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/tmux.d.ts +43 -4
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +1025 -139
- package/dist/hud/tmux.js.map +1 -1
- package/dist/leader/__tests__/contract.test.js +71 -34
- package/dist/leader/__tests__/contract.test.js.map +1 -1
- package/dist/leader/contract.d.ts +1 -6
- package/dist/leader/contract.d.ts.map +1 -1
- package/dist/leader/contract.js +25 -24
- package/dist/leader/contract.js.map +1 -1
- package/dist/mcp/__tests__/hermes-bridge.test.js +17 -0
- package/dist/mcp/__tests__/hermes-bridge.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +4 -4
- package/dist/mcp/__tests__/state-paths.test.js +735 -4
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server-ralph-phase.test.js +29 -4
- package/dist/mcp/__tests__/state-server-ralph-phase.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server-schema.test.js +13 -3
- package/dist/mcp/__tests__/state-server-schema.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server.test.js +11 -1033
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/__tests__/trace-server.test.js +2 -2
- package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
- package/dist/mcp/hermes-bridge.d.ts.map +1 -1
- package/dist/mcp/hermes-bridge.js +2 -2
- package/dist/mcp/hermes-bridge.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +78 -4
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +543 -40
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts +68 -97
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +116 -67
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/modes/__tests__/base-autopilot-gates.test.js +1 -168
- package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -1
- package/dist/modes/__tests__/base-autoresearch-contract.test.js +1 -85
- package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +1 -1
- package/dist/modes/__tests__/base-multi-state-compat.test.js +1 -35
- package/dist/modes/__tests__/base-multi-state-compat.test.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +10 -158
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/base.d.ts +6 -6
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +116 -90
- package/dist/modes/base.js.map +1 -1
- package/dist/native-assets/archive.d.ts +17 -0
- package/dist/native-assets/archive.d.ts.map +1 -0
- package/dist/native-assets/archive.js +238 -0
- package/dist/native-assets/archive.js.map +1 -0
- package/dist/native-assets/policy.d.ts +42 -0
- package/dist/native-assets/policy.d.ts.map +1 -0
- package/dist/native-assets/policy.js +155 -0
- package/dist/native-assets/policy.js.map +1 -0
- package/dist/notifications/__tests__/formatter.test.js +8 -0
- package/dist/notifications/__tests__/formatter.test.js.map +1 -1
- package/dist/notifications/__tests__/template-engine.test.js +8 -0
- package/dist/notifications/__tests__/template-engine.test.js.map +1 -1
- package/dist/notifications/formatter.js +1 -1
- package/dist/notifications/formatter.js.map +1 -1
- package/dist/notifications/template-engine.js +1 -1
- package/dist/notifications/template-engine.js.map +1 -1
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js +0 -21
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js.map +1 -1
- package/dist/question/autopilot-wait.d.ts.map +1 -1
- package/dist/question/autopilot-wait.js +2 -2
- package/dist/question/autopilot-wait.js.map +1 -1
- package/dist/question/deep-interview.d.ts +1 -2
- package/dist/question/deep-interview.d.ts.map +1 -1
- package/dist/question/deep-interview.js +4 -4
- package/dist/question/deep-interview.js.map +1 -1
- package/dist/ralplan/__tests__/documented-leader-preflight.test.js +328 -39
- package/dist/ralplan/__tests__/documented-leader-preflight.test.js.map +1 -1
- package/dist/ralplan/__tests__/runtime.test.js +56 -821
- package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
- package/dist/ralplan/documented-leader-preflight.d.ts +15 -8
- package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -1
- package/dist/ralplan/documented-leader-preflight.js +356 -54
- package/dist/ralplan/documented-leader-preflight.js.map +1 -1
- package/dist/ralplan/runtime.d.ts +2 -2
- package/dist/ralplan/runtime.d.ts.map +1 -1
- package/dist/ralplan/runtime.js +145 -163
- package/dist/ralplan/runtime.js.map +1 -1
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +45 -0
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/runtime/run-state.d.ts +5 -1
- package/dist/runtime/run-state.d.ts.map +1 -1
- package/dist/runtime/run-state.js +15 -8
- package/dist/runtime/run-state.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +12490 -19414
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/docs-site-contract.test.js +2 -2
- package/dist/scripts/__tests__/docs-site-contract.test.js.map +1 -1
- package/dist/scripts/__tests__/generated-artifact-drift.test.d.ts +2 -0
- package/dist/scripts/__tests__/generated-artifact-drift.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/generated-artifact-drift.test.js +84 -0
- package/dist/scripts/__tests__/generated-artifact-drift.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js +235 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js +188 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js +207 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js +156 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js +191 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js +40 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.js +63 -0
- package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.js +65 -0
- package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.js +189 -0
- package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.js.map +1 -0
- package/dist/scripts/__tests__/notify-state-io.test.js +26 -0
- package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-tmux-injection.test.js +23 -1
- package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -1
- package/dist/scripts/__tests__/postinstall.test.js +19 -1
- package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
- package/dist/scripts/__tests__/prompt-inventory.test.js +54 -1
- package/dist/scripts/__tests__/prompt-inventory.test.js.map +1 -1
- package/dist/scripts/__tests__/reasoning-artifact-contract.test.js +2 -2
- package/dist/scripts/__tests__/reasoning-artifact-contract.test.js.map +1 -1
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +46 -60
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -1
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +60 -25
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js +168 -20
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts +2 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.js +235 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts +51 -2
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +3648 -1332
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts +9 -0
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +33 -22
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/generate-native-release-manifest.js +80 -51
- package/dist/scripts/generate-native-release-manifest.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +28 -39
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts +2 -48
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +1 -0
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +5 -0
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +8 -5
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +32 -3
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +3 -2
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.js +23 -3
- package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +45 -5
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -0
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +4 -1
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.d.ts.map +1 -1
- package/dist/scripts/notify-hook.js +71 -124
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/postinstall-advisory.d.ts +14 -0
- package/dist/scripts/postinstall-advisory.d.ts.map +1 -0
- package/dist/scripts/postinstall-advisory.js +49 -0
- package/dist/scripts/postinstall-advisory.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +1 -1
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +1 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/scripts/prompt-inventory.d.ts +39 -0
- package/dist/scripts/prompt-inventory.d.ts.map +1 -1
- package/dist/scripts/prompt-inventory.js +108 -3
- package/dist/scripts/prompt-inventory.js.map +1 -1
- package/dist/scripts/run-compiled-ci.js +2 -0
- package/dist/scripts/run-compiled-ci.js.map +1 -1
- package/dist/scripts/run-test-files.js +1 -0
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +32 -1
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +407 -60
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
- package/dist/scripts/sync-plugin-mirror.js +16 -1
- package/dist/scripts/sync-plugin-mirror.js.map +1 -1
- package/dist/scripts/sync-prompt-guidance-fragments.js +62 -20
- package/dist/scripts/sync-prompt-guidance-fragments.js.map +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
- package/dist/scripts/tmux-hook-engine.js +3 -3
- package/dist/scripts/tmux-hook-engine.js.map +1 -1
- package/dist/scripts/verify-capabilities-lock.d.ts +3 -0
- package/dist/scripts/verify-capabilities-lock.d.ts.map +1 -0
- package/dist/scripts/verify-capabilities-lock.js +22 -0
- package/dist/scripts/verify-capabilities-lock.js.map +1 -0
- package/dist/scripts/verify-native-release-assets.js +37 -23
- package/dist/scripts/verify-native-release-assets.js.map +1 -1
- package/dist/state/__tests__/authority-decreasing.test.d.ts +2 -0
- package/dist/state/__tests__/authority-decreasing.test.d.ts.map +1 -0
- package/dist/state/__tests__/authority-decreasing.test.js +78 -0
- package/dist/state/__tests__/authority-decreasing.test.js.map +1 -0
- package/dist/state/__tests__/handoff-carrier.test.d.ts +2 -0
- package/dist/state/__tests__/handoff-carrier.test.d.ts.map +1 -0
- package/dist/state/__tests__/handoff-carrier.test.js +96 -0
- package/dist/state/__tests__/handoff-carrier.test.js.map +1 -0
- package/dist/state/__tests__/mode-state-context.test.js +12 -5
- package/dist/state/__tests__/mode-state-context.test.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +870 -2517
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/single-writer-invariant.test.d.ts +2 -0
- package/dist/state/__tests__/single-writer-invariant.test.d.ts.map +1 -0
- package/dist/state/__tests__/single-writer-invariant.test.js +342 -0
- package/dist/state/__tests__/single-writer-invariant.test.js.map +1 -0
- package/dist/state/__tests__/skill-active.test.js +400 -2
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/__tests__/stale-state-neutralization.test.d.ts +2 -0
- package/dist/state/__tests__/stale-state-neutralization.test.d.ts.map +1 -0
- package/dist/state/__tests__/stale-state-neutralization.test.js +84 -0
- package/dist/state/__tests__/stale-state-neutralization.test.js.map +1 -0
- package/dist/state/__tests__/workflow-transition.test.js +20 -33
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/handoff-carrier.d.ts +46 -0
- package/dist/state/handoff-carrier.d.ts.map +1 -0
- package/dist/state/handoff-carrier.js +85 -0
- package/dist/state/handoff-carrier.js.map +1 -0
- package/dist/state/mode-state-context.d.ts +3 -0
- package/dist/state/mode-state-context.d.ts.map +1 -1
- package/dist/state/mode-state-context.js +27 -13
- package/dist/state/mode-state-context.js.map +1 -1
- package/dist/state/namespace-owners.d.ts +34 -0
- package/dist/state/namespace-owners.d.ts.map +1 -0
- package/dist/state/namespace-owners.js +127 -0
- package/dist/state/namespace-owners.js.map +1 -0
- package/dist/state/operations.d.ts +9 -4
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +194 -235
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts +18 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +421 -31
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.d.ts +3 -0
- package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
- package/dist/state/workflow-transition-reconcile.js +11 -31
- package/dist/state/workflow-transition-reconcile.js.map +1 -1
- package/dist/state/workflow-transition.d.ts +1 -27
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +9 -790
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +27 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -1
- package/dist/subagents/__tests__/tracker.test.js +837 -1048
- package/dist/subagents/__tests__/tracker.test.js.map +1 -1
- package/dist/subagents/tracker.d.ts +64 -60
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +809 -358
- package/dist/subagents/tracker.js.map +1 -1
- package/dist/team/__tests__/api-interop.test.js +1 -0
- package/dist/team/__tests__/api-interop.test.js.map +1 -1
- package/dist/team/__tests__/delivery-e2e-smoke.test.js +6 -7
- package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
- package/dist/team/__tests__/mcp-comm.test.js +104 -3
- package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
- package/dist/team/__tests__/notice-ledger.test.d.ts +2 -0
- package/dist/team/__tests__/notice-ledger.test.d.ts.map +1 -0
- package/dist/team/__tests__/notice-ledger.test.js +131 -0
- package/dist/team/__tests__/notice-ledger.test.js.map +1 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts +2 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts.map +1 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.js +410 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.js.map +1 -0
- package/dist/team/__tests__/phase-controller.test.js +20 -0
- package/dist/team/__tests__/phase-controller.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +725 -59
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +269 -245
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +117 -2
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/team-ops-contract.test.js +1 -0
- package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +1093 -101
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts +2 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts.map +1 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.js +159 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.js.map +1 -0
- package/dist/team/__tests__/tmux-test-fixture.d.ts +69 -0
- package/dist/team/__tests__/tmux-test-fixture.d.ts.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.js +242 -15
- package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.test.js +177 -1
- package/dist/team/__tests__/tmux-test-fixture.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +11 -13
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/__tests__/worker-provenance.test.d.ts +2 -0
- package/dist/team/__tests__/worker-provenance.test.d.ts.map +1 -0
- package/dist/team/__tests__/worker-provenance.test.js +251 -0
- package/dist/team/__tests__/worker-provenance.test.js.map +1 -0
- package/dist/team/__tests__/worker-runtime-identity.test.js +45 -72
- package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +14 -8
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/mcp-comm.d.ts.map +1 -1
- package/dist/team/mcp-comm.js +3 -8
- package/dist/team/mcp-comm.js.map +1 -1
- package/dist/team/notice-ledger.d.ts +54 -0
- package/dist/team/notice-ledger.d.ts.map +1 -0
- package/dist/team/notice-ledger.js +259 -0
- package/dist/team/notice-ledger.js.map +1 -0
- package/dist/team/phase-controller.d.ts.map +1 -1
- package/dist/team/phase-controller.js +2 -0
- package/dist/team/phase-controller.js.map +1 -1
- package/dist/team/runtime.d.ts +3 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +314 -142
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +161 -91
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/monitor.d.ts +10 -0
- package/dist/team/state/monitor.d.ts.map +1 -1
- package/dist/team/state/monitor.js +13 -0
- package/dist/team/state/monitor.js.map +1 -1
- package/dist/team/state/types.d.ts +15 -0
- package/dist/team/state/types.d.ts.map +1 -1
- package/dist/team/state/types.js.map +1 -1
- package/dist/team/state-root.d.ts +12 -0
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +177 -0
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts +19 -0
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +47 -1
- package/dist/team/state.js.map +1 -1
- package/dist/team/team-ops.d.ts +1 -0
- package/dist/team/team-ops.d.ts.map +1 -1
- package/dist/team/team-ops.js +1 -0
- package/dist/team/team-ops.js.map +1 -1
- package/dist/team/tmux-session.d.ts +42 -4
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +572 -196
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/ultragoal-context.d.ts +1 -0
- package/dist/team/ultragoal-context.d.ts.map +1 -1
- package/dist/team/ultragoal-context.js +2 -0
- package/dist/team/ultragoal-context.js.map +1 -1
- package/dist/team/worker-provenance.d.ts +35 -0
- package/dist/team/worker-provenance.d.ts.map +1 -0
- package/dist/team/worker-provenance.js +213 -0
- package/dist/team/worker-provenance.js.map +1 -0
- package/dist/ultragoal/__tests__/artifacts.test.js +1053 -2
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/__tests__/docs-contract.test.js +89 -59
- package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts +36 -1
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +267 -51
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/dist/url-reader/__tests__/url-reader.test.js +14 -0
- package/dist/url-reader/__tests__/url-reader.test.js.map +1 -1
- package/dist/url-reader/index.js +5 -3
- package/dist/url-reader/index.js.map +1 -1
- package/dist/utils/__tests__/file-durability.test.js +58 -1
- package/dist/utils/__tests__/file-durability.test.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +21 -1
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/__tests__/version.test.js +17 -0
- package/dist/utils/__tests__/version.test.js.map +1 -1
- package/dist/utils/file-durability.d.ts +10 -0
- package/dist/utils/file-durability.d.ts.map +1 -1
- package/dist/utils/file-durability.js +34 -4
- package/dist/utils/file-durability.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -6
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +2 -1
- package/dist/utils/version.js.map +1 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js +49 -4
- package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js +60 -0
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
- package/dist/verification/__tests__/native-release-manifest.test.js +157 -4
- package/dist/verification/__tests__/native-release-manifest.test.js.map +1 -1
- package/package.json +17 -6
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +81 -17
- package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +60 -135
- package/plugins/oh-my-codex/skills/analyze/SKILL.md +35 -111
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +72 -163
- package/plugins/oh-my-codex/skills/cancel/SKILL.md +33 -392
- package/plugins/oh-my-codex/skills/code-review/SKILL.md +66 -256
- package/plugins/oh-my-codex/skills/configure-notifications/SKILL.md +30 -216
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +11 -10
- package/plugins/oh-my-codex/skills/design/SKILL.md +32 -132
- package/plugins/oh-my-codex/skills/doctor/SKILL.md +56 -177
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +35 -116
- package/plugins/oh-my-codex/skills/plan/SKILL.md +45 -228
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +20 -22
- package/plugins/oh-my-codex/skills/skill/SKILL.md +82 -807
- package/plugins/oh-my-codex/skills/team/SKILL.md +32 -520
- package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +47 -150
- package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +75 -252
- package/plugins/oh-my-codex/skills/visual-ralph/SKILL.md +33 -111
- package/plugins/oh-my-codex/skills/worker/SKILL.md +40 -113
- package/prompts/analyst.md +27 -107
- package/prompts/api-reviewer.md +17 -84
- package/prompts/architect.md +31 -70
- package/prompts/code-reviewer.md +18 -107
- package/prompts/code-simplifier.md +32 -110
- package/prompts/critic.md +32 -54
- package/prompts/dependency-expert.md +37 -107
- package/prompts/designer.md +40 -107
- package/prompts/executor.md +26 -75
- package/prompts/information-architect.md +51 -200
- package/prompts/performance-reviewer.md +17 -81
- package/prompts/planner.md +33 -76
- package/prompts/product-analyst.md +65 -280
- package/prompts/product-manager.md +48 -216
- package/prompts/qa-tester.md +33 -104
- package/prompts/quality-reviewer.md +17 -93
- package/prompts/quality-strategist.md +31 -255
- package/prompts/researcher.md +32 -89
- package/prompts/security-reviewer.md +12 -98
- package/prompts/test-engineer.md +29 -110
- package/prompts/ux-researcher.md +46 -300
- package/prompts/verifier.md +23 -51
- package/skills/ai-slop-cleaner/SKILL.md +60 -135
- package/skills/analyze/SKILL.md +35 -111
- package/skills/autopilot/SKILL.md +72 -163
- package/skills/autoresearch-goal/SKILL.md +6 -31
- package/skills/cancel/SKILL.md +33 -392
- package/skills/code-review/SKILL.md +66 -256
- package/skills/configure-notifications/SKILL.md +30 -216
- package/skills/deep-interview/SKILL.md +11 -10
- package/skills/design/SKILL.md +32 -132
- package/skills/doctor/SKILL.md +56 -177
- package/skills/omx-setup/SKILL.md +35 -116
- package/skills/pipeline/SKILL.md +6 -89
- package/skills/plan/SKILL.md +45 -228
- package/skills/ralph/SKILL.md +6 -290
- package/skills/ralplan/SKILL.md +20 -22
- package/skills/skill/SKILL.md +82 -807
- package/skills/team/SKILL.md +32 -520
- package/skills/ultragoal/SKILL.md +47 -150
- package/skills/ultraqa/SKILL.md +75 -252
- package/skills/ultrawork/SKILL.md +6 -182
- package/skills/visual-ralph/SKILL.md +33 -111
- package/skills/worker/SKILL.md +40 -113
- package/src/scripts/__tests__/codex-native-hook.test.ts +18888 -28799
- package/src/scripts/__tests__/docs-site-contract.test.ts +2 -2
- package/src/scripts/__tests__/generated-artifact-drift.test.ts +97 -0
- package/src/scripts/__tests__/issue-3293-callsite-parity.test.ts +197 -0
- package/src/scripts/__tests__/issue-3293-cancel-transaction.test.ts +189 -0
- package/src/scripts/__tests__/issue-3293-hook-owned-cancel.test.ts +186 -0
- package/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts +177 -0
- package/src/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.ts +201 -0
- package/src/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.ts +43 -0
- package/src/scripts/__tests__/issue-3481-conductor-deadlock.test.ts +77 -0
- package/src/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.ts +95 -0
- package/src/scripts/__tests__/issue-3536-external-team-state-root.test.ts +216 -0
- package/src/scripts/__tests__/notify-state-io.test.ts +29 -0
- package/src/scripts/__tests__/notify-tmux-injection.test.ts +26 -1
- package/src/scripts/__tests__/postinstall.test.ts +23 -1
- package/src/scripts/__tests__/prompt-inventory.test.ts +62 -1
- package/src/scripts/__tests__/reasoning-artifact-contract.test.ts +1 -2
- package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +49 -59
- package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +61 -27
- package/src/scripts/__tests__/smoke-packed-install.test.ts +223 -23
- package/src/scripts/__tests__/verify-native-release-assets.test.ts +240 -0
- package/src/scripts/codex-native-hook.ts +3618 -1383
- package/src/scripts/codex-native-pre-post.ts +50 -24
- package/src/scripts/generate-native-release-manifest.ts +83 -79
- package/src/scripts/notify-fallback-watcher.ts +38 -38
- package/src/scripts/notify-hook/auto-nudge.ts +1 -0
- package/src/scripts/notify-hook/state-io.ts +11 -0
- package/src/scripts/notify-hook/team-dispatch.ts +8 -5
- package/src/scripts/notify-hook/team-leader-nudge.ts +32 -4
- package/src/scripts/notify-hook/team-tmux-guard.ts +3 -1
- package/src/scripts/notify-hook/team-worker-stop.ts +23 -4
- package/src/scripts/notify-hook/team-worker.ts +43 -5
- package/src/scripts/notify-hook/tmux-injection.ts +5 -1
- package/src/scripts/notify-hook.ts +76 -124
- package/src/scripts/postinstall-advisory.ts +67 -0
- package/src/scripts/postinstall.ts +1 -1
- package/src/scripts/prompt-inventory.ts +142 -3
- package/src/scripts/run-compiled-ci.ts +2 -0
- package/src/scripts/run-test-files.ts +1 -0
- package/src/scripts/smoke-packed-install.ts +440 -59
- package/src/scripts/sync-plugin-mirror.ts +17 -1
- package/src/scripts/sync-prompt-guidance-fragments.ts +59 -22
- package/src/scripts/tmux-hook-engine.ts +3 -3
- package/src/scripts/verify-capabilities-lock.ts +23 -0
- package/src/scripts/verify-native-release-assets.ts +39 -31
- package/templates/AGENTS.md +45 -9
- package/templates/catalog-manifest.json +6 -146
- package/dist/autopilot/__tests__/deep-interview-gate.test.d.ts +0 -2
- package/dist/autopilot/__tests__/deep-interview-gate.test.d.ts.map +0 -1
- package/dist/autopilot/__tests__/deep-interview-gate.test.js +0 -215
- package/dist/autopilot/__tests__/deep-interview-gate.test.js.map +0 -1
- package/dist/autopilot/__tests__/ralplan-gate.test.d.ts +0 -2
- package/dist/autopilot/__tests__/ralplan-gate.test.d.ts.map +0 -1
- package/dist/autopilot/__tests__/ralplan-gate.test.js +0 -1361
- package/dist/autopilot/__tests__/ralplan-gate.test.js.map +0 -1
- package/dist/autopilot/deep-interview-gate.d.ts +0 -18
- package/dist/autopilot/deep-interview-gate.d.ts.map +0 -1
- package/dist/autopilot/deep-interview-gate.js +0 -396
- package/dist/autopilot/deep-interview-gate.js.map +0 -1
- package/dist/autopilot/ralplan-gate.d.ts +0 -18
- package/dist/autopilot/ralplan-gate.d.ts.map +0 -1
- package/dist/autopilot/ralplan-gate.js +0 -148
- package/dist/autopilot/ralplan-gate.js.map +0 -1
- package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js +0 -320
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +0 -1
- package/dist/pipeline/__tests__/orchestrator.test.d.ts +0 -2
- package/dist/pipeline/__tests__/orchestrator.test.d.ts.map +0 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +0 -770
- package/dist/pipeline/__tests__/orchestrator.test.js.map +0 -1
- package/dist/pipeline/__tests__/stages.test.d.ts +0 -2
- package/dist/pipeline/__tests__/stages.test.d.ts.map +0 -1
- package/dist/pipeline/__tests__/stages.test.js +0 -1778
- package/dist/pipeline/__tests__/stages.test.js.map +0 -1
- package/dist/pipeline/index.d.ts +0 -25
- package/dist/pipeline/index.d.ts.map +0 -1
- package/dist/pipeline/index.js +0 -17
- package/dist/pipeline/index.js.map +0 -1
- package/dist/pipeline/orchestrator.d.ts +0 -52
- package/dist/pipeline/orchestrator.d.ts.map +0 -1
- package/dist/pipeline/orchestrator.js +0 -399
- package/dist/pipeline/orchestrator.js.map +0 -1
- package/dist/pipeline/review-verdict.d.ts +0 -3
- package/dist/pipeline/review-verdict.d.ts.map +0 -1
- package/dist/pipeline/review-verdict.js +0 -14
- package/dist/pipeline/review-verdict.js.map +0 -1
- package/dist/pipeline/stages/code-review.d.ts +0 -35
- package/dist/pipeline/stages/code-review.d.ts.map +0 -1
- package/dist/pipeline/stages/code-review.js +0 -55
- package/dist/pipeline/stages/code-review.js.map +0 -1
- package/dist/pipeline/stages/deep-interview.d.ts +0 -15
- package/dist/pipeline/stages/deep-interview.d.ts.map +0 -1
- package/dist/pipeline/stages/deep-interview.js +0 -32
- package/dist/pipeline/stages/deep-interview.js.map +0 -1
- package/dist/pipeline/stages/ralph-verify.d.ts +0 -53
- package/dist/pipeline/stages/ralph-verify.d.ts.map +0 -1
- package/dist/pipeline/stages/ralph-verify.js +0 -89
- package/dist/pipeline/stages/ralph-verify.js.map +0 -1
- package/dist/pipeline/stages/ralplan.d.ts +0 -27
- package/dist/pipeline/stages/ralplan.d.ts.map +0 -1
- package/dist/pipeline/stages/ralplan.js +0 -152
- package/dist/pipeline/stages/ralplan.js.map +0 -1
- package/dist/pipeline/stages/team-exec.d.ts +0 -52
- package/dist/pipeline/stages/team-exec.d.ts.map +0 -1
- package/dist/pipeline/stages/team-exec.js +0 -266
- package/dist/pipeline/stages/team-exec.js.map +0 -1
- package/dist/pipeline/stages/ultragoal.d.ts +0 -23
- package/dist/pipeline/stages/ultragoal.d.ts.map +0 -1
- package/dist/pipeline/stages/ultragoal.js +0 -53
- package/dist/pipeline/stages/ultragoal.js.map +0 -1
- package/dist/pipeline/stages/ultraqa.d.ts +0 -33
- package/dist/pipeline/stages/ultraqa.d.ts.map +0 -1
- package/dist/pipeline/stages/ultraqa.js +0 -49
- package/dist/pipeline/stages/ultraqa.js.map +0 -1
- package/dist/pipeline/types.d.ts +0 -124
- package/dist/pipeline/types.d.ts.map +0 -1
- package/dist/pipeline/types.js +0 -8
- package/dist/pipeline/types.js.map +0 -1
- package/dist/ralplan/__tests__/consensus-gate.test.d.ts +0 -2
- package/dist/ralplan/__tests__/consensus-gate.test.d.ts.map +0 -1
- package/dist/ralplan/__tests__/consensus-gate.test.js +0 -1455
- package/dist/ralplan/__tests__/consensus-gate.test.js.map +0 -1
- package/dist/ralplan/consensus-gate.d.ts +0 -62
- package/dist/ralplan/consensus-gate.d.ts.map +0 -1
- package/dist/ralplan/consensus-gate.js +0 -760
- package/dist/ralplan/consensus-gate.js.map +0 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts +0 -25
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +0 -1
- package/dist/scripts/notify-hook/ralph-session-resume.js +0 -377
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +0 -1
- package/dist/state/__tests__/planning-gate.test.d.ts +0 -2
- package/dist/state/__tests__/planning-gate.test.d.ts.map +0 -1
- package/dist/state/__tests__/planning-gate.test.js +0 -629
- package/dist/state/__tests__/planning-gate.test.js.map +0 -1
- package/plugins/oh-my-codex/skills/autoresearch-goal/SKILL.md +0 -39
- package/plugins/oh-my-codex/skills/pipeline/SKILL.md +0 -97
- package/plugins/oh-my-codex/skills/prometheus-strict/README.md +0 -35
- package/plugins/oh-my-codex/skills/prometheus-strict/SKILL.md +0 -219
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +0 -298
- package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +0 -190
- package/plugins/oh-my-codex/skills/ultrawork/references/agent-tiers.md +0 -62
- package/prompts/prometheus-strict-metis.md +0 -274
- package/prompts/prometheus-strict-momus.md +0 -82
- package/prompts/prometheus-strict-oracle.md +0 -107
- package/prompts/scholastic.md +0 -11
- package/prompts/sisyphus-lite.md +0 -111
- package/skills/ask-claude/SKILL.md +0 -12
- package/skills/ask-gemini/SKILL.md +0 -12
- package/skills/build-fix/SKILL.md +0 -10
- package/skills/deepsearch/SKILL.md +0 -10
- package/skills/ecomode/SKILL.md +0 -114
- package/skills/ecomode/references/agent-tiers.md +0 -61
- package/skills/frontend-ui-ux/SKILL.md +0 -16
- package/skills/help/SKILL.md +0 -10
- package/skills/note/SKILL.md +0 -10
- package/skills/prometheus-strict/README.md +0 -35
- package/skills/prometheus-strict/SKILL.md +0 -219
- package/skills/ralph-init/SKILL.md +0 -10
- package/skills/review/SKILL.md +0 -10
- package/skills/security-review/SKILL.md +0 -10
- package/skills/swarm/SKILL.md +0 -12
- package/skills/tdd/SKILL.md +0 -104
- package/skills/trace/SKILL.md +0 -10
- package/skills/visual-verdict/SKILL.md +0 -10
- package/skills/web-clone/SKILL.md +0 -357
- package/src/scripts/notify-hook/ralph-session-resume.ts +0 -466
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { afterEach, describe, it, mock } from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, utimesSync } from "node:fs";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
4
5
|
import { chmod, lstat, mkdir, mkdtemp, readFile, readdir as fsReaddir, rm, stat, symlink, writeFile } from "node:fs/promises";
|
|
5
6
|
import { delimiter, dirname, join } from "node:path";
|
|
6
7
|
import { tmpdir } from "node:os";
|
|
7
8
|
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { once } from "node:events";
|
|
9
9
|
import TOML from "@iarna/toml";
|
|
10
|
-
import { HELP, normalizeCodexLaunchArgs, buildTmuxShellCommand, buildTmuxPaneCommand, shouldSourceTmuxPaneShellRc, buildWindowsPromptCommand, buildTmuxSessionName, resolveCliInvocation, parseResumeCodexHomeSelection, isResumeCodexLaunch, CODEX_GLOBAL_OPTIONS_WITH_SPLIT_VALUE, isCodexVersionRequest, resolveUpdateChannelArg, commandOwnsLocalHelp, resolveCodexLaunchPolicy, resolveEffectiveLeaderLaunchPolicyOverride, resolveEnvLaunchPolicyOverride, resolveLeaderLaunchPolicyOverride, classifyCodexExecFailure, resolveSignalExitCode, parseTmuxPaneSnapshot, findHudWatchPaneIds, buildHudPaneCleanupTargets, readTopLevelTomlString, upsertTopLevelTomlString, collectInheritableTeamWorkerArgs, resolveTeamWorkerLaunchArgsEnv, injectModelInstructionsBypassArgs, resolveWorkerSparkModel, resolveSetupInstallModeArg, resolveSetupMcpModeArg, resolveSetupScopeArg, resolveSetupTeamModeArg, resolveSetupAgentsMergePolicyArg, resolveLaunchConfigRepairOptions, readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, shouldAutoIsolateMadmaxLaunch, createMadmaxIsolatedRoot, buildMadmaxDetachedLaunchContextKey, withMadmaxDetachedContextLock, resolveOmxRootForLaunch, resolveDisposableWorktreeOmxRootForLaunch, prepareCodexHomeForLaunch, captureMadmaxWorktreeRuntimeContext, persistProjectLaunchRuntimeAuthState, persistProjectLaunchRuntimeProjectTrustState, cleanupRuntimeCodexHome, runtimeCodexHomePath, buildDetachedSessionBootstrapSteps, buildDetachedTmuxSessionName, buildDetachedSessionFinalizeSteps, shouldAttachDetachedTmuxSession, buildDetachedSessionRollbackSteps, detectDetachedSessionWindowIndex, resolveNotifyTempContract, buildNotifyTempStartupMessages, buildNotifyFallbackWatcherEnv, shouldEnableNotifyFallbackWatcher, reapStaleNotifyFallbackWatcher, cleanupLaunchOrphanedMcpProcesses, reapPostLaunchOrphanedMcpProcesses, cleanupPostLaunchModeStateFiles, resolveBackgroundHelperLaunchMode, shouldDetachBackgroundHelper, resolveNotifyFallbackWatcherScript, resolveHookDerivedWatcherScript, resolveNotifyHookScript,
|
|
10
|
+
import { HELP, normalizeCodexLaunchArgs, buildTmuxShellCommand, buildTmuxPaneCommand, shouldSourceTmuxPaneShellRc, buildWindowsPromptCommand, buildWindowsDetachedChildCommand, buildTmuxSessionName, resolveCliInvocation, parseResumeCodexHomeSelection, isResumeCodexLaunch, CODEX_GLOBAL_OPTIONS_WITH_SPLIT_VALUE, isCodexVersionRequest, resolveUpdateChannelArg, commandOwnsLocalHelp, resolveCodexLaunchPolicy, resolveEffectiveLeaderLaunchPolicyOverride, resolveEnvLaunchPolicyOverride, resolveLeaderLaunchPolicyOverride, classifyCodexExecFailure, resolveSignalExitCode, parseTmuxPaneSnapshot, findHudWatchPaneIds, buildHudPaneCleanupTargets, readTopLevelTomlString, upsertTopLevelTomlString, collectInheritableTeamWorkerArgs, resolveTeamWorkerLaunchArgsEnv, injectModelInstructionsBypassArgs, resolveWorkerSparkModel, resolveSetupInstallModeArg, resolveSetupMcpModeArg, resolveSetupScopeArg, resolveSetupTeamModeArg, resolveSetupAgentsMergePolicyArg, resolveLaunchConfigRepairOptions, readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, shouldAutoIsolateMadmaxLaunch, createMadmaxIsolatedRoot, buildMadmaxDetachedLaunchContextKey, withMadmaxDetachedContextLock, executeDetachedLaunchStateMachine, resolveOmxRootForLaunch, resolveDisposableWorktreeOmxRootForLaunch, prepareCodexHomeForLaunch, captureMadmaxWorktreeRuntimeContext, persistProjectLaunchRuntimeAuthState, persistProjectLaunchRuntimeProjectTrustState, cleanupRuntimeCodexHome, runtimeCodexHomePath, buildDetachedSessionBootstrapSteps, buildDetachedTmuxSessionName, buildDetachedSessionFinalizeSteps, shouldAttachDetachedTmuxSession, buildDetachedSessionRollbackSteps, detectDetachedSessionWindowIndex, resolveNotifyTempContract, buildNotifyTempStartupMessages, buildNotifyFallbackWatcherEnv, shouldEnableNotifyFallbackWatcher, reapStaleNotifyFallbackWatcher, cleanupLaunchOrphanedMcpProcesses, reapPostLaunchOrphanedMcpProcesses, cleanupPostLaunchModeStateFiles, resolveBackgroundHelperLaunchMode, shouldDetachBackgroundHelper, resolveNotifyFallbackWatcherScript, resolveHookDerivedWatcherScript, resolveNotifyHookScript, acquireTmuxExtendedKeysLease, resolveNativeSessionName, releaseTmuxExtendedKeysLease, withTmuxExtendedKeys, serializeDetachedSessionParentEnv, buildInsideTmuxHudHookEnv, registerInsideTmuxHudResizeHook, buildDetachedHudHookEnv, registerDetachedHudLayoutReconcileHook, ensureOmxRuntimeCommandShim, omxRuntimeCommandShimPath, prependOmxRuntimeCommandShimToEnv, CODEX_SQLITE_HOME_ENV, DETACHED_TMUX_HISTORY_LIMIT, isExistingTmuxWindowTooCrampedForLaunchHud, guardDetachedHudDeferredMutation, DETACHED_LAUNCH_CONTROL_PLANE_KEYS, buildDetachedLaunchControlPlane, } from "../index.js";
|
|
11
11
|
import { buildResumeArgsWithPreservedFlags, stripHotswapArg } from "../../auth/hotswap.js";
|
|
12
|
+
import { writeSkillActiveStateCopiesForStateDir } from '../../state/skill-active.js';
|
|
12
13
|
import { mergeConfig, repairConfigIfNeeded } from "../../config/generator.js";
|
|
13
14
|
import { ensureReusableNodeModules } from "../../utils/repo-deps.js";
|
|
14
15
|
import { readAllState } from "../../hud/state.js";
|
|
@@ -17,6 +18,7 @@ import { HUD_TMUX_HEIGHT_LINES, HUD_TMUX_MIN_LAUNCH_WINDOW_HEIGHT_LINES } from "
|
|
|
17
18
|
import { createHudWatchPane as createSharedHudWatchPane, listCurrentWindowHudPaneIds } from "../../hud/tmux.js";
|
|
18
19
|
import { DEFAULT_FRONTIER_MODEL, getTeamLowComplexityModel, } from "../../config/models.js";
|
|
19
20
|
import { splitWorkerLaunchArgs } from "../../team/model-contract.js";
|
|
21
|
+
import { buildRegisterResizeHookArgs } from "../../team/tmux-session.js";
|
|
20
22
|
const testDir = dirname(fileURLToPath(import.meta.url));
|
|
21
23
|
const repoRoot = join(testDir, "..", "..", "..");
|
|
22
24
|
function normalizeDarwinTmpPath(value) {
|
|
@@ -67,6 +69,7 @@ describe("madmax state isolation", () => {
|
|
|
67
69
|
const runDir = createMadmaxIsolatedRoot(wd, ["--madmax", "--high"], env);
|
|
68
70
|
env.OMX_ROOT = runDir;
|
|
69
71
|
env.OMXBOX_ACTIVE = "1";
|
|
72
|
+
env.OMX_SOURCE_CWD = wd;
|
|
70
73
|
assert.equal(shouldAutoIsolateMadmaxLaunch("launch", ["--madmax", "--high"], env, wd), false);
|
|
71
74
|
assert.equal(shouldAutoIsolateMadmaxLaunch("launch", ["--madmax", "--xhigh"], env, wd), true, "changed launch semantics must not reuse an inherited boxed root");
|
|
72
75
|
}
|
|
@@ -78,29 +81,40 @@ describe("madmax state isolation", () => {
|
|
|
78
81
|
it("preserves explicit no-box behavior", () => {
|
|
79
82
|
assert.equal(shouldAutoIsolateMadmaxLaunch("launch", ["--madmax"], { OMX_NO_BOX: "1" }, "/repo"), false);
|
|
80
83
|
});
|
|
81
|
-
it("captures madmax worktree context from parsed worktree state, not remaining args", () => {
|
|
84
|
+
it("captures madmax worktree context from parsed worktree state, not remaining args", async () => {
|
|
82
85
|
const sourceCwd = "/repo/source";
|
|
83
86
|
const worktreeCwd = "/repo/.worktrees/session";
|
|
84
|
-
const runDir = "
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
87
|
+
const runDir = await mkdtemp(join(tmpdir(), "omx-run-issue-3043-"));
|
|
88
|
+
try {
|
|
89
|
+
const detachedContext = buildMadmaxDetachedLaunchContextKey(sourceCwd, ["--madmax", "--worktree", "--version"], runDir);
|
|
90
|
+
await writeFile(join(runDir, ".omxbox-run.json"), JSON.stringify({
|
|
91
|
+
cwd: runDir,
|
|
92
|
+
source_cwd: sourceCwd,
|
|
93
|
+
detached_launch_context: detachedContext,
|
|
94
|
+
}));
|
|
95
|
+
const context = captureMadmaxWorktreeRuntimeContext({
|
|
96
|
+
originalLaunchArgs: ["--madmax", "--worktree", "--version"],
|
|
97
|
+
worktreeEnabled: true,
|
|
98
|
+
sourceCwd,
|
|
99
|
+
worktreeCwd,
|
|
100
|
+
env: {
|
|
101
|
+
OMX_ROOT: runDir,
|
|
102
|
+
OMXBOX_ACTIVE: "1",
|
|
103
|
+
OMX_SOURCE_CWD: sourceCwd,
|
|
104
|
+
OMX_MADMAX_DETACHED_CONTEXT: detachedContext,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
assert.deepEqual(context, {
|
|
108
|
+
omxRoot: runDir,
|
|
109
|
+
sourceCwd,
|
|
110
|
+
worktreeCwd,
|
|
111
|
+
madmaxDetachedContext: detachedContext,
|
|
112
|
+
boxedActive: true,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
await rm(runDir, { recursive: true, force: true });
|
|
117
|
+
}
|
|
104
118
|
});
|
|
105
119
|
it("does not capture ordinary worktree or unboxed madmax launches", () => {
|
|
106
120
|
assert.equal(captureMadmaxWorktreeRuntimeContext({
|
|
@@ -196,7 +210,7 @@ describe("madmax state isolation", () => {
|
|
|
196
210
|
mkdirSync(lockPath, { recursive: true });
|
|
197
211
|
await writeFile(join(lockPath, "pid"), "2147483647");
|
|
198
212
|
let ran = false;
|
|
199
|
-
const result = withMadmaxDetachedContextLock(runs, contextKey, () => {
|
|
213
|
+
const result = await withMadmaxDetachedContextLock(runs, contextKey, () => {
|
|
200
214
|
ran = true;
|
|
201
215
|
return "acquired";
|
|
202
216
|
}, { maxAttempts: 2, retryMs: 0 });
|
|
@@ -221,7 +235,7 @@ describe("madmax state isolation", () => {
|
|
|
221
235
|
acquired_at: new Date().toISOString(),
|
|
222
236
|
})}\n`);
|
|
223
237
|
await writeFile(join(lockPath, "pid"), String(process.pid));
|
|
224
|
-
assert.
|
|
238
|
+
await assert.rejects(() => withMadmaxDetachedContextLock(runs, contextKey, () => "should-not-run", { maxAttempts: 1, retryMs: 0 }), (err) => {
|
|
225
239
|
assert.ok(err instanceof Error);
|
|
226
240
|
assert.match(err.message, /timed out waiting for madmax detached launch context lock/);
|
|
227
241
|
assert.match(err.message, new RegExp(`holder pid ${process.pid} is still running`));
|
|
@@ -238,6 +252,135 @@ describe("madmax state isolation", () => {
|
|
|
238
252
|
}
|
|
239
253
|
});
|
|
240
254
|
});
|
|
255
|
+
describe("detached launch state machine", () => {
|
|
256
|
+
function createDependencies(events, failAt) {
|
|
257
|
+
const step = async (name) => {
|
|
258
|
+
events.push(name);
|
|
259
|
+
if (failAt === name)
|
|
260
|
+
throw new Error(name);
|
|
261
|
+
};
|
|
262
|
+
return {
|
|
263
|
+
establish: async () => { await step("D1"); return "binding"; },
|
|
264
|
+
complete: async () => { await step("D2"); return { kind: "success" }; },
|
|
265
|
+
createInertSession: async () => { await step("D3"); return "inert"; },
|
|
266
|
+
capturePane: async () => { await step("D4"); return "%1"; },
|
|
267
|
+
updateNameMetadata: async () => { await step("D5"); return "committed-released"; },
|
|
268
|
+
updatePaneMetadata: async () => { await step("D6"); return "committed-released"; },
|
|
269
|
+
publishActiveRecord: async () => {
|
|
270
|
+
await step("D7");
|
|
271
|
+
return { bytes: "record", digest: "digest", nonce: "nonce" };
|
|
272
|
+
},
|
|
273
|
+
finalizeSetupFailure: async () => { await step("finalize-setup-failure"); },
|
|
274
|
+
releaseBarrier: async () => { await step("D9"); },
|
|
275
|
+
abortAndAwaitFinalization: async () => ({
|
|
276
|
+
acknowledged: true,
|
|
277
|
+
nonce: "nonce",
|
|
278
|
+
sessionId: "session",
|
|
279
|
+
sessionName: "session-name",
|
|
280
|
+
leaderPid: 123,
|
|
281
|
+
kind: "failed",
|
|
282
|
+
}),
|
|
283
|
+
attachOrReturn: async () => { await step("D10"); },
|
|
284
|
+
rollback: async () => { events.push("rollback"); },
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
it("uses the frozen D0 outcome without rediscovering transport or reuse", async () => {
|
|
288
|
+
const events = [];
|
|
289
|
+
const result = await executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, createDependencies(events));
|
|
290
|
+
assert.equal(result.kind, "attached");
|
|
291
|
+
assert.deepEqual(events, ["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D9", "D10"]);
|
|
292
|
+
});
|
|
293
|
+
for (const platform of ["posix", "native-windows"]) {
|
|
294
|
+
it(`${platform}: releases only after atomic record and starts exactly once`, async () => {
|
|
295
|
+
const events = [];
|
|
296
|
+
const result = await executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: platform === "posix", report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, createDependencies(events));
|
|
297
|
+
assert.equal(result.kind, platform === "posix" ? "attached" : "returned");
|
|
298
|
+
assert.deepEqual(events, ["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D9", "D10"]);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
for (const failure of ["D1", "D2", "D3", "D4", "D5", "D6", "D7"]) {
|
|
302
|
+
it(`rolls back verified pre-release ownership when ${failure} fails`, async () => {
|
|
303
|
+
const events = [];
|
|
304
|
+
await assert.rejects(executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, createDependencies(events, failure)), (err) => {
|
|
305
|
+
assert.ok(err instanceof Error);
|
|
306
|
+
assert.equal(err.report?.transitions.at(-1), failure);
|
|
307
|
+
return true;
|
|
308
|
+
});
|
|
309
|
+
assert.ok(events.includes("rollback"));
|
|
310
|
+
assert.equal(events.includes("D10"), false);
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
it("finalizes and closes exactly once before D2 rollback without transport effects", async () => {
|
|
314
|
+
const events = [];
|
|
315
|
+
const deps = createDependencies(events);
|
|
316
|
+
deps.complete = async () => {
|
|
317
|
+
events.push("D2");
|
|
318
|
+
return { kind: "failure", operation: "session-instructions", error: new Error("instructions") };
|
|
319
|
+
};
|
|
320
|
+
await assert.rejects(() => executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, deps), /preLaunch session-instructions failed: instructions/);
|
|
321
|
+
assert.deepEqual(events, ["D1", "D2", "finalize-setup-failure", "rollback"]);
|
|
322
|
+
});
|
|
323
|
+
it("rolls back proven pane authority when leader parsing fails before a report PID", async () => {
|
|
324
|
+
const events = [];
|
|
325
|
+
const deps = createDependencies(events, "D2");
|
|
326
|
+
deps.abortAndAwaitFinalization = async () => ({ acknowledged: false, rollbackAuthorized: true });
|
|
327
|
+
await assert.rejects(executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, deps));
|
|
328
|
+
assert.equal(events.includes("rollback"), true);
|
|
329
|
+
});
|
|
330
|
+
it("never rolls back, deletes records, or falls back after D10 attach failure", async () => {
|
|
331
|
+
const events = [];
|
|
332
|
+
await assert.rejects(executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, createDependencies(events, "D10")), (err) => {
|
|
333
|
+
assert.ok(err instanceof Error);
|
|
334
|
+
assert.equal(err.report?.transitions.at(-1), "D10");
|
|
335
|
+
return true;
|
|
336
|
+
});
|
|
337
|
+
assert.equal(events.includes("rollback"), false);
|
|
338
|
+
assert.deepEqual(events.slice(-2), ["D9", "D10"]);
|
|
339
|
+
});
|
|
340
|
+
it("preserves leader authority when D9 publication fails without an authenticated finalization acknowledgement", async () => {
|
|
341
|
+
const events = [];
|
|
342
|
+
const deps = createDependencies(events, "D9");
|
|
343
|
+
deps.abortAndAwaitFinalization = async () => {
|
|
344
|
+
events.push("abort-request");
|
|
345
|
+
return { acknowledged: false };
|
|
346
|
+
};
|
|
347
|
+
await assert.rejects(() => executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, deps));
|
|
348
|
+
assert.deepEqual(events.slice(-2), ["D9", "abort-request"]);
|
|
349
|
+
assert.equal(events.includes("rollback"), false);
|
|
350
|
+
});
|
|
351
|
+
it("permits rollback only after an authenticated D9 abort acknowledgement", async () => {
|
|
352
|
+
const events = [];
|
|
353
|
+
const deps = createDependencies(events, "D9");
|
|
354
|
+
deps.abortAndAwaitFinalization = async () => ({
|
|
355
|
+
acknowledged: true,
|
|
356
|
+
nonce: "nonce",
|
|
357
|
+
sessionId: "session",
|
|
358
|
+
sessionName: "session-name",
|
|
359
|
+
leaderPid: 123,
|
|
360
|
+
kind: "failed",
|
|
361
|
+
});
|
|
362
|
+
await assert.rejects(() => executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, deps));
|
|
363
|
+
assert.equal(events.includes("rollback"), true);
|
|
364
|
+
});
|
|
365
|
+
it("fails closed when a purported D9 acknowledgement omits its finalized authority binding", async () => {
|
|
366
|
+
const events = [];
|
|
367
|
+
const deps = createDependencies(events, "D9");
|
|
368
|
+
deps.abortAndAwaitFinalization = async () => ({ acknowledged: true });
|
|
369
|
+
await assert.rejects(() => executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, deps));
|
|
370
|
+
assert.equal(events.includes("rollback"), false);
|
|
371
|
+
});
|
|
372
|
+
it("preserves the authority-owning leader on a pre-D9 failure without finalized acknowledgement", async () => {
|
|
373
|
+
const events = [];
|
|
374
|
+
const deps = createDependencies(events, "D4");
|
|
375
|
+
deps.abortAndAwaitFinalization = async () => {
|
|
376
|
+
events.push("abort-request");
|
|
377
|
+
return { acknowledged: false };
|
|
378
|
+
};
|
|
379
|
+
await assert.rejects(() => executeDetachedLaunchStateMachine({ preflight: { kind: "available", shouldAttach: true, report: { transitions: ["D0"], rollback: { attempted: [], failures: [] } } } }, deps));
|
|
380
|
+
assert.deepEqual(events.slice(-2), ["D4", "abort-request"]);
|
|
381
|
+
assert.equal(events.includes("rollback"), false);
|
|
382
|
+
});
|
|
383
|
+
});
|
|
241
384
|
describe("resolveOmxRootForLaunch", () => {
|
|
242
385
|
it("preserves POSIX absolute OMX_ROOT", () => {
|
|
243
386
|
assert.equal(resolveOmxRootForLaunch("/repo", { OMX_ROOT: "/var/tmp/omx" }), "/var/tmp/omx");
|
|
@@ -850,6 +993,81 @@ describe("cleanupPostLaunchModeStateFiles", () => {
|
|
|
850
993
|
}
|
|
851
994
|
assert.deepEqual(warnings, []);
|
|
852
995
|
});
|
|
996
|
+
it('routes root skill-active cleanup through the locked root writer', async () => {
|
|
997
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-postlaunch-root-writer-'));
|
|
998
|
+
const sessionId = 'sess-root-writer';
|
|
999
|
+
const stateDir = join(wd, '.omx', 'state');
|
|
1000
|
+
const rootState = {
|
|
1001
|
+
version: 1,
|
|
1002
|
+
active: true,
|
|
1003
|
+
skill: 'ralph',
|
|
1004
|
+
session_id: sessionId,
|
|
1005
|
+
active_skills: [{ skill: 'ralph', phase: 'executing', active: true, session_id: sessionId }],
|
|
1006
|
+
};
|
|
1007
|
+
await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
|
|
1008
|
+
await writeFile(join(stateDir, 'skill-active-state.json'), `${JSON.stringify(rootState, null, 2)}\n`, 'utf8');
|
|
1009
|
+
let writerCalls = 0;
|
|
1010
|
+
await cleanupPostLaunchModeStateFiles(wd, sessionId, {
|
|
1011
|
+
writeRootState: async (rootDir, update) => {
|
|
1012
|
+
writerCalls += 1;
|
|
1013
|
+
const concurrentRoot = {
|
|
1014
|
+
...rootState,
|
|
1015
|
+
active_skills: [
|
|
1016
|
+
...rootState.active_skills,
|
|
1017
|
+
{ skill: 'team', phase: 'running', active: true, session_id: 'sess-concurrent' },
|
|
1018
|
+
],
|
|
1019
|
+
};
|
|
1020
|
+
const nextState = update(concurrentRoot);
|
|
1021
|
+
assert.ok(nextState);
|
|
1022
|
+
await writeSkillActiveStateCopiesForStateDir(rootDir, nextState);
|
|
1023
|
+
},
|
|
1024
|
+
});
|
|
1025
|
+
assert.equal(writerCalls, 1);
|
|
1026
|
+
const persisted = JSON.parse(await readFile(join(stateDir, 'skill-active-state.json'), 'utf8'));
|
|
1027
|
+
assert.equal(persisted.active, true);
|
|
1028
|
+
assert.deepEqual(persisted.active_skills, [{ skill: 'team', phase: 'running', active: true, session_id: 'sess-concurrent' }]);
|
|
1029
|
+
});
|
|
1030
|
+
it('preserves a process-level session update before root scrub cleanup', async () => {
|
|
1031
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-postlaunch-process-scrub-'));
|
|
1032
|
+
const sessionId = 'sess-process-scrub';
|
|
1033
|
+
const stateDir = join(wd, '.omx', 'state');
|
|
1034
|
+
const rootPath = join(stateDir, 'skill-active-state.json');
|
|
1035
|
+
const rootState = {
|
|
1036
|
+
version: 1,
|
|
1037
|
+
active: true,
|
|
1038
|
+
skill: 'ralph',
|
|
1039
|
+
session_id: sessionId,
|
|
1040
|
+
active_skills: [{ skill: 'ralph', phase: 'executing', active: true, session_id: sessionId }],
|
|
1041
|
+
};
|
|
1042
|
+
try {
|
|
1043
|
+
await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
|
|
1044
|
+
await writeFile(rootPath, `${JSON.stringify(rootState, null, 2)}\n`, 'utf8');
|
|
1045
|
+
const updateScript = `
|
|
1046
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
1047
|
+
import { writeSkillActiveStateCopiesForStateDir } from './dist/state/skill-active.js';
|
|
1048
|
+
const stateDir = process.env.STATE_DIR;
|
|
1049
|
+
const current = JSON.parse(await readFile(process.env.ROOT_PATH, 'utf8'));
|
|
1050
|
+
current.active_skills.push({ skill: 'team', phase: 'running', active: true, session_id: 'sess-process-concurrent' });
|
|
1051
|
+
await writeSkillActiveStateCopiesForStateDir(stateDir, current, undefined, current);
|
|
1052
|
+
`;
|
|
1053
|
+
const update = spawnSync(process.execPath, ['--input-type=module', '-e', updateScript], {
|
|
1054
|
+
cwd: repoRoot,
|
|
1055
|
+
env: { ...process.env, STATE_DIR: stateDir, ROOT_PATH: rootPath },
|
|
1056
|
+
encoding: 'utf8',
|
|
1057
|
+
});
|
|
1058
|
+
assert.equal(update.status, 0, update.stderr);
|
|
1059
|
+
const scrub = spawnSync(process.execPath, ['--input-type=module', '-e', `
|
|
1060
|
+
import { cleanupPostLaunchModeStateFiles } from './dist/cli/index.js';
|
|
1061
|
+
await cleanupPostLaunchModeStateFiles(${JSON.stringify(wd)}, ${JSON.stringify(sessionId)});
|
|
1062
|
+
`], { cwd: repoRoot, env: { ...process.env }, encoding: 'utf8' });
|
|
1063
|
+
assert.equal(scrub.status, 0, scrub.stderr);
|
|
1064
|
+
const persisted = JSON.parse(await readFile(rootPath, 'utf8'));
|
|
1065
|
+
assert.deepEqual(persisted.active_skills, [{ skill: 'team', phase: 'running', active: true, session_id: 'sess-process-concurrent' }]);
|
|
1066
|
+
}
|
|
1067
|
+
finally {
|
|
1068
|
+
await rm(wd, { recursive: true, force: true });
|
|
1069
|
+
}
|
|
1070
|
+
});
|
|
853
1071
|
it("normalizes stale terminal deep-interview locks during postLaunch cleanup", async () => {
|
|
854
1072
|
const wd = await mkdtemp(join(tmpdir(), "omx-postlaunch-di-terminal-locks-"));
|
|
855
1073
|
const sessionId = "sess-postlaunch-di-terminal-locks";
|
|
@@ -1532,6 +1750,10 @@ describe("resolveCliInvocation", () => {
|
|
|
1532
1750
|
assert.match(HELP, /omx update --stable\s+Install\/rollback to npm stable \(oh-my-codex@latest\), then refresh setup/);
|
|
1533
1751
|
assert.match(HELP, /omx update --dev\s+Install the upstream dev branch, then refresh setup/);
|
|
1534
1752
|
});
|
|
1753
|
+
it("scopes Ralplan authority preflight in top-level help", () => {
|
|
1754
|
+
assert.match(HELP, /omx ralplan\s+Adapted Ralplan authority support; preflight applies only when native role routing is unavailable\s+and adapted Ralplan authority is requested/);
|
|
1755
|
+
assert.doesNotMatch(HELP, /Record validated role intents/);
|
|
1756
|
+
});
|
|
1535
1757
|
it("advertises only the four supported root reasoning modes", () => {
|
|
1536
1758
|
assert.match(HELP, /omx reasoning Show or set model reasoning effort \(low\|medium\|high\|xhigh\)/);
|
|
1537
1759
|
assert.match(HELP, /--high\s+Launch Codex with high reasoning effort/);
|
|
@@ -2231,6 +2453,47 @@ describe("project launch scope helpers", () => {
|
|
|
2231
2453
|
await rm(wd, { recursive: true, force: true });
|
|
2232
2454
|
}
|
|
2233
2455
|
});
|
|
2456
|
+
it("walks upward to find a project-scoped setup for launch resolution", async () => {
|
|
2457
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-launch-scope-"));
|
|
2458
|
+
try {
|
|
2459
|
+
await mkdir(join(wd, ".omx"), { recursive: true });
|
|
2460
|
+
await writeFile(join(wd, ".omx", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
2461
|
+
const nested = join(wd, "packages", "app", "src");
|
|
2462
|
+
await mkdir(nested, { recursive: true });
|
|
2463
|
+
assert.equal(resolveCodexHomeForLaunch(nested, {}), join(wd, ".codex"));
|
|
2464
|
+
assert.equal(resolveCodexConfigPathForLaunch(nested, {}), join(wd, ".codex", "config.toml"));
|
|
2465
|
+
}
|
|
2466
|
+
finally {
|
|
2467
|
+
await rm(wd, { recursive: true, force: true });
|
|
2468
|
+
}
|
|
2469
|
+
});
|
|
2470
|
+
it("does not redirect a launch outside any setup root into project CODEX_HOME", async () => {
|
|
2471
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-launch-scope-"));
|
|
2472
|
+
try {
|
|
2473
|
+
await mkdir(join(wd, ".omx"), { recursive: true });
|
|
2474
|
+
await writeFile(join(wd, ".omx", "setup-scope.json"), JSON.stringify({ scope: "project" }));
|
|
2475
|
+
const outside = join(wd, "..", `outside-${Date.now()}`);
|
|
2476
|
+
await mkdir(outside, { recursive: true });
|
|
2477
|
+
assert.equal(resolveCodexHomeForLaunch(outside, {}), undefined);
|
|
2478
|
+
}
|
|
2479
|
+
finally {
|
|
2480
|
+
await rm(wd, { recursive: true, force: true });
|
|
2481
|
+
}
|
|
2482
|
+
});
|
|
2483
|
+
it("keeps a user-scope setup on the user config when launching from a subdirectory", async () => {
|
|
2484
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-launch-scope-"));
|
|
2485
|
+
try {
|
|
2486
|
+
await mkdir(join(wd, ".omx"), { recursive: true });
|
|
2487
|
+
await writeFile(join(wd, ".omx", "setup-scope.json"), JSON.stringify({ scope: "user" }));
|
|
2488
|
+
const nested = join(wd, "sub");
|
|
2489
|
+
await mkdir(nested, { recursive: true });
|
|
2490
|
+
assert.equal(resolveCodexHomeForLaunch(nested, {}), undefined);
|
|
2491
|
+
assert.equal(resolveProjectLocalCodexHomeForLaunch(nested, {}), undefined);
|
|
2492
|
+
}
|
|
2493
|
+
finally {
|
|
2494
|
+
await rm(wd, { recursive: true, force: true });
|
|
2495
|
+
}
|
|
2496
|
+
});
|
|
2234
2497
|
});
|
|
2235
2498
|
describe("pointer launch aborts", () => {
|
|
2236
2499
|
it("does not launch, tag, or retain a runtime home when a pointer lock is held", async () => {
|
|
@@ -2320,7 +2583,7 @@ describe("pointer launch aborts", () => {
|
|
|
2320
2583
|
},
|
|
2321
2584
|
});
|
|
2322
2585
|
assert.equal(result.status, 1, result.stderr || result.stdout);
|
|
2323
|
-
assert.match(result.stderr, /
|
|
2586
|
+
assert.match(result.stderr, /Unable to establish launch directory capability/);
|
|
2324
2587
|
assert.equal(existsSync(codexLog), false);
|
|
2325
2588
|
assert.equal(existsSync(tmuxLog), false);
|
|
2326
2589
|
assert.equal(existsSync(join(wd, ".omx", "state", "sessions")), false);
|
|
@@ -2455,20 +2718,23 @@ describe("tmux HUD pane helpers", () => {
|
|
|
2455
2718
|
it("buildHudPaneCleanupTargets is a no-op guard when leaderPaneId is absent", () => {
|
|
2456
2719
|
assert.deepEqual(buildHudPaneCleanupTargets(["%3"], "%4"), ["%3", "%4"]);
|
|
2457
2720
|
});
|
|
2458
|
-
it("listCurrentWindowHudPaneIds
|
|
2721
|
+
it("listCurrentWindowHudPaneIds excludes snapshots without complete current ownership", () => {
|
|
2459
2722
|
const calls = [];
|
|
2460
|
-
const panes = listCurrentWindowHudPaneIds("%
|
|
2723
|
+
const panes = listCurrentWindowHudPaneIds("%1", (args) => {
|
|
2461
2724
|
calls.push(args);
|
|
2725
|
+
if (args.at(-1) === "#{pane_id}")
|
|
2726
|
+
return "%1\n%2\n";
|
|
2462
2727
|
return [
|
|
2463
|
-
"%
|
|
2464
|
-
"%
|
|
2728
|
+
"%1\x1fcodex\x1f0\x1f0\x1f100\x1f40\x1f39\x1f100\x1f40\x1fcodex\x1f/repo\x1f0\x1f101",
|
|
2729
|
+
"%2\x1fnode\x1f0\x1f40\x1f100\x1f3\x1f42\x1f100\x1f43\x1fexec env OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%1' node /tmp/bin/dist/cli/omx.js hud --watch\x1f/repo\x1f0\x1f202",
|
|
2465
2730
|
].join("\n");
|
|
2466
2731
|
});
|
|
2467
|
-
assert.deepEqual(panes, [
|
|
2468
|
-
assert.deepEqual(calls[0], [
|
|
2732
|
+
assert.deepEqual(panes, []);
|
|
2733
|
+
assert.deepEqual(calls[0], ["list-panes", "-t", "%1", "-F", "#{pane_id}"]);
|
|
2734
|
+
assert.deepEqual(calls[1], [
|
|
2469
2735
|
"list-panes",
|
|
2470
2736
|
"-t",
|
|
2471
|
-
"%
|
|
2737
|
+
"%1",
|
|
2472
2738
|
"-F",
|
|
2473
2739
|
[
|
|
2474
2740
|
"#{pane_id}",
|
|
@@ -2482,31 +2748,67 @@ describe("tmux HUD pane helpers", () => {
|
|
|
2482
2748
|
"#{window_height}",
|
|
2483
2749
|
"#{pane_start_command}",
|
|
2484
2750
|
"#{pane_current_path}",
|
|
2751
|
+
"#{pane_dead}",
|
|
2752
|
+
"#{pane_pid}",
|
|
2485
2753
|
].join("\x1f"),
|
|
2486
2754
|
]);
|
|
2487
2755
|
});
|
|
2488
|
-
it("createHudWatchPane
|
|
2756
|
+
it("createHudWatchPane rejects an incomplete synthetic source incarnation", () => {
|
|
2489
2757
|
const calls = [];
|
|
2490
|
-
const
|
|
2758
|
+
const options = new Map();
|
|
2759
|
+
let splitCreated = false;
|
|
2760
|
+
let splitMarker = "";
|
|
2761
|
+
const paneId = createSharedHudWatchPane("/repo", "node /repo/dist/cli/omx.js hud --watch", { heightLines: 3, targetPaneId: "%1" }, (args) => {
|
|
2491
2762
|
calls.push(args);
|
|
2492
|
-
|
|
2763
|
+
if (args[0] === "display-message") {
|
|
2764
|
+
const format = args.at(-1);
|
|
2765
|
+
if (format === "#{pane_id}\t#{pane_dead}\t#{pane_pid}\t#{session_id}\t#{window_id}") {
|
|
2766
|
+
return "%1\t0\t101\t$7\t@1";
|
|
2767
|
+
}
|
|
2768
|
+
if (format === "#{session_id}\t#{window_id}")
|
|
2769
|
+
return "$7\t@1";
|
|
2770
|
+
}
|
|
2771
|
+
if (args[0] === "list-panes") {
|
|
2772
|
+
const format = args.at(-1);
|
|
2773
|
+
const panes = splitCreated ? ["%1", "%2"] : ["%1"];
|
|
2774
|
+
if (format === "#{pane_id}")
|
|
2775
|
+
return `${panes.join("\n")}\n`;
|
|
2776
|
+
if (format === "#{pane_id}\t#{pane_start_command}") {
|
|
2777
|
+
return [
|
|
2778
|
+
"%1\tcodex",
|
|
2779
|
+
`%2\tOMX_TMUX_SPLIT_OPERATION_MARKER='${splitMarker}'; export OMX_TMUX_SPLIT_OPERATION_MARKER; exec env OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%1' node /repo/dist/cli/omx.js hud --watch`,
|
|
2780
|
+
].join("\n");
|
|
2781
|
+
}
|
|
2782
|
+
if (format === "#{pane_id}\t#{pane_dead}\t#{pane_pid}") {
|
|
2783
|
+
return "%1\t0\t101\n%2\t0\t202\n";
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
if (args[0] === "set-option") {
|
|
2787
|
+
options.set(args[2], args[3]);
|
|
2788
|
+
return "";
|
|
2789
|
+
}
|
|
2790
|
+
if (args[0] === "show-options")
|
|
2791
|
+
return `${options.get(args.at(-1)) ?? ""}\n`;
|
|
2792
|
+
if (args[0] === "if-shell") {
|
|
2793
|
+
assert.equal(args[1], "-F");
|
|
2794
|
+
assert.equal(args[2], "-t");
|
|
2795
|
+
assert.equal(args[3], "%1");
|
|
2796
|
+
assert.match(args[4], /#\{pane_id\},%1/);
|
|
2797
|
+
assert.match(args[4], /#\{pane_pid\},101/);
|
|
2798
|
+
assert.match(args[4], /#\{session_id\},\$1/);
|
|
2799
|
+
assert.match(args[4], /#\{window_id\},@1/);
|
|
2800
|
+
splitCreated = true;
|
|
2801
|
+
const marker = /OMX_TMUX_SPLIT_OPERATION_MARKER='([\w-]+)'/.exec(args[5]);
|
|
2802
|
+
const receipt = /display-message -p (__omx_hud_split_[\w-]+)/.exec(args[5]);
|
|
2803
|
+
assert.ok(marker, "guarded split must bind an operation marker");
|
|
2804
|
+
assert.ok(receipt, "guarded split must emit an exact receipt");
|
|
2805
|
+
splitMarker = marker[1];
|
|
2806
|
+
return `${receipt[1]}\n`;
|
|
2807
|
+
}
|
|
2808
|
+
throw new Error(`unexpected tmux command: ${args.join(" ")}`);
|
|
2493
2809
|
});
|
|
2494
|
-
assert.equal(paneId,
|
|
2495
|
-
assert.
|
|
2496
|
-
"split-window",
|
|
2497
|
-
"-v",
|
|
2498
|
-
"-l",
|
|
2499
|
-
"3",
|
|
2500
|
-
"-d",
|
|
2501
|
-
"-t",
|
|
2502
|
-
"%leader",
|
|
2503
|
-
"-c",
|
|
2504
|
-
"/repo",
|
|
2505
|
-
"-P",
|
|
2506
|
-
"-F",
|
|
2507
|
-
"#{pane_id}",
|
|
2508
|
-
"node /repo/dist/cli/omx.js hud --watch",
|
|
2509
|
-
]);
|
|
2810
|
+
assert.equal(paneId, null);
|
|
2811
|
+
assert.equal(calls.some((args) => args[0] === "if-shell"), false);
|
|
2510
2812
|
});
|
|
2511
2813
|
});
|
|
2512
2814
|
describe("detached tmux new-session sequencing", () => {
|
|
@@ -2575,7 +2877,7 @@ describe("detached tmux new-session sequencing", () => {
|
|
|
2575
2877
|
assert.equal(newSession.args.includes("-e") &&
|
|
2576
2878
|
newSession.args.some((arg) => arg === "OMX_ROOT=/tmp/omx-root"), true);
|
|
2577
2879
|
});
|
|
2578
|
-
it("
|
|
2880
|
+
it("clears unverified boxed env from detached tmux sessions", () => {
|
|
2579
2881
|
const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/boxed-runtime", "'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null, undefined, null, false, "sess-detached-managed", undefined, undefined, "/tmp/boxed-runtime", {
|
|
2580
2882
|
OMXBOX_ACTIVE: "1",
|
|
2581
2883
|
OMX_SOURCE_CWD: "/tmp/source-project",
|
|
@@ -2583,11 +2885,11 @@ describe("detached tmux new-session sequencing", () => {
|
|
|
2583
2885
|
});
|
|
2584
2886
|
const newSession = steps.find((step) => step.name === "new-session");
|
|
2585
2887
|
assert.ok(newSession);
|
|
2586
|
-
assert.equal(newSession.args.some((arg) => arg === "OMX_ROOT=/tmp/boxed-runtime"),
|
|
2888
|
+
assert.equal(newSession.args.some((arg) => arg === "OMX_ROOT=/tmp/boxed-runtime"), false);
|
|
2587
2889
|
assert.equal(newSession.args.some((arg) => arg === "OMX_STATE_ROOT=/tmp/boxed-state-root"), false);
|
|
2588
2890
|
assert.equal(newSession.args.some((arg) => arg === "OMX_TMUX_HUD_OWNER=1"), true);
|
|
2589
|
-
assert.equal(newSession.args.some((arg) => arg === "OMXBOX_ACTIVE=1"),
|
|
2590
|
-
assert.equal(newSession.args.some((arg) => arg === "OMX_SOURCE_CWD=/tmp/source-project"),
|
|
2891
|
+
assert.equal(newSession.args.some((arg) => arg === "OMXBOX_ACTIVE=1"), false);
|
|
2892
|
+
assert.equal(newSession.args.some((arg) => arg === "OMX_SOURCE_CWD=/tmp/source-project"), false);
|
|
2591
2893
|
});
|
|
2592
2894
|
it("buildDetachedSessionBootstrapSteps preserves OMX_STATE_ROOT identity when no root override is explicit", () => {
|
|
2593
2895
|
const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null, undefined, null, false, "sess-detached-managed", undefined, undefined, "/tmp/state-root", { OMX_STATE_ROOT: "/tmp/state-root" });
|
|
@@ -2879,13 +3181,15 @@ exit 0
|
|
|
2879
3181
|
it("runCodex builds inside-tmux HUD command through explicit runtime-root resolver", async () => {
|
|
2880
3182
|
const source = await readFile(join(repoRoot, 'src', 'cli', 'index.ts'), 'utf-8');
|
|
2881
3183
|
assert.match(source, /const hudRuntimeRoot: HudRuntimeRootForLaunch = runtimeContext\s*\? \{ omxRoot: runtimeContext\.omxRoot, rootSource: 'omx-root-env' \}\s*: resolveHudRuntimeRootForLaunch\(cwd, process\.env\);/);
|
|
2882
|
-
assert.match(source, /const hudRuntimeEnv = \
|
|
2883
|
-
assert.match(source, /
|
|
3184
|
+
assert.match(source, /const hudRuntimeEnv = launchOwnedControlPlane\s*\? Object\.fromEntries\([\s\S]*?\)\s*:\s*\{\s*\.\.\.buildHudRuntimeEnv\(/);
|
|
3185
|
+
assert.match(source, /const restoreInsideTmuxControlPlane = insideTmuxControlPlane\s*\? applyLaunchOwnedControlPlane\(insideTmuxControlPlane\)/);
|
|
3186
|
+
assert.match(source, /const restoreInsideTmuxControlPlane[\s\S]*?launch = await preLaunch/);
|
|
3187
|
+
assert.match(source, /\.\.\.runtimeEnvOverlay,\s*\.\.\.launchOwnedControlPlaneEnv/);
|
|
2884
3188
|
assert.match(source, /buildTmuxPaneCommand\("env",\s*\[\.\.\.hudEnvArgs,\s*"node",\s*omxBin,\s*"hud",\s*"--watch"\]\)/);
|
|
2885
3189
|
});
|
|
2886
3190
|
it("runCodex registers a HUD resize hook immediately for inside-tmux launches", async () => {
|
|
2887
3191
|
const source = await readFile(join(repoRoot, 'src', 'cli', 'index.ts'), 'utf-8');
|
|
2888
|
-
assert.match(source, /registerInsideTmuxHudResizeHook\(\{\s*hudPaneId,\s*currentPaneId,\s*cwd,\s*sessionId,\s*omxRootOverride,\s*baseEnv: runtimeHookEnv,\s*\}\)/);
|
|
3192
|
+
assert.match(source, /registerInsideTmuxHudResizeHook\(\{\s*hudPaneId,\s*currentPaneId,\s*cwd,\s*sessionId,\s*omxRootOverride: selectedOmxRootOverride,\s*baseEnv: runtimeHookEnv,\s*\}\)/);
|
|
2889
3193
|
assert.match(source, /if \(currentPaneId\) \{\s*unregisterHudResizeHook\(currentPaneId\);\s*\}/);
|
|
2890
3194
|
});
|
|
2891
3195
|
it("buildInsideTmuxHudHookEnv tags hook commands with session, owner, leader, and local root", () => {
|
|
@@ -2944,6 +3248,59 @@ exit 0
|
|
|
2944
3248
|
assert.equal(env.OMX_ROOT, "/repo");
|
|
2945
3249
|
assert.equal(env.OMX_ENTRY_PATH, "/repo/dist/cli/omx.js");
|
|
2946
3250
|
});
|
|
3251
|
+
describe("detached HUD deferred mutation guard", () => {
|
|
3252
|
+
const leader = {
|
|
3253
|
+
paneId: "%11",
|
|
3254
|
+
panePid: 1100,
|
|
3255
|
+
sessionName: "omx-detached",
|
|
3256
|
+
sessionId: "$1",
|
|
3257
|
+
sessionCreated: "1700000000",
|
|
3258
|
+
windowId: "@1",
|
|
3259
|
+
windowIndex: "0",
|
|
3260
|
+
ownerId: "instance-1",
|
|
3261
|
+
};
|
|
3262
|
+
const hud = {
|
|
3263
|
+
paneId: "%77",
|
|
3264
|
+
panePid: 7700,
|
|
3265
|
+
sessionId: "$1",
|
|
3266
|
+
windowId: "@1",
|
|
3267
|
+
operationMarker: "operation-1",
|
|
3268
|
+
};
|
|
3269
|
+
it("throws fail-closed when a deferred HUD payload has format escapes but no resize sink", () => {
|
|
3270
|
+
const sinkFree = ["run-shell", "-b",
|
|
3271
|
+
"tmux list-panes -a -F '#{pane_id}\t#{pane_dead}\t#{pane_pid}' >/dev/null 2>&1 || true"];
|
|
3272
|
+
assert.throws(() => guardDetachedHudDeferredMutation(leader, hud, sinkFree), /detached deferred HUD mutation lacks a recognized resize sink/);
|
|
3273
|
+
});
|
|
3274
|
+
it("guards immediate and delayed resize sinks as bare tmux command-list commands", () => {
|
|
3275
|
+
const args = buildRegisterResizeHookArgs("omx-detached:0", "omx_resize_detached", "%77", 2, 7700, "instance-1");
|
|
3276
|
+
const guarded = guardDetachedHudDeferredMutation(leader, hud, args);
|
|
3277
|
+
const hookCommand = guarded.at(-1);
|
|
3278
|
+
assert.match(hookCommand, /resize-pane -t %77 -y 2 ; display-message/);
|
|
3279
|
+
assert.doesNotMatch(hookCommand, /tmux resize-pane -t %77 -y 2 ; display-message/);
|
|
3280
|
+
assert.match(hookCommand, /tmux if-shell -F/);
|
|
3281
|
+
assert.match(hookCommand, /##\{pane_id\}/);
|
|
3282
|
+
assert.equal(countMatches(hookCommand, /tmux if-shell -F/g), 2);
|
|
3283
|
+
assert.equal(countMatches(hookCommand, /run-shell -b/g), 1);
|
|
3284
|
+
});
|
|
3285
|
+
it("escapes injected authority conditions so they survive the outer run-shell format pass", () => {
|
|
3286
|
+
const args = buildRegisterResizeHookArgs("omx-detached:0", "omx_resize_detached", "%77", 2, 7700, "instance-1");
|
|
3287
|
+
const hookCommand = guardDetachedHudDeferredMutation(leader, hud, args).at(-1);
|
|
3288
|
+
// run-shell applies exactly one outer tmux format pass to the stored payload.
|
|
3289
|
+
// Unescaped, tmux pre-expands these conditions against the hook's own pane and
|
|
3290
|
+
// collapses them to constants, denying the resize before the sink is parsed.
|
|
3291
|
+
for (const condition of [
|
|
3292
|
+
"##{==:##{pane_id},%11}",
|
|
3293
|
+
"##{==:##{pane_pid},1100}",
|
|
3294
|
+
"##{==:##{@omx_instance_id},instance-1}",
|
|
3295
|
+
"##{==:##{pane_id},%77}",
|
|
3296
|
+
"##{m:*OMX_DETACHED_HUD_OPERATION=operation-1*,##{pane_start_command}}",
|
|
3297
|
+
]) {
|
|
3298
|
+
assert.ok(hookCommand.includes(condition), `stored payload must escape ${condition}`);
|
|
3299
|
+
}
|
|
3300
|
+
assert.doesNotMatch(hookCommand, /(^|[^#])#\{==:#\{pane_id\},%77\}/);
|
|
3301
|
+
assert.doesNotMatch(hookCommand, /(^|[^#])#\{&&:/);
|
|
3302
|
+
});
|
|
3303
|
+
});
|
|
2947
3304
|
it("registerDetachedHudLayoutReconcileHook reads TMUX from the detached leader pane before registering", () => {
|
|
2948
3305
|
const calls = [];
|
|
2949
3306
|
const readTargets = [];
|
|
@@ -2993,412 +3350,28 @@ exit 0
|
|
|
2993
3350
|
},
|
|
2994
3351
|
}), false);
|
|
2995
3352
|
});
|
|
2996
|
-
it("buildDetachedSessionBootstrapSteps starts native Windows
|
|
2997
|
-
const
|
|
2998
|
-
"omx.js",
|
|
2999
|
-
"hud",
|
|
3000
|
-
"--watch",
|
|
3001
|
-
]);
|
|
3002
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", "C:/project", "'codex' '--dangerously-bypass-approvals-and-sandbox'", hudCmd, "--model gpt-5", "C:/codex-home", null, true);
|
|
3003
|
-
assert.equal(steps[0]?.name, "new-session");
|
|
3004
|
-
assert.equal(steps[0]?.args.at(-1), "powershell.exe");
|
|
3005
|
-
assert.equal(steps[1]?.name, "split-and-capture-hud-pane");
|
|
3006
|
-
assert.equal(steps[1]?.args.at(-1), hudCmd);
|
|
3007
|
-
});
|
|
3008
|
-
it("buildDetachedWindowsBootstrapScript targets the resolved tmux-compatible command", () => {
|
|
3009
|
-
const script = buildDetachedWindowsBootstrapScript("omx-demo", "powershell.exe -NoLogo -NoExit -EncodedCommand abc", 2500, "C:\\Program Files\\psmux\\psmux.exe");
|
|
3010
|
-
assert.match(script, /const tmuxCommand = "C:\\\\Program Files\\\\psmux\\\\psmux\.exe";/);
|
|
3011
|
-
assert.match(script, /execFileSync\(tmuxCommand, \['send-keys'/);
|
|
3012
|
-
assert.doesNotMatch(script, /execFileSync\('tmux'/);
|
|
3013
|
-
});
|
|
3014
|
-
it("buildDetachedSessionBootstrapSteps kills detached tmux session on normal shell exit", () => {
|
|
3015
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null);
|
|
3353
|
+
it("buildDetachedSessionBootstrapSteps starts native Windows with the persistent internal leader", () => {
|
|
3354
|
+
const steps = buildDetachedSessionBootstrapSteps("omx-demo", "C:/project", buildWindowsDetachedChildCommand("codex", ["--model", "gpt-5"]), "'node' 'omx.js' 'hud' '--watch'", null, undefined, null, true, "omx-session-123", "C:/project/.codex", "C:/project/.omx/runtime/codex-home/omx-session-123", undefined, process.env, undefined, undefined, undefined, "C:/project/.omx/runtime/detached-release/omx-session-123.release", "C:/project/dist/cli/omx.js");
|
|
3016
3355
|
const leaderCmd = steps[0]?.args.at(-1);
|
|
3017
3356
|
assert.equal(typeof leaderCmd, "string");
|
|
3018
|
-
assert.match(leaderCmd,
|
|
3019
|
-
assert.
|
|
3020
|
-
assert.
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
assert.match(leaderCmd, /<\&3 &/);
|
|
3026
|
-
assert.match(leaderCmd, /wait "\$omx_codex_pid";/);
|
|
3027
|
-
assert.match(leaderCmd, /kill -TERM "\$omx_codex_pid"/);
|
|
3028
|
-
assert.match(leaderCmd, /releaseTmuxExtendedKeysLease/);
|
|
3029
|
-
assert.match(leaderCmd, /if \[ "\$status" -eq 0 \]; then/);
|
|
3030
|
-
assert.match(leaderCmd, /tmux kill-session -t/);
|
|
3031
|
-
assert.match(leaderCmd, /"omx-demo"/);
|
|
3032
|
-
assert.match(leaderCmd, /codex exited immediately with code 0/);
|
|
3033
|
-
assert.match(leaderCmd, /codex exited with code/);
|
|
3034
|
-
assert.match(leaderCmd, /detached tmux session is being kept open/);
|
|
3035
|
-
assert.match(leaderCmd, /exit \$status/);
|
|
3036
|
-
});
|
|
3037
|
-
it("buildDetachedSessionBootstrapSteps finalizes postLaunch inside the detached leader when a session id is available", () => {
|
|
3038
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null, "/tmp/codex-home", null, false, "omx-session-123", "/tmp/project/.codex-project", "/tmp/project/.omx/runtime/codex-home/omx-session-123");
|
|
3357
|
+
assert.match(leaderCmd, /powershell\.exe -NoLogo -NoProfile -NonInteractive -Command/);
|
|
3358
|
+
assert.match(leaderCmd, /__detached-session-leader/);
|
|
3359
|
+
assert.doesNotMatch(leaderCmd, /__detached-post-launch|Test-Path -LiteralPath/);
|
|
3360
|
+
});
|
|
3361
|
+
it("buildDetachedSessionBootstrapSteps gives the POSIX leader persistent lifecycle ownership", () => {
|
|
3362
|
+
const releaseMarkerPath = "/tmp/project/.omx/runtime/detached-release/omx-session-123.release";
|
|
3363
|
+
const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "'codex' '--model' 'gpt-5'", "'node' '/tmp/omx.js' 'hud' '--watch'", null, "/tmp/codex-home", null, false, "omx-session-123", "/tmp/project/.codex-project", "/tmp/project/.omx/runtime/codex-home/omx-session-123", undefined, process.env, undefined, undefined, undefined, releaseMarkerPath);
|
|
3039
3364
|
const leaderCmd = steps[0]?.args.at(-1);
|
|
3040
3365
|
assert.equal(typeof leaderCmd, "string");
|
|
3041
|
-
assert.match(leaderCmd, /
|
|
3042
|
-
assert.match(leaderCmd, /
|
|
3043
|
-
assert.
|
|
3044
|
-
assert.match(leaderCmd, /\/tmp\/project\/\.codex-project/);
|
|
3045
|
-
assert.match(leaderCmd, /\/tmp\/project\/\.omx\/runtime\/codex-home\/omx-session-123/);
|
|
3046
|
-
const helperIndex = leaderCmd.indexOf("runDetachedSessionPostLaunch");
|
|
3047
|
-
const signalGateIndex = leaderCmd.indexOf('if [ "$status" -eq 0 ]');
|
|
3048
|
-
assert.ok(helperIndex >= 0);
|
|
3049
|
-
assert.ok(signalGateIndex >= 0);
|
|
3050
|
-
assert.ok(helperIndex < signalGateIndex, "detached postLaunch helper must run before the signal-derived tmux kill-session gate");
|
|
3051
|
-
});
|
|
3052
|
-
it("detached leader command keeps stdin open for the Codex child", async () => {
|
|
3053
|
-
const cwd = await mkdtemp(join(tmpdir(), "omx-detached-leader-stdin-"));
|
|
3054
|
-
const fakeBin = join(cwd, "bin");
|
|
3055
|
-
const stdinLogPath = join(cwd, "stdin.log");
|
|
3056
|
-
try {
|
|
3057
|
-
await mkdir(fakeBin, { recursive: true });
|
|
3058
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
3059
|
-
if IFS= read -r line; then
|
|
3060
|
-
printf 'stdin:%s\n' "$line" > "${stdinLogPath}"
|
|
3061
|
-
else
|
|
3062
|
-
printf 'stdin:EOF\n' > "${stdinLogPath}"
|
|
3063
|
-
fi
|
|
3064
|
-
`);
|
|
3065
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
3066
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
3067
|
-
case "$1" in
|
|
3068
|
-
display-message)
|
|
3069
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
3070
|
-
printf '/tmp/tmux-test.sock\n'
|
|
3071
|
-
else
|
|
3072
|
-
printf '0\n'
|
|
3073
|
-
fi
|
|
3074
|
-
;;
|
|
3075
|
-
show-options)
|
|
3076
|
-
printf 'off\n'
|
|
3077
|
-
;;
|
|
3078
|
-
set-option|kill-session)
|
|
3079
|
-
;;
|
|
3080
|
-
esac
|
|
3081
|
-
exit 0
|
|
3082
|
-
`);
|
|
3083
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
3084
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", cwd, buildTmuxPaneCommand("codex", [], "/bin/sh"), "'node' '/tmp/omx.js' 'hud' '--watch'", null);
|
|
3085
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
3086
|
-
assert.equal(typeof leaderCmd, "string");
|
|
3087
|
-
const result = (await import("node:child_process")).spawnSync("/bin/sh", ["-c", leaderCmd], {
|
|
3088
|
-
cwd,
|
|
3089
|
-
env: {
|
|
3090
|
-
...process.env,
|
|
3091
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
3092
|
-
HOME: cwd,
|
|
3093
|
-
},
|
|
3094
|
-
input: "hello from leader\n",
|
|
3095
|
-
encoding: "utf-8",
|
|
3096
|
-
});
|
|
3097
|
-
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
3098
|
-
const stdinLog = await readFile(stdinLogPath, "utf-8");
|
|
3099
|
-
assert.match(stdinLog, /stdin:hello from leader/);
|
|
3100
|
-
}
|
|
3101
|
-
finally {
|
|
3102
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3103
|
-
}
|
|
3104
|
-
});
|
|
3105
|
-
it("detached leader command preserves cwd and cleanup without shell-quote breakage", async () => {
|
|
3106
|
-
const cwd = await mkdtemp(join(tmpdir(), "omx-detached-leader-"));
|
|
3107
|
-
const fakeBin = join(cwd, "bin");
|
|
3108
|
-
const logPath = join(cwd, "leader.log");
|
|
3109
|
-
try {
|
|
3110
|
-
await mkdir(fakeBin, { recursive: true });
|
|
3111
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
3112
|
-
printf 'codex:%s\\n' "$*" >> "${logPath}"
|
|
3113
|
-
printf 'codex-pwd:%s\\n' "$(pwd)" >> "${logPath}"
|
|
3114
|
-
printf 'codex-bridge-env:%s\\n' "\${OMX_HERMES_MCP_BRIDGE-unset}" >> "${logPath}"
|
|
3115
|
-
exit 0
|
|
3116
|
-
`);
|
|
3117
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
3118
|
-
await writeFile(join(cwd, ".profile"), "cd ..\n");
|
|
3119
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
3120
|
-
printf 'tmux:%s\\n' "$*" >> "${logPath}"
|
|
3121
|
-
case "$1" in
|
|
3122
|
-
display-message)
|
|
3123
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
3124
|
-
printf '/tmp/tmux-test.sock\\n'
|
|
3125
|
-
else
|
|
3126
|
-
printf '0\\n'
|
|
3127
|
-
fi
|
|
3128
|
-
;;
|
|
3129
|
-
show-options)
|
|
3130
|
-
printf 'off\\n'
|
|
3131
|
-
;;
|
|
3132
|
-
set-option|kill-session)
|
|
3133
|
-
;;
|
|
3134
|
-
esac
|
|
3135
|
-
exit 0
|
|
3136
|
-
`);
|
|
3137
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
3138
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", cwd, buildTmuxPaneCommand("codex", ["--dangerously-bypass-approvals-and-sandbox"], "/bin/sh"), "'node' '/tmp/omx.js' 'hud' '--watch'", null);
|
|
3139
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
3140
|
-
assert.equal(typeof leaderCmd, "string");
|
|
3141
|
-
(await import("node:child_process")).execFileSync("/bin/sh", ["-c", leaderCmd], {
|
|
3142
|
-
cwd,
|
|
3143
|
-
env: {
|
|
3144
|
-
...process.env,
|
|
3145
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
3146
|
-
HOME: cwd,
|
|
3147
|
-
OMX_HERMES_MCP_BRIDGE: "1",
|
|
3148
|
-
},
|
|
3149
|
-
stdio: "ignore",
|
|
3150
|
-
});
|
|
3151
|
-
const log = await readFile(logPath, "utf-8");
|
|
3152
|
-
assert.match(log, /codex:--dangerously-bypass-approvals-and-sandbox/);
|
|
3153
|
-
assert.match(normalizeDarwinTmpPath(log), new RegExp(`codex-pwd:${escapeRegExp(normalizeDarwinTmpPath(cwd))}`));
|
|
3154
|
-
assert.match(log, /codex-bridge-env:unset/);
|
|
3155
|
-
assert.match(log, /tmux:display-message -p #\{socket_path\}/);
|
|
3156
|
-
assert.match(log, /tmux:show-options -sv extended-keys/);
|
|
3157
|
-
assert.match(log, /tmux:set-option -sq extended-keys always/);
|
|
3158
|
-
assert.match(log, /tmux:set-option -sq extended-keys off/);
|
|
3159
|
-
assert.match(log, /tmux:kill-session -t omx-demo/);
|
|
3160
|
-
}
|
|
3161
|
-
finally {
|
|
3162
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3163
|
-
}
|
|
3164
|
-
});
|
|
3165
|
-
it("detached leader command preserves the detached tmux session on signal-derived exits", async () => {
|
|
3166
|
-
const cwd = await mkdtemp(join(tmpdir(), "omx-detached-leader-signal-"));
|
|
3167
|
-
const fakeBin = join(cwd, "bin");
|
|
3168
|
-
const logPath = join(cwd, "leader.log");
|
|
3169
|
-
try {
|
|
3170
|
-
await mkdir(fakeBin, { recursive: true });
|
|
3171
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
3172
|
-
printf 'codex:%s\\n' "$*" >> "${logPath}"
|
|
3173
|
-
exit 143
|
|
3174
|
-
`);
|
|
3175
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
3176
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
3177
|
-
printf 'tmux:%s\\n' "$*" >> "${logPath}"
|
|
3178
|
-
case "$1" in
|
|
3179
|
-
display-message)
|
|
3180
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
3181
|
-
printf '/tmp/tmux-test.sock\\n'
|
|
3182
|
-
else
|
|
3183
|
-
printf '0\\n'
|
|
3184
|
-
fi
|
|
3185
|
-
;;
|
|
3186
|
-
show-options)
|
|
3187
|
-
printf 'off\\n'
|
|
3188
|
-
;;
|
|
3189
|
-
set-option|kill-session)
|
|
3190
|
-
;;
|
|
3191
|
-
esac
|
|
3192
|
-
exit 0
|
|
3193
|
-
`);
|
|
3194
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
3195
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", cwd, buildTmuxPaneCommand("codex", ["--dangerously-bypass-approvals-and-sandbox"], "/bin/sh"), "'node' '/tmp/omx.js' 'hud' '--watch'", null);
|
|
3196
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
3197
|
-
assert.equal(typeof leaderCmd, "string");
|
|
3198
|
-
const result = (await import("node:child_process")).spawnSync("/bin/sh", ["-c", leaderCmd], {
|
|
3199
|
-
cwd,
|
|
3200
|
-
env: {
|
|
3201
|
-
...process.env,
|
|
3202
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
3203
|
-
HOME: cwd,
|
|
3204
|
-
},
|
|
3205
|
-
encoding: "utf-8",
|
|
3206
|
-
});
|
|
3207
|
-
assert.equal(result.status, 143);
|
|
3208
|
-
const log = await readFile(logPath, "utf-8");
|
|
3209
|
-
assert.match(log, /codex:--dangerously-bypass-approvals-and-sandbox/);
|
|
3210
|
-
assert.match(log, /tmux:display-message -p #\{socket_path\}/);
|
|
3211
|
-
assert.match(log, /tmux:show-options -sv extended-keys/);
|
|
3212
|
-
assert.match(log, /tmux:set-option -sq extended-keys always/);
|
|
3213
|
-
assert.match(log, /tmux:set-option -sq extended-keys off/);
|
|
3214
|
-
assert.doesNotMatch(log, /tmux:kill-session -t omx-demo/);
|
|
3215
|
-
}
|
|
3216
|
-
finally {
|
|
3217
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3218
|
-
}
|
|
3219
|
-
});
|
|
3220
|
-
it("detached leader command keeps child startup errors visible instead of killing the session", async () => {
|
|
3221
|
-
const cwd = await mkdtemp(join(tmpdir(), "omx-detached-leader-error-"));
|
|
3222
|
-
const fakeBin = join(cwd, "bin");
|
|
3223
|
-
const logPath = join(cwd, "leader.log");
|
|
3224
|
-
try {
|
|
3225
|
-
await mkdir(fakeBin, { recursive: true });
|
|
3226
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
3227
|
-
printf 'codex-stderr: unsupported startup flag\\n' >&2
|
|
3228
|
-
exit 42
|
|
3229
|
-
`);
|
|
3230
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
3231
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
3232
|
-
printf 'tmux:%s\\n' "$*" >> "${logPath}"
|
|
3233
|
-
case "$1" in
|
|
3234
|
-
display-message)
|
|
3235
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
3236
|
-
printf '/tmp/tmux-test.sock\\n'
|
|
3237
|
-
else
|
|
3238
|
-
printf '0\\n'
|
|
3239
|
-
fi
|
|
3240
|
-
;;
|
|
3241
|
-
show-options)
|
|
3242
|
-
printf 'off\\n'
|
|
3243
|
-
;;
|
|
3244
|
-
set-option|kill-session)
|
|
3245
|
-
;;
|
|
3246
|
-
esac
|
|
3247
|
-
exit 0
|
|
3248
|
-
`);
|
|
3249
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
3250
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", cwd, buildTmuxPaneCommand("codex", ["--bad-startup-flag"], "/bin/sh"), "'node' '/tmp/omx.js' 'hud' '--watch'", null);
|
|
3251
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
3252
|
-
assert.equal(typeof leaderCmd, "string");
|
|
3253
|
-
const result = (await import("node:child_process")).spawnSync("/bin/sh", ["-c", leaderCmd], {
|
|
3254
|
-
cwd,
|
|
3255
|
-
env: {
|
|
3256
|
-
...process.env,
|
|
3257
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
3258
|
-
HOME: cwd,
|
|
3259
|
-
},
|
|
3260
|
-
input: "\n",
|
|
3261
|
-
encoding: "utf-8",
|
|
3262
|
-
});
|
|
3263
|
-
assert.equal(result.status, 42);
|
|
3264
|
-
assert.match(result.stderr, /codex-stderr: unsupported startup flag/);
|
|
3265
|
-
assert.match(result.stderr, /codex exited with code 42 during startup/);
|
|
3266
|
-
assert.match(result.stderr, /detached tmux session is being kept open/);
|
|
3267
|
-
const log = await readFile(logPath, "utf-8");
|
|
3268
|
-
assert.doesNotMatch(log, /tmux:kill-session -t omx-demo/);
|
|
3269
|
-
}
|
|
3270
|
-
finally {
|
|
3271
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3272
|
-
}
|
|
3273
|
-
});
|
|
3274
|
-
it("detached leader command keeps immediate zero-code exits visible instead of silently closing", async () => {
|
|
3275
|
-
const cwd = await mkdtemp(join(tmpdir(), "omx-detached-leader-zero-"));
|
|
3276
|
-
const fakeBin = join(cwd, "bin");
|
|
3277
|
-
const logPath = join(cwd, "leader.log");
|
|
3278
|
-
try {
|
|
3279
|
-
await mkdir(fakeBin, { recursive: true });
|
|
3280
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
3281
|
-
printf 'codex-started-then-quit\\n' >&2
|
|
3282
|
-
exit 0
|
|
3283
|
-
`);
|
|
3284
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
3285
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
3286
|
-
printf 'tmux:%s\\n' "$*" >> "${logPath}"
|
|
3287
|
-
case "$1" in
|
|
3288
|
-
display-message)
|
|
3289
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
3290
|
-
printf '/tmp/tmux-test.sock\\n'
|
|
3291
|
-
else
|
|
3292
|
-
printf '0\\n'
|
|
3293
|
-
fi
|
|
3294
|
-
;;
|
|
3295
|
-
show-options)
|
|
3296
|
-
printf 'off\\n'
|
|
3297
|
-
;;
|
|
3298
|
-
set-option|kill-session)
|
|
3299
|
-
;;
|
|
3300
|
-
esac
|
|
3301
|
-
exit 0
|
|
3302
|
-
`);
|
|
3303
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
3304
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", cwd, buildTmuxPaneCommand("codex", [], "/bin/sh"), "'node' '/tmp/omx.js' 'hud' '--watch'", null);
|
|
3305
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
3306
|
-
assert.equal(typeof leaderCmd, "string");
|
|
3307
|
-
const result = (await import("node:child_process")).spawnSync("/bin/sh", ["-c", leaderCmd], {
|
|
3308
|
-
cwd,
|
|
3309
|
-
env: {
|
|
3310
|
-
...process.env,
|
|
3311
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
3312
|
-
HOME: cwd,
|
|
3313
|
-
},
|
|
3314
|
-
input: "\n",
|
|
3315
|
-
encoding: "utf-8",
|
|
3316
|
-
});
|
|
3317
|
-
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
3318
|
-
assert.match(result.stderr, /codex-started-then-quit/);
|
|
3319
|
-
assert.match(result.stderr, /codex exited immediately with code 0 during startup/);
|
|
3320
|
-
assert.match(result.stderr, /detached tmux session is being kept open/);
|
|
3321
|
-
const log = await readFile(logPath, "utf-8");
|
|
3322
|
-
assert.match(log, /tmux:kill-session -t omx-demo/);
|
|
3323
|
-
}
|
|
3324
|
-
finally {
|
|
3325
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3326
|
-
}
|
|
3366
|
+
assert.match(leaderCmd, /^\/bin\/sh -c '/);
|
|
3367
|
+
assert.match(leaderCmd, /__detached-session-leader/);
|
|
3368
|
+
assert.doesNotMatch(leaderCmd, /__detached-post-launch|omx_codex_pid|while \[ ! -f/);
|
|
3327
3369
|
});
|
|
3328
|
-
it("
|
|
3329
|
-
const
|
|
3330
|
-
const
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
await mkdir(fakeBin, { recursive: true });
|
|
3334
|
-
await writeFile(join(fakeBin, "codex"), `#!/bin/sh
|
|
3335
|
-
echo $$ > "${pidFile}"
|
|
3336
|
-
trap '' HUP
|
|
3337
|
-
while true; do sleep 1; done
|
|
3338
|
-
`);
|
|
3339
|
-
await chmod(join(fakeBin, "codex"), 0o755);
|
|
3340
|
-
await writeFile(join(fakeBin, "tmux"), `#!/bin/sh
|
|
3341
|
-
case "$1" in
|
|
3342
|
-
display-message)
|
|
3343
|
-
if [ "$3" = '#{socket_path}' ] || [ "$4" = '#{socket_path}' ]; then
|
|
3344
|
-
printf '/tmp/tmux-test.sock\\n'
|
|
3345
|
-
else
|
|
3346
|
-
printf '0\\n'
|
|
3347
|
-
fi
|
|
3348
|
-
;;
|
|
3349
|
-
show-options) printf 'off\\n' ;;
|
|
3350
|
-
set-option|kill-session) ;;
|
|
3351
|
-
esac
|
|
3352
|
-
exit 0
|
|
3353
|
-
`);
|
|
3354
|
-
await chmod(join(fakeBin, "tmux"), 0o755);
|
|
3355
|
-
const steps = buildDetachedSessionBootstrapSteps("omx-demo", cwd, buildTmuxPaneCommand("codex", [], "/bin/sh"), "'node' '/tmp/omx.js' 'hud' '--watch'", null);
|
|
3356
|
-
const leaderCmd = steps[0]?.args.at(-1);
|
|
3357
|
-
assert.equal(typeof leaderCmd, "string");
|
|
3358
|
-
const { spawn } = await import("node:child_process");
|
|
3359
|
-
const child = spawn("/bin/sh", ["-c", `exec ${leaderCmd}`], {
|
|
3360
|
-
cwd,
|
|
3361
|
-
env: {
|
|
3362
|
-
...process.env,
|
|
3363
|
-
PATH: `${fakeBin}:/usr/bin:/bin`,
|
|
3364
|
-
HOME: cwd,
|
|
3365
|
-
},
|
|
3366
|
-
stdio: "ignore",
|
|
3367
|
-
detached: true,
|
|
3368
|
-
});
|
|
3369
|
-
try {
|
|
3370
|
-
for (let i = 0; i < 50; i += 1) {
|
|
3371
|
-
if (existsSync(pidFile))
|
|
3372
|
-
break;
|
|
3373
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3374
|
-
}
|
|
3375
|
-
assert.ok(existsSync(pidFile), "codex pid file not written");
|
|
3376
|
-
const codexPid = Number.parseInt((await readFile(pidFile, "utf-8")).trim(), 10);
|
|
3377
|
-
assert.ok(codexPid > 0, "codex pid must be positive");
|
|
3378
|
-
assert.doesNotThrow(() => process.kill(codexPid, 0), "codex must be alive before signal");
|
|
3379
|
-
const leaderExit = once(child, "exit");
|
|
3380
|
-
process.kill(child.pid, "SIGHUP");
|
|
3381
|
-
await Promise.race([
|
|
3382
|
-
leaderExit,
|
|
3383
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("leader did not exit after SIGHUP")), 3000)),
|
|
3384
|
-
]);
|
|
3385
|
-
assert.throws(() => process.kill(codexPid, 0), (err) => typeof err === "object" &&
|
|
3386
|
-
err !== null &&
|
|
3387
|
-
"code" in err &&
|
|
3388
|
-
err.code === "ESRCH", "codex child must be terminated after leader SIGHUP");
|
|
3389
|
-
}
|
|
3390
|
-
finally {
|
|
3391
|
-
try {
|
|
3392
|
-
process.kill(child.pid, "SIGKILL");
|
|
3393
|
-
}
|
|
3394
|
-
catch {
|
|
3395
|
-
/* already dead */
|
|
3396
|
-
}
|
|
3397
|
-
}
|
|
3398
|
-
}
|
|
3399
|
-
finally {
|
|
3400
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3401
|
-
}
|
|
3370
|
+
it("keeps capability data out of the detached leader command payload", () => {
|
|
3371
|
+
const steps = buildDetachedSessionBootstrapSteps("omx-demo", "/tmp/project", "codex", "hud", null, undefined, null, false, "omx-session-123", undefined, undefined, undefined, process.env);
|
|
3372
|
+
const leaderCmd = steps[0]?.args.at(-1) ?? "";
|
|
3373
|
+
assert.match(leaderCmd, /__detached-session-leader/);
|
|
3374
|
+
assert.doesNotMatch(leaderCmd, /launch_lineage_token|directoryIdentity|FileHandle/);
|
|
3402
3375
|
});
|
|
3403
3376
|
it("withTmuxExtendedKeys enables tmux extended keys during codex launch and restores them afterwards", async () => {
|
|
3404
3377
|
const cwd = await mkdtemp(join(tmpdir(), "omx-tmux-lease-wrapper-"));
|
|
@@ -3953,6 +3926,45 @@ describe("buildWindowsPromptCommand", () => {
|
|
|
3953
3926
|
assert.equal(decoded, "$ErrorActionPreference = 'Stop'; & { & 'codex' '--dangerously-bypass-approvals-and-sandbox' '-c' 'model_reasoning_effort=\"high\"' 'it''s' }");
|
|
3954
3927
|
});
|
|
3955
3928
|
});
|
|
3929
|
+
describe("buildWindowsDetachedChildCommand", () => {
|
|
3930
|
+
it("exits with the Codex child status instead of retaining an interactive shell", () => {
|
|
3931
|
+
const result = buildWindowsDetachedChildCommand("codex", ["--model", "gpt-5"]);
|
|
3932
|
+
const prefix = "powershell.exe -NoLogo -NoProfile -NonInteractive -EncodedCommand ";
|
|
3933
|
+
assert.ok(result.startsWith(prefix));
|
|
3934
|
+
assert.doesNotMatch(result, /-NoExit/);
|
|
3935
|
+
assert.equal(Buffer.from(result.slice(prefix.length), "base64").toString("utf16le"), "$ErrorActionPreference = 'Stop'; & 'codex' '--model' 'gpt-5'; exit $LASTEXITCODE");
|
|
3936
|
+
});
|
|
3937
|
+
});
|
|
3938
|
+
describe("Windows detached leader environment", () => {
|
|
3939
|
+
it("serializes inherited parent values into the detached Windows leader command", () => {
|
|
3940
|
+
const steps = buildDetachedSessionBootstrapSteps("omx-test", "C:/project", "codex", "hud", null, undefined, null, true, "session-1", undefined, undefined, undefined, {
|
|
3941
|
+
PATH: "C:/runtime-shim;C:/parent/bin",
|
|
3942
|
+
CUSTOM_VALUE: "retained",
|
|
3943
|
+
CODEX_HOME: "C:/project/.codex-runtime",
|
|
3944
|
+
CODEX_SQLITE_HOME: "C:/project/.codex-sqlite",
|
|
3945
|
+
OMX_ROOT: "C:/project/.omx-run",
|
|
3946
|
+
OMX_CODEX_LAUNCH_ID: "launch-id",
|
|
3947
|
+
OMX_NOTIFY_TEMP_CONTRACT: "{\"active\":true}",
|
|
3948
|
+
OMX_TEAM_WORKER_LAUNCH_ARGS: "[\"--model\",\"gpt-5\"]",
|
|
3949
|
+
TMUX: "foreign",
|
|
3950
|
+
TMUX_PANE: "%9",
|
|
3951
|
+
TERM: "xterm-256color",
|
|
3952
|
+
});
|
|
3953
|
+
const command = steps[0]?.args.at(-1) ?? "";
|
|
3954
|
+
const encodedPayload = command.match(/__detached-session-leader ''([^']+)''/)?.[1];
|
|
3955
|
+
assert.ok(encodedPayload);
|
|
3956
|
+
const payload = JSON.parse(Buffer.from(encodedPayload, "base64url").toString("utf8"));
|
|
3957
|
+
assert.deepEqual(payload.parentEnv, {
|
|
3958
|
+
CODEX_HOME: "C:/project/.codex-runtime",
|
|
3959
|
+
CODEX_SQLITE_HOME: "C:/project/.codex-sqlite",
|
|
3960
|
+
CUSTOM_VALUE: "retained",
|
|
3961
|
+
OMX_CODEX_LAUNCH_ID: "launch-id",
|
|
3962
|
+
OMX_NOTIFY_TEMP_CONTRACT: "{\"active\":true}",
|
|
3963
|
+
OMX_TEAM_WORKER_LAUNCH_ARGS: "[\"--model\",\"gpt-5\"]",
|
|
3964
|
+
PATH: "C:/runtime-shim;C:/parent/bin",
|
|
3965
|
+
});
|
|
3966
|
+
});
|
|
3967
|
+
});
|
|
3956
3968
|
describe("buildTmuxSessionName", () => {
|
|
3957
3969
|
it("uses detached fallback quietly outside git repos", () => {
|
|
3958
3970
|
const name = buildTmuxSessionName("/tmp/My Repo", "omx-1770992424158-abc123");
|
|
@@ -4256,4 +4268,153 @@ describe("isExistingTmuxWindowTooCrampedForLaunchHud (#2754)", () => {
|
|
|
4256
4268
|
assert.equal(isExistingTmuxWindowTooCrampedForLaunchHud(39, 40), true);
|
|
4257
4269
|
});
|
|
4258
4270
|
});
|
|
4271
|
+
describe("detached control-plane binding", () => {
|
|
4272
|
+
it("bounds inside-tmux lifecycle propagation to the finite launch-owned control plane", async () => {
|
|
4273
|
+
const source = await readFile(join(repoRoot, "src", "cli", "index.ts"), "utf8");
|
|
4274
|
+
assert.match(source, /if \(launchPolicy === "inside-tmux"\) \{[\s\S]*?buildDetachedLaunchControlPlane\(/);
|
|
4275
|
+
assert.match(source, /const restoreInsideTmuxControlPlane = insideTmuxControlPlane\s*\? applyLaunchOwnedControlPlane\(insideTmuxControlPlane\)/);
|
|
4276
|
+
assert.match(source, /const codexBaseEnv = prependOmxRuntimeCommandShimToEnv\([\s\S]*?\.\.\.launchOwnedControlPlaneEnv/);
|
|
4277
|
+
assert.match(source, /const runtimeHookEnv = launchOwnedControlPlane\s*\?[\s\S]*?\.\.\.launchOwnedControlPlaneEnv/);
|
|
4278
|
+
});
|
|
4279
|
+
it("emits one stable assignment for every managed key and clears poisoned identity", () => {
|
|
4280
|
+
const env = {
|
|
4281
|
+
OMX_ROOT: "",
|
|
4282
|
+
OMX_STATE_ROOT: "",
|
|
4283
|
+
OMX_TEAM_STATE_ROOT: "",
|
|
4284
|
+
OMX_RUNS_DIR: "/foreign/runs",
|
|
4285
|
+
OMX_TEAM_LEADER_CWD: "/foreign",
|
|
4286
|
+
OMX_TEAM_WORKER: "foreign/worker-1",
|
|
4287
|
+
OMX_TEAM_INTERNAL_WORKER: "foreign/worker-1",
|
|
4288
|
+
};
|
|
4289
|
+
const controlPlane = buildDetachedLaunchControlPlane({ cwd: "/tmp/project", sessionId: "sess-binding", env });
|
|
4290
|
+
assert.deepEqual([...controlPlane.keys], [...DETACHED_LAUNCH_CONTROL_PLANE_KEYS]);
|
|
4291
|
+
assert.deepEqual(Object.keys(controlPlane.values), [...DETACHED_LAUNCH_CONTROL_PLANE_KEYS]);
|
|
4292
|
+
assert.equal(controlPlane.values.OMX_SESSION_ID, "sess-binding");
|
|
4293
|
+
assert.equal(controlPlane.values.OMX_TMUX_HUD_OWNER, "1");
|
|
4294
|
+
for (const key of [
|
|
4295
|
+
"CODEX_SESSION_ID", "SESSION_ID", "OMX_TMUX_HUD_LEADER_PANE", "OMX_ROOT", "OMX_STATE_ROOT",
|
|
4296
|
+
"OMX_TEAM_STATE_ROOT", "OMXBOX_ACTIVE", "OMX_SOURCE_CWD", "OMX_MADMAX_DETACHED_CONTEXT", "OMX_RUNS_DIR",
|
|
4297
|
+
"OMX_TEAM_LEADER_CWD", "OMX_TEAM_WORKER", "OMX_TEAM_INTERNAL_WORKER",
|
|
4298
|
+
])
|
|
4299
|
+
assert.equal(controlPlane.values[key], "", `${key} must be cleared`);
|
|
4300
|
+
const steps = buildDetachedSessionBootstrapSteps("omx-binding", "/tmp/project", "codex", "hud", null, undefined, null, false, "sess-binding", undefined, undefined, undefined, env, undefined, undefined, undefined, undefined, undefined, undefined, controlPlane);
|
|
4301
|
+
const newSession = steps.find((step) => step.name === "new-session");
|
|
4302
|
+
assert.ok(newSession);
|
|
4303
|
+
const managedAssignments = newSession.args.filter((arg) => DETACHED_LAUNCH_CONTROL_PLANE_KEYS.some((key) => arg.startsWith(`${key}=`)));
|
|
4304
|
+
assert.equal(managedAssignments.length, DETACHED_LAUNCH_CONTROL_PLANE_KEYS.length);
|
|
4305
|
+
assert.deepEqual(managedAssignments.map((assignment) => assignment.slice(0, assignment.indexOf("="))), [...DETACHED_LAUNCH_CONTROL_PLANE_KEYS]);
|
|
4306
|
+
});
|
|
4307
|
+
it("preserves selected explicit roots and valid Madmax runs identity", () => {
|
|
4308
|
+
const explicit = buildDetachedLaunchControlPlane({
|
|
4309
|
+
cwd: "/tmp/project", sessionId: "sess-explicit",
|
|
4310
|
+
env: { OMX_ROOT: "/tmp/selected-root", OMX_STATE_ROOT: "/tmp/stale-state" },
|
|
4311
|
+
});
|
|
4312
|
+
assert.equal(explicit.values.OMX_ROOT, "/tmp/selected-root");
|
|
4313
|
+
assert.equal(explicit.values.OMX_STATE_ROOT, "");
|
|
4314
|
+
assert.equal(explicit.values.OMX_RUNS_DIR, "");
|
|
4315
|
+
const madmax = buildDetachedLaunchControlPlane({
|
|
4316
|
+
cwd: "/tmp/project", sessionId: "sess-madmax",
|
|
4317
|
+
omxRootOverride: "/tmp/run-root",
|
|
4318
|
+
verifiedMadmaxContext: {
|
|
4319
|
+
root: "/tmp/run-root",
|
|
4320
|
+
sourceCwd: "/tmp/project",
|
|
4321
|
+
context: "ctx-madmax",
|
|
4322
|
+
runsRoot: "/tmp/outer-runs",
|
|
4323
|
+
},
|
|
4324
|
+
env: {
|
|
4325
|
+
OMX_ROOT: "/tmp/run-root", OMXBOX_ACTIVE: "1", OMX_SOURCE_CWD: "/tmp/project",
|
|
4326
|
+
OMX_MADMAX_DETACHED_CONTEXT: "ctx-madmax", OMX_RUNS_DIR: "/tmp/outer-runs",
|
|
4327
|
+
},
|
|
4328
|
+
});
|
|
4329
|
+
assert.deepEqual([madmax.values.OMX_ROOT, madmax.values.OMXBOX_ACTIVE, madmax.values.OMX_SOURCE_CWD,
|
|
4330
|
+
madmax.values.OMX_MADMAX_DETACHED_CONTEXT, madmax.values.OMX_RUNS_DIR], ["/tmp/run-root", "1", "/tmp/project", "ctx-madmax", "/tmp/outer-runs"]);
|
|
4331
|
+
const poisoned = buildDetachedLaunchControlPlane({
|
|
4332
|
+
cwd: "/tmp/project", sessionId: "sess-poisoned", omxRootOverride: "/foreign/root",
|
|
4333
|
+
env: {
|
|
4334
|
+
OMX_ROOT: "/foreign/root", OMXBOX_ACTIVE: "1", OMX_SOURCE_CWD: "/foreign/source",
|
|
4335
|
+
OMX_MADMAX_DETACHED_CONTEXT: "poisoned-context", OMX_RUNS_DIR: "/foreign/runs",
|
|
4336
|
+
},
|
|
4337
|
+
});
|
|
4338
|
+
assert.deepEqual([poisoned.values.OMX_ROOT, poisoned.values.OMX_SOURCE_CWD,
|
|
4339
|
+
poisoned.values.OMX_MADMAX_DETACHED_CONTEXT, poisoned.values.OMX_RUNS_DIR], ["", "", "", ""]);
|
|
4340
|
+
});
|
|
4341
|
+
it("preserves an explicit team root while clearing unverified boxed lineage and worker tuple", () => {
|
|
4342
|
+
const cases = [
|
|
4343
|
+
{
|
|
4344
|
+
name: "boxed guard without worker tuple",
|
|
4345
|
+
env: {
|
|
4346
|
+
OMX_TEAM_STATE_ROOT: "/tmp/explicit-team-root",
|
|
4347
|
+
OMX_ROOT: "/tmp/poison-root",
|
|
4348
|
+
OMX_STATE_ROOT: "/tmp/poison-state-root",
|
|
4349
|
+
OMXBOX_ACTIVE: "1",
|
|
4350
|
+
OMX_SOURCE_CWD: "/tmp/poison-source",
|
|
4351
|
+
OMX_MADMAX_DETACHED_CONTEXT: "poison-context",
|
|
4352
|
+
OMX_RUNS_DIR: "/tmp/poison-runs",
|
|
4353
|
+
},
|
|
4354
|
+
},
|
|
4355
|
+
{
|
|
4356
|
+
name: "boxed guard with poisoned worker tuple",
|
|
4357
|
+
env: {
|
|
4358
|
+
OMX_TEAM_STATE_ROOT: "/tmp/explicit-team-root",
|
|
4359
|
+
OMX_ROOT: "/tmp/poison-root",
|
|
4360
|
+
OMX_STATE_ROOT: "/tmp/poison-state-root",
|
|
4361
|
+
OMXBOX_ACTIVE: "1",
|
|
4362
|
+
OMX_SOURCE_CWD: "/tmp/poison-source",
|
|
4363
|
+
OMX_MADMAX_DETACHED_CONTEXT: "poison-context",
|
|
4364
|
+
OMX_RUNS_DIR: "/tmp/poison-runs",
|
|
4365
|
+
OMX_TEAM_LEADER_CWD: "/tmp/poison-leader",
|
|
4366
|
+
OMX_TEAM_WORKER: "poison-team/worker-1",
|
|
4367
|
+
OMX_TEAM_INTERNAL_WORKER: "poison-team/worker-2",
|
|
4368
|
+
},
|
|
4369
|
+
},
|
|
4370
|
+
];
|
|
4371
|
+
for (const testCase of cases) {
|
|
4372
|
+
const controlPlane = buildDetachedLaunchControlPlane({
|
|
4373
|
+
cwd: "/tmp/project",
|
|
4374
|
+
sessionId: `sess-${testCase.name.replaceAll(" ", "-")}`,
|
|
4375
|
+
env: testCase.env,
|
|
4376
|
+
});
|
|
4377
|
+
assert.equal(controlPlane.values.OMX_TEAM_STATE_ROOT, "/tmp/explicit-team-root", testCase.name);
|
|
4378
|
+
for (const key of [
|
|
4379
|
+
"OMX_ROOT", "OMX_STATE_ROOT", "OMXBOX_ACTIVE", "OMX_SOURCE_CWD",
|
|
4380
|
+
"OMX_MADMAX_DETACHED_CONTEXT", "OMX_RUNS_DIR", "OMX_TEAM_LEADER_CWD",
|
|
4381
|
+
"OMX_TEAM_WORKER", "OMX_TEAM_INTERNAL_WORKER",
|
|
4382
|
+
]) {
|
|
4383
|
+
assert.equal(controlPlane.values[key], "", `${testCase.name}: ${key} must be cleared`);
|
|
4384
|
+
}
|
|
4385
|
+
}
|
|
4386
|
+
});
|
|
4387
|
+
it("keeps unrelated parent configuration while filtering exact managed replay names", () => {
|
|
4388
|
+
const serialized = serializeDetachedSessionParentEnv({
|
|
4389
|
+
OMX_ROOT: "/foreign/root", omx_root: "/foreign/mixed-case-root",
|
|
4390
|
+
OMX_TEAM_WORKER: "foreign/worker", Omx_Notify_Fallback: "1",
|
|
4391
|
+
PROVIDER_SENTINEL: "provider-value", Path: "/system/path",
|
|
4392
|
+
});
|
|
4393
|
+
assert.doesNotMatch(serialized, /export OMX_ROOT=/);
|
|
4394
|
+
assert.doesNotMatch(serialized, /export OMX_TEAM_WORKER=/);
|
|
4395
|
+
assert.match(serialized, /export omx_root='/);
|
|
4396
|
+
assert.match(serialized, /export PROVIDER_SENTINEL='provider-value'/);
|
|
4397
|
+
assert.match(serialized, /export Path='\/system\/path'/);
|
|
4398
|
+
assert.match(serialized, /export Omx_Notify_Fallback='1'/);
|
|
4399
|
+
});
|
|
4400
|
+
it("filters every managed Windows case variant while preserving unrelated configuration", () => {
|
|
4401
|
+
const env = {
|
|
4402
|
+
oMx_RoOt: "/foreign/root",
|
|
4403
|
+
OmX_TeAm_WorkEr: "foreign/worker",
|
|
4404
|
+
OMX_PROVIDER_URL: "https://provider.invalid",
|
|
4405
|
+
Path: "/system/path",
|
|
4406
|
+
Omx_Notify_Fallback: "1",
|
|
4407
|
+
};
|
|
4408
|
+
const steps = buildDetachedSessionBootstrapSteps("omx-windows-binding", "/tmp/project", "codex", "hud", null, undefined, null, true, "sess-windows", undefined, undefined, undefined, env);
|
|
4409
|
+
const command = steps[0]?.args.at(-1) ?? "";
|
|
4410
|
+
const encoded = /__detached-session-leader [^A-Za-z0-9_-]*([A-Za-z0-9_-]{40,})/.exec(command)?.[1];
|
|
4411
|
+
assert.ok(encoded);
|
|
4412
|
+
const payload = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
4413
|
+
assert.equal(payload.parentEnv?.oMx_RoOt, undefined);
|
|
4414
|
+
assert.equal(payload.parentEnv?.OmX_TeAm_WorkEr, undefined);
|
|
4415
|
+
assert.equal(payload.parentEnv?.OMX_PROVIDER_URL, "https://provider.invalid");
|
|
4416
|
+
assert.equal(payload.parentEnv?.Path, "/system/path");
|
|
4417
|
+
assert.equal(payload.parentEnv?.Omx_Notify_Fallback, "1");
|
|
4418
|
+
});
|
|
4419
|
+
});
|
|
4259
4420
|
//# sourceMappingURL=index.test.js.map
|