oh-my-codex 0.11.11 → 0.11.13
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 +5 -5
- package/Cargo.toml +1 -1
- package/README.de.md +12 -6
- package/README.el.md +223 -0
- package/README.es.md +12 -6
- package/README.fr.md +11 -5
- package/README.it.md +12 -6
- package/README.ja.md +12 -6
- package/README.ko.md +12 -6
- package/README.md +56 -28
- package/README.pl.md +216 -0
- package/README.pt.md +12 -6
- package/README.ru.md +12 -6
- package/README.tr.md +12 -6
- package/README.vi.md +148 -183
- package/README.zh-TW.md +14 -17
- package/README.zh.md +12 -6
- package/crates/omx-runtime-core/src/engine.rs +122 -4
- package/crates/omx-runtime-core/src/lib.rs +17 -0
- package/dist/autoresearch/contracts.d.ts.map +1 -1
- package/dist/autoresearch/contracts.js +1 -0
- package/dist/autoresearch/contracts.js.map +1 -1
- package/dist/autoresearch/runtime.d.ts.map +1 -1
- package/dist/autoresearch/runtime.js +7 -1
- package/dist/autoresearch/runtime.js.map +1 -1
- package/dist/cli/__tests__/agents.test.js +24 -1
- package/dist/cli/__tests__/agents.test.js.map +1 -1
- package/dist/cli/__tests__/autoresearch.test.js +11 -0
- package/dist/cli/__tests__/autoresearch.test.js.map +1 -1
- package/dist/cli/__tests__/cleanup.test.js +117 -4
- package/dist/cli/__tests__/cleanup.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +33 -3
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/error-handling-warnings.test.js +13 -0
- package/dist/cli/__tests__/error-handling-warnings.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +6 -0
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +101 -1
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +3 -0
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/package-bin-contract.test.js +10 -0
- package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
- package/dist/cli/__tests__/packaged-script-resolution.test.js +4 -3
- package/dist/cli/__tests__/packaged-script-resolution.test.js.map +1 -1
- package/dist/cli/__tests__/resume.test.js +6 -0
- package/dist/cli/__tests__/resume.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +29 -12
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-scope.test.js +1 -1
- package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
- package/dist/cli/__tests__/star-prompt.test.js +16 -0
- package/dist/cli/__tests__/star-prompt.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +112 -1
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts +2 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.d.ts.map +1 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +30 -0
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -0
- package/dist/cli/agents.d.ts.map +1 -1
- package/dist/cli/agents.js +9 -3
- package/dist/cli/agents.js.map +1 -1
- package/dist/cli/autoresearch-guided.d.ts.map +1 -1
- package/dist/cli/autoresearch-guided.js +9 -3
- package/dist/cli/autoresearch-guided.js.map +1 -1
- package/dist/cli/autoresearch.d.ts.map +1 -1
- package/dist/cli/autoresearch.js +8 -2
- package/dist/cli/autoresearch.js.map +1 -1
- package/dist/cli/cleanup.d.ts +2 -0
- package/dist/cli/cleanup.d.ts.map +1 -1
- package/dist/cli/cleanup.js +27 -1
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/doctor.js +7 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +9 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +171 -55
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +18 -15
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/star-prompt.d.ts.map +1 -1
- package/dist/cli/star-prompt.js +2 -0
- package/dist/cli/star-prompt.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +5 -1
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/tmux-hook.d.ts.map +1 -1
- package/dist/cli/tmux-hook.js +4 -1
- package/dist/cli/tmux-hook.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +26 -0
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +1 -0
- package/dist/cli/update.js.map +1 -1
- package/dist/compat/__tests__/rust-runtime-compat.test.js +84 -1
- package/dist/compat/__tests__/rust-runtime-compat.test.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +4 -4
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/mcp-registry.test.js +13 -16
- package/dist/config/__tests__/mcp-registry.test.js.map +1 -1
- package/dist/config/mcp-registry.d.ts +1 -0
- package/dist/config/mcp-registry.d.ts.map +1 -1
- package/dist/config/mcp-registry.js +4 -4
- package/dist/config/mcp-registry.js.map +1 -1
- package/dist/config/models.d.ts +1 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +39 -1
- package/dist/config/models.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +12 -1
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +554 -18
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +347 -16
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js +5 -0
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +597 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +19 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +73 -53
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +193 -2
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +183 -0
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +255 -97
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +0 -0
- package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +46 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-team-routing.test.js +34 -0
- package/dist/hooks/__tests__/prompt-team-routing.test.js.map +1 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.js +32 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +1 -1
- package/dist/hooks/code-simplifier/index.d.ts.map +1 -1
- package/dist/hooks/code-simplifier/index.js +1 -0
- package/dist/hooks/code-simplifier/index.js.map +1 -1
- package/dist/hooks/codebase-map.d.ts.map +1 -1
- package/dist/hooks/codebase-map.js +1 -0
- package/dist/hooks/codebase-map.js.map +1 -1
- package/dist/hooks/extensibility/sdk/tmux.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/tmux.js +3 -1
- package/dist/hooks/extensibility/sdk/tmux.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +1 -0
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +48 -0
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +6 -0
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +1 -0
- package/dist/hooks/session.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +70 -1
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/authority.d.ts.map +1 -1
- package/dist/hud/authority.js +1 -0
- package/dist/hud/authority.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +52 -0
- package/dist/hud/state.js.map +1 -1
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +5 -0
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +46 -0
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +4 -0
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts +2 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.js +84 -0
- package/dist/notifications/__tests__/custom-alias-enablement.test.js.map +1 -0
- package/dist/notifications/__tests__/idle-cooldown.test.js +55 -0
- package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -1
- package/dist/notifications/idle-cooldown.d.ts +8 -6
- package/dist/notifications/idle-cooldown.d.ts.map +1 -1
- package/dist/notifications/idle-cooldown.js +53 -22
- package/dist/notifications/idle-cooldown.js.map +1 -1
- package/dist/notifications/notifier.js +1 -1
- package/dist/notifications/notifier.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +1 -0
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/tmux.d.ts.map +1 -1
- package/dist/notifications/tmux.js +4 -0
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/openclaw/config.js +2 -2
- package/dist/openclaw/config.js.map +1 -1
- package/dist/runtime/bridge.d.ts +2 -0
- package/dist/runtime/bridge.d.ts.map +1 -1
- package/dist/runtime/bridge.js +8 -0
- package/dist/runtime/bridge.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +103 -53
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts +2 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +90 -104
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.d.ts +19 -0
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -0
- package/dist/scripts/notify-hook/managed-tmux.js +320 -0
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -0
- package/dist/scripts/notify-hook/operational-events.d.ts.map +1 -1
- package/dist/scripts/notify-hook/operational-events.js +2 -0
- package/dist/scripts/notify-hook/operational-events.js.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts +22 -0
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -0
- package/dist/scripts/notify-hook/ralph-session-resume.js +277 -0
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -0
- package/dist/scripts/notify-hook/state-io.d.ts +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +2 -10
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +123 -72
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts +2 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +13 -5
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-tmux-guard.js +1 -19
- package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +4 -4
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +102 -35
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.js +144 -20
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/run-provider-advisor.js +2 -0
- package/dist/scripts/run-provider-advisor.js.map +1 -1
- package/dist/scripts/run-test-files.d.ts +2 -0
- package/dist/scripts/run-test-files.d.ts.map +1 -0
- package/dist/scripts/run-test-files.js +41 -0
- package/dist/scripts/run-test-files.js.map +1 -0
- package/dist/scripts/tmux-hook-engine.d.ts +2 -0
- package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
- package/dist/scripts/tmux-hook-engine.js +15 -0
- package/dist/scripts/tmux-hook-engine.js.map +1 -1
- package/dist/team/__tests__/api-interop.test.js +136 -4
- package/dist/team/__tests__/api-interop.test.js.map +1 -1
- package/dist/team/__tests__/leader-activity.test.js +107 -2
- package/dist/team/__tests__/leader-activity.test.js.map +1 -1
- package/dist/team/__tests__/runtime-cli.test.js +32 -0
- package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +148 -0
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/shutdown-fallback.test.js +13 -0
- package/dist/team/__tests__/shutdown-fallback.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +11 -1
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/state.test.js +237 -0
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +521 -2
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +41 -31
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/commit-hygiene.d.ts +60 -0
- package/dist/team/commit-hygiene.d.ts.map +1 -0
- package/dist/team/commit-hygiene.js +232 -0
- package/dist/team/commit-hygiene.js.map +1 -0
- package/dist/team/leader-activity.d.ts.map +1 -1
- package/dist/team/leader-activity.js +56 -4
- package/dist/team/leader-activity.js.map +1 -1
- package/dist/team/runtime-cli.d.ts +9 -1
- package/dist/team/runtime-cli.d.ts.map +1 -1
- package/dist/team/runtime-cli.js +15 -6
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime.d.ts +7 -2
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +392 -171
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +6 -2
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/dispatch.d.ts +2 -0
- package/dist/team/state/dispatch.d.ts.map +1 -1
- package/dist/team/state/dispatch.js +86 -40
- package/dist/team/state/dispatch.js.map +1 -1
- package/dist/team/state/mailbox.d.ts +3 -0
- package/dist/team/state/mailbox.d.ts.map +1 -1
- package/dist/team/state/mailbox.js +93 -19
- package/dist/team/state/mailbox.js.map +1 -1
- package/dist/team/state-root.d.ts +1 -1
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +8 -3
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +96 -2
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +81 -29
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +4 -0
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/team/worktree.d.ts.map +1 -1
- package/dist/team/worktree.js +9 -0
- package/dist/team/worktree.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +98 -11
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/__tests__/platform-command.test.js +101 -2
- package/dist/utils/__tests__/platform-command.test.js.map +1 -1
- package/dist/utils/git-layout.d.ts +8 -0
- package/dist/utils/git-layout.d.ts.map +1 -0
- package/dist/utils/git-layout.js +58 -0
- package/dist/utils/git-layout.js.map +1 -0
- package/dist/utils/paths.d.ts +3 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -4
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/platform-command.d.ts.map +1 -1
- package/dist/utils/platform-command.js +35 -3
- package/dist/utils/platform-command.js.map +1 -1
- package/package.json +9 -5
- package/src/scripts/notify-fallback-watcher.ts +103 -53
- package/src/scripts/notify-hook/auto-nudge.ts +97 -103
- package/src/scripts/notify-hook/managed-tmux.ts +324 -0
- package/src/scripts/notify-hook/operational-events.ts +2 -0
- package/src/scripts/notify-hook/ralph-session-resume.ts +337 -0
- package/src/scripts/notify-hook/state-io.ts +2 -10
- package/src/scripts/notify-hook/team-dispatch.ts +131 -66
- package/src/scripts/notify-hook/team-leader-nudge.ts +19 -5
- package/src/scripts/notify-hook/team-tmux-guard.ts +0 -20
- package/src/scripts/notify-hook/team-worker.ts +4 -4
- package/src/scripts/notify-hook/tmux-injection.ts +103 -33
- package/src/scripts/notify-hook.ts +150 -21
- package/src/scripts/run-provider-advisor.ts +4 -2
- package/src/scripts/run-test-files.ts +48 -0
- package/src/scripts/tmux-hook-engine.ts +16 -0
- package/templates/AGENTS.md +51 -43
|
@@ -5,12 +5,12 @@ import { execFileSync } from 'child_process';
|
|
|
5
5
|
import { dirname, join, resolve } from 'path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { safeString } from './utils.js';
|
|
8
|
-
import { resolveRuntimeBinaryPath } from '../../runtime/bridge.js';
|
|
8
|
+
import { resolveBridgeStateDir, resolveRuntimeBinaryPath } from '../../runtime/bridge.js';
|
|
9
9
|
|
|
10
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
11
|
const __dirname = dirname(__filename);
|
|
12
12
|
import { runProcess } from './process-runner.js';
|
|
13
|
-
import { resolvePaneTarget } from './tmux-injection.js';
|
|
13
|
+
import { resolvePaneTarget, resolveSessionToPane } from './tmux-injection.js';
|
|
14
14
|
import { evaluatePaneInjectionReadiness, sendPaneInput } from './team-tmux-guard.js';
|
|
15
15
|
import {
|
|
16
16
|
buildCapturePaneArgv,
|
|
@@ -21,16 +21,19 @@ import {
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Route dispatch state transitions through the Rust runtime binary.
|
|
24
|
-
* Non-fatal: if the binary is missing or fails, the
|
|
24
|
+
* Non-fatal: if the binary is missing or fails, the legacy JSON fallback lane
|
|
25
|
+
* remains available when the caller is already operating outside the bridge-
|
|
26
|
+
* owned path.
|
|
25
27
|
* Disable entirely with OMX_RUNTIME_BRIDGE=0.
|
|
26
28
|
*/
|
|
27
|
-
function runtimeExec(command) {
|
|
29
|
+
function runtimeExec(command, stateDir) {
|
|
28
30
|
if (process.env.OMX_RUNTIME_BRIDGE === '0') return;
|
|
29
31
|
try {
|
|
30
32
|
const binaryPath = resolveRuntimeBinaryPath();
|
|
31
|
-
execFileSync(binaryPath, ['exec', JSON.stringify(command)], {
|
|
33
|
+
execFileSync(binaryPath, ['exec', JSON.stringify(command), `--state-dir=${stateDir}`], {
|
|
32
34
|
timeout: 5000,
|
|
33
35
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
36
|
+
windowsHide: true,
|
|
34
37
|
});
|
|
35
38
|
} catch {
|
|
36
39
|
// non-fatal: JS path is the fallback
|
|
@@ -43,6 +46,47 @@ function readJson(path, fallback) {
|
|
|
43
46
|
.catch(() => fallback);
|
|
44
47
|
}
|
|
45
48
|
|
|
49
|
+
async function readBridgeDispatchRequests(stateDir, teamName) {
|
|
50
|
+
const candidate = join(stateDir, 'dispatch.json');
|
|
51
|
+
if (!existsSync(candidate)) return null;
|
|
52
|
+
const parsed = await readJson(candidate, null);
|
|
53
|
+
if (!parsed || !Array.isArray(parsed.records)) return null;
|
|
54
|
+
return parsed.records
|
|
55
|
+
.map((record) => {
|
|
56
|
+
if (!record || typeof record !== 'object') return null;
|
|
57
|
+
const metadata = record.metadata && typeof record.metadata === 'object' ? record.metadata : {};
|
|
58
|
+
const metadataTeam = safeString(metadata.team_name).trim();
|
|
59
|
+
if (metadataTeam && metadataTeam !== teamName) return null;
|
|
60
|
+
return {
|
|
61
|
+
request_id: safeString(record.request_id).trim(),
|
|
62
|
+
kind: safeString(metadata.kind).trim() || 'inbox',
|
|
63
|
+
team_name: teamName,
|
|
64
|
+
to_worker: safeString(record.target).trim(),
|
|
65
|
+
worker_index: typeof metadata.worker_index === 'number' ? metadata.worker_index : undefined,
|
|
66
|
+
pane_id: safeString(metadata.pane_id).trim() || undefined,
|
|
67
|
+
trigger_message: safeString(metadata.trigger_message).trim() || safeString(record.reason).trim() || safeString(record.request_id).trim(),
|
|
68
|
+
message_id: safeString(metadata.message_id).trim() || undefined,
|
|
69
|
+
inbox_correlation_key: safeString(metadata.inbox_correlation_key).trim() || undefined,
|
|
70
|
+
transport_preference: safeString(metadata.transport_preference).trim() || 'hook_preferred_with_fallback',
|
|
71
|
+
fallback_allowed: typeof metadata.fallback_allowed === 'boolean' ? metadata.fallback_allowed : true,
|
|
72
|
+
status: safeString(record.status).trim() || 'pending',
|
|
73
|
+
attempt_count: Number.isFinite(metadata.attempt_count) ? Number(metadata.attempt_count) : 0,
|
|
74
|
+
created_at: safeString(record.created_at).trim() || new Date().toISOString(),
|
|
75
|
+
updated_at:
|
|
76
|
+
safeString(record.delivered_at).trim()
|
|
77
|
+
|| safeString(record.failed_at).trim()
|
|
78
|
+
|| safeString(record.notified_at).trim()
|
|
79
|
+
|| safeString(record.created_at).trim()
|
|
80
|
+
|| new Date().toISOString(),
|
|
81
|
+
notified_at: safeString(record.notified_at).trim() || undefined,
|
|
82
|
+
delivered_at: safeString(record.delivered_at).trim() || undefined,
|
|
83
|
+
failed_at: safeString(record.failed_at).trim() || undefined,
|
|
84
|
+
last_reason: safeString(record.reason).trim() || undefined,
|
|
85
|
+
};
|
|
86
|
+
})
|
|
87
|
+
.filter((record) => record && record.request_id && record.to_worker && record.trigger_message);
|
|
88
|
+
}
|
|
89
|
+
|
|
46
90
|
async function writeJsonAtomic(path, value) {
|
|
47
91
|
await mkdir(dirname(path), { recursive: true });
|
|
48
92
|
const tmp = `${path}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
@@ -138,8 +182,7 @@ function parseTriggerCooldownEntry(entry) {
|
|
|
138
182
|
};
|
|
139
183
|
}
|
|
140
184
|
|
|
141
|
-
async function
|
|
142
|
-
const lockDir = join(teamDirPath, 'dispatch', '.lock');
|
|
185
|
+
async function withLockDirectory(lockDir, timeoutError, fn) {
|
|
143
186
|
const ownerPath = join(lockDir, 'owner');
|
|
144
187
|
const ownerToken = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
|
|
145
188
|
const deadline = Date.now() + 5_000;
|
|
@@ -166,7 +209,7 @@ async function withDispatchLock(teamDirPath, fn) {
|
|
|
166
209
|
} catch {
|
|
167
210
|
// best effort
|
|
168
211
|
}
|
|
169
|
-
if (Date.now() > deadline) throw new Error(
|
|
212
|
+
if (Date.now() > deadline) throw new Error(timeoutError);
|
|
170
213
|
await new Promise((resolveDelay) => setTimeout(resolveDelay, 25));
|
|
171
214
|
}
|
|
172
215
|
}
|
|
@@ -185,57 +228,63 @@ async function withDispatchLock(teamDirPath, fn) {
|
|
|
185
228
|
}
|
|
186
229
|
}
|
|
187
230
|
|
|
188
|
-
async function
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
while (true) {
|
|
196
|
-
try {
|
|
197
|
-
await mkdir(lockDir, { recursive: false });
|
|
198
|
-
try {
|
|
199
|
-
await writeFile(ownerPath, ownerToken, 'utf8');
|
|
200
|
-
} catch (error) {
|
|
201
|
-
await rm(lockDir, { recursive: true, force: true });
|
|
202
|
-
throw error;
|
|
203
|
-
}
|
|
204
|
-
break;
|
|
205
|
-
} catch (error) {
|
|
206
|
-
if (error?.code !== 'EEXIST') throw error;
|
|
207
|
-
try {
|
|
208
|
-
const info = await stat(lockDir);
|
|
209
|
-
if (Date.now() - info.mtimeMs > DISPATCH_LOCK_STALE_MS) {
|
|
210
|
-
await rm(lockDir, { recursive: true, force: true });
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
} catch {
|
|
214
|
-
// best effort
|
|
215
|
-
}
|
|
216
|
-
if (Date.now() > deadline) throw new Error(`Timed out acquiring mailbox lock for ${teamDirPath}/${workerName}`);
|
|
217
|
-
await new Promise((resolveDelay) => setTimeout(resolveDelay, 25));
|
|
218
|
-
}
|
|
219
|
-
}
|
|
231
|
+
async function withDispatchLock(teamDirPath, fn) {
|
|
232
|
+
return await withLockDirectory(
|
|
233
|
+
join(teamDirPath, 'dispatch', '.lock'),
|
|
234
|
+
`Timed out acquiring dispatch lock for ${teamDirPath}`,
|
|
235
|
+
fn,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
220
238
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
await rm(lockDir, { recursive: true, force: true });
|
|
228
|
-
}
|
|
229
|
-
} catch {
|
|
230
|
-
// best effort
|
|
231
|
-
}
|
|
232
|
-
}
|
|
239
|
+
async function withMailboxLock(teamDirPath, workerName, fn) {
|
|
240
|
+
return await withLockDirectory(
|
|
241
|
+
join(teamDirPath, 'mailbox', `.lock-${workerName}`),
|
|
242
|
+
`Timed out acquiring mailbox lock for ${teamDirPath}/${workerName}`,
|
|
243
|
+
fn,
|
|
244
|
+
);
|
|
233
245
|
}
|
|
234
246
|
|
|
235
247
|
function resolveLeaderPaneId(config) {
|
|
236
248
|
return safeString(config?.leader_pane_id).trim();
|
|
237
249
|
}
|
|
238
250
|
|
|
251
|
+
function serializeDispatchRequestRecord(request) {
|
|
252
|
+
return {
|
|
253
|
+
request_id: safeString(request.request_id).trim(),
|
|
254
|
+
target: safeString(request.to_worker).trim(),
|
|
255
|
+
status: safeString(request.status).trim() || 'pending',
|
|
256
|
+
created_at: safeString(request.created_at).trim() || new Date().toISOString(),
|
|
257
|
+
notified_at: safeString(request.notified_at).trim() || null,
|
|
258
|
+
delivered_at: safeString(request.delivered_at).trim() || null,
|
|
259
|
+
failed_at: safeString(request.failed_at).trim() || null,
|
|
260
|
+
reason: safeString(request.last_reason).trim() || null,
|
|
261
|
+
metadata: {
|
|
262
|
+
kind: safeString(request.kind).trim() || 'inbox',
|
|
263
|
+
team_name: safeString(request.team_name).trim(),
|
|
264
|
+
worker_index: Number.isFinite(request.worker_index) ? Number(request.worker_index) : undefined,
|
|
265
|
+
pane_id: safeString(request.pane_id).trim() || undefined,
|
|
266
|
+
trigger_message: safeString(request.trigger_message).trim(),
|
|
267
|
+
message_id: safeString(request.message_id).trim() || undefined,
|
|
268
|
+
inbox_correlation_key: safeString(request.inbox_correlation_key).trim() || undefined,
|
|
269
|
+
transport_preference: safeString(request.transport_preference).trim() || 'hook_preferred_with_fallback',
|
|
270
|
+
fallback_allowed: typeof request.fallback_allowed === 'boolean' ? request.fallback_allowed : true,
|
|
271
|
+
attempt_count: Number.isFinite(request.attempt_count) ? Number(request.attempt_count) : 0,
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async function writeBridgeDispatchCompat(stateDir, teamName, requests) {
|
|
277
|
+
const compatPath = join(stateDir, 'dispatch.json');
|
|
278
|
+
const current = await readJson(compatPath, { records: [] });
|
|
279
|
+
const existing = Array.isArray(current?.records) ? current.records : [];
|
|
280
|
+
const otherTeams = existing.filter((record) => {
|
|
281
|
+
const metadata = record?.metadata && typeof record.metadata === 'object' ? record.metadata : {};
|
|
282
|
+
return safeString(metadata.team_name).trim() !== teamName;
|
|
283
|
+
});
|
|
284
|
+
const records = [...otherTeams, ...requests.map(serializeDispatchRequestRecord)];
|
|
285
|
+
await writeJsonAtomic(compatPath, { records });
|
|
286
|
+
}
|
|
287
|
+
|
|
239
288
|
|
|
240
289
|
function defaultInjectTarget(request, config) {
|
|
241
290
|
if (request.to_worker === 'leader-fixed') {
|
|
@@ -318,12 +367,20 @@ function capturedPaneContainsTriggerNearTail(captured, trigger, nonEmptyTailLine
|
|
|
318
367
|
const INJECT_VERIFY_DELAY_MS = 250;
|
|
319
368
|
const INJECT_VERIFY_ROUNDS = 3;
|
|
320
369
|
|
|
321
|
-
async function injectDispatchRequest(request, config, cwd) {
|
|
370
|
+
async function injectDispatchRequest(request, config, cwd, stateDir) {
|
|
322
371
|
const target = defaultInjectTarget(request, config);
|
|
323
372
|
if (!target) {
|
|
324
373
|
return { ok: false, reason: 'missing_tmux_target' };
|
|
325
374
|
}
|
|
326
|
-
|
|
375
|
+
let resolution;
|
|
376
|
+
if (target.type === 'session') {
|
|
377
|
+
const paneId = await resolveSessionToPane(target.value).catch(() => null);
|
|
378
|
+
resolution = paneId
|
|
379
|
+
? { paneTarget: paneId, reason: 'session_target_resolved' }
|
|
380
|
+
: { paneTarget: null, reason: 'target_not_found' };
|
|
381
|
+
} else {
|
|
382
|
+
resolution = await resolvePaneTarget(target, '', '', '', {});
|
|
383
|
+
}
|
|
327
384
|
if (!resolution.paneTarget) {
|
|
328
385
|
return { ok: false, reason: `target_resolution_failed:${resolution.reason}` };
|
|
329
386
|
}
|
|
@@ -390,7 +447,7 @@ async function injectDispatchRequest(request, config, cwd) {
|
|
|
390
447
|
const wideCap = await runProcess('tmux', verifyWideArgv, 2000);
|
|
391
448
|
// Worker is actively processing (mirrors sync path tmux-session.ts:1292-1294)
|
|
392
449
|
if (paneHasActiveTask(wideCap.stdout)) {
|
|
393
|
-
runtimeExec({ command: 'MarkDelivered', request_id: request.request_id });
|
|
450
|
+
runtimeExec({ command: 'MarkDelivered', request_id: request.request_id }, stateDir);
|
|
394
451
|
return { ok: true, reason: 'tmux_send_keys_confirmed_active_task', pane: resolution.paneTarget };
|
|
395
452
|
}
|
|
396
453
|
// Do not declare success while a *worker* pane is still bootstrapping / not
|
|
@@ -403,7 +460,7 @@ async function injectDispatchRequest(request, config, cwd) {
|
|
|
403
460
|
const triggerInNarrow = capturedPaneContainsTrigger(narrowCap.stdout, request.trigger_message);
|
|
404
461
|
const triggerNearTail = capturedPaneContainsTriggerNearTail(wideCap.stdout, request.trigger_message);
|
|
405
462
|
if (!triggerInNarrow && !triggerNearTail) {
|
|
406
|
-
runtimeExec({ command: 'MarkDelivered', request_id: request.request_id });
|
|
463
|
+
runtimeExec({ command: 'MarkDelivered', request_id: request.request_id }, stateDir);
|
|
407
464
|
return { ok: true, reason: 'tmux_send_keys_confirmed', pane: resolution.paneTarget };
|
|
408
465
|
}
|
|
409
466
|
} catch {
|
|
@@ -450,7 +507,7 @@ async function appendDispatchLog(logsDir, event) {
|
|
|
450
507
|
|
|
451
508
|
export async function drainPendingTeamDispatch({
|
|
452
509
|
cwd,
|
|
453
|
-
stateDir =
|
|
510
|
+
stateDir = resolveBridgeStateDir(cwd),
|
|
454
511
|
logsDir = join(cwd, '.omx', 'logs'),
|
|
455
512
|
maxPerTick = 5,
|
|
456
513
|
injector = injectDispatchRequest,
|
|
@@ -475,11 +532,12 @@ export async function drainPendingTeamDispatch({
|
|
|
475
532
|
const manifestPath = join(teamDirPath, 'manifest.v2.json');
|
|
476
533
|
const configPath = join(teamDirPath, 'config.json');
|
|
477
534
|
const requestsPath = join(teamDirPath, 'dispatch', 'requests.json');
|
|
478
|
-
if (!existsSync(requestsPath)) continue;
|
|
479
535
|
|
|
480
536
|
const config = await readJson(existsSync(manifestPath) ? manifestPath : configPath, {});
|
|
481
537
|
await withDispatchLock(teamDirPath, async () => {
|
|
482
|
-
const
|
|
538
|
+
const bridgeRequests = await readBridgeDispatchRequests(stateDir, teamName);
|
|
539
|
+
const usingLegacyRequests = bridgeRequests === null;
|
|
540
|
+
const requests = usingLegacyRequests ? await readJson(requestsPath, []) : bridgeRequests;
|
|
483
541
|
if (!Array.isArray(requests)) return;
|
|
484
542
|
const issueCooldownState = await readIssueCooldownState(teamDirPath);
|
|
485
543
|
const triggerCooldownState = await readTriggerCooldownState(teamDirPath);
|
|
@@ -518,8 +576,9 @@ export async function drainPendingTeamDispatch({
|
|
|
518
576
|
leader_pane_id: safeString(config?.leader_pane_id).trim() || null,
|
|
519
577
|
tmux_injection_attempted: false,
|
|
520
578
|
});
|
|
521
|
-
//
|
|
522
|
-
// for
|
|
579
|
+
// On the legacy fallback lane, requests.json still carries the queue
|
|
580
|
+
// state for this deferred request; this event stays a progress
|
|
581
|
+
// artifact for hook/watcher readers.
|
|
523
582
|
await appendLeaderNotificationDeferredEvent({
|
|
524
583
|
stateDir,
|
|
525
584
|
teamName,
|
|
@@ -554,7 +613,7 @@ export async function drainPendingTeamDispatch({
|
|
|
554
613
|
}
|
|
555
614
|
}
|
|
556
615
|
|
|
557
|
-
const result = await injector(request, config, resolve(cwd));
|
|
616
|
+
const result = await injector(request, config, resolve(cwd), stateDir);
|
|
558
617
|
if (issueKey && issueCooldownMs > 0) {
|
|
559
618
|
issueCooldownByIssue[issueKey] = Date.now();
|
|
560
619
|
mutated = true;
|
|
@@ -602,7 +661,7 @@ export async function drainPendingTeamDispatch({
|
|
|
602
661
|
request.status = 'failed';
|
|
603
662
|
request.failed_at = nowIso;
|
|
604
663
|
request.last_reason = 'unconfirmed_after_max_retries';
|
|
605
|
-
runtimeExec({ command: 'MarkFailed', request_id: request.request_id, reason: 'unconfirmed_after_max_retries' });
|
|
664
|
+
runtimeExec({ command: 'MarkFailed', request_id: request.request_id, reason: 'unconfirmed_after_max_retries' }, stateDir);
|
|
606
665
|
processed += 1;
|
|
607
666
|
failed += 1;
|
|
608
667
|
mutated = true;
|
|
@@ -629,9 +688,12 @@ export async function drainPendingTeamDispatch({
|
|
|
629
688
|
request.status = 'notified';
|
|
630
689
|
request.notified_at = nowIso;
|
|
631
690
|
request.last_reason = result.reason;
|
|
632
|
-
runtimeExec({ command: 'MarkNotified', request_id: request.request_id, channel: 'tmux' });
|
|
691
|
+
runtimeExec({ command: 'MarkNotified', request_id: request.request_id, channel: 'tmux' }, stateDir);
|
|
633
692
|
if (request.kind === 'mailbox' && request.message_id) {
|
|
634
|
-
|
|
693
|
+
runtimeExec({ command: 'MarkMailboxNotified', message_id: request.message_id }, stateDir);
|
|
694
|
+
if (usingLegacyRequests) {
|
|
695
|
+
await updateMailboxNotified(stateDir, teamName, request.to_worker, request.message_id).catch(() => {});
|
|
696
|
+
}
|
|
635
697
|
}
|
|
636
698
|
processed += 1;
|
|
637
699
|
mutated = true;
|
|
@@ -647,7 +709,7 @@ export async function drainPendingTeamDispatch({
|
|
|
647
709
|
request.status = 'failed';
|
|
648
710
|
request.failed_at = nowIso;
|
|
649
711
|
request.last_reason = result.reason;
|
|
650
|
-
runtimeExec({ command: 'MarkFailed', request_id: request.request_id, reason: result.reason });
|
|
712
|
+
runtimeExec({ command: 'MarkFailed', request_id: request.request_id, reason: result.reason }, stateDir);
|
|
651
713
|
processed += 1;
|
|
652
714
|
failed += 1;
|
|
653
715
|
mutated = true;
|
|
@@ -679,6 +741,9 @@ export async function drainPendingTeamDispatch({
|
|
|
679
741
|
triggerCooldownState.by_trigger = triggerCooldownByKey;
|
|
680
742
|
await writeJsonAtomic(triggerCooldownStatePath(teamDirPath), triggerCooldownState);
|
|
681
743
|
await writeJsonAtomic(requestsPath, requests);
|
|
744
|
+
if (!usingLegacyRequests) {
|
|
745
|
+
await writeBridgeDispatchCompat(stateDir, teamName, requests);
|
|
746
|
+
}
|
|
682
747
|
}
|
|
683
748
|
});
|
|
684
749
|
}
|
|
@@ -510,7 +510,13 @@ async function emitLeaderNudgeDeferredEvent(cwd, teamName, reason, nowIso, { tmu
|
|
|
510
510
|
}
|
|
511
511
|
}
|
|
512
512
|
|
|
513
|
-
export async function maybeNudgeTeamLeader({
|
|
513
|
+
export async function maybeNudgeTeamLeader({
|
|
514
|
+
cwd,
|
|
515
|
+
stateDir,
|
|
516
|
+
logsDir,
|
|
517
|
+
preComputedLeaderStale,
|
|
518
|
+
allowFreshMailboxNudges = true,
|
|
519
|
+
}) {
|
|
514
520
|
const intervalMs = resolveLeaderNudgeIntervalMs();
|
|
515
521
|
const idleCooldownMs = resolveLeaderAllIdleNudgeCooldownMs();
|
|
516
522
|
const fallbackProgressStallThresholdMs = resolveFallbackProgressStallThresholdMs();
|
|
@@ -683,7 +689,8 @@ export async function maybeNudgeTeamLeader({ cwd, stateDir, logsDir, preComputed
|
|
|
683
689
|
const stalledTeamNudge = teamProgressStalled && (dueByTime || !previousStalledTeamNudge);
|
|
684
690
|
const staleFollowupDue = stalePanesNudge && dueByTime;
|
|
685
691
|
|
|
686
|
-
|
|
692
|
+
const hasActionableNewMessage = hasNewMessage && (allowFreshMailboxNudges || leaderStale);
|
|
693
|
+
if (!shouldSendAllIdleNudge && !hasActionableNewMessage && !stalledTeamNudge && !staleFollowupDue) continue;
|
|
687
694
|
|
|
688
695
|
let nudgeReason = '';
|
|
689
696
|
let text = '';
|
|
@@ -717,7 +724,7 @@ export async function maybeNudgeTeamLeader({ cwd, stateDir, logsDir, preComputed
|
|
|
717
724
|
`Team ${teamName}: ${stallPrefix}no progress ${formatDurationMs(stalledForMs)}. `
|
|
718
725
|
+ `${leaderActionGuidance} `
|
|
719
726
|
+ `(p:${pending} ip:${in_progress} b:${blocked}${missingSignals})`;
|
|
720
|
-
} else if (stalePanesNudge &&
|
|
727
|
+
} else if (stalePanesNudge && hasActionableNewMessage) {
|
|
721
728
|
nudgeReason = 'stale_leader_with_messages';
|
|
722
729
|
text =
|
|
723
730
|
`Team ${teamName}: leader stale, ${paneStatus.paneCount} pane(s) active, ${messages.length} msg(s) pending. `
|
|
@@ -727,7 +734,7 @@ export async function maybeNudgeTeamLeader({ cwd, stateDir, logsDir, preComputed
|
|
|
727
734
|
text =
|
|
728
735
|
`Team ${teamName}: leader stale, ${paneStatus.paneCount} worker pane(s) still active. `
|
|
729
736
|
+ leaderActionGuidance;
|
|
730
|
-
} else if (
|
|
737
|
+
} else if (hasActionableNewMessage) {
|
|
731
738
|
nudgeReason = 'new_mailbox_message';
|
|
732
739
|
text = `Team ${teamName}: ${messages.length} msg(s) for leader. ${buildMailboxCheckReminder(teamName)}`;
|
|
733
740
|
} else {
|
|
@@ -763,7 +770,14 @@ export async function maybeNudgeTeamLeader({ cwd, stateDir, logsDir, preComputed
|
|
|
763
770
|
continue;
|
|
764
771
|
}
|
|
765
772
|
|
|
766
|
-
const paneGuard = await evaluatePaneInjectionReadiness(tmuxTarget, {
|
|
773
|
+
const paneGuard = await evaluatePaneInjectionReadiness(tmuxTarget, {
|
|
774
|
+
skipIfScrolling: true,
|
|
775
|
+
// Leader nudges should still queue into a live Codex pane even while the
|
|
776
|
+
// agent is busy; shell/copy-mode guards stay enforced.
|
|
777
|
+
requireRunningAgent: true,
|
|
778
|
+
requireReady: false,
|
|
779
|
+
requireIdle: false,
|
|
780
|
+
});
|
|
767
781
|
if (!paneGuard.ok) {
|
|
768
782
|
const deferredReason = paneGuard.reason === 'pane_running_shell'
|
|
769
783
|
? LEADER_PANE_SHELL_NO_INJECTION_REASON
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
isPaneRunningShell,
|
|
9
9
|
paneHasActiveTask,
|
|
10
10
|
paneLooksReady,
|
|
11
|
-
resolveCodexPane,
|
|
12
11
|
} from '../tmux-hook-engine.js';
|
|
13
12
|
|
|
14
13
|
export function mapPaneInjectionReadinessReason(reason: any): any {
|
|
@@ -33,25 +32,6 @@ export async function evaluatePaneInjectionReadiness(paneTarget: any, {
|
|
|
33
32
|
paneCapture: '',
|
|
34
33
|
};
|
|
35
34
|
}
|
|
36
|
-
|
|
37
|
-
// Canonical bypass: if resolveCodexPane confirms this is a codex pane
|
|
38
|
-
// (via pane_start_command), skip all readiness guards. The pane IS running
|
|
39
|
-
// codex even though tmux may report cmd=sh (shell wrapper).
|
|
40
|
-
try {
|
|
41
|
-
if (resolveCodexPane() === target) {
|
|
42
|
-
return {
|
|
43
|
-
ok: true,
|
|
44
|
-
sent: false,
|
|
45
|
-
reason: 'ok',
|
|
46
|
-
paneTarget: target,
|
|
47
|
-
paneCurrentCommand: 'codex',
|
|
48
|
-
paneCapture: '',
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
} catch {
|
|
52
|
-
// Non-fatal: fall through to normal readiness checks
|
|
53
|
-
}
|
|
54
|
-
|
|
55
35
|
if (skipIfScrolling) {
|
|
56
36
|
try {
|
|
57
37
|
const modeResult = await runProcess('tmux', buildPaneInModeArgv(target), 1000);
|
|
@@ -262,7 +262,7 @@ async function resolveCanonicalLeaderPaneId(_tmuxSession, leaderPaneId) {
|
|
|
262
262
|
const normalizedLeaderPaneId = safeString(leaderPaneId).trim();
|
|
263
263
|
if (normalizedLeaderPaneId) {
|
|
264
264
|
try {
|
|
265
|
-
const resolved = await resolvePaneTarget({ type: 'pane', value: normalizedLeaderPaneId }, '', '', '');
|
|
265
|
+
const resolved = await resolvePaneTarget({ type: 'pane', value: normalizedLeaderPaneId }, '', '', '', {});
|
|
266
266
|
const paneTarget = safeString(resolved?.paneTarget).trim();
|
|
267
267
|
if (paneTarget) return paneTarget;
|
|
268
268
|
} catch {
|
|
@@ -541,8 +541,8 @@ export async function maybeNotifyLeaderWorkerIdle({ cwd, stateDir, logsDir, pars
|
|
|
541
541
|
await rename(tmpPath, prevStatePath);
|
|
542
542
|
} catch { /* best effort */ }
|
|
543
543
|
|
|
544
|
-
//
|
|
545
|
-
if (currentState !== 'idle') return;
|
|
544
|
+
// Fire when a worker leaves active work into an idle-ish terminal state.
|
|
545
|
+
if (currentState !== 'idle' && currentState !== 'done') return;
|
|
546
546
|
if (!statusFresh) return;
|
|
547
547
|
if (prevState === 'idle' || prevState === 'done') return;
|
|
548
548
|
|
|
@@ -608,7 +608,7 @@ export async function maybeNotifyLeaderWorkerIdle({ cwd, stateDir, logsDir, pars
|
|
|
608
608
|
}
|
|
609
609
|
|
|
610
610
|
// Build notification message with context
|
|
611
|
-
const parts = [`[OMX] ${workerName}
|
|
611
|
+
const parts = [`[OMX] ${workerName} ${currentState}`];
|
|
612
612
|
if (prevState && prevState !== 'unknown') parts.push(`(was: ${prevState})`);
|
|
613
613
|
if (currentTaskId) parts.push(`task: ${currentTaskId}`);
|
|
614
614
|
if (currentReason) parts.push(`reason: ${currentReason}`);
|