mixdog 0.9.3 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -3
- package/scripts/bench/lead-review-tasks-r3.json +20 -0
- package/scripts/bench/lead-review-tasks.json +20 -0
- package/scripts/bench/r4-mixed-tasks.json +20 -0
- package/scripts/bench/review-tasks.json +20 -0
- package/scripts/bench/round-codex.json +114 -0
- package/scripts/bench/round-mixdog-lead-r3.json +269 -0
- package/scripts/bench/round-mixdog-lead.json +269 -0
- package/scripts/bench/round-mixdog.json +126 -0
- package/scripts/bench/round-r10-bigsample.json +679 -0
- package/scripts/bench/round-r11-codexalign.json +257 -0
- package/scripts/bench/round-r4-codex.json +114 -0
- package/scripts/bench/round-r4-mixed.json +225 -0
- package/scripts/bench/round-r5-gpt-lead.json +259 -0
- package/scripts/bench/round-r6-codex.json +114 -0
- package/scripts/bench/round-r6-solo.json +257 -0
- package/scripts/bench/round-r7-full.json +254 -0
- package/scripts/bench/round-r8-fulldefault.json +255 -0
- package/scripts/bench-run.mjs +215 -29
- package/scripts/freevar-smoke.mjs +95 -0
- package/scripts/internal-comms-bench.mjs +1 -0
- package/scripts/internal-comms-smoke.mjs +10 -9
- package/scripts/mouse-probe.mjs +45 -0
- package/scripts/output-style-bench.mjs +13 -6
- package/scripts/output-style-smoke.mjs +4 -4
- package/scripts/provider-toolcall-test.mjs +7 -3
- package/scripts/recall-usecase-cases.json +18 -0
- package/scripts/recall-usecase-probe.json +6 -0
- package/scripts/session-bench.mjs +152 -6
- package/scripts/tool-smoke.mjs +23 -63
- package/scripts/tui-render-smoke.mjs +90 -0
- package/scripts/webhook-smoke.mjs +208 -0
- package/src/agents/debugger/AGENT.md +4 -1
- package/src/agents/heavy-worker/AGENT.md +6 -5
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +2 -1
- package/src/agents/worker/AGENT.md +8 -4
- package/src/lib/rules-builder.cjs +4 -0
- package/src/mixdog-session-runtime.mjs +632 -2042
- package/src/output-styles/default.md +34 -9
- package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
- package/src/output-styles/minimal.md +4 -1
- package/src/output-styles/simple.md +22 -7
- package/src/rules/agent/00-common.md +2 -0
- package/src/rules/lead/lead-brief.md +12 -0
- package/src/rules/lead/lead-tool.md +0 -11
- package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
- package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
- package/src/runtime/agent/orchestrator/config.mjs +69 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +62 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +81 -1281
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -3
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +43 -1013
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +86 -11
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +348 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +40 -1143
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +732 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +297 -2123
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +130 -1002
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +227 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +436 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
- package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +182 -0
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +251 -397
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +166 -1087
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +32 -41
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -92
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +28 -265
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +0 -6
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +57 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +10 -122
- package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
- package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +0 -21
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -72
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
- package/src/runtime/channels/backends/discord-access.mjs +32 -0
- package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
- package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
- package/src/runtime/channels/backends/discord.mjs +12 -292
- package/src/runtime/channels/index.mjs +229 -663
- package/src/runtime/channels/lib/backend-dispatch.mjs +44 -0
- package/src/runtime/channels/lib/event-pipeline.mjs +18 -1
- package/src/runtime/channels/lib/event-queue.mjs +63 -4
- package/src/runtime/channels/lib/inbound-routing.mjs +111 -0
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -1
- package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
- package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
- package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
- package/src/runtime/channels/lib/session-discovery.mjs +56 -4
- package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
- package/src/runtime/channels/lib/tool-format.mjs +1 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
- package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
- package/src/runtime/channels/lib/webhook/deliveries.mjs +312 -0
- package/src/runtime/channels/lib/webhook/log.mjs +42 -0
- package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
- package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
- package/src/runtime/channels/lib/webhook.mjs +36 -570
- package/src/runtime/channels/tool-defs.mjs +11 -130
- package/src/runtime/memory/index.mjs +201 -1948
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
- package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
- package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
- package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
- package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +24 -842
- package/src/runtime/memory/lib/memory-embed.mjs +149 -0
- package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
- package/src/runtime/memory/lib/query-handlers.mjs +780 -0
- package/src/runtime/memory/lib/recall-format.mjs +55 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
- package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
- package/src/runtime/memory/tool-defs.mjs +5 -13
- package/src/runtime/search/lib/http-fetch.mjs +274 -0
- package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
- package/src/runtime/search/lib/web-tools.mjs +24 -602
- package/src/runtime/shared/atomic-file.mjs +26 -1
- package/src/runtime/shared/launcher-control.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +308 -0
- package/src/runtime/shared/tool-result-summary.mjs +515 -0
- package/src/runtime/shared/tool-surface.mjs +80 -898
- package/src/runtime/shared/transcript-writer.mjs +23 -0
- package/src/runtime/shared/update-checker.mjs +7 -4
- package/src/session-runtime/config-helpers.mjs +84 -2
- package/src/session-runtime/config-lifecycle.mjs +232 -0
- package/src/session-runtime/cwd-plugins.mjs +226 -0
- package/src/session-runtime/mcp-glue.mjs +177 -0
- package/src/session-runtime/model-recency.mjs +111 -0
- package/src/session-runtime/native-search.mjs +247 -0
- package/src/session-runtime/output-styles.mjs +11 -9
- package/src/session-runtime/prewarm.mjs +142 -0
- package/src/session-runtime/provider-models.mjs +278 -0
- package/src/session-runtime/provider-usage.mjs +120 -0
- package/src/session-runtime/quick-model-rows.mjs +170 -0
- package/src/session-runtime/quick-search-models.mjs +46 -0
- package/src/session-runtime/session-hooks.mjs +93 -0
- package/src/session-runtime/settings-api.mjs +319 -0
- package/src/session-runtime/tool-catalog.mjs +29 -29
- package/src/session-runtime/tool-defs.mjs +84 -0
- package/src/session-runtime/warmup-schedulers.mjs +201 -0
- package/src/standalone/agent-tool/helpers.mjs +237 -0
- package/src/standalone/agent-tool/notify.mjs +107 -0
- package/src/standalone/agent-tool/provider-init.mjs +143 -0
- package/src/standalone/agent-tool/render.mjs +152 -0
- package/src/standalone/agent-tool/tool-def.mjs +55 -0
- package/src/standalone/agent-tool.mjs +110 -671
- package/src/standalone/channel-worker.mjs +4 -7
- package/src/standalone/explore-tool.mjs +30 -9
- package/src/standalone/hook-bus/config.mjs +207 -0
- package/src/standalone/hook-bus/constants.mjs +90 -0
- package/src/standalone/hook-bus/handlers.mjs +481 -0
- package/src/standalone/hook-bus/payload.mjs +31 -0
- package/src/standalone/hook-bus/rules.mjs +77 -0
- package/src/standalone/hook-bus.mjs +77 -870
- package/src/standalone/memory-runtime-proxy.mjs +7 -0
- package/src/standalone/opencode-go-login.mjs +5 -1
- package/src/standalone/provider-admin.mjs +1 -16
- package/src/standalone/usage-dashboard.mjs +3 -1
- package/src/tui/App.jsx +945 -8094
- package/src/tui/app/app-format.mjs +206 -0
- package/src/tui/app/channel-pickers.mjs +510 -0
- package/src/tui/app/clipboard.mjs +67 -0
- package/src/tui/app/core-memory-picker.mjs +210 -0
- package/src/tui/app/extension-pickers.mjs +506 -0
- package/src/tui/app/input-parsers.mjs +193 -0
- package/src/tui/app/maintenance-pickers.mjs +324 -0
- package/src/tui/app/model-options.mjs +330 -0
- package/src/tui/app/model-picker.mjs +365 -0
- package/src/tui/app/onboarding-steps.mjs +400 -0
- package/src/tui/app/project-picker.mjs +247 -0
- package/src/tui/app/provider-setup-picker.mjs +580 -0
- package/src/tui/app/resume-picker.mjs +55 -0
- package/src/tui/app/route-pickers.mjs +419 -0
- package/src/tui/app/settings-picker.mjs +490 -0
- package/src/tui/app/slash-commands.mjs +101 -0
- package/src/tui/app/slash-dispatch.mjs +427 -0
- package/src/tui/app/text-layout.mjs +46 -0
- package/src/tui/app/theme-effort-pickers.mjs +154 -0
- package/src/tui/app/transcript-window.mjs +671 -0
- package/src/tui/app/use-mouse-input.mjs +460 -0
- package/src/tui/app/use-prompt-handlers.mjs +310 -0
- package/src/tui/app/use-transcript-scroll.mjs +510 -0
- package/src/tui/app/use-transcript-window.mjs +589 -0
- package/src/tui/components/ConfirmBar.jsx +1 -1
- package/src/tui/components/Picker.jsx +32 -4
- package/src/tui/components/PromptInput.jsx +23 -101
- package/src/tui/components/SlashCommandPalette.jsx +8 -1
- package/src/tui/components/StatusLine.jsx +63 -12
- package/src/tui/components/TextEntryPanel.jsx +11 -0
- package/src/tui/components/ToolExecution.jsx +52 -594
- package/src/tui/components/TranscriptItem.jsx +105 -0
- package/src/tui/components/UsagePanel.jsx +18 -4
- package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
- package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
- package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
- package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
- package/src/tui/components/tool-execution/text-format.mjs +161 -0
- package/src/tui/display-width.mjs +20 -3
- package/src/tui/dist/index.mjs +19652 -18630
- package/src/tui/engine/agent-job-feed.mjs +133 -0
- package/src/tui/engine/notification-plan.mjs +76 -0
- package/src/tui/engine/render-timing.mjs +17 -0
- package/src/tui/engine/tool-approval.mjs +94 -0
- package/src/tui/engine/tool-card-results.mjs +234 -0
- package/src/tui/engine/tool-result-status.mjs +135 -0
- package/src/tui/engine.mjs +122 -562
- package/src/tui/figures.mjs +5 -0
- package/src/tui/index.jsx +105 -0
- package/src/tui/input-editing.mjs +2 -2
- package/src/tui/markdown/format-token.mjs +4 -1
- package/src/tui/statusline-ansi-bridge.mjs +11 -3
- package/src/tui/theme.mjs +6 -0
- package/src/ui/statusline-agents.mjs +213 -0
- package/src/ui/statusline-format.mjs +146 -0
- package/src/ui/statusline-segments.mjs +148 -0
- package/src/ui/statusline.mjs +67 -501
- package/src/ui/tool-card.mjs +0 -1
- package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
- package/src/workflows/default/WORKFLOW.md +1 -1
- package/src/workflows/sequential/WORKFLOW.md +1 -1
- package/vendor/ink/build/display-width.js +19 -3
- package/vendor/ink/build/ink.js +103 -6
- package/vendor/ink/build/log-update.js +17 -3
- package/vendor/ink/build/wrap-text.js +125 -0
- package/scripts/_test-folder-dialog.mjs +0 -30
- package/scripts/fix-brief-fn.mjs +0 -35
- package/scripts/fix-format-tool-surface.mjs +0 -24
- package/scripts/fix-tool-exec-visible.mjs +0 -42
- package/scripts/patch-agent-brief.mjs +0 -48
- package/scripts/patch-app.mjs +0 -21
- package/scripts/patch-app2.mjs +0 -18
- package/scripts/patch-dist-brief.mjs +0 -96
- package/scripts/patch-tool-exec.mjs +0 -70
- package/src/examples/schedules/SCHEDULE.example.md +0 -32
- package/src/examples/webhooks/WEBHOOK.example.md +0 -40
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +0 -162
- package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
- package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
- package/src/runtime/shared/task-notification-envelope.test.mjs +0 -107
- package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
- package/src/standalone/agent-task-status.test.mjs +0 -76
- package/src/tui/components/tool-output-format.test.mjs +0 -399
- package/src/tui/display-width.test.mjs +0 -35
- package/src/tui/engine-runtime-notification.test.mjs +0 -115
- package/src/tui/engine-tool-result-text.test.mjs +0 -75
- package/src/tui/input-editing.selection.test.mjs +0 -75
- package/src/tui/markdown/format-token.test.mjs +0 -354
- package/src/tui/markdown/render-ansi.test.mjs +0 -108
- package/src/tui/markdown/stream-fence.test.mjs +0 -26
- package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
- package/src/tui/paste-fix.test.mjs +0 -119
- package/src/tui/prompt-history-store.test.mjs +0 -52
- package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
- package/src/tui/transcript-tool-failures.test.mjs +0 -111
- package/src/ui/markdown.test.mjs +0 -70
- package/src/ui/statusline-context-label.test.mjs +0 -15
- package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
- package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
|
@@ -9,15 +9,12 @@ import { appendBuffered } from '../runtime/shared/buffered-appender.mjs';
|
|
|
9
9
|
const CHANNEL_TOOLS = new Set([
|
|
10
10
|
'reply',
|
|
11
11
|
'fetch',
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
'trigger_schedule',
|
|
17
|
-
'schedule_control',
|
|
12
|
+
// activate_channel_bridge/reload_config are NOT model-facing tools (no
|
|
13
|
+
// TOOL_DEFS entry) but stay in the allow-set: mixdog-session-runtime.mjs
|
|
14
|
+
// calls channels.execute() with these names directly as internal
|
|
15
|
+
// Lead-only runtime plumbing (bridge-claim on start, config hot-reload).
|
|
18
16
|
'activate_channel_bridge',
|
|
19
17
|
'reload_config',
|
|
20
|
-
'inject_command',
|
|
21
18
|
]);
|
|
22
19
|
|
|
23
20
|
const WORKER_PRELOAD = fileURLToPath(new URL('./channel-worker-preload.cjs', import.meta.url));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isAbsolute, resolve } from 'node:path';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
2
3
|
import { homedir } from 'node:os';
|
|
3
4
|
import { makeAgentDispatch } from '../runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs';
|
|
4
5
|
import { loadConfig } from '../runtime/agent/orchestrator/config.mjs';
|
|
@@ -80,11 +81,11 @@ function resolveExploreCwd(input, callerCwd) {
|
|
|
80
81
|
return base;
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
function settledExplorerResult(result) {
|
|
84
|
+
function settledExplorerResult(result, cwd = null) {
|
|
84
85
|
if (result?.status !== 'fulfilled') {
|
|
85
86
|
return { ok: false, text: `[explorer error] ${result?.reason?.message || String(result?.reason)}` };
|
|
86
87
|
}
|
|
87
|
-
const text = cleanExplorerText(typeof result.value === 'string' ? result.value : responseText(result.value));
|
|
88
|
+
const text = cleanExplorerText(typeof result.value === 'string' ? result.value : responseText(result.value), cwd);
|
|
88
89
|
if (!text) return { ok: false, text: '[explorer error] empty response' };
|
|
89
90
|
return { ok: true, text };
|
|
90
91
|
}
|
|
@@ -106,10 +107,10 @@ function fatalExploreError(settled) {
|
|
|
106
107
|
return (settled || []).find((r) => r?.status === 'rejected' && isFatalExploreError(r.reason))?.reason || null;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
function mergeSettled(settled, queries) {
|
|
110
|
+
function mergeSettled(settled, queries, cwd = null) {
|
|
110
111
|
const single = queries.length === 1;
|
|
111
112
|
if (single) {
|
|
112
|
-
const { text: body } = settledExplorerResult(settled[0]);
|
|
113
|
+
const { text: body } = settledExplorerResult(settled[0], cwd);
|
|
113
114
|
return body.length > EXPLORE_OUTPUT_CHAR_CAP
|
|
114
115
|
? body.slice(0, EXPLORE_OUTPUT_CHAR_CAP) + EXPLORE_TRUNCATION_MARKER
|
|
115
116
|
: body;
|
|
@@ -120,7 +121,7 @@ function mergeSettled(settled, queries) {
|
|
|
120
121
|
let truncated = false;
|
|
121
122
|
for (let i = 0; i < settled.length; i++) {
|
|
122
123
|
const header = `Q${i + 1}: ${String(queries[i] ?? '').replace(/\s+/g, ' ').slice(0, 60)}`;
|
|
123
|
-
const { text: body } = settledExplorerResult(settled[i]);
|
|
124
|
+
const { text: body } = settledExplorerResult(settled[i], cwd);
|
|
124
125
|
const piece = `${header}\n${body}`;
|
|
125
126
|
const addLen = (parts.length === 0 ? 0 : sep.length) + piece.length;
|
|
126
127
|
if (total + addLen > EXPLORE_OUTPUT_CHAR_CAP) {
|
|
@@ -247,6 +248,7 @@ function responseText(response) {
|
|
|
247
248
|
}
|
|
248
249
|
|
|
249
250
|
const ANCHOR_LINE_RE = /(?:^|\s)(?:[A-Za-z]:[\\/][^:\n]+|\.{0,2}[\\/][^:\n]+|src[\\/][^:\n]+|[\w.-]+[\\/][^:\n]+):\d+\b/;
|
|
251
|
+
const ANCHOR_PATH_CAPTURE_RE = /(?:^|\s)((?:[A-Za-z]:[\\/][^:\n]+|\.{0,2}[\\/][^:\n]+|src[\\/][^:\n]+|[\w.-]+[\\/][^:\n]+)):\d+\b/;
|
|
250
252
|
const FAILED_RE = /\b(?:EXPLORATION_FAILED|exploration failed|no credible (?:anchor|location)|no relevant (?:anchor|location)|not found|could(?: not|n't) find)\b/i;
|
|
251
253
|
|
|
252
254
|
function normalizeExplorerLine(line) {
|
|
@@ -260,7 +262,16 @@ function normalizeExplorerLine(line) {
|
|
|
260
262
|
.trim();
|
|
261
263
|
}
|
|
262
264
|
|
|
263
|
-
|
|
265
|
+
// Anchor existence filter: a locator answer citing a file that does not exist
|
|
266
|
+
// is a hallucination — drop the line. Only enforced when cwd is known.
|
|
267
|
+
function anchorLineExists(line, cwd) {
|
|
268
|
+
const m = line.match(ANCHOR_PATH_CAPTURE_RE);
|
|
269
|
+
if (!m) return true;
|
|
270
|
+
const p = m[1].trim();
|
|
271
|
+
try { return existsSync(isAbsolute(p) ? p : resolve(cwd, p)); } catch { return true; }
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function cleanExplorerText(text, cwd = null) {
|
|
264
275
|
const raw = String(text || '').trim();
|
|
265
276
|
if (!raw) return '';
|
|
266
277
|
const anchors = [];
|
|
@@ -270,7 +281,12 @@ function cleanExplorerText(text) {
|
|
|
270
281
|
if (/^EXPLORATION_FAILED\b/i.test(line)) return 'EXPLORATION_FAILED';
|
|
271
282
|
if (ANCHOR_LINE_RE.test(line)) anchors.push(line);
|
|
272
283
|
}
|
|
273
|
-
if (anchors.length)
|
|
284
|
+
if (anchors.length) {
|
|
285
|
+
const real = cwd ? anchors.filter((l) => anchorLineExists(l, cwd)) : anchors;
|
|
286
|
+
// All anchors pointed at nonexistent paths: fail harmlessly instead of
|
|
287
|
+
// forwarding hallucinated locations.
|
|
288
|
+
return real.length ? real.join('\n') : 'EXPLORATION_FAILED';
|
|
289
|
+
}
|
|
274
290
|
if (FAILED_RE.test(raw)) return 'EXPLORATION_FAILED';
|
|
275
291
|
return raw;
|
|
276
292
|
}
|
|
@@ -311,10 +327,15 @@ async function runExploreSync(args = {}, ctx = {}) {
|
|
|
311
327
|
const presetName = (route && typeof route === 'object')
|
|
312
328
|
? `${clean(route.provider)}/${clean(route.model)}`
|
|
313
329
|
: (route || '');
|
|
330
|
+
// Explorer is a one-shot locator (one grep+code_graph turn, answer, stop —
|
|
331
|
+
// rules/agent/30-explorer.md). Pin a low hard cap so a drifting explorer
|
|
332
|
+
// cannot run an 11-call research loop; 3 leaves room for one lookup turn,
|
|
333
|
+
// one recovery turn, and the answer.
|
|
314
334
|
const llm = makeAgentDispatch({
|
|
315
335
|
agent: 'explorer',
|
|
316
336
|
cwd: resolvedCwd,
|
|
317
337
|
brief: true,
|
|
338
|
+
maxLoopIterations: 3,
|
|
318
339
|
parentSessionId: ctx.callerSessionId || null,
|
|
319
340
|
clientHostPid: ctx.clientHostPid || null,
|
|
320
341
|
config,
|
|
@@ -328,8 +349,8 @@ async function runExploreSync(args = {}, ctx = {}) {
|
|
|
328
349
|
const fatal = fatalExploreError(settled);
|
|
329
350
|
if (fatal) return fail(presentErrorText(fatal, { surface: 'explore' }));
|
|
330
351
|
|
|
331
|
-
const merged = mergeSettled(settled, working);
|
|
332
|
-
const allFailed = settled.every((r) => !settledExplorerResult(r).ok);
|
|
352
|
+
const merged = mergeSettled(settled, working, resolvedCwd);
|
|
353
|
+
const allFailed = settled.every((r) => !settledExplorerResult(r, resolvedCwd).ok);
|
|
333
354
|
const out = capNotice + merged;
|
|
334
355
|
return allFailed ? fail(out) : ok(out);
|
|
335
356
|
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { listRegisteredPlugins } from '../plugin-admin.mjs';
|
|
4
|
+
import { NO_MATCHER_EVENTS } from './constants.mjs';
|
|
5
|
+
|
|
6
|
+
export function hookRulesPath(dataDir) {
|
|
7
|
+
if (process.env.MIXDOG_HOOKS_FILE) return resolve(process.env.MIXDOG_HOOKS_FILE);
|
|
8
|
+
return dataDir ? join(dataDir, 'hooks.json') : null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function normalizeRules(raw) {
|
|
12
|
+
if (Array.isArray(raw)) return raw;
|
|
13
|
+
if (Array.isArray(raw?.toolBefore)) return raw.toolBefore;
|
|
14
|
+
if (Array.isArray(raw?.beforeTool)) return raw.beforeTool;
|
|
15
|
+
if (Array.isArray(raw?.hooks?.toolBefore)) return raw.hooks.toolBefore;
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function uniqueHookEntries(entries) {
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
const out = [];
|
|
22
|
+
for (const entry of entries) {
|
|
23
|
+
if (!entry?.path) continue;
|
|
24
|
+
const resolved = resolve(entry.path);
|
|
25
|
+
const key = process.platform === 'win32' ? resolved.toLowerCase() : resolved;
|
|
26
|
+
if (seen.has(key)) continue;
|
|
27
|
+
seen.add(key);
|
|
28
|
+
out.push({ ...entry, path: resolved });
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function cleanHookId(value) {
|
|
34
|
+
return String(value ?? '').trim()
|
|
35
|
+
.toLowerCase()
|
|
36
|
+
.replace(/[^a-z0-9_.-]+/g, '-')
|
|
37
|
+
.replace(/^-+|-+$/g, '');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function pluginHookConfigEntries(dataDir) {
|
|
41
|
+
if (!dataDir) return [];
|
|
42
|
+
let plugins = [];
|
|
43
|
+
try {
|
|
44
|
+
plugins = listRegisteredPlugins({ dataDir });
|
|
45
|
+
} catch {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
const entries = [];
|
|
49
|
+
for (const plugin of plugins || []) {
|
|
50
|
+
const root = String(plugin?.root || '').trim();
|
|
51
|
+
if (!root || !existsSync(root)) continue;
|
|
52
|
+
const id = cleanHookId(plugin.id || plugin.name || plugin.title || root.split(/[\\/]/).pop());
|
|
53
|
+
const pluginData = join(dataDir, 'plugins', 'data', id || 'plugin');
|
|
54
|
+
entries.push({
|
|
55
|
+
path: join(root, 'hooks', 'hooks.json'),
|
|
56
|
+
pluginRoot: root,
|
|
57
|
+
pluginData,
|
|
58
|
+
sourceType: 'plugin',
|
|
59
|
+
});
|
|
60
|
+
entries.push({
|
|
61
|
+
path: join(root, '.mixdog', 'hooks.json'),
|
|
62
|
+
pluginRoot: root,
|
|
63
|
+
pluginData,
|
|
64
|
+
sourceType: 'plugin',
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return entries;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function hookConfigEntries(dataDir, cwd) {
|
|
71
|
+
if (process.env.MIXDOG_HOOKS_FILE) {
|
|
72
|
+
return uniqueHookEntries([{ path: process.env.MIXDOG_HOOKS_FILE, sourceType: 'env' }]);
|
|
73
|
+
}
|
|
74
|
+
const projectDir = cwd ? resolve(cwd) : process.cwd();
|
|
75
|
+
return uniqueHookEntries([
|
|
76
|
+
projectDir ? { path: join(projectDir, '.mixdog', 'hooks.json'), sourceType: 'project' } : null,
|
|
77
|
+
projectDir ? { path: join(projectDir, '.mixdog', 'hooks', 'hooks.json'), sourceType: 'project' } : null,
|
|
78
|
+
dataDir ? { path: join(dataDir, 'hooks.json'), sourceType: 'data' } : null,
|
|
79
|
+
dataDir ? { path: join(dataDir, 'hooks', 'hooks.json'), sourceType: 'data' } : null,
|
|
80
|
+
...pluginHookConfigEntries(dataDir),
|
|
81
|
+
]);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function isStandardConfig(parsed) {
|
|
85
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return false;
|
|
86
|
+
const hooks = parsed.hooks;
|
|
87
|
+
if (!hooks || typeof hooks !== 'object' || Array.isArray(hooks)) return false;
|
|
88
|
+
const values = Object.values(hooks);
|
|
89
|
+
if (values.length === 0) return false;
|
|
90
|
+
return values.every((groups) => (
|
|
91
|
+
Array.isArray(groups)
|
|
92
|
+
&& groups.every((g) => g && typeof g === 'object' && Array.isArray(g.hooks))
|
|
93
|
+
));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const SIMPLE_MATCHER_RE = /^[A-Za-z0-9_ ,|]*$/;
|
|
97
|
+
export function matcherFires(matcher, field) {
|
|
98
|
+
if (matcher == null) return true;
|
|
99
|
+
const text = String(matcher).trim();
|
|
100
|
+
if (text === '' || text === '*') return true;
|
|
101
|
+
const value = String(field ?? '');
|
|
102
|
+
if (SIMPLE_MATCHER_RE.test(text)) {
|
|
103
|
+
const items = text.split(/[|,]/).map((s) => s.trim()).filter(Boolean);
|
|
104
|
+
if (items.length === 0) return true;
|
|
105
|
+
return items.includes(value);
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
return new RegExp(text).test(value);
|
|
109
|
+
} catch {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function parseStandardConfig(parsed, source, meta = {}) {
|
|
115
|
+
const events = {};
|
|
116
|
+
const hooks = parsed.hooks || {};
|
|
117
|
+
for (const [eventName, groups] of Object.entries(hooks)) {
|
|
118
|
+
if (!Array.isArray(groups)) continue;
|
|
119
|
+
const cleanGroups = [];
|
|
120
|
+
for (const group of groups) {
|
|
121
|
+
if (!group || typeof group !== 'object') continue;
|
|
122
|
+
const handlers = Array.isArray(group.hooks)
|
|
123
|
+
? group.hooks
|
|
124
|
+
.filter((h) => h && typeof h === 'object' && h.type)
|
|
125
|
+
.map((h) => ({
|
|
126
|
+
...h,
|
|
127
|
+
_source: source,
|
|
128
|
+
...(meta.pluginRoot ? { _pluginRoot: meta.pluginRoot } : {}),
|
|
129
|
+
...(meta.pluginData ? { _pluginData: meta.pluginData } : {}),
|
|
130
|
+
}))
|
|
131
|
+
: [];
|
|
132
|
+
if (handlers.length === 0) continue;
|
|
133
|
+
cleanGroups.push({ matcher: group.matcher, hooks: handlers, _source: source });
|
|
134
|
+
}
|
|
135
|
+
if (cleanGroups.length > 0) events[eventName] = cleanGroups;
|
|
136
|
+
}
|
|
137
|
+
return events;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function mergeEvents(target, source) {
|
|
141
|
+
for (const [eventName, groups] of Object.entries(source || {})) {
|
|
142
|
+
if (!Array.isArray(target[eventName])) target[eventName] = [];
|
|
143
|
+
target[eventName].push(...groups);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function buildEventPayload(eventName, input = {}) {
|
|
148
|
+
const payload = {
|
|
149
|
+
session_id: input.sessionId ?? input.session_id ?? null,
|
|
150
|
+
cwd: input.cwd ?? null,
|
|
151
|
+
hook_event_name: eventName,
|
|
152
|
+
};
|
|
153
|
+
if (input.transcriptPath != null || input.transcript_path != null) {
|
|
154
|
+
payload.transcript_path = input.transcriptPath ?? input.transcript_path;
|
|
155
|
+
}
|
|
156
|
+
if (input.permissionMode != null || input.permission_mode != null) {
|
|
157
|
+
payload.permission_mode = input.permissionMode ?? input.permission_mode;
|
|
158
|
+
}
|
|
159
|
+
if (input.effort != null) payload.effort = input.effort;
|
|
160
|
+
const toolName = input.name ?? input.tool_name;
|
|
161
|
+
if (toolName != null) payload.tool_name = toolName;
|
|
162
|
+
const toolInput = input.args ?? input.tool_input;
|
|
163
|
+
if (toolInput != null) payload.tool_input = toolInput;
|
|
164
|
+
if (input.toolCallId != null || input.tool_use_id != null) {
|
|
165
|
+
payload.tool_use_id = input.toolCallId ?? input.tool_use_id;
|
|
166
|
+
}
|
|
167
|
+
if (input.toolResponse != null || input.tool_response != null || input.result != null) {
|
|
168
|
+
payload.tool_response = input.toolResponse ?? input.tool_response ?? input.result;
|
|
169
|
+
}
|
|
170
|
+
for (const key of [
|
|
171
|
+
'prompt',
|
|
172
|
+
'source',
|
|
173
|
+
'model',
|
|
174
|
+
'session_title',
|
|
175
|
+
'message',
|
|
176
|
+
'notification_type',
|
|
177
|
+
'trigger',
|
|
178
|
+
'load_reason',
|
|
179
|
+
'file_path',
|
|
180
|
+
'memory_type',
|
|
181
|
+
'command_name',
|
|
182
|
+
'command_args',
|
|
183
|
+
'command_source',
|
|
184
|
+
'expansion_type',
|
|
185
|
+
'stop_reason',
|
|
186
|
+
'error_type',
|
|
187
|
+
'agent_type',
|
|
188
|
+
]) {
|
|
189
|
+
if (input[key] != null) payload[key] = input[key];
|
|
190
|
+
}
|
|
191
|
+
return payload;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function matchFieldFor(eventName, payload) {
|
|
195
|
+
if (NO_MATCHER_EVENTS.has(eventName)) return null;
|
|
196
|
+
if (eventName === 'SessionStart') return payload.source ?? '';
|
|
197
|
+
if (eventName === 'Setup') return payload.trigger ?? '';
|
|
198
|
+
if (eventName === 'SessionEnd') return payload.reason ?? '';
|
|
199
|
+
if (eventName === 'Notification') return payload.notification_type ?? payload.type ?? '';
|
|
200
|
+
if (eventName === 'SubagentStart' || eventName === 'SubagentStop') return payload.agent_type ?? '';
|
|
201
|
+
if (eventName === 'PreCompact' || eventName === 'PostCompact') return payload.trigger ?? '';
|
|
202
|
+
if (eventName === 'ConfigChange') return payload.source ?? '';
|
|
203
|
+
if (eventName === 'InstructionsLoaded') return payload.load_reason ?? '';
|
|
204
|
+
if (eventName === 'UserPromptExpansion') return payload.command_name ?? '';
|
|
205
|
+
if (eventName === 'StopFailure') return payload.error_type ?? '';
|
|
206
|
+
return payload.tool_name ?? '';
|
|
207
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export const DEFAULT_EVENTS = Object.freeze([
|
|
2
|
+
'runtime:start',
|
|
3
|
+
'session:create',
|
|
4
|
+
'turn:start',
|
|
5
|
+
'turn:end',
|
|
6
|
+
'turn:error',
|
|
7
|
+
'tool:planned',
|
|
8
|
+
'tool:before',
|
|
9
|
+
'tool:ask',
|
|
10
|
+
'tool:deny',
|
|
11
|
+
'tool:modify',
|
|
12
|
+
'hook:error',
|
|
13
|
+
'SessionStart',
|
|
14
|
+
'UserPromptSubmit',
|
|
15
|
+
'PreToolUse',
|
|
16
|
+
'PostToolUse',
|
|
17
|
+
'Stop',
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
export const DEFAULT_COMMAND_TIMEOUT_S = 600;
|
|
21
|
+
export const USER_PROMPT_TIMEOUT_S = 30;
|
|
22
|
+
export const MESSAGE_DISPLAY_TIMEOUT_S = 10;
|
|
23
|
+
export const DEFAULT_PROMPT_TIMEOUT_S = 30;
|
|
24
|
+
export const DEFAULT_AGENT_TIMEOUT_S = 60;
|
|
25
|
+
export const MAX_OUTPUT_CHARS = 10_000;
|
|
26
|
+
export const MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
27
|
+
|
|
28
|
+
export const TOOL_IF_EVENTS = new Set([
|
|
29
|
+
'PreToolUse',
|
|
30
|
+
'PostToolUse',
|
|
31
|
+
'PostToolUseFailure',
|
|
32
|
+
'PermissionRequest',
|
|
33
|
+
'PermissionDenied',
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
export const NO_MATCHER_EVENTS = new Set([
|
|
37
|
+
'UserPromptSubmit',
|
|
38
|
+
'PostToolBatch',
|
|
39
|
+
'Stop',
|
|
40
|
+
'TeammateIdle',
|
|
41
|
+
'TaskCreated',
|
|
42
|
+
'TaskCompleted',
|
|
43
|
+
'WorktreeCreate',
|
|
44
|
+
'WorktreeRemove',
|
|
45
|
+
'CwdChanged',
|
|
46
|
+
'MessageDisplay',
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
export const EXIT2_BLOCK_EVENTS = new Set([
|
|
50
|
+
'PreToolUse',
|
|
51
|
+
'PermissionRequest',
|
|
52
|
+
'UserPromptSubmit',
|
|
53
|
+
'UserPromptExpansion',
|
|
54
|
+
'Stop',
|
|
55
|
+
'SubagentStop',
|
|
56
|
+
'TeammateIdle',
|
|
57
|
+
'TaskCreated',
|
|
58
|
+
'TaskCompleted',
|
|
59
|
+
'ConfigChange',
|
|
60
|
+
'PostToolBatch',
|
|
61
|
+
'PreCompact',
|
|
62
|
+
'Elicitation',
|
|
63
|
+
'ElicitationResult',
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
export const TOP_LEVEL_DECISION_EVENTS = new Set([
|
|
67
|
+
'UserPromptSubmit',
|
|
68
|
+
'UserPromptExpansion',
|
|
69
|
+
'PostToolUse',
|
|
70
|
+
'PostToolUseFailure',
|
|
71
|
+
'PostToolBatch',
|
|
72
|
+
'Stop',
|
|
73
|
+
'SubagentStop',
|
|
74
|
+
'ConfigChange',
|
|
75
|
+
'PreCompact',
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
export const PLAIN_STDOUT_CONTEXT_EVENTS = new Set([
|
|
79
|
+
'SessionStart',
|
|
80
|
+
'UserPromptSubmit',
|
|
81
|
+
'UserPromptExpansion',
|
|
82
|
+
]);
|
|
83
|
+
|
|
84
|
+
export const SUPPORTED_HANDLER_TYPES = new Set(['command', 'http', 'mcp_tool', 'prompt']);
|
|
85
|
+
|
|
86
|
+
export function limitText(text) {
|
|
87
|
+
const value = String(text || '');
|
|
88
|
+
if (value.length <= MAX_OUTPUT_CHARS) return value;
|
|
89
|
+
return `${value.slice(0, MAX_OUTPUT_CHARS)}\n... [hook output truncated; original ${value.length} chars]`;
|
|
90
|
+
}
|