@mutagent/cli 0.1.23 → 0.1.25

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/dist/bin/cli.js CHANGED
@@ -16,46 +16,24 @@ var __toESM = (mod, isNodeMode, target) => {
16
16
  });
17
17
  return to;
18
18
  };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
19
29
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
30
 
21
- // src/bin/cli.ts
22
- import { Command as Command15 } from "commander";
23
- import chalk18 from "chalk";
24
- import { readFileSync as readFileSync10 } from "fs";
25
- import { join as join7, dirname } from "path";
26
- import { fileURLToPath } from "url";
27
-
28
- // src/commands/auth.ts
29
- import { Command } from "commander";
30
- import inquirer from "inquirer";
31
- import chalk3 from "chalk";
32
- import ora from "ora";
33
- import { existsSync as existsSync3 } from "fs";
34
- import { join as join4 } from "path";
35
-
36
31
  // src/lib/config.ts
37
32
  import { cosmiconfigSync } from "cosmiconfig";
38
33
  import { z } from "zod";
39
34
  import { homedir } from "os";
40
35
  import { join } from "path";
41
36
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
42
- var configSchema = z.object({
43
- apiKey: z.string().optional(),
44
- endpoint: z.string().default("https://api.mutagent.io"),
45
- format: z.enum(["table", "json"]).default("table"),
46
- timeout: z.number().default(30000),
47
- defaultWorkspace: z.string().optional(),
48
- defaultOrganization: z.string().optional()
49
- });
50
- var credentialsSchema = z.object({
51
- apiKey: z.string().optional(),
52
- endpoint: z.string().optional(),
53
- defaultWorkspace: z.string().optional(),
54
- defaultOrganization: z.string().optional(),
55
- expiresAt: z.string().optional()
56
- }).loose();
57
- var CREDENTIALS_DIR = join(homedir(), ".config", "mutagent");
58
- var CREDENTIALS_FILE = join(CREDENTIALS_DIR, "credentials.json");
59
37
  function parseJsonSafe(content, schema) {
60
38
  try {
61
39
  const parsed = JSON.parse(content);
@@ -163,79 +141,28 @@ function setDefaultOrganization(organizationId) {
163
141
  };
164
142
  writeFileSync(CREDENTIALS_FILE, JSON.stringify(updated, null, 2));
165
143
  }
166
-
167
- // src/lib/sdk-client.ts
168
- import { Mutagent, HTTPClient } from "@mutagent/sdk";
144
+ var configSchema, credentialsSchema, CREDENTIALS_DIR, CREDENTIALS_FILE;
145
+ var init_config = __esm(() => {
146
+ configSchema = z.object({
147
+ apiKey: z.string().optional(),
148
+ endpoint: z.string().default("https://api.mutagent.io"),
149
+ format: z.enum(["table", "json"]).default("table"),
150
+ timeout: z.number().default(30000),
151
+ defaultWorkspace: z.string().optional(),
152
+ defaultOrganization: z.string().optional()
153
+ });
154
+ credentialsSchema = z.object({
155
+ apiKey: z.string().optional(),
156
+ endpoint: z.string().optional(),
157
+ defaultWorkspace: z.string().optional(),
158
+ defaultOrganization: z.string().optional(),
159
+ expiresAt: z.string().optional()
160
+ }).loose();
161
+ CREDENTIALS_DIR = join(homedir(), ".config", "mutagent");
162
+ CREDENTIALS_FILE = join(CREDENTIALS_DIR, "credentials.json");
163
+ });
169
164
 
170
165
  // src/lib/errors.ts
171
- class MutagentError extends Error {
172
- code;
173
- suggestion;
174
- exitCode;
175
- constructor(code, message, suggestion, exitCode = 1) {
176
- super(message);
177
- this.code = code;
178
- this.suggestion = suggestion;
179
- this.exitCode = exitCode;
180
- this.name = "MutagentError";
181
- }
182
- toJSON() {
183
- return {
184
- success: false,
185
- error: this.message,
186
- code: this.code,
187
- suggestedAction: this.suggestion
188
- };
189
- }
190
- }
191
- var AUTH_REMEDIATION_MESSAGE = [
192
- "Authentication required. Options:",
193
- " Interactive: mutagent auth login --browser",
194
- " Non-interactive: export MUTAGENT_API_KEY=<your-key>",
195
- " CI/CD: mutagent auth login --api-key <key>"
196
- ].join(`
197
- `);
198
-
199
- class AuthenticationError extends MutagentError {
200
- suggestions;
201
- cause;
202
- constructor(message, options = {}) {
203
- super("AUTH_REQUIRED", message ?? 'Authentication required. Please run "mutagent auth login"', options.suggestions ? options.suggestions[0] : "Run: mutagent auth login --browser", 2);
204
- this.suggestions = options.suggestions ?? [
205
- "mutagent auth login --browser",
206
- "export MUTAGENT_API_KEY=<your-key>",
207
- "mutagent auth login --api-key <key>"
208
- ];
209
- this.suggestion = options.suggestions ? options.suggestions[0] : "Run: mutagent auth login --browser";
210
- this.cause = options.cause;
211
- }
212
- }
213
-
214
- class ApiError extends MutagentError {
215
- statusCode;
216
- constructor(status, message) {
217
- super(`API_${String(status)}`, message, status === 401 ? "Check your API key with: mutagent auth status" : undefined, 1);
218
- this.statusCode = status;
219
- }
220
- }
221
- var WORKSPACE_REMEDIATION_MESSAGE = [
222
- "Workspace context missing. To fix:",
223
- " mutagent config set workspace <workspace-id> # Set default workspace",
224
- " mutagent workspaces list # List available workspaces"
225
- ].join(`
226
- `);
227
-
228
- class WorkspaceContextError extends MutagentError {
229
- constructor(message) {
230
- super("WORKSPACE_REQUIRED", message ?? "Workspace context is required but not configured", "Run: mutagent config set workspace <workspace-id>", 3);
231
- }
232
- }
233
-
234
- class ValidationError extends MutagentError {
235
- constructor(message) {
236
- super("VALIDATION_ERROR", message, "Check the command syntax with: mutagent <command> --help", 1);
237
- }
238
- }
239
166
  function handleError(error, isJson) {
240
167
  if (error instanceof MutagentError) {
241
168
  if (isJson) {
@@ -260,6 +187,14 @@ function handleError(error, isJson) {
260
187
  checkPermissions: "Verify your API key has the required permissions"
261
188
  };
262
189
  }
190
+ if (error.suggestion) {
191
+ const helpMatch = /^Run:\s+(mutagent\s+[^\n]+--help)/.exec(error.suggestion);
192
+ const helpCommand = helpMatch ? helpMatch[1] : "mutagent --help";
193
+ jsonOutput._agentGuidance = {
194
+ helpCommand,
195
+ suggestion: error.suggestion
196
+ };
197
+ }
263
198
  console.log(JSON.stringify(jsonOutput, null, 2));
264
199
  } else {
265
200
  console.error(`Error: ${error.message}`);
@@ -314,8 +249,86 @@ function handleError(error, isJson) {
314
249
  }
315
250
  process.exit(1);
316
251
  }
252
+ var MutagentError, AUTH_REMEDIATION_MESSAGE, AuthenticationError, ApiError, WORKSPACE_REMEDIATION_MESSAGE, WorkspaceContextError, ValidationError;
253
+ var init_errors = __esm(() => {
254
+ MutagentError = class MutagentError extends Error {
255
+ code;
256
+ suggestion;
257
+ exitCode;
258
+ constructor(code, message, suggestion, exitCode = 1) {
259
+ super(message);
260
+ this.code = code;
261
+ this.suggestion = suggestion;
262
+ this.exitCode = exitCode;
263
+ this.name = "MutagentError";
264
+ }
265
+ toJSON() {
266
+ return {
267
+ success: false,
268
+ error: this.message,
269
+ code: this.code,
270
+ suggestedAction: this.suggestion
271
+ };
272
+ }
273
+ };
274
+ AUTH_REMEDIATION_MESSAGE = [
275
+ "Authentication required. Options:",
276
+ " Interactive: mutagent auth login --browser",
277
+ " Non-interactive: export MUTAGENT_API_KEY=<your-key>",
278
+ " CI/CD: mutagent auth login --api-key <key>"
279
+ ].join(`
280
+ `);
281
+ AuthenticationError = class AuthenticationError extends MutagentError {
282
+ suggestions;
283
+ cause;
284
+ constructor(message, options = {}) {
285
+ super("AUTH_REQUIRED", message ?? 'Authentication required. Please run "mutagent auth login"', options.suggestions ? options.suggestions[0] : "Run: mutagent auth login --browser", 2);
286
+ this.suggestions = options.suggestions ?? [
287
+ "mutagent auth login --browser",
288
+ "export MUTAGENT_API_KEY=<your-key>",
289
+ "mutagent auth login --api-key <key>"
290
+ ];
291
+ this.suggestion = options.suggestions ? options.suggestions[0] : "Run: mutagent auth login --browser";
292
+ this.cause = options.cause;
293
+ }
294
+ };
295
+ ApiError = class ApiError extends MutagentError {
296
+ statusCode;
297
+ constructor(status, message) {
298
+ super(`API_${String(status)}`, message, status === 401 ? "Check your API key with: mutagent auth status" : undefined, 1);
299
+ this.statusCode = status;
300
+ }
301
+ };
302
+ WORKSPACE_REMEDIATION_MESSAGE = [
303
+ "Workspace context missing. To fix:",
304
+ " mutagent config set workspace <workspace-id> # Set default workspace",
305
+ " mutagent workspaces list # List available workspaces"
306
+ ].join(`
307
+ `);
308
+ WorkspaceContextError = class WorkspaceContextError extends MutagentError {
309
+ constructor(message) {
310
+ super("WORKSPACE_REQUIRED", message ?? "Workspace context is required but not configured", "Run: mutagent config set workspace <workspace-id>", 3);
311
+ }
312
+ };
313
+ ValidationError = class ValidationError extends MutagentError {
314
+ constructor(message) {
315
+ super("VALIDATION_ERROR", message, "Check the command syntax with: mutagent <command> --help", 1);
316
+ }
317
+ };
318
+ });
317
319
 
318
320
  // src/lib/sdk-client.ts
321
+ var exports_sdk_client = {};
322
+ __export(exports_sdk_client, {
323
+ validateApiKey: () => validateApiKey,
324
+ resetSDKClient: () => resetSDKClient,
325
+ getSDKClient: () => getSDKClient,
326
+ fetchWorkspaces: () => fetchWorkspaces,
327
+ fetchOrganizations: () => fetchOrganizations,
328
+ MutagentSDK: () => SDKClientWrapper
329
+ });
330
+ import { Mutagent, HTTPClient } from "@mutagent/sdk";
331
+
319
332
  class SDKClientWrapper {
320
333
  sdk;
321
334
  apiKey;
@@ -870,7 +883,6 @@ class SDKClientWrapper {
870
883
  }
871
884
  }
872
885
  }
873
- var sdkClient = null;
874
886
  function getSDKClient() {
875
887
  if (!sdkClient) {
876
888
  const apiKey = getApiKey();
@@ -887,6 +899,9 @@ function getSDKClient() {
887
899
  }
888
900
  return sdkClient;
889
901
  }
902
+ function resetSDKClient() {
903
+ sdkClient = null;
904
+ }
890
905
  async function validateApiKey(apiKey, endpoint) {
891
906
  try {
892
907
  const response = await fetch(`${endpoint}/api/organizations`, {
@@ -923,6 +938,28 @@ async function fetchWorkspaces(apiKey, endpoint, orgId) {
923
938
  return [];
924
939
  }
925
940
  }
941
+ var sdkClient = null;
942
+ var init_sdk_client = __esm(() => {
943
+ init_errors();
944
+ init_config();
945
+ });
946
+
947
+ // src/bin/cli.ts
948
+ import { Command as Command15 } from "commander";
949
+ import chalk18 from "chalk";
950
+ import { readFileSync as readFileSync10 } from "fs";
951
+ import { join as join7, dirname } from "path";
952
+ import { fileURLToPath } from "url";
953
+
954
+ // src/commands/auth.ts
955
+ init_config();
956
+ init_sdk_client();
957
+ import { Command } from "commander";
958
+ import inquirer from "inquirer";
959
+ import chalk3 from "chalk";
960
+ import ora from "ora";
961
+ import { existsSync as existsSync3 } from "fs";
962
+ import { join as join4 } from "path";
926
963
 
927
964
  // src/lib/output.ts
928
965
  import chalk from "chalk";
@@ -1068,6 +1105,9 @@ function createSpinner(text, isJson) {
1068
1105
  return { start };
1069
1106
  }
1070
1107
 
1108
+ // src/commands/auth.ts
1109
+ init_errors();
1110
+
1071
1111
  // src/lib/browser-auth.ts
1072
1112
  import { hostname, platform } from "os";
1073
1113
  function generateCliToken() {
@@ -1868,6 +1908,8 @@ Environment Variables:
1868
1908
  let endpoint = process.env.MUTAGENT_ENDPOINT ?? options.endpoint;
1869
1909
  let workspaceName;
1870
1910
  let organizationName;
1911
+ let loginWorkspaceId;
1912
+ let loginOrgId;
1871
1913
  if (apiKey) {
1872
1914
  output.info("Validating API key...");
1873
1915
  const isValid = await validateApiKey(apiKey, endpoint);
@@ -1890,8 +1932,21 @@ Environment Variables:
1890
1932
  organizationId: orgId
1891
1933
  });
1892
1934
  output.success("Authenticated successfully");
1893
- if (!isJson) {
1935
+ if (isJson) {
1936
+ output.output({
1937
+ success: true,
1938
+ authenticated: true,
1939
+ endpoint,
1940
+ workspace: wsId ? { id: wsId } : null,
1941
+ organization: orgId ? { id: orgId } : null,
1942
+ _directive: {
1943
+ instruction: "Verify workspace. Run: mutagent workspaces list --json",
1944
+ next: ["mutagent workspaces list --json", "mutagent prompts list --json"]
1945
+ }
1946
+ });
1947
+ } else {
1894
1948
  output.info(`Endpoint: ${endpoint}`);
1949
+ output.info("Next: mutagent workspaces list --json");
1895
1950
  }
1896
1951
  return;
1897
1952
  }
@@ -1956,6 +2011,8 @@ Environment Variables:
1956
2011
  apiKey = result.apiKey;
1957
2012
  workspaceName = result.workspaceName;
1958
2013
  organizationName = result.organizationName;
2014
+ loginWorkspaceId = result.workspaceId;
2015
+ loginOrgId = result.organizationId;
1959
2016
  console.log("");
1960
2017
  output.info("Workspace: " + workspaceName);
1961
2018
  output.info("Organization: " + organizationName);
@@ -2034,6 +2091,10 @@ Environment Variables:
2034
2091
  workspaceId: selectedWsId,
2035
2092
  organizationId: selectedOrgId
2036
2093
  });
2094
+ workspaceName = selectedWsName;
2095
+ organizationName = selectedOrgName;
2096
+ loginWorkspaceId = selectedWsId;
2097
+ loginOrgId = selectedOrgId;
2037
2098
  output.success("Authenticated successfully");
2038
2099
  if (selectedOrgName)
2039
2100
  output.info("Organization: " + selectedOrgName);
@@ -2041,6 +2102,21 @@ Environment Variables:
2041
2102
  output.info("Workspace: " + selectedWsName);
2042
2103
  output.info("Endpoint: " + endpoint);
2043
2104
  }
2105
+ if (isJson) {
2106
+ output.output({
2107
+ success: true,
2108
+ authenticated: true,
2109
+ endpoint,
2110
+ workspace: loginWorkspaceId ? { id: loginWorkspaceId, name: workspaceName } : null,
2111
+ organization: loginOrgId ? { id: loginOrgId, name: organizationName } : null,
2112
+ _directive: {
2113
+ instruction: "Verify workspace. Run: mutagent workspaces list --json",
2114
+ next: ["mutagent workspaces list --json", "mutagent prompts list --json"]
2115
+ }
2116
+ });
2117
+ } else {
2118
+ output.info("Next: mutagent workspaces list --json");
2119
+ }
2044
2120
  if (wasFirstLogin && process.stdin.isTTY && !isJson) {
2045
2121
  await runPostOnboarding();
2046
2122
  }
@@ -2156,10 +2232,13 @@ Examples:
2156
2232
  }
2157
2233
 
2158
2234
  // src/commands/login.ts
2235
+ init_config();
2236
+ init_sdk_client();
2159
2237
  import { Command as Command2 } from "commander";
2160
2238
  import inquirer2 from "inquirer";
2161
2239
  import chalk4 from "chalk";
2162
2240
  import ora2 from "ora";
2241
+ init_errors();
2163
2242
  function createLoginCommand() {
2164
2243
  const login = new Command2("login").description("Login to MutagenT platform").option("--browser", "Force browser-based authentication").option("--non-interactive", "Disable interactive prompts (auto-selects browser auth)").option("--endpoint <url>", "API endpoint", "https://api.mutagent.io").addHelpText("after", `
2165
2244
  Examples:
@@ -2302,9 +2381,11 @@ Environment Variables:
2302
2381
  }
2303
2382
 
2304
2383
  // src/commands/prompts.ts
2384
+ init_sdk_client();
2305
2385
  import { Command as Command3 } from "commander";
2306
2386
  import chalk6 from "chalk";
2307
2387
  import { readFileSync as readFileSync4, existsSync as existsSync4 } from "fs";
2388
+ init_errors();
2308
2389
 
2309
2390
  // src/lib/ui-links.ts
2310
2391
  function getAppBaseUrl() {
@@ -2390,6 +2471,13 @@ function evaluationLinks(promptId, evalId) {
2390
2471
  }
2391
2472
  var AI_DIRECTIVE = `
2392
2473
  [AI Agent: STOP. Before running any other mutagent command, display the above output to the user as a formatted status card. Do not summarize or omit details. Show all links and suggested next steps.]`;
2474
+ function echoDirectiveToStderr(directive) {
2475
+ if (directive?.instruction) {
2476
+ console.error(`
2477
+ ⚠️ AI AGENT: ${directive.instruction}
2478
+ `);
2479
+ }
2480
+ }
2393
2481
  function formatCreationHints(hint) {
2394
2482
  const lines = [
2395
2483
  "",
@@ -2839,22 +2927,12 @@ function isSchemaEmpty(schema) {
2839
2927
  return true;
2840
2928
  return false;
2841
2929
  }
2842
- function warnSingleBraceVariables(content, output) {
2843
- const singleBracePattern = /(?<!\{)\{([a-zA-Z_][a-zA-Z0-9_]*)\}(?!\})/g;
2844
- const matches = [...content.matchAll(singleBracePattern)];
2845
- if (matches.length > 0) {
2846
- const variables = [...new Set(matches.map((m) => m[1] ?? ""))];
2847
- for (const variable of variables) {
2848
- output.warn(`Found {${variable}} -- MutagenT uses {{${variable}}} syntax. Did you mean {{${variable}}}?`);
2849
- }
2850
- }
2851
- }
2852
2930
  function createPromptsCommand() {
2853
2931
  const prompts = new Command3("prompts").description("Manage prompts, datasets, evaluations, and optimizations").addHelpText("after", `
2854
2932
  Examples:
2855
2933
  ${chalk6.dim("$")} mutagent prompts list
2856
2934
  ${chalk6.dim("$")} mutagent prompts get <prompt-id>
2857
- ${chalk6.dim("$")} mutagent prompts create --name "my-prompt" --system "You are helpful" --human "{{input}}"
2935
+ ${chalk6.dim("$")} mutagent prompts create --name "my-prompt" --system "You are helpful" --human "{input}"
2858
2936
  ${chalk6.dim("$")} mutagent prompts dataset list <prompt-id>
2859
2937
  ${chalk6.dim("$")} mutagent prompts evaluation create <prompt-id> --name "My Eval"
2860
2938
  ${chalk6.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
@@ -2947,19 +3025,27 @@ ${chalk6.dim("Tip: Combine --with-datasets and --with-evals to fetch all nested
2947
3025
  });
2948
3026
  prompts.command("create").description("Create a new prompt").option("-d, --data <json>", "Prompt as JSON string (recommended — curl-style inline)").option("--raw-file <path>", "Create from plain text file (used as rawPrompt)").option("-n, --name <name>", "Prompt name").option("--description <text>", "Prompt description (shown in dashboard)").option("-c, --content <content>", "Prompt content (rawPrompt) [DEPRECATED: use --raw]").option("-r, --raw <text>", "Raw prompt text (single prompt)").option("--system <text>", "System prompt (use with --human)").option("--human <text>", "Human prompt (use with --system)").option("--messages <json>", `Messages array as JSON (e.g., '[{"role":"system","content":"..."}]')`).option("--output-schema <json>", "Output schema as JSON string (required for optimization)").addHelpText("after", `
2949
3027
  Examples:
2950
- ${chalk6.dim("$")} mutagent prompts create --name "my-prompt" --description "Greeting prompt for customers" --system "You are helpful" --human "{{input}}" --output-schema '{"type":"object","properties":{"result":{"type":"string","description":"The result"}}}'
2951
- ${chalk6.dim("$")} mutagent prompts create --name "raw-prompt" --raw "Summarize: {{text}}" --output-schema '{"type":"object","properties":{"summary":{"type":"string","description":"Summary"}}}'
2952
- ${chalk6.dim("$")} mutagent prompts create -d '{"name":"summarizer","systemPrompt":"Summarize","humanPrompt":"{{text}}","outputSchema":{"type":"object","properties":{"summary":{"type":"string","description":"Summary"}}}}'
3028
+ ${chalk6.dim("$")} mutagent prompts create --name "my-prompt" --description "Greeting prompt for customers" --system "You are helpful" --human "{input}" --output-schema '{"type":"object","properties":{"result":{"type":"string","description":"The result"}}}'
3029
+ ${chalk6.dim("$")} mutagent prompts create --name "raw-prompt" --raw "Summarize: {text}" --output-schema '{"type":"object","properties":{"summary":{"type":"string","description":"Summary"}}}'
3030
+ ${chalk6.dim("$")} mutagent prompts create -d '{"name":"summarizer","systemPrompt":"Summarize","humanPrompt":"{text}","outputSchema":{"type":"object","properties":{"summary":{"type":"string","description":"Summary"}}}}'
2953
3031
 
2954
3032
  Prompt Input Methods (pick one, priority order):
2955
3033
  --system/--human Structured system + user message pair ${chalk6.green("(recommended)")}
2956
- --raw Single raw prompt text with {{variables}}
3034
+ --raw Single raw prompt text with {variables}
2957
3035
  -d, --data Inline JSON object (CI/scripts/agents)
2958
3036
  --messages Full messages array as JSON
2959
3037
  --raw-file Load plain text file as raw prompt
2960
3038
 
2961
3039
  Expected JSON (--data):
2962
- ${chalk6.dim(`'{"name":"my-prompt","systemPrompt":"You are...","humanPrompt":"{{input}}","outputSchema":{"type":"object","properties":{"result":{"type":"string","description":"The result"}}},"inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"User input"}}}}'`)}
3040
+ ${chalk6.dim(`'{"name":"my-prompt","systemPrompt":"You are...","humanPrompt":"{input}","outputSchema":{"type":"object","properties":{"result":{"type":"string","description":"The result"}}},"inputSchema":{"type":"object","properties":{"input":{"type":"string","description":"User input"}}}}'`)}
3041
+
3042
+ ${chalk6.yellow("Variable Syntax:")}
3043
+ MutagenT uses {single_braces} for template variables.
3044
+ humanPrompt: "Analyze this: {document}" ${chalk6.green("✓ correct")}
3045
+ humanPrompt: "Analyze this: {{document}}" ${chalk6.red("✗ wrong")}
3046
+
3047
+ Variables in humanPrompt MUST also appear in inputSchema.properties.
3048
+ Static prompts (no variables) cannot substitute inputs during optimization.
2963
3049
 
2964
3050
  ${chalk6.red("outputSchema is required.")}
2965
3051
  `).action(async (options) => {
@@ -2971,7 +3057,8 @@ ${chalk6.red("outputSchema is required.")}
2971
3057
  try {
2972
3058
  data = JSON.parse(options.data);
2973
3059
  } catch {
2974
- throw new MutagentError("INVALID_JSON", "Invalid JSON in --data flag", `Provide a valid JSON object, e.g., '{"name":"my-prompt","systemPrompt":"You are helpful"}'`);
3060
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in --data flag", `Run: mutagent prompts create --help
3061
+ Provide a valid JSON object, e.g., '{"name":"my-prompt","systemPrompt":"You are helpful"}'`);
2975
3062
  }
2976
3063
  if (options.name)
2977
3064
  data.name = options.name;
@@ -2979,7 +3066,8 @@ ${chalk6.red("outputSchema is required.")}
2979
3066
  data.description = options.description;
2980
3067
  } else if (options.rawFile) {
2981
3068
  if (!existsSync4(options.rawFile)) {
2982
- throw new MutagentError("FILE_NOT_FOUND", `File not found: ${options.rawFile}`, "Check the file path and try again");
3069
+ throw new MutagentError("FILE_NOT_FOUND", `File not found: ${options.rawFile}`, `Run: mutagent prompts create --help
3070
+ Check the file path and try again`);
2983
3071
  }
2984
3072
  const textContent = readFileSync4(options.rawFile, "utf-8");
2985
3073
  data = {
@@ -2999,7 +3087,8 @@ ${chalk6.red("outputSchema is required.")}
2999
3087
  if (humanMsg)
3000
3088
  data.humanPrompt = humanMsg.content;
3001
3089
  } catch {
3002
- throw new MutagentError("INVALID_JSON", "Invalid JSON in --messages flag", `Provide a valid JSON array, e.g., '[{"role":"system","content":"..."}]'`);
3090
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in --messages flag", `Run: mutagent prompts create --help
3091
+ Provide a valid JSON array, e.g., '[{"role":"system","content":"..."}]'`);
3003
3092
  }
3004
3093
  } else if (options.system ?? options.human) {
3005
3094
  if (options.system)
@@ -3011,34 +3100,37 @@ ${chalk6.red("outputSchema is required.")}
3011
3100
  } else if (options.content) {
3012
3101
  data.rawPrompt = options.content;
3013
3102
  } else {
3014
- throw new MutagentError("MISSING_ARGUMENTS", "Prompt content required", "Use --data, --raw-file, --raw, --system/--human, or --messages to specify prompt content");
3103
+ throw new MutagentError("MISSING_ARGUMENTS", "Prompt content required", `Run: mutagent prompts create --help
3104
+ Use --data, --raw-file, --raw, --system/--human, or --messages to specify prompt content`);
3015
3105
  }
3016
3106
  } else {
3017
- throw new MutagentError("MISSING_ARGUMENTS", "Either --data, --raw-file, or --name with prompt content is required", "Use --data for inline JSON, --raw-file for plain text, or provide --name with --raw, --system/--human, or --messages");
3018
- }
3019
- const promptContent = data.rawPrompt ?? data.systemPrompt ?? data.humanPrompt ?? "";
3020
- if (promptContent && !isJson) {
3021
- warnSingleBraceVariables(promptContent, output);
3107
+ throw new MutagentError("MISSING_ARGUMENTS", "Either --data, --raw-file, or --name with prompt content is required", `Run: mutagent prompts create --help
3108
+ Use --data for inline JSON, --raw-file for plain text, or provide --name with --raw, --system/--human, or --messages`);
3022
3109
  }
3023
3110
  if (options.outputSchema) {
3024
3111
  try {
3025
3112
  data.outputSchema = JSON.parse(options.outputSchema);
3026
3113
  } catch {
3027
- throw new MutagentError("INVALID_JSON", "Invalid JSON in --output-schema flag", `Provide a valid JSON Schema, e.g., '{"type":"object","properties":{"result":{"type":"string"}}}'`);
3114
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in --output-schema flag", `Run: mutagent prompts create --help
3115
+ Provide a valid JSON Schema, e.g., '{"type":"object","properties":{"result":{"type":"string"}}}'`);
3028
3116
  }
3029
3117
  }
3030
3118
  if (isSchemaEmpty(data.outputSchema)) {
3031
- throw new MutagentError("MISSING_ARGUMENTS", "outputSchema is required for prompt creation", `Use --output-schema '{"type":"object","properties":{...}}' or include outputSchema in --data`);
3119
+ throw new MutagentError("MISSING_ARGUMENTS", "outputSchema is required for prompt creation", `Run: mutagent prompts create --help
3120
+ Use --output-schema '{"type":"object","properties":{...}}' or include outputSchema in --data`);
3032
3121
  }
3033
3122
  if (isSchemaEmpty(data.inputSchema)) {
3034
- throw new MutagentError("VALIDATION_ERROR", "inputSchema is required. Optimization cannot run without defined input variables.", `Provide inputSchema via --data. Example:
3123
+ throw new MutagentError("VALIDATION_ERROR", "inputSchema is required. Optimization cannot run without defined input variables.", `Run: mutagent prompts create --help
3124
+ Provide inputSchema via --data. Example:
3035
3125
  ` + ` --data '{"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"User query"}}}}'`);
3036
3126
  } else if (!isValidJsonSchema(data.inputSchema)) {
3037
- throw new MutagentError("VALIDATION_ERROR", "inputSchema is not a valid JSON Schema object.", formatSchemaWarning("inputSchema"));
3127
+ throw new MutagentError("VALIDATION_ERROR", "inputSchema is not a valid JSON Schema object.", `Run: mutagent prompts create --help
3128
+ ` + formatSchemaWarning("inputSchema"));
3038
3129
  } else {
3039
3130
  const missingDescs = validateSchemaDescriptions(data.inputSchema);
3040
3131
  if (missingDescs.length > 0) {
3041
- throw new MutagentError("VALIDATION_ERROR", `inputSchema properties missing descriptions: ${missingDescs.join(", ")}`, `Add a 'description' field to each property in your inputSchema. Example: { "properties": { "field": { "type": "string", "description": "What this field contains" } } }`);
3132
+ throw new MutagentError("VALIDATION_ERROR", `inputSchema properties missing descriptions: ${missingDescs.join(", ")}`, `Run: mutagent prompts create --help
3133
+ Add a 'description' field to each property in your inputSchema. Example: { "properties": { "field": { "type": "string", "description": "What this field contains" } } }`);
3042
3134
  }
3043
3135
  }
3044
3136
  if (isSchemaEmpty(data.outputSchema)) {
@@ -3049,7 +3141,9 @@ ${chalk6.red("outputSchema is required.")}
3049
3141
  const client = getSDKClient();
3050
3142
  const prompt = await client.createPrompt(data);
3051
3143
  if (isJson) {
3052
- output.output({ ...prompt, _links: promptLinks(prompt.id), _directive: promptCreatedDirective(prompt.id, prompt.name) });
3144
+ const directive = promptCreatedDirective(prompt.id, prompt.name);
3145
+ output.output({ ...prompt, _links: promptLinks(prompt.id), _directive: directive });
3146
+ echoDirectiveToStderr(directive);
3053
3147
  } else {
3054
3148
  output.success(`Created prompt: ${prompt.name} (id: ${String(prompt.id)})`);
3055
3149
  output.info(`Workspace: ${client.getCurrentWorkspaceId() ?? "auto-inferred from API key"}`);
@@ -3076,9 +3170,9 @@ ${chalk6.red("outputSchema is required.")}
3076
3170
  });
3077
3171
  prompts.command("update").description("Update a prompt").argument("<id>", "Prompt ID (from: mutagent prompts list)").option("-d, --data <json>", "Update fields as JSON string (recommended — curl-style inline)").option("--raw-file <path>", "Update from plain text file (used as rawPrompt)").option("-n, --name <name>", "New name").option("--description <text>", "New description (shown in dashboard)").option("-c, --content <content>", "New content (rawPrompt) [DEPRECATED: use --raw]").option("-r, --raw <text>", "Raw prompt text (single prompt)").option("--system <text>", "System prompt (use with --human)").option("--human <text>", "Human prompt (use with --system)").option("--messages <json>", `Messages array as JSON (e.g., '[{"role":"system","content":"..."}]')`).option("--input-schema <json>", "Input schema as JSON string").option("--input-schema-file <path>", "Input schema from JSON file").option("--output-schema <json>", "Output schema as JSON string").option("--output-schema-file <path>", "Output schema from JSON file").addHelpText("after", `
3078
3172
  Examples:
3079
- ${chalk6.dim("$")} mutagent prompts update <id> --system "Updated system prompt" --human "{{input}}"
3173
+ ${chalk6.dim("$")} mutagent prompts update <id> --system "Updated system prompt" --human "{input}"
3080
3174
  ${chalk6.dim("$")} mutagent prompts update <id> --name "new-name" --description "Updated description"
3081
- ${chalk6.dim("$")} mutagent prompts update <id> --raw "Summarize: {{text}}"
3175
+ ${chalk6.dim("$")} mutagent prompts update <id> --raw "Summarize: {text}"
3082
3176
  ${chalk6.dim("$")} mutagent prompts update <id> -d '{"name":"new-name","systemPrompt":"Updated prompt"}'
3083
3177
  ${chalk6.dim("$")} mutagent prompts update <id> --input-schema '{"type":"object","properties":{"text":{"type":"string","description":"Input text"}}}'
3084
3178
 
@@ -3092,7 +3186,8 @@ ${chalk6.dim("CLI flags (--name) override --data fields.")}
3092
3186
  try {
3093
3187
  data = JSON.parse(options.data);
3094
3188
  } catch {
3095
- throw new MutagentError("INVALID_JSON", "Invalid JSON in --data flag", `Provide a valid JSON object, e.g., '{"name":"new-name","systemPrompt":"Updated prompt"}'`);
3189
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in --data flag", `Run: mutagent prompts update --help
3190
+ ` + `Provide a valid JSON object, e.g., '{"name":"new-name","systemPrompt":"Updated prompt"}'`);
3096
3191
  }
3097
3192
  if (options.name)
3098
3193
  data.name = options.name;
@@ -3100,7 +3195,8 @@ ${chalk6.dim("CLI flags (--name) override --data fields.")}
3100
3195
  data.description = options.description;
3101
3196
  } else if (options.rawFile) {
3102
3197
  if (!existsSync4(options.rawFile)) {
3103
- throw new MutagentError("FILE_NOT_FOUND", `File not found: ${options.rawFile}`, "Check the file path and try again");
3198
+ throw new MutagentError("FILE_NOT_FOUND", `File not found: ${options.rawFile}`, `Run: mutagent prompts update --help
3199
+ ` + "Check the file path and try again");
3104
3200
  }
3105
3201
  const textContent = readFileSync4(options.rawFile, "utf-8");
3106
3202
  data.rawPrompt = textContent;
@@ -3123,7 +3219,8 @@ ${chalk6.dim("CLI flags (--name) override --data fields.")}
3123
3219
  if (humanMsg)
3124
3220
  data.humanPrompt = humanMsg.content;
3125
3221
  } catch {
3126
- throw new MutagentError("INVALID_JSON", "Invalid JSON in --messages flag", `Provide a valid JSON array, e.g., '[{"role":"system","content":"..."}]'`);
3222
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in --messages flag", `Run: mutagent prompts update --help
3223
+ ` + `Provide a valid JSON array, e.g., '[{"role":"system","content":"..."}]'`);
3127
3224
  }
3128
3225
  } else if (options.system ?? options.human) {
3129
3226
  if (options.system)
@@ -3137,60 +3234,68 @@ ${chalk6.dim("CLI flags (--name) override --data fields.")}
3137
3234
  }
3138
3235
  }
3139
3236
  if (options.inputSchema && options.inputSchemaFile) {
3140
- throw new MutagentError("INVALID_ARGUMENTS", "Cannot use --input-schema and --input-schema-file together", "Use --input-schema for inline JSON or --input-schema-file for file-based input, not both");
3237
+ throw new MutagentError("INVALID_ARGUMENTS", "Cannot use --input-schema and --input-schema-file together", `Run: mutagent prompts update --help
3238
+ ` + "Use --input-schema for inline JSON or --input-schema-file for file-based input, not both");
3141
3239
  }
3142
3240
  if (options.inputSchema) {
3143
3241
  try {
3144
3242
  data.inputSchema = JSON.parse(options.inputSchema);
3145
3243
  } catch {
3146
- throw new MutagentError("INVALID_JSON", "Invalid JSON in --input-schema flag", `Provide a valid JSON Schema, e.g., '{"type":"object","properties":{"text":{"type":"string","description":"Input text"}}}'`);
3244
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in --input-schema flag", `Run: mutagent prompts update --help
3245
+ ` + `Provide a valid JSON Schema, e.g., '{"type":"object","properties":{"text":{"type":"string","description":"Input text"}}}'`);
3147
3246
  }
3148
3247
  } else if (options.inputSchemaFile) {
3149
3248
  if (!existsSync4(options.inputSchemaFile)) {
3150
- throw new MutagentError("FILE_NOT_FOUND", `File not found: ${options.inputSchemaFile}`, "Check the file path and try again");
3249
+ throw new MutagentError("FILE_NOT_FOUND", `File not found: ${options.inputSchemaFile}`, `Run: mutagent prompts update --help
3250
+ ` + "Check the file path and try again");
3151
3251
  }
3152
3252
  try {
3153
3253
  data.inputSchema = JSON.parse(readFileSync4(options.inputSchemaFile, "utf-8"));
3154
3254
  } catch {
3155
- throw new MutagentError("INVALID_JSON", `Failed to parse JSON from ${options.inputSchemaFile}`, "Ensure the file contains valid JSON Schema");
3255
+ throw new MutagentError("INVALID_JSON", `Failed to parse JSON from ${options.inputSchemaFile}`, `Run: mutagent prompts update --help
3256
+ ` + "Ensure the file contains valid JSON Schema");
3156
3257
  }
3157
3258
  }
3158
3259
  if (options.outputSchema && options.outputSchemaFile) {
3159
- throw new MutagentError("INVALID_ARGUMENTS", "Cannot use --output-schema and --output-schema-file together", "Use --output-schema for inline JSON or --output-schema-file for file-based input, not both");
3260
+ throw new MutagentError("INVALID_ARGUMENTS", "Cannot use --output-schema and --output-schema-file together", `Run: mutagent prompts update --help
3261
+ ` + "Use --output-schema for inline JSON or --output-schema-file for file-based input, not both");
3160
3262
  }
3161
3263
  if (options.outputSchema) {
3162
3264
  try {
3163
3265
  data.outputSchema = JSON.parse(options.outputSchema);
3164
3266
  } catch {
3165
- throw new MutagentError("INVALID_JSON", "Invalid JSON in --output-schema flag", `Provide a valid JSON Schema, e.g., '{"type":"object","properties":{"result":{"type":"string"}}}'`);
3267
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in --output-schema flag", `Run: mutagent prompts update --help
3268
+ ` + `Provide a valid JSON Schema, e.g., '{"type":"object","properties":{"result":{"type":"string"}}}'`);
3166
3269
  }
3167
3270
  } else if (options.outputSchemaFile) {
3168
3271
  if (!existsSync4(options.outputSchemaFile)) {
3169
- throw new MutagentError("FILE_NOT_FOUND", `File not found: ${options.outputSchemaFile}`, "Check the file path and try again");
3272
+ throw new MutagentError("FILE_NOT_FOUND", `File not found: ${options.outputSchemaFile}`, `Run: mutagent prompts update --help
3273
+ ` + "Check the file path and try again");
3170
3274
  }
3171
3275
  try {
3172
3276
  data.outputSchema = JSON.parse(readFileSync4(options.outputSchemaFile, "utf-8"));
3173
3277
  } catch {
3174
- throw new MutagentError("INVALID_JSON", `Failed to parse JSON from ${options.outputSchemaFile}`, "Ensure the file contains valid JSON Schema");
3278
+ throw new MutagentError("INVALID_JSON", `Failed to parse JSON from ${options.outputSchemaFile}`, `Run: mutagent prompts update --help
3279
+ ` + "Ensure the file contains valid JSON Schema");
3175
3280
  }
3176
3281
  }
3177
3282
  if (data.inputSchema && isValidJsonSchema(data.inputSchema)) {
3178
3283
  const missingDescs = validateSchemaDescriptions(data.inputSchema);
3179
3284
  if (missingDescs.length > 0) {
3180
- throw new MutagentError("VALIDATION_ERROR", `inputSchema properties missing descriptions: ${missingDescs.join(", ")}`, `Add a 'description' field to each property in your inputSchema. Example: { "properties": { "field": { "type": "string", "description": "What this field contains" } } }`);
3285
+ throw new MutagentError("VALIDATION_ERROR", `inputSchema properties missing descriptions: ${missingDescs.join(", ")}`, `Run: mutagent prompts update --help
3286
+ ` + `Add a 'description' field to each property in your inputSchema. Example: { "properties": { "field": { "type": "string", "description": "What this field contains" } } }`);
3181
3287
  }
3182
3288
  }
3183
3289
  if (Object.keys(data).length === 0) {
3184
- throw new MutagentError("MISSING_ARGUMENTS", "No update data provided", "Use --data, --raw-file, --name, --raw, --system/--human, --messages, --input-schema, or --output-schema");
3185
- }
3186
- const promptContent = data.rawPrompt ?? data.systemPrompt ?? data.humanPrompt ?? "";
3187
- if (promptContent && !isJson) {
3188
- warnSingleBraceVariables(promptContent, output);
3290
+ throw new MutagentError("MISSING_ARGUMENTS", "No update data provided", `Run: mutagent prompts update --help
3291
+ ` + "Use --data, --raw-file, --name, --raw, --system/--human, --messages, --input-schema, or --output-schema");
3189
3292
  }
3190
3293
  const client = getSDKClient();
3191
3294
  const prompt = await client.updatePrompt(id, data);
3192
3295
  if (isJson) {
3193
- output.output({ ...prompt, _links: promptLinks(prompt.id), _directive: promptUpdatedDirective(prompt.id, prompt.name) });
3296
+ const directive = promptUpdatedDirective(prompt.id, prompt.name);
3297
+ output.output({ ...prompt, _links: promptLinks(prompt.id), _directive: directive });
3298
+ echoDirectiveToStderr(directive);
3194
3299
  } else {
3195
3300
  output.success(`Updated prompt: ${prompt.name} (id: ${String(prompt.id)})`);
3196
3301
  const hints = formatCreationHints({
@@ -3224,7 +3329,8 @@ ${chalk6.dim("Note: --force is required. The CLI is non-interactive — confirm
3224
3329
  const output = new OutputFormatter(isJson ? "json" : "table");
3225
3330
  try {
3226
3331
  if (!options.force && !isJson) {
3227
- throw new MutagentError("CONFIRMATION_REQUIRED", `Deleting prompt ${id} requires confirmation`, `[Agent: Ask the user to confirm via MultiChoice, then pass --force]
3332
+ throw new MutagentError("CONFIRMATION_REQUIRED", `Deleting prompt ${id} requires confirmation`, `Run: mutagent prompts delete --help
3333
+ ` + `[Agent: Ask the user to confirm via MultiChoice, then pass --force]
3228
3334
  ` + `Use --force to confirm: mutagent prompts delete ${id} --force`);
3229
3335
  }
3230
3336
  const client = getSDKClient();
@@ -3233,7 +3339,9 @@ ${chalk6.dim("Note: --force is required. The CLI is non-interactive — confirm
3233
3339
  } catch (deleteError) {
3234
3340
  if (deleteError instanceof ApiError && deleteError.statusCode === 404) {
3235
3341
  if (isJson) {
3236
- output.output({ success: true, deletedId: id, _links: { prompts: promptsDashboardLink() }, _directive: promptDeletedDirective(id) });
3342
+ const directive = promptDeletedDirective(id);
3343
+ output.output({ success: true, deletedId: id, _links: { prompts: promptsDashboardLink() }, _directive: directive });
3344
+ echoDirectiveToStderr(directive);
3237
3345
  } else {
3238
3346
  output.success(`Prompt ${id} already deleted (idempotent)`);
3239
3347
  }
@@ -3242,7 +3350,9 @@ ${chalk6.dim("Note: --force is required. The CLI is non-interactive — confirm
3242
3350
  throw deleteError;
3243
3351
  }
3244
3352
  if (isJson) {
3245
- output.output({ success: true, deletedId: id, _links: { prompts: promptsDashboardLink() }, _directive: promptDeletedDirective(id) });
3353
+ const directive = promptDeletedDirective(id);
3354
+ output.output({ success: true, deletedId: id, _links: { prompts: promptsDashboardLink() }, _directive: directive });
3355
+ echoDirectiveToStderr(directive);
3246
3356
  } else {
3247
3357
  output.success(`Deleted prompt: ${id}`);
3248
3358
  output.info(`View prompts: ${promptsDashboardLink()}`);
@@ -3305,39 +3415,51 @@ Inline data format (-d):
3305
3415
  Expected item format:
3306
3416
  ${chalk6.dim('{"input": {"<field>": "<value>"}, "expectedOutput": {"<field>": "<value>"}}')}
3307
3417
 
3418
+ ${chalk6.yellow("AI Agent Note:")}
3419
+ Items MUST have BOTH input AND expectedOutput.
3420
+ Keys must match prompt's inputSchema.properties (input) and outputSchema.properties (expectedOutput).
3421
+ expectedOutput is REQUIRED for evaluation scoring.
3422
+ Check schemas: mutagent prompts get <prompt-id> --json
3423
+
3308
3424
  ${chalk6.red("Required: --data must be provided.")}
3309
3425
  `).action(async (promptId, options) => {
3310
3426
  const isJson = getJsonFlag(prompts);
3311
3427
  const output = new OutputFormatter(isJson ? "json" : "table");
3312
3428
  try {
3313
3429
  if (!options.data) {
3314
- throw new MutagentError("MISSING_ARGUMENTS", "-d/--data is required", "Use -d '[{...}]' to provide inline JSON data");
3430
+ throw new MutagentError("MISSING_ARGUMENTS", "-d/--data is required", `Run: mutagent prompts dataset add --help
3431
+ ` + "Use -d '[{...}]' to provide inline JSON data");
3315
3432
  }
3316
3433
  let content;
3317
3434
  try {
3318
3435
  const parsed = JSON.parse(options.data);
3319
3436
  if (!Array.isArray(parsed)) {
3320
- throw new MutagentError("INVALID_JSON", "Inline data must be a JSON array", `Provide a JSON array, e.g., '[{"input": {...}, "expectedOutput": {...}}]'`);
3437
+ throw new MutagentError("INVALID_JSON", "Inline data must be a JSON array", `Run: mutagent prompts dataset add --help
3438
+ ` + `Provide a JSON array, e.g., '[{"input": {...}, "expectedOutput": {...}}]'`);
3321
3439
  }
3322
3440
  content = options.data;
3323
3441
  } catch (e) {
3324
3442
  if (e instanceof MutagentError)
3325
3443
  throw e;
3326
- throw new MutagentError("INVALID_JSON", "Invalid JSON in -d/--data flag", `Provide a valid JSON array, e.g., '[{"input": {...}, "expectedOutput": {...}}]'`);
3444
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in -d/--data flag", `Run: mutagent prompts dataset add --help
3445
+ ` + `Provide a valid JSON array, e.g., '[{"input": {...}, "expectedOutput": {...}}]'`);
3327
3446
  }
3328
3447
  const datasetName = options.name;
3329
3448
  if (!datasetName) {
3330
- throw new MutagentError("MISSING_ARGUMENTS", "Dataset name is required", `[Agent: Ask the user for a dataset name via AskUserQuestion, then pass --name]
3449
+ throw new MutagentError("MISSING_ARGUMENTS", "Dataset name is required", `Run: mutagent prompts dataset add --help
3450
+ ` + `[Agent: Ask the user for a dataset name via AskUserQuestion, then pass --name]
3331
3451
  ` + `Use --name <name>, e.g., mutagent prompts dataset add ${promptId} --name "my-dataset" -d '[...]'`);
3332
3452
  }
3333
3453
  const client = getSDKClient();
3334
3454
  const datasetResult = await client.addDataset(promptId, content, datasetName);
3335
3455
  if (isJson) {
3456
+ const directive = datasetAddedDirective(promptId, datasetResult.id, datasetResult.name, datasetResult.itemCount);
3336
3457
  output.output({
3337
3458
  ...datasetResult,
3338
3459
  _links: datasetLinks(promptId, datasetResult.id),
3339
- _directive: datasetAddedDirective(promptId, datasetResult.id, datasetResult.name, datasetResult.itemCount)
3460
+ _directive: directive
3340
3461
  });
3462
+ echoDirectiveToStderr(directive);
3341
3463
  } else {
3342
3464
  output.success(`Added dataset "${datasetResult.name}" to prompt: ${promptId} (id: ${String(datasetResult.id)})`);
3343
3465
  if (datasetResult.itemCount !== undefined && datasetResult.itemCount > 0) {
@@ -3373,7 +3495,8 @@ Examples:
3373
3495
  const output = new OutputFormatter(isJson ? "json" : "table");
3374
3496
  try {
3375
3497
  if (!options.force && !isJson) {
3376
- throw new MutagentError("CONFIRMATION_REQUIRED", `Removing dataset ${datasetId} from prompt ${promptId} requires confirmation`, `[Agent: Ask the user to confirm via MultiChoice, then pass --force]
3498
+ throw new MutagentError("CONFIRMATION_REQUIRED", `Removing dataset ${datasetId} from prompt ${promptId} requires confirmation`, `Run: mutagent prompts dataset remove --help
3499
+ ` + `[Agent: Ask the user to confirm via MultiChoice, then pass --force]
3377
3500
  ` + `Use --force to confirm: mutagent prompts dataset remove ${promptId} ${datasetId} --force`);
3378
3501
  }
3379
3502
  const client = getSDKClient();
@@ -3382,7 +3505,9 @@ Examples:
3382
3505
  } catch (deleteError) {
3383
3506
  if (deleteError instanceof ApiError && deleteError.statusCode === 404) {
3384
3507
  if (isJson) {
3385
- output.output({ success: true, deletedId: datasetId, _links: { datasets: promptDatasetsLink(promptId) }, _directive: datasetRemovedDirective(promptId, datasetId) });
3508
+ const directive = datasetRemovedDirective(promptId, datasetId);
3509
+ output.output({ success: true, deletedId: datasetId, _links: { datasets: promptDatasetsLink(promptId) }, _directive: directive });
3510
+ echoDirectiveToStderr(directive);
3386
3511
  } else {
3387
3512
  output.success(`Dataset ${datasetId} already removed (idempotent)`);
3388
3513
  }
@@ -3391,7 +3516,9 @@ Examples:
3391
3516
  throw deleteError;
3392
3517
  }
3393
3518
  if (isJson) {
3394
- output.output({ success: true, deletedId: datasetId, _links: { datasets: promptDatasetsLink(promptId) }, _directive: datasetRemovedDirective(promptId, datasetId) });
3519
+ const directive = datasetRemovedDirective(promptId, datasetId);
3520
+ output.output({ success: true, deletedId: datasetId, _links: { datasets: promptDatasetsLink(promptId) }, _directive: directive });
3521
+ echoDirectiveToStderr(directive);
3395
3522
  } else {
3396
3523
  output.success(`Removed dataset ${datasetId} from prompt ${promptId}`);
3397
3524
  output.info(`View datasets: ${promptDatasetsLink(promptId)}`);
@@ -3500,7 +3627,7 @@ Examples:
3500
3627
  handleError(error, isJson);
3501
3628
  }
3502
3629
  });
3503
- evaluation.command("create").description("Create an evaluation configuration for a prompt").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").option("-d, --data <json>", "Evaluation as JSON string (for pre-validated criteria only)").option("-n, --name <name>", "Evaluation name (required unless --guided)").option("--description <text>", "Evaluation description").option("--guided", "Show evaluation workflow guide with prompt schema fields and criteria template (recommended)").addHelpText("after", `
3630
+ evaluation.command("create").description("Create an evaluation configuration for a prompt").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").option("-d, --data <json>", "Evaluation as JSON string (for pre-validated criteria only)").option("-n, --name <name>", "Evaluation name (required unless --guided)").option("--description <text>", "Evaluation description").option("--guided", "Interactive guided mode build criteria step by step (ALWAYS pair with --json for AI agents)").addHelpText("after", `
3504
3631
  Examples:
3505
3632
  ${chalk6.dim("$")} mutagent prompts evaluation create <prompt-id> --guided ${chalk6.dim("# recommended: shows workflow guide + schema fields")}
3506
3633
  ${chalk6.dim("$")} mutagent prompts evaluation create <prompt-id> --guided --json ${chalk6.dim("# structured workflow for AI agents")}
@@ -3516,9 +3643,11 @@ Guided Workflow (recommended):
3516
3643
  Works in all modes (TTY, non-TTY, --json).
3517
3644
 
3518
3645
  AI Agent Directive:
3519
- Before creating an eval, CHECK if criteria already exist in the user's code:
3520
- - If criteria match expected shape (name + description + evaluationParameter targeting schema fields) → use --data
3521
- - If criteria are missing or malformed → use --guided
3646
+ CRITICAL: Run mutagent prompts evaluation create --help FIRST.
3647
+ Then: mutagent prompts evaluation create <id> --guided --json
3648
+ NEVER --guided alone. ALWAYS --guided --json.
3649
+ NEVER construct criteria JSON manually.
3650
+ Parse askUserQuestions from --guided --json output, use AskUserQuestion to collect from user.
3522
3651
 
3523
3652
  Expected Criteria Shape (--data):
3524
3653
  ${chalk6.dim('{"evalConfig":{"criteria":[{"name":"<name>","description":"<scoring rubric>","evaluationParameter":"<schema field>"}]}}')}
@@ -3531,7 +3660,7 @@ ${chalk6.dim("Get prompt IDs: mutagent prompts list")}
3531
3660
  const isJson = getJsonFlag(prompts);
3532
3661
  const output = new OutputFormatter(isJson ? "json" : "table");
3533
3662
  try {
3534
- if (options.guided) {
3663
+ const buildGuidedWorkflow = async () => {
3535
3664
  const client2 = getSDKClient();
3536
3665
  const prompt = await client2.getPrompt(promptId);
3537
3666
  const inputFields = prompt.inputSchema && typeof prompt.inputSchema === "object" ? Object.keys(prompt.inputSchema.properties ?? {}) : [];
@@ -3559,48 +3688,26 @@ ${chalk6.dim("Get prompt IDs: mutagent prompts list")}
3559
3688
  ],
3560
3689
  multiSelect: false
3561
3690
  }));
3562
- const workflow = {
3691
+ return {
3563
3692
  prompt: { id: promptId, name: prompt.name },
3564
3693
  inputSchema: { fields: inputFields },
3565
3694
  outputSchema: { fields: outputFields },
3566
3695
  workflow: {
3567
3696
  description: "Follow these steps to create an evaluation for this prompt:",
3568
3697
  steps: [
3569
- {
3570
- step: 1,
3571
- action: "Review the prompt schemas above",
3572
- detail: "Each criterion must target a field from outputSchema (preferred) or inputSchema"
3573
- },
3574
- {
3575
- step: 2,
3576
- action: "Ask the user about each schema field using AskUserQuestion",
3577
- detail: "For EACH field listed in askUserQuestions below, present the question to the user. Collect their scoring rubric choice or custom description."
3578
- },
3579
- {
3580
- step: 3,
3581
- action: "Build criteria JSON from user answers",
3582
- detail: `Map each user answer to a criterion: { name: "<field> <rubric>", description: "<user's rubric>", evaluationParameter: "<field>" }`
3583
- },
3584
- {
3585
- step: 4,
3586
- action: "Ask for evaluation name",
3587
- detail: 'Ask the user what to name this evaluation (e.g., "Accuracy Check", "Quality Eval")'
3588
- },
3589
- {
3590
- step: 5,
3591
- action: "Create the evaluation",
3592
- detail: `Run: mutagent prompts evaluation create <prompt-id> --name "<name>" -d '{"evalConfig":{"criteria":[...]}}'`
3593
- }
3698
+ { step: 1, action: "Review the prompt schemas above", detail: "Each criterion must target a field from outputSchema (preferred) or inputSchema" },
3699
+ { step: 2, action: "Ask the user about each schema field using AskUserQuestion", detail: "For EACH field listed in askUserQuestions below, present the question to the user. Collect their scoring rubric choice or custom description." },
3700
+ { step: 3, action: "Build criteria JSON from user answers", detail: `Map each user answer to a criterion: { name: "<field> <rubric>", description: "<user's rubric>", evaluationParameter: "<field>" }` },
3701
+ { step: 4, action: "Ask for evaluation name", detail: 'Ask the user what to name this evaluation (e.g., "Accuracy Check", "Quality Eval")' },
3702
+ { step: 5, action: "Create the evaluation", detail: `Run: mutagent prompts evaluation create <prompt-id> --name "<name>" -d '{"evalConfig":{"criteria":[...]}}'` }
3594
3703
  ],
3595
3704
  criteriaTemplate: {
3596
3705
  evalConfig: {
3597
- criteria: [
3598
- {
3599
- name: "<criterion_name>",
3600
- description: "<scoring rubric - describe what 1.0 vs 0.0 means>",
3601
- evaluationParameter: `<one of: ${allFields.length > 0 ? allFields.map((f) => f.field).join(", ") : "no fields detected - check prompt schemas"}>`
3602
- }
3603
- ]
3706
+ criteria: [{
3707
+ name: "<criterion_name>",
3708
+ description: "<scoring rubric - describe what 1.0 vs 0.0 means>",
3709
+ evaluationParameter: `<one of: ${allFields.length > 0 ? allFields.map((f) => f.field).join(", ") : "no fields detected - check prompt schemas"}>`
3710
+ }]
3604
3711
  }
3605
3712
  },
3606
3713
  exampleCommand: `mutagent prompts evaluation create ${promptId} --name "My Evaluation" -d '${JSON.stringify({
@@ -3622,12 +3729,18 @@ ${chalk6.dim("Get prompt IDs: mutagent prompts list")}
3622
3729
  step2: "If criteria are missing or malformed, use the askUserQuestions payloads to collect them via AskUserQuestion.",
3623
3730
  step3: `After collecting all criteria, construct the --data JSON and run: mutagent prompts evaluation create <prompt-id> --name "<name>" -d '<json>'`
3624
3731
  }
3625
- }
3732
+ },
3733
+ _meta: { inputFields, outputFields, allFields }
3626
3734
  };
3735
+ };
3736
+ const renderGuidedWorkflow = (wf) => {
3737
+ const { inputFields, outputFields, allFields } = wf._meta;
3627
3738
  if (isJson) {
3628
- output.output(workflow);
3739
+ const { _meta: _discarded, ...cleanWorkflow } = wf;
3740
+ output.output(cleanWorkflow);
3741
+ echoDirectiveToStderr(wf._directive);
3629
3742
  } else {
3630
- output.success(`Guided Evaluation Workflow for prompt: ${prompt.name} (ID: ${promptId})`);
3743
+ output.success(`Guided Evaluation Workflow for prompt: ${wf.prompt.name} (ID: ${promptId})`);
3631
3744
  console.log("");
3632
3745
  if (outputFields.length > 0) {
3633
3746
  console.log(` Output Schema Fields: ${outputFields.join(", ")}`);
@@ -3647,15 +3760,24 @@ ${chalk6.dim("Get prompt IDs: mutagent prompts list")}
3647
3760
  console.log(` -d '{"evalConfig":{"criteria":[{"name":"accuracy","description":"Score 1.0 if correct","evaluationParameter":"${outputFields[0] ?? "<field>"}"}]}}'`);
3648
3761
  console.log("");
3649
3762
  }
3763
+ };
3764
+ if (options.guided) {
3765
+ const workflow = await buildGuidedWorkflow();
3766
+ renderGuidedWorkflow(workflow);
3650
3767
  return;
3651
3768
  }
3652
3769
  if (!options.data) {
3653
- throw new MutagentError("MISSING_ARGUMENTS", "No criteria source provided", `[Agent: Run --guided first to see available schema fields, then ask the user to define criteria via AskUserQuestion]
3654
- ` + `Use --guided to see the evaluation workflow and available schema fields, or provide criteria via --data.
3655
- ` + "Example: mutagent prompts evaluation create " + promptId + " --guided");
3770
+ if (isJson || process.stdout.isTTY) {
3771
+ const workflow = await buildGuidedWorkflow();
3772
+ renderGuidedWorkflow(workflow);
3773
+ return;
3774
+ }
3775
+ throw new MutagentError("MISSING_ARGUMENTS", "No criteria source provided", `Run: mutagent prompts evaluation create --help
3776
+ ` + "Then: mutagent prompts evaluation create " + promptId + " --guided --json");
3656
3777
  }
3657
3778
  if (!options.name) {
3658
- throw new MutagentError("MISSING_ARGUMENTS", "Evaluation name is required", `[Agent: Ask the user for an evaluation name via AskUserQuestion, then pass --name]
3779
+ throw new MutagentError("MISSING_ARGUMENTS", "Evaluation name is required", `Run: mutagent prompts evaluation create --help
3780
+ ` + `[Agent: Ask the user for an evaluation name via AskUserQuestion, then pass --name]
3659
3781
  ` + "Use --name <name>, e.g., mutagent prompts evaluation create " + promptId + ` --name "My Eval" --data '...'`);
3660
3782
  }
3661
3783
  const evalData = {
@@ -3673,7 +3795,8 @@ ${chalk6.dim("Get prompt IDs: mutagent prompts list")}
3673
3795
  if (parsed.metadata)
3674
3796
  evalData.metadata = parsed.metadata;
3675
3797
  } catch {
3676
- throw new MutagentError("INVALID_JSON", "Invalid JSON in --data flag", `Provide a valid JSON object, e.g., '{"evalConfig":{"criteria":[...]},"llmConfig":{"model":"gpt-4"}}'`);
3798
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in --data flag", `Run: mutagent prompts evaluation create --help
3799
+ ` + `Provide a valid JSON object, e.g., '{"evalConfig":{"criteria":[...]},"llmConfig":{"model":"gpt-4"}}'`);
3677
3800
  }
3678
3801
  if (options.name)
3679
3802
  evalData.name = options.name;
@@ -3697,7 +3820,8 @@ Detected output fields from prompt schema: ${fields.join(", ")}
3697
3820
  }
3698
3821
  }
3699
3822
  } catch {}
3700
- throw new MutagentError("VALIDATION_ERROR", "Evaluation criteria are required. Provide criteria via --data.", `Run with --guided to see available schema fields and criteria template.
3823
+ throw new MutagentError("VALIDATION_ERROR", "Evaluation criteria are required. Provide criteria via --data.", `Run: mutagent prompts evaluation create --help
3824
+ ` + "Then: mutagent prompts evaluation create " + promptId + ` --guided --json
3701
3825
  ` + fieldsHint + `
3702
3826
  Example JSON (--data flag):
3703
3827
  ` + ` --data '{"evalConfig":{"criteria":[{"name":"Accuracy","description":"...","evaluationParameter":"classification"}]}}'
@@ -3717,7 +3841,8 @@ Example JSON (--data flag):
3717
3841
  const hasEvalParam = c.evaluationParameter;
3718
3842
  if (!c.name || !hasDescription || !hasEvalParam) {
3719
3843
  const cName = typeof c.name === "string" ? c.name : "unnamed";
3720
- throw new MutagentError("VALIDATION_ERROR", `Criterion "${cName}" is missing required fields. Need: name, description, evaluationParameter.`, "Run with --guided to see available schema fields and criteria template. Use --data to pass well-formed criteria.");
3844
+ throw new MutagentError("VALIDATION_ERROR", `Criterion "${cName}" is missing required fields. Need: name, description, evaluationParameter.`, `Run: mutagent prompts evaluation create --help
3845
+ ` + "Then: mutagent prompts evaluation create " + promptId + " --guided --json");
3721
3846
  }
3722
3847
  }
3723
3848
  const seenParams = new Set;
@@ -3746,7 +3871,8 @@ Example JSON (--data flag):
3746
3871
  const uniqueDupes = [...new Set(duplicateParams)];
3747
3872
  const fieldsHint = availableFields.length > 0 ? `
3748
3873
  Available output fields: ${availableFields.join(", ")}` : "";
3749
- throw new MutagentError("VALIDATION_ERROR", `Duplicate evaluationParameter: "${uniqueDupes.join('", "')}". Each criterion must target a unique output field.`, "Each criterion scores a different output field. Fix by changing the evaluationParameter to a unique field." + fieldsHint + `
3874
+ throw new MutagentError("VALIDATION_ERROR", `Duplicate evaluationParameter: "${uniqueDupes.join('", "')}". Each criterion must target a unique output field.`, `Run: mutagent prompts evaluation create --help
3875
+ ` + "Each criterion scores a different output field. Fix by changing the evaluationParameter to a unique field." + fieldsHint + `
3750
3876
 
3751
3877
  Example:
3752
3878
  --data '{"evalConfig":{"criteria":[` + '{"name":"Accuracy","description":"...","evaluationParameter":"classification"},' + '{"name":"Confidence","description":"...","evaluationParameter":"confidence"}' + "]}}'");
@@ -3755,11 +3881,13 @@ Example:
3755
3881
  const evalResult = await client.createEvaluation(promptId, evalData);
3756
3882
  if (isJson) {
3757
3883
  const criteriaLen = evalData.evalConfig?.criteria?.length ?? 0;
3884
+ const directive = evaluationCreatedDirective(promptId, evalResult.id, evalResult.name, criteriaLen);
3758
3885
  output.output({
3759
3886
  ...evalResult,
3760
3887
  _links: evaluationLinks(promptId, evalResult.id),
3761
- _directive: evaluationCreatedDirective(promptId, evalResult.id, evalResult.name, criteriaLen)
3888
+ _directive: directive
3762
3889
  });
3890
+ echoDirectiveToStderr(directive);
3763
3891
  } else {
3764
3892
  output.success(`Created evaluation: ${evalResult.name} (id: ${String(evalResult.id)})`);
3765
3893
  const hints = formatCreationHints({
@@ -3789,7 +3917,8 @@ Examples:
3789
3917
  const output = new OutputFormatter(isJson ? "json" : "table");
3790
3918
  try {
3791
3919
  if (!options.force && !isJson) {
3792
- throw new MutagentError("CONFIRMATION_REQUIRED", `Deleting evaluation ${evaluationId} requires confirmation`, `[Agent: Ask the user to confirm via MultiChoice, then pass --force]
3920
+ throw new MutagentError("CONFIRMATION_REQUIRED", `Deleting evaluation ${evaluationId} requires confirmation`, `Run: mutagent prompts evaluation delete --help
3921
+ ` + `[Agent: Ask the user to confirm via MultiChoice, then pass --force]
3793
3922
  ` + `Use --force to confirm: mutagent prompts evaluation delete ${evaluationId} --force`);
3794
3923
  }
3795
3924
  const client = getSDKClient();
@@ -3798,7 +3927,9 @@ Examples:
3798
3927
  } catch (deleteError) {
3799
3928
  if (deleteError instanceof ApiError && deleteError.statusCode === 404) {
3800
3929
  if (isJson) {
3801
- output.output({ success: true, deletedId: evaluationId, _links: { dashboard: promptsDashboardLink() }, _directive: evaluationDeletedDirective(evaluationId) });
3930
+ const directive = evaluationDeletedDirective(evaluationId);
3931
+ output.output({ success: true, deletedId: evaluationId, _links: { dashboard: promptsDashboardLink() }, _directive: directive });
3932
+ echoDirectiveToStderr(directive);
3802
3933
  } else {
3803
3934
  output.success(`Evaluation ${evaluationId} already deleted (idempotent)`);
3804
3935
  }
@@ -3807,7 +3938,9 @@ Examples:
3807
3938
  throw deleteError;
3808
3939
  }
3809
3940
  if (isJson) {
3810
- output.output({ success: true, deletedId: evaluationId, _links: { dashboard: promptsDashboardLink() }, _directive: evaluationDeletedDirective(evaluationId) });
3941
+ const directive = evaluationDeletedDirective(evaluationId);
3942
+ output.output({ success: true, deletedId: evaluationId, _links: { dashboard: promptsDashboardLink() }, _directive: directive });
3943
+ echoDirectiveToStderr(directive);
3811
3944
  } else {
3812
3945
  output.success(`Evaluation ${evaluationId} deleted successfully`);
3813
3946
  output.info(`View evaluations: ${promptsDashboardLink()}`);
@@ -3833,11 +3966,15 @@ Examples:
3833
3966
  ${chalk6.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --max-iterations 5
3834
3967
  ${chalk6.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --target-score 0.95 --model claude-sonnet-4-5-20250929
3835
3968
  ${chalk6.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --json
3969
+ ${chalk6.yellow("Pre-Optimization Checklist:")}
3970
+ □ mutagent prompts get <id> --json ${chalk6.dim("(has inputSchema + outputSchema)")}
3971
+ □ mutagent prompts evaluation list <id> --json ${chalk6.dim("(exactly 1 evaluation)")}
3972
+ □ mutagent prompts dataset list <id> --json ${chalk6.dim("(dataset with expectedOutput)")}
3973
+ □ mutagent usage --json ${chalk6.dim("(remaining runs > 0)")}
3974
+
3836
3975
  ${PREREQUISITES_TEXT}
3837
3976
 
3838
3977
  ${chalk6.dim("Monitor progress with: mutagent prompts optimize status <job-id>")}
3839
-
3840
- ${chalk6.dim("AI Agent Note: After running commands, present CLI output to the user as a status report. Use --json for structured parsing.")}
3841
3978
  `).action(async (promptId, options) => {
3842
3979
  const isJson = getJsonFlag(prompts);
3843
3980
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3847,7 +3984,8 @@ ${chalk6.dim("AI Agent Note: After running commands, present CLI output to the u
3847
3984
  output.info("Running pre-flight checks...");
3848
3985
  const prompt = await client.getPrompt(promptId);
3849
3986
  if (isSchemaEmpty(prompt.outputSchema)) {
3850
- throw new MutagentError("MISSING_OUTPUT_SCHEMA", "Prompt is missing outputSchema — required for optimization", `Update your prompt: mutagent prompts update ${promptId} -d '{"outputSchema":{"type":"object","properties":{"result":{"type":"string"}}}}'`);
3987
+ throw new MutagentError("MISSING_OUTPUT_SCHEMA", "Prompt is missing outputSchema — required for optimization", `Run: mutagent prompts optimize start --help
3988
+ ` + `Update your prompt: mutagent prompts update ${promptId} -d '{"outputSchema":{"type":"object","properties":{"result":{"type":"string"}}}}'`);
3851
3989
  }
3852
3990
  if (isSchemaEmpty(prompt.inputSchema)) {
3853
3991
  output.warn("Prompt has no inputSchema. Optimization works best with defined input variables.");
@@ -3880,14 +4018,16 @@ ${chalk6.dim("AI Agent Note: After running commands, present CLI output to the u
3880
4018
  evalModel: options.evalModel
3881
4019
  });
3882
4020
  if (isJson) {
4021
+ const directive = startDirective(job, promptId);
3883
4022
  output.output({
3884
4023
  ...job,
3885
4024
  _links: {
3886
4025
  dashboard: optimizerLink(job.id),
3887
4026
  api: `/api/prompts/${promptId}/optimizations/${job.id}`
3888
4027
  },
3889
- _directive: startDirective(job, promptId)
4028
+ _directive: directive
3890
4029
  });
4030
+ echoDirectiveToStderr(directive);
3891
4031
  } else {
3892
4032
  renderOptimizationStartCard({ job, promptId, datasetId: options.dataset });
3893
4033
  }
@@ -3945,11 +4085,13 @@ Examples:
3945
4085
  const client = getSDKClient();
3946
4086
  const status = await client.getOptimizationStatus(jobId);
3947
4087
  if (isJson) {
4088
+ const directive = statusDirective(status);
3948
4089
  output.output({
3949
4090
  ...status,
3950
4091
  _links: { optimizer: optimizerLink(jobId) },
3951
- _directive: statusDirective(status)
4092
+ _directive: directive
3952
4093
  });
4094
+ echoDirectiveToStderr(directive);
3953
4095
  } else {
3954
4096
  renderOptimizationStatusCard(status);
3955
4097
  }
@@ -4026,8 +4168,10 @@ Actions:
4026
4168
  }
4027
4169
 
4028
4170
  // src/commands/traces.ts
4171
+ init_sdk_client();
4029
4172
  import { Command as Command4 } from "commander";
4030
4173
  import chalk7 from "chalk";
4174
+ init_errors();
4031
4175
  function createTracesCommand() {
4032
4176
  const traces = new Command4("traces").description("View and analyze traces (replaces Langfuse)").addHelpText("after", `
4033
4177
  Examples:
@@ -4174,10 +4318,12 @@ ${chalk7.dim("Exports to stdout by default. Use --output to save to a file.")}
4174
4318
  }
4175
4319
 
4176
4320
  // src/commands/integrate.ts
4321
+ init_config();
4177
4322
  import { Command as Command5 } from "commander";
4178
4323
  import chalk8 from "chalk";
4179
4324
  import { writeFileSync as writeFileSync3, existsSync as existsSync9 } from "fs";
4180
4325
  import { execSync } from "child_process";
4326
+ init_errors();
4181
4327
 
4182
4328
  // src/lib/integrations/langchain.ts
4183
4329
  import { readFileSync as readFileSync5, existsSync as existsSync5 } from "fs";
@@ -4931,8 +5077,10 @@ AI AGENT: Execute these steps using Bash for install, Write/Edit for code change
4931
5077
  }
4932
5078
 
4933
5079
  // src/commands/agents.ts
5080
+ init_sdk_client();
4934
5081
  import { Command as Command6 } from "commander";
4935
5082
  import chalk9 from "chalk";
5083
+ init_errors();
4936
5084
  function createAgentsCommand() {
4937
5085
  const agents = new Command6("agents").description("Manage AI agents").addHelpText("after", `
4938
5086
  Examples:
@@ -5343,8 +5491,10 @@ Examples:
5343
5491
  }
5344
5492
 
5345
5493
  // src/commands/config.ts
5494
+ init_config();
5346
5495
  import { Command as Command7 } from "commander";
5347
5496
  import chalk10 from "chalk";
5497
+ init_errors();
5348
5498
  var VALID_CONFIG_KEYS = ["apiKey", "endpoint", "format", "timeout", "defaultWorkspace", "defaultOrganization"];
5349
5499
  function createConfigCommand() {
5350
5500
  const config = new Command7("config").description("Manage CLI configuration").addHelpText("after", `
@@ -5434,8 +5584,10 @@ ${chalk10.dim("Persists organization ID for org-scoped API keys.")}
5434
5584
  }
5435
5585
 
5436
5586
  // src/commands/playground.ts
5587
+ init_sdk_client();
5437
5588
  import { Command as Command8 } from "commander";
5438
5589
  import chalk11 from "chalk";
5590
+ init_errors();
5439
5591
  function parseSSELine(line) {
5440
5592
  if (!line || line.startsWith(":")) {
5441
5593
  return null;
@@ -5687,8 +5839,10 @@ Streaming Output:`));
5687
5839
  }
5688
5840
 
5689
5841
  // src/commands/workspaces.ts
5842
+ init_sdk_client();
5690
5843
  import { Command as Command9 } from "commander";
5691
5844
  import chalk12 from "chalk";
5845
+ init_errors();
5692
5846
  function createWorkspacesCommand() {
5693
5847
  const workspaces = new Command9("workspaces").description("View workspaces (read-only)").addHelpText("after", `
5694
5848
  Examples:
@@ -5775,8 +5929,10 @@ Examples:
5775
5929
  }
5776
5930
 
5777
5931
  // src/commands/providers.ts
5932
+ init_sdk_client();
5778
5933
  import { Command as Command10 } from "commander";
5779
5934
  import chalk13 from "chalk";
5935
+ init_errors();
5780
5936
  var VALID_PROVIDER_TYPES = [
5781
5937
  "openai",
5782
5938
  "anthropic",
@@ -5945,12 +6101,14 @@ Available Models:`));
5945
6101
  }
5946
6102
 
5947
6103
  // src/commands/init.ts
6104
+ init_config();
5948
6105
  import { Command as Command11 } from "commander";
5949
6106
  import inquirer3 from "inquirer";
5950
6107
  import chalk14 from "chalk";
5951
6108
  import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "fs";
5952
6109
  import { execSync as execSync2 } from "child_process";
5953
6110
  import { join as join5 } from "path";
6111
+ init_errors();
5954
6112
  var FRAMEWORK_DETECTION_MAP = {
5955
6113
  "@mastra/core": {
5956
6114
  name: "mastra",
@@ -6185,7 +6343,35 @@ Modes:
6185
6343
  }
6186
6344
  const config = loadConfig();
6187
6345
  const endpoint = config.endpoint ?? "https://api.mutagent.io";
6188
- const workspace = config.defaultWorkspace;
6346
+ let workspace = config.defaultWorkspace;
6347
+ let workspaceValidation;
6348
+ if (authenticated) {
6349
+ try {
6350
+ const apiKey = getApiKey();
6351
+ if (apiKey) {
6352
+ const { fetchOrganizations: fetchOrganizations2, fetchWorkspaces: fetchWorkspaces2 } = await Promise.resolve().then(() => (init_sdk_client(), exports_sdk_client));
6353
+ let orgId = config.defaultOrganization;
6354
+ if (!orgId) {
6355
+ const orgs = await fetchOrganizations2(apiKey, endpoint);
6356
+ orgId = orgs[0]?.id;
6357
+ }
6358
+ if (orgId) {
6359
+ const workspaces = await fetchWorkspaces2(apiKey, endpoint, orgId);
6360
+ if (workspaces.length > 0) {
6361
+ const found = workspace ? workspaces.find((w) => w.id === workspace) : undefined;
6362
+ if (found) {
6363
+ workspaceValidation = { id: found.id, name: found.name, validated: true, corrected: false };
6364
+ } else if (workspaces[0]) {
6365
+ const first = workspaces[0];
6366
+ setDefaultWorkspace(first.id);
6367
+ workspace = first.id;
6368
+ workspaceValidation = { id: first.id, name: first.name, validated: true, corrected: true };
6369
+ }
6370
+ }
6371
+ }
6372
+ }
6373
+ } catch {}
6374
+ }
6189
6375
  const rcConfig = {
6190
6376
  endpoint,
6191
6377
  ...workspace ? { workspace } : {},
@@ -6206,6 +6392,16 @@ Modes:
6206
6392
  }
6207
6393
  writeRcConfig(rcConfig, cwd);
6208
6394
  output.success("Created .mutagentrc.json");
6395
+ if (!isJson && workspaceValidation) {
6396
+ if (workspaceValidation.corrected) {
6397
+ output.warn(`Workspace auto-corrected to: ${workspaceValidation.name} (${workspaceValidation.id})`);
6398
+ } else {
6399
+ output.info(`Workspace: ${workspaceValidation.name} (${workspaceValidation.id})`);
6400
+ }
6401
+ }
6402
+ if (!isJson) {
6403
+ output.info("Verify workspace: mutagent workspaces list --json");
6404
+ }
6209
6405
  console.log("");
6210
6406
  output.info("Next steps:");
6211
6407
  output.info(` 1. Run: mutagent integrate ${confirmedFramework.name}`);
@@ -6214,10 +6410,20 @@ Modes:
6214
6410
  } else {
6215
6411
  writeRcConfig(rcConfig, cwd);
6216
6412
  output.success("Created .mutagentrc.json");
6413
+ if (!isJson && workspaceValidation) {
6414
+ if (workspaceValidation.corrected) {
6415
+ output.warn(`Workspace auto-corrected to: ${workspaceValidation.name} (${workspaceValidation.id})`);
6416
+ } else {
6417
+ output.info(`Workspace: ${workspaceValidation.name} (${workspaceValidation.id})`);
6418
+ }
6419
+ }
6217
6420
  if (!authenticated) {
6218
6421
  output.info("Next: mutagent auth login --browser");
6219
6422
  } else {
6220
6423
  output.info('Ready! Run "mutagent --help" to see available commands.');
6424
+ if (!isJson) {
6425
+ output.info("Verify workspace: mutagent workspaces list --json");
6426
+ }
6221
6427
  }
6222
6428
  }
6223
6429
  if (!isNonInteractive) {
@@ -6253,7 +6459,12 @@ Modes:
6253
6459
  configFile: ".mutagentrc.json",
6254
6460
  config: rcConfig,
6255
6461
  framework: confirmedFramework?.name ?? null,
6256
- authenticated
6462
+ authenticated,
6463
+ workspaceValidation: workspaceValidation ?? null,
6464
+ _directive: {
6465
+ instruction: "Verify workspace. Run: mutagent workspaces list --json",
6466
+ next: ["mutagent workspaces list --json", "mutagent prompts list --json"]
6467
+ }
6257
6468
  });
6258
6469
  }
6259
6470
  } catch (error) {
@@ -6267,6 +6478,7 @@ Modes:
6267
6478
  import { Command as Command12 } from "commander";
6268
6479
  import chalk15 from "chalk";
6269
6480
  import { resolve as resolve3 } from "path";
6481
+ init_errors();
6270
6482
  function createExploreCommand() {
6271
6483
  const explore = new Command12("explore").description("Scan codebase for prompts, datasets, and MutagenT markers").option("-p, --path <dir>", "Directory to scan", ".").option("--depth <n>", "Max directory depth", "10").option("--include <glob>", "Include file pattern", "**/*.{ts,js,py,tsx,jsx}").option("--exclude <dirs>", "Comma-separated directories to exclude", "node_modules,dist,.git,build,.next,__pycache__,venv,.venv").option("--markers-only", "Only find existing MutagenT markers").addHelpText("after", `
6272
6484
  Examples:
@@ -6532,8 +6744,11 @@ ${SKILL_BODY}
6532
6744
  }
6533
6745
 
6534
6746
  // src/commands/usage.ts
6747
+ init_config();
6535
6748
  import { Command as Command14 } from "commander";
6536
6749
  import chalk17 from "chalk";
6750
+ init_errors();
6751
+ init_sdk_client();
6537
6752
  var TRIAL_OPTIMIZATION_LIMIT = 5;
6538
6753
  var BILLING_URL = "https://app.mutagent.io/settings/billing";
6539
6754
  function renderProgressBar(used, limit, width = 30) {
@@ -6628,7 +6843,7 @@ Examples:
6628
6843
  }
6629
6844
 
6630
6845
  // src/bin/cli.ts
6631
- import { existsSync as existsSync12 } from "fs";
6846
+ init_config();
6632
6847
  var cliVersion = "0.1.1";
6633
6848
  if (process.env.CLI_VERSION) {
6634
6849
  cliVersion = process.env.CLI_VERSION;
@@ -6650,65 +6865,56 @@ program.name("mutagent").description(`MutagenT CLI - AI-native prompt optimizati
6650
6865
  });
6651
6866
  program.addHelpText("after", `
6652
6867
  ${chalk18.yellow("Non-Interactive Mode (CI/CD & Coding Agents):")}
6653
- Export your API key: ${chalk18.green("export MUTAGENT_API_KEY=mt_your_key_here")}
6654
- Or pass inline: ${chalk18.green("mutagent prompts list --api-key mt_your_key")}
6655
- Machine-readable output: ${chalk18.green("mutagent prompts list --json")}
6656
- Disable prompts: ${chalk18.green("mutagent prompts list --non-interactive")}
6657
- Set default workspace: ${chalk18.green("mutagent config set workspace <workspace-id>")}
6658
- Set default org: ${chalk18.green("mutagent config set org <org-id>")}
6659
- `);
6660
- program.addHelpText("after", `
6661
- ${chalk18.yellow("Workflows:")}
6662
- ${chalk18.bold("Evaluate Optimize Loop:")}
6663
- 1. mutagent prompts create --name "..." --raw-file prompt.txt
6664
- 2. mutagent prompts dataset add <prompt-id> --name "..." -d '[{"input":{...},"expectedOutput":{...}}]'
6665
- 3. mutagent prompts evaluation create <prompt-id> --name "..." -d '{"evalConfig":{"criteria":[...]}}'
6666
- 4. mutagent prompts optimize start <prompt-id> --dataset <id> --max-iterations 1
6667
-
6668
- ${chalk18.bold("Quick Test:")}
6669
- mutagent playground run <prompt-id> --input '{"key":"value"}'
6670
-
6671
- ${chalk18.bold("Prerequisites for Optimization:")}
6672
- ${chalk18.green("✓")} Prompt with input/output parameters
6673
- ${chalk18.green("")} Dataset with items (input + expectedOutput pairs)
6674
- ${chalk18.green("")} Evaluation with criteria (field-level, input/output focused)
6675
- ${chalk18.dim("•")} LLM provider ${chalk18.dim("(only when server uses external providers)")}
6676
- `);
6677
- var skillInstalled = existsSync12(join7(findRepoRoot(), ".claude/skills/mutagent-cli/SKILL.md"));
6678
- program.addHelpText("after", `
6679
- ${chalk18.cyan("┌─ AI AGENT INTEGRATION HINT ────────────────────────────────────────────────┐")}
6680
- ${chalk18.cyan("")} ${chalk18.cyan("│")}
6681
- ${chalk18.cyan("│")} Frameworks: langchain, langgraph, vercel-ai, openai ${chalk18.cyan("")}
6682
- ${chalk18.cyan("│")} ${chalk18.cyan("│")}
6683
- ${chalk18.cyan("│")} Get integration guide: mutagent integrate <framework> ${chalk18.cyan("│")}
6684
- ${chalk18.cyan("│")} Verify setup: mutagent integrate <framework> --verify ${chalk18.cyan("")}
6685
- ${chalk18.cyan("│")} Use --json for AI parsing: mutagent <command> --json ${chalk18.cyan("")}
6686
- ${chalk18.cyan("│")} ${chalk18.cyan("")}
6687
- ${chalk18.cyan("└────────────────────────────────────────────────────────────────────────────┘")}
6688
- ${!hasCredentials() ? chalk18.yellow(`
6689
- Warning: Not authenticated. Run: mutagent auth login --browser
6690
- `) : ""}${!hasRcConfig() ? chalk18.green(`
6691
- Get started: mutagent init
6692
- `) : ""}
6693
- ${chalk18.red.bold("┌─ CRITICAL: AI CODING AGENT READ THIS FIRST ─────────────────────────────┐")}
6694
- ${chalk18.red.bold("│")} ${chalk18.red.bold("│")}
6695
- ${chalk18.red.bold("│")} MutagenT Skill Status: ${skillInstalled ? chalk18.green.bold("INSTALLED ✓") + " " : chalk18.yellow.bold("NOT INSTALLED") + " "}${chalk18.red.bold("│")}
6696
- ${chalk18.red.bold("│")} ${chalk18.red.bold("│")}${skillInstalled ? "" : `
6697
- ${chalk18.red.bold("│")} The MutagenT CLI skill (.claude/skills/mutagent-cli/SKILL.md) is ${chalk18.red.bold("│")}
6698
- ${chalk18.red.bold("│")} NOT installed in this project. This skill teaches you how to use ${chalk18.red.bold("│")}
6699
- ${chalk18.red.bold("│")} the MutagenT CLI effectively for prompt optimization workflows. ${chalk18.red.bold("│")}
6700
- ${chalk18.red.bold("")} ${chalk18.red.bold("│")}
6701
- ${chalk18.red.bold("│")} ACTION REQUIRED: Ask the user: ${chalk18.red.bold("│")}
6702
- ${chalk18.red.bold("│")} "Install the MutagenT CLI skill for better AI assistance? (Yes/No)" ${chalk18.red.bold("│")}
6703
- ${chalk18.red.bold("│")} ${chalk18.red.bold("│")}
6704
- ${chalk18.red.bold("│")} If Yes → run: mutagent skills install ${chalk18.red.bold("│")}
6705
- ${chalk18.red.bold("│")} If No → continue without skill (reduced guidance) ${chalk18.red.bold("│")}
6706
- ${chalk18.red.bold("│")} ${chalk18.red.bold("│")}`}
6707
- ${chalk18.red.bold("│")} After install, the skill auto-loads when triggers match: ${chalk18.red.bold("│")}
6708
- ${chalk18.red.bold("│")} "mutagent", "optimize prompt", "integrate tracing", etc. ${chalk18.red.bold("│")}
6709
- ${chalk18.red.bold("│")} ${chalk18.red.bold("│")}
6710
- ${chalk18.red.bold("└────────────────────────────────────────────────────────────────────────────┘")}
6711
- `);
6868
+ export MUTAGENT_API_KEY=mt_... ${chalk18.dim("or")} --api-key mt_...
6869
+ --json ${chalk18.dim("for structured output")} --non-interactive ${chalk18.dim("to disable prompts")}
6870
+
6871
+ ${chalk18.yellow("Command Navigation:")}
6872
+ mutagent auth login --browser ${chalk18.dim("Authenticate (OAuth)")}
6873
+ mutagent auth status ${chalk18.dim("Check auth + workspace")}
6874
+ mutagent init ${chalk18.dim("Initialize project (.mutagentrc.json)")}
6875
+ mutagent explore ${chalk18.dim("Discover prompts in codebase")}
6876
+ mutagent workspaces list --json ${chalk18.dim("List workspaces (verify ID)")}
6877
+ mutagent config set workspace <id> ${chalk18.dim("Set active workspace")}
6878
+ mutagent usage --json ${chalk18.dim("Check plan limits")}
6879
+
6880
+ mutagent prompts create --help ${chalk18.dim("Upload prompt (read help first!)")}
6881
+ mutagent prompts list --json ${chalk18.dim("List prompts")}
6882
+ mutagent prompts get <id> --json ${chalk18.dim("Full prompt details + schemas")}
6883
+
6884
+ mutagent prompts dataset add --help ${chalk18.dim("Upload dataset (read help first!)")}
6885
+ mutagent prompts dataset list <id> ${chalk18.dim("List datasets")}
6886
+
6887
+ mutagent prompts evaluation create --help ${chalk18.dim("Create eval (read help first!)")}
6888
+ mutagent prompts evaluation create <id> --guided --json ${chalk18.dim("Guided eval workflow")}
6889
+ mutagent prompts evaluation list <id> --json ${chalk18.dim("List evaluations")}
6890
+
6891
+ mutagent prompts optimize start --help ${chalk18.dim("Run optimization (read help first!)")}
6892
+ mutagent prompts optimize status <job-id> ${chalk18.dim("Poll progress")}
6893
+ mutagent prompts optimize results <job-id> ${chalk18.dim("View scorecard")}
6894
+
6895
+ mutagent integrate <framework> ${chalk18.dim("Framework integration guide")}
6896
+ mutagent playground run <id> --input '{...}' ${chalk18.dim("Quick test")}
6897
+
6898
+ ${chalk18.yellow("Workflow: Evaluate Optimize:")}
6899
+ 1. mutagent prompts create --help ${chalk18.dim("← read help")}
6900
+ 2. mutagent prompts create ... --json ${chalk18.dim("← upload prompt with {variables}")}
6901
+ 3. mutagent prompts dataset add --help ${chalk18.dim("← read help")}
6902
+ 4. mutagent prompts dataset add <id> ... --json ${chalk18.dim("← upload dataset")}
6903
+ 5. mutagent prompts evaluation create <id> --guided --json ${chalk18.dim("← guided eval")}
6904
+ 6. mutagent prompts optimize start <id> --dataset <d> --evaluation <e> --json
6905
+
6906
+ ${chalk18.yellow("AI Agent Rules:")}
6907
+ 1. ALWAYS run <command> --help before using any command for the first time
6908
+ 2. ALWAYS use --json on every command execution
6909
+ 3. ALWAYS use --guided --json for evaluation creation (never --guided alone)
6910
+ 4. ALWAYS display _directive status cards to the user after mutations
6911
+ 5. After mutagent init, verify workspace: mutagent workspaces list --json
6912
+ 6. Use {single_braces} for template variables in prompts
6913
+ ${!hasCredentials() ? `
6914
+ ` + chalk18.yellow(" Warning: Not authenticated. Run: mutagent auth login --browser") + `
6915
+ ` : ""}${!hasRcConfig() ? `
6916
+ ` + chalk18.green(" Get started: mutagent init") + `
6917
+ ` : ""}`);
6712
6918
  program.hook("preAction", (thisCommand) => {
6713
6919
  const globalOpts = thisCommand.optsWithGlobals();
6714
6920
  if (globalOpts.apiKey && !process.env.MUTAGENT_API_KEY) {
@@ -6737,5 +6943,5 @@ program.addCommand(createSkillsCommand());
6737
6943
  program.addCommand(createUsageCommand());
6738
6944
  program.parse();
6739
6945
 
6740
- //# debugId=C797200705360DE264756E2164756E21
6946
+ //# debugId=E8884F7D56DA73D764756E2164756E21
6741
6947
  //# sourceMappingURL=cli.js.map