@moda-ai/cli 1.55.41 → 1.55.43

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 (33) hide show
  1. package/dist/{agent-ck6y31n2.js → agent-x1gwrrvd.js} +6 -5
  2. package/dist/{cli-xddtv3yn.js → cli-5fhqfx04.js} +1 -39
  3. package/dist/{cli-gt3yq1y5.js → cli-5y9tj6cb.js} +183 -1
  4. package/dist/{cli-f1jfrqgf.js → cli-9a0a3v13.js} +234 -17
  5. package/dist/cli-e0kbye4s.js +39 -0
  6. package/dist/{cli-ypqwcf9n.js → cli-fpd1pfvt.js} +2 -2
  7. package/dist/{cli-a8nxbtpk.js → cli-h62j4jn7.js} +2 -2
  8. package/dist/{cli-4tg0hkbz.js → cli-k5drmy8r.js} +7 -7
  9. package/dist/{cli-azage7s0.js → cli-s1w5phms.js} +3 -3
  10. package/dist/{cli-7bn406mt.js → cli-stfpr2ct.js} +2 -2
  11. package/dist/cli.js +224 -52
  12. package/dist/{doctor-p8sp6cbk.js → doctor-wrgajgev.js} +5 -4
  13. package/dist/{fix-0r974yge.js → fix-7aajsdbf.js} +1 -1
  14. package/dist/{harness-72ejenza.js → harness-1rn1hqzz.js} +4 -3
  15. package/dist/{harness-github-actions-2qc4gg2w.js → harness-github-actions-m95qvgbs.js} +4 -3
  16. package/dist/{index-w7v472w4.js → index-svfzq5rb.js} +7 -6
  17. package/dist/{production-intelligence-e5vsc6cw.js → production-intelligence-7jvfdz6b.js} +22 -5
  18. package/dist/{prompt-attribution-3987hhqz.js → prompt-attribution-hc6mcvee.js} +4 -3
  19. package/dist/prompt-source-mcp.js +4 -3
  20. package/dist/{prompts-ab-gmd10n5d.js → prompts-ab-ws66335h.js} +5 -4
  21. package/dist/{prompts-propose-q626zmm4.js → prompts-propose-a9m0p9nr.js} +5 -4
  22. package/dist/{prompts-ysm9ra72.js → prompts-xe5bgbx8.js} +4 -3
  23. package/dist/{provision-cya5rpxa.js → provision-a9kkfvp7.js} +2 -1
  24. package/dist/{registry-7xz09ry0.js → registry-j2dsfh6v.js} +1 -1
  25. package/dist/{skills-x6yszxxn.js → skills-vveagdwe.js} +4 -3
  26. package/dist/{sync-trjzvam9.js → sync-yy3fgnxe.js} +6 -5
  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/commands.md +8 -3
  31. package/skills/moda-cli/references/dashboard-parity.md +7 -2
  32. package/skills/moda-cli/references/detections.md +20 -0
  33. package/skills/moda-cli/references/production-intelligence.md +48 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildDoctorReport
3
- } from "./cli-a8nxbtpk.js";
3
+ } from "./cli-h62j4jn7.js";
4
4
  import {
5
5
  selectTenantAndCreateKey
6
6
  } from "./cli-1z1sx8dg.js";
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  agentsMdProblem,
22
22
  runSkillSync
23
- } from "./cli-7bn406mt.js";
23
+ } from "./cli-stfpr2ct.js";
24
24
  import"./cli-qm5b1vck.js";
