mixdog 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/LICENSES/oh-my-pi-MIT.txt +23 -0
  2. package/NOTICE.md +17 -2
  3. package/README.md +11 -0
  4. package/package.json +3 -11
  5. package/scripts/daemon-stub.mjs +1 -1
  6. package/scripts/embed-google-oauth-client.mjs +49 -0
  7. package/scripts/gate-local.mjs +4 -2
  8. package/scripts/lib/test-spawn-ledger.mjs +46 -1
  9. package/scripts/native-release-status.mjs +2 -2
  10. package/scripts/recall-history-cases.json +1 -1
  11. package/scripts/suite-health.mjs +10 -1
  12. package/scripts/test.mjs +12 -11
  13. package/src/agents/reviewer/AGENT.md +7 -11
  14. package/src/agents/reviewer/agent.json +1 -1
  15. package/src/defaults/shipped-history.json +25 -1
  16. package/src/defaults/skills/browser-use/SKILL.md +77 -17
  17. package/src/defaults/skills/code-tidy/SKILL.md +142 -270
  18. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
  19. package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
  20. package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
  21. package/src/defaults/skills/computer-use/SKILL.md +33 -9
  22. package/src/defaults/skills/setup/SKILL.md +29 -2
  23. package/src/defaults/skills/setup/references/actions.md +117 -28
  24. package/src/defaults/skills/setup/references/surfaces.md +77 -35
  25. package/src/defaults/skills/setup-guide/SKILL.md +3 -3
  26. package/src/defaults/skills/visualize/SKILL.md +2 -1
  27. package/src/lib/keychain-cjs.cjs +359 -29
  28. package/src/lib/rules-builder.cjs +10 -8
  29. package/src/rules/agent/AGENT.md +6 -6
  30. package/src/rules/agent-mode/AGENT_MODE.md +10 -2
  31. package/src/rules/agent-mode/MIXY.md +12 -0
  32. package/src/rules/lead/LEAD.md +18 -20
  33. package/src/rules/shared/05-tool-calls.md +5 -6
  34. package/src/rules/shared/10-tool-workflow.md +2 -0
  35. package/src/rules/shared/60-verification.md +7 -5
  36. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
  37. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
  38. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
  39. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
  40. package/src/runtime/agent/orchestrator/config.mjs +34 -0
  41. package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
  42. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
  43. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
  44. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
  45. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +177 -73
  46. package/src/runtime/agent/orchestrator/mcp/client.mjs +25 -2
  47. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
  48. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
  49. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
  50. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
  51. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
  52. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
  53. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +230 -137
  54. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +64 -7
  55. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
  56. package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
  59. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
  60. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +160 -69
  61. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
  63. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
  64. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
  65. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
  66. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
  67. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
  68. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
  69. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +142 -104
  70. package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
  71. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -6
  76. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
  77. package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
  78. package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
  79. package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
  80. package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
  81. package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
  82. package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
  83. package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
  84. package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
  85. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
  86. package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
  87. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
  88. package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
  89. package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
  90. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
  91. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
  92. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
  93. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
  94. package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
  95. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
  97. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
  98. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
  99. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
  100. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
  101. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  102. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
  103. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +19 -1
  104. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
  105. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  107. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
  109. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
  110. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
  111. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
  112. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
  113. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
  114. package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
  115. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
  116. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
  117. package/src/runtime/agent/orchestrator/providers/registry.mjs +43 -3
  118. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
  119. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
  120. package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
  121. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
  122. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  123. package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
  124. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
  125. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
  126. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +1 -1
  127. package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
  128. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
  129. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
  130. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  131. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
  132. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
  133. package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
  134. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
  135. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
  136. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
  137. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  138. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
  139. package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
  140. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
  141. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +148 -25
  142. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
  143. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
  144. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -0
  145. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +47 -9
  146. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -2
  147. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
  148. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +14 -2
  149. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
  151. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
  152. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +11 -2
  153. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
  154. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +51 -3
  155. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
  156. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -2
  157. package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
  158. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +14 -4
  159. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  160. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
  161. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
  163. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +23 -5
  164. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
  165. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
  166. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
  167. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
  168. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
  170. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
  171. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
  172. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
  173. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
  174. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
  175. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
  176. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
  177. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
  178. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
  179. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
  180. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
  181. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
  182. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
  183. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
  184. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
  185. package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
  186. package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
  187. package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
  188. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
  189. package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
  190. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
  191. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
  192. package/src/runtime/agent/orchestrator/session/routine-result.mjs +47 -11
  193. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
  194. package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
  195. package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
  196. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
  197. package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
  198. package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
  199. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
  200. package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
  201. package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
  202. package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
  203. package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
  204. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +133 -18
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
  206. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
  207. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
  208. package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
  209. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
  210. package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
  211. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
  212. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
  213. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +4 -0
  214. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
  215. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +25 -2
  216. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
  217. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
  218. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
  219. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
  220. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
  221. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
  222. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
  224. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +25 -5
  225. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
  226. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
  227. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
  228. package/src/runtime/browser-bridge/action-schema.mjs +13 -2
  229. package/src/runtime/browser-bridge/client.mjs +73 -8
  230. package/src/runtime/browser-bridge/input-fields.mjs +8 -9
  231. package/src/runtime/browser-bridge/mail-links.mjs +107 -0
  232. package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
  233. package/src/runtime/channels/lib/config.mjs +6 -61
  234. package/src/runtime/channels/lib/crash-log.mjs +1 -1
  235. package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
  236. package/src/runtime/channels/lib/event-queue.mjs +3 -18
  237. package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
  238. package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
  239. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
  240. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
  241. package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
  242. package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
  243. package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
  244. package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
  245. package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
  246. package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
  247. package/src/runtime/channels/lib/scheduler.mjs +135 -154
  248. package/src/runtime/channels/lib/schedules-db.mjs +83 -11
  249. package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
  250. package/src/runtime/channels/lib/tool-dispatch.mjs +14 -2
  251. package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
  252. package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
  253. package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
  254. package/src/runtime/channels/lib/worker-main.mjs +19 -34
  255. package/src/runtime/computer-bridge/action-schema.mjs +42 -1
  256. package/src/runtime/computer-bridge/actions.mjs +9 -1
  257. package/src/runtime/computer-bridge/client.mjs +180 -8
  258. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  259. package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
  260. package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
  261. package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
  262. package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
  263. package/src/runtime/connectors/gmail-app-password.mjs +172 -39
  264. package/src/runtime/connectors/google-mcp.mjs +10 -12
  265. package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
  266. package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
  267. package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
  268. package/src/runtime/office/com/com-adapter.mjs +17 -1
  269. package/src/runtime/office/com/office-com-host.ps1 +51 -1
  270. package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
  271. package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
  272. package/src/runtime/office/pdf/document-preview.mjs +326 -8
  273. package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
  274. package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
  275. package/src/runtime/office/portable/portable-soffice.mjs +45 -5
  276. package/src/runtime/session-search/session-search-db.mjs +73 -9
  277. package/src/runtime/session-search/session-search-ingest.mjs +110 -20
  278. package/src/runtime/shared/abort-race.mjs +89 -0
  279. package/src/runtime/shared/agent-avatar.d.mts +0 -1
  280. package/src/runtime/shared/agent-kind.mjs +4 -3
  281. package/src/runtime/shared/bot-hops.mjs +62 -2
  282. package/src/runtime/shared/bounded-download.mjs +8 -3
  283. package/src/runtime/shared/config.mjs +51 -35
  284. package/src/runtime/shared/connector-accounts.mjs +20 -10
  285. package/src/runtime/shared/connector-catalog.d.mts +33 -2
  286. package/src/runtime/shared/connector-catalog.mjs +166 -8
  287. package/src/runtime/shared/connector-triggers.mjs +22 -19
  288. package/src/runtime/shared/defaults-separation.mjs +2 -14
  289. package/src/runtime/shared/delegated-approval-host.mjs +103 -11
  290. package/src/runtime/shared/developer-options.mjs +32 -1
  291. package/src/runtime/shared/err-text.mjs +24 -15
  292. package/src/runtime/shared/file-permissions.d.mts +0 -8
  293. package/src/runtime/shared/file-permissions.mjs +0 -11
  294. package/src/runtime/shared/git-direct.test-support.mjs +19 -0
  295. package/src/runtime/shared/google-oauth-client.generated.json +4 -0
  296. package/src/runtime/shared/google-oauth-client.mjs +34 -9
  297. package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
  298. package/src/runtime/shared/heartbeat-interval.mjs +19 -0
  299. package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
  300. package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
  301. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
  302. package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
  303. package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
  304. package/src/runtime/shared/llm/well-formed.mjs +66 -0
  305. package/src/runtime/shared/mixy-presence.mjs +22 -0
  306. package/src/runtime/shared/orchestration.d.mts +2 -0
  307. package/src/runtime/shared/pg-schema-db.mjs +27 -16
  308. package/src/runtime/shared/profile-config.cjs +1 -1
  309. package/src/runtime/shared/prompt-origin.d.mts +4 -0
  310. package/src/runtime/shared/prompt-origin.mjs +21 -0
  311. package/src/runtime/shared/provider-accounts.mjs +231 -59
  312. package/src/runtime/shared/provider-api-key.mjs +19 -8
  313. package/src/runtime/shared/provider-display-name.mjs +29 -0
  314. package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
  315. package/src/runtime/shared/routine-trigger.d.mts +2 -0
  316. package/src/runtime/shared/routine-trigger.mjs +52 -0
  317. package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
  318. package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
  319. package/src/runtime/shared/session-activity-signal.mjs +34 -1
  320. package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
  321. package/src/runtime/shared/session-sidebar-host.mjs +7 -3
  322. package/src/runtime/shared/session-turn-prelude.mjs +18 -0
  323. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  324. package/src/runtime/shared/tool-result-summary.mjs +1 -14
  325. package/src/runtime/shared/transcript-metadata.mjs +38 -0
  326. package/src/runtime/shared/user-data-guard.mjs +30 -2
  327. package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
  328. package/src/runtime/shared/worktrees/test-support.mjs +9 -4
  329. package/src/runtime/terminal-bridge/client.mjs +10 -1
  330. package/src/runtime/visualize-bridge/client.mjs +27 -8
  331. package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
  332. package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
  333. package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
  334. package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
  335. package/src/session-runtime/agent-home-delivery.mjs +486 -179
  336. package/src/session-runtime/agent-room-delivery.mjs +28 -1
  337. package/src/session-runtime/agent-task-sessions.mjs +561 -199
  338. package/src/session-runtime/boot/apis.mjs +9 -0
  339. package/src/session-runtime/boot/begin.mjs +3 -2
  340. package/src/session-runtime/boot/infrastructure.mjs +4 -0
  341. package/src/session-runtime/boot/providers.mjs +3 -0
  342. package/src/session-runtime/boot/tools.mjs +8 -1
  343. package/src/session-runtime/bot-chain.mjs +32 -0
  344. package/src/session-runtime/bot-status.mjs +7 -4
  345. package/src/session-runtime/channel-config-api.mjs +63 -17
  346. package/src/session-runtime/config-lifecycle.mjs +6 -0
  347. package/src/session-runtime/connector-merge-migration.mjs +305 -0
  348. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
  349. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
  350. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
  351. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
  352. package/src/session-runtime/internal-tool-executor.mjs +4 -0
  353. package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
  354. package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
  355. package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
  356. package/src/session-runtime/lifecycle/teardown.mjs +23 -5
  357. package/src/session-runtime/mcp-glue/server-catalog.mjs +61 -3
  358. package/src/session-runtime/mcp-oauth-login.mjs +5 -3
  359. package/src/session-runtime/mixy-heartbeat.mjs +927 -0
  360. package/src/session-runtime/model-route/route-tuning.mjs +10 -6
  361. package/src/session-runtime/notification-bus.mjs +31 -117
  362. package/src/session-runtime/notification-completion-queue.mjs +54 -0
  363. package/src/session-runtime/notification-listeners.mjs +76 -0
  364. package/src/session-runtime/owned-automation-run.mjs +35 -13
  365. package/src/session-runtime/prewarm/channel-start.mjs +3 -7
  366. package/src/session-runtime/provider-auth/login.mjs +7 -0
  367. package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
  368. package/src/session-runtime/resource-mcp-api.mjs +143 -224
  369. package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
  370. package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
  371. package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
  372. package/src/session-runtime/resource-mcp-servers.mjs +78 -0
  373. package/src/session-runtime/resource-mcp-store.mjs +49 -0
  374. package/src/session-runtime/routine-home-turn.mjs +33 -6
  375. package/src/session-runtime/routine-owner.mjs +40 -9
  376. package/src/session-runtime/schedule-session-run.mjs +7 -3
  377. package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
  378. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
  379. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
  380. package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
  381. package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
  382. package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
  383. package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
  384. package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
  385. package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
  386. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
  387. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
  388. package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
  389. package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
  390. package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
  391. package/src/session-runtime/services/channel-admin.mjs +73 -31
  392. package/src/session-runtime/services/channel-session-router.mjs +4 -2
  393. package/src/session-runtime/services/channel-worker.mjs +1 -1
  394. package/src/session-runtime/services/provider-admin.mjs +128 -25
  395. package/src/session-runtime/services/schedule-access.mjs +14 -0
  396. package/src/session-runtime/services/seeds.mjs +0 -28
  397. package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
  398. package/src/session-runtime/session-compaction-sync.mjs +27 -0
  399. package/src/session-runtime/session-create/session-options.mjs +8 -4
  400. package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
  401. package/src/session-runtime/settings-compaction-api.mjs +2 -40
  402. package/src/session-runtime/settings-system-api.mjs +28 -1
  403. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
  404. package/src/session-runtime/setup-tool/executor.mjs +187 -29
  405. package/src/session-runtime/setup-tool/extended-actions.mjs +33 -2
  406. package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
  407. package/src/session-runtime/setup-tool/settings-contract.mjs +68 -6
  408. package/src/session-runtime/setup-tool/tool-defs.mjs +92 -6
  409. package/src/session-runtime/task-session-route.mjs +99 -0
  410. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
  411. package/src/session-runtime/tool-policy/policy-stage.mjs +21 -4
  412. package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
  413. package/src/session-runtime/tool-surface.mjs +4 -0
  414. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  415. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
  416. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
  417. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
  418. package/src/session-runtime/workspace/transitions.mjs +10 -2
  419. package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
  420. package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
  421. package/src/standalone/channel-transport/client-registry.mjs +24 -163
  422. package/src/standalone/channel-transport.mjs +1 -1
  423. package/src/standalone/daemon-channels-loader.mjs +10 -8
  424. package/src/standalone/daemon-session-control/list-page.mjs +72 -0
  425. package/src/standalone/daemon-session-control/request.mjs +51 -0
  426. package/src/standalone/daemon-session-control/room-host.mjs +57 -0
  427. package/src/standalone/daemon-session-control/route-control.mjs +48 -0
  428. package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
  429. package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
  430. package/src/standalone/daemon-session-control.mjs +161 -157
  431. package/src/standalone/daemon.mjs +33 -2
  432. package/src/standalone/session-client.mjs +7 -3
  433. package/src/standalone/session-protocol.mjs +10 -0
  434. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
  435. package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
  436. package/src/standalone/session-service/quota-resume.mjs +3 -0
  437. package/src/standalone/session-service/retention/busy.mjs +65 -1
  438. package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
  439. package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
  440. package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
  441. package/src/standalone/session-service.mjs +13 -0
  442. package/src/standalone/session-tool-output.mjs +21 -10
  443. package/src/tui/app/model-options.mjs +4 -27
  444. package/src/tui/dist/index.mjs +81 -65
  445. package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
  446. package/src/tui/session/initial-state.mjs +3 -0
  447. package/src/tui/session/notice-surface.mjs +23 -1
  448. package/src/tui/session/queue-helpers.mjs +3 -42
  449. package/src/tui/session/session-api/integrations.mjs +1 -0
  450. package/src/tui/session/session-api/lifecycle.mjs +8 -0
  451. package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
  452. package/src/tui/session/session-api/routes-write.mjs +5 -1
  453. package/src/tui/session/session-api/routes.mjs +1 -0
  454. package/src/tui/session/session-api/settings.mjs +30 -2
  455. package/src/tui/session/session-flow/auto-clear.mjs +4 -33
  456. package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
  457. package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
  458. package/src/tui/session/session-flow/drain-retry.mjs +35 -0
  459. package/src/tui/session/session-flow/drain.mjs +118 -149
  460. package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
  461. package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
  462. package/src/tui/session/tool-approval-delegation.mjs +64 -0
  463. package/src/tui/session/tool-approval-request.mjs +39 -0
  464. package/src/tui/session/tool-approval-settle.mjs +62 -0
  465. package/src/tui/session/tool-approval.mjs +69 -115
  466. package/src/tui/session/tui-steering-persist.mjs +8 -1
  467. package/src/tui/session/turn-stream.mjs +36 -3
  468. package/src/tui/session/turn.mjs +23 -2
  469. package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
  470. package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
  471. package/scripts/code-graph-description-contract.mjs +0 -188
  472. package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
