mixdog 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. package/NOTICE.md +52 -9
  2. package/README.md +8 -4
  3. package/package.json +2 -2
  4. package/scripts/native-release-status.mjs +238 -0
  5. package/src/defaults/shipped-history.json +8 -1
  6. package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
  7. package/src/defaults/skills/setup/SKILL.md +23 -1
  8. package/src/defaults/skills/setup/references/actions.md +54 -4
  9. package/src/defaults/skills/setup/references/surfaces.md +23 -3
  10. package/src/defaults/skills/setup-guide/SKILL.md +17 -10
  11. package/src/defaults/skills/visualize/SKILL.md +9 -6
  12. package/src/defaults/skills/visualize/references/craft.md +8 -1
  13. package/src/help.mjs +1 -1
  14. package/src/lib/keychain-cjs.cjs +4 -1
  15. package/src/lib/rules-builder.cjs +14 -7
  16. package/src/output-styles/common.md +13 -8
  17. package/src/rules/agent-mode/AGENT_MODE.md +9 -6
  18. package/src/rules/agent-mode/MIXY.md +11 -6
  19. package/src/rules/lead/LEAD.md +2 -2
  20. package/src/rules/shared/10-tool-workflow.md +4 -0
  21. package/src/rules/shared/20-research.md +2 -0
  22. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
  23. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
  24. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
  25. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
  26. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
  28. package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
  29. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
  30. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  31. package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
  32. package/src/runtime/agent/orchestrator/config.mjs +11 -0
  33. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +81 -16
  34. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -4
  35. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
  36. package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
  37. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +80 -31
  38. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
  39. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  40. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +67 -38
  41. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
  42. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +7 -2
  43. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
  44. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +34 -16
  45. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
  46. package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
  47. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
  48. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
  49. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +19 -1
  50. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
  51. package/src/runtime/agent/orchestrator/providers/lib/tool-call-wire-ids.mjs +65 -0
  52. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
  53. package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
  54. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
  55. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
  56. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
  57. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
  58. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +8 -2
  59. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +10 -2
  60. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
  61. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
  62. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +3 -1
  63. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
  64. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
  65. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +14 -2
  66. package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -0
  67. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +17 -0
  68. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
  69. package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
  70. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
  71. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
  72. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
  73. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +5 -5
  74. package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
  75. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
  76. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +12 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +17 -6
  78. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +41 -10
  79. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +6 -4
  80. package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
  81. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +2 -0
  82. package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
  83. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
  84. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
  85. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +21 -2
  86. package/src/runtime/agent/orchestrator/session/agent-room.mjs +149 -45
  87. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
  88. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  89. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +14 -11
  90. package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
  91. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +68 -18
  92. package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
  93. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
  94. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
  95. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +5 -1
  96. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +1 -1
  97. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
  99. package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +230 -0
  100. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +156 -25
  101. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
  102. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +21 -9
  103. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
  104. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
  105. package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
  106. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
  107. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +189 -105
  108. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +9 -0
  109. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
  110. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +111 -9
  111. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +11 -14
  112. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
  113. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +38 -5
  114. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +21 -0
  115. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
  116. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
  117. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
  118. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +46 -4
  119. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
  120. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +18 -8
  121. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +4 -0
  122. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  123. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  124. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
  125. package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +99 -0
  126. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
  127. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
  128. package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
  129. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
  130. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +50 -0
  131. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
  132. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
  133. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
  134. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +62 -47
  135. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +6 -8
  136. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +12 -1
  137. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
  138. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +7 -1
  139. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
  140. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +1 -1
  141. package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
  142. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +5 -2
  143. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +42 -10
  144. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
  145. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +35 -4
  146. package/src/runtime/agent/orchestrator/session/routine-result.mjs +179 -16
  147. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -1
  148. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
  149. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
  150. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
  151. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
  152. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
  153. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +8 -3
  154. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +36 -1
  155. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -1
  156. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
  157. package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
  158. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
  159. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
  160. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
  161. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +49 -14
  162. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +134 -17
  163. package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +35 -13
  164. package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
  165. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -3
  166. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
  167. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
  168. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
  169. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
  170. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +6 -14
  171. package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
  172. package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
  173. package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
  174. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
  175. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
  176. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +34 -21
  177. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
  178. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
  179. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
  180. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
  181. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
  182. package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
  183. package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
  184. package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
  185. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
  186. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
  187. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
  188. package/src/runtime/attachments/attachment-reference.mjs +155 -0
  189. package/src/runtime/attachments/limits.mjs +5 -1
  190. package/src/runtime/attachments/office-extract.mjs +3 -6
  191. package/src/runtime/attachments/pdf-extract.mjs +84 -10
  192. package/src/runtime/attachments/store.mjs +55 -30
  193. package/src/runtime/browser-bridge/client.mjs +73 -20
  194. package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
  195. package/src/runtime/channels/lib/scheduler.mjs +14 -7
  196. package/src/runtime/channels/lib/state-file.mjs +15 -15
  197. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
  198. package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
  199. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
  200. package/src/runtime/channels/lib/worker-main.mjs +3 -2
  201. package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
  202. package/src/runtime/effort-judge/judge-client.mjs +6 -3
  203. package/src/runtime/effort-judge/model-install.mjs +16 -8
  204. package/src/runtime/effort-judge/model-manifest.json +7 -7
  205. package/src/runtime/local-provider/asset-installer.mjs +10 -4
  206. package/src/runtime/local-provider/catalog.mjs +5 -2
  207. package/src/runtime/local-provider/registered-models.mjs +64 -27
  208. package/src/runtime/local-provider/server.mjs +2 -3
  209. package/src/runtime/media/adapters/image-api.mjs +89 -0
  210. package/src/runtime/media/auth.mjs +64 -1
  211. package/src/runtime/media/catalog.mjs +66 -4
  212. package/src/runtime/media/jobs.mjs +4 -0
  213. package/src/runtime/media/lanes.mjs +46 -5
  214. package/src/runtime/media/media-usage.mjs +17 -0
  215. package/src/runtime/media/renditions.mjs +15 -15
  216. package/src/runtime/media/store.mjs +36 -35
  217. package/src/runtime/media/tool.mjs +8 -1
  218. package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
  219. package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
  220. package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
  221. package/src/runtime/memory/lib/pg/process.mjs +8 -4
  222. package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
  223. package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
  224. package/src/runtime/office/core/journal.mjs +7 -14
  225. package/src/runtime/office/design/library/design-library-core.mjs +4 -16
  226. package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
  227. package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
  228. package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
  229. package/src/runtime/office/pdf/pdf-render.mjs +30 -18
  230. package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
  231. package/src/runtime/office/portable/portable-soffice.mjs +4 -0
  232. package/src/runtime/shared/agent-kind-migration.mjs +200 -0
  233. package/src/runtime/shared/agent-kind.mjs +152 -0
  234. package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
  235. package/src/runtime/shared/agent-message-envelope.mjs +44 -0
  236. package/src/runtime/shared/agent-reap-state.d.mts +4 -0
  237. package/src/runtime/shared/agent-route-config.d.mts +1 -0
  238. package/src/runtime/shared/agent-route-config.mjs +22 -8
  239. package/src/runtime/shared/agent-store.mjs +149 -0
  240. package/src/runtime/shared/agent-task-starts.mjs +27 -0
  241. package/src/runtime/shared/atomic-file.d.mts +50 -0
  242. package/src/runtime/shared/atomic-file.mjs +394 -132
  243. package/src/runtime/shared/background-tasks.mjs +7 -4
  244. package/src/runtime/shared/bot-hops.mjs +30 -0
  245. package/src/runtime/shared/bot-split-migration.mjs +457 -0
  246. package/src/runtime/shared/bounded-download.mjs +4 -2
  247. package/src/runtime/shared/config-patch.mjs +20 -1
  248. package/src/runtime/shared/config.mjs +39 -9
  249. package/src/runtime/shared/connector-catalog.d.mts +1 -2
  250. package/src/runtime/shared/connector-catalog.mjs +2 -4
  251. package/src/runtime/shared/connector-triggers.mjs +2 -0
  252. package/src/runtime/shared/defaults-separation.mjs +6 -2
  253. package/src/runtime/shared/delegated-approval-host.mjs +74 -0
  254. package/src/runtime/shared/err-text.mjs +7 -1
  255. package/src/runtime/shared/error-presentation.mjs +113 -10
  256. package/src/runtime/shared/file-has-data.mjs +28 -0
  257. package/src/runtime/shared/handoff-artifacts.d.mts +20 -0
  258. package/src/runtime/shared/handoff-artifacts.mjs +61 -0
  259. package/src/runtime/shared/llm/provider-model-identities.mjs +6 -1
  260. package/src/runtime/shared/llm/usage-accounting.mjs +7 -1
  261. package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
  262. package/src/runtime/shared/model-route-fallback.mjs +79 -7
  263. package/src/runtime/shared/pending-agent-work.mjs +54 -0
  264. package/src/runtime/shared/plain-preview.mjs +22 -17
  265. package/src/runtime/shared/process-lifecycle.mjs +8 -12
  266. package/src/runtime/shared/projects.mjs +50 -41
  267. package/src/runtime/shared/provider-accounts.mjs +17 -12
  268. package/src/runtime/shared/routine-trigger.d.mts +6 -1
  269. package/src/runtime/shared/routine-trigger.mjs +14 -6
  270. package/src/runtime/shared/run-child.d.mts +3 -0
  271. package/src/runtime/shared/run-child.mjs +24 -3
  272. package/src/runtime/shared/sensitive-path-rules.d.mts +15 -0
  273. package/src/runtime/shared/sensitive-path-rules.mjs +256 -0
  274. package/src/runtime/shared/session-baseline-store.mjs +8 -2
  275. package/src/runtime/shared/singleton-owner.mjs +7 -6
  276. package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
  277. package/src/runtime/shared/staged-update.mjs +4 -2
  278. package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
  279. package/src/runtime/shared/tool-execution-contract.mjs +6 -0
  280. package/src/runtime/shared/transcript-metadata.mjs +28 -3
  281. package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
  282. package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
  283. package/src/runtime/shared/turn-snapshot.mjs +44 -2
  284. package/src/runtime/shared/usage-readout-totals.mjs +15 -13
  285. package/src/runtime/shared/user-cwd.mjs +9 -4
  286. package/src/runtime/shared/user-data-guard.mjs +46 -44
  287. package/src/runtime/shared/utf8-cut.mjs +10 -0
  288. package/src/runtime/shared/worktrees/activity-gate.mjs +269 -61
  289. package/src/runtime/shared/worktrees/registry.mjs +26 -26
  290. package/src/runtime/tidy/core-install.mjs +26 -4
  291. package/src/runtime/tidy/install.mjs +91 -23
  292. package/src/runtime/web-search/lib/config.mjs +4 -16
  293. package/src/session-runtime/agent-home-delivery.mjs +859 -136
  294. package/src/session-runtime/agent-room-delivery.mjs +167 -19
  295. package/src/session-runtime/agent-task-sessions.mjs +831 -69
  296. package/src/session-runtime/agent-tool-routing.mjs +1 -0
  297. package/src/session-runtime/boot/apis.mjs +58 -24
  298. package/src/session-runtime/boot/config.mjs +1 -0
  299. package/src/session-runtime/boot/facade.mjs +11 -1
  300. package/src/session-runtime/boot/infrastructure.mjs +14 -2
  301. package/src/session-runtime/boot/providers.mjs +16 -6
  302. package/src/session-runtime/boot/shared.mjs +12 -6
  303. package/src/session-runtime/boot/tools.mjs +2 -2
  304. package/src/session-runtime/bot-status.mjs +432 -0
  305. package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
  306. package/src/session-runtime/config-lifecycle.mjs +78 -32
  307. package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
  308. package/src/session-runtime/handoff-attachments.mjs +593 -0
  309. package/src/session-runtime/held-requests.mjs +36 -33
  310. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
  311. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
  312. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +45 -6
  313. package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
  314. package/src/session-runtime/lifecycle/teardown.mjs +11 -3
  315. package/src/session-runtime/mcp-glue/connect.mjs +100 -186
  316. package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
  317. package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
  318. package/src/session-runtime/media-api.mjs +5 -2
  319. package/src/session-runtime/model-route/route-persist.mjs +2 -2
  320. package/src/session-runtime/model-route/route-tuning.mjs +11 -2
  321. package/src/session-runtime/model-route/set-route.mjs +82 -2
  322. package/src/session-runtime/native-web-search.mjs +2 -2
  323. package/src/session-runtime/new-session-config.mjs +6 -1
  324. package/src/session-runtime/owned-automation-run.mjs +8 -1
  325. package/src/session-runtime/room-member-gate.mjs +16 -3
  326. package/src/session-runtime/route-resolution.mjs +21 -19
  327. package/src/session-runtime/route-state.mjs +1 -59
  328. package/src/session-runtime/routine-home-turn.mjs +5 -3
  329. package/src/session-runtime/runtime-bootstrap.mjs +5 -3
  330. package/src/session-runtime/runtime-paths.mjs +11 -5
  331. package/src/session-runtime/runtime-tunables.mjs +6 -0
  332. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
  333. package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
  334. package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
  335. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
  336. package/src/session-runtime/services/agent-tool/helpers.mjs +24 -5
  337. package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
  338. package/src/session-runtime/services/agent-tool/send-flow.mjs +36 -24
  339. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -0
  340. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
  341. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +12 -6
  342. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +5 -8
  343. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  344. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
  345. package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
  346. package/src/session-runtime/services/agent-tool.mjs +6 -0
  347. package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
  348. package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
  349. package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
  350. package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
  351. package/src/session-runtime/services/plugin-admin.mjs +26 -26
  352. package/src/session-runtime/services/provider-admin.mjs +14 -4
  353. package/src/session-runtime/services/schedule-access.mjs +33 -4
  354. package/src/session-runtime/services/seeds.mjs +4 -3
  355. package/src/session-runtime/services/usage-dashboard.mjs +1 -1
  356. package/src/session-runtime/services/usage-stats-model.mjs +2 -1
  357. package/src/session-runtime/session-create/materialize.mjs +2 -3
  358. package/src/session-runtime/session-create/session-options.mjs +15 -2
  359. package/src/session-runtime/settings-builtin-tools-api.mjs +63 -1
  360. package/src/session-runtime/settings-compaction-api.mjs +86 -39
  361. package/src/session-runtime/setup-tool/executor.mjs +20 -3
  362. package/src/session-runtime/setup-tool/extended-actions.mjs +19 -7
  363. package/src/session-runtime/setup-tool/settings-contract.mjs +37 -1
  364. package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
  365. package/src/session-runtime/skills-api.mjs +12 -5
  366. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +265 -0
  367. package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
  368. package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
  369. package/src/session-runtime/tool-policy/policy-stage.mjs +165 -0
  370. package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
  371. package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
  372. package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
  373. package/src/session-runtime/tool-policy-refresh.mjs +47 -358
  374. package/src/session-runtime/tool-surface.mjs +5 -3
  375. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +99 -81
  376. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  377. package/src/session-runtime/turn/turn-run.mjs +2 -1
  378. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
  379. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +578 -301
  380. package/src/session-runtime/workflow-agents-api/agent-route.mjs +113 -53
  381. package/src/session-runtime/workflow-agents-api/onboarding.mjs +11 -4
  382. package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
  383. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
  384. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
  385. package/src/session-runtime/workspace/workspace-state.mjs +7 -6
  386. package/src/standalone/daemon-agent-control.mjs +4 -1
  387. package/src/standalone/daemon-session-control.mjs +60 -11
  388. package/src/standalone/daemon.mjs +34 -4
  389. package/src/standalone/local-session-runtime.mjs +22 -14
  390. package/src/standalone/session-client.mjs +7 -2
  391. package/src/standalone/session-protocol.mjs +7 -0
  392. package/src/standalone/session-service/agent-tree/agent-turns.mjs +46 -3
  393. package/src/standalone/session-service/agent-tree.mjs +4 -3
  394. package/src/standalone/session-service/session-calls/session-turns.mjs +19 -0
  395. package/src/standalone/session-service.mjs +11 -0
  396. package/src/standalone/session-state-projection.mjs +19 -9
  397. package/src/standalone/session-tool-output.mjs +35 -9
  398. package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
  399. package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
  400. package/src/tui/app/slash-commands.mjs +1 -1
  401. package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
  402. package/src/tui/dist/index.mjs +599 -342
  403. package/src/tui/prompt-history-store.mjs +16 -21
  404. package/src/tui/session/context-state.mjs +4 -0
  405. package/src/tui/session/notice-surface.mjs +3 -4
  406. package/src/tui/session/session-api/intake/abort.mjs +19 -1
  407. package/src/tui/session/session-api/media.mjs +2 -1
  408. package/src/tui/session/session-api/routes-agent-definitions.mjs +75 -0
  409. package/src/tui/session/session-api/routes-write.mjs +203 -0
  410. package/src/tui/session/session-api/routes.mjs +23 -236
  411. package/src/tui/session/session-api/settings.mjs +14 -1
  412. package/src/tui/session/session-flow/drain.mjs +28 -3
  413. package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
  414. package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
  415. package/src/tui/session/session-flow/steering.mjs +8 -3
  416. package/src/tui/session/tool-approval.mjs +185 -20
  417. package/src/tui/session/transcript-intake.mjs +4 -0
  418. package/src/tui/session/turn-live-call.mjs +11 -3
  419. package/src/tui/session/turn.mjs +36 -17
  420. package/src/tui/transcript-tool-failures.mjs +8 -2
  421. package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
  422. package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
  423. package/src/rules/agent-mode/ROUTINE.md +0 -6
