@moda-ai/cli 1.55.28 → 1.55.30

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.
@@ -9,7 +9,7 @@ import {
9
9
  parsePromptFileForAb,
10
10
  readPromptLock,
11
11
  runPromptSync
12
- } from "./cli-3retgh64.js";
12
+ } from "./cli-6ycf2aj5.js";
13
13
  import {
14
14
  UUID_RE
15
15
  } from "./cli-n2hng3gv.js";
@@ -5725,9 +5725,9 @@ async function runPromptsCommand(input, legacyFlags, legacyProfileOptions) {
5725
5725
  await promotePrompt(positionals, flags, profileOptions, context);
5726
5726
  break;
5727
5727
  case "ab":
5728
- return (await import("./prompts-ab-ezrd63sk.js")).runPromptAb(flags, profileOptions, context);
5728
+ return (await import("./prompts-ab-98pqf06s.js")).runPromptAb(flags, profileOptions, context);
5729
5729
  case "propose":
5730
- await (await import("./prompts-propose-2k3enm2q.js")).runPromptPropose(positionals, flags, profileOptions, context);
5730
+ await (await import("./prompts-propose-md1k1ax8.js")).runPromptPropose(positionals, flags, profileOptions, context);
5731
5731
  break;
5732
5732
  case "list":
5733
5733
  case "show":
@@ -5830,7 +5830,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
5830
5830
  const analyzedDefinitions = new Map;
5831
5831
  if (flags["no-analyze"] !== "true") {
5832
5832
  options.onProgress?.("Analyzing prompt sources before sync.");
5833
- const { analyzeHarnessPrompts } = await import("./harness-7azmzytc.js");
5833
+ const { analyzeHarnessPrompts } = await import("./harness-8rbsmg8y.js");
5834
5834
  const result = await analyzeHarnessPrompts({
5835
5835
  rootDir: process.cwd(),
5836
5836
  existing: established.flatMap((prompt) => prompt.sourceDefinition ? [prompt.sourceDefinition.source] : []),
@@ -5858,7 +5858,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
5858
5858
  const mergedSources = mergePromptSources(manifest.sources, extraSources);
5859
5859
  const manifestUpdate = stableJson(mergedSources) === stableJson(mergePromptSources(manifest.sources, [])) ? undefined : $stringify({ version: 2, prompt_paths: manifest.promptPaths, sources: mergedSources });
5860
5860
  const prompts = await discoverPrompts(extraSources);
5861
- const { checkPromptAttribution } = await import("./prompt-attribution-1nytc9wj.js");
5861
+ const { checkPromptAttribution } = await import("./prompt-attribution-gypvn8z9.js");
5862
5862
  const attribution = checkPromptAttribution(process.cwd(), prompts.map((prompt) => prompt.key));
5863
5863
  const brokenAttribution = attribution.references.filter((reference) => reference.status === "missing");
5864
5864
  if (brokenAttribution.length) {
@@ -6164,7 +6164,7 @@ async function migratePromptManifest(options = {}) {
6164
6164
  let addedSources = [];
6165
6165
  let pendingSources = [];
6166
6166
  if (options.discover) {
6167
- const { analyzeHarnessPrompts } = await import("./harness-7azmzytc.js");
6167
+ const { analyzeHarnessPrompts } = await import("./harness-8rbsmg8y.js");
6168
6168
  const result = await analyzeHarnessPrompts({
6169
6169
  rootDir: root,
6170
6170
  existing: manifest.sources,
package/dist/cli.js CHANGED
@@ -91,6 +91,7 @@ import {
91
91
  createCliOutput,
92
92
  embeddedTenantIdFromApiKey,
93
93
  errorToAgentError,
94
+ getActiveProfile,
94
95
  getApiRequestCount,
95
96
  getModaDir,
96
97
  isPlatformApiKey,
@@ -128,7 +129,7 @@ import {
128
129
  } from "./cli-0v6na3yp.js";
129
130
 
130
131
  // src/cli.ts
131
- import { randomUUID as randomUUID2 } from "node:crypto";
132
+ import { randomUUID as randomUUID3 } from "node:crypto";
132
133
  import { z } from "zod";
133
134
 
134
135
  // src/replays.ts
@@ -387,10 +388,223 @@ function spawnDetachedNode(script, options = {}, spawnImpl = spawn) {
387
388
  }
388
389
 
389
390
  // src/telemetry.ts
390
- 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
391
603
  var INLINE_TELEMETRY_TIMEOUT_MS = 500;
392
604
  var DETACHED_TELEMETRY_TIMEOUT_MS = 5000;
393
- 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();
394
608
  var TELEMETRY_FLAG = "no-telemetry";
395
609
  var TELEMETRY_TRANSPORT_ENV = "MODA_CLI_TELEMETRY_TRANSPORT";
396
610
  var MAX_TELEMETRY_DURATION_MS = 86400000;
@@ -560,48 +774,103 @@ function safeCode(value) {
560
774
  var TELEMETRY_SENDER_SCRIPT = [
561
775
  "try {",
562
776
  " let raw = '';",
563
- ` const quit = setTimeout(() => process.exit(0), ${DETACHED_TELEMETRY_TIMEOUT_MS + 1000});`,
564
- " 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
+ " };",
565
806
  " process.stdin.setEncoding('utf8');",
566
807
  " process.stdin.on('error', () => {});",
567
808
  " process.stdin.on('data', (chunk) => { raw += chunk; });",
568
809
  " process.stdin.on('end', () => {",
569
- " try {",
570
- " const r = raw ? JSON.parse(raw) : null;",
571
- " raw = '';",
572
- " if (!r || typeof r.url !== 'string' || typeof fetch !== 'function') return done();",
573
- " const c = new AbortController();",
574
- ` const t = setTimeout(() => c.abort(), ${DETACHED_TELEMETRY_TIMEOUT_MS});`,
575
- " fetch(r.url, { method: 'POST', headers: r.headers, body: r.body, signal: c.signal })",
576
- " .then((res) => (res.body && res.body.cancel ? res.body.cancel() : undefined))",
577
- " .catch(() => {})",
578
- " .finally(() => { clearTimeout(t); done(); });",
579
- " } 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);",
580
816
  " });",
581
817
  "} catch {}"
582
818
  ].join(`
583
819
  `);
584
- function spawnDetachedTelemetrySender(request, spawnImpl = spawn2) {
585
- 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
+ }
586
830
  }
587
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) {
588
844
  const controller = new AbortController;
589
845
  const timeout = setTimeout(() => controller.abort(), INLINE_TELEMETRY_TIMEOUT_MS);
590
846
  if (typeof timeout.unref === "function") {
591
847
  timeout.unref();
592
848
  }
593
849
  try {
594
- await fetch(request.url, {
850
+ const response = await fetch(request.url, {
595
851
  method: "POST",
596
852
  headers: request.headers,
597
853
  body: request.body,
598
854
  signal: controller.signal
599
855
  });
600
- } catch {} finally {
856
+ return response.status;
857
+ } catch {
858
+ return 0;
859
+ } finally {
601
860
  clearTimeout(timeout);
602
861
  }
603
862
  }
604
- 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) {
605
874
  const baseUrl = resolveModaBaseUrlStrict(input.profile ? { profile: input.profile } : {});
606
875
  if (!baseUrl)
607
876
  return;
@@ -613,12 +882,8 @@ function buildCliUsageRequest(input) {
613
882
  delete adoption[key];
614
883
  }
615
884
  return {
616
- url: `${baseUrl}/api/v1/data/cli-usage`,
617
- headers: {
618
- ...apiKeyHeaders(input.apiKey),
619
- "Content-Type": "application/json"
620
- },
621
- body: JSON.stringify({
885
+ baseUrl,
886
+ event: {
622
887
  invocation_id: INVOCATION_ID,
623
888
  command: safeCode(input.command.slice(0, 64)) ?? "unknown",
624
889
  status: input.status,
@@ -637,27 +902,79 @@ function buildCliUsageRequest(input) {
637
902
  ...((alias) => alias ? { legacy_alias: alias } : {})(safeCode(sanitizeReasonCode(input.legacyAlias?.replace(/ /g, ":"), 64)))
638
903
  },
639
904
  ...adoption
640
- })
905
+ }
906
+ };
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
641
940
  };
642
941
  }
942
+ function discardSpoolOnEnvOptOut() {
943
+ if (!isTelemetryDisabled({}))
944
+ return false;
945
+ discardSpool();
946
+ return true;
947
+ }
643
948
  async function sendCliUsageTelemetry(input) {
644
949
  try {
950
+ if (discardSpoolOnEnvOptOut())
951
+ return;
645
952
  if (!input.apiKey || isTelemetryDisabled(input.flags)) {
646
953
  return;
647
954
  }
648
- const request = buildCliUsageRequest({ ...input, apiKey: input.apiKey });
649
- if (!request)
955
+ const built = buildCliUsageEvent(input);
956
+ if (!built)
650
957
  return;
651
- 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);
652
961
  return;
653
962
  }
654
- 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);
655
972
  } catch {}
656
973
  }
657
974
 
658
975
  // src/update-check.ts
659
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
660
- 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";
661
978
  var UPDATE_CHECK_FLAG = "no-update-check";
662
979
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
663
980
  var REGISTRY_TIMEOUT_MS = 1500;
@@ -670,11 +987,11 @@ function isUpdateCheckDisabled(flags, env = process.env) {
670
987
  return optOutFlagSet(flags, UPDATE_CHECK_FLAG) || envSwitchedOff(env.MODA_CLI_UPDATE_CHECK) || envOptOutSet(env.DO_NOT_TRACK) || envOptOutSet(env.CI);
671
988
  }
672
989
  function cachePath(options = {}) {
673
- return join(getModaDir(options), "update-check.json");
990
+ return join2(getModaDir(options), "update-check.json");
674
991
  }
675
992
  function readCache(options = {}) {
676
993
  try {
677
- const parsed = JSON.parse(readFileSync(cachePath(options), "utf8"));
994
+ const parsed = JSON.parse(readFileSync2(cachePath(options), "utf8"));
678
995
  if (parsed && typeof parsed === "object" && typeof parsed.checked_at === "number" && typeof parsed.latest === "string") {
679
996
  return parsed;
680
997
  }
@@ -683,7 +1000,7 @@ function readCache(options = {}) {
683
1000
  }
684
1001
  function writeCache(cache, options = {}) {
685
1002
  try {
686
- mkdirSync(getModaDir(options), { recursive: true });
1003
+ mkdirSync2(getModaDir(options), { recursive: true });
687
1004
  writeFileSync(cachePath(options), `${JSON.stringify(cache, null, 2)}
688
1005
  `, "utf8");
689
1006
  } catch {}
@@ -2642,7 +2959,7 @@ function leafManifestFields(leaf, commands) {
2642
2959
  import { fileURLToPath } from "url";
2643
2960
  import { realpathSync } from "fs";
2644
2961
  async function runPromptsCommand(...args) {
2645
- return (await import("./prompts-6y9wfq5z.js")).runPromptsCommand(...args);
2962
+ return (await import("./prompts-3qr24vd6.js")).runPromptsCommand(...args);
2646
2963
  }
2647
2964
  async function runSkillsCommand(...args) {
2648
2965
  return (await import("./skills-j8865009.js")).runSkillsCommand(...args);
@@ -2654,19 +2971,19 @@ async function runFixesCommand(...args) {
2654
2971
  return (await import("./fix-w5z02wt4.js")).runFixesCommand(...args);
2655
2972
  }
2656
2973
  async function runHarnessCommand(...args) {
2657
- return (await import("./harness-7azmzytc.js")).runHarnessCommand(...args);
2974
+ return (await import("./harness-8rbsmg8y.js")).runHarnessCommand(...args);
2658
2975
  }
2659
2976
  async function runSyncCommand(...args) {
2660
- return (await import("./sync-ew7yvy0e.js")).runSyncCommand(...args);
2977
+ return (await import("./sync-q9raqnk4.js")).runSyncCommand(...args);
2661
2978
  }
2662
2979
  async function runRegistryCommand(...args) {
2663
- return (await import("./registry-96aze5wp.js")).runRegistryCommand(...args);
2980
+ return (await import("./registry-ctnn8e26.js")).runRegistryCommand(...args);
2664
2981
  }
2665
2982
  async function runDoctorCommand(...args) {
2666
- return (await import("./doctor-k3ta6h2y.js")).runDoctorCommand(...args);
2983
+ return (await import("./doctor-2hd9rq68.js")).runDoctorCommand(...args);
2667
2984
  }
2668
2985
  async function runStatusCommand(...args) {
2669
- return (await import("./doctor-k3ta6h2y.js")).runStatusCommand(...args);
2986
+ return (await import("./doctor-2hd9rq68.js")).runStatusCommand(...args);
2670
2987
  }
2671
2988
  async function runAuthCommand(...args) {
2672
2989
  return (await import("./profile-commands-h8evz9x0.js")).runAuthCommand(...args);
@@ -2678,7 +2995,7 @@ async function runProfilesCommand(...args) {
2678
2995
  return (await import("./profile-commands-h8evz9x0.js")).runProfilesCommand(...args);
2679
2996
  }
2680
2997
  async function runAgentCommand(...args) {
2681
- return (await import("./agent-0w9rtdsw.js")).runAgentCommand(...args);
2998
+ return (await import("./agent-wjkgt137.js")).runAgentCommand(...args);
2682
2999
  }
2683
3000
  async function runProductionCommand(...args) {
2684
3001
  return (await import("./production-intelligence-wvsgjxth.js")).runProductionCommand(...args);
@@ -5445,7 +5762,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
5445
5762
  }
5446
5763
  const data = await callDataAPI(reviewPath, {
5447
5764
  method: "POST",
5448
- body: JSON.stringify({ ...reviewBody, request_nonce: randomUUID2() }),
5765
+ body: JSON.stringify({ ...reviewBody, request_nonce: randomUUID3() }),
5449
5766
  headers: { "Content-Type": "application/json" }
5450
5767
  });
5451
5768
  context.output.writeData(data);
@@ -5538,7 +5855,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
5538
5855
  });
5539
5856
  break;
5540
5857
  }
5541
- 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;
5542
5859
  const data = await callDataAPI(request.path, {
5543
5860
  method: request.method,
5544
5861
  ...sentBody ? { body: JSON.stringify(sentBody), headers: { "Content-Type": "application/json" } } : {}
@@ -5826,7 +6143,7 @@ var commandRegistry = createCommandRegistry([
5826
6143
  resetApiRequestCountBeforeRun: true,
5827
6144
  telemetry: "result-and-error",
5828
6145
  handler: async (context) => {
5829
- const { runInit } = await import("./index-d1z50dsq.js");
6146
+ const { runInit } = await import("./index-ecsjv99z.js");
5830
6147
  if (context.outputMode === "agent-stream") {
5831
6148
  context.output.writeEvent({
5832
6149
  event: "started",
@@ -7100,6 +7417,8 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
7100
7417
  const switchError = normalizeBooleanFlags(flags);
7101
7418
  const typedFlags = stripUpdateCheckFlag(stripTelemetryFlag(flags));
7102
7419
  const telemetryDisabled = isTelemetryDisabled(flags);
7420
+ if (telemetryDisabled)
7421
+ discardSpoolOnEnvOptOut();
7103
7422
  const updateCheckDisabled = isUpdateCheckDisabled(flags);
7104
7423
  if (command === "--version" || command === "-V" || flags.version === "true") {
7105
7424
  console.log(`moda-cli ${VERSION}`);
@@ -3,9 +3,9 @@ import {
3
3
  promptsDiscoveredCheck,
4
4
  runDoctorCommand,
5
5
  runStatusCommand
6
- } from "./cli-ny48a8de.js";
6
+ } from "./cli-2eqh3150.js";
7
7
  import"./cli-9bgnvth2.js";
8
- import"./cli-3retgh64.js";
8
+ import"./cli-6ycf2aj5.js";
9
9
  import"./cli-mm48br00.js";
10
10
  import"./cli-xq45etg1.js";
11
11
  import"./cli-dr6x0zv7.js";
@@ -40,7 +40,7 @@ import {
40
40
  writeHarnessAnalyzeResult,
41
41
  writeHarnessArtifacts,
42
42
  writeHumanProgress
43
- } from "./cli-3n0gz4d0.js";
43
+ } from "./cli-37r94bmk.js";
44
44
  import {
45
45
  readHarnessSyncState
46
46
  } from "./cli-xq45etg1.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildSourceSnapshot
3
- } from "./cli-3n0gz4d0.js";
3
+ } from "./cli-37r94bmk.js";
4
4
  import"./cli-xq45etg1.js";
5
5
  import"./cli-97fnztpy.js";
6
6
  import"./cli-cesds766.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildDoctorReport
3
- } from "./cli-ny48a8de.js";
3
+ } from "./cli-2eqh3150.js";
4
4
  import {
5
5
  selectTenantAndCreateKey
6
6
  } from "./cli-9bgk5jeh.js";
@@ -29,7 +29,7 @@ import {
29
29
  import {
30
30
  initPrompts,
31
31
  runPromptSync
32
- } from "./cli-3retgh64.js";
32
+ } from "./cli-6ycf2aj5.js";
33
33
  import"./cli-mm48br00.js";
34
34
  import {
35
35
  codingAgentDisplayName,
@@ -43,7 +43,7 @@ import {
43
43
  runCodingAgent,
44
44
  runHarnessCommand,
45
45
  startRemoteAnalyze
46
- } from "./cli-3n0gz4d0.js";
46
+ } from "./cli-37r94bmk.js";
47
47
  import {
48
48
  canonicalText,
49
49
  renderInitBanner,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  inventoryFiles,
3
3
  safePromptEvidencePath
4
- } from "./cli-3n0gz4d0.js";
4
+ } from "./cli-37r94bmk.js";
5
5
  import"./cli-xq45etg1.js";
6
6
  import"./cli-97fnztpy.js";
7
7
  import"./cli-cesds766.js";