claudecode-omc 4.8.4 → 4.9.4
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +3 -3
- package/README.de.md +26 -0
- package/README.es.md +26 -0
- package/README.fr.md +26 -0
- package/README.it.md +26 -0
- package/README.ja.md +26 -0
- package/README.ko.md +26 -0
- package/README.md +80 -133
- package/README.pt.md +26 -0
- package/README.ru.md +26 -0
- package/README.tr.md +26 -0
- package/README.vi.md +26 -0
- package/README.zh.md +26 -0
- package/agents/analyst.md +1 -0
- package/agents/architect.md +1 -0
- package/agents/code-reviewer.md +1 -0
- package/agents/code-simplifier.md +1 -0
- package/agents/critic.md +1 -0
- package/agents/debugger.md +1 -0
- package/agents/designer.md +1 -0
- package/agents/document-specialist.md +1 -0
- package/agents/executor.md +1 -0
- package/agents/explore.md +21 -19
- package/agents/git-master.md +1 -0
- package/agents/planner.md +1 -0
- package/agents/qa-tester.md +1 -0
- package/agents/scientist.md +1 -0
- package/agents/security-reviewer.md +1 -0
- package/agents/test-engineer.md +1 -0
- package/agents/tracer.md +161 -0
- package/agents/verifier.md +21 -13
- package/agents/writer.md +1 -0
- package/bridge/cli.cjs +37707 -25194
- package/bridge/gyoshu_bridge.py +60 -15
- package/bridge/mcp-server.cjs +1323 -503
- package/bridge/runtime-cli.cjs +1220 -328
- package/bridge/team-bridge.cjs +140 -112
- package/bridge/team-mcp.cjs +325 -107
- package/bridge/team.js +2572 -1462
- package/dist/__tests__/agent-registry.test.js +5 -3
- package/dist/__tests__/agent-registry.test.js.map +1 -1
- package/dist/__tests__/auto-slash-aliases.test.js +149 -68
- package/dist/__tests__/auto-slash-aliases.test.js.map +1 -1
- package/dist/__tests__/auto-update.test.js +502 -3
- package/dist/__tests__/auto-update.test.js.map +1 -1
- package/dist/__tests__/background-cleanup-directory.test.d.ts +2 -0
- package/dist/__tests__/background-cleanup-directory.test.d.ts.map +1 -0
- package/dist/__tests__/background-cleanup-directory.test.js +57 -0
- package/dist/__tests__/background-cleanup-directory.test.js.map +1 -0
- package/dist/__tests__/bedrock-lm-suffix-hook.test.d.ts +24 -0
- package/dist/__tests__/bedrock-lm-suffix-hook.test.d.ts.map +1 -0
- package/dist/__tests__/bedrock-lm-suffix-hook.test.js +210 -0
- package/dist/__tests__/bedrock-lm-suffix-hook.test.js.map +1 -0
- package/dist/__tests__/cleanup-validation.test.js +5 -3
- package/dist/__tests__/cleanup-validation.test.js.map +1 -1
- package/dist/__tests__/context-guard-stop.test.js +20 -0
- package/dist/__tests__/context-guard-stop.test.js.map +1 -1
- package/dist/__tests__/context-safety.test.js +51 -22
- package/dist/__tests__/context-safety.test.js.map +1 -1
- package/dist/__tests__/deep-interview-provider-options.test.d.ts +2 -0
- package/dist/__tests__/deep-interview-provider-options.test.d.ts.map +1 -0
- package/dist/__tests__/deep-interview-provider-options.test.js +79 -0
- package/dist/__tests__/deep-interview-provider-options.test.js.map +1 -0
- package/dist/__tests__/delegation-enforcement-levels.test.js +4 -0
- package/dist/__tests__/delegation-enforcement-levels.test.js.map +1 -1
- package/dist/__tests__/delegation-enforcer.test.js +12 -0
- package/dist/__tests__/delegation-enforcer.test.js.map +1 -1
- package/dist/__tests__/doctor-conflicts.test.js +111 -24
- package/dist/__tests__/doctor-conflicts.test.js.map +1 -1
- package/dist/__tests__/featured-contributors-generator.test.d.ts +2 -0
- package/dist/__tests__/featured-contributors-generator.test.d.ts.map +1 -0
- package/dist/__tests__/featured-contributors-generator.test.js +118 -0
- package/dist/__tests__/featured-contributors-generator.test.js.map +1 -0
- package/dist/__tests__/hooks/learner/bridge.test.js +27 -1
- package/dist/__tests__/hooks/learner/bridge.test.js.map +1 -1
- package/dist/__tests__/hooks/learner/transliteration-map.test.d.ts +8 -0
- package/dist/__tests__/hooks/learner/transliteration-map.test.d.ts.map +1 -0
- package/dist/__tests__/hooks/learner/transliteration-map.test.js +183 -0
- package/dist/__tests__/hooks/learner/transliteration-map.test.js.map +1 -0
- package/dist/__tests__/hooks-command-escaping.test.d.ts +2 -0
- package/dist/__tests__/hooks-command-escaping.test.d.ts.map +1 -0
- package/dist/__tests__/hooks-command-escaping.test.js +41 -0
- package/dist/__tests__/hooks-command-escaping.test.js.map +1 -0
- package/dist/__tests__/hooks.test.js +13 -9
- package/dist/__tests__/hooks.test.js.map +1 -1
- package/dist/__tests__/hud/background-tasks.test.d.ts +2 -0
- package/dist/__tests__/hud/background-tasks.test.d.ts.map +1 -0
- package/dist/__tests__/hud/background-tasks.test.js +90 -0
- package/dist/__tests__/hud/background-tasks.test.js.map +1 -0
- package/dist/__tests__/hud/context.test.d.ts +2 -0
- package/dist/__tests__/hud/context.test.d.ts.map +1 -0
- package/dist/__tests__/hud/context.test.js +47 -0
- package/dist/__tests__/hud/context.test.js.map +1 -0
- package/dist/__tests__/hud/defaults.test.js +11 -0
- package/dist/__tests__/hud/defaults.test.js.map +1 -1
- package/dist/__tests__/hud/git.test.js +2 -1
- package/dist/__tests__/hud/git.test.js.map +1 -1
- package/dist/__tests__/hud/mission-board-state.test.js +32 -0
- package/dist/__tests__/hud/mission-board-state.test.js.map +1 -1
- package/dist/__tests__/hud/mission-board.test.js +1 -0
- package/dist/__tests__/hud/mission-board.test.js.map +1 -1
- package/dist/__tests__/hud/omc-state.test.d.ts +2 -0
- package/dist/__tests__/hud/omc-state.test.d.ts.map +1 -0
- package/dist/__tests__/hud/omc-state.test.js +123 -0
- package/dist/__tests__/hud/omc-state.test.js.map +1 -0
- package/dist/__tests__/hud/render-rate-limits-priority.test.js +1 -0
- package/dist/__tests__/hud/render-rate-limits-priority.test.js.map +1 -1
- package/dist/__tests__/hud/render.test.js +125 -0
- package/dist/__tests__/hud/render.test.js.map +1 -1
- package/dist/__tests__/hud/state.test.js +104 -47
- package/dist/__tests__/hud/state.test.js.map +1 -1
- package/dist/__tests__/hud/stdin.test.d.ts +2 -0
- package/dist/__tests__/hud/stdin.test.d.ts.map +1 -0
- package/dist/__tests__/hud/stdin.test.js +108 -0
- package/dist/__tests__/hud/stdin.test.js.map +1 -0
- package/dist/__tests__/hud/token-usage.test.d.ts +2 -0
- package/dist/__tests__/hud/token-usage.test.d.ts.map +1 -0
- package/dist/__tests__/hud/token-usage.test.js +143 -0
- package/dist/__tests__/hud/token-usage.test.js.map +1 -0
- package/dist/__tests__/hud/usage-api-lock.test.js +6 -3
- package/dist/__tests__/hud/usage-api-lock.test.js.map +1 -1
- package/dist/__tests__/hud/usage-api-stale.test.js +4 -2
- package/dist/__tests__/hud/usage-api-stale.test.js.map +1 -1
- package/dist/__tests__/hud/usage-api.test.js +128 -1
- package/dist/__tests__/hud/usage-api.test.js.map +1 -1
- package/dist/__tests__/hud/version-display.test.js +1 -0
- package/dist/__tests__/hud/version-display.test.js.map +1 -1
- package/dist/__tests__/hud/watch-mode-init.test.js +25 -3
- package/dist/__tests__/hud/watch-mode-init.test.js.map +1 -1
- package/dist/__tests__/hud-marketplace-resolution.test.js +25 -0
- package/dist/__tests__/hud-marketplace-resolution.test.js.map +1 -1
- package/dist/__tests__/hud-windows.test.js +11 -0
- package/dist/__tests__/hud-windows.test.js.map +1 -1
- package/dist/__tests__/installer-mcp-config.test.d.ts +2 -0
- package/dist/__tests__/installer-mcp-config.test.d.ts.map +1 -0
- package/dist/__tests__/installer-mcp-config.test.js +119 -0
- package/dist/__tests__/installer-mcp-config.test.js.map +1 -0
- package/dist/__tests__/installer-omc-reference.test.d.ts +2 -0
- package/dist/__tests__/installer-omc-reference.test.d.ts.map +1 -0
- package/dist/__tests__/installer-omc-reference.test.js +85 -0
- package/dist/__tests__/installer-omc-reference.test.js.map +1 -0
- package/dist/__tests__/job-management-sqlite.test.js +1 -1
- package/dist/__tests__/job-state-db.test.js +1 -1
- package/dist/__tests__/jobid-collision-safety.test.d.ts +10 -0
- package/dist/__tests__/jobid-collision-safety.test.d.ts.map +1 -0
- package/dist/__tests__/jobid-collision-safety.test.js +51 -0
- package/dist/__tests__/jobid-collision-safety.test.js.map +1 -0
- package/dist/__tests__/live-data.test.js +21 -0
- package/dist/__tests__/live-data.test.js.map +1 -1
- package/dist/__tests__/load-agent-prompt.test.js +10 -0
- package/dist/__tests__/load-agent-prompt.test.js.map +1 -1
- package/dist/__tests__/lsp-servers.test.js +14 -2
- package/dist/__tests__/lsp-servers.test.js.map +1 -1
- package/dist/__tests__/marketplace-metadata.test.d.ts +2 -0
- package/dist/__tests__/marketplace-metadata.test.d.ts.map +1 -0
- package/dist/__tests__/marketplace-metadata.test.js +20 -0
- package/dist/__tests__/marketplace-metadata.test.js.map +1 -0
- package/dist/__tests__/mcp-comm-inbox-dedup.test.d.ts +2 -0
- package/dist/__tests__/mcp-comm-inbox-dedup.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-comm-inbox-dedup.test.js +105 -0
- package/dist/__tests__/mcp-comm-inbox-dedup.test.js.map +1 -0
- package/dist/__tests__/mnemosyne/finder.test.js +10 -0
- package/dist/__tests__/mnemosyne/finder.test.js.map +1 -1
- package/dist/__tests__/mode-names-ralplan.test.d.ts +2 -0
- package/dist/__tests__/mode-names-ralplan.test.d.ts.map +1 -0
- package/dist/__tests__/mode-names-ralplan.test.js +31 -0
- package/dist/__tests__/mode-names-ralplan.test.js.map +1 -0
- package/dist/__tests__/model-routing-esm.test.d.ts +2 -0
- package/dist/__tests__/model-routing-esm.test.d.ts.map +1 -0
- package/dist/__tests__/model-routing-esm.test.js +26 -0
- package/dist/__tests__/model-routing-esm.test.js.map +1 -0
- package/dist/__tests__/notepad.test.js +20 -0
- package/dist/__tests__/notepad.test.js.map +1 -1
- package/dist/__tests__/omc-cli-rendering.test.d.ts +2 -0
- package/dist/__tests__/omc-cli-rendering.test.d.ts.map +1 -0
- package/dist/__tests__/omc-cli-rendering.test.js +33 -0
- package/dist/__tests__/omc-cli-rendering.test.js.map +1 -0
- package/dist/__tests__/omc-tools-server.test.js +5 -5
- package/dist/__tests__/outbox-reader-partial-lines.test.d.ts +2 -0
- package/dist/__tests__/outbox-reader-partial-lines.test.d.ts.map +1 -0
- package/dist/__tests__/outbox-reader-partial-lines.test.js +49 -0
- package/dist/__tests__/outbox-reader-partial-lines.test.js.map +1 -0
- package/dist/__tests__/package-dir-resolution-regression.test.js +30 -0
- package/dist/__tests__/package-dir-resolution-regression.test.js.map +1 -1
- package/dist/__tests__/pipeline-signal-regex-escape.test.d.ts +2 -0
- package/dist/__tests__/pipeline-signal-regex-escape.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline-signal-regex-escape.test.js +32 -0
- package/dist/__tests__/pipeline-signal-regex-escape.test.js.map +1 -0
- package/dist/__tests__/plugin-setup-devpaths.test.d.ts +2 -0
- package/dist/__tests__/plugin-setup-devpaths.test.d.ts.map +1 -0
- package/dist/__tests__/plugin-setup-devpaths.test.js +47 -0
- package/dist/__tests__/plugin-setup-devpaths.test.js.map +1 -0
- package/dist/__tests__/pre-compact-cwd.test.js +1 -1
- package/dist/__tests__/pre-tool-enforcer.test.js +101 -2
- package/dist/__tests__/pre-tool-enforcer.test.js.map +1 -1
- package/dist/__tests__/project-memory-merge.test.js +17 -0
- package/dist/__tests__/project-memory-merge.test.js.map +1 -1
- package/dist/__tests__/providers/bitbucket.test.js +70 -56
- package/dist/__tests__/providers/bitbucket.test.js.map +1 -1
- package/dist/__tests__/providers/gitea.test.js +36 -0
- package/dist/__tests__/providers/gitea.test.js.map +1 -1
- package/dist/__tests__/purge-stale-cache.test.js +17 -2
- package/dist/__tests__/purge-stale-cache.test.js.map +1 -1
- package/dist/__tests__/rate-limit-wait/daemon-bootstrap.test.js +7 -3
- package/dist/__tests__/rate-limit-wait/daemon-bootstrap.test.js.map +1 -1
- package/dist/__tests__/rate-limit-wait/integration.test.js +9 -5
- package/dist/__tests__/rate-limit-wait/integration.test.js.map +1 -1
- package/dist/__tests__/rate-limit-wait/tmux-detector.test.js +11 -11
- package/dist/__tests__/rate-limit-wait/tmux-detector.test.js.map +1 -1
- package/dist/__tests__/repo-slug-dots.test.d.ts +2 -0
- package/dist/__tests__/repo-slug-dots.test.d.ts.map +1 -0
- package/dist/__tests__/repo-slug-dots.test.js +24 -0
- package/dist/__tests__/repo-slug-dots.test.js.map +1 -0
- package/dist/__tests__/routing-force-inherit.test.js +31 -0
- package/dist/__tests__/routing-force-inherit.test.js.map +1 -1
- package/dist/__tests__/runtime-task-orphan.test.d.ts +2 -0
- package/dist/__tests__/runtime-task-orphan.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-task-orphan.test.js +103 -0
- package/dist/__tests__/runtime-task-orphan.test.js.map +1 -0
- package/dist/__tests__/session-start-script-context.test.js +85 -0
- package/dist/__tests__/session-start-script-context.test.js.map +1 -1
- package/dist/__tests__/session-start-timeout-cleanup.test.d.ts +2 -0
- package/dist/__tests__/session-start-timeout-cleanup.test.d.ts.map +1 -0
- package/dist/__tests__/session-start-timeout-cleanup.test.js +26 -0
- package/dist/__tests__/session-start-timeout-cleanup.test.js.map +1 -0
- package/dist/__tests__/session-summary-pid-tracking.test.d.ts +2 -0
- package/dist/__tests__/session-summary-pid-tracking.test.d.ts.map +1 -0
- package/dist/__tests__/session-summary-pid-tracking.test.js +107 -0
- package/dist/__tests__/session-summary-pid-tracking.test.js.map +1 -0
- package/dist/__tests__/setup-claude-md-script.test.d.ts +2 -0
- package/dist/__tests__/setup-claude-md-script.test.d.ts.map +1 -0
- package/dist/__tests__/setup-claude-md-script.test.js +292 -0
- package/dist/__tests__/setup-claude-md-script.test.js.map +1 -0
- package/dist/__tests__/shared-state-locking.test.d.ts +10 -0
- package/dist/__tests__/shared-state-locking.test.d.ts.map +1 -0
- package/dist/__tests__/shared-state-locking.test.js +61 -0
- package/dist/__tests__/shared-state-locking.test.js.map +1 -0
- package/dist/__tests__/skills.test.js +135 -17
- package/dist/__tests__/skills.test.js.map +1 -1
- package/dist/__tests__/slack-fallback-removal.test.d.ts +2 -0
- package/dist/__tests__/slack-fallback-removal.test.d.ts.map +1 -0
- package/dist/__tests__/slack-fallback-removal.test.js +16 -0
- package/dist/__tests__/slack-fallback-removal.test.js.map +1 -0
- package/dist/__tests__/ssrf-guard.test.js +12 -0
- package/dist/__tests__/ssrf-guard.test.js.map +1 -1
- package/dist/__tests__/team-ops-task-locking.test.d.ts +2 -0
- package/dist/__tests__/team-ops-task-locking.test.d.ts.map +1 -0
- package/dist/__tests__/team-ops-task-locking.test.js +66 -0
- package/dist/__tests__/team-ops-task-locking.test.js.map +1 -0
- package/dist/__tests__/team-server-validation.test.js +6 -5
- package/dist/__tests__/team-server-validation.test.js.map +1 -1
- package/dist/__tests__/team-status-failed-count.test.d.ts +2 -0
- package/dist/__tests__/team-status-failed-count.test.d.ts.map +1 -0
- package/dist/__tests__/team-status-failed-count.test.js +91 -0
- package/dist/__tests__/team-status-failed-count.test.js.map +1 -0
- package/dist/__tests__/team-status-tmux-provider.test.d.ts +2 -0
- package/dist/__tests__/team-status-tmux-provider.test.d.ts.map +1 -0
- package/dist/__tests__/team-status-tmux-provider.test.js +39 -0
- package/dist/__tests__/team-status-tmux-provider.test.js.map +1 -0
- package/dist/__tests__/tier0-docs-consistency.test.js +42 -0
- package/dist/__tests__/tier0-docs-consistency.test.js.map +1 -1
- package/dist/__tests__/tools/ast-tools.test.d.ts +2 -0
- package/dist/__tests__/tools/ast-tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools/ast-tools.test.js +74 -0
- package/dist/__tests__/tools/ast-tools.test.js.map +1 -0
- package/dist/__tests__/visual-verdict-skill.test.d.ts +2 -0
- package/dist/__tests__/visual-verdict-skill.test.d.ts.map +1 -0
- package/dist/__tests__/visual-verdict-skill.test.js +26 -0
- package/dist/__tests__/visual-verdict-skill.test.js.map +1 -0
- package/dist/__tests__/webhook-timeout-cleanup.test.d.ts +2 -0
- package/dist/__tests__/webhook-timeout-cleanup.test.d.ts.map +1 -0
- package/dist/__tests__/webhook-timeout-cleanup.test.js +18 -0
- package/dist/__tests__/webhook-timeout-cleanup.test.js.map +1 -0
- package/dist/__tests__/worktree-metadata-locking.test.d.ts +2 -0
- package/dist/__tests__/worktree-metadata-locking.test.d.ts.map +1 -0
- package/dist/__tests__/worktree-metadata-locking.test.js +51 -0
- package/dist/__tests__/worktree-metadata-locking.test.js.map +1 -0
- package/dist/agents/definitions.d.ts +2 -1
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +6 -1
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +1 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/tracer.d.ts +11 -0
- package/dist/agents/tracer.d.ts.map +1 -0
- package/dist/agents/tracer.js +40 -0
- package/dist/agents/tracer.js.map +1 -0
- package/dist/agents/utils.d.ts.map +1 -1
- package/dist/agents/utils.js +2 -0
- package/dist/agents/utils.js.map +1 -1
- package/dist/autoresearch/__tests__/contracts.test.d.ts +2 -0
- package/dist/autoresearch/__tests__/contracts.test.d.ts.map +1 -0
- package/dist/autoresearch/__tests__/contracts.test.js +90 -0
- package/dist/autoresearch/__tests__/contracts.test.js.map +1 -0
- package/dist/autoresearch/__tests__/runtime-parity-extra.test.d.ts +2 -0
- package/dist/autoresearch/__tests__/runtime-parity-extra.test.d.ts.map +1 -0
- package/dist/autoresearch/__tests__/runtime-parity-extra.test.js +352 -0
- package/dist/autoresearch/__tests__/runtime-parity-extra.test.js.map +1 -0
- package/dist/autoresearch/__tests__/runtime.test.d.ts +2 -0
- package/dist/autoresearch/__tests__/runtime.test.d.ts.map +1 -0
- package/dist/autoresearch/__tests__/runtime.test.js +210 -0
- package/dist/autoresearch/__tests__/runtime.test.js.map +1 -0
- package/dist/autoresearch/__tests__/setup-contract.test.d.ts +2 -0
- package/dist/autoresearch/__tests__/setup-contract.test.d.ts.map +1 -0
- package/dist/autoresearch/__tests__/setup-contract.test.js +57 -0
- package/dist/autoresearch/__tests__/setup-contract.test.js.map +1 -0
- package/dist/autoresearch/contracts.d.ts +31 -0
- package/dist/autoresearch/contracts.d.ts.map +1 -0
- package/dist/autoresearch/contracts.js +189 -0
- package/dist/autoresearch/contracts.js.map +1 -0
- package/dist/autoresearch/runtime.d.ts +137 -0
- package/dist/autoresearch/runtime.d.ts.map +1 -0
- package/dist/autoresearch/runtime.js +1103 -0
- package/dist/autoresearch/runtime.js.map +1 -0
- package/dist/autoresearch/setup-contract.d.ts +18 -0
- package/dist/autoresearch/setup-contract.d.ts.map +1 -0
- package/dist/autoresearch/setup-contract.js +96 -0
- package/dist/autoresearch/setup-contract.js.map +1 -0
- package/dist/cli/__tests__/ask.test.js +32 -130
- package/dist/cli/__tests__/ask.test.js.map +1 -1
- package/dist/cli/__tests__/autoresearch-guided.test.d.ts +2 -0
- package/dist/cli/__tests__/autoresearch-guided.test.d.ts.map +1 -0
- package/dist/cli/__tests__/autoresearch-guided.test.js +389 -0
- package/dist/cli/__tests__/autoresearch-guided.test.js.map +1 -0
- package/dist/cli/__tests__/autoresearch-intake.test.d.ts +2 -0
- package/dist/cli/__tests__/autoresearch-intake.test.d.ts.map +1 -0
- package/dist/cli/__tests__/autoresearch-intake.test.js +131 -0
- package/dist/cli/__tests__/autoresearch-intake.test.js.map +1 -0
- package/dist/cli/__tests__/autoresearch-setup-session.test.d.ts +2 -0
- package/dist/cli/__tests__/autoresearch-setup-session.test.d.ts.map +1 -0
- package/dist/cli/__tests__/autoresearch-setup-session.test.js +73 -0
- package/dist/cli/__tests__/autoresearch-setup-session.test.js.map +1 -0
- package/dist/cli/__tests__/autoresearch.test.d.ts +2 -0
- package/dist/cli/__tests__/autoresearch.test.d.ts.map +1 -0
- package/dist/cli/__tests__/autoresearch.test.js +148 -0
- package/dist/cli/__tests__/autoresearch.test.js.map +1 -0
- package/dist/cli/__tests__/hud-watch.test.d.ts +2 -0
- package/dist/cli/__tests__/hud-watch.test.d.ts.map +1 -0
- package/dist/cli/__tests__/hud-watch.test.js +56 -0
- package/dist/cli/__tests__/hud-watch.test.js.map +1 -0
- package/dist/cli/__tests__/launch.test.js +82 -5
- package/dist/cli/__tests__/launch.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +44 -2
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/tmux-utils.test.js +41 -1
- package/dist/cli/__tests__/tmux-utils.test.js.map +1 -1
- package/dist/cli/autoresearch-guided.d.ts +37 -0
- package/dist/cli/autoresearch-guided.d.ts.map +1 -0
- package/dist/cli/autoresearch-guided.js +312 -0
- package/dist/cli/autoresearch-guided.js.map +1 -0
- package/dist/cli/autoresearch-intake.d.ts +60 -0
- package/dist/cli/autoresearch-intake.d.ts.map +1 -0
- package/dist/cli/autoresearch-intake.js +325 -0
- package/dist/cli/autoresearch-intake.js.map +1 -0
- package/dist/cli/autoresearch-setup-session.d.ts +15 -0
- package/dist/cli/autoresearch-setup-session.d.ts.map +1 -0
- package/dist/cli/autoresearch-setup-session.js +133 -0
- package/dist/cli/autoresearch-setup-session.js.map +1 -0
- package/dist/cli/autoresearch.d.ts +19 -0
- package/dist/cli/autoresearch.d.ts.map +1 -0
- package/dist/cli/autoresearch.js +330 -0
- package/dist/cli/autoresearch.js.map +1 -0
- package/dist/cli/commands/__tests__/team.test.js +88 -1
- package/dist/cli/commands/__tests__/team.test.js.map +1 -1
- package/dist/cli/commands/doctor-conflicts.d.ts +2 -0
- package/dist/cli/commands/doctor-conflicts.d.ts.map +1 -1
- package/dist/cli/commands/doctor-conflicts.js +44 -1
- package/dist/cli/commands/doctor-conflicts.js.map +1 -1
- package/dist/cli/commands/ralphthon.d.ts +30 -0
- package/dist/cli/commands/ralphthon.d.ts.map +1 -0
- package/dist/cli/commands/ralphthon.js +361 -0
- package/dist/cli/commands/ralphthon.js.map +1 -0
- package/dist/cli/commands/team.d.ts +39 -0
- package/dist/cli/commands/team.d.ts.map +1 -1
- package/dist/cli/commands/team.js +178 -19
- package/dist/cli/commands/team.js.map +1 -1
- package/dist/cli/commands/teleport.js +5 -5
- package/dist/cli/commands/teleport.js.map +1 -1
- package/dist/cli/hud-watch.d.ts +15 -0
- package/dist/cli/hud-watch.d.ts.map +1 -0
- package/dist/cli/hud-watch.js +37 -0
- package/dist/cli/hud-watch.js.map +1 -0
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +39 -180
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/launch.d.ts +9 -1
- package/dist/cli/launch.d.ts.map +1 -1
- package/dist/cli/launch.js +25 -4
- package/dist/cli/launch.js.map +1 -1
- package/dist/cli/team.d.ts +1 -0
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +42 -54
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/tmux-utils.d.ts +3 -2
- package/dist/cli/tmux-utils.d.ts.map +1 -1
- package/dist/cli/tmux-utils.js +16 -3
- package/dist/cli/tmux-utils.js.map +1 -1
- package/dist/config/__tests__/loader.test.js +121 -67
- package/dist/config/__tests__/loader.test.js.map +1 -1
- package/dist/config/__tests__/models.test.js +114 -1
- package/dist/config/__tests__/models.test.js.map +1 -1
- package/dist/config/__tests__/plan-output.test.d.ts +2 -0
- package/dist/config/__tests__/plan-output.test.d.ts.map +1 -0
- package/dist/config/__tests__/plan-output.test.js +41 -0
- package/dist/config/__tests__/plan-output.test.js.map +1 -0
- package/dist/config/index.d.ts +2 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +280 -215
- package/dist/config/loader.js.map +1 -1
- package/dist/config/models.d.ts +33 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +57 -0
- package/dist/config/models.js.map +1 -1
- package/dist/config/plan-output.d.ts +12 -0
- package/dist/config/plan-output.d.ts.map +1 -0
- package/dist/config/plan-output.js +67 -0
- package/dist/config/plan-output.js.map +1 -0
- package/dist/constants/names.d.ts +1 -5
- package/dist/constants/names.d.ts.map +1 -1
- package/dist/constants/names.js +1 -6
- package/dist/constants/names.js.map +1 -1
- package/dist/features/auto-update.d.ts +8 -0
- package/dist/features/auto-update.d.ts.map +1 -1
- package/dist/features/auto-update.js +218 -24
- package/dist/features/auto-update.js.map +1 -1
- package/dist/features/boulder-state/storage.d.ts.map +1 -1
- package/dist/features/boulder-state/storage.js +15 -10
- package/dist/features/boulder-state/storage.js.map +1 -1
- package/dist/features/builtin-skills/runtime-guidance.d.ts +9 -0
- package/dist/features/builtin-skills/runtime-guidance.d.ts.map +1 -0
- package/dist/features/builtin-skills/runtime-guidance.js +35 -0
- package/dist/features/builtin-skills/runtime-guidance.js.map +1 -0
- package/dist/features/builtin-skills/skills.d.ts.map +1 -1
- package/dist/features/builtin-skills/skills.js +32 -7
- package/dist/features/builtin-skills/skills.js.map +1 -1
- package/dist/features/continuation-enforcement.d.ts.map +1 -1
- package/dist/features/continuation-enforcement.js +3 -2
- package/dist/features/continuation-enforcement.js.map +1 -1
- package/dist/features/delegation-categories/__tests__/index.test.d.ts.map +1 -0
- package/dist/features/delegation-categories/__tests__/index.test.js +19 -0
- package/dist/features/delegation-categories/__tests__/index.test.js.map +1 -0
- package/dist/features/delegation-enforcer.d.ts.map +1 -1
- package/dist/features/delegation-enforcer.js +62 -3
- package/dist/features/delegation-enforcer.js.map +1 -1
- package/dist/features/magic-keywords.d.ts +1 -1
- package/dist/features/magic-keywords.d.ts.map +1 -1
- package/dist/features/magic-keywords.js +42 -12
- package/dist/features/magic-keywords.js.map +1 -1
- package/dist/features/model-routing/__tests__/index.test.d.ts +2 -0
- package/dist/features/model-routing/__tests__/index.test.d.ts.map +1 -0
- package/dist/features/model-routing/__tests__/index.test.js +21 -0
- package/dist/features/model-routing/__tests__/index.test.js.map +1 -0
- package/dist/features/model-routing/index.d.ts.map +1 -1
- package/dist/features/model-routing/index.js +3 -2
- package/dist/features/model-routing/index.js.map +1 -1
- package/dist/features/model-routing/signals.js +1 -1
- package/dist/features/model-routing/signals.js.map +1 -1
- package/dist/features/model-routing/types.d.ts +1 -1
- package/dist/features/rate-limit-wait/daemon.d.ts.map +1 -1
- package/dist/features/rate-limit-wait/daemon.js +11 -22
- package/dist/features/rate-limit-wait/daemon.js.map +1 -1
- package/dist/features/rate-limit-wait/tmux-detector.js +6 -6
- package/dist/features/rate-limit-wait/tmux-detector.js.map +1 -1
- package/dist/features/rate-limit-wait/types.d.ts +3 -3
- package/dist/features/rate-limit-wait/types.d.ts.map +1 -1
- package/dist/features/state-manager/index.d.ts +2 -2
- package/dist/features/state-manager/index.d.ts.map +1 -1
- package/dist/features/state-manager/index.js +12 -8
- package/dist/features/state-manager/index.js.map +1 -1
- package/dist/features/state-manager/types.d.ts +2 -2
- package/dist/features/state-manager/types.d.ts.map +1 -1
- package/dist/features/state-manager/types.js +2 -2
- package/dist/features/state-manager/types.js.map +1 -1
- package/dist/features/task-decomposer/index.js +3 -1
- package/dist/features/task-decomposer/index.js.map +1 -1
- package/dist/features/verification/index.d.ts.map +1 -1
- package/dist/features/verification/index.js +4 -2
- package/dist/features/verification/index.js.map +1 -1
- package/dist/hooks/__tests__/background-process-guard.test.js +151 -3
- package/dist/hooks/__tests__/background-process-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/bridge-openclaw.test.js +15 -0
- package/dist/hooks/__tests__/bridge-openclaw.test.js.map +1 -1
- package/dist/hooks/__tests__/bridge-routing.test.js +130 -0
- package/dist/hooks/__tests__/bridge-routing.test.js.map +1 -1
- package/dist/hooks/__tests__/bridge-team-worker-guard.test.js +1 -1
- package/dist/hooks/__tests__/bridge-team-worker-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/bridge.test.js +101 -0
- package/dist/hooks/__tests__/bridge.test.js.map +1 -1
- package/dist/hooks/__tests__/team-worker-heartbeat.test.d.ts +10 -0
- package/dist/hooks/__tests__/team-worker-heartbeat.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/team-worker-heartbeat.test.js +87 -0
- package/dist/hooks/__tests__/team-worker-heartbeat.test.js.map +1 -0
- package/dist/hooks/auto-slash-command/executor.d.ts.map +1 -1
- package/dist/hooks/auto-slash-command/executor.js +134 -70
- package/dist/hooks/auto-slash-command/executor.js.map +1 -1
- package/dist/hooks/auto-slash-command/live-data.d.ts.map +1 -1
- package/dist/hooks/auto-slash-command/live-data.js +12 -0
- package/dist/hooks/auto-slash-command/live-data.js.map +1 -1
- package/dist/hooks/autopilot/__tests__/prompts.test.js +61 -52
- package/dist/hooks/autopilot/__tests__/prompts.test.js.map +1 -1
- package/dist/hooks/autopilot/__tests__/state.test.js +34 -34
- package/dist/hooks/autopilot/adapters/execution-adapter.d.ts +1 -1
- package/dist/hooks/autopilot/adapters/execution-adapter.d.ts.map +1 -1
- package/dist/hooks/autopilot/adapters/execution-adapter.js +6 -5
- package/dist/hooks/autopilot/adapters/execution-adapter.js.map +1 -1
- package/dist/hooks/autopilot/adapters/ralplan-adapter.d.ts +1 -1
- package/dist/hooks/autopilot/adapters/ralplan-adapter.d.ts.map +1 -1
- package/dist/hooks/autopilot/adapters/ralplan-adapter.js +8 -7
- package/dist/hooks/autopilot/adapters/ralplan-adapter.js.map +1 -1
- package/dist/hooks/autopilot/enforcement.d.ts +2 -2
- package/dist/hooks/autopilot/enforcement.d.ts.map +1 -1
- package/dist/hooks/autopilot/enforcement.js +98 -70
- package/dist/hooks/autopilot/enforcement.js.map +1 -1
- package/dist/hooks/autopilot/pipeline-types.d.ts +8 -6
- package/dist/hooks/autopilot/pipeline-types.d.ts.map +1 -1
- package/dist/hooks/autopilot/pipeline-types.js +9 -9
- package/dist/hooks/autopilot/pipeline-types.js.map +1 -1
- package/dist/hooks/autopilot/pipeline.d.ts +3 -3
- package/dist/hooks/autopilot/pipeline.d.ts.map +1 -1
- package/dist/hooks/autopilot/pipeline.js +51 -36
- package/dist/hooks/autopilot/pipeline.js.map +1 -1
- package/dist/hooks/autopilot/prompts.d.ts +4 -2
- package/dist/hooks/autopilot/prompts.d.ts.map +1 -1
- package/dist/hooks/autopilot/prompts.js +31 -24
- package/dist/hooks/autopilot/prompts.js.map +1 -1
- package/dist/hooks/autopilot/state.d.ts.map +1 -1
- package/dist/hooks/autopilot/state.js +21 -14
- package/dist/hooks/autopilot/state.js.map +1 -1
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +329 -71
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/code-simplifier/index.d.ts +3 -2
- package/dist/hooks/code-simplifier/index.d.ts.map +1 -1
- package/dist/hooks/code-simplifier/index.js +15 -12
- package/dist/hooks/code-simplifier/index.js.map +1 -1
- package/dist/hooks/comment-checker/index.d.ts.map +1 -1
- package/dist/hooks/comment-checker/index.js +0 -17
- package/dist/hooks/comment-checker/index.js.map +1 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +0 -8
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/keyword-detector/__tests__/index.test.js +304 -0
- package/dist/hooks/keyword-detector/__tests__/index.test.js.map +1 -1
- package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
- package/dist/hooks/keyword-detector/index.js +46 -16
- package/dist/hooks/keyword-detector/index.js.map +1 -1
- package/dist/hooks/learner/bridge.d.ts +1 -0
- package/dist/hooks/learner/bridge.d.ts.map +1 -1
- package/dist/hooks/learner/bridge.js +30 -19
- package/dist/hooks/learner/bridge.js.map +1 -1
- package/dist/hooks/learner/constants.d.ts +2 -0
- package/dist/hooks/learner/constants.d.ts.map +1 -1
- package/dist/hooks/learner/constants.js +2 -0
- package/dist/hooks/learner/constants.js.map +1 -1
- package/dist/hooks/learner/finder.d.ts.map +1 -1
- package/dist/hooks/learner/finder.js +25 -20
- package/dist/hooks/learner/finder.js.map +1 -1
- package/dist/hooks/learner/transliteration-map.d.ts +30 -0
- package/dist/hooks/learner/transliteration-map.d.ts.map +1 -0
- package/dist/hooks/learner/transliteration-map.js +51 -0
- package/dist/hooks/learner/transliteration-map.js.map +1 -0
- package/dist/hooks/non-interactive-env/index.d.ts.map +1 -1
- package/dist/hooks/non-interactive-env/index.js +5 -5
- package/dist/hooks/non-interactive-env/index.js.map +1 -1
- package/dist/hooks/non-interactive-env/index.test.d.ts +2 -0
- package/dist/hooks/non-interactive-env/index.test.d.ts.map +1 -0
- package/dist/hooks/non-interactive-env/index.test.js +30 -0
- package/dist/hooks/non-interactive-env/index.test.js.map +1 -0
- package/dist/hooks/notepad/index.d.ts.map +1 -1
- package/dist/hooks/notepad/index.js +20 -6
- package/dist/hooks/notepad/index.js.map +1 -1
- package/dist/hooks/omc-orchestrator/index.d.ts.map +1 -1
- package/dist/hooks/omc-orchestrator/index.js +6 -2
- package/dist/hooks/omc-orchestrator/index.js.map +1 -1
- package/dist/hooks/permission-handler/__tests__/index.test.js +9 -1
- package/dist/hooks/permission-handler/__tests__/index.test.js.map +1 -1
- package/dist/hooks/permission-handler/index.d.ts +2 -0
- package/dist/hooks/permission-handler/index.d.ts.map +1 -1
- package/dist/hooks/permission-handler/index.js +67 -7
- package/dist/hooks/permission-handler/index.js.map +1 -1
- package/dist/hooks/persistent-mode/__tests__/idle-cooldown.test.js +79 -15
- package/dist/hooks/persistent-mode/__tests__/idle-cooldown.test.js.map +1 -1
- package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.js +1 -1
- package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.js.map +1 -1
- package/dist/hooks/persistent-mode/__tests__/skill-state-stop.test.js +36 -1
- package/dist/hooks/persistent-mode/__tests__/skill-state-stop.test.js.map +1 -1
- package/dist/hooks/persistent-mode/__tests__/team-ralplan-stop.test.js +113 -2
- package/dist/hooks/persistent-mode/__tests__/team-ralplan-stop.test.js.map +1 -1
- package/dist/hooks/persistent-mode/index.d.ts +1 -1
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +50 -14
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/persistent-mode/session-isolation.test.js +20 -14
- package/dist/hooks/persistent-mode/session-isolation.test.js.map +1 -1
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js +173 -5
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js.map +1 -1
- package/dist/hooks/project-memory/__tests__/formatter.test.js +244 -191
- package/dist/hooks/project-memory/__tests__/formatter.test.js.map +1 -1
- package/dist/hooks/project-memory/__tests__/integration.test.js +185 -101
- package/dist/hooks/project-memory/__tests__/integration.test.js.map +1 -1
- package/dist/hooks/project-memory/__tests__/pre-compact.test.d.ts +5 -0
- package/dist/hooks/project-memory/__tests__/pre-compact.test.d.ts.map +1 -0
- package/dist/hooks/project-memory/__tests__/pre-compact.test.js +121 -0
- package/dist/hooks/project-memory/__tests__/pre-compact.test.js.map +1 -0
- package/dist/hooks/project-memory/formatter.d.ts +2 -2
- package/dist/hooks/project-memory/formatter.d.ts.map +1 -1
- package/dist/hooks/project-memory/formatter.js +167 -92
- package/dist/hooks/project-memory/formatter.js.map +1 -1
- package/dist/hooks/project-memory/hot-path-tracker.d.ts +3 -3
- package/dist/hooks/project-memory/hot-path-tracker.d.ts.map +1 -1
- package/dist/hooks/project-memory/hot-path-tracker.js +71 -27
- package/dist/hooks/project-memory/hot-path-tracker.js.map +1 -1
- package/dist/hooks/project-memory/index.d.ts +0 -20
- package/dist/hooks/project-memory/index.d.ts.map +1 -1
- package/dist/hooks/project-memory/index.js +37 -39
- package/dist/hooks/project-memory/index.js.map +1 -1
- package/dist/hooks/project-memory/pre-compact.d.ts.map +1 -1
- package/dist/hooks/project-memory/pre-compact.js +2 -1
- package/dist/hooks/project-memory/pre-compact.js.map +1 -1
- package/dist/hooks/project-memory/types.d.ts +11 -6
- package/dist/hooks/project-memory/types.d.ts.map +1 -1
- package/dist/hooks/ralph/verifier.d.ts.map +1 -1
- package/dist/hooks/ralph/verifier.js +2 -1
- package/dist/hooks/ralph/verifier.js.map +1 -1
- package/dist/hooks/recovery/session-recovery.d.ts.map +1 -1
- package/dist/hooks/recovery/session-recovery.js +7 -4
- package/dist/hooks/recovery/session-recovery.js.map +1 -1
- package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.js +28 -0
- package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.js.map +1 -1
- package/dist/hooks/session-end/__tests__/session-end-timeout.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/session-end-timeout.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/session-end-timeout.test.js +91 -0
- package/dist/hooks/session-end/__tests__/session-end-timeout.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/team-cleanup.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/team-cleanup.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/team-cleanup.test.js +150 -0
- package/dist/hooks/session-end/__tests__/team-cleanup.test.js.map +1 -0
- package/dist/hooks/session-end/index.d.ts +9 -0
- package/dist/hooks/session-end/index.d.ts.map +1 -1
- package/dist/hooks/session-end/index.js +178 -30
- package/dist/hooks/session-end/index.js.map +1 -1
- package/dist/hooks/setup/__tests__/windows-patch.test.js +8 -7
- package/dist/hooks/setup/__tests__/windows-patch.test.js.map +1 -1
- package/dist/hooks/setup/index.d.ts +1 -1
- package/dist/hooks/setup/index.js +3 -3
- package/dist/hooks/setup/index.js.map +1 -1
- package/dist/hooks/skill-bridge.cjs +48 -16
- package/dist/hooks/skill-state/__tests__/skill-state.test.js +74 -8
- package/dist/hooks/skill-state/__tests__/skill-state.test.js.map +1 -1
- package/dist/hooks/skill-state/index.d.ts +18 -4
- package/dist/hooks/skill-state/index.d.ts.map +1 -1
- package/dist/hooks/skill-state/index.js +43 -7
- package/dist/hooks/skill-state/index.js.map +1 -1
- package/dist/hooks/subagent-tracker/__tests__/index.test.js +42 -1
- package/dist/hooks/subagent-tracker/__tests__/index.test.js.map +1 -1
- package/dist/hooks/subagent-tracker/index.d.ts +5 -0
- package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
- package/dist/hooks/subagent-tracker/index.js +62 -49
- package/dist/hooks/subagent-tracker/index.js.map +1 -1
- package/dist/hooks/team-dispatch-hook.d.ts.map +1 -1
- package/dist/hooks/team-dispatch-hook.js +4 -2
- package/dist/hooks/team-dispatch-hook.js.map +1 -1
- package/dist/hooks/team-leader-nudge-hook.d.ts +6 -0
- package/dist/hooks/team-leader-nudge-hook.d.ts.map +1 -1
- package/dist/hooks/team-leader-nudge-hook.js +113 -15
- package/dist/hooks/team-leader-nudge-hook.js.map +1 -1
- package/dist/hooks/team-worker-hook.d.ts.map +1 -1
- package/dist/hooks/team-worker-hook.js +6 -3
- package/dist/hooks/team-worker-hook.js.map +1 -1
- package/dist/hud/background-cleanup.d.ts +3 -3
- package/dist/hud/background-cleanup.d.ts.map +1 -1
- package/dist/hud/background-cleanup.js +9 -9
- package/dist/hud/background-cleanup.js.map +1 -1
- package/dist/hud/background-tasks.d.ts +7 -0
- package/dist/hud/background-tasks.d.ts.map +1 -1
- package/dist/hud/background-tasks.js +83 -0
- package/dist/hud/background-tasks.js.map +1 -1
- package/dist/hud/elements/context.d.ts +12 -2
- package/dist/hud/elements/context.d.ts.map +1 -1
- package/dist/hud/elements/context.js +86 -35
- package/dist/hud/elements/context.js.map +1 -1
- package/dist/hud/elements/git.d.ts +4 -0
- package/dist/hud/elements/git.d.ts.map +1 -1
- package/dist/hud/elements/git.js +39 -9
- package/dist/hud/elements/git.js.map +1 -1
- package/dist/hud/elements/index.d.ts +1 -0
- package/dist/hud/elements/index.d.ts.map +1 -1
- package/dist/hud/elements/index.js +1 -0
- package/dist/hud/elements/index.js.map +1 -1
- package/dist/hud/elements/session-summary.d.ts +23 -0
- package/dist/hud/elements/session-summary.d.ts.map +1 -0
- package/dist/hud/elements/session-summary.js +23 -0
- package/dist/hud/elements/session-summary.js.map +1 -0
- package/dist/hud/elements/token-usage.d.ts +8 -0
- package/dist/hud/elements/token-usage.d.ts.map +1 -0
- package/dist/hud/elements/token-usage.js +24 -0
- package/dist/hud/elements/token-usage.js.map +1 -0
- package/dist/hud/index.d.ts +4 -0
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +165 -32
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/mission-board.d.ts.map +1 -1
- package/dist/hud/mission-board.js +8 -2
- package/dist/hud/mission-board.js.map +1 -1
- package/dist/hud/omc-state.d.ts +5 -5
- package/dist/hud/omc-state.d.ts.map +1 -1
- package/dist/hud/omc-state.js +20 -16
- package/dist/hud/omc-state.js.map +1 -1
- package/dist/hud/render.d.ts +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +69 -54
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts +3 -3
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +110 -57
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/stdin.d.ts +8 -1
- package/dist/hud/stdin.d.ts.map +1 -1
- package/dist/hud/stdin.js +60 -13
- package/dist/hud/stdin.js.map +1 -1
- package/dist/hud/transcript.d.ts.map +1 -1
- package/dist/hud/transcript.js +148 -35
- package/dist/hud/transcript.js.map +1 -1
- package/dist/hud/types.d.ts +30 -13
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js +24 -0
- package/dist/hud/types.js.map +1 -1
- package/dist/hud/usage-api.d.ts.map +1 -1
- package/dist/hud/usage-api.js +57 -24
- package/dist/hud/usage-api.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installer/__tests__/claude-md-merge.test.js +23 -0
- package/dist/installer/__tests__/claude-md-merge.test.js.map +1 -1
- package/dist/installer/__tests__/hook-templates.test.js +50 -5
- package/dist/installer/__tests__/hook-templates.test.js.map +1 -1
- package/dist/installer/__tests__/mcp-registry.test.d.ts +2 -0
- package/dist/installer/__tests__/mcp-registry.test.d.ts.map +1 -0
- package/dist/installer/__tests__/mcp-registry.test.js +316 -0
- package/dist/installer/__tests__/mcp-registry.test.js.map +1 -0
- package/dist/installer/__tests__/session-start-template.test.d.ts +2 -0
- package/dist/installer/__tests__/session-start-template.test.d.ts.map +1 -0
- package/dist/installer/__tests__/session-start-template.test.js +95 -0
- package/dist/installer/__tests__/session-start-template.test.js.map +1 -0
- package/dist/installer/hooks.d.ts +0 -14
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +0 -33
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +2 -0
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +71 -7
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/mcp-registry.d.ts +48 -0
- package/dist/installer/mcp-registry.d.ts.map +1 -0
- package/dist/installer/mcp-registry.js +453 -0
- package/dist/installer/mcp-registry.js.map +1 -0
- package/dist/interop/omx-team-state.d.ts +2 -0
- package/dist/interop/omx-team-state.d.ts.map +1 -1
- package/dist/interop/omx-team-state.js.map +1 -1
- package/dist/interop/shared-state.d.ts.map +1 -1
- package/dist/interop/shared-state.js +21 -18
- package/dist/interop/shared-state.js.map +1 -1
- package/dist/lib/__tests__/mode-state-io.test.js +58 -8
- package/dist/lib/__tests__/mode-state-io.test.js.map +1 -1
- package/dist/lib/__tests__/swallowed-error.test.d.ts +2 -0
- package/dist/lib/__tests__/swallowed-error.test.d.ts.map +1 -0
- package/dist/lib/__tests__/swallowed-error.test.js +19 -0
- package/dist/lib/__tests__/swallowed-error.test.js.map +1 -0
- package/dist/lib/featured-contributors.d.ts +54 -0
- package/dist/lib/featured-contributors.d.ts.map +1 -0
- package/dist/lib/featured-contributors.js +290 -0
- package/dist/lib/featured-contributors.js.map +1 -0
- package/dist/lib/file-lock.d.ts.map +1 -1
- package/dist/lib/file-lock.js +49 -51
- package/dist/lib/file-lock.js.map +1 -1
- package/dist/lib/mode-names.d.ts +1 -0
- package/dist/lib/mode-names.d.ts.map +1 -1
- package/dist/lib/mode-names.js +5 -0
- package/dist/lib/mode-names.js.map +1 -1
- package/dist/lib/mode-state-io.d.ts +2 -0
- package/dist/lib/mode-state-io.d.ts.map +1 -1
- package/dist/lib/mode-state-io.js +57 -11
- package/dist/lib/mode-state-io.js.map +1 -1
- package/dist/lib/project-memory-merge.d.ts.map +1 -1
- package/dist/lib/project-memory-merge.js +2 -0
- package/dist/lib/project-memory-merge.js.map +1 -1
- package/dist/lib/shared-memory.d.ts.map +1 -1
- package/dist/lib/shared-memory.js +40 -21
- package/dist/lib/shared-memory.js.map +1 -1
- package/dist/lib/swallowed-error.d.ts +4 -0
- package/dist/lib/swallowed-error.d.ts.map +1 -0
- package/dist/lib/swallowed-error.js +26 -0
- package/dist/lib/swallowed-error.js.map +1 -0
- package/dist/lib/worktree-paths.d.ts +1 -0
- package/dist/lib/worktree-paths.d.ts.map +1 -1
- package/dist/lib/worktree-paths.js +1 -0
- package/dist/lib/worktree-paths.js.map +1 -1
- package/dist/mcp/__tests__/prompt-injection.test.js +15 -0
- package/dist/mcp/__tests__/prompt-injection.test.js.map +1 -1
- package/dist/mcp/__tests__/standalone-shutdown.test.d.ts +2 -0
- package/dist/mcp/__tests__/standalone-shutdown.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/standalone-shutdown.test.js +57 -0
- package/dist/mcp/__tests__/standalone-shutdown.test.js.map +1 -0
- package/dist/mcp/__tests__/team-cleanup.test.js +5 -5
- package/dist/mcp/job-management.d.ts +4 -0
- package/dist/mcp/job-management.d.ts.map +1 -1
- package/dist/mcp/job-management.js +30 -10
- package/dist/mcp/job-management.js.map +1 -1
- package/dist/mcp/omc-tools-server.d.ts +2 -0
- package/dist/mcp/omc-tools-server.d.ts.map +1 -1
- package/dist/mcp/omc-tools-server.js +10 -2
- package/dist/mcp/omc-tools-server.js.map +1 -1
- package/dist/mcp/prompt-injection.d.ts.map +1 -1
- package/dist/mcp/prompt-injection.js +25 -4
- package/dist/mcp/prompt-injection.js.map +1 -1
- package/dist/mcp/prompt-persistence.js +1 -1
- package/dist/mcp/prompt-persistence.js.map +1 -1
- package/dist/mcp/standalone-server.js +15 -4
- package/dist/mcp/standalone-server.js.map +1 -1
- package/dist/mcp/standalone-shutdown.d.ts +25 -0
- package/dist/mcp/standalone-shutdown.d.ts.map +1 -0
- package/dist/mcp/standalone-shutdown.js +68 -0
- package/dist/mcp/standalone-shutdown.js.map +1 -0
- package/dist/mcp/team-job-convergence.d.ts +0 -1
- package/dist/mcp/team-job-convergence.d.ts.map +1 -1
- package/dist/mcp/team-job-convergence.js +0 -9
- package/dist/mcp/team-job-convergence.js.map +1 -1
- package/dist/mcp/team-server.d.ts.map +1 -1
- package/dist/mcp/team-server.js +18 -11
- package/dist/mcp/team-server.js.map +1 -1
- package/dist/notifications/__tests__/reply-listener.test.js +57 -1
- package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +36 -3
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/dispatcher.d.ts.map +1 -1
- package/dist/notifications/dispatcher.js +18 -14
- package/dist/notifications/dispatcher.js.map +1 -1
- package/dist/notifications/redact.d.ts.map +1 -1
- package/dist/notifications/redact.js +10 -1
- package/dist/notifications/redact.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts +2 -0
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +17 -24
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/session-registry.d.ts +1 -1
- package/dist/notifications/session-registry.d.ts.map +1 -1
- package/dist/notifications/session-registry.js +37 -43
- package/dist/notifications/session-registry.js.map +1 -1
- package/dist/notifications/types.d.ts +2 -0
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/planning/__tests__/artifacts.test.d.ts +2 -0
- package/dist/planning/__tests__/artifacts.test.d.ts.map +1 -0
- package/dist/planning/__tests__/artifacts.test.js +303 -0
- package/dist/planning/__tests__/artifacts.test.js.map +1 -0
- package/dist/planning/artifacts.d.ts +29 -0
- package/dist/planning/artifacts.d.ts.map +1 -0
- package/dist/planning/artifacts.js +144 -0
- package/dist/planning/artifacts.js.map +1 -0
- package/dist/platform/process-utils.d.ts +1 -0
- package/dist/platform/process-utils.d.ts.map +1 -1
- package/dist/platform/process-utils.js +7 -3
- package/dist/platform/process-utils.js.map +1 -1
- package/dist/providers/bitbucket.d.ts +2 -2
- package/dist/providers/bitbucket.d.ts.map +1 -1
- package/dist/providers/bitbucket.js +11 -12
- package/dist/providers/bitbucket.js.map +1 -1
- package/dist/providers/gitea.d.ts.map +1 -1
- package/dist/providers/gitea.js +8 -2
- package/dist/providers/gitea.js.map +1 -1
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +49 -26
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/types.d.ts +2 -2
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/ralphthon/__tests__/cli.test.d.ts +5 -0
- package/dist/ralphthon/__tests__/cli.test.d.ts.map +1 -0
- package/dist/ralphthon/__tests__/cli.test.js +103 -0
- package/dist/ralphthon/__tests__/cli.test.js.map +1 -0
- package/dist/ralphthon/__tests__/orchestrator.test.d.ts +5 -0
- package/dist/ralphthon/__tests__/orchestrator.test.d.ts.map +1 -0
- package/dist/ralphthon/__tests__/orchestrator.test.js +393 -0
- package/dist/ralphthon/__tests__/orchestrator.test.js.map +1 -0
- package/dist/ralphthon/__tests__/prd.test.d.ts +5 -0
- package/dist/ralphthon/__tests__/prd.test.d.ts.map +1 -0
- package/dist/ralphthon/__tests__/prd.test.js +454 -0
- package/dist/ralphthon/__tests__/prd.test.js.map +1 -0
- package/dist/ralphthon/deep-interview-prompt.d.ts +2 -0
- package/dist/ralphthon/deep-interview-prompt.d.ts.map +1 -0
- package/dist/ralphthon/deep-interview-prompt.js +20 -0
- package/dist/ralphthon/deep-interview-prompt.js.map +1 -0
- package/dist/ralphthon/index.d.ts +13 -0
- package/dist/ralphthon/index.d.ts.map +1 -0
- package/dist/ralphthon/index.js +14 -0
- package/dist/ralphthon/index.js.map +1 -0
- package/dist/ralphthon/orchestrator.d.ts +112 -0
- package/dist/ralphthon/orchestrator.d.ts.map +1 -0
- package/dist/ralphthon/orchestrator.js +453 -0
- package/dist/ralphthon/orchestrator.js.map +1 -0
- package/dist/ralphthon/prd.d.ts +111 -0
- package/dist/ralphthon/prd.d.ts.map +1 -0
- package/dist/ralphthon/prd.js +345 -0
- package/dist/ralphthon/prd.js.map +1 -0
- package/dist/ralphthon/types.d.ts +213 -0
- package/dist/ralphthon/types.d.ts.map +1 -0
- package/dist/ralphthon/types.js +21 -0
- package/dist/ralphthon/types.js.map +1 -0
- package/dist/shared/types.d.ts +25 -16
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/skills/__tests__/mingw-escape.test.js +15 -0
- package/dist/skills/__tests__/mingw-escape.test.js.map +1 -1
- package/dist/team/__tests__/allocation-policy.test.d.ts +2 -0
- package/dist/team/__tests__/allocation-policy.test.d.ts.map +1 -0
- package/dist/team/__tests__/allocation-policy.test.js +125 -0
- package/dist/team/__tests__/allocation-policy.test.js.map +1 -0
- package/dist/team/__tests__/api-interop.cleanup.test.d.ts +2 -0
- package/dist/team/__tests__/api-interop.cleanup.test.d.ts.map +1 -0
- package/dist/team/__tests__/api-interop.cleanup.test.js +129 -0
- package/dist/team/__tests__/api-interop.cleanup.test.js.map +1 -0
- package/dist/team/__tests__/api-interop.cwd-resolution.test.js +22 -0
- package/dist/team/__tests__/api-interop.cwd-resolution.test.js.map +1 -1
- package/dist/team/__tests__/api-interop.dispatch.test.js +59 -0
- package/dist/team/__tests__/api-interop.dispatch.test.js.map +1 -1
- package/dist/team/__tests__/audit-log.test.js +0 -1
- package/dist/team/__tests__/audit-log.test.js.map +1 -1
- package/dist/team/__tests__/bridge-integration.test.js.map +1 -1
- package/dist/team/__tests__/events.swallowed-error.test.d.ts +2 -0
- package/dist/team/__tests__/events.swallowed-error.test.d.ts.map +1 -0
- package/dist/team/__tests__/events.swallowed-error.test.js +33 -0
- package/dist/team/__tests__/events.swallowed-error.test.js.map +1 -0
- package/dist/team/__tests__/followup-planner.test.d.ts +2 -0
- package/dist/team/__tests__/followup-planner.test.d.ts.map +1 -0
- package/dist/team/__tests__/followup-planner.test.js +197 -0
- package/dist/team/__tests__/followup-planner.test.js.map +1 -0
- package/dist/team/__tests__/governance-enforcement.test.d.ts +2 -0
- package/dist/team/__tests__/governance-enforcement.test.d.ts.map +1 -0
- package/dist/team/__tests__/governance-enforcement.test.js +138 -0
- package/dist/team/__tests__/governance-enforcement.test.js.map +1 -0
- package/dist/team/__tests__/governance.test.d.ts +2 -0
- package/dist/team/__tests__/governance.test.d.ts.map +1 -0
- package/dist/team/__tests__/governance.test.js +38 -0
- package/dist/team/__tests__/governance.test.js.map +1 -0
- package/dist/team/__tests__/idle-nudge.test.js +9 -0
- package/dist/team/__tests__/idle-nudge.test.js.map +1 -1
- package/dist/team/__tests__/leader-nudge-guidance.test.d.ts +2 -0
- package/dist/team/__tests__/leader-nudge-guidance.test.d.ts.map +1 -0
- package/dist/team/__tests__/leader-nudge-guidance.test.js +37 -0
- package/dist/team/__tests__/leader-nudge-guidance.test.js.map +1 -0
- package/dist/team/__tests__/lifecycle-profile.test.d.ts +2 -0
- package/dist/team/__tests__/lifecycle-profile.test.d.ts.map +1 -0
- package/dist/team/__tests__/lifecycle-profile.test.js +46 -0
- package/dist/team/__tests__/lifecycle-profile.test.js.map +1 -0
- package/dist/team/__tests__/model-contract.test.js +84 -3
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/phase1-foundation.test.d.ts +2 -0
- package/dist/team/__tests__/phase1-foundation.test.d.ts.map +1 -0
- package/dist/team/__tests__/phase1-foundation.test.js +151 -0
- package/dist/team/__tests__/phase1-foundation.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 +122 -0
- package/dist/team/__tests__/role-router.test.js.map +1 -0
- package/dist/team/__tests__/runtime-prompt-mode.test.js +4 -1
- package/dist/team/__tests__/runtime-prompt-mode.test.js.map +1 -1
- package/dist/team/__tests__/runtime-v2.dispatch.test.js +114 -6
- package/dist/team/__tests__/runtime-v2.dispatch.test.js.map +1 -1
- package/dist/team/__tests__/runtime-v2.monitor.test.js +45 -0
- package/dist/team/__tests__/runtime-v2.monitor.test.js.map +1 -1
- package/dist/team/__tests__/runtime-v2.shutdown-pane-cleanup.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-v2.shutdown-pane-cleanup.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-v2.shutdown-pane-cleanup.test.js +110 -0
- package/dist/team/__tests__/runtime-v2.shutdown-pane-cleanup.test.js.map +1 -0
- package/dist/team/__tests__/scaling.test.d.ts +2 -0
- package/dist/team/__tests__/scaling.test.d.ts.map +1 -0
- package/dist/team/__tests__/scaling.test.js +44 -0
- package/dist/team/__tests__/scaling.test.js.map +1 -0
- package/dist/team/__tests__/shell-affinity.test.d.ts +2 -0
- package/dist/team/__tests__/shell-affinity.test.d.ts.map +1 -0
- package/dist/team/__tests__/shell-affinity.test.js +98 -0
- package/dist/team/__tests__/shell-affinity.test.js.map +1 -0
- package/dist/team/__tests__/state-paths.test.js +4 -1
- package/dist/team/__tests__/state-paths.test.js.map +1 -1
- package/dist/team/__tests__/task-file-ops.test.js +6 -4
- package/dist/team/__tests__/task-file-ops.test.js.map +1 -1
- package/dist/team/__tests__/team-leader-nudge-hook.logging.test.d.ts +2 -0
- package/dist/team/__tests__/team-leader-nudge-hook.logging.test.d.ts.map +1 -0
- package/dist/team/__tests__/team-leader-nudge-hook.logging.test.js +63 -0
- package/dist/team/__tests__/team-leader-nudge-hook.logging.test.js.map +1 -0
- package/dist/team/__tests__/team-leader-nudge-hook.test.d.ts +2 -0
- package/dist/team/__tests__/team-leader-nudge-hook.test.d.ts.map +1 -0
- package/dist/team/__tests__/team-leader-nudge-hook.test.js +90 -0
- package/dist/team/__tests__/team-leader-nudge-hook.test.js.map +1 -0
- package/dist/team/__tests__/tmux-comm.test.js +5 -4
- package/dist/team/__tests__/tmux-comm.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.create-team.test.js +46 -2
- package/dist/team/__tests__/tmux-session.create-team.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.kill-team-session.test.js +45 -13
- package/dist/team/__tests__/tmux-session.kill-team-session.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +50 -58
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/unified-team.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +50 -5
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/__tests__/worker-canonicalization.test.d.ts +2 -0
- package/dist/team/__tests__/worker-canonicalization.test.d.ts.map +1 -0
- package/dist/team/__tests__/worker-canonicalization.test.js +35 -0
- package/dist/team/__tests__/worker-canonicalization.test.js.map +1 -0
- package/dist/team/__tests__/worker-health.test.js.map +1 -1
- package/dist/team/__tests__/worker-restart.test.js +3 -1
- package/dist/team/__tests__/worker-restart.test.js.map +1 -1
- package/dist/team/allocation-policy.d.ts +34 -0
- package/dist/team/allocation-policy.d.ts.map +1 -0
- package/dist/team/allocation-policy.js +92 -0
- package/dist/team/allocation-policy.js.map +1 -0
- package/dist/team/api-interop.d.ts +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +51 -6
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/audit-log.d.ts.map +1 -1
- package/dist/team/audit-log.js +3 -2
- package/dist/team/audit-log.js.map +1 -1
- package/dist/team/events.d.ts.map +1 -1
- package/dist/team/events.js +6 -4
- package/dist/team/events.js.map +1 -1
- package/dist/team/followup-planner.d.ts +32 -0
- package/dist/team/followup-planner.d.ts.map +1 -0
- package/dist/team/followup-planner.js +82 -0
- package/dist/team/followup-planner.js.map +1 -0
- package/dist/team/git-worktree.d.ts.map +1 -1
- package/dist/team/git-worktree.js +20 -10
- package/dist/team/git-worktree.js.map +1 -1
- package/dist/team/governance.d.ts +18 -0
- package/dist/team/governance.d.ts.map +1 -0
- package/dist/team/governance.js +68 -0
- package/dist/team/governance.js.map +1 -0
- package/dist/team/index.d.ts +2 -1
- package/dist/team/index.d.ts.map +1 -1
- package/dist/team/index.js +1 -0
- package/dist/team/index.js.map +1 -1
- package/dist/team/leader-nudge-guidance.d.ts +23 -0
- package/dist/team/leader-nudge-guidance.d.ts.map +1 -0
- package/dist/team/leader-nudge-guidance.js +44 -0
- package/dist/team/leader-nudge-guidance.js.map +1 -0
- package/dist/team/mcp-comm.d.ts.map +1 -1
- package/dist/team/mcp-comm.js +17 -3
- package/dist/team/mcp-comm.js.map +1 -1
- package/dist/team/mcp-team-bridge.d.ts.map +1 -1
- package/dist/team/mcp-team-bridge.js +11 -48
- package/dist/team/mcp-team-bridge.js.map +1 -1
- package/dist/team/merge-coordinator.d.ts +3 -1
- package/dist/team/merge-coordinator.d.ts.map +1 -1
- package/dist/team/merge-coordinator.js +27 -5
- package/dist/team/merge-coordinator.js.map +1 -1
- package/dist/team/model-contract.d.ts +17 -0
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +49 -2
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/monitor.d.ts.map +1 -1
- package/dist/team/monitor.js +69 -2
- package/dist/team/monitor.js.map +1 -1
- package/dist/team/outbox-reader.d.ts.map +1 -1
- package/dist/team/outbox-reader.js +13 -10
- package/dist/team/outbox-reader.js.map +1 -1
- package/dist/team/phase-controller.js +2 -2
- package/dist/team/phase-controller.js.map +1 -1
- package/dist/team/role-router.d.ts +36 -0
- package/dist/team/role-router.d.ts.map +1 -0
- package/dist/team/role-router.js +215 -0
- package/dist/team/role-router.js.map +1 -0
- package/dist/team/runtime-cli.d.ts.map +1 -1
- package/dist/team/runtime-cli.js +35 -0
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime-v2.d.ts +1 -0
- package/dist/team/runtime-v2.d.ts.map +1 -1
- package/dist/team/runtime-v2.js +164 -49
- package/dist/team/runtime-v2.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +29 -15
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +12 -3
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/tasks.js +1 -1
- package/dist/team/state/tasks.js.map +1 -1
- package/dist/team/state-paths.js +2 -2
- package/dist/team/state-paths.js.map +1 -1
- package/dist/team/task-file-ops.d.ts.map +1 -1
- package/dist/team/task-file-ops.js +3 -43
- package/dist/team/task-file-ops.js.map +1 -1
- package/dist/team/task-router.d.ts.map +1 -1
- package/dist/team/task-router.js +31 -1
- package/dist/team/task-router.js.map +1 -1
- package/dist/team/team-ops.d.ts.map +1 -1
- package/dist/team/team-ops.js +93 -49
- package/dist/team/team-ops.js.map +1 -1
- package/dist/team/team-registration.d.ts.map +1 -1
- package/dist/team/team-registration.js +18 -14
- package/dist/team/team-registration.js.map +1 -1
- package/dist/team/team-status.d.ts +1 -1
- package/dist/team/team-status.d.ts.map +1 -1
- package/dist/team/team-status.js +8 -5
- package/dist/team/team-status.js.map +1 -1
- package/dist/team/tmux-comm.d.ts.map +1 -1
- package/dist/team/tmux-comm.js +5 -2
- package/dist/team/tmux-comm.js.map +1 -1
- package/dist/team/tmux-session.d.ts +32 -5
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +179 -50
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/types.d.ts +16 -3
- package/dist/team/types.d.ts.map +1 -1
- package/dist/team/types.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +36 -23
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/team/worker-canonicalization.d.ts +8 -0
- package/dist/team/worker-canonicalization.d.ts.map +1 -0
- package/dist/team/worker-canonicalization.js +98 -0
- package/dist/team/worker-canonicalization.js.map +1 -0
- package/dist/tools/__tests__/cancel-integration.test.js +57 -2
- package/dist/tools/__tests__/cancel-integration.test.js.map +1 -1
- package/dist/tools/__tests__/deepinit-manifest.test.d.ts +7 -0
- package/dist/tools/__tests__/deepinit-manifest.test.d.ts.map +1 -0
- package/dist/tools/__tests__/deepinit-manifest.test.js +559 -0
- package/dist/tools/__tests__/deepinit-manifest.test.js.map +1 -0
- package/dist/tools/__tests__/state-tools.test.js +16 -0
- package/dist/tools/__tests__/state-tools.test.js.map +1 -1
- package/dist/tools/ast-tools.d.ts.map +1 -1
- package/dist/tools/ast-tools.js +11 -2
- package/dist/tools/ast-tools.js.map +1 -1
- package/dist/tools/deepinit-manifest.d.ts +88 -0
- package/dist/tools/deepinit-manifest.d.ts.map +1 -0
- package/dist/tools/deepinit-manifest.js +373 -0
- package/dist/tools/deepinit-manifest.js.map +1 -0
- package/dist/tools/diagnostics/tsc-runner.js +2 -2
- package/dist/tools/diagnostics/tsc-runner.js.map +1 -1
- package/dist/tools/lsp/__tests__/client-devcontainer.test.d.ts +2 -0
- package/dist/tools/lsp/__tests__/client-devcontainer.test.d.ts.map +1 -0
- package/dist/tools/lsp/__tests__/client-devcontainer.test.js +185 -0
- package/dist/tools/lsp/__tests__/client-devcontainer.test.js.map +1 -0
- package/dist/tools/lsp/__tests__/client-singleton.test.d.ts +2 -0
- package/dist/tools/lsp/__tests__/client-singleton.test.d.ts.map +1 -0
- package/dist/tools/lsp/__tests__/client-singleton.test.js +17 -0
- package/dist/tools/lsp/__tests__/client-singleton.test.js.map +1 -0
- package/dist/tools/lsp/__tests__/client-timeout-env.test.js +18 -2
- package/dist/tools/lsp/__tests__/client-timeout-env.test.js.map +1 -1
- package/dist/tools/lsp/__tests__/devcontainer.test.d.ts +2 -0
- package/dist/tools/lsp/__tests__/devcontainer.test.d.ts.map +1 -0
- package/dist/tools/lsp/__tests__/devcontainer.test.js +311 -0
- package/dist/tools/lsp/__tests__/devcontainer.test.js.map +1 -0
- package/dist/tools/lsp/client.d.ts +17 -3
- package/dist/tools/lsp/client.d.ts.map +1 -1
- package/dist/tools/lsp/client.js +228 -77
- package/dist/tools/lsp/client.js.map +1 -1
- package/dist/tools/lsp/devcontainer.d.ts +12 -0
- package/dist/tools/lsp/devcontainer.d.ts.map +1 -0
- package/dist/tools/lsp/devcontainer.js +276 -0
- package/dist/tools/lsp/devcontainer.js.map +1 -0
- package/dist/tools/lsp/index.d.ts +2 -0
- package/dist/tools/lsp/index.d.ts.map +1 -1
- package/dist/tools/lsp/index.js +1 -0
- package/dist/tools/lsp/index.js.map +1 -1
- package/dist/tools/lsp/servers.d.ts +1 -0
- package/dist/tools/lsp/servers.d.ts.map +1 -1
- package/dist/tools/lsp/servers.js +20 -5
- package/dist/tools/lsp/servers.js.map +1 -1
- package/dist/tools/lsp/utils.d.ts.map +1 -1
- package/dist/tools/lsp/utils.js +7 -1
- package/dist/tools/lsp/utils.js.map +1 -1
- package/dist/tools/python-repl/__tests__/bridge-manager-cleanup.test.js +34 -1
- package/dist/tools/python-repl/__tests__/bridge-manager-cleanup.test.js.map +1 -1
- package/dist/tools/python-repl/bridge-manager.d.ts +2 -0
- package/dist/tools/python-repl/bridge-manager.d.ts.map +1 -1
- package/dist/tools/python-repl/bridge-manager.js +38 -2
- package/dist/tools/python-repl/bridge-manager.js.map +1 -1
- package/dist/tools/python-repl/socket-client.d.ts.map +1 -1
- package/dist/tools/python-repl/socket-client.js +37 -7
- package/dist/tools/python-repl/socket-client.js.map +1 -1
- package/dist/tools/python-repl/tool.d.ts.map +1 -1
- package/dist/tools/python-repl/tool.js +1 -5
- package/dist/tools/python-repl/tool.js.map +1 -1
- package/dist/tools/state-tools.d.ts.map +1 -1
- package/dist/tools/state-tools.js +193 -57
- package/dist/tools/state-tools.js.map +1 -1
- package/dist/tools/trace-tools.d.ts.map +1 -1
- package/dist/tools/trace-tools.js +7 -5
- package/dist/tools/trace-tools.js.map +1 -1
- package/dist/tools/types.d.ts +16 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils/__tests__/paths.test.js +86 -1
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/jsonc.d.ts.map +1 -1
- package/dist/utils/jsonc.js +6 -2
- package/dist/utils/jsonc.js.map +1 -1
- package/dist/utils/omc-cli-rendering.d.ts +8 -0
- package/dist/utils/omc-cli-rendering.d.ts.map +1 -0
- package/dist/utils/omc-cli-rendering.js +37 -0
- package/dist/utils/omc-cli-rendering.js.map +1 -0
- package/dist/utils/paths.d.ts +32 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +103 -8
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/skill-resources.d.ts +7 -0
- package/dist/utils/skill-resources.d.ts.map +1 -0
- package/dist/utils/skill-resources.js +53 -0
- package/dist/utils/skill-resources.js.map +1 -0
- package/dist/utils/ssrf-guard.d.ts.map +1 -1
- package/dist/utils/ssrf-guard.js +22 -0
- package/dist/utils/ssrf-guard.js.map +1 -1
- package/docs/ARCHITECTURE.md +468 -37
- package/docs/CLAUDE.md +1 -1
- package/docs/COMPATIBILITY.md +18 -1
- package/docs/LOCAL_PLUGIN_INSTALL.md +17 -3
- package/docs/MIGRATION.md +8 -46
- package/docs/PERFORMANCE-MONITORING.md +2 -2
- package/docs/REFERENCE.md +99 -58
- package/docs/design/SKILLS_2_0_ADAPTATION.md +115 -0
- package/docs/ko/ARCHITECTURE.md +1 -1
- package/docs/ko/MIGRATION.md +7 -47
- package/docs/ko/REFERENCE.md +1 -15
- package/docs/partials/features.md +1 -32
- package/docs/partials/mode-hierarchy.md +7 -22
- package/docs/partials/verification-tiers.md +1 -1
- package/docs/plans/2026-02-26-skill-optimization-design.md +3 -3
- package/docs/shared/features.md +1 -32
- package/docs/shared/mode-hierarchy.md +7 -22
- package/docs/shared/verification-tiers.md +1 -1
- package/hooks/hooks.json +21 -31
- package/package.json +1 -1
- package/scripts/cleanup-orphans.mjs +12 -9
- package/scripts/context-guard-stop.mjs +13 -5
- package/scripts/context-safety.mjs +12 -149
- package/scripts/eval-autoresearch-json.mjs +49 -0
- package/scripts/eval-autoresearch-timed-json.mjs +62 -0
- package/scripts/generate-featured-contributors.ts +43 -0
- package/scripts/keyword-detector.mjs +136 -36
- package/scripts/persistent-mode.cjs +87 -25
- package/scripts/persistent-mode.mjs +37 -17
- package/scripts/plugin-setup.mjs +19 -16
- package/scripts/post-tool-verifier.mjs +25 -20
- package/scripts/pre-tool-enforcer.mjs +184 -6
- package/scripts/project-memory-session.mjs +5 -1
- package/scripts/release.ts +511 -0
- package/scripts/run-provider-advisor.js +10 -4
- package/scripts/session-end.mjs +3 -2
- package/scripts/session-start.mjs +118 -4
- package/scripts/session-summary.mjs +241 -0
- package/scripts/setup-claude-md.sh +140 -3
- package/scripts/skill-injector.mjs +2 -1
- package/scripts/sync-metadata.ts +41 -7
- package/scripts/sync-version.sh +42 -0
- package/skills/AGENTS.md +108 -74
- package/skills/ai-slop-cleaner/SKILL.md +120 -117
- package/skills/ask/SKILL.md +4 -2
- package/skills/autopilot/SKILL.md +1 -0
- package/skills/cancel/SKILL.md +62 -0
- package/skills/ccg/SKILL.md +7 -13
- package/skills/configure-notifications/SKILL.md +1 -0
- package/skills/deep-dive/SKILL.md +476 -0
- package/skills/deep-interview/SKILL.md +109 -14
- package/skills/deepinit/SKILL.md +1 -0
- package/skills/external-context/SKILL.md +1 -0
- package/skills/hud/SKILL.md +6 -5
- package/skills/learner/SKILL.md +63 -57
- package/skills/mcp-setup/SKILL.md +1 -0
- package/skills/omc-doctor/SKILL.md +6 -5
- package/skills/omc-reference/SKILL.md +141 -0
- package/skills/omc-setup/SKILL.md +11 -2
- package/skills/omc-setup/phases/01-install-claude-md.md +11 -1
- package/skills/omc-setup/phases/02-configure.md +3 -1
- package/skills/omc-teams/SKILL.md +9 -5
- package/skills/plan/SKILL.md +23 -7
- package/skills/project-session-manager/SKILL.md +3 -2
- package/skills/ralph/SKILL.md +17 -1
- package/skills/ralplan/SKILL.md +4 -1
- package/skills/release/SKILL.md +1 -0
- package/skills/sciomc/SKILL.md +1 -0
- package/skills/setup/SKILL.md +9 -8
- package/skills/skill-creator/SKILL.md +311 -0
- package/skills/skill-creator/references/upstream-anthropic-skill-creator.md +485 -0
- package/skills/skill-debugger/README.md +52 -0
- package/skills/skill-debugger/SKILL.md +146 -270
- package/skills/skill-quality-analyzer/HOW_TO_USE.md +92 -185
- package/skills/skill-quality-analyzer/README.md +39 -35
- package/skills/skill-quality-analyzer/SKILL.md +105 -196
- package/skills/skill-tester/README.md +31 -23
- package/skills/skill-tester/SKILL.md +116 -266
- package/skills/team/SKILL.md +1 -0
- package/skills/trace/SKILL.md +262 -0
- package/skills/ultraqa/SKILL.md +1 -0
- package/skills/ultrawork/SKILL.md +1 -0
- package/skills/visual-verdict/SKILL.md +77 -0
- package/skills/writer-memory/SKILL.md +1 -0
- package/templates/hooks/keyword-detector.mjs +89 -25
- package/templates/hooks/persistent-mode.mjs +33 -9
- package/templates/hooks/post-tool-use-failure.mjs +2 -5
- package/templates/hooks/pre-tool-use.mjs +47 -1
- package/templates/hooks/session-start.mjs +105 -14
- package/templates/hooks/stop-continuation.mjs +7 -1
- package/dist/__tests__/codex-backoff.test.d.ts +0 -2
- package/dist/__tests__/codex-backoff.test.d.ts.map +0 -1
- package/dist/__tests__/codex-backoff.test.js +0 -143
- package/dist/__tests__/codex-backoff.test.js.map +0 -1
- package/dist/__tests__/codex-callsite-normalization.test.js +0 -112
- package/dist/__tests__/compatibility-security.test.d.ts +0 -13
- package/dist/__tests__/compatibility-security.test.d.ts.map +0 -1
- package/dist/__tests__/compatibility-security.test.js +0 -403
- package/dist/__tests__/compatibility-security.test.js.map +0 -1
- package/dist/__tests__/compatibility.test.d.ts +0 -7
- package/dist/__tests__/compatibility.test.d.ts.map +0 -1
- package/dist/__tests__/compatibility.test.js +0 -484
- package/dist/__tests__/compatibility.test.js.map +0 -1
- package/dist/__tests__/example.test.d.ts +0 -2
- package/dist/__tests__/example.test.d.ts.map +0 -1
- package/dist/__tests__/example.test.js +0 -20
- package/dist/__tests__/example.test.js.map +0 -1
- package/dist/__tests__/hud/analytics-display.test.d.ts +0 -2
- package/dist/__tests__/hud/analytics-display.test.d.ts.map +0 -1
- package/dist/__tests__/hud/analytics-display.test.js +0 -236
- package/dist/__tests__/hud/analytics-display.test.js.map +0 -1
- package/dist/__tests__/hud/top-agents.test.d.ts +0 -8
- package/dist/__tests__/hud/top-agents.test.d.ts.map +0 -1
- package/dist/__tests__/hud/top-agents.test.js +0 -158
- package/dist/__tests__/hud/top-agents.test.js.map +0 -1
- package/dist/__tests__/inline-prompt-integration.test.d.ts +0 -2
- package/dist/__tests__/inline-prompt-integration.test.d.ts.map +0 -1
- package/dist/__tests__/inline-prompt-integration.test.js +0 -411
- package/dist/__tests__/inline-prompt-integration.test.js.map +0 -1
- package/dist/__tests__/inline-success-shape.test.d.ts +0 -2
- package/dist/__tests__/inline-success-shape.test.d.ts.map +0 -1
- package/dist/__tests__/inline-success-shape.test.js +0 -130
- package/dist/__tests__/inline-success-shape.test.js.map +0 -1
- package/dist/__tests__/mcp-fallback-429.test.d.ts +0 -2
- package/dist/__tests__/mcp-fallback-429.test.d.ts.map +0 -1
- package/dist/__tests__/mcp-fallback-429.test.js +0 -193
- package/dist/__tests__/mcp-fallback-429.test.js.map +0 -1
- package/dist/__tests__/mcp-server-workflows.test.d.ts +0 -2
- package/dist/__tests__/mcp-server-workflows.test.d.ts.map +0 -1
- package/dist/__tests__/mcp-server-workflows.test.js +0 -301
- package/dist/__tests__/mcp-server-workflows.test.js.map +0 -1
- package/dist/__tests__/multi-model-mcp-integration.test.d.ts +0 -2
- package/dist/__tests__/multi-model-mcp-integration.test.d.ts.map +0 -1
- package/dist/__tests__/multi-model-mcp-integration.test.js +0 -69
- package/dist/__tests__/multi-model-mcp-integration.test.js.map +0 -1
- package/dist/__tests__/multi-model-mcp.test.d.ts +0 -2
- package/dist/__tests__/multi-model-mcp.test.d.ts.map +0 -1
- package/dist/__tests__/multi-model-mcp.test.js +0 -145
- package/dist/__tests__/multi-model-mcp.test.js.map +0 -1
- package/dist/__tests__/omc-shorthand.test.d.ts +0 -2
- package/dist/__tests__/omc-shorthand.test.d.ts.map +0 -1
- package/dist/__tests__/omc-shorthand.test.js +0 -73
- package/dist/__tests__/omc-shorthand.test.js.map +0 -1
- package/dist/__tests__/prompt-file-only.test.d.ts +0 -2
- package/dist/__tests__/prompt-file-only.test.d.ts.map +0 -1
- package/dist/__tests__/prompt-file-only.test.js +0 -263
- package/dist/__tests__/prompt-file-only.test.js.map +0 -1
- package/dist/__tests__/session-catalog.test.d.ts +0 -2
- package/dist/__tests__/session-catalog.test.d.ts.map +0 -1
- package/dist/__tests__/session-catalog.test.js +0 -195
- package/dist/__tests__/session-catalog.test.js.map +0 -1
- package/dist/__tests__/session-migration.test.d.ts +0 -2
- package/dist/__tests__/session-migration.test.d.ts.map +0 -1
- package/dist/__tests__/session-migration.test.js +0 -155
- package/dist/__tests__/session-migration.test.js.map +0 -1
- package/dist/__tests__/shell-path.test.d.ts +0 -5
- package/dist/__tests__/shell-path.test.d.ts.map +0 -1
- package/dist/__tests__/shell-path.test.js +0 -70
- package/dist/__tests__/shell-path.test.js.map +0 -1
- package/dist/__tests__/smoke-functional.test.d.ts +0 -8
- package/dist/__tests__/smoke-functional.test.d.ts.map +0 -1
- package/dist/__tests__/smoke-functional.test.js +0 -450
- package/dist/__tests__/smoke-functional.test.js.map +0 -1
- package/dist/__tests__/smoke-team-worker.test.d.ts +0 -15
- package/dist/__tests__/smoke-team-worker.test.d.ts.map +0 -1
- package/dist/__tests__/smoke-team-worker.test.js +0 -483
- package/dist/__tests__/smoke-team-worker.test.js.map +0 -1
- package/dist/__tests__/validate-and-read-file.test.d.ts +0 -2
- package/dist/__tests__/validate-and-read-file.test.d.ts.map +0 -1
- package/dist/__tests__/validate-and-read-file.test.js +0 -84
- package/dist/__tests__/validate-and-read-file.test.js.map +0 -1
- package/dist/__tests__/worker-adapter.test.d.ts +0 -5
- package/dist/__tests__/worker-adapter.test.d.ts.map +0 -1
- package/dist/__tests__/worker-adapter.test.js +0 -211
- package/dist/__tests__/worker-adapter.test.js.map +0 -1
- package/dist/agents/coordinator-deprecated.d.ts +0 -18
- package/dist/agents/coordinator-deprecated.d.ts.map +0 -1
- package/dist/agents/coordinator-deprecated.js +0 -38
- package/dist/agents/coordinator-deprecated.js.map +0 -1
- package/dist/agents/deep-executor.d.ts +0 -15
- package/dist/agents/deep-executor.d.ts.map +0 -1
- package/dist/agents/deep-executor.js +0 -45
- package/dist/agents/deep-executor.js.map +0 -1
- package/dist/agents/delegation-validator.d.ts +0 -31
- package/dist/agents/delegation-validator.d.ts.map +0 -1
- package/dist/agents/delegation-validator.js +0 -75
- package/dist/agents/delegation-validator.js.map +0 -1
- package/dist/agents/harsh-critic.d.ts +0 -14
- package/dist/agents/harsh-critic.d.ts.map +0 -1
- package/dist/agents/harsh-critic.js +0 -42
- package/dist/agents/harsh-critic.js.map +0 -1
- package/dist/agents/preamble.d.ts +0 -38
- package/dist/agents/preamble.d.ts.map +0 -1
- package/dist/agents/preamble.js +0 -122
- package/dist/agents/preamble.js.map +0 -1
- package/dist/agents/prompt-generator.d.ts +0 -96
- package/dist/agents/prompt-generator.d.ts.map +0 -1
- package/dist/agents/prompt-generator.js +0 -141
- package/dist/agents/prompt-generator.js.map +0 -1
- package/dist/agents/researcher.d.ts +0 -12
- package/dist/agents/researcher.d.ts.map +0 -1
- package/dist/agents/researcher.js +0 -40
- package/dist/agents/researcher.js.map +0 -1
- package/dist/agents/vision.d.ts +0 -11
- package/dist/agents/vision.d.ts.map +0 -1
- package/dist/agents/vision.js +0 -40
- package/dist/agents/vision.js.map +0 -1
- package/dist/cli/commands/__tests__/cleanup.test.d.ts +0 -2
- package/dist/cli/commands/__tests__/cleanup.test.d.ts.map +0 -1
- package/dist/cli/commands/__tests__/cleanup.test.js +0 -37
- package/dist/cli/commands/__tests__/cleanup.test.js.map +0 -1
- package/dist/compatibility/discovery.d.ts +0 -58
- package/dist/compatibility/discovery.d.ts.map +0 -1
- package/dist/compatibility/discovery.js +0 -620
- package/dist/compatibility/discovery.js.map +0 -1
- package/dist/compatibility/index.d.ts +0 -51
- package/dist/compatibility/index.d.ts.map +0 -1
- package/dist/compatibility/index.js +0 -72
- package/dist/compatibility/index.js.map +0 -1
- package/dist/compatibility/mcp-bridge.d.ts +0 -143
- package/dist/compatibility/mcp-bridge.d.ts.map +0 -1
- package/dist/compatibility/mcp-bridge.js +0 -540
- package/dist/compatibility/mcp-bridge.js.map +0 -1
- package/dist/compatibility/permission-adapter.d.ts +0 -79
- package/dist/compatibility/permission-adapter.d.ts.map +0 -1
- package/dist/compatibility/permission-adapter.js +0 -369
- package/dist/compatibility/permission-adapter.js.map +0 -1
- package/dist/compatibility/registry.d.ts +0 -161
- package/dist/compatibility/registry.d.ts.map +0 -1
- package/dist/compatibility/registry.js +0 -389
- package/dist/compatibility/registry.js.map +0 -1
- package/dist/compatibility/types.d.ts +0 -249
- package/dist/compatibility/types.d.ts.map +0 -1
- package/dist/compatibility/types.js +0 -8
- package/dist/compatibility/types.js.map +0 -1
- package/dist/features/model-routing/__tests__/external-model-policy.test.d.ts +0 -2
- package/dist/features/model-routing/__tests__/external-model-policy.test.d.ts.map +0 -1
- package/dist/features/model-routing/__tests__/external-model-policy.test.js +0 -476
- package/dist/features/model-routing/__tests__/external-model-policy.test.js.map +0 -1
- package/dist/features/model-routing/external-model-policy.d.ts +0 -27
- package/dist/features/model-routing/external-model-policy.d.ts.map +0 -1
- package/dist/features/model-routing/external-model-policy.js +0 -145
- package/dist/features/model-routing/external-model-policy.js.map +0 -1
- package/dist/features/verification/example.d.ts +0 -49
- package/dist/features/verification/example.d.ts.map +0 -1
- package/dist/features/verification/example.js +0 -237
- package/dist/features/verification/example.js.map +0 -1
- package/dist/hooks/setup/__tests__/github-star.test.d.ts +0 -8
- package/dist/hooks/setup/__tests__/github-star.test.d.ts.map +0 -1
- package/dist/hooks/setup/__tests__/github-star.test.js +0 -208
- package/dist/hooks/setup/__tests__/github-star.test.js.map +0 -1
- package/dist/hooks/setup/github-star.d.ts +0 -37
- package/dist/hooks/setup/github-star.d.ts.map +0 -1
- package/dist/hooks/setup/github-star.js +0 -123
- package/dist/hooks/setup/github-star.js.map +0 -1
- package/dist/hooks/swarm/__tests__/addMoreTasks.test.d.ts +0 -2
- package/dist/hooks/swarm/__tests__/addMoreTasks.test.d.ts.map +0 -1
- package/dist/hooks/swarm/__tests__/addMoreTasks.test.js +0 -203
- package/dist/hooks/swarm/__tests__/addMoreTasks.test.js.map +0 -1
- package/dist/hooks/swarm/__tests__/aggressive-swarm.integration.test.d.ts +0 -2
- package/dist/hooks/swarm/__tests__/aggressive-swarm.integration.test.d.ts.map +0 -1
- package/dist/hooks/swarm/__tests__/aggressive-swarm.integration.test.js +0 -273
- package/dist/hooks/swarm/__tests__/aggressive-swarm.integration.test.js.map +0 -1
- package/dist/hooks/swarm/__tests__/claiming.test.d.ts +0 -2
- package/dist/hooks/swarm/__tests__/claiming.test.d.ts.map +0 -1
- package/dist/hooks/swarm/__tests__/claiming.test.js +0 -170
- package/dist/hooks/swarm/__tests__/claiming.test.js.map +0 -1
- package/dist/hooks/swarm/__tests__/index.test.d.ts.map +0 -1
- package/dist/hooks/swarm/__tests__/index.test.js +0 -157
- package/dist/hooks/swarm/__tests__/index.test.js.map +0 -1
- package/dist/hooks/swarm/__tests__/migration.test.d.ts +0 -2
- package/dist/hooks/swarm/__tests__/migration.test.d.ts.map +0 -1
- package/dist/hooks/swarm/__tests__/migration.test.js +0 -140
- package/dist/hooks/swarm/__tests__/migration.test.js.map +0 -1
- package/dist/hooks/swarm/__tests__/mode-registry.test.d.ts +0 -2
- package/dist/hooks/swarm/__tests__/mode-registry.test.d.ts.map +0 -1
- package/dist/hooks/swarm/__tests__/mode-registry.test.js +0 -177
- package/dist/hooks/swarm/__tests__/mode-registry.test.js.map +0 -1
- package/dist/hooks/swarm/__tests__/priority-claiming.test.d.ts +0 -2
- package/dist/hooks/swarm/__tests__/priority-claiming.test.d.ts.map +0 -1
- package/dist/hooks/swarm/__tests__/priority-claiming.test.js +0 -122
- package/dist/hooks/swarm/__tests__/priority-claiming.test.js.map +0 -1
- package/dist/hooks/swarm/__tests__/types.test.d.ts +0 -2
- package/dist/hooks/swarm/__tests__/types.test.d.ts.map +0 -1
- package/dist/hooks/swarm/__tests__/types.test.js +0 -73
- package/dist/hooks/swarm/__tests__/types.test.js.map +0 -1
- package/dist/hooks/swarm/claiming.d.ts +0 -123
- package/dist/hooks/swarm/claiming.d.ts.map +0 -1
- package/dist/hooks/swarm/claiming.js +0 -639
- package/dist/hooks/swarm/claiming.js.map +0 -1
- package/dist/hooks/swarm/index.d.ts +0 -261
- package/dist/hooks/swarm/index.d.ts.map +0 -1
- package/dist/hooks/swarm/index.js +0 -485
- package/dist/hooks/swarm/index.js.map +0 -1
- package/dist/hooks/swarm/state.d.ts +0 -131
- package/dist/hooks/swarm/state.d.ts.map +0 -1
- package/dist/hooks/swarm/state.js +0 -690
- package/dist/hooks/swarm/state.js.map +0 -1
- package/dist/hooks/swarm/types.d.ts +0 -138
- package/dist/hooks/swarm/types.d.ts.map +0 -1
- package/dist/hooks/swarm/types.js +0 -22
- package/dist/hooks/swarm/types.js.map +0 -1
- package/dist/hooks/ultrapilot/decomposer.d.ts +0 -141
- package/dist/hooks/ultrapilot/decomposer.d.ts.map +0 -1
- package/dist/hooks/ultrapilot/decomposer.js +0 -379
- package/dist/hooks/ultrapilot/decomposer.js.map +0 -1
- package/dist/hooks/ultrapilot/index.d.ts +0 -121
- package/dist/hooks/ultrapilot/index.d.ts.map +0 -1
- package/dist/hooks/ultrapilot/index.js +0 -353
- package/dist/hooks/ultrapilot/index.js.map +0 -1
- package/dist/hooks/ultrapilot/state.d.ts +0 -72
- package/dist/hooks/ultrapilot/state.d.ts.map +0 -1
- package/dist/hooks/ultrapilot/state.js +0 -275
- package/dist/hooks/ultrapilot/state.js.map +0 -1
- package/dist/hooks/ultrapilot/types.d.ts +0 -115
- package/dist/hooks/ultrapilot/types.d.ts.map +0 -1
- package/dist/hooks/ultrapilot/types.js +0 -36
- package/dist/hooks/ultrapilot/types.js.map +0 -1
- package/dist/interop/__tests__/worker-adapter-integration.test.d.ts +0 -2
- package/dist/interop/__tests__/worker-adapter-integration.test.d.ts.map +0 -1
- package/dist/interop/__tests__/worker-adapter-integration.test.js +0 -219
- package/dist/interop/__tests__/worker-adapter-integration.test.js.map +0 -1
- package/dist/interop/__tests__/worker-adapter.test.d.ts +0 -2
- package/dist/interop/__tests__/worker-adapter.test.d.ts.map +0 -1
- package/dist/interop/__tests__/worker-adapter.test.js +0 -408
- package/dist/interop/__tests__/worker-adapter.test.js.map +0 -1
- package/dist/interop/adapter-types.d.ts +0 -39
- package/dist/interop/adapter-types.d.ts.map +0 -1
- package/dist/interop/adapter-types.js +0 -9
- package/dist/interop/adapter-types.js.map +0 -1
- package/dist/interop/worker-adapter.d.ts +0 -116
- package/dist/interop/worker-adapter.d.ts.map +0 -1
- package/dist/interop/worker-adapter.js +0 -324
- package/dist/interop/worker-adapter.js.map +0 -1
- package/dist/mcp/__tests__/codex-reasoning-effort.test.d.ts +0 -2
- package/dist/mcp/__tests__/codex-reasoning-effort.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/codex-reasoning-effort.test.js +0 -175
- package/dist/mcp/__tests__/codex-reasoning-effort.test.js.map +0 -1
- package/dist/mcp/__tests__/job-state-db-deprecation.test.d.ts +0 -2
- package/dist/mcp/__tests__/job-state-db-deprecation.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/job-state-db-deprecation.test.js +0 -119
- package/dist/mcp/__tests__/job-state-db-deprecation.test.js.map +0 -1
- package/dist/mcp/__tests__/shared-exec.test.d.ts +0 -2
- package/dist/mcp/__tests__/shared-exec.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/shared-exec.test.js +0 -151
- package/dist/mcp/__tests__/shared-exec.test.js.map +0 -1
- package/dist/mcp/__tests__/team-server-deprecation.test.d.ts +0 -2
- package/dist/mcp/__tests__/team-server-deprecation.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/team-server-deprecation.test.js +0 -56
- package/dist/mcp/__tests__/team-server-deprecation.test.js.map +0 -1
- package/dist/mcp/cli-detection.d.ts +0 -22
- package/dist/mcp/cli-detection.d.ts.map +0 -1
- package/dist/mcp/cli-detection.js +0 -77
- package/dist/mcp/cli-detection.js.map +0 -1
- package/dist/mcp/codex-core.d.ts +0 -119
- package/dist/mcp/codex-core.d.ts.map +0 -1
- package/dist/mcp/codex-core.js +0 -942
- package/dist/mcp/codex-core.js.map +0 -1
- package/dist/mcp/codex-request-normalizer.js +0 -59
- package/dist/mcp/codex-server.d.ts +0 -20
- package/dist/mcp/codex-server.d.ts.map +0 -1
- package/dist/mcp/codex-server.js +0 -81
- package/dist/mcp/codex-server.js.map +0 -1
- package/dist/mcp/codex-standalone-server.d.ts +0 -8
- package/dist/mcp/codex-standalone-server.d.ts.map +0 -1
- package/dist/mcp/codex-standalone-server.js +0 -81
- package/dist/mcp/codex-standalone-server.js.map +0 -1
- package/dist/mcp/gemini-core.d.ts +0 -75
- package/dist/mcp/gemini-core.d.ts.map +0 -1
- package/dist/mcp/gemini-core.js +0 -674
- package/dist/mcp/gemini-core.js.map +0 -1
- package/dist/mcp/gemini-server.d.ts +0 -20
- package/dist/mcp/gemini-server.d.ts.map +0 -1
- package/dist/mcp/gemini-server.js +0 -69
- package/dist/mcp/gemini-server.js.map +0 -1
- package/dist/mcp/gemini-standalone-server.d.ts +0 -8
- package/dist/mcp/gemini-standalone-server.d.ts.map +0 -1
- package/dist/mcp/gemini-standalone-server.js +0 -72
- package/dist/mcp/gemini-standalone-server.js.map +0 -1
- package/dist/mcp/job-state-db.d.ts +0 -2
- package/dist/mcp/job-state-db.d.ts.map +0 -1
- package/dist/mcp/job-state-db.js +0 -3
- package/dist/mcp/job-state-db.js.map +0 -1
- package/dist/mcp/shared-exec.d.ts +0 -50
- package/dist/mcp/shared-exec.d.ts.map +0 -1
- package/dist/mcp/shared-exec.js +0 -182
- package/dist/mcp/shared-exec.js.map +0 -1
- package/dist/team/__tests__/cli-path-resolution.test.d.ts +0 -2
- package/dist/team/__tests__/cli-path-resolution.test.d.ts.map +0 -1
- package/dist/team/__tests__/cli-path-resolution.test.js +0 -281
- package/dist/team/__tests__/cli-path-resolution.test.js.map +0 -1
- package/dist/team/__tests__/layout-stabilizer.test.d.ts +0 -2
- package/dist/team/__tests__/layout-stabilizer.test.d.ts.map +0 -1
- package/dist/team/__tests__/layout-stabilizer.test.js +0 -217
- package/dist/team/__tests__/layout-stabilizer.test.js.map +0 -1
- package/dist/team/__tests__/pane-readiness.test.d.ts +0 -2
- package/dist/team/__tests__/pane-readiness.test.d.ts.map +0 -1
- package/dist/team/__tests__/pane-readiness.test.js +0 -185
- package/dist/team/__tests__/pane-readiness.test.js.map +0 -1
- package/dist/team/__tests__/runtime-gemini-prompt.test.d.ts +0 -2
- package/dist/team/__tests__/runtime-gemini-prompt.test.d.ts.map +0 -1
- package/dist/team/__tests__/runtime-gemini-prompt.test.js +0 -153
- package/dist/team/__tests__/runtime-gemini-prompt.test.js.map +0 -1
- package/dist/team/__tests__/runtime-interop-spawn-regression.test.d.ts +0 -2
- package/dist/team/__tests__/runtime-interop-spawn-regression.test.d.ts.map +0 -1
- package/dist/team/__tests__/runtime-interop-spawn-regression.test.js +0 -139
- package/dist/team/__tests__/runtime-interop-spawn-regression.test.js.map +0 -1
- package/dist/team/__tests__/shell-path.test.d.ts +0 -2
- package/dist/team/__tests__/shell-path.test.d.ts.map +0 -1
- package/dist/team/__tests__/shell-path.test.js +0 -193
- package/dist/team/__tests__/shell-path.test.js.map +0 -1
- package/dist/team/__tests__/wait-for-shell-ready.test.d.ts +0 -2
- package/dist/team/__tests__/wait-for-shell-ready.test.d.ts.map +0 -1
- package/dist/team/__tests__/wait-for-shell-ready.test.js +0 -242
- package/dist/team/__tests__/wait-for-shell-ready.test.js.map +0 -1
- package/dist/team/shell-path.d.ts +0 -21
- package/dist/team/shell-path.d.ts.map +0 -1
- package/dist/team/shell-path.js +0 -73
- package/dist/team/shell-path.js.map +0 -1
- package/scripts/ask-codex.sh +0 -24
- package/scripts/ask-gemini.sh +0 -24
- package/scripts/build-gemini-server.mjs +0 -74
- package/scripts/test-codex-gemini-team.mjs +0 -78
- package/skills/skill-development/SKILL.md +0 -218
- package/skills/skill-development/references/description-patterns.md +0 -160
- package/skills/skill-development/references/format-guide.md +0 -203
- /package/dist/{hooks/swarm → features/delegation-categories}/__tests__/index.test.d.ts +0 -0
package/bridge/runtime-cli.cjs
CHANGED
|
@@ -50,9 +50,11 @@ var init_team_name = __esm({
|
|
|
50
50
|
// src/team/tmux-session.ts
|
|
51
51
|
var tmux_session_exports = {};
|
|
52
52
|
__export(tmux_session_exports, {
|
|
53
|
+
buildWorkerLaunchSpec: () => buildWorkerLaunchSpec,
|
|
53
54
|
buildWorkerStartCommand: () => buildWorkerStartCommand,
|
|
54
55
|
createSession: () => createSession,
|
|
55
56
|
createTeamSession: () => createTeamSession,
|
|
57
|
+
detectTeamMultiplexerContext: () => detectTeamMultiplexerContext,
|
|
56
58
|
getDefaultShell: () => getDefaultShell,
|
|
57
59
|
injectToLeaderPane: () => injectToLeaderPane,
|
|
58
60
|
isSessionAlive: () => isSessionAlive,
|
|
@@ -64,6 +66,9 @@ __export(tmux_session_exports, {
|
|
|
64
66
|
listActiveSessions: () => listActiveSessions,
|
|
65
67
|
paneHasActiveTask: () => paneHasActiveTask,
|
|
66
68
|
paneLooksReady: () => paneLooksReady,
|
|
69
|
+
resolveShellFromCandidates: () => resolveShellFromCandidates,
|
|
70
|
+
resolveSplitPaneWorkerPaneIds: () => resolveSplitPaneWorkerPaneIds,
|
|
71
|
+
resolveSupportedShellAffinity: () => resolveSupportedShellAffinity,
|
|
67
72
|
sanitizeName: () => sanitizeName,
|
|
68
73
|
sendToWorker: () => sendToWorker,
|
|
69
74
|
sessionName: () => sessionName,
|
|
@@ -73,12 +78,17 @@ __export(tmux_session_exports, {
|
|
|
73
78
|
validateTmux: () => validateTmux,
|
|
74
79
|
waitForPaneReady: () => waitForPaneReady
|
|
75
80
|
});
|
|
81
|
+
function detectTeamMultiplexerContext(env = process.env) {
|
|
82
|
+
if (env.TMUX) return "tmux";
|
|
83
|
+
if (env.CMUX_SURFACE_ID) return "cmux";
|
|
84
|
+
return "none";
|
|
85
|
+
}
|
|
76
86
|
function isUnixLikeOnWindows() {
|
|
77
87
|
return process.platform === "win32" && !!(process.env.MSYSTEM || process.env.MINGW_PREFIX);
|
|
78
88
|
}
|
|
79
89
|
async function tmuxAsync(args) {
|
|
80
90
|
if (args.some((a) => a.includes("#{"))) {
|
|
81
|
-
const escaped = args.map((a) =>
|
|
91
|
+
const escaped = args.map((a) => "'" + a.replace(/'/g, "'\\''") + "'").join(" ");
|
|
82
92
|
return promisifiedExec(`tmux ${escaped}`);
|
|
83
93
|
}
|
|
84
94
|
return promisifiedExecFile("tmux", args);
|
|
@@ -87,7 +97,42 @@ function getDefaultShell() {
|
|
|
87
97
|
if (process.platform === "win32" && !isUnixLikeOnWindows()) {
|
|
88
98
|
return process.env.COMSPEC || "cmd.exe";
|
|
89
99
|
}
|
|
90
|
-
|
|
100
|
+
const shell = process.env.SHELL || "/bin/bash";
|
|
101
|
+
const name = (0, import_path5.basename)(shell.replace(/\\/g, "/")).replace(/\.(exe|cmd|bat)$/i, "");
|
|
102
|
+
if (!SUPPORTED_POSIX_SHELLS.has(name)) {
|
|
103
|
+
return "/bin/sh";
|
|
104
|
+
}
|
|
105
|
+
return shell;
|
|
106
|
+
}
|
|
107
|
+
function resolveShellFromCandidates(paths, rcFile) {
|
|
108
|
+
for (const p of paths) {
|
|
109
|
+
if ((0, import_fs4.existsSync)(p)) return { shell: p, rcFile };
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
function resolveSupportedShellAffinity(shellPath) {
|
|
114
|
+
if (!shellPath) return null;
|
|
115
|
+
const name = (0, import_path5.basename)(shellPath.replace(/\\/g, "/")).replace(/\.(exe|cmd|bat)$/i, "");
|
|
116
|
+
if (name !== "zsh" && name !== "bash") return null;
|
|
117
|
+
if (!(0, import_fs4.existsSync)(shellPath)) return null;
|
|
118
|
+
const home = process.env.HOME ?? "";
|
|
119
|
+
const rcFile = home ? `${home}/.${name}rc` : null;
|
|
120
|
+
return { shell: shellPath, rcFile };
|
|
121
|
+
}
|
|
122
|
+
function buildWorkerLaunchSpec(shellPath) {
|
|
123
|
+
if (isUnixLikeOnWindows()) {
|
|
124
|
+
return { shell: "/bin/sh", rcFile: null };
|
|
125
|
+
}
|
|
126
|
+
const preferred = resolveSupportedShellAffinity(shellPath);
|
|
127
|
+
if (preferred) return preferred;
|
|
128
|
+
const home = process.env.HOME ?? "";
|
|
129
|
+
const zshRc = home ? `${home}/.zshrc` : null;
|
|
130
|
+
const zsh = resolveShellFromCandidates(ZSH_CANDIDATES, zshRc ?? "");
|
|
131
|
+
if (zsh) return { shell: zsh.shell, rcFile: zshRc };
|
|
132
|
+
const bashRc = home ? `${home}/.bashrc` : null;
|
|
133
|
+
const bash = resolveShellFromCandidates(BASH_CANDIDATES, bashRc ?? "");
|
|
134
|
+
if (bash) return { shell: bash.shell, rcFile: bashRc };
|
|
135
|
+
return { shell: "/bin/sh", rcFile: null };
|
|
91
136
|
}
|
|
92
137
|
function escapeForCmdSet(value) {
|
|
93
138
|
return value.replace(/"/g, '""');
|
|
@@ -127,12 +172,15 @@ function getLaunchWords(config) {
|
|
|
127
172
|
return [config.launchBinary, ...config.launchArgs ?? []];
|
|
128
173
|
}
|
|
129
174
|
if (config.launchCmd) {
|
|
130
|
-
|
|
175
|
+
throw new Error(
|
|
176
|
+
"launchCmd is deprecated and has been removed for security reasons. Use launchBinary + launchArgs instead."
|
|
177
|
+
);
|
|
131
178
|
}
|
|
132
179
|
throw new Error("Missing worker launch command. Provide launchBinary or launchCmd.");
|
|
133
180
|
}
|
|
134
181
|
function buildWorkerStartCommand(config) {
|
|
135
182
|
const shell = getDefaultShell();
|
|
183
|
+
const launchSpec = buildWorkerLaunchSpec(process.env.SHELL);
|
|
136
184
|
const launchWords = getLaunchWords(config);
|
|
137
185
|
const shouldSourceRc = process.env.OMC_TEAM_NO_RC !== "1";
|
|
138
186
|
if (process.platform === "win32" && !isUnixLikeOnWindows()) {
|
|
@@ -152,8 +200,8 @@ function buildWorkerStartCommand(config) {
|
|
|
152
200
|
const shellName2 = shellNameFromPath(shell) || "bash";
|
|
153
201
|
const isFish2 = shellName2 === "fish";
|
|
154
202
|
const execArgsCommand = isFish2 ? "exec $argv" : 'exec "$@"';
|
|
155
|
-
let rcFile2 = "";
|
|
156
|
-
if (process.env.HOME) {
|
|
203
|
+
let rcFile2 = (launchSpec.shell === shell ? launchSpec.rcFile : null) ?? "";
|
|
204
|
+
if (!rcFile2 && process.env.HOME) {
|
|
157
205
|
rcFile2 = isFish2 ? `${process.env.HOME}/.config/fish/config.fish` : `${process.env.HOME}/.${shellName2}rc`;
|
|
158
206
|
}
|
|
159
207
|
let script;
|
|
@@ -164,14 +212,10 @@ function buildWorkerStartCommand(config) {
|
|
|
164
212
|
}
|
|
165
213
|
const shellFlags = isFish2 ? ["-l", "-c"] : ["-lc"];
|
|
166
214
|
return [
|
|
167
|
-
"env",
|
|
215
|
+
shellEscape("env"),
|
|
168
216
|
...envAssignments,
|
|
169
|
-
shell,
|
|
170
|
-
|
|
171
|
-
script,
|
|
172
|
-
"--",
|
|
173
|
-
...launchWords
|
|
174
|
-
].map(shellEscape).join(" ");
|
|
217
|
+
...[shell, ...shellFlags, script, "--", ...launchWords].map(shellEscape)
|
|
218
|
+
].join(" ");
|
|
175
219
|
}
|
|
176
220
|
const envString = Object.entries(config.envVars).map(([k, v]) => {
|
|
177
221
|
assertSafeEnvKey(k);
|
|
@@ -179,8 +223,8 @@ function buildWorkerStartCommand(config) {
|
|
|
179
223
|
}).join(" ");
|
|
180
224
|
const shellName = shellNameFromPath(shell) || "bash";
|
|
181
225
|
const isFish = shellName === "fish";
|
|
182
|
-
let rcFile = "";
|
|
183
|
-
if (process.env.HOME) {
|
|
226
|
+
let rcFile = (launchSpec.shell === shell ? launchSpec.rcFile : null) ?? "";
|
|
227
|
+
if (!rcFile && process.env.HOME) {
|
|
184
228
|
rcFile = isFish ? `${process.env.HOME}/.config/fish/config.fish` : `${process.env.HOME}/.${shellName}rc`;
|
|
185
229
|
}
|
|
186
230
|
let sourceCmd = "";
|
|
@@ -243,9 +287,7 @@ function isSessionAlive(teamName, workerName2) {
|
|
|
243
287
|
function listActiveSessions(teamName) {
|
|
244
288
|
const prefix = `${TMUX_SESSION_PREFIX}-${sanitizeName(teamName)}-`;
|
|
245
289
|
try {
|
|
246
|
-
const
|
|
247
|
-
const shellCmd = "tmux " + fmtArgs.map((a) => `"${a.replace(/"/g, '\\"')}"`).join(" ");
|
|
248
|
-
const output = (0, import_child_process2.execSync)(shellCmd, {
|
|
290
|
+
const output = (0, import_child_process2.execSync)("tmux list-sessions -F '#{session_name}'", {
|
|
249
291
|
encoding: "utf-8",
|
|
250
292
|
timeout: 5e3,
|
|
251
293
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -260,10 +302,11 @@ function spawnBridgeInSession(tmuxSession, bridgeScriptPath, configFilePath) {
|
|
|
260
302
|
(0, import_child_process2.execFileSync)("tmux", ["send-keys", "-t", tmuxSession, cmd, "Enter"], { stdio: "pipe", timeout: 5e3 });
|
|
261
303
|
}
|
|
262
304
|
async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
263
|
-
const { execFile:
|
|
264
|
-
const { promisify:
|
|
265
|
-
const
|
|
266
|
-
const
|
|
305
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
306
|
+
const { promisify: promisify3 } = await import("util");
|
|
307
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
308
|
+
const multiplexerContext = detectTeamMultiplexerContext();
|
|
309
|
+
const inTmux = multiplexerContext === "tmux";
|
|
267
310
|
const useDedicatedWindow = Boolean(options.newWindow && inTmux);
|
|
268
311
|
const envPaneIdRaw = (process.env.TMUX_PANE ?? "").trim();
|
|
269
312
|
const envPaneId = /^%\d+$/.test(envPaneIdRaw) ? envPaneIdRaw : "";
|
|
@@ -272,7 +315,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
272
315
|
let sessionMode = inTmux ? "split-pane" : "detached-session";
|
|
273
316
|
if (!inTmux) {
|
|
274
317
|
const detachedSessionName = `${TMUX_SESSION_PREFIX}-${sanitizeName(teamName)}-${Date.now().toString(36)}`;
|
|
275
|
-
const detachedResult = await
|
|
318
|
+
const detachedResult = await execFileAsync2("tmux", [
|
|
276
319
|
"new-session",
|
|
277
320
|
"-d",
|
|
278
321
|
"-P",
|
|
@@ -293,7 +336,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
293
336
|
}
|
|
294
337
|
if (inTmux && envPaneId) {
|
|
295
338
|
try {
|
|
296
|
-
const targetedContextResult = await
|
|
339
|
+
const targetedContextResult = await execFileAsync2("tmux", [
|
|
297
340
|
"display-message",
|
|
298
341
|
"-p",
|
|
299
342
|
"-t",
|
|
@@ -323,7 +366,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
323
366
|
if (useDedicatedWindow) {
|
|
324
367
|
const targetSession = sessionAndWindow.split(":")[0] ?? sessionAndWindow;
|
|
325
368
|
const windowName = `omc-${sanitizeName(teamName)}`.slice(0, 32);
|
|
326
|
-
const newWindowResult = await
|
|
369
|
+
const newWindowResult = await execFileAsync2("tmux", [
|
|
327
370
|
"new-window",
|
|
328
371
|
"-d",
|
|
329
372
|
"-P",
|
|
@@ -350,12 +393,12 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
350
393
|
const workerPaneIds = [];
|
|
351
394
|
if (workerCount <= 0) {
|
|
352
395
|
try {
|
|
353
|
-
await
|
|
396
|
+
await execFileAsync2("tmux", ["set-option", "-t", resolvedSessionName, "mouse", "on"]);
|
|
354
397
|
} catch {
|
|
355
398
|
}
|
|
356
399
|
if (sessionMode !== "dedicated-window") {
|
|
357
400
|
try {
|
|
358
|
-
await
|
|
401
|
+
await execFileAsync2("tmux", ["select-pane", "-t", leaderPaneId]);
|
|
359
402
|
} catch {
|
|
360
403
|
}
|
|
361
404
|
}
|
|
@@ -383,7 +426,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
383
426
|
}
|
|
384
427
|
}
|
|
385
428
|
try {
|
|
386
|
-
await
|
|
429
|
+
await execFileAsync2("tmux", ["select-layout", "-t", teamTarget, "main-vertical"]);
|
|
387
430
|
} catch {
|
|
388
431
|
}
|
|
389
432
|
try {
|
|
@@ -397,18 +440,18 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
397
440
|
const width = parseInt(widthResult.stdout.trim(), 10);
|
|
398
441
|
if (Number.isFinite(width) && width >= 40) {
|
|
399
442
|
const half = String(Math.floor(width / 2));
|
|
400
|
-
await
|
|
401
|
-
await
|
|
443
|
+
await execFileAsync2("tmux", ["set-window-option", "-t", teamTarget, "main-pane-width", half]);
|
|
444
|
+
await execFileAsync2("tmux", ["select-layout", "-t", teamTarget, "main-vertical"]);
|
|
402
445
|
}
|
|
403
446
|
} catch {
|
|
404
447
|
}
|
|
405
448
|
try {
|
|
406
|
-
await
|
|
449
|
+
await execFileAsync2("tmux", ["set-option", "-t", resolvedSessionName, "mouse", "on"]);
|
|
407
450
|
} catch {
|
|
408
451
|
}
|
|
409
452
|
if (sessionMode !== "dedicated-window") {
|
|
410
453
|
try {
|
|
411
|
-
await
|
|
454
|
+
await execFileAsync2("tmux", ["select-pane", "-t", leaderPaneId]);
|
|
412
455
|
} catch {
|
|
413
456
|
}
|
|
414
457
|
}
|
|
@@ -416,26 +459,26 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
|
|
|
416
459
|
return { sessionName: teamTarget, leaderPaneId, workerPaneIds, sessionMode };
|
|
417
460
|
}
|
|
418
461
|
async function spawnWorkerInPane(sessionName2, paneId, config) {
|
|
419
|
-
const { execFile:
|
|
420
|
-
const { promisify:
|
|
421
|
-
const
|
|
462
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
463
|
+
const { promisify: promisify3 } = await import("util");
|
|
464
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
422
465
|
validateTeamName(config.teamName);
|
|
423
466
|
const startCmd = buildWorkerStartCommand(config);
|
|
424
|
-
await
|
|
467
|
+
await execFileAsync2("tmux", [
|
|
425
468
|
"send-keys",
|
|
426
469
|
"-t",
|
|
427
470
|
paneId,
|
|
428
471
|
"-l",
|
|
429
472
|
startCmd
|
|
430
473
|
]);
|
|
431
|
-
await
|
|
474
|
+
await execFileAsync2("tmux", ["send-keys", "-t", paneId, "Enter"]);
|
|
432
475
|
}
|
|
433
476
|
function normalizeTmuxCapture(value) {
|
|
434
477
|
return value.replace(/\r/g, "").replace(/\s+/g, " ").trim();
|
|
435
478
|
}
|
|
436
|
-
async function capturePaneAsync(paneId,
|
|
479
|
+
async function capturePaneAsync(paneId, execFileAsync2) {
|
|
437
480
|
try {
|
|
438
|
-
const result = await
|
|
481
|
+
const result = await execFileAsync2("tmux", ["capture-pane", "-t", paneId, "-p", "-S", "-80"]);
|
|
439
482
|
return result.stdout;
|
|
440
483
|
} catch {
|
|
441
484
|
return "";
|
|
@@ -448,23 +491,32 @@ function paneHasTrustPrompt(captured) {
|
|
|
448
491
|
const hasChoices = tail.some((l) => /Yes,\s*continue|No,\s*quit|Press enter to continue/i.test(l));
|
|
449
492
|
return hasQuestion && hasChoices;
|
|
450
493
|
}
|
|
494
|
+
function paneIsBootstrapping(captured) {
|
|
495
|
+
const lines = captured.split("\n").map((line) => line.replace(/\r/g, "").trim()).filter((line) => line.length > 0);
|
|
496
|
+
return lines.some(
|
|
497
|
+
(line) => /\b(loading|initializing|starting up)\b/i.test(line) || /\bmodel:\s*loading\b/i.test(line) || /\bconnecting\s+to\b/i.test(line)
|
|
498
|
+
);
|
|
499
|
+
}
|
|
451
500
|
function paneHasActiveTask(captured) {
|
|
452
501
|
const lines = captured.split("\n").map((l) => l.replace(/\r/g, "").trim()).filter((l) => l.length > 0);
|
|
453
502
|
const tail = lines.slice(-40);
|
|
503
|
+
if (tail.some((l) => /\b\d+\s+background terminal running\b/i.test(l))) return true;
|
|
454
504
|
if (tail.some((l) => /esc to interrupt/i.test(l))) return true;
|
|
455
505
|
if (tail.some((l) => /\bbackground terminal running\b/i.test(l))) return true;
|
|
506
|
+
if (tail.some((l) => /^[·✻]\s+[A-Za-z][A-Za-z0-9''-]*(?:\s+[A-Za-z][A-Za-z0-9''-]*){0,3}(?:…|\.{3})$/u.test(l))) return true;
|
|
456
507
|
return false;
|
|
457
508
|
}
|
|
458
509
|
function paneLooksReady(captured) {
|
|
459
|
-
const
|
|
510
|
+
const content = captured.trimEnd();
|
|
511
|
+
if (content === "") return false;
|
|
512
|
+
const lines = content.split("\n").map((line) => line.replace(/\r/g, "").trimEnd()).filter((line) => line.trim() !== "");
|
|
460
513
|
if (lines.length === 0) return false;
|
|
461
|
-
|
|
462
|
-
const
|
|
463
|
-
if (
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
return hasCodexHint;
|
|
514
|
+
if (paneIsBootstrapping(content)) return false;
|
|
515
|
+
const lastLine = lines[lines.length - 1];
|
|
516
|
+
if (/^\s*[›>❯]\s*/u.test(lastLine)) return true;
|
|
517
|
+
const hasCodexPromptLine = lines.some((line) => /^\s*›\s*/u.test(line));
|
|
518
|
+
const hasClaudePromptLine = lines.some((line) => /^\s*❯\s*/u.test(line));
|
|
519
|
+
return hasCodexPromptLine || hasClaudePromptLine;
|
|
468
520
|
}
|
|
469
521
|
async function waitForPaneReady(paneId, opts = {}) {
|
|
470
522
|
const envTimeout = Number.parseInt(process.env.OMC_SHELL_READY_TIMEOUT_MS ?? "", 10);
|
|
@@ -486,7 +538,7 @@ async function waitForPaneReady(paneId, opts = {}) {
|
|
|
486
538
|
function paneTailContainsLiteralLine(captured, text) {
|
|
487
539
|
return normalizeTmuxCapture(captured).includes(normalizeTmuxCapture(text));
|
|
488
540
|
}
|
|
489
|
-
async function paneInCopyMode(paneId
|
|
541
|
+
async function paneInCopyMode(paneId) {
|
|
490
542
|
try {
|
|
491
543
|
const result = await tmuxAsync(["display-message", "-t", paneId, "-p", "#{pane_in_mode}"]);
|
|
492
544
|
return result.stdout.trim() === "1";
|
|
@@ -507,21 +559,21 @@ function shouldAttemptAdaptiveRetry(args) {
|
|
|
507
559
|
}
|
|
508
560
|
async function sendToWorker(_sessionName, paneId, message) {
|
|
509
561
|
if (message.length > 200) {
|
|
510
|
-
console.warn(`[tmux-session] sendToWorker: message
|
|
511
|
-
|
|
562
|
+
console.warn(`[tmux-session] sendToWorker: message rejected (${message.length} chars exceeds 200 char limit)`);
|
|
563
|
+
return false;
|
|
512
564
|
}
|
|
513
565
|
try {
|
|
514
|
-
const { execFile:
|
|
515
|
-
const { promisify:
|
|
516
|
-
const
|
|
566
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
567
|
+
const { promisify: promisify3 } = await import("util");
|
|
568
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
517
569
|
const sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
518
570
|
const sendKey = async (key) => {
|
|
519
|
-
await
|
|
571
|
+
await execFileAsync2("tmux", ["send-keys", "-t", paneId, key]);
|
|
520
572
|
};
|
|
521
|
-
if (await paneInCopyMode(paneId
|
|
573
|
+
if (await paneInCopyMode(paneId)) {
|
|
522
574
|
return false;
|
|
523
575
|
}
|
|
524
|
-
const initialCapture = await capturePaneAsync(paneId,
|
|
576
|
+
const initialCapture = await capturePaneAsync(paneId, execFileAsync2);
|
|
525
577
|
const paneBusy = paneHasActiveTask(initialCapture);
|
|
526
578
|
if (paneHasTrustPrompt(initialCapture)) {
|
|
527
579
|
await sendKey("C-m");
|
|
@@ -529,7 +581,7 @@ async function sendToWorker(_sessionName, paneId, message) {
|
|
|
529
581
|
await sendKey("C-m");
|
|
530
582
|
await sleep2(200);
|
|
531
583
|
}
|
|
532
|
-
await
|
|
584
|
+
await execFileAsync2("tmux", ["send-keys", "-t", paneId, "-l", "--", message]);
|
|
533
585
|
await sleep2(150);
|
|
534
586
|
const submitRounds = 6;
|
|
535
587
|
for (let round = 0; round < submitRounds; round++) {
|
|
@@ -544,15 +596,15 @@ async function sendToWorker(_sessionName, paneId, message) {
|
|
|
544
596
|
await sendKey("C-m");
|
|
545
597
|
}
|
|
546
598
|
await sleep2(140);
|
|
547
|
-
const checkCapture = await capturePaneAsync(paneId,
|
|
599
|
+
const checkCapture = await capturePaneAsync(paneId, execFileAsync2);
|
|
548
600
|
if (!paneTailContainsLiteralLine(checkCapture, message)) return true;
|
|
549
601
|
await sleep2(140);
|
|
550
602
|
}
|
|
551
|
-
if (await paneInCopyMode(paneId
|
|
603
|
+
if (await paneInCopyMode(paneId)) {
|
|
552
604
|
return false;
|
|
553
605
|
}
|
|
554
|
-
const finalCapture = await capturePaneAsync(paneId,
|
|
555
|
-
const paneModeBeforeAdaptiveRetry = await paneInCopyMode(paneId
|
|
606
|
+
const finalCapture = await capturePaneAsync(paneId, execFileAsync2);
|
|
607
|
+
const paneModeBeforeAdaptiveRetry = await paneInCopyMode(paneId);
|
|
556
608
|
if (shouldAttemptAdaptiveRetry({
|
|
557
609
|
paneBusy,
|
|
558
610
|
latestCapture: finalCapture,
|
|
@@ -560,26 +612,26 @@ async function sendToWorker(_sessionName, paneId, message) {
|
|
|
560
612
|
paneInCopyMode: paneModeBeforeAdaptiveRetry,
|
|
561
613
|
retriesAttempted: 0
|
|
562
614
|
})) {
|
|
563
|
-
if (await paneInCopyMode(paneId
|
|
615
|
+
if (await paneInCopyMode(paneId)) {
|
|
564
616
|
return false;
|
|
565
617
|
}
|
|
566
618
|
await sendKey("C-u");
|
|
567
619
|
await sleep2(80);
|
|
568
|
-
if (await paneInCopyMode(paneId
|
|
620
|
+
if (await paneInCopyMode(paneId)) {
|
|
569
621
|
return false;
|
|
570
622
|
}
|
|
571
|
-
await
|
|
623
|
+
await execFileAsync2("tmux", ["send-keys", "-t", paneId, "-l", "--", message]);
|
|
572
624
|
await sleep2(120);
|
|
573
625
|
for (let round = 0; round < 4; round++) {
|
|
574
626
|
await sendKey("C-m");
|
|
575
627
|
await sleep2(180);
|
|
576
628
|
await sendKey("C-m");
|
|
577
629
|
await sleep2(140);
|
|
578
|
-
const retryCapture = await capturePaneAsync(paneId,
|
|
630
|
+
const retryCapture = await capturePaneAsync(paneId, execFileAsync2);
|
|
579
631
|
if (!paneTailContainsLiteralLine(retryCapture, message)) return true;
|
|
580
632
|
}
|
|
581
633
|
}
|
|
582
|
-
if (await paneInCopyMode(paneId
|
|
634
|
+
if (await paneInCopyMode(paneId)) {
|
|
583
635
|
return false;
|
|
584
636
|
}
|
|
585
637
|
await sendKey("C-m");
|
|
@@ -593,15 +645,15 @@ async function sendToWorker(_sessionName, paneId, message) {
|
|
|
593
645
|
async function injectToLeaderPane(sessionName2, leaderPaneId, message) {
|
|
594
646
|
const prefixed = `[OMC_TMUX_INJECT] ${message}`.slice(0, 200);
|
|
595
647
|
try {
|
|
596
|
-
const { execFile:
|
|
597
|
-
const { promisify:
|
|
598
|
-
const
|
|
599
|
-
if (await paneInCopyMode(leaderPaneId
|
|
648
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
649
|
+
const { promisify: promisify3 } = await import("util");
|
|
650
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
651
|
+
if (await paneInCopyMode(leaderPaneId)) {
|
|
600
652
|
return false;
|
|
601
653
|
}
|
|
602
|
-
const captured = await capturePaneAsync(leaderPaneId,
|
|
654
|
+
const captured = await capturePaneAsync(leaderPaneId, execFileAsync2);
|
|
603
655
|
if (paneHasActiveTask(captured)) {
|
|
604
|
-
await
|
|
656
|
+
await execFileAsync2("tmux", ["send-keys", "-t", leaderPaneId, "C-c"]);
|
|
605
657
|
await new Promise((r) => setTimeout(r, 250));
|
|
606
658
|
}
|
|
607
659
|
} catch {
|
|
@@ -610,9 +662,6 @@ async function injectToLeaderPane(sessionName2, leaderPaneId, message) {
|
|
|
610
662
|
}
|
|
611
663
|
async function isWorkerAlive(paneId) {
|
|
612
664
|
try {
|
|
613
|
-
const { execFile: execFile3 } = await import("child_process");
|
|
614
|
-
const { promisify: promisify2 } = await import("util");
|
|
615
|
-
const execFileAsync = promisify2(execFile3);
|
|
616
665
|
const result = await tmuxAsync([
|
|
617
666
|
"display-message",
|
|
618
667
|
"-t",
|
|
@@ -631,31 +680,60 @@ async function killWorkerPanes(opts) {
|
|
|
631
680
|
const shutdownPath = (0, import_path5.join)(cwd, ".omc", "state", "team", teamName, "shutdown.json");
|
|
632
681
|
try {
|
|
633
682
|
await import_promises.default.writeFile(shutdownPath, JSON.stringify({ requestedAt: Date.now() }));
|
|
634
|
-
await
|
|
683
|
+
const aliveChecks = await Promise.all(paneIds.map((id) => isWorkerAlive(id)));
|
|
684
|
+
if (aliveChecks.some((alive) => alive)) {
|
|
685
|
+
await sleep(graceMs);
|
|
686
|
+
}
|
|
635
687
|
} catch {
|
|
636
688
|
}
|
|
637
|
-
const { execFile:
|
|
638
|
-
const { promisify:
|
|
639
|
-
const
|
|
689
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
690
|
+
const { promisify: promisify3 } = await import("util");
|
|
691
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
640
692
|
for (const paneId of paneIds) {
|
|
641
693
|
if (paneId === leaderPaneId) continue;
|
|
642
694
|
try {
|
|
643
|
-
await
|
|
695
|
+
await execFileAsync2("tmux", ["kill-pane", "-t", paneId]);
|
|
644
696
|
} catch {
|
|
645
697
|
}
|
|
646
698
|
}
|
|
647
699
|
}
|
|
700
|
+
function isPaneId(value) {
|
|
701
|
+
return typeof value === "string" && /^%\d+$/.test(value.trim());
|
|
702
|
+
}
|
|
703
|
+
function dedupeWorkerPaneIds(paneIds, leaderPaneId) {
|
|
704
|
+
const unique = /* @__PURE__ */ new Set();
|
|
705
|
+
for (const paneId of paneIds) {
|
|
706
|
+
if (!isPaneId(paneId)) continue;
|
|
707
|
+
const normalized = paneId.trim();
|
|
708
|
+
if (normalized === leaderPaneId) continue;
|
|
709
|
+
unique.add(normalized);
|
|
710
|
+
}
|
|
711
|
+
return [...unique];
|
|
712
|
+
}
|
|
713
|
+
async function resolveSplitPaneWorkerPaneIds(sessionName2, recordedPaneIds, leaderPaneId) {
|
|
714
|
+
const resolved = dedupeWorkerPaneIds(recordedPaneIds ?? [], leaderPaneId);
|
|
715
|
+
if (!sessionName2.includes(":")) return resolved;
|
|
716
|
+
try {
|
|
717
|
+
const paneResult = await tmuxAsync(["list-panes", "-t", sessionName2, "-F", "#{pane_id}"]);
|
|
718
|
+
return dedupeWorkerPaneIds(
|
|
719
|
+
[...resolved, ...paneResult.stdout.split("\n").map((paneId) => paneId.trim())],
|
|
720
|
+
leaderPaneId
|
|
721
|
+
);
|
|
722
|
+
} catch {
|
|
723
|
+
return resolved;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
648
726
|
async function killTeamSession(sessionName2, workerPaneIds, leaderPaneId, options = {}) {
|
|
649
|
-
const { execFile:
|
|
650
|
-
const { promisify:
|
|
651
|
-
const
|
|
727
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
728
|
+
const { promisify: promisify3 } = await import("util");
|
|
729
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
652
730
|
const sessionMode = options.sessionMode ?? (sessionName2.includes(":") ? "split-pane" : "detached-session");
|
|
653
731
|
if (sessionMode === "split-pane") {
|
|
654
732
|
if (!workerPaneIds?.length) return;
|
|
655
733
|
for (const id of workerPaneIds) {
|
|
656
734
|
if (id === leaderPaneId) continue;
|
|
657
735
|
try {
|
|
658
|
-
await
|
|
736
|
+
await execFileAsync2("tmux", ["kill-pane", "-t", id]);
|
|
659
737
|
} catch {
|
|
660
738
|
}
|
|
661
739
|
}
|
|
@@ -663,7 +741,7 @@ async function killTeamSession(sessionName2, workerPaneIds, leaderPaneId, option
|
|
|
663
741
|
}
|
|
664
742
|
if (sessionMode === "dedicated-window") {
|
|
665
743
|
try {
|
|
666
|
-
await
|
|
744
|
+
await execFileAsync2("tmux", ["kill-window", "-t", sessionName2]);
|
|
667
745
|
} catch {
|
|
668
746
|
}
|
|
669
747
|
return;
|
|
@@ -680,15 +758,16 @@ async function killTeamSession(sessionName2, workerPaneIds, leaderPaneId, option
|
|
|
680
758
|
}
|
|
681
759
|
}
|
|
682
760
|
try {
|
|
683
|
-
await
|
|
761
|
+
await execFileAsync2("tmux", ["kill-session", "-t", sessionTarget]);
|
|
684
762
|
} catch {
|
|
685
763
|
}
|
|
686
764
|
}
|
|
687
|
-
var import_child_process2, import_path5, import_util, import_promises, sleep, TMUX_SESSION_PREFIX, promisifiedExec, promisifiedExecFile, DANGEROUS_LAUNCH_BINARY_CHARS;
|
|
765
|
+
var import_child_process2, import_fs4, import_path5, import_util, import_promises, sleep, TMUX_SESSION_PREFIX, promisifiedExec, promisifiedExecFile, SUPPORTED_POSIX_SHELLS, ZSH_CANDIDATES, BASH_CANDIDATES, DANGEROUS_LAUNCH_BINARY_CHARS;
|
|
688
766
|
var init_tmux_session = __esm({
|
|
689
767
|
"src/team/tmux-session.ts"() {
|
|
690
768
|
"use strict";
|
|
691
769
|
import_child_process2 = require("child_process");
|
|
770
|
+
import_fs4 = require("fs");
|
|
692
771
|
import_path5 = require("path");
|
|
693
772
|
import_util = require("util");
|
|
694
773
|
import_promises = __toESM(require("fs/promises"), 1);
|
|
@@ -697,10 +776,190 @@ var init_tmux_session = __esm({
|
|
|
697
776
|
TMUX_SESSION_PREFIX = "omc-team";
|
|
698
777
|
promisifiedExec = (0, import_util.promisify)(import_child_process2.exec);
|
|
699
778
|
promisifiedExecFile = (0, import_util.promisify)(import_child_process2.execFile);
|
|
779
|
+
SUPPORTED_POSIX_SHELLS = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "fish", "ksh"]);
|
|
780
|
+
ZSH_CANDIDATES = ["/bin/zsh", "/usr/bin/zsh", "/usr/local/bin/zsh", "/opt/homebrew/bin/zsh"];
|
|
781
|
+
BASH_CANDIDATES = ["/bin/bash", "/usr/bin/bash"];
|
|
700
782
|
DANGEROUS_LAUNCH_BINARY_CHARS = /[;&|`$()<>\n\r\t\0]/;
|
|
701
783
|
}
|
|
702
784
|
});
|
|
703
785
|
|
|
786
|
+
// src/lib/atomic-write.ts
|
|
787
|
+
function ensureDirSync(dir) {
|
|
788
|
+
if (fsSync.existsSync(dir)) {
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
try {
|
|
792
|
+
fsSync.mkdirSync(dir, { recursive: true });
|
|
793
|
+
} catch (err) {
|
|
794
|
+
if (err.code === "EEXIST") {
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
throw err;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
var fs2, fsSync, path, crypto;
|
|
801
|
+
var init_atomic_write = __esm({
|
|
802
|
+
"src/lib/atomic-write.ts"() {
|
|
803
|
+
"use strict";
|
|
804
|
+
fs2 = __toESM(require("fs/promises"), 1);
|
|
805
|
+
fsSync = __toESM(require("fs"), 1);
|
|
806
|
+
path = __toESM(require("path"), 1);
|
|
807
|
+
crypto = __toESM(require("crypto"), 1);
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
// src/platform/process-utils.ts
|
|
812
|
+
function isProcessAlive(pid) {
|
|
813
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
814
|
+
try {
|
|
815
|
+
process.kill(pid, 0);
|
|
816
|
+
return true;
|
|
817
|
+
} catch (e) {
|
|
818
|
+
if (e && typeof e === "object" && "code" in e && e.code === "EPERM") {
|
|
819
|
+
return true;
|
|
820
|
+
}
|
|
821
|
+
return false;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
var import_child_process4, import_util2, fsPromises, execFileAsync;
|
|
825
|
+
var init_process_utils = __esm({
|
|
826
|
+
"src/platform/process-utils.ts"() {
|
|
827
|
+
"use strict";
|
|
828
|
+
import_child_process4 = require("child_process");
|
|
829
|
+
import_util2 = require("util");
|
|
830
|
+
fsPromises = __toESM(require("fs/promises"), 1);
|
|
831
|
+
execFileAsync = (0, import_util2.promisify)(import_child_process4.execFile);
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
// src/platform/index.ts
|
|
836
|
+
var path2, import_fs7, PLATFORM;
|
|
837
|
+
var init_platform = __esm({
|
|
838
|
+
"src/platform/index.ts"() {
|
|
839
|
+
"use strict";
|
|
840
|
+
path2 = __toESM(require("path"), 1);
|
|
841
|
+
import_fs7 = require("fs");
|
|
842
|
+
init_process_utils();
|
|
843
|
+
PLATFORM = process.platform;
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
// src/lib/file-lock.ts
|
|
848
|
+
function isLockStale(lockPath, staleLockMs) {
|
|
849
|
+
try {
|
|
850
|
+
const stat2 = (0, import_fs8.statSync)(lockPath);
|
|
851
|
+
const ageMs = Date.now() - stat2.mtimeMs;
|
|
852
|
+
if (ageMs < staleLockMs) return false;
|
|
853
|
+
try {
|
|
854
|
+
const raw = (0, import_fs8.readFileSync)(lockPath, "utf-8");
|
|
855
|
+
const payload = JSON.parse(raw);
|
|
856
|
+
if (payload.pid && isProcessAlive(payload.pid)) return false;
|
|
857
|
+
} catch {
|
|
858
|
+
}
|
|
859
|
+
return true;
|
|
860
|
+
} catch {
|
|
861
|
+
return false;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
function tryAcquireSync(lockPath, staleLockMs) {
|
|
865
|
+
ensureDirSync(path3.dirname(lockPath));
|
|
866
|
+
try {
|
|
867
|
+
const fd = (0, import_fs8.openSync)(
|
|
868
|
+
lockPath,
|
|
869
|
+
import_fs8.constants.O_CREAT | import_fs8.constants.O_EXCL | import_fs8.constants.O_WRONLY,
|
|
870
|
+
384
|
|
871
|
+
);
|
|
872
|
+
const payload = JSON.stringify({
|
|
873
|
+
pid: process.pid,
|
|
874
|
+
timestamp: Date.now()
|
|
875
|
+
});
|
|
876
|
+
(0, import_fs8.writeSync)(fd, payload, null, "utf-8");
|
|
877
|
+
return { fd, path: lockPath };
|
|
878
|
+
} catch (err) {
|
|
879
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
880
|
+
if (isLockStale(lockPath, staleLockMs)) {
|
|
881
|
+
try {
|
|
882
|
+
(0, import_fs8.unlinkSync)(lockPath);
|
|
883
|
+
} catch {
|
|
884
|
+
}
|
|
885
|
+
try {
|
|
886
|
+
const fd = (0, import_fs8.openSync)(
|
|
887
|
+
lockPath,
|
|
888
|
+
import_fs8.constants.O_CREAT | import_fs8.constants.O_EXCL | import_fs8.constants.O_WRONLY,
|
|
889
|
+
384
|
|
890
|
+
);
|
|
891
|
+
const payload = JSON.stringify({
|
|
892
|
+
pid: process.pid,
|
|
893
|
+
timestamp: Date.now()
|
|
894
|
+
});
|
|
895
|
+
(0, import_fs8.writeSync)(fd, payload, null, "utf-8");
|
|
896
|
+
return { fd, path: lockPath };
|
|
897
|
+
} catch {
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
return null;
|
|
902
|
+
}
|
|
903
|
+
throw err;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
function acquireFileLockSync(lockPath, opts) {
|
|
907
|
+
const staleLockMs = opts?.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
908
|
+
const timeoutMs = opts?.timeoutMs ?? 0;
|
|
909
|
+
const retryDelayMs = opts?.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;
|
|
910
|
+
const handle = tryAcquireSync(lockPath, staleLockMs);
|
|
911
|
+
if (handle || timeoutMs <= 0) return handle;
|
|
912
|
+
const deadline = Date.now() + timeoutMs;
|
|
913
|
+
const sharedBuf = new SharedArrayBuffer(4);
|
|
914
|
+
const sharedArr = new Int32Array(sharedBuf);
|
|
915
|
+
while (Date.now() < deadline) {
|
|
916
|
+
const waitMs = Math.min(retryDelayMs, deadline - Date.now());
|
|
917
|
+
try {
|
|
918
|
+
Atomics.wait(sharedArr, 0, 0, waitMs);
|
|
919
|
+
} catch {
|
|
920
|
+
const waitUntil = Date.now() + waitMs;
|
|
921
|
+
while (Date.now() < waitUntil) {
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
const retryHandle = tryAcquireSync(lockPath, staleLockMs);
|
|
925
|
+
if (retryHandle) return retryHandle;
|
|
926
|
+
}
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
function releaseFileLockSync(handle) {
|
|
930
|
+
try {
|
|
931
|
+
(0, import_fs8.closeSync)(handle.fd);
|
|
932
|
+
} catch {
|
|
933
|
+
}
|
|
934
|
+
try {
|
|
935
|
+
(0, import_fs8.unlinkSync)(handle.path);
|
|
936
|
+
} catch {
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
function withFileLockSync(lockPath, fn, opts) {
|
|
940
|
+
const handle = acquireFileLockSync(lockPath, opts);
|
|
941
|
+
if (!handle) {
|
|
942
|
+
throw new Error(`Failed to acquire file lock: ${lockPath}`);
|
|
943
|
+
}
|
|
944
|
+
try {
|
|
945
|
+
return fn();
|
|
946
|
+
} finally {
|
|
947
|
+
releaseFileLockSync(handle);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
var import_fs8, path3, DEFAULT_STALE_LOCK_MS, DEFAULT_RETRY_DELAY_MS;
|
|
951
|
+
var init_file_lock = __esm({
|
|
952
|
+
"src/lib/file-lock.ts"() {
|
|
953
|
+
"use strict";
|
|
954
|
+
import_fs8 = require("fs");
|
|
955
|
+
path3 = __toESM(require("path"), 1);
|
|
956
|
+
init_atomic_write();
|
|
957
|
+
init_platform();
|
|
958
|
+
DEFAULT_STALE_LOCK_MS = 3e4;
|
|
959
|
+
DEFAULT_RETRY_DELAY_MS = 50;
|
|
960
|
+
}
|
|
961
|
+
});
|
|
962
|
+
|
|
704
963
|
// src/team/runtime-cli.ts
|
|
705
964
|
var runtime_cli_exports = {};
|
|
706
965
|
__export(runtime_cli_exports, {
|
|
@@ -709,14 +968,14 @@ __export(runtime_cli_exports, {
|
|
|
709
968
|
writeResultArtifact: () => writeResultArtifact
|
|
710
969
|
});
|
|
711
970
|
module.exports = __toCommonJS(runtime_cli_exports);
|
|
712
|
-
var
|
|
971
|
+
var import_fs17 = require("fs");
|
|
713
972
|
var import_promises8 = require("fs/promises");
|
|
714
973
|
var import_path17 = require("path");
|
|
715
974
|
|
|
716
975
|
// src/team/runtime.ts
|
|
717
976
|
var import_promises3 = require("fs/promises");
|
|
718
977
|
var import_path11 = require("path");
|
|
719
|
-
var
|
|
978
|
+
var import_fs10 = require("fs");
|
|
720
979
|
|
|
721
980
|
// src/team/model-contract.ts
|
|
722
981
|
var import_child_process = require("child_process");
|
|
@@ -825,9 +1084,14 @@ function stripJsoncComments(content) {
|
|
|
825
1084
|
result += content[i];
|
|
826
1085
|
i++;
|
|
827
1086
|
while (i < content.length && content[i] !== '"') {
|
|
828
|
-
if (content[i] === "\\"
|
|
1087
|
+
if (content[i] === "\\") {
|
|
829
1088
|
result += content[i];
|
|
830
1089
|
i++;
|
|
1090
|
+
if (i < content.length) {
|
|
1091
|
+
result += content[i];
|
|
1092
|
+
i++;
|
|
1093
|
+
}
|
|
1094
|
+
continue;
|
|
831
1095
|
}
|
|
832
1096
|
result += content[i];
|
|
833
1097
|
i++;
|
|
@@ -864,8 +1128,12 @@ var BLOCKED_HOST_PATTERNS = [
|
|
|
864
1128
|
// IPv6 loopback
|
|
865
1129
|
/^\[?fc00:/i,
|
|
866
1130
|
// IPv6 unique local
|
|
867
|
-
/^\[?fe80:/i
|
|
1131
|
+
/^\[?fe80:/i,
|
|
868
1132
|
// IPv6 link-local
|
|
1133
|
+
/^\[?::ffff:/i,
|
|
1134
|
+
// IPv6-mapped IPv4 (all private ranges accessible via this prefix)
|
|
1135
|
+
/^\[?0{0,4}:{0,2}ffff:/i
|
|
1136
|
+
// IPv6-mapped IPv4 expanded forms
|
|
869
1137
|
];
|
|
870
1138
|
var ALLOWED_SCHEMES = ["https:", "http:"];
|
|
871
1139
|
function validateUrlForSSRF(urlString) {
|
|
@@ -890,6 +1158,24 @@ function validateUrlForSSRF(urlString) {
|
|
|
890
1158
|
};
|
|
891
1159
|
}
|
|
892
1160
|
}
|
|
1161
|
+
if (/^0x[0-9a-f]+$/i.test(hostname)) {
|
|
1162
|
+
return {
|
|
1163
|
+
allowed: false,
|
|
1164
|
+
reason: `Hostname '${hostname}' looks like a hex-encoded IP address`
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
if (/^\d+$/.test(hostname) && hostname.length > 3) {
|
|
1168
|
+
return {
|
|
1169
|
+
allowed: false,
|
|
1170
|
+
reason: `Hostname '${hostname}' looks like a decimal-encoded IP address`
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
if (/^0\d+\./.test(hostname)) {
|
|
1174
|
+
return {
|
|
1175
|
+
allowed: false,
|
|
1176
|
+
reason: `Hostname '${hostname}' looks like an octal-encoded IP address`
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
893
1179
|
if (parsed.username || parsed.password) {
|
|
894
1180
|
return { allowed: false, reason: "URLs with embedded credentials are not allowed" };
|
|
895
1181
|
}
|
|
@@ -1005,6 +1291,21 @@ function isBedrock() {
|
|
|
1005
1291
|
if (modelId && /^((us|eu|ap|global)\.anthropic\.|anthropic\.claude)/i.test(modelId)) {
|
|
1006
1292
|
return true;
|
|
1007
1293
|
}
|
|
1294
|
+
if (modelId && /^arn:aws(-[^:]+)?:bedrock:/i.test(modelId) && /:(inference-profile|application-inference-profile)\//i.test(modelId) && modelId.toLowerCase().includes("claude")) {
|
|
1295
|
+
return true;
|
|
1296
|
+
}
|
|
1297
|
+
return false;
|
|
1298
|
+
}
|
|
1299
|
+
function isProviderSpecificModelId(modelId) {
|
|
1300
|
+
if (/^((us|eu|ap|global)\.anthropic\.|anthropic\.claude)/i.test(modelId)) {
|
|
1301
|
+
return true;
|
|
1302
|
+
}
|
|
1303
|
+
if (/^arn:aws(-[^:]+)?:bedrock:/i.test(modelId)) {
|
|
1304
|
+
return true;
|
|
1305
|
+
}
|
|
1306
|
+
if (modelId.toLowerCase().startsWith("vertex_ai/")) {
|
|
1307
|
+
return true;
|
|
1308
|
+
}
|
|
1008
1309
|
return false;
|
|
1009
1310
|
}
|
|
1010
1311
|
function isVertexAI() {
|
|
@@ -1065,6 +1366,7 @@ function buildDefaultConfig() {
|
|
|
1065
1366
|
writer: { model: defaultTierModels.LOW },
|
|
1066
1367
|
qaTester: { model: defaultTierModels.MEDIUM },
|
|
1067
1368
|
scientist: { model: defaultTierModels.MEDIUM },
|
|
1369
|
+
tracer: { model: defaultTierModels.MEDIUM },
|
|
1068
1370
|
gitMaster: { model: defaultTierModels.MEDIUM },
|
|
1069
1371
|
codeSimplifier: { model: defaultTierModels.HIGH },
|
|
1070
1372
|
critic: { model: defaultTierModels.HIGH },
|
|
@@ -1104,12 +1406,24 @@ function buildDefaultConfig() {
|
|
|
1104
1406
|
maxEscalations: 2,
|
|
1105
1407
|
tierModels: { ...defaultTierModels },
|
|
1106
1408
|
agentOverrides: {
|
|
1107
|
-
architect: {
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1409
|
+
architect: {
|
|
1410
|
+
tier: "HIGH",
|
|
1411
|
+
reason: "Advisory agent requires deep reasoning"
|
|
1412
|
+
},
|
|
1413
|
+
planner: {
|
|
1414
|
+
tier: "HIGH",
|
|
1415
|
+
reason: "Strategic planning requires deep reasoning"
|
|
1416
|
+
},
|
|
1417
|
+
critic: {
|
|
1418
|
+
tier: "HIGH",
|
|
1419
|
+
reason: "Critical review requires deep reasoning"
|
|
1420
|
+
},
|
|
1421
|
+
analyst: {
|
|
1422
|
+
tier: "HIGH",
|
|
1423
|
+
reason: "Pre-planning analysis requires deep reasoning"
|
|
1424
|
+
},
|
|
1111
1425
|
explore: { tier: "LOW", reason: "Exploration is search-focused" },
|
|
1112
|
-
|
|
1426
|
+
writer: { tier: "LOW", reason: "Documentation is straightforward" }
|
|
1113
1427
|
},
|
|
1114
1428
|
escalationKeywords: [
|
|
1115
1429
|
"critical",
|
|
@@ -1151,6 +1465,10 @@ function buildDefaultConfig() {
|
|
|
1151
1465
|
defaultProvider: "claude",
|
|
1152
1466
|
roles: {}
|
|
1153
1467
|
},
|
|
1468
|
+
planOutput: {
|
|
1469
|
+
directory: ".omc/plans",
|
|
1470
|
+
filenameTemplate: "{{name}}.md"
|
|
1471
|
+
},
|
|
1154
1472
|
startupCodebaseMap: {
|
|
1155
1473
|
enabled: true,
|
|
1156
1474
|
maxFiles: 200,
|
|
@@ -1172,16 +1490,16 @@ function getConfigPaths() {
|
|
|
1172
1490
|
project: (0, import_path3.join)(process.cwd(), ".claude", "omc.jsonc")
|
|
1173
1491
|
};
|
|
1174
1492
|
}
|
|
1175
|
-
function loadJsoncFile(
|
|
1176
|
-
if (!(0, import_fs3.existsSync)(
|
|
1493
|
+
function loadJsoncFile(path4) {
|
|
1494
|
+
if (!(0, import_fs3.existsSync)(path4)) {
|
|
1177
1495
|
return null;
|
|
1178
1496
|
}
|
|
1179
1497
|
try {
|
|
1180
|
-
const content = (0, import_fs3.readFileSync)(
|
|
1498
|
+
const content = (0, import_fs3.readFileSync)(path4, "utf-8");
|
|
1181
1499
|
const result = parseJsonc(content);
|
|
1182
1500
|
return result;
|
|
1183
1501
|
} catch (error) {
|
|
1184
|
-
console.error(`Error loading config from ${
|
|
1502
|
+
console.error(`Error loading config from ${path4}:`, error);
|
|
1185
1503
|
return null;
|
|
1186
1504
|
}
|
|
1187
1505
|
}
|
|
@@ -1189,6 +1507,8 @@ function deepMerge(target, source) {
|
|
|
1189
1507
|
const result = { ...target };
|
|
1190
1508
|
const mutableResult = result;
|
|
1191
1509
|
for (const key of Object.keys(source)) {
|
|
1510
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype")
|
|
1511
|
+
continue;
|
|
1192
1512
|
const sourceValue = source[key];
|
|
1193
1513
|
const targetValue = mutableResult[key];
|
|
1194
1514
|
if (sourceValue !== void 0 && typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
|
|
@@ -1685,6 +2005,39 @@ var exploreAgent = {
|
|
|
1685
2005
|
metadata: EXPLORE_PROMPT_METADATA
|
|
1686
2006
|
};
|
|
1687
2007
|
|
|
2008
|
+
// src/agents/tracer.ts
|
|
2009
|
+
var TRACER_PROMPT_METADATA = {
|
|
2010
|
+
category: "advisor",
|
|
2011
|
+
cost: "EXPENSIVE",
|
|
2012
|
+
promptAlias: "tracer",
|
|
2013
|
+
triggers: [
|
|
2014
|
+
{ domain: "Causal tracing", trigger: "Why did this happen? Which explanation best fits the evidence?" },
|
|
2015
|
+
{ domain: "Forensic analysis", trigger: "Observed output, artifact, or behavior needs ranked explanations" },
|
|
2016
|
+
{ domain: "Evidence-driven uncertainty reduction", trigger: "Need competing hypotheses and the next best probe" }
|
|
2017
|
+
],
|
|
2018
|
+
useWhen: [
|
|
2019
|
+
"Tracing ambiguous runtime behavior, regressions, or orchestration outcomes",
|
|
2020
|
+
"Ranking competing explanations for an observed result",
|
|
2021
|
+
"Separating observation, evidence, and inference",
|
|
2022
|
+
"Explaining performance, architecture, scientific, or configuration outcomes",
|
|
2023
|
+
"Identifying the next probe that would collapse uncertainty fastest"
|
|
2024
|
+
],
|
|
2025
|
+
avoidWhen: [
|
|
2026
|
+
"The task is pure implementation or fixing (use executor/debugger)",
|
|
2027
|
+
"The task is a generic summary without causal analysis",
|
|
2028
|
+
"A single-file code search is enough (use explore)",
|
|
2029
|
+
"You already have decisive evidence and only need execution"
|
|
2030
|
+
]
|
|
2031
|
+
};
|
|
2032
|
+
var tracerAgent = {
|
|
2033
|
+
name: "tracer",
|
|
2034
|
+
description: "Evidence-driven causal tracing specialist. Explains observed outcomes using competing hypotheses, evidence for and against, uncertainty tracking, and next-probe recommendations.",
|
|
2035
|
+
prompt: loadAgentPrompt("tracer"),
|
|
2036
|
+
model: "sonnet",
|
|
2037
|
+
defaultModel: "sonnet",
|
|
2038
|
+
metadata: TRACER_PROMPT_METADATA
|
|
2039
|
+
};
|
|
2040
|
+
|
|
1688
2041
|
// src/agents/document-specialist.ts
|
|
1689
2042
|
var DOCUMENT_SPECIALIST_PROMPT_METADATA = {
|
|
1690
2043
|
category: "exploration",
|
|
@@ -1873,7 +2226,10 @@ var CONTRACTS = {
|
|
|
1873
2226
|
installInstructions: "Install Claude CLI: https://claude.ai/download",
|
|
1874
2227
|
buildLaunchArgs(model, extraFlags = []) {
|
|
1875
2228
|
const args = ["--dangerously-skip-permissions"];
|
|
1876
|
-
if (model)
|
|
2229
|
+
if (model) {
|
|
2230
|
+
const resolved = isProviderSpecificModelId(model) ? model : normalizeToCcAlias(model);
|
|
2231
|
+
args.push("--model", resolved);
|
|
2232
|
+
}
|
|
1877
2233
|
return [...args, ...extraFlags];
|
|
1878
2234
|
},
|
|
1879
2235
|
parseOutput(rawOutput) {
|
|
@@ -2008,6 +2364,24 @@ function isPromptModeAgent(agentType) {
|
|
|
2008
2364
|
const contract = getContract(agentType);
|
|
2009
2365
|
return !!contract.supportsPromptMode;
|
|
2010
2366
|
}
|
|
2367
|
+
function resolveClaudeWorkerModel(env = process.env) {
|
|
2368
|
+
if (!isBedrock() && !isVertexAI()) {
|
|
2369
|
+
return void 0;
|
|
2370
|
+
}
|
|
2371
|
+
const directModel = env.ANTHROPIC_MODEL || env.CLAUDE_MODEL || "";
|
|
2372
|
+
if (directModel) {
|
|
2373
|
+
return directModel;
|
|
2374
|
+
}
|
|
2375
|
+
const bedrockModel = env.CLAUDE_CODE_BEDROCK_SONNET_MODEL || env.ANTHROPIC_DEFAULT_SONNET_MODEL || "";
|
|
2376
|
+
if (bedrockModel) {
|
|
2377
|
+
return bedrockModel;
|
|
2378
|
+
}
|
|
2379
|
+
const omcModel = env.OMC_MODEL_MEDIUM || "";
|
|
2380
|
+
if (omcModel) {
|
|
2381
|
+
return omcModel;
|
|
2382
|
+
}
|
|
2383
|
+
return void 0;
|
|
2384
|
+
}
|
|
2011
2385
|
function getPromptModeArgs(agentType, instruction) {
|
|
2012
2386
|
const contract = getContract(agentType);
|
|
2013
2387
|
if (!contract.supportsPromptMode) {
|
|
@@ -2028,7 +2402,7 @@ var import_promises2 = require("fs/promises");
|
|
|
2028
2402
|
var import_path7 = require("path");
|
|
2029
2403
|
|
|
2030
2404
|
// src/agents/prompt-helpers.ts
|
|
2031
|
-
var
|
|
2405
|
+
var import_fs5 = require("fs");
|
|
2032
2406
|
var import_path6 = require("path");
|
|
2033
2407
|
var import_url2 = require("url");
|
|
2034
2408
|
var import_meta2 = {};
|
|
@@ -2063,7 +2437,7 @@ function getValidAgentRoles() {
|
|
|
2063
2437
|
}
|
|
2064
2438
|
try {
|
|
2065
2439
|
const agentsDir = (0, import_path6.join)(getPackageDir2(), "agents");
|
|
2066
|
-
const files = (0,
|
|
2440
|
+
const files = (0, import_fs5.readdirSync)(agentsDir);
|
|
2067
2441
|
_cachedRoles = files.filter((f) => f.endsWith(".md")).map((f) => (0, import_path6.basename)(f, ".md")).sort();
|
|
2068
2442
|
} catch (err) {
|
|
2069
2443
|
console.error("[prompt-injection] CRITICAL: Could not scan agents/ directory for role discovery:", err);
|
|
@@ -2089,6 +2463,35 @@ function sanitizePromptContent(content, maxLength = 4e3) {
|
|
|
2089
2463
|
return sanitized;
|
|
2090
2464
|
}
|
|
2091
2465
|
|
|
2466
|
+
// src/utils/omc-cli-rendering.ts
|
|
2467
|
+
var import_child_process3 = require("child_process");
|
|
2468
|
+
var OMC_CLI_BINARY = "omc";
|
|
2469
|
+
var OMC_PLUGIN_BRIDGE_PREFIX = 'node "$CLAUDE_PLUGIN_ROOT"/bridge/cli.cjs';
|
|
2470
|
+
function commandExists(command, env) {
|
|
2471
|
+
const lookupCommand = process.platform === "win32" ? "where" : "which";
|
|
2472
|
+
const result = (0, import_child_process3.spawnSync)(lookupCommand, [command], {
|
|
2473
|
+
stdio: "ignore",
|
|
2474
|
+
env
|
|
2475
|
+
});
|
|
2476
|
+
return result.status === 0;
|
|
2477
|
+
}
|
|
2478
|
+
function resolveOmcCliPrefix(options = {}) {
|
|
2479
|
+
const env = options.env ?? process.env;
|
|
2480
|
+
const omcAvailable = options.omcAvailable ?? commandExists(OMC_CLI_BINARY, env);
|
|
2481
|
+
if (omcAvailable) {
|
|
2482
|
+
return OMC_CLI_BINARY;
|
|
2483
|
+
}
|
|
2484
|
+
const pluginRoot = typeof env.CLAUDE_PLUGIN_ROOT === "string" ? env.CLAUDE_PLUGIN_ROOT.trim() : "";
|
|
2485
|
+
if (pluginRoot) {
|
|
2486
|
+
return OMC_PLUGIN_BRIDGE_PREFIX;
|
|
2487
|
+
}
|
|
2488
|
+
return OMC_CLI_BINARY;
|
|
2489
|
+
}
|
|
2490
|
+
function formatOmcCliInvocation(commandSuffix, options = {}) {
|
|
2491
|
+
const suffix = commandSuffix.trim().replace(/^omc\s+/, "");
|
|
2492
|
+
return `${resolveOmcCliPrefix(options)} ${suffix}`.trim();
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2092
2495
|
// src/team/worker-bootstrap.ts
|
|
2093
2496
|
function buildInstructionPath(...parts) {
|
|
2094
2497
|
return (0, import_path7.join)(...parts).replaceAll("\\", "/");
|
|
@@ -2098,23 +2501,26 @@ function generateTriggerMessage(teamName, workerName2, teamStateRoot2 = ".omc/st
|
|
|
2098
2501
|
if (teamStateRoot2 !== ".omc/state") {
|
|
2099
2502
|
return `Read ${inboxPath}, work now, report progress.`;
|
|
2100
2503
|
}
|
|
2101
|
-
return `Read ${inboxPath}, start work now,
|
|
2504
|
+
return `Read ${inboxPath}, start work now, report concrete progress (not ACK-only), and keep executing your assigned or next feasible work.`;
|
|
2102
2505
|
}
|
|
2103
2506
|
function agentTypeGuidance(agentType) {
|
|
2507
|
+
const teamApiCommand = formatOmcCliInvocation("team api");
|
|
2508
|
+
const claimTaskCommand = formatOmcCliInvocation("team api claim-task");
|
|
2509
|
+
const transitionTaskStatusCommand = formatOmcCliInvocation("team api transition-task-status");
|
|
2104
2510
|
switch (agentType) {
|
|
2105
2511
|
case "codex":
|
|
2106
2512
|
return [
|
|
2107
2513
|
"### Agent-Type Guidance (codex)",
|
|
2108
|
-
|
|
2514
|
+
`- Prefer short, explicit \`${teamApiCommand} ... --json\` commands and parse outputs before next step.`,
|
|
2109
2515
|
"- If a command fails, report the exact stderr to leader-fixed before retrying.",
|
|
2110
|
-
|
|
2516
|
+
`- You MUST run \`${claimTaskCommand}\` before starting work and \`${transitionTaskStatusCommand}\` when done.`
|
|
2111
2517
|
].join("\n");
|
|
2112
2518
|
case "gemini":
|
|
2113
2519
|
return [
|
|
2114
2520
|
"### Agent-Type Guidance (gemini)",
|
|
2115
2521
|
"- Execute task work in small, verifiable increments and report each milestone to leader-fixed.",
|
|
2116
2522
|
"- Keep commit-sized changes scoped to assigned files only; no broad refactors.",
|
|
2117
|
-
|
|
2523
|
+
`- CRITICAL: You MUST run \`${claimTaskCommand}\` before starting work and \`${transitionTaskStatusCommand}\` when done. Do not exit without transitioning the task status.`
|
|
2118
2524
|
].join("\n");
|
|
2119
2525
|
case "claude":
|
|
2120
2526
|
default:
|
|
@@ -2136,7 +2542,16 @@ function generateWorkerOverlay(params) {
|
|
|
2136
2542
|
const heartbeatPath = `.omc/state/team/${teamName}/workers/${workerName2}/heartbeat.json`;
|
|
2137
2543
|
const inboxPath = `.omc/state/team/${teamName}/workers/${workerName2}/inbox.md`;
|
|
2138
2544
|
const statusPath = `.omc/state/team/${teamName}/workers/${workerName2}/status.json`;
|
|
2139
|
-
const
|
|
2545
|
+
const claimTaskCommand = formatOmcCliInvocation(`team api claim-task --input "{\\"team_name\\":\\"${teamName}\\",\\"task_id\\":\\"<id>\\",\\"worker\\":\\"${workerName2}\\"}" --json`);
|
|
2546
|
+
const sendAckCommand = formatOmcCliInvocation(`team api send-message --input "{\\"team_name\\":\\"${teamName}\\",\\"from_worker\\":\\"${workerName2}\\",\\"to_worker\\":\\"leader-fixed\\",\\"body\\":\\"ACK: ${workerName2} initialized\\"}" --json`);
|
|
2547
|
+
const completeTaskCommand = formatOmcCliInvocation(`team api transition-task-status --input "{\\"team_name\\":\\"${teamName}\\",\\"task_id\\":\\"<id>\\",\\"from\\":\\"in_progress\\",\\"to\\":\\"completed\\",\\"claim_token\\":\\"<claim_token>\\"}" --json`);
|
|
2548
|
+
const failTaskCommand = formatOmcCliInvocation(`team api transition-task-status --input "{\\"team_name\\":\\"${teamName}\\",\\"task_id\\":\\"<id>\\",\\"from\\":\\"in_progress\\",\\"to\\":\\"failed\\",\\"claim_token\\":\\"<claim_token>\\"}" --json`);
|
|
2549
|
+
const readTaskCommand = formatOmcCliInvocation(`team api read-task --input "{\\"team_name\\":\\"${teamName}\\",\\"task_id\\":\\"<id>\\"}" --json`);
|
|
2550
|
+
const releaseClaimCommand = formatOmcCliInvocation(`team api release-task-claim --input "{\\"team_name\\":\\"${teamName}\\",\\"task_id\\":\\"<id>\\",\\"claim_token\\":\\"<claim_token>\\",\\"worker\\":\\"${workerName2}\\"}" --json`);
|
|
2551
|
+
const mailboxListCommand = formatOmcCliInvocation(`team api mailbox-list --input "{\\"team_name\\":\\"${teamName}\\",\\"worker\\":\\"${workerName2}\\"}" --json`);
|
|
2552
|
+
const mailboxDeliveredCommand = formatOmcCliInvocation(`team api mailbox-mark-delivered --input "{\\"team_name\\":\\"${teamName}\\",\\"worker\\":\\"${workerName2}\\",\\"message_id\\":\\"<id>\\"}" --json`);
|
|
2553
|
+
const teamApiCommand = formatOmcCliInvocation("team api");
|
|
2554
|
+
const teamCommand = formatOmcCliInvocation("team");
|
|
2140
2555
|
const taskList = sanitizedTasks.length > 0 ? sanitizedTasks.map((t) => `- **Task ${t.id}**: ${t.subject}
|
|
2141
2556
|
Description: ${t.description}
|
|
2142
2557
|
Status: pending`).join("\n") : "- No tasks assigned yet. Check your inbox for assignments.";
|
|
@@ -2154,15 +2569,15 @@ mkdir -p $(dirname ${sentinelPath}) && touch ${sentinelPath}
|
|
|
2154
2569
|
You MUST complete ALL of these steps. Do NOT skip any step. Do NOT exit without step 4.
|
|
2155
2570
|
|
|
2156
2571
|
1. **Claim** your task (run this command first):
|
|
2157
|
-
|
|
2572
|
+
\`${claimTaskCommand}\`
|
|
2158
2573
|
Save the \`claim_token\` from the response \u2014 you need it for step 4.
|
|
2159
2574
|
2. **Do the work** described in your task assignment below.
|
|
2160
2575
|
3. **Send ACK** to the leader:
|
|
2161
|
-
|
|
2576
|
+
\`${sendAckCommand}\`
|
|
2162
2577
|
4. **Transition** the task status (REQUIRED before exit):
|
|
2163
|
-
- On success:
|
|
2164
|
-
- On failure:
|
|
2165
|
-
5. **
|
|
2578
|
+
- On success: \`${completeTaskCommand}\`
|
|
2579
|
+
- On failure: \`${failTaskCommand}\`
|
|
2580
|
+
5. **Keep going after replies**: ACK/progress messages are not a stop signal. Keep executing your assigned or next feasible work until the task is actually complete or failed, then transition and exit.
|
|
2166
2581
|
|
|
2167
2582
|
## Identity
|
|
2168
2583
|
- **Team**: ${teamName}
|
|
@@ -2176,12 +2591,12 @@ ${taskList}
|
|
|
2176
2591
|
## Task Lifecycle Reference (CLI API)
|
|
2177
2592
|
Use the CLI API for all task lifecycle operations. Do NOT directly edit task files.
|
|
2178
2593
|
|
|
2179
|
-
- Inspect task state:
|
|
2594
|
+
- Inspect task state: \`${readTaskCommand}\`
|
|
2180
2595
|
- Task id format: State/CLI APIs use task_id: "<id>" (example: "1"), not "task-1"
|
|
2181
|
-
- Claim task:
|
|
2182
|
-
- Complete task:
|
|
2183
|
-
- Fail task:
|
|
2184
|
-
- Release claim (rollback):
|
|
2596
|
+
- Claim task: \`${claimTaskCommand}\`
|
|
2597
|
+
- Complete task: \`${completeTaskCommand}\`
|
|
2598
|
+
- Fail task: \`${failTaskCommand}\`
|
|
2599
|
+
- Release claim (rollback): \`${releaseClaimCommand}\`
|
|
2185
2600
|
|
|
2186
2601
|
## Communication Protocol
|
|
2187
2602
|
- **Inbox**: Read ${inboxPath} for new instructions
|
|
@@ -2197,13 +2612,13 @@ Use the CLI API for all task lifecycle operations. Do NOT directly edit task fil
|
|
|
2197
2612
|
|
|
2198
2613
|
## Message Protocol
|
|
2199
2614
|
Send messages via CLI API:
|
|
2200
|
-
- To leader:
|
|
2201
|
-
- Check mailbox:
|
|
2202
|
-
- Mark delivered:
|
|
2615
|
+
- To leader: \`${formatOmcCliInvocation(`team api send-message --input "{\\"team_name\\":\\"${teamName}\\",\\"from_worker\\":\\"${workerName2}\\",\\"to_worker\\":\\"leader-fixed\\",\\"body\\":\\"<message>\\"}" --json`)}\`
|
|
2616
|
+
- Check mailbox: \`${mailboxListCommand}\`
|
|
2617
|
+
- Mark delivered: \`${mailboxDeliveredCommand}\`
|
|
2203
2618
|
|
|
2204
2619
|
## Startup Handshake (Required)
|
|
2205
2620
|
Before doing any task work, send exactly one startup ACK to the leader:
|
|
2206
|
-
|
|
2621
|
+
\`${sendAckCommand}\`
|
|
2207
2622
|
|
|
2208
2623
|
## Shutdown Protocol
|
|
2209
2624
|
When you see a shutdown request in your inbox:
|
|
@@ -2219,14 +2634,14 @@ When you see a shutdown request in your inbox:
|
|
|
2219
2634
|
- Do NOT write lifecycle fields (status, owner, result, error) directly in task files; use CLI API
|
|
2220
2635
|
- Do NOT spawn sub-agents. Complete work in this worker session only.
|
|
2221
2636
|
- Do NOT create tmux panes/sessions (\`tmux split-window\`, \`tmux new-session\`, etc.).
|
|
2222
|
-
- Do NOT run team spawning/orchestration commands (for example:
|
|
2223
|
-
- Worker-allowed control surface is only:
|
|
2637
|
+
- Do NOT run team spawning/orchestration commands (for example: \`${teamCommand} ...\`, \`omx team ...\`, \`$team\`, \`$ultrawork\`, \`$autopilot\`, \`$ralph\`).
|
|
2638
|
+
- Worker-allowed control surface is only: \`${teamApiCommand} ... --json\` (and equivalent \`omx team api ... --json\` where configured).
|
|
2224
2639
|
- If blocked, write {"state": "blocked", "reason": "..."} to your status file
|
|
2225
2640
|
|
|
2226
2641
|
${agentTypeGuidance(agentType)}
|
|
2227
2642
|
|
|
2228
2643
|
## BEFORE YOU EXIT
|
|
2229
|
-
You MUST call
|
|
2644
|
+
You MUST call \`${formatOmcCliInvocation("team api transition-task-status")}\` to mark your task as "completed" or "failed" before exiting.
|
|
2230
2645
|
If you skip this step, the leader cannot track your work and the task will appear stuck.
|
|
2231
2646
|
|
|
2232
2647
|
${bootstrapInstructions ? `## Role Context
|
|
@@ -2261,17 +2676,17 @@ var import_node_path = require("node:path");
|
|
|
2261
2676
|
var import_node_child_process = require("node:child_process");
|
|
2262
2677
|
|
|
2263
2678
|
// src/team/fs-utils.ts
|
|
2264
|
-
var
|
|
2679
|
+
var import_fs6 = require("fs");
|
|
2265
2680
|
var import_path8 = require("path");
|
|
2266
2681
|
function atomicWriteJson(filePath, data, mode = 384) {
|
|
2267
2682
|
const dir = (0, import_path8.dirname)(filePath);
|
|
2268
|
-
if (!(0,
|
|
2683
|
+
if (!(0, import_fs6.existsSync)(dir)) (0, import_fs6.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
2269
2684
|
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
2270
|
-
(0,
|
|
2271
|
-
(0,
|
|
2685
|
+
(0, import_fs6.writeFileSync)(tmpPath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode });
|
|
2686
|
+
(0, import_fs6.renameSync)(tmpPath, filePath);
|
|
2272
2687
|
}
|
|
2273
2688
|
function ensureDirWithMode(dirPath, mode = 448) {
|
|
2274
|
-
if (!(0,
|
|
2689
|
+
if (!(0, import_fs6.existsSync)(dirPath)) (0, import_fs6.mkdirSync)(dirPath, { recursive: true, mode });
|
|
2275
2690
|
}
|
|
2276
2691
|
function canonicalizePath(p) {
|
|
2277
2692
|
const absInput = (0, import_path8.resolve)(p);
|
|
@@ -2279,7 +2694,7 @@ function canonicalizePath(p) {
|
|
|
2279
2694
|
let probe = absInput;
|
|
2280
2695
|
while (true) {
|
|
2281
2696
|
try {
|
|
2282
|
-
const realBase = (0,
|
|
2697
|
+
const realBase = (0, import_fs6.realpathSync)(probe);
|
|
2283
2698
|
return tail.reduce((acc, seg) => (0, import_path8.resolve)(acc, seg), realBase);
|
|
2284
2699
|
} catch {
|
|
2285
2700
|
const parent = (0, import_path8.dirname)(probe);
|
|
@@ -2300,6 +2715,7 @@ function validateResolvedPath(resolvedPath, expectedBase) {
|
|
|
2300
2715
|
|
|
2301
2716
|
// src/team/git-worktree.ts
|
|
2302
2717
|
init_tmux_session();
|
|
2718
|
+
init_file_lock();
|
|
2303
2719
|
function getWorktreePath(repoRoot, teamName, workerName2) {
|
|
2304
2720
|
return (0, import_node_path.join)(repoRoot, ".omc", "worktrees", sanitizeName(teamName), sanitizeName(workerName2));
|
|
2305
2721
|
}
|
|
@@ -2314,7 +2730,10 @@ function readMetadata(repoRoot, teamName) {
|
|
|
2314
2730
|
if (!(0, import_node_fs.existsSync)(metaPath)) return [];
|
|
2315
2731
|
try {
|
|
2316
2732
|
return JSON.parse((0, import_node_fs.readFileSync)(metaPath, "utf-8"));
|
|
2317
|
-
} catch {
|
|
2733
|
+
} catch (err) {
|
|
2734
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2735
|
+
process.stderr.write(`[omc] warning: worktrees.json parse error: ${msg}
|
|
2736
|
+
`);
|
|
2318
2737
|
return [];
|
|
2319
2738
|
}
|
|
2320
2739
|
}
|
|
@@ -2340,9 +2759,12 @@ function removeWorkerWorktree(teamName, workerName2, repoRoot) {
|
|
|
2340
2759
|
(0, import_node_child_process.execFileSync)("git", ["branch", "-D", branch], { cwd: repoRoot, stdio: "pipe" });
|
|
2341
2760
|
} catch {
|
|
2342
2761
|
}
|
|
2343
|
-
const
|
|
2344
|
-
|
|
2345
|
-
|
|
2762
|
+
const metaLockPath = getMetadataPath(repoRoot, teamName) + ".lock";
|
|
2763
|
+
withFileLockSync(metaLockPath, () => {
|
|
2764
|
+
const existing = readMetadata(repoRoot, teamName);
|
|
2765
|
+
const updated = existing.filter((e) => e.workerName !== workerName2);
|
|
2766
|
+
writeMetadata(repoRoot, teamName, updated);
|
|
2767
|
+
});
|
|
2346
2768
|
}
|
|
2347
2769
|
function cleanupTeamWorktrees(teamName, repoRoot) {
|
|
2348
2770
|
const entries = readMetadata(repoRoot, teamName);
|
|
@@ -2355,9 +2777,10 @@ function cleanupTeamWorktrees(teamName, repoRoot) {
|
|
|
2355
2777
|
}
|
|
2356
2778
|
|
|
2357
2779
|
// src/team/task-file-ops.ts
|
|
2358
|
-
var
|
|
2780
|
+
var import_fs9 = require("fs");
|
|
2359
2781
|
var import_path10 = require("path");
|
|
2360
2782
|
init_tmux_session();
|
|
2783
|
+
init_platform();
|
|
2361
2784
|
|
|
2362
2785
|
// src/team/state-paths.ts
|
|
2363
2786
|
var import_path9 = require("path");
|
|
@@ -2400,7 +2823,7 @@ var TeamPaths = {
|
|
|
2400
2823
|
shutdownRequest: (teamName, workerName2) => `.omc/state/team/${teamName}/workers/${workerName2}/shutdown-request.json`
|
|
2401
2824
|
};
|
|
2402
2825
|
function absPath(cwd, relativePath) {
|
|
2403
|
-
return (0, import_path9.join)(cwd, relativePath);
|
|
2826
|
+
return (0, import_path9.isAbsolute)(relativePath) ? relativePath : (0, import_path9.join)(cwd, relativePath);
|
|
2404
2827
|
}
|
|
2405
2828
|
function teamStateRoot(cwd, teamName) {
|
|
2406
2829
|
return (0, import_path9.join)(cwd, TeamPaths.root(teamName));
|
|
@@ -2413,37 +2836,27 @@ function getTaskStoragePath(cwd, teamName, taskId) {
|
|
|
2413
2836
|
}
|
|
2414
2837
|
|
|
2415
2838
|
// src/team/task-file-ops.ts
|
|
2416
|
-
var
|
|
2417
|
-
function isPidAlive(pid) {
|
|
2418
|
-
if (pid <= 0 || !Number.isFinite(pid)) return false;
|
|
2419
|
-
try {
|
|
2420
|
-
process.kill(pid, 0);
|
|
2421
|
-
return true;
|
|
2422
|
-
} catch (e) {
|
|
2423
|
-
if (e && typeof e === "object" && "code" in e && e.code === "EPERM") return true;
|
|
2424
|
-
return false;
|
|
2425
|
-
}
|
|
2426
|
-
}
|
|
2839
|
+
var DEFAULT_STALE_LOCK_MS2 = 3e4;
|
|
2427
2840
|
function acquireTaskLock(teamName, taskId, opts) {
|
|
2428
|
-
const staleLockMs = opts?.staleLockMs ??
|
|
2841
|
+
const staleLockMs = opts?.staleLockMs ?? DEFAULT_STALE_LOCK_MS2;
|
|
2429
2842
|
const dir = canonicalTasksDir(teamName, opts?.cwd);
|
|
2430
2843
|
ensureDirWithMode(dir);
|
|
2431
2844
|
const lockPath = (0, import_path10.join)(dir, `${sanitizeTaskId(taskId)}.lock`);
|
|
2432
2845
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
2433
2846
|
try {
|
|
2434
|
-
const fd = (0,
|
|
2847
|
+
const fd = (0, import_fs9.openSync)(lockPath, import_fs9.constants.O_CREAT | import_fs9.constants.O_EXCL | import_fs9.constants.O_WRONLY, 384);
|
|
2435
2848
|
const payload = JSON.stringify({
|
|
2436
2849
|
pid: process.pid,
|
|
2437
2850
|
workerName: opts?.workerName ?? "",
|
|
2438
2851
|
timestamp: Date.now()
|
|
2439
2852
|
});
|
|
2440
|
-
(0,
|
|
2853
|
+
(0, import_fs9.writeSync)(fd, payload, null, "utf-8");
|
|
2441
2854
|
return { fd, path: lockPath };
|
|
2442
2855
|
} catch (err) {
|
|
2443
2856
|
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
2444
|
-
if (attempt === 0 &&
|
|
2857
|
+
if (attempt === 0 && isLockStale2(lockPath, staleLockMs)) {
|
|
2445
2858
|
try {
|
|
2446
|
-
(0,
|
|
2859
|
+
(0, import_fs9.unlinkSync)(lockPath);
|
|
2447
2860
|
} catch {
|
|
2448
2861
|
}
|
|
2449
2862
|
continue;
|
|
@@ -2457,11 +2870,11 @@ function acquireTaskLock(teamName, taskId, opts) {
|
|
|
2457
2870
|
}
|
|
2458
2871
|
function releaseTaskLock(handle) {
|
|
2459
2872
|
try {
|
|
2460
|
-
(0,
|
|
2873
|
+
(0, import_fs9.closeSync)(handle.fd);
|
|
2461
2874
|
} catch {
|
|
2462
2875
|
}
|
|
2463
2876
|
try {
|
|
2464
|
-
(0,
|
|
2877
|
+
(0, import_fs9.unlinkSync)(handle.path);
|
|
2465
2878
|
} catch {
|
|
2466
2879
|
}
|
|
2467
2880
|
}
|
|
@@ -2474,15 +2887,15 @@ async function withTaskLock(teamName, taskId, fn, opts) {
|
|
|
2474
2887
|
releaseTaskLock(handle);
|
|
2475
2888
|
}
|
|
2476
2889
|
}
|
|
2477
|
-
function
|
|
2890
|
+
function isLockStale2(lockPath, staleLockMs) {
|
|
2478
2891
|
try {
|
|
2479
|
-
const stat2 = (0,
|
|
2892
|
+
const stat2 = (0, import_fs9.statSync)(lockPath);
|
|
2480
2893
|
const ageMs = Date.now() - stat2.mtimeMs;
|
|
2481
2894
|
if (ageMs < staleLockMs) return false;
|
|
2482
2895
|
try {
|
|
2483
|
-
const raw = (0,
|
|
2896
|
+
const raw = (0, import_fs9.readFileSync)(lockPath, "utf-8");
|
|
2484
2897
|
const payload = JSON.parse(raw);
|
|
2485
|
-
if (payload.pid &&
|
|
2898
|
+
if (payload.pid && isProcessAlive(payload.pid)) return false;
|
|
2486
2899
|
} catch {
|
|
2487
2900
|
}
|
|
2488
2901
|
return true;
|
|
@@ -2519,9 +2932,9 @@ function writeTaskFailure(teamName, taskId, error, opts) {
|
|
|
2519
2932
|
}
|
|
2520
2933
|
function readTaskFailure(teamName, taskId, opts) {
|
|
2521
2934
|
const filePath = failureSidecarPath(teamName, taskId, opts?.cwd);
|
|
2522
|
-
if (!(0,
|
|
2935
|
+
if (!(0, import_fs9.existsSync)(filePath)) return null;
|
|
2523
2936
|
try {
|
|
2524
|
-
const raw = (0,
|
|
2937
|
+
const raw = (0, import_fs9.readFileSync)(filePath, "utf-8");
|
|
2525
2938
|
return JSON.parse(raw);
|
|
2526
2939
|
} catch {
|
|
2527
2940
|
return null;
|
|
@@ -2888,8 +3301,8 @@ function watchdogCliWorkers(runtime, intervalMs) {
|
|
|
2888
3301
|
unresponsiveCounts.delete(wName);
|
|
2889
3302
|
await markTaskFromDone(root, runtime.teamName, runtime.cwd, signal.taskId || active.taskId, signal.status, signal.summary);
|
|
2890
3303
|
try {
|
|
2891
|
-
const { unlink:
|
|
2892
|
-
await
|
|
3304
|
+
const { unlink: unlink3 } = await import("fs/promises");
|
|
3305
|
+
await unlink3(donePath);
|
|
2893
3306
|
} catch {
|
|
2894
3307
|
}
|
|
2895
3308
|
await killWorkerPane(runtime, wName, active.paneId);
|
|
@@ -2978,12 +3391,12 @@ async function spawnWorkerForTask(runtime, workerNameValue, taskIndex) {
|
|
|
2978
3391
|
if (!task) return "";
|
|
2979
3392
|
const marked = await markTaskInProgress(root, taskId, workerNameValue, runtime.teamName, runtime.cwd);
|
|
2980
3393
|
if (!marked) return "";
|
|
2981
|
-
const { execFile:
|
|
2982
|
-
const { promisify:
|
|
2983
|
-
const
|
|
3394
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
3395
|
+
const { promisify: promisify3 } = await import("util");
|
|
3396
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
2984
3397
|
const splitTarget = runtime.workerPaneIds.length === 0 ? runtime.leaderPaneId : runtime.workerPaneIds[runtime.workerPaneIds.length - 1];
|
|
2985
3398
|
const splitType = runtime.workerPaneIds.length === 0 ? "-h" : "-v";
|
|
2986
|
-
const splitResult = await
|
|
3399
|
+
const splitResult = await execFileAsync2("tmux", [
|
|
2987
3400
|
"split-window",
|
|
2988
3401
|
splitType,
|
|
2989
3402
|
"-t",
|
|
@@ -2996,13 +3409,18 @@ async function spawnWorkerForTask(runtime, workerNameValue, taskIndex) {
|
|
|
2996
3409
|
runtime.cwd
|
|
2997
3410
|
]);
|
|
2998
3411
|
const paneId = splitResult.stdout.split("\n")[0]?.trim();
|
|
2999
|
-
if (!paneId)
|
|
3412
|
+
if (!paneId) {
|
|
3413
|
+
try {
|
|
3414
|
+
await resetTaskToPending(root, taskId, runtime.teamName, runtime.cwd);
|
|
3415
|
+
} catch {
|
|
3416
|
+
}
|
|
3417
|
+
return "";
|
|
3418
|
+
}
|
|
3000
3419
|
const workerIndex = parseWorkerIndex(workerNameValue);
|
|
3001
3420
|
const agentType = runtime.config.agentTypes[workerIndex % runtime.config.agentTypes.length] ?? runtime.config.agentTypes[0] ?? "claude";
|
|
3002
3421
|
const usePromptMode = isPromptModeAgent(agentType);
|
|
3003
3422
|
const instruction = buildInitialTaskInstruction(runtime.teamName, workerNameValue, task, taskId);
|
|
3004
3423
|
await composeInitialInbox(runtime.teamName, workerNameValue, instruction, runtime.cwd);
|
|
3005
|
-
const relInboxPath = `.omc/state/team/${runtime.teamName}/workers/${workerNameValue}/inbox.md`;
|
|
3006
3424
|
const envVars = getWorkerEnv(runtime.teamName, workerNameValue, agentType);
|
|
3007
3425
|
const resolvedBinaryPath = runtime.resolvedBinaryPaths?.[agentType] ?? resolveValidatedBinaryPath(agentType);
|
|
3008
3426
|
if (!runtime.resolvedBinaryPaths) {
|
|
@@ -3016,7 +3434,7 @@ async function spawnWorkerForTask(runtime, workerNameValue, taskIndex) {
|
|
|
3016
3434
|
if (agentType === "gemini") {
|
|
3017
3435
|
return process.env.OMC_EXTERNAL_MODELS_DEFAULT_GEMINI_MODEL || process.env.OMC_GEMINI_DEFAULT_MODEL || void 0;
|
|
3018
3436
|
}
|
|
3019
|
-
return
|
|
3437
|
+
return resolveClaudeWorkerModel();
|
|
3020
3438
|
})();
|
|
3021
3439
|
const [launchBinary, ...launchArgs] = buildWorkerArgv(agentType, {
|
|
3022
3440
|
teamName: runtime.teamName,
|
|
@@ -3041,7 +3459,7 @@ async function spawnWorkerForTask(runtime, workerNameValue, taskIndex) {
|
|
|
3041
3459
|
runtime.workerPaneIds.push(paneId);
|
|
3042
3460
|
runtime.activeWorkers.set(workerNameValue, { paneId, taskId, spawnedAt: Date.now() });
|
|
3043
3461
|
try {
|
|
3044
|
-
await
|
|
3462
|
+
await execFileAsync2("tmux", ["select-layout", "-t", runtime.sessionName, "main-vertical"]);
|
|
3045
3463
|
} catch {
|
|
3046
3464
|
}
|
|
3047
3465
|
try {
|
|
@@ -3079,10 +3497,10 @@ async function spawnWorkerForTask(runtime, workerNameValue, taskIndex) {
|
|
|
3079
3497
|
}
|
|
3080
3498
|
async function killWorkerPane(runtime, workerNameValue, paneId) {
|
|
3081
3499
|
try {
|
|
3082
|
-
const { execFile:
|
|
3083
|
-
const { promisify:
|
|
3084
|
-
const
|
|
3085
|
-
await
|
|
3500
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
3501
|
+
const { promisify: promisify3 } = await import("util");
|
|
3502
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
3503
|
+
await execFileAsync2("tmux", ["kill-pane", "-t", paneId]);
|
|
3086
3504
|
} catch {
|
|
3087
3505
|
}
|
|
3088
3506
|
const paneIndex = runtime.workerPaneIds.indexOf(paneId);
|
|
@@ -3112,7 +3530,7 @@ async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, worker
|
|
|
3112
3530
|
while (Date.now() < deadline && expectedAcks.length > 0) {
|
|
3113
3531
|
for (const wName of [...expectedAcks]) {
|
|
3114
3532
|
const ackPath = (0, import_path11.join)(root, "workers", wName, "shutdown-ack.json");
|
|
3115
|
-
if ((0,
|
|
3533
|
+
if ((0, import_fs10.existsSync)(ackPath)) {
|
|
3116
3534
|
expectedAcks.splice(expectedAcks.indexOf(wName), 1);
|
|
3117
3535
|
}
|
|
3118
3536
|
}
|
|
@@ -3122,7 +3540,8 @@ async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, worker
|
|
|
3122
3540
|
}
|
|
3123
3541
|
}
|
|
3124
3542
|
const sessionMode = ownsWindow ?? Boolean(configData?.tmuxOwnsWindow) ? sessionName2.includes(":") ? "dedicated-window" : "detached-session" : "split-pane";
|
|
3125
|
-
await
|
|
3543
|
+
const effectiveWorkerPaneIds = sessionMode === "split-pane" ? await resolveSplitPaneWorkerPaneIds(sessionName2, workerPaneIds, leaderPaneId) : workerPaneIds;
|
|
3544
|
+
await killTeamSession(sessionName2, effectiveWorkerPaneIds, leaderPaneId, { sessionMode });
|
|
3126
3545
|
try {
|
|
3127
3546
|
cleanupTeamWorktrees(teamName, cwd);
|
|
3128
3547
|
} catch {
|
|
@@ -3133,9 +3552,142 @@ async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, worker
|
|
|
3133
3552
|
}
|
|
3134
3553
|
}
|
|
3135
3554
|
|
|
3136
|
-
// src/
|
|
3137
|
-
var
|
|
3555
|
+
// src/team/events.ts
|
|
3556
|
+
var import_crypto = require("crypto");
|
|
3138
3557
|
var import_path12 = require("path");
|
|
3558
|
+
var import_promises4 = require("fs/promises");
|
|
3559
|
+
var import_fs11 = require("fs");
|
|
3560
|
+
|
|
3561
|
+
// src/lib/swallowed-error.ts
|
|
3562
|
+
function formatSwallowedError(error) {
|
|
3563
|
+
if (error instanceof Error) return error.message;
|
|
3564
|
+
if (typeof error === "string") return error;
|
|
3565
|
+
try {
|
|
3566
|
+
return JSON.stringify(error);
|
|
3567
|
+
} catch {
|
|
3568
|
+
return String(error);
|
|
3569
|
+
}
|
|
3570
|
+
}
|
|
3571
|
+
function logSwallowedError(context, error) {
|
|
3572
|
+
try {
|
|
3573
|
+
console.warn(`[omc] ${context}: ${formatSwallowedError(error)}`);
|
|
3574
|
+
} catch {
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
function createSwallowedErrorLogger(context) {
|
|
3578
|
+
return (error) => {
|
|
3579
|
+
logSwallowedError(context, error);
|
|
3580
|
+
};
|
|
3581
|
+
}
|
|
3582
|
+
|
|
3583
|
+
// src/team/events.ts
|
|
3584
|
+
async function appendTeamEvent(teamName, event, cwd) {
|
|
3585
|
+
const full = {
|
|
3586
|
+
event_id: (0, import_crypto.randomUUID)(),
|
|
3587
|
+
team: teamName,
|
|
3588
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3589
|
+
...event
|
|
3590
|
+
};
|
|
3591
|
+
const p = absPath(cwd, TeamPaths.events(teamName));
|
|
3592
|
+
await (0, import_promises4.mkdir)((0, import_path12.dirname)(p), { recursive: true });
|
|
3593
|
+
await (0, import_promises4.appendFile)(p, `${JSON.stringify(full)}
|
|
3594
|
+
`, "utf8");
|
|
3595
|
+
return full;
|
|
3596
|
+
}
|
|
3597
|
+
async function emitMonitorDerivedEvents(teamName, tasks, workers, previousSnapshot, cwd) {
|
|
3598
|
+
if (!previousSnapshot) return;
|
|
3599
|
+
const logDerivedEventFailure = createSwallowedErrorLogger(
|
|
3600
|
+
"team.events.emitMonitorDerivedEvents appendTeamEvent failed"
|
|
3601
|
+
);
|
|
3602
|
+
const completedEventTaskIds = { ...previousSnapshot.completedEventTaskIds ?? {} };
|
|
3603
|
+
for (const task of tasks) {
|
|
3604
|
+
const prevStatus = previousSnapshot.taskStatusById?.[task.id];
|
|
3605
|
+
if (!prevStatus || prevStatus === task.status) continue;
|
|
3606
|
+
if (task.status === "completed" && !completedEventTaskIds[task.id]) {
|
|
3607
|
+
await appendTeamEvent(teamName, {
|
|
3608
|
+
type: "task_completed",
|
|
3609
|
+
worker: "leader-fixed",
|
|
3610
|
+
task_id: task.id,
|
|
3611
|
+
reason: `status_transition:${prevStatus}->${task.status}`
|
|
3612
|
+
}, cwd).catch(logDerivedEventFailure);
|
|
3613
|
+
completedEventTaskIds[task.id] = true;
|
|
3614
|
+
} else if (task.status === "failed") {
|
|
3615
|
+
await appendTeamEvent(teamName, {
|
|
3616
|
+
type: "task_failed",
|
|
3617
|
+
worker: "leader-fixed",
|
|
3618
|
+
task_id: task.id,
|
|
3619
|
+
reason: `status_transition:${prevStatus}->${task.status}`
|
|
3620
|
+
}, cwd).catch(logDerivedEventFailure);
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
for (const worker of workers) {
|
|
3624
|
+
const prevAlive = previousSnapshot.workerAliveByName?.[worker.name];
|
|
3625
|
+
const prevState = previousSnapshot.workerStateByName?.[worker.name];
|
|
3626
|
+
if (prevAlive === true && !worker.alive) {
|
|
3627
|
+
await appendTeamEvent(teamName, {
|
|
3628
|
+
type: "worker_stopped",
|
|
3629
|
+
worker: worker.name,
|
|
3630
|
+
reason: "pane_exited"
|
|
3631
|
+
}, cwd).catch(logDerivedEventFailure);
|
|
3632
|
+
}
|
|
3633
|
+
if (prevState === "working" && worker.status.state === "idle") {
|
|
3634
|
+
await appendTeamEvent(teamName, {
|
|
3635
|
+
type: "worker_idle",
|
|
3636
|
+
worker: worker.name,
|
|
3637
|
+
reason: `state_transition:${prevState}->${worker.status.state}`
|
|
3638
|
+
}, cwd).catch(logDerivedEventFailure);
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
|
|
3643
|
+
// src/team/leader-nudge-guidance.ts
|
|
3644
|
+
function activeTaskCount(input) {
|
|
3645
|
+
return input.tasks.pending + input.tasks.blocked + input.tasks.inProgress;
|
|
3646
|
+
}
|
|
3647
|
+
function deriveTeamLeaderGuidance(input) {
|
|
3648
|
+
const activeTasks = activeTaskCount(input);
|
|
3649
|
+
const totalWorkers = Math.max(0, input.workers.total);
|
|
3650
|
+
const aliveWorkers = Math.max(0, input.workers.alive);
|
|
3651
|
+
const idleWorkers = Math.max(0, input.workers.idle);
|
|
3652
|
+
const nonReportingWorkers = Math.max(0, input.workers.nonReporting);
|
|
3653
|
+
if (activeTasks === 0) {
|
|
3654
|
+
return {
|
|
3655
|
+
nextAction: "shutdown",
|
|
3656
|
+
reason: `all_tasks_terminal:completed=${input.tasks.completed},failed=${input.tasks.failed},workers=${totalWorkers}`,
|
|
3657
|
+
message: "All tasks are in a terminal state. Review any failures, then shut down or clean up the current team."
|
|
3658
|
+
};
|
|
3659
|
+
}
|
|
3660
|
+
if (aliveWorkers === 0) {
|
|
3661
|
+
return {
|
|
3662
|
+
nextAction: "launch-new-team",
|
|
3663
|
+
reason: `no_alive_workers:active=${activeTasks},total_workers=${totalWorkers}`,
|
|
3664
|
+
message: "Active tasks remain, but no workers appear alive. Launch a new team or replace the dead workers."
|
|
3665
|
+
};
|
|
3666
|
+
}
|
|
3667
|
+
if (idleWorkers >= aliveWorkers) {
|
|
3668
|
+
return {
|
|
3669
|
+
nextAction: "reuse-current-team",
|
|
3670
|
+
reason: `all_alive_workers_idle:active=${activeTasks},alive=${aliveWorkers},idle=${idleWorkers}`,
|
|
3671
|
+
message: "Workers are idle while active tasks remain. Reuse the current team and reassign, unblock, or restart the pending work."
|
|
3672
|
+
};
|
|
3673
|
+
}
|
|
3674
|
+
if (nonReportingWorkers >= aliveWorkers) {
|
|
3675
|
+
return {
|
|
3676
|
+
nextAction: "launch-new-team",
|
|
3677
|
+
reason: `all_alive_workers_non_reporting:active=${activeTasks},alive=${aliveWorkers},non_reporting=${nonReportingWorkers}`,
|
|
3678
|
+
message: "Workers are still marked alive, but none are reporting progress. Launch a replacement team or restart the stuck workers."
|
|
3679
|
+
};
|
|
3680
|
+
}
|
|
3681
|
+
return {
|
|
3682
|
+
nextAction: "keep-checking-status",
|
|
3683
|
+
reason: `workers_still_active:active=${activeTasks},alive=${aliveWorkers},idle=${idleWorkers},non_reporting=${nonReportingWorkers}`,
|
|
3684
|
+
message: "Workers still appear active. Keep checking team status before intervening."
|
|
3685
|
+
};
|
|
3686
|
+
}
|
|
3687
|
+
|
|
3688
|
+
// src/hooks/factcheck/checks.ts
|
|
3689
|
+
var import_fs12 = require("fs");
|
|
3690
|
+
var import_path13 = require("path");
|
|
3139
3691
|
|
|
3140
3692
|
// src/hooks/factcheck/types.ts
|
|
3141
3693
|
var REQUIRED_FIELDS = /* @__PURE__ */ new Set([
|
|
@@ -3217,7 +3769,7 @@ function checkPaths(claims, policy) {
|
|
|
3217
3769
|
}
|
|
3218
3770
|
}
|
|
3219
3771
|
}
|
|
3220
|
-
if (!(0,
|
|
3772
|
+
if (!(0, import_fs12.existsSync)(pathStr)) {
|
|
3221
3773
|
out.push({ check: "C", severity: "FAIL", detail: `File not found: ${pathStr}` });
|
|
3222
3774
|
}
|
|
3223
3775
|
}
|
|
@@ -3244,8 +3796,8 @@ function checkCommands(claims, policy) {
|
|
|
3244
3796
|
function checkCwdParity(claimsCwd, runtimeCwd, mode, policy) {
|
|
3245
3797
|
const enforceCwd = policy.warn_on_cwd_mismatch && (mode !== "quick" || policy.enforce_cwd_parity_in_quick);
|
|
3246
3798
|
if (!enforceCwd || !claimsCwd) return null;
|
|
3247
|
-
const claimsCwdCanonical = (0,
|
|
3248
|
-
const runtimeCwdCanonical = (0,
|
|
3799
|
+
const claimsCwdCanonical = (0, import_path13.resolve)(claimsCwd);
|
|
3800
|
+
const runtimeCwdCanonical = (0, import_path13.resolve)(runtimeCwd);
|
|
3249
3801
|
if (claimsCwdCanonical !== runtimeCwdCanonical) {
|
|
3250
3802
|
const severity = mode === "strict" ? "FAIL" : "WARN";
|
|
3251
3803
|
return {
|
|
@@ -3425,7 +3977,7 @@ function runFactcheck(claims, options) {
|
|
|
3425
3977
|
}
|
|
3426
3978
|
|
|
3427
3979
|
// src/hooks/factcheck/sentinel.ts
|
|
3428
|
-
var
|
|
3980
|
+
var import_fs13 = require("fs");
|
|
3429
3981
|
function computeRate(numerator, denominator) {
|
|
3430
3982
|
if (denominator === 0) return 0;
|
|
3431
3983
|
return numerator / denominator;
|
|
@@ -3466,12 +4018,12 @@ function analyzeLog(logPath) {
|
|
|
3466
4018
|
timeout_count: 0,
|
|
3467
4019
|
reason_coverage_count: 0
|
|
3468
4020
|
};
|
|
3469
|
-
if (!(0,
|
|
4021
|
+
if (!(0, import_fs13.existsSync)(logPath)) {
|
|
3470
4022
|
return stats;
|
|
3471
4023
|
}
|
|
3472
4024
|
let content;
|
|
3473
4025
|
try {
|
|
3474
|
-
content = (0,
|
|
4026
|
+
content = (0, import_fs13.readFileSync)(logPath, "utf-8");
|
|
3475
4027
|
} catch {
|
|
3476
4028
|
return stats;
|
|
3477
4029
|
}
|
|
@@ -3650,20 +4202,213 @@ async function waitForSentinelReadiness(options = {}) {
|
|
|
3650
4202
|
}
|
|
3651
4203
|
|
|
3652
4204
|
// src/team/runtime-v2.ts
|
|
3653
|
-
var
|
|
4205
|
+
var import_child_process5 = require("child_process");
|
|
3654
4206
|
var import_path16 = require("path");
|
|
3655
|
-
var
|
|
4207
|
+
var import_fs16 = require("fs");
|
|
3656
4208
|
var import_promises7 = require("fs/promises");
|
|
3657
4209
|
var import_perf_hooks = require("perf_hooks");
|
|
3658
4210
|
|
|
4211
|
+
// src/team/allocation-policy.ts
|
|
4212
|
+
function allocateTasksToWorkers(tasks, workers) {
|
|
4213
|
+
if (tasks.length === 0 || workers.length === 0) return [];
|
|
4214
|
+
const uniformRolePool = isUniformRolePool(workers);
|
|
4215
|
+
const results = [];
|
|
4216
|
+
const loadMap = new Map(workers.map((w) => [w.name, w.currentLoad]));
|
|
4217
|
+
if (uniformRolePool) {
|
|
4218
|
+
for (const task of tasks) {
|
|
4219
|
+
const target = pickLeastLoaded(workers, loadMap);
|
|
4220
|
+
results.push({
|
|
4221
|
+
taskId: task.id,
|
|
4222
|
+
workerName: target.name,
|
|
4223
|
+
reason: `uniform pool round-robin (role=${target.role}, load=${loadMap.get(target.name)})`
|
|
4224
|
+
});
|
|
4225
|
+
loadMap.set(target.name, (loadMap.get(target.name) ?? 0) + 1);
|
|
4226
|
+
}
|
|
4227
|
+
} else {
|
|
4228
|
+
for (const task of tasks) {
|
|
4229
|
+
const target = pickBestWorker(task, workers, loadMap);
|
|
4230
|
+
results.push({
|
|
4231
|
+
taskId: task.id,
|
|
4232
|
+
workerName: target.name,
|
|
4233
|
+
reason: `role match (task.role=${task.role ?? "any"}, worker.role=${target.role}, load=${loadMap.get(target.name)})`
|
|
4234
|
+
});
|
|
4235
|
+
loadMap.set(target.name, (loadMap.get(target.name) ?? 0) + 1);
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4238
|
+
return results;
|
|
4239
|
+
}
|
|
4240
|
+
function isUniformRolePool(workers) {
|
|
4241
|
+
if (workers.length === 0) return true;
|
|
4242
|
+
const firstRole = workers[0].role;
|
|
4243
|
+
return workers.every((w) => w.role === firstRole);
|
|
4244
|
+
}
|
|
4245
|
+
function pickLeastLoaded(workers, loadMap) {
|
|
4246
|
+
let best = workers[0];
|
|
4247
|
+
let bestLoad = loadMap.get(best.name) ?? 0;
|
|
4248
|
+
for (const w of workers) {
|
|
4249
|
+
const load = loadMap.get(w.name) ?? 0;
|
|
4250
|
+
if (load < bestLoad) {
|
|
4251
|
+
best = w;
|
|
4252
|
+
bestLoad = load;
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
return best;
|
|
4256
|
+
}
|
|
4257
|
+
function pickBestWorker(task, workers, loadMap) {
|
|
4258
|
+
const scored = workers.map((w) => {
|
|
4259
|
+
const load = loadMap.get(w.name) ?? 0;
|
|
4260
|
+
const roleScore = task.role ? w.role === task.role ? 1 : 0 : 0.5;
|
|
4261
|
+
const score = roleScore - load * 0.2;
|
|
4262
|
+
return { worker: w, score };
|
|
4263
|
+
});
|
|
4264
|
+
scored.sort((a, b) => b.score - a.score);
|
|
4265
|
+
return scored[0].worker;
|
|
4266
|
+
}
|
|
4267
|
+
|
|
4268
|
+
// src/team/monitor.ts
|
|
4269
|
+
var import_fs14 = require("fs");
|
|
4270
|
+
var import_promises5 = require("fs/promises");
|
|
4271
|
+
var import_path14 = require("path");
|
|
4272
|
+
|
|
4273
|
+
// src/team/governance.ts
|
|
4274
|
+
var DEFAULT_TEAM_TRANSPORT_POLICY = {
|
|
4275
|
+
display_mode: "split_pane",
|
|
4276
|
+
worker_launch_mode: "interactive",
|
|
4277
|
+
dispatch_mode: "hook_preferred_with_fallback",
|
|
4278
|
+
dispatch_ack_timeout_ms: 15e3
|
|
4279
|
+
};
|
|
4280
|
+
var DEFAULT_TEAM_GOVERNANCE = {
|
|
4281
|
+
delegation_only: false,
|
|
4282
|
+
plan_approval_required: false,
|
|
4283
|
+
nested_teams_allowed: false,
|
|
4284
|
+
one_team_per_leader_session: true,
|
|
4285
|
+
cleanup_requires_all_workers_inactive: true
|
|
4286
|
+
};
|
|
4287
|
+
function normalizeTeamTransportPolicy(policy) {
|
|
4288
|
+
return {
|
|
4289
|
+
display_mode: policy?.display_mode ?? DEFAULT_TEAM_TRANSPORT_POLICY.display_mode,
|
|
4290
|
+
worker_launch_mode: policy?.worker_launch_mode ?? DEFAULT_TEAM_TRANSPORT_POLICY.worker_launch_mode,
|
|
4291
|
+
dispatch_mode: policy?.dispatch_mode ?? DEFAULT_TEAM_TRANSPORT_POLICY.dispatch_mode,
|
|
4292
|
+
dispatch_ack_timeout_ms: typeof policy?.dispatch_ack_timeout_ms === "number" ? policy.dispatch_ack_timeout_ms : DEFAULT_TEAM_TRANSPORT_POLICY.dispatch_ack_timeout_ms
|
|
4293
|
+
};
|
|
4294
|
+
}
|
|
4295
|
+
function normalizeTeamGovernance(governance, legacyPolicy) {
|
|
4296
|
+
return {
|
|
4297
|
+
delegation_only: governance?.delegation_only ?? legacyPolicy?.delegation_only ?? DEFAULT_TEAM_GOVERNANCE.delegation_only,
|
|
4298
|
+
plan_approval_required: governance?.plan_approval_required ?? legacyPolicy?.plan_approval_required ?? DEFAULT_TEAM_GOVERNANCE.plan_approval_required,
|
|
4299
|
+
nested_teams_allowed: governance?.nested_teams_allowed ?? legacyPolicy?.nested_teams_allowed ?? DEFAULT_TEAM_GOVERNANCE.nested_teams_allowed,
|
|
4300
|
+
one_team_per_leader_session: governance?.one_team_per_leader_session ?? legacyPolicy?.one_team_per_leader_session ?? DEFAULT_TEAM_GOVERNANCE.one_team_per_leader_session,
|
|
4301
|
+
cleanup_requires_all_workers_inactive: governance?.cleanup_requires_all_workers_inactive ?? legacyPolicy?.cleanup_requires_all_workers_inactive ?? DEFAULT_TEAM_GOVERNANCE.cleanup_requires_all_workers_inactive
|
|
4302
|
+
};
|
|
4303
|
+
}
|
|
4304
|
+
function normalizeTeamManifest(manifest) {
|
|
4305
|
+
return {
|
|
4306
|
+
...manifest,
|
|
4307
|
+
policy: normalizeTeamTransportPolicy(manifest.policy),
|
|
4308
|
+
governance: normalizeTeamGovernance(manifest.governance, manifest.policy)
|
|
4309
|
+
};
|
|
4310
|
+
}
|
|
4311
|
+
function getConfigGovernance(config) {
|
|
4312
|
+
return normalizeTeamGovernance(config?.governance, config?.policy);
|
|
4313
|
+
}
|
|
4314
|
+
|
|
4315
|
+
// src/team/worker-canonicalization.ts
|
|
4316
|
+
function hasText(value) {
|
|
4317
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
4318
|
+
}
|
|
4319
|
+
function hasAssignedTasks(worker) {
|
|
4320
|
+
return Array.isArray(worker.assigned_tasks) && worker.assigned_tasks.length > 0;
|
|
4321
|
+
}
|
|
4322
|
+
function workerPriority(worker) {
|
|
4323
|
+
if (hasText(worker.pane_id)) return 4;
|
|
4324
|
+
if (typeof worker.pid === "number" && Number.isFinite(worker.pid)) return 3;
|
|
4325
|
+
if (hasAssignedTasks(worker)) return 2;
|
|
4326
|
+
if (typeof worker.index === "number" && worker.index > 0) return 1;
|
|
4327
|
+
return 0;
|
|
4328
|
+
}
|
|
4329
|
+
function mergeAssignedTasks(primary, secondary) {
|
|
4330
|
+
const merged = [];
|
|
4331
|
+
for (const taskId of [...primary ?? [], ...secondary ?? []]) {
|
|
4332
|
+
if (typeof taskId !== "string" || taskId.trim() === "" || merged.includes(taskId)) continue;
|
|
4333
|
+
merged.push(taskId);
|
|
4334
|
+
}
|
|
4335
|
+
return merged;
|
|
4336
|
+
}
|
|
4337
|
+
function backfillText(primary, secondary) {
|
|
4338
|
+
return hasText(primary) ? primary : secondary;
|
|
4339
|
+
}
|
|
4340
|
+
function backfillBoolean(primary, secondary) {
|
|
4341
|
+
return typeof primary === "boolean" ? primary : secondary;
|
|
4342
|
+
}
|
|
4343
|
+
function backfillNumber(primary, secondary, predicate) {
|
|
4344
|
+
const isUsable = (value) => typeof value === "number" && Number.isFinite(value) && (predicate ? predicate(value) : true);
|
|
4345
|
+
return isUsable(primary) ? primary : isUsable(secondary) ? secondary : void 0;
|
|
4346
|
+
}
|
|
4347
|
+
function chooseWinningWorker(existing, incoming) {
|
|
4348
|
+
const existingPriority = workerPriority(existing);
|
|
4349
|
+
const incomingPriority = workerPriority(incoming);
|
|
4350
|
+
if (incomingPriority > existingPriority) return { winner: incoming, loser: existing };
|
|
4351
|
+
if (incomingPriority < existingPriority) return { winner: existing, loser: incoming };
|
|
4352
|
+
if ((incoming.index ?? 0) >= (existing.index ?? 0)) return { winner: incoming, loser: existing };
|
|
4353
|
+
return { winner: existing, loser: incoming };
|
|
4354
|
+
}
|
|
4355
|
+
function canonicalizeWorkers(workers) {
|
|
4356
|
+
const byName = /* @__PURE__ */ new Map();
|
|
4357
|
+
const duplicateNames = /* @__PURE__ */ new Set();
|
|
4358
|
+
for (const worker of workers) {
|
|
4359
|
+
const name = typeof worker.name === "string" ? worker.name.trim() : "";
|
|
4360
|
+
if (!name) continue;
|
|
4361
|
+
const normalized = {
|
|
4362
|
+
...worker,
|
|
4363
|
+
name,
|
|
4364
|
+
assigned_tasks: Array.isArray(worker.assigned_tasks) ? worker.assigned_tasks : []
|
|
4365
|
+
};
|
|
4366
|
+
const existing = byName.get(name);
|
|
4367
|
+
if (!existing) {
|
|
4368
|
+
byName.set(name, normalized);
|
|
4369
|
+
continue;
|
|
4370
|
+
}
|
|
4371
|
+
duplicateNames.add(name);
|
|
4372
|
+
const { winner, loser } = chooseWinningWorker(existing, normalized);
|
|
4373
|
+
byName.set(name, {
|
|
4374
|
+
...winner,
|
|
4375
|
+
name,
|
|
4376
|
+
assigned_tasks: mergeAssignedTasks(winner.assigned_tasks, loser.assigned_tasks),
|
|
4377
|
+
pane_id: backfillText(winner.pane_id, loser.pane_id),
|
|
4378
|
+
pid: backfillNumber(winner.pid, loser.pid),
|
|
4379
|
+
index: backfillNumber(winner.index, loser.index, (value) => value > 0) ?? 0,
|
|
4380
|
+
role: backfillText(winner.role, loser.role) ?? winner.role,
|
|
4381
|
+
worker_cli: backfillText(winner.worker_cli, loser.worker_cli),
|
|
4382
|
+
working_dir: backfillText(winner.working_dir, loser.working_dir),
|
|
4383
|
+
worktree_path: backfillText(winner.worktree_path, loser.worktree_path),
|
|
4384
|
+
worktree_branch: backfillText(winner.worktree_branch, loser.worktree_branch),
|
|
4385
|
+
worktree_detached: backfillBoolean(winner.worktree_detached, loser.worktree_detached),
|
|
4386
|
+
team_state_root: backfillText(winner.team_state_root, loser.team_state_root)
|
|
4387
|
+
});
|
|
4388
|
+
}
|
|
4389
|
+
return {
|
|
4390
|
+
workers: Array.from(byName.values()),
|
|
4391
|
+
duplicateNames: Array.from(duplicateNames.values())
|
|
4392
|
+
};
|
|
4393
|
+
}
|
|
4394
|
+
function canonicalizeTeamConfigWorkers(config) {
|
|
4395
|
+
const { workers, duplicateNames } = canonicalizeWorkers(config.workers ?? []);
|
|
4396
|
+
if (duplicateNames.length > 0) {
|
|
4397
|
+
console.warn(
|
|
4398
|
+
`[team] canonicalized duplicate worker entries: ${duplicateNames.join(", ")}`
|
|
4399
|
+
);
|
|
4400
|
+
}
|
|
4401
|
+
return {
|
|
4402
|
+
...config,
|
|
4403
|
+
workers
|
|
4404
|
+
};
|
|
4405
|
+
}
|
|
4406
|
+
|
|
3659
4407
|
// src/team/monitor.ts
|
|
3660
|
-
var import_fs10 = require("fs");
|
|
3661
|
-
var import_promises4 = require("fs/promises");
|
|
3662
|
-
var import_path13 = require("path");
|
|
3663
4408
|
async function readJsonSafe2(filePath) {
|
|
3664
4409
|
try {
|
|
3665
|
-
if (!(0,
|
|
3666
|
-
const raw = await (0,
|
|
4410
|
+
if (!(0, import_fs14.existsSync)(filePath)) return null;
|
|
4411
|
+
const raw = await (0, import_promises5.readFile)(filePath, "utf-8");
|
|
3667
4412
|
return JSON.parse(raw);
|
|
3668
4413
|
} catch {
|
|
3669
4414
|
return null;
|
|
@@ -3671,14 +4416,56 @@ async function readJsonSafe2(filePath) {
|
|
|
3671
4416
|
}
|
|
3672
4417
|
async function writeAtomic(filePath, data) {
|
|
3673
4418
|
const { writeFile: writeFile6 } = await import("fs/promises");
|
|
3674
|
-
await (0,
|
|
4419
|
+
await (0, import_promises5.mkdir)((0, import_path14.dirname)(filePath), { recursive: true });
|
|
3675
4420
|
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
3676
4421
|
await writeFile6(tmpPath, data, "utf-8");
|
|
3677
|
-
const { rename:
|
|
3678
|
-
await
|
|
4422
|
+
const { rename: rename4 } = await import("fs/promises");
|
|
4423
|
+
await rename4(tmpPath, filePath);
|
|
4424
|
+
}
|
|
4425
|
+
function configFromManifest(manifest) {
|
|
4426
|
+
return {
|
|
4427
|
+
name: manifest.name,
|
|
4428
|
+
task: manifest.task,
|
|
4429
|
+
agent_type: "claude",
|
|
4430
|
+
policy: manifest.policy,
|
|
4431
|
+
governance: manifest.governance,
|
|
4432
|
+
worker_launch_mode: manifest.policy.worker_launch_mode,
|
|
4433
|
+
worker_count: manifest.worker_count,
|
|
4434
|
+
max_workers: 20,
|
|
4435
|
+
workers: manifest.workers,
|
|
4436
|
+
created_at: manifest.created_at,
|
|
4437
|
+
tmux_session: manifest.tmux_session,
|
|
4438
|
+
next_task_id: manifest.next_task_id,
|
|
4439
|
+
leader_cwd: manifest.leader_cwd,
|
|
4440
|
+
team_state_root: manifest.team_state_root,
|
|
4441
|
+
workspace_mode: manifest.workspace_mode,
|
|
4442
|
+
leader_pane_id: manifest.leader_pane_id,
|
|
4443
|
+
hud_pane_id: manifest.hud_pane_id,
|
|
4444
|
+
resize_hook_name: manifest.resize_hook_name,
|
|
4445
|
+
resize_hook_target: manifest.resize_hook_target,
|
|
4446
|
+
next_worker_index: manifest.next_worker_index
|
|
4447
|
+
};
|
|
3679
4448
|
}
|
|
3680
4449
|
async function readTeamConfig(teamName, cwd) {
|
|
3681
|
-
|
|
4450
|
+
const [config, manifest] = await Promise.all([
|
|
4451
|
+
readJsonSafe2(absPath(cwd, TeamPaths.config(teamName))),
|
|
4452
|
+
readTeamManifest(teamName, cwd)
|
|
4453
|
+
]);
|
|
4454
|
+
if (!config && !manifest) return null;
|
|
4455
|
+
if (!manifest) return config ? canonicalizeTeamConfigWorkers(config) : null;
|
|
4456
|
+
if (!config) return canonicalizeTeamConfigWorkers(configFromManifest(manifest));
|
|
4457
|
+
return canonicalizeTeamConfigWorkers({
|
|
4458
|
+
...configFromManifest(manifest),
|
|
4459
|
+
...config,
|
|
4460
|
+
workers: [...config.workers ?? [], ...manifest.workers ?? []],
|
|
4461
|
+
worker_count: Math.max(config.worker_count ?? 0, manifest.worker_count ?? 0),
|
|
4462
|
+
next_task_id: Math.max(config.next_task_id ?? 1, manifest.next_task_id ?? 1),
|
|
4463
|
+
max_workers: Math.max(config.max_workers ?? 0, 20)
|
|
4464
|
+
});
|
|
4465
|
+
}
|
|
4466
|
+
async function readTeamManifest(teamName, cwd) {
|
|
4467
|
+
const manifest = await readJsonSafe2(absPath(cwd, TeamPaths.manifest(teamName)));
|
|
4468
|
+
return manifest ? normalizeTeamManifest(manifest) : null;
|
|
3682
4469
|
}
|
|
3683
4470
|
async function readWorkerStatus(teamName, workerName2, cwd) {
|
|
3684
4471
|
const data = await readJsonSafe2(absPath(cwd, TeamPaths.workerStatus(teamName, workerName2)));
|
|
@@ -3689,9 +4476,9 @@ async function readWorkerHeartbeat(teamName, workerName2, cwd) {
|
|
|
3689
4476
|
}
|
|
3690
4477
|
async function readMonitorSnapshot(teamName, cwd) {
|
|
3691
4478
|
const p = absPath(cwd, TeamPaths.monitorSnapshot(teamName));
|
|
3692
|
-
if (!(0,
|
|
4479
|
+
if (!(0, import_fs14.existsSync)(p)) return null;
|
|
3693
4480
|
try {
|
|
3694
|
-
const raw = await (0,
|
|
4481
|
+
const raw = await (0, import_promises5.readFile)(p, "utf-8");
|
|
3695
4482
|
const parsed = JSON.parse(raw);
|
|
3696
4483
|
if (!parsed || typeof parsed !== "object") return null;
|
|
3697
4484
|
const monitorTimings = (() => {
|
|
@@ -3740,7 +4527,7 @@ async function readShutdownAck(teamName, workerName2, cwd, requestedAfter) {
|
|
|
3740
4527
|
}
|
|
3741
4528
|
async function listTasksFromFiles(teamName, cwd) {
|
|
3742
4529
|
const tasksDir = absPath(cwd, TeamPaths.tasks(teamName));
|
|
3743
|
-
if (!(0,
|
|
4530
|
+
if (!(0, import_fs14.existsSync)(tasksDir)) return [];
|
|
3744
4531
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
3745
4532
|
const entries = await readdir2(tasksDir);
|
|
3746
4533
|
const tasks = [];
|
|
@@ -3757,81 +4544,39 @@ async function writeWorkerInbox(teamName, workerName2, content, cwd) {
|
|
|
3757
4544
|
}
|
|
3758
4545
|
async function saveTeamConfig(config, cwd) {
|
|
3759
4546
|
await writeAtomic(absPath(cwd, TeamPaths.config(config.name)), JSON.stringify(config, null, 2));
|
|
4547
|
+
const manifestPath = absPath(cwd, TeamPaths.manifest(config.name));
|
|
4548
|
+
const existingManifest = await readJsonSafe2(manifestPath);
|
|
4549
|
+
if (existingManifest) {
|
|
4550
|
+
const nextManifest = normalizeTeamManifest({
|
|
4551
|
+
...existingManifest,
|
|
4552
|
+
workers: config.workers,
|
|
4553
|
+
worker_count: config.worker_count,
|
|
4554
|
+
tmux_session: config.tmux_session,
|
|
4555
|
+
next_task_id: config.next_task_id,
|
|
4556
|
+
created_at: config.created_at,
|
|
4557
|
+
leader_cwd: config.leader_cwd,
|
|
4558
|
+
team_state_root: config.team_state_root,
|
|
4559
|
+
workspace_mode: config.workspace_mode,
|
|
4560
|
+
leader_pane_id: config.leader_pane_id,
|
|
4561
|
+
hud_pane_id: config.hud_pane_id,
|
|
4562
|
+
resize_hook_name: config.resize_hook_name,
|
|
4563
|
+
resize_hook_target: config.resize_hook_target,
|
|
4564
|
+
next_worker_index: config.next_worker_index,
|
|
4565
|
+
policy: config.policy ?? existingManifest.policy,
|
|
4566
|
+
governance: config.governance ?? existingManifest.governance
|
|
4567
|
+
});
|
|
4568
|
+
await writeAtomic(manifestPath, JSON.stringify(nextManifest, null, 2));
|
|
4569
|
+
}
|
|
3760
4570
|
}
|
|
3761
4571
|
async function cleanupTeamState(teamName, cwd) {
|
|
3762
4572
|
const root = absPath(cwd, TeamPaths.root(teamName));
|
|
3763
|
-
const { rm:
|
|
4573
|
+
const { rm: rm3 } = await import("fs/promises");
|
|
3764
4574
|
try {
|
|
3765
|
-
await
|
|
4575
|
+
await rm3(root, { recursive: true, force: true });
|
|
3766
4576
|
} catch {
|
|
3767
4577
|
}
|
|
3768
4578
|
}
|
|
3769
4579
|
|
|
3770
|
-
// src/team/events.ts
|
|
3771
|
-
var import_crypto = require("crypto");
|
|
3772
|
-
var import_path14 = require("path");
|
|
3773
|
-
var import_promises5 = require("fs/promises");
|
|
3774
|
-
var import_fs11 = require("fs");
|
|
3775
|
-
async function appendTeamEvent(teamName, event, cwd) {
|
|
3776
|
-
const full = {
|
|
3777
|
-
event_id: (0, import_crypto.randomUUID)(),
|
|
3778
|
-
team: teamName,
|
|
3779
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3780
|
-
...event
|
|
3781
|
-
};
|
|
3782
|
-
const p = absPath(cwd, TeamPaths.events(teamName));
|
|
3783
|
-
await (0, import_promises5.mkdir)((0, import_path14.dirname)(p), { recursive: true });
|
|
3784
|
-
await (0, import_promises5.appendFile)(p, `${JSON.stringify(full)}
|
|
3785
|
-
`, "utf8");
|
|
3786
|
-
return full;
|
|
3787
|
-
}
|
|
3788
|
-
async function emitMonitorDerivedEvents(teamName, tasks, workers, previousSnapshot, cwd) {
|
|
3789
|
-
if (!previousSnapshot) return;
|
|
3790
|
-
const completedEventTaskIds = { ...previousSnapshot.completedEventTaskIds ?? {} };
|
|
3791
|
-
for (const task of tasks) {
|
|
3792
|
-
const prevStatus = previousSnapshot.taskStatusById?.[task.id];
|
|
3793
|
-
if (!prevStatus || prevStatus === task.status) continue;
|
|
3794
|
-
if (task.status === "completed" && !completedEventTaskIds[task.id]) {
|
|
3795
|
-
await appendTeamEvent(teamName, {
|
|
3796
|
-
type: "task_completed",
|
|
3797
|
-
worker: "leader-fixed",
|
|
3798
|
-
task_id: task.id,
|
|
3799
|
-
reason: `status_transition:${prevStatus}->${task.status}`
|
|
3800
|
-
}, cwd).catch(() => {
|
|
3801
|
-
});
|
|
3802
|
-
completedEventTaskIds[task.id] = true;
|
|
3803
|
-
} else if (task.status === "failed") {
|
|
3804
|
-
await appendTeamEvent(teamName, {
|
|
3805
|
-
type: "task_failed",
|
|
3806
|
-
worker: "leader-fixed",
|
|
3807
|
-
task_id: task.id,
|
|
3808
|
-
reason: `status_transition:${prevStatus}->${task.status}`
|
|
3809
|
-
}, cwd).catch(() => {
|
|
3810
|
-
});
|
|
3811
|
-
}
|
|
3812
|
-
}
|
|
3813
|
-
for (const worker of workers) {
|
|
3814
|
-
const prevAlive = previousSnapshot.workerAliveByName?.[worker.name];
|
|
3815
|
-
const prevState = previousSnapshot.workerStateByName?.[worker.name];
|
|
3816
|
-
if (prevAlive === true && !worker.alive) {
|
|
3817
|
-
await appendTeamEvent(teamName, {
|
|
3818
|
-
type: "worker_stopped",
|
|
3819
|
-
worker: worker.name,
|
|
3820
|
-
reason: "pane_exited"
|
|
3821
|
-
}, cwd).catch(() => {
|
|
3822
|
-
});
|
|
3823
|
-
}
|
|
3824
|
-
if (prevState === "working" && worker.status.state === "idle") {
|
|
3825
|
-
await appendTeamEvent(teamName, {
|
|
3826
|
-
type: "worker_idle",
|
|
3827
|
-
worker: worker.name,
|
|
3828
|
-
reason: `state_transition:${prevState}->${worker.status.state}`
|
|
3829
|
-
}, cwd).catch(() => {
|
|
3830
|
-
});
|
|
3831
|
-
}
|
|
3832
|
-
}
|
|
3833
|
-
}
|
|
3834
|
-
|
|
3835
4580
|
// src/team/phase-controller.ts
|
|
3836
4581
|
function inferPhase(tasks) {
|
|
3837
4582
|
if (tasks.length === 0) return "initializing";
|
|
@@ -3849,7 +4594,7 @@ function inferPhase(tasks) {
|
|
|
3849
4594
|
if (pending.length === tasks.length && genuinelyCompleted.length === 0 && allFailed.length === 0) {
|
|
3850
4595
|
return "planning";
|
|
3851
4596
|
}
|
|
3852
|
-
if (pending.length > 0 && genuinelyCompleted.length > 0 && inProgress.length === 0) {
|
|
4597
|
+
if (pending.length > 0 && genuinelyCompleted.length > 0 && inProgress.length === 0 && allFailed.length === 0) {
|
|
3853
4598
|
return "executing";
|
|
3854
4599
|
}
|
|
3855
4600
|
if (allFailed.length > 0) {
|
|
@@ -3875,7 +4620,7 @@ init_tmux_session();
|
|
|
3875
4620
|
|
|
3876
4621
|
// src/team/dispatch-queue.ts
|
|
3877
4622
|
var import_crypto2 = require("crypto");
|
|
3878
|
-
var
|
|
4623
|
+
var import_fs15 = require("fs");
|
|
3879
4624
|
var import_promises6 = require("fs/promises");
|
|
3880
4625
|
var import_path15 = require("path");
|
|
3881
4626
|
|
|
@@ -3910,7 +4655,7 @@ function resolveDispatchLockTimeoutMs(env = process.env) {
|
|
|
3910
4655
|
}
|
|
3911
4656
|
async function withDispatchLock(teamName, cwd, fn) {
|
|
3912
4657
|
const root = absPath(cwd, TeamPaths.root(teamName));
|
|
3913
|
-
if (!(0,
|
|
4658
|
+
if (!(0, import_fs15.existsSync)(root)) throw new Error(`Team ${teamName} not found`);
|
|
3914
4659
|
const lockDir = absPath(cwd, TeamPaths.dispatchLockDir(teamName));
|
|
3915
4660
|
const ownerPath = (0, import_path15.join)(lockDir, "owner");
|
|
3916
4661
|
const ownerToken = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
|
|
@@ -3962,10 +4707,10 @@ async function withDispatchLock(teamName, cwd, fn) {
|
|
|
3962
4707
|
}
|
|
3963
4708
|
}
|
|
3964
4709
|
async function readDispatchRequestsFromFile(teamName, cwd) {
|
|
3965
|
-
const
|
|
4710
|
+
const path4 = absPath(cwd, TeamPaths.dispatchRequests(teamName));
|
|
3966
4711
|
try {
|
|
3967
|
-
if (!(0,
|
|
3968
|
-
const raw = await (0, import_promises6.readFile)(
|
|
4712
|
+
if (!(0, import_fs15.existsSync)(path4)) return [];
|
|
4713
|
+
const raw = await (0, import_promises6.readFile)(path4, "utf8");
|
|
3969
4714
|
const parsed = JSON.parse(raw);
|
|
3970
4715
|
if (!Array.isArray(parsed)) return [];
|
|
3971
4716
|
return parsed.map((entry) => normalizeDispatchRequest(teamName, entry)).filter((req) => req !== null);
|
|
@@ -3974,10 +4719,10 @@ async function readDispatchRequestsFromFile(teamName, cwd) {
|
|
|
3974
4719
|
}
|
|
3975
4720
|
}
|
|
3976
4721
|
async function writeDispatchRequestsToFile(teamName, requests, cwd) {
|
|
3977
|
-
const
|
|
3978
|
-
const dir = (0, import_path15.dirname)(
|
|
4722
|
+
const path4 = absPath(cwd, TeamPaths.dispatchRequests(teamName));
|
|
4723
|
+
const dir = (0, import_path15.dirname)(path4);
|
|
3979
4724
|
ensureDirWithMode(dir);
|
|
3980
|
-
atomicWriteJson(
|
|
4725
|
+
atomicWriteJson(path4, requests);
|
|
3981
4726
|
}
|
|
3982
4727
|
function normalizeDispatchRequest(teamName, raw, nowIso = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
3983
4728
|
if (!isDispatchKind(raw.kind)) return null;
|
|
@@ -4110,6 +4855,9 @@ function notifyExceptionReason(error) {
|
|
|
4110
4855
|
async function markImmediateDispatchFailure(params) {
|
|
4111
4856
|
const { teamName, request, reason, messageId, cwd } = params;
|
|
4112
4857
|
if (request.transport_preference === "hook_preferred_with_fallback") return;
|
|
4858
|
+
const logTransitionFailure = createSwallowedErrorLogger(
|
|
4859
|
+
"team.mcp-comm.markImmediateDispatchFailure transitionDispatchRequest failed"
|
|
4860
|
+
);
|
|
4113
4861
|
const current = await readDispatchRequest(teamName, request.request_id, cwd);
|
|
4114
4862
|
if (!current) return;
|
|
4115
4863
|
if (current.status === "failed" || current.status === "notified" || current.status === "delivered") return;
|
|
@@ -4123,11 +4871,9 @@ async function markImmediateDispatchFailure(params) {
|
|
|
4123
4871
|
last_reason: reason
|
|
4124
4872
|
},
|
|
4125
4873
|
cwd
|
|
4126
|
-
).catch(
|
|
4127
|
-
});
|
|
4874
|
+
).catch(logTransitionFailure);
|
|
4128
4875
|
}
|
|
4129
4876
|
async function queueInboxInstruction(params) {
|
|
4130
|
-
await params.deps.writeWorkerInbox(params.teamName, params.workerName, params.inbox, params.cwd);
|
|
4131
4877
|
const queued = await enqueueDispatchRequest(
|
|
4132
4878
|
params.teamName,
|
|
4133
4879
|
{
|
|
@@ -4150,6 +4896,17 @@ async function queueInboxInstruction(params) {
|
|
|
4150
4896
|
request_id: queued.request.request_id
|
|
4151
4897
|
};
|
|
4152
4898
|
}
|
|
4899
|
+
try {
|
|
4900
|
+
await params.deps.writeWorkerInbox(params.teamName, params.workerName, params.inbox, params.cwd);
|
|
4901
|
+
} catch (error) {
|
|
4902
|
+
await markImmediateDispatchFailure({
|
|
4903
|
+
teamName: params.teamName,
|
|
4904
|
+
request: queued.request,
|
|
4905
|
+
reason: "inbox_write_failed",
|
|
4906
|
+
cwd: params.cwd
|
|
4907
|
+
});
|
|
4908
|
+
throw error;
|
|
4909
|
+
}
|
|
4153
4910
|
const notifyOutcome = await Promise.resolve(params.notify(
|
|
4154
4911
|
{ workerName: params.workerName, workerIndex: params.workerIndex, paneId: params.paneId },
|
|
4155
4912
|
params.triggerMessage,
|
|
@@ -4187,7 +4944,9 @@ function isRuntimeV2Enabled(env = process.env) {
|
|
|
4187
4944
|
}
|
|
4188
4945
|
var MONITOR_SIGNAL_STALE_MS = 3e4;
|
|
4189
4946
|
function sanitizeTeamName(name) {
|
|
4190
|
-
|
|
4947
|
+
const sanitized = name.toLowerCase().replace(/[^a-z0-9-]/g, "").slice(0, 30);
|
|
4948
|
+
if (!sanitized) throw new Error(`Invalid team name: "${name}" produces empty slug after sanitization`);
|
|
4949
|
+
return sanitized;
|
|
4191
4950
|
}
|
|
4192
4951
|
async function isWorkerPaneAlive(paneId) {
|
|
4193
4952
|
if (!paneId) return false;
|
|
@@ -4201,7 +4960,7 @@ async function isWorkerPaneAlive(paneId) {
|
|
|
4201
4960
|
async function captureWorkerPane(paneId) {
|
|
4202
4961
|
if (!paneId) return "";
|
|
4203
4962
|
return await new Promise((resolve5) => {
|
|
4204
|
-
(0,
|
|
4963
|
+
(0, import_child_process5.execFile)("tmux", ["capture-pane", "-t", paneId, "-p", "-S", "-80"], (err, stdout) => {
|
|
4205
4964
|
if (err) resolve5("");
|
|
4206
4965
|
else resolve5(stdout ?? "");
|
|
4207
4966
|
});
|
|
@@ -4226,19 +4985,29 @@ function findOutstandingWorkerTask(worker, taskById, inProgressByOwner) {
|
|
|
4226
4985
|
return owned[0] ?? null;
|
|
4227
4986
|
}
|
|
4228
4987
|
function buildV2TaskInstruction(teamName, workerName2, task, taskId) {
|
|
4988
|
+
const claimTaskCommand = formatOmcCliInvocation(
|
|
4989
|
+
`team api claim-task --input '${JSON.stringify({ team_name: teamName, task_id: taskId, worker: workerName2 })}' --json`,
|
|
4990
|
+
{}
|
|
4991
|
+
);
|
|
4992
|
+
const completeTaskCommand = formatOmcCliInvocation(
|
|
4993
|
+
`team api transition-task-status --input '${JSON.stringify({ team_name: teamName, task_id: taskId, from: "in_progress", to: "completed", claim_token: "<claim_token>" })}' --json`
|
|
4994
|
+
);
|
|
4995
|
+
const failTaskCommand = formatOmcCliInvocation(
|
|
4996
|
+
`team api transition-task-status --input '${JSON.stringify({ team_name: teamName, task_id: taskId, from: "in_progress", to: "failed", claim_token: "<claim_token>" })}' --json`
|
|
4997
|
+
);
|
|
4229
4998
|
return [
|
|
4230
4999
|
`## REQUIRED: Task Lifecycle Commands`,
|
|
4231
5000
|
`You MUST run these commands. Do NOT skip any step.`,
|
|
4232
5001
|
``,
|
|
4233
5002
|
`1. Claim your task:`,
|
|
4234
|
-
`
|
|
5003
|
+
` ${claimTaskCommand}`,
|
|
4235
5004
|
` Save the claim_token from the response.`,
|
|
4236
5005
|
`2. Do the work described below.`,
|
|
4237
5006
|
`3. On completion (use claim_token from step 1):`,
|
|
4238
|
-
`
|
|
5007
|
+
` ${completeTaskCommand}`,
|
|
4239
5008
|
`4. On failure (use claim_token from step 1):`,
|
|
4240
|
-
`
|
|
4241
|
-
`5.
|
|
5009
|
+
` ${failTaskCommand}`,
|
|
5010
|
+
`5. ACK/progress replies are not a stop signal. Keep executing your assigned or next feasible work until the task is actually complete or failed, then transition and exit.`,
|
|
4242
5011
|
``,
|
|
4243
5012
|
`## Task Assignment`,
|
|
4244
5013
|
`Task ID: ${taskId}`,
|
|
@@ -4278,16 +5047,16 @@ async function hasWorkerTaskClaimEvidence(teamName, workerName2, cwd, taskId) {
|
|
|
4278
5047
|
return false;
|
|
4279
5048
|
}
|
|
4280
5049
|
}
|
|
4281
|
-
async function
|
|
5050
|
+
async function hasWorkerStartupEvidence(teamName, workerName2, taskId, cwd) {
|
|
4282
5051
|
const [hasClaimEvidence, status] = await Promise.all([
|
|
4283
5052
|
hasWorkerTaskClaimEvidence(teamName, workerName2, cwd, taskId),
|
|
4284
5053
|
readWorkerStatus(teamName, workerName2, cwd)
|
|
4285
5054
|
]);
|
|
4286
5055
|
return hasClaimEvidence || hasWorkerStatusProgress(status, taskId);
|
|
4287
5056
|
}
|
|
4288
|
-
async function
|
|
5057
|
+
async function waitForWorkerStartupEvidence(teamName, workerName2, taskId, cwd, attempts = 3, delayMs = 250) {
|
|
4289
5058
|
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
4290
|
-
if (await
|
|
5059
|
+
if (await hasWorkerStartupEvidence(teamName, workerName2, taskId, cwd)) {
|
|
4291
5060
|
return true;
|
|
4292
5061
|
}
|
|
4293
5062
|
if (attempt < attempts) {
|
|
@@ -4297,12 +5066,12 @@ async function waitForClaudeStartupEvidence(teamName, workerName2, taskId, cwd,
|
|
|
4297
5066
|
return false;
|
|
4298
5067
|
}
|
|
4299
5068
|
async function spawnV2Worker(opts) {
|
|
4300
|
-
const { execFile:
|
|
4301
|
-
const { promisify:
|
|
4302
|
-
const
|
|
5069
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
5070
|
+
const { promisify: promisify3 } = await import("util");
|
|
5071
|
+
const execFileAsync2 = promisify3(execFile4);
|
|
4303
5072
|
const splitTarget = opts.existingWorkerPaneIds.length === 0 ? opts.leaderPaneId : opts.existingWorkerPaneIds[opts.existingWorkerPaneIds.length - 1];
|
|
4304
5073
|
const splitType = opts.existingWorkerPaneIds.length === 0 ? "-h" : "-v";
|
|
4305
|
-
const splitResult = await
|
|
5074
|
+
const splitResult = await execFileAsync2("tmux", [
|
|
4306
5075
|
"split-window",
|
|
4307
5076
|
splitType,
|
|
4308
5077
|
"-t",
|
|
@@ -4325,7 +5094,6 @@ async function spawnV2Worker(opts) {
|
|
|
4325
5094
|
opts.task,
|
|
4326
5095
|
opts.taskId
|
|
4327
5096
|
);
|
|
4328
|
-
const relInboxPath = `.omc/state/team/${opts.teamName}/workers/${opts.workerName}/inbox.md`;
|
|
4329
5097
|
const inboxTriggerMessage = generateTriggerMessage(opts.teamName, opts.workerName);
|
|
4330
5098
|
if (usePromptMode) {
|
|
4331
5099
|
await composeInitialInbox(opts.teamName, opts.workerName, instruction, opts.cwd);
|
|
@@ -4343,7 +5111,7 @@ async function spawnV2Worker(opts) {
|
|
|
4343
5111
|
if (opts.agentType === "gemini") {
|
|
4344
5112
|
return process.env.OMC_EXTERNAL_MODELS_DEFAULT_GEMINI_MODEL || process.env.OMC_GEMINI_DEFAULT_MODEL || void 0;
|
|
4345
5113
|
}
|
|
4346
|
-
return
|
|
5114
|
+
return resolveClaudeWorkerModel();
|
|
4347
5115
|
})();
|
|
4348
5116
|
const [launchBinary, ...launchArgs] = buildWorkerArgv(opts.agentType, {
|
|
4349
5117
|
teamName: opts.teamName,
|
|
@@ -4353,11 +5121,7 @@ async function spawnV2Worker(opts) {
|
|
|
4353
5121
|
model: modelForAgent
|
|
4354
5122
|
});
|
|
4355
5123
|
if (usePromptMode) {
|
|
4356
|
-
|
|
4357
|
-
opts.agentType,
|
|
4358
|
-
inboxTriggerMessage
|
|
4359
|
-
);
|
|
4360
|
-
launchArgs.push(...promptArgs);
|
|
5124
|
+
launchArgs.push(...getPromptModeArgs(opts.agentType, instruction));
|
|
4361
5125
|
}
|
|
4362
5126
|
const paneConfig = {
|
|
4363
5127
|
teamName: opts.teamName,
|
|
@@ -4369,7 +5133,7 @@ async function spawnV2Worker(opts) {
|
|
|
4369
5133
|
};
|
|
4370
5134
|
await spawnWorkerInPane(opts.sessionName, paneId, paneConfig);
|
|
4371
5135
|
try {
|
|
4372
|
-
await
|
|
5136
|
+
await execFileAsync2("tmux", [
|
|
4373
5137
|
"select-layout",
|
|
4374
5138
|
"-t",
|
|
4375
5139
|
opts.sessionName,
|
|
@@ -4423,7 +5187,7 @@ async function spawnV2Worker(opts) {
|
|
|
4423
5187
|
};
|
|
4424
5188
|
}
|
|
4425
5189
|
if (opts.agentType === "claude") {
|
|
4426
|
-
const settled = await
|
|
5190
|
+
const settled = await waitForWorkerStartupEvidence(
|
|
4427
5191
|
opts.teamName,
|
|
4428
5192
|
opts.workerName,
|
|
4429
5193
|
opts.taskId,
|
|
@@ -4438,7 +5202,7 @@ async function spawnV2Worker(opts) {
|
|
|
4438
5202
|
startupFailureReason: `${renotified.reason}:startup_evidence_missing`
|
|
4439
5203
|
};
|
|
4440
5204
|
}
|
|
4441
|
-
const settledAfterRetry = await
|
|
5205
|
+
const settledAfterRetry = await waitForWorkerStartupEvidence(
|
|
4442
5206
|
opts.teamName,
|
|
4443
5207
|
opts.workerName,
|
|
4444
5208
|
opts.taskId,
|
|
@@ -4453,6 +5217,21 @@ async function spawnV2Worker(opts) {
|
|
|
4453
5217
|
}
|
|
4454
5218
|
}
|
|
4455
5219
|
}
|
|
5220
|
+
if (usePromptMode) {
|
|
5221
|
+
const settled = await waitForWorkerStartupEvidence(
|
|
5222
|
+
opts.teamName,
|
|
5223
|
+
opts.workerName,
|
|
5224
|
+
opts.taskId,
|
|
5225
|
+
opts.cwd
|
|
5226
|
+
);
|
|
5227
|
+
if (!settled) {
|
|
5228
|
+
return {
|
|
5229
|
+
paneId,
|
|
5230
|
+
startupAssigned: false,
|
|
5231
|
+
startupFailureReason: `${opts.agentType}_startup_evidence_missing`
|
|
5232
|
+
};
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
4456
5235
|
return {
|
|
4457
5236
|
paneId,
|
|
4458
5237
|
startupAssigned: true
|
|
@@ -4484,10 +5263,35 @@ async function startTeamV2(config) {
|
|
|
4484
5263
|
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4485
5264
|
}, null, 2), "utf-8");
|
|
4486
5265
|
}
|
|
4487
|
-
const workerNames =
|
|
5266
|
+
const workerNames = Array.from({ length: config.workerCount }, (_, index) => `worker-${index + 1}`);
|
|
5267
|
+
const workerNameSet = new Set(workerNames);
|
|
5268
|
+
const startupAllocations = [];
|
|
5269
|
+
const unownedTaskIndices = [];
|
|
4488
5270
|
for (let i = 0; i < config.tasks.length; i++) {
|
|
4489
|
-
const
|
|
4490
|
-
|
|
5271
|
+
const owner = config.tasks[i]?.owner;
|
|
5272
|
+
if (typeof owner === "string" && workerNameSet.has(owner)) {
|
|
5273
|
+
startupAllocations.push({ workerName: owner, taskIndex: i });
|
|
5274
|
+
} else {
|
|
5275
|
+
unownedTaskIndices.push(i);
|
|
5276
|
+
}
|
|
5277
|
+
}
|
|
5278
|
+
if (unownedTaskIndices.length > 0) {
|
|
5279
|
+
const allocationTasks = unownedTaskIndices.map((idx) => ({
|
|
5280
|
+
id: String(idx),
|
|
5281
|
+
subject: config.tasks[idx].subject,
|
|
5282
|
+
description: config.tasks[idx].description
|
|
5283
|
+
}));
|
|
5284
|
+
const allocationWorkers = workerNames.map((name, i) => ({
|
|
5285
|
+
name,
|
|
5286
|
+
role: config.workerRoles?.[i] ?? (agentTypes[i % agentTypes.length] ?? agentTypes[0] ?? "claude"),
|
|
5287
|
+
currentLoad: 0
|
|
5288
|
+
}));
|
|
5289
|
+
for (const r of allocateTasksToWorkers(allocationTasks, allocationWorkers)) {
|
|
5290
|
+
startupAllocations.push({ workerName: r.workerName, taskIndex: Number(r.taskId) });
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
for (let i = 0; i < workerNames.length; i++) {
|
|
5294
|
+
const wName = workerNames[i];
|
|
4491
5295
|
const agentType = agentTypes[i % agentTypes.length] ?? agentTypes[0] ?? "claude";
|
|
4492
5296
|
await ensureWorkerStateDir(sanitized, wName, leaderCwd);
|
|
4493
5297
|
await writeWorkerOverlay({
|
|
@@ -4513,7 +5317,7 @@ async function startTeamV2(config) {
|
|
|
4513
5317
|
const workersInfo = workerNames.map((wName, i) => ({
|
|
4514
5318
|
name: wName,
|
|
4515
5319
|
index: i + 1,
|
|
4516
|
-
role: agentTypes[i % agentTypes.length] ?? agentTypes[0] ?? "claude",
|
|
5320
|
+
role: config.workerRoles?.[i] ?? (agentTypes[i % agentTypes.length] ?? agentTypes[0] ?? "claude"),
|
|
4517
5321
|
assigned_tasks: [],
|
|
4518
5322
|
working_dir: leaderCwd
|
|
4519
5323
|
}));
|
|
@@ -4522,6 +5326,8 @@ async function startTeamV2(config) {
|
|
|
4522
5326
|
task: config.tasks.map((t) => t.subject).join("; "),
|
|
4523
5327
|
agent_type: agentTypes[0] || "claude",
|
|
4524
5328
|
worker_launch_mode: "interactive",
|
|
5329
|
+
policy: DEFAULT_TEAM_TRANSPORT_POLICY,
|
|
5330
|
+
governance: DEFAULT_TEAM_GOVERNANCE,
|
|
4525
5331
|
worker_count: config.workerCount,
|
|
4526
5332
|
max_workers: 20,
|
|
4527
5333
|
workers: workersInfo,
|
|
@@ -4538,20 +5344,60 @@ async function startTeamV2(config) {
|
|
|
4538
5344
|
...ownsWindow ? { workspace_mode: "single" } : {}
|
|
4539
5345
|
};
|
|
4540
5346
|
await saveTeamConfig(teamConfig, leaderCwd);
|
|
4541
|
-
const
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
5347
|
+
const permissionsSnapshot = {
|
|
5348
|
+
approval_mode: process.env.OMC_APPROVAL_MODE || "default",
|
|
5349
|
+
sandbox_mode: process.env.OMC_SANDBOX_MODE || "default",
|
|
5350
|
+
network_access: process.env.OMC_NETWORK_ACCESS === "1"
|
|
5351
|
+
};
|
|
5352
|
+
const teamManifest = {
|
|
5353
|
+
schema_version: 2,
|
|
5354
|
+
name: sanitized,
|
|
5355
|
+
task: teamConfig.task,
|
|
5356
|
+
leader: {
|
|
5357
|
+
session_id: sessionName2,
|
|
5358
|
+
worker_id: "leader-fixed",
|
|
5359
|
+
role: "leader"
|
|
5360
|
+
},
|
|
5361
|
+
policy: DEFAULT_TEAM_TRANSPORT_POLICY,
|
|
5362
|
+
governance: DEFAULT_TEAM_GOVERNANCE,
|
|
5363
|
+
permissions_snapshot: permissionsSnapshot,
|
|
5364
|
+
tmux_session: sessionName2,
|
|
5365
|
+
worker_count: teamConfig.worker_count,
|
|
5366
|
+
workers: workersInfo,
|
|
5367
|
+
next_task_id: teamConfig.next_task_id,
|
|
5368
|
+
created_at: teamConfig.created_at,
|
|
5369
|
+
leader_cwd: leaderCwd,
|
|
5370
|
+
team_state_root: teamConfig.team_state_root,
|
|
5371
|
+
workspace_mode: teamConfig.workspace_mode,
|
|
5372
|
+
leader_pane_id: leaderPaneId,
|
|
5373
|
+
hud_pane_id: null,
|
|
5374
|
+
resize_hook_name: null,
|
|
5375
|
+
resize_hook_target: null,
|
|
5376
|
+
next_worker_index: teamConfig.next_worker_index
|
|
5377
|
+
};
|
|
5378
|
+
await (0, import_promises7.writeFile)(absPath(leaderCwd, TeamPaths.manifest(sanitized)), JSON.stringify(teamManifest, null, 2), "utf-8");
|
|
5379
|
+
const initialStartupAllocations = [];
|
|
5380
|
+
const seenStartupWorkers = /* @__PURE__ */ new Set();
|
|
5381
|
+
for (const decision of startupAllocations) {
|
|
5382
|
+
if (seenStartupWorkers.has(decision.workerName)) continue;
|
|
5383
|
+
initialStartupAllocations.push(decision);
|
|
5384
|
+
seenStartupWorkers.add(decision.workerName);
|
|
5385
|
+
if (initialStartupAllocations.length >= config.workerCount) break;
|
|
5386
|
+
}
|
|
5387
|
+
for (const decision of initialStartupAllocations) {
|
|
5388
|
+
const wName = decision.workerName;
|
|
5389
|
+
const workerIndex = Number.parseInt(wName.replace("worker-", ""), 10) - 1;
|
|
5390
|
+
const taskId = String(decision.taskIndex + 1);
|
|
5391
|
+
const task = config.tasks[decision.taskIndex];
|
|
5392
|
+
if (!task || workerIndex < 0) continue;
|
|
4547
5393
|
const workerLaunch = await spawnV2Worker({
|
|
4548
5394
|
sessionName: sessionName2,
|
|
4549
5395
|
leaderPaneId,
|
|
4550
5396
|
existingWorkerPaneIds: workerPaneIds,
|
|
4551
5397
|
teamName: sanitized,
|
|
4552
5398
|
workerName: wName,
|
|
4553
|
-
workerIndex
|
|
4554
|
-
agentType: agentTypes[
|
|
5399
|
+
workerIndex,
|
|
5400
|
+
agentType: agentTypes[workerIndex % agentTypes.length] ?? agentTypes[0] ?? "claude",
|
|
4555
5401
|
task,
|
|
4556
5402
|
taskId,
|
|
4557
5403
|
cwd: leaderCwd,
|
|
@@ -4559,7 +5405,7 @@ async function startTeamV2(config) {
|
|
|
4559
5405
|
});
|
|
4560
5406
|
if (workerLaunch.paneId) {
|
|
4561
5407
|
workerPaneIds.push(workerLaunch.paneId);
|
|
4562
|
-
const workerInfo = workersInfo[
|
|
5408
|
+
const workerInfo = workersInfo[workerIndex];
|
|
4563
5409
|
if (workerInfo) {
|
|
4564
5410
|
workerInfo.pane_id = workerLaunch.paneId;
|
|
4565
5411
|
workerInfo.assigned_tasks = workerLaunch.startupAssigned ? [taskId] : [];
|
|
@@ -4728,6 +5574,9 @@ async function monitorTeamV2(teamName, cwd) {
|
|
|
4728
5574
|
};
|
|
4729
5575
|
}
|
|
4730
5576
|
async function shutdownTeamV2(teamName, cwd, options = {}) {
|
|
5577
|
+
const logEventFailure = createSwallowedErrorLogger(
|
|
5578
|
+
"team.runtime-v2.shutdownTeamV2 appendTeamEvent failed"
|
|
5579
|
+
);
|
|
4731
5580
|
const force = options.force === true;
|
|
4732
5581
|
const ralph = options.ralph === true;
|
|
4733
5582
|
const timeoutMs = options.timeoutMs ?? 15e3;
|
|
@@ -4739,6 +5588,7 @@ async function shutdownTeamV2(teamName, cwd, options = {}) {
|
|
|
4739
5588
|
}
|
|
4740
5589
|
if (!force) {
|
|
4741
5590
|
const allTasks = await listTasksFromFiles(sanitized, cwd);
|
|
5591
|
+
const governance = getConfigGovernance(config);
|
|
4742
5592
|
const gate = {
|
|
4743
5593
|
total: allTasks.length,
|
|
4744
5594
|
pending: allTasks.filter((t) => t.status === "pending").length,
|
|
@@ -4753,17 +5603,21 @@ async function shutdownTeamV2(teamName, cwd, options = {}) {
|
|
|
4753
5603
|
type: "shutdown_gate",
|
|
4754
5604
|
worker: "leader-fixed",
|
|
4755
5605
|
reason: `allowed=${gate.allowed} total=${gate.total} pending=${gate.pending} blocked=${gate.blocked} in_progress=${gate.in_progress} completed=${gate.completed} failed=${gate.failed}${ralph ? " policy=ralph" : ""}`
|
|
4756
|
-
}, cwd).catch(
|
|
4757
|
-
});
|
|
5606
|
+
}, cwd).catch(logEventFailure);
|
|
4758
5607
|
if (!gate.allowed) {
|
|
4759
5608
|
const hasActiveWork = gate.pending > 0 || gate.blocked > 0 || gate.in_progress > 0;
|
|
4760
|
-
if (
|
|
5609
|
+
if (!governance.cleanup_requires_all_workers_inactive) {
|
|
5610
|
+
await appendTeamEvent(sanitized, {
|
|
5611
|
+
type: "team_leader_nudge",
|
|
5612
|
+
worker: "leader-fixed",
|
|
5613
|
+
reason: `cleanup_override_bypassed:pending=${gate.pending},blocked=${gate.blocked},in_progress=${gate.in_progress},failed=${gate.failed}`
|
|
5614
|
+
}, cwd).catch(logEventFailure);
|
|
5615
|
+
} else if (ralph && !hasActiveWork) {
|
|
4761
5616
|
await appendTeamEvent(sanitized, {
|
|
4762
5617
|
type: "team_leader_nudge",
|
|
4763
5618
|
worker: "leader-fixed",
|
|
4764
5619
|
reason: `gate_bypassed:pending=${gate.pending},blocked=${gate.blocked},in_progress=${gate.in_progress},failed=${gate.failed}`
|
|
4765
|
-
}, cwd).catch(
|
|
4766
|
-
});
|
|
5620
|
+
}, cwd).catch(logEventFailure);
|
|
4767
5621
|
} else {
|
|
4768
5622
|
throw new Error(
|
|
4769
5623
|
`shutdown_gate_blocked:pending=${gate.pending},blocked=${gate.blocked},in_progress=${gate.in_progress},failed=${gate.failed}`
|
|
@@ -4776,8 +5630,7 @@ async function shutdownTeamV2(teamName, cwd, options = {}) {
|
|
|
4776
5630
|
type: "shutdown_gate_forced",
|
|
4777
5631
|
worker: "leader-fixed",
|
|
4778
5632
|
reason: "force_bypass"
|
|
4779
|
-
}, cwd).catch(
|
|
4780
|
-
});
|
|
5633
|
+
}, cwd).catch(logEventFailure);
|
|
4781
5634
|
}
|
|
4782
5635
|
const shutdownRequestTimes = /* @__PURE__ */ new Map();
|
|
4783
5636
|
for (const w of config.workers) {
|
|
@@ -4813,8 +5666,7 @@ Then exit your session.
|
|
|
4813
5666
|
type: "shutdown_ack",
|
|
4814
5667
|
worker: w.name,
|
|
4815
5668
|
reason: ack.status === "reject" ? `reject:${ack.reason || "no_reason"}` : "accept"
|
|
4816
|
-
}, cwd).catch(
|
|
4817
|
-
});
|
|
5669
|
+
}, cwd).catch(logEventFailure);
|
|
4818
5670
|
if (ack.status === "reject") {
|
|
4819
5671
|
rejected.push({ worker: w.name, reason: ack.reason || "no_reason" });
|
|
4820
5672
|
}
|
|
@@ -4829,9 +5681,14 @@ Then exit your session.
|
|
|
4829
5681
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
4830
5682
|
}
|
|
4831
5683
|
try {
|
|
4832
|
-
const { killWorkerPanes: killWorkerPanes2, killTeamSession: killTeamSession2 } = await Promise.resolve().then(() => (init_tmux_session(), tmux_session_exports));
|
|
4833
|
-
const
|
|
5684
|
+
const { killWorkerPanes: killWorkerPanes2, killTeamSession: killTeamSession2, resolveSplitPaneWorkerPaneIds: resolveSplitPaneWorkerPaneIds2 } = await Promise.resolve().then(() => (init_tmux_session(), tmux_session_exports));
|
|
5685
|
+
const recordedWorkerPaneIds = config.workers.map((w) => w.pane_id).filter((p) => typeof p === "string" && p.trim().length > 0);
|
|
4834
5686
|
const ownsWindow = config.tmux_window_owned === true;
|
|
5687
|
+
const workerPaneIds = ownsWindow ? recordedWorkerPaneIds : await resolveSplitPaneWorkerPaneIds2(
|
|
5688
|
+
config.tmux_session,
|
|
5689
|
+
recordedWorkerPaneIds,
|
|
5690
|
+
config.leader_pane_id ?? void 0
|
|
5691
|
+
);
|
|
4835
5692
|
await killWorkerPanes2({
|
|
4836
5693
|
paneIds: workerPaneIds,
|
|
4837
5694
|
leaderPaneId: config.leader_pane_id ?? void 0,
|
|
@@ -4860,8 +5717,7 @@ Then exit your session.
|
|
|
4860
5717
|
type: "team_leader_nudge",
|
|
4861
5718
|
worker: "leader-fixed",
|
|
4862
5719
|
reason: `ralph_cleanup_summary: total=${finalTasks.length} completed=${completed} failed=${failed} pending=${pending} force=${force}`
|
|
4863
|
-
}, cwd).catch(
|
|
4864
|
-
});
|
|
5720
|
+
}, cwd).catch(logEventFailure);
|
|
4865
5721
|
}
|
|
4866
5722
|
try {
|
|
4867
5723
|
cleanupTeamWorktrees(sanitized, cwd);
|
|
@@ -4944,10 +5800,10 @@ async function writePanesFile(jobId, paneIds, leaderPaneId, sessionName2, ownsWi
|
|
|
4944
5800
|
function collectTaskResults(stateRoot2) {
|
|
4945
5801
|
const tasksDir = (0, import_path17.join)(stateRoot2, "tasks");
|
|
4946
5802
|
try {
|
|
4947
|
-
const files = (0,
|
|
5803
|
+
const files = (0, import_fs17.readdirSync)(tasksDir).filter((f) => f.endsWith(".json"));
|
|
4948
5804
|
return files.map((f) => {
|
|
4949
5805
|
try {
|
|
4950
|
-
const raw = (0,
|
|
5806
|
+
const raw = (0, import_fs17.readFileSync)((0, import_path17.join)(tasksDir, f), "utf-8");
|
|
4951
5807
|
const task = JSON.parse(raw);
|
|
4952
5808
|
return {
|
|
4953
5809
|
taskId: task.id ?? f.replace(".json", ""),
|
|
@@ -4964,6 +5820,9 @@ function collectTaskResults(stateRoot2) {
|
|
|
4964
5820
|
}
|
|
4965
5821
|
async function main() {
|
|
4966
5822
|
const startTime = Date.now();
|
|
5823
|
+
const logLeaderNudgeEventFailure = createSwallowedErrorLogger(
|
|
5824
|
+
"team.runtime-cli main appendTeamEvent failed"
|
|
5825
|
+
);
|
|
4967
5826
|
const chunks = [];
|
|
4968
5827
|
for await (const chunk of process.stdin) {
|
|
4969
5828
|
chunks.push(chunk);
|
|
@@ -5108,6 +5967,7 @@ async function main() {
|
|
|
5108
5967
|
}
|
|
5109
5968
|
if (useV2) {
|
|
5110
5969
|
process.stderr.write("[runtime-cli] Using runtime v2 (event-driven, no watchdog)\n");
|
|
5970
|
+
let lastLeaderNudgeReason = "";
|
|
5111
5971
|
while (pollActive) {
|
|
5112
5972
|
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
5113
5973
|
if (!pollActive) break;
|
|
@@ -5132,6 +5992,38 @@ async function main() {
|
|
|
5132
5992
|
`[runtime-cli/v2] phase=${snap.phase} pending=${snap.tasks.pending} in_progress=${snap.tasks.in_progress} completed=${snap.tasks.completed} failed=${snap.tasks.failed} dead=${snap.deadWorkers.length} totalMs=${snap.performance.total_ms}
|
|
5133
5993
|
`
|
|
5134
5994
|
);
|
|
5995
|
+
const leaderGuidance = deriveTeamLeaderGuidance({
|
|
5996
|
+
tasks: {
|
|
5997
|
+
pending: snap.tasks.pending,
|
|
5998
|
+
blocked: snap.tasks.blocked,
|
|
5999
|
+
inProgress: snap.tasks.in_progress,
|
|
6000
|
+
completed: snap.tasks.completed,
|
|
6001
|
+
failed: snap.tasks.failed
|
|
6002
|
+
},
|
|
6003
|
+
workers: {
|
|
6004
|
+
total: snap.workers.length,
|
|
6005
|
+
alive: snap.workers.filter((worker) => worker.alive).length,
|
|
6006
|
+
idle: snap.workers.filter((worker) => worker.alive && (worker.status.state === "idle" || worker.status.state === "done")).length,
|
|
6007
|
+
nonReporting: snap.nonReportingWorkers.length
|
|
6008
|
+
}
|
|
6009
|
+
});
|
|
6010
|
+
process.stderr.write(
|
|
6011
|
+
`[runtime-cli/v2] leader_next_action=${leaderGuidance.nextAction} reason=${leaderGuidance.reason}
|
|
6012
|
+
`
|
|
6013
|
+
);
|
|
6014
|
+
if (leaderGuidance.nextAction === "keep-checking-status") {
|
|
6015
|
+
lastLeaderNudgeReason = "";
|
|
6016
|
+
}
|
|
6017
|
+
if (leaderGuidance.nextAction !== "keep-checking-status" && leaderGuidance.reason !== lastLeaderNudgeReason) {
|
|
6018
|
+
await appendTeamEvent(teamName, {
|
|
6019
|
+
type: "team_leader_nudge",
|
|
6020
|
+
worker: "leader-fixed",
|
|
6021
|
+
reason: leaderGuidance.reason,
|
|
6022
|
+
next_action: leaderGuidance.nextAction,
|
|
6023
|
+
message: leaderGuidance.message
|
|
6024
|
+
}, cwd).catch(logLeaderNudgeEventFailure);
|
|
6025
|
+
lastLeaderNudgeReason = leaderGuidance.reason;
|
|
6026
|
+
}
|
|
5135
6027
|
const v2Observed = snap.tasks.pending + snap.tasks.in_progress + snap.tasks.completed + snap.tasks.failed;
|
|
5136
6028
|
if (v2Observed !== expectedTaskCount) {
|
|
5137
6029
|
mismatchStreak += 1;
|