mixdog 0.9.93 → 0.9.95

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 (186) hide show
  1. package/NOTICE.md +72 -0
  2. package/package.json +16 -6
  3. package/scripts/lib/isolated-root-cleanup.mjs +19 -0
  4. package/scripts/run-suite.mjs +100 -0
  5. package/src/lib/rules-builder.cjs +4 -3
  6. package/src/output-styles/detailed.md +13 -15
  7. package/src/output-styles/extreme-minimal.md +7 -11
  8. package/src/output-styles/minimal.md +4 -7
  9. package/src/output-styles/simple.md +11 -13
  10. package/src/rules/agent/30-explorer.md +22 -16
  11. package/src/rules/lead/01-general.md +1 -2
  12. package/src/rules/lead/lead-brief.md +4 -5
  13. package/src/rules/lead/lead-tool.md +3 -2
  14. package/src/rules/shared/01-tool.md +28 -29
  15. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -2
  16. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +23 -7
  17. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +4 -0
  18. package/src/runtime/agent/orchestrator/agent-trace.mjs +29 -0
  19. package/src/runtime/agent/orchestrator/context/collect.mjs +6 -2
  20. package/src/runtime/agent/orchestrator/mcp/client.mjs +3 -3
  21. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +97 -7
  22. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +11 -4
  23. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -3
  24. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +1 -1
  25. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +4 -6
  26. package/src/runtime/agent/orchestrator/providers/lib/stream-outcome.mjs +1 -1
  27. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +75 -15
  28. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +8 -8
  29. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -8
  30. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2 -2
  31. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +14 -16
  32. package/src/runtime/agent/orchestrator/providers/openai-ws-headers.mjs +5 -4
  33. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +10 -10
  34. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -3
  35. package/src/runtime/agent/orchestrator/providers/registry.mjs +51 -4
  36. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +15 -15
  37. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +12 -32
  38. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +7 -0
  39. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +42 -2
  40. package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +10 -3
  41. package/src/runtime/agent/orchestrator/session/context-utils.mjs +10 -11
  42. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +1 -0
  43. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -3
  44. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +0 -14
  45. package/src/runtime/agent/orchestrator/session/loop/stop-hooks.mjs +9 -8
  46. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +7 -4
  47. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  48. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +1 -1
  49. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +40 -13
  50. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +3 -0
  51. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -1
  52. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +5 -9
  53. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +3 -3
  54. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +103 -92
  55. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +98 -3
  56. package/src/runtime/agent/orchestrator/stall-policy.mjs +2 -3
  57. package/src/runtime/agent/orchestrator/tools/bash-session.mjs +3 -3
  58. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +25 -3
  59. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +10 -2
  60. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
  61. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +12 -3
  62. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +22 -0
  63. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +491 -0
  64. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +91 -13
  65. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +90 -27
  66. package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +20 -1
  67. package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +4 -4
  69. package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +2 -2
  70. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +19 -9
  71. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +2 -1
  72. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +3 -3
  73. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +7 -2
  74. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +32 -4
  75. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +1 -1
  76. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +16 -1
  77. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +546 -23
  78. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +8 -5
  79. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +12 -0
  80. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-spawn.mjs +10 -3
  81. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +35 -5
  82. package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +3 -3
  83. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +98 -0
  84. package/src/runtime/agent/orchestrator/tools/builtin/tool-output-limit.mjs +48 -0
  85. package/src/runtime/agent/orchestrator/tools/builtin.mjs +71 -1
  86. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +7 -3
  87. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +104 -14
  88. package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +47 -2
  89. package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +6 -17
  90. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +2 -4
  91. package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +3 -1
  92. package/src/runtime/agent/orchestrator/tools/env-scrub.mjs +9 -2
  93. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +5 -5
  94. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +57 -2
  96. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +151 -18
  97. package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +5 -1
  98. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +109 -13
  99. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +10 -10
  100. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +4 -5
  101. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +4 -0
  102. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +1 -1
  103. package/src/runtime/channels/backends/discord.mjs +5 -14
  104. package/src/runtime/channels/backends/telegram.mjs +0 -5
  105. package/src/runtime/channels/lib/inbound-handler.mjs +0 -1
  106. package/src/runtime/channels/lib/output-forwarder.mjs +24 -5
  107. package/src/runtime/channels/lib/scheduler.mjs +1 -1
  108. package/src/runtime/channels/lib/worker-main.mjs +1 -1
  109. package/src/runtime/media/renditions.mjs +21 -2
  110. package/src/runtime/memory/lib/tool-call-handler.mjs +16 -1
  111. package/src/runtime/memory/tool-defs.mjs +6 -6
  112. package/src/runtime/shared/atomic-file.mjs +53 -0
  113. package/src/runtime/shared/background-tasks.mjs +16 -6
  114. package/src/runtime/shared/child-spawn-gate.mjs +50 -26
  115. package/src/runtime/shared/resource-admission.mjs +40 -1
  116. package/src/runtime/shared/task-notification-envelope.mjs +11 -2
  117. package/src/runtime/shared/tool-card-model.mjs +6 -2
  118. package/src/runtime/shared/tool-status.mjs +10 -1
  119. package/src/runtime/shared/tool-surface.mjs +5 -0
  120. package/src/runtime/shared/turn-snapshot.mjs +385 -21
  121. package/src/runtime/shared/turn-worktree-snapshot.mjs +540 -0
  122. package/src/session-runtime/context-status.mjs +9 -3
  123. package/src/session-runtime/lifecycle-api.mjs +35 -5
  124. package/src/session-runtime/mcp-glue.mjs +11 -6
  125. package/src/session-runtime/provider-models.mjs +94 -43
  126. package/src/session-runtime/provider-usage.mjs +26 -2
  127. package/src/session-runtime/runtime-core.mjs +46 -8
  128. package/src/session-runtime/runtime-tunables.mjs +4 -0
  129. package/src/session-runtime/self-update.mjs +33 -4
  130. package/src/session-runtime/session-lifecycle.mjs +2 -0
  131. package/src/session-runtime/session-text.mjs +2 -1
  132. package/src/session-runtime/session-turn-api.mjs +106 -22
  133. package/src/session-runtime/workflow.mjs +11 -4
  134. package/src/standalone/agent-tool.mjs +4 -4
  135. package/src/standalone/backend-daemon.mjs +570 -0
  136. package/src/standalone/channel-daemon-transport.mjs +141 -1
  137. package/src/standalone/channel-worker.mjs +3 -2
  138. package/src/standalone/engine-daemon-client.mjs +894 -0
  139. package/src/standalone/engine-daemon-local-bridge.mjs +20 -0
  140. package/src/standalone/engine-daemon-protocol.mjs +33 -0
  141. package/src/standalone/engine-daemon-service.mjs +864 -0
  142. package/src/standalone/engine-daemon-transport.mjs +603 -0
  143. package/src/standalone/explore-tool.mjs +1 -1
  144. package/src/tui/App.jsx +62 -47
  145. package/src/tui/app/app-format.mjs +4 -2
  146. package/src/tui/app/app-view.jsx +5 -0
  147. package/src/tui/app/channel-pickers.mjs +7 -6
  148. package/src/tui/app/core-memory-picker.mjs +4 -4
  149. package/src/tui/app/extension-pickers.mjs +20 -18
  150. package/src/tui/app/maintenance-pickers.mjs +27 -27
  151. package/src/tui/app/onboarding-steps.mjs +23 -18
  152. package/src/tui/app/prompt-submit.mjs +13 -2
  153. package/src/tui/app/route-pickers.mjs +13 -8
  154. package/src/tui/app/settings-picker.mjs +55 -58
  155. package/src/tui/app/slash-dispatch.mjs +32 -28
  156. package/src/tui/app/transcript-window.mjs +19 -0
  157. package/src/tui/app/usage-context-panels.mjs +22 -7
  158. package/src/tui/app/use-mouse-input.mjs +25 -3
  159. package/src/tui/app/use-prompt-queue-history.mjs +31 -16
  160. package/src/tui/app/use-transcript-scroll.mjs +30 -8
  161. package/src/tui/app/use-transcript-window.mjs +22 -1
  162. package/src/tui/app/use-welcome-prompt-hint.mjs +2 -2
  163. package/src/tui/components/PromptInput.jsx +10 -0
  164. package/src/tui/components/Spinner.jsx +89 -86
  165. package/src/tui/components/TextEntryPanel.jsx +14 -0
  166. package/src/tui/components/ToolExecution.jsx +2 -2
  167. package/src/tui/dist/index.mjs +1537 -9718
  168. package/src/tui/engine/agent-job-feed.mjs +2 -2
  169. package/src/tui/engine/live-share.mjs +97 -4
  170. package/src/tui/engine/session-api-ext.mjs +23 -1
  171. package/src/tui/engine/session-api.mjs +88 -41
  172. package/src/tui/engine/session-flow.mjs +43 -4
  173. package/src/tui/engine/tool-card-results.mjs +6 -0
  174. package/src/tui/engine/turn.mjs +84 -4
  175. package/src/tui/engine-local-session.mjs +1108 -0
  176. package/src/tui/engine.mjs +16 -1057
  177. package/src/tui/index.jsx +47 -2
  178. package/src/tui/markdown/stream-fence.mjs +1 -1
  179. package/src/tui/spinner-meta.mjs +80 -0
  180. package/src/tui/spinner-verbs.mjs +35 -0
  181. package/src/ui/statusline-segments.mjs +43 -10
  182. package/src/ui/statusline.mjs +10 -1
  183. package/scripts/tmp-cdp-errors.mjs +0 -41
  184. package/scripts/tmp-cdp-inspect.mjs +0 -41
  185. package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +0 -176
  186. package/src/standalone/channel-daemon.mjs +0 -226
