mixdog 1.4.1 → 1.4.3

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 (630) hide show
  1. package/package.json +4 -3
  2. package/scripts/build-shipped-history.mjs +125 -33
  3. package/scripts/gate-local.mjs +220 -63
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +139 -32
  6. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  7. package/scripts/lib/run-node-tests.mjs +71 -34
  8. package/scripts/lib/scoped-temp.mjs +1 -0
  9. package/scripts/lib/test-failure-records.mjs +14 -1
  10. package/scripts/lib/test-failure-summary.mjs +9 -4
  11. package/scripts/lib/test-spawn-ledger.mjs +43 -3
  12. package/scripts/post-release-check.mjs +26 -16
  13. package/scripts/pptx-kit-index.mjs +5 -6
  14. package/scripts/provider-pingpong-live.mjs +1 -1
  15. package/scripts/prune-embedding-runtime.mjs +3 -1
  16. package/scripts/release-paths.mjs +7 -1
  17. package/scripts/suite-health.mjs +110 -28
  18. package/scripts/test.mjs +9 -14
  19. package/src/agents/advisor/AGENT.md +4 -4
  20. package/src/agents/advisor/agent.json +1 -1
  21. package/src/agents/explore/AGENT.md +22 -0
  22. package/src/agents/explore/agent.json +6 -0
  23. package/src/cli.mjs +7 -0
  24. package/src/defaults/agents.json +7 -0
  25. package/src/defaults/shipped-history.json +38 -2
  26. package/src/defaults/skills/browser-use/SKILL.md +4 -1
  27. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  28. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  29. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  30. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  31. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  32. package/src/defaults/skills/computer-use/SKILL.md +12 -2
  33. package/src/defaults/skills/setup/SKILL.md +2 -2
  34. package/src/defaults/skills/setup/references/actions.md +28 -9
  35. package/src/defaults/skills/setup/references/surfaces.md +5 -2
  36. package/src/defaults/skills/setup-guide/SKILL.md +11 -3
  37. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  38. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  39. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  40. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  41. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  42. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  43. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  44. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  45. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  46. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  47. package/src/defaults/skills/visualize/SKILL.md +6 -2
  48. package/src/lib/instruction-text.cjs +36 -0
  49. package/src/lib/rules-builder.cjs +40 -50
  50. package/src/orchestration/balanced.md +23 -0
  51. package/src/orchestration/focused.md +22 -0
  52. package/src/orchestration/none.md +5 -0
  53. package/src/orchestration/swarm.md +24 -0
  54. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  55. package/src/rules/agent-mode/MIXY.md +2 -2
  56. package/src/rules/lead/LEAD.md +3 -3
  57. package/src/rules/shared/20-research.md +3 -6
  58. package/src/rules/shared/40-editing.md +1 -0
  59. package/src/rules/shared/60-verification.md +10 -9
  60. package/src/rules/shared/70-delivery.md +4 -3
  61. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  62. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  63. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
  64. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
  65. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
  66. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  67. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  69. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  70. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  71. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
  72. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
  73. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  74. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
  75. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
  76. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
  77. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
  78. package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
  79. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  81. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
  82. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  84. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
  85. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
  86. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
  87. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
  89. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  90. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  91. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  92. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  95. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  96. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  97. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  98. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  99. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  100. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  102. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
  103. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  104. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  105. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  106. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  107. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  109. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  110. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  111. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  112. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
  113. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
  116. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  118. package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
  119. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  120. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  121. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  122. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
  123. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  124. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
  125. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  126. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  127. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  128. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  129. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  130. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  131. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  132. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  133. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  134. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  135. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  136. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  137. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  138. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  139. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  140. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
  141. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  142. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  143. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
  145. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  146. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
  147. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
  148. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  149. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  150. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  151. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  152. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  153. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  154. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
  155. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  156. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  157. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  158. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  159. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  160. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  161. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
  162. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
  163. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
  164. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  165. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
  166. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  167. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
  169. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  170. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  172. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
  174. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  175. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  176. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  177. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  178. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  179. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  180. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  181. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  182. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
  183. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
  184. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  185. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  186. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  187. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  188. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
  189. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  190. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  191. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  192. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  193. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  194. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  195. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  196. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  197. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  198. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  199. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  200. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  201. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  202. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  203. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  204. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
  205. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
  206. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
  207. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
  208. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  210. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
  211. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  212. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
  213. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  214. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  215. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  216. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
  217. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  218. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  219. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  220. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  221. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  222. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
  223. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  224. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  225. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  226. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
  227. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  228. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
  229. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  230. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  231. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  232. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  233. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  234. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  235. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  236. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  237. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
  238. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  239. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
  240. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  241. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  242. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  243. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  244. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  245. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  246. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  247. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  248. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  249. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  250. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  251. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  252. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  253. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  254. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
  255. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
  256. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  257. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  258. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  259. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  260. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  261. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  262. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
  263. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  264. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  265. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  266. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  267. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  269. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  270. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  271. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  272. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  273. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  274. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  275. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
  276. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  277. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  278. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  279. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
  280. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
  281. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  282. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
  283. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  284. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  285. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  286. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  287. package/src/runtime/attachments/store.d.mts +1 -0
  288. package/src/runtime/attachments/store.mjs +2 -2
  289. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  290. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  291. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  292. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  293. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  294. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  295. package/src/runtime/channels/lib/whisper-port.mjs +19 -10
  296. package/src/runtime/channels/lib/whisper-server.mjs +22 -13
  297. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  298. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  299. package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
  300. package/src/runtime/connectors/gmail-app-password.mjs +4 -4
  301. package/src/runtime/connectors/google-mcp.mjs +1 -1
  302. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  303. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  304. package/src/runtime/explore/explorer.mjs +88 -0
  305. package/src/runtime/explore/tool-defs.mjs +35 -0
  306. package/src/runtime/explore/tool.mjs +123 -0
  307. package/src/runtime/local-provider/hardware.mjs +1 -1
  308. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  309. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  310. package/src/runtime/media/media-usage.mjs +1 -1
  311. package/src/runtime/media/store.mjs +1 -1
  312. package/src/runtime/memory/index.mjs +15 -1
  313. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  314. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  315. package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
  316. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  317. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  318. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  319. package/src/runtime/memory/lib/memory.mjs +17 -0
  320. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  321. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  322. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  323. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  324. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  325. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  326. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  327. package/src/runtime/office/capabilities.mjs +1 -1
  328. package/src/runtime/office/core/office-core.mjs +1 -1
  329. package/src/runtime/office/design/content-model.mjs +3 -3
  330. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  331. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  332. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  333. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  334. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  335. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  336. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  337. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  338. package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
  339. package/src/runtime/shared/agent-route-config.mjs +17 -2
  340. package/src/runtime/shared/atomic-file.d.mts +8 -0
  341. package/src/runtime/shared/atomic-file.mjs +103 -2
  342. package/src/runtime/shared/background-tasks.mjs +37 -10
  343. package/src/runtime/shared/background-wait.mjs +66 -0
  344. package/src/runtime/shared/child-guardian.mjs +17 -7
  345. package/src/runtime/shared/config.mjs +313 -16
  346. package/src/runtime/shared/connector-accounts.mjs +5 -5
  347. package/src/runtime/shared/connector-catalog.d.mts +14 -8
  348. package/src/runtime/shared/connector-catalog.mjs +70 -52
  349. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  350. package/src/runtime/shared/file-has-data.mjs +26 -2
  351. package/src/runtime/shared/file-lock.mjs +21 -18
  352. package/src/runtime/shared/git-launch.d.mts +9 -0
  353. package/src/runtime/shared/git-launch.mjs +213 -0
  354. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  355. package/src/runtime/shared/git-runner.mjs +7 -2
  356. package/src/runtime/shared/idle-gc.mjs +30 -7
  357. package/src/runtime/shared/llm/cost.mjs +6 -1
  358. package/src/runtime/shared/llm/http-agent.mjs +316 -29
  359. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  360. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  361. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  362. package/src/runtime/shared/llm/system-proxy.mjs +453 -0
  363. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  364. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  365. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  366. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  367. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  368. package/src/runtime/shared/process-runner.mjs +8 -4
  369. package/src/runtime/shared/provider-accounts.mjs +52 -2
  370. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  371. package/src/runtime/shared/routine-trigger.mjs +34 -0
  372. package/src/runtime/shared/run-child.d.mts +2 -1
  373. package/src/runtime/shared/run-child.mjs +70 -18
  374. package/src/runtime/shared/session-scratch.mjs +14 -2
  375. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  376. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  377. package/src/runtime/shared/staged-update.mjs +47 -2
  378. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  379. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  380. package/src/runtime/shared/tool-surface.mjs +110 -36
  381. package/src/runtime/shared/tool-work-units.mjs +35 -6
  382. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  383. package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
  384. package/src/runtime/shared/worker-requests.mjs +17 -3
  385. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  386. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  387. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  388. package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
  389. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  390. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  391. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  392. package/src/runtime/shared/worktrees/git.mjs +97 -7
  393. package/src/runtime/shared/worktrees/include.mjs +6 -4
  394. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  395. package/src/runtime/shared/worktrees/manager.mjs +962 -197
  396. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  397. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  398. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  399. package/src/runtime/tidy/install.mjs +95 -15
  400. package/src/runtime/tidy/languages.mjs +17 -15
  401. package/src/runtime/tidy/process.mjs +9 -5
  402. package/src/runtime/tidy/resolve.mjs +19 -16
  403. package/src/runtime/tidy/runners/biome.mjs +3 -3
  404. package/src/runtime/tidy/tool.mjs +1 -1
  405. package/src/runtime/tidy/worktree.mjs +10 -6
  406. package/src/runtime/visualize-bridge/client.mjs +4 -1
  407. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  408. package/src/runtime/web-search/index.mjs +4 -23
  409. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  410. package/src/runtime/web-search/tool-defs.mjs +17 -26
  411. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  412. package/src/session-runtime/agent-task-sessions.mjs +410 -353
  413. package/src/session-runtime/boot/apis.mjs +27 -4
  414. package/src/session-runtime/boot/begin.mjs +2 -0
  415. package/src/session-runtime/boot/config.mjs +10 -1
  416. package/src/session-runtime/boot/facade.mjs +1 -0
  417. package/src/session-runtime/boot/providers.mjs +70 -3
  418. package/src/session-runtime/boot/session.mjs +2 -0
  419. package/src/session-runtime/boot/tools.mjs +71 -25
  420. package/src/session-runtime/bot-status.mjs +103 -103
  421. package/src/session-runtime/channel-config-api.mjs +1 -0
  422. package/src/session-runtime/config-change-effects.mjs +179 -0
  423. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  424. package/src/session-runtime/config-lifecycle.mjs +160 -24
  425. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  426. package/src/session-runtime/conversation-import/discovery.mjs +245 -47
  427. package/src/session-runtime/conversation-import/service.mjs +12 -5
  428. package/src/session-runtime/goal-facade-api.mjs +49 -3
  429. package/src/session-runtime/handoff-attachments.mjs +1 -1
  430. package/src/session-runtime/held-requests.mjs +3 -1
  431. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  432. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  433. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
  434. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  435. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
  436. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  437. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  438. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  439. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  440. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  441. package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
  442. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  443. package/src/session-runtime/lifecycle-api.mjs +1 -0
  444. package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
  445. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  446. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  447. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  448. package/src/session-runtime/model-route/set-route.mjs +40 -7
  449. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  450. package/src/session-runtime/provider-auth/login.mjs +2 -2
  451. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  452. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  453. package/src/session-runtime/provider-readiness.mjs +53 -4
  454. package/src/session-runtime/resource-api.mjs +1 -1
  455. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  456. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  457. package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
  458. package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
  459. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  460. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  461. package/src/session-runtime/routine-executor.mjs +152 -0
  462. package/src/session-runtime/routine-home-turn.mjs +46 -5
  463. package/src/session-runtime/runtime-facade.mjs +5 -0
  464. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  465. package/src/session-runtime/schedule-session-run.mjs +1 -0
  466. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  467. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  468. package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
  469. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  470. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  471. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  472. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
  473. package/src/session-runtime/services/agent-tool.mjs +51 -1
  474. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  475. package/src/session-runtime/services/channel-admin.mjs +18 -0
  476. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  477. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  478. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  479. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  480. package/src/session-runtime/services/plugin-admin.mjs +14 -6
  481. package/src/session-runtime/services/provider-admin.mjs +281 -10
  482. package/src/session-runtime/services/seeds.mjs +7 -0
  483. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  484. package/src/session-runtime/session-create/materialize.mjs +4 -2
  485. package/src/session-runtime/session-create/session-options.mjs +2 -0
  486. package/src/session-runtime/session-turn-api.mjs +2 -0
  487. package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
  488. package/src/session-runtime/settings-system-api.mjs +1 -1
  489. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  490. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  491. package/src/session-runtime/setup-tool/executor.mjs +14 -3
  492. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  493. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  494. package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
  495. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  496. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  497. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  498. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  499. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  500. package/src/session-runtime/tool-surface.mjs +38 -1
  501. package/src/session-runtime/turn/agent-ops.mjs +33 -2
  502. package/src/session-runtime/turn/session-ops.mjs +2 -0
  503. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  504. package/src/session-runtime/turn/turn-run.mjs +1 -1
  505. package/src/session-runtime/webhook-session-run.mjs +2 -0
  506. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
  507. package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
  508. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  509. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  510. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  511. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  512. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  513. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  514. package/src/session-runtime/workspace/session-view.mjs +149 -0
  515. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  516. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  517. package/src/session-runtime/workspace/transitions.mjs +128 -1070
  518. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  519. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  520. package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
  521. package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
  522. package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
  523. package/src/standalone/daemon-agent-control.mjs +25 -8
  524. package/src/standalone/daemon-desktop-runtime.mjs +8 -2
  525. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  526. package/src/standalone/daemon-session-control.mjs +151 -136
  527. package/src/standalone/daemon.mjs +61 -2
  528. package/src/standalone/desktop-service-registry.mjs +9 -0
  529. package/src/standalone/local-session-runtime.mjs +21 -1
  530. package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
  531. package/src/standalone/session-client.mjs +5 -1
  532. package/src/standalone/session-frame-stream.mjs +83 -11
  533. package/src/standalone/session-protocol.mjs +15 -0
  534. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  535. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  536. package/src/standalone/session-service/agent-tree.mjs +45 -9
  537. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  538. package/src/standalone/session-service/quota-resume.mjs +9 -0
  539. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  540. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  541. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  542. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  543. package/src/standalone/session-service/session-calls.mjs +2 -1
  544. package/src/standalone/session-service/stored-reader.mjs +127 -40
  545. package/src/tui/App.jsx +162 -164
  546. package/src/tui/app/app-view/floating-panel.jsx +3 -0
  547. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  548. package/src/tui/app/clipboard.mjs +22 -11
  549. package/src/tui/app/create-app-pickers.mjs +2 -0
  550. package/src/tui/app/doctor.mjs +2 -2
  551. package/src/tui/app/panel-signature.mjs +1 -1
  552. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  553. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  554. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  555. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  556. package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
  557. package/src/tui/app/provider-setup-picker.mjs +20 -13
  558. package/src/tui/app/settings-picker.mjs +53 -8
  559. package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
  560. package/src/tui/app/slash-commands.mjs +2 -1
  561. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  562. package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
  563. package/src/tui/app/slash-dispatch.mjs +1 -1
  564. package/src/tui/app/use-btw-panel.mjs +29 -0
  565. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  566. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  567. package/src/tui/app/use-mouse-input.mjs +11 -0
  568. package/src/tui/app/use-onboarding-start.mjs +8 -3
  569. package/src/tui/app/use-panel-transition.mjs +10 -1
  570. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  571. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  572. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  573. package/src/tui/app/use-prompt-queue-history.mjs +5 -4
  574. package/src/tui/app/use-selection-focus.mjs +11 -2
  575. package/src/tui/app/use-selection-geometry.mjs +18 -9
  576. package/src/tui/app/use-selection-paint.mjs +4 -4
  577. package/src/tui/app/use-selection-stitch.mjs +3 -3
  578. package/src/tui/app/use-slash-palette.mjs +62 -0
  579. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  580. package/src/tui/app/use-transcript-activity.mjs +48 -33
  581. package/src/tui/app/use-transcript-follow.mjs +12 -4
  582. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  583. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  584. package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
  585. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  586. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  587. package/src/tui/app/use-transcript-window.mjs +21 -11
  588. package/src/tui/app/use-tui-ready.mjs +18 -0
  589. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  590. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  591. package/src/tui/components/Picker.jsx +27 -3
  592. package/src/tui/components/SignInUrl.jsx +68 -0
  593. package/src/tui/components/TextEntryPanel.jsx +76 -46
  594. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  595. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  596. package/src/tui/components/question-panel-model.mjs +4 -4
  597. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  598. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  599. package/src/tui/components/user-message-skills.mjs +1 -1
  600. package/src/tui/dist/index.mjs +2205 -1371
  601. package/src/tui/markdown/render-ansi.mjs +1 -1
  602. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  603. package/src/tui/session/agent-job-feed.mjs +2 -0
  604. package/src/tui/session/context-state.mjs +3 -0
  605. package/src/tui/session/goal-turn-state.mjs +6 -2
  606. package/src/tui/session/quota-resume.mjs +1 -1
  607. package/src/tui/session/session-api/controls.mjs +4 -0
  608. package/src/tui/session/session-api/extensions.mjs +8 -0
  609. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  610. package/src/tui/session/session-api/intake.mjs +2 -0
  611. package/src/tui/session/session-api/integrations.mjs +2 -2
  612. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  613. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  614. package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
  615. package/src/tui/session/session-api/settings.mjs +2 -2
  616. package/src/tui/session/session-api/worktree.mjs +13 -1
  617. package/src/tui/session/session-flow/drain.mjs +11 -14
  618. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  619. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  620. package/src/tui/session/transcript-spill.mjs +92 -4
  621. package/src/tui/session/transcript-store.mjs +2 -0
  622. package/src/tui/session/turn-quiet.mjs +1 -1
  623. package/src/tui/session/turn.mjs +3 -0
  624. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  625. package/src/tui/spinner-meta.mjs +3 -3
  626. package/src/tui/spinner-verbs.mjs +2 -2
  627. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  628. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
  629. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  630. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -5,6 +5,7 @@
