@moda-ai/cli 1.55.27 → 1.55.29

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 (43) hide show
  1. package/dist/{agent-vp9prdma.js → agent-0w9rtdsw.js} +22 -16
  2. package/dist/cli-3n0gz4d0.js +17971 -0
  3. package/dist/{cli-q9nsvqqg.js → cli-3retgh64.js} +85 -1165
  4. package/dist/{cli-ccjfwzqx.js → cli-97jew729.js} +1 -1
  5. package/dist/{cli-r5pp7qny.js → cli-99p2jh28.js} +42 -456
  6. package/dist/{cli-0pkc8jhg.js → cli-9bgk5jeh.js} +8 -6
  7. package/dist/{cli-hmjdgxrn.js → cli-9bgnvth2.js} +5 -3
  8. package/dist/cli-9kfxkxmk.js +6994 -0
  9. package/dist/cli-cesds766.js +1516 -0
  10. package/dist/{cli-v8q7sd7g.js → cli-dr6x0zv7.js} +1 -1
  11. package/dist/{cli-pg5qfmqc.js → cli-e23g9ywa.js} +1 -1
  12. package/dist/{cli-vdkwkkp5.js → cli-fwpqghgc.js} +4 -2
  13. package/dist/cli-k4tqwah4.js +89 -0
  14. package/dist/{cli-6et4z504.js → cli-mg5zv4s6.js} +15 -13
  15. package/dist/{cli-wzds257x.js → cli-n2hng3gv.js} +6 -4
  16. package/dist/cli-ns5fcnkz.js +341 -0
  17. package/dist/{cli-4h0ave0f.js → cli-ny48a8de.js} +12 -9
  18. package/dist/{cli-qwgct6x7.js → cli-qpq84eee.js} +5220 -32716
  19. package/dist/cli-xq45etg1.js +1098 -0
  20. package/dist/cli-yf39avhh.js +754 -0
  21. package/dist/cli-yz8xcpyk.js +12 -0
  22. package/dist/cli.js +435 -192
  23. package/dist/doctor-k3ta6h2y.js +24 -0
  24. package/dist/{fix-75s9s0d6.js → fix-w5z02wt4.js} +8 -9
  25. package/dist/{harness-a7tb9a23.js → harness-7azmzytc.js} +15 -7
  26. package/dist/{harness-github-actions-6v4wydb8.js → harness-github-actions-bv2qrnqb.js} +11 -5
  27. package/dist/harness-report-rd9c4e9v.js +54 -0
  28. package/dist/{index-91bpc8g8.js → index-d1z50dsq.js} +41 -33
  29. package/dist/{production-intelligence-7nqddd4f.js → production-intelligence-wvsgjxth.js} +9 -6
  30. package/dist/{profile-commands-49yn02yg.js → profile-commands-h8evz9x0.js} +7 -4
  31. package/dist/prompt-attribution-1nytc9wj.js +148 -0
  32. package/dist/prompt-source-mcp.js +14 -7
  33. package/dist/prompt-sources-07tczyqa.js +19 -0
  34. package/dist/{prompts-17wyrst6.js → prompts-6y9wfq5z.js} +8 -7
  35. package/dist/prompts-ab-ezrd63sk.js +70 -0
  36. package/dist/prompts-propose-2k3enm2q.js +255 -0
  37. package/dist/{provision-bc3h68e1.js → provision-y5bdbh4y.js} +9 -6
  38. package/dist/{registry-fpzhjznj.js → registry-96aze5wp.js} +7 -4
  39. package/dist/{skills-ccdbqghj.js → skills-j8865009.js} +7 -5
  40. package/dist/{sync-hkxce5zh.js → sync-ew7yvy0e.js} +16 -10
  41. package/package.json +1 -1
  42. package/skills/integration/index.json +2 -2
  43. package/dist/doctor-wmre3mr7.js +0 -22
