@moda-ai/cli 1.1.1 → 1.3.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 +36 -0
- package/dist/agent.d.ts +5 -0
- package/dist/agent.js +477 -0
- package/dist/analyst-tui.d.ts +81 -0
- package/dist/analyst-tui.js +314 -0
- package/dist/api-client.d.ts +4 -0
- package/dist/api-client.js +20 -3
- package/dist/auth.d.ts +22 -3
- package/dist/auth.js +230 -66
- package/dist/cli.d.ts +20 -3
- package/dist/cli.js +745 -93
- package/dist/command-context.d.ts +34 -0
- package/dist/command-context.js +38 -0
- package/dist/command-registry.d.ts +22 -0
- package/dist/command-registry.js +15 -0
- package/dist/config.d.ts +40 -1
- package/dist/config.js +70 -3
- package/dist/doctor.d.ts +79 -0
- package/dist/doctor.js +1111 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +9 -0
- package/dist/harness-report.d.ts +138 -0
- package/dist/harness-report.js +1464 -0
- package/dist/harness.d.ts +233 -0
- package/dist/harness.js +3264 -0
- package/dist/init/index.d.ts +30 -1
- package/dist/init/index.js +389 -23
- package/dist/init/rules.d.ts +5 -1
- package/dist/init/rules.js +22 -16
- package/dist/init/sdk-guide.d.ts +3 -0
- package/dist/init/sdk-guide.js +397 -0
- package/dist/init/tenant.js +12 -3
- package/dist/keys.d.ts +47 -0
- package/dist/keys.js +136 -0
- package/dist/output.d.ts +118 -0
- package/dist/output.js +228 -0
- package/dist/production-intelligence.d.ts +134 -0
- package/dist/production-intelligence.js +1113 -0
- package/dist/profile-commands.d.ts +10 -0
- package/dist/profile-commands.js +252 -0
- package/dist/profiles.d.ts +90 -0
- package/dist/profiles.js +432 -0
- package/dist/prompts.d.ts +6 -0
- package/dist/prompts.js +368 -0
- package/dist/schemas.d.ts +4 -4
- package/dist/skills.d.ts +25 -0
- package/dist/skills.js +468 -0
- package/dist/sync.d.ts +5 -0
- package/dist/sync.js +27 -0
- package/dist/telemetry.d.ts +18 -0
- package/dist/telemetry.js +63 -0
- package/dist/tui.d.ts +40 -0
- package/dist/tui.js +387 -0
- package/dist/workspace.d.ts +12 -0
- package/dist/workspace.js +1294 -0
- package/hooks/moda-snapshot.sh +41 -0
- package/package.json +10 -7
- package/skills/moda-cli/SKILL.md +48 -4
- package/skills/integrate-moda/SKILL.md +0 -63
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Moda shadow workspace hook for coding agents.
|
|
3
|
+
# Triggered by Claude Code, Codex, and Cursor lifecycle/tool matchers.
|
|
4
|
+
#
|
|
5
|
+
# Claude Code passes hook context as a JSON object on stdin (per the Claude
|
|
6
|
+
# Code hooks reference): session_id, tool_use_id, prompt, hook_event_name,
|
|
7
|
+
# etc. We forward that stdin straight through to `moda workspace snapshot
|
|
8
|
+
# --hook-stdin`, which parses it server-side so the CLI sees the same
|
|
9
|
+
# correlation keys (session_id, tool_use_id, prompt_sha) the ingest worker
|
|
10
|
+
# will later join on. The previous version read $CLAUDE_SESSION_ID and
|
|
11
|
+
# $CLAUDE_PROMPT_HASH env vars, but Claude never sets those — so session_id
|
|
12
|
+
# and prompt-level joins were unrecoverable. Reading stdin fixes that.
|
|
13
|
+
#
|
|
14
|
+
# Runs `moda workspace snapshot` in the background so the hook never blocks
|
|
15
|
+
# Claude; redirects all output to /dev/null so user-visible output stays
|
|
16
|
+
# clean; always exits 0 so a transient failure can't break the user session.
|
|
17
|
+
|
|
18
|
+
set +e
|
|
19
|
+
case "${1:-}" in
|
|
20
|
+
claude|claude_code|codex|cursor)
|
|
21
|
+
PROVIDER="$1"
|
|
22
|
+
EVENT="${2:-UserPromptSubmit}"
|
|
23
|
+
;;
|
|
24
|
+
*)
|
|
25
|
+
PROVIDER="claude_code"
|
|
26
|
+
EVENT="${1:-UserPromptSubmit}"
|
|
27
|
+
;;
|
|
28
|
+
esac
|
|
29
|
+
MODA_SNAPSHOT_BIN="${MODA_BIN:-moda}"
|
|
30
|
+
|
|
31
|
+
# Buffer the hook JSON once so the background subshell sees it after this
|
|
32
|
+
# script's stdin is closed by Claude.
|
|
33
|
+
PAYLOAD="$(cat)"
|
|
34
|
+
|
|
35
|
+
(
|
|
36
|
+
printf '%s' "$PAYLOAD" \
|
|
37
|
+
| "$MODA_SNAPSHOT_BIN" workspace snapshot --provider "$PROVIDER" --event "$EVENT" --json --hook-stdin \
|
|
38
|
+
> /dev/null 2>&1
|
|
39
|
+
) &
|
|
40
|
+
|
|
41
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moda-ai/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "CLI for Moda - AI agent analytics and observability",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"dist/**/*.js",
|
|
12
12
|
"dist/**/*.d.ts",
|
|
13
13
|
"!dist/__tests__",
|
|
14
|
+
"hooks/**",
|
|
14
15
|
"skills/**/SKILL.md",
|
|
15
16
|
"README.md",
|
|
16
17
|
".env.example"
|
|
@@ -20,16 +21,16 @@
|
|
|
20
21
|
},
|
|
21
22
|
"scripts": {
|
|
22
23
|
"build": "tsc",
|
|
23
|
-
"prepublishOnly": "tsc",
|
|
24
24
|
"dev": "tsc --watch",
|
|
25
25
|
"typecheck": "tsc --noEmit",
|
|
26
26
|
"test": "vitest run",
|
|
27
|
-
"test:
|
|
28
|
-
"
|
|
27
|
+
"test:watch": "vitest",
|
|
28
|
+
"lint": "eslint ."
|
|
29
29
|
},
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
32
|
-
"url": "https://github.com/ModaLabs/
|
|
32
|
+
"url": "https://github.com/ModaLabs/modaobservability.git",
|
|
33
|
+
"directory": "apps/moda-cli"
|
|
33
34
|
},
|
|
34
35
|
"keywords": [
|
|
35
36
|
"moda",
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
"license": "MIT",
|
|
44
45
|
"homepage": "https://docs.moda.dev/data-api/cli",
|
|
45
46
|
"bugs": {
|
|
46
|
-
"url": "https://github.com/ModaLabs/
|
|
47
|
+
"url": "https://github.com/ModaLabs/ModaObservability/issues"
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
49
50
|
"@inquirer/prompts": "^8.4.1",
|
|
@@ -51,9 +52,11 @@
|
|
|
51
52
|
"zod": "^3.24.1"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
55
|
+
"@moda/eslint-config": "*",
|
|
54
56
|
"@types/node": "^22.10.5",
|
|
57
|
+
"eslint": "^9.17.0",
|
|
55
58
|
"typescript": "^5.7.2",
|
|
56
|
-
"vitest": "^
|
|
59
|
+
"vitest": "^4.0.14"
|
|
57
60
|
},
|
|
58
61
|
"engines": {
|
|
59
62
|
"node": ">=18.0.0"
|
package/skills/moda-cli/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: moda-cli
|
|
3
|
-
description: Query Moda's AI agent conversation analytics from the terminal — overview KPIs, topic clusters, conversation search, message context, user frustration detections, tool failures, agent jobs
|
|
3
|
+
description: Query Moda's AI agent conversation analytics and manage code-first prompt versions from the terminal — overview KPIs, topic clusters, conversation search, message context, user frustration detections, tool failures, agent jobs, recurring workflows, active loop detections, and moda prompts status/sync/promote. Use when the user asks about moda, modaflows, conversation analytics, prompt management, user frustrations, agent observability, tool failure debugging, why an agent run partially completed or looped, or wants to investigate how their AI agent is performing.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Moda CLI
|
|
@@ -9,7 +9,9 @@ description: Query Moda's AI agent conversation analytics from the terminal —
|
|
|
9
9
|
|
|
10
10
|
Wraps the `moda` CLI so the agent can query a Moda tenant's conversation
|
|
11
11
|
analytics directly. Every command returns JSON on stdout; pipe to `jq` to
|
|
12
|
-
filter.
|
|
12
|
+
filter. Analytics commands are read-only. Prompt management includes both
|
|
13
|
+
read-only commands (`prompts status`, `prompts diff`) and commands that sync
|
|
14
|
+
or promote remote state (`prompts sync`, `prompts promote`).
|
|
13
15
|
|
|
14
16
|
## When to use
|
|
15
17
|
|
|
@@ -20,10 +22,13 @@ Activate this skill when the user wants to:
|
|
|
20
22
|
- Investigate which tools are failing and why
|
|
21
23
|
- Browse conversation topics (clusters)
|
|
22
24
|
- Search conversations by content, user, environment, or time range
|
|
25
|
+
- Manage code-first prompt versions when the user explicitly asks for prompt
|
|
26
|
+
sync, prompt status, or prompt promotion
|
|
23
27
|
|
|
24
28
|
**Do not** activate for: writing code that calls the Moda Data API directly
|
|
25
|
-
(use the API docs instead),
|
|
26
|
-
|
|
29
|
+
(use the API docs instead), changing application instrumentation unless the
|
|
30
|
+
user explicitly asks for SDK setup, or modifying prompt registry state unless
|
|
31
|
+
the user specifically asked for `moda prompts sync` or `moda prompts promote`.
|
|
27
32
|
|
|
28
33
|
## Required inputs
|
|
29
34
|
|
|
@@ -196,6 +201,41 @@ agent re-ran the same action 378 times. Use the `loop_signature_human`
|
|
|
196
201
|
field to recognize cross-conversation patterns (one tool definition bug
|
|
197
202
|
will produce identical signatures across many users).
|
|
198
203
|
|
|
204
|
+
### 10. Prompt management
|
|
205
|
+
|
|
206
|
+
Use these only when working on the code-first prompt registry.
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
moda prompts init # create .moda/prompts.yml
|
|
210
|
+
moda prompts status # read-only local status
|
|
211
|
+
moda prompts diff # read-only local diff/status
|
|
212
|
+
moda prompts sync # upload changed prompt versions
|
|
213
|
+
moda prompts sync --watch # sync when local prompt hashes change
|
|
214
|
+
moda prompts promote support.triage --label=prod --version=pver_abc123
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
`status` and `diff` are read-only. `sync` uploads prompt versions and writes
|
|
218
|
+
`.moda/prompts.lock.json`. `promote` moves a remote `dev`, `staging`, or
|
|
219
|
+
`prod` label to an existing version.
|
|
220
|
+
|
|
221
|
+
Runtime code should render synced prompts through the SDK:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
const rendered = Moda.prompt("support.triage").render({
|
|
225
|
+
ticket: { text: userMessage },
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
rendered = moda.prompt("support.triage").render({
|
|
231
|
+
"ticket": {"text": user_message},
|
|
232
|
+
})
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Do not copy prompt text from the dashboard into source code. The repo prompt
|
|
236
|
+
files are the source of truth; the dashboard is for visibility, usage, labels,
|
|
237
|
+
and future evals.
|
|
238
|
+
|
|
199
239
|
## Common workflow recipes
|
|
200
240
|
|
|
201
241
|
### Daily health check
|
|
@@ -314,6 +354,10 @@ npx: `npx -p @moda-ai/cli moda <command>`.
|
|
|
314
354
|
| `moda run <run_id>` | One execution + its side-effect receipts |
|
|
315
355
|
| `moda loops` | Currently-active loop detections |
|
|
316
356
|
| `moda loop <detection_id>` | One loop signature with blast radius |
|
|
357
|
+
| `moda prompts status` | Read-only local prompt status |
|
|
358
|
+
| `moda prompts diff` | Read-only local prompt diff/status |
|
|
359
|
+
| `moda prompts sync` | Upload changed prompt versions and update lockfile |
|
|
360
|
+
| `moda prompts promote <key>` | Move a remote prompt label |
|
|
317
361
|
|
|
318
362
|
Common flags across most commands: `--days-back=N` (1–90), `--limit=N`,
|
|
319
363
|
`--offset=N`, `--time-range=<range>`. Runs commands also accept
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: integrate-moda
|
|
3
|
-
description: Integrate the Moda SDK into this project for LLM observability. Use when the user asks to add Moda, set up observability, or instrument LLM calls.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Integrate Moda SDK
|
|
7
|
-
|
|
8
|
-
Moda auto-instruments LLM calls (OpenAI, Anthropic) via OpenTelemetry.
|
|
9
|
-
After `Moda.init()`, all LLM calls are captured automatically — no wrappers needed.
|
|
10
|
-
|
|
11
|
-
## Steps
|
|
12
|
-
|
|
13
|
-
1. Install the SDK: `npm install moda-ai` (or bun/yarn/pnpm equivalent)
|
|
14
|
-
2. Ensure `MODA_API_KEY` is set in the environment
|
|
15
|
-
3. Initialize once at app startup, before any LLM client is created:
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
import { Moda } from 'moda-ai';
|
|
19
|
-
await Moda.init(process.env.MODA_API_KEY!);
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Python: `import moda; moda.init()`
|
|
23
|
-
|
|
24
|
-
4. Set conversation ID before LLM calls to group multi-turn conversations.
|
|
25
|
-
Without this, each call appears as a separate conversation in the dashboard.
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
Moda.conversationId = sessionId;
|
|
29
|
-
Moda.userId = userId; // optional but recommended
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
For concurrent requests, use scoped context:
|
|
33
|
-
```typescript
|
|
34
|
-
import { withConversationId } from 'moda-ai';
|
|
35
|
-
await withConversationId(sessionId, async () => {
|
|
36
|
-
await openai.chat.completions.create({ ... });
|
|
37
|
-
});
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Python: `moda.conversation_id = session_id` or `with moda.set_conversation_id(session_id):`
|
|
41
|
-
|
|
42
|
-
5. Flush pending traces before process exit: `await Moda.flush();`
|
|
43
|
-
|
|
44
|
-
## Vercel AI SDK
|
|
45
|
-
|
|
46
|
-
When using the `ai` package, auto-instrumentation does not cover it. Pass telemetry config:
|
|
47
|
-
```typescript
|
|
48
|
-
const result = await generateText({
|
|
49
|
-
model: openai('gpt-4o'),
|
|
50
|
-
prompt: 'Hello',
|
|
51
|
-
experimental_telemetry: Moda.getVercelAITelemetry(),
|
|
52
|
-
});
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Rules
|
|
56
|
-
|
|
57
|
-
- Initialize Moda before creating any LLM client instances
|
|
58
|
-
- Place `Moda.init()` in the app entry point, not in individual route handlers
|
|
59
|
-
- Set `conversationId` per request/session, not globally
|
|
60
|
-
- Use `withConversationId` in server environments handling concurrent requests
|
|
61
|
-
- Call `Moda.flush()` in graceful shutdown handlers and before `process.exit()`
|
|
62
|
-
- Do not wrap LLM calls — auto-instrumentation handles OpenAI and Anthropic automatically
|
|
63
|
-
- Do not import or configure OpenTelemetry manually — Moda manages its own provider
|