@moda-ai/cli 1.55.25 → 1.55.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{agent-t7dxmpdq.js → agent-nqmha8ck.js} +8 -8
  2. package/dist/{cli-9hc5bg2r.js → cli-1mbb0ct0.js} +1 -1
  3. package/dist/{cli-mebf5vtr.js → cli-5g1tv80h.js} +5 -5
  4. package/dist/{cli-m0045npe.js → cli-8tfk8qeb.js} +7 -6
  5. package/dist/{cli-m805msp6.js → cli-b4740tnv.js} +7 -7
  6. package/dist/{cli-qvg26twp.js → cli-cdrvjva5.js} +11 -8
  7. package/dist/{cli-7xc585hc.js → cli-d577kq6h.js} +5 -5
  8. package/dist/{cli-dn91fb56.js → cli-jgfm7w1r.js} +89 -47
  9. package/dist/{cli-9btx12wp.js → cli-jtyvbd8d.js} +1 -1
  10. package/dist/{cli-qycsmxev.js → cli-k6q8dbpk.js} +3 -3
  11. package/dist/{cli-0wr3483h.js → cli-q6f6vrrr.js} +1 -1
  12. package/dist/{cli-dve50x7p.js → cli-sqsjd08w.js} +784 -725
  13. package/dist/cli.js +708 -232
  14. package/dist/{doctor-q21mr5ya.js → doctor-w913fj4g.js} +8 -8
  15. package/dist/{fix-0qdtdz5h.js → fix-crkwdkt4.js} +6 -6
  16. package/dist/{harness-github-actions-atc5bbkj.js → harness-github-actions-fjhvhgpj.js} +5 -5
  17. package/dist/{harness-vzy7n7ea.js → harness-x3e7d68b.js} +5 -5
  18. package/dist/{index-4b1ybz51.js → index-2kf3fnnb.js} +11 -11
  19. package/dist/{production-intelligence-c8e0xw3n.js → production-intelligence-7n83c701.js} +75 -15
  20. package/dist/{profile-commands-6e2dgv72.js → profile-commands-ct2t0bfr.js} +3 -3
  21. package/dist/prompt-source-mcp.js +5 -5
  22. package/dist/{prompts-3h5jcjrw.js → prompts-92aqqb2k.js} +6 -6
  23. package/dist/{provision-q86phh4a.js → provision-gn8raqpt.js} +5 -5
  24. package/dist/{registry-s2vdsfw8.js → registry-ex162j5y.js} +3 -3
  25. package/dist/{skills-vq3njc8a.js → skills-2mbsj9bt.js} +5 -5
  26. package/dist/{sync-hq9dpqpr.js → sync-kghmmmk5.js} +7 -7
  27. package/package.json +1 -1
  28. package/skills/integration/index.json +2 -2
  29. package/skills/moda-cli/SKILL.md +4 -1
  30. package/skills/moda-cli/references/dashboard-parity.md +1 -1
  31. package/skills/moda-cli/references/output-protocol.md +35 -10
  32. package/skills/moda-cli/references/search-and-traces.md +20 -2
@@ -3,16 +3,16 @@ import {
3
3
  promptsDiscoveredCheck,
4
4
  runDoctorCommand,
5
5
  runStatusCommand
6
- } from "./cli-mebf5vtr.js";
7
- import"./cli-0wr3483h.js";
8
- import"./cli-m805msp6.js";
6
+ } from "./cli-5g1tv80h.js";
7
+ import"./cli-q6f6vrrr.js";
8
+ import"./cli-b4740tnv.js";
9
9
  import"./cli-mm48br00.js";
10
- import"./cli-7xc585hc.js";
10
+ import"./cli-d577kq6h.js";
11
11
  import"./cli-97fnztpy.js";
12
- import"./cli-qvg26twp.js";
13
- import"./cli-dn91fb56.js";
14
- import"./cli-9btx12wp.js";
15
- import"./cli-dve50x7p.js";
12
+ import"./cli-cdrvjva5.js";
13
+ import"./cli-jgfm7w1r.js";
14
+ import"./cli-jtyvbd8d.js";
15
+ import"./cli-sqsjd08w.js";
16
16
  import"./cli-0v6na3yp.js";