25
25
  import {
26
26
  detectAgents
@@ -32,7 +32,7 @@ import {
32
32
  import {
33
33
  initPrompts,
34
34
  runPromptSync
35
- } from "./cli-4tg0hkbz.js";
35
+ } from "./cli-k5drmy8r.js";
36
36
  import"./cli-mm48br00.js";
37
37
  import {
38
38
  codingAgentDisplayName,
@@ -46,7 +46,7 @@ import {
46
46
  runCodingAgent,
47
47
  runHarnessCommand,
48
48
  startRemoteAnalyze
49
- } from "./cli-azage7s0.js";
49
+ } from "./cli-s1w5phms.js";
50
50
  import {
51
51
  canonicalText,
52
52
  renderInitBanner,
@@ -62,8 +62,9 @@ import"./cli-cesds766.js";
62
62
  import"./cli-qpq84eee.js";
63
63
  import {
64
64
  createCommandContext
65
- } from "./cli-xddtv3yn.js";
66
- import"./cli-f1jfrqgf.js";
65
+ } from "./cli-5fhqfx04.js";
66
+ import"./cli-e0kbye4s.js";
67
+ import"./cli-9a0a3v13.js";
67
68
  import"./cli-0xc5htv7.js";
68
69
  import {
69
70
  VERSION,
@@ -5,14 +5,19 @@ import {
5
5
  asString,
6
6
  contextTarget,
7
7
  frustrationAnchorIndex,
8
- frustrationsFromEmotions
9
- } from "./cli-gt3yq1y5.js";
8
+ frustrationsFromEmotions,
9
+ loadTrends,
10
+ overviewTrendsQuery,
11
+ renderTrendsHuman,
12
+ trendsSummaryText
13
+ } from "./cli-5y9tj6cb.js";
10
14
  import {
11
15
  renderMarkdownForTerminal,
12
16
  shouldColorTerminalOutput,
13
17
  stripAnsi,
14
18
  terminalStyles
15
19
  } from "./cli-97fnztpy.js";
20
+ import"./cli-e0kbye4s.js";
16
21
  import {
17
22
  callControlAPI,
18
23
  callDataAPI
@@ -407,7 +412,12 @@ function isAuthFailure(error) {
407
412
  async function runProductionCommand(context) {
408
413
  const daysBack = daysBackFlag(context.flags);
409
414
  if (context.command === "overview") {
410
- const briefing = await loadOverviewBriefing({ daysBack, cwd: context.cwd });
415
+ const trendsQuery = overviewTrendsQuery(context.flags, daysBack);
416
+ const [loaded, trends] = await Promise.all([
417
+ loadOverviewBriefing({ daysBack, cwd: context.cwd }),
418
+ trendsQuery ? loadTrends(trendsQuery) : Promise.resolve(undefined)
419
+ ]);
420
+ const briefing = trends ? { ...loaded, trends } : loaded;
411
421
  if (context.flags.raw === "true") {
412
422
  context.output.writeData(briefing.rawOverview, {
413
423
  summary: "Loaded raw Moda overview.",
@@ -1463,16 +1473,19 @@ function investigationAgentOptions(investigation) {
1463
1473
  };
1464
1474
  }
1465
1475
  function overviewAgentOptions(briefing) {
1476
+ const trendText = briefing.trends ? trendsSummaryText(briefing.trends) : null;
1477
+ const trendNotes = Array.isArray(briefing.trends?.notes) ? briefing.trends.notes.map(String) : [];
1478
+ const warnings = [...detectorWarnings(briefing.detectors), ...trendNotes];
1466
1479
  return {
1467
1480
  summary: {
1468
- text: `Moda health briefing: ${briefing.status}. Next: ${briefing.nextCommand}`,
1481
+ text: `Moda health briefing: ${briefing.status}.${trendText ? ` ${trendText}` : ""} Next: ${briefing.nextCommand}`,
1469
1482
  confidence: briefing.topFinding ? briefing.topFinding.confidence : "medium"
1470
1483
  },
1471
1484
  findings: briefing.topFinding ? [agentFinding(briefing.topFinding)] : [],
1472
1485
  evidenceRefs: briefing.evidenceRefs.map(agentEvidence),
1473
1486
  recommendedActions: briefing.topFinding ? briefing.topFinding.recommendedActions.map(agentAction) : [],
1474
1487
  nextCommands: [nextCommand(briefing.nextCommand)],
1475
- ...detectorWarnings(briefing.detectors).length > 0 ? { warnings: detectorWarnings(briefing.detectors) } : {}
1488
+ ...warnings.length > 0 ? { warnings } : {}
1476
1489
  };
1477
1490
  }
1478
1491
  function askAgentOptions(result) {
@@ -1558,6 +1571,10 @@ function renderOverviewBriefingHuman(briefing) {
1558
1571
  for (const warning of detectorWarnings(briefing.detectors))
1559
1572
  lines.push(` Warning: ${warning}`);
1560
1573
  }
1574
+ if (briefing.trends) {
1575
+ lines.push("");
1576
+ lines.push(...renderTrendsHuman(briefing.trends));
1577
+ }
1561
1578
  lines.push("");
1562
1579
  lines.push("Top signal");
1563
1580
  if (briefing.topFinding) {
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  inventoryFiles,
3
3
  safePromptEvidencePath
4
- } from "./cli-azage7s0.js";
4
+ } from "./cli-s1w5phms.js";
5
5
  import"./cli-xq45etg1.js";
6
6
  import"./cli-97fnztpy.js";
7
7
  import"./cli-cesds766.js";
8
8
  import {
9
9
  require_typescript
10
10
  } from "./cli-qpq84eee.js";
11
- import"./cli-xddtv3yn.js";
12
- import"./cli-f1jfrqgf.js";
11
+ import"./cli-5fhqfx04.js";
12
+ import"./cli-e0kbye4s.js";
13
+ import"./cli-9a0a3v13.js";
13
14
  import"./cli-0xc5htv7.js";
14
15
  import"./cli-t0pb7qbs.js";
15
16
  import"./cli-k4tqwah4.js";
@@ -3,7 +3,7 @@ import {
3
3
  checkPromptMapping,
4
4
  discoverHarnessPromptSources,
5
5
  safePromptEvidencePath
6
- } from "./cli-azage7s0.js";
6
+ } from "./cli-s1w5phms.js";
7
7
  import"./cli-xq45etg1.js";
8
8
  import"./cli-97fnztpy.js";
9
9
  import"./cli-cesds766.js";
@@ -11,8 +11,9 @@ import {
11
11
  inspectCodeSelectors,
12
12
  inspectPythonSelectors
13
13
  } from "./cli-qpq84eee.js";
14
- import"./cli-xddtv3yn.js";
15
- import"./cli-f1jfrqgf.js";
14
+ import"./cli-5fhqfx04.js";
15
+ import"./cli-e0kbye4s.js";
16
+ import"./cli-9a0a3v13.js";
16
17
  import"./cli-0xc5htv7.js";
17
18
  import"./cli-t0pb7qbs.js";
18
19
  import"./cli-k4tqwah4.js";
@@ -23,12 +23,13 @@ import {
23
23
  runPromptAb,
24
24
  selectProblemCases,
25
25
  waitLabel
26
- } from "./cli-ypqwcf9n.js";
27
- import"./cli-4tg0hkbz.js";
26
+ } from "./cli-fpd1pfvt.js";
27
+ import"./cli-k5drmy8r.js";
28
28
  import"./cli-daqkdnm1.js";
29
29
  import"./cli-mm48br00.js";
30
- import"./cli-xddtv3yn.js";
31
- import"./cli-f1jfrqgf.js";
30
+ import"./cli-5fhqfx04.js";
31
+ import"./cli-e0kbye4s.js";
32
+ import"./cli-9a0a3v13.js";
32
33
  import"./cli-0xc5htv7.js";
33
34
  import"./cli-t0pb7qbs.js";
34
35
  import"./cli-k4tqwah4.js";
@@ -7,12 +7,13 @@ import {
7
7
  formatVerdict,
8
8
  rerunWithYes,
9
9
  resolvePromptArmSpec
10
- } from "./cli-ypqwcf9n.js";
11
- import"./cli-4tg0hkbz.js";
10
+ } from "./cli-fpd1pfvt.js";
11
+ import"./cli-k5drmy8r.js";
12
12
  import"./cli-daqkdnm1.js";
13
13
  import"./cli-mm48br00.js";
14
- import"./cli-xddtv3yn.js";
15
- import"./cli-f1jfrqgf.js";
14
+ import"./cli-5fhqfx04.js";
15
+ import"./cli-e0kbye4s.js";
16
+ import"./cli-9a0a3v13.js";
16
17
  import {
17
18
  callControlAPI
18
19
  } from "./cli-0xc5htv7.js";
@@ -11,12 +11,13 @@ import {
11
11
  runPromptSync,
12
12
  runPromptsCommand,
13
13
  writePromptSyncProgress
14
- } from "./cli-4tg0hkbz.js";
14
+ } from "./cli-k5drmy8r.js";
15
15
  import {
16
16
  promptSourceHashPayload
17
17
  } from "./cli-mm48br00.js";
18
- import"./cli-xddtv3yn.js";
19
- import"./cli-f1jfrqgf.js";
18
+ import"./cli-5fhqfx04.js";
19
+ import"./cli-e0kbye4s.js";
20
+ import"./cli-9a0a3v13.js";
20
21
  import"./cli-0xc5htv7.js";
21
22
  import"./cli-t0pb7qbs.js";
22
23
  import"./cli-k4tqwah4.js";
@@ -7,7 +7,8 @@ import {
7
7
  } from "./cli-pmzh2qjy.js";
8
8
  import {
9
9
  stringOption
10
- } from "./cli-xddtv3yn.js";
10
+ } from "./cli-5fhqfx04.js";
11
+ import"./cli-e0kbye4s.js";
11
12
  import {
12
13
  resolveIngestUrl,
13
14
  resolveModaBaseUrl
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  assertFlags
3
- } from "./cli-f1jfrqgf.js";
3
+ } from "./cli-9a0a3v13.js";
4
4
  import {
5
5
  callControlAPI
6
6
  } from "./cli-0xc5htv7.js";
@@ -3,12 +3,13 @@ import {
3
3
  pullSkills,
4
4
  runSkillSync,
5
5
  runSkillsCommand
6
- } from "./cli-7bn406mt.js";
6
+ } from "./cli-stfpr2ct.js";
7
7
  import"./cli-qm5b1vck.js";
