@moda-ai/cli 1.24.0 → 1.26.0

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/README.md CHANGED
@@ -34,49 +34,87 @@ Get your API key from [moda.dev/settings](https://moda.dev/settings).
34
34
 
35
35
  ## Usage
36
36
 
37
+ Find things by meaning, then drill in:
38
+
37
39
  ```bash
38
- moda overview # Dashboard overview
39
- moda overview --days-back=30 # Last 30 days
40
+ moda search "user wants a refund" --mode=semantic # Semantic/keyword/hybrid message search
41
+ moda search "stripe.charges.create" --mode=keyword # Exact identifiers, incl. tool calls
42
+ moda search "checkout" --include-tool-io # Search tool inputs/outputs too
43
+ moda context <conversation_id> --msg-index=5 # Read the exact turn
44
+ moda audit <conversation_id|trace_id> # Raw span/trace audit
45
+ ```
40
46
 
41
- moda clusters # Browse topic clusters
42
- moda clusters --parent-id=node-abc # Drill into a category
47
+ Production intelligence:
43
48
 
44
- moda cluster-conversations <node_id> # Conversations in a cluster
49
+ ```bash
50
+ moda overview --days-back=30 # Health briefing (KPIs, clusters, activity)
51
+ moda ask "what should I fix first?" # Grounded answer with evidence
52
+ moda investigate # Ranked issues worth fixing
53
+ moda problems # Cross-signal Problems by root cause
54
+ moda problem <problem_id> # One Problem: full dossier
55
+ moda problem <problem_id> --evidence # ...attribution evidence (keyset paged)
56
+ moda problem <problem_id> --reports # ...investigation reports
57
+ moda problem <problem_id> --conversations # ...affected conversations
58
+ moda problem-feedback <problem_id> --action=mark_fixed # Close the loop from the terminal
59
+ ```
45
60
 
46
- moda conversations --search="error" # Search conversations
47
- moda conversations --time-range=24h # Filter by time
48
- moda conversations --environment=production # Filter by environment
61
+ Signals:
49
62
 
50
- moda context <conversation_id> # Get conversation context
51
- moda context <conversation_id> --msg-index=5 # Center on message 5
63
+ ```bash
64
+ moda emotions --family=confusion # Multi-family emotion detections
65
+ moda hallucinations --kind=contradicted # Grounding: contradicted/verified outputs
66
+ moda frustrations --include-window --window=1 # Legacy single-family frustration view
67
+ moda tool-failures # Tool failure overview
68
+ moda tool-failure-detail <tool_name> --include-window
69
+ moda step-scores <conversation_id> # Graph-PRM per-step reward curves
70
+ ```
52
71
 
53
- moda frustrations # User frustration detections
54
- moda frustrations --days-back=14 --limit=20
55
- moda frustrations --include-window --window=1 # Attach 3-message slice per row
72
+ Conversations, clusters, memory:
56
73
 
57
- moda tool-failures # Tool failure overview
58
- moda tool-failure-detail <tool_name> # Per-tool failure detail
59
- moda tool-failure-detail <tool_name> --include-window --window=1
74
+ ```bash
75
+ moda conversations --search="error" --environment=production
76
+ moda clusters # Walk the topic hierarchy
77
+ moda clusters --search="billing disputes" # Find a cluster by meaning
78
+ moda world-state <conversation_id> # Agent memory (slots/threads/events)
79
+ moda world-state <id> --snapshot --msg-index=42 # What the agent believed at turn 42
80
+ moda world-state <id> --replay --message-count=50 # State evolution frame by frame
81
+ ```
60
82
 
61
- moda feedback "cluster label looks wrong" # Help us improve: flag wrong/missing data
62
- moda feedback "..." --category=missing_data --conversation-id=<id>
83
+ Live tail (one JSON line per new item — `tail -f` for your agent):
63
84
 
64
- # Prompt management
85
+ ```bash
86
+ moda tail # New conversations, every 15s
87
+ moda tail --signal=all --interval=30 # Conversations + emotion detections
88
+ ```
89
+
90
+ Prompt management:
91
+
92
+ ```bash
65
93
  moda prompts init # Create .moda/prompts.yml
66
94
  moda prompts status # Read-only local prompt status
67
- moda prompts diff # Read-only local prompt diff/status
68
95
  moda prompts sync # Upload changed prompt versions
69
- moda prompts sync --watch # Sync when local prompt hashes change
70
96
  moda prompts promote support.triage --label=prod --version=pver_abc123
71
97
  ```
72
98
 
73
- All commands output JSON. Pipe to `jq` for filtering:
99
+ Feedback:
74
100
 
75
101
  ```bash
76
- moda overview | jq '.frustrations'
77
- moda frustrations | jq '.frustrations[].primary_cause'
102
+ moda feedback "cluster label looks wrong" --category=bad_cluster_label
78
103
  ```
79
104
 
105
+ Output adapts to where it runs: piped/CI/agent environments get schema-versioned
106
+ JSON (`moda.agent.v1`), an interactive terminal gets human prose. Force a mode
107
+ with `--json`, `--agent`, or `--human`. In JSON modes, pipe to `jq`:
108
+
109
+ ```bash
110
+ moda overview | jq '.data.metrics'
111
+ moda frustrations | jq '.data.frustrations[].primary_cause'
112
+ ```
113
+
114
+ Every command supports `moda <command> --help` for scoped usage, and
115
+ `moda manifest --json` describes the full machine protocol (commands, exit
116
+ codes, event schema) for agents.
117
+
80
118
  ## Prompt Management
81
119
 
82
120
  Prompt management is code-first. Keep prompts in `prompts/**/*.prompt.md` or
@@ -1301,6 +1301,19 @@ function createAgentEvent(command, event, state) {
1301
1301
  };
1302
1302
  return redactDeep(stamped);
1303
1303
  }