@@ -0,0 +1,255 @@
1
+ import {
2
+ assertAllowedModel,
3
+ assertPlayoutBudget,
4
+ candidateOutcome,
5
+ describePlayouts,
6
+ enqueueAndPollComparison,
7
+ formatVerdict,
8
+ rerunWithYes,
9
+ resolvePromptArmSpec
10
+ } from "./cli-yf39avhh.js";
11
+ import"./cli-yz8xcpyk.js";
12
+ import"./cli-3retgh64.js";
13
+ import"./cli-mm48br00.js";
14
+ import"./cli-dr6x0zv7.js";
15
+ import"./cli-n2hng3gv.js";
16
+ import {
17
+ callControlAPI
18
+ } from "./cli-e23g9ywa.js";
19
+ import {
20
+ resolveApiTenantId,
21
+ shellArg,
22
+ validateConfig
23
+ } from "./cli-99p2jh28.js";
24
+ import {
25
+ CliInputError
26
+ } from "./cli-k4tqwah4.js";
27
+ import"./cli-9kfxkxmk.js";
28
+ import"./cli-ns5fcnkz.js";
29
+ import"./cli-0v6na3yp.js";
30
+
31
+ // src/prompts-propose.ts
32
+ import { writeFileSync } from "node:fs";
33
+ import { isAbsolute, resolve } from "node:path";
34
+ var PROPOSE_TIMEOUT_MS = 300000;
35
+ async function runPromptPropose(positionals, flags, profileOptions, context) {
36
+ validateConfig();
37
+ const promptKey = flags["prompt-key"] || positionals[1];
38
+ const fromRunId = flags["from-run"] || flags["from-run-id"] || flags["run-id"];
39
+ const replaySetId = flags["set-id"] || flags["replay-set-id"];
40
+ if (!promptKey || !fromRunId || !replaySetId) {
41
+ throw new Error("Usage: moda prompts propose --prompt-key=<key> --from-run=<run_id> --set-id=<replay_set_id> [--max-dossiers=8] [--model=<slug>] [--out=path.prompt.md] [--gate [--seeds=1-10] [--assistant-model=<slug>] [--yes]] [--promote-on-win] [--allow-any-model]");
42
+ }
43
+ const maxDossiers = parsePositiveInt(flags["max-dossiers"], 8, 16, "--max-dossiers");
44
+ parsePositiveInt(flags["gate-timeout"] ?? flags.timeout, 2 * 60 * 60 * 1000, 24 * 60 * 60 * 1000, flags["gate-timeout"] !== undefined ? "--gate-timeout" : "--timeout");
45
+ parsePositiveInt(flags["poll-interval"], 15000, 120000, "--poll-interval");
46
+ const model = assertAllowedModel(flags.model ?? flags["revise-model"], flags, "--model");
47
+ const wantGate = flags.gate === "true";
48
+ let gatePlan;
49
+ if (wantGate) {
50
+ const tenantId = flags["tenant-id"] || resolveApiTenantId(profileOptions);
51
+ if (!tenantId) {
52
+ throw new Error("Missing tenant id for --gate. Run `moda init` or pass --tenant-id=<id>.");
53
+ }
54
+ const seedsPerCase = parsePositiveInt(flags.seeds ?? flags["seeds-per-case"], 3, 10, flags.seeds !== undefined ? "--seeds" : "--seeds-per-case");
55
+ const assistantModel = assertAllowedModel(flags["assistant-model"], flags, "--assistant-model");
56
+ const snapshot = await fetchGateSetCases(tenantId, replaySetId, profileOptions);
57
+ const cases = snapshot?.ids.length ?? null;
58
+ const plannedPlayouts = cases === null ? null : cases * seedsPerCase * 2;
59
+ assertPlayoutBudget(plannedPlayouts, { seedsPerCase, cases }, context.yes, rerunWithYes("prompts propose", positionals.slice(1), flags));
60
+ if (context.outputMode === "human") {
61
+ process.stderr.write(`Gate: ${describePlayouts(plannedPlayouts, cases, seedsPerCase)}
62
+ `);
63
+ }
64
+ gatePlan = { tenantId, seedsPerCase, assistantModel, plannedPlayouts, cases, caseIds: snapshot?.ids };
65
+ }
66
+ const result = await callControlAPI(`/prompts/${encodeURIComponent(promptKey)}/propose`, {
67
+ method: "POST",
68
+ body: JSON.stringify({ fromRunId, replaySetId, maxDossiers, model: model || undefined })
69
+ }, profileOptions, { timeoutMs: PROPOSE_TIMEOUT_MS, retries: 0 });
70
+ let outPath;
71
+ if (result.status === "proposed" && result.content && flags.out) {
72
+ outPath = isAbsolute(flags.out) ? flags.out : resolve(process.cwd(), flags.out);
73
+ writeFileSync(outPath, result.content, "utf8");
74
+ }
75
+ const promoteOnWin = flags["promote-on-win"] === "true";
76
+ let gate;
77
+ if (gatePlan) {
78
+ if (result.status !== "proposed" || !result.content) {
79
+ gate = {
80
+ ran: false,
81
+ scope: "full-set",
82
+ scopeNote: `no candidate to gate (${result.status})`,
83
+ verdict: "skipped",
84
+ outcome: "no-run",
85
+ runId: null,
86
+ promoted: false,
87
+ plannedPlayouts: gatePlan.plannedPlayouts
88
+ };
89
+ } else {
90
+ gate = await runGate({
91
+ result,
92
+ promptKey,
93
+ replaySetId,
94
+ flags,
95
+ plan: gatePlan,
96
+ promoteOnWin,
97
+ profileOptions,
98
+ context
99
+ });
100
+ }
101
+ }
102
+ if (context.outputMode === "human") {
103
+ printHuman(result, outPath, gate);
104
+ }
105
+ context.output.writeData({
106
+ ...result,
107
+ ...outPath ? { outPath } : {},
108
+ ...gate ? { gate } : {}
109
+ });
110
+ }
111
+ async function fetchGateSetCases(tenantId, replaySetId, profileOptions) {
112
+ let set;
113
+ try {
114
+ set = await callControlAPI(`/tenants/${encodeURIComponent(tenantId)}/replay-sets/${encodeURIComponent(replaySetId)}`, { method: "GET" }, profileOptions);
115
+ } catch (error) {
116
+ if (error?.statusCode === 404) {
117
+ throw new CliInputError(`Replay set '${replaySetId}' not found for tenant ${tenantId}, so nothing was sent.`, "Check --set-id: use the replay set the --from-run run was scored on (see `moda prompts replay-runs <key>`).");
118
+ }
119
+ return null;
120
+ }
121
+ if (!Array.isArray(set?.cases))
122
+ return null;
123
+ return {
124
+ ids: set.cases.filter((c) => String(c?.scenario ?? "").trim()).map((c, index) => String(c?.id ?? `case_${index}`))
125
+ };
126
+ }
127
+ async function runGate(args) {
128
+ const { result, promptKey, replaySetId, flags, plan, promoteOnWin, profileOptions, context } = args;
129
+ const { tenantId, seedsPerCase, assistantModel } = plan;
130
+ const prodArm = await resolvePromptArmSpec(promptKey, "baseline", { preferKey: true });
131
+ const proposedArm = {
132
+ content: result.content ?? "",
133
+ prompt_version_id: result.versionId ?? "",
134
+ prompt_id: "",
135
+ prompt_label: "candidate"
136
+ };
137
+ const timeoutMs = parsePositiveInt(flags["gate-timeout"] ?? flags.timeout, 2 * 60 * 60 * 1000, 24 * 60 * 60 * 1000, flags["gate-timeout"] !== undefined ? "--gate-timeout" : "--timeout");
138
+ const pollIntervalMs = parsePositiveInt(flags["poll-interval"], 15000, 120000, "--poll-interval");
139
+ const scopeNote = result.holdoutCaseIds.length ? `gated over the FULL replay set (${result.holdoutCaseIds.length} holdout case(s) could not be isolated — the run endpoint scores every case)` : "gated over the FULL replay set";
140
+ if (context.outputMode === "human") {
141
+ process.stderr.write(`
142
+ Gating candidate for '${promptKey}' — ${scopeNote}...
143
+ `);
144
+ }
145
+ const payload = await enqueueAndPollComparison({
146
+ tenantId,
147
+ replaySetId,
148
+ promptArms: { prod: prodArm, proposed: proposedArm },
149
+ seedsPerCase,
150
+ assistantModel: assistantModel || undefined,
151
+ promotePrimary: false,
152
+ caseIds: plan.caseIds,
153
+ timeoutMs,
154
+ pollIntervalMs,
155
+ onWaiting: context.outputMode === "human" ? (status) => process.stderr.write(`Waiting for gate run (${status})...
156
+ `) : undefined
157
+ }, profileOptions);
158
+ const outcome = candidateOutcome(payload);
159
+ const gate = {
160
+ ran: true,
161
+ scope: "full-set",
162
+ scopeNote,
163
+ verdict: formatVerdict(payload),
164
+ outcome,
165
+ runId: payload.run?.runId ?? null,
166
+ promoted: false,
167
+ plannedPlayouts: plan.plannedPlayouts
168
+ };
169
+ if (promoteOnWin) {
170
+ if (outcome === "candidate" && result.versionId) {
171
+ await callControlAPI(`/prompts/${encodeURIComponent(promptKey)}/labels`, { method: "POST", body: JSON.stringify({ label: "prod", versionId: result.versionId }) }, profileOptions);
172
+ gate.promoted = true;
173
+ } else {
174
+ gate.promoteSkippedReason = outcome === "candidate" ? "no candidate versionId to promote" : `candidate did not strictly win (${outcome})`;
175
+ }
176
+ }
177
+ return gate;
178
+ }
179
+ function printHuman(result, outPath, gate) {
180
+ const w = (s) => process.stderr.write(s + `
181
+ `);
182
+ if (result.status !== "proposed") {
183
+ w(`No candidate produced (${result.status}): ${result.note}`);
184
+ return;
185
+ }
186
+ w(`Proposed candidate for '${result.promptKey}'`);
187
+ w(` new version: ${result.versionId} (unlabeled — not promoted)`);
188
+ w(` base version: ${result.baseVersionId ?? "(none)"}`);
189
+ w(` from run: built from ${result.dossierCount} failure dossier(s)`);
190
+ if (result.changelog)
191
+ w(` changelog: ${result.changelog}`);
192
+ if (result.risks.length)
193
+ w(` risks: ${result.risks.map((r) => `- ${r}`).join(`
194
+ `)}`);
195
+ if (outPath)
196
+ w(` written to: ${outPath}`);
197
+ if (result.lowN) {
198
+ w("");
199
+ w(` ⚠ low sample: ${result.lowN}`);
200
+ }
201
+ w("");
202
+ if (gate?.ran) {
203
+ w("Gate (automatic A/B of candidate vs baseline):");
204
+ w(` scope: ${gate.scopeNote}`);
205
+ w(` verdict: ${gate.verdict}`);
206
+ if (gate.plannedPlayouts !== undefined)
207
+ w(` playouts: ${gate.plannedPlayouts ?? "unknown"} planned`);
208
+ if (gate.runId)
209
+ w(` run id: ${gate.runId}`);
210
+ if (gate.promoted) {
211
+ w(` promoted: candidate won — promoted version ${result.versionId} to label 'prod'`);
212
+ } else if (gate.promoteSkippedReason) {
213
+ w(` promote: skipped (${gate.promoteSkippedReason})`);
214
+ }
215
+ w("");
216
+ if (!gate.promoted) {
217
+ w(` moda prompts promote ${shellArg(result.promptKey)} --label=prod --version=${result.versionId ? shellArg(result.versionId) : "<version_id>"}`);
218
+ }
219
+ return;
220
+ }
221
+ if (gate && !gate.ran) {
222
+ w(`Gate not run: ${gate.scopeNote}`);
223
+ w("");
224
+ }
225
+ w("Next — gate on holdout cases the revision never saw, then promote if it wins:");
226
+ if (result.holdoutCaseIds.length) {
227
+ w(` holdout cases (${result.holdoutCaseIds.length}): ${result.holdoutCaseIds.join(", ")}`);
228
+ } else {
229
+ w(" (too few failures to reserve a holdout — gate on a fresh --auto-generate set)");
230
+ }
231
+ if (outPath) {
232
+ w(` moda prompts ab --baseline-key=${shellArg(result.promptKey)} --candidate=${shellArg(outPath)} --auto-generate`);
233
+ } else {
234
+ w(` # re-run with --out=<path.prompt.md> to materialize the candidate, then:`);
235
+ w(` moda prompts ab --baseline-key=${shellArg(result.promptKey)} --candidate=<path.prompt.md> --auto-generate`);
236
+ }
237
+ w(` # or: moda prompts propose ... --gate --promote-on-win (auto-A/B, promote on a strict win)`);
238
+ w(` moda prompts promote ${shellArg(result.promptKey)} --label=prod --version=${result.versionId ? shellArg(result.versionId) : "<version_id>"}`);
239
+ }
240
+ function parsePositiveInt(raw, fallback, max, flagName) {
241
+ if (raw === undefined)
242
+ return fallback;
243
+ const text = String(raw).trim();
244
+ const parsed = Number(text);
245
+ if (!/^\d+$/.test(text) || !Number.isSafeInteger(parsed) || parsed < 1) {
246
+ throw new CliInputError(`${flagName}=${raw} must be a whole number of at least 1, so nothing was sent.`, `Use ${flagName}=N with 1 <= N <= ${max}.`);
247
+ }
248
+ if (parsed > max) {
249
+ throw new CliInputError(`${flagName}=${parsed} is above the maximum of ${max}, so nothing was sent.`, `Use ${flagName}=${max} or less.`);
250
+ }
251
+ return parsed;
252
+ }
253
+ export {
254
+ runPromptPropose
255
+ };
@@ -1,18 +1,21 @@
1
1
  import {
2
2
  selectTenantAndCreateKey
3
- } from "./cli-0pkc8jhg.js";
4
- import"./cli-ccjfwzqx.js";
3
+ } from "./cli-9bgk5jeh.js";
4
+ import"./cli-97jew729.js";
5
5
  import {
6
6
  loadAuthSession
7
- } from "./cli-hmjdgxrn.js";
7
+ } from "./cli-9bgnvth2.js";
8
8
  import {
9
9
  stringOption
10
- } from "./cli-v8q7sd7g.js";
10
+ } from "./cli-dr6x0zv7.js";
11
11
  import {
12
- CliAuthError,
13
12
  resolveIngestUrl,
14
13
  resolveModaBaseUrl
15
- } from "./cli-r5pp7qny.js";
14
+ } from "./cli-99p2jh28.js";
15
+ import {
16
+ CliAuthError
17
+ } from "./cli-k4tqwah4.js";
18
+ import"./cli-ns5fcnkz.js";
16
19
  import"./cli-0v6na3yp.js";
