oh-my-codex 0.7.5 → 0.8.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/README.de.md +314 -0
- package/README.es.md +295 -17
- package/README.fr.md +314 -0
- package/README.it.md +314 -0
- package/README.ja.md +296 -18
- package/README.ko.md +295 -17
- package/README.md +68 -3
- package/README.pt.md +295 -17
- package/README.ru.md +295 -17
- package/README.tr.md +314 -0
- package/README.vi.md +296 -18
- package/README.zh.md +292 -17
- package/dist/catalog/__tests__/generator.test.js +2 -0
- package/dist/catalog/__tests__/generator.test.js.map +1 -1
- package/dist/catalog/__tests__/schema.test.js +7 -0
- package/dist/catalog/__tests__/schema.test.js.map +1 -1
- package/dist/cli/__tests__/ask.test.d.ts +2 -0
- package/dist/cli/__tests__/ask.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ask.test.js +236 -0
- package/dist/cli/__tests__/ask.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.d.ts +2 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.d.ts.map +1 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js +45 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -0
- package/dist/cli/__tests__/index.test.js +43 -1
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts +2 -0
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +15 -0
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +1 -0
- package/dist/cli/__tests__/ralph.test.d.ts +2 -0
- package/dist/cli/__tests__/ralph.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralph.test.js +40 -0
- package/dist/cli/__tests__/ralph.test.js.map +1 -0
- package/dist/cli/__tests__/setup-scope.test.js +2 -0
- package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
- package/dist/cli/__tests__/team-decompose.test.d.ts +2 -0
- package/dist/cli/__tests__/team-decompose.test.d.ts.map +1 -0
- package/dist/cli/__tests__/team-decompose.test.js +67 -0
- package/dist/cli/__tests__/team-decompose.test.js.map +1 -0
- package/dist/cli/__tests__/version.test.d.ts +2 -0
- package/dist/cli/__tests__/version.test.d.ts.map +1 -0
- package/dist/cli/__tests__/version.test.js +21 -0
- package/dist/cli/__tests__/version.test.js.map +1 -0
- package/dist/cli/ask.d.ts +13 -0
- package/dist/cli/ask.d.ts.map +1 -0
- package/dist/cli/ask.js +174 -0
- package/dist/cli/ask.js.map +1 -0
- package/dist/cli/constants.d.ts +10 -0
- package/dist/cli/constants.d.ts.map +1 -0
- package/dist/cli/constants.js +10 -0
- package/dist/cli/constants.js.map +1 -0
- package/dist/cli/doctor.js +16 -5
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +7 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +117 -43
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ralph.d.ts +4 -0
- package/dist/cli/ralph.d.ts.map +1 -1
- package/dist/cli/ralph.js +89 -13
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/setup.js +1 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/team.d.ts +18 -0
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +108 -16
- package/dist/cli/team.js.map +1 -1
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +8 -0
- package/dist/config/generator.js.map +1 -1
- package/dist/hooks/__tests__/deep-interview-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/deep-interview-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/deep-interview-contract.test.js +55 -0
- package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/emulator.test.js +6 -0
- package/dist/hooks/__tests__/emulator.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +44 -22
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +59 -0
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +88 -0
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +199 -0
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts +11 -0
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js +266 -0
- package/dist/hooks/__tests__/notify-hook-visual-verdict.test.js.map +1 -0
- package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/openclaw-setup-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/openclaw-setup-contract.test.js +51 -0
- package/dist/hooks/__tests__/openclaw-setup-contract.test.js.map +1 -0
- package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts +2 -0
- package/dist/hooks/__tests__/pre-context-gate-skills.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js +34 -0
- package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -0
- package/dist/hooks/__tests__/tmux-hook-engine.test.js +36 -1
- package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +1 -1
- package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts +2 -0
- package/dist/hooks/__tests__/visual-verdict-loop.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/visual-verdict-loop.test.js +35 -0
- package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +1 -0
- package/dist/hooks/agents-overlay.d.ts.map +1 -1
- package/dist/hooks/agents-overlay.js +18 -16
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/codebase-map.d.ts.map +1 -1
- package/dist/hooks/codebase-map.js +6 -2
- package/dist/hooks/codebase-map.js.map +1 -1
- package/dist/hooks/emulator.d.ts.map +1 -1
- package/dist/hooks/emulator.js +2 -0
- package/dist/hooks/emulator.js.map +1 -1
- package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk.js +2 -1
- package/dist/hooks/extensibility/sdk.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +6 -0
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +2 -24
- package/dist/hud/index.js.map +1 -1
- package/dist/mcp/__tests__/team-server-cleanup.test.d.ts +2 -0
- package/dist/mcp/__tests__/team-server-cleanup.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/team-server-cleanup.test.js +219 -0
- package/dist/mcp/__tests__/team-server-cleanup.test.js.map +1 -0
- package/dist/mcp/bootstrap.d.ts +1 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +1 -0
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/code-intel-server.d.ts.map +1 -1
- package/dist/mcp/code-intel-server.js +18 -8
- package/dist/mcp/code-intel-server.js.map +1 -1
- package/dist/mcp/memory-server.js +72 -11
- package/dist/mcp/memory-server.js.map +1 -1
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +4 -1
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +18 -5
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/mcp/team-server.d.ts +24 -0
- package/dist/mcp/team-server.d.ts.map +1 -0
- package/dist/mcp/team-server.js +425 -0
- package/dist/mcp/team-server.js.map +1 -0
- package/dist/mcp/trace-server.d.ts.map +1 -1
- package/dist/mcp/trace-server.js +8 -3
- package/dist/mcp/trace-server.js.map +1 -1
- package/dist/notifications/__tests__/verbosity.test.js +35 -0
- package/dist/notifications/__tests__/verbosity.test.js.map +1 -1
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +12 -3
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/dispatcher.d.ts.map +1 -1
- package/dist/notifications/dispatcher.js +4 -4
- package/dist/notifications/dispatcher.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +6 -2
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/session-registry.d.ts.map +1 -1
- package/dist/notifications/session-registry.js +2 -2
- package/dist/notifications/session-registry.js.map +1 -1
- package/dist/notifications/tmux.d.ts.map +1 -1
- package/dist/notifications/tmux.js +13 -4
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/notifications/types.d.ts +4 -0
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/openclaw/__tests__/index.test.js +40 -0
- package/dist/openclaw/__tests__/index.test.js.map +1 -1
- package/dist/openclaw/dispatcher.d.ts.map +1 -1
- package/dist/openclaw/dispatcher.js +5 -2
- package/dist/openclaw/dispatcher.js.map +1 -1
- package/dist/openclaw/index.d.ts.map +1 -1
- package/dist/openclaw/index.js +1 -0
- package/dist/openclaw/index.js.map +1 -1
- package/dist/openclaw/types.d.ts +2 -0
- package/dist/openclaw/types.d.ts.map +1 -1
- package/dist/ralph/__tests__/persistence.test.js +28 -1
- package/dist/ralph/__tests__/persistence.test.js.map +1 -1
- package/dist/ralph/persistence.d.ts +21 -0
- package/dist/ralph/persistence.d.ts.map +1 -1
- package/dist/ralph/persistence.js +85 -2
- package/dist/ralph/persistence.js.map +1 -1
- package/dist/state/paths.d.ts +3 -0
- package/dist/state/paths.d.ts.map +1 -0
- package/dist/state/paths.js +2 -0
- package/dist/state/paths.js.map +1 -0
- package/dist/team/__tests__/idle-nudge.test.d.ts +2 -0
- package/dist/team/__tests__/idle-nudge.test.d.ts.map +1 -0
- package/dist/team/__tests__/idle-nudge.test.js +225 -0
- package/dist/team/__tests__/idle-nudge.test.js.map +1 -0
- package/dist/team/__tests__/role-router.test.d.ts +2 -0
- package/dist/team/__tests__/role-router.test.d.ts.map +1 -0
- package/dist/team/__tests__/role-router.test.js +204 -0
- package/dist/team/__tests__/role-router.test.js.map +1 -0
- package/dist/team/__tests__/runtime-cli.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-cli.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-cli.test.js +72 -0
- package/dist/team/__tests__/runtime-cli.test.js.map +1 -0
- package/dist/team/__tests__/runtime.test.js +195 -9
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +132 -2
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.d.ts +2 -0
- package/dist/team/__tests__/state-root.test.d.ts.map +1 -0
- package/dist/team/__tests__/state-root.test.js +9 -0
- package/dist/team/__tests__/state-root.test.js.map +1 -0
- package/dist/team/__tests__/state.test.js +52 -17
- package/dist/team/__tests__/state.test.js.map +1 -1
- package/dist/team/__tests__/team-ops-contract.test.d.ts +2 -0
- package/dist/team/__tests__/team-ops-contract.test.d.ts.map +1 -0
- package/dist/team/__tests__/team-ops-contract.test.js +90 -0
- package/dist/team/__tests__/team-ops-contract.test.js.map +1 -0
- package/dist/team/__tests__/tmux-session.test.js +94 -7
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +59 -0
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/__tests__/worktree.test.js +81 -2
- package/dist/team/__tests__/worktree.test.js.map +1 -1
- package/dist/team/idle-nudge.d.ts +53 -0
- package/dist/team/idle-nudge.d.ts.map +1 -0
- package/dist/team/idle-nudge.js +140 -0
- package/dist/team/idle-nudge.js.map +1 -0
- package/dist/team/mcp-comm.d.ts +1 -1
- package/dist/team/mcp-comm.d.ts.map +1 -1
- package/dist/team/mcp-comm.js +6 -2
- package/dist/team/mcp-comm.js.map +1 -1
- package/dist/team/orchestrator.d.ts +1 -10
- package/dist/team/orchestrator.d.ts.map +1 -1
- package/dist/team/orchestrator.js +8 -0
- package/dist/team/orchestrator.js.map +1 -1
- package/dist/team/role-router.d.ts +32 -0
- package/dist/team/role-router.d.ts.map +1 -0
- package/dist/team/role-router.js +137 -0
- package/dist/team/role-router.js.map +1 -0
- package/dist/team/runtime-cli.d.ts +18 -0
- package/dist/team/runtime-cli.d.ts.map +1 -0
- package/dist/team/runtime-cli.js +244 -0
- package/dist/team/runtime-cli.js.map +1 -0
- package/dist/team/runtime.d.ts +6 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +148 -60
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts +1 -0
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +74 -32
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/approvals.d.ts +25 -0
- package/dist/team/state/approvals.d.ts.map +1 -0
- package/dist/team/state/approvals.js +31 -0
- package/dist/team/state/approvals.js.map +1 -0
- package/dist/team/state/config.d.ts +2 -0
- package/dist/team/state/config.d.ts.map +1 -0
- package/dist/team/state/config.js +2 -0
- package/dist/team/state/config.js.map +1 -0
- package/dist/team/state/dispatch-lock.d.ts +3 -0
- package/dist/team/state/dispatch-lock.d.ts.map +1 -0
- package/dist/team/state/dispatch-lock.js +81 -0
- package/dist/team/state/dispatch-lock.js.map +1 -0
- package/dist/team/state/dispatch.d.ts +61 -0
- package/dist/team/state/dispatch.d.ts.map +1 -0
- package/dist/team/state/dispatch.js +158 -0
- package/dist/team/state/dispatch.js.map +1 -0
- package/dist/team/state/events.d.ts +2 -0
- package/dist/team/state/events.d.ts.map +1 -0
- package/dist/team/state/events.js +2 -0
- package/dist/team/state/events.js.map +1 -0
- package/dist/team/state/index.d.ts +11 -0
- package/dist/team/state/index.d.ts.map +1 -0
- package/dist/team/state/index.js +11 -0
- package/dist/team/state/index.js.map +1 -0
- package/dist/team/state/io.d.ts +2 -0
- package/dist/team/state/io.d.ts.map +1 -0
- package/dist/team/state/io.js +2 -0
- package/dist/team/state/io.js.map +1 -0
- package/dist/team/state/locks.d.ts +16 -0
- package/dist/team/state/locks.d.ts.map +1 -0
- package/dist/team/state/locks.js +201 -0
- package/dist/team/state/locks.js.map +1 -0
- package/dist/team/state/mailbox.d.ts +39 -0
- package/dist/team/state/mailbox.d.ts.map +1 -0
- package/dist/team/state/mailbox.js +58 -0
- package/dist/team/state/mailbox.js.map +1 -0
- package/dist/team/state/monitor.d.ts +96 -0
- package/dist/team/state/monitor.d.ts.map +1 -0
- package/dist/team/state/monitor.js +163 -0
- package/dist/team/state/monitor.js.map +1 -0
- package/dist/team/state/shutdown.d.ts +2 -0
- package/dist/team/state/shutdown.d.ts.map +1 -0
- package/dist/team/state/shutdown.js +2 -0
- package/dist/team/state/shutdown.js.map +1 -0
- package/dist/team/state/summary.d.ts +2 -0
- package/dist/team/state/summary.d.ts.map +1 -0
- package/dist/team/state/summary.js +2 -0
- package/dist/team/state/summary.js.map +1 -0
- package/dist/team/state/tasks.d.ts +49 -0
- package/dist/team/state/tasks.d.ts.map +1 -0
- package/dist/team/state/tasks.js +182 -0
- package/dist/team/state/tasks.js.map +1 -0
- package/dist/team/state/types.d.ts +281 -0
- package/dist/team/state/types.d.ts.map +1 -0
- package/dist/team/state/types.js +3 -0
- package/dist/team/state/types.js.map +1 -0
- package/dist/team/state/workers.d.ts +2 -0
- package/dist/team/state/workers.d.ts.map +1 -0
- package/dist/team/state/workers.js +2 -0
- package/dist/team/state/workers.js.map +1 -0
- package/dist/team/state-root.d.ts +5 -0
- package/dist/team/state-root.d.ts.map +1 -0
- package/dist/team/state-root.js +8 -0
- package/dist/team/state-root.js.map +1 -0
- package/dist/team/state.d.ts +6 -2
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +200 -881
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts +42 -2
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +229 -74
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +2 -0
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +47 -20
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/team/worktree.d.ts +5 -1
- package/dist/team/worktree.d.ts.map +1 -1
- package/dist/team/worktree.js +71 -17
- package/dist/team/worktree.js.map +1 -1
- package/dist/utils/safe-json.d.ts +3 -0
- package/dist/utils/safe-json.d.ts.map +1 -0
- package/dist/utils/safe-json.js +19 -0
- package/dist/utils/safe-json.js.map +1 -0
- package/dist/utils/sleep.d.ts +3 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +15 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/visual/__tests__/verdict.test.d.ts +2 -0
- package/dist/visual/__tests__/verdict.test.d.ts.map +1 -0
- package/dist/visual/__tests__/verdict.test.js +81 -0
- package/dist/visual/__tests__/verdict.test.js.map +1 -0
- package/dist/visual/constants.d.ts +4 -0
- package/dist/visual/constants.d.ts.map +1 -0
- package/dist/visual/constants.js +3 -0
- package/dist/visual/constants.js.map +1 -0
- package/dist/visual/verdict.d.ts +17 -0
- package/dist/visual/verdict.d.ts.map +1 -0
- package/dist/visual/verdict.js +61 -0
- package/dist/visual/verdict.js.map +1 -0
- package/package.json +10 -3
- package/scripts/ask-claude.sh +17 -0
- package/scripts/ask-gemini.sh +14 -0
- package/scripts/fixtures/ask-advisor-stub.js +12 -0
- package/scripts/notify-hook/log.js +5 -0
- package/scripts/notify-hook/team-dispatch.js +56 -1
- package/scripts/notify-hook/tmux-injection.js +45 -4
- package/scripts/notify-hook/visual-verdict.js +158 -0
- package/scripts/notify-hook.js +27 -0
- package/scripts/run-provider-advisor.js +179 -0
- package/scripts/tmux-hook-engine.js +24 -0
- package/skills/ask-claude/SKILL.md +61 -0
- package/skills/ask-gemini/SKILL.md +61 -0
- package/skills/autopilot/SKILL.md +34 -4
- package/skills/configure-notifications/SKILL.md +1 -1
- package/skills/configure-openclaw/SKILL.md +154 -157
- package/skills/deep-interview/SKILL.md +247 -0
- package/skills/doctor/SKILL.md +1 -1
- package/skills/help/SKILL.md +3 -3
- package/skills/ralph/SKILL.md +42 -11
- package/skills/ralplan/SKILL.md +17 -0
- package/skills/skill/SKILL.md +32 -32
- package/skills/team/SKILL.md +60 -0
- package/skills/visual-verdict/SKILL.md +76 -0
- package/skills/web-clone/SKILL.md +366 -0
- package/skills/worker/SKILL.md +5 -4
- package/templates/AGENTS.md +9 -0
- package/templates/catalog-manifest.json +39 -2
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { spawnSync } from 'child_process';
|
|
1
|
+
import { spawnSync, execFile } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
2
3
|
import { readFileSync } from 'fs';
|
|
3
4
|
import { join } from 'path';
|
|
5
|
+
import { CODEX_BYPASS_FLAG, MADMAX_FLAG, CONFIG_FLAG, LONG_CONFIG_FLAG, MODEL_FLAG, } from '../cli/constants.js';
|
|
6
|
+
import { sleep, sleepSync } from '../utils/sleep.js';
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
4
8
|
import { HUD_RESIZE_RECONCILE_DELAY_SECONDS, HUD_TMUX_TEAM_HEIGHT_LINES } from '../hud/constants.js';
|
|
5
9
|
const INJECTION_MARKER = '[OMX_TMUX_INJECT]';
|
|
6
|
-
const CODEX_BYPASS_FLAG = '--dangerously-bypass-approvals-and-sandbox';
|
|
7
|
-
const MADMAX_FLAG = '--madmax';
|
|
8
|
-
const CONFIG_FLAG = '-c';
|
|
9
|
-
const LONG_CONFIG_FLAG = '--config';
|
|
10
|
-
const MODEL_FLAG = '--model';
|
|
11
10
|
const MODEL_INSTRUCTIONS_FILE_KEY = 'model_instructions_file';
|
|
12
11
|
const OMX_BYPASS_DEFAULT_SYSTEM_PROMPT_ENV = 'OMX_BYPASS_DEFAULT_SYSTEM_PROMPT';
|
|
13
12
|
const OMX_MODEL_INSTRUCTIONS_FILE_ENV = 'OMX_MODEL_INSTRUCTIONS_FILE';
|
|
@@ -99,9 +98,6 @@ function findHudPaneIds(target, leaderPaneId) {
|
|
|
99
98
|
.filter((pane) => isHudWatchPane(pane))
|
|
100
99
|
.map((pane) => pane.paneId);
|
|
101
100
|
}
|
|
102
|
-
function sleepMs(ms) {
|
|
103
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
104
|
-
}
|
|
105
101
|
const MAX_FRACTIONAL_SLEEP_MS = 60_000;
|
|
106
102
|
function toFractionalSleepMs(seconds) {
|
|
107
103
|
if (!Number.isFinite(seconds) || seconds <= 0)
|
|
@@ -114,12 +110,64 @@ function toFractionalSleepMs(seconds) {
|
|
|
114
110
|
function sleepSeconds(seconds) {
|
|
115
111
|
sleepFractionalSeconds(seconds);
|
|
116
112
|
}
|
|
117
|
-
export function sleepFractionalSeconds(seconds, sleepImpl =
|
|
113
|
+
export function sleepFractionalSeconds(seconds, sleepImpl = sleepSync) {
|
|
118
114
|
const ms = toFractionalSleepMs(seconds);
|
|
119
115
|
if (ms <= 0)
|
|
120
116
|
return;
|
|
121
117
|
sleepImpl(ms);
|
|
122
118
|
}
|
|
119
|
+
// ── Async tmux helpers ──────────────────────────────────────────────────────
|
|
120
|
+
async function runTmuxAsync(args) {
|
|
121
|
+
try {
|
|
122
|
+
const { stdout } = await execFileAsync('tmux', args, { encoding: 'utf-8' });
|
|
123
|
+
return { ok: true, stdout: (stdout || '').trim() };
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
const err = error;
|
|
127
|
+
return { ok: false, stderr: (err.stderr || err.message || '').trim() || 'tmux command failed' };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function sendKeyAsync(target, key) {
|
|
131
|
+
const result = await runTmuxAsync(['send-keys', '-t', target, key]);
|
|
132
|
+
if (!result.ok) {
|
|
133
|
+
throw new Error(`sendKeyAsync: failed to send ${key}: ${result.stderr}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async function capturePaneAsync(target) {
|
|
137
|
+
const result = await runTmuxAsync(['capture-pane', '-t', target, '-p', '-S', '-80']);
|
|
138
|
+
if (!result.ok)
|
|
139
|
+
return '';
|
|
140
|
+
return result.stdout;
|
|
141
|
+
}
|
|
142
|
+
async function isWorkerAliveAsync(sessionName, workerIndex, workerPaneId) {
|
|
143
|
+
const result = await runTmuxAsync([
|
|
144
|
+
'list-panes',
|
|
145
|
+
'-t', paneTarget(sessionName, workerIndex, workerPaneId),
|
|
146
|
+
'-F',
|
|
147
|
+
'#{pane_dead} #{pane_pid}',
|
|
148
|
+
]);
|
|
149
|
+
if (!result.ok)
|
|
150
|
+
return false;
|
|
151
|
+
const line = result.stdout.split('\n')[0]?.trim();
|
|
152
|
+
if (!line)
|
|
153
|
+
return false;
|
|
154
|
+
const parts = line.split(/\s+/);
|
|
155
|
+
if (parts.length < 2)
|
|
156
|
+
return false;
|
|
157
|
+
const paneDead = parts[0];
|
|
158
|
+
const pid = Number.parseInt(parts[1], 10);
|
|
159
|
+
if (paneDead === '1')
|
|
160
|
+
return false;
|
|
161
|
+
if (!Number.isFinite(pid))
|
|
162
|
+
return false;
|
|
163
|
+
try {
|
|
164
|
+
process.kill(pid, 0);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
123
171
|
function shellQuoteSingle(value) {
|
|
124
172
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
125
173
|
}
|
|
@@ -489,9 +537,14 @@ export function createTeamSession(teamName, workerCount, cwd, workerLaunchArgs =
|
|
|
489
537
|
let registeredResizeHook = null;
|
|
490
538
|
const rollbackPaneIds = [];
|
|
491
539
|
try {
|
|
492
|
-
const
|
|
540
|
+
const tmuxPaneTarget = process.env.TMUX_PANE;
|
|
541
|
+
const displayArgs = tmuxPaneTarget
|
|
542
|
+
? ['display-message', '-p', '-t', tmuxPaneTarget, '#S:#I #{pane_id}']
|
|
543
|
+
: ['display-message', '-p', '#S:#I #{pane_id}'];
|
|
544
|
+
const context = runTmux(displayArgs);
|
|
493
545
|
if (!context.ok) {
|
|
494
|
-
|
|
546
|
+
const paneHint = tmuxPaneTarget ? ` (TMUX_PANE=${tmuxPaneTarget})` : '';
|
|
547
|
+
throw new Error(`failed to detect current tmux target${paneHint}: ${context.stderr}`);
|
|
495
548
|
}
|
|
496
549
|
const [sessionAndWindow = '', detectedLeaderPaneId = ''] = context.stdout.split(' ');
|
|
497
550
|
const [sessionName, windowIndex] = (sessionAndWindow || '').split(':');
|
|
@@ -706,7 +759,7 @@ export function paneIsBootstrapping(lines) {
|
|
|
706
759
|
/\bmodel:\s*loading\b/i.test(line) ||
|
|
707
760
|
/\bconnecting\s+to\b/i.test(line));
|
|
708
761
|
}
|
|
709
|
-
function paneLooksReady(captured) {
|
|
762
|
+
export function paneLooksReady(captured) {
|
|
710
763
|
const content = captured.trimEnd();
|
|
711
764
|
if (content === '')
|
|
712
765
|
return false;
|
|
@@ -730,6 +783,11 @@ function paneLooksReady(captured) {
|
|
|
730
783
|
const hasClaudePromptLine = lines.some((line) => /^\s*❯\s*/u.test(line));
|
|
731
784
|
if (hasCodexPromptLine || hasClaudePromptLine)
|
|
732
785
|
return true;
|
|
786
|
+
// Custom per-issue prompts (e.g. "› IND-123 only..."). Capture output can
|
|
787
|
+
// occasionally omit the glyph, so accept both with/without leading prompt char.
|
|
788
|
+
const hasIssuePromptLine = lines.some((line) => /^\s*(?:[›>❯]\s*)?[A-Z][A-Z0-9]+-\d+\s+only(?:\s*(?:…|\.{3}))?\s*$/iu.test(line));
|
|
789
|
+
if (hasIssuePromptLine)
|
|
790
|
+
return true;
|
|
733
791
|
// Status-only markers (model name in status bar, token budget) are NOT
|
|
734
792
|
// sufficient on their own — they can appear during bootstrap before the CLI
|
|
735
793
|
// accepts input. Require an actual prompt character (checked above).
|
|
@@ -745,12 +803,15 @@ function paneHasTrustPrompt(captured) {
|
|
|
745
803
|
const hasActiveChoices = tail.some((line) => /Yes,\s*continue|No,\s*quit|Press enter to continue/i.test(line));
|
|
746
804
|
return hasQuestion && hasActiveChoices;
|
|
747
805
|
}
|
|
748
|
-
function paneHasActiveTask(captured) {
|
|
806
|
+
export function paneHasActiveTask(captured) {
|
|
749
807
|
const lines = captured
|
|
750
808
|
.split('\n')
|
|
751
809
|
.map((line) => line.replace(/\r/g, '').trim())
|
|
752
810
|
.filter((line) => line.length > 0);
|
|
753
811
|
const tail = lines.slice(-40);
|
|
812
|
+
// Codex v5 status line can appear without "esc to interrupt"; treat as busy first.
|
|
813
|
+
if (tail.some((line) => /\b\d+\s+background terminal running\b/i.test(line)))
|
|
814
|
+
return true;
|
|
754
815
|
if (tail.some((line) => /esc to interrupt/i.test(line)))
|
|
755
816
|
return true;
|
|
756
817
|
if (tail.some((line) => /\bbackground terminal running\b/i.test(line)))
|
|
@@ -836,39 +897,34 @@ export function shouldAttemptAdaptiveRetry(strategy, paneBusyAtStart, allowAdapt
|
|
|
836
897
|
return false;
|
|
837
898
|
return true;
|
|
838
899
|
}
|
|
839
|
-
function sendKeyOrThrow(target, key, label) {
|
|
840
|
-
const result = runTmux(['send-keys', '-t', target, key]);
|
|
841
|
-
if (!result.ok) {
|
|
842
|
-
throw new Error(`sendToWorker: failed to send ${label}: ${result.stderr}`);
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
900
|
function sendLiteralTextOrThrow(target, text) {
|
|
846
901
|
const send = runTmux(['send-keys', '-t', target, '-l', '--', text]);
|
|
847
902
|
if (!send.ok) {
|
|
848
903
|
throw new Error(`sendToWorker: failed to send text: ${send.stderr}`);
|
|
849
904
|
}
|
|
850
905
|
}
|
|
851
|
-
function attemptSubmitRounds(target, text, rounds, queueFirstRound, submitKeyPressesPerRound) {
|
|
906
|
+
async function attemptSubmitRounds(target, text, rounds, queueFirstRound, submitKeyPressesPerRound) {
|
|
852
907
|
const presses = Math.max(1, Math.floor(submitKeyPressesPerRound));
|
|
853
908
|
for (let round = 0; round < rounds; round++) {
|
|
854
|
-
|
|
909
|
+
await sleep(100);
|
|
855
910
|
if (round === 0 && queueFirstRound) {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
911
|
+
await sendKeyAsync(target, 'Tab');
|
|
912
|
+
await sleep(80);
|
|
913
|
+
await sendKeyAsync(target, 'C-m');
|
|
859
914
|
}
|
|
860
915
|
else {
|
|
861
916
|
for (let press = 0; press < presses; press++) {
|
|
862
|
-
|
|
917
|
+
await sendKeyAsync(target, 'C-m');
|
|
863
918
|
if (press < presses - 1) {
|
|
864
|
-
|
|
919
|
+
await sleep(200);
|
|
865
920
|
}
|
|
866
921
|
}
|
|
867
922
|
}
|
|
868
|
-
|
|
869
|
-
|
|
923
|
+
await sleep(140);
|
|
924
|
+
const captured = await capturePaneAsync(target);
|
|
925
|
+
if (!normalizeTmuxCapture(captured).includes(normalizeTmuxCapture(text)))
|
|
870
926
|
return true;
|
|
871
|
-
|
|
927
|
+
await sleep(140);
|
|
872
928
|
}
|
|
873
929
|
return false;
|
|
874
930
|
}
|
|
@@ -948,12 +1004,6 @@ export function dismissTrustPromptIfPresent(sessionName, workerIndex, workerPane
|
|
|
948
1004
|
runTmux(['send-keys', '-t', target, 'C-m']);
|
|
949
1005
|
return true;
|
|
950
1006
|
}
|
|
951
|
-
function paneTailContainsLiteralLine(target, text) {
|
|
952
|
-
const result = runTmux(['capture-pane', '-t', target, '-p', '-S', '-80']);
|
|
953
|
-
if (!result.ok)
|
|
954
|
-
return false;
|
|
955
|
-
return normalizeTmuxCapture(result.stdout).includes(normalizeTmuxCapture(text));
|
|
956
|
-
}
|
|
957
1007
|
export function normalizeTmuxCapture(value) {
|
|
958
1008
|
return value
|
|
959
1009
|
.replace(/\r/g, '')
|
|
@@ -981,47 +1031,46 @@ export function sendToWorkerStdin(stdin, text) {
|
|
|
981
1031
|
// Send SHORT text (<200 chars) to worker via tmux send-keys
|
|
982
1032
|
// Validates: text < 200 chars, no injection marker
|
|
983
1033
|
// Throws on violation
|
|
984
|
-
export function sendToWorker(sessionName, workerIndex, text, workerPaneId, workerCli) {
|
|
1034
|
+
export async function sendToWorker(sessionName, workerIndex, text, workerPaneId, workerCli) {
|
|
985
1035
|
assertWorkerTriggerText(text);
|
|
986
1036
|
const target = paneTarget(sessionName, workerIndex, workerPaneId);
|
|
987
1037
|
const strategy = resolveSendStrategyFromEnv();
|
|
988
1038
|
const resolvedWorkerCli = resolveWorkerCliForSend(workerIndex, workerCli);
|
|
989
1039
|
// Guard: if the trust prompt is still present, advance it first so our trigger text
|
|
990
1040
|
// doesn't get typed into the trust screen and ignored.
|
|
991
|
-
const
|
|
992
|
-
const paneBusy =
|
|
993
|
-
if (
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1041
|
+
const capturedStr = await capturePaneAsync(target);
|
|
1042
|
+
const paneBusy = paneHasActiveTask(capturedStr);
|
|
1043
|
+
if (paneHasTrustPrompt(capturedStr)) {
|
|
1044
|
+
await sendKeyAsync(target, 'C-m');
|
|
1045
|
+
await sleep(120);
|
|
1046
|
+
await sendKeyAsync(target, 'C-m');
|
|
1047
|
+
await sleep(200);
|
|
998
1048
|
}
|
|
999
1049
|
sendLiteralTextOrThrow(target, text);
|
|
1000
1050
|
// Allow the input buffer to settle before sending C-m
|
|
1001
|
-
|
|
1051
|
+
await sleep(150);
|
|
1002
1052
|
const allowAutoInterruptRetry = process.env[OMX_TEAM_AUTO_INTERRUPT_RETRY_ENV] !== '0';
|
|
1003
1053
|
const submitPlan = buildWorkerSubmitPlan(strategy, resolvedWorkerCli, paneBusy, allowAutoInterruptRetry);
|
|
1004
1054
|
if (submitPlan.shouldInterrupt) {
|
|
1005
1055
|
// Explicit interrupt mode: abort current turn first, then submit the new command.
|
|
1006
|
-
|
|
1007
|
-
|
|
1056
|
+
await sendKeyAsync(target, 'C-c');
|
|
1057
|
+
await sleep(100);
|
|
1008
1058
|
}
|
|
1009
1059
|
// Submit deterministically using CLI-specific plan:
|
|
1010
1060
|
// - Codex: queue-first Tab+C-m when configured/busy, then double C-m rounds.
|
|
1011
1061
|
// - Claude: direct C-m rounds only (never queue-first Tab).
|
|
1012
|
-
if (attemptSubmitRounds(target, text, submitPlan.rounds, submitPlan.queueFirstRound, submitPlan.submitKeyPressesPerRound))
|
|
1062
|
+
if (await attemptSubmitRounds(target, text, submitPlan.rounds, submitPlan.queueFirstRound, submitPlan.submitKeyPressesPerRound))
|
|
1013
1063
|
return;
|
|
1014
1064
|
// Adaptive escalation for "likely unsent trigger text at ready prompt" cases:
|
|
1015
1065
|
// clear line, re-send trigger, then re-submit with deterministic C-m rounds.
|
|
1016
|
-
const
|
|
1017
|
-
|
|
1018
|
-
if (shouldAttemptAdaptiveRetry(strategy, paneBusy, submitPlan.allowAdaptiveRetry, latestCapture, text)) {
|
|
1066
|
+
const latestCapture = await capturePaneAsync(target);
|
|
1067
|
+
if (shouldAttemptAdaptiveRetry(strategy, paneBusy, submitPlan.allowAdaptiveRetry, latestCapture || null, text)) {
|
|
1019
1068
|
// Keep this branch non-interrupting to avoid canceling active turns on false positives.
|
|
1020
|
-
|
|
1021
|
-
|
|
1069
|
+
await sendKeyAsync(target, 'C-u');
|
|
1070
|
+
await sleep(80);
|
|
1022
1071
|
sendLiteralTextOrThrow(target, text);
|
|
1023
|
-
|
|
1024
|
-
if (attemptSubmitRounds(target, text, 4, false, submitPlan.submitKeyPressesPerRound))
|
|
1072
|
+
await sleep(120);
|
|
1073
|
+
if (await attemptSubmitRounds(target, text, 4, false, submitPlan.submitKeyPressesPerRound))
|
|
1025
1074
|
return;
|
|
1026
1075
|
}
|
|
1027
1076
|
// Fail-open by default: Codex may keep the last submitted line visible even after executing it.
|
|
@@ -1031,22 +1080,22 @@ export function sendToWorker(sessionName, workerIndex, text, workerPaneId, worke
|
|
|
1031
1080
|
throw new Error('sendToWorker: submit_failed (trigger text still visible after retries)');
|
|
1032
1081
|
}
|
|
1033
1082
|
// One last best-effort double C-m nudge, then verify.
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1083
|
+
await sendKeyAsync(target, 'C-m');
|
|
1084
|
+
await sleep(120);
|
|
1085
|
+
await sendKeyAsync(target, 'C-m');
|
|
1037
1086
|
// Post-submit verification: wait briefly and confirm the worker consumed the
|
|
1038
1087
|
// trigger (draft disappeared or active-task indicator appeared). Fixes #391.
|
|
1039
|
-
|
|
1040
|
-
const
|
|
1041
|
-
if (
|
|
1042
|
-
if (paneHasActiveTask(
|
|
1088
|
+
await sleep(300);
|
|
1089
|
+
const verifyCapture = await capturePaneAsync(target);
|
|
1090
|
+
if (verifyCapture) {
|
|
1091
|
+
if (paneHasActiveTask(verifyCapture))
|
|
1043
1092
|
return;
|
|
1044
|
-
if (!
|
|
1093
|
+
if (!normalizeTmuxCapture(verifyCapture).includes(normalizeTmuxCapture(text)))
|
|
1045
1094
|
return;
|
|
1046
1095
|
// Draft still visible and no active task — one more C-m attempt.
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1096
|
+
await sendKeyAsync(target, 'C-m');
|
|
1097
|
+
await sleep(150);
|
|
1098
|
+
await sendKeyAsync(target, 'C-m');
|
|
1050
1099
|
}
|
|
1051
1100
|
}
|
|
1052
1101
|
export function notifyLeaderStatus(sessionName, message) {
|
|
@@ -1104,18 +1153,18 @@ export function isWorkerAlive(sessionName, workerIndex, workerPaneId) {
|
|
|
1104
1153
|
}
|
|
1105
1154
|
// Kill a specific worker: send C-c, then C-d, then kill-pane if still alive.
|
|
1106
1155
|
// leaderPaneId: when provided, the kill is skipped entirely if workerPaneId matches it.
|
|
1107
|
-
export function killWorker(sessionName, workerIndex, workerPaneId, leaderPaneId) {
|
|
1156
|
+
export async function killWorker(sessionName, workerIndex, workerPaneId, leaderPaneId) {
|
|
1108
1157
|
// Guard: never kill the leader's own pane.
|
|
1109
1158
|
if (leaderPaneId && workerPaneId === leaderPaneId)
|
|
1110
1159
|
return;
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
if (
|
|
1114
|
-
|
|
1115
|
-
|
|
1160
|
+
await runTmuxAsync(['send-keys', '-t', paneTarget(sessionName, workerIndex, workerPaneId), 'C-c']);
|
|
1161
|
+
await sleep(1000);
|
|
1162
|
+
if (await isWorkerAliveAsync(sessionName, workerIndex, workerPaneId)) {
|
|
1163
|
+
await runTmuxAsync(['send-keys', '-t', paneTarget(sessionName, workerIndex, workerPaneId), 'C-d']);
|
|
1164
|
+
await sleep(1000);
|
|
1116
1165
|
}
|
|
1117
|
-
if (
|
|
1118
|
-
|
|
1166
|
+
if (await isWorkerAliveAsync(sessionName, workerIndex, workerPaneId)) {
|
|
1167
|
+
await runTmuxAsync(['kill-pane', '-t', paneTarget(sessionName, workerIndex, workerPaneId)]);
|
|
1119
1168
|
}
|
|
1120
1169
|
}
|
|
1121
1170
|
// leaderPaneId: when provided, the kill is skipped if workerPaneId matches it.
|
|
@@ -1127,6 +1176,81 @@ export function killWorkerByPaneId(workerPaneId, leaderPaneId) {
|
|
|
1127
1176
|
return;
|
|
1128
1177
|
runTmux(['kill-pane', '-t', workerPaneId]);
|
|
1129
1178
|
}
|
|
1179
|
+
export async function killWorkerByPaneIdAsync(workerPaneId, leaderPaneId) {
|
|
1180
|
+
if (!workerPaneId.startsWith('%'))
|
|
1181
|
+
return;
|
|
1182
|
+
// Guard: never kill the leader's own pane.
|
|
1183
|
+
if (leaderPaneId && workerPaneId === leaderPaneId)
|
|
1184
|
+
return;
|
|
1185
|
+
await runTmuxAsync(['kill-pane', '-t', workerPaneId]);
|
|
1186
|
+
}
|
|
1187
|
+
function normalizePaneTarget(value) {
|
|
1188
|
+
if (typeof value !== 'string')
|
|
1189
|
+
return null;
|
|
1190
|
+
const trimmed = value.trim();
|
|
1191
|
+
if (!trimmed.startsWith('%'))
|
|
1192
|
+
return null;
|
|
1193
|
+
return trimmed;
|
|
1194
|
+
}
|
|
1195
|
+
function normalizePaneTargets(paneIds, options = {}) {
|
|
1196
|
+
const leaderPaneId = normalizePaneTarget(options.leaderPaneId);
|
|
1197
|
+
const hudPaneId = normalizePaneTarget(options.hudPaneId);
|
|
1198
|
+
const excluded = { leader: 0, hud: 0, invalid: 0 };
|
|
1199
|
+
const deduped = new Set();
|
|
1200
|
+
const killablePaneIds = [];
|
|
1201
|
+
for (const paneId of paneIds) {
|
|
1202
|
+
const normalized = normalizePaneTarget(paneId);
|
|
1203
|
+
if (!normalized) {
|
|
1204
|
+
excluded.invalid += 1;
|
|
1205
|
+
continue;
|
|
1206
|
+
}
|
|
1207
|
+
if (leaderPaneId && normalized === leaderPaneId) {
|
|
1208
|
+
excluded.leader += 1;
|
|
1209
|
+
continue;
|
|
1210
|
+
}
|
|
1211
|
+
if (hudPaneId && normalized === hudPaneId) {
|
|
1212
|
+
excluded.hud += 1;
|
|
1213
|
+
continue;
|
|
1214
|
+
}
|
|
1215
|
+
if (deduped.has(normalized))
|
|
1216
|
+
continue;
|
|
1217
|
+
deduped.add(normalized);
|
|
1218
|
+
killablePaneIds.push(normalized);
|
|
1219
|
+
}
|
|
1220
|
+
return { killablePaneIds, excluded };
|
|
1221
|
+
}
|
|
1222
|
+
/**
|
|
1223
|
+
* Shared pane-id-direct teardown primitive for worker pane cleanup.
|
|
1224
|
+
* Must remain liveness-agnostic: do not gate on isWorkerAlive/killWorker.
|
|
1225
|
+
*/
|
|
1226
|
+
export async function teardownWorkerPanes(paneIds, options = {}) {
|
|
1227
|
+
const { killablePaneIds, excluded } = normalizePaneTargets(paneIds, options);
|
|
1228
|
+
const graceMs = options.graceMs ?? 2000;
|
|
1229
|
+
const perPaneGrace = killablePaneIds.length > 0
|
|
1230
|
+
? Math.max(100, Math.floor(graceMs / killablePaneIds.length))
|
|
1231
|
+
: 0;
|
|
1232
|
+
const summary = {
|
|
1233
|
+
attemptedPaneIds: killablePaneIds,
|
|
1234
|
+
excluded,
|
|
1235
|
+
kill: {
|
|
1236
|
+
attempted: killablePaneIds.length,
|
|
1237
|
+
succeeded: 0,
|
|
1238
|
+
failed: 0,
|
|
1239
|
+
},
|
|
1240
|
+
};
|
|
1241
|
+
for (const paneId of killablePaneIds) {
|
|
1242
|
+
const result = await runTmuxAsync(['kill-pane', '-t', paneId]);
|
|
1243
|
+
if (result.ok)
|
|
1244
|
+
summary.kill.succeeded += 1;
|
|
1245
|
+
else
|
|
1246
|
+
summary.kill.failed += 1;
|
|
1247
|
+
await sleep(perPaneGrace);
|
|
1248
|
+
}
|
|
1249
|
+
return summary;
|
|
1250
|
+
}
|
|
1251
|
+
export async function killWorkerPanes(paneIds, leaderPaneId, graceMs = 2000, hudPaneId) {
|
|
1252
|
+
return teardownWorkerPanes(paneIds, { leaderPaneId, hudPaneId: hudPaneId ?? null, graceMs });
|
|
1253
|
+
}
|
|
1130
1254
|
// Kill entire tmux session. Tolerates already-dead sessions.
|
|
1131
1255
|
export function destroyTeamSession(sessionName) {
|
|
1132
1256
|
try {
|
|
@@ -1147,4 +1271,35 @@ export function listTeamSessions() {
|
|
|
1147
1271
|
.filter(Boolean)
|
|
1148
1272
|
.map(baseSessionName);
|
|
1149
1273
|
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Send a trigger message directly to the leader pane via tmux send-keys.
|
|
1276
|
+
* Used as the direct-inject fallback when hook-based dispatch to the leader
|
|
1277
|
+
* times out. Unlike notifyLeaderMailboxAsync (which only writes to the
|
|
1278
|
+
* mailbox file), this actually injects text into the leader's tmux pane
|
|
1279
|
+
* so the leader sees it immediately. Fixes #437.
|
|
1280
|
+
*/
|
|
1281
|
+
export async function sendToLeaderPane(leaderPaneId, text) {
|
|
1282
|
+
const send = runTmux(['send-keys', '-t', leaderPaneId, '-l', '--', text]);
|
|
1283
|
+
if (!send.ok) {
|
|
1284
|
+
throw new Error(`sendToLeaderPane: failed to send text: ${send.stderr}`);
|
|
1285
|
+
}
|
|
1286
|
+
await sleep(150);
|
|
1287
|
+
await sendKeyAsync(leaderPaneId, 'C-m');
|
|
1288
|
+
await sleep(100);
|
|
1289
|
+
await sendKeyAsync(leaderPaneId, 'C-m');
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Notify the leader via mailbox instead of tmux display-message.
|
|
1293
|
+
* This is the async mailbox-based replacement for notifyLeaderStatus.
|
|
1294
|
+
*/
|
|
1295
|
+
export async function notifyLeaderMailboxAsync(teamName, fromWorker, message, cwd) {
|
|
1296
|
+
try {
|
|
1297
|
+
const { sendDirectMessage } = await import('./state.js');
|
|
1298
|
+
await sendDirectMessage(teamName, fromWorker, 'leader-fixed', message, cwd);
|
|
1299
|
+
return true;
|
|
1300
|
+
}
|
|
1301
|
+
catch {
|
|
1302
|
+
return false;
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1150
1305
|
//# sourceMappingURL=tmux-session.js.map
|