oh-my-codex 0.18.0 → 0.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +6 -6
- package/Cargo.toml +1 -1
- package/README.md +45 -19
- package/crates/omx-api/src/lib.rs +66 -9
- package/crates/omx-sparkshell/src/exec.rs +125 -3
- package/crates/omx-sparkshell/src/main.rs +126 -36
- package/crates/omx-sparkshell/tests/execution.rs +225 -1
- package/dist/agents/__tests__/definitions.test.js +14 -0
- package/dist/agents/__tests__/definitions.test.js.map +1 -1
- package/dist/agents/__tests__/native-config.test.js +19 -0
- 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 +30 -0
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/native-config.d.ts +1 -0
- package/dist/agents/native-config.d.ts.map +1 -1
- package/dist/agents/native-config.js +4 -0
- package/dist/agents/native-config.js.map +1 -1
- package/dist/catalog/__tests__/generator.test.js +4 -0
- package/dist/catalog/__tests__/generator.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +15 -7
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +137 -8
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +203 -15
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/install-docs-contract.test.d.ts +2 -0
- package/dist/cli/__tests__/install-docs-contract.test.d.ts.map +1 -0
- package/dist/cli/__tests__/install-docs-contract.test.js +55 -0
- package/dist/cli/__tests__/install-docs-contract.test.js.map +1 -0
- package/dist/cli/__tests__/launch-fallback.test.js +163 -0
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/question.test.js +29 -43
- package/dist/cli/__tests__/question.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +94 -35
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js +20 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-packaging.test.js +1 -0
- package/dist/cli/__tests__/sparkshell-packaging.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +227 -4
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/__tests__/update.test.js +72 -1
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/codex-feature-probe.d.ts +5 -0
- package/dist/cli/codex-feature-probe.d.ts.map +1 -1
- package/dist/cli/codex-feature-probe.js +13 -7
- package/dist/cli/codex-feature-probe.js.map +1 -1
- package/dist/cli/doctor.d.ts +7 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +297 -17
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +9 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +465 -110
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/plugin-marketplace.d.ts +2 -0
- package/dist/cli/plugin-marketplace.d.ts.map +1 -1
- package/dist/cli/plugin-marketplace.js +15 -1
- package/dist/cli/plugin-marketplace.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +71 -11
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/sparkshell.d.ts +7 -1
- package/dist/cli/sparkshell.d.ts.map +1 -1
- package/dist/cli/sparkshell.js +13 -3
- 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 +184 -10
- package/dist/cli/ultragoal.js.map +1 -1
- package/dist/cli/update.d.ts +2 -0
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +14 -3
- package/dist/cli/update.js.map +1 -1
- package/dist/compat/__tests__/doctor-contract.test.js +3 -0
- package/dist/compat/__tests__/doctor-contract.test.js.map +1 -1
- package/dist/config/__tests__/codex-feature-flags.test.js +11 -1
- package/dist/config/__tests__/codex-feature-flags.test.js.map +1 -1
- package/dist/config/__tests__/codex-hooks.test.js +22 -11
- package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
- package/dist/config/__tests__/commit-lore-guard.test.d.ts +2 -0
- package/dist/config/__tests__/commit-lore-guard.test.d.ts.map +1 -0
- package/dist/config/__tests__/commit-lore-guard.test.js +20 -0
- package/dist/config/__tests__/commit-lore-guard.test.js.map +1 -0
- package/dist/config/codex-feature-flags.d.ts +4 -0
- package/dist/config/codex-feature-flags.d.ts.map +1 -1
- package/dist/config/codex-feature-flags.js +4 -0
- package/dist/config/codex-feature-flags.js.map +1 -1
- package/dist/config/codex-hooks.d.ts +1 -0
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +8 -10
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/config/commit-lore-guard.d.ts +1 -0
- package/dist/config/commit-lore-guard.d.ts.map +1 -1
- package/dist/config/commit-lore-guard.js +29 -3
- package/dist/config/commit-lore-guard.js.map +1 -1
- package/dist/config/generator.d.ts +17 -1
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +124 -11
- package/dist/config/generator.js.map +1 -1
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +21 -0
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.d.ts +4 -0
- package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.js +50 -3
- package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +27 -6
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js +13 -11
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +4 -3
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +173 -17
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +33 -0
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js +320 -0
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +12 -0
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
- package/dist/hooks/__tests__/research-workflow-boundaries.test.d.ts +2 -0
- package/dist/hooks/__tests__/research-workflow-boundaries.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/research-workflow-boundaries.test.js +35 -0
- package/dist/hooks/__tests__/research-workflow-boundaries.test.js.map +1 -0
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js +26 -3
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js +29 -14
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +1 -1
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +36 -9
- 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 +1 -0
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +14 -2
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.js +36 -8
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +122 -11
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/render.test.js +84 -0
- package/dist/hud/__tests__/render.test.js.map +1 -1
- package/dist/hud/__tests__/resource-leak-watch.test.d.ts +2 -0
- package/dist/hud/__tests__/resource-leak-watch.test.d.ts.map +1 -0
- package/dist/hud/__tests__/resource-leak-watch.test.js +28 -0
- package/dist/hud/__tests__/resource-leak-watch.test.js.map +1 -0
- package/dist/hud/__tests__/state.test.js +51 -1
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +69 -23
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/index.d.ts +2 -2
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +17 -6
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/reconcile.d.ts.map +1 -1
- package/dist/hud/reconcile.js +6 -3
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +26 -0
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts +2 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +62 -1
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/tmux.d.ts +10 -3
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +60 -11
- package/dist/hud/tmux.js.map +1 -1
- package/dist/hud/types.d.ts +22 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js.map +1 -1
- package/dist/notifications/__tests__/http-client-resource.test.d.ts +2 -0
- package/dist/notifications/__tests__/http-client-resource.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/http-client-resource.test.js +41 -0
- package/dist/notifications/__tests__/http-client-resource.test.js.map +1 -0
- package/dist/notifications/__tests__/verbosity.test.js +20 -0
- package/dist/notifications/__tests__/verbosity.test.js.map +1 -1
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +6 -3
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/http-client.d.ts.map +1 -1
- package/dist/notifications/http-client.js +78 -27
- package/dist/notifications/http-client.js.map +1 -1
- package/dist/notifications/types.d.ts +2 -0
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/openclaw/__tests__/dispatcher.test.js +49 -1
- package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -1
- package/dist/openclaw/dispatcher.d.ts +7 -4
- package/dist/openclaw/dispatcher.d.ts.map +1 -1
- package/dist/openclaw/dispatcher.js +32 -69
- package/dist/openclaw/dispatcher.js.map +1 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +128 -4
- package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
- package/dist/pipeline/__tests__/stages.test.js +460 -9
- package/dist/pipeline/__tests__/stages.test.js.map +1 -1
- package/dist/pipeline/index.d.ts +8 -2
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/index.js +5 -2
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/orchestrator.d.ts +5 -4
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.js +85 -17
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/pipeline/stages/code-review.d.ts +2 -2
- package/dist/pipeline/stages/code-review.d.ts.map +1 -1
- package/dist/pipeline/stages/code-review.js +5 -3
- package/dist/pipeline/stages/code-review.js.map +1 -1
- package/dist/pipeline/stages/deep-interview.d.ts +15 -0
- package/dist/pipeline/stages/deep-interview.d.ts.map +1 -0
- package/dist/pipeline/stages/deep-interview.js +32 -0
- package/dist/pipeline/stages/deep-interview.js.map +1 -0
- package/dist/pipeline/stages/ralph-verify.d.ts +5 -5
- package/dist/pipeline/stages/ralph-verify.d.ts.map +1 -1
- package/dist/pipeline/stages/ralph-verify.js +2 -2
- package/dist/pipeline/stages/ralph-verify.js.map +1 -1
- package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
- package/dist/pipeline/stages/ralplan.js +41 -6
- package/dist/pipeline/stages/ralplan.js.map +1 -1
- package/dist/pipeline/stages/ultragoal.d.ts +19 -0
- package/dist/pipeline/stages/ultragoal.d.ts.map +1 -0
- package/dist/pipeline/stages/ultragoal.js +38 -0
- package/dist/pipeline/stages/ultragoal.js.map +1 -0
- package/dist/pipeline/stages/ultraqa.d.ts +30 -0
- package/dist/pipeline/stages/ultraqa.d.ts.map +1 -0
- package/dist/pipeline/stages/ultraqa.js +46 -0
- package/dist/pipeline/stages/ultraqa.js.map +1 -0
- package/dist/pipeline/types.d.ts +8 -6
- package/dist/pipeline/types.d.ts.map +1 -1
- package/dist/pipeline/types.js +2 -2
- package/dist/question/__tests__/ui.test.js +43 -10
- package/dist/question/__tests__/ui.test.js.map +1 -1
- package/dist/question/ui.d.ts +12 -0
- package/dist/question/ui.d.ts.map +1 -1
- package/dist/question/ui.js +83 -46
- package/dist/question/ui.js.map +1 -1
- package/dist/ralplan/__tests__/runtime.test.js +200 -10
- package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
- package/dist/ralplan/consensus-gate.d.ts +23 -0
- package/dist/ralplan/consensus-gate.d.ts.map +1 -0
- package/dist/ralplan/consensus-gate.js +212 -0
- package/dist/ralplan/consensus-gate.js.map +1 -0
- package/dist/ralplan/runtime.d.ts +25 -0
- package/dist/ralplan/runtime.d.ts.map +1 -1
- package/dist/ralplan/runtime.js +144 -8
- package/dist/ralplan/runtime.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +1358 -79
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/docs-site-contract.test.d.ts +2 -0
- package/dist/scripts/__tests__/docs-site-contract.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/docs-site-contract.test.js +42 -0
- package/dist/scripts/__tests__/docs-site-contract.test.js.map +1 -0
- package/dist/scripts/__tests__/notify-dispatcher.test.js +115 -2
- package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -1
- package/dist/scripts/__tests__/run-test-files.test.js +57 -0
- package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js +23 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/__tests__/verify-native-agents.test.js +18 -3
- package/dist/scripts/__tests__/verify-native-agents.test.js.map +1 -1
- package/dist/scripts/cleanup-explore-harness.js +1 -0
- package/dist/scripts/cleanup-explore-harness.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +372 -44
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +9 -1
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/notify-dispatcher.js +188 -4
- package/dist/scripts/notify-dispatcher.js.map +1 -1
- package/dist/scripts/notify-hook/process-runner.d.ts.map +1 -1
- package/dist/scripts/notify-hook/process-runner.js +39 -17
- package/dist/scripts/notify-hook/process-runner.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +9 -5
- package/dist/scripts/notify-hook/team-dispatch.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 +7 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/run-test-files.js +13 -0
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +3 -0
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +99 -1
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.js +2 -2
- package/dist/scripts/sync-plugin-mirror.js.map +1 -1
- package/dist/scripts/verify-native-agents.js +2 -2
- package/dist/scripts/verify-native-agents.js.map +1 -1
- package/dist/sidecar/__tests__/resource-leak-watch.test.d.ts +2 -0
- package/dist/sidecar/__tests__/resource-leak-watch.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/resource-leak-watch.test.js +38 -0
- package/dist/sidecar/__tests__/resource-leak-watch.test.js.map +1 -0
- package/dist/sidecar/index.d.ts +1 -1
- package/dist/sidecar/index.d.ts.map +1 -1
- package/dist/sidecar/index.js +29 -12
- package/dist/sidecar/index.js.map +1 -1
- package/dist/state/__tests__/operations-ralph-phase.test.js +88 -1
- package/dist/state/__tests__/operations-ralph-phase.test.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.js +6 -0
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +11 -0
- package/dist/state/operations.js.map +1 -1
- package/dist/state/workflow-transition.d.ts +1 -1
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +7 -0
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +4 -3
- package/dist/subagents/tracker.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +36 -44
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +163 -15
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +10 -20
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +51 -21
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/ultragoal/__tests__/artifacts.test.js +764 -10
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/__tests__/docs-contract.test.js +57 -1
- package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
- package/dist/ultragoal/__tests__/steering-fixtures.d.ts +68 -0
- package/dist/ultragoal/__tests__/steering-fixtures.d.ts.map +1 -0
- package/dist/ultragoal/__tests__/steering-fixtures.js +259 -0
- package/dist/ultragoal/__tests__/steering-fixtures.js.map +1 -0
- package/dist/ultragoal/__tests__/steering-fixtures.test.d.ts +2 -0
- package/dist/ultragoal/__tests__/steering-fixtures.test.d.ts.map +1 -0
- package/dist/ultragoal/__tests__/steering-fixtures.test.js +65 -0
- package/dist/ultragoal/__tests__/steering-fixtures.test.js.map +1 -0
- package/dist/ultragoal/artifacts.d.ts +97 -2
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +837 -256
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/dist/utils/__tests__/sleep-resource.test.d.ts +2 -0
- package/dist/utils/__tests__/sleep-resource.test.d.ts.map +1 -0
- package/dist/utils/__tests__/sleep-resource.test.js +39 -0
- package/dist/utils/__tests__/sleep-resource.test.js.map +1 -0
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js +17 -6
- package/dist/utils/sleep.js.map +1 -1
- package/package.json +2 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +4 -3
- package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +56 -0
- package/plugins/oh-my-codex/hooks/hooks.json +77 -0
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +92 -50
- package/plugins/oh-my-codex/skills/autoresearch/SKILL.md +4 -0
- package/plugins/oh-my-codex/skills/autoresearch-goal/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/best-practice-research/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/cancel/SKILL.md +2 -2
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +8 -8
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/pipeline/SKILL.md +23 -12
- package/plugins/oh-my-codex/skills/plan/SKILL.md +8 -8
- package/plugins/oh-my-codex/skills/prometheus-strict/README.md +35 -0
- package/plugins/oh-my-codex/skills/prometheus-strict/SKILL.md +219 -0
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +7 -0
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +22 -7
- package/plugins/oh-my-codex/skills/team/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +38 -4
- package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +1 -1
- package/prompts/planner.md +1 -1
- package/prompts/prometheus-strict-metis.md +274 -0
- package/prompts/prometheus-strict-momus.md +82 -0
- package/prompts/prometheus-strict-oracle.md +107 -0
- package/prompts/researcher.md +22 -3
- package/skills/autopilot/SKILL.md +92 -50
- package/skills/autoresearch/SKILL.md +4 -0
- package/skills/autoresearch-goal/SKILL.md +1 -1
- package/skills/best-practice-research/SKILL.md +1 -1
- package/skills/cancel/SKILL.md +2 -2
- package/skills/deep-interview/SKILL.md +8 -8
- package/skills/omx-setup/SKILL.md +1 -1
- package/skills/pipeline/SKILL.md +23 -12
- package/skills/plan/SKILL.md +8 -8
- package/skills/prometheus-strict/README.md +35 -0
- package/skills/prometheus-strict/SKILL.md +219 -0
- package/skills/ralph/SKILL.md +7 -0
- package/skills/ralplan/SKILL.md +22 -7
- package/skills/team/SKILL.md +1 -1
- package/skills/ultragoal/SKILL.md +38 -4
- package/skills/ultrawork/SKILL.md +1 -1
- package/src/scripts/__tests__/codex-native-hook.test.ts +1757 -210
- package/src/scripts/__tests__/docs-site-contract.test.ts +47 -0
- package/src/scripts/__tests__/notify-dispatcher.test.ts +132 -3
- package/src/scripts/__tests__/run-test-files.test.ts +67 -0
- package/src/scripts/__tests__/smoke-packed-install.test.ts +31 -0
- package/src/scripts/__tests__/verify-native-agents.test.ts +23 -3
- package/src/scripts/cleanup-explore-harness.ts +1 -0
- package/src/scripts/codex-native-hook.ts +393 -40
- package/src/scripts/codex-native-pre-post.ts +16 -1
- package/src/scripts/notify-dispatcher.ts +202 -4
- package/src/scripts/notify-hook/process-runner.ts +40 -16
- package/src/scripts/notify-hook/team-dispatch.ts +9 -5
- package/src/scripts/notify-hook/team-tmux-guard.ts +7 -0
- package/src/scripts/run-test-files.ts +13 -0
- package/src/scripts/smoke-packed-install.ts +105 -0
- package/src/scripts/sync-plugin-mirror.ts +3 -3
- package/src/scripts/verify-native-agents.ts +2 -2
- package/templates/catalog-manifest.json +22 -0
|
@@ -5,10 +5,13 @@ import { mkdtemp, rm, mkdir, readFile, writeFile } from 'fs/promises';
|
|
|
5
5
|
import { basename, dirname, join, relative } from 'path';
|
|
6
6
|
import { tmpdir } from 'os';
|
|
7
7
|
import { existsSync } from 'fs';
|
|
8
|
+
import { createDeepInterviewStage, buildDeepInterviewInstruction } from '../stages/deep-interview.js';
|
|
8
9
|
import { createRalplanStage } from '../stages/ralplan.js';
|
|
9
10
|
import { createTeamExecStage, buildTeamInstruction } from '../stages/team-exec.js';
|
|
10
11
|
import { createRalphVerifyStage, createRalphStage, buildRalphInstruction } from '../stages/ralph-verify.js';
|
|
11
12
|
import { createCodeReviewStage, buildCodeReviewInstruction } from '../stages/code-review.js';
|
|
13
|
+
import { createUltragoalStage, buildUltragoalInstruction } from '../stages/ultragoal.js';
|
|
14
|
+
import { createUltraqaStage, buildUltraqaInstruction } from '../stages/ultraqa.js';
|
|
12
15
|
import { buildFollowupStaffingPlan } from '../../team/followup-planner.js';
|
|
13
16
|
import { packageRoot } from '../../utils/paths.js';
|
|
14
17
|
// ---------------------------------------------------------------------------
|
|
@@ -94,12 +97,13 @@ describe('RALPLAN Stage', () => {
|
|
|
94
97
|
const stage = createRalplanStage();
|
|
95
98
|
assert.equal(stage.name, 'ralplan');
|
|
96
99
|
});
|
|
97
|
-
it('
|
|
100
|
+
it('fails closed without planning artifacts and consensus evidence', async () => {
|
|
98
101
|
const stage = createRalplanStage();
|
|
99
102
|
const result = await stage.run(makeCtx());
|
|
100
|
-
assert.equal(result.status, '
|
|
103
|
+
assert.equal(result.status, 'failed');
|
|
101
104
|
assert.equal(result.artifacts.stage, 'ralplan');
|
|
102
105
|
assert.ok(result.artifacts.instruction);
|
|
106
|
+
assert.equal(result.error, 'ralplan_planning_artifacts_missing');
|
|
103
107
|
});
|
|
104
108
|
it('canSkip returns false when no plans directory exists', () => {
|
|
105
109
|
const stage = createRalplanStage();
|
|
@@ -118,13 +122,329 @@ describe('RALPLAN Stage', () => {
|
|
|
118
122
|
const stage = createRalplanStage();
|
|
119
123
|
assert.equal(stage.canSkip(makeCtx()), false);
|
|
120
124
|
});
|
|
121
|
-
it('canSkip returns
|
|
125
|
+
it('canSkip returns false when only prd and test spec plan files exist without consensus evidence', async () => {
|
|
126
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
127
|
+
await mkdir(plansDir, { recursive: true });
|
|
128
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
129
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
130
|
+
const stage = createRalplanStage();
|
|
131
|
+
assert.equal(stage.canSkip(makeCtx()), false);
|
|
132
|
+
});
|
|
133
|
+
it('run fails with consensus-specific artifact error when consensus exists but planning artifacts are missing', async () => {
|
|
134
|
+
const stage = createRalplanStage();
|
|
135
|
+
const result = await stage.run(makeCtx({
|
|
136
|
+
artifacts: {
|
|
137
|
+
ralplan: {
|
|
138
|
+
ralplanConsensusGate: {
|
|
139
|
+
complete: true,
|
|
140
|
+
sequence: ['architect-review', 'critic-review'],
|
|
141
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
|
|
142
|
+
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
}));
|
|
147
|
+
assert.equal(result.status, 'failed');
|
|
148
|
+
assert.equal(result.error, 'ralplan_planning_artifacts_missing_after_consensus');
|
|
149
|
+
assert.equal(result.artifacts.planningComplete, false);
|
|
150
|
+
});
|
|
151
|
+
it('canSkip returns true only when planning artifacts have sequential Architect and Critic approval evidence', async () => {
|
|
152
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
153
|
+
await mkdir(plansDir, { recursive: true });
|
|
154
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
155
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
156
|
+
const stage = createRalplanStage();
|
|
157
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
158
|
+
artifacts: {
|
|
159
|
+
ralplan: {
|
|
160
|
+
ralplanConsensusGate: {
|
|
161
|
+
complete: true,
|
|
162
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', summary: 'architect approved' },
|
|
163
|
+
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', summary: 'critic approved after architect' },
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
})), true);
|
|
168
|
+
});
|
|
169
|
+
it('canSkip honors explicit session-scoped consensus state before root state', async () => {
|
|
170
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
171
|
+
const stateDir = join(tempDir, '.omx', 'state');
|
|
172
|
+
const sessionDir = join(stateDir, 'sessions', 'sess-explicit');
|
|
173
|
+
await mkdir(plansDir, { recursive: true });
|
|
174
|
+
await mkdir(sessionDir, { recursive: true });
|
|
175
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
176
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
177
|
+
await writeFile(join(stateDir, 'autopilot-state.json'), JSON.stringify({
|
|
178
|
+
state: {
|
|
179
|
+
handoff_artifacts: {
|
|
180
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'reject', approved: true },
|
|
181
|
+
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
}));
|
|
185
|
+
await writeFile(join(sessionDir, 'autopilot-state.json'), JSON.stringify({
|
|
186
|
+
state: {
|
|
187
|
+
handoff_artifacts: {
|
|
188
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
|
|
189
|
+
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
}));
|
|
193
|
+
const stage = createRalplanStage();
|
|
194
|
+
assert.equal(stage.canSkip(makeCtx({ sessionId: 'sess-explicit' })), true);
|
|
195
|
+
});
|
|
196
|
+
it('canSkip fails closed when explicit session state is missing despite root consensus', async () => {
|
|
197
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
198
|
+
const stateDir = join(tempDir, '.omx', 'state');
|
|
199
|
+
await mkdir(plansDir, { recursive: true });
|
|
200
|
+
await mkdir(stateDir, { recursive: true });
|
|
201
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
202
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
203
|
+
await writeFile(join(stateDir, 'autopilot-state.json'), JSON.stringify({
|
|
204
|
+
state: {
|
|
205
|
+
handoff_artifacts: {
|
|
206
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
|
|
207
|
+
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
}));
|
|
211
|
+
const stage = createRalplanStage();
|
|
212
|
+
assert.equal(stage.canSkip(makeCtx({ sessionId: 'sess-missing' })), false);
|
|
213
|
+
});
|
|
214
|
+
it('canSkip fails closed for malformed explicit session ids instead of falling back to root consensus', async () => {
|
|
215
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
216
|
+
const stateDir = join(tempDir, '.omx', 'state');
|
|
217
|
+
await mkdir(plansDir, { recursive: true });
|
|
218
|
+
await mkdir(stateDir, { recursive: true });
|
|
219
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
220
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
221
|
+
await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
|
|
222
|
+
ralplanConsensusGate: {
|
|
223
|
+
complete: true,
|
|
224
|
+
sequence: ['architect-review', 'critic-review'],
|
|
225
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
|
|
226
|
+
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
|
|
227
|
+
},
|
|
228
|
+
}));
|
|
229
|
+
const stage = createRalplanStage();
|
|
230
|
+
for (const sessionId of ['../bad', 'a'.repeat(65), '']) {
|
|
231
|
+
assert.equal(stage.canSkip(makeCtx({ sessionId })), false);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
it('canSkip rejects blocker aliases even with approval-shaped booleans', async () => {
|
|
235
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
236
|
+
await mkdir(plansDir, { recursive: true });
|
|
237
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
238
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
239
|
+
const stage = createRalplanStage();
|
|
240
|
+
for (const blocker of [
|
|
241
|
+
{ blocking: true },
|
|
242
|
+
{ request_changes: true },
|
|
243
|
+
{ requestChanges: true },
|
|
244
|
+
{ status: 'request changes' },
|
|
245
|
+
{ recommendation: 'changes-requested' },
|
|
246
|
+
]) {
|
|
247
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
248
|
+
artifacts: {
|
|
249
|
+
ralplan: {
|
|
250
|
+
ralplanConsensusGate: {
|
|
251
|
+
complete: true,
|
|
252
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
|
|
253
|
+
ralplan_critic_review: { agent_role: 'critic', approved: true, clean: true, ...blocker },
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
})), false);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
it('canSkip returns false when Critic evidence is recorded before Architect evidence', async () => {
|
|
261
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
262
|
+
await mkdir(plansDir, { recursive: true });
|
|
263
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
264
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
265
|
+
const stage = createRalplanStage();
|
|
266
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
267
|
+
artifacts: {
|
|
268
|
+
ralplan: {
|
|
269
|
+
ralplanConsensusGate: {
|
|
270
|
+
complete: true,
|
|
271
|
+
sequence: ['critic-review', 'architect-review'],
|
|
272
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
|
|
273
|
+
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
})), false);
|
|
278
|
+
});
|
|
279
|
+
it('canSkip returns false when Critic timestamp predates Architect timestamp', async () => {
|
|
280
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
281
|
+
await mkdir(plansDir, { recursive: true });
|
|
282
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
283
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
284
|
+
const stage = createRalplanStage();
|
|
285
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
286
|
+
artifacts: {
|
|
287
|
+
ralplan: {
|
|
288
|
+
ralplanConsensusGate: {
|
|
289
|
+
complete: true,
|
|
290
|
+
sequence: ['architect-review', 'critic-review'],
|
|
291
|
+
ralplan_architect_review: {
|
|
292
|
+
agent_role: 'architect',
|
|
293
|
+
verdict: 'approve',
|
|
294
|
+
completed_at: '2026-05-21T10:05:00.000Z',
|
|
295
|
+
},
|
|
296
|
+
ralplan_critic_review: {
|
|
297
|
+
agent_role: 'critic',
|
|
298
|
+
verdict: 'approve',
|
|
299
|
+
completed_at: '2026-05-21T10:00:00.000Z',
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
})), false);
|
|
305
|
+
});
|
|
306
|
+
it('canSkip ignores ambient OMX_ROOT consensus state for local PRD/test-spec-only artifacts', async () => {
|
|
307
|
+
const ambientRoot = await mkdtemp(join(tmpdir(), 'omx-ralplan-ambient-'));
|
|
308
|
+
const previousOmxRoot = process.env.OMX_ROOT;
|
|
309
|
+
try {
|
|
310
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
311
|
+
await mkdir(plansDir, { recursive: true });
|
|
312
|
+
await writeFile(join(plansDir, 'prd-local.md'), '# Plan\n');
|
|
313
|
+
await writeFile(join(plansDir, 'test-spec-local.md'), '# Test Spec\n');
|
|
314
|
+
const ambientStateDir = join(ambientRoot, '.omx', 'state');
|
|
315
|
+
await mkdir(ambientStateDir, { recursive: true });
|
|
316
|
+
await writeFile(join(ambientStateDir, 'ralplan-state.json'), JSON.stringify({
|
|
317
|
+
current_phase: 'complete',
|
|
318
|
+
planning_complete: true,
|
|
319
|
+
ralplan_consensus_gate: {
|
|
320
|
+
complete: true,
|
|
321
|
+
ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', iteration: 1 },
|
|
322
|
+
ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', iteration: 1 },
|
|
323
|
+
},
|
|
324
|
+
}));
|
|
325
|
+
process.env.OMX_ROOT = ambientRoot;
|
|
326
|
+
const stage = createRalplanStage();
|
|
327
|
+
assert.equal(stage.canSkip(makeCtx()), false);
|
|
328
|
+
}
|
|
329
|
+
finally {
|
|
330
|
+
if (previousOmxRoot === undefined)
|
|
331
|
+
delete process.env.OMX_ROOT;
|
|
332
|
+
else
|
|
333
|
+
process.env.OMX_ROOT = previousOmxRoot;
|
|
334
|
+
await rm(ambientRoot, { recursive: true, force: true });
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
it('canSkip returns false for rejected consensus objects with approval-shaped booleans', async () => {
|
|
122
338
|
const plansDir = join(tempDir, '.omx', 'plans');
|
|
123
339
|
await mkdir(plansDir, { recursive: true });
|
|
124
340
|
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
125
341
|
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
126
342
|
const stage = createRalplanStage();
|
|
127
|
-
assert.equal(stage.canSkip(makeCtx(
|
|
343
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
344
|
+
artifacts: {
|
|
345
|
+
ralplan: {
|
|
346
|
+
ralplanConsensusGate: {
|
|
347
|
+
complete: true,
|
|
348
|
+
ralplan_architect_review: {
|
|
349
|
+
agent_role: 'architect',
|
|
350
|
+
verdict: 'reject',
|
|
351
|
+
approved: true,
|
|
352
|
+
clean: true,
|
|
353
|
+
},
|
|
354
|
+
ralplan_critic_review: {
|
|
355
|
+
agent_role: 'critic',
|
|
356
|
+
verdict: 'approve',
|
|
357
|
+
approved: true,
|
|
358
|
+
clean: true,
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
})), false);
|
|
364
|
+
});
|
|
365
|
+
it('canSkip returns false when consensus-shaped reviews do not record agent roles', async () => {
|
|
366
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
367
|
+
await mkdir(plansDir, { recursive: true });
|
|
368
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
369
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
370
|
+
const stage = createRalplanStage();
|
|
371
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
372
|
+
artifacts: {
|
|
373
|
+
ralplan: {
|
|
374
|
+
ralplanConsensusGate: {
|
|
375
|
+
complete: true,
|
|
376
|
+
ralplan_architect_review: { verdict: 'approve', summary: 'role missing' },
|
|
377
|
+
ralplan_critic_review: { verdict: 'approve', summary: 'role missing' },
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
})), false);
|
|
382
|
+
});
|
|
383
|
+
it('canSkip returns false when review history entries do not record agent roles', async () => {
|
|
384
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
385
|
+
await mkdir(plansDir, { recursive: true });
|
|
386
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
387
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
388
|
+
const stage = createRalplanStage();
|
|
389
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
390
|
+
artifacts: {
|
|
391
|
+
ralplan: {
|
|
392
|
+
review_history: [{
|
|
393
|
+
architect_review: { verdict: 'approve', summary: 'role missing' },
|
|
394
|
+
critic_review: { verdict: 'approve', summary: 'role missing' },
|
|
395
|
+
}],
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
})), false);
|
|
399
|
+
});
|
|
400
|
+
it('canSkip returns false when review arrays do not record agent roles', async () => {
|
|
401
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
402
|
+
await mkdir(plansDir, { recursive: true });
|
|
403
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
404
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
405
|
+
const stage = createRalplanStage();
|
|
406
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
407
|
+
artifacts: {
|
|
408
|
+
ralplan: {
|
|
409
|
+
architectReviews: [{ verdict: 'approve', summary: 'role missing' }],
|
|
410
|
+
criticReviews: [{ verdict: 'approve', summary: 'role missing' }],
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
})), false);
|
|
414
|
+
});
|
|
415
|
+
it('canSkip returns false when local state only has latest verdict fields', async () => {
|
|
416
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
417
|
+
const stateDir = join(tempDir, '.omx', 'state');
|
|
418
|
+
await mkdir(plansDir, { recursive: true });
|
|
419
|
+
await mkdir(stateDir, { recursive: true });
|
|
420
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
421
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
422
|
+
await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
|
|
423
|
+
current_phase: 'complete',
|
|
424
|
+
planning_complete: true,
|
|
425
|
+
latest_architect_verdict: 'approve',
|
|
426
|
+
latest_critic_verdict: 'approve',
|
|
427
|
+
}));
|
|
428
|
+
const stage = createRalplanStage();
|
|
429
|
+
assert.equal(stage.canSkip(makeCtx()), false);
|
|
430
|
+
});
|
|
431
|
+
it('canSkip returns false when Architect and Critic roles are swapped', async () => {
|
|
432
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
433
|
+
await mkdir(plansDir, { recursive: true });
|
|
434
|
+
await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
|
|
435
|
+
await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
|
|
436
|
+
const stage = createRalplanStage();
|
|
437
|
+
assert.equal(stage.canSkip(makeCtx({
|
|
438
|
+
artifacts: {
|
|
439
|
+
ralplan: {
|
|
440
|
+
ralplanConsensusGate: {
|
|
441
|
+
complete: true,
|
|
442
|
+
ralplan_architect_review: { agent_role: 'critic', verdict: 'approve' },
|
|
443
|
+
ralplan_critic_review: { agent_role: 'architect', verdict: 'approve' },
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
})), false);
|
|
128
448
|
});
|
|
129
449
|
it('canSkip returns false after non-clean code-review loopback even when plans exist', async () => {
|
|
130
450
|
const plansDir = join(tempDir, '.omx', 'plans');
|
|
@@ -186,11 +506,100 @@ describe('RALPLAN Stage', () => {
|
|
|
186
506
|
const result = await stage.run(makeCtx({ task: 'live ralplan run' }));
|
|
187
507
|
const artifacts = result.artifacts;
|
|
188
508
|
assert.equal(result.status, 'completed');
|
|
509
|
+
assert.equal(result.error, undefined);
|
|
189
510
|
assert.equal(artifacts.runtime, true);
|
|
190
511
|
assert.equal(artifacts.planningComplete, true);
|
|
512
|
+
assert.deepEqual(artifacts.ralplanConsensusGate, {
|
|
513
|
+
complete: true,
|
|
514
|
+
sequence: ['architect-review', 'critic-review'],
|
|
515
|
+
ralplan_architect_review: { agent_role: 'architect', iteration: 1, verdict: 'approve', summary: 'architect ok' },
|
|
516
|
+
ralplan_critic_review: { agent_role: 'critic', iteration: 1, verdict: 'approve', summary: 'critic ok' },
|
|
517
|
+
source: 'runtime-result',
|
|
518
|
+
blockedReason: null,
|
|
519
|
+
});
|
|
191
520
|
assert.equal(artifacts.iteration, 1);
|
|
192
521
|
assert.equal(artifacts.runtimeDrafted, true);
|
|
193
522
|
});
|
|
523
|
+
it('fails runtime handoff when consensus approves but test spec does not match selected PRD', async () => {
|
|
524
|
+
const stage = createRalplanStage({
|
|
525
|
+
executor: {
|
|
526
|
+
async draft() {
|
|
527
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
528
|
+
await mkdir(plansDir, { recursive: true });
|
|
529
|
+
const prdPath = join(plansDir, 'prd-new.md');
|
|
530
|
+
await writeFile(prdPath, '# New runtime plan\n');
|
|
531
|
+
await writeFile(join(plansDir, 'test-spec-old.md'), '# Stale runtime tests\n');
|
|
532
|
+
return { summary: 'drafted mismatched artifacts', planPath: prdPath };
|
|
533
|
+
},
|
|
534
|
+
async architectReview() {
|
|
535
|
+
return { verdict: 'approve', summary: 'architect ok' };
|
|
536
|
+
},
|
|
537
|
+
async criticReview() {
|
|
538
|
+
return { verdict: 'approve', summary: 'critic ok' };
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
});
|
|
542
|
+
const result = await stage.run(makeCtx({ task: 'live ralplan mismatched artifacts' }));
|
|
543
|
+
const artifacts = result.artifacts;
|
|
544
|
+
assert.equal(result.status, 'failed');
|
|
545
|
+
assert.equal(result.error, 'ralplan_planning_artifacts_missing_after_consensus');
|
|
546
|
+
assert.equal(artifacts.planningComplete, false);
|
|
547
|
+
assert.equal(artifacts.ralplanConsensusGate.complete, true);
|
|
548
|
+
});
|
|
549
|
+
it('fails runtime handoff when consensus approves but required planning artifacts are missing', async () => {
|
|
550
|
+
const stage = createRalplanStage({
|
|
551
|
+
executor: {
|
|
552
|
+
async draft() {
|
|
553
|
+
return { summary: 'draft without files' };
|
|
554
|
+
},
|
|
555
|
+
async architectReview() {
|
|
556
|
+
return { verdict: 'approve', summary: 'architect ok' };
|
|
557
|
+
},
|
|
558
|
+
async criticReview() {
|
|
559
|
+
return { verdict: 'approve', summary: 'critic ok' };
|
|
560
|
+
},
|
|
561
|
+
},
|
|
562
|
+
});
|
|
563
|
+
const result = await stage.run(makeCtx({ task: 'live ralplan no artifacts' }));
|
|
564
|
+
const artifacts = result.artifacts;
|
|
565
|
+
assert.equal(result.status, 'failed');
|
|
566
|
+
assert.equal(result.error, 'ralplan_planning_artifacts_missing_after_consensus');
|
|
567
|
+
assert.equal(artifacts.planningComplete, false);
|
|
568
|
+
assert.equal(artifacts.ralplanConsensusGate.complete, true);
|
|
569
|
+
});
|
|
570
|
+
it('fails runtime handoff when Critic has not approved after Architect', async () => {
|
|
571
|
+
const stage = createRalplanStage({
|
|
572
|
+
executor: {
|
|
573
|
+
async draft() {
|
|
574
|
+
const plansDir = join(tempDir, '.omx', 'plans');
|
|
575
|
+
await mkdir(plansDir, { recursive: true });
|
|
576
|
+
const prdPath = join(plansDir, 'prd-runtime.md');
|
|
577
|
+
await writeFile(prdPath, '# Runtime Plan\n');
|
|
578
|
+
await writeFile(join(plansDir, 'test-spec-runtime.md'), '# Runtime Tests\n');
|
|
579
|
+
return { summary: 'drafted', planPath: prdPath };
|
|
580
|
+
},
|
|
581
|
+
async architectReview() {
|
|
582
|
+
return { verdict: 'approve', summary: 'architect ok' };
|
|
583
|
+
},
|
|
584
|
+
async criticReview() {
|
|
585
|
+
return { verdict: 'iterate', summary: 'critic needs changes' };
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
maxIterations: 1,
|
|
589
|
+
});
|
|
590
|
+
const result = await stage.run(makeCtx({ task: 'live ralplan run' }));
|
|
591
|
+
const artifacts = result.artifacts;
|
|
592
|
+
assert.equal(result.status, 'failed');
|
|
593
|
+
assert.equal(result.error, 'ralplan_consensus_not_reached_after_1_iterations');
|
|
594
|
+
assert.deepEqual(artifacts.ralplanConsensusGate, {
|
|
595
|
+
complete: false,
|
|
596
|
+
sequence: ['architect-review', 'critic-review'],
|
|
597
|
+
ralplan_architect_review: null,
|
|
598
|
+
ralplan_critic_review: null,
|
|
599
|
+
source: null,
|
|
600
|
+
blockedReason: 'missing_sequential_architect_then_critic_approval',
|
|
601
|
+
});
|
|
602
|
+
});
|
|
194
603
|
it('canSkip returns false for non-prd plan files', async () => {
|
|
195
604
|
const plansDir = join(tempDir, '.omx', 'plans');
|
|
196
605
|
await mkdir(plansDir, { recursive: true });
|
|
@@ -1000,13 +1409,13 @@ describe('Ralph Verify Stage', () => {
|
|
|
1000
1409
|
// ---------------------------------------------------------------------------
|
|
1001
1410
|
// Strict Autopilot stage tests
|
|
1002
1411
|
// ---------------------------------------------------------------------------
|
|
1003
|
-
describe('
|
|
1412
|
+
describe('Explicit Legacy Ralph Stage', () => {
|
|
1004
1413
|
beforeEach(async () => { await setup(); });
|
|
1005
1414
|
afterEach(async () => { await cleanup(); });
|
|
1006
|
-
it('uses the
|
|
1415
|
+
it('uses the explicit legacy phase name ralph', () => {
|
|
1007
1416
|
assert.equal(createRalphStage().name, 'ralph');
|
|
1008
1417
|
});
|
|
1009
|
-
it('uses ralplan artifacts as the primary
|
|
1418
|
+
it('uses ralplan artifacts as the primary explicit legacy Ralph execution input', async () => {
|
|
1010
1419
|
const result = await createRalphStage().run(makeCtx({
|
|
1011
1420
|
artifacts: {
|
|
1012
1421
|
ralplan: { plan: 'approved plan' },
|
|
@@ -1017,14 +1426,56 @@ describe('Strict Autopilot Ralph Stage', () => {
|
|
|
1017
1426
|
assert.deepEqual(descriptor.executionArtifacts, { plan: 'approved plan' });
|
|
1018
1427
|
});
|
|
1019
1428
|
});
|
|
1429
|
+
describe('Default Autopilot Ultragoal Stage Adapters', () => {
|
|
1430
|
+
beforeEach(async () => { await setup(); });
|
|
1431
|
+
afterEach(async () => { await cleanup(); });
|
|
1432
|
+
it('creates a deep-interview descriptor and instruction', async () => {
|
|
1433
|
+
const stage = createDeepInterviewStage();
|
|
1434
|
+
assert.equal(stage.name, 'deep-interview');
|
|
1435
|
+
const result = await stage.run(makeCtx());
|
|
1436
|
+
const artifacts = result.artifacts;
|
|
1437
|
+
assert.equal(artifacts.stage, 'deep-interview');
|
|
1438
|
+
assert.match(artifacts.instruction, /^\$deep-interview /);
|
|
1439
|
+
assert.match(buildDeepInterviewInstruction('clarify me'), /^\$deep-interview /);
|
|
1440
|
+
});
|
|
1441
|
+
it('creates an ultragoal descriptor with explicit team condition', async () => {
|
|
1442
|
+
const stage = createUltragoalStage();
|
|
1443
|
+
assert.equal(stage.name, 'ultragoal');
|
|
1444
|
+
const result = await stage.run(makeCtx({ artifacts: { ralplan: { plan: 'approved' } } }));
|
|
1445
|
+
const artifacts = result.artifacts;
|
|
1446
|
+
const descriptor = artifacts.ultragoalDescriptor;
|
|
1447
|
+
assert.equal(artifacts.stage, 'ultragoal');
|
|
1448
|
+
assert.deepEqual(descriptor.ralplanArtifacts, { plan: 'approved' });
|
|
1449
|
+
assert.match(artifacts.team_condition, /Launch \$team only inside an active Ultragoal story/);
|
|
1450
|
+
assert.match(buildUltragoalInstruction('execute me'), /^\$ultragoal /);
|
|
1451
|
+
});
|
|
1452
|
+
it('creates an ultraqa gate that fails closed without evidence and can record clean skips', async () => {
|
|
1453
|
+
const missingEvidence = await createUltraqaStage().run(makeCtx({
|
|
1454
|
+
artifacts: { ultragoal: { tests: 'passed' }, 'code-review': { review_verdict: { clean: true } } },
|
|
1455
|
+
}));
|
|
1456
|
+
const missingArtifacts = missingEvidence.artifacts;
|
|
1457
|
+
const missingVerdict = missingArtifacts.qa_verdict;
|
|
1458
|
+
assert.equal(missingVerdict.clean, false);
|
|
1459
|
+
assert.equal(missingArtifacts.return_to_ralplan_reason, 'UltraQA evidence missing; fail closed and return to ralplan.');
|
|
1460
|
+
const skipped = await createUltraqaStage({ skipped: true, summary: 'Docs-only change; QA not applicable.' }).run(makeCtx());
|
|
1461
|
+
const skippedArtifacts = skipped.artifacts;
|
|
1462
|
+
const skippedVerdict = skippedArtifacts.qa_verdict;
|
|
1463
|
+
assert.equal(skippedVerdict.clean, true);
|
|
1464
|
+
assert.equal(skippedVerdict.skipped, true);
|
|
1465
|
+
assert.equal(skippedArtifacts.return_to_ralplan_reason, null);
|
|
1466
|
+
assert.match(buildUltraqaInstruction('qa me'), /^\$ultraqa /);
|
|
1467
|
+
});
|
|
1468
|
+
});
|
|
1020
1469
|
describe('Code Review Stage', () => {
|
|
1021
1470
|
beforeEach(async () => { await setup(); });
|
|
1022
1471
|
afterEach(async () => { await cleanup(); });
|
|
1023
|
-
it('creates a
|
|
1472
|
+
it('creates a code-review stage that fails closed without review evidence', async () => {
|
|
1024
1473
|
const stage = createCodeReviewStage();
|
|
1025
1474
|
assert.equal(stage.name, 'code-review');
|
|
1026
|
-
const result = await stage.run(makeCtx({ artifacts: {
|
|
1475
|
+
const result = await stage.run(makeCtx({ artifacts: { ultragoal: { tests: 'passed' } } }));
|
|
1027
1476
|
const artifacts = result.artifacts;
|
|
1477
|
+
const descriptor = artifacts.codeReviewDescriptor;
|
|
1478
|
+
assert.deepEqual(descriptor.executionArtifacts, { tests: 'passed' });
|
|
1028
1479
|
const verdict = artifacts.review_verdict;
|
|
1029
1480
|
assert.equal(result.status, 'completed');
|
|
1030
1481
|
assert.equal(verdict.clean, false);
|