17
20
 
18
21
  // src/provision.ts
@@ -1,14 +1,17 @@
1
1
  import {
2
2
  assertFlags
3
- } from "./cli-wzds257x.js";
3
+ } from "./cli-n2hng3gv.js";
4
4
  import {
5
5
  callControlAPI
6
- } from "./cli-pg5qfmqc.js";
6
+ } from "./cli-e23g9ywa.js";
7
7
  import {
8
- CliInputError,
9
8
  explicitOutputMode,
10
9
  resolveApiKey
11
- } from "./cli-r5pp7qny.js";
10
+ } from "./cli-99p2jh28.js";
11
+ import {
12
+ CliInputError
13
+ } from "./cli-k4tqwah4.js";
14
+ import"./cli-ns5fcnkz.js";
12
15
  import"./cli-0v6na3yp.js";
13
16
 
14
17
  // src/registry.ts
@@ -3,12 +3,14 @@ import {
3
3
  pullSkills,
4
4
  runSkillSync,
5
5
  runSkillsCommand
6
- } from "./cli-6et4z504.js";
7
- import"./cli-v8q7sd7g.js";
8
- import"./cli-wzds257x.js";
9
- import"./cli-pg5qfmqc.js";
10
- import"./cli-r5pp7qny.js";
6
+ } from "./cli-mg5zv4s6.js";
11
7
  import"./cli-8dtnwp9r.js";
