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
package/dist/cli/doctor.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* omx doctor - Validate oh-my-codex installation
|
|
3
3
|
*/
|
|
4
|
+
import { recoverNativeHookClaimJournal } from "./native-hook-claim-journal.js";
|
|
4
5
|
import { constants, existsSync, readFileSync } from "fs";
|
|
5
|
-
import { access, chown, lstat, mkdtemp, readdir, readFile, rm } from "fs/promises";
|
|
6
|
+
import { access, chown, lstat, mkdtemp, readdir, readFile, rmdir, rm } from "fs/promises";
|
|
6
7
|
import { spawnSync } from "child_process";
|
|
7
|
-
import { basename, join, relative } from "path";
|
|
8
|
+
import { basename, dirname, join, relative } from "path";
|
|
8
9
|
import { tmpdir } from "os";
|
|
9
10
|
import { codexHome, codexConfigPath, codexPromptsDir, userSkillsDir, projectSkillsDir, omxStateDir, detectLegacySkillRootOverlap, codexAgentsDir, } from "../utils/paths.js";
|
|
10
11
|
import { classifySpawnError, spawnPlatformCommandSync, } from "../utils/platform-command.js";
|
|
@@ -13,7 +14,7 @@ import { parse as parseToml } from "@iarna/toml";
|
|
|
13
14
|
import { getBuiltinExploreHarnessUnsupportedReason, resolvePackagedExploreHarnessCommand, EXPLORE_BIN_ENV, } from "./explore.js";
|
|
14
15
|
import { getPackageRoot } from "../utils/package.js";
|
|
15
16
|
import { analyzeLegacyMultiAgentConfig, hasExactOmxSeededBehavioralDefaultsPair, hasLegacyOmxTeamRunTable, } from "../config/generator.js";
|
|
16
|
-
import { MANAGED_HOOK_EVENTS, buildManagedCodexNativeHookCommand, discoverCodexHookConfigPaths,
|
|
17
|
+
import { MANAGED_HOOK_EVENTS, buildManagedCodexNativeHookCommand, buildManagedCodexNativeHookWindowsShimContent, classifyManagedCodexNativeHookWindowsShimOwnership, discoverCodexHookConfigPaths, isManagedCodexHookCommand, parseManagedCodexNativeHookWindowsShimCommand, planManagedCodexHooksRemoval, resolveWindowsPowerShellPath, validateCodexHooksConfigStrict, } from "../config/codex-hooks.js";
|
|
17
18
|
import { OMX_FIRST_PARTY_MCP_SERVER_NAMES } from "../config/omx-first-party-mcp.js";
|
|
18
19
|
import { getDefaultBridge, isBridgeEnabled } from "../runtime/bridge.js";
|
|
19
20
|
import { OMX_EXPLORE_CMD_ENV, isExploreCommandRoutingEnabled, } from "../hooks/explore-routing.js";
|
|
@@ -124,6 +125,7 @@ export async function doctor(options = {}) {
|
|
|
124
125
|
const cwd = process.cwd();
|
|
125
126
|
const scopeResolution = await resolveDoctorScope(cwd);
|
|
126
127
|
const paths = resolveDoctorPaths(cwd, scopeResolution.scope);
|
|
128
|
+
await recoverNativeHookClaimJournal(paths.codexHomeDir);
|
|
127
129
|
const scopeSourceMessage = scopeResolution.source === "persisted"
|
|
128
130
|
? " (from .omx/setup-scope.json)"
|
|
129
131
|
: scopeResolution.source === "config"
|
|
@@ -182,13 +184,14 @@ export async function doctor(options = {}) {
|
|
|
182
184
|
checks.push(seededContextDefaultsCheck);
|
|
183
185
|
}
|
|
184
186
|
// Check 4.25: Native hooks coverage
|
|
185
|
-
|
|
187
|
+
const nativeHooksCheck = await checkNativeHooks(paths.hooksPath, paths.configPath, {
|
|
186
188
|
codexHomeDir: paths.codexHomeDir,
|
|
187
189
|
installMode: scopeResolution.installMode,
|
|
188
|
-
})
|
|
190
|
+
});
|
|
191
|
+
checks.push(nativeHooksCheck);
|
|
189
192
|
checks.push(await checkNativeHookDistSmoke());
|
|
190
193
|
if (options.verbose) {
|
|
191
|
-
const postCompactRuntimeCheck = await checkNativePostCompactHookRuntime(paths.hooksPath, cwd, paths.codexHomeDir);
|
|
194
|
+
const postCompactRuntimeCheck = await checkNativePostCompactHookRuntime(paths.hooksPath, cwd, paths.codexHomeDir, { nativeHooksCheck });
|
|
192
195
|
if (postCompactRuntimeCheck)
|
|
193
196
|
checks.push(postCompactRuntimeCheck);
|
|
194
197
|
}
|
|
@@ -249,10 +252,10 @@ export async function doctor(options = {}) {
|
|
|
249
252
|
}
|
|
250
253
|
console.log(`\nResults: ${passCount} passed, ${warnCount} warnings, ${failCount} failed`);
|
|
251
254
|
if (failCount > 0) {
|
|
252
|
-
console.log('\
|
|
255
|
+
console.log('\nReview failed checks above. Follow the check-specific recovery guidance; inspect invalid or ambiguous hook documents manually because doctor will not modify them.');
|
|
253
256
|
}
|
|
254
257
|
else if (warnCount > 0) {
|
|
255
|
-
console.log('\nReview warnings above.
|
|
258
|
+
console.log('\nReview warnings above. Follow the check-specific recovery guidance; for AGENTS.md preservation prefer "omx setup --merge-agents".');
|
|
256
259
|
}
|
|
257
260
|
else {
|
|
258
261
|
console.log("\nAll checks passed! oh-my-codex is ready.");
|
|
@@ -1229,6 +1232,183 @@ function configEnablesPluginScopedHooks(configContent) {
|
|
|
1229
1232
|
return /^\s*plugin_hooks\s*=\s*(?:true|1|"true"|"1"|"yes"|"on")\s*$/m.test(configContent);
|
|
1230
1233
|
}
|
|
1231
1234
|
}
|
|
1235
|
+
function trimNativeHookDetailTerminalPeriod(detail) {
|
|
1236
|
+
return detail.endsWith(".") ? detail.slice(0, -1) : detail;
|
|
1237
|
+
}
|
|
1238
|
+
function formatNativeHookDiagnostics(diagnostics) {
|
|
1239
|
+
return diagnostics
|
|
1240
|
+
.map((diagnostic) => {
|
|
1241
|
+
const coordinate = `${diagnostic.eventName}[${diagnostic.groupIndex}]${diagnostic.handlerIndex === undefined
|
|
1242
|
+
? ""
|
|
1243
|
+
: `.${diagnostic.handlerIndex}`}`;
|
|
1244
|
+
return `${coordinate}: ${trimNativeHookDetailTerminalPeriod(diagnostic.message)}`;
|
|
1245
|
+
})
|
|
1246
|
+
.join("; ");
|
|
1247
|
+
}
|
|
1248
|
+
function isJsonRecord(value) {
|
|
1249
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1250
|
+
}
|
|
1251
|
+
const WINDOWS_SHIM_SCAN_EVENTS = [
|
|
1252
|
+
"PreToolUse",
|
|
1253
|
+
"PermissionRequest",
|
|
1254
|
+
"PostToolUse",
|
|
1255
|
+
"PreCompact",
|
|
1256
|
+
"PostCompact",
|
|
1257
|
+
"SessionStart",
|
|
1258
|
+
"UserPromptSubmit",
|
|
1259
|
+
"SubagentStart",
|
|
1260
|
+
"SubagentStop",
|
|
1261
|
+
"Stop",
|
|
1262
|
+
];
|
|
1263
|
+
function effectiveWindowsHookCommand(handler) {
|
|
1264
|
+
const commandWindows = handler.commandWindows;
|
|
1265
|
+
if (typeof commandWindows === "string")
|
|
1266
|
+
return commandWindows;
|
|
1267
|
+
const commandWindowsSnakeCase = handler.command_windows;
|
|
1268
|
+
if (typeof commandWindowsSnakeCase === "string")
|
|
1269
|
+
return commandWindowsSnakeCase;
|
|
1270
|
+
return typeof handler.command === "string" ? handler.command : null;
|
|
1271
|
+
}
|
|
1272
|
+
function referencedWindowsNativeHookShimPaths(root, diagnostics, codexHomeDir) {
|
|
1273
|
+
if (!isJsonRecord(root.hooks))
|
|
1274
|
+
return [];
|
|
1275
|
+
const skippedGroups = new Set(diagnostics
|
|
1276
|
+
.filter((diagnostic) => diagnostic.code === "invalid_matcher")
|
|
1277
|
+
.map((diagnostic) => `${diagnostic.eventName}:${diagnostic.groupIndex}`));
|
|
1278
|
+
const skippedHandlers = new Set(diagnostics
|
|
1279
|
+
.filter((diagnostic) => diagnostic.code === "async_command" || diagnostic.code === "empty_command")
|
|
1280
|
+
.map((diagnostic) => `${diagnostic.eventName}:${diagnostic.groupIndex}:${diagnostic.handlerIndex}`));
|
|
1281
|
+
const shimPaths = new Set();
|
|
1282
|
+
for (const eventName of WINDOWS_SHIM_SCAN_EVENTS) {
|
|
1283
|
+
const eventGroups = root.hooks[eventName];
|
|
1284
|
+
if (!Array.isArray(eventGroups))
|
|
1285
|
+
continue;
|
|
1286
|
+
for (const [groupIndex, group] of eventGroups.entries()) {
|
|
1287
|
+
if (skippedGroups.has(`${eventName}:${groupIndex}`) || !isJsonRecord(group) || !Array.isArray(group.hooks))
|
|
1288
|
+
continue;
|
|
1289
|
+
for (const [handlerIndex, handler] of group.hooks.entries()) {
|
|
1290
|
+
if (skippedHandlers.has(`${eventName}:${groupIndex}:${handlerIndex}`) ||
|
|
1291
|
+
!isJsonRecord(handler) ||
|
|
1292
|
+
handler.type !== "command")
|
|
1293
|
+
continue;
|
|
1294
|
+
const command = effectiveWindowsHookCommand(handler);
|
|
1295
|
+
if (!command)
|
|
1296
|
+
continue;
|
|
1297
|
+
const shimPath = parseManagedCodexNativeHookWindowsShimCommand(command, {
|
|
1298
|
+
platform: "win32",
|
|
1299
|
+
codexHomeDir,
|
|
1300
|
+
});
|
|
1301
|
+
if (shimPath)
|
|
1302
|
+
shimPaths.add(shimPath);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
return [...shimPaths];
|
|
1307
|
+
}
|
|
1308
|
+
async function checkWindowsNativeHookShimParentTopology(shimPath, codexHomeDir) {
|
|
1309
|
+
let ancestorPath = dirname(shimPath);
|
|
1310
|
+
for (;;) {
|
|
1311
|
+
try {
|
|
1312
|
+
const ancestorStat = await lstat(ancestorPath);
|
|
1313
|
+
if (ancestorStat.isSymbolicLink() || !ancestorStat.isDirectory()) {
|
|
1314
|
+
return {
|
|
1315
|
+
name: "Native hooks",
|
|
1316
|
+
status: "fail",
|
|
1317
|
+
message: `referenced Windows native hook shim at ${shimPath} has an unsafe parent topology at ${ancestorPath}; doctor will not follow or modify it`,
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
catch {
|
|
1322
|
+
return {
|
|
1323
|
+
name: "Native hooks",
|
|
1324
|
+
status: "fail",
|
|
1325
|
+
message: `referenced Windows native hook shim at ${shimPath} has a parent topology that cannot be safely validated; doctor will not follow or modify it`,
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
if (ancestorPath === codexHomeDir)
|
|
1329
|
+
return null;
|
|
1330
|
+
const parentPath = dirname(ancestorPath);
|
|
1331
|
+
if (parentPath === ancestorPath) {
|
|
1332
|
+
return {
|
|
1333
|
+
name: "Native hooks",
|
|
1334
|
+
status: "fail",
|
|
1335
|
+
message: `referenced Windows native hook shim at ${shimPath} is outside the controlled Codex home topology; doctor will not follow or modify it`,
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
ancestorPath = parentPath;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
async function checkWindowsNativeHookShims(root, diagnostics, codexHomeDir, requireCurrent = false) {
|
|
1342
|
+
const expected = Buffer.from(buildManagedCodexNativeHookWindowsShimContent(getPackageRoot()), "utf-8");
|
|
1343
|
+
for (const shimPath of referencedWindowsNativeHookShimPaths(root, diagnostics, codexHomeDir)) {
|
|
1344
|
+
let shimContent;
|
|
1345
|
+
try {
|
|
1346
|
+
const shimStat = await lstat(shimPath);
|
|
1347
|
+
if (shimStat.isSymbolicLink() || !shimStat.isFile()) {
|
|
1348
|
+
return {
|
|
1349
|
+
name: "Native hooks",
|
|
1350
|
+
status: "fail",
|
|
1351
|
+
message: `referenced Windows native hook shim at ${shimPath} is not a regular file; doctor will not follow or modify it`,
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
if (shimStat.nlink !== 1) {
|
|
1355
|
+
return {
|
|
1356
|
+
name: "Native hooks",
|
|
1357
|
+
status: "fail",
|
|
1358
|
+
message: `referenced Windows native hook shim at ${shimPath} is hard-linked; doctor will not execute or modify it`,
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
shimContent = await readFile(shimPath);
|
|
1362
|
+
const topologyCheck = await checkWindowsNativeHookShimParentTopology(shimPath, codexHomeDir);
|
|
1363
|
+
if (topologyCheck)
|
|
1364
|
+
return topologyCheck;
|
|
1365
|
+
}
|
|
1366
|
+
catch (error) {
|
|
1367
|
+
const code = typeof error === "object" && error !== null && "code" in error
|
|
1368
|
+
? String(error.code)
|
|
1369
|
+
: undefined;
|
|
1370
|
+
return {
|
|
1371
|
+
name: "Native hooks",
|
|
1372
|
+
status: "fail",
|
|
1373
|
+
message: code === "ENOENT"
|
|
1374
|
+
? `referenced Windows native hook shim is missing at ${shimPath}; manually reinstall the matching oh-my-codex version because doctor will not create or modify shims`
|
|
1375
|
+
: `cannot read referenced Windows native hook shim at ${shimPath}; inspect it and manually reinstall the matching oh-my-codex version because doctor will not modify shims`,
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1378
|
+
const ownership = classifyManagedCodexNativeHookWindowsShimOwnership(shimContent, expected);
|
|
1379
|
+
if (ownership === "modified") {
|
|
1380
|
+
return {
|
|
1381
|
+
name: "Native hooks",
|
|
1382
|
+
status: "fail",
|
|
1383
|
+
message: `referenced Windows native hook shim at ${shimPath} is not an exact current or complete historical generated shim; it may be modified, truncated, have extra content, or use ambiguous encoding. Manually reinstall the matching oh-my-codex version because doctor will not overwrite it`,
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
if (requireCurrent && ownership !== "current") {
|
|
1387
|
+
return {
|
|
1388
|
+
name: "Native hooks",
|
|
1389
|
+
status: "warn",
|
|
1390
|
+
message: `referenced Windows native hook shim at ${shimPath} is a complete historical generated shim, but verbose execution requires exact current shim bytes; run "omx setup" to migrate it before retrying`,
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return null;
|
|
1395
|
+
}
|
|
1396
|
+
const MANAGED_HOOK_TRUST_KEY_LABELS = {
|
|
1397
|
+
SessionStart: "session_start",
|
|
1398
|
+
PreToolUse: "pre_tool_use",
|
|
1399
|
+
PostToolUse: "post_tool_use",
|
|
1400
|
+
UserPromptSubmit: "user_prompt_submit",
|
|
1401
|
+
PreCompact: "pre_compact",
|
|
1402
|
+
PostCompact: "post_compact",
|
|
1403
|
+
Stop: "stop",
|
|
1404
|
+
};
|
|
1405
|
+
function getMissingManagedHookEventsFromPlan(plan) {
|
|
1406
|
+
return MANAGED_HOOK_EVENTS.filter((eventName) => {
|
|
1407
|
+
const label = MANAGED_HOOK_TRUST_KEY_LABELS[eventName];
|
|
1408
|
+
const keyPattern = new RegExp(`:${label}:\\d+:\\d+$`);
|
|
1409
|
+
return !Object.keys(plan.priorTrustState).some((key) => keyPattern.test(key));
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1232
1412
|
function pluginHooksJsonHasNativeCoverage(content) {
|
|
1233
1413
|
try {
|
|
1234
1414
|
const parsed = JSON.parse(content);
|
|
@@ -1260,7 +1440,7 @@ function pluginHooksJsonHasNativeCoverage(content) {
|
|
|
1260
1440
|
}
|
|
1261
1441
|
async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
1262
1442
|
const setupHooksPathDescription = existsSync(setupHooksPath)
|
|
1263
|
-
? `existing hooks.json at ${setupHooksPath} is
|
|
1443
|
+
? `existing hooks.json at ${setupHooksPath} is retained read-only and validated separately because plugin-scoped hooks are enabled`
|
|
1264
1444
|
: `setup-owned hooks.json is intentionally absent at ${setupHooksPath}`;
|
|
1265
1445
|
const packagedMarketplace = await resolvePackagedOmxMarketplace(getPackageRoot());
|
|
1266
1446
|
if (!packagedMarketplace) {
|
|
@@ -1282,14 +1462,14 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1282
1462
|
return {
|
|
1283
1463
|
name: "Native hooks",
|
|
1284
1464
|
status: "warn",
|
|
1285
|
-
message: `plugin-scoped hooks are enabled, but the expected Codex plugin cache manifest is missing at ${join(expectedCacheDir, ".codex-plugin", "plugin.json")}; ${setupHooksPathDescription}; run "omx setup --plugin
|
|
1465
|
+
message: `plugin-scoped hooks are enabled, but the expected Codex plugin cache manifest is missing at ${join(expectedCacheDir, ".codex-plugin", "plugin.json")}; ${setupHooksPathDescription}; run "omx setup --plugin" to refresh the plugin cache`,
|
|
1286
1466
|
};
|
|
1287
1467
|
}
|
|
1288
1468
|
if (state.hooksPointer !== "./hooks/hooks.json") {
|
|
1289
1469
|
return {
|
|
1290
1470
|
name: "Native hooks",
|
|
1291
1471
|
status: "warn",
|
|
1292
|
-
message: `plugin-scoped hooks are enabled, but the Codex plugin cache manifest points hooks to ${String(state.hooksPointer)} instead of ./hooks/hooks.json at ${expectedHooksPath}; run "omx setup --plugin
|
|
1472
|
+
message: `plugin-scoped hooks are enabled, but the Codex plugin cache manifest points hooks to ${String(state.hooksPointer)} instead of ./hooks/hooks.json at ${expectedHooksPath}; run "omx setup --plugin" to refresh the plugin cache`,
|
|
1293
1473
|
};
|
|
1294
1474
|
}
|
|
1295
1475
|
for (const expectedPath of [expectedHooksPath, expectedHookLauncherPath, expectedPinnedLauncherPath]) {
|
|
@@ -1297,7 +1477,7 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1297
1477
|
return {
|
|
1298
1478
|
name: "Native hooks",
|
|
1299
1479
|
status: "warn",
|
|
1300
|
-
message: `plugin-scoped hooks are enabled, but expected plugin hook file is missing at ${expectedPath}; ${setupHooksPathDescription}; run "omx setup --plugin
|
|
1480
|
+
message: `plugin-scoped hooks are enabled, but expected plugin hook file is missing at ${expectedPath}; ${setupHooksPathDescription}; run "omx setup --plugin" to refresh the plugin cache`,
|
|
1301
1481
|
};
|
|
1302
1482
|
}
|
|
1303
1483
|
}
|
|
@@ -1305,7 +1485,7 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1305
1485
|
return {
|
|
1306
1486
|
name: "Native hooks",
|
|
1307
1487
|
status: "warn",
|
|
1308
|
-
message: `plugin-scoped hooks are enabled, but cached plugin hook files or pinned hook launcher in ${expectedCacheDir} do not match the packaged plugin; ${setupHooksPathDescription}; run "omx setup --plugin
|
|
1488
|
+
message: `plugin-scoped hooks are enabled, but cached plugin hook files or pinned hook launcher in ${expectedCacheDir} do not match the packaged plugin; ${setupHooksPathDescription}; run "omx setup --plugin" to refresh the plugin cache`,
|
|
1309
1489
|
};
|
|
1310
1490
|
}
|
|
1311
1491
|
let hookContent;
|
|
@@ -1331,7 +1511,7 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1331
1511
|
return {
|
|
1332
1512
|
name: "Native hooks",
|
|
1333
1513
|
status: "warn",
|
|
1334
|
-
message: `plugin-scoped hooks.json at ${expectedHooksPath} is missing OMX native coverage for one or more events; run "omx setup --plugin
|
|
1514
|
+
message: `plugin-scoped hooks.json at ${expectedHooksPath} is missing OMX native coverage for one or more events; run "omx setup --plugin" to refresh the plugin cache`,
|
|
1335
1515
|
};
|
|
1336
1516
|
}
|
|
1337
1517
|
const smokeCwd = await mkdtemp(join(tmpdir(), "omx-doctor-plugin-hook-"));
|
|
@@ -1384,12 +1564,145 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1384
1564
|
message: `plugin-scoped hooks are enabled; ${setupHooksPathDescription}, and plugin cache native hook coverage smoke passed via ${expectedHooksPath}`,
|
|
1385
1565
|
};
|
|
1386
1566
|
}
|
|
1387
|
-
|
|
1567
|
+
function decodeStrictUtf8(bytes) {
|
|
1568
|
+
try {
|
|
1569
|
+
const content = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
1570
|
+
return Buffer.from(content, "utf-8").equals(bytes) ? content : null;
|
|
1571
|
+
}
|
|
1572
|
+
catch {
|
|
1573
|
+
return null;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
function combinePluginAndGlobalNativeHookChecks(plugin, global) {
|
|
1577
|
+
if (!global)
|
|
1578
|
+
return plugin;
|
|
1579
|
+
const status = plugin.status === "fail" || global.status === "fail"
|
|
1580
|
+
? "fail"
|
|
1581
|
+
: plugin.status === "warn" || global.status === "warn"
|
|
1582
|
+
? "warn"
|
|
1583
|
+
: "pass";
|
|
1584
|
+
return {
|
|
1585
|
+
name: "Native hooks",
|
|
1586
|
+
status,
|
|
1587
|
+
message: `${plugin.message}; existing global hooks.json: ${global.message}`,
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
function combineNativeHookIntegrityAndRemovalChecks(integrityCheck, removalCheck) {
|
|
1591
|
+
if (!integrityCheck)
|
|
1592
|
+
return removalCheck;
|
|
1593
|
+
return {
|
|
1594
|
+
name: "Native hooks",
|
|
1595
|
+
status: integrityCheck.status === "fail" || removalCheck.status === "fail"
|
|
1596
|
+
? "fail"
|
|
1597
|
+
: "warn",
|
|
1598
|
+
message: `${integrityCheck.message}; ${removalCheck.message}`,
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
async function checkExistingNativeHooks(hooksPath, context) {
|
|
1602
|
+
const platform = context.platform ?? process.platform;
|
|
1603
|
+
try {
|
|
1604
|
+
const hooksStat = await lstat(hooksPath);
|
|
1605
|
+
if (hooksStat.isSymbolicLink() || !hooksStat.isFile()) {
|
|
1606
|
+
return {
|
|
1607
|
+
name: "Native hooks",
|
|
1608
|
+
status: "fail",
|
|
1609
|
+
message: `hooks.json at ${hooksPath} is not a regular file; doctor will not follow or modify it`,
|
|
1610
|
+
};
|
|
1611
|
+
}
|
|
1612
|
+
const content = decodeStrictUtf8(await readFile(hooksPath));
|
|
1613
|
+
if (content === null) {
|
|
1614
|
+
return {
|
|
1615
|
+
name: "Native hooks",
|
|
1616
|
+
status: "fail",
|
|
1617
|
+
message: `hooks.json at ${hooksPath} is not valid UTF-8; inspect the file manually because doctor will not modify it`,
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
1620
|
+
const validation = validateCodexHooksConfigStrict(content, {
|
|
1621
|
+
platform,
|
|
1622
|
+
codexHomeDir: context.codexHomeDir,
|
|
1623
|
+
});
|
|
1624
|
+
if (!validation.ok) {
|
|
1625
|
+
return {
|
|
1626
|
+
name: "Native hooks",
|
|
1627
|
+
status: "fail",
|
|
1628
|
+
message: `hooks.json failed strict load validation (${validation.error.code}): ${trimNativeHookDetailTerminalPeriod(validation.error.message)}; inspect the file manually because doctor will not modify it`,
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
const removalPlan = planManagedCodexHooksRemoval(content, hooksPath, {
|
|
1632
|
+
platform,
|
|
1633
|
+
codexHomeDir: context.codexHomeDir,
|
|
1634
|
+
});
|
|
1635
|
+
const windowsShimCheck = platform === "win32"
|
|
1636
|
+
? await checkWindowsNativeHookShims(validation.root, validation.diagnostics, context.codexHomeDir)
|
|
1637
|
+
: null;
|
|
1638
|
+
if (!removalPlan.ok) {
|
|
1639
|
+
const removalIsCoordinateOnly = removalPlan.error.code === "unsafe_managed_removal";
|
|
1640
|
+
const removalCheck = {
|
|
1641
|
+
name: "Native hooks",
|
|
1642
|
+
status: removalIsCoordinateOnly ? "warn" : "fail",
|
|
1643
|
+
message: removalIsCoordinateOnly
|
|
1644
|
+
? `hooks.json has OMX entries that cannot be safely removed (${removalPlan.error.code}): ${trimNativeHookDetailTerminalPeriod(removalPlan.error.message)}; manual cleanup is required because doctor will not overwrite or remove it`
|
|
1645
|
+
: `hooks.json has ambiguous or untrusted OMX ownership (${removalPlan.error.code}): ${trimNativeHookDetailTerminalPeriod(removalPlan.error.message)}; inspect the file manually because doctor will not overwrite or remove it`,
|
|
1646
|
+
};
|
|
1647
|
+
return combineNativeHookIntegrityAndRemovalChecks(windowsShimCheck, removalCheck);
|
|
1648
|
+
}
|
|
1649
|
+
if (windowsShimCheck)
|
|
1650
|
+
return windowsShimCheck;
|
|
1651
|
+
const legacyTrustStateEntries = Object.keys(removalPlan.legacyTrustState).length;
|
|
1652
|
+
if (legacyTrustStateEntries > 0) {
|
|
1653
|
+
return {
|
|
1654
|
+
name: "Native hooks",
|
|
1655
|
+
status: "warn",
|
|
1656
|
+
message: `hooks.json contains ${legacyTrustStateEntries} exact historical OMX hook trust-state ${legacyTrustStateEntries === 1 ? "entry that requires" : "entries that require"} migration; run "omx setup" to migrate ${legacyTrustStateEntries === 1 ? "it" : "them"} after reviewing the configuration`,
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
if (validation.diagnostics.length > 0) {
|
|
1660
|
+
return {
|
|
1661
|
+
name: "Native hooks",
|
|
1662
|
+
status: "warn",
|
|
1663
|
+
message: `hooks.json discovery warnings: ${formatNativeHookDiagnostics(validation.diagnostics)}; Codex may ignore the listed entries, and doctor will not modify them`,
|
|
1664
|
+
};
|
|
1665
|
+
}
|
|
1666
|
+
const missingEvents = getMissingManagedHookEventsFromPlan(removalPlan);
|
|
1667
|
+
if (removalPlan.hasForeignHooks &&
|
|
1668
|
+
removalPlan.removedCount === 0 &&
|
|
1669
|
+
missingEvents.length === MANAGED_HOOK_EVENTS.length) {
|
|
1670
|
+
return {
|
|
1671
|
+
name: "Native hooks",
|
|
1672
|
+
status: "pass",
|
|
1673
|
+
message: "hooks.json contains valid foreign hook entries and no OMX-managed wrappers; doctor will preserve the user-owned configuration",
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
if (missingEvents.length > 0) {
|
|
1677
|
+
return {
|
|
1678
|
+
name: "Native hooks",
|
|
1679
|
+
status: "warn",
|
|
1680
|
+
message: `hooks.json is missing OMX-managed coverage for ${missingEvents.join(", ")}; run "omx setup" to restore native hooks${removalPlan.hasForeignHooks ? "; valid foreign hooks will be preserved" : ""}`,
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
return {
|
|
1684
|
+
name: "Native hooks",
|
|
1685
|
+
status: "pass",
|
|
1686
|
+
message: `hooks.json includes OMX-managed coverage for all native hook events${removalPlan.hasForeignHooks ? "; valid foreign hooks will be preserved" : ""}`,
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
catch {
|
|
1690
|
+
return {
|
|
1691
|
+
name: "Native hooks",
|
|
1692
|
+
status: "fail",
|
|
1693
|
+
message: "cannot read hooks.json",
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
export async function checkNativeHooks(hooksPath, configPath, context) {
|
|
1388
1698
|
if (existsSync(configPath) && context.installMode === "plugin") {
|
|
1389
1699
|
try {
|
|
1390
1700
|
const configContent = await readFile(configPath, "utf-8");
|
|
1391
1701
|
if (configEnablesPluginScopedHooks(configContent)) {
|
|
1392
|
-
|
|
1702
|
+
const globalCheck = existsSync(hooksPath)
|
|
1703
|
+
? await checkExistingNativeHooks(hooksPath, context)
|
|
1704
|
+
: null;
|
|
1705
|
+
return combinePluginAndGlobalNativeHookChecks(await checkPluginScopedNativeHooks(context.codexHomeDir, hooksPath), globalCheck);
|
|
1393
1706
|
}
|
|
1394
1707
|
}
|
|
1395
1708
|
catch {
|
|
@@ -1401,25 +1714,23 @@ async function checkNativeHooks(hooksPath, configPath, context) {
|
|
|
1401
1714
|
if (existsSync(configPath)) {
|
|
1402
1715
|
try {
|
|
1403
1716
|
const configContent = await readFile(configPath, "utf-8");
|
|
1404
|
-
if (context.installMode === "plugin") {
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
};
|
|
1411
|
-
}
|
|
1717
|
+
if (context.installMode === "plugin" && configHasOmxEntries(configContent)) {
|
|
1718
|
+
return {
|
|
1719
|
+
name: "Native hooks",
|
|
1720
|
+
status: "warn",
|
|
1721
|
+
message: `plugin mode is using legacy native hook fallback, but expected setup-owned hooks.json is missing at ${hooksPath}; run "omx setup --plugin" to restore the fallback hook file, or upgrade Codex to plugin_hooks support so setup can use plugin-scoped hooks`,
|
|
1722
|
+
};
|
|
1412
1723
|
}
|
|
1413
1724
|
if (configHasOmxEntries(configContent)) {
|
|
1414
1725
|
return {
|
|
1415
1726
|
name: "Native hooks",
|
|
1416
1727
|
status: "warn",
|
|
1417
|
-
message: `expected setup-owned hooks.json is missing at ${hooksPath} even though config.toml has OMX entries; run "omx setup
|
|
1728
|
+
message: `expected setup-owned hooks.json is missing at ${hooksPath} even though config.toml has OMX entries; run "omx setup" to restore native hook coverage`,
|
|
1418
1729
|
};
|
|
1419
1730
|
}
|
|
1420
1731
|
}
|
|
1421
1732
|
catch {
|
|
1422
|
-
//
|
|
1733
|
+
// Fall through to the neutral first-setup path when config cannot be read here;
|
|
1423
1734
|
// the dedicated config check will report read failures separately.
|
|
1424
1735
|
}
|
|
1425
1736
|
}
|
|
@@ -1429,66 +1740,18 @@ async function checkNativeHooks(hooksPath, configPath, context) {
|
|
|
1429
1740
|
message: "hooks.json not found yet (expected before first setup)",
|
|
1430
1741
|
};
|
|
1431
1742
|
}
|
|
1432
|
-
|
|
1433
|
-
const content = await readFile(hooksPath, "utf-8");
|
|
1434
|
-
const missingEvents = getMissingManagedCodexHookEvents(content);
|
|
1435
|
-
if (missingEvents === null) {
|
|
1436
|
-
return {
|
|
1437
|
-
name: "Native hooks",
|
|
1438
|
-
status: "fail",
|
|
1439
|
-
message: 'invalid hooks.json; Codex may skip OMX hook coverage until "omx setup --force" repairs it',
|
|
1440
|
-
};
|
|
1441
|
-
}
|
|
1442
|
-
const hasTopLevelState = hasCodexHooksJsonTopLevelState(content);
|
|
1443
|
-
if (hasTopLevelState === true) {
|
|
1444
|
-
return {
|
|
1445
|
-
name: "Native hooks",
|
|
1446
|
-
status: "fail",
|
|
1447
|
-
message: 'top-level state in hooks.json is incompatible with Codex 0.140 (unknown field state, expected hooks); run "omx setup --force" to migrate trust state to config.toml and repair hooks.json',
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
|
-
if (missingEvents.length > 0) {
|
|
1451
|
-
return {
|
|
1452
|
-
name: "Native hooks",
|
|
1453
|
-
status: "warn",
|
|
1454
|
-
message: `hooks.json is missing OMX-managed coverage for ${missingEvents.join(", ")}; run "omx setup --force" to restore native hooks`,
|
|
1455
|
-
};
|
|
1456
|
-
}
|
|
1457
|
-
return {
|
|
1458
|
-
name: "Native hooks",
|
|
1459
|
-
status: "pass",
|
|
1460
|
-
message: "hooks.json includes OMX-managed coverage for all native hook events",
|
|
1461
|
-
};
|
|
1462
|
-
}
|
|
1463
|
-
catch {
|
|
1464
|
-
return {
|
|
1465
|
-
name: "Native hooks",
|
|
1466
|
-
status: "fail",
|
|
1467
|
-
message: "cannot read hooks.json",
|
|
1468
|
-
};
|
|
1469
|
-
}
|
|
1743
|
+
return checkExistingNativeHooks(hooksPath, context);
|
|
1470
1744
|
}
|
|
1471
1745
|
export async function checkNativeHookDistSmoke(options = {}) {
|
|
1472
1746
|
const packageRoot = options.packageRoot ?? getPackageRoot();
|
|
1473
1747
|
const nodePath = options.nodePath ?? process.execPath;
|
|
1474
1748
|
const runner = options.runner ?? spawnSync;
|
|
1475
1749
|
const scriptPath = join(packageRoot, "dist", "scripts", "codex-native-hook.js");
|
|
1476
|
-
const packageJsonPath = join(packageRoot, "package.json");
|
|
1477
|
-
let packageVersion = "current";
|
|
1478
|
-
try {
|
|
1479
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
1480
|
-
if (typeof packageJson.version === "string" && packageJson.version.trim()) {
|
|
1481
|
-
packageVersion = packageJson.version.trim();
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
catch {
|
|
1485
|
-
// Keep the generic recovery copy when package metadata is not readable.
|
|
1486
|
-
}
|
|
1487
1750
|
if (!existsSync(scriptPath)) {
|
|
1488
1751
|
return {
|
|
1489
1752
|
name: "Native hook dist smoke",
|
|
1490
1753
|
status: "fail",
|
|
1491
|
-
message: `installed native hook script is missing at ${scriptPath}; reinstall oh-my-codex and run "omx setup
|
|
1754
|
+
message: `installed native hook script is missing at ${scriptPath}; reinstall oh-my-codex and run "omx setup"`,
|
|
1492
1755
|
};
|
|
1493
1756
|
}
|
|
1494
1757
|
const smokeCwd = await mkdtemp(join(tmpdir(), "omx-doctor-native-hook-dist-"));
|
|
@@ -1518,7 +1781,7 @@ export async function checkNativeHookDistSmoke(options = {}) {
|
|
|
1518
1781
|
return {
|
|
1519
1782
|
name: "Native hook dist smoke",
|
|
1520
1783
|
status: "fail",
|
|
1521
|
-
message: `installed native hook dist smoke failed to run (${result.error.message}); reinstall oh-my-codex and run "omx setup
|
|
1784
|
+
message: `installed native hook dist smoke failed to run (${result.error.message}); reinstall oh-my-codex and run "omx setup"`,
|
|
1522
1785
|
};
|
|
1523
1786
|
}
|
|
1524
1787
|
if (result.status !== 0) {
|
|
@@ -1528,7 +1791,7 @@ export async function checkNativeHookDistSmoke(options = {}) {
|
|
|
1528
1791
|
return {
|
|
1529
1792
|
name: "Native hook dist smoke",
|
|
1530
1793
|
status: "fail",
|
|
1531
|
-
message: `installed native hook dist failed a minimal UserPromptSubmit smoke (${detail}); reinstall
|
|
1794
|
+
message: `installed native hook dist failed a minimal UserPromptSubmit smoke (${detail}); reinstall the matching oh-my-codex version and then run "omx setup"`,
|
|
1532
1795
|
};
|
|
1533
1796
|
}
|
|
1534
1797
|
return {
|
|
@@ -1550,14 +1813,14 @@ export function classifyPostCompactHookStdout(stdout) {
|
|
|
1550
1813
|
return {
|
|
1551
1814
|
name: "Native PostCompact hook",
|
|
1552
1815
|
status: "fail",
|
|
1553
|
-
message: "PostCompact hook emitted JSON stdout, but OMX PostCompact must emit no stdout until Codex defines a supported PostCompact output contract;
|
|
1816
|
+
message: "PostCompact hook emitted JSON stdout, but OMX PostCompact must emit no stdout until Codex defines a supported PostCompact output contract; rerun \"omx setup\" after upgrading",
|
|
1554
1817
|
};
|
|
1555
1818
|
}
|
|
1556
1819
|
catch (error) {
|
|
1557
1820
|
return {
|
|
1558
1821
|
name: "Native PostCompact hook",
|
|
1559
1822
|
status: "fail",
|
|
1560
|
-
message: `PostCompact hook emitted invalid JSON stdout (${error instanceof Error ? error.message : String(error)});
|
|
1823
|
+
message: `PostCompact hook emitted invalid JSON stdout (${error instanceof Error ? error.message : String(error)}); rerun "omx setup" after upgrading`,
|
|
1561
1824
|
};
|
|
1562
1825
|
}
|
|
1563
1826
|
}
|
|
@@ -1582,77 +1845,278 @@ export function buildPostCompactSmokeSpawnInvocation(expectedCommand, options =
|
|
|
1582
1845
|
shell: true,
|
|
1583
1846
|
};
|
|
1584
1847
|
}
|
|
1585
|
-
|
|
1586
|
-
|
|
1848
|
+
function buildInMemoryWindowsShimSmokeInvocation(expectedShimContent, options = {}) {
|
|
1849
|
+
const shimSource = decodeStrictUtf8(expectedShimContent);
|
|
1850
|
+
if (shimSource === null)
|
|
1587
1851
|
return null;
|
|
1588
|
-
|
|
1852
|
+
const encodedShimBytes = expectedShimContent.toString("base64");
|
|
1853
|
+
const command = [
|
|
1854
|
+
"$ErrorActionPreference = 'Stop'",
|
|
1855
|
+
`$omxShimSource = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${encodedShimBytes}'))`,
|
|
1856
|
+
"if ($omxShimSource.Length -gt 0 -and [int][char]$omxShimSource[0] -eq 0xFEFF) { $omxShimSource = $omxShimSource.Substring(1) }",
|
|
1857
|
+
"& ([ScriptBlock]::Create($omxShimSource))",
|
|
1858
|
+
"exit $LASTEXITCODE",
|
|
1859
|
+
].join("; ");
|
|
1860
|
+
return {
|
|
1861
|
+
command: resolveWindowsPowerShellPath(options.env),
|
|
1862
|
+
args: [
|
|
1863
|
+
"-NoProfile",
|
|
1864
|
+
"-ExecutionPolicy",
|
|
1865
|
+
"Bypass",
|
|
1866
|
+
"-EncodedCommand",
|
|
1867
|
+
Buffer.from(command, "utf16le").toString("base64"),
|
|
1868
|
+
],
|
|
1869
|
+
shell: false,
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
function smokeDirectoryIdentity(stat) {
|
|
1873
|
+
if (!stat.isDirectory() ||
|
|
1874
|
+
stat.isSymbolicLink() ||
|
|
1875
|
+
(process.platform !== "win32" && (stat.mode & 0o077) !== 0))
|
|
1876
|
+
return null;
|
|
1877
|
+
return { dev: stat.dev, ino: stat.ino };
|
|
1878
|
+
}
|
|
1879
|
+
async function readSmokeDirectoryIdentity(smokeCwd) {
|
|
1589
1880
|
try {
|
|
1590
|
-
|
|
1881
|
+
return smokeDirectoryIdentity(await lstat(smokeCwd));
|
|
1591
1882
|
}
|
|
1592
1883
|
catch {
|
|
1593
1884
|
return null;
|
|
1594
1885
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1886
|
+
}
|
|
1887
|
+
function sameSmokeDirectoryIdentity(expected, actual) {
|
|
1888
|
+
return actual !== null && actual.dev === expected.dev && actual.ino === expected.ino;
|
|
1889
|
+
}
|
|
1890
|
+
function smokeDirectorySafetyCheck(message) {
|
|
1891
|
+
return {
|
|
1892
|
+
name: "Native PostCompact hook",
|
|
1893
|
+
status: "warn",
|
|
1894
|
+
message,
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
async function cleanupSmokeDirectoryIfUnchanged(smokeCwd, identity) {
|
|
1898
|
+
if (!sameSmokeDirectoryIdentity(identity, await readSmokeDirectoryIdentity(smokeCwd))) {
|
|
1899
|
+
return smokeDirectorySafetyCheck("temporary PostCompact smoke directory changed during validation; doctor preserved it for manual recovery and skipped cleanup for safety");
|
|
1900
|
+
}
|
|
1901
|
+
try {
|
|
1902
|
+
// Only remove the empty, identity-checked directory. Never recursively remove
|
|
1903
|
+
// a directory that another process could have replaced or populated.
|
|
1904
|
+
await rmdir(smokeCwd);
|
|
1597
1905
|
return null;
|
|
1598
1906
|
}
|
|
1599
|
-
|
|
1907
|
+
catch {
|
|
1908
|
+
return smokeDirectorySafetyCheck("temporary PostCompact smoke directory could not be removed without recursive deletion; doctor preserved it for manual recovery");
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
function inMemoryWindowsShimSmokeCheck() {
|
|
1912
|
+
return {
|
|
1913
|
+
name: "Native PostCompact hook",
|
|
1914
|
+
status: "warn",
|
|
1915
|
+
message: "doctor could not build an in-memory Windows native hook smoke command from exact validated shim bytes; doctor skipped execution for safety",
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
function getManagedPostCompactHookCommands(content, platform, codexHomeDir) {
|
|
1919
|
+
const validation = validateCodexHooksConfigStrict(content, {
|
|
1920
|
+
platform,
|
|
1921
|
+
codexHomeDir,
|
|
1922
|
+
});
|
|
1923
|
+
if (!validation.ok)
|
|
1924
|
+
return null;
|
|
1925
|
+
return validation.discoveredCommands
|
|
1926
|
+
.filter((command) => command.eventName === "PostCompact")
|
|
1927
|
+
.map((command) => command.command)
|
|
1928
|
+
.filter((command) => isManagedCodexHookCommand(command) ||
|
|
1929
|
+
(platform === "win32" && parseManagedCodexNativeHookWindowsShimCommand(command, {
|
|
1930
|
+
platform,
|
|
1931
|
+
codexHomeDir,
|
|
1932
|
+
}) !== null));
|
|
1933
|
+
}
|
|
1934
|
+
function currentPostCompactCommandCheck() {
|
|
1935
|
+
return {
|
|
1936
|
+
name: "Native PostCompact hook",
|
|
1937
|
+
status: "warn",
|
|
1938
|
+
message: "effective PostCompact OMX command does not match this installation's managed hook command; doctor skipped execution for safety, and rerunning \"omx setup\" should refresh stale hooks.json entries",
|
|
1939
|
+
};
|
|
1940
|
+
}
|
|
1941
|
+
function skippedPostCompactIntegrityCheck(integrityCheck) {
|
|
1942
|
+
return {
|
|
1943
|
+
name: "Native PostCompact hook",
|
|
1944
|
+
status: integrityCheck.status === "fail" ? "fail" : "warn",
|
|
1945
|
+
message: `${integrityCheck.message}; doctor skipped execution because native hook integrity validation did not pass`,
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
export async function checkNativePostCompactHookRuntime(hooksPath, cwd, codexHomeDir, options = {}) {
|
|
1949
|
+
if (!existsSync(hooksPath))
|
|
1950
|
+
return null;
|
|
1951
|
+
if (options.nativeHooksCheck && options.nativeHooksCheck.status !== "pass")
|
|
1952
|
+
return null;
|
|
1953
|
+
const platform = options.platform ?? process.platform;
|
|
1954
|
+
const expectedCommand = options.expectedCommand ?? buildManagedCodexNativeHookCommand(getPackageRoot(), {
|
|
1600
1955
|
codexHomeDir,
|
|
1956
|
+
platform,
|
|
1601
1957
|
});
|
|
1958
|
+
let content;
|
|
1959
|
+
try {
|
|
1960
|
+
content = decodeStrictUtf8(await readFile(hooksPath));
|
|
1961
|
+
}
|
|
1962
|
+
catch {
|
|
1963
|
+
return null;
|
|
1964
|
+
}
|
|
1965
|
+
if (content === null)
|
|
1966
|
+
return null;
|
|
1967
|
+
const postCompactCommands = getManagedPostCompactHookCommands(content, platform, codexHomeDir);
|
|
1968
|
+
if (postCompactCommands === null || postCompactCommands.length === 0)
|
|
1969
|
+
return null;
|
|
1602
1970
|
const uniqueCommands = [...new Set(postCompactCommands)];
|
|
1603
1971
|
if (uniqueCommands.length !== 1 || uniqueCommands[0] !== expectedCommand) {
|
|
1604
|
-
return
|
|
1605
|
-
name: "Native PostCompact hook",
|
|
1606
|
-
status: "warn",
|
|
1607
|
-
message: "effective PostCompact OMX command does not match this installation's managed hook command; doctor skipped execution for safety, and \"omx setup --force\" should refresh stale hooks.json entries",
|
|
1608
|
-
};
|
|
1972
|
+
return currentPostCompactCommandCheck();
|
|
1609
1973
|
}
|
|
1610
1974
|
const smokeCwd = await mkdtemp(join(tmpdir(), "omx-doctor-postcompact-"));
|
|
1975
|
+
const smokeDirectory = await readSmokeDirectoryIdentity(smokeCwd);
|
|
1976
|
+
if (!smokeDirectory) {
|
|
1977
|
+
return smokeDirectorySafetyCheck("temporary PostCompact smoke directory could not be validated; doctor preserved it for manual recovery and skipped execution for safety");
|
|
1978
|
+
}
|
|
1979
|
+
let primaryResult = null;
|
|
1980
|
+
let primaryError = null;
|
|
1611
1981
|
try {
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1982
|
+
primaryResult = await (async () => {
|
|
1983
|
+
const revalidatedIntegrity = await checkExistingNativeHooks(hooksPath, {
|
|
1984
|
+
codexHomeDir,
|
|
1985
|
+
platform,
|
|
1986
|
+
});
|
|
1987
|
+
if (revalidatedIntegrity.status !== "pass") {
|
|
1988
|
+
return skippedPostCompactIntegrityCheck(revalidatedIntegrity);
|
|
1989
|
+
}
|
|
1990
|
+
let revalidatedContent;
|
|
1991
|
+
try {
|
|
1992
|
+
revalidatedContent = decodeStrictUtf8(await readFile(hooksPath));
|
|
1993
|
+
}
|
|
1994
|
+
catch {
|
|
1995
|
+
return {
|
|
1996
|
+
name: "Native PostCompact hook",
|
|
1997
|
+
status: "warn",
|
|
1998
|
+
message: "hooks.json changed during verbose validation; doctor skipped execution for safety",
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
if (revalidatedContent === null) {
|
|
2002
|
+
return {
|
|
2003
|
+
name: "Native PostCompact hook",
|
|
2004
|
+
status: "warn",
|
|
2005
|
+
message: "hooks.json changed during verbose validation; doctor skipped execution for safety",
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
const revalidatedCommands = getManagedPostCompactHookCommands(revalidatedContent, platform, codexHomeDir);
|
|
2009
|
+
if (revalidatedCommands === null ||
|
|
2010
|
+
revalidatedCommands.length === 0 ||
|
|
2011
|
+
new Set(revalidatedCommands).size !== 1 ||
|
|
2012
|
+
revalidatedCommands[0] !== expectedCommand) {
|
|
2013
|
+
return currentPostCompactCommandCheck();
|
|
2014
|
+
}
|
|
2015
|
+
if (platform === "win32") {
|
|
2016
|
+
const validation = validateCodexHooksConfigStrict(revalidatedContent, {
|
|
2017
|
+
platform,
|
|
2018
|
+
codexHomeDir,
|
|
2019
|
+
});
|
|
2020
|
+
if (!validation.ok) {
|
|
2021
|
+
return {
|
|
2022
|
+
name: "Native PostCompact hook",
|
|
2023
|
+
status: "warn",
|
|
2024
|
+
message: "hooks.json changed during verbose validation; doctor skipped execution for safety",
|
|
2025
|
+
};
|
|
2026
|
+
}
|
|
2027
|
+
const currentShimCheck = await checkWindowsNativeHookShims(validation.root, validation.diagnostics, codexHomeDir, true);
|
|
2028
|
+
if (currentShimCheck)
|
|
2029
|
+
return skippedPostCompactIntegrityCheck(currentShimCheck);
|
|
2030
|
+
}
|
|
2031
|
+
let smokeInvocation;
|
|
2032
|
+
if (platform === "win32") {
|
|
2033
|
+
const canonicalShimPath = parseManagedCodexNativeHookWindowsShimCommand(expectedCommand, {
|
|
2034
|
+
platform,
|
|
2035
|
+
codexHomeDir,
|
|
2036
|
+
});
|
|
2037
|
+
if (!canonicalShimPath)
|
|
2038
|
+
return currentPostCompactCommandCheck();
|
|
2039
|
+
const expectedShimContent = Buffer.from(buildManagedCodexNativeHookWindowsShimContent(getPackageRoot()), "utf-8");
|
|
2040
|
+
const inMemoryInvocation = buildInMemoryWindowsShimSmokeInvocation(expectedShimContent);
|
|
2041
|
+
if (!inMemoryInvocation)
|
|
2042
|
+
return inMemoryWindowsShimSmokeCheck();
|
|
2043
|
+
smokeInvocation = inMemoryInvocation;
|
|
2044
|
+
try {
|
|
2045
|
+
await options.beforeWindowsShimSmoke?.({ canonicalShimPath, smokeCwd });
|
|
2046
|
+
}
|
|
2047
|
+
catch {
|
|
2048
|
+
return smokeDirectorySafetyCheck("Windows native hook changed during validation; doctor skipped execution for safety");
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
else {
|
|
2052
|
+
smokeInvocation = buildPostCompactSmokeSpawnInvocation(expectedCommand, { platform });
|
|
2053
|
+
}
|
|
2054
|
+
if (!sameSmokeDirectoryIdentity(smokeDirectory, await readSmokeDirectoryIdentity(smokeCwd))) {
|
|
2055
|
+
return smokeDirectorySafetyCheck("temporary PostCompact smoke directory changed during validation; doctor preserved it for manual recovery and skipped execution for safety");
|
|
2056
|
+
}
|
|
2057
|
+
const payload = JSON.stringify({
|
|
2058
|
+
hook_event_name: "PostCompact",
|
|
2059
|
+
cwd: smokeCwd,
|
|
2060
|
+
session_id: "omx-doctor-postcompact-smoke",
|
|
2061
|
+
});
|
|
2062
|
+
const result = (options.runner ?? spawnSync)(smokeInvocation.command, smokeInvocation.args, {
|
|
2063
|
+
cwd,
|
|
2064
|
+
encoding: "utf-8",
|
|
2065
|
+
env: {
|
|
2066
|
+
...process.env,
|
|
2067
|
+
OMX_NATIVE_HOOK_DOCTOR_SMOKE: "1",
|
|
2068
|
+
OMX_ROOT: smokeCwd,
|
|
2069
|
+
OMX_SESSION_ID: "omx-doctor-postcompact-smoke",
|
|
2070
|
+
OMX_SOURCE_CWD: smokeCwd,
|
|
2071
|
+
OMX_STARTUP_CWD: smokeCwd,
|
|
2072
|
+
},
|
|
2073
|
+
input: payload,
|
|
2074
|
+
shell: smokeInvocation.shell,
|
|
2075
|
+
timeout: 5_000,
|
|
2076
|
+
});
|
|
2077
|
+
if (result.error) {
|
|
2078
|
+
return {
|
|
2079
|
+
name: "Native PostCompact hook",
|
|
2080
|
+
status: "fail",
|
|
2081
|
+
message: `PostCompact hook smoke validation failed to run (${result.error.message})`,
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2084
|
+
if (result.status !== 0) {
|
|
2085
|
+
const stderr = (result.stderr || "").trim();
|
|
2086
|
+
return {
|
|
2087
|
+
name: "Native PostCompact hook",
|
|
2088
|
+
status: "fail",
|
|
2089
|
+
message: `PostCompact hook smoke validation exited ${result.status}${stderr ? `: ${stderr}` : ""}`,
|
|
2090
|
+
};
|
|
2091
|
+
}
|
|
2092
|
+
const stdoutCheck = classifyPostCompactHookStdout(result.stdout || "");
|
|
2093
|
+
if (stdoutCheck)
|
|
2094
|
+
return stdoutCheck;
|
|
1638
2095
|
return {
|
|
1639
2096
|
name: "Native PostCompact hook",
|
|
1640
|
-
status: "
|
|
1641
|
-
message:
|
|
2097
|
+
status: "pass",
|
|
2098
|
+
message: "verbose smoke validation confirmed the effective PostCompact hook exits successfully with no stdout",
|
|
1642
2099
|
};
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
name: "Native PostCompact hook",
|
|
1649
|
-
status: "pass",
|
|
1650
|
-
message: "verbose smoke validation confirmed the effective PostCompact hook exits successfully with no stdout",
|
|
1651
|
-
};
|
|
2100
|
+
})();
|
|
2101
|
+
}
|
|
2102
|
+
catch (error) {
|
|
2103
|
+
primaryError = error instanceof Error ? error : new Error(String(error));
|
|
2104
|
+
throw primaryError;
|
|
1652
2105
|
}
|
|
1653
2106
|
finally {
|
|
1654
|
-
await
|
|
2107
|
+
const cleanupCheck = await cleanupSmokeDirectoryIfUnchanged(smokeCwd, smokeDirectory);
|
|
2108
|
+
if (cleanupCheck) {
|
|
2109
|
+
if (primaryResult) {
|
|
2110
|
+
if (primaryResult.status === "pass")
|
|
2111
|
+
primaryResult.status = cleanupCheck.status;
|
|
2112
|
+
primaryResult.message = `${primaryResult.message}; ${cleanupCheck.message}`;
|
|
2113
|
+
}
|
|
2114
|
+
else if (primaryError) {
|
|
2115
|
+
primaryError.message = `${primaryError.message}; ${cleanupCheck.message}`;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
1655
2118
|
}
|
|
2119
|
+
return primaryResult;
|
|
1656
2120
|
}
|
|
1657
2121
|
async function checkNativeHookRuntimeMirrors(cwd, hooksPath) {
|
|
1658
2122
|
if (!existsSync(hooksPath))
|