claudecode-omc 4.8.2 → 4.8.3
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 +3 -3
- package/.claude-plugin/plugin.json +3 -3
- package/README.de.md +60 -0
- package/README.es.md +60 -0
- package/README.fr.md +60 -0
- package/README.it.md +60 -0
- package/README.ja.md +60 -0
- package/README.ko.md +60 -0
- package/README.md +101 -16
- package/README.pt.md +60 -0
- package/README.ru.md +60 -0
- package/README.tr.md +60 -0
- package/README.vi.md +60 -0
- package/README.zh.md +60 -0
- package/agents/code-reviewer.md +107 -6
- package/agents/critic.md +212 -42
- package/agents/debugger.md +52 -4
- package/agents/document-specialist.md +39 -60
- package/agents/executor.md +29 -9
- package/agents/explore.md +3 -1
- package/agents/security-reviewer.md +57 -0
- package/agents/test-engineer.md +21 -0
- package/agents/verifier.md +2 -0
- package/agents/writer.md +2 -0
- package/bridge/cli.cjs +7402 -3580
- package/bridge/mcp-server.cjs +558 -43
- package/bridge/runtime-cli.cjs +3034 -1801
- package/bridge/team-bridge.cjs +25 -1
- package/bridge/team-mcp.cjs +257 -88
- package/bridge/team.js +5226 -413
- package/dist/__tests__/agent-boundary-guidance.test.d.ts +2 -0
- package/dist/__tests__/agent-boundary-guidance.test.d.ts.map +1 -0
- package/dist/__tests__/agent-boundary-guidance.test.js +48 -0
- package/dist/__tests__/agent-boundary-guidance.test.js.map +1 -0
- package/dist/__tests__/agent-registry.test.js +48 -11
- package/dist/__tests__/agent-registry.test.js.map +1 -1
- package/dist/__tests__/auto-slash-aliases.test.js +25 -0
- package/dist/__tests__/auto-slash-aliases.test.js.map +1 -1
- package/dist/__tests__/bedrock-model-routing.test.d.ts +21 -0
- package/dist/__tests__/bedrock-model-routing.test.d.ts.map +1 -0
- package/dist/__tests__/bedrock-model-routing.test.js +397 -0
- package/dist/__tests__/bedrock-model-routing.test.js.map +1 -0
- package/dist/__tests__/cleanup-validation.test.js +7 -3
- package/dist/__tests__/cleanup-validation.test.js.map +1 -1
- package/dist/__tests__/cli-win32-warning.test.js +15 -2
- package/dist/__tests__/cli-win32-warning.test.js.map +1 -1
- package/dist/__tests__/consolidation-contracts.test.js +28 -3
- package/dist/__tests__/consolidation-contracts.test.js.map +1 -1
- package/dist/__tests__/context-guard-stop.test.d.ts +2 -0
- package/dist/__tests__/context-guard-stop.test.d.ts.map +1 -0
- package/dist/__tests__/context-guard-stop.test.js +58 -0
- package/dist/__tests__/context-guard-stop.test.js.map +1 -0
- package/dist/__tests__/delegation-enforcer.test.js +76 -11
- package/dist/__tests__/delegation-enforcer.test.js.map +1 -1
- package/dist/__tests__/doctor-conflicts.test.js +62 -1
- package/dist/__tests__/doctor-conflicts.test.js.map +1 -1
- package/dist/__tests__/hooks.test.js +165 -4
- package/dist/__tests__/hooks.test.js.map +1 -1
- package/dist/__tests__/hud/defaults.test.js +4 -0
- package/dist/__tests__/hud/defaults.test.js.map +1 -1
- package/dist/__tests__/hud/limits-error.test.js +2 -4
- package/dist/__tests__/hud/limits-error.test.js.map +1 -1
- package/dist/__tests__/hud/mission-board-state.test.d.ts +2 -0
- package/dist/__tests__/hud/mission-board-state.test.d.ts.map +1 -0
- package/dist/__tests__/hud/mission-board-state.test.js +170 -0
- package/dist/__tests__/hud/mission-board-state.test.js.map +1 -0
- package/dist/__tests__/hud/mission-board.test.d.ts +2 -0
- package/dist/__tests__/hud/mission-board.test.d.ts.map +1 -0
- package/dist/__tests__/hud/mission-board.test.js +143 -0
- package/dist/__tests__/hud/mission-board.test.js.map +1 -0
- package/dist/__tests__/hud/rate-limits-error.test.js +13 -0
- package/dist/__tests__/hud/rate-limits-error.test.js.map +1 -1
- package/dist/__tests__/hud/render-rate-limits-priority.test.d.ts +8 -0
- package/dist/__tests__/hud/render-rate-limits-priority.test.d.ts.map +1 -0
- package/dist/__tests__/hud/render-rate-limits-priority.test.js +145 -0
- package/dist/__tests__/hud/render-rate-limits-priority.test.js.map +1 -0
- package/dist/__tests__/hud/render.test.js +22 -0
- package/dist/__tests__/hud/render.test.js.map +1 -1
- package/dist/__tests__/hud/stale-indicator.test.d.ts +9 -0
- package/dist/__tests__/hud/stale-indicator.test.d.ts.map +1 -0
- package/dist/__tests__/hud/stale-indicator.test.js +81 -0
- package/dist/__tests__/hud/stale-indicator.test.js.map +1 -0
- package/dist/__tests__/hud/state.test.js +30 -0
- package/dist/__tests__/hud/state.test.js.map +1 -1
- package/dist/__tests__/hud/usage-api-lock.test.d.ts +2 -0
- package/dist/__tests__/hud/usage-api-lock.test.d.ts.map +1 -0
- package/dist/__tests__/hud/usage-api-lock.test.js +245 -0
- package/dist/__tests__/hud/usage-api-lock.test.js.map +1 -0
- package/dist/__tests__/hud/usage-api-stale.test.d.ts +9 -0
- package/dist/__tests__/hud/usage-api-stale.test.d.ts.map +1 -0
- package/dist/__tests__/hud/usage-api-stale.test.js +297 -0
- package/dist/__tests__/hud/usage-api-stale.test.js.map +1 -0
- package/dist/__tests__/hud/usage-api.test.js +223 -0
- package/dist/__tests__/hud/usage-api.test.js.map +1 -1
- package/dist/__tests__/hud/watch-mode-init.test.d.ts +2 -0
- package/dist/__tests__/hud/watch-mode-init.test.d.ts.map +1 -0
- package/dist/__tests__/hud/watch-mode-init.test.js +133 -0
- package/dist/__tests__/hud/watch-mode-init.test.js.map +1 -0
- package/dist/__tests__/hud-agents.test.js +12 -10
- package/dist/__tests__/hud-agents.test.js.map +1 -1
- package/dist/__tests__/hud-build-guidance.test.js +6 -2
- package/dist/__tests__/hud-build-guidance.test.js.map +1 -1
- package/dist/__tests__/hud-marketplace-resolution.test.d.ts +2 -0
- package/dist/__tests__/hud-marketplace-resolution.test.d.ts.map +1 -0
- package/dist/__tests__/hud-marketplace-resolution.test.js +53 -0
- package/dist/__tests__/hud-marketplace-resolution.test.js.map +1 -0
- package/dist/__tests__/installer-hud-skip.test.js +12 -0
- package/dist/__tests__/installer-hud-skip.test.js.map +1 -1
- package/dist/__tests__/installer-plugin-agents.test.d.ts +2 -0
- package/dist/__tests__/installer-plugin-agents.test.d.ts.map +1 -0
- package/dist/__tests__/installer-plugin-agents.test.js +111 -0
- package/dist/__tests__/installer-plugin-agents.test.js.map +1 -0
- package/dist/__tests__/installer-version-guard.test.d.ts +2 -0
- package/dist/__tests__/installer-version-guard.test.d.ts.map +1 -0
- package/dist/__tests__/installer-version-guard.test.js +75 -0
- package/dist/__tests__/installer-version-guard.test.js.map +1 -0
- package/dist/__tests__/installer.test.js +58 -4
- package/dist/__tests__/installer.test.js.map +1 -1
- package/dist/__tests__/omc-tools-server.test.js +8 -5
- package/dist/__tests__/omc-tools-server.test.js.map +1 -1
- package/dist/__tests__/pre-tool-enforcer.test.js +38 -0
- package/dist/__tests__/pre-tool-enforcer.test.js.map +1 -1
- package/dist/__tests__/prompt-injection.test.js +3 -3
- package/dist/__tests__/prompt-injection.test.js.map +1 -1
- package/dist/__tests__/ralph-prd-mandatory.test.js +53 -2
- package/dist/__tests__/ralph-prd-mandatory.test.js.map +1 -1
- package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.js +42 -0
- package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.js.map +1 -1
- package/dist/__tests__/rate-limit-wait/tmux-detector.test.js +1 -1
- package/dist/__tests__/session-history-search.test.d.ts +2 -0
- package/dist/__tests__/session-history-search.test.d.ts.map +1 -0
- package/dist/__tests__/session-history-search.test.js +115 -0
- package/dist/__tests__/session-history-search.test.js.map +1 -0
- package/dist/__tests__/session-start-script-context.test.d.ts +2 -0
- package/dist/__tests__/session-start-script-context.test.d.ts.map +1 -0
- package/dist/__tests__/session-start-script-context.test.js +49 -0
- package/dist/__tests__/session-start-script-context.test.js.map +1 -0
- package/dist/__tests__/skills.test.js +71 -24
- package/dist/__tests__/skills.test.js.map +1 -1
- package/dist/__tests__/standalone-server.test.js +8 -4
- package/dist/__tests__/standalone-server.test.js.map +1 -1
- package/dist/__tests__/tier0-docs-consistency.test.js +10 -2
- package/dist/__tests__/tier0-docs-consistency.test.js.map +1 -1
- package/dist/agents/definitions.d.ts +5 -15
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +48 -49
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/document-specialist.d.ts +1 -1
- package/dist/agents/document-specialist.d.ts.map +1 -1
- package/dist/agents/document-specialist.js +46 -21
- package/dist/agents/document-specialist.js.map +1 -1
- package/dist/agents/explore.d.ts.map +1 -1
- package/dist/agents/explore.js +3 -2
- package/dist/agents/explore.js.map +1 -1
- package/dist/agents/index.d.ts +2 -4
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +3 -6
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/types.d.ts +2 -2
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/cli/__tests__/ask.test.js +255 -8
- package/dist/cli/__tests__/ask.test.js.map +1 -1
- package/dist/cli/__tests__/session-search-help.test.d.ts +2 -0
- package/dist/cli/__tests__/session-search-help.test.d.ts.map +1 -0
- package/dist/cli/__tests__/session-search-help.test.js +13 -0
- package/dist/cli/__tests__/session-search-help.test.js.map +1 -0
- package/dist/cli/__tests__/session-search.test.d.ts +2 -0
- package/dist/cli/__tests__/session-search.test.d.ts.map +1 -0
- package/dist/cli/__tests__/session-search.test.js +72 -0
- package/dist/cli/__tests__/session-search.test.js.map +1 -0
- package/dist/cli/__tests__/team-help.test.js +1 -1
- package/dist/cli/__tests__/team-help.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +256 -4
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/commands/__tests__/team.test.js +52 -2
- package/dist/cli/commands/__tests__/team.test.js.map +1 -1
- package/dist/cli/commands/doctor-conflicts.d.ts.map +1 -1
- package/dist/cli/commands/doctor-conflicts.js +15 -1
- package/dist/cli/commands/doctor-conflicts.js.map +1 -1
- package/dist/cli/commands/session-search.d.ts +18 -0
- package/dist/cli/commands/session-search.d.ts.map +1 -0
- package/dist/cli/commands/session-search.js +47 -0
- package/dist/cli/commands/session-search.js.map +1 -0
- package/dist/cli/commands/team.d.ts +11 -0
- package/dist/cli/commands/team.d.ts.map +1 -1
- package/dist/cli/commands/team.js +94 -24
- package/dist/cli/commands/team.js.map +1 -1
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +12 -1
- package/dist/cli/commands/wait.js.map +1 -1
- package/dist/cli/index.js +70 -2
- package/dist/cli/index.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 +100 -214
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/win32-warning.d.ts +2 -1
- package/dist/cli/win32-warning.d.ts.map +1 -1
- package/dist/cli/win32-warning.js +20 -6
- package/dist/cli/win32-warning.js.map +1 -1
- package/dist/config/__tests__/loader.test.d.ts +2 -0
- package/dist/config/__tests__/loader.test.d.ts.map +1 -0
- package/dist/config/__tests__/loader.test.js +145 -0
- package/dist/config/__tests__/loader.test.js.map +1 -0
- package/dist/config/__tests__/models.test.d.ts +2 -0
- package/dist/config/__tests__/models.test.d.ts.map +1 -0
- package/dist/config/__tests__/models.test.js +147 -0
- package/dist/config/__tests__/models.test.js.map +1 -0
- package/dist/config/__tests__/test-helpers.d.ts +3 -0
- package/dist/config/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/config/__tests__/test-helpers.js +19 -0
- package/dist/config/__tests__/test-helpers.js.map +1 -0
- package/dist/config/loader.d.ts +3 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +140 -126
- package/dist/config/loader.js.map +1 -1
- package/dist/config/models.d.ts +29 -10
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +96 -10
- package/dist/config/models.js.map +1 -1
- package/dist/features/builtin-skills/skills.d.ts.map +1 -1
- package/dist/features/builtin-skills/skills.js +8 -1
- package/dist/features/builtin-skills/skills.js.map +1 -1
- package/dist/features/builtin-skills/types.d.ts +3 -0
- package/dist/features/builtin-skills/types.d.ts.map +1 -1
- package/dist/features/delegation-enforcer.d.ts +5 -12
- package/dist/features/delegation-enforcer.d.ts.map +1 -1
- package/dist/features/delegation-enforcer.js +48 -54
- package/dist/features/delegation-enforcer.js.map +1 -1
- package/dist/features/delegation-routing/__tests__/resolver.test.js +4 -3
- package/dist/features/delegation-routing/__tests__/resolver.test.js.map +1 -1
- package/dist/features/delegation-routing/types.d.ts.map +1 -1
- package/dist/features/delegation-routing/types.js +7 -4
- package/dist/features/delegation-routing/types.js.map +1 -1
- package/dist/features/index.d.ts +1 -0
- package/dist/features/index.d.ts.map +1 -1
- package/dist/features/index.js +2 -0
- package/dist/features/index.js.map +1 -1
- package/dist/features/rate-limit-wait/daemon.d.ts.map +1 -1
- package/dist/features/rate-limit-wait/daemon.js +8 -5
- package/dist/features/rate-limit-wait/daemon.js.map +1 -1
- package/dist/features/rate-limit-wait/index.d.ts +1 -1
- package/dist/features/rate-limit-wait/index.d.ts.map +1 -1
- package/dist/features/rate-limit-wait/index.js +1 -1
- package/dist/features/rate-limit-wait/index.js.map +1 -1
- package/dist/features/rate-limit-wait/rate-limit-monitor.d.ts +9 -0
- package/dist/features/rate-limit-wait/rate-limit-monitor.d.ts.map +1 -1
- package/dist/features/rate-limit-wait/rate-limit-monitor.js +38 -0
- package/dist/features/rate-limit-wait/rate-limit-monitor.js.map +1 -1
- package/dist/features/rate-limit-wait/tmux-detector.d.ts +2 -1
- package/dist/features/rate-limit-wait/tmux-detector.d.ts.map +1 -1
- package/dist/features/rate-limit-wait/tmux-detector.js +8 -9
- package/dist/features/rate-limit-wait/tmux-detector.js.map +1 -1
- package/dist/features/rate-limit-wait/types.d.ts +11 -0
- package/dist/features/rate-limit-wait/types.d.ts.map +1 -1
- package/dist/features/session-history-search/index.d.ts +6 -0
- package/dist/features/session-history-search/index.d.ts.map +1 -0
- package/dist/features/session-history-search/index.js +480 -0
- package/dist/features/session-history-search/index.js.map +1 -0
- package/dist/features/session-history-search/types.d.ts +36 -0
- package/dist/features/session-history-search/types.d.ts.map +1 -0
- package/dist/features/session-history-search/types.js +2 -0
- package/dist/features/session-history-search/types.js.map +1 -0
- package/dist/hooks/__tests__/background-process-guard.test.js +101 -5
- package/dist/hooks/__tests__/background-process-guard.test.js.map +1 -1
- package/dist/hooks/__tests__/bridge-openclaw.test.js +16 -5
- package/dist/hooks/__tests__/bridge-openclaw.test.js.map +1 -1
- package/dist/hooks/__tests__/bridge-routing.test.js +48 -1
- package/dist/hooks/__tests__/bridge-routing.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 +9 -1
- package/dist/hooks/auto-slash-command/executor.js.map +1 -1
- package/dist/hooks/auto-slash-command/types.d.ts +2 -0
- package/dist/hooks/auto-slash-command/types.d.ts.map +1 -1
- package/dist/hooks/auto-slash-command/types.js +0 -7
- package/dist/hooks/auto-slash-command/types.js.map +1 -1
- package/dist/hooks/autopilot/adapters/execution-adapter.js +3 -3
- package/dist/hooks/autopilot/prompts.js +1 -1
- package/dist/hooks/bridge-normalize.d.ts.map +1 -1
- package/dist/hooks/bridge-normalize.js +2 -0
- package/dist/hooks/bridge-normalize.js.map +1 -1
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +248 -39
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/keyword-detector/__tests__/index.test.js +41 -0
- package/dist/hooks/keyword-detector/__tests__/index.test.js.map +1 -1
- package/dist/hooks/keyword-detector/index.d.ts +1 -1
- package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
- package/dist/hooks/keyword-detector/index.js +3 -1
- package/dist/hooks/keyword-detector/index.js.map +1 -1
- package/dist/hooks/permission-handler/index.d.ts +8 -0
- package/dist/hooks/permission-handler/index.d.ts.map +1 -1
- package/dist/hooks/permission-handler/index.js +76 -0
- package/dist/hooks/permission-handler/index.js.map +1 -1
- package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.d.ts +2 -0
- package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.d.ts.map +1 -0
- package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.js +90 -0
- package/dist/hooks/persistent-mode/__tests__/ralph-verification-flow.test.js.map +1 -0
- package/dist/hooks/persistent-mode/__tests__/team-ralplan-stop.test.d.ts +2 -0
- package/dist/hooks/persistent-mode/__tests__/team-ralplan-stop.test.d.ts.map +1 -0
- package/dist/hooks/persistent-mode/__tests__/team-ralplan-stop.test.js +535 -0
- package/dist/hooks/persistent-mode/__tests__/team-ralplan-stop.test.js.map +1 -0
- 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 +296 -21
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js +156 -0
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js.map +1 -1
- package/dist/hooks/project-memory/__tests__/integration.test.js +27 -2
- package/dist/hooks/project-memory/__tests__/integration.test.js.map +1 -1
- package/dist/hooks/project-memory/__tests__/storage.test.js +37 -0
- package/dist/hooks/project-memory/__tests__/storage.test.js.map +1 -1
- package/dist/hooks/project-memory/storage.d.ts +1 -1
- package/dist/hooks/project-memory/storage.d.ts.map +1 -1
- package/dist/hooks/project-memory/storage.js +5 -4
- package/dist/hooks/project-memory/storage.js.map +1 -1
- package/dist/hooks/ralph/index.d.ts +1 -1
- package/dist/hooks/ralph/index.d.ts.map +1 -1
- package/dist/hooks/ralph/index.js +1 -1
- package/dist/hooks/ralph/index.js.map +1 -1
- package/dist/hooks/ralph/loop.d.ts +18 -0
- package/dist/hooks/ralph/loop.d.ts.map +1 -1
- package/dist/hooks/ralph/loop.js +31 -0
- package/dist/hooks/ralph/loop.js.map +1 -1
- package/dist/hooks/ralph/verifier.d.ts +4 -1
- package/dist/hooks/ralph/verifier.d.ts.map +1 -1
- package/dist/hooks/ralph/verifier.js +56 -21
- package/dist/hooks/ralph/verifier.js.map +1 -1
- package/dist/hooks/recovery/__tests__/storage.test.d.ts +2 -0
- package/dist/hooks/recovery/__tests__/storage.test.d.ts.map +1 -0
- package/dist/hooks/recovery/__tests__/storage.test.js +65 -0
- package/dist/hooks/recovery/__tests__/storage.test.js.map +1 -0
- package/dist/hooks/recovery/storage.d.ts +5 -1
- package/dist/hooks/recovery/storage.d.ts.map +1 -1
- package/dist/hooks/recovery/storage.js +7 -29
- package/dist/hooks/recovery/storage.js.map +1 -1
- package/dist/hooks/recovery/types.d.ts +1 -1
- package/dist/hooks/recovery/types.d.ts.map +1 -1
- package/dist/hooks/session-end/__tests__/duplicate-notifications.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/duplicate-notifications.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/duplicate-notifications.test.js +140 -0
- package/dist/hooks/session-end/__tests__/duplicate-notifications.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.d.ts +2 -0
- package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.d.ts.map +1 -0
- package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.js +122 -0
- package/dist/hooks/session-end/__tests__/mode-state-cleanup.test.js.map +1 -0
- package/dist/hooks/session-end/__tests__/openclaw-session-end.test.js +38 -12
- package/dist/hooks/session-end/__tests__/openclaw-session-end.test.js.map +1 -1
- package/dist/hooks/session-end/callbacks.d.ts +4 -1
- package/dist/hooks/session-end/callbacks.d.ts.map +1 -1
- package/dist/hooks/session-end/callbacks.js +5 -4
- package/dist/hooks/session-end/callbacks.js.map +1 -1
- package/dist/hooks/session-end/index.d.ts.map +1 -1
- package/dist/hooks/session-end/index.js +162 -36
- package/dist/hooks/session-end/index.js.map +1 -1
- package/dist/hooks/skill-state/__tests__/skill-state.test.js +35 -33
- package/dist/hooks/skill-state/__tests__/skill-state.test.js.map +1 -1
- package/dist/hooks/skill-state/index.d.ts +3 -3
- package/dist/hooks/skill-state/index.d.ts.map +1 -1
- package/dist/hooks/skill-state/index.js +7 -11
- package/dist/hooks/skill-state/index.js.map +1 -1
- package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
- package/dist/hooks/subagent-tracker/index.js +22 -0
- package/dist/hooks/subagent-tracker/index.js.map +1 -1
- package/dist/hooks/think-mode/__tests__/index.test.js +20 -20
- package/dist/hooks/think-mode/__tests__/index.test.js.map +1 -1
- package/dist/hooks/think-mode/switcher.d.ts.map +1 -1
- package/dist/hooks/think-mode/switcher.js +13 -10
- package/dist/hooks/think-mode/switcher.js.map +1 -1
- package/dist/hooks/thinking-block-validator/__tests__/index.test.d.ts +2 -0
- package/dist/hooks/thinking-block-validator/__tests__/index.test.d.ts.map +1 -0
- package/dist/hooks/thinking-block-validator/__tests__/index.test.js +56 -0
- package/dist/hooks/thinking-block-validator/__tests__/index.test.js.map +1 -0
- package/dist/hooks/thinking-block-validator/index.d.ts.map +1 -1
- package/dist/hooks/thinking-block-validator/index.js +7 -6
- package/dist/hooks/thinking-block-validator/index.js.map +1 -1
- package/dist/hooks/todo-continuation/index.d.ts +6 -0
- package/dist/hooks/todo-continuation/index.d.ts.map +1 -1
- package/dist/hooks/todo-continuation/index.js +14 -5
- package/dist/hooks/todo-continuation/index.js.map +1 -1
- package/dist/hud/elements/agents.d.ts.map +1 -1
- package/dist/hud/elements/agents.js +8 -14
- package/dist/hud/elements/agents.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/limits.d.ts +3 -3
- package/dist/hud/elements/limits.d.ts.map +1 -1
- package/dist/hud/elements/limits.js +26 -18
- package/dist/hud/elements/limits.js.map +1 -1
- package/dist/hud/elements/mission-board.d.ts +2 -0
- package/dist/hud/elements/mission-board.d.ts.map +1 -0
- package/dist/hud/elements/mission-board.js +2 -0
- package/dist/hud/elements/mission-board.js.map +1 -0
- package/dist/hud/index.d.ts +1 -1
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +10 -2
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/mission-board.d.ts +75 -0
- package/dist/hud/mission-board.d.ts.map +1 -0
- package/dist/hud/mission-board.js +420 -0
- package/dist/hud/mission-board.js.map +1 -0
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +16 -8
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +13 -0
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/types.d.ts +11 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js +10 -0
- package/dist/hud/types.js.map +1 -1
- package/dist/hud/usage-api.d.ts +1 -1
- package/dist/hud/usage-api.d.ts.map +1 -1
- package/dist/hud/usage-api.js +207 -106
- package/dist/hud/usage-api.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/installer/__tests__/claude-md-merge.test.js +53 -9
- package/dist/installer/__tests__/claude-md-merge.test.js.map +1 -1
- package/dist/installer/__tests__/hook-templates.test.d.ts +2 -0
- package/dist/installer/__tests__/hook-templates.test.d.ts.map +1 -0
- package/dist/installer/__tests__/hook-templates.test.js +76 -0
- package/dist/installer/__tests__/hook-templates.test.js.map +1 -0
- package/dist/installer/hooks.d.ts +15 -0
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +51 -0
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +25 -0
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +273 -64
- package/dist/installer/index.js.map +1 -1
- package/dist/lib/mode-names.d.ts.map +1 -1
- package/dist/lib/mode-names.js +2 -0
- package/dist/lib/mode-names.js.map +1 -1
- package/dist/mcp/__tests__/team-server-artifact-convergence.test.js +30 -3
- package/dist/mcp/__tests__/team-server-artifact-convergence.test.js.map +1 -1
- package/dist/mcp/__tests__/team-server-deprecation.test.js +2 -0
- package/dist/mcp/__tests__/team-server-deprecation.test.js.map +1 -1
- package/dist/mcp/team-job-convergence.d.ts.map +1 -1
- package/dist/mcp/team-job-convergence.js +12 -3
- 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 -4
- package/dist/mcp/team-server.js.map +1 -1
- package/dist/notifications/__tests__/config-merge.test.js +36 -1
- package/dist/notifications/__tests__/config-merge.test.js.map +1 -1
- package/dist/notifications/__tests__/formatter.test.js +13 -5
- package/dist/notifications/__tests__/formatter.test.js.map +1 -1
- package/dist/notifications/__tests__/notify-registry-integration.test.js +27 -1
- package/dist/notifications/__tests__/notify-registry-integration.test.js.map +1 -1
- package/dist/notifications/__tests__/verbosity.test.js +33 -1
- package/dist/notifications/__tests__/verbosity.test.js.map +1 -1
- package/dist/notifications/config.d.ts +7 -0
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +18 -0
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/formatter.d.ts +2 -2
- package/dist/notifications/formatter.d.ts.map +1 -1
- package/dist/notifications/formatter.js +7 -6
- package/dist/notifications/formatter.js.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +5 -3
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/template-engine.js +1 -1
- package/dist/notifications/template-engine.js.map +1 -1
- package/dist/notifications/types.d.ts +4 -0
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/openclaw/__tests__/dispatcher.test.js +26 -0
- package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -1
- package/dist/openclaw/__tests__/index.test.js +42 -0
- package/dist/openclaw/__tests__/index.test.js.map +1 -1
- package/dist/openclaw/__tests__/signal.test.d.ts +2 -0
- package/dist/openclaw/__tests__/signal.test.d.ts.map +1 -0
- package/dist/openclaw/__tests__/signal.test.js +69 -0
- package/dist/openclaw/__tests__/signal.test.js.map +1 -0
- package/dist/openclaw/dispatcher.d.ts +5 -1
- package/dist/openclaw/dispatcher.d.ts.map +1 -1
- package/dist/openclaw/dispatcher.js +13 -2
- package/dist/openclaw/dispatcher.js.map +1 -1
- package/dist/openclaw/index.d.ts +2 -1
- package/dist/openclaw/index.d.ts.map +1 -1
- package/dist/openclaw/index.js +29 -15
- package/dist/openclaw/index.js.map +1 -1
- package/dist/openclaw/signal.d.ts +3 -0
- package/dist/openclaw/signal.d.ts.map +1 -0
- package/dist/openclaw/signal.js +215 -0
- package/dist/openclaw/signal.js.map +1 -0
- package/dist/openclaw/types.d.ts +35 -0
- package/dist/openclaw/types.d.ts.map +1 -1
- package/dist/shared/types.d.ts +2 -12
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/skills/__tests__/mingw-escape.test.js +41 -11
- package/dist/skills/__tests__/mingw-escape.test.js.map +1 -1
- package/dist/team/__tests__/api-interop.cwd-resolution.test.d.ts +2 -0
- package/dist/team/__tests__/api-interop.cwd-resolution.test.d.ts.map +1 -0
- package/dist/team/__tests__/api-interop.cwd-resolution.test.js +78 -0
- package/dist/team/__tests__/api-interop.cwd-resolution.test.js.map +1 -0
- package/dist/team/__tests__/api-interop.dispatch.test.d.ts +2 -0
- package/dist/team/__tests__/api-interop.dispatch.test.d.ts.map +1 -0
- package/dist/team/__tests__/api-interop.dispatch.test.js +125 -0
- package/dist/team/__tests__/api-interop.dispatch.test.js.map +1 -0
- package/dist/team/__tests__/cli-detection.test.d.ts +2 -0
- package/dist/team/__tests__/cli-detection.test.d.ts.map +1 -0
- package/dist/team/__tests__/cli-detection.test.js +36 -0
- package/dist/team/__tests__/cli-detection.test.js.map +1 -0
- package/dist/team/__tests__/model-contract.test.js +79 -2
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/runtime-done-recovery.test.js +1 -0
- package/dist/team/__tests__/runtime-done-recovery.test.js.map +1 -1
- package/dist/team/__tests__/runtime-prompt-mode.test.js +84 -8
- package/dist/team/__tests__/runtime-prompt-mode.test.js.map +1 -1
- package/dist/team/__tests__/runtime-v2.dispatch.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-v2.dispatch.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-v2.dispatch.test.js +237 -0
- package/dist/team/__tests__/runtime-v2.dispatch.test.js.map +1 -0
- package/dist/team/__tests__/runtime-v2.monitor.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-v2.monitor.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-v2.monitor.test.js +103 -0
- package/dist/team/__tests__/runtime-v2.monitor.test.js.map +1 -0
- package/dist/team/__tests__/runtime-v2.shutdown.test.d.ts +2 -0
- package/dist/team/__tests__/runtime-v2.shutdown.test.d.ts.map +1 -0
- package/dist/team/__tests__/runtime-v2.shutdown.test.js +49 -0
- package/dist/team/__tests__/runtime-v2.shutdown.test.js.map +1 -0
- package/dist/team/__tests__/runtime-watchdog-retry.test.js +3 -0
- package/dist/team/__tests__/runtime-watchdog-retry.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.create-team.test.js +29 -12
- package/dist/team/__tests__/tmux-session.create-team.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.kill-team-session.test.js +6 -0
- package/dist/team/__tests__/tmux-session.kill-team-session.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +9 -0
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +32 -3
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +153 -2
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/cli-detection.d.ts.map +1 -1
- package/dist/team/cli-detection.js +6 -2
- package/dist/team/cli-detection.js.map +1 -1
- package/dist/team/idle-nudge.js +1 -1
- package/dist/team/idle-nudge.js.map +1 -1
- package/dist/team/mcp-team-bridge.d.ts.map +1 -1
- package/dist/team/mcp-team-bridge.js +2 -1
- package/dist/team/mcp-team-bridge.js.map +1 -1
- package/dist/team/model-contract.d.ts +1 -1
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +35 -4
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/runtime-cli.d.ts.map +1 -1
- package/dist/team/runtime-cli.js +10 -7
- package/dist/team/runtime-cli.js.map +1 -1
- package/dist/team/runtime-v2.d.ts +4 -0
- package/dist/team/runtime-v2.d.ts.map +1 -1
- package/dist/team/runtime-v2.js +231 -59
- package/dist/team/runtime-v2.js.map +1 -1
- package/dist/team/runtime.d.ts +6 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +39 -14
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/tmux-session.d.ts +20 -11
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +108 -51
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/types.d.ts +1 -0
- package/dist/team/types.d.ts.map +1 -1
- package/dist/team/types.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +2 -0
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +46 -12
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/tools/__tests__/memory-tools.test.js +29 -1
- package/dist/tools/__tests__/memory-tools.test.js.map +1 -1
- package/dist/tools/lsp/client.d.ts +11 -0
- package/dist/tools/lsp/client.d.ts.map +1 -1
- package/dist/tools/lsp/client.js +46 -0
- package/dist/tools/lsp/client.js.map +1 -1
- package/dist/tools/session-history-tools.d.ts +23 -0
- package/dist/tools/session-history-tools.d.ts.map +1 -0
- package/dist/tools/session-history-tools.js +41 -0
- package/dist/tools/session-history-tools.js.map +1 -0
- package/dist/tools/trace-tools.d.ts +9 -0
- package/dist/tools/trace-tools.d.ts.map +1 -1
- package/dist/tools/trace-tools.js +2 -1
- package/dist/tools/trace-tools.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +5 -0
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +22 -0
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/skill-pipeline.d.ts +9 -0
- package/dist/utils/skill-pipeline.d.ts.map +1 -0
- package/dist/utils/skill-pipeline.js +97 -0
- package/dist/utils/skill-pipeline.js.map +1 -0
- package/docs/AGENTS.md +1 -1
- package/docs/ANALYTICS-SYSTEM.md +23 -132
- package/docs/CLAUDE.md +40 -139
- package/docs/MIGRATION.md +4 -4
- package/docs/OPENCLAW-ROUTING.md +102 -0
- package/docs/PERFORMANCE-MONITORING.md +30 -55
- package/docs/REFERENCE.md +62 -35
- package/docs/TIERED_AGENTS_V2.md +3 -2
- package/docs/design/SKILL_AUDIT_1445.md +75 -0
- package/docs/ko/MIGRATION.md +2 -2
- package/docs/ko/REFERENCE.md +14 -22
- package/docs/partials/agent-tiers.md +11 -15
- package/docs/partials/features.md +2 -2
- package/docs/partials/mode-selection-guide.md +2 -2
- package/docs/shared/agent-tiers.md +11 -15
- package/docs/shared/features.md +2 -2
- package/docs/shared/mode-selection-guide.md +2 -2
- package/package.json +4 -1
- package/scripts/code-simplifier.mjs +1 -1
- package/scripts/context-guard-stop.mjs +26 -10
- package/scripts/keyword-detector.mjs +99 -39
- package/scripts/persistent-mode.cjs +295 -34
- package/scripts/persistent-mode.mjs +79 -21
- package/scripts/plugin-setup.mjs +10 -1
- package/scripts/post-tool-verifier.mjs +57 -3
- package/scripts/pre-tool-enforcer.mjs +207 -2
- package/scripts/run-provider-advisor.js +30 -3
- package/scripts/session-start.mjs +3 -3
- package/scripts/setup-claude-md.sh +159 -0
- package/scripts/setup-progress.sh +123 -0
- package/scripts/sync-metadata.ts +11 -1
- package/skills/AGENTS.md +13 -17
- package/skills/ai-slop-cleaner/SKILL.md +130 -0
- package/skills/ask/SKILL.md +51 -0
- package/skills/ccg/SKILL.md +6 -6
- package/skills/deep-interview/SKILL.md +4 -0
- package/skills/omc-doctor/SKILL.md +2 -2
- package/skills/omc-setup/SKILL.md +75 -1206
- package/skills/omc-setup/phases/01-install-claude-md.md +76 -0
- package/skills/omc-setup/phases/02-configure.md +211 -0
- package/skills/omc-setup/phases/03-integrations.md +192 -0
- package/skills/omc-setup/phases/04-welcome.md +192 -0
- package/skills/omc-teams/SKILL.md +35 -2
- package/skills/plan/SKILL.md +3 -0
- package/skills/ralph/SKILL.md +16 -10
- package/skills/release/SKILL.md +4 -0
- package/skills/setup/SKILL.md +40 -0
- package/skills/team/SKILL.md +6 -6
- package/templates/hooks/code-simplifier.mjs +1 -1
- package/templates/hooks/keyword-detector.mjs +100 -32
- package/templates/hooks/persistent-mode.mjs +43 -4
- package/templates/hooks/pre-tool-use.mjs +115 -1
- package/templates/hooks/session-start.mjs +1 -1
- package/agents/build-fixer.md +0 -90
- package/agents/deep-executor.md +0 -112
- package/agents/harsh-critic.md +0 -254
- package/agents/quality-reviewer.md +0 -151
- package/skills/analyze/SKILL.md +0 -87
- package/skills/ask-codex/SKILL.md +0 -47
- package/skills/ask-gemini/SKILL.md +0 -47
- package/skills/build-fix/SKILL.md +0 -123
- package/skills/code-review/SKILL.md +0 -573
- package/skills/configure-openclaw/SKILL.md +0 -383
- package/skills/learn-about-omc/SKILL.md +0 -37
- package/skills/note/SKILL.md +0 -62
- package/skills/omc-help/SKILL.md +0 -192
- package/skills/ralph-init/SKILL.md +0 -40
- package/skills/security-review/SKILL.md +0 -282
- package/skills/tdd/SKILL.md +0 -104
- package/skills/trace/SKILL.md +0 -33
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
writeFileSync,
|
|
15
15
|
readdirSync,
|
|
16
16
|
mkdirSync,
|
|
17
|
+
unlinkSync,
|
|
17
18
|
} = require("fs");
|
|
18
19
|
const { join, dirname, resolve, normalize } = require("path");
|
|
19
20
|
const { homedir } = require("os");
|
|
@@ -130,6 +131,35 @@ async function sendStopNotification(modeName, stateData, sessionId, directory) {
|
|
|
130
131
|
*/
|
|
131
132
|
const STALE_STATE_THRESHOLD_MS = 2 * 60 * 60 * 1000; // 2 hours
|
|
132
133
|
|
|
134
|
+
// Stop breaker constants for first-class mode enforcement
|
|
135
|
+
const TEAM_PIPELINE_STOP_BLOCKER_MAX = 20;
|
|
136
|
+
const TEAM_PIPELINE_STOP_BLOCKER_TTL_MS = 5 * 60 * 1000; // 5 min
|
|
137
|
+
const RALPLAN_STOP_BLOCKER_MAX = 30;
|
|
138
|
+
const RALPLAN_STOP_BLOCKER_TTL_MS = 45 * 60 * 1000; // 45 min
|
|
139
|
+
const TEAM_TERMINAL_PHASES = new Set([
|
|
140
|
+
"completed",
|
|
141
|
+
"complete",
|
|
142
|
+
"failed",
|
|
143
|
+
"cancelled",
|
|
144
|
+
"canceled",
|
|
145
|
+
"aborted",
|
|
146
|
+
"terminated",
|
|
147
|
+
"done",
|
|
148
|
+
]);
|
|
149
|
+
const TEAM_ACTIVE_PHASES = new Set([
|
|
150
|
+
"team-plan",
|
|
151
|
+
"team-prd",
|
|
152
|
+
"team-exec",
|
|
153
|
+
"team-verify",
|
|
154
|
+
"team-fix",
|
|
155
|
+
"planning",
|
|
156
|
+
"executing",
|
|
157
|
+
"verify",
|
|
158
|
+
"verification",
|
|
159
|
+
"fix",
|
|
160
|
+
"fixing",
|
|
161
|
+
]);
|
|
162
|
+
|
|
133
163
|
/**
|
|
134
164
|
* Check if a state is stale based on its timestamps.
|
|
135
165
|
* A state is considered stale if it hasn't been updated recently.
|
|
@@ -150,6 +180,63 @@ function isStaleState(state) {
|
|
|
150
180
|
return age > STALE_STATE_THRESHOLD_MS;
|
|
151
181
|
}
|
|
152
182
|
|
|
183
|
+
function normalizeTeamPhase(state) {
|
|
184
|
+
if (!state || typeof state !== "object") return null;
|
|
185
|
+
|
|
186
|
+
const rawPhase = state.current_phase ?? state.phase ?? state.stage;
|
|
187
|
+
if (typeof rawPhase !== "string") return null;
|
|
188
|
+
|
|
189
|
+
const phase = rawPhase.trim().toLowerCase();
|
|
190
|
+
if (!phase || TEAM_TERMINAL_PHASES.has(phase)) return null;
|
|
191
|
+
return TEAM_ACTIVE_PHASES.has(phase) ? phase : null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function getSafeReinforcementCount(value) {
|
|
195
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0
|
|
196
|
+
? Math.floor(value)
|
|
197
|
+
: 0;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
// Stop Breaker helpers (shared by team pipeline and ralplan)
|
|
202
|
+
// ---------------------------------------------------------------------------
|
|
203
|
+
|
|
204
|
+
function readStopBreaker(stateDir, name, sessionId, ttlMs) {
|
|
205
|
+
const dir = sessionId
|
|
206
|
+
? join(stateDir, "sessions", sessionId)
|
|
207
|
+
: stateDir;
|
|
208
|
+
const breakerPath = join(dir, `${name}-stop-breaker.json`);
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
if (!existsSync(breakerPath)) return 0;
|
|
212
|
+
const raw = JSON.parse(readFileSync(breakerPath, "utf-8"));
|
|
213
|
+
if (ttlMs && raw.updated_at) {
|
|
214
|
+
const updatedAt = new Date(raw.updated_at).getTime();
|
|
215
|
+
if (Number.isFinite(updatedAt) && Date.now() - updatedAt > ttlMs) {
|
|
216
|
+
unlinkSync(breakerPath);
|
|
217
|
+
return 0;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return typeof raw.count === "number" ? raw.count : 0;
|
|
221
|
+
} catch {
|
|
222
|
+
return 0;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function writeStopBreaker(stateDir, name, count, sessionId) {
|
|
227
|
+
const dir = sessionId
|
|
228
|
+
? join(stateDir, "sessions", sessionId)
|
|
229
|
+
: stateDir;
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
233
|
+
const breakerPath = join(dir, `${name}-stop-breaker.json`);
|
|
234
|
+
writeJsonFile(breakerPath, { count, updated_at: new Date().toISOString() });
|
|
235
|
+
} catch {
|
|
236
|
+
// Fail-open
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
153
240
|
/**
|
|
154
241
|
* Check if a cancel signal is in progress for the session.
|
|
155
242
|
* Cancel signals are written by state_clear and expire after 30 seconds.
|
|
@@ -255,7 +342,26 @@ function readStateFileWithSession(stateDir, filename, sessionId) {
|
|
|
255
342
|
if (state) {
|
|
256
343
|
return { state, path: sessionPath, isGlobal: false };
|
|
257
344
|
}
|
|
258
|
-
// Session path not found —
|
|
345
|
+
// Session path not found — fallback: scan ALL session dirs for a state
|
|
346
|
+
// whose session_id matches ours (handles path mismatches)
|
|
347
|
+
try {
|
|
348
|
+
const allSessionsDir = join(stateDir, 'sessions');
|
|
349
|
+
if (existsSync(allSessionsDir)) {
|
|
350
|
+
const dirs = readdirSync(allSessionsDir).filter(d => /^[a-zA-Z0-9]/.test(d));
|
|
351
|
+
for (const dir of dirs) {
|
|
352
|
+
const candidatePath = join(allSessionsDir, dir, filename);
|
|
353
|
+
const candidateState = readJsonFile(candidatePath);
|
|
354
|
+
if (candidateState && candidateState.session_id === sessionId) {
|
|
355
|
+
return { state: candidateState, path: candidatePath, isGlobal: false };
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
} catch { /* ignore scan errors */ }
|
|
360
|
+
// Also check legacy path if its session_id matches
|
|
361
|
+
const legacyResult = readStateFile(stateDir, filename);
|
|
362
|
+
if (legacyResult.state && legacyResult.state.session_id === sessionId) {
|
|
363
|
+
return legacyResult;
|
|
364
|
+
}
|
|
259
365
|
return { state: null, path: null, isGlobal: false };
|
|
260
366
|
}
|
|
261
367
|
// No sessionId: fall back to legacy path (backward compat)
|
|
@@ -355,7 +461,15 @@ function countIncompleteTodos(sessionId, projectDir) {
|
|
|
355
461
|
* See: https://github.com/Yeachan-Heo/oh-my-claudecode/issues/213
|
|
356
462
|
*/
|
|
357
463
|
function isContextLimitStop(data) {
|
|
358
|
-
const
|
|
464
|
+
const reasons = [
|
|
465
|
+
data.stop_reason,
|
|
466
|
+
data.stopReason,
|
|
467
|
+
data.end_turn_reason,
|
|
468
|
+
data.endTurnReason,
|
|
469
|
+
data.reason,
|
|
470
|
+
]
|
|
471
|
+
.filter((value) => typeof value === "string" && value.trim().length > 0)
|
|
472
|
+
.map((value) => value.toLowerCase().replace(/[\s-]+/g, "_"));
|
|
359
473
|
|
|
360
474
|
const contextPatterns = [
|
|
361
475
|
"context_limit",
|
|
@@ -369,20 +483,27 @@ function isContextLimitStop(data) {
|
|
|
369
483
|
"input_too_long",
|
|
370
484
|
];
|
|
371
485
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
486
|
+
return reasons.some((reason) => contextPatterns.some((p) => reason.includes(p)));
|
|
487
|
+
}
|
|
375
488
|
|
|
376
|
-
|
|
377
|
-
data.end_turn_reason ||
|
|
378
|
-
data.endTurnReason ||
|
|
379
|
-
""
|
|
380
|
-
).toLowerCase();
|
|
381
|
-
if (endTurnReason && contextPatterns.some((p) => endTurnReason.includes(p))) {
|
|
382
|
-
return true;
|
|
383
|
-
}
|
|
489
|
+
const CRITICAL_CONTEXT_STOP_PERCENT = 95;
|
|
384
490
|
|
|
385
|
-
|
|
491
|
+
function estimateContextPercent(transcriptPath) {
|
|
492
|
+
if (!transcriptPath || !existsSync(transcriptPath)) return 0;
|
|
493
|
+
|
|
494
|
+
try {
|
|
495
|
+
const content = readFileSync(transcriptPath, "utf-8");
|
|
496
|
+
const windowMatch = content.match(/"context_window"\s{0,5}:\s{0,5}(\d+)/g);
|
|
497
|
+
const inputMatch = content.match(/"input_tokens"\s{0,5}:\s{0,5}(\d+)/g);
|
|
498
|
+
if (!windowMatch || !inputMatch) return 0;
|
|
499
|
+
|
|
500
|
+
const lastWindow = parseInt(windowMatch[windowMatch.length - 1].match(/(\d+)/)[1], 10);
|
|
501
|
+
const lastInput = parseInt(inputMatch[inputMatch.length - 1].match(/(\d+)/)[1], 10);
|
|
502
|
+
if (!Number.isFinite(lastWindow) || lastWindow <= 0 || !Number.isFinite(lastInput)) return 0;
|
|
503
|
+
return Math.round((lastInput / lastWindow) * 100);
|
|
504
|
+
} catch {
|
|
505
|
+
return 0;
|
|
506
|
+
}
|
|
386
507
|
}
|
|
387
508
|
|
|
388
509
|
/**
|
|
@@ -460,6 +581,12 @@ async function main() {
|
|
|
460
581
|
return;
|
|
461
582
|
}
|
|
462
583
|
|
|
584
|
+
const criticalTranscriptPath = data.transcript_path || data.transcriptPath || "";
|
|
585
|
+
if (estimateContextPercent(criticalTranscriptPath) >= CRITICAL_CONTEXT_STOP_PERCENT) {
|
|
586
|
+
console.log(JSON.stringify({ continue: true, suppressOutput: true }));
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
|
|
463
590
|
// Respect user abort (Ctrl+C, cancel)
|
|
464
591
|
if (isUserAbort(data)) {
|
|
465
592
|
console.log(JSON.stringify({ continue: true, suppressOutput: true }));
|
|
@@ -480,6 +607,7 @@ async function main() {
|
|
|
480
607
|
const ultraqa = readStateFileWithSession(stateDir, "ultraqa-state.json", sessionId);
|
|
481
608
|
const pipeline = readStateFileWithSession(stateDir, "pipeline-state.json", sessionId);
|
|
482
609
|
const team = readStateFileWithSession(stateDir, "team-state.json", sessionId);
|
|
610
|
+
const ralplan = readStateFileWithSession(stateDir, "ralplan-state.json", sessionId);
|
|
483
611
|
const omcTeams = readStateFileWithSession(stateDir, "omc-teams-state.json", sessionId);
|
|
484
612
|
|
|
485
613
|
// Swarm uses swarm-summary.json (not swarm-state.json) + marker file
|
|
@@ -492,7 +620,9 @@ async function main() {
|
|
|
492
620
|
const totalIncomplete = taskCount + todoCount;
|
|
493
621
|
|
|
494
622
|
// Check if cancel is in progress - if so, allow stop immediately
|
|
495
|
-
|
|
623
|
+
// Cache the result to pass to sub-checks (avoids TOCTOU re-reads, issue #1058)
|
|
624
|
+
const cancelInProgress = isSessionCancelInProgress(stateDir, sessionId);
|
|
625
|
+
if (cancelInProgress) {
|
|
496
626
|
console.log(JSON.stringify({ continue: true, suppressOutput: true }));
|
|
497
627
|
return;
|
|
498
628
|
}
|
|
@@ -513,7 +643,7 @@ async function main() {
|
|
|
513
643
|
|
|
514
644
|
console.log(
|
|
515
645
|
JSON.stringify({
|
|
516
|
-
decision: "block",
|
|
646
|
+
continue: false, decision: "block",
|
|
517
647
|
reason: `[RALPH LOOP - ITERATION ${iteration + 1}/${maxIter}] Work is NOT done. Continue working.\nWhen FULLY complete (after Architect verification), run /oh-my-claudecode:cancel to cleanly exit ralph mode and clean up all state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.\n${ralph.state.prompt ? `Task: ${ralph.state.prompt}` : ""}`,
|
|
518
648
|
}),
|
|
519
649
|
);
|
|
@@ -536,7 +666,7 @@ async function main() {
|
|
|
536
666
|
|
|
537
667
|
console.log(
|
|
538
668
|
JSON.stringify({
|
|
539
|
-
decision: "block",
|
|
669
|
+
continue: false, decision: "block",
|
|
540
670
|
reason: `[AUTOPILOT - Phase: ${phase}] Autopilot not complete. Continue working. When all phases are complete, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`,
|
|
541
671
|
}),
|
|
542
672
|
);
|
|
@@ -545,6 +675,102 @@ async function main() {
|
|
|
545
675
|
}
|
|
546
676
|
}
|
|
547
677
|
|
|
678
|
+
// Priority 2.5: Team Pipeline (standalone team mode — first-class enforcement)
|
|
679
|
+
// When team runs WITHOUT ralph, this provides stop-hook blocking.
|
|
680
|
+
// When team runs WITH ralph, checkRalphLoop (Priority 1) handles it.
|
|
681
|
+
let teamPipelineHandled = false;
|
|
682
|
+
if (team.state && isSessionMatch(team.state, sessionId)) {
|
|
683
|
+
if (!team.state.active) {
|
|
684
|
+
// Inactive — reset breaker, allow stop, mark as handled
|
|
685
|
+
writeStopBreaker(stateDir, "team-pipeline", 0, sessionId);
|
|
686
|
+
teamPipelineHandled = true;
|
|
687
|
+
} else if (!isStaleState(team.state)) {
|
|
688
|
+
teamPipelineHandled = true;
|
|
689
|
+
|
|
690
|
+
// Cancel-in-progress bypass (TOCTOU defense, issue #1058)
|
|
691
|
+
if (!cancelInProgress) {
|
|
692
|
+
// Read phase: canonical field priority matching bridge code
|
|
693
|
+
const rawPhase = team.state.phase
|
|
694
|
+
?? team.state.current_phase
|
|
695
|
+
?? team.state.currentStage
|
|
696
|
+
?? team.state.current_stage
|
|
697
|
+
?? team.state.stage;
|
|
698
|
+
|
|
699
|
+
if (typeof rawPhase !== "string") {
|
|
700
|
+
// No valid phase — fail-open (don't block)
|
|
701
|
+
} else {
|
|
702
|
+
const phase = rawPhase.trim().toLowerCase();
|
|
703
|
+
|
|
704
|
+
if (TEAM_TERMINAL_PHASES.has(phase) || phase === "cancel") {
|
|
705
|
+
// Terminal — reset breaker, allow stop
|
|
706
|
+
writeStopBreaker(stateDir, "team-pipeline", 0, sessionId);
|
|
707
|
+
} else if (!TEAM_ACTIVE_PHASES.has(phase)) {
|
|
708
|
+
// Unknown phase — fail-open (don't block)
|
|
709
|
+
} else {
|
|
710
|
+
// Status-level terminal check
|
|
711
|
+
const rawStatus = team.state.status;
|
|
712
|
+
const status = typeof rawStatus === "string" ? rawStatus.trim().toLowerCase() : null;
|
|
713
|
+
if (status && TEAM_TERMINAL_PHASES.has(status)) {
|
|
714
|
+
writeStopBreaker(stateDir, "team-pipeline", 0, sessionId);
|
|
715
|
+
} else if (team.state.cancel?.requested) {
|
|
716
|
+
// Cancel requested — allow stop
|
|
717
|
+
writeStopBreaker(stateDir, "team-pipeline", 0, sessionId);
|
|
718
|
+
} else {
|
|
719
|
+
// Active phase — block with circuit breaker
|
|
720
|
+
const breakerCount = readStopBreaker(stateDir, "team-pipeline", sessionId, TEAM_PIPELINE_STOP_BLOCKER_TTL_MS) + 1;
|
|
721
|
+
if (breakerCount > TEAM_PIPELINE_STOP_BLOCKER_MAX) {
|
|
722
|
+
writeStopBreaker(stateDir, "team-pipeline", 0, sessionId);
|
|
723
|
+
// Circuit breaker tripped — allow stop
|
|
724
|
+
} else {
|
|
725
|
+
writeStopBreaker(stateDir, "team-pipeline", breakerCount, sessionId);
|
|
726
|
+
sendStopNotification("team", team.state, sessionId, directory).catch(() => {});
|
|
727
|
+
|
|
728
|
+
console.log(JSON.stringify({
|
|
729
|
+
continue: false, decision: "block",
|
|
730
|
+
reason: `[TEAM PIPELINE - PHASE: ${phase.toUpperCase()} | REINFORCEMENT ${breakerCount}/${TEAM_PIPELINE_STOP_BLOCKER_MAX}] The team pipeline is active in phase "${phase}". Continue working on the team workflow. Do not stop until the pipeline reaches a terminal state (complete/failed/cancelled). When done, run /oh-my-claudecode:cancel to cleanly exit.`,
|
|
731
|
+
}));
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// Priority 2.6: Ralplan (standalone consensus planning — first-class enforcement)
|
|
742
|
+
if (ralplan.state?.active && !isStaleState(ralplan.state) && isSessionMatch(ralplan.state, sessionId)) {
|
|
743
|
+
// Terminal phase detection
|
|
744
|
+
const currentPhase = ralplan.state.current_phase;
|
|
745
|
+
let ralplanTerminal = false;
|
|
746
|
+
if (typeof currentPhase === "string") {
|
|
747
|
+
const terminal = ["complete", "completed", "failed", "cancelled", "canceled", "done"];
|
|
748
|
+
if (terminal.includes(currentPhase.toLowerCase())) {
|
|
749
|
+
writeStopBreaker(stateDir, "ralplan", 0, sessionId);
|
|
750
|
+
ralplanTerminal = true;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
if (!ralplanTerminal && !cancelInProgress) {
|
|
755
|
+
// Circuit breaker
|
|
756
|
+
const breakerCount = readStopBreaker(stateDir, "ralplan", sessionId, RALPLAN_STOP_BLOCKER_TTL_MS) + 1;
|
|
757
|
+
if (breakerCount > RALPLAN_STOP_BLOCKER_MAX) {
|
|
758
|
+
writeStopBreaker(stateDir, "ralplan", 0, sessionId);
|
|
759
|
+
// Circuit breaker tripped — allow stop
|
|
760
|
+
} else {
|
|
761
|
+
writeStopBreaker(stateDir, "ralplan", breakerCount, sessionId);
|
|
762
|
+
|
|
763
|
+
sendStopNotification("ralplan", ralplan.state, sessionId, directory).catch(() => {});
|
|
764
|
+
|
|
765
|
+
console.log(JSON.stringify({
|
|
766
|
+
continue: false, decision: "block",
|
|
767
|
+
reason: `[RALPLAN - CONSENSUS PLANNING | REINFORCEMENT ${breakerCount}/${RALPLAN_STOP_BLOCKER_MAX}] The ralplan consensus workflow is active. Continue the Planner/Architect/Critic loop. Do not stop until consensus is reached or the workflow completes. When done, run /oh-my-claudecode:cancel to cleanly exit.`,
|
|
768
|
+
}));
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
548
774
|
// Priority 3: Ultrapilot (parallel autopilot)
|
|
549
775
|
if (ultrapilot.state?.active && !isStaleState(ultrapilot.state) && isSessionMatch(ultrapilot.state, sessionId)) {
|
|
550
776
|
const workers = ultrapilot.state.workers || [];
|
|
@@ -563,7 +789,7 @@ async function main() {
|
|
|
563
789
|
|
|
564
790
|
console.log(
|
|
565
791
|
JSON.stringify({
|
|
566
|
-
decision: "block",
|
|
792
|
+
continue: false, decision: "block",
|
|
567
793
|
reason: `[ULTRAPILOT] ${incomplete} workers still running. Continue working. When all workers complete, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`,
|
|
568
794
|
}),
|
|
569
795
|
);
|
|
@@ -588,7 +814,7 @@ async function main() {
|
|
|
588
814
|
|
|
589
815
|
console.log(
|
|
590
816
|
JSON.stringify({
|
|
591
|
-
decision: "block",
|
|
817
|
+
continue: false, decision: "block",
|
|
592
818
|
reason: `[SWARM ACTIVE] ${pending} tasks remain. Continue working. When all tasks are done, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`,
|
|
593
819
|
}),
|
|
594
820
|
);
|
|
@@ -613,7 +839,7 @@ async function main() {
|
|
|
613
839
|
|
|
614
840
|
console.log(
|
|
615
841
|
JSON.stringify({
|
|
616
|
-
decision: "block",
|
|
842
|
+
continue: false, decision: "block",
|
|
617
843
|
reason: `[PIPELINE - Stage ${currentStage + 1}/${totalStages}] Pipeline not complete. Continue working. When all stages complete, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`,
|
|
618
844
|
}),
|
|
619
845
|
);
|
|
@@ -622,12 +848,11 @@ async function main() {
|
|
|
622
848
|
}
|
|
623
849
|
}
|
|
624
850
|
|
|
625
|
-
// Priority 6: Team (native Claude Code teams)
|
|
626
|
-
if (team.state?.active && !isStaleState(team.state) && isSessionMatch(team.state, sessionId)) {
|
|
627
|
-
const phase = team.state
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
const newCount = (team.state.reinforcement_count || 0) + 1;
|
|
851
|
+
// Priority 6: Team (native Claude Code teams) — fallback for cases not handled by Priority 2.5
|
|
852
|
+
if (!teamPipelineHandled && team.state?.active && !isStaleState(team.state) && isSessionMatch(team.state, sessionId)) {
|
|
853
|
+
const phase = normalizeTeamPhase(team.state);
|
|
854
|
+
if (phase) {
|
|
855
|
+
const newCount = getSafeReinforcementCount(team.state.reinforcement_count) + 1;
|
|
631
856
|
if (newCount <= 20) {
|
|
632
857
|
team.state.reinforcement_count = newCount;
|
|
633
858
|
team.state.last_checked_at = new Date().toISOString();
|
|
@@ -638,7 +863,7 @@ async function main() {
|
|
|
638
863
|
|
|
639
864
|
console.log(
|
|
640
865
|
JSON.stringify({
|
|
641
|
-
decision: "block",
|
|
866
|
+
continue: false, decision: "block",
|
|
642
867
|
reason: `[TEAM - Phase: ${phase}] Team mode active. Continue working. When all team tasks complete, run /oh-my-claudecode:cancel to cleanly exit. If cancel fails, retry with /oh-my-claudecode:cancel --force.`,
|
|
643
868
|
}),
|
|
644
869
|
);
|
|
@@ -649,10 +874,9 @@ async function main() {
|
|
|
649
874
|
|
|
650
875
|
// Priority 6.5: OMC Teams (tmux CLI workers — independent of native team state)
|
|
651
876
|
if (omcTeams.state?.active && !isStaleState(omcTeams.state) && isSessionMatch(omcTeams.state, sessionId)) {
|
|
652
|
-
const phase = omcTeams.state
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
const newCount = (omcTeams.state.reinforcement_count || 0) + 1;
|
|
877
|
+
const phase = normalizeTeamPhase(omcTeams.state);
|
|
878
|
+
if (phase) {
|
|
879
|
+
const newCount = getSafeReinforcementCount(omcTeams.state.reinforcement_count) + 1;
|
|
656
880
|
if (newCount <= 20) {
|
|
657
881
|
omcTeams.state.reinforcement_count = newCount;
|
|
658
882
|
omcTeams.state.last_checked_at = new Date().toISOString();
|
|
@@ -663,7 +887,7 @@ async function main() {
|
|
|
663
887
|
|
|
664
888
|
console.log(
|
|
665
889
|
JSON.stringify({
|
|
666
|
-
decision: "block",
|
|
890
|
+
continue: false, decision: "block",
|
|
667
891
|
reason: `[OMC TEAMS - Phase: ${phase}] OMC Teams workers active. Continue working. When all workers complete, run /oh-my-claudecode:cancel to cleanly exit. If cancel fails, retry with /oh-my-claudecode:cancel --force.`,
|
|
668
892
|
}),
|
|
669
893
|
);
|
|
@@ -686,7 +910,7 @@ async function main() {
|
|
|
686
910
|
|
|
687
911
|
console.log(
|
|
688
912
|
JSON.stringify({
|
|
689
|
-
decision: "block",
|
|
913
|
+
continue: false, decision: "block",
|
|
690
914
|
reason: `[ULTRAQA - Cycle ${cycle + 1}/${maxCycles}] Tests not all passing. Continue fixing. When all tests pass, run /oh-my-claudecode:cancel to cleanly exit and clean up state files. If cancel fails, retry with /oh-my-claudecode:cancel --force.`,
|
|
691
915
|
}),
|
|
692
916
|
);
|
|
@@ -737,10 +961,47 @@ async function main() {
|
|
|
737
961
|
reason += `\nTask: ${ultrawork.state.original_prompt}`;
|
|
738
962
|
}
|
|
739
963
|
|
|
740
|
-
console.log(JSON.stringify({ decision: "block", reason }));
|
|
964
|
+
console.log(JSON.stringify({ continue: false, decision: "block", reason }));
|
|
741
965
|
return;
|
|
742
966
|
}
|
|
743
967
|
|
|
968
|
+
// Priority 9: Skill Active State (issue #1033)
|
|
969
|
+
// Skills like code-review, plan, ralplan, tdd, etc. write skill-active-state.json
|
|
970
|
+
// when invoked via the Skill tool. This prevents premature stops mid-skill.
|
|
971
|
+
{
|
|
972
|
+
const skillState = readStateFileWithSession(stateDir, "skill-active-state.json", sessionId);
|
|
973
|
+
if (skillState.state?.active) {
|
|
974
|
+
// Staleness check (per-skill TTL)
|
|
975
|
+
const sLastChecked = skillState.state.last_checked_at ? new Date(skillState.state.last_checked_at).getTime() : 0;
|
|
976
|
+
const sStartedAt = skillState.state.started_at ? new Date(skillState.state.started_at).getTime() : 0;
|
|
977
|
+
const sMostRecent = Math.max(sLastChecked, sStartedAt);
|
|
978
|
+
const sTtl = skillState.state.stale_ttl_ms || 5 * 60 * 1000;
|
|
979
|
+
const sAge = sMostRecent > 0 ? Date.now() - sMostRecent : Infinity;
|
|
980
|
+
const isStale = sMostRecent === 0 || sAge > sTtl;
|
|
981
|
+
|
|
982
|
+
if (!isStale && isSessionMatch(skillState.state, sessionId)) {
|
|
983
|
+
const count = skillState.state.reinforcement_count || 0;
|
|
984
|
+
const maxReinforcements = skillState.state.max_reinforcements || 3;
|
|
985
|
+
|
|
986
|
+
if (count < maxReinforcements) {
|
|
987
|
+
skillState.state.reinforcement_count = count + 1;
|
|
988
|
+
skillState.state.last_checked_at = new Date().toISOString();
|
|
989
|
+
writeJsonFile(skillState.path, skillState.state);
|
|
990
|
+
|
|
991
|
+
const skillName = skillState.state.skill_name || "unknown";
|
|
992
|
+
console.log(JSON.stringify({
|
|
993
|
+
continue: false, decision: "block",
|
|
994
|
+
reason: `[SKILL ACTIVE: ${skillName}] The "${skillName}" skill is still executing (reinforcement ${count + 1}/${maxReinforcements}). Continue working on the skill's instructions. Do not stop until the skill completes its workflow.`,
|
|
995
|
+
}));
|
|
996
|
+
return;
|
|
997
|
+
} else {
|
|
998
|
+
// Reinforcement limit reached - clear state and allow stop
|
|
999
|
+
try { if (skillState.path && existsSync(skillState.path)) unlinkSync(skillState.path); } catch {}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
744
1005
|
// No blocking needed — Claude is truly idle.
|
|
745
1006
|
// Send session-idle notification (fire-and-forget) so external integrations
|
|
746
1007
|
// (Telegram, Discord) know the session went idle without any active mode.
|
|
@@ -132,6 +132,29 @@ Do NOT skip this step. Do NOT move on without fixing the error.
|
|
|
132
132
|
* from causing the stop hook to malfunction in new sessions.
|
|
133
133
|
*/
|
|
134
134
|
const STALE_STATE_THRESHOLD_MS = 2 * 60 * 60 * 1000; // 2 hours
|
|
135
|
+
const TEAM_TERMINAL_PHASES = new Set([
|
|
136
|
+
"completed",
|
|
137
|
+
"complete",
|
|
138
|
+
"failed",
|
|
139
|
+
"cancelled",
|
|
140
|
+
"canceled",
|
|
141
|
+
"aborted",
|
|
142
|
+
"terminated",
|
|
143
|
+
"done",
|
|
144
|
+
]);
|
|
145
|
+
const TEAM_ACTIVE_PHASES = new Set([
|
|
146
|
+
"team-plan",
|
|
147
|
+
"team-prd",
|
|
148
|
+
"team-exec",
|
|
149
|
+
"team-verify",
|
|
150
|
+
"team-fix",
|
|
151
|
+
"planning",
|
|
152
|
+
"executing",
|
|
153
|
+
"verify",
|
|
154
|
+
"verification",
|
|
155
|
+
"fix",
|
|
156
|
+
"fixing",
|
|
157
|
+
]);
|
|
135
158
|
|
|
136
159
|
/**
|
|
137
160
|
* Check if a state is stale based on its timestamps.
|
|
@@ -153,6 +176,23 @@ function isStaleState(state) {
|
|
|
153
176
|
return age > STALE_STATE_THRESHOLD_MS;
|
|
154
177
|
}
|
|
155
178
|
|
|
179
|
+
function normalizeTeamPhase(state) {
|
|
180
|
+
if (!state || typeof state !== "object") return null;
|
|
181
|
+
|
|
182
|
+
const rawPhase = state.current_phase ?? state.phase ?? state.stage;
|
|
183
|
+
if (typeof rawPhase !== "string") return null;
|
|
184
|
+
|
|
185
|
+
const phase = rawPhase.trim().toLowerCase();
|
|
186
|
+
if (!phase || TEAM_TERMINAL_PHASES.has(phase)) return null;
|
|
187
|
+
return TEAM_ACTIVE_PHASES.has(phase) ? phase : null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function getSafeReinforcementCount(value) {
|
|
191
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0
|
|
192
|
+
? Math.floor(value)
|
|
193
|
+
: 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
156
196
|
/**
|
|
157
197
|
* Normalize a path for comparison.
|
|
158
198
|
*/
|
|
@@ -325,7 +365,15 @@ function countIncompleteTodos(sessionId, projectDir) {
|
|
|
325
365
|
* See: https://github.com/Yeachan-Heo/oh-my-claudecode/issues/213
|
|
326
366
|
*/
|
|
327
367
|
function isContextLimitStop(data) {
|
|
328
|
-
const
|
|
368
|
+
const reasons = [
|
|
369
|
+
data.stop_reason,
|
|
370
|
+
data.stopReason,
|
|
371
|
+
data.end_turn_reason,
|
|
372
|
+
data.endTurnReason,
|
|
373
|
+
data.reason,
|
|
374
|
+
]
|
|
375
|
+
.filter((value) => typeof value === "string" && value.trim().length > 0)
|
|
376
|
+
.map((value) => value.toLowerCase().replace(/[\s-]+/g, "_"));
|
|
329
377
|
|
|
330
378
|
const contextPatterns = [
|
|
331
379
|
"context_limit",
|
|
@@ -339,20 +387,26 @@ function isContextLimitStop(data) {
|
|
|
339
387
|
"input_too_long",
|
|
340
388
|
];
|
|
341
389
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
390
|
+
return reasons.some((reason) => contextPatterns.some((p) => reason.includes(p)));
|
|
391
|
+
}
|
|
345
392
|
|
|
346
|
-
|
|
347
|
-
data.end_turn_reason ||
|
|
348
|
-
data.endTurnReason ||
|
|
349
|
-
""
|
|
350
|
-
).toLowerCase();
|
|
351
|
-
if (endTurnReason && contextPatterns.some((p) => endTurnReason.includes(p))) {
|
|
352
|
-
return true;
|
|
353
|
-
}
|
|
393
|
+
const CRITICAL_CONTEXT_STOP_PERCENT = 95;
|
|
354
394
|
|
|
355
|
-
|
|
395
|
+
function estimateContextPercent(transcriptPath) {
|
|
396
|
+
if (!transcriptPath || !existsSync(transcriptPath)) return 0;
|
|
397
|
+
try {
|
|
398
|
+
const content = readFileSync(transcriptPath, "utf-8");
|
|
399
|
+
const windowMatch = content.match(/"context_window"\s{0,5}:\s{0,5}(\d+)/g);
|
|
400
|
+
const inputMatch = content.match(/"input_tokens"\s{0,5}:\s{0,5}(\d+)/g);
|
|
401
|
+
if (!windowMatch || !inputMatch) return 0;
|
|
402
|
+
|
|
403
|
+
const lastWindow = parseInt(windowMatch[windowMatch.length - 1].match(/(\d+)/)[1], 10);
|
|
404
|
+
const lastInput = parseInt(inputMatch[inputMatch.length - 1].match(/(\d+)/)[1], 10);
|
|
405
|
+
if (!Number.isFinite(lastWindow) || lastWindow <= 0 || !Number.isFinite(lastInput)) return 0;
|
|
406
|
+
return Math.round((lastInput / lastWindow) * 100);
|
|
407
|
+
} catch {
|
|
408
|
+
return 0;
|
|
409
|
+
}
|
|
356
410
|
}
|
|
357
411
|
|
|
358
412
|
/**
|
|
@@ -433,6 +487,12 @@ async function main() {
|
|
|
433
487
|
return;
|
|
434
488
|
}
|
|
435
489
|
|
|
490
|
+
const criticalTranscriptPath = data.transcript_path || data.transcriptPath || "";
|
|
491
|
+
if (estimateContextPercent(criticalTranscriptPath) >= CRITICAL_CONTEXT_STOP_PERCENT) {
|
|
492
|
+
console.log(JSON.stringify({ continue: true, suppressOutput: true }));
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
436
496
|
// Respect user abort (Ctrl+C, cancel)
|
|
437
497
|
if (isUserAbort(data)) {
|
|
438
498
|
console.log(JSON.stringify({ continue: true, suppressOutput: true }));
|
|
@@ -720,10 +780,9 @@ async function main() {
|
|
|
720
780
|
? team.state.session_id === sessionId
|
|
721
781
|
: !team.state.session_id || team.state.session_id === sessionId;
|
|
722
782
|
if (sessionMatches) {
|
|
723
|
-
const phase = team.state
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
const newCount = (team.state.reinforcement_count || 0) + 1;
|
|
783
|
+
const phase = normalizeTeamPhase(team.state);
|
|
784
|
+
if (phase) {
|
|
785
|
+
const newCount = getSafeReinforcementCount(team.state.reinforcement_count) + 1;
|
|
727
786
|
if (newCount <= 20) {
|
|
728
787
|
const toolError = readLastToolError(stateDir);
|
|
729
788
|
const errorGuidance = getToolErrorRetryGuidance(toolError);
|
|
@@ -760,10 +819,9 @@ async function main() {
|
|
|
760
819
|
? omcTeams.state.session_id === sessionId
|
|
761
820
|
: !omcTeams.state.session_id || omcTeams.state.session_id === sessionId;
|
|
762
821
|
if (sessionMatches) {
|
|
763
|
-
const phase = omcTeams.state
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
const newCount = (omcTeams.state.reinforcement_count || 0) + 1;
|
|
822
|
+
const phase = normalizeTeamPhase(omcTeams.state);
|
|
823
|
+
if (phase) {
|
|
824
|
+
const newCount = getSafeReinforcementCount(omcTeams.state.reinforcement_count) + 1;
|
|
767
825
|
if (newCount <= 20) {
|
|
768
826
|
const toolError = readLastToolError(stateDir);
|
|
769
827
|
const errorGuidance = getToolErrorRetryGuidance(toolError);
|
package/scripts/plugin-setup.mjs
CHANGED
|
@@ -104,7 +104,16 @@ async function main() {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
// 3.
|
|
107
|
+
// 3. Marketplace clone (for marketplace installs without a populated cache)
|
|
108
|
+
const marketplaceHudPath = join(configDir, "plugins", "marketplaces", "omc", "dist/hud/index.js");
|
|
109
|
+
if (existsSync(marketplaceHudPath)) {
|
|
110
|
+
try {
|
|
111
|
+
await import(pathToFileURL(marketplaceHudPath).href);
|
|
112
|
+
return;
|
|
113
|
+
} catch { /* continue */ }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 4. Fallback: provide targeted repair guidance
|
|
108
117
|
if (pluginCacheDir && existsSync(pluginCacheDir)) {
|
|
109
118
|
const distDir = join(pluginCacheDir, "dist");
|
|
110
119
|
if (!existsSync(distDir)) {
|