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
@@ -7,7 +7,6 @@ import {
7
7
  readClaudeCodeCurrentRoute,
8
8
  } from '../src/gateway/claude-current.mjs';
9
9
  import {
10
- normalizeClientHostPid,
11
10
  readLatestGatewayHostRoute,
12
11
  readGatewaySessionRoute,
13
12
  } from '../src/gateway/session-routes.mjs';
@@ -16,33 +15,13 @@ import {
16
15
  defaultEffectiveContextWindowPercent,
17
16
  } from '../src/gateway/route-meta.mjs';
18
17
  import { getModelMetadataSync } from '../../../runtime/agent/orchestrator/providers/model-catalog.mjs';
19
- import { resolveRuntimeRoot } from '../../../runtime/shared/runtime-root.mjs';
20
18
  import { withDefaultPresets } from '../../../runtime/agent/orchestrator/config-presets.mjs';
21
19
 
22
- function positiveInt(value) {
23
- const n = parseInt(String(value || ''), 10);
24
- return Number.isFinite(n) && n > 0 ? n : 0;
25
- }
26
-
27
20
  // Keep the last known OAuth usage snapshot visible while idle. Live refreshes
28
21
  // replace it when available, but a delayed/failed refresh must not make the
29
22
  // statusline usage segment disappear. Previous-launch snapshots stay hidden
30
23
  // during boot until the current process captures usage once.
31
24
  const STATUSLINE_PROCESS_STARTED_AT_MS = Date.now() - Math.floor((Number(process.uptime?.()) || 0) * 1000);
32
- function isPidAlive(pid) {
33
- const n = positiveInt(pid);
34
- if (!n) return false;
35
- try {
36
- process.kill(n, 0);
37
- return true;
38
- } catch (e) {
39
- return !!(e && e.code === 'EPERM');
40
- }
41
- }
42
-
43
- function runtimeRoot() {
44
- return resolveRuntimeRoot();
45
- }
46
25
 
47
26
  function claudeConfigDir() {
48
27
  return process.env.MIXDOG_CONFIG_DIR || path.join(os.homedir(), '.mixdog');
@@ -246,62 +225,11 @@ function routeContextMeta(provider, info = {}, inherited = {}) {
246
225
  };
247
226
  }
248
227
 
249
- // Test-only export of the route context-meta resolver for the auto-compact
250
- // limit migration smoke (scripts/compact-trigger-migration-smoke.mjs).
251
- export const _routeContextMeta = routeContextMeta;
252
-
253
- // Resolve the auto-compact limit displayed by loadGatewayStatus(). The active
254
- // value MUST be validated against the ACTIVE route's own boundary/window, never
255
- // configured?.contextWindow: the configured window can be larger than the
256
- // active window, so validating a stale active full-window value (== active
257
- // window) against the configured window would let it slip through as an
258
- // explicit limit. The configured route's limit (already sanitized by
259
- // routeContextMeta) is preferred when a configured route is present, but it
260
- // never validates a stale active value.
261
- function resolveStatusAutoCompactTokenLimit(configured, active = {}, lastCompact = null) {
262
- if (configured) {
263
- const c = num(configured.autoCompactTokenLimit, 0);
264
- return c > 0 ? c : null;
265
- }
266
- const activeBoundary = num(
267
- active?.gateway_context_window
268
- ?? active?.gateway_raw_context_window
269
- ?? lastCompact?.budgetWindow
270
- ?? lastCompact?.contextWindow,
271
- 0,
272
- );
273
- const raw = num(active?.gateway_auto_compact_token_limit, 0);
274
- if (!(raw > 0)) return null;
275
- if (activeBoundary > 0) return raw < activeBoundary ? raw : null;
276
- return raw;
277
- }
278
-
279
- // Test-only export of the status auto-compact-limit resolver.
280
- export const _resolveStatusAutoCompactTokenLimit = resolveStatusAutoCompactTokenLimit;
281
-
282
228
  export function compactBoundaryForStatus(routeInfo = {}, compact = null) {
283
229
  const n = compactBoundaryDenominator(routeInfo, compact);
284
230
  return n > 0 ? n : null;
285
231
  }