8
+ import"./cli-dr6x0zv7.js";
9
+ import"./cli-n2hng3gv.js";
10
+ import"./cli-e23g9ywa.js";
11
+ import"./cli-99p2jh28.js";
12
+ import"./cli-k4tqwah4.js";
13
+ import"./cli-ns5fcnkz.js";
12
14
  import"./cli-0v6na3yp.js";
13
15
  export {
14
16
  runSkillsCommand,
@@ -1,21 +1,27 @@
1
+ import {
2
+ runSkillsCommand
3
+ } from "./cli-mg5zv4s6.js";
4
+ import"./cli-8dtnwp9r.js";
1
5
  import {
2
6
  runPromptsCommand
3
- } from "./cli-q9nsvqqg.js";
7
+ } from "./cli-3retgh64.js";
4
8
  import"./cli-mm48br00.js";
5
9
  import {
6
10
  runHarnessCommand
7
- } from "./cli-qwgct6x7.js";
11
+ } from "./cli-3n0gz4d0.js";
12
+ import"./cli-xq45etg1.js";
8
13
  import"./cli-97fnztpy.js";
9
- import {
10
- runSkillsCommand
11
- } from "./cli-6et4z504.js";
12
- import"./cli-v8q7sd7g.js";
13
- import"./cli-wzds257x.js";
14
- import"./cli-pg5qfmqc.js";
14
+ import"./cli-cesds766.js";
15
+ import"./cli-qpq84eee.js";
16
+ import"./cli-dr6x0zv7.js";
17
+ import"./cli-n2hng3gv.js";
18
+ import"./cli-e23g9ywa.js";
19
+ import"./cli-99p2jh28.js";
15
20
  import {
16
21
  CliInputError
17
- } from "./cli-r5pp7qny.js";
18
- import"./cli-8dtnwp9r.js";
22
+ } from "./cli-k4tqwah4.js";
23
+ import"./cli-9kfxkxmk.js";
24
+ import"./cli-ns5fcnkz.js";
19
25
  import"./cli-0v6na3yp.js";
