@a1hvdy/cc-openclaw 0.3.2
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/LICENSE +22 -0
- package/README.md +207 -0
- package/configs/.gitkeep +0 -0
- package/configs/council-reviewer-prompt.md +82 -0
- package/configs/council-system-prompt.md +141 -0
- package/dist/scripts/bench/ab-harness.d.ts +58 -0
- package/dist/scripts/bench/ab-harness.d.ts.map +1 -0
- package/dist/scripts/bench/ab-harness.js +78 -0
- package/dist/scripts/bench/ab-harness.js.map +1 -0
- package/dist/src/channels/adapter.d.ts +103 -0
- package/dist/src/channels/adapter.d.ts.map +1 -0
- package/dist/src/channels/adapter.js +38 -0
- package/dist/src/channels/adapter.js.map +1 -0
- package/dist/src/channels/telegram/completion-summary.d.ts +22 -0
- package/dist/src/channels/telegram/completion-summary.d.ts.map +1 -0
- package/dist/src/channels/telegram/completion-summary.js +186 -0
- package/dist/src/channels/telegram/completion-summary.js.map +1 -0
- package/dist/src/channels/telegram/error-renderer.d.ts +30 -0
- package/dist/src/channels/telegram/error-renderer.d.ts.map +1 -0
- package/dist/src/channels/telegram/error-renderer.js +133 -0
- package/dist/src/channels/telegram/error-renderer.js.map +1 -0
- package/dist/src/channels/telegram/event-reducer.d.ts +34 -0
- package/dist/src/channels/telegram/event-reducer.d.ts.map +1 -0
- package/dist/src/channels/telegram/event-reducer.js +579 -0
- package/dist/src/channels/telegram/event-reducer.js.map +1 -0
- package/dist/src/channels/telegram/index.d.ts +14 -0
- package/dist/src/channels/telegram/index.d.ts.map +1 -0
- package/dist/src/channels/telegram/index.js +14 -0
- package/dist/src/channels/telegram/index.js.map +1 -0
- package/dist/src/channels/telegram/injector.d.ts +54 -0
- package/dist/src/channels/telegram/injector.d.ts.map +1 -0
- package/dist/src/channels/telegram/injector.js +200 -0
- package/dist/src/channels/telegram/injector.js.map +1 -0
- package/dist/src/channels/telegram/live-card.d.ts +230 -0
- package/dist/src/channels/telegram/live-card.d.ts.map +1 -0
- package/dist/src/channels/telegram/live-card.js +916 -0
- package/dist/src/channels/telegram/live-card.js.map +1 -0
- package/dist/src/channels/telegram/state-machine.d.ts +23 -0
- package/dist/src/channels/telegram/state-machine.d.ts.map +1 -0
- package/dist/src/channels/telegram/state-machine.js +72 -0
- package/dist/src/channels/telegram/state-machine.js.map +1 -0
- package/dist/src/channels/telegram/tool-tracker.d.ts +147 -0
- package/dist/src/channels/telegram/tool-tracker.d.ts.map +1 -0
- package/dist/src/channels/telegram/tool-tracker.js +520 -0
- package/dist/src/channels/telegram/tool-tracker.js.map +1 -0
- package/dist/src/circuit-breaker.d.ts +22 -0
- package/dist/src/circuit-breaker.d.ts.map +1 -0
- package/dist/src/circuit-breaker.js +47 -0
- package/dist/src/circuit-breaker.js.map +1 -0
- package/dist/src/command-router/cc-handler.d.ts +67 -0
- package/dist/src/command-router/cc-handler.d.ts.map +1 -0
- package/dist/src/command-router/cc-handler.js +980 -0
- package/dist/src/command-router/cc-handler.js.map +1 -0
- package/dist/src/command-router/index.d.ts +3 -0
- package/dist/src/command-router/index.d.ts.map +1 -0
- package/dist/src/command-router/index.js +2 -0
- package/dist/src/command-router/index.js.map +1 -0
- package/dist/src/constants.d.ts +132 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +140 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/council/consensus.d.ts +21 -0
- package/dist/src/council/consensus.d.ts.map +1 -0
- package/dist/src/council/consensus.js +52 -0
- package/dist/src/council/consensus.js.map +1 -0
- package/dist/src/council/council.d.ts +68 -0
- package/dist/src/council/council.d.ts.map +1 -0
- package/dist/src/council/council.js +914 -0
- package/dist/src/council/council.js.map +1 -0
- package/dist/src/council/index.d.ts +3 -0
- package/dist/src/council/index.d.ts.map +1 -0
- package/dist/src/council/index.js +3 -0
- package/dist/src/council/index.js.map +1 -0
- package/dist/src/engines/base-oneshot-session.d.ts +88 -0
- package/dist/src/engines/base-oneshot-session.d.ts.map +1 -0
- package/dist/src/engines/base-oneshot-session.js +228 -0
- package/dist/src/engines/base-oneshot-session.js.map +1 -0
- package/dist/src/engines/index.d.ts +7 -0
- package/dist/src/engines/index.d.ts.map +1 -0
- package/dist/src/engines/index.js +7 -0
- package/dist/src/engines/index.js.map +1 -0
- package/dist/src/engines/persistent-codex-session.d.ts +17 -0
- package/dist/src/engines/persistent-codex-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-codex-session.js +106 -0
- package/dist/src/engines/persistent-codex-session.js.map +1 -0
- package/dist/src/engines/persistent-cursor-session.d.ts +22 -0
- package/dist/src/engines/persistent-cursor-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-cursor-session.js +242 -0
- package/dist/src/engines/persistent-cursor-session.js.map +1 -0
- package/dist/src/engines/persistent-custom-session.d.ts +79 -0
- package/dist/src/engines/persistent-custom-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-custom-session.js +939 -0
- package/dist/src/engines/persistent-custom-session.js.map +1 -0
- package/dist/src/engines/persistent-gemini-session.d.ts +22 -0
- package/dist/src/engines/persistent-gemini-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-gemini-session.js +217 -0
- package/dist/src/engines/persistent-gemini-session.js.map +1 -0
- package/dist/src/engines/persistent-session.d.ts +77 -0
- package/dist/src/engines/persistent-session.d.ts.map +1 -0
- package/dist/src/engines/persistent-session.js +730 -0
- package/dist/src/engines/persistent-session.js.map +1 -0
- package/dist/src/health/handler.d.ts +40 -0
- package/dist/src/health/handler.d.ts.map +1 -0
- package/dist/src/health/handler.js +70 -0
- package/dist/src/health/handler.js.map +1 -0
- package/dist/src/health/index.d.ts +2 -0
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/health/index.js +2 -0
- package/dist/src/health/index.js.map +1 -0
- package/dist/src/index.d.ts +49 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +84 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/auto-recovery.d.ts +45 -0
- package/dist/src/lib/auto-recovery.d.ts.map +1 -0
- package/dist/src/lib/auto-recovery.js +217 -0
- package/dist/src/lib/auto-recovery.js.map +1 -0
- package/dist/src/lib/cache-parity.d.ts +39 -0
- package/dist/src/lib/cache-parity.d.ts.map +1 -0
- package/dist/src/lib/cache-parity.js +92 -0
- package/dist/src/lib/cache-parity.js.map +1 -0
- package/dist/src/lib/circuit-breaker.d.ts +22 -0
- package/dist/src/lib/circuit-breaker.d.ts.map +1 -0
- package/dist/src/lib/circuit-breaker.js +47 -0
- package/dist/src/lib/circuit-breaker.js.map +1 -0
- package/dist/src/lib/config.d.ts +74 -0
- package/dist/src/lib/config.d.ts.map +1 -0
- package/dist/src/lib/config.js +244 -0
- package/dist/src/lib/config.js.map +1 -0
- package/dist/src/lib/drift-detector.d.ts +47 -0
- package/dist/src/lib/drift-detector.d.ts.map +1 -0
- package/dist/src/lib/drift-detector.js +192 -0
- package/dist/src/lib/drift-detector.js.map +1 -0
- package/dist/src/lib/error-formatter.d.ts +78 -0
- package/dist/src/lib/error-formatter.d.ts.map +1 -0
- package/dist/src/lib/error-formatter.js +149 -0
- package/dist/src/lib/error-formatter.js.map +1 -0
- package/dist/src/lib/heartbeat-workaround.d.ts +45 -0
- package/dist/src/lib/heartbeat-workaround.d.ts.map +1 -0
- package/dist/src/lib/heartbeat-workaround.js +61 -0
- package/dist/src/lib/heartbeat-workaround.js.map +1 -0
- package/dist/src/lib/index.d.ts +8 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +8 -0
- package/dist/src/lib/index.js.map +1 -0
- package/dist/src/lib/register-guard.d.ts +49 -0
- package/dist/src/lib/register-guard.d.ts.map +1 -0
- package/dist/src/lib/register-guard.js +73 -0
- package/dist/src/lib/register-guard.js.map +1 -0
- package/dist/src/lib/route-flag.d.ts +50 -0
- package/dist/src/lib/route-flag.d.ts.map +1 -0
- package/dist/src/lib/route-flag.js +52 -0
- package/dist/src/lib/route-flag.js.map +1 -0
- package/dist/src/lib/sysprompt-strip.d.ts +54 -0
- package/dist/src/lib/sysprompt-strip.d.ts.map +1 -0
- package/dist/src/lib/sysprompt-strip.js +75 -0
- package/dist/src/lib/sysprompt-strip.js.map +1 -0
- package/dist/src/lib/telemetry.d.ts +39 -0
- package/dist/src/lib/telemetry.d.ts.map +1 -0
- package/dist/src/lib/telemetry.js +73 -0
- package/dist/src/lib/telemetry.js.map +1 -0
- package/dist/src/lib/test-mode.d.ts +27 -0
- package/dist/src/lib/test-mode.d.ts.map +1 -0
- package/dist/src/lib/test-mode.js +38 -0
- package/dist/src/lib/test-mode.js.map +1 -0
- package/dist/src/lib/vendor-paths.d.ts +15 -0
- package/dist/src/lib/vendor-paths.d.ts.map +1 -0
- package/dist/src/lib/vendor-paths.js +32 -0
- package/dist/src/lib/vendor-paths.js.map +1 -0
- package/dist/src/logger.d.ts +17 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +46 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/mcp/bridge.d.ts +22 -0
- package/dist/src/mcp/bridge.d.ts.map +1 -0
- package/dist/src/mcp/bridge.js +78 -0
- package/dist/src/mcp/bridge.js.map +1 -0
- package/dist/src/mcp/index.d.ts +3 -0
- package/dist/src/mcp/index.d.ts.map +1 -0
- package/dist/src/mcp/index.js +2 -0
- package/dist/src/mcp/index.js.map +1 -0
- package/dist/src/models.d.ts +70 -0
- package/dist/src/models.d.ts.map +1 -0
- package/dist/src/models.js +289 -0
- package/dist/src/models.js.map +1 -0
- package/dist/src/openai-compat/cli-stream-parser.d.ts +135 -0
- package/dist/src/openai-compat/cli-stream-parser.d.ts.map +1 -0
- package/dist/src/openai-compat/cli-stream-parser.js +195 -0
- package/dist/src/openai-compat/cli-stream-parser.js.map +1 -0
- package/dist/src/openai-compat/index.d.ts +2 -0
- package/dist/src/openai-compat/index.d.ts.map +1 -0
- package/dist/src/openai-compat/index.js +2 -0
- package/dist/src/openai-compat/index.js.map +1 -0
- package/dist/src/openai-compat/openai-compat.d.ts +281 -0
- package/dist/src/openai-compat/openai-compat.d.ts.map +1 -0
- package/dist/src/openai-compat/openai-compat.js +939 -0
- package/dist/src/openai-compat/openai-compat.js.map +1 -0
- package/dist/src/openai-compat/skill-resolver.d.ts +36 -0
- package/dist/src/openai-compat/skill-resolver.d.ts.map +1 -0
- package/dist/src/openai-compat/skill-resolver.js +134 -0
- package/dist/src/openai-compat/skill-resolver.js.map +1 -0
- package/dist/src/openai-compat/sse-translator.d.ts +32 -0
- package/dist/src/openai-compat/sse-translator.d.ts.map +1 -0
- package/dist/src/openai-compat/sse-translator.js +155 -0
- package/dist/src/openai-compat/sse-translator.js.map +1 -0
- package/dist/src/proxy/anthropic-adapter.d.ts +137 -0
- package/dist/src/proxy/anthropic-adapter.d.ts.map +1 -0
- package/dist/src/proxy/anthropic-adapter.js +392 -0
- package/dist/src/proxy/anthropic-adapter.js.map +1 -0
- package/dist/src/proxy/handler.d.ts +40 -0
- package/dist/src/proxy/handler.d.ts.map +1 -0
- package/dist/src/proxy/handler.js +378 -0
- package/dist/src/proxy/handler.js.map +1 -0
- package/dist/src/proxy/index.d.ts +5 -0
- package/dist/src/proxy/index.d.ts.map +1 -0
- package/dist/src/proxy/index.js +5 -0
- package/dist/src/proxy/index.js.map +1 -0
- package/dist/src/proxy/schema-cleaner.d.ts +12 -0
- package/dist/src/proxy/schema-cleaner.d.ts.map +1 -0
- package/dist/src/proxy/schema-cleaner.js +34 -0
- package/dist/src/proxy/schema-cleaner.js.map +1 -0
- package/dist/src/proxy/thought-cache.d.ts +20 -0
- package/dist/src/proxy/thought-cache.d.ts.map +1 -0
- package/dist/src/proxy/thought-cache.js +53 -0
- package/dist/src/proxy/thought-cache.js.map +1 -0
- package/dist/src/session/embedded-server.d.ts +26 -0
- package/dist/src/session/embedded-server.d.ts.map +1 -0
- package/dist/src/session/embedded-server.js +367 -0
- package/dist/src/session/embedded-server.js.map +1 -0
- package/dist/src/session/inbox-manager.d.ts +39 -0
- package/dist/src/session/inbox-manager.d.ts.map +1 -0
- package/dist/src/session/inbox-manager.js +111 -0
- package/dist/src/session/inbox-manager.js.map +1 -0
- package/dist/src/session/index.d.ts +4 -0
- package/dist/src/session/index.d.ts.map +1 -0
- package/dist/src/session/index.js +4 -0
- package/dist/src/session/index.js.map +1 -0
- package/dist/src/session/session-manager.d.ts +212 -0
- package/dist/src/session/session-manager.d.ts.map +1 -0
- package/dist/src/session/session-manager.js +1351 -0
- package/dist/src/session/session-manager.js.map +1 -0
- package/dist/src/session-bootstrap/cwd-patch.d.ts +51 -0
- package/dist/src/session-bootstrap/cwd-patch.d.ts.map +1 -0
- package/dist/src/session-bootstrap/cwd-patch.js +955 -0
- package/dist/src/session-bootstrap/cwd-patch.js.map +1 -0
- package/dist/src/session-bootstrap/index.d.ts +4 -0
- package/dist/src/session-bootstrap/index.d.ts.map +1 -0
- package/dist/src/session-bootstrap/index.js +4 -0
- package/dist/src/session-bootstrap/index.js.map +1 -0
- package/dist/src/session-bootstrap/sysprompt-strip.d.ts +26 -0
- package/dist/src/session-bootstrap/sysprompt-strip.d.ts.map +1 -0
- package/dist/src/session-bootstrap/sysprompt-strip.js +57 -0
- package/dist/src/session-bootstrap/sysprompt-strip.js.map +1 -0
- package/dist/src/session-bootstrap/think-conflict-resolver.d.ts +33 -0
- package/dist/src/session-bootstrap/think-conflict-resolver.d.ts.map +1 -0
- package/dist/src/session-bootstrap/think-conflict-resolver.js +234 -0
- package/dist/src/session-bootstrap/think-conflict-resolver.js.map +1 -0
- package/dist/src/types.d.ts +489 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +8 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/validation.d.ts +32 -0
- package/dist/src/validation.d.ts.map +1 -0
- package/dist/src/validation.js +104 -0
- package/dist/src/validation.js.map +1 -0
- package/dist/tests/_helpers/subprocess-mock.d.ts +35 -0
- package/dist/tests/_helpers/subprocess-mock.d.ts.map +1 -0
- package/dist/tests/_helpers/subprocess-mock.js +136 -0
- package/dist/tests/_helpers/subprocess-mock.js.map +1 -0
- package/dist/tests/auto-recovery.test.d.ts +2 -0
- package/dist/tests/auto-recovery.test.d.ts.map +1 -0
- package/dist/tests/auto-recovery.test.js +189 -0
- package/dist/tests/auto-recovery.test.js.map +1 -0
- package/dist/tests/bench-harness.test.d.ts +2 -0
- package/dist/tests/bench-harness.test.d.ts.map +1 -0
- package/dist/tests/bench-harness.test.js +21 -0
- package/dist/tests/bench-harness.test.js.map +1 -0
- package/dist/tests/cache-parity.test.d.ts +2 -0
- package/dist/tests/cache-parity.test.d.ts.map +1 -0
- package/dist/tests/cache-parity.test.js +401 -0
- package/dist/tests/cache-parity.test.js.map +1 -0
- package/dist/tests/command-router.test.d.ts +2 -0
- package/dist/tests/command-router.test.d.ts.map +1 -0
- package/dist/tests/command-router.test.js +60 -0
- package/dist/tests/command-router.test.js.map +1 -0
- package/dist/tests/council.test.d.ts +2 -0
- package/dist/tests/council.test.d.ts.map +1 -0
- package/dist/tests/council.test.js +20 -0
- package/dist/tests/council.test.js.map +1 -0
- package/dist/tests/drift-detector.test.d.ts +2 -0
- package/dist/tests/drift-detector.test.d.ts.map +1 -0
- package/dist/tests/drift-detector.test.js +268 -0
- package/dist/tests/drift-detector.test.js.map +1 -0
- package/dist/tests/eager-bootstrap-gating.test.d.ts +9 -0
- package/dist/tests/eager-bootstrap-gating.test.d.ts.map +1 -0
- package/dist/tests/eager-bootstrap-gating.test.js +97 -0
- package/dist/tests/eager-bootstrap-gating.test.js.map +1 -0
- package/dist/tests/engines.test.d.ts +2 -0
- package/dist/tests/engines.test.d.ts.map +1 -0
- package/dist/tests/engines.test.js +8 -0
- package/dist/tests/engines.test.js.map +1 -0
- package/dist/tests/error-formatter.test.d.ts +2 -0
- package/dist/tests/error-formatter.test.d.ts.map +1 -0
- package/dist/tests/error-formatter.test.js +220 -0
- package/dist/tests/error-formatter.test.js.map +1 -0
- package/dist/tests/health.test.d.ts +2 -0
- package/dist/tests/health.test.d.ts.map +1 -0
- package/dist/tests/health.test.js +110 -0
- package/dist/tests/health.test.js.map +1 -0
- package/dist/tests/heartbeat-workaround.test.d.ts +2 -0
- package/dist/tests/heartbeat-workaround.test.d.ts.map +1 -0
- package/dist/tests/heartbeat-workaround.test.js +90 -0
- package/dist/tests/heartbeat-workaround.test.js.map +1 -0
- package/dist/tests/index.test.d.ts +2 -0
- package/dist/tests/index.test.d.ts.map +1 -0
- package/dist/tests/index.test.js +7 -0
- package/dist/tests/index.test.js.map +1 -0
- package/dist/tests/lib-sysprompt-strip.test.d.ts +2 -0
- package/dist/tests/lib-sysprompt-strip.test.d.ts.map +1 -0
- package/dist/tests/lib-sysprompt-strip.test.js +145 -0
- package/dist/tests/lib-sysprompt-strip.test.js.map +1 -0
- package/dist/tests/listener-activation.test.d.ts +2 -0
- package/dist/tests/listener-activation.test.d.ts.map +1 -0
- package/dist/tests/listener-activation.test.js +87 -0
- package/dist/tests/listener-activation.test.js.map +1 -0
- package/dist/tests/mcp-bridge.test.d.ts +2 -0
- package/dist/tests/mcp-bridge.test.d.ts.map +1 -0
- package/dist/tests/mcp-bridge.test.js +137 -0
- package/dist/tests/mcp-bridge.test.js.map +1 -0
- package/dist/tests/openai-compat.test.d.ts +2 -0
- package/dist/tests/openai-compat.test.d.ts.map +1 -0
- package/dist/tests/openai-compat.test.js +8 -0
- package/dist/tests/openai-compat.test.js.map +1 -0
- package/dist/tests/proxy-heartbeat-integration.test.d.ts +15 -0
- package/dist/tests/proxy-heartbeat-integration.test.d.ts.map +1 -0
- package/dist/tests/proxy-heartbeat-integration.test.js +122 -0
- package/dist/tests/proxy-heartbeat-integration.test.js.map +1 -0
- package/dist/tests/proxy.test.d.ts +2 -0
- package/dist/tests/proxy.test.d.ts.map +1 -0
- package/dist/tests/proxy.test.js +8 -0
- package/dist/tests/proxy.test.js.map +1 -0
- package/dist/tests/register-guard-stacking.test.d.ts +2 -0
- package/dist/tests/register-guard-stacking.test.d.ts.map +1 -0
- package/dist/tests/register-guard-stacking.test.js +61 -0
- package/dist/tests/register-guard-stacking.test.js.map +1 -0
- package/dist/tests/register-guard.test.d.ts +2 -0
- package/dist/tests/register-guard.test.d.ts.map +1 -0
- package/dist/tests/register-guard.test.js +129 -0
- package/dist/tests/register-guard.test.js.map +1 -0
- package/dist/tests/route-flag-rollback.test.d.ts +2 -0
- package/dist/tests/route-flag-rollback.test.d.ts.map +1 -0
- package/dist/tests/route-flag-rollback.test.js +70 -0
- package/dist/tests/route-flag-rollback.test.js.map +1 -0
- package/dist/tests/route-flag.test.d.ts +2 -0
- package/dist/tests/route-flag.test.d.ts.map +1 -0
- package/dist/tests/route-flag.test.js +101 -0
- package/dist/tests/route-flag.test.js.map +1 -0
- package/dist/tests/session-bootstrap.test.d.ts +2 -0
- package/dist/tests/session-bootstrap.test.d.ts.map +1 -0
- package/dist/tests/session-bootstrap.test.js +183 -0
- package/dist/tests/session-bootstrap.test.js.map +1 -0
- package/dist/tests/session.test.d.ts +2 -0
- package/dist/tests/session.test.d.ts.map +1 -0
- package/dist/tests/session.test.js +17 -0
- package/dist/tests/session.test.js.map +1 -0
- package/dist/tests/state-machine.test.d.ts +2 -0
- package/dist/tests/state-machine.test.d.ts.map +1 -0
- package/dist/tests/state-machine.test.js +133 -0
- package/dist/tests/state-machine.test.js.map +1 -0
- package/dist/tests/streaming/cli-stream-parser.test.d.ts +2 -0
- package/dist/tests/streaming/cli-stream-parser.test.d.ts.map +1 -0
- package/dist/tests/streaming/cli-stream-parser.test.js +233 -0
- package/dist/tests/streaming/cli-stream-parser.test.js.map +1 -0
- package/dist/tests/streaming/feature-flag.test.d.ts +14 -0
- package/dist/tests/streaming/feature-flag.test.d.ts.map +1 -0
- package/dist/tests/streaming/feature-flag.test.js +163 -0
- package/dist/tests/streaming/feature-flag.test.js.map +1 -0
- package/dist/tests/streaming/no-tools-prompt.test.d.ts +17 -0
- package/dist/tests/streaming/no-tools-prompt.test.d.ts.map +1 -0
- package/dist/tests/streaming/no-tools-prompt.test.js +229 -0
- package/dist/tests/streaming/no-tools-prompt.test.js.map +1 -0
- package/dist/tests/streaming/skill-plus-tools.test.d.ts +14 -0
- package/dist/tests/streaming/skill-plus-tools.test.d.ts.map +1 -0
- package/dist/tests/streaming/skill-plus-tools.test.js +234 -0
- package/dist/tests/streaming/skill-plus-tools.test.js.map +1 -0
- package/dist/tests/streaming/sse-translator.test.d.ts +2 -0
- package/dist/tests/streaming/sse-translator.test.d.ts.map +1 -0
- package/dist/tests/streaming/sse-translator.test.js +227 -0
- package/dist/tests/streaming/sse-translator.test.js.map +1 -0
- package/dist/tests/streaming/tool-result-roundtrip.test.d.ts +11 -0
- package/dist/tests/streaming/tool-result-roundtrip.test.d.ts.map +1 -0
- package/dist/tests/streaming/tool-result-roundtrip.test.js +215 -0
- package/dist/tests/streaming/tool-result-roundtrip.test.js.map +1 -0
- package/dist/tests/streaming/tool-use-translation.test.d.ts +10 -0
- package/dist/tests/streaming/tool-use-translation.test.d.ts.map +1 -0
- package/dist/tests/streaming/tool-use-translation.test.js +251 -0
- package/dist/tests/streaming/tool-use-translation.test.js.map +1 -0
- package/dist/tests/telegram-bridge.test.d.ts +2 -0
- package/dist/tests/telegram-bridge.test.d.ts.map +1 -0
- package/dist/tests/telegram-bridge.test.js +17 -0
- package/dist/tests/telegram-bridge.test.js.map +1 -0
- package/dist/tests/telegram-injector.test.d.ts +2 -0
- package/dist/tests/telegram-injector.test.d.ts.map +1 -0
- package/dist/tests/telegram-injector.test.js +74 -0
- package/dist/tests/telegram-injector.test.js.map +1 -0
- package/dist/tests/telemetry.test.d.ts +2 -0
- package/dist/tests/telemetry.test.d.ts.map +1 -0
- package/dist/tests/telemetry.test.js +405 -0
- package/dist/tests/telemetry.test.js.map +1 -0
- package/dist/tests/test-mode.test.d.ts +2 -0
- package/dist/tests/test-mode.test.d.ts.map +1 -0
- package/dist/tests/test-mode.test.js +39 -0
- package/dist/tests/test-mode.test.js.map +1 -0
- package/mcp-config.template.json +13 -0
- package/mcp-tools.json +1 -0
- package/openclaw-mcp-bridge.cjs +152 -0
- package/openclaw.plugin.json +30 -0
- package/package.json +45 -0
- package/skills/.gitkeep +0 -0
- package/stubs/commands-status-deps.runtime.js +10 -0
- package/stubs/status.runtime.js +149 -0
- package/vendor/base-oneshot-session.d.ts +87 -0
- package/vendor/base-oneshot-session.js +227 -0
- package/vendor/base-oneshot-session.js.map +1 -0
- package/vendor/circuit-breaker.d.ts +21 -0
- package/vendor/circuit-breaker.js +47 -0
- package/vendor/circuit-breaker.js.map +1 -0
- package/vendor/consensus.d.ts +20 -0
- package/vendor/consensus.js +52 -0
- package/vendor/consensus.js.map +1 -0
- package/vendor/constants.d.ts +130 -0
- package/vendor/constants.js +139 -0
- package/vendor/constants.js.map +1 -0
- package/vendor/council.d.ts +67 -0
- package/vendor/council.js +913 -0
- package/vendor/council.js.map +1 -0
- package/vendor/embedded-server.d.ts +25 -0
- package/vendor/embedded-server.js +360 -0
- package/vendor/embedded-server.js.map +1 -0
- package/vendor/inbox-manager.d.ts +38 -0
- package/vendor/inbox-manager.js +111 -0
- package/vendor/inbox-manager.js.map +1 -0
- package/vendor/index.d.ts +63 -0
- package/vendor/index.js +705 -0
- package/vendor/index.js.map +1 -0
- package/vendor/logger.d.ts +16 -0
- package/vendor/logger.js +44 -0
- package/vendor/logger.js.map +1 -0
- package/vendor/models.d.ts +69 -0
- package/vendor/models.js +289 -0
- package/vendor/models.js.map +1 -0
- package/vendor/openai-compat.d.ts +197 -0
- package/vendor/openai-compat.js +721 -0
- package/vendor/openai-compat.js.map +1 -0
- package/vendor/persistent-codex-session.d.ts +16 -0
- package/vendor/persistent-codex-session.js +105 -0
- package/vendor/persistent-codex-session.js.map +1 -0
- package/vendor/persistent-cursor-session.d.ts +21 -0
- package/vendor/persistent-cursor-session.js +241 -0
- package/vendor/persistent-cursor-session.js.map +1 -0
- package/vendor/persistent-custom-session.d.ts +78 -0
- package/vendor/persistent-custom-session.js +937 -0
- package/vendor/persistent-custom-session.js.map +1 -0
- package/vendor/persistent-gemini-session.d.ts +21 -0
- package/vendor/persistent-gemini-session.js +216 -0
- package/vendor/persistent-gemini-session.js.map +1 -0
- package/vendor/persistent-session.d.ts +74 -0
- package/vendor/persistent-session.js +684 -0
- package/vendor/persistent-session.js.map +1 -0
- package/vendor/proxy/anthropic-adapter.d.ts +136 -0
- package/vendor/proxy/anthropic-adapter.js +392 -0
- package/vendor/proxy/anthropic-adapter.js.map +1 -0
- package/vendor/proxy/handler.d.ts +39 -0
- package/vendor/proxy/handler.js +323 -0
- package/vendor/proxy/handler.js.map +1 -0
- package/vendor/proxy/schema-cleaner.d.ts +11 -0
- package/vendor/proxy/schema-cleaner.js +34 -0
- package/vendor/proxy/schema-cleaner.js.map +1 -0
- package/vendor/proxy/thought-cache.d.ts +19 -0
- package/vendor/proxy/thought-cache.js +53 -0
- package/vendor/proxy/thought-cache.js.map +1 -0
- package/vendor/session-manager.d.ts +211 -0
- package/vendor/session-manager.js +1345 -0
- package/vendor/session-manager.js.map +1 -0
- package/vendor/skill-resolver.js +107 -0
- package/vendor/types.d.ts +466 -0
- package/vendor/types.js +8 -0
- package/vendor/types.js.map +1 -0
- package/vendor/validation.d.ts +31 -0
- package/vendor/validation.js +104 -0
- package/vendor/validation.js.map +1 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// phase: 4 | pillar: 2 | agent: P2.B
|
|
2
|
+
/**
|
|
3
|
+
* drift-detector — cross-laptop version mismatch detection.
|
|
4
|
+
*
|
|
5
|
+
* On register() and every 5 minutes (default), captures:
|
|
6
|
+
* { laptopId, ccOpenclawBuildHash, openclawBinaryVersion, claudeCodeVersion, ts }
|
|
7
|
+
*
|
|
8
|
+
* Writes to ~/.openclaw/state/cc-openclaw-version-state.json (one slot per
|
|
9
|
+
* laptopId) per handoff system slot rule. Compares own slot vs other laptop
|
|
10
|
+
* slots; on mismatch fires Telegram alert + drift.jsonl row with 1h dedup.
|
|
11
|
+
*
|
|
12
|
+
* Configurable via:
|
|
13
|
+
* OPENCLAW_CC_OPENCLAW_DRIFT_ALERTS=0 — disable Telegram noise
|
|
14
|
+
* OPENCLAW_CC_OPENCLAW_DRIFT_DEDUPE_WINDOW_MS — dedup window (default 3600000)
|
|
15
|
+
*/
|
|
16
|
+
import { execSync } from 'node:child_process';
|
|
17
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
18
|
+
import { join, dirname } from 'node:path';
|
|
19
|
+
import { homedir, hostname } from 'node:os';
|
|
20
|
+
import { createHash } from 'node:crypto';
|
|
21
|
+
import { formatError, ERROR_CODES } from './error-formatter.js';
|
|
22
|
+
import { renderError } from '../channels/telegram/error-renderer.js';
|
|
23
|
+
// ─── Config ───────────────────────────────────────────────────────────────────
|
|
24
|
+
const STATE_PATH = join(homedir(), '.openclaw', 'state', 'cc-openclaw-version-state.json');
|
|
25
|
+
const POLL_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
|
|
26
|
+
function isDriftAlertsEnabled() {
|
|
27
|
+
return process.env.OPENCLAW_CC_OPENCLAW_DRIFT_ALERTS !== '0';
|
|
28
|
+
}
|
|
29
|
+
function getDedupWindowMs() {
|
|
30
|
+
const v = process.env.OPENCLAW_CC_OPENCLAW_DRIFT_DEDUPE_WINDOW_MS;
|
|
31
|
+
const n = v !== undefined ? parseInt(v, 10) : NaN;
|
|
32
|
+
return Number.isFinite(n) && n > 0 ? n : 3_600_000;
|
|
33
|
+
}
|
|
34
|
+
// ─── Version capture helpers ─────────────────────────────────────────────────
|
|
35
|
+
function safeExec(cmd, fallback) {
|
|
36
|
+
try {
|
|
37
|
+
return execSync(cmd, { timeout: 5000, stdio: ['ignore', 'pipe', 'ignore'] })
|
|
38
|
+
.toString()
|
|
39
|
+
.trim();
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return fallback;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function resolveLaptopId() {
|
|
46
|
+
// Prefer env override for test isolation, then hostname
|
|
47
|
+
return process.env.OPENCLAW_LAPTOP_ID || hostname();
|
|
48
|
+
}
|
|
49
|
+
function resolveBuildHash() {
|
|
50
|
+
// Hash of own package.json version + the dist/src/index.js mtime for change detection
|
|
51
|
+
try {
|
|
52
|
+
const pkgPath = join(dirname(new URL(import.meta.url).pathname), '../../package.json');
|
|
53
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
54
|
+
const version = pkg.version ?? 'unknown';
|
|
55
|
+
return createHash('sha1').update(version).digest('hex').slice(0, 12);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return 'unknown';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function resolveOpenclawBinaryVersion() {
|
|
62
|
+
return safeExec('openclaw --version 2>/dev/null || openclaw version 2>/dev/null', 'unknown');
|
|
63
|
+
}
|
|
64
|
+
function resolveClaudeCodeVersion() {
|
|
65
|
+
return safeExec('claude --version 2>/dev/null', 'unknown');
|
|
66
|
+
}
|
|
67
|
+
export function captureVersionSlot() {
|
|
68
|
+
return {
|
|
69
|
+
laptopId: resolveLaptopId(),
|
|
70
|
+
ccOpenclawBuildHash: resolveBuildHash(),
|
|
71
|
+
openclawBinaryVersion: resolveOpenclawBinaryVersion(),
|
|
72
|
+
claudeCodeVersion: resolveClaudeCodeVersion(),
|
|
73
|
+
ts: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// ─── State file I/O ───────────────────────────────────────────────────────────
|
|
77
|
+
function readStateFile() {
|
|
78
|
+
try {
|
|
79
|
+
if (!existsSync(STATE_PATH))
|
|
80
|
+
return {};
|
|
81
|
+
const raw = readFileSync(STATE_PATH, 'utf8');
|
|
82
|
+
return JSON.parse(raw);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return {};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function writeStateFile(state) {
|
|
89
|
+
try {
|
|
90
|
+
const dir = dirname(STATE_PATH);
|
|
91
|
+
if (!existsSync(dir))
|
|
92
|
+
mkdirSync(dir, { recursive: true });
|
|
93
|
+
writeFileSync(STATE_PATH, JSON.stringify(state, null, 2) + '\n');
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
process.stderr.write(`[cc-openclaw/drift-detector] state write failed: ${err.message}\n`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ─── Drift comparison ─────────────────────────────────────────────────────────
|
|
100
|
+
const COMPARED_FIELDS = [
|
|
101
|
+
'ccOpenclawBuildHash',
|
|
102
|
+
'openclawBinaryVersion',
|
|
103
|
+
'claudeCodeVersion',
|
|
104
|
+
];
|
|
105
|
+
function detectDrift(own, state) {
|
|
106
|
+
const conflictingSlots = [];
|
|
107
|
+
for (const [laptopId, slot] of Object.entries(state)) {
|
|
108
|
+
if (laptopId === own.laptopId)
|
|
109
|
+
continue;
|
|
110
|
+
const mismatchedFields = COMPARED_FIELDS.filter((f) => slot[f] !== own[f]);
|
|
111
|
+
if (mismatchedFields.length > 0) {
|
|
112
|
+
conflictingSlots.push({ laptopId, slot, fields: mismatchedFields });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
detected: conflictingSlots.length > 0,
|
|
117
|
+
ownSlot: own,
|
|
118
|
+
conflictingSlots,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
// ─── Alert dedup (module-level) ───────────────────────────────────────────────
|
|
122
|
+
let _lastDriftAlertAt = 0;
|
|
123
|
+
function isDriftAlertDue() {
|
|
124
|
+
return Date.now() - _lastDriftAlertAt > getDedupWindowMs();
|
|
125
|
+
}
|
|
126
|
+
function markDriftAlerted() {
|
|
127
|
+
_lastDriftAlertAt = Date.now();
|
|
128
|
+
}
|
|
129
|
+
/** Test-only reset. */
|
|
130
|
+
export function _resetDriftAlertForTests() {
|
|
131
|
+
_lastDriftAlertAt = 0;
|
|
132
|
+
}
|
|
133
|
+
// ─── Core check function ──────────────────────────────────────────────────────
|
|
134
|
+
/**
|
|
135
|
+
* Capture own slot, update state file, compare with other laptops.
|
|
136
|
+
* Fires Telegram + jsonl on mismatch (with 1h dedup).
|
|
137
|
+
*
|
|
138
|
+
* Returns the DriftReport so callers can react programmatically.
|
|
139
|
+
*/
|
|
140
|
+
export async function checkDrift() {
|
|
141
|
+
const own = captureVersionSlot();
|
|
142
|
+
const state = readStateFile();
|
|
143
|
+
// Update own slot
|
|
144
|
+
state[own.laptopId] = own;
|
|
145
|
+
writeStateFile(state);
|
|
146
|
+
const report = detectDrift(own, state);
|
|
147
|
+
if (report.detected && isDriftAlertsEnabled() && isDriftAlertDue()) {
|
|
148
|
+
markDriftAlerted();
|
|
149
|
+
const firstConflict = report.conflictingSlots[0];
|
|
150
|
+
const details = {
|
|
151
|
+
otherLaptop: firstConflict.laptopId,
|
|
152
|
+
mismatchedFields: firstConflict.fields.join(', '),
|
|
153
|
+
ownBuildHash: own.ccOpenclawBuildHash,
|
|
154
|
+
otherBuildHash: firstConflict.slot.ccOpenclawBuildHash,
|
|
155
|
+
ownOpenclawVersion: own.openclawBinaryVersion,
|
|
156
|
+
otherOpenclawVersion: firstConflict.slot.openclawBinaryVersion,
|
|
157
|
+
};
|
|
158
|
+
const formatted = formatError(new Error(`Version drift detected vs ${firstConflict.laptopId}: ` +
|
|
159
|
+
firstConflict.fields.map((f) => `${f}=${firstConflict.slot[f]}`).join(', ')), {
|
|
160
|
+
code: ERROR_CODES.DRIFT_DETECTED,
|
|
161
|
+
laptopId: own.laptopId,
|
|
162
|
+
details,
|
|
163
|
+
});
|
|
164
|
+
await renderError(formatted, { writeJsonl: true });
|
|
165
|
+
}
|
|
166
|
+
return report;
|
|
167
|
+
}
|
|
168
|
+
// ─── Polling lifecycle ────────────────────────────────────────────────────────
|
|
169
|
+
let _pollTimer = null;
|
|
170
|
+
export function startDriftPolling() {
|
|
171
|
+
if (_pollTimer !== null)
|
|
172
|
+
return; // already running
|
|
173
|
+
_pollTimer = setInterval(() => {
|
|
174
|
+
checkDrift().catch((err) => {
|
|
175
|
+
process.stderr.write(`[cc-openclaw/drift-detector] poll error: ${err.message}\n`);
|
|
176
|
+
});
|
|
177
|
+
}, POLL_INTERVAL_MS);
|
|
178
|
+
// Unref so the timer doesn't keep the process alive in test/short-lived contexts
|
|
179
|
+
if (_pollTimer.unref)
|
|
180
|
+
_pollTimer.unref();
|
|
181
|
+
}
|
|
182
|
+
export function stopDriftPolling() {
|
|
183
|
+
if (_pollTimer !== null) {
|
|
184
|
+
clearInterval(_pollTimer);
|
|
185
|
+
_pollTimer = null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** Test-only: check if polling is active. */
|
|
189
|
+
export function _isDriftPollingActive() {
|
|
190
|
+
return _pollTimer !== null;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=drift-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift-detector.js","sourceRoot":"","sources":["../../../src/lib/drift-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* error-formatter — pure ({error, context}) => {jsonlRow, telegramText}
|
|
3
|
+
*
|
|
4
|
+
* Structured error taxonomy for cc-openclaw. Every catchable error site
|
|
5
|
+
* should pass through here so errors are never "Error: undefined" in
|
|
6
|
+
* Telegram or jsonl outputs.
|
|
7
|
+
*
|
|
8
|
+
* Error code taxonomy:
|
|
9
|
+
* CC_OPENCLAW_TOOL_FAILURE — tool invocation failed
|
|
10
|
+
* CC_OPENCLAW_BUDGET_EXCEEDED — quota/budget limit hit
|
|
11
|
+
* CC_OPENCLAW_GATEWAY_CRASH — PM2 process exited unexpectedly
|
|
12
|
+
* CC_OPENCLAW_DRIFT_DETECTED — cross-laptop version mismatch
|
|
13
|
+
* CC_OPENCLAW_HEALTH_PROBE_FAILED — /health endpoint unreachable
|
|
14
|
+
* CC_OPENCLAW_RECOVERY_FAILED — auto-recovery did not succeed
|
|
15
|
+
* CC_OPENCLAW_RECOVERY_OK — auto-recovery succeeded (info)
|
|
16
|
+
* CC_OPENCLAW_SESSION_ERROR — session-level error
|
|
17
|
+
* CC_OPENCLAW_PARSE_ERROR — stream parsing error
|
|
18
|
+
* CC_OPENCLAW_CONFIG_ERROR — configuration/env error
|
|
19
|
+
* CC_OPENCLAW_NETWORK_ERROR — upstream HTTP/network failure
|
|
20
|
+
* CC_OPENCLAW_TIMEOUT — operation exceeded time limit
|
|
21
|
+
* CC_OPENCLAW_AUTH_ERROR — authentication/API key failure
|
|
22
|
+
* CC_OPENCLAW_UNKNOWN — unclassified error
|
|
23
|
+
*/
|
|
24
|
+
export declare const ERROR_CODES: {
|
|
25
|
+
readonly TOOL_FAILURE: "CC_OPENCLAW_TOOL_FAILURE";
|
|
26
|
+
readonly BUDGET_EXCEEDED: "CC_OPENCLAW_BUDGET_EXCEEDED";
|
|
27
|
+
readonly GATEWAY_CRASH: "CC_OPENCLAW_GATEWAY_CRASH";
|
|
28
|
+
readonly DRIFT_DETECTED: "CC_OPENCLAW_DRIFT_DETECTED";
|
|
29
|
+
readonly HEALTH_PROBE_FAILED: "CC_OPENCLAW_HEALTH_PROBE_FAILED";
|
|
30
|
+
readonly RECOVERY_FAILED: "CC_OPENCLAW_RECOVERY_FAILED";
|
|
31
|
+
readonly RECOVERY_OK: "CC_OPENCLAW_RECOVERY_OK";
|
|
32
|
+
readonly SESSION_ERROR: "CC_OPENCLAW_SESSION_ERROR";
|
|
33
|
+
readonly PARSE_ERROR: "CC_OPENCLAW_PARSE_ERROR";
|
|
34
|
+
readonly CONFIG_ERROR: "CC_OPENCLAW_CONFIG_ERROR";
|
|
35
|
+
readonly NETWORK_ERROR: "CC_OPENCLAW_NETWORK_ERROR";
|
|
36
|
+
readonly TIMEOUT: "CC_OPENCLAW_TIMEOUT";
|
|
37
|
+
readonly AUTH_ERROR: "CC_OPENCLAW_AUTH_ERROR";
|
|
38
|
+
readonly UNKNOWN: "CC_OPENCLAW_UNKNOWN";
|
|
39
|
+
};
|
|
40
|
+
export type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
|
|
41
|
+
export type Severity = 'critical' | 'error' | 'warning' | 'info';
|
|
42
|
+
export interface ErrorContext {
|
|
43
|
+
code: ErrorCode;
|
|
44
|
+
sessionId?: string;
|
|
45
|
+
laptopId?: string;
|
|
46
|
+
/** Additional structured key-value details */
|
|
47
|
+
details?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
export interface FormattedError {
|
|
50
|
+
/** NDJSON-ready row */
|
|
51
|
+
jsonlRow: ErrorJsonlRow;
|
|
52
|
+
/** Telegram message text (MarkdownV2-safe) */
|
|
53
|
+
telegramText: string;
|
|
54
|
+
}
|
|
55
|
+
export interface ErrorJsonlRow {
|
|
56
|
+
ts: string;
|
|
57
|
+
code: ErrorCode;
|
|
58
|
+
severity: Severity;
|
|
59
|
+
message: string;
|
|
60
|
+
sessionId?: string;
|
|
61
|
+
laptopId?: string;
|
|
62
|
+
stack?: string;
|
|
63
|
+
details?: Record<string, unknown>;
|
|
64
|
+
}
|
|
65
|
+
/** Extract a usable message from unknown thrown values. */
|
|
66
|
+
export declare function extractMessage(error: unknown): string;
|
|
67
|
+
/** Escape characters special to Telegram MarkdownV2. */
|
|
68
|
+
export declare function escapeMdV2(text: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Pure formatter — no side effects, fully unit-testable.
|
|
71
|
+
*
|
|
72
|
+
* @param error The thrown value (Error instance, string, or unknown)
|
|
73
|
+
* @param context Structured context including mandatory error code
|
|
74
|
+
*/
|
|
75
|
+
export declare function formatError(error: unknown, context: ErrorContext): FormattedError;
|
|
76
|
+
/** Shorthand for the common "unknown catch block" pattern. */
|
|
77
|
+
export declare function formatUnknownError(error: unknown, sessionId?: string): FormattedError;
|
|
78
|
+
//# sourceMappingURL=error-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-formatter.d.ts","sourceRoot":"","sources":["../../../src/lib/error-formatter.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;CAed,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAEvE,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAqBjE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,QAAQ,EAAE,aAAa,CAAC;IACxB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAID,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUrD;AAWD,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/C;AAWD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,cAAc,CA6CjF;AAID,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,CAKrF"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// phase: 4 | pillar: 2 | agent: P2.B
|
|
2
|
+
/**
|
|
3
|
+
* error-formatter — pure ({error, context}) => {jsonlRow, telegramText}
|
|
4
|
+
*
|
|
5
|
+
* Structured error taxonomy for cc-openclaw. Every catchable error site
|
|
6
|
+
* should pass through here so errors are never "Error: undefined" in
|
|
7
|
+
* Telegram or jsonl outputs.
|
|
8
|
+
*
|
|
9
|
+
* Error code taxonomy:
|
|
10
|
+
* CC_OPENCLAW_TOOL_FAILURE — tool invocation failed
|
|
11
|
+
* CC_OPENCLAW_BUDGET_EXCEEDED — quota/budget limit hit
|
|
12
|
+
* CC_OPENCLAW_GATEWAY_CRASH — PM2 process exited unexpectedly
|
|
13
|
+
* CC_OPENCLAW_DRIFT_DETECTED — cross-laptop version mismatch
|
|
14
|
+
* CC_OPENCLAW_HEALTH_PROBE_FAILED — /health endpoint unreachable
|
|
15
|
+
* CC_OPENCLAW_RECOVERY_FAILED — auto-recovery did not succeed
|
|
16
|
+
* CC_OPENCLAW_RECOVERY_OK — auto-recovery succeeded (info)
|
|
17
|
+
* CC_OPENCLAW_SESSION_ERROR — session-level error
|
|
18
|
+
* CC_OPENCLAW_PARSE_ERROR — stream parsing error
|
|
19
|
+
* CC_OPENCLAW_CONFIG_ERROR — configuration/env error
|
|
20
|
+
* CC_OPENCLAW_NETWORK_ERROR — upstream HTTP/network failure
|
|
21
|
+
* CC_OPENCLAW_TIMEOUT — operation exceeded time limit
|
|
22
|
+
* CC_OPENCLAW_AUTH_ERROR — authentication/API key failure
|
|
23
|
+
* CC_OPENCLAW_UNKNOWN — unclassified error
|
|
24
|
+
*/
|
|
25
|
+
// ─── Error code taxonomy ─────────────────────────────────────────────────────
|
|
26
|
+
export const ERROR_CODES = {
|
|
27
|
+
TOOL_FAILURE: 'CC_OPENCLAW_TOOL_FAILURE',
|
|
28
|
+
BUDGET_EXCEEDED: 'CC_OPENCLAW_BUDGET_EXCEEDED',
|
|
29
|
+
GATEWAY_CRASH: 'CC_OPENCLAW_GATEWAY_CRASH',
|
|
30
|
+
DRIFT_DETECTED: 'CC_OPENCLAW_DRIFT_DETECTED',
|
|
31
|
+
HEALTH_PROBE_FAILED: 'CC_OPENCLAW_HEALTH_PROBE_FAILED',
|
|
32
|
+
RECOVERY_FAILED: 'CC_OPENCLAW_RECOVERY_FAILED',
|
|
33
|
+
RECOVERY_OK: 'CC_OPENCLAW_RECOVERY_OK',
|
|
34
|
+
SESSION_ERROR: 'CC_OPENCLAW_SESSION_ERROR',
|
|
35
|
+
PARSE_ERROR: 'CC_OPENCLAW_PARSE_ERROR',
|
|
36
|
+
CONFIG_ERROR: 'CC_OPENCLAW_CONFIG_ERROR',
|
|
37
|
+
NETWORK_ERROR: 'CC_OPENCLAW_NETWORK_ERROR',
|
|
38
|
+
TIMEOUT: 'CC_OPENCLAW_TIMEOUT',
|
|
39
|
+
AUTH_ERROR: 'CC_OPENCLAW_AUTH_ERROR',
|
|
40
|
+
UNKNOWN: 'CC_OPENCLAW_UNKNOWN',
|
|
41
|
+
};
|
|
42
|
+
const SEVERITY_BY_CODE = {
|
|
43
|
+
[ERROR_CODES.TOOL_FAILURE]: 'error',
|
|
44
|
+
[ERROR_CODES.BUDGET_EXCEEDED]: 'warning',
|
|
45
|
+
[ERROR_CODES.GATEWAY_CRASH]: 'critical',
|
|
46
|
+
[ERROR_CODES.DRIFT_DETECTED]: 'warning',
|
|
47
|
+
[ERROR_CODES.HEALTH_PROBE_FAILED]: 'error',
|
|
48
|
+
[ERROR_CODES.RECOVERY_FAILED]: 'critical',
|
|
49
|
+
[ERROR_CODES.RECOVERY_OK]: 'info',
|
|
50
|
+
[ERROR_CODES.SESSION_ERROR]: 'error',
|
|
51
|
+
[ERROR_CODES.PARSE_ERROR]: 'error',
|
|
52
|
+
[ERROR_CODES.CONFIG_ERROR]: 'critical',
|
|
53
|
+
[ERROR_CODES.NETWORK_ERROR]: 'error',
|
|
54
|
+
[ERROR_CODES.TIMEOUT]: 'warning',
|
|
55
|
+
[ERROR_CODES.AUTH_ERROR]: 'critical',
|
|
56
|
+
[ERROR_CODES.UNKNOWN]: 'error',
|
|
57
|
+
};
|
|
58
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
59
|
+
/** Extract a usable message from unknown thrown values. */
|
|
60
|
+
export function extractMessage(error) {
|
|
61
|
+
if (error === null || error === undefined)
|
|
62
|
+
return '(no error message)';
|
|
63
|
+
if (typeof error === 'string')
|
|
64
|
+
return error.trim() || '(empty string error)';
|
|
65
|
+
if (error instanceof Error)
|
|
66
|
+
return error.message || error.name || '(empty Error message)';
|
|
67
|
+
try {
|
|
68
|
+
const s = JSON.stringify(error);
|
|
69
|
+
return s.length > 200 ? s.slice(0, 200) + '...' : s;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return String(error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Extract stack trace when available. */
|
|
76
|
+
function extractStack(error) {
|
|
77
|
+
if (error instanceof Error && error.stack) {
|
|
78
|
+
// Trim to 3 lines to keep jsonl rows compact
|
|
79
|
+
return error.stack.split('\n').slice(0, 4).join('\n');
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
/** Escape characters special to Telegram MarkdownV2. */
|
|
84
|
+
export function escapeMdV2(text) {
|
|
85
|
+
// Per Telegram docs, these must be escaped: _ * [ ] ( ) ~ ` > # + - = | { } . !
|
|
86
|
+
return text.replace(/[_*[\]()~`>#+=|{}.!\\-]/g, (c) => `\\${c}`);
|
|
87
|
+
}
|
|
88
|
+
const SEVERITY_EMOJI = {
|
|
89
|
+
critical: '🚨',
|
|
90
|
+
error: '❌',
|
|
91
|
+
warning: '⚠️',
|
|
92
|
+
info: '✅',
|
|
93
|
+
};
|
|
94
|
+
// ─── Core formatter ───────────────────────────────────────────────────────────
|
|
95
|
+
/**
|
|
96
|
+
* Pure formatter — no side effects, fully unit-testable.
|
|
97
|
+
*
|
|
98
|
+
* @param error The thrown value (Error instance, string, or unknown)
|
|
99
|
+
* @param context Structured context including mandatory error code
|
|
100
|
+
*/
|
|
101
|
+
export function formatError(error, context) {
|
|
102
|
+
const message = extractMessage(error);
|
|
103
|
+
const stack = extractStack(error);
|
|
104
|
+
const severity = SEVERITY_BY_CODE[context.code] ?? 'error';
|
|
105
|
+
const ts = new Date().toISOString();
|
|
106
|
+
const jsonlRow = {
|
|
107
|
+
ts,
|
|
108
|
+
code: context.code,
|
|
109
|
+
severity,
|
|
110
|
+
message,
|
|
111
|
+
...(context.sessionId !== undefined ? { sessionId: context.sessionId } : {}),
|
|
112
|
+
...(context.laptopId !== undefined ? { laptopId: context.laptopId } : {}),
|
|
113
|
+
...(stack !== undefined ? { stack } : {}),
|
|
114
|
+
...(context.details !== undefined ? { details: context.details } : {}),
|
|
115
|
+
};
|
|
116
|
+
const emoji = SEVERITY_EMOJI[severity];
|
|
117
|
+
const safeCode = escapeMdV2(context.code);
|
|
118
|
+
const safeMsg = escapeMdV2(message.length > 300 ? message.slice(0, 300) + '...' : message);
|
|
119
|
+
const safeTs = escapeMdV2(ts.slice(0, 19).replace('T', ' '));
|
|
120
|
+
const lines = [
|
|
121
|
+
`${emoji} *${safeCode}*`,
|
|
122
|
+
`\`${safeMsg}\``,
|
|
123
|
+
`_${safeTs}_`,
|
|
124
|
+
];
|
|
125
|
+
if (context.sessionId) {
|
|
126
|
+
lines.push(`session: \`${escapeMdV2(context.sessionId)}\``);
|
|
127
|
+
}
|
|
128
|
+
if (context.laptopId) {
|
|
129
|
+
lines.push(`laptop: \`${escapeMdV2(context.laptopId)}\``);
|
|
130
|
+
}
|
|
131
|
+
if (context.details && Object.keys(context.details).length > 0) {
|
|
132
|
+
const detailParts = Object.entries(context.details)
|
|
133
|
+
.slice(0, 5)
|
|
134
|
+
.map(([k, v]) => `${escapeMdV2(k)}: ${escapeMdV2(String(v))}`)
|
|
135
|
+
.join(', ');
|
|
136
|
+
lines.push(`_${detailParts}_`);
|
|
137
|
+
}
|
|
138
|
+
const telegramText = lines.join('\n');
|
|
139
|
+
return { jsonlRow, telegramText };
|
|
140
|
+
}
|
|
141
|
+
// ─── Convenience factory ─────────────────────────────────────────────────────
|
|
142
|
+
/** Shorthand for the common "unknown catch block" pattern. */
|
|
143
|
+
export function formatUnknownError(error, sessionId) {
|
|
144
|
+
return formatError(error, {
|
|
145
|
+
code: ERROR_CODES.UNKNOWN,
|
|
146
|
+
sessionId,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=error-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-formatter.js","sourceRoot":"","sources":["../../../src/lib/error-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heartbeat model workaround — SDK-call-layer override.
|
|
3
|
+
*
|
|
4
|
+
* Tracks OpenClaw issues #9556, #13009, #14279: heartbeat-triggered runs
|
|
5
|
+
* ignore the heartbeat.model field and use the session's primary model
|
|
6
|
+
* (typically Opus). This wastes tokens and adds latency on what should be
|
|
7
|
+
* a cheap Haiku ping.
|
|
8
|
+
*
|
|
9
|
+
* applyHeartbeatWorkaround() inspects an SDK request payload, detects
|
|
10
|
+
* heartbeat-shaped requests via heuristics (low input tokens + heartbeat
|
|
11
|
+
* sentinel in messages), and forces the model field to the heartbeat.model
|
|
12
|
+
* value (or HEARTBEAT_FALLBACK_MODEL when missing).
|
|
13
|
+
*
|
|
14
|
+
* Disable via CC_OPENCLAW_DISABLE_HEARTBEAT_WORKAROUND=1 — set this when
|
|
15
|
+
* upstream OpenClaw ships a native fix.
|
|
16
|
+
*/
|
|
17
|
+
export declare const HEARTBEAT_FALLBACK_MODEL = "claude-haiku-4-5";
|
|
18
|
+
/** Sentinel strings observed in upstream OpenClaw heartbeat payloads. */
|
|
19
|
+
export declare const HEARTBEAT_SENTINELS: readonly ["__heartbeat__", "heartbeat:ping", "__keepalive__"];
|
|
20
|
+
export interface SdkRequestPayload {
|
|
21
|
+
model: string;
|
|
22
|
+
messages?: Array<{
|
|
23
|
+
role: string;
|
|
24
|
+
content: string | unknown;
|
|
25
|
+
}>;
|
|
26
|
+
metadata?: Record<string, unknown>;
|
|
27
|
+
/** Some payloads carry the intended heartbeat model in metadata or top-level */
|
|
28
|
+
heartbeat?: {
|
|
29
|
+
model?: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Heuristic: a request is heartbeat-shaped if:
|
|
34
|
+
* - metadata.heartbeat or top-level heartbeat field is set, OR
|
|
35
|
+
* - any message content contains a heartbeat sentinel, OR
|
|
36
|
+
* - metadata flag `is_heartbeat: true`
|
|
37
|
+
*/
|
|
38
|
+
export declare function isHeartbeatRequest(req: SdkRequestPayload): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Apply the workaround: if the request is heartbeat-shaped and the workaround
|
|
41
|
+
* is not disabled, override the model to the heartbeat target. Returns a NEW
|
|
42
|
+
* payload object (does not mutate input).
|
|
43
|
+
*/
|
|
44
|
+
export declare function applyHeartbeatWorkaround(req: SdkRequestPayload): SdkRequestPayload;
|
|
45
|
+
//# sourceMappingURL=heartbeat-workaround.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat-workaround.d.ts","sourceRoot":"","sources":["../../../src/lib/heartbeat-workaround.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAE3D,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,+DAAgE,CAAC;AAEjG,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gFAAgF;IAChF,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAclE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,iBAAiB,GAAG,iBAAiB,CAOlF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heartbeat model workaround — SDK-call-layer override.
|
|
3
|
+
*
|
|
4
|
+
* Tracks OpenClaw issues #9556, #13009, #14279: heartbeat-triggered runs
|
|
5
|
+
* ignore the heartbeat.model field and use the session's primary model
|
|
6
|
+
* (typically Opus). This wastes tokens and adds latency on what should be
|
|
7
|
+
* a cheap Haiku ping.
|
|
8
|
+
*
|
|
9
|
+
* applyHeartbeatWorkaround() inspects an SDK request payload, detects
|
|
10
|
+
* heartbeat-shaped requests via heuristics (low input tokens + heartbeat
|
|
11
|
+
* sentinel in messages), and forces the model field to the heartbeat.model
|
|
12
|
+
* value (or HEARTBEAT_FALLBACK_MODEL when missing).
|
|
13
|
+
*
|
|
14
|
+
* Disable via CC_OPENCLAW_DISABLE_HEARTBEAT_WORKAROUND=1 — set this when
|
|
15
|
+
* upstream OpenClaw ships a native fix.
|
|
16
|
+
*/
|
|
17
|
+
import { isHeartbeatWorkaroundDisabled } from './config.js';
|
|
18
|
+
export const HEARTBEAT_FALLBACK_MODEL = 'claude-haiku-4-5';
|
|
19
|
+
/** Sentinel strings observed in upstream OpenClaw heartbeat payloads. */
|
|
20
|
+
export const HEARTBEAT_SENTINELS = ['__heartbeat__', 'heartbeat:ping', '__keepalive__'];
|
|
21
|
+
/**
|
|
22
|
+
* Heuristic: a request is heartbeat-shaped if:
|
|
23
|
+
* - metadata.heartbeat or top-level heartbeat field is set, OR
|
|
24
|
+
* - any message content contains a heartbeat sentinel, OR
|
|
25
|
+
* - metadata flag `is_heartbeat: true`
|
|
26
|
+
*/
|
|
27
|
+
export function isHeartbeatRequest(req) {
|
|
28
|
+
if (req.heartbeat?.model)
|
|
29
|
+
return true;
|
|
30
|
+
if (req.metadata?.heartbeat)
|
|
31
|
+
return true;
|
|
32
|
+
if (req.metadata?.is_heartbeat === true)
|
|
33
|
+
return true;
|
|
34
|
+
if (Array.isArray(req.messages)) {
|
|
35
|
+
for (const msg of req.messages) {
|
|
36
|
+
if (typeof msg.content === 'string') {
|
|
37
|
+
for (const sentinel of HEARTBEAT_SENTINELS) {
|
|
38
|
+
if (msg.content.includes(sentinel))
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Apply the workaround: if the request is heartbeat-shaped and the workaround
|
|
48
|
+
* is not disabled, override the model to the heartbeat target. Returns a NEW
|
|
49
|
+
* payload object (does not mutate input).
|
|
50
|
+
*/
|
|
51
|
+
export function applyHeartbeatWorkaround(req) {
|
|
52
|
+
if (isHeartbeatWorkaroundDisabled())
|
|
53
|
+
return req;
|
|
54
|
+
if (!isHeartbeatRequest(req))
|
|
55
|
+
return req;
|
|
56
|
+
const heartbeatModel = req.heartbeat?.model
|
|
57
|
+
?? req.metadata?.heartbeat?.model
|
|
58
|
+
?? HEARTBEAT_FALLBACK_MODEL;
|
|
59
|
+
return { ...req, model: heartbeatModel };
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=heartbeat-workaround.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat-workaround.js","sourceRoot":"","sources":["../../../src/lib/heartbeat-workaround.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,CAAC,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAE3D,yEAAyE;AACzE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,eAAe,EAAE,gBAAgB,EAAE,eAAe,CAAU,CAAC;AAUjG;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAsB;IACvD,IAAI,GAAG,CAAC,SAAS,EAAE,KAAK;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,GAAG,CAAC,QAAQ,EAAE,SAAS;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC/B,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACpC,KAAK,MAAM,QAAQ,IAAI,mBAAmB,EAAE,CAAC;oBAC3C,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAAE,OAAO,IAAI,CAAC;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAsB;IAC7D,IAAI,6BAA6B,EAAE;QAAE,OAAO,GAAG,CAAC;IAChD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACzC,MAAM,cAAc,GAAG,GAAG,CAAC,SAAS,EAAE,KAAK;WACrC,GAAG,CAAC,QAAQ,EAAE,SAA4C,EAAE,KAAK;WAClE,wBAAwB,CAAC;IAC9B,OAAO,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './register-guard.js';
|
|
2
|
+
export { registerOnce } from './register-guard.js';
|
|
3
|
+
export { stripSysprompt, isStripEnabled, type StripOptions, type StripResult } from './sysprompt-strip.js';
|
|
4
|
+
export { isCacheParityEnabled, hashPrompt, recordAttachment, readRegistry, REGISTRY_PATH, type RegistryEntry, } from './cache-parity.js';
|
|
5
|
+
export { selectEngine, isCcOpenclawEnabled, captureSessionRoute, ACTIVE_FLAG_ENV, ROUTE_FLAG_ENV, type Engine, type SessionRoute, } from './route-flag.js';
|
|
6
|
+
export { isTestMode, TEST_MODE_ENV, _setTestModeForTests } from './test-mode.js';
|
|
7
|
+
export { getAggressiveStripEnabled, getCacheParityEnabled, getLogLevel, isLogLevelDebug, } from './config.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC3G,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,KAAK,MAAM,EACX,KAAK,YAAY,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,WAAW,EACX,eAAe,GAChB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './register-guard.js';
|
|
2
|
+
export { registerOnce } from './register-guard.js';
|
|
3
|
+
export { stripSysprompt, isStripEnabled } from './sysprompt-strip.js';
|
|
4
|
+
export { isCacheParityEnabled, hashPrompt, recordAttachment, readRegistry, REGISTRY_PATH, } from './cache-parity.js';
|
|
5
|
+
export { selectEngine, isCcOpenclawEnabled, captureSessionRoute, ACTIVE_FLAG_ENV, ROUTE_FLAG_ENV, } from './route-flag.js';
|
|
6
|
+
export { isTestMode, TEST_MODE_ENV, _setTestModeForTests } from './test-mode.js';
|
|
7
|
+
export { getAggressiveStripEnabled, getCacheParityEnabled, getLogLevel, isLogLevelDebug, } from './config.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAuC,MAAM,sBAAsB,CAAC;AAC3G,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,GAEd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,cAAc,GAGf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,WAAW,EACX,eAAe,GAChB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized register-guard — eliminates listener stacking systemwide.
|
|
3
|
+
* Each plugin module gets its own guard instance via createRegisterGuard().
|
|
4
|
+
* Multiple register() calls with same id → no-op (regardless of api identity).
|
|
5
|
+
*
|
|
6
|
+
* Rationale (revised 2026-04-29 after observed production stacking):
|
|
7
|
+
* The openclaw gateway calls plugin register() multiple times per process —
|
|
8
|
+
* once per plugin context (gateway thread, per-agent thread). Each context
|
|
9
|
+
* passes a different `api` instance, but every api wraps the SAME shared
|
|
10
|
+
* event bus. Calling `api.on('event', fn)` from any api instance adds `fn`
|
|
11
|
+
* to that shared bus. So if we re-fire register body on each "new api",
|
|
12
|
+
* listeners stack N× → duplicate emissions (e.g. doubled-greeting on /new
|
|
13
|
+
* with 3 register cycles producing 3 sendMessage calls per reply).
|
|
14
|
+
*
|
|
15
|
+
* Previous behavior: tracked by (id, api) pair — re-fired on new api.
|
|
16
|
+
* Rationale was "hot-reload should re-wire" but that's not what happens
|
|
17
|
+
* in production; production gets multi-context registration in one process.
|
|
18
|
+
*
|
|
19
|
+
* Current behavior: track by id only. First register fires body; subsequent
|
|
20
|
+
* registers (any api) skip. Use `_resetForTests()` to clear between tests.
|
|
21
|
+
*
|
|
22
|
+
* Telemetry: when OPENCLAW_REGISTER_DEBUG=1, emits a structured event per
|
|
23
|
+
* register call (id, registered_before, timestamp). Sibling agent
|
|
24
|
+
* cco-hardening-B implements telemetry.ts which consumes these events.
|
|
25
|
+
*/
|
|
26
|
+
export interface RegisterGuard {
|
|
27
|
+
/** Wraps the actual register body — only runs once per (id, api) pair. */
|
|
28
|
+
guard(id: string, api: unknown, body: () => void): void;
|
|
29
|
+
/** Test-only reset. */
|
|
30
|
+
_resetForTests(): void;
|
|
31
|
+
/** Inspector for tests / telemetry. */
|
|
32
|
+
isRegistered(id: string): boolean;
|
|
33
|
+
}
|
|
34
|
+
export declare function createRegisterGuard(): RegisterGuard;
|
|
35
|
+
/** Default singleton — most modules import this directly for simplicity. */
|
|
36
|
+
export declare const defaultRegisterGuard: RegisterGuard;
|
|
37
|
+
/**
|
|
38
|
+
* `registerOnce(id, api, body)` — preferred shorthand for the v3 §5 hard-rule
|
|
39
|
+
* contract: every `api.on(...)` call site must live inside an idempotency
|
|
40
|
+
* wrapper. Delegates to `defaultRegisterGuard.guard(id, api, body)` —
|
|
41
|
+
* semantically identical, just shorter at call sites.
|
|
42
|
+
*
|
|
43
|
+
* The CI check `scripts/check-register-once.sh` greps for any `api.on(`
|
|
44
|
+
* line whose containing module does NOT also reference `registerOnce` or
|
|
45
|
+
* `defaultRegisterGuard.guard`. Either form passes; bare `api.on()` calls
|
|
46
|
+
* (no idempotency wrapper) fail.
|
|
47
|
+
*/
|
|
48
|
+
export declare function registerOnce(id: string, api: unknown, body: () => void): void;
|
|
49
|
+
//# sourceMappingURL=register-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-guard.d.ts","sourceRoot":"","sources":["../../../src/lib/register-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACxD,uBAAuB;IACvB,cAAc,IAAI,IAAI,CAAC;IACvB,uCAAuC;IACvC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED,wBAAgB,mBAAmB,IAAI,aAAa,CA8BnD;AAED,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,eAAwB,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAE7E"}
|