mixdog 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/README.md +1 -0
  2. package/package.json +2 -2
  3. package/scripts/lib/run-node-tests.mjs +9 -0
  4. package/scripts/prune-desktop-runtime.mjs +3 -0
  5. package/scripts/release-paths.mjs +39 -2
  6. package/scripts/test-direct.mjs +4 -2
  7. package/src/defaults/shipped-history.json +6 -0
  8. package/src/defaults/skills/setup/references/actions.md +5 -2
  9. package/src/defaults/skills/visualize/SKILL.md +157 -0
  10. package/src/defaults/skills/visualize/references/craft.md +88 -0
  11. package/src/headless-command.mjs +56 -3
  12. package/src/headless-exec.mjs +17 -1
  13. package/src/headless-role.mjs +2 -2
  14. package/src/help.mjs +2 -0
  15. package/src/lib/rules-builder.cjs +0 -23
  16. package/src/rules/lead/LEAD.md +2 -2
  17. package/src/rules/shared/70-delivery.md +2 -2
  18. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  19. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
  20. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
  21. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  22. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
  23. package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
  24. package/src/runtime/agent/orchestrator/config.mjs +9 -1
  25. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +47 -7
  26. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +51 -8
  27. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +25 -5
  28. package/src/runtime/agent/orchestrator/mcp/client.mjs +348 -122
  29. package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
  30. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
  31. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
  32. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +13 -1
  33. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
  34. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
  35. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
  36. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +12 -4
  37. package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
  38. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  39. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  40. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
  41. package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
  42. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
  43. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
  44. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +67 -0
  45. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +521 -0
  46. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
  47. package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
  48. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
  49. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +3 -0
  50. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +6 -1
  51. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
  52. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
  53. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
  54. package/src/runtime/agent/orchestrator/providers/registry.mjs +15 -1
  55. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
  56. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
  57. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +12 -11
  58. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
  59. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +11 -0
  60. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +11 -8
  61. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
  62. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
  63. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
  64. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
  65. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +18 -11
  66. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
  67. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
  68. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
  69. package/src/runtime/agent/orchestrator/session/context-utils.mjs +12 -14
  70. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
  71. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
  72. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
  73. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
  74. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -1
  75. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +1 -0
  76. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +17 -7
  77. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
  78. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +12 -2
  79. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -0
  80. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +5 -3
  81. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
  82. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
  83. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
  84. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
  85. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
  86. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
  87. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
  88. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
  89. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
  90. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
  91. package/src/runtime/agent/orchestrator/session/manager.mjs +1 -5
  92. package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
  93. package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
  94. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +29 -19
  95. package/src/runtime/agent/orchestrator/session/read-dedup.mjs +0 -1
  96. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
  97. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
  98. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
  99. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +29 -0
  100. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +5 -1
  101. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +23 -4
  102. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
  103. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +28 -8
  104. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +140 -0
  105. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
  106. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
  107. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
  108. package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
  109. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +31 -12
  110. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
  111. package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
  112. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
  113. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +80 -66
  114. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
  115. package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +5 -1
  116. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
  117. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
  118. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
  119. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
  120. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
  121. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
  122. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
  123. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
  124. package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
  125. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
  126. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
  127. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -10
  128. package/src/runtime/attachments/store.mjs +38 -0
  129. package/src/runtime/channels/index.mjs +1 -5
  130. package/src/runtime/channels/lib/runtime-paths.mjs +8 -23
  131. package/src/runtime/channels/lib/tool-dispatch.mjs +1 -13
  132. package/src/runtime/channels/lib/worker-ipc.mjs +2 -2
  133. package/src/runtime/channels/lib/worker-main.mjs +4 -34
  134. package/src/runtime/shared/atomic-file.mjs +8 -2
  135. package/src/runtime/shared/best-effort-stderr.mjs +8 -0
  136. package/src/runtime/shared/code-graph-state.mjs +12 -0
  137. package/src/runtime/shared/defaults-separation.mjs +2 -0
  138. package/src/runtime/shared/git-runner-worker.mjs +3 -2
  139. package/src/runtime/shared/git-runner.mjs +4 -3
  140. package/src/runtime/shared/llm/default-context-window.mjs +6 -0
  141. package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
  142. package/src/runtime/shared/llm/model-catalog.mjs +240 -118
  143. package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
  144. package/src/runtime/shared/llm/provider-catalog-registry.mjs +156 -0
  145. package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
  146. package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
  147. package/src/runtime/shared/model-proxy-mode.mjs +19 -0
  148. package/src/runtime/shared/provider-accounts.mjs +2 -2
  149. package/src/runtime/shared/provider-api-key.mjs +21 -1
  150. package/src/runtime/shared/schedule-model-ref.mjs +11 -2
  151. package/src/runtime/shared/semver.d.mts +1 -0
  152. package/src/runtime/shared/semver.mjs +57 -0
  153. package/src/runtime/shared/session-usage-totals.mjs +19 -0
  154. package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
  155. package/src/runtime/shared/singleton-owner.mjs +36 -6
  156. package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
  157. package/src/runtime/shared/tool-surface.mjs +9 -2
  158. package/src/runtime/shared/tool-work-units.mjs +14 -0
  159. package/src/runtime/shared/transcript-metadata.mjs +17 -1
  160. package/src/runtime/shared/turn-changes.mjs +791 -0
  161. package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
  162. package/src/runtime/shared/turn-snapshot.mjs +690 -81
  163. package/src/runtime/shared/turn-worktree-snapshot.mjs +161 -11
  164. package/src/runtime/shared/update-checker.mjs +2 -31
  165. package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
  166. package/src/runtime/shared/worktrees/contract.mjs +551 -0
  167. package/src/runtime/shared/worktrees/disk.mjs +57 -0
  168. package/src/runtime/shared/worktrees/git.mjs +247 -0
  169. package/src/runtime/shared/worktrees/include.mjs +480 -0
  170. package/src/runtime/shared/worktrees/lock.mjs +46 -0
  171. package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
  172. package/src/runtime/shared/worktrees/manager.mjs +1215 -0
  173. package/src/runtime/shared/worktrees/merge.mjs +182 -0
  174. package/src/runtime/shared/worktrees/owner.mjs +46 -0
  175. package/src/runtime/shared/worktrees/paths.mjs +62 -0
  176. package/src/runtime/shared/worktrees/registry.mjs +110 -0
  177. package/src/runtime/shared/worktrees/settings.mjs +84 -0
  178. package/src/runtime/shared/worktrees/slug.mjs +62 -0
  179. package/src/runtime/shared/worktrees/test-support.mjs +96 -0
  180. package/src/runtime/visualize-bridge/client.mjs +181 -0
  181. package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
  182. package/src/session-runtime/boot/apis.mjs +35 -0
  183. package/src/session-runtime/boot/begin.mjs +0 -2
  184. package/src/session-runtime/boot/config.mjs +2 -0
  185. package/src/session-runtime/boot/facade.mjs +20 -0
  186. package/src/session-runtime/boot/infrastructure.mjs +1 -0
  187. package/src/session-runtime/boot/session.mjs +1 -0
  188. package/src/session-runtime/boot/tools.mjs +9 -4
  189. package/src/session-runtime/config-lifecycle.mjs +10 -1
  190. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +11 -1
  191. package/src/session-runtime/global-extensions.mjs +2 -2
  192. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
  193. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
  194. package/src/session-runtime/internal-tool-executor.mjs +9 -1
  195. package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
  196. package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
  197. package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
  198. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
  199. package/src/session-runtime/mcp-glue/connect.mjs +11 -6
  200. package/src/session-runtime/mcp-glue/server-catalog.mjs +7 -3
  201. package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
  202. package/src/session-runtime/model-route/route-persist.mjs +3 -0
  203. package/src/session-runtime/model-route/set-route.mjs +15 -2
  204. package/src/session-runtime/notification-bus.mjs +9 -1
  205. package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
  206. package/src/session-runtime/resource-extension-sync.mjs +30 -7
  207. package/src/session-runtime/resource-mcp-api.mjs +27 -10
  208. package/src/session-runtime/route-resolution.mjs +10 -1
  209. package/src/session-runtime/route-state.mjs +16 -2
  210. package/src/session-runtime/runtime-bootstrap.mjs +0 -4
  211. package/src/session-runtime/runtime-core.mjs +5 -0
  212. package/src/session-runtime/runtime-facade.mjs +8 -0
  213. package/src/session-runtime/runtime-paths.mjs +0 -1
  214. package/src/session-runtime/runtime-review-api.mjs +9 -0
  215. package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
  216. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
  217. package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
  218. package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
  219. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
  220. package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
  221. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
  222. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
  223. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  224. package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
  225. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
  226. package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
  227. package/src/session-runtime/services/agent-tool.mjs +1 -0
  228. package/src/session-runtime/services/channel-worker.mjs +1 -1
  229. package/src/session-runtime/services/daemon-candidate.mjs +3 -2
  230. package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
  231. package/src/session-runtime/session-create/session-options.mjs +10 -1
  232. package/src/session-runtime/session-turn-api.mjs +1 -0
  233. package/src/session-runtime/settings-api.mjs +4 -2
  234. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
  235. package/src/session-runtime/settings-profile-api.mjs +27 -2
  236. package/src/session-runtime/settings-worktree-api.mjs +17 -0
  237. package/src/session-runtime/setup-tool/executor.mjs +11 -4
  238. package/src/session-runtime/setup-tool/settings-contract.mjs +3 -1
  239. package/src/session-runtime/setup-tool/tool-defs.mjs +31 -3
  240. package/src/session-runtime/starter-guide-state.mjs +62 -0
  241. package/src/session-runtime/turn/agent-ops.mjs +12 -1
  242. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +13 -3
  243. package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
  244. package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
  245. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
  246. package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
  247. package/src/session-runtime/turn/turn-run.mjs +6 -7
  248. package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
  249. package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -2
  250. package/src/session-runtime/workspace/admission-gate.mjs +197 -0
  251. package/src/session-runtime/workspace/project-branches.mjs +136 -0
  252. package/src/session-runtime/workspace/transition-steps.mjs +364 -0
  253. package/src/session-runtime/workspace/transitions.mjs +651 -0
  254. package/src/session-runtime/workspace/workspace-state.mjs +112 -0
  255. package/src/standalone/channel-binding.mjs +1 -2
  256. package/src/standalone/channel-transport/call-dispatch.mjs +4 -10
  257. package/src/standalone/channel-transport/http-routes.mjs +17 -0
  258. package/src/standalone/channel-transport.mjs +13 -1
  259. package/src/standalone/daemon-channels-loader.mjs +2 -3
  260. package/src/standalone/daemon-desktop-runtime.mjs +1 -0
  261. package/src/standalone/daemon-owner.mjs +372 -0
  262. package/src/standalone/daemon-stored-session-views.mjs +4 -1
  263. package/src/standalone/daemon.mjs +139 -5
  264. package/src/standalone/desktop-service-registry.mjs +20 -0
  265. package/src/standalone/local-session-runtime.mjs +13 -78
  266. package/src/standalone/session-client/attachment-calls.mjs +3 -1
  267. package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
  268. package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
  269. package/src/standalone/session-client.mjs +104 -13
  270. package/src/standalone/session-protocol.mjs +17 -0
  271. package/src/standalone/session-proxy.mjs +3 -0
  272. package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
  273. package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
  274. package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
  275. package/src/standalone/session-service/projection/revisions.mjs +2 -0
  276. package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
  277. package/src/standalone/session-service/projection/workspace.mjs +14 -0
  278. package/src/standalone/session-service/session-calls/session-action.mjs +11 -3
  279. package/src/standalone/session-transport/call-route.mjs +13 -0
  280. package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
  281. package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
  282. package/src/standalone/session-transport/client-registry.mjs +20 -3
  283. package/src/standalone/session-transport/routes.mjs +79 -2
  284. package/src/standalone/session-transport/stack.mjs +2 -0
  285. package/src/standalone/session-transport.mjs +24 -1
  286. package/src/tui/app/message-selector.mjs +2 -1
  287. package/src/tui/app/model-options.mjs +35 -5
  288. package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
  289. package/src/tui/app/model-picker.mjs +4 -2
  290. package/src/tui/dist/index.mjs +332 -36
  291. package/src/tui/index.jsx +10 -2
  292. package/src/tui/session/compaction-view.mjs +147 -0
  293. package/src/tui/session/context-state.mjs +6 -0
  294. package/src/tui/session/initial-state.mjs +3 -0
  295. package/src/tui/session/quota-resume.mjs +2 -1
  296. package/src/tui/session/session-api/commands.mjs +10 -2
  297. package/src/tui/session/session-api/controls.mjs +4 -0
  298. package/src/tui/session/session-api/extensions.mjs +12 -8
  299. package/src/tui/session/session-api/intake/rewind.mjs +2 -1
  300. package/src/tui/session/session-api/integrations.mjs +18 -0
  301. package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
  302. package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
  303. package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
  304. package/src/tui/session/session-api/routes.mjs +10 -1
  305. package/src/tui/session/session-api/settings.mjs +2 -0
  306. package/src/tui/session/session-api/shared.mjs +10 -6
  307. package/src/tui/session/session-api/worktree.mjs +60 -0
  308. package/src/tui/session/session-api.mjs +2 -0
  309. package/src/tui/session/session-flow/auto-clear.mjs +31 -12
  310. package/src/tui/session/session-flow/drain.mjs +15 -1
  311. package/src/tui/session/session-flow/session-reset.mjs +4 -3
  312. package/src/tui/session/session-flow.mjs +2 -0
  313. package/src/tui/session/transcript-intake.mjs +14 -5
  314. package/src/tui/session/turn-stream.mjs +32 -4
  315. package/src/tui/session/turn-tool-cards.mjs +10 -2
  316. package/src/tui/session/turn.mjs +39 -10
  317. package/src/runtime/channels/tool-defs.mjs +0 -17
