oh-my-codex 0.20.1 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +6 -6
- package/Cargo.toml +1 -1
- package/README.md +10 -1
- package/dist/adapt/__tests__/hermes.test.js.map +1 -1
- package/dist/adapt/contracts.d.ts.map +1 -1
- package/dist/agents/native-config.js.map +1 -1
- package/dist/auth/__tests__/hotswap.test.d.ts +2 -0
- package/dist/auth/__tests__/hotswap.test.d.ts.map +1 -0
- package/dist/auth/__tests__/hotswap.test.js +183 -0
- package/dist/auth/__tests__/hotswap.test.js.map +1 -0
- package/dist/auth/hotswap.d.ts.map +1 -1
- package/dist/auth/hotswap.js +17 -4
- package/dist/auth/hotswap.js.map +1 -1
- package/dist/auth/paths.js.map +1 -1
- package/dist/auth/storage.js.map +1 -1
- package/dist/autopilot/__tests__/ralplan-gate.test.js +4 -4
- package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
- package/dist/autopilot/completion-gate.js.map +1 -1
- package/dist/autopilot/fsm.d.ts +1 -1
- package/dist/autopilot/fsm.d.ts.map +1 -1
- package/dist/autoresearch/goal.js.map +1 -1
- package/dist/autoresearch/runtime.js.map +1 -1
- package/dist/capabilities/lockfile.js.map +1 -1
- package/dist/catalog/reader.js.map +1 -1
- package/dist/catalog/skill-mirror.js.map +1 -1
- package/dist/cli/__tests__/adapt-help.test.js.map +1 -1
- package/dist/cli/__tests__/agents-init.test.js.map +1 -1
- package/dist/cli/__tests__/agents.test.js.map +1 -1
- package/dist/cli/__tests__/api.test.js.map +1 -1
- package/dist/cli/__tests__/ask.test.js.map +1 -1
- package/dist/cli/__tests__/auth.test.js.map +1 -1
- package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -1
- package/dist/cli/__tests__/autoresearch.test.js.map +1 -1
- package/dist/cli/__tests__/capabilities.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-context-window-warning.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-invalid-config.test.js +47 -4
- package/dist/cli/__tests__/doctor-invalid-config.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +650 -15
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/imagegen-continuation.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +216 -11
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +49 -3
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-parity.test.js +84 -12
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/native-hook-claim-journal.test.d.ts +2 -0
- package/dist/cli/__tests__/native-hook-claim-journal.test.d.ts.map +1 -0
- package/dist/cli/__tests__/native-hook-claim-journal.test.js +128 -0
- package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -0
- package/dist/cli/__tests__/nested-help-routing.test.js.map +1 -1
- package/dist/cli/__tests__/question.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-deslop-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +6 -0
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-smoke.test.js.map +1 -1
- package/dist/cli/__tests__/ralph.test.js +8 -3
- package/dist/cli/__tests__/ralph.test.js.map +1 -1
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.d.ts +2 -0
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +187 -0
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -0
- package/dist/cli/__tests__/ralplan.test.d.ts +2 -0
- package/dist/cli/__tests__/ralplan.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralplan.test.js +129 -0
- package/dist/cli/__tests__/ralplan.test.js.map +1 -0
- package/dist/cli/__tests__/resume.test.js +6 -1
- package/dist/cli/__tests__/resume.test.js.map +1 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.js +25 -0
- package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
- package/dist/cli/__tests__/session-search-help.test.js.map +1 -1
- package/dist/cli/__tests__/session-search.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +79 -0
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-gh-star.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +77 -3
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.d.ts +2 -0
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.d.ts.map +1 -0
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js +285 -0
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js.map +1 -0
- package/dist/cli/__tests__/setup-install-mode.test.js +2261 -14
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/setup-preferences.test.d.ts +2 -0
- package/dist/cli/__tests__/setup-preferences.test.d.ts.map +1 -0
- package/dist/cli/__tests__/setup-preferences.test.js +79 -0
- package/dist/cli/__tests__/setup-preferences.test.js.map +1 -0
- package/dist/cli/__tests__/setup-refresh.test.js +33 -2
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-scope.test.js +46 -3
- package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
- package/dist/cli/__tests__/state.test.js +37 -0
- package/dist/cli/__tests__/state.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +61 -1
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +1771 -24
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/update.test.js +58 -0
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/__tests__/url.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
- package/dist/cli/adapt.js.map +1 -1
- package/dist/cli/agents-init.js.map +1 -1
- package/dist/cli/agents.js.map +1 -1
- package/dist/cli/api.js.map +1 -1
- package/dist/cli/ask.d.ts +1 -1
- package/dist/cli/ask.d.ts.map +1 -1
- package/dist/cli/ask.js.map +1 -1
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/autoresearch-guided.js.map +1 -1
- package/dist/cli/autoresearch-intake.js.map +1 -1
- package/dist/cli/capabilities.js.map +1 -1
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/codex-feature-probe.js.map +1 -1
- package/dist/cli/codex-home.js.map +1 -1
- package/dist/cli/doctor.d.ts +18 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +594 -130
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/explore.js.map +1 -1
- package/dist/cli/index.d.ts +11 -3
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +108 -20
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-serve.js.map +1 -1
- package/dist/cli/mission.js.map +1 -1
- package/dist/cli/native-assets.js.map +1 -1
- package/dist/cli/native-hook-claim-journal.d.ts +18 -0
- package/dist/cli/native-hook-claim-journal.d.ts.map +1 -0
- package/dist/cli/native-hook-claim-journal.js +239 -0
- package/dist/cli/native-hook-claim-journal.js.map +1 -0
- package/dist/cli/omx.js.map +1 -1
- package/dist/cli/plugin-marketplace.js.map +1 -1
- package/dist/cli/project-runtime-codex-homes.js.map +1 -1
- package/dist/cli/question.js.map +1 -1
- package/dist/cli/ralph.d.ts.map +1 -1
- package/dist/cli/ralph.js +3 -2
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/ralplan.d.ts +14 -0
- package/dist/cli/ralplan.d.ts.map +1 -0
- package/dist/cli/ralplan.js +203 -0
- package/dist/cli/ralplan.js.map +1 -0
- package/dist/cli/setup-preferences.d.ts +11 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -1
- package/dist/cli/setup-preferences.js +32 -0
- package/dist/cli/setup-preferences.js.map +1 -1
- package/dist/cli/setup.d.ts +53 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +1401 -398
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/sparkshell.js.map +1 -1
- package/dist/cli/star-prompt.js.map +1 -1
- package/dist/cli/state.d.ts.map +1 -1
- package/dist/cli/state.js +2 -1
- package/dist/cli/state.js.map +1 -1
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/ultragoal.d.ts +5 -1
- package/dist/cli/ultragoal.d.ts.map +1 -1
- package/dist/cli/ultragoal.js +34 -2
- package/dist/cli/ultragoal.js.map +1 -1
- package/dist/cli/uninstall.d.ts +8 -0
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +944 -95
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +8 -1
- package/dist/cli/update.js.map +1 -1
- package/dist/cli/url.js.map +1 -1
- package/dist/compat/__tests__/doctor-contract.test.js +5 -1
- package/dist/compat/__tests__/doctor-contract.test.js.map +1 -1
- package/dist/compat/__tests__/rust-runtime-compat.test.js.map +1 -1
- package/dist/config/__tests__/codex-hooks.test.js +1287 -11
- package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +850 -32
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +6 -1
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/codex-feature-flags.d.ts.map +1 -1
- package/dist/config/codex-feature-flags.js.map +1 -1
- package/dist/config/codex-hooks.d.ts +124 -1
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +2142 -265
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/config/commit-lore-guard.js.map +1 -1
- package/dist/config/generator.d.ts +21 -16
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +991 -137
- package/dist/config/generator.js.map +1 -1
- package/dist/config/mcp-registry.js.map +1 -1
- package/dist/config/models.d.ts +2 -2
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js.map +1 -1
- package/dist/config/omx-first-party-mcp.js.map +1 -1
- package/dist/config/team-mode.d.ts.map +1 -1
- package/dist/document-refresh/__tests__/enforcer.test.js.map +1 -1
- package/dist/document-refresh/enforcer.js.map +1 -1
- package/dist/exec/followup.js.map +1 -1
- package/dist/goal-workflows/artifacts.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +7 -4
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/analyze-routing-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/analyze-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +9 -3
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/design-skill.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +1372 -2
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +14 -0
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +669 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +2 -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 +142 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js +48 -2
- package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +61 -44
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js +3 -2
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +243 -4
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +8 -1
- 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.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-test-helpers.js.map +1 -1
- package/dist/hooks/__tests__/prompt-session-provenance.test.d.ts +2 -0
- package/dist/hooks/__tests__/prompt-session-provenance.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/prompt-session-provenance.test.js +82 -0
- package/dist/hooks/__tests__/prompt-session-provenance.test.js.map +1 -0
- package/dist/hooks/__tests__/session.test.js +532 -11
- package/dist/hooks/__tests__/session.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.js.map +1 -1
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +1 -1
- package/dist/hooks/agents-overlay.js +5 -5
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/code-simplifier/index.js.map +1 -1
- package/dist/hooks/explore-routing.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/extensibility/events.js.map +1 -1
- package/dist/hooks/extensibility/loader.js.map +1 -1
- package/dist/hooks/extensibility/plugin-runner-stdin.js.map +1 -1
- package/dist/hooks/extensibility/sdk/logging.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +33 -7
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +2228 -119
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts +12 -0
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +41 -0
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hooks/prompt-session-provenance.d.ts +87 -0
- package/dist/hooks/prompt-session-provenance.d.ts.map +1 -0
- package/dist/hooks/prompt-session-provenance.js +180 -0
- package/dist/hooks/prompt-session-provenance.js.map +1 -0
- package/dist/hooks/session.d.ts +139 -34
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +1239 -317
- package/dist/hooks/session.js.map +1 -1
- package/dist/hooks/task-size-detector.js.map +1 -1
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/authority.js.map +1 -1
- package/dist/hud/constants.js.map +1 -1
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/tmux.js.map +1 -1
- package/dist/leader/__tests__/contract.test.js +103 -1
- package/dist/leader/__tests__/contract.test.js.map +1 -1
- package/dist/leader/contract.d.ts +26 -5
- package/dist/leader/contract.d.ts.map +1 -1
- package/dist/leader/contract.js +109 -3
- package/dist/leader/contract.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +15 -2
- package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
- package/dist/mcp/__tests__/state-paths.test.js +98 -1
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/code-intel-server.d.ts +58 -58
- package/dist/mcp/code-intel-server.d.ts.map +1 -1
- package/dist/mcp/code-intel-server.js.map +1 -1
- package/dist/mcp/hermes-bridge.js.map +1 -1
- package/dist/mcp/hermes-server.d.ts +70 -70
- package/dist/mcp/hermes-server.d.ts.map +1 -1
- package/dist/mcp/lifecycle-telemetry.js.map +1 -1
- package/dist/mcp/memory-server.d.ts +34 -34
- package/dist/mcp/memory-server.d.ts.map +1 -1
- package/dist/mcp/memory-server.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +14 -0
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +96 -20
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts +47 -47
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/trace-server.d.ts +4 -4
- package/dist/mcp/trace-server.d.ts.map +1 -1
- package/dist/mcp/trace-server.js.map +1 -1
- package/dist/mcp/wiki-server.d.ts +23 -23
- package/dist/mcp/wiki-server.d.ts.map +1 -1
- package/dist/mcp/wiki-server.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +53 -1
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +5 -5
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/__tests__/lifecycle-dedupe.test.js.map +1 -1
- package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js +177 -85
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js.map +1 -1
- package/dist/notifications/__tests__/session-registry.test.js.map +1 -1
- package/dist/notifications/__tests__/template-engine.test.js.map +1 -1
- package/dist/notifications/__tests__/verbosity.test.js.map +1 -1
- package/dist/notifications/http-client.js.map +1 -1
- package/dist/notifications/index.d.ts +4 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +3 -9
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/lifecycle-dedupe.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/session-registry.js.map +1 -1
- package/dist/notifications/session-status.js.map +1 -1
- package/dist/notifications/temp-contract.js.map +1 -1
- package/dist/notifications/tmux-detector.js.map +1 -1
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/openclaw/config.js.map +1 -1
- package/dist/openclaw/dispatcher.js.map +1 -1
- package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
- package/dist/pipeline/__tests__/stages.test.js +8 -5
- package/dist/pipeline/__tests__/stages.test.js.map +1 -1
- package/dist/pipeline/stages/code-review.js.map +1 -1
- package/dist/pipeline/stages/ralph-verify.js.map +1 -1
- package/dist/pipeline/stages/ralplan.js.map +1 -1
- package/dist/pipeline/stages/team-exec.js.map +1 -1
- package/dist/pipeline/stages/ultragoal.js.map +1 -1
- package/dist/pipeline/stages/ultraqa.js.map +1 -1
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js.map +1 -1
- package/dist/planning/artifact-names.js.map +1 -1
- package/dist/planning/artifacts.js.map +1 -1
- package/dist/question/__tests__/state.test.js.map +1 -1
- package/dist/question/__tests__/ui.test.js.map +1 -1
- package/dist/question/autopilot-wait.js.map +1 -1
- package/dist/question/client.d.ts.map +1 -1
- package/dist/question/client.js.map +1 -1
- package/dist/question/deep-interview.js.map +1 -1
- package/dist/question/events.js.map +1 -1
- package/dist/question/renderer.js.map +1 -1
- package/dist/question/state.d.ts.map +1 -1
- package/dist/question/state.js.map +1 -1
- package/dist/question/ui.js.map +1 -1
- package/dist/ralph/contract.d.ts +1 -1
- package/dist/ralph/contract.d.ts.map +1 -1
- package/dist/ralplan/__tests__/consensus-gate.test.js +403 -8
- package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
- package/dist/ralplan/__tests__/runtime.test.js +112 -14
- package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
- package/dist/ralplan/consensus-gate.d.ts +3 -3
- package/dist/ralplan/consensus-gate.d.ts.map +1 -1
- package/dist/ralplan/consensus-gate.js +155 -60
- package/dist/ralplan/consensus-gate.js.map +1 -1
- package/dist/ralplan/runtime.d.ts +2 -2
- package/dist/ralplan/runtime.d.ts.map +1 -1
- package/dist/ralplan/runtime.js +1 -2
- package/dist/ralplan/runtime.js.map +1 -1
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/runtime/process-tree.js.map +1 -1
- package/dist/runtime/run-loop.js.map +1 -1
- package/dist/runtime/run-outcome.d.ts +3 -3
- package/dist/runtime/run-outcome.d.ts.map +1 -1
- package/dist/runtime/run-outcome.js.map +1 -1
- package/dist/runtime/run-state.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +4121 -592
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/fixtures/issue-3138-installed-smoke.d.ts +2 -0
- package/dist/scripts/__tests__/fixtures/issue-3138-installed-smoke.d.ts.map +1 -0
- package/dist/scripts/__tests__/fixtures/issue-3138-installed-smoke.js +634 -0
- package/dist/scripts/__tests__/fixtures/issue-3138-installed-smoke.js.map +1 -0
- package/dist/scripts/__tests__/generate-release-body.test.js.map +1 -1
- package/dist/scripts/__tests__/hook-derived-watcher.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-fallback-delivery.test.d.ts +2 -0
- package/dist/scripts/__tests__/notify-fallback-delivery.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/notify-fallback-delivery.test.js +174 -0
- package/dist/scripts/__tests__/notify-fallback-delivery.test.js.map +1 -0
- package/dist/scripts/__tests__/notify-state-io.test.js +57 -1
- package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.d.ts +2 -0
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +205 -0
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -0
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.d.ts +2 -0
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +175 -0
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -0
- package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js +848 -4
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/__tests__/test-reply-listener-live.test.js.map +1 -1
- package/dist/scripts/build-api.js.map +1 -1
- package/dist/scripts/build-explore-harness.js.map +1 -1
- package/dist/scripts/build-sparkshell.js.map +1 -1
- package/dist/scripts/cleanup-explore-harness.js.map +1 -1
- package/dist/scripts/codex-execution-surface.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +689 -156
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/generate-native-release-manifest.js.map +1 -1
- package/dist/scripts/generate-release-body.js.map +1 -1
- package/dist/scripts/hook-payload-guard.d.ts.map +1 -1
- package/dist/scripts/hook-payload-guard.js.map +1 -1
- package/dist/scripts/notify-fallback-delivery.d.ts +48 -0
- package/dist/scripts/notify-fallback-delivery.d.ts.map +1 -0
- package/dist/scripts/notify-fallback-delivery.js +419 -0
- package/dist/scripts/notify-fallback-delivery.js.map +1 -0
- package/dist/scripts/notify-fallback-watcher.js +136 -30
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts +18 -9
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +39 -13
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.d.ts +23 -0
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.js +122 -12
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
- package/dist/scripts/notify-hook/orchestration-intent.d.ts +7 -7
- package/dist/scripts/notify-hook/orchestration-intent.d.ts.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts +5 -2
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.js +33 -37
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts +17 -0
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +73 -11
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts +2 -2
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts +4 -4
- package/dist/scripts/notify-hook/team-worker-posttooluse.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.d.ts +1 -1
- package/dist/scripts/notify-hook/team-worker.d.ts +2 -2
- package/dist/scripts/notify-hook/tmux-injection.d.ts +8 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +25 -16
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook/visual-verdict.d.ts +1 -1
- package/dist/scripts/notify-hook/visual-verdict.d.ts.map +1 -1
- package/dist/scripts/notify-hook/visual-verdict.js +15 -13
- package/dist/scripts/notify-hook/visual-verdict.js.map +1 -1
- package/dist/scripts/notify-hook.d.ts +24 -1
- package/dist/scripts/notify-hook.d.ts.map +1 -1
- package/dist/scripts/notify-hook.js +266 -90
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/scripts/prompt-inventory.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +879 -2
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +1528 -7
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.js.map +1 -1
- package/dist/scripts/test-reply-listener-live.js.map +1 -1
- package/dist/scripts/test-sparkshell.js.map +1 -1
- package/dist/scripts/verify-native-agents.js.map +1 -1
- package/dist/session-history/friction.js.map +1 -1
- package/dist/session-history/search.js.map +1 -1
- package/dist/sidecar/__tests__/boundary.test.js.map +1 -1
- package/dist/sidecar/collector.js.map +1 -1
- package/dist/sidecar/index.js.map +1 -1
- package/dist/sidecar/render.js.map +1 -1
- package/dist/sidecar/tmux.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +64 -15
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/skill-active.test.js +19 -1
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.js +61 -0
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/mode-state-context.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 +49 -55
- package/dist/state/operations.js.map +1 -1
- package/dist/state/paths.d.ts +1 -1
- package/dist/state/paths.d.ts.map +1 -1
- package/dist/state/paths.js +1 -1
- package/dist/state/paths.js.map +1 -1
- package/dist/state/skill-active.d.ts +13 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +43 -4
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/terminal-normalization.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
- package/dist/state/workflow-transition-reconcile.js +20 -4
- package/dist/state/workflow-transition-reconcile.js.map +1 -1
- package/dist/state/workflow-transition.d.ts +1 -1
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/subagents/__tests__/adapted-role-binding.test.d.ts +2 -0
- package/dist/subagents/__tests__/adapted-role-binding.test.d.ts.map +1 -0
- package/dist/subagents/__tests__/adapted-role-binding.test.js +988 -0
- package/dist/subagents/__tests__/adapted-role-binding.test.js.map +1 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.d.ts +2 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.d.ts.map +1 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +273 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -0
- package/dist/subagents/__tests__/tracker.test.js +1550 -10
- package/dist/subagents/__tests__/tracker.test.js.map +1 -1
- package/dist/subagents/adapted-role-binding.d.ts +17 -0
- package/dist/subagents/adapted-role-binding.d.ts.map +1 -0
- package/dist/subagents/adapted-role-binding.js +75 -0
- package/dist/subagents/adapted-role-binding.js.map +1 -0
- package/dist/subagents/role-routing-marker.d.ts +10 -0
- package/dist/subagents/role-routing-marker.d.ts.map +1 -0
- package/dist/subagents/role-routing-marker.js +136 -0
- package/dist/subagents/role-routing-marker.js.map +1 -0
- package/dist/subagents/tracker.d.ts +172 -0
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +1077 -61
- package/dist/subagents/tracker.js.map +1 -1
- package/dist/team/__tests__/approved-execution.test.js.map +1 -1
- package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
- package/dist/team/__tests__/model-contract.test.js +231 -1
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/role-router.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +401 -1
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +181 -0
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +434 -4
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
- package/dist/team/api-interop.d.ts +2 -2
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/commit-hygiene.js.map +1 -1
- package/dist/team/contracts.d.ts +5 -5
- package/dist/team/contracts.d.ts.map +1 -1
- package/dist/team/delivery-log.js.map +1 -1
- package/dist/team/followup-planner.js.map +1 -1
- package/dist/team/goal-workflow.js.map +1 -1
- package/dist/team/idle-nudge.d.ts.map +1 -1
- package/dist/team/model-contract.d.ts +20 -1
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +267 -30
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/orchestrator.js.map +1 -1
- package/dist/team/pane-status.js.map +1 -1
- package/dist/team/phase-controller.js.map +1 -1
- package/dist/team/reminder-intents.d.ts +1 -1
- package/dist/team/reminder-intents.d.ts.map +1 -1
- package/dist/team/reminder-intents.js.map +1 -1
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +83 -52
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts +9 -7
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +69 -28
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/dispatch-lock.js.map +1 -1
- package/dist/team/state/dispatch.js.map +1 -1
- package/dist/team/state/events.js.map +1 -1
- package/dist/team/state/tasks.js.map +1 -1
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.js.map +1 -1
- package/dist/team/team-identity.d.ts.map +1 -1
- package/dist/team/team-identity.js.map +1 -1
- package/dist/team/tmux-session.d.ts +2 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +90 -42
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/team/worktree.js.map +1 -1
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +4 -1
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/dist/url-reader/index.js.map +1 -1
- package/dist/utils/agents-model-table.js.map +1 -1
- package/dist/utils/package.js.map +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/platform-command.js.map +1 -1
- package/dist/utils/repo-deps.js.map +1 -1
- package/dist/utils/version.js.map +1 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js +1 -1
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +1 -1
- package/dist/verification/verifier.js.map +1 -1
- package/dist/visual/constants.d.ts +1 -1
- package/dist/visual/constants.d.ts.map +1 -1
- package/dist/vscode/__tests__/index.test.js.map +1 -1
- package/dist/vscode/index.js.map +1 -1
- package/dist/wiki/__tests__/cjk-tokenize.test.js.map +1 -1
- package/dist/wiki/__tests__/lint.test.js.map +1 -1
- package/dist/wiki/__tests__/query.test.js.map +1 -1
- package/dist/wiki/__tests__/storage.test.js.map +1 -1
- package/dist/wiki/__tests__/test-helpers.d.ts.map +1 -1
- package/dist/wiki/lint.js.map +1 -1
- package/dist/wiki/query.js.map +1 -1
- package/dist/wiki/storage.js.map +1 -1
- package/package.json +2 -2
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +10 -5
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +4 -2
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +5 -2
- package/skills/omx-setup/SKILL.md +10 -5
- package/skills/ralph/SKILL.md +4 -2
- package/skills/ralplan/SKILL.md +5 -2
- package/src/scripts/__tests__/codex-native-hook.test.ts +17522 -10630
- package/src/scripts/__tests__/fixtures/issue-3138-installed-smoke.ts +734 -0
- package/src/scripts/__tests__/notify-fallback-delivery.test.ts +177 -0
- package/src/scripts/__tests__/notify-state-io.test.ts +73 -0
- package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +215 -0
- package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +193 -0
- package/src/scripts/__tests__/smoke-packed-install.test.ts +991 -4
- package/src/scripts/codex-native-hook.ts +779 -159
- package/src/scripts/notify-fallback-delivery.ts +416 -0
- package/src/scripts/notify-fallback-watcher.ts +132 -40
- package/src/scripts/notify-hook/auto-nudge.ts +43 -12
- package/src/scripts/notify-hook/managed-tmux.ts +149 -12
- package/src/scripts/notify-hook/ralph-session-resume.ts +37 -36
- package/src/scripts/notify-hook/state-io.ts +100 -13
- package/src/scripts/notify-hook/tmux-injection.ts +38 -21
- package/src/scripts/notify-hook/visual-verdict.ts +22 -12
- package/src/scripts/notify-hook.ts +335 -90
- package/src/scripts/smoke-packed-install.ts +1829 -6
|
@@ -6,18 +6,22 @@ import { pathToFileURL } from "url";
|
|
|
6
6
|
import { readModeStateForActiveDecision, readModeStateForSession, updateModeState } from "../modes/base.js";
|
|
7
7
|
import { redactAuthSecrets } from "../auth/redact.js";
|
|
8
8
|
import { SKILL_ACTIVE_STATE_FILE, extractSessionIdFromInitializedStatePath, getSkillActiveStatePathsForStateDir, listActiveSkills, readSkillActiveState, readVisibleSkillActiveStateForStateDir, } from "../state/skill-active.js";
|
|
9
|
-
import { isTrustedSubagentThread, readSubagentSessionSummary, readSubagentSessionLedger, readSubagentTrackingState, recordSubagentTurnForSession, } from "../subagents/tracker.js";
|
|
9
|
+
import { isTrustedSubagentThread, OMX_ADAPTED_PROVENANCE, attestLeaderThread, readSubagentSessionSummary, readSubagentSessionLedger, readSubagentTrackingState, readSubagentTrackingStateStrict, recordSubagentTurn, recordSubagentTurnForSession, resolveInstalledRoleName, } from "../subagents/tracker.js";
|
|
10
|
+
import { bindAndPublishAdaptedRole, NATIVE_SUBAGENT_ROLE_ROUTING_MARKER_TTL_MS, recoverAdaptedRoleBindings, } from "../subagents/adapted-role-binding.js";
|
|
11
|
+
import { readRoleRoutingMarker, writeRoleRoutingMarker } from "../subagents/role-routing-marker.js";
|
|
10
12
|
import { resolveCanonicalTeamStateRoot, resolveWorkerNotifyTeamStateRootPath } from "../team/state-root.js";
|
|
11
13
|
import { inferTerminalLifecycleOutcome } from "../runtime/run-outcome.js";
|
|
12
|
-
import { appendToLog, isSessionStale, isSessionStateUsable, readSessionState, readUsableSessionState, reconcileNativeSessionStart, } from "../hooks/session.js";
|
|
14
|
+
import { appendPromptSessionProvenanceRejection, appendToLog, isSessionPointerLaunchAbort, isSessionStale, isSessionStateUsable, normalizeSessionId, readSessionPointer, readSessionState, readUsableSessionState, reconcileNativeSessionStart, resolveSessionPointerContext, } from "../hooks/session.js";
|
|
15
|
+
import { evaluateResolvedPromptTurn, extractSelectedTargetOwnerEvidence, preflightSelectedTargetOwner, } from "../hooks/prompt-session-provenance.js";
|
|
13
16
|
import { appendTeamEvent, readTeamLeaderAttention, readTeamConfig, readTeamManifestV2, readTeamPhase, writeTeamLeaderAttention, writeTeamPhase, } from "../team/state.js";
|
|
14
|
-
import {
|
|
17
|
+
import { omxNotepadPath, resolveProjectMemoryPath } from "../utils/paths.js";
|
|
15
18
|
import { findGitLayout } from "../utils/git-layout.js";
|
|
16
|
-
import { getBaseStateDir, getStateFilePath, getStatePath,
|
|
17
|
-
import {
|
|
19
|
+
import { getAuthoritativeActiveStatePaths, getBaseStateDir, getStateFilePath, getStatePath, resolveWritableStateScope, WRITABLE_STATE_SCOPE_ERRORS, } from "../mcp/state-paths.js";
|
|
20
|
+
import { classifyKeywordInput, recordSkillActivation, } from "../hooks/keyword-detector.js";
|
|
18
21
|
import { buildDeepInterviewConfigInstruction } from "../hooks/deep-interview-config-instruction.js";
|
|
19
22
|
import { readTeamModeConfig } from "../config/team-mode.js";
|
|
20
23
|
import { detectNativeStopStallPattern, loadAutoNudgeConfig, normalizeAutoNudgeSignatureText, resolveEffectiveAutoNudgeResponse, } from "./notify-hook/auto-nudge.js";
|
|
24
|
+
import { probeActualTmuxInstanceEvidence, tmuxEvidenceBindsCandidate } from "./notify-hook/managed-tmux.js";
|
|
21
25
|
import { SLOPPY_FALLBACK_GROUNDING_PATTERNS, SLOPPY_FALLBACK_IMPLEMENTATION_CONTEXT_PATTERNS, SLOPPY_FALLBACK_PHRASE_PATTERNS, buildNativePostToolUseOutput, buildNativePreToolUseOutput, commandInvokesApplyPatch, detectMcpTransportFailure, hasAnyPattern, } from "./codex-native-pre-post.js";
|
|
22
26
|
import { handleTeamWorkerPostToolUseSuccess } from "./notify-hook/team-worker-posttooluse.js";
|
|
23
27
|
import { maybeNudgeLeaderForAllowedWorkerStop } from "./notify-hook/team-worker-stop.js";
|
|
@@ -29,9 +33,8 @@ import { getNotificationConfig, getVerbosity } from "../notifications/config.js"
|
|
|
29
33
|
import { reconcileHudForPromptSubmit } from "../hud/reconcile.js";
|
|
30
34
|
import { onPreCompact as buildWikiPreCompactContext, onSessionStart as buildWikiSessionStartContext, } from "../wiki/lifecycle.js";
|
|
31
35
|
import { readAutoresearchCompletionStatus, readAutoresearchModeStateForActiveDecision } from "../autoresearch/skill-validation.js";
|
|
32
|
-
import { AGENT_DEFINITIONS } from "../agents/definitions.js";
|
|
33
36
|
import { deriveAutopilotChildPhase, normalizeAutopilotPhase } from "../autopilot/fsm.js";
|
|
34
|
-
import { CONDUCTOR_ORCHESTRATION_METADATA_PREFIXES, LEADER_CONDUCTOR_BLOCK, LEADER_CONDUCTOR_REUSE_AND_LEDGER_GUIDANCE, NATIVE_SUBAGENT_SUPPORT_BLOCKER_FILE, actionKindForConductorArtifact, authorizeConductorAction, buildUnsupportedNativeSubagentGuidance, classifyConductorArtifactKind, isUnsupportedNativeSubagentEvidence, resolveNativeSubagentSupportStatus, } from "../leader/contract.js";
|
|
37
|
+
import { CONDUCTOR_ORCHESTRATION_METADATA_PREFIXES, LEADER_CONDUCTOR_BLOCK, LEADER_CONDUCTOR_REUSE_AND_LEDGER_GUIDANCE, NATIVE_SUBAGENT_SUPPORT_BLOCKER_FILE, actionKindForConductorArtifact, authorizeConductorAction, buildRoleRoutingUnavailableGuidance, buildUnsupportedNativeSubagentGuidance, classifyConductorArtifactKind, isNativeSubagentSpawnToolName, isRoleRoutingUnavailableEvidence, isUnsupportedNativeSubagentEvidence, parseRoleIntentCorrelationToken, resolveNativeSubagentSupportStatus, } from "../leader/contract.js";
|
|
35
38
|
import { readRunState } from "../runtime/run-state.js";
|
|
36
39
|
import { evaluateRalphCompletionAuditEvidence, isRalphCompletePhase } from "../ralph/completion-audit.js";
|
|
37
40
|
import { buildCodexGoalTerminalCleanupNotice, } from "../goal-workflows/codex-goal-snapshot.js";
|
|
@@ -89,9 +92,6 @@ const RALPH_LIVE_RISK_PATTERNS = [
|
|
|
89
92
|
/\b(?:database|db|terraform|kubectl|kubernetes|aws|gcp|azure|external|destructive)\b/i,
|
|
90
93
|
/\b(?:telegram|vps|service|restart|send|notify|notification|notifications|cron)\b/i,
|
|
91
94
|
];
|
|
92
|
-
const KNOWN_TYPED_AGENT_ROLES = new Set(Object.keys(AGENT_DEFINITIONS));
|
|
93
|
-
let installedTypedAgentRoleNamesCacheKey = "";
|
|
94
|
-
let installedTypedAgentRoleNamesCache = new Set();
|
|
95
95
|
const RALPH_TASK_TEXT_FIELDS = [
|
|
96
96
|
"task_description",
|
|
97
97
|
"taskDescription",
|
|
@@ -115,6 +115,18 @@ const MAX_SESSION_META_LINE_BYTES = 256 * 1024;
|
|
|
115
115
|
function safeString(value) {
|
|
116
116
|
return typeof value === "string" ? value : "";
|
|
117
117
|
}
|
|
118
|
+
async function resolveVerifiedOwnerOmxSessionId() {
|
|
119
|
+
const candidate = normalizeSessionId(process.env.OMX_SESSION_ID);
|
|
120
|
+
if (!candidate)
|
|
121
|
+
return undefined;
|
|
122
|
+
const evidence = await probeActualTmuxInstanceEvidence(process.env.TMUX_PANE);
|
|
123
|
+
return tmuxEvidenceBindsCandidate(evidence, candidate) ? candidate : undefined;
|
|
124
|
+
}
|
|
125
|
+
function isImplicitWritableScopeFailure(error) {
|
|
126
|
+
return error instanceof Error
|
|
127
|
+
&& (error.message === WRITABLE_STATE_SCOPE_ERRORS.unboundEnvironment
|
|
128
|
+
|| error.message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession);
|
|
129
|
+
}
|
|
118
130
|
function safeObject(value) {
|
|
119
131
|
return value && typeof value === "object" ? value : {};
|
|
120
132
|
}
|
|
@@ -219,6 +231,14 @@ function readBoundedFirstLineSync(path) {
|
|
|
219
231
|
closeSync(fd);
|
|
220
232
|
}
|
|
221
233
|
}
|
|
234
|
+
function selectAuthoritativeTaskName(threadSpawn, subagent, payload) {
|
|
235
|
+
for (const obj of [threadSpawn, subagent, payload]) {
|
|
236
|
+
if (obj && typeof obj === "object" && "task_name" in obj) {
|
|
237
|
+
return { present: true, value: obj.task_name };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return { present: false, value: undefined };
|
|
241
|
+
}
|
|
222
242
|
function readNativeSubagentSessionStartMetadata(transcriptPath) {
|
|
223
243
|
const normalizedPath = transcriptPath.trim();
|
|
224
244
|
if (!normalizedPath)
|
|
@@ -237,40 +257,100 @@ function readNativeSubagentSessionStartMetadata(transcriptPath) {
|
|
|
237
257
|
const parentThreadId = safeString(threadSpawn.parent_thread_id).trim();
|
|
238
258
|
if (!parentThreadId)
|
|
239
259
|
return null;
|
|
240
|
-
const
|
|
241
|
-
|
|
260
|
+
const agentNicknameCarrierValues = [
|
|
261
|
+
threadSpawn.agent_nickname ?? threadSpawn.agentNickname,
|
|
262
|
+
subagent.agent_nickname ?? subagent.agentNickname,
|
|
263
|
+
payload.agent_nickname ?? payload.agentNickname,
|
|
264
|
+
];
|
|
265
|
+
const agentNickname = safeString(agentNicknameCarrierValues[0]).trim();
|
|
266
|
+
const authoritativeTaskName = selectAuthoritativeTaskName(threadSpawn, subagent, payload);
|
|
267
|
+
const correlationToken = authoritativeTaskName.present
|
|
268
|
+
? parseRoleIntentCorrelationToken(authoritativeTaskName.value)
|
|
269
|
+
: undefined;
|
|
270
|
+
const agentRole = safeString(threadSpawn.agent_role
|
|
271
|
+
?? threadSpawn.agentRole
|
|
272
|
+
?? threadSpawn.agent_type
|
|
273
|
+
?? threadSpawn.agentType
|
|
274
|
+
?? payload.agent_role
|
|
275
|
+
?? payload.agentRole
|
|
276
|
+
?? payload.agent_type
|
|
277
|
+
?? payload.agentType).trim();
|
|
242
278
|
return {
|
|
243
279
|
parentThreadId,
|
|
244
280
|
...(agentNickname ? { agentNickname } : {}),
|
|
245
281
|
...(agentRole ? { agentRole } : {}),
|
|
282
|
+
...(correlationToken ? { correlationToken } : {}),
|
|
246
283
|
};
|
|
247
284
|
}
|
|
248
285
|
catch {
|
|
249
286
|
return null;
|
|
250
287
|
}
|
|
251
288
|
}
|
|
289
|
+
function reportRoleRoutingBindingFailure(error) {
|
|
290
|
+
console.error(`[omx] SECURITY: native adapted role binding did not complete; retained binding will be recovered: ${error instanceof Error ? error.message : String(error)}`);
|
|
291
|
+
}
|
|
252
292
|
async function recordNativeSubagentSessionStart(cwd, canonicalSessionId, childSessionId, metadata, transcriptPath) {
|
|
253
293
|
const parentThreadId = metadata.parentThreadId.trim();
|
|
254
294
|
const childThreadId = childSessionId.trim();
|
|
295
|
+
const correlationSessionId = canonicalSessionId.trim() || parentThreadId;
|
|
255
296
|
const trackingSessionIds = [...new Set([
|
|
256
297
|
canonicalSessionId.trim(),
|
|
257
298
|
parentThreadId,
|
|
258
299
|
].filter(Boolean))];
|
|
259
|
-
|
|
260
|
-
|
|
300
|
+
let adaptedRoleIntent = null;
|
|
301
|
+
if (!metadata.agentRole && correlationSessionId && parentThreadId) {
|
|
302
|
+
try {
|
|
303
|
+
const bound = bindAndPublishAdaptedRole(cwd, getBaseStateDir(cwd), {
|
|
304
|
+
correlationSessionId,
|
|
305
|
+
parentThreadId,
|
|
306
|
+
correlationToken: metadata.correlationToken,
|
|
307
|
+
}, (state, intent) => {
|
|
308
|
+
let next = state;
|
|
309
|
+
for (const sessionId of trackingSessionIds) {
|
|
310
|
+
if (parentThreadId && parentThreadId !== childThreadId) {
|
|
311
|
+
next = recordSubagentTurn(next, {
|
|
312
|
+
sessionId,
|
|
313
|
+
threadId: parentThreadId,
|
|
314
|
+
kind: "leader",
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
next = recordSubagentTurn(next, {
|
|
318
|
+
sessionId,
|
|
319
|
+
threadId: childThreadId,
|
|
320
|
+
kind: "subagent",
|
|
321
|
+
...(parentThreadId && parentThreadId !== childThreadId ? { leaderThreadId: parentThreadId } : {}),
|
|
322
|
+
mode: intent.role,
|
|
323
|
+
role: intent.role,
|
|
324
|
+
provenanceKind: intent.provenanceKind,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
return next;
|
|
328
|
+
});
|
|
329
|
+
adaptedRoleIntent = bound ? { role: bound.role, provenanceKind: OMX_ADAPTED_PROVENANCE } : null;
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
reportRoleRoutingBindingFailure(error);
|
|
333
|
+
throw error;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (!adaptedRoleIntent) {
|
|
337
|
+
for (const sessionId of trackingSessionIds) {
|
|
338
|
+
if (parentThreadId && parentThreadId !== childThreadId) {
|
|
339
|
+
await recordSubagentTurnForSession(cwd, {
|
|
340
|
+
sessionId,
|
|
341
|
+
threadId: parentThreadId,
|
|
342
|
+
kind: "leader",
|
|
343
|
+
}).catch(() => { });
|
|
344
|
+
}
|
|
261
345
|
await recordSubagentTurnForSession(cwd, {
|
|
262
346
|
sessionId,
|
|
263
|
-
threadId:
|
|
264
|
-
kind:
|
|
347
|
+
threadId: childThreadId,
|
|
348
|
+
kind: "subagent",
|
|
349
|
+
...(parentThreadId && parentThreadId !== childThreadId ? { leaderThreadId: parentThreadId } : {}),
|
|
350
|
+
mode: metadata.agentRole,
|
|
265
351
|
}).catch(() => { });
|
|
266
352
|
}
|
|
267
|
-
|
|
268
|
-
sessionId,
|
|
269
|
-
threadId: childThreadId,
|
|
270
|
-
kind: 'subagent',
|
|
271
|
-
...(parentThreadId && parentThreadId !== childThreadId ? { leaderThreadId: parentThreadId } : {}),
|
|
272
|
-
mode: metadata.agentRole,
|
|
273
|
-
}).catch(() => { });
|
|
353
|
+
refreshNativeSubagentRoleRoutingMarker(cwd, getBaseStateDir(cwd), correlationSessionId, parentThreadId);
|
|
274
354
|
}
|
|
275
355
|
await appendToLog(cwd, {
|
|
276
356
|
event: "subagent_session_start",
|
|
@@ -349,6 +429,26 @@ async function isNativeSubagentHook(cwd, canonicalSessionId, nativeSessionId, th
|
|
|
349
429
|
return false;
|
|
350
430
|
return Object.values(trackingState.sessions).some((session) => (candidateIds.some((id) => isTrustedSubagentThread(session, id))));
|
|
351
431
|
}
|
|
432
|
+
async function readNativePromptThreadFacts(cwd, nativeSessionId, threadId, currentSessionState) {
|
|
433
|
+
const candidateIds = [nativeSessionId, threadId].map((value) => value.trim()).filter(Boolean);
|
|
434
|
+
if (candidateIds.length === 0)
|
|
435
|
+
return undefined;
|
|
436
|
+
const currentNativeIds = new Set([
|
|
437
|
+
safeString(currentSessionState?.native_session_id).trim(),
|
|
438
|
+
safeString(currentSessionState?.codex_session_id).trim(),
|
|
439
|
+
safeString(currentSessionState?.owner_codex_session_id).trim(),
|
|
440
|
+
].filter(Boolean));
|
|
441
|
+
const currentTargetAnchored = Boolean(nativeSessionId && currentNativeIds.has(nativeSessionId));
|
|
442
|
+
const trackingState = await readSubagentTrackingState(cwd).catch(() => null);
|
|
443
|
+
if (!trackingState)
|
|
444
|
+
return currentTargetAnchored ? { currentTargetAnchored: true, rootOrDrift: true } : undefined;
|
|
445
|
+
const roots = Object.values(trackingState.sessions).flatMap((session) => (candidateIds.some((candidate) => isTrustedSubagentThread(session, candidate))
|
|
446
|
+
? [session.session_id]
|
|
447
|
+
: []));
|
|
448
|
+
return roots.length > 0 || currentTargetAnchored
|
|
449
|
+
? { trackerRootOwnerSessionIds: roots, currentTargetAnchored, rootOrDrift: currentTargetAnchored }
|
|
450
|
+
: undefined;
|
|
451
|
+
}
|
|
352
452
|
function shouldSuppressSubagentLifecycleHookDispatch() {
|
|
353
453
|
const config = getNotificationConfig();
|
|
354
454
|
if (config?.includeChildAgents === true)
|
|
@@ -494,8 +594,8 @@ function readPromptText(payload) {
|
|
|
494
594
|
payload.userPrompt,
|
|
495
595
|
];
|
|
496
596
|
for (const candidate of candidates) {
|
|
497
|
-
const value = safeString(candidate)
|
|
498
|
-
if (value)
|
|
597
|
+
const value = safeString(candidate);
|
|
598
|
+
if (value.trim())
|
|
499
599
|
return value;
|
|
500
600
|
}
|
|
501
601
|
return "";
|
|
@@ -1759,19 +1859,21 @@ function buildTeamHelpInstruction(cwd, payload) {
|
|
|
1759
1859
|
nativeSessionId: safeString(payload?.session_id ?? payload?.sessionId).trim(),
|
|
1760
1860
|
}).teamHelpInstruction;
|
|
1761
1861
|
}
|
|
1762
|
-
function
|
|
1763
|
-
if (!readTeamModeConfig(cwd).enabled)
|
|
1764
|
-
return null;
|
|
1765
|
-
const match = detectPrimaryKeyword(prompt);
|
|
1766
|
-
if (match?.skill !== "team")
|
|
1767
|
-
return null;
|
|
1862
|
+
function isNativeOutsideTmuxUserPrompt(cwd, payload, sessionId) {
|
|
1768
1863
|
const environment = resolveExecutionEnvironment(cwd, {
|
|
1769
1864
|
hookEventName: "UserPromptSubmit",
|
|
1770
1865
|
payload,
|
|
1771
1866
|
canonicalSessionId: sessionId ?? "",
|
|
1772
1867
|
nativeSessionId: safeString(payload.session_id ?? payload.sessionId).trim(),
|
|
1773
1868
|
});
|
|
1774
|
-
|
|
1869
|
+
return environment.launcher === "native" && environment.transport === "outside-tmux";
|
|
1870
|
+
}
|
|
1871
|
+
function buildNativeOutsideTmuxTeamPromptBlockState(classification, cwd, payload, sessionId, threadId, turnId) {
|
|
1872
|
+
const teamMode = readTeamModeConfig(cwd);
|
|
1873
|
+
const match = classification.matches.filter((entry) => teamMode.enabled || entry.skill !== "team")[0] ?? null;
|
|
1874
|
+
if (match?.skill !== "team")
|
|
1875
|
+
return null;
|
|
1876
|
+
if (!isNativeOutsideTmuxUserPrompt(cwd, payload, sessionId))
|
|
1775
1877
|
return null;
|
|
1776
1878
|
const nowIso = new Date().toISOString();
|
|
1777
1879
|
return {
|
|
@@ -1803,13 +1905,19 @@ function buildAutopilotPromptActivationNote(skillState, options = {}) {
|
|
|
1803
1905
|
const nativeSubagentSupport = resolveNativeSubagentSupportStatus({
|
|
1804
1906
|
payload: options.payload,
|
|
1805
1907
|
persistedSupportBlocker: readJsonSyncIfExists(nativeSubagentSupportBlockerPath(stateDir)),
|
|
1908
|
+
persistedRoleRoutingMarker: readRoleRoutingMarker(stateDir, {
|
|
1909
|
+
cwd: options.cwd,
|
|
1910
|
+
sessionId: options.sessionId ?? "",
|
|
1911
|
+
}),
|
|
1806
1912
|
persistedCapacityBlocker: readJsonSyncIfExists(nativeSubagentCapacityBlockerPath(stateDir)),
|
|
1807
1913
|
cwd: options.cwd,
|
|
1808
1914
|
sessionId: options.sessionId,
|
|
1809
1915
|
});
|
|
1810
1916
|
const conductorGuidance = nativeSubagentSupport.status === "unsupported"
|
|
1811
1917
|
? buildUnsupportedNativeSubagentGuidance(nativeSubagentSupport)
|
|
1812
|
-
:
|
|
1918
|
+
: nativeSubagentSupport.status === "role_routing_unavailable"
|
|
1919
|
+
? buildRoleRoutingUnavailableGuidance(nativeSubagentSupport)
|
|
1920
|
+
: `${LEADER_CONDUCTOR_BLOCK} ${LEADER_CONDUCTOR_REUSE_AND_LEDGER_GUIDANCE}`;
|
|
1813
1921
|
return [
|
|
1814
1922
|
`Autopilot protocol: the durable default chain is $deep-interview -> $ralplan -> $ultragoal${teamHandoff} -> $code-review -> $ultraqa (deep-interview -> ralplan -> ultragoal -> code-review -> ultraqa).`,
|
|
1815
1923
|
"Start/resume at current_phase=deep-interview unless the task is clear and bounded; if deep-interview is intentionally skipped, persist and state an explicit deep_interview_gate.skip_reason before moving to ralplan.",
|
|
@@ -1829,7 +1937,8 @@ function formatExecutionHandoffList(cwd) {
|
|
|
1829
1937
|
? "`$ultragoal`, `$team`, or `$ralph`"
|
|
1830
1938
|
: "`$ultragoal` or `$ralph`";
|
|
1831
1939
|
}
|
|
1832
|
-
function buildAdditionalContextMessage(
|
|
1940
|
+
function buildAdditionalContextMessage(classification, skillState, cwd = process.cwd(), payload) {
|
|
1941
|
+
const prompt = classification.originalText;
|
|
1833
1942
|
if (!prompt)
|
|
1834
1943
|
return null;
|
|
1835
1944
|
const promptPriorityMessage = buildPromptPriorityMessage(prompt);
|
|
@@ -1837,20 +1946,29 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
|
|
|
1837
1946
|
return promptPriorityMessage;
|
|
1838
1947
|
}
|
|
1839
1948
|
const teamMode = readTeamModeConfig(cwd);
|
|
1840
|
-
const matches =
|
|
1949
|
+
const matches = classification.matches.filter((entry) => teamMode.enabled || entry.skill !== "team");
|
|
1841
1950
|
const match = matches[0] ?? null;
|
|
1842
1951
|
if (!match) {
|
|
1952
|
+
const markedQuestionAnswer = classification.reservedInput === "omx-question-answered";
|
|
1843
1953
|
const continuedSkill = safeString(skillState?.skill).trim();
|
|
1844
|
-
|
|
1954
|
+
const eligibleMarkedContinuation = markedQuestionAnswer
|
|
1955
|
+
&& skillState?.active === true
|
|
1956
|
+
&& (continuedSkill === "autopilot" || continuedSkill === "deep-interview");
|
|
1957
|
+
const eligibleOrdinaryContinuation = classification.reservedInput === null
|
|
1958
|
+
&& !classification.hasExplicitLikeInvocation
|
|
1959
|
+
&& skillState?.active === true
|
|
1960
|
+
&& Boolean(continuedSkill);
|
|
1961
|
+
if (!eligibleMarkedContinuation && !eligibleOrdinaryContinuation)
|
|
1845
1962
|
return promptPriorityMessage;
|
|
1846
1963
|
const deepInterviewPromptActivationNote = skillState?.initialized_mode === "deep-interview"
|
|
1847
1964
|
? buildDeepInterviewQuestionBridgeInstruction(cwd, payload)
|
|
1848
1965
|
: null;
|
|
1849
1966
|
const deepInterviewConfigPromptActivationNote = buildDeepInterviewConfigInstruction(cwd, skillState);
|
|
1850
|
-
const markedQuestionAnswer = /^\s*\[omx question answered\]/i.test(prompt);
|
|
1851
1967
|
const autopilotPromptActivationNote = buildAutopilotPromptActivationNote(skillState, { markedQuestionAnswer, cwd, payload, sessionId: safeString(skillState?.session_id).trim() });
|
|
1852
1968
|
return [
|
|
1853
|
-
|
|
1969
|
+
markedQuestionAnswer
|
|
1970
|
+
? `OMX native UserPromptSubmit continued active workflow skill "${continuedSkill}"; workflow-like tokens inside the marked omx question answer are treated as answer text, not a new workflow activation.`
|
|
1971
|
+
: `OMX native UserPromptSubmit continued active workflow skill "${continuedSkill}".`,
|
|
1854
1972
|
promptPriorityMessage,
|
|
1855
1973
|
skillState?.initialized_mode && skillState.initialized_state_path
|
|
1856
1974
|
? buildSkillStateCliInstruction(skillState.initialized_mode, skillState.initialized_state_path)
|
|
@@ -1864,27 +1982,6 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
|
|
|
1864
1982
|
const detectedKeywordMessage = matches.length > 1
|
|
1865
1983
|
? `OMX native UserPromptSubmit detected workflow keywords ${matches.map((entry) => `"${entry.keyword}" -> ${entry.skill}`).join(", ")}.`
|
|
1866
1984
|
: `OMX native UserPromptSubmit detected workflow keyword "${match.keyword}" -> ${match.skill}.`;
|
|
1867
|
-
const continuedSkill = safeString(skillState?.skill).trim();
|
|
1868
|
-
if (continuedSkill
|
|
1869
|
-
&& continuedSkill !== match.skill
|
|
1870
|
-
&& /^\s*\[omx question answered\]/i.test(prompt)) {
|
|
1871
|
-
const deepInterviewPromptActivationNote = skillState?.initialized_mode === "deep-interview"
|
|
1872
|
-
? buildDeepInterviewQuestionBridgeInstruction(cwd, payload)
|
|
1873
|
-
: null;
|
|
1874
|
-
const deepInterviewConfigPromptActivationNote = buildDeepInterviewConfigInstruction(cwd, skillState);
|
|
1875
|
-
const autopilotPromptActivationNote = buildAutopilotPromptActivationNote(skillState, { markedQuestionAnswer: true, cwd, payload, sessionId: safeString(skillState?.session_id).trim() });
|
|
1876
|
-
return [
|
|
1877
|
-
`OMX native UserPromptSubmit continued active workflow skill "${continuedSkill}"; workflow-like tokens inside the marked omx question answer are treated as answer text, not a new workflow activation.`,
|
|
1878
|
-
promptPriorityMessage,
|
|
1879
|
-
skillState?.initialized_mode && skillState.initialized_state_path
|
|
1880
|
-
? buildSkillStateCliInstruction(skillState.initialized_mode, skillState.initialized_state_path)
|
|
1881
|
-
: null,
|
|
1882
|
-
deepInterviewPromptActivationNote,
|
|
1883
|
-
deepInterviewConfigPromptActivationNote,
|
|
1884
|
-
autopilotPromptActivationNote,
|
|
1885
|
-
"Follow AGENTS.md routing and preserve workflow transition and planning-safety rules.",
|
|
1886
|
-
].filter(Boolean).join(" ");
|
|
1887
|
-
}
|
|
1888
1985
|
const activeSkills = Array.isArray(skillState?.active_skills)
|
|
1889
1986
|
? skillState.active_skills.map((entry) => entry.skill)
|
|
1890
1987
|
: [];
|
|
@@ -2627,31 +2724,66 @@ function readPayloadAgentRole(payload) {
|
|
|
2627
2724
|
?? threadSpawn?.agent_type
|
|
2628
2725
|
?? threadSpawn?.agentType).trim().toLowerCase();
|
|
2629
2726
|
}
|
|
2630
|
-
function
|
|
2631
|
-
const
|
|
2632
|
-
if (
|
|
2633
|
-
return
|
|
2634
|
-
const
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
continue;
|
|
2640
|
-
installedRoleNames.add(entry.name.slice(0, -5).trim().toLowerCase());
|
|
2641
|
-
}
|
|
2642
|
-
}
|
|
2643
|
-
catch {
|
|
2644
|
-
// Ignore missing or unreadable agent directories; built-in definitions remain authoritative.
|
|
2645
|
-
}
|
|
2646
|
-
}
|
|
2647
|
-
installedTypedAgentRoleNamesCacheKey = cacheKey;
|
|
2648
|
-
installedTypedAgentRoleNamesCache = installedRoleNames;
|
|
2649
|
-
return installedTypedAgentRoleNamesCache;
|
|
2727
|
+
function readRequestedSpawnRole(payload) {
|
|
2728
|
+
const toolName = safeString(payload.tool_name).trim();
|
|
2729
|
+
if (!isNativeSubagentSpawnToolName(toolName))
|
|
2730
|
+
return "";
|
|
2731
|
+
const toolInput = safeObject(payload.tool_input);
|
|
2732
|
+
return safeString(toolInput.agent_role
|
|
2733
|
+
?? toolInput.agentRole
|
|
2734
|
+
?? toolInput.agent_type
|
|
2735
|
+
?? toolInput.agentType).trim().toLowerCase();
|
|
2650
2736
|
}
|
|
2651
2737
|
function isTypedAgentRolePayload(payload) {
|
|
2652
2738
|
const agentRole = readPayloadAgentRole(payload);
|
|
2653
|
-
return agentRole !== "" && (
|
|
2654
|
-
|
|
2739
|
+
return agentRole !== "" && resolveInstalledRoleName(agentRole) !== null;
|
|
2740
|
+
}
|
|
2741
|
+
// #3181: detect a runtime-set native subagent PreToolUse. The runtime sets
|
|
2742
|
+
// source.subagent.thread_spawn (not agent-controlled tool arguments), so the mere
|
|
2743
|
+
// STRUCTURAL PRESENCE of that carrier — even if its parent id is blank, malformed, or
|
|
2744
|
+
// null — marks a child/subagent turn that must never be attested as the session leader.
|
|
2745
|
+
// This is a negative security decision, so it fails closed on any present carrier rather
|
|
2746
|
+
// than requiring a well-formed parent id.
|
|
2747
|
+
function hasSubagentThreadSpawnProvenance(payload) {
|
|
2748
|
+
const source = payload.source;
|
|
2749
|
+
if (!source || typeof source !== "object")
|
|
2750
|
+
return false;
|
|
2751
|
+
const subagent = source.subagent;
|
|
2752
|
+
if (!subagent || typeof subagent !== "object")
|
|
2753
|
+
return false;
|
|
2754
|
+
return Object.prototype.hasOwnProperty.call(subagent, "thread_spawn");
|
|
2755
|
+
}
|
|
2756
|
+
// #3181: positive counter-evidence guard. A thread durably tracked as a subagent in ANY
|
|
2757
|
+
// session must never be attested as a leader, even if the current payload lacks typed-role
|
|
2758
|
+
// or thread_spawn provenance. This closes the source-less/untyped child escalation where a
|
|
2759
|
+
// child recorded at its SessionStart later self-promotes via a source-less PreToolUse.
|
|
2760
|
+
async function isThreadTrackedAsSubagent(cwd, threadId) {
|
|
2761
|
+
const id = threadId.trim();
|
|
2762
|
+
if (!id)
|
|
2763
|
+
return false;
|
|
2764
|
+
// Strict read: an unreadable/corrupt tracker fails closed (treated as "is a subagent")
|
|
2765
|
+
// so corrupt evidence cannot let a source-less child reconcile/attest as leader.
|
|
2766
|
+
const read = await readSubagentTrackingStateStrict(cwd);
|
|
2767
|
+
if (!read.ok)
|
|
2768
|
+
return true;
|
|
2769
|
+
for (const session of Object.values(read.state.sessions)) {
|
|
2770
|
+
if (session.threads?.[id]?.kind === "subagent")
|
|
2771
|
+
return true;
|
|
2772
|
+
}
|
|
2773
|
+
return false;
|
|
2774
|
+
}
|
|
2775
|
+
function buildNativeUnknownRolePreToolUseOutput(payload) {
|
|
2776
|
+
const requestedRole = readRequestedSpawnRole(payload);
|
|
2777
|
+
if (!requestedRole || resolveInstalledRoleName(requestedRole) !== null)
|
|
2778
|
+
return null;
|
|
2779
|
+
return {
|
|
2780
|
+
decision: "block",
|
|
2781
|
+
reason: "Native typed-subagent dispatch denied: supplied agent_type/agent_role is unknown or not installed.",
|
|
2782
|
+
hookSpecificOutput: {
|
|
2783
|
+
hookEventName: "PreToolUse",
|
|
2784
|
+
additionalContext: "Use an installed OMX role for native agent_type/agent_role dispatch. On a role-routing-unavailable surface, record a validated OMX adapted role intent before spawning without fabricating agent_type.",
|
|
2785
|
+
},
|
|
2786
|
+
};
|
|
2655
2787
|
}
|
|
2656
2788
|
function readPayloadTurnId(payload) {
|
|
2657
2789
|
return safeString(payload.turn_id ?? payload.turnId).trim();
|
|
@@ -2736,6 +2868,21 @@ async function recordNativeSubagentSupportBlocker(cwd, stateDir, payload) {
|
|
|
2736
2868
|
cwd,
|
|
2737
2869
|
}, null, 2));
|
|
2738
2870
|
}
|
|
2871
|
+
function refreshNativeSubagentRoleRoutingMarker(cwd, stateDir, sessionId, parentThreadId) {
|
|
2872
|
+
const marker = readRoleRoutingMarker(stateDir, {
|
|
2873
|
+
cwd,
|
|
2874
|
+
sessionId,
|
|
2875
|
+
...(parentThreadId ? { parentThreadId } : {}),
|
|
2876
|
+
});
|
|
2877
|
+
if (!marker)
|
|
2878
|
+
return;
|
|
2879
|
+
const nowMs = Date.now();
|
|
2880
|
+
writeRoleRoutingMarker(stateDir, {
|
|
2881
|
+
...marker,
|
|
2882
|
+
observed_at: new Date(nowMs).toISOString(),
|
|
2883
|
+
expires_at: new Date(nowMs + NATIVE_SUBAGENT_ROLE_ROUTING_MARKER_TTL_MS).toISOString(),
|
|
2884
|
+
});
|
|
2885
|
+
}
|
|
2739
2886
|
function summarizeCapacityFailure(text) {
|
|
2740
2887
|
const normalized = text.replace(/\s+/g, " ").trim();
|
|
2741
2888
|
if (!normalized)
|
|
@@ -2824,13 +2971,13 @@ async function buildNativeSubagentCapacityCloseGuardOutput(payload, cwd, stateDi
|
|
|
2824
2971
|
},
|
|
2825
2972
|
};
|
|
2826
2973
|
}
|
|
2827
|
-
async function resolveInternalSessionIdForPayload(cwd, payloadSessionId, stateDir) {
|
|
2828
|
-
const currentSession = stateDir
|
|
2974
|
+
async function resolveInternalSessionIdForPayload(cwd, payloadSessionId, stateDir, pointerSessionState, allowUnboundPayloadFallback = true) {
|
|
2975
|
+
const currentSession = pointerSessionState ?? (stateDir
|
|
2829
2976
|
? await readUsableSessionStateFromStateDir(cwd, stateDir)
|
|
2830
|
-
: await readUsableSessionState(cwd);
|
|
2977
|
+
: await readUsableSessionState(cwd));
|
|
2831
2978
|
const canonicalSessionId = safeString(currentSession?.session_id).trim();
|
|
2832
2979
|
if (!canonicalSessionId)
|
|
2833
|
-
return payloadSessionId;
|
|
2980
|
+
return allowUnboundPayloadFallback ? payloadSessionId : "";
|
|
2834
2981
|
const nativeSessionId = safeString(currentSession?.native_session_id).trim();
|
|
2835
2982
|
const ownerOmxSessionId = safeString(currentSession?.owner_omx_session_id).trim();
|
|
2836
2983
|
if (!payloadSessionId)
|
|
@@ -2841,7 +2988,7 @@ async function resolveInternalSessionIdForPayload(cwd, payloadSessionId, stateDi
|
|
|
2841
2988
|
return canonicalSessionId;
|
|
2842
2989
|
if (ownerOmxSessionId && payloadSessionId === ownerOmxSessionId)
|
|
2843
2990
|
return canonicalSessionId;
|
|
2844
|
-
return payloadSessionId;
|
|
2991
|
+
return allowUnboundPayloadFallback ? payloadSessionId : "";
|
|
2845
2992
|
}
|
|
2846
2993
|
async function readRootSessionStateFromStateDir(stateDir) {
|
|
2847
2994
|
const sessionPath = join(stateDir, "session.json");
|
|
@@ -2945,17 +3092,6 @@ const RALPLAN_EXECUTION_HANDOFF_SKILLS = new Set([
|
|
|
2945
3092
|
"ultrawork",
|
|
2946
3093
|
"ultraqa",
|
|
2947
3094
|
]);
|
|
2948
|
-
function isActiveDeepInterviewPhase(state) {
|
|
2949
|
-
if (!state || state.active !== true)
|
|
2950
|
-
return false;
|
|
2951
|
-
const mode = safeString(state.mode).trim();
|
|
2952
|
-
if (mode && mode !== "deep-interview")
|
|
2953
|
-
return false;
|
|
2954
|
-
const phase = safeString(state.current_phase ?? state.currentPhase).trim().toLowerCase();
|
|
2955
|
-
if (phase && (TERMINAL_MODE_PHASES.has(phase) || phase === "completing"))
|
|
2956
|
-
return false;
|
|
2957
|
-
return true;
|
|
2958
|
-
}
|
|
2959
3095
|
function isInactiveCompletedDeepInterviewPhase(state) {
|
|
2960
3096
|
if (!state || state.active !== false)
|
|
2961
3097
|
return false;
|
|
@@ -6250,6 +6386,121 @@ function isCompleteRalplanTerminalWritePayload(payload, activeState, sessionId)
|
|
|
6250
6386
|
return false;
|
|
6251
6387
|
return true;
|
|
6252
6388
|
}
|
|
6389
|
+
function hasUnquotedShellControlOrRedirection(command) {
|
|
6390
|
+
let quote = null;
|
|
6391
|
+
for (let index = 0; index < command.length; index += 1) {
|
|
6392
|
+
const char = command[index] ?? "";
|
|
6393
|
+
if (char === "\\" && quote !== "'") {
|
|
6394
|
+
index += 1;
|
|
6395
|
+
continue;
|
|
6396
|
+
}
|
|
6397
|
+
if (char === "'" || char === '"') {
|
|
6398
|
+
quote = quote === char ? null : quote ?? char;
|
|
6399
|
+
continue;
|
|
6400
|
+
}
|
|
6401
|
+
if (!quote && ";&|()<>\n\r".includes(char))
|
|
6402
|
+
return true;
|
|
6403
|
+
}
|
|
6404
|
+
return false;
|
|
6405
|
+
}
|
|
6406
|
+
function suppliedSessionAliasesMatch(payload, sessionId) {
|
|
6407
|
+
return [
|
|
6408
|
+
payload.session_id,
|
|
6409
|
+
payload.owner_omx_session_id,
|
|
6410
|
+
payload.codex_session_id,
|
|
6411
|
+
payload.owner_codex_session_id,
|
|
6412
|
+
].filter((value) => value !== undefined)
|
|
6413
|
+
.every((value) => safeString(value).trim() === sessionId);
|
|
6414
|
+
}
|
|
6415
|
+
function hasOnlyFinishedExplicitOutcomes(payload) {
|
|
6416
|
+
const values = [
|
|
6417
|
+
payload.lifecycle_outcome,
|
|
6418
|
+
payload.lifecycleOutcome,
|
|
6419
|
+
payload.terminal_outcome,
|
|
6420
|
+
payload.terminalOutcome,
|
|
6421
|
+
payload.run_outcome,
|
|
6422
|
+
payload.runOutcome,
|
|
6423
|
+
].filter((value) => value !== undefined);
|
|
6424
|
+
return values.every((value) => inferTerminalLifecycleOutcome({ lifecycle_outcome: value }, { includeQuestionEnforcement: false }) === "finished");
|
|
6425
|
+
}
|
|
6426
|
+
function isCompleteDeepInterviewTerminalWritePayload(payload, activeState, sessionId) {
|
|
6427
|
+
if (!sessionId)
|
|
6428
|
+
return false;
|
|
6429
|
+
const activeMode = safeString(activeState.mode).trim().toLowerCase();
|
|
6430
|
+
if (activeMode && activeMode !== "deep-interview")
|
|
6431
|
+
return false;
|
|
6432
|
+
const activeSessionId = safeString(activeState.session_id
|
|
6433
|
+
?? activeState.owner_omx_session_id
|
|
6434
|
+
?? activeState.codex_session_id
|
|
6435
|
+
?? activeState.owner_codex_session_id).trim();
|
|
6436
|
+
if (activeSessionId && activeSessionId !== sessionId)
|
|
6437
|
+
return false;
|
|
6438
|
+
const mode = safeString(payload.mode).trim().toLowerCase();
|
|
6439
|
+
const phase = safeString(payload.current_phase ?? payload.currentPhase).trim().toLowerCase();
|
|
6440
|
+
const payloadSessionId = safeString(payload.session_id).trim();
|
|
6441
|
+
if (!hasOnlyFinishedExplicitOutcomes(payload))
|
|
6442
|
+
return false;
|
|
6443
|
+
return mode === "deep-interview"
|
|
6444
|
+
&& payload.active === false
|
|
6445
|
+
&& phase === "complete"
|
|
6446
|
+
&& payloadSessionId === sessionId
|
|
6447
|
+
&& inferTerminalLifecycleOutcome(payload, { includeQuestionEnforcement: false }) === "finished";
|
|
6448
|
+
}
|
|
6449
|
+
function isAllowedDeepInterviewTerminalStateWriteCommand(cwd, command, activeState, sessionId) {
|
|
6450
|
+
const rawWords = tokenizeShellWords(normalizeShellLineContinuations(command).trim());
|
|
6451
|
+
if (rawWords[0] !== "omx")
|
|
6452
|
+
return false;
|
|
6453
|
+
const canonicalCommand = canonicalizeOmxStateTransportCommand(command);
|
|
6454
|
+
if (hasUnquotedShellControlOrRedirection(command))
|
|
6455
|
+
return false;
|
|
6456
|
+
if (hasUnsafeUnquotedHeredocExpansion(canonicalCommand))
|
|
6457
|
+
return false;
|
|
6458
|
+
if (hasUnquotedShellSubstitution(canonicalCommand))
|
|
6459
|
+
return false;
|
|
6460
|
+
if (splitStateScanSegments(canonicalCommand).length !== 1)
|
|
6461
|
+
return false;
|
|
6462
|
+
if (sourcesFileWrittenEarlierInSameCommand(cwd, canonicalCommand))
|
|
6463
|
+
return false;
|
|
6464
|
+
if (findUnquotedOmxStateCommandIndexes(canonicalCommand, "clear").length > 0)
|
|
6465
|
+
return false;
|
|
6466
|
+
if (hasDynamicNestedShellExecution(canonicalCommand))
|
|
6467
|
+
return false;
|
|
6468
|
+
if (extractDeepInterviewCommandWriteTargets(command).length > 0)
|
|
6469
|
+
return false;
|
|
6470
|
+
const operations = collectOmxStateCommandOperations(command, "write");
|
|
6471
|
+
if (operations.length !== 1)
|
|
6472
|
+
return false;
|
|
6473
|
+
const operation = operations[0];
|
|
6474
|
+
if (!operation || operation.nested || operation.commandPrefix.trim() || hasPriorExecutableCommand(operation.prefix))
|
|
6475
|
+
return false;
|
|
6476
|
+
const inlineInputCount = operation.args.filter((arg) => arg === "--input" || arg.startsWith("--input=")).length;
|
|
6477
|
+
if (inlineInputCount !== 1 || operation.args.some((arg) => arg === "--input-file" || arg.startsWith("--input-file=")))
|
|
6478
|
+
return false;
|
|
6479
|
+
const inlineInput = readStateWriteFlagValue(operation.args, "--input");
|
|
6480
|
+
let rawPayload = null;
|
|
6481
|
+
try {
|
|
6482
|
+
rawPayload = inlineInput ? safeObject(JSON.parse(inlineInput)) : null;
|
|
6483
|
+
}
|
|
6484
|
+
catch {
|
|
6485
|
+
rawPayload = null;
|
|
6486
|
+
}
|
|
6487
|
+
const nestedState = safeObject(rawPayload?.state);
|
|
6488
|
+
if (!rawPayload
|
|
6489
|
+
|| "workingDirectory" in rawPayload
|
|
6490
|
+
|| !suppliedSessionAliasesMatch(rawPayload, sessionId)
|
|
6491
|
+
|| !hasOnlyFinishedExplicitOutcomes(rawPayload)
|
|
6492
|
+
|| (nestedState && ("mode" in nestedState
|
|
6493
|
+
|| "session_id" in nestedState
|
|
6494
|
+
|| "workingDirectory" in nestedState
|
|
6495
|
+
|| "active" in nestedState
|
|
6496
|
+
|| "current_phase" in nestedState
|
|
6497
|
+
|| "currentPhase" in nestedState
|
|
6498
|
+
|| !suppliedSessionAliasesMatch(nestedState, sessionId)
|
|
6499
|
+
|| !hasOnlyFinishedExplicitOutcomes(nestedState))))
|
|
6500
|
+
return false;
|
|
6501
|
+
const payload = readStateWriteInputPayload(cwd, canonicalCommand, command);
|
|
6502
|
+
return payload ? isCompleteDeepInterviewTerminalWritePayload(payload, activeState, sessionId) : false;
|
|
6503
|
+
}
|
|
6253
6504
|
function isAllowedRalplanTerminalStateWriteCommand(cwd, command, activeState, sessionId) {
|
|
6254
6505
|
const canonicalCommand = canonicalizeOmxStateTransportCommand(command);
|
|
6255
6506
|
if (hasUnsafeUnquotedHeredocExpansion(canonicalCommand))
|
|
@@ -6295,13 +6546,56 @@ function commandEndsPlanningPhase(cwd, command) {
|
|
|
6295
6546
|
const payload = readStateWriteInputPayload(cwd, canonicalCommand, command);
|
|
6296
6547
|
return payload ? isPlanningPhaseDeactivationPayload(payload) : true;
|
|
6297
6548
|
}
|
|
6298
|
-
function isAllowedDeepInterviewBashWrite(cwd, command) {
|
|
6549
|
+
function isAllowedDeepInterviewBashWrite(cwd, command, activeState, sessionId = "") {
|
|
6550
|
+
const stateWriteOperations = collectOmxStateCommandOperations(command, "write");
|
|
6551
|
+
const hasUnsafeRuntimeStateWrite = (words) => {
|
|
6552
|
+
const stateWordIndex = words.indexOf("state");
|
|
6553
|
+
const writeWordIndex = stateWordIndex >= 0 ? words.indexOf("write", stateWordIndex + 1) : -1;
|
|
6554
|
+
if (writeWordIndex <= stateWordIndex)
|
|
6555
|
+
return false;
|
|
6556
|
+
const hasRuntimeBeforeState = words.slice(0, stateWordIndex).some((word) => {
|
|
6557
|
+
const base = shellWordBaseName(word);
|
|
6558
|
+
return isNodeInterpreterCommandWord(base) || base === "bun" || base === "tsx";
|
|
6559
|
+
});
|
|
6560
|
+
if (!hasRuntimeBeforeState)
|
|
6561
|
+
return false;
|
|
6562
|
+
const inlineInput = readStateWriteFlagValue(words, "--input");
|
|
6563
|
+
let payload = null;
|
|
6564
|
+
try {
|
|
6565
|
+
const parsed = inlineInput ? safeObject(JSON.parse(inlineInput)) : null;
|
|
6566
|
+
const modeOverride = readStateWriteFlagValue(words, "--mode");
|
|
6567
|
+
payload = parsed
|
|
6568
|
+
? normalizeStateWriteClassificationPayload(modeOverride ? { ...parsed, mode: modeOverride } : parsed)
|
|
6569
|
+
: null;
|
|
6570
|
+
}
|
|
6571
|
+
catch {
|
|
6572
|
+
payload = null;
|
|
6573
|
+
}
|
|
6574
|
+
return (!payload && stateWriteOperations.length === 0)
|
|
6575
|
+
|| Boolean(payload && (safeString(payload.mode).trim().toLowerCase() !== "deep-interview"
|
|
6576
|
+
|| isPlanningPhaseDeactivationPayload(payload)));
|
|
6577
|
+
};
|
|
6578
|
+
const rawCommand = normalizeShellLineContinuations(command).trim();
|
|
6579
|
+
if ([rawCommand, canonicalizeOmxStateTransportCommand(rawCommand)]
|
|
6580
|
+
.some((candidate) => hasUnsafeRuntimeStateWrite(tokenizeShellWords(candidate))))
|
|
6581
|
+
return false;
|
|
6582
|
+
if (stateWriteOperations.some((operation) => operation.nested))
|
|
6583
|
+
return false;
|
|
6299
6584
|
if (isAllowedDeepInterviewRalplanHandoffCommand(cwd, command))
|
|
6300
6585
|
return true;
|
|
6301
6586
|
if (hasDeepInterviewRalplanHandoffStateMutation(cwd, command))
|
|
6302
6587
|
return false;
|
|
6303
|
-
if (commandEndsPlanningPhase(cwd, command))
|
|
6304
|
-
return
|
|
6588
|
+
if (commandEndsPlanningPhase(cwd, command)) {
|
|
6589
|
+
return activeState
|
|
6590
|
+
? isAllowedDeepInterviewTerminalStateWriteCommand(cwd, command, activeState, sessionId)
|
|
6591
|
+
: false;
|
|
6592
|
+
}
|
|
6593
|
+
if (stateWriteOperations.length > 0) {
|
|
6594
|
+
const canonicalCommand = canonicalizeOmxStateTransportCommand(command);
|
|
6595
|
+
const payload = readStateWriteInputPayload(cwd, canonicalCommand, command);
|
|
6596
|
+
if (!payload || safeString(payload.mode).trim().toLowerCase() !== "deep-interview")
|
|
6597
|
+
return false;
|
|
6598
|
+
}
|
|
6305
6599
|
if (commandHasUntargetedPlanningForbiddenIntent(command))
|
|
6306
6600
|
return false;
|
|
6307
6601
|
if (firstPlanningTmpScriptExecutionTarget(cwd, command))
|
|
@@ -6324,12 +6618,10 @@ async function readActiveDeepInterviewStateForPreToolUse(cwd, stateDir, sessionI
|
|
|
6324
6618
|
const modeState = sessionId
|
|
6325
6619
|
? await readStopSessionPinnedState("deep-interview-state.json", cwd, sessionId, stateDir)
|
|
6326
6620
|
: await readJsonIfExists(join(stateDir, "deep-interview-state.json"));
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
return modeState;
|
|
6332
|
-
}
|
|
6621
|
+
const hasActiveDeepInterviewSkill = listActiveSkills(canonicalState).some((entry) => (entry.skill === "deep-interview"
|
|
6622
|
+
&& matchesSkillStopContext(entry, canonicalState, sessionId, threadId)));
|
|
6623
|
+
if (hasActiveDeepInterviewSkill && modeState?.active === true)
|
|
6624
|
+
return modeState;
|
|
6333
6625
|
if (isInactiveCompletedDeepInterviewPhase(modeState))
|
|
6334
6626
|
return null;
|
|
6335
6627
|
const autopilotState = sessionId
|
|
@@ -6547,7 +6839,7 @@ async function buildDeepInterviewPreToolUseBoundaryOutput(payload, cwd, stateDir
|
|
|
6547
6839
|
let blocked = false;
|
|
6548
6840
|
let blockedDetail = "implementation/write tools are blocked until an explicit handoff workflow is activated";
|
|
6549
6841
|
if (toolName === "Bash") {
|
|
6550
|
-
blocked = !isAllowedDeepInterviewBashWrite(cwd, command);
|
|
6842
|
+
blocked = !isAllowedDeepInterviewBashWrite(cwd, command, activeState, sessionId);
|
|
6551
6843
|
if (blocked) {
|
|
6552
6844
|
blockedDetail = buildDeepInterviewBashBlockedDetail(cwd, command);
|
|
6553
6845
|
}
|
|
@@ -6661,6 +6953,11 @@ async function hasTrustedTypedSubagentProvenanceForPreToolUse(payload, cwd, stat
|
|
|
6661
6953
|
if (!session)
|
|
6662
6954
|
return false;
|
|
6663
6955
|
const payloadThreadId = readPayloadThreadId(payload);
|
|
6956
|
+
const trackedPayloadThread = payloadThreadId ? session.threads[payloadThreadId] : undefined;
|
|
6957
|
+
const hasTrackedAdaptedTypedRole = payloadThreadId !== ""
|
|
6958
|
+
&& isTrustedSubagentThread(session, payloadThreadId)
|
|
6959
|
+
&& trackedPayloadThread?.provenance_kind === OMX_ADAPTED_PROVENANCE
|
|
6960
|
+
&& resolveInstalledRoleName(trackedPayloadThread.role ?? "") !== null;
|
|
6664
6961
|
// Resolve the Main-root leader THREAD identity from the tracker's leader_thread_id
|
|
6665
6962
|
// plus the canonical session's native_session_id (the leader's native thread). Only
|
|
6666
6963
|
// genuine leader-thread identifiers may anchor the leader: owner_*_session_id are
|
|
@@ -6693,9 +6990,11 @@ async function hasTrustedTypedSubagentProvenanceForPreToolUse(payload, cwd, stat
|
|
|
6693
6990
|
return false;
|
|
6694
6991
|
// Planning boundary guards (ralplan, deep-interview) still require a recognized typed
|
|
6695
6992
|
// agent role, so an untyped collaboration.spawn_agent child cannot write before an
|
|
6696
|
-
// execution handoff/approval.
|
|
6697
|
-
//
|
|
6698
|
-
if (options.allowUntypedProvenance !== true
|
|
6993
|
+
// execution handoff/approval. A tracker-recorded OMX-adapted child is the equivalent
|
|
6994
|
+
// of a typed role only when its own persisted role is installed and validated.
|
|
6995
|
+
if (options.allowUntypedProvenance !== true
|
|
6996
|
+
&& !isTypedAgentRolePayload(payload)
|
|
6997
|
+
&& !hasTrackedAdaptedTypedRole) {
|
|
6699
6998
|
return false;
|
|
6700
6999
|
}
|
|
6701
7000
|
// Tracker-backed provenance: the payload's own thread is a recorded, non-leader
|
|
@@ -7565,6 +7864,10 @@ export async function buildConductorPreToolUseWriteGuardOutput(payload, cwd, sta
|
|
|
7565
7864
|
const nativeSubagentSupport = resolveNativeSubagentSupportStatus({
|
|
7566
7865
|
payload,
|
|
7567
7866
|
persistedSupportBlocker: await readJsonIfExists(nativeSubagentSupportBlockerPath(stateDir)),
|
|
7867
|
+
persistedRoleRoutingMarker: readRoleRoutingMarker(stateDir, {
|
|
7868
|
+
cwd,
|
|
7869
|
+
sessionId: resolvedSessionId || readPayloadSessionId(payload),
|
|
7870
|
+
}),
|
|
7568
7871
|
persistedCapacityBlocker: await readJsonIfExists(nativeSubagentCapacityBlockerPath(stateDir)),
|
|
7569
7872
|
cwd,
|
|
7570
7873
|
sessionId: resolvedSessionId || readPayloadSessionId(payload),
|
|
@@ -7598,6 +7901,9 @@ export async function buildConductorPreToolUseWriteGuardOutput(payload, cwd, sta
|
|
|
7598
7901
|
const unsupportedNativeGuidance = isUnsupportedNativeSubagentEvidence(nativeSubagentSupport)
|
|
7599
7902
|
? ` ${buildUnsupportedNativeSubagentGuidance(nativeSubagentSupport)} Treat the active conductor workflow as blocked/cancelled for native delegation recovery; do not call multi_agent_v1.close_agent.`
|
|
7600
7903
|
: "";
|
|
7904
|
+
const roleRoutingUnavailableGuidance = isRoleRoutingUnavailableEvidence(nativeSubagentSupport)
|
|
7905
|
+
? ` ${buildRoleRoutingUnavailableGuidance(nativeSubagentSupport)}`
|
|
7906
|
+
: "";
|
|
7601
7907
|
return {
|
|
7602
7908
|
decision: "block",
|
|
7603
7909
|
reason: `Main-root Conductor mode is active (${activeState.mode} phase: ${formatPhase(activeState.phase, "active")}); direct plan/code writes are blocked and must be delegated; ${blockedDetail}.`,
|
|
@@ -7607,6 +7913,7 @@ export async function buildConductorPreToolUseWriteGuardOutput(payload, cwd, sta
|
|
|
7607
7913
|
+ "Use specialized agents for source edits and plan/spec authorship. "
|
|
7608
7914
|
+ `Main-root Conductor may write only orchestration metadata/transport/ledger artifacts under ${CONDUCTOR_ORCHESTRATION_METADATA_PREFIXES.join(", ")}; path location alone is not authorization for substantive deliverables. `
|
|
7609
7915
|
+ unsupportedNativeGuidance
|
|
7916
|
+
+ roleRoutingUnavailableGuidance
|
|
7610
7917
|
+ " Autopilot rework and typed subagent/worker lanes are exempt from this guard.",
|
|
7611
7918
|
},
|
|
7612
7919
|
};
|
|
@@ -8424,7 +8731,8 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
8424
8731
|
return null;
|
|
8425
8732
|
}
|
|
8426
8733
|
const sessionId = readPayloadSessionId(payload);
|
|
8427
|
-
const canonicalSessionId =
|
|
8734
|
+
const canonicalSessionId = options.canonicalSessionId
|
|
8735
|
+
?? await resolveInternalSessionIdForPayload(cwd, sessionId);
|
|
8428
8736
|
const threadId = readPayloadThreadId(payload);
|
|
8429
8737
|
const suppressParentWorkflowStop = shouldSuppressParentWorkflowStopForSideConversation(payload);
|
|
8430
8738
|
if (canonicalSessionId) {
|
|
@@ -8468,7 +8776,7 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
8468
8776
|
}
|
|
8469
8777
|
const ralphState = options.skipRalphStopBlock === true
|
|
8470
8778
|
? null
|
|
8471
|
-
: await readActiveRalphState(cwd, stateDir, canonicalSessionId, ralphOwnerContext);
|
|
8779
|
+
: await readActiveRalphState(cwd, stateDir, sessionId || canonicalSessionId, ralphOwnerContext);
|
|
8472
8780
|
if (!ralphState) {
|
|
8473
8781
|
const autoresearchState = await readActiveAutoresearchState(cwd, canonicalSessionId);
|
|
8474
8782
|
if (autoresearchState) {
|
|
@@ -8549,7 +8857,8 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
8549
8857
|
return ordinaryNoProgressOutput;
|
|
8550
8858
|
const autoNudgeConfig = await loadAutoNudgeConfig();
|
|
8551
8859
|
const autoNudgePhase = await readStopAutoNudgePhase(cwd, stateDir, canonicalSessionId, threadId);
|
|
8552
|
-
if (
|
|
8860
|
+
if (options.skipAutoNudge !== true
|
|
8861
|
+
&& autoNudgeConfig.enabled
|
|
8553
8862
|
&& detectNativeStopStallPattern(lastAssistantMessage, autoNudgeConfig.patterns, autoNudgePhase)) {
|
|
8554
8863
|
const effectiveResponse = resolveEffectiveAutoNudgeResponse(autoNudgeConfig.response);
|
|
8555
8864
|
return await returnPersistentStopBlock(payload, stateDir, "auto-nudge", lastAssistantMessage, {
|
|
@@ -8583,10 +8892,37 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
8583
8892
|
systemMessage,
|
|
8584
8893
|
}, canonicalSessionId);
|
|
8585
8894
|
}
|
|
8895
|
+
async function preflightNativePromptTarget(stateDir, context) {
|
|
8896
|
+
if (context.status !== "authorized")
|
|
8897
|
+
return context;
|
|
8898
|
+
const targetDir = join(stateDir, "sessions", context.authorization.targetSessionId);
|
|
8899
|
+
const evidence = [];
|
|
8900
|
+
let filenames;
|
|
8901
|
+
try {
|
|
8902
|
+
filenames = await readdir(targetDir);
|
|
8903
|
+
}
|
|
8904
|
+
catch (error) {
|
|
8905
|
+
if (error.code === "ENOENT")
|
|
8906
|
+
return context;
|
|
8907
|
+
return preflightSelectedTargetOwner(context, [{ ownerCodexSessionId: {} }], "native", new Date().toISOString());
|
|
8908
|
+
}
|
|
8909
|
+
for (const filename of filenames) {
|
|
8910
|
+
if (!filename.endsWith("-state.json") && filename !== SKILL_ACTIVE_STATE_FILE)
|
|
8911
|
+
continue;
|
|
8912
|
+
try {
|
|
8913
|
+
const value = JSON.parse(await readFile(join(targetDir, filename), "utf8"));
|
|
8914
|
+
evidence.push(...extractSelectedTargetOwnerEvidence(value));
|
|
8915
|
+
}
|
|
8916
|
+
catch {
|
|
8917
|
+
evidence.push({ ownerCodexSessionId: {} });
|
|
8918
|
+
}
|
|
8919
|
+
}
|
|
8920
|
+
return preflightSelectedTargetOwner(context, evidence, "native", new Date().toISOString());
|
|
8921
|
+
}
|
|
8586
8922
|
export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
8587
8923
|
const hookEventName = readHookEventName(payload);
|
|
8588
8924
|
const cwd = options.cwd ?? (safeString(payload.cwd).trim() || process.cwd());
|
|
8589
|
-
if (hookEventName === "
|
|
8925
|
+
if (hookEventName === "PostCompact" && process.env.OMX_NATIVE_HOOK_DOCTOR_SMOKE === "1") {
|
|
8590
8926
|
return {
|
|
8591
8927
|
hookEventName,
|
|
8592
8928
|
omxEventName: mapCodexHookEventToOmxEvent(hookEventName),
|
|
@@ -8594,22 +8930,70 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8594
8930
|
outputJson: null,
|
|
8595
8931
|
};
|
|
8596
8932
|
}
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
const stateDir = getBaseStateDir(cwd);
|
|
8600
|
-
if (hookEventName !== "Stop") {
|
|
8601
|
-
await mkdir(stateDir, { recursive: true });
|
|
8933
|
+
try {
|
|
8934
|
+
recoverAdaptedRoleBindings(cwd, getBaseStateDir(cwd));
|
|
8602
8935
|
}
|
|
8936
|
+
catch {
|
|
8937
|
+
// Recovery is best-effort for unrelated hook events.
|
|
8938
|
+
}
|
|
8939
|
+
if (hookEventName === "Stop" && !hasNativeStopRuntimeSurface(cwd)) {
|
|
8940
|
+
return {
|
|
8941
|
+
hookEventName,
|
|
8942
|
+
omxEventName: mapCodexHookEventToOmxEvent(hookEventName),
|
|
8943
|
+
skillState: null,
|
|
8944
|
+
outputJson: null,
|
|
8945
|
+
};
|
|
8946
|
+
}
|
|
8947
|
+
// Native hooks must use the exact pointer root selected for this dispatch.
|
|
8948
|
+
const pointerContext = resolveSessionPointerContext(cwd);
|
|
8949
|
+
const stateDir = pointerContext.baseStateDir;
|
|
8603
8950
|
const omxEventName = mapCodexHookEventToOmxEvent(hookEventName);
|
|
8604
8951
|
let skillState = null;
|
|
8605
8952
|
let triageAdditionalContext = null;
|
|
8606
8953
|
let goalWorkflowAdditionalContext = null;
|
|
8607
8954
|
let ultragoalSteeringAdditionalContext = null;
|
|
8955
|
+
let promptClassification = null;
|
|
8608
8956
|
const nativeSessionId = safeString(payload.session_id ?? payload.sessionId).trim();
|
|
8609
8957
|
const threadId = safeString(payload.thread_id ?? payload.threadId).trim();
|
|
8610
8958
|
const turnId = safeString(payload.turn_id ?? payload.turnId).trim();
|
|
8611
|
-
const
|
|
8959
|
+
const pointer = await readSessionPointer(pointerContext);
|
|
8960
|
+
const currentSessionState = pointer.status === "usable" ? pointer.state ?? null : null;
|
|
8961
|
+
let promptTurnContext = hookEventName === "UserPromptSubmit"
|
|
8962
|
+
? evaluateResolvedPromptTurn({
|
|
8963
|
+
producer: "native",
|
|
8964
|
+
payloadSessionId: payload.session_id ?? payload.sessionId,
|
|
8965
|
+
ownerEnvSessionId: undefined,
|
|
8966
|
+
selectedPointer: pointer,
|
|
8967
|
+
threadFacts: await readNativePromptThreadFacts(cwd, nativeSessionId, threadId, currentSessionState),
|
|
8968
|
+
nowIso: new Date().toISOString(),
|
|
8969
|
+
})
|
|
8970
|
+
: null;
|
|
8971
|
+
if (promptTurnContext) {
|
|
8972
|
+
promptTurnContext = await preflightNativePromptTarget(stateDir, promptTurnContext);
|
|
8973
|
+
}
|
|
8974
|
+
if (promptTurnContext?.status === "rejected") {
|
|
8975
|
+
await appendPromptSessionProvenanceRejection(pointerContext, promptTurnContext.diagnostic).catch(() => { });
|
|
8976
|
+
return { hookEventName, omxEventName, skillState: null, outputJson: null };
|
|
8977
|
+
}
|
|
8978
|
+
if (promptTurnContext?.status === "suppressed-target-child") {
|
|
8979
|
+
return { hookEventName, omxEventName, skillState: null, outputJson: null };
|
|
8980
|
+
}
|
|
8981
|
+
if (hookEventName !== "Stop") {
|
|
8982
|
+
await mkdir(stateDir, { recursive: true });
|
|
8983
|
+
}
|
|
8984
|
+
let allowImplicitSessionSideEffects = pointer.status === "usable" || pointer.status === "absent" || promptTurnContext?.status === "authorized";
|
|
8985
|
+
let stopAuthorizationFailure = allowImplicitSessionSideEffects
|
|
8986
|
+
? null
|
|
8987
|
+
: {
|
|
8988
|
+
stopReason: "session_pointer_unusable",
|
|
8989
|
+
reason: `OMX cannot authorize Stop while the selected session pointer is ${pointer.status}; repair the pointer evidence before continuing.`,
|
|
8990
|
+
};
|
|
8612
8991
|
let canonicalSessionId = safeString(currentSessionState?.session_id).trim();
|
|
8992
|
+
if (promptTurnContext?.status === "authorized") {
|
|
8993
|
+
canonicalSessionId = promptTurnContext.authorization.targetSessionId;
|
|
8994
|
+
}
|
|
8995
|
+
const allowPromptGlobalSideEffects = promptTurnContext?.status !== "authorized"
|
|
8996
|
+
|| promptTurnContext.authorization.globalSideEffects === "allow";
|
|
8613
8997
|
let resolvedNativeSessionId = nativeSessionId;
|
|
8614
8998
|
let skipCanonicalSessionStartContext = false;
|
|
8615
8999
|
let isSubagentSessionStart = false;
|
|
@@ -8648,20 +9032,58 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8648
9032
|
}
|
|
8649
9033
|
}
|
|
8650
9034
|
else {
|
|
8651
|
-
const
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
9035
|
+
const ownerOmxSessionId = await resolveVerifiedOwnerOmxSessionId();
|
|
9036
|
+
try {
|
|
9037
|
+
const sessionState = await reconcileNativeSessionStart(cwd, nativeSessionId, {
|
|
9038
|
+
context: pointerContext,
|
|
9039
|
+
pid: options.sessionOwnerPid ?? resolveSessionOwnerPid(payload),
|
|
9040
|
+
...(ownerOmxSessionId
|
|
9041
|
+
? { ownerOmxSessionId, ownerAliasVerified: true }
|
|
9042
|
+
: {}),
|
|
9043
|
+
});
|
|
9044
|
+
canonicalSessionId = safeString(sessionState.session_id).trim();
|
|
9045
|
+
resolvedNativeSessionId = safeString(sessionState.native_session_id).trim() || nativeSessionId;
|
|
9046
|
+
allowImplicitSessionSideEffects = true;
|
|
9047
|
+
stopAuthorizationFailure = null;
|
|
9048
|
+
// #3181: leader attestation is intentionally NOT performed here. This branch is
|
|
9049
|
+
// reached whenever readNativeSubagentSessionStartMetadata() returns null, which
|
|
9050
|
+
// conflates a genuine root start with an unreadable/malformed child transcript, so
|
|
9051
|
+
// it cannot positively classify a leader (a legitimate leader may also carry no
|
|
9052
|
+
// transcript). Leader attestation is performed only on the strictly-gated fresh
|
|
9053
|
+
// leader PreToolUse path below, which fires before the first in-turn role-intent
|
|
9054
|
+
// write. Fail closed here rather than risk a false-leader adoption.
|
|
9055
|
+
}
|
|
9056
|
+
catch (error) {
|
|
9057
|
+
if (!isSessionPointerLaunchAbort(error))
|
|
9058
|
+
throw error;
|
|
9059
|
+
canonicalSessionId = "";
|
|
9060
|
+
resolvedNativeSessionId = nativeSessionId;
|
|
9061
|
+
skipCanonicalSessionStartContext = true;
|
|
9062
|
+
allowImplicitSessionSideEffects = false;
|
|
9063
|
+
stopAuthorizationFailure = {
|
|
9064
|
+
stopReason: "session_pointer_unusable",
|
|
9065
|
+
reason: `OMX cannot authorize Stop while the selected session pointer is ${pointer.status}; repair the pointer evidence before continuing.`,
|
|
9066
|
+
};
|
|
9067
|
+
}
|
|
8656
9068
|
}
|
|
8657
9069
|
}
|
|
8658
9070
|
else if (!canonicalSessionId) {
|
|
8659
9071
|
canonicalSessionId = safeString(currentSessionState?.session_id).trim();
|
|
8660
9072
|
}
|
|
8661
9073
|
if (hookEventName === "Stop") {
|
|
8662
|
-
const
|
|
8663
|
-
const stopCanonicalSessionId = await resolveInternalSessionIdForPayload(cwd,
|
|
8664
|
-
if (stopCanonicalSessionId) {
|
|
9074
|
+
const stopPayloadSessionId = readPayloadSessionId(payload);
|
|
9075
|
+
const stopCanonicalSessionId = await resolveInternalSessionIdForPayload(cwd, stopPayloadSessionId, undefined, currentSessionState, pointer.status === "absent");
|
|
9076
|
+
if (stopPayloadSessionId && !stopCanonicalSessionId) {
|
|
9077
|
+
canonicalSessionId = "";
|
|
9078
|
+
allowImplicitSessionSideEffects = false;
|
|
9079
|
+
if (!stopAuthorizationFailure) {
|
|
9080
|
+
stopAuthorizationFailure = {
|
|
9081
|
+
stopReason: "session_scope_unmatched",
|
|
9082
|
+
reason: `OMX cannot authorize Stop for unmatched session id ${stopPayloadSessionId}; the selected session pointer remains authoritative.`,
|
|
9083
|
+
};
|
|
9084
|
+
}
|
|
9085
|
+
}
|
|
9086
|
+
else if (stopCanonicalSessionId) {
|
|
8665
9087
|
canonicalSessionId = stopCanonicalSessionId;
|
|
8666
9088
|
}
|
|
8667
9089
|
if (canonicalSessionId && safeString(currentSessionState?.session_id).trim() === canonicalSessionId) {
|
|
@@ -8669,8 +9091,8 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8669
9091
|
safeString(currentSessionState?.native_session_id).trim() || resolvedNativeSessionId;
|
|
8670
9092
|
}
|
|
8671
9093
|
}
|
|
8672
|
-
|
|
8673
|
-
|
|
9094
|
+
let eventSessionId = canonicalSessionId || nativeSessionId || undefined;
|
|
9095
|
+
let sessionIdForState = canonicalSessionId || null;
|
|
8674
9096
|
let outputJson = null;
|
|
8675
9097
|
const typedAgentRolePayload = isTypedAgentRolePayload(payload);
|
|
8676
9098
|
const isSubagentPromptSubmit = hookEventName === "UserPromptSubmit"
|
|
@@ -8685,27 +9107,74 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8685
9107
|
? safeString(currentSessionState?.native_session_id).trim()
|
|
8686
9108
|
: "")))).some(Boolean)
|
|
8687
9109
|
: false;
|
|
9110
|
+
if (isSubagentStop && stopAuthorizationFailure?.stopReason === "session_scope_unmatched") {
|
|
9111
|
+
canonicalSessionId = normalizeSessionId(readPayloadSessionId(payload)) ?? "";
|
|
9112
|
+
allowImplicitSessionSideEffects = true;
|
|
9113
|
+
stopAuthorizationFailure = null;
|
|
9114
|
+
eventSessionId = canonicalSessionId || nativeSessionId || undefined;
|
|
9115
|
+
sessionIdForState = canonicalSessionId || null;
|
|
9116
|
+
}
|
|
8688
9117
|
const suppressNoisySubagentLifecycleDispatch = (isSubagentSessionStart || isSubagentStop)
|
|
8689
9118
|
&& shouldSuppressSubagentLifecycleHookDispatch();
|
|
8690
9119
|
if (hookEventName === "UserPromptSubmit") {
|
|
8691
9120
|
const prompt = readPromptText(payload);
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
9121
|
+
if (!isSubagentPromptSubmit) {
|
|
9122
|
+
promptClassification = classifyKeywordInput(prompt);
|
|
9123
|
+
}
|
|
9124
|
+
goalWorkflowAdditionalContext = allowPromptGlobalSideEffects
|
|
9125
|
+
? await buildCompletedGoalCleanupPromptWarning(cwd, prompt).catch(() => null)
|
|
9126
|
+
?? await buildGoalWorkflowReconciliationPromptWarning(cwd, prompt).catch(() => null)
|
|
9127
|
+
: null;
|
|
9128
|
+
ultragoalSteeringAdditionalContext = prompt && !isSubagentPromptSubmit && allowImplicitSessionSideEffects && allowPromptGlobalSideEffects
|
|
8695
9129
|
? await applyUserPromptUltragoalSteering(cwd, prompt).catch((error) => `OMX native UserPromptSubmit rejected bounded .omx/ultragoal steering for G002-cli-and-prompt-submit-bridge: ${error instanceof Error ? error.message : String(error)}`)
|
|
8696
9130
|
: null;
|
|
8697
|
-
|
|
8698
|
-
|
|
9131
|
+
let suppressActivationSeeding = !allowImplicitSessionSideEffects;
|
|
9132
|
+
if (promptTurnContext?.status === "authorized") {
|
|
9133
|
+
sessionIdForState = promptTurnContext.authorization.targetSessionId;
|
|
9134
|
+
}
|
|
9135
|
+
else if (prompt && !isSubagentPromptSubmit && allowImplicitSessionSideEffects) {
|
|
9136
|
+
const rawHookSessionId = canonicalSessionId || nativeSessionId;
|
|
9137
|
+
const normalizedHookSessionId = normalizeSessionId(rawHookSessionId);
|
|
9138
|
+
const explicitHookSessionId = currentSessionState ? undefined : normalizedHookSessionId;
|
|
9139
|
+
if (rawHookSessionId && !normalizedHookSessionId) {
|
|
9140
|
+
suppressActivationSeeding = true;
|
|
9141
|
+
}
|
|
9142
|
+
else {
|
|
9143
|
+
try {
|
|
9144
|
+
const writableScope = await resolveWritableStateScope(cwd, explicitHookSessionId);
|
|
9145
|
+
sessionIdForState = writableScope.sessionId ?? null;
|
|
9146
|
+
}
|
|
9147
|
+
catch (error) {
|
|
9148
|
+
if (!isImplicitWritableScopeFailure(error))
|
|
9149
|
+
throw error;
|
|
9150
|
+
suppressActivationSeeding = true;
|
|
9151
|
+
}
|
|
9152
|
+
}
|
|
9153
|
+
}
|
|
9154
|
+
if (prompt && promptClassification && !isSubagentPromptSubmit && !suppressActivationSeeding) {
|
|
9155
|
+
skillState = buildNativeOutsideTmuxTeamPromptBlockState(promptClassification, cwd, payload, sessionIdForState || undefined, threadId || undefined, turnId || undefined) ?? await recordSkillActivation({
|
|
8699
9156
|
stateDir,
|
|
8700
9157
|
sourceCwd: cwd,
|
|
8701
9158
|
text: prompt,
|
|
8702
|
-
|
|
9159
|
+
classification: promptClassification,
|
|
9160
|
+
allowSecondaryTeam: !isNativeOutsideTmuxUserPrompt(cwd, payload, sessionIdForState || undefined),
|
|
9161
|
+
sessionId: sessionIdForState || undefined,
|
|
8703
9162
|
threadId,
|
|
8704
9163
|
turnId,
|
|
9164
|
+
resolvedPromptTurnContext: promptTurnContext ?? undefined,
|
|
9165
|
+
onProvenanceRejected: async (diagnostic) => {
|
|
9166
|
+
await appendPromptSessionProvenanceRejection(pointerContext, diagnostic).catch(() => { });
|
|
9167
|
+
},
|
|
8705
9168
|
});
|
|
8706
9169
|
}
|
|
8707
9170
|
// --- Triage classifier (advisory-only, non-keyword prompts) ---
|
|
8708
|
-
if (prompt
|
|
9171
|
+
if (prompt
|
|
9172
|
+
&& skillState === null
|
|
9173
|
+
&& !isSubagentPromptSubmit
|
|
9174
|
+
&& allowPromptGlobalSideEffects
|
|
9175
|
+
&& promptClassification?.reservedInput === null
|
|
9176
|
+
&& promptClassification.hasExplicitLikeInvocation === false
|
|
9177
|
+
&& promptClassification.matches.length === 0) {
|
|
8709
9178
|
try {
|
|
8710
9179
|
if (readTriageConfig().enabled) {
|
|
8711
9180
|
const normalized = prompt.trim().toLowerCase();
|
|
@@ -8734,7 +9203,9 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8734
9203
|
},
|
|
8735
9204
|
suppress_followup: true,
|
|
8736
9205
|
};
|
|
8737
|
-
|
|
9206
|
+
if (!suppressActivationSeeding) {
|
|
9207
|
+
writeTriageState({ cwd, sessionId: sessionIdForState || null, state: newState });
|
|
9208
|
+
}
|
|
8738
9209
|
}
|
|
8739
9210
|
else if (decision.lane === "LIGHT") {
|
|
8740
9211
|
if (decision.destination === "explore") {
|
|
@@ -8767,7 +9238,9 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8767
9238
|
},
|
|
8768
9239
|
suppress_followup: true,
|
|
8769
9240
|
};
|
|
8770
|
-
|
|
9241
|
+
if (!suppressActivationSeeding) {
|
|
9242
|
+
writeTriageState({ cwd, sessionId: sessionIdForState || null, state: newState });
|
|
9243
|
+
}
|
|
8771
9244
|
}
|
|
8772
9245
|
}
|
|
8773
9246
|
// lane === "PASS": no context, no state write
|
|
@@ -8782,14 +9255,14 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8782
9255
|
const skipHudReconcileForDoctorSmoke = process.env.OMX_NATIVE_HOOK_DOCTOR_SMOKE === "1";
|
|
8783
9256
|
const skipHudReconcileForTeamWorkerPane = !isSubagentPromptSubmit
|
|
8784
9257
|
&& await isConfirmedTeamWorkerPromptSubmitPane(cwd).catch(() => false);
|
|
8785
|
-
if (!skipHudReconcileForDoctorSmoke && !skipHudReconcileForTeamWorkerPane) {
|
|
9258
|
+
if (allowImplicitSessionSideEffects && allowPromptGlobalSideEffects && !skipHudReconcileForDoctorSmoke && !skipHudReconcileForTeamWorkerPane) {
|
|
8786
9259
|
const reconcileHudForPromptSubmitFn = options.reconcileHudForPromptSubmitFn ?? reconcileHudForPromptSubmit;
|
|
8787
9260
|
const hudSessionId = resolveHudReconcileSessionId(currentSessionState, canonicalSessionId, sessionIdForState);
|
|
8788
9261
|
const hudSessionIds = resolveHudReconcileSessionIds(currentSessionState, canonicalSessionId, sessionIdForState, nativeSessionId);
|
|
8789
9262
|
await reconcileHudForPromptSubmitFn(cwd, { sessionId: hudSessionId, sessionIds: hudSessionIds }).catch(() => { });
|
|
8790
9263
|
}
|
|
8791
9264
|
}
|
|
8792
|
-
if (omxEventName && !skipCanonicalSessionStartContext && !suppressNoisySubagentLifecycleDispatch) {
|
|
9265
|
+
if (omxEventName && allowImplicitSessionSideEffects && allowPromptGlobalSideEffects && !skipCanonicalSessionStartContext && !suppressNoisySubagentLifecycleDispatch) {
|
|
8793
9266
|
const baseContext = buildBaseContext(cwd, payload, hookEventName, canonicalSessionId);
|
|
8794
9267
|
if (resolvedNativeSessionId) {
|
|
8795
9268
|
baseContext.native_session_id = resolvedNativeSessionId;
|
|
@@ -8826,12 +9299,14 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8826
9299
|
})
|
|
8827
9300
|
: isSubagentPromptSubmit
|
|
8828
9301
|
? null
|
|
8829
|
-
:
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
9302
|
+
: promptClassification
|
|
9303
|
+
? [
|
|
9304
|
+
buildAdditionalContextMessage(promptClassification, skillState, cwd, payload),
|
|
9305
|
+
ultragoalSteeringAdditionalContext,
|
|
9306
|
+
goalWorkflowAdditionalContext,
|
|
9307
|
+
triageAdditionalContext,
|
|
9308
|
+
].filter((entry) => Boolean(entry)).join("\n\n") || null
|
|
9309
|
+
: null;
|
|
8835
9310
|
if (additionalContext) {
|
|
8836
9311
|
outputJson = {
|
|
8837
9312
|
hookSpecificOutput: {
|
|
@@ -8842,12 +9317,52 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8842
9317
|
}
|
|
8843
9318
|
}
|
|
8844
9319
|
else if (hookEventName === "PreToolUse") {
|
|
9320
|
+
// #3181 Phase-1 (PreToolUse): this hook fires before the shell tool call that runs
|
|
9321
|
+
// the first in-turn `omx ralplan role-intent write`. On a fresh App/outside-tmux
|
|
9322
|
+
// turn where SessionStart did not establish the pointer, reconcile the canonical
|
|
9323
|
+
// pointer and attest the leader here so the first command can bootstrap. Strictly
|
|
9324
|
+
// gated to a fresh (absent-pointer) LEADER turn: no canonical session yet, a present
|
|
9325
|
+
// native session id, a leader-shaped thread (absent or equal to the native session
|
|
9326
|
+
// id), and no subagent/typed-role provenance. Best-effort; never blocks PreToolUse.
|
|
9327
|
+
if (allowImplicitSessionSideEffects
|
|
9328
|
+
&& !canonicalSessionId
|
|
9329
|
+
&& nativeSessionId
|
|
9330
|
+
&& readPayloadAgentRole(payload) === ""
|
|
9331
|
+
&& !hasSubagentThreadSpawnProvenance(payload)) {
|
|
9332
|
+
const preToolUseLeaderThreadId = readPayloadThreadId(payload);
|
|
9333
|
+
if (preToolUseLeaderThreadId
|
|
9334
|
+
&& preToolUseLeaderThreadId === nativeSessionId
|
|
9335
|
+
&& !(await isThreadTrackedAsSubagent(cwd, nativeSessionId))) {
|
|
9336
|
+
try {
|
|
9337
|
+
const ownerOmxSessionId = await resolveVerifiedOwnerOmxSessionId();
|
|
9338
|
+
const sessionState = await reconcileNativeSessionStart(cwd, nativeSessionId, {
|
|
9339
|
+
context: pointerContext,
|
|
9340
|
+
pid: options.sessionOwnerPid ?? resolveSessionOwnerPid(payload),
|
|
9341
|
+
...(ownerOmxSessionId ? { ownerOmxSessionId, ownerAliasVerified: true } : {}),
|
|
9342
|
+
});
|
|
9343
|
+
const bootstrapSessionId = safeString(sessionState.session_id).trim();
|
|
9344
|
+
const bootstrapLeaderThreadId = safeString(sessionState.native_session_id).trim() || nativeSessionId;
|
|
9345
|
+
if (bootstrapSessionId && bootstrapLeaderThreadId) {
|
|
9346
|
+
canonicalSessionId = bootstrapSessionId;
|
|
9347
|
+
attestLeaderThread(cwd, {
|
|
9348
|
+
sessionId: bootstrapSessionId,
|
|
9349
|
+
leaderThreadId: bootstrapLeaderThreadId,
|
|
9350
|
+
source: 'native-pretooluse',
|
|
9351
|
+
});
|
|
9352
|
+
}
|
|
9353
|
+
}
|
|
9354
|
+
catch {
|
|
9355
|
+
// Best-effort bootstrap; PreToolUse must never fail on this.
|
|
9356
|
+
}
|
|
9357
|
+
}
|
|
9358
|
+
}
|
|
8845
9359
|
const payloadSessionId = readPayloadSessionId(payload);
|
|
8846
9360
|
const rootPointerConflict = await readLiveRootSessionPointerConflict(stateDir, payloadSessionId);
|
|
8847
9361
|
const preToolUseSessionId = payloadSessionId
|
|
8848
9362
|
? await resolveInternalSessionIdForPayload(cwd, payloadSessionId, stateDir)
|
|
8849
9363
|
: "";
|
|
8850
|
-
outputJson =
|
|
9364
|
+
outputJson = buildNativeUnknownRolePreToolUseOutput(payload)
|
|
9365
|
+
?? await buildDeepInterviewPreToolUseBoundaryOutput(payload, cwd, stateDir, preToolUseSessionId)
|
|
8851
9366
|
?? await buildRalplanPreToolUseBoundaryOutput(payload, cwd, stateDir, preToolUseSessionId)
|
|
8852
9367
|
?? await buildPlanningRootPointerConflictPreToolUseOutput(payload, cwd, stateDir, rootPointerConflict)
|
|
8853
9368
|
?? await buildConductorPreToolUseWriteGuardOutput(payload, cwd, stateDir, preToolUseSessionId)
|
|
@@ -8856,18 +9371,36 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
8856
9371
|
?? buildNativePreToolUseOutput(payload);
|
|
8857
9372
|
}
|
|
8858
9373
|
else if (hookEventName === "PostToolUse") {
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
9374
|
+
if (allowImplicitSessionSideEffects) {
|
|
9375
|
+
await recordNativeSubagentCapacityBlocker(cwd, stateDir, payload).catch(() => { });
|
|
9376
|
+
await recordNativeSubagentSupportBlocker(cwd, stateDir, payload).catch(() => { });
|
|
9377
|
+
if (detectMcpTransportFailure(payload)) {
|
|
9378
|
+
await markTeamTransportFailure(cwd, payload);
|
|
9379
|
+
}
|
|
9380
|
+
await handleTeamWorkerPostToolUseSuccess(payload, cwd);
|
|
8863
9381
|
}
|
|
8864
9382
|
outputJson = buildNativePostToolUseOutput(payload);
|
|
8865
|
-
await handleTeamWorkerPostToolUseSuccess(payload, cwd);
|
|
8866
9383
|
}
|
|
8867
9384
|
else if (hookEventName === "Stop") {
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
9385
|
+
if (allowImplicitSessionSideEffects) {
|
|
9386
|
+
outputJson = await buildStopHookOutput(payload, cwd, stateDir, {
|
|
9387
|
+
canonicalSessionId: canonicalSessionId || undefined,
|
|
9388
|
+
skipRalphStopBlock: isSubagentStop,
|
|
9389
|
+
skipAutoNudge: isSubagentStop,
|
|
9390
|
+
}) ?? await buildCompletedGoalCleanupStopOutput(payload, cwd);
|
|
9391
|
+
}
|
|
9392
|
+
else {
|
|
9393
|
+
const failure = stopAuthorizationFailure ?? {
|
|
9394
|
+
stopReason: "session_pointer_unusable",
|
|
9395
|
+
reason: "OMX cannot authorize Stop without a writable session authority.",
|
|
9396
|
+
};
|
|
9397
|
+
outputJson = {
|
|
9398
|
+
decision: "block",
|
|
9399
|
+
stopReason: failure.stopReason,
|
|
9400
|
+
reason: failure.reason,
|
|
9401
|
+
systemMessage: failure.reason,
|
|
9402
|
+
};
|
|
9403
|
+
}
|
|
8871
9404
|
}
|
|
8872
9405
|
return {
|
|
8873
9406
|
hookEventName,
|