@@ -4,7 +4,8 @@
4
4
  * flattening, session activity timestamps, and batch merging.
5
5
  */
6
6
  import { agentJobResultText, parseAgentJob, parseSyntheticAgentMessage } from './agent-envelope.mjs';
7
- import { attachmentTextForPart, isAttachmentReference } from '../../runtime/attachments/store.mjs';
7
+ import { isAttachmentReference } from '../../runtime/attachments/store.mjs';
8
+ import { promptContentText, sessionActivityTimestamp } from '../../runtime/shared/idle-auto-clear-gate.mjs';
8
9
  import { recognisedSlashToken } from '../app/slash-commands.mjs';
9
10
 
10
11
  const QUEUE_PRIORITY = { now: 0, next: 1, later: 2 };
@@ -82,47 +83,7 @@ export function notificationDisplayText(text) {
82
83
  return firstQueueLine(synthetic?.result || result || text) || 'agent notification';
83
84
  }
84
85
 
85
- export function promptContentText(content) {
86
- if (typeof content === 'string') return content;
87
- if (Array.isArray(content)) {
88
- return content
89
- .map((part) => {
90
- if (typeof part === 'string') return part;
91
- if (part?.type === 'text') return isAttachmentReference(part) ? attachmentTextForPart(part) : part.text || '';
92
- if (part?.type === 'image') return '[Image]';
93
- if (part?.type === 'file') return '[File]';
94
- return part?.text || '';
95
- })
96
- .filter(Boolean)
97
- .join('\n');
98
- }
99
- return String(content ?? '');
100
- }
101
-
102
- function timestampMs(value) {
103
- if (value == null || value === '') return 0;
104
- const n = Number(value);
105
- if (Number.isFinite(n) && n > 0) return n;
106
- const parsed = Date.parse(String(value));
107
- return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
108
- }
109
-
110
- function hasModelVisibleConversation(session) {
111
- const messages = Array.isArray(session?.messages) ? session.messages : [];
112
- return messages.some((message) => {
113
- const role = message?.role;
114
- if (role !== 'user' && role !== 'assistant' && role !== 'tool') return false;
115
- const text = promptContentText(message.content).trim();
116
- if (role === 'user' && text.startsWith('<system-reminder>')) return false;
117
- if (role === 'assistant' && text === '.' && !Array.isArray(message.toolCalls)) return false;
118
- return !!text || role === 'assistant' || role === 'tool';
119
- });
120
- }
121
-
122
- export function sessionActivityTimestamp(session, fallback = 0) {
123
- if (!hasModelVisibleConversation(session)) return 0;
124
- return timestampMs(session?.lastUsedAt) || timestampMs(session?.updatedAt) || timestampMs(fallback);
125
- }
86
+ export { promptContentText, sessionActivityTimestamp };
126
87
 
