mixdog 1.2.4 → 1.2.6

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 (292) hide show
  1. package/package.json +1 -1
  2. package/scripts/lib/gate-scheduler.mjs +2 -2
  3. package/scripts/lib/run-node-tests.mjs +5 -14
  4. package/scripts/mobile-release.mjs +5 -4
  5. package/scripts/provider-pingpong-live.mjs +9 -9
  6. package/src/agents/advisor/AGENT.md +4 -4
  7. package/src/agents/advisor/agent.json +1 -1
  8. package/src/agents/reviewer/AGENT.md +2 -3
  9. package/src/agents/reviewer/agent.json +1 -1
  10. package/src/defaults/shipped-history.json +11 -0
  11. package/src/defaults/skills/browser-use/SKILL.md +2 -1
  12. package/src/defaults/skills/computer-use/SKILL.md +3 -1
  13. package/src/defaults/skills/visualize/SKILL.md +3 -2
  14. package/src/lib/rules-builder.cjs +1 -1
  15. package/src/output-styles/common.md +22 -5
  16. package/src/output-styles/detailed.md +7 -5
  17. package/src/output-styles/minimal.md +7 -3
  18. package/src/output-styles/simple.md +2 -3
  19. package/src/rules/agent/AGENT.md +3 -1
  20. package/src/rules/lead/LEAD.md +10 -7
  21. package/src/rules/shared/10-tool-workflow.md +2 -1
  22. package/src/rules/shared/60-verification.md +4 -5
  23. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
  24. package/src/runtime/agent/orchestrator/config.mjs +6 -0
  25. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +1 -1
  26. package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
  27. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +53 -60
  28. package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
  29. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
  30. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
  31. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +40 -19
  32. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +3 -2
  33. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +4 -1
  34. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +2 -0
  35. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
  36. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -1
  37. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -1
  38. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +1 -2
  39. package/src/runtime/agent/orchestrator/providers/catalog-deadline.mjs +163 -0
  40. package/src/runtime/agent/orchestrator/providers/catalog-failures.mjs +34 -0
  41. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +38 -14
  42. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +100 -26
  43. package/src/runtime/agent/orchestrator/providers/lib/send-callbacks.mjs +24 -0
  44. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -0
  45. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +2 -1
  46. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
  47. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +4 -0
  48. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  49. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  50. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +49 -4
  51. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -7
  52. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +7 -1
  53. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
  54. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -0
  55. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
  56. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +5 -1
  57. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +11 -2
  58. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -0
  59. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +45 -16
  60. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +1 -0
  61. package/src/runtime/agent/orchestrator/providers/openai-ws-connect.mjs +196 -0
  62. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +74 -9
  63. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +14 -1
  64. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -0
  65. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-login.mjs +194 -0
  66. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-tokens.mjs +353 -0
  67. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +293 -0
  68. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +33 -100
  69. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +23 -14
  70. package/src/runtime/agent/orchestrator/providers/registry.mjs +41 -27
  71. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +2 -3
  72. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +3 -8
  73. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
  74. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +74 -13
  75. package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +102 -0
  76. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +8 -2
  77. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +16 -0
  78. package/src/runtime/agent/orchestrator/session/lifecycle-scan.mjs +9 -0
  79. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
  80. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +9 -19
  81. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -3
  82. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -0
  83. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
  84. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +10 -7
  85. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -22
  86. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +23 -1
  87. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
  88. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
  89. package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -0
  90. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +16 -1
  91. package/src/runtime/agent/orchestrator/session/side-question.mjs +5 -43
  92. package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +10 -0
  93. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +73 -6
  94. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +40 -0
  95. package/src/runtime/agent/orchestrator/session/store/save-fault.mjs +15 -0
  96. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +12 -0
  97. package/src/runtime/agent/orchestrator/session/store-agent-worker-header.mjs +36 -0
  98. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +255 -32
  99. package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +306 -0
  100. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +70 -21
  101. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
  102. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +144 -45
  103. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +32 -13
  104. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +364 -38
  105. package/src/runtime/agent/orchestrator/session/store.mjs +9 -2
  106. package/src/runtime/agent/orchestrator/session/task-wait-control.mjs +43 -12
  107. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +23 -6
  108. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -6
  109. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +13 -7
  110. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +1 -1
  111. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -1
  112. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +40 -7
  113. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +37 -34
  114. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +1 -1
  115. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +0 -4
  116. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -0
  117. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +29 -27
  118. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +1 -1
  119. package/src/runtime/agent/orchestrator/tools/builtin/find-files-tool.mjs +28 -11
  120. package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +12 -3
  121. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +203 -101
  122. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +90 -41
  123. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +17 -1
  124. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-delivery.mjs +199 -0
  125. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +165 -39
  126. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
  127. package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +7 -6
  128. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +19 -4
  129. package/src/runtime/agent/orchestrator/tools/builtin/read-line-collector.mjs +5 -3
  130. package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +25 -7
  131. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +2 -1
  132. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-render.mjs +3 -1
  133. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +12 -5
  134. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +61 -22
  135. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +32 -8
  136. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +193 -19
  137. package/src/runtime/agent/orchestrator/tools/builtin/shell-direct-exe.mjs +57 -7
  138. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +119 -32
  139. package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +26 -1
  140. package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +13 -28
  141. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +90 -11
  142. package/src/runtime/agent/orchestrator/tools/builtin/wait-budgets.mjs +23 -0
  143. package/src/runtime/agent/orchestrator/tools/builtin.mjs +54 -10
  144. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +22 -28
  145. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +11 -7
  146. package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +126 -9
  147. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  148. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +15 -6
  149. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +40 -2
  150. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -2
  151. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promotion-results.mjs +13 -3
  152. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +2 -0
  153. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +3 -1
  154. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
  155. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +35 -4
  156. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +7 -2
  157. package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +39 -23
  158. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +6 -2
  159. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  160. package/src/runtime/attachments/office-extract.mjs +11 -9
  161. package/src/runtime/memory/lib/embedding-tokenizer.mjs +32 -18
  162. package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
  163. package/src/runtime/memory/lib/tool-call-handler.mjs +7 -5
  164. package/src/runtime/office/authoring/pptx-script-normalize.mjs +11 -8
  165. package/src/runtime/office/core/tabular.mjs +1 -1
  166. package/src/runtime/office/design/library/design-template-inspect.mjs +7 -4
  167. package/src/runtime/office/portable/docx-formatting.mjs +1 -1
  168. package/src/runtime/office/portable/docx-runs.mjs +1 -1
  169. package/src/runtime/office/portable/docx-tracked-edits.mjs +2 -2
  170. package/src/runtime/office/portable/portable-docx-edits.mjs +11 -10
  171. package/src/runtime/office/portable/portable-docx-operations.mjs +21 -17
  172. package/src/runtime/office/portable/portable-docx-parts.mjs +15 -9
  173. package/src/runtime/office/portable/portable-docx-styles.mjs +4 -1
  174. package/src/runtime/office/portable/portable-docx-xml.mjs +9 -9
  175. package/src/runtime/office/portable/portable-opc.mjs +27 -13
  176. package/src/runtime/office/portable/portable-pivot.mjs +3 -3
  177. package/src/runtime/office/portable/portable-pptx-chart.mjs +3 -3
  178. package/src/runtime/office/portable/portable-pptx-charts.mjs +24 -18
  179. package/src/runtime/office/portable/portable-pptx-core.mjs +5 -5
  180. package/src/runtime/office/portable/portable-pptx-deck.mjs +8 -4
  181. package/src/runtime/office/portable/portable-pptx-package.mjs +7 -4
  182. package/src/runtime/office/portable/portable-pptx-shapes.mjs +18 -9
  183. package/src/runtime/office/portable/portable-sheet-parts.mjs +9 -3
  184. package/src/runtime/office/portable/portable-sheet-xml.mjs +5 -5
  185. package/src/runtime/office/portable/portable-xlsx-charts.mjs +4 -1
  186. package/src/runtime/office/portable/portable-xlsx-drawings.mjs +10 -6
  187. package/src/runtime/office/portable/portable-xlsx-operations.mjs +8 -5
  188. package/src/runtime/office/portable/portable-xlsx-pivot-ops.mjs +1 -1
  189. package/src/runtime/office/portable/portable-xlsx-reference-shift.mjs +11 -7
  190. package/src/runtime/office/portable/portable-xlsx-sheet-edits.mjs +6 -3
  191. package/src/runtime/office/portable/portable-xml.mjs +1 -1
  192. package/src/runtime/shared/atomic-file.mjs +22 -13
  193. package/src/runtime/shared/background-tasks.mjs +60 -20
  194. package/src/runtime/shared/child-spawn-gate.mjs +26 -16
  195. package/src/runtime/shared/config.mjs +0 -10
  196. package/src/runtime/shared/file-lock.mjs +7 -1
  197. package/src/runtime/shared/file-permissions-worker.mjs +38 -0
  198. package/src/runtime/shared/file-permissions.d.mts +19 -4
  199. package/src/runtime/shared/file-permissions.mjs +310 -4
  200. package/src/runtime/shared/git-runner-worker.mjs +6 -78
  201. package/src/runtime/shared/llm/http-agent.mjs +7 -3
  202. package/src/runtime/shared/llm/provider-catalog-registry.mjs +10 -0
  203. package/src/runtime/shared/llm/usage-accounting.mjs +2 -0
  204. package/src/runtime/shared/llm/usage-ledger-import.mjs +32 -3
  205. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +12 -5
  206. package/src/runtime/shared/llm/usage-ledger-worker.mjs +1 -1
  207. package/src/runtime/shared/llm/usage-ledger.mjs +20 -5
  208. package/src/runtime/shared/memory-snapshot.mjs +5 -1
  209. package/src/runtime/shared/notify-trace.mjs +8 -1
  210. package/src/runtime/shared/pristine-execution-contract.json +5 -1
  211. package/src/runtime/shared/process-runner-worker.mjs +7 -0
  212. package/src/runtime/shared/process-runner.mjs +38 -0
  213. package/src/runtime/shared/provider-accounts.mjs +2 -1
  214. package/src/runtime/shared/provider-api-key.mjs +0 -1
  215. package/src/runtime/shared/read-row-numbers.mjs +1 -1
  216. package/src/runtime/shared/resource-admission.mjs +60 -18
  217. package/src/runtime/shared/run-child.mjs +84 -0
  218. package/src/runtime/shared/session-activity-signal.mjs +23 -0
  219. package/src/runtime/shared/shell-output-summary.mjs +23 -0
  220. package/src/runtime/shared/singleton-owner.mjs +126 -42
  221. package/src/runtime/shared/tool-output-limit.mjs +4 -2
  222. package/src/runtime/shared/tool-output-marker.mjs +58 -0
  223. package/src/runtime/shared/user-data-guard.mjs +28 -9
  224. package/src/runtime/shared/worktrees/activity-gate.mjs +33 -8
  225. package/src/runtime/shared/worktrees/git-head.mjs +20 -2
  226. package/src/runtime/shared/worktrees/lock.mjs +3 -2
  227. package/src/runtime/terminal-bridge/tool-defs.mjs +1 -1
  228. package/src/runtime/tidy/runners/biome.mjs +3 -1
  229. package/src/runtime/tidy/shadow.mjs +2 -1
  230. package/src/runtime/web-search/index.mjs +5 -7
  231. package/src/runtime/web-search/lib/formatter.mjs +42 -6
  232. package/src/runtime/web-search/tool-defs.mjs +6 -1
  233. package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +4 -3
  234. package/src/session-runtime/lifecycle/session-switch/resume.mjs +7 -4
  235. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
  236. package/src/session-runtime/lifecycle/shared.mjs +19 -2
  237. package/src/session-runtime/lifecycle/teardown/session-close.mjs +2 -0
  238. package/src/session-runtime/lifecycle/teardown.mjs +5 -2
  239. package/src/session-runtime/lifecycle-api.mjs +3 -1
  240. package/src/session-runtime/provider-auth/login.mjs +10 -6
  241. package/src/session-runtime/provider-auth/setup.mjs +19 -2
  242. package/src/session-runtime/provider-catalog-cache.mjs +101 -25
  243. package/src/session-runtime/provider-models/catalog-load.mjs +14 -3
  244. package/src/session-runtime/provider-models/row-hydration.mjs +4 -0
  245. package/src/session-runtime/provider-models.mjs +76 -10
  246. package/src/session-runtime/provider-readiness.mjs +4 -0
  247. package/src/session-runtime/services/agent-tool/close-flow.mjs +2 -1
  248. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +10 -2
  249. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +13 -4
  250. package/src/session-runtime/services/agent-tool/notify.mjs +15 -4
  251. package/src/session-runtime/services/agent-tool/restart-notify.mjs +134 -0
  252. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -1
  253. package/src/session-runtime/services/agent-tool/spawn-flow/deferred-spawn.mjs +2 -1
  254. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -3
  255. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -1
  256. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +8 -3
  257. package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -0
  258. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +4 -0
  259. package/src/session-runtime/services/agent-tool/worker-index.mjs +44 -10
  260. package/src/session-runtime/services/agent-tool.mjs +20 -0
  261. package/src/session-runtime/services/provider-admin.mjs +92 -20
  262. package/src/session-runtime/services/usage-dashboard-model.mjs +2 -2
  263. package/src/session-runtime/services/usage-dashboard.mjs +27 -69
  264. package/src/session-runtime/turn/session-ops.mjs +2 -2
  265. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  266. package/src/session-runtime/usage-stats-api.mjs +6 -1
  267. package/src/standalone/channel-transport/http-routes.mjs +10 -9
  268. package/src/standalone/daemon-desktop-runtime.mjs +20 -7
  269. package/src/standalone/daemon-owner.mjs +117 -25
  270. package/src/standalone/daemon.mjs +43 -13
  271. package/src/standalone/desktop-service-registry.mjs +32 -5
  272. package/src/standalone/session-call-cache.mjs +6 -0
  273. package/src/standalone/session-protocol.mjs +1 -1
  274. package/src/standalone/session-service/retention/busy.mjs +7 -2
  275. package/src/standalone/session-transport/routes.mjs +7 -6
  276. package/src/tui/app/model-options.mjs +39 -2
  277. package/src/tui/app/model-picker.mjs +16 -2
  278. package/src/tui/app/provider-setup-picker.mjs +1 -2
  279. package/src/tui/dist/index.mjs +436 -123
  280. package/src/tui/session/notice-text.mjs +0 -1
  281. package/src/tui/session/session-api/intake/submission.mjs +7 -13
  282. package/src/tui/session/session-api/integrations.mjs +1 -5
  283. package/src/tui/session/session-flow/drain.mjs +8 -0
  284. package/src/tui/session/session-flow/steering.mjs +46 -0
  285. package/src/tui/session/session-flow.mjs +2 -0
  286. package/src/tui/session/turn-stream.mjs +33 -0
  287. package/src/tui/session/turn.mjs +30 -3
  288. package/src/ui/statusline.mjs +1 -6
  289. package/src/ui/streaming-markdown-heal.mjs +94 -25
  290. package/src/vendor/statusline/bin/statusline-route.mjs +0 -1
  291. package/src/vendor/statusline/src/gateway/route-meta.mjs +0 -1
  292. package/src/workflows/default/WORKFLOW.md +9 -13
