mixdog 1.4.0 → 1.4.1

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 (236) hide show
  1. package/package.json +1 -1
  2. package/scripts/check-voice-runtime-inputs.mjs +25 -0
  3. package/scripts/gate-local.mjs +12 -3
  4. package/scripts/latest-guard.mjs +21 -9
  5. package/scripts/lib/isolated-test-env.mjs +10 -5
  6. package/scripts/lib/run-node-tests.mjs +37 -37
  7. package/scripts/lib/scoped-temp.d.mts +16 -0
  8. package/scripts/lib/scoped-temp.mjs +123 -0
  9. package/scripts/lib/stale-temp.mjs +44 -0
  10. package/scripts/post-release-check.mjs +1 -6
  11. package/scripts/pptx-kit-index.mjs +17 -4
  12. package/scripts/suite-health.mjs +10 -1
  13. package/scripts/test-data-dir.mjs +10 -7
  14. package/src/app.mjs +4 -0
  15. package/src/defaults/shipped-history.json +5 -0
  16. package/src/defaults/skills/browser-use/SKILL.md +6 -4
  17. package/src/defaults/skills/computer-use/SKILL.md +4 -2
  18. package/src/lib/rules-builder.cjs +29 -12
  19. package/src/output-styles/common.md +2 -2
  20. package/src/output-styles/simple.md +1 -1
  21. package/src/rules/agent/AGENT.md +5 -4
  22. package/src/rules/lead/LEAD.md +10 -5
  23. package/src/rules/shared/10-tool-workflow.md +3 -1
  24. package/src/rules/shared/45-destructive.md +0 -2
  25. package/src/rules/shared/50-execution.md +2 -0
  26. package/src/rules/shared/70-delivery.md +7 -9
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
  28. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
  29. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +1 -1
  30. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +3 -1
  31. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
  32. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +11 -0
  33. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
  34. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
  35. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
  36. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
  37. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
  38. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
  39. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -3
  40. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +6 -0
  41. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
  42. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
  43. package/src/runtime/agent/orchestrator/providers/cursor.mjs +3 -0
  44. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
  45. package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
  46. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
  47. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
  48. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
  49. package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
  50. package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
  51. package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
  52. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
  53. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
  54. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
  55. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
  56. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
  57. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
  58. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
  59. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
  60. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
  61. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
  62. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
  63. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
  64. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
  65. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
  66. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +136 -5
  67. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
  68. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
  69. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
  70. package/src/runtime/agent/orchestrator/providers/registry.mjs +12 -0
  71. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +41 -13
  72. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
  73. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +7 -3
  74. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
  75. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
  76. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
  77. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +8 -2
  78. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  79. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
  80. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
  81. package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
  82. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +160 -36
  83. package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
  84. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
  85. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
  86. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
  87. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
  88. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +90 -22
  89. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +33 -3
  90. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +7 -2
  91. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
  92. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
  93. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +14 -0
  94. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +13 -1
  95. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +2 -2
  96. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +39 -21
  97. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
  98. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
  99. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +2 -2
  100. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +2 -1
  101. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
  102. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +61 -6
  103. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -8
  104. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
  105. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -3
  106. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
  107. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +3 -0
  108. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
  109. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +5 -1
  110. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +30 -7
  111. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
  112. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
  113. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
  114. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
  115. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +37 -8
  116. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +9 -1
  117. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +61 -2
  118. package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
  119. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
  120. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
  121. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
  122. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -20
  123. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
  124. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
  125. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
  126. package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
  127. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
  128. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
  129. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
  130. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
  131. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
  132. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
  133. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
  134. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
  135. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  136. package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
  137. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +26 -4
  138. package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
  139. package/src/runtime/channels/lib/whisper-port.mjs +10 -1
  140. package/src/runtime/computer-bridge/action-schema.mjs +2 -2
  141. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  142. package/src/runtime/computer-bridge/error-recovery.mjs +5 -4
  143. package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
  144. package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
  145. package/src/runtime/local-provider/server-process.mjs +2 -1
  146. package/src/runtime/media/adapters/gemini-video.mjs +4 -1
  147. package/src/runtime/media/adapters/xai-media.mjs +2 -1
  148. package/src/runtime/memory/lib/embedding-worker.mjs +6 -3
  149. package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
  150. package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
  151. package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
  152. package/src/runtime/office/design/design-art-direction.mjs +29 -27
  153. package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
  154. package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
  155. package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
  156. package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
  157. package/src/runtime/office/quality/assurance-structure-docx.mjs +3 -1
  158. package/src/runtime/office/quality/design-review.mjs +1 -5
  159. package/src/runtime/office/quality/document-brief.mjs +1 -5
  160. package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
  161. package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
  162. package/src/runtime/shared/bot-owned-work.mjs +56 -0
  163. package/src/runtime/shared/defaults-separation.mjs +1 -4
  164. package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
  165. package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
  166. package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
  167. package/src/runtime/shared/handoff-artifacts.mjs +18 -8
  168. package/src/runtime/shared/idle-auto-clear-gate.mjs +29 -7
  169. package/src/runtime/shared/llm/cost.mjs +5 -1
  170. package/src/runtime/shared/loopback-listener.mjs +25 -2
  171. package/src/runtime/shared/model-route-chain.d.mts +7 -2
  172. package/src/runtime/shared/model-route-chain.mjs +22 -4
  173. package/src/runtime/shared/open-url.mjs +10 -0
  174. package/src/runtime/shared/session-activity-signal.mjs +14 -0
  175. package/src/runtime/shared/session-scratch.mjs +37 -0
  176. package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
  177. package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
  178. package/src/runtime/shared/tool-result-summary.mjs +1 -1
  179. package/src/runtime/shared/tool-surface.mjs +3 -0
  180. package/src/runtime/shared/tool-work-units.mjs +2 -0
  181. package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
  182. package/src/runtime/shared/worktrees/contract.mjs +4 -1
  183. package/src/runtime/shared/worktrees/git.mjs +15 -0
  184. package/src/runtime/shared/worktrees/manager.mjs +87 -38
  185. package/src/runtime/shared/worktrees/test-support.mjs +6 -10
  186. package/src/runtime/visualize-bridge/client.mjs +2 -0
  187. package/src/session-runtime/agent-home-delivery.mjs +41 -0
  188. package/src/session-runtime/agent-task-sessions.mjs +152 -63
  189. package/src/session-runtime/agent-tool-routing.mjs +8 -41
  190. package/src/session-runtime/boot/tools.mjs +5 -1
  191. package/src/session-runtime/bot-status.mjs +12 -6
  192. package/src/session-runtime/bot-target.mjs +38 -0
  193. package/src/session-runtime/channel-config-api.mjs +6 -1
  194. package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
  195. package/src/session-runtime/conversation-import/discovery.mjs +271 -25
  196. package/src/session-runtime/conversation-import/service.mjs +26 -5
  197. package/src/session-runtime/handoff-attachments.mjs +82 -31
  198. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +12 -13
  199. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +1 -0
  200. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
  201. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
  202. package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
  203. package/src/session-runtime/lifecycle/session-catalog.mjs +9 -1
  204. package/src/session-runtime/model-route/set-route.mjs +11 -2
  205. package/src/session-runtime/provider-catalog-cache.mjs +82 -36
  206. package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
  207. package/src/session-runtime/provider-models.mjs +4 -2
  208. package/src/session-runtime/resource-recall-api.mjs +6 -1
  209. package/src/session-runtime/runtime-feature-gates.mjs +5 -1
  210. package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
  211. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
  212. package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
  213. package/src/session-runtime/services/agent-tool/render.mjs +71 -17
  214. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +6 -2
  215. package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
  216. package/src/session-runtime/services/provider-admin.mjs +2 -1
  217. package/src/session-runtime/tool-policy/policy-stage.mjs +1 -0
  218. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
  219. package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
  220. package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
  221. package/src/session-runtime/workspace/transitions.mjs +25 -0
  222. package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
  223. package/src/standalone/daemon-session-control.mjs +18 -2
  224. package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
  225. package/src/standalone/session-service/session-calls/session-action.mjs +10 -3
  226. package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
  227. package/src/tui/app/app-view/floating-panel.jsx +7 -4
  228. package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
  229. package/src/tui/app/model-picker/route-selection.mjs +5 -6
  230. package/src/tui/app/provider-setup/oauth-actions.mjs +38 -20
  231. package/src/tui/app/provider-setup/provider-items.mjs +8 -2
  232. package/src/tui/app/provider-setup-picker.mjs +9 -5
  233. package/src/tui/components/QuestionPanel.jsx +13 -4
  234. package/src/tui/dist/index.mjs +75 -28
  235. package/src/tui/session/session-flow/queue/take-entries.mjs +11 -0
  236. package/src/ui/statusline-agents.mjs +1 -3
