mixdog 0.9.2 → 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 +8 -3
- package/scripts/anthropic-maxtokens-test.mjs +119 -0
- 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/build-tui.mjs +13 -1
- package/scripts/explore-bench.mjs +124 -0
- package/scripts/freevar-smoke.mjs +95 -0
- package/scripts/hook-bus-test.mjs +191 -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/path-suffix-test.mjs +57 -0
- package/scripts/provider-toolcall-test.mjs +7 -3
- package/scripts/recall-bench.mjs +207 -0
- 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 +30 -67
- package/scripts/tui-render-smoke.mjs +90 -0
- package/scripts/webhook-smoke.mjs +208 -0
- package/src/agents/debugger/AGENT.md +5 -2
- package/src/agents/heavy-worker/AGENT.md +21 -11
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +3 -2
- package/src/agents/worker/AGENT.md +21 -11
- package/src/lib/rules-builder.cjs +4 -0
- package/src/mixdog-session-runtime.mjs +933 -3731
- 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/repl.mjs +5 -5
- package/src/rules/agent/00-common.md +2 -0
- package/src/rules/agent/30-explorer.md +8 -11
- package/src/rules/lead/lead-brief.md +12 -0
- package/src/rules/lead/lead-tool.md +2 -9
- package/src/rules/shared/01-tool.md +11 -5
- 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/context/collect.mjs +51 -0
- package/src/runtime/agent/orchestrator/mcp/client.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +63 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +93 -0
- 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 +97 -1343
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +78 -10
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +1 -13
- 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 +44 -1014
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +18 -4
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +32 -0
- 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/oauth-usage.mjs +54 -20
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +19 -12
- 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 +41 -1142
- 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 +303 -2119
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +140 -995
- 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/providers/opencode-go-usage.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +7 -8
- 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-debug.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +274 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +38 -0
- package/src/runtime/agent/orchestrator/session/loop/env.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/loop/hidden-agents.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +47 -0
- 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/steering.mjs +63 -0
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +52 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +218 -0
- package/src/runtime/agent/orchestrator/session/loop/transcript-repair.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +409 -1304
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +230 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +235 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +149 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +155 -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/tool-resolution.mjs +303 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +226 -2114
- 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/stall-policy.mjs +3 -3
- 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 +33 -42
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +241 -0
- package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +42 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +11 -4
- 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 -87
- 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 +78 -304
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +11 -6
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +303 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +43 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +382 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +551 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +295 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +158 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/lang-predicates.mjs +128 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.mjs +66 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +44 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1080 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +81 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +19 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +280 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +347 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +36 -4277
- 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 +1 -23
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +10 -74
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +2 -4
- 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 +241 -894
- package/src/runtime/channels/lib/backend-dispatch.mjs +44 -0
- package/src/runtime/channels/lib/boot-profile.mjs +23 -0
- package/src/runtime/channels/lib/crash-log.mjs +106 -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/index-drop-trace.mjs +72 -0
- package/src/runtime/channels/lib/output-forwarder.mjs +9 -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/telegram-format.mjs +19 -22
- 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/lib/whisper-language.mjs +42 -0
- package/src/runtime/channels/tool-defs.mjs +11 -130
- package/src/runtime/memory/index.mjs +258 -2050
- package/src/runtime/memory/lib/core-memory-store.mjs +351 -1
- 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/cycle-signatures.mjs +34 -0
- package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
- package/src/runtime/memory/lib/http-wire.mjs +57 -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 +72 -837
- 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-scope-filter.mjs +24 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
- package/src/runtime/memory/lib/memory-retrievers.mjs +8 -0
- package/src/runtime/memory/lib/memory.mjs +20 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
- package/src/runtime/memory/lib/promotion-fingerprint.mjs +50 -0
- package/src/runtime/memory/lib/query-handlers.mjs +780 -0
- package/src/runtime/memory/lib/recall-format.mjs +238 -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 +6 -14
- 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/abort-controller.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +26 -1
- package/src/runtime/shared/background-tasks.mjs +2 -3
- package/src/runtime/shared/buffered-appender.mjs +149 -0
- package/src/runtime/shared/launcher-control.mjs +2 -2
- package/src/runtime/shared/task-notification-envelope.mjs +98 -0
- package/src/runtime/shared/tool-execution-contract.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 +52 -2
- package/src/runtime/shared/update-checker.mjs +7 -4
- package/src/session-runtime/config-helpers.mjs +291 -0
- package/src/session-runtime/config-lifecycle.mjs +232 -0
- package/src/session-runtime/cwd-plugins.mjs +226 -0
- package/src/session-runtime/effort.mjs +128 -0
- package/src/session-runtime/fs-utils.mjs +10 -0
- package/src/session-runtime/mcp-glue.mjs +177 -0
- package/src/session-runtime/model-capabilities.mjs +130 -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 +126 -0
- package/src/session-runtime/plugin-mcp.mjs +114 -0
- 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/session-text.mjs +100 -0
- package/src/session-runtime/settings-api.mjs +319 -0
- package/src/session-runtime/statusline-route.mjs +35 -0
- package/src/session-runtime/tool-catalog.mjs +720 -0
- package/src/session-runtime/tool-defs.mjs +84 -0
- package/src/session-runtime/warmup-schedulers.mjs +201 -0
- package/src/session-runtime/workflow.mjs +358 -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 +155 -677
- package/src/standalone/channel-worker.mjs +7 -9
- package/src/standalone/explore-tool.mjs +40 -12
- 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 +110 -746
- package/src/standalone/memory-runtime-proxy.mjs +7 -0
- package/src/standalone/opencode-go-login.mjs +125 -0
- package/src/standalone/provider-admin.mjs +15 -19
- package/src/standalone/usage-dashboard.mjs +3 -1
- package/src/tui/App.jsx +1163 -7571
- 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 +259 -80
- 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 +56 -588
- 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/components/tool-output-format.mjs +2 -2
- package/src/tui/display-width.mjs +20 -3
- package/src/tui/dist/index.mjs +18034 -17188
- package/src/tui/engine/agent-envelope.mjs +296 -0
- package/src/tui/engine/agent-job-feed.mjs +133 -0
- package/src/tui/engine/boot-profile.mjs +21 -0
- package/src/tui/engine/labels.mjs +67 -0
- package/src/tui/engine/notice-text.mjs +112 -0
- package/src/tui/engine/notification-plan.mjs +76 -0
- package/src/tui/engine/queue-helpers.mjs +161 -0
- package/src/tui/engine/render-timing.mjs +17 -0
- package/src/tui/engine/session-stats.mjs +46 -0
- package/src/tui/engine/tool-approval.mjs +94 -0
- package/src/tui/engine/tool-call-fields.mjs +23 -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/tool-result-text.mjs +126 -0
- package/src/tui/engine.mjs +405 -1385
- package/src/tui/figures.mjs +5 -0
- package/src/tui/index.jsx +105 -0
- package/src/tui/input-editing.mjs +60 -10
- package/src/tui/keyboard-protocol.mjs +2 -2
- package/src/tui/lib/voice-recorder.mjs +35 -19
- package/src/tui/markdown/format-token.mjs +11 -9
- package/src/tui/paste-attachments.mjs +38 -0
- package/src/tui/statusline-ansi-bridge.mjs +11 -3
- package/src/tui/theme.mjs +6 -0
- package/src/tui/themes/base.mjs +2 -2
- package/src/tui/themes/kanagawa.mjs +4 -4
- package/src/tui/themes/teal.mjs +4 -5
- package/src/tui/themes/utils.mjs +1 -1
- 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 +77 -462
- package/src/ui/tool-card.mjs +0 -1
- package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
- package/src/workflows/default/WORKFLOW.md +16 -9
- package/src/workflows/sequential/WORKFLOW.md +16 -11
- package/src/workflows/solo/WORKFLOW.md +5 -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/open-config-tool.mjs +0 -26
- package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
- 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/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/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
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Message classification, protected-context splitting, and summary-message
|
|
2
|
+
// construction helpers. Extracted verbatim from compact.mjs
|
|
3
|
+
// (behavior-preserving).
|
|
4
|
+
import { SUMMARY_PREFIX } from './constants.mjs';
|
|
5
|
+
import { sha16, roleCounts } from './text-utils.mjs';
|
|
6
|
+
|
|
7
|
+
export function compactHeader(oldHistory) {
|
|
8
|
+
const encoded = JSON.stringify(oldHistory ?? []);
|
|
9
|
+
return [
|
|
10
|
+
SUMMARY_PREFIX,
|
|
11
|
+
`messages=${oldHistory.length} sha256=${sha16(encoded)} roles=${roleCounts(oldHistory) || 'none'}`,
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function makeSummaryMessage(content) {
|
|
16
|
+
return { role: 'user', content };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// A compact summary message is a synthetic role:'user' message carrying the
|
|
20
|
+
// SUMMARY_PREFIX anchor. It is NOT a real user turn: it must be excluded from
|
|
21
|
+
// real user-turn boundary calculations and treated as merge input, otherwise
|
|
22
|
+
// an old summary can sit in the preserved tail as a live user message,
|
|
23
|
+
// duplicate, or fail to merge across repeated compaction.
|
|
24
|
+
export function isSummaryMessage(m) {
|
|
25
|
+
return m?.role === 'user'
|
|
26
|
+
&& typeof m.content === 'string'
|
|
27
|
+
&& m.content.startsWith(SUMMARY_PREFIX);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function isProtectedContextUserMessage(m) {
|
|
31
|
+
if (m?.role !== 'user' || typeof m.content !== 'string') return false;
|
|
32
|
+
return m.content.trimStart().startsWith('<system-reminder>');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// An injected Skill-body user message (the general newMessages channel carries
|
|
36
|
+
// the full SKILL.md body as a role:'user' message after the Skill tool_result).
|
|
37
|
+
// Like isSummaryMessage / isProtectedContextUserMessage, it is detected by
|
|
38
|
+
// content prefix (the `<skill>` envelope from buildSkillResultEnvelope) so the
|
|
39
|
+
// check survives even if the synthetic `meta` field is dropped during a tail
|
|
40
|
+
// rebuild. It is NOT the human's latest prompt and must be excluded from
|
|
41
|
+
// "latest human request" selection (deriveCurrentRequest /
|
|
42
|
+
// buildRecallFastTrackQuery). The `meta:'skill'` marker is also honoured.
|
|
43
|
+
export function isInjectedSkillBodyMessage(m) {
|
|
44
|
+
if (m?.role !== 'user') return false;
|
|
45
|
+
if (m.meta === 'skill') return true;
|
|
46
|
+
return typeof m.content === 'string' && m.content.trimStart().startsWith('<skill>');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function isProtectedContextAckMessage(m) {
|
|
50
|
+
return m?.role === 'assistant'
|
|
51
|
+
&& typeof m.content === 'string'
|
|
52
|
+
&& m.content.trim() === '.'
|
|
53
|
+
&& !Array.isArray(m.toolCalls);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function splitProtectedContext(messages) {
|
|
57
|
+
const protectedPrefix = [];
|
|
58
|
+
const conversation = [];
|
|
59
|
+
let prefixMode = true;
|
|
60
|
+
let previousWasProtectedContext = false;
|
|
61
|
+
for (const m of messages || []) {
|
|
62
|
+
if (m?.role === 'system') {
|
|
63
|
+
protectedPrefix.push(m);
|
|
64
|
+
previousWasProtectedContext = false;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (prefixMode && isProtectedContextUserMessage(m)) {
|
|
68
|
+
protectedPrefix.push(m);
|
|
69
|
+
previousWasProtectedContext = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (prefixMode && previousWasProtectedContext && isProtectedContextAckMessage(m)) {
|
|
73
|
+
protectedPrefix.push(m);
|
|
74
|
+
previousWasProtectedContext = false;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
prefixMode = false;
|
|
78
|
+
previousWasProtectedContext = false;
|
|
79
|
+
conversation.push(m);
|
|
80
|
+
}
|
|
81
|
+
return { protectedPrefix, conversation };
|
|
82
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
// Semantic-summary schema machinery: required-section anchors, heading
|
|
2
|
+
// matching, schema validation, deterministic repair/backfill, minimal
|
|
3
|
+
// schema-valid scaffold, and section-aware truncation. Extracted verbatim
|
|
4
|
+
// from summary.mjs (behavior-preserving) — summary.mjs re-exports the
|
|
5
|
+
// public entry points so the compact/ facade surface is unchanged.
|
|
6
|
+
import {
|
|
7
|
+
extractText,
|
|
8
|
+
truncateMiddle,
|
|
9
|
+
} from './text-utils.mjs';
|
|
10
|
+
import {
|
|
11
|
+
isProtectedContextUserMessage,
|
|
12
|
+
isInjectedSkillBodyMessage,
|
|
13
|
+
} from './messages.mjs';
|
|
14
|
+
|
|
15
|
+
// Canonical section anchors the semantic summary template (SUMMARY_TEMPLATE)
|
|
16
|
+
// must contain. Used for lightweight schema validation of provider output.
|
|
17
|
+
const REQUIRED_SUMMARY_SECTIONS = Object.freeze([
|
|
18
|
+
'## Goal',
|
|
19
|
+
'## Constraints',
|
|
20
|
+
'## Progress',
|
|
21
|
+
'## Key Decisions',
|
|
22
|
+
'## Next Steps',
|
|
23
|
+
'## Critical Context',
|
|
24
|
+
'## Relevant Files',
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
// Collect actual top-level (`## `, not `### `) heading lines from a summary.
|
|
28
|
+
// Validation is heading-anchor based (not substring includes) so prose or code
|
|
29
|
+
// that merely mentions "## Relevant Files" inside a bullet body cannot satisfy
|
|
30
|
+
// a section anchor.
|
|
31
|
+
function summaryHeadingLines(summary) {
|
|
32
|
+
const out = [];
|
|
33
|
+
let inFence = false;
|
|
34
|
+
for (const rawLine of String(summary || '').split('\n')) {
|
|
35
|
+
const line = rawLine.trim();
|
|
36
|
+
if (/^(?:```|~~~)/.test(line)) { inFence = !inFence; continue; }
|
|
37
|
+
if (inFence) continue;
|
|
38
|
+
if (/^##\s+\S/.test(line) && !/^###\s+/.test(line)) out.push(line);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// An anchor matches a heading when the heading title equals the anchor title or
|
|
44
|
+
// extends it at a word/punctuation boundary. This lets `## Constraints &
|
|
45
|
+
// Preferences` satisfy the `## Constraints` anchor while NOT letting an
|
|
46
|
+
// unrelated `## Goalkeeper` heading satisfy `## Goal`. Requires a real `## `
|
|
47
|
+
// heading line (not a substring buried in prose).
|
|
48
|
+
export function headingMatchesAnchor(heading, anchor) {
|
|
49
|
+
const anchorTitle = anchor.replace(/^##\s+/, '').trim().toLowerCase();
|
|
50
|
+
const headingTitle = heading.replace(/^##\s+/, '').trim().toLowerCase();
|
|
51
|
+
if (headingTitle === anchorTitle) return true;
|
|
52
|
+
if (!headingTitle.startsWith(anchorTitle)) return false;
|
|
53
|
+
// Next char after the anchor title must be a boundary (space or &/punct),
|
|
54
|
+
// not a continuation letter/digit.
|
|
55
|
+
const nextChar = headingTitle.charAt(anchorTitle.length);
|
|
56
|
+
return /[\s&:(-]/.test(nextChar);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function summarySchemaScore(summary) {
|
|
60
|
+
const headings = summaryHeadingLines(summary);
|
|
61
|
+
let hits = 0;
|
|
62
|
+
for (const anchor of REQUIRED_SUMMARY_SECTIONS) {
|
|
63
|
+
if (headings.some((h) => headingMatchesAnchor(h, anchor))) hits += 1;
|
|
64
|
+
}
|
|
65
|
+
return hits;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// A summary is schema-valid only when EVERY required section anchor is present
|
|
69
|
+
// as a real heading. A partial summary (e.g. missing Critical Context /
|
|
70
|
+
// Relevant Files) must be repaired rather than injected unchanged.
|
|
71
|
+
export function summaryIsSchemaValid(summary) {
|
|
72
|
+
if (summarySchemaScore(summary) !== REQUIRED_SUMMARY_SECTIONS.length) return false;
|
|
73
|
+
return !summaryHasUnrecognizedHeadings(summary);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function deriveRelevantFilesBullets(head) {
|
|
77
|
+
const seen = new Set();
|
|
78
|
+
const out = [];
|
|
79
|
+
const fileRe = /(?:[A-Za-z]:[\\/]|\.{1,2}[\\/]|[\w$.-]+[\\/])?[\w$.-]+\.(?:mjs|cjs|js|jsx|ts|tsx|json|md|rs|go|py|java|kt|cs|cpp|c|h|hpp|css|html|yml|yaml|toml|lock|sh|ps1)\b/gi;
|
|
80
|
+
for (const m of Array.isArray(head) ? head : []) {
|
|
81
|
+
const text = extractText(m);
|
|
82
|
+
if (!text) continue;
|
|
83
|
+
let match;
|
|
84
|
+
while ((match = fileRe.exec(text)) && out.length < 8) {
|
|
85
|
+
const file = match[0];
|
|
86
|
+
const key = file.toLowerCase();
|
|
87
|
+
if (seen.has(key)) continue;
|
|
88
|
+
seen.add(key);
|
|
89
|
+
out.push(`- ${file}`);
|
|
90
|
+
}
|
|
91
|
+
if (out.length >= 8) break;
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function deriveCurrentRequest(messages) {
|
|
97
|
+
for (let i = (Array.isArray(messages) ? messages.length : 0) - 1; i >= 0; i -= 1) {
|
|
98
|
+
const m = messages[i];
|
|
99
|
+
if (m?.role === 'user' && !isProtectedContextUserMessage(m) && !isInjectedSkillBodyMessage(m)) {
|
|
100
|
+
const text = truncateMiddle(extractText(m).trim(), 400);
|
|
101
|
+
if (text) return text;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Canonical ordered section headings the structured summary scaffold emits.
|
|
108
|
+
// Each `## ` heading maps to one REQUIRED_SUMMARY_SECTIONS anchor; Progress
|
|
109
|
+
// additionally carries its three `### ` sub-headings.
|
|
110
|
+
const SUMMARY_SECTION_LAYOUT = Object.freeze([
|
|
111
|
+
{ heading: '## Goal', anchor: '## Goal' },
|
|
112
|
+
{ heading: '## Constraints & Preferences', anchor: '## Constraints' },
|
|
113
|
+
{ heading: '## Progress', anchor: '## Progress', sub: ['### Done', '### In Progress', '### Blocked'] },
|
|
114
|
+
{ heading: '## Key Decisions', anchor: '## Key Decisions' },
|
|
115
|
+
{ heading: '## Next Steps', anchor: '## Next Steps' },
|
|
116
|
+
{ heading: '## Critical Context', anchor: '## Critical Context' },
|
|
117
|
+
{ heading: '## Relevant Files', anchor: '## Relevant Files' },
|
|
118
|
+
]);
|
|
119
|
+
|
|
120
|
+
// Split a markdown summary into a map of top-level `## ` heading -> body lines.
|
|
121
|
+
function parseSummarySections(text) {
|
|
122
|
+
const map = new Map();
|
|
123
|
+
let current = null;
|
|
124
|
+
let inFence = false;
|
|
125
|
+
for (const rawLine of String(text || '').split('\n')) {
|
|
126
|
+
const trimmed = rawLine.trim();
|
|
127
|
+
const line = rawLine.replace(/\s+$/, '');
|
|
128
|
+
if (/^(?:```|~~~)/.test(trimmed)) {
|
|
129
|
+
inFence = !inFence;
|
|
130
|
+
if (current) map.get(current).push(line);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (!inFence && /^##\s+/.test(trimmed) && !/^###\s+/.test(trimmed)) {
|
|
134
|
+
current = trimmed;
|
|
135
|
+
if (!map.has(current)) map.set(current, []);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (current) map.get(current).push(line);
|
|
139
|
+
}
|
|
140
|
+
return map;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function summarySectionIsRecognized(heading) {
|
|
144
|
+
for (const section of SUMMARY_SECTION_LAYOUT) {
|
|
145
|
+
if (headingMatchesAnchor(heading, section.anchor)) return true;
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function summaryHasUnrecognizedHeadings(summary) {
|
|
151
|
+
for (const heading of parseSummarySections(summary).keys()) {
|
|
152
|
+
if (!summarySectionIsRecognized(heading)) return true;
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function summaryLinesToBullets(text) {
|
|
158
|
+
return String(text || '')
|
|
159
|
+
.split('\n')
|
|
160
|
+
.map((l) => l.trim())
|
|
161
|
+
.filter(Boolean)
|
|
162
|
+
.map((l) => (l.startsWith('-') ? l : `- ${l}`));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function unrecognizedSummarySectionText(present) {
|
|
166
|
+
const chunks = [];
|
|
167
|
+
for (const [heading, body] of present) {
|
|
168
|
+
if (summarySectionIsRecognized(heading)) continue;
|
|
169
|
+
const lines = [heading];
|
|
170
|
+
for (const line of body || []) {
|
|
171
|
+
const trimmed = String(line).trim();
|
|
172
|
+
if (trimmed) lines.push(line);
|
|
173
|
+
}
|
|
174
|
+
chunks.push(lines.join('\n'));
|
|
175
|
+
}
|
|
176
|
+
return chunks.join('\n\n').trim();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Deterministic schema repair for a non-empty but malformed/partial semantic
|
|
180
|
+
// summary. Preserve every section the provider DID supply (matched by anchor),
|
|
181
|
+
// and scaffold the missing required sections so downstream consumers always
|
|
182
|
+
// receive the full structured anchored shape. Content that lives outside any
|
|
183
|
+
// recognized section is routed into Critical Context so nothing is dropped.
|
|
184
|
+
// Lightly backfill Goal / Relevant Files from the transcript when empty.
|
|
185
|
+
export function repairSemanticSummary(summary, { head = [], tail = [] } = {}) {
|
|
186
|
+
const raw = String(summary || '').trim();
|
|
187
|
+
const present = parseSummarySections(raw);
|
|
188
|
+
// Capture any leading content before the first recognized `## ` heading so
|
|
189
|
+
// an entirely unstructured blob is preserved rather than silently dropped.
|
|
190
|
+
let preamble = '';
|
|
191
|
+
if (raw) {
|
|
192
|
+
const firstHeading = raw.search(/(^|\n)\s*##\s+/);
|
|
193
|
+
preamble = firstHeading === -1 ? raw : raw.slice(0, firstHeading);
|
|
194
|
+
preamble = preamble.trim();
|
|
195
|
+
}
|
|
196
|
+
const orphanText = unrecognizedSummarySectionText(present);
|
|
197
|
+
const extraContextParts = [];
|
|
198
|
+
if (preamble) extraContextParts.push(preamble);
|
|
199
|
+
if (orphanText) extraContextParts.push(orphanText);
|
|
200
|
+
const extraContext = extraContextParts.join('\n\n').trim();
|
|
201
|
+
const bulletize = (lines) => {
|
|
202
|
+
const cleaned = (Array.isArray(lines) ? lines : [])
|
|
203
|
+
.map((l) => String(l).trim())
|
|
204
|
+
.filter(Boolean);
|
|
205
|
+
return cleaned.length ? cleaned : null;
|
|
206
|
+
};
|
|
207
|
+
const findPresent = (anchor) => {
|
|
208
|
+
let found = null;
|
|
209
|
+
for (const [heading, body] of present) {
|
|
210
|
+
if (headingMatchesAnchor(heading, anchor)) {
|
|
211
|
+
if (!found) found = [];
|
|
212
|
+
found.push(...(body || []));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return found;
|
|
216
|
+
};
|
|
217
|
+
const goal = deriveCurrentRequest(tail) || deriveCurrentRequest(head);
|
|
218
|
+
const files = deriveRelevantFilesBullets(head);
|
|
219
|
+
const out = [];
|
|
220
|
+
for (const section of SUMMARY_SECTION_LAYOUT) {
|
|
221
|
+
if (out.length) out.push('');
|
|
222
|
+
out.push(section.heading);
|
|
223
|
+
const body = bulletize(findPresent(section.anchor));
|
|
224
|
+
if (section.sub) {
|
|
225
|
+
// Progress: keep provider sub-bodies when present, else scaffold.
|
|
226
|
+
if (body) {
|
|
227
|
+
out.push(...body);
|
|
228
|
+
} else {
|
|
229
|
+
for (const sub of section.sub) {
|
|
230
|
+
out.push(sub, '- (none)');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (section.anchor === '## Critical Context') {
|
|
236
|
+
const ccLines = [];
|
|
237
|
+
if (body) ccLines.push(...body);
|
|
238
|
+
for (const line of summaryLinesToBullets(extraContext)) {
|
|
239
|
+
if (!ccLines.some((existing) => existing.trim() === line.trim())) ccLines.push(line);
|
|
240
|
+
}
|
|
241
|
+
if (ccLines.some((line) => line.trim() !== '- (none)')) {
|
|
242
|
+
const withoutPlaceholder = ccLines.filter((line) => line.trim() !== '- (none)');
|
|
243
|
+
out.push(...(withoutPlaceholder.length ? withoutPlaceholder : ccLines));
|
|
244
|
+
} else {
|
|
245
|
+
out.push(...(ccLines.length ? ccLines : ['- (none)']));
|
|
246
|
+
}
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (body) {
|
|
250
|
+
out.push(...body);
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
if (section.anchor === '## Goal') {
|
|
254
|
+
out.push(goal ? `- ${goal}` : '- (none)');
|
|
255
|
+
} else if (section.anchor === '## Relevant Files') {
|
|
256
|
+
out.push(...(files.length ? files : ['- (none)']));
|
|
257
|
+
} else {
|
|
258
|
+
out.push('- (none)');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return out.join('\n');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// A headings-only structured summary: every required `## ` (and Progress `### `)
|
|
265
|
+
// anchor present with `- (none)` bodies. This is the minimal schema-valid shape
|
|
266
|
+
// the fitter can fall back to when token pressure cannot hold real section
|
|
267
|
+
// bodies — it still passes summaryIsSchemaValid so the injected message is
|
|
268
|
+
// never partial.
|
|
269
|
+
export function minimalSchemaSummary() {
|
|
270
|
+
const out = [];
|
|
271
|
+
for (const section of SUMMARY_SECTION_LAYOUT) {
|
|
272
|
+
if (out.length) out.push('');
|
|
273
|
+
out.push(section.heading);
|
|
274
|
+
if (section.sub) {
|
|
275
|
+
for (const sub of section.sub) out.push(sub, '- (none)');
|
|
276
|
+
} else {
|
|
277
|
+
out.push('- (none)');
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return out.join('\n');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Section-aware truncation: keep EVERY `## ` heading and Progress `### `
|
|
284
|
+
// sub-heading intact, trimming only section bodies to `perSectionChars`. Unlike
|
|
285
|
+
// a raw text.slice(0, n) this never drops a trailing required section, so the
|
|
286
|
+
// result stays schema-valid (all anchors present) at any budget.
|
|
287
|
+
export function truncateSummaryBySections(summary, perSectionChars) {
|
|
288
|
+
const sections = parseSummarySections(summary);
|
|
289
|
+
const out = [];
|
|
290
|
+
for (const section of SUMMARY_SECTION_LAYOUT) {
|
|
291
|
+
if (out.length) out.push('');
|
|
292
|
+
out.push(section.heading);
|
|
293
|
+
let body = null;
|
|
294
|
+
for (const [heading, lines] of sections) {
|
|
295
|
+
if (headingMatchesAnchor(heading, section.anchor)) {
|
|
296
|
+
if (!body) body = [];
|
|
297
|
+
body.push(...(lines || []));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
const bodyText = (Array.isArray(body) ? body : [])
|
|
301
|
+
.map((l) => String(l).trim())
|
|
302
|
+
.filter(Boolean)
|
|
303
|
+
.join('\n');
|
|
304
|
+
if (!bodyText) {
|
|
305
|
+
if (section.sub) for (const sub of section.sub) out.push(sub, '- (none)');
|
|
306
|
+
else out.push('- (none)');
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
const trimmed = perSectionChars > 0 ? truncateMiddle(bodyText, perSectionChars) : '';
|
|
310
|
+
if (trimmed) out.push(trimmed);
|
|
311
|
+
else if (section.sub) for (const sub of section.sub) out.push(sub, '- (none)');
|
|
312
|
+
else out.push('- (none)');
|
|
313
|
+
}
|
|
314
|
+
return out.join('\n');
|
|
315
|
+
}
|