oh-my-codex 0.14.4 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +20 -0
- package/Cargo.lock +6 -6
- package/Cargo.toml +2 -1
- package/README.md +40 -7
- package/crates/omx-explore/Cargo.toml +1 -0
- package/crates/omx-explore/src/main.rs +246 -24
- package/crates/omx-mux/Cargo.toml +1 -0
- package/crates/omx-runtime/Cargo.toml +1 -0
- package/crates/omx-runtime-core/Cargo.toml +1 -0
- package/crates/omx-runtime-core/src/dispatch.rs +2 -1
- package/crates/omx-runtime-core/src/engine.rs +2 -2
- package/crates/omx-runtime-core/src/mailbox.rs +2 -1
- package/crates/omx-sparkshell/Cargo.toml +1 -0
- package/crates/omx-sparkshell/src/codex_bridge.rs +1 -0
- package/crates/omx-sparkshell/src/prompt.rs +1 -0
- package/crates/omx-sparkshell/src/threshold.rs +1 -0
- package/dist/agents/__tests__/native-config.test.js +98 -4
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/native-config.d.ts +4 -0
- package/dist/agents/native-config.d.ts.map +1 -1
- package/dist/agents/native-config.js +19 -3
- package/dist/agents/native-config.js.map +1 -1
- package/dist/agents/policy.d.ts +10 -0
- package/dist/agents/policy.d.ts.map +1 -0
- package/dist/agents/policy.js +61 -0
- package/dist/agents/policy.js.map +1 -0
- package/dist/catalog/__tests__/generator.test.js +2 -0
- package/dist/catalog/__tests__/generator.test.js.map +1 -1
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts +2 -0
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.d.ts.map +1 -0
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +72 -0
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +1 -0
- package/dist/catalog/installable.d.ts +5 -0
- package/dist/catalog/installable.d.ts.map +1 -0
- package/dist/catalog/installable.js +13 -0
- package/dist/catalog/installable.js.map +1 -0
- package/dist/catalog/skill-mirror.d.ts +20 -0
- package/dist/catalog/skill-mirror.d.ts.map +1 -0
- package/dist/catalog/skill-mirror.js +104 -0
- package/dist/catalog/skill-mirror.js.map +1 -0
- package/dist/cli/__tests__/ask.test.js +4 -1
- package/dist/cli/__tests__/ask.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.d.ts +2 -0
- package/dist/cli/__tests__/codex-plugin-layout.test.d.ts.map +1 -0
- package/dist/cli/__tests__/codex-plugin-layout.test.js +210 -0
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-team.test.js +46 -1
- package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +225 -111
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +96 -1
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/explore.test.js +26 -9
- package/dist/cli/__tests__/explore.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +301 -7
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +358 -4
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/list.test.d.ts +2 -0
- package/dist/cli/__tests__/list.test.d.ts.map +1 -0
- package/dist/cli/__tests__/list.test.js +38 -0
- package/dist/cli/__tests__/list.test.js.map +1 -0
- package/dist/cli/__tests__/mcp-parity.test.js +86 -0
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-serve.test.d.ts +2 -0
- package/dist/cli/__tests__/mcp-serve.test.d.ts.map +1 -0
- package/dist/cli/__tests__/mcp-serve.test.js +38 -0
- package/dist/cli/__tests__/mcp-serve.test.js.map +1 -0
- package/dist/cli/__tests__/nested-help-routing.test.js +1 -0
- package/dist/cli/__tests__/nested-help-routing.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +58 -3
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/question.test.js +209 -5
- package/dist/cli/__tests__/question.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +146 -3
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.d.ts +2 -0
- package/dist/cli/__tests__/setup-install-mode.test.d.ts.map +1 -0
- package/dist/cli/__tests__/setup-install-mode.test.js +873 -0
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -0
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js +83 -22
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +120 -2
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +32 -13
- package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/sidecar.test.d.ts +2 -0
- package/dist/cli/__tests__/sidecar.test.d.ts.map +1 -0
- package/dist/cli/__tests__/sidecar.test.js +24 -0
- package/dist/cli/__tests__/sidecar.test.js.map +1 -0
- package/dist/cli/__tests__/team.test.js +90 -42
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/version-sync-contract.test.js +11 -0
- package/dist/cli/__tests__/version-sync-contract.test.js.map +1 -1
- package/dist/cli/codex-home.d.ts +4 -5
- package/dist/cli/codex-home.d.ts.map +1 -1
- package/dist/cli/codex-home.js +9 -37
- package/dist/cli/codex-home.js.map +1 -1
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +509 -278
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +13 -5
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +351 -60
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/list.d.ts +2 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +40 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/mcp-serve.d.ts +12 -0
- package/dist/cli/mcp-serve.d.ts.map +1 -0
- package/dist/cli/mcp-serve.js +63 -0
- package/dist/cli/mcp-serve.js.map +1 -0
- package/dist/cli/plugin-marketplace.d.ts +13 -0
- package/dist/cli/plugin-marketplace.d.ts.map +1 -0
- package/dist/cli/plugin-marketplace.js +77 -0
- package/dist/cli/plugin-marketplace.js.map +1 -0
- package/dist/cli/question.d.ts.map +1 -1
- package/dist/cli/question.js +27 -2
- package/dist/cli/question.js.map +1 -1
- package/dist/cli/setup-preferences.d.ts +20 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -0
- package/dist/cli/setup-preferences.js +71 -0
- package/dist/cli/setup-preferences.js.map +1 -0
- package/dist/cli/setup.d.ts +12 -3
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +1080 -254
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/team.d.ts +1 -0
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +22 -3
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +2 -8
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +100 -3
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +6 -5
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/__tests__/generator-status-line-presets.test.d.ts +2 -0
- package/dist/config/__tests__/generator-status-line-presets.test.d.ts.map +1 -0
- package/dist/config/__tests__/generator-status-line-presets.test.js +203 -0
- package/dist/config/__tests__/generator-status-line-presets.test.js.map +1 -0
- package/dist/config/__tests__/models.test.js +35 -2
- package/dist/config/__tests__/models.test.js.map +1 -1
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +2 -7
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/config/generator.d.ts +10 -0
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +259 -76
- package/dist/config/generator.js.map +1 -1
- package/dist/config/models.d.ts +13 -3
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +25 -5
- package/dist/config/models.js.map +1 -1
- package/dist/config/omx-first-party-mcp.d.ts +18 -0
- package/dist/config/omx-first-party-mcp.d.ts.map +1 -0
- package/dist/config/omx-first-party-mcp.js +76 -0
- package/dist/config/omx-first-party-mcp.js.map +1 -0
- package/dist/document-refresh/__tests__/enforcer.test.d.ts +2 -0
- package/dist/document-refresh/__tests__/enforcer.test.d.ts.map +1 -0
- package/dist/document-refresh/__tests__/enforcer.test.js +128 -0
- package/dist/document-refresh/__tests__/enforcer.test.js.map +1 -0
- package/dist/document-refresh/config.d.ts +9 -0
- package/dist/document-refresh/config.d.ts.map +1 -0
- package/dist/document-refresh/config.js +70 -0
- package/dist/document-refresh/config.js.map +1 -0
- package/dist/document-refresh/enforcer.d.ts +43 -0
- package/dist/document-refresh/enforcer.d.ts.map +1 -0
- package/dist/document-refresh/enforcer.js +329 -0
- package/dist/document-refresh/enforcer.js.map +1 -0
- package/dist/exec/followup.d.ts +44 -0
- package/dist/exec/followup.d.ts.map +1 -0
- package/dist/exec/followup.js +349 -0
- package/dist/exec/followup.js.map +1 -0
- package/dist/hooks/__tests__/codebase-map.test.js +63 -1
- package/dist/hooks/__tests__/codebase-map.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +10 -7
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +89 -0
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +84 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +23 -2
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +43 -0
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +17 -0
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +53 -0
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +4 -4
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +103 -0
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +27 -13
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +35 -0
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +70 -3
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js +5 -0
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.js +3 -2
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/prompt-refactor-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/prompt-refactor-contract.test.js +22 -0
- package/dist/hooks/__tests__/prompt-refactor-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js +28 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/triage-heuristic.test.js +59 -4
- package/dist/hooks/__tests__/triage-heuristic.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts +2 -0
- package/dist/hooks/__tests__/visual-ralph-skill.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/visual-ralph-skill.test.js +44 -0
- package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +1 -0
- package/dist/hooks/codebase-map.d.ts.map +1 -1
- package/dist/hooks/codebase-map.js +83 -6
- package/dist/hooks/codebase-map.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +19 -14
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts +6 -0
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +89 -0
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hooks/session.d.ts +2 -0
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +6 -0
- package/dist/hooks/session.js.map +1 -1
- package/dist/hooks/triage-heuristic.d.ts +2 -2
- package/dist/hooks/triage-heuristic.d.ts.map +1 -1
- package/dist/hooks/triage-heuristic.js +97 -20
- package/dist/hooks/triage-heuristic.js.map +1 -1
- package/dist/hooks/triage-state.d.ts +1 -1
- package/dist/hooks/triage-state.d.ts.map +1 -1
- package/dist/hooks/triage-state.js +2 -1
- package/dist/hooks/triage-state.js.map +1 -1
- package/dist/hud/__tests__/index.test.js +4 -4
- package/dist/hud/__tests__/index.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +4 -0
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/types.test.js +27 -0
- package/dist/hud/__tests__/types.test.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +8 -0
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/types.d.ts +9 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js +3 -0
- package/dist/hud/types.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js +45 -5
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +50 -7
- package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server.test.js +67 -9
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/bootstrap.d.ts +12 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +87 -29
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/state-server.d.ts +5 -11
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +16 -432
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/planning/__tests__/artifacts.test.js +152 -1
- package/dist/planning/__tests__/artifacts.test.js.map +1 -1
- package/dist/planning/artifacts.d.ts +9 -0
- package/dist/planning/artifacts.d.ts.map +1 -1
- package/dist/planning/artifacts.js +60 -1
- package/dist/planning/artifacts.js.map +1 -1
- package/dist/question/__tests__/deep-interview.test.js +1 -1
- package/dist/question/__tests__/deep-interview.test.js.map +1 -1
- package/dist/question/__tests__/renderer.test.js +70 -0
- package/dist/question/__tests__/renderer.test.js.map +1 -1
- package/dist/question/__tests__/ui.test.js +49 -0
- package/dist/question/__tests__/ui.test.js.map +1 -1
- package/dist/question/renderer.d.ts +14 -1
- package/dist/question/renderer.d.ts.map +1 -1
- package/dist/question/renderer.js +109 -10
- package/dist/question/renderer.js.map +1 -1
- package/dist/question/state.d.ts +2 -0
- package/dist/question/state.d.ts.map +1 -1
- package/dist/question/state.js +4 -0
- package/dist/question/state.js.map +1 -1
- package/dist/question/types.d.ts +2 -1
- package/dist/question/types.d.ts.map +1 -1
- package/dist/question/types.js.map +1 -1
- package/dist/question/ui.d.ts.map +1 -1
- package/dist/question/ui.js +28 -8
- package/dist/question/ui.js.map +1 -1
- package/dist/runtime/__tests__/bridge.test.js +143 -1
- package/dist/runtime/__tests__/bridge.test.js.map +1 -1
- package/dist/runtime/bridge.d.ts +21 -0
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +54 -4
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +1904 -230
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/generate-release-body.test.js +90 -1
- package/dist/scripts/__tests__/generate-release-body.test.js.map +1 -1
- package/dist/scripts/__tests__/hook-derived-watcher.test.js +110 -2
- package/dist/scripts/__tests__/hook-derived-watcher.test.js.map +1 -1
- package/dist/scripts/__tests__/postinstall.test.js +7 -93
- package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
- package/dist/scripts/__tests__/prompt-inventory.test.d.ts +2 -0
- package/dist/scripts/__tests__/prompt-inventory.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/prompt-inventory.test.js +56 -0
- package/dist/scripts/__tests__/prompt-inventory.test.js.map +1 -0
- package/dist/scripts/__tests__/run-test-files.test.d.ts +2 -0
- package/dist/scripts/__tests__/run-test-files.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/run-test-files.test.js +62 -0
- package/dist/scripts/__tests__/run-test-files.test.js.map +1 -0
- package/dist/scripts/__tests__/smoke-packed-install.test.js +13 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/__tests__/verify-native-agents.test.d.ts +2 -0
- package/dist/scripts/__tests__/verify-native-agents.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/verify-native-agents.test.js +166 -0
- package/dist/scripts/__tests__/verify-native-agents.test.js.map +1 -0
- package/dist/scripts/codex-execution-surface.d.ts +16 -0
- package/dist/scripts/codex-execution-surface.d.ts.map +1 -0
- package/dist/scripts/codex-execution-surface.js +42 -0
- package/dist/scripts/codex-execution-surface.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +418 -76
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts +8 -0
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +133 -19
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/generate-release-body.d.ts +1 -0
- package/dist/scripts/generate-release-body.d.ts.map +1 -1
- package/dist/scripts/generate-release-body.js +32 -3
- package/dist/scripts/generate-release-body.js.map +1 -1
- package/dist/scripts/hook-derived-watcher.js +46 -7
- package/dist/scripts/hook-derived-watcher.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +59 -9
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts +2 -0
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.d.ts.map +1 -0
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js +153 -0
- package/dist/scripts/notify-hook/__tests__/team-worker-posttooluse.test.js.map +1 -0
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.js +18 -1
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
- package/dist/scripts/notify-hook/process-runner.d.ts.map +1 -1
- package/dist/scripts/notify-hook/process-runner.js +7 -3
- package/dist/scripts/notify-hook/process-runner.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +96 -11
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +3 -3
- package/dist/scripts/notify-hook/team-worker-posttooluse.d.ts +34 -0
- package/dist/scripts/notify-hook/team-worker-posttooluse.d.ts.map +1 -0
- package/dist/scripts/notify-hook/team-worker-posttooluse.js +434 -0
- package/dist/scripts/notify-hook/team-worker-posttooluse.js.map +1 -0
- package/dist/scripts/notify-hook/team-worker.d.ts +1 -1
- package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +3 -43
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook.js +36 -5
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/postinstall.d.ts +1 -5
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +3 -42
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/scripts/prompt-inventory.d.ts +29 -0
- package/dist/scripts/prompt-inventory.d.ts.map +1 -0
- package/dist/scripts/prompt-inventory.js +178 -0
- package/dist/scripts/prompt-inventory.js.map +1 -0
- package/dist/scripts/run-test-files.js +32 -2
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +3 -0
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +9 -1
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.d.ts +13 -0
- package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -0
- package/dist/scripts/sync-plugin-mirror.js +242 -0
- package/dist/scripts/sync-plugin-mirror.js.map +1 -0
- package/dist/scripts/verify-native-agents.d.ts +16 -0
- package/dist/scripts/verify-native-agents.d.ts.map +1 -0
- package/dist/scripts/verify-native-agents.js +188 -0
- package/dist/scripts/verify-native-agents.js.map +1 -0
- package/dist/session-history/search.d.ts.map +1 -1
- package/dist/session-history/search.js +7 -2
- package/dist/session-history/search.js.map +1 -1
- package/dist/sidecar/__tests__/boundary.test.d.ts +2 -0
- package/dist/sidecar/__tests__/boundary.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/boundary.test.js +48 -0
- package/dist/sidecar/__tests__/boundary.test.js.map +1 -0
- package/dist/sidecar/__tests__/collector.test.d.ts +2 -0
- package/dist/sidecar/__tests__/collector.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/collector.test.js +162 -0
- package/dist/sidecar/__tests__/collector.test.js.map +1 -0
- package/dist/sidecar/__tests__/render.test.d.ts +2 -0
- package/dist/sidecar/__tests__/render.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/render.test.js +67 -0
- package/dist/sidecar/__tests__/render.test.js.map +1 -0
- package/dist/sidecar/__tests__/tmux.test.d.ts +2 -0
- package/dist/sidecar/__tests__/tmux.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/tmux.test.js +30 -0
- package/dist/sidecar/__tests__/tmux.test.js.map +1 -0
- package/dist/sidecar/__tests__/watch.test.d.ts +2 -0
- package/dist/sidecar/__tests__/watch.test.d.ts.map +1 -0
- package/dist/sidecar/__tests__/watch.test.js +42 -0
- package/dist/sidecar/__tests__/watch.test.js.map +1 -0
- package/dist/sidecar/collector.d.ts +4 -0
- package/dist/sidecar/collector.d.ts.map +1 -0
- package/dist/sidecar/collector.js +377 -0
- package/dist/sidecar/collector.js.map +1 -0
- package/dist/sidecar/index.d.ts +25 -0
- package/dist/sidecar/index.d.ts.map +1 -0
- package/dist/sidecar/index.js +165 -0
- package/dist/sidecar/index.js.map +1 -0
- package/dist/sidecar/render.d.ts +3 -0
- package/dist/sidecar/render.d.ts.map +1 -0
- package/dist/sidecar/render.js +72 -0
- package/dist/sidecar/render.js.map +1 -0
- package/dist/sidecar/tmux.d.ts +13 -0
- package/dist/sidecar/tmux.d.ts.map +1 -0
- package/dist/sidecar/tmux.js +44 -0
- package/dist/sidecar/tmux.js.map +1 -0
- package/dist/sidecar/types.d.ts +125 -0
- package/dist/sidecar/types.d.ts.map +1 -0
- package/dist/sidecar/types.js +2 -0
- package/dist/sidecar/types.js.map +1 -0
- package/dist/state/__tests__/operations.test.js +50 -22
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/operations.d.ts +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +19 -7
- package/dist/state/operations.js.map +1 -1
- package/dist/team/__tests__/commit-hygiene.test.d.ts +2 -0
- package/dist/team/__tests__/commit-hygiene.test.d.ts.map +1 -0
- package/dist/team/__tests__/commit-hygiene.test.js +93 -0
- package/dist/team/__tests__/commit-hygiene.test.js.map +1 -0
- package/dist/team/__tests__/delegation-policy.test.d.ts +2 -0
- package/dist/team/__tests__/delegation-policy.test.d.ts.map +1 -0
- package/dist/team/__tests__/delegation-policy.test.js +69 -0
- package/dist/team/__tests__/delegation-policy.test.js.map +1 -0
- package/dist/team/__tests__/events.test.js +54 -4
- package/dist/team/__tests__/events.test.js.map +1 -1
- package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts +2 -0
- package/dist/team/__tests__/hook-primary-e2e-contract.test.d.ts.map +1 -0
- package/dist/team/__tests__/hook-primary-e2e-contract.test.js +78 -0
- package/dist/team/__tests__/hook-primary-e2e-contract.test.js.map +1 -0
- package/dist/team/__tests__/model-contract.test.js +18 -2
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/repo-aware-decomposition.test.d.ts +2 -0
- package/dist/team/__tests__/repo-aware-decomposition.test.d.ts.map +1 -0
- package/dist/team/__tests__/repo-aware-decomposition.test.js +95 -0
- package/dist/team/__tests__/repo-aware-decomposition.test.js.map +1 -0
- package/dist/team/__tests__/runtime.test.js +677 -17
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +177 -1
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/state.test.js +110 -0
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +301 -2
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +94 -0
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/commit-hygiene.d.ts +22 -3
- package/dist/team/commit-hygiene.d.ts.map +1 -1
- package/dist/team/commit-hygiene.js +134 -2
- package/dist/team/commit-hygiene.js.map +1 -1
- package/dist/team/contracts.d.ts +1 -1
- package/dist/team/contracts.d.ts.map +1 -1
- package/dist/team/contracts.js +2 -0
- package/dist/team/contracts.js.map +1 -1
- package/dist/team/dag-schema.d.ts +38 -0
- package/dist/team/dag-schema.d.ts.map +1 -0
- package/dist/team/dag-schema.js +221 -0
- package/dist/team/dag-schema.js.map +1 -0
- package/dist/team/delegation-policy.d.ts +3 -0
- package/dist/team/delegation-policy.d.ts.map +1 -0
- package/dist/team/delegation-policy.js +82 -0
- package/dist/team/delegation-policy.js.map +1 -0
- package/dist/team/model-contract.d.ts +3 -1
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +44 -5
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/repo-aware-decomposition.d.ts +60 -0
- package/dist/team/repo-aware-decomposition.d.ts.map +1 -0
- package/dist/team/repo-aware-decomposition.js +229 -0
- package/dist/team/repo-aware-decomposition.js.map +1 -0
- package/dist/team/runtime.d.ts +34 -0
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +191 -50
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/state/tasks.d.ts.map +1 -1
- package/dist/team/state/tasks.js +33 -0
- package/dist/team/state/tasks.js.map +1 -1
- package/dist/team/state/types.d.ts +23 -1
- package/dist/team/state/types.d.ts.map +1 -1
- package/dist/team/state/types.js.map +1 -1
- package/dist/team/state-root.d.ts +35 -0
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +281 -1
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts +27 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +6 -0
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts +1 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +83 -6
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +3 -0
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +77 -4
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/utils/__tests__/agents-model-table.test.js +8 -0
- package/dist/utils/__tests__/agents-model-table.test.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +42 -9
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/agents-md.d.ts +3 -0
- package/dist/utils/agents-md.d.ts.map +1 -1
- package/dist/utils/agents-md.js +25 -0
- package/dist/utils/agents-md.js.map +1 -1
- package/dist/utils/agents-model-table.d.ts.map +1 -1
- package/dist/utils/agents-model-table.js +2 -3
- package/dist/utils/agents-model-table.js.map +1 -1
- package/package.json +14 -7
- package/plugins/oh-my-codex/.app.json +3 -0
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +30 -0
- package/plugins/oh-my-codex/.mcp.json +44 -0
- package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +114 -0
- package/plugins/oh-my-codex/skills/analyze/SKILL.md +148 -0
- package/plugins/oh-my-codex/skills/ask-claude/SKILL.md +61 -0
- package/plugins/oh-my-codex/skills/ask-gemini/SKILL.md +61 -0
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +231 -0
- package/plugins/oh-my-codex/skills/autoresearch/SKILL.md +68 -0
- package/plugins/oh-my-codex/skills/cancel/SKILL.md +399 -0
- package/plugins/oh-my-codex/skills/code-review/SKILL.md +290 -0
- package/plugins/oh-my-codex/skills/configure-notifications/SKILL.md +287 -0
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +464 -0
- package/plugins/oh-my-codex/skills/doctor/SKILL.md +239 -0
- package/plugins/oh-my-codex/skills/help/SKILL.md +202 -0
- package/plugins/oh-my-codex/skills/hud/SKILL.md +98 -0
- package/plugins/oh-my-codex/skills/note/SKILL.md +62 -0
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +135 -0
- package/plugins/oh-my-codex/skills/pipeline/SKILL.md +86 -0
- package/plugins/oh-my-codex/skills/plan/SKILL.md +276 -0
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +269 -0
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +162 -0
- package/plugins/oh-my-codex/skills/security-review/SKILL.md +300 -0
- package/plugins/oh-my-codex/skills/skill/SKILL.md +835 -0
- package/plugins/oh-my-codex/skills/team/SKILL.md +510 -0
- package/plugins/oh-my-codex/skills/trace/SKILL.md +33 -0
- package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +143 -0
- package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +175 -0
- package/plugins/oh-my-codex/skills/visual-ralph/SKILL.md +153 -0
- package/plugins/oh-my-codex/skills/visual-verdict/SKILL.md +76 -0
- package/plugins/oh-my-codex/skills/wiki/SKILL.md +57 -0
- package/plugins/oh-my-codex/skills/worker/SKILL.md +106 -0
- package/prompts/critic.md +35 -83
- package/prompts/executor.md +32 -109
- package/prompts/explore-harness.md +1 -1
- package/prompts/explore.md +37 -90
- package/prompts/planner.md +28 -58
- package/prompts/researcher.md +46 -78
- package/prompts/verifier.md +23 -31
- package/skills/autopilot/SKILL.md +1 -4
- package/skills/deep-interview/SKILL.md +8 -5
- package/skills/doctor/SKILL.md +45 -17
- package/skills/help/SKILL.md +2 -2
- package/skills/omx-setup/SKILL.md +52 -9
- package/skills/plan/SKILL.md +1 -4
- package/skills/ralph/SKILL.md +3 -5
- package/skills/ralplan/SKILL.md +2 -6
- package/skills/team/SKILL.md +2 -5
- package/skills/ultraqa/SKILL.md +1 -4
- package/skills/ultrawork/SKILL.md +2 -3
- package/skills/visual-ralph/SKILL.md +153 -0
- package/skills/web-clone/SKILL.md +12 -354
- package/src/scripts/__tests__/codex-native-hook.test.ts +2306 -224
- package/src/scripts/__tests__/generate-release-body.test.ts +109 -0
- package/src/scripts/__tests__/hook-derived-watcher.test.ts +132 -2
- package/src/scripts/__tests__/postinstall.test.ts +7 -104
- package/src/scripts/__tests__/prompt-inventory.test.ts +64 -0
- package/src/scripts/__tests__/run-test-files.test.ts +72 -0
- package/src/scripts/__tests__/smoke-packed-install.test.ts +15 -0
- package/src/scripts/__tests__/verify-native-agents.test.ts +204 -0
- package/src/scripts/codex-execution-surface.ts +73 -0
- package/src/scripts/codex-native-hook.ts +579 -82
- package/src/scripts/codex-native-pre-post.ts +157 -19
- package/src/scripts/generate-release-body.ts +34 -2
- package/src/scripts/hook-derived-watcher.ts +51 -8
- package/src/scripts/notify-fallback-watcher.ts +65 -9
- package/src/scripts/notify-hook/__tests__/team-worker-posttooluse.test.ts +180 -0
- package/src/scripts/notify-hook/managed-tmux.ts +22 -4
- package/src/scripts/notify-hook/process-runner.ts +7 -3
- package/src/scripts/notify-hook/team-dispatch.ts +103 -11
- package/src/scripts/notify-hook/team-tmux-guard.ts +3 -3
- package/src/scripts/notify-hook/team-worker-posttooluse.ts +536 -0
- package/src/scripts/notify-hook/team-worker.ts +4 -48
- package/src/scripts/notify-hook.ts +36 -5
- package/src/scripts/postinstall.ts +4 -58
- package/src/scripts/prompt-inventory.ts +218 -0
- package/src/scripts/run-test-files.ts +41 -2
- package/src/scripts/smoke-packed-install.ts +10 -1
- package/src/scripts/sync-plugin-mirror.ts +360 -0
- package/src/scripts/verify-native-agents.ts +245 -0
- package/templates/AGENTS.md +26 -91
- package/templates/catalog-manifest.json +16 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "oh-my-codex-local",
|
|
3
|
+
"interface": {
|
|
4
|
+
"displayName": "oh-my-codex Local Plugins"
|
|
5
|
+
},
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "oh-my-codex",
|
|
9
|
+
"source": {
|
|
10
|
+
"source": "local",
|
|
11
|
+
"path": "./plugins/oh-my-codex"
|
|
12
|
+
},
|
|
13
|
+
"policy": {
|
|
14
|
+
"installation": "AVAILABLE",
|
|
15
|
+
"authentication": "ON_INSTALL"
|
|
16
|
+
},
|
|
17
|
+
"category": "Developer Tools"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
package/Cargo.lock
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This file is automatically @generated by Cargo.
|
|
2
2
|
# It is not intended for manual editing.
|
|
3
|
-
version =
|
|
3
|
+
version = 3
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "fs2"
|
|
@@ -32,11 +32,11 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
|
|
32
32
|
|
|
33
33
|
[[package]]
|
|
34
34
|
name = "omx-explore-harness"
|
|
35
|
-
version = "0.
|
|
35
|
+
version = "0.15.1"
|
|
36
36
|
|
|
37
37
|
[[package]]
|
|
38
38
|
name = "omx-mux"
|
|
39
|
-
version = "0.
|
|
39
|
+
version = "0.15.1"
|
|
40
40
|
dependencies = [
|
|
41
41
|
"serde",
|
|
42
42
|
"serde_json",
|
|
@@ -44,7 +44,7 @@ dependencies = [
|
|
|
44
44
|
|
|
45
45
|
[[package]]
|
|
46
46
|
name = "omx-runtime"
|
|
47
|
-
version = "0.
|
|
47
|
+
version = "0.15.1"
|
|
48
48
|
dependencies = [
|
|
49
49
|
"omx-mux",
|
|
50
50
|
"omx-runtime-core",
|
|
@@ -53,7 +53,7 @@ dependencies = [
|
|
|
53
53
|
|
|
54
54
|
[[package]]
|
|
55
55
|
name = "omx-runtime-core"
|
|
56
|
-
version = "0.
|
|
56
|
+
version = "0.15.1"
|
|
57
57
|
dependencies = [
|
|
58
58
|
"fs2",
|
|
59
59
|
"serde",
|
|
@@ -62,7 +62,7 @@ dependencies = [
|
|
|
62
62
|
|
|
63
63
|
[[package]]
|
|
64
64
|
name = "omx-sparkshell"
|
|
65
|
-
version = "0.
|
|
65
|
+
version = "0.15.1"
|
|
66
66
|
dependencies = [
|
|
67
67
|
"omx-mux",
|
|
68
68
|
]
|
package/Cargo.toml
CHANGED
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ It keeps Codex as the execution engine and makes it easier to:
|
|
|
51
51
|
| HaD0Yun | [@HaD0Yun](https://github.com/HaD0Yun) |
|
|
52
52
|
| Junho Yeo | [@junhoyeo](https://github.com/junhoyeo) |
|
|
53
53
|
| JiHongKim98 | [@JiHongKim98](https://github.com/JiHongKim98) |
|
|
54
|
-
| Lor |
|
|
54
|
+
| Lor | [@gobylor](https://github.com/gobylor) |
|
|
55
55
|
| HyunjunJeon | [@HyunjunJeon](https://github.com/HyunjunJeon) |
|
|
56
56
|
|
|
57
57
|
## Recommended default flow
|
|
@@ -63,7 +63,9 @@ npm install -g @openai/codex oh-my-codex
|
|
|
63
63
|
omx --madmax --high
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
On a real `oh-my-codex` version bump, the global npm install now
|
|
66
|
+
On a real `oh-my-codex` version bump, the global npm install now prints an explicit reminder instead of launching `omx setup` automatically. When you're ready, run `omx setup` manually or use `omx update` to check npm and then run the same setup refresh path.
|
|
67
|
+
|
|
68
|
+
**Codex plugin install note:** this repo also ships an official Codex plugin layout at `plugins/oh-my-codex` with marketplace metadata in `.agents/plugins/marketplace.json`. That plugin bundles the mirrored skill surface plus plugin-scoped companion metadata for MCP servers and apps. Native/runtime hooks still stay on the setup/runtime side rather than the installable plugin manifest. It is still **not** a replacement for `npm install -g oh-my-codex` plus `omx setup`: legacy setup mode installs native agents and prompts, while plugin setup mode relies on plugin discovery for bundled skills and archives/removes legacy OMX-managed prompts/native-agent TOMLs so stale role files cannot shadow plugin behavior.
|
|
67
69
|
|
|
68
70
|
Then work normally inside Codex:
|
|
69
71
|
|
|
@@ -116,13 +118,41 @@ Launch OMX the recommended way:
|
|
|
116
118
|
omx --madmax --high
|
|
117
119
|
```
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
On macOS/Linux interactive terminals with `tmux` available, this starts the
|
|
122
|
+
leader in OMX-managed detached tmux by default so the HUD/runtime panes can be
|
|
123
|
+
created and recovered.
|
|
124
|
+
|
|
125
|
+
If you want a one-off launch with no OMX tmux/HUD management, use `--direct`:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
omx --direct --yolo
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
For a persistent shell/profile preference, set an environment policy:
|
|
121
132
|
|
|
122
133
|
```bash
|
|
123
|
-
omx --
|
|
134
|
+
OMX_LAUNCH_POLICY=direct omx --yolo
|
|
124
135
|
```
|
|
125
136
|
|
|
137
|
+
Return to the auto/default behavior with:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
unset OMX_LAUNCH_POLICY
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
CLI policy flags win over the environment, and the last CLI policy flag before
|
|
144
|
+
`--` wins:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
OMX_LAUNCH_POLICY=direct omx --tmux --yolo
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Use `OMX_LAUNCH_POLICY=direct|tmux|detached-tmux|auto`. This iteration only
|
|
151
|
+
adds CLI and environment controls; it intentionally does not add a config-file
|
|
152
|
+
setting. If you run `--direct` from inside an existing tmux pane, OMX will not
|
|
153
|
+
create HUD splits, enable mouse mode, or wrap extended-key handling, but the
|
|
154
|
+
process still runs inside that already-open terminal pane.
|
|
155
|
+
|
|
126
156
|
Then try the canonical workflow:
|
|
127
157
|
|
|
128
158
|
```text
|
|
@@ -149,7 +179,7 @@ Most users should think of OMX as **better task routing + better workflow + bett
|
|
|
149
179
|
## Start here if you are new
|
|
150
180
|
|
|
151
181
|
1. Install or update OMX with `npm install -g @openai/codex oh-my-codex`
|
|
152
|
-
2.
|
|
182
|
+
2. After install or real OMX version bumps, run `omx setup` yourself when you're ready, or use `omx update` when you also want npm to check for and install the latest build before refreshing setup
|
|
153
183
|
3. Run `omx doctor`
|
|
154
184
|
4. Run a real execution smoke test: `codex login status` and `omx exec --skip-git-repo-check -C . "Reply with exactly OMX-EXEC-OK"`
|
|
155
185
|
5. Launch with `omx --madmax --high`
|
|
@@ -179,7 +209,7 @@ These are useful, but they are not the main onboarding path.
|
|
|
179
209
|
|
|
180
210
|
### Team runtime
|
|
181
211
|
|
|
182
|
-
Use the team runtime when you specifically need durable tmux/worktree coordination, not as the default way to begin using OMX.
|
|
212
|
+
Use the team runtime when you specifically need durable tmux/worktree coordination, not as the default way to begin using OMX. In Codex App or plain outside-tmux sessions, treat `omx team` as a tmux-runtime shell surface rather than a directly available in-app workflow; launch OMX CLI from shell first if you actually want team execution.
|
|
183
213
|
|
|
184
214
|
```bash
|
|
185
215
|
omx team 3:executor "fix the failing tests with verification"
|
|
@@ -191,8 +221,10 @@ omx team shutdown <team-name>
|
|
|
191
221
|
### Setup, doctor, and HUD
|
|
192
222
|
|
|
193
223
|
These are operator/support surfaces:
|
|
224
|
+
- Codex plugin marketplace install/discovery can cache the plugin under `${CODEX_HOME:-~/.codex}/plugins/cache/$MARKETPLACE_NAME/oh-my-codex/$VERSION/` (local installs may use `local` as the version identifier); that packaged plugin now includes plugin-scoped companion metadata for MCP servers and apps, while native/runtime hooks remain setup-owned, so it is still not the full OMX runtime setup
|
|
194
225
|
- `omx setup` installs prompts, skills, AGENTS scaffolding, `.codex/config.toml`, and OMX-managed native Codex hooks in `.codex/hooks.json`
|
|
195
226
|
- setup refresh preserves non-OMX hook entries in `.codex/hooks.json` and only rewrites OMX-managed wrappers
|
|
227
|
+
- `omx setup --merge-agents` preserves existing `AGENTS.md` guidance while inserting or refreshing generated OMX sections between `<!-- OMX:AGENTS:START -->` / `<!-- OMX:AGENTS:END -->`; without `--merge-agents` or `--force`, non-interactive setup keeps skipping existing `AGENTS.md` files
|
|
196
228
|
- `omx uninstall` removes OMX-managed wrappers from `.codex/hooks.json` but keeps the file when user hooks remain
|
|
197
229
|
- `omx update` checks npm immediately, installs the newest global OMX build, then reruns the same interactive setup refresh path
|
|
198
230
|
- fresh OMX-managed `gpt-5.5` config seeding now recommends `model_context_window = 250000` and `model_auto_compact_token_limit = 200000`, but only when those keys are missing
|
|
@@ -231,6 +263,7 @@ If `Shift+Enter` still submits instead of inserting a newline inside an OMX-mana
|
|
|
231
263
|
- `omx explore --prompt "..."` is for read-only repository lookup
|
|
232
264
|
- `omx sparkshell <command>` is for shell-native inspection and bounded verification
|
|
233
265
|
- when `.omx/wiki/` exists, `omx explore` can inject wiki-first context before falling back to broader repository search
|
|
266
|
+
- fallback boundaries are explicit: sparkshell-backend fallback is reported on stderr, and spark-model fallback emits stderr metadata plus an `## OMX Explore fallback` notice in stdout so users can see when cost/behavior may differ from the low-cost path
|
|
234
267
|
|
|
235
268
|
Examples:
|
|
236
269
|
|
|
@@ -38,10 +38,19 @@ struct AttemptResult {
|
|
|
38
38
|
output_markdown: Option<String>,
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
42
|
+
struct FallbackEvent {
|
|
43
|
+
from_model: String,
|
|
44
|
+
to_model: String,
|
|
45
|
+
exit_code: i32,
|
|
46
|
+
stderr: String,
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
#[derive(Debug)]
|
|
42
50
|
struct AllowlistEnvironment {
|
|
43
51
|
bin_dir: PathBuf,
|
|
44
52
|
shell_path: PathBuf,
|
|
53
|
+
sandbox_bin_dir: Option<PathBuf>,
|
|
45
54
|
_root: TempDirGuard,
|
|
46
55
|
}
|
|
47
56
|
|
|
@@ -110,21 +119,18 @@ where
|
|
|
110
119
|
return Ok(());
|
|
111
120
|
}
|
|
112
121
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
args.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
spark_attempt.stderr.trim()
|
|
121
|
-
);
|
|
122
|
-
}
|
|
122
|
+
let fallback_event = FallbackEvent {
|
|
123
|
+
from_model: args.spark_model.clone(),
|
|
124
|
+
to_model: args.fallback_model.clone(),
|
|
125
|
+
exit_code: spark_attempt.status_code,
|
|
126
|
+
stderr: spark_attempt.stderr.clone(),
|
|
127
|
+
};
|
|
128
|
+
emit_model_fallback_event(&fallback_event);
|
|
123
129
|
|
|
124
130
|
let fallback_attempt = invoke_codex(&args, &args.fallback_model, &prompt_contract)
|
|
125
131
|
.map_err(|err| format!("fallback attempt failed to launch: {err}"))?;
|
|
126
132
|
if fallback_attempt.status_code == 0 {
|
|
127
|
-
|
|
133
|
+
print_attempt_output_with_fallback(fallback_attempt, &fallback_event)?;
|
|
128
134
|
return Ok(());
|
|
129
135
|
}
|
|
130
136
|
|
|
@@ -139,7 +145,27 @@ where
|
|
|
139
145
|
}
|
|
140
146
|
|
|
141
147
|
fn print_attempt_output(attempt: AttemptResult) -> Result<(), String> {
|
|
148
|
+
print_attempt_output_with_optional_fallback(attempt, None)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
fn print_attempt_output_with_fallback(
|
|
152
|
+
attempt: AttemptResult,
|
|
153
|
+
fallback: &FallbackEvent,
|
|
154
|
+
) -> Result<(), String> {
|
|
155
|
+
print_attempt_output_with_optional_fallback(attempt, Some(fallback))
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
fn print_attempt_output_with_optional_fallback(
|
|
159
|
+
attempt: AttemptResult,
|
|
160
|
+
fallback: Option<&FallbackEvent>,
|
|
161
|
+
) -> Result<(), String> {
|
|
142
162
|
if let Some(markdown) = attempt.output_markdown {
|
|
163
|
+
if let Some(event) = fallback {
|
|
164
|
+
print!("{}", fallback_output_notice(event));
|
|
165
|
+
if !markdown.starts_with('\n') {
|
|
166
|
+
println!();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
143
169
|
print!("{}", markdown);
|
|
144
170
|
return Ok(());
|
|
145
171
|
}
|
|
@@ -149,6 +175,31 @@ fn print_attempt_output(attempt: AttemptResult) -> Result<(), String> {
|
|
|
149
175
|
)
|
|
150
176
|
}
|
|
151
177
|
|
|
178
|
+
fn emit_model_fallback_event(event: &FallbackEvent) {
|
|
179
|
+
eprintln!("{}", fallback_attempt_event_message(event));
|
|
180
|
+
eprintln!(
|
|
181
|
+
"[omx explore] spark model `{}` unavailable or failed (exit {}). Falling back to `{}`.",
|
|
182
|
+
event.from_model, event.exit_code, event.to_model
|
|
183
|
+
);
|
|
184
|
+
if !event.stderr.trim().is_empty() {
|
|
185
|
+
eprintln!("[omx explore] spark stderr: {}", event.stderr.trim());
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
fn fallback_attempt_event_message(event: &FallbackEvent) -> String {
|
|
190
|
+
format!(
|
|
191
|
+
"[omx explore] fallback-attempt=model from=`{}` to=`{}` reason=spark_attempt_failed exit={}. Cost/behavior boundary changed if fallback succeeds; stdout fallback notice is emitted only after successful fallback output.",
|
|
192
|
+
event.from_model, event.to_model, event.exit_code
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
fn fallback_output_notice(event: &FallbackEvent) -> String {
|
|
197
|
+
format!(
|
|
198
|
+
"## OMX Explore fallback\n- fallback: model\n- from: `{}`\n- to: `{}`\n- reason: spark attempt failed with exit {}\n- boundary: cost/behavior may differ from the low-cost spark path\n",
|
|
199
|
+
event.from_model, event.to_model, event.exit_code
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
152
203
|
fn parse_args<I>(mut args: I) -> Result<Args, String>
|
|
153
204
|
where
|
|
154
205
|
I: Iterator<Item = OsString>,
|
|
@@ -211,9 +262,11 @@ fn usage() -> &'static str {
|
|
|
211
262
|
"Usage: omx-explore --cwd <dir> --prompt <text> --prompt-file <explore-prompt.md> --instructions-file <AGENTS.md> --model-spark <model> --model-fallback <model>"
|
|
212
263
|
}
|
|
213
264
|
|
|
265
|
+
#[allow(unknown_lints, clippy::io_other_error)]
|
|
214
266
|
fn invoke_codex(args: &Args, model: &str, prompt_contract: &str) -> io::Result<AttemptResult> {
|
|
215
267
|
let codex_launch = resolve_codex_launch();
|
|
216
|
-
let allowlist =
|
|
268
|
+
let allowlist =
|
|
269
|
+
prepare_allowlist_environment().map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
|
|
217
270
|
let output_path = temp_output_path();
|
|
218
271
|
let final_prompt = compose_exec_prompt(&args.prompt, prompt_contract);
|
|
219
272
|
let mut command = Command::new(&codex_launch.program);
|
|
@@ -241,7 +294,11 @@ fn invoke_codex(args: &Args, model: &str, prompt_contract: &str) -> io::Result<A
|
|
|
241
294
|
.arg(&output_path)
|
|
242
295
|
.arg(&final_prompt)
|
|
243
296
|
.env(HARNESS_ROOT_ENV, &args.cwd)
|
|
244
|
-
.env(
|
|
297
|
+
.env(
|
|
298
|
+
"PATH",
|
|
299
|
+
build_codex_path(&allowlist.bin_dir, allowlist.sandbox_bin_dir.as_deref())
|
|
300
|
+
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?,
|
|
301
|
+
)
|
|
245
302
|
.env("SHELL", &allowlist.shell_path);
|
|
246
303
|
sanitize_explore_subprocess_env(&mut command);
|
|
247
304
|
let output = command.output()?;
|
|
@@ -531,13 +588,49 @@ fn prepare_allowlist_environment() -> Result<AllowlistEnvironment, String> {
|
|
|
531
588
|
write_executable(&shell_path, &bash_wrapper)?;
|
|
532
589
|
write_executable(&bin_dir.join("sh"), &sh_wrapper)?;
|
|
533
590
|
|
|
591
|
+
let sandbox_bin_dir = prepare_sandbox_dependency_bin(&root.path)?;
|
|
592
|
+
|
|
534
593
|
Ok(AllowlistEnvironment {
|
|
535
594
|
bin_dir,
|
|
536
595
|
shell_path,
|
|
596
|
+
sandbox_bin_dir,
|
|
537
597
|
_root: root,
|
|
538
598
|
})
|
|
539
599
|
}
|
|
540
600
|
|
|
601
|
+
fn build_codex_path(
|
|
602
|
+
allowlist_bin_dir: &Path,
|
|
603
|
+
sandbox_bin_dir: Option<&Path>,
|
|
604
|
+
) -> Result<OsString, String> {
|
|
605
|
+
let mut entries = vec![allowlist_bin_dir.to_path_buf()];
|
|
606
|
+
if let Some(sandbox_bin_dir) = sandbox_bin_dir {
|
|
607
|
+
entries.push(sandbox_bin_dir.to_path_buf());
|
|
608
|
+
}
|
|
609
|
+
env::join_paths(entries).map_err(|err| format!("failed to construct restricted PATH: {err}"))
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
fn prepare_sandbox_dependency_bin(root: &Path) -> Result<Option<PathBuf>, String> {
|
|
613
|
+
let Some(bwrap_path) = resolve_host_command("bwrap") else {
|
|
614
|
+
return Ok(None);
|
|
615
|
+
};
|
|
616
|
+
|
|
617
|
+
let sandbox_bin_dir = root.join("sandbox-bin");
|
|
618
|
+
create_dir_all(&sandbox_bin_dir).map_err(|err| {
|
|
619
|
+
format!(
|
|
620
|
+
"failed to create sandbox dependency bin dir {}: {err}",
|
|
621
|
+
sandbox_bin_dir.display()
|
|
622
|
+
)
|
|
623
|
+
})?;
|
|
624
|
+
write_executable(
|
|
625
|
+
&sandbox_bin_dir.join("bwrap"),
|
|
626
|
+
&format!(
|
|
627
|
+
"#!/bin/sh\nexec {} \"$@\"\n",
|
|
628
|
+
shell_quote(&bwrap_path.display().to_string())
|
|
629
|
+
),
|
|
630
|
+
)?;
|
|
631
|
+
Ok(Some(sandbox_bin_dir))
|
|
632
|
+
}
|
|
633
|
+
|
|
541
634
|
fn allowlist_platform_diagnostic(os: &str) -> Option<&'static str> {
|
|
542
635
|
if os.eq_ignore_ascii_case("windows") {
|
|
543
636
|
return Some(WINDOWS_UNSUPPORTED_ALLOWLIST_MESSAGE);
|
|
@@ -745,7 +838,7 @@ fn validate_shell_invocation(args: &[String]) -> Result<String, String> {
|
|
|
745
838
|
|
|
746
839
|
let tokens: Vec<String> = command
|
|
747
840
|
.split_whitespace()
|
|
748
|
-
.map(|token| token.trim_matches(
|
|
841
|
+
.map(|token| token.trim_matches(|ch| ch == '"' || ch == '\'').to_string())
|
|
749
842
|
.filter(|token| !token.is_empty())
|
|
750
843
|
.collect();
|
|
751
844
|
let first = tokens
|
|
@@ -884,19 +977,28 @@ fn validate_repo_paths(command_name: &str, args: &[String]) -> Result<(), String
|
|
|
884
977
|
let candidate_paths = command_path_operands(command_name, args);
|
|
885
978
|
for operand in candidate_paths {
|
|
886
979
|
let normalized = normalize_candidate_path(&repo_root, operand);
|
|
887
|
-
|
|
980
|
+
let canonical_candidate = canonicalize_existing_prefix(&normalized);
|
|
981
|
+
let is_textually_inside = normalized.starts_with(&repo_root);
|
|
982
|
+
let is_canonically_inside = match (&canonical_candidate, &canonical_repo_root) {
|
|
983
|
+
(Some(candidate), Some(root)) => candidate.starts_with(root),
|
|
984
|
+
_ => false,
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
if !is_textually_inside && !is_canonically_inside {
|
|
888
988
|
return Err(format!(
|
|
889
989
|
"path `{operand}` escapes the omx explore repository root {}",
|
|
890
990
|
repo_root.display()
|
|
891
991
|
));
|
|
892
992
|
}
|
|
893
|
-
if
|
|
894
|
-
if let Some(
|
|
895
|
-
if
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
993
|
+
if is_textually_inside {
|
|
994
|
+
if let Some(canonical_candidate) = canonical_candidate {
|
|
995
|
+
if let Some(canonical_repo_root) = &canonical_repo_root {
|
|
996
|
+
if !canonical_candidate.starts_with(canonical_repo_root) {
|
|
997
|
+
return Err(format!(
|
|
998
|
+
"path `{operand}` resolves outside the omx explore repository root {}",
|
|
999
|
+
canonical_repo_root.display()
|
|
1000
|
+
));
|
|
1001
|
+
}
|
|
900
1002
|
}
|
|
901
1003
|
}
|
|
902
1004
|
}
|
|
@@ -971,6 +1073,7 @@ fn canonicalize_existing_prefix(path: &Path) -> Option<PathBuf> {
|
|
|
971
1073
|
}
|
|
972
1074
|
|
|
973
1075
|
#[cfg(test)]
|
|
1076
|
+
#[allow(unused_unsafe)]
|
|
974
1077
|
mod tests {
|
|
975
1078
|
use super::*;
|
|
976
1079
|
use std::sync::{Mutex, OnceLock};
|
|
@@ -1162,7 +1265,7 @@ exec node "$basedir/../@openai/codex/bin/codex.js" "$@"
|
|
|
1162
1265
|
create_dir_all(&good_bin).expect("create good bin");
|
|
1163
1266
|
|
|
1164
1267
|
let blocked_directory = bad_bin.join("node");
|
|
1165
|
-
create_dir_all(
|
|
1268
|
+
create_dir_all(blocked_directory).expect("create blocked directory");
|
|
1166
1269
|
|
|
1167
1270
|
let blocked_node = blocked_file_bin.join("node");
|
|
1168
1271
|
write(&blocked_node, "#!/bin/sh\nexit 0\n").expect("write blocked file node");
|
|
@@ -1280,6 +1383,88 @@ exec node "$basedir/../@openai/codex/bin/codex.js" "$@"
|
|
|
1280
1383
|
result
|
|
1281
1384
|
}
|
|
1282
1385
|
|
|
1386
|
+
#[test]
|
|
1387
|
+
fn build_codex_path_keeps_allowlist_first_and_only_adds_sandbox_bin() {
|
|
1388
|
+
let allowlist_bin = Path::new("/tmp/omx-explore-allowlist/bin");
|
|
1389
|
+
let sandbox_bin = Path::new("/tmp/omx-explore-sandbox-bin");
|
|
1390
|
+
|
|
1391
|
+
let path = build_codex_path(allowlist_bin, Some(sandbox_bin)).expect("restricted path");
|
|
1392
|
+
let entries: Vec<PathBuf> = env::split_paths(&path).collect();
|
|
1393
|
+
|
|
1394
|
+
assert_eq!(
|
|
1395
|
+
entries,
|
|
1396
|
+
vec![allowlist_bin.to_path_buf(), sandbox_bin.to_path_buf()]
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
#[test]
|
|
1401
|
+
fn build_codex_path_omits_sandbox_bin_when_bwrap_is_absent() {
|
|
1402
|
+
let allowlist_bin = Path::new("/tmp/omx-explore-allowlist/bin");
|
|
1403
|
+
|
|
1404
|
+
let path = build_codex_path(allowlist_bin, None).expect("restricted path");
|
|
1405
|
+
let entries: Vec<PathBuf> = env::split_paths(&path).collect();
|
|
1406
|
+
|
|
1407
|
+
assert_eq!(entries, vec![allowlist_bin.to_path_buf()]);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
#[cfg(unix)]
|
|
1411
|
+
#[test]
|
|
1412
|
+
fn prepare_allowlist_environment_adds_controlled_bwrap_without_host_path() {
|
|
1413
|
+
let _guard = env_lock();
|
|
1414
|
+
let mut commands = vec!["bash", "sh"];
|
|
1415
|
+
commands.extend(
|
|
1416
|
+
ALLOWED_DIRECT_COMMANDS
|
|
1417
|
+
.iter()
|
|
1418
|
+
.copied()
|
|
1419
|
+
.filter(|command| *command != "rg"),
|
|
1420
|
+
);
|
|
1421
|
+
let (_root, host_bin) = create_host_bin_with_commands(&commands);
|
|
1422
|
+
let fake_bwrap = host_bin.join("bwrap");
|
|
1423
|
+
write_executable(&fake_bwrap, "#!/bin/sh\nexit 0\n").expect("write fake bwrap");
|
|
1424
|
+
|
|
1425
|
+
let allowlist =
|
|
1426
|
+
with_path(&host_bin, prepare_allowlist_environment).expect("allowlist environment");
|
|
1427
|
+
let sandbox_bin = allowlist
|
|
1428
|
+
.sandbox_bin_dir
|
|
1429
|
+
.as_ref()
|
|
1430
|
+
.expect("sandbox bin when bwrap exists");
|
|
1431
|
+
let path = build_codex_path(&allowlist.bin_dir, allowlist.sandbox_bin_dir.as_deref())
|
|
1432
|
+
.expect("codex path");
|
|
1433
|
+
let entries: Vec<PathBuf> = env::split_paths(&path).collect();
|
|
1434
|
+
|
|
1435
|
+
assert_eq!(
|
|
1436
|
+
entries,
|
|
1437
|
+
vec![allowlist.bin_dir.clone(), sandbox_bin.clone()]
|
|
1438
|
+
);
|
|
1439
|
+
assert!(!entries.contains(&host_bin));
|
|
1440
|
+
let controlled_bwrap =
|
|
1441
|
+
read_to_string(sandbox_bin.join("bwrap")).expect("read controlled bwrap");
|
|
1442
|
+
assert!(controlled_bwrap.contains(&fake_bwrap.display().to_string()));
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
#[cfg(unix)]
|
|
1446
|
+
#[test]
|
|
1447
|
+
fn prepare_allowlist_environment_leaves_path_allowlist_only_without_bwrap() {
|
|
1448
|
+
let _guard = env_lock();
|
|
1449
|
+
let mut commands = vec!["bash", "sh"];
|
|
1450
|
+
commands.extend(
|
|
1451
|
+
ALLOWED_DIRECT_COMMANDS
|
|
1452
|
+
.iter()
|
|
1453
|
+
.copied()
|
|
1454
|
+
.filter(|command| *command != "rg"),
|
|
1455
|
+
);
|
|
1456
|
+
let (_root, host_bin) = create_host_bin_with_commands(&commands);
|
|
1457
|
+
|
|
1458
|
+
let allowlist =
|
|
1459
|
+
with_path(&host_bin, prepare_allowlist_environment).expect("allowlist environment");
|
|
1460
|
+
let path = build_codex_path(&allowlist.bin_dir, allowlist.sandbox_bin_dir.as_deref())
|
|
1461
|
+
.expect("codex path");
|
|
1462
|
+
let entries: Vec<PathBuf> = env::split_paths(&path).collect();
|
|
1463
|
+
|
|
1464
|
+
assert!(allowlist.sandbox_bin_dir.is_none());
|
|
1465
|
+
assert_eq!(entries, vec![allowlist.bin_dir]);
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1283
1468
|
#[cfg(unix)]
|
|
1284
1469
|
#[test]
|
|
1285
1470
|
fn prepare_allowlist_environment_tolerates_missing_rg_by_stubbing_wrapper() {
|
|
@@ -1808,7 +1993,7 @@ printf '# Answer\nok\n' > "$output_path"
|
|
|
1808
1993
|
unsafe {
|
|
1809
1994
|
env::set_var("BASH_ENV", &bash_env);
|
|
1810
1995
|
}
|
|
1811
|
-
let mut child = Command::new(
|
|
1996
|
+
let mut child = Command::new(bash_path);
|
|
1812
1997
|
child
|
|
1813
1998
|
.arg("--noprofile")
|
|
1814
1999
|
.arg("--norc")
|
|
@@ -1824,6 +2009,43 @@ printf '# Answer\nok\n' > "$output_path"
|
|
|
1824
2009
|
assert_eq!(read_to_string(&bash_env_log).unwrap_or_default(), "");
|
|
1825
2010
|
}
|
|
1826
2011
|
|
|
2012
|
+
fn fallback_test_event() -> FallbackEvent {
|
|
2013
|
+
FallbackEvent {
|
|
2014
|
+
from_model: "spark-model".to_string(),
|
|
2015
|
+
to_model: "fallback-model".to_string(),
|
|
2016
|
+
exit_code: 17,
|
|
2017
|
+
stderr: "spark timed out".to_string(),
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
#[test]
|
|
2022
|
+
fn fallback_attempt_event_distinguishes_attempt_from_output_notice() {
|
|
2023
|
+
let event = fallback_test_event();
|
|
2024
|
+
|
|
2025
|
+
let message = fallback_attempt_event_message(&event);
|
|
2026
|
+
assert!(message.contains("fallback-attempt=model"));
|
|
2027
|
+
assert!(message.contains("from=`spark-model`"));
|
|
2028
|
+
assert!(message.contains("to=`fallback-model`"));
|
|
2029
|
+
assert!(message.contains("spark_attempt_failed exit=17"));
|
|
2030
|
+
assert!(message
|
|
2031
|
+
.contains("stdout fallback notice is emitted only after successful fallback output"));
|
|
2032
|
+
assert!(!message.contains("output includes a fallback notice"));
|
|
2033
|
+
assert!(!message.contains("## OMX Explore fallback"));
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
#[test]
|
|
2037
|
+
fn fallback_output_notice_records_model_boundary() {
|
|
2038
|
+
let event = fallback_test_event();
|
|
2039
|
+
|
|
2040
|
+
let notice = fallback_output_notice(&event);
|
|
2041
|
+
assert!(notice.contains("## OMX Explore fallback"));
|
|
2042
|
+
assert!(notice.contains("fallback: model"));
|
|
2043
|
+
assert!(notice.contains("from: `spark-model`"));
|
|
2044
|
+
assert!(notice.contains("to: `fallback-model`"));
|
|
2045
|
+
assert!(notice.contains("spark attempt failed with exit 17"));
|
|
2046
|
+
assert!(notice.contains("cost/behavior may differ from the low-cost spark path"));
|
|
2047
|
+
}
|
|
2048
|
+
|
|
1827
2049
|
#[test]
|
|
1828
2050
|
fn print_attempt_output_requires_markdown_artifact() {
|
|
1829
2051
|
let result = print_attempt_output(AttemptResult {
|
|
@@ -236,8 +236,9 @@ fn epoch_days_to_date(total_days: u64) -> (u64, u64, u64) {
|
|
|
236
236
|
(year, month, days + 1)
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
#[allow(unknown_lints, clippy::manual_is_multiple_of)]
|
|
239
240
|
fn is_leap(year: u64) -> bool {
|
|
240
|
-
year
|
|
241
|
+
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
|
|
241
242
|
}
|
|
242
243
|
|
|
243
244
|
#[cfg(test)]
|
|
@@ -236,7 +236,7 @@ impl RuntimeEngine {
|
|
|
236
236
|
std::fs::create_dir_all(dir)?;
|
|
237
237
|
|
|
238
238
|
let lock_file = std::fs::File::create(dir.join("engine.lock"))?;
|
|
239
|
-
|
|
239
|
+
FileExt::lock_exclusive(&lock_file)?;
|
|
240
240
|
|
|
241
241
|
let snapshot_json = serde_json::to_string_pretty(&self.snapshot())?;
|
|
242
242
|
std::fs::write(dir.join("snapshot.json"), snapshot_json)?;
|
|
@@ -291,7 +291,7 @@ impl RuntimeEngine {
|
|
|
291
291
|
let lock_path = dir.join("engine.lock");
|
|
292
292
|
let lock_file =
|
|
293
293
|
std::fs::File::open(&lock_path).or_else(|_| std::fs::File::create(&lock_path))?;
|
|
294
|
-
|
|
294
|
+
FileExt::lock_shared(&lock_file)?;
|
|
295
295
|
|
|
296
296
|
let events_json = std::fs::read_to_string(dir.join("events.json"))?;
|
|
297
297
|
let mut events: Vec<RuntimeEvent> = serde_json::from_str(&events_json)?;
|
|
@@ -153,8 +153,9 @@ fn epoch_days_to_date(total_days: u64) -> (u64, u64, u64) {
|
|
|
153
153
|
(year, month, days + 1)
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
#[allow(unknown_lints, clippy::manual_is_multiple_of)]
|
|
156
157
|
fn is_leap(year: u64) -> bool {
|
|
157
|
-
year
|
|
158
|
+
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
#[cfg(test)]
|