oh-my-codex 0.14.4 → 0.15.1
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/.agents/plugins/marketplace.json +20 -0
- package/Cargo.lock +6 -6
- package/Cargo.toml +2 -1
- package/README.md +40 -7
- package/crates/omx-explore/Cargo.toml +1 -0
- package/crates/omx-explore/src/main.rs +246 -24
- package/crates/omx-mux/Cargo.toml +1 -0
- package/crates/omx-runtime/Cargo.toml +1 -0
- package/crates/omx-runtime-core/Cargo.toml +1 -0
- package/crates/omx-runtime-core/src/dispatch.rs +2 -1
- package/crates/omx-runtime-core/src/engine.rs +2 -2
- package/crates/omx-runtime-core/src/mailbox.rs +2 -1
- package/crates/omx-sparkshell/Cargo.toml +1 -0
- package/crates/omx-sparkshell/src/codex_bridge.rs +1 -0
- package/crates/omx-sparkshell/src/prompt.rs +1 -0
- package/crates/omx-sparkshell/src/threshold.rs +1 -0
- package/dist/agents/__tests__/native-config.test.js +98 -4
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/native-config.d.ts +4 -0
- package/dist/agents/native-config.d.ts.map +1 -1
- package/dist/agents/native-config.js +19 -3
- package/dist/agents/native-config.js.map +1 -1
- package/dist/agents/policy.d.ts +10 -0
- package/dist/agents/policy.d.ts.map +1 -0
- package/dist/agents/policy.js +61 -0
- package/dist/agents/policy.js.map +1 -0
- package/dist/catalog/__tests__/generator.test.js +2 -0
- package/dist/catalog/__tests__/generator.test.js.map +1 -1
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts +2 -0
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts.map +1 -0
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +72 -0
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +1 -0
- package/dist/catalog/installable.d.ts +5 -0
- package/dist/catalog/installable.d.ts.map +1 -0
- package/dist/catalog/installable.js +13 -0
- package/dist/catalog/installable.js.map +1 -0
- package/dist/catalog/skill-mirror.d.ts +20 -0
- package/dist/catalog/skill-mirror.d.ts.map +1 -0
- package/dist/catalog/skill-mirror.js +104 -0
- package/dist/catalog/skill-mirror.js.map +1 -0
- package/dist/cli/__tests__/ask.test.js +4 -1
- package/dist/cli/__tests__/ask.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.d.ts +2 -0
- package/dist/cli/__tests__/codex-plugin-layout.test.d.ts.map +1 -0
- package/dist/cli/__tests__/codex-plugin-layout.test.js +210 -0
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -0
- 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 +26 -9
- package/dist/cli/__tests__/explore.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +301 -7
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +358 -4
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/list.test.d.ts +2 -0
- package/dist/cli/__tests__/list.test.d.ts.map +1 -0
- package/dist/cli/__tests__/list.test.js +38 -0
- package/dist/cli/__tests__/list.test.js.map +1 -0
- 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__/mcp-serve.test.d.ts +2 -0
- package/dist/cli/__tests__/mcp-serve.test.d.ts.map +1 -0
- package/dist/cli/__tests__/mcp-serve.test.js +38 -0
- package/dist/cli/__tests__/mcp-serve.test.js.map +1 -0
- package/dist/cli/__tests__/nested-help-routing.test.js +1 -0
- package/dist/cli/__tests__/nested-help-routing.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +58 -3
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/question.test.js +209 -5
- package/dist/cli/__tests__/question.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +146 -3
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.d.ts +2 -0
- package/dist/cli/__tests__/setup-install-mode.test.d.ts.map +1 -0
- package/dist/cli/__tests__/setup-install-mode.test.js +873 -0
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -0
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js +83 -22
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +120 -2
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +32 -13
- package/dist/cli/__tests__/setup-skills-overwrite.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 +90 -42
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/version-sync-contract.test.js +11 -0
- package/dist/cli/__tests__/version-sync-contract.test.js.map +1 -1
- package/dist/cli/codex-home.d.ts +4 -5
- package/dist/cli/codex-home.d.ts.map +1 -1
- package/dist/cli/codex-home.js +9 -37
- 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 -278
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +13 -5
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +351 -60
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/list.d.ts +2 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +40 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/mcp-serve.d.ts +12 -0
- package/dist/cli/mcp-serve.d.ts.map +1 -0
- package/dist/cli/mcp-serve.js +63 -0
- package/dist/cli/mcp-serve.js.map +1 -0
- 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.map +1 -1
- package/dist/cli/question.js +27 -2
- 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 +12 -3
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +1080 -254
- 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 +22 -3
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +2 -8
- package/dist/cli/uninstall.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 +35 -2
- package/dist/config/__tests__/models.test.js.map +1 -1
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +2 -7
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/config/generator.d.ts +10 -0
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +259 -76
- package/dist/config/generator.js.map +1 -1
- package/dist/config/models.d.ts +13 -3
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +25 -5
- package/dist/config/models.js.map +1 -1
- package/dist/config/omx-first-party-mcp.d.ts +18 -0
- package/dist/config/omx-first-party-mcp.d.ts.map +1 -0
- package/dist/config/omx-first-party-mcp.js +76 -0
- package/dist/config/omx-first-party-mcp.js.map +1 -0
- package/dist/document-refresh/__tests__/enforcer.test.d.ts +2 -0
- package/dist/document-refresh/__tests__/enforcer.test.d.ts.map +1 -0
- package/dist/document-refresh/__tests__/enforcer.test.js +128 -0
- package/dist/document-refresh/__tests__/enforcer.test.js.map +1 -0
- package/dist/document-refresh/config.d.ts +9 -0
- package/dist/document-refresh/config.d.ts.map +1 -0
- package/dist/document-refresh/config.js +70 -0
- package/dist/document-refresh/config.js.map +1 -0
- package/dist/document-refresh/enforcer.d.ts +43 -0
- package/dist/document-refresh/enforcer.d.ts.map +1 -0
- package/dist/document-refresh/enforcer.js +329 -0
- package/dist/document-refresh/enforcer.js.map +1 -0
- 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__/codebase-map.test.js +63 -1
- package/dist/hooks/__tests__/codebase-map.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +10 -7
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +89 -0
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +84 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.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 +43 -0
- 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 +53 -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-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-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-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/__tests__/team-runtime-gating-docs-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js +28 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/triage-heuristic.test.js +59 -4
- package/dist/hooks/__tests__/triage-heuristic.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts +2 -0
- package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/visual-ralph-skill.test.js +44 -0
- package/dist/hooks/__tests__/visual-ralph-skill.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.map +1 -1
- package/dist/hooks/keyword-detector.js +19 -14
- 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 +89 -0
- 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/hooks/triage-heuristic.d.ts +2 -2
- package/dist/hooks/triage-heuristic.d.ts.map +1 -1
- package/dist/hooks/triage-heuristic.js +97 -20
- package/dist/hooks/triage-heuristic.js.map +1 -1
- package/dist/hooks/triage-state.d.ts +1 -1
- package/dist/hooks/triage-state.d.ts.map +1 -1
- package/dist/hooks/triage-state.js +2 -1
- package/dist/hooks/triage-state.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 +45 -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 +67 -9
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/bootstrap.d.ts +12 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +87 -29
- 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/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__/deep-interview.test.js +1 -1
- package/dist/question/__tests__/deep-interview.test.js.map +1 -1
- package/dist/question/__tests__/renderer.test.js +70 -0
- package/dist/question/__tests__/renderer.test.js.map +1 -1
- package/dist/question/__tests__/ui.test.js +49 -0
- package/dist/question/__tests__/ui.test.js.map +1 -1
- package/dist/question/renderer.d.ts +14 -1
- package/dist/question/renderer.d.ts.map +1 -1
- package/dist/question/renderer.js +109 -10
- package/dist/question/renderer.js.map +1 -1
- package/dist/question/state.d.ts +2 -0
- package/dist/question/state.d.ts.map +1 -1
- package/dist/question/state.js +4 -0
- package/dist/question/state.js.map +1 -1
- package/dist/question/types.d.ts +2 -1
- package/dist/question/types.d.ts.map +1 -1
- package/dist/question/types.js.map +1 -1
- package/dist/question/ui.d.ts.map +1 -1
- package/dist/question/ui.js +28 -8
- package/dist/question/ui.js.map +1 -1
- package/dist/runtime/__tests__/bridge.test.js +143 -1
- package/dist/runtime/__tests__/bridge.test.js.map +1 -1
- package/dist/runtime/bridge.d.ts +21 -0
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +54 -4
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +1904 -230
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/generate-release-body.test.js +90 -1
- package/dist/scripts/__tests__/generate-release-body.test.js.map +1 -1
- package/dist/scripts/__tests__/hook-derived-watcher.test.js +110 -2
- package/dist/scripts/__tests__/hook-derived-watcher.test.js.map +1 -1
- package/dist/scripts/__tests__/postinstall.test.js +7 -93
- package/dist/scripts/__tests__/postinstall.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/__tests__/run-test-files.test.d.ts +2 -0
- package/dist/scripts/__tests__/run-test-files.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/run-test-files.test.js +62 -0
- package/dist/scripts/__tests__/run-test-files.test.js.map +1 -0
- package/dist/scripts/__tests__/smoke-packed-install.test.js +13 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/__tests__/verify-native-agents.test.d.ts +2 -0
- package/dist/scripts/__tests__/verify-native-agents.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/verify-native-agents.test.js +166 -0
- package/dist/scripts/__tests__/verify-native-agents.test.js.map +1 -0
- package/dist/scripts/codex-execution-surface.d.ts +16 -0
- package/dist/scripts/codex-execution-surface.d.ts.map +1 -0
- package/dist/scripts/codex-execution-surface.js +42 -0
- package/dist/scripts/codex-execution-surface.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +418 -76
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts +8 -0
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +133 -19
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/generate-release-body.d.ts +1 -0
- package/dist/scripts/generate-release-body.d.ts.map +1 -1
- package/dist/scripts/generate-release-body.js +32 -3
- package/dist/scripts/generate-release-body.js.map +1 -1
- package/dist/scripts/hook-derived-watcher.js +46 -7
- package/dist/scripts/hook-derived-watcher.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +59 -9
- package/dist/scripts/notify-fallback-watcher.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.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.js +18 -1
- 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.js +36 -5
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/postinstall.d.ts +1 -5
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +3 -42
- package/dist/scripts/postinstall.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 +32 -2
- 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 +9 -1
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.d.ts +13 -0
- package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -0
- package/dist/scripts/sync-plugin-mirror.js +242 -0
- package/dist/scripts/sync-plugin-mirror.js.map +1 -0
- package/dist/scripts/verify-native-agents.d.ts +16 -0
- package/dist/scripts/verify-native-agents.d.ts.map +1 -0
- package/dist/scripts/verify-native-agents.js +188 -0
- package/dist/scripts/verify-native-agents.js.map +1 -0
- package/dist/session-history/search.d.ts.map +1 -1
- package/dist/session-history/search.js +7 -2
- package/dist/session-history/search.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/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/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 +18 -2
- 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 +677 -17
- 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 +301 -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 +34 -0
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +191 -50
- 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 +83 -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/__tests__/agents-model-table.test.js +8 -0
- package/dist/utils/__tests__/agents-model-table.test.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +42 -9
- package/dist/utils/__tests__/paths.test.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/dist/utils/agents-model-table.d.ts.map +1 -1
- package/dist/utils/agents-model-table.js +2 -3
- package/dist/utils/agents-model-table.js.map +1 -1
- package/package.json +14 -7
- package/plugins/oh-my-codex/.app.json +3 -0
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +30 -0
- package/plugins/oh-my-codex/.mcp.json +44 -0
- package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +114 -0
- package/plugins/oh-my-codex/skills/analyze/SKILL.md +148 -0
- package/plugins/oh-my-codex/skills/ask-claude/SKILL.md +61 -0
- package/plugins/oh-my-codex/skills/ask-gemini/SKILL.md +61 -0
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +231 -0
- package/plugins/oh-my-codex/skills/autoresearch/SKILL.md +68 -0
- package/plugins/oh-my-codex/skills/cancel/SKILL.md +399 -0
- package/plugins/oh-my-codex/skills/code-review/SKILL.md +290 -0
- package/plugins/oh-my-codex/skills/configure-notifications/SKILL.md +287 -0
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +464 -0
- package/plugins/oh-my-codex/skills/doctor/SKILL.md +239 -0
- package/plugins/oh-my-codex/skills/help/SKILL.md +202 -0
- package/plugins/oh-my-codex/skills/hud/SKILL.md +98 -0
- package/plugins/oh-my-codex/skills/note/SKILL.md +62 -0
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +135 -0
- package/plugins/oh-my-codex/skills/pipeline/SKILL.md +86 -0
- package/plugins/oh-my-codex/skills/plan/SKILL.md +276 -0
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +269 -0
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +162 -0
- package/plugins/oh-my-codex/skills/security-review/SKILL.md +300 -0
- package/plugins/oh-my-codex/skills/skill/SKILL.md +835 -0
- package/plugins/oh-my-codex/skills/team/SKILL.md +510 -0
- package/plugins/oh-my-codex/skills/trace/SKILL.md +33 -0
- package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +143 -0
- package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +175 -0
- package/plugins/oh-my-codex/skills/visual-ralph/SKILL.md +153 -0
- package/plugins/oh-my-codex/skills/visual-verdict/SKILL.md +76 -0
- package/plugins/oh-my-codex/skills/wiki/SKILL.md +57 -0
- package/plugins/oh-my-codex/skills/worker/SKILL.md +106 -0
- package/prompts/critic.md +35 -83
- package/prompts/executor.md +32 -109
- package/prompts/explore-harness.md +1 -1
- package/prompts/explore.md +37 -90
- package/prompts/planner.md +28 -58
- package/prompts/researcher.md +46 -78
- package/prompts/verifier.md +23 -31
- package/skills/autopilot/SKILL.md +1 -4
- package/skills/deep-interview/SKILL.md +8 -5
- package/skills/doctor/SKILL.md +45 -17
- package/skills/help/SKILL.md +2 -2
- package/skills/omx-setup/SKILL.md +52 -9
- package/skills/plan/SKILL.md +1 -4
- package/skills/ralph/SKILL.md +3 -5
- package/skills/ralplan/SKILL.md +2 -6
- package/skills/team/SKILL.md +2 -5
- package/skills/ultraqa/SKILL.md +1 -4
- package/skills/ultrawork/SKILL.md +2 -3
- package/skills/visual-ralph/SKILL.md +153 -0
- package/skills/web-clone/SKILL.md +12 -354
- package/src/scripts/__tests__/codex-native-hook.test.ts +2306 -224
- package/src/scripts/__tests__/generate-release-body.test.ts +109 -0
- package/src/scripts/__tests__/hook-derived-watcher.test.ts +132 -2
- package/src/scripts/__tests__/postinstall.test.ts +7 -104
- package/src/scripts/__tests__/prompt-inventory.test.ts +64 -0
- package/src/scripts/__tests__/run-test-files.test.ts +72 -0
- package/src/scripts/__tests__/smoke-packed-install.test.ts +15 -0
- package/src/scripts/__tests__/verify-native-agents.test.ts +204 -0
- package/src/scripts/codex-execution-surface.ts +73 -0
- package/src/scripts/codex-native-hook.ts +579 -82
- package/src/scripts/codex-native-pre-post.ts +157 -19
- package/src/scripts/generate-release-body.ts +34 -2
- package/src/scripts/hook-derived-watcher.ts +51 -8
- package/src/scripts/notify-fallback-watcher.ts +65 -9
- package/src/scripts/notify-hook/__tests__/team-worker-posttooluse.test.ts +180 -0
- package/src/scripts/notify-hook/managed-tmux.ts +22 -4
- 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.ts +36 -5
- package/src/scripts/postinstall.ts +4 -58
- package/src/scripts/prompt-inventory.ts +218 -0
- package/src/scripts/run-test-files.ts +41 -2
- package/src/scripts/smoke-packed-install.ts +10 -1
- package/src/scripts/sync-plugin-mirror.ts +360 -0
- package/src/scripts/verify-native-agents.ts +245 -0
- package/templates/AGENTS.md +26 -91
- package/templates/catalog-manifest.json +16 -1
|
@@ -1,31 +1,35 @@
|
|
|
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 { listActiveSkills, readVisibleSkillActiveState, } from "../state/skill-active.js";
|
|
8
|
-
import { readSubagentSessionSummary } from "../subagents/tracker.js";
|
|
9
|
-
import { resolveCanonicalTeamStateRoot } from "../team/state-root.js";
|
|
10
|
-
import { isSessionStateUsable, readSessionState, readUsableSessionState, reconcileNativeSessionStart, } from "../hooks/session.js";
|
|
8
|
+
import { readSubagentSessionSummary, recordSubagentTurnForSession, } from "../subagents/tracker.js";
|
|
9
|
+
import { resolveCanonicalTeamStateRoot, resolveWorkerNotifyTeamStateRootPath } from "../team/state-root.js";
|
|
10
|
+
import { appendToLog, isSessionStateUsable, readSessionState, readUsableSessionState, reconcileNativeSessionStart, } from "../hooks/session.js";
|
|
11
11
|
import { appendTeamEvent, readTeamLeaderAttention, readTeamManifestV2, readTeamPhase, writeTeamLeaderAttention, writeTeamPhase, } from "../team/state.js";
|
|
12
12
|
import { omxNotepadPath, omxProjectMemoryPath } from "../utils/paths.js";
|
|
13
|
+
import { findGitLayout } from "../utils/git-layout.js";
|
|
13
14
|
import { getStateFilePath, getStatePath } from "../mcp/state-paths.js";
|
|
14
15
|
import { detectKeywords, detectPrimaryKeyword, recordSkillActivation, } from "../hooks/keyword-detector.js";
|
|
15
16
|
import { detectNativeStopStallPattern, loadAutoNudgeConfig, normalizeAutoNudgeSignatureText, resolveEffectiveAutoNudgeResponse, } from "./notify-hook/auto-nudge.js";
|
|
16
17
|
import { buildNativePostToolUseOutput, buildNativePreToolUseOutput, detectMcpTransportFailure, } from "./codex-native-pre-post.js";
|
|
18
|
+
import { handleTeamWorkerPostToolUseSuccess } from "./notify-hook/team-worker-posttooluse.js";
|
|
19
|
+
import { resolveCodexExecutionSurface, } from "./codex-execution-surface.js";
|
|
17
20
|
import { buildNativeHookEvent, } from "../hooks/extensibility/events.js";
|
|
18
21
|
import { dispatchHookEvent } from "../hooks/extensibility/dispatcher.js";
|
|
19
22
|
import { reconcileHudForPromptSubmit } from "../hud/reconcile.js";
|
|
20
|
-
import { shellEscapeSingle } from "../hud/tmux.js";
|
|
21
23
|
import { onSessionStart as buildWikiSessionStartContext } from "../wiki/lifecycle.js";
|
|
22
24
|
import { readAutoresearchCompletionStatus, readAutoresearchModeState } from "../autoresearch/skill-validation.js";
|
|
23
|
-
import {
|
|
25
|
+
import { readRunState } from "../runtime/run-state.js";
|
|
26
|
+
import { getRunContinuationSnapshot, shouldContinueRun } from "../runtime/run-loop.js";
|
|
24
27
|
import { triagePrompt } from "../hooks/triage-heuristic.js";
|
|
25
28
|
import { readTriageConfig } from "../hooks/triage-config.js";
|
|
26
29
|
import { readTriageState, writeTriageState, shouldSuppressFollowup, promptSignature, } from "../hooks/triage-state.js";
|
|
27
30
|
import { isPendingDeepInterviewQuestionEnforcement, reconcileDeepInterviewQuestionEnforcementFromAnsweredRecords, } from "../question/deep-interview.js";
|
|
28
|
-
import {
|
|
31
|
+
import { buildDocumentRefreshAdvisoryOutput, evaluateFinalHandoffDocumentRefresh, isFinalHandoffDocumentRefreshCandidate, } from "../document-refresh/enforcer.js";
|
|
32
|
+
import { buildExecFollowupStopOutput } from "../exec/followup.js";
|
|
29
33
|
const TERMINAL_MODE_PHASES = new Set(["complete", "failed", "cancelled"]);
|
|
30
34
|
const SKILL_STOP_BLOCKERS = new Set(["ralplan"]);
|
|
31
35
|
const TEAM_TERMINAL_TASK_STATUSES = new Set(["completed", "failed"]);
|
|
@@ -49,12 +53,125 @@ const SHORT_FOLLOWUP_PRIORITY_PATTERNS = [
|
|
|
49
53
|
/(?:按照|按|基于)(?:这个|上述|当前)?(?:plan|计划|方案)/u,
|
|
50
54
|
/\b(?:follow up|latest request|this turn|current turn|newest request)\b/i,
|
|
51
55
|
];
|
|
56
|
+
const MAX_SESSION_META_LINE_BYTES = 256 * 1024;
|
|
52
57
|
function safeString(value) {
|
|
53
58
|
return typeof value === "string" ? value : "";
|
|
54
59
|
}
|
|
55
60
|
function safeObject(value) {
|
|
56
61
|
return value && typeof value === "object" ? value : {};
|
|
57
62
|
}
|
|
63
|
+
function readBoundedFirstLineSync(path) {
|
|
64
|
+
const fd = openSync(path, "r");
|
|
65
|
+
try {
|
|
66
|
+
const chunks = [];
|
|
67
|
+
const buffer = Buffer.alloc(Math.min(8192, MAX_SESSION_META_LINE_BYTES));
|
|
68
|
+
let totalBytesRead = 0;
|
|
69
|
+
while (totalBytesRead < MAX_SESSION_META_LINE_BYTES) {
|
|
70
|
+
const bytesToRead = Math.min(buffer.length, MAX_SESSION_META_LINE_BYTES - totalBytesRead);
|
|
71
|
+
const bytesRead = readSync(fd, buffer, 0, bytesToRead, totalBytesRead);
|
|
72
|
+
if (bytesRead <= 0)
|
|
73
|
+
break;
|
|
74
|
+
totalBytesRead += bytesRead;
|
|
75
|
+
const chunk = buffer.subarray(0, bytesRead);
|
|
76
|
+
const newlineOffset = chunk.indexOf(0x0a);
|
|
77
|
+
if (newlineOffset >= 0) {
|
|
78
|
+
chunks.push(Buffer.from(chunk.subarray(0, newlineOffset)));
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
chunks.push(Buffer.from(chunk));
|
|
82
|
+
}
|
|
83
|
+
return Buffer.concat(chunks).toString("utf-8").replace(/\r$/, "");
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
closeSync(fd);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function readNativeSubagentSessionStartMetadata(transcriptPath) {
|
|
90
|
+
const normalizedPath = transcriptPath.trim();
|
|
91
|
+
if (!normalizedPath)
|
|
92
|
+
return null;
|
|
93
|
+
try {
|
|
94
|
+
const firstLine = readBoundedFirstLineSync(normalizedPath).trim();
|
|
95
|
+
if (!firstLine)
|
|
96
|
+
return null;
|
|
97
|
+
const firstRecord = safeObject(JSON.parse(firstLine));
|
|
98
|
+
if (safeString(firstRecord.type) !== "session_meta")
|
|
99
|
+
return null;
|
|
100
|
+
const payload = safeObject(firstRecord.payload);
|
|
101
|
+
const source = safeObject(payload.source);
|
|
102
|
+
const subagent = safeObject(source.subagent);
|
|
103
|
+
const threadSpawn = safeObject(subagent.thread_spawn);
|
|
104
|
+
const parentThreadId = safeString(threadSpawn.parent_thread_id).trim();
|
|
105
|
+
if (!parentThreadId)
|
|
106
|
+
return null;
|
|
107
|
+
const agentNickname = safeString(threadSpawn.agent_nickname ?? payload.agent_nickname).trim();
|
|
108
|
+
const agentRole = safeString(threadSpawn.agent_role ?? payload.agent_role).trim();
|
|
109
|
+
return {
|
|
110
|
+
parentThreadId,
|
|
111
|
+
...(agentNickname ? { agentNickname } : {}),
|
|
112
|
+
...(agentRole ? { agentRole } : {}),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async function recordNativeSubagentSessionStart(cwd, canonicalSessionId, childSessionId, metadata, transcriptPath) {
|
|
120
|
+
const trackingSessionIds = [...new Set([
|
|
121
|
+
canonicalSessionId.trim(),
|
|
122
|
+
metadata.parentThreadId.trim(),
|
|
123
|
+
].filter(Boolean))];
|
|
124
|
+
for (const sessionId of trackingSessionIds) {
|
|
125
|
+
await recordSubagentTurnForSession(cwd, {
|
|
126
|
+
sessionId,
|
|
127
|
+
threadId: metadata.parentThreadId,
|
|
128
|
+
}).catch(() => { });
|
|
129
|
+
await recordSubagentTurnForSession(cwd, {
|
|
130
|
+
sessionId,
|
|
131
|
+
threadId: childSessionId,
|
|
132
|
+
mode: metadata.agentRole,
|
|
133
|
+
}).catch(() => { });
|
|
134
|
+
}
|
|
135
|
+
await appendToLog(cwd, {
|
|
136
|
+
event: "subagent_session_start",
|
|
137
|
+
session_id: canonicalSessionId,
|
|
138
|
+
native_owner_session_id: metadata.parentThreadId,
|
|
139
|
+
native_session_id: childSessionId,
|
|
140
|
+
parent_thread_id: metadata.parentThreadId,
|
|
141
|
+
...(metadata.agentNickname ? { agent_nickname: metadata.agentNickname } : {}),
|
|
142
|
+
...(metadata.agentRole ? { agent_role: metadata.agentRole } : {}),
|
|
143
|
+
...(transcriptPath ? { transcript_path: transcriptPath } : {}),
|
|
144
|
+
timestamp: new Date().toISOString(),
|
|
145
|
+
}).catch(() => { });
|
|
146
|
+
}
|
|
147
|
+
async function nativeSubagentSessionStartBelongsToCanonicalSession(cwd, canonicalSessionId, currentSessionState, metadata) {
|
|
148
|
+
const parentThreadId = metadata.parentThreadId.trim();
|
|
149
|
+
if (!parentThreadId)
|
|
150
|
+
return false;
|
|
151
|
+
const currentNativeSessionId = safeString(currentSessionState?.native_session_id).trim();
|
|
152
|
+
if (currentNativeSessionId && currentNativeSessionId === parentThreadId) {
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
const summary = await readSubagentSessionSummary(cwd, canonicalSessionId).catch(() => null);
|
|
156
|
+
if (!summary)
|
|
157
|
+
return false;
|
|
158
|
+
if (summary.leaderThreadId === parentThreadId)
|
|
159
|
+
return true;
|
|
160
|
+
return summary.allThreadIds.includes(parentThreadId);
|
|
161
|
+
}
|
|
162
|
+
async function recordIgnoredNativeSubagentSessionStart(cwd, canonicalSessionId, childSessionId, metadata, transcriptPath) {
|
|
163
|
+
await appendToLog(cwd, {
|
|
164
|
+
event: "subagent_session_start_ignored",
|
|
165
|
+
reason: "parent_not_in_canonical_session",
|
|
166
|
+
session_id: canonicalSessionId,
|
|
167
|
+
native_session_id: childSessionId,
|
|
168
|
+
parent_thread_id: metadata.parentThreadId,
|
|
169
|
+
...(metadata.agentNickname ? { agent_nickname: metadata.agentNickname } : {}),
|
|
170
|
+
...(metadata.agentRole ? { agent_role: metadata.agentRole } : {}),
|
|
171
|
+
...(transcriptPath ? { transcript_path: transcriptPath } : {}),
|
|
172
|
+
timestamp: new Date().toISOString(),
|
|
173
|
+
}).catch(() => { });
|
|
174
|
+
}
|
|
58
175
|
function safePositiveInteger(value) {
|
|
59
176
|
if (typeof value === "number" && Number.isInteger(value) && value > 0)
|
|
60
177
|
return value;
|
|
@@ -192,6 +309,31 @@ async function readActiveAutoresearchState(cwd, sessionId) {
|
|
|
192
309
|
return null;
|
|
193
310
|
return state;
|
|
194
311
|
}
|
|
312
|
+
function isRalphStartingPhase(state) {
|
|
313
|
+
return safeString(state.current_phase ?? state.currentPhase).trim().toLowerCase() === "starting";
|
|
314
|
+
}
|
|
315
|
+
function shouldHonorCanonicalTerminalRunState(runState, mode) {
|
|
316
|
+
if (!runState)
|
|
317
|
+
return false;
|
|
318
|
+
const runMode = safeString(runState.mode).trim();
|
|
319
|
+
if (runMode && runMode !== mode)
|
|
320
|
+
return false;
|
|
321
|
+
return getRunContinuationSnapshot(runState)?.terminal === true;
|
|
322
|
+
}
|
|
323
|
+
async function readCanonicalTerminalRunStateForStop(cwd, sessionId, mode) {
|
|
324
|
+
if (!safeString(sessionId).trim())
|
|
325
|
+
return null;
|
|
326
|
+
const runState = await readRunState(cwd, sessionId).catch(() => null);
|
|
327
|
+
const runRecord = runState;
|
|
328
|
+
return shouldHonorCanonicalTerminalRunState(runRecord, mode) ? runRecord : null;
|
|
329
|
+
}
|
|
330
|
+
async function isVisibleRalphActiveForSession(cwd, sessionId) {
|
|
331
|
+
const canonicalState = await readVisibleSkillActiveState(cwd, sessionId);
|
|
332
|
+
if (!canonicalState)
|
|
333
|
+
return false;
|
|
334
|
+
return listActiveSkills(canonicalState).some((entry) => (entry.skill === "ralph"
|
|
335
|
+
&& matchesSkillStopContext(entry, canonicalState, sessionId, "")));
|
|
336
|
+
}
|
|
195
337
|
async function readActiveRalphState(stateDir, preferredSessionId) {
|
|
196
338
|
const cwd = resolve(stateDir, "..", "..");
|
|
197
339
|
const [rawSessionInfo, usableSessionInfo] = await Promise.all([
|
|
@@ -213,16 +355,26 @@ async function readActiveRalphState(stateDir, preferredSessionId) {
|
|
|
213
355
|
if (staleCurrentSessionId && sessionId === staleCurrentSessionId) {
|
|
214
356
|
continue;
|
|
215
357
|
}
|
|
216
|
-
|
|
358
|
+
if (await readCanonicalTerminalRunStateForStop(cwd, sessionId, "ralph")) {
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
const sessionScopedPath = getStateFilePath("ralph-state.json", cwd, sessionId);
|
|
362
|
+
const sessionScoped = await readJsonIfExists(sessionScopedPath);
|
|
363
|
+
if (sessionScoped?.active === true
|
|
364
|
+
&& isRalphStartingPhase(sessionScoped)
|
|
365
|
+
&& !(await isVisibleRalphActiveForSession(cwd, sessionId))) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
217
368
|
if (sessionScoped?.active === true && shouldContinueRun(sessionScoped)) {
|
|
218
|
-
return sessionScoped;
|
|
369
|
+
return { state: sessionScoped, path: sessionScopedPath };
|
|
219
370
|
}
|
|
220
371
|
}
|
|
221
372
|
if (sessionCandidates.length > 0)
|
|
222
373
|
return null;
|
|
223
|
-
const
|
|
374
|
+
const directPath = join(stateDir, "ralph-state.json");
|
|
375
|
+
const direct = await readJsonIfExists(directPath);
|
|
224
376
|
if (direct?.active === true && shouldContinueRun(direct)) {
|
|
225
|
-
return direct;
|
|
377
|
+
return { state: direct, path: directPath };
|
|
226
378
|
}
|
|
227
379
|
return null;
|
|
228
380
|
}
|
|
@@ -328,6 +480,22 @@ function tryReadGitValue(cwd, args) {
|
|
|
328
480
|
return null;
|
|
329
481
|
}
|
|
330
482
|
}
|
|
483
|
+
function localExcludeAlreadyIgnoresOmx(cwd) {
|
|
484
|
+
const layout = findGitLayout(cwd);
|
|
485
|
+
if (!layout)
|
|
486
|
+
return false;
|
|
487
|
+
const excludePath = join(layout.gitDir, "info", "exclude");
|
|
488
|
+
try {
|
|
489
|
+
const lines = readFileSync(excludePath, "utf-8")
|
|
490
|
+
.split(/\r?\n/)
|
|
491
|
+
.map((line) => line.trim())
|
|
492
|
+
.filter((line) => line && !line.startsWith("#"));
|
|
493
|
+
return lines.includes(".omx/") || lines.includes(".omx");
|
|
494
|
+
}
|
|
495
|
+
catch {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
331
499
|
function isPathIgnoredByGit(cwd, path) {
|
|
332
500
|
try {
|
|
333
501
|
execFileSync("git", ["check-ignore", "-q", path], {
|
|
@@ -345,7 +513,7 @@ async function ensureOmxLocalIgnoreEntry(cwd) {
|
|
|
345
513
|
const repoRoot = tryReadGitValue(cwd, ["rev-parse", "--show-toplevel"]);
|
|
346
514
|
if (!repoRoot)
|
|
347
515
|
return { changed: false };
|
|
348
|
-
if (isPathIgnoredByGit(repoRoot, ".omx/")) {
|
|
516
|
+
if (localExcludeAlreadyIgnoresOmx(repoRoot) || isPathIgnoredByGit(repoRoot, ".omx/")) {
|
|
349
517
|
return { changed: false };
|
|
350
518
|
}
|
|
351
519
|
const excludePathValue = tryReadGitValue(repoRoot, ["rev-parse", "--git-path", "info/exclude"]);
|
|
@@ -363,8 +531,14 @@ async function ensureOmxLocalIgnoreEntry(cwd) {
|
|
|
363
531
|
await writeFile(excludePath, next);
|
|
364
532
|
return { changed: true, excludePath };
|
|
365
533
|
}
|
|
366
|
-
async function buildSessionStartContext(cwd, sessionId) {
|
|
534
|
+
async function buildSessionStartContext(cwd, sessionId, options = {}) {
|
|
367
535
|
const sections = [];
|
|
536
|
+
sections.push(buildExecutionEnvironmentSection(cwd, {
|
|
537
|
+
hookEventName: options.hookEventName,
|
|
538
|
+
payload: options.payload,
|
|
539
|
+
canonicalSessionId: options.canonicalSessionId,
|
|
540
|
+
nativeSessionId: options.nativeSessionId,
|
|
541
|
+
}));
|
|
368
542
|
const localIgnoreResult = await ensureOmxLocalIgnoreEntry(cwd);
|
|
369
543
|
if (localIgnoreResult.changed) {
|
|
370
544
|
sections.push(`Added .omx/ to ${localIgnoreResult.excludePath} to keep local OMX state out of source control without mutating tracked repo ignores.`);
|
|
@@ -453,6 +627,79 @@ async function buildSessionStartContext(cwd, sessionId) {
|
|
|
453
627
|
}
|
|
454
628
|
return sections.length > 0 ? sections.join("\n\n") : null;
|
|
455
629
|
}
|
|
630
|
+
function resolveExecutionEnvironment(cwd, options = {}) {
|
|
631
|
+
const executionSurface = resolveCodexExecutionSurface(cwd, options);
|
|
632
|
+
const leaderPaneHint = resolveQuestionLeaderPaneHint(cwd, options.payload);
|
|
633
|
+
const questionBridgeHint = leaderPaneHint
|
|
634
|
+
? `tmux return bridge recorded at ${leaderPaneHint}, but this process is not attached to tmux; prefer native/user-input fallback unless running from an attached tmux pane`
|
|
635
|
+
: "not available from this outside-tmux surface; use native structured input when available or ask one concise plain-text question";
|
|
636
|
+
if (executionSurface.transport === "attached-tmux") {
|
|
637
|
+
return {
|
|
638
|
+
kind: "attached-tmux-runtime",
|
|
639
|
+
launcher: executionSurface.launcher,
|
|
640
|
+
transport: executionSurface.transport,
|
|
641
|
+
surface: "attached tmux runtime - tmux",
|
|
642
|
+
tmuxWorkflowGuidance: "omx team, omx hud, and omx question are directly usable in this session",
|
|
643
|
+
questionGuidance: "visible renderer available from the current pane",
|
|
644
|
+
teamRuntimeInstruction: "Use the durable OMX team runtime via `omx team ...` for coordinated execution; do not replace it with in-process fanout.",
|
|
645
|
+
teamHelpInstruction: "If you need runtime syntax, run `omx team --help` yourself.",
|
|
646
|
+
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 visible renderer directly. After starting `omx question` in a background terminal, wait for that terminal to finish and read the JSON answer before continuing the interview. Stop remains blocked while a deep-interview question obligation is pending.",
|
|
647
|
+
leaderPaneHint,
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
if (leaderPaneHint) {
|
|
651
|
+
const isNativeOutsideTmux = executionSurface.launcher === "native";
|
|
652
|
+
return {
|
|
653
|
+
kind: "outside-tmux-with-bridge",
|
|
654
|
+
launcher: executionSurface.launcher,
|
|
655
|
+
transport: executionSurface.transport,
|
|
656
|
+
surface: isNativeOutsideTmux
|
|
657
|
+
? "native-hook / Codex App outside tmux with tmux return bridge"
|
|
658
|
+
: "direct CLI outside tmux with tmux return bridge",
|
|
659
|
+
tmuxWorkflowGuidance: "omx team and omx hud need an attached tmux OMX CLI shell from this surface; omx question can use the detected bridge",
|
|
660
|
+
questionGuidance: questionBridgeHint,
|
|
661
|
+
teamRuntimeInstruction: isNativeOutsideTmux
|
|
662
|
+
? "This session is native-hook / Codex App outside tmux; `omx team` is a CLI/tmux runtime surface, not directly available here. Launch OMX CLI from an attached tmux shell first; do not replace it with in-process fanout."
|
|
663
|
+
: "This session is direct CLI outside tmux with a tmux return bridge for `omx question`; prompt-side `$team` does not auto-start the durable tmux team runtime here. If you intentionally want the runtime, run `omx team ...` yourself from shell instead of replacing it with in-process fanout.",
|
|
664
|
+
teamHelpInstruction: isNativeOutsideTmux
|
|
665
|
+
? "If you need runtime syntax, run `omx team --help` from an attached tmux OMX CLI shell."
|
|
666
|
+
: "If you need runtime syntax, run `omx team --help` yourself from shell.",
|
|
667
|
+
deepInterviewInstruction: `Deep-interview is active, but this session is not attached to tmux. Do not invoke \`omx question\`, \`omx hud\`, or \`omx team\` from this surface. Ask each interview round through the native structured question tool when available; otherwise ask exactly one concise plain-text question and wait for the answer. A tmux return bridge (${leaderPaneHint}) is recorded for explicit attached-tmux recovery only, not for default Codex App/native fallback.`,
|
|
668
|
+
leaderPaneHint,
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
const isNativeOutsideTmux = executionSurface.launcher === "native" && executionSurface.transport === "outside-tmux";
|
|
672
|
+
const surface = isNativeOutsideTmux
|
|
673
|
+
? "native-hook / Codex App outside tmux"
|
|
674
|
+
: "direct CLI outside tmux";
|
|
675
|
+
const teamRuntimeInstruction = isNativeOutsideTmux
|
|
676
|
+
? "This session is native-hook / Codex App outside tmux; `omx team` is a CLI/tmux runtime surface, not directly available here. Launch OMX CLI from an attached tmux shell first; do not replace it with in-process fanout."
|
|
677
|
+
: "This session is direct CLI outside tmux; prompt-side `$team` does not auto-start the durable tmux team runtime here. If you intentionally want the runtime, run `omx team ...` yourself from shell instead of replacing it with in-process fanout.";
|
|
678
|
+
const teamHelpInstruction = isNativeOutsideTmux
|
|
679
|
+
? "If you need runtime syntax, run `omx team --help` from an attached tmux OMX CLI shell rather than from Codex App/native outside-tmux context."
|
|
680
|
+
: "If you need runtime syntax, run `omx team --help` yourself from shell.";
|
|
681
|
+
return {
|
|
682
|
+
kind: isNativeOutsideTmux ? "native-outside-tmux" : "direct-cli-outside-tmux",
|
|
683
|
+
launcher: executionSurface.launcher,
|
|
684
|
+
transport: executionSurface.transport,
|
|
685
|
+
surface,
|
|
686
|
+
tmuxWorkflowGuidance: "omx team, omx hud, and omx question need an attached tmux OMX CLI shell or preserved question bridge from this surface",
|
|
687
|
+
questionGuidance: questionBridgeHint,
|
|
688
|
+
teamRuntimeInstruction,
|
|
689
|
+
teamHelpInstruction,
|
|
690
|
+
deepInterviewInstruction: "Deep-interview is active, but this session is not attached to tmux. Do not invoke `omx question`, `omx hud`, or `omx team` from this surface. Ask each interview round through the native structured question tool when available; otherwise ask exactly one concise plain-text question and wait for the answer. Stop gating still applies to the interview, but no tmux question obligation should be created outside tmux.",
|
|
691
|
+
leaderPaneHint: "",
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
function buildExecutionEnvironmentSection(cwd, options = {}) {
|
|
695
|
+
const environment = resolveExecutionEnvironment(cwd, options);
|
|
696
|
+
return [
|
|
697
|
+
"[Execution environment]",
|
|
698
|
+
`- surface: ${environment.surface}`,
|
|
699
|
+
`- omx runtime surfaces: ${environment.tmuxWorkflowGuidance}`,
|
|
700
|
+
`- omx question: ${environment.questionGuidance}`,
|
|
701
|
+
].join("\n");
|
|
702
|
+
}
|
|
456
703
|
function resolveQuestionLeaderPaneHint(cwd, payload) {
|
|
457
704
|
const payloadSessionId = safeString(payload?.session_id).trim();
|
|
458
705
|
const envSessionId = safeString(process.env.OMX_SESSION_ID || process.env.CODEX_SESSION_ID || process.env.SESSION_ID).trim();
|
|
@@ -480,15 +727,54 @@ function resolveQuestionLeaderPaneHint(cwd, payload) {
|
|
|
480
727
|
return /^%\d+$/.test(envPane) ? envPane : '';
|
|
481
728
|
}
|
|
482
729
|
function buildDeepInterviewQuestionBridgeInstruction(cwd, payload) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
730
|
+
return resolveExecutionEnvironment(cwd, {
|
|
731
|
+
hookEventName: "UserPromptSubmit",
|
|
732
|
+
payload,
|
|
733
|
+
nativeSessionId: safeString(payload?.session_id ?? payload?.sessionId).trim(),
|
|
734
|
+
}).deepInterviewInstruction;
|
|
735
|
+
}
|
|
736
|
+
function buildTeamRuntimeInstruction(cwd, payload) {
|
|
737
|
+
return resolveExecutionEnvironment(cwd, {
|
|
738
|
+
hookEventName: "UserPromptSubmit",
|
|
739
|
+
payload,
|
|
740
|
+
nativeSessionId: safeString(payload?.session_id ?? payload?.sessionId).trim(),
|
|
741
|
+
}).teamRuntimeInstruction;
|
|
742
|
+
}
|
|
743
|
+
function buildTeamHelpInstruction(cwd, payload) {
|
|
744
|
+
return resolveExecutionEnvironment(cwd, {
|
|
745
|
+
hookEventName: "UserPromptSubmit",
|
|
746
|
+
payload,
|
|
747
|
+
nativeSessionId: safeString(payload?.session_id ?? payload?.sessionId).trim(),
|
|
748
|
+
}).teamHelpInstruction;
|
|
749
|
+
}
|
|
750
|
+
function buildNativeOutsideTmuxTeamPromptBlockState(prompt, cwd, payload, sessionId, threadId, turnId) {
|
|
751
|
+
const match = detectPrimaryKeyword(prompt);
|
|
752
|
+
if (match?.skill !== "team")
|
|
753
|
+
return null;
|
|
754
|
+
const environment = resolveExecutionEnvironment(cwd, {
|
|
755
|
+
hookEventName: "UserPromptSubmit",
|
|
756
|
+
payload,
|
|
757
|
+
canonicalSessionId: sessionId ?? "",
|
|
758
|
+
nativeSessionId: safeString(payload.session_id ?? payload.sessionId).trim(),
|
|
759
|
+
});
|
|
760
|
+
if (!(environment.launcher === "native" && environment.transport === "outside-tmux"))
|
|
761
|
+
return null;
|
|
762
|
+
const nowIso = new Date().toISOString();
|
|
763
|
+
return {
|
|
764
|
+
version: 1,
|
|
765
|
+
active: false,
|
|
766
|
+
skill: "team",
|
|
767
|
+
keyword: match.keyword,
|
|
768
|
+
phase: "planning",
|
|
769
|
+
activated_at: nowIso,
|
|
770
|
+
updated_at: nowIso,
|
|
771
|
+
source: "keyword-detector",
|
|
772
|
+
session_id: sessionId,
|
|
773
|
+
thread_id: threadId,
|
|
774
|
+
turn_id: turnId,
|
|
775
|
+
active_skills: [],
|
|
776
|
+
transition_error: "Codex App/native outside-tmux sessions cannot activate the tmux-only `team` workflow directly. Launch OMX CLI from an attached tmux shell first, then run `omx team ...` there.",
|
|
777
|
+
};
|
|
492
778
|
}
|
|
493
779
|
function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(), payload) {
|
|
494
780
|
if (!prompt)
|
|
@@ -548,9 +834,9 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
|
|
|
548
834
|
? `skill: ${skillState.initialized_mode} activated and initial state initialized at ${skillState.initialized_state_path}; write subsequent updates via omx_state MCP.`
|
|
549
835
|
: null,
|
|
550
836
|
teamDetected
|
|
551
|
-
?
|
|
837
|
+
? buildTeamRuntimeInstruction(cwd, payload)
|
|
552
838
|
: null,
|
|
553
|
-
teamDetected ?
|
|
839
|
+
teamDetected ? buildTeamHelpInstruction(cwd, payload) : null,
|
|
554
840
|
'Follow AGENTS.md routing and preserve workflow transition and planning-safety rules.',
|
|
555
841
|
].filter(Boolean).join(' ');
|
|
556
842
|
}
|
|
@@ -568,8 +854,8 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
|
|
|
568
854
|
initializedStateMessage,
|
|
569
855
|
deepInterviewPromptActivationNote,
|
|
570
856
|
ultraworkPromptActivationNote,
|
|
571
|
-
|
|
572
|
-
|
|
857
|
+
buildTeamRuntimeInstruction(cwd, payload),
|
|
858
|
+
buildTeamHelpInstruction(cwd, payload),
|
|
573
859
|
"Follow AGENTS.md routing and preserve workflow transition and planning-safety rules.",
|
|
574
860
|
].filter(Boolean).join(" ");
|
|
575
861
|
}
|
|
@@ -599,43 +885,16 @@ function parseTeamWorkerEnv(rawValue) {
|
|
|
599
885
|
workerName: match[2] || "",
|
|
600
886
|
};
|
|
601
887
|
}
|
|
602
|
-
async function readTeamStateRootFromJson(path) {
|
|
603
|
-
const parsed = await readJsonIfExists(path);
|
|
604
|
-
const value = safeString(parsed?.team_state_root).trim();
|
|
605
|
-
return value || null;
|
|
606
|
-
}
|
|
607
888
|
async function resolveTeamStateDirForWorkerContext(cwd, workerContext) {
|
|
608
|
-
|
|
609
|
-
if (explicitStateRoot) {
|
|
610
|
-
return resolve(cwd, explicitStateRoot);
|
|
611
|
-
}
|
|
612
|
-
const leaderCwd = safeString(process.env.OMX_TEAM_LEADER_CWD).trim();
|
|
613
|
-
const candidateStateDirs = [
|
|
614
|
-
...(leaderCwd ? [join(resolve(leaderCwd), ".omx", "state")] : []),
|
|
615
|
-
join(cwd, ".omx", "state"),
|
|
616
|
-
];
|
|
617
|
-
for (const candidateStateDir of candidateStateDirs) {
|
|
618
|
-
const teamRoot = join(candidateStateDir, "team", workerContext.teamName);
|
|
619
|
-
if (!existsSync(teamRoot))
|
|
620
|
-
continue;
|
|
621
|
-
const identityRoot = await readTeamStateRootFromJson(join(teamRoot, "workers", workerContext.workerName, "identity.json"));
|
|
622
|
-
if (identityRoot)
|
|
623
|
-
return resolve(cwd, identityRoot);
|
|
624
|
-
const manifestRoot = await readTeamStateRootFromJson(join(teamRoot, "manifest.v2.json"));
|
|
625
|
-
if (manifestRoot)
|
|
626
|
-
return resolve(cwd, manifestRoot);
|
|
627
|
-
const configRoot = await readTeamStateRootFromJson(join(teamRoot, "config.json"));
|
|
628
|
-
if (configRoot)
|
|
629
|
-
return resolve(cwd, configRoot);
|
|
630
|
-
return candidateStateDir;
|
|
631
|
-
}
|
|
632
|
-
return join(cwd, ".omx", "state");
|
|
889
|
+
return resolveWorkerNotifyTeamStateRootPath(cwd, workerContext, process.env);
|
|
633
890
|
}
|
|
634
891
|
async function buildTeamWorkerStopOutput(cwd) {
|
|
635
892
|
const workerContext = parseTeamWorkerEnv(safeString(process.env.OMX_TEAM_WORKER));
|
|
636
893
|
if (!workerContext)
|
|
637
894
|
return null;
|
|
638
895
|
const stateDir = await resolveTeamStateDirForWorkerContext(cwd, workerContext);
|
|
896
|
+
if (!stateDir)
|
|
897
|
+
return null;
|
|
639
898
|
const workerRoot = join(stateDir, "team", workerContext.teamName, "workers", workerContext.workerName);
|
|
640
899
|
const [identity, status] = await Promise.all([
|
|
641
900
|
readJsonIfExists(join(workerRoot, "identity.json")),
|
|
@@ -716,6 +975,9 @@ async function readTeamModeStateForStop(cwd, sessionId) {
|
|
|
716
975
|
return rootState;
|
|
717
976
|
}
|
|
718
977
|
async function buildTeamStopOutput(cwd, sessionId) {
|
|
978
|
+
if (await readCanonicalTerminalRunStateForStop(cwd, sessionId, "team")) {
|
|
979
|
+
return null;
|
|
980
|
+
}
|
|
719
981
|
const teamState = await readTeamModeStateForStop(cwd, sessionId);
|
|
720
982
|
if (teamState?.active !== true)
|
|
721
983
|
return null;
|
|
@@ -943,6 +1205,12 @@ function buildRepeatableStopSignature(payload, kind, detail = "", canonicalSessi
|
|
|
943
1205
|
normalizedDetail || "no-detail",
|
|
944
1206
|
].join("|");
|
|
945
1207
|
}
|
|
1208
|
+
function formatStopStatePath(cwd, statePath) {
|
|
1209
|
+
const relativePath = relative(cwd, statePath);
|
|
1210
|
+
if (!relativePath || relativePath.startsWith(".."))
|
|
1211
|
+
return statePath;
|
|
1212
|
+
return relativePath.replace(/\\/g, "/");
|
|
1213
|
+
}
|
|
946
1214
|
function readNativeStopSessionKey(payload, canonicalSessionId) {
|
|
947
1215
|
return resolveRepeatableStopSessionId(payload, canonicalSessionId) || readPayloadThreadId(payload) || "global";
|
|
948
1216
|
}
|
|
@@ -1153,6 +1421,9 @@ async function buildStopHookOutput(payload, cwd, stateDir) {
|
|
|
1153
1421
|
const sessionId = readPayloadSessionId(payload);
|
|
1154
1422
|
const canonicalSessionId = await resolveInternalSessionIdForPayload(cwd, sessionId);
|
|
1155
1423
|
const threadId = readPayloadThreadId(payload);
|
|
1424
|
+
const execFollowupOutput = await buildExecFollowupStopOutput(cwd, canonicalSessionId);
|
|
1425
|
+
if (execFollowupOutput)
|
|
1426
|
+
return execFollowupOutput;
|
|
1156
1427
|
const ralphState = await readActiveRalphState(stateDir, canonicalSessionId);
|
|
1157
1428
|
if (!ralphState) {
|
|
1158
1429
|
const autoresearchState = await readActiveAutoresearchState(cwd, canonicalSessionId);
|
|
@@ -1170,8 +1441,9 @@ async function buildStopHookOutput(payload, cwd, stateDir) {
|
|
|
1170
1441
|
}
|
|
1171
1442
|
}
|
|
1172
1443
|
const teamWorkerOutput = await buildTeamWorkerStopOutput(cwd);
|
|
1173
|
-
if (hasTeamWorkerContext() && teamWorkerOutput)
|
|
1174
|
-
return teamWorkerOutput;
|
|
1444
|
+
if (hasTeamWorkerContext() && teamWorkerOutput) {
|
|
1445
|
+
return await returnPersistentStopBlock(payload, stateDir, "team-worker-stop", safeString(teamWorkerOutput.stopReason), teamWorkerOutput, canonicalSessionId, { allowRepeatDuringStopHook: false });
|
|
1446
|
+
}
|
|
1175
1447
|
const autopilotOutput = await buildModeBasedStopOutput("autopilot", cwd, canonicalSessionId);
|
|
1176
1448
|
if (autopilotOutput) {
|
|
1177
1449
|
return await returnPersistentStopBlock(payload, stateDir, "autopilot-stop", safeString(autopilotOutput.stopReason), autopilotOutput, canonicalSessionId, { allowRepeatDuringStopHook: false });
|
|
@@ -1196,7 +1468,9 @@ async function buildStopHookOutput(payload, cwd, stateDir) {
|
|
|
1196
1468
|
if (deepInterviewQuestionOutput) {
|
|
1197
1469
|
return await returnPersistentStopBlock(payload, stateDir, "deep-interview-question-stop", deepInterviewQuestionOutput.obligationId, deepInterviewQuestionOutput.output, canonicalSessionId);
|
|
1198
1470
|
}
|
|
1199
|
-
const canonicalTeam = await
|
|
1471
|
+
const canonicalTeam = await readCanonicalTerminalRunStateForStop(cwd, canonicalSessionId, "team")
|
|
1472
|
+
? null
|
|
1473
|
+
: await findCanonicalActiveTeamForSession(cwd, canonicalSessionId);
|
|
1200
1474
|
if (canonicalTeam) {
|
|
1201
1475
|
const canonicalTeamOutput = buildTeamStopOutputForPhase(canonicalTeam.teamName, canonicalTeam.phase);
|
|
1202
1476
|
const repeatedCanonicalTeamOutput = await returnPersistentStopBlock(payload, stateDir, "team-stop", `${canonicalTeam.teamName}|${canonicalTeam.phase}`, canonicalTeamOutput, canonicalSessionId);
|
|
@@ -1221,11 +1495,18 @@ async function buildStopHookOutput(payload, cwd, stateDir) {
|
|
|
1221
1495
|
systemMessage: "OMX native Stop detected a stall/permission-style handoff and continued the turn automatically.",
|
|
1222
1496
|
}, canonicalSessionId);
|
|
1223
1497
|
}
|
|
1498
|
+
if (isFinalHandoffDocumentRefreshCandidate(lastAssistantMessage)) {
|
|
1499
|
+
const documentRefreshWarning = evaluateFinalHandoffDocumentRefresh(cwd, lastAssistantMessage);
|
|
1500
|
+
if (documentRefreshWarning) {
|
|
1501
|
+
return await maybeReturnRepeatableStopOutput(payload, stateDir, buildRepeatableStopSignature(payload, "document-refresh-stop", documentRefreshWarning.triggeringPaths.join("|"), canonicalSessionId), buildDocumentRefreshAdvisoryOutput(documentRefreshWarning, "Stop"), canonicalSessionId, { allowRepeatDuringStopHook: false });
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1224
1504
|
return null;
|
|
1225
1505
|
}
|
|
1226
|
-
const currentPhase = safeString(ralphState
|
|
1506
|
+
const currentPhase = safeString(ralphState.state.current_phase).trim() || "executing";
|
|
1507
|
+
const blockingPath = formatStopStatePath(cwd, ralphState.path);
|
|
1227
1508
|
const stopReason = `ralph_${currentPhase}`;
|
|
1228
|
-
const systemMessage = `OMX Ralph is still active (phase: ${currentPhase}); continue the task and gather fresh verification evidence before stopping.`;
|
|
1509
|
+
const systemMessage = `OMX Ralph is still active (phase: ${currentPhase}; state: ${blockingPath}); continue the task and gather fresh verification evidence before stopping.`;
|
|
1229
1510
|
return await returnPersistentStopBlock(payload, stateDir, "ralph-stop", currentPhase, {
|
|
1230
1511
|
decision: "block",
|
|
1231
1512
|
reason: systemMessage,
|
|
@@ -1247,12 +1528,30 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
1247
1528
|
const currentSessionState = await readUsableSessionState(cwd);
|
|
1248
1529
|
let canonicalSessionId = safeString(currentSessionState?.session_id).trim();
|
|
1249
1530
|
let resolvedNativeSessionId = nativeSessionId;
|
|
1531
|
+
let skipCanonicalSessionStartContext = false;
|
|
1250
1532
|
if (hookEventName === "SessionStart" && nativeSessionId) {
|
|
1251
|
-
const
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1533
|
+
const transcriptPath = safeString(payload.transcript_path ?? payload.transcriptPath).trim();
|
|
1534
|
+
const subagentSessionStart = readNativeSubagentSessionStartMetadata(transcriptPath);
|
|
1535
|
+
if (subagentSessionStart && canonicalSessionId) {
|
|
1536
|
+
const belongsToCanonicalSession = await nativeSubagentSessionStartBelongsToCanonicalSession(cwd, canonicalSessionId, currentSessionState, subagentSessionStart);
|
|
1537
|
+
if (belongsToCanonicalSession) {
|
|
1538
|
+
resolvedNativeSessionId = nativeSessionId;
|
|
1539
|
+
await recordNativeSubagentSessionStart(cwd, canonicalSessionId, nativeSessionId, subagentSessionStart, transcriptPath);
|
|
1540
|
+
}
|
|
1541
|
+
else {
|
|
1542
|
+
skipCanonicalSessionStartContext = true;
|
|
1543
|
+
resolvedNativeSessionId =
|
|
1544
|
+
safeString(currentSessionState?.native_session_id).trim() || nativeSessionId;
|
|
1545
|
+
await recordIgnoredNativeSubagentSessionStart(cwd, canonicalSessionId, nativeSessionId, subagentSessionStart, transcriptPath);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
else {
|
|
1549
|
+
const sessionState = await reconcileNativeSessionStart(cwd, nativeSessionId, {
|
|
1550
|
+
pid: options.sessionOwnerPid ?? resolveSessionOwnerPid(payload),
|
|
1551
|
+
});
|
|
1552
|
+
canonicalSessionId = safeString(sessionState.session_id).trim();
|
|
1553
|
+
resolvedNativeSessionId = safeString(sessionState.native_session_id).trim() || nativeSessionId;
|
|
1554
|
+
}
|
|
1256
1555
|
}
|
|
1257
1556
|
else if (!canonicalSessionId) {
|
|
1258
1557
|
canonicalSessionId = safeString(currentSessionState?.session_id).trim();
|
|
@@ -1273,7 +1572,7 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
1273
1572
|
if (hookEventName === "UserPromptSubmit") {
|
|
1274
1573
|
const prompt = readPromptText(payload);
|
|
1275
1574
|
if (prompt) {
|
|
1276
|
-
skillState = await recordSkillActivation({
|
|
1575
|
+
skillState = buildNativeOutsideTmuxTeamPromptBlockState(prompt, cwd, payload, sessionIdForState, threadId || undefined, turnId || undefined) ?? await recordSkillActivation({
|
|
1277
1576
|
stateDir,
|
|
1278
1577
|
text: prompt,
|
|
1279
1578
|
sessionId: sessionIdForState,
|
|
@@ -1326,6 +1625,10 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
1326
1625
|
triageAdditionalContext =
|
|
1327
1626
|
"OMX native UserPromptSubmit triage detected a visual/style request with no workflow keyword. This is advisory prompt-routing context only. Prefer the designer role surface.";
|
|
1328
1627
|
}
|
|
1628
|
+
else if (decision.destination === "researcher") {
|
|
1629
|
+
triageAdditionalContext =
|
|
1630
|
+
"OMX native UserPromptSubmit triage detected an external documentation/reference research request with no workflow keyword. This is advisory prompt-routing context only. Prefer the researcher role surface rather than repo-local explore or autopilot.";
|
|
1631
|
+
}
|
|
1329
1632
|
if (triageAdditionalContext !== null) {
|
|
1330
1633
|
const dest = decision.destination;
|
|
1331
1634
|
const newState = {
|
|
@@ -1355,7 +1658,7 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
1355
1658
|
const reconcileHudForPromptSubmitFn = options.reconcileHudForPromptSubmitFn ?? reconcileHudForPromptSubmit;
|
|
1356
1659
|
await reconcileHudForPromptSubmitFn(cwd, { sessionId: canonicalSessionId || sessionIdForState || undefined }).catch(() => { });
|
|
1357
1660
|
}
|
|
1358
|
-
if (omxEventName) {
|
|
1661
|
+
if (omxEventName && !skipCanonicalSessionStartContext) {
|
|
1359
1662
|
const baseContext = buildBaseContext(cwd, payload, hookEventName, canonicalSessionId);
|
|
1360
1663
|
if (resolvedNativeSessionId) {
|
|
1361
1664
|
baseContext.native_session_id = resolvedNativeSessionId;
|
|
@@ -1372,9 +1675,14 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
1372
1675
|
});
|
|
1373
1676
|
await dispatchHookEvent(event, { cwd });
|
|
1374
1677
|
}
|
|
1375
|
-
if (hookEventName === "SessionStart" || hookEventName === "UserPromptSubmit") {
|
|
1678
|
+
if ((hookEventName === "SessionStart" && !skipCanonicalSessionStartContext) || hookEventName === "UserPromptSubmit") {
|
|
1376
1679
|
const additionalContext = hookEventName === "SessionStart"
|
|
1377
|
-
? await buildSessionStartContext(cwd, canonicalSessionId || nativeSessionId
|
|
1680
|
+
? await buildSessionStartContext(cwd, canonicalSessionId || nativeSessionId, {
|
|
1681
|
+
hookEventName,
|
|
1682
|
+
payload,
|
|
1683
|
+
canonicalSessionId,
|
|
1684
|
+
nativeSessionId: resolvedNativeSessionId || nativeSessionId,
|
|
1685
|
+
})
|
|
1378
1686
|
: (buildAdditionalContextMessage(readPromptText(payload), skillState, cwd, payload) ?? triageAdditionalContext);
|
|
1379
1687
|
if (additionalContext) {
|
|
1380
1688
|
outputJson = {
|
|
@@ -1393,6 +1701,7 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
1393
1701
|
await markTeamTransportFailure(cwd, payload);
|
|
1394
1702
|
}
|
|
1395
1703
|
outputJson = buildNativePostToolUseOutput(payload);
|
|
1704
|
+
await handleTeamWorkerPostToolUseSuccess(payload, cwd);
|
|
1396
1705
|
}
|
|
1397
1706
|
else if (hookEventName === "Stop") {
|
|
1398
1707
|
outputJson = await buildStopHookOutput(payload, cwd, stateDir);
|
|
@@ -1431,22 +1740,55 @@ async function readStdinJson() {
|
|
|
1431
1740
|
};
|
|
1432
1741
|
}
|
|
1433
1742
|
}
|
|
1743
|
+
function writeNativeHookJsonStdout(output) {
|
|
1744
|
+
process.stdout.write(`${JSON.stringify(output)}\n`);
|
|
1745
|
+
}
|
|
1746
|
+
function isStopDispatchFailureTestTrigger(payload) {
|
|
1747
|
+
return process.env.NODE_ENV === "test"
|
|
1748
|
+
&& process.env.OMX_NATIVE_HOOK_TEST_THROW_STOP_DISPATCH === "1"
|
|
1749
|
+
&& readHookEventName(payload) === "Stop";
|
|
1750
|
+
}
|
|
1751
|
+
function buildStopDispatchFailureOutput(error) {
|
|
1752
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1753
|
+
const reason = "OMX native Stop hook failed before normal continuation handling. Continue once more, preserve runtime state, inspect the hook logs, and retry with a valid Stop JSON response.";
|
|
1754
|
+
return {
|
|
1755
|
+
decision: "block",
|
|
1756
|
+
reason,
|
|
1757
|
+
stopReason: "native_stop_dispatch_failure",
|
|
1758
|
+
systemMessage: `${reason} Failure: ${detail}`,
|
|
1759
|
+
};
|
|
1760
|
+
}
|
|
1434
1761
|
export async function runCodexNativeHookCli() {
|
|
1435
1762
|
const { payload, parseError } = await readStdinJson();
|
|
1436
1763
|
if (parseError) {
|
|
1437
|
-
|
|
1764
|
+
writeNativeHookJsonStdout({
|
|
1438
1765
|
decision: "block",
|
|
1439
1766
|
reason: "OMX native hook received malformed JSON input. Preserve runtime state, inspect the emitting hook payload yourself, and retry with valid JSON.",
|
|
1440
1767
|
hookSpecificOutput: {
|
|
1441
1768
|
hookEventName: "Unknown",
|
|
1442
1769
|
additionalContext: `stdin JSON parsing failed inside codex-native-hook: ${parseError.message}. Emit valid JSON from the native hook caller before retrying.`,
|
|
1443
1770
|
},
|
|
1444
|
-
})
|
|
1771
|
+
});
|
|
1445
1772
|
return;
|
|
1446
1773
|
}
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1774
|
+
try {
|
|
1775
|
+
if (isStopDispatchFailureTestTrigger(payload)) {
|
|
1776
|
+
throw new Error("test-induced Stop dispatch failure");
|
|
1777
|
+
}
|
|
1778
|
+
const result = await dispatchCodexNativeHook(payload);
|
|
1779
|
+
if (result.outputJson) {
|
|
1780
|
+
writeNativeHookJsonStdout(result.outputJson);
|
|
1781
|
+
}
|
|
1782
|
+
else if (result.hookEventName === "Stop") {
|
|
1783
|
+
writeNativeHookJsonStdout({});
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
catch (error) {
|
|
1787
|
+
if (readHookEventName(payload) !== "Stop") {
|
|
1788
|
+
throw error;
|
|
1789
|
+
}
|
|
1790
|
+
process.stderr.write(`[omx] codex-native Stop hook dispatch failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
1791
|
+
writeNativeHookJsonStdout(buildStopDispatchFailureOutput(error));
|
|
1450
1792
|
}
|
|
1451
1793
|
}
|
|
1452
1794
|
if (isCodexNativeHookMainModule(import.meta.url, process.argv[1])) {
|