@moda-ai/cli 1.55.26 → 1.55.27

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 (30) hide show
  1. package/dist/{agent-nqmha8ck.js → agent-vp9prdma.js} +8 -8
  2. package/dist/{cli-k6q8dbpk.js → cli-0pkc8jhg.js} +3 -3
  3. package/dist/{cli-5g1tv80h.js → cli-4h0ave0f.js} +5 -5
  4. package/dist/{cli-8tfk8qeb.js → cli-6et4z504.js} +7 -6
  5. package/dist/{cli-1mbb0ct0.js → cli-ccjfwzqx.js} +1 -1
  6. package/dist/{cli-q6f6vrrr.js → cli-hmjdgxrn.js} +1 -1
  7. package/dist/{cli-jtyvbd8d.js → cli-pg5qfmqc.js} +1 -1
  8. package/dist/{cli-b4740tnv.js → cli-q9nsvqqg.js} +14 -14
  9. package/dist/{cli-d577kq6h.js → cli-qwgct6x7.js} +7 -6
  10. package/dist/{cli-sqsjd08w.js → cli-r5pp7qny.js} +64 -438
  11. package/dist/{cli-cdrvjva5.js → cli-v8q7sd7g.js} +28 -6
  12. package/dist/cli-vdkwkkp5.js +567 -0
  13. package/dist/{cli-jgfm7w1r.js → cli-wzds257x.js} +5 -4
  14. package/dist/cli.js +299 -151
  15. package/dist/{doctor-w913fj4g.js → doctor-wmre3mr7.js} +8 -8
  16. package/dist/{fix-crkwdkt4.js → fix-75s9s0d6.js} +45 -47
  17. package/dist/{harness-x3e7d68b.js → harness-a7tb9a23.js} +5 -5
  18. package/dist/{harness-github-actions-fjhvhgpj.js → harness-github-actions-6v4wydb8.js} +5 -5
  19. package/dist/{index-2kf3fnnb.js → index-91bpc8g8.js} +15 -14
  20. package/dist/{production-intelligence-7n83c701.js → production-intelligence-7nqddd4f.js} +15 -15
  21. package/dist/{profile-commands-ct2t0bfr.js → profile-commands-49yn02yg.js} +5 -4
  22. package/dist/prompt-source-mcp.js +5 -5
  23. package/dist/{prompts-92aqqb2k.js → prompts-17wyrst6.js} +6 -6
  24. package/dist/{provision-gn8raqpt.js → provision-bc3h68e1.js} +5 -5
  25. package/dist/{registry-ex162j5y.js → registry-fpzhjznj.js} +3 -3
  26. package/dist/{skills-2mbsj9bt.js → skills-ccdbqghj.js} +5 -5
  27. package/dist/{sync-kghmmmk5.js → sync-hkxce5zh.js} +7 -7
  28. package/package.json +1 -1
  29. package/skills/integration/index.json +2 -2
  30. package/dist/cli-bb7133m7.js +0 -144
