@moda-ai/cli 1.55.27 → 1.55.29

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 (43) hide show
  1. package/dist/{agent-vp9prdma.js → agent-0w9rtdsw.js} +22 -16
  2. package/dist/cli-3n0gz4d0.js +17971 -0
  3. package/dist/{cli-q9nsvqqg.js → cli-3retgh64.js} +85 -1165
  4. package/dist/{cli-ccjfwzqx.js → cli-97jew729.js} +1 -1
  5. package/dist/{cli-r5pp7qny.js → cli-99p2jh28.js} +42 -456
  6. package/dist/{cli-0pkc8jhg.js → cli-9bgk5jeh.js} +8 -6
  7. package/dist/{cli-hmjdgxrn.js → cli-9bgnvth2.js} +5 -3
  8. package/dist/cli-9kfxkxmk.js +6994 -0
  9. package/dist/cli-cesds766.js +1516 -0
  10. package/dist/{cli-v8q7sd7g.js → cli-dr6x0zv7.js} +1 -1
  11. package/dist/{cli-pg5qfmqc.js → cli-e23g9ywa.js} +1 -1
  12. package/dist/{cli-vdkwkkp5.js → cli-fwpqghgc.js} +4 -2
  13. package/dist/cli-k4tqwah4.js +89 -0
  14. package/dist/{cli-6et4z504.js → cli-mg5zv4s6.js} +15 -13
  15. package/dist/{cli-wzds257x.js → cli-n2hng3gv.js} +6 -4
  16. package/dist/cli-ns5fcnkz.js +341 -0
  17. package/dist/{cli-4h0ave0f.js → cli-ny48a8de.js} +12 -9
  18. package/dist/{cli-qwgct6x7.js → cli-qpq84eee.js} +5220 -32716
  19. package/dist/cli-xq45etg1.js +1098 -0
  20. package/dist/cli-yf39avhh.js +754 -0
  21. package/dist/cli-yz8xcpyk.js +12 -0
  22. package/dist/cli.js +435 -192
  23. package/dist/doctor-k3ta6h2y.js +24 -0
  24. package/dist/{fix-75s9s0d6.js → fix-w5z02wt4.js} +8 -9
  25. package/dist/{harness-a7tb9a23.js → harness-7azmzytc.js} +15 -7
  26. package/dist/{harness-github-actions-6v4wydb8.js → harness-github-actions-bv2qrnqb.js} +11 -5
  27. package/dist/harness-report-rd9c4e9v.js +54 -0
  28. package/dist/{index-91bpc8g8.js → index-d1z50dsq.js} +41 -33
  29. package/dist/{production-intelligence-7nqddd4f.js → production-intelligence-wvsgjxth.js} +9 -6
  30. package/dist/{profile-commands-49yn02yg.js → profile-commands-h8evz9x0.js} +7 -4
  31. package/dist/prompt-attribution-1nytc9wj.js +148 -0
  32. package/dist/prompt-source-mcp.js +14 -7
  33. package/dist/prompt-sources-07tczyqa.js +19 -0
  34. package/dist/{prompts-17wyrst6.js → prompts-6y9wfq5z.js} +8 -7
  35. package/dist/prompts-ab-ezrd63sk.js +70 -0
  36. package/dist/prompts-propose-2k3enm2q.js +255 -0
  37. package/dist/{provision-bc3h68e1.js → provision-y5bdbh4y.js} +9 -6
  38. package/dist/{registry-fpzhjznj.js → registry-96aze5wp.js} +7 -4
  39. package/dist/{skills-ccdbqghj.js → skills-j8865009.js} +7 -5
  40. package/dist/{sync-hkxce5zh.js → sync-ew7yvy0e.js} +16 -10
  41. package/package.json +1 -1
  42. package/skills/integration/index.json +2 -2
  43. package/dist/doctor-wmre3mr7.js +0 -22
package/dist/cli.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  withFrustrationAnchors,
18
18
  withToolFailureAnchors,
19
19
  withoutDetectionWindows