17
17
  export {
18
18
  runStatusCommand,
@@ -2,17 +2,17 @@ import {
2
2
  DEFAULT_POLL_INTERVAL_MS,
3
3
  DEFAULT_WAIT_TIMEOUT_MS,
4
4
  fetchLatestRun
5
- } from "./cli-m805msp6.js";
5
+ } from "./cli-b4740tnv.js";
6
6
  import"./cli-mm48br00.js";
7
- import"./cli-7xc585hc.js";
7
+ import"./cli-d577kq6h.js";
8
8
  import"./cli-97fnztpy.js";
9
- import"./cli-qvg26twp.js";
9
+ import"./cli-cdrvjva5.js";
10
10
  import {
11
11
  assertFlags
12
- } from "./cli-dn91fb56.js";
12
+ } from "./cli-jgfm7w1r.js";
13
13
  import {
14
14
  callControlAPI
15
- } from "./cli-9btx12wp.js";
15
+ } from "./cli-jtyvbd8d.js";
16
16
  import {
17
17
  CliInputError,
18
18
  EXIT_DEGRADED,
@@ -21,7 +21,7 @@ import {
21
21
  getModaPaths,
22
22
  resolveApiTenantId,
23
23
  validateConfig
24
- } from "./cli-dve50x7p.js";
24
+ } from "./cli-sqsjd08w.js";
25
25
  import"./cli-0v6na3yp.js";
26
26
 
27
27
  // src/fix.ts
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  buildSourceSnapshot
3
- } from "./cli-7xc585hc.js";
3
+ } from "./cli-d577kq6h.js";
4
4
  import"./cli-97fnztpy.js";
5
- import"./cli-qvg26twp.js";
6
- import"./cli-dn91fb56.js";
7
- import"./cli-9btx12wp.js";
5
+ import"./cli-cdrvjva5.js";
6
+ import"./cli-jgfm7w1r.js";
7
+ import"./cli-jtyvbd8d.js";
8
8
  import {
9
9
  recordApiRequest
10
- } from "./cli-dve50x7p.js";
10
+ } from "./cli-sqsjd08w.js";
11
11
  import"./cli-0v6na3yp.js";
12
12
 
13
13
  // src/harness-github-actions.ts
@@ -42,12 +42,12 @@ import {
42
42
  writeHarnessAnalyzeResult,
43
43
  writeHarnessArtifacts,
44
44
  writeHumanProgress
45
- } from "./cli-7xc585hc.js";
45
+ } from "./cli-d577kq6h.js";
46
46
  import"./cli-97fnztpy.js";
47
- import"./cli-qvg26twp.js";
48
- import"./cli-dn91fb56.js";
49
- import"./cli-9btx12wp.js";
50
- import"./cli-dve50x7p.js";
47
+ import"./cli-cdrvjva5.js";
48
+ import"./cli-jgfm7w1r.js";
49
+ import"./cli-jtyvbd8d.js";
50
+ import"./cli-sqsjd08w.js";
51
51
  import"./cli-0v6na3yp.js";
52
52
  export {
53
53
  writeHumanProgress,
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  selectTenantAndCreateKey
3
- } from "./cli-qycsmxev.js";
4
- import"./cli-9hc5bg2r.js";
3
+ } from "./cli-k6q8dbpk.js";
4
+ import"./cli-1mbb0ct0.js";
5
5
  import {
6
6
  buildDoctorReport
7
- } from "./cli-mebf5vtr.js";
7
+ } from "./cli-5g1tv80h.js";
8
8
  import {
9
9
  ConnectCodeError,
10
10
  connectWithCode,
11
11
  loadAuthSession,
12
12
  loadToken,
13
13
  login
14
- } from "./cli-0wr3483h.js";
14
+ } from "./cli-q6f6vrrr.js";
15
15
  import {
16
16
  initPrompts,
17
17
  runPromptSync
18
- } from "./cli-m805msp6.js";
18
+ } from "./cli-b4740tnv.js";
19
19
  import"./cli-mm48br00.js";
20
20
  import {
21
21
  canonicalText,
@@ -35,7 +35,7 @@ import {
35
35
  runCodingAgent,
36
36
  runHarnessCommand,
37
37
  startRemoteAnalyze
38
- } from "./cli-7xc585hc.js";
38
+ } from "./cli-d577kq6h.js";
39
39
  import {
40
40
  stripAnsi
41
41
  } from "./cli-97fnztpy.js";
