mixdog 1.4.2 → 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 (417) hide show
  1. package/package.json +2 -2
  2. package/scripts/build-shipped-history.mjs +15 -5
  3. package/scripts/gate-local.mjs +65 -19
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +2 -1
  6. package/scripts/lib/run-node-tests.mjs +17 -5
  7. package/scripts/lib/test-failure-summary.mjs +1 -8
  8. package/scripts/lib/test-spawn-ledger.mjs +33 -2
  9. package/scripts/post-release-check.mjs +26 -16
  10. package/scripts/provider-pingpong-live.mjs +1 -1
  11. package/scripts/prune-embedding-runtime.mjs +3 -1
  12. package/scripts/release-paths.mjs +7 -1
  13. package/src/defaults/shipped-history.json +20 -0
  14. package/src/defaults/skills/setup/SKILL.md +2 -2
  15. package/src/defaults/skills/setup/references/actions.md +16 -3
  16. package/src/defaults/skills/setup/references/surfaces.md +3 -0
  17. package/src/defaults/skills/setup-guide/SKILL.md +6 -1
  18. package/src/lib/instruction-text.cjs +36 -0
  19. package/src/lib/rules-builder.cjs +34 -20
  20. package/src/orchestration/balanced.md +23 -0
  21. package/src/orchestration/focused.md +22 -0
  22. package/src/orchestration/none.md +5 -0
  23. package/src/orchestration/swarm.md +24 -0
  24. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  25. package/src/rules/agent-mode/MIXY.md +2 -2
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +0 -1
  28. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +4 -2
  29. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +0 -9
  30. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  31. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  32. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  33. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +4 -4
  34. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -1
  35. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +199 -46
  36. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +3 -5
  37. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +9 -3
  38. package/src/runtime/agent/orchestrator/mcp/client.mjs +3 -5
  39. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  40. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  41. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  42. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  43. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  45. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  46. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  47. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  48. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  49. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  50. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  51. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  52. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +10 -1
  53. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  54. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +30 -0
  55. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  56. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  57. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  58. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  59. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  60. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  61. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  62. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  63. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  64. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  65. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  66. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  67. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  68. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  69. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  70. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -48
  71. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  72. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  73. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  74. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +9 -0
  75. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  76. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +1 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  79. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  80. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  81. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +2 -2
  82. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  83. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  84. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  85. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  86. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  87. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  88. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +1 -1
  89. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +1 -1
  90. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +1 -1
  91. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  92. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +1 -2
  94. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  97. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  99. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  100. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  101. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  102. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  103. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  104. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  105. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  106. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +6 -1
  107. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  108. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  109. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  110. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +57 -26
  111. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  112. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  113. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  114. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  115. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  116. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  117. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  118. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  119. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  120. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  121. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  122. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  123. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  124. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  125. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  126. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +19 -0
  127. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +19 -10
  128. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +5 -0
  129. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  130. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +31 -0
  131. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  132. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +42 -6
  133. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  134. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +11 -1
  135. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  136. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  137. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  138. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  139. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  140. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +1 -1
  141. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  142. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  143. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +1 -1
  144. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  145. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  146. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  147. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  148. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  149. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  150. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  151. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  152. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  153. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +14 -5
  154. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +2 -2
  155. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  156. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  157. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  158. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  159. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  160. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  161. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  162. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  163. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  164. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  165. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  166. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  167. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +7 -3
  168. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +27 -9
  169. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  170. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  172. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  173. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1 -2
  174. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  175. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  176. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  177. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  179. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  180. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  181. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  182. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +2 -2
  183. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +1 -1
  184. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -4
  185. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  186. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  187. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  188. package/src/runtime/attachments/store.d.mts +1 -0
  189. package/src/runtime/attachments/store.mjs +2 -2
  190. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  191. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  192. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  193. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  194. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  195. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  196. package/src/runtime/channels/lib/whisper-server.mjs +12 -12
  197. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  198. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  199. package/src/runtime/connectors/connector-accounts-mcp.mjs +169 -33
  200. package/src/runtime/connectors/gmail-app-password.mjs +2 -2
  201. package/src/runtime/connectors/google-mcp.mjs +1 -1
  202. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  203. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  204. package/src/runtime/explore/explorer.mjs +0 -5
  205. package/src/runtime/explore/tool.mjs +3 -3
  206. package/src/runtime/local-provider/hardware.mjs +1 -1
  207. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  208. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  209. package/src/runtime/media/media-usage.mjs +1 -1
  210. package/src/runtime/media/store.mjs +1 -1
  211. package/src/runtime/memory/index.mjs +11 -1
  212. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  213. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  214. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  215. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  216. package/src/runtime/memory/lib/memory.mjs +17 -0
  217. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  218. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  219. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  220. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  221. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  222. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  223. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  224. package/src/runtime/office/capabilities.mjs +1 -1
  225. package/src/runtime/office/core/office-core.mjs +1 -1
  226. package/src/runtime/office/design/content-model.mjs +3 -3
  227. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  228. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  229. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  230. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  231. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  232. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  233. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  234. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  235. package/src/runtime/shared/atomic-file.d.mts +8 -0
  236. package/src/runtime/shared/background-tasks.mjs +22 -4
  237. package/src/runtime/shared/background-wait.mjs +66 -0
  238. package/src/runtime/shared/child-guardian.mjs +17 -7
  239. package/src/runtime/shared/config.mjs +313 -16
  240. package/src/runtime/shared/connector-catalog.d.mts +4 -5
  241. package/src/runtime/shared/connector-catalog.mjs +11 -1
  242. package/src/runtime/shared/file-lock.mjs +8 -3
  243. package/src/runtime/shared/git-runner.mjs +7 -2
  244. package/src/runtime/shared/idle-gc.mjs +30 -7
  245. package/src/runtime/shared/llm/http-agent.mjs +8 -5
  246. package/src/runtime/shared/llm/system-proxy.mjs +2 -1
  247. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  248. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  249. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  250. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  251. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  252. package/src/runtime/shared/process-runner.mjs +8 -4
  253. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  254. package/src/runtime/shared/routine-trigger.mjs +34 -0
  255. package/src/runtime/shared/run-child.d.mts +2 -1
  256. package/src/runtime/shared/run-child.mjs +70 -18
  257. package/src/runtime/shared/session-scratch.mjs +14 -2
  258. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  259. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  260. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  261. package/src/runtime/shared/tool-work-units.mjs +31 -6
  262. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  263. package/src/runtime/shared/turn-worktree-snapshot.mjs +6 -11
  264. package/src/runtime/shared/worker-requests.mjs +17 -3
  265. package/src/runtime/shared/worktrees/branch-management.mjs +1 -5
  266. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  267. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  268. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  269. package/src/runtime/shared/worktrees/git.mjs +44 -11
  270. package/src/runtime/shared/worktrees/include.mjs +6 -4
  271. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  272. package/src/runtime/shared/worktrees/manager.mjs +772 -75
  273. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  274. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  275. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  276. package/src/runtime/tidy/process.mjs +2 -1
  277. package/src/runtime/web-search/index.mjs +3 -22
  278. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  279. package/src/runtime/web-search/tool-defs.mjs +17 -26
  280. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  281. package/src/session-runtime/boot/apis.mjs +27 -4
  282. package/src/session-runtime/boot/begin.mjs +2 -0
  283. package/src/session-runtime/boot/config.mjs +10 -1
  284. package/src/session-runtime/boot/facade.mjs +1 -0
  285. package/src/session-runtime/boot/providers.mjs +70 -3
  286. package/src/session-runtime/boot/session.mjs +2 -0
  287. package/src/session-runtime/boot/tools.mjs +69 -25
  288. package/src/session-runtime/channel-config-api.mjs +1 -0
  289. package/src/session-runtime/config-change-effects.mjs +179 -0
  290. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  291. package/src/session-runtime/config-lifecycle.mjs +160 -24
  292. package/src/session-runtime/conversation-import/discovery.mjs +86 -7
  293. package/src/session-runtime/conversation-import/service.mjs +3 -2
  294. package/src/session-runtime/goal-facade-api.mjs +49 -3
  295. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  296. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  297. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +3 -11
  298. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +18 -4
  299. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  300. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  301. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  302. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  303. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  304. package/src/session-runtime/lifecycle/teardown/session-close.mjs +4 -4
  305. package/src/session-runtime/lifecycle-api.mjs +1 -0
  306. package/src/session-runtime/mcp-glue/server-catalog.mjs +14 -3
  307. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  308. package/src/session-runtime/model-route/set-route.mjs +40 -7
  309. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  310. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  311. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  312. package/src/session-runtime/provider-readiness.mjs +53 -4
  313. package/src/session-runtime/resource-api.mjs +1 -1
  314. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  315. package/src/session-runtime/resource-mcp-connector-accounts.mjs +5 -1
  316. package/src/session-runtime/resource-mcp-secrets.mjs +3 -3
  317. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  318. package/src/session-runtime/routine-executor.mjs +152 -0
  319. package/src/session-runtime/routine-home-turn.mjs +46 -5
  320. package/src/session-runtime/runtime-facade.mjs +5 -0
  321. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  322. package/src/session-runtime/schedule-session-run.mjs +1 -0
  323. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  324. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  325. package/src/session-runtime/services/agent-tool/send-flow.mjs +110 -6
  326. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  327. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  328. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +24 -6
  329. package/src/session-runtime/services/agent-tool.mjs +51 -1
  330. package/src/session-runtime/services/channel-admin.mjs +18 -0
  331. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  332. package/src/session-runtime/services/plugin-admin.mjs +4 -0
  333. package/src/session-runtime/services/seeds.mjs +7 -0
  334. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  335. package/src/session-runtime/session-create/materialize.mjs +4 -2
  336. package/src/session-runtime/session-create/session-options.mjs +2 -0
  337. package/src/session-runtime/settings-builtin-tools-api.mjs +1 -9
  338. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +1 -1
  339. package/src/session-runtime/setup-tool/executor.mjs +8 -1
  340. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  341. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  342. package/src/session-runtime/setup-tool/tool-defs.mjs +26 -1
  343. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  344. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  345. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  346. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  347. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  348. package/src/session-runtime/tool-surface.mjs +38 -1
  349. package/src/session-runtime/turn/agent-ops.mjs +10 -2
  350. package/src/session-runtime/turn/session-ops.mjs +2 -0
  351. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  352. package/src/session-runtime/turn/turn-run.mjs +1 -1
  353. package/src/session-runtime/webhook-session-run.mjs +2 -0
  354. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +1 -4
  355. package/src/session-runtime/workflow-agents-api/agent-route.mjs +3 -10
  356. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  357. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  358. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  359. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  360. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  361. package/src/session-runtime/workspace/session-view.mjs +1 -1
  362. package/src/session-runtime/workspace/transitions.mjs +20 -4
  363. package/src/session-runtime/workspace/worktree-maintenance.mjs +126 -6
  364. package/src/session-runtime/workspace/worktree-setup.mjs +13 -1
  365. package/src/session-runtime/workspace/worktree-tool.mjs +16 -0
  366. package/src/standalone/daemon-agent-control.mjs +25 -8
  367. package/src/standalone/daemon-desktop-runtime.mjs +6 -2
  368. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  369. package/src/standalone/daemon.mjs +54 -2
  370. package/src/standalone/local-session-runtime.mjs +16 -0
  371. package/src/standalone/session-client/daemon-unavailable.mjs +1 -1
  372. package/src/standalone/session-protocol.mjs +11 -0
  373. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  374. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  375. package/src/standalone/session-service/quota-resume.mjs +9 -0
  376. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  377. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  378. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  379. package/src/standalone/session-service/session-calls.mjs +2 -1
  380. package/src/tui/App.jsx +8 -0
  381. package/src/tui/app/clipboard.mjs +1 -1
  382. package/src/tui/app/create-app-pickers.mjs +2 -0
  383. package/src/tui/app/doctor.mjs +2 -2
  384. package/src/tui/app/panel-signature.mjs +1 -1
  385. package/src/tui/app/settings-picker.mjs +53 -8
  386. package/src/tui/app/shell-layout/row-budgets.mjs +2 -2
  387. package/src/tui/app/slash-commands.mjs +1 -1
  388. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  389. package/src/tui/app/slash-dispatch/session-commands.mjs +1 -1
  390. package/src/tui/app/use-prompt-queue-history.mjs +2 -2
  391. package/src/tui/app/use-transcript-activity.mjs +1 -1
  392. package/src/tui/app/use-transcript-window/geometry.mjs +1 -1
  393. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  394. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  395. package/src/tui/components/question-panel-model.mjs +4 -4
  396. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  397. package/src/tui/components/user-message-skills.mjs +1 -1
  398. package/src/tui/dist/index.mjs +309 -30
  399. package/src/tui/markdown/render-ansi.mjs +1 -1
  400. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  401. package/src/tui/session/agent-job-feed.mjs +2 -0
  402. package/src/tui/session/context-state.mjs +3 -0
  403. package/src/tui/session/quota-resume.mjs +1 -1
  404. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  405. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  406. package/src/tui/session/session-api/routes-agent-definitions.mjs +5 -0
  407. package/src/tui/session/session-api/worktree.mjs +13 -1
  408. package/src/tui/session/session-flow/drain.mjs +11 -14
  409. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  410. package/src/tui/session/turn-quiet.mjs +1 -1
  411. package/src/tui/session/turn.mjs +3 -0
  412. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  413. package/src/tui/spinner-meta.mjs +3 -3
  414. package/src/tui/spinner-verbs.mjs +2 -2
  415. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  416. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  417. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -23551,7 +23551,12 @@ async function runAsync(steps) {
23551
23551
  }