8
8
  import"./cli-rjav0vj1.js";
9
9
  import"./cli-hcwdz9sd.js";
10
- import"./cli-xddtv3yn.js";
11
- import"./cli-f1jfrqgf.js";
10
+ import"./cli-5fhqfx04.js";
11
+ import"./cli-e0kbye4s.js";
12
+ import"./cli-9a0a3v13.js";
12
13
  import"./cli-0xc5htv7.js";
13
14
  import"./cli-t0pb7qbs.js";
14
15
  import"./cli-k4tqwah4.js";
@@ -1,22 +1,23 @@
1
1
  import {
2
2
  runSkillsCommand
3
- } from "./cli-7bn406mt.js";
3
+ } from "./cli-stfpr2ct.js";
4
4
  import"./cli-qm5b1vck.js";
5
5
  import"./cli-rjav0vj1.js";
6
6
  import"./cli-hcwdz9sd.js";
7
7
  import {
8
8
  runPromptsCommand
9
- } from "./cli-4tg0hkbz.js";
9
+ } from "./cli-k5drmy8r.js";
10
10
  import"./cli-mm48br00.js";
11
11
  import {
12
12
  runHarnessCommand
13
- } from "./cli-azage7s0.js";
13
+ } from "./cli-s1w5phms.js";
14
14
  import"./cli-xq45etg1.js";
