mixdog 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/package.json +3 -2
  2. package/scripts/build-shipped-history.mjs +115 -33
  3. package/scripts/gate-local.mjs +172 -61
  4. package/scripts/lib/gate-scheduler.mjs +138 -32
  5. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  6. package/scripts/lib/run-node-tests.mjs +54 -29
  7. package/scripts/lib/scoped-temp.mjs +1 -0
  8. package/scripts/lib/test-failure-records.mjs +14 -1
  9. package/scripts/lib/test-failure-summary.mjs +16 -4
  10. package/scripts/lib/test-spawn-ledger.mjs +12 -3
  11. package/scripts/pptx-kit-index.mjs +5 -6
  12. package/scripts/suite-health.mjs +110 -28
  13. package/scripts/test.mjs +9 -14
  14. package/src/agents/advisor/AGENT.md +4 -4
  15. package/src/agents/advisor/agent.json +1 -1
  16. package/src/agents/explore/AGENT.md +22 -0
  17. package/src/agents/explore/agent.json +6 -0
  18. package/src/cli.mjs +7 -0
  19. package/src/defaults/agents.json +7 -0
  20. package/src/defaults/shipped-history.json +18 -2
  21. package/src/defaults/skills/browser-use/SKILL.md +4 -1
  22. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  23. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  24. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  25. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  26. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  27. package/src/defaults/skills/computer-use/SKILL.md +12 -2
  28. package/src/defaults/skills/goal-management/SKILL.md +1 -1
  29. package/src/defaults/skills/setup/references/actions.md +12 -6
  30. package/src/defaults/skills/setup/references/surfaces.md +2 -2
  31. package/src/defaults/skills/setup-guide/SKILL.md +5 -2
  32. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  33. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  34. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  35. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  36. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  37. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  38. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  39. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  40. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  41. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  42. package/src/defaults/skills/visualize/SKILL.md +6 -2
  43. package/src/lib/rules-builder.cjs +6 -30
  44. package/src/rules/lead/LEAD.md +3 -3
  45. package/src/rules/shared/20-research.md +3 -6
  46. package/src/rules/shared/40-editing.md +1 -0
  47. package/src/rules/shared/60-verification.md +10 -9
  48. package/src/rules/shared/70-delivery.md +4 -3
  49. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  50. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -1
  51. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +130 -21
  52. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -0
  53. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  54. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  55. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
  56. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +5 -26
  57. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  58. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +122 -12
  59. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -3
  60. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +13 -2
  61. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +152 -58
  62. package/src/runtime/agent/orchestrator/mcp/client.mjs +51 -18
  63. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
  64. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +42 -26
  65. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
  66. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
  67. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
  69. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  70. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  71. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  73. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  74. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  75. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  76. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  77. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  78. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  79. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  80. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
  81. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  82. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  83. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  84. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  85. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  86. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  87. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
  88. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
  89. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
  90. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  91. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  92. package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
  93. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  94. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  95. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  96. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +567 -0
  97. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  98. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +2 -1
  99. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  100. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -0
  101. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +14 -5
  102. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  103. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  104. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  105. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
  106. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +3 -3
  107. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +10 -5
  108. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +5 -5
  109. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
  110. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  111. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -6
  112. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
  113. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +21 -2
  114. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +2 -0
  115. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  116. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  117. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +50 -28
  118. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +1 -0
  119. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +3 -4
  120. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
  121. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +7 -0
  122. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  123. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +25 -14
  124. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +17 -14
  125. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  126. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  127. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -3
  128. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +47 -29
  129. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  130. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +11 -5
  131. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
  132. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
  133. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  134. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +164 -4
  135. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  136. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  137. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +36 -26
  138. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +3 -5
  139. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  140. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  141. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +96 -20
  142. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  143. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  144. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  145. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  146. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +103 -13
  147. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  148. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  149. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  150. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +34 -10
  151. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
  152. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  153. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -2
  154. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  155. package/src/runtime/channels/lib/whisper-port.mjs +19 -10
  156. package/src/runtime/channels/lib/whisper-server.mjs +10 -1
  157. package/src/runtime/connectors/connector-accounts-mcp.mjs +236 -103
  158. package/src/runtime/connectors/gmail-app-password.mjs +3 -3
  159. package/src/runtime/explore/explorer.mjs +93 -0
  160. package/src/runtime/explore/tool-defs.mjs +35 -0
  161. package/src/runtime/explore/tool.mjs +123 -0
  162. package/src/runtime/memory/index.mjs +4 -0
  163. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  164. package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
  165. package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
  166. package/src/runtime/shared/agent-route-config.mjs +17 -2
  167. package/src/runtime/shared/atomic-file.mjs +103 -2
  168. package/src/runtime/shared/background-tasks.mjs +15 -6
  169. package/src/runtime/shared/connector-accounts.mjs +5 -5
  170. package/src/runtime/shared/connector-catalog.d.mts +11 -4
  171. package/src/runtime/shared/connector-catalog.mjs +60 -52
  172. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  173. package/src/runtime/shared/file-has-data.mjs +26 -2
  174. package/src/runtime/shared/file-lock.mjs +13 -15
  175. package/src/runtime/shared/git-launch.d.mts +9 -0
  176. package/src/runtime/shared/git-launch.mjs +213 -0
  177. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  178. package/src/runtime/shared/llm/cost.mjs +6 -1
  179. package/src/runtime/shared/llm/http-agent.mjs +313 -29
  180. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  181. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  182. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  183. package/src/runtime/shared/llm/system-proxy.mjs +452 -0
  184. package/src/runtime/shared/provider-accounts.mjs +52 -2
  185. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  186. package/src/runtime/shared/staged-update.mjs +47 -2
  187. package/src/runtime/shared/tool-surface.mjs +110 -36
  188. package/src/runtime/shared/tool-work-units.mjs +4 -0
  189. package/src/runtime/shared/turn-worktree-snapshot.mjs +414 -54
  190. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  191. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  192. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  193. package/src/runtime/shared/worktrees/branch-management.mjs +9 -3
  194. package/src/runtime/shared/worktrees/git.mjs +57 -0
  195. package/src/runtime/shared/worktrees/manager.mjs +205 -137
  196. package/src/runtime/tidy/install.mjs +95 -15
  197. package/src/runtime/tidy/languages.mjs +17 -15
  198. package/src/runtime/tidy/process.mjs +7 -4
  199. package/src/runtime/tidy/resolve.mjs +19 -16
  200. package/src/runtime/tidy/runners/biome.mjs +3 -3
  201. package/src/runtime/tidy/tool.mjs +1 -1
  202. package/src/runtime/tidy/worktree.mjs +10 -6
  203. package/src/runtime/visualize-bridge/client.mjs +4 -1
  204. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  205. package/src/runtime/web-search/index.mjs +1 -1
  206. package/src/session-runtime/agent-task-sessions.mjs +410 -353
  207. package/src/session-runtime/boot/tools.mjs +2 -0
  208. package/src/session-runtime/bot-status.mjs +103 -103
  209. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  210. package/src/session-runtime/conversation-import/discovery.mjs +159 -40
  211. package/src/session-runtime/conversation-import/service.mjs +9 -3
  212. package/src/session-runtime/handoff-attachments.mjs +1 -1
  213. package/src/session-runtime/held-requests.mjs +3 -1
  214. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -0
  215. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  216. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +143 -116
  217. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -1
  218. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  219. package/src/session-runtime/mcp-glue/server-catalog.mjs +16 -10
  220. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  221. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  222. package/src/session-runtime/provider-auth/login.mjs +2 -2
  223. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  224. package/src/session-runtime/resource-mcp-connector-accounts.mjs +44 -31
  225. package/src/session-runtime/resource-mcp-secrets.mjs +28 -11
  226. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  227. package/src/session-runtime/services/agent-tool/send-flow.mjs +10 -2
  228. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  229. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
  230. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  231. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  232. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  233. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  234. package/src/session-runtime/services/plugin-admin.mjs +10 -6
  235. package/src/session-runtime/services/provider-admin.mjs +281 -10
  236. package/src/session-runtime/session-turn-api.mjs +2 -0
  237. package/src/session-runtime/settings-builtin-tools-api.mjs +4 -1
  238. package/src/session-runtime/settings-system-api.mjs +1 -1
  239. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  240. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  241. package/src/session-runtime/setup-tool/executor.mjs +6 -2
  242. package/src/session-runtime/setup-tool/tool-defs.mjs +2 -1
  243. package/src/session-runtime/turn/agent-ops.mjs +23 -0
  244. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +49 -11
  245. package/src/session-runtime/workflow-agents-api/agent-route.mjs +10 -1
  246. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  247. package/src/session-runtime/workspace/session-view.mjs +149 -0
  248. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  249. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  250. package/src/session-runtime/workspace/transitions.mjs +108 -1066
  251. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  252. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  253. package/src/session-runtime/workspace/worktree-maintenance.mjs +80 -0
  254. package/src/session-runtime/workspace/worktree-setup.mjs +85 -0
  255. package/src/session-runtime/workspace/worktree-tool.mjs +54 -54
  256. package/src/standalone/daemon-desktop-runtime.mjs +2 -0
  257. package/src/standalone/daemon-session-control.mjs +151 -136
  258. package/src/standalone/daemon.mjs +7 -0
  259. package/src/standalone/desktop-service-registry.mjs +9 -0
  260. package/src/standalone/local-session-runtime.mjs +5 -1
  261. package/src/standalone/session-client/daemon-unavailable.mjs +3 -0
  262. package/src/standalone/session-client.mjs +5 -1
  263. package/src/standalone/session-frame-stream.mjs +83 -11
  264. package/src/standalone/session-protocol.mjs +4 -0
  265. package/src/standalone/session-service/agent-tree.mjs +45 -9
  266. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  267. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  268. package/src/standalone/session-service/stored-reader.mjs +127 -40
  269. package/src/tui/App.jsx +154 -164
  270. package/src/tui/app/app-view/floating-panel.jsx +3 -0
  271. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  272. package/src/tui/app/clipboard.mjs +21 -10
  273. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  274. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  275. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  276. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  277. package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
  278. package/src/tui/app/provider-setup-picker.mjs +20 -13
  279. package/src/tui/app/shell-layout/row-budgets.mjs +12 -10
  280. package/src/tui/app/slash-commands.mjs +1 -0
  281. package/src/tui/app/slash-dispatch/session-commands.mjs +46 -0
  282. package/src/tui/app/slash-dispatch.mjs +1 -1
  283. package/src/tui/app/use-btw-panel.mjs +29 -0
  284. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  285. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  286. package/src/tui/app/use-mouse-input.mjs +11 -0
  287. package/src/tui/app/use-onboarding-start.mjs +8 -3
  288. package/src/tui/app/use-panel-transition.mjs +10 -1
  289. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  290. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  291. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  292. package/src/tui/app/use-prompt-queue-history.mjs +3 -2
  293. package/src/tui/app/use-selection-focus.mjs +11 -2
  294. package/src/tui/app/use-selection-geometry.mjs +18 -9
  295. package/src/tui/app/use-selection-paint.mjs +4 -4
  296. package/src/tui/app/use-selection-stitch.mjs +3 -3
  297. package/src/tui/app/use-slash-palette.mjs +62 -0
  298. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  299. package/src/tui/app/use-transcript-activity.mjs +47 -32
  300. package/src/tui/app/use-transcript-follow.mjs +12 -4
  301. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  302. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  303. package/src/tui/app/use-transcript-window/geometry.mjs +19 -5
  304. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  305. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  306. package/src/tui/app/use-transcript-window.mjs +21 -11
  307. package/src/tui/app/use-tui-ready.mjs +18 -0
  308. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  309. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  310. package/src/tui/components/Picker.jsx +27 -3
  311. package/src/tui/components/SignInUrl.jsx +68 -0
  312. package/src/tui/components/TextEntryPanel.jsx +76 -46
  313. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  314. package/src/tui/dist/index.mjs +1896 -1341
  315. package/src/tui/session/goal-turn-state.mjs +6 -2
  316. package/src/tui/session/session-api/controls.mjs +4 -0
  317. package/src/tui/session/session-api/extensions.mjs +8 -0
  318. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  319. package/src/tui/session/session-api/intake.mjs +2 -0
  320. package/src/tui/session/session-api/integrations.mjs +2 -2
  321. package/src/tui/session/session-api/routes-agent-definitions.mjs +1 -0
  322. package/src/tui/session/session-api/settings.mjs +2 -2
  323. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  324. package/src/tui/session/transcript-spill.mjs +92 -4
  325. package/src/tui/session/transcript-store.mjs +2 -0
  326. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
