oh-my-codex 0.20.0 → 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 +27 -0
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-context-window-warning.test.js +83 -78
- package/dist/cli/__tests__/doctor-context-window-warning.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-invalid-config.test.js +56 -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 +735 -14
- 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 +131 -5
- 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 +2264 -17
- 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 +168 -5
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-scope.test.js +73 -6
- 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 +2067 -26
- 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 +20 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +636 -161
- 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 +1403 -400
- 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 +947 -99
- 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 +1049 -135
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +28 -49
- 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 +40 -26
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +1159 -288
- 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 +146 -2
- 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 +131 -7
- 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 +5414 -801
- 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 +825 -172
- 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/__tests__/agents-md.test.js +16 -0
- package/dist/utils/__tests__/agents-md.test.js.map +1 -1
- package/dist/utils/agents-md.d.ts.map +1 -1
- package/dist/utils/agents-md.js +4 -3
- package/dist/utils/agents-md.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 +20497 -12377
- 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 +918 -172
- 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";
|
|
@@ -12,8 +13,8 @@ import { getCatalogExpectations } from "./catalog-contract.js";
|
|
|
12
13
|
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
|
-
import {
|
|
16
|
-
import { MANAGED_HOOK_EVENTS, buildManagedCodexNativeHookCommand, discoverCodexHookConfigPaths,
|
|
16
|
+
import { analyzeLegacyMultiAgentConfig, hasExactOmxSeededBehavioralDefaultsPair, hasLegacyOmxTeamRunTable, } from "../config/generator.js";
|
|
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"
|
|
@@ -170,19 +172,26 @@ export async function doctor(options = {}) {
|
|
|
170
172
|
// Check 3: Codex home directory
|
|
171
173
|
checks.push(checkDirectory("Codex home", paths.codexHomeDir));
|
|
172
174
|
// Check 4: Config file
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
checks.push(
|
|
175
|
+
const configCheck = await checkConfig(paths.configPath);
|
|
176
|
+
checks.push(configCheck);
|
|
177
|
+
const multiAgentCompatibilityCheck = await checkLegacyMultiAgentCompatibility(paths.configPath, scopeResolution.scope);
|
|
178
|
+
if (multiAgentCompatibilityCheck)
|
|
179
|
+
checks.push(multiAgentCompatibilityCheck);
|
|
180
|
+
// Check 4.1: unchanged OMX-seeded context defaults
|
|
181
|
+
if (configCheck.status !== "fail") {
|
|
182
|
+
const seededContextDefaultsCheck = await checkSeededContextDefaults(paths.configPath);
|
|
183
|
+
if (seededContextDefaultsCheck)
|
|
184
|
+
checks.push(seededContextDefaultsCheck);
|
|
185
|
+
}
|
|
178
186
|
// Check 4.25: Native hooks coverage
|
|
179
|
-
|
|
187
|
+
const nativeHooksCheck = await checkNativeHooks(paths.hooksPath, paths.configPath, {
|
|
180
188
|
codexHomeDir: paths.codexHomeDir,
|
|
181
189
|
installMode: scopeResolution.installMode,
|
|
182
|
-
})
|
|
190
|
+
});
|
|
191
|
+
checks.push(nativeHooksCheck);
|
|
183
192
|
checks.push(await checkNativeHookDistSmoke());
|
|
184
193
|
if (options.verbose) {
|
|
185
|
-
const postCompactRuntimeCheck = await checkNativePostCompactHookRuntime(paths.hooksPath, cwd, paths.codexHomeDir);
|
|
194
|
+
const postCompactRuntimeCheck = await checkNativePostCompactHookRuntime(paths.hooksPath, cwd, paths.codexHomeDir, { nativeHooksCheck });
|
|
186
195
|
if (postCompactRuntimeCheck)
|
|
187
196
|
checks.push(postCompactRuntimeCheck);
|
|
188
197
|
}
|
|
@@ -243,10 +252,10 @@ export async function doctor(options = {}) {
|
|
|
243
252
|
}
|
|
244
253
|
console.log(`\nResults: ${passCount} passed, ${warnCount} warnings, ${failCount} failed`);
|
|
245
254
|
if (failCount > 0) {
|
|
246
|
-
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.');
|
|
247
256
|
}
|
|
248
257
|
else if (warnCount > 0) {
|
|
249
|
-
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".');
|
|
250
259
|
}
|
|
251
260
|
else {
|
|
252
261
|
console.log("\nAll checks passed! oh-my-codex is ready.");
|
|
@@ -854,6 +863,32 @@ function validateToml(content) {
|
|
|
854
863
|
return "unknown TOML parse error";
|
|
855
864
|
}
|
|
856
865
|
}
|
|
866
|
+
export async function checkLegacyMultiAgentCompatibility(configPath, scope) {
|
|
867
|
+
if (!existsSync(configPath))
|
|
868
|
+
return null;
|
|
869
|
+
try {
|
|
870
|
+
const content = await readFile(configPath, "utf-8");
|
|
871
|
+
if (validateToml(content))
|
|
872
|
+
return null;
|
|
873
|
+
const affected = Object.values(analyzeLegacyMultiAgentConfig(content).assessments).filter((assessment) => assessment.state !== "absent");
|
|
874
|
+
if (affected.length === 0)
|
|
875
|
+
return null;
|
|
876
|
+
const details = affected
|
|
877
|
+
.map(({ key, state, reasonCode }) => `${key} (${state}; ${reasonCode})`)
|
|
878
|
+
.join(", ");
|
|
879
|
+
return {
|
|
880
|
+
name: "GPT-5.6 multi-agent compatibility",
|
|
881
|
+
status: "warn",
|
|
882
|
+
message: `${scope} scope config at ${configPath}: ${details}. ` +
|
|
883
|
+
"OMX preserves these settings because historical ownership cannot be proven. " +
|
|
884
|
+
`Back up ${configPath}, remove only keys you confirm OMX authored, rerun omx setup --scope ${scope}, then omx doctor. ` +
|
|
885
|
+
"Setup does not auto-delete them.",
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
catch {
|
|
889
|
+
return null;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
857
892
|
async function checkConfig(configPath) {
|
|
858
893
|
if (!existsSync(configPath)) {
|
|
859
894
|
return { name: "Config", status: "warn", message: "config.toml not found" };
|
|
@@ -902,38 +937,17 @@ async function checkConfig(configPath) {
|
|
|
902
937
|
};
|
|
903
938
|
}
|
|
904
939
|
}
|
|
905
|
-
function
|
|
906
|
-
return `${configuredValues.join(", ")} exceeds the OMX setup recommendation for gpt-5.6-sol (${recommendedContextWindow} / ${recommendedAutoCompactLimit}); doctor does not rewrite user config, so lower these values or verify your active Codex runtime/provider behavior if this customization is intentional`;
|
|
907
|
-
}
|
|
908
|
-
async function checkModelContextRecommendation(configPath) {
|
|
940
|
+
async function checkSeededContextDefaults(configPath) {
|
|
909
941
|
if (!existsSync(configPath))
|
|
910
942
|
return null;
|
|
911
943
|
try {
|
|
912
944
|
const content = await readFile(configPath, "utf-8");
|
|
913
|
-
|
|
914
|
-
const model = parsed.model;
|
|
915
|
-
if (typeof model !== "string")
|
|
916
|
-
return null;
|
|
917
|
-
const recommendation = getModelContextRecommendation(model);
|
|
918
|
-
if (!recommendation)
|
|
919
|
-
return null;
|
|
920
|
-
const configuredValues = [];
|
|
921
|
-
const contextWindow = parsed.model_context_window;
|
|
922
|
-
if (typeof contextWindow === "number" &&
|
|
923
|
-
contextWindow > recommendation.modelContextWindow) {
|
|
924
|
-
configuredValues.push(`model_context_window=${contextWindow}`);
|
|
925
|
-
}
|
|
926
|
-
const autoCompactLimit = parsed.model_auto_compact_token_limit;
|
|
927
|
-
if (typeof autoCompactLimit === "number" &&
|
|
928
|
-
autoCompactLimit > recommendation.modelAutoCompactTokenLimit) {
|
|
929
|
-
configuredValues.push(`model_auto_compact_token_limit=${autoCompactLimit}`);
|
|
930
|
-
}
|
|
931
|
-
if (configuredValues.length === 0)
|
|
945
|
+
if (!hasExactOmxSeededBehavioralDefaultsPair(content))
|
|
932
946
|
return null;
|
|
933
947
|
return {
|
|
934
|
-
name: "
|
|
948
|
+
name: "Legacy OMX context defaults",
|
|
935
949
|
status: "warn",
|
|
936
|
-
message:
|
|
950
|
+
message: "config.toml contains unchanged OMX-seeded context defaults; rerun \"omx setup\" to migrate them. Doctor did not rewrite config.",
|
|
937
951
|
};
|
|
938
952
|
}
|
|
939
953
|
catch {
|
|
@@ -1218,6 +1232,183 @@ function configEnablesPluginScopedHooks(configContent) {
|
|
|
1218
1232
|
return /^\s*plugin_hooks\s*=\s*(?:true|1|"true"|"1"|"yes"|"on")\s*$/m.test(configContent);
|
|
1219
1233
|
}
|
|
1220
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
|
+
}
|
|
1221
1412
|
function pluginHooksJsonHasNativeCoverage(content) {
|
|
1222
1413
|
try {
|
|
1223
1414
|
const parsed = JSON.parse(content);
|
|
@@ -1249,7 +1440,7 @@ function pluginHooksJsonHasNativeCoverage(content) {
|
|
|
1249
1440
|
}
|
|
1250
1441
|
async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
1251
1442
|
const setupHooksPathDescription = existsSync(setupHooksPath)
|
|
1252
|
-
? `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`
|
|
1253
1444
|
: `setup-owned hooks.json is intentionally absent at ${setupHooksPath}`;
|
|
1254
1445
|
const packagedMarketplace = await resolvePackagedOmxMarketplace(getPackageRoot());
|
|
1255
1446
|
if (!packagedMarketplace) {
|
|
@@ -1271,14 +1462,14 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1271
1462
|
return {
|
|
1272
1463
|
name: "Native hooks",
|
|
1273
1464
|
status: "warn",
|
|
1274
|
-
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`,
|
|
1275
1466
|
};
|
|
1276
1467
|
}
|
|
1277
1468
|
if (state.hooksPointer !== "./hooks/hooks.json") {
|
|
1278
1469
|
return {
|
|
1279
1470
|
name: "Native hooks",
|
|
1280
1471
|
status: "warn",
|
|
1281
|
-
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`,
|
|
1282
1473
|
};
|
|
1283
1474
|
}
|
|
1284
1475
|
for (const expectedPath of [expectedHooksPath, expectedHookLauncherPath, expectedPinnedLauncherPath]) {
|
|
@@ -1286,7 +1477,7 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1286
1477
|
return {
|
|
1287
1478
|
name: "Native hooks",
|
|
1288
1479
|
status: "warn",
|
|
1289
|
-
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`,
|
|
1290
1481
|
};
|
|
1291
1482
|
}
|
|
1292
1483
|
}
|
|
@@ -1294,7 +1485,7 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1294
1485
|
return {
|
|
1295
1486
|
name: "Native hooks",
|
|
1296
1487
|
status: "warn",
|
|
1297
|
-
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`,
|
|
1298
1489
|
};
|
|
1299
1490
|
}
|
|
1300
1491
|
let hookContent;
|
|
@@ -1320,7 +1511,7 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1320
1511
|
return {
|
|
1321
1512
|
name: "Native hooks",
|
|
1322
1513
|
status: "warn",
|
|
1323
|
-
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`,
|
|
1324
1515
|
};
|
|
1325
1516
|
}
|
|
1326
1517
|
const smokeCwd = await mkdtemp(join(tmpdir(), "omx-doctor-plugin-hook-"));
|
|
@@ -1373,12 +1564,145 @@ async function checkPluginScopedNativeHooks(codexHomeDir, setupHooksPath) {
|
|
|
1373
1564
|
message: `plugin-scoped hooks are enabled; ${setupHooksPathDescription}, and plugin cache native hook coverage smoke passed via ${expectedHooksPath}`,
|
|
1374
1565
|
};
|
|
1375
1566
|
}
|
|
1376
|
-
|
|
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) {
|
|
1377
1698
|
if (existsSync(configPath) && context.installMode === "plugin") {
|
|
1378
1699
|
try {
|
|
1379
1700
|
const configContent = await readFile(configPath, "utf-8");
|
|
1380
1701
|
if (configEnablesPluginScopedHooks(configContent)) {
|
|
1381
|
-
|
|
1702
|
+
const globalCheck = existsSync(hooksPath)
|
|
1703
|
+
? await checkExistingNativeHooks(hooksPath, context)
|
|
1704
|
+
: null;
|
|
1705
|
+
return combinePluginAndGlobalNativeHookChecks(await checkPluginScopedNativeHooks(context.codexHomeDir, hooksPath), globalCheck);
|
|
1382
1706
|
}
|
|
1383
1707
|
}
|
|
1384
1708
|
catch {
|
|
@@ -1390,25 +1714,23 @@ async function checkNativeHooks(hooksPath, configPath, context) {
|
|
|
1390
1714
|
if (existsSync(configPath)) {
|
|
1391
1715
|
try {
|
|
1392
1716
|
const configContent = await readFile(configPath, "utf-8");
|
|
1393
|
-
if (context.installMode === "plugin") {
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
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
|
+
};
|
|
1401
1723
|
}
|
|
1402
1724
|
if (configHasOmxEntries(configContent)) {
|
|
1403
1725
|
return {
|
|
1404
1726
|
name: "Native hooks",
|
|
1405
1727
|
status: "warn",
|
|
1406
|
-
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`,
|
|
1407
1729
|
};
|
|
1408
1730
|
}
|
|
1409
1731
|
}
|
|
1410
1732
|
catch {
|
|
1411
|
-
//
|
|
1733
|
+
// Fall through to the neutral first-setup path when config cannot be read here;
|
|
1412
1734
|
// the dedicated config check will report read failures separately.
|
|
1413
1735
|
}
|
|
1414
1736
|
}
|
|
@@ -1418,66 +1740,18 @@ async function checkNativeHooks(hooksPath, configPath, context) {
|
|
|
1418
1740
|
message: "hooks.json not found yet (expected before first setup)",
|
|
1419
1741
|
};
|
|
1420
1742
|
}
|
|
1421
|
-
|
|
1422
|
-
const content = await readFile(hooksPath, "utf-8");
|
|
1423
|
-
const missingEvents = getMissingManagedCodexHookEvents(content);
|
|
1424
|
-
if (missingEvents === null) {
|
|
1425
|
-
return {
|
|
1426
|
-
name: "Native hooks",
|
|
1427
|
-
status: "fail",
|
|
1428
|
-
message: 'invalid hooks.json; Codex may skip OMX hook coverage until "omx setup --force" repairs it',
|
|
1429
|
-
};
|
|
1430
|
-
}
|
|
1431
|
-
const hasTopLevelState = hasCodexHooksJsonTopLevelState(content);
|
|
1432
|
-
if (hasTopLevelState === true) {
|
|
1433
|
-
return {
|
|
1434
|
-
name: "Native hooks",
|
|
1435
|
-
status: "fail",
|
|
1436
|
-
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',
|
|
1437
|
-
};
|
|
1438
|
-
}
|
|
1439
|
-
if (missingEvents.length > 0) {
|
|
1440
|
-
return {
|
|
1441
|
-
name: "Native hooks",
|
|
1442
|
-
status: "warn",
|
|
1443
|
-
message: `hooks.json is missing OMX-managed coverage for ${missingEvents.join(", ")}; run "omx setup --force" to restore native hooks`,
|
|
1444
|
-
};
|
|
1445
|
-
}
|
|
1446
|
-
return {
|
|
1447
|
-
name: "Native hooks",
|
|
1448
|
-
status: "pass",
|
|
1449
|
-
message: "hooks.json includes OMX-managed coverage for all native hook events",
|
|
1450
|
-
};
|
|
1451
|
-
}
|
|
1452
|
-
catch {
|
|
1453
|
-
return {
|
|
1454
|
-
name: "Native hooks",
|
|
1455
|
-
status: "fail",
|
|
1456
|
-
message: "cannot read hooks.json",
|
|
1457
|
-
};
|
|
1458
|
-
}
|
|
1743
|
+
return checkExistingNativeHooks(hooksPath, context);
|
|
1459
1744
|
}
|
|
1460
1745
|
export async function checkNativeHookDistSmoke(options = {}) {
|
|
1461
1746
|
const packageRoot = options.packageRoot ?? getPackageRoot();
|
|
1462
1747
|
const nodePath = options.nodePath ?? process.execPath;
|
|
1463
1748
|
const runner = options.runner ?? spawnSync;
|
|
1464
1749
|
const scriptPath = join(packageRoot, "dist", "scripts", "codex-native-hook.js");
|
|
1465
|
-
const packageJsonPath = join(packageRoot, "package.json");
|
|
1466
|
-
let packageVersion = "current";
|
|
1467
|
-
try {
|
|
1468
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
1469
|
-
if (typeof packageJson.version === "string" && packageJson.version.trim()) {
|
|
1470
|
-
packageVersion = packageJson.version.trim();
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
catch {
|
|
1474
|
-
// Keep the generic recovery copy when package metadata is not readable.
|
|
1475
|
-
}
|
|
1476
1750
|
if (!existsSync(scriptPath)) {
|
|
1477
1751
|
return {
|
|
1478
1752
|
name: "Native hook dist smoke",
|
|
1479
1753
|
status: "fail",
|
|
1480
|
-
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"`,
|
|
1481
1755
|
};
|
|
1482
1756
|
}
|
|
1483
1757
|
const smokeCwd = await mkdtemp(join(tmpdir(), "omx-doctor-native-hook-dist-"));
|
|
@@ -1507,7 +1781,7 @@ export async function checkNativeHookDistSmoke(options = {}) {
|
|
|
1507
1781
|
return {
|
|
1508
1782
|
name: "Native hook dist smoke",
|
|
1509
1783
|
status: "fail",
|
|
1510
|
-
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"`,
|
|
1511
1785
|
};
|
|
1512
1786
|
}
|
|
1513
1787
|
if (result.status !== 0) {
|
|
@@ -1517,7 +1791,7 @@ export async function checkNativeHookDistSmoke(options = {}) {
|
|
|
1517
1791
|
return {
|
|
1518
1792
|
name: "Native hook dist smoke",
|
|
1519
1793
|
status: "fail",
|
|
1520
|
-
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"`,
|
|
1521
1795
|
};
|
|
1522
1796
|
}
|
|
1523
1797
|
return {
|
|
@@ -1539,14 +1813,14 @@ export function classifyPostCompactHookStdout(stdout) {
|
|
|
1539
1813
|
return {
|
|
1540
1814
|
name: "Native PostCompact hook",
|
|
1541
1815
|
status: "fail",
|
|
1542
|
-
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",
|
|
1543
1817
|
};
|
|
1544
1818
|
}
|
|
1545
1819
|
catch (error) {
|
|
1546
1820
|
return {
|
|
1547
1821
|
name: "Native PostCompact hook",
|
|
1548
1822
|
status: "fail",
|
|
1549
|
-
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`,
|
|
1550
1824
|
};
|
|
1551
1825
|
}
|
|
1552
1826
|
}
|
|
@@ -1571,77 +1845,278 @@ export function buildPostCompactSmokeSpawnInvocation(expectedCommand, options =
|
|
|
1571
1845
|
shell: true,
|
|
1572
1846
|
};
|
|
1573
1847
|
}
|
|
1574
|
-
|
|
1575
|
-
|
|
1848
|
+
function buildInMemoryWindowsShimSmokeInvocation(expectedShimContent, options = {}) {
|
|
1849
|
+
const shimSource = decodeStrictUtf8(expectedShimContent);
|
|
1850
|
+
if (shimSource === null)
|
|
1576
1851
|
return null;
|
|
1577
|
-
|
|
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) {
|
|
1578
1880
|
try {
|
|
1579
|
-
|
|
1881
|
+
return smokeDirectoryIdentity(await lstat(smokeCwd));
|
|
1580
1882
|
}
|
|
1581
1883
|
catch {
|
|
1582
1884
|
return null;
|
|
1583
1885
|
}
|
|
1584
|
-
|
|
1585
|
-
|
|
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);
|
|
1586
1905
|
return null;
|
|
1587
1906
|
}
|
|
1588
|
-
|
|
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(), {
|
|
1589
1955
|
codexHomeDir,
|
|
1956
|
+
platform,
|
|
1590
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;
|
|
1591
1970
|
const uniqueCommands = [...new Set(postCompactCommands)];
|
|
1592
1971
|
if (uniqueCommands.length !== 1 || uniqueCommands[0] !== expectedCommand) {
|
|
1593
|
-
return
|
|
1594
|
-
name: "Native PostCompact hook",
|
|
1595
|
-
status: "warn",
|
|
1596
|
-
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",
|
|
1597
|
-
};
|
|
1972
|
+
return currentPostCompactCommandCheck();
|
|
1598
1973
|
}
|
|
1599
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;
|
|
1600
1981
|
try {
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
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;
|
|
1627
2095
|
return {
|
|
1628
2096
|
name: "Native PostCompact hook",
|
|
1629
|
-
status: "
|
|
1630
|
-
message:
|
|
2097
|
+
status: "pass",
|
|
2098
|
+
message: "verbose smoke validation confirmed the effective PostCompact hook exits successfully with no stdout",
|
|
1631
2099
|
};
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
name: "Native PostCompact hook",
|
|
1638
|
-
status: "pass",
|
|
1639
|
-
message: "verbose smoke validation confirmed the effective PostCompact hook exits successfully with no stdout",
|
|
1640
|
-
};
|
|
2100
|
+
})();
|
|
2101
|
+
}
|
|
2102
|
+
catch (error) {
|
|
2103
|
+
primaryError = error instanceof Error ? error : new Error(String(error));
|
|
2104
|
+
throw primaryError;
|
|
1641
2105
|
}
|
|
1642
2106
|
finally {
|
|
1643
|
-
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
|
+
}
|
|
1644
2118
|
}
|
|
2119
|
+
return primaryResult;
|
|
1645
2120
|
}
|
|
1646
2121
|
async function checkNativeHookRuntimeMirrors(cwd, hooksPath) {
|
|
1647
2122
|
if (!existsSync(hooksPath))
|