mixdog 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (630) hide show
  1. package/package.json +4 -3
  2. package/scripts/build-shipped-history.mjs +125 -33
  3. package/scripts/gate-local.mjs +220 -63
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +139 -32
  6. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  7. package/scripts/lib/run-node-tests.mjs +71 -34
  8. package/scripts/lib/scoped-temp.mjs +1 -0
  9. package/scripts/lib/test-failure-records.mjs +14 -1
  10. package/scripts/lib/test-failure-summary.mjs +9 -4
  11. package/scripts/lib/test-spawn-ledger.mjs +43 -3
  12. package/scripts/post-release-check.mjs +26 -16
  13. package/scripts/pptx-kit-index.mjs +5 -6
  14. package/scripts/provider-pingpong-live.mjs +1 -1
  15. package/scripts/prune-embedding-runtime.mjs +3 -1
  16. package/scripts/release-paths.mjs +7 -1
  17. package/scripts/suite-health.mjs +110 -28
  18. package/scripts/test.mjs +9 -14
  19. package/src/agents/advisor/AGENT.md +4 -4
  20. package/src/agents/advisor/agent.json +1 -1
  21. package/src/agents/explore/AGENT.md +22 -0
  22. package/src/agents/explore/agent.json +6 -0
  23. package/src/cli.mjs +7 -0
  24. package/src/defaults/agents.json +7 -0
  25. package/src/defaults/shipped-history.json +38 -2
  26. package/src/defaults/skills/browser-use/SKILL.md +4 -1
  27. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  28. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  29. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  30. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  31. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  32. package/src/defaults/skills/computer-use/SKILL.md +12 -2
  33. package/src/defaults/skills/setup/SKILL.md +2 -2
  34. package/src/defaults/skills/setup/references/actions.md +28 -9
  35. package/src/defaults/skills/setup/references/surfaces.md +5 -2
  36. package/src/defaults/skills/setup-guide/SKILL.md +11 -3
  37. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  38. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  39. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  40. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  41. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  42. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  43. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  44. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  45. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  46. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  47. package/src/defaults/skills/visualize/SKILL.md +6 -2
  48. package/src/lib/instruction-text.cjs +36 -0
  49. package/src/lib/rules-builder.cjs +40 -50
  50. package/src/orchestration/balanced.md +23 -0
  51. package/src/orchestration/focused.md +22 -0
  52. package/src/orchestration/none.md +5 -0
  53. package/src/orchestration/swarm.md +24 -0
  54. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  55. package/src/rules/agent-mode/MIXY.md +2 -2
  56. package/src/rules/lead/LEAD.md +3 -3
  57. package/src/rules/shared/20-research.md +3 -6
  58. package/src/rules/shared/40-editing.md +1 -0
  59. package/src/rules/shared/60-verification.md +10 -9
  60. package/src/rules/shared/70-delivery.md +4 -3
  61. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  62. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  63. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
  64. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
  65. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
  66. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  67. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  69. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  70. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  71. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
  72. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
  73. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  74. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
  75. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
  76. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
  77. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
  78. package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
  79. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  81. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
  82. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  84. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
  85. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
  86. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
  87. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
  89. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  90. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  91. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  92. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  95. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  96. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  97. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  98. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  99. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  100. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  102. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
  103. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  104. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  105. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  106. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  107. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  109. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  110. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  111. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  112. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
  113. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
  116. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  118. package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
  119. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  120. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  121. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  122. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
  123. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  124. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
  125. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  126. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  127. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  128. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  129. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  130. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  131. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  132. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  133. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  134. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  135. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  136. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  137. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  138. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  139. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  140. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
  141. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  142. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  143. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
  145. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  146. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
  147. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
  148. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  149. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  150. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  151. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  152. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  153. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  154. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
  155. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  156. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  157. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  158. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  159. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  160. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  161. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
  162. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
  163. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
  164. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  165. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
  166. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  167. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
  169. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  170. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  172. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
  174. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  175. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  176. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  177. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  178. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  179. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  180. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  181. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  182. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
  183. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
  184. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  185. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  186. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  187. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  188. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
  189. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  190. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  191. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  192. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  193. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  194. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  195. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  196. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  197. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  198. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  199. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  200. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  201. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  202. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  203. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  204. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
  205. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
  206. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
  207. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
  208. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  210. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
  211. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  212. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
  213. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  214. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  215. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  216. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
  217. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  218. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  219. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  220. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  221. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  222. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
  223. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  224. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  225. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  226. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
  227. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  228. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
  229. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  230. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  231. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  232. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  233. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  234. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  235. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  236. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  237. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
  238. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  239. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
  240. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  241. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  242. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  243. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  244. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  245. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  246. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  247. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  248. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  249. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  250. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  251. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  252. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  253. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  254. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
  255. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
  256. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  257. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  258. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  259. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  260. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  261. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  262. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
  263. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  264. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  265. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  266. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  267. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  269. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  270. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  271. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  272. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  273. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  274. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  275. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
  276. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  277. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  278. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  279. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
  280. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
  281. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  282. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
  283. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  284. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  285. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  286. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  287. package/src/runtime/attachments/store.d.mts +1 -0
  288. package/src/runtime/attachments/store.mjs +2 -2
  289. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  290. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  291. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  292. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  293. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  294. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  295. package/src/runtime/channels/lib/whisper-port.mjs +19 -10
  296. package/src/runtime/channels/lib/whisper-server.mjs +22 -13
  297. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  298. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  299. package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
  300. package/src/runtime/connectors/gmail-app-password.mjs +4 -4
  301. package/src/runtime/connectors/google-mcp.mjs +1 -1
  302. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  303. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  304. package/src/runtime/explore/explorer.mjs +88 -0
  305. package/src/runtime/explore/tool-defs.mjs +35 -0
  306. package/src/runtime/explore/tool.mjs +123 -0
  307. package/src/runtime/local-provider/hardware.mjs +1 -1
  308. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  309. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  310. package/src/runtime/media/media-usage.mjs +1 -1
  311. package/src/runtime/media/store.mjs +1 -1
  312. package/src/runtime/memory/index.mjs +15 -1
  313. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  314. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  315. package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
  316. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  317. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  318. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  319. package/src/runtime/memory/lib/memory.mjs +17 -0
  320. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  321. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  322. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  323. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  324. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  325. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  326. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  327. package/src/runtime/office/capabilities.mjs +1 -1
  328. package/src/runtime/office/core/office-core.mjs +1 -1
  329. package/src/runtime/office/design/content-model.mjs +3 -3
  330. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  331. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  332. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  333. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  334. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  335. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  336. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  337. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  338. package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
  339. package/src/runtime/shared/agent-route-config.mjs +17 -2
  340. package/src/runtime/shared/atomic-file.d.mts +8 -0
  341. package/src/runtime/shared/atomic-file.mjs +103 -2
  342. package/src/runtime/shared/background-tasks.mjs +37 -10
  343. package/src/runtime/shared/background-wait.mjs +66 -0
  344. package/src/runtime/shared/child-guardian.mjs +17 -7
  345. package/src/runtime/shared/config.mjs +313 -16
  346. package/src/runtime/shared/connector-accounts.mjs +5 -5
  347. package/src/runtime/shared/connector-catalog.d.mts +14 -8
  348. package/src/runtime/shared/connector-catalog.mjs +70 -52
  349. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  350. package/src/runtime/shared/file-has-data.mjs +26 -2
  351. package/src/runtime/shared/file-lock.mjs +21 -18
  352. package/src/runtime/shared/git-launch.d.mts +9 -0
  353. package/src/runtime/shared/git-launch.mjs +213 -0
  354. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  355. package/src/runtime/shared/git-runner.mjs +7 -2
  356. package/src/runtime/shared/idle-gc.mjs +30 -7
  357. package/src/runtime/shared/llm/cost.mjs +6 -1
  358. package/src/runtime/shared/llm/http-agent.mjs +316 -29
  359. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  360. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  361. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  362. package/src/runtime/shared/llm/system-proxy.mjs +453 -0
  363. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  364. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  365. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  366. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  367. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  368. package/src/runtime/shared/process-runner.mjs +8 -4
  369. package/src/runtime/shared/provider-accounts.mjs +52 -2
  370. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  371. package/src/runtime/shared/routine-trigger.mjs +34 -0
  372. package/src/runtime/shared/run-child.d.mts +2 -1
  373. package/src/runtime/shared/run-child.mjs +70 -18
  374. package/src/runtime/shared/session-scratch.mjs +14 -2
  375. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  376. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  377. package/src/runtime/shared/staged-update.mjs +47 -2
  378. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  379. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  380. package/src/runtime/shared/tool-surface.mjs +110 -36
  381. package/src/runtime/shared/tool-work-units.mjs +35 -6
  382. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  383. package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
  384. package/src/runtime/shared/worker-requests.mjs +17 -3
  385. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  386. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  387. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  388. package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
  389. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  390. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  391. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  392. package/src/runtime/shared/worktrees/git.mjs +97 -7
  393. package/src/runtime/shared/worktrees/include.mjs +6 -4
  394. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  395. package/src/runtime/shared/worktrees/manager.mjs +962 -197
  396. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  397. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  398. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  399. package/src/runtime/tidy/install.mjs +95 -15
  400. package/src/runtime/tidy/languages.mjs +17 -15
  401. package/src/runtime/tidy/process.mjs +9 -5
  402. package/src/runtime/tidy/resolve.mjs +19 -16
  403. package/src/runtime/tidy/runners/biome.mjs +3 -3
  404. package/src/runtime/tidy/tool.mjs +1 -1
  405. package/src/runtime/tidy/worktree.mjs +10 -6
  406. package/src/runtime/visualize-bridge/client.mjs +4 -1
  407. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  408. package/src/runtime/web-search/index.mjs +4 -23
  409. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  410. package/src/runtime/web-search/tool-defs.mjs +17 -26
  411. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  412. package/src/session-runtime/agent-task-sessions.mjs +410 -353
  413. package/src/session-runtime/boot/apis.mjs +27 -4
  414. package/src/session-runtime/boot/begin.mjs +2 -0
  415. package/src/session-runtime/boot/config.mjs +10 -1
  416. package/src/session-runtime/boot/facade.mjs +1 -0
  417. package/src/session-runtime/boot/providers.mjs +70 -3
  418. package/src/session-runtime/boot/session.mjs +2 -0
  419. package/src/session-runtime/boot/tools.mjs +71 -25
  420. package/src/session-runtime/bot-status.mjs +103 -103
  421. package/src/session-runtime/channel-config-api.mjs +1 -0
  422. package/src/session-runtime/config-change-effects.mjs +179 -0
  423. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  424. package/src/session-runtime/config-lifecycle.mjs +160 -24
  425. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  426. package/src/session-runtime/conversation-import/discovery.mjs +245 -47
  427. package/src/session-runtime/conversation-import/service.mjs +12 -5
  428. package/src/session-runtime/goal-facade-api.mjs +49 -3
  429. package/src/session-runtime/handoff-attachments.mjs +1 -1
  430. package/src/session-runtime/held-requests.mjs +3 -1
  431. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  432. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  433. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
  434. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  435. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
  436. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  437. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  438. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  439. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  440. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  441. package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
  442. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  443. package/src/session-runtime/lifecycle-api.mjs +1 -0
  444. package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
  445. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  446. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  447. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  448. package/src/session-runtime/model-route/set-route.mjs +40 -7
  449. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  450. package/src/session-runtime/provider-auth/login.mjs +2 -2
  451. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  452. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  453. package/src/session-runtime/provider-readiness.mjs +53 -4
  454. package/src/session-runtime/resource-api.mjs +1 -1
  455. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  456. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  457. package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
  458. package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
  459. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  460. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  461. package/src/session-runtime/routine-executor.mjs +152 -0
  462. package/src/session-runtime/routine-home-turn.mjs +46 -5
  463. package/src/session-runtime/runtime-facade.mjs +5 -0
  464. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  465. package/src/session-runtime/schedule-session-run.mjs +1 -0
  466. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  467. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  468. package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
  469. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  470. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  471. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  472. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
  473. package/src/session-runtime/services/agent-tool.mjs +51 -1
  474. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  475. package/src/session-runtime/services/channel-admin.mjs +18 -0
  476. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  477. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  478. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  479. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  480. package/src/session-runtime/services/plugin-admin.mjs +14 -6
  481. package/src/session-runtime/services/provider-admin.mjs +281 -10
  482. package/src/session-runtime/services/seeds.mjs +7 -0
  483. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  484. package/src/session-runtime/session-create/materialize.mjs +4 -2
  485. package/src/session-runtime/session-create/session-options.mjs +2 -0
  486. package/src/session-runtime/session-turn-api.mjs +2 -0
  487. package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
  488. package/src/session-runtime/settings-system-api.mjs +1 -1
  489. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  490. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  491. package/src/session-runtime/setup-tool/executor.mjs +14 -3
  492. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  493. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  494. package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
  495. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  496. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  497. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  498. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  499. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  500. package/src/session-runtime/tool-surface.mjs +38 -1
  501. package/src/session-runtime/turn/agent-ops.mjs +33 -2
  502. package/src/session-runtime/turn/session-ops.mjs +2 -0
  503. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  504. package/src/session-runtime/turn/turn-run.mjs +1 -1
  505. package/src/session-runtime/webhook-session-run.mjs +2 -0
  506. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
  507. package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
  508. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  509. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  510. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  511. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  512. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  513. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  514. package/src/session-runtime/workspace/session-view.mjs +149 -0
  515. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  516. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  517. package/src/session-runtime/workspace/transitions.mjs +128 -1070
  518. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  519. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  520. package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
  521. package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
  522. package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
  523. package/src/standalone/daemon-agent-control.mjs +25 -8
  524. package/src/standalone/daemon-desktop-runtime.mjs +8 -2
  525. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  526. package/src/standalone/daemon-session-control.mjs +151 -136
  527. package/src/standalone/daemon.mjs +61 -2
  528. package/src/standalone/desktop-service-registry.mjs +9 -0
  529. package/src/standalone/local-session-runtime.mjs +21 -1
  530. package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
  531. package/src/standalone/session-client.mjs +5 -1
  532. package/src/standalone/session-frame-stream.mjs +83 -11
  533. package/src/standalone/session-protocol.mjs +15 -0
  534. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  535. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  536. package/src/standalone/session-service/agent-tree.mjs +45 -9
  537. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  538. package/src/standalone/session-service/quota-resume.mjs +9 -0
  539. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  540. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  541. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  542. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  543. package/src/standalone/session-service/session-calls.mjs +2 -1
  544. package/src/standalone/session-service/stored-reader.mjs +127 -40
  545. package/src/tui/App.jsx +162 -164
  546. package/src/tui/app/app-view/floating-panel.jsx +3 -0
  547. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  548. package/src/tui/app/clipboard.mjs +22 -11
  549. package/src/tui/app/create-app-pickers.mjs +2 -0
  550. package/src/tui/app/doctor.mjs +2 -2
  551. package/src/tui/app/panel-signature.mjs +1 -1
  552. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  553. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  554. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  555. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  556. package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
  557. package/src/tui/app/provider-setup-picker.mjs +20 -13
  558. package/src/tui/app/settings-picker.mjs +53 -8
  559. package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
  560. package/src/tui/app/slash-commands.mjs +2 -1
  561. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  562. package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
  563. package/src/tui/app/slash-dispatch.mjs +1 -1
  564. package/src/tui/app/use-btw-panel.mjs +29 -0
  565. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  566. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  567. package/src/tui/app/use-mouse-input.mjs +11 -0
  568. package/src/tui/app/use-onboarding-start.mjs +8 -3
  569. package/src/tui/app/use-panel-transition.mjs +10 -1
  570. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  571. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  572. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  573. package/src/tui/app/use-prompt-queue-history.mjs +5 -4
  574. package/src/tui/app/use-selection-focus.mjs +11 -2
  575. package/src/tui/app/use-selection-geometry.mjs +18 -9
  576. package/src/tui/app/use-selection-paint.mjs +4 -4
  577. package/src/tui/app/use-selection-stitch.mjs +3 -3
  578. package/src/tui/app/use-slash-palette.mjs +62 -0
  579. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  580. package/src/tui/app/use-transcript-activity.mjs +48 -33
  581. package/src/tui/app/use-transcript-follow.mjs +12 -4
  582. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  583. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  584. package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
  585. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  586. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  587. package/src/tui/app/use-transcript-window.mjs +21 -11
  588. package/src/tui/app/use-tui-ready.mjs +18 -0
  589. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  590. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  591. package/src/tui/components/Picker.jsx +27 -3
  592. package/src/tui/components/SignInUrl.jsx +68 -0
  593. package/src/tui/components/TextEntryPanel.jsx +76 -46
  594. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  595. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  596. package/src/tui/components/question-panel-model.mjs +4 -4
  597. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  598. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  599. package/src/tui/components/user-message-skills.mjs +1 -1
  600. package/src/tui/dist/index.mjs +2205 -1371
  601. package/src/tui/markdown/render-ansi.mjs +1 -1
  602. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  603. package/src/tui/session/agent-job-feed.mjs +2 -0
  604. package/src/tui/session/context-state.mjs +3 -0
  605. package/src/tui/session/goal-turn-state.mjs +6 -2
  606. package/src/tui/session/quota-resume.mjs +1 -1
  607. package/src/tui/session/session-api/controls.mjs +4 -0
  608. package/src/tui/session/session-api/extensions.mjs +8 -0
  609. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  610. package/src/tui/session/session-api/intake.mjs +2 -0
  611. package/src/tui/session/session-api/integrations.mjs +2 -2
  612. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  613. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  614. package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
  615. package/src/tui/session/session-api/settings.mjs +2 -2
  616. package/src/tui/session/session-api/worktree.mjs +13 -1
  617. package/src/tui/session/session-flow/drain.mjs +11 -14
  618. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  619. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  620. package/src/tui/session/transcript-spill.mjs +92 -4
  621. package/src/tui/session/transcript-store.mjs +2 -0
  622. package/src/tui/session/turn-quiet.mjs +1 -1
  623. package/src/tui/session/turn.mjs +3 -0
  624. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  625. package/src/tui/spinner-meta.mjs +3 -3
  626. package/src/tui/spinner-verbs.mjs +2 -2
  627. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  628. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
  629. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  630. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -55,14 +55,10 @@ export {
55
55
  // deployment recalibrate without a code change; values are clamped to a
56
56
  // plausible band.
57
57
  //
58
- // The Anthropic factor was 1.9 while opaque replay blobs were projected as a
59
- // fixed marker — that is, while a transcript's entire reasoning stream (15-35%
60
- // of it) was priced at zero, and the multiplier was silently covering the gap.
61
- // Now that those blobs carry their measured cost, the ratio was re-measured
62
- // against the provider's own token counter on twenty real transcripts:
63
- // 1.23-1.40, median 1.32 (previously 1.72-2.48 — a fifth of the spread, since
64
- // the multiplier no longer has to absorb a variable amount of reasoning).
65
- // 1.4 covers the measured maximum without double counting.
58
+ // Opaque replay blobs carry their measured cost, so the Anthropic ratio does
59
+ // not have to absorb a variable amount of reasoning. Measured against the
60
+ // provider's own token counter on twenty real transcripts: 1.23-1.40, median
61
+ // 1.32. 1.4 covers the measured maximum without double counting.
66
62
  //
67
63
  // Only Anthropic-style providers can be calibrated against reported usage at
68
64
  // all, because only they resend the whole transcript every turn. OpenAI/xAI
@@ -96,10 +92,10 @@ export { estimateRequestReserveTokens, estimateToolSchemaTokens, toolSchemaSigna
96
92
 
97
93
  // Opaque replay payloads (Anthropic thinking signatures, OpenAI encrypted
98
94
  // reasoning blobs, redacted data) are long base64-ish strings that ARE billed
99
- // proportionally to their serialized length — see the measurement below. They
100
- // were previously replaced with a fixed marker, which priced a provider's
101
- // entire reasoning stream at nearly zero. Project them at their measured cost
102
- // instead. Projection is KEY-SCOPED: only fields that structurally carry
95
+ // proportionally to their serialized length — see the measurement below. A
96
+ // fixed marker would price a provider's entire reasoning stream at nearly zero,
97
+ // so they are projected at their measured cost. Projection is KEY-SCOPED: only
98
+ // fields that structurally carry
103
99
  // opaque replay
104
100
  // material (signatures / encrypted / redacted / raw data blobs) are eligible,
105
101
  // so genuine long model text (e.g. Gemini thought text) keeps its real cost.
@@ -14,6 +14,7 @@ import {
14
14
  IMAGE_OMITTED_TEXT,
15
15
  IMPORT_WARNING_IMAGE_OMITTED,
16
16
  isWholeElement,
17
+ stringOrNull,
17
18
  textPart,
18
19
  titleFromText,
19
20
  toolNote,
@@ -78,7 +79,7 @@ export function unwrapClaudePastes(text) {
78
79
  return unwrapped.trim() ? unwrapped : text;
79
80
  }
80
81
 
81
- export function isClaudeEnvelopeText(text) {
82
+ function isClaudeEnvelopeText(text) {
82
83
  const trimmed = String(text || '').trim();
83
84
  if (!trimmed) return true;
84
85
  return (
@@ -92,7 +93,7 @@ export function isClaudeEnvelopeText(text) {
92
93
  const tagValue = (text, tag) => new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`).exec(text)?.[1].trim() || '';
93
94
 
94
95
  /** A slash-command envelope as Claude Code shows it (`/name args`), else null. */
95
- export function claudeCommandText(text) {
96
+ function claudeCommandText(text) {
96
97
  const trimmed = String(text || '').trim();
97
98
  if (!SLASH_COMMAND_RE.test(trimmed)) return null;
98
99
  const name = (tagValue(trimmed, 'command-name') || tagValue(trimmed, 'command-message')).replace(/^\//, '');
@@ -101,7 +102,6 @@ export function claudeCommandText(text) {
101
102
  }
102
103
 
103
104
  const isMessageEntry = (record) => record?.type === 'user' || record?.type === 'assistant';
104
- const stringOrNull = (value) => (typeof value === 'string' && value.trim() ? value.trim() : null);
105
105
  const uuidOrNull = (value) => (typeof value === 'string' ? value : null);
106
106
  const timestampOrNull = (value) => (typeof value === 'string' || typeof value === 'number' ? value : null);
107
107
  // Rough fixed cost of one retained entry object, so tiny entries still count.
@@ -193,7 +193,7 @@ function entryParts(role, content, warnings, marks) {
193
193
  * (a cleared rename) ends the name tier without falling back to the AI title.
194
194
  * Other record types, such as `task-summary` or `agent-name`, never name it.
195
195
  */
196
- export function createClaudeTitleScan() {
196
+ function createClaudeTitleScan() {
197
197
  let custom;
198
198
  let ai;
199
199
  let summary;
@@ -5,7 +5,14 @@
5
5
  * messages, Codex's own wrapper user messages, tool outputs, reasoning,
6
6
  * event_msg, token counts and turn_context.
7
7
  */
8
- import { IMAGE_OMITTED_TEXT, IMPORT_WARNING_IMAGE_OMITTED, isWholeElement, textPart, toolNote } from './turns.mjs';
8
+ import {
9
+ IMAGE_OMITTED_TEXT,
10
+ IMPORT_WARNING_IMAGE_OMITTED,
11
+ isWholeElement,
12
+ stringOrNull,
13
+ textPart,
14
+ toolNote,
15
+ } from './turns.mjs';
9
16
 
10
17
  // User-role envelopes Codex injects itself (environment, instructions, abort
11
18
  // notices, plugin hints, shell-command echoes, image wrappers).
@@ -21,7 +28,7 @@ const CODEX_ENVELOPE_TAGS = [
21
28
  ];
22
29
  const TOOL_CALL_TYPES = new Set(['function_call', 'custom_tool_call', 'local_shell_call']);
23
30
 
24
- export function isCodexEnvelopeText(text) {
31
+ function isCodexEnvelopeText(text) {
25
32
  const trimmed = String(text || '').trim();
26
33
  if (!trimmed) return true;
27
34
  if (/^# AGENTS\.md instructions\b/.test(trimmed) && trimmed.includes('<INSTRUCTIONS>')) return true;
@@ -36,7 +43,7 @@ export function isCodexEnvelopeText(text) {
36
43
  const USER_REQUEST_HEADING = '## My request for Codex:';
37
44
 
38
45
  /** A user text part as Codex displays it. */
39
- export function codexUserDisplayText(text) {
46
+ function codexUserDisplayText(text) {
40
47
  const at = text.lastIndexOf(USER_REQUEST_HEADING);
41
48
  return at < 0 ? text : text.slice(at + USER_REQUEST_HEADING.length).trim();
42
49
  }
@@ -64,8 +71,6 @@ function toolName(payload) {
64
71
  return payload.type === 'local_shell_call' ? 'local_shell' : '';
65
72
  }
66
73
 
67
- const stringOrNull = (value) => (typeof value === 'string' && value.trim() ? value.trim() : null);
68
-
69
74
  // `session_meta.thread_source` values Codex gives threads it runs for itself.
70
75
  const INTERNAL_THREAD_SOURCES = {
71
76
  subagent: 'subagent',
@@ -81,7 +86,7 @@ const INTERNAL_THREAD_SOURCES = {
81
86
  * is the approval reviewer) or `{ internal: … }`. Other sources (cli, vscode,
82
87
  * exec, mcp, custom) and features (automation, voice chat) are the user's.
83
88
  */
84
- export function codexInternalKind(payload) {
89
+ function codexInternalKind(payload) {
85
90
  const byThread = INTERNAL_THREAD_SOURCES[payload?.thread_source];
86
91
  if (byThread) return byThread;
87
92
  const source = payload?.source;
@@ -14,7 +14,7 @@ import {
14
14
  normalizeTurns,
15
15
  } from './turns.mjs';
16
16
 
17
- export const IMPORT_SOURCES = Object.freeze(['codex', 'claude']);
17
+ const IMPORT_SOURCES = Object.freeze(['codex', 'claude', 'cowork']);
18
18
  /** A line or converted transcript beyond the import limits fails the file. */
19
19
  export const IMPORT_ERROR_TOO_LARGE = 'tooLarge';
20
20
  export const IMPORT_MAX_LINE_BYTES = 32 * 1024 * 1024;
@@ -58,7 +58,7 @@ export function createConversationConverter(
58
58
  let records = 0;
59
59
  let malformed = 0;
60
60
  let tooLarge = false;
61
- let historyPartial = false;
61
+ let historyPartial = null;
62
62
  return {
63
63
  /** True while every message seen so far is a Claude sidechain message. */
64
64
  get sidechainOnly() {
@@ -67,9 +67,9 @@ export function createConversationConverter(
67
67
  markTooLarge() {
68
68
  tooLarge = true;
69
69
  },
70
- /** A history base could not be followed in full. */
71
- markHistoryPartial() {
72
- historyPartial = true;
70
+ /** A history base could not be followed in full; `warning` names why. */
71
+ markHistoryPartial(warning = IMPORT_WARNING_HISTORY_PARTIAL) {
72
+ historyPartial = warning;
73
73
  },
74
74
  /** Feed a line for the stored title only (Claude Code's tail window); other sources ignore it. */
75
75
  pushTitleLine(raw) {
@@ -117,7 +117,7 @@ export function createConversationConverter(
117
117
  if (transcriptChars(turns) > maxTranscriptChars) tooLarge = true;
118
118
  const warnings = new Set(parsed.warnings);
119
119
  if (malformed) warnings.add(IMPORT_WARNING_MALFORMED);
120
- if (historyPartial) warnings.add(IMPORT_WARNING_HISTORY_PARTIAL);
120
+ if (historyPartial) warnings.add(historyPartial);
121
121
  let errorCode = null;
122
122
  if (tooLarge) errorCode = IMPORT_ERROR_TOO_LARGE;
123
123
  else if (parsed.internalKind) errorCode = IMPORT_ERROR_INTERNAL;
@@ -12,11 +12,15 @@ import { writeStderrBestEffort } from '../../../../shared/best-effort-stderr.mjs
12
12
  import { IMPORTED_MESSAGE_SOURCE } from '../imported-message.mjs';
13
13
  import { ingestSessionTurn } from '../../../../session-search/session-search-ingest.mjs';
14
14
 
15
- export const IMPORT_ORIGIN_VERSION = 1;
15
+ const IMPORT_ORIGIN_VERSION = 1;
16
16
 
17
- /** Dedupe identity: the foreign session id, else the canonical source path. */
17
+ /**
18
+ * Dedupe identity: the foreign session id, else the canonical source path.
19
+ * Cowork transcripts are Claude Code transcripts, so both share the `claude` namespace.
20
+ */
18
21
  export function importOriginKey(source, foreignSessionId, canonicalPath) {
19
- return foreignSessionId ? `${source}:${foreignSessionId}` : `${source}:path:${canonicalPath}`;
22
+ const namespace = source === 'cowork' ? 'claude' : source;
23
+ return foreignSessionId ? `${namespace}:${foreignSessionId}` : `${namespace}:path:${canonicalPath}`;
20
24
  }
21
25
 
22
26
  export function buildImportOrigin({ source, sourcePath, foreignSessionId = null, sourceCwd = null, importedAt }) {
@@ -11,6 +11,13 @@ export const IMPORT_WARNING_MALFORMED = 'malformed';
11
11
  export const IMPORT_WARNING_CWD_MISSING = 'cwdMissing';
12
12
  /** The conversation continues a history stored in another file that was not followed. */
13
13
  export const IMPORT_WARNING_HISTORY_PARTIAL = 'historyPartial';
14
+ /** Earlier history was left out because following it would pass the import size limit. */
15
+ export const IMPORT_WARNING_HISTORY_SIZE_LIMIT = 'historySizeLimit';
16
+ /** Earlier history was left out because its file is missing or could not be read. */
17
+ export const IMPORT_WARNING_HISTORY_UNAVAILABLE = 'historyUnavailable';
18
+
19
+ /** A compressed rollout needs a Node.js runtime with zstd; used as the failure code and as the warning of an unreadable base. */
20
+ export const IMPORT_ERROR_NEEDS_NEWER_NODE = 'needsNewerNode';
14
21
 
15
22
  /** Failure code of a record the source app writes for its own use (not a conversation). */
16
23
  export const IMPORT_ERROR_INTERNAL = 'internalRecord';
@@ -33,7 +40,7 @@ export function toolNote(name) {
33
40
  }
34
41
 
35
42
  /** Longest model-facing run line, and the longest tool name shown in it. */
36
- export const TOOL_RUN_LINE_MAX_CHARS = 400;
43
+ const TOOL_RUN_LINE_MAX_CHARS = 400;
37
44
  const TOOL_RUN_NAME_MAX_CHARS = 40;
38
45
 
39
46
  /**
@@ -67,6 +74,9 @@ function toolRunCounts(notes) {
67
74
  return [...counts].map(([name, count]) => ({ name, count }));
68
75
  }
69
76
 
77
+ /** A trimmed non-blank string, else null. */
78
+ export const stringOrNull = (value) => (typeof value === 'string' && value.trim() ? value.trim() : null);
79
+
70
80
  export function textPart(text) {
71
81
  return { text: String(text), note: false };
72
82
  }
@@ -39,9 +39,10 @@ export function createEagerDispatcher({
39
39
  repeatFailLimit,
40
40
  });
41
41
  const barriers = createEagerBarriers({ cwd });
42
- // A capped turn runs its calls in order, so none past its cap starts early
43
- // (loop/turn-limits.mjs).
44
- const capped = turnLimitsOf(opts) !== null;
42
+ // A turn capped by calls or time runs its calls in order, so none past its
43
+ // cap starts early (loop/turn-limits.mjs).
44
+ const limits = turnLimitsOf(opts);
45
+ const capped = limits !== null && (limits.maxToolCalls !== Infinity || limits.wrapUpAt !== Infinity);
45
46
  const execute = (call, entry) =>
46
47
  executeToolFn(call.name, call.arguments, cwd, sessionId, sessionRef, {
47
48
  toolCallId: call.id,
@@ -7,7 +7,7 @@
7
7
  // user's words; the structured `heldRequest` payload is for the UI only.
8
8
  import { escapeHarnessTags } from '../../../../shared/shell-output-summary.mjs';
9
9
 
10
- export const HELD_REQUEST_SOURCE = 'held-request';
10
+ const HELD_REQUEST_SOURCE = 'held-request';
11
11
  const STATUSES = new Set(['pending', 'approved', 'denied', 'expired']);
12
12
 
13
13
  const clean = (value, limit = 200) =>
@@ -7,13 +7,19 @@
7
7
  // secret — the user types a value into a target field; the request names
8
8
  // the target and the field label, never a value;
9
9
  // takeover — the user does a step themselves and says "done";
10
- // permission — the user picks one of the offered scopes.
11
- // A response is one of HUMAN_RESPONSES plus a `remember` scope; a policy lists
10
+ // permission — the user picks one of the offered scopes;
11
+ // connector — a bot asks for more authority on one connector tool of its
12
+ // own: the card names the tool, its current level and the one
13
+ // asked for, and the person picks the level (`scope`: one of
14
+ // `choices`) or denies. Answered once, never remembered.
15
+ // A response is one of RESPONSES_BY_KIND for its kind plus a `remember` scope; a policy lists
12
16
  // the scopes it allows and can leave out `always`. Nothing here ever carries a
13
17
  // secret value: a decision that names one is stripped to its verdict.
14
18
 
15
- const HUMAN_REQUEST_KINDS = Object.freeze(['approval', 'outbound', 'secret', 'takeover', 'permission']);
16
- const HUMAN_RESPONSES = Object.freeze(['approve', 'deny', 'edit-and-approve', 'provide-secret', 'skip', 'done']);
19
+ const HUMAN_REQUEST_KINDS = Object.freeze(['approval', 'outbound', 'secret', 'takeover', 'permission', 'connector']);
20
+ /** The levels a connector card may raise a tool to. */
21
+ export const CONNECTOR_WIDEN_LEVELS = Object.freeze(['needs_approval', 'auto']);
22
+ const CONNECTOR_LEVELS = ['disabled', ...CONNECTOR_WIDEN_LEVELS];
17
23
  const REMEMBER_SCOPES = Object.freeze(['once', 'agent', 'always']);
18
24
  export const SECRET_REQUEST_TIMEOUT_MS = 120_000;
19
25
  /** What a secret's bound field is: a sign-in form (아이디 + 비밀번호), a lone
@@ -36,6 +42,7 @@ const RESPONSES_BY_KIND = Object.freeze({
36
42
  secret: ['provide-secret', 'skip'],
37
43
  takeover: ['done', 'deny'],
38
44
  permission: ['approve', 'deny'],
45
+ connector: ['approve', 'deny'],
39
46
  });
40
47
  const GRANTING_RESPONSES = new Set(['approve', 'edit-and-approve', 'provide-secret', 'done']);
41
48
  const TEXT_LIMIT = 200;
@@ -89,12 +96,15 @@ function rememberScopes(value) {
89
96
  return ['once', ...new Set(listed.filter((scope) => scope !== 'once'))];
90
97
  }
91
98
 
92
- /** The kind-specific fields of a request, whitelisted. Spread onto the
93
- * presented request; `args` is replaced for a secret so no value rides it. */
99
+ /** The kind-specific fields of a request, whitelisted, plus the connector
100
+ * `account` a tool call is bound to (any kind; the card names it). Spread
101
+ * onto the presented request; `args` is replaced for a secret so no value
102
+ * rides it. */
94
103
  export function humanRequestFields(input = {}) {
104
+ const bound = text(input?.account) ? { account: text(input.account) } : {};
95
105
  const kind = input?.kind;
96
- if (!HUMAN_REQUEST_KINDS.includes(kind)) return {};
97
- const fields = { remember: rememberScopes(input.remember) };
106
+ if (!HUMAN_REQUEST_KINDS.includes(kind)) return bound;
107
+ const fields = { ...bound, remember: rememberScopes(input.remember) };
98
108
  // The agent the request acts for (its name on the card and the remembered grant).
99
109
  if (text(input.agentId)) fields.agentId = text(input.agentId);
100
110
  if (kind === 'outbound' && isRecord(input.outbound)) {
@@ -187,6 +197,20 @@ export function humanRequestFields(input = {}) {
187
197
  })),
188
198
  };
189
199
  }
200
+ if (kind === 'connector') {
201
+ const connector = isRecord(input.connector) ? input.connector : {};
202
+ const level = (value) => (CONNECTOR_LEVELS.includes(value) ? value : '');
203
+ fields.connector = {
204
+ server: text(connector.server),
205
+ tool: text(connector.tool),
206
+ from: level(connector.from),
207
+ requested: level(connector.requested),
208
+ choices: (Array.isArray(connector.choices) ? connector.choices : []).filter((choice) =>
209
+ CONNECTOR_WIDEN_LEVELS.includes(choice)
210
+ ),
211
+ };
212
+ fields.remember = ['once'];
213
+ }
190
214
  return fields;
191
215
  }
192
216
 
@@ -226,6 +250,11 @@ export function normalizeHumanResponse(request, approved, extra = {}) {
226
250
  const ids = (request?.permission?.scopes || []).map((scope) => scope.id);
227
251
  if (ids.includes(extra?.scope)) result.scope = extra.scope;
228
252
  }
253
+ // The level the person picked; none of the offered ones picks nothing.
254
+ if (kind === 'connector' && polarity) {
255
+ const choices = Array.isArray(request?.connector?.choices) ? request.connector.choices : [];
256
+ if (choices.includes(extra?.scope)) result.scope = extra.scope;
257
+ }
229
258
  return result;
230
259
  }
231
260
 
@@ -20,7 +20,7 @@ export const AUTOMATION_GRANT_REASON =
20
20
  export const isGrantedRun = (run) => Boolean(run) && run.kind !== 'room';
21
21
 
22
22
  /** Whether an outbound request is a payment or permanent delete. */
23
- export function isForbiddenInRun(request) {
23
+ function isForbiddenInRun(request) {
24
24
  const category = request?.kind === 'outbound' ? request.outbound?.category : '';
25
25
  return ACTION_KINDS.includes(category) && !isRememberableAction(category);
26
26
  }
@@ -151,7 +151,7 @@ export function persistsConfirmedImageRejection(err, strip) {
151
151
  return strip.uniqueImages === 1;
152
152
  }
153
153
 
154
- export const PREPARATION_FAILED_CODE = 'anthropic_image_preparation_failed';
154
+ const PREPARATION_FAILED_CODE = 'anthropic_image_preparation_failed';
155
155
 
156
156
  /** True for prepareAnthropicImages' local "this image is invalid" rejection. */
157
157
  export function isImagePreparationFailed(err) {
@@ -37,7 +37,17 @@ export function crossTurnSignature(name, args) {
37
37
  // they must not reset the escalation ladder's "zero edit" condition. Skill /
38
38
  // recall / agent / task / cwd / load_tool are exploration/meta plumbing.
39
39
  // (tool_search kept as legacy alias for old transcripts.)
40
- const NON_PROGRESS_TOOLS = new Set(['Skill', 'recall', 'agent', 'task', 'cwd', 'session', 'load_tool', 'tool_search']);
40
+ const NON_PROGRESS_TOOLS = new Set([
41
+ 'Skill',
42
+ 'recall',
43
+ 'agent',
44
+ 'task',
45
+ 'cwd',
46
+ 'session',
47
+ 'load_tool',
48
+ 'tool_search',
49
+ 'todo',
50
+ ]);
41
51
 
42
52
  // True when a successfully-executed tool represents real edit/progress. A tool
43
53
  // counts as progress only if its def lacks readOnlyHint (not eager) AND it is
@@ -55,7 +55,7 @@ const tokens = (value) => `${Number(value || 0).toLocaleString('en-US')} tokens`
55
55
  // for any history, so compacting the history cannot help and is not tried.
56
56
  // The wording avoids provider context-overflow phrasing on purpose: this is
57
57
  // not a "conversation too long" refusal and must not be routed as one.
58
- export class ToolSurfaceExceedsContextError extends Error {
58
+ class ToolSurfaceExceedsContextError extends Error {
59
59
  constructor({ sessionId, provider, model, overhead }) {
60
60
  const target = [provider, model].filter(Boolean).join('/') || 'this model';
61
61
  const reserve = overhead.kind === 'configured_reserve';
@@ -281,9 +281,11 @@ function currentSkillResolver(sessionRef, { preview = false } = {}) {
281
281
  const { resource } = delivery;
282
282
  // The tools whose use counts as use of the skill: its tool dependencies,
283
283
  // an MCP server as `mcp:<server>`.
284
- const tools = (resource.toolDependencies || []).flatMap(({ type, value }) =>
285
- type === 'tool' ? [value] : type === 'mcp' ? [`mcp:${value}`] : []
286
- );
284
+ const tools = (resource.toolDependencies || []).flatMap(({ type, value }) => {
285
+ if (type === 'tool') return [value];
286
+ if (type === 'mcp') return [`mcp:${value}`];
287
+ return [];
288
+ });
287
289
  if (preview) return { body: delivery.body, native: undefined, tools };
288
290
  const envelope = loadSkillToolDependencies(
289
291
  buildSkillToolEnvelope(name, resource.content, resource.dir, resource),
@@ -129,6 +129,8 @@ export function createLoopState({ provider, messages, model, tools, cwd, sendOpt
129
129
  opts,
130
130
  sessionId,
131
131
  onSkillPrompt: (content, message) => state.pendingSkillPrompts.push({ content, message }),
132
+ // Input taken into the turn at any boundary is new work to answer.
133
+ onInjected: () => state.noToolTurn.noteNewInput(),
132
134
  });
133
135
  // Bounded recovery for provider turns that returned no client tool calls
134
136
  // (max-output ladder, refusal retry, provider continuation, empty-turn
@@ -143,6 +145,8 @@ export function createLoopState({ provider, messages, model, tools, cwd, sendOpt
143
145
  escalateMaxTokens: () => state.provider?.escalatedMaxTokens?.(state.model, state.opts, state.lastSendTools) ?? null,
144
146
  // Characters the latest send put on screen through the live text stream.
145
147
  streamedChars: () => state.lastStreamedChars,
148
+ // A capped turn was told to reply; it may end without the todo check.
149
+ turnLimited: () => state.turnLimitNoticed === true,
146
150
  });
147
151
  return state;
148
152
  }
@@ -155,6 +159,9 @@ export function finishLoop(state) {
155
159
  // A reaction-only turn is a successful completion, never an empty finish.
156
160
  const terminationReason = classifyTerminationReason(response, { sessionAgent: state.sessionAgent });
157
161
  const reactionCompleted = terminationReason === 'empty' && state.noToolTurn.reactionCompleted;
162
+ // So is an empty end after a kept answer only todo bookkeeping followed:
163
+ // that answer is the turn's report (no-tool-turn.mjs).
164
+ const reportCompleted = terminationReason === 'empty' && state.noToolTurn.reportStands;
158
165
  return {
159
166
  ...response,
160
167
  usage: state.lastUsage || response.usage,
@@ -165,7 +172,7 @@ export function finishLoop(state) {
165
172
  toolCallsTotal: state.toolCallsTotal,
166
173
  providerState: state.providerState,
167
174
  providerStateUpdated: state.providerStateUpdated,
168
- terminationReason: reactionCompleted ? undefined : terminationReason,
175
+ terminationReason: reactionCompleted || reportCompleted ? undefined : terminationReason,
169
176
  ...(reactionCompleted ? { reactionCompleted: true } : {}),
170
177
  providerContinuations: state.noToolTurn.providerContinuations,
171
178
  ...(state.routeUsageHops?.length
@@ -0,0 +1,196 @@
1
+ // End-of-turn completion check for the session's todo list.
2
+ //
3
+ // A turn that ends without a tool call while pending/in-progress items remain
4
+ // gets one hidden reminder naming them, and the loop sends again. Bounded:
5
+ // at most MAX_TODO_REMINDERS per user cycle (reset only by a genuine user
6
+ // prompt, never by an automatic continuation), and silent after a reminder
7
+ // that produced no progress (no tool batch since). Skipped while the turn is
8
+ // genuinely waiting: on the user (an approval denied or a question left
9
+ // unanswered this turn), on an agent, or on a background shell started this
10
+ // user cycle (background-wait.mjs).
11
+ // Cancelled, failed and usage-limited turns never reach this point.
12
+ //
13
+ // With an active Goal whose items are all closed, the same check asks once
14
+ // per cycle for the completion audit: complete the Goal or append the rest.
15
+ import { resolvePluginData } from '../../../../../shared/plugin-paths.mjs';
16
+ import { awaitingBackgroundWork, beginUserCycle } from '../../../../../shared/background-wait.mjs';
17
+ import { readStoredGoalSnapshot } from '../../../runtime-core/goal-storage.mjs';
18
+ import {
19
+ clearTodo,
20
+ openTodoItems,
21
+ todoAllClosed,
22
+ todoPhases,
23
+ unfinishedTodoItems,
24
+ } from '../../../runtime-core/todo-list.mjs';
25
+ import { TODO_TOOL } from '../../../runtime-core/todo-tool-defs.mjs';
26
+ import { HIDDEN_AGENT_NAMES } from '../hidden-agents.mjs';
27
+ import { _isMutationTool, _isShellTool } from '../tool-classify.mjs';
28
+
29
+ const MAX_TODO_REMINDERS = 3;
30
+
31
+ // Sessions whose current turn waits on the user's decision (in memory: the
32
+ // turn itself is in memory, and a new turn clears it).
33
+ const userWaits = new Set();
34
+
35
+ /** The current turn now waits on the user (approval denied, question dismissed). */
36
+ export function noteTodoUserWait(sessionId) {
37
+ if (sessionId) userWaits.add(String(sessionId));
38
+ }
39
+
40
+ function checkState(session) {
41
+ const current = session.todoCheck;
42
+ if (current && typeof current === 'object') return current;
43
+ session.todoCheck = { reminders: 0, awaitingProgress: false, auditAsked: false };
44
+ return session.todoCheck;
45
+ }
46
+
47
+ /** A turn starts: `genuine` (a real user prompt) opens a new reminder cycle. */
48
+ export function beginTodoTurn(session, { genuine = false } = {}) {
49
+ if (!session || typeof session !== 'object') return;
50
+ if (session.id) userWaits.delete(String(session.id));
51
+ if (genuine) {
52
+ session.todoCheck = { reminders: 0, awaitingProgress: false, auditAsked: false };
53
+ beginUserCycle(session.id);
54
+ // A finished list stays on screen until the user moves on, then goes the
55
+ // way a finished Goal does. An active Goal keeps it for its audit.
56
+ if (todoAllClosed(session) && !activeGoal(session.id)) clearTodo(session);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * A delegated agent received a new brief or follow-up (a genuine prompt) with
62
+ * no open list: the hidden reminder trailing that prompt, once per prompt, or
63
+ * null. The tool description alone was read past on short multi-ask briefs.
64
+ */
65
+ export function todoStartReminder(session) {
66
+ if (!session || typeof session !== 'object' || session.owner !== 'agent') return null;
67
+ if (HIDDEN_AGENT_NAMES.has(session.agent)) return null;
68
+ if (!session.tools?.some((tool) => tool?.name === TODO_TOOL.name)) return null;
69
+ if (openTodoItems(session).length) return null;
70
+ // `init` refuses while any item is unfinished (blocked included), so such a
71
+ // list is reconciled or appended to, never re-initialized.
72
+ if (unfinishedTodoItems(session).length) {
73
+ return [
74
+ '<system-reminder>',
75
+ 'The todo list still has blocked items. If this brief adds asks, append them; first done, drop or unblock each blocked item that this brief settles. Do not init over them. Do not mention this reminder.',
76
+ '</system-reminder>',
77
+ ].join('\n');
78
+ }
79
+ return [
80
+ '<system-reminder>',
81
+ 'If this brief has three or more steps or several asks, init the todo list with every ask as its own item in the same response as your first tool call; each item the brief lists is its own todo item, never folded into one. A single step or a plain answer needs none. Do not mention this reminder.',
82
+ '</system-reminder>',
83
+ ].join('\n');
84
+ }
85
+
86
+ /** A tool batch ran: the last reminder produced progress. */
87
+ export function noteTodoProgress(session) {
88
+ if (session?.todoCheck?.awaitingProgress) session.todoCheck.awaitingProgress = false;
89
+ }
90
+
91
+ // Mid-turn nudge: a long turn can finish items without ever touching the list,
92
+ // leaving the progress shown to the user stale. After this many successful
93
+ // mutating tool calls with no todo call (and no earlier nudge), one hidden
94
+ // reminder is appended. Counted per call, not per batch, so a turn of parallel
95
+ // edits ages the list faster than a turn of reads; a batch of three edits is
96
+ // three. What mutates is the work the list tracks: file edits, command
97
+ // execution (shell, as a bash tool is) and mutating git/github requests.
98
+ const STALE_TODO_MUTATIONS = 10;
99
+
100
+ function mutatingCall(call, results) {
101
+ const name = call?.name ?? call?.function?.name;
102
+ const args = call?.arguments ?? call?.function?.arguments;
103
+ if (!_isMutationTool(name, args) && !_isShellTool(name)) return false;
104
+ const result = results.find((message) => message?.toolCallId === call.id);
105
+ // A call that failed or was skipped (a dependency guard after a failed edit) changed nothing.
106
+ return result?.toolKind !== 'error' && result?.toolKind !== 'skipped';
107
+ }
108
+
109
+ /**
110
+ * A tool batch ran with `calls` (and their result messages): the hidden
111
+ * stale-list reminder to append to the transcript, or null. Calls are read in
112
+ * order: a todo call restarts the count, a successful mutating call adds one.
113
+ * Outside the end-of-turn budget (`todoCheck.reminders`) and its progress gate.
114
+ */
115
+ export function staleTodoReminder(session, calls = [], results = [], { sessionAgent = null } = {}) {
116
+ if (!session || typeof session !== 'object' || HIDDEN_AGENT_NAMES.has(sessionAgent)) return null;
117
+ const check = checkState(session);
118
+ for (const call of calls) {
119
+ if ((call?.name ?? call?.function?.name) === TODO_TOOL.name) check.staleMutations = 0;
120
+ else if (mutatingCall(call, results)) check.staleMutations = (check.staleMutations || 0) + 1;
121
+ }
122
+ const phases = todoPhases(session);
123
+ // A finished list needs nothing more; no list at all is nudged once per
124
+ // user cycle (long runs that never made one), an open list repeatedly.
125
+ if (phases.length && !openTodoItems(session).length) {
126
+ check.staleMutations = 0;
127
+ return null;
128
+ }
129
+ if (!phases.length && check.createNudged) return null;
130
+ if ((check.staleMutations || 0) < STALE_TODO_MUTATIONS) return null;
131
+ check.staleMutations = 0;
132
+ if (!phases.length) {
133
+ check.createNudged = true;
134
+ return [
135
+ '<system-reminder>',
136
+ 'No todo list exists for this work yet. If it has three or more steps, init one now with the steps left and keep it current; if it is a single step, ignore this. Keep working; do not mention this reminder.',
137
+ '</system-reminder>',
138
+ ].join('\n');
139
+ }
140
+ return [
141
+ '<system-reminder>',
142
+ 'The todo tool has not been used for a while. Mark finished items done now (one call each, never batched at the end) so the in-progress pointer is on what you are doing. Keep working; do not mention this reminder.',
143
+ ...phases.flatMap((phase) => phase.tasks.map((task) => `- [${task.status}] ${task.content}`)),
144
+ '</system-reminder>',
145
+ ].join('\n');
146
+ }
147
+
148
+ function activeGoal(sessionId) {
149
+ try {
150
+ const goal = readStoredGoalSnapshot({ dataDir: resolvePluginData(), sessionId });
151
+ return goal?.status === 'active' ? goal : null;
152
+ } catch {
153
+ return null;
154
+ }
155
+ }
156
+
157
+ function openItemsReminder(open, count) {
158
+ return [
159
+ '<system-reminder>',
160
+ `You ended the turn with ${open.length} open todo item(s):`,
161
+ ...open.map((task) => `- ${task.content}`),
162
+ 'Continue them, or close each with the todo tool (done, drop, or block with its reason).',
163
+ `(Reminder ${count}/${MAX_TODO_REMINDERS})`,
164
+ '</system-reminder>',
165
+ ].join('\n');
166
+ }
167
+
168
+ const GOAL_AUDIT_REMINDER = [
169
+ '<system-reminder>',
170
+ 'Every todo item is closed but the Goal is still active. Audit each user condition of the Goal objective against current evidence: when all are proven met, call goal with action complete; otherwise append the remaining work to todo and continue.',
171
+ '</system-reminder>',
172
+ ].join('\n');
173
+
174
+ /** The reminder to send before the turn may end, or null to let it end. */
175
+ export function todoCompletionReminder(session, { sessionId = null, sessionAgent = null, turnLimited = false } = {}) {
176
+ if (!session || typeof session !== 'object' || turnLimited) return null;
177
+ if (HIDDEN_AGENT_NAMES.has(sessionAgent)) return null;
178
+ const id = String(sessionId || session.id || '');
179
+ const phases = todoPhases(session);
180
+ if (!phases.length) return null;
181
+ const check = checkState(session);
182
+ if (check.awaitingProgress || userWaits.has(id)) return null;
183
+ const open = openTodoItems(session);
184
+ if (open.length) {
185
+ if (check.reminders >= MAX_TODO_REMINDERS) return null;
186
+ if (awaitingBackgroundWork({ sessionId: id })) return null;
187
+ check.reminders += 1;
188
+ check.awaitingProgress = true;
189
+ return openItemsReminder(open, check.reminders);
190
+ }
191
+ if (check.auditAsked || !id || !activeGoal(id)) return null;
192
+ if (awaitingBackgroundWork({ sessionId: id })) return null;
193
+ check.auditAsked = true;
194
+ check.awaitingProgress = true;
195
+ return GOAL_AUDIT_REMINDER;
196
+ }