@@ -11,6 +11,7 @@ import {
11
11
  } from '../../runtime/shared/tool-execution-contract.mjs';
12
12
  import { isLateToolAnnouncement } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
13
13
  import { appendPromptHistory } from '../prompt-history-store.mjs';
14
+ import { newTranscriptMessageId } from '../../runtime/shared/transcript-metadata.mjs';
14
15
  import {
15
16
  buildExecutionResponseToolItem,
16
17
  completionCardFromExecution,
@@ -21,7 +22,7 @@ import { appendAgentResponseTail } from './agent-response-tail.mjs';
21
22
  import { nextId } from './transcript-spill.mjs';
22
23
 
23
24
  export function createTranscriptIntake({ getState, flags, pushItem, patchItem, transcriptRouteMetadata }) {
24
- const upsertSyntheticToolItem = (text, id = nextId(), parsed = null) => {
25
+ const upsertSyntheticToolItem = (text, id = nextId(), parsed = null, messageId = '') => {
25
26
  const synthetic = parsed || parseSyntheticAgentMessage(text);
26
27
  if (!synthetic) return false;
27
28
  const label = synthetic.label || 'notification';
@@ -56,6 +57,7 @@ export function createTranscriptIntake({ getState, flags, pushItem, patchItem, t
56
57
  pushItem({
57
58
  kind: 'tool',
58
59
  id,
60
+ ...(messageId ? { messageId } : {}),
59
61
  name: synthetic.name || 'agent',
60
62
  args,
61
63
  result: synthetic.result,
@@ -75,11 +77,11 @@ export function createTranscriptIntake({ getState, flags, pushItem, patchItem, t
75
77
  // the text parser cannot read still shows up instead of vanishing.
76
78
  if (origin === 'injected' && (extra?.mode === 'task-notification' || extra?.execution)) {
77
79
  const card = completionCardFromExecution(extra?.execution, text);
78
- if (card && upsertSyntheticToolItem(text, id, card)) return;
80
+ if (card && upsertSyntheticToolItem(text, id, card, extra?.messageId)) return;
79
81
  }
80
82
  if (origin === 'injected') {
81
83
  const completion = parseModelVisibleCompletionWrapper(text);
82
- if (completion && upsertSyntheticToolItem(text, id, completion)) return;
84
+ if (completion && upsertSyntheticToolItem(text, id, completion, extra?.messageId)) return;
83
85
  }
84
86
  // The lenient shape-only wrapper check is display-suppression only and
85
87
  // must never hide a real, directly-typed/pasted user prompt just because
@@ -95,13 +97,20 @@ export function createTranscriptIntake({ getState, flags, pushItem, patchItem, t
95
97
  // keep it in model context, but render NOTHING user-facing — not even the
96
98
  // collapsed one-line notice (user request: hide late-tool notices entirely).
97
99
  if (isLateToolAnnouncement(text)) return;
98
- if (upsertSyntheticToolItem(text, id)) return;
100
+ if (upsertSyntheticToolItem(text, id, null, extra?.messageId)) return;
99
101
  // Genuine, directly-typed/pasted user submissions only (never injected or
100
102
  // synthetic paths, which returned above): persist to the cwd-scoped store so
101
103
  // up-arrow history survives across sessions. Runs before pushItem so the
102
104
  // merge in pushItem's user branch (loadPromptHistory) already sees it.
103
105
  if (origin === 'user') appendPromptHistory(getState().cwd, text);
104
- const transcriptMeta = transcriptRouteMetadata();
106
+ // The row carries its message's stable id: the runtime's (a steered
107
+ // message reports it) or, for a typed prompt, a new one that goes with
108
+ // the prompt into the model transcript. An injected row with no message
109
+ // id of its own carries none.
110
+ let messageId = '';
111
+ if (typeof extra?.messageId === 'string' && extra.messageId) messageId = extra.messageId;
112
+ else if (origin === 'user') messageId = newTranscriptMessageId();
113
+ const transcriptMeta = { ...transcriptRouteMetadata(), ...(messageId ? { messageId } : {}) };
105
114
  if (origin === 'user') flags.pendingTranscriptMeta = transcriptMeta;
106
115
  pushItem({
107
116
  kind: 'user',
@@ -5,6 +5,7 @@
5
5
  // scalars); every function here takes it as its first argument.
6
6
  import { TUI_FRAME_MS, yieldToRenderer } from './render-timing.mjs';
7
7
  import { retryStatusLine } from '../../runtime/shared/err-text.mjs';
8
+ import { newTranscriptMessageId } from '../../runtime/shared/transcript-metadata.mjs';
8
9
 
9
10
  // Share Ink's exact 120fps cadence with the frame-batched store. A separate
10
11
  // 16ms timer left every other terminal frame idle, so completed script lines
@@ -59,9 +60,27 @@ function ensureAssistant(stream, initialText = '') {
59
60
  if (!stream.currentAssistantId) {
60
61
  stream.currentAssistantId = stream.nextId();
61
62
  const meta = stream.transcriptMeta;
62
- const assistantAt =
63
- Number.isFinite(Number(meta.assistantAt)) && Number(meta.assistantAt) > 0 ? Number(meta.assistantAt) : Date.now();
64
- meta.assistantAt = assistantAt;
63
+ // A non-streaming continuation was persisted before its text reached this
64
+ // row: the runtime left that message's id and time (ask-session
65
+ // takeAssistant), and the row carries them instead of minting new ones.
66
+ const persisted = stream.claimPersistedAssistant ? meta.persistedAssistant : null;
67
+ if (persisted) meta.persistedAssistant = null;
68
+ let assistantAt = persisted?.at;
69
+ let messageId = persisted?.messageId;
70
+ if (!persisted) {
71
+ assistantAt =
72
+ Number.isFinite(Number(meta.assistantAt)) && Number(meta.assistantAt) > 0
73
+ ? Number(meta.assistantAt)
74
+ : Date.now();
75
+ meta.assistantAt = assistantAt;
76
+ // The reply this segment becomes is persisted with this stable id (the
77
+ // runtime takes it with assistantAt), so a compaction that drops the
78
+ // reply greys this row.
79
+ if (!(typeof meta.assistantMessageId === 'string' && meta.assistantMessageId)) {
80
+ meta.assistantMessageId = newTranscriptMessageId();
81
+ }
82
+ messageId = meta.assistantMessageId;
83
+ }
65
84
  // Do NOT reset currentAssistantText here: the first onTextDelta has
66
85
  // already accumulated the opening chunk before this batched flush runs.
67
86
  // Segment resets are owned by closeAssistantSegment(). Seed the new row
@@ -70,6 +89,7 @@ function ensureAssistant(stream, initialText = '') {
70
89
  stream.updateStreamingTail(stream.currentAssistantId, {
71
90
  text: String(initialText || ''),
72
91
  at: assistantAt,
92
+ messageId,
73
93
  ...stream.routeMeta,
74
94
  });
75
95
  }
@@ -86,6 +106,7 @@ function resetLineScan(stream) {
86
106
  function closeAssistantSegment(stream) {
87
107
  stream.currentAssistantId = null;
88
108
  stream.currentAssistantText = '';
109
+ stream.claimPersistedAssistant = false;
89
110
  resetLineScan(stream);
90
111
  }
91
112
 
@@ -290,11 +311,18 @@ export function appendTextDelta(stream, textChunk) {
290
311
  // Mid-turn assistant text that precedes a tool call from a provider that only
291
312
  // returns the final response.content (no deltas); the streaming path owns
292
313
  // the render when it already produced text for this segment.
293
- export function appendAssistantText(stream, full) {
314
+ export function appendAssistantText(stream, full, { committed = false } = {}) {
294
315
  endThinkingForText(stream);
295
316
  stream.assistantText += full;
296
317
  stream.currentAssistantText += full;
297
318
  stream.pendingTextFlush = true;
319
+ // Only post-commit text is the persisted message's own: its row takes that
320
+ // id. Any other text (a tool preamble published before its message commits)
321
+ // leaves an earlier recorded id unclaimed, so drop it.
322
+ stream.claimPersistedAssistant = committed;
323
+ if (!committed && stream.transcriptMeta && typeof stream.transcriptMeta === 'object') {
324
+ stream.transcriptMeta.persistedAssistant = null;
325
+ }
298
326
  flushStreamBatch(stream);
299
327
  }
300
328
 
@@ -57,10 +57,12 @@ export async function builtinSkillNamesFor(runtime, calls) {
57
57
  }
58
58
 
59
59
  // Transcript spec for a standalone (non-aggregated) tool card.
60
- function standaloneCardSpec(itemId, name, args) {
60
+ function standaloneCardSpec(itemId, name, args, callId = '') {
61
61
  return {
62
62
  kind: 'tool',
63
63
  id: itemId,
64
+ // Ties the card to its call (a compaction that drops it greys the card).
65
+ ...(callId ? { callId } : {}),
64
66
  name,
65
67
  args,
66
68
  result: null,
@@ -221,7 +223,13 @@ function openToolCard(cards, call, index, batch) {
221
223
  // Defer the visible push: the card enters the transcript when its real
222
224
  // header will paint (delay elapsed) or its result lands first, so no
223
225
  // blank placeholder height scrolls the body ahead of the glyphs.
224
- const card = { itemId, callId: callKey, done: false, pushed: false, spec: standaloneCardSpec(itemId, name, args) };
226
+ const card = {
227
+ itemId,
228
+ callId: callKey,
229
+ done: false,
230
+ pushed: false,
231
+ spec: standaloneCardSpec(itemId, name, args, callId),
232
+ };
225
233
  cards.deferredCards.registerCard(card);
226
234
  trackCard(cards, callId, card);
227
235
  // Immediate row-reserve is deferred until every touched aggregate has its
@@ -18,6 +18,7 @@ import { isRejected429, safeErrorDetails } from '../../runtime/shared/error-pres
18
18
  import { registerTaskWaitSteeringCheck } from '../../runtime/agent/orchestrator/session/task-wait-control.mjs';
19
19
  import { promptDisplayText, STEERING_SUPPRESSED_DISPLAY } from './queue-helpers.mjs';
20
20
  import { yieldToRenderer } from './render-timing.mjs';
21
+ import { archiveItemsForCompaction, compactionArchivedRows } from './compaction-view.mjs';
21
22
  import {
22
23
  createTurnStream,
23
24
  flushStreamBatch,
@@ -105,7 +106,8 @@ function beginTurn({ flags, getState, transcriptRouteMetadata }, options) {
105
106
  completionVerb,
106
107
  };
107
108
  flags.pendingTranscriptMeta = null;
108
- const { at: _userItemAt, ...routeMeta } = transcriptMeta;
109
+ // The prompt's own time and stable id stay on the prompt row.
110
+ const { at: _userItemAt, messageId: _promptMessageId, ...routeMeta } = transcriptMeta;
109
111
  return {
110
112
  index,
111
113
  startedAt,
@@ -182,6 +184,11 @@ function commitPromptRestore(flags, turn) {
182
184
 
183
185
  function steeringItemExtras(steeringMeta) {
184
186
  return {
187
+ // The steered message's stable id, so a compaction that drops it greys
188
+ // this row.
189
+ ...(typeof steeringMeta?.messageId === 'string' && steeringMeta.messageId
190
+ ? { messageId: steeringMeta.messageId }
191
+ : {}),
185
192
  // Queue mode + execution provenance: a task notification is rendered as
186
193
  // a tool card, never as an injected user bubble.
187
194
  ...(steeringMeta?.mode === 'task-notification' ? { mode: 'task-notification' } : {}),
@@ -261,10 +268,10 @@ function publishContextPressure({ syncContextStats, getState, set }, info) {
261
268
  }
262
269
 
263
270
  // Compaction itself remains owned by the pre-provider-send pass. This event
264
- // trims the visible transcript to the current turn and refreshes the gauge
265
- // from the already-mutated transcript before another render can show stale
266
- // pressure.
267
- function applyCompactEvent(ctx, event) {
271
+ // archives the visible rows before the current turn (they stay in view above
272
+ // the compaction divider) and refreshes the gauge from the already-mutated
273
+ // transcript before another render can show stale pressure.
274
+ export function applyCompactEvent(ctx, event) {
268
275
  const { turn, stream, cards, getState, set, replaceItems, pushItem, nextId, syncContextStats, routeState } = ctx;
269
276
  flushStreamBatch(stream);
270
277
  // Non-tool transcript item — same block-boundary rule as the steered user
@@ -272,12 +279,31 @@ function applyCompactEvent(ctx, event) {
272
279
  cards.aggregates.clearAggregateContinuation();
273
280
  const compactStatus = String(event?.status || '').toLowerCase();
274
281
  const compactChanged = !['failed', 'skipped', 'no_change'].includes(compactStatus);
282
+ const doneItem = {
283
+ kind: 'statusdone',
284
+ id: nextId(),
285
+ label: compactEventLabel(event),
286
+ detail: compactEventDetail(event),
287
+ };
275
288
  if (compactChanged) {
276
- set({ items: replaceItems(getState().items.slice(turn.currentItemsStart), { preserveStreamingTail: true }) });
277
- turn.currentItemsStart = 0;
289
+ // The current turn starts at its submitted row (spill paging may have
290
+ // shifted the index recorded at turn start).
291
+ const current = getState().items;
292
+ const submitted = new Set(turn.submittedIds.filter((id) => id != null));
293
+ const submittedIndex = submitted.size ? current.findIndex((item) => submitted.has(item?.id)) : -1;
294
+ const boundary = submittedIndex >= 0 ? submittedIndex : turn.currentItemsStart;
295
+ const { items, dividerIndex } = archiveItemsForCompaction(current, doneItem, boundary, {
296
+ archived: compactionArchivedRows(event),
297
+ // Only explicit identities name what left the current turn; a bare
298
+ // count says nothing about it.
299
+ archiveTail: Boolean(event?.droppedIdentities && typeof event.droppedIdentities === 'object'),
300
+ });
301
+ set({ items: replaceItems(items, { preserveStreamingTail: true, preserveSpill: true }) });
302
+ turn.currentItemsStart = dividerIndex + 1;
278
303
  turn.transcriptCompacted = true;
304
+ } else {
305
+ pushItem(doneItem);
279
306
  }
280
- pushItem({ kind: 'statusdone', id: nextId(), label: compactEventLabel(event), detail: compactEventDetail(event) });
281
307
  syncContextStats({ allowEstimated: true, invalidateExact: compactChanged });
282
308
  // syncContextStats only STAGES its patch; publication is the caller's, and
283
309
  // without this set the post-compact gauge reached React only if some later
@@ -359,7 +385,7 @@ function streamHandlers(ctx) {
359
385
  appendTextDelta(stream, textChunk);
360
386
  },
361
387
  onTextReset: (reset = {}) => (isCurrentTurn() ? resetStreamedText(stream, reset) : false),
362
- onAssistantText: (text) => {
388
+ onAssistantText: (text, detail) => {
363
389
  const full = String(text ?? '');
364
390
  if (!full.trim() || !isCurrentTurn()) return;
365
391
  // The streaming path owns this segment when it already produced text.
@@ -367,7 +393,7 @@ function streamHandlers(ctx) {
367
393
  // there across tool calls.
368
394
  if (stream.currentAssistantText.trim()) return;
369
395
  ctx.markPromptCommitted();
370
- appendAssistantText(stream, full);
396
+ appendAssistantText(stream, full, { committed: detail?.committed === true });
371
397
  },
372
398
  onReasoningDelta: (chunk) => {
373
399
  if (isCurrentTurn()) appendReasoningDelta(stream, String(chunk ?? ''));
@@ -420,9 +446,12 @@ export function failTurn(ctx, error) {
420
446
  }
421
447
 
422
448
  export function turnDoneItem({ turn, stream, cards, getState, nextId }) {
449
+ // The outer prompt id is the turn's change-record key (runtime.ask `id`).
450
+ const checkpointId = turn.submittedIds[0] == null ? '' : String(turn.submittedIds[0]).trim();
423
451
  return {
424
452
  kind: 'turndone',
425
453
  id: nextId(),
454
+ ...(checkpointId ? { checkpointId } : {}),
426
455
  elapsedMs: Date.now() - turn.startedAt,
427
456
  status: turnOutcome(turn.cancelled, turn.failed),
428
457
  // Notifications resolve this exact terminal assistant item, never a
@@ -1,17 +0,0 @@
1
- export const TOOL_DEFS = [
2
- // reply/fetch model-facing tools removed 2026-08: the output forwarder
3
- // delivers session output to the channel and the inbound bridge injects
4
- // incoming messages, so the model never needed to call them directly.
5
- // memory and recall_memory tools are now provided by memory-service.mjs via MCP
6
- // react/edit_message/download_attachment tools removed (no remaining
7
- // callers); provider editMessage/downloadAttachment/react methods stay for
8
- // internal use.
9
- // schedule_status/trigger_schedule/schedule_control tools removed (no
10
- // remaining callers). activate_channel_bridge/reload_config are NOT model-
11
- // facing tools anymore (no TOOL_DEFS entry) but the underlying
12
- // channels.execute('activate_channel_bridge'|'reload_config', ...) dispatch
13
- // stays alive in index.mjs/channel-worker.mjs because
14
- // mixdog-session-runtime.mjs calls them directly as internal Lead-only
15
- // runtime plumbing (bridge-claim on start, config hot-reload) — see
16
- // reloadChannelsSoon() and the remote-start bridge claim.
17
- ];