@@ -8,11 +8,15 @@ import {
8
8
  // A shared scan's outcome belongs to every subscriber, not only the caller
9
9
  // whose computation won admission. Persisted cache hits contain safe text.
10
10
  export async function runScopedSearchInFlight(key, compute, options, outcome) {
11
- const settled = await runResultCacheInFlight(key, async ({ signal }) => {
12
- const scopedCacheOutcome = createScopedCacheOutcome();
13
- const result = await compute({ signal, scopedCacheOutcome });
14
- return { result, scopedCacheOutcome };
15
- }, options);
11
+ const settled = await runResultCacheInFlight(
12
+ key,
13
+ async ({ signal }) => {
14
+ const scopedCacheOutcome = createScopedCacheOutcome();
15
+ const result = await compute({ signal, scopedCacheOutcome });
16
+ return { result, scopedCacheOutcome };
17
+ },
18
+ options
19
+ );
16
20
  if (typeof settled === 'string') return settled;
17
21
  if (settled.scopedCacheOutcome.complete === false) markScopedCacheIncomplete(outcome);
18
22
  if (settled.scopedCacheOutcome.cacheSafe === false) markScopedCacheUnsafe(outcome);
@@ -53,7 +53,13 @@ export async function streamRangeResult(ctx, { source, fileHandle, prefixBuffer
53
53
  res.firstEmitted && res.lastEmitted ? [{ startLine: res.firstEmitted, endLine: res.lastEmitted }] : [];
54
54
  const snapshotMeta = { source, ranges, rangeHashes: _rangeHashesFromRenderedReadText(res.text, ranges) };
55
55
  if (!res.readSnapshotStat) return res.text;
56
- return await commitStreamResult({ ...ctx, st: res.readSnapshotStat }, res.text, snapshotMeta, res.prefixHash, helpers);
56
+ return await commitStreamResult(
57
+ { ...ctx, st: res.readSnapshotStat },
58
+ res.text,
59
+ snapshotMeta,
60
+ res.prefixHash,
61
+ helpers
62
+ );
57
63
  } catch (err) {
58
64
  return `Error: ${normalizeErrorMessage(err instanceof Error ? err.message : String(err))}`;
59
65
  }
@@ -137,9 +137,12 @@ async function readRangeFromHandle(fh, fullPath, offset, limit, stHint, hooks) {
137
137
  }
138
138
  if (!stop) lines.finishTail();
139
139
  let readSnapshotStat = null;
140
- if (!(await publishReadRangeIndex(rangeIndex, fh, null, checkDeadline, (version) => {
141
- readSnapshotStat = version;
142
- }))) checkDeadline();
140
+ if (
141
+ !(await publishReadRangeIndex(rangeIndex, fh, null, checkDeadline, (version) => {
142
+ readSnapshotStat = version;
143
+ }))
144
+ )
145
+ checkDeadline();
143
146
 
144
147
  ioTraceDone('read_range_stream', traceStart, {
145
148
  pathHash: hashText(fullPath).slice(0, 12),
@@ -41,7 +41,7 @@ async function estimateTaskBytes(entry, workDir) {
41
41
  const st = await stat(resolvePath(workDir || '.', String(entry?.path || ''))).catch(() => null);
42
42
  if (!st?.isFile()) return Infinity;
43
43
  const lines = Math.max(1, st.size / AVG_LINE_BYTES);
44
- let need = st.size + st.size / MIN_LINE_BYTES * LINE_PREFIX_BYTES;
44
+ let need = st.size + (st.size / MIN_LINE_BYTES) * LINE_PREFIX_BYTES;
45
45
  // A coalesced entry reads its whole union window, not only its own slot.
46
46
  const limit = Number(readEntryCoalescedDiskWindow(entry)?.limit ?? entry?.limit);
47
47
  if (Number.isFinite(limit) && limit > 0) need *= Math.min(1, limit / lines);
@@ -85,10 +85,14 @@ export async function runBatchReadSnapshotPublication(executeChildBuiltinTool, h
85
85
  // A numbered row may end halfway through its content at the byte cap.
86
86
  // Only this slot's producer can certify complete lines; another read of
87
87
  // the same path must not authorize hashing this slot's partial text.
88
- return mergeReadRanges(ranges.flatMap((range) => (observation?.ranges ?? []).map((complete) => ({
89
- startLine: Math.max(range.startLine, complete.startLine),
90
- endLine: Math.min(range.endLine, complete.endLine),
91
- }))));
88
+ return mergeReadRanges(
89
+ ranges.flatMap((range) =>
90
+ (observation?.ranges ?? []).map((complete) => ({
91
+ startLine: Math.max(range.startLine, complete.startLine),
92
+ endLine: Math.min(range.endLine, complete.endLine),
93
+ }))
94
+ )
95
+ );
92
96
  },
93
97
  _recordReadSnapshot: (fullPath, _st, scope, meta) => {
94
98
  corrections.set(fullPath, { scope: scope ?? null, meta });
@@ -104,22 +108,29 @@ export async function runBatchReadSnapshotPublication(executeChildBuiltinTool, h
104
108
  }
105
109
  for (const [fullPath, correction] of corrections) {
106
110
  const delivered = tasks.filter((task) => task.fullPath === fullPath && hasRenderedLines(task.body));
107
- const observations = delivered.map((task) => task.records.findLast(
108
- (record) => record.fullPath === fullPath && record.scope === correction.scope
109
- ));
111
+ const observations = delivered.map((task) =>
112
+ task.records.findLast((record) => record.fullPath === fullPath && record.scope === correction.scope)
113
+ );
110
114
  // Never combine different versions or bless stale/missing observations.
111
115
  // The eventual recorder rechecks the retained lease after all awaits.
112
- if (observations.length && observations.every((record) =>
113
- record?.isCurrent() && sameFileVersion(record.identity, observations[0].identity)
114
- )) {
116
+ if (
117
+ observations.length &&
118
+ observations.every(
119
+ (record) => record?.isCurrent() && sameFileVersion(record.identity, observations[0].identity)
120
+ )
121
+ ) {
115
122
  observations[0].publish(correction.meta);
116
123
  }
117
124
  }
118
125
  // Rich media/binary results have no line slices. Preserve their original
119
126
  // evidence, still under the producer's lease rather than the batch's.
120
127
  for (const task of tasks) {
121
- if (hasRenderedLines(task.body) || task.body?.isError === true ||
122
- (typeof task.body === 'string' && helpers.classifyResultKind(task.body) === 'error')) continue;
128
+ if (
129
+ hasRenderedLines(task.body) ||
130
+ task.body?.isError === true ||
131
+ (typeof task.body === 'string' && helpers.classifyResultKind(task.body) === 'error')
132
+ )
133
+ continue;
123
134
  for (const record of task.records) {
124
135
  if (!corrections.has(record.fullPath)) record.publish();
125
136
  }
@@ -69,7 +69,12 @@ async function rawRangeHashes(fullPath, mergedRanges, { _hashText }) {
69
69
 
70
70
  export async function recordSlicedBatchSnapshots(orderedResults, workDir, readStateScope, helpers) {
71
71
  const { _mergeReadRanges, _recordReadSnapshot } = helpers;
72
- const { exactRangesByPath, rangeHashesByPath } = deliveredRangesByPath(orderedResults, workDir, readStateScope, helpers);
72
+ const { exactRangesByPath, rangeHashesByPath } = deliveredRangesByPath(
73
+ orderedResults,
74
+ workDir,
75
+ readStateScope,
76
+ helpers
77
+ );
73
78
  for (const [fullPath, ranges] of exactRangesByPath) {
74
79
  const mergedRanges = _mergeReadRanges(ranges);
75
80
  let rangeHashes = rangeHashesByPath.get(fullPath) || [];
@@ -112,14 +112,7 @@ export async function executeReadTool(args, ...rest) {
112
112
  return `${out}\n[skipped ${skipped.length} more file(s) over the per-call limit: ${skipped.join(', ')} — read them in another call]`;
113
113
  }
114
114
 
115
- async function executeReadToolBody(
116
- args,
117
- workDir,
118
- readStateScope,
119
- executeChildBuiltinTool,
120
- options = {},
121
- helpers = {}
122
- ) {
115
+ async function executeReadToolBody(args, workDir, readStateScope, executeChildBuiltinTool, options = {}, helpers = {}) {
123
116
  const { normalizeInputPath, normaliseReadLineWindowArgs } = helpers;
124
117
  applyFilePathAlias(args);
125
118
  args.path = coerceReadFamilyPathArg(args.path);
@@ -129,7 +129,9 @@ function federateRoots(name, args, plan, signal, options, execute) {
129
129
  }
130
130
  const runOne = async (root, nextArgs) =>
131
131
  execute(name, nextArgs, root, signal, { ...options, excludedProjectRoots: excludedRootsFor(root, roots) });
132
- const work = _runCodeGraphFederation(roots, runOne, projectArgs, options.scopedCacheOutcome).then((sections) => sections.join('\n\n'));
132
+ const work = _runCodeGraphFederation(roots, runOne, projectArgs, options.scopedCacheOutcome).then((sections) =>
133
+ sections.join('\n\n')
134
+ );
133
135
  return raceAbort(work, signal);
134
136
  }
135
137
 
@@ -26,7 +26,7 @@ export const CODE_GRAPH_TOOL_DEFS = [
26
26
  compressibleLossless: true,
27
27
  },
28
28
  description:
29
- 'Code structure and relations from the parsed graph, no text matching. symbols → file outline rows `[export ]kind name (Lstart-end) signature`; find_symbol returns declaration/body; references adds usages (body opt-in); callers/callees return locations; dependents/impact → importers and blast radius. Exact identifiers: find_symbol/references/callers/callees; keywords: symbol_search/search; literal text and regex belong to grep. Prefer it over read/grep for declarations and relations; every row’s location is a read window. symbols already outlines a file: never pair it with overview for one need.',
29
+ 'Code structure and relations from the parsed graph, no text matching. symbols → file outline rows `[export ]kind name (Lstart-end) signature`; find_symbol returns declaration/body; references adds usages; callers/callees return locations; dependents/impact → importers and blast radius. Exact identifiers: find_symbol/references/callers/callees; keywords: symbol_search/search; literal text and regex belong to grep. Prefer it over read/grep for declarations and relations. symbols already outlines a file: never pair it with overview for one need.',
30
30
  inputSchema: {
31
31
  type: 'object',
32
32
  properties: {
@@ -1,30 +1,30 @@
1
1
  {
2
- "version": "0.1.33",
2
+ "version": "0.1.34",
3
3
  "_comment": "Synced from immutable graph-v release assets.",
4
4
  "assets": {
5
5
  "darwin-arm64": {
6
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-darwin-arm64",
7
- "sha256": "8637d61493eddca3eee80620a64e737f12eead44ea899ad19a18966a3843ff3a"
6
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-darwin-arm64",
7
+ "sha256": "5bcf8c79135224d2e77eec70a57debd06d462bab01418ce1a6c1656a858eedad"
8
8
  },
9
9
  "darwin-x64": {
10
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-darwin-x64",
11
- "sha256": "49ce311687c3df7e7080ecb7694219c9b51bbbb272864aa43d2102a8baa83550"
10
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-darwin-x64",
11
+ "sha256": "2845ea2afa2802841589bd74c8785670cfe8c6b58b2ad5b258ac928afccbaa94"
12
12
  },
13
13
  "linux-arm64": {
14
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-linux-arm64",
15
- "sha256": "2e2a4ea6dccc5b33f583040b0ee6e8d47f93a1e879eb17343acd0b2f9838696f"
14
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-linux-arm64",
15
+ "sha256": "0364bc1c3741683fbdb45ed755f2baabb50a0556e2354c13a05f3d816bc1c461"
16
16
  },
17
17
  "linux-x64": {
18
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-linux-x64",
19
- "sha256": "2cd1caa7f39e183d6fb6f7764f49e9a0643863d137c2bfb5f40bb7ac616c8d73"
18
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-linux-x64",
19
+ "sha256": "4f9091b2c5a89631efade89aae17e5411dda8bfec99e15ff64948906f9fa20d0"
20
20
  },
21
21
  "win32-arm64": {
22
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-win32-arm64.exe",
23
- "sha256": "592dfa7e95e1e91424c7467e74f35d09758de502be403b7d229444b435600392"
22
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-win32-arm64.exe",
23
+ "sha256": "03abef6f09b095b86c5cc32c6bead3f5d82f77961220c31221ab0b3f60974110"
24
24
  },
25
25
  "win32-x64": {
26
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-win32-x64.exe",
27
- "sha256": "0ed17859a39f0160421865f3a3486ce53957b836ee164d606434519b85b90830"
26
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-win32-x64.exe",
27
+ "sha256": "650cffe82ccbe9898e7ac8fc9b025c92098a810ad3ca95276c0bb8c19a328993"
28
28
  }
29
29
  }
30
30
  }
@@ -1,9 +1,10 @@
1
- import { mkdirSync, mkdtempSync } from 'node:fs';
2
- import { tmpdir } from 'node:os';
1
+ import { mkdirSync } from 'node:fs';
3
2
  import { join } from 'node:path';
3
+ import { makeTempDirSync } from '../../../../../../scripts/lib/scoped-temp.mjs';
4
4
 
5
5
  // Import before runtime modules: several paths are captured at module load.
6
- export const fixtureRoot = mkdtempSync(join(tmpdir(), 'mixdog-shell-fixture-'));
6
+ // Removed when the importing test process exits.
7
+ export const fixtureRoot = makeTempDirSync('shell-fixture');
7
8
  for (const name of [
8
9
  'HOME',
9
10
  'USERPROFILE',
@@ -55,8 +55,13 @@ function _disabled() {
55
55
  return process.env.MIXDOG_SHELL_WARM_STANDBY === '0';
56
56
  }
57
57
 
58
+ // Per-session scratch variables: they differ between sessions by design, so
59
+ // they stay out of the reuse signature and are set in the hand-off prelude.
60
+ const SCRATCH_ENV_KEYS = Object.freeze(['TEMP', 'TMP', 'TMPDIR']);
61
+
58
62
  function envSignature(env) {
59
63
  const entries = Object.entries(env || {})
64
+ .filter(([key]) => !SCRATCH_ENV_KEYS.includes(key))
60
65
  .map(([key, value]) => `${key}=${value}`)
61
66
  .sort()
62
67
  .join('\n');
@@ -67,8 +72,16 @@ function _slotAlive(slot) {
67
72
  return Boolean(slot?.native?.child && slot.native.child.exitCode == null && !slot.native.child.killed);
68
73
  }
69
74
 
70
- function psQuote(value) {
71
- return String(value).replace(/'/g, "''");
75
+ // A PowerShell expression yielding `value` for any text. PowerShell quoting has
76
+ // no safe form for typographic apostrophes and the like, so the value travels
77
+ // as UTF-8 Base64 and is decoded inside the expression.
78
+ function psStringExpr(value) {
79
+ return `[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${Buffer.from(String(value), 'utf8').toString('base64')}'))`;
80
+ }
81
+
82
+ /** The parked standby slot, for tests. */
83
+ export function _parkedShellStandbyForTest() {
84
+ return _slot;
72
85
  }
73
86
 
74
87
  /** Pre-spawn the next standby (fire-and-forget; a live one is kept). */
@@ -164,9 +177,18 @@ export function takeWarmShellStandby({ shell, env }) {
164
177
  // cwd prelude: the standby was spawned in the daemon cwd. Set-Location
165
178
  // fixes $PWD and native-child working dirs; Environment.CurrentDirectory
166
179
  // fixes .NET relative-path APIs.
167
- const prelude = workDir
168
- ? `Set-Location -LiteralPath '${psQuote(workDir)}'; [System.Environment]::CurrentDirectory = '${psQuote(workDir)}'; `
180
+ const cwdPrelude = workDir
181
+ ? `$__mixdogCwd = ${psStringExpr(workDir)}; Set-Location -LiteralPath $__mixdogCwd; [System.Environment]::CurrentDirectory = $__mixdogCwd; `
169
182
  : '';
183
+ // Scratch prelude: the standby was spawned for whichever session parked
184
+ // it. Set (or clear, when the request has none) the requested values
185
+ // before the command runs, so no other session's scratch path survives.
186
+ const scratchPrelude = SCRATCH_ENV_KEYS.map((key) =>
187
+ typeof env?.[key] === 'string'
188
+ ? `$env:${key} = ${psStringExpr(env[key])}; `
189
+ : `Remove-Item -LiteralPath 'Env:${key}' -ErrorAction SilentlyContinue; `
190
+ ).join('');
191
+ const prelude = scratchPrelude + cwdPrelude;
170
192
  // Single atomic write+EOF: a separate close message can race ahead
171
193
  // of the server's async write thread and feed an empty script.
172
194
  slot.native.child.writeStdin(prelude + String(commandText ?? ''), { close: true });
@@ -46,7 +46,10 @@ function verifySignature(secret, rawBody, signatureValue, parser) {
46
46
  if (!vMatch || !tMatch) return false;
47
47
  const ts = Number(tMatch[1]);
48
48
  if (!Number.isFinite(ts) || Math.abs(Date.now() - ts * 1000) > STRIPE_TOLERANCE_MS) return false;
49
- const expected = crypto.createHmac('sha256', secret).update(Buffer.concat([Buffer.from(`${tMatch[1]}.`), Buffer.from(rawBody)])).digest('hex');
49
+ const expected = crypto
50
+ .createHmac('sha256', secret)
51
+ .update(Buffer.concat([Buffer.from(`${tMatch[1]}.`), Buffer.from(rawBody)]))
52
+ .digest('hex');
50
53
  return hexDigestsEqual(vMatch[1], expected);
51
54
  }
52
55
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
@@ -1,6 +1,7 @@
1
1
  import net from 'node:net';
2
2
  import path from 'node:path';
3
3
  import { execFile } from 'node:child_process';
4
+ import { FETCH_BLOCKED_PORTS, FETCH_SAFE_ATTEMPTS } from '../../shared/fetch-safe-listen.mjs';
4
5
 
5
6
  // whisper.cpp cannot bind port 0 itself. Ask the OS for an available port,
6
7
  // release the reservation immediately before spawn, then verify the listener's
@@ -15,9 +16,17 @@ export function selectWhisperPort(host, preferred) {
15
16
  server.close((error) => (error ? reject(error) : resolve(selected)));
16
17
  });
17
18
  });
19
+ // The server is reached with fetch, which refuses a "bad port" the OS may assign.
20
+ const reserveFetchSafe = async () => {
21
+ for (let attempt = 0; attempt <= FETCH_SAFE_ATTEMPTS; attempt += 1) {
22
+ const port = await reserve(0);
23
+ if (!FETCH_BLOCKED_PORTS.has(port)) return port;
24
+ }
25
+ throw new Error('no fetch-safe loopback port was assigned');
26
+ };
18
27
  return reserve(preferred).catch((error) => {
19
28
  if (error.code !== 'EADDRINUSE' && error.code !== 'EACCES') throw error;
20
- return reserve(0);
29
+ return reserveFetchSafe();
21
30
  });
22
31
  }
23
32
 
@@ -362,13 +362,13 @@ export const COMPUTER_ACTION_CONTRACTS = [
362
362
  type: 'string',
363
363
  minLength: 1,
364
364
  description:
365
- "Fallback sign-in in the user's own browser; prefer its existing session/SSO or Browser Use's saved sign-in. Saved login (username or masked label; a miss lists the site's labels) written after host checks into the focused field of a Chrome/Edge HTTPS page. The site receives it. A password is kept from you and its browser's pixels are withheld this turn, but a page that redisplays it can expose it, and other programs of the same Windows user are outside this protection; a username is not hidden. On refusal hand the secret to the user (ask_user secret, surface computer).",
365
+ "Fallback sign-in in the user's own browser; prefer its existing session/SSO or Browser Use's saved sign-in. Saved login (username or masked label; a miss lists the site's labels) written after host checks into the focused field of a Chrome/Edge HTTPS page. The site receives it. A password is kept from you and its browser's pixels are withheld this turn, but a page that redisplays it can expose it, and other programs of the same Windows user are outside this protection; a username is not hidden. On refusal hand the secret to the user (handoff_user secret, surface computer).",
366
366
  },
367
367
  field: {
368
368
  type: 'string',
369
369
  enum: SAVED_LOGIN_FIELDS,
370
370
  description:
371
- "username (text field) or password (password field). One-time codes, passkeys, security keys and app approvals are the user's step: ask_user takeover.",
371
+ "username (text field) or password (password field). One-time codes, passkeys, security keys and app approvals are the user's step: handoff_user takeover.",
372
372
  },
373
373
  },
374
374
  ['savedAccount', 'field']
@@ -74,13 +74,13 @@ export const COMPUTER_CORE_ACTION_SCHEMA = {
74
74
  text: {
75
75
  type: 'string',
76
76
  maxLength: 30_000,
77
- description: `Literal text; foreground cap ${MAX_COMPUTER_FOREGROUND_TEXT_CHARS} UTF-16 code units per action. Never a password or one-time code, even one shown on screen: saved_login or ask_user.`,
77
+ description: `Literal text; foreground cap ${MAX_COMPUTER_FOREGROUND_TEXT_CHARS} UTF-16 code units per action. Never a password or one-time code, even one shown on screen: saved_login or handoff_user.`,
78
78
  },
79
79
  value: {
80
80
  type: 'string',
81
81
  maxLength: 30_000,
82
82
  description:
83
- 'set_value replacement for an element that advertises set_value; writes the control directly, without focus or keystrokes. Never a password or one-time code, even one shown on screen: saved_login or ask_user.',
83
+ 'set_value replacement for an element that advertises set_value; writes the control directly, without focus or keystrokes. Never a password or one-time code, even one shown on screen: saved_login or handoff_user.',
84
84
  },
85
85
  keys: {
86
86
  type: 'string',
@@ -31,8 +31,9 @@ const CLEANUP_CODES = new Set([
31
31
  const PIXEL_CODES = new Set(['pixel_unavailable', 'observation_unavailable']);
32
32
  // Saved-login refusals made before anything was written (host/saved-login.ts).
33
33
  const SAVED_LOGIN_REFUSAL_CODES = new Set(['saved_login_refused', 'saved_login_changed', 'saved_login_unavailable']);
34
- const SECRET_HANDOFF = 'hand the secret to the user with ask_user (kind "secret", surface "computer")';
35
- const STEP_HANDOFF = 'hand the step to the user with ask_user (kind "takeover", surface "computer", need "sign_in")';
34
+ const SECRET_HANDOFF = 'hand the secret to the user with handoff_user (kind "secret", surface "computer")';
35
+ const STEP_HANDOFF =
36
+ 'hand the step to the user with handoff_user (kind "takeover", surface "computer", need "sign_in")';
36
37
  // Reads send no input, so their timeout is a provider budget, not an uncertain
37
38
  // mutation: the caller needs another read route, not a cleanup investigation.
38
39
  const READ_ONLY_ACTIONS = new Set(['capture', 'list', 'diagnose', 'verify']);
@@ -157,14 +158,14 @@ function recoveryForCode(code, args) {
157
158
  if (SAVED_LOGIN_REFUSAL_CODES.has(code)) {
158
159
  return {
159
160
  code,
160
- next: 'ask_user',
161
+ next: 'handoff_user',
161
162
  guidance: `Nothing was written. If the refusal lists stored masked labels and the user's account is one of them, use that label; otherwise ${SECRET_HANDOFF}. Never type the secret yourself or try another window or field to get past the check.`,
162
163
  };
163
164
  }
164
165
  if (code === 'saved_login_unconfirmed') {
165
166
  return {
166
167
  code,
167
- next: 'ask_user',
168
+ next: 'handoff_user',
168
169
  guidance: `The saved value may have been written. Do not call saved_login again for this field and do not type it yourself; ${STEP_HANDOFF} to check the field and finish signing in.`,
169
170
  };
170
171
  }
@@ -14,15 +14,34 @@
14
14
  // pointer/keyboard the input device (uinput on Wayland, XTest on X11).
15
15
 
16
16
  const WINDOW_ACTIONS = new Set([
17
- 'list_windows', 'window_snapshot', 'related_windows', 'window_bounds', 'window_capture',
18
- 'window_integrity', 'validate_background_input', 'list_apps', 'verify', 'focus_window',
19
- 'move_window', 'window_state', 'close_window', 'terminate_process',
17
+ 'list_windows',
18
+ 'window_snapshot',
19
+ 'related_windows',
20
+ 'window_bounds',
21
+ 'window_capture',
22
+ 'window_integrity',
23
+ 'validate_background_input',
24
+ 'list_apps',
25
+ 'verify',
26
+ 'focus_window',
27
+ 'move_window',
28
+ 'window_state',
29
+ 'close_window',
30
+ 'terminate_process',
20
31
  ]);
21
32
  const ACCESSIBILITY_ACTIONS = new Set(['snapshot', 'find', 'window_predicates', 'accessibility_probe']);
22
33
  const SEMANTIC_ACTIONS = new Set(['invoke', 'set_value', 'toggle', 'invoke_menu']);
23
34
  const POINTER_ACTIONS = new Set([
24
- 'click', 'double_click', 'right_click', 'middle_click', 'triple_click',
25
- 'mouse_down', 'mouse_up', 'mouse_move', 'drag', 'scroll',
35
+ 'click',
36
+ 'double_click',
37
+ 'right_click',
38
+ 'middle_click',
39
+ 'triple_click',
40
+ 'mouse_down',
41
+ 'mouse_up',
42
+ 'mouse_move',
43
+ 'drag',
44
+ 'scroll',
26
45
  ]);
27
46
  const KEYBOARD_ACTIONS = new Set(['type', 'key', 'key_down', 'key_up']);
28
47
 
@@ -35,7 +35,10 @@ export interface LinuxComputerRefusal {
35
35
  export const MIN_WINDOW_HELPER_VERSION: number;
36
36
  export const CAPABILITY_UNAVAILABLE_CODE: 'computer_capability_unavailable';
37
37
  export function detectSession(env: Record<string, string | undefined>): 'wayland' | 'x11';
38
- export function detectDesktop(env: Record<string, string | undefined>, session: 'wayland' | 'x11'): LinuxComputerReadiness['desktop'];
38
+ export function detectDesktop(
39
+ env: Record<string, string | undefined>,
40
+ session: 'wayland' | 'x11'
41
+ ): LinuxComputerReadiness['desktop'];
39
42
  export function checkLinuxComputerReadiness(options?: Record<string, unknown>): Promise<LinuxComputerReadiness>;
40
43
  export function getLinuxComputerReadiness(options?: Record<string, unknown>): Promise<LinuxComputerReadiness>;
41
44
  export function missingCapabilities(
@@ -47,4 +50,6 @@ export function resetLinuxComputerPreflightCache(): void;
47
50
  export const GNOME_EXTENSION_UUID: 'mixdog-windows@mixdog.io';
48
51
  export function gnomeExtensionDirs(env?: Record<string, string | undefined>): string[];
49
52
  export const CAPTURE_FALLBACK_NOTE: string;
50
- export function linuxCaptureFallback(options?: Record<string, unknown>): Promise<{ command: Record<string, unknown>; note: string } | null>;
53
+ export function linuxCaptureFallback(
54
+ options?: Record<string, unknown>
55
+ ): Promise<{ command: Record<string, unknown>; note: string } | null>;
@@ -4,13 +4,14 @@ import { setTimeout as delay } from 'node:timers/promises';
4
4
  import { redactedLog, spawnServerState } from './server-process/child-state.mjs';
5
5
  import { awaitServerReady } from './server-process/readiness.mjs';
6
6
  import { createSerialChain } from './serial-chain.mjs';
7
+ import { listenOnFetchSafePort } from '../shared/fetch-safe-listen.mjs';
7
8
 
8
9
  async function freeLoopbackPort() {
9
10
  return new Promise((resolve, reject) => {
10
11
  const probe = createServer();
11
12
  probe.unref();
12
13
  probe.once('error', reject);
13
- probe.listen(0, '127.0.0.1', () => {
14
+ listenOnFetchSafePort(probe, '127.0.0.1', () => {
14
15
  const port = probe.address().port;
15
16
  probe.close((error) => (error ? reject(error) : resolve(port)));
16
17
  });
@@ -120,7 +120,10 @@ async function generateViaVeo({ model, prompt, options, references = [], signal,
120
120
  // Veo reports no usage; it bills per generated second. The response does
121
121
  // not echo the length, so the requested one (default 8s) is the billed one.
122
122
  // A failed download still leaves the generated seconds billed.
123
- const usage = { seconds: parameters.durationSeconds || VEO_DEFAULT_SECONDS, resolution: parameters.resolution || '720p' };
123
+ const usage = {
124
+ seconds: parameters.durationSeconds || VEO_DEFAULT_SECONDS,
125
+ resolution: parameters.resolution || '720p',
126
+ };
124
127
  // The download is part of the generation budget: unbounded, it held an
125
128
  // active job slot (and the upstream connection) open indefinitely after
126
129
  // the poll loop finished.
@@ -120,7 +120,8 @@ export async function generateVideo({ lane, model, prompt, options = {}, referen
120
120
  // let the catalog's per-second rate price it otherwise.
121
121
  const seconds = Number(data?.video?.duration) || duration;
122
122
  const usage = { ...xaiUsage(data?.usage), seconds, resolution };
123
- if (!url) throw withReportedUsage(mediaError('xAI video finished without a URL', 'MEDIA_EMPTY_RESULT', 502), usage);
123
+ if (!url)
124
+ throw withReportedUsage(mediaError('xAI video finished without a URL', 'MEDIA_EMPTY_RESULT', 502), usage);
124
125
  const bytes = await downloadPublicMedia(url, { signal, label: 'xAI video' }).catch((error) => {
125
126
  throw withReportedUsage(error, usage);
126
127
  });
@@ -300,7 +300,11 @@ async function loadTokenizer() {
300
300
  async function createExtractor(device) {
301
301
  const ort = loadOrt();
302
302
  const encode = await loadTokenizer();
303
- const graphPath = await ensureModelGraph(MODEL_CACHE_DIR, MODEL_ID, getEmbeddingModelGraphFile(MODEL_ID, configuredDtype));
303
+ const graphPath = await ensureModelGraph(
304
+ MODEL_CACHE_DIR,
305
+ MODEL_ID,
306
+ getEmbeddingModelGraphFile(MODEL_ID, configuredDtype)
307
+ );
304
308
  const session = await ort.InferenceSession.create(graphPath, {
305
309
  executionProviders: [device],
306
310
  intraOpNumThreads: INTRA_OP_THREADS,
@@ -397,8 +401,7 @@ async function loadExtractor() {
397
401
  } catch (e) {
398
402
  // Unprivileged processes cannot raise priority back (EACCES/EPERM);
399
403
  // on Linux that is expected, not a stuck state worth warning about.
400
- const expectedOnLinux =
401
- process.platform === 'linux' && /EACCES|EPERM/.test(`${e?.code} ${e?.message}`);
404
+ const expectedOnLinux = process.platform === 'linux' && /EACCES|EPERM/.test(`${e?.code} ${e?.message}`);
402
405
  if (!expectedOnLinux) {
403
406
  __mixdogMemoryLog(
404
407
  `[embed-worker] WARN: process priority stuck below normal (restore failed: ${e?.message || e})\n`
@@ -6,13 +6,7 @@
6
6
  import { runFullBackfill } from '../memory-ops-policy.mjs';
7
7
  import { throwIfAborted } from '../memory-cycle-shared.mjs';
8
8
 
9
- export function createBackfillAction({
10
- getDb,
11
- dataDir,
12
- awaitCycle1Run,
13
- ingestTranscriptFile,
14
- cwdFromTranscriptPath,
15
- }) {
9
+ export function createBackfillAction({ getDb, dataDir, awaitCycle1Run, ingestTranscriptFile, cwdFromTranscriptPath }) {
16
10
  // Whole-action backfill mutex (transport-agnostic). memory-cycle1's
17
11
  // _runCycle1InFlight only protects cycle1; ingest workers
18
12
  // (memory-ops-policy.mjs) can still overlap if a second backfill
@@ -315,12 +315,7 @@ function createCycle1PacketGenerator({ callLlm, request, signal, inputTokenBudge
315
315
 
316
316
  export async function generateCycle1Chunks(
317
317
  rows,
318
- {
319
- callLlm,
320
- request = {},
321
- inputTokenBudget = CYCLE1_INPUT_TOKEN_BUDGET,
322
- signal = request.signal,
323
- } = {}
318
+ { callLlm, request = {}, inputTokenBudget = CYCLE1_INPUT_TOKEN_BUDGET, signal = request.signal } = {}
324
319
  ) {
325
320
  const startedAt = Date.now();
326
321
  const stats = { groupingCalls: 0, verificationCalls: 0, llmMs: 0, verificationMs: 0, retries: 0, fragments: 0 };
@@ -22,12 +22,7 @@ import {
22
22
  } from '../core/office-sessions.mjs';
23
23
  import { snapshotPdf } from '../pdf/pdf-adapter.mjs';
24
24
  import { inlineOfficeAudit } from '../quality/inline-audit.mjs';
25
- import {
26
- factsGate,
27
- parseAuthoringBrief,
28
- reviewBriefPromises,
29
- reviewSourceGrounding,
30
- } from './pptx-brief.mjs';
25
+ import { factsGate, parseAuthoringBrief, reviewBriefPromises, reviewSourceGrounding } from './pptx-brief.mjs';
31
26
  import { editsReplacedByAuthor, markAuthoredFromHtml } from './html-source-drift.mjs';
32
27
  import { hasSlideSections, htmlBriefScript, runPptxHtmlAuthoring } from './pptx-html-runner.mjs';
33
28
  import {