1304
+ function formatValidationMessage(error) {
1305
+ const issues = error.issues;
1306
+ if (error.name !== "ZodError" || !Array.isArray(issues) || issues.length === 0) {
1307
+ return error.message;
1308
+ }
1309
+ const parts = issues.map((issue) => {
1310
+ const record = issue;
1311
+ const path = Array.isArray(record.path) && record.path.length > 0 ? record.path.join(".") : "input";
1312
+ const message = typeof record.message === "string" ? record.message : "is invalid";
1313
+ return `${path}: ${message}`;
1314
+ });
1315
+ return `Validation error — ${parts.join("; ")}`;
1316
+ }
1304
1317
  function errorToAgentError(error) {
1305
1318
  if (error instanceof CliInputRequiredError) {
1306
1319
  return {
@@ -1344,7 +1357,7 @@ function errorToAgentError(error) {
1344
1357
  if (error instanceof CliInputError || error.name === "ZodError") {
1345
1358
  return {
1346
1359
  code: "input_error",
1347
- message: error.message,
1360
+ message: formatValidationMessage(error),
1348
1361
  cause: "usage" in error && typeof error.usage === "string" ? error.usage : undefined,
1349
1362
  suggested_commands: "usage" in error && typeof error.usage === "string" ? extractSuggestedCommands(error.usage) : undefined,
1350
1363
  blocking: true
@@ -8,7 +8,7 @@ import {
8
8
  saveProfileConfig,
9
9
  secretFilePathFromRef,
10
10
  writeSecretJsonFile
11
- } from "./cli-vc7zddj1.js";
11
+ } from "./cli-59yacef3.js";
12
12
 
13
13
  // src/auth-storage.ts
14
14
  import { existsSync, readFileSync, rmSync } from "node:fs";
@@ -23,7 +23,7 @@ import {
23
23
  resolveTenantId,
24
24
  shouldInventoryFile,
25
25
  stringOption
26
- } from "./cli-vc7zddj1.js";
26
+ } from "./cli-59yacef3.js";
27
27
 
28
28
  // src/api-client.ts
29
29
  var REQUEST_TIMEOUT_MS = 30000;
@@ -3314,6 +3314,17 @@ async function runHarnessCommand(context) {
3314
3314
  return { exitCode: 0 };
3315
3315
  }
3316
3316
  case "analyze": {
3317
+ const cliAnalyzeEnabled = context.flags["experimental"] === "true" || process.env.MODA_HARNESS_ANALYZE_CLI === "1";
3318
+ if (!cliAnalyzeEnabled) {
3319
+ context.output.writeData({
3320
+ schema: "harness_analyze_disabled.v0.1",
3321
+ status: "disabled",
3322
+ reason: "cli_analyze_gated",
3323
+ message: "Harness analysis now runs automatically via the Moda GitHub App — connect your repo in the Moda dashboard (Settings → Integrations). To run the experimental CLI analyze anyway, pass --experimental or set MODA_HARNESS_ANALYZE_CLI=1."
3324
+ });
3325
+ writeHumanProgress(context, "moda harness analyze is disabled: connect the Moda GitHub App (Settings → Integrations) for automatic analysis, or pass --experimental to run the CLI analyze.");
3326
+ return { exitCode: 1 };
3327
+ }
3317
3328
  await approveScanIfNeeded(scanPlan, {
3318
3329
  context,
3319
3330
  message: "Run Moda Analyst to investigate this project and produce a cited harness report?",
@@ -3327,7 +3338,7 @@ async function runHarnessCommand(context) {
3327
3338
  elapsed_ms: Date.now() - context.startedAt
3328
3339
  });
3329
3340
  if (context.flags["github-actions"] === "true") {
3330
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-ar3sfmqq.js");
3341
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-ct8fwzdr.js");
3331
3342
  const result = await runGithubActionsAnalyze(rootDir, {
3332
3343
  writeReport: (report2) => {
3333
3344
  const normalized = normalizeHarnessReport(report2);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  authFetch,
3
3
  getCachedLoginContext
4
- } from "./cli-8s69sg7f.js";
4
+ } from "./cli-9xw5bq1j.js";
5
5
  import {
6
6
  CliAccessError,
7
7
  CliInputError,
@@ -15,7 +15,7 @@ import {
15
15
  resolveTenantIdFromActiveProfile,
16
16
  saveCliConfig,
17
17
  writeSecretJsonFile
18
- } from "./cli-vc7zddj1.js";
18
+ } from "./cli-59yacef3.js";
19
19
 
20
20
  // src/init/tenant.ts
21
21
  import { randomUUID } from "node:crypto";
@@ -11,11 +11,11 @@ import {
11
11
  renderStatusHuman,
12
12
  scanHarness,
13
13
  validateHarnessReport
14
- } from "./cli-f2f0twjw.js";
14
+ } from "./cli-g931ntph.js";
15
15
  import {
16
16
  isAuthSessionValid,
17
17
  loadAuthSession
18
- } from "./cli-8s69sg7f.js";
18
+ } from "./cli-9xw5bq1j.js";
19
19
  import {
20
20
  CliInputError,
21
21
  createCommandContext,
@@ -31,7 +31,7 @@ import {
31
31
  resolveTenantId,
32
32
  secretFilePathFromRef,
33
33
  validateConfig
34
- } from "./cli-vc7zddj1.js";
34
+ } from "./cli-59yacef3.js";
35
35
 
36
36
  // src/prompts.ts
37
37
  import { execFileSync } from "node:child_process";
@@ -2397,7 +2397,7 @@ function harnessReportStateCheck(cwd) {
2397
2397
  severity: "warning",
2398
2398
  evidence: [{ label: "path", value: HARNESS_REPORT_PATH }],
2399
2399
  remediation: "Run a Moda Analyst pass so the harness graph has cited evidence before cloud sync.",
2400
- nextCommand: "moda harness analyze --summary"
2400
+ nextCommand: "moda harness analyze --experimental --summary"
2401
2401
  };
2402
2402
  }
2403
2403
  try {
@@ -2421,7 +2421,7 @@ function harnessReportStateCheck(cwd) {
2421
2421
  { label: "errors", value: validation.errors.slice(0, 3).join(" | ") || "validation failed" }
2422
2422
  ],
2423
2423
  remediation: "Regenerate or fix the harness report before approving or syncing.",
2424
- nextCommand: "moda harness analyze --summary"
2424
+ nextCommand: "moda harness analyze --experimental --summary"
2425
2425
  };
2426
2426
  }
2427
2427
  const approval = readHarnessReportApproval(cwd);
@@ -2476,7 +2476,7 @@ function harnessReportStateCheck(cwd) {
2476
2476
  { label: "error", value: err instanceof Error ? err.message : String(err) }
2477
2477
  ],
2478
2478
  remediation: "Regenerate the harness report.",
2479
- nextCommand: "moda harness analyze --summary"
2479
+ nextCommand: "moda harness analyze --experimental --summary"
2480
2480
  };
2481
2481
  }
2482
2482
  }