@@ -47,12 +47,12 @@ import {
47
47
  import {
48
48
  agentsMdProblem,
49
49
  runSkillSync
50
- } from "./cli-m0045npe.js";
50
+ } from "./cli-8tfk8qeb.js";
51
51
  import {
52
52
  createCommandContext
53
- } from "./cli-qvg26twp.js";
54
- import"./cli-dn91fb56.js";
55
- import"./cli-9btx12wp.js";
53
+ } from "./cli-cdrvjva5.js";
54
+ import"./cli-jgfm7w1r.js";
55
+ import"./cli-jtyvbd8d.js";
56
56
  import {
57
57
  CliAuthError,
58
58
  CliInputError,
@@ -60,7 +60,7 @@ import {
60
60
  recordApiRequest,
61
61
  resolveIngestUrl,
62
62
  resolveModaBaseUrl
63
- } from "./cli-dve50x7p.js";
63
+ } from "./cli-sqsjd08w.js";
64
64
  import {
65
65
  detectAgents,
66
66
  installRules,
@@ -10,12 +10,13 @@ import {
10
10
  import {
11
11
  callControlAPI,
12
12
  callDataAPI
13
- } from "./cli-9btx12wp.js";
13
+ } from "./cli-jtyvbd8d.js";
14
14
  import {
15
15
  CliAuthError,
16
16
  CliInputError,
17
17
  EXIT_DEGRADED,
18
18
  EXIT_OK,
19
+ apiErrorStatus,
19
20
  apiKeyHeaders,
20
21
  asNumber,
21
22
  asRecord,
@@ -28,7 +29,7 @@ import {
28
29
  resolveModaBaseUrl,
29
30
  safeWriteStderr,
30
31
  shellWord
31
- } from "./cli-dve50x7p.js";
32
+ } from "./cli-sqsjd08w.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
- context.output.writeData(briefing, overviewAgentOptions(briefing));
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: 0 };
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: 0 };
466
+ return { exitCode: investigation.degraded ? EXIT_DEGRADED : EXIT_OK };
462
467
  }
463
468
  throw new CliInputError(`Unknown production command '${context.command}'`);
464
469
  }
@@ -522,6 +527,13 @@ 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
  }
@@ -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[0];
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, investigationAgentOptions(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.raw
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) {
@@ -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 ?? summary ?? data
904
+ value: first ? frustrationEvidenceIds(first, anchorIndex) : { frustrated_count: count, at_risk_count: atRisk }
878
905
  });
879
906
  return [{
880
907
  id: "finding_frustration_rate",
@@ -897,6 +924,17 @@ function frustrationFindings(data, daysBack, evidenceRefs) {
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.raw
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 {
@@ -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-9hc5bg2r.js";
5
+ } from "./cli-1mbb0ct0.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-0wr3483h.js";
13
+ } from "./cli-q6f6vrrr.js";
14
14
  import {
15
15
  CliInputError,
16
16
  DEFAULT_INGEST_URL,
@@ -35,7 +35,7 @@ import {
35
35
  secretFilePathFromRef,
36
36
  setActiveProfile,
37
37
  upsertProfile
38
- } from "./cli-dve50x7p.js";
38
+ } from "./cli-sqsjd08w.js";
39
39
  import"./cli-0v6na3yp.js";
40
40
 
41
41
  // src/profile-commands.ts
@@ -5,12 +5,12 @@ import {
5
5
  inspectCodeSelectors,
6
6
  inspectPythonSelectors,
7
7
  safePromptEvidencePath
8
- } from "./cli-7xc585hc.js";
8
+ } from "./cli-d577kq6h.js";
9
9
  import"./cli-97fnztpy.js";
10
- import"./cli-qvg26twp.js";
11
- import"./cli-dn91fb56.js";
12
- import"./cli-9btx12wp.js";
13
- import"./cli-dve50x7p.js";
10
+ import"./cli-cdrvjva5.js";
11
+ import"./cli-jgfm7w1r.js";
12
+ import"./cli-jtyvbd8d.js";
13
+ import"./cli-sqsjd08w.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-m805msp6.js";
14
+ } from "./cli-b4740tnv.js";
15
15
  import {
16
16
  promptSourceHashPayload
17
17
  } from "./cli-mm48br00.js";
18
- import"./cli-7xc585hc.js";
18
+ import"./cli-d577kq6h.js";
19
19
  import"./cli-97fnztpy.js";
