@moda-ai/cli
v1.22.0
Published
CLI for Moda - AI agent analytics and observability
Downloads
6,781
Maintainers
Readme
moda-cli
CLI for Moda -- AI agent analytics and observability.
Query your conversation analytics from the terminal.
Install
npm install -g @moda-ai/cliOr use without installing:
npx -p @moda-ai/cli moda overviewSetup
Run the wizard to authenticate, pick an org, and provision an API key:
moda initOr set the key manually:
export MODA_API_KEY="moda_sk_..."Get your API key from moda.dev/settings.
Usage
moda overview # Dashboard overview
moda overview --days-back=30 # Last 30 days
moda clusters # Browse topic clusters
moda clusters --parent-id=node-abc # Drill into a category
moda cluster-conversations <node_id> # Conversations in a cluster
moda conversations --search="error" # Search conversations
moda conversations --time-range=24h # Filter by time
moda conversations --environment=production # Filter by environment
moda context <conversation_id> # Get conversation context
moda context <conversation_id> --msg-index=5 # Center on message 5
moda frustrations # User frustration detections
moda frustrations --days-back=14 --limit=20
moda frustrations --include-window --window=1 # Attach 3-message slice per row
moda tool-failures # Tool failure overview
moda tool-failure-detail <tool_name> # Per-tool failure detail
moda tool-failure-detail <tool_name> --include-window --window=1
moda feedback "cluster label looks wrong" # Help us improve: flag wrong/missing data
moda feedback "..." --category=missing_data --conversation-id=<id>
# Prompt management
moda prompts init # Create .moda/prompts.yml
moda prompts status # Read-only local prompt status
moda prompts diff # Read-only local prompt diff/status
moda prompts sync # Upload changed prompt versions
moda prompts sync --watch # Sync when local prompt hashes change
moda prompts promote support.triage --label=prod --version=pver_abc123All commands output JSON. Pipe to jq for filtering:
moda overview | jq '.frustrations'
moda frustrations | jq '.frustrations[].primary_cause'Prompt Management
Prompt management is code-first. Keep prompts in prompts/**/*.prompt.md or
prompts/**/*.prompt.json, sync them with the CLI, and render them through the
SDK so LLM spans include prompt metadata.
moda prompts init
moda prompts status
moda prompts syncstatus and diff are read-only. sync uploads changed versions and writes
.moda/prompts.lock.json. promote moves a remote dev, staging, or prod
label.
const rendered = Moda.prompt("support.triage").render({
ticket: { text: userMessage },
});rendered = moda.prompt("support.triage").render({
"ticket": {"text": user_message},
})Anchors and message windows
Rows returned by moda frustrations and moda tool-failure-detail carry
a top-level anchor block naming the exact turn the event fired on:
// frustrations
{ "kind": "frustration", "conversation_id": "...", "msg_index": 12,
"signal": "exasperation", "quote_preview": "...", "all_turns": [...],
"no_anchor": false }
// tool-failure-detail examples
{ "kind": "tool_failure", "conversation_id": "...", "msg_index": 7,
"tool_name": "search", "tool_use_id": "...",
"error_subtype": "SEARCH_NO_RESULTS", "no_anchor": false }msg_index is the 0-indexed turn where the breakage happened. For
frustrations it's derived from key_turns[0] (the same turn the API centers
the embedded window on), falling back to user_quotes[0].turn when
key_turns is empty. no_anchor: true means no anchor could be derived for
that row.
Both commands accept two flags to inline a message window per row:
| Flag | Default | Description |
|------|---------|-------------|
| --include-window | off | Attach a window field with the message slice centered on the anchor |
| --window=N | 1 | Half-width (1–5). --window=1 ⇒ 3 messages total (anchor ± 1) |
Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| MODA_API_KEY | Yes | -- | Your Moda API key (moda_sk_...) |
| MODA_BASE_URL | No | https://moda.dev | Base URL for the Data API |
Documentation
License
MIT
