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
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildDocumentRefreshAdvisoryOutput,
|
|
3
|
+
evaluateStagedDocumentRefresh,
|
|
4
|
+
} from "../document-refresh/enforcer.js";
|
|
5
|
+
import { resolveCodexExecutionSurface } from "./codex-execution-surface.js";
|
|
6
|
+
|
|
1
7
|
type CodexHookPayload = Record<string, unknown>;
|
|
2
8
|
|
|
9
|
+
type GitRepositorySelection = "current-cwd" | "explicit-target";
|
|
10
|
+
|
|
3
11
|
export interface NormalizedPreToolUsePayload {
|
|
4
12
|
toolName: string;
|
|
5
13
|
toolUseId: string;
|
|
@@ -45,6 +53,16 @@ function safeObject(value: unknown): Record<string, unknown> | null {
|
|
|
45
53
|
: null;
|
|
46
54
|
}
|
|
47
55
|
|
|
56
|
+
function isNativeOutsideTmuxSurface(payload: CodexHookPayload): boolean {
|
|
57
|
+
const cwd = safeString(payload.cwd).trim() || process.cwd();
|
|
58
|
+
const surface = resolveCodexExecutionSurface(cwd, {
|
|
59
|
+
hookEventName: "PreToolUse",
|
|
60
|
+
payload,
|
|
61
|
+
nativeSessionId: safeString(payload.session_id ?? payload.sessionId).trim(),
|
|
62
|
+
});
|
|
63
|
+
return surface.launcher === "native" && surface.transport === "outside-tmux";
|
|
64
|
+
}
|
|
65
|
+
|
|
48
66
|
function tryParseJsonString(value: unknown): Record<string, unknown> | null {
|
|
49
67
|
const text = safeString(value).trim();
|
|
50
68
|
if (!text) return null;
|
|
@@ -134,6 +152,7 @@ export function detectMcpTransportFailure(
|
|
|
134
152
|
payload: CodexHookPayload,
|
|
135
153
|
): McpTransportFailureSignal | null {
|
|
136
154
|
const normalized = normalizePostToolUsePayload(payload);
|
|
155
|
+
if (normalized.isBash) return null;
|
|
137
156
|
const combined = [
|
|
138
157
|
normalized.stderrText,
|
|
139
158
|
normalized.stdoutText,
|
|
@@ -268,6 +287,7 @@ function tokenizeShellCommand(commandText: string): string[] | null {
|
|
|
268
287
|
interface GitCommitCommandParseResult {
|
|
269
288
|
isGitCommit: boolean;
|
|
270
289
|
inlineMessage: string | null;
|
|
290
|
+
repositorySelection: GitRepositorySelection;
|
|
271
291
|
requiresExternalMessageSource: boolean;
|
|
272
292
|
}
|
|
273
293
|
|
|
@@ -348,6 +368,14 @@ function gitOptionConsumesNextValue(token: string): boolean {
|
|
|
348
368
|
|| token === "--attr-source";
|
|
349
369
|
}
|
|
350
370
|
|
|
371
|
+
function gitOptionSelectsRepository(token: string): boolean {
|
|
372
|
+
return token === "-C"
|
|
373
|
+
|| token === "--git-dir"
|
|
374
|
+
|| token === "--work-tree"
|
|
375
|
+
|| token.startsWith("--git-dir=")
|
|
376
|
+
|| token.startsWith("--work-tree=");
|
|
377
|
+
}
|
|
378
|
+
|
|
351
379
|
function gitOptionStopsBeforeSubcommand(token: string): boolean {
|
|
352
380
|
return token === "-h"
|
|
353
381
|
|| token === "--help"
|
|
@@ -382,12 +410,22 @@ function findGitSubcommandIndex(tokens: string[], gitTokenIndex: number): number
|
|
|
382
410
|
return index < tokens.length ? index : -1;
|
|
383
411
|
}
|
|
384
412
|
|
|
385
|
-
function
|
|
413
|
+
function readGitRepositorySelection(tokens: string[], gitTokenIndex: number, subcommandIndex: number): GitRepositorySelection {
|
|
414
|
+
for (let index = gitTokenIndex + 1; index < subcommandIndex; index += 1) {
|
|
415
|
+
const token = tokens[index] ?? "";
|
|
416
|
+
if (gitOptionSelectsRepository(token)) return "explicit-target";
|
|
417
|
+
if (gitOptionConsumesNextValue(token)) index += 1;
|
|
418
|
+
}
|
|
419
|
+
return "current-cwd";
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
export function parseGitCommitCommand(commandText: string): GitCommitCommandParseResult {
|
|
386
423
|
const tokens = tokenizeShellCommand(commandText);
|
|
387
424
|
if (!tokens) {
|
|
388
425
|
return {
|
|
389
426
|
isGitCommit: false,
|
|
390
427
|
inlineMessage: null,
|
|
428
|
+
repositorySelection: "current-cwd",
|
|
391
429
|
requiresExternalMessageSource: false,
|
|
392
430
|
};
|
|
393
431
|
}
|
|
@@ -397,6 +435,7 @@ function parseGitCommitCommand(commandText: string): GitCommitCommandParseResult
|
|
|
397
435
|
return {
|
|
398
436
|
isGitCommit: false,
|
|
399
437
|
inlineMessage: null,
|
|
438
|
+
repositorySelection: "current-cwd",
|
|
400
439
|
requiresExternalMessageSource: false,
|
|
401
440
|
};
|
|
402
441
|
}
|
|
@@ -406,10 +445,12 @@ function parseGitCommitCommand(commandText: string): GitCommitCommandParseResult
|
|
|
406
445
|
return {
|
|
407
446
|
isGitCommit: false,
|
|
408
447
|
inlineMessage: null,
|
|
448
|
+
repositorySelection: "current-cwd",
|
|
409
449
|
requiresExternalMessageSource: false,
|
|
410
450
|
};
|
|
411
451
|
}
|
|
412
452
|
|
|
453
|
+
const repositorySelection = readGitRepositorySelection(tokens, gitTokenIndex, subcommandIndex);
|
|
413
454
|
const messageParts: string[] = [];
|
|
414
455
|
let requiresExternalMessageSource = false;
|
|
415
456
|
const args = tokens.slice(subcommandIndex + 1);
|
|
@@ -452,6 +493,7 @@ function parseGitCommitCommand(commandText: string): GitCommitCommandParseResult
|
|
|
452
493
|
return {
|
|
453
494
|
isGitCommit: true,
|
|
454
495
|
inlineMessage: messageParts.length > 0 ? messageParts.join("\n\n").trim() : null,
|
|
496
|
+
repositorySelection,
|
|
455
497
|
requiresExternalMessageSource,
|
|
456
498
|
};
|
|
457
499
|
}
|
|
@@ -550,10 +592,6 @@ function buildGitCommitEnforcementOutput(commandText: string): Record<string, un
|
|
|
550
592
|
"git commit is blocked until the inline commit message satisfies the Lore format and includes the required OmX co-author trailer.",
|
|
551
593
|
hookSpecificOutput: {
|
|
552
594
|
hookEventName: "PreToolUse",
|
|
553
|
-
additionalContext: [
|
|
554
|
-
"Lore-format git commit enforcement triggered.",
|
|
555
|
-
...errors.map((error) => `- ${error}`),
|
|
556
|
-
].join("\n"),
|
|
557
595
|
},
|
|
558
596
|
systemMessage: [
|
|
559
597
|
"git commit is blocked until the inline commit message follows the Lore protocol and includes `Co-authored-by: OmX <omx@oh-my-codex.dev>`.",
|
|
@@ -562,6 +600,22 @@ function buildGitCommitEnforcementOutput(commandText: string): Record<string, un
|
|
|
562
600
|
};
|
|
563
601
|
}
|
|
564
602
|
|
|
603
|
+
|
|
604
|
+
function buildDocumentRefreshPreToolUseOutput(
|
|
605
|
+
commandText: string,
|
|
606
|
+
cwd: string,
|
|
607
|
+
): Record<string, unknown> | null {
|
|
608
|
+
const parsed = parseGitCommitCommand(commandText);
|
|
609
|
+
if (!parsed.isGitCommit) return null;
|
|
610
|
+
|
|
611
|
+
if (parsed.repositorySelection !== "current-cwd") return null;
|
|
612
|
+
|
|
613
|
+
const warning = evaluateStagedDocumentRefresh(cwd, parsed.inlineMessage);
|
|
614
|
+
if (!warning) return null;
|
|
615
|
+
|
|
616
|
+
return buildDocumentRefreshAdvisoryOutput(warning, "PreToolUse");
|
|
617
|
+
}
|
|
618
|
+
|
|
565
619
|
function commandInvokesOmxQuestion(command: string): boolean {
|
|
566
620
|
const tokens = tokenizeShellCommand(command)?.map((token) => token.toLowerCase()) ?? [];
|
|
567
621
|
for (let index = 0; index < tokens.length; index += 1) {
|
|
@@ -582,26 +636,95 @@ function isQuestionReturnPaneAssignment(token: string): boolean {
|
|
|
582
636
|
return /^%\d+$/.test(value) || /^\$\{?TMUX_PANE\}?$/.test(value);
|
|
583
637
|
}
|
|
584
638
|
|
|
639
|
+
function hasInheritedQuestionReturnPaneBridge(): boolean {
|
|
640
|
+
// Intentionally trust only the explicit bridge envs that question renderer
|
|
641
|
+
// already accepts outside tmux; TMUX_PANE alone is not stable across all
|
|
642
|
+
// Bash/background-terminal tool paths that this enforcement protects.
|
|
643
|
+
const explicitPane = safeString(
|
|
644
|
+
process.env.OMX_QUESTION_RETURN_PANE || process.env.OMX_LEADER_PANE_ID,
|
|
645
|
+
).trim();
|
|
646
|
+
return /^%\d+$/.test(explicitPane);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
function commandHasPowerShellQuestionReturnPane(command: string): boolean {
|
|
650
|
+
return /\$env:(?:OMX_QUESTION_RETURN_PANE|OMX_LEADER_PANE_ID)\s*=\s*(?:['"]?%\d+['"]?|\$env:TMUX_PANE)\b/i.test(command)
|
|
651
|
+
|| /\$env:TMUX_PANE\s*=\s*['"]?%\d+['"]?/i.test(command);
|
|
652
|
+
}
|
|
653
|
+
|
|
585
654
|
function commandHasQuestionReturnPane(command: string): boolean {
|
|
655
|
+
if (hasInheritedQuestionReturnPaneBridge()) return true;
|
|
656
|
+
if (commandHasPowerShellQuestionReturnPane(command)) return true;
|
|
586
657
|
return (tokenizeShellCommand(command) ?? []).some(isQuestionReturnPaneAssignment);
|
|
587
658
|
}
|
|
588
659
|
|
|
589
|
-
function
|
|
660
|
+
function commandInvokesOmxTeam(command: string): boolean {
|
|
661
|
+
const tokens = tokenizeShellCommand(command)?.map((token) => token.toLowerCase()) ?? [];
|
|
662
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
663
|
+
const rawToken = tokens[index] || '';
|
|
664
|
+
const token = rawToken.replace(/\\/g, '/').split('/').pop() || '';
|
|
665
|
+
if ((token === 'omx' || token === 'omx.js') && tokens[index + 1] === 'team') return true;
|
|
666
|
+
if ((token === 'node' || token === 'node.exe') && /(?:^|\/)omx\.js$/.test(tokens[index + 1] || '') && tokens[index + 2] === 'team') return true;
|
|
667
|
+
}
|
|
668
|
+
return /\bomx\s+team\b/i.test(command) || /\bomx\.js['"]?\s+team\b/i.test(command);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
function commandInvokesOmxHud(command: string): boolean {
|
|
672
|
+
const tokens = tokenizeShellCommand(command)?.map((token) => token.toLowerCase()) ?? [];
|
|
673
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
674
|
+
const rawToken = tokens[index] || '';
|
|
675
|
+
const token = rawToken.replace(/\\/g, '/').split('/').pop() || '';
|
|
676
|
+
if ((token === 'omx' || token === 'omx.js') && tokens[index + 1] === 'hud') return true;
|
|
677
|
+
if ((token === 'node' || token === 'node.exe') && /(?:^|\/)omx\.js$/.test(tokens[index + 1] || '') && tokens[index + 2] === 'hud') return true;
|
|
678
|
+
}
|
|
679
|
+
return /\bomx\s+hud\b/i.test(command) || /\bomx\.js['"]?\s+hud\b/i.test(command);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
function buildNativeOmxHudPreToolUseEnforcementOutput(
|
|
683
|
+
command: string,
|
|
684
|
+
payload: CodexHookPayload,
|
|
685
|
+
): Record<string, unknown> | null {
|
|
686
|
+
if (!isNativeOutsideTmuxSurface(payload) || !commandInvokesOmxHud(command)) return null;
|
|
687
|
+
|
|
688
|
+
return {
|
|
689
|
+
decision: "block",
|
|
690
|
+
reason: "omx hud cannot be launched directly from Codex App/native outside-tmux Bash sessions.",
|
|
691
|
+
systemMessage: "omx hud is blocked from Bash in Codex App/native outside-tmux sessions; use SessionStart/HUD context instead, or launch OMX CLI from an attached tmux shell first for the tmux HUD runtime.",
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function buildNativeOmxTeamPreToolUseEnforcementOutput(
|
|
696
|
+
command: string,
|
|
697
|
+
payload: CodexHookPayload,
|
|
698
|
+
): Record<string, unknown> | null {
|
|
699
|
+
if (!isNativeOutsideTmuxSurface(payload) || !commandInvokesOmxTeam(command)) return null;
|
|
700
|
+
|
|
701
|
+
return {
|
|
702
|
+
decision: "block",
|
|
703
|
+
reason: "omx team cannot be launched directly from Codex App/native outside-tmux Bash sessions.",
|
|
704
|
+
systemMessage: `omx team is blocked from Bash in Codex App/native outside-tmux sessions; launch OMX CLI from an attached tmux shell first. Original command: ${command}`,
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
function buildOmxQuestionPreToolUseEnforcementOutput(
|
|
709
|
+
command: string,
|
|
710
|
+
payload: CodexHookPayload,
|
|
711
|
+
): Record<string, unknown> | null {
|
|
590
712
|
if (!commandInvokesOmxQuestion(command)) return null;
|
|
713
|
+
|
|
714
|
+
if (isNativeOutsideTmuxSurface(payload)) {
|
|
715
|
+
return {
|
|
716
|
+
decision: "block",
|
|
717
|
+
reason: "omx question cannot be launched directly from Codex App/native outside-tmux Bash sessions.",
|
|
718
|
+
systemMessage: `omx question is blocked from Codex App/native outside-tmux Bash because no attached tmux pane is available. Use the native structured question tool when available, or ask exactly one concise plain-text question. Original command: ${command}`,
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
|
|
591
722
|
if (commandHasQuestionReturnPane(command)) return null;
|
|
592
723
|
|
|
593
724
|
return {
|
|
594
725
|
decision: "block",
|
|
595
726
|
reason: "omx question Bash invocations must preserve the leader pane return target.",
|
|
596
|
-
|
|
597
|
-
hookEventName: "PreToolUse",
|
|
598
|
-
additionalContext: [
|
|
599
|
-
"omx question leader-pane enforcement triggered.",
|
|
600
|
-
"Prefix the Bash command with `OMX_QUESTION_RETURN_PANE=$TMUX_PANE` (or a concrete `%pane` value) so `[omx question answered]` returns to the leader pane even when the tool path drops/stales TMUX_PANE.",
|
|
601
|
-
`Original command: ${command}`,
|
|
602
|
-
].join("\n"),
|
|
603
|
-
},
|
|
604
|
-
systemMessage: "omx question is blocked from Bash until the command preserves the leader pane with `OMX_QUESTION_RETURN_PANE=$TMUX_PANE` or an explicit `%pane` value.",
|
|
727
|
+
systemMessage: `omx question is blocked from Bash until the command preserves the leader pane with \`OMX_QUESTION_RETURN_PANE=$TMUX_PANE\` or an explicit \`%pane\` value. Original command: ${command}`,
|
|
605
728
|
};
|
|
606
729
|
}
|
|
607
730
|
|
|
@@ -612,8 +735,17 @@ export function buildNativePreToolUseOutput(
|
|
|
612
735
|
if (!normalized.isBash) return null;
|
|
613
736
|
const gitCommitEnforcement = buildGitCommitEnforcementOutput(normalized.normalizedCommand);
|
|
614
737
|
if (gitCommitEnforcement) return gitCommitEnforcement;
|
|
615
|
-
const
|
|
738
|
+
const hudEnforcement = buildNativeOmxHudPreToolUseEnforcementOutput(normalized.normalizedCommand, payload);
|
|
739
|
+
if (hudEnforcement) return hudEnforcement;
|
|
740
|
+
const teamEnforcement = buildNativeOmxTeamPreToolUseEnforcementOutput(normalized.normalizedCommand, payload);
|
|
741
|
+
if (teamEnforcement) return teamEnforcement;
|
|
742
|
+
const questionEnforcement = buildOmxQuestionPreToolUseEnforcementOutput(normalized.normalizedCommand, payload);
|
|
616
743
|
if (questionEnforcement) return questionEnforcement;
|
|
744
|
+
const documentRefreshWarning = buildDocumentRefreshPreToolUseOutput(
|
|
745
|
+
normalized.normalizedCommand,
|
|
746
|
+
safeString(payload.cwd).trim() || process.cwd(),
|
|
747
|
+
);
|
|
748
|
+
if (documentRefreshWarning) return documentRefreshWarning;
|
|
617
749
|
if (!matchesDestructiveFixture(normalized.normalizedCommand)) return null;
|
|
618
750
|
|
|
619
751
|
return {
|
|
@@ -629,10 +761,17 @@ function containsHardFailure(text: string): boolean {
|
|
|
629
761
|
return /command not found|permission denied|no such file or directory/i.test(text);
|
|
630
762
|
}
|
|
631
763
|
|
|
764
|
+
function hasActionableBashHardFailure(normalized: NormalizedPostToolUsePayload): boolean {
|
|
765
|
+
if (containsHardFailure(normalized.stderrText)) return true;
|
|
766
|
+
if (normalized.exitCode === null || normalized.exitCode === 0) return false;
|
|
767
|
+
return containsHardFailure(`${normalized.stderrText}\n${normalized.stdoutText}`);
|
|
768
|
+
}
|
|
769
|
+
|
|
632
770
|
export function buildNativePostToolUseOutput(
|
|
633
771
|
payload: CodexHookPayload,
|
|
634
772
|
): Record<string, unknown> | null {
|
|
635
|
-
const
|
|
773
|
+
const normalized = normalizePostToolUsePayload(payload);
|
|
774
|
+
const mcpTransportFailure = normalized.isBash ? null : detectMcpTransportFailure(payload);
|
|
636
775
|
if (mcpTransportFailure) {
|
|
637
776
|
const fallbackCommand = buildOmxParityFallbackCommand(payload, mcpTransportFailure.toolName);
|
|
638
777
|
const fallbackText = fallbackCommand
|
|
@@ -649,11 +788,10 @@ export function buildNativePostToolUseOutput(
|
|
|
649
788
|
};
|
|
650
789
|
}
|
|
651
790
|
|
|
652
|
-
const normalized = normalizePostToolUsePayload(payload);
|
|
653
791
|
if (!normalized.isBash) return null;
|
|
654
792
|
|
|
655
793
|
const combined = `${normalized.stderrText}\n${normalized.stdoutText}`.trim();
|
|
656
|
-
if (
|
|
794
|
+
if (hasActionableBashHardFailure(normalized)) {
|
|
657
795
|
return {
|
|
658
796
|
decision: "block",
|
|
659
797
|
reason: "The Bash output indicates a command/setup failure that should be fixed before retrying.",
|
|
@@ -75,6 +75,15 @@ export function resolveCurrentTag(cwd: string, explicit?: string): string {
|
|
|
75
75
|
throw new Error('unable to determine current release tag; pass --current-tag or set GITHUB_REF_NAME');
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
function isAncestorTag(cwd: string, possibleAncestor: string, currentTag: string): boolean {
|
|
79
|
+
const result = spawnSync('git', ['merge-base', '--is-ancestor', possibleAncestor, currentTag], {
|
|
80
|
+
cwd,
|
|
81
|
+
encoding: 'utf-8',
|
|
82
|
+
stdio: 'pipe',
|
|
83
|
+
});
|
|
84
|
+
return result.status === 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
78
87
|
export function resolvePreviousTag(cwd: string, currentTag: string, explicit?: string): string | undefined {
|
|
79
88
|
if (explicit) return explicit;
|
|
80
89
|
const tags = runGit(['tag', '--list', 'v*', '--sort=-v:refname'], cwd, true)
|
|
@@ -83,8 +92,30 @@ export function resolvePreviousTag(cwd: string, currentTag: string, explicit?: s
|
|
|
83
92
|
.filter(Boolean);
|
|
84
93
|
if (tags.length === 0) return undefined;
|
|
85
94
|
const currentIndex = tags.indexOf(currentTag);
|
|
86
|
-
|
|
87
|
-
|
|
95
|
+
const candidates = currentIndex >= 0
|
|
96
|
+
? tags.slice(currentIndex + 1)
|
|
97
|
+
: tags.filter((tag) => tag !== currentTag);
|
|
98
|
+
return candidates.find((tag) => isAncestorTag(cwd, tag, currentTag));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function verifyGitCommitRef(cwd: string, ref: string, label: string): void {
|
|
102
|
+
if (!runGit(['rev-parse', '--verify', '--quiet', `${ref}^{commit}`], cwd, true)) {
|
|
103
|
+
throw new Error(`unable to verify ${label} ref for release compare: ${ref}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function verifyCompareRange(cwd: string, currentTag: string, previousTag?: string): void {
|
|
108
|
+
if (!previousTag) return;
|
|
109
|
+
verifyGitCommitRef(cwd, previousTag, 'previous tag');
|
|
110
|
+
verifyGitCommitRef(cwd, currentTag, 'current tag');
|
|
111
|
+
const mergeBase = spawnSync('git', ['merge-base', '--is-ancestor', previousTag, currentTag], {
|
|
112
|
+
cwd,
|
|
113
|
+
encoding: 'utf-8',
|
|
114
|
+
stdio: 'pipe',
|
|
115
|
+
});
|
|
116
|
+
if (mergeBase.status !== 0) {
|
|
117
|
+
throw new Error(`invalid release compare range: ${previousTag} is not an ancestor of ${currentTag}`);
|
|
118
|
+
}
|
|
88
119
|
}
|
|
89
120
|
|
|
90
121
|
function normalizeContributors(contributors: Contributor[]): Contributor[] {
|
|
@@ -256,6 +287,7 @@ export async function generateReleaseBody(options: GenerateReleaseBodyOptions):
|
|
|
256
287
|
const outPath = resolve(cwd, options.outPath);
|
|
257
288
|
const currentTag = resolveCurrentTag(cwd, options.currentTag);
|
|
258
289
|
const previousTag = resolvePreviousTag(cwd, currentTag, options.previousTag);
|
|
290
|
+
verifyCompareRange(cwd, currentTag, previousTag);
|
|
259
291
|
const repo = options.repo || process.env.GITHUB_REPOSITORY || resolveRepositoryFromRemote(cwd);
|
|
260
292
|
const contributors = await resolveContributors({
|
|
261
293
|
cwd,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { existsSync } from 'fs';
|
|
4
|
-
import { appendFile, mkdir, readFile, readdir, stat, writeFile } from 'fs/promises';
|
|
4
|
+
import { appendFile, mkdir, open, readFile, readdir, stat, writeFile } from 'fs/promises';
|
|
5
5
|
import { dirname, join, resolve } from 'path';
|
|
6
6
|
import { homedir } from 'os';
|
|
7
|
+
import { StringDecoder } from 'string_decoder';
|
|
7
8
|
import {
|
|
8
9
|
buildOperationalContext,
|
|
9
10
|
classifyExecCommand,
|
|
@@ -40,6 +41,7 @@ interface FileMeta {
|
|
|
40
41
|
partial: string;
|
|
41
42
|
dispatched: number;
|
|
42
43
|
currentTurnId: string;
|
|
44
|
+
decoder: StringDecoder;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
interface PendingCall {
|
|
@@ -415,7 +417,9 @@ async function ensureTrackedFiles(): Promise<void> {
|
|
|
415
417
|
const firstLine = await readFirstLine(path).catch(() => '');
|
|
416
418
|
const meta = shouldTrackSessionMeta(firstLine);
|
|
417
419
|
if (!meta) continue;
|
|
418
|
-
const
|
|
420
|
+
const fileStat = await stat(path).catch(() => null);
|
|
421
|
+
if (!fileStat) continue;
|
|
422
|
+
const size = fileStat.size || 0;
|
|
419
423
|
const offset = runOnce ? 0 : size;
|
|
420
424
|
fileState.set(path, {
|
|
421
425
|
...meta,
|
|
@@ -423,6 +427,7 @@ async function ensureTrackedFiles(): Promise<void> {
|
|
|
423
427
|
partial: '',
|
|
424
428
|
dispatched: 0,
|
|
425
429
|
currentTurnId: '',
|
|
430
|
+
decoder: new StringDecoder('utf8'),
|
|
426
431
|
});
|
|
427
432
|
}
|
|
428
433
|
}
|
|
@@ -504,16 +509,54 @@ async function processLine(meta: FileMeta, line: string): Promise<void> {
|
|
|
504
509
|
meta.dispatched += 1;
|
|
505
510
|
}
|
|
506
511
|
|
|
512
|
+
async function readFileDelta(
|
|
513
|
+
path: string,
|
|
514
|
+
offset: number,
|
|
515
|
+
currentSize: number,
|
|
516
|
+
): Promise<{ bytes: Buffer; nextOffset: number }> {
|
|
517
|
+
const length = currentSize - offset;
|
|
518
|
+
if (length <= 0) return { bytes: Buffer.alloc(0), nextOffset: offset };
|
|
519
|
+
const handle = await open(path, 'r');
|
|
520
|
+
try {
|
|
521
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
522
|
+
let totalBytesRead = 0;
|
|
523
|
+
while (totalBytesRead < length) {
|
|
524
|
+
const { bytesRead } = await handle.read(
|
|
525
|
+
buffer,
|
|
526
|
+
totalBytesRead,
|
|
527
|
+
length - totalBytesRead,
|
|
528
|
+
offset + totalBytesRead,
|
|
529
|
+
);
|
|
530
|
+
if (bytesRead === 0) break;
|
|
531
|
+
totalBytesRead += bytesRead;
|
|
532
|
+
}
|
|
533
|
+
return {
|
|
534
|
+
bytes: buffer.subarray(0, totalBytesRead),
|
|
535
|
+
nextOffset: offset + totalBytesRead,
|
|
536
|
+
};
|
|
537
|
+
} finally {
|
|
538
|
+
await handle.close().catch(() => {});
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
507
542
|
async function pollFiles(): Promise<void> {
|
|
508
543
|
for (const [path, meta] of fileState.entries()) {
|
|
509
|
-
const
|
|
544
|
+
const fileStat = await stat(path).catch(() => null);
|
|
545
|
+
if (!fileStat) continue;
|
|
546
|
+
const currentSize = fileStat.size || 0;
|
|
547
|
+
if (currentSize < meta.offset) {
|
|
548
|
+
meta.offset = 0;
|
|
549
|
+
meta.partial = '';
|
|
550
|
+
meta.decoder = new StringDecoder('utf8');
|
|
551
|
+
}
|
|
510
552
|
if (currentSize <= meta.offset) continue;
|
|
511
553
|
|
|
512
|
-
const
|
|
513
|
-
if (!
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
554
|
+
const read = await readFileDelta(path, meta.offset, currentSize).catch(() => null);
|
|
555
|
+
if (!read || read.bytes.length === 0) continue;
|
|
556
|
+
const { bytes, nextOffset } = read;
|
|
557
|
+
meta.offset = nextOffset;
|
|
558
|
+
const delta = meta.decoder.write(bytes);
|
|
559
|
+
if (!delta) continue;
|
|
517
560
|
const merged = meta.partial + delta;
|
|
518
561
|
const lines = merged.split('\n');
|
|
519
562
|
meta.partial = lines.pop() || '';
|
|
@@ -5,6 +5,7 @@ import { appendFile, mkdir, open, readFile, readdir, rename, rm, stat, unlink, w
|
|
|
5
5
|
import { spawnSync } from 'child_process';
|
|
6
6
|
import { dirname, join, resolve } from 'path';
|
|
7
7
|
import { homedir } from 'os';
|
|
8
|
+
import { StringDecoder } from 'string_decoder';
|
|
8
9
|
import { spawnPlatformCommandSync } from '../utils/platform-command.js';
|
|
9
10
|
import { drainPendingTeamDispatch } from './notify-hook/team-dispatch.js';
|
|
10
11
|
import {
|
|
@@ -93,6 +94,19 @@ function sleep(ms: number): Promise<void> {
|
|
|
93
94
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
94
95
|
}
|
|
95
96
|
|
|
97
|
+
let atomicJsonWriteCounter = 0;
|
|
98
|
+
|
|
99
|
+
async function writeJsonObjectAtomically(path: string, value: unknown): Promise<void> {
|
|
100
|
+
const tempPath = `${path}.${process.pid}.${Date.now()}.${++atomicJsonWriteCounter}.tmp`;
|
|
101
|
+
try {
|
|
102
|
+
await writeFile(tempPath, JSON.stringify(value, null, 2));
|
|
103
|
+
await rename(tempPath, path);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
await rm(tempPath, { force: true }).catch(() => {});
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
96
110
|
async function waitForPidExit(pid: number, timeoutMs = 3000, stepMs = 50): Promise<boolean> {
|
|
97
111
|
const deadline = Date.now() + timeoutMs;
|
|
98
112
|
while (Date.now() < deadline) {
|
|
@@ -156,6 +170,7 @@ interface WatcherFileMeta {
|
|
|
156
170
|
offset: number;
|
|
157
171
|
size: number;
|
|
158
172
|
partial: string;
|
|
173
|
+
decoder: StringDecoder;
|
|
159
174
|
}
|
|
160
175
|
|
|
161
176
|
interface RalphContinueSteerState {
|
|
@@ -1334,7 +1349,7 @@ async function writeState(extra: Record<string, unknown> = {}): Promise<void> {
|
|
|
1334
1349
|
},
|
|
1335
1350
|
...extra,
|
|
1336
1351
|
};
|
|
1337
|
-
await
|
|
1352
|
+
await writeJsonObjectAtomically(statePath, state).catch(() => {});
|
|
1338
1353
|
}
|
|
1339
1354
|
|
|
1340
1355
|
async function writeAuthorityBackoffState(): Promise<void> {
|
|
@@ -1343,7 +1358,7 @@ async function writeAuthorityBackoffState(): Promise<void> {
|
|
|
1343
1358
|
const state = existing && typeof existing === 'object'
|
|
1344
1359
|
? { ...existing, authority_backoff: lastAuthorityBackoff }
|
|
1345
1360
|
: { authority_backoff: lastAuthorityBackoff };
|
|
1346
|
-
await
|
|
1361
|
+
await writeJsonObjectAtomically(statePath, state).catch(() => {});
|
|
1347
1362
|
}
|
|
1348
1363
|
|
|
1349
1364
|
async function readJsonObject(path: string): Promise<Record<string, unknown> | null> {
|
|
@@ -1683,9 +1698,11 @@ async function ensureTrackedFiles(): Promise<void> {
|
|
|
1683
1698
|
const line = await readFirstLine(path).catch(() => '');
|
|
1684
1699
|
const threadId = shouldTrackSessionMeta(line);
|
|
1685
1700
|
if (!threadId) continue;
|
|
1686
|
-
const
|
|
1701
|
+
const fileStat = await stat(path).catch(() => null);
|
|
1702
|
+
if (!fileStat) continue;
|
|
1703
|
+
const size = fileStat.size || 0;
|
|
1687
1704
|
const offset = runOnce ? 0 : size;
|
|
1688
|
-
fileState.set(path, { threadId, offset, size, partial: '' });
|
|
1705
|
+
fileState.set(path, { threadId, offset, size, partial: '', decoder: new StringDecoder('utf8') });
|
|
1689
1706
|
}
|
|
1690
1707
|
}
|
|
1691
1708
|
|
|
@@ -1698,15 +1715,54 @@ function splitBufferedLines(partial: string, delta: string): { lines: string[];
|
|
|
1698
1715
|
};
|
|
1699
1716
|
}
|
|
1700
1717
|
|
|
1718
|
+
async function readFileDelta(
|
|
1719
|
+
path: string,
|
|
1720
|
+
offset: number,
|
|
1721
|
+
currentSize: number,
|
|
1722
|
+
): Promise<{ bytes: Buffer; nextOffset: number }> {
|
|
1723
|
+
const length = currentSize - offset;
|
|
1724
|
+
if (length <= 0) return { bytes: Buffer.alloc(0), nextOffset: offset };
|
|
1725
|
+
const handle = await open(path, 'r');
|
|
1726
|
+
try {
|
|
1727
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
1728
|
+
let totalBytesRead = 0;
|
|
1729
|
+
while (totalBytesRead < length) {
|
|
1730
|
+
const { bytesRead } = await handle.read(
|
|
1731
|
+
buffer,
|
|
1732
|
+
totalBytesRead,
|
|
1733
|
+
length - totalBytesRead,
|
|
1734
|
+
offset + totalBytesRead,
|
|
1735
|
+
);
|
|
1736
|
+
if (bytesRead === 0) break;
|
|
1737
|
+
totalBytesRead += bytesRead;
|
|
1738
|
+
}
|
|
1739
|
+
return {
|
|
1740
|
+
bytes: buffer.subarray(0, totalBytesRead),
|
|
1741
|
+
nextOffset: offset + totalBytesRead,
|
|
1742
|
+
};
|
|
1743
|
+
} finally {
|
|
1744
|
+
await handle.close().catch(() => {});
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1701
1748
|
async function pollFiles(): Promise<number> {
|
|
1702
1749
|
let processedCount = 0;
|
|
1703
1750
|
for (const [path, meta] of fileState.entries()) {
|
|
1704
|
-
const
|
|
1751
|
+
const fileStat = await stat(path).catch(() => null);
|
|
1752
|
+
if (!fileStat) continue;
|
|
1753
|
+
const currentSize = fileStat.size || 0;
|
|
1754
|
+
if (currentSize < meta.offset) {
|
|
1755
|
+
meta.offset = 0;
|
|
1756
|
+
meta.partial = '';
|
|
1757
|
+
meta.decoder = new StringDecoder('utf8');
|
|
1758
|
+
}
|
|
1705
1759
|
if (currentSize <= meta.offset) continue;
|
|
1706
|
-
const
|
|
1707
|
-
if (!
|
|
1708
|
-
const
|
|
1709
|
-
meta.offset =
|
|
1760
|
+
const read = await readFileDelta(path, meta.offset, currentSize).catch(() => null);
|
|
1761
|
+
if (!read || read.bytes.length === 0) continue;
|
|
1762
|
+
const { bytes, nextOffset } = read;
|
|
1763
|
+
meta.offset = nextOffset;
|
|
1764
|
+
const delta = meta.decoder.write(bytes);
|
|
1765
|
+
if (!delta) continue;
|
|
1710
1766
|
const buffered = splitBufferedLines(meta.partial, delta);
|
|
1711
1767
|
const lines = buffered.lines;
|
|
1712
1768
|
meta.partial = buffered.partial;
|