@moda-ai/cli 1.55.26 → 1.55.28
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-0w9rtdsw.js} +22 -16
- package/dist/cli-3n0gz4d0.js +17971 -0
- package/dist/{cli-b4740tnv.js → cli-3retgh64.js} +85 -1165
- package/dist/{cli-1mbb0ct0.js → cli-97jew729.js} +1 -1
- package/dist/{cli-sqsjd08w.js → cli-99p2jh28.js} +105 -893
- package/dist/{cli-k6q8dbpk.js → cli-9bgk5jeh.js} +8 -6
- package/dist/{cli-q6f6vrrr.js → cli-9bgnvth2.js} +5 -3
- package/dist/cli-9kfxkxmk.js +6994 -0
- package/dist/cli-cesds766.js +1516 -0
- package/dist/{cli-cdrvjva5.js → cli-dr6x0zv7.js} +28 -6
- package/dist/{cli-jtyvbd8d.js → cli-e23g9ywa.js} +1 -1
- package/dist/cli-fwpqghgc.js +569 -0
- package/dist/cli-k4tqwah4.js +89 -0
- package/dist/{cli-8tfk8qeb.js → cli-mg5zv4s6.js} +18 -15
- package/dist/{cli-jgfm7w1r.js → cli-n2hng3gv.js} +9 -6
- package/dist/cli-ns5fcnkz.js +341 -0
- package/dist/{cli-5g1tv80h.js → cli-ny48a8de.js} +12 -9
- package/dist/{cli-d577kq6h.js → cli-qpq84eee.js} +5220 -32715
- package/dist/cli-xq45etg1.js +1098 -0
- package/dist/cli-yf39avhh.js +754 -0
- package/dist/cli-yz8xcpyk.js +12 -0
- package/dist/cli.js +355 -283
- package/dist/doctor-k3ta6h2y.js +24 -0
- package/dist/{fix-crkwdkt4.js → fix-w5z02wt4.js} +47 -50
- package/dist/{harness-x3e7d68b.js → harness-7azmzytc.js} +15 -7
- package/dist/{harness-github-actions-fjhvhgpj.js → harness-github-actions-bv2qrnqb.js} +11 -5
- package/dist/harness-report-rd9c4e9v.js +54 -0
- package/dist/{index-2kf3fnnb.js → index-d1z50dsq.js} +45 -36
- package/dist/{production-intelligence-7n83c701.js → production-intelligence-wvsgjxth.js} +21 -18
- package/dist/{profile-commands-ct2t0bfr.js → profile-commands-h8evz9x0.js} +9 -5
- package/dist/prompt-attribution-1nytc9wj.js +148 -0
- package/dist/prompt-source-mcp.js +14 -7
- package/dist/prompt-sources-07tczyqa.js +19 -0
- package/dist/{prompts-92aqqb2k.js → prompts-6y9wfq5z.js} +8 -7
- package/dist/prompts-ab-ezrd63sk.js +70 -0
- package/dist/prompts-propose-2k3enm2q.js +255 -0
- package/dist/{provision-gn8raqpt.js → provision-y5bdbh4y.js} +9 -6
- package/dist/{registry-ex162j5y.js → registry-96aze5wp.js} +7 -4
- package/dist/{skills-2mbsj9bt.js → skills-j8865009.js} +7 -5
- package/dist/{sync-kghmmmk5.js → sync-ew7yvy0e.js} +16 -10
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/dist/cli-bb7133m7.js +0 -144
- package/dist/doctor-w913fj4g.js +0 -22
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-fwpqghgc.js";
|
|
5
21
|
import {
|
|
6
22
|
createCommandContext,
|
|
7
|
-
|
|
8
|
-
|
|
23
|
+
envOptOutSet,
|
|
24
|
+
envSwitchedOff,
|
|
25
|
+
optOutFlagSet,
|
|
26
|
+
parseBooleanFlagValue,
|
|
27
|
+
withoutFlag
|
|
28
|
+
} from "./cli-dr6x0zv7.js";
|
|
9
29
|
import {
|
|
10
30
|
AuditSchema,
|
|
11
31
|
COMMAND_FLAG_SPECS,
|
|
@@ -47,22 +67,14 @@ import {
|
|
|
47
67
|
unknownSignalsSubcommandError,
|
|
48
68
|
usageLine,
|
|
49
69
|
writeDryRun
|
|
50
|
-
} from "./cli-
|
|
70
|
+
} from "./cli-n2hng3gv.js";
|
|
51
71
|
import {
|
|
52
72
|
ApiError,
|
|
53
73
|
callControlAPI,
|
|
54
74
|
callDataAPI
|
|
55
|
-
} from "./cli-
|
|
75
|
+
} from "./cli-e23g9ywa.js";
|
|
56
76
|
import {
|
|
57
77
|
AGENT_ERROR_CODES,
|
|
58
|
-
BATCH_CONCURRENCY,
|
|
59
|
-
BATCH_MAX_TARGETS,
|
|
60
|
-
CliAccessError,
|
|
61
|
-
CliAuthError,
|
|
62
|
-
CliCancellationError,
|
|
63
|
-
CliInputError,
|
|
64
|
-
CliInputRequiredError,
|
|
65
|
-
CliNotFoundError,
|
|
66
78
|
EXIT_AUTH_REQUIRED,
|
|
67
79
|
EXIT_CANCELLED,
|
|
68
80
|
EXIT_DEGRADED,
|
|
@@ -74,46 +86,43 @@ import {
|
|
|
74
86
|
VERSION,
|
|
75
87
|
agentEnvelopeFits,
|
|
76
88
|
agentMaxOutputBytes,
|
|
77
|
-
apiErrorStatus,
|
|
78
89
|
apiKeyHeaders,
|
|
79
|
-
asNumber,
|
|
80
|
-
asRecord,
|
|
81
|
-
asString,
|
|
82
|
-
attachInputDetails,
|
|
83
90
|
canonicalCommandText,
|
|
84
|
-
collectBatchTargets,
|
|
85
|
-
compactProblemDossier,
|
|
86
|
-
contextTarget,
|
|
87
91
|
createCliOutput,
|
|
88
92
|
embeddedTenantIdFromApiKey,
|
|
89
|
-
embeddedWindowSize,
|
|
90
93
|
errorToAgentError,
|
|
91
|
-
frustrationsFromEmotions,
|
|
92
94
|
getApiRequestCount,
|
|
93
95
|
getModaDir,
|
|
94
|
-
inputDetailsOf,
|
|
95
|
-
isApiLikeError,
|
|
96
|
-
isNetworkLikeError,
|
|
97
96
|
isPlatformApiKey,
|
|
98
97
|
loadProfileConfig,
|
|
99
|
-
mapWithConcurrency,
|
|
100
|
-
parseBatchTarget,
|
|
101
98
|
resetApiRequestCount,
|
|
102
99
|
resolveApiKey,
|
|
103
100
|
resolveApiTenantId,
|
|
104
101
|
resolveModaBaseUrl,
|
|
102
|
+
resolveModaBaseUrlStrict,
|
|
105
103
|
resolveOutputMode,
|
|
106
104
|
safeWriteStderr,
|
|
107
105
|
safeWriteStdout,
|
|
108
106
|
setAgentUpdateNotice,
|
|
109
107
|
setPlatformTenantOverride,
|
|
110
|
-
|
|
108
|
+
shellArg,
|
|
111
109
|
validateConfig,
|
|
112
|
-
wasOutputCancelled
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
wasOutputCancelled
|
|
111
|
+
} from "./cli-99p2jh28.js";
|
|
112
|
+
import {
|
|
113
|
+
CliAccessError,
|
|
114
|
+
CliAuthError,
|
|
115
|
+
CliCancellationError,
|
|
116
|
+
CliInputError,
|
|
117
|
+
CliInputRequiredError,
|
|
118
|
+
CliNotFoundError,
|
|
119
|
+
apiErrorStatus,
|
|
120
|
+
attachInputDetails,
|
|
121
|
+
inputDetailsOf,
|
|
122
|
+
isApiLikeError,
|
|
123
|
+
isNetworkLikeError
|
|
124
|
+
} from "./cli-k4tqwah4.js";
|
|
125
|
+
import"./cli-ns5fcnkz.js";
|
|
117
126
|
import {
|
|
118
127
|
__require
|
|
119
128
|
} from "./cli-0v6na3yp.js";
|
|
@@ -302,16 +311,91 @@ async function runReplaysCommand(context) {
|
|
|
302
311
|
}
|
|
303
312
|
|
|
304
313
|
// src/telemetry.ts
|
|
314
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
315
|
+
|
|
316
|
+
// src/detached.ts
|
|
305
317
|
import { spawn } from "node:child_process";
|
|
318
|
+
var INSPECTOR_VALUE_OPTIONS = new Set(["--inspect-port", "--debug-port", "--inspect-publish-uid"]);
|
|
319
|
+
function nodeOptionTokens(nodeOptions) {
|
|
320
|
+
const tokens = [];
|
|
321
|
+
let start = -1;
|
|
322
|
+
let quoted = false;
|
|
323
|
+
for (let i = 0;i < nodeOptions.length; i += 1) {
|
|
324
|
+
const ch = nodeOptions[i];
|
|
325
|
+
if (start === -1) {
|
|
326
|
+
if (/\s/.test(ch))
|
|
327
|
+
continue;
|
|
328
|
+
start = i;
|
|
329
|
+
}
|
|
330
|
+
if (quoted && ch === "\\") {
|
|
331
|
+
i += 1;
|
|
332
|
+
} else if (ch === '"') {
|
|
333
|
+
quoted = !quoted;
|
|
334
|
+
} else if (!quoted && /\s/.test(ch)) {
|
|
335
|
+
tokens.push(nodeOptions.slice(start, i));
|
|
336
|
+
start = -1;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (start !== -1)
|
|
340
|
+
tokens.push(nodeOptions.slice(start));
|
|
341
|
+
return tokens;
|
|
342
|
+
}
|
|
343
|
+
function withoutInspectorOptions(nodeOptions) {
|
|
344
|
+
const tokens = nodeOptionTokens(nodeOptions);
|
|
345
|
+
const kept = [];
|
|
346
|
+
for (let i = 0;i < tokens.length; i += 1) {
|
|
347
|
+
const name = tokens[i].split("=")[0];
|
|
348
|
+
if (!name.startsWith("--inspect") && name !== "--debug-port") {
|
|
349
|
+
kept.push(tokens[i]);
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
if (INSPECTOR_VALUE_OPTIONS.has(tokens[i]) && tokens[i + 1] && !tokens[i + 1].startsWith("-"))
|
|
353
|
+
i += 1;
|
|
354
|
+
}
|
|
355
|
+
return kept.join(" ");
|
|
356
|
+
}
|
|
357
|
+
function spawnDetachedNode(script, options = {}, spawnImpl = spawn) {
|
|
358
|
+
try {
|
|
359
|
+
const env = { ...process.env, ...options.env };
|
|
360
|
+
for (const key of options.dropEnv ?? [])
|
|
361
|
+
delete env[key];
|
|
362
|
+
if (env.NODE_OPTIONS?.includes("--inspect")) {
|
|
363
|
+
const kept = withoutInspectorOptions(env.NODE_OPTIONS);
|
|
364
|
+
if (kept)
|
|
365
|
+
env.NODE_OPTIONS = kept;
|
|
366
|
+
else
|
|
367
|
+
delete env.NODE_OPTIONS;
|
|
368
|
+
}
|
|
369
|
+
const child = spawnImpl(process.execPath, ["-e", script], {
|
|
370
|
+
detached: true,
|
|
371
|
+
stdio: [options.stdin === undefined ? "ignore" : "pipe", "ignore", "ignore"],
|
|
372
|
+
windowsHide: true,
|
|
373
|
+
env
|
|
374
|
+
});
|
|
375
|
+
child.on("error", () => {});
|
|
376
|
+
if (child.pid === undefined)
|
|
377
|
+
return false;
|
|
378
|
+
if (options.stdin !== undefined && child.stdin) {
|
|
379
|
+
child.stdin.on("error", () => {});
|
|
380
|
+
child.stdin.end(options.stdin);
|
|
381
|
+
}
|
|
382
|
+
child.unref();
|
|
383
|
+
return true;
|
|
384
|
+
} catch {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// src/telemetry.ts
|
|
306
390
|
import { randomUUID } from "node:crypto";
|
|
307
391
|
var INLINE_TELEMETRY_TIMEOUT_MS = 500;
|
|
308
392
|
var DETACHED_TELEMETRY_TIMEOUT_MS = 5000;
|
|
309
393
|
var INVOCATION_ID = randomUUID();
|
|
310
394
|
var TELEMETRY_FLAG = "no-telemetry";
|
|
311
|
-
var TELEMETRY_REQUEST_ENV = "MODA_CLI_TELEMETRY_REQUEST";
|
|
312
395
|
var TELEMETRY_TRANSPORT_ENV = "MODA_CLI_TELEMETRY_TRANSPORT";
|
|
313
396
|
var MAX_TELEMETRY_DURATION_MS = 86400000;
|
|
314
397
|
var MAX_TELEMETRY_API_REQUEST_COUNT = 1e6;
|
|
398
|
+
var MAX_UNKNOWN_FLAG_COUNT = 1000;
|
|
315
399
|
var SEARCH_SURFACE_BY_COMMAND = {
|
|
316
400
|
search: "message",
|
|
317
401
|
conversations: "conversation",
|
|
@@ -413,11 +497,10 @@ function serializeAdoption(adoption) {
|
|
|
413
497
|
return out;
|
|
414
498
|
}
|
|
415
499
|
function stripTelemetryFlag(flags) {
|
|
416
|
-
|
|
417
|
-
return rest;
|
|
500
|
+
return withoutFlag(flags, TELEMETRY_FLAG);
|
|
418
501
|
}
|
|
419
|
-
function isTelemetryDisabled(flags) {
|
|
420
|
-
return flags
|
|
502
|
+
function isTelemetryDisabled(flags, env = process.env) {
|
|
503
|
+
return optOutFlagSet(flags, TELEMETRY_FLAG) || envSwitchedOff(env.MODA_CLI_TELEMETRY) || envOptOutSet(env.DO_NOT_TRACK);
|
|
421
504
|
}
|
|
422
505
|
var VALIDATION_REASON_MAX = 128;
|
|
423
506
|
var DEGRADE_REASON_MAX = 64;
|
|
@@ -428,88 +511,78 @@ function sanitizeReasonCode(reason, max) {
|
|
|
428
511
|
function sanitizeValidationReason(reason) {
|
|
429
512
|
return sanitizeReasonCode(reason, VALIDATION_REASON_MAX);
|
|
430
513
|
}
|
|
431
|
-
|
|
432
|
-
|
|
514
|
+
var MAX_FLAG_NAMES = 50;
|
|
515
|
+
var FLAG_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
516
|
+
var SECRET_PATTERNS = [
|
|
517
|
+
/moda_sk_/i,
|
|
518
|
+
/(?:^|[^A-Za-z0-9])sk-[A-Za-z0-9_-]{8,}/,
|
|
519
|
+
/(?:^|[^A-Za-z0-9])(?:sk|pk|rk)_(?:live|test)_/i,
|
|
520
|
+
/gh[pousr]_[A-Za-z0-9]{16,}/,
|
|
521
|
+
/github_pat_/i,
|
|
522
|
+
/xox[abprs]-/i,
|
|
523
|
+
/AKIA[0-9A-Z]{16}/,
|
|
524
|
+
/eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/,
|
|
525
|
+
/-----BEGIN [A-Z ]*PRIVATE KEY/,
|
|
526
|
+
/[^\s@]+@[^\s@]+\.[A-Za-z]{2,}/,
|
|
527
|
+
/[A-Za-z0-9+/=]{32,}/
|
|
528
|
+
];
|
|
529
|
+
function looksSecret(value) {
|
|
530
|
+
return SECRET_PATTERNS.some((pattern) => pattern.test(value));
|
|
531
|
+
}
|
|
532
|
+
function reportedFlagNames(flags, acceptedFlags = new Set) {
|
|
533
|
+
const names = new Set;
|
|
534
|
+
let unknownCount = 0;
|
|
535
|
+
for (const key of Object.keys(stripTelemetryFlag(flags))) {
|
|
536
|
+
if (acceptedFlags.has(key.replace(/_/g, "-")) && FLAG_NAME_RE.test(key) && !looksSecret(key))
|
|
537
|
+
names.add(key);
|
|
538
|
+
else
|
|
539
|
+
unknownCount += 1;
|
|
540
|
+
}
|
|
541
|
+
const sorted = [...names].sort();
|
|
542
|
+
return { names: sorted.slice(0, MAX_FLAG_NAMES), unknownCount: unknownCount + Math.max(0, sorted.length - MAX_FLAG_NAMES) };
|
|
543
|
+
}
|
|
544
|
+
function reportedValidationReason(reason, knownFlags = new Set) {
|
|
545
|
+
let code = reason;
|
|
546
|
+
const unknownFlag = code ? /^unknown_flag:(.*)$/s.exec(code) : null;
|
|
547
|
+
if (unknownFlag) {
|
|
548
|
+
const name = unknownFlag[1].replace(/_/g, "-");
|
|
549
|
+
code = knownFlags.has(name) && FLAG_NAME_RE.test(name) ? `unknown_flag:${name}` : "unknown_flag";
|
|
550
|
+
}
|
|
551
|
+
const cleaned = sanitizeValidationReason(code);
|
|
552
|
+
if (!cleaned || !looksSecret(cleaned))
|
|
553
|
+
return cleaned;
|
|
554
|
+
const head = cleaned.split(":")[0];
|
|
555
|
+
return head && !looksSecret(head) ? head : undefined;
|
|
556
|
+
}
|
|
557
|
+
function safeCode(value) {
|
|
558
|
+
return value && !looksSecret(value) ? value : undefined;
|
|
433
559
|
}
|
|
434
560
|
var TELEMETRY_SENDER_SCRIPT = [
|
|
435
561
|
"try {",
|
|
436
|
-
|
|
437
|
-
`
|
|
438
|
-
" const
|
|
439
|
-
"
|
|
440
|
-
"
|
|
441
|
-
|
|
442
|
-
"
|
|
443
|
-
"
|
|
444
|
-
" .
|
|
445
|
-
"
|
|
446
|
-
"
|
|
562
|
+
" let raw = '';",
|
|
563
|
+
` const quit = setTimeout(() => process.exit(0), ${DETACHED_TELEMETRY_TIMEOUT_MS + 1000});`,
|
|
564
|
+
" const done = () => clearTimeout(quit);",
|
|
565
|
+
" process.stdin.setEncoding('utf8');",
|
|
566
|
+
" process.stdin.on('error', () => {});",
|
|
567
|
+
" process.stdin.on('data', (chunk) => { raw += chunk; });",
|
|
568
|
+
" 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(); }",
|
|
580
|
+
" });",
|
|
447
581
|
"} catch {}"
|
|
448
582
|
].join(`
|
|
449
583
|
`);
|
|
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
|
-
}
|
|
584
|
+
function spawnDetachedTelemetrySender(request, spawnImpl = spawn2) {
|
|
585
|
+
return spawnDetachedNode(TELEMETRY_SENDER_SCRIPT, { stdin: JSON.stringify(request), dropEnv: ["MODA_API_KEY"] }, spawnImpl);
|
|
513
586
|
}
|
|
514
587
|
async function sendInline(request) {
|
|
515
588
|
const controller = new AbortController;
|
|
@@ -529,16 +602,25 @@ async function sendInline(request) {
|
|
|
529
602
|
}
|
|
530
603
|
}
|
|
531
604
|
function buildCliUsageRequest(input) {
|
|
532
|
-
const
|
|
605
|
+
const baseUrl = resolveModaBaseUrlStrict(input.profile ? { profile: input.profile } : {});
|
|
606
|
+
if (!baseUrl)
|
|
607
|
+
return;
|
|
608
|
+
const validationReason = reportedValidationReason(input.validationReason, input.knownFlags);
|
|
609
|
+
const flagNames = reportedFlagNames(input.flags, input.acceptedFlags);
|
|
610
|
+
const adoption = serializeAdoption(input.adoption);
|
|
611
|
+
for (const key of ["subcommand", "degrade_reason", "skill_version"]) {
|
|
612
|
+
if (typeof adoption[key] === "string" && looksSecret(adoption[key]))
|
|
613
|
+
delete adoption[key];
|
|
614
|
+
}
|
|
533
615
|
return {
|
|
534
|
-
url: `${
|
|
616
|
+
url: `${baseUrl}/api/v1/data/cli-usage`,
|
|
535
617
|
headers: {
|
|
536
618
|
...apiKeyHeaders(input.apiKey),
|
|
537
619
|
"Content-Type": "application/json"
|
|
538
620
|
},
|
|
539
621
|
body: JSON.stringify({
|
|
540
622
|
invocation_id: INVOCATION_ID,
|
|
541
|
-
command: input.command.slice(0, 64),
|
|
623
|
+
command: safeCode(input.command.slice(0, 64)) ?? "unknown",
|
|
542
624
|
status: input.status,
|
|
543
625
|
error_type: input.errorType,
|
|
544
626
|
...validationReason ? { validation_reason: validationReason } : {},
|
|
@@ -550,10 +632,11 @@ function buildCliUsageRequest(input) {
|
|
|
550
632
|
platform: process.platform,
|
|
551
633
|
arch: process.arch,
|
|
552
634
|
flags_json: {
|
|
553
|
-
names:
|
|
554
|
-
...
|
|
635
|
+
names: flagNames.names,
|
|
636
|
+
...flagNames.unknownCount > 0 ? { unknown_count: Math.min(flagNames.unknownCount, MAX_UNKNOWN_FLAG_COUNT) } : {},
|
|
637
|
+
...((alias) => alias ? { legacy_alias: alias } : {})(safeCode(sanitizeReasonCode(input.legacyAlias?.replace(/ /g, ":"), 64)))
|
|
555
638
|
},
|
|
556
|
-
...
|
|
639
|
+
...adoption
|
|
557
640
|
})
|
|
558
641
|
};
|
|
559
642
|
}
|
|
@@ -563,6 +646,8 @@ async function sendCliUsageTelemetry(input) {
|
|
|
563
646
|
return;
|
|
564
647
|
}
|
|
565
648
|
const request = buildCliUsageRequest({ ...input, apiKey: input.apiKey });
|
|
649
|
+
if (!request)
|
|
650
|
+
return;
|
|
566
651
|
if (process.env[TELEMETRY_TRANSPORT_ENV] !== "inline" && spawnDetachedTelemetrySender(request)) {
|
|
567
652
|
return;
|
|
568
653
|
}
|
|
@@ -579,11 +664,10 @@ var REGISTRY_TIMEOUT_MS = 1500;
|
|
|
579
664
|
var REGISTRY_LATEST_URL = "https://registry.npmjs.org/@moda-ai/cli/latest";
|
|
580
665
|
var SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
|
|
581
666
|
function stripUpdateCheckFlag(flags) {
|
|
582
|
-
|
|
583
|
-
return rest;
|
|
667
|
+
return withoutFlag(flags, UPDATE_CHECK_FLAG);
|
|
584
668
|
}
|
|
585
669
|
function isUpdateCheckDisabled(flags, env = process.env) {
|
|
586
|
-
return flags
|
|
670
|
+
return optOutFlagSet(flags, UPDATE_CHECK_FLAG) || envSwitchedOff(env.MODA_CLI_UPDATE_CHECK) || envOptOutSet(env.DO_NOT_TRACK) || envOptOutSet(env.CI);
|
|
587
671
|
}
|
|
588
672
|
function cachePath(options = {}) {
|
|
589
673
|
return join(getModaDir(options), "update-check.json");
|
|
@@ -616,9 +700,39 @@ function isNewerVersion(candidate, current) {
|
|
|
616
700
|
}
|
|
617
701
|
return false;
|
|
618
702
|
}
|
|
619
|
-
|
|
703
|
+
var UPDATE_CHECK_URL_ENV = "MODA_CLI_UPDATE_CHECK_URL";
|
|
704
|
+
var UPDATE_CHECK_CACHE_ENV = "MODA_CLI_UPDATE_CHECK_CACHE";
|
|
705
|
+
var DETACHED_REGISTRY_TIMEOUT_MS = 1e4;
|
|
706
|
+
var UPDATE_CHECK_SCRIPT = [
|
|
707
|
+
"try {",
|
|
708
|
+
` const url = process.env.${UPDATE_CHECK_URL_ENV};`,
|
|
709
|
+
` const path = process.env.${UPDATE_CHECK_CACHE_ENV};`,
|
|
710
|
+
` const semver = new RegExp(${JSON.stringify(SEMVER_RE.source)});`,
|
|
711
|
+
" if (url && path && typeof fetch === 'function') {",
|
|
712
|
+
" const c = new AbortController();",
|
|
713
|
+
` const t = setTimeout(() => c.abort(), ${DETACHED_REGISTRY_TIMEOUT_MS});`,
|
|
714
|
+
" fetch(url, { headers: { Accept: 'application/json' }, signal: c.signal })",
|
|
715
|
+
" .then((res) => (res.ok ? res.json() : null))",
|
|
716
|
+
" .then((body) => {",
|
|
717
|
+
" if (body && typeof body.version === 'string' && semver.test(body.version)) {",
|
|
718
|
+
" require('fs').writeFileSync(path, JSON.stringify({ checked_at: Date.now(), latest: body.version }, null, 2) + '\\n', 'utf8');",
|
|
719
|
+
" }",
|
|
720
|
+
" })",
|
|
721
|
+
" .catch(() => {})",
|
|
722
|
+
" .finally(() => clearTimeout(t));",
|
|
723
|
+
" }",
|
|
724
|
+
"} catch {}"
|
|
725
|
+
].join(`
|
|
726
|
+
`);
|
|
727
|
+
async function startUpdateCheck(options = {}, now = Date.now(), mode = {}) {
|
|
620
728
|
const cache = readCache(options);
|
|
621
|
-
if (cache && now - cache.checked_at < CHECK_INTERVAL_MS) {
|
|
729
|
+
if (cache && cache.checked_at <= now && now - cache.checked_at < CHECK_INTERVAL_MS) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const known = cache && SEMVER_RE.test(cache.latest) ? cache.latest : "";
|
|
733
|
+
writeCache({ checked_at: now, latest: known }, options);
|
|
734
|
+
if (mode.detached) {
|
|
735
|
+
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
736
|
return;
|
|
623
737
|
}
|
|
624
738
|
const controller = new AbortController;
|
|
@@ -643,16 +757,16 @@ async function startUpdateCheck(options = {}, now = Date.now()) {
|
|
|
643
757
|
}
|
|
644
758
|
function getAvailableUpdate(options = {}) {
|
|
645
759
|
const cache = readCache(options);
|
|
646
|
-
return cache && isNewerVersion(cache.latest, VERSION) ? cache.latest : undefined;
|
|
760
|
+
return cache && SEMVER_RE.test(cache.latest) && isNewerVersion(cache.latest, VERSION) ? cache.latest : undefined;
|
|
647
761
|
}
|
|
648
762
|
function getUpdateNotice(options = {}) {
|
|
649
|
-
const
|
|
650
|
-
if (!
|
|
763
|
+
const latest = getAvailableUpdate(options);
|
|
764
|
+
if (!latest) {
|
|
651
765
|
return;
|
|
652
766
|
}
|
|
653
767
|
return [
|
|
654
768
|
"",
|
|
655
|
-
`Update available: moda-cli ${VERSION} → ${
|
|
769
|
+
`Update available: moda-cli ${VERSION} → ${latest}`,
|
|
656
770
|
"Run `npm install -g @moda-ai/cli@latest` to update."
|
|
657
771
|
].join(`
|
|
658
772
|
`);
|
|
@@ -2528,46 +2642,46 @@ function leafManifestFields(leaf, commands) {
|
|
|
2528
2642
|
import { fileURLToPath } from "url";
|
|
2529
2643
|
import { realpathSync } from "fs";
|
|
2530
2644
|
async function runPromptsCommand(...args) {
|
|
2531
|
-
return (await import("./prompts-
|
|
2645
|
+
return (await import("./prompts-6y9wfq5z.js")).runPromptsCommand(...args);
|
|
2532
2646
|
}
|
|
2533
2647
|
async function runSkillsCommand(...args) {
|
|
2534
|
-
return (await import("./skills-
|
|
2648
|
+
return (await import("./skills-j8865009.js")).runSkillsCommand(...args);
|
|
2535
2649
|
}
|
|
2536
2650
|
async function runFixCommand(...args) {
|
|
2537
|
-
return (await import("./fix-
|
|
2651
|
+
return (await import("./fix-w5z02wt4.js")).runFixCommand(...args);
|
|
2538
2652
|
}
|
|
2539
2653
|
async function runFixesCommand(...args) {
|
|
2540
|
-
return (await import("./fix-
|
|
2654
|
+
return (await import("./fix-w5z02wt4.js")).runFixesCommand(...args);
|
|
2541
2655
|
}
|
|
2542
2656
|
async function runHarnessCommand(...args) {
|
|
2543
|
-
return (await import("./harness-
|
|
2657
|
+
return (await import("./harness-7azmzytc.js")).runHarnessCommand(...args);
|
|
2544
2658
|
}
|
|
2545
2659
|
async function runSyncCommand(...args) {
|
|
2546
|
-
return (await import("./sync-
|
|
2660
|
+
return (await import("./sync-ew7yvy0e.js")).runSyncCommand(...args);
|
|
2547
2661
|
}
|
|
2548
2662
|
async function runRegistryCommand(...args) {
|
|
2549
|
-
return (await import("./registry-
|
|
2663
|
+
return (await import("./registry-96aze5wp.js")).runRegistryCommand(...args);
|
|
2550
2664
|
}
|
|
2551
2665
|
async function runDoctorCommand(...args) {
|
|
2552
|
-
return (await import("./doctor-
|
|
2666
|
+
return (await import("./doctor-k3ta6h2y.js")).runDoctorCommand(...args);
|
|
2553
2667
|
}
|
|
2554
2668
|
async function runStatusCommand(...args) {
|
|
2555
|
-
return (await import("./doctor-
|
|
2669
|
+
return (await import("./doctor-k3ta6h2y.js")).runStatusCommand(...args);
|
|
2556
2670
|
}
|
|
2557
2671
|
async function runAuthCommand(...args) {
|
|
2558
|
-
return (await import("./profile-commands-
|
|
2672
|
+
return (await import("./profile-commands-h8evz9x0.js")).runAuthCommand(...args);
|
|
2559
2673
|
}
|
|
2560
2674
|
async function runConfigCommand(...args) {
|
|
2561
|
-
return (await import("./profile-commands-
|
|
2675
|
+
return (await import("./profile-commands-h8evz9x0.js")).runConfigCommand(...args);
|
|
2562
2676
|
}
|
|
2563
2677
|
async function runProfilesCommand(...args) {
|
|
2564
|
-
return (await import("./profile-commands-
|
|
2678
|
+
return (await import("./profile-commands-h8evz9x0.js")).runProfilesCommand(...args);
|
|
2565
2679
|
}
|
|
2566
2680
|
async function runAgentCommand(...args) {
|
|
2567
|
-
return (await import("./agent-
|
|
2681
|
+
return (await import("./agent-0w9rtdsw.js")).runAgentCommand(...args);
|
|
2568
2682
|
}
|
|
2569
2683
|
async function runProductionCommand(...args) {
|
|
2570
|
-
return (await import("./production-intelligence-
|
|
2684
|
+
return (await import("./production-intelligence-wvsgjxth.js")).runProductionCommand(...args);
|
|
2571
2685
|
}
|
|
2572
2686
|
function parseArgs(argv) {
|
|
2573
2687
|
const args = argv.slice(2);
|
|
@@ -3265,23 +3379,21 @@ function noWorldStateWarnings(conversationId, isMissing) {
|
|
|
3265
3379
|
}
|
|
3266
3380
|
var AUDIT_DEFAULT_LIMIT = 200;
|
|
3267
3381
|
var AUDIT_MAX_LIMIT = 1000;
|
|
3268
|
-
function auditCapStatus(data
|
|
3382
|
+
function auditCapStatus(data) {
|
|
3269
3383
|
const record = asRecord(data);
|
|
3270
3384
|
if (!record)
|
|
3271
3385
|
return null;
|
|
3272
3386
|
const summary = asRecord(record.summary) ?? {};
|
|
3273
3387
|
const rows = (asNumber(summary.ingest_rows) ?? (Array.isArray(record.ingest) ? record.ingest.length : 0)) + (asNumber(record.parse_errors) ?? 0);
|
|
3274
3388
|
const spans = asNumber(summary.total_spans) ?? (Array.isArray(record.spans) ? record.spans.length : 0);
|
|
3275
|
-
const
|
|
3389
|
+
const rowsCapped = record.has_more === true || summary.has_more === true;
|
|
3276
3390
|
const spansCapped = summary.truncated === true || record.truncated === true;
|
|
3277
|
-
const serverSaid = typeof record.has_more === "boolean" || typeof summary.has_more === "boolean";
|
|
3278
|
-
const rowsCapped = hasMore || !serverSaid && rows >= limit;
|
|
3279
3391
|
if (!rowsCapped && !spansCapped)
|
|
3280
3392
|
return null;
|
|
3281
3393
|
const reason = typeof summary.truncated_reason === "string" ? summary.truncated_reason : null;
|
|
3282
3394
|
const cursorValue = summary.next_cursor ?? record.next_cursor;
|
|
3283
3395
|
const nextCursor = typeof cursorValue === "string" && cursorValue ? cursorValue : null;
|
|
3284
|
-
return { rowsCapped, spansCapped,
|
|
3396
|
+
return { rowsCapped, spansCapped, rows, spans, reason, nextCursor };
|
|
3285
3397
|
}
|
|
3286
3398
|
var AUDIT_AGENT_RESERVE_BYTES = 16384;
|
|
3287
3399
|
function auditMaxBytes(budgetBytes) {
|
|
@@ -3326,7 +3438,7 @@ function auditOutput(command, params, data, keep) {
|
|
|
3326
3438
|
if (partial && record) {
|
|
3327
3439
|
const continueWith = auditFlags([
|
|
3328
3440
|
params.limit ? `--limit=${params.limit}` : "",
|
|
3329
|
-
params.cursor ? `--cursor=${params.cursor}` : "",
|
|
3441
|
+
params.cursor ? `--cursor=${shellArg(params.cursor)}` : "",
|
|
3330
3442
|
params.page_bytes ? `--page-bytes=${params.page_bytes}` : "",
|
|
3331
3443
|
`--span-offset=${end}`
|
|
3332
3444
|
]);
|
|
@@ -3352,7 +3464,7 @@ function auditOutput(command, params, data, keep) {
|
|
|
3352
3464
|
}
|
|
3353
3465
|
};
|
|
3354
3466
|
}
|
|
3355
|
-
const capped = auditCapStatus(data
|
|
3467
|
+
const capped = auditCapStatus(data);
|
|
3356
3468
|
if (!capped || !record) {
|
|
3357
3469
|
return {
|
|
3358
3470
|
data: record ? { ...record, truncated: false, has_more: false, next_cursor: null } : data,
|
|
@@ -3365,7 +3477,7 @@ function auditOutput(command, params, data, keep) {
|
|
|
3365
3477
|
const nextCommands = [];
|
|
3366
3478
|
if (capped.nextCursor) {
|
|
3367
3479
|
nextCommands.push({
|
|
3368
|
-
command: auditFlags([params.limit ? `--limit=${params.limit}` : "", `--cursor=${capped.nextCursor}`]),
|
|
3480
|
+
command: auditFlags([params.limit ? `--limit=${params.limit}` : "", `--cursor=${shellArg(capped.nextCursor)}`]),
|
|
3369
3481
|
purpose: "Read the next page of ingest rows of this trace.",
|
|
3370
3482
|
mutability: "read",
|
|
3371
3483
|
requires_approval: false
|
|
@@ -3377,7 +3489,7 @@ function auditOutput(command, params, data, keep) {
|
|
|
3377
3489
|
warnings.push(`Spans were capped: the page reached the server's per-page span cap after ${capped.rows} ingest row(s), so this trace has more spans than the ${shownText}. Continue with the next_cursor page. Orphan/duplicate analysis covers this page only.`);
|
|
3378
3490
|
} else if (capped.rowsCapped) {
|
|
3379
3491
|
const bigger = Math.min(AUDIT_MAX_LIMIT, limit * 5);
|
|
3380
|
-
warnings.push(`Spans were capped: read ${capped.rows} ingest row(s), the --limit=${limit} maximum, so this trace
|
|
3492
|
+
warnings.push(`Spans were capped: read ${capped.rows} ingest row(s), the --limit=${limit} maximum, so this trace has more spans than the ${shownText}. ` + (capped.nextCursor ? "Page on with the next_cursor command, or " : "") + (limit < AUDIT_MAX_LIMIT ? `${capped.nextCursor ? "rerun" : "Rerun"} with --limit=${bigger} (max ${AUDIT_MAX_LIMIT}), or ${perTrace}.` : capped.nextCursor ? `${perTrace}.` : `${perTrace[0].toUpperCase()}${perTrace.slice(1)}.`));
|
|
3381
3493
|
if (limit < AUDIT_MAX_LIMIT && !params.cursor && !sliced) {
|
|
3382
3494
|
nextCommands.push({ command: auditFlags([`--limit=${bigger}`]), purpose: "Read more ingest rows of this trace.", mutability: "read", requires_approval: false });
|
|
3383
3495
|
}
|
|
@@ -3767,13 +3879,6 @@ function specParseOptions(spec) {
|
|
|
3767
3879
|
...spec.flagAliases ? { flagAliases: spec.flagAliases } : {}
|
|
3768
3880
|
};
|
|
3769
3881
|
}
|
|
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
3882
|
function semanticIndexCoverage(coverage) {
|
|
3778
3883
|
const ratio = asRecord(asRecord(coverage)?.semantic_index)?.coverage_ratio;
|
|
3779
3884
|
if (typeof ratio !== "number" || !Number.isFinite(ratio) || ratio < 0 || ratio > 1)
|
|
@@ -4153,8 +4258,18 @@ var CONTEXT_BUDGET_BYTES_PER_FIRST_PAGE_MESSAGE = 480;
|
|
|
4153
4258
|
function jsonByteLength(value) {
|
|
4154
4259
|
return Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
|
|
4155
4260
|
}
|
|
4156
|
-
|
|
4157
|
-
|
|
4261
|
+
function largestFittingCount(max, fits) {
|
|
4262
|
+
let low = 1;
|
|
4263
|
+
let high = Math.max(1, max);
|
|
4264
|
+
while (low < high) {
|
|
4265
|
+
const mid = Math.ceil((low + high) / 2);
|
|
4266
|
+
if (fits(mid))
|
|
4267
|
+
low = mid;
|
|
4268
|
+
else
|
|
4269
|
+
high = mid - 1;
|
|
4270
|
+
}
|
|
4271
|
+
return low;
|
|
4272
|
+
}
|
|
4158
4273
|
var LONE_SURROGATE = /[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/g;
|
|
4159
4274
|
function stripLoneSurrogates(value) {
|
|
4160
4275
|
if (typeof value === "string")
|
|
@@ -4166,13 +4281,6 @@ function stripLoneSurrogates(value) {
|
|
|
4166
4281
|
}
|
|
4167
4282
|
return value;
|
|
4168
4283
|
}
|
|
4169
|
-
function isUnknownRangeParamsError(error) {
|
|
4170
|
-
const e = error;
|
|
4171
|
-
if (e?.statusCode !== 400)
|
|
4172
|
-
return false;
|
|
4173
|
-
const text = `${typeof e.responseBody === "string" ? e.responseBody : ""} ${typeof e.message === "string" ? e.message : ""}`;
|
|
4174
|
-
return /property (from|count) should not exist/i.test(text);
|
|
4175
|
-
}
|
|
4176
4284
|
function pageMessages(page) {
|
|
4177
4285
|
const messages = asRecord(page.context)?.messages ?? page.messages;
|
|
4178
4286
|
return (Array.isArray(messages) ? messages : []).map((m) => asRecord(m) ?? {});
|
|
@@ -4182,13 +4290,11 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4182
4290
|
const start = opts.from ?? 0;
|
|
4183
4291
|
const requested = opts.maxMessages ?? FULL_TRANSCRIPT_DEFAULT_MAX_MESSAGES;
|
|
4184
4292
|
const path = `/conversations/${encodeURIComponent(conversationId)}/context`;
|
|
4185
|
-
const warnings = [];
|
|
4186
4293
|
const messages = [];
|
|
4187
4294
|
let total = 0;
|
|
4188
4295
|
let summary = null;
|
|
4189
4296
|
let ordering;
|
|
4190
4297
|
let nextFrom = null;
|
|
4191
|
-
let legacy = false;
|
|
4192
4298
|
let cursor = start;
|
|
4193
4299
|
let readBytes = 0;
|
|
4194
4300
|
const byteBudget = opts.fits ? opts.maxBytes : undefined;
|
|
@@ -4199,22 +4305,13 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4199
4305
|
const estimate = average > 0 ? Math.ceil(Math.max(0, byteBudget - readBytes) / average) + 1 : Math.max(1, Math.floor(byteBudget / CONTEXT_BUDGET_BYTES_PER_FIRST_PAGE_MESSAGE));
|
|
4200
4306
|
count = Math.max(1, Math.min(count, estimate));
|
|
4201
4307
|
}
|
|
4202
|
-
|
|
4203
|
-
try {
|
|
4204
|
-
page = asRecord(await callDataAPI(`${path}?from=${cursor}&count=${count}`)) ?? {};
|
|
4205
|
-
} catch (error) {
|
|
4206
|
-
if (cursor === start && isUnknownRangeParamsError(error)) {
|
|
4207
|
-
legacy = true;
|
|
4208
|
-
break;
|
|
4209
|
-
}
|
|
4210
|
-
throw error;
|
|
4211
|
-
}
|
|
4308
|
+
const page = asRecord(await callDataAPI(`${path}?from=${cursor}&count=${count}`)) ?? {};
|
|
4212
4309
|
if (cursor === start) {
|
|
4213
4310
|
total = asNumber(page.total_messages) ?? 0;
|
|
4214
|
-
summary = page.summary ?? null;
|
|
4215
|
-
ordering = asRecord(page.ordering) ?? undefined;
|
|
4311
|
+
summary = stripLoneSurrogates(page.summary ?? null);
|
|
4312
|
+
ordering = stripLoneSurrogates(asRecord(page.ordering) ?? undefined);
|
|
4216
4313
|
}
|
|
4217
|
-
const batch = pageMessages(page);
|
|
4314
|
+
const batch = stripLoneSurrogates(pageMessages(page));
|
|
4218
4315
|
messages.push(...batch);
|
|
4219
4316
|
if (byteBudget !== undefined)
|
|
4220
4317
|
readBytes += batch.reduce((sum, message) => sum + jsonByteLength(message) + 1, 0);
|
|
@@ -4226,46 +4323,13 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4226
4323
|
break;
|
|
4227
4324
|
cursor = nextFrom;
|
|
4228
4325
|
}
|
|
4229
|
-
if (legacy) {
|
|
4230
|
-
const limit = Math.min(requested, LEGACY_WINDOW_MAX_MESSAGES);
|
|
4231
|
-
const window = 5;
|
|
4232
|
-
const span = window * 2 + 1;
|
|
4233
|
-
const byIndex = new Map;
|
|
4234
|
-
for (let center = start + window;; center += span) {
|
|
4235
|
-
const page = asRecord(await callDataAPI(`${path}?msg_index=${center}&window=${window}`)) ?? {};
|
|
4236
|
-
if (center === start + window) {
|
|
4237
|
-
total = asNumber(page.total_messages) ?? 0;
|
|
4238
|
-
summary = page.summary ?? null;
|
|
4239
|
-
}
|
|
4240
|
-
for (const message of pageMessages(page)) {
|
|
4241
|
-
const index = asNumber(message.index);
|
|
4242
|
-
if (index !== null && index !== undefined && index >= start && index < start + limit)
|
|
4243
|
-
byIndex.set(index, message);
|
|
4244
|
-
}
|
|
4245
|
-
if (center + window + 1 >= Math.min(total, start + limit))
|
|
4246
|
-
break;
|
|
4247
|
-
}
|
|
4248
|
-
messages.push(...[...byIndex.entries()].sort(([a], [b]) => a - b).map(([, message]) => message));
|
|
4249
|
-
const end = start + messages.length;
|
|
4250
|
-
nextFrom = end < total && messages.length > 0 ? end : null;
|
|
4251
|
-
warnings.push(`This Moda server has no range reads for context (older backend), so --all fell back to windowed paging and stopped at ${LEGACY_WINDOW_MAX_MESSAGES} messages to keep it cheap.`);
|
|
4252
|
-
}
|
|
4253
4326
|
throwIfNotFound("trace", conversationId, total === 0);
|
|
4254
|
-
const pageSize =
|
|
4327
|
+
const pageSize = requested;
|
|
4255
4328
|
const tied = asNumber(ordering?.tied_timestamp_messages) ?? 0;
|
|
4256
4329
|
const synthetic = asNumber(ordering?.synthetic_timestamp_messages) ?? 0;
|
|
4257
|
-
const atCap = (value) => {
|
|
4258
|
-
const text = typeof value === "string" ? value : value === undefined || value === null ? "" : JSON.stringify(value);
|
|
4259
|
-
return text.length >= CONTEXT_MESSAGE_TRUNCATE_CHARS;
|
|
4260
|
-
};
|
|
4261
|
-
const isTruncated = (record) => {
|
|
4262
|
-
const toolCalls = Array.isArray(record.tool_calls) ? record.tool_calls : [];
|
|
4263
|
-
const toolResults = Array.isArray(record.tool_results) ? record.tool_results : [];
|
|
4264
|
-
return atCap(record.content) || toolCalls.some((call) => atCap(asRecord(call)?.input)) || toolResults.some((result) => atCap(asRecord(result)?.content));
|
|
4265
|
-
};
|
|
4266
4330
|
const build = (kept) => {
|
|
4267
4331
|
const returned = messages.slice(0, kept);
|
|
4268
|
-
const out = [
|
|
4332
|
+
const out = [];
|
|
4269
4333
|
if (total > 0 && start >= total) {
|
|
4270
4334
|
out.push(`--from=${start} is past the end of this trace (${total} messages, indexes 0-${total - 1}).`);
|
|
4271
4335
|
}
|
|
@@ -4287,12 +4351,9 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4287
4351
|
if (tied > 0 || synthetic > 0) {
|
|
4288
4352
|
out.push(`Message order may not be chronological: ${tied} of ${total} messages share a timestamp with another message (ordered by id, not time)${synthetic > 0 ? ` and ${synthetic} carry a synthetic pre-2022 timestamp` : ""}.`);
|
|
4289
4353
|
}
|
|
4290
|
-
if (legacy && returned.some(isTruncated)) {
|
|
4291
|
-
out.push(`This Moda server is older and truncates message text, tool-call inputs and tool results longer than ${CONTEXT_MESSAGE_TRUNCATE_CHARS} characters. For full content (prompts, tool arguments/results) use \`moda traces spans <conversation_id> --include-bodies\` (or \`--include-raw\` for the verbatim events).`);
|
|
4292
|
-
}
|
|
4293
4354
|
return {
|
|
4294
|
-
data:
|
|
4295
|
-
conversation_id: conversationId,
|
|
4355
|
+
data: {
|
|
4356
|
+
conversation_id: stripLoneSurrogates(conversationId),
|
|
4296
4357
|
total_messages: total,
|
|
4297
4358
|
from: start,
|
|
4298
4359
|
returned: returned.length,
|
|
@@ -4301,7 +4362,7 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4301
4362
|
summary,
|
|
4302
4363
|
...ordering ? { ordering } : {},
|
|
4303
4364
|
messages: returned
|
|
4304
|
-
}
|
|
4365
|
+
},
|
|
4305
4366
|
warnings: out,
|
|
4306
4367
|
nextCommands
|
|
4307
4368
|
};
|
|
@@ -4309,18 +4370,10 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4309
4370
|
const full = build(messages.length);
|
|
4310
4371
|
if (!opts.fits || messages.length <= 1 || opts.fits(full))
|
|
4311
4372
|
return full;
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
while (low < high) {
|
|
4315
|
-
const mid = Math.ceil((low + high) / 2);
|
|
4316
|
-
if (opts.fits(build(mid)))
|
|
4317
|
-
low = mid;
|
|
4318
|
-
else
|
|
4319
|
-
high = mid - 1;
|
|
4320
|
-
}
|
|
4321
|
-
return build(low);
|
|
4373
|
+
const fits = opts.fits;
|
|
4374
|
+
return build(largestFittingCount(messages.length - 1, (kept) => fits(build(kept))));
|
|
4322
4375
|
}
|
|
4323
|
-
async function readContextItem(
|
|
4376
|
+
async function readContextItem(params, inputWarnings, budget) {
|
|
4324
4377
|
const fits = budget?.fits;
|
|
4325
4378
|
if (params.all === true) {
|
|
4326
4379
|
const full = await readFullTranscript(params.conversation_id, {
|
|
@@ -4429,17 +4482,10 @@ function trimContextWindow(conversationId, record, requestedAnchor, fits) {
|
|
|
4429
4482
|
};
|
|
4430
4483
|
return { data, warnings, nextCommands };
|
|
4431
4484
|
};
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
const page = build(mid);
|
|
4437
|
-
if (fits(page.data, page.warnings, page.nextCommands))
|
|
4438
|
-
low = mid;
|
|
4439
|
-
else
|
|
4440
|
-
high = mid - 1;
|
|
4441
|
-
}
|
|
4442
|
-
return build(low);
|
|
4485
|
+
return build(largestFittingCount(order.length, (kept) => {
|
|
4486
|
+
const page = build(kept);
|
|
4487
|
+
return fits(page.data, page.warnings, page.nextCommands);
|
|
4488
|
+
}));
|
|
4443
4489
|
}
|
|
4444
4490
|
var AUDIT_USAGE = "Usage: moda traces spans <conversation_id|trace_id> [--kind=auto|trace|conversation] [--include-raw] [--include-bodies] [--limit=N] [--cursor=<next_cursor>]";
|
|
4445
4491
|
var AUDIT_BATCH_USAGE = `Usage: moda traces spans <id> <id> ... | --ids-from=-|<file> [--kind=auto|trace|conversation] [--include-raw] [--include-bodies] [--limit=N] (max ${BATCH_MAX_TARGETS} targets)`;
|
|
@@ -4465,16 +4511,10 @@ async function readAuditItem(command, params, budget) {
|
|
|
4465
4511
|
const available = (Array.isArray(spans) ? spans.length : 0) - (params.span_offset ?? 0);
|
|
4466
4512
|
if (available <= 0)
|
|
4467
4513
|
return whole;
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
const page2 = auditOutput(command, params, raw, mid);
|
|
4473
|
-
if (budget.fits(page2.data, page2.options))
|
|
4474
|
-
low = mid;
|
|
4475
|
-
else
|
|
4476
|
-
high = mid - 1;
|
|
4477
|
-
}
|
|
4514
|
+
const low = largestFittingCount(available, (keep) => {
|
|
4515
|
+
const page2 = auditOutput(command, params, raw, keep);
|
|
4516
|
+
return budget.fits(page2.data, page2.options);
|
|
4517
|
+
});
|
|
4478
4518
|
const page = auditOutput(command, params, raw, low);
|
|
4479
4519
|
if (low === 1 && !budget.fits(page.data, page.options)) {
|
|
4480
4520
|
page.options.warnings = [
|
|
@@ -4557,7 +4597,7 @@ async function readBatchTargets(targets, agentMode, read) {
|
|
|
4557
4597
|
});
|
|
4558
4598
|
}
|
|
4559
4599
|
function fitsShare(share) {
|
|
4560
|
-
return (data, options) =>
|
|
4600
|
+
return (data, options) => jsonByteLength({ data, ...options }) <= share;
|
|
4561
4601
|
}
|
|
4562
4602
|
function isBatchFatal(error) {
|
|
4563
4603
|
const type = classifyCliError(error);
|
|
@@ -4672,7 +4712,7 @@ async function runContextBatch(command, positionals, flags, context) {
|
|
|
4672
4712
|
conversation_id: target.id,
|
|
4673
4713
|
...target.msgIndex !== undefined ? { msg_index: target.msgIndex } : {}
|
|
4674
4714
|
};
|
|
4675
|
-
return withAnchorHint(target, () => readContextItem(
|
|
4715
|
+
return withAnchorHint(target, () => readContextItem(params, [], budget));
|
|
4676
4716
|
});
|
|
4677
4717
|
return writeBatchResult(command, context, targets, results, inputWarnings, rest);
|
|
4678
4718
|
}
|
|
@@ -4879,16 +4919,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
4879
4919
|
return agentEnvelopeFits(command, page2.data, page2.options);
|
|
4880
4920
|
};
|
|
4881
4921
|
if (agentMode && kept > 1 && !fitsAgent(kept)) {
|
|
4882
|
-
|
|
4883
|
-
let high = kept - 1;
|
|
4884
|
-
while (low < high) {
|
|
4885
|
-
const mid = Math.ceil((low + high) / 2);
|
|
4886
|
-
if (fitsAgent(mid))
|
|
4887
|
-
low = mid;
|
|
4888
|
-
else
|
|
4889
|
-
high = mid - 1;
|
|
4890
|
-
}
|
|
4891
|
-
kept = low;
|
|
4922
|
+
kept = largestFittingCount(kept - 1, fitsAgent);
|
|
4892
4923
|
}
|
|
4893
4924
|
const page = write(kept);
|
|
4894
4925
|
recordSearchTelemetry(context, page.data);
|
|
@@ -4950,7 +4981,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
4950
4981
|
return runContextBatch(command, positionals, flags, context);
|
|
4951
4982
|
const { params, warnings: inputWarnings } = parseContextRequest(...singleContextTarget(positional, flags));
|
|
4952
4983
|
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
4953
|
-
const read = () => readContextItem(
|
|
4984
|
+
const read = () => readContextItem(params, inputWarnings, agentMode ? { fits: (data, options) => agentEnvelopeFits(command, data, options), maxBytes: agentMaxOutputBytes() } : undefined);
|
|
4954
4985
|
const item = positional === undefined ? await read() : await withAnchorHint(parseBatchTarget(positional, true, CONTEXT_USAGE), read);
|
|
4955
4986
|
context.output.writeData(item.data, item.options);
|
|
4956
4987
|
break;
|
|
@@ -5239,10 +5270,10 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5239
5270
|
});
|
|
5240
5271
|
const link = asRecord(data)?.link;
|
|
5241
5272
|
const summary = describeLinearLink(link);
|
|
5242
|
-
const nextCommands = link ? [] : [`moda problems link ${positional}`];
|
|
5273
|
+
const nextCommands = link ? [] : [`moda problems link ${shellArg(positional)}`];
|
|
5243
5274
|
if (context.outputMode === "human" && !context.quiet) {
|
|
5244
5275
|
safeWriteStderr(link ? `${summary}
|
|
5245
|
-
` : `${summary} File one with: moda problems link ${positional}
|
|
5276
|
+
` : `${summary} File one with: moda problems link ${shellArg(positional)}
|
|
5246
5277
|
`);
|
|
5247
5278
|
}
|
|
5248
5279
|
context.output.writeData(data, { summary, nextCommands });
|
|
@@ -5663,7 +5694,6 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5663
5694
|
function telemetryCommandName(definition) {
|
|
5664
5695
|
return definition.telemetryCommand ?? definition.name;
|
|
5665
5696
|
}
|
|
5666
|
-
var TELEMETRY_EXEMPT_COMMANDS = {};
|
|
5667
5697
|
function telemetrySubcommandNames(definition) {
|
|
5668
5698
|
return [
|
|
5669
5699
|
...definition.subcommands?.map((subcommand) => subcommand.name) ?? [],
|
|
@@ -5796,7 +5826,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
5796
5826
|
resetApiRequestCountBeforeRun: true,
|
|
5797
5827
|
telemetry: "result-and-error",
|
|
5798
5828
|
handler: async (context) => {
|
|
5799
|
-
const { runInit } = await import("./index-
|
|
5829
|
+
const { runInit } = await import("./index-d1z50dsq.js");
|
|
5800
5830
|
if (context.outputMode === "agent-stream") {
|
|
5801
5831
|
context.output.writeEvent({
|
|
5802
5832
|
event: "started",
|
|
@@ -5846,7 +5876,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
5846
5876
|
resetApiRequestCountBeforeRun: true,
|
|
5847
5877
|
telemetry: "result-and-error",
|
|
5848
5878
|
handler: async (context) => {
|
|
5849
|
-
const { runProvision } = await import("./provision-
|
|
5879
|
+
const { runProvision } = await import("./provision-y5bdbh4y.js");
|
|
5850
5880
|
return runProvision(context, {
|
|
5851
5881
|
resumeCommand: buildResumeCommand("provision", context.rawFlags)
|
|
5852
5882
|
});
|
|
@@ -6923,6 +6953,46 @@ function printAgentCliError(command, error, mode = "agent") {
|
|
|
6923
6953
|
});
|
|
6924
6954
|
output.writeError(error);
|
|
6925
6955
|
}
|
|
6956
|
+
function flagNamesInLabel(label) {
|
|
6957
|
+
return [...label.matchAll(/--([A-Za-z0-9][A-Za-z0-9-]*)/g)].map((match) => match[1]);
|
|
6958
|
+
}
|
|
6959
|
+
function specFlagNamesDeep(spec) {
|
|
6960
|
+
if (!spec)
|
|
6961
|
+
return [];
|
|
6962
|
+
return [...specFlagNames(spec), ...Object.values(spec.subcommands ?? {}).flatMap((sub) => specFlagNames(sub))];
|
|
6963
|
+
}
|
|
6964
|
+
function telemetryAcceptedFlags(definition, route) {
|
|
6965
|
+
const names = new Set([...GLOBAL_FLAG_NAMES, ...GLOBAL_BOOLEAN_FLAGS]);
|
|
6966
|
+
const add = (list) => {
|
|
6967
|
+
for (const name of list)
|
|
6968
|
+
names.add(name);
|
|
6969
|
+
};
|
|
6970
|
+
if (definition) {
|
|
6971
|
+
add(specFlagNamesDeep(flagSpecFor(definition.name)));
|
|
6972
|
+
for (const flag of definition.documentedFlags ?? [])
|
|
6973
|
+
add(flagNamesInLabel(flag.name));
|
|
6974
|
+
for (const sub of definition.subcommands ?? [])
|
|
6975
|
+
for (const flag of sub.flags ?? [])
|
|
6976
|
+
add(flagNamesInLabel(flag.name));
|
|
6977
|
+
}
|
|
6978
|
+
if (route) {
|
|
6979
|
+
add(route.allowedFlags ?? []);
|
|
6980
|
+
add(Object.keys(route.flagAliases ?? {}));
|
|
6981
|
+
add(specFlagNamesDeep(leafFlagSpec(route.leaf)));
|
|
6982
|
+
}
|
|
6983
|
+
return names;
|
|
6984
|
+
}
|
|
6985
|
+
var knownFlagNames;
|
|
6986
|
+
function telemetryKnownFlags() {
|
|
6987
|
+
if (!knownFlagNames) {
|
|
6988
|
+
knownFlagNames = new Set(RAW_BOOLEAN_FLAGS);
|
|
6989
|
+
for (const definition of commandRegistry.all()) {
|
|
6990
|
+
for (const name of telemetryAcceptedFlags(definition, undefined))
|
|
6991
|
+
knownFlagNames.add(name);
|
|
6992
|
+
}
|
|
6993
|
+
}
|
|
6994
|
+
return knownFlagNames;
|
|
6995
|
+
}
|
|
6926
6996
|
function existingFlagProfile(flags) {
|
|
6927
6997
|
const name = flags.profile;
|
|
6928
6998
|
if (!name || name === "true")
|
|
@@ -7095,6 +7165,8 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
|
|
|
7095
7165
|
if (!handlerTelemetry)
|
|
7096
7166
|
return;
|
|
7097
7167
|
const telemetryProfile = existingFlagProfile(typedFlags);
|
|
7168
|
+
if (typedFlags.profile !== undefined && telemetryProfile === undefined)
|
|
7169
|
+
return;
|
|
7098
7170
|
const adoption = buildSearchAdoptionTelemetry({
|
|
7099
7171
|
command: handlerTelemetry,
|
|
7100
7172
|
positional: parsed.positional,
|
|
@@ -7122,12 +7194,14 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
|
|
|
7122
7194
|
durationMs: Date.now() - startedAt,
|
|
7123
7195
|
apiRequestCount: input.apiRequestCount,
|
|
7124
7196
|
adoption,
|
|
7125
|
-
...identity2?.legacyAlias ? { legacyAlias: identity2.legacyAlias } : {}
|
|
7197
|
+
...identity2?.legacyAlias ? { legacyAlias: identity2.legacyAlias } : {},
|
|
7198
|
+
acceptedFlags: telemetryAcceptedFlags(definition2, route),
|
|
7199
|
+
knownFlags: telemetryKnownFlags()
|
|
7126
7200
|
});
|
|
7127
7201
|
};
|
|
7128
7202
|
const failEarly = (error, commandDefinition, identity2) => {
|
|
7129
7203
|
const mode = outputModeFor();
|
|
7130
|
-
const telemetryOptOut = telemetryDisabled || flags
|
|
7204
|
+
const telemetryOptOut = telemetryDisabled || optOutFlagSet(flags, "no-telemetry", false);
|
|
7131
7205
|
const reports = commandDefinition ? commandDefinition.telemetry === "result-and-error" : identity2 !== undefined;
|
|
7132
7206
|
if (reports && !telemetryOptOut) {
|
|
7133
7207
|
reportUsage({
|
|
@@ -7179,7 +7253,7 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
|
|
|
7179
7253
|
const known = Object.keys(loadProfileConfig({ env: process.env }).profiles);
|
|
7180
7254
|
if (!known.includes(requestedProfile)) {
|
|
7181
7255
|
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);
|
|
7256
|
+
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
7257
|
}
|
|
7184
7258
|
if (commandFlags.profile)
|
|
7185
7259
|
process.env.MODA_PROFILE = commandFlags.profile;
|
|
@@ -7188,7 +7262,7 @@ async function dispatchParsedCommandInner(typedParsed, startedAt) {
|
|
|
7188
7262
|
commandFlags.agent = "true";
|
|
7189
7263
|
}
|
|
7190
7264
|
if (!updateCheckDisabled) {
|
|
7191
|
-
startUpdateCheck();
|
|
7265
|
+
startUpdateCheck({}, Date.now(), { detached: outputModeFor() !== "human" });
|
|
7192
7266
|
setAgentUpdateNotice(() => {
|
|
7193
7267
|
const latest = getAvailableUpdate();
|
|
7194
7268
|
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;
|
|
@@ -7331,7 +7405,6 @@ export {
|
|
|
7331
7405
|
trimContextWindow,
|
|
7332
7406
|
telemetrySubcommandNames,
|
|
7333
7407
|
telemetryCommandName,
|
|
7334
|
-
stripLoneSurrogates,
|
|
7335
7408
|
searchOutcomeWarnings,
|
|
7336
7409
|
searchDegradeWarning,
|
|
7337
7410
|
searchCoverageWarnings,
|
|
@@ -7342,6 +7415,7 @@ export {
|
|
|
7342
7415
|
parseCommandFlags,
|
|
7343
7416
|
parseArgs,
|
|
7344
7417
|
normalizeBooleanFlags,
|
|
7418
|
+
largestFittingCount,
|
|
7345
7419
|
initFlagsForContext,
|
|
7346
7420
|
globalFlagHelpLines,
|
|
7347
7421
|
flagsToArgs,
|
|
@@ -7358,10 +7432,8 @@ export {
|
|
|
7358
7432
|
canonicalFlagKey,
|
|
7359
7433
|
buildResumeCommand,
|
|
7360
7434
|
auditCapStatus,
|
|
7361
|
-
TELEMETRY_EXEMPT_COMMANDS,
|
|
7362
7435
|
TAIL_LIMITS,
|
|
7363
7436
|
RAW_BOOLEAN_FLAGS,
|
|
7364
|
-
LEGACY_WINDOW_MAX_MESSAGES,
|
|
7365
7437
|
FULL_TRANSCRIPT_DEFAULT_MAX_MESSAGES,
|
|
7366
7438
|
CliInputError,
|
|
7367
7439
|
CONTEXT_MAX_WINDOW,
|