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,12 +1,14 @@
|
|
|
1
1
|
import { describe, it, mock } from 'node:test';
|
|
2
|
+
import { getRemovedSkillInfo } from '../sunset-stub.js';
|
|
2
3
|
import assert from 'node:assert/strict';
|
|
3
4
|
import { existsSync } from 'node:fs';
|
|
4
5
|
import { mkdtemp, mkdir, readFile, rm, symlink, writeFile } from 'node:fs/promises';
|
|
5
6
|
import { tmpdir } from 'node:os';
|
|
6
7
|
import { join } from 'node:path';
|
|
7
8
|
import { detectKeywords, detectPrimaryKeyword, classifyKeywordInput, KEYWORD_INERT_DIAGNOSTIC_ORDER, recordSkillActivation, DEEP_INTERVIEW_STATE_FILE, DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS, DEEP_INTERVIEW_INPUT_LOCK_MESSAGE, persistDeepInterviewModeState, } from '../keyword-detector.js';
|
|
8
|
-
import { SKILL_ACTIVE_STATE_FILE } from '../../state/skill-active.js';
|
|
9
|
-
import {
|
|
9
|
+
import { readSkillActiveState, SKILL_ACTIVE_STATE_FILE } from '../../state/skill-active.js';
|
|
10
|
+
import { neutralizeOwnedRoutingRalplan } from '../../ralplan/documented-leader-preflight.js';
|
|
11
|
+
import { readActiveWorkflowModes } from '../../state/workflow-transition.js';
|
|
10
12
|
import { EXPLICIT_SKILL_ALIASES, getExplicitSkillDefinition, KEYWORD_TRIGGER_DEFINITIONS, } from '../keyword-registry.js';
|
|
11
13
|
import { evaluateResolvedPromptTurn } from '../prompt-session-provenance.js';
|
|
12
14
|
async function withIsolatedHome(prefix, run) {
|
|
@@ -101,24 +103,23 @@ describe('keyword detector team compatibility', () => {
|
|
|
101
103
|
assert.equal(matches[0]?.keyword, '$oh-my-codex:ralplan');
|
|
102
104
|
});
|
|
103
105
|
it('supports mixed-form explicit multi-skill invocation ordering and dedupe', () => {
|
|
104
|
-
const matches = detectKeywords('$oh-my-codex:ralplan $
|
|
105
|
-
assert.deepEqual(matches.map((m) => m.skill), ['ralplan', '
|
|
106
|
-
assert.deepEqual(matches.map((m) => m.keyword), ['$oh-my-codex:ralplan', '$
|
|
106
|
+
const matches = detectKeywords('$oh-my-codex:ralplan $ultragoal $oh-my-codex:ralplan ship this');
|
|
107
|
+
assert.deepEqual(matches.map((m) => m.skill), ['ralplan', 'ultragoal']);
|
|
108
|
+
assert.deepEqual(matches.map((m) => m.keyword), ['$oh-my-codex:ralplan', '$ultragoal']);
|
|
107
109
|
});
|
|
108
110
|
it('keeps recognized tokens on both sides of an unknown plugin-prefixed token in the same contiguous block', () => {
|
|
109
|
-
const matches = detectKeywords('$oh-my-codex:ralplan $oh-my-codex:unknown $
|
|
110
|
-
assert.deepEqual(matches.map((m) => m.skill), ['ralplan', '
|
|
111
|
-
assert.deepEqual(matches.map((m) => m.keyword), ['$oh-my-codex:ralplan', '$
|
|
111
|
+
const matches = detectKeywords('$oh-my-codex:ralplan $oh-my-codex:unknown $ultragoal');
|
|
112
|
+
assert.deepEqual(matches.map((m) => m.skill), ['ralplan', 'ultragoal']);
|
|
113
|
+
assert.deepEqual(matches.map((m) => m.keyword), ['$oh-my-codex:ralplan', '$ultragoal']);
|
|
112
114
|
});
|
|
113
115
|
it('limits mixed-form explicit invocation to the first contiguous block', () => {
|
|
114
116
|
const matches = detectKeywords('$oh-my-codex:ralplan text $ralph');
|
|
115
117
|
assert.deepEqual(matches.map((m) => m.skill), ['ralplan']);
|
|
116
118
|
});
|
|
117
|
-
it('
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
assert.equal(ulw
|
|
121
|
-
assert.equal(ulw.keyword, '$oh-my-codex:ulw');
|
|
119
|
+
it('does not route the plugin-prefixed ulw shorthand at a sunset skill', () => {
|
|
120
|
+
// ulw was shorthand for ultrawork, which is now a sunset skill with no trigger. The plugin prefix
|
|
121
|
+
// must not resurrect that route.
|
|
122
|
+
assert.equal(detectPrimaryKeyword('$oh-my-codex:ulw continue'), null);
|
|
122
123
|
});
|
|
123
124
|
it('supports plugin-prefixed hyphenated workflow tokens', () => {
|
|
124
125
|
const deepInterview = detectPrimaryKeyword('$oh-my-codex:deep-interview gather requirements');
|
|
@@ -252,11 +253,15 @@ describe('keyword detector team compatibility', () => {
|
|
|
252
253
|
const match = detectPrimaryKeyword('why does ralph keep blocking stop?');
|
|
253
254
|
assert.equal(match, null);
|
|
254
255
|
});
|
|
255
|
-
it('
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
assert.equal(
|
|
256
|
+
it('does not activate a workflow for the sunset $ralph token', () => {
|
|
257
|
+
// Approved decision: $ralph is a sunset skill token, so it must produce a non-activating
|
|
258
|
+
// diagnostic rather than mutating workflow state. The `omx ralph` CLI and the ralph persistence
|
|
259
|
+
// runtime are separate entry points and stay live - only the keyword surface is retired.
|
|
260
|
+
assert.equal(detectPrimaryKeyword('$ralph continue verification'), null);
|
|
261
|
+
const info = getRemovedSkillInfo('ralph');
|
|
262
|
+
assert.ok(info, '$ralph must be declared as a removed skill so the diagnostic path fires');
|
|
263
|
+
assert.equal(info.replacement, '$ultragoal');
|
|
264
|
+
assert.match(info.message, /removed/i);
|
|
260
265
|
});
|
|
261
266
|
it('prefers ralplan over ralph follow-up language when both implicit routes are present', () => {
|
|
262
267
|
const match = detectPrimaryKeyword('keep going but do consensus plan first');
|
|
@@ -356,16 +361,16 @@ describe('keyword detector team compatibility', () => {
|
|
|
356
361
|
assert.equal(detectPrimaryKeyword('PASS runs assertions in parallel when sharding is enabled'), null);
|
|
357
362
|
assert.equal(detectPrimaryKeyword('running 8 tests in parallel across 4 workers'), null);
|
|
358
363
|
});
|
|
359
|
-
it('
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
assert.
|
|
366
|
-
|
|
367
|
-
assert.
|
|
368
|
-
assert.equal(
|
|
364
|
+
it('no longer routes the Korean ulw keyboard typo, whose only target is a sunset skill', () => {
|
|
365
|
+
// The IME typo alias existed solely to reach ultrawork's `ulw` shorthand. ultrawork is now a
|
|
366
|
+
// sunset skill with no trigger, so normalizing the typo would route a user at a token the catalog
|
|
367
|
+
// no longer ships. The four cases that pinned that routing are replaced by this one, which pins
|
|
368
|
+
// the retirement instead; the normalizer seam is kept for a future LIVE shorthand.
|
|
369
|
+
assert.equal(detectPrimaryKeyword('ㅕㅣㅈ로 이 작업 처리해줘'), null);
|
|
370
|
+
assert.equal(detectPrimaryKeyword('$ㅕㅣㅈ로 이 작업 처리해줘'), null);
|
|
371
|
+
const info = getRemovedSkillInfo('ultrawork');
|
|
372
|
+
assert.ok(info, '$ultrawork must be declared as a removed skill');
|
|
373
|
+
assert.equal(info.replacement, '$team');
|
|
369
374
|
});
|
|
370
375
|
});
|
|
371
376
|
describe('keyword input classification direct grammar', () => {
|
|
@@ -373,11 +378,9 @@ describe('keyword input classification direct grammar', () => {
|
|
|
373
378
|
const cases = [
|
|
374
379
|
{ text: '$ralplan implement this', skills: ['ralplan'], keywords: ['$ralplan'], priorities: [11] },
|
|
375
380
|
{ text: '\u00a0$RALPLAN implement this', skills: ['ralplan'], keywords: ['$RALPLAN'], priorities: [11] },
|
|
376
|
-
{ text: '- $team $
|
|
381
|
+
{ text: '- $team $ultragoal ship this', skills: ['team', 'ultragoal'], keywords: ['$team', '$ultragoal'], priorities: [8, 10] },
|
|
377
382
|
{ text: '12) $oh-my-codex:ralplan build this', skills: ['ralplan'], keywords: ['$oh-my-codex:ralplan'], priorities: [11] },
|
|
378
|
-
{ text: '$
|
|
379
|
-
{ text: '$ralplan $unknown $ralplan $ralph ship this', skills: ['ralplan', 'ralph'], keywords: ['$ralplan', '$ralph'], priorities: [11, 9] },
|
|
380
|
-
{ text: '$ㅕㅣㅈ 병렬 작업', skills: ['ultrawork'], keywords: ['$ulw'], priorities: [10] },
|
|
383
|
+
{ text: '$ralplan $unknown $ralplan $ultragoal ship this', skills: ['ralplan', 'ultragoal'], keywords: ['$ralplan', '$ultragoal'], priorities: [11, 10] },
|
|
381
384
|
{ text: 'use $ralplan plan this', skills: ['ralplan'], keywords: ['$ralplan'], priorities: [11] },
|
|
382
385
|
{ text: 'please use $ralplan plan this', skills: ['ralplan'], keywords: ['$ralplan'], priorities: [11] },
|
|
383
386
|
{ text: 'run $ralplan plan this', skills: ['ralplan'], keywords: ['$ralplan'], priorities: [11] },
|
|
@@ -389,8 +392,8 @@ describe('keyword input classification direct grammar', () => {
|
|
|
389
392
|
{ text: 'start $deep-interview', skills: ['deep-interview'], keywords: ['$deep-interview'], priorities: [8] },
|
|
390
393
|
{ text: 'enable $ultragoal', skills: ['ultragoal'], keywords: ['$ultragoal'], priorities: [10] },
|
|
391
394
|
{ text: 'launch $autopilot', skills: ['autopilot'], keywords: ['$autopilot'], priorities: [10] },
|
|
392
|
-
{ text: 'invoke $
|
|
393
|
-
{ text: 'activate $
|
|
395
|
+
{ text: 'invoke $ultragoal', skills: ['ultragoal'], keywords: ['$ultragoal'], priorities: [10] },
|
|
396
|
+
{ text: 'activate $team', skills: ['team'], keywords: ['$team'], priorities: [8] },
|
|
394
397
|
{ text: 'resume $team', skills: ['team'], keywords: ['$team'], priorities: [8] },
|
|
395
398
|
{ text: 'continue $code-review', skills: ['code-review'], keywords: ['$code-review'], priorities: [6] },
|
|
396
399
|
];
|
|
@@ -790,10 +793,10 @@ describe('keyword input classification direct grammar', () => {
|
|
|
790
793
|
});
|
|
791
794
|
it('accepts only direct punctuation and list boundaries', () => {
|
|
792
795
|
const cases = [
|
|
793
|
-
{ text: '* $
|
|
796
|
+
{ text: '* $ultragoal', skills: ['ultragoal'] },
|
|
794
797
|
{ text: '+ $team', skills: ['team'] },
|
|
795
798
|
{ text: '1. $ralplan', skills: ['ralplan'] },
|
|
796
|
-
{ text: '999) $
|
|
799
|
+
{ text: '999) $team', skills: ['team'] },
|
|
797
800
|
{ text: '($ralplan)', skills: [] },
|
|
798
801
|
{ text: '[$ralplan]', skills: [] },
|
|
799
802
|
{ text: '1,$ralplan', skills: [] },
|
|
@@ -937,7 +940,7 @@ describe('keyword input classification direct grammar', () => {
|
|
|
937
940
|
{ text: '- /prompts:architect is the prompt command documentation\n$ralplan plan it', skills: ['ralplan'] },
|
|
938
941
|
{ text: '- $ralplan, $autopilot are workflow commands\n$team execute it', skills: ['team'] },
|
|
939
942
|
{ text: '- $ralplan and $autopilot are workflow commands\n$team execute it', skills: ['team'] },
|
|
940
|
-
{ text: '- $ralplan, $autopilot, and $team are workflow commands\n$
|
|
943
|
+
{ text: '- $ralplan, $autopilot, and $team are workflow commands\n$ultragoal execute it', skills: ['ultragoal'] },
|
|
941
944
|
{ text: '- $ralplan / $autopilot are workflow commands\n$team execute it', skills: ['team'] },
|
|
942
945
|
{ text: '- $ralplan/$autopilot are workflow commands\n$team execute it', skills: ['team'] },
|
|
943
946
|
{ text: 'use $ralplan is the consensus-planning command\n$autopilot build it', skills: ['autopilot'] },
|
|
@@ -964,7 +967,7 @@ describe('keyword input classification direct grammar', () => {
|
|
|
964
967
|
{ text: 'For instance: manual mode is slower。 Use autopilot mode.', skills: ['autopilot'] },
|
|
965
968
|
{ text: 'use $ralplan is the workflow command; autopilot mode is its alias; $team execute it', skills: ['team'] },
|
|
966
969
|
{ text: 'use $ralplan is the workflow command; autopilot mode is documented in the guide; $team execute it', skills: ['team'] },
|
|
967
|
-
{ text: 'use $ralplan is the workflow command; autopilot mode is workflow documentation; use $
|
|
970
|
+
{ text: 'use $ralplan is the workflow command; autopilot mode is workflow documentation; use $ultragoal execute it', skills: ['ultragoal'] },
|
|
968
971
|
{ text: `use $ralplan is the workflow command; use${' '.repeat(161)}$autopilot build it`, skills: ['autopilot'] },
|
|
969
972
|
{ text: 'use $ralplan is the consensus-planning command! run $autopilot', skills: ['autopilot'] },
|
|
970
973
|
{ text: 'use $ralplan is the consensus-planning command? run $autopilot', skills: ['autopilot'] },
|
|
@@ -1093,7 +1096,9 @@ describe('keyword input classification direct grammar', () => {
|
|
|
1093
1096
|
for (const testCase of [
|
|
1094
1097
|
{ text: 'Use autopilot mode.', skills: ['autopilot'] },
|
|
1095
1098
|
{ text: 'List files and use autopilot mode.', skills: ['autopilot'] },
|
|
1096
|
-
|
|
1099
|
+
// "don't stop" was an implicit ralph trigger. Ralph's keyword surface is retired, so the phrase
|
|
1100
|
+
// must no longer activate any workflow - a bare English phrase should never start one.
|
|
1101
|
+
{ text: "No, don't stop.", skills: [] },
|
|
1097
1102
|
{ text: 'Do not use deep interview, but use autopilot mode.', skills: ['autopilot'] },
|
|
1098
1103
|
{ text: 'Do not use deep interview but use autopilot mode.', skills: ['autopilot'] },
|
|
1099
1104
|
{ text: 'Do not use deep interview but instead use autopilot mode.', skills: ['autopilot'] },
|
|
@@ -1377,12 +1382,12 @@ describe('keyword input classification direct grammar', () => {
|
|
|
1377
1382
|
],
|
|
1378
1383
|
},
|
|
1379
1384
|
{
|
|
1380
|
-
|
|
1385
|
+
// $ulw is retired, so it is no longer a candidate at all; $team alone carries the block.
|
|
1386
|
+
text: '$team ship this',
|
|
1381
1387
|
reservedInput: null,
|
|
1382
|
-
skills: ['
|
|
1388
|
+
skills: ['team'],
|
|
1383
1389
|
candidates: [
|
|
1384
|
-
{ rawKeyword: '$
|
|
1385
|
-
{ rawKeyword: '$ulw', reasons: [] },
|
|
1390
|
+
{ rawKeyword: '$team', reasons: [] },
|
|
1386
1391
|
],
|
|
1387
1392
|
},
|
|
1388
1393
|
{
|
|
@@ -1659,11 +1664,12 @@ describe('explicit skill-name invocation requirement', () => {
|
|
|
1659
1664
|
it('does not trigger ralplan from bare skill-name usage', () => {
|
|
1660
1665
|
assert.equal(detectPrimaryKeyword('please do ralplan first'), null);
|
|
1661
1666
|
});
|
|
1662
|
-
it('
|
|
1663
|
-
const
|
|
1664
|
-
assert.
|
|
1665
|
-
assert.equal(
|
|
1666
|
-
assert.
|
|
1667
|
+
it('treats removed prometheus-strict as sunset stub', () => {
|
|
1668
|
+
const c = classifyKeywordInput('please run $prometheus-strict before implementation');
|
|
1669
|
+
assert.equal(c.matches.length, 0);
|
|
1670
|
+
assert.equal(c.removedMatches.length, 1);
|
|
1671
|
+
assert.match(c.removedMatches[0].message, /removed/i);
|
|
1672
|
+
assert.match(c.removedMatches[0].message, /use/i);
|
|
1667
1673
|
assert.equal(detectPrimaryKeyword('please use prometheus-strict planning here'), null);
|
|
1668
1674
|
});
|
|
1669
1675
|
});
|
|
@@ -1685,7 +1691,6 @@ describe('keyword registry coverage', () => {
|
|
|
1685
1691
|
assert.ok(registryKeywords.has('wiki lint'));
|
|
1686
1692
|
assert.ok(registryKeywords.has('$autoresearch'));
|
|
1687
1693
|
assert.ok(registryKeywords.has('$ultragoal'));
|
|
1688
|
-
assert.ok(registryKeywords.has('$prometheus-strict'));
|
|
1689
1694
|
assert.ok(registryKeywords.has('ultragoal'));
|
|
1690
1695
|
assert.ok(registryKeywords.has('autopilot'));
|
|
1691
1696
|
});
|
|
@@ -1794,6 +1799,54 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
1794
1799
|
await rm(root, { recursive: true, force: true });
|
|
1795
1800
|
}
|
|
1796
1801
|
});
|
|
1802
|
+
it('#3463: starts fresh native Autopilot even when receipt verification is unavailable (transition is reachable via user-authorized handoff)', async () => {
|
|
1803
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-autopilot-preflight-'));
|
|
1804
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1805
|
+
try {
|
|
1806
|
+
const result = await recordSkillActivation({
|
|
1807
|
+
stateDir,
|
|
1808
|
+
sourceCwd: cwd,
|
|
1809
|
+
text: '$autopilot implement the task',
|
|
1810
|
+
sessionId: 'sess-autopilot-preflight',
|
|
1811
|
+
nowIso: '2026-07-23T00:00:00.000Z',
|
|
1812
|
+
});
|
|
1813
|
+
// The preflight no longer blocks; autopilot starts normally.
|
|
1814
|
+
assert.equal(result?.active, true);
|
|
1815
|
+
assert.equal(result?.skill, 'autopilot');
|
|
1816
|
+
}
|
|
1817
|
+
finally {
|
|
1818
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1819
|
+
}
|
|
1820
|
+
});
|
|
1821
|
+
it('#3463: continues an active native Autopilot session when receipt verification is unavailable', async () => {
|
|
1822
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-active-autopilot-preflight-'));
|
|
1823
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
1824
|
+
const sessionId = 'sess-active-autopilot-preflight';
|
|
1825
|
+
const sessionDir = join(stateDir, 'sessions', sessionId);
|
|
1826
|
+
const statePath = join(sessionDir, SKILL_ACTIVE_STATE_FILE);
|
|
1827
|
+
const modePath = join(sessionDir, 'autopilot-state.json');
|
|
1828
|
+
const rawState = '{"version":1,"active":true,"skill":"autopilot","keyword":"$autopilot","phase":"ralplan","activated_at":"2026-07-22T00:00:00.000Z","updated_at":"2026-07-22T00:00:00.000Z","source":"keyword-detector","session_id":"sess-active-autopilot-preflight","metadata":{"preserve":true},"active_skills":[{"skill":"autopilot","active":true,"phase":"ralplan","session_id":"sess-active-autopilot-preflight"}]}\n';
|
|
1829
|
+
const rawMode = '{"active":true,"mode":"autopilot","current_phase":"ralplan","session_id":"sess-active-autopilot-preflight","metadata":{"preserve":true},"handoff_artifacts":{"ralplan":{"path":".omx/plans/existing.md"}}}\n';
|
|
1830
|
+
try {
|
|
1831
|
+
await mkdir(sessionDir, { recursive: true });
|
|
1832
|
+
await writeFile(statePath, rawState);
|
|
1833
|
+
await writeFile(modePath, rawMode);
|
|
1834
|
+
const result = await recordSkillActivation({
|
|
1835
|
+
stateDir,
|
|
1836
|
+
sourceCwd: cwd,
|
|
1837
|
+
text: '$autopilot continue',
|
|
1838
|
+
sessionId,
|
|
1839
|
+
nowIso: '2026-07-23T00:00:00.000Z',
|
|
1840
|
+
});
|
|
1841
|
+
// #3463: without the preflight block, the existing autopilot is
|
|
1842
|
+
// continued normally (no longer byte-preserved by the dead-end guard).
|
|
1843
|
+
assert.equal(result?.active, true);
|
|
1844
|
+
assert.equal(result?.phase, 'ralplan');
|
|
1845
|
+
}
|
|
1846
|
+
finally {
|
|
1847
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1848
|
+
}
|
|
1849
|
+
});
|
|
1797
1850
|
it('writes skill-active-state.json with deep-interview phase when autopilot keyword activates', async () => {
|
|
1798
1851
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-'));
|
|
1799
1852
|
const stateDir = join(cwd, '.omx', 'state');
|
|
@@ -1852,15 +1905,6 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
1852
1905
|
},
|
|
1853
1906
|
deep_interview: null,
|
|
1854
1907
|
ralplan: null,
|
|
1855
|
-
ralplan_consensus_gate: {
|
|
1856
|
-
required: true,
|
|
1857
|
-
sequence: ['architect-review', 'critic-review'],
|
|
1858
|
-
planning_artifacts_are_not_consensus: true,
|
|
1859
|
-
required_review_roles: ['architect', 'critic'],
|
|
1860
|
-
ralplan_architect_review: null,
|
|
1861
|
-
ralplan_critic_review: null,
|
|
1862
|
-
complete: false,
|
|
1863
|
-
},
|
|
1864
1908
|
ultragoal: null,
|
|
1865
1909
|
code_review: null,
|
|
1866
1910
|
ultraqa: null,
|
|
@@ -1888,133 +1932,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
1888
1932
|
await rm(codexHome, { recursive: true, force: true });
|
|
1889
1933
|
}
|
|
1890
1934
|
});
|
|
1891
|
-
it('
|
|
1892
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-supervised-gate-'));
|
|
1893
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
1894
|
-
try {
|
|
1895
|
-
await mkdir(stateDir, { recursive: true });
|
|
1896
|
-
// Activate Autopilot: seeds autopilot-state.json at current_phase=deep-interview
|
|
1897
|
-
// with deep_interview_gate.status="required" (gate not satisfied).
|
|
1898
|
-
const activated = await recordSkillActivation({
|
|
1899
|
-
stateDir,
|
|
1900
|
-
text: 'please run $autopilot',
|
|
1901
|
-
sessionId: 'sess-gate',
|
|
1902
|
-
threadId: 'thread-gate',
|
|
1903
|
-
turnId: 'turn-1',
|
|
1904
|
-
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1905
|
-
});
|
|
1906
|
-
assert.equal(activated?.phase, 'deep-interview');
|
|
1907
|
-
const autopilotStatePath = join(stateDir, 'sessions', 'sess-gate', 'autopilot-state.json');
|
|
1908
|
-
const beforeAdvance = JSON.parse(await readFile(autopilotStatePath, 'utf-8'));
|
|
1909
|
-
assert.equal(beforeAdvance.current_phase, 'deep-interview');
|
|
1910
|
-
// A bare `$ralplan` keyword handoff must not advance current_phase across the
|
|
1911
|
-
// deep-interview -> ralplan gate while the gate is unsatisfied. The keyword
|
|
1912
|
-
// path now defers to the same gate as the state_write backend.
|
|
1913
|
-
const denied = await recordSkillActivation({
|
|
1914
|
-
stateDir,
|
|
1915
|
-
text: 'continue with $ralplan',
|
|
1916
|
-
sessionId: 'sess-gate',
|
|
1917
|
-
threadId: 'thread-gate',
|
|
1918
|
-
turnId: 'turn-2',
|
|
1919
|
-
nowIso: '2026-02-25T00:01:00.000Z',
|
|
1920
|
-
});
|
|
1921
|
-
const afterAdvance = JSON.parse(await readFile(autopilotStatePath, 'utf-8'));
|
|
1922
|
-
assert.equal(afterAdvance.current_phase, 'deep-interview', 'keyword handoff must not skip the deep-interview gate');
|
|
1923
|
-
// The visible canonical skill-active state must stay aligned with the held
|
|
1924
|
-
// detail phase (no drift to ralplan) — both the returned state and the
|
|
1925
|
-
// persisted skill-active-state.json mirror.
|
|
1926
|
-
assert.equal(denied?.phase, 'deep-interview');
|
|
1927
|
-
assert.deepEqual(denied?.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'deep-interview']]);
|
|
1928
|
-
const canonical = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-gate', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
|
|
1929
|
-
assert.equal(canonical.phase, 'deep-interview');
|
|
1930
|
-
assert.deepEqual(canonical.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'deep-interview']]);
|
|
1931
|
-
}
|
|
1932
|
-
finally {
|
|
1933
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1934
|
-
}
|
|
1935
|
-
});
|
|
1936
|
-
it('does not let a keyword jump ahead past a planning gate (forward skip)', async () => {
|
|
1937
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-skip-ahead-'));
|
|
1938
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
1939
|
-
try {
|
|
1940
|
-
await mkdir(stateDir, { recursive: true });
|
|
1941
|
-
await recordSkillActivation({
|
|
1942
|
-
stateDir,
|
|
1943
|
-
text: 'please run $autopilot',
|
|
1944
|
-
sessionId: 'sess-skip',
|
|
1945
|
-
threadId: 'thread-skip',
|
|
1946
|
-
turnId: 'turn-1',
|
|
1947
|
-
nowIso: '2026-02-25T00:00:00.000Z',
|
|
1948
|
-
});
|
|
1949
|
-
// `$ultragoal` while in deep-interview skips the ralplan gate entirely; the
|
|
1950
|
-
// keyword handoff must hold the current phase rather than jump ahead.
|
|
1951
|
-
const result = await recordSkillActivation({
|
|
1952
|
-
stateDir,
|
|
1953
|
-
text: 'jump straight to $ultragoal',
|
|
1954
|
-
sessionId: 'sess-skip',
|
|
1955
|
-
threadId: 'thread-skip',
|
|
1956
|
-
turnId: 'turn-2',
|
|
1957
|
-
nowIso: '2026-02-25T00:01:00.000Z',
|
|
1958
|
-
});
|
|
1959
|
-
const autopilotState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-skip', 'autopilot-state.json'), 'utf-8'));
|
|
1960
|
-
assert.equal(autopilotState.current_phase, 'deep-interview', 'forward skip must be held');
|
|
1961
|
-
// skill-active phase is kept in sync with the held autopilot phase.
|
|
1962
|
-
assert.equal(result?.phase, 'deep-interview');
|
|
1963
|
-
}
|
|
1964
|
-
finally {
|
|
1965
|
-
await rm(cwd, { recursive: true, force: true });
|
|
1966
|
-
}
|
|
1967
|
-
});
|
|
1968
|
-
it('does not advance or drift canonical state past an unsatisfied ralplan -> ultragoal gate', async () => {
|
|
1969
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-gate-'));
|
|
1970
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
1971
|
-
const sessionId = 'sess-ralplan-gate';
|
|
1972
|
-
try {
|
|
1973
|
-
await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
|
|
1974
|
-
// Supervised Autopilot already in ralplan, with no ralplan consensus evidence
|
|
1975
|
-
// (the ralplan -> ultragoal gate is unsatisfied).
|
|
1976
|
-
await writeFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), JSON.stringify({
|
|
1977
|
-
version: 1,
|
|
1978
|
-
active: true,
|
|
1979
|
-
skill: 'autopilot',
|
|
1980
|
-
keyword: '$autopilot',
|
|
1981
|
-
phase: 'ralplan',
|
|
1982
|
-
source: 'keyword-detector',
|
|
1983
|
-
session_id: sessionId,
|
|
1984
|
-
active_skills: [{ skill: 'autopilot', phase: 'ralplan', active: true, session_id: sessionId }],
|
|
1985
|
-
}, null, 2));
|
|
1986
|
-
const autopilotStatePath = join(stateDir, 'sessions', sessionId, 'autopilot-state.json');
|
|
1987
|
-
await writeFile(autopilotStatePath, JSON.stringify({ active: true, mode: 'autopilot', current_phase: 'ralplan', session_id: sessionId }, null, 2));
|
|
1988
|
-
await writeFile(join(stateDir, 'sessions', sessionId, 'ralplan-state.json'), JSON.stringify({
|
|
1989
|
-
active: true,
|
|
1990
|
-
mode: 'ralplan',
|
|
1991
|
-
current_phase: 'planning',
|
|
1992
|
-
session_id: sessionId,
|
|
1993
|
-
}, null, 2));
|
|
1994
|
-
const denied = await recordSkillActivation({
|
|
1995
|
-
stateDir,
|
|
1996
|
-
text: 'advance to $ultragoal',
|
|
1997
|
-
sessionId,
|
|
1998
|
-
threadId: 'thread-ralplan-gate',
|
|
1999
|
-
turnId: 'turn-ralplan-gate',
|
|
2000
|
-
nowIso: '2026-02-25T00:01:00.000Z',
|
|
2001
|
-
});
|
|
2002
|
-
const afterAdvance = JSON.parse(await readFile(autopilotStatePath, 'utf-8'));
|
|
2003
|
-
assert.equal(afterAdvance.current_phase, 'ralplan', 'keyword handoff must not skip the ralplan -> ultragoal gate');
|
|
2004
|
-
assert.equal(denied?.phase, 'ralplan');
|
|
2005
|
-
assert.deepEqual(denied?.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ralplan']]);
|
|
2006
|
-
const ralplanState = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, 'ralplan-state.json'), 'utf-8'));
|
|
2007
|
-
assert.equal(ralplanState.active, true, 'blocked gate must not auto-complete ralplan state');
|
|
2008
|
-
assert.equal(ralplanState.current_phase, 'planning', 'blocked gate must not advance ralplan state');
|
|
2009
|
-
const canonical = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), 'utf-8'));
|
|
2010
|
-
assert.equal(canonical.phase, 'ralplan');
|
|
2011
|
-
assert.deepEqual(canonical.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ralplan']]);
|
|
2012
|
-
}
|
|
2013
|
-
finally {
|
|
2014
|
-
await rm(cwd, { recursive: true, force: true });
|
|
2015
|
-
}
|
|
2016
|
-
});
|
|
2017
|
-
it('does not let an implementation-phase keyword skip the code-review gate to ultraqa', async () => {
|
|
1935
|
+
it('permits an implementation-phase keyword skip to ultraqa with a code-review advisory', async () => {
|
|
2018
1936
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ultraqa-skip-'));
|
|
2019
1937
|
const stateDir = join(cwd, '.omx', 'state');
|
|
2020
1938
|
const sessionId = 'sess-ultraqa-skip';
|
|
@@ -2034,7 +1952,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2034
1952
|
}, null, 2));
|
|
2035
1953
|
const autopilotStatePath = join(stateDir, 'sessions', sessionId, 'autopilot-state.json');
|
|
2036
1954
|
await writeFile(autopilotStatePath, JSON.stringify({ active: true, mode: 'autopilot', current_phase: 'ultragoal', session_id: sessionId }, null, 2));
|
|
2037
|
-
const
|
|
1955
|
+
const advanced = await recordSkillActivation({
|
|
2038
1956
|
stateDir,
|
|
2039
1957
|
text: 'run $ultraqa now',
|
|
2040
1958
|
sessionId,
|
|
@@ -2043,12 +1961,18 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2043
1961
|
nowIso: '2026-02-25T00:01:00.000Z',
|
|
2044
1962
|
});
|
|
2045
1963
|
const afterAdvance = JSON.parse(await readFile(autopilotStatePath, 'utf-8'));
|
|
2046
|
-
assert.equal(afterAdvance.current_phase, '
|
|
2047
|
-
assert.equal(
|
|
2048
|
-
|
|
1964
|
+
assert.equal(afterAdvance.current_phase, 'ultraqa');
|
|
1965
|
+
assert.equal(advanced?.phase, 'ultraqa');
|
|
1966
|
+
const advisory = advanced?.advisory;
|
|
1967
|
+
assert.equal(advisory?.skippedGate, 'code-review');
|
|
1968
|
+
assert.ok(advisory?.missingEvidence);
|
|
1969
|
+
assert.equal(afterAdvance.skipped_gates?.length, 1);
|
|
1970
|
+
assert.equal(afterAdvance.skipped_gates?.[0]?.skippedGate, 'code-review');
|
|
1971
|
+
assert.ok(afterAdvance.skipped_gates?.[0]?.missingEvidence);
|
|
1972
|
+
assert.deepEqual(advanced?.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ultraqa']]);
|
|
2049
1973
|
const canonical = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), 'utf-8'));
|
|
2050
|
-
assert.equal(canonical.phase, '
|
|
2051
|
-
assert.deepEqual(canonical.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', '
|
|
1974
|
+
assert.equal(canonical.phase, 'ultraqa');
|
|
1975
|
+
assert.deepEqual(canonical.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ultraqa']]);
|
|
2052
1976
|
}
|
|
2053
1977
|
finally {
|
|
2054
1978
|
await rm(cwd, { recursive: true, force: true });
|
|
@@ -2412,7 +2336,6 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2412
2336
|
},
|
|
2413
2337
|
state: {
|
|
2414
2338
|
handoff_artifacts: {
|
|
2415
|
-
ralplan_consensus_gate: { complete: false },
|
|
2416
2339
|
code_review: { verdict: 'stale' },
|
|
2417
2340
|
},
|
|
2418
2341
|
},
|
|
@@ -2456,15 +2379,6 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2456
2379
|
},
|
|
2457
2380
|
deep_interview: null,
|
|
2458
2381
|
ralplan: null,
|
|
2459
|
-
ralplan_consensus_gate: {
|
|
2460
|
-
required: true,
|
|
2461
|
-
sequence: ['architect-review', 'critic-review'],
|
|
2462
|
-
planning_artifacts_are_not_consensus: true,
|
|
2463
|
-
required_review_roles: ['architect', 'critic'],
|
|
2464
|
-
ralplan_architect_review: null,
|
|
2465
|
-
ralplan_critic_review: null,
|
|
2466
|
-
complete: false,
|
|
2467
|
-
},
|
|
2468
2382
|
ultragoal: null,
|
|
2469
2383
|
code_review: null,
|
|
2470
2384
|
ultraqa: null,
|
|
@@ -2539,29 +2453,29 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2539
2453
|
});
|
|
2540
2454
|
const result = await recordSkillActivation({
|
|
2541
2455
|
stateDir,
|
|
2542
|
-
text: '$
|
|
2456
|
+
text: '$ultragoal continue verification',
|
|
2543
2457
|
sessionId: 'sess-overlap',
|
|
2544
2458
|
threadId: 'thread-overlap',
|
|
2545
2459
|
turnId: 'turn-2',
|
|
2546
2460
|
nowIso: '2026-02-26T00:05:00.000Z',
|
|
2547
2461
|
});
|
|
2548
2462
|
assert.ok(result);
|
|
2549
|
-
assert.deepEqual(result.active_skills?.map((entry) => entry.skill), ['team', '
|
|
2463
|
+
assert.deepEqual(result.active_skills?.map((entry) => entry.skill), ['team', 'ultragoal']);
|
|
2550
2464
|
const persisted = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-overlap', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
|
|
2551
|
-
assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team', '
|
|
2465
|
+
assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team', 'ultragoal']);
|
|
2552
2466
|
}
|
|
2553
2467
|
finally {
|
|
2554
2468
|
await rm(cwd, { recursive: true, force: true });
|
|
2555
2469
|
}
|
|
2556
2470
|
});
|
|
2557
|
-
it('keeps a session-scoped
|
|
2471
|
+
it('keeps a session-scoped Ultragoal activation out of the root canonical state for other sessions', async () => {
|
|
2558
2472
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-ralph-isolation-'));
|
|
2559
2473
|
const stateDir = join(cwd, '.omx', 'state');
|
|
2560
2474
|
try {
|
|
2561
2475
|
await mkdir(stateDir, { recursive: true });
|
|
2562
2476
|
const result = await recordSkillActivation({
|
|
2563
2477
|
stateDir,
|
|
2564
|
-
text: '$
|
|
2478
|
+
text: '$ultragoal continue verification',
|
|
2565
2479
|
sessionId: 'sess-ralph-a',
|
|
2566
2480
|
threadId: 'thread-ralph-a',
|
|
2567
2481
|
turnId: 'turn-ralph-a',
|
|
@@ -2572,7 +2486,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2572
2486
|
assert.equal(existsSync(rootSkillStatePath), false, 'session-scoped prompt activation should not create a root canonical skill state');
|
|
2573
2487
|
const sessionScopedSkillState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ralph-a', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
|
|
2574
2488
|
assert.deepEqual(sessionScopedSkillState.active_skills, [{
|
|
2575
|
-
skill: '
|
|
2489
|
+
skill: 'ultragoal',
|
|
2576
2490
|
phase: 'planning',
|
|
2577
2491
|
active: true,
|
|
2578
2492
|
activated_at: '2026-04-14T00:00:00.000Z',
|
|
@@ -2586,34 +2500,49 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2586
2500
|
await rm(cwd, { recursive: true, force: true });
|
|
2587
2501
|
}
|
|
2588
2502
|
});
|
|
2589
|
-
it('
|
|
2590
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-
|
|
2503
|
+
it('#3463: preserves an active Autopilot mode when canonical skill state is missing', async () => {
|
|
2504
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-autopilot-mode-drift-'));
|
|
2591
2505
|
const stateDir = join(cwd, '.omx', 'state');
|
|
2506
|
+
const sessionId = 'sess-autopilot-mode-drift';
|
|
2507
|
+
const modePath = join(stateDir, 'sessions', sessionId, 'autopilot-state.json');
|
|
2592
2508
|
try {
|
|
2593
|
-
await mkdir(stateDir, { recursive: true });
|
|
2594
|
-
|
|
2509
|
+
await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
|
|
2510
|
+
const rawMode = '{"active":true,"mode":"autopilot","current_phase":"ralplan","session_id":"sess-autopilot-mode-drift","marker":"preserve-active-mode","metadata":{"nested":{"keep":true}}}\n';
|
|
2511
|
+
await writeFile(modePath, rawMode);
|
|
2512
|
+
const result = await recordSkillActivation({
|
|
2595
2513
|
stateDir,
|
|
2596
|
-
text: '$
|
|
2597
|
-
sessionId
|
|
2598
|
-
|
|
2599
|
-
turnId: 'turn-1',
|
|
2600
|
-
nowIso: '2026-02-26T00:00:00.000Z',
|
|
2514
|
+
text: '$autopilot continue',
|
|
2515
|
+
sessionId,
|
|
2516
|
+
nowIso: '2026-07-23T00:00:00.000Z',
|
|
2601
2517
|
});
|
|
2602
|
-
|
|
2518
|
+
// #3463: without the preflight block, the existing autopilot session
|
|
2519
|
+
// at ralplan is detected as active and continued (cancelled/restarted
|
|
2520
|
+
// path) rather than being hard-preserved.
|
|
2521
|
+
assert.equal(result?.skill, 'autopilot');
|
|
2522
|
+
}
|
|
2523
|
+
finally {
|
|
2524
|
+
await rm(cwd, { recursive: true, force: true });
|
|
2525
|
+
}
|
|
2526
|
+
});
|
|
2527
|
+
it('#3463: no longer denies autopilot when fresh Autopilot preflight was previously unavailable', async () => {
|
|
2528
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-autopilot-preflight-'));
|
|
2529
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
2530
|
+
const sessionId = 'sess-ralplan-autopilot-preflight';
|
|
2531
|
+
const statePath = join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE);
|
|
2532
|
+
const rawState = '{"version":1,"active":true,"skill":"ralplan","keyword":"$ralplan","phase":"planning","session_id":"sess-ralplan-autopilot-preflight","active_skills":[{"skill":"ralplan","phase":"planning","active":true,"session_id":"sess-ralplan-autopilot-preflight"}]}';
|
|
2533
|
+
try {
|
|
2534
|
+
await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
|
|
2535
|
+
await writeFile(statePath, rawState);
|
|
2536
|
+
const result = await recordSkillActivation({
|
|
2603
2537
|
stateDir,
|
|
2604
2538
|
text: '$autopilot do it too',
|
|
2605
|
-
sessionId
|
|
2606
|
-
|
|
2607
|
-
turnId: 'turn-2',
|
|
2608
|
-
nowIso: '2026-02-26T00:05:00.000Z',
|
|
2539
|
+
sessionId,
|
|
2540
|
+
nowIso: '2026-07-23T00:00:00.000Z',
|
|
2609
2541
|
});
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
assert.
|
|
2614
|
-
const persisted = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-deny', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
|
|
2615
|
-
assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team']);
|
|
2616
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-deny', 'autopilot-state.json')), false);
|
|
2542
|
+
// #3463: The preflight no longer hard-denies the transition. The
|
|
2543
|
+
// ralplan session is active, so autopilot may be blocked by workflow
|
|
2544
|
+
// overlap rules instead, but NOT by documented_host_consensus_receipt.
|
|
2545
|
+
assert.notEqual(result?.transition_error, 'documented_host_consensus_receipt_unavailable');
|
|
2617
2546
|
}
|
|
2618
2547
|
finally {
|
|
2619
2548
|
await rm(cwd, { recursive: true, force: true });
|
|
@@ -2639,46 +2568,19 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2639
2568
|
session_id: 'sess-visible',
|
|
2640
2569
|
active_skills: [
|
|
2641
2570
|
{ skill: 'team', phase: 'running', active: true },
|
|
2642
|
-
{ skill: '
|
|
2571
|
+
{ skill: 'ultraqa', phase: 'executing', active: true, session_id: 'sess-visible' },
|
|
2643
2572
|
],
|
|
2644
2573
|
}, null, 2));
|
|
2645
2574
|
const allowed = await recordSkillActivation({
|
|
2646
2575
|
stateDir,
|
|
2647
|
-
text: '$
|
|
2576
|
+
text: '$autoresearch continue',
|
|
2648
2577
|
sessionId: 'sess-visible',
|
|
2649
2578
|
nowIso: '2026-04-10T00:00:00.000Z',
|
|
2650
2579
|
});
|
|
2651
2580
|
assert.equal(allowed?.transition_error, undefined);
|
|
2652
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-visible', '
|
|
2581
|
+
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-visible', 'autoresearch-state.json')), true);
|
|
2653
2582
|
const persisted = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-visible', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
|
|
2654
|
-
assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team', '
|
|
2655
|
-
}
|
|
2656
|
-
finally {
|
|
2657
|
-
await rm(cwd, { recursive: true, force: true });
|
|
2658
|
-
}
|
|
2659
|
-
});
|
|
2660
|
-
it('activates ultrawork mode from the Korean keyboard typo for ulw', async () => {
|
|
2661
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-ulw-ko-'));
|
|
2662
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
2663
|
-
try {
|
|
2664
|
-
await mkdir(stateDir, { recursive: true });
|
|
2665
|
-
const result = await recordSkillActivation({
|
|
2666
|
-
stateDir,
|
|
2667
|
-
text: 'ㅕㅣㅈ로 병렬 처리해줘',
|
|
2668
|
-
sessionId: 'sess-ulw-ko',
|
|
2669
|
-
threadId: 'thread-ulw-ko',
|
|
2670
|
-
turnId: 'turn-ulw-ko',
|
|
2671
|
-
nowIso: '2026-04-21T00:00:00.000Z',
|
|
2672
|
-
});
|
|
2673
|
-
assert.ok(result);
|
|
2674
|
-
assert.equal(result.skill, 'ultrawork');
|
|
2675
|
-
assert.equal(result.keyword, 'ulw');
|
|
2676
|
-
assert.equal(result.initialized_mode, 'ultrawork');
|
|
2677
|
-
assert.equal(result.initialized_state_path, '.omx/state/sessions/sess-ulw-ko/ultrawork-state.json');
|
|
2678
|
-
const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ulw-ko', 'ultrawork-state.json'), 'utf-8'));
|
|
2679
|
-
assert.equal(modeState.mode, 'ultrawork');
|
|
2680
|
-
assert.equal(modeState.active, true);
|
|
2681
|
-
assert.equal(modeState.current_phase, 'planning');
|
|
2583
|
+
assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team', 'ultraqa', 'autoresearch']);
|
|
2682
2584
|
}
|
|
2683
2585
|
finally {
|
|
2684
2586
|
await rm(cwd, { recursive: true, force: true });
|
|
@@ -2842,6 +2744,35 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2842
2744
|
await rm(cwd, { recursive: true, force: true });
|
|
2843
2745
|
}
|
|
2844
2746
|
});
|
|
2747
|
+
it('does not reactivate a neutralized routing-only Ralplan seed on plain continuation', async () => {
|
|
2748
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-neutralized-ralplan-'));
|
|
2749
|
+
const stateDir = join(cwd, '.omx', 'state');
|
|
2750
|
+
const sessionId = 'sess-neutralized';
|
|
2751
|
+
const previousSessionId = process.env.OMX_SESSION_ID;
|
|
2752
|
+
try {
|
|
2753
|
+
process.env.OMX_SESSION_ID = sessionId;
|
|
2754
|
+
await mkdir(stateDir, { recursive: true });
|
|
2755
|
+
await writeFile(join(stateDir, 'session.json'), JSON.stringify({ session_id: sessionId, cwd, state_root: stateDir }));
|
|
2756
|
+
assert.ok(await recordSkillActivation({ stateDir, sourceCwd: cwd, text: '$ralplan tighten the plan', sessionId, nowIso: '2026-02-25T00:00:00.000Z' }));
|
|
2757
|
+
const sessionDir = join(stateDir, 'sessions', sessionId);
|
|
2758
|
+
const ralplanPath = join(sessionDir, 'ralplan-state.json');
|
|
2759
|
+
const skillPath = join(sessionDir, SKILL_ACTIVE_STATE_FILE);
|
|
2760
|
+
const [ralplanBefore, skillBefore] = await Promise.all([readFile(ralplanPath), readFile(skillPath)]);
|
|
2761
|
+
assert.equal(await neutralizeOwnedRoutingRalplan(cwd), true);
|
|
2762
|
+
assert.deepEqual(await readActiveWorkflowModes(cwd, sessionId), []);
|
|
2763
|
+
assert.equal(await recordSkillActivation({ stateDir, sourceCwd: cwd, text: 'continue', sessionId, nowIso: '2026-02-25T00:00:01.000Z' }), null);
|
|
2764
|
+
assert.deepEqual(await readFile(ralplanPath), ralplanBefore);
|
|
2765
|
+
assert.deepEqual(await readFile(skillPath), skillBefore);
|
|
2766
|
+
assert.equal((await readSkillActiveState(skillPath))?.active, false);
|
|
2767
|
+
}
|
|
2768
|
+
finally {
|
|
2769
|
+
if (previousSessionId === undefined)
|
|
2770
|
+
delete process.env.OMX_SESSION_ID;
|
|
2771
|
+
else
|
|
2772
|
+
process.env.OMX_SESSION_ID = previousSessionId;
|
|
2773
|
+
await rm(cwd, { recursive: true, force: true });
|
|
2774
|
+
}
|
|
2775
|
+
});
|
|
2845
2776
|
it('auto-completes deep-interview during allowlisted forward handoff', async () => {
|
|
2846
2777
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-handoff-'));
|
|
2847
2778
|
const stateDir = join(cwd, '.omx', 'state');
|
|
@@ -2892,37 +2823,6 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2892
2823
|
await rm(cwd, { recursive: true, force: true });
|
|
2893
2824
|
}
|
|
2894
2825
|
});
|
|
2895
|
-
it('denies ralplan handoff from deep-interview without completion or explicit skip evidence', async () => {
|
|
2896
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-handoff-'));
|
|
2897
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
2898
|
-
try {
|
|
2899
|
-
await mkdir(join(stateDir, 'sessions', 'sess-ralplan-handoff'), { recursive: true });
|
|
2900
|
-
await writeFile(join(stateDir, 'sessions', 'sess-ralplan-handoff', SKILL_ACTIVE_STATE_FILE), JSON.stringify({
|
|
2901
|
-
version: 1,
|
|
2902
|
-
active: true,
|
|
2903
|
-
skill: 'deep-interview',
|
|
2904
|
-
phase: 'planning',
|
|
2905
|
-
session_id: 'sess-ralplan-handoff',
|
|
2906
|
-
active_skills: [{ skill: 'deep-interview', phase: 'planning', active: true, session_id: 'sess-ralplan-handoff' }],
|
|
2907
|
-
}, null, 2));
|
|
2908
|
-
await writeFile(join(stateDir, 'sessions', 'sess-ralplan-handoff', 'deep-interview-state.json'), JSON.stringify({ active: true, mode: 'deep-interview', current_phase: 'intent-first' }, null, 2));
|
|
2909
|
-
const result = await recordSkillActivation({
|
|
2910
|
-
stateDir,
|
|
2911
|
-
text: '$ralplan implement the approved contract',
|
|
2912
|
-
sessionId: 'sess-ralplan-handoff',
|
|
2913
|
-
nowIso: '2026-04-10T00:00:00.000Z',
|
|
2914
|
-
});
|
|
2915
|
-
assert.equal(result?.skill, 'deep-interview');
|
|
2916
|
-
assert.match(String(result?.transition_error), /missing deep-interview completion\/skip gate/i);
|
|
2917
|
-
const preserved = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ralplan-handoff', 'deep-interview-state.json'), 'utf-8'));
|
|
2918
|
-
assert.equal(preserved.active, true);
|
|
2919
|
-
assert.equal(preserved.current_phase, 'intent-first');
|
|
2920
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-ralplan-handoff', 'ralplan-state.json')), false);
|
|
2921
|
-
}
|
|
2922
|
-
finally {
|
|
2923
|
-
await rm(cwd, { recursive: true, force: true });
|
|
2924
|
-
}
|
|
2925
|
-
});
|
|
2926
2826
|
it('allows ralplan handoff from deep-interview with a durable completion gate', async () => {
|
|
2927
2827
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-handoff-complete-'));
|
|
2928
2828
|
const stateDir = join(cwd, '.omx', 'state');
|
|
@@ -2969,7 +2869,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2969
2869
|
await mkdir(stateDir, { recursive: true });
|
|
2970
2870
|
const result = await recordSkillActivation({
|
|
2971
2871
|
stateDir,
|
|
2972
|
-
text: '$ralplan $team $
|
|
2872
|
+
text: '$ralplan $team $ultragoal ship this fix',
|
|
2973
2873
|
sessionId: 'sess-multi',
|
|
2974
2874
|
nowIso: '2026-04-10T00:00:00.000Z',
|
|
2975
2875
|
});
|
|
@@ -2977,10 +2877,10 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2977
2877
|
assert.equal(result?.transition_message, undefined);
|
|
2978
2878
|
assert.equal(result?.skill, 'ralplan');
|
|
2979
2879
|
assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ralplan']);
|
|
2980
|
-
assert.deepEqual(result?.deferred_skills, ['team', '
|
|
2880
|
+
assert.deepEqual(result?.deferred_skills, ['team', 'ultragoal']);
|
|
2981
2881
|
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-multi', 'ralplan-state.json')), true);
|
|
2982
2882
|
assert.equal(existsSync(join(stateDir, 'team-state.json')), false);
|
|
2983
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-multi', '
|
|
2883
|
+
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-multi', 'ultragoal-state.json')), false);
|
|
2984
2884
|
}
|
|
2985
2885
|
finally {
|
|
2986
2886
|
await rm(cwd, { recursive: true, force: true });
|
|
@@ -2993,22 +2893,22 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
2993
2893
|
await mkdir(stateDir, { recursive: true });
|
|
2994
2894
|
const result = await recordSkillActivation({
|
|
2995
2895
|
stateDir,
|
|
2996
|
-
text: '$
|
|
2896
|
+
text: '$ultragoal $ralplan continue',
|
|
2997
2897
|
sessionId: 'sess-priority',
|
|
2998
2898
|
nowIso: '2026-04-10T00:00:00.000Z',
|
|
2999
2899
|
});
|
|
3000
2900
|
assert.equal(result?.transition_error, undefined);
|
|
3001
2901
|
assert.equal(result?.skill, 'ralplan');
|
|
3002
2902
|
assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ralplan']);
|
|
3003
|
-
assert.deepEqual(result?.deferred_skills, ['
|
|
2903
|
+
assert.deepEqual(result?.deferred_skills, ['ultragoal']);
|
|
3004
2904
|
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-priority', 'ralplan-state.json')), true);
|
|
3005
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-priority', '
|
|
2905
|
+
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-priority', 'ultragoal-state.json')), false);
|
|
3006
2906
|
}
|
|
3007
2907
|
finally {
|
|
3008
2908
|
await rm(cwd, { recursive: true, force: true });
|
|
3009
2909
|
}
|
|
3010
2910
|
});
|
|
3011
|
-
it('seeds
|
|
2911
|
+
it('seeds session-keyed team state for team prompt-submit activation', async () => {
|
|
3012
2912
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-team-'));
|
|
3013
2913
|
const stateDir = join(cwd, '.omx', 'state');
|
|
3014
2914
|
try {
|
|
@@ -3022,8 +2922,8 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
3022
2922
|
assert.ok(result);
|
|
3023
2923
|
assert.equal(result.skill, 'team');
|
|
3024
2924
|
assert.equal(result.initialized_mode, 'team');
|
|
3025
|
-
assert.equal(result.initialized_state_path, '.omx/state/team-state.json');
|
|
3026
|
-
const modeState = JSON.parse(await readFile(join(stateDir, 'team-state.json'), 'utf-8'));
|
|
2925
|
+
assert.equal(result.initialized_state_path, '.omx/state/sessions/sess-team/team-state.json');
|
|
2926
|
+
const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-team', 'team-state.json'), 'utf-8'));
|
|
3027
2927
|
assert.equal(modeState.mode, 'team');
|
|
3028
2928
|
assert.equal(modeState.active, true);
|
|
3029
2929
|
assert.equal(modeState.current_phase, 'starting');
|
|
@@ -3062,14 +2962,14 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
3062
2962
|
await writeFile(join(cwd, '.omx', 'setup-scope.json'), JSON.stringify({ scope: 'project', teamMode: 'disabled' }, null, 2));
|
|
3063
2963
|
const result = await recordSkillActivation({
|
|
3064
2964
|
stateDir,
|
|
3065
|
-
text: '$team $
|
|
2965
|
+
text: '$team $ultragoal ship this fix',
|
|
3066
2966
|
sessionId: 'sess-team-disabled-primary',
|
|
3067
2967
|
nowIso: '2026-04-10T01:00:00.000Z',
|
|
3068
2968
|
});
|
|
3069
|
-
assert.equal(result?.skill, '
|
|
3070
|
-
assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['
|
|
2969
|
+
assert.equal(result?.skill, 'ultragoal');
|
|
2970
|
+
assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ultragoal']);
|
|
3071
2971
|
assert.equal(existsSync(join(stateDir, 'team-state.json')), false);
|
|
3072
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-team-disabled-primary', '
|
|
2972
|
+
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-team-disabled-primary', 'ultragoal-state.json')), true);
|
|
3073
2973
|
}
|
|
3074
2974
|
finally {
|
|
3075
2975
|
await rm(cwd, { recursive: true, force: true });
|
|
@@ -3084,13 +2984,13 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
3084
2984
|
await writeFile(join(cwd, '.omx', 'setup-scope.json'), JSON.stringify({ scope: 'project', teamMode: 'disabled' }, null, 2));
|
|
3085
2985
|
const result = await recordSkillActivation({
|
|
3086
2986
|
stateDir,
|
|
3087
|
-
text: '$ralplan $team $
|
|
2987
|
+
text: '$ralplan $team $ultragoal ship this fix',
|
|
3088
2988
|
sessionId: 'sess-team-disabled-deferred',
|
|
3089
2989
|
nowIso: '2026-04-10T00:00:00.000Z',
|
|
3090
2990
|
});
|
|
3091
2991
|
assert.equal(result?.skill, 'ralplan');
|
|
3092
2992
|
assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ralplan']);
|
|
3093
|
-
assert.deepEqual(result?.deferred_skills, ['
|
|
2993
|
+
assert.deepEqual(result?.deferred_skills, ['ultragoal']);
|
|
3094
2994
|
assert.equal(existsSync(join(stateDir, 'team-state.json')), false);
|
|
3095
2995
|
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-team-disabled-deferred', 'team-state.json')), false);
|
|
3096
2996
|
}
|
|
@@ -3098,12 +2998,12 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
3098
2998
|
await rm(cwd, { recursive: true, force: true });
|
|
3099
2999
|
}
|
|
3100
3000
|
});
|
|
3101
|
-
it('preserves active team
|
|
3001
|
+
it('preserves active session-keyed team state when $team is re-entered from prompt routing', async () => {
|
|
3102
3002
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-team-preserve-'));
|
|
3103
3003
|
const stateDir = join(cwd, '.omx', 'state');
|
|
3104
3004
|
try {
|
|
3105
|
-
await mkdir(stateDir, { recursive: true });
|
|
3106
|
-
await writeFile(join(stateDir, 'team-state.json'), JSON.stringify({
|
|
3005
|
+
await mkdir(join(stateDir, 'sessions', 'sess-team-preserve'), { recursive: true });
|
|
3006
|
+
await writeFile(join(stateDir, 'sessions', 'sess-team-preserve', 'team-state.json'), JSON.stringify({
|
|
3107
3007
|
active: true,
|
|
3108
3008
|
mode: 'team',
|
|
3109
3009
|
current_phase: 'team-verify',
|
|
@@ -3119,8 +3019,8 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
3119
3019
|
});
|
|
3120
3020
|
assert.ok(result);
|
|
3121
3021
|
assert.equal(result.initialized_mode, 'team');
|
|
3122
|
-
assert.equal(result.initialized_state_path, '.omx/state/team-state.json');
|
|
3123
|
-
const modeState = JSON.parse(await readFile(join(stateDir, 'team-state.json'), 'utf-8'));
|
|
3022
|
+
assert.equal(result.initialized_state_path, '.omx/state/sessions/sess-team-preserve/team-state.json');
|
|
3023
|
+
const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-team-preserve', 'team-state.json'), 'utf-8'));
|
|
3124
3024
|
assert.equal(modeState.mode, 'team');
|
|
3125
3025
|
assert.equal(modeState.active, true);
|
|
3126
3026
|
assert.equal(modeState.current_phase, 'team-verify');
|
|
@@ -3167,58 +3067,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
3167
3067
|
await rm(cwd, { recursive: true, force: true });
|
|
3168
3068
|
}
|
|
3169
3069
|
});
|
|
3170
|
-
it('
|
|
3171
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-ultragoal-handoff-'));
|
|
3172
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
3173
|
-
try {
|
|
3174
|
-
await mkdir(join(stateDir, 'sessions', 'sess-ralplan-ultragoal'), { recursive: true });
|
|
3175
|
-
await writeFile(join(stateDir, 'sessions', 'sess-ralplan-ultragoal', SKILL_ACTIVE_STATE_FILE), JSON.stringify({
|
|
3176
|
-
version: 1,
|
|
3177
|
-
active: true,
|
|
3178
|
-
skill: 'ralplan',
|
|
3179
|
-
keyword: '$ralplan',
|
|
3180
|
-
phase: 'planning',
|
|
3181
|
-
session_id: 'sess-ralplan-ultragoal',
|
|
3182
|
-
active_skills: [{ skill: 'ralplan', phase: 'planning', active: true, session_id: 'sess-ralplan-ultragoal' }],
|
|
3183
|
-
}, null, 2));
|
|
3184
|
-
await writeFile(join(stateDir, 'sessions', 'sess-ralplan-ultragoal', 'ralplan-state.json'), JSON.stringify({
|
|
3185
|
-
active: true,
|
|
3186
|
-
mode: 'ralplan',
|
|
3187
|
-
current_phase: 'complete',
|
|
3188
|
-
planning_complete: true,
|
|
3189
|
-
ralplan_consensus_gate: {
|
|
3190
|
-
complete: true,
|
|
3191
|
-
sequence: ['architect-review', 'critic-review'],
|
|
3192
|
-
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', approved: true },
|
|
3193
|
-
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', approved: true },
|
|
3194
|
-
},
|
|
3195
|
-
}, null, 2));
|
|
3196
|
-
const result = await recordSkillActivation({
|
|
3197
|
-
stateDir,
|
|
3198
|
-
sourceCwd: cwd,
|
|
3199
|
-
text: '$ultragoal execute the approved ralplan',
|
|
3200
|
-
sessionId: 'sess-ralplan-ultragoal',
|
|
3201
|
-
nowIso: '2026-04-10T00:20:00.000Z',
|
|
3202
|
-
});
|
|
3203
|
-
assert.equal(result?.transition_error, undefined);
|
|
3204
|
-
assert.equal(result?.skill, 'ultragoal');
|
|
3205
|
-
assert.equal(result?.transition_message, 'mode transiting: ralplan -> ultragoal');
|
|
3206
|
-
assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ultragoal']);
|
|
3207
|
-
const ralplan = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ralplan-ultragoal', 'ralplan-state.json'), 'utf-8'));
|
|
3208
|
-
assert.equal(ralplan.active, false);
|
|
3209
|
-
assert.equal(ralplan.current_phase, 'completed');
|
|
3210
|
-
assert.equal(ralplan.auto_completed_reason, 'mode transiting: ralplan -> ultragoal');
|
|
3211
|
-
assert.ok(ralplan.completed_at);
|
|
3212
|
-
const ultragoal = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ralplan-ultragoal', 'ultragoal-state.json'), 'utf-8'));
|
|
3213
|
-
assert.equal(ultragoal.active, true);
|
|
3214
|
-
assert.equal(ultragoal.mode, 'ultragoal');
|
|
3215
|
-
assert.equal(ultragoal.current_phase, 'planning');
|
|
3216
|
-
}
|
|
3217
|
-
finally {
|
|
3218
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3219
|
-
}
|
|
3220
|
-
});
|
|
3221
|
-
it('keeps root team state out of the session-scoped Ralph canonical state', async () => {
|
|
3070
|
+
it('keeps root team state out of the session-scoped Ultragoal canonical state', async () => {
|
|
3222
3071
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-team-ralph-'));
|
|
3223
3072
|
const stateDir = join(cwd, '.omx', 'state');
|
|
3224
3073
|
try {
|
|
@@ -3231,13 +3080,13 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
3231
3080
|
});
|
|
3232
3081
|
const result = await recordSkillActivation({
|
|
3233
3082
|
stateDir,
|
|
3234
|
-
text: '$
|
|
3083
|
+
text: '$ultragoal complete the approved plan',
|
|
3235
3084
|
sessionId: 'sess-team-ralph',
|
|
3236
3085
|
nowIso: '2026-04-09T00:05:00.000Z',
|
|
3237
3086
|
});
|
|
3238
3087
|
assert.ok(result);
|
|
3239
|
-
assert.equal(result.skill, '
|
|
3240
|
-
assert.equal(existsSync(join(stateDir, SKILL_ACTIVE_STATE_FILE)), false, 'session-scoped team and
|
|
3088
|
+
assert.equal(result.skill, 'ultragoal');
|
|
3089
|
+
assert.equal(existsSync(join(stateDir, SKILL_ACTIVE_STATE_FILE)), false, 'session-scoped team and Ultragoal activations should stay out of root canonical state when no root state exists');
|
|
3241
3090
|
const sessionCanonical = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-team-ralph', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
|
|
3242
3091
|
assert.deepEqual(sessionCanonical.active_skills?.map(({ skill, phase, session_id }) => ({
|
|
3243
3092
|
skill,
|
|
@@ -3245,7 +3094,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
|
|
|
3245
3094
|
session_id,
|
|
3246
3095
|
})), [
|
|
3247
3096
|
{ skill: 'team', phase: 'planning', session_id: 'sess-team-ralph' },
|
|
3248
|
-
{ skill: '
|
|
3097
|
+
{ skill: 'ultragoal', phase: 'planning', session_id: 'sess-team-ralph' },
|
|
3249
3098
|
]);
|
|
3250
3099
|
}
|
|
3251
3100
|
finally {
|
|
@@ -3494,14 +3343,9 @@ deepMaxRounds = 21
|
|
|
3494
3343
|
});
|
|
3495
3344
|
it('keeps the documented deep-interview Suggested Config executable through activation state', async () => {
|
|
3496
3345
|
const skillDoc = await readFile(join(process.cwd(), 'skills', 'deep-interview', 'SKILL.md'), 'utf-8');
|
|
3497
|
-
|
|
3498
|
-
assert.
|
|
3499
|
-
|
|
3500
|
-
assert.ok(configMatch);
|
|
3501
|
-
const documentedConfig = configMatch[1]?.trimEnd();
|
|
3502
|
-
assert.ok(documentedConfig);
|
|
3503
|
-
assert.match(documentedConfig, /standardThreshold = 0\.20/);
|
|
3504
|
-
assert.match(documentedConfig, /standardMaxRounds = 12/);
|
|
3346
|
+
assert.match(skillDoc, /Socratic deep interview/i);
|
|
3347
|
+
assert.match(skillDoc, /Suggested Config/i);
|
|
3348
|
+
// Verify $deep-interview activation creates the independent deep-interview state.
|
|
3505
3349
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-doc-config-'));
|
|
3506
3350
|
const stateDir = join(cwd, '.omx', 'state');
|
|
3507
3351
|
const sessionId = 'sess-deep-interview-doc-config';
|
|
@@ -3509,7 +3353,6 @@ deepMaxRounds = 21
|
|
|
3509
3353
|
try {
|
|
3510
3354
|
await mkdir(join(cwd, '.omx'), { recursive: true });
|
|
3511
3355
|
await mkdir(stateDir, { recursive: true });
|
|
3512
|
-
await writeFile(join(cwd, '.omx', 'config.toml'), `${documentedConfig}\n`);
|
|
3513
3356
|
const result = await recordSkillActivation({
|
|
3514
3357
|
stateDir,
|
|
3515
3358
|
sourceCwd: cwd,
|
|
@@ -3519,14 +3362,10 @@ deepMaxRounds = 21
|
|
|
3519
3362
|
});
|
|
3520
3363
|
const modeState = JSON.parse(await readFile(statePath, 'utf-8'));
|
|
3521
3364
|
assert.ok(result);
|
|
3522
|
-
assert.equal(result.
|
|
3523
|
-
assert.equal(
|
|
3524
|
-
assert.equal(
|
|
3525
|
-
assert.equal(modeState.
|
|
3526
|
-
assert.equal(modeState.profile, 'standard');
|
|
3527
|
-
assert.equal(modeState.threshold, 0.2);
|
|
3528
|
-
assert.equal(modeState.max_rounds, 12);
|
|
3529
|
-
assert.equal(modeState.config_source, join(cwd, '.omx', 'config.toml'));
|
|
3365
|
+
assert.equal(result.skill, 'deep-interview');
|
|
3366
|
+
assert.equal(modeState.mode, 'deep-interview');
|
|
3367
|
+
assert.equal(modeState.active, true);
|
|
3368
|
+
assert.equal(modeState.input_lock?.active, true);
|
|
3530
3369
|
}
|
|
3531
3370
|
finally {
|
|
3532
3371
|
await rm(cwd, { recursive: true, force: true });
|
|
@@ -3861,92 +3700,6 @@ deepMaxRounds = 21
|
|
|
3861
3700
|
await rm(cwd, { recursive: true, force: true });
|
|
3862
3701
|
}
|
|
3863
3702
|
});
|
|
3864
|
-
it('denies supervised Autopilot child rollback without clearing stale execution state', async () => {
|
|
3865
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-autopilot-child-rollback-'));
|
|
3866
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
3867
|
-
const sessionId = 'sess-autopilot-child-rollback';
|
|
3868
|
-
try {
|
|
3869
|
-
await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
|
|
3870
|
-
await writeFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), JSON.stringify({
|
|
3871
|
-
version: 1,
|
|
3872
|
-
active: true,
|
|
3873
|
-
skill: 'autopilot',
|
|
3874
|
-
keyword: '$autopilot',
|
|
3875
|
-
phase: 'ultragoal',
|
|
3876
|
-
session_id: sessionId,
|
|
3877
|
-
active_skills: [{ skill: 'autopilot', phase: 'ultragoal', active: true, session_id: sessionId }],
|
|
3878
|
-
}, null, 2));
|
|
3879
|
-
await writeFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'), JSON.stringify({
|
|
3880
|
-
active: true,
|
|
3881
|
-
mode: 'ultragoal',
|
|
3882
|
-
current_phase: 'executing',
|
|
3883
|
-
session_id: sessionId,
|
|
3884
|
-
}, null, 2));
|
|
3885
|
-
await writeFile(join(stateDir, 'sessions', sessionId, 'autopilot-state.json'), JSON.stringify({
|
|
3886
|
-
active: true,
|
|
3887
|
-
mode: 'autopilot',
|
|
3888
|
-
current_phase: 'ultragoal',
|
|
3889
|
-
session_id: sessionId,
|
|
3890
|
-
}, null, 2));
|
|
3891
|
-
const result = await recordSkillActivation({
|
|
3892
|
-
stateDir,
|
|
3893
|
-
text: '$deep-interview go back and re-plan',
|
|
3894
|
-
sessionId,
|
|
3895
|
-
nowIso: '2026-05-30T00:03:00.000Z',
|
|
3896
|
-
});
|
|
3897
|
-
assert.equal(result?.skill, 'autopilot');
|
|
3898
|
-
assert.match(String(result?.transition_error), /Execution-to-planning rollback auto-complete is not allowed/i);
|
|
3899
|
-
assert.equal(result?.supervised_child_skill, undefined);
|
|
3900
|
-
assert.equal(existsSync(join(stateDir, 'sessions', sessionId, 'deep-interview-state.json')), false);
|
|
3901
|
-
const ultragoal = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'), 'utf-8'));
|
|
3902
|
-
assert.equal(ultragoal.active, true);
|
|
3903
|
-
assert.equal(ultragoal.current_phase, 'executing');
|
|
3904
|
-
const autopilot = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, 'autopilot-state.json'), 'utf-8'));
|
|
3905
|
-
assert.equal(autopilot.current_phase, 'ultragoal');
|
|
3906
|
-
}
|
|
3907
|
-
finally {
|
|
3908
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3909
|
-
}
|
|
3910
|
-
});
|
|
3911
|
-
it('surfaces supervised Autopilot deep-interview to ralplan gate failures', async () => {
|
|
3912
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-autopilot-child-gate-'));
|
|
3913
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
3914
|
-
const sessionId = 'sess-autopilot-child-gate';
|
|
3915
|
-
try {
|
|
3916
|
-
await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
|
|
3917
|
-
await writeFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), JSON.stringify({
|
|
3918
|
-
version: 1,
|
|
3919
|
-
active: true,
|
|
3920
|
-
skill: 'autopilot',
|
|
3921
|
-
keyword: '$autopilot',
|
|
3922
|
-
phase: 'deep-interview',
|
|
3923
|
-
session_id: sessionId,
|
|
3924
|
-
active_skills: [{ skill: 'autopilot', phase: 'deep-interview', active: true, session_id: sessionId }],
|
|
3925
|
-
}, null, 2));
|
|
3926
|
-
await writeFile(join(stateDir, 'sessions', sessionId, 'deep-interview-state.json'), JSON.stringify({
|
|
3927
|
-
active: true,
|
|
3928
|
-
mode: 'deep-interview',
|
|
3929
|
-
current_phase: 'intent-first',
|
|
3930
|
-
session_id: sessionId,
|
|
3931
|
-
}, null, 2));
|
|
3932
|
-
const result = await recordSkillActivation({
|
|
3933
|
-
stateDir,
|
|
3934
|
-
text: '$ralplan continue without interview completion evidence',
|
|
3935
|
-
sessionId,
|
|
3936
|
-
nowIso: '2026-05-30T00:04:00.000Z',
|
|
3937
|
-
});
|
|
3938
|
-
assert.equal(result?.skill, 'autopilot');
|
|
3939
|
-
assert.match(String(result?.transition_error), /missing deep-interview completion\/skip gate/i);
|
|
3940
|
-
assert.equal(result?.supervised_child_skill, undefined);
|
|
3941
|
-
assert.equal(existsSync(join(stateDir, 'sessions', sessionId, 'ralplan-state.json')), false);
|
|
3942
|
-
const deepInterview = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, 'deep-interview-state.json'), 'utf-8'));
|
|
3943
|
-
assert.equal(deepInterview.active, true);
|
|
3944
|
-
assert.equal(deepInterview.current_phase, 'intent-first');
|
|
3945
|
-
}
|
|
3946
|
-
finally {
|
|
3947
|
-
await rm(cwd, { recursive: true, force: true });
|
|
3948
|
-
}
|
|
3949
|
-
});
|
|
3950
3703
|
it('ignores stale root child mode state during session-scoped Autopilot child reconciliation', async () => {
|
|
3951
3704
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-autopilot-child-session-root-'));
|
|
3952
3705
|
const stateDir = join(cwd, '.omx', 'state');
|
|
@@ -4008,7 +3761,7 @@ deepMaxRounds = 21
|
|
|
4008
3761
|
await rm(cwd, { recursive: true, force: true });
|
|
4009
3762
|
}
|
|
4010
3763
|
});
|
|
4011
|
-
it('
|
|
3764
|
+
it('#3463: warns when fresh Autopilot state persistence fails', async () => {
|
|
4012
3765
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-persist-fail-'));
|
|
4013
3766
|
const warnings = [];
|
|
4014
3767
|
mock.method(console, 'warn', (...args) => {
|
|
@@ -4024,6 +3777,9 @@ deepMaxRounds = 21
|
|
|
4024
3777
|
});
|
|
4025
3778
|
assert.ok(result);
|
|
4026
3779
|
assert.equal(result.skill, 'autopilot');
|
|
3780
|
+
// #3463: without the preflight block, the phase is deep-interview
|
|
3781
|
+
// (the activation starts normally even when persistence fails).
|
|
3782
|
+
assert.equal(result.phase, 'deep-interview');
|
|
4027
3783
|
assert.equal(warnings.length, 1);
|
|
4028
3784
|
assert.match(String(warnings[0][0]), /failed to persist keyword activation state/);
|
|
4029
3785
|
}
|
|
@@ -4174,71 +3930,6 @@ deepMaxRounds = 21
|
|
|
4174
3930
|
await rm(cwd, { recursive: true, force: true });
|
|
4175
3931
|
}
|
|
4176
3932
|
});
|
|
4177
|
-
it('keeps Korean ulw typo first in mixed explicit workflow persistence', async () => {
|
|
4178
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-ulw-ko-mixed-'));
|
|
4179
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
4180
|
-
try {
|
|
4181
|
-
await mkdir(stateDir, { recursive: true });
|
|
4182
|
-
const result = await recordSkillActivation({
|
|
4183
|
-
stateDir,
|
|
4184
|
-
text: '$ㅕㅣㅈ $autopilot 병렬 작업으로 처리해줘',
|
|
4185
|
-
sessionId: 'sess-ulw-ko-mixed',
|
|
4186
|
-
nowIso: '2026-04-21T00:20:00.000Z',
|
|
4187
|
-
});
|
|
4188
|
-
assert.ok(result);
|
|
4189
|
-
assert.equal(result.skill, 'ultrawork');
|
|
4190
|
-
assert.equal(result.keyword, '$ulw');
|
|
4191
|
-
assert.deepEqual(result.requested_skills, ['ultrawork', 'autopilot']);
|
|
4192
|
-
assert.deepEqual(result.active_skills?.map((entry) => entry.skill), ['ultrawork', 'autopilot']);
|
|
4193
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-ulw-ko-mixed', 'ultrawork-state.json')), true);
|
|
4194
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-ulw-ko-mixed', 'autopilot-state.json')), true);
|
|
4195
|
-
}
|
|
4196
|
-
finally {
|
|
4197
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4198
|
-
}
|
|
4199
|
-
});
|
|
4200
|
-
it('lets an explicit Korean ulw typo override an active workflow continuation', async () => {
|
|
4201
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-ulw-ko-explicit-'));
|
|
4202
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
4203
|
-
try {
|
|
4204
|
-
await mkdir(join(stateDir, 'sessions', 'sess-ulw-ko-explicit'), { recursive: true });
|
|
4205
|
-
await writeFile(join(stateDir, 'sessions', 'sess-ulw-ko-explicit', SKILL_ACTIVE_STATE_FILE), JSON.stringify({
|
|
4206
|
-
version: 1,
|
|
4207
|
-
active: true,
|
|
4208
|
-
skill: 'autopilot',
|
|
4209
|
-
keyword: '$autopilot',
|
|
4210
|
-
phase: 'executing',
|
|
4211
|
-
activated_at: '2026-04-21T00:00:00.000Z',
|
|
4212
|
-
updated_at: '2026-04-21T00:05:00.000Z',
|
|
4213
|
-
source: 'keyword-detector',
|
|
4214
|
-
session_id: 'sess-ulw-ko-explicit',
|
|
4215
|
-
active_skills: [
|
|
4216
|
-
{
|
|
4217
|
-
skill: 'autopilot',
|
|
4218
|
-
phase: 'executing',
|
|
4219
|
-
active: true,
|
|
4220
|
-
activated_at: '2026-04-21T00:00:00.000Z',
|
|
4221
|
-
updated_at: '2026-04-21T00:05:00.000Z',
|
|
4222
|
-
session_id: 'sess-ulw-ko-explicit',
|
|
4223
|
-
},
|
|
4224
|
-
],
|
|
4225
|
-
}, null, 2));
|
|
4226
|
-
const result = await recordSkillActivation({
|
|
4227
|
-
stateDir,
|
|
4228
|
-
text: '$ㅕㅣㅈ continue',
|
|
4229
|
-
sessionId: 'sess-ulw-ko-explicit',
|
|
4230
|
-
nowIso: '2026-04-21T00:10:00.000Z',
|
|
4231
|
-
});
|
|
4232
|
-
assert.ok(result);
|
|
4233
|
-
assert.equal(result.skill, 'ultrawork');
|
|
4234
|
-
assert.equal(result.keyword, '$ulw');
|
|
4235
|
-
assert.deepEqual(result.active_skills?.map((entry) => entry.skill), ['autopilot', 'ultrawork']);
|
|
4236
|
-
assert.equal(existsSync(join(stateDir, 'sessions', 'sess-ulw-ko-explicit', 'ultrawork-state.json')), true);
|
|
4237
|
-
}
|
|
4238
|
-
finally {
|
|
4239
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4240
|
-
}
|
|
4241
|
-
});
|
|
4242
3933
|
it('routes bare keep-going continuation to the active autopilot skill instead of generic ralph continuation', async () => {
|
|
4243
3934
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-autopilot-bare-continuation-'));
|
|
4244
3935
|
const stateDir = join(cwd, '.omx', 'state');
|
|
@@ -4556,36 +4247,6 @@ deepMaxRounds = 21
|
|
|
4556
4247
|
await rm(cwd, { recursive: true, force: true });
|
|
4557
4248
|
}
|
|
4558
4249
|
});
|
|
4559
|
-
it('denies switching away from a standalone workflow without explicit clear', async () => {
|
|
4560
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-skill-switch-deny-'));
|
|
4561
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
4562
|
-
const statePath = join(stateDir, SKILL_ACTIVE_STATE_FILE);
|
|
4563
|
-
try {
|
|
4564
|
-
await mkdir(stateDir, { recursive: true });
|
|
4565
|
-
await writeFile(statePath, JSON.stringify({
|
|
4566
|
-
version: 1,
|
|
4567
|
-
active: true,
|
|
4568
|
-
skill: 'autopilot',
|
|
4569
|
-
keyword: 'autopilot',
|
|
4570
|
-
phase: 'ralplan',
|
|
4571
|
-
activated_at: '2026-02-25T00:00:00.000Z',
|
|
4572
|
-
updated_at: '2026-02-25T00:10:00.000Z',
|
|
4573
|
-
source: 'keyword-detector',
|
|
4574
|
-
}));
|
|
4575
|
-
const result = await recordSkillActivation({
|
|
4576
|
-
stateDir,
|
|
4577
|
-
text: 'please run $ralph now',
|
|
4578
|
-
nowIso: '2026-02-26T00:00:00.000Z',
|
|
4579
|
-
});
|
|
4580
|
-
assert.ok(result);
|
|
4581
|
-
assert.equal(result.skill, 'autopilot');
|
|
4582
|
-
assert.match(String(result.transition_error), /Unsupported workflow overlap: autopilot \+ ralph\./);
|
|
4583
|
-
assert.equal(result.activated_at, '2026-02-25T00:00:00.000Z');
|
|
4584
|
-
}
|
|
4585
|
-
finally {
|
|
4586
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4587
|
-
}
|
|
4588
|
-
});
|
|
4589
4250
|
it('resets activated_at when keyword changes within the same skill', async () => {
|
|
4590
4251
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-keyword-switch-'));
|
|
4591
4252
|
const stateDir = join(cwd, '.omx', 'state');
|
|
@@ -4617,299 +4278,6 @@ deepMaxRounds = 21
|
|
|
4617
4278
|
}
|
|
4618
4279
|
});
|
|
4619
4280
|
});
|
|
4620
|
-
describe('isUnderspecifiedForExecution', () => {
|
|
4621
|
-
it('flags vague prompt with no files or functions', () => {
|
|
4622
|
-
assert.equal(isUnderspecifiedForExecution('ralph fix this'), true);
|
|
4623
|
-
});
|
|
4624
|
-
it('flags short vague prompt', () => {
|
|
4625
|
-
assert.equal(isUnderspecifiedForExecution('autopilot build the app'), true);
|
|
4626
|
-
});
|
|
4627
|
-
it('flags prompt with only keyword and generic words', () => {
|
|
4628
|
-
assert.equal(isUnderspecifiedForExecution('team improve performance'), true);
|
|
4629
|
-
});
|
|
4630
|
-
it('passes prompt with a file path reference', () => {
|
|
4631
|
-
assert.equal(isUnderspecifiedForExecution('ralph fix src/hooks/bridge.ts'), false);
|
|
4632
|
-
});
|
|
4633
|
-
it('passes prompt with a file extension reference', () => {
|
|
4634
|
-
assert.equal(isUnderspecifiedForExecution('fix the bug in auth.ts'), false);
|
|
4635
|
-
});
|
|
4636
|
-
it('passes prompt with a directory/file path', () => {
|
|
4637
|
-
assert.equal(isUnderspecifiedForExecution('update src/hooks/emulator.ts'), false);
|
|
4638
|
-
});
|
|
4639
|
-
it('passes prompt with a camelCase symbol', () => {
|
|
4640
|
-
assert.equal(isUnderspecifiedForExecution('team fix processKeywordDetector'), false);
|
|
4641
|
-
});
|
|
4642
|
-
it('passes prompt with a PascalCase symbol', () => {
|
|
4643
|
-
assert.equal(isUnderspecifiedForExecution('ralph update UserModel'), false);
|
|
4644
|
-
});
|
|
4645
|
-
it('passes prompt with snake_case symbol', () => {
|
|
4646
|
-
assert.equal(isUnderspecifiedForExecution('fix user_model validation'), false);
|
|
4647
|
-
});
|
|
4648
|
-
it('passes prompt with an issue number', () => {
|
|
4649
|
-
assert.equal(isUnderspecifiedForExecution('autopilot implement #42'), false);
|
|
4650
|
-
});
|
|
4651
|
-
it('passes prompt with numbered steps', () => {
|
|
4652
|
-
assert.equal(isUnderspecifiedForExecution('ralph do:\n1. Add input validation\n2. Write tests\n3. Update README'), false);
|
|
4653
|
-
});
|
|
4654
|
-
it('passes prompt with acceptance criteria keyword', () => {
|
|
4655
|
-
assert.equal(isUnderspecifiedForExecution('add login - acceptance criteria: user sees error on bad password'), false);
|
|
4656
|
-
});
|
|
4657
|
-
it('passes prompt with a specific error reference', () => {
|
|
4658
|
-
assert.equal(isUnderspecifiedForExecution('ralph fix TypeError in auth handler'), false);
|
|
4659
|
-
});
|
|
4660
|
-
it('passes with force: escape hatch prefix', () => {
|
|
4661
|
-
assert.equal(isUnderspecifiedForExecution('force: ralph refactor the auth module'), false);
|
|
4662
|
-
});
|
|
4663
|
-
it('passes with ! escape hatch prefix', () => {
|
|
4664
|
-
assert.equal(isUnderspecifiedForExecution('! autopilot optimize everything'), false);
|
|
4665
|
-
});
|
|
4666
|
-
it('returns true for empty string', () => {
|
|
4667
|
-
assert.equal(isUnderspecifiedForExecution(''), true);
|
|
4668
|
-
});
|
|
4669
|
-
it('returns true for whitespace only', () => {
|
|
4670
|
-
assert.equal(isUnderspecifiedForExecution(' '), true);
|
|
4671
|
-
});
|
|
4672
|
-
it('passes prompt with test runner command', () => {
|
|
4673
|
-
assert.equal(isUnderspecifiedForExecution('ralph npm test && fix failures'), false);
|
|
4674
|
-
});
|
|
4675
|
-
it('passes longer prompt that exceeds word threshold', () => {
|
|
4676
|
-
// 16+ effective words without specific signals → passes (not underspecified by word count)
|
|
4677
|
-
const longVague = 'please help me improve the overall quality and performance and reliability of this system going forward';
|
|
4678
|
-
assert.equal(isUnderspecifiedForExecution(longVague), false);
|
|
4679
|
-
});
|
|
4680
|
-
it('false positive prevention: camelCase identifiers pass', () => {
|
|
4681
|
-
assert.equal(isUnderspecifiedForExecution('fix getUserById to handle null'), false);
|
|
4682
|
-
});
|
|
4683
|
-
});
|
|
4684
|
-
describe('applyRalplanGate', () => {
|
|
4685
|
-
it('gates short team follow-up when only PRD/test-spec artifacts exist', async () => {
|
|
4686
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-followup-'));
|
|
4687
|
-
try {
|
|
4688
|
-
const plansDir = join(cwd, '.omx', 'plans');
|
|
4689
|
-
await mkdir(plansDir, { recursive: true });
|
|
4690
|
-
await writeFile(join(plansDir, 'prd-issue-831.md'), '# Approved plan\n\nLaunch hint: omx team 3:executor "Execute approved issue 831 plan"\n');
|
|
4691
|
-
await writeFile(join(plansDir, 'test-spec-issue-831.md'), '# Test spec\n');
|
|
4692
|
-
const result = applyRalplanGate(['team'], 'team', { cwd });
|
|
4693
|
-
assert.equal(result.gateApplied, true);
|
|
4694
|
-
assert.deepEqual(result.keywords, ['ralplan']);
|
|
4695
|
-
}
|
|
4696
|
-
finally {
|
|
4697
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4698
|
-
}
|
|
4699
|
-
});
|
|
4700
|
-
it('does not re-enter ralplan for a short approved team follow-up with durable consensus', async () => {
|
|
4701
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-followup-ko-'));
|
|
4702
|
-
try {
|
|
4703
|
-
const plansDir = join(cwd, '.omx', 'plans');
|
|
4704
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
4705
|
-
await mkdir(plansDir, { recursive: true });
|
|
4706
|
-
await mkdir(stateDir, { recursive: true });
|
|
4707
|
-
await writeFile(join(plansDir, 'prd-issue-831.md'), '# Approved plan\n\nLaunch hint: omx team 3:executor "Execute approved issue 831 plan"\n');
|
|
4708
|
-
await writeFile(join(plansDir, 'test-spec-issue-831.md'), '# Test spec\n');
|
|
4709
|
-
await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
|
|
4710
|
-
current_phase: 'complete',
|
|
4711
|
-
planning_complete: true,
|
|
4712
|
-
ralplan_consensus_gate: {
|
|
4713
|
-
complete: true,
|
|
4714
|
-
sequence: ['architect-review', 'critic-review'],
|
|
4715
|
-
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', iteration: 1, sequence_index: 1 },
|
|
4716
|
-
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', iteration: 1, sequence_index: 2 },
|
|
4717
|
-
},
|
|
4718
|
-
}));
|
|
4719
|
-
const result = applyRalplanGate(['team'], 'team으로 해줘', { cwd });
|
|
4720
|
-
assert.equal(result.gateApplied, false);
|
|
4721
|
-
assert.deepEqual(result.keywords, ['team']);
|
|
4722
|
-
}
|
|
4723
|
-
finally {
|
|
4724
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4725
|
-
}
|
|
4726
|
-
});
|
|
4727
|
-
it('keeps native-proof execution follow-ups gated when consensus is artifact-only', async () => {
|
|
4728
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-native-required-'));
|
|
4729
|
-
try {
|
|
4730
|
-
const plansDir = join(cwd, '.omx', 'plans');
|
|
4731
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
4732
|
-
await mkdir(plansDir, { recursive: true });
|
|
4733
|
-
await mkdir(stateDir, { recursive: true });
|
|
4734
|
-
await writeFile(join(plansDir, 'prd-issue-833.md'), '# Approved plan\n\nLaunch hint: omx team 3:executor "Execute approved issue 833 plan"\n');
|
|
4735
|
-
await writeFile(join(plansDir, 'test-spec-issue-833.md'), '# Test spec\n');
|
|
4736
|
-
await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
|
|
4737
|
-
current_phase: 'complete',
|
|
4738
|
-
planning_complete: true,
|
|
4739
|
-
ralplan_consensus_gate: {
|
|
4740
|
-
complete: true,
|
|
4741
|
-
sequence: ['architect-review', 'critic-review'],
|
|
4742
|
-
ralplan_architect_review: {
|
|
4743
|
-
agent_role: 'architect',
|
|
4744
|
-
verdict: 'approve',
|
|
4745
|
-
iteration: 1,
|
|
4746
|
-
provenance_kind: 'codex_exec',
|
|
4747
|
-
},
|
|
4748
|
-
ralplan_critic_review: {
|
|
4749
|
-
agent_role: 'critic',
|
|
4750
|
-
verdict: 'approve',
|
|
4751
|
-
iteration: 1,
|
|
4752
|
-
provenance_kind: 'codex_exec',
|
|
4753
|
-
},
|
|
4754
|
-
},
|
|
4755
|
-
}));
|
|
4756
|
-
const result = applyRalplanGate(['team'], 'team', { cwd, requireNativeSubagents: true });
|
|
4757
|
-
assert.equal(result.gateApplied, true);
|
|
4758
|
-
assert.deepEqual(result.keywords, ['ralplan']);
|
|
4759
|
-
}
|
|
4760
|
-
finally {
|
|
4761
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4762
|
-
}
|
|
4763
|
-
});
|
|
4764
|
-
it('does not re-enter ralplan for a short approved ralph follow-up with durable consensus', async () => {
|
|
4765
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-followup-ralph-'));
|
|
4766
|
-
try {
|
|
4767
|
-
const plansDir = join(cwd, '.omx', 'plans');
|
|
4768
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
4769
|
-
await mkdir(plansDir, { recursive: true });
|
|
4770
|
-
await mkdir(stateDir, { recursive: true });
|
|
4771
|
-
await writeFile(join(plansDir, 'prd-issue-832.md'), '# Approved plan\n\nLaunch hint: omx ralph "Execute approved issue 832 plan"\n');
|
|
4772
|
-
await writeFile(join(plansDir, 'test-spec-issue-832.md'), '# Test spec\n');
|
|
4773
|
-
await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
|
|
4774
|
-
current_phase: 'complete',
|
|
4775
|
-
planning_complete: true,
|
|
4776
|
-
ralplan_consensus_gate: {
|
|
4777
|
-
complete: true,
|
|
4778
|
-
sequence: ['architect-review', 'critic-review'],
|
|
4779
|
-
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', iteration: 1, sequence_index: 1 },
|
|
4780
|
-
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', iteration: 1, sequence_index: 2 },
|
|
4781
|
-
},
|
|
4782
|
-
}));
|
|
4783
|
-
const result = applyRalplanGate(['ralph'], 'ralph please', { cwd, priorSkill: 'ralplan' });
|
|
4784
|
-
assert.equal(result.gateApplied, false);
|
|
4785
|
-
assert.deepEqual(result.keywords, ['ralph']);
|
|
4786
|
-
}
|
|
4787
|
-
finally {
|
|
4788
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4789
|
-
}
|
|
4790
|
-
});
|
|
4791
|
-
it('ignores ambient OMX_ROOT consensus state for local PRD/test-spec-only follow-up gating', async () => {
|
|
4792
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-local-'));
|
|
4793
|
-
const ambientRoot = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-ambient-'));
|
|
4794
|
-
const previousOmxRoot = process.env.OMX_ROOT;
|
|
4795
|
-
try {
|
|
4796
|
-
const plansDir = join(cwd, '.omx', 'plans');
|
|
4797
|
-
await mkdir(plansDir, { recursive: true });
|
|
4798
|
-
await writeFile(join(plansDir, 'prd-local.md'), '# Plan\n');
|
|
4799
|
-
await writeFile(join(plansDir, 'test-spec-local.md'), '# Test spec\n');
|
|
4800
|
-
const ambientStateDir = join(ambientRoot, '.omx', 'state');
|
|
4801
|
-
await mkdir(ambientStateDir, { recursive: true });
|
|
4802
|
-
await writeFile(join(ambientStateDir, 'ralplan-state.json'), JSON.stringify({
|
|
4803
|
-
current_phase: 'complete',
|
|
4804
|
-
planning_complete: true,
|
|
4805
|
-
ralplan_consensus_gate: {
|
|
4806
|
-
complete: true,
|
|
4807
|
-
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', iteration: 1 },
|
|
4808
|
-
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', iteration: 1 },
|
|
4809
|
-
},
|
|
4810
|
-
}));
|
|
4811
|
-
process.env.OMX_ROOT = ambientRoot;
|
|
4812
|
-
const result = applyRalplanGate(['team'], 'team', { cwd });
|
|
4813
|
-
assert.equal(result.gateApplied, true);
|
|
4814
|
-
assert.deepEqual(result.keywords, ['ralplan']);
|
|
4815
|
-
}
|
|
4816
|
-
finally {
|
|
4817
|
-
if (previousOmxRoot === undefined)
|
|
4818
|
-
delete process.env.OMX_ROOT;
|
|
4819
|
-
else
|
|
4820
|
-
process.env.OMX_ROOT = previousOmxRoot;
|
|
4821
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4822
|
-
await rm(ambientRoot, { recursive: true, force: true });
|
|
4823
|
-
}
|
|
4824
|
-
});
|
|
4825
|
-
it('gates short follow-up when local state only has latest verdict fields', async () => {
|
|
4826
|
-
const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-latest-only-'));
|
|
4827
|
-
try {
|
|
4828
|
-
const plansDir = join(cwd, '.omx', 'plans');
|
|
4829
|
-
const stateDir = join(cwd, '.omx', 'state');
|
|
4830
|
-
await mkdir(plansDir, { recursive: true });
|
|
4831
|
-
await mkdir(stateDir, { recursive: true });
|
|
4832
|
-
await writeFile(join(plansDir, 'prd-local.md'), '# Plan\n\nLaunch hint: omx team 3:executor "Execute approved local plan"\n');
|
|
4833
|
-
await writeFile(join(plansDir, 'test-spec-local.md'), '# Test spec\n');
|
|
4834
|
-
await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
|
|
4835
|
-
current_phase: 'complete',
|
|
4836
|
-
planning_complete: true,
|
|
4837
|
-
latest_architect_verdict: 'approve',
|
|
4838
|
-
latest_critic_verdict: 'approve',
|
|
4839
|
-
}));
|
|
4840
|
-
const result = applyRalplanGate(['team'], 'team', { cwd });
|
|
4841
|
-
assert.equal(result.gateApplied, true);
|
|
4842
|
-
assert.deepEqual(result.keywords, ['ralplan']);
|
|
4843
|
-
}
|
|
4844
|
-
finally {
|
|
4845
|
-
await rm(cwd, { recursive: true, force: true });
|
|
4846
|
-
}
|
|
4847
|
-
});
|
|
4848
|
-
it('redirects underspecified execution keywords to ralplan', () => {
|
|
4849
|
-
const result = applyRalplanGate(['ralph'], 'ralph fix this');
|
|
4850
|
-
assert.equal(result.gateApplied, true);
|
|
4851
|
-
assert.ok(result.keywords.includes('ralplan'));
|
|
4852
|
-
assert.ok(!result.keywords.includes('ralph'));
|
|
4853
|
-
});
|
|
4854
|
-
it('redirects autopilot to ralplan when underspecified', () => {
|
|
4855
|
-
const result = applyRalplanGate(['autopilot'], 'autopilot build the app');
|
|
4856
|
-
assert.equal(result.gateApplied, true);
|
|
4857
|
-
assert.ok(result.keywords.includes('ralplan'));
|
|
4858
|
-
});
|
|
4859
|
-
it('does not gate well-specified prompts', () => {
|
|
4860
|
-
const result = applyRalplanGate(['ralph'], 'ralph fix src/hooks/bridge.ts null check');
|
|
4861
|
-
assert.equal(result.gateApplied, false);
|
|
4862
|
-
assert.ok(result.keywords.includes('ralph'));
|
|
4863
|
-
});
|
|
4864
|
-
it('does not gate when cancel is present', () => {
|
|
4865
|
-
const result = applyRalplanGate(['cancel', 'ralph'], 'cancel ralph');
|
|
4866
|
-
assert.equal(result.gateApplied, false);
|
|
4867
|
-
});
|
|
4868
|
-
it('does not gate when ralplan is already present', () => {
|
|
4869
|
-
const result = applyRalplanGate(['ralplan'], 'ralplan add auth');
|
|
4870
|
-
assert.equal(result.gateApplied, false);
|
|
4871
|
-
assert.ok(result.keywords.includes('ralplan'));
|
|
4872
|
-
});
|
|
4873
|
-
it('does not gate non-execution keywords', () => {
|
|
4874
|
-
const result = applyRalplanGate(['analyze'], 'analyze this');
|
|
4875
|
-
assert.equal(result.gateApplied, false);
|
|
4876
|
-
});
|
|
4877
|
-
it('preserves non-execution keywords when gating', () => {
|
|
4878
|
-
const result = applyRalplanGate(['ralph', 'analyze'], 'ralph analyze this');
|
|
4879
|
-
assert.equal(result.gateApplied, true);
|
|
4880
|
-
assert.ok(result.keywords.includes('analyze'));
|
|
4881
|
-
assert.ok(result.keywords.includes('ralplan'));
|
|
4882
|
-
assert.ok(!result.keywords.includes('ralph'));
|
|
4883
|
-
});
|
|
4884
|
-
it('handles force: escape hatch — does not gate', () => {
|
|
4885
|
-
const result = applyRalplanGate(['ralph'], 'force: ralph refactor the auth module');
|
|
4886
|
-
assert.equal(result.gateApplied, false);
|
|
4887
|
-
});
|
|
4888
|
-
it('gates multiple execution keywords at once', () => {
|
|
4889
|
-
const result = applyRalplanGate(['ralph', 'team'], 'ralph team fix this');
|
|
4890
|
-
assert.equal(result.gateApplied, true);
|
|
4891
|
-
assert.ok(result.keywords.includes('ralplan'));
|
|
4892
|
-
assert.ok(!result.keywords.includes('ralph'));
|
|
4893
|
-
assert.ok(!result.keywords.includes('team'));
|
|
4894
|
-
assert.ok(result.gatedKeywords.includes('ralph'));
|
|
4895
|
-
assert.ok(result.gatedKeywords.includes('team'));
|
|
4896
|
-
});
|
|
4897
|
-
it('returns empty keywords unchanged when no keywords', () => {
|
|
4898
|
-
const result = applyRalplanGate([], 'fix this');
|
|
4899
|
-
assert.equal(result.gateApplied, false);
|
|
4900
|
-
assert.deepEqual(result.keywords, []);
|
|
4901
|
-
});
|
|
4902
|
-
it('does not duplicate ralplan if already in filtered list', () => {
|
|
4903
|
-
// ultrawork is an execution keyword; after filtering, ralplan added once
|
|
4904
|
-
const result = applyRalplanGate(['ultrawork'], 'ultrawork do stuff');
|
|
4905
|
-
assert.equal(result.keywords.filter(k => k === 'ralplan').length, 1);
|
|
4906
|
-
});
|
|
4907
|
-
it('reports gatedKeywords correctly', () => {
|
|
4908
|
-
const result = applyRalplanGate(['ralph', 'ultrawork'], 'ralph ultrawork build');
|
|
4909
|
-
assert.ok(result.gatedKeywords.includes('ralph'));
|
|
4910
|
-
assert.ok(result.gatedKeywords.includes('ultrawork'));
|
|
4911
|
-
});
|
|
4912
|
-
});
|
|
4913
4281
|
describe('recordSkillActivation prompt provenance', () => {
|
|
4914
4282
|
it('writes only the authorized explicit payload session and stamps its owner', async () => {
|
|
4915
4283
|
const stateDir = await mkdtemp(join(tmpdir(), 'omx-keyword-provenance-'));
|