20
- import"./cli-qvg26twp.js";
21
- import"./cli-dn91fb56.js";
22
- import"./cli-9btx12wp.js";
23
- import"./cli-dve50x7p.js";
20
+ import"./cli-cdrvjva5.js";
21
+ import"./cli-jgfm7w1r.js";
22
+ import"./cli-jtyvbd8d.js";
23
+ import"./cli-sqsjd08w.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-qycsmxev.js";
4
- import"./cli-9hc5bg2r.js";
3
+ } from "./cli-k6q8dbpk.js";
4
+ import"./cli-1mbb0ct0.js";
5
5
  import {
6
6
  loadAuthSession
7
- } from "./cli-0wr3483h.js";
7
+ } from "./cli-q6f6vrrr.js";
8
8
  import {
9
9
  stringOption
10
- } from "./cli-qvg26twp.js";
10
+ } from "./cli-cdrvjva5.js";
11
11
  import {
12
12
  CliAuthError,
13
13
  resolveIngestUrl,
14
14
  resolveModaBaseUrl
15
- } from "./cli-dve50x7p.js";
15
+ } from "./cli-sqsjd08w.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-dn91fb56.js";
3
+ } from "./cli-jgfm7w1r.js";
4
4
  import {
5
5
  callControlAPI
6
- } from "./cli-9btx12wp.js";
6
+ } from "./cli-jtyvbd8d.js";
7
7
  import {
8
8
  CliInputError,
9
9
  explicitOutputMode,
10
10
  resolveApiKey
11
- } from "./cli-dve50x7p.js";
11
+ } from "./cli-sqsjd08w.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-m0045npe.js";
7
- import"./cli-qvg26twp.js";
8
- import"./cli-dn91fb56.js";
9
- import"./cli-9btx12wp.js";
10
- import"./cli-dve50x7p.js";
6
+ } from "./cli-8tfk8qeb.js";
7
+ import"./cli-cdrvjva5.js";
8
+ import"./cli-jgfm7w1r.js";
9
+ import"./cli-jtyvbd8d.js";
10
+ import"./cli-sqsjd08w.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-m805msp6.js";
3
+ } from "./cli-b4740tnv.js";
4
4
  import"./cli-mm48br00.js";
5
5
  import {
6
6
  runHarnessCommand
7
- } from "./cli-7xc585hc.js";
7
+ } from "./cli-d577kq6h.js";
8
8
  import"./cli-97fnztpy.js";
9
9
  import {
10
10
  runSkillsCommand
11
- } from "./cli-m0045npe.js";
12
- import"./cli-qvg26twp.js";
13
- import"./cli-dn91fb56.js";
14
- import"./cli-9btx12wp.js";
11
+ } from "./cli-8tfk8qeb.js";
12
+ import"./cli-cdrvjva5.js";
13
+ import"./cli-jgfm7w1r.js";
14
+ import"./cli-jtyvbd8d.js";
15
15
  import {
16
16
  CliInputError
17
- } from "./cli-dve50x7p.js";
17
+ } from "./cli-sqsjd08w.js";
18
18
  import"./cli-8dtnwp9r.js";
19
19
  import"./cli-0v6na3yp.js";
20
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moda-ai/cli",
3
- "version": "1.55.25",
3
+ "version": "1.55.26",
4
4
  "description": "CLI for Moda: production monitoring and evals for AI agents.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": "moda.skill_index.v1",
3
- "bundled_at": "2026-10-15T20:30:38.730Z",
4
- "cli_version": "1.55.25",
3
+ "bundled_at": "2026-10-15T21:00:31.183Z",
4
+ "cli_version": "1.55.26",
5
5
  "skills": [
6
6
  {
7
7
  "id": "integration-cloudflare-think",
@@ -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. Use `--dry-run` where a command offers it.
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` (prints the exact request, sends nothing) except `problems feedback`, `review`, `problems link`, and `prompts promote|ab|propose`. Those refuse `--dry-run` before sending anything, so run them only when you mean it.
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; answer synthesized from local Data API evidence | Answer is present but lower-trust; verify before acting. |
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. Stray arguments on commands that take
202
- none fail the same way.
203
- - **`--dry-run` is only accepted where it's implemented** (for example
204
- `registry push`, `harness sync|delete|register`, `prompts sync|decide`,
205
- `skills sync|policy`, `signals` write subcommands, `problem-reopen`;
206
- `moda <command> --help` says whether a command takes it). Anywhere else it fails **before
207
- anything is sent**. It is never silently ignored, so a "preview" can't
208
- perform a real write.
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).