23552
23552
  function* readLockOwner(lockPath) {
23553
23553
  try {
23554
- const parts = String(yield ["read", lockPath]).trim().split(/\s+/);
23554
+ const text = String(yield ["read", lockPath]).trim();
23555
+ if (text.startsWith("{")) {
23556
+ const legacyPid = Number(JSON.parse(text)?.pid);
23557
+ return { pid: Number.isInteger(legacyPid) && legacyPid > 0 ? legacyPid : null, token: null };
23558
+ }
23559
+ const parts = text.split(/\s+/);
23555
23560
  const pid = Number.parseInt(parts[0], 10);
23556
23561
  return {
23557
23562
  pid: Number.isFinite(pid) && pid > 0 ? pid : null,
@@ -24031,6 +24036,19 @@ function settlesWithin(promise, ms) {
24031
24036
  });
24032
24037
  return Promise.race([promise.then(() => true), bound]).finally(() => clearTimeout(timer2));
24033
24038
  }
24039
+ async function readTarget(path2, read) {
24040
+ const key = targetKey(path2);
24041
+ let use = useOf(key);
24042
+ while (use.renaming) use = await outwaitRename(key, use);
24043
+ use.reads += 1;
24044
+ try {
24045
+ return await read();
24046
+ } finally {
24047
+ use.reads -= 1;
24048
+ if (use.reads === 0) for (const done of use.drained.splice(0)) done();
24049
+ forgetIfIdle(key, use);
24050
+ }
24051
+ }
24034
24052
  async function renameOver(src, dst) {
24035
24053
  const key = targetKey(dst);
24036
24054
  let use = useOf(key);
@@ -24256,6 +24274,14 @@ function readContentOrNullSync(filePath) {
24256
24274
  throw err;
24257
24275
  }
24258
24276
  }
24277
+ async function readContentOrNullAsync(filePath) {
24278
+ try {
24279
+ return await readTarget(filePath, () => readFileAsync3(filePath));
24280
+ } catch (err) {
24281
+ if (err?.code === "ENOENT") return null;
24282
+ throw err;
24283
+ }
24284
+ }
24259
24285
  function reportDamaged(filePath, error, outcome) {
24260
24286
  const reason = String(error?.message || error).replace(/[\0-\x1f]/g, (c) => `\\x${c.charCodeAt(0).toString(16)}`);
24261
24287
  process.stderr.write(`[state] ${filePath} is damaged (${reason}); ${outcome}
@@ -24275,6 +24301,20 @@ function recoverDamagedSync(filePath, parse, opts) {
24275
24301
  reportDamaged(filePath, current.error, recoveredOutcome(aside, backup));
24276
24302
  return backup.state === "ok" ? backup : { state: "absent" };
24277
24303
  }
24304
+ async function recoverDamagedAsync(filePath, parse, opts) {
24305
+ const current = parse(await readContentOrNullAsync(filePath));
24306
+ if (current.state !== "damaged") return current;
24307
+ const backup = opts.restoreBackup === false ? NO_BACKUP : parse(await readContentOrNullAsync(`${filePath}.bak`));
24308
+ if (backup.state !== "ok" && opts.keepWithoutBackup) {
24309
+ reportDamaged(filePath, current.error, KEPT_IN_PLACE);
24310
+ return { state: "absent" };
24311
+ }
24312
+ const aside = quarantinePath(filePath);
24313
+ await renameWithRetry(filePath, aside, opts);
24314
+ if (backup.state === "ok") await publishFileAsync(filePath, backup.content, restoreOpts(opts));
24315
+ reportDamaged(filePath, current.error, recoveredOutcome(aside, backup));
24316
+ return backup.state === "ok" ? backup : { state: "absent" };
24317
+ }
24278
24318
  function readJsonStateSync(filePath, { validate: validate2, decode, fallback = null, ...opts } = {}) {
24279
24319
  const parse = stateParser(validate2, decode);
24280
24320
  const first = parse(readContentOrNullSync(filePath));
@@ -24290,6 +24330,13 @@ function readJsonStateSync(filePath, { validate: validate2, decode, fallback = n
24290
24330
  }
24291
24331
  return recovered.state === "ok" ? recovered.value : fallback;
24292
24332
  }
24333
+ async function readForMutationAsync(filePath, opts) {
24334
+ const current = parseAnyJson(await readContentOrNullAsync(filePath));
24335
+ if (current.state === "ok") return current.value;
24336
+ if (current.state === "absent") return null;
24337
+ const recovered = await recoverDamagedAsync(filePath, parseAnyJson, opts);
24338
+ return recovered.state === "ok" ? recovered.value : null;
24339
+ }
24293
24340
  async function writeFileAtomicAsync(filePath, data, opts = {}) {
24294
24341
  assertTestSecretWriteSafe(filePath, opts);
24295
24342
  const run = () => publishFileAsync(filePath, data, opts);
@@ -24356,6 +24403,20 @@ function writeJsonAtomicAsync(filePath, value, opts = {}) {
24356
24403
  return writeFileAtomicAsync(filePath, `${JSON.stringify(value, null, opts.compact ? 0 : 2)}
24357
24404
  `, jsonBackupOpts(opts));
24358
24405
  }
24406
+ async function updateJsonAtomic(filePath, mutator, opts = {}) {
24407
+ const { lock: _lock, ...writeOpts } = opts;
24408
+ return withFileLock(
24409
+ `${filePath}.lock`,
24410
+ async () => {
24411
+ const cur = await readForMutationAsync(filePath, writeOpts);
24412
+ const next = mutator(cur);
24413
+ if (next === void 0) return cur;
24414
+ await writeJsonAtomicAsync(filePath, next, { ...writeOpts, lock: false });
24415
+ return next;
24416
+ },
24417
+ opts
24418
+ );
24419
+ }
24359
24420
  var _ioCeiling, _ioLimit, _ioActive, _ioFastStreak, _ioQueue, RETRY_CODES, RENAME_READ_WAIT_MS, targetUse, targetKey, FILE_FSYNC_TOLERATED, DIR_FSYNC_TOLERATED, keepsAsBackup, backupWriteOpts, jsonBackupOpts, quarantinePath, LOCK_BUSY_CODES, STATE_UNSUPPORTED, acceptAny, utf8Text, stateParser, restoreOpts, KEPT_IN_PLACE, NO_BACKUP, recoveredOutcome, parseAnyJson;
24360
24421
  var init_atomic_file = __esm({
24361
24422
  "src/runtime/shared/atomic-file.mjs"() {
@@ -36033,7 +36094,7 @@ var SLASH_COMMANDS = [
36033
36094
  {
36034
36095
  name: "goal",
36035
36096
  usage: "/goal",
36036
- params: "[objective --time 1h --time-mode max|status|pause|resume|edit|stop]",
36097
+ params: "[objective --time 1h|status|pause|resume|edit|stop]",
36037
36098
  description: "Run and manage a durable session Goal"
36038
36099
  },
36039
36100
  {
@@ -41346,13 +41407,8 @@ function goalUnit(a) {
41346
41407
  const verbs = {
41347
41408
  status: ["Checking", "Checked"],
41348
41409
  create: ["Creating", "Created"],
41349
- pause: ["Pausing", "Paused"],
41350
- resume: ["Resuming", "Resumed"],
41351
- set_tasks: ["Planning", "Planned"],
41352
- update_tasks: ["Updating", "Updated"],
41353
41410
  complete: ["Completing", "Completed"],
41354
- block: ["Blocking", "Blocked"],
41355
- abandon: ["Abandoning", "Abandoned"]
41411
+ block: ["Blocking", "Blocked"]
41356
41412
  }[action] || ["Updating", "Updated"];
41357
41413
  return unitDescriptor("Setup", {
41358
41414
  count: 1,
@@ -41442,6 +41498,12 @@ function agentUnit(a) {
41442
41498
  if (/^(?:status|read|list)$/.test(type)) {
41443
41499
  return unitDescriptor("Agent", { count, active: "Checking", done: "Checked", noun: "agent" });
41444
41500
  }
41501
+ if (type === "cancel") {
41502
+ return unitDescriptor("Agent", { count, active: "Cancelling", done: "Cancelled", noun: "agent", effect: true });
41503
+ }
41504
+ if (type === "close") {
41505
+ return unitDescriptor("Agent", { count, active: "Ending", done: "Ended", noun: "agent", effect: true });
41506
+ }
41445
41507
  return unitDescriptor("Agent", { count, noun: "agent" });
41446
41508
  }
41447
41509
  function taskUnit(a) {
@@ -41533,6 +41595,25 @@ function cwdUnit(a) {
41533
41595
  pluralNoun: "working directories"
41534
41596
  });
41535
41597
  }
41598
+ function sessionUnit(a) {
41599
+ const action = String(a.action || a.type || "").toLowerCase();
41600
+ if (action === "create") {
41601
+ return unitDescriptor("Setup", { active: "Creating", done: "Created", noun: "session", effect: true });
41602
+ }
41603
+ if (action === "send") {
41604
+ return unitDescriptor("Setup", { active: "Sending to", done: "Sent to", noun: "session", effect: true });
41605
+ }
41606
+ if (action === "cancel") {
41607
+ return unitDescriptor("Setup", { active: "Cancelling", done: "Cancelled", noun: "session", effect: true });
41608
+ }
41609
+ if (action === "delete") {
41610
+ return unitDescriptor("Setup", { active: "Deleting", done: "Deleted", noun: "session", effect: true });
41611
+ }
41612
+ if (/^(?:list|bots|read|suggest)$/.test(action)) {
41613
+ return unitDescriptor("Setup", { active: "Checking", done: "Checked", noun: "session" });
41614
+ }
41615
+ return cwdUnit(a);
41616
+ }
41536
41617
  var TOOL_UNITS = /* @__PURE__ */ new Map([
41537
41618
  [
41538
41619
  "read",
@@ -41643,7 +41724,7 @@ var TOOL_UNITS = /* @__PURE__ */ new Map([
41643
41724
  ],
41644
41725
  ["cwd", cwdUnit],
41645
41726
  // legacy: old transcripts
41646
- ["session", cwdUnit]
41727
+ ["session", sessionUnit]
41647
41728
  ]);
41648
41729
  function mcpUnit(name, a) {
41649
41730
  const mcp = parseMcpToolName(name);
@@ -50908,8 +50989,8 @@ function buildSpinnerMeta({
50908
50989
  thinkingParts,
50909
50990
  tokensText: tokens > 0 ? `${formatSpinnerTokens(tokens)} tokens` : "",
50910
50991
  // The count appears with the FIRST token (user: 30초가 아니라 바로).
50911
- // Elapsed was never gated, so the byline used to grow a second field
50912
- // mid-turn for no reason the reader could see; now both arrive together.
50992
+ // Elapsed is never gated, so showing tokens with the first token keeps the
50993
+ // byline from growing a second field mid-turn; both arrive together.
50913
50994
  showTokens: tokens > 0,
50914
50995
  thinkingText,
50915
50996
  thinkingActive: Boolean(thinking || Number(thinkingSince) > 0),
@@ -62370,6 +62451,7 @@ function createSettingsNavigation({ openers, openSettingsPicker, setSettingsProm
62370
62451
  import { readFileSync as readFileSync11, readdirSync as readdirSync2, statSync as statSync5, mkdirSync as mkdirSync5, existsSync as existsSync10, watch as fsWatch } from "node:fs";
62371
62452
  import { basename as basename6, join as join12, dirname as dirname9 } from "node:path";
62372
62453
  import { createRequire as createRequire3 } from "node:module";
62454
+ import { randomUUID as randomUUID2 } from "node:crypto";
62373
62455
 
62374
62456
  // src/runtime/shared/object.mjs
62375
62457
  function hasOwn(value, key) {
@@ -62837,6 +62919,7 @@ var AGENT_PROVIDER_ENV_ALIASES = Object.freeze({
62837
62919
 
62838
62920
  // src/runtime/shared/config.mjs
62839
62921
  var _require = createRequire3(import.meta.url);
62922
+ var _keychain = _require("../../lib/keychain-cjs.cjs");
62840
62923
  var {
62841
62924
  getSecret: _getSecret,
62842
62925
  setSecret: _setSecret,
@@ -62848,8 +62931,9 @@ var {
62848
62931
  keychainStatus: _keychainStatus,
62849
62932
  retryKeychain: _retryKeychain,
62850
62933
  refreshKeychainStatus: _refreshKeychainStatus,
62851
- onKeychainRecovered: _onKeychainRecovered
62852
- } = _require("../../lib/keychain-cjs.cjs");
62934
+ onKeychainRecovered: _onKeychainRecovered,
62935
+ prewarmSecrets: _prewarmSecrets
62936
+ } = _keychain;
62853
62937
  function configPath() {
62854
62938
  return join12(resolvePluginData(), "mixdog-config.json");
62855
62939
  }
@@ -62865,6 +62949,7 @@ function withFreshDefaultsVersion(fresh, root) {
62865
62949
  return root;
62866
62950
  }
62867
62951
  var _configReadCache = null;
62952
+ var _inNotificationPass = false;
62868
62953
  var CONFIG_READ_TTL_MS = (() => {
62869
62954
  const n = Number(process.env.MIXDOG_CONFIG_READ_TTL_MS);
62870
62955
  return Number.isFinite(n) && n >= 0 ? n : 0;
@@ -62872,6 +62957,9 @@ var CONFIG_READ_TTL_MS = (() => {
62872
62957
  function invalidateConfigReadCache() {
62873
62958
  _configReadCache = null;
62874
62959
  }
62960
+ function statKey(st) {
62961
+ return `${st.mtimeMs}:${st.ctimeMs}:${st.size}:${st.ino}`;
62962
+ }
62875
62963
  function readConfigRawCached() {
62876
62964
  const now = Date.now();
62877
62965
  if (_configReadCache && _configReadCache.path !== configPath()) _configReadCache = null;
@@ -62881,7 +62969,7 @@ function readConfigRawCached() {
62881
62969
  }
62882
62970
  try {
62883
62971
  const st2 = statSync5(configPath());
62884
- if (st2.mtimeMs === _configReadCache.mtimeMs && st2.size === _configReadCache.size) {
62972
+ if (statKey(st2) === _configReadCache.stat) {
62885
62973
  _configReadCache.atMs = now;
62886
62974
  return _configReadCache.raw;
62887
62975
  }
@@ -62912,7 +63000,7 @@ function readConfigRawCached() {
62912
63000
  `);
62913
63001
  throw err;
62914
63002
  }
62915
- _configReadCache = { raw, path: configPath(), mtimeMs: st.mtimeMs, size: st.size, atMs: now };
63003
+ _configReadCache = { raw, path: configPath(), stat: statKey(st), atMs: now };
62916
63004
  return raw;
62917
63005
  }
