mixdog 1.1.2 → 1.2.1

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 (424) hide show
  1. package/README.md +8 -5
  2. package/package.json +2 -1
  3. package/scripts/lib/run-node-tests.mjs +9 -0
  4. package/scripts/prune-desktop-runtime.mjs +3 -0
  5. package/scripts/test-direct.mjs +4 -2
  6. package/src/defaults/shipped-history.json +10 -0
  7. package/src/defaults/skills/pptx/SKILL.md +6 -6
  8. package/src/defaults/skills/pptx/references/review.md +6 -4
  9. package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
  10. package/src/defaults/skills/setup/references/actions.md +18 -5
  11. package/src/defaults/skills/visualize/SKILL.md +160 -0
  12. package/src/defaults/skills/visualize/references/craft.md +88 -0
  13. package/src/headless-command.mjs +56 -3
  14. package/src/headless-exec.mjs +17 -1
  15. package/src/help.mjs +2 -0
  16. package/src/rules/shared/60-verification.md +3 -1
  17. package/src/rules/shared/70-delivery.md +4 -2
  18. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  19. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
  20. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
  21. package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
  22. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  23. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
  24. package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
  25. package/src/runtime/agent/orchestrator/config.mjs +19 -5
  26. package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
  27. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
  28. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
  29. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +133 -15
  30. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +55 -8
  31. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +86 -8
  32. package/src/runtime/agent/orchestrator/mcp/client.mjs +474 -164
  33. package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
  34. package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
  35. package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
  36. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +108 -17
  37. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  38. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
  40. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -12
  41. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
  42. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
  43. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
  44. package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
  45. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +444 -0
  46. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
  47. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  48. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
  49. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
  50. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +21 -6
  51. package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
  52. package/src/runtime/agent/orchestrator/providers/gemini.mjs +41 -28
  53. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  54. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  55. package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
  56. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
  57. package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
  58. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
  59. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
  60. package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
  61. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +82 -0
  62. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +556 -0
  63. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
  64. package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
  65. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
  66. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +15 -0
  67. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
  68. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -1
  69. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
  70. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
  71. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +2 -1
  72. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +15 -4
  73. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
  74. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
  75. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
  76. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +4 -4
  77. package/src/runtime/agent/orchestrator/providers/registry.mjs +47 -7
  78. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
  79. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
  80. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -11
  81. package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
  82. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
  83. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
  84. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +278 -84
  85. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
  86. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
  87. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
  88. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -3
  89. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
  90. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
  91. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
  92. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
  93. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +268 -0
  94. package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
  95. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
  96. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
  97. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +24 -13
  98. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
  99. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
  100. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
  101. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
  102. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
  103. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
  104. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
  105. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
  106. package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
  107. package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
  108. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
  109. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
  110. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
  111. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
  112. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
  113. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
  114. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +5 -3
  115. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -4
  116. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +21 -10
  117. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
  118. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
  119. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -3
  120. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +15 -3
  121. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +22 -12
  122. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +9 -2
  123. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +9 -3
  124. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
  125. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
  126. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
  127. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +17 -4
  128. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
  129. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
  130. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
  131. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
  132. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
  133. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
  134. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
  136. package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
  137. package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
  138. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +33 -22
  139. package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
  140. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
  141. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
  142. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
  143. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
  144. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +817 -0
  145. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +36 -0
  146. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +23 -12
  147. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
  148. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +202 -374
  149. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
  150. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
  151. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
  152. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +48 -9
  153. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +161 -0
  154. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
  155. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
  156. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
  157. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
  158. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
  159. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
  160. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
  161. package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
  162. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +203 -33
  163. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
  164. package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
  165. package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
  166. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
  167. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +83 -68
  168. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
  169. package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +20 -3
  170. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
  171. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
  172. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
  173. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
  174. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
  175. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
  176. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
  177. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
  179. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
  180. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
  181. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
  182. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
  183. package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
  184. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
  185. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
  186. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
  187. package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
  188. package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
  189. package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
  190. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
  191. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
  192. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
  193. package/src/runtime/attachments/store.d.mts +3 -0
  194. package/src/runtime/attachments/store.mjs +38 -0
  195. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
  196. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
  197. package/src/runtime/channels/lib/worker-main.mjs +17 -14
  198. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
  199. package/src/runtime/effort-judge/judge-client.mjs +56 -18
  200. package/src/runtime/memory/lib/memory.mjs +1 -1
  201. package/src/runtime/memory/lib/session-ingest.mjs +2 -2
  202. package/src/runtime/shared/atomic-file.mjs +33 -6
  203. package/src/runtime/shared/best-effort-stderr.mjs +8 -0
  204. package/src/runtime/shared/code-graph-state.mjs +12 -0
  205. package/src/runtime/shared/defaults-separation.mjs +2 -0
  206. package/src/runtime/shared/extension-scopes.mjs +5 -3
  207. package/src/runtime/shared/file-lock.mjs +37 -11
  208. package/src/runtime/shared/git-runner-worker.mjs +3 -2
  209. package/src/runtime/shared/git-runner.mjs +4 -3
  210. package/src/runtime/shared/llm/anthropic-effort.mjs +14 -0
  211. package/src/runtime/shared/llm/default-context-window.mjs +6 -0
  212. package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
  213. package/src/runtime/shared/llm/model-catalog.mjs +240 -130
  214. package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
  215. package/src/runtime/shared/llm/provider-catalog-registry.mjs +162 -0
  216. package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
  217. package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
  218. package/src/runtime/shared/model-proxy-mode.mjs +19 -0
  219. package/src/runtime/shared/plugin-manifest.mjs +18 -9
  220. package/src/runtime/shared/pristine-execution-contract.json +9 -2
  221. package/src/runtime/shared/pristine-execution.mjs +28 -4
  222. package/src/runtime/shared/provider-accounts.mjs +125 -21
  223. package/src/runtime/shared/provider-api-key.mjs +33 -1
  224. package/src/runtime/shared/schedule-model-ref.mjs +11 -2
  225. package/src/runtime/shared/session-usage-totals.mjs +19 -0
  226. package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
  227. package/src/runtime/shared/shell-display.mjs +9 -3
  228. package/src/runtime/shared/singleton-owner.mjs +36 -6
  229. package/src/runtime/shared/skill-mentions.d.mts +10 -0
  230. package/src/runtime/shared/skill-mentions.mjs +133 -0
  231. package/src/runtime/shared/skill-script-runtime.mjs +264 -0
  232. package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
  233. package/src/runtime/shared/tool-primitives.mjs +35 -2
  234. package/src/runtime/shared/tool-surface.mjs +7 -0
  235. package/src/runtime/shared/tool-work-units.mjs +14 -0
  236. package/src/runtime/shared/transcript-metadata.mjs +17 -1
  237. package/src/runtime/shared/turn-changes.mjs +791 -0
  238. package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
  239. package/src/runtime/shared/turn-snapshot.mjs +690 -81
  240. package/src/runtime/shared/turn-worktree-snapshot.mjs +185 -15
  241. package/src/runtime/shared/worker-requests.mjs +15 -2
  242. package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
  243. package/src/runtime/shared/worktrees/contract.mjs +551 -0
  244. package/src/runtime/shared/worktrees/disk.mjs +57 -0
  245. package/src/runtime/shared/worktrees/git.mjs +247 -0
  246. package/src/runtime/shared/worktrees/include.mjs +480 -0
  247. package/src/runtime/shared/worktrees/lock.mjs +46 -0
  248. package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
  249. package/src/runtime/shared/worktrees/manager.mjs +1215 -0
  250. package/src/runtime/shared/worktrees/merge.mjs +182 -0
  251. package/src/runtime/shared/worktrees/owner.mjs +46 -0
  252. package/src/runtime/shared/worktrees/paths.mjs +62 -0
  253. package/src/runtime/shared/worktrees/registry.mjs +110 -0
  254. package/src/runtime/shared/worktrees/settings.mjs +84 -0
  255. package/src/runtime/shared/worktrees/slug.mjs +62 -0
  256. package/src/runtime/shared/worktrees/test-support.mjs +96 -0
  257. package/src/runtime/visualize-bridge/client.mjs +181 -0
  258. package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
  259. package/src/session-runtime/automation-agents.mjs +8 -2
  260. package/src/session-runtime/boot/apis.mjs +90 -0
  261. package/src/session-runtime/boot/config.mjs +7 -2
  262. package/src/session-runtime/boot/facade.mjs +21 -0
  263. package/src/session-runtime/boot/infrastructure.mjs +30 -18
  264. package/src/session-runtime/boot/session.mjs +1 -0
  265. package/src/session-runtime/boot/tools.mjs +4 -0
  266. package/src/session-runtime/config-lifecycle.mjs +10 -1
  267. package/src/session-runtime/conversation-import/discovery.mjs +698 -0
  268. package/src/session-runtime/conversation-import/service.mjs +369 -0
  269. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +21 -6
  270. package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
  271. package/src/session-runtime/global-extensions.mjs +2 -2
  272. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
  273. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
  274. package/src/session-runtime/internal-tool-executor.mjs +9 -1
  275. package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
  276. package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
  277. package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
  278. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
  279. package/src/session-runtime/mcp-glue/connect.mjs +68 -16
  280. package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
  281. package/src/session-runtime/mcp-glue/server-catalog.mjs +122 -33
  282. package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
  283. package/src/session-runtime/mcp-glue.mjs +22 -2
  284. package/src/session-runtime/model-route/route-persist.mjs +3 -0
  285. package/src/session-runtime/model-route/set-route.mjs +15 -2
  286. package/src/session-runtime/new-session-config.mjs +3 -2
  287. package/src/session-runtime/notification-bus.mjs +18 -3
  288. package/src/session-runtime/provider-auth/accounts.mjs +33 -15
  289. package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
  290. package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
  291. package/src/session-runtime/provider-readiness.mjs +16 -10
  292. package/src/session-runtime/resource-extension-sync.mjs +45 -7
  293. package/src/session-runtime/resource-mcp-api.mjs +121 -84
  294. package/src/session-runtime/resource-plugins-api.mjs +29 -41
  295. package/src/session-runtime/resource-scope-decorate.mjs +6 -8
  296. package/src/session-runtime/resource-skills-api.mjs +23 -2
  297. package/src/session-runtime/route-resolution.mjs +10 -1
  298. package/src/session-runtime/route-state.mjs +16 -2
  299. package/src/session-runtime/runtime-core.mjs +5 -0
  300. package/src/session-runtime/runtime-facade.mjs +8 -0
  301. package/src/session-runtime/runtime-review-api.mjs +9 -0
  302. package/src/session-runtime/schedule-session-run.mjs +1 -1
  303. package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
  304. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
  305. package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
  306. package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
  307. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
  308. package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
  309. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
  310. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
  311. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  312. package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
  313. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
  314. package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
  315. package/src/session-runtime/services/agent-tool.mjs +1 -0
  316. package/src/session-runtime/services/channel-session-router.mjs +4 -1
  317. package/src/session-runtime/services/daemon-candidate.mjs +3 -2
  318. package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
  319. package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
  320. package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
  321. package/src/session-runtime/services/provider-admin.mjs +64 -18
  322. package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
  323. package/src/session-runtime/session-create/session-options.mjs +10 -1
  324. package/src/session-runtime/session-turn-api.mjs +1 -0
  325. package/src/session-runtime/settings-api.mjs +4 -2
  326. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
  327. package/src/session-runtime/settings-worktree-api.mjs +17 -0
  328. package/src/session-runtime/setup-tool/executor.mjs +23 -5
  329. package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
  330. package/src/session-runtime/setup-tool/settings-contract.mjs +4 -1
  331. package/src/session-runtime/setup-tool/tool-defs.mjs +38 -4
  332. package/src/session-runtime/skills-api.mjs +7 -3
  333. package/src/session-runtime/turn/agent-ops.mjs +12 -1
  334. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +14 -3
  335. package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
  336. package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
  337. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
  338. package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
  339. package/src/session-runtime/turn/turn-run.mjs +6 -7
  340. package/src/session-runtime/webhook-session-run.mjs +16 -4
  341. package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
  342. package/src/session-runtime/workspace/admission-gate.mjs +197 -0
  343. package/src/session-runtime/workspace/project-branches.mjs +136 -0
  344. package/src/session-runtime/workspace/transition-steps.mjs +364 -0
  345. package/src/session-runtime/workspace/transitions.mjs +651 -0
  346. package/src/session-runtime/workspace/workspace-state.mjs +112 -0
  347. package/src/skill-script-entry.mjs +36 -0
  348. package/src/standalone/channel-transport/http-routes.mjs +17 -0
  349. package/src/standalone/channel-transport.mjs +13 -1
  350. package/src/standalone/daemon-desktop-runtime.mjs +1 -0
  351. package/src/standalone/daemon-owner.mjs +372 -0
  352. package/src/standalone/daemon-stored-session-views.mjs +15 -4
  353. package/src/standalone/daemon.mjs +179 -8
  354. package/src/standalone/desktop-service-registry.mjs +20 -0
  355. package/src/standalone/local-session-runtime.mjs +11 -0
  356. package/src/standalone/session-client/attachment-calls.mjs +3 -1
  357. package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
  358. package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
  359. package/src/standalone/session-client.mjs +104 -13
  360. package/src/standalone/session-protocol.mjs +21 -0
  361. package/src/standalone/session-proxy.mjs +3 -0
  362. package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
  363. package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
  364. package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
  365. package/src/standalone/session-service/projection/revisions.mjs +2 -0
  366. package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
  367. package/src/standalone/session-service/projection/workspace.mjs +14 -0
  368. package/src/standalone/session-service/session-calls/session-action.mjs +17 -4
  369. package/src/standalone/session-transport/call-route.mjs +13 -0
  370. package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
  371. package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
  372. package/src/standalone/session-transport/client-registry.mjs +20 -3
  373. package/src/standalone/session-transport/routes.mjs +79 -2
  374. package/src/standalone/session-transport/stack.mjs +2 -0
  375. package/src/standalone/session-transport.mjs +24 -1
  376. package/src/tui/App.jsx +9 -1
  377. package/src/tui/app/app-view/floating-panel.jsx +9 -1
  378. package/src/tui/app/app-view.jsx +6 -0
  379. package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
  380. package/src/tui/app/message-selector.mjs +2 -1
  381. package/src/tui/app/model-options.mjs +37 -5
  382. package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
  383. package/src/tui/app/model-picker.mjs +4 -2
  384. package/src/tui/app/skill-mention-palette.mjs +88 -0
  385. package/src/tui/app/slash-palette.mjs +23 -7
  386. package/src/tui/app/transcript-row-estimate.mjs +11 -3
  387. package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
  388. package/src/tui/app/use-prompt-state.mjs +5 -0
  389. package/src/tui/components/Message.jsx +22 -1
  390. package/src/tui/components/PromptInput.jsx +21 -3
  391. package/src/tui/components/SlashCommandPalette.jsx +12 -3
  392. package/src/tui/components/TranscriptItem.jsx +9 -1
  393. package/src/tui/components/prompt-input/key-handler.mjs +21 -8
  394. package/src/tui/components/user-message-skills.mjs +38 -0
  395. package/src/tui/dist/index.mjs +839 -207
  396. package/src/tui/index.jsx +10 -2
  397. package/src/tui/session/compaction-view.mjs +147 -0
  398. package/src/tui/session/context-state.mjs +6 -0
  399. package/src/tui/session/initial-state.mjs +3 -0
  400. package/src/tui/session/queue-helpers.mjs +7 -2
  401. package/src/tui/session/quota-resume.mjs +2 -1
  402. package/src/tui/session/session-api/commands.mjs +10 -2
  403. package/src/tui/session/session-api/controls.mjs +4 -0
  404. package/src/tui/session/session-api/extensions.mjs +4 -2
  405. package/src/tui/session/session-api/intake/rewind.mjs +2 -1
  406. package/src/tui/session/session-api/integrations.mjs +17 -0
  407. package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
  408. package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
  409. package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
  410. package/src/tui/session/session-api/routes.mjs +10 -1
  411. package/src/tui/session/session-api/settings.mjs +9 -0
  412. package/src/tui/session/session-api/worktree.mjs +60 -0
  413. package/src/tui/session/session-api.mjs +2 -0
  414. package/src/tui/session/session-flow/auto-clear.mjs +31 -12
  415. package/src/tui/session/session-flow/drain.mjs +27 -3
  416. package/src/tui/session/session-flow/session-reset.mjs +4 -3
  417. package/src/tui/session/session-flow.mjs +2 -0
  418. package/src/tui/session/transcript-intake.mjs +14 -5
  419. package/src/tui/session/tui-steering-persist.mjs +25 -9
  420. package/src/tui/session/turn-stream.mjs +32 -4
  421. package/src/tui/session/turn-tool-cards.mjs +10 -2
  422. package/src/tui/session/turn.mjs +56 -10
  423. package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
  424. package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
