mixdog 1.4.0 → 1.4.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.
Files changed (493) hide show
  1. package/package.json +3 -2
  2. package/scripts/build-shipped-history.mjs +115 -33
  3. package/scripts/check-voice-runtime-inputs.mjs +25 -0
  4. package/scripts/gate-local.mjs +183 -63
  5. package/scripts/latest-guard.mjs +21 -9
  6. package/scripts/lib/gate-scheduler.mjs +138 -32
  7. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  8. package/scripts/lib/isolated-test-env.mjs +10 -5
  9. package/scripts/lib/run-node-tests.mjs +91 -66
  10. package/scripts/lib/scoped-temp.d.mts +16 -0
  11. package/scripts/lib/scoped-temp.mjs +124 -0
  12. package/scripts/lib/stale-temp.mjs +44 -0
  13. package/scripts/lib/test-failure-records.mjs +14 -1
  14. package/scripts/lib/test-failure-summary.mjs +16 -4
  15. package/scripts/lib/test-spawn-ledger.mjs +12 -3
  16. package/scripts/post-release-check.mjs +1 -6
  17. package/scripts/pptx-kit-index.mjs +17 -5
  18. package/scripts/suite-health.mjs +115 -24
  19. package/scripts/test-data-dir.mjs +10 -7
  20. package/scripts/test.mjs +9 -14
  21. package/src/agents/advisor/AGENT.md +4 -4
  22. package/src/agents/advisor/agent.json +1 -1
  23. package/src/agents/explore/AGENT.md +22 -0
  24. package/src/agents/explore/agent.json +6 -0
  25. package/src/app.mjs +4 -0
  26. package/src/cli.mjs +7 -0
  27. package/src/defaults/agents.json +7 -0
  28. package/src/defaults/shipped-history.json +23 -2
  29. package/src/defaults/skills/browser-use/SKILL.md +10 -5
  30. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  31. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  32. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  33. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  34. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  35. package/src/defaults/skills/computer-use/SKILL.md +16 -4
  36. package/src/defaults/skills/goal-management/SKILL.md +1 -1
  37. package/src/defaults/skills/setup/references/actions.md +12 -6
  38. package/src/defaults/skills/setup/references/surfaces.md +2 -2
  39. package/src/defaults/skills/setup-guide/SKILL.md +5 -2
  40. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  41. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  42. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  43. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  44. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  45. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  46. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  47. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  48. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  49. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  50. package/src/defaults/skills/visualize/SKILL.md +6 -2
  51. package/src/lib/rules-builder.cjs +35 -42
  52. package/src/output-styles/common.md +2 -2
  53. package/src/output-styles/simple.md +1 -1
  54. package/src/rules/agent/AGENT.md +5 -4
  55. package/src/rules/lead/LEAD.md +12 -7
  56. package/src/rules/shared/10-tool-workflow.md +3 -1
  57. package/src/rules/shared/20-research.md +3 -6
  58. package/src/rules/shared/40-editing.md +1 -0
  59. package/src/rules/shared/45-destructive.md +0 -2
  60. package/src/rules/shared/50-execution.md +2 -0
  61. package/src/rules/shared/60-verification.md +10 -9
  62. package/src/rules/shared/70-delivery.md +8 -9
  63. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  64. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -1
  65. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +156 -24
  66. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -0
  67. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
  69. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  70. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +8 -8
  71. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +5 -26
  72. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +3 -1
  73. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  74. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +122 -12
  75. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -3
  76. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +13 -2
  77. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +152 -58
  78. package/src/runtime/agent/orchestrator/mcp/client.mjs +51 -18
  79. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +88 -54
  80. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +42 -26
  81. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +54 -8
  82. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +37 -31
  84. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
  85. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
  86. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
  87. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
  89. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
  90. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -3
  91. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +6 -0
  92. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
  93. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  94. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  95. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
  97. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/providers/cursor.mjs +3 -0
  99. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  100. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  101. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  102. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  103. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  104. package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
  105. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  106. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  107. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +248 -41
  108. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
  109. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
  110. package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
  111. package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
  112. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  113. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  114. package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
  115. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  116. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  117. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  118. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  119. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
  120. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
  121. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
  127. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
  128. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
  129. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
  130. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
  131. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
  132. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
  133. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +160 -31
  134. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +22 -12
  135. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
  136. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +49 -22
  137. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  138. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  139. package/src/runtime/agent/orchestrator/providers/registry.mjs +45 -2
  140. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  141. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  142. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  143. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +567 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +41 -13
  145. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  146. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -6
  147. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +7 -3
  148. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  149. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -1
  150. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +14 -5
  151. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  152. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
  153. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  154. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  155. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
  156. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +102 -12
  157. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  158. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
  159. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
  160. package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
  161. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +160 -36
  162. package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
  163. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +164 -23
  164. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +139 -19
  165. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
  166. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
  167. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +100 -22
  168. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  169. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -6
  170. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +33 -3
  171. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +9 -2
  172. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
  174. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +14 -0
  175. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +13 -1
  176. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +23 -4
  177. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +2 -0
  178. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  179. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +39 -21
  180. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  181. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +50 -28
  182. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
  183. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
  184. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +2 -2
  185. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +1 -0
  186. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +2 -1
  187. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +30 -13
  188. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +63 -6
  189. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +7 -0
  190. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  191. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +35 -13
  192. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +24 -14
  193. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  194. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  195. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +10 -6
  196. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
  197. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +3 -0
  198. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +56 -29
  199. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  200. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +11 -5
  201. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +5 -1
  202. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +30 -7
  203. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
  204. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
  206. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
  207. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +37 -8
  208. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +252 -39
  209. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  210. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +164 -4
  211. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  212. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +61 -2
  213. package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
  214. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  215. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
  216. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
  217. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
  218. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -20
  219. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
  220. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +67 -31
  221. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +25 -13
  222. package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
  223. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  224. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
  225. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
  226. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
  227. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
  228. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
  229. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
  230. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  231. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +96 -20
  232. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  233. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
  234. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
  235. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  236. package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
  237. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  238. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  239. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +103 -13
  240. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  241. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  242. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  243. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +34 -10
  244. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +28 -4
  245. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  246. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -2
  247. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  248. package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
  249. package/src/runtime/channels/lib/whisper-port.mjs +29 -11
  250. package/src/runtime/channels/lib/whisper-server.mjs +10 -1
  251. package/src/runtime/computer-bridge/action-schema.mjs +2 -2
  252. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  253. package/src/runtime/computer-bridge/error-recovery.mjs +5 -4
  254. package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
  255. package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
  256. package/src/runtime/connectors/connector-accounts-mcp.mjs +236 -103
  257. package/src/runtime/connectors/gmail-app-password.mjs +3 -3
  258. package/src/runtime/explore/explorer.mjs +93 -0
  259. package/src/runtime/explore/tool-defs.mjs +35 -0
  260. package/src/runtime/explore/tool.mjs +123 -0
  261. package/src/runtime/local-provider/server-process.mjs +2 -1
  262. package/src/runtime/media/adapters/gemini-video.mjs +4 -1
  263. package/src/runtime/media/adapters/xai-media.mjs +2 -1
  264. package/src/runtime/memory/index.mjs +4 -0
  265. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  266. package/src/runtime/memory/lib/embedding-worker.mjs +10 -3
  267. package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
  268. package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
  269. package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
  270. package/src/runtime/office/design/design-art-direction.mjs +29 -27
  271. package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
  272. package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
  273. package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
  274. package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
  275. package/src/runtime/office/quality/assurance-structure-docx.mjs +4 -2
  276. package/src/runtime/office/quality/design-review.mjs +1 -5
  277. package/src/runtime/office/quality/document-brief.mjs +1 -5
  278. package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
  279. package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
  280. package/src/runtime/shared/agent-route-config.mjs +17 -2
  281. package/src/runtime/shared/atomic-file.mjs +103 -2
  282. package/src/runtime/shared/background-tasks.mjs +15 -6
  283. package/src/runtime/shared/bot-owned-work.mjs +56 -0
  284. package/src/runtime/shared/connector-accounts.mjs +5 -5
  285. package/src/runtime/shared/connector-catalog.d.mts +11 -4
  286. package/src/runtime/shared/connector-catalog.mjs +60 -52
  287. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  288. package/src/runtime/shared/defaults-separation.mjs +1 -4
  289. package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
  290. package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
  291. package/src/runtime/shared/file-has-data.mjs +26 -2
  292. package/src/runtime/shared/file-lock.mjs +13 -15
  293. package/src/runtime/shared/git-launch.d.mts +9 -0
  294. package/src/runtime/shared/git-launch.mjs +213 -0
  295. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  296. package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
  297. package/src/runtime/shared/handoff-artifacts.mjs +18 -8
  298. package/src/runtime/shared/idle-auto-clear-gate.mjs +29 -7
  299. package/src/runtime/shared/llm/cost.mjs +11 -2
  300. package/src/runtime/shared/llm/http-agent.mjs +313 -29
  301. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  302. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  303. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  304. package/src/runtime/shared/llm/system-proxy.mjs +452 -0
  305. package/src/runtime/shared/loopback-listener.mjs +25 -2
  306. package/src/runtime/shared/model-route-chain.d.mts +7 -2
  307. package/src/runtime/shared/model-route-chain.mjs +22 -4
  308. package/src/runtime/shared/open-url.mjs +10 -0
  309. package/src/runtime/shared/provider-accounts.mjs +52 -2
  310. package/src/runtime/shared/session-activity-signal.mjs +14 -0
  311. package/src/runtime/shared/session-scratch.mjs +37 -0
  312. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  313. package/src/runtime/shared/staged-update.mjs +47 -2
  314. package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
  315. package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
  316. package/src/runtime/shared/tool-result-summary.mjs +1 -1
  317. package/src/runtime/shared/tool-surface.mjs +113 -36
  318. package/src/runtime/shared/tool-work-units.mjs +6 -0
  319. package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
  320. package/src/runtime/shared/turn-worktree-snapshot.mjs +414 -54
  321. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  322. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  323. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  324. package/src/runtime/shared/worktrees/branch-management.mjs +9 -3
  325. package/src/runtime/shared/worktrees/contract.mjs +4 -1
  326. package/src/runtime/shared/worktrees/git.mjs +72 -0
  327. package/src/runtime/shared/worktrees/manager.mjs +285 -168
  328. package/src/runtime/shared/worktrees/test-support.mjs +6 -10
  329. package/src/runtime/tidy/install.mjs +95 -15
  330. package/src/runtime/tidy/languages.mjs +17 -15
  331. package/src/runtime/tidy/process.mjs +7 -4
  332. package/src/runtime/tidy/resolve.mjs +19 -16
  333. package/src/runtime/tidy/runners/biome.mjs +3 -3
  334. package/src/runtime/tidy/tool.mjs +1 -1
  335. package/src/runtime/tidy/worktree.mjs +10 -6
  336. package/src/runtime/visualize-bridge/client.mjs +6 -1
  337. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  338. package/src/runtime/web-search/index.mjs +1 -1
  339. package/src/session-runtime/agent-home-delivery.mjs +41 -0
  340. package/src/session-runtime/agent-task-sessions.mjs +458 -312
  341. package/src/session-runtime/agent-tool-routing.mjs +8 -41
  342. package/src/session-runtime/boot/tools.mjs +7 -1
  343. package/src/session-runtime/bot-status.mjs +107 -101
  344. package/src/session-runtime/bot-target.mjs +38 -0
  345. package/src/session-runtime/channel-config-api.mjs +6 -1
  346. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  347. package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
  348. package/src/session-runtime/conversation-import/discovery.mjs +401 -36
  349. package/src/session-runtime/conversation-import/service.mjs +35 -8
  350. package/src/session-runtime/handoff-attachments.mjs +82 -31
  351. package/src/session-runtime/held-requests.mjs +3 -1
  352. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +12 -13
  353. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +1 -0
  354. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -0
  355. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  356. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
  357. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +145 -112
  358. package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
  359. package/src/session-runtime/lifecycle/session-catalog.mjs +9 -1
  360. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -1
  361. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  362. package/src/session-runtime/mcp-glue/server-catalog.mjs +16 -10
  363. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  364. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  365. package/src/session-runtime/model-route/set-route.mjs +11 -2
  366. package/src/session-runtime/provider-auth/login.mjs +2 -2
  367. package/src/session-runtime/provider-catalog-cache.mjs +82 -36
  368. package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
  369. package/src/session-runtime/provider-models.mjs +4 -2
  370. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  371. package/src/session-runtime/resource-mcp-connector-accounts.mjs +44 -31
  372. package/src/session-runtime/resource-mcp-secrets.mjs +28 -11
  373. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  374. package/src/session-runtime/resource-recall-api.mjs +6 -1
  375. package/src/session-runtime/runtime-feature-gates.mjs +5 -1
  376. package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
  377. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
  378. package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
  379. package/src/session-runtime/services/agent-tool/render.mjs +71 -17
  380. package/src/session-runtime/services/agent-tool/send-flow.mjs +10 -2
  381. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  382. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
  383. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +6 -2
  384. package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
  385. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  386. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  387. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  388. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  389. package/src/session-runtime/services/plugin-admin.mjs +10 -6
  390. package/src/session-runtime/services/provider-admin.mjs +283 -11
  391. package/src/session-runtime/session-turn-api.mjs +2 -0
  392. package/src/session-runtime/settings-builtin-tools-api.mjs +4 -1
  393. package/src/session-runtime/settings-system-api.mjs +1 -1
  394. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  395. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  396. package/src/session-runtime/setup-tool/executor.mjs +6 -2
  397. package/src/session-runtime/setup-tool/tool-defs.mjs +2 -1
  398. package/src/session-runtime/tool-policy/policy-stage.mjs +1 -0
  399. package/src/session-runtime/turn/agent-ops.mjs +23 -0
  400. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +49 -11
  401. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
  402. package/src/session-runtime/workflow-agents-api/agent-route.mjs +25 -5
  403. package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
  404. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  405. package/src/session-runtime/workspace/session-view.mjs +149 -0
  406. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  407. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  408. package/src/session-runtime/workspace/transitions.mjs +108 -1041
  409. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  410. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  411. package/src/session-runtime/workspace/worktree-maintenance.mjs +80 -0
  412. package/src/session-runtime/workspace/worktree-setup.mjs +85 -0
  413. package/src/session-runtime/workspace/worktree-tool.mjs +73 -56
  414. package/src/standalone/daemon-desktop-runtime.mjs +2 -0
  415. package/src/standalone/daemon-session-control.mjs +169 -138
  416. package/src/standalone/daemon.mjs +7 -0
  417. package/src/standalone/desktop-service-registry.mjs +9 -0
  418. package/src/standalone/local-session-runtime.mjs +5 -1
  419. package/src/standalone/session-client/daemon-unavailable.mjs +3 -0
  420. package/src/standalone/session-client.mjs +5 -1
  421. package/src/standalone/session-frame-stream.mjs +83 -11
  422. package/src/standalone/session-protocol.mjs +4 -0
  423. package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
  424. package/src/standalone/session-service/agent-tree.mjs +45 -9
  425. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  426. package/src/standalone/session-service/session-calls/session-action.mjs +10 -3
  427. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  428. package/src/standalone/session-service/stored-reader.mjs +127 -40
  429. package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
  430. package/src/tui/App.jsx +154 -164
  431. package/src/tui/app/app-view/floating-panel.jsx +10 -4
  432. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  433. package/src/tui/app/clipboard.mjs +21 -10
  434. package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
  435. package/src/tui/app/model-picker/route-selection.mjs +5 -6
  436. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  437. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  438. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  439. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  440. package/src/tui/app/provider-setup/oauth-actions.mjs +58 -21
  441. package/src/tui/app/provider-setup/provider-items.mjs +8 -2
  442. package/src/tui/app/provider-setup-picker.mjs +29 -18
  443. package/src/tui/app/shell-layout/row-budgets.mjs +12 -10
  444. package/src/tui/app/slash-commands.mjs +1 -0
  445. package/src/tui/app/slash-dispatch/session-commands.mjs +46 -0
  446. package/src/tui/app/slash-dispatch.mjs +1 -1
  447. package/src/tui/app/use-btw-panel.mjs +29 -0
  448. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  449. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  450. package/src/tui/app/use-mouse-input.mjs +11 -0
  451. package/src/tui/app/use-onboarding-start.mjs +8 -3
  452. package/src/tui/app/use-panel-transition.mjs +10 -1
  453. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  454. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  455. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  456. package/src/tui/app/use-prompt-queue-history.mjs +3 -2
  457. package/src/tui/app/use-selection-focus.mjs +11 -2
  458. package/src/tui/app/use-selection-geometry.mjs +18 -9
  459. package/src/tui/app/use-selection-paint.mjs +4 -4
  460. package/src/tui/app/use-selection-stitch.mjs +3 -3
  461. package/src/tui/app/use-slash-palette.mjs +62 -0
  462. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  463. package/src/tui/app/use-transcript-activity.mjs +47 -32
  464. package/src/tui/app/use-transcript-follow.mjs +12 -4
  465. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  466. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  467. package/src/tui/app/use-transcript-window/geometry.mjs +19 -5
  468. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  469. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  470. package/src/tui/app/use-transcript-window.mjs +21 -11
  471. package/src/tui/app/use-tui-ready.mjs +18 -0
  472. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  473. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  474. package/src/tui/components/Picker.jsx +27 -3
  475. package/src/tui/components/QuestionPanel.jsx +13 -4
  476. package/src/tui/components/SignInUrl.jsx +68 -0
  477. package/src/tui/components/TextEntryPanel.jsx +76 -46
  478. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  479. package/src/tui/dist/index.mjs +1963 -1361
  480. package/src/tui/session/goal-turn-state.mjs +6 -2
  481. package/src/tui/session/session-api/controls.mjs +4 -0
  482. package/src/tui/session/session-api/extensions.mjs +8 -0
  483. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  484. package/src/tui/session/session-api/intake.mjs +2 -0
  485. package/src/tui/session/session-api/integrations.mjs +2 -2
  486. package/src/tui/session/session-api/routes-agent-definitions.mjs +1 -0
  487. package/src/tui/session/session-api/settings.mjs +2 -2
  488. package/src/tui/session/session-flow/queue/take-entries.mjs +11 -0
  489. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  490. package/src/tui/session/transcript-spill.mjs +92 -4
  491. package/src/tui/session/transcript-store.mjs +2 -0
  492. package/src/ui/statusline-agents.mjs +1 -3
  493. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