15
15
  import"./cli-97fnztpy.js";
16
16
  import"./cli-cesds766.js";
17
17
  import"./cli-qpq84eee.js";
18
- import"./cli-xddtv3yn.js";
19
- import"./cli-f1jfrqgf.js";
18
+ import"./cli-5fhqfx04.js";
19
+ import"./cli-e0kbye4s.js";
20
+ import"./cli-9a0a3v13.js";
20
21
  import"./cli-0xc5htv7.js";
21
22
  import"./cli-t0pb7qbs.js";
22
23
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moda-ai/cli",
3
- "version": "1.55.41",
3
+ "version": "1.55.43",
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-18T02:11:16.441Z",
4
- "cli_version": "1.55.41",
3
+ "bundled_at": "2026-10-18T02:56:13.211Z",
4
+ "cli_version": "1.55.43",
5
5
  "skills": [
6
6
  {
7
7
  "id": "integration-cloudflare-think",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: moda-cli
3
- version: 3.0.7
3
+ version: 3.0.9
4
4
  description: Investigate a production AI agent with the Moda CLI (`moda`) - find where something happened in real traces (traces search, then traces get), check agent health, rank what to fix (investigate, problems), and dig into tool failures, user frustration, and hallucinations. Also prompt registry sync/promote, replays, custom signals, and false-positive marking. Use when the user mentions Moda, production traces or conversations of their agent, agent failures, or asks what to fix.
5
5
  ---
6
6
 
@@ -60,6 +60,8 @@ Details: `references/output-protocol.md`.
60
60
  | Where did X happen / traces about Y | `moda traces search "<words>"` (`--mode=keyword` for ids, error codes, exact strings; `--include-tool-io` for tool inputs/outputs) | `moda traces get <conversation_id> --msg-index=<message_index> --window=3` |
61
61
  | Search returned nothing | Read `.warnings` (degraded mode, reason). Try a shorter phrase, `--mode=keyword`, a wider `--time-range` | `moda traces --search="<words>"` |
62
62
  | Is the agent healthy? | `moda overview --days-back=7` | `moda investigate` |
63
+ | Did my change make it worse? | `moda overview --compare --since=<deploy time, ISO UTC>` (after the deploy against the same span before it; add `--agent-name=<sub-agent>` for one sub-agent) | `moda overview --series --since=<deploy time>` (per hour up to 2 days, else per day), `moda detections list --family=<f> --compare`, `moda problems get <problem_id> --trend` |
64
+ | Is X trending up? | `moda overview --compare --series --days-back=14` | `moda problems get <problem_id> --trend --days-back=30` (incidents per day) |
63
65
  | What to fix first? | `moda investigate` or `moda problems list` (free; both rank the same list the dashboard shows, `data.problemsView` names it) | `moda problems get <problem_id>` (`--view=dream` on a dream-grouped tenant), then `--evidence` / `--traces` |
64
66
  | Why is tool T failing? | `moda detections tools` | `moda detections tools <T>` (use each row's `anchor`) |
65
67
  | How often is tool T called / what is its schema? | `moda tools list` (every tool: calls, failed calls, success rate; `--sort=failure_rate`) | `moda tools get <T>` (registered schema, observed payload fields, usage over time, top failure categories) |
@@ -72,6 +74,7 @@ Details: `references/output-protocol.md`.
72
74
  | Read one whole trace | `moda traces get <id> --all` (pages of up to 500 messages) | `moda traces spans <id>` for raw spans |
73
75
  | Read several traces or turns | `moda traces get <id1>@<msg_index> <id2>@<msg_index> ...` (up to 25; or one per line via `--ids-from=-`) | Same for `moda traces spans <id1> <id2> ...` |
74
76
  | One user's experience | `moda users`, `moda user <user_id>` | `moda traces search "<words>" --user-id=<id>` |
77
+ | Is this only hurting <segment> (enterprise, new users, ...)? | `moda cohorts list` (the ref of a built-in or saved cohort), then `moda problems list --sort=users --cohort=<ref>` and the same command without `--cohort` | `moda detections list --family=frustration --cohort=<ref>` vs no `--cohort` (totals count traces); `moda cohorts compare <ref> builtin:power_users` for size, health and failure mix |
75
78
  | Topic mix | `moda clusters` | `moda cluster-traces <node_id>` |
76
79
  | What the agent believed at a turn | `moda traces state <id> --snapshot --msg-index=<n>` | |
77
80
  | A synthesized answer | `moda ask "<question>"` only when the user asks: each call is a paid agent run (up to about 200k tokens) | Exit 3 means degraded |
@@ -15,7 +15,7 @@ Loaded on demand from the moda-cli skill. This table can lag the CLI: `moda <com
15
15
  | `moda auth status` | Both credentials; exit `0` if either is usable, `4` if neither (expected, not an error) |
16
16
  | `moda auth token` | Print the raw bearer token for `$(moda auth token)` composition |
17
17
  | `moda traces search "<query>"` | **Message-grain semantic/keyword/hybrid search (incl. tool calls); primary content-discovery path** |
18
- | `moda overview` | Dashboard KPIs, top clusters, recent activity |
18
+ | `moda overview` | Dashboard KPIs, top clusters, recent activity. `--compare` adds `trends`: overview KPIs, per-unit rates, Problems and each detector family against the previous window of equal length; `--series` adds `[bucket, value]` arrays; `--since=<ISO> [--until=<ISO>]` sets the window (before/after a deploy); `--agent-name=<sub-agent>`; `--unit=conversation\|segment\|turn` |
19
19
  | `moda ask "<question>"` | Natural-language production/harness answer with evidence (exit `3` = degraded local fallback) |
20
20
  | `moda investigate` | Rank production issues (tool failures, frustrations, top Problems) with evidence + next commands |
21
21
  | `moda clusters` | Browse topic cluster hierarchy; `--search="q"` finds clusters by meaning, `--node-id=ID` resolves a deep link |
@@ -25,7 +25,7 @@ Loaded on demand from the moda-cli skill. This table can lag the CLI: `moda <com
25
25
  | `moda detections list --family=frustration` | User frustration detections with evidence (the frustration family of `emotions`, legacy field names) |
26
26
  | `moda detections list --family=emotion` | Multi-family emotion detections: frustration, disapproval, sadness, confusion, anxiety, trust, positive (`--family=F`, `--user-id`, `--conversation-id`, limit 1–20) |
27
27
  | `moda detections list --family=hallucination` | Grounding detections: contradicted/verified outputs, rule breakdown (`--kind=contradicted\|verified`, `--conversation-id=ID`) |
28
- | `moda detections tools` | Tool failure overview |
28
+ | `moda detections tools` | Tool failure overview (`--compare` adds `summary.compare`) |
29
29
  | `moda detections tools <tool_name>` | Per-tool failure breakdown + examples |
30
30
  | `moda tools list` | Tool catalog: every tool called in the window with calls, failed calls, success rate, traces, effect direction, last seen (`--sort=calls\|failure_rate\|failures\|traces\|last_seen`, `--search`, `--direction`, `--limit` 1-200, `--offset`) |
31
31
  | `moda tools get <tool_name>` | One tool: call stats, registered description and schema, observed payload fields, usage over time, top failure categories with the newest failure (`--days-back`, `--full`) |
@@ -35,6 +35,8 @@ Loaded on demand from the moda-cli skill. This table can lag the CLI: `moda <com
35
35
  | `moda review <kind> <target>` | Write: kinds `problem\|problem-detection\|quote\|tool\|laziness\|hallucination\|custom-signal`; `--reason` optional; problem-detection needs `--conversation-id` + `--attribution-id`; quote needs `--family`, `--turn`, `--quote`; tool needs `--tool` plus `--tool-use-id` or `--msg-index`; custom-signal needs `--conversation-id`; `--verdict=clear` removes a mark (not for problem) |
36
36
  | `moda reviews list [conversation_id]` | Current false-positive marks: all (`--kind=quote\|tool\|laziness\|hallucination\|custom-signal`, `--all` to include removed, `--limit`) or one trace with its problem detection reviews. Problem dismissals are read with `moda problems get <problem_id> --feedback`, detection reviews with `moda reviews list <conversation_id> --kind=problem-detection` |
37
37
  | `moda detections list --family=laziness` | Laziness detections per trace (`--days-back`, `--limit` 1-50, `--conversation-id`, `--family`) |
38
+ | `moda detections list --family=<f> --compare` | Adds `summary.compare`: the family's dashboard KPI tiles and per-trace rate for the list's `--days-back` window against the previous window of equal length (whole family; not with `--conversation-id`/`--user-id`) |
39
+ | `moda problems get <problem_id> --trend` | Incidents and users per day (`[date, value]`) and incidents/signals against the previous window of equal length (`--days-back`, default 30; no comparison above 45) |
38
40
  | `moda detections list --family=<f> --group-by=trace` | The dashboard's per-trace list for emotion, frustration and hallucination: totals count traces. Dashboard filters imply it: emotion/frustration `--search --status --elicitor --trajectory --signal --sort --order`; hallucination `--search --status --rule --source --sort --order`; laziness (always per trace) `--search --status --sort --order`. See detections.md 5a |
39
41
  | `moda problems linear <problem_id>` | The Problem's linked Linear issue (key, state, URL) or `link: null`; needs Linear connected (Integrations → Linear) |
40
42
  | `moda problems link <problem_id>` | Write: file the Problem as a Linear issue (`--team-id`, `--title`, `--priority=0-4`), or link an existing one with `--issue=ENG-123\|URL` (exclusive with the others). Idempotent per Problem |
@@ -54,7 +56,10 @@ Loaded on demand from the moda-cli skill. This table can lag the CLI: `moda <com
54
56
  | `moda prompts sync` | Upload changed prompt versions and update lockfile |
55
57
  | `moda prompts promote <key>` | Move a remote prompt label |
56
58
  | `moda registry template\|validate\|push\|status\|coverage\|log\|show\|prompt` | Register prompts, skills, tools, and agent wiring from one agent-written manifest (`--file`, `--dry-run`, `--live`, `--message`, `--days`); every push is a commit in the Registry history; no repo scan |
57
- | `moda users` / `moda user <id>` | End users with health/activity (`--page-size=N`, alias `--limit=N`; `--page=N`); one user's profile |
59
+ | `moda users` / `moda user <id>` | End users with health/activity (`--page-size=N`, alias `--limit=N`; `--page=N`; `--cohort=builtin:<key>\|<saved id>`); one user's profile |
60
+ | `moda cohorts list\|get\|fields\|preview\|compare` | User cohorts (built-in and saved): refs and definitions, the definition fields, a member count and sample for an unsaved definition (`--file`/`--definition`), two cohorts side by side (`--days=7\|30\|90`) |
61
+ | `moda cohorts create\|update` | Write: save a cohort (`--name`, `--file`/`--definition`, `--description`, `--pinned`, `--color`) or edit a saved one (`<cohort_id>`, same flags plus `--note`); both take `--dry-run` |
62
+ | `--cohort=<ref>` | Scope `problems list`, `traces list`, `detections list` (emotion/frustration/hallucination per trace, laziness, custom_signal hits), `detections tools` and `clusters` to one cohort (`builtin:<key>` or a saved id from `moda cohorts list`). The summary names the cohort; a warning means the server did not confirm the scope |
58
63
  | `moda problems reopen <pid>` | Reopen a Problem marked fixed |
59
64
  | `moda signals <create\|update\|activate\|pause\|delete\|examples\|refine\|revise\|proposals\|accept\|reject\|search\|preview>` | Manage custom signals (writes take `--dry-run`; LLM-backed ones are rate-limited per key) |
60
65
  | `moda prompts list\|show\|proposals\|usage\|replay-runs\|decide` | Read the prompt registry; merge/reject proposals |
@@ -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`: 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.
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`, `cohorts create|update` 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
  |---|---|
@@ -14,7 +14,12 @@ Writes listed here accept `--dry-run`: it validates the call, prints the exact r
14
14
  | Traces list: Processed, Use case confidence, Indexed columns | `moda traces` rows: `processing_status`, `error_message`, `membership_score`, `indexed_at`; `moda traces get <id>`: `trace_state` |
15
15
  | Signals tabs: per-trace list, filters, sort | `moda detections list --family=<f> --group-by=trace` plus `--trajectory --elicitor --signal --status --search --sort --order` (emotion), `--rule --source` (hallucination) |
16
16
  | Settings: which detectors run | `moda overview` → `detectors` (read-only; switching one is dashboard-only) |
17
- | Users page / user profile | `moda users [--window --cohort --sort --order --health-status]`, `moda user <id>` |
17
+ | Home / Analytics / Signals KPI cards: change against the previous period, sparklines, agent selector | `moda overview --compare [--series] [--since=<ISO> --until=<ISO>] [--agent-name=<sub-agent>] [--unit=turn]` |
18
+ | Detector tab KPI tiles with deltas | `moda detections list --family=<f> --compare` (`summary.compare`) |
19
+ | Problem history per day | `moda problems get <problem_id> --trend [--days-back=N]` |
20
+ | Users page / user profile | `moda users [--window --cohort --sort --order --health-status]`, `moda user <id>` (`--cohort` takes `builtin:<key>`, a saved cohort id, or a bare built-in key) |
21
+ | Cohort selector on Problems, Traces, Signals tabs, custom signals, Topics | `--cohort=builtin:<key>\|<saved id>` on `problems list`, `traces list`, `detections list` (emotion, frustration and hallucination read the per-trace list; laziness; custom_signal `--signal-id`), `detections tools`, `clusters` (`--time-range=all\|3d\|7d\|30d`, also with `--search`). Output says which cohort scoped it (summary line and `cohort` in the data). `traces search` has no cohort scope |
22
+ | Cohort builder: list, fields, preview, compare, save, edit | `moda cohorts list [--include-archived]`, `get <ref>`, `fields`, `preview --file=<definition.json>`, `compare <a> <b> [--days=7\|30\|90]`, `create --name --file [--dry-run]`, `update <cohort_id> [--name --file --note] [--dry-run]` (archiving is dashboard-only) |
18
23
  | Tool catalog: every tool, its schema and usage | `moda tools list [--sort=calls\|failure_rate\|failures\|traces\|last_seen --search --direction --offset]`, `moda tools get <tool_name>` |
19
24
  | Problems list (dream grouping or Book, as the page decides): sort, cohort, page | `moda problems list [--sort=users --cohort=builtin:<key> --offset=N --list-version=V]`; `--view=book\|dream` forces one |
20
25
  | Problem page (dream view): severity, incidents with verdicts | `moda problems get <problem_id> --view=dream [--offset=N]` |
@@ -126,6 +126,26 @@ An empty detection list is not proof a trace is clean:
126
126
  pending or errored traces: a pending trace may already have some detections,
127
127
  but its detections may be incomplete.
128
128
 
129
+ ### 5c. Is a family getting worse? (`--compare`)
130
+
131
+ ```bash
132
+ moda detections list --family=frustration --compare --days-back=7
133
+ moda detections list --family=laziness:stub_body --compare
134
+ moda detections tools --compare --days-back=14
135
+ ```
136
+
137
+ `--compare` adds `summary.compare`, one more read (GET `/v1/data/trends`)
138
+ with the dashboard's KPI tiles for the family: `kpis` (for example emotion
139
+ analyzed traces, negative rate, negative detections, affected users and traces
140
+ per family) and `rate` (share of traces with a detection, the Signals rate
141
+ card; left out for `frustration` and a sub-family, since the card counts the
142
+ whole detector, and `notes` says so). Each figure is `{current, previous, delta, delta_pct, spike?}` for the
143
+ list's `--days-back` window against the window of equal length just before it.
144
+ It covers the whole family, so it rejects `--conversation-id` and `--user-id`;
145
+ other list filters do not narrow it. For a before/after-deploy window, or a
146
+ series per hour or day, use `moda overview --compare --since=<deploy time>`
147
+ and `--series` (see production-intelligence.md).
148
+
129
149
  ### 6. Tool failure investigation
130
150
 
131
151
  ```bash
@@ -12,6 +12,54 @@ moda overview --days-back=30
12
12
  Returns total traces, trend, frustration rate, tool failure summary,
13
13
  top clusters, recent activity.
14
14
 
15
+ #### Before/after and trends (`--compare`, `--series`)
16
+
17
+ ```bash
18
+ moda overview --compare # last 7 days against the 7 days before
19
+ moda overview --compare --since=2026-10-17T14:00:00Z # after a deploy against the same span before it
20
+ moda overview --compare --since=2026-10-10 --until=2026-10-12 # a fixed window against the one before it
21
+ moda overview --series --days-back=14 # adds [bucket, value] series (implies --compare)
22
+ moda overview --compare --agent-name=planner # one sub-agent (names in trends.agent.options)
23
+ moda overview --compare --unit=turn # rates per user turn (or segment) instead of per trace
24
+ ```
25
+
26
+ Adds `trends` (GET `/v1/data/trends`), read from the dashboard's own loaders.
27
+ The previous window is always the span of equal length just before the window,
28
+ as the dashboard defines it. So `--since=<deploy time>` (to now) compares after
29
+ the deploy with the same length of time before it. There is no separate
30
+ `--compare-to` flag: every dashboard loader computes "previous" this way.
31
+ `--days-back` and `--since` are exclusive; `--until` needs `--since`; a window
32
+ can be up to 90 days.
33
+
34
+ Each figure is `{current, previous, delta, delta_pct, spike?}`. `delta` is
35
+ current minus previous (percentage points for a `_pct` rate). `delta_pct` is the
36
+ relative change. `spike` is the dashboard's spike rule. Sections:
37
+
38
+ | Section | Dashboard source | Figures |
39
+ |---|---|---|
40
+ | `overview` | Analytics overview | traces, messages, negative emotion rate (per analyzed trace), failed tool calls (per call), ungrounded claims (per scored message); `n` gives numerator and denominator |
41
+ | `problems` | Problems trend card | analysed traces, traces with any signal, signal rate (`--days-back` only) |
42
+ | `rates` | Signals overview rate cards | each detector's share of units with a detection (`--unit=conversation\|segment\|turn`) |
43
+ | `detectors` | Detector tab KPI tiles | emotion (analyzed, negative rate, detections, affected users, traces per family), tool_failure (failed traces, classified failures, failure rate, calls, users, tools), laziness, hallucination |
44
+
45
+ The same detector can show different rates in different sections because each
46
+ uses its own denominator (`rate_note` says which). `detectors.tool_failure.failure_rate_pct`
47
+ counts classified failures per call and is higher than `overview.tool_failure_rate_pct`
48
+ (failed call records per call).
49
+
50
+ `--series` adds `trends.series`: compact `[bucket, value]` arrays, per hour for
51
+ windows up to 2 days and per day above. Bucket keys are `YYYY-MM-DD` or
52
+ `YYYY-MM-DDTHH:00Z`.
53
+
54
+ `--agent-name` scopes the `overview` section only. The Problems, rates and
55
+ detector loaders have no sub-agent filter, so those sections are left out and
56
+ `trends.notes` says so.
57
+
58
+ The `overview` section is the slow part: on a large workspace a 30-day window
59
+ can take about 40 seconds, and the CLI waits up to 90. A figure whose read
60
+ failed is `null` with `unavailable: true` (never zero), and `trends.notes`
61
+ names it.
62
+
15
63
  ### 2b. Ask & investigate (production intelligence)
16
64
 
17
65
  `moda ask` answers a natural-language production/harness question (a paid