mixdog 0.9.166 → 0.9.167

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 (221) hide show
  1. package/package.json +1 -1
  2. package/scripts/audit-usage-ledger.mjs +86 -0
  3. package/scripts/generate-voice-runtime-manifest.mjs +22 -17
  4. package/scripts/memory-chunk-quality.mjs +128 -0
  5. package/scripts/memory-layer2-check.mjs +133 -0
  6. package/scripts/model-catalog-audit.mjs +6 -0
  7. package/scripts/native-tool-download.mjs +14 -0
  8. package/scripts/prepare-native-assets.mjs +2 -7
  9. package/scripts/tool-failures.mjs +7 -2
  10. package/scripts/verify-release-assets.mjs +48 -90
  11. package/src/defaults/skills/browser-use/SKILL.md +33 -18
  12. package/src/defaults/skills/computer-use/SKILL.md +16 -8
  13. package/src/lib/keychain-cjs.cjs +0 -1
  14. package/src/lib/rules-builder.cjs +4 -1
  15. package/src/rules/agent/40-cycle1-agent.md +21 -13
  16. package/src/rules/lead/01-general.md +8 -3
  17. package/src/rules/shared/10-tool-workflow.md +20 -11
  18. package/src/rules/shared/30-exploration.md +11 -4
  19. package/src/rules/shared/40-editing.md +2 -3
  20. package/src/rules/shared/50-execution.md +6 -3
  21. package/src/rules/shared/60-verification.md +3 -2
  22. package/src/rules/shared/70-delivery.md +0 -4
  23. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +51 -45
  24. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +3 -4
  25. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +44 -7
  26. package/src/runtime/agent/orchestrator/agent-trace.mjs +9 -0
  27. package/src/runtime/agent/orchestrator/config.mjs +9 -4
  28. package/src/runtime/agent/orchestrator/context/collect.mjs +25 -1055
  29. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +272 -0
  30. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +296 -0
  31. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +523 -0
  32. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +7 -2
  33. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +13 -14
  34. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +214 -0
  35. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +220 -116
  36. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +74 -44
  37. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +191 -29
  38. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +13 -12
  39. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +1 -9
  40. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +5 -2
  41. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +48 -25
  42. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +28 -2
  43. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +3 -1
  44. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +1 -8
  45. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +32 -0
  46. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +21 -6
  47. package/src/runtime/agent/orchestrator/providers/lib/grok-tool-schema.mjs +61 -13
  48. package/src/runtime/agent/orchestrator/providers/model-catalog-projection.mjs +6 -1
  49. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +123 -118
  50. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +54 -0
  51. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +5 -2
  52. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +34 -3
  53. package/src/runtime/agent/orchestrator/providers/openai-codex-endpoints.mjs +21 -0
  54. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +154 -0
  55. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +2 -1
  56. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +322 -0
  57. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +243 -702
  58. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +2 -2
  59. package/src/runtime/agent/orchestrator/providers/openai-startup-prewarm.mjs +221 -0
  60. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +3 -2
  61. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +1 -1
  62. package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +19 -0
  63. package/src/runtime/agent/orchestrator/providers/provider-model-identities.mjs +40 -0
  64. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +120 -710
  65. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +36 -15
  66. package/src/runtime/agent/orchestrator/session/cache/util.mjs +9 -0
  67. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +17 -4
  68. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +36 -31
  69. package/src/runtime/agent/orchestrator/session/compact.mjs +4 -5
  70. package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +6 -5
  71. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -6
  72. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +121 -0
  73. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -3
  74. package/src/runtime/agent/orchestrator/session/loop/diagnostics.mjs +74 -0
  75. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +44 -17
  76. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +266 -0
  77. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +111 -0
  78. package/src/runtime/agent/orchestrator/session/loop/request-projection.mjs +99 -0
  79. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +91 -0
  80. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +36 -0
  81. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +3 -3
  82. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
  83. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +20 -11
  84. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +3 -5
  85. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +9 -3
  86. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +39 -0
  87. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +3 -2
  88. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +21 -3
  89. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +1 -1
  90. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +2 -3
  91. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +25 -25
  92. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +62 -10
  93. package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +17 -0
  94. package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +61 -4
  95. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +13 -9
  96. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +12 -2
  97. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +3 -2
  98. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +8 -3
  99. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +69 -6
  100. package/src/runtime/agent/orchestrator/tools/builtin.mjs +14 -17
  101. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
  102. package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +1 -1
  103. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
  104. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +1 -1
  105. package/src/runtime/bridge-discovery.mjs +8 -0
  106. package/src/runtime/browser-bridge/action-schema.mjs +37 -43
  107. package/src/runtime/browser-bridge/client.mjs +111 -99
  108. package/src/runtime/browser-bridge/input-fields.mjs +187 -0
  109. package/src/runtime/browser-bridge/tool-defs.mjs +12 -227
  110. package/src/runtime/computer-bridge/action-schema.mjs +2 -46
  111. package/src/runtime/computer-bridge/client.mjs +69 -77
  112. package/src/runtime/computer-bridge/core-actions.mjs +7 -5
  113. package/src/runtime/computer-bridge/error-recovery.mjs +41 -37
  114. package/src/runtime/computer-bridge/tool-defs.mjs +1 -1
  115. package/src/runtime/github/commands.mjs +4 -1
  116. package/src/runtime/github/contract.mjs +1 -1
  117. package/src/runtime/github/tool.mjs +2 -2
  118. package/src/runtime/media/adapters/antigravity-image.mjs +72 -0
  119. package/src/runtime/media/adapters/gemini-image.mjs +20 -11
  120. package/src/runtime/media/auth.mjs +12 -0
  121. package/src/runtime/media/catalog.mjs +30 -10
  122. package/src/runtime/media/jobs.mjs +4 -0
  123. package/src/runtime/media/lanes.mjs +40 -31
  124. package/src/runtime/memory/index.mjs +2 -9
  125. package/src/runtime/memory/lib/compact-handoff.mjs +26 -18
  126. package/src/runtime/memory/lib/memory-chunk-audit.mjs +41 -0
  127. package/src/runtime/memory/lib/memory-chunk-quality.mjs +388 -0
  128. package/src/runtime/memory/lib/memory-cycle1.mjs +95 -394
  129. package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +29 -4
  130. package/src/runtime/memory/lib/memory-recall-store.mjs +8 -12
  131. package/src/runtime/memory/lib/memory-retrievers.mjs +8 -11
  132. package/src/runtime/memory/lib/memory.mjs +2 -0
  133. package/src/runtime/memory/lib/query-handlers.mjs +98 -144
  134. package/src/runtime/memory/lib/query-ranking.mjs +23 -9
  135. package/src/runtime/memory/lib/recall-format.mjs +37 -27
  136. package/src/runtime/memory/lib/session-ingest-runtime.mjs +14 -8
  137. package/src/runtime/memory/lib/session-ingest.mjs +45 -84
  138. package/src/runtime/memory/lib/transcript-ingest.mjs +19 -21
  139. package/src/runtime/memory/tool-defs.mjs +2 -2
  140. package/src/runtime/office/authoring/pptx-author-session.mjs +3 -7
  141. package/src/runtime/office/core/office-actions-batch.mjs +2 -8
  142. package/src/runtime/office/core/office-actions-open.mjs +124 -0
  143. package/src/runtime/office/core/office-actions-read.mjs +127 -0
  144. package/src/runtime/office/core/office-core.mjs +80 -1
  145. package/src/runtime/office/core/office-sessions.mjs +116 -138
  146. package/src/runtime/office/index.mjs +18 -271
  147. package/src/runtime/office/pdf/pdf-analysis.mjs +2 -2
  148. package/src/runtime/office/pdf/pdf-limits.mjs +2 -0
  149. package/src/runtime/office/tool-defs.mjs +7 -6
  150. package/src/runtime/shared/agent-route-config.mjs +8 -8
  151. package/src/runtime/shared/child-spawn-gate.mjs +10 -13
  152. package/src/runtime/shared/config.mjs +2 -7
  153. package/src/runtime/shared/env.mjs +3 -3
  154. package/src/runtime/shared/err-text.mjs +1 -1
  155. package/src/runtime/shared/extension-scopes.mjs +3 -2
  156. package/src/runtime/shared/heap-cap.mjs +10 -6
  157. package/src/runtime/shared/llm/cost.mjs +35 -10
  158. package/src/runtime/shared/llm/usage-accounting.mjs +11 -1
  159. package/src/runtime/shared/llm/usage-context.mjs +6 -0
  160. package/src/runtime/shared/llm/usage-ledger-import.mjs +5 -0
  161. package/src/runtime/shared/llm/usage-ledger-repair.mjs +109 -0
  162. package/src/runtime/shared/llm/usage-ledger.mjs +59 -20
  163. package/src/runtime/shared/llm/usage-pricing-refresh.mjs +26 -0
  164. package/src/runtime/shared/llm/usage-rollup.mjs +17 -15
  165. package/src/runtime/shared/native-asset.mjs +3 -4
  166. package/src/runtime/shared/object.mjs +4 -0
  167. package/src/runtime/shared/pg-schema-db.mjs +21 -0
  168. package/src/runtime/shared/plugin-metadata.mjs +3 -1
  169. package/src/runtime/shared/resource-admission.mjs +1 -6
  170. package/src/runtime/shared/schedules-db.mjs +8 -24
  171. package/src/runtime/shared/schema-value-error.d.mts +2 -0
  172. package/src/runtime/shared/schema-value-error.mjs +68 -0
  173. package/src/runtime/shared/singleton-owner.mjs +11 -24
  174. package/src/runtime/shared/staged-update.mjs +1 -10
  175. package/src/runtime/shared/tool-card-model.mjs +8 -5
  176. package/src/runtime/shared/tool-execution-contract.mjs +1 -1
  177. package/src/runtime/shared/tool-surface.mjs +1 -5
  178. package/src/runtime/shared/user-data-guard.mjs +1 -4
  179. package/src/runtime/shared/webhooks-db.mjs +8 -24
  180. package/src/runtime/web-search/index.mjs +32 -8
  181. package/src/runtime/web-search/tool-defs.mjs +4 -4
  182. package/src/session-runtime/config-lifecycle.mjs +34 -0
  183. package/src/session-runtime/context-status.mjs +19 -0
  184. package/src/session-runtime/cwd-plugins.mjs +12 -29
  185. package/src/session-runtime/goal-tasks.mjs +2 -2
  186. package/src/session-runtime/goal-tool-defs.mjs +3 -2
  187. package/src/session-runtime/internal-tool-executor.mjs +7 -0
  188. package/src/session-runtime/lifecycle-api.mjs +5 -11
  189. package/src/session-runtime/notification-bus.mjs +41 -0
  190. package/src/session-runtime/prewarm.mjs +22 -0
  191. package/src/session-runtime/runtime-bootstrap.mjs +90 -0
  192. package/src/session-runtime/runtime-core.mjs +88 -202
  193. package/src/session-runtime/runtime-feature-gates.mjs +37 -0
  194. package/src/session-runtime/session-lifecycle.mjs +5 -5
  195. package/src/session-runtime/session-turn-api.mjs +1 -12
  196. package/src/session-runtime/setup-tool/executor.mjs +13 -5
  197. package/src/session-runtime/setup-tool/tool-defs.mjs +52 -46
  198. package/src/session-runtime/tool-defs.mjs +73 -4
  199. package/src/session-runtime/usage-stats-api.mjs +4 -1
  200. package/src/session-runtime/warmup-schedulers.mjs +8 -2
  201. package/src/session-runtime/workflow.mjs +14 -0
  202. package/src/standalone/channel-session-router.mjs +3 -1
  203. package/src/standalone/channel-worker.mjs +18 -9
  204. package/src/standalone/daemon-crash-capture.mjs +534 -0
  205. package/src/standalone/daemon-telemetry.mjs +175 -0
  206. package/src/standalone/daemon.mjs +31 -21
  207. package/src/standalone/session-client.mjs +31 -23
  208. package/src/standalone/usage-dashboard-model.mjs +2 -0
  209. package/src/standalone/usage-stats-hours.mjs +18 -11
  210. package/src/standalone/usage-stats-model.mjs +39 -28
  211. package/src/standalone/usage-stats-period.mjs +43 -45
  212. package/src/tui/app/use-transcript-window.mjs +1 -1
  213. package/src/tui/components/StatusLine.jsx +13 -42
  214. package/src/tui/dist/index.mjs +256 -239
  215. package/src/tui/session/session-api-ext.mjs +44 -41
  216. package/src/tui/session/session-api.mjs +4 -0
  217. package/src/tui/session/tool-card-results.mjs +25 -78
  218. package/src/tui/session/tool-result-status.mjs +94 -1
  219. package/src/tui/session/turn-aggregate-cards.mjs +17 -54
  220. package/src/ui/statusline-format.mjs +6 -26
  221. package/src/workflows/default/WORKFLOW.md +5 -0