5
5
  import { readFileSync, readdirSync, statSync, mkdirSync, existsSync, watch as fsWatch } from 'node:fs';
6
6
  import { basename, join, dirname } from 'node:path';
7
7
  import { createRequire } from 'node:module';
8
+ import { randomUUID } from 'node:crypto';
8
9
  import { resolvePluginData } from './plugin-paths.mjs';
9
10
  import { hasOwn, isPlainObject } from './object.mjs';
10
11
  import {
@@ -13,6 +14,8 @@ import {
13
14
  renameWithRetrySync,
14
15
  writeJsonAtomicSync,
15
16
  writeJsonAtomicAsync,
17
+ updateJsonAtomicSync,
18
+ updateJsonAtomic,
16
19
  withFileLockSync,
17
20
  withFileLock,
18
21
  } from './atomic-file.mjs';
@@ -30,6 +33,7 @@ import { AGENT_PROVIDER_ENV, AGENT_PROVIDER_ENV_ALIASES, getAgentApiKey } from '
30
33
  export { AGENT_PROVIDER_ENV, AGENT_PROVIDER_ENV_ALIASES, getAgentApiKey };
31
34
 
32
35
  const _require = createRequire(import.meta.url);
36
+ const _keychain = _require('../../lib/keychain-cjs.cjs');
33
37
  const {
34
38
  getSecret: _getSecret,
35
39
  setSecret: _setSecret,
@@ -42,7 +46,8 @@ const {
42
46
  retryKeychain: _retryKeychain,
43
47
  refreshKeychainStatus: _refreshKeychainStatus,
44
48
  onKeychainRecovered: _onKeychainRecovered,
45
- } = _require('../../lib/keychain-cjs.cjs');
49
+ prewarmSecrets: _prewarmSecrets,
50
+ } = _keychain;
46
51
  const _setSecretAsync = _setSecretAsyncImpl ?? (async (account, value) => _setSecret(account, value));
47
52
  const _deleteSecretAsync = _deleteSecretAsyncImpl ?? (async (account) => _deleteSecret(account));
48
53
 
@@ -80,7 +85,9 @@ function withFreshDefaultsVersion(fresh, root) {
80
85
  // isolated, freely-mutable object (no shared-reference poisoning). Only the
81
86
  // non-RMW readAll() consults this; the RMW path (readAllForRmW) always reads
82
87
  // disk under the lock. Read errors and malformed JSON are never cached.
83
- let _configReadCache = null; // { raw, mtimeMs, size, atMs } | null
88
+ let _configReadCache = null; // { raw, path, stat, atMs } | null
89
+ // While a change notification runs its listeners (runConfigChangeListeners).
90
+ let _inNotificationPass = false;
84
91
  // Optional coarse fast-path window (ms). Default 0 => the cached raw string is
85
92
  // validated against the file's mtime+size on EVERY read via a cheap statSync
86
93
  // (no content read, no whole-file JSON.parse), so a cross-process edit is
@@ -97,6 +104,12 @@ export function invalidateConfigReadCache() {
97
104
  _configReadCache = null;
98
105
  }
99
106
 
107
+ // A replacement of the same size within the mtime's resolution still moves the
108
+ // inode (atomic rename) or the change time.
109
+ function statKey(st) {
110
+ return `${st.mtimeMs}:${st.ctimeMs}:${st.size}:${st.ino}`;
111
+ }
112
+
100
113
  function readConfigRawCached() {
101
114
  const now = Date.now();
102
115
  if (_configReadCache && _configReadCache.path !== configPath()) _configReadCache = null;
@@ -106,12 +119,12 @@ function readConfigRawCached() {
106
119
  if (CONFIG_READ_TTL_MS > 0 && now - _configReadCache.atMs < CONFIG_READ_TTL_MS) {
107
120
  return _configReadCache.raw;
108
121
  }
109
- // Freshness gate: metadata-only stat. Unchanged mtime+size => the cached
122
+ // Freshness gate: metadata-only stat. Unchanged mtime+ctime+size+inode => the cached
110
123
  // raw is still current, cross-process writes included — atomic writers land
111
124
  // a new inode with a fresh mtime, so this reliably detects them.
112
125
  try {
113
126
  const st = statSync(configPath());
114
- if (st.mtimeMs === _configReadCache.mtimeMs && st.size === _configReadCache.size) {
127
+ if (statKey(st) === _configReadCache.stat) {
115
128
  _configReadCache.atMs = now;
116
129
  return _configReadCache.raw;
117
130
  }
@@ -146,7 +159,7 @@ function readConfigRawCached() {
146
159
  process.stderr.write(`[config] readJsonFile: unexpected read error for ${configPath()}: ${err.message}\n`);
147
160
  throw err;
148
161
  }
149
- _configReadCache = { raw, path: configPath(), mtimeMs: st.mtimeMs, size: st.size, atMs: now };
162
+ _configReadCache = { raw, path: configPath(), stat: statKey(st), atMs: now };
150
163
  return raw;
151
164
  }
152
165
 
@@ -225,6 +238,7 @@ function readConfigFile() {
225
238
  // parse must not be re-served; drop it so the post-quarantine/restore read
226
239
  // hits disk fresh (malformed = never cached).
227
240
  invalidateConfigReadCache();
241
+ if (_inNotificationPass) throw configMidWriteError(err);
228
242
  quarantineMalformedConfig(err);
229
243
  return null;
230
244
  }
@@ -422,19 +436,164 @@ function readAllForRmW() {
422
436
  if (!isPlainObject(parsed)) throw new SyntaxError('config root must be a JSON object');
423
437
  return parsed;
424
438
  } catch (parseErr) {
439
+ if (_inNotificationPass) throw configMidWriteError(parseErr);
425
440
  return restoreAllForRmWOrThrow(parseErr.message, quarantineMalformedConfig(parseErr));
426
441
  }
427
442
  }
428
443
 
444
+ // Secret change marker. Keychain writes never touch mixdog-config.json, so they
445
+ // publish through this file beside it (account -> token of its last change):
446
+ // it rides the same directory watch and notification as a config write. Each
447
+ // process remembers the tokens it has applied and drops exactly the changed
448
+ // accounts from its keychain read cache before listeners reload.
449
+ // A deletion removes the account's entry (the marker holds live accounts only)
450
+ // and moves this token: a process that never saw the account's entry (a secret
451
+ // stored before the marker existed, or set and deleted between two of its
452
+ // syncs) may still cache it, so it drops its whole keychain read cache.
453
+ const SECRETS_MARKER_FILE = 'mixdog-secrets-changed.json';
454
+ const SECRET_DELETED_KEY = '#deleted';
455
+ let _secretsSeen = null;
456
+ let _secretsSeenPath = '';
457
+ let _secretsMarkerStat = '';
458
+
459
+ function secretsMarkerPath() {
460
+ return join(dirname(configPath()), SECRETS_MARKER_FILE);
461
+ }
462
+
463
+ function secretsMarkerStat(path) {
464
+ try {
465
+ const stat = statSync(path);
466
+ return `${stat.mtimeMs}:${stat.size}:${stat.ino}`;
467
+ } catch {
468
+ return 'missing';
469
+ }
470
+ }
471
+
472
+ function readSecretsMarker() {
473
+ try {
474
+ const parsed = parseJsonText(readFileSync(secretsMarkerPath(), 'utf8'));
475
+ return isPlainObject(parsed) ? parsed : {};
476
+ } catch {
477
+ return {};
478
+ }
479
+ }
480
+
481
+ /** Apply marker entries this process has not seen; answers the changed accounts. */
482
+ function syncSecretsMarker() {
483
+ const path = secretsMarkerPath();
484
+ if (_secretsSeenPath !== path) {
485
+ _secretsSeen = null;
486
+ _secretsSeenPath = path;
487
+ }
488
+ _secretsMarkerStat = secretsMarkerStat(path);
489
+ const marker = readSecretsMarker();
490
+ if (_secretsSeen === null) {
491
+ _secretsSeen = marker;
492
+ return [];
493
+ }
494
+ const seen = _secretsSeen;
495
+ const changed = [...new Set([...Object.keys(seen), ...Object.keys(marker)])].filter(
496
+ (account) => seen[account] !== marker[account]
497
+ );
498
+ _secretsSeen = marker;
499
+ if (changed.includes(SECRET_DELETED_KEY)) _keychain.invalidateSecretCache?.();
500
+ else for (const account of changed) if (!account.startsWith('#')) _keychain.invalidateSecretCache?.(account);
501
+ return changed;
502
+ }
503
+
504
+ // The read path of a process that may have no config-change subscriber (an
505
+ // injected config, a helper process): one stat, and a re-read only when the
506
+ // marker moved, so a secret changed or forgotten elsewhere is never served
507
+ // from this process's cache.
508
+ function syncSecretsMarkerIfMoved() {
509
+ if (_secretsSeen !== null && _secretsSeenPath === secretsMarkerPath()) {
510
+ if (secretsMarkerStat(_secretsSeenPath) === _secretsMarkerStat) return;
511
+ }
512
+ syncSecretsMarker();
513
+ }
514
+
515
+ /** account -> token of the last change of that secret this process has
516
+ * applied (its own writes and other processes'). Values are never included. */
517
+ export function secretChangeTokens() {
518
+ if (_secretsSeen === null) syncSecretsMarker();
519
+ return { ..._secretsSeen };
520
+ }
521
+
522
+ const secretChangeToken = () => `${process.pid}:${Date.now()}:${randomUUID()}`;
523
+ function withSecretChange(marker, account, token, deleted) {
524
+ const next = { ...(isPlainObject(marker) ? marker : {}) };
525
+ if (deleted) {
526
+ delete next[account];
527
+ next[SECRET_DELETED_KEY] = token;
528
+ } else {
529
+ next[account] = token;
530
+ }
531
+ return next;
532
+ }
533
+
534
+ function beginSecretChange() {
535
+ // Other processes' changes are applied first, so recording our own token
536
+ // never absorbs theirs unapplied.
537
+ syncSecretsMarker();
538
+ return secretChangeToken();
539
+ }
540
+
541
+ function finishSecretChange(account, token, deleted) {
542
+ // This process already holds the new value (the keychain module updated its
543
+ // cache), so its own change is recorded as applied.
544
+ _secretsSeen = withSecretChange(_secretsSeen, account, token, deleted);
545
+ _secretsMarkerStat = secretsMarkerStat(secretsMarkerPath());
546
+ notifyConfigChanged();
547
+ }
548
+
549
+ const secretMarkerFailure = (err) =>
550
+ process.stderr.write(`[config] secret change marker write failed: ${err?.message || err}\n`);
551
+
552
+ // Never throws: the secret itself is already stored; a marker that could not
553
+ // be written is reported and only delays what other processes see.
554
+ function publishSecretChange(account, deleted = false) {
555
+ const token = beginSecretChange();
556
+ try {
557
+ mkdirSync(dirname(secretsMarkerPath()), { recursive: true, mode: 0o700 });
558
+ updateJsonAtomicSync(secretsMarkerPath(), (marker) => withSecretChange(marker, account, token, deleted), {
559
+ mode: 0o600,
560
+ });
561
+ } catch (err) {
562
+ secretMarkerFailure(err);
563
+ }
564
+ finishSecretChange(account, token, deleted);
565
+ }
566
+
567
+ async function publishSecretChangeAsync(account, deleted = false) {
568
+ const token = beginSecretChange();
569
+ try {
570
+ mkdirSync(dirname(secretsMarkerPath()), { recursive: true, mode: 0o700 });
571
+ await updateJsonAtomic(secretsMarkerPath(), (marker) => withSecretChange(marker, account, token, deleted), {
572
+ mode: 0o600,
573
+ });
574
+ } catch (err) {
575
+ secretMarkerFailure(err);
576
+ }
577
+ finishSecretChange(account, token, deleted);
578
+ }
579
+
429
580
  // Config-change notification. In-process writes notify directly after the file
430
581
  // is persisted; writes from other processes arrive through one lazily started
431
582
  // directory watch (the atomic rename replaces the file, which would orphan a
432
583
  // file-level watch on POSIX). Bursts coalesce into one listener pass.
433
584
  const CONFIG_CHANGE_DEBOUNCE_MS = 100;
585
+ // A watch that failed (or could not start) is re-established on this delay
586
+ // while anyone listens; changes missed meanwhile are announced once it is back.
587
+ const CONFIG_WATCH_RETRY_MS = 1000;
588
+ const WATCHED_FILES = new Set(['mixdog-config.json', SECRETS_MARKER_FILE]);
434
589
  const _configChangeListeners = new Set();
435
590
  let _configChangeTimer = null;
436
591
  let _configWatcher = null;
437
592
  let _configWatchDir = '';
593
+ let _configWatchRetryTimer = null;
594
+
595
+ /** The directory watch implementation; tests substitute a failing watcher. */
596
+ export const configWatchDeps = { watch: fsWatch };
438
597
 
439
598
  function stopConfigWatcher() {
440
599
  try {
@@ -444,46 +603,142 @@ function stopConfigWatcher() {
444
603
  _configWatchDir = '';
445
604
  }
446
605
 
447
- function notifyConfigChanged() {
448
- if (!_configChangeListeners.size) return;
449
- if (_configChangeTimer) clearTimeout(_configChangeTimer);
450
- _configChangeTimer = setTimeout(() => {
451
- _configChangeTimer = null;
452
- invalidateConfigReadCache();
606
+ // The watched files' bytes at the last listener pass (or the first subscribe).
607
+ // A pass caused only by the watch finds nothing to do when they are unchanged,
608
+ // e.g. another process rewriting a marker with identical content.
609
+ let _configChangeForced = false;
610
+ let _watchedContent = null;
611
+
612
+ function watchedContent() {
613
+ const dir = dirname(configPath());
614
+ return [...WATCHED_FILES].map((file) => {
615
+ try {
616
+ return readFileSync(join(dir, file), 'latin1');
617
+ } catch {
618
+ return null;
619
+ }
620
+ });
621
+ }
622
+
623
+ // A config that does not parse while a notification pass runs its listeners
624
+ // is usually a write in progress (a hand edit saved half-typed or torn, maybe
625
+ // landing after the pass began): every read of the pass (readConfigFile,
626
+ // readAllForRmW) then throws instead of quarantining it, so the listeners keep
627
+ // their current config, and the pass runs again once shortly. Only reads
628
+ // outside a pass (boot, explicit reads, writes) quarantine it.
629
+ const CONFIG_SETTLE_RETRY_MS = 300;
630
+ let _configSettleTimer = null;
631
+ let _configSettleRetried = false;
632
+
633
+ function configMidWriteError(parseErr) {
634
+ // The retry runs the listeners even when the bytes then equal the ones this
635
+ // pass saw (the save completed back to them).
636
+ _configChangeForced = true;
637
+ if (!_configSettleRetried && !_configSettleTimer && _configChangeListeners.size) {
638
+ _configSettleTimer = setTimeout(() => {
639
+ _configSettleTimer = null;
640
+ _configSettleRetried = true;
641
+ void runConfigChangeListeners();
642
+ }, CONFIG_SETTLE_RETRY_MS);
643
+ _configSettleTimer.unref?.();
644
+ }
645
+ const error = new Error(
646
+ `[config] mixdog-config.json does not parse yet (${parseErr.message}); keeping the current config`
647
+ );
648
+ error.code = 'ECONFIG_MID_WRITE';
649
+ return error;
650
+ }
651
+
652
+ async function runConfigChangeListeners() {
653
+ const forced = _configChangeForced;
654
+ _configChangeForced = false;
655
+ const content = watchedContent();
656
+ const last = _watchedContent;
657
+ if (!forced && Array.isArray(last) && last.every((value, index) => value === content[index])) return;
658
+ _watchedContent = content;
659
+ invalidateConfigReadCache();
660
+ // A Linux keyring is read only through a snapshot, which the invalidation
661
+ // dropped: re-take it so listeners reload the changed keys.
662
+ if (syncSecretsMarker().length && process.platform === 'linux') {
663
+ try {
664
+ await _prewarmSecrets?.();
665
+ } catch {}
666
+ }
667
+ _inNotificationPass = true;
668
+ try {
453
669
  for (const listener of [..._configChangeListeners]) {
454
670
  try {
455
671
  listener();
456
672
  } catch {}
457
673
  }
674
+ } finally {
675
+ _inNotificationPass = false;
676
+ }
677
+ }
678
+
679
+ // In-process writes and a re-established watch always run the listeners (a
680
+ // secret stored while its marker write failed changes no watched byte).
681
+ function notifyConfigChanged({ fromWatch = false } = {}) {
682
+ if (!_configChangeListeners.size) return;
683
+ if (!fromWatch) _configChangeForced = true;
684
+ _configSettleRetried = false;
685
+ if (_configChangeTimer) clearTimeout(_configChangeTimer);
686
+ _configChangeTimer = setTimeout(() => {
687
+ _configChangeTimer = null;
688
+ void runConfigChangeListeners();
458
689
  }, CONFIG_CHANGE_DEBOUNCE_MS);
459
690
  _configChangeTimer.unref?.();
460
691
  }
461
692
 
693
+ function scheduleConfigWatchRetry() {
694
+ if (_configWatchRetryTimer || !_configChangeListeners.size) return;
695
+ _configWatchRetryTimer = setTimeout(() => {
696
+ _configWatchRetryTimer = null;
697
+ if (!_configChangeListeners.size) return;
698
+ ensureConfigWatcher();
699
+ if (_configWatcher) notifyConfigChanged();
700
+ }, CONFIG_WATCH_RETRY_MS);
701
+ _configWatchRetryTimer.unref?.();
702
+ }
703
+
462
704
  function ensureConfigWatcher() {
463
705
  const dir = dirname(configPath());
464
706
  if (_configWatcher && _configWatchDir === dir) return;
465
707
  stopConfigWatcher();
466
708
  try {
467
- _configWatcher = fsWatch(dir, (_event, filename) => {
468
- if (!filename || String(filename) === 'mixdog-config.json') notifyConfigChanged();
709
+ const watcher = configWatchDeps.watch(dir, (_event, filename) => {
710
+ if (!filename || WATCHED_FILES.has(String(filename))) notifyConfigChanged({ fromWatch: true });
469
711
  });
470
- _configWatcher.unref?.();
471
- _configWatcher.on?.('error', stopConfigWatcher);
712
+ watcher.unref?.();
713
+ watcher.on?.('error', () => {
714
+ if (_configWatcher !== watcher) return;
715
+ stopConfigWatcher();
716
+ scheduleConfigWatchRetry();
717
+ });
718
+ _configWatcher = watcher;
472
719
  _configWatchDir = dir;
473
720
  } catch {
474
721
  _configWatcher = null;
722
+ scheduleConfigWatchRetry();
475
723
  }
476
724
  }
477
725
 
478
- /** Subscribe to persisted config changes (this process or another). Returns unsubscribe. */
726
+ /** Subscribe to persisted config and secret changes (this process or another). Returns unsubscribe. */
479
727
  export function subscribeConfigChange(listener) {
728
+ if (!_configChangeListeners.size) _watchedContent = watchedContent();
480
729
  _configChangeListeners.add(listener);
730
+ // The first subscriber fixes the secret baseline this process applies from.
731
+ if (_secretsSeen === null) syncSecretsMarker();
481
732
  ensureConfigWatcher();
482
733
  return () => {
483
734
  _configChangeListeners.delete(listener);
484
735
  if (!_configChangeListeners.size) {
485
736
  if (_configChangeTimer) clearTimeout(_configChangeTimer);
486
737
  _configChangeTimer = null;
738
+ clearTimeout(_configSettleTimer);
739
+ _configSettleTimer = null;
740
+ if (_configWatchRetryTimer) clearTimeout(_configWatchRetryTimer);
741
+ _configWatchRetryTimer = null;
487
742
  stopConfigWatcher();
488
743
  }
489
744
  };
@@ -664,6 +919,7 @@ function _readSecret(account) {
664
919
  const envVal = process.env[_envKey(account)];
665
920
  if (envVal) return envVal;
666
921
  try {
922
+ syncSecretsMarkerIfMoved();
667
923
  return _getSecret(account);
668
924
  } catch {
669
925
  return null;
@@ -692,6 +948,7 @@ export function saveSecret(account, value) {
692
948
  } catch (err) {
693
949
  throw saveSecretError(account, err);
694
950
  }
951
+ publishSecretChange(account);
695
952
  }
696
953
 
697
954
  /** Non-blocking saveSecret: Linux secret-tool runs off the event loop. */
@@ -701,6 +958,7 @@ export async function saveSecretAsync(account, value) {
701
958
  } catch (err) {
702
959
  throw saveSecretError(account, err);
703
960
  }
961
+ await publishSecretChangeAsync(account);
704
962
  }
705
963
 
706
964
  function saveSecretError(account, err) {
@@ -725,11 +983,49 @@ function saveSecretError(account, err) {
725
983
  /** Remove a secret from the OS keychain (if present) and the Linux fallback file. */
726
984
  export function deleteSecret(account) {
727
985
  _deleteSecret(account);
986
+ publishSecretChange(account, true);
728
987
  }
729
988
 
730
989
  /** Non-blocking deleteSecret: Linux secret-tool runs off the event loop. */
731
990
  export async function deleteSecretAsync(account) {
732
991
  await _deleteSecretAsync(account);
992
+ await publishSecretChangeAsync(account, true);
993
+ }
994
+
995
+ /**
996
+ * The keychain as a credential store for modules that keep their own secrets
997
+ * in it (MCP OAuth tokens and client secrets, Gmail app passwords). Reads are
998
+ * the keychain's own; every write publishes the secret change marker exactly
999
+ * as saveSecret/deleteSecret do, so other processes learn of it. Write errors
1000
+ * stay the keychain's: the provider-key environment hint of saveSecret does
1001
+ * not apply to these accounts. Calls reach the keychain module at call time.
1002
+ * `{ announce: false }` writes without the marker, for a change other
1003
+ * processes observe by their own means (an MCP OAuth token refresh: its
1004
+ * revision marker), so it does not reach every runtime as a settings change.
1005
+ * Reads first apply the marker, so a process without a config-change
1006
+ * subscriber never serves a secret changed or forgotten elsewhere.
1007
+ */
1008
+ export const keychainSecretStore = Object.freeze({
1009
+ getSecretAsync(account) {
1010
+ syncSecretsMarkerIfMoved();
1011
+ return _keychain.getSecretAsync(account);
1012
+ },
1013
+ invalidateSecretCache: (account) => _keychain.invalidateSecretCache?.(account),
1014
+ async setSecretAsync(account, value, { announce = true } = {}) {
1015
+ await _keychain.setSecretAsync(account, value);
1016
+ if (announce) await publishSecretChangeAsync(account);
1017
+ },
1018
+ async deleteSecretAsync(account, { announce = true } = {}) {
1019
+ await _keychain.deleteSecretAsync(account);
1020
+ if (announce) await publishSecretChangeAsync(account, true);
1021
+ },
1022
+ });
1023
+
1024
+ /** Announce a change of state kept outside mixdog-config.json that settings
1025
+ * depend on (`plugins`: the plugin registry), under a reserved `#` key of the
1026
+ * secret change marker, so it reaches other processes on the same path. */
1027
+ export function announceStoredStateChange(key) {
1028
+ publishSecretChange(`#${key}`);
733
1029
  }
734
1030
 
735
1031
  /** Retry a failed Linux keyring read; true when it just recovered. */
@@ -763,6 +1059,7 @@ export function getKeychainStatus() {
763
1059
  */
764
1060
  export function hasStoredSecret(account) {
765
1061
  try {
1062
+ syncSecretsMarkerIfMoved();
766
1063
  if (typeof _hasSecret === 'function') return !!_hasSecret(account);
767
1064
  return !!_getSecret(account);
768
1065
  } catch {
@@ -1,7 +1,7 @@
1
- // What a multi-account connector server tells the model about itself (MCP
1
+ // What a connector server tells the model about its accounts (MCP
2
2
  // `instructions`), in one line: the connected accounts, and that each tool
3
- // takes `account` (asked of the user when several are connected and none was
4
- // named). An account that cannot be used right now is listed with why.
3
+ // takes `account` (left out, the account used last). An account that cannot
4
+ // be used right now is listed with why.
5
5
 
6
6
  /** The MCP instructions naming `accounts` (`{ email, note? }`, `note` a short
7
7
  * reason it is unusable such as "needs sign-in"; one without an address is
@@ -12,12 +12,12 @@ export function connectorAccountsInstructions(accounts) {
12
12
  const list = named.map(({ email, note }) => (note ? `${email} (${note})` : email)).join(', ');
13
13
  return named.length === 1
14
14
  ? `Accounts: ${list}. \`account\` may be left out.`
15
- : `Accounts: ${list}. Pass \`account\`; if the user named none and there are several, ask which.`;
15
+ : `Accounts: ${list}. \`account\` picks one; left out, a call uses the account used last, and its result names it.`;
16
16
  }
17
17
 
18
18
  /** The account addresses instructions from connectorAccountsInstructions name. */
19
19
  export function accountsOfInstructions(instructions) {
20
- const list = /^Accounts: (.+?)\. (?:`account`|Pass `account`)/.exec(String(instructions || ''))?.[1] || '';
20
+ const list = /^Accounts: (.+?)\. `account`/.exec(String(instructions || ''))?.[1] || '';
21
21
  return list
22
22
  .split(', ')
23
23
  .map((part) => part.replace(/ \(.*\)$/, '').trim())
@@ -37,12 +37,7 @@ export const CONNECTOR_IDS: readonly string[];
37
37
  export function connectorById(id: unknown): ConnectorCatalogEntry | null;
38
38
  export function connectorOfServer(cfg: unknown): string;
39
39
  export function connectorToolDefault(connectorId: string, tool: string): 'auto' | 'needs_approval';
40
- export function connectorServerInput(
41
- entry: ConnectorCatalogEntry,
42
- name: string,
43
- key?: string,
44
- options?: { extraAccount?: boolean }
45
- ): Record<string, unknown>;
40
+ export function connectorServerInput(entry: ConnectorCatalogEntry, name: string, key?: string): Record<string, unknown>;
46
41
  export function connectorAppPasswordOnly(entry: ConnectorCatalogEntry | null | undefined): boolean;
47
42
  export function connectorUsesGoogleClient(entry: ConnectorCatalogEntry | null | undefined): boolean;
48
43
  export function connectorMultiAccount(entry: ConnectorCatalogEntry | null | undefined): boolean;
@@ -52,12 +47,21 @@ export function gmailAppPasswordValue(value: unknown): string;
52
47
  export function gmailAppPasswordAccount(cfg: unknown): string;
53
48
  export function gmailAppPasswordServerInput(name: string, email: string, password: string): Record<string, unknown>;
54
49
 
55
- /** One stored account of a multi-account connector server. */
50
+ /** One stored account of a connector server. */
56
51
  export interface ConnectorAccountEntry {
57
52
  name: string;
58
- url: string;
53
+ /** Its identity, given when it was added (connectorAccountId). */
54
+ id?: string;
55
+ /** Absent: http. */
56
+ type?: string;
57
+ url?: string;
59
58
  headers?: Record<string, string>;
60
59
  oauthClientId?: string;
60
+ /** The account's own sign-in key, when another account signs in at its URL. */
61
+ oauthKey?: string;
62
+ command?: string;
63
+ args?: string[];
64
+ env?: Record<string, string>;
61
65
  /** `false`: the account is kept but neither connected nor called. */
62
66
  enabled?: boolean;
63
67
  }
@@ -67,6 +71,7 @@ export function connectorAccountServer(
67
71
  cfg: Record<string, unknown>,
68
72
  account: ConnectorAccountEntry
69
73
  ): Record<string, unknown>;
74
+ export function connectorAccountId(cfg: Record<string, unknown>, account: ConnectorAccountEntry): string;
70
75
  export function connectorAccountServers(cfg: unknown): Record<string, unknown>[];
71
76
  export function connectorAccountEnabled(account: ConnectorAccountEntry): boolean;
72
77
  export function connectorLiveAccountServers(cfg: unknown): Record<string, unknown>[];
@@ -76,6 +81,7 @@ export function withConnectorAccountEnabled(
76
81
  enabled: boolean
77
82
  ): Record<string, unknown>;
78
83
  export function connectorAccountEntry(name: string, cfg: Record<string, unknown>): ConnectorAccountEntry;
84
+ export function connectorServerSettings(cfg: Record<string, unknown>): Record<string, unknown>;
79
85
  export function mergeConnectorAccountServers(servers: Record<string, unknown>): {
80
86
  servers: Record<string, unknown>;
81
87
  merged: { connector: string; name: string; from: string[] }[];