oh-my-codex 0.15.0 → 0.15.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 +5 -5
- package/Cargo.toml +1 -1
- package/README.md +36 -5
- package/crates/omx-explore/src/main.rs +222 -12
- package/dist/agents/__tests__/native-config.test.js +40 -0
- package/dist/agents/__tests__/native-config.test.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 +6 -1
- package/dist/agents/native-config.js.map +1 -1
- package/dist/agents/policy.d.ts +1 -0
- package/dist/agents/policy.d.ts.map +1 -1
- package/dist/agents/policy.js +4 -0
- package/dist/agents/policy.js.map +1 -1
- package/dist/cli/__tests__/autoresearch-guided.test.js +37 -13
- package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-team.test.js +46 -1
- package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +225 -111
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +96 -1
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/explore.test.js +15 -2
- package/dist/cli/__tests__/explore.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +292 -3
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +223 -0
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-parity.test.js +86 -0
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +23 -0
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/question.test.js +76 -11
- package/dist/cli/__tests__/question.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +140 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +310 -4
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js +78 -19
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +79 -2
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/sidecar.test.d.ts +2 -0
- package/dist/cli/__tests__/sidecar.test.d.ts.map +1 -0
- package/dist/cli/__tests__/sidecar.test.js +24 -0
- package/dist/cli/__tests__/sidecar.test.js.map +1 -0
- package/dist/cli/__tests__/team.test.js +54 -7
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/autoresearch-guided.d.ts.map +1 -1
- package/dist/cli/autoresearch-guided.js +12 -4
- package/dist/cli/autoresearch-guided.js.map +1 -1
- package/dist/cli/codex-home.d.ts +4 -6
- package/dist/cli/codex-home.d.ts.map +1 -1
- package/dist/cli/codex-home.js +9 -41
- package/dist/cli/codex-home.js.map +1 -1
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +509 -279
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +6 -4
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +284 -25
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/omx.js +3 -1
- package/dist/cli/omx.js.map +1 -1
- package/dist/cli/plugin-marketplace.d.ts +13 -0
- package/dist/cli/plugin-marketplace.d.ts.map +1 -0
- package/dist/cli/plugin-marketplace.js +77 -0
- package/dist/cli/plugin-marketplace.js.map +1 -0
- package/dist/cli/question.d.ts +1 -1
- package/dist/cli/question.d.ts.map +1 -1
- package/dist/cli/question.js +26 -12
- package/dist/cli/question.js.map +1 -1
- package/dist/cli/setup-preferences.d.ts +20 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -0
- package/dist/cli/setup-preferences.js +71 -0
- package/dist/cli/setup-preferences.js.map +1 -0
- package/dist/cli/setup.d.ts +7 -5
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +271 -152
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/team.d.ts +1 -0
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +70 -15
- package/dist/cli/team.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +100 -3
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +6 -5
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/__tests__/generator-status-line-presets.test.d.ts +2 -0
- package/dist/config/__tests__/generator-status-line-presets.test.d.ts.map +1 -0
- package/dist/config/__tests__/generator-status-line-presets.test.js +203 -0
- package/dist/config/__tests__/generator-status-line-presets.test.js.map +1 -0
- package/dist/config/__tests__/models.test.js +23 -1
- package/dist/config/__tests__/models.test.js.map +1 -1
- package/dist/config/generator.d.ts +9 -1
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +184 -16
- package/dist/config/generator.js.map +1 -1
- package/dist/config/models.d.ts +5 -1
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +12 -2
- package/dist/config/models.js.map +1 -1
- package/dist/exec/followup.d.ts +44 -0
- package/dist/exec/followup.d.ts.map +1 -0
- package/dist/exec/followup.js +349 -0
- package/dist/exec/followup.js.map +1 -0
- package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/autopilot-skill-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +37 -0
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/codebase-map.test.js +63 -1
- package/dist/hooks/__tests__/codebase-map.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 +5 -5
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +12 -9
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +25 -18
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +23 -2
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +45 -2
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +17 -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 +121 -0
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +4 -4
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +103 -0
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +2 -2
- 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 +27 -13
- 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.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +35 -0
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +215 -0
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +70 -3
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js +5 -0
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.js +3 -2
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +9 -0
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/prompt-refactor-contract.test.js +22 -0
- package/dist/hooks/__tests__/prompt-refactor-contract.test.js.map +1 -0
- package/dist/hooks/codebase-map.d.ts.map +1 -1
- package/dist/hooks/codebase-map.js +83 -6
- package/dist/hooks/codebase-map.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 +35 -4
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts +6 -0
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +117 -13
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hooks/session.d.ts +2 -0
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +6 -0
- package/dist/hooks/session.js.map +1 -1
- package/dist/hud/__tests__/index.test.js +4 -4
- package/dist/hud/__tests__/index.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +4 -0
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/types.test.js +27 -0
- package/dist/hud/__tests__/types.test.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +8 -0
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/types.d.ts +9 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js +3 -0
- package/dist/hud/types.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js +23 -5
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +50 -7
- package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server.test.js +70 -12
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/bootstrap.d.ts +10 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +71 -26
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/state-server.d.ts +5 -11
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +16 -432
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/modes/__tests__/base-autoresearch-contract.test.js +1 -1
- package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +1 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +89 -5
- package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
- package/dist/pipeline/__tests__/stages.test.js +98 -1
- package/dist/pipeline/__tests__/stages.test.js.map +1 -1
- package/dist/pipeline/index.d.ts +5 -3
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/index.js +4 -3
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/orchestrator.d.ts +7 -6
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.js +90 -11
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/pipeline/review-verdict.d.ts +3 -0
- package/dist/pipeline/review-verdict.d.ts.map +1 -0
- package/dist/pipeline/review-verdict.js +14 -0
- package/dist/pipeline/review-verdict.js.map +1 -0
- package/dist/pipeline/stages/code-review.d.ts +33 -0
- package/dist/pipeline/stages/code-review.d.ts.map +1 -0
- package/dist/pipeline/stages/code-review.js +51 -0
- package/dist/pipeline/stages/code-review.js.map +1 -0
- package/dist/pipeline/stages/ralph-verify.d.ts +12 -2
- package/dist/pipeline/stages/ralph-verify.d.ts.map +1 -1
- package/dist/pipeline/stages/ralph-verify.js +24 -6
- package/dist/pipeline/stages/ralph-verify.js.map +1 -1
- package/dist/pipeline/stages/ralplan.d.ts +1 -1
- package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
- package/dist/pipeline/stages/ralplan.js +21 -1
- package/dist/pipeline/stages/ralplan.js.map +1 -1
- package/dist/pipeline/types.d.ts +14 -7
- package/dist/pipeline/types.d.ts.map +1 -1
- package/dist/pipeline/types.js +2 -2
- package/dist/planning/__tests__/artifacts.test.js +152 -1
- package/dist/planning/__tests__/artifacts.test.js.map +1 -1
- package/dist/planning/artifacts.d.ts +9 -0
- package/dist/planning/artifacts.d.ts.map +1 -1
- package/dist/planning/artifacts.js +60 -1
- package/dist/planning/artifacts.js.map +1 -1
- package/dist/question/__tests__/client.test.js +23 -3
- package/dist/question/__tests__/client.test.js.map +1 -1
- package/dist/question/__tests__/renderer.test.js +148 -37
- package/dist/question/__tests__/renderer.test.js.map +1 -1
- package/dist/question/__tests__/types.test.js +21 -0
- package/dist/question/__tests__/types.test.js.map +1 -1
- package/dist/question/__tests__/ui.test.js +155 -7
- package/dist/question/__tests__/ui.test.js.map +1 -1
- package/dist/question/client.d.ts +14 -4
- package/dist/question/client.d.ts.map +1 -1
- package/dist/question/client.js.map +1 -1
- package/dist/question/renderer.d.ts +11 -1
- package/dist/question/renderer.d.ts.map +1 -1
- package/dist/question/renderer.js +102 -7
- package/dist/question/renderer.js.map +1 -1
- package/dist/question/state.d.ts +2 -2
- package/dist/question/state.d.ts.map +1 -1
- package/dist/question/state.js +26 -17
- package/dist/question/state.js.map +1 -1
- package/dist/question/types.d.ts +25 -1
- package/dist/question/types.d.ts.map +1 -1
- package/dist/question/types.js +48 -13
- package/dist/question/types.js.map +1 -1
- package/dist/question/ui.d.ts +15 -2
- package/dist/question/ui.d.ts.map +1 -1
- package/dist/question/ui.js +268 -162
- package/dist/question/ui.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +415 -94
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/generate-release-body.test.js +36 -0
- package/dist/scripts/__tests__/generate-release-body.test.js.map +1 -1
- package/dist/scripts/__tests__/prompt-inventory.test.d.ts +2 -0
- package/dist/scripts/__tests__/prompt-inventory.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/prompt-inventory.test.js +56 -0
- package/dist/scripts/__tests__/prompt-inventory.test.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +232 -54
- 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 +12 -9
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/generate-release-body.d.ts.map +1 -1
- package/dist/scripts/generate-release-body.js +12 -3
- package/dist/scripts/generate-release-body.js.map +1 -1
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts +2 -0
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts.map +1 -0
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js +153 -0
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js.map +1 -0
- package/dist/scripts/notify-hook/managed-tmux.d.ts +4 -2
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.js +188 -6
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
- package/dist/scripts/notify-hook/process-runner.d.ts.map +1 -1
- package/dist/scripts/notify-hook/process-runner.js +7 -3
- 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 +96 -11
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +3 -3
- package/dist/scripts/notify-hook/team-worker-posttooluse.d.ts +34 -0
- package/dist/scripts/notify-hook/team-worker-posttooluse.d.ts.map +1 -0
- package/dist/scripts/notify-hook/team-worker-posttooluse.js +434 -0
- package/dist/scripts/notify-hook/team-worker-posttooluse.js.map +1 -0
- package/dist/scripts/notify-hook/team-worker.d.ts +1 -1
- package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +3 -43
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +25 -4
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.js +36 -5
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/prompt-inventory.d.ts +29 -0
- package/dist/scripts/prompt-inventory.d.ts.map +1 -0
- package/dist/scripts/prompt-inventory.js +178 -0
- package/dist/scripts/prompt-inventory.js.map +1 -0
- package/dist/scripts/run-test-files.js +1 -0
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/sidecar/__tests__/boundary.test.d.ts +2 -0
- package/dist/sidecar/__tests__/boundary.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/boundary.test.js +48 -0
- package/dist/sidecar/__tests__/boundary.test.js.map +1 -0
- package/dist/sidecar/__tests__/collector.test.d.ts +2 -0
- package/dist/sidecar/__tests__/collector.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/collector.test.js +162 -0
- package/dist/sidecar/__tests__/collector.test.js.map +1 -0
- package/dist/sidecar/__tests__/render.test.d.ts +2 -0
- package/dist/sidecar/__tests__/render.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/render.test.js +67 -0
- package/dist/sidecar/__tests__/render.test.js.map +1 -0
- package/dist/sidecar/__tests__/tmux.test.d.ts +2 -0
- package/dist/sidecar/__tests__/tmux.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/tmux.test.js +30 -0
- package/dist/sidecar/__tests__/tmux.test.js.map +1 -0
- package/dist/sidecar/__tests__/watch.test.d.ts +2 -0
- package/dist/sidecar/__tests__/watch.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/watch.test.js +42 -0
- package/dist/sidecar/__tests__/watch.test.js.map +1 -0
- package/dist/sidecar/collector.d.ts +4 -0
- package/dist/sidecar/collector.d.ts.map +1 -0
- package/dist/sidecar/collector.js +377 -0
- package/dist/sidecar/collector.js.map +1 -0
- package/dist/sidecar/index.d.ts +25 -0
- package/dist/sidecar/index.d.ts.map +1 -0
- package/dist/sidecar/index.js +165 -0
- package/dist/sidecar/index.js.map +1 -0
- package/dist/sidecar/render.d.ts +3 -0
- package/dist/sidecar/render.d.ts.map +1 -0
- package/dist/sidecar/render.js +72 -0
- package/dist/sidecar/render.js.map +1 -0
- package/dist/sidecar/tmux.d.ts +13 -0
- package/dist/sidecar/tmux.d.ts.map +1 -0
- package/dist/sidecar/tmux.js +44 -0
- package/dist/sidecar/tmux.js.map +1 -0
- package/dist/sidecar/types.d.ts +125 -0
- package/dist/sidecar/types.d.ts.map +1 -0
- package/dist/sidecar/types.js +2 -0
- package/dist/sidecar/types.js.map +1 -0
- package/dist/state/__tests__/operations.test.js +50 -22
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.js +9 -1
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/operations.d.ts +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +19 -7
- package/dist/state/operations.js.map +1 -1
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +1 -0
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/team/__tests__/commit-hygiene.test.d.ts +2 -0
- package/dist/team/__tests__/commit-hygiene.test.d.ts.map +1 -0
- package/dist/team/__tests__/commit-hygiene.test.js +93 -0
- package/dist/team/__tests__/commit-hygiene.test.js.map +1 -0
- package/dist/team/__tests__/delegation-policy.test.d.ts +2 -0
- package/dist/team/__tests__/delegation-policy.test.d.ts.map +1 -0
- package/dist/team/__tests__/delegation-policy.test.js +69 -0
- package/dist/team/__tests__/delegation-policy.test.js.map +1 -0
- package/dist/team/__tests__/events.test.js +54 -4
- package/dist/team/__tests__/events.test.js.map +1 -1
- package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts +2 -0
- package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts.map +1 -0
- package/dist/team/__tests__/hook-primary-e2e-contract.test.js +78 -0
- package/dist/team/__tests__/hook-primary-e2e-contract.test.js.map +1 -0
- package/dist/team/__tests__/model-contract.test.js +16 -0
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/repo-aware-decomposition.test.d.ts +2 -0
- package/dist/team/__tests__/repo-aware-decomposition.test.d.ts.map +1 -0
- package/dist/team/__tests__/repo-aware-decomposition.test.js +95 -0
- package/dist/team/__tests__/repo-aware-decomposition.test.js.map +1 -0
- package/dist/team/__tests__/runtime.test.js +623 -14
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +177 -1
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/state.test.js +110 -0
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +399 -2
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +94 -0
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/commit-hygiene.d.ts +22 -3
- package/dist/team/commit-hygiene.d.ts.map +1 -1
- package/dist/team/commit-hygiene.js +134 -2
- package/dist/team/commit-hygiene.js.map +1 -1
- package/dist/team/contracts.d.ts +1 -1
- package/dist/team/contracts.d.ts.map +1 -1
- package/dist/team/contracts.js +2 -0
- package/dist/team/contracts.js.map +1 -1
- package/dist/team/dag-schema.d.ts +38 -0
- package/dist/team/dag-schema.d.ts.map +1 -0
- package/dist/team/dag-schema.js +221 -0
- package/dist/team/dag-schema.js.map +1 -0
- package/dist/team/delegation-policy.d.ts +3 -0
- package/dist/team/delegation-policy.d.ts.map +1 -0
- package/dist/team/delegation-policy.js +82 -0
- package/dist/team/delegation-policy.js.map +1 -0
- package/dist/team/model-contract.d.ts +3 -1
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +44 -5
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/repo-aware-decomposition.d.ts +60 -0
- package/dist/team/repo-aware-decomposition.d.ts.map +1 -0
- package/dist/team/repo-aware-decomposition.js +229 -0
- package/dist/team/repo-aware-decomposition.js.map +1 -0
- package/dist/team/runtime.d.ts +27 -0
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +172 -52
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/state/tasks.d.ts.map +1 -1
- package/dist/team/state/tasks.js +33 -0
- package/dist/team/state/tasks.js.map +1 -1
- package/dist/team/state/types.d.ts +23 -1
- 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 +35 -0
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +281 -1
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts +27 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +6 -0
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts +1 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +105 -6
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +3 -0
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +77 -4
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/utils/agents-md.d.ts +3 -0
- package/dist/utils/agents-md.d.ts.map +1 -1
- package/dist/utils/agents-md.js +25 -0
- package/dist/utils/agents-md.js.map +1 -1
- package/package.json +3 -2
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +2 -2
- package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/analyze/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +134 -205
- package/plugins/oh-my-codex/skills/code-review/SKILL.md +4 -4
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +14 -7
- package/plugins/oh-my-codex/skills/doctor/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/help/SKILL.md +1 -1
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +41 -10
- package/plugins/oh-my-codex/skills/plan/SKILL.md +12 -14
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +2 -4
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +5 -9
- package/plugins/oh-my-codex/skills/security-review/SKILL.md +4 -4
- package/plugins/oh-my-codex/skills/team/SKILL.md +2 -5
- package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +2 -5
- package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +2 -3
- package/prompts/analyst.md +2 -2
- package/prompts/api-reviewer.md +2 -2
- package/prompts/architect.md +2 -2
- package/prompts/build-fixer.md +2 -2
- package/prompts/code-reviewer.md +15 -5
- package/prompts/code-simplifier.md +1 -1
- package/prompts/critic.md +35 -83
- package/prompts/debugger.md +2 -2
- package/prompts/dependency-expert.md +2 -2
- package/prompts/designer.md +2 -2
- package/prompts/executor.md +40 -114
- package/prompts/explore-harness.md +1 -1
- package/prompts/explore.md +37 -90
- package/prompts/git-master.md +2 -2
- package/prompts/information-architect.md +1 -1
- package/prompts/performance-reviewer.md +2 -2
- package/prompts/planner.md +35 -62
- package/prompts/product-analyst.md +2 -2
- package/prompts/product-manager.md +2 -2
- package/prompts/qa-tester.md +2 -2
- package/prompts/quality-reviewer.md +2 -2
- package/prompts/quality-strategist.md +2 -2
- package/prompts/researcher.md +46 -78
- package/prompts/security-reviewer.md +2 -2
- package/prompts/sisyphus-lite.md +2 -2
- package/prompts/style-reviewer.md +2 -2
- package/prompts/team-executor.md +1 -1
- package/prompts/test-engineer.md +2 -2
- package/prompts/ux-researcher.md +2 -2
- package/prompts/verifier.md +29 -34
- package/prompts/vision.md +2 -2
- package/prompts/writer.md +2 -2
- package/skills/ai-slop-cleaner/SKILL.md +1 -1
- package/skills/analyze/SKILL.md +1 -1
- package/skills/autopilot/SKILL.md +134 -205
- package/skills/build-fix/SKILL.md +4 -4
- package/skills/code-review/SKILL.md +4 -4
- package/skills/deep-interview/SKILL.md +14 -7
- package/skills/doctor/SKILL.md +1 -1
- package/skills/help/SKILL.md +1 -1
- package/skills/omx-setup/SKILL.md +41 -10
- package/skills/plan/SKILL.md +12 -14
- package/skills/ralph/SKILL.md +2 -4
- package/skills/ralplan/SKILL.md +5 -9
- package/skills/security-review/SKILL.md +4 -4
- package/skills/team/SKILL.md +2 -5
- package/skills/ultraqa/SKILL.md +2 -5
- package/skills/ultrawork/SKILL.md +2 -3
- package/src/scripts/__tests__/codex-native-hook.test.ts +502 -94
- package/src/scripts/__tests__/generate-release-body.test.ts +41 -0
- package/src/scripts/__tests__/prompt-inventory.test.ts +64 -0
- package/src/scripts/codex-native-hook.ts +293 -61
- package/src/scripts/codex-native-pre-post.ts +10 -8
- package/src/scripts/generate-release-body.ts +13 -2
- package/src/scripts/notify-hook/__tests__/team-worker-posttooluse.test.ts +180 -0
- package/src/scripts/notify-hook/managed-tmux.ts +196 -9
- package/src/scripts/notify-hook/process-runner.ts +7 -3
- package/src/scripts/notify-hook/team-dispatch.ts +103 -11
- package/src/scripts/notify-hook/team-tmux-guard.ts +3 -3
- package/src/scripts/notify-hook/team-worker-posttooluse.ts +536 -0
- package/src/scripts/notify-hook/team-worker.ts +4 -48
- package/src/scripts/notify-hook/tmux-injection.ts +24 -6
- package/src/scripts/notify-hook.ts +36 -5
- package/src/scripts/prompt-inventory.ts +218 -0
- package/src/scripts/run-test-files.ts +1 -0
- package/templates/AGENTS.md +34 -95
|
@@ -139,6 +139,47 @@ describe('generate-release-body', () => {
|
|
|
139
139
|
});
|
|
140
140
|
|
|
141
141
|
|
|
142
|
+
it('skips off-ancestry semver-previous tags when auto-resolving the compare base', async () => {
|
|
143
|
+
const root = await mkdtemp(join(tmpdir(), 'omx-generate-release-body-off-ancestry-'));
|
|
144
|
+
try {
|
|
145
|
+
git(root, ['init']);
|
|
146
|
+
git(root, ['config', 'user.name', 'Release Bot']);
|
|
147
|
+
git(root, ['config', 'user.email', 'release@example.com']);
|
|
148
|
+
await writeFile(join(root, 'notes.txt'), 'base\n');
|
|
149
|
+
git(root, ['add', '.']);
|
|
150
|
+
git(root, ['commit', '-m', 'base']);
|
|
151
|
+
git(root, ['tag', 'v0.14.3']);
|
|
152
|
+
|
|
153
|
+
await writeFile(join(root, 'notes.txt'), 'dev train\n');
|
|
154
|
+
git(root, ['add', 'notes.txt']);
|
|
155
|
+
git(root, ['commit', '-m', 'dev train']);
|
|
156
|
+
git(root, ['tag', 'v0.15.1']);
|
|
157
|
+
|
|
158
|
+
git(root, ['checkout', '-b', 'side-release', 'v0.14.3']);
|
|
159
|
+
await writeFile(join(root, 'side.txt'), 'side release\n');
|
|
160
|
+
git(root, ['add', 'side.txt']);
|
|
161
|
+
git(root, ['commit', '-m', 'side release']);
|
|
162
|
+
git(root, ['tag', 'v0.15.0']);
|
|
163
|
+
git(root, ['checkout', 'v0.15.1']);
|
|
164
|
+
|
|
165
|
+
await writeFile(join(root, 'RELEASE_BODY.md'), TEMPLATE);
|
|
166
|
+
await generateReleaseBody({
|
|
167
|
+
cwd: root,
|
|
168
|
+
templatePath: 'RELEASE_BODY.md',
|
|
169
|
+
outPath: 'RELEASE_BODY.generated.md',
|
|
170
|
+
currentTag: 'v0.15.1',
|
|
171
|
+
repo: 'example/oh-my-codex',
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const generated = await readFile(join(root, 'RELEASE_BODY.generated.md'), 'utf-8');
|
|
175
|
+
assert.match(generated, /`v0\.14\.3\.\.\.v0\.15\.1`/);
|
|
176
|
+
assert.doesNotMatch(generated, /`v0\.15\.0\.\.\.v0\.15\.1`/);
|
|
177
|
+
} finally {
|
|
178
|
+
await rm(root, { recursive: true, force: true });
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
|
|
142
183
|
it('rejects missing or inverted compare refs before rendering a compare link', async () => {
|
|
143
184
|
const root = await mkdtemp(join(tmpdir(), 'omx-generate-release-body-range-'));
|
|
144
185
|
try {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { mkdtemp, rm, writeFile, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { describe, it } from 'node:test';
|
|
6
|
+
import { buildPromptInventory, listPromptSurfacePaths, renderPromptInventoryMarkdown } from '../prompt-inventory.js';
|
|
7
|
+
|
|
8
|
+
describe('prompt inventory', () => {
|
|
9
|
+
it('counts prompt surfaces, absolute directives, markers, and duplicate fragments', async () => {
|
|
10
|
+
const root = await mkdtemp(join(tmpdir(), 'omx-prompt-inventory-'));
|
|
11
|
+
try {
|
|
12
|
+
await mkdir(join(root, 'templates'), { recursive: true });
|
|
13
|
+
await mkdir(join(root, 'prompts'), { recursive: true });
|
|
14
|
+
await mkdir(join(root, 'skills', 'worker'), { recursive: true });
|
|
15
|
+
await mkdir(join(root, 'docs', 'prompt-guidance-fragments'), { recursive: true });
|
|
16
|
+
await mkdir(join(root, 'src', 'hooks'), { recursive: true });
|
|
17
|
+
await mkdir(join(root, 'src', 'config'), { recursive: true });
|
|
18
|
+
await mkdir(join(root, 'src', 'cli'), { recursive: true });
|
|
19
|
+
|
|
20
|
+
const repeated = 'AUTO-CONTINUE for clear, already-requested, low-risk, reversible local work with evidence.';
|
|
21
|
+
await writeFile(join(root, 'AGENTS.md'), `# Root\n${repeated}\n<!-- omx:generated:agents-md -->\n`);
|
|
22
|
+
await writeFile(
|
|
23
|
+
join(root, 'templates', 'AGENTS.md'),
|
|
24
|
+
`# Template\nMUST preserve markers.\n${repeated}\n<!-- OMX:RUNTIME:START -->\n<!-- OMX:RUNTIME:END -->\n`,
|
|
25
|
+
);
|
|
26
|
+
await writeFile(join(root, 'prompts', 'executor.md'), `# Executor\nDO NOT stop early.\n${repeated}\n`);
|
|
27
|
+
await writeFile(join(root, 'skills', 'worker', 'SKILL.md'), '# Worker\nALWAYS claim tasks.\n');
|
|
28
|
+
await writeFile(join(root, 'docs', 'prompt-guidance-contract.md'), '# Contract\n');
|
|
29
|
+
await writeFile(join(root, 'docs', 'guidance-schema.md'), '# Schema\n');
|
|
30
|
+
await writeFile(join(root, 'docs', 'prompt-guidance-fragments', 'core.md'), 'fragment\n');
|
|
31
|
+
await writeFile(join(root, 'src', 'hooks', 'prompt-guidance-contract.ts'), 'export {};\n');
|
|
32
|
+
await writeFile(join(root, 'src', 'config', 'generator.ts'), 'export {};\n');
|
|
33
|
+
await writeFile(join(root, 'src', 'cli', 'setup.ts'), 'export {};\n');
|
|
34
|
+
|
|
35
|
+
const paths = listPromptSurfacePaths(root);
|
|
36
|
+
assert.deepEqual(paths, [
|
|
37
|
+
'AGENTS.md',
|
|
38
|
+
'docs/guidance-schema.md',
|
|
39
|
+
'docs/prompt-guidance-contract.md',
|
|
40
|
+
'docs/prompt-guidance-fragments/core.md',
|
|
41
|
+
'prompts/executor.md',
|
|
42
|
+
'skills/worker/SKILL.md',
|
|
43
|
+
'src/cli/setup.ts',
|
|
44
|
+
'src/config/generator.ts',
|
|
45
|
+
'src/hooks/prompt-guidance-contract.ts',
|
|
46
|
+
'templates/AGENTS.md',
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
const report = buildPromptInventory(root, '2026-01-01T00:00:00.000Z');
|
|
50
|
+
assert.equal(report.totals.files, paths.length);
|
|
51
|
+
assert.ok(report.totals.lines > 0);
|
|
52
|
+
assert.ok(report.totals.approximateTokens > 0);
|
|
53
|
+
assert.equal(report.totals.absoluteDirectiveCount, 6);
|
|
54
|
+
assert.equal(
|
|
55
|
+
report.surfaces.find((surface) => surface.path === 'templates/AGENTS.md')?.markers['<!-- OMX:RUNTIME:START -->'],
|
|
56
|
+
1,
|
|
57
|
+
);
|
|
58
|
+
assert.equal(report.duplicateFragmentFamilies[0]?.count, 3);
|
|
59
|
+
assert.match(renderPromptInventoryMarkdown(report), /# Prompt Inventory/);
|
|
60
|
+
} finally {
|
|
61
|
+
await rm(root, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { execFileSync } from "child_process";
|
|
2
|
-
import { existsSync, readFileSync } from "fs";
|
|
2
|
+
import { closeSync, existsSync, openSync, readFileSync, readSync } from "fs";
|
|
3
3
|
import { mkdir, readFile, readdir, writeFile } from "fs/promises";
|
|
4
|
-
import { join, resolve } from "path";
|
|
4
|
+
import { join, relative, resolve } from "path";
|
|
5
5
|
import { pathToFileURL } from "url";
|
|
6
6
|
import { readModeState, readModeStateForSession, updateModeState } from "../modes/base.js";
|
|
7
7
|
import {
|
|
8
8
|
listActiveSkills,
|
|
9
9
|
readVisibleSkillActiveState,
|
|
10
10
|
} from "../state/skill-active.js";
|
|
11
|
-
import { readSubagentSessionSummary } from "../subagents/tracker.js";
|
|
12
|
-
import { resolveCanonicalTeamStateRoot } from "../team/state-root.js";
|
|
13
11
|
import {
|
|
12
|
+
readSubagentSessionSummary,
|
|
13
|
+
recordSubagentTurnForSession,
|
|
14
|
+
} from "../subagents/tracker.js";
|
|
15
|
+
import { resolveCanonicalTeamStateRoot, resolveWorkerNotifyTeamStateRootPath } from "../team/state-root.js";
|
|
16
|
+
import {
|
|
17
|
+
appendToLog,
|
|
14
18
|
isSessionStateUsable,
|
|
15
19
|
readSessionState,
|
|
16
20
|
readUsableSessionState,
|
|
17
21
|
reconcileNativeSessionStart,
|
|
22
|
+
type SessionState,
|
|
18
23
|
} from "../hooks/session.js";
|
|
19
24
|
import {
|
|
20
25
|
appendTeamEvent,
|
|
@@ -25,6 +30,7 @@ import {
|
|
|
25
30
|
writeTeamPhase,
|
|
26
31
|
} from "../team/state.js";
|
|
27
32
|
import { omxNotepadPath, omxProjectMemoryPath } from "../utils/paths.js";
|
|
33
|
+
import { findGitLayout } from "../utils/git-layout.js";
|
|
28
34
|
import { getStateFilePath, getStatePath } from "../mcp/state-paths.js";
|
|
29
35
|
import {
|
|
30
36
|
detectKeywords,
|
|
@@ -43,6 +49,7 @@ import {
|
|
|
43
49
|
buildNativePreToolUseOutput,
|
|
44
50
|
detectMcpTransportFailure,
|
|
45
51
|
} from "./codex-native-pre-post.js";
|
|
52
|
+
import { handleTeamWorkerPostToolUseSuccess } from "./notify-hook/team-worker-posttooluse.js";
|
|
46
53
|
import {
|
|
47
54
|
resolveCodexExecutionSurface,
|
|
48
55
|
type CodexLauncherKind,
|
|
@@ -56,7 +63,8 @@ import { dispatchHookEvent } from "../hooks/extensibility/dispatcher.js";
|
|
|
56
63
|
import { reconcileHudForPromptSubmit } from "../hud/reconcile.js";
|
|
57
64
|
import { onSessionStart as buildWikiSessionStartContext } from "../wiki/lifecycle.js";
|
|
58
65
|
import { readAutoresearchCompletionStatus, readAutoresearchModeState } from "../autoresearch/skill-validation.js";
|
|
59
|
-
import {
|
|
66
|
+
import { readRunState } from "../runtime/run-state.js";
|
|
67
|
+
import { getRunContinuationSnapshot, shouldContinueRun } from "../runtime/run-loop.js";
|
|
60
68
|
import { triagePrompt } from "../hooks/triage-heuristic.js";
|
|
61
69
|
import { readTriageConfig } from "../hooks/triage-config.js";
|
|
62
70
|
import {
|
|
@@ -75,6 +83,7 @@ import {
|
|
|
75
83
|
evaluateFinalHandoffDocumentRefresh,
|
|
76
84
|
isFinalHandoffDocumentRefreshCandidate,
|
|
77
85
|
} from "../document-refresh/enforcer.js";
|
|
86
|
+
import { buildExecFollowupStopOutput } from "../exec/followup.js";
|
|
78
87
|
|
|
79
88
|
type CodexHookEventName =
|
|
80
89
|
| "SessionStart"
|
|
@@ -122,6 +131,7 @@ const SHORT_FOLLOWUP_PRIORITY_PATTERNS = [
|
|
|
122
131
|
/(?:按照|按|基于)(?:这个|上述|当前)?(?:plan|计划|方案)/u,
|
|
123
132
|
/\b(?:follow up|latest request|this turn|current turn|newest request)\b/i,
|
|
124
133
|
] as const;
|
|
134
|
+
const MAX_SESSION_META_LINE_BYTES = 256 * 1024;
|
|
125
135
|
|
|
126
136
|
function safeString(value: unknown): string {
|
|
127
137
|
return typeof value === "string" ? value : "";
|
|
@@ -131,6 +141,144 @@ function safeObject(value: unknown): Record<string, unknown> {
|
|
|
131
141
|
return value && typeof value === "object" ? value as Record<string, unknown> : {};
|
|
132
142
|
}
|
|
133
143
|
|
|
144
|
+
interface NativeSubagentSessionStartMetadata {
|
|
145
|
+
parentThreadId: string;
|
|
146
|
+
agentNickname?: string;
|
|
147
|
+
agentRole?: string;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function readBoundedFirstLineSync(path: string): string {
|
|
151
|
+
const fd = openSync(path, "r");
|
|
152
|
+
try {
|
|
153
|
+
const chunks: Buffer[] = [];
|
|
154
|
+
const buffer = Buffer.alloc(Math.min(8192, MAX_SESSION_META_LINE_BYTES));
|
|
155
|
+
let totalBytesRead = 0;
|
|
156
|
+
|
|
157
|
+
while (totalBytesRead < MAX_SESSION_META_LINE_BYTES) {
|
|
158
|
+
const bytesToRead = Math.min(buffer.length, MAX_SESSION_META_LINE_BYTES - totalBytesRead);
|
|
159
|
+
const bytesRead = readSync(fd, buffer, 0, bytesToRead, totalBytesRead);
|
|
160
|
+
if (bytesRead <= 0) break;
|
|
161
|
+
|
|
162
|
+
totalBytesRead += bytesRead;
|
|
163
|
+
const chunk = buffer.subarray(0, bytesRead);
|
|
164
|
+
const newlineOffset = chunk.indexOf(0x0a);
|
|
165
|
+
if (newlineOffset >= 0) {
|
|
166
|
+
chunks.push(Buffer.from(chunk.subarray(0, newlineOffset)));
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
chunks.push(Buffer.from(chunk));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return Buffer.concat(chunks).toString("utf-8").replace(/\r$/, "");
|
|
173
|
+
} finally {
|
|
174
|
+
closeSync(fd);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function readNativeSubagentSessionStartMetadata(transcriptPath: string): NativeSubagentSessionStartMetadata | null {
|
|
179
|
+
const normalizedPath = transcriptPath.trim();
|
|
180
|
+
if (!normalizedPath) return null;
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
const firstLine = readBoundedFirstLineSync(normalizedPath).trim();
|
|
184
|
+
if (!firstLine) return null;
|
|
185
|
+
const firstRecord = safeObject(JSON.parse(firstLine));
|
|
186
|
+
if (safeString(firstRecord.type) !== "session_meta") return null;
|
|
187
|
+
|
|
188
|
+
const payload = safeObject(firstRecord.payload);
|
|
189
|
+
const source = safeObject(payload.source);
|
|
190
|
+
const subagent = safeObject(source.subagent);
|
|
191
|
+
const threadSpawn = safeObject(subagent.thread_spawn);
|
|
192
|
+
const parentThreadId = safeString(threadSpawn.parent_thread_id).trim();
|
|
193
|
+
if (!parentThreadId) return null;
|
|
194
|
+
|
|
195
|
+
const agentNickname = safeString(threadSpawn.agent_nickname ?? payload.agent_nickname).trim();
|
|
196
|
+
const agentRole = safeString(threadSpawn.agent_role ?? payload.agent_role).trim();
|
|
197
|
+
return {
|
|
198
|
+
parentThreadId,
|
|
199
|
+
...(agentNickname ? { agentNickname } : {}),
|
|
200
|
+
...(agentRole ? { agentRole } : {}),
|
|
201
|
+
};
|
|
202
|
+
} catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async function recordNativeSubagentSessionStart(
|
|
208
|
+
cwd: string,
|
|
209
|
+
canonicalSessionId: string,
|
|
210
|
+
childSessionId: string,
|
|
211
|
+
metadata: NativeSubagentSessionStartMetadata,
|
|
212
|
+
transcriptPath: string,
|
|
213
|
+
): Promise<void> {
|
|
214
|
+
const trackingSessionIds = [...new Set([
|
|
215
|
+
canonicalSessionId.trim(),
|
|
216
|
+
metadata.parentThreadId.trim(),
|
|
217
|
+
].filter(Boolean))];
|
|
218
|
+
for (const sessionId of trackingSessionIds) {
|
|
219
|
+
await recordSubagentTurnForSession(cwd, {
|
|
220
|
+
sessionId,
|
|
221
|
+
threadId: metadata.parentThreadId,
|
|
222
|
+
}).catch(() => {});
|
|
223
|
+
await recordSubagentTurnForSession(cwd, {
|
|
224
|
+
sessionId,
|
|
225
|
+
threadId: childSessionId,
|
|
226
|
+
mode: metadata.agentRole,
|
|
227
|
+
}).catch(() => {});
|
|
228
|
+
}
|
|
229
|
+
await appendToLog(cwd, {
|
|
230
|
+
event: "subagent_session_start",
|
|
231
|
+
session_id: canonicalSessionId,
|
|
232
|
+
native_owner_session_id: metadata.parentThreadId,
|
|
233
|
+
native_session_id: childSessionId,
|
|
234
|
+
parent_thread_id: metadata.parentThreadId,
|
|
235
|
+
...(metadata.agentNickname ? { agent_nickname: metadata.agentNickname } : {}),
|
|
236
|
+
...(metadata.agentRole ? { agent_role: metadata.agentRole } : {}),
|
|
237
|
+
...(transcriptPath ? { transcript_path: transcriptPath } : {}),
|
|
238
|
+
timestamp: new Date().toISOString(),
|
|
239
|
+
}).catch(() => {});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async function nativeSubagentSessionStartBelongsToCanonicalSession(
|
|
243
|
+
cwd: string,
|
|
244
|
+
canonicalSessionId: string,
|
|
245
|
+
currentSessionState: SessionState | null,
|
|
246
|
+
metadata: NativeSubagentSessionStartMetadata,
|
|
247
|
+
): Promise<boolean> {
|
|
248
|
+
const parentThreadId = metadata.parentThreadId.trim();
|
|
249
|
+
if (!parentThreadId) return false;
|
|
250
|
+
|
|
251
|
+
const currentNativeSessionId = safeString(currentSessionState?.native_session_id).trim();
|
|
252
|
+
if (currentNativeSessionId && currentNativeSessionId === parentThreadId) {
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const summary = await readSubagentSessionSummary(cwd, canonicalSessionId).catch(() => null);
|
|
257
|
+
if (!summary) return false;
|
|
258
|
+
if (summary.leaderThreadId === parentThreadId) return true;
|
|
259
|
+
return summary.allThreadIds.includes(parentThreadId);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function recordIgnoredNativeSubagentSessionStart(
|
|
263
|
+
cwd: string,
|
|
264
|
+
canonicalSessionId: string,
|
|
265
|
+
childSessionId: string,
|
|
266
|
+
metadata: NativeSubagentSessionStartMetadata,
|
|
267
|
+
transcriptPath: string,
|
|
268
|
+
): Promise<void> {
|
|
269
|
+
await appendToLog(cwd, {
|
|
270
|
+
event: "subagent_session_start_ignored",
|
|
271
|
+
reason: "parent_not_in_canonical_session",
|
|
272
|
+
session_id: canonicalSessionId,
|
|
273
|
+
native_session_id: childSessionId,
|
|
274
|
+
parent_thread_id: metadata.parentThreadId,
|
|
275
|
+
...(metadata.agentNickname ? { agent_nickname: metadata.agentNickname } : {}),
|
|
276
|
+
...(metadata.agentRole ? { agent_role: metadata.agentRole } : {}),
|
|
277
|
+
...(transcriptPath ? { transcript_path: transcriptPath } : {}),
|
|
278
|
+
timestamp: new Date().toISOString(),
|
|
279
|
+
}).catch(() => {});
|
|
280
|
+
}
|
|
281
|
+
|
|
134
282
|
function safePositiveInteger(value: unknown): number | null {
|
|
135
283
|
if (typeof value === "number" && Number.isInteger(value) && value > 0) return value;
|
|
136
284
|
if (typeof value === "string" && value.trim() !== "") {
|
|
@@ -291,10 +439,49 @@ async function readActiveAutoresearchState(
|
|
|
291
439
|
return state;
|
|
292
440
|
}
|
|
293
441
|
|
|
442
|
+
interface ActiveRalphStopState {
|
|
443
|
+
state: Record<string, unknown>;
|
|
444
|
+
path: string;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function isRalphStartingPhase(state: Record<string, unknown>): boolean {
|
|
448
|
+
return safeString(state.current_phase ?? state.currentPhase).trim().toLowerCase() === "starting";
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function shouldHonorCanonicalTerminalRunState(
|
|
452
|
+
runState: Record<string, unknown> | null,
|
|
453
|
+
mode: string,
|
|
454
|
+
): boolean {
|
|
455
|
+
if (!runState) return false;
|
|
456
|
+
const runMode = safeString(runState.mode).trim();
|
|
457
|
+
if (runMode && runMode !== mode) return false;
|
|
458
|
+
return getRunContinuationSnapshot(runState)?.terminal === true;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
async function readCanonicalTerminalRunStateForStop(
|
|
462
|
+
cwd: string,
|
|
463
|
+
sessionId: string | undefined,
|
|
464
|
+
mode: string,
|
|
465
|
+
): Promise<Record<string, unknown> | null> {
|
|
466
|
+
if (!safeString(sessionId).trim()) return null;
|
|
467
|
+
const runState = await readRunState(cwd, sessionId).catch(() => null);
|
|
468
|
+
const runRecord = runState as unknown as Record<string, unknown> | null;
|
|
469
|
+
return shouldHonorCanonicalTerminalRunState(runRecord, mode) ? runRecord : null;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
async function isVisibleRalphActiveForSession(cwd: string, sessionId: string): Promise<boolean> {
|
|
473
|
+
const canonicalState = await readVisibleSkillActiveState(cwd, sessionId);
|
|
474
|
+
if (!canonicalState) return false;
|
|
475
|
+
return listActiveSkills(canonicalState).some((entry) => (
|
|
476
|
+
entry.skill === "ralph"
|
|
477
|
+
&& matchesSkillStopContext(entry, canonicalState, sessionId, "")
|
|
478
|
+
));
|
|
479
|
+
}
|
|
480
|
+
|
|
294
481
|
async function readActiveRalphState(
|
|
295
482
|
stateDir: string,
|
|
296
483
|
preferredSessionId?: string,
|
|
297
|
-
): Promise<
|
|
484
|
+
): Promise<ActiveRalphStopState | null> {
|
|
298
485
|
const cwd = resolve(stateDir, "..", "..");
|
|
299
486
|
const [rawSessionInfo, usableSessionInfo] = await Promise.all([
|
|
300
487
|
readSessionState(cwd),
|
|
@@ -316,17 +503,29 @@ async function readActiveRalphState(
|
|
|
316
503
|
if (staleCurrentSessionId && sessionId === staleCurrentSessionId) {
|
|
317
504
|
continue;
|
|
318
505
|
}
|
|
319
|
-
|
|
506
|
+
if (await readCanonicalTerminalRunStateForStop(cwd, sessionId, "ralph")) {
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
const sessionScopedPath = getStateFilePath("ralph-state.json", cwd, sessionId);
|
|
510
|
+
const sessionScoped = await readJsonIfExists(sessionScopedPath);
|
|
511
|
+
if (
|
|
512
|
+
sessionScoped?.active === true
|
|
513
|
+
&& isRalphStartingPhase(sessionScoped)
|
|
514
|
+
&& !(await isVisibleRalphActiveForSession(cwd, sessionId))
|
|
515
|
+
) {
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
320
518
|
if (sessionScoped?.active === true && shouldContinueRun(sessionScoped)) {
|
|
321
|
-
return sessionScoped;
|
|
519
|
+
return { state: sessionScoped, path: sessionScopedPath };
|
|
322
520
|
}
|
|
323
521
|
}
|
|
324
522
|
|
|
325
523
|
if (sessionCandidates.length > 0) return null;
|
|
326
524
|
|
|
327
|
-
const
|
|
525
|
+
const directPath = join(stateDir, "ralph-state.json");
|
|
526
|
+
const direct = await readJsonIfExists(directPath);
|
|
328
527
|
if (direct?.active === true && shouldContinueRun(direct)) {
|
|
329
|
-
return direct;
|
|
528
|
+
return { state: direct, path: directPath };
|
|
330
529
|
}
|
|
331
530
|
|
|
332
531
|
return null;
|
|
@@ -444,6 +643,22 @@ function tryReadGitValue(cwd: string, args: string[]): string | null {
|
|
|
444
643
|
}
|
|
445
644
|
}
|
|
446
645
|
|
|
646
|
+
|
|
647
|
+
function localExcludeAlreadyIgnoresOmx(cwd: string): boolean {
|
|
648
|
+
const layout = findGitLayout(cwd);
|
|
649
|
+
if (!layout) return false;
|
|
650
|
+
const excludePath = join(layout.gitDir, "info", "exclude");
|
|
651
|
+
try {
|
|
652
|
+
const lines = readFileSync(excludePath, "utf-8")
|
|
653
|
+
.split(/\r?\n/)
|
|
654
|
+
.map((line) => line.trim())
|
|
655
|
+
.filter((line) => line && !line.startsWith("#"));
|
|
656
|
+
return lines.includes(".omx/") || lines.includes(".omx");
|
|
657
|
+
} catch {
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
447
662
|
function isPathIgnoredByGit(cwd: string, path: string): boolean {
|
|
448
663
|
try {
|
|
449
664
|
execFileSync("git", ["check-ignore", "-q", path], {
|
|
@@ -460,7 +675,7 @@ function isPathIgnoredByGit(cwd: string, path: string): boolean {
|
|
|
460
675
|
async function ensureOmxLocalIgnoreEntry(cwd: string): Promise<{ changed: boolean; excludePath?: string }> {
|
|
461
676
|
const repoRoot = tryReadGitValue(cwd, ["rev-parse", "--show-toplevel"]);
|
|
462
677
|
if (!repoRoot) return { changed: false };
|
|
463
|
-
if (isPathIgnoredByGit(repoRoot, ".omx/")) {
|
|
678
|
+
if (localExcludeAlreadyIgnoresOmx(repoRoot) || isPathIgnoredByGit(repoRoot, ".omx/")) {
|
|
464
679
|
return { changed: false };
|
|
465
680
|
}
|
|
466
681
|
|
|
@@ -631,10 +846,10 @@ function resolveExecutionEnvironment(
|
|
|
631
846
|
transport: executionSurface.transport,
|
|
632
847
|
surface: "attached tmux runtime - tmux",
|
|
633
848
|
tmuxWorkflowGuidance: "omx team, omx hud, and omx question are directly usable in this session",
|
|
634
|
-
questionGuidance: "visible renderer available from the current pane",
|
|
849
|
+
questionGuidance: "visible temporary renderer available from the current pane; primary success JSON is answers[]",
|
|
635
850
|
teamRuntimeInstruction: "Use the durable OMX team runtime via `omx team ...` for coordinated execution; do not replace it with in-process fanout.",
|
|
636
851
|
teamHelpInstruction: "If you need runtime syntax, run `omx team --help` yourself.",
|
|
637
|
-
deepInterviewInstruction: "Deep-interview must ask each interview round via `omx question`; do not fall back to `request_user_input` or plain-text questioning. This session is already attached to tmux, so `omx question` can open its
|
|
852
|
+
deepInterviewInstruction: "Deep-interview must ask each interview round via `omx question`; do not fall back to `request_user_input` or plain-text questioning. This session is already attached to tmux, so `omx question` can open its temporary renderer directly over the leader pane. After starting `omx question` in a background terminal, wait for that terminal to finish and read the JSON answer before continuing the interview. Prefer `answers[0].answer` / `answers[]`; use legacy `answer` only as fallback. Deep-interview remains one question per round, so do not batch multiple interview rounds into one `questions[]` form. Stop remains blocked while a deep-interview question obligation is pending.",
|
|
638
853
|
leaderPaneHint,
|
|
639
854
|
};
|
|
640
855
|
}
|
|
@@ -905,48 +1120,14 @@ function parseTeamWorkerEnv(rawValue: string): { teamName: string; workerName: s
|
|
|
905
1120
|
};
|
|
906
1121
|
}
|
|
907
1122
|
|
|
908
|
-
async function readTeamStateRootFromJson(path: string): Promise<string | null> {
|
|
909
|
-
const parsed = await readJsonIfExists(path);
|
|
910
|
-
const value = safeString(parsed?.team_state_root).trim();
|
|
911
|
-
return value || null;
|
|
912
|
-
}
|
|
913
|
-
|
|
914
1123
|
async function resolveTeamStateDirForWorkerContext(
|
|
915
1124
|
cwd: string,
|
|
916
1125
|
workerContext: { teamName: string; workerName: string },
|
|
917
|
-
): Promise<string> {
|
|
918
|
-
|
|
919
|
-
if (explicitStateRoot) {
|
|
920
|
-
return resolve(cwd, explicitStateRoot);
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
const leaderCwd = safeString(process.env.OMX_TEAM_LEADER_CWD).trim();
|
|
924
|
-
const candidateStateDirs = [
|
|
925
|
-
...(leaderCwd ? [join(resolve(leaderCwd), ".omx", "state")] : []),
|
|
926
|
-
join(cwd, ".omx", "state"),
|
|
927
|
-
];
|
|
928
|
-
|
|
929
|
-
for (const candidateStateDir of candidateStateDirs) {
|
|
930
|
-
const teamRoot = join(candidateStateDir, "team", workerContext.teamName);
|
|
931
|
-
if (!existsSync(teamRoot)) continue;
|
|
932
|
-
|
|
933
|
-
const identityRoot = await readTeamStateRootFromJson(
|
|
934
|
-
join(teamRoot, "workers", workerContext.workerName, "identity.json"),
|
|
935
|
-
);
|
|
936
|
-
if (identityRoot) return resolve(cwd, identityRoot);
|
|
937
|
-
|
|
938
|
-
const manifestRoot = await readTeamStateRootFromJson(join(teamRoot, "manifest.v2.json"));
|
|
939
|
-
if (manifestRoot) return resolve(cwd, manifestRoot);
|
|
940
|
-
|
|
941
|
-
const configRoot = await readTeamStateRootFromJson(join(teamRoot, "config.json"));
|
|
942
|
-
if (configRoot) return resolve(cwd, configRoot);
|
|
943
|
-
|
|
944
|
-
return candidateStateDir;
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
return join(cwd, ".omx", "state");
|
|
1126
|
+
): Promise<string | null> {
|
|
1127
|
+
return resolveWorkerNotifyTeamStateRootPath(cwd, workerContext, process.env);
|
|
948
1128
|
}
|
|
949
1129
|
|
|
1130
|
+
|
|
950
1131
|
async function buildTeamWorkerStopOutput(
|
|
951
1132
|
cwd: string,
|
|
952
1133
|
): Promise<Record<string, unknown> | null> {
|
|
@@ -954,6 +1135,7 @@ async function buildTeamWorkerStopOutput(
|
|
|
954
1135
|
if (!workerContext) return null;
|
|
955
1136
|
|
|
956
1137
|
const stateDir = await resolveTeamStateDirForWorkerContext(cwd, workerContext);
|
|
1138
|
+
if (!stateDir) return null;
|
|
957
1139
|
const workerRoot = join(stateDir, "team", workerContext.teamName, "workers", workerContext.workerName);
|
|
958
1140
|
const [identity, status] = await Promise.all([
|
|
959
1141
|
readJsonIfExists(join(workerRoot, "identity.json")),
|
|
@@ -1053,6 +1235,9 @@ async function readTeamModeStateForStop(
|
|
|
1053
1235
|
}
|
|
1054
1236
|
|
|
1055
1237
|
async function buildTeamStopOutput(cwd: string, sessionId?: string): Promise<Record<string, unknown> | null> {
|
|
1238
|
+
if (await readCanonicalTerminalRunStateForStop(cwd, sessionId, "team")) {
|
|
1239
|
+
return null;
|
|
1240
|
+
}
|
|
1056
1241
|
const teamState = await readTeamModeStateForStop(cwd, sessionId);
|
|
1057
1242
|
if (teamState?.active !== true) return null;
|
|
1058
1243
|
const teamName = safeString(teamState.team_name).trim();
|
|
@@ -1303,7 +1488,7 @@ async function buildDeepInterviewQuestionStopOutput(
|
|
|
1303
1488
|
if (!obligationId) return null;
|
|
1304
1489
|
|
|
1305
1490
|
const systemMessage =
|
|
1306
|
-
`OMX deep-interview is still active (phase: ${phase}) and requires a structured question via omx question before stopping.`;
|
|
1491
|
+
`OMX deep-interview is still active (phase: ${phase}) and requires a structured question via omx question before stopping; read the returned answers[] JSON before continuing.`;
|
|
1307
1492
|
|
|
1308
1493
|
return {
|
|
1309
1494
|
obligationId,
|
|
@@ -1359,6 +1544,12 @@ function buildRepeatableStopSignature(
|
|
|
1359
1544
|
].join("|");
|
|
1360
1545
|
}
|
|
1361
1546
|
|
|
1547
|
+
function formatStopStatePath(cwd: string, statePath: string): string {
|
|
1548
|
+
const relativePath = relative(cwd, statePath);
|
|
1549
|
+
if (!relativePath || relativePath.startsWith("..")) return statePath;
|
|
1550
|
+
return relativePath.replace(/\\/g, "/");
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1362
1553
|
function readNativeStopSessionKey(
|
|
1363
1554
|
payload: CodexHookPayload,
|
|
1364
1555
|
canonicalSessionId?: string,
|
|
@@ -1672,6 +1863,8 @@ async function buildStopHookOutput(
|
|
|
1672
1863
|
const sessionId = readPayloadSessionId(payload);
|
|
1673
1864
|
const canonicalSessionId = await resolveInternalSessionIdForPayload(cwd, sessionId);
|
|
1674
1865
|
const threadId = readPayloadThreadId(payload);
|
|
1866
|
+
const execFollowupOutput = await buildExecFollowupStopOutput(cwd, canonicalSessionId);
|
|
1867
|
+
if (execFollowupOutput) return execFollowupOutput;
|
|
1675
1868
|
const ralphState = await readActiveRalphState(stateDir, canonicalSessionId);
|
|
1676
1869
|
if (!ralphState) {
|
|
1677
1870
|
const autoresearchState = await readActiveAutoresearchState(cwd, canonicalSessionId);
|
|
@@ -1784,7 +1977,9 @@ async function buildStopHookOutput(
|
|
|
1784
1977
|
);
|
|
1785
1978
|
}
|
|
1786
1979
|
|
|
1787
|
-
const canonicalTeam = await
|
|
1980
|
+
const canonicalTeam = await readCanonicalTerminalRunStateForStop(cwd, canonicalSessionId, "team")
|
|
1981
|
+
? null
|
|
1982
|
+
: await findCanonicalActiveTeamForSession(cwd, canonicalSessionId);
|
|
1788
1983
|
if (canonicalTeam) {
|
|
1789
1984
|
const canonicalTeamOutput = buildTeamStopOutputForPhase(
|
|
1790
1985
|
canonicalTeam.teamName,
|
|
@@ -1864,10 +2059,11 @@ async function buildStopHookOutput(
|
|
|
1864
2059
|
return null;
|
|
1865
2060
|
}
|
|
1866
2061
|
|
|
1867
|
-
const currentPhase = safeString(ralphState
|
|
2062
|
+
const currentPhase = safeString(ralphState.state.current_phase).trim() || "executing";
|
|
2063
|
+
const blockingPath = formatStopStatePath(cwd, ralphState.path);
|
|
1868
2064
|
const stopReason = `ralph_${currentPhase}`;
|
|
1869
2065
|
const systemMessage =
|
|
1870
|
-
`OMX Ralph is still active (phase: ${currentPhase}); continue the task and gather fresh verification evidence before stopping.`;
|
|
2066
|
+
`OMX Ralph is still active (phase: ${currentPhase}; state: ${blockingPath}); continue the task and gather fresh verification evidence before stopping.`;
|
|
1871
2067
|
|
|
1872
2068
|
return await returnPersistentStopBlock(
|
|
1873
2069
|
payload,
|
|
@@ -1903,13 +2099,46 @@ export async function dispatchCodexNativeHook(
|
|
|
1903
2099
|
const currentSessionState = await readUsableSessionState(cwd);
|
|
1904
2100
|
let canonicalSessionId = safeString(currentSessionState?.session_id).trim();
|
|
1905
2101
|
let resolvedNativeSessionId = nativeSessionId;
|
|
2102
|
+
let skipCanonicalSessionStartContext = false;
|
|
1906
2103
|
|
|
1907
2104
|
if (hookEventName === "SessionStart" && nativeSessionId) {
|
|
1908
|
-
const
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
2105
|
+
const transcriptPath = safeString(payload.transcript_path ?? payload.transcriptPath).trim();
|
|
2106
|
+
const subagentSessionStart = readNativeSubagentSessionStartMetadata(transcriptPath);
|
|
2107
|
+
if (subagentSessionStart && canonicalSessionId) {
|
|
2108
|
+
const belongsToCanonicalSession = await nativeSubagentSessionStartBelongsToCanonicalSession(
|
|
2109
|
+
cwd,
|
|
2110
|
+
canonicalSessionId,
|
|
2111
|
+
currentSessionState,
|
|
2112
|
+
subagentSessionStart,
|
|
2113
|
+
);
|
|
2114
|
+
if (belongsToCanonicalSession) {
|
|
2115
|
+
resolvedNativeSessionId = nativeSessionId;
|
|
2116
|
+
await recordNativeSubagentSessionStart(
|
|
2117
|
+
cwd,
|
|
2118
|
+
canonicalSessionId,
|
|
2119
|
+
nativeSessionId,
|
|
2120
|
+
subagentSessionStart,
|
|
2121
|
+
transcriptPath,
|
|
2122
|
+
);
|
|
2123
|
+
} else {
|
|
2124
|
+
skipCanonicalSessionStartContext = true;
|
|
2125
|
+
resolvedNativeSessionId =
|
|
2126
|
+
safeString(currentSessionState?.native_session_id).trim() || nativeSessionId;
|
|
2127
|
+
await recordIgnoredNativeSubagentSessionStart(
|
|
2128
|
+
cwd,
|
|
2129
|
+
canonicalSessionId,
|
|
2130
|
+
nativeSessionId,
|
|
2131
|
+
subagentSessionStart,
|
|
2132
|
+
transcriptPath,
|
|
2133
|
+
);
|
|
2134
|
+
}
|
|
2135
|
+
} else {
|
|
2136
|
+
const sessionState = await reconcileNativeSessionStart(cwd, nativeSessionId, {
|
|
2137
|
+
pid: options.sessionOwnerPid ?? resolveSessionOwnerPid(payload),
|
|
2138
|
+
});
|
|
2139
|
+
canonicalSessionId = safeString(sessionState.session_id).trim();
|
|
2140
|
+
resolvedNativeSessionId = safeString(sessionState.native_session_id).trim() || nativeSessionId;
|
|
2141
|
+
}
|
|
1913
2142
|
} else if (!canonicalSessionId) {
|
|
1914
2143
|
canonicalSessionId = safeString(currentSessionState?.session_id).trim();
|
|
1915
2144
|
}
|
|
@@ -2024,7 +2253,7 @@ export async function dispatchCodexNativeHook(
|
|
|
2024
2253
|
await reconcileHudForPromptSubmitFn(cwd, { sessionId: canonicalSessionId || sessionIdForState || undefined }).catch(() => {});
|
|
2025
2254
|
}
|
|
2026
2255
|
|
|
2027
|
-
if (omxEventName) {
|
|
2256
|
+
if (omxEventName && !skipCanonicalSessionStartContext) {
|
|
2028
2257
|
const baseContext = buildBaseContext(cwd, payload, hookEventName!, canonicalSessionId);
|
|
2029
2258
|
if (resolvedNativeSessionId) {
|
|
2030
2259
|
baseContext.native_session_id = resolvedNativeSessionId;
|
|
@@ -2046,7 +2275,7 @@ export async function dispatchCodexNativeHook(
|
|
|
2046
2275
|
await dispatchHookEvent(event, { cwd });
|
|
2047
2276
|
}
|
|
2048
2277
|
|
|
2049
|
-
if (hookEventName === "SessionStart" || hookEventName === "UserPromptSubmit") {
|
|
2278
|
+
if ((hookEventName === "SessionStart" && !skipCanonicalSessionStartContext) || hookEventName === "UserPromptSubmit") {
|
|
2050
2279
|
const additionalContext = hookEventName === "SessionStart"
|
|
2051
2280
|
? await buildSessionStartContext(cwd, canonicalSessionId || nativeSessionId, {
|
|
2052
2281
|
hookEventName,
|
|
@@ -2070,6 +2299,7 @@ export async function dispatchCodexNativeHook(
|
|
|
2070
2299
|
await markTeamTransportFailure(cwd, payload);
|
|
2071
2300
|
}
|
|
2072
2301
|
outputJson = buildNativePostToolUseOutput(payload);
|
|
2302
|
+
await handleTeamWorkerPostToolUseSuccess(payload, cwd);
|
|
2073
2303
|
} else if (hookEventName === "Stop") {
|
|
2074
2304
|
outputJson = await buildStopHookOutput(payload, cwd, stateDir);
|
|
2075
2305
|
}
|
|
@@ -2163,6 +2393,8 @@ export async function runCodexNativeHookCli(): Promise<void> {
|
|
|
2163
2393
|
const result = await dispatchCodexNativeHook(payload);
|
|
2164
2394
|
if (result.outputJson) {
|
|
2165
2395
|
writeNativeHookJsonStdout(result.outputJson);
|
|
2396
|
+
} else if (result.hookEventName === "Stop") {
|
|
2397
|
+
writeNativeHookJsonStdout({});
|
|
2166
2398
|
}
|
|
2167
2399
|
} catch (error) {
|
|
2168
2400
|
if (readHookEventName(payload) !== "Stop") {
|