oh-my-codex 0.20.1 → 0.20.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +7 -6
- package/Cargo.toml +1 -1
- package/README.md +36 -1
- package/crates/omx-runtime/Cargo.toml +1 -0
- package/crates/omx-runtime/src/main.rs +25 -2
- package/crates/omx-runtime/tests/execution.rs +219 -0
- package/crates/omx-runtime-core/src/dispatch.rs +96 -10
- package/crates/omx-runtime-core/src/engine.rs +839 -29
- package/crates/omx-runtime-core/src/lib.rs +8 -0
- package/dist/adapt/__tests__/hermes.test.js.map +1 -1
- package/dist/adapt/contracts.d.ts.map +1 -1
- package/dist/agents/__tests__/definitions.test.js +81 -0
- package/dist/agents/__tests__/definitions.test.js.map +1 -1
- package/dist/agents/__tests__/native-config.test.js +25 -0
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/native-config.d.ts +2 -1
- package/dist/agents/native-config.d.ts.map +1 -1
- package/dist/agents/native-config.js.map +1 -1
- package/dist/auth/__tests__/hotswap.test.d.ts +2 -0
- package/dist/auth/__tests__/hotswap.test.d.ts.map +1 -0
- package/dist/auth/__tests__/hotswap.test.js +183 -0
- package/dist/auth/__tests__/hotswap.test.js.map +1 -0
- package/dist/auth/hotswap.d.ts +6 -0
- package/dist/auth/hotswap.d.ts.map +1 -1
- package/dist/auth/hotswap.js +102 -19
- package/dist/auth/hotswap.js.map +1 -1
- package/dist/auth/paths.js.map +1 -1
- package/dist/auth/storage.js.map +1 -1
- package/dist/autopilot/__tests__/ralplan-gate.test.js +5 -5
- package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
- package/dist/autopilot/completion-gate.js.map +1 -1
- package/dist/autopilot/fsm.d.ts +1 -1
- package/dist/autopilot/fsm.d.ts.map +1 -1
- package/dist/autoresearch/goal.js.map +1 -1
- package/dist/autoresearch/runtime.js.map +1 -1
- package/dist/capabilities/lockfile.js.map +1 -1
- package/dist/catalog/reader.js.map +1 -1
- package/dist/catalog/skill-mirror.js.map +1 -1
- package/dist/cli/__tests__/adapt-help.test.js.map +1 -1
- package/dist/cli/__tests__/agents-init.test.js.map +1 -1
- package/dist/cli/__tests__/agents.test.js.map +1 -1
- package/dist/cli/__tests__/api.test.js.map +1 -1
- package/dist/cli/__tests__/ask.test.js.map +1 -1
- package/dist/cli/__tests__/auth.test.js +60 -6
- package/dist/cli/__tests__/auth.test.js.map +1 -1
- package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -1
- package/dist/cli/__tests__/autoresearch.test.js.map +1 -1
- package/dist/cli/__tests__/capabilities.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +80 -0
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-context-window-warning.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-invalid-config.test.js +47 -4
- package/dist/cli/__tests__/doctor-invalid-config.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +752 -15
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +136 -0
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/imagegen-continuation.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +473 -14
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +336 -4
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-parity.test.js +87 -12
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/native-hook-claim-journal.test.d.ts +2 -0
- package/dist/cli/__tests__/native-hook-claim-journal.test.d.ts.map +1 -0
- package/dist/cli/__tests__/native-hook-claim-journal.test.js +206 -0
- package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -0
- package/dist/cli/__tests__/nested-help-routing.test.js.map +1 -1
- package/dist/cli/__tests__/question.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-deslop-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +6 -0
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-smoke.test.js.map +1 -1
- package/dist/cli/__tests__/ralph.test.js +8 -3
- package/dist/cli/__tests__/ralph.test.js.map +1 -1
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.d.ts +2 -0
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +72 -0
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -0
- package/dist/cli/__tests__/ralplan.test.d.ts +2 -0
- package/dist/cli/__tests__/ralplan.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralplan.test.js +55 -0
- package/dist/cli/__tests__/ralplan.test.js.map +1 -0
- package/dist/cli/__tests__/resume.test.js +17 -11
- package/dist/cli/__tests__/resume.test.js.map +1 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.js +25 -0
- package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
- package/dist/cli/__tests__/session-search-help.test.js +25 -1
- package/dist/cli/__tests__/session-search-help.test.js.map +1 -1
- package/dist/cli/__tests__/session-search.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +79 -0
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-gh-star.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +77 -3
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.d.ts +2 -0
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.d.ts.map +1 -0
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js +285 -0
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js.map +1 -0
- package/dist/cli/__tests__/setup-install-mode.test.js +2579 -294
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/setup-preferences.test.d.ts +2 -0
- package/dist/cli/__tests__/setup-preferences.test.d.ts.map +1 -0
- package/dist/cli/__tests__/setup-preferences.test.js +79 -0
- package/dist/cli/__tests__/setup-preferences.test.js.map +1 -0
- package/dist/cli/__tests__/setup-refresh.test.js +33 -2
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-scope.test.js +46 -3
- package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
- package/dist/cli/__tests__/state.test.js +37 -0
- package/dist/cli/__tests__/state.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +105 -7
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +61 -1
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +1817 -24
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/update.test.js +58 -0
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/__tests__/url.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +2 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
- package/dist/cli/adapt.js.map +1 -1
- package/dist/cli/agents-init.js.map +1 -1
- package/dist/cli/agents.js.map +1 -1
- package/dist/cli/api.js.map +1 -1
- package/dist/cli/ask.d.ts +1 -1
- package/dist/cli/ask.d.ts.map +1 -1
- package/dist/cli/ask.js.map +1 -1
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/autoresearch-guided.js.map +1 -1
- package/dist/cli/autoresearch-intake.js.map +1 -1
- package/dist/cli/capabilities.js.map +1 -1
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/codex-feature-probe.js.map +1 -1
- package/dist/cli/codex-home.js.map +1 -1
- package/dist/cli/doctor.d.ts +21 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +607 -130
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/explore.js.map +1 -1
- package/dist/cli/index.d.ts +14 -3
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +245 -57
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-parity.js +2 -2
- package/dist/cli/mcp-parity.js.map +1 -1
- package/dist/cli/mcp-serve.js.map +1 -1
- package/dist/cli/mission.js.map +1 -1
- package/dist/cli/native-assets.js.map +1 -1
- package/dist/cli/native-hook-claim-journal.d.ts +29 -0
- package/dist/cli/native-hook-claim-journal.d.ts.map +1 -0
- package/dist/cli/native-hook-claim-journal.js +252 -0
- package/dist/cli/native-hook-claim-journal.js.map +1 -0
- package/dist/cli/omx.js.map +1 -1
- package/dist/cli/plugin-marketplace.js.map +1 -1
- package/dist/cli/project-runtime-codex-homes.js.map +1 -1
- package/dist/cli/question.js.map +1 -1
- package/dist/cli/ralph.d.ts.map +1 -1
- package/dist/cli/ralph.js +3 -2
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/ralplan.d.ts +10 -0
- package/dist/cli/ralplan.d.ts.map +1 -0
- package/dist/cli/ralplan.js +110 -0
- package/dist/cli/ralplan.js.map +1 -0
- package/dist/cli/session-search.d.ts +5 -0
- package/dist/cli/session-search.d.ts.map +1 -1
- package/dist/cli/session-search.js +87 -0
- package/dist/cli/session-search.js.map +1 -1
- package/dist/cli/setup-preferences.d.ts +11 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -1
- package/dist/cli/setup-preferences.js +32 -0
- package/dist/cli/setup-preferences.js.map +1 -1
- package/dist/cli/setup.d.ts +58 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +1450 -398
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/sparkshell.js.map +1 -1
- package/dist/cli/star-prompt.js.map +1 -1
- package/dist/cli/state.d.ts.map +1 -1
- package/dist/cli/state.js +2 -1
- package/dist/cli/state.js.map +1 -1
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/ultragoal.d.ts +5 -1
- package/dist/cli/ultragoal.d.ts.map +1 -1
- package/dist/cli/ultragoal.js +34 -2
- package/dist/cli/ultragoal.js.map +1 -1
- package/dist/cli/uninstall.d.ts +17 -0
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +986 -95
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +8 -1
- package/dist/cli/update.js.map +1 -1
- package/dist/cli/url.js.map +1 -1
- package/dist/compat/__tests__/doctor-contract.test.js +5 -1
- package/dist/compat/__tests__/doctor-contract.test.js.map +1 -1
- package/dist/compat/__tests__/rust-runtime-compat.test.js +1 -1
- package/dist/compat/__tests__/rust-runtime-compat.test.js.map +1 -1
- package/dist/config/__tests__/codex-hooks.test.js +1287 -11
- package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +1179 -32
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +6 -1
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/__tests__/models.test.js +67 -3
- package/dist/config/__tests__/models.test.js.map +1 -1
- package/dist/config/codex-feature-flags.d.ts.map +1 -1
- package/dist/config/codex-feature-flags.js.map +1 -1
- package/dist/config/codex-hooks.d.ts +124 -1
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +2142 -265
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/config/commit-lore-guard.js.map +1 -1
- package/dist/config/generator.d.ts +23 -34
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +1480 -246
- package/dist/config/generator.js.map +1 -1
- package/dist/config/mcp-registry.js.map +1 -1
- package/dist/config/models.d.ts +14 -4
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +15 -1
- package/dist/config/models.js.map +1 -1
- package/dist/config/omx-first-party-mcp.js.map +1 -1
- package/dist/config/team-mode.d.ts.map +1 -1
- package/dist/document-refresh/__tests__/enforcer.test.js.map +1 -1
- package/dist/document-refresh/enforcer.js.map +1 -1
- package/dist/exec/followup.js.map +1 -1
- package/dist/goal-workflows/artifacts.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +7 -4
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/analyze-routing-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/analyze-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +9 -3
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/design-skill.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +1376 -6
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +252 -543
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +38 -4
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +765 -10
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +2 -0
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +142 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js +48 -2
- package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +61 -44
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js +3 -2
- package/dist/hooks/__tests__/notify-hook-session-idle-dedupe.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +243 -4
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +531 -12
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +163 -24
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +482 -32
- package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +68 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +7 -1
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +43 -4
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-fragments.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-test-helpers.js.map +1 -1
- package/dist/hooks/__tests__/prompt-session-provenance.test.d.ts +2 -0
- package/dist/hooks/__tests__/prompt-session-provenance.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/prompt-session-provenance.test.js +82 -0
- package/dist/hooks/__tests__/prompt-session-provenance.test.js.map +1 -0
- package/dist/hooks/__tests__/session.test.js +878 -11
- package/dist/hooks/__tests__/session.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.js.map +1 -1
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +1 -1
- package/dist/hooks/agents-overlay.js +5 -5
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/code-simplifier/index.js.map +1 -1
- package/dist/hooks/explore-routing.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/extensibility/events.js.map +1 -1
- package/dist/hooks/extensibility/loader.js.map +1 -1
- package/dist/hooks/extensibility/plugin-runner-stdin.js.map +1 -1
- package/dist/hooks/extensibility/sdk/logging.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +33 -7
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +2228 -119
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts +12 -0
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +41 -0
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hooks/prompt-session-provenance.d.ts +87 -0
- package/dist/hooks/prompt-session-provenance.d.ts.map +1 -0
- package/dist/hooks/prompt-session-provenance.js +180 -0
- package/dist/hooks/prompt-session-provenance.js.map +1 -0
- package/dist/hooks/session.d.ts +163 -34
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +1395 -317
- package/dist/hooks/session.js.map +1 -1
- package/dist/hooks/task-size-detector.js.map +1 -1
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/authority.js.map +1 -1
- package/dist/hud/constants.js.map +1 -1
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/tmux.js.map +1 -1
- package/dist/leader/__tests__/contract.test.js +153 -1
- package/dist/leader/__tests__/contract.test.js.map +1 -1
- package/dist/leader/contract.d.ts +42 -5
- package/dist/leader/contract.d.ts.map +1 -1
- package/dist/leader/contract.js +184 -3
- package/dist/leader/contract.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/__tests__/code-intel-server.test.js +31 -3
- package/dist/mcp/__tests__/code-intel-server.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +15 -2
- package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
- package/dist/mcp/__tests__/state-paths.test.js +98 -1
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/__tests__/wiki-server.test.js +18 -0
- package/dist/mcp/__tests__/wiki-server.test.js.map +1 -1
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/code-intel-server.d.ts +58 -58
- package/dist/mcp/code-intel-server.d.ts.map +1 -1
- package/dist/mcp/code-intel-server.js +13 -3
- package/dist/mcp/code-intel-server.js.map +1 -1
- package/dist/mcp/hermes-bridge.js.map +1 -1
- package/dist/mcp/hermes-server.d.ts +70 -70
- package/dist/mcp/hermes-server.d.ts.map +1 -1
- package/dist/mcp/lifecycle-telemetry.js.map +1 -1
- package/dist/mcp/memory-server.d.ts +34 -34
- package/dist/mcp/memory-server.d.ts.map +1 -1
- package/dist/mcp/memory-server.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +14 -0
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +96 -20
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts +47 -47
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/trace-server.d.ts +4 -4
- package/dist/mcp/trace-server.d.ts.map +1 -1
- package/dist/mcp/trace-server.js.map +1 -1
- package/dist/mcp/wiki-server.d.ts +34 -23
- package/dist/mcp/wiki-server.d.ts.map +1 -1
- package/dist/mcp/wiki-server.js +9 -2
- package/dist/mcp/wiki-server.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +53 -1
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/__tests__/base-tmux-pane.test.js +4 -4
- package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +5 -5
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/__tests__/lifecycle-dedupe.test.js.map +1 -1
- package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js +177 -85
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js.map +1 -1
- package/dist/notifications/__tests__/session-registry.test.js.map +1 -1
- package/dist/notifications/__tests__/template-engine.test.js.map +1 -1
- package/dist/notifications/__tests__/verbosity.test.js.map +1 -1
- package/dist/notifications/http-client.js.map +1 -1
- package/dist/notifications/index.d.ts +4 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +3 -9
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/lifecycle-dedupe.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/session-registry.js.map +1 -1
- package/dist/notifications/session-status.js.map +1 -1
- package/dist/notifications/temp-contract.d.ts.map +1 -1
- package/dist/notifications/temp-contract.js +4 -0
- package/dist/notifications/temp-contract.js.map +1 -1
- package/dist/notifications/tmux-detector.js.map +1 -1
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/openclaw/config.js.map +1 -1
- package/dist/openclaw/dispatcher.js.map +1 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +4 -4
- package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
- package/dist/pipeline/__tests__/stages.test.js +16 -13
- package/dist/pipeline/__tests__/stages.test.js.map +1 -1
- package/dist/pipeline/stages/code-review.js.map +1 -1
- package/dist/pipeline/stages/ralph-verify.js.map +1 -1
- package/dist/pipeline/stages/ralplan.js.map +1 -1
- package/dist/pipeline/stages/team-exec.js.map +1 -1
- package/dist/pipeline/stages/ultragoal.js.map +1 -1
- package/dist/pipeline/stages/ultraqa.js.map +1 -1
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js.map +1 -1
- package/dist/planning/artifact-names.js.map +1 -1
- package/dist/planning/artifacts.js.map +1 -1
- package/dist/question/__tests__/state.test.js.map +1 -1
- package/dist/question/__tests__/ui.test.js.map +1 -1
- package/dist/question/autopilot-wait.js.map +1 -1
- package/dist/question/client.d.ts.map +1 -1
- package/dist/question/client.js.map +1 -1
- package/dist/question/deep-interview.js.map +1 -1
- package/dist/question/events.js.map +1 -1
- package/dist/question/renderer.js.map +1 -1
- package/dist/question/state.d.ts.map +1 -1
- package/dist/question/state.js.map +1 -1
- package/dist/question/ui.js.map +1 -1
- package/dist/ralph/contract.d.ts +1 -1
- package/dist/ralph/contract.d.ts.map +1 -1
- package/dist/ralplan/__tests__/consensus-gate.test.js +527 -8
- package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
- package/dist/ralplan/__tests__/documented-leader-preflight.test.d.ts +2 -0
- package/dist/ralplan/__tests__/documented-leader-preflight.test.d.ts.map +1 -0
- package/dist/ralplan/__tests__/documented-leader-preflight.test.js +46 -0
- package/dist/ralplan/__tests__/documented-leader-preflight.test.js.map +1 -0
- package/dist/ralplan/__tests__/runtime.test.js +116 -14
- package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
- package/dist/ralplan/consensus-gate.d.ts +3 -3
- package/dist/ralplan/consensus-gate.d.ts.map +1 -1
- package/dist/ralplan/consensus-gate.js +173 -70
- package/dist/ralplan/consensus-gate.js.map +1 -1
- package/dist/ralplan/documented-leader-preflight.d.ts +34 -0
- package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -0
- package/dist/ralplan/documented-leader-preflight.js +58 -0
- package/dist/ralplan/documented-leader-preflight.js.map +1 -0
- package/dist/ralplan/runtime.d.ts +3 -2
- package/dist/ralplan/runtime.d.ts.map +1 -1
- package/dist/ralplan/runtime.js +12 -9
- package/dist/ralplan/runtime.js.map +1 -1
- package/dist/runtime/__tests__/bridge.test.js +42 -1
- package/dist/runtime/__tests__/bridge.test.js.map +1 -1
- package/dist/runtime/bridge.d.ts +12 -0
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +52 -1
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/runtime/process-tree.js.map +1 -1
- package/dist/runtime/run-loop.js.map +1 -1
- package/dist/runtime/run-outcome.d.ts +3 -3
- package/dist/runtime/run-outcome.d.ts.map +1 -1
- package/dist/runtime/run-outcome.js.map +1 -1
- package/dist/runtime/run-state.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +6657 -995
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/fixtures/issue-3138-installed-smoke.d.ts +2 -0
- package/dist/scripts/__tests__/fixtures/issue-3138-installed-smoke.d.ts.map +1 -0
- package/dist/scripts/__tests__/fixtures/issue-3138-installed-smoke.js +634 -0
- package/dist/scripts/__tests__/fixtures/issue-3138-installed-smoke.js.map +1 -0
- package/dist/scripts/__tests__/generate-release-body.test.js.map +1 -1
- package/dist/scripts/__tests__/hook-derived-watcher.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-fallback-delivery.test.d.ts +2 -0
- package/dist/scripts/__tests__/notify-fallback-delivery.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/notify-fallback-delivery.test.js +174 -0
- package/dist/scripts/__tests__/notify-fallback-delivery.test.js.map +1 -0
- package/dist/scripts/__tests__/notify-state-io.test.js +57 -1
- package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
- package/dist/scripts/__tests__/reasoning-artifact-contract.test.d.ts +2 -0
- package/dist/scripts/__tests__/reasoning-artifact-contract.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/reasoning-artifact-contract.test.js +108 -0
- package/dist/scripts/__tests__/reasoning-artifact-contract.test.js.map +1 -0
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.d.ts +2 -0
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +78 -0
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -0
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.d.ts +2 -0
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +55 -0
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -0
- package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js +1100 -4
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/__tests__/test-reply-listener-live.test.js.map +1 -1
- package/dist/scripts/build-api.js.map +1 -1
- package/dist/scripts/build-explore-harness.js.map +1 -1
- package/dist/scripts/build-sparkshell.js.map +1 -1
- package/dist/scripts/cleanup-explore-harness.js.map +1 -1
- package/dist/scripts/codex-execution-surface.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts +4 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +11577 -1184
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/generate-native-release-manifest.js.map +1 -1
- package/dist/scripts/generate-release-body.js.map +1 -1
- package/dist/scripts/hook-payload-guard.d.ts.map +1 -1
- package/dist/scripts/hook-payload-guard.js.map +1 -1
- package/dist/scripts/notify-fallback-delivery.d.ts +48 -0
- package/dist/scripts/notify-fallback-delivery.d.ts.map +1 -0
- package/dist/scripts/notify-fallback-delivery.js +419 -0
- package/dist/scripts/notify-fallback-delivery.js.map +1 -0
- package/dist/scripts/notify-fallback-watcher.js +218 -138
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts +18 -9
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +112 -15
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.d.ts +23 -0
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.js +122 -12
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
- package/dist/scripts/notify-hook/orchestration-intent.d.ts +7 -7
- package/dist/scripts/notify-hook/orchestration-intent.d.ts.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts +5 -2
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.js +33 -37
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts +17 -0
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +73 -11
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts +10 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +234 -79
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts +2 -2
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +39 -13
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts +16 -8
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +365 -44
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker-posttooluse.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.d.ts +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.js +19 -18
- package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.d.ts +5 -2
- package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +37 -28
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts +8 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +53 -18
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook/visual-verdict.d.ts +1 -1
- package/dist/scripts/notify-hook/visual-verdict.d.ts.map +1 -1
- package/dist/scripts/notify-hook/visual-verdict.js +15 -13
- package/dist/scripts/notify-hook/visual-verdict.js.map +1 -1
- package/dist/scripts/notify-hook.d.ts +24 -1
- package/dist/scripts/notify-hook.d.ts.map +1 -1
- package/dist/scripts/notify-hook.js +267 -90
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/scripts/prompt-inventory.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +927 -5
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +4317 -13
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.js.map +1 -1
- package/dist/scripts/test-reply-listener-live.js.map +1 -1
- package/dist/scripts/test-sparkshell.js.map +1 -1
- package/dist/scripts/verify-native-agents.js.map +1 -1
- package/dist/session-history/friction.js.map +1 -1
- package/dist/session-history/search.js.map +1 -1
- package/dist/sidecar/__tests__/boundary.test.js.map +1 -1
- package/dist/sidecar/collector.js.map +1 -1
- package/dist/sidecar/index.js.map +1 -1
- package/dist/sidecar/render.js.map +1 -1
- package/dist/sidecar/tmux.js.map +1 -1
- package/dist/state/__tests__/mode-state-context.test.js +54 -0
- package/dist/state/__tests__/mode-state-context.test.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +66 -15
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/skill-active.test.js +19 -1
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.js +61 -0
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/mode-state-context.d.ts +5 -0
- package/dist/state/mode-state-context.d.ts.map +1 -1
- package/dist/state/mode-state-context.js +59 -0
- package/dist/state/mode-state-context.js.map +1 -1
- package/dist/state/operations.d.ts +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +49 -55
- package/dist/state/operations.js.map +1 -1
- package/dist/state/paths.d.ts +1 -1
- package/dist/state/paths.d.ts.map +1 -1
- package/dist/state/paths.js +1 -1
- package/dist/state/paths.js.map +1 -1
- package/dist/state/skill-active.d.ts +13 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +43 -4
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/terminal-normalization.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
- package/dist/state/workflow-transition-reconcile.js +20 -4
- package/dist/state/workflow-transition-reconcile.js.map +1 -1
- package/dist/state/workflow-transition.d.ts +1 -1
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.d.ts +2 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.d.ts.map +1 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +52 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -0
- package/dist/subagents/__tests__/tracker.test.js +1550 -10
- package/dist/subagents/__tests__/tracker.test.js.map +1 -1
- package/dist/subagents/role-routing-marker.d.ts +10 -0
- package/dist/subagents/role-routing-marker.d.ts.map +1 -0
- package/dist/subagents/role-routing-marker.js +136 -0
- package/dist/subagents/role-routing-marker.js.map +1 -0
- package/dist/subagents/tracker.d.ts +91 -0
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +806 -62
- package/dist/subagents/tracker.js.map +1 -1
- package/dist/team/__tests__/api-interop.test.js +91 -1
- package/dist/team/__tests__/api-interop.test.js.map +1 -1
- package/dist/team/__tests__/approved-execution.test.js.map +1 -1
- package/dist/team/__tests__/delivery-e2e-smoke.test.js +52 -10
- package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
- package/dist/team/__tests__/idle-nudge.test.js +45 -15
- package/dist/team/__tests__/idle-nudge.test.js.map +1 -1
- package/dist/team/__tests__/mcp-comm.test.js +93 -27
- package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
- package/dist/team/__tests__/model-contract.test.js +341 -4
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/role-router.test.js.map +1 -1
- package/dist/team/__tests__/runtime-cli.test.js +9 -0
- package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +3624 -355
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +2516 -118
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/state.test.js +804 -36
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/team-ops-contract.test.js +6 -0
- package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +3664 -969
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
- package/dist/team/__tests__/worker-runtime-identity.test.js +38 -2
- package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
- package/dist/team/__tests__/worktree.test.js +6 -0
- package/dist/team/__tests__/worktree.test.js.map +1 -1
- package/dist/team/api-interop.d.ts +2 -2
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +15 -9
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/commit-hygiene.js.map +1 -1
- package/dist/team/contracts.d.ts +5 -5
- package/dist/team/contracts.d.ts.map +1 -1
- package/dist/team/delivery-log.js.map +1 -1
- package/dist/team/exact-pane.d.ts +23 -0
- package/dist/team/exact-pane.d.ts.map +1 -0
- package/dist/team/exact-pane.js +133 -0
- package/dist/team/exact-pane.js.map +1 -0
- package/dist/team/followup-planner.js.map +1 -1
- package/dist/team/goal-workflow.js.map +1 -1
- package/dist/team/idle-nudge.d.ts +12 -1
- package/dist/team/idle-nudge.d.ts.map +1 -1
- package/dist/team/idle-nudge.js +41 -14
- package/dist/team/idle-nudge.js.map +1 -1
- package/dist/team/model-contract.d.ts +18 -2
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +314 -35
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/orchestrator.js.map +1 -1
- package/dist/team/pane-status.js.map +1 -1
- package/dist/team/phase-controller.js.map +1 -1
- package/dist/team/reminder-intents.d.ts +1 -1
- package/dist/team/reminder-intents.d.ts.map +1 -1
- package/dist/team/reminder-intents.js.map +1 -1
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime.d.ts +1 -0
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +1326 -231
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts +22 -8
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +1463 -376
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/dispatch-lock.js.map +1 -1
- package/dist/team/state/dispatch.d.ts.map +1 -1
- package/dist/team/state/dispatch.js +26 -8
- package/dist/team/state/dispatch.js.map +1 -1
- package/dist/team/state/events.js.map +1 -1
- package/dist/team/state/locks.d.ts.map +1 -1
- package/dist/team/state/locks.js +61 -13
- package/dist/team/state/locks.js.map +1 -1
- package/dist/team/state/tasks.d.ts.map +1 -1
- package/dist/team/state/tasks.js +4 -3
- package/dist/team/state/tasks.js.map +1 -1
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts +67 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +636 -129
- package/dist/team/state.js.map +1 -1
- package/dist/team/team-identity.d.ts.map +1 -1
- package/dist/team/team-identity.js.map +1 -1
- package/dist/team/team-ops.d.ts +5 -0
- package/dist/team/team-ops.d.ts.map +1 -1
- package/dist/team/team-ops.js +4 -0
- package/dist/team/team-ops.js.map +1 -1
- package/dist/team/tmux-session.d.ts +125 -23
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +1340 -333
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/team/worktree.d.ts.map +1 -1
- package/dist/team/worktree.js +4 -0
- package/dist/team/worktree.js.map +1 -1
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +4 -1
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/dist/url-reader/index.js.map +1 -1
- package/dist/utils/__tests__/file-durability.test.d.ts +2 -0
- package/dist/utils/__tests__/file-durability.test.d.ts.map +1 -0
- package/dist/utils/__tests__/file-durability.test.js +57 -0
- package/dist/utils/__tests__/file-durability.test.js.map +1 -0
- package/dist/utils/agents-model-table.js.map +1 -1
- package/dist/utils/file-durability.d.ts +15 -0
- package/dist/utils/file-durability.d.ts.map +1 -0
- package/dist/utils/file-durability.js +37 -0
- package/dist/utils/file-durability.js.map +1 -0
- package/dist/utils/package.js.map +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/platform-command.js.map +1 -1
- package/dist/utils/repo-deps.js.map +1 -1
- package/dist/utils/version.js.map +1 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js +1 -1
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +3 -0
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +1 -1
- package/dist/verification/verifier.js.map +1 -1
- package/dist/visual/constants.d.ts +1 -1
- package/dist/visual/constants.d.ts.map +1 -1
- package/dist/vscode/__tests__/index.test.js.map +1 -1
- package/dist/vscode/index.js.map +1 -1
- package/dist/wiki/__tests__/cjk-tokenize.test.js.map +1 -1
- package/dist/wiki/__tests__/lint.test.js.map +1 -1
- package/dist/wiki/__tests__/query.test.js.map +1 -1
- package/dist/wiki/__tests__/storage.test.js.map +1 -1
- package/dist/wiki/__tests__/test-helpers.d.ts.map +1 -1
- package/dist/wiki/lint.d.ts +4 -1
- package/dist/wiki/lint.d.ts.map +1 -1
- package/dist/wiki/lint.js +3 -2
- package/dist/wiki/lint.js.map +1 -1
- package/dist/wiki/query.js.map +1 -1
- package/dist/wiki/storage.js.map +1 -1
- package/package.json +2 -2
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +24 -0
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +10 -5
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +6 -2
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +6 -2
- package/plugins/oh-my-codex/skills/team/SKILL.md +13 -9
- package/skills/omx-setup/SKILL.md +10 -5
- package/skills/ralph/SKILL.md +6 -2
- package/skills/ralplan/SKILL.md +6 -2
- package/skills/team/SKILL.md +13 -9
- package/src/scripts/__tests__/codex-native-hook.test.ts +20048 -10827
- package/src/scripts/__tests__/fixtures/issue-3138-installed-smoke.ts +734 -0
- package/src/scripts/__tests__/notify-fallback-delivery.test.ts +177 -0
- package/src/scripts/__tests__/notify-state-io.test.ts +73 -0
- package/src/scripts/__tests__/reasoning-artifact-contract.test.ts +129 -0
- package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +78 -0
- package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +60 -0
- package/src/scripts/__tests__/smoke-packed-install.test.ts +1309 -4
- package/src/scripts/codex-native-hook.ts +11429 -1163
- package/src/scripts/notify-fallback-delivery.ts +416 -0
- package/src/scripts/notify-fallback-watcher.ts +216 -155
- package/src/scripts/notify-hook/auto-nudge.ts +113 -14
- package/src/scripts/notify-hook/managed-tmux.ts +149 -12
- package/src/scripts/notify-hook/ralph-session-resume.ts +37 -36
- package/src/scripts/notify-hook/state-io.ts +100 -13
- package/src/scripts/notify-hook/team-dispatch.ts +242 -75
- package/src/scripts/notify-hook/team-leader-nudge.ts +40 -18
- package/src/scripts/notify-hook/team-tmux-guard.ts +366 -39
- package/src/scripts/notify-hook/team-worker-stop.ts +20 -16
- package/src/scripts/notify-hook/team-worker.ts +39 -26
- package/src/scripts/notify-hook/tmux-injection.ts +66 -23
- package/src/scripts/notify-hook/visual-verdict.ts +22 -12
- package/src/scripts/notify-hook.ts +336 -90
- package/src/scripts/smoke-packed-install.ts +5154 -149
|
@@ -74,6 +74,11 @@ if [[ "$cmd" == "display-message" ]]; then
|
|
|
74
74
|
fi
|
|
75
75
|
exit 0
|
|
76
76
|
fi
|
|
77
|
+
if [[ "$cmd" == "show-option" && "$*" == *"@omx_team_pane_owner_id" ]]; then
|
|
78
|
+
echo "team:alpha"
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
77
82
|
if [[ "$cmd" == "set-buffer" ]]; then
|
|
78
83
|
printf '%s' "\${@: -1}" > "${tmuxLogPath}.buffer"
|
|
79
84
|
exit 0
|
|
@@ -103,12 +108,49 @@ if [[ "$cmd" == "send-keys" ]]; then
|
|
|
103
108
|
exit 0
|
|
104
109
|
fi
|
|
105
110
|
if [[ "$cmd" == "list-panes" ]]; then
|
|
111
|
+
if [[ "$*" == *"#{pane_dead}"* ]]; then
|
|
112
|
+
if [[ -n "\${OMX_TEST_EXACT_PANE_SEQUENCE_FILE:-}" && -f "\${OMX_TEST_EXACT_PANE_SEQUENCE_FILE}" ]]; then
|
|
113
|
+
counterFile="\${OMX_TEST_EXACT_PANE_COUNTER_FILE:-\${OMX_TEST_EXACT_PANE_SEQUENCE_FILE}.idx}"
|
|
114
|
+
idx=0
|
|
115
|
+
if [[ -f "$counterFile" ]]; then idx="$(cat "$counterFile")"; fi
|
|
116
|
+
lineNo=$((idx + 1))
|
|
117
|
+
line="$(sed -n "\${lineNo}p" "\${OMX_TEST_EXACT_PANE_SEQUENCE_FILE}" || true)"
|
|
118
|
+
if [[ -z "$line" ]]; then
|
|
119
|
+
line="$(tail -n 1 "\${OMX_TEST_EXACT_PANE_SEQUENCE_FILE}" || true)"
|
|
120
|
+
fi
|
|
121
|
+
echo "$lineNo" > "$counterFile"
|
|
122
|
+
if [[ "$line" != "__EMPTY__" ]]; then printf '%b\n' "$line"; fi
|
|
123
|
+
exit 0
|
|
124
|
+
fi
|
|
125
|
+
printf '%%42\t0\t4242\n%%99\t0\t9999\n'
|
|
126
|
+
exit 0
|
|
127
|
+
fi
|
|
106
128
|
echo "%42 1"
|
|
107
129
|
exit 0
|
|
108
130
|
fi
|
|
109
131
|
exit 0
|
|
110
132
|
`;
|
|
111
133
|
}
|
|
134
|
+
function assertFreshExactProofBeforePaneEffects(tmuxLog, paneId) {
|
|
135
|
+
const commands = tmuxLog.trim().split('\n').filter(Boolean);
|
|
136
|
+
const exactGlobalPaneProof = /^list-panes -a -F #\{pane_id\}\t#\{pane_dead\}\t#\{pane_pid\}$/;
|
|
137
|
+
const ownerProof = new RegExp(`^show-option -qv -p -t ${paneId} @omx_team_pane_owner_id$`);
|
|
138
|
+
const effects = commands
|
|
139
|
+
.map((command, index) => ({ command, index }))
|
|
140
|
+
.filter(({ command }) => (command.startsWith(`paste-buffer -t ${paneId} `)
|
|
141
|
+
|| command.startsWith(`kill-pane -t ${paneId} `)
|
|
142
|
+
|| (command.startsWith(`send-keys -t ${paneId} `) && !command.includes(' -l '))));
|
|
143
|
+
assert.ok(effects.length > 0, `expected explicit pane effects for ${paneId}:\n${commands.join('\n')}`);
|
|
144
|
+
for (const { command, index } of effects) {
|
|
145
|
+
assert.match(commands[index - 1] ?? '', exactGlobalPaneProof, `final PID proof must immediately precede ${command}`);
|
|
146
|
+
assert.match(commands[index - 2] ?? '', ownerProof, `owner proof must immediately precede the final PID proof for ${command}`);
|
|
147
|
+
assert.match(commands[index - 3] ?? '', exactGlobalPaneProof, `initial PID proof must precede owner proof for ${command}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function bindCanonicalTeamPaneAuthority(config, hudPaneId = '%88') {
|
|
151
|
+
config.tmux_pane_owner_id = 'team:alpha';
|
|
152
|
+
config.hud_pane_id = hudPaneId;
|
|
153
|
+
}
|
|
112
154
|
async function readTeamDeliveryLog(cwd) {
|
|
113
155
|
const path = join(cwd, '.omx', 'logs', `team-delivery-${new Date().toISOString().slice(0, 10)}.jsonl`);
|
|
114
156
|
const raw = await readFile(path, 'utf-8').catch(() => '');
|
|
@@ -579,6 +621,8 @@ exit 0
|
|
|
579
621
|
if (!cfg)
|
|
580
622
|
throw new Error('missing team config');
|
|
581
623
|
cfg.leader_pane_id = '%99';
|
|
624
|
+
cfg.leader_pane_pid = 9999;
|
|
625
|
+
bindCanonicalTeamPaneAuthority(cfg);
|
|
582
626
|
await saveTeamConfig(cfg, cwd);
|
|
583
627
|
const msg = await sendDirectMessage('alpha', 'worker-1', 'leader-fixed', 'hello leader', cwd);
|
|
584
628
|
await enqueueDispatchRequest('alpha', {
|
|
@@ -592,6 +636,7 @@ exit 0
|
|
|
592
636
|
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
593
637
|
assert.equal(result.processed, 1);
|
|
594
638
|
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
639
|
+
assertFreshExactProofBeforePaneEffects(tmuxLog, '%99');
|
|
595
640
|
assert.match(tmuxLog, /send-keys -t %99/);
|
|
596
641
|
assert.match(tmuxLog, /mailbox\/leader-fixed\.json; worker-1 sent a new message/);
|
|
597
642
|
assert.doesNotMatch(tmuxLog, /send-keys -t .*devsess/);
|
|
@@ -604,7 +649,207 @@ exit 0
|
|
|
604
649
|
await rm(cwd, { recursive: true, force: true });
|
|
605
650
|
}
|
|
606
651
|
});
|
|
607
|
-
it('
|
|
652
|
+
it('uses the persisted worker pane as an exact identity without generic resolution', async () => {
|
|
653
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-hook-team-dispatch-'));
|
|
654
|
+
const fakeBinDir = join(cwd, 'fake-bin');
|
|
655
|
+
const tmuxLogPath = join(cwd, 'tmux.log');
|
|
656
|
+
const previousPath = process.env.PATH;
|
|
657
|
+
try {
|
|
658
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
659
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
660
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
661
|
+
process.env.PATH = `${fakeBinDir}:${previousPath || ''}`;
|
|
662
|
+
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
663
|
+
const cfg = await readTeamConfig('alpha', cwd);
|
|
664
|
+
assert.ok(cfg);
|
|
665
|
+
if (!cfg)
|
|
666
|
+
throw new Error('missing team config');
|
|
667
|
+
cfg.workers[0].pane_id = '%99';
|
|
668
|
+
cfg.workers[0].pid = 9999;
|
|
669
|
+
bindCanonicalTeamPaneAuthority(cfg);
|
|
670
|
+
await saveTeamConfig(cfg, cwd);
|
|
671
|
+
await enqueueDispatchRequest('alpha', {
|
|
672
|
+
kind: 'inbox',
|
|
673
|
+
to_worker: 'worker-1',
|
|
674
|
+
worker_index: 1,
|
|
675
|
+
trigger_message: 'use the configured worker pane',
|
|
676
|
+
}, cwd);
|
|
677
|
+
const modulePath = new URL('../../../dist/scripts/notify-hook/team-dispatch.js', import.meta.url).pathname;
|
|
678
|
+
const mod = await import(pathToFileURL(modulePath).href);
|
|
679
|
+
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
680
|
+
assert.equal(result.processed, 1);
|
|
681
|
+
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
682
|
+
assertFreshExactProofBeforePaneEffects(tmuxLog, '%99');
|
|
683
|
+
assert.match(tmuxLog, /send-keys -t %99/);
|
|
684
|
+
assert.doesNotMatch(tmuxLog, /display-message -p -t %99 #\{pane_id\}/);
|
|
685
|
+
assert.doesNotMatch(tmuxLog, /list-panes -t /);
|
|
686
|
+
}
|
|
687
|
+
finally {
|
|
688
|
+
if (typeof previousPath === 'string')
|
|
689
|
+
process.env.PATH = previousPath;
|
|
690
|
+
else
|
|
691
|
+
delete process.env.PATH;
|
|
692
|
+
await rm(cwd, { recursive: true, force: true });
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
it('fails closed without a canonical PID for explicit worker and leader panes', async () => {
|
|
696
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-hook-missing-pane-pid-'));
|
|
697
|
+
try {
|
|
698
|
+
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
699
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
700
|
+
assert.ok(config?.workers[0]);
|
|
701
|
+
if (!config?.workers[0])
|
|
702
|
+
throw new Error('missing worker');
|
|
703
|
+
config.workers[0].pane_id = '%42';
|
|
704
|
+
config.leader_pane_id = '%99';
|
|
705
|
+
await saveTeamConfig(config, cwd);
|
|
706
|
+
const worker = await enqueueDispatchRequest('alpha', {
|
|
707
|
+
kind: 'inbox', to_worker: 'worker-1', worker_index: 1, trigger_message: 'do not send',
|
|
708
|
+
}, cwd);
|
|
709
|
+
const leader = await enqueueDispatchRequest('alpha', {
|
|
710
|
+
kind: 'nudge', to_worker: 'leader-fixed', trigger_message: 'leader do not send',
|
|
711
|
+
}, cwd);
|
|
712
|
+
const modulePath = new URL('../../../dist/scripts/notify-hook/team-dispatch.js', import.meta.url).pathname;
|
|
713
|
+
const mod = await import(pathToFileURL(modulePath).href);
|
|
714
|
+
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
715
|
+
assert.equal(result.failed, 2);
|
|
716
|
+
assert.equal((await readDispatchRequest('alpha', worker.request.request_id, cwd))?.last_reason, 'missing_exact_pane_pid');
|
|
717
|
+
assert.equal((await readDispatchRequest('alpha', leader.request.request_id, cwd))?.last_reason, 'missing_exact_pane_pid');
|
|
718
|
+
}
|
|
719
|
+
finally {
|
|
720
|
+
await rm(cwd, { recursive: true, force: true });
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
it('does not send when a guarded worker pane is reused before input effects', async () => {
|
|
724
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-hook-pane-pid-reuse-'));
|
|
725
|
+
const fakeBinDir = join(cwd, 'fake-bin');
|
|
726
|
+
const tmuxLogPath = join(cwd, 'tmux.log');
|
|
727
|
+
const proofSequencePath = join(cwd, 'exact-pane-sequence.txt');
|
|
728
|
+
const previousPath = process.env.PATH;
|
|
729
|
+
try {
|
|
730
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
731
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
732
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
733
|
+
await writeFile(proofSequencePath, [
|
|
734
|
+
'%42\\t0\\t4242', '%42\\t0\\t4242', '%42\\t0\\t4242',
|
|
735
|
+
'%42\\t0\\t4242', '%42\\t0\\t4242', '%42\\t0\\t4242',
|
|
736
|
+
'%42\\t0\\t5252',
|
|
737
|
+
].join('\n'));
|
|
738
|
+
process.env.PATH = `${fakeBinDir}:${previousPath || ''}`;
|
|
739
|
+
process.env.OMX_TEST_EXACT_PANE_SEQUENCE_FILE = proofSequencePath;
|
|
740
|
+
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
741
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
742
|
+
assert.ok(config?.workers[0]);
|
|
743
|
+
if (!config?.workers[0])
|
|
744
|
+
throw new Error('missing worker');
|
|
745
|
+
config.workers[0].pane_id = '%42';
|
|
746
|
+
config.workers[0].pid = 4242;
|
|
747
|
+
bindCanonicalTeamPaneAuthority(config);
|
|
748
|
+
await saveTeamConfig(config, cwd);
|
|
749
|
+
const queued = await enqueueDispatchRequest('alpha', {
|
|
750
|
+
kind: 'inbox', to_worker: 'worker-1', worker_index: 1, trigger_message: 'do not send',
|
|
751
|
+
}, cwd);
|
|
752
|
+
const modulePath = new URL('../../../dist/scripts/notify-hook/team-dispatch.js', import.meta.url).pathname;
|
|
753
|
+
const mod = await import(pathToFileURL(modulePath).href);
|
|
754
|
+
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
755
|
+
assert.equal(result.failed, 1);
|
|
756
|
+
assert.equal((await readDispatchRequest('alpha', queued.request.request_id, cwd))?.last_reason, 'exact_pane_unavailable');
|
|
757
|
+
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
758
|
+
assert.doesNotMatch(tmuxLog, /(?:paste-buffer|send-keys) -t %42/, 'replacement pane must receive no input effect');
|
|
759
|
+
}
|
|
760
|
+
finally {
|
|
761
|
+
if (typeof previousPath === 'string')
|
|
762
|
+
process.env.PATH = previousPath;
|
|
763
|
+
else
|
|
764
|
+
delete process.env.PATH;
|
|
765
|
+
delete process.env.OMX_TEST_EXACT_PANE_SEQUENCE_FILE;
|
|
766
|
+
delete process.env.OMX_TEST_EXACT_PANE_COUNTER_FILE;
|
|
767
|
+
await rm(cwd, { recursive: true, force: true });
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
it('fails closed before tmux effects when request and configured panes differ', async () => {
|
|
771
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-hook-team-dispatch-'));
|
|
772
|
+
const fakeBinDir = join(cwd, 'fake-bin');
|
|
773
|
+
const tmuxLogPath = join(cwd, 'tmux.log');
|
|
774
|
+
const previousPath = process.env.PATH;
|
|
775
|
+
try {
|
|
776
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
777
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
778
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
779
|
+
process.env.PATH = `${fakeBinDir}:${previousPath || ''}`;
|
|
780
|
+
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
781
|
+
const cfg = await readTeamConfig('alpha', cwd);
|
|
782
|
+
assert.ok(cfg);
|
|
783
|
+
if (!cfg)
|
|
784
|
+
throw new Error('missing team config');
|
|
785
|
+
cfg.workers[0].pane_id = '%99';
|
|
786
|
+
await saveTeamConfig(cfg, cwd);
|
|
787
|
+
const queued = await enqueueDispatchRequest('alpha', {
|
|
788
|
+
kind: 'inbox',
|
|
789
|
+
to_worker: 'worker-1',
|
|
790
|
+
worker_index: 1,
|
|
791
|
+
pane_id: '%42',
|
|
792
|
+
trigger_message: 'must not be redirected',
|
|
793
|
+
}, cwd);
|
|
794
|
+
const modulePath = new URL('../../../dist/scripts/notify-hook/team-dispatch.js', import.meta.url).pathname;
|
|
795
|
+
const mod = await import(pathToFileURL(modulePath).href);
|
|
796
|
+
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
797
|
+
assert.equal(result.failed, 1);
|
|
798
|
+
const request = await readDispatchRequest('alpha', queued.request.request_id, cwd);
|
|
799
|
+
assert.equal(request?.status, 'failed');
|
|
800
|
+
assert.equal(request?.last_reason, 'exact_pane_mismatch');
|
|
801
|
+
assert.equal(await readFile(tmuxLogPath, 'utf8').catch(() => ''), '');
|
|
802
|
+
}
|
|
803
|
+
finally {
|
|
804
|
+
if (typeof previousPath === 'string')
|
|
805
|
+
process.env.PATH = previousPath;
|
|
806
|
+
else
|
|
807
|
+
delete process.env.PATH;
|
|
808
|
+
await rm(cwd, { recursive: true, force: true });
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
it('fails an invalid request pane without session or index fallback', async () => {
|
|
812
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-hook-team-dispatch-'));
|
|
813
|
+
const fakeBinDir = join(cwd, 'fake-bin');
|
|
814
|
+
const tmuxLogPath = join(cwd, 'tmux.log');
|
|
815
|
+
const previousPath = process.env.PATH;
|
|
816
|
+
try {
|
|
817
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
818
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
819
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
820
|
+
process.env.PATH = `${fakeBinDir}:${previousPath || ''}`;
|
|
821
|
+
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
822
|
+
const cfg = await readTeamConfig('alpha', cwd);
|
|
823
|
+
assert.ok(cfg);
|
|
824
|
+
if (!cfg)
|
|
825
|
+
throw new Error('missing team config');
|
|
826
|
+
cfg.tmux_session = 'must-not-resolve';
|
|
827
|
+
delete cfg.workers[0].pane_id;
|
|
828
|
+
await saveTeamConfig(cfg, cwd);
|
|
829
|
+
const queued = await enqueueDispatchRequest('alpha', {
|
|
830
|
+
kind: 'inbox',
|
|
831
|
+
to_worker: 'worker-1',
|
|
832
|
+
worker_index: 1,
|
|
833
|
+
pane_id: 'invalid-pane-id',
|
|
834
|
+
trigger_message: 'must not be sent',
|
|
835
|
+
}, cwd);
|
|
836
|
+
const modulePath = new URL('../../../dist/scripts/notify-hook/team-dispatch.js', import.meta.url).pathname;
|
|
837
|
+
const mod = await import(pathToFileURL(modulePath).href);
|
|
838
|
+
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
839
|
+
assert.equal(result.failed, 1);
|
|
840
|
+
const request = await readDispatchRequest('alpha', queued.request.request_id, cwd);
|
|
841
|
+
assert.equal(request?.last_reason, 'exact_pane_unavailable');
|
|
842
|
+
assert.equal(await readFile(tmuxLogPath, 'utf8').catch(() => ''), '');
|
|
843
|
+
}
|
|
844
|
+
finally {
|
|
845
|
+
if (typeof previousPath === 'string')
|
|
846
|
+
process.env.PATH = previousPath;
|
|
847
|
+
else
|
|
848
|
+
delete process.env.PATH;
|
|
849
|
+
await rm(cwd, { recursive: true, force: true });
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
it('uses the persisted leader pane as an exact identity without resolver healing', async () => {
|
|
608
853
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-hook-team-dispatch-'));
|
|
609
854
|
const fakeBinDir = join(cwd, 'fake-bin');
|
|
610
855
|
const tmuxLogPath = join(cwd, 'tmux.log');
|
|
@@ -657,7 +902,7 @@ if [[ "$cmd" == "display-message" ]]; then
|
|
|
657
902
|
exit 0
|
|
658
903
|
fi
|
|
659
904
|
if [[ "$fmt" == "#{pane_start_command}" && "$target" == "%91" ]]; then
|
|
660
|
-
echo "
|
|
905
|
+
echo "codex"
|
|
661
906
|
exit 0
|
|
662
907
|
fi
|
|
663
908
|
if [[ "$fmt" == "#{pane_start_command}" && "$target" == "%42" ]]; then
|
|
@@ -674,6 +919,10 @@ if [[ "$cmd" == "display-message" ]]; then
|
|
|
674
919
|
fi
|
|
675
920
|
exit 0
|
|
676
921
|
fi
|
|
922
|
+
if [[ "$cmd" == "show-option" && "$*" == *"@omx_team_pane_owner_id" ]]; then
|
|
923
|
+
echo "team:alpha"
|
|
924
|
+
exit 0
|
|
925
|
+
fi
|
|
677
926
|
if [[ "$cmd" == "set-buffer" ]]; then
|
|
678
927
|
printf '%s' "\${@: -1}" > "${tmuxLogPath}.buffer"
|
|
679
928
|
exit 0
|
|
@@ -703,7 +952,11 @@ if [[ "$cmd" == "send-keys" ]]; then
|
|
|
703
952
|
exit 0
|
|
704
953
|
fi
|
|
705
954
|
if [[ "$cmd" == "list-panes" ]]; then
|
|
706
|
-
|
|
955
|
+
if [[ "$*" == *"#{pane_dead}"* ]]; then
|
|
956
|
+
printf "%%42\\t0\\t4242\\n%%91\\t0\\t9191\\n"
|
|
957
|
+
else
|
|
958
|
+
printf "%%42\\t1\\tnode\\tcodex\\n%%91\\t0\\tnode\\tnode dist/cli/omx.js hud --watch\\n"
|
|
959
|
+
fi
|
|
707
960
|
exit 0
|
|
708
961
|
fi
|
|
709
962
|
exit 0
|
|
@@ -718,6 +971,8 @@ exit 0
|
|
|
718
971
|
if (!cfg)
|
|
719
972
|
throw new Error('missing team config');
|
|
720
973
|
cfg.leader_pane_id = '%91';
|
|
974
|
+
cfg.leader_pane_pid = 9191;
|
|
975
|
+
bindCanonicalTeamPaneAuthority(cfg);
|
|
721
976
|
await saveTeamConfig(cfg, cwd);
|
|
722
977
|
const msg = await sendDirectMessage('alpha', 'worker-1', 'leader-fixed', 'hello leader', cwd);
|
|
723
978
|
await enqueueDispatchRequest('alpha', {
|
|
@@ -731,8 +986,22 @@ exit 0
|
|
|
731
986
|
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
732
987
|
assert.equal(result.processed, 1);
|
|
733
988
|
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
734
|
-
assert.match(tmuxLog, /send-keys -t %
|
|
735
|
-
assert.doesNotMatch(tmuxLog, /send-keys -t %
|
|
989
|
+
assert.match(tmuxLog, /send-keys -t %91/);
|
|
990
|
+
assert.doesNotMatch(tmuxLog, /send-keys -t %42/);
|
|
991
|
+
assert.doesNotMatch(tmuxLog, /display-message -p -t %91 #\{pane_id\}/, 'configured leader pane must bypass the generic resolver');
|
|
992
|
+
cfg.hud_pane_id = '%91';
|
|
993
|
+
await saveTeamConfig(cfg, cwd);
|
|
994
|
+
const hudMsg = await sendDirectMessage('alpha', 'worker-1', 'leader-fixed', 'second leader message', cwd);
|
|
995
|
+
const hudQueued = await enqueueDispatchRequest('alpha', {
|
|
996
|
+
kind: 'mailbox',
|
|
997
|
+
to_worker: 'leader-fixed',
|
|
998
|
+
message_id: hudMsg.message_id,
|
|
999
|
+
trigger_message: 'must not target the HUD pane',
|
|
1000
|
+
}, cwd);
|
|
1001
|
+
const hudResult = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
1002
|
+
assert.equal(hudResult.failed, 1);
|
|
1003
|
+
const hudRequest = await readDispatchRequest('alpha', hudQueued.request.request_id, cwd);
|
|
1004
|
+
assert.equal(hudRequest?.last_reason, 'hud_pane_target');
|
|
736
1005
|
}
|
|
737
1006
|
finally {
|
|
738
1007
|
if (typeof prevPath === 'string')
|
|
@@ -795,6 +1064,10 @@ if [[ "$cmd" == "display-message" ]]; then
|
|
|
795
1064
|
fi
|
|
796
1065
|
exit 0
|
|
797
1066
|
fi
|
|
1067
|
+
if [[ "$cmd" == "show-option" && "$*" == *"@omx_team_pane_owner_id" ]]; then
|
|
1068
|
+
echo "team:alpha"
|
|
1069
|
+
exit 0
|
|
1070
|
+
fi
|
|
798
1071
|
if [[ "$cmd" == "set-buffer" ]]; then
|
|
799
1072
|
printf '%s' "\${@: -1}" > "${tmuxLogPath}.buffer"
|
|
800
1073
|
exit 0
|
|
@@ -824,7 +1097,11 @@ if [[ "$cmd" == "send-keys" ]]; then
|
|
|
824
1097
|
exit 0
|
|
825
1098
|
fi
|
|
826
1099
|
if [[ "$cmd" == "list-panes" ]]; then
|
|
827
|
-
|
|
1100
|
+
if [[ "$*" == *"#{pane_dead}"* ]]; then
|
|
1101
|
+
printf "%%77\\t0\\t7777\\n"
|
|
1102
|
+
else
|
|
1103
|
+
printf "%%77\\t1\\tcodex\\tcodex\\n"
|
|
1104
|
+
fi
|
|
828
1105
|
exit 0
|
|
829
1106
|
fi
|
|
830
1107
|
exit 0
|
|
@@ -837,6 +1114,8 @@ exit 0
|
|
|
837
1114
|
if (!cfg)
|
|
838
1115
|
throw new Error('missing team config');
|
|
839
1116
|
cfg.leader_pane_id = '%77';
|
|
1117
|
+
cfg.leader_pane_pid = 7777;
|
|
1118
|
+
bindCanonicalTeamPaneAuthority(cfg);
|
|
840
1119
|
await saveTeamConfig(cfg, cwd);
|
|
841
1120
|
const msg = await sendDirectMessage('alpha', 'worker-1', 'leader-fixed', 'hello leader', cwd);
|
|
842
1121
|
const queued = await enqueueDispatchRequest('alpha', {
|
|
@@ -1233,6 +1512,14 @@ exit 0
|
|
|
1233
1512
|
process.env.PATH = `${fakeBinDir}:${previousPath || ''}`;
|
|
1234
1513
|
process.env.OMX_TEST_CAPTURE_FILE = captureFile;
|
|
1235
1514
|
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
1515
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
1516
|
+
assert.ok(config?.workers[0]);
|
|
1517
|
+
if (!config?.workers[0])
|
|
1518
|
+
throw new Error('missing worker');
|
|
1519
|
+
config.workers[0].pane_id = '%42';
|
|
1520
|
+
config.workers[0].pid = 4242;
|
|
1521
|
+
bindCanonicalTeamPaneAuthority(config);
|
|
1522
|
+
await saveTeamConfig(config, cwd);
|
|
1236
1523
|
const queued = await enqueueDispatchRequest('alpha', {
|
|
1237
1524
|
kind: 'inbox',
|
|
1238
1525
|
to_worker: 'worker-1',
|
|
@@ -1290,6 +1577,14 @@ exit 0
|
|
|
1290
1577
|
process.env.OMX_TEST_CAPTURE_SEQUENCE_FILE = captureSeqFile;
|
|
1291
1578
|
process.env.OMX_TEST_CAPTURE_COUNTER_FILE = captureCounterFile;
|
|
1292
1579
|
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
1580
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
1581
|
+
assert.ok(config?.workers[0]);
|
|
1582
|
+
if (!config?.workers[0])
|
|
1583
|
+
throw new Error('missing worker');
|
|
1584
|
+
config.workers[0].pane_id = '%42';
|
|
1585
|
+
config.workers[0].pid = 4242;
|
|
1586
|
+
bindCanonicalTeamPaneAuthority(config);
|
|
1587
|
+
await saveTeamConfig(config, cwd);
|
|
1293
1588
|
const queued = await enqueueDispatchRequest('alpha', {
|
|
1294
1589
|
kind: 'inbox',
|
|
1295
1590
|
to_worker: 'worker-1',
|
|
@@ -1343,6 +1638,14 @@ exit 0
|
|
|
1343
1638
|
process.env.OMX_TEST_CAPTURE_SEQUENCE_FILE = captureSeqFile;
|
|
1344
1639
|
process.env.OMX_TEST_CAPTURE_COUNTER_FILE = captureCounterFile;
|
|
1345
1640
|
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
1641
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
1642
|
+
assert.ok(config?.workers[0]);
|
|
1643
|
+
if (!config?.workers[0])
|
|
1644
|
+
throw new Error('missing worker');
|
|
1645
|
+
config.workers[0].pane_id = '%42';
|
|
1646
|
+
config.workers[0].pid = 4242;
|
|
1647
|
+
bindCanonicalTeamPaneAuthority(config);
|
|
1648
|
+
await saveTeamConfig(config, cwd);
|
|
1346
1649
|
const queued = await enqueueDispatchRequest('alpha', {
|
|
1347
1650
|
kind: 'inbox',
|
|
1348
1651
|
to_worker: 'worker-1',
|
|
@@ -1390,6 +1693,14 @@ exit 0
|
|
|
1390
1693
|
process.env.OMX_TEST_CAPTURE_SEQUENCE_FILE = captureSeqFile;
|
|
1391
1694
|
process.env.OMX_TEST_CAPTURE_COUNTER_FILE = captureCounterFile;
|
|
1392
1695
|
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
1696
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
1697
|
+
assert.ok(config?.workers[0]);
|
|
1698
|
+
if (!config?.workers[0])
|
|
1699
|
+
throw new Error('missing worker');
|
|
1700
|
+
config.workers[0].pane_id = '%42';
|
|
1701
|
+
config.workers[0].pid = 4242;
|
|
1702
|
+
bindCanonicalTeamPaneAuthority(config);
|
|
1703
|
+
await saveTeamConfig(config, cwd);
|
|
1393
1704
|
const queued = await enqueueDispatchRequest('alpha', {
|
|
1394
1705
|
kind: 'inbox',
|
|
1395
1706
|
to_worker: 'worker-1',
|
|
@@ -1504,7 +1815,7 @@ exit 0
|
|
|
1504
1815
|
await rm(cwd, { recursive: true, force: true });
|
|
1505
1816
|
}
|
|
1506
1817
|
});
|
|
1507
|
-
it('
|
|
1818
|
+
it('rejects a session-only dispatch target without an exact Team pane binding', async () => {
|
|
1508
1819
|
const cwd = await mkdtemp(join(tmpdir(), 'omx-dispatch-session-target-'));
|
|
1509
1820
|
const stateDir = join(cwd, '.omx', 'state');
|
|
1510
1821
|
const logsDir = join(cwd, '.omx', 'logs');
|
|
@@ -1543,13 +1854,221 @@ exit 0
|
|
|
1543
1854
|
}
|
|
1544
1855
|
const requests = JSON.parse(await readFile(join(stateDir, 'team', 'session-target-team', 'dispatch', 'requests.json'), 'utf-8'));
|
|
1545
1856
|
const request = requests.find((entry) => entry.to_worker === 'worker-1');
|
|
1546
|
-
assert.
|
|
1547
|
-
assert.
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1857
|
+
assert.equal(request?.status, 'failed');
|
|
1858
|
+
assert.equal(request?.last_reason, 'missing_tmux_target');
|
|
1859
|
+
assert.equal(await readFile(tmuxLogPath, 'utf-8').catch(() => ''), '');
|
|
1860
|
+
}
|
|
1861
|
+
finally {
|
|
1862
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1863
|
+
}
|
|
1864
|
+
});
|
|
1865
|
+
it('fails closed for invalid explicit pane proofs without resolving or targeting another pane', async () => {
|
|
1866
|
+
const scenarios = [
|
|
1867
|
+
['similar', '%420\\t0\\t4200'],
|
|
1868
|
+
['dead', '%42\\t1\\t4242'],
|
|
1869
|
+
['missing', '__EMPTY__'],
|
|
1870
|
+
['unavailable', 'malformed snapshot'],
|
|
1871
|
+
];
|
|
1872
|
+
for (const [name, snapshot] of scenarios) {
|
|
1873
|
+
const cwd = await mkdtemp(join(tmpdir(), `omx-hook-exact-pane-${name}-`));
|
|
1874
|
+
const fakeBinDir = join(cwd, 'fake-bin');
|
|
1875
|
+
const tmuxLogPath = join(cwd, 'tmux.log');
|
|
1876
|
+
const exactPaneSequencePath = join(cwd, 'exact-pane-sequence.txt');
|
|
1877
|
+
const previousPath = process.env.PATH;
|
|
1878
|
+
try {
|
|
1879
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
1880
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
1881
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
1882
|
+
await writeFile(exactPaneSequencePath, `${snapshot}\n`);
|
|
1883
|
+
process.env.PATH = `${fakeBinDir}:${previousPath || ''}`;
|
|
1884
|
+
process.env.OMX_TEST_EXACT_PANE_SEQUENCE_FILE = exactPaneSequencePath;
|
|
1885
|
+
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
1886
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
1887
|
+
assert.ok(config?.workers[0]);
|
|
1888
|
+
if (!config?.workers[0])
|
|
1889
|
+
throw new Error('missing worker');
|
|
1890
|
+
config.workers[0].pane_id = '%42';
|
|
1891
|
+
config.workers[0].pid = 4242;
|
|
1892
|
+
bindCanonicalTeamPaneAuthority(config);
|
|
1893
|
+
await saveTeamConfig(config, cwd);
|
|
1894
|
+
const queued = await enqueueDispatchRequest('alpha', {
|
|
1895
|
+
kind: 'inbox',
|
|
1896
|
+
to_worker: 'worker-1',
|
|
1897
|
+
worker_index: 1,
|
|
1898
|
+
pane_id: '%42',
|
|
1899
|
+
trigger_message: 'do not retarget this request',
|
|
1900
|
+
}, cwd);
|
|
1901
|
+
const modulePath = new URL('../../../dist/scripts/notify-hook/team-dispatch.js', import.meta.url).pathname;
|
|
1902
|
+
const mod = await import(pathToFileURL(modulePath).href);
|
|
1903
|
+
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
1904
|
+
assert.equal(result.failed, 1, `${name} proof should fail the request`);
|
|
1905
|
+
const request = await readDispatchRequest('alpha', queued.request.request_id, cwd);
|
|
1906
|
+
assert.equal(request?.status, 'failed');
|
|
1907
|
+
assert.equal(request?.last_reason, 'exact_pane_unavailable');
|
|
1908
|
+
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
1909
|
+
const commands = tmuxLog.trim().split('\n').filter(Boolean);
|
|
1910
|
+
assert.match(commands[0] || '', /^list-panes -a(?:\s|$)/, `${name} must prove the global pane first`);
|
|
1911
|
+
assert.doesNotMatch(tmuxLog, /display-message|capture-pane|send-keys|paste-buffer/);
|
|
1912
|
+
assert.doesNotMatch(tmuxLog, /list-panes -t /, `${name} must not use the session resolver fallback`);
|
|
1913
|
+
const dispatchLogPath = join(cwd, '.omx', 'logs', `team-dispatch-${new Date().toISOString().slice(0, 10)}.jsonl`);
|
|
1914
|
+
const dispatchLog = (await readFile(dispatchLogPath, 'utf8')).trim().split('\n').filter(Boolean).map((line) => JSON.parse(line));
|
|
1915
|
+
const failure = dispatchLog.find((entry) => entry.request_id === queued.request.request_id && entry.type === 'dispatch_failed');
|
|
1916
|
+
assert.equal(failure?.exact_pane_proof?.status, name === 'unavailable' ? 'unavailable' : 'gone');
|
|
1917
|
+
}
|
|
1918
|
+
finally {
|
|
1919
|
+
if (typeof previousPath === 'string')
|
|
1920
|
+
process.env.PATH = previousPath;
|
|
1921
|
+
else
|
|
1922
|
+
delete process.env.PATH;
|
|
1923
|
+
delete process.env.OMX_TEST_EXACT_PANE_SEQUENCE_FILE;
|
|
1924
|
+
delete process.env.OMX_TEST_EXACT_PANE_COUNTER_FILE;
|
|
1925
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
});
|
|
1929
|
+
it('rejects a recycled configured worker pane before dispatch effects', async () => {
|
|
1930
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-hook-recycled-worker-pane-'));
|
|
1931
|
+
const fakeBinDir = join(cwd, 'fake-bin');
|
|
1932
|
+
const tmuxLogPath = join(cwd, 'tmux.log');
|
|
1933
|
+
const exactPaneSequencePath = join(cwd, 'exact-pane-sequence.txt');
|
|
1934
|
+
const previousPath = process.env.PATH;
|
|
1935
|
+
try {
|
|
1936
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
1937
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
1938
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
1939
|
+
await writeFile(exactPaneSequencePath, '%42\t0\t4242\n');
|
|
1940
|
+
process.env.PATH = `${fakeBinDir}:${previousPath || ''}`;
|
|
1941
|
+
process.env.OMX_TEST_EXACT_PANE_SEQUENCE_FILE = exactPaneSequencePath;
|
|
1942
|
+
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
1943
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
1944
|
+
assert.ok(config?.workers[0]);
|
|
1945
|
+
if (!config?.workers[0])
|
|
1946
|
+
return;
|
|
1947
|
+
config.workers[0].pane_id = '%42';
|
|
1948
|
+
config.workers[0].pid = 1111;
|
|
1949
|
+
bindCanonicalTeamPaneAuthority(config);
|
|
1950
|
+
await saveTeamConfig(config, cwd);
|
|
1951
|
+
const queued = await enqueueDispatchRequest('alpha', {
|
|
1952
|
+
kind: 'inbox',
|
|
1953
|
+
to_worker: 'worker-1',
|
|
1954
|
+
worker_index: 1,
|
|
1955
|
+
pane_id: '%42',
|
|
1956
|
+
trigger_message: 'must not reach recycled pane',
|
|
1957
|
+
}, cwd);
|
|
1958
|
+
const modulePath = new URL('../../../dist/scripts/notify-hook/team-dispatch.js', import.meta.url).pathname;
|
|
1959
|
+
const mod = await import(pathToFileURL(modulePath).href);
|
|
1960
|
+
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
1961
|
+
assert.equal(result.failed, 1);
|
|
1962
|
+
const request = await readDispatchRequest('alpha', queued.request.request_id, cwd);
|
|
1963
|
+
assert.equal(request?.status, 'failed');
|
|
1964
|
+
assert.equal(request?.last_reason, 'exact_pane_unavailable');
|
|
1965
|
+
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
1966
|
+
assert.doesNotMatch(tmuxLog, /display-message|capture-pane|send-keys|paste-buffer|set-buffer/);
|
|
1967
|
+
const dispatchLogPath = join(cwd, '.omx', 'logs', `team-dispatch-${new Date().toISOString().slice(0, 10)}.jsonl`);
|
|
1968
|
+
const dispatchLog = (await readFile(dispatchLogPath, 'utf8')).trim().split('\n').filter(Boolean).map((line) => JSON.parse(line));
|
|
1969
|
+
const failure = dispatchLog.find((entry) => entry.request_id === queued.request.request_id && entry.type === 'dispatch_failed');
|
|
1970
|
+
assert.equal(failure?.exact_pane_proof?.reason, 'pane_pid_changed');
|
|
1971
|
+
assert.equal(failure?.exact_pane_proof?.expectedPid, 1111);
|
|
1551
1972
|
}
|
|
1552
1973
|
finally {
|
|
1974
|
+
if (typeof previousPath === 'string')
|
|
1975
|
+
process.env.PATH = previousPath;
|
|
1976
|
+
else
|
|
1977
|
+
delete process.env.PATH;
|
|
1978
|
+
delete process.env.OMX_TEST_EXACT_PANE_SEQUENCE_FILE;
|
|
1979
|
+
delete process.env.OMX_TEST_EXACT_PANE_COUNTER_FILE;
|
|
1980
|
+
await rm(cwd, { recursive: true, force: true });
|
|
1981
|
+
}
|
|
1982
|
+
});
|
|
1983
|
+
it('stops explicit-pane dispatch after a later exact proof is lost', async () => {
|
|
1984
|
+
const cwd = await mkdtemp(join(tmpdir(), 'omx-hook-exact-pane-loss-'));
|
|
1985
|
+
const fakeBinDir = join(cwd, 'fake-bin');
|
|
1986
|
+
const tmuxLogPath = join(cwd, 'tmux.log');
|
|
1987
|
+
const exactPaneSequencePath = join(cwd, 'exact-pane-sequence.txt');
|
|
1988
|
+
const previousPath = process.env.PATH;
|
|
1989
|
+
try {
|
|
1990
|
+
await mkdir(fakeBinDir, { recursive: true });
|
|
1991
|
+
await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(tmuxLogPath));
|
|
1992
|
+
await chmod(join(fakeBinDir, 'tmux'), 0o755);
|
|
1993
|
+
await writeFile(exactPaneSequencePath, [
|
|
1994
|
+
'%42\t0\t4242', // readiness mode: initial PID proof
|
|
1995
|
+
'%42\t0\t4242', // readiness mode: final PID proof after owner read
|
|
1996
|
+
'%42\t0\t4242', // readiness start-command: initial PID proof
|
|
1997
|
+
'%42\t0\t4242', // readiness start-command: final PID proof after owner read
|
|
1998
|
+
'%42\t0\t4242', // readiness current-command: initial PID proof
|
|
1999
|
+
'%42\t0\t4242', // readiness current-command: final PID proof after owner read
|
|
2000
|
+
'%42\t0\t4242', // readiness capture: initial PID proof
|
|
2001
|
+
'%42\t0\t4242', // readiness capture: final PID proof after owner read
|
|
2002
|
+
'%42\t0\t4242', // readiness capture: initial PID proof
|
|
2003
|
+
'%42\t0\t4242', // readiness capture: final PID proof after owner read
|
|
2004
|
+
'%42\t0\t4242', // readiness capture: initial PID proof
|
|
2005
|
+
'%42\t0\t4242', // readiness capture: final PID proof after owner read
|
|
2006
|
+
'%42\t0\t4242', // send: initial identity proof before HUD guard
|
|
2007
|
+
'%42\t0\t4242', // send: final identity proof before HUD guard
|
|
2008
|
+
'%42\t0\t4242', // send: final identity proof after HUD guard
|
|
2009
|
+
'%42\t0\t4242', // send: initial proof before buffer setup
|
|
2010
|
+
'%42\t0\t4242', // send: final proof after HUD guard
|
|
2011
|
+
'%42\t0\t4242', // clear composer: initial PID proof before owner read
|
|
2012
|
+
'%42\t0\t4242', // clear composer: final PID proof after owner read
|
|
2013
|
+
'%42\t0\t4242', // clear composer: final PID proof after owner read
|
|
2014
|
+
'%42\t0\t4242', // paste buffer: initial PID proof before owner read
|
|
2015
|
+
'%42\t0\t4242', // paste buffer: final PID proof after owner read
|
|
2016
|
+
'%42\t0\t4242', // paste buffer verification: initial PID proof
|
|
2017
|
+
'%42\t0\t4242', // paste buffer verification: final PID proof after owner read
|
|
2018
|
+
'%42\t1\t4242', // paste buffer: final PID proof must block
|
|
2019
|
+
].join('\n'));
|
|
2020
|
+
process.env.PATH = `${fakeBinDir}:${previousPath || ''}`;
|
|
2021
|
+
process.env.OMX_TEST_EXACT_PANE_SEQUENCE_FILE = exactPaneSequencePath;
|
|
2022
|
+
await initTeamState('alpha', 'task', 'executor', 1, cwd);
|
|
2023
|
+
const config = await readTeamConfig('alpha', cwd);
|
|
2024
|
+
assert.ok(config?.workers[0]);
|
|
2025
|
+
if (!config?.workers[0])
|
|
2026
|
+
throw new Error('missing worker');
|
|
2027
|
+
config.workers[0].pane_id = '%42';
|
|
2028
|
+
config.workers[0].pid = 4242;
|
|
2029
|
+
bindCanonicalTeamPaneAuthority(config);
|
|
2030
|
+
await saveTeamConfig(config, cwd);
|
|
2031
|
+
const queued = await enqueueDispatchRequest('alpha', {
|
|
2032
|
+
kind: 'inbox',
|
|
2033
|
+
to_worker: 'worker-1',
|
|
2034
|
+
worker_index: 1,
|
|
2035
|
+
pane_id: '%42',
|
|
2036
|
+
trigger_message: 'stop after proof loss',
|
|
2037
|
+
}, cwd);
|
|
2038
|
+
const modulePath = new URL('../../../dist/scripts/notify-hook/team-dispatch.js', import.meta.url).pathname;
|
|
2039
|
+
const mod = await import(pathToFileURL(modulePath).href);
|
|
2040
|
+
const result = await mod.drainPendingTeamDispatch({ cwd, maxPerTick: 5 });
|
|
2041
|
+
assert.equal(result.failed, 1);
|
|
2042
|
+
const request = await readDispatchRequest('alpha', queued.request.request_id, cwd);
|
|
2043
|
+
assert.equal(request?.status, 'failed');
|
|
2044
|
+
assert.equal(request?.last_reason, 'exact_pane_unavailable');
|
|
2045
|
+
const tmuxLog = await readFile(tmuxLogPath, 'utf8');
|
|
2046
|
+
const commands = tmuxLog.trim().split('\n').filter(Boolean);
|
|
2047
|
+
const exactGlobalPaneProof = /^list-panes -a -F #\{pane_id\}\t#\{pane_dead\}\t#\{pane_pid\}$/;
|
|
2048
|
+
assert.match(commands[0] || '', exactGlobalPaneProof);
|
|
2049
|
+
assert.match(tmuxLog, /send-keys -t %42 C-u/, 'the live proof should permit the clear effect');
|
|
2050
|
+
assert.doesNotMatch(tmuxLog, /send-keys -t %42 C-m/);
|
|
2051
|
+
const ownerProof = 'show-option -qv -p -t %42 @omx_team_pane_owner_id';
|
|
2052
|
+
for (const [index, command] of commands.entries()) {
|
|
2053
|
+
if (!/^(send-keys|paste-buffer)\b/.test(command) || !command.includes('-t %42') || /^send-keys\b.*\s-l\s/.test(command))
|
|
2054
|
+
continue;
|
|
2055
|
+
assert.match(commands[index - 1] || '', exactGlobalPaneProof, `final PID proof must immediately precede ${command}`);
|
|
2056
|
+
assert.equal(commands[index - 2], ownerProof, `owner proof must precede final PID proof for ${command}`);
|
|
2057
|
+
assert.match(commands[index - 3] || '', exactGlobalPaneProof, `initial PID proof must precede owner proof for ${command}`);
|
|
2058
|
+
}
|
|
2059
|
+
const lastProof = commands.map((command, index) => exactGlobalPaneProof.test(command) ? index : -1).filter((index) => index >= 0).at(-1);
|
|
2060
|
+
assert.notEqual(lastProof, undefined);
|
|
2061
|
+
const commandsAfterLostProof = commands.slice((lastProof || 0) + 1);
|
|
2062
|
+
assert.equal(commandsAfterLostProof.length, 1, 'only non-pane buffer cleanup may follow proof loss');
|
|
2063
|
+
assert.match(commandsAfterLostProof[0] || '', /^delete-buffer -b /);
|
|
2064
|
+
}
|
|
2065
|
+
finally {
|
|
2066
|
+
if (typeof previousPath === 'string')
|
|
2067
|
+
process.env.PATH = previousPath;
|
|
2068
|
+
else
|
|
2069
|
+
delete process.env.PATH;
|
|
2070
|
+
delete process.env.OMX_TEST_EXACT_PANE_SEQUENCE_FILE;
|
|
2071
|
+
delete process.env.OMX_TEST_EXACT_PANE_COUNTER_FILE;
|
|
1553
2072
|
await rm(cwd, { recursive: true, force: true });
|
|
1554
2073
|
}
|
|
1555
2074
|
});
|