62918
63006
  function canonicalizeStoredChannelsConfig(value = {}) {
@@ -62965,6 +63053,7 @@ function readConfigFile() {
62965
63053
  return parseJsonText(raw);
62966
63054
  } catch (err) {
62967
63055
  invalidateConfigReadCache();
63056
+ if (_inNotificationPass) throw configMidWriteError(err);
62968
63057
  quarantineMalformedConfig(err);
62969
63058
  return null;
62970
63059
  }
@@ -63108,24 +63197,164 @@ function readAllForRmW() {
63108
63197
  if (!isPlainObject(parsed)) throw new SyntaxError("config root must be a JSON object");
63109
63198
  return parsed;
63110
63199
  } catch (parseErr) {
63200
+ if (_inNotificationPass) throw configMidWriteError(parseErr);
63111
63201
  return restoreAllForRmWOrThrow(parseErr.message, quarantineMalformedConfig(parseErr));
63112
63202
  }
63113
63203
  }
63204
+ var SECRETS_MARKER_FILE = "mixdog-secrets-changed.json";
63205
+ var SECRET_DELETED_KEY = "#deleted";
63206
+ var _secretsSeen = null;
63207
+ var _secretsSeenPath = "";
63208
+ var _secretsMarkerStat = "";
63209
+ function secretsMarkerPath() {
63210
+ return join12(dirname9(configPath()), SECRETS_MARKER_FILE);
63211
+ }
63212
+ function secretsMarkerStat(path2) {
63213
+ try {
63214
+ const stat2 = statSync5(path2);
63215
+ return `${stat2.mtimeMs}:${stat2.size}:${stat2.ino}`;
63216
+ } catch {
63217
+ return "missing";
63218
+ }
63219
+ }
63220
+ function readSecretsMarker() {
63221
+ try {
63222
+ const parsed = parseJsonText(readFileSync11(secretsMarkerPath(), "utf8"));
63223
+ return isPlainObject(parsed) ? parsed : {};
63224
+ } catch {
63225
+ return {};
63226
+ }
63227
+ }
63228
+ function syncSecretsMarker() {
63229
+ const path2 = secretsMarkerPath();
63230
+ if (_secretsSeenPath !== path2) {
63231
+ _secretsSeen = null;
63232
+ _secretsSeenPath = path2;
63233
+ }
63234
+ _secretsMarkerStat = secretsMarkerStat(path2);
63235
+ const marker = readSecretsMarker();
63236
+ if (_secretsSeen === null) {
63237
+ _secretsSeen = marker;
63238
+ return [];
63239
+ }
63240
+ const seen = _secretsSeen;
63241
+ const changed = [.../* @__PURE__ */ new Set([...Object.keys(seen), ...Object.keys(marker)])].filter(
63242
+ (account) => seen[account] !== marker[account]
63243
+ );
63244
+ _secretsSeen = marker;
63245
+ if (changed.includes(SECRET_DELETED_KEY)) _keychain.invalidateSecretCache?.();
63246
+ else for (const account of changed) if (!account.startsWith("#")) _keychain.invalidateSecretCache?.(account);
63247
+ return changed;
63248
+ }
63249
+ function syncSecretsMarkerIfMoved() {
63250
+ if (_secretsSeen !== null && _secretsSeenPath === secretsMarkerPath()) {
63251
+ if (secretsMarkerStat(_secretsSeenPath) === _secretsMarkerStat) return;
63252
+ }
63253
+ syncSecretsMarker();
63254
+ }
63255
+ var secretChangeToken = () => `${process.pid}:${Date.now()}:${randomUUID2()}`;
63256
+ function withSecretChange(marker, account, token, deleted) {
63257
+ const next = { ...isPlainObject(marker) ? marker : {} };
63258
+ if (deleted) {
63259
+ delete next[account];
63260
+ next[SECRET_DELETED_KEY] = token;
63261
+ } else {
63262
+ next[account] = token;
63263
+ }
63264
+ return next;
63265
+ }
63266
+ function beginSecretChange() {
63267
+ syncSecretsMarker();
63268
+ return secretChangeToken();
63269
+ }
63270
+ function finishSecretChange(account, token, deleted) {
63271
+ _secretsSeen = withSecretChange(_secretsSeen, account, token, deleted);
63272
+ _secretsMarkerStat = secretsMarkerStat(secretsMarkerPath());
63273
+ notifyConfigChanged();
63274
+ }
63275
+ var secretMarkerFailure = (err) => process.stderr.write(`[config] secret change marker write failed: ${err?.message || err}
63276
+ `);
63277
+ async function publishSecretChangeAsync(account, deleted = false) {
63278
+ const token = beginSecretChange();
63279
+ try {
63280
+ mkdirSync5(dirname9(secretsMarkerPath()), { recursive: true, mode: 448 });
63281
+ await updateJsonAtomic(secretsMarkerPath(), (marker) => withSecretChange(marker, account, token, deleted), {
63282
+ mode: 384
63283
+ });
63284
+ } catch (err) {
63285
+ secretMarkerFailure(err);
63286
+ }
63287
+ finishSecretChange(account, token, deleted);
63288
+ }
63114
63289
  var CONFIG_CHANGE_DEBOUNCE_MS = 100;
