mixdog 1.2.5 → 1.3.0

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/LICENSES/simple-icons-CC0-1.0.txt +30 -0
  2. package/NOTICE.md +19 -0
  3. package/package.json +4 -1
  4. package/scripts/check-model-recommendations.mjs +89 -0
  5. package/scripts/gate-local.mjs +7 -0
  6. package/scripts/lib/gate-scheduler.mjs +2 -2
  7. package/scripts/lib/isolated-test-env.mjs +16 -0
  8. package/scripts/lib/run-node-tests.mjs +5 -14
  9. package/scripts/provider-pingpong-live.mjs +9 -9
  10. package/src/agents/advisor/AGENT.md +4 -4
  11. package/src/agents/advisor/agent.json +1 -1
  12. package/src/agents/reviewer/AGENT.md +5 -4
  13. package/src/agents/reviewer/agent.json +1 -1
  14. package/src/defaults/shipped-history.json +17 -0
  15. package/src/defaults/skills/browser-use/SKILL.md +7 -1
  16. package/src/defaults/skills/computer-use/SKILL.md +3 -1
  17. package/src/defaults/skills/memory-management/SKILL.md +4 -1
  18. package/src/defaults/skills/setup/references/actions.md +11 -4
  19. package/src/defaults/skills/setup-guide/SKILL.md +175 -0
  20. package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
  21. package/src/defaults/skills/visualize/SKILL.md +3 -2
  22. package/src/lib/rules-builder.cjs +56 -7
  23. package/src/output-styles/common.md +22 -6
  24. package/src/output-styles/detailed.md +7 -5
  25. package/src/output-styles/minimal.md +7 -3
  26. package/src/output-styles/simple.md +2 -3
  27. package/src/rules/agent/AGENT.md +7 -1
  28. package/src/rules/agent-mode/AGENT_MODE.md +24 -0
  29. package/src/rules/agent-mode/MIXY.md +21 -0
  30. package/src/rules/agent-mode/ROUTINE.md +6 -0
  31. package/src/rules/lead/LEAD.md +9 -4
  32. package/src/rules/shared/10-tool-workflow.md +2 -1
  33. package/src/rules/shared/60-verification.md +4 -5
  34. package/src/rules/shared/70-delivery.md +3 -0
  35. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
  36. package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
  37. package/src/runtime/agent/orchestrator/config.mjs +6 -0
  38. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
  39. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +182 -13
  40. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +5 -3
  41. package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
  42. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +215 -0
  43. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +58 -64
  44. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
  45. package/src/runtime/agent/orchestrator/mcp/client.mjs +122 -15
  46. package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
  47. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
  48. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
  49. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
  50. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
  51. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
  52. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
  53. package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
  54. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
  55. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  56. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +41 -19
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +3 -2
  58. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +4 -1
  59. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +2 -0
  60. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
  61. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -1
  62. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -1
  63. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +11 -5
  64. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
  65. package/src/runtime/agent/orchestrator/providers/catalog-deadline.mjs +163 -0
  66. package/src/runtime/agent/orchestrator/providers/catalog-failures.mjs +34 -0
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +38 -14
  69. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +100 -26
  70. package/src/runtime/agent/orchestrator/providers/lib/send-callbacks.mjs +24 -0
  71. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -0
  72. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +2 -1
  73. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
  74. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +4 -0
  75. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  76. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  77. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +49 -4
  78. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -7
  79. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +7 -1
  80. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
  81. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -0
  82. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
  83. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
  84. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +5 -1
  85. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +11 -2
  86. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -0
  87. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +45 -16
  88. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
  89. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +1 -0
  90. package/src/runtime/agent/orchestrator/providers/openai-ws-connect.mjs +196 -0
  91. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +74 -9
  92. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +14 -1
  93. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -0
  94. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-login.mjs +194 -0
  95. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-tokens.mjs +353 -0
  96. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +293 -0
  97. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +33 -100
  98. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +23 -14
  99. package/src/runtime/agent/orchestrator/providers/registry.mjs +41 -27
  100. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +98 -4
  101. package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
  102. package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
  103. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +15 -8
  104. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
  105. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
  106. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
  107. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -4
  108. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +4 -1
  109. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +50 -20
  110. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
  111. package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
  112. package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
  113. package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
  114. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
  115. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
  116. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
  117. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +162 -0
  118. package/src/runtime/agent/orchestrator/session/agent-room.mjs +641 -0
  119. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
  120. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +74 -13
  121. package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +102 -0
  122. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +8 -2
  123. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +16 -0
  124. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
  125. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
  126. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +165 -0
  127. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
  128. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
  129. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
  130. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
  131. package/src/runtime/agent/orchestrator/session/lifecycle-scan.mjs +9 -0
  132. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
  133. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
  134. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
  135. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +16 -1
  136. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +82 -33
  137. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +11 -4
  138. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
  139. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
  140. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +7 -0
  141. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
  142. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +6 -1
  143. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  144. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
  145. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
  146. package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
  147. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +10 -7
  148. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -22
  149. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
  150. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
  151. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +23 -1
  152. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
  153. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
  154. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -5
  155. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +55 -8
  156. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
  157. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
  158. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
  159. package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
  160. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
  161. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +24 -0
  162. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
  163. package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -0
  164. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +70 -0
  165. package/src/runtime/agent/orchestrator/session/routine-result.mjs +277 -0
  166. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +16 -1
  167. package/src/runtime/agent/orchestrator/session/side-question.mjs +5 -43
  168. package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +10 -0
  169. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +73 -6
  170. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +40 -0
  171. package/src/runtime/agent/orchestrator/session/store/save-fault.mjs +15 -0
  172. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +12 -0
  173. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
  174. package/src/runtime/agent/orchestrator/session/store-agent-worker-header.mjs +36 -0
  175. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +258 -43
  176. package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +325 -0
  177. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +84 -21
  178. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
  179. package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
  180. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
  181. package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
  182. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +144 -45
  183. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +32 -13
  184. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +364 -38
  185. package/src/runtime/agent/orchestrator/session/store.mjs +9 -2
  186. package/src/runtime/agent/orchestrator/session/task-wait-control.mjs +43 -12
  187. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +23 -6
  188. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +44 -1
  189. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -6
  190. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +13 -7
  191. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +1 -1
  192. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -1
  193. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +40 -7
  194. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +37 -34
  195. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +1 -1
  196. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +0 -4
  197. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -0
  198. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +29 -27
  199. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +1 -1
  200. package/src/runtime/agent/orchestrator/tools/builtin/find-files-tool.mjs +28 -11
  201. package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +12 -3
  202. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +203 -101
  203. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +90 -41
  204. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +17 -1
  205. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-delivery.mjs +199 -0
  206. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
  207. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +165 -39
  208. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
  209. package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
  210. package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +7 -6
  211. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +19 -4
  212. package/src/runtime/agent/orchestrator/tools/builtin/read-line-collector.mjs +5 -3
  213. package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +25 -7
  214. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +2 -1
  215. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-render.mjs +3 -1
  216. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +12 -5
  217. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +61 -22
  218. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +32 -8
  219. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +193 -19
  220. package/src/runtime/agent/orchestrator/tools/builtin/shell-direct-exe.mjs +57 -7
  221. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +123 -32
  222. package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +26 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +13 -28
  224. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +90 -11
  225. package/src/runtime/agent/orchestrator/tools/builtin/wait-budgets.mjs +23 -0
  226. package/src/runtime/agent/orchestrator/tools/builtin.mjs +54 -10
  227. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +22 -28
  228. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +11 -7
  229. package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +126 -9
  230. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  231. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +15 -6
  232. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +64 -2
  233. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +10 -2
  234. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promotion-results.mjs +13 -3
  235. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +8 -0
  236. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -1
  237. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
  238. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +104 -55
  239. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +7 -2
  240. package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +39 -23
  241. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +6 -2
  242. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  243. package/src/runtime/attachments/office-extract.mjs +11 -9
  244. package/src/runtime/browser-bridge/client.mjs +24 -0
  245. package/src/runtime/channels/lib/scheduler.mjs +40 -12
  246. package/src/runtime/channels/lib/schedules-db.mjs +71 -12
  247. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
  248. package/src/runtime/channels/lib/webhook.mjs +0 -1
  249. package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
  250. package/src/runtime/channels/lib/worker-main.mjs +17 -20
  251. package/src/runtime/computer-bridge/client.mjs +28 -1
  252. package/src/runtime/connectors/gmail-app-password.mjs +690 -0
  253. package/src/runtime/connectors/google-mcp.mjs +446 -0
  254. package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
  255. package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
  256. package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
  257. package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
  258. package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
  259. package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
  260. package/src/runtime/memory/lib/embedding-tokenizer.mjs +32 -18
  261. package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
  262. package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
  263. package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
  264. package/src/runtime/memory/lib/memory.mjs +7 -1
  265. package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
  266. package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
  267. package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
  268. package/src/runtime/memory/lib/tool-call-handler.mjs +9 -5
  269. package/src/runtime/memory/tool-defs.mjs +5 -0
  270. package/src/runtime/office/authoring/pptx-script-normalize.mjs +11 -8
  271. package/src/runtime/office/core/tabular.mjs +1 -1
  272. package/src/runtime/office/design/library/design-template-inspect.mjs +7 -4
  273. package/src/runtime/office/portable/docx-formatting.mjs +1 -1
  274. package/src/runtime/office/portable/docx-runs.mjs +1 -1
  275. package/src/runtime/office/portable/docx-tracked-edits.mjs +2 -2
  276. package/src/runtime/office/portable/portable-docx-edits.mjs +11 -10
  277. package/src/runtime/office/portable/portable-docx-operations.mjs +21 -17
  278. package/src/runtime/office/portable/portable-docx-parts.mjs +15 -9
  279. package/src/runtime/office/portable/portable-docx-styles.mjs +4 -1
  280. package/src/runtime/office/portable/portable-docx-xml.mjs +9 -9
  281. package/src/runtime/office/portable/portable-opc.mjs +27 -13
  282. package/src/runtime/office/portable/portable-pivot.mjs +3 -3
  283. package/src/runtime/office/portable/portable-pptx-chart.mjs +3 -3
  284. package/src/runtime/office/portable/portable-pptx-charts.mjs +24 -18
  285. package/src/runtime/office/portable/portable-pptx-core.mjs +5 -5
  286. package/src/runtime/office/portable/portable-pptx-deck.mjs +8 -4
  287. package/src/runtime/office/portable/portable-pptx-package.mjs +7 -4
  288. package/src/runtime/office/portable/portable-pptx-shapes.mjs +18 -9
  289. package/src/runtime/office/portable/portable-sheet-parts.mjs +9 -3
  290. package/src/runtime/office/portable/portable-sheet-xml.mjs +5 -5
  291. package/src/runtime/office/portable/portable-xlsx-charts.mjs +4 -1
  292. package/src/runtime/office/portable/portable-xlsx-drawings.mjs +10 -6
  293. package/src/runtime/office/portable/portable-xlsx-operations.mjs +8 -5
  294. package/src/runtime/office/portable/portable-xlsx-pivot-ops.mjs +1 -1
  295. package/src/runtime/office/portable/portable-xlsx-reference-shift.mjs +11 -7
  296. package/src/runtime/office/portable/portable-xlsx-sheet-edits.mjs +6 -3
  297. package/src/runtime/office/portable/portable-xml.mjs +1 -1
  298. package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
  299. package/src/runtime/shared/agent-avatar.d.mts +64 -0
  300. package/src/runtime/shared/agent-avatar.mjs +320 -0
  301. package/src/runtime/shared/agent-route-config.d.mts +3 -0
  302. package/src/runtime/shared/agent-route-config.mjs +16 -0
  303. package/src/runtime/shared/atomic-file.mjs +36 -14
  304. package/src/runtime/shared/background-tasks.mjs +60 -20
  305. package/src/runtime/shared/child-spawn-gate.mjs +26 -16
  306. package/src/runtime/shared/config.mjs +8 -11
  307. package/src/runtime/shared/connector-accounts.mjs +15 -0
  308. package/src/runtime/shared/connector-catalog.d.mts +52 -0
  309. package/src/runtime/shared/connector-catalog.mjs +230 -0
  310. package/src/runtime/shared/connector-triggers.d.mts +3 -0
  311. package/src/runtime/shared/connector-triggers.mjs +43 -0
  312. package/src/runtime/shared/file-lock.mjs +7 -1
  313. package/src/runtime/shared/file-permissions-worker.mjs +38 -0
  314. package/src/runtime/shared/file-permissions.d.mts +19 -4
  315. package/src/runtime/shared/file-permissions.mjs +310 -4
  316. package/src/runtime/shared/git-runner-worker.mjs +6 -78
  317. package/src/runtime/shared/google-oauth-client.mjs +24 -0
  318. package/src/runtime/shared/held-request-host.d.mts +12 -0
  319. package/src/runtime/shared/held-request-host.mjs +71 -0
  320. package/src/runtime/shared/llm/http-agent.mjs +7 -3
  321. package/src/runtime/shared/llm/provider-catalog-registry.mjs +10 -0
  322. package/src/runtime/shared/llm/usage-accounting.mjs +2 -0
  323. package/src/runtime/shared/llm/usage-ledger-import.mjs +32 -3
  324. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +12 -5
  325. package/src/runtime/shared/llm/usage-ledger-worker.mjs +1 -1
  326. package/src/runtime/shared/llm/usage-ledger.mjs +20 -5
  327. package/src/runtime/shared/memory-snapshot.mjs +5 -1
  328. package/src/runtime/shared/notify-trace.mjs +8 -1
  329. package/src/runtime/shared/plain-preview.d.mts +1 -0
  330. package/src/runtime/shared/plain-preview.mjs +28 -0
  331. package/src/runtime/shared/pristine-execution-contract.json +5 -1
  332. package/src/runtime/shared/process-runner-worker.mjs +7 -0
  333. package/src/runtime/shared/process-runner.mjs +38 -0
  334. package/src/runtime/shared/provider-accounts.mjs +2 -1
  335. package/src/runtime/shared/provider-api-key.mjs +0 -1
  336. package/src/runtime/shared/read-row-numbers.mjs +1 -1
  337. package/src/runtime/shared/resource-admission.mjs +60 -18
  338. package/src/runtime/shared/routine-limits.d.mts +11 -0
  339. package/src/runtime/shared/routine-limits.mjs +21 -0
  340. package/src/runtime/shared/routine-trigger.d.mts +10 -0
  341. package/src/runtime/shared/routine-trigger.mjs +44 -0
  342. package/src/runtime/shared/run-child.mjs +84 -0
  343. package/src/runtime/shared/schedule-model-ref.mjs +9 -10
  344. package/src/runtime/shared/session-activity-signal.mjs +23 -0
  345. package/src/runtime/shared/shell-output-summary.mjs +23 -0
  346. package/src/runtime/shared/singleton-owner.mjs +126 -42
  347. package/src/runtime/shared/slow-span.mjs +4 -12
  348. package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
  349. package/src/runtime/shared/tool-output-limit.mjs +4 -2
  350. package/src/runtime/shared/tool-output-marker.mjs +58 -0
  351. package/src/runtime/shared/transcript-metadata.mjs +10 -0
  352. package/src/runtime/shared/turn-changes.mjs +0 -8
  353. package/src/runtime/shared/usage-readout-totals.mjs +56 -0
  354. package/src/runtime/shared/user-data-guard.mjs +131 -34
  355. package/src/runtime/shared/worktrees/activity-gate.mjs +33 -8
  356. package/src/runtime/shared/worktrees/git-head.mjs +20 -2
  357. package/src/runtime/shared/worktrees/lock.mjs +3 -2
  358. package/src/runtime/terminal-bridge/tool-defs.mjs +1 -1
  359. package/src/runtime/tidy/runners/biome.mjs +3 -1
  360. package/src/runtime/tidy/shadow.mjs +2 -1
  361. package/src/runtime/web-search/index.mjs +5 -7
  362. package/src/runtime/web-search/lib/formatter.mjs +42 -6
  363. package/src/runtime/web-search/tool-defs.mjs +6 -1
  364. package/src/session-runtime/agent-home-delivery.mjs +459 -0
  365. package/src/session-runtime/agent-profile-changes.mjs +21 -0
  366. package/src/session-runtime/agent-room-delivery.mjs +92 -0
  367. package/src/session-runtime/agent-task-sessions.mjs +200 -0
  368. package/src/session-runtime/boot/apis.mjs +50 -18
  369. package/src/session-runtime/boot/facade.mjs +5 -8
  370. package/src/session-runtime/boot/infrastructure.mjs +28 -17
  371. package/src/session-runtime/boot/tools.mjs +3 -0
  372. package/src/session-runtime/channel-config-api.mjs +53 -5
  373. package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
  374. package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
  375. package/src/session-runtime/held-requests.mjs +228 -0
  376. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
  377. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
  378. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
  379. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +31 -2
  380. package/src/session-runtime/internal-tool-executor.mjs +2 -0
  381. package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
  382. package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +4 -3
  383. package/src/session-runtime/lifecycle/session-switch/resume.mjs +11 -4
  384. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
  385. package/src/session-runtime/lifecycle/shared.mjs +25 -2
  386. package/src/session-runtime/lifecycle/teardown/session-close.mjs +2 -0
  387. package/src/session-runtime/lifecycle/teardown.mjs +5 -2
  388. package/src/session-runtime/lifecycle-api.mjs +3 -1
  389. package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
  390. package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
  391. package/src/session-runtime/mcp-oauth-login.mjs +112 -15
  392. package/src/session-runtime/model-route/set-route.mjs +14 -3
  393. package/src/session-runtime/owned-automation-run.mjs +229 -0
  394. package/src/session-runtime/provider-auth/login.mjs +10 -6
  395. package/src/session-runtime/provider-auth/setup.mjs +19 -2
  396. package/src/session-runtime/provider-catalog-cache.mjs +101 -25
  397. package/src/session-runtime/provider-models/catalog-load.mjs +14 -3
  398. package/src/session-runtime/provider-models/row-hydration.mjs +4 -0
  399. package/src/session-runtime/provider-models.mjs +76 -10
  400. package/src/session-runtime/provider-readiness.mjs +4 -0
  401. package/src/session-runtime/resource-api.mjs +5 -0
  402. package/src/session-runtime/resource-mcp-api.mjs +107 -13
  403. package/src/session-runtime/resource-skills-api.mjs +12 -0
  404. package/src/session-runtime/room-member-gate.mjs +48 -0
  405. package/src/session-runtime/routine-home-turn.mjs +156 -0
  406. package/src/session-runtime/routine-owner.mjs +48 -0
  407. package/src/session-runtime/schedule-session-run.mjs +30 -64
  408. package/src/session-runtime/services/agent-tool/close-flow.mjs +2 -1
  409. package/src/session-runtime/services/agent-tool/helpers.mjs +10 -0
  410. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +10 -2
  411. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +13 -4
  412. package/src/session-runtime/services/agent-tool/notify.mjs +15 -4
  413. package/src/session-runtime/services/agent-tool/restart-notify.mjs +134 -0
  414. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -1
  415. package/src/session-runtime/services/agent-tool/spawn-flow/deferred-spawn.mjs +2 -1
  416. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -3
  417. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
  418. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
  419. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -1
  420. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +8 -3
  421. package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -0
  422. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +4 -0
  423. package/src/session-runtime/services/agent-tool/worker-index.mjs +44 -10
  424. package/src/session-runtime/services/agent-tool.mjs +20 -0
  425. package/src/session-runtime/services/channel-admin.mjs +93 -24
  426. package/src/session-runtime/services/memory-access.mjs +37 -0
  427. package/src/session-runtime/services/provider-admin.mjs +166 -59
  428. package/src/session-runtime/services/schedule-access.mjs +91 -0
  429. package/src/session-runtime/services/usage-dashboard-model.mjs +2 -2
  430. package/src/session-runtime/services/usage-dashboard.mjs +27 -69
  431. package/src/session-runtime/session-create/session-options.mjs +34 -7
  432. package/src/session-runtime/session-hooks.mjs +16 -8
  433. package/src/session-runtime/setup-tool/executor.mjs +68 -6
  434. package/src/session-runtime/setup-tool/extended-actions.mjs +72 -14
  435. package/src/session-runtime/setup-tool/settings-contract.mjs +8 -6
  436. package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
  437. package/src/session-runtime/skills-api.mjs +16 -1
  438. package/src/session-runtime/tool-policy-refresh.mjs +238 -29
  439. package/src/session-runtime/turn/session-ops.mjs +10 -3
  440. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +11 -2
  441. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +3 -0
  442. package/src/session-runtime/usage-stats-api.mjs +6 -1
  443. package/src/session-runtime/webhook-session-run.mjs +49 -67
  444. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
  445. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +556 -22
  446. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
  447. package/src/session-runtime/workflow-agents-api.mjs +4 -1
  448. package/src/standalone/channel-transport/http-routes.mjs +10 -9
  449. package/src/standalone/daemon-agent-control.mjs +1 -8
  450. package/src/standalone/daemon-desktop-runtime.mjs +20 -7
  451. package/src/standalone/daemon-owner.mjs +117 -25
  452. package/src/standalone/daemon-session-control.mjs +11 -2
  453. package/src/standalone/daemon.mjs +61 -17
  454. package/src/standalone/session-call-cache.mjs +6 -0
  455. package/src/standalone/session-protocol.mjs +28 -1
  456. package/src/standalone/session-service/retention/busy.mjs +7 -2
  457. package/src/standalone/session-service/session-calls/session-turns.mjs +9 -0
  458. package/src/standalone/session-service.mjs +19 -0
  459. package/src/standalone/session-transport/routes.mjs +7 -6
  460. package/src/tui/app/model-options.mjs +39 -2
  461. package/src/tui/app/model-picker.mjs +16 -2
  462. package/src/tui/app/provider-setup-picker.mjs +1 -2
  463. package/src/tui/app/slash-commands.mjs +20 -0
  464. package/src/tui/dist/index.mjs +487 -128
  465. package/src/tui/session/context-state.mjs +6 -1
  466. package/src/tui/session/notice-surface.mjs +35 -4
  467. package/src/tui/session/notice-text.mjs +0 -1
  468. package/src/tui/session/queue-helpers.mjs +2 -1
  469. package/src/tui/session/session-api/extensions.mjs +4 -0
  470. package/src/tui/session/session-api/intake/submission.mjs +12 -13
  471. package/src/tui/session/session-api/integrations.mjs +9 -5
  472. package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
  473. package/src/tui/session/session-api/lifecycle.mjs +17 -1
  474. package/src/tui/session/session-api/routes.mjs +48 -3
  475. package/src/tui/session/session-flow/drain.mjs +20 -3
  476. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
  477. package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
  478. package/src/tui/session/session-flow/steering.mjs +104 -24
  479. package/src/tui/session/session-flow.mjs +2 -0
  480. package/src/tui/session/tool-approval.mjs +26 -5
  481. package/src/tui/session/transcript-intake.mjs +6 -2
  482. package/src/tui/session/transcript-spill.mjs +5 -1
  483. package/src/tui/session/tui-steering-persist.mjs +65 -42
  484. package/src/tui/session/turn-live-call.mjs +56 -0
  485. package/src/tui/session/turn-stream.mjs +33 -0
  486. package/src/tui/session/turn.mjs +50 -7
  487. package/src/ui/statusline.mjs +1 -6
  488. package/src/ui/streaming-markdown-heal.mjs +24 -7
  489. package/src/vendor/statusline/bin/statusline-route.mjs +0 -1
  490. package/src/vendor/statusline/src/gateway/route-meta.mjs +0 -1
  491. package/src/workflows/default/WORKFLOW.md +9 -13
  492. package/src/session-runtime/automation-agents.mjs +0 -94
  493. package/src/session-runtime/automation-workflow.mjs +0 -59