package/dist/cli.js CHANGED
@@ -1,11 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- MODA_INTELLIGENCE_V1_JSON_SCHEMA
4
- } from "./cli-bb7133m7.js";
3
+ BATCH_CONCURRENCY,
4
+ BATCH_MAX_TARGETS,
5
+ MODA_INTELLIGENCE_V1_JSON_SCHEMA,
6
+ asNumber,
7
+ asRecord,
8
+ asString,
9
+ collectBatchTargets,
10
+ compactProblemDossier,
11
+ contextTarget,
12
+ embeddedWindowSize,
13
+ frustrationsFromEmotions,
14
+ mapWithConcurrency,
15
+ parseBatchTarget,
16
+ trimToolFailureConversations,
17
+ withFrustrationAnchors,
18
+ withToolFailureAnchors,
19
+ withoutDetectionWindows
20
+ } from "./cli-vdkwkkp5.js";
5
21
  import {
6
22
  createCommandContext,
7
- parseBooleanFlagValue
8
- } from "./cli-cdrvjva5.js";
23
+ envOptOutSet,
24
+ envSwitchedOff,
25
+ optOutFlagSet,
26
+ parseBooleanFlagValue,
27
+ withoutFlag
28
+ } from "./cli-v8q7sd7g.js";
9
29
  import {
10
30
  AuditSchema,
11
31
  COMMAND_FLAG_SPECS,
@@ -47,16 +67,14 @@ import {
47
67
  unknownSignalsSubcommandError,
48
68
  usageLine,
49
69
  writeDryRun
50
- } from "./cli-jgfm7w1r.js";
70
+ } from "./cli-wzds257x.js";
51
71
  import {
52
72
  ApiError,
53
73
  callControlAPI,
54
74
  callDataAPI
55
- } from "./cli-jtyvbd8d.js";
75
+ } from "./cli-pg5qfmqc.js";
56
76
  import {
57
77
  AGENT_ERROR_CODES,
58
- BATCH_CONCURRENCY,
59
- BATCH_MAX_TARGETS,
60
78
  CliAccessError,
61
79
  CliAuthError,
62
80
  CliCancellationError,
@@ -76,19 +94,11 @@ import {
76
94
  agentMaxOutputBytes,
77
95
  apiErrorStatus,
78
96
  apiKeyHeaders,
79
- asNumber,
80
- asRecord,
81
- asString,
82
97
  attachInputDetails,
83
98
  canonicalCommandText,
84
- collectBatchTargets,
85
- compactProblemDossier,
86
- contextTarget,
87
99
  createCliOutput,
88
100
  embeddedTenantIdFromApiKey,
89
- embeddedWindowSize,
90
101
  errorToAgentError,
91
- frustrationsFromEmotions,
92
102
  getApiRequestCount,
93
103
  getModaDir,
94
104
  inputDetailsOf,
@@ -96,24 +106,20 @@ import {
96
106
  isNetworkLikeError,
97
107
  isPlatformApiKey,
98
108
  loadProfileConfig,
99
- mapWithConcurrency,
100
- parseBatchTarget,
101
109
  resetApiRequestCount,
102
110
  resolveApiKey,
103
111
  resolveApiTenantId,
104
112
  resolveModaBaseUrl,
113
+ resolveModaBaseUrlStrict,
105
114
  resolveOutputMode,
106
115
  safeWriteStderr,
107
116
  safeWriteStdout,
108
117
  setAgentUpdateNotice,
109
118
  setPlatformTenantOverride,
110
- trimToolFailureConversations,
119
+ shellArg,
111
120
  validateConfig,
112
- wasOutputCancelled,
113
- withFrustrationAnchors,
114
- withToolFailureAnchors,
115
- withoutDetectionWindows
116
- } from "./cli-sqsjd08w.js";
121
+ wasOutputCancelled
122
+ } from "./cli-r5pp7qny.js";
117
123
  import {
118
124
  __require
119
125
  } from "./cli-0v6na3yp.js";
@@ -302,16 +308,91 @@ async function runReplaysCommand(context) {
302
308
  }
303
309
 
304
310
  // src/telemetry.ts
311
+ import { spawn as spawn2 } from "node:child_process";
312
+
313
+ // src/detached.ts
305
314
  import { spawn } from "node:child_process";
315
+ var INSPECTOR_VALUE_OPTIONS = new Set(["--inspect-port", "--debug-port", "--inspect-publish-uid"]);
316
+ function nodeOptionTokens(nodeOptions) {
317
+ const tokens = [];
318
+ let start = -1;
319
+ let quoted = false;
320
+ for (let i = 0;i < nodeOptions.length; i += 1) {
321
+ const ch = nodeOptions[i];
322
+ if (start === -1) {
323
+ if (/\s/.test(ch))
324
+ continue;
325
+ start = i;
326
+ }
327
+ if (quoted && ch === "\\") {
328
+ i += 1;
329
+ } else if (ch === '"') {
330
+ quoted = !quoted;
331
+ } else if (!quoted && /\s/.test(ch)) {
332
+ tokens.push(nodeOptions.slice(start, i));
333
+ start = -1;
334
+ }
335
+ }
336
+ if (start !== -1)
337
+ tokens.push(nodeOptions.slice(start));
338
+ return tokens;
339
+ }
340
+ function withoutInspectorOptions(nodeOptions) {
341
+ const tokens = nodeOptionTokens(nodeOptions);
342
+ const kept = [];
343
+ for (let i = 0;i < tokens.length; i += 1) {
344
+ const name = tokens[i].split("=")[0];
345
+ if (!name.startsWith("--inspect") && name !== "--debug-port") {
346
+ kept.push(tokens[i]);
347
+ continue;
348
+ }
349
+ if (INSPECTOR_VALUE_OPTIONS.has(tokens[i]) && tokens[i + 1] && !tokens[i + 1].startsWith("-"))
350
+ i += 1;
351
+ }
352
+ return kept.join(" ");
353
+ }
354
+ function spawnDetachedNode(script, options = {}, spawnImpl = spawn) {
355
+ try {
356
+ const env = { ...process.env, ...options.env };
357
+ for (const key of options.dropEnv ?? [])
358
+ delete env[key];
359
+ if (env.NODE_OPTIONS?.includes("--inspect")) {
360
+ const kept = withoutInspectorOptions(env.NODE_OPTIONS);
361
+ if (kept)
362
+ env.NODE_OPTIONS = kept;
363
+ else
364
+ delete env.NODE_OPTIONS;
365
+ }
366
+ const child = spawnImpl(process.execPath, ["-e", script], {
367
+ detached: true,
368
+ stdio: [options.stdin === undefined ? "ignore" : "pipe", "ignore", "ignore"],
369
+ windowsHide: true,
370
+ env
371
+ });
372
+ child.on("error", () => {});
373
+ if (child.pid === undefined)
374
+ return false;
375
+ if (options.stdin !== undefined && child.stdin) {
376
+ child.stdin.on("error", () => {});
377
+ child.stdin.end(options.stdin);
378
+ }
379
+ child.unref();
380
+ return true;
381
+ } catch {
382
+ return false;
383
+ }
384
+ }
385
+
386
+ // src/telemetry.ts
306
387
  import { randomUUID } from "node:crypto";
307
388
  var INLINE_TELEMETRY_TIMEOUT_MS = 500;
308
389
  var DETACHED_TELEMETRY_TIMEOUT_MS = 5000;
309
390
  var INVOCATION_ID = randomUUID();
310
391
  var TELEMETRY_FLAG = "no-telemetry";
311
- var TELEMETRY_REQUEST_ENV = "MODA_CLI_TELEMETRY_REQUEST";
312
392
  var TELEMETRY_TRANSPORT_ENV = "MODA_CLI_TELEMETRY_TRANSPORT";
313
393
  var MAX_TELEMETRY_DURATION_MS = 86400000;
314
394
  var MAX_TELEMETRY_API_REQUEST_COUNT = 1e6;
395
+ var MAX_UNKNOWN_FLAG_COUNT = 1000;
315
396
  var SEARCH_SURFACE_BY_COMMAND = {
316
397
  search: "message",
317
398
  conversations: "conversation",
@@ -413,11 +494,10 @@ function serializeAdoption(adoption) {
413
494
  return out;
414
495
  }
415
496
  function stripTelemetryFlag(flags) {
416
- const { [TELEMETRY_FLAG]: _drop, ...rest } = flags;
417
- return rest;
497
+ return withoutFlag(flags, TELEMETRY_FLAG);
418
498
  }
419
- function isTelemetryDisabled(flags) {
420
- return flags[TELEMETRY_FLAG] === "true" || process.env.MODA_CLI_TELEMETRY === "0" || process.env.DO_NOT_TRACK === "1";
499
+ function isTelemetryDisabled(flags, env = process.env) {
500
+ return optOutFlagSet(flags, TELEMETRY_FLAG) || envSwitchedOff(env.MODA_CLI_TELEMETRY) || envOptOutSet(env.DO_NOT_TRACK);
421
501
  }
422
502
  var VALIDATION_REASON_MAX = 128;
423
503
  var DEGRADE_REASON_MAX = 64;
@@ -428,88 +508,78 @@ function sanitizeReasonCode(reason, max) {
428
508
  function sanitizeValidationReason(reason) {
429
509
  return sanitizeReasonCode(reason, VALIDATION_REASON_MAX);
430
510
  }
431
- function sanitizedFlagNames(flags) {
432
- return Object.keys(stripTelemetryFlag(flags)).sort();
511
+ var MAX_FLAG_NAMES = 50;
512
+ var FLAG_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
513
+ var SECRET_PATTERNS = [
514
+ /moda_sk_/i,
515
+ /(?:^|[^A-Za-z0-9])sk-[A-Za-z0-9_-]{8,}/,
516
+ /(?:^|[^A-Za-z0-9])(?:sk|pk|rk)_(?:live|test)_/i,
517
+ /gh[pousr]_[A-Za-z0-9]{16,}/,
518
+ /github_pat_/i,
519
+ /xox[abprs]-/i,
520
+ /AKIA[0-9A-Z]{16}/,
521
+ /eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/,
522
+ /-----BEGIN [A-Z ]*PRIVATE KEY/,
523
+ /[^\s@]+@[^\s@]+\.[A-Za-z]{2,}/,
524
+ /[A-Za-z0-9+/=]{32,}/
525
+ ];
526
+ function looksSecret(value) {
527
+ return SECRET_PATTERNS.some((pattern) => pattern.test(value));
528
+ }
529
+ function reportedFlagNames(flags, acceptedFlags = new Set) {
530
+ const names = new Set;
531
+ let unknownCount = 0;
532
+ for (const key of Object.keys(stripTelemetryFlag(flags))) {
533
+ if (acceptedFlags.has(key.replace(/_/g, "-")) && FLAG_NAME_RE.test(key) && !looksSecret(key))
534
+ names.add(key);
535
+ else
536
+ unknownCount += 1;
537
+ }
538
+ const sorted = [...names].sort();
539
+ return { names: sorted.slice(0, MAX_FLAG_NAMES), unknownCount: unknownCount + Math.max(0, sorted.length - MAX_FLAG_NAMES) };
540
+ }
541
+ function reportedValidationReason(reason, knownFlags = new Set) {
542
+ let code = reason;
543
+ const unknownFlag = code ? /^unknown_flag:(.*)$/s.exec(code) : null;
544
+ if (unknownFlag) {
545
+ const name = unknownFlag[1].replace(/_/g, "-");
546
+ code = knownFlags.has(name) && FLAG_NAME_RE.test(name) ? `unknown_flag:${name}` : "unknown_flag";
547
+ }
548
+ const cleaned = sanitizeValidationReason(code);
549
+ if (!cleaned || !looksSecret(cleaned))
550
+ return cleaned;
551
+ const head = cleaned.split(":")[0];
552
+ return head && !looksSecret(head) ? head : undefined;
553
+ }
554
+ function safeCode(value) {
555
+ return value && !looksSecret(value) ? value : undefined;
433
556
  }
434
557
  var TELEMETRY_SENDER_SCRIPT = [
435
558
  "try {",
436
- ` const raw = process.env.${TELEMETRY_REQUEST_ENV};`,
437
- ` delete process.env.${TELEMETRY_REQUEST_ENV};`,
438
- " const r = raw ? JSON.parse(raw) : null;",
439
- " if (r && typeof r.url === 'string' && typeof fetch === 'function') {",
440
- " const c = new AbortController();",
441
- ` const t = setTimeout(() => c.abort(), ${DETACHED_TELEMETRY_TIMEOUT_MS});`,
442
- " fetch(r.url, { method: 'POST', headers: r.headers, body: r.body, signal: c.signal })",
443
- " .then((res) => (res.body && res.body.cancel ? res.body.cancel() : undefined))",
444
- " .catch(() => {})",
445
- " .finally(() => clearTimeout(t));",
446
- " }",
559
+ " let raw = '';",
560
+ ` const quit = setTimeout(() => process.exit(0), ${DETACHED_TELEMETRY_TIMEOUT_MS + 1000});`,
561
+ " const done = () => clearTimeout(quit);",
562
+ " process.stdin.setEncoding('utf8');",
563
+ " process.stdin.on('error', () => {});",
564
+ " process.stdin.on('data', (chunk) => { raw += chunk; });",
565
+ " 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(); }",
577
+ " });",
447
578
  "} catch {}"
448
579
  ].join(`
449
580
  `);
450
- var INSPECTOR_VALUE_OPTIONS = new Set(["--inspect-port", "--debug-port", "--inspect-publish-uid"]);
451
- function nodeOptionTokens(nodeOptions) {
452
- const tokens = [];
453
- let start = -1;
454
- let quoted = false;
455
- for (let i = 0;i < nodeOptions.length; i += 1) {
456
- const ch = nodeOptions[i];
457
- if (start === -1) {
458
- if (/\s/.test(ch))
459
- continue;
460
- start = i;
461
- }
462
- if (quoted && ch === "\\") {
463
- i += 1;
464
- } else if (ch === '"') {
465
- quoted = !quoted;
466
- } else if (!quoted && /\s/.test(ch)) {
467
- tokens.push(nodeOptions.slice(start, i));
468
- start = -1;
469
- }
470
- }
471
- if (start !== -1)
472
- tokens.push(nodeOptions.slice(start));
473
- return tokens;
474
- }
475
- function withoutInspectorOptions(nodeOptions) {
476
- const tokens = nodeOptionTokens(nodeOptions);
477
- const kept = [];
478
- for (let i = 0;i < tokens.length; i += 1) {
479
- const name = tokens[i].split("=")[0];
480
- if (!name.startsWith("--inspect") && name !== "--debug-port") {
481
- kept.push(tokens[i]);
482
- continue;
483
- }
484
- if (INSPECTOR_VALUE_OPTIONS.has(tokens[i]) && tokens[i + 1] && !tokens[i + 1].startsWith("-"))
485
- i += 1;
486
- }
487
- return kept.join(" ");
488
- }
489
- function spawnDetachedTelemetrySender(request, spawnImpl = spawn) {
490
- try {
491
- const env = { ...process.env, [TELEMETRY_REQUEST_ENV]: JSON.stringify(request) };
492
- if (env.NODE_OPTIONS?.includes("--inspect")) {
493
- const kept = withoutInspectorOptions(env.NODE_OPTIONS);
494
- if (kept)
495
- env.NODE_OPTIONS = kept;
496
- else
497
- delete env.NODE_OPTIONS;
498
- }
499
- const child = spawnImpl(process.execPath, ["-e", TELEMETRY_SENDER_SCRIPT], {
500
- detached: true,
501
- stdio: "ignore",
502
- windowsHide: true,
503
- env
504
- });
505
- child.on("error", () => {});
506
- if (child.pid === undefined)
507
- return false;
508
- child.unref();
509
- return true;
510
- } catch {
511
- return false;
512
- }
581
+ function spawnDetachedTelemetrySender(request, spawnImpl = spawn2) {
582
+ return spawnDetachedNode(TELEMETRY_SENDER_SCRIPT, { stdin: JSON.stringify(request), dropEnv: ["MODA_API_KEY"] }, spawnImpl);
513
583
  }
514
584
  async function sendInline(request) {
515
585
  const controller = new AbortController;
@@ -529,16 +599,25 @@ async function sendInline(request) {
529
599
  }
530
600
  }
531
601
  function buildCliUsageRequest(input) {
532
- const validationReason = sanitizeValidationReason(input.validationReason);
602
+ const baseUrl = resolveModaBaseUrlStrict(input.profile ? { profile: input.profile } : {});
603
+ if (!baseUrl)
604
+ return;
605
+ const validationReason = reportedValidationReason(input.validationReason, input.knownFlags);
606
+ const flagNames = reportedFlagNames(input.flags, input.acceptedFlags);
607
+ const adoption = serializeAdoption(input.adoption);
608
+ for (const key of ["subcommand", "degrade_reason", "skill_version"]) {
609
+ if (typeof adoption[key] === "string" && looksSecret(adoption[key]))
610
+ delete adoption[key];
611
+ }
533
612
  return {
534
- url: `${resolveModaBaseUrl({ profile: input.profile })}/api/v1/data/cli-usage`,
613
+ url: `${baseUrl}/api/v1/data/cli-usage`,
535
614
  headers: {
536
615
  ...apiKeyHeaders(input.apiKey),
537
616
  "Content-Type": "application/json"
538
617
  },
539
618
  body: JSON.stringify({
540
619
  invocation_id: INVOCATION_ID,
541
- command: input.command.slice(0, 64),
620
+ command: safeCode(input.command.slice(0, 64)) ?? "unknown",
542
621
  status: input.status,
543
622
  error_type: input.errorType,
544
623
  ...validationReason ? { validation_reason: validationReason } : {},
@@ -550,10 +629,11 @@ function buildCliUsageRequest(input) {
550
629
  platform: process.platform,
551
630
  arch: process.arch,
552
631
  flags_json: {
553
- names: sanitizedFlagNames(input.flags),
554
- ...((alias) => alias ? { legacy_alias: alias } : {})(sanitizeReasonCode(input.legacyAlias?.replace(/ /g, ":"), 64))
632
+ names: flagNames.names,
633
+ ...flagNames.unknownCount > 0 ? { unknown_count: Math.min(flagNames.unknownCount, MAX_UNKNOWN_FLAG_COUNT) } : {},
634
+ ...((alias) => alias ? { legacy_alias: alias } : {})(safeCode(sanitizeReasonCode(input.legacyAlias?.replace(/ /g, ":"), 64)))
555
635
  },
556
- ...serializeAdoption(input.adoption)
636
+ ...adoption
557
637
  })
558
638
  };
559
639
  }
@@ -563,6 +643,8 @@ async function sendCliUsageTelemetry(input) {
563
643
  return;
564
644
  }
565
645
  const request = buildCliUsageRequest({ ...input, apiKey: input.apiKey });
646
+ if (!request)
647
+ return;
566
648
  if (process.env[TELEMETRY_TRANSPORT_ENV] !== "inline" && spawnDetachedTelemetrySender(request)) {
567
649
  return;
568
650
  }
@@ -579,11 +661,10 @@ var REGISTRY_TIMEOUT_MS = 1500;
579
661
  var REGISTRY_LATEST_URL = "https://registry.npmjs.org/@moda-ai/cli/latest";
580
662
  var SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
581
663
  function stripUpdateCheckFlag(flags) {
582
- const { [UPDATE_CHECK_FLAG]: _drop, ...rest } = flags;
583
- return rest;
664
+ return withoutFlag(flags, UPDATE_CHECK_FLAG);
584
665
  }
585
666
  function isUpdateCheckDisabled(flags, env = process.env) {
586
- return flags[UPDATE_CHECK_FLAG] === "true" || env.MODA_CLI_UPDATE_CHECK === "0" || env.DO_NOT_TRACK === "1" || env.CI !== undefined && env.CI !== "" && env.CI !== "false" && env.CI !== "0";
667
+ return optOutFlagSet(flags, UPDATE_CHECK_FLAG) || envSwitchedOff(env.MODA_CLI_UPDATE_CHECK) || envOptOutSet(env.DO_NOT_TRACK) || envOptOutSet(env.CI);
587
668
  }
588
669
  function cachePath(options = {}) {
589
670
  return join(getModaDir(options), "update-check.json");
@@ -616,9 +697,39 @@ function isNewerVersion(candidate, current) {
616
697
  }
617
698
  return false;
618
699
  }
619
- async function startUpdateCheck(options = {}, now = Date.now()) {
700
+ var UPDATE_CHECK_URL_ENV = "MODA_CLI_UPDATE_CHECK_URL";
701
+ var UPDATE_CHECK_CACHE_ENV = "MODA_CLI_UPDATE_CHECK_CACHE";
702
+ var DETACHED_REGISTRY_TIMEOUT_MS = 1e4;
703
+ var UPDATE_CHECK_SCRIPT = [
704
+ "try {",
705
+ ` const url = process.env.${UPDATE_CHECK_URL_ENV};`,
706
+ ` const path = process.env.${UPDATE_CHECK_CACHE_ENV};`,
707
+ ` const semver = new RegExp(${JSON.stringify(SEMVER_RE.source)});`,
708
+ " if (url && path && typeof fetch === 'function') {",
709
+ " const c = new AbortController();",
710
+ ` const t = setTimeout(() => c.abort(), ${DETACHED_REGISTRY_TIMEOUT_MS});`,
711
+ " fetch(url, { headers: { Accept: 'application/json' }, signal: c.signal })",
712
+ " .then((res) => (res.ok ? res.json() : null))",
713
+ " .then((body) => {",
714
+ " if (body && typeof body.version === 'string' && semver.test(body.version)) {",
715
+ " require('fs').writeFileSync(path, JSON.stringify({ checked_at: Date.now(), latest: body.version }, null, 2) + '\\n', 'utf8');",
716
+ " }",
717
+ " })",
718
+ " .catch(() => {})",
719
+ " .finally(() => clearTimeout(t));",
720
+ " }",
721
+ "} catch {}"
722
+ ].join(`
723
+ `);
724
+ async function startUpdateCheck(options = {}, now = Date.now(), mode = {}) {
620
725
  const cache = readCache(options);
621
- if (cache && now - cache.checked_at < CHECK_INTERVAL_MS) {
726
+ if (cache && cache.checked_at <= now && now - cache.checked_at < CHECK_INTERVAL_MS) {
727
+ return;
728
+ }
729
+ const known = cache && SEMVER_RE.test(cache.latest) ? cache.latest : "";
730
+ writeCache({ checked_at: now, latest: known }, options);
731
+ if (mode.detached) {
732
+ spawnDetachedNode(UPDATE_CHECK_SCRIPT, { env: { [UPDATE_CHECK_URL_ENV]: REGISTRY_LATEST_URL, [UPDATE_CHECK_CACHE_ENV]: cachePath(options) }, dropEnv: ["MODA_API_KEY"] }, mode.spawnImpl);
622
733
  return;
623
734
  }
624
735
  const controller = new AbortController;
@@ -643,16 +754,16 @@ async function startUpdateCheck(options = {}, now = Date.now()) {
643
754
  }
644
755
  function getAvailableUpdate(options = {}) {
645
756
  const cache = readCache(options);
646
- return cache && isNewerVersion(cache.latest, VERSION) ? cache.latest : undefined;
757
+ return cache && SEMVER_RE.test(cache.latest) && isNewerVersion(cache.latest, VERSION) ? cache.latest : undefined;
647
758
  }
648
759
  function getUpdateNotice(options = {}) {
649
- const cache = readCache(options);
650
- if (!cache || !isNewerVersion(cache.latest, VERSION)) {
760
+ const latest = getAvailableUpdate(options);
761
+ if (!latest) {
651
762
  return;
652
763
  }
653
764
  return [
654
765
  "",
655
- `Update available: moda-cli ${VERSION} → ${cache.latest}`,
766
+ `Update available: moda-cli ${VERSION} → ${latest}`,
656
767
  "Run `npm install -g @moda-ai/cli@latest` to update."
657
768
  ].join(`
658
769
  `);
@@ -2528,46 +2639,46 @@ function leafManifestFields(leaf, commands) {
2528
2639
  import { fileURLToPath } from "url";
2529
2640
  import { realpathSync } from "fs";
2530
2641
  async function runPromptsCommand(...args) {
2531
- return (await import("./prompts-92aqqb2k.js")).runPromptsCommand(...args);
2642
+ return (await import("./prompts-17wyrst6.js")).runPromptsCommand(...args);
2532
2643
  }
2533
2644
  async function runSkillsCommand(...args) {
2534
- return (await import("./skills-2mbsj9bt.js")).runSkillsCommand(...args);
2645
+ return (await import("./skills-ccdbqghj.js")).runSkillsCommand(...args);
2535
2646
  }
2536
2647
  async function runFixCommand(...args) {
2537
- return (await import("./fix-crkwdkt4.js")).runFixCommand(...args);
2648
+ return (await import("./fix-75s9s0d6.js")).runFixCommand(...args);
2538
2649
  }
2539
2650
  async function runFixesCommand(...args) {
2540
- return (await import("./fix-crkwdkt4.js")).runFixesCommand(...args);
2651
+ return (await import("./fix-75s9s0d6.js")).runFixesCommand(...args);
2541
2652
  }
2542
2653
  async function runHarnessCommand(...args) {
2543
- return (await import("./harness-x3e7d68b.js")).runHarnessCommand(...args);
2654
+ return (await import("./harness-a7tb9a23.js")).runHarnessCommand(...args);
2544
2655
  }
2545
2656
  async function runSyncCommand(...args) {
2546
- return (await import("./sync-kghmmmk5.js")).runSyncCommand(...args);
2657
+ return (await import("./sync-hkxce5zh.js")).runSyncCommand(...args);
2547
2658
  }
2548
2659
  async function runRegistryCommand(...args) {
2549
- return (await import("./registry-ex162j5y.js")).runRegistryCommand(...args);
2660
+ return (await import("./registry-fpzhjznj.js")).runRegistryCommand(...args);
2550
2661
  }
2551
2662
  async function runDoctorCommand(...args) {
2552
- return (await import("./doctor-w913fj4g.js")).runDoctorCommand(...args);
2663
+ return (await import("./doctor-wmre3mr7.js")).runDoctorCommand(...args);
2553
2664
  }
2554
2665
  async function runStatusCommand(...args) {
2555
- return (await import("./doctor-w913fj4g.js")).runStatusCommand(...args);
2666
+ return (await import("./doctor-wmre3mr7.js")).runStatusCommand(...args);
2556
2667
  }
2557
2668
  async function runAuthCommand(...args) {
2558
- return (await import("./profile-commands-ct2t0bfr.js")).runAuthCommand(...args);
2669
+ return (await import("./profile-commands-49yn02yg.js")).runAuthCommand(...args);
2559
2670
  }
2560
2671
  async function runConfigCommand(...args) {
2561
- return (await import("./profile-commands-ct2t0bfr.js")).runConfigCommand(...args);
2672
+ return (await import("./profile-commands-49yn02yg.js")).runConfigCommand(...args);
2562
2673
  }
2563
2674
  async function runProfilesCommand(...args) {
2564
- return (await import("./profile-commands-ct2t0bfr.js")).runProfilesCommand(...args);
2675
+ return (await import("./profile-commands-49yn02yg.js")).runProfilesCommand(...args);
2565
2676
  }
2566
2677
  async function runAgentCommand(...args) {
2567
- return (await import("./agent-nqmha8ck.js")).runAgentCommand(...args);
2678
+ return (await import("./agent-vp9prdma.js")).runAgentCommand(...args);
2568
2679
  }
2569
2680
  async function runProductionCommand(...args) {
2570
- return (await import("./production-intelligence-7n83c701.js")).runProductionCommand(...args);
2681
+ return (await import("./production-intelligence-7nqddd4f.js")).runProductionCommand(...args);
2571
2682
  }
2572
2683
  function parseArgs(argv) {
2573
2684
  const args = argv.slice(2);
@@ -3326,7 +3437,7 @@ function auditOutput(command, params, data, keep) {
3326
3437
  if (partial && record) {
3327
3438
  const continueWith = auditFlags([
3328
3439
  params.limit ? `--limit=${params.limit}` : "",
3329
- params.cursor ? `--cursor=${params.cursor}` : "",
3440
+ params.cursor ? `--cursor=${shellArg(params.cursor)}` : "",
3330
3441
  params.page_bytes ? `--page-bytes=${params.page_bytes}` : "",
3331
3442
  `--span-offset=${end}`
3332
3443
  ]);
@@ -3365,7 +3476,7 @@ function auditOutput(command, params, data, keep) {
3365
3476
  const nextCommands = [];
3366
3477
  if (capped.nextCursor) {
3367
3478
  nextCommands.push({
3368
- command: auditFlags([params.limit ? `--limit=${params.limit}` : "", `--cursor=${capped.nextCursor}`]),
3479
+ command: auditFlags([params.limit ? `--limit=${params.limit}` : "", `--cursor=${shellArg(capped.nextCursor)}`]),
3369
3480
  purpose: "Read the next page of ingest rows of this trace.",
3370
3481
  mutability: "read",
3371
3482
  requires_approval: false
@@ -3767,13 +3878,6 @@ function specParseOptions(spec) {
3767
3878
  ...spec.flagAliases ? { flagAliases: spec.flagAliases } : {}
3768
3879
  };
3769
3880
  }
3770
- function shellArg(value) {
3771
- if (/^[A-Za-z0-9_.,:@%+\/=-]+$/.test(value))
3772
- return value;
3773
- if (!/["$`\\!]/.test(value))
3774
- return `"${value}"`;
3775
- return `'${value.replace(/'/g, `'\\''`)}'`;
3776
- }
3777
3881
  function semanticIndexCoverage(coverage) {
3778
3882
  const ratio = asRecord(asRecord(coverage)?.semantic_index)?.coverage_ratio;
3779
3883
  if (typeof ratio !== "number" || !Number.isFinite(ratio) || ratio < 0 || ratio > 1)
@@ -5239,10 +5343,10 @@ async function runCommand(command, positional, flags, positionals = positional ?
5239
5343
  });
5240
5344
  const link = asRecord(data)?.link;
5241
5345
  const summary = describeLinearLink(link);
5242
- const nextCommands = link ? [] : [`moda problems link ${positional}`];
5346
+ const nextCommands = link ? [] : [`moda problems link ${shellArg(positional)}`];
5243
5347
  if (context.outputMode === "human" && !context.quiet) {
5244
5348
  safeWriteStderr(link ? `${summary}
5245
- ` : `${summary} File one with: moda problems link ${positional}
5349
+ ` : `${summary} File one with: moda problems link ${shellArg(positional)}
5246
5350
  `);
5247
5351
  }
5248
5352
  context.output.writeData(data, { summary, nextCommands });
@@ -5796,7 +5900,7 @@ var commandRegistry = createCommandRegistry([
5796
5900
  resetApiRequestCountBeforeRun: true,
5797
5901
  telemetry: "result-and-error",
5798
5902
  handler: async (context) => {
5799
- const { runInit } = await import("./index-2kf3fnnb.js");
5903
+ const { runInit } = await import("./index-91bpc8g8.js");
5800
5904
  if (context.outputMode === "agent-stream") {
5801
5905
  context.output.writeEvent({
5802
5906
  event: "started",
@@ -5846,7 +5950,7 @@ var commandRegistry = createCommandRegistry([
5846
5950
  resetApiRequestCountBeforeRun: true,
5847
5951
  telemetry: "result-and-error",
5848
5952
  handler: async (context) => {
5849
- const { runProvision } = await import("./provision-gn8raqpt.js");
5953
+ const { runProvision } = await import("./provision-bc3h68e1.js");
5850
5954
  return runProvision(context, {
5851
5955
  resumeCommand: buildResumeCommand("provision", context.rawFlags)
5852
5956
  });
@@ -6923,6 +7027,46 @@ function printAgentCliError(command, error, mode = "agent") {
6923
7027
  });
6924
7028
  output.writeError(error);
6925
7029
  }
7030
+ function flagNamesInLabel(label) {
7031
+ return [...label.matchAll(/--([A-Za-z0-9][A-Za-z0-9-]*)/g)].map((match) => match[1]);
7032
+ }
7033
+ function specFlagNamesDeep(spec) {
7034
+ if (!spec)
7035
+ return [];
7036
+ return [...specFlagNames(spec), ...Object.values(spec.subcommands ?? {}).flatMap((sub) => specFlagNames(sub))];
7037
+ }
7038
+ function telemetryAcceptedFlags(definition, route) {
7039
+ const names = new Set([...GLOBAL_FLAG_NAMES, ...GLOBAL_BOOLEAN_FLAGS]);
7040
+ const add = (list) => {
7041
+ for (const name of list)
7042
+ names.add(name);
7043
+ };
7044
+ if (definition) {
7045
+ add(specFlagNamesDeep(flagSpecFor(definition.name)));
7046
+ for (const flag of definition.documentedFlags ?? [])
7047
+ add(flagNamesInLabel(flag.name));
7048
+ for (const sub of definition.subcommands ?? [])
7049
+ for (const flag of sub.flags ?? [])
7050
+ add(flagNamesInLabel(flag.name));
7051
+ }
7052
+ if (route) {
7053
+ add(route.allowedFlags ?? []);
7054
+ add(Object.keys(route.flagAliases ?? {}));
7055
+ add(specFlagNamesDeep(leafFlagSpec(route.leaf)));
7056
+ }
7057
+ return names;
7058
+ }
7059
+ var knownFlagNames;
7060
+ function telemetryKnownFlags() {
7061
+ if (!knownFlagNames) {
7062
+ knownFlagNames = new Set(RAW_BOOLEAN_FLAGS);
7063
+ for (const definition of commandRegistry.all()) {
7064
+ for (const name of telemetryAcceptedFlags(definition, undefined))
7065
+ knownFlagNames.add(name);
7066
+ }
7067
+ }
7068
+ return knownFlagNames;
7069
+ }
6926
7070
  function existingFlagProfile(flags) {
6927
7071
  const name = flags.profile;
6928
7072
  if (!name || name === "true")
@@ -7095,6 +7239,8 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
7095
7239
  if (!handlerTelemetry)
7096
7240
  return;
7097
7241
  const telemetryProfile = existingFlagProfile(typedFlags);
7242
+ if (typedFlags.profile !== undefined && telemetryProfile === undefined)
7243
+ return;
7098
7244
  const adoption = buildSearchAdoptionTelemetry({
7099
7245
  command: handlerTelemetry,
7100
7246
  positional: parsed.positional,
@@ -7122,12 +7268,14 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
7122
7268
  durationMs: Date.now() - startedAt,
7123
7269
  apiRequestCount: input.apiRequestCount,
7124
7270
  adoption,
7125
- ...identity2?.legacyAlias ? { legacyAlias: identity2.legacyAlias } : {}
7271
+ ...identity2?.legacyAlias ? { legacyAlias: identity2.legacyAlias } : {},
7272
+ acceptedFlags: telemetryAcceptedFlags(definition2, route),
7273
+ knownFlags: telemetryKnownFlags()
7126
7274
  });
7127
7275
  };
7128
7276
  const failEarly = (error, commandDefinition, identity2) => {
7129
7277
  const mode = outputModeFor();
7130
- const telemetryOptOut = telemetryDisabled || flags["no-telemetry"] !== undefined && flags["no-telemetry"] !== "false";
7278
+ const telemetryOptOut = telemetryDisabled || optOutFlagSet(flags, "no-telemetry", false);
7131
7279
  const reports = commandDefinition ? commandDefinition.telemetry === "result-and-error" : identity2 !== undefined;
7132
7280
  if (reports && !telemetryOptOut) {
7133
7281
  reportUsage({
@@ -7179,7 +7327,7 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
7179
7327
  const known = Object.keys(loadProfileConfig({ env: process.env }).profiles);
7180
7328
  if (!known.includes(requestedProfile)) {
7181
7329
  const source = commandFlags.profile ? `--profile=${requestedProfile}` : `MODA_PROFILE=${requestedProfile}`;
7182
- return failEarly(new CliInputError(`Moda profile '${requestedProfile}' does not exist (from ${source}), so nothing was run.`, `Known profiles: ${known.join(", ")}. Create it with 'moda profiles create ${requestedProfile}' or fix the name.`, "unknown_profile"), definition, identity);
7330
+ return failEarly(new CliInputError(`Moda profile '${requestedProfile}' does not exist (from ${source}), so nothing was run.`, `Known profiles: ${known.join(", ")}. Create it with 'moda profiles create ${shellArg(requestedProfile)}' or fix the name.`, "unknown_profile"), definition, identity);
7183
7331
  }
7184
7332
  if (commandFlags.profile)
7185
7333
  process.env.MODA_PROFILE = commandFlags.profile;
@@ -7188,7 +7336,7 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
7188
7336
  commandFlags.agent = "true";
7189
7337
  }
7190
7338
  if (!updateCheckDisabled) {
7191
- startUpdateCheck();
7339
+ startUpdateCheck({}, Date.now(), { detached: outputModeFor() !== "human" });
7192
7340
  setAgentUpdateNotice(() => {
7193
7341
  const latest = getAvailableUpdate();
7194
7342
  return latest ? `moda-cli ${VERSION} is out of date (latest ${latest}); commands and flags may differ from the docs. Update: npm install -g @moda-ai/cli@latest` : undefined;