20
- } from "./cli-vdkwkkp5.js";
20
+ } from "./cli-fwpqghgc.js";
21
21
  import {
22
22
  createCommandContext,
23
23
  envOptOutSet,
@@ -25,7 +25,7 @@ import {
25
25
  optOutFlagSet,
26
26
  parseBooleanFlagValue,
27
27
  withoutFlag
28
- } from "./cli-v8q7sd7g.js";
28
+ } from "./cli-dr6x0zv7.js";
29
29
  import {
30
30
  AuditSchema,
31
31
  COMMAND_FLAG_SPECS,
@@ -67,20 +67,14 @@ import {
67
67
  unknownSignalsSubcommandError,
68
68
  usageLine,
69
69
  writeDryRun
70
- } from "./cli-wzds257x.js";
70
+ } from "./cli-n2hng3gv.js";
71
71
  import {
72
72
  ApiError,
73
73
  callControlAPI,
74
74
  callDataAPI
75
- } from "./cli-pg5qfmqc.js";
75
+ } from "./cli-e23g9ywa.js";
76
76
  import {
77
77
  AGENT_ERROR_CODES,
78
- CliAccessError,
79
- CliAuthError,
80
- CliCancellationError,
81
- CliInputError,
82
- CliInputRequiredError,
83
- CliNotFoundError,
84
78
  EXIT_AUTH_REQUIRED,
85
79
  EXIT_CANCELLED,
86
80
  EXIT_DEGRADED,
@@ -92,18 +86,14 @@ import {
92
86
  VERSION,
93
87
  agentEnvelopeFits,
94
88
  agentMaxOutputBytes,
95
- apiErrorStatus,
96
89
  apiKeyHeaders,
97
- attachInputDetails,
98
90
  canonicalCommandText,
99
91
  createCliOutput,
100
92
  embeddedTenantIdFromApiKey,
101
93
  errorToAgentError,
94
+ getActiveProfile,
102
95
  getApiRequestCount,
103
96
  getModaDir,
104
- inputDetailsOf,
105
- isApiLikeError,
106
- isNetworkLikeError,
107
97
  isPlatformApiKey,
108
98
  loadProfileConfig,
109
99
  resetApiRequestCount,
@@ -119,13 +109,27 @@ import {
119
109
  shellArg,
120
110
  validateConfig,
121
111
  wasOutputCancelled
122
- } from "./cli-r5pp7qny.js";
112
+ } from "./cli-99p2jh28.js";
113
+ import {
114
+ CliAccessError,
115
+ CliAuthError,
116
+ CliCancellationError,
117
+ CliInputError,
118
+ CliInputRequiredError,
119
+ CliNotFoundError,
120
+ apiErrorStatus,
121
+ attachInputDetails,
122
+ inputDetailsOf,
123
+ isApiLikeError,
124
+ isNetworkLikeError
125
+ } from "./cli-k4tqwah4.js";
126
+ import"./cli-ns5fcnkz.js";
123
127
  import {
124
128
  __require
125
129
  } from "./cli-0v6na3yp.js";
126
130
 
127
131
  // src/cli.ts
128
- import { randomUUID as randomUUID2 } from "node:crypto";
132
+ import { randomUUID as randomUUID3 } from "node:crypto";
129
133
  import { z } from "zod";
130
134
 
131
135
  // src/replays.ts
@@ -384,10 +388,223 @@ function spawnDetachedNode(script, options = {}, spawnImpl = spawn) {
384
388
  }
385
389
 
386
390
  // src/telemetry.ts
387
- import { randomUUID } from "node:crypto";
391
+ import { randomUUID as randomUUID2 } from "node:crypto";
392
+
393
+ // src/telemetry-spool.ts
394
+ import { createHash, randomUUID } from "node:crypto";
395
+ import {
396
+ closeSync,
397
+ constants as fsConstants,
398
+ fchmodSync,
399
+ mkdirSync,
400
+ openSync,
401
+ readFileSync,
402
+ renameSync,
403
+ rmSync,
404
+ statSync,
405
+ unlinkSync,
406
+ writeSync
407
+ } from "node:fs";
408
+ import { join } from "node:path";
409
+ var SPOOL_MAX_BYTES = 256 * 1024;
410
+ var FLUSH_MIN_EVENTS = 20;
411
+ var FLUSH_MAX_AGE_MS = 30000;
412
+ var SPOOL_MAX_EVENT_AGE_MS = 7 * 24 * 60 * 60 * 1000;
413
+ var FLUSH_LOCK_STALE_MS = 30000;
414
+ var MAX_BATCH_EVENTS = 50;
415
+ var SPOOL_LOCK_STALE_MS = 2000;
416
+ var SPOOL_LOCK_WAIT_MS = 200;
417
+ var SPOOL_FILE = "usage-spool.jsonl";
418
+ var LOCK_FILE = "flush.lock";
419
+ var SPOOL_LOCK_FILE = "spool.lock";
420
+ var O_NOFOLLOW = fsConstants.O_NOFOLLOW ?? 0;
421
+ function telemetrySpoolDir() {
422
+ return join(getModaDir(), "telemetry");
423
+ }
424
+ function keyFingerprint(apiKey) {
425
+ return createHash("sha256").update(`moda-cli-usage-spool\x00${apiKey}`).digest("hex").slice(0, 16);
426
+ }
427
+ function ensureDir(dir) {
428
+ mkdirSync(dir, { recursive: true, mode: 448 });
429
+ }
430
+ function appendLines(path, text) {
431
+ const fd = openSync(path, fsConstants.O_WRONLY | fsConstants.O_APPEND | fsConstants.O_CREAT | O_NOFOLLOW, 384);
432
+ try {
433
+ try {
434
+ fchmodSync(fd, 384);
435
+ } catch {}
436
+ writeSync(fd, text);
437
+ } finally {
438
+ closeSync(fd);
439
+ }
440
+ }
441
+ function sleepSync(ms) {
442
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
443
+ }
444
+ function createLockFile(path, staleMs, now) {
445
+ for (let attempt = 0;attempt < 2; attempt += 1) {
446
+ try {
447
+ const fd = openSync(path, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | O_NOFOLLOW, 384);
448
+ try {
449
+ writeSync(fd, String(process.pid));
450
+ } finally {
451
+ closeSync(fd);
452
+ }
453
+ return true;
454
+ } catch (error) {
455
+ if (error.code !== "EEXIST")
456
+ return false;
457
+ try {
458
+ if (now - statSync(path).mtimeMs < staleMs)
459
+ return false;
460
+ unlinkSync(path);
461
+ } catch {}
462
+ }
463
+ }
464
+ return false;
465
+ }
466
+ function withSpoolLock(dir, fn) {
467
+ const path = join(dir, SPOOL_LOCK_FILE);
468
+ const deadline = Date.now() + SPOOL_LOCK_WAIT_MS;
469
+ while (!createLockFile(path, SPOOL_LOCK_STALE_MS, Date.now())) {
470
+ if (Date.now() >= deadline)
471
+ throw new Error("telemetry spool is locked");
472
+ sleepSync(5);
473
+ }
474
+ try {
475
+ return fn();
476
+ } finally {
477
+ try {
478
+ unlinkSync(path);
479
+ } catch {}
480
+ }
481
+ }
482
+ function fileSize(path) {
483
+ try {
484
+ return statSync(path).size;
485
+ } catch {
486
+ return 0;
487
+ }
488
+ }
489
+ function parseEntries(text) {
490
+ const entries = [];
491
+ for (const line of text.split(`
492
+ `)) {
493
+ if (!line)
494
+ continue;
495
+ try {
496
+ const entry = JSON.parse(line);
497
+ if (entry && entry.v === 1 && typeof entry.url === "string" && typeof entry.profile === "string" && typeof entry.key === "string" && typeof entry.t === "number" && entry.event && typeof entry.event === "object") {
498
+ entries.push(entry);
499
+ }
500
+ } catch {}
501
+ }
502
+ return entries;
503
+ }
504
+ function sameGroup(a, b) {
505
+ return a.url === b.url && a.profile === b.profile && a.key === b.key;
506
+ }
507
+ function appendSpoolEntry(entry, dir = telemetrySpoolDir()) {
508
+ ensureDir(dir);
509
+ const path = join(dir, SPOOL_FILE);
510
+ const line = `${JSON.stringify(entry)}
511
+ `;
512
+ return withSpoolLock(dir, () => {
513
+ if (fileSize(path) + Buffer.byteLength(line) > SPOOL_MAX_BYTES)
514
+ return false;
515
+ appendLines(path, line);
516
+ return true;
517
+ });
518
+ }
519
+ function readSpool(dir = telemetrySpoolDir()) {
520
+ try {
521
+ return parseEntries(readFileSync(join(dir, SPOOL_FILE), "utf8"));
522
+ } catch {
523
+ return [];
524
+ }
525
+ }
526
+ function discardSpool(dir = telemetrySpoolDir()) {
527
+ try {
528
+ rmSync(join(dir, SPOOL_FILE), { force: true });
529
+ } catch {}
530
+ }
531
+ function flushDue(entries, group, now) {
532
+ let count = 0;
533
+ for (const entry of entries) {
534
+ if (!sameGroup(entry, group))
535
+ continue;
536
+ count += 1;
537
+ if (count >= FLUSH_MIN_EVENTS || now - entry.t >= FLUSH_MAX_AGE_MS)
538
+ return true;
539
+ }
540
+ return false;
541
+ }
542
+ function acquireFlushLock(dir = telemetrySpoolDir(), now = Date.now()) {
543
+ ensureDir(dir);
544
+ const path = join(dir, LOCK_FILE);
545
+ return createLockFile(path, FLUSH_LOCK_STALE_MS, now) ? path : undefined;
546
+ }
547
+ function releaseFlushLock(path) {
548
+ if (!path)
549
+ return;
550
+ try {
551
+ unlinkSync(path);
552
+ } catch {}
553
+ }
554
+ function claimSpoolGroup(group, dir = telemetrySpoolDir(), now = Date.now(), limit = Number.POSITIVE_INFINITY) {
555
+ try {
556
+ return withSpoolLock(dir, () => claimLocked(group, dir, now, limit));
557
+ } catch {
558
+ return [];
559
+ }
560
+ }
561
+ function claimLocked(group, dir, now, limit) {
562
+ const path = join(dir, SPOOL_FILE);
563
+ const claim = join(dir, `${SPOOL_FILE}.${process.pid}.${randomUUID()}.claim`);
564
+ try {
565
+ renameSync(path, claim);
566
+ } catch {
567
+ return [];
568
+ }
569
+ let entries = [];
570
+ try {
571
+ entries = parseEntries(readFileSync(claim, "utf8"));
572
+ } catch {} finally {
573
+ rmSync(claim, { force: true });
574
+ }
575
+ const mine = [];
576
+ const others = [];
577
+ for (const entry of entries) {
578
+ const age = now - entry.t;
579
+ if (age > SPOOL_MAX_EVENT_AGE_MS || age < -FLUSH_LOCK_STALE_MS)
580
+ continue;
581
+ (sameGroup(entry, group) && mine.length < limit ? mine : others).push(entry);
582
+ }
583
+ if (others.length > 0) {
584
+ try {
585
+ const text = others.map((entry) => `${JSON.stringify(entry)}
586
+ `).join("");
587
+ if (fileSize(path) + Buffer.byteLength(text) <= SPOOL_MAX_BYTES)
588
+ appendLines(path, text);
589
+ } catch {}
590
+ }
591
+ return mine;
592
+ }
593
+ function batchBodies(entries, now = Date.now()) {
594
+ const bodies = [];
595
+ for (let start = 0;start < entries.length; start += MAX_BATCH_EVENTS) {
596
+ const events = entries.slice(start, start + MAX_BATCH_EVENTS).map((entry) => ({ ...entry.event, age_ms: Math.min(SPOOL_MAX_EVENT_AGE_MS, Math.max(0, Math.round(now - entry.t))) }));
597
+ bodies.push(JSON.stringify(events));
598
+ }
599
+ return bodies;
600
+ }
601
+
602
+ // src/telemetry.ts
388
603
  var INLINE_TELEMETRY_TIMEOUT_MS = 500;
389
604
  var DETACHED_TELEMETRY_TIMEOUT_MS = 5000;
390
- var INVOCATION_ID = randomUUID();
605
+ var DETACHED_TELEMETRY_HARD_STOP_MS = 20000;
606
+ var MAX_FLUSH_BATCHES = Math.floor(DETACHED_TELEMETRY_HARD_STOP_MS / (2 * DETACHED_TELEMETRY_TIMEOUT_MS));
607
+ var INVOCATION_ID = randomUUID2();
391
608
  var TELEMETRY_FLAG = "no-telemetry";
392
609
  var TELEMETRY_TRANSPORT_ENV = "MODA_CLI_TELEMETRY_TRANSPORT";
393
610
  var MAX_TELEMETRY_DURATION_MS = 86400000;
@@ -557,48 +774,103 @@ function safeCode(value) {
557
774
  var TELEMETRY_SENDER_SCRIPT = [
558
775
  "try {",
559
776
  " let raw = '';",
560
- ` const quit = setTimeout(() => process.exit(0), ${DETACHED_TELEMETRY_TIMEOUT_MS + 1000});`,
561
- " const done = () => clearTimeout(quit);",
777
+ " let lock;",
778
+ " const release = () => { if (typeof lock === 'string') { try { require('node:fs').unlinkSync(lock); } catch {} lock = undefined; } };",
779
+ ` const quit = setTimeout(() => { release(); process.exit(0); }, ${DETACHED_TELEMETRY_HARD_STOP_MS});`,
780
+ " const done = () => { release(); clearTimeout(quit); };",
781
+ " const post = (r, body) => new Promise((resolve) => {",
782
+ " try {",
783
+ " const u = new URL(r.url);",
784
+ " const lib = require(u.protocol === 'https:' ? 'node:https' : 'node:http');",
785
+ " const headers = Object.assign({}, r.headers, { 'Content-Length': Buffer.byteLength(body) });",
786
+ ` const req = lib.request(u, { method: 'POST', headers, agent: false, timeout: ${DETACHED_TELEMETRY_TIMEOUT_MS} }, (res) => {`,
787
+ " res.on('error', () => resolve(0));",
788
+ " res.on('end', () => resolve(res.statusCode || 0));",
789
+ " res.resume();",
790
+ " });",
791
+ " req.on('timeout', () => req.destroy());",
792
+ " req.on('error', () => resolve(0));",
793
+ " req.end(body);",
794
+ " } catch { resolve(0); }",
795
+ " });",
796
+ " const run = async (requests) => {",
797
+ " for (const r of requests) {",
798
+ " if (!r || typeof r.url !== 'string' || typeof r.body !== 'string' || !r.headers || typeof r.headers !== 'object') continue;",
799
+ " const status = await post(r, r.body);",
800
+ " if (status !== 400 || r.body[0] !== '[') continue;",
801
+ " let events = [];",
802
+ " try { events = JSON.parse(r.body); } catch {}",
803
+ " await Promise.all((Array.isArray(events) ? events : []).map((event) => post(r, JSON.stringify(event))));",
804
+ " }",
805
+ " };",
562
806
  " process.stdin.setEncoding('utf8');",
563
807
  " process.stdin.on('error', () => {});",
564
808
  " process.stdin.on('data', (chunk) => { raw += chunk; });",
565
809
  " process.stdin.on('end', () => {",
566
- " try {",
567
- " const r = raw ? JSON.parse(raw) : null;",
568
- " raw = '';",
569
- " if (!r || typeof r.url !== 'string' || typeof fetch !== 'function') return done();",
570
- " const c = new AbortController();",
571
- ` const t = setTimeout(() => c.abort(), ${DETACHED_TELEMETRY_TIMEOUT_MS});`,
572
- " fetch(r.url, { method: 'POST', headers: r.headers, body: r.body, signal: c.signal })",
573
- " .then((res) => (res.body && res.body.cancel ? res.body.cancel() : undefined))",
574
- " .catch(() => {})",
575
- " .finally(() => { clearTimeout(t); done(); });",
576
- " } catch { done(); }",
810
+ " let job = null;",
811
+ " try { job = raw ? JSON.parse(raw) : null; } catch {}",
812
+ " raw = '';",
813
+ " if (job && typeof job.lock === 'string') lock = job.lock;",
814
+ " const requests = job && Array.isArray(job.requests) ? job.requests : [];",
815
+ " run(requests).catch(() => {}).finally(done);",
577
816
  " });",
578
817
  "} catch {}"
579
818
  ].join(`
580
819
  `);
581
- function spawnDetachedTelemetrySender(request, spawnImpl = spawn2) {
582
- return spawnDetachedNode(TELEMETRY_SENDER_SCRIPT, { stdin: JSON.stringify(request), dropEnv: ["MODA_API_KEY"] }, spawnImpl);
820
+ function spawnDetachedTelemetrySender(job, spawnImpl = spawn2) {
821
+ return spawnDetachedNode(TELEMETRY_SENDER_SCRIPT, { stdin: JSON.stringify(job), dropEnv: ["MODA_API_KEY"] }, spawnImpl);
822
+ }
823
+ async function sendTelemetryJobInline(job) {
824
+ try {
825
+ for (const pending of job.requests)
826
+ await sendInline(pending);
827
+ } finally {
828
+ releaseFlushLock(job.lock);
829
+ }
583
830
  }
584
831
  async function sendInline(request) {
832
+ const status = await postInline(request);
833
+ if (status !== 400 || !request.body.startsWith("["))
834
+ return;
835
+ let events = [];
836
+ try {
837
+ events = JSON.parse(request.body);
838
+ } catch {}
839
+ if (!Array.isArray(events))
840
+ return;
841
+ await Promise.all(events.map((event) => postInline({ ...request, body: JSON.stringify(event) })));
842
+ }
843
+ async function postInline(request) {
585
844
  const controller = new AbortController;
586
845
  const timeout = setTimeout(() => controller.abort(), INLINE_TELEMETRY_TIMEOUT_MS);
587
846
  if (typeof timeout.unref === "function") {
588
847
  timeout.unref();
589
848
  }
590
849
  try {
591
- await fetch(request.url, {
850
+ const response = await fetch(request.url, {
592
851
  method: "POST",
593
852
  headers: request.headers,
594
853
  body: request.body,
595
854
  signal: controller.signal
596
855
  });
597
- } catch {} finally {
856
+ return response.status;
857
+ } catch {
858
+ return 0;
859
+ } finally {
598
860
  clearTimeout(timeout);
599
861
  }
600
862
  }
601
- function buildCliUsageRequest(input) {
863
+ function usageRequest(baseUrl, apiKey, body) {
864
+ return {
865
+ url: `${baseUrl}/api/v1/data/cli-usage`,
866
+ headers: {
867
+ ...apiKeyHeaders(apiKey),
868
+ "Content-Type": "application/json"
869
+ },
870
+ body
871
+ };
872
+ }
873
+ function buildCliUsageEvent(input) {
602
874
  const baseUrl = resolveModaBaseUrlStrict(input.profile ? { profile: input.profile } : {});
603
875
  if (!baseUrl)
604
876
  return;
@@ -610,12 +882,8 @@ function buildCliUsageRequest(input) {
610
882
  delete adoption[key];
611
883
  }
612
884
  return {
613
- url: `${baseUrl}/api/v1/data/cli-usage`,
614
- headers: {
615
- ...apiKeyHeaders(input.apiKey),
616
- "Content-Type": "application/json"
617
- },
618
- body: JSON.stringify({
885
+ baseUrl,
886
+ event: {
619
887
  invocation_id: INVOCATION_ID,
620
888
  command: safeCode(input.command.slice(0, 64)) ?? "unknown",
621
889
  status: input.status,
@@ -634,27 +902,79 @@ function buildCliUsageRequest(input) {
634
902
  ...((alias) => alias ? { legacy_alias: alias } : {})(safeCode(sanitizeReasonCode(input.legacyAlias?.replace(/ /g, ":"), 64)))
635
903
  },
636
904
  ...adoption
637
- })
905
+ }
638
906
  };
639
907
  }
908
+ function telemetryProfileName(profile) {
909
+ try {
910
+ return getActiveProfile(profile ? { profile } : {}).name;
911
+ } catch {
912
+ return "";
913
+ }
914
+ }
915
+ function queueCliUsageEvent(request, group, event, now) {
916
+ const dir = telemetrySpoolDir();
917
+ const entry = { v: 1, ...group, t: now, event };
918
+ let unspooled = [];
919
+ try {
920
+ if (!appendSpoolEntry(entry, dir))
921
+ unspooled = [entry];
922
+ } catch {
923
+ return { requests: [request] };
924
+ }
925
+ const due = unspooled.length > 0 || envOptOutSet(process.env.CI) || flushDue(readSpool(dir), group, now);
926
+ if (!due)
927
+ return;
928
+ const lock = acquireFlushLock(dir, now);
929
+ if (!lock)
930
+ return unspooled.length > 0 ? { requests: [request] } : undefined;
931
+ const limit = MAX_FLUSH_BATCHES * MAX_BATCH_EVENTS - unspooled.length;
932
+ const entries = [...claimSpoolGroup(group, dir, now, limit), ...unspooled];
933
+ if (entries.length === 0) {
934
+ releaseFlushLock(lock);
935
+ return;
936
+ }
937
+ return {
938
+ requests: batchBodies(entries, now).map((body) => ({ url: request.url, headers: request.headers, body })),
939
+ lock
940
+ };
941
+ }
942
+ function discardSpoolOnEnvOptOut() {
943
+ if (!isTelemetryDisabled({}))
944
+ return false;
945
+ discardSpool();
946
+ return true;
947
+ }
640
948
  async function sendCliUsageTelemetry(input) {
641
949
  try {
950
+ if (discardSpoolOnEnvOptOut())
951
+ return;
642
952
  if (!input.apiKey || isTelemetryDisabled(input.flags)) {
643
953
  return;
644
954
  }
645
- const request = buildCliUsageRequest({ ...input, apiKey: input.apiKey });
646
- if (!request)
955
+ const built = buildCliUsageEvent(input);
956
+ if (!built)
647
957
  return;
648
- if (process.env[TELEMETRY_TRANSPORT_ENV] !== "inline" && spawnDetachedTelemetrySender(request)) {
958
+ const request = usageRequest(built.baseUrl, input.apiKey, JSON.stringify(built.event));
959
+ if (process.env[TELEMETRY_TRANSPORT_ENV] === "inline") {
960
+ await sendInline(request);
649
961
  return;
650
962
  }
651
- await sendInline(request);
963
+ const group = {
964
+ url: built.baseUrl,
965
+ profile: telemetryProfileName(input.profile),
966
+ key: keyFingerprint(input.apiKey)
967
+ };
968
+ const job = queueCliUsageEvent(request, group, built.event, Date.now());
969
+ if (!job || spawnDetachedTelemetrySender(job))
970
+ return;
971
+ await sendTelemetryJobInline(job);
652
972
  } catch {}
653
973
  }
654
974
 
655
975
  // src/update-check.ts
656
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
657
- import { join } from "node:path";
976
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "node:fs";
977
+ import { join as join2 } from "node:path";
658
978
  var UPDATE_CHECK_FLAG = "no-update-check";
659
979
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
660
980
  var REGISTRY_TIMEOUT_MS = 1500;
@@ -667,11 +987,11 @@ function isUpdateCheckDisabled(flags, env = process.env) {
667
987
  return optOutFlagSet(flags, UPDATE_CHECK_FLAG) || envSwitchedOff(env.MODA_CLI_UPDATE_CHECK) || envOptOutSet(env.DO_NOT_TRACK) || envOptOutSet(env.CI);
668
988
  }
669
989
  function cachePath(options = {}) {
670
- return join(getModaDir(options), "update-check.json");
990
+ return join2(getModaDir(options), "update-check.json");
671
991
  }
672
992
  function readCache(options = {}) {
673
993
  try {
674
- const parsed = JSON.parse(readFileSync(cachePath(options), "utf8"));
994
+ const parsed = JSON.parse(readFileSync2(cachePath(options), "utf8"));
675
995
  if (parsed && typeof parsed === "object" && typeof parsed.checked_at === "number" && typeof parsed.latest === "string") {
676
996
  return parsed;
677
997
  }
@@ -680,7 +1000,7 @@ function readCache(options = {}) {
680
1000
  }
681
1001
  function writeCache(cache, options = {}) {
682
1002
  try {
683
- mkdirSync(getModaDir(options), { recursive: true });
1003
+ mkdirSync2(getModaDir(options), { recursive: true });
684
1004
  writeFileSync(cachePath(options), `${JSON.stringify(cache, null, 2)}
685
1005
  `, "utf8");
686
1006
  } catch {}
@@ -2639,46 +2959,46 @@ function leafManifestFields(leaf, commands) {
2639
2959
  import { fileURLToPath } from "url";
2640
2960
  import { realpathSync } from "fs";
2641
2961
  async function runPromptsCommand(...args) {
2642
- return (await import("./prompts-17wyrst6.js")).runPromptsCommand(...args);
2962
+ return (await import("./prompts-6y9wfq5z.js")).runPromptsCommand(...args);
2643
2963
  }
2644
2964
  async function runSkillsCommand(...args) {
2645
- return (await import("./skills-ccdbqghj.js")).runSkillsCommand(...args);
2965
+ return (await import("./skills-j8865009.js")).runSkillsCommand(...args);
2646
2966
  }
2647
2967
  async function runFixCommand(...args) {
2648
- return (await import("./fix-75s9s0d6.js")).runFixCommand(...args);
2968
+ return (await import("./fix-w5z02wt4.js")).runFixCommand(...args);
2649
2969
  }
2650
2970
  async function runFixesCommand(...args) {
2651
- return (await import("./fix-75s9s0d6.js")).runFixesCommand(...args);
2971
+ return (await import("./fix-w5z02wt4.js")).runFixesCommand(...args);
2652
2972
  }
2653
2973
  async function runHarnessCommand(...args) {
2654
- return (await import("./harness-a7tb9a23.js")).runHarnessCommand(...args);
2974
+ return (await import("./harness-7azmzytc.js")).runHarnessCommand(...args);
2655
2975
  }
2656
2976
  async function runSyncCommand(...args) {
2657
- return (await import("./sync-hkxce5zh.js")).runSyncCommand(...args);
2977
+ return (await import("./sync-ew7yvy0e.js")).runSyncCommand(...args);
2658
2978
  }
2659
2979
  async function runRegistryCommand(...args) {
2660
- return (await import("./registry-fpzhjznj.js")).runRegistryCommand(...args);
2980
+ return (await import("./registry-96aze5wp.js")).runRegistryCommand(...args);
2661
2981
  }
2662
2982
  async function runDoctorCommand(...args) {
2663
- return (await import("./doctor-wmre3mr7.js")).runDoctorCommand(...args);
2983
+ return (await import("./doctor-k3ta6h2y.js")).runDoctorCommand(...args);
2664
2984
  }
2665
2985
  async function runStatusCommand(...args) {
2666
- return (await import("./doctor-wmre3mr7.js")).runStatusCommand(...args);
2986
+ return (await import("./doctor-k3ta6h2y.js")).runStatusCommand(...args);
2667
2987
  }
2668
2988
  async function runAuthCommand(...args) {
2669
- return (await import("./profile-commands-49yn02yg.js")).runAuthCommand(...args);
2989
+ return (await import("./profile-commands-h8evz9x0.js")).runAuthCommand(...args);
2670
2990
  }
2671
2991
  async function runConfigCommand(...args) {
2672
- return (await import("./profile-commands-49yn02yg.js")).runConfigCommand(...args);
2992
+ return (await import("./profile-commands-h8evz9x0.js")).runConfigCommand(...args);
2673
2993
  }
2674
2994
  async function runProfilesCommand(...args) {
2675
- return (await import("./profile-commands-49yn02yg.js")).runProfilesCommand(...args);
2995
+ return (await import("./profile-commands-h8evz9x0.js")).runProfilesCommand(...args);
2676
2996
  }
2677
2997
  async function runAgentCommand(...args) {
2678
- return (await import("./agent-vp9prdma.js")).runAgentCommand(...args);
2998
+ return (await import("./agent-0w9rtdsw.js")).runAgentCommand(...args);
2679
2999
  }
2680
3000
  async function runProductionCommand(...args) {
2681
- return (await import("./production-intelligence-7nqddd4f.js")).runProductionCommand(...args);
3001
+ return (await import("./production-intelligence-wvsgjxth.js")).runProductionCommand(...args);
2682
3002
  }
2683
3003
  function parseArgs(argv) {
2684
3004
  const args = argv.slice(2);
@@ -3376,23 +3696,21 @@ function noWorldStateWarnings(conversationId, isMissing) {
3376
3696
  }
3377
3697
  var AUDIT_DEFAULT_LIMIT = 200;
3378
3698
  var AUDIT_MAX_LIMIT = 1000;
3379
- function auditCapStatus(data, limit) {
3699
+ function auditCapStatus(data) {
3380
3700
  const record = asRecord(data);
3381
3701
  if (!record)
3382
3702
  return null;
3383
3703
  const summary = asRecord(record.summary) ?? {};
3384
3704
  const rows = (asNumber(summary.ingest_rows) ?? (Array.isArray(record.ingest) ? record.ingest.length : 0)) + (asNumber(record.parse_errors) ?? 0);
3385
3705
  const spans = asNumber(summary.total_spans) ?? (Array.isArray(record.spans) ? record.spans.length : 0);
3386
- const hasMore = record.has_more === true || summary.has_more === true;
3706
+ const rowsCapped = record.has_more === true || summary.has_more === true;
3387
3707
  const spansCapped = summary.truncated === true || record.truncated === true;
3388
- const serverSaid = typeof record.has_more === "boolean" || typeof summary.has_more === "boolean";
3389
- const rowsCapped = hasMore || !serverSaid && rows >= limit;
3390
3708
  if (!rowsCapped && !spansCapped)
3391
3709
  return null;
3392
3710
  const reason = typeof summary.truncated_reason === "string" ? summary.truncated_reason : null;
3393
3711
  const cursorValue = summary.next_cursor ?? record.next_cursor;
3394
3712
  const nextCursor = typeof cursorValue === "string" && cursorValue ? cursorValue : null;
3395
- return { rowsCapped, spansCapped, hasMoreKnown: hasMore, rows, spans, reason, nextCursor };
3713
+ return { rowsCapped, spansCapped, rows, spans, reason, nextCursor };
3396
3714
  }
3397
3715
  var AUDIT_AGENT_RESERVE_BYTES = 16384;
3398
3716
  function auditMaxBytes(budgetBytes) {
@@ -3463,7 +3781,7 @@ function auditOutput(command, params, data, keep) {
3463
3781
  }
3464
3782
  };
3465
3783
  }
3466
- const capped = auditCapStatus(data, limit);
3784
+ const capped = auditCapStatus(data);
3467
3785
  if (!capped || !record) {
3468
3786
  return {
3469
3787
  data: record ? { ...record, truncated: false, has_more: false, next_cursor: null } : data,
@@ -3488,7 +3806,7 @@ function auditOutput(command, params, data, keep) {
3488
3806
  warnings.push(`Spans were capped: the page reached the server's per-page span cap after ${capped.rows} ingest row(s), so this trace has more spans than the ${shownText}. Continue with the next_cursor page. Orphan/duplicate analysis covers this page only.`);
3489
3807
  } else if (capped.rowsCapped) {
3490
3808
  const bigger = Math.min(AUDIT_MAX_LIMIT, limit * 5);
3491
- warnings.push(`Spans were capped: read ${capped.rows} ingest row(s), the --limit=${limit} maximum, so this trace ${capped.hasMoreKnown ? "has" : "may have"} more spans than the ${shownText}. ` + (capped.nextCursor ? "Page on with the next_cursor command, or " : "") + (limit < AUDIT_MAX_LIMIT ? `${capped.nextCursor ? "rerun" : "Rerun"} with --limit=${bigger} (max ${AUDIT_MAX_LIMIT}), or ${perTrace}.` : capped.nextCursor ? `${perTrace}.` : `${perTrace[0].toUpperCase()}${perTrace.slice(1)}.`));
3809
+ warnings.push(`Spans were capped: read ${capped.rows} ingest row(s), the --limit=${limit} maximum, so this trace has more spans than the ${shownText}. ` + (capped.nextCursor ? "Page on with the next_cursor command, or " : "") + (limit < AUDIT_MAX_LIMIT ? `${capped.nextCursor ? "rerun" : "Rerun"} with --limit=${bigger} (max ${AUDIT_MAX_LIMIT}), or ${perTrace}.` : capped.nextCursor ? `${perTrace}.` : `${perTrace[0].toUpperCase()}${perTrace.slice(1)}.`));
3492
3810
  if (limit < AUDIT_MAX_LIMIT && !params.cursor && !sliced) {
3493
3811
  nextCommands.push({ command: auditFlags([`--limit=${bigger}`]), purpose: "Read more ingest rows of this trace.", mutability: "read", requires_approval: false });
3494
3812
  }
@@ -4257,8 +4575,18 @@ var CONTEXT_BUDGET_BYTES_PER_FIRST_PAGE_MESSAGE = 480;
4257
4575
  function jsonByteLength(value) {
4258
4576
  return Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
4259
4577
  }
4260
- var LEGACY_WINDOW_MAX_MESSAGES = 100;
4261
- var CONTEXT_MESSAGE_TRUNCATE_CHARS = 500;
4578
+ function largestFittingCount(max, fits) {
4579
+ let low = 1;
4580
+ let high = Math.max(1, max);
4581
+ while (low < high) {
4582
+ const mid = Math.ceil((low + high) / 2);
4583
+ if (fits(mid))
4584
+ low = mid;
4585
+ else
4586
+ high = mid - 1;
4587
+ }
4588
+ return low;
4589
+ }
4262
4590
  var LONE_SURROGATE = /[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/g;
4263
4591
  function stripLoneSurrogates(value) {
4264
4592
  if (typeof value === "string")
@@ -4270,13 +4598,6 @@ function stripLoneSurrogates(value) {
4270
4598
  }
4271
4599
  return value;
4272
4600
  }
4273
- function isUnknownRangeParamsError(error) {
4274
- const e = error;
4275
- if (e?.statusCode !== 400)
4276
- return false;
4277
- const text = `${typeof e.responseBody === "string" ? e.responseBody : ""} ${typeof e.message === "string" ? e.message : ""}`;
4278
- return /property (from|count) should not exist/i.test(text);
4279
- }
4280
4601
  function pageMessages(page) {
4281
4602
  const messages = asRecord(page.context)?.messages ?? page.messages;
4282
4603
  return (Array.isArray(messages) ? messages : []).map((m) => asRecord(m) ?? {});
@@ -4286,13 +4607,11 @@ async function readFullTranscript(conversationId, opts = {}) {
4286
4607
  const start = opts.from ?? 0;
4287
4608
  const requested = opts.maxMessages ?? FULL_TRANSCRIPT_DEFAULT_MAX_MESSAGES;
4288
4609
  const path = `/conversations/${encodeURIComponent(conversationId)}/context`;
4289
- const warnings = [];
4290
4610
  const messages = [];
4291
4611
  let total = 0;
4292
4612
  let summary = null;
4293
4613
  let ordering;
4294
4614
  let nextFrom = null;
4295
- let legacy = false;
4296
4615
  let cursor = start;
4297
4616
  let readBytes = 0;
4298
4617
  const byteBudget = opts.fits ? opts.maxBytes : undefined;
@@ -4303,22 +4622,13 @@ async function readFullTranscript(conversationId, opts = {}) {
4303
4622
  const estimate = average > 0 ? Math.ceil(Math.max(0, byteBudget - readBytes) / average) + 1 : Math.max(1, Math.floor(byteBudget / CONTEXT_BUDGET_BYTES_PER_FIRST_PAGE_MESSAGE));
4304
4623
  count = Math.max(1, Math.min(count, estimate));
4305
4624
  }
4306
- let page;
4307
- try {
4308
- page = asRecord(await callDataAPI(`${path}?from=${cursor}&count=${count}`)) ?? {};
4309
- } catch (error) {
4310
- if (cursor === start && isUnknownRangeParamsError(error)) {
4311
- legacy = true;
4312
- break;
4313
- }
4314
- throw error;
4315
- }
4625
+ const page = asRecord(await callDataAPI(`${path}?from=${cursor}&count=${count}`)) ?? {};
4316
4626
  if (cursor === start) {
4317
4627
  total = asNumber(page.total_messages) ?? 0;
4318
- summary = page.summary ?? null;
4319
- ordering = asRecord(page.ordering) ?? undefined;
4628
+ summary = stripLoneSurrogates(page.summary ?? null);
4629
+ ordering = stripLoneSurrogates(asRecord(page.ordering) ?? undefined);
4320
4630
  }
4321
- const batch = pageMessages(page);
4631
+ const batch = stripLoneSurrogates(pageMessages(page));
4322
4632
  messages.push(...batch);
4323
4633
  if (byteBudget !== undefined)
4324
4634
  readBytes += batch.reduce((sum, message) => sum + jsonByteLength(message) + 1, 0);
@@ -4330,46 +4640,13 @@ async function readFullTranscript(conversationId, opts = {}) {
4330
4640
  break;
4331
4641
  cursor = nextFrom;
4332
4642
  }
4333
- if (legacy) {
4334
- const limit = Math.min(requested, LEGACY_WINDOW_MAX_MESSAGES);
4335
- const window = 5;
4336
- const span = window * 2 + 1;
4337
- const byIndex = new Map;
4338
- for (let center = start + window;; center += span) {
4339
- const page = asRecord(await callDataAPI(`${path}?msg_index=${center}&window=${window}`)) ?? {};
4340
- if (center === start + window) {
4341
- total = asNumber(page.total_messages) ?? 0;
4342
- summary = page.summary ?? null;
4343
- }
4344
- for (const message of pageMessages(page)) {
4345
- const index = asNumber(message.index);
4346
- if (index !== null && index !== undefined && index >= start && index < start + limit)
4347
- byIndex.set(index, message);
4348
- }
4349
- if (center + window + 1 >= Math.min(total, start + limit))
4350
- break;
4351
- }
4352
- messages.push(...[...byIndex.entries()].sort(([a], [b]) => a - b).map(([, message]) => message));
4353
- const end = start + messages.length;
4354
- nextFrom = end < total && messages.length > 0 ? end : null;
4355
- warnings.push(`This Moda server has no range reads for context (older backend), so --all fell back to windowed paging and stopped at ${LEGACY_WINDOW_MAX_MESSAGES} messages to keep it cheap.`);
4356
- }
4357
4643
  throwIfNotFound("trace", conversationId, total === 0);
4358
- const pageSize = legacy ? LEGACY_WINDOW_MAX_MESSAGES : requested;
4644
+ const pageSize = requested;
4359
4645
  const tied = asNumber(ordering?.tied_timestamp_messages) ?? 0;
4360
4646
  const synthetic = asNumber(ordering?.synthetic_timestamp_messages) ?? 0;
4361
- const atCap = (value) => {
4362
- const text = typeof value === "string" ? value : value === undefined || value === null ? "" : JSON.stringify(value);
4363
- return text.length >= CONTEXT_MESSAGE_TRUNCATE_CHARS;
4364
- };
4365
- const isTruncated = (record) => {
4366
- const toolCalls = Array.isArray(record.tool_calls) ? record.tool_calls : [];
4367
- const toolResults = Array.isArray(record.tool_results) ? record.tool_results : [];
4368
- return atCap(record.content) || toolCalls.some((call) => atCap(asRecord(call)?.input)) || toolResults.some((result) => atCap(asRecord(result)?.content));
4369
- };
4370
4647
  const build = (kept) => {
4371
4648
  const returned = messages.slice(0, kept);
4372
- const out = [...warnings];
4649
+ const out = [];
4373
4650
  if (total > 0 && start >= total) {
4374
4651
  out.push(`--from=${start} is past the end of this trace (${total} messages, indexes 0-${total - 1}).`);
4375
4652
  }
@@ -4391,12 +4668,9 @@ async function readFullTranscript(conversationId, opts = {}) {
4391
4668
  if (tied > 0 || synthetic > 0) {
4392
4669
  out.push(`Message order may not be chronological: ${tied} of ${total} messages share a timestamp with another message (ordered by id, not time)${synthetic > 0 ? ` and ${synthetic} carry a synthetic pre-2022 timestamp` : ""}.`);
4393
4670
  }
4394
- if (legacy && returned.some(isTruncated)) {
4395
- out.push(`This Moda server is older and truncates message text, tool-call inputs and tool results longer than ${CONTEXT_MESSAGE_TRUNCATE_CHARS} characters. For full content (prompts, tool arguments/results) use \`moda traces spans <conversation_id> --include-bodies\` (or \`--include-raw\` for the verbatim events).`);
4396
- }
4397
4671
  return {
4398
- data: stripLoneSurrogates({
4399
- conversation_id: conversationId,
4672
+ data: {
4673
+ conversation_id: stripLoneSurrogates(conversationId),
4400
4674
  total_messages: total,
4401
4675
  from: start,
4402
4676
  returned: returned.length,
@@ -4405,7 +4679,7 @@ async function readFullTranscript(conversationId, opts = {}) {
4405
4679
  summary,
4406
4680
  ...ordering ? { ordering } : {},
4407
4681
  messages: returned
4408
- }),
4682
+ },
4409
4683
  warnings: out,
4410
4684
  nextCommands
4411
4685
  };
@@ -4413,18 +4687,10 @@ async function readFullTranscript(conversationId, opts = {}) {
4413
4687
  const full = build(messages.length);
4414
4688
  if (!opts.fits || messages.length <= 1 || opts.fits(full))
4415
4689
  return full;
4416
- let low = 1;
4417
- let high = messages.length - 1;
4418
- while (low < high) {
4419
- const mid = Math.ceil((low + high) / 2);
4420
- if (opts.fits(build(mid)))
4421
- low = mid;
4422
- else
4423
- high = mid - 1;
4424
- }
4425
- return build(low);
4690
+ const fits = opts.fits;
4691
+ return build(largestFittingCount(messages.length - 1, (kept) => fits(build(kept))));
4426
4692
  }
4427
- async function readContextItem(command, params, inputWarnings, budget) {
4693
+ async function readContextItem(params, inputWarnings, budget) {
4428
4694
  const fits = budget?.fits;
4429
4695
  if (params.all === true) {
4430
4696
  const full = await readFullTranscript(params.conversation_id, {
@@ -4533,17 +4799,10 @@ function trimContextWindow(conversationId, record, requestedAnchor, fits) {
4533
4799
  };
4534
4800
  return { data, warnings, nextCommands };
4535
4801
  };
4536
- let low = 1;
4537
- let high = order.length;
4538
- while (low < high) {
4539
- const mid = Math.ceil((low + high) / 2);
4540
- const page = build(mid);
4541
- if (fits(page.data, page.warnings, page.nextCommands))
4542
- low = mid;
4543
- else
4544
- high = mid - 1;
4545
- }
4546
- return build(low);
4802
+ return build(largestFittingCount(order.length, (kept) => {
4803
+ const page = build(kept);
4804
+ return fits(page.data, page.warnings, page.nextCommands);
4805
+ }));
4547
4806
  }
4548
4807
  var AUDIT_USAGE = "Usage: moda traces spans <conversation_id|trace_id> [--kind=auto|trace|conversation] [--include-raw] [--include-bodies] [--limit=N] [--cursor=<next_cursor>]";
4549
4808
  var AUDIT_BATCH_USAGE = `Usage: moda traces spans <id> <id> ... | --ids-from=-|<file> [--kind=auto|trace|conversation] [--include-raw] [--include-bodies] [--limit=N] (max ${BATCH_MAX_TARGETS} targets)`;
@@ -4569,16 +4828,10 @@ async function readAuditItem(command, params, budget) {
4569
4828
  const available = (Array.isArray(spans) ? spans.length : 0) - (params.span_offset ?? 0);
4570
4829
  if (available <= 0)
4571
4830
  return whole;
4572
- let low = 1;
4573
- let high = available;
4574
- while (low < high) {
4575
- const mid = Math.ceil((low + high) / 2);
4576
- const page2 = auditOutput(command, params, raw, mid);
4577
- if (budget.fits(page2.data, page2.options))
4578
- low = mid;
4579
- else
4580
- high = mid - 1;
4581
- }
4831
+ const low = largestFittingCount(available, (keep) => {
4832
+ const page2 = auditOutput(command, params, raw, keep);
4833
+ return budget.fits(page2.data, page2.options);
4834
+ });
4582
4835
  const page = auditOutput(command, params, raw, low);
4583
4836
  if (low === 1 && !budget.fits(page.data, page.options)) {
4584
4837
  page.options.warnings = [
@@ -4661,7 +4914,7 @@ async function readBatchTargets(targets, agentMode, read) {
4661
4914
  });
4662
4915
  }
4663
4916
  function fitsShare(share) {
4664
- return (data, options) => Buffer.byteLength(JSON.stringify({ data, ...options }) ?? "", "utf8") <= share;
4917
+ return (data, options) => jsonByteLength({ data, ...options }) <= share;
4665
4918
  }
4666
4919
  function isBatchFatal(error) {
4667
4920
  const type = classifyCliError(error);
@@ -4776,7 +5029,7 @@ async function runContextBatch(command, positionals, flags, context) {
4776
5029
  conversation_id: target.id,
4777
5030
  ...target.msgIndex !== undefined ? { msg_index: target.msgIndex } : {}
4778
5031
  };
4779
- return withAnchorHint(target, () => readContextItem(command, params, [], budget));
5032
+ return withAnchorHint(target, () => readContextItem(params, [], budget));
4780
5033
  });
4781
5034
  return writeBatchResult(command, context, targets, results, inputWarnings, rest);
4782
5035
  }
@@ -4983,16 +5236,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
4983
5236
  return agentEnvelopeFits(command, page2.data, page2.options);
4984
5237
  };
4985
5238
  if (agentMode && kept > 1 && !fitsAgent(kept)) {
4986
- let low = 1;
4987
- let high = kept - 1;
4988
- while (low < high) {
4989
- const mid = Math.ceil((low + high) / 2);
4990
- if (fitsAgent(mid))
4991
- low = mid;
4992
- else
4993
- high = mid - 1;
4994
- }
4995
- kept = low;
5239
+ kept = largestFittingCount(kept - 1, fitsAgent);
4996
5240
  }
4997
5241
  const page = write(kept);
4998
5242
  recordSearchTelemetry(context, page.data);
@@ -5054,7 +5298,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
5054
5298
  return runContextBatch(command, positionals, flags, context);
5055
5299
  const { params, warnings: inputWarnings } = parseContextRequest(...singleContextTarget(positional, flags));
5056
5300
  const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
5057
- const read = () => readContextItem(command, params, inputWarnings, agentMode ? { fits: (data, options) => agentEnvelopeFits(command, data, options), maxBytes: agentMaxOutputBytes() } : undefined);
5301
+ const read = () => readContextItem(params, inputWarnings, agentMode ? { fits: (data, options) => agentEnvelopeFits(command, data, options), maxBytes: agentMaxOutputBytes() } : undefined);
5058
5302
  const item = positional === undefined ? await read() : await withAnchorHint(parseBatchTarget(positional, true, CONTEXT_USAGE), read);
5059
5303
  context.output.writeData(item.data, item.options);
5060
5304
  break;
@@ -5518,7 +5762,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
5518
5762
  }
5519
5763
  const data = await callDataAPI(reviewPath, {
5520
5764
  method: "POST",
5521
- body: JSON.stringify({ ...reviewBody, request_nonce: randomUUID2() }),
5765
+ body: JSON.stringify({ ...reviewBody, request_nonce: randomUUID3() }),
5522
5766
  headers: { "Content-Type": "application/json" }
5523
5767
  });
5524
5768
  context.output.writeData(data);
@@ -5611,7 +5855,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
5611
5855
  });
5612
5856
  break;
5613
5857
  }
5614
- const sentBody = request.body && request.nonce ? { ...request.body, request_nonce: randomUUID2() } : request.body;
5858
+ const sentBody = request.body && request.nonce ? { ...request.body, request_nonce: randomUUID3() } : request.body;
5615
5859
  const data = await callDataAPI(request.path, {
5616
5860
  method: request.method,
5617
5861
  ...sentBody ? { body: JSON.stringify(sentBody), headers: { "Content-Type": "application/json" } } : {}
@@ -5767,7 +6011,6 @@ async function runCommand(command, positional, flags, positionals = positional ?
5767
6011
  function telemetryCommandName(definition) {
5768
6012
  return definition.telemetryCommand ?? definition.name;
5769
6013
  }
5770
- var TELEMETRY_EXEMPT_COMMANDS = {};
5771
6014
  function telemetrySubcommandNames(definition) {
5772
6015
  return [
5773
6016
  ...definition.subcommands?.map((subcommand) => subcommand.name) ?? [],
@@ -5900,7 +6143,7 @@ var commandRegistry = createCommandRegistry([
5900
6143
  resetApiRequestCountBeforeRun: true,
5901
6144
  telemetry: "result-and-error",
5902
6145
  handler: async (context) => {
5903
- const { runInit } = await import("./index-91bpc8g8.js");
6146
+ const { runInit } = await import("./index-d1z50dsq.js");
5904
6147
  if (context.outputMode === "agent-stream") {
5905
6148
  context.output.writeEvent({
5906
6149
  event: "started",
@@ -5950,7 +6193,7 @@ var commandRegistry = createCommandRegistry([
5950
6193
  resetApiRequestCountBeforeRun: true,
5951
6194
  telemetry: "result-and-error",
5952
6195
  handler: async (context) => {
5953
- const { runProvision } = await import("./provision-bc3h68e1.js");
6196
+ const { runProvision } = await import("./provision-y5bdbh4y.js");
5954
6197
  return runProvision(context, {
5955
6198
  resumeCommand: buildResumeCommand("provision", context.rawFlags)
5956
6199
  });
@@ -7174,6 +7417,8 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
7174
7417
  const switchError = normalizeBooleanFlags(flags);
7175
7418
  const typedFlags = stripUpdateCheckFlag(stripTelemetryFlag(flags));
7176
7419
  const telemetryDisabled = isTelemetryDisabled(flags);
7420
+ if (telemetryDisabled)
7421
+ discardSpoolOnEnvOptOut();
7177
7422
  const updateCheckDisabled = isUpdateCheckDisabled(flags);
7178
7423
  if (command === "--version" || command === "-V" || flags.version === "true") {
7179
7424
  console.log(`moda-cli ${VERSION}`);
@@ -7479,7 +7724,6 @@ export {
7479
7724
  trimContextWindow,
7480
7725
  telemetrySubcommandNames,
7481
7726
  telemetryCommandName,
7482
- stripLoneSurrogates,
7483
7727
  searchOutcomeWarnings,
7484
7728
  searchDegradeWarning,
7485
7729
  searchCoverageWarnings,
@@ -7490,6 +7734,7 @@ export {
7490
7734
  parseCommandFlags,
7491
7735
  parseArgs,
7492
7736
  normalizeBooleanFlags,
7737
+ largestFittingCount,
7493
7738
  initFlagsForContext,
7494
7739
  globalFlagHelpLines,
7495
7740
  flagsToArgs,
@@ -7506,10 +7751,8 @@ export {
7506
7751
  canonicalFlagKey,
7507
7752
  buildResumeCommand,
7508
7753
  auditCapStatus,
7509
- TELEMETRY_EXEMPT_COMMANDS,
7510
7754
  TAIL_LIMITS,
7511
7755
  RAW_BOOLEAN_FLAGS,
7512
- LEGACY_WINDOW_MAX_MESSAGES,
7513
7756
  FULL_TRANSCRIPT_DEFAULT_MAX_MESSAGES,
7514
7757
  CliInputError,
7515
7758
  CONTEXT_MAX_WINDOW,