286
232
 
287
- function sessionIdFromTranscriptPath(transcriptPath) {
288
- const base = path.basename(String(transcriptPath || ''));
289
- return base.endsWith('.jsonl') ? base.slice(0, -6) : '';
290
- }
291
-
292
- function gatewaySessionStatusFileName(sessionId, clientHostPid = null) {
293
- const sid = cleanString(sessionId).replace(/[^0-9A-Za-z._-]/g, '');
294
- if (!sid) return null;
295
- const pid = normalizeClientHostPid(clientHostPid);
296
- return pid ? `${sid}--host-${pid}.json` : `${sid}.json`;
297
- }
298
-
299
- function gatewaySessionStatus(sessionId, clientHostPid = null) {
300
- const name = gatewaySessionStatusFileName(sessionId, clientHostPid);
301
- if (!name) return null;
302
- return readJson(path.join(runtimeRoot(), 'gateway-session-status', name));
303
- }
304
-
305
233
  function sessionRouteFor(gateway, sessionId, clientHostPid = null) {
306
234
  const sid = cleanString(sessionId);
307
235
  if (!sid) return { route: gateway, sessionScoped: false };
@@ -538,153 +466,7 @@ export function loadGatewayStatus(options = {}) {
538
466
  balance: null,
539
467
  routeSpend: null,
540
468
  } : null;
541
- const activeOverride = options.activeOverride && typeof options.activeOverride === 'object' ? options.activeOverride : null;
542
- const activeGlobal = activeOverride || readJson(path.join(runtimeRoot(), 'active-instance.json'));
543
- const currentClientHostPid = normalizeClientHostPid(options.clientHostPid);
544
- const sessionStatus = activeOverride || gatewaySessionStatus(options.sessionId, currentClientHostPid);
545
- const active = sessionStatus || activeGlobal;
546
- if (!active || !active.gateway_port || !active.gateway_provider || !active.gateway_model) return configuredStatus;
547
- const ownerPid = positiveInt(active.gateway_server_pid);
548
- if (ownerPid && !isPidAlive(ownerPid)) return configuredStatus;
549
- const updatedAt = num(active.gateway_updated_at, 0) || num(active.updatedAt, 0);
550
- if (updatedAt && Date.now() - updatedAt > 5 * 60_000) return configuredStatus;
551
- // Gate active-instance metrics on a positive ownership proof. The display
552
- // route itself always comes from the current session config (`configured`)
553
- // when present; active-instance only contributes live usage for that same
554
- // session/route, never model identity.
555
- const currentSessionId = cleanString(options.sessionId);
556
- const gatewayCcSessionMatch = currentSessionId && cleanString(active.gateway_cc_session_id) === currentSessionId;
557
- const activeClientHostPid = normalizeClientHostPid(active.gateway_client_host_pid ?? active.clientHostPid);
558
- const gatewayClientHostMatch = !currentClientHostPid || activeClientHostPid === currentClientHostPid;
559
- const gwTranscript = typeof active.gateway_transcript_path === 'string' && active.gateway_transcript_path || null;
560
- const currentTranscript = typeof activeGlobal?.transcriptPath === 'string' && activeGlobal.transcriptPath || null;
561
- const gatewayTranscriptMatch = currentSessionId
562
- ? sessionIdFromTranscriptPath(gwTranscript) === currentSessionId
563
- : !!(gwTranscript && currentTranscript && gwTranscript === currentTranscript);
564
- const activeTranscriptMatch = currentSessionId
565
- ? sessionIdFromTranscriptPath(currentTranscript) === currentSessionId
566
- : false;
567
- const transcriptMatch = gatewayCcSessionMatch || gatewayTranscriptMatch || (!gwTranscript && activeTranscriptMatch);
568
- const routeMatchesConfigured = configured
569
- ? configured.provider === active.gateway_provider && configured.model === active.gateway_model
570
- : true;
571
- const activeRouteBoundary = compactBoundaryForStatus({
572
- autoCompactTokenLimit: active.gateway_auto_compact_token_limit,
573
- contextWindow: active.gateway_context_window,
574
- rawContextWindow: active.gateway_raw_context_window,
575
- });
576
- const configuredRouteBoundary = configured ? compactBoundaryForStatus(configured) : null;
577
- const routeBoundaryMatchesConfigured = !configured
578
- || !configuredRouteBoundary
579
- || !activeRouteBoundary
580
- || configuredRouteBoundary === activeRouteBoundary;
581
- const metricsOwnCurrentSession = !!(sessionStatus || gatewayCcSessionMatch || gatewayTranscriptMatch || activeTranscriptMatch);
582
- const metricsMatch = gatewayClientHostMatch && metricsOwnCurrentSession && routeMatchesConfigured && routeBoundaryMatchesConfigured;
583
- // Strong ownership = this session's own status file or an explicit session/
584
- // transcript id match from the gateway advert. `activeTranscriptMatch` (the
585
- // global active-instance transcript merely naming the current session) is NOT
586
- // strong: right after /new the global record can already point at the new
587
- // session while its stored gateway metrics (context pct, last usage) still
588
- // belong to the previous one.
589
- const strongSessionOwnership = !!(sessionStatus || gatewayCcSessionMatch || gatewayTranscriptMatch);
590
- // A model switch can keep strong session ownership while the active gateway
591
- // advert still contains the previous route's lastUsage.compact. Do not let
592
- // that stale compact boundary override the configured/current route window.
593
- const lastUsage = gatewayClientHostMatch && strongSessionOwnership && routeMatchesConfigured && routeBoundaryMatchesConfigured && active.gateway_last_usage && typeof active.gateway_last_usage === 'object'
594
- ? active.gateway_last_usage
595
- : null;
596
- const rawLastCompact = lastUsage?.compact && typeof lastUsage.compact === 'object'
597
- ? lastUsage.compact
598
- : null;
599
- // A model/window switch updates the active route fields (context/raw window)
600
- // but can leave the PREVIOUS route's boundary inside gateway_last_usage.compact.
601
- // routeBoundaryMatchesConfigured only checks the active route fields, so that
602
- // stale compact telemetry would otherwise survive and, via compactBoundaryTokens,
603
- // resurrect the previous boundary in compactBoundaryForStatus below. Drop the
604
- // compact telemetry when its own implied boundary contradicts the active route
605
- // window.
606
- const lastCompactBoundary = rawLastCompact
607
- ? compactBoundaryForStatus({}, rawLastCompact)
608
- : null;
609
- const lastCompact = rawLastCompact
610
- && (!activeRouteBoundary || !lastCompactBoundary || lastCompactBoundary === activeRouteBoundary)
611
- ? rawLastCompact
612
- : null;
613
- const statusLastUsage = lastUsage
614
- ? {
615
- ...lastUsage,
616
- compact: lastCompact,
617
- }
618
- : null;
619
- const contextBoundary = compactBoundaryForStatus({
620
- autoCompactTokenLimit: active.gateway_auto_compact_token_limit,
621
- contextWindow: active.gateway_context_window,
622
- rawContextWindow: active.gateway_raw_context_window,
623
- }, lastCompact);
624
- const liveContextTokens = num(options.activeContextTokens, null);
625
- const compactRequestWithLiveTokens = lastUsage?.requestKind === 'compact' && liveContextTokens !== null;
626
- const overflowContextTokens = !compactRequestWithLiveTokens && lastCompact?.overflow === true
627
- ? Math.max(
628
- num(lastUsage?.promptTokens, 0),
629
- num(lastCompact?.beforeTokens, 0),
630
- num(lastCompact?.afterTokens, 0),
631
- num(contextBoundary, 0),
632
- )
633
- : null;
634
- const contextNumerator = liveContextTokens !== null && Number.isFinite(liveContextTokens)
635
- ? liveContextTokens
636
- : (overflowContextTokens ?? null);
637
- const recomputedContextUsedPct = pctOf(contextNumerator, contextBoundary);
638
- const activeQuotaWindows = metricsMatch && Array.isArray(active.gateway_quota_windows)
639
- ? active.gateway_quota_windows
640
- : [];
641
- const statusProvider = configured?.provider || active.gateway_provider;
642
- const statusProviderKind = configured?.providerKind
643
- || (routeMatchesConfigured ? cleanString(active.gateway_provider_kind) : '')
644
- || providerKind(statusProvider);
645
- // Sanitize the auto-compact limit before display: a stale boundary/window-
646
- // sized active.gateway_auto_compact_token_limit must not surface as an
647
- // explicit autoCompactTokenLimit (the runtime would read it as the trigger
648
- // and collapse the buffer). The active value must be validated against the
649
- // ACTIVE route's own boundary/window — NOT configured?.contextWindow. The
650
- // configured window can be larger than the active window, so using it would
651
- // let a stale active full-window value (== active window) slip through. Use
652
- // the active boundary (active context/raw window, or the lastCompact budget
653
- // when present) and null the active value when it is >= that boundary.
654
- const statusAutoCompactTokenLimit = resolveStatusAutoCompactTokenLimit(configured, active, lastCompact);
655
- const activeStatus = {
656
- provider: statusProvider,
657
- model: configured?.model || active.gateway_model,
658
- modelDisplay: configured?.modelDisplay
659
- || statuslineDisplayForModel(active.gateway_provider, active.gateway_model, {}, active.gateway_model_display)
660
- || active.gateway_model,
661
- effort: configured?.effort ?? active.gateway_effort ?? '',
662
- fast: configured?.fast ?? active.gateway_fast === true,
663
- contextWindow: configured?.contextWindow ?? num(active.gateway_context_window, null),
664
- rawContextWindow: configured?.rawContextWindow ?? num(active.gateway_raw_context_window, null),
665
- effectiveContextWindowPercent: configured?.effectiveContextWindowPercent ?? num(active.gateway_effective_context_window_percent, null),
666
- autoCompactTokenLimit: statusAutoCompactTokenLimit,
667
- // Live recompute (from the caller's own context tokens) may use the weaker
668
- // metricsMatch gate, but the STORED gateway_context_used_pct fallback needs
669
- // strong ownership — otherwise a fresh /new session with a not-yet-updated
670
- // active-instance record would keep showing the old session's context %.
671
- contextUsedPct: metricsMatch
672
- ? recomputedContextUsedPct ?? (strongSessionOwnership ? num(active.gateway_context_used_pct, null) : null)
673
- : null,
674
- lastUsage: statusLastUsage,
675
- quotaWindows: activeQuotaWindows.length ? activeQuotaWindows : (configuredStatus?.quotaWindows || []),
676
- // Provenance for monotonic hysteresis: live active-instance windows are
677
- // own-instance data timestamped by the advert's updatedAt; otherwise inherit
678
- // the shared-cache fallback's (unowned) asOf. Older/unowned snapshots must
679
- // not displace a value already rendered from newer/owned data.
680
- quotaWindowsAsOf: activeQuotaWindows.length ? (updatedAt || 0) : num(configuredStatus?.quotaWindowsAsOf, 0),
681
- quotaWindowsOwned: activeQuotaWindows.length ? metricsMatch : false,
682
- balance: metricsMatch && active.gateway_balance && typeof active.gateway_balance === 'object' ? active.gateway_balance : (configuredStatus?.balance || null),
683
- routeSpend: metricsMatch && active.gateway_route_spend && typeof active.gateway_route_spend === 'object' ? active.gateway_route_spend : (configuredStatus?.routeSpend || null),
684
- providerKind: statusProviderKind,
685
- };
686
- if (!configured) return activeStatus;
687
- return activeStatus;
469
+ return configuredStatus;
688
470
  }
