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
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { describe, it } from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { cp, mkdir, mkdtemp, readFile, rm, symlink, writeFile, } from "node:fs/promises";
|
|
4
|
-
import { existsSync } from "node:fs";
|
|
3
|
+
import { cp, link, mkdir, mkdtemp, realpath, readFile, rename, rm, symlink, writeFile, } from "node:fs/promises";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { join, dirname } from "node:path";
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
import { spawnSync } from "node:child_process";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { withPackagedExploreHarnessHidden, withPackagedExploreHarnessLock, } from "./packaged-explore-harness-lock.js";
|
|
10
|
-
import {
|
|
11
|
-
import { buildManagedCodexNativeHookCommand } from "../../config/codex-hooks.js";
|
|
10
|
+
import { buildPostCompactSmokeSpawnInvocation, checkExternalCodexProcessGuards, checkExploreHarness, checkLegacyMultiAgentCompatibility, checkNativeHookDistSmoke, checkNativePostCompactHookRuntime, checkNativeHooks, classifyPostCompactHookStdout, } from "../doctor.js";
|
|
11
|
+
import { buildManagedCodexNativeHookCommand, buildManagedCodexNativeHookWindowsShimContent, } from "../../config/codex-hooks.js";
|
|
12
12
|
const MANAGED_HOOK_EVENTS = [
|
|
13
13
|
"SessionStart",
|
|
14
14
|
"PreToolUse",
|
|
@@ -54,6 +54,13 @@ function currentNativeHookCommand(codexHomeDir) {
|
|
|
54
54
|
codexHomeDir,
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
+
function buildWindowsShimCommand(shimPath) {
|
|
58
|
+
return `& 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe' -NoProfile -ExecutionPolicy Bypass -File '${shimPath.replace(/'/g, "''")}'`;
|
|
59
|
+
}
|
|
60
|
+
function buildWindowsShimHooksJson(shimPath, codexHomeDir) {
|
|
61
|
+
const command = buildWindowsShimCommand(shimPath);
|
|
62
|
+
return buildHooksJsonWithPostCompactCommand(command, codexHomeDir, command);
|
|
63
|
+
}
|
|
57
64
|
async function installPluginCacheFixture(codexDir) {
|
|
58
65
|
const root = repoRoot();
|
|
59
66
|
const sourcePluginDir = join(root, "plugins", "oh-my-codex");
|
|
@@ -77,8 +84,7 @@ async function packagedPluginVersion() {
|
|
|
77
84
|
}
|
|
78
85
|
return manifest.version;
|
|
79
86
|
}
|
|
80
|
-
function buildHooksJsonWithPostCompactCommand(postCompactCommand, codexHomeDir) {
|
|
81
|
-
const expectedCommand = currentNativeHookCommand(codexHomeDir);
|
|
87
|
+
function buildHooksJsonWithPostCompactCommand(postCompactCommand, codexHomeDir, expectedCommand = currentNativeHookCommand(codexHomeDir)) {
|
|
82
88
|
return `${JSON.stringify({
|
|
83
89
|
hooks: Object.fromEntries(MANAGED_HOOK_EVENTS.map((eventName) => [
|
|
84
90
|
eventName,
|
|
@@ -891,7 +897,7 @@ OMX_LORE_COMMIT_GUARD = "truee"
|
|
|
891
897
|
return;
|
|
892
898
|
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
893
899
|
assert.doesNotMatch(res.stdout, /Resolved setup install mode: plugin \(inferred from Codex plugin config\)/);
|
|
894
|
-
assert.match(res.stdout, /Native hooks: expected setup-owned hooks\.json is missing at .*\.codex[\\/]+hooks\.json even though config\.toml has OMX entries; run "omx setup
|
|
900
|
+
assert.match(res.stdout, /Native hooks: expected setup-owned hooks\.json is missing at .*\.codex[\\/]+hooks\.json even though config\.toml has OMX entries; run "omx setup" to restore native hook coverage/);
|
|
895
901
|
assert.match(res.stdout, /Prompts: prompts directory not found/);
|
|
896
902
|
}
|
|
897
903
|
finally {
|
|
@@ -1144,7 +1150,7 @@ OMX_LORE_COMMIT_GUARD = "truee"
|
|
|
1144
1150
|
if (shouldSkipForSpawnPermissions(res.error))
|
|
1145
1151
|
return;
|
|
1146
1152
|
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1147
|
-
assert.match(res.stdout, new RegExp(`\\[!!\\] Native hooks: plugin-scoped hooks are enabled, but cached plugin hook files or pinned hook launcher in ${cacheDir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")} do not match the packaged plugin; setup-owned hooks\\.json is intentionally absent at .*\\.codex[\\/]+hooks\\.json; run "omx setup --plugin
|
|
1153
|
+
assert.match(res.stdout, new RegExp(`\\[!!\\] Native hooks: plugin-scoped hooks are enabled, but cached plugin hook files or pinned hook launcher in ${cacheDir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")} do not match the packaged plugin; setup-owned hooks\\.json is intentionally absent at .*\\.codex[\\/]+hooks\\.json; run "omx setup --plugin" to refresh the plugin cache`));
|
|
1148
1154
|
assert.doesNotMatch(res.stdout, /plugin cache native hook coverage smoke passed/);
|
|
1149
1155
|
}
|
|
1150
1156
|
finally {
|
|
@@ -1194,7 +1200,7 @@ OMX_LORE_COMMIT_GUARD = "truee"
|
|
|
1194
1200
|
if (shouldSkipForSpawnPermissions(res.error))
|
|
1195
1201
|
return;
|
|
1196
1202
|
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1197
|
-
assert.match(res.stdout, new RegExp(`\\[OK\\] Native hooks: plugin-scoped hooks are enabled; existing hooks\\.json at .*\\.codex[\\/]+hooks\\.json is
|
|
1203
|
+
assert.match(res.stdout, new RegExp(`\\[OK\\] Native hooks: plugin-scoped hooks are enabled; existing hooks\\.json at .*\\.codex[\\/]+hooks\\.json is retained read-only and validated separately because plugin-scoped hooks are enabled, and plugin cache native hook coverage smoke passed via ${join(cacheDir, "hooks", "hooks.json").replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`));
|
|
1198
1204
|
assert.doesNotMatch(res.stdout, /hooks\.json is missing OMX-managed coverage/);
|
|
1199
1205
|
assert.doesNotMatch(res.stdout, /run "omx setup --force" to restore native hooks/);
|
|
1200
1206
|
}
|
|
@@ -1229,7 +1235,7 @@ OMX_LORE_COMMIT_GUARD = "truee"
|
|
|
1229
1235
|
if (shouldSkipForSpawnPermissions(res.error))
|
|
1230
1236
|
return;
|
|
1231
1237
|
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1232
|
-
assert.match(res.stdout, /Native hooks: hooks\.json is missing OMX-managed coverage for PreToolUse, PostToolUse, UserPromptSubmit, PreCompact, PostCompact, Stop; run "omx setup
|
|
1238
|
+
assert.match(res.stdout, /Native hooks: hooks\.json is missing OMX-managed coverage for PreToolUse, PostToolUse, UserPromptSubmit, PreCompact, PostCompact, Stop; run "omx setup" to restore native hooks/);
|
|
1233
1239
|
}
|
|
1234
1240
|
finally {
|
|
1235
1241
|
await rm(wd, { recursive: true, force: true });
|
|
@@ -1289,7 +1295,7 @@ command = "node"
|
|
|
1289
1295
|
if (shouldSkipForSpawnPermissions(res.error))
|
|
1290
1296
|
return;
|
|
1291
1297
|
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1292
|
-
assert.match(res.stdout, /Native hooks: expected setup-owned hooks\.json is missing at .*\.codex[\/]+hooks\.json even though config\.toml has OMX entries; run "omx setup
|
|
1298
|
+
assert.match(res.stdout, /Native hooks: expected setup-owned hooks\.json is missing at .*\.codex[\/]+hooks\.json even though config\.toml has OMX entries; run "omx setup" to restore native hook coverage/);
|
|
1293
1299
|
}
|
|
1294
1300
|
finally {
|
|
1295
1301
|
await rm(wd, { recursive: true, force: true });
|
|
@@ -1309,7 +1315,508 @@ command = "node"
|
|
|
1309
1315
|
if (shouldSkipForSpawnPermissions(res.error))
|
|
1310
1316
|
return;
|
|
1311
1317
|
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1312
|
-
assert.match(res.stdout, /\[XX\] Native hooks:
|
|
1318
|
+
assert.match(res.stdout, /\[XX\] Native hooks: hooks\.json failed strict load validation \(invalid_document\): hooks\.json must contain a JSON object; inspect the file manually because doctor will not modify it/);
|
|
1319
|
+
}
|
|
1320
|
+
finally {
|
|
1321
|
+
await rm(wd, { recursive: true, force: true });
|
|
1322
|
+
}
|
|
1323
|
+
});
|
|
1324
|
+
it("reports matcher-aware discovery warnings without touching hooks.json", async () => {
|
|
1325
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-hooks-matcher-warning-"));
|
|
1326
|
+
try {
|
|
1327
|
+
const home = join(wd, "home");
|
|
1328
|
+
const codexDir = join(home, ".codex");
|
|
1329
|
+
await mkdir(codexDir, { recursive: true });
|
|
1330
|
+
await writeFile(join(codexDir, "hooks.json"), JSON.stringify({
|
|
1331
|
+
hooks: {
|
|
1332
|
+
SessionStart: [{
|
|
1333
|
+
matcher: "[",
|
|
1334
|
+
hooks: [{ type: "command", command: "echo user-owned" }],
|
|
1335
|
+
}],
|
|
1336
|
+
},
|
|
1337
|
+
}, null, 2) + "\n");
|
|
1338
|
+
const res = runOmx(wd, ["doctor"], { HOME: home, CODEX_HOME: codexDir });
|
|
1339
|
+
if (shouldSkipForSpawnPermissions(res.error))
|
|
1340
|
+
return;
|
|
1341
|
+
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1342
|
+
assert.match(res.stdout, /Native hooks: hooks\.json discovery warnings: SessionStart\[0\]: Codex skips groups whose matcher is not a valid regular expression; Codex may ignore the listed entries, and doctor will not modify them/);
|
|
1343
|
+
assert.doesNotMatch(res.stdout, /Native hooks:.*--force/);
|
|
1344
|
+
}
|
|
1345
|
+
finally {
|
|
1346
|
+
await rm(wd, { recursive: true, force: true });
|
|
1347
|
+
}
|
|
1348
|
+
});
|
|
1349
|
+
it("treats UserPromptSubmit and Stop matcher groups as valid foreign survivors", async () => {
|
|
1350
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-hooks-foreign-survivors-"));
|
|
1351
|
+
try {
|
|
1352
|
+
const home = join(wd, "home");
|
|
1353
|
+
const codexDir = join(home, ".codex");
|
|
1354
|
+
await mkdir(codexDir, { recursive: true });
|
|
1355
|
+
await writeFile(join(codexDir, "hooks.json"), JSON.stringify({
|
|
1356
|
+
hooks: {
|
|
1357
|
+
UserPromptSubmit: [{ matcher: "[", hooks: [{ type: "command", command: "echo prompt" }] }],
|
|
1358
|
+
Stop: [{ matcher: "[", hooks: [{ type: "command", command: "echo stop" }] }],
|
|
1359
|
+
},
|
|
1360
|
+
}, null, 2) + "\n");
|
|
1361
|
+
const res = runOmx(wd, ["doctor"], { HOME: home, CODEX_HOME: codexDir });
|
|
1362
|
+
if (shouldSkipForSpawnPermissions(res.error))
|
|
1363
|
+
return;
|
|
1364
|
+
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1365
|
+
assert.match(res.stdout, /\[OK\] Native hooks: hooks\.json contains valid foreign hook entries and no OMX-managed wrappers; doctor will preserve the user-owned configuration/);
|
|
1366
|
+
assert.doesNotMatch(res.stdout, /hooks\.json discovery warnings/);
|
|
1367
|
+
assert.doesNotMatch(res.stdout, /Native hooks:.*--force/);
|
|
1368
|
+
}
|
|
1369
|
+
finally {
|
|
1370
|
+
await rm(wd, { recursive: true, force: true });
|
|
1371
|
+
}
|
|
1372
|
+
});
|
|
1373
|
+
it("reports unsafe managed removal without recommending destructive repair", async () => {
|
|
1374
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-hooks-unsafe-removal-"));
|
|
1375
|
+
try {
|
|
1376
|
+
const home = join(wd, "home");
|
|
1377
|
+
const codexDir = join(home, ".codex");
|
|
1378
|
+
await mkdir(codexDir, { recursive: true });
|
|
1379
|
+
await writeFile(join(codexDir, "hooks.json"), JSON.stringify({
|
|
1380
|
+
hooks: {
|
|
1381
|
+
SessionStart: [{
|
|
1382
|
+
matcher: "startup|resume|clear",
|
|
1383
|
+
hooks: [
|
|
1384
|
+
{ type: "command", command: 'node "/repo/dist/scripts/codex-native-hook.js"' },
|
|
1385
|
+
{ type: "command", command: "echo user-owned" },
|
|
1386
|
+
],
|
|
1387
|
+
}],
|
|
1388
|
+
},
|
|
1389
|
+
}, null, 2) + "\n");
|
|
1390
|
+
const res = runOmx(wd, ["doctor"], { HOME: home, CODEX_HOME: codexDir });
|
|
1391
|
+
if (shouldSkipForSpawnPermissions(res.error))
|
|
1392
|
+
return;
|
|
1393
|
+
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1394
|
+
assert.match(res.stdout, /\[!!\] Native hooks: hooks\.json has OMX entries that cannot be safely removed \(unsafe_managed_removal\): Removing OMX hooks would shift a foreign coordinate or discard opaque metadata; manual cleanup is required because doctor will not overwrite or remove it/);
|
|
1395
|
+
assert.doesNotMatch(res.stdout, /Native hooks:.*--force/);
|
|
1396
|
+
}
|
|
1397
|
+
finally {
|
|
1398
|
+
await rm(wd, { recursive: true, force: true });
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
it("fails closed when a Windows native hook references a missing shim", async () => {
|
|
1402
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-windows-shim-missing-"));
|
|
1403
|
+
try {
|
|
1404
|
+
const codexDir = join(wd, ".codex");
|
|
1405
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1406
|
+
const shimPath = join(codexDir, "hooks", "omx-native-hook-windows-shim.ps1");
|
|
1407
|
+
await mkdir(codexDir, { recursive: true });
|
|
1408
|
+
const original = buildWindowsShimHooksJson(shimPath, codexDir);
|
|
1409
|
+
await writeFile(hooksPath, original);
|
|
1410
|
+
const check = await checkNativeHooks(hooksPath, join(codexDir, "config.toml"), {
|
|
1411
|
+
codexHomeDir: codexDir,
|
|
1412
|
+
platform: "win32",
|
|
1413
|
+
});
|
|
1414
|
+
assert.equal(check.status, "fail");
|
|
1415
|
+
assert.match(check.message, /referenced Windows native hook shim is missing at/);
|
|
1416
|
+
assert.match(check.message, /manually reinstall the matching oh-my-codex version/);
|
|
1417
|
+
assert.doesNotMatch(check.message, /omx setup|--force/);
|
|
1418
|
+
assert.equal(existsSync(shimPath), false);
|
|
1419
|
+
assert.equal(await readFile(hooksPath, "utf-8"), original);
|
|
1420
|
+
}
|
|
1421
|
+
finally {
|
|
1422
|
+
await rm(wd, { recursive: true, force: true });
|
|
1423
|
+
}
|
|
1424
|
+
});
|
|
1425
|
+
it("fails closed when a referenced Windows native hook shim is tampered", async () => {
|
|
1426
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-windows-shim-tampered-"));
|
|
1427
|
+
try {
|
|
1428
|
+
const codexDir = join(wd, ".codex");
|
|
1429
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1430
|
+
const shimPath = join(codexDir, "hooks", "omx-native-hook-windows-shim.ps1");
|
|
1431
|
+
await mkdir(dirname(shimPath), { recursive: true });
|
|
1432
|
+
const original = buildWindowsShimHooksJson(shimPath, codexDir);
|
|
1433
|
+
const tamperedShim = `${buildManagedCodexNativeHookWindowsShimContent(repoRoot())}# user change\n`;
|
|
1434
|
+
await writeFile(hooksPath, original);
|
|
1435
|
+
await writeFile(shimPath, tamperedShim, "utf-8");
|
|
1436
|
+
const check = await checkNativeHooks(hooksPath, join(codexDir, "config.toml"), {
|
|
1437
|
+
codexHomeDir: codexDir,
|
|
1438
|
+
platform: "win32",
|
|
1439
|
+
});
|
|
1440
|
+
assert.equal(check.status, "fail");
|
|
1441
|
+
assert.match(check.message, /not an exact current or complete historical generated shim/);
|
|
1442
|
+
assert.match(check.message, /modified, truncated, have extra content, or use ambiguous encoding/);
|
|
1443
|
+
assert.doesNotMatch(check.message, /omx setup|--force/);
|
|
1444
|
+
assert.equal(await readFile(hooksPath, "utf-8"), original);
|
|
1445
|
+
assert.equal(await readFile(shimPath, "utf-8"), tamperedShim);
|
|
1446
|
+
}
|
|
1447
|
+
finally {
|
|
1448
|
+
await rm(wd, { recursive: true, force: true });
|
|
1449
|
+
}
|
|
1450
|
+
});
|
|
1451
|
+
it("accepts a complete historical Windows native hook shim without modifying it", async () => {
|
|
1452
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-windows-shim-historical-"));
|
|
1453
|
+
try {
|
|
1454
|
+
const codexDir = join(wd, ".codex");
|
|
1455
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1456
|
+
const shimPath = join(codexDir, "hooks", "omx-native-hook-windows-shim.ps1");
|
|
1457
|
+
await mkdir(dirname(shimPath), { recursive: true });
|
|
1458
|
+
const original = buildWindowsShimHooksJson(shimPath, codexDir);
|
|
1459
|
+
const historicalShim = buildManagedCodexNativeHookWindowsShimContent("", {
|
|
1460
|
+
nodePath: "C:\\Historical Node\\node.exe",
|
|
1461
|
+
hookScriptPath: "C:\\Historical Install\\oh-my-codex\\dist\\scripts\\codex-native-hook.js",
|
|
1462
|
+
});
|
|
1463
|
+
await writeFile(hooksPath, original);
|
|
1464
|
+
await writeFile(shimPath, historicalShim, "utf-8");
|
|
1465
|
+
const check = await checkNativeHooks(hooksPath, join(codexDir, "config.toml"), {
|
|
1466
|
+
codexHomeDir: codexDir,
|
|
1467
|
+
platform: "win32",
|
|
1468
|
+
});
|
|
1469
|
+
assert.equal(check.status, "pass");
|
|
1470
|
+
assert.match(check.message, /includes OMX-managed coverage for all native hook events/);
|
|
1471
|
+
assert.equal(await readFile(hooksPath, "utf-8"), original);
|
|
1472
|
+
assert.equal(await readFile(shimPath, "utf-8"), historicalShim);
|
|
1473
|
+
}
|
|
1474
|
+
finally {
|
|
1475
|
+
await rm(wd, { recursive: true, force: true });
|
|
1476
|
+
}
|
|
1477
|
+
});
|
|
1478
|
+
it("reports Windows shim integrity before an unsafe managed/foreign group coordinate warning", async () => {
|
|
1479
|
+
for (const fixture of [
|
|
1480
|
+
{
|
|
1481
|
+
name: "missing",
|
|
1482
|
+
shimContent: null,
|
|
1483
|
+
integrity: /referenced Windows native hook shim is missing at/,
|
|
1484
|
+
},
|
|
1485
|
+
{
|
|
1486
|
+
name: "tampered",
|
|
1487
|
+
shimContent: `${buildManagedCodexNativeHookWindowsShimContent(repoRoot())}# mixed-group sentinel\n`,
|
|
1488
|
+
integrity: /not an exact current or complete historical generated shim/,
|
|
1489
|
+
},
|
|
1490
|
+
]) {
|
|
1491
|
+
const wd = await mkdtemp(join(tmpdir(), `omx-doctor-windows-shim-${fixture.name}-unsafe-`));
|
|
1492
|
+
try {
|
|
1493
|
+
const codexDir = join(wd, ".codex");
|
|
1494
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1495
|
+
const shimPath = join(codexDir, "hooks", "omx-native-hook-windows-shim.ps1");
|
|
1496
|
+
const parsed = JSON.parse(buildWindowsShimHooksJson(shimPath, codexDir));
|
|
1497
|
+
parsed.hooks.PreToolUse[0].hooks.push({
|
|
1498
|
+
type: "command",
|
|
1499
|
+
command: "echo foreign-handler",
|
|
1500
|
+
});
|
|
1501
|
+
await mkdir(codexDir, { recursive: true });
|
|
1502
|
+
await writeFile(hooksPath, `${JSON.stringify(parsed, null, 2)}\n`);
|
|
1503
|
+
if (fixture.shimContent !== null) {
|
|
1504
|
+
await mkdir(dirname(shimPath), { recursive: true });
|
|
1505
|
+
await writeFile(shimPath, fixture.shimContent, "utf-8");
|
|
1506
|
+
}
|
|
1507
|
+
const check = await checkNativeHooks(hooksPath, join(codexDir, "config.toml"), {
|
|
1508
|
+
codexHomeDir: codexDir,
|
|
1509
|
+
platform: "win32",
|
|
1510
|
+
});
|
|
1511
|
+
assert.equal(check.status, "fail", fixture.name);
|
|
1512
|
+
assert.match(check.message, fixture.integrity, fixture.name);
|
|
1513
|
+
assert.match(check.message, /unsafe_managed_removal/, fixture.name);
|
|
1514
|
+
assert.ok(check.message.search(fixture.integrity) < check.message.indexOf("unsafe_managed_removal"), `${fixture.name} shim integrity must take precedence over the coordinate warning`);
|
|
1515
|
+
}
|
|
1516
|
+
finally {
|
|
1517
|
+
await rm(wd, { recursive: true, force: true });
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
});
|
|
1521
|
+
it("never executes missing, tampered, historical, hard-linked, or symlinked Windows shim sentinels during verbose validation", async () => {
|
|
1522
|
+
for (const fixture of [
|
|
1523
|
+
{
|
|
1524
|
+
name: "missing",
|
|
1525
|
+
shimContent: null,
|
|
1526
|
+
hardLink: false,
|
|
1527
|
+
symlinkTarget: null,
|
|
1528
|
+
expected: /referenced Windows native hook shim is missing at/,
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
name: "tampered",
|
|
1532
|
+
shimContent: `${buildManagedCodexNativeHookWindowsShimContent(repoRoot())}# verbose-execution sentinel\n`,
|
|
1533
|
+
hardLink: false,
|
|
1534
|
+
symlinkTarget: null,
|
|
1535
|
+
expected: /not an exact current or complete historical generated shim/,
|
|
1536
|
+
},
|
|
1537
|
+
{
|
|
1538
|
+
name: "historical",
|
|
1539
|
+
shimContent: buildManagedCodexNativeHookWindowsShimContent("", {
|
|
1540
|
+
nodePath: "C:\\Historical Node\\node.exe",
|
|
1541
|
+
hookScriptPath: "C:\\Historical Install\\oh-my-codex\\dist\\scripts\\codex-native-hook.js",
|
|
1542
|
+
}),
|
|
1543
|
+
hardLink: false,
|
|
1544
|
+
symlinkTarget: null,
|
|
1545
|
+
expected: /complete historical generated shim.*run "omx setup" to migrate/,
|
|
1546
|
+
},
|
|
1547
|
+
{
|
|
1548
|
+
name: "hard-linked",
|
|
1549
|
+
shimContent: buildManagedCodexNativeHookWindowsShimContent(repoRoot()),
|
|
1550
|
+
hardLink: true,
|
|
1551
|
+
symlinkTarget: null,
|
|
1552
|
+
expected: /is hard-linked; doctor will not execute or modify it/,
|
|
1553
|
+
},
|
|
1554
|
+
{
|
|
1555
|
+
name: "symlinked",
|
|
1556
|
+
shimContent: null,
|
|
1557
|
+
hardLink: false,
|
|
1558
|
+
symlinkTarget: buildManagedCodexNativeHookWindowsShimContent(repoRoot()),
|
|
1559
|
+
expected: /is not a regular file; doctor will not follow or modify it/,
|
|
1560
|
+
},
|
|
1561
|
+
]) {
|
|
1562
|
+
const wd = await mkdtemp(join(tmpdir(), `omx-doctor-verbose-windows-shim-${fixture.name}-`));
|
|
1563
|
+
try {
|
|
1564
|
+
const codexDir = join(wd, ".codex");
|
|
1565
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1566
|
+
const shimPath = join(codexDir, "hooks", "omx-native-hook-windows-shim.ps1");
|
|
1567
|
+
const command = buildWindowsShimCommand(shimPath);
|
|
1568
|
+
await mkdir(codexDir, { recursive: true });
|
|
1569
|
+
await writeFile(hooksPath, buildWindowsShimHooksJson(shimPath, codexDir));
|
|
1570
|
+
if (fixture.symlinkTarget !== null) {
|
|
1571
|
+
const symlinkTargetPath = join(wd, "symlink-target.ps1");
|
|
1572
|
+
await mkdir(dirname(shimPath), { recursive: true });
|
|
1573
|
+
await writeFile(symlinkTargetPath, fixture.symlinkTarget, "utf-8");
|
|
1574
|
+
await symlink(symlinkTargetPath, shimPath);
|
|
1575
|
+
}
|
|
1576
|
+
else if (fixture.shimContent !== null) {
|
|
1577
|
+
await mkdir(dirname(shimPath), { recursive: true });
|
|
1578
|
+
await writeFile(shimPath, fixture.shimContent, "utf-8");
|
|
1579
|
+
if (fixture.hardLink) {
|
|
1580
|
+
await link(shimPath, join(wd, "canonical-shim-hardlink.ps1"));
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
let spawned = false;
|
|
1584
|
+
const check = await checkNativePostCompactHookRuntime(hooksPath, wd, codexDir, {
|
|
1585
|
+
platform: "win32",
|
|
1586
|
+
expectedCommand: command,
|
|
1587
|
+
runner: (() => {
|
|
1588
|
+
spawned = true;
|
|
1589
|
+
throw new Error("unverified Windows shim execution");
|
|
1590
|
+
}),
|
|
1591
|
+
});
|
|
1592
|
+
assert.equal(spawned, false, `${fixture.name} shim executed`);
|
|
1593
|
+
assert.ok(check, `${fixture.name} shim must produce a safety diagnostic`);
|
|
1594
|
+
assert.notEqual(check.status, "pass", fixture.name);
|
|
1595
|
+
assert.match(check.message, fixture.expected, fixture.name);
|
|
1596
|
+
}
|
|
1597
|
+
finally {
|
|
1598
|
+
await rm(wd, { recursive: true, force: true });
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
it("runs exact current Windows shim bytes in memory after canonical replacement, hard-linking, and ancestor retargeting", async () => {
|
|
1603
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-verbose-windows-shim-in-memory-"));
|
|
1604
|
+
try {
|
|
1605
|
+
const codexDir = join(wd, ".codex");
|
|
1606
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1607
|
+
const hooksDir = join(codexDir, "hooks");
|
|
1608
|
+
const shimPath = join(hooksDir, "omx-native-hook-windows-shim.ps1");
|
|
1609
|
+
const command = buildWindowsShimCommand(shimPath);
|
|
1610
|
+
const currentShim = buildManagedCodexNativeHookWindowsShimContent(repoRoot());
|
|
1611
|
+
const sentinel = "# foreign canonical shim sentinel\n";
|
|
1612
|
+
const foreignHooksDir = join(codexDir, "foreign-hooks");
|
|
1613
|
+
const foreignShimPath = join(foreignHooksDir, "omx-native-hook-windows-shim.ps1");
|
|
1614
|
+
const foreignHardLinkPath = join(foreignHooksDir, "foreign-shim-hard-link.ps1");
|
|
1615
|
+
await mkdir(hooksDir, { recursive: true });
|
|
1616
|
+
await writeFile(hooksPath, buildWindowsShimHooksJson(shimPath, codexDir));
|
|
1617
|
+
await writeFile(shimPath, currentShim, "utf-8");
|
|
1618
|
+
const check = await checkNativePostCompactHookRuntime(hooksPath, wd, codexDir, {
|
|
1619
|
+
platform: "win32",
|
|
1620
|
+
expectedCommand: command,
|
|
1621
|
+
beforeWindowsShimSmoke: async () => {
|
|
1622
|
+
const parkedHooksDir = join(codexDir, "validated-hooks");
|
|
1623
|
+
await rename(hooksDir, parkedHooksDir);
|
|
1624
|
+
await mkdir(foreignHooksDir, { recursive: true });
|
|
1625
|
+
await writeFile(foreignShimPath, sentinel);
|
|
1626
|
+
await link(foreignShimPath, foreignHardLinkPath);
|
|
1627
|
+
await symlink(foreignHooksDir, hooksDir, "dir");
|
|
1628
|
+
},
|
|
1629
|
+
runner: ((_command, args) => {
|
|
1630
|
+
const encodedCommand = args[args.indexOf("-EncodedCommand") + 1];
|
|
1631
|
+
if (typeof encodedCommand !== "string") {
|
|
1632
|
+
throw new Error("PowerShell smoke must receive an encoded in-memory command");
|
|
1633
|
+
}
|
|
1634
|
+
assert.doesNotMatch(args.join("\u0000"), /(?:^|\u0000)-File(?:\u0000|$)/);
|
|
1635
|
+
const smokeCommand = Buffer.from(encodedCommand, "base64").toString("utf16le");
|
|
1636
|
+
assert.doesNotMatch(smokeCommand, /(?:^|\s)-File(?:\s|$)/);
|
|
1637
|
+
assert.equal(smokeCommand.includes(shimPath), false);
|
|
1638
|
+
assert.match(smokeCommand, /\[ScriptBlock\]::Create\(\$omxShimSource\)/);
|
|
1639
|
+
const encodedShimBytes = /FromBase64String\('([A-Za-z0-9+/=]+)'\)/.exec(smokeCommand)?.[1];
|
|
1640
|
+
if (encodedShimBytes === undefined) {
|
|
1641
|
+
throw new Error("encoded PowerShell smoke command omitted validated shim bytes");
|
|
1642
|
+
}
|
|
1643
|
+
assert.deepEqual(Buffer.from(encodedShimBytes, "base64"), Buffer.from(currentShim, "utf-8"));
|
|
1644
|
+
assert.equal(readFileSync(shimPath, "utf-8"), sentinel);
|
|
1645
|
+
assert.equal(readFileSync(foreignHardLinkPath, "utf-8"), sentinel);
|
|
1646
|
+
return { status: 0, stdout: "", stderr: "" };
|
|
1647
|
+
}),
|
|
1648
|
+
});
|
|
1649
|
+
assert.equal(check?.status, "pass");
|
|
1650
|
+
}
|
|
1651
|
+
finally {
|
|
1652
|
+
await rm(wd, { recursive: true, force: true });
|
|
1653
|
+
}
|
|
1654
|
+
});
|
|
1655
|
+
it("preserves a swapped Windows PostCompact smoke root instead of recursively deleting it", async () => {
|
|
1656
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-verbose-windows-smoke-root-"));
|
|
1657
|
+
let foreignSmokeCwd = null;
|
|
1658
|
+
let parkedSmokeCwd = null;
|
|
1659
|
+
try {
|
|
1660
|
+
const codexDir = join(wd, ".codex");
|
|
1661
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1662
|
+
const hooksDir = join(codexDir, "hooks");
|
|
1663
|
+
const shimPath = join(hooksDir, "omx-native-hook-windows-shim.ps1");
|
|
1664
|
+
const command = buildWindowsShimCommand(shimPath);
|
|
1665
|
+
await mkdir(hooksDir, { recursive: true });
|
|
1666
|
+
await writeFile(hooksPath, buildWindowsShimHooksJson(shimPath, codexDir));
|
|
1667
|
+
await writeFile(shimPath, buildManagedCodexNativeHookWindowsShimContent(repoRoot()), "utf-8");
|
|
1668
|
+
const check = await checkNativePostCompactHookRuntime(hooksPath, wd, codexDir, {
|
|
1669
|
+
platform: "win32",
|
|
1670
|
+
expectedCommand: command,
|
|
1671
|
+
beforeWindowsShimSmoke: ({ smokeCwd }) => {
|
|
1672
|
+
foreignSmokeCwd = smokeCwd;
|
|
1673
|
+
},
|
|
1674
|
+
runner: (() => {
|
|
1675
|
+
const currentSmokeCwd = foreignSmokeCwd;
|
|
1676
|
+
if (currentSmokeCwd === null) {
|
|
1677
|
+
throw new Error("Windows smoke root was not captured before execution");
|
|
1678
|
+
}
|
|
1679
|
+
parkedSmokeCwd = `${currentSmokeCwd}-parked`;
|
|
1680
|
+
renameSync(currentSmokeCwd, parkedSmokeCwd);
|
|
1681
|
+
mkdirSync(currentSmokeCwd, { mode: 0o700 });
|
|
1682
|
+
writeFileSync(join(currentSmokeCwd, "foreign-sentinel.txt"), "foreign smoke root\n");
|
|
1683
|
+
return { status: 0, stdout: "", stderr: "" };
|
|
1684
|
+
}),
|
|
1685
|
+
});
|
|
1686
|
+
assert.equal(check?.status, "warn");
|
|
1687
|
+
assert.match(check?.message ?? "", /temporary PostCompact smoke directory changed during validation/);
|
|
1688
|
+
if (foreignSmokeCwd === null)
|
|
1689
|
+
assert.fail("Windows smoke root was not captured");
|
|
1690
|
+
assert.equal(readFileSync(join(foreignSmokeCwd, "foreign-sentinel.txt"), "utf-8"), "foreign smoke root\n");
|
|
1691
|
+
}
|
|
1692
|
+
finally {
|
|
1693
|
+
if (foreignSmokeCwd !== null)
|
|
1694
|
+
await rm(foreignSmokeCwd, { recursive: true, force: true });
|
|
1695
|
+
if (parkedSmokeCwd !== null)
|
|
1696
|
+
await rm(parkedSmokeCwd, { recursive: true, force: true });
|
|
1697
|
+
await rm(wd, { recursive: true, force: true });
|
|
1698
|
+
}
|
|
1699
|
+
});
|
|
1700
|
+
it("preserves a failed PostCompact smoke result when cleanup retains the smoke directory", async () => {
|
|
1701
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-postcompact-smoke-cleanup-failure-"));
|
|
1702
|
+
let smokeCwd = null;
|
|
1703
|
+
try {
|
|
1704
|
+
const codexDir = join(wd, ".codex");
|
|
1705
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1706
|
+
const hooksDir = join(codexDir, "hooks");
|
|
1707
|
+
const shimPath = join(hooksDir, "omx-native-hook-windows-shim.ps1");
|
|
1708
|
+
const command = buildWindowsShimCommand(shimPath);
|
|
1709
|
+
await mkdir(hooksDir, { recursive: true });
|
|
1710
|
+
await writeFile(hooksPath, buildWindowsShimHooksJson(shimPath, codexDir));
|
|
1711
|
+
await writeFile(shimPath, buildManagedCodexNativeHookWindowsShimContent(repoRoot()), "utf-8");
|
|
1712
|
+
const check = await checkNativePostCompactHookRuntime(hooksPath, wd, codexDir, {
|
|
1713
|
+
platform: "win32",
|
|
1714
|
+
expectedCommand: command,
|
|
1715
|
+
beforeWindowsShimSmoke: ({ smokeCwd: currentSmokeCwd }) => {
|
|
1716
|
+
smokeCwd = currentSmokeCwd;
|
|
1717
|
+
},
|
|
1718
|
+
runner: (() => {
|
|
1719
|
+
if (smokeCwd === null) {
|
|
1720
|
+
throw new Error("Windows smoke root was not captured before execution");
|
|
1721
|
+
}
|
|
1722
|
+
writeFileSync(join(smokeCwd, "retained-sentinel.txt"), "retained smoke root\n");
|
|
1723
|
+
return { status: 1, stdout: "", stderr: "hook failure" };
|
|
1724
|
+
}),
|
|
1725
|
+
});
|
|
1726
|
+
assert.equal(check?.status, "fail");
|
|
1727
|
+
assert.match(check?.message ?? "", /PostCompact hook smoke validation exited 1: hook failure/);
|
|
1728
|
+
assert.match(check?.message ?? "", /temporary PostCompact smoke directory could not be removed without recursive deletion/);
|
|
1729
|
+
if (smokeCwd === null)
|
|
1730
|
+
assert.fail("Windows smoke root was not captured");
|
|
1731
|
+
assert.equal(readFileSync(join(smokeCwd, "retained-sentinel.txt"), "utf-8"), "retained smoke root\n");
|
|
1732
|
+
}
|
|
1733
|
+
finally {
|
|
1734
|
+
if (smokeCwd !== null)
|
|
1735
|
+
await rm(smokeCwd, { recursive: true, force: true });
|
|
1736
|
+
await rm(wd, { recursive: true, force: true });
|
|
1737
|
+
}
|
|
1738
|
+
});
|
|
1739
|
+
it("preserves a thrown PostCompact smoke error when cleanup also fails", async () => {
|
|
1740
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-postcompact-smoke-thrown-cleanup-"));
|
|
1741
|
+
let smokeCwd = null;
|
|
1742
|
+
try {
|
|
1743
|
+
const codexDir = join(wd, ".codex");
|
|
1744
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1745
|
+
const hooksDir = join(codexDir, "hooks");
|
|
1746
|
+
const shimPath = join(hooksDir, "omx-native-hook-windows-shim.ps1");
|
|
1747
|
+
const command = buildWindowsShimCommand(shimPath);
|
|
1748
|
+
await mkdir(hooksDir, { recursive: true });
|
|
1749
|
+
await writeFile(hooksPath, buildWindowsShimHooksJson(shimPath, codexDir));
|
|
1750
|
+
await writeFile(shimPath, buildManagedCodexNativeHookWindowsShimContent(repoRoot()), "utf-8");
|
|
1751
|
+
await assert.rejects(checkNativePostCompactHookRuntime(hooksPath, wd, codexDir, {
|
|
1752
|
+
platform: "win32",
|
|
1753
|
+
expectedCommand: command,
|
|
1754
|
+
beforeWindowsShimSmoke: ({ smokeCwd: currentSmokeCwd }) => {
|
|
1755
|
+
smokeCwd = currentSmokeCwd;
|
|
1756
|
+
},
|
|
1757
|
+
runner: (() => {
|
|
1758
|
+
if (smokeCwd === null)
|
|
1759
|
+
throw new Error("Windows smoke root was not captured before execution");
|
|
1760
|
+
writeFileSync(join(smokeCwd, "retained-sentinel.txt"), "retained smoke root\n");
|
|
1761
|
+
throw new Error("primary spawn failure");
|
|
1762
|
+
}),
|
|
1763
|
+
}), /primary spawn failure; temporary PostCompact smoke directory could not be removed without recursive deletion/);
|
|
1764
|
+
}
|
|
1765
|
+
finally {
|
|
1766
|
+
if (smokeCwd !== null)
|
|
1767
|
+
await rm(smokeCwd, { recursive: true, force: true });
|
|
1768
|
+
await rm(wd, { recursive: true, force: true });
|
|
1769
|
+
}
|
|
1770
|
+
});
|
|
1771
|
+
it("reports exact nested legacy hook trust state as migration-required without modifying hooks.json", async () => {
|
|
1772
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-hooks-legacy-trust-"));
|
|
1773
|
+
try {
|
|
1774
|
+
const home = join(wd, "home");
|
|
1775
|
+
const codexDir = join(home, ".codex");
|
|
1776
|
+
await mkdir(codexDir, { recursive: true });
|
|
1777
|
+
const parsed = JSON.parse(buildHooksJsonWithPostCompactCommand(currentNativeHookCommand(codexDir), codexDir));
|
|
1778
|
+
parsed.hooks.state = {
|
|
1779
|
+
"custom:/hooks.json:stop:0:0": {
|
|
1780
|
+
trusted_hash: "sha256:legacy",
|
|
1781
|
+
enabled: false,
|
|
1782
|
+
},
|
|
1783
|
+
};
|
|
1784
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1785
|
+
const original = `${JSON.stringify(parsed, null, 2)}\n`;
|
|
1786
|
+
await writeFile(hooksPath, original);
|
|
1787
|
+
const res = runOmx(wd, ["doctor"], { HOME: home, CODEX_HOME: codexDir });
|
|
1788
|
+
if (shouldSkipForSpawnPermissions(res.error))
|
|
1789
|
+
return;
|
|
1790
|
+
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1791
|
+
assert.match(res.stdout, /\[!!\] Native hooks: hooks\.json contains 1 exact historical OMX hook trust-state entry that requires migration; run "omx setup" to migrate it after reviewing the configuration/);
|
|
1792
|
+
assert.doesNotMatch(res.stdout, /Native hooks: hooks\.json includes OMX-managed coverage/);
|
|
1793
|
+
assert.doesNotMatch(res.stdout, /Native hooks:.*--force/);
|
|
1794
|
+
assert.equal(await readFile(hooksPath, "utf-8"), original);
|
|
1795
|
+
}
|
|
1796
|
+
finally {
|
|
1797
|
+
await rm(wd, { recursive: true, force: true });
|
|
1798
|
+
}
|
|
1799
|
+
});
|
|
1800
|
+
it("preserves nonmatching nested hooks.state without reporting a migration", async () => {
|
|
1801
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-hooks-nonlegacy-state-"));
|
|
1802
|
+
try {
|
|
1803
|
+
const home = join(wd, "home");
|
|
1804
|
+
const codexDir = join(home, ".codex");
|
|
1805
|
+
await mkdir(codexDir, { recursive: true });
|
|
1806
|
+
const parsed = JSON.parse(buildHooksJsonWithPostCompactCommand(currentNativeHookCommand(codexDir), codexDir));
|
|
1807
|
+
parsed.hooks.state = {
|
|
1808
|
+
retained: { custom: true, trusted_hash: "sha256:not-omx" },
|
|
1809
|
+
};
|
|
1810
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
1811
|
+
const original = `${JSON.stringify(parsed, null, 2)}\n`;
|
|
1812
|
+
await writeFile(hooksPath, original);
|
|
1813
|
+
const res = runOmx(wd, ["doctor"], { HOME: home, CODEX_HOME: codexDir });
|
|
1814
|
+
if (shouldSkipForSpawnPermissions(res.error))
|
|
1815
|
+
return;
|
|
1816
|
+
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1817
|
+
assert.match(res.stdout, /\[OK\] Native hooks: hooks\.json includes OMX-managed coverage for all native hook events/);
|
|
1818
|
+
assert.doesNotMatch(res.stdout, /Native hooks:.*legacy OMX hook trust-state/);
|
|
1819
|
+
assert.equal(await readFile(hooksPath, "utf-8"), original);
|
|
1313
1820
|
}
|
|
1314
1821
|
finally {
|
|
1315
1822
|
await rm(wd, { recursive: true, force: true });
|
|
@@ -1407,8 +1914,9 @@ command = "node"
|
|
|
1407
1914
|
assert.equal(check.name, "Native hook dist smoke");
|
|
1408
1915
|
assert.equal(check.status, "fail");
|
|
1409
1916
|
assert.match(check.message, /minimal UserPromptSubmit smoke/);
|
|
1410
|
-
assert.match(check.message, /
|
|
1411
|
-
assert.
|
|
1917
|
+
assert.match(check.message, /reinstall the matching oh-my-codex version/);
|
|
1918
|
+
assert.doesNotMatch(check.message, /--force/);
|
|
1919
|
+
assert.match(check.message, /run "omx setup"/);
|
|
1412
1920
|
}
|
|
1413
1921
|
finally {
|
|
1414
1922
|
await rm(wd, { recursive: true, force: true });
|
|
@@ -1440,5 +1948,218 @@ command = "node"
|
|
|
1440
1948
|
await rm(wd, { recursive: true, force: true });
|
|
1441
1949
|
}
|
|
1442
1950
|
});
|
|
1951
|
+
it("reports retained and custom GPT-5.6 multi-agent settings without diagnosing a clean config", async () => {
|
|
1952
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-multi-agent-"));
|
|
1953
|
+
try {
|
|
1954
|
+
const cleanPath = join(wd, "clean.toml");
|
|
1955
|
+
await writeFile(cleanPath, 'model = "gpt-5.6"\n');
|
|
1956
|
+
assert.equal(await checkLegacyMultiAgentCompatibility(cleanPath, "user"), null);
|
|
1957
|
+
const userPath = join(wd, "user.toml");
|
|
1958
|
+
await writeFile(userPath, "[features]\nmulti_agent = true\n\n[agents]\nmax_threads = 6\nmax_depth = 2\n");
|
|
1959
|
+
const userCheck = await checkLegacyMultiAgentCompatibility(userPath, "user");
|
|
1960
|
+
assert.ok(userCheck);
|
|
1961
|
+
assert.equal(userCheck.name, "GPT-5.6 multi-agent compatibility");
|
|
1962
|
+
assert.equal(userCheck.status, "warn");
|
|
1963
|
+
assert.match(userCheck.message, new RegExp(`user scope config at ${userPath}`));
|
|
1964
|
+
assert.match(userCheck.message, /features\.multi_agent \(retained-legacy; exact-legacy-value\)/);
|
|
1965
|
+
assert.match(userCheck.message, /agents\.max_threads \(retained-legacy; exact-legacy-value\)/);
|
|
1966
|
+
assert.match(userCheck.message, /agents\.max_depth \(retained-legacy; exact-legacy-value\)/);
|
|
1967
|
+
assert.match(userCheck.message, /historical ownership cannot be proven/);
|
|
1968
|
+
assert.match(userCheck.message, /remove only keys you confirm OMX authored/);
|
|
1969
|
+
assert.match(userCheck.message, /omx setup --scope user/);
|
|
1970
|
+
assert.match(userCheck.message, /Setup does not auto-delete them/);
|
|
1971
|
+
const projectPath = join(wd, "project.toml");
|
|
1972
|
+
await writeFile(projectPath, "[agents]\nmax_threads = 8\n");
|
|
1973
|
+
const projectCheck = await checkLegacyMultiAgentCompatibility(projectPath, "project");
|
|
1974
|
+
assert.ok(projectCheck);
|
|
1975
|
+
assert.match(projectCheck.message, new RegExp(`project scope config at ${projectPath}`));
|
|
1976
|
+
assert.match(projectCheck.message, /agents\.max_threads \(custom; custom-value\)/);
|
|
1977
|
+
assert.doesNotMatch(projectCheck.message, /All checks passed/);
|
|
1978
|
+
}
|
|
1979
|
+
finally {
|
|
1980
|
+
await rm(wd, { recursive: true, force: true });
|
|
1981
|
+
}
|
|
1982
|
+
});
|
|
1983
|
+
it("reports project-scoped custom values once through the full doctor command", async () => {
|
|
1984
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-project-multi-agent-"));
|
|
1985
|
+
try {
|
|
1986
|
+
const home = join(wd, "home");
|
|
1987
|
+
const codexDir = join(wd, ".codex");
|
|
1988
|
+
await mkdir(home, { recursive: true });
|
|
1989
|
+
await mkdir(codexDir, { recursive: true });
|
|
1990
|
+
await mkdir(join(wd, ".omx"), { recursive: true });
|
|
1991
|
+
await writeFile(join(wd, ".omx", "setup-scope.json"), `${JSON.stringify({ scope: "project" }, null, 2)}\n`);
|
|
1992
|
+
const configPath = join(codexDir, "config.toml");
|
|
1993
|
+
await writeFile(configPath, "[features]\nmulti_agent = false\n\n[agents]\nmax_threads = 17\nmax_depth = 5\n");
|
|
1994
|
+
const res = runOmx(wd, ["doctor"], { HOME: home });
|
|
1995
|
+
if (shouldSkipForSpawnPermissions(res.error))
|
|
1996
|
+
return;
|
|
1997
|
+
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
1998
|
+
assert.match(res.stdout, /Resolved setup scope: project \(from \.omx\/setup-scope\.json\)/);
|
|
1999
|
+
assert.equal(res.stdout.match(/\[!!\] GPT-5\.6 multi-agent compatibility:/g)?.length, 1);
|
|
2000
|
+
assert.match(res.stdout, new RegExp(`project scope config at ${join(await realpath(wd), ".codex", "config.toml")}`));
|
|
2001
|
+
assert.match(res.stdout, /features\.multi_agent \(custom; custom-value\)/);
|
|
2002
|
+
assert.match(res.stdout, /agents\.max_threads \(custom; custom-value\)/);
|
|
2003
|
+
assert.match(res.stdout, /agents\.max_depth \(custom; custom-value\)/);
|
|
2004
|
+
assert.match(res.stdout, /historical ownership cannot be proven/);
|
|
2005
|
+
assert.match(res.stdout, /remove only keys you confirm OMX authored/);
|
|
2006
|
+
assert.match(res.stdout, /omx setup --scope project/);
|
|
2007
|
+
assert.match(res.stdout, /Setup does not auto-delete them/);
|
|
2008
|
+
assert.match(res.stdout, /Results: \d+ passed, [1-9]\d* warnings, \d+ failed/);
|
|
2009
|
+
assert.doesNotMatch(res.stdout, /All checks passed!/);
|
|
2010
|
+
}
|
|
2011
|
+
finally {
|
|
2012
|
+
await rm(wd, { recursive: true, force: true });
|
|
2013
|
+
}
|
|
2014
|
+
});
|
|
2015
|
+
it("counts the multi-agent compatibility warning and suppresses the all-clear footer", async () => {
|
|
2016
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-multi-agent-footer-"));
|
|
2017
|
+
try {
|
|
2018
|
+
const home = join(wd, "home");
|
|
2019
|
+
const codexDir = join(home, ".codex");
|
|
2020
|
+
await mkdir(codexDir, { recursive: true });
|
|
2021
|
+
await writeFile(join(codexDir, "config.toml"), "[features]\nmulti_agent = true\n");
|
|
2022
|
+
const res = runOmx(wd, ["doctor"], {
|
|
2023
|
+
HOME: home,
|
|
2024
|
+
CODEX_HOME: codexDir,
|
|
2025
|
+
});
|
|
2026
|
+
if (shouldSkipForSpawnPermissions(res.error))
|
|
2027
|
+
return;
|
|
2028
|
+
assert.equal(res.status, 0, res.stderr || res.stdout);
|
|
2029
|
+
assert.match(res.stdout, /\[!!\] GPT-5\.6 multi-agent compatibility:/);
|
|
2030
|
+
assert.match(res.stdout, /Results: \d+ passed, [1-9]\d* warnings, \d+ failed/);
|
|
2031
|
+
assert.doesNotMatch(res.stdout, /All checks passed!/);
|
|
2032
|
+
}
|
|
2033
|
+
finally {
|
|
2034
|
+
await rm(wd, { recursive: true, force: true });
|
|
2035
|
+
}
|
|
2036
|
+
});
|
|
2037
|
+
it("validates an existing global hooks.json before reporting plugin-cache status", async () => {
|
|
2038
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-plugin-global-invalid-"));
|
|
2039
|
+
try {
|
|
2040
|
+
const codexDir = join(wd, ".codex");
|
|
2041
|
+
const configPath = join(codexDir, "config.toml");
|
|
2042
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
2043
|
+
await mkdir(codexDir, { recursive: true });
|
|
2044
|
+
await writeFile(configPath, "plugin_hooks = true\n");
|
|
2045
|
+
await writeFile(hooksPath, '{"state":{}}\n');
|
|
2046
|
+
const check = await checkNativeHooks(hooksPath, configPath, {
|
|
2047
|
+
codexHomeDir: codexDir,
|
|
2048
|
+
installMode: "plugin",
|
|
2049
|
+
});
|
|
2050
|
+
assert.equal(check.status, "fail");
|
|
2051
|
+
assert.match(check.message, /plugin-scoped hooks are enabled/);
|
|
2052
|
+
assert.match(check.message, /existing global hooks\.json: hooks\.json failed strict load validation/);
|
|
2053
|
+
assert.match(check.message, /unknown root field state/);
|
|
2054
|
+
}
|
|
2055
|
+
finally {
|
|
2056
|
+
await rm(wd, { recursive: true, force: true });
|
|
2057
|
+
}
|
|
2058
|
+
});
|
|
2059
|
+
it("fails plugin mode when an existing global Windows shim is tampered", async () => {
|
|
2060
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-plugin-global-shim-"));
|
|
2061
|
+
try {
|
|
2062
|
+
const codexDir = join(wd, ".codex");
|
|
2063
|
+
const configPath = join(codexDir, "config.toml");
|
|
2064
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
2065
|
+
const shimPath = join(codexDir, "hooks", "omx-native-hook-windows-shim.ps1");
|
|
2066
|
+
await mkdir(dirname(shimPath), { recursive: true });
|
|
2067
|
+
await writeFile(configPath, "plugin_hooks = true\n");
|
|
2068
|
+
await writeFile(hooksPath, `${JSON.stringify({
|
|
2069
|
+
hooks: {
|
|
2070
|
+
PostCompact: [{ hooks: [{ type: "command", command: buildWindowsShimCommand(shimPath) }] }],
|
|
2071
|
+
},
|
|
2072
|
+
})}\n`);
|
|
2073
|
+
await writeFile(shimPath, "# modified\n");
|
|
2074
|
+
const check = await checkNativeHooks(hooksPath, configPath, {
|
|
2075
|
+
codexHomeDir: codexDir,
|
|
2076
|
+
installMode: "plugin",
|
|
2077
|
+
platform: "win32",
|
|
2078
|
+
});
|
|
2079
|
+
assert.equal(check.status, "fail");
|
|
2080
|
+
assert.match(check.message, /not an exact current or complete historical generated shim/);
|
|
2081
|
+
assert.match(check.message, /plugin-scoped hooks are enabled/);
|
|
2082
|
+
}
|
|
2083
|
+
finally {
|
|
2084
|
+
await rm(wd, { recursive: true, force: true });
|
|
2085
|
+
}
|
|
2086
|
+
});
|
|
2087
|
+
it("fails ambiguous managed handler ownership instead of downgrading it to a warning", async () => {
|
|
2088
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-ambiguous-managed-handler-"));
|
|
2089
|
+
try {
|
|
2090
|
+
const codexDir = join(wd, ".codex");
|
|
2091
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
2092
|
+
await mkdir(codexDir, { recursive: true });
|
|
2093
|
+
await writeFile(hooksPath, `${JSON.stringify({
|
|
2094
|
+
hooks: {
|
|
2095
|
+
SessionStart: [{
|
|
2096
|
+
matcher: "startup|resume|clear",
|
|
2097
|
+
hooks: [{ type: "command", command: "node /repo/dist/scripts/codex-native-hook.js --unexpected" }],
|
|
2098
|
+
}],
|
|
2099
|
+
},
|
|
2100
|
+
})}\n`);
|
|
2101
|
+
const check = await checkNativeHooks(hooksPath, join(codexDir, "config.toml"), {
|
|
2102
|
+
codexHomeDir: codexDir,
|
|
2103
|
+
});
|
|
2104
|
+
assert.equal(check.status, "fail");
|
|
2105
|
+
assert.match(check.message, /ambiguous_managed_handler/);
|
|
2106
|
+
assert.match(check.message, /ambiguous or untrusted OMX ownership/);
|
|
2107
|
+
}
|
|
2108
|
+
finally {
|
|
2109
|
+
await rm(wd, { recursive: true, force: true });
|
|
2110
|
+
}
|
|
2111
|
+
});
|
|
2112
|
+
it("fails closed instead of recognizing a shell-expanding foreign command as an OMX hook", async () => {
|
|
2113
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-shell-expanding-handler-"));
|
|
2114
|
+
try {
|
|
2115
|
+
const codexDir = join(wd, ".codex");
|
|
2116
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
2117
|
+
await mkdir(codexDir, { recursive: true });
|
|
2118
|
+
await writeFile(hooksPath, `${JSON.stringify({
|
|
2119
|
+
hooks: {
|
|
2120
|
+
SessionStart: [{
|
|
2121
|
+
matcher: "startup|resume|clear",
|
|
2122
|
+
hooks: [{ type: "command", command: 'node "$HOME/repo/dist/scripts/codex-native-hook.js"' }],
|
|
2123
|
+
}],
|
|
2124
|
+
},
|
|
2125
|
+
})}\n`);
|
|
2126
|
+
const check = await checkNativeHooks(hooksPath, join(codexDir, "config.toml"), {
|
|
2127
|
+
codexHomeDir: codexDir,
|
|
2128
|
+
});
|
|
2129
|
+
assert.equal(check.status, "fail");
|
|
2130
|
+
assert.match(check.message, /ambiguous_managed_handler|does not match the managed command grammar/i);
|
|
2131
|
+
}
|
|
2132
|
+
finally {
|
|
2133
|
+
await rm(wd, { recursive: true, force: true });
|
|
2134
|
+
}
|
|
2135
|
+
});
|
|
2136
|
+
it("ignores prompt, agent, and future-event metadata while scanning Windows shim references", async () => {
|
|
2137
|
+
const wd = await mkdtemp(join(tmpdir(), "omx-doctor-inert-shim-metadata-"));
|
|
2138
|
+
try {
|
|
2139
|
+
const codexDir = join(wd, ".codex");
|
|
2140
|
+
const hooksPath = join(codexDir, "hooks.json");
|
|
2141
|
+
const missingShimPath = join(codexDir, "hooks", "omx-native-hook-windows-shim.ps1");
|
|
2142
|
+
await mkdir(codexDir, { recursive: true });
|
|
2143
|
+
await writeFile(hooksPath, `${JSON.stringify({
|
|
2144
|
+
hooks: {
|
|
2145
|
+
PostCompact: [{ hooks: [
|
|
2146
|
+
{ type: "prompt", command: buildWindowsShimCommand(missingShimPath) },
|
|
2147
|
+
{ type: "agent", commandWindows: buildWindowsShimCommand(missingShimPath) },
|
|
2148
|
+
] }],
|
|
2149
|
+
FutureSerdeEvent: [{ hooks: [{ type: "command", command: buildWindowsShimCommand(missingShimPath) }] }],
|
|
2150
|
+
},
|
|
2151
|
+
})}\n`);
|
|
2152
|
+
const check = await checkNativeHooks(hooksPath, join(codexDir, "config.toml"), {
|
|
2153
|
+
codexHomeDir: codexDir,
|
|
2154
|
+
platform: "win32",
|
|
2155
|
+
});
|
|
2156
|
+
assert.equal(check.status, "warn");
|
|
2157
|
+
assert.match(check.message, /hooks\.json discovery warnings/);
|
|
2158
|
+
assert.doesNotMatch(check.message, /referenced Windows native hook shim/);
|
|
2159
|
+
}
|
|
2160
|
+
finally {
|
|
2161
|
+
await rm(wd, { recursive: true, force: true });
|
|
2162
|
+
}
|
|
2163
|
+
});
|
|
1443
2164
|
});
|
|
1444
2165
|
//# sourceMappingURL=doctor-warning-copy.test.js.map
|