@@ -201,8 +201,8 @@ function isExcludedUserIngestText(m, text) {
201
201
  if (metaSource === 'task-notification') return true;
202
202
  // `Reference files:` synthetic user rows (manager.mjs isReferenceFilesMessage).
203
203
  if (/^Reference files:\s*/i.test(trimmedStart)) return true;
204
- // Attachment-only placeholder rows (e.g. Discord provider discord.mjs:724
205
- // `"(attachment)"` fallback when a message carries no text, only files).
204
+ // Attachment-only placeholder rows (`"(attachment)"` fallback written by the
205
+ // former channel provider when a message carried no text, only files).
206
206
  if (text.trim() === '(attachment)') return true;
207
207
  // Compaction summary user rows (compact.mjs isSummaryMessage / SUMMARY_PREFIX).
208
208
  if (metaSource === 'compact-summary') return true;
@@ -21,7 +21,7 @@ import {
21
21
  } from 'node:fs/promises';
22
22
  import { dirname, basename, join } from 'node:path';
23
23
  import { randomBytes } from 'node:crypto';
24
- import { DEFAULT_BACKOFFS_MS, withFileLock, withFileLockSync } from './file-lock.mjs';
24
+ import { DEFAULT_BACKOFFS_MS, recordLockTiming, withFileLock, withFileLockSync } from './file-lock.mjs';
25
25
  import {
26
26
  enforceOwnerOnlyAclWin32 as _enforceOwnerOnlyAclWin32,
27
27
  enforceOwnerOnlyAclWin32Async as _enforceOwnerOnlyAclWin32Async,
@@ -240,6 +240,12 @@ export function writeJsonAtomicSync(filePath, value, opts = {}) {
240
240
  return writeFileAtomicSync(filePath, `${JSON.stringify(value, null, opts.compact ? 0 : 2)}\n`, opts);
241
241
  }
242
242
 
243
+ // Windows editors and PowerShell 5 save UTF-8 with a leading byte order mark,
244
+ // which JSON.parse rejects; a hand-edited state file must still load.
245
+ export function parseJsonText(text) {
246
+ return JSON.parse(text.charCodeAt(0) === 0xfeff ? text.slice(1) : text);
247
+ }
248
+
243
249
  function recoverJsonMutationRead(error) {
244
250
  // Missing/malformed JSON retains the existing initializer contract. An I/O
245
251
  // or permission failure is not an empty document and must never authorize
@@ -255,7 +261,7 @@ export function updateJsonAtomicSync(filePath, mutator, opts = {}) {
255
261
  () => {
256
262
  let cur = null;
257
263
  try {
258
- cur = JSON.parse(readFileSync(filePath, 'utf8'));
264
+ cur = parseJsonText(readFileSync(filePath, 'utf8'));
259
265
  } catch (error) {
260
266
  cur = recoverJsonMutationRead(error);
261
267
  }
@@ -315,9 +321,30 @@ export async function writeFileAtomicAsync(filePath, data, opts = {}) {
315
321
  };
316
322
  // Acquire the file lock before occupying an I/O slot. Otherwise a waiter can
317
323
  // exhaust the gate while the current lock owner needs it to finish its write.
318
- return opts.lock === true
319
- ? withFileLock(`${filePath}.lock`, () => _runAdaptiveFileIo(run), opts)
320
- : _runAdaptiveFileIo(run);
324
+ if (opts.lock !== true) return _runAdaptiveFileIo(run);
325
+ const lockPath = `${filePath}.lock`;
326
+ return withFileLock(
327
+ lockPath,
328
+ async () => {
329
+ const queuedAt = Date.now();
330
+ let startedAt = 0;
331
+ try {
332
+ return await _runAdaptiveFileIo(() => {
333
+ startedAt = Date.now();
334
+ return run();
335
+ });
336
+ } finally {
337
+ const now = Date.now();
338
+ // Recorded from this (lock-owner) context so the held warning can
339
+ // split the hold into gate wait vs. the write itself.
340
+ recordLockTiming(lockPath, {
341
+ ioGateWaitMs: (startedAt || now) - queuedAt,
342
+ writeMs: startedAt ? now - startedAt : 0,
343
+ });
344
+ }
345
+ },
346
+ opts
347
+ );
321
348
  }
322
349
 
323
350
  export function writeJsonAtomicAsync(filePath, value, opts = {}) {
@@ -336,7 +363,7 @@ export async function updateJsonAtomic(filePath, mutator, opts = {}) {
336
363
  async () => {
337
364
  let cur = null;
338
365
  try {
339
- cur = JSON.parse(await readFileAsync(filePath, 'utf8'));
366
+ cur = parseJsonText(await readFileAsync(filePath, 'utf8'));
340
367
  } catch (error) {
341
368
  cur = recoverJsonMutationRead(error);
342
369
  }
@@ -0,0 +1,8 @@
1
+ // stderr diagnostics that must never throw (closed or broken stderr).
2
+ export function writeStderrBestEffort(line) {
3
+ try {
4
+ process.stderr.write(line);
5
+ } catch {
6
+ /* diagnostics only */
7
+ }
8
+ }
@@ -74,6 +74,18 @@ export function markCodeGraphDirtyPaths(paths) {
74
74
  }
75
75
  }
76
76
 
77
+ /** Drop the resident graph, pending dirty paths and dirty generation of one
78
+ * root (exact canonical match; nested roots are other roots). Returns the
79
+ * names of the state that was actually dropped. */
80
+ export function forgetCodeGraphStateRoot(root) {
81
+ const key = canonicalGraphCwd(root);
82
+ const removed = [];
83
+ if (codeGraphCache.delete(key)) removed.push('resident-graph');
84
+ if (codeGraphDirtyPaths.delete(key)) removed.push('dirty-paths');
85
+ if (codeGraphDirtyGen.delete(key)) removed.push('dirty-generation');
86
+ return removed;
87
+ }
88
+
77
89
  export function registerCodeGraphDrain(fn) {
78
90
  drainCodeGraphCacheFn = typeof fn === 'function' ? fn : null;
79
91
  }
@@ -21,6 +21,7 @@ import { DEFAULTS_VERSION, DEFAULTS_VERSION_KEY, configPath, readConfig, updateC
21
21
  import { DEFAULT_DISABLED_AGENT_ROSTER, disabledAgentDelta, disabledAgentIds } from './agent-route-config.mjs';
22
22
  import { withGrandfatheredBuiltins } from './builtin-grandfathering.mjs';
23
23
  import { DEFAULT_ORCHESTRATION_MODE, legacyWorkflowOrchestrationMode } from './orchestration.mjs';
24
+ import { WORKTREE_SETTINGS_DEFAULTS } from './worktrees/settings.mjs';
24
25
 
25
26
  export { DEFAULTS_VERSION, DEFAULTS_VERSION_KEY };
26
27
 
@@ -33,6 +34,7 @@ const AGENT_SECTION_DEFAULTS = Object.freeze({
33
34
  update: Object.freeze({ auto: true }),
34
35
  recap: Object.freeze({ enabled: true }),
35
36
  memoryTools: Object.freeze({ enabled: true }),
37
+ worktree: WORKTREE_SETTINGS_DEFAULTS,
36
38
  });
37
39
  const MODULE_DEFAULTS = Object.freeze({ enabled: true });
38
40
 
@@ -16,6 +16,7 @@
16
16
  import { resolve, sep } from 'node:path';
17
17
  import { clean } from './clean.mjs';
18
18
  import { isPlainObject } from './object.mjs';
19
+ import { parseMcpToolName } from './tool-primitives.mjs';
19
20
 
20
21
  export const EXTENSION_SCOPE_KINDS = Object.freeze(['skills', 'mcp', 'plugins']);
21
22
 
@@ -123,9 +124,10 @@ export function skillAllowedForCwd(scopes, skill, cwd) {
123
124
  return true;
124
125
  }
125
126
 
126
- export function mcpServerNameOfTool(toolName) {
127
- const match = /^mcp__(.+?)__(.+)$/.exec(clean(toolName));
128
- return match ? match[1] : '';
127
+ /** Server of an MCP tool definition or name (metadata first; see parseMcpToolName). */
128
+ export function mcpServerNameOfTool(toolOrName) {
129
+ const value = toolOrName && typeof toolOrName === 'object' ? toolOrName : clean(toolOrName);
130
+ return clean(parseMcpToolName(value)?.server);
129
131
  }
130
132
 
131
133
  /** New config with one entry replaced; `projects` null/empty removes it (global). */
@@ -177,16 +177,38 @@ function warnLockRateLimited(warnedAt, lockPath, line) {
177
177
  }
178
178
  }
179
179
 
180
- function reportLockWait(lockPath, waitedMs, mode) {
180
+ function formatLockTiming(timing) {
181
+ return Object.entries(timing || {})
182
+ .filter(([, ms]) => Number.isFinite(ms))
183
+ .map(([name, ms]) => ` ${name}=${ms}ms`)
184
+ .join('');
185
+ }
186
+
187
+ // Lets a lock owner's callback attribute its time (io gate wait, write) to the
188
+ // held-warning of the lock it runs under.
189
+ export function recordLockTiming(lockPath, fields) {
190
+ const lease = heldLockPaths.getStore()?.get(lockPath);
191
+ if (lease?.active) Object.assign(lease.timing, fields);
192
+ }
193
+
194
+ function reportLockWait(lockPath, waitedMs, mode, timing) {
181
195
  if (waitedMs < LOCK_WAIT_WARN_MS) return;
182
- warnLockRateLimited(lockWaitWarnedAt, lockPath, `[atomic-file] ${mode} lock wait ${waitedMs}ms: ${lockPath}\n`);
196
+ warnLockRateLimited(
197
+ lockWaitWarnedAt,
198
+ lockPath,
199
+ `[atomic-file] ${mode} lock wait ${waitedMs}ms:${formatLockTiming(timing)} ${lockPath}\n`
200
+ );
183
201
  }
184
202
 
185
203
  // A lock held this long starves every waiter (they time out at 2s), so the
186
204
  // holder's duration is reported once released.
187
- function reportLockHeld(lockPath, heldMs, mode) {
205
+ function reportLockHeld(lockPath, heldMs, mode, timing) {
188
206
  if (heldMs < LOCK_HELD_WARN_MS) return;
189
- warnLockRateLimited(lockHeldWarnedAt, lockPath, `[atomic-file] ${mode} lock held ${heldMs}ms: ${lockPath}\n`);
207
+ warnLockRateLimited(
208
+ lockHeldWarnedAt,
209
+ lockPath,
210
+ `[atomic-file] ${mode} lock held ${heldMs}ms:${formatLockTiming(timing)} ${lockPath}\n`
211
+ );
190
212
  }
191
213
 
192
214
  function* tryAcquireReclaimGuard(lockPath) {
@@ -387,7 +409,7 @@ export function sweepStagedLockFiles(lockPath, now = Date.now()) {
387
409
  return removed;
388
410
  }
389
411
 
390
- function* acquireLock(lockPath, opts, mode, markHeld) {
412
+ function* acquireLock(lockPath, opts, mode, markHeld, timing = null) {
391
413
  const timeoutMs = lockTimeoutMs(opts);
392
414
  const staleMs = lockStaleMs(opts);
393
415
  const deadline = Date.now() + timeoutMs;
@@ -415,7 +437,9 @@ function* acquireLock(lockPath, opts, mode, markHeld) {
415
437
  attempt += 1;
416
438
  continue;
417
439
  }
418
- reportLockWait(lockPath, Date.now() - waitStartedAt, mode);
440
+ const osMs = Date.now() - waitStartedAt;
441
+ if (timing) timing.osAcquireMs = osMs;
442
+ reportLockWait(lockPath, osMs, mode, timing);
419
443
  return;
420
444
  }
421
445
  throw timeoutError(lockPath, timeoutMs, lastError, yield* describeLockHolder(lockPath));
@@ -444,13 +468,15 @@ export function withFileLockSync(lockPath, fn, opts = {}) {
444
468
  export async function withFileLock(lockPath, fn, opts = {}) {
445
469
  if (heldLockPaths.getStore()?.get(lockPath)?.active) return fn();
446
470
  if (lockTimeoutMs(opts) <= 0) return withOsFileLock(lockPath, fn, opts);
447
- return lockQueue(lockPath, () => withOsFileLock(lockPath, fn, opts));
471
+ const enqueuedAt = Date.now();
472
+ return lockQueue(lockPath, () => withOsFileLock(lockPath, fn, opts, Date.now() - enqueuedAt));
448
473
  }
449
474
 
450
- async function withOsFileLock(lockPath, fn, opts = {}) {
451
- await runAsync(acquireLock(lockPath, opts, 'async', true));
475
+ async function withOsFileLock(lockPath, fn, opts = {}, queueWaitMs = 0) {
476
+ const timing = { queueWaitMs };
477
+ await runAsync(acquireLock(lockPath, opts, 'async', true, timing));
452
478
  const heldSince = Date.now();
453
- const lease = { active: false };
479
+ const lease = { active: false, timing };
454
480
  try {
455
481
  if (opts.secret === true) await enforceOwnerOnlyAclWin32Async(lockPath, { fresh: true });
456
482
  // Async descendants inherit a reference to this lease, not permanent
@@ -464,7 +490,7 @@ async function withOsFileLock(lockPath, fn, opts = {}) {
464
490
  try {
465
491
  await runAsync(releaseLock(lockPath));
466
492
  } finally {
467
- reportLockHeld(lockPath, Date.now() - heldSince, 'async');
493
+ reportLockHeld(lockPath, Date.now() - heldSince, 'async', timing);
468
494
  // Unmark only once the lock file is gone: a sync waiter arriving while
469
495
  // the release is still pending must fail fast, not block its completion.
470
496
  unmarkOsHeld(lockPath);
@@ -6,7 +6,7 @@
6
6
  import { spawn } from 'node:child_process';
7
7
  import { serveWorkerRequests } from './worker-requests.mjs';
8
8
 
9
- function runGit({ args, cwd, input, env, timeoutMs, maxBytes }) {
9
+ function runGit({ args, cwd, input, env, timeoutMs, maxBytes, stdoutEncoding = 'utf8' }) {
10
10
  return new Promise((resolvePromise, rejectPromise) => {
11
11
  const hasInput = (typeof input === 'string' || ArrayBuffer.isView(input)) && input.length > 0;
12
12
  const child = spawn('git', args, {
@@ -55,7 +55,8 @@ function runGit({ args, cwd, input, env, timeoutMs, maxBytes }) {
55
55
  child.once('close', (code) => {
56
56
  const result = {
57
57
  code: Number(code ?? 1),
58
- stdout: Buffer.concat(stdout).toString('utf8'),
58
+ // 'base64' keeps non-UTF-8 bytes (a replayable patch) intact across the thread hop.
59
+ stdout: Buffer.concat(stdout).toString(stdoutEncoding === 'base64' ? 'base64' : 'utf8'),
59
60
  stderr: Buffer.concat(stderr).toString('utf8'),
60
61
  };
61
62
  // A failed stdin write only matters when git otherwise reported success.
@@ -13,8 +13,9 @@ const requestGit = createWorkerRequestClient(new URL('./git-runner-worker.mjs',
13
13
  /**
14
14
  * Resolves to { code, stdout, stderr }. Rejects with code ETIMEDOUT after
15
15
  * timeoutMs (the child is killed), EMAXBUFFER once stdout+stderr exceed
16
- * maxBytes, or the spawn error itself.
16
+ * maxBytes, or the spawn error itself. `stdoutEncoding: 'base64'` returns the
17
+ * exact stdout bytes base64-encoded instead of decoded as UTF-8.
17
18
  */
18
- export function runGitOffThread(args, { cwd, input = '', env = null, timeoutMs, maxBytes }) {
19
- return requestGit({ args, cwd, input, env, timeoutMs, maxBytes });
19
+ export function runGitOffThread(args, { cwd, input = '', env = null, timeoutMs, maxBytes, stdoutEncoding = 'utf8' }) {
20
+ return requestGit({ args, cwd, input, env, timeoutMs, maxBytes, stdoutEncoding });
20
21
  }
@@ -96,6 +96,20 @@ function _catalogLevels(model) {
96
96
  return null;
97
97
  }
98
98
 
99
+ /**
100
+ * Effort levels the wire builder sends unchanged for `model` (reserved `max`
101
+ * excluded), from the same capability gates normalizeAnthropicEffortInput and
102
+ * applyAnthropicEffortToBody use: catalog record first, regex ladder for an
103
+ * absent record. A model without effort support, or whose catalog record
104
+ * declares none, accepts none.
105
+ */
106
+ export function anthropicEffortLevelsFor(model) {
107
+ if (!modelSupportsEffort(model)) return [];
108
+ const levels = ['low', 'medium', 'high'];
109
+ if (modelSupportsXhighEffort(model)) levels.push('xhigh');
110
+ return levels;
111
+ }
112
+
99
113
  export const EFFORT_BETA_HEADER = 'effort-2025-11-24';
100
114
 
101
115
  export const LEGACY_EFFORT_BUDGET = Object.freeze({
@@ -24,6 +24,12 @@ function positiveTokens(value) {
24
24
  return Number.isFinite(tokens) && tokens > 0 ? Math.floor(tokens) : 0;
25
25
  }
26
26
 
27
+ /** An exact context-window selection in tokens (`contextTokens`); undefined when unset or invalid. */
28
+ export function normalizeContextTokens(value) {
29
+ const tokens = Math.round(Number(value));
30
+ return Number.isFinite(tokens) && tokens > 0 ? tokens : undefined;
31
+ }
32
+
27
33
  /**
28
34
  * The default and the largest selectable window of one model row, in tokens.
29
35
  * `defaultWindow` is 0 when the row states no window to start from.
@@ -69,7 +69,8 @@ function projectModelsDevRow(row) {
69
69
  if (limit) out.limit = limit;
70
70
  const modalities = pickArrays(row.modalities, MODELSDEV_MODALITY_FIELDS);
71
71
  if (modalities) out.modalities = modalities;
72
- if (row.reasoning === true) out.reasoning = true;
72
+ // A declared `reasoning: false` must stay distinct from absent (capabilityFlag).
73
+ if (typeof row.reasoning === 'boolean') out.reasoning = row.reasoning;
73
74
  if (Array.isArray(row.reasoning_options) && row.reasoning_options.length > 0) {
74
75
  out.reasoning_options = row.reasoning_options;
75
76
  }
@@ -129,8 +130,8 @@ const LITELLM_NUMBER_FIELDS = [
129
130
  'output_cost_per_video_token',
130
131
  'output_cost_per_second',
131
132
  ];
132
- // _normalize tests each of these with `=== true`, so only a true value carries
133
- // information; anything else is indistinguishable from absent.
133
+ // _normalize keeps each declared boolean (an explicit false outranks a lower
134
+ // layer's true); any other value is indistinguishable from absent.
134
135
  const LITELLM_FLAG_FIELDS = [
135
136
  'supports_vision',
136
137
  'supports_function_calling',
@@ -164,7 +165,7 @@ function projectLitellmRow(row) {
164
165
  out[field] = value;
165
166
  }
166
167
  for (const field of LITELLM_FLAG_FIELDS) {
167
- if (row[field] === true) out[field] = true;
168
+ if (typeof row[field] === 'boolean') out[field] = row[field];
168
169
  }
169
170
  for (const field of LITELLM_STRING_FIELDS) {
170
171
  const value = row[field];