oh-my-codex 0.20.3 → 0.21.0
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 +35 -18
- package/Cargo.toml +1 -1
- package/README.md +22 -19
- package/crates/omx-runtime/Cargo.toml +3 -0
- package/crates/omx-runtime/src/main.rs +390 -0
- package/crates/omx-runtime/tests/execution.rs +264 -0
- package/dist/adapt/__tests__/herdr-target.test.d.ts +2 -0
- package/dist/adapt/__tests__/herdr-target.test.d.ts.map +1 -0
- package/dist/adapt/__tests__/herdr-target.test.js +72 -0
- package/dist/adapt/__tests__/herdr-target.test.js.map +1 -0
- package/dist/adapt/contracts.d.ts +1 -1
- package/dist/adapt/contracts.d.ts.map +1 -1
- package/dist/adapt/contracts.js +1 -1
- package/dist/adapt/contracts.js.map +1 -1
- package/dist/adapt/herdr/__tests__/authority.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/authority.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/authority.test.js +49 -0
- package/dist/adapt/herdr/__tests__/authority.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/bridge.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/bridge.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/bridge.test.js +176 -0
- package/dist/adapt/herdr/__tests__/bridge.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.js +45 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/semantic.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/semantic.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/semantic.test.js +130 -0
- package/dist/adapt/herdr/__tests__/semantic.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.js +54 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.js +104 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/team-map.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/team-map.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/team-map.test.js +46 -0
- package/dist/adapt/herdr/__tests__/team-map.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/transport.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/transport.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/transport.test.js +160 -0
- package/dist/adapt/herdr/__tests__/transport.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/wiring.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/wiring.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/wiring.test.js +118 -0
- package/dist/adapt/herdr/__tests__/wiring.test.js.map +1 -0
- package/dist/adapt/herdr/authority.d.ts +34 -0
- package/dist/adapt/herdr/authority.d.ts.map +1 -0
- package/dist/adapt/herdr/authority.js +71 -0
- package/dist/adapt/herdr/authority.js.map +1 -0
- package/dist/adapt/herdr/bridge.d.ts +84 -0
- package/dist/adapt/herdr/bridge.d.ts.map +1 -0
- package/dist/adapt/herdr/bridge.js +222 -0
- package/dist/adapt/herdr/bridge.js.map +1 -0
- package/dist/adapt/herdr/sanitize.d.ts +20 -0
- package/dist/adapt/herdr/sanitize.d.ts.map +1 -0
- package/dist/adapt/herdr/sanitize.js +70 -0
- package/dist/adapt/herdr/sanitize.js.map +1 -0
- package/dist/adapt/herdr/semantic.d.ts +67 -0
- package/dist/adapt/herdr/semantic.d.ts.map +1 -0
- package/dist/adapt/herdr/semantic.js +170 -0
- package/dist/adapt/herdr/semantic.js.map +1 -0
- package/dist/adapt/herdr/seq-store.d.ts +32 -0
- package/dist/adapt/herdr/seq-store.d.ts.map +1 -0
- package/dist/adapt/herdr/seq-store.js +126 -0
- package/dist/adapt/herdr/seq-store.js.map +1 -0
- package/dist/adapt/herdr/team-map.d.ts +30 -0
- package/dist/adapt/herdr/team-map.d.ts.map +1 -0
- package/dist/adapt/herdr/team-map.js +37 -0
- package/dist/adapt/herdr/team-map.js.map +1 -0
- package/dist/adapt/herdr/transport.d.ts +115 -0
- package/dist/adapt/herdr/transport.d.ts.map +1 -0
- package/dist/adapt/herdr/transport.js +260 -0
- package/dist/adapt/herdr/transport.js.map +1 -0
- package/dist/adapt/herdr/wiring.d.ts +24 -0
- package/dist/adapt/herdr/wiring.d.ts.map +1 -0
- package/dist/adapt/herdr/wiring.js +62 -0
- package/dist/adapt/herdr/wiring.js.map +1 -0
- package/dist/adapt/herdr.d.ts +19 -0
- package/dist/adapt/herdr.d.ts.map +1 -0
- package/dist/adapt/herdr.js +115 -0
- package/dist/adapt/herdr.js.map +1 -0
- package/dist/adapt/index.d.ts +4 -0
- package/dist/adapt/index.d.ts.map +1 -1
- package/dist/adapt/index.js +48 -0
- package/dist/adapt/index.js.map +1 -1
- package/dist/adapt/registry.d.ts.map +1 -1
- package/dist/adapt/registry.js +11 -0
- package/dist/adapt/registry.js.map +1 -1
- package/dist/agents/__tests__/definitions.test.js +0 -27
- package/dist/agents/__tests__/definitions.test.js.map +1 -1
- package/dist/agents/__tests__/native-config.test.js +3 -8
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +0 -41
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/policy.d.ts.map +1 -1
- package/dist/agents/policy.js +0 -1
- package/dist/agents/policy.js.map +1 -1
- package/dist/auth/__tests__/hotswap.test.js +60 -1
- package/dist/auth/__tests__/hotswap.test.js.map +1 -1
- package/dist/auth/__tests__/storage.test.js +33 -1
- package/dist/auth/__tests__/storage.test.js.map +1 -1
- package/dist/auth/hotswap.d.ts +16 -2
- package/dist/auth/hotswap.d.ts.map +1 -1
- package/dist/auth/hotswap.js +22 -7
- package/dist/auth/hotswap.js.map +1 -1
- package/dist/auth/storage.js +1 -1
- package/dist/auth/storage.js.map +1 -1
- package/dist/autopilot/__tests__/completion-gate-advisory.test.d.ts +2 -0
- package/dist/autopilot/__tests__/completion-gate-advisory.test.d.ts.map +1 -0
- package/dist/autopilot/__tests__/completion-gate-advisory.test.js +383 -0
- package/dist/autopilot/__tests__/completion-gate-advisory.test.js.map +1 -0
- package/dist/autopilot/completion-gate.d.ts +6 -1
- package/dist/autopilot/completion-gate.d.ts.map +1 -1
- package/dist/autopilot/completion-gate.js +247 -7
- package/dist/autopilot/completion-gate.js.map +1 -1
- package/dist/catalog/__tests__/generator.test.js +15 -10
- package/dist/catalog/__tests__/generator.test.js.map +1 -1
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +13 -7
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +1 -1
- package/dist/catalog/__tests__/schema.test.js +3 -5
- package/dist/catalog/__tests__/schema.test.js.map +1 -1
- package/dist/catalog/schema.js +1 -1
- package/dist/catalog/schema.js.map +1 -1
- package/dist/cli/__tests__/agents-init.test.js +4 -23
- package/dist/cli/__tests__/agents-init.test.js.map +1 -1
- package/dist/cli/__tests__/api.test.js +61 -24
- package/dist/cli/__tests__/api.test.js.map +1 -1
- package/dist/cli/__tests__/auth.test.js +3 -1
- package/dist/cli/__tests__/auth.test.js.map +1 -1
- package/dist/cli/__tests__/autopilot.test.d.ts +2 -0
- package/dist/cli/__tests__/autopilot.test.d.ts.map +1 -0
- package/dist/cli/__tests__/autopilot.test.js +143 -0
- package/dist/cli/__tests__/autopilot.test.js.map +1 -0
- package/dist/cli/__tests__/codex-feature-probe.test.js +66 -1
- package/dist/cli/__tests__/codex-feature-probe.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +76 -4
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/detached-leader-teardown.test.d.ts +2 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.d.ts.map +1 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.js +473 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts +2 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts.map +1 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.js +103 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts +2 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts.map +1 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.js +206 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-team.test.js +85 -0
- package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +38 -6
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +75 -0
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +621 -460
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +1125 -143
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-parity.test.js +4 -3
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/native-assets.test.js +398 -16
- package/dist/cli/__tests__/native-assets.test.js.map +1 -1
- package/dist/cli/__tests__/native-hook-claim-journal.test.js +53 -5
- package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +5 -8
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-deslop-contract.test.js +4 -18
- package/dist/cli/__tests__/ralph-deslop-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +4 -30
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +4 -15
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +1 -1
- package/dist/cli/__tests__/ralph.test.js +2 -2
- package/dist/cli/__tests__/ralph.test.js.map +1 -1
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +57 -57
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -1
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts +2 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.js +56 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.js.map +1 -0
- package/dist/cli/__tests__/ralplan.test.js +131 -14
- package/dist/cli/__tests__/ralplan.test.js.map +1 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.js +1153 -43
- package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
- package/dist/cli/__tests__/session-search-help.test.js +65 -3
- package/dist/cli/__tests__/session-search-help.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +57 -55
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +34 -0
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js +1 -1
- package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +258 -26
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js +1 -1
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +3 -6
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +180 -21
- package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js +93 -41
- package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +45 -1
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +161 -2
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +73 -28
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/update.test.js +749 -177
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +32 -2
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
- package/dist/cli/api.d.ts.map +1 -1
- package/dist/cli/api.js +9 -10
- package/dist/cli/api.js.map +1 -1
- package/dist/cli/autopilot.d.ts +8 -0
- package/dist/cli/autopilot.d.ts.map +1 -0
- package/dist/cli/autopilot.js +160 -0
- package/dist/cli/autopilot.js.map +1 -0
- package/dist/cli/codex-feature-probe.d.ts +16 -0
- package/dist/cli/codex-feature-probe.d.ts.map +1 -1
- package/dist/cli/codex-feature-probe.js +44 -0
- package/dist/cli/codex-feature-probe.js.map +1 -1
- package/dist/cli/codex-home.d.ts.map +1 -1
- package/dist/cli/codex-home.js +7 -4
- package/dist/cli/codex-home.js.map +1 -1
- package/dist/cli/doctor.d.ts +29 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +433 -19
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +231 -12
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2354 -724
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-parity.d.ts.map +1 -1
- package/dist/cli/mcp-parity.js +7 -3
- package/dist/cli/mcp-parity.js.map +1 -1
- package/dist/cli/native-assets.d.ts +26 -1
- package/dist/cli/native-assets.d.ts.map +1 -1
- package/dist/cli/native-assets.js +448 -51
- package/dist/cli/native-assets.js.map +1 -1
- package/dist/cli/native-hook-claim-journal.d.ts +8 -4
- package/dist/cli/native-hook-claim-journal.d.ts.map +1 -1
- package/dist/cli/native-hook-claim-journal.js +30 -8
- package/dist/cli/native-hook-claim-journal.js.map +1 -1
- package/dist/cli/package-manager-ownership.d.ts +69 -0
- package/dist/cli/package-manager-ownership.d.ts.map +1 -0
- package/dist/cli/package-manager-ownership.js +338 -0
- package/dist/cli/package-manager-ownership.js.map +1 -0
- package/dist/cli/plugin-marketplace.d.ts +1 -0
- package/dist/cli/plugin-marketplace.d.ts.map +1 -1
- package/dist/cli/plugin-marketplace.js +123 -55
- package/dist/cli/plugin-marketplace.js.map +1 -1
- package/dist/cli/ralph.js +2 -2
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/ralplan.d.ts +6 -2
- package/dist/cli/ralplan.d.ts.map +1 -1
- package/dist/cli/ralplan.js +134 -34
- package/dist/cli/ralplan.js.map +1 -1
- package/dist/cli/session-search.d.ts.map +1 -1
- package/dist/cli/session-search.js +38 -1
- package/dist/cli/session-search.js.map +1 -1
- package/dist/cli/setup-preferences.d.ts +15 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -1
- package/dist/cli/setup-preferences.js +27 -1
- package/dist/cli/setup-preferences.js.map +1 -1
- package/dist/cli/setup.d.ts +6 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +425 -215
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/sparkshell.d.ts.map +1 -1
- package/dist/cli/sparkshell.js +52 -9
- package/dist/cli/sparkshell.js.map +1 -1
- package/dist/cli/ultragoal.d.ts +1 -1
- package/dist/cli/ultragoal.d.ts.map +1 -1
- package/dist/cli/ultragoal.js +10 -7
- package/dist/cli/ultragoal.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +27 -28
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update-worker.d.ts +2 -0
- package/dist/cli/update-worker.d.ts.map +1 -0
- package/dist/cli/update-worker.js +142 -0
- package/dist/cli/update-worker.js.map +1 -0
- package/dist/cli/update.d.ts +16 -23
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +212 -241
- package/dist/cli/update.js.map +1 -1
- package/dist/compat/__tests__/upgrade-from-0-20.test.d.ts +2 -0
- package/dist/compat/__tests__/upgrade-from-0-20.test.d.ts.map +1 -0
- package/dist/compat/__tests__/upgrade-from-0-20.test.js +109 -0
- package/dist/compat/__tests__/upgrade-from-0-20.test.js.map +1 -0
- package/dist/compat/upgrade-from-0-20.d.ts +64 -0
- package/dist/compat/upgrade-from-0-20.d.ts.map +1 -0
- package/dist/compat/upgrade-from-0-20.js +276 -0
- package/dist/compat/upgrade-from-0-20.js.map +1 -0
- package/dist/config/__tests__/generator-idempotent.test.js +173 -29
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +3 -1
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/generator.d.ts +25 -3
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +113 -35
- package/dist/config/generator.js.map +1 -1
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +25 -0
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.d.ts +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.js +2 -0
- package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +3 -1
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/analyze-skill-contract.test.js +24 -31
- package/dist/hooks/__tests__/analyze-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/anti-slop-workflow.test.js +66 -135
- package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +47 -106
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/code-review-skill-contract.test.js +16 -18
- package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +2 -14
- package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts.map +1 -1
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js +56 -234
- package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.js +1 -3
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/design-skill.test.js +18 -16
- package/dist/hooks/__tests__/design-skill.test.js.map +1 -1
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js +24 -20
- package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts +2 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js +164 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js.map +1 -0
- package/dist/hooks/__tests__/issue-3497-hook-simplification.test.d.ts +2 -0
- package/dist/hooks/__tests__/issue-3497-hook-simplification.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/issue-3497-hook-simplification.test.js +169 -0
- package/dist/hooks/__tests__/issue-3497-hook-simplification.test.js.map +1 -0
- package/dist/hooks/__tests__/keyword-detector.test.js +226 -858
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +176 -14
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +1 -0
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +33 -21
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +27 -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 +10 -118
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +14 -904
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +7 -0
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +5 -5
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +7 -7
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +11 -8
- 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 +7 -6
- 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.js +2 -1
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +1 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js +19 -21
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js +23 -3
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +23 -28
- package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
- package/dist/hooks/__tests__/research-workflow-boundaries.test.js +9 -8
- package/dist/hooks/__tests__/research-workflow-boundaries.test.js.map +1 -1
- package/dist/hooks/__tests__/session.test.js +3656 -656
- package/dist/hooks/__tests__/session.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.js +13 -22
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-guidance-contract.test.js +3 -13
- package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/sunset-routing-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/sunset-routing-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/sunset-routing-contract.test.js +172 -0
- package/dist/hooks/__tests__/sunset-routing-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js +2 -2
- package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.js +18 -3
- package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-ralph-skill.test.js +20 -17
- package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-verdict-loop.test.js +17 -18
- package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +1 -1
- package/dist/hooks/agents-overlay.js +1 -1
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js +108 -2
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.js +151 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js +20 -3
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/extensibility/plugin-runner.js +1 -0
- package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
- package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
- package/dist/hooks/extensibility/runtime.js.map +1 -1
- package/dist/hooks/extensibility/sdk/paths.d.ts +1 -1
- package/dist/hooks/extensibility/sdk/paths.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/paths.js +2 -2
- package/dist/hooks/extensibility/sdk/paths.js.map +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.d.ts +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.js +55 -15
- package/dist/hooks/extensibility/sdk/runtime-state.js.map +1 -1
- package/dist/hooks/extensibility/sdk.d.ts +1 -0
- package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk.js +1 -1
- package/dist/hooks/extensibility/sdk.js.map +1 -1
- package/dist/hooks/extensibility/types.d.ts +7 -0
- package/dist/hooks/extensibility/types.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +6 -47
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +156 -268
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +14 -26
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hooks/native/capability-warnings.d.ts +16 -0
- package/dist/hooks/native/capability-warnings.d.ts.map +1 -0
- package/dist/hooks/native/capability-warnings.js +40 -0
- package/dist/hooks/native/capability-warnings.js.map +1 -0
- package/dist/hooks/native/index.d.ts +17 -0
- package/dist/hooks/native/index.d.ts.map +1 -0
- package/dist/hooks/native/index.js +17 -0
- package/dist/hooks/native/index.js.map +1 -0
- package/dist/hooks/native/pre-tool-use-advisory.d.ts +17 -0
- package/dist/hooks/native/pre-tool-use-advisory.d.ts.map +1 -0
- package/dist/hooks/native/pre-tool-use-advisory.js +112 -0
- package/dist/hooks/native/pre-tool-use-advisory.js.map +1 -0
- package/dist/hooks/native/types.d.ts +30 -0
- package/dist/hooks/native/types.d.ts.map +1 -0
- package/dist/hooks/native/types.js +22 -0
- package/dist/hooks/native/types.js.map +1 -0
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +46 -93
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hooks/session.d.ts +197 -18
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +1939 -271
- package/dist/hooks/session.js.map +1 -1
- package/dist/hooks/sunset-stub.d.ts +17 -0
- package/dist/hooks/sunset-stub.d.ts.map +1 -0
- package/dist/hooks/sunset-stub.js +125 -0
- package/dist/hooks/sunset-stub.js.map +1 -0
- package/dist/hud/__tests__/hud-tmux-injection.test.js +6 -6
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
- package/dist/hud/__tests__/index.test.js +26 -16
- package/dist/hud/__tests__/index.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +83 -78
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +36 -31
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/tmux-split-realtmux.test.d.ts +2 -0
- package/dist/hud/__tests__/tmux-split-realtmux.test.d.ts.map +1 -0
- package/dist/hud/__tests__/tmux-split-realtmux.test.js +112 -0
- package/dist/hud/__tests__/tmux-split-realtmux.test.js.map +1 -0
- package/dist/hud/__tests__/tmux.test.js +217 -198
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/tmux.d.ts +43 -4
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +1025 -139
- package/dist/hud/tmux.js.map +1 -1
- package/dist/leader/__tests__/contract.test.js +71 -34
- package/dist/leader/__tests__/contract.test.js.map +1 -1
- package/dist/leader/contract.d.ts +1 -6
- package/dist/leader/contract.d.ts.map +1 -1
- package/dist/leader/contract.js +25 -24
- package/dist/leader/contract.js.map +1 -1
- package/dist/mcp/__tests__/hermes-bridge.test.js +17 -0
- package/dist/mcp/__tests__/hermes-bridge.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +4 -4
- package/dist/mcp/__tests__/state-paths.test.js +735 -4
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server-ralph-phase.test.js +29 -4
- package/dist/mcp/__tests__/state-server-ralph-phase.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server-schema.test.js +13 -3
- package/dist/mcp/__tests__/state-server-schema.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server.test.js +11 -1033
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/__tests__/trace-server.test.js +2 -2
- package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
- package/dist/mcp/hermes-bridge.d.ts.map +1 -1
- package/dist/mcp/hermes-bridge.js +2 -2
- package/dist/mcp/hermes-bridge.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +78 -4
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +543 -40
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts +68 -97
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +116 -67
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/modes/__tests__/base-autopilot-gates.test.js +1 -168
- package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -1
- package/dist/modes/__tests__/base-autoresearch-contract.test.js +1 -85
- package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +1 -1
- package/dist/modes/__tests__/base-multi-state-compat.test.js +1 -35
- package/dist/modes/__tests__/base-multi-state-compat.test.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +10 -158
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/base.d.ts +6 -6
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +116 -90
- package/dist/modes/base.js.map +1 -1
- package/dist/native-assets/archive.d.ts +17 -0
- package/dist/native-assets/archive.d.ts.map +1 -0
- package/dist/native-assets/archive.js +238 -0
- package/dist/native-assets/archive.js.map +1 -0
- package/dist/native-assets/policy.d.ts +42 -0
- package/dist/native-assets/policy.d.ts.map +1 -0
- package/dist/native-assets/policy.js +155 -0
- package/dist/native-assets/policy.js.map +1 -0
- package/dist/notifications/__tests__/formatter.test.js +8 -0
- package/dist/notifications/__tests__/formatter.test.js.map +1 -1
- package/dist/notifications/__tests__/template-engine.test.js +8 -0
- package/dist/notifications/__tests__/template-engine.test.js.map +1 -1
- package/dist/notifications/formatter.js +1 -1
- package/dist/notifications/formatter.js.map +1 -1
- package/dist/notifications/template-engine.js +1 -1
- package/dist/notifications/template-engine.js.map +1 -1
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js +0 -21
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js.map +1 -1
- package/dist/question/autopilot-wait.d.ts.map +1 -1
- package/dist/question/autopilot-wait.js +2 -2
- package/dist/question/autopilot-wait.js.map +1 -1
- package/dist/question/deep-interview.d.ts +1 -2
- package/dist/question/deep-interview.d.ts.map +1 -1
- package/dist/question/deep-interview.js +4 -4
- package/dist/question/deep-interview.js.map +1 -1
- package/dist/ralplan/__tests__/documented-leader-preflight.test.js +328 -39
- package/dist/ralplan/__tests__/documented-leader-preflight.test.js.map +1 -1
- package/dist/ralplan/__tests__/runtime.test.js +56 -821
- package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
- package/dist/ralplan/documented-leader-preflight.d.ts +15 -8
- package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -1
- package/dist/ralplan/documented-leader-preflight.js +356 -54
- package/dist/ralplan/documented-leader-preflight.js.map +1 -1
- package/dist/ralplan/runtime.d.ts +2 -2
- package/dist/ralplan/runtime.d.ts.map +1 -1
- package/dist/ralplan/runtime.js +145 -163
- package/dist/ralplan/runtime.js.map +1 -1
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +45 -0
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/runtime/run-state.d.ts +5 -1
- package/dist/runtime/run-state.d.ts.map +1 -1
- package/dist/runtime/run-state.js +15 -8
- package/dist/runtime/run-state.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +12490 -19414
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/docs-site-contract.test.js +2 -2
- package/dist/scripts/__tests__/docs-site-contract.test.js.map +1 -1
- package/dist/scripts/__tests__/generated-artifact-drift.test.d.ts +2 -0
- package/dist/scripts/__tests__/generated-artifact-drift.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/generated-artifact-drift.test.js +84 -0
- package/dist/scripts/__tests__/generated-artifact-drift.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js +235 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js +188 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js +207 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js +156 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js +191 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js +40 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.js +63 -0
- package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.js +65 -0
- package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.js +189 -0
- package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.js.map +1 -0
- package/dist/scripts/__tests__/notify-state-io.test.js +26 -0
- package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-tmux-injection.test.js +23 -1
- package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -1
- package/dist/scripts/__tests__/postinstall.test.js +19 -1
- package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
- package/dist/scripts/__tests__/prompt-inventory.test.js +54 -1
- package/dist/scripts/__tests__/prompt-inventory.test.js.map +1 -1
- package/dist/scripts/__tests__/reasoning-artifact-contract.test.js +2 -2
- package/dist/scripts/__tests__/reasoning-artifact-contract.test.js.map +1 -1
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +46 -60
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -1
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +60 -25
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js +168 -20
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts +2 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.js +235 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts +51 -2
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +3648 -1332
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts +9 -0
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +33 -22
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/generate-native-release-manifest.js +80 -51
- package/dist/scripts/generate-native-release-manifest.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +28 -39
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts +2 -48
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +1 -0
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +5 -0
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +8 -5
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +32 -3
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +3 -2
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.js +23 -3
- package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +45 -5
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -0
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +4 -1
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.d.ts.map +1 -1
- package/dist/scripts/notify-hook.js +71 -124
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/postinstall-advisory.d.ts +14 -0
- package/dist/scripts/postinstall-advisory.d.ts.map +1 -0
- package/dist/scripts/postinstall-advisory.js +49 -0
- package/dist/scripts/postinstall-advisory.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +1 -1
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +1 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/scripts/prompt-inventory.d.ts +39 -0
- package/dist/scripts/prompt-inventory.d.ts.map +1 -1
- package/dist/scripts/prompt-inventory.js +108 -3
- package/dist/scripts/prompt-inventory.js.map +1 -1
- package/dist/scripts/run-compiled-ci.js +2 -0
- package/dist/scripts/run-compiled-ci.js.map +1 -1
- package/dist/scripts/run-test-files.js +1 -0
- package/dist/scripts/run-test-files.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +32 -1
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +407 -60
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
- package/dist/scripts/sync-plugin-mirror.js +16 -1
- package/dist/scripts/sync-plugin-mirror.js.map +1 -1
- package/dist/scripts/sync-prompt-guidance-fragments.js +62 -20
- package/dist/scripts/sync-prompt-guidance-fragments.js.map +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
- package/dist/scripts/tmux-hook-engine.js +3 -3
- package/dist/scripts/tmux-hook-engine.js.map +1 -1
- package/dist/scripts/verify-capabilities-lock.d.ts +3 -0
- package/dist/scripts/verify-capabilities-lock.d.ts.map +1 -0
- package/dist/scripts/verify-capabilities-lock.js +22 -0
- package/dist/scripts/verify-capabilities-lock.js.map +1 -0
- package/dist/scripts/verify-native-release-assets.js +37 -23
- package/dist/scripts/verify-native-release-assets.js.map +1 -1
- package/dist/state/__tests__/authority-decreasing.test.d.ts +2 -0
- package/dist/state/__tests__/authority-decreasing.test.d.ts.map +1 -0
- package/dist/state/__tests__/authority-decreasing.test.js +78 -0
- package/dist/state/__tests__/authority-decreasing.test.js.map +1 -0
- package/dist/state/__tests__/handoff-carrier.test.d.ts +2 -0
- package/dist/state/__tests__/handoff-carrier.test.d.ts.map +1 -0
- package/dist/state/__tests__/handoff-carrier.test.js +96 -0
- package/dist/state/__tests__/handoff-carrier.test.js.map +1 -0
- package/dist/state/__tests__/mode-state-context.test.js +12 -5
- package/dist/state/__tests__/mode-state-context.test.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +870 -2517
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/single-writer-invariant.test.d.ts +2 -0
- package/dist/state/__tests__/single-writer-invariant.test.d.ts.map +1 -0
- package/dist/state/__tests__/single-writer-invariant.test.js +342 -0
- package/dist/state/__tests__/single-writer-invariant.test.js.map +1 -0
- package/dist/state/__tests__/skill-active.test.js +400 -2
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/__tests__/stale-state-neutralization.test.d.ts +2 -0
- package/dist/state/__tests__/stale-state-neutralization.test.d.ts.map +1 -0
- package/dist/state/__tests__/stale-state-neutralization.test.js +84 -0
- package/dist/state/__tests__/stale-state-neutralization.test.js.map +1 -0
- package/dist/state/__tests__/workflow-transition.test.js +20 -33
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/handoff-carrier.d.ts +46 -0
- package/dist/state/handoff-carrier.d.ts.map +1 -0
- package/dist/state/handoff-carrier.js +85 -0
- package/dist/state/handoff-carrier.js.map +1 -0
- package/dist/state/mode-state-context.d.ts +3 -0
- package/dist/state/mode-state-context.d.ts.map +1 -1
- package/dist/state/mode-state-context.js +27 -13
- package/dist/state/mode-state-context.js.map +1 -1
- package/dist/state/namespace-owners.d.ts +34 -0
- package/dist/state/namespace-owners.d.ts.map +1 -0
- package/dist/state/namespace-owners.js +127 -0
- package/dist/state/namespace-owners.js.map +1 -0
- package/dist/state/operations.d.ts +9 -4
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +194 -235
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts +18 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +421 -31
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.d.ts +3 -0
- package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
- package/dist/state/workflow-transition-reconcile.js +11 -31
- package/dist/state/workflow-transition-reconcile.js.map +1 -1
- package/dist/state/workflow-transition.d.ts +1 -27
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +9 -790
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +27 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -1
- package/dist/subagents/__tests__/tracker.test.js +837 -1048
- package/dist/subagents/__tests__/tracker.test.js.map +1 -1
- package/dist/subagents/tracker.d.ts +64 -60
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +809 -358
- package/dist/subagents/tracker.js.map +1 -1
- package/dist/team/__tests__/api-interop.test.js +1 -0
- package/dist/team/__tests__/api-interop.test.js.map +1 -1
- package/dist/team/__tests__/delivery-e2e-smoke.test.js +6 -7
- package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
- package/dist/team/__tests__/mcp-comm.test.js +104 -3
- package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
- package/dist/team/__tests__/notice-ledger.test.d.ts +2 -0
- package/dist/team/__tests__/notice-ledger.test.d.ts.map +1 -0
- package/dist/team/__tests__/notice-ledger.test.js +131 -0
- package/dist/team/__tests__/notice-ledger.test.js.map +1 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts +2 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts.map +1 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.js +410 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.js.map +1 -0
- package/dist/team/__tests__/phase-controller.test.js +20 -0
- package/dist/team/__tests__/phase-controller.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +725 -59
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +269 -245
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +117 -2
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/team-ops-contract.test.js +1 -0
- package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +1093 -101
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts +2 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts.map +1 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.js +159 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.js.map +1 -0
- package/dist/team/__tests__/tmux-test-fixture.d.ts +69 -0
- package/dist/team/__tests__/tmux-test-fixture.d.ts.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.js +242 -15
- package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.test.js +177 -1
- package/dist/team/__tests__/tmux-test-fixture.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +11 -13
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/__tests__/worker-provenance.test.d.ts +2 -0
- package/dist/team/__tests__/worker-provenance.test.d.ts.map +1 -0
- package/dist/team/__tests__/worker-provenance.test.js +251 -0
- package/dist/team/__tests__/worker-provenance.test.js.map +1 -0
- package/dist/team/__tests__/worker-runtime-identity.test.js +45 -72
- package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +14 -8
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/mcp-comm.d.ts.map +1 -1
- package/dist/team/mcp-comm.js +3 -8
- package/dist/team/mcp-comm.js.map +1 -1
- package/dist/team/notice-ledger.d.ts +54 -0
- package/dist/team/notice-ledger.d.ts.map +1 -0
- package/dist/team/notice-ledger.js +259 -0
- package/dist/team/notice-ledger.js.map +1 -0
- package/dist/team/phase-controller.d.ts.map +1 -1
- package/dist/team/phase-controller.js +2 -0
- package/dist/team/phase-controller.js.map +1 -1
- package/dist/team/runtime.d.ts +3 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +314 -142
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +161 -91
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/monitor.d.ts +10 -0
- package/dist/team/state/monitor.d.ts.map +1 -1
- package/dist/team/state/monitor.js +13 -0
- package/dist/team/state/monitor.js.map +1 -1
- package/dist/team/state/types.d.ts +15 -0
- 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 +12 -0
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +177 -0
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts +19 -0
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +47 -1
- package/dist/team/state.js.map +1 -1
- package/dist/team/team-ops.d.ts +1 -0
- package/dist/team/team-ops.d.ts.map +1 -1
- package/dist/team/team-ops.js +1 -0
- package/dist/team/team-ops.js.map +1 -1
- package/dist/team/tmux-session.d.ts +42 -4
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +572 -196
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/ultragoal-context.d.ts +1 -0
- package/dist/team/ultragoal-context.d.ts.map +1 -1
- package/dist/team/ultragoal-context.js +2 -0
- package/dist/team/ultragoal-context.js.map +1 -1
- package/dist/team/worker-provenance.d.ts +35 -0
- package/dist/team/worker-provenance.d.ts.map +1 -0
- package/dist/team/worker-provenance.js +213 -0
- package/dist/team/worker-provenance.js.map +1 -0
- package/dist/ultragoal/__tests__/artifacts.test.js +1053 -2
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/__tests__/docs-contract.test.js +89 -59
- package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts +36 -1
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +267 -51
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/dist/url-reader/__tests__/url-reader.test.js +14 -0
- package/dist/url-reader/__tests__/url-reader.test.js.map +1 -1
- package/dist/url-reader/index.js +5 -3
- package/dist/url-reader/index.js.map +1 -1
- package/dist/utils/__tests__/file-durability.test.js +58 -1
- package/dist/utils/__tests__/file-durability.test.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +21 -1
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/__tests__/version.test.js +17 -0
- package/dist/utils/__tests__/version.test.js.map +1 -1
- package/dist/utils/file-durability.d.ts +10 -0
- package/dist/utils/file-durability.d.ts.map +1 -1
- package/dist/utils/file-durability.js +34 -4
- package/dist/utils/file-durability.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -6
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +2 -1
- package/dist/utils/version.js.map +1 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js +49 -4
- package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js +60 -0
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
- package/dist/verification/__tests__/native-release-manifest.test.js +157 -4
- package/dist/verification/__tests__/native-release-manifest.test.js.map +1 -1
- package/package.json +17 -6
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +81 -17
- package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +60 -135
- package/plugins/oh-my-codex/skills/analyze/SKILL.md +35 -111
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +72 -163
- package/plugins/oh-my-codex/skills/cancel/SKILL.md +33 -392
- package/plugins/oh-my-codex/skills/code-review/SKILL.md +66 -256
- package/plugins/oh-my-codex/skills/configure-notifications/SKILL.md +30 -216
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +11 -10
- package/plugins/oh-my-codex/skills/design/SKILL.md +32 -132
- package/plugins/oh-my-codex/skills/doctor/SKILL.md +56 -177
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +35 -116
- package/plugins/oh-my-codex/skills/plan/SKILL.md +45 -228
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +20 -22
- package/plugins/oh-my-codex/skills/skill/SKILL.md +82 -807
- package/plugins/oh-my-codex/skills/team/SKILL.md +32 -520
- package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +47 -150
- package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +75 -252
- package/plugins/oh-my-codex/skills/visual-ralph/SKILL.md +33 -111
- package/plugins/oh-my-codex/skills/worker/SKILL.md +40 -113
- package/prompts/analyst.md +27 -107
- package/prompts/api-reviewer.md +17 -84
- package/prompts/architect.md +31 -70
- package/prompts/code-reviewer.md +18 -107
- package/prompts/code-simplifier.md +32 -110
- package/prompts/critic.md +32 -54
- package/prompts/dependency-expert.md +37 -107
- package/prompts/designer.md +40 -107
- package/prompts/executor.md +26 -75
- package/prompts/information-architect.md +51 -200
- package/prompts/performance-reviewer.md +17 -81
- package/prompts/planner.md +33 -76
- package/prompts/product-analyst.md +65 -280
- package/prompts/product-manager.md +48 -216
- package/prompts/qa-tester.md +33 -104
- package/prompts/quality-reviewer.md +17 -93
- package/prompts/quality-strategist.md +31 -255
- package/prompts/researcher.md +32 -89
- package/prompts/security-reviewer.md +12 -98
- package/prompts/test-engineer.md +29 -110
- package/prompts/ux-researcher.md +46 -300
- package/prompts/verifier.md +23 -51
- package/skills/ai-slop-cleaner/SKILL.md +60 -135
- package/skills/analyze/SKILL.md +35 -111
- package/skills/autopilot/SKILL.md +72 -163
- package/skills/autoresearch-goal/SKILL.md +6 -31
- package/skills/cancel/SKILL.md +33 -392
- package/skills/code-review/SKILL.md +66 -256
- package/skills/configure-notifications/SKILL.md +30 -216
- package/skills/deep-interview/SKILL.md +11 -10
- package/skills/design/SKILL.md +32 -132
- package/skills/doctor/SKILL.md +56 -177
- package/skills/omx-setup/SKILL.md +35 -116
- package/skills/pipeline/SKILL.md +6 -89
- package/skills/plan/SKILL.md +45 -228
- package/skills/ralph/SKILL.md +6 -290
- package/skills/ralplan/SKILL.md +20 -22
- package/skills/skill/SKILL.md +82 -807
- package/skills/team/SKILL.md +32 -520
- package/skills/ultragoal/SKILL.md +47 -150
- package/skills/ultraqa/SKILL.md +75 -252
- package/skills/ultrawork/SKILL.md +6 -182
- package/skills/visual-ralph/SKILL.md +33 -111
- package/skills/worker/SKILL.md +40 -113
- package/src/scripts/__tests__/codex-native-hook.test.ts +18888 -28799
- package/src/scripts/__tests__/docs-site-contract.test.ts +2 -2
- package/src/scripts/__tests__/generated-artifact-drift.test.ts +97 -0
- package/src/scripts/__tests__/issue-3293-callsite-parity.test.ts +197 -0
- package/src/scripts/__tests__/issue-3293-cancel-transaction.test.ts +189 -0
- package/src/scripts/__tests__/issue-3293-hook-owned-cancel.test.ts +186 -0
- package/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts +177 -0
- package/src/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.ts +201 -0
- package/src/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.ts +43 -0
- package/src/scripts/__tests__/issue-3481-conductor-deadlock.test.ts +77 -0
- package/src/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.ts +95 -0
- package/src/scripts/__tests__/issue-3536-external-team-state-root.test.ts +216 -0
- package/src/scripts/__tests__/notify-state-io.test.ts +29 -0
- package/src/scripts/__tests__/notify-tmux-injection.test.ts +26 -1
- package/src/scripts/__tests__/postinstall.test.ts +23 -1
- package/src/scripts/__tests__/prompt-inventory.test.ts +62 -1
- package/src/scripts/__tests__/reasoning-artifact-contract.test.ts +1 -2
- package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +49 -59
- package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +61 -27
- package/src/scripts/__tests__/smoke-packed-install.test.ts +223 -23
- package/src/scripts/__tests__/verify-native-release-assets.test.ts +240 -0
- package/src/scripts/codex-native-hook.ts +3618 -1383
- package/src/scripts/codex-native-pre-post.ts +50 -24
- package/src/scripts/generate-native-release-manifest.ts +83 -79
- package/src/scripts/notify-fallback-watcher.ts +38 -38
- package/src/scripts/notify-hook/auto-nudge.ts +1 -0
- package/src/scripts/notify-hook/state-io.ts +11 -0
- package/src/scripts/notify-hook/team-dispatch.ts +8 -5
- package/src/scripts/notify-hook/team-leader-nudge.ts +32 -4
- package/src/scripts/notify-hook/team-tmux-guard.ts +3 -1
- package/src/scripts/notify-hook/team-worker-stop.ts +23 -4
- package/src/scripts/notify-hook/team-worker.ts +43 -5
- package/src/scripts/notify-hook/tmux-injection.ts +5 -1
- package/src/scripts/notify-hook.ts +76 -124
- package/src/scripts/postinstall-advisory.ts +67 -0
- package/src/scripts/postinstall.ts +1 -1
- package/src/scripts/prompt-inventory.ts +142 -3
- package/src/scripts/run-compiled-ci.ts +2 -0
- package/src/scripts/run-test-files.ts +1 -0
- package/src/scripts/smoke-packed-install.ts +440 -59
- package/src/scripts/sync-plugin-mirror.ts +17 -1
- package/src/scripts/sync-prompt-guidance-fragments.ts +59 -22
- package/src/scripts/tmux-hook-engine.ts +3 -3
- package/src/scripts/verify-capabilities-lock.ts +23 -0
- package/src/scripts/verify-native-release-assets.ts +39 -31
- package/templates/AGENTS.md +45 -9
- package/templates/catalog-manifest.json +6 -146
- package/dist/autopilot/__tests__/deep-interview-gate.test.d.ts +0 -2
- package/dist/autopilot/__tests__/deep-interview-gate.test.d.ts.map +0 -1
- package/dist/autopilot/__tests__/deep-interview-gate.test.js +0 -215
- package/dist/autopilot/__tests__/deep-interview-gate.test.js.map +0 -1
- package/dist/autopilot/__tests__/ralplan-gate.test.d.ts +0 -2
- package/dist/autopilot/__tests__/ralplan-gate.test.d.ts.map +0 -1
- package/dist/autopilot/__tests__/ralplan-gate.test.js +0 -1361
- package/dist/autopilot/__tests__/ralplan-gate.test.js.map +0 -1
- package/dist/autopilot/deep-interview-gate.d.ts +0 -18
- package/dist/autopilot/deep-interview-gate.d.ts.map +0 -1
- package/dist/autopilot/deep-interview-gate.js +0 -396
- package/dist/autopilot/deep-interview-gate.js.map +0 -1
- package/dist/autopilot/ralplan-gate.d.ts +0 -18
- package/dist/autopilot/ralplan-gate.d.ts.map +0 -1
- package/dist/autopilot/ralplan-gate.js +0 -148
- package/dist/autopilot/ralplan-gate.js.map +0 -1
- package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts +0 -2
- package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js +0 -320
- package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +0 -1
- package/dist/pipeline/__tests__/orchestrator.test.d.ts +0 -2
- package/dist/pipeline/__tests__/orchestrator.test.d.ts.map +0 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +0 -770
- package/dist/pipeline/__tests__/orchestrator.test.js.map +0 -1
- package/dist/pipeline/__tests__/stages.test.d.ts +0 -2
- package/dist/pipeline/__tests__/stages.test.d.ts.map +0 -1
- package/dist/pipeline/__tests__/stages.test.js +0 -1778
- package/dist/pipeline/__tests__/stages.test.js.map +0 -1
- package/dist/pipeline/index.d.ts +0 -25
- package/dist/pipeline/index.d.ts.map +0 -1
- package/dist/pipeline/index.js +0 -17
- package/dist/pipeline/index.js.map +0 -1
- package/dist/pipeline/orchestrator.d.ts +0 -52
- package/dist/pipeline/orchestrator.d.ts.map +0 -1
- package/dist/pipeline/orchestrator.js +0 -399
- package/dist/pipeline/orchestrator.js.map +0 -1
- package/dist/pipeline/review-verdict.d.ts +0 -3
- package/dist/pipeline/review-verdict.d.ts.map +0 -1
- package/dist/pipeline/review-verdict.js +0 -14
- package/dist/pipeline/review-verdict.js.map +0 -1
- package/dist/pipeline/stages/code-review.d.ts +0 -35
- package/dist/pipeline/stages/code-review.d.ts.map +0 -1
- package/dist/pipeline/stages/code-review.js +0 -55
- package/dist/pipeline/stages/code-review.js.map +0 -1
- package/dist/pipeline/stages/deep-interview.d.ts +0 -15
- package/dist/pipeline/stages/deep-interview.d.ts.map +0 -1
- package/dist/pipeline/stages/deep-interview.js +0 -32
- package/dist/pipeline/stages/deep-interview.js.map +0 -1
- package/dist/pipeline/stages/ralph-verify.d.ts +0 -53
- package/dist/pipeline/stages/ralph-verify.d.ts.map +0 -1
- package/dist/pipeline/stages/ralph-verify.js +0 -89
- package/dist/pipeline/stages/ralph-verify.js.map +0 -1
- package/dist/pipeline/stages/ralplan.d.ts +0 -27
- package/dist/pipeline/stages/ralplan.d.ts.map +0 -1
- package/dist/pipeline/stages/ralplan.js +0 -152
- package/dist/pipeline/stages/ralplan.js.map +0 -1
- package/dist/pipeline/stages/team-exec.d.ts +0 -52
- package/dist/pipeline/stages/team-exec.d.ts.map +0 -1
- package/dist/pipeline/stages/team-exec.js +0 -266
- package/dist/pipeline/stages/team-exec.js.map +0 -1
- package/dist/pipeline/stages/ultragoal.d.ts +0 -23
- package/dist/pipeline/stages/ultragoal.d.ts.map +0 -1
- package/dist/pipeline/stages/ultragoal.js +0 -53
- package/dist/pipeline/stages/ultragoal.js.map +0 -1
- package/dist/pipeline/stages/ultraqa.d.ts +0 -33
- package/dist/pipeline/stages/ultraqa.d.ts.map +0 -1
- package/dist/pipeline/stages/ultraqa.js +0 -49
- package/dist/pipeline/stages/ultraqa.js.map +0 -1
- package/dist/pipeline/types.d.ts +0 -124
- package/dist/pipeline/types.d.ts.map +0 -1
- package/dist/pipeline/types.js +0 -8
- package/dist/pipeline/types.js.map +0 -1
- package/dist/ralplan/__tests__/consensus-gate.test.d.ts +0 -2
- package/dist/ralplan/__tests__/consensus-gate.test.d.ts.map +0 -1
- package/dist/ralplan/__tests__/consensus-gate.test.js +0 -1455
- package/dist/ralplan/__tests__/consensus-gate.test.js.map +0 -1
- package/dist/ralplan/consensus-gate.d.ts +0 -62
- package/dist/ralplan/consensus-gate.d.ts.map +0 -1
- package/dist/ralplan/consensus-gate.js +0 -760
- package/dist/ralplan/consensus-gate.js.map +0 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts +0 -25
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +0 -1
- package/dist/scripts/notify-hook/ralph-session-resume.js +0 -377
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +0 -1
- package/dist/state/__tests__/planning-gate.test.d.ts +0 -2
- package/dist/state/__tests__/planning-gate.test.d.ts.map +0 -1
- package/dist/state/__tests__/planning-gate.test.js +0 -629
- package/dist/state/__tests__/planning-gate.test.js.map +0 -1
- package/plugins/oh-my-codex/skills/autoresearch-goal/SKILL.md +0 -39
- package/plugins/oh-my-codex/skills/pipeline/SKILL.md +0 -97
- package/plugins/oh-my-codex/skills/prometheus-strict/README.md +0 -35
- package/plugins/oh-my-codex/skills/prometheus-strict/SKILL.md +0 -219
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +0 -298
- package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +0 -190
- package/plugins/oh-my-codex/skills/ultrawork/references/agent-tiers.md +0 -62
- package/prompts/prometheus-strict-metis.md +0 -274
- package/prompts/prometheus-strict-momus.md +0 -82
- package/prompts/prometheus-strict-oracle.md +0 -107
- package/prompts/scholastic.md +0 -11
- package/prompts/sisyphus-lite.md +0 -111
- package/skills/ask-claude/SKILL.md +0 -12
- package/skills/ask-gemini/SKILL.md +0 -12
- package/skills/build-fix/SKILL.md +0 -10
- package/skills/deepsearch/SKILL.md +0 -10
- package/skills/ecomode/SKILL.md +0 -114
- package/skills/ecomode/references/agent-tiers.md +0 -61
- package/skills/frontend-ui-ux/SKILL.md +0 -16
- package/skills/help/SKILL.md +0 -10
- package/skills/note/SKILL.md +0 -10
- package/skills/prometheus-strict/README.md +0 -35
- package/skills/prometheus-strict/SKILL.md +0 -219
- package/skills/ralph-init/SKILL.md +0 -10
- package/skills/review/SKILL.md +0 -10
- package/skills/security-review/SKILL.md +0 -10
- package/skills/swarm/SKILL.md +0 -12
- package/skills/tdd/SKILL.md +0 -104
- package/skills/trace/SKILL.md +0 -10
- package/skills/visual-verdict/SKILL.md +0 -10
- package/skills/web-clone/SKILL.md +0 -357
- package/src/scripts/notify-hook/ralph-session-resume.ts +0 -466
package/dist/hud/tmux.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { execFileSync } from 'child_process';
|
|
2
3
|
import { existsSync } from 'fs';
|
|
3
4
|
import { HUD_RESIZE_RECONCILE_DELAY_SECONDS, HUD_TMUX_HEIGHT_LINES } from './constants.js';
|
|
@@ -9,6 +10,70 @@ export const TMUX_PANE_FIELD_SEPARATOR = '\x1f';
|
|
|
9
10
|
export const TMUX_PANE_FIELD_SEPARATOR_OCTAL_ESCAPE = '\\037';
|
|
10
11
|
/** Upper bound for tmux hook indices (signed 32-bit max). */
|
|
11
12
|
const TMUX_HOOK_INDEX_MAX = 2147483647;
|
|
13
|
+
const PSMUX_PANE_ID_MAX = 0xffffffffn;
|
|
14
|
+
const PSMUX_PANE_ID_MAX_DIGITS = PSMUX_PANE_ID_MAX.toString().length;
|
|
15
|
+
export function parseCanonicalTmuxPaneId(value) {
|
|
16
|
+
if (typeof value !== 'string')
|
|
17
|
+
return null;
|
|
18
|
+
const match = /^%(0|[1-9]\d*)$/.exec(value);
|
|
19
|
+
if (!match || match[1].length > PSMUX_PANE_ID_MAX_DIGITS)
|
|
20
|
+
return null;
|
|
21
|
+
try {
|
|
22
|
+
return BigInt(match[1]) <= PSMUX_PANE_ID_MAX ? value : null;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parses tmux output used as authority. Authority frames are deliberately
|
|
30
|
+
* transport-strict: a nonempty body followed by exactly one LF or CRLF.
|
|
31
|
+
*/
|
|
32
|
+
export function parseExactTmuxAuthorityLines(output) {
|
|
33
|
+
if (typeof output !== 'string' || output.length < 2)
|
|
34
|
+
return null;
|
|
35
|
+
const terminator = output.endsWith('\r\n') ? '\r\n' : output.endsWith('\n') ? '\n' : null;
|
|
36
|
+
if (!terminator)
|
|
37
|
+
return null;
|
|
38
|
+
const body = output.slice(0, -terminator.length);
|
|
39
|
+
if (body === '' || body.endsWith('\n') || body.includes('\r'))
|
|
40
|
+
return null;
|
|
41
|
+
return body.split('\n');
|
|
42
|
+
}
|
|
43
|
+
/** Parses one exact, nonempty tmux authority scalar. */
|
|
44
|
+
export function parseExactTmuxAuthorityScalar(output) {
|
|
45
|
+
const lines = parseExactTmuxAuthorityLines(output);
|
|
46
|
+
return lines?.length === 1 && lines[0] !== '' ? lines[0] : null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Tolerant pane parsing is for display metadata only. Callers using its output
|
|
50
|
+
* as authority MUST first validate framing with parseExactTmuxAuthorityLines.
|
|
51
|
+
*/
|
|
52
|
+
function canonicalizePaneSnapshotBatch(panes) {
|
|
53
|
+
const paneIds = new Set();
|
|
54
|
+
const canonicalPanes = [];
|
|
55
|
+
for (const pane of panes) {
|
|
56
|
+
const paneId = parseCanonicalTmuxPaneId(pane.paneId);
|
|
57
|
+
if (!paneId || paneIds.has(paneId))
|
|
58
|
+
return null;
|
|
59
|
+
paneIds.add(paneId);
|
|
60
|
+
canonicalPanes.push({ ...pane, paneId });
|
|
61
|
+
}
|
|
62
|
+
return canonicalPanes;
|
|
63
|
+
}
|
|
64
|
+
function parseCanonicalPaneIdSnapshot(output) {
|
|
65
|
+
const lines = parseExactTmuxAuthorityLines(output);
|
|
66
|
+
if (!lines)
|
|
67
|
+
return null;
|
|
68
|
+
const paneIds = new Set();
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
const paneId = parseCanonicalTmuxPaneId(line);
|
|
71
|
+
if (!paneId || paneIds.has(paneId))
|
|
72
|
+
return null;
|
|
73
|
+
paneIds.add(paneId);
|
|
74
|
+
}
|
|
75
|
+
return paneIds;
|
|
76
|
+
}
|
|
12
77
|
function defaultExecTmuxSync(args) {
|
|
13
78
|
try {
|
|
14
79
|
return execFileSync(resolveTmuxBinaryForPlatform() || 'tmux', args, {
|
|
@@ -25,28 +90,36 @@ function defaultExecTmuxSync(args) {
|
|
|
25
90
|
}
|
|
26
91
|
}
|
|
27
92
|
function parseNonNegativeInteger(value) {
|
|
28
|
-
if (typeof value !== 'string' ||
|
|
93
|
+
if (typeof value !== 'string' || !/^(?:0|[1-9][0-9]*)$/.test(value))
|
|
29
94
|
return null;
|
|
30
|
-
const parsed = Number
|
|
31
|
-
return Number.
|
|
95
|
+
const parsed = Number(value);
|
|
96
|
+
return Number.isSafeInteger(parsed) && parsed <= 4_294_967_295 ? parsed : null;
|
|
32
97
|
}
|
|
33
98
|
function parsePositiveInteger(value) {
|
|
34
99
|
const parsed = parseNonNegativeInteger(value);
|
|
35
100
|
return parsed !== null && parsed > 0 ? parsed : null;
|
|
36
101
|
}
|
|
37
|
-
export function parseTmuxPaneSnapshot(output) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
|
|
102
|
+
export function parseTmuxPaneSnapshot(output, authoritativePaneIds) {
|
|
103
|
+
const lines = output.split('\n');
|
|
104
|
+
if (lines.at(-1) === '')
|
|
105
|
+
lines.pop();
|
|
106
|
+
if (lines.length === 0)
|
|
107
|
+
return [];
|
|
108
|
+
const panes = [];
|
|
109
|
+
for (const line of lines) {
|
|
110
|
+
if (line === '')
|
|
111
|
+
return [];
|
|
43
112
|
const fieldSeparator = line.includes(TMUX_PANE_FIELD_SEPARATOR)
|
|
44
113
|
? TMUX_PANE_FIELD_SEPARATOR
|
|
45
114
|
: line.includes(TMUX_PANE_FIELD_SEPARATOR_OCTAL_ESCAPE)
|
|
46
115
|
? TMUX_PANE_FIELD_SEPARATOR_OCTAL_ESCAPE
|
|
47
116
|
: '\t';
|
|
48
117
|
const parts = line.split(fieldSeparator);
|
|
49
|
-
const [
|
|
118
|
+
const [rawPaneId = '', currentCommand = ''] = parts;
|
|
119
|
+
const paneId = parseCanonicalTmuxPaneId(rawPaneId);
|
|
120
|
+
if (!paneId)
|
|
121
|
+
return [];
|
|
122
|
+
const hasGeometryFields = parts.length >= 9;
|
|
50
123
|
const paneLeft = parseNonNegativeInteger(parts[2]);
|
|
51
124
|
const paneTop = parseNonNegativeInteger(parts[3]);
|
|
52
125
|
const paneWidth = parsePositiveInteger(parts[4]);
|
|
@@ -61,16 +134,25 @@ export function parseTmuxPaneSnapshot(output) {
|
|
|
61
134
|
&& paneBottom !== null
|
|
62
135
|
&& windowWidth !== null
|
|
63
136
|
&& windowHeight !== null);
|
|
137
|
+
if (hasGeometryFields && !hasGeometry)
|
|
138
|
+
return [];
|
|
64
139
|
const payloadParts = hasGeometry ? parts.slice(9) : parts.slice(2);
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
140
|
+
const hasIncarnationFields = hasGeometry
|
|
141
|
+
&& payloadParts.length >= 4
|
|
142
|
+
&& /^(?:0|1)$/.test(payloadParts.at(-2) ?? '')
|
|
143
|
+
&& parsePositiveInteger(payloadParts.at(-1)) !== null;
|
|
144
|
+
const incarnationParts = hasIncarnationFields ? payloadParts.slice(-2) : [];
|
|
145
|
+
const commandParts = hasIncarnationFields ? payloadParts.slice(0, -2) : payloadParts;
|
|
146
|
+
const hasCurrentPathColumn = commandParts.length >= 2;
|
|
147
|
+
const currentPath = hasCurrentPathColumn ? (commandParts.at(-1) ?? '') : '';
|
|
148
|
+
const startCommandParts = hasCurrentPathColumn ? commandParts.slice(0, -1) : commandParts;
|
|
68
149
|
const trimmedCurrentPath = currentPath.trim();
|
|
69
|
-
|
|
70
|
-
paneId
|
|
150
|
+
panes.push({
|
|
151
|
+
paneId,
|
|
71
152
|
currentCommand: currentCommand.trim(),
|
|
72
153
|
startCommand: startCommandParts.join('\t').trim(),
|
|
73
154
|
...(trimmedCurrentPath ? { currentPath: trimmedCurrentPath } : {}),
|
|
155
|
+
...(hasIncarnationFields ? { paneDead: incarnationParts[0] === '1', panePid: incarnationParts[1] } : {}),
|
|
74
156
|
...(hasGeometry
|
|
75
157
|
? {
|
|
76
158
|
paneLeft,
|
|
@@ -82,9 +164,16 @@ export function parseTmuxPaneSnapshot(output) {
|
|
|
82
164
|
windowHeight,
|
|
83
165
|
}
|
|
84
166
|
: {}),
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
const canonicalPanes = canonicalizePaneSnapshotBatch(panes);
|
|
170
|
+
if (!canonicalPanes)
|
|
171
|
+
return [];
|
|
172
|
+
if (authoritativePaneIds
|
|
173
|
+
&& (canonicalPanes.length !== authoritativePaneIds.size
|
|
174
|
+
|| canonicalPanes.some((pane) => !authoritativePaneIds.has(pane.paneId))))
|
|
175
|
+
return [];
|
|
176
|
+
return canonicalPanes;
|
|
88
177
|
}
|
|
89
178
|
export function isHudWatchPane(pane) {
|
|
90
179
|
const command = `${pane.startCommand} ${pane.currentCommand}`.toLowerCase();
|
|
@@ -92,53 +181,302 @@ export function isHudWatchPane(pane) {
|
|
|
92
181
|
&& /--watch\b/.test(command)
|
|
93
182
|
&& (/\bomx(?:\.js)?\b/.test(command) || /\bnode\b/.test(command)));
|
|
94
183
|
}
|
|
184
|
+
const HUD_OWNER_ENV_KEYS = [
|
|
185
|
+
OMX_TMUX_HUD_OWNER_ENV,
|
|
186
|
+
'OMX_SESSION_ID',
|
|
187
|
+
OMX_TMUX_HUD_LEADER_PANE_ENV,
|
|
188
|
+
];
|
|
189
|
+
function isHudOwnerEnvKey(key) {
|
|
190
|
+
return HUD_OWNER_ENV_KEYS.some((ownerKey) => ownerKey === key);
|
|
191
|
+
}
|
|
192
|
+
function isPowerShellHudOwnerEnvKey(key) {
|
|
193
|
+
return HUD_OWNER_ENV_KEYS.some((ownerKey) => ownerKey === key.toUpperCase());
|
|
194
|
+
}
|
|
195
|
+
function lexPosixWords(command) {
|
|
196
|
+
const words = [];
|
|
197
|
+
let index = 0;
|
|
198
|
+
while (index < command.length) {
|
|
199
|
+
while (/\s/.test(command[index] ?? ''))
|
|
200
|
+
index += 1;
|
|
201
|
+
if (index >= command.length)
|
|
202
|
+
break;
|
|
203
|
+
if (command[index] === '#')
|
|
204
|
+
break;
|
|
205
|
+
let word = '';
|
|
206
|
+
let quoted = false;
|
|
207
|
+
while (index < command.length && !/\s/.test(command[index] ?? '')) {
|
|
208
|
+
const char = command[index];
|
|
209
|
+
if (';|&()<>`'.includes(char) || char === '\n' || char === '\r')
|
|
210
|
+
return null;
|
|
211
|
+
if (char === '\\') {
|
|
212
|
+
index += 1;
|
|
213
|
+
if (index >= command.length)
|
|
214
|
+
return null;
|
|
215
|
+
word += command[index];
|
|
216
|
+
index += 1;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (char === "'") {
|
|
220
|
+
quoted = true;
|
|
221
|
+
index += 1;
|
|
222
|
+
while (index < command.length && command[index] !== "'") {
|
|
223
|
+
word += command[index];
|
|
224
|
+
index += 1;
|
|
225
|
+
}
|
|
226
|
+
if (index >= command.length)
|
|
227
|
+
return null;
|
|
228
|
+
index += 1;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (char === '"') {
|
|
232
|
+
quoted = true;
|
|
233
|
+
index += 1;
|
|
234
|
+
while (index < command.length && command[index] !== '"') {
|
|
235
|
+
if (command[index] === '\\') {
|
|
236
|
+
index += 1;
|
|
237
|
+
if (index >= command.length)
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
word += command[index];
|
|
241
|
+
index += 1;
|
|
242
|
+
}
|
|
243
|
+
if (index >= command.length)
|
|
244
|
+
return null;
|
|
245
|
+
index += 1;
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
word += char;
|
|
249
|
+
index += 1;
|
|
250
|
+
}
|
|
251
|
+
if (!word && !quoted)
|
|
252
|
+
return null;
|
|
253
|
+
words.push(word);
|
|
254
|
+
}
|
|
255
|
+
return words;
|
|
256
|
+
}
|
|
257
|
+
function parsePosixHudEnvAssignments(command) {
|
|
258
|
+
const values = new Map();
|
|
259
|
+
const attempted = HUD_OWNER_ENV_KEYS.some((key) => command.includes(key));
|
|
260
|
+
const words = lexPosixWords(command);
|
|
261
|
+
if (!words)
|
|
262
|
+
return { attempted, valid: false, values };
|
|
263
|
+
const inspect = (tokens) => {
|
|
264
|
+
let commandStarted = false;
|
|
265
|
+
let acceptsEnvAssignments = false;
|
|
266
|
+
for (let index = 0; index < tokens.length; index += 1) {
|
|
267
|
+
const token = tokens[index];
|
|
268
|
+
const assignment = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/.exec(token);
|
|
269
|
+
if (assignment && isHudOwnerEnvKey(assignment[1]) && (!commandStarted || acceptsEnvAssignments)) {
|
|
270
|
+
const key = assignment[1];
|
|
271
|
+
const existing = values.get(key) ?? [];
|
|
272
|
+
existing.push(assignment[2]);
|
|
273
|
+
values.set(key, existing);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
if (token === '-c' && index + 1 < tokens.length) {
|
|
277
|
+
const nested = lexPosixWords(tokens[index + 1]);
|
|
278
|
+
if (!nested || !inspect(nested))
|
|
279
|
+
return false;
|
|
280
|
+
commandStarted = true;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (token === 'exec' && !commandStarted)
|
|
284
|
+
continue;
|
|
285
|
+
if (!commandStarted && token === 'env') {
|
|
286
|
+
commandStarted = true;
|
|
287
|
+
acceptsEnvAssignments = true;
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
commandStarted = true;
|
|
291
|
+
acceptsEnvAssignments = false;
|
|
292
|
+
}
|
|
293
|
+
return true;
|
|
294
|
+
};
|
|
295
|
+
return { attempted, valid: inspect(words), values };
|
|
296
|
+
}
|
|
297
|
+
function parseShellEnvAssignments(command, key) {
|
|
298
|
+
const parsed = parsePosixHudEnvAssignments(command);
|
|
299
|
+
return parsed.valid ? (parsed.values.get(key) ?? []) : [];
|
|
300
|
+
}
|
|
95
301
|
function parseShellEnvAssignment(command, key) {
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
302
|
+
const values = parseShellEnvAssignments(command, key);
|
|
303
|
+
return values.length === 1 && values[0] !== '' ? values[0] : undefined;
|
|
304
|
+
}
|
|
305
|
+
function containsPowerShellHudOwnerReferenceOutsideQuotes(command) {
|
|
306
|
+
let quote = null;
|
|
307
|
+
let blockComment = false;
|
|
308
|
+
let lineComment = false;
|
|
309
|
+
for (let index = 0; index < command.length; index += 1) {
|
|
310
|
+
const char = command[index];
|
|
311
|
+
const next = command[index + 1];
|
|
312
|
+
if (blockComment) {
|
|
313
|
+
if (char === '#' && next === '>') {
|
|
314
|
+
blockComment = false;
|
|
315
|
+
index += 1;
|
|
316
|
+
}
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (lineComment) {
|
|
320
|
+
if (char === '\n' || char === '\r')
|
|
321
|
+
lineComment = false;
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
if (quote === 'single') {
|
|
325
|
+
if (char === "'" && next === "'")
|
|
326
|
+
index += 1;
|
|
327
|
+
else if (char === "'")
|
|
328
|
+
quote = null;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (quote === 'double') {
|
|
332
|
+
if (char === '`')
|
|
333
|
+
index += 1;
|
|
334
|
+
else if (char === '"')
|
|
335
|
+
quote = null;
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
if (char === '<' && next === '#') {
|
|
339
|
+
blockComment = true;
|
|
340
|
+
index += 1;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
if (char === '#') {
|
|
344
|
+
lineComment = true;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (char === "'") {
|
|
348
|
+
quote = 'single';
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (char === '"') {
|
|
352
|
+
quote = 'double';
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (char === '`') {
|
|
356
|
+
index += 1;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (command.slice(index, index + 5).toLowerCase() === '$env:') {
|
|
360
|
+
const match = /^\$env:([A-Za-z_][A-Za-z0-9_]*)/i.exec(command.slice(index));
|
|
361
|
+
if (match && isPowerShellHudOwnerEnvKey(match[1]))
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
function unwrapKnownPowerShellCommand(command) {
|
|
368
|
+
const match = /^\s*powershell(?:\.exe)?\s+-NoLogo\s+-NoExit\s+-Command\s+'((?:''|[^'])*)'(.*)$/i.exec(command);
|
|
369
|
+
if (!match)
|
|
370
|
+
return null;
|
|
371
|
+
return { command: match[1].replace(/''/g, "'"), remainder: match[2] };
|
|
372
|
+
}
|
|
373
|
+
function parsePowerShellHudEnvPrefix(command) {
|
|
374
|
+
const unwrapped = unwrapKnownPowerShellCommand(command);
|
|
375
|
+
const source = unwrapped?.command ?? command;
|
|
376
|
+
const present = containsPowerShellHudOwnerReferenceOutsideQuotes(source);
|
|
377
|
+
const values = new Map();
|
|
378
|
+
if (!present)
|
|
379
|
+
return { present: false, valid: false, values, remainder: command };
|
|
380
|
+
const prefixMatch = /^\s*((?:\$env:[A-Za-z_][A-Za-z0-9_]*\s*=\s*'(?:''|[^'])*'\s*;\s*)+)&(?:\s|$)/i.exec(source);
|
|
381
|
+
if (!prefixMatch)
|
|
382
|
+
return { present: true, valid: false, values, remainder: command };
|
|
383
|
+
const assignmentPattern = /\$env:([A-Za-z_][A-Za-z0-9_]*)\s*=\s*'((?:''|[^'])*)'\s*;/gi;
|
|
384
|
+
for (const match of prefixMatch[1].matchAll(assignmentPattern)) {
|
|
385
|
+
const key = match[1].toUpperCase();
|
|
386
|
+
const existing = values.get(key) ?? [];
|
|
387
|
+
existing.push(match[2].replace(/''/g, "'"));
|
|
388
|
+
values.set(key, existing);
|
|
389
|
+
}
|
|
390
|
+
const remainder = `${source.slice(prefixMatch[0].length)}${unwrapped?.remainder ?? ''}`;
|
|
391
|
+
return { present: true, valid: true, values, remainder };
|
|
392
|
+
}
|
|
393
|
+
function hasHudOwnerMetadataAttempt(command) {
|
|
394
|
+
return parsePowerShellHudEnvPrefix(command).present || parsePosixHudEnvAssignments(command).attempted;
|
|
395
|
+
}
|
|
396
|
+
function isInvalidHudOwnerValue(key, value) {
|
|
397
|
+
return value === '' || (key === OMX_TMUX_HUD_OWNER_ENV && value !== '1');
|
|
398
|
+
}
|
|
399
|
+
function parseHudEnvAssignment(command, key) {
|
|
400
|
+
const posix = parsePosixHudEnvAssignments(command);
|
|
401
|
+
const powerShellPrefix = parsePowerShellHudEnvPrefix(command);
|
|
402
|
+
if (powerShellPrefix.present)
|
|
403
|
+
return powerShellPrefix.valid ? (powerShellPrefix.values.get(key.toUpperCase())?.length === 1 ? powerShellPrefix.values.get(key.toUpperCase())[0] : undefined) : undefined;
|
|
404
|
+
return posix.valid ? parseShellEnvAssignment(command, key) : undefined;
|
|
405
|
+
}
|
|
406
|
+
function hasAmbiguousHudOwnerMetadata(command) {
|
|
407
|
+
const posix = parsePosixHudEnvAssignments(command);
|
|
408
|
+
const powerShellPrefix = parsePowerShellHudEnvPrefix(command);
|
|
409
|
+
if (powerShellPrefix.present) {
|
|
410
|
+
if (!powerShellPrefix.valid
|
|
411
|
+
|| posix.values.size > 0
|
|
412
|
+
|| containsPowerShellHudOwnerReferenceOutsideQuotes(powerShellPrefix.remainder)
|
|
413
|
+
|| parsePosixHudEnvAssignments(powerShellPrefix.remainder).attempted)
|
|
414
|
+
return true;
|
|
415
|
+
return HUD_OWNER_ENV_KEYS.some((key) => {
|
|
416
|
+
const values = powerShellPrefix.values.get(key) ?? [];
|
|
417
|
+
return values.length > 1 || (values.length === 1 && isInvalidHudOwnerValue(key, values[0]));
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (posix.attempted && (!posix.valid || posix.values.size === 0))
|
|
421
|
+
return true;
|
|
422
|
+
return HUD_OWNER_ENV_KEYS.some((key) => {
|
|
423
|
+
const values = posix.values.get(key) ?? [];
|
|
424
|
+
return values.length > 1 || (values.length === 1 && isInvalidHudOwnerValue(key, values[0]));
|
|
425
|
+
});
|
|
106
426
|
}
|
|
107
427
|
export function readHudPaneOwner(pane) {
|
|
108
428
|
const command = `${pane.startCommand} ${pane.currentCommand}`;
|
|
429
|
+
const rawLeaderPaneId = parseHudEnvAssignment(command, OMX_TMUX_HUD_LEADER_PANE_ENV);
|
|
430
|
+
if (hasAmbiguousHudOwnerMetadata(command)
|
|
431
|
+
|| (rawLeaderPaneId !== undefined && !parseCanonicalTmuxPaneId(rawLeaderPaneId))) {
|
|
432
|
+
return { sessionId: undefined, leaderPaneId: undefined };
|
|
433
|
+
}
|
|
109
434
|
return {
|
|
110
|
-
sessionId:
|
|
111
|
-
leaderPaneId:
|
|
435
|
+
sessionId: parseHudEnvAssignment(command, 'OMX_SESSION_ID'),
|
|
436
|
+
leaderPaneId: rawLeaderPaneId ? parseCanonicalTmuxPaneId(rawLeaderPaneId) ?? undefined : undefined,
|
|
112
437
|
};
|
|
113
438
|
}
|
|
114
439
|
function hasHudPaneOwnerMetadata(pane) {
|
|
115
440
|
const command = `${pane.startCommand} ${pane.currentCommand}`;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
441
|
+
return hasHudOwnerMetadataAttempt(command) && !hasAmbiguousHudOwnerMetadata(command);
|
|
442
|
+
}
|
|
443
|
+
export function hasValidHudOwnerMarker(pane) {
|
|
444
|
+
const command = `${pane.startCommand} ${pane.currentCommand}`;
|
|
445
|
+
if (hasAmbiguousHudOwnerMetadata(command))
|
|
446
|
+
return false;
|
|
447
|
+
return parseHudEnvAssignment(command, OMX_TMUX_HUD_OWNER_ENV) === '1';
|
|
119
448
|
}
|
|
120
449
|
function hasOmxCliToken(command) {
|
|
121
450
|
return /(?:^|[\s'"])(?:[^\s'"]*\/)?omx(?:\.js)?(?=$|[\s'"])/.test(command);
|
|
122
451
|
}
|
|
452
|
+
function hasPowerShellEnvironmentAssignmentPrefix(command) {
|
|
453
|
+
return /^\s*(?:\$env:[A-Za-z_][A-Za-z0-9_]*\s*=\s*(?:'(?:''|[^'])*'|"(?:`.|[^"])*")\s*;\s*)+&(?:\s|$)/i.test(command);
|
|
454
|
+
}
|
|
123
455
|
function isLegacyFocusedHudWatchPane(pane) {
|
|
124
456
|
// Migration-only heuristic for prompt-submit auto-HUD reconciliation: older
|
|
125
457
|
// focused auto-HUD panes lacked owner metadata, so keep this deliberately
|
|
126
458
|
// narrower than general HUD ownership/reaping.
|
|
127
|
-
if (!isHudWatchPane(pane) || hasHudPaneOwnerMetadata(pane))
|
|
128
|
-
return false;
|
|
129
459
|
const command = `${pane.startCommand} ${pane.currentCommand}`;
|
|
460
|
+
if (!isHudWatchPane(pane)
|
|
461
|
+
|| hasHudOwnerMetadataAttempt(command)
|
|
462
|
+
|| hasPowerShellEnvironmentAssignmentPrefix(command))
|
|
463
|
+
return false;
|
|
130
464
|
return hasOmxCliToken(command)
|
|
131
465
|
&& !/(?:^|[\s'"])--tmux(?:[\s'"]|$)/.test(command)
|
|
132
466
|
&& /(?:^|[\s'"])--preset=focused(?:[\s'"]|$)/.test(command);
|
|
133
467
|
}
|
|
134
468
|
export function findLegacyFocusedHudWatchPaneIds(panes, currentPaneId) {
|
|
135
|
-
|
|
136
|
-
|
|
469
|
+
const canonicalPanes = canonicalizePaneSnapshotBatch(panes);
|
|
470
|
+
const canonicalCurrentPaneId = currentPaneId ? parseCanonicalTmuxPaneId(currentPaneId) : null;
|
|
471
|
+
if (!canonicalPanes || (currentPaneId && !canonicalCurrentPaneId))
|
|
472
|
+
return [];
|
|
473
|
+
return canonicalPanes
|
|
474
|
+
.filter((pane) => pane.paneId !== canonicalCurrentPaneId)
|
|
137
475
|
.filter((pane) => isLegacyFocusedHudWatchPane(pane))
|
|
138
476
|
.map((pane) => pane.paneId);
|
|
139
477
|
}
|
|
140
478
|
export function hudPaneMatchesOwner(pane, owner = {}) {
|
|
141
|
-
if (!isHudWatchPane(pane))
|
|
479
|
+
if (!parseCanonicalTmuxPaneId(pane.paneId) || !isHudWatchPane(pane))
|
|
142
480
|
return false;
|
|
143
481
|
const wantedSessionIds = [
|
|
144
482
|
typeof owner.sessionId === 'string' ? owner.sessionId.trim() : '',
|
|
@@ -146,11 +484,16 @@ export function hudPaneMatchesOwner(pane, owner = {}) {
|
|
|
146
484
|
]
|
|
147
485
|
.map((sessionId) => sessionId.trim())
|
|
148
486
|
.filter((sessionId, index, sessionIds) => sessionId !== '' && sessionIds.indexOf(sessionId) === index);
|
|
149
|
-
const
|
|
487
|
+
const rawWantedLeaderPaneId = typeof owner.leaderPaneId === 'string' ? owner.leaderPaneId : '';
|
|
488
|
+
const wantedLeaderPaneId = rawWantedLeaderPaneId ? parseCanonicalTmuxPaneId(rawWantedLeaderPaneId) : null;
|
|
489
|
+
if (rawWantedLeaderPaneId && !wantedLeaderPaneId)
|
|
490
|
+
return false;
|
|
150
491
|
const wantsSession = wantedSessionIds.length > 0;
|
|
151
|
-
const wantsLeaderPane = wantedLeaderPaneId !==
|
|
492
|
+
const wantsLeaderPane = wantedLeaderPaneId !== null;
|
|
152
493
|
if (!wantsSession && !wantsLeaderPane)
|
|
153
494
|
return true;
|
|
495
|
+
if (hasAmbiguousHudOwnerMetadata(`${pane.startCommand} ${pane.currentCommand}`))
|
|
496
|
+
return false;
|
|
154
497
|
const paneOwner = readHudPaneOwner(pane);
|
|
155
498
|
const sessionMatches = wantsSession && wantedSessionIds.includes(paneOwner.sessionId ?? '');
|
|
156
499
|
const leaderPaneMatches = wantsLeaderPane && paneOwner.leaderPaneId === wantedLeaderPaneId;
|
|
@@ -165,8 +508,12 @@ export function hudPaneMatchesOwner(pane, owner = {}) {
|
|
|
165
508
|
return leaderPaneMatches;
|
|
166
509
|
}
|
|
167
510
|
export function findHudWatchPaneIds(panes, currentPaneId, owner = {}) {
|
|
168
|
-
|
|
169
|
-
|
|
511
|
+
const canonicalPanes = canonicalizePaneSnapshotBatch(panes);
|
|
512
|
+
const canonicalCurrentPaneId = currentPaneId ? parseCanonicalTmuxPaneId(currentPaneId) : null;
|
|
513
|
+
if (!canonicalPanes || (currentPaneId && !canonicalCurrentPaneId))
|
|
514
|
+
return [];
|
|
515
|
+
return canonicalPanes
|
|
516
|
+
.filter((pane) => pane.paneId !== canonicalCurrentPaneId)
|
|
170
517
|
.filter((pane) => hudPaneMatchesOwner(pane, owner))
|
|
171
518
|
.map((pane) => pane.paneId);
|
|
172
519
|
}
|
|
@@ -184,8 +531,13 @@ function isDoctorSmokeSessionId(sessionId) {
|
|
|
184
531
|
function shouldReapDeletedCwdHudPane(pane, isLivePane) {
|
|
185
532
|
// A deleted tmux launch cwd is not enough to prove a HUD is dead: watch mode can
|
|
186
533
|
// keep serving from a resolved live cwd. Reap only explicit doctor smoke panes or
|
|
187
|
-
// owner-tagged panes whose leader is gone.
|
|
188
|
-
|
|
534
|
+
// owner-tagged panes whose canonical leader is gone.
|
|
535
|
+
const command = `${pane.startCommand} ${pane.currentCommand}`;
|
|
536
|
+
const rawLeaderPaneId = parseHudEnvAssignment(command, OMX_TMUX_HUD_LEADER_PANE_ENV);
|
|
537
|
+
if (!hasHudPaneOwnerMetadata(pane)
|
|
538
|
+
|| !hasDeletedTmuxPaneMarker(pane.currentPath)
|
|
539
|
+
|| hasAmbiguousHudOwnerMetadata(command)
|
|
540
|
+
|| (rawLeaderPaneId !== undefined && !parseCanonicalTmuxPaneId(rawLeaderPaneId)))
|
|
189
541
|
return false;
|
|
190
542
|
const owner = readHudPaneOwner(pane);
|
|
191
543
|
if (isDoctorSmokeSessionId(owner.sessionId))
|
|
@@ -195,18 +547,27 @@ function shouldReapDeletedCwdHudPane(pane, isLivePane) {
|
|
|
195
547
|
return !owner.leaderPaneId || !isLivePane(owner.leaderPaneId);
|
|
196
548
|
}
|
|
197
549
|
export function reapDeadHudPanes(panes, opts = {}) {
|
|
198
|
-
const
|
|
550
|
+
const canonicalPanes = canonicalizePaneSnapshotBatch(panes);
|
|
551
|
+
if (!canonicalPanes)
|
|
552
|
+
return { reaped: [], preserved: panes.map((pane) => pane.paneId) };
|
|
553
|
+
const livePaneIds = new Set(canonicalPanes.map((pane) => pane.paneId));
|
|
199
554
|
const isLivePane = opts.isLivePane ?? ((paneId) => livePaneIds.has(paneId));
|
|
200
555
|
const killPane = opts.killPane ?? ((paneId) => killTmuxPane(paneId));
|
|
201
556
|
const reaped = [];
|
|
202
557
|
const preserved = [];
|
|
203
|
-
for (const pane of
|
|
558
|
+
for (const pane of canonicalPanes) {
|
|
204
559
|
if (!isHudWatchPane(pane))
|
|
205
560
|
continue;
|
|
206
561
|
if (shouldReapDeletedCwdHudPane(pane, isLivePane) && killPane(pane.paneId)) {
|
|
207
562
|
reaped.push(pane.paneId);
|
|
208
563
|
continue;
|
|
209
564
|
}
|
|
565
|
+
// Never let HUD-looking command text authorize a destructive pane mutation.
|
|
566
|
+
// Only metadata accepted by the strict owner parsers may do so.
|
|
567
|
+
if (!hasHudPaneOwnerMetadata(pane)) {
|
|
568
|
+
preserved.push(pane.paneId);
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
210
571
|
const leaderPaneId = readHudPaneOwner(pane).leaderPaneId;
|
|
211
572
|
if (!leaderPaneId) {
|
|
212
573
|
preserved.push(pane.paneId);
|
|
@@ -226,8 +587,10 @@ export function reapDeadHudPanes(panes, opts = {}) {
|
|
|
226
587
|
return { reaped, preserved };
|
|
227
588
|
}
|
|
228
589
|
export function parsePaneIdFromTmuxOutput(rawOutput) {
|
|
229
|
-
const
|
|
230
|
-
|
|
590
|
+
const lines = rawOutput.split('\n');
|
|
591
|
+
if (lines.at(-1) === '')
|
|
592
|
+
lines.pop();
|
|
593
|
+
return lines.length === 1 ? parseCanonicalTmuxPaneId(lines[0]) : null;
|
|
231
594
|
}
|
|
232
595
|
export function shellEscapeSingle(value) {
|
|
233
596
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
@@ -242,9 +605,6 @@ function isTmuxSessionId(value) {
|
|
|
242
605
|
function isTmuxWindowId(value) {
|
|
243
606
|
return /^@\d+$/.test(value);
|
|
244
607
|
}
|
|
245
|
-
function isTmuxPaneId(value) {
|
|
246
|
-
return /^%\d+$/.test(value);
|
|
247
|
-
}
|
|
248
608
|
export function buildHudResizeHookName(sessionId, windowId, leaderPaneId) {
|
|
249
609
|
return [
|
|
250
610
|
'omx_hud_resize',
|
|
@@ -253,13 +613,6 @@ export function buildHudResizeHookName(sessionId, windowId, leaderPaneId) {
|
|
|
253
613
|
normalizeTmuxHookToken(leaderPaneId),
|
|
254
614
|
].join('_');
|
|
255
615
|
}
|
|
256
|
-
function buildLegacyHudResizeHookName(sessionId, windowId) {
|
|
257
|
-
return [
|
|
258
|
-
'omx_hud_resize',
|
|
259
|
-
normalizeTmuxHookToken(sessionId),
|
|
260
|
-
normalizeTmuxHookToken(windowId),
|
|
261
|
-
].join('_');
|
|
262
|
-
}
|
|
263
616
|
export function buildHudResizeHookSlot(hookName) {
|
|
264
617
|
let hash = 0;
|
|
265
618
|
for (let i = 0; i < hookName.length; i++) {
|
|
@@ -274,35 +627,101 @@ export function buildHudLayoutHookSlot(hookName) {
|
|
|
274
627
|
}
|
|
275
628
|
return `window-layout-changed[${Math.abs(hash) % TMUX_HOOK_INDEX_MAX}]`;
|
|
276
629
|
}
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
630
|
+
function hudHookIdentityOption(hookSlot) {
|
|
631
|
+
const match = /^(client-resized|window-layout-changed)\[([0-9]+)\]$/.exec(hookSlot);
|
|
632
|
+
if (!match)
|
|
633
|
+
throw new Error('invalid_tmux_hook_slot');
|
|
634
|
+
return `@omx_hook_identity_${match[1].replaceAll('-', '_')}_${match[2]}`;
|
|
635
|
+
}
|
|
636
|
+
function hudHookIdentityToken(hookName, hookSlot) {
|
|
637
|
+
let hash = 2166136261;
|
|
638
|
+
for (const char of `${hookName}:${hookSlot}`)
|
|
639
|
+
hash = Math.imul(hash ^ char.charCodeAt(0), 16777619);
|
|
640
|
+
return `omx-${(hash >>> 0).toString(16)}`;
|
|
641
|
+
}
|
|
642
|
+
function buildHudHookRegistrationSuffix(context, hookSlot) {
|
|
643
|
+
return [
|
|
644
|
+
'\\;', 'set-option', '-t', context.sessionId,
|
|
645
|
+
hudHookIdentityOption(hookSlot), hudHookIdentityToken(context.hookName, hookSlot),
|
|
646
|
+
];
|
|
647
|
+
}
|
|
648
|
+
function buildGuardedHudHookUnregisterArgs(context, hookSlot) {
|
|
649
|
+
const identityOption = hudHookIdentityOption(hookSlot);
|
|
650
|
+
return [
|
|
651
|
+
'if-shell', '-F', '-t', context.sessionId,
|
|
652
|
+
`#{==:${identityOption},${hudHookIdentityToken(context.hookName, hookSlot)}}`,
|
|
653
|
+
`set-hook -u -t ${context.sessionId} ${hookSlot} \\; set-option -u -t ${context.sessionId} ${identityOption}`,
|
|
654
|
+
'',
|
|
655
|
+
];
|
|
656
|
+
}
|
|
657
|
+
function readHudResizeHookPaneIncarnations(hudPaneId, leaderPaneId, execTmuxSync) {
|
|
658
|
+
try {
|
|
659
|
+
const lines = parseExactTmuxAuthorityLines(execTmuxSync(['list-panes', '-a', '-F', '#{pane_id} #{pane_dead} #{pane_pid}']));
|
|
660
|
+
if (!lines)
|
|
661
|
+
return null;
|
|
662
|
+
const seen = new Set();
|
|
663
|
+
let leaderPanePid = null;
|
|
664
|
+
let hudPanePid = null;
|
|
665
|
+
for (const line of lines) {
|
|
666
|
+
const match = /^(%\S+) ([01]) ([1-9][0-9]*)$/.exec(line);
|
|
667
|
+
const paneId = match ? parseCanonicalTmuxPaneId(match[1]) : null;
|
|
668
|
+
if (!match || !paneId || paneId !== match[1] || seen.has(paneId))
|
|
669
|
+
return null;
|
|
670
|
+
seen.add(paneId);
|
|
671
|
+
if (match[2] === '1')
|
|
672
|
+
continue;
|
|
673
|
+
if (paneId === leaderPaneId)
|
|
674
|
+
leaderPanePid = match[3];
|
|
675
|
+
if (paneId === hudPaneId)
|
|
676
|
+
hudPanePid = match[3];
|
|
677
|
+
}
|
|
678
|
+
return leaderPanePid && hudPanePid ? { leaderPanePid, hudPanePid } : null;
|
|
679
|
+
}
|
|
680
|
+
catch {
|
|
681
|
+
return null;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
export function parseHudResizeHookContext(output, leaderPaneId, hudPaneId = leaderPaneId, incarnations = { leaderPanePid: '1', hudPanePid: '1' }) {
|
|
685
|
+
const line = parseExactTmuxAuthorityScalar(output);
|
|
686
|
+
if (line === null)
|
|
687
|
+
return null;
|
|
688
|
+
const parts = line.split('\t');
|
|
689
|
+
if (parts.length !== 2 || parts.some((part) => part.trim() !== part || part === ''))
|
|
690
|
+
return null;
|
|
691
|
+
const [sessionId = '', windowId = ''] = parts;
|
|
692
|
+
const normalizedLeaderPaneId = parseCanonicalTmuxPaneId(leaderPaneId);
|
|
693
|
+
const normalizedHudPaneId = parseCanonicalTmuxPaneId(hudPaneId);
|
|
694
|
+
if (!isTmuxSessionId(sessionId) || !isTmuxWindowId(windowId) || !normalizedLeaderPaneId || !normalizedHudPaneId)
|
|
284
695
|
return null;
|
|
285
696
|
const hookName = buildHudResizeHookName(sessionId, windowId, normalizedLeaderPaneId);
|
|
286
697
|
return {
|
|
287
698
|
sessionId,
|
|
288
699
|
windowId,
|
|
289
700
|
leaderPaneId: normalizedLeaderPaneId,
|
|
701
|
+
leaderPanePid: incarnations.leaderPanePid,
|
|
702
|
+
hudPaneId: normalizedHudPaneId,
|
|
703
|
+
hudPanePid: incarnations.hudPanePid,
|
|
290
704
|
hookName,
|
|
291
705
|
hookSlot: buildHudResizeHookSlot(hookName),
|
|
292
706
|
layoutHookSlot: buildHudLayoutHookSlot(hookName),
|
|
293
707
|
};
|
|
294
708
|
}
|
|
295
|
-
export function readHudResizeHookContext(leaderPaneId, execTmuxSync = defaultExecTmuxSync) {
|
|
296
|
-
|
|
709
|
+
export function readHudResizeHookContext(hudPaneId, leaderPaneId, execTmuxSync = defaultExecTmuxSync) {
|
|
710
|
+
const canonicalLeaderPaneId = parseCanonicalTmuxPaneId(leaderPaneId);
|
|
711
|
+
const canonicalHudPaneId = parseCanonicalTmuxPaneId(hudPaneId);
|
|
712
|
+
if (!canonicalLeaderPaneId || !canonicalHudPaneId)
|
|
713
|
+
return null;
|
|
714
|
+
const incarnations = readHudResizeHookPaneIncarnations(canonicalHudPaneId, canonicalLeaderPaneId, execTmuxSync);
|
|
715
|
+
if (!incarnations)
|
|
297
716
|
return null;
|
|
298
717
|
try {
|
|
299
718
|
return parseHudResizeHookContext(execTmuxSync([
|
|
300
719
|
'display-message',
|
|
301
720
|
'-p',
|
|
302
721
|
'-t',
|
|
303
|
-
|
|
722
|
+
canonicalLeaderPaneId,
|
|
304
723
|
'#{session_id}\t#{window_id}',
|
|
305
|
-
]),
|
|
724
|
+
]), canonicalLeaderPaneId, canonicalHudPaneId, incarnations);
|
|
306
725
|
}
|
|
307
726
|
catch {
|
|
308
727
|
return null;
|
|
@@ -312,22 +731,54 @@ function buildNestedTmuxCommand(tmuxBin, args, tmuxEnv) {
|
|
|
312
731
|
const command = [tmuxBin, ...args].map((part) => shellEscapeSingle(part)).join(' ');
|
|
313
732
|
return `${buildEnvPrefix({ TMUX: tmuxEnv })}${command}`;
|
|
314
733
|
}
|
|
315
|
-
function
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
734
|
+
function quoteHudHookShellArgument(value) {
|
|
735
|
+
return process.platform === 'win32'
|
|
736
|
+
? `'${value.replace(/'/g, "''")}'`
|
|
737
|
+
: shellEscapeSingle(value);
|
|
738
|
+
}
|
|
739
|
+
function buildHudHookIncarnationCondition(paneId, panePid) {
|
|
740
|
+
return `#{&&:#{==:#{pane_id},${paneId}},#{&&:#{==:#{pane_dead},0},#{==:#{pane_pid},${panePid}}}}`;
|
|
741
|
+
}
|
|
742
|
+
function buildHudHookSelfUnregister(context) {
|
|
743
|
+
const identityOption = hudHookIdentityOption(context.hookSlot);
|
|
744
|
+
return `if-shell -F -t ${context.sessionId} ${quoteHudHookShellArgument(`#{==:${identityOption},${hudHookIdentityToken(context.hookName, context.hookSlot)}}`)} ${quoteHudHookShellArgument(`set-hook -u -t ${context.sessionId} ${context.hookSlot} \\; set-option -u -t ${context.sessionId} ${identityOption}`)} ''`;
|
|
320
745
|
}
|
|
321
|
-
function
|
|
322
|
-
const
|
|
323
|
-
const
|
|
324
|
-
|
|
746
|
+
function buildAtomicHudHookCommand(tmuxBin, context, success, tmuxEnv) {
|
|
747
|
+
const unregister = buildHudHookSelfUnregister(context);
|
|
748
|
+
const hudConditional = [
|
|
749
|
+
'if-shell', '-F', '-t', context.hudPaneId,
|
|
750
|
+
quoteHudHookShellArgument(buildHudHookIncarnationCondition(context.hudPaneId, context.hudPanePid)),
|
|
751
|
+
quoteHudHookShellArgument(success),
|
|
752
|
+
quoteHudHookShellArgument(unregister),
|
|
753
|
+
].join(' ');
|
|
754
|
+
const args = [
|
|
755
|
+
'if-shell', '-F', '-t', context.leaderPaneId,
|
|
756
|
+
buildHudHookIncarnationCondition(context.leaderPaneId, context.leaderPanePid),
|
|
757
|
+
hudConditional,
|
|
758
|
+
unregister,
|
|
759
|
+
];
|
|
760
|
+
if (process.platform === 'win32') {
|
|
761
|
+
const quotePowerShell = (value) => `'${value.replace(/'/g, "''")}'`;
|
|
762
|
+
const invoke = `& ${quotePowerShell(tmuxBin)} ${args.map(quotePowerShell).join(' ')}`;
|
|
763
|
+
return tmuxEnv
|
|
764
|
+
? `& { $env:TMUX = ${quotePowerShell(tmuxEnv)}; ${invoke} } | Out-Null`
|
|
765
|
+
: `${invoke} | Out-Null`;
|
|
766
|
+
}
|
|
767
|
+
const command = buildNestedTmuxCommand(tmuxBin, args, tmuxEnv);
|
|
768
|
+
return `${command} >/dev/null 2>&1 || true`;
|
|
769
|
+
}
|
|
770
|
+
function buildAtomicHudResizeCommand(tmuxBin, hudPaneId, height, context, tmuxEnv) {
|
|
771
|
+
return buildAtomicHudHookCommand(tmuxBin, context, `resize-pane -t ${hudPaneId} -y ${height}`, tmuxEnv);
|
|
772
|
+
}
|
|
773
|
+
function buildHudResizeHookCommand(tmuxBin, hudPaneId, height, context, tmuxEnv) {
|
|
774
|
+
const atomicResize = buildAtomicHudResizeCommand(tmuxBin, hudPaneId, height, context, tmuxEnv);
|
|
775
|
+
return process.platform === 'win32'
|
|
776
|
+
? `${atomicResize}; Start-Sleep -Seconds ${HUD_RESIZE_RECONCILE_DELAY_SECONDS}; ${atomicResize}`
|
|
777
|
+
: `${atomicResize}; sleep ${HUD_RESIZE_RECONCILE_DELAY_SECONDS}; ${atomicResize}`;
|
|
325
778
|
}
|
|
326
779
|
function buildHudLayoutReconcileHookCommand(tmuxBin, omxBin, leaderPaneId, context, options = {}) {
|
|
327
780
|
const env = options.env ?? process.env;
|
|
328
781
|
const cwd = options.cwd?.trim() || process.cwd();
|
|
329
|
-
const leaderAlive = buildNestedTmuxCommand(tmuxBin, ['display-message', '-p', '-t', leaderPaneId, '#{pane_id}'], env.TMUX);
|
|
330
|
-
const unregister = buildHudHookUnregisterCommand(tmuxBin, context, env.TMUX);
|
|
331
782
|
const reconcileEnv = buildEnvPrefix({
|
|
332
783
|
TMUX: env.TMUX,
|
|
333
784
|
TMUX_PANE: leaderPaneId,
|
|
@@ -346,19 +797,20 @@ function buildHudLayoutReconcileHookCommand(tmuxBin, omxBin, leaderPaneId, conte
|
|
|
346
797
|
'hud',
|
|
347
798
|
'--reconcile-tmux',
|
|
348
799
|
].join(' ');
|
|
349
|
-
|
|
800
|
+
const layoutContext = { ...context, hookSlot: context.layoutHookSlot };
|
|
801
|
+
if (process.platform === 'win32') {
|
|
802
|
+
const nativeReconcile = `Set-Location -LiteralPath '${cwd.replace(/'/g, "''")}'; & '${process.execPath.replace(/'/g, "''")}' '${omxBin.replace(/'/g, "''")}' hud --reconcile-tmux | Out-Null`;
|
|
803
|
+
const success = `${buildHudHookSelfUnregister(layoutContext)} \\; run-shell -b ${quoteHudHookShellArgument(nativeReconcile)}`;
|
|
804
|
+
return buildAtomicHudHookCommand(tmuxBin, layoutContext, success, env.TMUX);
|
|
805
|
+
}
|
|
806
|
+
const success = `${buildHudHookSelfUnregister(layoutContext)} \\; run-shell -b ${quoteHudHookShellArgument(`${reconcile} >/dev/null 2>&1`)}`;
|
|
807
|
+
return buildAtomicHudHookCommand(tmuxBin, layoutContext, success, env.TMUX);
|
|
350
808
|
}
|
|
351
809
|
function unregisterLegacyHudResizeHook(context, execTmuxSync) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
execTmuxSync(['set-hook', '-u', '-t', context.sessionId, legacyHookSlot]);
|
|
357
|
-
}
|
|
358
|
-
catch {
|
|
359
|
-
// Best-effort migration cleanup: failure should not prevent the new
|
|
360
|
-
// leader-scoped hook from being registered or unregistered.
|
|
361
|
-
}
|
|
810
|
+
// Legacy registrations predate identity metadata. Leaving them untouched is
|
|
811
|
+
// safer than clearing a slot that may now belong to another registration.
|
|
812
|
+
void context;
|
|
813
|
+
void execTmuxSync;
|
|
362
814
|
}
|
|
363
815
|
function buildEnvPrefix(env) {
|
|
364
816
|
const assignments = Object.entries(env)
|
|
@@ -367,9 +819,34 @@ function buildEnvPrefix(env) {
|
|
|
367
819
|
.map(([key, value]) => `${key}=${shellEscapeSingle(value)}`);
|
|
368
820
|
return assignments.length > 0 ? `env ${assignments.join(' ')} ` : '';
|
|
369
821
|
}
|
|
822
|
+
/** The sole platform-aware serializer for tmux HUD watch commands. */
|
|
823
|
+
export function writeHudWatchCommand(options) {
|
|
824
|
+
const safePreset = options.preset === 'minimal' || options.preset === 'focused' || options.preset === 'full'
|
|
825
|
+
? `--preset=${options.preset}`
|
|
826
|
+
: undefined;
|
|
827
|
+
const platform = options.platform ?? process.platform;
|
|
828
|
+
const presetArgument = safePreset ? ` ${shellEscapeSingle(safePreset)}` : '';
|
|
829
|
+
if (platform === 'win32') {
|
|
830
|
+
const quotePowerShell = (value) => `'${value.replace(/'/g, "''")}'`;
|
|
831
|
+
const assignments = Object.entries(options.runtimeEnv)
|
|
832
|
+
.map(([key, value]) => `$env:${key} = ${quotePowerShell(value)}`)
|
|
833
|
+
.join('; ');
|
|
834
|
+
const invocation = ['&', quotePowerShell(options.nodeCommand), quotePowerShell(options.omxEntry), 'hud', '--watch', ...(safePreset ? [safePreset] : [])].join(' ');
|
|
835
|
+
const script = `${assignments}; ${invocation}`;
|
|
836
|
+
return options.powerShellEnvelope
|
|
837
|
+
? `powershell.exe -NoLogo -NoExit -Command ${quotePowerShell(script)}`
|
|
838
|
+
: script;
|
|
839
|
+
}
|
|
840
|
+
const assignments = Object.entries(options.runtimeEnv)
|
|
841
|
+
.map(([key, value]) => `${key}=${key === OMX_TMUX_HUD_OWNER_ENV && !options.quoteOwnerValue ? value : shellEscapeSingle(value)}`)
|
|
842
|
+
.join(' ');
|
|
843
|
+
const nodeCommand = options.nodeCommand === 'node' ? 'node' : shellEscapeSingle(options.nodeCommand);
|
|
844
|
+
return `exec ${assignments ? `env ${assignments} ` : ''}${nodeCommand} ${shellEscapeSingle(options.omxEntry)} hud --watch${presetArgument}`;
|
|
845
|
+
}
|
|
370
846
|
export function buildHudRuntimeEnv(input = {}) {
|
|
371
847
|
const sessionId = typeof input.sessionId === 'string' ? input.sessionId.trim() : '';
|
|
372
|
-
const
|
|
848
|
+
const rawLeaderPaneId = typeof input.leaderPaneId === 'string' ? input.leaderPaneId : '';
|
|
849
|
+
const leaderPaneId = rawLeaderPaneId ? parseCanonicalTmuxPaneId(rawLeaderPaneId) : null;
|
|
373
850
|
const env = {};
|
|
374
851
|
if (sessionId)
|
|
375
852
|
env.OMX_SESSION_ID = sessionId;
|
|
@@ -393,23 +870,40 @@ export function buildHudRuntimeEnv(input = {}) {
|
|
|
393
870
|
},
|
|
394
871
|
};
|
|
395
872
|
}
|
|
396
|
-
export function buildHudWatchCommand(omxBin, preset, sessionId, omxRoot, leaderPaneId, rootEnv) {
|
|
397
|
-
const
|
|
398
|
-
? ` --preset=${preset}`
|
|
399
|
-
: '';
|
|
400
|
-
const envPrefix = buildEnvPrefix(buildHudRuntimeEnv({
|
|
873
|
+
export function buildHudWatchCommand(omxBin, preset, sessionId, omxRoot, leaderPaneId, rootEnv, platform = process.platform) {
|
|
874
|
+
const runtimeEnv = buildHudRuntimeEnv({
|
|
401
875
|
sessionId,
|
|
402
876
|
leaderPaneId,
|
|
403
877
|
omxRoot,
|
|
404
878
|
...(rootEnv ?? { rootSource: 'omx-root-env' }),
|
|
405
|
-
}).env
|
|
406
|
-
return
|
|
879
|
+
}).env;
|
|
880
|
+
return writeHudWatchCommand({
|
|
881
|
+
omxEntry: omxBin,
|
|
882
|
+
runtimeEnv,
|
|
883
|
+
nodeCommand: process.execPath,
|
|
884
|
+
preset,
|
|
885
|
+
platform,
|
|
886
|
+
powerShellEnvelope: platform === 'win32',
|
|
887
|
+
quoteOwnerValue: true,
|
|
888
|
+
});
|
|
407
889
|
}
|
|
408
890
|
export function listCurrentWindowPanes(execTmuxSync = defaultExecTmuxSync, currentPaneId) {
|
|
891
|
+
const canonicalCurrentPaneId = currentPaneId ? parseCanonicalTmuxPaneId(currentPaneId) : null;
|
|
892
|
+
if (currentPaneId && !canonicalCurrentPaneId)
|
|
893
|
+
return [];
|
|
894
|
+
const targetArgs = canonicalCurrentPaneId ? ['-t', canonicalCurrentPaneId] : [];
|
|
409
895
|
try {
|
|
410
|
-
|
|
896
|
+
const paneIds = parseCanonicalPaneIdSnapshot(execTmuxSync([
|
|
897
|
+
'list-panes',
|
|
898
|
+
...targetArgs,
|
|
899
|
+
'-F',
|
|
900
|
+
'#{pane_id}',
|
|
901
|
+
]));
|
|
902
|
+
if (!paneIds)
|
|
903
|
+
return [];
|
|
904
|
+
const paneSnapshotOutput = execTmuxSync([
|
|
411
905
|
'list-panes',
|
|
412
|
-
...
|
|
906
|
+
...targetArgs,
|
|
413
907
|
'-F',
|
|
414
908
|
[
|
|
415
909
|
'#{pane_id}',
|
|
@@ -423,8 +917,13 @@ export function listCurrentWindowPanes(execTmuxSync = defaultExecTmuxSync, curre
|
|
|
423
917
|
'#{window_height}',
|
|
424
918
|
'#{pane_start_command}',
|
|
425
919
|
'#{pane_current_path}',
|
|
920
|
+
'#{pane_dead}',
|
|
921
|
+
'#{pane_pid}',
|
|
426
922
|
].join(TMUX_PANE_FIELD_SEPARATOR),
|
|
427
|
-
])
|
|
923
|
+
]);
|
|
924
|
+
if (!parseExactTmuxAuthorityLines(paneSnapshotOutput))
|
|
925
|
+
return [];
|
|
926
|
+
return parseTmuxPaneSnapshot(paneSnapshotOutput, paneIds);
|
|
428
927
|
}
|
|
429
928
|
catch {
|
|
430
929
|
return [];
|
|
@@ -432,7 +931,8 @@ export function listCurrentWindowPanes(execTmuxSync = defaultExecTmuxSync, curre
|
|
|
432
931
|
}
|
|
433
932
|
export function readActiveTmuxPaneId(execTmuxSync = defaultExecTmuxSync) {
|
|
434
933
|
try {
|
|
435
|
-
|
|
934
|
+
const paneId = parseExactTmuxAuthorityScalar(execTmuxSync(['display-message', '-p', '#{pane_id}']));
|
|
935
|
+
return parseCanonicalTmuxPaneId(paneId);
|
|
436
936
|
}
|
|
437
937
|
catch {
|
|
438
938
|
return null;
|
|
@@ -442,56 +942,429 @@ export function listCurrentWindowHudPaneIds(currentPaneId, execTmuxSync = defaul
|
|
|
442
942
|
return findHudWatchPaneIds(listCurrentWindowPanes(execTmuxSync, currentPaneId), currentPaneId, owner);
|
|
443
943
|
}
|
|
444
944
|
export function readCurrentWindowSize(execTmuxSync = defaultExecTmuxSync, currentPaneId) {
|
|
945
|
+
const canonicalCurrentPaneId = currentPaneId ? parseCanonicalTmuxPaneId(currentPaneId) : null;
|
|
946
|
+
if (currentPaneId && !canonicalCurrentPaneId)
|
|
947
|
+
return { width: null, height: null };
|
|
445
948
|
try {
|
|
446
949
|
const raw = execTmuxSync([
|
|
447
950
|
'display-message',
|
|
448
951
|
'-p',
|
|
449
|
-
...(
|
|
952
|
+
...(canonicalCurrentPaneId ? ['-t', canonicalCurrentPaneId] : []),
|
|
450
953
|
'#{window_width}\t#{window_height}',
|
|
451
954
|
]);
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
955
|
+
const framed = parseExactTmuxAuthorityScalar(raw);
|
|
956
|
+
if (framed === null)
|
|
957
|
+
return { width: null, height: null };
|
|
958
|
+
const fields = framed.split('\t');
|
|
959
|
+
if (fields.length !== 2)
|
|
960
|
+
return { width: null, height: null };
|
|
961
|
+
const width = parsePositiveInteger(fields[0]);
|
|
962
|
+
const height = parsePositiveInteger(fields[1]);
|
|
963
|
+
return { width, height };
|
|
459
964
|
}
|
|
460
965
|
catch {
|
|
461
966
|
return { width: null, height: null };
|
|
462
967
|
}
|
|
463
968
|
}
|
|
969
|
+
function readHudSplitSourceAuthority(targetPaneId, execTmuxSync) {
|
|
970
|
+
try {
|
|
971
|
+
const source = parseExactTmuxAuthorityScalar(execTmuxSync([
|
|
972
|
+
'display-message',
|
|
973
|
+
'-p',
|
|
974
|
+
...(targetPaneId ? ['-t', targetPaneId] : []),
|
|
975
|
+
'#{pane_id}\t#{pane_dead}\t#{pane_pid}\t#{session_id}\t#{window_id}',
|
|
976
|
+
]));
|
|
977
|
+
if (!source)
|
|
978
|
+
return null;
|
|
979
|
+
const fields = source.split('\t');
|
|
980
|
+
if (fields.length !== 5)
|
|
981
|
+
return null;
|
|
982
|
+
const paneId = parseCanonicalTmuxPaneId(fields[0]);
|
|
983
|
+
const paneDead = fields[1];
|
|
984
|
+
const panePid = fields[2];
|
|
985
|
+
const sessionId = fields[3];
|
|
986
|
+
const windowId = fields[4];
|
|
987
|
+
if (!paneId
|
|
988
|
+
|| (targetPaneId && paneId !== targetPaneId)
|
|
989
|
+
|| paneDead !== '0'
|
|
990
|
+
|| !/^[1-9][0-9]*$/.test(panePid ?? '')
|
|
991
|
+
|| !isTmuxSessionId(sessionId ?? '')
|
|
992
|
+
|| !isTmuxWindowId(windowId ?? ''))
|
|
993
|
+
return null;
|
|
994
|
+
return { paneId, panePid: panePid, sessionId: sessionId, windowId: windowId };
|
|
995
|
+
}
|
|
996
|
+
catch {
|
|
997
|
+
return null;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
function buildHudSplitSourceCondition(source) {
|
|
1001
|
+
return `#{&&:#{==:#{pane_id},${source.paneId}},#{&&:#{==:#{pane_dead},0},#{&&:#{==:#{pane_pid},${source.panePid}},#{&&:#{==:#{session_id},${source.sessionId}},#{==:#{window_id},${source.windowId}}}}}}`;
|
|
1002
|
+
}
|
|
1003
|
+
const hudSplitAuthorities = new Map();
|
|
1004
|
+
function readCanonicalPaneIdSnapshot(execTmuxSync, targetPaneId, global = false) {
|
|
1005
|
+
try {
|
|
1006
|
+
return parseCanonicalPaneIdSnapshot(execTmuxSync([
|
|
1007
|
+
'list-panes',
|
|
1008
|
+
...(global ? ['-a'] : targetPaneId ? ['-t', targetPaneId] : []),
|
|
1009
|
+
'-F',
|
|
1010
|
+
'#{pane_id}',
|
|
1011
|
+
]));
|
|
1012
|
+
}
|
|
1013
|
+
catch {
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
function deriveSingleNewPane(before, after) {
|
|
1018
|
+
if (after.size !== before.size + 1 || ![...before].every((paneId) => after.has(paneId)))
|
|
1019
|
+
return null;
|
|
1020
|
+
const created = [...after].filter((paneId) => !before.has(paneId));
|
|
1021
|
+
return created.length === 1 ? created[0] ?? null : null;
|
|
1022
|
+
}
|
|
1023
|
+
const OMX_TMUX_SPLIT_OPERATION_MARKER_ENV = 'OMX_TMUX_SPLIT_OPERATION_MARKER';
|
|
1024
|
+
function writeHudSplitOperationMarkedCommand(command, marker) {
|
|
1025
|
+
if (process.platform === 'win32')
|
|
1026
|
+
return `$env:${OMX_TMUX_SPLIT_OPERATION_MARKER_ENV} = '${marker}'; ${command}`;
|
|
1027
|
+
return `${OMX_TMUX_SPLIT_OPERATION_MARKER_ENV}='${marker}' ${command}`;
|
|
1028
|
+
}
|
|
1029
|
+
function hasHudSplitOperationMarker(startCommand, marker) {
|
|
1030
|
+
// tmux 3.2a wraps `pane_start_command` values containing special characters
|
|
1031
|
+
// in double quotes (e.g. `"OMX_TMUX_SPLIT_OPERATION_MARKER='<marker>' node omx.js hud --watch"`).
|
|
1032
|
+
// The marker must sit at the very start of the command, optionally inside that
|
|
1033
|
+
// wrapper, followed by a `;` (old export form) or ` ` (command-scoped assignment).
|
|
1034
|
+
// Mid-command mentions and marker-prefix collisions are never accepted.
|
|
1035
|
+
const posixMarker = `${OMX_TMUX_SPLIT_OPERATION_MARKER_ENV}='${marker}'`;
|
|
1036
|
+
const powerShellMarker = `$env:${OMX_TMUX_SPLIT_OPERATION_MARKER_ENV} = '${marker}'`;
|
|
1037
|
+
return [posixMarker, `"${posixMarker}`].some((prefix) => (startCommand === `${prefix}`
|
|
1038
|
+
|| startCommand === `${prefix}"`
|
|
1039
|
+
|| startCommand.startsWith(`${prefix};`)
|
|
1040
|
+
|| startCommand.startsWith(`${prefix} `)))
|
|
1041
|
+
|| [powerShellMarker, `"${powerShellMarker}`].some((prefix) => (startCommand === `${prefix}`
|
|
1042
|
+
|| startCommand === `${prefix}"`
|
|
1043
|
+
|| startCommand.startsWith(`${prefix};`)));
|
|
1044
|
+
}
|
|
1045
|
+
export function findHudSplitOperationMarkerPaneId(marker, execTmuxSync) {
|
|
1046
|
+
try {
|
|
1047
|
+
const lines = parseExactTmuxAuthorityLines(execTmuxSync(['list-panes', '-a', '-F', '#{pane_id}\t#{pane_start_command}']));
|
|
1048
|
+
if (!lines)
|
|
1049
|
+
return null;
|
|
1050
|
+
let candidate = null;
|
|
1051
|
+
const seen = new Set();
|
|
1052
|
+
for (const rawLine of lines) {
|
|
1053
|
+
const fields = rawLine.split('\t');
|
|
1054
|
+
if (fields.length !== 2)
|
|
1055
|
+
return null;
|
|
1056
|
+
const paneId = parseCanonicalTmuxPaneId(fields[0]);
|
|
1057
|
+
if (!paneId || paneId !== fields[0] || seen.has(paneId))
|
|
1058
|
+
return null;
|
|
1059
|
+
seen.add(paneId);
|
|
1060
|
+
const command = fields[1] ?? '';
|
|
1061
|
+
if (!hasHudSplitOperationMarker(command, marker))
|
|
1062
|
+
continue;
|
|
1063
|
+
if (candidate)
|
|
1064
|
+
return null;
|
|
1065
|
+
candidate = paneId;
|
|
1066
|
+
}
|
|
1067
|
+
return candidate;
|
|
1068
|
+
}
|
|
1069
|
+
catch {
|
|
1070
|
+
return null;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
function recoverHudSplitPaneId(globalBefore, targetBefore, targetPaneId, marker, execTmuxSync) {
|
|
1074
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
1075
|
+
const globalAfter = readCanonicalPaneIdSnapshot(execTmuxSync, undefined, true);
|
|
1076
|
+
const targetAfter = targetPaneId ? readCanonicalPaneIdSnapshot(execTmuxSync, targetPaneId) : null;
|
|
1077
|
+
const globalCandidate = globalAfter ? deriveSingleNewPane(globalBefore, globalAfter) : null;
|
|
1078
|
+
const targetCandidate = targetPaneId ? (targetAfter ? deriveSingleNewPane(targetBefore, targetAfter) : null) : globalCandidate;
|
|
1079
|
+
const markerCandidate = findHudSplitOperationMarkerPaneId(marker, execTmuxSync);
|
|
1080
|
+
if (globalCandidate && globalCandidate === targetCandidate && markerCandidate === globalCandidate)
|
|
1081
|
+
return globalCandidate;
|
|
1082
|
+
if (markerCandidate && !globalBefore.has(markerCandidate))
|
|
1083
|
+
return markerCandidate;
|
|
1084
|
+
if (attempt < 2)
|
|
1085
|
+
sleepSync(50);
|
|
1086
|
+
}
|
|
1087
|
+
return null;
|
|
1088
|
+
}
|
|
1089
|
+
function sleepSync(milliseconds) {
|
|
1090
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
|
|
1091
|
+
}
|
|
1092
|
+
function readTmuxOptionExactly(execTmuxSync, option) {
|
|
1093
|
+
try {
|
|
1094
|
+
return parseExactTmuxAuthorityScalar(execTmuxSync(['show-options', '-g', '-v', option]));
|
|
1095
|
+
}
|
|
1096
|
+
catch {
|
|
1097
|
+
return null;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
function hasHudSplitAuthority(paneId, execTmuxSync = defaultExecTmuxSync) {
|
|
1101
|
+
const authority = hudSplitAuthorities.get(paneId);
|
|
1102
|
+
if (!authority)
|
|
1103
|
+
return false;
|
|
1104
|
+
const globalPanes = readCanonicalPaneIdSnapshot(execTmuxSync, undefined, true);
|
|
1105
|
+
if (!globalPanes?.has(paneId))
|
|
1106
|
+
return false;
|
|
1107
|
+
if (authority.targetPaneId) {
|
|
1108
|
+
const targetPanes = readCanonicalPaneIdSnapshot(execTmuxSync, authority.targetPaneId);
|
|
1109
|
+
if (!targetPanes?.has(paneId))
|
|
1110
|
+
return false;
|
|
1111
|
+
}
|
|
1112
|
+
const location = readHudPaneSessionAndWindow(paneId, execTmuxSync);
|
|
1113
|
+
return (findHudSplitOperationMarkerPaneId(authority.operationMarker, execTmuxSync) === paneId
|
|
1114
|
+
&& readHudPaneIncarnation(paneId, execTmuxSync)?.panePid === authority.panePid
|
|
1115
|
+
&& location?.sessionId === authority.sessionId
|
|
1116
|
+
&& location?.windowId === authority.windowId
|
|
1117
|
+
&& readTmuxOptionExactly(execTmuxSync, authority.proofOption) === authority.proofValue);
|
|
1118
|
+
}
|
|
1119
|
+
function readHudPaneIncarnation(paneId, execTmuxSync) {
|
|
1120
|
+
try {
|
|
1121
|
+
const lines = parseExactTmuxAuthorityLines(execTmuxSync(['list-panes', '-a', '-F', '#{pane_id} #{pane_dead} #{pane_pid}']));
|
|
1122
|
+
if (!lines)
|
|
1123
|
+
return null;
|
|
1124
|
+
const seenPaneIds = new Set();
|
|
1125
|
+
let incarnation = null;
|
|
1126
|
+
for (const line of lines) {
|
|
1127
|
+
const match = /^(%\S+) ([01]) ([0-9]+)$/.exec(line);
|
|
1128
|
+
const observedPaneId = match ? parseCanonicalTmuxPaneId(match[1]) : null;
|
|
1129
|
+
if (!match || !observedPaneId || observedPaneId !== match[1] || seenPaneIds.has(observedPaneId))
|
|
1130
|
+
return null;
|
|
1131
|
+
seenPaneIds.add(observedPaneId);
|
|
1132
|
+
if (match[2] === '1')
|
|
1133
|
+
continue;
|
|
1134
|
+
if (!/^[1-9][0-9]*$/.test(match[3]))
|
|
1135
|
+
return null;
|
|
1136
|
+
if (observedPaneId === paneId)
|
|
1137
|
+
incarnation = { paneDead: false, panePid: match[3] };
|
|
1138
|
+
}
|
|
1139
|
+
return incarnation;
|
|
1140
|
+
}
|
|
1141
|
+
catch {
|
|
1142
|
+
return null;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
function isPaneLiveInStrictGlobalProbe(paneId, expectedPid, execTmuxSync) {
|
|
1146
|
+
const incarnation = readHudPaneIncarnation(paneId, execTmuxSync);
|
|
1147
|
+
return Boolean(incarnation && !incarnation.paneDead && (!expectedPid || incarnation.panePid === expectedPid));
|
|
1148
|
+
}
|
|
1149
|
+
/** Freshly validates retained split proof and sustained global liveness before a HUD mutation sink. */
|
|
1150
|
+
export function verifyHudWatchPaneAuthority(paneId, execTmuxSync = defaultExecTmuxSync) {
|
|
1151
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1152
|
+
if (!canonicalPaneId || !hasHudSplitAuthority(canonicalPaneId, execTmuxSync))
|
|
1153
|
+
return false;
|
|
1154
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
1155
|
+
if (attempt > 0)
|
|
1156
|
+
sleepSync(100);
|
|
1157
|
+
if (!hasHudSplitAuthority(canonicalPaneId, execTmuxSync)
|
|
1158
|
+
|| !isPaneLiveInStrictGlobalProbe(canonicalPaneId, hudSplitAuthorities.get(canonicalPaneId)?.panePid, execTmuxSync))
|
|
1159
|
+
return false;
|
|
1160
|
+
}
|
|
1161
|
+
return true;
|
|
1162
|
+
}
|
|
1163
|
+
/** Kills only a pane still bound to this process's exact split proof. */
|
|
1164
|
+
export function rollbackHudWatchPaneAuthority(paneId, execTmuxSync = defaultExecTmuxSync) {
|
|
1165
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1166
|
+
const authority = canonicalPaneId ? hudSplitAuthorities.get(canonicalPaneId) : undefined;
|
|
1167
|
+
if (!canonicalPaneId || !authority)
|
|
1168
|
+
return false;
|
|
1169
|
+
const killed = mutateHudWatchPaneIfCurrent(canonicalPaneId, authority.panePid, `kill-pane -t ${canonicalPaneId}`, execTmuxSync);
|
|
1170
|
+
if (killed)
|
|
1171
|
+
hudSplitAuthorities.delete(canonicalPaneId);
|
|
1172
|
+
return killed;
|
|
1173
|
+
}
|
|
1174
|
+
function rollbackRecoveredHudSplitPane(paneId, proofOption, proofValue, operationMarker, panePid, sessionId, windowId, execTmuxSync = defaultExecTmuxSync) {
|
|
1175
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1176
|
+
if (!canonicalPaneId || canonicalPaneId !== paneId)
|
|
1177
|
+
return false;
|
|
1178
|
+
const pidCondition = panePid && /^[1-9][0-9]*$/.test(panePid) ? `#{&&:#{==:#{pane_pid},${panePid}},` : '';
|
|
1179
|
+
const sessionCondition = sessionId && /^\$[0-9]+$/.test(sessionId) ? `#{&&:#{==:#{session_id},${sessionId}},` : '';
|
|
1180
|
+
const windowCondition = windowId && /^@[0-9]+$/.test(windowId) ? `#{&&:#{==:#{window_id},${windowId}},` : '';
|
|
1181
|
+
const closes = `${pidCondition ? '}' : ''}${sessionCondition ? '}' : ''}${windowCondition ? '}' : ''}`;
|
|
1182
|
+
const receipt = `__omx_hud_rollback_${randomUUID()}`;
|
|
1183
|
+
const condition = `#{&&:#{==:#{pane_id},${paneId}},#{&&:#{==:#{pane_dead},0},${pidCondition}${sessionCondition}${windowCondition}#{&&:#{==:#{${proofOption}},${proofValue}},#{m:*${operationMarker}*,#{pane_start_command}}}${closes}}`;
|
|
1184
|
+
try {
|
|
1185
|
+
return parseExactTmuxAuthorityScalar(execTmuxSync([
|
|
1186
|
+
'if-shell', '-F', '-t', paneId,
|
|
1187
|
+
condition,
|
|
1188
|
+
`kill-pane -t ${paneId} \\; display-message -p ${receipt}`,
|
|
1189
|
+
`display-message -p __omx_hud_rollback_rejected_${receipt}`,
|
|
1190
|
+
])) === receipt;
|
|
1191
|
+
}
|
|
1192
|
+
catch {
|
|
1193
|
+
return false;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
464
1196
|
export function createHudWatchPane(cwd, hudCmd, options = {}, execTmuxSync = defaultExecTmuxSync) {
|
|
1197
|
+
const canonicalTargetPaneId = options.targetPaneId ? parseCanonicalTmuxPaneId(options.targetPaneId) : null;
|
|
1198
|
+
if (options.targetPaneId && !canonicalTargetPaneId)
|
|
1199
|
+
return null;
|
|
1200
|
+
const sourceAuthority = readHudSplitSourceAuthority(canonicalTargetPaneId, execTmuxSync);
|
|
1201
|
+
if (!sourceAuthority)
|
|
1202
|
+
return null;
|
|
1203
|
+
const sourcePaneId = sourceAuthority.paneId;
|
|
1204
|
+
const globalBefore = readCanonicalPaneIdSnapshot(execTmuxSync, undefined, true);
|
|
1205
|
+
const targetBefore = readCanonicalPaneIdSnapshot(execTmuxSync, sourcePaneId);
|
|
1206
|
+
if (!globalBefore || !targetBefore)
|
|
1207
|
+
return null;
|
|
1208
|
+
const operationMarker = randomUUID();
|
|
465
1209
|
const heightLines = Number.isFinite(options.heightLines) && (options.heightLines ?? 0) > 0
|
|
466
1210
|
? Math.floor(options.heightLines ?? HUD_TMUX_HEIGHT_LINES)
|
|
467
1211
|
: HUD_TMUX_HEIGHT_LINES;
|
|
468
1212
|
const args = [
|
|
469
|
-
'split-window',
|
|
470
|
-
'-
|
|
471
|
-
...(options.fullWidth ? ['-f'] : []),
|
|
472
|
-
'-l',
|
|
473
|
-
String(heightLines),
|
|
474
|
-
'-d',
|
|
475
|
-
...(options.targetPaneId ? ['-t', options.targetPaneId] : []),
|
|
476
|
-
'-c',
|
|
477
|
-
cwd,
|
|
478
|
-
'-P',
|
|
479
|
-
'-F',
|
|
480
|
-
'#{pane_id}',
|
|
481
|
-
hudCmd,
|
|
1213
|
+
'split-window', '-v', ...(options.fullWidth ? ['-f'] : []), '-l', String(heightLines), '-d',
|
|
1214
|
+
'-t', sourcePaneId, '-c', shellEscapeSingle(cwd), shellEscapeSingle(writeHudSplitOperationMarkedCommand(hudCmd, operationMarker)),
|
|
482
1215
|
];
|
|
1216
|
+
let paneId = null;
|
|
1217
|
+
const nonce = randomUUID();
|
|
1218
|
+
const proofOption = `@omx_hud_split_owner_nonce_${nonce}`;
|
|
1219
|
+
const provisionalProof = `pending:${nonce}`;
|
|
1220
|
+
const receipt = `__omx_hud_split_${randomUUID()}`;
|
|
1221
|
+
const splitCommand = args.join(' ');
|
|
1222
|
+
try {
|
|
1223
|
+
execTmuxSync(['set-option', '-g', proofOption, provisionalProof]);
|
|
1224
|
+
if (readTmuxOptionExactly(execTmuxSync, proofOption) !== provisionalProof)
|
|
1225
|
+
return null;
|
|
1226
|
+
const splitOutput = execTmuxSync([
|
|
1227
|
+
'if-shell', '-F', '-t', sourcePaneId, buildHudSplitSourceCondition(sourceAuthority),
|
|
1228
|
+
`${splitCommand} ; display-message -p ${receipt}`,
|
|
1229
|
+
`display-message -p __omx_hud_split_rejected_${receipt}`,
|
|
1230
|
+
]);
|
|
1231
|
+
if (parseExactTmuxAuthorityScalar(splitOutput) !== receipt)
|
|
1232
|
+
return null;
|
|
1233
|
+
paneId = recoverHudSplitPaneId(globalBefore, targetBefore, sourcePaneId, operationMarker, execTmuxSync);
|
|
1234
|
+
const incarnation = paneId ? readHudPaneIncarnation(paneId, execTmuxSync) : null;
|
|
1235
|
+
const location = paneId ? readHudPaneSessionAndWindow(paneId, execTmuxSync) : null;
|
|
1236
|
+
if (!paneId
|
|
1237
|
+
|| !incarnation
|
|
1238
|
+
|| !location
|
|
1239
|
+
|| location.sessionId !== sourceAuthority.sessionId
|
|
1240
|
+
|| location.windowId !== sourceAuthority.windowId) {
|
|
1241
|
+
if (paneId) {
|
|
1242
|
+
rollbackRecoveredHudSplitPane(paneId, proofOption, provisionalProof, operationMarker, incarnation?.panePid, location?.sessionId ?? sourceAuthority.sessionId, location?.windowId ?? sourceAuthority.windowId, execTmuxSync);
|
|
1243
|
+
}
|
|
1244
|
+
return null;
|
|
1245
|
+
}
|
|
1246
|
+
hudSplitAuthorities.set(paneId, {
|
|
1247
|
+
proofOption,
|
|
1248
|
+
proofValue: provisionalProof,
|
|
1249
|
+
operationMarker,
|
|
1250
|
+
panePid: incarnation.panePid,
|
|
1251
|
+
sessionId: location.sessionId,
|
|
1252
|
+
windowId: location.windowId,
|
|
1253
|
+
targetPaneId: sourcePaneId,
|
|
1254
|
+
});
|
|
1255
|
+
if (!hasHudSplitAuthority(paneId, execTmuxSync)) {
|
|
1256
|
+
rollbackHudWatchPaneAuthority(paneId, execTmuxSync);
|
|
1257
|
+
return null;
|
|
1258
|
+
}
|
|
1259
|
+
const proofValue = `${paneId}:split:${nonce}`;
|
|
1260
|
+
execTmuxSync(['set-option', '-g', proofOption, proofValue]);
|
|
1261
|
+
hudSplitAuthorities.set(paneId, { proofOption, proofValue, operationMarker, panePid: incarnation.panePid, sessionId: location.sessionId, windowId: location.windowId, targetPaneId: sourcePaneId });
|
|
1262
|
+
if (readTmuxOptionExactly(execTmuxSync, proofOption) !== proofValue) {
|
|
1263
|
+
rollbackHudWatchPaneAuthority(paneId, execTmuxSync);
|
|
1264
|
+
return null;
|
|
1265
|
+
}
|
|
1266
|
+
if (!verifyHudWatchPaneAuthority(paneId, execTmuxSync)) {
|
|
1267
|
+
rollbackHudWatchPaneAuthority(paneId, execTmuxSync);
|
|
1268
|
+
return null;
|
|
1269
|
+
}
|
|
1270
|
+
return paneId;
|
|
1271
|
+
}
|
|
1272
|
+
catch {
|
|
1273
|
+
if (paneId) {
|
|
1274
|
+
rollbackHudWatchPaneAuthority(paneId, execTmuxSync);
|
|
1275
|
+
}
|
|
1276
|
+
else {
|
|
1277
|
+
const recoveredPaneId = recoverHudSplitPaneId(globalBefore, targetBefore, sourcePaneId, operationMarker, execTmuxSync);
|
|
1278
|
+
if (recoveredPaneId) {
|
|
1279
|
+
rollbackRecoveredHudSplitPane(recoveredPaneId, proofOption, provisionalProof, operationMarker, undefined, sourceAuthority.sessionId, sourceAuthority.windowId, execTmuxSync);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
return null;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
function readHudPaneSessionAndWindow(paneId, execTmuxSync) {
|
|
483
1286
|
try {
|
|
484
|
-
|
|
1287
|
+
const value = parseExactTmuxAuthorityScalar(execTmuxSync([
|
|
1288
|
+
'display-message', '-p', '-t', paneId, '#{session_id}\t#{window_id}',
|
|
1289
|
+
]));
|
|
1290
|
+
if (!value)
|
|
1291
|
+
return null;
|
|
1292
|
+
const [sessionId, windowId, ...extra] = value.split('\t');
|
|
1293
|
+
return !extra.length && isTmuxSessionId(sessionId ?? '') && isTmuxWindowId(windowId ?? '')
|
|
1294
|
+
? { sessionId: sessionId, windowId: windowId }
|
|
1295
|
+
: null;
|
|
485
1296
|
}
|
|
486
1297
|
catch {
|
|
487
1298
|
return null;
|
|
488
1299
|
}
|
|
489
1300
|
}
|
|
1301
|
+
/** Executes a split-owned pane mutation only while its immutable owner proof and exact incarnation remain current. */
|
|
1302
|
+
export function mutateHudWatchPaneIfCurrent(paneId, expectedPanePid, mutation, execTmuxSync = defaultExecTmuxSync) {
|
|
1303
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1304
|
+
const authority = canonicalPaneId ? hudSplitAuthorities.get(canonicalPaneId) : undefined;
|
|
1305
|
+
if (!canonicalPaneId
|
|
1306
|
+
|| !authority
|
|
1307
|
+
|| authority.panePid !== expectedPanePid
|
|
1308
|
+
|| !/^[1-9][0-9]*$/.test(expectedPanePid)
|
|
1309
|
+
|| !/^(?:kill-pane|resize-pane) -t %(?:0|[1-9][0-9]*)(?: -y [1-9][0-9]*)?$/.test(mutation))
|
|
1310
|
+
return false;
|
|
1311
|
+
const marker = `__omx_hud_mutation_${randomUUID()}`;
|
|
1312
|
+
const condition = `#{&&:#{==:#{pane_id},${canonicalPaneId}},#{&&:#{==:#{pane_dead},0},#{&&:#{==:#{pane_pid},${expectedPanePid}},#{&&:#{==:#{session_id},${authority.sessionId}},#{&&:#{==:#{window_id},${authority.windowId}},#{&&:#{==:#{${authority.proofOption}},${authority.proofValue}},#{m:*${authority.operationMarker}*,#{pane_start_command}}}}}}}`;
|
|
1313
|
+
try {
|
|
1314
|
+
const output = execTmuxSync([
|
|
1315
|
+
'if-shell', '-F', '-t', canonicalPaneId,
|
|
1316
|
+
condition,
|
|
1317
|
+
`${mutation} \\; display-message -p ${marker}`,
|
|
1318
|
+
`display-message -p __omx_hud_mutation_failed_${marker}`,
|
|
1319
|
+
]);
|
|
1320
|
+
return parseExactTmuxAuthorityScalar(output) === marker;
|
|
1321
|
+
}
|
|
1322
|
+
catch {
|
|
1323
|
+
return false;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
/** Executes a retained pane mutation only while the exact target incarnation remains live. */
|
|
1327
|
+
function mutateTmuxPaneIfCurrent(paneId, expectedPanePid, mutation, execTmuxSync = defaultExecTmuxSync) {
|
|
1328
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1329
|
+
if (!canonicalPaneId || !/^[1-9][0-9]*$/.test(expectedPanePid))
|
|
1330
|
+
return false;
|
|
1331
|
+
const marker = `__omx_hud_mutation_${randomUUID()}`;
|
|
1332
|
+
try {
|
|
1333
|
+
const output = execTmuxSync([
|
|
1334
|
+
'if-shell', '-F', '-t', canonicalPaneId,
|
|
1335
|
+
buildHudHookIncarnationCondition(canonicalPaneId, expectedPanePid),
|
|
1336
|
+
`${mutation} \\; display-message -p ${marker}`,
|
|
1337
|
+
`display-message -p __omx_hud_mutation_failed_${marker}`,
|
|
1338
|
+
]);
|
|
1339
|
+
return parseExactTmuxAuthorityScalar(output) === marker;
|
|
1340
|
+
}
|
|
1341
|
+
catch {
|
|
1342
|
+
return false;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
/** Kills a pane only while its exact live incarnation remains the target. */
|
|
1346
|
+
export function killTmuxPaneIfCurrent(paneId, expectedPanePid, execTmuxSync = defaultExecTmuxSync) {
|
|
1347
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1348
|
+
return canonicalPaneId
|
|
1349
|
+
? mutateTmuxPaneIfCurrent(canonicalPaneId, expectedPanePid, `kill-pane -t ${canonicalPaneId}`, execTmuxSync)
|
|
1350
|
+
: false;
|
|
1351
|
+
}
|
|
1352
|
+
/** Resizes a pane only while its exact live incarnation remains the target. */
|
|
1353
|
+
export function resizeTmuxPaneIfCurrent(paneId, expectedPanePid, heightLines, execTmuxSync = defaultExecTmuxSync) {
|
|
1354
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1355
|
+
if (!canonicalPaneId)
|
|
1356
|
+
return false;
|
|
1357
|
+
const height = Number.isFinite(heightLines) && heightLines > 0
|
|
1358
|
+
? Math.floor(heightLines)
|
|
1359
|
+
: HUD_TMUX_HEIGHT_LINES;
|
|
1360
|
+
return mutateTmuxPaneIfCurrent(canonicalPaneId, expectedPanePid, `resize-pane -t ${canonicalPaneId} -y ${height}`, execTmuxSync);
|
|
1361
|
+
}
|
|
490
1362
|
export function killTmuxPane(paneId, execTmuxSync = defaultExecTmuxSync) {
|
|
491
|
-
|
|
1363
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1364
|
+
if (!canonicalPaneId)
|
|
492
1365
|
return false;
|
|
493
1366
|
try {
|
|
494
|
-
execTmuxSync(['kill-pane', '-t',
|
|
1367
|
+
execTmuxSync(['kill-pane', '-t', canonicalPaneId]);
|
|
495
1368
|
return true;
|
|
496
1369
|
}
|
|
497
1370
|
catch {
|
|
@@ -499,13 +1372,14 @@ export function killTmuxPane(paneId, execTmuxSync = defaultExecTmuxSync) {
|
|
|
499
1372
|
}
|
|
500
1373
|
}
|
|
501
1374
|
export function resizeTmuxPane(paneId, heightLines, execTmuxSync = defaultExecTmuxSync) {
|
|
502
|
-
|
|
1375
|
+
const canonicalPaneId = parseCanonicalTmuxPaneId(paneId);
|
|
1376
|
+
if (!canonicalPaneId)
|
|
503
1377
|
return false;
|
|
504
1378
|
const height = Number.isFinite(heightLines) && heightLines > 0
|
|
505
1379
|
? Math.floor(heightLines)
|
|
506
1380
|
: HUD_TMUX_HEIGHT_LINES;
|
|
507
1381
|
try {
|
|
508
|
-
execTmuxSync(['resize-pane', '-t',
|
|
1382
|
+
execTmuxSync(['resize-pane', '-t', canonicalPaneId, '-y', String(height)]);
|
|
509
1383
|
return true;
|
|
510
1384
|
}
|
|
511
1385
|
catch {
|
|
@@ -517,26 +1391,28 @@ export function registerHudResizeHook(hudPaneId, leaderPaneId, heightLines, opti
|
|
|
517
1391
|
const execTmuxSync = typeof optionsOrExecTmuxSync === 'function'
|
|
518
1392
|
? optionsOrExecTmuxSync
|
|
519
1393
|
: (maybeExecTmuxSync ?? defaultExecTmuxSync);
|
|
520
|
-
|
|
1394
|
+
const canonicalHudPaneId = parseCanonicalTmuxPaneId(hudPaneId);
|
|
1395
|
+
const canonicalLeaderPaneId = parseCanonicalTmuxPaneId(leaderPaneId);
|
|
1396
|
+
if (!canonicalHudPaneId || !canonicalLeaderPaneId)
|
|
521
1397
|
return false;
|
|
522
|
-
const context = readHudResizeHookContext(
|
|
1398
|
+
const context = readHudResizeHookContext(canonicalHudPaneId, canonicalLeaderPaneId, execTmuxSync);
|
|
523
1399
|
if (!context)
|
|
524
1400
|
return false;
|
|
525
1401
|
const tmuxBin = resolveTmuxBinaryForPlatform() || 'tmux';
|
|
526
1402
|
const height = String(Math.max(1, Math.floor(heightLines)));
|
|
527
|
-
const resizeCmd = shellEscapeSingle(buildHudResizeHookCommand(tmuxBin,
|
|
1403
|
+
const resizeCmd = shellEscapeSingle(buildHudResizeHookCommand(tmuxBin, canonicalHudPaneId, height, context, options.env?.TMUX));
|
|
528
1404
|
const omxBin = resolveOmxCliEntryPath({ cwd: options.cwd, env: options.env });
|
|
529
1405
|
try {
|
|
530
|
-
execTmuxSync(['set-hook', '-t', context.sessionId, context.hookSlot, `run-shell -b ${resizeCmd}
|
|
1406
|
+
execTmuxSync(['set-hook', '-t', context.sessionId, context.hookSlot, `run-shell -b ${resizeCmd}`, ...buildHudHookRegistrationSuffix(context, context.hookSlot)]);
|
|
531
1407
|
unregisterLegacyHudResizeHook(context, execTmuxSync);
|
|
532
1408
|
}
|
|
533
1409
|
catch {
|
|
534
1410
|
return false;
|
|
535
1411
|
}
|
|
536
|
-
if (omxBin
|
|
1412
|
+
if (omxBin) {
|
|
537
1413
|
try {
|
|
538
|
-
const reconcileCmd = shellEscapeSingle(buildHudLayoutReconcileHookCommand(tmuxBin, omxBin,
|
|
539
|
-
execTmuxSync(['set-hook', '-t', context.sessionId, context.layoutHookSlot, `run-shell -b ${reconcileCmd}
|
|
1414
|
+
const reconcileCmd = shellEscapeSingle(buildHudLayoutReconcileHookCommand(tmuxBin, omxBin, canonicalLeaderPaneId, context, options));
|
|
1415
|
+
execTmuxSync(['set-hook', '-t', context.sessionId, context.layoutHookSlot, `run-shell -b ${reconcileCmd}`, ...buildHudHookRegistrationSuffix(context, context.layoutHookSlot)]);
|
|
540
1416
|
}
|
|
541
1417
|
catch {
|
|
542
1418
|
// Keep the resize hook installed so older tmux builds still recover on
|
|
@@ -547,19 +1423,29 @@ export function registerHudResizeHook(hudPaneId, leaderPaneId, heightLines, opti
|
|
|
547
1423
|
return true;
|
|
548
1424
|
}
|
|
549
1425
|
export function unregisterHudResizeHook(leaderPaneId, execTmuxSync = defaultExecTmuxSync) {
|
|
550
|
-
const
|
|
1426
|
+
const canonicalLeaderPaneId = parseCanonicalTmuxPaneId(leaderPaneId);
|
|
1427
|
+
if (!canonicalLeaderPaneId)
|
|
1428
|
+
return false;
|
|
1429
|
+
let contextOutput;
|
|
1430
|
+
try {
|
|
1431
|
+
contextOutput = execTmuxSync(['display-message', '-p', '-t', canonicalLeaderPaneId, '#{session_id}\t#{window_id}']);
|
|
1432
|
+
}
|
|
1433
|
+
catch {
|
|
1434
|
+
return false;
|
|
1435
|
+
}
|
|
1436
|
+
const context = parseHudResizeHookContext(contextOutput, canonicalLeaderPaneId, canonicalLeaderPaneId, { leaderPanePid: '1', hudPanePid: '1' });
|
|
551
1437
|
if (!context)
|
|
552
1438
|
return false;
|
|
553
1439
|
let ok = true;
|
|
554
1440
|
try {
|
|
555
1441
|
unregisterLegacyHudResizeHook(context, execTmuxSync);
|
|
556
|
-
execTmuxSync(
|
|
1442
|
+
execTmuxSync(buildGuardedHudHookUnregisterArgs(context, context.hookSlot));
|
|
557
1443
|
}
|
|
558
1444
|
catch {
|
|
559
1445
|
ok = false;
|
|
560
1446
|
}
|
|
561
1447
|
try {
|
|
562
|
-
execTmuxSync(
|
|
1448
|
+
execTmuxSync(buildGuardedHudHookUnregisterArgs(context, context.layoutHookSlot));
|
|
563
1449
|
}
|
|
564
1450
|
catch {
|
|
565
1451
|
ok = false;
|