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
@@ -57,7 +57,7 @@ function* armedScheduleFires(scheduler) {
57
57
  const fireAt = cronTaskNextFireAt(task);
58
58
  if (fireAt !== null) yield { name, fireAt, kind: 'cron' };
59
59
  }
60
- const defs = [...(scheduler.nonInteractive || []), ...(scheduler.interactive || [])];
60
+ const defs = scheduler.schedules || [];
61
61
  for (const name of (scheduler.oneShotTimers || new Map()).keys()) {
62
62
  if (scheduler.shouldSkip?.(name)) continue;
63
63
  const def = defs.find((s) => s.name === name);
@@ -1,8 +1,9 @@
1
1
  // Worker/HTTP runtime-lifecycle dispatch (activate_channel_bridge /
2
- // reload_config). Channel messaging — forwarder, transcript binding, typing —
3
- // is deleted with Discord/Telegram; only the automation lifecycle remains.
2
+ // reload_config). Only the automation lifecycle is dispatched here.
4
3
  // Lifecycle functions are threaded in as a bag of lazy getters so the module
5
4
  // reads the live file-level references at call time.
5
+ import { scheduleErrorFields } from './schedule-errors.mjs';
6
+
6
7
  function createToolDispatch({ isChannelsDegraded, lifecycle }) {
7
8
  const {
8
9
  getChannelBridgeActive,
@@ -13,6 +14,7 @@ function createToolDispatch({ isChannelsDegraded, lifecycle }) {
13
14
  startChannelBridge,
14
15
  stopOwnedRuntime,
15
16
  reloadRuntimeConfig,
17
+ renameSchedule,
16
18
  } = lifecycle;
17
19
 
18
20
  async function handleToolCall(name, args, _signal) {
@@ -82,6 +84,14 @@ function createToolDispatch({ isChannelsDegraded, lifecycle }) {
82
84
  };
83
85
  break;
84
86
  }
87
+ // The scheduler's owner moves a schedule row only while no run of it
88
+ // can start or be in flight (Scheduler.renameLocked). Resolves the
89
+ // renamed row as JSON text; a refusal is an isError result.
90
+ case 'rename_schedule': {
91
+ const saved = await renameSchedule(args.name, args.def, { timingChanged: args.timingChanged === true });
92
+ result = { content: [{ type: 'text', text: JSON.stringify(saved) }] };
93
+ break;
94
+ }
85
95
  // memory — handled by memory-service.mjs MCP
86
96
  default:
87
97
  result = {
@@ -94,6 +104,8 @@ function createToolDispatch({ isChannelsDegraded, lifecycle }) {
94
104
  result = {
95
105
  content: [{ type: 'text', text: `${name} failed: ${msg}` }],
96
106
  isError: true,
107
+ // A schedule refusal keeps its code and public name; nothing else crosses.
108
+ ...scheduleErrorFields(err),
97
109
  };
98
110
  }
99
111
  return result;
@@ -26,8 +26,7 @@ CREATE SCHEMA IF NOT EXISTS webhooks;
26
26
  CREATE TABLE IF NOT EXISTS webhooks.endpoints (
27
27
  name text PRIMARY KEY,
28
28
  description text NOT NULL DEFAULT '',
29
- channel_id text,
30
- role text NOT NULL DEFAULT '',
29
+ role text NOT NULL DEFAULT '',
31
30
  model text,
32
31
  parser text,
33
32
  secret text,
@@ -87,14 +86,13 @@ const getDb = createPgSchemaDb({
87
86
  // The stored payload itself is never projected here (readEndpointLastPayload
88
87
  // is its only read path); rows carry a presence flag.
89
88
  const ENDPOINT_COLS =
90
- 'name, description, channel_id, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, last_event_at, last_success_at, last_failed_at, last_skipped_at, consecutive_failures, result_delivery, (last_payload IS NOT NULL) AS has_last_payload, created_at, updated_at';
89
+ 'name, description, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, last_event_at, last_success_at, last_failed_at, last_skipped_at, consecutive_failures, result_delivery, (last_payload IS NOT NULL) AS has_last_payload, created_at, updated_at';
91
90
 
92
91
  function rowToEndpoint(row) {
93
92
  if (!row) return null;
94
93
  return {
95
94
  name: row.name,
96
95
  description: row.description,
97
- channelId: row.channel_id,
98
96
  parser: row.parser,
99
97
  cwd: row.cwd,
100
98
  attachments: row.attachments || null,
@@ -180,7 +178,6 @@ export async function upsertEndpoint(def, { dataDir } = {}) {
180
178
  const params = [
181
179
  def.name,
182
180
  def.description ?? '',
183
- def.channelId ?? null,
184
181
  '',
185
182
  def.parser ?? null,
186
183
  def.secret ?? null,
@@ -195,13 +192,12 @@ export async function upsertEndpoint(def, { dataDir } = {}) {
195
192
  // not the definition.
196
193
  const { rows } = await db.query(
197
194
  `INSERT INTO webhooks.endpoints
198
- (name, description, channel_id, role, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id)
199
- VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)
195
+ (name, description, role, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id)
196
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)
200
197
  ON CONFLICT (name) DO UPDATE SET
201
198
  owner_agent_id = EXCLUDED.owner_agent_id,
202
199
  description = EXCLUDED.description,
203
- channel_id = EXCLUDED.channel_id,
204
- role = EXCLUDED.role,
200
+ role = EXCLUDED.role,
205
201
  parser = EXCLUDED.parser,
206
202
  secret = EXCLUDED.secret,
207
203
  cwd = EXCLUDED.cwd,
@@ -102,7 +102,6 @@ export function runWorkerBootstrap({
102
102
  // Publish owner identity immediately so the SessionStart shim's
103
103
  // owner_lead_alive() sees a live owner and uses the full connect budget
104
104
  // instead of the 5s no-owner grace (fixes missing recap/core on restart).
105
- // providerReady intentionally omitted — readiness stays gated until connect.
106
105
  try {
107
106
  refreshActiveInstance(instanceId);
108
107
  } catch (e) {
@@ -11,7 +11,6 @@ export function runWorkerIpc({
11
11
  clearServerPid,
12
12
  instanceId,
13
13
  statusState: _statusState,
14
- getProvider: _getProvider,
15
14
  getConfig: _getConfig,
16
15
  handleMemoryCallResponse,
17
16
  handleToolCall,
@@ -1,13 +1,13 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import { createRequire } from 'node:module';
4
- import { loadConfig, createProvider, DATA_DIR } from './config.mjs';
4
+ import { loadConfig, DATA_DIR } from './config.mjs';
5
5
  import { resolveVoiceRuntime } from './voice-runtime-fetcher.mjs';
6
6
  import { whisperThreadCount } from './voice-transcription.mjs';
7
7
  import { ensureReady, stopVoiceWhisperServer } from './whisper-server.mjs';
8
8
  import { ensurePrivateRuntimeRoot, resolveRuntimeRoot } from '../../shared/runtime-root.mjs';
9
9
  import { Scheduler } from './scheduler.mjs';
10
- import { hasPending as dispatchHasPending } from '../../agent/orchestrator/dispatch-persist.mjs';
10
+ import { renameSchedule as renameScheduleRow } from './schedules-db.mjs';
11
11
  import { stripSoftWarns } from '../../agent/orchestrator/tool-loop-guard.mjs';
12
12
  import { JsonStateFile } from './state-file.mjs';
13
13
  import { writeJsonAtomicSync } from '../../shared/atomic-file.mjs';
@@ -93,7 +93,6 @@ if (isMixdogDebug()) {
93
93
  );
94
94
  }
95
95
  let config = await loadConfig();
96
- let provider = createProvider(config);
97
96
  const INSTANCE_ID = makeInstanceId();
98
97
  const TERMINAL_LEAD_PID = getTerminalLeadPid();
99
98
  runWorkerBootstrap({
@@ -128,22 +127,13 @@ let _reloadDebounce = null;
128
127
  const STATUS_FILE = getStatusPath(INSTANCE_ID);
129
128
  const statusState = new JsonStateFile(STATUS_FILE, {});
130
129
  statusState.ensure();
131
- const scheduler = new Scheduler(config.nonInteractive ?? [], config.interactive ?? []);
130
+ const scheduler = new Scheduler(config.schedules ?? []);
132
131
  // A schedule fire is a turn in its owner bot's chat; the runner belongs to the
133
132
  // session-runtime layer, so this worker entry injects it (lazy, like webhooks).
134
133
  scheduler.setScheduleRunner(async (schedule, opts) => {
135
134
  const { runScheduleSession } = await import('../../../session-runtime/schedule-session-run.mjs');
136
135
  return runScheduleSession(schedule, opts);
137
136
  });
138
- // Register the pending-dispatch probe so the scheduler treats an in-flight
139
- // bridge dispatch as "active" regardless of user-inbound silence.
140
- scheduler.setPendingCheck(() => {
141
- try {
142
- return dispatchHasPending(DATA_DIR);
143
- } catch {
144
- return false;
145
- }
146
- });
147
137
  let webhookServer = null;
148
138
  let eventPipeline = null;
149
139
  let bridgeRuntimeConnected = false;
@@ -157,10 +147,6 @@ const { startAutomationRuntime, startOwnedRuntime, stopOwnedRuntime, reloadRunti
157
147
  setConfig: (v) => {
158
148
  config = v;
159
149
  },
160
- getProvider: () => provider,
161
- setProvider: (v) => {
162
- provider = v;
163
- },
164
150
  getBridgeRuntimeConnected: () => bridgeRuntimeConnected,
165
151
  setBridgeRuntimeConnected: (v) => {
166
152
  bridgeRuntimeConnected = v;
@@ -184,7 +170,7 @@ const { startAutomationRuntime, startOwnedRuntime, stopOwnedRuntime, reloadRunti
184
170
  wireWebhookHandlers,
185
171
  wireEventQueueHandlers,
186
172
  });
187
- function injectAndRecord(channelId, _name, content, options) {
173
+ function injectAndRecord(content, options) {
188
174
  // Strip soft-warn marker blocks (Tool-loop / Repeated-input / legacy
189
175
  // Repeated-tool / Mixed-tool / Tool-budget / Same-file multi-chunk /
190
176
  // Bash file-lookup / Iteration / 0-match advisory) from anywhere in the
@@ -198,22 +184,14 @@ function injectAndRecord(channelId, _name, content, options) {
198
184
  const now = new Date();
199
185
  const timeLabel = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')} `;
200
186
  const sourceLabel = options?.type ? `${timeLabel}: ${options.type}` : timeLabel;
201
- const meta = { chat_id: channelId, user: sourceLabel, user_id: 'system', ts };
187
+ const meta = { user: sourceLabel, user_id: 'system', ts };
202
188
  if (options?.instruction) meta.instruction = options.instruction;
203
189
  if (options?.type) meta.type = options.type;
204
190
  // `silent_to_agent` — lifecycle status pings (worker/iter/started echoes)
205
- // must NOT land in Lead's context window. The channel relay that used to
206
- // surface them is retired, so silent pings are dropped entirely.
191
+ // must NOT land in Lead's context window, so silent pings are dropped.
207
192
  if (options?.silent_to_agent === true) return;
208
193
  sendNotifyToParent('notifications/claude/channel', { content, meta });
209
194
  }
210
- scheduler.setInjectHandler((channelId, name, content, options) => {
211
- injectAndRecord(channelId, name, content, options);
212
- });
213
- // Interactive schedule fires may only inject while this process
214
- // actually holds the live bridge seat; otherwise the scheduler falls back to
215
- // the visible-session run so the fire is never lost.
216
- scheduler.setInjectReadyCheck(() => bridgeRuntimeConnected && currentOwnerState().owned);
217
195
  function wireWebhookHandlers() {
218
196
  if (!webhookServer) return;
219
197
  webhookServer.setEventPipeline(eventPipeline);
@@ -236,8 +214,8 @@ function wireWebhookHandlers() {
236
214
  }
237
215
  function wireEventQueueHandlers(eventQueue) {
238
216
  if (!eventQueue) return;
239
- eventQueue.setInjectHandler((channelId, name, content, options) => {
240
- injectAndRecord(channelId, name, content, options);
217
+ eventQueue.setInjectHandler((_name, content, options) => {
218
+ injectAndRecord(content, options);
241
219
  });
242
220
  // Defensive ownership probe: the queue tick should only run in the active
243
221
  // owner process. Non-owner instances see bridgeRuntimeConnected=false and
@@ -261,9 +239,17 @@ const { handleToolCall } = createToolDispatch({
261
239
  },
262
240
  writeBridgeState,
263
241
  notifyRemoteAcquired,
264
- startChannelBridge: () => start({ messaging: true }),
242
+ startChannelBridge: () => start({ bridge: true }),
265
243
  stopOwnedRuntime,
266
244
  reloadRuntimeConfig,
245
+ // Rename and re-arm under one reservation: the scheduler is reloaded from
246
+ // the renamed row (timers and one-shots of the old name cleared) before
247
+ // the name is released for fires.
248
+ renameSchedule: (name, def, opts) =>
249
+ scheduler.renameLocked(name, () => renameScheduleRow(name, def, opts), {
250
+ newName: def.name,
251
+ reload: reloadRuntimeConfig,
252
+ }),
267
253
  },
268
254
  });
269
255
  function ensureConfigWatcher() {
@@ -279,7 +265,7 @@ function ensureConfigWatcher() {
279
265
  } catch {}
280
266
  }
281
267
  async function start(options = {}) {
282
- if (options?.messaging === false) {
268
+ if (options?.bridge === false) {
283
269
  channelBridgeActive = false;
284
270
  writeBridgeState(false);
285
271
  await startAutomationRuntime();
@@ -299,7 +285,7 @@ async function start(options = {}) {
299
285
  }
300
286
  // Hot-reload config on file change (schedules/webhooks/events).
301
287
  // Cross-process edits invalidate the raw config cache before the debounced
302
- // reload so both messaging and automation-only daemon modes stay current.
288
+ // reload so both bridge and automation-only daemon modes stay current.
303
289
  ensureConfigWatcher();
304
290
  // Pre-warm the whisper-server manager once at owner startup so the first
305
291
  // voice transcription does not pay cold-start cost. Non-blocking: failures
@@ -352,7 +338,6 @@ if (_isWorkerMode && process.send && process.env.MIXDOG_DAEMON_HOST !== '1') {
352
338
  clearServerPid,
353
339
  instanceId: INSTANCE_ID,
354
340
  statusState,
355
- getProvider: () => provider,
356
341
  getConfig: () => config,
357
342
  handleMemoryCallResponse,
358
343
  handleToolCall,
@@ -35,8 +35,13 @@ const ACTIONS = [
35
35
  'menu',
36
36
  'clipboard',
37
37
  'launch',
38
+ 'saved_login',
38
39
  ];
39
40
 
41
+ // Which value of a saved login saved_login types (the host checks the focused
42
+ // field's kind before typing it).
43
+ const SAVED_LOGIN_FIELDS = ['username', 'password'];
44
+
40
45
  const windowTarget = {
41
46
  window_id: {
42
47
  type: 'string',
@@ -347,6 +352,28 @@ export const COMPUTER_ACTION_CONTRACTS = [
347
352
  ['app']
348
353
  )
349
354
  ),
355
+ branch(
356
+ 'saved_login',
357
+ input(
358
+ {
359
+ ...windowTarget,
360
+ ...appTarget,
361
+ savedAccount: {
362
+ type: 'string',
363
+ minLength: 1,
364
+ description:
365
+ "Fallback sign-in in the user's own browser; prefer its existing session/SSO or Browser Use's saved sign-in. Saved login (username or masked label; a miss lists the site's labels) written after host checks into the focused field of a Chrome/Edge HTTPS page. The site receives it. A password is kept from you and its browser's pixels are withheld this turn, but a page that redisplays it can expose it, and other programs of the same Windows user are outside this protection; a username is not hidden. On refusal hand the secret to the user (ask_user secret, surface computer).",
366
+ },
367
+ field: {
368
+ type: 'string',
369
+ enum: SAVED_LOGIN_FIELDS,
370
+ description:
371
+ "username (text field) or password (password field). One-time codes, passkeys, security keys and app approvals are the user's step: ask_user takeover.",
372
+ },
373
+ },
374
+ ['savedAccount', 'field']
375
+ )
376
+ ),
350
377
  ];
351
378
 
352
379
  // A JSON Schema 2020-12 object root with no root combinator (Anthropic
@@ -396,7 +423,7 @@ for (const actionBranch of COMPUTER_ACTION_CONTRACTS) {
396
423
  // Actions that drive one exact window. They carry exactly one window target:
397
424
  // the exact window_id, or an app label the host resolves to one window and
398
425
  // refuses when it matches more than one.
399
- const WINDOW_TARGET_ACTIONS = new Set(['act', 'window', 'menu', 'verify']);
426
+ const WINDOW_TARGET_ACTIONS = new Set(['act', 'window', 'menu', 'verify', 'saved_login']);
400
427
  // The host command each window operation becomes; every other operation is a
401
428
  // window_state change carrying the operation as its state.
402
429
  const WINDOW_OPERATION_ACTIONS = Object.freeze({
@@ -564,6 +591,11 @@ function launchError(input) {
564
591
  return null;
565
592
  }
566
593
 
594
+ function savedLoginError(input) {
595
+ if (!String(input.savedAccount || '').trim()) return 'Computer Use saved_login savedAccount must not be empty';
596
+ return null;
597
+ }
598
+
567
599
  function listError(input) {
568
600
  if (hasOwn(input, 'limit') && input.kind !== 'history') {
569
601
  return 'Computer Use list limit applies to kind="history"';
@@ -584,6 +616,7 @@ const ACTION_RULES = {
584
616
  window: windowError,
585
617
  clipboard: clipboardError,
586
618
  launch: launchError,
619
+ saved_login: savedLoginError,
587
620
  };
588
621
 
589
622
  export function validateComputerToolArgs(rawArgs) {
@@ -686,6 +719,14 @@ export function toComputerHostCommand(rawArgs) {
686
719
  command.action = inputValue.operation === 'write' ? 'clipboard_write' : 'clipboard_read';
687
720
  delete command.operation;
688
721
  break;
722
+ case 'saved_login':
723
+ // Always foreground: the value goes to the field focused in the
724
+ // browser window the host verified, never through window messages.
725
+ command.action = 'fill_saved_login';
726
+ command.saved_account = inputValue.savedAccount;
727
+ command.delivery = 'foreground';
728
+ delete command.savedAccount;
729
+ break;
689
730
  default:
690
731
  command.action = args.action;
691
732
  }
@@ -29,6 +29,8 @@ action('input_recovery_state', nativeRead);
29
29
  action('input_idle_state', nativeRead);
30
30
  action('ocr_image', nativeRead);
31
31
  action('ocr_status', nativeRead);
32
+ // Host-internal: whether a saved-login owner's runtime process has ended.
33
+ action('process_fate', nativeRead);
32
34
  action('release_session', { retainNativeRefs: true });
33
35
  action('release_cursor_theme', { retainNativeRefs: true });
34
36
  // Handing held input, focus and pointer back changes no target's content, so a
@@ -98,8 +100,14 @@ for (const name of [
98
100
  });
99
101
  }
100
102
  action('clipboard_write', { foreground: true });
103
+ // A saved login written into the focused field of the user's browser window:
104
+ // an input bound to a fresh observation, always on the foreground lane, with no
105
+ // automatic capture (the reply never carries the field it filled).
106
+ action('fill_saved_login', { observationBound: true, foreground: true, policy: 'act' });
101
107
  action('sequence', { policy: 'act' });
102
- for (const name of ['execution_end', 'session_release', 'session_abort']) {
108
+ // turn_settle: the runtime's settlement of one agent turn (turn_id), which
109
+ // alone retires a saved-login fill's protection (desktop secret-input.ts).
110
+ for (const name of ['execution_end', 'session_release', 'session_abort', 'turn_settle']) {
103
111
  action(name, { lifecycle: true, observeOnly: true });
104
112
  }
105
113
  export const COMPUTER_ACTIONS = Object.freeze(catalogue);
@@ -25,6 +25,8 @@ import { MAX_COMPUTER_REQUEST_BYTES, readComputerBridgeJson, validateComputerRep
25
25
  import { computerActionHas } from './actions.mjs';
26
26
  import { linuxCaptureFallback, linuxComputerPreflight } from './linux-readiness.mjs';
27
27
  import { continuePendingComputerWork, isPendingComputerWork } from './pending-continuation.mjs';
28
+ import { randomUUID } from 'node:crypto';
29
+ import { request as httpRequest } from 'node:http';
28
30
 
29
31
  export { canonicalComputerResultText };
30
32
 
@@ -53,6 +55,18 @@ const pendingComputerSessionReleases = new Map();
53
55
  // explicit release, so shutdown needs the full set.
54
56
  const hostBoundComputerSessions = new Set();
55
57
  const activeComputerExecutions = new Set();
58
+ // Per session, the newest agent turn that sent a saved-login fill whose
59
+ // settlement the desktop has not yet accepted. Aborts never clear it.
60
+ const savedLoginTurns = new Map();
61
+ /** This runtime process as the owner of its saved-login fills: the desktop
62
+ * keeps a fill's protection until its turn settles or this owner is gone
63
+ * (apps/desktop/src/main/secret-input.ts SavedLoginTurn). */
64
+ export const SAVED_LOGIN_OWNER_ID = randomUUID();
65
+ // The owner connection: one held POST /owner (owner id and this process id)
66
+ // to the bridge it was opened on. A close only detaches it on the desktop;
67
+ // the desktop retires this owner early only when the OS proves this process
68
+ // ended. The socket never keeps the process alive.
69
+ let savedLoginOwner = null;
56
70
  const BRIDGE_UNAVAILABLE_MESSAGE =
57
71
  'computer use is unavailable; open the Mixdog desktop app and enable Computer Use in settings';
58
72
 
@@ -269,7 +283,15 @@ async function executeComputerToolInner(rawArgs, context, note) {
269
283
  command = fallback.command;
270
284
  note.text = fallback.note;
271
285
  }
272
- const encoded = JSON.stringify({ ...command, ...(sessionId ? { session_id: sessionId } : {}) });
286
+ // A saved-login fill names its agent turn: the desktop keeps the fill's
287
+ // protection until that turn's settlement (settleSavedLoginTurn).
288
+ const turnId = Number(context?.turnId) || 0;
289
+ const savedLoginTurn = command.action === 'fill_saved_login' && sessionId && turnId > 0 ? turnId : 0;
290
+ const encoded = JSON.stringify({
291
+ ...command,
292
+ ...(sessionId ? { session_id: sessionId } : {}),
293
+ ...(savedLoginTurn ? { turn_id: savedLoginTurn, runtime_id: SAVED_LOGIN_OWNER_ID } : {}),
294
+ });
273
295
  if (Buffer.byteLength(encoded) > MAX_COMPUTER_REQUEST_BYTES) {
274
296
  return computerErrorResult('Error: computer request exceeds byte limit; no input was dispatched');
275
297
  }
@@ -286,7 +308,14 @@ async function executeComputerToolInner(rawArgs, context, note) {
286
308
  }
287
309
  const releaseError = await awaitPendingSessionRelease(sessionId, args, context);
288
310
  if (releaseError) return releaseError;
311
+ if (savedLoginTurn) {
312
+ const ownerError = await savedLoginOwnerError(discovery, sessionId, args, context);
313
+ if (ownerError) return ownerError;
314
+ }
289
315
  trackComputerSession(sessionId, command);
316
+ // Recorded before the request leaves: the fill may arm its protection even
317
+ // when its reply is lost, so the turn's settlement is owed regardless.
318
+ if (savedLoginTurn) savedLoginTurns.set(sessionId, Math.max(savedLoginTurns.get(sessionId) || 0, savedLoginTurn));
290
319
  const posted = await postWithBridgeRecovery(discovery, command, encoded, sessionId, context);
291
320
  if (!posted.response) return posted;
292
321
  const { bridge, response } = posted;
@@ -362,7 +391,7 @@ async function settlePendingComputerWork(value, command, bridge, sessionId, cont
362
391
  }
363
392
  }
364
393
 
365
- async function sendComputerSessionControl(sessionId, action, timeoutMs) {
394
+ async function sendComputerSessionControl(sessionId, action, timeoutMs, extra = {}) {
366
395
  const discovery = readBridgeDiscovery(DISCOVERY_FILE);
367
396
  if (!discovery) return false;
368
397
  try {
@@ -371,6 +400,7 @@ async function sendComputerSessionControl(sessionId, action, timeoutMs) {
371
400
  {
372
401
  action,
373
402
  session_id: sessionId,
403
+ ...extra,
374
404
  },
375
405
  { timeoutMs }
376
406
  );
@@ -381,12 +411,40 @@ async function sendComputerSessionControl(sessionId, action, timeoutMs) {
381
411
  }
382
412
  }
383
413
 
414
+ /** Runtime-only, at request time: bind `requestId` to the exact window and
415
+ * field ref the agent named (desktop secret-input.ts bindComputerSecret).
416
+ * Answers 'bound' or 'no_field'; no desktop or an unknown answer is 'blocked'. */
417
+ export async function computerSecretBind(sessionId, requestId, { ref = '', windowId = '', signal } = {}) {
418
+ const discovery = readBridgeDiscovery(DISCOVERY_FILE);
419
+ if (!discovery || !sessionId || !requestId) return 'blocked';
420
+ try {
421
+ const response = await postComputerCommand(
422
+ discovery,
423
+ {
424
+ action: 'secret_bind',
425
+ session_id: String(sessionId),
426
+ request_id: String(requestId),
427
+ ref: String(ref),
428
+ window_id: String(windowId),
429
+ },
430
+ { signal }
431
+ );
432
+ const body = await readComputerBridgeJson(response);
433
+ const text = response.ok && body?.ok === true ? body.value?.text : '';
434
+ return ['bound', 'no_field'].includes(text) ? text : 'blocked';
435
+ } catch {
436
+ return 'blocked';
437
+ }
438
+ }
439
+
384
440
  /** Runtime-only: type the secret the user handed the desktop for `requestId`
385
- * into the focused field (or `ref`) once. The value never passes through
386
- * here; the host answers only whether it was typed. */
441
+ * into the window and field it was bound to (computerSecretBind) once. The
442
+ * value never passes through here; the host answers only the outcome
443
+ * ('entered', 'no_field', 'page_changed', 'blocked', 'expired'); no desktop
444
+ * or an unknown answer is 'blocked'. */
387
445
  export async function computerSecretInput(sessionId, requestId, { ref = '', windowId = '', signal } = {}) {
388
446
  const discovery = readBridgeDiscovery(DISCOVERY_FILE);
389
- if (!discovery || !sessionId || !requestId) return 'skipped';
447
+ if (!discovery || !sessionId || !requestId) return 'blocked';
390
448
  try {
391
449
  const response = await postComputerCommand(
392
450
  discovery,
@@ -400,9 +458,10 @@ export async function computerSecretInput(sessionId, requestId, { ref = '', wind
400
458
  { signal }
401
459
  );
402
460
  const body = await readComputerBridgeJson(response);
403
- return response.ok && body?.ok === true && body.value?.text === 'provided' ? 'provided' : 'skipped';
461
+ const text = response.ok && body?.ok === true ? body.value?.text : '';
462
+ return ['entered', 'no_field', 'page_changed', 'blocked', 'expired'].includes(text) ? text : 'blocked';
404
463
  } catch {
405
- return 'skipped';
464
+ return 'blocked';
406
465
  }
407
466
  }
408
467
 
@@ -423,12 +482,125 @@ async function abortComputerSession(sessionId) {
423
482
  * desktop back, keeping the warm worker and observation refs for a possible follow-up. */
424
483
  export async function endComputerExecution(sessionId) {
425
484
  const id = String(sessionId || '').trim();
426
- if (!id || !activeComputerExecutions.has(id)) return false;
485
+ if (!id) return false;
486
+ await settleSavedLoginTurn(id);
487
+ if (!activeComputerExecutions.has(id)) return false;
427
488
  const ended = await sendComputerSessionControl(id, 'execution_end', EXECUTION_END_TIMEOUT_MS);
428
489
  if (ended) activeComputerExecutions.delete(id);
429
490
  return ended;
430
491
  }
431
492
 
493
+ /** Agent-turn settlement for a session that filled a saved login: tell the
494
+ * desktop the turn is over so that fill's protection can retire. Separate
495
+ * from input cleanup and independent of any abort; a settlement the desktop
496
+ * did not accept stays owed and is sent again at the session's next one.
497
+ * `endedTurnId` is the turn that ended when the caller knows it (the
498
+ * session's terminal state); otherwise the newest owed turn is the one
499
+ * ending (the lead's turn settlement). */
500
+ async function settleSavedLoginTurn(sessionId, endedTurnId = 0) {
501
+ const owed = savedLoginTurns.get(sessionId);
502
+ if (!owed) return;
503
+ if (endedTurnId > 0 && owed > endedTurnId) return;
504
+ const accepted = await sendComputerSessionControl(sessionId, 'turn_settle', EXECUTION_END_TIMEOUT_MS, {
505
+ turn_id: owed,
506
+ runtime_id: SAVED_LOGIN_OWNER_ID,
507
+ });
508
+ if (accepted && savedLoginTurns.get(sessionId) === owed) savedLoginTurns.delete(sessionId);
509
+ }
510
+
511
+ /** A session's agent turn reached its terminal state (done, error or
512
+ * cancelled; manager/runtime-liveness.mjs, for lead and sub-agent sessions
513
+ * alike): settle its saved-login fills. */
514
+ export async function finishComputerTurn(sessionId, turnId) {
515
+ const id = String(sessionId || '').trim();
516
+ if (!id || !(Number(turnId) > 0)) return;
517
+ await settleSavedLoginTurn(id, Number(turnId));
518
+ }
519
+
520
+ // Returns the error result that ends a saved-login call whose owner connection
521
+ // is not attached, or null to proceed. Nothing was sent in any of these cases.
522
+ async function savedLoginOwnerError(discovery, sessionId, args, context) {
523
+ let attached;
524
+ try {
525
+ attached = await attachSavedLoginOwner(discovery, context.signal);
526
+ } catch (error) {
527
+ if (context.signal?.aborted) return cancelledComputerResult(sessionId, false);
528
+ return computerErrorResult(
529
+ formatComputerToolError(
530
+ `saved_login_unavailable: the desktop did not answer the owner attachment (${error.name}); no input was sent`,
531
+ args
532
+ )
533
+ );
534
+ }
535
+ if (attached) return null;
536
+ return computerErrorResult(
537
+ formatComputerToolError(
538
+ 'saved_login_unavailable: the desktop did not accept this runtime as the owner of its saved-login fills; no input was sent',
539
+ args
540
+ )
541
+ );
542
+ }
543
+
544
+ /** Open (or reuse) this runtime's owner connection to `discovery`'s bridge:
545
+ * true once the desktop answered it, false when it refused or is unreachable.
546
+ * The shared handshake is bounded by the bridge request timeout (rejecting
547
+ * with its TimeoutError and resetting the shared state); each caller's wait
548
+ * also ends on its own `signal` without closing the shared connection. */
549
+ function attachSavedLoginOwner(discovery, signal) {
550
+ const current = savedLoginOwner;
551
+ if (current && current.port === discovery.port && current.token === discovery.token) {
552
+ return waitForComputerRelease(current.attached, signal);
553
+ }
554
+ current?.request.destroy();
555
+ const owner = { port: discovery.port, token: discovery.token, request: null, attached: null };
556
+ owner.attached = new Promise((resolve, reject) => {
557
+ const body = JSON.stringify({ runtime_id: SAVED_LOGIN_OWNER_ID, pid: process.pid });
558
+ const handshake = AbortSignal.timeout(REQUEST_TIMEOUT_MS);
559
+ const forget = () => {
560
+ handshake.removeEventListener('abort', onHandshakeTimeout);
561
+ if (savedLoginOwner === owner) savedLoginOwner = null;
562
+ resolve(false);
563
+ };
564
+ // Rejects first, so the callers see the timeout; forgetting at once lets
565
+ // the next fill attach afresh instead of waiting on the closing socket.
566
+ function onHandshakeTimeout() {
567
+ reject(handshake.reason);
568
+ forget();
569
+ owner.request.destroy();
570
+ }
571
+ handshake.addEventListener('abort', onHandshakeTimeout, { once: true });
572
+ owner.request = httpRequest(
573
+ {
574
+ host: '127.0.0.1',
575
+ port: discovery.port,
576
+ path: '/owner',
577
+ method: 'POST',
578
+ agent: false,
579
+ headers: { ...computerCommandHeaders(discovery), 'content-length': Buffer.byteLength(body) },
580
+ },
581
+ (response) => {
582
+ response.once('close', forget);
583
+ response.once('error', forget);
584
+ if (response.statusCode !== 200) {
585
+ response.resume();
586
+ forget();
587
+ return;
588
+ }
589
+ response.once('data', () => {
590
+ handshake.removeEventListener('abort', onHandshakeTimeout);
591
+ resolve(true);
592
+ });
593
+ }
594
+ );
595
+ owner.request.once('socket', (socket) => socket.unref());
596
+ owner.request.once('error', forget);
597
+ owner.request.once('close', forget);
598
+ owner.request.end(body);
599
+ });
600
+ savedLoginOwner = owner;
601
+ return waitForComputerRelease(owner.attached, signal);
602
+ }
603
+
432
604
  function cancelDeferredComputerSessionRelease(sessionId) {
433
605
  const id = String(sessionId || '').trim();
434
606
  if (!id) return false;
@@ -74,13 +74,13 @@ export const COMPUTER_CORE_ACTION_SCHEMA = {
74
74
  text: {
75
75
  type: 'string',
76
76
  maxLength: 30_000,
77
- description: `Literal text; foreground cap ${MAX_COMPUTER_FOREGROUND_TEXT_CHARS} UTF-16 code units per action.`,
77
+ description: `Literal text; foreground cap ${MAX_COMPUTER_FOREGROUND_TEXT_CHARS} UTF-16 code units per action. Never a password or one-time code, even one shown on screen: saved_login or ask_user.`,
78
78
  },
79
79
  value: {
80
80
  type: 'string',
81
81
  maxLength: 30_000,
82
82
  description:
83
- 'set_value replacement for an element that advertises set_value; writes the control directly, without focus or keystrokes.',
83
+ 'set_value replacement for an element that advertises set_value; writes the control directly, without focus or keystrokes. Never a password or one-time code, even one shown on screen: saved_login or ask_user.',
84
84
  },
85
85
  keys: {
86
86
  type: 'string',