@moda-ai/cli 1.55.25 → 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-t7dxmpdq.js → agent-vp9prdma.js} +8 -8
- package/dist/{cli-qycsmxev.js → cli-0pkc8jhg.js} +3 -3
- package/dist/{cli-mebf5vtr.js → cli-4h0ave0f.js} +5 -5
- package/dist/{cli-m0045npe.js → cli-6et4z504.js} +10 -8
- package/dist/{cli-9hc5bg2r.js → cli-ccjfwzqx.js} +1 -1
- package/dist/{cli-0wr3483h.js → cli-hmjdgxrn.js} +1 -1
- package/dist/{cli-9btx12wp.js → cli-pg5qfmqc.js} +1 -1
- package/dist/{cli-m805msp6.js → cli-q9nsvqqg.js} +14 -14
- package/dist/{cli-7xc585hc.js → cli-qwgct6x7.js} +7 -6
- package/dist/{cli-dve50x7p.js → cli-r5pp7qny.js} +140 -455
- package/dist/{cli-qvg26twp.js → cli-v8q7sd7g.js} +38 -13
- package/dist/cli-vdkwkkp5.js +567 -0
- package/dist/{cli-dn91fb56.js → cli-wzds257x.js} +92 -49
- package/dist/cli.js +986 -362
- package/dist/{doctor-q21mr5ya.js → doctor-wmre3mr7.js} +8 -8
- package/dist/{fix-0qdtdz5h.js → fix-75s9s0d6.js} +45 -47
- package/dist/{harness-vzy7n7ea.js → harness-a7tb9a23.js} +5 -5
- package/dist/{harness-github-actions-atc5bbkj.js → harness-github-actions-6v4wydb8.js} +5 -5
- package/dist/{index-4b1ybz51.js → index-91bpc8g8.js} +15 -14
- package/dist/{production-intelligence-c8e0xw3n.js → production-intelligence-7nqddd4f.js} +88 -28
- package/dist/{profile-commands-6e2dgv72.js → profile-commands-49yn02yg.js} +5 -4
- package/dist/prompt-source-mcp.js +5 -5
- package/dist/{prompts-3h5jcjrw.js → prompts-17wyrst6.js} +6 -6
- package/dist/{provision-q86phh4a.js → provision-bc3h68e1.js} +5 -5
- package/dist/{registry-s2vdsfw8.js → registry-fpzhjznj.js} +3 -3
- package/dist/{skills-vq3njc8a.js → skills-ccdbqghj.js} +5 -5
- package/dist/{sync-hq9dpqpr.js → sync-hkxce5zh.js} +7 -7
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +4 -1
- package/skills/moda-cli/references/dashboard-parity.md +1 -1
- package/skills/moda-cli/references/output-protocol.md +35 -10
- package/skills/moda-cli/references/search-and-traces.md +20 -2
- package/dist/cli-bb7133m7.js +0 -144
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
INTELLIGENCE_SCHEMA_VERSION
|
|
3
|
-
|
|
2
|
+
INTELLIGENCE_SCHEMA_VERSION,
|
|
3
|
+
asNumber,
|
|
4
|
+
asRecord,
|
|
5
|
+
asString,
|
|
6
|
+
contextTarget,
|
|
7
|
+
frustrationAnchorIndex,
|
|
8
|
+
frustrationsFromEmotions
|
|
9
|
+
} from "./cli-vdkwkkp5.js";
|
|
4
10
|
import {
|
|
5
11
|
renderMarkdownForTerminal,
|
|
6
12
|
shouldColorTerminalOutput,
|
|
@@ -10,25 +16,20 @@ import {
|
|
|
10
16
|
import {
|
|
11
17
|
callControlAPI,
|
|
12
18
|
callDataAPI
|
|
13
|
-
} from "./cli-
|
|
19
|
+
} from "./cli-pg5qfmqc.js";
|
|
14
20
|
import {
|
|
15
21
|
CliAuthError,
|
|
16
22
|
CliInputError,
|
|
17
23
|
EXIT_DEGRADED,
|
|
18
24
|
EXIT_OK,
|
|
25
|
+
apiErrorStatus,
|
|
19
26
|
apiKeyHeaders,
|
|
20
|
-
asNumber,
|
|
21
|
-
asRecord,
|
|
22
|
-
asString,
|
|
23
|
-
contextTarget,
|
|
24
|
-
frustrationAnchorIndex,
|
|
25
|
-
frustrationsFromEmotions,
|
|
26
27
|
recordApiRequest,
|
|
27
28
|
resolveApiKey,
|
|
28
29
|
resolveModaBaseUrl,
|
|
29
30
|
safeWriteStderr,
|
|
30
|
-
|
|
31
|
-
} from "./cli-
|
|
31
|
+
shellArg
|
|
32
|
+
} from "./cli-r5pp7qny.js";
|
|
32
33
|
import"./cli-0v6na3yp.js";
|
|
33
34
|
|
|
34
35
|
// src/production-intelligence.ts
|
|
@@ -406,6 +407,9 @@ var OVERVIEW_SCHEMA_VERSION = "production_overview.v0.1";
|
|
|
406
407
|
var ASK_SCHEMA_VERSION = "production_ask.v0.1";
|
|
407
408
|
var INVESTIGATION_PROBLEM_LIMIT = 3;
|
|
408
409
|
var INVESTIGATION_PROBLEM_SLOTS = INVESTIGATION_PROBLEM_LIMIT;
|
|
410
|
+
function isAuthFailure(error) {
|
|
411
|
+
return error instanceof CliAuthError || apiErrorStatus(error) === 401;
|
|
412
|
+
}
|
|
409
413
|
async function runProductionCommand(context) {
|
|
410
414
|
const daysBack = daysBackFlag(context.flags);
|
|
411
415
|
if (context.command === "overview") {
|
|
@@ -419,7 +423,8 @@ async function runProductionCommand(context) {
|
|
|
419
423
|
if (!context.quiet)
|
|
420
424
|
console.log(renderOverviewBriefingHuman(briefing));
|
|
421
425
|
} else {
|
|
422
|
-
|
|
426
|
+
const { rawOverview: _rawOverview, ...withoutRaw } = briefing;
|
|
427
|
+
context.output.writeData(withoutRaw, overviewAgentOptions(briefing));
|
|
423
428
|
}
|
|
424
429
|
return { exitCode: 0 };
|
|
425
430
|
}
|
|
@@ -448,7 +453,7 @@ async function runProductionCommand(context) {
|
|
|
448
453
|
toolName: context.flags.tool
|
|
449
454
|
});
|
|
450
455
|
writeInvestigation(context, investigation);
|
|
451
|
-
return { exitCode:
|
|
456
|
+
return { exitCode: investigation.degraded ? EXIT_DEGRADED : EXIT_OK };
|
|
452
457
|
}
|
|
453
458
|
if (context.command === "investigate") {
|
|
454
459
|
const investigation = await investigateProduction({
|
|
@@ -458,7 +463,7 @@ async function runProductionCommand(context) {
|
|
|
458
463
|
toolName: context.flags.tool
|
|
459
464
|
});
|
|
460
465
|
writeInvestigation(context, investigation);
|
|
461
|
-
return { exitCode:
|
|
466
|
+
return { exitCode: investigation.degraded ? EXIT_DEGRADED : EXIT_OK };
|
|
462
467
|
}
|
|
463
468
|
throw new CliInputError(`Unknown production command '${context.command}'`);
|
|
464
469
|
}
|
|
@@ -522,11 +527,18 @@ async function investigateProduction(options) {
|
|
|
522
527
|
if (result.warning)
|
|
523
528
|
warnings.push(result.warning);
|
|
524
529
|
}
|
|
530
|
+
const failed = Object.entries(sources).filter(([, result]) => result.status === "unavailable");
|
|
531
|
+
const authFailure = failed.find(([, result]) => isAuthFailure(result.error));
|
|
532
|
+
if (authFailure)
|
|
533
|
+
throw authFailure[1].error;
|
|
534
|
+
if (failed.length > 0 && failed.length === Object.keys(sources).length)
|
|
535
|
+
throw failed[0][1].error;
|
|
536
|
+
const failedSources = failed.map(([key]) => key);
|
|
525
537
|
if (options.toolName && tools.status === "ok" && toolRows(tools.data, options.toolName).every((row) => row.count <= 0)) {
|
|
526
538
|
warnings.push(`No failures found for tool "${options.toolName}" in the last ${options.daysBack} day(s) — the tool may have no failures in this window, or the name may not exist in this tenant. ` + "Run `moda detections tools` to list tools with recorded failures, or widen --days-back.");
|
|
527
539
|
}
|
|
528
540
|
if (options.conversationId) {
|
|
529
|
-
warnings.push(`Scoped to trace ${options.conversationId} for frustration evidence only; overview and tool failures are tenant-wide. ` + `Open the trace itself with \`moda traces spans ${options.conversationId}\`.`);
|
|
541
|
+
warnings.push(`Scoped to trace ${options.conversationId} for frustration evidence only; overview and tool failures are tenant-wide. ` + `Open the trace itself with \`moda traces spans ${shellArg(options.conversationId)}\`.`);
|
|
530
542
|
}
|
|
531
543
|
const evidenceRefs = [];
|
|
532
544
|
const findings = [];
|
|
@@ -537,12 +549,17 @@ async function investigateProduction(options) {
|
|
|
537
549
|
findings.push(...problemFindings(problems.data, options.daysBack, evidenceRefs));
|
|
538
550
|
}
|
|
539
551
|
if (findings.length === 0) {
|
|
540
|
-
findings.push(insufficientDataFinding(overview.data, evidenceRefs));
|
|
552
|
+
findings.push(failedSources.length > 0 ? incompleteDataFinding(failedSources, Object.keys(sources).length) : insufficientDataFinding(overview.data, evidenceRefs));
|
|
541
553
|
}
|
|
542
554
|
findings.sort(compareFindings);
|
|
543
555
|
const boundedFindings = capFindings(findings, 8, INVESTIGATION_PROBLEM_SLOTS);
|
|
544
556
|
const nextCommands = nextCommandsForFindings(boundedFindings, options.daysBack, !options.failureOnly);
|
|
545
557
|
const summary = summarizeInvestigation(boundedFindings);
|
|
558
|
+
if (failedSources.length > 0) {
|
|
559
|
+
summary.text = `Incomplete: could not load ${failedSources.join(", ")}, so findings cover only ${Object.keys(sources).filter((key) => !failedSources.includes(key)).join(", ")}. ${summary.text}`;
|
|
560
|
+
if (summary.confidence === "high" || summary.confidence === "medium")
|
|
561
|
+
summary.confidence = "low";
|
|
562
|
+
}
|
|
546
563
|
if (options.conversationId) {
|
|
547
564
|
summary.text = `${summary.text} (Only frustration evidence is scoped to trace ${options.conversationId}.)`;
|
|
548
565
|
}
|
|
@@ -560,7 +577,9 @@ async function investigateProduction(options) {
|
|
|
560
577
|
evidenceRefs: uniqueEvidenceRefs(evidenceRefs),
|
|
561
578
|
nextCommands,
|
|
562
579
|
warnings,
|
|
563
|
-
sourceStatus
|
|
580
|
+
sourceStatus,
|
|
581
|
+
degraded: failedSources.length > 0,
|
|
582
|
+
failedSources
|
|
564
583
|
};
|
|
565
584
|
}
|
|
566
585
|
async function askModa(options) {
|
|
@@ -592,8 +611,8 @@ async function askModa(options) {
|
|
|
592
611
|
cwd: options.cwd,
|
|
593
612
|
question: options.question
|
|
594
613
|
});
|
|
595
|
-
const top = investigation.findings
|
|
596
|
-
const answer = top ? `Moda Cloud intelligence is not available, so I synthesized this from production evidence. The strongest signal is: ${top.title}. ${top.summary}` : "Moda Cloud intelligence is not available, and the local Data API evidence did not contain a strong production signal.";
|
|
614
|
+
const top = investigation.findings.find((finding) => finding.kind !== "insufficient_data");
|
|
615
|
+
const answer = top ? `Moda Cloud intelligence is not available, so I synthesized this from production evidence${investigation.degraded ? ` (${investigation.failedSources.join(", ")} could not be loaded)` : ""}. The strongest signal is: ${top.title}. ${top.summary}` : investigation.degraded ? `Moda Cloud intelligence is not available, and ${investigation.failedSources.join(", ")} could not be loaded, so no answer could be synthesized and no issue is ruled out.` : "Moda Cloud intelligence is not available, and the local Data API evidence did not contain a strong production signal.";
|
|
597
616
|
const confidence = capFallbackConfidence(investigation.summary.confidence);
|
|
598
617
|
const evidenceRefs = investigation.evidenceRefs.slice(0, 12);
|
|
599
618
|
const findings = investigation.findings.slice(0, 5);
|
|
@@ -717,9 +736,16 @@ function writeInvestigation(context, investigation) {
|
|
|
717
736
|
if (context.outputMode === "human") {
|
|
718
737
|
if (!context.quiet)
|
|
719
738
|
console.log(renderInvestigationHuman(investigation));
|
|
739
|
+
if (investigation.degraded) {
|
|
740
|
+
safeWriteStderr(`Warning: incomplete result, could not load ${investigation.failedSources.join(", ")}.
|
|
741
|
+
`);
|
|
742
|
+
}
|
|
720
743
|
return;
|
|
721
744
|
}
|
|
722
|
-
context.output.writeData(investigation,
|
|
745
|
+
context.output.writeData(investigation, {
|
|
746
|
+
...investigationAgentOptions(investigation),
|
|
747
|
+
...investigation.degraded ? { status: "degraded" } : {}
|
|
748
|
+
});
|
|
723
749
|
}
|
|
724
750
|
async function safeData(endpoint) {
|
|
725
751
|
try {
|
|
@@ -728,7 +754,8 @@ async function safeData(endpoint) {
|
|
|
728
754
|
return {
|
|
729
755
|
data: null,
|
|
730
756
|
status: "unavailable",
|
|
731
|
-
warning: `Could not load ${endpoint}: ${error instanceof Error ? error.message : String(error)}
|
|
757
|
+
warning: `Could not load ${endpoint}: ${error instanceof Error ? error.message : String(error)}`,
|
|
758
|
+
error
|
|
732
759
|
};
|
|
733
760
|
}
|
|
734
761
|
}
|
|
@@ -817,7 +844,7 @@ function toolFailureFindings(data, daysBack, hints, evidenceRefs, scopedTool) {
|
|
|
817
844
|
label: `${name}: ${count} failure(s)${subtype}`,
|
|
818
845
|
endpoint: scopedTool ? `/tool-failures/${encodeURIComponent(name)}?days_back=${daysBack}` : `/tool-failures?days_back=${daysBack}`,
|
|
819
846
|
toolName: name,
|
|
820
|
-
value: tool.
|
|
847
|
+
value: { tool_name: name, failure_count: count, conversation_count: tool.conversations, ...tool.subtype ? { subtype: tool.subtype } : {} }
|
|
821
848
|
});
|
|
822
849
|
const location = likelyToolLocation(name, hints);
|
|
823
850
|
if (location?.path) {
|
|
@@ -845,7 +872,7 @@ function toolFailureFindings(data, daysBack, hints, evidenceRefs, scopedTool) {
|
|
|
845
872
|
id: `action_tool_detail_${slug(name)}`,
|
|
846
873
|
title: `Inspect ${name} failure examples.`,
|
|
847
874
|
rationale: "Examples include trace anchors and error subtypes.",
|
|
848
|
-
command: `moda detections tools ${name} --days-back=${daysBack} --include-window`,
|
|
875
|
+
command: `moda detections tools ${shellArg(name)} --days-back=${daysBack} --include-window`,
|
|
849
876
|
mutability: "read",
|
|
850
877
|
requiresApproval: false
|
|
851
878
|
}]
|
|
@@ -874,7 +901,7 @@ function frustrationFindings(data, daysBack, evidenceRefs) {
|
|
|
874
901
|
label: quote ? `Frustration anchor: "${quote}"` : `${count} frustrated trace(s)`,
|
|
875
902
|
endpoint: investigateFrustrationsEndpoint(daysBack),
|
|
876
903
|
...conversationId ? { conversationId } : {},
|
|
877
|
-
value: first
|
|
904
|
+
value: first ? frustrationEvidenceIds(first, anchorIndex) : { frustrated_count: count, at_risk_count: atRisk }
|
|
878
905
|
});
|
|
879
906
|
return [{
|
|
880
907
|
id: "finding_frustration_rate",
|
|
@@ -891,12 +918,23 @@ function frustrationFindings(data, daysBack, evidenceRefs) {
|
|
|
891
918
|
id: "action_frustration_window",
|
|
892
919
|
title: "Read the frustration window.",
|
|
893
920
|
rationale: "The user quote and nearby turns reveal what confused or blocked the user.",
|
|
894
|
-
command: conversationId ? `moda traces get ${
|
|
921
|
+
command: conversationId ? `moda traces get ${shellArg(contextTarget(conversationId))}${anchorIndex !== null ? ` --msg-index=${anchorIndex}` : ""} --window=3` : `moda detections list --family=frustration --days-back=${daysBack} --include-window`,
|
|
895
922
|
mutability: "read",
|
|
896
923
|
requiresApproval: false
|
|
897
924
|
}]
|
|
898
925
|
}];
|
|
899
926
|
}
|
|
927
|
+
function frustrationEvidenceIds(row, anchorIndex) {
|
|
928
|
+
const ids = {};
|
|
929
|
+
for (const key of ["detection_id", "conversation_id", "trace_id", "user_id"]) {
|
|
930
|
+
const value = asString(row[key]);
|
|
931
|
+
if (value)
|
|
932
|
+
ids[key] = value;
|
|
933
|
+
}
|
|
934
|
+
if (anchorIndex !== null)
|
|
935
|
+
ids.msg_index = anchorIndex;
|
|
936
|
+
return ids;
|
|
937
|
+
}
|
|
900
938
|
function problemRows(data) {
|
|
901
939
|
const record = asRecord(data);
|
|
902
940
|
const rows = [];
|
|
@@ -938,7 +976,7 @@ function problemFindings(data, daysBack, evidenceRefs) {
|
|
|
938
976
|
kind: "problem",
|
|
939
977
|
label: `Problem "${problem.name}" (${trustNote})`,
|
|
940
978
|
endpoint: `/problems?days_back=${daysBack}&limit=${INVESTIGATION_PROBLEM_LIMIT}`,
|
|
941
|
-
value: problem.
|
|
979
|
+
value: { problem_id: problem.id, lifecycle: problem.lifecycle, trust: problem.trust, affected_conversations: problem.affectedConversations }
|
|
942
980
|
});
|
|
943
981
|
const affected = problem.affectedConversations;
|
|
944
982
|
return {
|
|
@@ -956,7 +994,7 @@ function problemFindings(data, daysBack, evidenceRefs) {
|
|
|
956
994
|
id: `action_problem_${slug(problem.id)}`,
|
|
957
995
|
title: `Open the Problem dossier for ${problem.name}.`,
|
|
958
996
|
rationale: "The dossier has the cause, evidence, affected traces and verification state.",
|
|
959
|
-
command: `moda problems get ${problem.id}`,
|
|
997
|
+
command: `moda problems get ${shellArg(problem.id)}`,
|
|
960
998
|
mutability: "read",
|
|
961
999
|
requiresApproval: false
|
|
962
1000
|
}]
|
|
@@ -971,7 +1009,7 @@ function insufficientDataFinding(overview, evidenceRefs) {
|
|
|
971
1009
|
kind: "data_api",
|
|
972
1010
|
label: "Overview did not contain actionable production signals",
|
|
973
1011
|
endpoint: "/overview",
|
|
974
|
-
value: overview
|
|
1012
|
+
value: overviewMetrics(overview)
|
|
975
1013
|
});
|
|
976
1014
|
}
|
|
977
1015
|
return {
|
|
@@ -995,6 +1033,28 @@ function insufficientDataFinding(overview, evidenceRefs) {
|
|
|
995
1033
|
}]
|
|
996
1034
|
};
|
|
997
1035
|
}
|
|
1036
|
+
function incompleteDataFinding(failedSources, total) {
|
|
1037
|
+
return {
|
|
1038
|
+
id: "finding_incomplete_data",
|
|
1039
|
+
kind: "insufficient_data",
|
|
1040
|
+
title: `Could not check ${failedSources.join(", ")} (${failedSources.length} of ${total} sources failed)`,
|
|
1041
|
+
severity: "info",
|
|
1042
|
+
confidence: "low",
|
|
1043
|
+
impactScore: 10,
|
|
1044
|
+
rankReason: "The sources that loaded show no ranked issue, but the failed ones were not checked.",
|
|
1045
|
+
summary: "This is not evidence that production is healthy; re-run once the failed sources load (see warnings).",
|
|
1046
|
+
evidenceRefIds: [],
|
|
1047
|
+
likelyLocations: [],
|
|
1048
|
+
recommendedActions: [{
|
|
1049
|
+
id: "action_doctor_online",
|
|
1050
|
+
title: "Check connectivity and the API key.",
|
|
1051
|
+
rationale: "Failed reads usually mean a network, server, or credential problem.",
|
|
1052
|
+
command: "moda doctor --online",
|
|
1053
|
+
mutability: "read",
|
|
1054
|
+
requiresApproval: false
|
|
1055
|
+
}]
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
998
1058
|
function normalizeCloudAsk(response, question) {
|
|
999
1059
|
const record = asRecord(response);
|
|
1000
1060
|
const answer = asString(record?.answer);
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
probeApiKey,
|
|
3
3
|
redactApiKey,
|
|
4
4
|
resolveApiKeyCredential
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-ccjfwzqx.js";
|
|
6
6
|
import {
|
|
7
7
|
authFetch,
|
|
8
8
|
clearAuthSession,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadAuthSession,
|
|
11
11
|
login,
|
|
12
12
|
revokeCliSessionToken
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-hmjdgxrn.js";
|
|
14
14
|
import {
|
|
15
15
|
CliInputError,
|
|
16
16
|
DEFAULT_INGEST_URL,
|
|
@@ -34,8 +34,9 @@ import {
|
|
|
34
34
|
saveCliConfig,
|
|
35
35
|
secretFilePathFromRef,
|
|
36
36
|
setActiveProfile,
|
|
37
|
+
shellArg,
|
|
37
38
|
upsertProfile
|
|
38
|
-
} from "./cli-
|
|
39
|
+
} from "./cli-r5pp7qny.js";
|
|
39
40
|
import"./cli-0v6na3yp.js";
|
|
40
41
|
|
|
41
42
|
// src/profile-commands.ts
|
|
@@ -326,7 +327,7 @@ async function runProfilesCommand(context) {
|
|
|
326
327
|
default_profile: config.active_profile,
|
|
327
328
|
profiles: Object.values(config.profiles).map((profile) => serializeProfile(profile, effective)),
|
|
328
329
|
migrations: config.migrations
|
|
329
|
-
}, missing ? { warnings: [`The active profile '${effective}' (from ${source}) does not exist. Create it with \`moda profiles create ${effective}\` or select an existing profile.`] } : undefined);
|
|
330
|
+
}, missing ? { warnings: [`The active profile '${effective}' (from ${source}) does not exist. Create it with \`moda profiles create ${shellArg(effective)}\` or select an existing profile.`] } : undefined);
|
|
330
331
|
return { exitCode: 0 };
|
|
331
332
|
}
|
|
332
333
|
case "use": {
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
inspectCodeSelectors,
|
|
6
6
|
inspectPythonSelectors,
|
|
7
7
|
safePromptEvidencePath
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-qwgct6x7.js";
|
|
9
9
|
import"./cli-97fnztpy.js";
|
|
10
|
-
import"./cli-
|
|
11
|
-
import"./cli-
|
|
12
|
-
import"./cli-
|
|
13
|
-
import"./cli-
|
|
10
|
+
import"./cli-v8q7sd7g.js";
|
|
11
|
+
import"./cli-wzds257x.js";
|
|
12
|
+
import"./cli-pg5qfmqc.js";
|
|
13
|
+
import"./cli-r5pp7qny.js";
|
|
14
14
|
import {
|
|
15
15
|
__commonJS,
|
|
16
16
|
__toESM
|
|
@@ -11,16 +11,16 @@ import {
|
|
|
11
11
|
runPromptSync,
|
|
12
12
|
runPromptsCommand,
|
|
13
13
|
writePromptSyncProgress
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-q9nsvqqg.js";
|
|
15
15
|
import {
|
|
16
16
|
promptSourceHashPayload
|
|
17
17
|
} from "./cli-mm48br00.js";
|
|
18
|
-
import"./cli-
|
|
18
|
+
import"./cli-qwgct6x7.js";
|
|
19
19
|
import"./cli-97fnztpy.js";
|
|
20
|
-
import"./cli-
|
|
21
|
-
import"./cli-
|
|
22
|
-
import"./cli-
|
|
23
|
-
import"./cli-
|
|
20
|
+
import"./cli-v8q7sd7g.js";
|
|
21
|
+
import"./cli-wzds257x.js";
|
|
22
|
+
import"./cli-pg5qfmqc.js";
|
|
23
|
+
import"./cli-r5pp7qny.js";
|
|
24
24
|
import"./cli-0v6na3yp.js";
|
|
25
25
|
export {
|
|
26
26
|
writePromptSyncProgress,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
selectTenantAndCreateKey
|
|
3
|
-
} from "./cli-
|
|
4
|
-
import"./cli-
|
|
3
|
+
} from "./cli-0pkc8jhg.js";
|
|
4
|
+
import"./cli-ccjfwzqx.js";
|
|
5
5
|
import {
|
|
6
6
|
loadAuthSession
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-hmjdgxrn.js";
|
|
8
8
|
import {
|
|
9
9
|
stringOption
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-v8q7sd7g.js";
|
|
11
11
|
import {
|
|
12
12
|
CliAuthError,
|
|
13
13
|
resolveIngestUrl,
|
|
14
14
|
resolveModaBaseUrl
|
|
15
|
-
} from "./cli-
|
|
15
|
+
} from "./cli-r5pp7qny.js";
|
|
16
16
|
import"./cli-0v6na3yp.js";
|
|
17
17
|
|
|
18
18
|
// src/provision.ts
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
assertFlags
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-wzds257x.js";
|
|
4
4
|
import {
|
|
5
5
|
callControlAPI
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-pg5qfmqc.js";
|
|
7
7
|
import {
|
|
8
8
|
CliInputError,
|
|
9
9
|
explicitOutputMode,
|
|
10
10
|
resolveApiKey
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-r5pp7qny.js";
|
|
12
12
|
import"./cli-0v6na3yp.js";
|
|
13
13
|
|
|
14
14
|
// src/registry.ts
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
pullSkills,
|
|
4
4
|
runSkillSync,
|
|
5
5
|
runSkillsCommand
|
|
6
|
-
} from "./cli-
|
|
7
|
-
import"./cli-
|
|
8
|
-
import"./cli-
|
|
9
|
-
import"./cli-
|
|
10
|
-
import"./cli-
|
|
6
|
+
} from "./cli-6et4z504.js";
|
|
7
|
+
import"./cli-v8q7sd7g.js";
|
|
8
|
+
import"./cli-wzds257x.js";
|
|
9
|
+
import"./cli-pg5qfmqc.js";
|
|
10
|
+
import"./cli-r5pp7qny.js";
|
|
11
11
|
import"./cli-8dtnwp9r.js";
|
|
12
12
|
import"./cli-0v6na3yp.js";
|
|
13
13
|
export {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runPromptsCommand
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-q9nsvqqg.js";
|
|
4
4
|
import"./cli-mm48br00.js";
|
|
5
5
|
import {
|
|
6
6
|
runHarnessCommand
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-qwgct6x7.js";
|
|
8
8
|
import"./cli-97fnztpy.js";
|
|
9
9
|
import {
|
|
10
10
|
runSkillsCommand
|
|
11
|
-
} from "./cli-
|
|
12
|
-
import"./cli-
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
11
|
+
} from "./cli-6et4z504.js";
|
|
12
|
+
import"./cli-v8q7sd7g.js";
|
|
13
|
+
import"./cli-wzds257x.js";
|
|
14
|
+
import"./cli-pg5qfmqc.js";
|
|
15
15
|
import {
|
|
16
16
|
CliInputError
|
|
17
|
-
} from "./cli-
|
|
17
|
+
} from "./cli-r5pp7qny.js";
|
|
18
18
|
import"./cli-8dtnwp9r.js";
|
|
19
19
|
import"./cli-0v6na3yp.js";
|
|
20
20
|
|
package/package.json
CHANGED
package/skills/moda-cli/SKILL.md
CHANGED
|
@@ -95,7 +95,10 @@ More: `references/production-intelligence.md`.
|
|
|
95
95
|
indexes when you report.
|
|
96
96
|
- Never run writes (`problems feedback`, `review`,
|
|
97
97
|
`signals create|update|...`, `prompts sync|promote|ab`, `registry push`)
|
|
98
|
-
unless the user asked.
|
|
98
|
+
unless the user asked. Preview with `--dry-run` (every write except
|
|
99
|
+
`prompts promote|ab|propose` takes it): it validates and applies nothing.
|
|
100
|
+
Most writes print the exact request and a `next_commands` entry that runs
|
|
101
|
+
it for real (see `references/output-protocol.md`).
|
|
99
102
|
- An empty result in a window means "nothing in that window". Widen the window
|
|
100
103
|
once before saying something never happened.
|
|
101
104
|
- Batch reads instead of looping one id per call: `moda traces get` and
|
|
@@ -5,7 +5,7 @@ Loaded on demand from the moda-cli skill.
|
|
|
5
5
|
### 10. Everything the dashboard does, from the CLI
|
|
6
6
|
|
|
7
7
|
Every command below needs only an API key, and the tenant comes from the key.
|
|
8
|
-
Writes listed here accept `--dry-run
|
|
8
|
+
Writes listed here accept `--dry-run`: it validates the call, prints the exact request (method, endpoint, body) and sends nothing, and its `next_commands` entry is the command that sends it for real (`mutability: write`, `requires_approval: true`). That covers `problems feedback|reopen|link`, `review`, `feedback` and the `signals` writes. `prompts promote|ab|propose` refuse `--dry-run` before sending anything, so run them only when you mean it.
|
|
9
9
|
|
|
10
10
|
| Dashboard | CLI |
|
|
11
11
|
|---|---|
|
|
@@ -40,7 +40,7 @@ Branch on the exit code; it is stable and cheaper than parsing the payload:
|
|
|
40
40
|
|---|---|---|
|
|
41
41
|
| `0` | ok — answer is grounded in Moda Cloud intelligence | Trust it. |
|
|
42
42
|
| `1` | error — bad input, unknown id (`not_found`), access denied, API/network failure | Read `errors[0].code`; retry only `network_error` / 5xx `api_error`. For `not_found`, find a valid id first (the `cause` names the command). |
|
|
43
|
-
| `3` | degraded — Moda Cloud was unavailable
|
|
43
|
+
| `3` | degraded — Moda Cloud was unavailable and the answer was synthesized from local Data API evidence (`ask`), or some sources failed to load (`investigate`/`failures`, named in `data.failedSources`) | Answer is present but lower-trust or partial; verify before acting, and never read a partial result as "no issues". |
|
|
44
44
|
| `4` | auth required — no API key, or the API rejected it (HTTP 401) | Set `MODA_API_KEY` or run the `login_command` from the `auth` payload (`moda auth login --api-key`), then re-run. |
|
|
45
45
|
| `5` | input required — a choice is needed that the non-interactive run could not answer | Pick a choice from the `input_request` payload and re-invoke the same command with that choice's `resume_flags` appended. |
|
|
46
46
|
| `130` | cancelled | Treat as interrupted or closed pipe; do not retry blindly. |
|
|
@@ -195,17 +195,42 @@ Treat an answer as degraded if **any** of these hold:
|
|
|
195
195
|
that text stays whole, and the error message says whether `data` is whole
|
|
196
196
|
or bounded with its complete copy at `truncation.data.full_output_path`.
|
|
197
197
|
You can also page with a smaller `--limit` and
|
|
198
|
-
`--offset`, or rerun with `--json` (no byte limit).
|
|
198
|
+
`--offset`, or rerun with `--json` (no byte limit). Commands that read
|
|
199
|
+
per-row extras (`--include-window`, `--include-world-state`, batch reads)
|
|
200
|
+
stop reading once the budget is spent; rows they did not enrich carry
|
|
201
|
+
`window_skipped` / `world_state_skipped: "agent_output_budget"`.
|
|
202
|
+
- **`--json` is compact when piped.** `--json` prints one line of JSON when
|
|
203
|
+
stdout is not a terminal (indented on a terminal); `--pretty` indents it
|
|
204
|
+
anyway. `--json` prints the payload as read: `--profile` is stamped only on
|
|
205
|
+
the agent envelope's generated commands (`next_commands`, `*_command`
|
|
206
|
+
fields), never on trace content.
|
|
199
207
|
- **Unknown flags fail.** A flag the command doesn't take (a typo, or a
|
|
200
208
|
filter it lacks) exits `1` with the valid flag list and a "did you mean",
|
|
201
|
-
instead of being silently ignored.
|
|
202
|
-
|
|
203
|
-
- **`--
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
+
instead of being silently ignored. So does a flag the chosen mode would
|
|
210
|
+
not send (`moda signal <id> --limit=3` without `--detections`).
|
|
211
|
+
- **`--days-back` and `--days_back` are the same flag.** Every flag is read
|
|
212
|
+
under its kebab-case name whichever spelling you type.
|
|
213
|
+
- **A value flag needs a value.** `--user-id` with nothing after it (often an
|
|
214
|
+
empty shell variable) exits `1` naming the flag instead of sending the
|
|
215
|
+
string "true". Switches such as `--include-tool-io` stay bare.
|
|
216
|
+
- **Numbers are plain decimal integers.** `--limit=0x10`, `--limit=1e1` and
|
|
217
|
+
`--limit=2.5` fail; text flags keep their text (`--search=404` searches
|
|
218
|
+
for "404").
|
|
219
|
+
- **Extra words fail.** A command that takes one id rejects a second word
|
|
220
|
+
instead of ignoring it. Free text joins every word: `moda traces search
|
|
221
|
+
refund not processed` searches "refund not processed" (same for `ask` and
|
|
222
|
+
`feedback`).
|
|
223
|
+
- **Writes take `--dry-run`** (`prompts promote|ab|propose` excepted).
|
|
224
|
+
- `problems feedback|reopen|link`, `review`, `feedback`, `signals` writes
|
|
225
|
+
and `skills policy` validate fully, send nothing, and return
|
|
226
|
+
`data.planned` (method, endpoint, body) plus a `next_commands` entry
|
|
227
|
+
that runs the write for real (`requires_approval: true`).
|
|
228
|
+
- `registry push`, `harness sync|delete|register`, `prompts sync|decide`
|
|
229
|
+
and `skills sync` return their own preview. Some ask the server to
|
|
230
|
+
compute it (`skills sync --dry-run` sends the local skills marked
|
|
231
|
+
`dryRun: true`), but none of them applies a change.
|
|
232
|
+
- A read refuses `--dry-run` **before anything is sent**, so a "preview"
|
|
233
|
+
can't perform a real write.
|
|
209
234
|
- **Unknown profiles fail.** `--profile=<name>` or `MODA_PROFILE` naming a
|
|
210
235
|
profile that doesn't exist exits `1` instead of falling back to another
|
|
211
236
|
profile's key and tenant. Time windows differ by command (below).
|
|
@@ -110,7 +110,16 @@ moda traces get <conversation_id> --all --from=500 --max-messages=500 # continu
|
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
`--all` returns `has_more`/`next_from`; when it stops at the cap, the warning
|
|
113
|
-
prints the exact `--from` command to continue.
|
|
113
|
+
prints the exact `--from` command to continue. In agent output `--all` reads
|
|
114
|
+
only about what fits the byte budget (a ~50-message first page), so
|
|
115
|
+
`returned` can be well under `--max-messages`; follow `next_from`.
|
|
116
|
+
|
|
117
|
+
A window over the agent byte budget is cut around its anchor, never past it:
|
|
118
|
+
the requested message is always returned, the rest are kept nearest-first on
|
|
119
|
+
both sides, `context.from_index`/`to_index` describe what was returned
|
|
120
|
+
(`requested_from_index`/`requested_to_index` and `omitted_for_byte_limit`
|
|
121
|
+
what was asked for), and `next_commands` has an `--all --from` command for
|
|
122
|
+
each side that lost messages.
|
|
114
123
|
|
|
115
124
|
**Several traces? Batch them in one call instead of looping `moda traces get`
|
|
116
125
|
per id.** Pass up to 25 targets as positionals or one per line with
|
|
@@ -130,7 +139,9 @@ plus `succeeded`/`failed` counts. A missing trace is a per-item
|
|
|
130
139
|
`error.code: "not_found"`, not a failed call; the exit code is 1 only when
|
|
131
140
|
every target failed. When the agent byte budget would overflow, the items that
|
|
132
141
|
fit are returned and `remaining_targets` plus a `next_commands` entry read the
|
|
133
|
-
rest.
|
|
142
|
+
rest. Agent output stops reading targets once the budget is spent, so the
|
|
143
|
+
targets it names were not read yet (nothing is read and then dropped). One
|
|
144
|
+
positional id keeps the single-trace output above.
|
|
134
145
|
|
|
135
146
|
`moda traces get` returns messages whole, with their tool calls and results. An
|
|
136
147
|
older Moda server cuts message text, tool inputs, and tool results at 500
|
|
@@ -148,6 +159,7 @@ moda traces spans <conversation_id> --include-raw # attach verbatim raw_event
|
|
|
148
159
|
moda traces spans <conversation_id> --include-bodies # keep prompt/response/attribute bodies
|
|
149
160
|
moda traces spans <conversation_id> --limit=1000 # ingest rows to read (default 200, max 1000)
|
|
150
161
|
moda traces spans <conversation_id> --cursor=<next_cursor> # next page of a capped audit
|
|
162
|
+
moda traces spans <conversation_id> --cursor=<c> --span-offset=N # rest of a page cut for the agent budget
|
|
151
163
|
moda traces spans <id1> <id2> <id3> # batch: up to 25 ids, one envelope
|
|
152
164
|
```
|
|
153
165
|
|
|
@@ -162,6 +174,12 @@ A full `--limit` page of ingest rows, the server's ~3 MB response budget
|
|
|
162
174
|
(`summary.truncated_reason: "byte_limit"`) or a span cap sets both, and a
|
|
163
175
|
warning plus `next_commands` give the follow-up — usually the `--cursor=` page
|
|
164
176
|
from `next_cursor`; for very large traces audit one OTLP trace at a time
|
|
177
|
+
(see below). In agent output a page over the byte budget (the server's
|
|
178
|
+
smallest page, 32 KiB, is over the 24,000-byte default) keeps the most spans
|
|
179
|
+
that fit: `span_offset`/`next_span_offset`/`page_spans` say which,
|
|
180
|
+
`next_cursor` is `null` until the last spans of the page are read, and
|
|
181
|
+
`next_commands` has the `--span-offset=N` command that reads the rest of the
|
|
182
|
+
same page. Following `next_commands` never skips a span;
|
|
165
183
|
(`summary.trace_ids`, `--kind=trace`). Prompt/response bodies are omitted by
|
|
166
184
|
default (`{"omitted": true, "original_bytes": N}`); `--include-bodies` keeps
|
|
167
185
|
them, cutting strings over 8 KB to `{"truncated": true, "original_bytes": N,
|