@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.
- package/dist/{agent-nqmha8ck.js → agent-vp9prdma.js} +8 -8
- package/dist/{cli-k6q8dbpk.js → cli-0pkc8jhg.js} +3 -3
- package/dist/{cli-5g1tv80h.js → cli-4h0ave0f.js} +5 -5
- package/dist/{cli-8tfk8qeb.js → cli-6et4z504.js} +7 -6
- package/dist/{cli-1mbb0ct0.js → cli-ccjfwzqx.js} +1 -1
- package/dist/{cli-q6f6vrrr.js → cli-hmjdgxrn.js} +1 -1
- package/dist/{cli-jtyvbd8d.js → cli-pg5qfmqc.js} +1 -1
- package/dist/{cli-b4740tnv.js → cli-q9nsvqqg.js} +14 -14
- package/dist/{cli-d577kq6h.js → cli-qwgct6x7.js} +7 -6
- package/dist/{cli-sqsjd08w.js → cli-r5pp7qny.js} +64 -438
- package/dist/{cli-cdrvjva5.js → cli-v8q7sd7g.js} +28 -6
- package/dist/cli-vdkwkkp5.js +567 -0
- package/dist/{cli-jgfm7w1r.js → cli-wzds257x.js} +5 -4
- package/dist/cli.js +299 -151
- package/dist/{doctor-w913fj4g.js → doctor-wmre3mr7.js} +8 -8
- package/dist/{fix-crkwdkt4.js → fix-75s9s0d6.js} +45 -47
- package/dist/{harness-x3e7d68b.js → harness-a7tb9a23.js} +5 -5
- package/dist/{harness-github-actions-fjhvhgpj.js → harness-github-actions-6v4wydb8.js} +5 -5
- package/dist/{index-2kf3fnnb.js → index-91bpc8g8.js} +15 -14
- package/dist/{production-intelligence-7n83c701.js → production-intelligence-7nqddd4f.js} +15 -15
- package/dist/{profile-commands-ct2t0bfr.js → profile-commands-49yn02yg.js} +5 -4
- package/dist/prompt-source-mcp.js +5 -5
- package/dist/{prompts-92aqqb2k.js → prompts-17wyrst6.js} +6 -6
- package/dist/{provision-gn8raqpt.js → provision-bc3h68e1.js} +5 -5
- package/dist/{registry-ex162j5y.js → registry-fpzhjznj.js} +3 -3
- package/dist/{skills-2mbsj9bt.js → skills-ccdbqghj.js} +5 -5
- package/dist/{sync-kghmmmk5.js → sync-hkxce5zh.js} +7 -7
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- 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
|
-
|
|
4
|
-
|
|
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
|
-
|
|
8
|
-
|
|
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-
|
|
70
|
+
} from "./cli-wzds257x.js";
|
|
51
71
|
import {
|
|
52
72
|
ApiError,
|
|
53
73
|
callControlAPI,
|
|
54
74
|
callDataAPI
|
|
55
|
-
} from "./cli-
|
|
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
|
-
|
|
119
|
+
shellArg,
|
|
111
120
|
validateConfig,
|
|
112
|
-
wasOutputCancelled
|
|
113
|
-
|
|
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
|
-
|
|
417
|
-
return rest;
|
|
497
|
+
return withoutFlag(flags, TELEMETRY_FLAG);
|
|
418
498
|
}
|
|
419
|
-
function isTelemetryDisabled(flags) {
|
|
420
|
-
return flags
|
|
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
|
-
|
|
432
|
-
|
|
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
|
-
|
|
437
|
-
`
|
|
438
|
-
" const
|
|
439
|
-
"
|
|
440
|
-
"
|
|
441
|
-
|
|
442
|
-
"
|
|
443
|
-
"
|
|
444
|
-
" .
|
|
445
|
-
"
|
|
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
|
-
|
|
451
|
-
|
|
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
|
|
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: `${
|
|
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:
|
|
554
|
-
...
|
|
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
|
-
...
|
|
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
|
-
|
|
583
|
-
return rest;
|
|
664
|
+
return withoutFlag(flags, UPDATE_CHECK_FLAG);
|
|
584
665
|
}
|
|
585
666
|
function isUpdateCheckDisabled(flags, env = process.env) {
|
|
586
|
-
return flags
|
|
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
|
-
|
|
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
|
|
650
|
-
if (!
|
|
760
|
+
const latest = getAvailableUpdate(options);
|
|
761
|
+
if (!latest) {
|
|
651
762
|
return;
|
|
652
763
|
}
|
|
653
764
|
return [
|
|
654
765
|
"",
|
|
655
|
-
`Update available: moda-cli ${VERSION} → ${
|
|
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-
|
|
2642
|
+
return (await import("./prompts-17wyrst6.js")).runPromptsCommand(...args);
|
|
2532
2643
|
}
|
|
2533
2644
|
async function runSkillsCommand(...args) {
|
|
2534
|
-
return (await import("./skills-
|
|
2645
|
+
return (await import("./skills-ccdbqghj.js")).runSkillsCommand(...args);
|
|
2535
2646
|
}
|
|
2536
2647
|
async function runFixCommand(...args) {
|
|
2537
|
-
return (await import("./fix-
|
|
2648
|
+
return (await import("./fix-75s9s0d6.js")).runFixCommand(...args);
|
|
2538
2649
|
}
|
|
2539
2650
|
async function runFixesCommand(...args) {
|
|
2540
|
-
return (await import("./fix-
|
|
2651
|
+
return (await import("./fix-75s9s0d6.js")).runFixesCommand(...args);
|
|
2541
2652
|
}
|
|
2542
2653
|
async function runHarnessCommand(...args) {
|
|
2543
|
-
return (await import("./harness-
|
|
2654
|
+
return (await import("./harness-a7tb9a23.js")).runHarnessCommand(...args);
|
|
2544
2655
|
}
|
|
2545
2656
|
async function runSyncCommand(...args) {
|
|
2546
|
-
return (await import("./sync-
|
|
2657
|
+
return (await import("./sync-hkxce5zh.js")).runSyncCommand(...args);
|
|
2547
2658
|
}
|
|
2548
2659
|
async function runRegistryCommand(...args) {
|
|
2549
|
-
return (await import("./registry-
|
|
2660
|
+
return (await import("./registry-fpzhjznj.js")).runRegistryCommand(...args);
|
|
2550
2661
|
}
|
|
2551
2662
|
async function runDoctorCommand(...args) {
|
|
2552
|
-
return (await import("./doctor-
|
|
2663
|
+
return (await import("./doctor-wmre3mr7.js")).runDoctorCommand(...args);
|
|
2553
2664
|
}
|
|
2554
2665
|
async function runStatusCommand(...args) {
|
|
2555
|
-
return (await import("./doctor-
|
|
2666
|
+
return (await import("./doctor-wmre3mr7.js")).runStatusCommand(...args);
|
|
2556
2667
|
}
|
|
2557
2668
|
async function runAuthCommand(...args) {
|
|
2558
|
-
return (await import("./profile-commands-
|
|
2669
|
+
return (await import("./profile-commands-49yn02yg.js")).runAuthCommand(...args);
|
|
2559
2670
|
}
|
|
2560
2671
|
async function runConfigCommand(...args) {
|
|
2561
|
-
return (await import("./profile-commands-
|
|
2672
|
+
return (await import("./profile-commands-49yn02yg.js")).runConfigCommand(...args);
|
|
2562
2673
|
}
|
|
2563
2674
|
async function runProfilesCommand(...args) {
|
|
2564
|
-
return (await import("./profile-commands-
|
|
2675
|
+
return (await import("./profile-commands-49yn02yg.js")).runProfilesCommand(...args);
|
|
2565
2676
|
}
|
|
2566
2677
|
async function runAgentCommand(...args) {
|
|
2567
|
-
return (await import("./agent-
|
|
2678
|
+
return (await import("./agent-vp9prdma.js")).runAgentCommand(...args);
|
|
2568
2679
|
}
|
|
2569
2680
|
async function runProductionCommand(...args) {
|
|
2570
|
-
return (await import("./production-intelligence-
|
|
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-
|
|
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-
|
|
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
|
|
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;
|