@@ -15,6 +15,7 @@ export const SESSION_READ_ACTIONS = Object.freeze([
15
15
  'getAgentAvatarImage',
16
16
  'getAgentConnectors',
17
17
  'getProjectConnectors',
18
+ 'getAgentAlwaysAllowedTools',
18
19
  'getAgentPermissions',
19
20
  'listConnectors',
20
21
  'listConnectorTools',
@@ -45,6 +46,8 @@ export const SESSION_READ_ACTIONS = Object.freeze([
45
46
  'getQuotaHistory',
46
47
  'getRecapSettings',
47
48
  'getSessionTitleSettings',
49
+ 'getLeadAppearance',
50
+ 'getBotOrder',
48
51
  'getWebSearchRoute',
49
52
  'getSettingsSnapshot',
50
53
  'getSystemShell',
@@ -188,6 +191,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
188
191
  'setAgentConnectorToolPermission',
189
192
  'setProjectConnectorEnabled',
190
193
  'setAgentPermission',
194
+ 'recordAgentApprovalAudit',
191
195
  'saveLeadPersona',
192
196
  'saveLeadAgentBody',
193
197
  'setLeadCreated',
@@ -233,6 +237,8 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
233
237
  'setProgressHint',
234
238
  'setRecapEnabled',
235
239
  'setAiSessionTitles',
240
+ 'setLeadAppearance',
241
+ 'setBotOrder',
236
242
  'setRoute',
237
243
  'setScheduleEnabled',
238
244
  'setWebSearchRoute',
@@ -241,6 +247,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
241
247
  'setToolMode',
242
248
  'setWebSearchEnabled',
243
249
  'setInstructionFiles',
250
+ 'setAutoEffortBase',
244
251
  'setWebhookConfig',
245
252
  'setWebhookEnabled',
246
253
  'setWorkflow',
@@ -4,6 +4,43 @@
4
4
  import { randomUUID } from 'node:crypto';
5
5
  import { createAgentChildFactory } from './agent-child.mjs';
6
6
  import { partialHandoffTextFromSession } from '../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
7
+ import { attachmentsForIntake } from '../../../runtime/attachments/store.mjs';
8
+ import { artifactLines } from '../../../runtime/shared/handoff-artifacts.mjs';
9
+ import { collectTurnArtifacts, handoffContent, sessionRoots } from '../../../session-runtime/handoff-attachments.mjs';
10
+
11
+ /** An agent turn's prompt: text, or text with forwarded attachment parts
12
+ * (handoff-attachments.mjs), never any other shape. */
13
+ export function agentTurnContent(prompt) {
14
+ if (!Array.isArray(prompt)) return String(prompt || '');
15
+ const text = prompt
16
+ .filter((part) => part?.type === 'text' && !part.attachmentRef)
17
+ .map((part) => String(part.text || ''))
18
+ .join('\n');
19
+ return handoffContent(text, prompt);
20
+ }
21
+
22
+ /** The prompt row's metadata: a Lead's message, with the files it carries. */
23
+ export function agentTurnTranscriptMeta(content) {
24
+ const attachments = Array.isArray(content) ? attachmentsForIntake(content) : [];
25
+ return { sender: 'lead', ...(attachments.length ? { attachments } : {}) };
26
+ }
27
+
28
+ /** The artifact lines of the turn that began at `messageStart`; [] on any
29
+ * failure to read it (the handoff still goes out). */
30
+ async function turnArtifactLines(runtime, messageStart, descriptor) {
31
+ try {
32
+ const { messages } = await runtime.readModelMessages(messageStart);
33
+ const session = runtime.session || descriptor;
34
+ const { files, omitted } = collectTurnArtifacts(messages, {
35
+ cwd: descriptor.cwd,
36
+ roots: sessionRoots(session, descriptor.cwd),
37
+ });
38
+ // Text only: the caller forwards these by path (an id in text is never trusted).
39
+ return artifactLines(files, omitted, { ids: false });
40
+ } catch {
41
+ return [];
42
+ }
43
+ }
7
44
 
8
45
  export function createAgentTurns({
9
46
  registry,
@@ -67,15 +104,16 @@ export function createAgentTurns({
67
104
  descriptor.stage = 'running';
68
105
  descriptor.updatedAt = Date.now();
69
106
  try {
107
+ const content = agentTurnContent(prompt);
70
108
  const options = {
71
109
  id: `agent-turn-${randomUUID()}`,
72
110
  mode: 'prompt',
73
111
  priority: 'next',
74
112
  context,
75
- transcriptMeta: { sender: 'lead' },
113
+ transcriptMeta: agentTurnTranscriptMeta(content),
76
114
  ...(entry.runtime.isWireSafe === true || typeof onToolResult !== 'function' ? {} : { onToolResult }),
77
115
  };
78
- const detail = await target.call(entry.runtime, String(prompt || ''), options);
116
+ const detail = await target.call(entry.runtime, content, options);
79
117
  if (detail?.status === 'failed') {
80
118
  throw new Error(String(detail.error || 'agent session turn failed'));
81
119
  }
@@ -91,7 +129,12 @@ export function createAgentTurns({
91
129
  const reason = String(detail?.reason || detail?.error || '').trim();
92
130
  throw new Error(`agent turn ${status}${reason ? `: ${reason}` : ''}`);
93
131
  }
94
- const result = detail?.result || { content: '' };
132
+ let result = detail?.result || { content: '' };
133
+ // The files the turn produced reach the owner with its handoff.
134
+ const files = await turnArtifactLines(entry.runtime, messageStart, descriptor);
135
+ if (files.length) {
136
+ result = { ...result, content: [String(result.content || ''), files.join('\n')].join('\n\n') };
137
+ }
95
138
  descriptor.status = 'idle';
96
139
  descriptor.stage = 'idle';
97
140
  descriptor.lastHandoff = typeof result?.content === 'string' ? result.content : '';
@@ -10,7 +10,7 @@
10
10
  import { createAgentCancellation } from './agent-tree/agent-cancel.mjs';
11
11
  import { createAgentRegistry } from './agent-tree/agent-registry.mjs';
12
12
  import { createAgentRehydration, lastStoredAgentHandoff } from './agent-tree/agent-rehydrate.mjs';
13
- import { createAgentTurns } from './agent-tree/agent-turns.mjs';
13
+ import { agentTurnContent, agentTurnTranscriptMeta, createAgentTurns } from './agent-tree/agent-turns.mjs';
14
14
  import { randomUUID } from 'node:crypto';
15
15
 
16
16
  export { SESSION_ID_PATTERN } from './agent-tree/agent-registry.mjs';
@@ -139,12 +139,13 @@ export function createAgentTree({
139
139
  const cancelEpoch = registry.assertAdmission(descriptor.id);
140
140
  const runtime = sessionOwner(descriptor.id)?.runtime;
141
141
  if (!runtime || !stateBusy(runtime.getState())) return null;
142
- const accepted = await runtime.submitAsync(String(prompt || ''), {
142
+ const content = agentTurnContent(prompt);
143
+ const accepted = await runtime.submitAsync(content, {
143
144
  id: `agent-message-${randomUUID()}`,
144
145
  mode: 'prompt',
145
146
  priority: 'next',
146
147
  context,
147
- transcriptMeta: { sender: 'lead' },
148
+ transcriptMeta: agentTurnTranscriptMeta(content),
148
149
  });
149
150
  if (accepted === false) throw new Error('agent follow-up was not accepted');
150
151
  registry.assertAdmission(descriptor.id, cancelEpoch);
@@ -12,6 +12,7 @@ import {
12
12
  import { providerNativePdf } from '../../../runtime/agent/orchestrator/providers/registry.mjs';
13
13
  import { cancelBackgroundTasks } from '../../../runtime/shared/background-tasks.mjs';
14
14
  import { isAgentModeSession } from '../../../runtime/agent/orchestrator/session/agent-mode.mjs';
15
+ import { isAgentHomeSessionId } from '../../../runtime/agent/orchestrator/session/agent-home.mjs';
15
16
  import { recognisedAgentRoomSlash } from '../../../tui/app/slash-commands.mjs';
16
17
  import { promptContentText } from '../../../tui/session/queue-helpers.mjs';
17
18
 
@@ -38,6 +39,17 @@ function abortsAgentTurn(id, state, hasAgentSession) {
38
39
  );
39
40
  }
40
41
 
42
+ /** A prompt the user typed: not an agent's send (`sender: 'lead'`), a hidden
43
+ * wake, a routine fire or any other runtime-made turn. */
44
+ export function isUserTurn(options = {}) {
45
+ return (
46
+ (options.mode || 'prompt') === 'prompt' &&
47
+ options.kickoff !== true &&
48
+ options.isMeta !== true &&
49
+ options.transcriptMeta?.sender !== 'lead'
50
+ );
51
+ }
52
+
41
53
  export function createSessionTurnCalls(ctx) {
42
54
  const { log, readStoredGoal, listStoredActiveGoalSessionIds, hasAgentSession, sessionResult, advanceForCaller } = ctx;
43
55
  const { retainUnwatched } = ctx.retention;
@@ -88,6 +100,13 @@ export function createSessionTurnCalls(ctx) {
88
100
  const accepted = await Promise.resolve(target.call(entry.runtime, intake.prompt, submissionOptions));
89
101
  if (accepted === true) {
90
102
  entry.reservedOnly = false;
103
+ if (isAgentHomeSessionId(id) && isUserTurn(submissionOptions)) {
104
+ // The user spoke in this agent's home: its round trips with other
105
+ // sessions count from zero again, so a capped thread wakes again.
106
+ void import('../../../session-runtime/agent-home-delivery.mjs')
107
+ .then(({ resetAgentTaskRounds }) => resetAgentTaskRounds(id))
108
+ .catch((error) => log(`round reset of ${id} failed: ${error?.message || error}`));
109
+ }
91
110
  }
92
111
  const step = settleAction(entry, 'headless session submit');
93
112
  log(`session submit session=${id} accepted=${accepted === true}`);
@@ -23,6 +23,7 @@ import { createViewerRegistry } from './session-service/viewers.mjs';
23
23
  import { createSessionEntries } from './session-service/entries.mjs';
24
24
  import { createSessionCalls } from './session-service/session-calls.mjs';
25
25
  import { createQuotaResumeScheduler } from './session-service/quota-resume.mjs';
26
+ import { registerDelegatedApprovalOpener } from '../runtime/shared/delegated-approval-host.mjs';
26
27
 
27
28
  const EXTERNAL_SESSION_ACTIONS = new Set([
28
29
  ...SESSION_READ_ACTION_SET,
@@ -205,6 +206,9 @@ export function createSessionService({
205
206
  retainUnwatched: retention.retainUnwatched,
206
207
  createSession: calls.createSession,
207
208
  });
209
+ // A sub-agent's approval shows in its top-level chat; one not loaded is
210
+ // brought up so the copy (and its notifications) appear there.
211
+ const unregisterApprovalOpener = registerDelegatedApprovalOpener((sessionId) => calls.materializeSession(sessionId));
208
212
  const quotaUsableReader = typeof readQuotaUsable === 'function' ? readQuotaUsable : async () => false;
209
213
  const quotaResume = quotaResumeStore
210
214
  ? createQuotaResumeScheduler({
@@ -219,6 +223,7 @@ export function createSessionService({
219
223
  function stop(reason = 'service stop') {
220
224
  if (stopPromise) return stopPromise;
221
225
  closed = true;
226
+ unregisterApprovalOpener();
222
227
  quotaResume?.stop();
223
228
  stopPromise = Promise.resolve().then(async () => {
224
229
  try {
@@ -243,6 +248,11 @@ export function createSessionService({
243
248
  return Boolean(owner) && retention.stateBusy(owner.runtime?.getState?.());
244
249
  }
245
250
 
251
+ /** Whether the runtime hosting `sessionId` shows an approval card waiting on the user. */
252
+ function liveSessionAwaitingApproval(sessionId) {
253
+ return Boolean(projection.sessionOwner(sessionId)?.runtime?.getState?.()?.toolApproval);
254
+ }
255
+
246
256
  /** Show a transcript notice in the hosted runtime of `sessionId` (no turn)
247
257
  * and publish it to its views; false when no runtime hosts it. */
248
258
  function pushLiveSessionNotice(sessionId, { text, tone = 'info', ...options } = {}) {
@@ -300,6 +310,7 @@ export function createSessionService({
300
310
  methods: {
301
311
  ...calls,
302
312
  liveSessionBusy,
313
+ liveSessionAwaitingApproval,
303
314
  pushLiveSessionNotice,
304
315
  stop,
305
316
  startQuotaResume: () => quotaResume?.start(),
@@ -1,4 +1,6 @@
1
1
  import { sanitizeForWire } from './session-wire-values.mjs';
2
+ import { stripAgentMessageEnvelope } from '../runtime/shared/agent-message-envelope.mjs';
3
+ import { transcriptSourceFields } from '../runtime/shared/transcript-metadata.mjs';
2
4
 
3
5
  /** Immutable source fields keep their wire identity until they actually change.
4
6
  * In particular, a live tail must not rebuild the settled transcript or resend
@@ -29,15 +31,23 @@ export function projectSessionState(entry, raw) {
29
31
  }
30
32
  let cloned;
31
33
  if (key === 'queued' && Array.isArray(value)) {
32
- cloned = value.map((item) => ({
33
- id: item?.id,
34
- submittedAt: item?.submittedAt,
35
- text: String(item?.displayText ?? item?.text ?? '').slice(0, 2_000),
36
- displayText: String(item?.displayText ?? item?.text ?? '').slice(0, 2_000),
37
- mode: item?.mode || 'prompt',
38
- priority: item?.priority || 'next',
39
- ...(Array.isArray(item?.images) && item.images.length ? { images: item.images } : {}),
40
- }));
34
+ cloned = value.map((item) => {
35
+ // A queued bot message reads like its delivered row: the sender tag
36
+ // and the message without its envelope.
37
+ const source = transcriptSourceFields(item?.transcriptMeta);
38
+ const queuedText = String(item?.displayText ?? item?.text ?? '');
39
+ const text = (source.fromAgent ? stripAgentMessageEnvelope(queuedText) : queuedText).slice(0, 2_000);
40
+ return {
41
+ id: item?.id,
42
+ submittedAt: item?.submittedAt,
43
+ text,
44
+ displayText: text,
45
+ mode: item?.mode || 'prompt',
46
+ priority: item?.priority || 'next',
47
+ ...source,
48
+ ...(Array.isArray(item?.images) && item.images.length ? { images: item.images } : {}),
49
+ };
50
+ });
41
51
  } else if (key === 'items' && Array.isArray(value)) {
42
52
  const items = entry.itemCache;
43
53
  const nextItems = new Map();
@@ -1,4 +1,6 @@
1
1
  import { encodeCatalogCursor } from '../runtime/agent/orchestrator/session/catalog-db/schema.mjs';
2
+ import { UNTRUSTED_NOTE, sessionBotOf } from '../session-runtime/bot-status.mjs';
3
+ import { escapeHarnessTags } from '../runtime/shared/shell-output-summary.mjs';
2
4
  import { truncateToolText } from '../runtime/shared/tool-primitives.mjs';
3
5
  import { summarizeToolResult } from '../runtime/shared/tool-result-summary.mjs';
4
6
 
@@ -6,18 +8,42 @@ import { TOOL_OUTPUT_PAGE_BYTES, TOOL_OUTPUT_TAIL_BYTES } from '../runtime/share
6
8
 
7
9
  export const SESSION_TOOL_OUTPUT_BYTES = TOOL_OUTPUT_TAIL_BYTES;
8
10
  const MESSAGE_TEXT_LIMIT = 2000;
11
+ const LIST_PREVIEW_LIMIT = 100;
9
12
  const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
10
13
 
11
- /** Keep catalog paging authoritative even when the output budget shortens a page. */
12
- export function sessionListOutput(page, limit) {
14
+ /** Keep catalog paging authoritative even when the output budget shortens a page.
15
+ * `rich` adds the owning bot, last activity, latest line and working state
16
+ * (never for a background caller: bot-status.mjs scopedBot). */
17
+ export function sessionListOutput(page, limit, { rich = true } = {}) {
13
18
  const raw = page.sessions;
14
- const sessions = raw.slice(0, limit).map((row) => ({
15
- id: row.id,
16
- ...(row.title || row.preview ? { title: truncateToolText(row.title || row.preview, 160) } : {}),
17
- ...(row.status ? { status: row.status } : {}),
18
- ...(row.cwd ? { cwd: row.cwd } : {}),
19
- }));
20
- const result = { sessions, nextCursor: page.nextCursor ?? null };
19
+ const sessions = raw.slice(0, limit).map((row) => {
20
+ const base = {
21
+ id: row.id,
22
+ ...(row.title || row.preview
23
+ ? { title: escapeHarnessTags(truncateToolText(row.title || row.preview, 160)) }
24
+ : {}),
25
+ ...(row.status ? { status: row.status } : {}),
26
+ ...(row.cwd ? { cwd: row.cwd } : {}),
27
+ };
28
+ if (!rich) return base;
29
+ // The bot it belongs to: its chat, room seat or the task's creator.
30
+ const bot = sessionBotOf(row);
31
+ const lastUsedAt = Number(row.lastUsedAt) || 0;
32
+ const preview = String(row.lastMessagePreview || '').replace(/\s+/g, ' ');
33
+ return {
34
+ ...base,
35
+ ...(bot ? { bot } : {}),
36
+ ...(lastUsedAt ? { lastUsedAt: new Date(lastUsedAt).toISOString() } : {}),
37
+ // The latest user or assistant line, quoted data.
38
+ ...(preview.trim() ? { preview: escapeHarnessTags(truncateToolText(preview, LIST_PREVIEW_LIMIT)) } : {}),
39
+ ...(row.working === true || row.agentWorking === true ? { working: true } : {}),
40
+ };
41
+ });
42
+ const result = {
43
+ sessions,
44
+ nextCursor: page.nextCursor ?? null,
45
+ ...(sessions.some((row) => row.preview) ? { note: UNTRUSTED_NOTE } : {}),
46
+ };
21
47
  for (;;) {
22
48
  if (sessions.length < raw.length && sessions.length) {
23
49
  result.nextCursor = encodeCatalogCursor(raw[sessions.length - 1]);
@@ -3,10 +3,14 @@
3
3
  // the Advanced list of provider default idle windows edited as text.
4
4
 
5
5
  // Lead BP4 messages cache TTL follows autoClear (cache-strategy.mjs
6
- // resolveLeadMessagesTtl): off or idle>=1h -> 1h, shorter idle -> 5m.
6
+ // resolveLeadMessagesTtl): off or idle>=1h (incl. unlimited) -> 1h, shorter
7
+ // idle -> 5m.
7
8
  const HOUR_MS = 60 * 60 * 1000;
9
+ // Typed (and shown) for "never auto-clear"; the runtime stores it as 0.
10
+ const UNLIMITED_INPUT = 'unlimited';
8
11
 
9
- const formatDurationInput = (ms) => {
12
+ const formatDurationInput = (ms, unlimited = false) => {
13
+ if (unlimited) return UNLIMITED_INPUT;
10
14
  const value = Math.max(0, Math.round(Number(ms) || 0));
11
15
  if (value > 0 && value % HOUR_MS === 0) return `${value / HOUR_MS}h`;
12
16
  if (value > 0 && value % 60_000 === 0) return `${value / 60_000}m`;
@@ -39,7 +43,7 @@ export function createAutoClearPicker({
39
43
  label: entry.provider,
40
44
  marker: entry.provider === provider ? '✓' : '',
41
45
  markerColor: theme.success,
42
- meta: `${formatDuration(entry.idleMs)}${entry.custom ? ' custom' : ''}`,
46
+ meta: `${entry.unlimited ? 'Unlimited' : formatDuration(entry.idleMs)}${entry.custom ? ' custom' : ''}`,
43
47
  description: `Default idle window for ${entry.provider}. Enter to edit as text.`,
44
48
  _action: 'provider-default',
45
49
  _entry: entry,
@@ -66,10 +70,10 @@ export function createAutoClearPicker({
66
70
  store.pushNotice('autoclear unavailable', 'warn');
67
71
  return;
68
72
  }
69
- store.pushNotice(
70
- next.enabled ? `autoclear on · idle ${formatDuration(next.idleMs)}` : 'autoclear off',
71
- 'info'
72
- );
73
+ let notice = 'autoclear off';
74
+ if (next.enabled)
75
+ notice = next.unlimited ? 'autoclear on · unlimited' : `autoclear on · idle ${formatDuration(next.idleMs)}`;
76
+ store.pushNotice(notice, 'info');
73
77
  })
74
78
  .catch((e) => store.pushNotice(`autoclear failed: ${e?.message || e}`, 'error'))
75
79
  .finally(settled);
@@ -80,8 +84,8 @@ export function createAutoClearPicker({
80
84
  setSettingsPrompt({
81
85
  kind: 'autoclear-provider',
82
86
  label: `Auto-clear · ${entry.provider}`,
83
- hint: `Type a duration like 10m, 1h, or 24h. Empty resets to built-in ${formatDurationInput(entry.builtInMs)}.`,
84
- initialValue: formatDurationInput(entry.idleMs),
87
+ hint: `Type a duration like 10m, 1h, or 24h, or ${UNLIMITED_INPUT} to never auto-clear. Empty resets to built-in ${formatDurationInput(entry.builtInMs, entry.builtInUnlimited)}.`,
88
+ initialValue: formatDurationInput(entry.idleMs, entry.unlimited),
85
89
  provider: entry.provider,
86
90
  builtInMs: entry.builtInMs,
87
91
  returnTo,
@@ -109,18 +113,20 @@ export function createAutoClearPicker({
109
113
  const current = await readCurrent();
110
114
  const enabled = current?.enabled !== false;
111
115
  const idleMs = Number(current?.idleMs || HOUR_MS);
116
+ const unlimited = current?.unlimited === true;
112
117
  const cacheTtlLabel = !enabled || idleMs >= HOUR_MS ? '1h' : '5m';
113
118
  let sourceLabel = `${current?.provider || 'default'} default`;
114
119
  if (current?.providerCustom) sourceLabel = `${current.provider} override`;
115
120
  else if (current?.custom) sourceLabel = 'global';
121
+ const clearText = unlimited
122
+ ? `Never clear idle sessions (${sourceLabel})`
123
+ : `Clear idle sessions after ${formatDuration(idleMs)} (${sourceLabel})`;
116
124
  const items = [
117
125
  {
118
126
  value: 'toggle',
119
127
  label: 'Auto-clear',
120
128
  meta: enabled ? 'On' : 'Off',
121
- description: enabled
122
- ? `Clear idle sessions after ${formatDuration(idleMs)} (${sourceLabel}) · lead cache TTL ${cacheTtlLabel}.`
123
- : 'Idle auto-clear disabled.',
129
+ description: enabled ? `${clearText} · lead cache TTL ${cacheTtlLabel}.` : 'Idle auto-clear disabled.',
124
130
  _action: 'toggle',
125
131
  },
126
132
  {
@@ -132,7 +138,7 @@ export function createAutoClearPicker({
132
138
  ];
133
139
  own.paint({
134
140
  title: 'Auto-clear',
135
- description: `Clear idle context after ${enabled ? `${formatDuration(idleMs)} (${sourceLabel})` : 'never'} · lead cache TTL ${cacheTtlLabel}.`,
141
+ description: `Clear idle context after ${enabled && !unlimited ? `${formatDuration(idleMs)} (${sourceLabel})` : 'never'} · lead cache TTL ${cacheTtlLabel}.`,
136
142
  help: '↑/↓ Select · ←/→ Toggle On/Off · Enter Open/Toggle · Esc Close',
137
143
  indexMode: 'always',
138
144
  labelWidth: 10,
@@ -139,9 +139,9 @@ export function buildSettingsItems({
139
139
  {
140
140
  value: 'autoclear',
141
141
  label: 'Auto-clear',
142
- meta: autoClearEnabled ? `On (${formatDuration(autoClear.idleMs)})` : 'Off',
142
+ meta: autoClearEnabled ? `On (${autoClear.unlimited ? 'Unlimited' : formatDuration(autoClear.idleMs)})` : 'Off',
143
143
  description: autoClearEnabled
144
- ? `Clear idle sessions after ${formatDuration(autoClear.idleMs)}${autoClearSource}. Enter for options.`
144
+ ? `${autoClear.unlimited ? 'Never clear idle sessions' : `Clear idle sessions after ${formatDuration(autoClear.idleMs)}`}${autoClearSource}. Enter for options.`
145
145
  : 'Idle auto-clear disabled. Enter for options.',
146
146
  _action: 'autoclear',
147
147
  },
@@ -30,7 +30,7 @@ export const SLASH_COMMANDS = [
30
30
  {
31
31
  name: 'autoclear',
32
32
  usage: '/autoclear',
33
- params: '[on|off|duration]',
33
+ params: '[on|off|duration|unlimited]',
34
34
  description: 'Reduce cache-miss cost after long idle gaps',
35
35
  },
36
36
  { name: 'resume', usage: '/resume', params: '[id]', description: 'Resume a saved chat' },
@@ -35,8 +35,12 @@ function compactElapsed(value) {
35
35
  return `${Math.max(1, Math.ceil(n / 1000))}s`;
36
36
  }
37
37
 
38
+ function compactionRunning(compaction) {
39
+ return compaction.inProgress === true || compaction.lastStage === 'compacting';
40
+ }
41
+
38
42
  function compactionState(compaction) {
39
- const compactRunning = compaction.inProgress === true || compaction.lastStage === 'compacting';
43
+ const compactRunning = compactionRunning(compaction);
40
44
  const autoClearFailed = compaction.lastStage === 'auto_clear_failed' || !!compaction.lastClearCompactError;
41
45
  const autoClearStage = compaction.lastStage === 'auto_clear' || compaction.lastClearAt;
42
46
  const compactInterrupted = compaction.lastStage === 'interrupted';
@@ -99,7 +103,9 @@ function contextMetrics({ toolsStatus, mcpStatus, skillsStatus, pluginsStatus, c
99
103
  );
100
104
  const cacheDenom = Number(usage.lastContextTokens || 0) || cachedRead + freshInput + cacheWrite;
101
105
  const compactState = compactionState(compaction);
102
- const compactDuration = compactElapsed(compaction.lastDurationMs);
106
+ // lastDurationMs belongs to the previous, finished compaction: a running
107
+ // one shows no duration rather than one that reads as its elapsed time.
108
+ const compactDuration = compactionRunning(compaction) ? '' : compactElapsed(compaction.lastDurationMs);
103
109
  return {
104
110
  tools,
105
111
  mcp,