claudecode-omc 4.4.5 → 4.4.6
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/.mcp.json +2 -6
- package/README.es.md +64 -8
- package/README.ja.md +64 -8
- package/README.ko.md +64 -8
- package/README.pt.md +29 -0
- package/README.vi.md +29 -0
- package/README.zh.md +64 -8
- package/agents/architect.md +17 -7
- package/agents/code-reviewer.md +6 -7
- package/agents/critic.md +14 -1
- package/agents/deep-executor.md +6 -7
- package/agents/designer.md +6 -8
- package/agents/executor.md +6 -7
- package/agents/planner.md +21 -0
- package/agents/quality-reviewer.md +6 -7
- package/agents/security-reviewer.md +6 -7
- package/agents/test-engineer.md +6 -7
- package/bridge/mcp-server.cjs +517 -202
- package/bridge/runtime-cli.cjs +1547 -0
- package/bridge/team-bridge.cjs +348 -92
- package/bridge/{gemini-server.cjs → team-mcp.cjs} +10914 -10240
- package/dist/__tests__/auto-update.test.js +1 -1
- package/dist/__tests__/auto-update.test.js.map +1 -1
- package/dist/__tests__/cli-win32-warning.test.d.ts +2 -0
- package/dist/__tests__/cli-win32-warning.test.d.ts.map +1 -0
- package/dist/__tests__/cli-win32-warning.test.js +46 -0
- package/dist/__tests__/cli-win32-warning.test.js.map +1 -0
- package/dist/__tests__/codex-callsite-normalization.test.js +112 -0
- package/dist/__tests__/consensus-execution-handoff.test.d.ts +2 -0
- package/dist/__tests__/consensus-execution-handoff.test.d.ts.map +1 -1
- package/dist/__tests__/consensus-execution-handoff.test.js +48 -0
- package/dist/__tests__/consensus-execution-handoff.test.js.map +1 -1
- package/dist/__tests__/context-safety.test.d.ts +2 -0
- package/dist/__tests__/context-safety.test.d.ts.map +1 -0
- package/dist/__tests__/context-safety.test.js +59 -0
- package/dist/__tests__/context-safety.test.js.map +1 -0
- package/dist/__tests__/hooks.test.js +15 -0
- package/dist/__tests__/hooks.test.js.map +1 -1
- package/dist/__tests__/hud/call-counts.test.js +0 -3
- package/dist/__tests__/hud/call-counts.test.js.map +1 -1
- package/dist/__tests__/hud/defaults.test.js +3 -5
- package/dist/__tests__/hud/defaults.test.js.map +1 -1
- package/dist/__tests__/hud/prompt-time.test.d.ts +2 -0
- package/dist/__tests__/hud/prompt-time.test.d.ts.map +1 -0
- package/dist/__tests__/hud/prompt-time.test.js +24 -0
- package/dist/__tests__/hud/prompt-time.test.js.map +1 -0
- package/dist/__tests__/hud/render.test.js +0 -1
- package/dist/__tests__/hud/render.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/windows-platform.test.js +0 -4
- package/dist/__tests__/hud/windows-platform.test.js.map +1 -1
- package/dist/__tests__/hud-windows.test.js +5 -3
- package/dist/__tests__/hud-windows.test.js.map +1 -1
- package/dist/__tests__/installer-hud-skip.test.js +12 -2
- package/dist/__tests__/installer-hud-skip.test.js.map +1 -1
- package/dist/__tests__/job-management-sqlite.test.js +0 -15
- package/dist/__tests__/job-management-sqlite.test.js.map +1 -1
- package/dist/__tests__/job-management.test.js +0 -16
- package/dist/__tests__/job-management.test.js.map +1 -1
- package/dist/__tests__/load-agent-prompt.test.js +0 -23
- package/dist/__tests__/load-agent-prompt.test.js.map +1 -1
- package/dist/__tests__/model-routing.test.js +3 -2
- package/dist/__tests__/model-routing.test.js.map +1 -1
- package/dist/__tests__/omc-tools-server-interop.test.js +1 -1
- package/dist/__tests__/omc-tools-server-interop.test.js.map +1 -1
- package/dist/__tests__/pre-tool-enforcer.test.d.ts +2 -0
- package/dist/__tests__/pre-tool-enforcer.test.d.ts.map +1 -0
- package/dist/__tests__/pre-tool-enforcer.test.js +194 -0
- package/dist/__tests__/pre-tool-enforcer.test.js.map +1 -0
- package/dist/__tests__/prompt-injection.test.js +0 -26
- package/dist/__tests__/prompt-injection.test.js.map +1 -1
- package/dist/__tests__/purge-stale-cache.test.js +3 -2
- package/dist/__tests__/purge-stale-cache.test.js.map +1 -1
- package/dist/__tests__/run-cjs-graceful-fallback.test.d.ts +2 -0
- package/dist/__tests__/run-cjs-graceful-fallback.test.d.ts.map +1 -0
- package/dist/__tests__/run-cjs-graceful-fallback.test.js +167 -0
- package/dist/__tests__/run-cjs-graceful-fallback.test.js.map +1 -0
- package/dist/__tests__/session-start-cache-cleanup.test.d.ts +2 -0
- package/dist/__tests__/session-start-cache-cleanup.test.d.ts.map +1 -0
- package/dist/__tests__/session-start-cache-cleanup.test.js +150 -0
- package/dist/__tests__/session-start-cache-cleanup.test.js.map +1 -0
- package/dist/__tests__/skills.test.js +10 -8
- package/dist/__tests__/skills.test.js.map +1 -1
- package/dist/__tests__/team-server-validation.test.d.ts +2 -0
- package/dist/__tests__/team-server-validation.test.d.ts.map +1 -0
- package/dist/__tests__/team-server-validation.test.js +122 -0
- package/dist/__tests__/team-server-validation.test.js.map +1 -0
- package/dist/agents/index.d.ts +0 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +0 -2
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/prompt-helpers.d.ts +74 -0
- package/dist/agents/prompt-helpers.d.ts.map +1 -0
- package/dist/agents/prompt-helpers.js +187 -0
- package/dist/agents/prompt-helpers.js.map +1 -0
- package/dist/agents/utils.d.ts +1 -5
- package/dist/agents/utils.d.ts.map +1 -1
- package/dist/agents/utils.js +1 -34
- package/dist/agents/utils.js.map +1 -1
- package/dist/cli/__tests__/launch.test.d.ts +1 -2
- package/dist/cli/__tests__/launch.test.d.ts.map +1 -1
- package/dist/cli/__tests__/launch.test.js +442 -48
- package/dist/cli/__tests__/launch.test.js.map +1 -1
- package/dist/cli/__tests__/teleport-help.test.d.ts +2 -0
- package/dist/cli/__tests__/teleport-help.test.d.ts.map +1 -0
- package/dist/cli/__tests__/teleport-help.test.js +17 -0
- package/dist/cli/__tests__/teleport-help.test.js.map +1 -0
- package/dist/cli/commands/teleport.d.ts +2 -1
- package/dist/cli/commands/teleport.d.ts.map +1 -1
- package/dist/cli/commands/teleport.js +6 -3
- package/dist/cli/commands/teleport.js.map +1 -1
- package/dist/cli/index.js +40 -290
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/launch.d.ts +83 -3
- package/dist/cli/launch.d.ts.map +1 -1
- package/dist/cli/launch.js +213 -48
- package/dist/cli/launch.js.map +1 -1
- package/dist/cli/win32-warning.d.ts +6 -0
- package/dist/cli/win32-warning.d.ts.map +1 -0
- package/dist/cli/win32-warning.js +15 -0
- package/dist/cli/win32-warning.js.map +1 -0
- package/dist/config/loader.d.ts +9 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +29 -19
- package/dist/config/loader.js.map +1 -1
- package/dist/config/models.d.ts +33 -0
- package/dist/config/models.d.ts.map +1 -0
- package/dist/config/models.js +49 -0
- package/dist/config/models.js.map +1 -0
- package/dist/constants/names.d.ts +2 -0
- package/dist/constants/names.d.ts.map +1 -1
- package/dist/constants/names.js +2 -0
- package/dist/constants/names.js.map +1 -1
- package/dist/features/auto-update.d.ts.map +1 -1
- package/dist/features/auto-update.js +21 -11
- package/dist/features/auto-update.js.map +1 -1
- package/dist/features/background-agent/manager.d.ts.map +1 -1
- package/dist/features/background-agent/manager.js +1 -2
- package/dist/features/background-agent/manager.js.map +1 -1
- package/dist/features/boulder-state/storage.d.ts.map +1 -1
- package/dist/features/boulder-state/storage.js +9 -5
- package/dist/features/boulder-state/storage.js.map +1 -1
- package/dist/features/boulder-state/types.d.ts +4 -0
- package/dist/features/boulder-state/types.d.ts.map +1 -1
- package/dist/features/builtin-skills/skills.d.ts.map +1 -1
- package/dist/features/builtin-skills/skills.js +25 -78
- package/dist/features/builtin-skills/skills.js.map +1 -1
- package/dist/features/delegation-enforcer.d.ts.map +1 -1
- package/dist/features/delegation-enforcer.js +4 -1
- package/dist/features/delegation-enforcer.js.map +1 -1
- package/dist/features/delegation-routing/__tests__/resolver.test.js +47 -122
- package/dist/features/delegation-routing/__tests__/resolver.test.js.map +1 -1
- package/dist/features/delegation-routing/resolver.d.ts.map +1 -1
- package/dist/features/delegation-routing/resolver.js +24 -47
- package/dist/features/delegation-routing/resolver.js.map +1 -1
- package/dist/features/delegation-routing/types.d.ts.map +1 -1
- package/dist/features/delegation-routing/types.js +2 -0
- package/dist/features/delegation-routing/types.js.map +1 -1
- package/dist/features/model-routing/external-model-policy.d.ts.map +1 -1
- package/dist/features/model-routing/external-model-policy.js.map +1 -1
- package/dist/features/model-routing/router.d.ts.map +1 -1
- package/dist/features/model-routing/router.js +12 -2
- package/dist/features/model-routing/router.js.map +1 -1
- package/dist/features/model-routing/types.d.ts +5 -1
- package/dist/features/model-routing/types.d.ts.map +1 -1
- package/dist/features/model-routing/types.js +7 -6
- package/dist/features/model-routing/types.js.map +1 -1
- package/dist/features/rate-limit-wait/daemon.d.ts.map +1 -1
- package/dist/features/rate-limit-wait/daemon.js +40 -4
- package/dist/features/rate-limit-wait/daemon.js.map +1 -1
- package/dist/features/task-decomposer/index.js +14 -4
- package/dist/features/task-decomposer/index.js.map +1 -1
- package/dist/hooks/__tests__/bridge-openclaw.test.d.ts +2 -0
- package/dist/hooks/__tests__/bridge-openclaw.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/bridge-openclaw.test.js +124 -0
- package/dist/hooks/__tests__/bridge-openclaw.test.js.map +1 -0
- package/dist/hooks/__tests__/bridge-security.test.js +1 -1
- package/dist/hooks/__tests__/bridge-security.test.js.map +1 -1
- package/dist/hooks/auto-slash-command/executor.d.ts.map +1 -1
- package/dist/hooks/auto-slash-command/executor.js +38 -61
- package/dist/hooks/auto-slash-command/executor.js.map +1 -1
- package/dist/hooks/bridge.d.ts +11 -0
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +154 -82
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/comment-checker/index.d.ts.map +1 -1
- package/dist/hooks/comment-checker/index.js +3 -1
- package/dist/hooks/comment-checker/index.js.map +1 -1
- package/dist/hooks/keyword-detector/__tests__/index.test.js +348 -1
- package/dist/hooks/keyword-detector/__tests__/index.test.js.map +1 -1
- package/dist/hooks/keyword-detector/index.d.ts +29 -0
- package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
- package/dist/hooks/keyword-detector/index.js +123 -1
- package/dist/hooks/keyword-detector/index.js.map +1 -1
- package/dist/hooks/mode-registry/__tests__/session-isolation.test.js +40 -0
- package/dist/hooks/mode-registry/__tests__/session-isolation.test.js.map +1 -1
- package/dist/hooks/mode-registry/index.d.ts.map +1 -1
- package/dist/hooks/mode-registry/index.js +135 -52
- package/dist/hooks/mode-registry/index.js.map +1 -1
- package/dist/hooks/notepad/index.d.ts.map +1 -1
- package/dist/hooks/notepad/index.js +5 -3
- package/dist/hooks/notepad/index.js.map +1 -1
- package/dist/hooks/persistent-mode/__tests__/cancel-race.test.d.ts +2 -0
- package/dist/hooks/persistent-mode/__tests__/cancel-race.test.d.ts.map +1 -0
- package/dist/hooks/persistent-mode/__tests__/cancel-race.test.js +73 -0
- package/dist/hooks/persistent-mode/__tests__/cancel-race.test.js.map +1 -0
- package/dist/hooks/persistent-mode/__tests__/idle-cooldown.test.js +89 -13
- package/dist/hooks/persistent-mode/__tests__/idle-cooldown.test.js.map +1 -1
- package/dist/hooks/persistent-mode/__tests__/skill-state-stop.test.d.ts +2 -0
- package/dist/hooks/persistent-mode/__tests__/skill-state-stop.test.d.ts.map +1 -0
- package/dist/hooks/persistent-mode/__tests__/skill-state-stop.test.js +156 -0
- package/dist/hooks/persistent-mode/__tests__/skill-state-stop.test.js.map +1 -0
- package/dist/hooks/persistent-mode/idle-cooldown.test.d.ts +2 -3
- package/dist/hooks/persistent-mode/idle-cooldown.test.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/idle-cooldown.test.js +19 -4
- package/dist/hooks/persistent-mode/idle-cooldown.test.js.map +1 -1
- package/dist/hooks/persistent-mode/index.d.ts +2 -2
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +144 -26
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/plugin-patterns/index.d.ts.map +1 -1
- package/dist/hooks/plugin-patterns/index.js +22 -31
- package/dist/hooks/plugin-patterns/index.js.map +1 -1
- package/dist/hooks/pre-compact/index.js +1 -1
- package/dist/hooks/preemptive-compaction/index.d.ts.map +1 -1
- package/dist/hooks/preemptive-compaction/index.js +3 -1
- package/dist/hooks/preemptive-compaction/index.js.map +1 -1
- package/dist/hooks/project-memory/index.d.ts.map +1 -1
- package/dist/hooks/project-memory/index.js +9 -0
- package/dist/hooks/project-memory/index.js.map +1 -1
- package/dist/hooks/project-memory/learner.d.ts.map +1 -1
- package/dist/hooks/project-memory/learner.js +107 -85
- package/dist/hooks/project-memory/learner.js.map +1 -1
- package/dist/hooks/project-memory/storage.d.ts.map +1 -1
- package/dist/hooks/project-memory/storage.js +3 -2
- package/dist/hooks/project-memory/storage.js.map +1 -1
- package/dist/hooks/recovery/context-window.d.ts +4 -0
- package/dist/hooks/recovery/context-window.d.ts.map +1 -1
- package/dist/hooks/recovery/context-window.js +22 -1
- package/dist/hooks/recovery/context-window.js.map +1 -1
- package/dist/hooks/recovery/session-recovery.js +1 -1
- package/dist/hooks/recovery/session-recovery.js.map +1 -1
- package/dist/hooks/session-end/index.d.ts.map +1 -1
- package/dist/hooks/session-end/index.js +13 -22
- package/dist/hooks/session-end/index.js.map +1 -1
- package/dist/hooks/setup/__tests__/windows-patch.test.d.ts +2 -0
- package/dist/hooks/setup/__tests__/windows-patch.test.d.ts.map +1 -0
- package/dist/hooks/setup/__tests__/windows-patch.test.js +110 -0
- package/dist/hooks/setup/__tests__/windows-patch.test.js.map +1 -0
- package/dist/hooks/setup/index.d.ts +18 -0
- package/dist/hooks/setup/index.d.ts.map +1 -1
- package/dist/hooks/setup/index.js +59 -1
- package/dist/hooks/setup/index.js.map +1 -1
- package/dist/hooks/skill-bridge.cjs +1 -0
- package/dist/hooks/skill-state/__tests__/skill-state.test.d.ts +2 -0
- package/dist/hooks/skill-state/__tests__/skill-state.test.d.ts.map +1 -0
- package/dist/hooks/skill-state/__tests__/skill-state.test.js +301 -0
- package/dist/hooks/skill-state/__tests__/skill-state.test.js.map +1 -0
- package/dist/hooks/skill-state/index.d.ts +79 -0
- package/dist/hooks/skill-state/index.d.ts.map +1 -0
- package/dist/hooks/skill-state/index.js +245 -0
- package/dist/hooks/skill-state/index.js.map +1 -0
- package/dist/hooks/team-pipeline/state.d.ts.map +1 -1
- package/dist/hooks/team-pipeline/state.js +5 -0
- package/dist/hooks/team-pipeline/state.js.map +1 -1
- package/dist/hooks/todo-continuation/index.d.ts +17 -0
- package/dist/hooks/todo-continuation/index.d.ts.map +1 -1
- package/dist/hooks/todo-continuation/index.js +44 -2
- package/dist/hooks/todo-continuation/index.js.map +1 -1
- package/dist/hud/elements/call-counts.d.ts.map +1 -1
- package/dist/hud/elements/call-counts.js +6 -4
- package/dist/hud/elements/call-counts.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/prompt-time.d.ts +13 -0
- package/dist/hud/elements/prompt-time.d.ts.map +1 -0
- package/dist/hud/elements/prompt-time.js +21 -0
- package/dist/hud/elements/prompt-time.js.map +1 -0
- package/dist/hud/index.d.ts +2 -1
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +40 -215
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +7 -108
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +4 -3
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/stdin.d.ts +10 -0
- package/dist/hud/stdin.d.ts.map +1 -1
- package/dist/hud/stdin.js +43 -0
- package/dist/hud/stdin.js.map +1 -1
- package/dist/hud/types.d.ts +6 -18
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js +6 -46
- package/dist/hud/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -11
- package/dist/index.js.map +1 -1
- package/dist/installer/hooks.d.ts +5 -0
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +8 -0
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +26 -11
- package/dist/installer/index.js.map +1 -1
- package/dist/interop/omx-team-state.d.ts.map +1 -1
- package/dist/interop/omx-team-state.js +38 -6
- 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 +58 -7
- package/dist/interop/shared-state.js.map +1 -1
- package/dist/lib/__tests__/worktree-paths.test.js +250 -1
- package/dist/lib/__tests__/worktree-paths.test.js.map +1 -1
- package/dist/lib/job-state-db.d.ts +150 -0
- package/dist/lib/job-state-db.d.ts.map +1 -0
- package/dist/lib/job-state-db.js +650 -0
- package/dist/lib/job-state-db.js.map +1 -0
- package/dist/lib/mode-names.d.ts +46 -0
- package/dist/lib/mode-names.d.ts.map +1 -0
- package/dist/lib/mode-names.js +73 -0
- package/dist/lib/mode-names.js.map +1 -0
- package/dist/lib/session-isolation.d.ts +32 -0
- package/dist/lib/session-isolation.d.ts.map +1 -0
- package/dist/lib/session-isolation.js +39 -0
- package/dist/lib/session-isolation.js.map +1 -0
- package/dist/lib/worktree-paths.d.ts +38 -8
- package/dist/lib/worktree-paths.d.ts.map +1 -1
- package/dist/lib/worktree-paths.js +124 -56
- package/dist/lib/worktree-paths.js.map +1 -1
- package/dist/mcp/__tests__/team-cleanup.test.d.ts +11 -0
- package/dist/mcp/__tests__/team-cleanup.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/team-cleanup.test.js +228 -0
- package/dist/mcp/__tests__/team-cleanup.test.js.map +1 -0
- package/dist/mcp/cli-detection.d.ts +4 -8
- package/dist/mcp/cli-detection.d.ts.map +1 -1
- package/dist/mcp/cli-detection.js +5 -8
- package/dist/mcp/cli-detection.js.map +1 -1
- package/dist/mcp/codex-request-normalizer.js +59 -0
- package/dist/mcp/codex-server.js +16 -4
- package/dist/mcp/codex-standalone-server.js +13 -4
- package/dist/mcp/index.d.ts +2 -4
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -5
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/job-management.d.ts.map +1 -1
- package/dist/mcp/job-management.js +11 -9
- package/dist/mcp/job-management.js.map +1 -1
- package/dist/mcp/job-state-db.d.ts +1 -149
- package/dist/mcp/job-state-db.d.ts.map +1 -1
- package/dist/mcp/job-state-db.js +2 -649
- package/dist/mcp/job-state-db.js.map +1 -1
- package/dist/mcp/mcp-config.d.ts +1 -1
- package/dist/mcp/mcp-config.js +1 -1
- package/dist/mcp/prompt-injection.d.ts +14 -76
- package/dist/mcp/prompt-injection.d.ts.map +1 -1
- package/dist/mcp/prompt-injection.js +34 -175
- package/dist/mcp/prompt-injection.js.map +1 -1
- package/dist/mcp/standalone-server.js +2 -0
- package/dist/mcp/standalone-server.js.map +1 -1
- package/dist/mcp/team-server.d.ts +16 -0
- package/dist/mcp/team-server.d.ts.map +1 -0
- package/dist/mcp/team-server.js +356 -0
- package/dist/mcp/team-server.js.map +1 -0
- package/dist/notifications/__tests__/formatter.test.js +62 -0
- package/dist/notifications/__tests__/formatter.test.js.map +1 -1
- package/dist/notifications/__tests__/hook-config.test.d.ts +14 -0
- package/dist/notifications/__tests__/hook-config.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/hook-config.test.js +210 -0
- package/dist/notifications/__tests__/hook-config.test.js.map +1 -0
- package/dist/notifications/__tests__/platform-gating.test.d.ts +12 -0
- package/dist/notifications/__tests__/platform-gating.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/platform-gating.test.js +140 -0
- package/dist/notifications/__tests__/platform-gating.test.js.map +1 -0
- package/dist/notifications/__tests__/template-engine.test.d.ts +13 -0
- package/dist/notifications/__tests__/template-engine.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/template-engine.test.js +378 -0
- package/dist/notifications/__tests__/template-engine.test.js.map +1 -0
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +54 -18
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/dispatcher.d.ts +2 -2
- package/dist/notifications/dispatcher.d.ts.map +1 -1
- package/dist/notifications/dispatcher.js +10 -6
- package/dist/notifications/dispatcher.js.map +1 -1
- package/dist/notifications/formatter.d.ts.map +1 -1
- package/dist/notifications/formatter.js +22 -0
- package/dist/notifications/formatter.js.map +1 -1
- package/dist/notifications/hook-config-types.d.ts +44 -0
- package/dist/notifications/hook-config-types.d.ts.map +1 -0
- package/dist/notifications/hook-config-types.js +8 -0
- package/dist/notifications/hook-config-types.js.map +1 -0
- package/dist/notifications/hook-config.d.ts +36 -0
- package/dist/notifications/hook-config.d.ts.map +1 -0
- package/dist/notifications/hook-config.js +95 -0
- package/dist/notifications/hook-config.js.map +1 -0
- package/dist/notifications/index.d.ts +3 -0
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +31 -3
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +1 -0
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/session-registry.d.ts.map +1 -1
- package/dist/notifications/session-registry.js +13 -5
- package/dist/notifications/session-registry.js.map +1 -1
- package/dist/notifications/template-engine.d.ts +34 -0
- package/dist/notifications/template-engine.d.ts.map +1 -0
- package/dist/notifications/template-engine.js +248 -0
- package/dist/notifications/template-engine.js.map +1 -0
- package/dist/notifications/types.d.ts +0 -2
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/openclaw/__tests__/config.test.d.ts +2 -0
- package/dist/openclaw/__tests__/config.test.d.ts.map +1 -0
- package/dist/openclaw/__tests__/config.test.js +200 -0
- package/dist/openclaw/__tests__/config.test.js.map +1 -0
- package/dist/openclaw/__tests__/dispatcher.test.d.ts +2 -0
- package/dist/openclaw/__tests__/dispatcher.test.d.ts.map +1 -0
- package/dist/openclaw/__tests__/dispatcher.test.js +348 -0
- package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -0
- package/dist/openclaw/__tests__/index.test.d.ts +2 -0
- package/dist/openclaw/__tests__/index.test.d.ts.map +1 -0
- package/dist/openclaw/__tests__/index.test.js +235 -0
- package/dist/openclaw/__tests__/index.test.js.map +1 -0
- package/dist/openclaw/config.d.ts +33 -0
- package/dist/openclaw/config.d.ts.map +1 -0
- package/dist/openclaw/config.js +83 -0
- package/dist/openclaw/config.js.map +1 -0
- package/dist/openclaw/dispatcher.d.ts +47 -0
- package/dist/openclaw/dispatcher.d.ts.map +1 -0
- package/dist/openclaw/dispatcher.js +138 -0
- package/dist/openclaw/dispatcher.js.map +1 -0
- package/dist/openclaw/index.d.ts +25 -0
- package/dist/openclaw/index.d.ts.map +1 -0
- package/dist/openclaw/index.js +132 -0
- package/dist/openclaw/index.js.map +1 -0
- package/dist/openclaw/types.d.ts +102 -0
- package/dist/openclaw/types.d.ts.map +1 -0
- package/dist/openclaw/types.js +8 -0
- package/dist/openclaw/types.js.map +1 -0
- package/dist/platform/index.d.ts +5 -0
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/index.js +17 -0
- package/dist/platform/index.js.map +1 -1
- package/dist/platform/process-utils.d.ts.map +1 -1
- package/dist/platform/process-utils.js +55 -9
- package/dist/platform/process-utils.js.map +1 -1
- package/dist/shared/types.d.ts +7 -5
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/team/__tests__/bridge-integration.test.js +10 -8
- package/dist/team/__tests__/bridge-integration.test.js.map +1 -1
- package/dist/team/__tests__/edge-cases.test.js +40 -29
- package/dist/team/__tests__/edge-cases.test.js.map +1 -1
- package/dist/team/__tests__/idle-nudge.test.d.ts +11 -0
- package/dist/team/__tests__/idle-nudge.test.d.ts.map +1 -0
- package/dist/team/__tests__/idle-nudge.test.js +282 -0
- package/dist/team/__tests__/idle-nudge.test.js.map +1 -0
- package/dist/team/__tests__/mcp-team-bridge.spawn-args.test.js +2 -2
- package/dist/team/__tests__/mcp-team-bridge.spawn-args.test.js.map +1 -1
- package/dist/team/__tests__/mcp-team-bridge.usage.test.d.ts +2 -0
- package/dist/team/__tests__/mcp-team-bridge.usage.test.d.ts.map +1 -0
- package/dist/team/__tests__/mcp-team-bridge.usage.test.js +49 -0
- package/dist/team/__tests__/mcp-team-bridge.usage.test.js.map +1 -0
- package/dist/team/__tests__/model-contract.test.d.ts +2 -0
- package/dist/team/__tests__/model-contract.test.d.ts.map +1 -0
- package/dist/team/__tests__/model-contract.test.js +121 -0
- package/dist/team/__tests__/model-contract.test.js.map +1 -0
- package/dist/team/__tests__/phase-controller.test.d.ts +2 -0
- package/dist/team/__tests__/phase-controller.test.d.ts.map +1 -0
- package/dist/team/__tests__/phase-controller.test.js +45 -0
- package/dist/team/__tests__/phase-controller.test.js.map +1 -0
- package/dist/team/__tests__/runtime-assign.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-assign.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-assign.test.js +43 -0
- package/dist/team/__tests__/runtime-assign.test.js.map +1 -0
- package/dist/team/__tests__/runtime-gemini-prompt.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-gemini-prompt.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-gemini-prompt.test.js +153 -0
- package/dist/team/__tests__/runtime-gemini-prompt.test.js.map +1 -0
- package/dist/team/__tests__/runtime-prompt-mode.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-prompt-mode.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-prompt-mode.test.js +162 -0
- package/dist/team/__tests__/runtime-prompt-mode.test.js.map +1 -0
- package/dist/team/__tests__/runtime.test.d.ts +2 -0
- package/dist/team/__tests__/runtime.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime.test.js +37 -0
- package/dist/team/__tests__/runtime.test.js.map +1 -0
- package/dist/team/__tests__/task-file-ops.test.js +63 -59
- package/dist/team/__tests__/task-file-ops.test.js.map +1 -1
- package/dist/team/__tests__/team-name.test.d.ts +2 -0
- package/dist/team/__tests__/team-name.test.d.ts.map +1 -0
- package/dist/team/__tests__/team-name.test.js +18 -0
- package/dist/team/__tests__/team-name.test.js.map +1 -0
- package/dist/team/__tests__/team-status.test.js +52 -6
- package/dist/team/__tests__/team-status.test.js.map +1 -1
- package/dist/team/__tests__/tmux-comm.test.d.ts +2 -0
- package/dist/team/__tests__/tmux-comm.test.d.ts.map +1 -0
- package/dist/team/__tests__/tmux-comm.test.js +26 -0
- package/dist/team/__tests__/tmux-comm.test.js.map +1 -0
- package/dist/team/__tests__/tmux-session.create-team.test.d.ts +2 -0
- package/dist/team/__tests__/tmux-session.create-team.test.d.ts.map +1 -0
- package/dist/team/__tests__/tmux-session.create-team.test.js +104 -0
- package/dist/team/__tests__/tmux-session.create-team.test.js.map +1 -0
- package/dist/team/__tests__/tmux-session.spawn.test.d.ts +2 -0
- package/dist/team/__tests__/tmux-session.spawn.test.d.ts.map +1 -0
- package/dist/team/__tests__/tmux-session.spawn.test.js +61 -0
- package/dist/team/__tests__/tmux-session.spawn.test.js.map +1 -0
- package/dist/team/__tests__/tmux-session.test.js +161 -2
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.d.ts +2 -0
- package/dist/team/__tests__/worker-bootstrap.test.d.ts.map +1 -0
- package/dist/team/__tests__/worker-bootstrap.test.js +58 -0
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -0
- package/dist/team/bridge-entry.d.ts.map +1 -1
- package/dist/team/bridge-entry.js +4 -0
- package/dist/team/bridge-entry.js.map +1 -1
- package/dist/team/capabilities.d.ts.map +1 -1
- package/dist/team/capabilities.js +3 -0
- package/dist/team/capabilities.js.map +1 -1
- package/dist/team/cli-detection.d.ts +9 -0
- package/dist/team/cli-detection.d.ts.map +1 -0
- package/dist/team/cli-detection.js +29 -0
- package/dist/team/cli-detection.js.map +1 -0
- package/dist/team/idle-nudge.d.ts +53 -0
- package/dist/team/idle-nudge.d.ts.map +1 -0
- package/dist/team/idle-nudge.js +124 -0
- package/dist/team/idle-nudge.js.map +1 -0
- package/dist/team/inbox-outbox.d.ts.map +1 -1
- package/dist/team/inbox-outbox.js +7 -3
- package/dist/team/inbox-outbox.js.map +1 -1
- package/dist/team/index.d.ts +14 -1
- package/dist/team/index.d.ts.map +1 -1
- package/dist/team/index.js +12 -1
- package/dist/team/index.js.map +1 -1
- package/dist/team/mcp-team-bridge.d.ts +9 -0
- package/dist/team/mcp-team-bridge.d.ts.map +1 -1
- package/dist/team/mcp-team-bridge.js +82 -3
- package/dist/team/mcp-team-bridge.js.map +1 -1
- package/dist/team/model-contract.d.ts +37 -0
- package/dist/team/model-contract.d.ts.map +1 -0
- package/dist/team/model-contract.js +139 -0
- package/dist/team/model-contract.js.map +1 -0
- package/dist/team/phase-controller.d.ts +33 -0
- package/dist/team/phase-controller.d.ts.map +1 -0
- package/dist/team/phase-controller.js +79 -0
- package/dist/team/phase-controller.js.map +1 -0
- package/dist/team/runtime-cli.d.ts +9 -0
- package/dist/team/runtime-cli.d.ts.map +1 -0
- package/dist/team/runtime-cli.js +188 -0
- package/dist/team/runtime-cli.js.map +1 -0
- package/dist/team/runtime.d.ts +95 -0
- package/dist/team/runtime.d.ts.map +1 -0
- package/dist/team/runtime.js +692 -0
- package/dist/team/runtime.js.map +1 -0
- package/dist/team/state-paths.d.ts +72 -0
- package/dist/team/state-paths.d.ts.map +1 -0
- package/dist/team/state-paths.js +87 -0
- package/dist/team/state-paths.js.map +1 -0
- package/dist/team/task-file-ops.d.ts +27 -7
- package/dist/team/task-file-ops.d.ts.map +1 -1
- package/dist/team/task-file-ops.js +116 -55
- package/dist/team/task-file-ops.js.map +1 -1
- package/dist/team/team-name.d.ts +2 -0
- package/dist/team/team-name.d.ts.map +1 -0
- package/dist/team/team-name.js +8 -0
- package/dist/team/team-name.js.map +1 -0
- package/dist/team/team-registration.d.ts +1 -1
- package/dist/team/team-registration.d.ts.map +1 -1
- package/dist/team/team-registration.js.map +1 -1
- package/dist/team/team-status.d.ts +11 -1
- package/dist/team/team-status.d.ts.map +1 -1
- package/dist/team/team-status.js +32 -3
- package/dist/team/team-status.js.map +1 -1
- package/dist/team/tmux-comm.d.ts +36 -0
- package/dist/team/tmux-comm.d.ts.map +1 -0
- package/dist/team/tmux-comm.js +115 -0
- package/dist/team/tmux-comm.js.map +1 -0
- package/dist/team/tmux-session.d.ts +92 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +533 -2
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/types.d.ts +10 -3
- package/dist/team/types.d.ts.map +1 -1
- package/dist/team/unified-team.d.ts.map +1 -1
- package/dist/team/unified-team.js +13 -3
- package/dist/team/unified-team.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +39 -0
- package/dist/team/worker-bootstrap.d.ts.map +1 -0
- package/dist/team/worker-bootstrap.js +117 -0
- package/dist/team/worker-bootstrap.js.map +1 -0
- package/dist/team/worker-health.d.ts.map +1 -1
- package/dist/team/worker-health.js +15 -3
- package/dist/team/worker-health.js.map +1 -1
- package/dist/tools/ast-tools.js +1 -1
- package/dist/tools/ast-tools.js.map +1 -1
- package/dist/tools/diagnostics/lsp-aggregator.d.ts.map +1 -1
- package/dist/tools/diagnostics/lsp-aggregator.js +4 -2
- package/dist/tools/diagnostics/lsp-aggregator.js.map +1 -1
- package/dist/tools/lsp/__tests__/client-handle-data.test.d.ts +2 -0
- package/dist/tools/lsp/__tests__/client-handle-data.test.d.ts.map +1 -0
- package/dist/tools/lsp/__tests__/client-handle-data.test.js +138 -0
- package/dist/tools/lsp/__tests__/client-handle-data.test.js.map +1 -0
- package/dist/tools/lsp/client.d.ts +13 -0
- package/dist/tools/lsp/client.d.ts.map +1 -1
- package/dist/tools/lsp/client.js +64 -8
- package/dist/tools/lsp/client.js.map +1 -1
- package/dist/tools/lsp/servers.d.ts.map +1 -1
- package/dist/tools/lsp/servers.js +4 -9
- package/dist/tools/lsp/servers.js.map +1 -1
- package/dist/tools/lsp-tools.d.ts.map +1 -1
- package/dist/tools/lsp-tools.js +4 -0
- package/dist/tools/lsp-tools.js.map +1 -1
- package/dist/tools/python-repl/bridge-manager.d.ts.map +1 -1
- package/dist/tools/python-repl/bridge-manager.js +15 -1
- package/dist/tools/python-repl/bridge-manager.js.map +1 -1
- package/dist/tools/python-repl/session-lock.d.ts.map +1 -1
- package/dist/tools/python-repl/session-lock.js +35 -15
- package/dist/tools/python-repl/session-lock.js.map +1 -1
- package/dist/tools/state-tools.d.ts.map +1 -1
- package/dist/tools/state-tools.js +10 -0
- package/dist/tools/state-tools.js.map +1 -1
- package/dist/utils/__tests__/frontmatter.test.d.ts +2 -0
- package/dist/utils/__tests__/frontmatter.test.d.ts.map +1 -0
- package/dist/utils/__tests__/frontmatter.test.js +147 -0
- package/dist/utils/__tests__/frontmatter.test.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +24 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +62 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +4 -2
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/string-width.d.ts.map +1 -1
- package/dist/utils/string-width.js +15 -4
- package/dist/utils/string-width.js.map +1 -1
- package/dist/verification/tier-selector.js +1 -1
- package/dist/verification/tier-selector.js.map +1 -1
- package/docs/AGENTS.md +4 -2
- package/docs/CLAUDE.md +8 -48
- package/docs/MIGRATION.md +114 -0
- package/docs/REFERENCE.md +35 -102
- package/hooks/hooks.json +23 -23
- package/package.json +8 -8
- package/scripts/build-runtime-cli.mjs +24 -0
- package/scripts/build-team-server.mjs +28 -0
- package/scripts/cleanup-orphans.mjs +22 -5
- package/scripts/context-safety.mjs +5 -1
- package/scripts/demo-team.mjs +26 -0
- package/scripts/keyword-detector.mjs +6 -76
- package/scripts/openclaw-gateway-demo.mjs +168 -0
- package/scripts/persistent-mode.cjs +30 -4
- package/scripts/persistent-mode.mjs +48 -3
- package/scripts/plugin-setup.mjs +66 -3
- package/scripts/post-tool-use-failure.mjs +20 -2
- package/scripts/post-tool-verifier.mjs +57 -6
- package/scripts/pre-tool-enforcer.mjs +125 -5
- package/scripts/run.cjs +114 -0
- package/scripts/session-start.mjs +56 -7
- package/scripts/status.mjs +144 -0
- package/scripts/test-codex-gemini-team.mjs +78 -0
- package/skills/AGENTS.md +5 -2
- package/skills/analyze/SKILL.md +5 -11
- package/skills/autopilot/SKILL.md +5 -6
- package/skills/ccg/SKILL.md +88 -99
- package/skills/configure-notifications/SKILL.md +177 -0
- package/skills/configure-openclaw/SKILL.md +320 -0
- package/skills/external-context/SKILL.md +7 -83
- package/skills/hud/SKILL.md +68 -46
- package/skills/omc-setup/SKILL.md +58 -19
- package/skills/omc-teams/SKILL.md +178 -0
- package/skills/pipeline/SKILL.md +4 -4
- package/skills/plan/SKILL.md +28 -16
- package/skills/ralph/SKILL.md +3 -4
- package/skills/ralph-init/SKILL.md +3 -1
- package/skills/ralplan/SKILL.md +93 -8
- package/skills/security-review/SKILL.md +5 -6
- package/skills/tdd/SKILL.md +5 -6
- package/skills/team/SKILL.md +35 -34
- package/templates/hooks/keyword-detector.mjs +11 -82
- package/templates/hooks/persistent-mode.mjs +120 -3
- package/templates/hooks/post-tool-use-failure.mjs +20 -2
- package/templates/hooks/session-start.mjs +2 -16
- package/dist/__tests__/analytics/backfill-dedup.test.d.ts +0 -2
- package/dist/__tests__/analytics/backfill-dedup.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/backfill-dedup.test.js +0 -179
- package/dist/__tests__/analytics/backfill-dedup.test.js.map +0 -1
- package/dist/__tests__/analytics/backfill-engine.test.d.ts +0 -2
- package/dist/__tests__/analytics/backfill-engine.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/backfill-engine.test.js +0 -362
- package/dist/__tests__/analytics/backfill-engine.test.js.map +0 -1
- package/dist/__tests__/analytics/output-estimator.test.d.ts +0 -2
- package/dist/__tests__/analytics/output-estimator.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/output-estimator.test.js +0 -124
- package/dist/__tests__/analytics/output-estimator.test.js.map +0 -1
- package/dist/__tests__/analytics/token-extractor.test.d.ts +0 -2
- package/dist/__tests__/analytics/token-extractor.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/token-extractor.test.js +0 -165
- package/dist/__tests__/analytics/token-extractor.test.js.map +0 -1
- package/dist/__tests__/analytics/token-tracker.test.d.ts +0 -2
- package/dist/__tests__/analytics/token-tracker.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/token-tracker.test.js +0 -189
- package/dist/__tests__/analytics/token-tracker.test.js.map +0 -1
- package/dist/__tests__/analytics/tokscale-adapter.test.d.ts +0 -2
- package/dist/__tests__/analytics/tokscale-adapter.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/tokscale-adapter.test.js +0 -79
- package/dist/__tests__/analytics/tokscale-adapter.test.js.map +0 -1
- package/dist/__tests__/analytics/transcript-parser.test.d.ts +0 -2
- package/dist/__tests__/analytics/transcript-parser.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/transcript-parser.test.js +0 -285
- package/dist/__tests__/analytics/transcript-parser.test.js.map +0 -1
- package/dist/__tests__/analytics/transcript-scanner.test.d.ts +0 -2
- package/dist/__tests__/analytics/transcript-scanner.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/transcript-scanner.test.js +0 -443
- package/dist/__tests__/analytics/transcript-scanner.test.js.map +0 -1
- package/dist/__tests__/analytics/transcript-token-extractor.test.d.ts +0 -2
- package/dist/__tests__/analytics/transcript-token-extractor.test.d.ts.map +0 -1
- package/dist/__tests__/analytics/transcript-token-extractor.test.js +0 -177
- package/dist/__tests__/analytics/transcript-token-extractor.test.js.map +0 -1
- package/dist/analytics/analytics-summary.d.ts +0 -47
- package/dist/analytics/analytics-summary.d.ts.map +0 -1
- package/dist/analytics/analytics-summary.js +0 -171
- package/dist/analytics/analytics-summary.js.map +0 -1
- package/dist/analytics/backfill-dedup.d.ts +0 -49
- package/dist/analytics/backfill-dedup.d.ts.map +0 -1
- package/dist/analytics/backfill-dedup.js +0 -115
- package/dist/analytics/backfill-dedup.js.map +0 -1
- package/dist/analytics/backfill-engine.d.ts +0 -59
- package/dist/analytics/backfill-engine.d.ts.map +0 -1
- package/dist/analytics/backfill-engine.js +0 -172
- package/dist/analytics/backfill-engine.js.map +0 -1
- package/dist/analytics/cost-estimator.d.ts +0 -29
- package/dist/analytics/cost-estimator.d.ts.map +0 -1
- package/dist/analytics/cost-estimator.js +0 -135
- package/dist/analytics/cost-estimator.js.map +0 -1
- package/dist/analytics/export.d.ts +0 -7
- package/dist/analytics/export.d.ts.map +0 -1
- package/dist/analytics/export.js +0 -93
- package/dist/analytics/export.js.map +0 -1
- package/dist/analytics/index.d.ts +0 -24
- package/dist/analytics/index.d.ts.map +0 -1
- package/dist/analytics/index.js +0 -30
- package/dist/analytics/index.js.map +0 -1
- package/dist/analytics/metrics-collector.d.ts +0 -30
- package/dist/analytics/metrics-collector.d.ts.map +0 -1
- package/dist/analytics/metrics-collector.js +0 -96
- package/dist/analytics/metrics-collector.js.map +0 -1
- package/dist/analytics/output-estimator.d.ts +0 -26
- package/dist/analytics/output-estimator.d.ts.map +0 -1
- package/dist/analytics/output-estimator.js +0 -65
- package/dist/analytics/output-estimator.js.map +0 -1
- package/dist/analytics/query-engine.d.ts +0 -35
- package/dist/analytics/query-engine.d.ts.map +0 -1
- package/dist/analytics/query-engine.js +0 -239
- package/dist/analytics/query-engine.js.map +0 -1
- package/dist/analytics/session-catalog.d.ts +0 -45
- package/dist/analytics/session-catalog.d.ts.map +0 -1
- package/dist/analytics/session-catalog.js +0 -153
- package/dist/analytics/session-catalog.js.map +0 -1
- package/dist/analytics/session-manager.d.ts +0 -58
- package/dist/analytics/session-manager.d.ts.map +0 -1
- package/dist/analytics/session-manager.js +0 -396
- package/dist/analytics/session-manager.js.map +0 -1
- package/dist/analytics/session-types.d.ts +0 -37
- package/dist/analytics/session-types.d.ts.map +0 -1
- package/dist/analytics/session-types.js +0 -2
- package/dist/analytics/session-types.js.map +0 -1
- package/dist/analytics/token-extractor.d.ts +0 -31
- package/dist/analytics/token-extractor.d.ts.map +0 -1
- package/dist/analytics/token-extractor.js +0 -57
- package/dist/analytics/token-extractor.js.map +0 -1
- package/dist/analytics/token-tracker.d.ts +0 -33
- package/dist/analytics/token-tracker.d.ts.map +0 -1
- package/dist/analytics/token-tracker.js +0 -443
- package/dist/analytics/token-tracker.js.map +0 -1
- package/dist/analytics/tokscale-adapter.d.ts +0 -71
- package/dist/analytics/tokscale-adapter.d.ts.map +0 -1
- package/dist/analytics/tokscale-adapter.js +0 -223
- package/dist/analytics/tokscale-adapter.js.map +0 -1
- package/dist/analytics/transcript-parser.d.ts +0 -42
- package/dist/analytics/transcript-parser.d.ts.map +0 -1
- package/dist/analytics/transcript-parser.js +0 -90
- package/dist/analytics/transcript-parser.js.map +0 -1
- package/dist/analytics/transcript-scanner.d.ts +0 -51
- package/dist/analytics/transcript-scanner.d.ts.map +0 -1
- package/dist/analytics/transcript-scanner.js +0 -279
- package/dist/analytics/transcript-scanner.js.map +0 -1
- package/dist/analytics/transcript-token-extractor.d.ts +0 -35
- package/dist/analytics/transcript-token-extractor.d.ts.map +0 -1
- package/dist/analytics/transcript-token-extractor.js +0 -136
- package/dist/analytics/transcript-token-extractor.js.map +0 -1
- package/dist/analytics/types.d.ts +0 -119
- package/dist/analytics/types.d.ts.map +0 -1
- package/dist/analytics/types.js +0 -32
- package/dist/analytics/types.js.map +0 -1
- package/dist/cli/analytics.d.ts +0 -3
- package/dist/cli/analytics.d.ts.map +0 -1
- package/dist/cli/analytics.js +0 -105
- package/dist/cli/analytics.js.map +0 -1
- package/dist/cli/commands/agents.d.ts +0 -5
- package/dist/cli/commands/agents.d.ts.map +0 -1
- package/dist/cli/commands/agents.js +0 -31
- package/dist/cli/commands/agents.js.map +0 -1
- package/dist/cli/commands/backfill.d.ts +0 -15
- package/dist/cli/commands/backfill.d.ts.map +0 -1
- package/dist/cli/commands/backfill.js +0 -146
- package/dist/cli/commands/backfill.js.map +0 -1
- package/dist/cli/commands/cleanup.d.ts +0 -4
- package/dist/cli/commands/cleanup.d.ts.map +0 -1
- package/dist/cli/commands/cleanup.js +0 -31
- package/dist/cli/commands/cleanup.js.map +0 -1
- package/dist/cli/commands/cost.d.ts +0 -4
- package/dist/cli/commands/cost.d.ts.map +0 -1
- package/dist/cli/commands/cost.js +0 -53
- package/dist/cli/commands/cost.js.map +0 -1
- package/dist/cli/commands/export.d.ts +0 -5
- package/dist/cli/commands/export.d.ts.map +0 -1
- package/dist/cli/commands/export.js +0 -30
- package/dist/cli/commands/export.js.map +0 -1
- package/dist/cli/commands/sessions.d.ts +0 -5
- package/dist/cli/commands/sessions.d.ts.map +0 -1
- package/dist/cli/commands/sessions.js +0 -89
- package/dist/cli/commands/sessions.js.map +0 -1
- package/dist/cli/commands/stats.d.ts +0 -5
- package/dist/cli/commands/stats.d.ts.map +0 -1
- package/dist/cli/commands/stats.js +0 -84
- package/dist/cli/commands/stats.js.map +0 -1
- package/dist/cli/utils/tokscale-launcher.d.ts +0 -25
- package/dist/cli/utils/tokscale-launcher.d.ts.map +0 -1
- package/dist/cli/utils/tokscale-launcher.js +0 -70
- package/dist/cli/utils/tokscale-launcher.js.map +0 -1
- package/dist/hud/analytics-display.d.ts +0 -63
- package/dist/hud/analytics-display.d.ts.map +0 -1
- package/dist/hud/analytics-display.js +0 -190
- package/dist/hud/analytics-display.js.map +0 -1
- package/scripts/build-codex-server.mjs +0 -95
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
import { mkdir, writeFile, readFile, rm, rename } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { buildWorkerArgv, validateCliAvailable, getWorkerEnv as getModelWorkerEnv, isPromptModeAgent, getPromptModeArgs } from './model-contract.js';
|
|
5
|
+
import { validateTeamName } from './team-name.js';
|
|
6
|
+
import { createTeamSession, spawnWorkerInPane, sendToWorker, isWorkerAlive, killTeamSession, } from './tmux-session.js';
|
|
7
|
+
import { composeInitialInbox, ensureWorkerStateDir, writeWorkerOverlay, } from './worker-bootstrap.js';
|
|
8
|
+
import { withTaskLock } from './task-file-ops.js';
|
|
9
|
+
function workerName(index) {
|
|
10
|
+
return `worker-${index + 1}`;
|
|
11
|
+
}
|
|
12
|
+
function stateRoot(cwd, teamName) {
|
|
13
|
+
validateTeamName(teamName);
|
|
14
|
+
return join(cwd, `.omc/state/team/${teamName}`);
|
|
15
|
+
}
|
|
16
|
+
async function writeJson(filePath, data) {
|
|
17
|
+
await mkdir(join(filePath, '..'), { recursive: true });
|
|
18
|
+
await writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
19
|
+
}
|
|
20
|
+
async function readJsonSafe(filePath) {
|
|
21
|
+
try {
|
|
22
|
+
const content = await readFile(filePath, 'utf-8');
|
|
23
|
+
return JSON.parse(content);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function parseWorkerIndex(workerNameValue) {
|
|
30
|
+
const match = workerNameValue.match(/^worker-(\d+)$/);
|
|
31
|
+
if (!match)
|
|
32
|
+
return 0;
|
|
33
|
+
const parsed = Number.parseInt(match[1], 10) - 1;
|
|
34
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
35
|
+
}
|
|
36
|
+
function taskPath(root, taskId) {
|
|
37
|
+
return join(root, 'tasks', `${taskId}.json`);
|
|
38
|
+
}
|
|
39
|
+
async function writePanesTrackingFileIfPresent(runtime) {
|
|
40
|
+
const jobId = process.env.OMC_JOB_ID;
|
|
41
|
+
const omcJobsDir = process.env.OMC_JOBS_DIR;
|
|
42
|
+
if (!jobId || !omcJobsDir)
|
|
43
|
+
return;
|
|
44
|
+
const panesPath = join(omcJobsDir, `${jobId}-panes.json`);
|
|
45
|
+
const tempPath = `${panesPath}.tmp`;
|
|
46
|
+
await writeFile(tempPath, JSON.stringify({ paneIds: [...runtime.workerPaneIds], leaderPaneId: runtime.leaderPaneId }), 'utf-8');
|
|
47
|
+
await rename(tempPath, panesPath);
|
|
48
|
+
}
|
|
49
|
+
async function readTask(root, taskId) {
|
|
50
|
+
return readJsonSafe(taskPath(root, taskId));
|
|
51
|
+
}
|
|
52
|
+
async function writeTask(root, task) {
|
|
53
|
+
await writeJson(taskPath(root, task.id), task);
|
|
54
|
+
}
|
|
55
|
+
async function markTaskInProgress(root, taskId, owner, teamName, cwd) {
|
|
56
|
+
const result = await withTaskLock(teamName, taskId, async () => {
|
|
57
|
+
const task = await readTask(root, taskId);
|
|
58
|
+
if (!task || task.status !== 'pending')
|
|
59
|
+
return false;
|
|
60
|
+
task.status = 'in_progress';
|
|
61
|
+
task.owner = owner;
|
|
62
|
+
task.assignedAt = new Date().toISOString();
|
|
63
|
+
await writeTask(root, task);
|
|
64
|
+
return true;
|
|
65
|
+
}, { cwd });
|
|
66
|
+
// withTaskLock returns null if the lock could not be acquired — treat as not claimed
|
|
67
|
+
return result ?? false;
|
|
68
|
+
}
|
|
69
|
+
async function resetTaskToPending(root, taskId) {
|
|
70
|
+
const task = await readTask(root, taskId);
|
|
71
|
+
if (!task)
|
|
72
|
+
return;
|
|
73
|
+
task.status = 'pending';
|
|
74
|
+
task.owner = null;
|
|
75
|
+
task.assignedAt = undefined;
|
|
76
|
+
await writeTask(root, task);
|
|
77
|
+
}
|
|
78
|
+
async function markTaskFromDone(root, taskId, status, summary) {
|
|
79
|
+
const task = await readTask(root, taskId);
|
|
80
|
+
if (!task)
|
|
81
|
+
return;
|
|
82
|
+
task.status = status;
|
|
83
|
+
task.result = summary;
|
|
84
|
+
task.summary = summary;
|
|
85
|
+
if (status === 'completed') {
|
|
86
|
+
task.completedAt = new Date().toISOString();
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
task.failedAt = new Date().toISOString();
|
|
90
|
+
}
|
|
91
|
+
await writeTask(root, task);
|
|
92
|
+
}
|
|
93
|
+
async function markTaskFailedDeadPane(root, taskId, workerNameValue) {
|
|
94
|
+
const task = await readTask(root, taskId);
|
|
95
|
+
if (!task)
|
|
96
|
+
return;
|
|
97
|
+
task.status = 'failed';
|
|
98
|
+
task.owner = workerNameValue;
|
|
99
|
+
task.summary = `Worker pane died before done.json was written (${workerNameValue})`;
|
|
100
|
+
task.result = task.summary;
|
|
101
|
+
task.failedAt = new Date().toISOString();
|
|
102
|
+
await writeTask(root, task);
|
|
103
|
+
}
|
|
104
|
+
async function nextPendingTaskIndex(runtime) {
|
|
105
|
+
const root = stateRoot(runtime.cwd, runtime.teamName);
|
|
106
|
+
for (let i = 0; i < runtime.config.tasks.length; i++) {
|
|
107
|
+
const task = await readTask(root, String(i + 1));
|
|
108
|
+
if (task?.status === 'pending')
|
|
109
|
+
return i;
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
async function notifyPaneWithRetry(sessionName, paneId, message, maxAttempts = 6, retryDelayMs = 350) {
|
|
114
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
115
|
+
if (await sendToWorker(sessionName, paneId, message)) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
if (attempt < maxAttempts) {
|
|
119
|
+
await new Promise(r => setTimeout(r, retryDelayMs));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
export async function allTasksTerminal(runtime) {
|
|
125
|
+
const root = stateRoot(runtime.cwd, runtime.teamName);
|
|
126
|
+
for (let i = 0; i < runtime.config.tasks.length; i++) {
|
|
127
|
+
const task = await readTask(root, String(i + 1));
|
|
128
|
+
if (!task)
|
|
129
|
+
return false;
|
|
130
|
+
if (task.status !== 'completed' && task.status !== 'failed')
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Build the initial task instruction written to a worker's inbox.
|
|
137
|
+
* Includes task ID, subject, full description, and done-signal path.
|
|
138
|
+
*/
|
|
139
|
+
function buildInitialTaskInstruction(teamName, workerName, task, taskId) {
|
|
140
|
+
const donePath = `.omc/state/team/${teamName}/workers/${workerName}/done.json`;
|
|
141
|
+
return [
|
|
142
|
+
`## Initial Task Assignment`,
|
|
143
|
+
`Task ID: ${taskId}`,
|
|
144
|
+
`Worker: ${workerName}`,
|
|
145
|
+
`Subject: ${task.subject}`,
|
|
146
|
+
``,
|
|
147
|
+
task.description,
|
|
148
|
+
``,
|
|
149
|
+
`When complete, write done signal to ${donePath}:`,
|
|
150
|
+
`{"taskId":"${taskId}","status":"completed","summary":"<brief summary>","completedAt":"<ISO timestamp>"}`,
|
|
151
|
+
``,
|
|
152
|
+
`IMPORTANT: Execute ONLY the task assigned to you in this inbox. After writing done.json, exit immediately. Do not read from the task directory or claim other tasks.`,
|
|
153
|
+
].join('\n');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Start a new team: create tmux session, spawn workers, wait for ready.
|
|
157
|
+
*/
|
|
158
|
+
export async function startTeam(config) {
|
|
159
|
+
const { teamName, agentTypes, tasks, cwd } = config;
|
|
160
|
+
validateTeamName(teamName);
|
|
161
|
+
// Validate CLIs are available
|
|
162
|
+
for (const agentType of [...new Set(agentTypes)]) {
|
|
163
|
+
validateCliAvailable(agentType);
|
|
164
|
+
}
|
|
165
|
+
const root = stateRoot(cwd, teamName);
|
|
166
|
+
await mkdir(join(root, 'tasks'), { recursive: true });
|
|
167
|
+
await mkdir(join(root, 'mailbox'), { recursive: true });
|
|
168
|
+
// Write config
|
|
169
|
+
await writeJson(join(root, 'config.json'), config);
|
|
170
|
+
// Create task files
|
|
171
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
172
|
+
const taskId = String(i + 1);
|
|
173
|
+
await writeJson(join(root, 'tasks', `${taskId}.json`), {
|
|
174
|
+
id: taskId,
|
|
175
|
+
subject: tasks[i].subject,
|
|
176
|
+
description: tasks[i].description,
|
|
177
|
+
status: 'pending',
|
|
178
|
+
owner: null,
|
|
179
|
+
result: null,
|
|
180
|
+
createdAt: new Date().toISOString(),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// Set up worker state dirs and overlays for all potential workers up front
|
|
184
|
+
// (overlays are cheap; workers are spawned on-demand later)
|
|
185
|
+
const workerNames = [];
|
|
186
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
187
|
+
const wName = workerName(i);
|
|
188
|
+
workerNames.push(wName);
|
|
189
|
+
const agentType = agentTypes[i % agentTypes.length] ?? agentTypes[0] ?? 'claude';
|
|
190
|
+
await ensureWorkerStateDir(teamName, wName, cwd);
|
|
191
|
+
await writeWorkerOverlay({
|
|
192
|
+
teamName, workerName: wName, agentType,
|
|
193
|
+
tasks: tasks.map((t, idx) => ({ id: String(idx + 1), subject: t.subject, description: t.description })),
|
|
194
|
+
cwd,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// Create tmux session with ZERO worker panes (leader only).
|
|
198
|
+
// Workers are spawned on-demand by the orchestrator.
|
|
199
|
+
const session = await createTeamSession(teamName, 0, cwd);
|
|
200
|
+
const runtime = {
|
|
201
|
+
teamName,
|
|
202
|
+
sessionName: session.sessionName,
|
|
203
|
+
leaderPaneId: session.leaderPaneId,
|
|
204
|
+
config,
|
|
205
|
+
workerNames,
|
|
206
|
+
workerPaneIds: session.workerPaneIds, // initially empty []
|
|
207
|
+
activeWorkers: new Map(),
|
|
208
|
+
cwd,
|
|
209
|
+
};
|
|
210
|
+
const maxConcurrentWorkers = agentTypes.length;
|
|
211
|
+
for (let i = 0; i < maxConcurrentWorkers; i++) {
|
|
212
|
+
const taskIndex = await nextPendingTaskIndex(runtime);
|
|
213
|
+
if (taskIndex == null)
|
|
214
|
+
break;
|
|
215
|
+
await spawnWorkerForTask(runtime, workerName(i), taskIndex);
|
|
216
|
+
}
|
|
217
|
+
runtime.stopWatchdog = watchdogCliWorkers(runtime, 1000);
|
|
218
|
+
return runtime;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Monitor team: poll worker health, detect stalls, return snapshot.
|
|
222
|
+
*/
|
|
223
|
+
export async function monitorTeam(teamName, cwd, workerPaneIds) {
|
|
224
|
+
validateTeamName(teamName);
|
|
225
|
+
const monitorStartedAt = Date.now();
|
|
226
|
+
const root = stateRoot(cwd, teamName);
|
|
227
|
+
// Read task counts
|
|
228
|
+
const taskScanStartedAt = Date.now();
|
|
229
|
+
const taskCounts = { pending: 0, inProgress: 0, completed: 0, failed: 0 };
|
|
230
|
+
try {
|
|
231
|
+
const { readdir } = await import('fs/promises');
|
|
232
|
+
const taskFiles = await readdir(join(root, 'tasks'));
|
|
233
|
+
for (const f of taskFiles.filter(f => f.endsWith('.json'))) {
|
|
234
|
+
const task = await readJsonSafe(join(root, 'tasks', f));
|
|
235
|
+
if (task?.status === 'pending')
|
|
236
|
+
taskCounts.pending++;
|
|
237
|
+
else if (task?.status === 'in_progress')
|
|
238
|
+
taskCounts.inProgress++;
|
|
239
|
+
else if (task?.status === 'completed')
|
|
240
|
+
taskCounts.completed++;
|
|
241
|
+
else if (task?.status === 'failed')
|
|
242
|
+
taskCounts.failed++;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch { /* tasks dir may not exist yet */ }
|
|
246
|
+
const listTasksMs = Date.now() - taskScanStartedAt;
|
|
247
|
+
// Check worker health
|
|
248
|
+
const workerScanStartedAt = Date.now();
|
|
249
|
+
const workers = [];
|
|
250
|
+
const deadWorkers = [];
|
|
251
|
+
for (let i = 0; i < workerPaneIds.length; i++) {
|
|
252
|
+
const wName = `worker-${i + 1}`;
|
|
253
|
+
const paneId = workerPaneIds[i];
|
|
254
|
+
const alive = await isWorkerAlive(paneId);
|
|
255
|
+
const heartbeatPath = join(root, 'workers', wName, 'heartbeat.json');
|
|
256
|
+
const heartbeat = await readJsonSafe(heartbeatPath);
|
|
257
|
+
// Detect stall: no heartbeat update in 60s
|
|
258
|
+
let stalled = false;
|
|
259
|
+
if (heartbeat?.updatedAt) {
|
|
260
|
+
const age = Date.now() - new Date(heartbeat.updatedAt).getTime();
|
|
261
|
+
stalled = age > 60_000;
|
|
262
|
+
}
|
|
263
|
+
const status = {
|
|
264
|
+
workerName: wName,
|
|
265
|
+
alive,
|
|
266
|
+
paneId,
|
|
267
|
+
currentTaskId: heartbeat?.currentTaskId,
|
|
268
|
+
lastHeartbeat: heartbeat?.updatedAt,
|
|
269
|
+
stalled,
|
|
270
|
+
};
|
|
271
|
+
workers.push(status);
|
|
272
|
+
if (!alive)
|
|
273
|
+
deadWorkers.push(wName);
|
|
274
|
+
// Note: CLI workers (codex/gemini) may not write heartbeat.json — stall is advisory only
|
|
275
|
+
}
|
|
276
|
+
const workerScanMs = Date.now() - workerScanStartedAt;
|
|
277
|
+
// Infer phase from task counts
|
|
278
|
+
let phase = 'executing';
|
|
279
|
+
if (taskCounts.inProgress === 0 && taskCounts.pending > 0 && taskCounts.completed === 0) {
|
|
280
|
+
phase = 'planning';
|
|
281
|
+
}
|
|
282
|
+
else if (taskCounts.failed > 0 && taskCounts.pending === 0 && taskCounts.inProgress === 0) {
|
|
283
|
+
phase = 'fixing';
|
|
284
|
+
}
|
|
285
|
+
else if (taskCounts.completed > 0 && taskCounts.pending === 0 && taskCounts.inProgress === 0 && taskCounts.failed === 0) {
|
|
286
|
+
phase = 'completed';
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
teamName,
|
|
290
|
+
phase,
|
|
291
|
+
workers,
|
|
292
|
+
taskCounts,
|
|
293
|
+
deadWorkers,
|
|
294
|
+
monitorPerformance: {
|
|
295
|
+
listTasksMs,
|
|
296
|
+
workerScanMs,
|
|
297
|
+
totalMs: Date.now() - monitorStartedAt,
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Runtime-owned worker watchdog/orchestrator loop.
|
|
303
|
+
* Handles done.json completion, dead pane failures, and next-task spawning.
|
|
304
|
+
*/
|
|
305
|
+
export function watchdogCliWorkers(runtime, intervalMs) {
|
|
306
|
+
let tickInFlight = false;
|
|
307
|
+
let consecutiveFailures = 0;
|
|
308
|
+
const MAX_CONSECUTIVE_FAILURES = 3;
|
|
309
|
+
// Track consecutive unresponsive ticks per worker
|
|
310
|
+
const unresponsiveCounts = new Map();
|
|
311
|
+
const UNRESPONSIVE_KILL_THRESHOLD = 3;
|
|
312
|
+
const tick = async () => {
|
|
313
|
+
if (tickInFlight)
|
|
314
|
+
return;
|
|
315
|
+
tickInFlight = true;
|
|
316
|
+
try {
|
|
317
|
+
const workers = [...runtime.activeWorkers.entries()];
|
|
318
|
+
if (workers.length === 0)
|
|
319
|
+
return;
|
|
320
|
+
const root = stateRoot(runtime.cwd, runtime.teamName);
|
|
321
|
+
// Collect done signals and alive checks in parallel to avoid O(N×300ms) sequential tmux calls.
|
|
322
|
+
const [doneSignals, aliveResults] = await Promise.all([
|
|
323
|
+
Promise.all(workers.map(([wName]) => {
|
|
324
|
+
const donePath = join(root, 'workers', wName, 'done.json');
|
|
325
|
+
return readJsonSafe(donePath);
|
|
326
|
+
})),
|
|
327
|
+
Promise.all(workers.map(([, active]) => isWorkerAlive(active.paneId))),
|
|
328
|
+
]);
|
|
329
|
+
for (let i = 0; i < workers.length; i++) {
|
|
330
|
+
const [wName, active] = workers[i];
|
|
331
|
+
const donePath = join(root, 'workers', wName, 'done.json');
|
|
332
|
+
const signal = doneSignals[i];
|
|
333
|
+
// Process done.json first if present
|
|
334
|
+
if (signal) {
|
|
335
|
+
unresponsiveCounts.delete(wName);
|
|
336
|
+
await markTaskFromDone(root, signal.taskId || active.taskId, signal.status, signal.summary);
|
|
337
|
+
try {
|
|
338
|
+
const { unlink } = await import('fs/promises');
|
|
339
|
+
await unlink(donePath);
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
// no-op
|
|
343
|
+
}
|
|
344
|
+
await killWorkerPane(runtime, wName, active.paneId);
|
|
345
|
+
if (!(await allTasksTerminal(runtime))) {
|
|
346
|
+
const nextTaskIndexValue = await nextPendingTaskIndex(runtime);
|
|
347
|
+
if (nextTaskIndexValue != null) {
|
|
348
|
+
await spawnWorkerForTask(runtime, wName, nextTaskIndexValue);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
// Dead pane without done.json => fail task, do not requeue
|
|
354
|
+
const alive = aliveResults[i];
|
|
355
|
+
if (!alive) {
|
|
356
|
+
unresponsiveCounts.delete(wName);
|
|
357
|
+
await markTaskFailedDeadPane(root, active.taskId, wName);
|
|
358
|
+
await killWorkerPane(runtime, wName, active.paneId);
|
|
359
|
+
if (!(await allTasksTerminal(runtime))) {
|
|
360
|
+
const nextTaskIndexValue = await nextPendingTaskIndex(runtime);
|
|
361
|
+
if (nextTaskIndexValue != null) {
|
|
362
|
+
await spawnWorkerForTask(runtime, wName, nextTaskIndexValue);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
// Pane is alive but no done.json — check heartbeat for stall detection
|
|
368
|
+
const heartbeatPath = join(root, 'workers', wName, 'heartbeat.json');
|
|
369
|
+
const heartbeat = await readJsonSafe(heartbeatPath);
|
|
370
|
+
const isStalled = heartbeat?.updatedAt
|
|
371
|
+
? Date.now() - new Date(heartbeat.updatedAt).getTime() > 60_000
|
|
372
|
+
: false;
|
|
373
|
+
if (isStalled) {
|
|
374
|
+
const count = (unresponsiveCounts.get(wName) ?? 0) + 1;
|
|
375
|
+
unresponsiveCounts.set(wName, count);
|
|
376
|
+
if (count < UNRESPONSIVE_KILL_THRESHOLD) {
|
|
377
|
+
console.warn(`[watchdog] worker ${wName} unresponsive (${count}/${UNRESPONSIVE_KILL_THRESHOLD}), task ${active.taskId}`);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
console.warn(`[watchdog] worker ${wName} unresponsive ${count} consecutive ticks — killing and reassigning task ${active.taskId}`);
|
|
381
|
+
unresponsiveCounts.delete(wName);
|
|
382
|
+
await markTaskFailedDeadPane(root, active.taskId, wName);
|
|
383
|
+
await killWorkerPane(runtime, wName, active.paneId);
|
|
384
|
+
if (!(await allTasksTerminal(runtime))) {
|
|
385
|
+
const nextTaskIndexValue = await nextPendingTaskIndex(runtime);
|
|
386
|
+
if (nextTaskIndexValue != null) {
|
|
387
|
+
await spawnWorkerForTask(runtime, wName, nextTaskIndexValue);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
// Worker is responsive — reset counter
|
|
394
|
+
unresponsiveCounts.delete(wName);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// Reset failure counter on a successful tick
|
|
398
|
+
consecutiveFailures = 0;
|
|
399
|
+
}
|
|
400
|
+
catch (err) {
|
|
401
|
+
consecutiveFailures++;
|
|
402
|
+
console.warn('[watchdog] tick error:', err);
|
|
403
|
+
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
|
404
|
+
console.warn(`[watchdog] ${consecutiveFailures} consecutive failures — marking team as failed`);
|
|
405
|
+
try {
|
|
406
|
+
const root = stateRoot(runtime.cwd, runtime.teamName);
|
|
407
|
+
await writeJson(join(root, 'watchdog-failed.json'), {
|
|
408
|
+
failedAt: new Date().toISOString(),
|
|
409
|
+
consecutiveFailures,
|
|
410
|
+
lastError: err instanceof Error ? err.message : String(err),
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
// best-effort
|
|
415
|
+
}
|
|
416
|
+
clearInterval(intervalId);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
finally {
|
|
420
|
+
tickInFlight = false;
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
const intervalId = setInterval(() => { tick(); }, intervalMs);
|
|
424
|
+
return () => clearInterval(intervalId);
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Spawn a worker pane for an explicit task assignment.
|
|
428
|
+
*/
|
|
429
|
+
export async function spawnWorkerForTask(runtime, workerNameValue, taskIndex) {
|
|
430
|
+
const root = stateRoot(runtime.cwd, runtime.teamName);
|
|
431
|
+
const taskId = String(taskIndex + 1);
|
|
432
|
+
const task = runtime.config.tasks[taskIndex];
|
|
433
|
+
if (!task)
|
|
434
|
+
return '';
|
|
435
|
+
const marked = await markTaskInProgress(root, taskId, workerNameValue, runtime.teamName, runtime.cwd);
|
|
436
|
+
if (!marked)
|
|
437
|
+
return '';
|
|
438
|
+
const { execFile } = await import('child_process');
|
|
439
|
+
const { promisify } = await import('util');
|
|
440
|
+
const execFileAsync = promisify(execFile);
|
|
441
|
+
const splitTarget = runtime.workerPaneIds.length === 0
|
|
442
|
+
? runtime.leaderPaneId
|
|
443
|
+
: runtime.workerPaneIds[runtime.workerPaneIds.length - 1];
|
|
444
|
+
const splitType = runtime.workerPaneIds.length === 0 ? '-h' : '-v';
|
|
445
|
+
const splitResult = await execFileAsync('tmux', [
|
|
446
|
+
'split-window', splitType, '-t', splitTarget,
|
|
447
|
+
'-d', '-P', '-F', '#{pane_id}',
|
|
448
|
+
'-c', runtime.cwd,
|
|
449
|
+
]);
|
|
450
|
+
const paneId = splitResult.stdout.split('\n')[0]?.trim();
|
|
451
|
+
if (!paneId)
|
|
452
|
+
return '';
|
|
453
|
+
const workerIndex = parseWorkerIndex(workerNameValue);
|
|
454
|
+
const agentType = runtime.config.agentTypes[workerIndex % runtime.config.agentTypes.length]
|
|
455
|
+
?? runtime.config.agentTypes[0]
|
|
456
|
+
?? 'claude';
|
|
457
|
+
const usePromptMode = isPromptModeAgent(agentType);
|
|
458
|
+
// Build the initial task instruction and write inbox before spawn.
|
|
459
|
+
// For prompt-mode agents the instruction is passed via CLI flag;
|
|
460
|
+
// for interactive agents it is sent via tmux send-keys after startup.
|
|
461
|
+
const instruction = buildInitialTaskInstruction(runtime.teamName, workerNameValue, task, taskId);
|
|
462
|
+
await composeInitialInbox(runtime.teamName, workerNameValue, instruction, runtime.cwd);
|
|
463
|
+
const relInboxPath = `.omc/state/team/${runtime.teamName}/workers/${workerNameValue}/inbox.md`;
|
|
464
|
+
const envVars = getModelWorkerEnv(runtime.teamName, workerNameValue, agentType);
|
|
465
|
+
const [launchBinary, ...launchArgs] = buildWorkerArgv(agentType, {
|
|
466
|
+
teamName: runtime.teamName,
|
|
467
|
+
workerName: workerNameValue,
|
|
468
|
+
cwd: runtime.cwd,
|
|
469
|
+
});
|
|
470
|
+
// For prompt-mode agents (e.g. Gemini Ink TUI), pass instruction via CLI
|
|
471
|
+
// flag so tmux send-keys never needs to interact with the TUI input widget.
|
|
472
|
+
if (usePromptMode) {
|
|
473
|
+
const promptArgs = getPromptModeArgs(agentType, `Read and execute your task from: ${relInboxPath}`);
|
|
474
|
+
launchArgs.push(...promptArgs);
|
|
475
|
+
}
|
|
476
|
+
const paneConfig = {
|
|
477
|
+
teamName: runtime.teamName,
|
|
478
|
+
workerName: workerNameValue,
|
|
479
|
+
envVars,
|
|
480
|
+
launchBinary,
|
|
481
|
+
launchArgs,
|
|
482
|
+
cwd: runtime.cwd,
|
|
483
|
+
};
|
|
484
|
+
await spawnWorkerInPane(runtime.sessionName, paneId, paneConfig);
|
|
485
|
+
runtime.workerPaneIds.push(paneId);
|
|
486
|
+
runtime.activeWorkers.set(workerNameValue, { paneId, taskId, spawnedAt: Date.now() });
|
|
487
|
+
try {
|
|
488
|
+
await execFileAsync('tmux', ['select-layout', '-t', runtime.sessionName, 'main-vertical']);
|
|
489
|
+
}
|
|
490
|
+
catch {
|
|
491
|
+
// layout update is best-effort
|
|
492
|
+
}
|
|
493
|
+
try {
|
|
494
|
+
await writePanesTrackingFileIfPresent(runtime);
|
|
495
|
+
}
|
|
496
|
+
catch {
|
|
497
|
+
// panes tracking is best-effort
|
|
498
|
+
}
|
|
499
|
+
if (!usePromptMode) {
|
|
500
|
+
// Interactive mode: wait for CLI startup, handle trust-confirm, then
|
|
501
|
+
// send instruction via tmux send-keys.
|
|
502
|
+
await new Promise(r => setTimeout(r, 4000));
|
|
503
|
+
if (agentType === 'gemini') {
|
|
504
|
+
const confirmed = await notifyPaneWithRetry(runtime.sessionName, paneId, '1');
|
|
505
|
+
if (!confirmed) {
|
|
506
|
+
await killWorkerPane(runtime, workerNameValue, paneId);
|
|
507
|
+
await resetTaskToPending(root, taskId);
|
|
508
|
+
throw new Error(`worker_notify_failed:${workerNameValue}:trust-confirm`);
|
|
509
|
+
}
|
|
510
|
+
await new Promise(r => setTimeout(r, 800));
|
|
511
|
+
}
|
|
512
|
+
const notified = await notifyPaneWithRetry(runtime.sessionName, paneId, `Read and execute your task from: ${relInboxPath}`);
|
|
513
|
+
if (!notified) {
|
|
514
|
+
await killWorkerPane(runtime, workerNameValue, paneId);
|
|
515
|
+
await resetTaskToPending(root, taskId);
|
|
516
|
+
throw new Error(`worker_notify_failed:${workerNameValue}:initial-inbox`);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
// Prompt-mode agents: instruction already passed via CLI flag at spawn.
|
|
520
|
+
// No trust-confirm or tmux send-keys interaction needed.
|
|
521
|
+
return paneId;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Kill a single worker pane and update runtime state.
|
|
525
|
+
*/
|
|
526
|
+
export async function killWorkerPane(runtime, workerNameValue, paneId) {
|
|
527
|
+
try {
|
|
528
|
+
const { execFile } = await import('child_process');
|
|
529
|
+
const { promisify } = await import('util');
|
|
530
|
+
const execFileAsync = promisify(execFile);
|
|
531
|
+
await execFileAsync('tmux', ['kill-pane', '-t', paneId]);
|
|
532
|
+
}
|
|
533
|
+
catch {
|
|
534
|
+
// idempotent: pane may already be gone
|
|
535
|
+
}
|
|
536
|
+
const paneIndex = runtime.workerPaneIds.indexOf(paneId);
|
|
537
|
+
if (paneIndex >= 0) {
|
|
538
|
+
runtime.workerPaneIds.splice(paneIndex, 1);
|
|
539
|
+
}
|
|
540
|
+
runtime.activeWorkers.delete(workerNameValue);
|
|
541
|
+
try {
|
|
542
|
+
await writePanesTrackingFileIfPresent(runtime);
|
|
543
|
+
}
|
|
544
|
+
catch {
|
|
545
|
+
// panes tracking is best-effort
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Assign a task to a specific worker via inbox + tmux trigger.
|
|
550
|
+
*/
|
|
551
|
+
export async function assignTask(teamName, taskId, targetWorkerName, paneId, sessionName, cwd) {
|
|
552
|
+
const root = stateRoot(cwd, teamName);
|
|
553
|
+
const taskFilePath = join(root, 'tasks', `${taskId}.json`);
|
|
554
|
+
let previousTaskState = null;
|
|
555
|
+
let lockedTask = null;
|
|
556
|
+
await withTaskLock(teamName, taskId, async () => {
|
|
557
|
+
const t = await readJsonSafe(taskFilePath);
|
|
558
|
+
lockedTask = t;
|
|
559
|
+
previousTaskState = t ? {
|
|
560
|
+
status: t.status,
|
|
561
|
+
owner: t.owner,
|
|
562
|
+
assignedAt: t.assignedAt,
|
|
563
|
+
} : null;
|
|
564
|
+
if (t) {
|
|
565
|
+
t.owner = targetWorkerName;
|
|
566
|
+
t.status = 'in_progress';
|
|
567
|
+
t.assignedAt = new Date().toISOString();
|
|
568
|
+
await writeJson(taskFilePath, t);
|
|
569
|
+
}
|
|
570
|
+
}, { cwd });
|
|
571
|
+
// Write to worker inbox
|
|
572
|
+
const inboxPath = join(root, 'workers', targetWorkerName, 'inbox.md');
|
|
573
|
+
await mkdir(join(inboxPath, '..'), { recursive: true });
|
|
574
|
+
const msg = `\n\n---\n## New Task Assignment\nTask ID: ${taskId}\nClaim and execute task from: .omc/state/team/${teamName}/tasks/${taskId}.json\n`;
|
|
575
|
+
const { appendFile } = await import('fs/promises');
|
|
576
|
+
await appendFile(inboxPath, msg, 'utf-8');
|
|
577
|
+
// Send tmux trigger
|
|
578
|
+
const notified = await notifyPaneWithRetry(sessionName, paneId, `new-task:${taskId}`);
|
|
579
|
+
if (!notified) {
|
|
580
|
+
if (lockedTask && previousTaskState) {
|
|
581
|
+
const rollback = lockedTask;
|
|
582
|
+
rollback.status = previousTaskState.status;
|
|
583
|
+
rollback.owner = previousTaskState.owner;
|
|
584
|
+
rollback.assignedAt = previousTaskState.assignedAt;
|
|
585
|
+
await writeJson(taskFilePath, rollback);
|
|
586
|
+
}
|
|
587
|
+
throw new Error(`worker_notify_failed:${targetWorkerName}:new-task:${taskId}`);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Gracefully shut down all workers and clean up.
|
|
592
|
+
*/
|
|
593
|
+
export async function shutdownTeam(teamName, sessionName, cwd, timeoutMs = 30_000, workerPaneIds, leaderPaneId) {
|
|
594
|
+
const root = stateRoot(cwd, teamName);
|
|
595
|
+
// Write shutdown request
|
|
596
|
+
await writeJson(join(root, 'shutdown.json'), {
|
|
597
|
+
requestedAt: new Date().toISOString(),
|
|
598
|
+
teamName,
|
|
599
|
+
});
|
|
600
|
+
const configData = await readJsonSafe(join(root, 'config.json'));
|
|
601
|
+
// CLI workers (claude/codex/gemini tmux pane processes) never write shutdown-ack.json.
|
|
602
|
+
// Polling for ACK files on CLI worker teams wastes the full timeoutMs on every shutdown.
|
|
603
|
+
// Detect CLI worker teams by checking if all agent types are known CLI types, and skip
|
|
604
|
+
// ACK polling — the tmux kill below handles process cleanup instead.
|
|
605
|
+
const CLI_AGENT_TYPES = new Set(['claude', 'codex', 'gemini']);
|
|
606
|
+
const agentTypes = configData?.agentTypes ?? [];
|
|
607
|
+
const isCliWorkerTeam = agentTypes.length > 0 && agentTypes.every(t => CLI_AGENT_TYPES.has(t));
|
|
608
|
+
if (!isCliWorkerTeam) {
|
|
609
|
+
// Bridge daemon workers do write shutdown-ack.json — poll for them.
|
|
610
|
+
const deadline = Date.now() + timeoutMs;
|
|
611
|
+
const workerCount = configData?.workerCount ?? 0;
|
|
612
|
+
const expectedAcks = Array.from({ length: workerCount }, (_, i) => `worker-${i + 1}`);
|
|
613
|
+
while (Date.now() < deadline && expectedAcks.length > 0) {
|
|
614
|
+
for (const wName of [...expectedAcks]) {
|
|
615
|
+
const ackPath = join(root, 'workers', wName, 'shutdown-ack.json');
|
|
616
|
+
if (existsSync(ackPath)) {
|
|
617
|
+
expectedAcks.splice(expectedAcks.indexOf(wName), 1);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if (expectedAcks.length > 0) {
|
|
621
|
+
await new Promise(r => setTimeout(r, 500));
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
// CLI worker teams: skip ACK polling — process exit is handled by tmux kill below.
|
|
626
|
+
// Kill tmux session (or just worker panes in split-pane mode)
|
|
627
|
+
await killTeamSession(sessionName, workerPaneIds, leaderPaneId);
|
|
628
|
+
// Clean up state
|
|
629
|
+
try {
|
|
630
|
+
await rm(root, { recursive: true, force: true });
|
|
631
|
+
}
|
|
632
|
+
catch {
|
|
633
|
+
// Ignore cleanup errors
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Resume an existing team from persisted state.
|
|
638
|
+
* Reconstructs activeWorkers by scanning task files for in_progress tasks
|
|
639
|
+
* so the watchdog loop can continue processing without stalling.
|
|
640
|
+
*/
|
|
641
|
+
export async function resumeTeam(teamName, cwd) {
|
|
642
|
+
const root = stateRoot(cwd, teamName);
|
|
643
|
+
const configData = await readJsonSafe(join(root, 'config.json'));
|
|
644
|
+
if (!configData)
|
|
645
|
+
return null;
|
|
646
|
+
// Check if session is alive
|
|
647
|
+
const { execFile } = await import('child_process');
|
|
648
|
+
const { promisify } = await import('util');
|
|
649
|
+
const execFileAsync = promisify(execFile);
|
|
650
|
+
const sName = `omc-team-${teamName}`;
|
|
651
|
+
try {
|
|
652
|
+
await execFileAsync('tmux', ['has-session', '-t', sName]);
|
|
653
|
+
}
|
|
654
|
+
catch {
|
|
655
|
+
return null; // Session not alive
|
|
656
|
+
}
|
|
657
|
+
// Read saved pane IDs (if we save them — for now derive from session)
|
|
658
|
+
const panesResult = await execFileAsync('tmux', [
|
|
659
|
+
'list-panes', '-t', sName, '-F', '#{pane_id}'
|
|
660
|
+
]);
|
|
661
|
+
const allPanes = panesResult.stdout.trim().split('\n').filter(Boolean);
|
|
662
|
+
// First pane is leader, rest are workers
|
|
663
|
+
const workerPaneIds = allPanes.slice(1);
|
|
664
|
+
const workerNames = workerPaneIds.map((_, i) => `worker-${i + 1}`);
|
|
665
|
+
// Reconstruct activeWorkers by scanning task files for in_progress tasks.
|
|
666
|
+
// Build a paneId lookup: worker-N maps to workerPaneIds[N-1].
|
|
667
|
+
const paneByWorker = new Map(workerNames.map((wName, i) => [wName, workerPaneIds[i] ?? '']));
|
|
668
|
+
const activeWorkers = new Map();
|
|
669
|
+
for (let i = 0; i < configData.tasks.length; i++) {
|
|
670
|
+
const taskId = String(i + 1);
|
|
671
|
+
const task = await readTask(root, taskId);
|
|
672
|
+
if (task?.status === 'in_progress' && task.owner) {
|
|
673
|
+
const paneId = paneByWorker.get(task.owner) ?? '';
|
|
674
|
+
activeWorkers.set(task.owner, {
|
|
675
|
+
paneId,
|
|
676
|
+
taskId,
|
|
677
|
+
spawnedAt: task.assignedAt ? new Date(task.assignedAt).getTime() : Date.now(),
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return {
|
|
682
|
+
teamName,
|
|
683
|
+
sessionName: sName,
|
|
684
|
+
leaderPaneId: allPanes[0] ?? '',
|
|
685
|
+
config: configData,
|
|
686
|
+
workerNames,
|
|
687
|
+
workerPaneIds,
|
|
688
|
+
activeWorkers,
|
|
689
|
+
cwd,
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
//# sourceMappingURL=runtime.js.map
|