689
471
 
690
472
  function isLocalEstimateWindow(window) {
@@ -307,10 +307,17 @@ function refreshUsageView() {
307
307
 
308
308
  // Bounded compaction: keep the newest MAX_USAGE_EVENTS lines. Runs in the
309
309
  // background under the store lock (appenders take it too, so no append is lost).
310
- let compactRunning = false;
311
- async function compactUsageStore(store) {
312
- if (compactRunning) return;
313
- compactRunning = true;
310
+ let compactRunning = null; // the compaction in flight
311
+ let compactTimer = null; // a compaction scheduled to run
312
+ let compactStore = null;
313
+ function compactUsageStore(store) {
314
+ compactRunning ??= runUsageCompaction(store).finally(() => {
315
+ compactRunning = null;
316
+ });
317
+ return compactRunning;
318
+ }
319
+
320
+ async function runUsageCompaction(store) {
314
321
  try {
315
322
  await withFileLock(usageLockPath(store), async () => {
316
323
  const lines = (await readFile(store, 'utf8')).split('\n').filter(l => l.trim());
@@ -319,8 +326,6 @@ async function compactUsageStore(store) {
319
326
  });
320
327
  } catch {
321
328
  // Compaction is best effort; the next flush retries.
322
- } finally {
323
- compactRunning = false;
324
329
  }
325
330
  }
326
331
 
@@ -330,8 +335,13 @@ function maybeScheduleCompaction(store) {
330
335
  } catch {
331
336
  return;
332
337
  }
333
- const t = setTimeout(() => { void compactUsageStore(store); }, 1000);
334
- t.unref?.();
338
+ if (compactTimer) return;
339
+ compactStore = store;
340
+ compactTimer = setTimeout(() => {
341
+ compactTimer = null;
342
+ void compactUsageStore(store);
343
+ }, 1000);
344
+ compactTimer.unref?.();
335
345
  }
336
346
 
337
347
  function takePendingUsageBatch() {
@@ -357,8 +367,12 @@ function flushGatewayUsageEvents() {
357
367
  const flush = withFileLock(usageLockPath(store), async () => {
358
368
  await mkdir(dirname(store), { recursive: true });
359
369
  await appendFile(store, data);
360
- }).then(() => maybeScheduleCompaction(store)).catch(() => {
361
- // Local telemetry must never affect the routed model call.
370
+ }).then(() => maybeScheduleCompaction(store)).catch((error) => {
371
+ // Local telemetry must never affect the routed model call, but a lost
372
+ // batch is reported rather than settled as written.
373
+ try {
374
+ process.stderr.write(`[statusline] gateway usage events not saved: ${error?.message || error}\n`);
375
+ } catch {}
362
376
  });
363
377
  usageFlushTail = Promise.all([usageFlushTail, flush]).then(() => {});
364
378
  return usageFlushTail;
@@ -378,9 +392,17 @@ function flushGatewayUsageEventsSync() {
378
392
  }
379
393
  }
380
394
 
381
- /** Resolves once every recorded usage event has been handed to disk. */
382
- export function settleGatewayUsageWrites() {
383
- return flushGatewayUsageEvents();
395
+ /** Resolves once every recorded usage event has been handed to disk and the
396
+ * compaction those writes scheduled (run now instead of on its timer) or
397
+ * started has rewritten the store. */
398
+ export async function settleGatewayUsageWrites() {
399
+ await flushGatewayUsageEvents();
400
+ if (compactTimer) {
401
+ clearTimeout(compactTimer);
402
+ compactTimer = null;
403
+ void compactUsageStore(compactStore);
404
+ }
405
+ await compactRunning;
384
406
  }
385
407
 
386
408
  function scheduleGatewayUsageFlush() {
@@ -1,188 +0,0 @@
1
- const FILE_MODES = ['overview', 'imports', 'dependents', 'related', 'impact'];
2
- const SYMBOL_MODES = ['find_symbol', 'symbol_search', 'search', 'references', 'callers', 'callees'];
3
- const EXACT_MODES = ['find_symbol', 'references', 'callers', 'callees'];
4
- const KEYWORD_MODES = ['symbol_search', 'search'];
5
- const NEGATION =
6
- /\b(?:no|not|never|without|cannot|won['’]t|ain['’]t|(?:is|are|was|were|do|does|did|has|have|had|can|could|would|should|must)(?:\s+not|n['’]t)|will\s+not|fail(?:s|ed|ing)?\s+to)\b/i;
7
-
8
- const clauses = (text) =>
9
- String(text || '')
10
- .split(/[.;]\s*/)
11
- .map((part) => part.trim())
12
- .filter(Boolean);
13
- const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
14
- const includesTerm = (text, term) => {
15
- if (/^[a-z_][a-z0-9_]*$/i.test(term)) {
16
- return new RegExp(`(?<![a-z0-9_])${escapeRegExp(term)}(?![a-z0-9_])`, 'i').test(text);
17
- }
18
- return text.toLowerCase().includes(term.toLowerCase());
19
- };
20
- const includesAll = (text, terms) => terms.every((term) => includesTerm(text, term));
21
- const hasPositiveClause = (text, terms) =>
22
- clauses(text).some((clause) => !NEGATION.test(clause) && includesAll(clause, terms));
23
- const hasModeClause = (text, label, modes) => hasPositiveClause(text, [label, ...modes]);
24
- const hasContradictoryTargetAssignment = (text) =>
25
- hasPositiveClause(text, [...FILE_MODES, 'symbols[]']) || hasPositiveClause(text, [...SYMBOL_MODES, 'files[]']);
26
- const removeIdentifier = (text, identifier) =>
27
- text.replace(new RegExp(`(?<![a-z0-9_])${escapeRegExp(identifier)}(?![a-z0-9_])`, 'gi'), '');
28
-
29
- const CODE_GRAPH_EQUIVALENT_DESCRIPTION_PROBES = [
30
- {
31
- description: [
32
- 'Keywords use search/symbol_search while callers/callees/references/find_symbol use exact identifiers.',
33
- 'symbols[] targets callees, search, references, symbol_search, callers, and find_symbol symbol modes.',
34
- 'files[] targets impact, related, dependents, imports, and overview file modes.',
35
- ].join(' '),
36
- modeDescription: [
37
- 'A file outline uses files[] for symbols with files.',
38
- 'Impact, related, dependents, imports, and overview are file modes.',
39
- 'Callees, callers, references, search, symbol_search, and find_symbol are symbol modes.',
40
- 'Keywords from fileless symbols route to symbol_search.',
41
- ].join(' '),
42
- symbolsDescription: [
43
- 'Keywords select search/symbol_search while callers/callees/references/find_symbol select exact identifiers.',
44
- 'Pass multiple exact symbols in one symbols[] call.',
45
- ].join(' '),
46
- },
47
- {
48
- description: [
49
- 'Exact identifiers route through callees, references, callers, or find_symbol.',
50
- 'Keywords route through search or symbol_search.',
51
- 'The overview, impact, imports, related, and dependents file modes accept files[].',
52
- 'The search, callees, find_symbol, references, symbol_search, and callers symbol modes accept symbols[].',
53
- ].join(' '),
54
- modeDescription: [
55
- 'Related, overview, impact, dependents, and imports are file modes.',
56
- 'Symbols with files produce a file outline from files[].',
57
- 'References, callers, callees, find_symbol, search, and symbol_search are symbol modes.',
58
- 'Fileless symbols treat keywords as symbol_search input.',
59
- ].join(' '),
60
- symbolsDescription: [
61
- 'Exact identifiers select references, callees, callers, or find_symbol.',
62
- 'Keywords select symbol_search or search.',
63
- 'Multiple exact symbols belong in one symbols[] call.',
64
- ].join(' '),
65
- },
66
- ];
67
-
68
- const CODE_GRAPH_DESCRIPTION_MUTATION_CORPUS = [
69
- {
70
- name: 'contracted negated file assignment',
71
- mutate: (parts) => ({
72
- ...parts,
73
- description: parts.description.replace(
74
- /file modes (?:take|use) files\[\]/i,
75
- "file modes aren't assigned files[]"
76
- ),
77
- filesDescription: String(parts.filesDescription || '').replace(
78
- /required for file modes/i,
79
- 'not required for file modes'
80
- ),
81
- }),
82
- },
83
- {
84
- name: 'contracted outline polarity inversion',
85
- allPositiveProbes: true,
86
- mutate: (parts) => ({
87
- ...parts,
88
- modeDescription: parts.modeDescription.replace(/file outline/i, "isn't a file outline"),
89
- }),
90
- },
91
- {
92
- name: 'keyword routing polarity inversion',
93
- allPositiveProbes: true,
94
- mutate: (parts) => ({
95
- ...parts,
96
- description: parts.description.replace(
97
- /keywords(?::|\s+(?:use|route through|select|via))/i,
98
- "keywords won't use"
99
- ),
100
- }),
101
- },
102
- {
103
- name: 'symbols-with-files outline inversion',
104
- allPositiveProbes: true,
105
- mutate: (parts) => ({
106
- ...parts,
107
- modeDescription: parts.modeDescription.replace(/symbols with files/i, 'symbols without files'),
108
- }),
109
- },
110
- {
111
- name: 'contradictory file-mode assignment retained beside correct clause',
112
- allPositiveProbes: true,
113
- mutate: (parts) => ({
114
- ...parts,
115
- description: `${parts.description} Overview, imports, dependents, related, and impact take symbols[].`,
116
- }),
117
- },
118
- {
119
- name: 'contradictory symbol-mode assignment retained beside correct clause',
120
- allPositiveProbes: true,
121
- mutate: (parts) => ({
122
- ...parts,
123
- description: `${parts.description} Find_symbol, symbol_search, search, references, callers, and callees take files[].`,
124
- }),
125
- },
126
- {
127
- name: 'swapped file-mode/symbol-mode array assignments',
128
- allPositiveProbes: true,
129
- mutate: (parts) => ({
130
- ...parts,
131
- description: `${parts.description} Overview, imports, dependents, related, and impact take symbols[]. Find_symbol, symbol_search, search, references, callers, and callees take files[].`,
132
- }),
133
- },
134
- {
135
- name: 'standalone search removed from symbol modes and keyword routing',
136
- allPositiveProbes: true,
137
- mutate: (parts) => ({
138
- ...parts,
139
- description: removeIdentifier(parts.description, 'search'),
140
- modeDescription: removeIdentifier(parts.modeDescription, 'search'),
141
- symbolsDescription: removeIdentifier(parts.symbolsDescription, 'search'),
142
- }),
143
- },
144
- ];
145
-
146
- function hasCodeGraphDescriptionContract({ description, modeDescription, filesDescription, symbolsDescription }) {
147
- return (
148
- (hasPositiveClause(description, ['file modes', 'files[]']) ||
149
- hasPositiveClause(filesDescription, ['required for file modes'])) &&
150
- (hasPositiveClause(description, ['symbol modes', 'symbols[]']) ||
151
- hasPositiveClause(symbolsDescription, ['required for symbol modes'])) &&
152
- hasPositiveClause(description, ['exact identifiers', ...EXACT_MODES]) &&
153
- hasPositiveClause(description, ['keywords', ...KEYWORD_MODES]) &&
154
- !hasContradictoryTargetAssignment(description) &&
155
- hasModeClause(modeDescription, 'file modes', FILE_MODES) &&
156
- hasPositiveClause(modeDescription, ['symbols with files', 'files[]', 'file outline']) &&
157
- !hasContradictoryTargetAssignment(modeDescription) &&
158
- !hasContradictoryTargetAssignment(filesDescription) &&
159
- hasPositiveClause(symbolsDescription, ['exact identifiers']) &&
160
- hasPositiveClause(symbolsDescription, ['keywords']) &&
161
- !hasContradictoryTargetAssignment(symbolsDescription)
162
- );
163
- }
164
-
165
- export function assertCodeGraphDescriptionContract(parts) {
166
- if (!hasCodeGraphDescriptionContract(parts)) {
167
- throw new Error('code_graph descriptions must preserve per-mode targets and exact-vs-keyword routing');
168
- }
169
- for (const probe of CODE_GRAPH_EQUIVALENT_DESCRIPTION_PROBES) {
170
- if (!hasCodeGraphDescriptionContract(probe)) {
171
- throw new Error('code_graph description contract must accept equivalent reordered compact prose');
172
- }
173
- for (const mutation of CODE_GRAPH_DESCRIPTION_MUTATION_CORPUS.filter((entry) => entry.allPositiveProbes)) {
174
- const mutated = mutation.mutate(probe);
175
- if (JSON.stringify(mutated) === JSON.stringify(probe)) {
176
- throw new Error(`code_graph description mutation did not apply to positive probe: ${mutation.name}`);
177
- }
178
- if (hasCodeGraphDescriptionContract(mutated)) {
179
- throw new Error(`code_graph description contract accepted positive-probe mutation: ${mutation.name}`);
180
- }
181
- }
182
- }
183
- for (const mutation of CODE_GRAPH_DESCRIPTION_MUTATION_CORPUS) {
184
- if (hasCodeGraphDescriptionContract(mutation.mutate(parts))) {
185
- throw new Error(`code_graph description contract accepted mutation: ${mutation.name}`);
186
- }
187
- }
188
- }
@@ -1,36 +0,0 @@
1
- // Daemon model: this runtime is the unconditional bridge owner, so a refresh
2
- // just keeps the owned runtime in sync with channelBridgeActive.
3
- export function createOwnershipRefresh({
4
- state,
5
- getBridgeRuntimeConnected,
6
- getChannelBridgeActive,
7
- startOwnedRuntime,
8
- stopOwnedRuntime,
9
- }) {
10
- async function syncWithBridgeActivity(options) {
11
- if (!getChannelBridgeActive()) {
12
- if (getBridgeRuntimeConnected()) await stopOwnedRuntime('bridge inactive');
13
- return;
14
- }
15
- // Idempotent; early-returns when already connected.
16
- await startOwnedRuntime(options);
17
- }
18
- // Concurrent callers coalesce onto the in-flight refresh so provider tool
19
- // calls landing during a normal login wait for the same connect attempt
20
- // instead of observing a spurious auto-connect failure.
21
- async function refreshBridgeOwnership(options = {}) {
22
- if (state.refreshInFlight) return state.refreshInFlight;
23
- state.refreshInFlight = syncWithBridgeActivity(options);
24
- try {
25
- return await state.refreshInFlight;
26
- } finally {
27
- state.refreshInFlight = null;
28
- }
29
- }
30
- function refreshBridgeOwnershipSafe(options = {}) {
31
- refreshBridgeOwnership(options).catch((err) =>
32
- process.stderr.write(`[channels] refreshBridgeOwnership rejected: ${err?.message || err}\n`)
33
- );
34
- }
35
- return { refreshBridgeOwnership, refreshBridgeOwnershipSafe };
36
- }