@@ -165,6 +165,8 @@ export class DesktopServiceRegistry {
165
165
  moduleUrl: requestedModule,
166
166
  instance,
167
167
  subscribers: new Set(),
168
+ visibilityEpochs: new Map(),
169
+ nextVisibilityEpoch: 0,
168
170
  };
169
171
  this.#servicesById.set(requestedId, record);
170
172
  this.#servicesByModule.set(requestedModule, record);
@@ -187,7 +189,14 @@ export class DesktopServiceRegistry {
187
189
  const service = await this.#initialize(params);
188
190
  if (this.#closed) throw new Error('session service is closed');
189
191
  const token = subscriberToken(ctx);
190
- if (token) service.subscribers.add(token);
192
+ if (token) {
193
+ service.subscribers.add(token);
194
+ // The adapter outlives desktop processes, whose request counters restart.
195
+ // Allocate the ordering namespace here, not from a client's wall clock.
196
+ if (!service.visibilityEpochs.has(token)) {
197
+ service.visibilityEpochs.set(token, ++service.nextVisibilityEpoch);
198
+ }
199
+ }
191
200
  this.#syncModelProxyPresence();
192
201
  return { desktopId: service.desktopId };
193
202
  }
@@ -215,14 +224,23 @@ export class DesktopServiceRegistry {
215
224
  }
216
225
 
217
226
  async invoke({ desktopId, method, args = [] } = {}, ctx = null) {
218
- const { service } = this.#requireSubscribed(desktopId, ctx);
227
+ const { service, token } = this.#requireSubscribed(desktopId, ctx);
219
228
  const name = String(method || '');
220
229
  if (!name) throw new TypeError('desktop service method is required');
230
+ let callArgs = Array.isArray(args) ? args : [];
231
+ if (name === 'setVisibleSessions' && token) {
232
+ const epoch = service.visibilityEpochs.get(token);
233
+ if (epoch === undefined) {
234
+ service.subscribers.delete(token);
235
+ throw new Error('desktop service client is not initialized');
236
+ }
237
+ callArgs = [callArgs[0], callArgs[1], epoch];
238
+ }
221
239
  // `[slow-op] desktop.invoke` names the call it timed: a desktop operation
222
240
  // (Git reads) or a session capability, not only the generic route.
223
241
  const target = name === 'invokeDesktopOperation' || name === 'invokeCapability' ? String(args?.[0] || '') : '';
224
242
  annotateSpan(target ? `${name}:${target}` : name);
225
- return sanitizeForWire(await service.instance.invoke(name, Array.isArray(args) ? args : [])) ?? null;
243
+ return sanitizeForWire(await service.instance.invoke(name, callArgs)) ?? null;
226
244
  }
227
245
 
228
246
  async control({ desktopId, message } = {}, ctx = null) {
@@ -241,7 +259,7 @@ export class DesktopServiceRegistry {
241
259
  async unsubscribe({ desktopId } = {}, ctx = null) {
242
260
  const service = this.#require(desktopId);
243
261
  const token = subscriberToken(ctx);
244
- if (token) service.subscribers.delete(token);
262
+ if (token) await this.#releaseSubscriber(service, token);
245
263
  this.#syncModelProxyPresence();
246
264
  return { ok: true, unsubscribed: true };
247
265
  }
@@ -250,11 +268,20 @@ export class DesktopServiceRegistry {
250
268
  const token = String(clientToken || '');
251
269
  if (!token) return;
252
270
  for (const service of this.#servicesById.values()) {
253
- service.subscribers.delete(token);
271
+ void this.#releaseSubscriber(service, token).catch((error) => {
272
+ this.#log(`desktop visibility release failed: ${error?.message || error}`);
273
+ });
254
274
  }
255
275
  this.#syncModelProxyPresence();
256
276
  }
257
277
 
278
+ async #releaseSubscriber(service, token) {
279
+ service.subscribers.delete(token);
280
+ const epoch = service.visibilityEpochs.get(token);
281
+ service.visibilityEpochs.delete(token);
282
+ if (epoch !== undefined) await service.instance.releaseClient?.(epoch);
283
+ }
284
+
258
285
  notifySessionRuntimeReleased(sessionId, reason) {
259
286
  // An evicted session has NO session subscribers. Its desktop resources
260
287
  // still belong to the desktop service and must be notified on that lane.
@@ -85,6 +85,10 @@ export function createSessionCallCache({
85
85
  // Identity cannot be removed inside the promised retry TTL.
86
86
  for (const [key, record] of records) {
87
87
  if (records.size <= maxEntries && retainedBytes <= maxBytes) return;
88
+ // Insertion order is `at` order and settledAt >= at, so no later record
89
+ // can have left its TTL: stop instead of rescanning every live entry on
90
+ // each new call while a burst holds the cache above its budget.
91
+ if (at - record.at < ttlMs) break;
88
92
  if (!record.settled || !record.settledAt) continue;
89
93
  if (at - record.settledAt < ttlMs) continue;
90
94
  remove(key, record);
@@ -120,6 +124,8 @@ export function createSessionCallCache({
120
124
  bytes: 0,
121
125
  timer: null,
122
126
  };
127
+ // Re-insert at the tail so Map order stays `at` order (prune relies on it).
128
+ remove(key);
123
129
  records.set(key, record);
124
130
  prune();
125
131
  promise
@@ -118,6 +118,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
118
118
  'saveCustomProvider',
119
119
  'removeCustomProvider',
120
120
  'updateCustomProviderModel',
121
+ 'setModelPreferences',
121
122
  'testCustomProvider',
122
123
  'checkCustomProviderKeyEnv',
123
124
  'discoverCustomProviderModels',
@@ -166,7 +167,6 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
166
167
  'saveAgentDefinition',
167
168
  'saveMcpServer',
168
169
  'saveOpenAIUsageSessionKey',
169
- 'saveOpenCodeGoUsageAuth',
170
170
  'saveProviderApiKey',
171
171
  'saveSchedule',
172
172
  'saveSkill',
@@ -6,7 +6,7 @@
6
6
  * cannot be read is treated as busy rather than risking the loss of a live
7
7
  * turn. The eviction sweep that consumes this lives in ../retention.mjs.
8
8
  */
9
- import { hasActiveBackgroundTasks } from '../../../runtime/shared/background-tasks.mjs';
9
+ import { activeBackgroundTaskSessionIds, hasActiveBackgroundTasks } from '../../../runtime/shared/background-tasks.mjs';
10
10
 
11
11
  export function createBusyTracker({ sessions, currentSessionId }) {
12
12
  function stateBusy(state) {
@@ -44,10 +44,15 @@ export function createBusyTracker({ sessions, currentSessionId }) {
44
44
  }
45
45
  }
46
46
 
47
+ // sessionBusy for every entry, with the background tasks scanned once: the
48
+ // owner heartbeat, telemetry and status ask this every few seconds, and a
49
+ // scan per session made it sessions × tasks on the event loop.
47
50
  function liveBusyCount() {
51
+ const withTasks = activeBackgroundTaskSessionIds();
48
52
  let count = 0;
49
53
  for (const entry of sessions) {
50
- if (sessionBusy(entry)) count += 1;
54
+ const sessionId = currentSessionId(entry);
55
+ if ((sessionId && withTasks.has(sessionId)) || sessionTurnBusy(entry)) count += 1;
51
56
  }
52
57
  return count;
53
58
  }
@@ -57,9 +57,10 @@ export function createTransportRoutes({
57
57
  }) {
58
58
  // Checked on every register/call, last right before the work is handed on
59
59
  // (after the body is read): a daemon that lost (or cannot re-verify) its
60
- // owner lease serves nothing.
61
- const refuseUnadmitted = (res) => {
62
- if (admitWork()) return false;
60
+ // owner lease serves nothing. `admitWork` may answer asynchronously (a
61
+ // request arriving during the lease's re-verification waits for it).
62
+ const refuseUnadmitted = async (res) => {
63
+ if (await admitWork()) return false;
63
64
  sendError(res, 'daemon owner lease is not held', 503);
64
65
  return true;
65
66
  };
@@ -99,7 +100,7 @@ export function createTransportRoutes({
99
100
 
100
101
  const register = async (req, res) => {
101
102
  const body = await readBody(req);
102
- if (refuseUnadmitted(res)) return;
103
+ if (await refuseUnadmitted(res)) return;
103
104
  if (drain.committed) {
104
105
  sendError(res, `daemon is draining: ${drain.reason}`, 503);
105
106
  return;
@@ -150,7 +151,7 @@ export function createTransportRoutes({
150
151
  };
151
152
 
152
153
  const call = async (req, res) => {
153
- if (refuseUnadmitted(res)) return;
154
+ if (await refuseUnadmitted(res)) return;
154
155
  if (drain.committed) {
155
156
  sendError(res, `daemon is draining: ${drain.reason}`, 503);
156
157
  return;
@@ -158,7 +159,7 @@ export function createTransportRoutes({
158
159
  const body = await readBody(req);
159
160
  // Again right before dispatch: the lease may have been fenced while the
160
161
  // body was still arriving.
161
- if (refuseUnadmitted(res)) return;
162
+ if (await refuseUnadmitted(res)) return;
162
163
  await callRoute(body, res);
163
164
  };
164
165
 
@@ -8,6 +8,7 @@
8
8
  import { theme } from '../theme.mjs';
9
9
  import { displayModelName, effortDisplayLabel } from '../../runtime/shared/model-display.mjs';
10
10
  import { isRollingModelAlias } from '../../runtime/shared/model-alias.mjs';
11
+ import { describeError } from '../../runtime/shared/error-presentation.mjs';
11
12
  import { DAYBREAK_PROVIDER, daybreakBlueOn } from '../../runtime/shared/llm/openai-daybreak.mjs';
12
13
 
13
14
  export const parsedModelVersion = (id) => {
@@ -183,7 +184,7 @@ const PROVIDER_DISPLAY_NAMES = new Map([
183
184
  ['xai-api', 'xAI API'],
184
185
  ['deepseek', 'DeepSeek API'],
185
186
  ['deepseek-api', 'DeepSeek API'],
186
- ['opencode-go', 'OpenCode Go API'],
187
+ ['opencode-go-oauth', 'OpenCode Go OAuth'],
187
188
  ['openrouter', 'OpenRouter'],
188
189
  ['mixdog-local', 'Local Provider'],
189
190
  ['default', 'Default'],
@@ -220,6 +221,42 @@ export const loadProviderDisplayNames = async (store) => {
220
221
  return names;
221
222
  };
222
223
 
224
+ /** `{ id, text }` for each provider whose model list failed, with the reason
225
+ * (the setup row's `catalogError`) and what to do about it. */
226
+ export const loadProviderCatalogFailures = async (store) => {
227
+ let setup = null;
228
+ try {
229
+ setup = await store?.getProviderSetup?.();
230
+ } catch {
231
+ return [];
232
+ }
233
+ const failures = [];
234
+ for (const group of ['api', 'oauth', 'local']) {
235
+ for (const entry of Array.isArray(setup?.[group]) ? setup[group] : []) {
236
+ const failure = entry?.catalogError;
237
+ if (!failure?.message) continue;
238
+ const { summary, recovery } = describeError({ message: failure.message, errorKind: failure.errorKind });
239
+ failures.push({ id: String(entry.id || '').trim(), text: [summary, recovery].filter(Boolean).join(' ') });
240
+ }
241
+ }
242
+ return failures;
243
+ };
244
+
245
+ /** Provider-list rows for failed providers that have no model rows, so an
246
+ * empty provider says why instead of being absent. */
247
+ export const buildCatalogFailureItems = (failures, models, providerNames = null) =>
248
+ failures
249
+ .filter(({ id }) => id && !models.some((model) => model.provider === id))
250
+ .map(({ id, text }) => ({
251
+ value: `provider-failed:${id}`,
252
+ label: resolveProviderDisplayName(id, providerNames),
253
+ marker: '!',
254
+ markerColor: theme.error,
255
+ description: text,
256
+ _action: 'catalog-failed',
257
+ _failure: text,
258
+ }));
259
+
223
260
  const PROVIDER_DISPLAY_RANKS = {
224
261
  default: 0,
225
262
  'openai-oauth': 10,
@@ -230,7 +267,7 @@ const PROVIDER_DISPLAY_RANKS = {
230
267
  'mimo-oauth': 34,
231
268
  'antigravity-oauth': 31,
232
269
  'cursor-oauth': 32,
233
- 'opencode-go': 35,
270
+ 'opencode-go-oauth': 34.5,
234
271
  openai: 40,
235
272
  'openai-api': 40,
236
273
  anthropic: 50,
@@ -10,7 +10,13 @@
10
10
  * state (getState) is read through a getter so it always reflects the current
11
11
  * render.
12
12
  */
13
- import { normalizeModelOptions, buildModelProviderItems, loadProviderDisplayNames } from './model-options.mjs';
13
+ import {
14
+ normalizeModelOptions,
15
+ buildCatalogFailureItems,
16
+ buildModelProviderItems,
17
+ loadProviderCatalogFailures,
18
+ loadProviderDisplayNames,
19
+ } from './model-options.mjs';
14
20
  import { createModelCatalog } from './model-picker/catalog-load.mjs';
15
21
  import { openProviderModelsPicker, saveSelectedRoute } from './model-picker/provider-models-list.mjs';
16
22
 
@@ -78,6 +84,7 @@ export function createModelPicker({
78
84
 
79
85
  const models = normalizeModelOptions(providerModels);
80
86
  const providerNames = await loadProviderDisplayNames(store);
87
+ const catalogFailures = await loadProviderCatalogFailures(store);
81
88
  const activeRoute = options.currentRoute || {
82
89
  provider: state.provider,
83
90
  model: state.model,
@@ -116,7 +123,10 @@ export function createModelPicker({
116
123
  providerListHighlightProvider = renderOptions.highlightProvider;
117
124
  }
118
125
  const highlightProvider = renderOptions.highlightProvider || providerListHighlightProvider || null;
119
- const providerItems = buildModelProviderItems(models, activeRoute, providerNames);
126
+ const providerItems = [
127
+ ...buildModelProviderItems(models, activeRoute, providerNames),
128
+ ...buildCatalogFailureItems(catalogFailures, models, providerNames),
129
+ ];
120
130
  const providerHighlight = highlightProvider || activeRoute?.provider || null;
121
131
  const providerInitialIndex = Math.max(
122
132
  0,
@@ -133,6 +143,10 @@ export function createModelPicker({
133
143
  pickerKey: `model-picker:providers:${providerHighlight || 'default'}`,
134
144
  items: providerItems,
135
145
  onSelect: (_value, item) => {
146
+ if (item?._failure) {
147
+ store.pushNotice(`${item.label}: ${item._failure}`, 'warn');
148
+ return;
149
+ }
136
150
  if (!item?._provider) return;
137
151
  openProviderModelsPicker({
138
152
  view,
@@ -74,8 +74,7 @@ export function createProviderSetupPicker({
74
74
  setSettingsPrompt(null);
75
75
  // Close full-panel overlays too: they render ahead of providerPrompt in
76
76
  // the floating-panel chain, so a lingering usage/context panel would mask
77
- // any text-entry prompt opened from the provider actions (e.g. the
78
- // OpenCode Go cookie prompt appeared to do nothing).
77
+ // any text-entry prompt opened from the provider actions.
79
78
  own.context(null);
80
79
  closeUsagePanel();
81
80
  // Onboarding (and any caller) can pass a preloaded provider setup so we skip