127
88
  export function promptDisplayText(content, options = {}) {
128
89
  if (typeof options.displayText === 'string' && options.displayText.trim()) return options.displayText;
@@ -138,6 +138,7 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
138
138
  (input) => runtime.saveCustomProvider(input),
139
139
  (result) => `custom provider saved: ${result.id}`
140
140
  ),
141
+ saveCustomProviderKey: (id, secret) => runtime.saveCustomProviderKey(id, secret),
141
142
  updateCustomProviderModel: (id, modelId, patch) => runtime.updateCustomProviderModel(id, modelId, patch),
142
143
  setModelPreferences: (provider, changes) => runtime.setModelPreferences(provider, changes),
143
144
  removeCustomProvider: async (id) => {
@@ -81,6 +81,14 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
81
81
  pushNotice,
82
82
  removeNotice,
83
83
  setProgressHint,
84
+ // A bot's emoji reactions on a user message (message-reactions.mjs): its
85
+ // live row shows them at once; false when the live rows do not hold it.
86
+ setMessageReactions: (messageId, reactions) => {
87
+ const row = bag
88
+ .getState()
89
+ .items.findLast((item) => item?.kind === 'user' && messageId && item.messageId === messageId);
90
+ return row ? bag.patchItem(row.id, { reactions: Array.isArray(reactions) ? reactions : [] }) : false;
91
+ },
84
92
  ...createSessionResetActions(bag),
85
93
  listSessions: (options) => {
86
94
  return runtime.listSessions(options);
@@ -2,6 +2,16 @@
2
2
  * routes-agent-definitions.mjs — the session route surface's passthroughs to
3
3
  * the runtime's agent, workflow-pack, connector and lead-identity services.
4
4
  */
5
+
6
+ /** Mixy's status with `exists`, the one rule (mixy-presence.mjs) the desktop
7
+ * answers from (main/mixy-first.ts). null when her routines cannot be read:
8
+ * the status still serves readers of her name. */
9
+ async function withMixyExists(status) {
10
+ if (!status || typeof status !== 'object') return status;
11
+ const { readMixyExists } = await import('../../../session-runtime/routine-owner.mjs');
12
+ return { ...status, exists: await readMixyExists(status).catch(() => null) };
13
+ }
14
+
5
15
  export function createAgentDefinitionApi(runtime) {
6
16
  return {
7
17
  listAgents: () => {
@@ -53,8 +63,10 @@ export function createAgentDefinitionApi(runtime) {
53
63
  saveLeadPersona: async (text) => runtime.saveLeadPersona?.(text) ?? '',
54
64
  getLeadAgentBody: () => runtime.getLeadAgentBody?.() ?? '',
55
65
  saveLeadAgentBody: async (text) => runtime.saveLeadAgentBody?.(text) ?? '',
56
- getLeadStatus: () =>
57
- runtime.getLeadStatus?.() ?? { created: null, name: '', avatar: null, homeChatted: false, route: null },
66
+ getLeadStatus: async () =>
67
+ withMixyExists(
68
+ runtime.getLeadStatus?.() ?? { created: null, name: '', avatar: null, homeChatted: false, route: null }
69
+ ),
58
70
  getLeadHomeRoute: () => runtime.getLeadHomeRoute?.() ?? null,
59
71
  saveLeadIdentity: async (payload) => runtime.saveLeadIdentity?.(payload) ?? null,
60
72
  setLeadCreated: async (created, description) => runtime.setLeadCreated?.(created, description) ?? null,
@@ -54,14 +54,18 @@ const SESSION_ONLY_KEYS = new Set(['provider', 'model', 'effort', 'fast', 'autoE
54
54
  * the tuning, or both. Completed here, inside the serialized route write,
55
55
  * against the latest selected route — so a Fast-only change keeps the effort a
56
56
  * previous write selected. `unchanged` when it asks for nothing the selected
57
- * route does not already have.
57
+ * route does not already have and the session itself already runs that model
58
+ * (a fallback hop moves the session, not the selected route).
58
59
  */
59
60
  function completeSessionOnlyRequest(request, selected) {
60
61
  const named = Boolean(request.provider || request.model);
61
62
  const target = named ? request : { ...request, provider: selected.provider, model: selected.model };
62
63
  const sameModel = target.provider === selected.provider && target.model === selected.model;
63
64
  if (!sameModel) return { request: target, unchanged: false };
65
+ const sessionOnTarget =
66
+ !selected.sessionModel || (selected.sessionProvider === target.provider && selected.sessionModel === target.model);
64
67
  const unchanged =
68
+ sessionOnTarget &&
65
69
  Object.keys(request).every((key) => SESSION_ONLY_KEYS.has(key)) &&
66
70
  (request.effort === undefined || request.effort === selected.effort) &&
67
71
  (request.fast === undefined || request.fast === (selected.fast === true)) &&
@@ -128,6 +128,7 @@ export function createSessionRouteApi(bag) {
128
128
  return result;
129
129
  }),
130
130
  getOrchestrationMode: () => runtime.getOrchestrationMode(),
131
+ getConfiguredOrchestrationMode: () => runtime.getConfiguredOrchestrationMode(),
131
132
  setOrchestrationMode: withCommandLock(async (mode, options) => {
132
133
  const result = await runtime.setOrchestrationMode(mode, options);
133
134
  publishSessionSwitches(bag, { orchestrationModeSwitch: result?.orchestrationModeSwitch });
@@ -34,8 +34,8 @@ export function createSessionSettingsApi(bag) {
34
34
  // refused: another command's lock does not block a selection.
35
35
  setModel: async (m) => (await bag.setSessionRoute({ model: m })) !== false,
36
36
  setEffort: withCommandLock(
37
- async (value) => {
38
- await runtime.setEffort(value);
37
+ async (value, options) => {
38
+ await runtime.setEffort(value, options);
39
39
  set({ ...routeState() });
40
40
  return runtime.effort || 'auto';
41
41
  },
@@ -112,6 +112,34 @@ export function createSessionSettingsApi(bag) {
112
112
  setAiSessionTitles: withCommandLock(async (enabled) => {
113
113
  return await runtime.setAiSessionTitles?.(enabled);
114
114
  }),
115
+ getCacheWarmingSettings: () => {
116
+ return runtime.getCacheWarmingSettings?.() || { enabled: true };
117
+ },
118
+ setCacheWarmingEnabled: withCommandLock(async (enabled) => {
119
+ return await runtime.setCacheWarmingEnabled?.(enabled);
120
+ }),
121
+ getHeartbeatSettings: () => {
122
+ return runtime.getHeartbeatSettings?.() || { heartbeat: true, intervalMinutes: 60 };
123
+ },
124
+ setHeartbeatEnabled: withCommandLock(async (enabled) => {
125
+ return await runtime.setHeartbeatEnabled?.(enabled);
126
+ }),
127
+ setHeartbeatInterval: withCommandLock(async (minutes) => {
128
+ return await runtime.setHeartbeatInterval?.(minutes);
129
+ }),
130
+ // The desktop app reports the user's latest in-app input time: Mixy's
131
+ // heartbeat waits for 30 quiet minutes (mixy-heartbeat.mjs noteUserInput).
132
+ noteUserInput: async (at) => {
133
+ const { noteUserInput } = await import('../../../session-runtime/mixy-heartbeat.mjs');
134
+ noteUserInput(at);
135
+ return { ok: true };
136
+ },
137
+ getReactionSettings: () => {
138
+ return runtime.getReactionSettings?.() || { reactions: true };
139
+ },
140
+ setReactionsEnabled: withCommandLock(async (enabled) => {
141
+ return await runtime.setReactionsEnabled?.(enabled);
142
+ }),
115
143
  getLeadAppearance: () => {
116
144
  return runtime.getLeadAppearance?.() || { avatar: null };
117
145
  },
@@ -4,7 +4,7 @@
4
4
  * cleared-session UI once the active turn settles.
5
5
  */
6
6
  import { presentErrorText } from '../../../runtime/shared/err-text.mjs';
7
- import { sessionActivityTimestamp } from '../queue-helpers.mjs';
7
+ import { idleAutoClearDue, sessionActivityTimestamp } from '../../../runtime/shared/idle-auto-clear-gate.mjs';
8
8
  import { archiveItemsForCompaction, compactionArchivedRows } from '../compaction-view.mjs';
9
9
 
10
10
  // Upper bound on the awaited idle compaction. Without a bound a stalled
@@ -17,29 +17,6 @@ import { archiveItemsForCompaction, compactionArchivedRows } from '../compaction
17
17
  const AUTO_CLEAR_COMPACT_TIMEOUT_MS = 60_000;
18
18
  const LATE_COMPLETION_NOTICE = 'auto-clear completed late; compacted conversation retained';
19
19
 
20
- // A zero is often an unavailable/stale meter field, not an authoritative
21
- // measurement. Do not let it mask the sibling live estimate.
22
- function contextUsageBelowThreshold(runtime, minContextPercent) {
23
- if (!(minContextPercent > 0)) return false;
24
- const status = runtime.contextStatus?.() || null;
25
- const usedTokens = Math.max(
26
- 0,
27
- Number(status?.usedTokens) || 0,
28
- Number(status?.currentEstimatedTokens) || 0,
29
- Number(status?.compaction?.currentEstimatedTokens) || 0
30
- );
31
- const triggerTokens = Number(
32
- status?.compaction?.triggerTokens ||
33
- status?.compaction?.autoCompactTokenLimit ||
34
- runtime.session?.autoCompactTokenLimit ||
35
- 0
36
- );
37
- if (!Number.isFinite(usedTokens) || !Number.isFinite(triggerTokens) || !(usedTokens > 0 && triggerTokens > 0)) {
38
- return true;
39
- }
40
- return (usedTokens / triggerTokens) * 100 < minContextPercent;
41
- }
42
-
43
20
  export function createAutoClearOps(bag, { reset, kickDrain }) {
44
21
  const {
45
22
  runtime,
@@ -140,15 +117,9 @@ export function createAutoClearOps(bag, { reset, kickDrain }) {
140
117
  const cfg = autoClearState();
141
118
  const now = Date.now();
142
119
  const activityAt = sessionActivityTimestamp(runtime.session, flags.lastUserActivityAt);
143
- const idleMs = activityAt ? now - activityAt : 0;
144
- const notIdle =
145
- !cfg.enabled ||
146
- getState().busy ||
147
- (!ignorePending && pending.length > 0) ||
148
- flags.autoClearRunning ||
149
- flags.autoClearInFlight ||
150
- idleMs < cfg.idleMs;
151
- if (notIdle || contextUsageBelowThreshold(runtime, Number(cfg.minContextPercent ?? 10))) {
120
+ const blocked =
121
+ getState().busy || (!ignorePending && pending.length > 0) || flags.autoClearRunning || flags.autoClearInFlight;
122
+ if (blocked || !idleAutoClearDue({ cfg, activityAt, at: now, runtime })) {
152
123
  if (!activityAt) flags.lastUserActivityAt = now;
153
124
  return false;
154
125
  }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * src/tui/session/session-flow/drain-closed-queue.mjs - settling the queue of a
3
+ * session whose canonical close completed (drain.mjs admission `terminal`).
4
+ */
5
+ import { dropTuiSteeringPersist } from '../tui-steering-persist.mjs';
6
+
7
+ export function createClosedQueueSettler({
8
+ pending,
9
+ pendingNotificationKeys,
10
+ clearBlockedDrainRetry,
11
+ queue,
12
+ steering,
13
+ submissions,
14
+ }) {
15
+ // Canonical close settled: nothing queued can ever run. Every accepted
16
+ // submission is settled explicitly (rejected), never silently dropped, and
17
+ // its durable steering mirror is released so a restart cannot resurrect it
18
+ // into the closed conversation.
19
+ return function settleClosedQueue() {
20
+ const entries = pending.splice(0);
21
+ pendingNotificationKeys.clear();
22
+ clearBlockedDrainRetry();
23
+ if (entries.length === 0) return;
24
+ queue.removeQueuedEntries(entries);
25
+ const mirrored = entries.filter((entry) => steering.shouldMirrorSteeringEntry(entry) && entry.steeringPersistId);
26
+ if (mirrored.length > 0) {
27
+ void Promise.resolve(dropTuiSteeringPersist(steering.leadSessionId(), mirrored)).catch(() => {});
28
+ }
29
+ for (const entry of entries) {
30
+ if (entry.id) submissions.forget(entry.id);
31
+ try {
32
+ entry.onSettled?.({ status: 'rejected', reason: 'session-closed', result: null, session: null });
33
+ } catch {
34
+ // A throwing callback must not leave the remaining entries unsettled.
35
+ }
36
+ }
37
+ };
38
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * src/tui/session/session-flow/drain-enqueue.mjs - idempotent intake of the
3
+ * unified prompt queue (drain.mjs): admission fence, duplicate submissions,
4
+ * notification keys, task-wait wakes and the durable steering mirror.
5
+ */
6
+ import { isQueuedEntryEditable, isQueuedEntryVisible } from '../queue-helpers.mjs';
7
+ import { appendTuiSteeringPersist } from '../tui-steering-persist.mjs';
8
+
9
+ export function createEnqueue({
10
+ admission,
11
+ tuiDebug,
12
+ flags,
13
+ pending,
14
+ pendingNotificationKeys,
15
+ getState,
16
+ set,
17
+ flushEmitImmediate,
18
+ getRuntime,
19
+ queue,
20
+ steering,
21
+ submissions,
22
+ drain,
23
+ }) {
24
+ return function enqueue(text, options = {}) {
25
+ // Admission fence. While closing, only user prompts are accepted (retained
26
+ // so a failed close loses nothing); notification-driven/model-visible
27
+ // enqueues are refused. A closed session accepts nothing.
28
+ const state = admission();
29
+ const mode = options.mode || 'prompt';
30
+ if (state !== 'open' && (state === 'terminal' || mode !== 'prompt')) {
31
+ tuiDebug(`enqueue refused: session admission=${state} mode=${mode}`);
32
+ return false;
33
+ }
34
+ const submissionId = String(options.id || '').trim();
35
+ // Idempotent intake: a transport that re-sent this exact submission (its
36
+ // first attempt landed but the response was lost) must not double-post.
37
+ if (submissionId && submissions.has(submissionId)) {
38
+ tuiDebug(`prompt-duplicate id=${submissionId} ignored`);
39
+ // This is an idempotent success, not a rejected submit. Returning false
40
+ // makes Desktop restore and retry a message that is already queued.
41
+ return true;
42
+ }
43
+ const entry = queue.makeQueueEntry(text, options);
44
+ if (entry.mode === 'task-notification' && entry.key) {
45
+ if (pendingNotificationKeys.has(entry.key)) return false;
46
+ pendingNotificationKeys.add(entry.key);
47
+ }
48
+ submissions.remember(submissionId);
49
+ pending.push(entry);
50
+ // Typed input or a deliverable notification ends a passive task wait or
51
+ // shell hold so the next boundary hands it to the model now.
52
+ const wake = steering.taskWaitWakeForEntry(entry);
53
+ if (wake) {
54
+ try {
55
+ getRuntime()?.interruptTaskWait?.(wake, wake === 'notification' ? entry.execution?.id || null : null);
56
+ } catch {}
57
+ }
58
+ const needsDurableSteering =
59
+ (getState().busy || getState().commandBusy || flags.autoClearRunning || flags.quotaResumePending) &&
60
+ steering.shouldMirrorSteeringEntry(entry);
61
+ const persistence = needsDurableSteering ? appendTuiSteeringPersist(steering.leadSessionId(), entry) : null;
62
+ if (isQueuedEntryVisible(entry)) {
63
+ set({ queued: [...getState().queued, entry] });
64
+ if (isQueuedEntryEditable(entry)) flushEmitImmediate?.();
65
+ }
66
+ const queueAgeMs = Math.max(0, Date.now() - Number(entry.submittedAt || Date.now()));
67
+ tuiDebug(`prompt-queued id=${String(entry.id)} busy=${getState().busy ? 1 : 0} ageMs=${queueAgeMs}`);
68
+ if (getState().busy) tuiDebug(`busy-queue enqueue mode=${entry.mode} pending=${pending.length}`);
69
+ void drain();
70
+ if (options.awaitPersistence === true && persistence) {
71
+ return Promise.resolve(persistence).then((persisted) => {
72
+ if (persisted !== false) return true;
73
+ const index = pending.indexOf(entry);
74
+ // A turn already took the prompt while its durable mirror was being
75
+ // written: it was delivered, so rejecting it would hand the sender a
76
+ // copy of a message the model already has.
77
+ if (index < 0) return true;
78
+ pending.splice(index, 1);
79
+ queue.removeQueuedEntries([entry]);
80
+ if (submissionId) submissions.forget(submissionId);
81
+ return false;
82
+ });
83
+ }
84
+ return true;
85
+ };
86
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * src/tui/session/session-flow/drain-retry.mjs - the re-check timer of a drain
3
+ * that found a gate closed (drain.mjs). One timer at most, kept on
4
+ * `flags.blockedDrainRetryTimer`.
5
+ */
6
+
7
+ // Re-check cadence for a drain that found a gate closed. A gate is state, not
8
+ // an event: the queue re-reads it instead of trusting that whoever closes it
9
+ // will remember to kick the queue on the way out. Both timers exist only while
10
+ // the queue actually holds work, so an idle session never polls.
11
+ const BLOCKED_DRAIN_RETRY_MS = 50;
12
+ // Session commands (setModel/newSession/resume/auto-clear) release in seconds;
13
+ // an active turn can run for many minutes, so its gate is re-read coarsely.
14
+ export const ACTIVE_TURN_RECHECK_MS = 2_000;
15
+
16
+ export function createBlockedDrainRetry({ flags, pending, drain }) {
17
+ function scheduleBlockedDrainRetry(delayMs = BLOCKED_DRAIN_RETRY_MS) {
18
+ if (pending.length === 0 || flags.disposed) return;
19
+ if (flags.blockedDrainRetryTimer) return;
20
+ const timer = setTimeout(() => {
21
+ flags.blockedDrainRetryTimer = null;
22
+ if (pending.length > 0) void drain();
23
+ }, delayMs);
24
+ if (typeof timer.unref === 'function') timer.unref();
25
+ flags.blockedDrainRetryTimer = timer;
26
+ }
27
+
28
+ function clearBlockedDrainRetry() {
29
+ if (!flags.blockedDrainRetryTimer) return;
30
+ clearTimeout(flags.blockedDrainRetryTimer);
31
+ flags.blockedDrainRetryTimer = null;
32
+ }
33
+
34
+ return { scheduleBlockedDrainRetry, clearBlockedDrainRetry };
35
+ }