63290
+ var WATCHED_FILES = /* @__PURE__ */ new Set(["mixdog-config.json", SECRETS_MARKER_FILE]);
63115
63291
  var _configChangeListeners = /* @__PURE__ */ new Set();
63116
63292
  var _configChangeTimer = null;
63117
- function notifyConfigChanged() {
63118
- if (!_configChangeListeners.size) return;
63119
- if (_configChangeTimer) clearTimeout(_configChangeTimer);
63120
- _configChangeTimer = setTimeout(() => {
63121
- _configChangeTimer = null;
63122
- invalidateConfigReadCache();
63293
+ var _configChangeForced = false;
63294
+ var _watchedContent = null;
63295
+ function watchedContent() {
63296
+ const dir = dirname9(configPath());
63297
+ return [...WATCHED_FILES].map((file) => {
63298
+ try {
63299
+ return readFileSync11(join12(dir, file), "latin1");
63300
+ } catch {
63301
+ return null;
63302
+ }
63303
+ });
63304
+ }
63305
+ var CONFIG_SETTLE_RETRY_MS = 300;
63306
+ var _configSettleTimer = null;
63307
+ var _configSettleRetried = false;
63308
+ function configMidWriteError(parseErr) {
63309
+ _configChangeForced = true;
63310
+ if (!_configSettleRetried && !_configSettleTimer && _configChangeListeners.size) {
63311
+ _configSettleTimer = setTimeout(() => {
63312
+ _configSettleTimer = null;
63313
+ _configSettleRetried = true;
63314
+ void runConfigChangeListeners();
63315
+ }, CONFIG_SETTLE_RETRY_MS);
63316
+ _configSettleTimer.unref?.();
63317
+ }
63318
+ const error = new Error(
63319
+ `[config] mixdog-config.json does not parse yet (${parseErr.message}); keeping the current config`
63320
+ );
63321
+ error.code = "ECONFIG_MID_WRITE";
63322
+ return error;
63323
+ }
63324
+ async function runConfigChangeListeners() {
63325
+ const forced = _configChangeForced;
63326
+ _configChangeForced = false;
63327
+ const content = watchedContent();
63328
+ const last = _watchedContent;
63329
+ if (!forced && Array.isArray(last) && last.every((value, index) => value === content[index])) return;
63330
+ _watchedContent = content;
63331
+ invalidateConfigReadCache();
63332
+ if (syncSecretsMarker().length && process.platform === "linux") {
63333
+ try {
63334
+ await _prewarmSecrets?.();
63335
+ } catch {
63336
+ }
63337
+ }
63338
+ _inNotificationPass = true;
63339
+ try {
63123
63340
  for (const listener of [..._configChangeListeners]) {
63124
63341
  try {
63125
63342
  listener();
63126
63343
  } catch {
63127
63344
  }
63128
63345
  }
63346
+ } finally {
63347
+ _inNotificationPass = false;
63348
+ }
63349
+ }
63350
+ function notifyConfigChanged({ fromWatch = false } = {}) {
63351
+ if (!_configChangeListeners.size) return;
63352
+ if (!fromWatch) _configChangeForced = true;
63353
+ _configSettleRetried = false;
63354
+ if (_configChangeTimer) clearTimeout(_configChangeTimer);
63355
+ _configChangeTimer = setTimeout(() => {
63356
+ _configChangeTimer = null;
63357
+ void runConfigChangeListeners();
63129
63358
  }, CONFIG_CHANGE_DEBOUNCE_MS);
63130
63359
  _configChangeTimer.unref?.();
63131
63360
  }
@@ -63190,6 +63419,21 @@ var SECRET_ACCOUNTS = Object.freeze({
63190
63419
  agentApiKey: (provider) => `agent.${provider}.apiKey`,
63191
63420
  openaiUsageSessionKey: "agent.openai.usageSessionKey"
63192
63421
  });
63422
+ var keychainSecretStore = Object.freeze({
63423
+ getSecretAsync(account) {
63424
+ syncSecretsMarkerIfMoved();
63425
+ return _keychain.getSecretAsync(account);
63426
+ },
63427
+ invalidateSecretCache: (account) => _keychain.invalidateSecretCache?.(account),
63428
+ async setSecretAsync(account, value, { announce = true } = {}) {
63429
+ await _keychain.setSecretAsync(account, value);
63430
+ if (announce) await publishSecretChangeAsync(account);
63431
+ },
63432
+ async deleteSecretAsync(account, { announce = true } = {}) {
63433
+ await _keychain.deleteSecretAsync(account);
63434
+ if (announce) await publishSecretChangeAsync(account, true);
63435
+ }
63436
+ });
63193
63437
 
63194
63438
  // src/runtime/channels/lib/voice-setup.mjs
63195
63439
  var _voiceRuntimeFetcherPromise = null;
@@ -63704,6 +63948,11 @@ function createSettingsToggles({
63704
63948
  }
63705
63949
 
63706
63950
  // src/tui/app/settings-picker.mjs
63951
+ var heavyGates = /* @__PURE__ */ new WeakMap();
63952
+ var heavyGateOf = (cacheRef) => {
63953
+ if (!heavyGates.has(cacheRef)) heavyGates.set(cacheRef, { running: false, queued: false, freshWrites: 0 });
63954
+ return heavyGates.get(cacheRef);
63955
+ };
63707
63956
  function createSettingsPicker({
63708
63957
  store,
63709
63958
  state,
@@ -63712,6 +63961,7 @@ function createSettingsPicker({
63712
63961
  setSettingsPrompt,
63713
63962
  settingsHeavyCacheRef,
63714
63963
  settingsRequestRef,
63964
+ settingsLiveRefreshRef,
63715
63965
  formatDuration: formatDuration2,
63716
63966
  displayModelName: displayModelName3,
63717
63967
  routeModelLabel: routeModelLabel2,
@@ -63730,10 +63980,18 @@ function createSettingsPicker({
63730
63980
  const own = surface.claim();
63731
63981
  const light = opts.light === true;
63732
63982
  if (!light && !own.paint(settingsHandoffPanel())) return;
63733
- const heavyCache = light ? settingsHeavyCacheRef.current : null;
63983
+ const heavyCache = light && opts.heavy !== true ? settingsHeavyCacheRef.current : null;
63984
+ const gate = heavyGateOf(settingsHeavyCacheRef);
63985
+ const freshWritesAtStart = gate.freshWrites;
63734
63986
  const snapshot = await store.getSettingsSnapshot?.({ heavy: !heavyCache }) || {};
63735
63987
  const view = readSettingsView({ snapshot, heavyCache, state });
63988
+ if (!isCurrentSettingsRequest(requestId)) {
63989
+ if (!heavyCache && own.owns() && gate.freshWrites === freshWritesAtStart) gate.queued = true;
63990
+ return;
63991
+ }
63992
+ if (!own.owns()) return;
63736
63993
  settingsHeavyCacheRef.current = { mcp: view.mcp, plugins: view.plugins, skills: view.skills };
63994
+ if (!heavyCache) gate.freshWrites += 1;
63737
63995
  const toggles = createSettingsToggles({
63738
63996
  store,
63739
63997
  view,
@@ -63758,8 +64016,6 @@ function createSettingsPicker({
63758
64016
  routeModelLabel: routeModelLabel2,
63759
64017
  workflowDisplayName: workflowDisplayName2
63760
64018
  });
63761
- if (!isCurrentSettingsRequest(requestId)) return;
63762
- if (!own.owns()) return;
63763
64019
  setProviderPrompt(null);
63764
64020
  setSettingsPrompt(null);
63765
64021
  own.paint({
@@ -63784,6 +64040,7 @@ function createSettingsPicker({
63784
64040
  own.close();
63785
64041
  }
63786
64042
  });
64043
+ if (settingsLiveRefreshRef) settingsLiveRefreshRef.current = own.defer(() => refreshSettings({ heavy: true }));
63787
64044
  };
63788
64045
  const openSettingsPicker = async (opts = {}) => {
63789
64046
  const requestId = nextSettingsRequest();
@@ -63793,8 +64050,23 @@ function createSettingsPicker({
63793
64050
  store.pushNotice(`settings unavailable: ${error?.message || error}`, "error");
63794
64051
  }
63795
64052
  };
63796
- const refreshSettings = () => {
63797
- void openSettingsPicker({ light: true });
64053
+ const refreshHeavy = () => {
64054
+ const gate = heavyGateOf(settingsHeavyCacheRef);
64055
+ if (gate.running) {
64056
+ gate.queued = true;
64057
+ return;
64058
+ }
64059
+ gate.running = true;
64060
+ void openSettingsPicker({ light: true, heavy: true }).finally(() => {
64061
+ gate.running = false;
64062
+ if (!gate.queued) return;
64063
+ gate.queued = false;
64064
+ settingsLiveRefreshRef?.current?.();
64065
+ });
64066
+ };
64067
+ const refreshSettings = ({ heavy = false } = {}) => {
64068
+ if (heavy) refreshHeavy();
64069
+ else void openSettingsPicker({ light: true });
63798
64070
  };
63799
64071
  const navigation = createSettingsNavigation({ openers, openSettingsPicker, setSettingsPrompt });
63800
64072
  return { openSettingsPicker };
@@ -64104,7 +64376,7 @@ var sessionCommands = {
64104
64376
  store.pushNotice("Goal is unavailable.", "warn");
64105
64377
  return;
64106
64378
  }
64107
- store.pushNotice(result.message || "Goal updated.", "info");
64379
+ store.pushNotice(result.message || "Goal updated.", result.ok === false ? "warn" : "info");
64108
64380
  }).catch((error) => store.pushNotice(`Goal failed: ${error?.message || error}`, "error"));
64109
64381
  return true;
64110
64382
  },
@@ -64298,6 +64570,7 @@ function createAppPickers({
64298
64570
  onboardingPrefetchSeqRef,
64299
64571
  settingsHeavyCacheRef,
64300
64572
  settingsRequestRef,
64573
+ settingsLiveRefreshRef,
64301
64574
  livePickerRef,
64302
64575
  disabledSkills,
64303
64576
  setDisabledSkills,
@@ -64418,6 +64691,7 @@ function createAppPickers({
64418
64691
  setSettingsPrompt,
64419
64692
  settingsHeavyCacheRef,
64420
64693
  settingsRequestRef,
64694
+ settingsLiveRefreshRef,
64421
64695
  formatDuration,
64422
64696
  displayModelName,
64423
64697
  routeModelLabel,
@@ -64903,15 +65177,15 @@ import { join as join16 } from "node:path";
64903
65177
  import { Worker as Worker2 } from "node:worker_threads";
64904
65178
 
64905
65179
  // src/tui/session/transcript-spill/spill-dir.mjs
64906
- import { randomUUID as randomUUID2 } from "node:crypto";
65180
+ import { randomUUID as randomUUID3 } from "node:crypto";
64907
65181
  import { mkdtempSync, readdirSync as readdirSync5, readFileSync as readFileSync14, rmSync as rmSync5, statSync as statSync7, writeFileSync as writeFileSync4 } from "node:fs";
64908
65182
  import { tmpdir as tmpdir3 } from "node:os";
64909
65183
  import { join as join15 } from "node:path";
64910
65184
  var STALE_MS = 24 * 60 * 60 * 1e3;
64911
- var PROCESS_NONCE = randomUUID2();
65185
+ var PROCESS_NONCE = randomUUID3();
64912
65186
 
64913
65187
  // src/tui/session/transcript-spill/spill-writer.mjs
64914
- import { randomUUID as randomUUID3 } from "node:crypto";
65188
+ import { randomUUID as randomUUID4 } from "node:crypto";
64915
65189
  import { mkdirSync as mkdirSync8 } from "node:fs";
64916
65190
  import { dirname as dirname11 } from "node:path";
64917
65191
 
@@ -66506,6 +66780,10 @@ function App2({ store, initialStatusLine = "", forceOnboarding = false, onboardi
66506
66780
  const { btwPanel, btw } = useBtwPanel({ store, sessionId: state.sessionId });
66507
66781
  const settingsHeavyCacheRef = useRef33(null);
66508
66782
  const settingsRequestRef = useRef33(0);
66783
+ const settingsLiveRefreshRef = useRef33(null);
66784
+ useEffect36(() => {
66785
+ if (state.setupChanged) settingsLiveRefreshRef.current?.();
66786
+ }, [state.setupChanged]);
66509
66787
  const [providerPrompt, setProviderPrompt] = useState26(null);
66510
66788
  const oauthSubmitRef = useRef33(false);
66511
66789
  const [settingsPrompt, setSettingsPrompt] = useState26(null);
@@ -66617,6 +66895,7 @@ function App2({ store, initialStatusLine = "", forceOnboarding = false, onboardi
66617
66895
  onboardingPrefetchSeqRef,
66618
66896
  settingsHeavyCacheRef,
66619
66897
  settingsRequestRef,
66898
+ settingsLiveRefreshRef,
66620
66899
  livePickerRef,
66621
66900
  disabledSkills,
66622
66901
  setDisabledSkills,
@@ -33,7 +33,7 @@ const MD_SYNTAX_RE = /[#*`|[>\-_~]|\n\n|(?:^|\n)\d+[.)] |(?:^|\n)\+ |(?:^|\n)={2
33
33
 
34
34
  // GFM strikethrough, pair-only. marked's default `del` also accepts a SINGLE
35
35
  // tilde, which turns approximation prose ("~100", "1~2개") into struck text —
36
- // the reason this tokenizer used to be disabled outright. Requiring `~~` keeps
36
+ // so the default tokenizer cannot be used as is. Requiring `~~` keeps
37
37
  // real strikethrough working and lockstep with the desktop pipeline
38
38
  // (remark-gfm singleTilde:false).
39
39
  const DEL_RE = /^~~(?=[^\s~])([\s\S]*?[^\s~])~~(?!~)/;
@@ -2,6 +2,10 @@ import { parseAgentJob } from '../agent-envelope.mjs';
2
2
  import { notificationQueueKey, resolveTuiRuntimeNotificationDelivery } from '../notification-plan.mjs';
3
3
  import { isTerminalExecutionStatus } from './agent-status-refresh.mjs';
4
4
 
5
+ // The runtime's setup-changed action after an empty session's settings
6
+ // reconcile (session-runtime/boot/tools.mjs CONTEXT_STATUS_REFRESHED_ACTION).
7
+ const CONTEXT_STATUS_REFRESHED = 'context_status_refreshed';
8
+
5
9
  // Routes one runtime notification by its delivery plan: UI-only kinds patch
6
10
  // the store or raise a notice, execution envelopes go through the execution
7
11
  // delivery, everything else becomes a model-visible task notification.
@@ -13,6 +17,7 @@ export function createNotificationRouter({
13
17
  statusRefresh,
14
18
  executionDelivery,
15
19
  modelNotification,
20
+ refreshContextStats = null,
16
21
  getAdmission = () => 'open',
17
22
  }) {
18
23
  let uiOpenSeq = 0;
@@ -20,6 +25,11 @@ export function createNotificationRouter({
20
25
  const uiActions = {
21
26
  'setup-ui': (delivery) => set({ setupUiRequest: { id: delivery.id, at: Date.now() } }),
22
27
  'setup-changed': (delivery) => {
28
+ // An empty session took moved settings: the context gauge re-reads.
29
+ if (delivery.setupAction === CONTEXT_STATUS_REFRESHED) {
30
+ refreshContextStats?.();
31
+ return;
32
+ }
23
33
  // Monotonic like ui-open: consecutive changes by the same action must
24
34
  // each refresh the attached surfaces.
25
35
  setupChangeSeq += 1;
@@ -37,6 +37,7 @@ export function createAgentJobFeed({
37
37
  displayedExecutionNotificationKeys,
38
38
  itemIndexById,
39
39
  pushNotice,
40
+ refreshContextStats = null,
40
41
  now = () => Date.now(),
41
42
  executionResumeTombstoneTtlMs = 30_000,
42
43
  executionResumeTombstoneLimit = 128,
@@ -79,6 +80,7 @@ export function createAgentJobFeed({
79
80
  statusRefresh,
80
81
  executionDelivery,
81
82
  modelNotification,
83
+ refreshContextStats,
82
84
  getAdmission,
83
85
  });
84
86
 
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { contextMeasurementStats } from '../../runtime/shared/context-measurement.mjs';
9
9
  import { goalStateSnapshot } from '../../runtime/agent/orchestrator/runtime-core/goal-state.mjs';
10
+ import { todoSnapshot } from '../../runtime/agent/orchestrator/runtime-core/todo-list.mjs';
10
11
 
11
12
  export function createContextState({
12
13
  runtime,
@@ -92,6 +93,8 @@ export function createContextState({
92
93
  // The daemon-queued quota resume of this session id (identity-stable while
93
94
  // unchanged), so a resume or session switch republishes it with the route.
94
95
  quotaResume: typeof getQuotaResume === 'function' ? getQuotaResume() : null,
96
+ // The session's own step list (identity-stable while unchanged); null when empty.
97
+ todo: todoSnapshot(runtime.session),
95
98
  });
96
99
 
97
100
  const routeState = () => {
@@ -57,7 +57,7 @@ export function latestQuotaFailure(items) {
57
57
 
58
58
  /** The turn key of the failed turndone that ends the transcript, when no
59
59
  * later turn has begun; '' otherwise. */
60
- export function latestFailedTurnKey(items) {
60
+ function latestFailedTurnKey(items) {
61
61
  const transcript = Array.isArray(items) ? items : [];
62
62
  for (let index = transcript.length - 1; index >= 0; index -= 1) {
63
63
  const item = transcript[index];
@@ -34,6 +34,7 @@ export function createDisposeAction(bag, { oauthFlows }) {
34
34
  'unsubscribeCompletionWakeGate',
35
35
  'unsubscribeGitHeadWatch',
36
36
  'unsubscribeWorktreeSetup',
37
+ 'unsubscribeTodo',
37
38
  ]) {
38
39
  try {
39
40
  lifecycle[key]?.();