20
26
 
21
27
  // src/sync.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moda-ai/cli",
3
- "version": "1.55.27",
3
+ "version": "1.55.29",
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-15T21:22:44.784Z",
4
- "cli_version": "1.55.27",
3
+ "bundled_at": "2026-10-15T21:58:38.008Z",
4
+ "cli_version": "1.55.29",
5
5
  "skills": [
6
6
  {
7
7
  "id": "integration-cloudflare-think",
@@ -1,22 +0,0 @@
1
- import {
2
- buildDoctorReport,
3
- promptsDiscoveredCheck,
4
- runDoctorCommand,
5
- runStatusCommand
6
- } from "./cli-4h0ave0f.js";
7
- import"./cli-hmjdgxrn.js";
8
- import"./cli-q9nsvqqg.js";
9
- import"./cli-mm48br00.js";
10
- import"./cli-qwgct6x7.js";
11
- import"./cli-97fnztpy.js";
12
- import"./cli-v8q7sd7g.js";
13
- import"./cli-wzds257x.js";
14
- import"./cli-pg5qfmqc.js";
15
- import"./cli-r5pp7qny.js";
16
- import"./cli-0v6na3yp.js";
17
- export {
18
- runStatusCommand,
19
- runDoctorCommand,
20
- promptsDiscoveredCheck,
21
- buildDoctorReport
22
- };