@@ -8,8 +8,10 @@
8
8
  * loop each read stretched to seconds. This worker runs exactly that pipeline
9
9
  * (stat → read → stat, digest, readTopLevelLifecycleRecord →
10
10
  * projectStoredTranscript with no turn checkpoint) and hands back the
11
- * digest and the same projection value; only the finished window crosses
12
- * back.
11
+ * digest and one slice of the session's display history: the history itself
12
+ * is built once per content and kept here with its base, and only the window
13
+ * or page a request names (`slice`: `{ limit, skip }`) crosses back, with its
14
+ * serialized size measured here.
13
15
  *
14
16
  * Inside the worker, one projection base (recovery, prepared session and
15
17
  * whole-transcript context gauge) per session content is shared by every
@@ -60,8 +62,14 @@ function clientFor(sessionId) {
60
62
  * the full file stamp the bytes provably came from, or null. Rejects when the
61
63
  * worker cannot answer; callers then run the pipeline on their own thread.
62
64
  */
63
- export function projectStoredTranscriptOffThread({ sessionId, recordPath, itemLimit, known = null }) {
64
- return clientFor(sessionId)({ sessionId, recordPath, itemLimit, known });
65
+ export function projectStoredTranscriptOffThread({
66
+ sessionId,
67
+ recordPath,
68
+ known = null,
69
+ fingerprint = '',
70
+ slice = null,
71
+ }) {
72
+ return clientFor(sessionId)({ sessionId, recordPath, known, fingerprint, slice });
65
73
  }
66
74
 
67
75
  /** Whether the projection worker of `sessionId` is attached (a request now
@@ -321,15 +329,108 @@ async function buildBase(sessionId, text, previousMessages, timing) {
321
329
 
322
330
  const baseBuilds = createBaseBuilds({ build: buildBase });
323
331
 
324
- async function project({ sessionId, recordPath, itemLimit, known }) {
332
+ // Serialized bytes of the display histories this worker keeps for slicing:
333
+ // one larger than the per-session bound is rebuilt per request instead, and
334
+ // the oldest go once all of them exceed the worker's bound. The worker's idle
335
+ // exit releases every one.
336
+ // Measured: a history is about as large as its record (74 MB record: 75 MB
337
+ // history) and a page of a retained one costs ~0.2 s, a rebuilt one ~1 s. 96
338
+ // MB keeps the largest sessions seen (~78 MB records) smooth; 128 MB holds
339
+ // one of those beside a few ordinary ones.
340
+ export const WORKER_HISTORY_SESSION_MAX_BYTES = 96 * 1024 * 1024;
341
+ export const WORKER_HISTORY_MAX_BYTES = 128 * 1024 * 1024;
342
+
343
+ /**
344
+ * The display histories one worker retains (`{ value, rowBytes, bytes }`,
345
+ * keyed by session, Map order LRU) within `sessionMaxBytes` each and
346
+ * `maxBytes` together. A history of other content (`owner`, the record
347
+ * content it was built from, and its sidecar fingerprint) is never served.
348
+ */
349
+ export function createHistoryRetention({
350
+ sessionMaxBytes = WORKER_HISTORY_SESSION_MAX_BYTES,
351
+ maxBytes = WORKER_HISTORY_MAX_BYTES,
352
+ } = {}) {
353
+ const histories = new Map();
354
+ let retainedBytes = 0;
355
+ const drop = (sessionId) => {
356
+ const entry = histories.get(sessionId);
357
+ if (!entry) return;
358
+ histories.delete(sessionId);
359
+ retainedBytes -= entry.history.bytes;
360
+ };
361
+ return {
362
+ get(sessionId, owner, fingerprint) {
363
+ const entry = histories.get(sessionId);
364
+ if (!entry || entry.owner !== owner || entry.fingerprint !== fingerprint) return null;
365
+ histories.delete(sessionId);
366
+ histories.set(sessionId, entry);
367
+ return entry.history;
368
+ },
369
+ /** Keeps `history` when it fits; whether it was kept. */
370
+ retain(sessionId, owner, fingerprint, history) {
371
+ drop(sessionId);
372
+ if (history.bytes > sessionMaxBytes) return false;
373
+ histories.set(sessionId, { owner, fingerprint, history });
374
+ retainedBytes += history.bytes;
375
+ while (retainedBytes > maxBytes && histories.size > 1) drop(histories.keys().next().value);
376
+ return true;
377
+ },
378
+ forget: drop,
379
+ stats: () => ({ histories: histories.size, retainedBytes }),
380
+ };
381
+ }
382
+
383
+ const historyRetention = createHistoryRetention();
384
+ /** sessionId -> { owner, fingerprint, promise }: histories being built. */
385
+ const historyBuilds = new Map();
386
+
387
+ /** The display history of `built` (one base) under sidecar `fingerprint`,
388
+ * with each row's serialized bytes: retained, joined while another request
389
+ * builds it, or built now. */
390
+ async function displayHistory(sessionId, built, content, fingerprint, projection) {
391
+ const retained = historyRetention.get(sessionId, content, fingerprint);
392
+ if (retained) return { history: retained, historyBuilt: false };
393
+ const pending = historyBuilds.get(sessionId);
394
+ if (pending && pending.owner === content && pending.fingerprint === fingerprint) {
395
+ return { history: await pending.promise, historyBuilt: false };
396
+ }
397
+ const promise = (async () => {
398
+ const value = await projection.windowStoredTranscript(sessionId, built.base, {
399
+ history: true,
400
+ includeMessages: false,
401
+ });
402
+ const rowBytes = new Float64Array(value.items.length);
403
+ let bytes = 0;
404
+ for (let index = 0; index < value.items.length; index += 1) {
405
+ rowBytes[index] = Buffer.byteLength(JSON.stringify(value.items[index] ?? null));
406
+ bytes += rowBytes[index];
407
+ }
408
+ return { value, rowBytes, bytes };
409
+ })();
410
+ const record = { owner: content, fingerprint, promise };
411
+ historyBuilds.set(sessionId, record);
412
+ try {
413
+ const history = await promise;
414
+ if (historyBuilds.get(sessionId) === record) historyRetention.retain(sessionId, content, fingerprint, history);
415
+ return { history, historyBuilt: true };
416
+ } finally {
417
+ if (historyBuilds.get(sessionId) === record) historyBuilds.delete(sessionId);
418
+ }
419
+ }
420
+
421
+ async function project({ sessionId, recordPath, known, fingerprint = '', slice = null }) {
325
422
  const importStartedAt = performance.now();
326
- const [{ statSessionStamp, sameSessionStamp }, { readTextFile, PROBE_PRESENT }, { transcriptTextHash }, projection] =
327
- await Promise.all([
328
- import('./store/canonical-reader.mjs'),
329
- import('./store/fs-probe.mjs'),
330
- import('./store-transcript-cache.mjs'),
331
- import('./store-transcript-projection.mjs'),
332
- ]);
423
+ const [
424
+ { statSessionStamp, sameSessionStamp },
425
+ { readTextFile, PROBE_PRESENT },
426
+ { transcriptTextHash, historyStampOf },
427
+ projection,
428
+ ] = await Promise.all([
429
+ import('./store/canonical-reader.mjs'),
430
+ import('./store/fs-probe.mjs'),
431
+ import('./store-transcript-cache.mjs'),
432
+ import('./store-transcript-projection.mjs'),
433
+ ]);
333
434
  const timing = { importMs: performance.now() - importStartedAt };
334
435
  const observe = () => {
335
436
  try {
@@ -374,12 +475,32 @@ async function project({ sessionId, recordPath, itemLimit, known }) {
374
475
  const built = await pending;
375
476
  if (built === RESTART_READ) continue;
376
477
  if (built.unreadable) return { ...digest, unreadable: true };
377
- const value = await projection.windowStoredTranscript(sessionId, built.base, {
378
- itemLimit,
379
- includeMessages: false,
380
- });
478
+ // The whole display history stays here (within its budgets); only the
479
+ // requested slice crosses back.
480
+ const { history, historyBuilt } = await displayHistory(
481
+ sessionId,
482
+ built,
483
+ `${digest.textHash}:${digest.textChars}`,
484
+ fingerprint,
485
+ projection
486
+ );
487
+ const request = slice || {};
488
+ const historyStamp = historyStampOf(sessionId, digest.textHash, digest.textChars, fingerprint, request.epoch);
489
+ const proven = Boolean(request.held) && request.baseHistory === historyStamp;
490
+ const value = projection.storedHistorySlice(
491
+ history.value,
492
+ { ...request, proven },
493
+ {
494
+ digestOf: request.held && !proven ? await projection.heldRowsDigester() : null,
495
+ rowBytes: (index) => history.rowBytes[index],
496
+ }
497
+ );
498
+ const { windowStamp } = value;
499
+ delete value.windowStamp;
500
+ value.projectionStamp = `${historyStamp}/${windowStamp}`;
501
+ const bytes = Buffer.byteLength(JSON.stringify(value));
381
502
  timing.projectMs = performance.now() - projectStartedAt;
382
- return { ...digest, value, lifecycle: built.lifecycle };
503
+ return { ...digest, value, bytes, historyBuilt, lifecycle: built.lifecycle };
383
504
  } finally {
384
505
  if (!submitted) baseBuilds.release(ticket);
385
506
  }
@@ -388,6 +509,9 @@ async function project({ sessionId, recordPath, itemLimit, known }) {
388
509
 
389
510
  if (!isMainThread && workerData?.kind === WORKER_KIND) {
390
511
  serveWorkerRequests((payload) => {
391
- return payload?.forget ? baseBuilds.forget(payload.forget) : project(payload);
512
+ if (!payload?.forget) return project(payload);
513
+ historyRetention.forget(payload.forget);
514
+ historyBuilds.delete(payload.forget);
515
+ return baseBuilds.forget(payload.forget);
392
516
  });
393
517
  }
@@ -44,6 +44,7 @@ import {
44
44
  } from '../../../../shared/transcript-metadata.mjs';
45
45
  import { routineTriggerField } from '../../../../shared/routine-trigger.mjs';
46
46
  import { isImportedMessage } from '../imported-message.mjs';
47
+ import { toolRunLine } from '../conversation-import/turns.mjs';
47
48
  import { isContextAckMessage } from '../compact/user-message-kind.mjs';
48
49
  import { isRoutineResultMessage, routineResultNotice } from '../routine-result.mjs';
49
50
  import { heldRequestNotice, isHeldRequestMessage } from '../human-gate/held-message.mjs';
@@ -140,7 +141,64 @@ function restoredContentText(message) {
140
141
  return typeof message?.content === 'string' ? message.content : toolResultText(message?.content);
141
142
  }
142
143
 
144
+ // The runs of tool use an imported assistant message recorded (conversation-import
145
+ // turns.mjs), kept only where the text still holds exactly their canonical line.
146
+ function importedToolRuns(message) {
147
+ const runs = message?.meta?.importedToolRuns;
148
+ if (!isImportedMessage(message) || typeof message.content !== 'string' || !Array.isArray(runs)) return [];
149
+ let cursor = 0;
150
+ return runs.filter((run) => {
151
+ const valid =
152
+ Number.isInteger(run?.start) &&
153
+ Number.isInteger(run?.end) &&
154
+ run.start >= cursor &&
155
+ run.end > run.start &&
156
+ run.end <= message.content.length &&
157
+ Array.isArray(run.tools) &&
158
+ run.tools.length > 0 &&
159
+ run.tools.every((tool) => typeof tool?.name === 'string' && Number.isInteger(tool.count) && tool.count > 0) &&
160
+ message.content.slice(run.start, run.end) === toolRunLine(run.tools);
161
+ if (valid) cursor = run.end;
162
+ return valid;
163
+ });
164
+ }
165
+
166
+ // An imported reply with tool use: its text around each run as assistant rows,
167
+ // each run as tool rows (one per tool, counted). The calls' results were never
168
+ // imported; the `imported` mark lets the row say so.
169
+ function restoredImportedAssistantItems(message, runs, nextId) {
170
+ const { completion: _completion, ...metadata } = restoredTranscriptMetadata(message);
171
+ const at = Number(message?.meta?.transcript?.at);
172
+ const items = [];
173
+ const pushText = (raw) => {
174
+ const text = raw.trim();
175
+ if (text) items.push({ kind: 'assistant', id: nextId(), text, ...metadata });
176
+ };
177
+ let cursor = 0;
178
+ for (const run of runs) {
179
+ pushText(message.content.slice(cursor, run.start));
180
+ for (const { name, count } of run.tools) {
181
+ if (isTranscriptHiddenControlToolName(name)) continue;
182
+ items.push({
183
+ kind: 'tool',
184
+ id: nextId(),
185
+ name,
186
+ imported: true,
187
+ expanded: false,
188
+ count,
189
+ completedCount: count,
190
+ ...(Number.isFinite(at) ? { at, startedAt: at, completedAt: at } : {}),
191
+ });
192
+ }
193
+ cursor = run.end;
194
+ }
195
+ pushText(message.content.slice(cursor));
196
+ return items;
197
+ }
198
+
143
199
  function restoredAssistantTranscriptItems(message, nextId) {
200
+ const runs = importedToolRuns(message);
201
+ if (runs.length) return restoredImportedAssistantItems(message, runs, nextId);
144
202
  const text = restoredContentText(message).trim();
145
203
  if (!text) return [];
146
204
  const { completion, ...metadata } = restoredTranscriptMetadata(message);
@@ -339,7 +397,7 @@ function mergeRestoredToolItems(items) {
339
397
  // Result-dependent hiding (built-in skill loads) resolves here, after
340
398
  // every role:'tool' result has been attached to its restored call.
341
399
  if (item?.kind === 'tool' && isTranscriptHiddenToolItem(item)) continue;
342
- const mergeable = item?.kind === 'tool' && item.aggregate !== true;
400
+ const mergeable = item?.kind === 'tool' && item.aggregate !== true && item.imported !== true;
343
401
  if (!mergeable) {
344
402
  flushRun();
345
403
  merged.push(item);
@@ -379,7 +437,8 @@ function restoredMessageItemUpperBound(message) {
379
437
  const calls = restoredMessageToolCalls(message);
380
438
  const content = message?.content;
381
439
  const hasContent = typeof content === 'string' ? content.length > 0 : Array.isArray(content) && content.length > 0;
382
- return Number(hasContent) + completionCount + calls.length + boundaries;
440
+ const importedRows = importedToolRuns(message).reduce((total, run) => total + run.tools.length + 1, 0);
441
+ return Number(hasContent) + completionCount + calls.length + importedRows + boundaries;
383
442
  }
384
443
 
385
444
  // One restored tool card for a parsed notification/completion envelope.
@@ -259,6 +259,29 @@ export const PROVIDER_WS_SEMANTIC_IDLE_TIMEOUT_MS = resolveTimeoutMs(
259
259
  { minMs: 10_000, maxMs: Math.max(10_000, STALL_ABORT_MS - STALL_TICK_MS) }
260
260
  );
261
261
 
262
+ // First-OUTPUT window of one provider stream: from the stream opening until
263
+ // the model's first semantic output (reasoning, text or a tool call). Server
264
+ // metadata and keepalives (response.created / in_progress, an empty reasoning
265
+ // or message item, a role-only chunk, pings) neither end this phase nor start
266
+ // the semantic-idle clock, so a reasoning model may think silently past the
267
+ // idle window (issue #244: 4–6 min on a large post-tool-result prompt). The
268
+ // window sits one tick under the stall abort — the same ceiling the semantic
269
+ // idle uses — so the provider still fails (and may retry or fall back) before
270
+ // the agent watchdog's first-output deadline (600s default), and it is never
271
+ // shorter than the idle window it replaces. Not separately tunable: it
272
+ // follows STALL_TIMEOUT_S.
273
+ export const PROVIDER_FIRST_OUTPUT_TIMEOUT_MS = Math.max(
274
+ PROVIDER_SEMANTIC_IDLE_TIMEOUT_MS,
275
+ PROVIDER_WS_SEMANTIC_IDLE_TIMEOUT_MS,
276
+ STALL_ABORT_MS - STALL_TICK_MS
277
+ );
278
+
279
+ /** The first-output window of a stream whose semantic idle is `idleMs`: a
280
+ * longer idle window (a provider profile) is never cut short by it. */
281
+ export function providerFirstOutputTimeoutMs(idleMs) {
282
+ return Math.max(idleMs, PROVIDER_FIRST_OUTPUT_TIMEOUT_MS);
283
+ }
284
+
262
285
  /**
263
286
  * The longest a provider's own first-byte handling may legitimately run
264
287
  * before it gives up, over every attempt it permits: `windowMs(n)` is the wait
@@ -25,6 +25,9 @@ import {
25
25
  * when the last observed survivor exits, `cancel` terminates them. */
26
26
  function trackSurvivingDescendants(handle, { command, cwd, options, startedAtMs } = {}) {
27
27
  if (!handle?.taskId) return null;
28
+ // Once cancelled, every observation pass terminates survivors that ignored
29
+ // the first kill, so a retry is not needed to finish the job.
30
+ let cancelled = false;
28
31
  try {
29
32
  const task = startBackgroundTask({
30
33
  taskId: handle.taskId,
@@ -36,10 +39,10 @@ function trackSurvivingDescendants(handle, { command, cwd, options, startedAtMs
36
39
  meta: { task_id: handle.taskId, stdout: null, stderr: null, cwd, timeoutMs: 0 },
37
40
  resultType: 'shell_task_result',
38
41
  run: async () => {
39
- await waitForShellDescendants(handle);
42
+ await waitForShellDescendants(handle, { sweep: () => cancelled });
40
43
  // The folder reservation the finished command handed to its
41
44
  // survivors ends with the last of them.
42
- releaseShellJobWorkspace(handle.taskId);
45
+ await releaseShellJobWorkspace(handle.taskId);
43
46
  return {
44
47
  task_id: handle.taskId,
45
48
  status: 'completed',
@@ -48,6 +51,7 @@ function trackSurvivingDescendants(handle, { command, cwd, options, startedAtMs
48
51
  },
49
52
  // The kill's own re-observation is what `task cancel` reports.
50
53
  cancel: () => {
54
+ cancelled = true;
51
55
  task.cancelOutcome = killShellDescendants(handle);
52
56
  },
53
57
  });
@@ -28,9 +28,9 @@ function prefixPowerShellUtf8(command) {
28
28
  // UTF-8 prefix (+ optional filter-tee rescue), or a POSIX bash/zsh snapshot
29
29
  // wrapper delivered through the environment. Returns `{ failure }` when the
30
30
  // snapshot wrapper cannot be built.
31
- export async function planShellInvocation({ command, resolvedSpec, cwd }) {
31
+ export async function planShellInvocation({ command, resolvedSpec, cwd, sessionId = null }) {
32
32
  const { shell, shellArg, shellArgs, shellType } = resolvedSpec;
33
- const spawnEnv = buildShellSpawnEnv(cwd);
33
+ const spawnEnv = buildShellSpawnEnv(cwd, process.env, sessionId);
34
34
  const plan = {
35
35
  execShell: shell,
36
36
  execShellArg: shellArg,
@@ -1,3 +1,4 @@
1
+ import { applySessionScratchEnv } from '../../../../../shared/session-scratch.mjs';
1
2
  import { withSkillLauncherPath } from '../../../../../shared/skill-script-runtime.mjs';
2
3
  import {
3
4
  applyShellEgressPolicy,
@@ -6,7 +7,8 @@ import {
6
7
  scrubRuntimeRootVars,
7
8
  } from '../../env-scrub.mjs';
8
9
 
9
- export function buildShellSpawnEnv(cwd, baseEnv = process.env) {
10
+ // `sessionId` points TEMP/TMP/TMPDIR at that session's scratch directory.
11
+ export function buildShellSpawnEnv(cwd, baseEnv = process.env, sessionId = null) {
10
12
  const spawnEnv = {
11
13
  ...baseEnv,
12
14
  LANG: 'C.UTF-8',
@@ -24,5 +26,5 @@ export function buildShellSpawnEnv(cwd, baseEnv = process.env) {
24
26
  // `mixdog-skill-node` (a skill's ${MIXDOG_SKILL_NODE}) resolves in every
25
27
  // model shell; only this env gets the entry, never the daemon's own.
26
28
  withSkillLauncherPath(spawnEnv);
27
- return spawnEnv;
29
+ return applySessionScratchEnv(spawnEnv, sessionId);
28
30
  }
@@ -116,7 +116,12 @@ export async function executeBashTool(args, workDir, options = {}) {
116
116
  // A queued run, or a foreground tree that may outlive its result, settles later.
117
117
  let runSettled = null;
118
118
  try {
119
- const invocation = await planShellInvocation({ command, resolvedSpec, cwd: bashWorkDir });
119
+ const invocation = await planShellInvocation({
120
+ command,
121
+ resolvedSpec,
122
+ cwd: bashWorkDir,
123
+ sessionId: options?.callerSessionId || options?.sessionId || null,
124
+ });
120
125
  if (invocation.failure) return invocation.failure;
121
126
  combinedAbort = combineAbortSignals(await sessionAbortSignal(options?.sessionId), options?.abortSignal || null);
122
127
  const startedAtMs = Date.now();
@@ -5,7 +5,7 @@
5
5
  // behavior, argument shapes, and the usage boundaries that only apply to that
6
6
  // tool; cross-tool policy lives in rules/shared/*.md.
7
7
  // Platform-specific command syntax belongs next to the command argument.
8
- import { GIT_TOOL_DEF } from './git-command-tool.mjs';
8
+ import { GIT_AGENT_TOOL_DEF, GIT_TOOL_DEF } from './git-command-tool.mjs';
9
9
  import { PUBLIC_PATH_BATCH_LIMIT, PUBLIC_READ_WINDOW_MAX } from './arg-guard.mjs';
10
10
  import { GITHUB_TOOL_DEF } from '../../../../github/tool.mjs';
11
11
  import { envFlag } from '../../../../shared/env.mjs';
@@ -50,7 +50,7 @@ export function buildShellRoutingRules(kind = _defaultShellKind) {
50
50
  function buildShellDescription(kind) {
51
51
  const run = _shellBackgroundDisabled
52
52
  ? 'Commands run in the foreground until completion.'
53
- : `Holds ${_holdS}s; then, or on input/task notification, backgrounds with task_id (command keeps running). Completion is automatic; never poll, and never sleep/poll-loop inside the shell (background:true or wait_ms instead; for an external job, background a command that exits when it ends). Result needed now: task wait. Known-long finite run: wait_ms up to ${SHELL_HOLD_MAX_MS}. Independent long runs, servers/watchers: background:true; cancel them when done.`;
53
+ : `Holds ${_holdS}s; then, or on input/task notification, backgrounds with task_id (command keeps running). Completion is automatic; never poll, and never sleep/poll-loop inside the shell (background:true or wait_ms instead; for an external job, background a command that exits when it ends). Result needed now: task wait. Independent long runs: background:true; cancel when done.`;
54
54
  return `Run programs, builds, tests and computation. ${buildShellRoutingRules(kind)} ${run}`;
55
55
  }
56
56
 
@@ -88,6 +88,10 @@ export function bindShellKind(tool, kind) {
88
88
  return bound;
89
89
  }
90
90
 
91
+ function taskTimeoutDescription(defaultMs) {
92
+ return `Wait ceiling in ms; else current output at the ceiling. Default ${defaultMs}; clamped to ${TASK_WAIT_TIMEOUT_MIN_MS}-${TASK_WAIT_TIMEOUT_MAX_MS}.`;
93
+ }
94
+
91
95
  export const BUILTIN_TOOLS = [
92
96
  {
93
97
  name: 'read',
@@ -101,7 +105,7 @@ export const BUILTIN_TOOLS = [
101
105
  compressible: false,
102
106
  },
103
107
  description:
104
- "Read file windows or images. One call per read stage: {file_path, offset, limit} entries for every located site (≤10 files per call), never a whole large file. Content in context is never read again. Missing paths are reported, never replaced. Directories: list. Binaries: bounded hex. Rows carry no line numbers; `[lines a-b]` gives each block's range. Never count rows: before writing a line number, copy it from grep, code_graph or git diff output; otherwise cite path and symbol.",
108
+ "Read file windows or images. One call per read stage: {file_path, offset, limit} entries for every located site, never a whole large file. Content in context is never read again. Missing paths are reported, never replaced. Directories: list. Binaries: bounded hex. Rows carry no line numbers; `[lines a-b]` gives each block's range. Never count rows: before writing a line number, copy it from grep, code_graph or git diff output; otherwise cite path and symbol.",
105
109
  inputSchema: {
106
110
  type: 'object',
107
111
  properties: {
@@ -129,8 +133,7 @@ export const BUILTIN_TOOLS = [
129
133
  },
130
134
  },
131
135
  ],
132
- description:
133
- 'Path(s) or {file_path, offset, limit} entries; overlapping windows of one file merge. A glob fans out to ≤10 newest files, 25 lines each.',
136
+ description: 'Overlapping windows of one file merge. A glob fans out to ≤10 newest files.',
134
137
  },
135
138
  offset: {
136
139
  type: 'integer',
@@ -167,14 +170,11 @@ export const BUILTIN_TOOLS = [
167
170
  compressibleLossless: true,
168
171
  },
169
172
  description:
170
- 'Replace exact text in one file. old_string must match once unless replace_all is true. Every non-overlapping edit of the stage in one response, using existing text, not text another edit creates; many files → one edit per file, all in that response. Widened replacements keep intervening lines verbatim.',
173
+ 'Replace exact text in one file. old_string must match once unless replace_all is true. Every non-overlapping edit of the stage in one response, using existing text, not text another edit creates; many files → one edit per file. Widened replacements keep intervening lines verbatim.',
171
174
  inputSchema: {
172
175
  type: 'object',
173
176
  properties: {
174
- file_path: {
175
- type: 'string',
176
- description: 'Path to the file to modify.',
177
- },
177
+ file_path: { type: 'string' },
178
178
  old_string: {
179
179
  type: 'string',
180
180
  description:
@@ -187,7 +187,7 @@ export const BUILTIN_TOOLS = [
187
187
  replace_all: {
188
188
  type: 'boolean',
189
189
  default: false,
190
- description: 'Replace all occurrences of old_string; default false.',
190
+ description: 'Replace all occurrences of old_string.',
191
191
  },
192
192
  },
193
193
  required: ['file_path', 'old_string', 'new_string'],
@@ -254,7 +254,7 @@ export const BUILTIN_TOOLS = [
254
254
  openWorldHint: false,
255
255
  },
256
256
  description:
257
- 'Manage shell tasks. Completion is delivered automatically; wait only when you need the result now, never poll with read. wait returns when the task finishes, or when new user input or any task notification arrives (the task keeps running). read/wait return new output, prioritizing the tail on completion. output:tail re-reads recent output without advancing the cursor; use read on the log path for omitted content.',
257
+ 'Manage shell tasks. Completion is delivered automatically; wait only when you need the result now, never poll with read. wait returns when the task finishes, or when new user input or any task notification arrives (the task keeps running). read/wait return new output, prioritizing the tail on completion. Use read on the log path for omitted content.',
258
258
  inputSchema: {
259
259
  type: 'object',
260
260
  properties: {
@@ -267,13 +267,13 @@ export const BUILTIN_TOOLS = [
267
267
  timeout_ms: {
268
268
  type: 'integer',
269
269
  minimum: 0,
270
- description: `Wait ceiling in ms; returns on completion, new user input or a task notification, else current output at the ceiling. Default ${TASK_WAIT_TIMEOUT_DEFAULT_MS} (agents ${AGENT_TASK_WAIT_DEFAULT_MS}); clamped to ${TASK_WAIT_TIMEOUT_MIN_MS}-${TASK_WAIT_TIMEOUT_MAX_MS}.`,
270
+ description: taskTimeoutDescription(TASK_WAIT_TIMEOUT_DEFAULT_MS),
271
271
  },
272
272
  output: {
273
273
  type: 'string',
274
274
  enum: ['new', 'tail'],
275
275
  description:
276
- 'read/wait only. Default new; tail replays recent output after an interruption or context loss. Up to 8 KiB per stream while running, 12 KiB on completion or replay; original logs are preserved.',
276
+ 'read/wait only. Default new; tail re-reads recent output without advancing the cursor, after an interruption or context loss. Up to 8 KiB per stream while running, 12 KiB on completion or replay; original logs are preserved.',
277
277
  },
278
278
  },
279
279
  required: ['action'],
@@ -324,7 +324,7 @@ export const BUILTIN_TOOLS = [
324
324
  description:
325
325
  'Requested results; default 250; 0 unlimited. Context output caps at 40 blocks; continue via the returned offset.',
326
326
  },
327
- offset: { type: 'integer', minimum: 0, description: 'Result offset.' },
327
+ offset: { type: 'integer', minimum: 0 },
328
328
  context: {
329
329
  type: 'integer',
330
330
  minimum: 0,
@@ -356,7 +356,7 @@ export const BUILTIN_TOOLS = [
356
356
  compressible: true,
357
357
  },
358
358
  description:
359
- 'Wildcard file-path lookup under a known directory; directories never match. Omit path for the current Project; no preliminary listing. Unknown base: find first with a known path fragment. Gitignored paths need include_noise:true.',
359
+ 'Wildcard file-path lookup under a known directory; directories never match. No preliminary listing. Unknown base: find first with a known path fragment.',
360
360
  inputSchema: {
361
361
  type: 'object',
362
362
  properties: {
@@ -374,7 +374,7 @@ export const BUILTIN_TOOLS = [
374
374
  description: 'mtime default (newest first); natural = raw walk order, cheaper on huge trees.',
375
375
  },
376
376
  limit: { type: 'integer', minimum: 0, description: 'Max entries; default 100; 0 unlimited.' },
377
- offset: { type: 'integer', minimum: 0, description: 'Entry offset.' },
377
+ offset: { type: 'integer', minimum: 0 },
378
378
  include_noise: {
379
379
  type: 'boolean',
380
380
  description: 'Also search gitignored trees.',
@@ -404,7 +404,7 @@ export const BUILTIN_TOOLS = [
404
404
  type: 'string',
405
405
  minLength: 1,
406
406
  pattern: '\\S',
407
- description: 'Non-empty filename/path fragment; space-separated fragments AND-match within one path.',
407
+ description: 'Filename/path fragment; space-separated fragments AND-match within one path.',
408
408
  },
409
409
  path: { type: 'string', description: 'Base directory; omit for the current Project.' },
410
410
  limit: { type: 'integer', minimum: 0, description: 'Max paths; default 25; 0 unlimited.' },
@@ -445,10 +445,36 @@ export const BUILTIN_TOOLS = [
445
445
  maximum: 100,
446
446
  description: 'Max entries; default 100; 0 = no page cap (absolute cap still applies).',
447
447
  },
448
- offset: { type: 'integer', minimum: 0, description: 'Entry offset.' },
448
+ offset: { type: 'integer', minimum: 0 },
449
449
  },
450
- required: [],
451
450
  additionalProperties: false,
452
451
  },
453
452
  },
454
453
  ];
454
+
455
+ // What a delegated agent's session sees of the tools whose text differs from
456
+ // the Lead's: git (worktree operations are Lead-only) and task (the agent wait
457
+ // default). Keyed by the shared definition, so a rebuilt list binds once.
458
+ const _taskTool = BUILTIN_TOOLS.find((tool) => tool.name === 'task');
459
+ const _agentTaskTool = {
460
+ ..._taskTool,
461
+ inputSchema: {
462
+ ..._taskTool.inputSchema,
463
+ properties: {
464
+ ..._taskTool.inputSchema.properties,
465
+ timeout_ms: {
466
+ ..._taskTool.inputSchema.properties.timeout_ms,
467
+ description: taskTimeoutDescription(AGENT_TASK_WAIT_DEFAULT_MS),
468
+ },
469
+ },
470
+ },
471
+ };
472
+ const _agentToolVariants = new Map([
473
+ [GIT_TOOL_DEF, GIT_AGENT_TOOL_DEF],
474
+ [_taskTool, _agentTaskTool],
475
+ ]);
476
+
477
+ /** The agent-session variant of `tool`, or `tool` itself when it has none. */
478
+ export function bindAgentOwner(tool) {
479
+ return _agentToolVariants.get(tool) ?? tool;
480
+ }
@@ -324,7 +324,13 @@ export function rawContentCacheSet(fullPath, stat, rawBuf, now = Date.now()) {
324
324
  if (!canPublishReadCache(fullPath)) return;
325
325
  if (!fullPath || !Buffer.isBuffer(rawBuf)) return;
326
326
  const version = fileVersion(stat);
327
- if (!version || !canCacheReadFile(version) || rawBuf.length !== version.size || rawBuf.length > RAW_CONTENT_CACHE_MAX_BYTES) return;
327
+ if (
328
+ !version ||
329
+ !canCacheReadFile(version) ||
330
+ rawBuf.length !== version.size ||
331
+ rawBuf.length > RAW_CONTENT_CACHE_MAX_BYTES
332
+ )
333
+ return;
328
334
  const key = canonicalCachePath(fullPath);
329
335
  rawContentCacheDelete(key);
330
336
  RAW_CONTENT_CACHE.set(key, {