@@ -113,6 +113,7 @@ export async function executeReadTool(args, workDir, readStateScope, executeChil
113
113
  _rangeHashesFromRenderedReadText,
114
114
  _readEntryLineWindow,
115
115
  _recordReadSnapshot,
116
+ READ_MAX_OUTPUT_BYTES,
116
117
  } = helpers;
117
118
  // CC `file_path` alias — official SDK schema uses `file_path`;
118
119
  // mixdog has historically used `path`. Honor `file_path` so a
@@ -310,6 +311,21 @@ export async function executeReadTool(args, workDir, readStateScope, executeChil
310
311
  if (a.offset !== b.offset) return a.offset - b.offset;
311
312
  return a.index - b.index;
312
313
  });
314
+ // A path[] Read shares one byte ceiling. Reserve room for headers and
315
+ // split the remaining body budget across distinct disk windows.
316
+ const _readCallBudget = Number(options?.readOutputBudgetBytes) > 0
317
+ ? Math.min(READ_MAX_OUTPUT_BYTES, Math.trunc(Number(options.readOutputBudgetBytes)))
318
+ : READ_MAX_OUTPUT_BYTES;
319
+ const _headerReserve = Math.min(
320
+ Math.max(2_048, entries.reduce((sum, entry) => (
321
+ sum + Buffer.byteLength(String(normalizeOutputPath(entry?.path || '(missing-path)')), 'utf8') + 128
322
+ ), 0)),
323
+ Math.floor(_readCallBudget / 2),
324
+ );
325
+ const _perTaskOutputBudget = Math.max(
326
+ 256,
327
+ Math.floor((_readCallBudget - _headerReserve) / Math.max(1, tasks.length)),
328
+ );
313
329
  const results = new Array(entries.length);