@@ -31,17 +31,61 @@ function escapeHtml(value) {
31
31
  .replaceAll("'", ''');
32
32
  }
33
33
 
34
- function renderPage({ heading, message, details }) {
35
- const title = escapeHtml(heading);
34
+ // The callback servers do not know the app language, so the default is
35
+ // bilingual (Korean first). A known language picks one copy.
36
+ const COPY = {
37
+ ko: {
38
+ successTitle: '로그인 완료',
39
+ successBody: (name) => `${name} 로그인이 완료되었습니다. 이 탭을 닫고 Mixdog로 돌아가 주세요.`,
40
+ failureTitle: '로그인 실패',
41
+ failureBody: 'Mixdog로 돌아가 다시 시도해 주세요.',
42
+ reason: '사유',
43
+ close: '닫기',
44
+ },
45
+ en: {
46
+ successTitle: 'Sign-in complete',
47
+ successBody: (name) => `You are signed in to ${name}. You can close this tab and return to Mixdog.`,
48
+ failureTitle: 'Sign-in failed',
49
+ failureBody: 'Return to Mixdog and try again.',
50
+ reason: 'Reason',
51
+ close: 'Close',
52
+ },
53
+ };
54
+
55
+ function renderPage({ kind, providerName, reason, lang }) {
56
+ const langs = lang === 'ko' || lang === 'en' ? [lang] : ['ko', 'en'];
57
+ const blocks = langs
58
+ .map((code, index) => {
59
+ const copy = COPY[code];
60
+ const title = kind === 'success' ? copy.successTitle : copy.failureTitle;
61
+ const body = kind === 'success' ? copy.successBody(providerName) : copy.failureBody;
62
+ const tag = index === 0 ? 'h1' : 'h2';
63
+ return `<section lang="${code}" class="${index === 0 ? 'primary' : 'secondary'}">
64
+ <${tag}>${escapeHtml(title)}</${tag}>
65
+ <p>${escapeHtml(body)}</p>
66
+ </section>`;
67
+ })
68
+ .join('\n ');
69
+ const reasonBlock = reason
70
+ ? `<div class="reason"><span>${langs.map((code) => COPY[code].reason).join(' / ')}</span>${escapeHtml(reason)}</div>`
71
+ : '';
72
+ const close = langs.map((code) => COPY[code].close).join(' · ');
73
+ const documentTitle = escapeHtml(
74
+ `${langs.map((code) => COPY[code][kind === 'success' ? 'successTitle' : 'failureTitle']).join(' / ')} · Mixdog`
75
+ );
36
76
  return `<!doctype html>
37
- <html lang="en">
77
+ <html lang="${langs[0]}">
38
78
  <head>
39
79
  <meta charset="utf-8" />
40
80
  <meta name="viewport" content="width=device-width, initial-scale=1" />
41
- <title>${title} · Mixdog</title>
81
+ <meta name="color-scheme" content="dark light" />
82
+ <title>${documentTitle}</title>
42
83
  <style>
84
+ :root { --bg: #f6f7f9; --fg: #0f172a; --muted: #475569; --card: #ffffff; --line: #d9dee6; --ok: #15803d; --bad: #b91c1c; --link: #1d4ed8; }
85
+ @media (prefers-color-scheme: dark) {
86
+ :root { --bg: #07080b; --fg: #f8fafc; --muted: #94a3b8; --card: #0f1116; --line: #232733; --ok: #4ade80; --bad: #f87171; --link: #93c5fd; }
87
+ }
43
88
  * { box-sizing: border-box; }
44
- html { color-scheme: dark; }
45
89
  body {
46
90
  margin: 0;
47
91
  min-height: 100vh;
@@ -49,32 +93,65 @@ function renderPage({ heading, message, details }) {
49
93
  align-items: center;
50
94
  justify-content: center;
51
95
  padding: 24px;
52
- background: #07080b;
53
- color: #f8fafc;
54
- font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
96
+ background: var(--bg);
97
+ color: var(--fg);
98
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo", "Noto Sans KR", Roboto, Arial, sans-serif;
55
99
  text-align: center;
56
100
  }
57
- main { width: 100%; max-width: 560px; display: flex; flex-direction: column; align-items: center; }
58
- .logo { width: 72px; height: 72px; margin-bottom: 24px; }
101
+ main {
102
+ width: 100%;
103
+ max-width: 520px;
104
+ padding: 40px 32px 32px;
105
+ background: var(--card);
106
+ border: 1px solid var(--line);
107
+ border-radius: 16px;
108
+ display: flex;
109
+ flex-direction: column;
110
+ align-items: center;
111
+ }
112
+ .logo { width: 72px; height: 72px; margin-bottom: 20px; }
59
113
  .logo svg { width: 100%; height: 100%; display: block; }
60
- h1 { margin: 0 0 10px; font-size: 28px; line-height: 1.15; font-weight: 650; }
61
- p { margin: 0; line-height: 1.7; color: #94a3b8; font-size: 15px; }
62
- .details {
63
- margin-top: 16px;
64
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
114
+ h1, h2 { margin: 0 0 6px; line-height: 1.2; font-weight: 650; }
115
+ h1 { font-size: 28px; color: ${kind === 'success' ? 'var(--ok)' : 'var(--bad)'}; }
116
+ h2 { font-size: 16px; color: var(--muted); font-weight: 600; }
117
+ p { margin: 0; line-height: 1.7; color: var(--muted); font-size: 15px; }
118
+ section.secondary { margin-top: 18px; }
119
+ .reason {
120
+ margin-top: 20px;
121
+ width: 100%;
122
+ padding: 12px 14px;
123
+ border: 1px solid var(--line);
124
+ border-radius: 10px;
125
+ text-align: left;
126
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
65
127
  font-size: 13px;
66
- color: #94a3b8;
128
+ color: var(--fg);
67
129
  white-space: pre-wrap;
68
130
  word-break: break-word;
69
131
  }
132
+ .reason span { display: block; margin-bottom: 4px; color: var(--muted); font-family: inherit; font-size: 12px; }
133
+ button {
134
+ margin-top: 24px;
135
+ min-width: 120px;
136
+ height: 40px;
137
+ padding: 0 20px;
138
+ border: 1px solid var(--line);
139
+ border-radius: 10px;
140
+ background: transparent;
141
+ color: var(--fg);
142
+ font: inherit;
143
+ font-size: 14px;
144
+ cursor: pointer;
145
+ }
146
+ button:hover { border-color: var(--muted); }
70
147
  </style>
71
148
  </head>
72
149
  <body>
73
150
  <main>
74
151
  <div class="logo">${LOGO_SVG}</div>
75
- <h1>${title}</h1>
76
- <p>${escapeHtml(message)}</p>
77
- ${details ? `<div class="details">${escapeHtml(details)}</div>` : ''}
152
+ ${blocks}
153
+ ${reasonBlock}
154
+ <button type="button" onclick="window.close()">${escapeHtml(close)}</button>
78
155
  </main>
79
156
  </body>
80
157
  </html>`;
@@ -82,13 +159,10 @@ function renderPage({ heading, message, details }) {
82
159
 
83
160
  export const OAUTH_PAGE_CONTENT_TYPE = 'text/html; charset=utf-8';
84
161
 
85
- export function oauthSuccessHtml(providerName) {
86
- return renderPage({
87
- heading: 'Authentication successful',
88
- message: `Signed in to ${providerName}. You can close this tab and return to Mixdog.`,
89
- });
162
+ export function oauthSuccessHtml(providerName, { lang } = {}) {
163
+ return renderPage({ kind: 'success', providerName, lang });
90
164
  }
91
165
 
92
- export function oauthErrorHtml(message, details) {
93
- return renderPage({ heading: 'Authentication failed', message, details });
166
+ export function oauthErrorHtml(reason, { lang } = {}) {
167
+ return renderPage({ kind: 'failure', reason, lang });
94
168
  }
@@ -8,5 +8,29 @@ export function streamCallbacks(opts) {
8
8
  onToolCall: functionOrNull(opts.onToolCall),
9
9
  onTextDelta: functionOrNull(opts.onTextDelta),
10
10
  onTextReset: functionOrNull(opts.onTextReset),
11
+ onStreamItemStart: functionOrNull(opts.onStreamItemStart),
11
12
  };
12
13
  }
14
+
15
+ /** Tell the caller a provider output item started streaming: `{ kind: 'tool' }`
16
+ * for a client tool call whose arguments are still on the way, `{ kind:
17
+ * 'text', phase }` for an assistant message that names its phase
18
+ * (`commentary` / `final_answer`). A listener failure never reaches the
19
+ * stream. */
20
+ export function reportStreamItemStart(onStreamItemStart, detail) {
21
+ if (typeof onStreamItemStart !== 'function' || !detail) return;
22
+ try {
23
+ onStreamItemStart(detail);
24
+ } catch {}
25
+ }
26
+
27
+ const ASSISTANT_PHASES = new Set(['commentary', 'final_answer']);
28
+
29
+ /** What a Responses output item tells `reportStreamItemStart`: a client tool
30
+ * call, an assistant message carrying its phase, or nothing (null). */
31
+ export function responsesItemStart(item) {
32
+ const type = item?.type;
33
+ if (type === 'function_call' || type === 'custom_tool_call' || type === 'tool_search_call') return { kind: 'tool' };
34
+ if (type === 'message' && ASSISTANT_PHASES.has(item.phase)) return { kind: 'text', phase: item.phase };
35
+ return null;
36
+ }
@@ -5,6 +5,7 @@ import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
5
5
  import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs';
6
6
  import { cursorTokenExpiry } from './cursor-auth.mjs';
7
7
  import { isValidMuseCredentialDocument } from './muse-code-oauth-tokens.mjs';
8
+ import { isValidOpenCodeGoCredentialDocument } from './opencode-go-oauth-tokens.mjs';
8
9
  import { developerOptionEnabled, developerOptionForProvider } from '../../../shared/developer-options.mjs';
9
10
  import { modelProxyClientMode } from '../../../shared/model-proxy-mode.mjs';
10
11
 
@@ -198,6 +199,17 @@ function museCodeOAuthState() {
198
199
  );
199
200
  }
200
201
 
202
+ function openCodeGoOAuthState() {
203
+ const paths = [
204
+ boundProviderAuthPath('opencode-go-oauth') ||
205
+ process.env.OPENCODE_GO_OAUTH_CREDENTIALS_PATH ||
206
+ join(resolvePluginData(), 'opencode-go-oauth.json'),
207
+ ];
208
+ return memoProbe('opencode-go-oauth', paths, () =>
209
+ resolveProbeState(paths, (docs) => docs.some(isValidOpenCodeGoCredentialDocument))
210
+ );
211
+ }
212
+
201
213
  // Antigravity needs a resolved Cloud project alongside the tokens: without it
202
214
  // every request 400s, so a half-finished login must not enable the provider.
203
215
  function antigravityOAuthState() {
@@ -270,6 +282,7 @@ const OAUTH_PROBE_STATES = new Map([
270
282
  ['mimo-oauth', mimoOAuthState],
271
283
  ['cursor-oauth', cursorOAuthState],
272
284
  ['antigravity-oauth', antigravityOAuthState],
285
+ ['opencode-go-oauth', openCodeGoOAuthState],
273
286
  ]);
274
287
 
275
288
  // Dev-only OAuth providers (Antigravity, Cursor). Each is hidden and treated as
@@ -869,7 +869,8 @@ async function measureUsage(provider, providerObj, routeInfo) {
869
869
  provider === 'cursor-api' ||
870
870
  provider === 'antigravity-oauth' ||
871
871
  provider === 'muse-code-oauth' ||
872
- provider === 'command-code-oauth') &&
872
+ provider === 'command-code-oauth' ||
873
+ provider === 'opencode-go-oauth') &&
873
874
  typeof providerObj?.getUsageSnapshot === 'function'
874
875
  ) {
875
876
  return await providerObj.getUsageSnapshot();
@@ -187,6 +187,7 @@ export async function sendCompatChat(provider, messages, useModel, tools, opts)
187
187
  onStreamDelta: opts.onStreamDelta,
188
188
  onToolCall: opts.onToolCall,
189
189
  onTextDelta: opts.onTextDelta,
190
+ onStreamItemStart: opts.onStreamItemStart,
190
191
  parseToolCalls,
191
192
  // Known tool names for the leaked-tool-call guard:
192
193
  // recovered leaked calls only synthesize when they name
@@ -4,6 +4,7 @@
4
4
  * reasoning aliases, tool_calls deltas, finish reason and usage.
5
5
  */
6
6
  import { mergeToolCallDelta } from './tool-call-acc.mjs';
7
+ import { reportStreamItemStart } from '../lib/send-callbacks.mjs';
7
8
  import { appendText, drainLeakedCalls, relayText, reportProgress, reportTransport } from './stream-state.mjs';
8
9
  import { chatContentParts } from '../openai-compat-reasoning-field.mjs';
9
10
 
@@ -58,7 +59,10 @@ export function applyCompatChunk(state, chunk) {
58
59
  if (Array.isArray(delta?.tool_calls) && delta.tool_calls.length) {
59
60
  reportProgress(state, 'tool');
60
61
  }
62
+ const toolsBefore = state.toolAcc.byKey.size;
61
63
  mergeToolCallDelta(state.toolAcc, delta?.tool_calls);
64
+ // A tool call's first delta: its arguments are still streaming.
65
+ if (state.toolAcc.byKey.size > toolsBefore) reportStreamItemStart(state.onStreamItemStart, { kind: 'tool' });
62
66
  if (choice?.finish_reason) {
63
67
  state.stopReason = choice.finish_reason;
64
68
  drainLeakedCalls(state);
@@ -22,6 +22,7 @@ export function createCompatStreamState({
22
22
  onStreamDelta,
23
23
  onToolCall,
24
24
  onTextDelta,
25
+ onStreamItemStart,
25
26
  }) {
26
27
  const toolDedupe = createToolCallDedupe();
27
28
  return {
@@ -30,6 +31,7 @@ export function createCompatStreamState({
30
31
  onStreamDelta,
31
32
  onToolCall,
32
33
  onTextDelta,
34
+ onStreamItemStart,
33
35
  semanticIdleDeadlineAt: 0,
34
36
  sawFirstEvent: false,
35
37
  content: '',
@@ -86,7 +88,7 @@ export function isIncompleteFinishReason(finishReason) {
86
88
 
87
89
  /** Whether `finish_reason` confirms a normal end of the turn: present, not an
88
90
  * incomplete outcome and not a gateway-reported failure (network_error/error). */
89
- export function isNormalFinishReason(finishReason) {
91
+ function isNormalFinishReason(finishReason) {
90
92
  return (
91
93
  Boolean(finishReason) && !isIncompleteFinishReason(finishReason) && !failingFinishReasonError(finishReason, '')
92
94
  );
@@ -39,6 +39,7 @@ export async function consumeCompatChatCompletionStream(
39
39
  onStreamDelta,
40
40
  onToolCall,
41
41
  onTextDelta,
42
+ onStreamItemStart,
42
43
  parseToolCalls,
43
44
  knownToolNames,
44
45
  semanticIdleTimeoutMs,
@@ -55,6 +56,7 @@ export async function consumeCompatChatCompletionStream(
55
56
  onStreamDelta,
56
57
  onToolCall,
57
58
  onTextDelta,
59
+ onStreamItemStart,
58
60
  });
59
61
  reportTransport(state);
60
62
  const iterator = stream[Symbol.asyncIterator]();
@@ -47,23 +47,68 @@ export function extractCompatReasoningEffort(model) {
47
47
  return null;
48
48
  }
49
49
 
50
+ const ERROR_BODY_LIMIT = 4096;
51
+ // An echoed key prefix this long (or the whole key, if shorter) is redacted.
52
+ const ECHOED_KEY_PREFIX_MIN = 8;
53
+
54
+ // Replaces the request key, and any run of its first ECHOED_KEY_PREFIX_MIN or
55
+ // more characters ("Incorrect API key provided: xai-abcd****"), in `value`.
56
+ function redactRequestKey(value, key) {
57
+ if (!key) return value;
58
+ const min = Math.min(ECHOED_KEY_PREFIX_MIN, key.length);
59
+ let out = '';
60
+ for (let i = 0; i < value.length; ) {
61
+ let n = 0;
62
+ while (n < key.length && value[i + n] === key[n]) n += 1;
63
+ if (n >= min) {
64
+ out += '[redacted]';
65
+ i += n;
66
+ } else {
67
+ out += value[i];
68
+ i += 1;
69
+ }
70
+ }
71
+ return out;
72
+ }
73
+
74
+ // A refused /models request keeps the provider's own reason (status plus the
75
+ // body's code/type/message) so the UI can say why the list is empty. The
76
+ // message stays `<name> models <status>`; the body rides on `providerError`,
77
+ // with the request key (`apiKey`) redacted from it.
78
+ async function compatModelsError(name, res, apiKey = '') {
79
+ const error = Object.assign(new Error(`${name} models ${res.status}`), { status: res.status });
80
+ try {
81
+ const body = JSON.parse((await res.text()).slice(0, ERROR_BODY_LIMIT));
82
+ const nested = body?.error && typeof body.error === 'object' ? body.error : null;
83
+ const text = (value) => (typeof value === 'string' && value ? redactRequestKey(value, apiKey) : undefined);
84
+ const providerError = {
85
+ message: text(body?.error) ?? text(nested?.message) ?? text(body?.message),
86
+ code: text(nested?.code) ?? text(body?.code),
87
+ type: text(nested?.type) ?? text(body?.type),
88
+ };
89
+ if (providerError.message || providerError.code || providerError.type) error.providerError = providerError;
90
+ } catch {
91
+ // A body that is not JSON adds no detail.
92
+ }
93
+ return error;
94
+ }
95
+
50
96
  // `keyless` omits the Authorization header entirely (keyless endpoints);
51
97
  // `signal` aborts the request together with the list timeout.
52
98
  export async function fetchCompatModelItems(provider, { signal = null, keyless = false } = {}) {
53
99
  const name = provider.name;
54
100
  const timeout = createTimeoutSignal(signal, MODEL_LIST_TIMEOUT_MS, `${name} model list`);
55
101
  try {
102
+ const apiKey = keyless ? '' : resolveProviderApiKey(name, provider.config || provider);
56
103
  const res = await fetch(`${String(provider.baseURL || '').replace(/\/+$/, '')}/models`, {
57
104
  method: 'GET',
58
105
  headers: {
59
- ...(keyless
60
- ? {}
61
- : { Authorization: `Bearer ${resolveProviderApiKey(name, provider.config || provider) || 'no-key'}` }),
106
+ ...(keyless ? {} : { Authorization: `Bearer ${apiKey || 'no-key'}` }),
62
107
  ...(provider.defaultHeaders || {}),
63
108
  },
64
109
  signal: timeout.signal,
65
110
  });
66
- if (!res.ok) throw Object.assign(new Error(`${provider.name} models ${res.status}`), { status: res.status });
111
+ if (!res.ok) throw await compatModelsError(provider.name, res, apiKey);
67
112
  const data = await res.json();
68
113
  if (Array.isArray(data?.data)) return data.data;
69
114
  if (Array.isArray(data)) return data;
@@ -9,13 +9,6 @@ export const OPENAI_COMPAT_PRESETS = {
9
9
  baseURL: 'https://api.x.ai/v1',
10
10
  defaultModel: 'grok-4.5',
11
11
  },
12
- // OpenCode Go - low-cost coding-model subscription gateway.
13
- 'opencode-go': {
14
- baseURL: 'https://opencode.ai/inference/go/v1',
15
- defaultModel: 'glm-5.2',
16
- // The gateway expects an application User-Agent (not the SDK default).
17
- extraHeaders: { 'User-Agent': 'mixdog' },
18
- },
19
12
  openrouter: {
20
13
  baseURL: 'https://openrouter.ai/api/v1',
21
14
  defaultModel: 'openrouter/auto',
@@ -14,6 +14,7 @@ import { truncatedCompatStreamError, parseCompletedToolCallArgumentsJson } from
14
14
  import { incompleteReasonFromEvent, isMaxOutputIncompleteReason } from './lib/responses-terminal-fields.mjs';
15
15
  import { responsesUsage } from './openai-compat-response-normalization.mjs';
16
16
  import { normalizeGatewayErrorDetail } from './provider-error-kind.mjs';
17
+ import { reportStreamItemStart, responsesItemStart } from './lib/send-callbacks.mjs';
17
18
 
18
19
  // An incomplete response was still billed: carry its reported usage on the
19
20
  // error so the provider-boundary accounting records it.
@@ -194,6 +195,7 @@ function onOutputItemAdded(event, state, ctx) {
194
195
  state.toolTracker?.mark(event.item);
195
196
  state.toolInFlight = true;
196
197
  }
198
+ reportStreamItemStart(ctx.onStreamItemStart, responsesItemStart(event.item));
197
199
  signal(ctx, state.toolInFlight ? 'tool' : 'semantic');
198
200
  }
199
201
 
@@ -249,7 +251,11 @@ function onRefusalDone(event, state, ctx) {
249
251
 
250
252
  function onOutputItemDone(event, state, ctx) {
251
253
  const item = event.item || {};
252
- if (item.type === 'message') refusalsOf(state).absorbMessage(item);
254
+ if (item.type === 'message') {
255
+ refusalsOf(state).absorbMessage(item);
256
+ // A stream that names the phase only on the finished item.
257
+ reportStreamItemStart(ctx.onStreamItemStart, responsesItemStart(item));
258
+ }
253
259
  if (item.type === 'function_call') {
254
260
  const itemId = reconcileCompatFunctionCallItem(state, item, ctx.label, ctx.onToolCall);
255
261
  // Drop the resolved function item from pendingCalls before
@@ -243,6 +243,7 @@ async function streamCompatResponses({ provider, params, label, signal, opts, he
243
243
  onStreamDelta: opts.onStreamDelta,
244
244
  onToolCall: opts.onToolCall,
245
245
  onTextDelta: opts.onTextDelta,
246
+ onStreamItemStart: opts.onStreamItemStart,
246
247
  parseResponsesToolCalls,
247
248
  responseOutputText,
248
249
  knownToolNames: knownToolNamesFromResponsesTools(params.tools),
@@ -51,6 +51,7 @@ export async function consumeCompatResponsesStream(
51
51
  onStreamDelta,
52
52
  onToolCall,
53
53
  onTextDelta,
54
+ onStreamItemStart,
54
55
  parseResponsesToolCalls,
55
56
  responseOutputText,
56
57
  knownToolNames,
@@ -89,6 +90,7 @@ export async function consumeCompatResponsesStream(
89
90
  onStreamDelta: reportProgress,
90
91
  onToolCall,
91
92
  onTextDelta,
93
+ onStreamItemStart,
92
94
  relayLeakText,
93
95
  };
94
96
  const stampOutcome = createResponsesOutcomeStamper(state, leakedCalls);
@@ -134,6 +134,7 @@ export async function sendXaiResponses(provider, messages, useModel, tools, opts
134
134
  onStreamDelta: opts.onStreamDelta,
135
135
  onToolCall: opts.onToolCall,
136
136
  onTextDelta: opts.onTextDelta,
137
+ onStreamItemStart: opts.onStreamItemStart,
137
138
  parseResponsesToolCalls,
138
139
  responseOutputText,
139
140
  knownToolNames: knownToolNamesFromResponsesTools(params.tools),
@@ -14,14 +14,6 @@ import { retryAfterMsFromError, sleepWithAbort } from './retry-classifier.mjs';
14
14
 
15
15
  const isObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
16
16
 
17
- // Explicit quota / billing refusals: waiting never helps, so no retry layer
18
- // may treat them as an ordinary rate limit.
19
- const QUOTA_OR_BILLING_CODE_RE = /quota|billing|usage_limit|usage_not_included/;
20
-
21
- export function isQuotaOrBillingCode(code) {
22
- return QUOTA_OR_BILLING_CODE_RE.test(String(code || '').toLowerCase());
23
- }
24
-
25
17
  /**
26
18
  * Parse an HTTP error body ONCE into its contract fields. `message` is the
27
19
  * body's own message (untruncated); callers truncate for diagnostics.
@@ -211,7 +203,8 @@ export function applyErrorContract(err, { status, headers, code, error, event }
211
203
  err.status = n;
212
204
  err.httpStatus = n;
213
205
  }
214
- const wireHeaders = headers ?? error?.headers ?? event?.error?.headers ?? event?.response?.error?.headers ?? event?.headers;
206
+ const wireHeaders =
207
+ headers ?? error?.headers ?? event?.error?.headers ?? event?.response?.error?.headers ?? event?.headers;
215
208
  if (wireHeaders && typeof wireHeaders === 'object') err.headers = wireHeaders;
216
209
  const rawCode = code ?? error?.code ?? error?.type ?? null;
217
210
  if (typeof rawCode === 'string' && rawCode.trim()) err.code = rawCode.trim().toLowerCase();
@@ -225,7 +218,13 @@ export function applyErrorContract(err, { status, headers, code, error, event }
225
218
  if (err.retryAfterAt == null) err.retryAfterAt = Date.now() + retryAfterMs;
226
219
  }
227
220
  const type = typeof error?.type === 'string' ? error.type.trim().toLowerCase() : '';
228
- const mapped = typedWireErrorMessage({ code: err.code || '', type, error, headers: err.headers, resetAt: err.resetAt });
221
+ const mapped = typedWireErrorMessage({
222
+ code: err.code || '',
223
+ type,
224
+ error,
225
+ headers: err.headers,
226
+ resetAt: err.resetAt,
227
+ });
229
228
  if (mapped) applyTypedWireMessage(err, mapped, error?.message);
230
229
  } catch {}
231
230
  return err;
@@ -238,7 +237,12 @@ export function applyErrorContract(err, { status, headers, code, error, event }
238
237
  * makes unknown codes default-retryable).
239
238
  */
240
239
  export function markContentFilter(err, reason) {
241
- if (String(reason || '').trim().toLowerCase() !== 'content_filter') return err;
240
+ if (
241
+ String(reason || '')
242
+ .trim()
243
+ .toLowerCase() !== 'content_filter'
244
+ )
245
+ return err;
242
246
  err.code = 'content_filter';
243
247
  err.providerErrorCode = 'content_filter';
244
248
  return err;
@@ -260,7 +264,8 @@ export function httpResponseError({ label, status, headers, text, initialRespons
260
264
  }
261
265
 
262
266
  // The route decides the HTTP/SSE label: the api-key `openai` provider is not OAuth.
263
- export const httpLabel = (auth) => (auth?.type === 'openai-direct' ? 'OpenAI HTTP fallback' : 'OpenAI OAuth HTTP fallback');
267
+ export const httpLabel = (auth) =>
268
+ auth?.type === 'openai-direct' ? 'OpenAI HTTP fallback' : 'OpenAI OAuth HTTP fallback';
264
269
 
265
270
  /**
266
271
  * Changing transport must not bypass the server's retry deadline.
@@ -5,8 +5,9 @@
5
5
  */
6
6
  import { createOutputItemEvents } from './response-events/output-items.mjs';
7
7
  import { createTerminalFrameEvents } from './response-events/terminal-frames.mjs';
8
+ import { reportStreamItemStart, responsesItemStart } from '../lib/send-callbacks.mjs';
8
9
 
9
- export function createResponseEvents({ state, items, text, outcome, meaningful, onServerEvent }) {
10
+ export function createResponseEvents({ state, items, text, outcome, meaningful, onServerEvent, onStreamItemStart }) {
10
11
  const output = createOutputItemEvents({ state, items, meaningful });
11
12
  const terminal = createTerminalFrameEvents({ state, items, text, outcome, meaningful });
12
13
 
@@ -34,6 +35,7 @@ export function createResponseEvents({ state, items, text, outcome, meaningful,
34
35
  break;
35
36
  case 'response.output_item.added':
36
37
  output.onOutputItemAdded(event.item);
38
+ reportStreamItemStart(onStreamItemStart, responsesItemStart(event.item));
37
39
  break;
38
40
  case 'response.function_call_arguments.delta':
39
41
  case 'response.custom_tool_call_input.delta':
@@ -54,6 +56,8 @@ export function createResponseEvents({ state, items, text, outcome, meaningful,
54
56
  break;
55
57
  case 'response.output_item.done':
56
58
  output.onOutputItemDone(event.item || {});
59
+ // A stream that names the phase only on the finished message.
60
+ if (event.item?.type === 'message') reportStreamItemStart(onStreamItemStart, responsesItemStart(event.item));
57
61
  break;
58
62
  case 'response.completed':
59
63
  terminal.onCompleted(event);
@@ -25,13 +25,22 @@ import { createResponseEvents } from './openai-http-sse-response-state/response-
25
25
  * @param {(text: string) => void} [deps.onTextDelta]
26
26
  * @param {(kind: string) => void} deps.meaningful semantic progress (re-arms the idle watchdog)
27
27
  * @param {() => void} deps.onServerEvent first-event → semantic-idle handover
28
+ * @param {(detail: object) => void} [deps.onStreamItemStart] a tool call or phased message started
28
29
  */
29
- export function createHttpSseResponseState({ body, onToolCall, onTextDelta, meaningful, onServerEvent, label }) {
30
+ export function createHttpSseResponseState({
31
+ body,
32
+ onToolCall,
33
+ onTextDelta,
34
+ onStreamItemStart = null,
35
+ meaningful,
36
+ onServerEvent,
37
+ label,
38
+ }) {
30
39
  const state = createResponseState(label);
31
40
  const outcome = createResponseOutcome({ state });
32
41
  const items = createResponseItems({ state, onToolCall });
33
42
  const text = createTextRelay({ state, body, onTextDelta, meaningful, emitToolCall: items.emitToolCall });
34
- const events = createResponseEvents({ state, items, text, outcome, meaningful, onServerEvent });
43
+ const events = createResponseEvents({ state, items, text, outcome, meaningful, onServerEvent, onStreamItemStart });
35
44
 
36
45
  return {
37
46
  handleEvent: events.handleEvent,
@@ -195,6 +195,7 @@ export async function sendViaHttpSse({
195
195
  body,
196
196
  onToolCall,
197
197
  onTextDelta,
198
+ onStreamItemStart: typeof opts?.onStreamItemStart === 'function' ? opts.onStreamItemStart : null,
198
199
  meaningful,
199
200
  onServerEvent: watchdogs.noteServerEvent,
200
201
  label,