@@ -2963,11 +2963,7 @@ var TOOL_CATEGORY = /* @__PURE__ */ new Map([
2963
2963
  function classifyToolCategory(name, args = {}) {
2964
2964
  if (isExternalMcpToolName(name)) return "MCP";
2965
2965
  const normalized = normalizeToolName(name);
2966
- if (normalized === "code_graph") {
2967
- const mode = String(args.mode || args.action || "").toLowerCase();
2968
- if (mode === "prewarm" || mode === "index" || mode === "build" || mode === "refresh") return "Setup";
2969
- return mode === "search" || mode === "find_symbol" || mode === "references" || mode === "callers" || mode === "callees" ? "Search" : "Read";
2970
- }
2966
+ if (normalized === "code_graph") return codeGraphLabel(args);
2971
2967
  return TOOL_CATEGORY.get(normalized) || "Other";
2972
2968
  }
2973
2969
  var CATEGORY_COPY = /* @__PURE__ */ new Map([
@@ -4674,6 +4670,9 @@ import { createRequire as createRequire2 } from "module";
4674
4670
  function hasOwn(value, key) {
4675
4671
  return value != null && Object.hasOwn(value, key);
4676
4672
  }
4673
+ function isPlainObject(value) {
4674
+ return !!value && typeof value === "object" && !Array.isArray(value);
4675
+ }
4677
4676
 
4678
4677
  // src/runtime/shared/user-data-guard.mjs
4679
4678
  import {
@@ -4722,9 +4721,6 @@ function initMarkerPath(dataDir2) {
4722
4721
  const id = createHash("sha256").update(String(dataDir2 || "unknown")).digest("hex").slice(0, 16);
4723
4722
  return join5(getBackupRoot(), `.initialized-${id}.json`);
4724
4723
  }
4725
- function isPlainObject(value) {
4726
- return !!value && typeof value === "object" && !Array.isArray(value);
4727
- }
4728
4724
  function hasUserDataInitMarker(dataDir2) {
4729
4725
  return existsSync4(initMarkerPath(dataDir2));
4730
4726
  }
@@ -4896,11 +4892,8 @@ function readConfigRawCached() {
4896
4892
  _configReadCache = { raw, mtimeMs: st.mtimeMs, size: st.size, atMs: now };
4897
4893
  return raw;
4898
4894
  }
4899
- function isPlainObject2(value) {
4900
- return !!value && typeof value === "object" && !Array.isArray(value);
4901
- }
4902
4895
  function canonicalizeStoredChannelsConfig(value = {}) {
4903
- const next = isPlainObject2(value) ? { ...value } : {};
4896
+ const next = isPlainObject(value) ? { ...value } : {};
4904
4897
  delete next.promptInjection;
4905
4898
  delete next.schedules;
4906
4899
  delete next.nonInteractive;
@@ -4913,22 +4906,22 @@ function canonicalizeStoredChannelsConfig(value = {}) {
4913
4906
  return next;
4914
4907
  }
4915
4908
  function canonicalizeUnifiedConfig(value = {}) {
4916
- const next = isPlainObject2(value) ? { ...value } : {};
4917
- const hadAgent = isPlainObject2(next.agent);
4909
+ const next = isPlainObject(value) ? { ...value } : {};
4910
+ const hadAgent = isPlainObject(next.agent);
4918
4911
  const agent = hadAgent ? { ...next.agent } : {};
4919
4912
  delete agent.outputStyle;
4920
4913
  for (const key of ["autoClear", "compaction", "shell"]) delete next[key];
4921
4914
  delete next.mcpServers;
4922
4915
  delete agent.search;
4923
4916
  delete agent.capabilities;
4924
- const modules = isPlainObject2(agent.modules) ? { ...agent.modules } : {};
4917
+ const modules = isPlainObject(agent.modules) ? { ...agent.modules } : {};
4925
4918
  if (hasOwn(modules, "memory")) {
4926
4919
  delete modules.memory;
4927
4920
  agent.modules = modules;
4928
4921
  }
4929
- if (isPlainObject2(next.memory)) {
4922
+ if (isPlainObject(next.memory)) {
4930
4923
  const memory = { ...next.memory };
4931
- const user = isPlainObject2(memory.user) ? { ...memory.user } : {};
4924
+ const user = isPlainObject(memory.user) ? { ...memory.user } : {};
4932
4925
  delete user.title;
4933
4926
  if (Object.keys(user).length) memory.user = user;
4934
4927
  else delete memory.user;
@@ -4936,7 +4929,7 @@ function canonicalizeUnifiedConfig(value = {}) {
4936
4929
  if (Object.keys(memory).length) next.memory = memory;
4937
4930
  else delete next.memory;
4938
4931
  }
4939
- if (isPlainObject2(next.channels)) {
4932
+ if (isPlainObject(next.channels)) {
4940
4933
  next.channels = canonicalizeStoredChannelsConfig(next.channels);
4941
4934
  }
4942
4935
  delete next.search;
@@ -4945,7 +4938,7 @@ function canonicalizeUnifiedConfig(value = {}) {
4945
4938
  return next;
4946
4939
  }
4947
4940
  function stripGeneratedMarker(data) {
4948
- if (!isPlainObject2(data) || !Object.prototype.hasOwnProperty.call(data, GENERATED_KEY)) return data;
4941
+ if (!isPlainObject(data) || !hasOwn(data, GENERATED_KEY)) return data;
4949
4942
  const { [GENERATED_KEY]: _generated, ...rest } = data;
4950
4943
  return rest;
4951
4944
  }
@@ -4985,7 +4978,7 @@ function readAll() {
4985
4978
  if (parsed != null) return canonicalizeUnifiedConfig(parsed);
4986
4979
  if (hasUserDataInitMarker(DATA_DIR)) {
4987
4980
  const restored = loadLatestMixdogConfigFromBackup(DATA_DIR);
4988
- if (restored && isPlainObject2(restored)) {
4981
+ if (restored && isPlainObject(restored)) {
4989
4982
  process.stderr.write("[config] read: restored mixdog-config.json from latest user-data backup (missing after init)\n");
4990
4983
  return canonicalizeUnifiedConfig(restored);
4991
4984
  }
@@ -5005,7 +4998,7 @@ function quarantineMalformedConfig(parseErr) {
5005
4998
  }
5006
4999
  function restoreAllForRmWOrThrow(reason) {
5007
5000
  const restored = loadLatestMixdogConfigFromBackup(DATA_DIR);
5008
- if (restored && isPlainObject2(restored)) {
5001
+ if (restored && isPlainObject(restored)) {
5009
5002
  process.stderr.write(`[config] RMW read: restored mixdog-config.json from latest user-data backup (${reason})
5010
5003
  `);
5011
5004
  return restored;
@@ -5031,7 +5024,7 @@ function readAllForRmW() {
5031
5024
  }
5032
5025
  try {
5033
5026
  const parsed = JSON.parse(raw);
5034
- if (!isPlainObject2(parsed)) throw new SyntaxError("config root must be a JSON object");
5027
+ if (!isPlainObject(parsed)) throw new SyntaxError("config root must be a JSON object");
5035
5028
  return parsed;
5036
5029
  } catch (parseErr) {
5037
5030
  quarantineMalformedConfig(parseErr);
@@ -5257,16 +5250,63 @@ var {
5257
5250
  } = import_profile_config2.default;
5258
5251
  var MAINTENANCE_SLOTS = Object.freeze(["memory"]);
5259
5252
 
5253
+ // src/runtime/agent/orchestrator/providers/provider-model-identities.mjs
5254
+ function fallbackModel(id, display, family, contextWindow, wire) {
5255
+ const tiered = wire && typeof wire === "object";
5256
+ return {
5257
+ id,
5258
+ name: display,
5259
+ display,
5260
+ provider: "antigravity-oauth",
5261
+ ...family ? { family } : {},
5262
+ contextWindow,
5263
+ supportsVision: true,
5264
+ supportsReasoning: true,
5265
+ supportsFunctionCalling: true,
5266
+ reasoningLevels: tiered ? Object.keys(wire) : [],
5267
+ wire
5268
+ };
5269
+ }
5270
+ var ANTIGRAVITY_MODELS = Object.freeze([
5271
+ fallbackModel("gemini-3.8-flash", "Gemini 3.8 Flash", "gemini-flash", 1048576, {
5272
+ low: "gemini-3.8-flash-low",
5273
+ medium: "gemini-3.8-flash-medium",
5274
+ high: "gemini-3.8-flash-high"
5275
+ }),
5276
+ fallbackModel("gemini-3.1-pro", "Gemini 3.1 Pro", "gemini-pro", 1048576, {
5277
+ low: "gemini-3.1-pro-low",
5278
+ high: "gemini-3.1-pro-high"
5279
+ }),
5280
+ fallbackModel("claude-opus-4-6-thinking", "Claude Opus 4.6 (Thinking)", null, 25e4, "claude-opus-4-6-thinking"),
5281
+ fallbackModel("claude-sonnet-4-6", "Claude Sonnet 4.6 (Thinking)", null, 25e4, "claude-sonnet-4-6"),
5282
+ fallbackModel("gpt-oss-120b-medium", "GPT-OSS 120B (Medium)", "gpt-oss", 131072, "gpt-oss-120b-medium")
5283
+ ]);
5284
+ var RETIRED_MODEL_ALIASES = Object.freeze({
5285
+ "grok-code-fast-1": "grok-build-0.1",
5286
+ "grok-code-fast": "grok-build-0.1",
5287
+ "grok-code-fast-1-0825": "grok-build-0.1"
5288
+ });
5289
+
5260
5290
  // src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs
5261
5291
  var PROVIDER_CACHE_FILES = Object.freeze({
5262
5292
  "openai-oauth": ["openai-oauth-models.json"],
5263
5293
  "anthropic-oauth": ["anthropic-oauth-models.json"],
5264
5294
  anthropic: ["anthropic-oauth-models.json"],
5265
5295
  gemini: ["gemini-models.json"],
5266
- "grok-oauth": ["grok-oauth-models.json"]
5296
+ "grok-oauth": ["grok-oauth-models.json"],
5297
+ "antigravity-oauth": ["antigravity-oauth-models.json"]
5267
5298
  });
5268
5299
 
5300
+ // src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs
5301
+ var PRICING_RATE_KEYS = Object.freeze([
5302
+ "inputCostPerM",
5303
+ "outputCostPerM",
5304
+ "cacheReadCostPerM",
5305
+ "cacheWriteCostPerM"
5306
+ ]);
5307
+
5269
5308
  // src/runtime/agent/orchestrator/providers/model-catalog.mjs
5309
+ var PRICING_CATALOG_REFRESH_MS = 6 * 60 * 60 * 1e3;
5270
5310
  var XAI_GROK_420_ROW = Object.freeze({
5271
5311
  litellm_provider: "xai",
5272
5312
  input_cost_per_token: 125e-8,
@@ -5391,21 +5431,13 @@ var D = colorEnabled() ? rgbSgr(136, 136, 136) : "";
5391
5431
  var GRN = colorEnabled() ? rgbSgr(0, 170, 75) : "";
5392
5432
  var YLW = colorEnabled() ? rgbSgr(255, 193, 7) : "";
5393
5433
  var RED = colorEnabled() ? rgbSgr(220, 70, 88) : "";
5394
- function formatElapsed2(ms) {
5395
- if (!Number.isFinite(Number(ms))) return "";
5396
- const value = Math.max(0, Number(ms) || 0);
5397
- if (value < 6e4) {
5398
- if (value < 1e3) return "";
5399
- return `${Math.floor(value / 1e3)}s`;
5400
- }
5401
- const days = Math.floor(value / 864e5);
5402
- const hours = Math.floor(value % 864e5 / 36e5);
5403
- const minutes = Math.floor(value % 36e5 / 6e4);
5404
- const seconds = Math.floor(value % 6e4 / 1e3);
5405
- if (days > 0) return `${days}d ${hours}h ${minutes}m`;
5406
- if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;
5407
- if (minutes > 0) return `${minutes}m ${seconds}s`;
5408
- return `${seconds}s`;
5434
+ function terminalColumns() {
5435
+ const cols = Number(process.stdout?.columns);
5436
+ return Number.isFinite(cols) && cols > 0 ? Math.floor(cols) : 120;
5437
+ }
5438
+ function num(v) {
5439
+ const n = Number(v);
5440
+ return Number.isFinite(n) ? n : 0;
5409
5441
  }
5410
5442
 
5411
5443
  // src/runtime/shared/numbers.mjs
@@ -5508,12 +5540,12 @@ async function refreshShellJobsStatus(ownerPid) {
5508
5540
  }
5509
5541
  if (count || bySession.size) {
5510
5542
  const now = Date.now();
5511
- const elapsedLabel = Number.isFinite(oldestMs) ? formatElapsed2(now - oldestMs) : "";
5543
+ const elapsedLabel = Number.isFinite(oldestMs) ? formatElapsed(now - oldestMs) : "";
5512
5544
  const sessions = {};
5513
5545
  for (const [owner, bucket] of bySession) {
5514
5546
  sessions[owner] = {
5515
5547
  count: bucket.count,
5516
- elapsedLabel: Number.isFinite(bucket.oldestMs) ? formatElapsed2(now - bucket.oldestMs) : "",
5548
+ elapsedLabel: Number.isFinite(bucket.oldestMs) ? formatElapsed(now - bucket.oldestMs) : "",
5517
5549
  jobs: bucket.jobs
5518
5550
  };
5519
5551
  }
@@ -5639,14 +5671,6 @@ function statusColors() {
5639
5671
  ERROR: ansiRgb(theme.error, rgbSgr(220, 70, 88))
5640
5672
  };
5641
5673
  }
5642
- function terminalColumns() {
5643
- const cols = Number(process.stdout?.columns);
5644
- return Number.isFinite(cols) && cols > 0 ? Math.floor(cols) : 120;
5645
- }
5646
- function localNum(value) {
5647
- const n = Number(value);
5648
- return Number.isFinite(n) ? n : 0;
5649
- }
5650
5674
  function localContextPct({
5651
5675
  provider = "",
5652
5676
  stats = null,
@@ -5688,22 +5712,6 @@ function localL2SpinnerFrame(now = Date.now()) {
5688
5712
  const index = Math.floor(now / LOCAL_L2_SPINNER_FRAME_MS) % LOCAL_WORKER_SPINNER_FRAMES.length;
5689
5713
  return LOCAL_WORKER_SPINNER_FRAMES[index] || LOCAL_WORKER_SPINNER_FRAMES[0];
5690
5714
  }
5691
- function localFormatElapsed(ms) {
5692
- if (!Number.isFinite(Number(ms))) return "";
5693
- const value = Math.max(0, Number(ms) || 0);
5694
- if (value < 6e4) {
5695
- if (value < 1e3) return "";
5696
- return `${Math.floor(value / 1e3)}s`;
5697
- }
5698
- const days = Math.floor(value / 864e5);
5699
- const hours = Math.floor(value % 864e5 / 36e5);
5700
- const minutes = Math.floor(value % 36e5 / 6e4);
5701
- const seconds = Math.floor(value % 6e4 / 1e3);
5702
- if (days > 0) return `${days}d ${hours}h ${minutes}m`;
5703
- if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;
5704
- if (minutes > 0) return `${minutes}m ${seconds}s`;
5705
- return `${seconds}s`;
5706
- }
5707
5715
  function localRunningWorkerCount(agentWorkers = [], agentJobs = []) {
5708
5716
  const seen = /* @__PURE__ */ new Set();
5709
5717
  for (const worker of Array.isArray(agentWorkers) ? agentWorkers : []) {
@@ -5754,7 +5762,7 @@ function localStatusLineL2({
5754
5762
  if (runningCount > 0) {
5755
5763
  const label = `Running ${runningCount} Agent${runningCount === 1 ? "" : "s"}`;
5756
5764
  const oldestStart = localOldestWorkerStartMs(agentWorkers, agentJobs);
5757
- const elapsed = oldestStart > 0 ? localFormatElapsed(now - oldestStart) : "";
5765
+ const elapsed = oldestStart > 0 ? formatElapsed(now - oldestStart) : "";
5758
5766
  l2Parts.push(`${spin} ${STATUS}${label}${RESET3}${elapsedSuffix(elapsed)}`);
5759
5767
  }
5760
5768
  const shellScope = String(sessionId ?? "").trim();
@@ -5767,12 +5775,12 @@ function localStatusLineL2({
5767
5775
  const tools = activeTools && typeof activeTools === "object" ? activeTools : {};
5768
5776
  const exploreInfo = tools.explore || null;
5769
5777
  const searchInfo = tools.search || null;
5770
- if (exploreInfo && localNum(exploreInfo.count) > 0) {
5771
- const elapsed = localNum(exploreInfo.startedAt) > 0 ? localFormatElapsed(now - localNum(exploreInfo.startedAt)) : "";
5778
+ if (exploreInfo && num(exploreInfo.count) > 0) {
5779
+ const elapsed = num(exploreInfo.startedAt) > 0 ? formatElapsed(now - num(exploreInfo.startedAt)) : "";
5772
5780
  l2Parts.push(`${spin} ${STATUS}Exploring${RESET3}${elapsedSuffix(elapsed)}`);
5773
5781
  }
5774
- if (searchInfo && localNum(searchInfo.count) > 0) {
5775
- const elapsed = localNum(searchInfo.startedAt) > 0 ? localFormatElapsed(now - localNum(searchInfo.startedAt)) : "";
5782
+ if (searchInfo && num(searchInfo.count) > 0) {
5783
+ const elapsed = num(searchInfo.startedAt) > 0 ? formatElapsed(now - num(searchInfo.startedAt)) : "";
5776
5784
  l2Parts.push(`${spin} ${STATUS}Web Searching${RESET3}${elapsedSuffix(elapsed)}`);
5777
5785
  }
5778
5786
  return l2Parts.length ? l2Parts.join(segSep) : "";
@@ -5878,13 +5886,13 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
5878
5886
  const agentJobsSignature = Array.isArray(agentJobs) ? agentJobs.map((j) => `${j?.tag || j?.agent || j?.name || ""}|${j?.status || j?.stage || ""}|${localTimeMs(j?.startedAt || j?.startTime || j?.createdAt)}`).join(",") : "";
5879
5887
  const statsForSignature = stats && typeof stats === "object" ? stats : {};
5880
5888
  const statsSignature = [
5881
- localNum(statsForSignature.currentContextTokens),
5882
- localNum(statsForSignature.currentEstimatedContextTokens),
5883
- localNum(statsForSignature.inputTokens),
5884
- localNum(statsForSignature.latestInputTokens),
5885
- localNum(statsForSignature.promptTokens),
5886
- localNum(statsForSignature.turns),
5887
- localNum(statsForSignature.contextTokens),
5889
+ num(statsForSignature.currentContextTokens),
5890
+ num(statsForSignature.currentEstimatedContextTokens),
5891
+ num(statsForSignature.inputTokens),
5892
+ num(statsForSignature.latestInputTokens),
5893
+ num(statsForSignature.promptTokens),
5894
+ num(statsForSignature.turns),
5895
+ num(statsForSignature.contextTokens),
5888
5896
  String(statsForSignature.currentContextSource || "")
5889
5897
  ].join("|");
5890
5898
  const refreshMs = hasActiveStatuslineWork(line, agentWorkers, agentJobs, activeTools) ? STATUSLINE_ACTIVE_REFRESH_MS : STATUSLINE_REFRESH_MS;
@@ -9831,8 +9839,8 @@ function parseMemoryCommand(text) {
9831
9839
  const [key, ...rest] = part.split("=");
9832
9840
  if (!key || rest.length === 0) continue;
9833
9841
  const raw = rest.join("=");
9834
- const num = Number(raw);
9835
- out[key] = Number.isFinite(num) && raw.trim() !== "" ? num : raw;
9842
+ const num2 = Number(raw);
9843
+ out[key] = Number.isFinite(num2) && raw.trim() !== "" ? num2 : raw;
9836
9844
  }
9837
9845
  return out;
9838
9846
  }
@@ -11958,6 +11966,9 @@ function describeError(value) {
11958
11966
  }
11959
11967
 
11960
11968
  // src/runtime/shared/err-text.mjs
11969
+ function errorHttpStatus(err) {
11970
+ return Number(err?.httpStatus || err?.status || err?.response?.status || 0) || 0;
11971
+ }
11961
11972
  function errText(e) {
11962
11973
  if (e == null) return String(e);
11963
11974
  if (typeof e === "string") return e;
@@ -12105,7 +12116,7 @@ function presentErrorText(error, options = {}) {
12105
12116
  let text = errText(error);
12106
12117
  const name = error && typeof error === "object" ? String(error.name || "") : "";
12107
12118
  const code = error && typeof error === "object" ? String(error.code || "") : "";
12108
- const status = Number(error?.httpStatus || error?.status || error?.response?.status || 0);
12119
+ const status = errorHttpStatus(error);
12109
12120
  const jsonError = extractJsonError(text);
12110
12121
  if (jsonError) text = jsonError;
12111
12122
  const embeddedError = extractEmbeddedError(text);
@@ -12266,9 +12277,6 @@ function normalizeCountMap(value = {}) {
12266
12277
  }
12267
12278
  return out;
12268
12279
  }
12269
- function plural(count, singular, pluralText = `${singular}s`) {
12270
- return count === 1 ? singular : pluralText;
12271
- }
12272
12280
  function shellResultStatus(value) {
12273
12281
  const match = String(value || "").match(/(?:^|\b)status:\s*(running|pending|queued|completed|failed|cancelled|canceled)\b/im);
12274
12282
  return match ? String(match[1] || "").toLowerCase() : "";
@@ -12342,7 +12350,7 @@ function shellDisplayStatus({ pending = false, failedCount = 0, exitFailedCount
12342
12350
  }
12343
12351
  function shellHeader(status, count = 1, verifying = false) {
12344
12352
  const n = Math.max(1, Number(count) || 1);
12345
- const object = `${n} ${plural(n, "command")}`;
12353
+ const object = `${n} ${pluralize(n, "command")}`;
12346
12354
  if (verifying && status === "running") return `Verifying ${object}`;
12347
12355
  if (verifying && status === "completed") return `Verified ${object}`;
12348
12356
  if (status === "running") return `Running ${object}`;
@@ -12358,8 +12366,16 @@ var SKILL_SURFACE_NAMES = /* @__PURE__ */ new Set([
12358
12366
  "skills_list",
12359
12367
  "use_skill"
12360
12368
  ]);
12369
+ var BACKGROUND_TASK_TOOL_NAMES = /* @__PURE__ */ new Set([
12370
+ "web_search",
12371
+ "shell",
12372
+ "bash",
12373
+ "bash_session",
12374
+ "shell_command",
12375
+ "task"
12376
+ ]);
12361
12377
  function isBackgroundTaskTool(normalizedName) {
12362
- return (/* @__PURE__ */ new Set(["web_search", "shell", "bash", "bash_session", "shell_command", "task"])).has(String(normalizedName || "").toLowerCase());
12378
+ return BACKGROUND_TASK_TOOL_NAMES.has(String(normalizedName || "").toLowerCase());
12363
12379
  }
12364
12380
  var AGENT_DISPLAY_NAMES2 = /* @__PURE__ */ new Map([
12365
12381
  ["maintainer", "Maintainer"],
@@ -13348,9 +13364,9 @@ function isAgentResponseResultText(text) {
13348
13364
  if (/^(?:background task\b|agent task:|task_id:)/i.test(value) && !/\n\s*\n[\s\S]*\S/.test(value)) return false;
13349
13365
  return true;
13350
13366
  }
13351
- var BACKGROUND_TASK_TOOL_NAMES = /* @__PURE__ */ new Set(["web_search", "shell", "bash", "bash_session", "shell_command", "task"]);
13367
+ var BACKGROUND_TASK_TOOL_NAMES2 = /* @__PURE__ */ new Set(["web_search", "shell", "bash", "bash_session", "shell_command", "task"]);
13352
13368
  function isBackgroundTaskToolName(normalizedName) {
13353
- return BACKGROUND_TASK_TOOL_NAMES.has(String(normalizedName || "").toLowerCase());
13369
+ return BACKGROUND_TASK_TOOL_NAMES2.has(String(normalizedName || "").toLowerCase());
13354
13370
  }
13355
13371
  function parseBackgroundTaskResultForRows(value) {
13356
13372
  const text = String(value || "").trim();
@@ -22648,8 +22664,161 @@ function useTerminalChrome({ stdout: stdout2, isRawModeSupported, setResizeState
22648
22664
 
22649
22665
  // src/tui/app/use-transcript-window.mjs
22650
22666
  import { useCallback as useCallback11, useEffect as useEffect12, useLayoutEffect as useLayoutEffect4, useMemo as useMemo4, useRef as useRef13 } from "react";
22651
- var HARVEST_BUMP_STREAK_LIMIT = 10;
22667
+
22668
+ // src/tui/session/transcript-spill.mjs
22669
+ import { randomUUID } from "node:crypto";
22670
+
22671
+ // src/runtime/attachments/store.mjs
22672
+ import {
22673
+ readdir as readdir2,
22674
+ readFile as readFileAsync3,
22675
+ stat as stat2,
22676
+ unlink
22677
+ } from "node:fs/promises";
22678
+ import { join as join10 } from "node:path";
22679
+
22680
+ // src/runtime/attachments/pdfjs-runtime.mjs
22681
+ import { definePDFJSModule } from "unpdf";
22682
+
22683
+ // src/runtime/attachments/pdf-extract.mjs
22684
+ var DEFAULT_MAX_OUTPUT_BYTES = 1024 * 1024;
22685
+
22686
+ // src/runtime/attachments/store.mjs
22687
+ var ATTACHMENT_REF_RE = /^[a-f0-9]{64}$/;
22688
+ var MAX_PROMPT_TEXT_BYTES = 1024 * 1024;
22689
+ var MAX_PROMPT_PDF_BYTES = 20 * 1024 * 1024;
22690
+ var ATTACHMENT_CACHE_MAX_BYTES = 64 * 1024 * 1024;
22691
+ var MAX_ATTACHMENT_BLOB_BYTES = 64 * 1024 * 1024;
22692
+ var ATTACHMENT_GC_MIN_AGE_MS = Math.max(
22693
+ 6e4,
22694
+ Number(process.env.MIXDOG_ATTACHMENT_GC_MIN_AGE_MS) || 7 * 24 * 60 * 60 * 1e3
22695
+ );
22696
+ var ATTACHMENT_GC_INTERVAL_MS = 6 * 60 * 60 * 1e3;
22697
+ var ATTACHMENT_GC_START_DELAY_MS = 5e3;
22698
+ var bufferCache = /* @__PURE__ */ new Map();
22699
+ var bufferCacheBytes = 0;
22700
+ var attachmentGcTimer = null;
22701
+ var lastAttachmentGcAt = 0;
22702
+ function attachmentsDir() {
22703
+ return join10(resolvePluginData(), "prompt-attachments", "sha256");
22704
+ }
22705
+ function dropCachedAttachment(path2) {
22706
+ const cached = bufferCache.get(path2);
22707
+ if (!cached) return;
22708
+ bufferCache.delete(path2);
22709
+ bufferCacheBytes -= cached.length;
22710
+ }
22711
+ async function persistedAttachmentReferencePaths() {
22712
+ const root = resolvePluginData();
22713
+ const paths = [];
22714
+ for (const dirname10 of ["sessions", "turn-checkpoints"]) {
22715
+ const dir = join10(root, dirname10);
22716
+ let entries;
22717
+ try {
22718
+ entries = await readdir2(dir, { withFileTypes: true });
22719
+ } catch (error) {
22720
+ if (error?.code === "ENOENT") continue;
22721
+ throw error;
22722
+ }
22723
+ for (const entry of entries) {
22724
+ if (entry.isFile() && entry.name.endsWith(".json")) paths.push(join10(dir, entry.name));
22725
+ }
22726
+ }
22727
+ paths.push(join10(root, "session-pending-messages.json"));
22728
+ return paths;
22729
+ }
22730
+ async function collectPromptAttachments({
22731
+ now = Date.now(),
22732
+ minAgeMs = ATTACHMENT_GC_MIN_AGE_MS
22733
+ } = {}) {
22734
+ const referenced = /* @__PURE__ */ new Set();
22735
+ let referenceFiles = 0;
22736
+ for (const path2 of await persistedAttachmentReferencePaths()) {
22737
+ let raw;
22738
+ try {
22739
+ raw = await readFileAsync3(path2, "utf8");
22740
+ } catch (error) {
22741
+ if (error?.code === "ENOENT") continue;
22742
+ return { deleted: 0, referenced: 0, fresh: 0, scanned: 0, incomplete: true };
22743
+ }
22744
+ referenceFiles += 1;
22745
+ const regex = /"attachmentRef"\s*:\s*"([a-f0-9]{64})"/g;
22746
+ let match;
22747
+ while ((match = regex.exec(raw)) !== null) referenced.add(match[1]);
22748
+ }
22749
+ const cutoff = Number(now) - Math.max(0, Number(minAgeMs) || 0);
22750
+ let prefixes;
22751
+ try {
22752
+ prefixes = await readdir2(attachmentsDir(), { withFileTypes: true });
22753
+ } catch (error) {
22754
+ if (error?.code === "ENOENT") {
22755
+ return { deleted: 0, referenced: referenced.size, fresh: 0, scanned: 0, referenceFiles };
22756
+ }
22757
+ return { deleted: 0, referenced: referenced.size, fresh: 0, scanned: 0, referenceFiles, incomplete: true };
22758
+ }
22759
+ let deleted = 0;
22760
+ let fresh = 0;
22761
+ let scanned = 0;
22762
+ for (const prefix of prefixes) {
22763
+ if (!prefix.isDirectory() || !/^[a-f0-9]{2}$/.test(prefix.name)) continue;
22764
+ const dir = join10(attachmentsDir(), prefix.name);
22765
+ let entries;
22766
+ try {
22767
+ entries = await readdir2(dir, { withFileTypes: true });
22768
+ } catch {
22769
+ continue;
22770
+ }
22771
+ for (const entry of entries) {
22772
+ if (!entry.isFile() || !ATTACHMENT_REF_RE.test(entry.name)) continue;
22773
+ scanned += 1;
22774
+ if (referenced.has(entry.name)) continue;
22775
+ const path2 = join10(dir, entry.name);
22776
+ try {
22777
+ const first = await stat2(path2);
22778
+ if (first.mtimeMs > cutoff) {
22779
+ fresh += 1;
22780
+ continue;
22781
+ }
22782
+ const latest = await stat2(path2);
22783
+ if (latest.mtimeMs > cutoff || latest.mtimeMs !== first.mtimeMs) {
22784
+ fresh += 1;
22785
+ continue;
22786
+ }
22787
+ await unlink(path2);
22788
+ dropCachedAttachment(path2);
22789
+ deleted += 1;
22790
+ } catch (error) {
22791
+ if (error?.code !== "ENOENT") fresh += 1;
22792
+ }
22793
+ }
22794
+ }
22795
+ return { deleted, referenced: referenced.size, fresh, scanned, referenceFiles };
22796
+ }
22797
+ function armAttachmentGc(delayMs) {
22798
+ if (attachmentGcTimer) return;
22799
+ attachmentGcTimer = setTimeout(() => {
22800
+ attachmentGcTimer = null;
22801
+ void collectPromptAttachments().catch(() => void 0).finally(() => {
22802
+ lastAttachmentGcAt = Date.now();
22803
+ armAttachmentGc(ATTACHMENT_GC_INTERVAL_MS);
22804
+ });
22805
+ }, Math.max(ATTACHMENT_GC_START_DELAY_MS, Number(delayMs) || 0));
22806
+ attachmentGcTimer.unref?.();
22807
+ }
22808
+ function scheduleAttachmentGc() {
22809
+ if (attachmentGcTimer) return;
22810
+ const elapsed = Date.now() - lastAttachmentGcAt;
22811
+ armAttachmentGc(lastAttachmentGcAt === 0 ? ATTACHMENT_GC_START_DELAY_MS : ATTACHMENT_GC_INTERVAL_MS - elapsed);
22812
+ }
22813
+ scheduleAttachmentGc();
22814
+
22815
+ // src/tui/session/transcript-spill.mjs
22652
22816
  var TUI_DEBUG = /^(1|true|yes|on)$/i.test(String(process.env.MIXDOG_TUI_DEBUG || ""));
22817
+ var TRANSCRIPT_SPILL_STALE_MS = 24 * 60 * 60 * 1e3;
22818
+ var TRANSCRIPT_PROCESS_NONCE = randomUUID();
22819
+
22820
+ // src/tui/app/use-transcript-window.mjs
22821
+ var HARVEST_BUMP_STREAK_LIMIT = 10;
22653
22822
  var harvestBreakerLogged = false;
22654
22823
  function traceHarvestBreaker(changedKeys) {
22655
22824
  if (harvestBreakerLogged && !TUI_DEBUG) return;
@@ -24540,158 +24709,6 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
24540
24709
  });
24541
24710
  }
24542
24711
 
24543
- // src/tui/session/transcript-spill.mjs
24544
- import { randomUUID } from "node:crypto";
24545
-
24546
- // src/runtime/attachments/store.mjs
24547
- import {
24548
- readdir as readdir2,
24549
- readFile as readFileAsync3,
24550
- stat as stat2,
24551
- unlink
24552
- } from "node:fs/promises";
24553
- import { join as join10 } from "node:path";
24554
-
24555
- // src/runtime/attachments/pdfjs-runtime.mjs
24556
- import { definePDFJSModule } from "unpdf";
24557
-
24558
- // src/runtime/attachments/pdf-extract.mjs
24559
- var DEFAULT_MAX_OUTPUT_BYTES = 1024 * 1024;
24560
-
24561
- // src/runtime/attachments/store.mjs
24562
- var ATTACHMENT_REF_RE = /^[a-f0-9]{64}$/;
24563
- var MAX_PROMPT_TEXT_BYTES = 1024 * 1024;
24564
- var MAX_PROMPT_PDF_BYTES = 20 * 1024 * 1024;
24565
- var ATTACHMENT_CACHE_MAX_BYTES = 64 * 1024 * 1024;
24566
- var MAX_ATTACHMENT_BLOB_BYTES = 64 * 1024 * 1024;
24567
- var ATTACHMENT_GC_MIN_AGE_MS = Math.max(
24568
- 6e4,
24569
- Number(process.env.MIXDOG_ATTACHMENT_GC_MIN_AGE_MS) || 7 * 24 * 60 * 60 * 1e3
24570
- );
24571
- var ATTACHMENT_GC_INTERVAL_MS = 6 * 60 * 60 * 1e3;
24572
- var ATTACHMENT_GC_START_DELAY_MS = 5e3;
24573
- var bufferCache = /* @__PURE__ */ new Map();
24574
- var bufferCacheBytes = 0;
24575
- var attachmentGcTimer = null;
24576
- var lastAttachmentGcAt = 0;
24577
- function attachmentsDir() {
24578
- return join10(resolvePluginData(), "prompt-attachments", "sha256");
24579
- }
24580
- function dropCachedAttachment(path2) {
24581
- const cached = bufferCache.get(path2);
24582
- if (!cached) return;
24583
- bufferCache.delete(path2);
24584
- bufferCacheBytes -= cached.length;
24585
- }
24586
- async function persistedAttachmentReferencePaths() {
24587
- const root = resolvePluginData();
24588
- const paths = [];
24589
- for (const dirname10 of ["sessions", "turn-checkpoints"]) {
24590
- const dir = join10(root, dirname10);
24591
- let entries;
24592
- try {
24593
- entries = await readdir2(dir, { withFileTypes: true });
24594
- } catch (error) {
24595
- if (error?.code === "ENOENT") continue;
24596
- throw error;
24597
- }
24598
- for (const entry of entries) {
24599
- if (entry.isFile() && entry.name.endsWith(".json")) paths.push(join10(dir, entry.name));
24600
- }
24601
- }
24602
- paths.push(join10(root, "session-pending-messages.json"));
24603
- return paths;
24604
- }
24605
- async function collectPromptAttachments({
24606
- now = Date.now(),
24607
- minAgeMs = ATTACHMENT_GC_MIN_AGE_MS
24608
- } = {}) {
24609
- const referenced = /* @__PURE__ */ new Set();
24610
- let referenceFiles = 0;
24611
- for (const path2 of await persistedAttachmentReferencePaths()) {
24612
- let raw;
24613
- try {
24614
- raw = await readFileAsync3(path2, "utf8");
24615
- } catch (error) {
24616
- if (error?.code === "ENOENT") continue;
24617
- return { deleted: 0, referenced: 0, fresh: 0, scanned: 0, incomplete: true };
24618
- }
24619
- referenceFiles += 1;
24620
- const regex = /"attachmentRef"\s*:\s*"([a-f0-9]{64})"/g;
24621
- let match;
24622
- while ((match = regex.exec(raw)) !== null) referenced.add(match[1]);
24623
- }
24624
- const cutoff = Number(now) - Math.max(0, Number(minAgeMs) || 0);
24625
- let prefixes;
24626
- try {
24627
- prefixes = await readdir2(attachmentsDir(), { withFileTypes: true });
24628
- } catch (error) {
24629
- if (error?.code === "ENOENT") {
24630
- return { deleted: 0, referenced: referenced.size, fresh: 0, scanned: 0, referenceFiles };
24631
- }
24632
- return { deleted: 0, referenced: referenced.size, fresh: 0, scanned: 0, referenceFiles, incomplete: true };
24633
- }
24634
- let deleted = 0;
24635
- let fresh = 0;
24636
- let scanned = 0;
24637
- for (const prefix of prefixes) {
24638
- if (!prefix.isDirectory() || !/^[a-f0-9]{2}$/.test(prefix.name)) continue;
24639
- const dir = join10(attachmentsDir(), prefix.name);
24640
- let entries;
24641
- try {
24642
- entries = await readdir2(dir, { withFileTypes: true });
24643
- } catch {
24644
- continue;
24645
- }
24646
- for (const entry of entries) {
24647
- if (!entry.isFile() || !ATTACHMENT_REF_RE.test(entry.name)) continue;
24648
- scanned += 1;
24649
- if (referenced.has(entry.name)) continue;
24650
- const path2 = join10(dir, entry.name);
24651
- try {
24652
- const first = await stat2(path2);
24653
- if (first.mtimeMs > cutoff) {
24654
- fresh += 1;
24655
- continue;
24656
- }
24657
- const latest = await stat2(path2);
24658
- if (latest.mtimeMs > cutoff || latest.mtimeMs !== first.mtimeMs) {
24659
- fresh += 1;
24660
- continue;
24661
- }
24662
- await unlink(path2);
24663
- dropCachedAttachment(path2);
24664
- deleted += 1;
24665
- } catch (error) {
24666
- if (error?.code !== "ENOENT") fresh += 1;
24667
- }
24668
- }
24669
- }
24670
- return { deleted, referenced: referenced.size, fresh, scanned, referenceFiles };
24671
- }
24672
- function armAttachmentGc(delayMs) {
24673
- if (attachmentGcTimer) return;
24674
- attachmentGcTimer = setTimeout(() => {
24675
- attachmentGcTimer = null;
24676
- void collectPromptAttachments().catch(() => void 0).finally(() => {
24677
- lastAttachmentGcAt = Date.now();
24678
- armAttachmentGc(ATTACHMENT_GC_INTERVAL_MS);
24679
- });
24680
- }, Math.max(ATTACHMENT_GC_START_DELAY_MS, Number(delayMs) || 0));
24681
- attachmentGcTimer.unref?.();
24682
- }
24683
- function scheduleAttachmentGc() {
24684
- if (attachmentGcTimer) return;
24685
- const elapsed = Date.now() - lastAttachmentGcAt;
24686
- armAttachmentGc(lastAttachmentGcAt === 0 ? ATTACHMENT_GC_START_DELAY_MS : ATTACHMENT_GC_INTERVAL_MS - elapsed);
24687
- }
24688
- scheduleAttachmentGc();
24689
-
24690
- // src/tui/session/transcript-spill.mjs
24691
- var TUI_DEBUG2 = /^(1|true|yes|on)$/i.test(String(process.env.MIXDOG_TUI_DEBUG || ""));
24692
- var TRANSCRIPT_SPILL_STALE_MS = 24 * 60 * 60 * 1e3;
24693
- var TRANSCRIPT_PROCESS_NONCE = randomUUID();
24694
-
24695
24712
  // src/tui/session.mjs
24696
24713
  async function createSessionRuntime(options = {}) {
24697
24714
  const { createSession } = await import("../../standalone/session-client.mjs");