314
330
  const readChains = new Map();
315
331
  await Promise.all(tasks.map(({ entry, index }) => {
@@ -319,9 +335,15 @@ export async function executeReadTool(args, workDir, readStateScope, executeChil
319
335
  }
320
336
  const run = async () => {
321
337
  const _diskWin = readEntryCoalescedDiskWindow(entry);
322
- const readEntry = _diskWin
338
+ let readEntry = _diskWin
323
339
  ? { ...entry, offset: _diskWin.offset, limit: _diskWin.limit }
324
340
  : entry;
341
+ if ((!readEntry.mode || readEntry.mode === 'full')
342
+ && readEntry.offset == null
343
+ && readEntry.limit == null
344
+ && readEntry.full !== true) {
345
+ readEntry = { ...readEntry, offset: 0, limit: 2000 };
346
+ }
325
347
  // Full image children retain their rich blocks; the aggregate
326
348
  // assembler below flattens them without stringification.
327
349
  // Other media (PDF/notebook) remains text-only in a batch so
@@ -332,6 +354,9 @@ export async function executeReadTool(args, workDir, readStateScope, executeChil
332
354
  suppressReadUnchangedStub: true,
333
355
  mediaTextOnly: !richImage,
334
356
  _skipReachPreflight: true,
357
+ forceReadRangeStream: true,
358
+ readOutputBudgetBytes: _perTaskOutputBudget,
359
+ toolOutputMaxBytes: _perTaskOutputBudget,
335
360
  });
336
361
  results[index] = { path: entry.path, mode: entry.mode || 'full', n: entry.n, body };
337
362
  };
@@ -470,11 +495,13 @@ export async function executeReadTool(args, workDir, readStateScope, executeChil
470
495
  const r = orderedResults[i];
471
496
  const path = normalizeOutputPath(r.path);
472
497
  const mode = r.n !== undefined ? `${r.mode} n=${r.n}` : r.mode;
498
+ // Default full mode carries no information — tag only non-default modes.
499
+ const modeTag = mode && mode !== 'full' ? ` [${mode}]` : '';
473
500
  const status = bodyFailed(r.body) ? 'error' : 'ok';
474
501
  const textBody = bodyTextFor(r.body);
475
502
  const match = /\[TRUNCATED (?:—|-) file is (\d+) lines \/ (\d+) KB\./.exec(textBody);
476
503
  const suffix = match ? ` (truncated ${match[1]}L/${match[2]}KB)` : '';
477
- const entryHeader = `${path} [${mode}] [${status}]${suffix}`;
504
+ const entryHeader = `${path}${modeTag} [${status}]${suffix}`;
478
505
  const richParts = richPartsFor(r.body);
479
506
  let priorIdx;
480
507
  if (richParts) {
@@ -513,16 +540,17 @@ export async function executeReadTool(args, workDir, readStateScope, executeChil
513
540
  const body = orderedResults.map((r, _i) => {
514
541
  const path = normalizeOutputPath(r.path);
515
542
  const mode = r.n !== undefined ? `${r.mode} n=${r.n}` : r.mode;
543
+ const modeTag = mode && mode !== 'full' ? ` [${mode}]` : '';
516
544
  const status = classifyResultKind(String(r.body || '')) === 'error' ? 'error' : 'ok';
517
545
  const dupKey = JSON.stringify([path, mode, r.body || '']);
518
546
  const priorIdx = _seenEntryBody.get(dupKey);
519
547
  if (priorIdx !== undefined) {
520
- return `${path} [${mode}] [${status}] [= entry #${priorIdx + 1}, identical result omitted]`;
548
+ return `${path}${modeTag} [${status}] [= entry #${priorIdx + 1}, identical result omitted]`;
521
549
  }
522
550
  _seenEntryBody.set(dupKey, _i);
523
551
  const match = /\[TRUNCATED (?:—|-) file is (\d+) lines \/ (\d+) KB\./.exec(r.body || '');
524
552
  const suffix = match ? ` (truncated ${match[1]}L/${match[2]}KB)` : '';
525
- return `${path} [${mode}] [${status}]${suffix}\n${r.body}`;
553
+ return `${path}${modeTag} [${status}]${suffix}\n${r.body}`;
526
554
  }).join('\n\n');
527
555
  return `${header}\n\n${body}${args._batchCapNote ? `\n\n${args._batchCapNote}` : ''}`;
528
556
  }
@@ -302,7 +302,7 @@ export async function rgSupportsPcre2() {
302
302
  }
303
303
 
304
304
  // Cap rg stdout accumulation so a runaway producer (huge repo, accidental
305
- // match-all) cannot balloon the JS string heap. Mirrors CC's ripgrep.ts cap.
305
+ // match-all) cannot balloon the JS string heap.
306
306
  const MAX_RG_STDOUT_BYTES = 20 * 1024 * 1024; // 20MB
307
307
 
308
308
  // SIGTERM → grace → force kill; hard Promise settle if 'close' never fires
@@ -31,7 +31,9 @@ export function buildGrepCacheKey(parts) {
31
31
  onlyMatching,
32
32
  pcre2,
33
33
  withFilename,
34
+ contextCharBudget = 0,
34
35
  patternCapTotal = 0,
36
+ candidatesKey = '',
35
37
  } = parts;
36
38
  return [
37
39
  'grep',
@@ -51,10 +53,15 @@ export function buildGrepCacheKey(parts) {
51
53
  Array.isArray(fileType) ? fileType.join('\x01') : (fileType || ''),
52
54
  pcre2 ? 'p1' : 'p0',
53
55
  withFilename ? 'H1' : 'H0',
56
+ 'cb' + String(contextCharBudget || 0),
54
57
  // Cap total keeps a capped request (first-N of M patterns, carrying the
55
58
  // "[capped at N of M]" notice) from colliding with an exact N-pattern
56
59
  // request or with a differently-capped one (of 15 vs of 20).
57
60
  'pc' + String(patternCapTotal || 0),
61
+ // Candidate-file scoping (fan-out prefilter) changes which files rg
62
+ // visits and their order; scoped results get their own cache slot so
63
+ // they never collide with an unscoped run of the same pattern.
64
+ 'cd' + String(candidatesKey || ''),
58
65
  ].join('|');
59
66
  }
60
67
 
@@ -75,6 +82,7 @@ export function buildGrepRgArgs(parts) {
75
82
  fixedStrings = false,
76
83
  pcre2 = false,
77
84
  withFilename = false,
85
+ candidateFiles = null,
78
86
  } = parts;
79
87
  // `--hidden`: search dotfiles/dot-dirs (.github, .mixdog) that
80
88
  // rg skips by default. The DEFAULT_IGNORE_GLOBS below still exclude .git and
@@ -127,7 +135,14 @@ export function buildGrepRgArgs(parts) {
127
135
  // `--type` is treated as a positional path, not parsed as an rg
128
136
  // option. Patterns already use `-e`, so the separator only needs to
129
137
  // guard the trailing path operand.
130
- rgArgs.push('--', searchPath);
138
+ if (Array.isArray(candidateFiles) && candidateFiles.length > 0) {
139
+ // Fan-out prefilter scoping: search ONLY the candidate files (paths
140
+ // relative to the spawn cwd) instead of walking searchPath — explicit
141
+ // file operands skip the directory walk entirely.
142
+ rgArgs.push('--', ...candidateFiles);
143
+ } else {
144
+ rgArgs.push('--', searchPath);
145
+ }
131
146
  return rgArgs;
132
147
  }
133
148