@moda-ai/cli 1.9.6 → 1.10.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.
@@ -78,6 +78,87 @@ npx -p @moda-ai/cli moda <command>
78
78
  export MODA_API_KEY="moda_sk_..." # from moda.dev/settings
79
79
  ```
80
80
 
81
+ ## Agent protocol
82
+
83
+ `moda` is agent-safe: it picks an output mode automatically, signals how much
84
+ to trust an answer through exit codes, and (in agent mode) emits a
85
+ schema-versioned `moda.agent.v1` JSON envelope you can parse instead of
86
+ scraping prose.
87
+
88
+ ### Output mode auto-selection
89
+
90
+ The mode is resolved in this priority order — first match wins, so you usually
91
+ need no flags at all:
92
+
93
+ 1. **Explicit flags** override everything:
94
+ - `--agent` — `moda.agent.v1` schema-versioned JSON envelope
95
+ - `--json` — raw JSON payload (no envelope)
96
+ - `--agent --stream` — NDJSON stream of `moda.agent_event.v1` events
97
+ - `--human` — force human prose
98
+ 2. **`MODA_FORMAT` env var** — one of `human | json | agent | agent-stream`.
99
+ 3. **Agent-environment auto-detect** — if `CLAUDECODE`, `CURSOR`, `CI`, or
100
+ `MODA_AGENT` is set, default to the agent JSON envelope.
101
+ 4. **TTY auto-detect** — if stdout is not a TTY (piped or redirected), default
102
+ to the agent JSON envelope; an interactive terminal defaults to human prose.
103
+
104
+ Running `moda` from inside Claude Code / Cursor, in CI, or through a pipe
105
+ already yields agent JSON — no flag required.
106
+
107
+ ### Exit codes
108
+
109
+ Branch on the exit code; it is stable and cheaper than parsing the payload:
110
+
111
+ | Exit | Meaning | How to treat it |
112
+ |---|---|---|
113
+ | `0` | ok — answer is grounded in Moda Cloud intelligence | Trust it. |
114
+ | `3` | degraded — Moda Cloud was unavailable; answer synthesized from local Data API evidence | Answer is present but lower-trust; verify before acting. |
115
+ | `1` | error — bad input, unknown command, or unexpected failure | Read `errors[]` in the envelope. |
116
+
117
+ ### The `moda.agent.v1` envelope
118
+
119
+ Fields an agent should read:
120
+
121
+ - `status` — `ok` | `degraded` | `error`.
122
+ - `summary.text` + `summary.confidence` — the answer and how much to trust it
123
+ (`high | medium | low | unknown`).
124
+ - `evidence_refs[]` — each `{ id, kind, label, path }`. When `path` looks like
125
+ `conversation/<id>`, open it with `moda context <id>`.
126
+ - `next_commands[]` — suggested follow-up commands (each carries `mutability`
127
+ and `requires_approval`).
128
+ - `warnings[]`, `errors[]`.
129
+ - `data` — the raw command payload. For `ask`, `data.source` is `cloud` or
130
+ `local_fallback` and `data.degraded` is a boolean — the canonical in-payload
131
+ way to detect degradation (in addition to exit code 3).
132
+
133
+ ### Detecting a degraded answer
134
+
135
+ Treat an answer as degraded if **any** of these hold:
136
+
137
+ - exit code is `3`, **or**
138
+ - `data.degraded === true` (for `ask`; equivalently `data.source === "local_fallback"`), **or**
139
+ - `status === "degraded"`.
140
+
141
+ ### Schema introspection
142
+
143
+ ```bash
144
+ moda --json-schemas # print the JSON Schemas for the agent output contract
145
+ ```
146
+
147
+ ### Recommended agent usage
148
+
149
+ ```bash
150
+ answer=$(moda ask "what should I fix first?")
151
+ case $? in
152
+ 0) printf 'grounded answer:\n%s\n' "$answer" ;;
153
+ 3) printf 'DEGRADED (local fallback — verify before acting):\n%s\n' "$answer" ;;
154
+ *) echo "moda ask failed:"; echo "$answer" | jq -r '.errors[].message'; exit 1 ;;
155
+ esac
156
+
157
+ # Pull the trusted parts straight out of the envelope
158
+ echo "$answer" | jq -r '.summary.text'
159
+ echo "$answer" | jq -r '.evidence_refs[] | "\(.kind)\t\(.label)\t\(.path // "")"'
160
+ ```
161
+
81
162
  ## Procedure
82
163
 
83
164
  Two entry points depending on the question:
@@ -146,6 +227,47 @@ moda overview --days-back=30
146
227
  Returns total conversations, trend, frustration rate, tool failure summary,
147
228
  top clusters, recent activity.
148
229
 
230
+ ### 2b. Ask & investigate (production intelligence)
231
+
232
+ `moda ask` answers a natural-language production/harness question; `moda
233
+ investigate` returns a ranked, evidence-backed list of the issues worth fixing
234
+ first. Both default to the last 7 days (`--days-back=N`, 1–90).
235
+
236
+ ```bash
237
+ moda ask "what should I fix first?" # grounded answer + evidence
238
+ moda ask "why are refunds failing?" --days-back=30
239
+ moda investigate # ranked findings, last 7d
240
+ moda investigate --days-back=14
241
+ moda overview # health briefing (see §2)
242
+ ```
243
+
244
+ In an agent environment these emit the `moda.agent.v1` envelope (see
245
+ [Agent protocol](#agent-protocol)). For `ask`, branch on the exit code (`0`
246
+ grounded, `3` degraded, `1` error) and read `data.source` /
247
+ `data.degraded` to know whether the answer came from Moda Cloud or a local
248
+ Data API fallback. Abbreviated envelope:
249
+
250
+ ```json
251
+ {
252
+ "schema_version": "moda.agent.v1",
253
+ "command": "ask",
254
+ "status": "degraded",
255
+ "summary": { "text": "Strongest signal is: lookupCustomer is failing in production.", "confidence": "medium" },
256
+ "evidence_refs": [
257
+ { "id": "tool:lookupCustomer", "kind": "tool_failure", "label": "lookupCustomer: 12 failure(s)", "path": null }
258
+ ],
259
+ "next_commands": [
260
+ { "command": "moda tool-failure-detail lookupCustomer --include-window", "purpose": "Inspect tool failure examples and conversation anchors.", "mutability": "read", "requires_approval": false }
261
+ ],
262
+ "warnings": ["Cloud ask endpoint unavailable; synthesized answer from local Data API evidence."],
263
+ "errors": [],
264
+ "data": { "source": "local_fallback", "degraded": true, "question": "what should I fix first?", "answer": "…", "confidence": "medium" }
265
+ }
266
+ ```
267
+
268
+ `moda investigate` also accepts scoping flags (`--tool`, `--run`,
269
+ `--conversation`, `--loop`) to focus the ranking on one signal.
270
+
149
271
  ### 3. Browse topic clusters
150
272
 
151
273
  ```bash