@@ -1,6 +1,7 @@
1
- // The accounts of a multi-account connector server as the MCP server API
2
- // edits them: adding one more account (into its server, or a new server
3
- // holding it) and editing one account's transport, app password or client.
1
+ // The accounts of a connector server as the MCP server API edits them: adding
2
+ // one more account (into its server, or a new server holding it) and editing
3
+ // one account's transport, app password or client.
4
+ import { randomUUID } from 'node:crypto';
4
5
  import { clean } from '../runtime/agent/orchestrator/runtime-core/session-text.mjs';
5
6
  import {
6
7
  mergeMcpServerConfig,
@@ -13,15 +14,16 @@ import {
13
14
  connectorAccountServers,
14
15
  connectorAccountsOf,
15
16
  connectorAccountsUrl,
16
- connectorById,
17
17
  connectorOfServer,
18
+ connectorServerSettings,
18
19
  gmailAppPasswordAccount,
19
20
  withConnectorAccountEnabled,
20
21
  } from '../runtime/shared/connector-catalog.mjs';
21
22
  import { forgetConnectorAccountHealth } from '../runtime/connectors/connector-accounts-mcp.mjs';
22
- import { accountTarget, mergedServerInput, nameTakenError, oauthUrlOf } from './resource-mcp-servers.mjs';
23
+ import { hasConfiguredMcpAuth } from '../runtime/agent/orchestrator/mcp/client-transport.mjs';
24
+ import { accountTarget, mergedServerInput, nameTakenError, oauthCredentialOf } from './resource-mcp-servers.mjs';
23
25
 
24
- /** The server of multi-account connector `connector` in `servers`, or ''. */
26
+ /** The server of connector `connector` in `servers`, or ''. */
25
27
  function connectorServerName(servers, connector) {
26
28
  return (
27
29
  Object.keys(servers).find(
@@ -36,7 +38,7 @@ function connectorServerName(servers, connector) {
36
38
  export const editsServerItself = (target, input) => {
37
39
  if (target.serverName !== target.account.name || !clean(input.url)) return false;
38
40
  try {
39
- return oauthUrlOf({ type: input.type || 'http', url: input.url }) === oauthUrlOf(target.cfg);
41
+ return oauthCredentialOf({ type: input.type || 'http', url: input.url }) === oauthCredentialOf(target.cfg);
40
42
  } catch {
41
43
  return false;
42
44
  }
@@ -51,12 +53,14 @@ export function createConnectorAccountEdits({
51
53
  storeOAuthClientSecret,
52
54
  storeGmailAppPassword,
53
55
  forgetUnusedGmailAppPassword,
56
+ forgetStoredSecrets,
54
57
  releaseOAuth,
55
58
  }) {
56
- /** One more account of multi-account connector `connector` (one-account
57
- * config `accountCfg` as normalized from `input`): into its server, or a
58
- * new server named `name` holding it. The same Gmail address again takes
59
- * the new app password. Resolves `{ name, account, status }`. */
59
+ /** One more account of connector `connector` (one-account config
60
+ * `accountCfg` as normalized from `input`): into its server, or a new
61
+ * server named `name` holding it. The same Gmail address again takes the
62
+ * new app password. `servers` is read under the caller's per-connector
63
+ * serialization (resource-mcp-api.mjs). Resolves `{ name, account, status }`. */
60
64
  async function addConnectorAccount(servers, connector, name, accountCfg, input) {
61
65
  const serverName = connectorServerName(servers, connector);
62
66
  const address = gmailAppPasswordAccount(accountCfg);
@@ -77,29 +81,38 @@ export function createConnectorAccountEdits({
77
81
  }
78
82
  const accountName = serverName ? freeName(servers, name) : name;
79
83
  const account = connectorAccountEntry(accountName, accountCfg);
80
- // Sign-in tokens are stored per exact URL: another account needs its own.
81
- const backendUrl = connectorById(connector)?.backend?.url;
82
- if (
83
- !address &&
84
- cfg &&
85
- connectorAccountServers(cfg).some((other) => oauthUrlOf(other) === oauthUrlOf({ type: 'http', url: account.url }))
86
- ) {
87
- account.url = `${backendUrl}?account=${encodeURIComponent(accountName)}`;
84
+ // A sign-in is stored per exact URL: another account signing in at the
85
+ // same URL gets its own key, so the two never share tokens.
86
+ const asServer = connectorAccountServer({ connector }, account);
87
+ const signIn = hasConfiguredMcpAuth(asServer) ? null : oauthCredentialOf(asServer);
88
+ if (signIn && cfg && connectorAccountServers(cfg).some((other) => oauthCredentialOf(other) === signIn)) {
89
+ account.oauthKey = randomUUID();
88
90
  }
89
91
  const storedCfg = connectorAccountServer({ connector }, account);
90
- await storeOAuthClientSecret(input, storedCfg);
91
- await storeGmailAppPassword(input, storedCfg, true);
92
- forgetConnectorAccountHealth(accountName);
93
92
  let target = serverName;
94
- if (cfg) {
95
- servers[serverName] = { ...cfg, accounts: [...connectorAccountsOf(cfg), account] };
96
- } else {
97
- // The server's own settings (timeouts, enabled) ride on the input.
98
- const { type: _type, url: _url, headers: _headers, oauthClientId: _client, ...rest } = accountCfg;
99
- target = name;
100
- servers[name] = { ...rest, type: 'http', url: connectorAccountsUrl(connector), connector, accounts: [account] };
93
+ // Its secrets and its config land together: a failed step takes back the secrets.
94
+ try {
95
+ await storeOAuthClientSecret(input, storedCfg);
96
+ await storeGmailAppPassword(input, storedCfg, true);
97
+ if (cfg) {
98
+ servers[serverName] = { ...cfg, accounts: [...connectorAccountsOf(cfg), account] };
99
+ } else {
100
+ // The server's own settings (timeouts, enabled) ride on the input.
101
+ target = name;
102
+ servers[name] = {
103
+ ...connectorServerSettings(accountCfg),
104
+ type: 'http',
105
+ url: connectorAccountsUrl(connector),
106
+ connector,
107
+ accounts: [account],
108
+ };
109
+ }
110
+ saveServers(servers);
111
+ } catch (error) {
112
+ await forgetStoredSecrets(storedCfg);
113
+ throw error;
101
114
  }
102
- saveServers(servers);
115
+ forgetConnectorAccountHealth(accountName);
103
116
  const status = await sync.reconnectMcpAndAnnounce({ only: target, enabled: servers[target].enabled !== false });
104
117
  return { name: target, account: accountName, status };
105
118
  }
@@ -116,7 +129,7 @@ export function createConnectorAccountEdits({
116
129
  await storeOAuthClientSecret(input, next, accountCfg);
117
130
  await storeGmailAppPassword(input, next, false);
118
131
  // Settings that are not the account's transport (timeouts) are the server's.
119
- const { type: _type, url: _url, headers: _headers, oauthClientId: _client, ...serverFields } = config;
132
+ const serverFields = connectorServerSettings(config);
120
133
  const server = { ...cfg };
121
134
  for (const group of MCP_TIMEOUT_FIELD_GROUPS) {
122
135
  if (group.some((field) => Object.hasOwn(serverFields, field))) for (const field of group) delete server[field];
@@ -6,8 +6,8 @@ import {
6
6
  gmailAppPasswordValue,
7
7
  connectorAccountServers,
8
8
  } from '../runtime/shared/connector-catalog.mjs';
9
- import { forgetConnectorAccountHealth } from '../runtime/connectors/connector-accounts-mcp.mjs';
10
- import { oauthUrlOf } from './resource-mcp-servers.mjs';
9
+ import { forgetConnectorAccountHealth, retireConnectorAccount } from '../runtime/connectors/connector-accounts-mcp.mjs';
10
+ import { oauthCredentialOf } from './resource-mcp-servers.mjs';
11
11
 
12
12
  /** Every config `servers` connects with, a multi-account server's accounts
13
13
  * as the one-account configs they are. */
@@ -44,15 +44,16 @@ export function createMcpServerSecrets({
44
44
  }
45
45
  };
46
46
  // A server's OAuth tokens and client registration go with it, unless another
47
- // configured server (plugin or disabled ones included, even with MCP
48
- // disabled for this runtime) still uses them through the same exact URL.
49
- // `signIn` tells the caller what happened to the sign-in: `removed` (local
50
- // secrets deleted, `revoked` when the provider confirmed the revocation
51
- // too), `shared` (another server still uses it), or none (null).
47
+ // configured server or account (plugin or disabled ones included, even with
48
+ // MCP disabled for this runtime) still uses them through the same exact URL
49
+ // (or the same account key). `signIn` tells the caller what happened to the
50
+ // sign-in: `removed` (local secrets deleted, `revoked` when the provider
51
+ // confirmed the revocation too), `shared` (another server still uses it),
52
+ // or none (null).
52
53
  const releaseOAuth = async (cfg) => {
53
- const url = oauthUrlOf(cfg);
54
- if (!url) return null;
55
- if (expandedConfigs(resolveConfiguredMcpCatalog().servers).some((other) => oauthUrlOf(other) === url)) {
54
+ const key = oauthCredentialOf(cfg);
55
+ if (!key) return null;
56
+ if (expandedConfigs(resolveConfiguredMcpCatalog().servers).some((other) => oauthCredentialOf(other) === key)) {
56
57
  return { signIn: 'shared', revoked: false };
57
58
  }
58
59
  const { revoked = false } = (await clearMcpServerOAuth(cfg, { revoke: true })) || {};
@@ -66,10 +67,19 @@ export function createMcpServerSecrets({
66
67
  await gmailAppPassword.forget(account);
67
68
  return true;
68
69
  };
70
+ // What storeOAuthClientSecret / storeGmailAppPassword stored for `cfg`, gone
71
+ // again unless a configured server uses it (an add that was not saved).
72
+ const forgetStoredSecrets = async (cfg) => {
73
+ await forgetUnusedGmailAppPassword(gmailAppPasswordAccount(cfg));
74
+ if (!cfg?.url || !cfg.oauthClientId) return;
75
+ const servers = expandedConfigs(resolveConfiguredMcpCatalog().servers);
76
+ if (!servers.some((other) => other.url === cfg.url && other.oauthClientId)) await saveOAuthClientSecret(cfg.url, '');
77
+ };
69
78
  // A removed account keeps no sign-in another configured server or account
70
79
  // does not share: `{ signIn, revoked }` as removeMcpServer reports it.
71
80
  const releaseAccount = async (accountCfg) => {
72
81
  forgetConnectorAccountHealth(accountCfg.name);
82
+ retireConnectorAccount(accountCfg.connector, accountCfg.name);
73
83
  const address = gmailAppPasswordAccount(accountCfg);
74
84
  if (address) {
75
85
  const forgotten = await forgetUnusedGmailAppPassword(address);
@@ -78,5 +88,12 @@ export function createMcpServerSecrets({
78
88
  return releaseOAuth(accountCfg);
79
89
  };
80
90
 
81
- return { storeOAuthClientSecret, storeGmailAppPassword, releaseOAuth, forgetUnusedGmailAppPassword, releaseAccount };
91
+ return {
92
+ storeOAuthClientSecret,
93
+ storeGmailAppPassword,
94
+ releaseOAuth,
95
+ forgetUnusedGmailAppPassword,
96
+ forgetStoredSecrets,
97
+ releaseAccount,
98
+ };
82
99
  }
@@ -3,7 +3,7 @@
3
3
  // name refusals and the merge of a partial server edit.
4
4
  import { clean } from '../runtime/agent/orchestrator/runtime-core/session-text.mjs';
5
5
  import { MCP_TIMEOUT_FIELD_GROUPS } from '../runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs';
6
- import { resolveMcpOAuthUrl } from '../runtime/agent/orchestrator/mcp/client-config.mjs';
6
+ import { resolveMcpOAuthCredentialKey } from '../runtime/agent/orchestrator/mcp/client-config.mjs';
7
7
  import {
8
8
  connectorAccountServer,
9
9
  connectorAccountsOf,
@@ -11,10 +11,11 @@ import {
11
11
  connectorOfServer,
12
12
  } from '../runtime/shared/connector-catalog.mjs';
13
13
 
14
- /** The URL a server's OAuth credentials are stored under, or null. */
15
- export function oauthUrlOf(cfg) {
14
+ /** What a server's OAuth credentials are stored under (its URL, or a
15
+ * connector account's own key), or null. */
16
+ export function oauthCredentialOf(cfg) {
16
17
  try {
17
- return resolveMcpOAuthUrl(cfg);
18
+ return resolveMcpOAuthCredentialKey(cfg);
18
19
  } catch {
19
20
  // No valid remote URL: such a server never logged in.
20
21
  return null;
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  isAgentProgressWatchdogAbortError,
3
+ noteStoppedShellJobsOnError,
3
4
  resolveAgentWatchdogPolicy,
4
5
  resolveHandoffMessageStartIndex,
5
6
  turnPartialHandoff,
@@ -20,6 +21,7 @@ import { handoffContent } from '../../handoff-attachments.mjs';
20
21
  import { rebindDelegation } from '../../../runtime/agent/orchestrator/session/human-gate/delegation.mjs';
21
22
  import { settledWorkerStatus } from './worker-index/row-liveness.mjs';
22
23
  import { whileTurnDispatched } from '../../../runtime/agent/orchestrator/session/manager/runtime-state.mjs';
24
+ import { takeStoppedShellJobs } from '../../../runtime/agent/orchestrator/session/manager/turn-reap.mjs';
23
25
 
24
26
  function workerResultIdentity({ session, tag, sessionId }) {
25
27
  return { tag, sessionId, agent: session.agent || null, provider: session.provider, model: session.model };
@@ -92,7 +94,12 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
92
94
  // the watchdog sweep re-stamps turnStartedAt at each turn boundary.
93
95
  const watchdogPolicy = resolveAgentWatchdogPolicy(
94
96
  sendAgent,
95
- spawnFlow.agentWatchdogOverrides({ agent: sendAgent, provider: session.provider, model: session.model })
97
+ spawnFlow.agentWatchdogOverrides({
98
+ agent: sendAgent,
99
+ provider: session.provider,
100
+ model: session.model,
101
+ ...(session.modelParameters ? { modelParameters: session.modelParameters } : {}),
102
+ })
96
103
  );
97
104
  const watchdog = spawnFlow.startProgressIdleWatchdog(sessionId, watchdogPolicy, sendAgent, {
98
105
  onTurnStart: spawnFlow.turnStartStamper(session, tag),
@@ -146,7 +153,7 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
146
153
  finalStatus = 'idle';
147
154
  const value = {
148
155
  ...workerResultIdentity({ session, tag, sessionId }),
149
- content: watchdogStoppedHandoff(error, partial),
156
+ content: watchdogStoppedHandoff(error, partial, await takeStoppedShellJobs(sessionId)),
150
157
  stallAbort: true,
151
158
  };
152
159
  if (job) job._terminalResultValue = value;
@@ -154,6 +161,7 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
154
161
  return value;
155
162
  }
156
163
  finalStatus = 'error';
164
+ noteStoppedShellJobsOnError(error, await takeStoppedShellJobs(sessionId));
157
165
  reconcileJobStreamStalled(job, error);
158
166
  throw error;
159
167
  } finally {
@@ -77,8 +77,8 @@ export function createSpawnPreparer({
77
77
  * first-response deadline and the provider's first-response budget for the
78
78
  * routed model (headers, and first output), handed to
79
79
  * resolveAgentWatchdogPolicy. A provider on the shared window names none. */
80
- function agentWatchdogOverrides({ agent, provider, model }) {
81
- const budget = getProvider(provider)?.firstResponseBudget?.(model);
80
+ function agentWatchdogOverrides({ agent, provider, model, modelParameters }) {
81
+ const budget = getProvider(provider)?.firstResponseBudget?.(model, { modelParameters });
82
82
  return {
83
83
  firstResponseTimeoutMs: readAgentFirstResponseTimeoutMs(agent, dataDir, STANDALONE_SOURCE_ROOT) ?? undefined,
84
84
  providerFirstByteTimeoutMs: budget?.transportMs,
@@ -145,7 +145,12 @@ export function createSpawnPreparer({
145
145
  prompt: plan.prompt,
146
146
  watchdogPolicy: resolveAgentWatchdogPolicy(
147
147
  plan.agent,
148
- agentWatchdogOverrides({ agent: plan.agent, provider: plan.preset.provider, model: plan.preset.model })
148
+ agentWatchdogOverrides({
149
+ agent: plan.agent,
150
+ provider: plan.preset.provider,
151
+ model: plan.preset.model,
152
+ modelParameters: plan.preset.modelParameters,
153
+ })
149
154
  ),
150
155
  };
151
156
  }
@@ -16,6 +16,7 @@ import { abnormalEmptyFinishError } from '../render.mjs';
16
16
  import { createProgressWatchdogRegistry } from '../../agent-watchdog-registry.mjs';
17
17
  import {
18
18
  isAgentProgressWatchdogAbortError,
19
+ noteStoppedShellJobsOnError,
19
20
  resolveHandoffMessageStartIndex,
20
21
  turnPartialHandoff,
21
22
  watchdogPartialHandoffFromError,
@@ -27,6 +28,7 @@ import { presetDescriptor } from './spawn-prep.mjs';
27
28
  import { workerStageForStatus } from '../worker-rows.mjs';
28
29
  import { handoffContent } from '../../../handoff-attachments.mjs';
29
30
  import { whileTurnDispatched } from '../../../../runtime/agent/orchestrator/session/manager/runtime-state.mjs';
31
+ import { takeStoppedShellJobs } from '../../../../runtime/agent/orchestrator/session/manager/turn-reap.mjs';
30
32
 
31
33
  // Mid-turn worker persistence cadence. The watchdog sweep runs every second;
32
34
  // a transcript save is far more expensive than a bookkeeping stamp, so the
@@ -209,7 +211,7 @@ export function createSpawnRunner({
209
211
  tag,
210
212
  sessionId: session.id,
211
213
  ...presetDescriptor(agent, preset, presetName),
212
- content: watchdogStoppedHandoff(error, partial),
214
+ content: watchdogStoppedHandoff(error, partial, await takeStoppedShellJobs(session.id)),
213
215
  stallAbort: true,
214
216
  };
215
217
  if (job) job._terminalResultValue = value;
@@ -217,6 +219,7 @@ export function createSpawnRunner({
217
219
  return value;
218
220
  }
219
221
  finalStatus = 'error';
222
+ noteStoppedShellJobsOnError(error, await takeStoppedShellJobs(session.id));
220
223
  reconcileJobStreamStalled(job, error);
221
224
  throw error;
222
225
  } finally {
@@ -2,6 +2,8 @@
2
2
  // One shared 1s timer sweeps every watched session, so a burst
3
3
  // of agents costs a single interval; the timer stops as soon as the last
4
4
  // watchdog is released. Abort policy itself lives in the runtime module.
5
+ import { randomUUID } from 'node:crypto';
6
+ import { armTurnTimeout } from '../../runtime/agent/orchestrator/session/manager/turn-reap.mjs';
5
7
  import {
6
8
  abortAgentProgressWatchdog,
7
9
  agentWatchdogPolicyActive,
@@ -23,6 +25,13 @@ export function getProgressWatchdogState(mgr, sessionId) {
23
25
  };
24
26
  }
25
27
 
28
+ // This watchdog owns its timeout: arm the session's shell reap before the
29
+ // abort propagates, unless the turn is already stopped (the guard skips it).
30
+ function abortOnTimeout(controller, ctx) {
31
+ if (!controller?.signal?.aborted && ctx?.error) armTurnTimeout(ctx.sessionId);
32
+ abortAgentProgressWatchdog(controller, ctx);
33
+ }
34
+
26
35
  export function createProgressWatchdogRegistry({ mgr }) {
27
36
  const watched = new Map();
28
37
  registrations.set(mgr, watched);
@@ -100,6 +109,15 @@ export function createProgressWatchdogRegistry({ mgr }) {
100
109
  const abortErr = snapshot ? evaluateAgentWatchdogAbort(snapshot, now, watchdogPolicy) : null;
101
110
  // No progress snapshot: fall back to the coarse last-progress timestamp so a
102
111
  // session that never reports structured progress can still stall out.
112
+ const observe = () => {
113
+ try {
114
+ return typeof mgr.getSessionProgressObservation === 'function'
115
+ ? mgr.getSessionProgressObservation(sessionId)
116
+ : null;
117
+ } catch {
118
+ return null;
119
+ }
120
+ };
103
121
  if (!abortErr && !snapshot) {
104
122
  // start() admits a manager that provides EITHER progress source, so this
105
123
  // fallback must not assume the coarse one exists: throwing here escaped
@@ -114,7 +132,7 @@ export function createProgressWatchdogRegistry({ mgr }) {
114
132
  }
115
133
  const last = reported || anchorTs;
116
134
  if (watchdogPolicy.idleStaleMs > 0 && now - last > watchdogPolicy.idleStaleMs) {
117
- abortAgentProgressWatchdog(controller, {
135
+ abortOnTimeout(controller, {
118
136
  sessionId,
119
137
  agent,
120
138
  error: new AgentStallAbortError(`agent task stale (${watchdogPolicy.idleStaleMs}ms without progress)`),
@@ -123,12 +141,14 @@ export function createProgressWatchdogRegistry({ mgr }) {
123
141
  anchorTs,
124
142
  lastProgressAt: reported,
125
143
  iteration,
144
+ observation: observe(),
145
+ registrationId: state.registrationId,
126
146
  });
127
147
  }
128
148
  return;
129
149
  }
130
150
  if (abortErr) {
131
- abortAgentProgressWatchdog(controller, {
151
+ abortOnTimeout(controller, {
132
152
  sessionId,
133
153
  agent,
134
154
  error: abortErr,
@@ -137,6 +157,8 @@ export function createProgressWatchdogRegistry({ mgr }) {
137
157
  now,
138
158
  anchorTs,
139
159
  iteration,
160
+ observation: observe(),
161
+ registrationId: state.registrationId,
140
162
  });
141
163
  }
142
164
  }
@@ -151,14 +173,19 @@ export function createProgressWatchdogRegistry({ mgr }) {
151
173
  state.lastSuccessfulCheckAt = Date.now();
152
174
  } catch (error) {
153
175
  state.error = String(error?.message || error);
154
- const elapsed = Date.now() - (state.lastSuccessfulCheckAt || state.anchorTs);
176
+ const compared = state.lastSuccessfulCheckAt
177
+ ? { at: state.lastSuccessfulCheckAt, field: 'last_successful_check_at' }
178
+ : { at: state.anchorTs, field: 'anchor_ts' };
179
+ const elapsed = Date.now() - compared.at;
155
180
  if (state.watchdogPolicy.idleStaleMs > 0 && elapsed > state.watchdogPolicy.idleStaleMs) {
156
- abortAgentProgressWatchdog(state.controller, {
181
+ abortOnTimeout(state.controller, {
157
182
  sessionId: state.sessionId,
158
183
  agent: state.agent,
159
184
  error: new AgentStallAbortError(`agent progress checks failed: ${state.error}`),
160
185
  policy: state.watchdogPolicy,
161
186
  anchorTs: state.anchorTs,
187
+ comparedClock: compared,
188
+ registrationId: state.registrationId,
162
189
  });
163
190
  }
164
191
  }
@@ -177,6 +204,7 @@ export function createProgressWatchdogRegistry({ mgr }) {
177
204
  return null;
178
205
  if (typeof mgr.linkParentSignalToSession !== 'function') return null;
179
206
  const state = {
207
+ registrationId: randomUUID().slice(0, 8),
180
208
  sessionId,
181
209
  watchdogPolicy,
182
210
  agent,
@@ -7,6 +7,7 @@ import { resolve } from 'node:path';
7
7
  import { fileURLToPath } from 'node:url';
8
8
  import { scrubLoaderVars } from '../../../runtime/agent/orchestrator/tools/env-scrub.mjs';
9
9
  import { withHeapCap } from '../../../runtime/shared/heap-cap.mjs';
10
+ import { systemProxyHandoffEnv } from '../../../runtime/shared/llm/system-proxy.mjs';
10
11
  import { detachedSpawnOpts } from '../../../runtime/shared/spawn-flags.mjs';
11
12
  import { forkDaemonCandidate } from '../daemon-candidate.mjs';
12
13
 
@@ -24,6 +25,7 @@ export function daemonEnv({ rootDir, dataDir, runtimeDir, leadPid }) {
24
25
  scrubLoaderVars(env);
25
26
  return {
26
27
  ...env,
28
+ ...systemProxyHandoffEnv(),
27
29
  MIXDOG_ROOT: rootDir,
28
30
  MIXDOG_DATA_DIR: dataDir,
29
31
  MIXDOG_RUNTIME_ROOT: runtimeDir,
@@ -8,6 +8,7 @@
8
8
  // and attaches to whoever won. The resolved `summary()` describes this boot as
9
9
  // observed when called, for a caller that has to give up.
10
10
  import { fork } from 'node:child_process';
11
+ import { withEnvProxy } from '../../runtime/shared/llm/http-agent.mjs';
11
12
  import { beginDaemonSpawnCapture } from './daemon-crash-capture.mjs';
12
13
 
13
14
  export function forkDaemonCandidate({
@@ -43,7 +44,9 @@ export function forkDaemonCandidate({
43
44
  cwd,
44
45
  execArgv,
45
46
  stdio: ['ignore', 'ignore', capture.stderrStdio, 'ipc'],
46
- env,
47
+ // Proxy variables (the user's or the desktop's system proxy) need
48
+ // NODE_USE_ENV_PROXY to reach the daemon's fetch.
49
+ env: withEnvProxy(env),
47
50
  ...spawnOptions,
48
51
  });
49
52
  } catch (error) {
@@ -4,6 +4,7 @@ import { dirname } from 'node:path';
4
4
  import { detachedSpawnOpts } from '../../../runtime/shared/spawn-flags.mjs';
5
5
  import { withHeapCap } from '../../../runtime/shared/heap-cap.mjs';
6
6
  import { resolveRuntimeRoot } from '../../../runtime/shared/runtime-root.mjs';
7
+ import { systemProxyHandoffEnv } from '../../../runtime/shared/llm/system-proxy.mjs';
7
8
  import { scrubLoaderVars } from '../../../runtime/agent/orchestrator/tools/env-scrub.mjs';
8
9
 
9
10
  // Once a spawn crashes deterministically, short-circuit re-forks for this
@@ -33,6 +34,9 @@ function daemonEnv({ dataDir, idleTtlMs }) {
33
34
  scrubLoaderVars(env);
34
35
  return {
35
36
  ...env,
37
+ // The runtime and model downloads follow the system proxy this process
38
+ // settled; the memory process consumes the handoff at startup.
39
+ ...systemProxyHandoffEnv(),
36
40
  MIXDOG_DATA_DIR: dataDir,
37
41
  MIXDOG_RUNTIME_ROOT: resolveRuntimeRoot(),
38
42
  MIXDOG_WORKER_MODE: '1',
@@ -8,6 +8,7 @@ import { resolvePluginData } from '../../runtime/shared/plugin-paths.mjs';
8
8
  import { pluginManifest } from '../../runtime/shared/plugin-manifest.mjs';
9
9
  import { pluginMetadata } from '../../runtime/shared/plugin-metadata.mjs';
10
10
  import { clean } from '../../runtime/shared/clean.mjs';
11
+ import { startGitSync } from '../../runtime/shared/git-launch.mjs';
11
12
 
12
13
  const REGISTRY_VERSION = 1;
13
14
 
@@ -125,12 +126,15 @@ function normalizeSource(input) {
125
126
  }
126
127
 
127
128
  function runGit(args, options = {}) {
128
- const result = spawnSync('git', args, {
129
- cwd: options.cwd,
130
- encoding: 'utf8',
131
- windowsHide: true,
132
- timeout: options.timeout ?? 120000,
133
- });
129
+ const result = startGitSync(null, (command, env) =>
130
+ spawnSync(command, args, {
131
+ cwd: options.cwd,
132
+ env,
133
+ encoding: 'utf8',
134
+ windowsHide: true,
135
+ timeout: options.timeout ?? 120000,
136
+ })
137
+ );
134
138
  if (result.status !== 0) {
135
139
  const detail = clean(result.stderr) || clean(result.stdout) || `git ${args.join(' ')} failed`;
136
140
  throw new Error(detail);