@@ -178,6 +300,27 @@ moda context <conversation_id> --msg-index=5 # center on message 5
178
300
  moda context <conversation_id> --window=3 # 3 messages each side (max 5)
179
301
  ```
180
302
 
303
+ `moda context` is turn-windowed (≤5 turns, deduped, no tool spans). For the raw,
304
+ complete picture of what was captured — every span, the parent/child hierarchy,
305
+ tool calls, prompt/response bodies, and `gen_ai.*` attributes — use `moda audit`.
306
+
307
+ ### 4b. Audit raw spans/trace (completeness, orphans, duplicates)
308
+
309
+ ```bash
310
+ moda audit <conversation_id|trace_id> # auto-detects trace vs conversation
311
+ moda audit <trace_id> --kind=trace # force trace lookup
312
+ moda audit <conversation_id> --include-raw # attach verbatim raw_event bodies
313
+ ```
314
+
315
+ Returns the raw, NON-deduped span set from the Layer-0 store (`events_raw`), so
316
+ nothing is collapsed. Use it to verify capture completeness: the `summary` gives
317
+ `total_spans`, `by_type` (llm/tool/agent/…), plus `orphan_count` (spans whose
318
+ parent is missing) and `duplicate_count` (double-instrumentation — the same
319
+ logical call emitted as >1 span). Each span carries `span_id`, `parent_span_id`,
320
+ `trace_id`, `type` (tool spans included), timing, `prompt`, `response`, and the
321
+ full semconv `attributes`. This is the honest substrate for auditing whether
322
+ Moda captured every LLM/tool call for a conversation.
323
+
181
324
  ### 5. Frustration analysis
182
325
 
183
326
  ```bash
@@ -393,6 +536,9 @@ moda tool-failures | jq '.tools[] | {tool: .tool_name, failures: .failure_count}
393
536
  ## Validation — how to know it worked
394
537
 
395
538
  - Every successful command exits 0 and prints valid JSON to stdout.
539
+ - `moda ask` / `moda investigate` may exit `3` (degraded): a real,
540
+ lower-trust answer synthesized from local evidence — not a failure. Treat
541
+ exit `1` as the only hard error (see [Agent protocol](#agent-protocol)).
396
542
  - Errors print to stderr with non-zero exit. Check stderr before claiming
397
543
  success.
398
544
  - If the JSON has `"conversations": []` or `"frustrations": []`, the call
@@ -441,6 +587,8 @@ npx: `npx -p @moda-ai/cli moda <command>`.
441
587
  | `moda init` | Browser auth + provision API key + install agent rules |
442
588
  | `moda search "<query>"` | **Message-grain semantic/keyword/hybrid search (incl. tool calls); primary content-discovery path** |
443
589
  | `moda overview` | Dashboard KPIs, top clusters, recent activity |
590
+ | `moda ask "<question>"` | Natural-language production/harness answer with evidence (exit `3` = degraded local fallback) |
591
+ | `moda investigate` | Rank production issues with evidence + next commands |
444
592
  | `moda clusters` | Browse topic cluster hierarchy |
445
593
  | `moda cluster-conversations <node_id>` | Conversations in a cluster |
446
594
  | `moda conversations` | List/filter conversations by structured fields |