@mutagent/cli 0.1.89 → 0.1.91

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
@@ -616,6 +616,20 @@ class SDKClientWrapper {
616
616
  this.handleError(error);
617
617
  }
618
618
  }
619
+ async getDataset(datasetId) {
620
+ try {
621
+ return await this.request(`/api/prompts/datasets/${String(datasetId)}`);
622
+ } catch (error) {
623
+ this.handleError(error);
624
+ }
625
+ }
626
+ async getDatasetItem(itemId) {
627
+ try {
628
+ return await this.request(`/api/prompts/dataset-items/${String(itemId)}`);
629
+ } catch (error) {
630
+ this.handleError(error);
631
+ }
632
+ }
619
633
  async listDatasets(promptId) {
620
634
  try {
621
635
  const response = await this.request(`/api/prompt/${promptId}/datasets`);
@@ -1142,7 +1156,7 @@ var init_sdk_client = __esm(() => {
1142
1156
 
1143
1157
  // src/bin/cli.ts
1144
1158
  import { Command as Command20 } from "commander";
1145
- import chalk31 from "chalk";
1159
+ import chalk32 from "chalk";
1146
1160
  import { readFileSync as readFileSync12 } from "fs";
1147
1161
  import { join as join10, dirname as dirname2 } from "path";
1148
1162
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -1151,9 +1165,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
1151
1165
  init_config();
1152
1166
  init_sdk_client();
1153
1167
  import { Command } from "commander";
1154
- import inquirer from "inquirer";
1155
- import chalk3 from "chalk";
1156
- import ora from "ora";
1168
+ import chalk4 from "chalk";
1157
1169
  import { existsSync as existsSync3 } from "fs";
1158
1170
  import { join as join4 } from "path";
1159
1171
 
@@ -1304,143 +1316,6 @@ function createSpinner(text, isJson) {
1304
1316
  // src/commands/auth.ts
1305
1317
  init_errors();
1306
1318
 
1307
- // src/lib/browser-auth.ts
1308
- import { hostname, platform } from "os";
1309
- function generateCliToken() {
1310
- return crypto.randomUUID();
1311
- }
1312
- async function initBrowserAuth(endpoint, cliToken) {
1313
- const response = await fetch(`${endpoint}/api/auth/cli/init`, {
1314
- method: "POST",
1315
- headers: { "Content-Type": "application/json" },
1316
- body: JSON.stringify({
1317
- cliToken,
1318
- hostname: hostname(),
1319
- platform: platform()
1320
- })
1321
- });
1322
- if (!response.ok) {
1323
- const errorText = await response.text();
1324
- throw new BrowserAuthError("INIT_FAILED", "Failed to initialize browser auth: " + String(response.status) + " " + errorText);
1325
- }
1326
- const data = await response.json();
1327
- return data;
1328
- }
1329
- async function pollAuthStatus(endpoint, cliToken) {
1330
- const response = await fetch(`${endpoint}/api/auth/cli/status?token=${encodeURIComponent(cliToken)}`);
1331
- if (!response.ok) {
1332
- const errorText = await response.text();
1333
- throw new BrowserAuthError("POLL_FAILED", "Failed to poll auth status: " + String(response.status) + " " + errorText);
1334
- }
1335
- const data = await response.json();
1336
- return data;
1337
- }
1338
- async function openBrowser(url) {
1339
- if (process.env.MUTAGENT_TEST_MODE === "true") {
1340
- console.log(`AUTH_URL:${url}`);
1341
- return;
1342
- }
1343
- try {
1344
- const { default: open } = await import("open");
1345
- await open(url);
1346
- } catch {
1347
- throw new BrowserAuthError("BROWSER_OPEN_FAILED", `Could not open browser automatically. Please visit: ${url}`);
1348
- }
1349
- }
1350
- function sleep(ms) {
1351
- return new Promise((resolve) => setTimeout(resolve, ms));
1352
- }
1353
- async function performBrowserAuth(options, onStatusUpdate) {
1354
- const {
1355
- endpoint,
1356
- timeout = 300000,
1357
- pollInterval = 2000,
1358
- skipBrowserOpen = false
1359
- } = options;
1360
- const cliToken = generateCliToken();
1361
- onStatusUpdate?.("Initializing browser authentication...");
1362
- const initResponse = await initBrowserAuth(endpoint, cliToken);
1363
- const { authUrl } = initResponse;
1364
- if (!skipBrowserOpen) {
1365
- onStatusUpdate?.("Opening browser for authentication...");
1366
- try {
1367
- await openBrowser(authUrl);
1368
- } catch (error) {
1369
- if (error instanceof BrowserAuthError && error.code === "BROWSER_OPEN_FAILED") {
1370
- onStatusUpdate?.(error.message);
1371
- } else {
1372
- throw error;
1373
- }
1374
- }
1375
- }
1376
- console.log("");
1377
- console.log(" Open this URL to authenticate:");
1378
- console.log("");
1379
- console.log(" " + authUrl);
1380
- console.log("");
1381
- onStatusUpdate?.("Waiting for browser authentication...");
1382
- const startTime = Date.now();
1383
- while (Date.now() - startTime < timeout) {
1384
- await sleep(pollInterval);
1385
- const status = await pollAuthStatus(endpoint, cliToken);
1386
- switch (status.status) {
1387
- case "pending":
1388
- continue;
1389
- case "completed":
1390
- if (!status.apiKey || !status.workspaceId || !status.workspaceName || !status.organizationId || !status.organizationName) {
1391
- throw new BrowserAuthError("INCOMPLETE_RESPONSE", "Server returned incomplete auth response");
1392
- }
1393
- return {
1394
- apiKey: status.apiKey,
1395
- workspaceId: status.workspaceId,
1396
- workspaceName: status.workspaceName,
1397
- organizationId: status.organizationId,
1398
- organizationName: status.organizationName,
1399
- expiresAt: status.expiresAt
1400
- };
1401
- case "expired":
1402
- throw new BrowserAuthError("AUTH_EXPIRED", "Browser authentication expired. Please try again.");
1403
- case "denied":
1404
- throw new BrowserAuthError("AUTH_DENIED", status.error ?? "Browser authentication was denied.");
1405
- case "not_found":
1406
- throw new BrowserAuthError("TOKEN_NOT_FOUND", "Authentication token not found. Please try again.");
1407
- default:
1408
- throw new BrowserAuthError("UNKNOWN_STATUS", "Unknown auth status: " + String(status.status));
1409
- }
1410
- }
1411
- throw new BrowserAuthError("AUTH_TIMEOUT", "Browser authentication timed out after 5 minutes. Please try again.");
1412
- }
1413
-
1414
- class BrowserAuthError extends Error {
1415
- code;
1416
- constructor(code, message) {
1417
- super(message);
1418
- this.name = "BrowserAuthError";
1419
- this.code = code;
1420
- }
1421
- getSuggestion() {
1422
- switch (this.code) {
1423
- case "INIT_FAILED":
1424
- return "Check your endpoint configuration and network connection.";
1425
- case "POLL_FAILED":
1426
- return "Check your network connection and try again.";
1427
- case "BROWSER_OPEN_FAILED":
1428
- return "Copy the URL above and open it manually in your browser.";
1429
- case "AUTH_EXPIRED":
1430
- case "AUTH_TIMEOUT":
1431
- return 'Run "mutagent auth login" again to restart authentication.';
1432
- case "AUTH_DENIED":
1433
- return "Ensure you have access to the workspace and try again.";
1434
- case "TOKEN_NOT_FOUND":
1435
- case "INCOMPLETE_RESPONSE":
1436
- case "UNKNOWN_STATUS":
1437
- return "Please try again. If the issue persists, contact support.";
1438
- default:
1439
- return "Please try again.";
1440
- }
1441
- }
1442
- }
1443
-
1444
1319
  // src/lib/mutation-context.ts
1445
1320
  import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
1446
1321
  import { join as join2, resolve } from "path";
@@ -2059,266 +1934,424 @@ function runOptimizationPath(promptCount, datasetCount) {
2059
1934
  console.log(chalk2.dim(` Upload one: mutagent prompts create --name "my-prompt" --raw-file <path>`));
2060
1935
  console.log("");
2061
1936
  }
2062
- if (datasetCount === 0) {
2063
- console.log(` ${String(step)}. ${chalk2.green(`mutagent prompts dataset add <prompt-id> -d '[{"input":{...},"expectedOutput":{...}}]' --name "my-dataset"`)}`);
2064
- console.log(" Upload a dataset with input/output pairs");
2065
- console.log("");
2066
- step++;
2067
- } else {
2068
- console.log(chalk2.dim(` ${chalk2.green("✓")} Datasets detected in codebase (${String(datasetCount)} found)`));
2069
- console.log(chalk2.dim(` Upload one: mutagent prompts dataset add <prompt-id> -d '[...]' --name "my-dataset"`));
2070
- console.log("");
1937
+ if (datasetCount === 0) {
1938
+ console.log(` ${String(step)}. ${chalk2.green(`mutagent prompts dataset add <prompt-id> -d '[{"input":{...},"expectedOutput":{...}}]' --name "my-dataset"`)}`);
1939
+ console.log(" Upload a dataset with input/output pairs");
1940
+ console.log("");
1941
+ step++;
1942
+ } else {
1943
+ console.log(chalk2.dim(` ${chalk2.green("✓")} Datasets detected in codebase (${String(datasetCount)} found)`));
1944
+ console.log(chalk2.dim(` Upload one: mutagent prompts dataset add <prompt-id> -d '[...]' --name "my-dataset"`));
1945
+ console.log("");
1946
+ }
1947
+ console.log(` ${String(step)}. ${chalk2.green(`mutagent prompts evaluation create <prompt-id> --name "My Eval" -d '{"evalConfig":{"criteria":[...]}}'`)}`);
1948
+ console.log(" Define evaluation criteria");
1949
+ console.log("");
1950
+ step++;
1951
+ console.log(` ${String(step)}. ${chalk2.green("mutagent prompts optimize start <prompt-id> --dataset <dataset-id>")}`);
1952
+ console.log(" Start the optimization loop");
1953
+ console.log("");
1954
+ console.log(chalk2.dim(" Tip: Use `mutagent prompts list` to see your prompt IDs."));
1955
+ console.log("");
1956
+ }
1957
+
1958
+ // src/lib/auth-flow.ts
1959
+ init_config();
1960
+ init_sdk_client();
1961
+ init_errors();
1962
+ import inquirer from "inquirer";
1963
+ import chalk3 from "chalk";
1964
+ import ora from "ora";
1965
+
1966
+ // src/lib/browser-auth.ts
1967
+ import { hostname, platform } from "os";
1968
+ function generateCliToken() {
1969
+ return crypto.randomUUID();
1970
+ }
1971
+ async function initBrowserAuth(endpoint, cliToken) {
1972
+ const response = await fetch(`${endpoint}/api/auth/cli/init`, {
1973
+ method: "POST",
1974
+ headers: { "Content-Type": "application/json" },
1975
+ body: JSON.stringify({
1976
+ cliToken,
1977
+ hostname: hostname(),
1978
+ platform: platform()
1979
+ })
1980
+ });
1981
+ if (!response.ok) {
1982
+ const errorText = await response.text();
1983
+ throw new BrowserAuthError("INIT_FAILED", "Failed to initialize browser auth: " + String(response.status) + " " + errorText);
1984
+ }
1985
+ const data = await response.json();
1986
+ return data;
1987
+ }
1988
+ async function pollAuthStatus(endpoint, cliToken) {
1989
+ const response = await fetch(`${endpoint}/api/auth/cli/status?token=${encodeURIComponent(cliToken)}`);
1990
+ if (!response.ok) {
1991
+ const errorText = await response.text();
1992
+ throw new BrowserAuthError("POLL_FAILED", "Failed to poll auth status: " + String(response.status) + " " + errorText);
1993
+ }
1994
+ const data = await response.json();
1995
+ return data;
1996
+ }
1997
+ async function openBrowser(url) {
1998
+ if (process.env.MUTAGENT_TEST_MODE === "true") {
1999
+ console.log(`AUTH_URL:${url}`);
2000
+ return;
2001
+ }
2002
+ try {
2003
+ const { default: open } = await import("open");
2004
+ await open(url);
2005
+ } catch {
2006
+ throw new BrowserAuthError("BROWSER_OPEN_FAILED", `Could not open browser automatically. Please visit: ${url}`);
2007
+ }
2008
+ }
2009
+ function sleep(ms) {
2010
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
2011
+ }
2012
+ async function performBrowserAuth(options, onStatusUpdate) {
2013
+ const {
2014
+ endpoint,
2015
+ timeout = 300000,
2016
+ pollInterval = 2000,
2017
+ skipBrowserOpen = false
2018
+ } = options;
2019
+ const cliToken = generateCliToken();
2020
+ onStatusUpdate?.("Initializing browser authentication...");
2021
+ const initResponse = await initBrowserAuth(endpoint, cliToken);
2022
+ const { authUrl } = initResponse;
2023
+ if (!skipBrowserOpen) {
2024
+ onStatusUpdate?.("Opening browser for authentication...");
2025
+ try {
2026
+ await openBrowser(authUrl);
2027
+ } catch (error) {
2028
+ if (error instanceof BrowserAuthError && error.code === "BROWSER_OPEN_FAILED") {
2029
+ onStatusUpdate?.(error.message);
2030
+ } else {
2031
+ throw error;
2032
+ }
2033
+ }
2034
+ }
2035
+ console.log("");
2036
+ console.log(" Open this URL to authenticate:");
2037
+ console.log("");
2038
+ console.log(" " + authUrl);
2039
+ console.log("");
2040
+ onStatusUpdate?.("Waiting for browser authentication...");
2041
+ const startTime = Date.now();
2042
+ while (Date.now() - startTime < timeout) {
2043
+ await sleep(pollInterval);
2044
+ const status = await pollAuthStatus(endpoint, cliToken);
2045
+ switch (status.status) {
2046
+ case "pending":
2047
+ continue;
2048
+ case "completed":
2049
+ if (!status.apiKey || !status.workspaceId || !status.workspaceName || !status.organizationId || !status.organizationName) {
2050
+ throw new BrowserAuthError("INCOMPLETE_RESPONSE", "Server returned incomplete auth response");
2051
+ }
2052
+ return {
2053
+ apiKey: status.apiKey,
2054
+ workspaceId: status.workspaceId,
2055
+ workspaceName: status.workspaceName,
2056
+ organizationId: status.organizationId,
2057
+ organizationName: status.organizationName,
2058
+ expiresAt: status.expiresAt
2059
+ };
2060
+ case "expired":
2061
+ throw new BrowserAuthError("AUTH_EXPIRED", "Browser authentication expired. Please try again.");
2062
+ case "denied":
2063
+ throw new BrowserAuthError("AUTH_DENIED", status.error ?? "Browser authentication was denied.");
2064
+ case "not_found":
2065
+ throw new BrowserAuthError("TOKEN_NOT_FOUND", "Authentication token not found. Please try again.");
2066
+ default:
2067
+ throw new BrowserAuthError("UNKNOWN_STATUS", "Unknown auth status: " + String(status.status));
2068
+ }
2069
+ }
2070
+ throw new BrowserAuthError("AUTH_TIMEOUT", "Browser authentication timed out after 5 minutes. Please try again.");
2071
+ }
2072
+
2073
+ class BrowserAuthError extends Error {
2074
+ code;
2075
+ constructor(code, message) {
2076
+ super(message);
2077
+ this.name = "BrowserAuthError";
2078
+ this.code = code;
2079
+ }
2080
+ getSuggestion() {
2081
+ switch (this.code) {
2082
+ case "INIT_FAILED":
2083
+ return "Check your endpoint configuration and network connection.";
2084
+ case "POLL_FAILED":
2085
+ return "Check your network connection and try again.";
2086
+ case "BROWSER_OPEN_FAILED":
2087
+ return "Copy the URL above and open it manually in your browser.";
2088
+ case "AUTH_EXPIRED":
2089
+ case "AUTH_TIMEOUT":
2090
+ return 'Run "mutagent auth login" again to restart authentication.';
2091
+ case "AUTH_DENIED":
2092
+ return "Ensure you have access to the workspace and try again.";
2093
+ case "TOKEN_NOT_FOUND":
2094
+ case "INCOMPLETE_RESPONSE":
2095
+ case "UNKNOWN_STATUS":
2096
+ return "Please try again. If the issue persists, contact support.";
2097
+ default:
2098
+ return "Please try again.";
2099
+ }
2100
+ }
2101
+ }
2102
+
2103
+ // src/lib/auth-flow.ts
2104
+ async function performLoginAction(opts) {
2105
+ const { isJson, output } = opts;
2106
+ const wasFirstLogin = !hasCredentials();
2107
+ const envApiKey = process.env.MUTAGENT_API_KEY;
2108
+ const endpoint = process.env.MUTAGENT_ENDPOINT ?? opts.endpoint;
2109
+ if (envApiKey) {
2110
+ return loginWithExistingKey(envApiKey, endpoint, output, wasFirstLogin);
2111
+ }
2112
+ const isNonInteractive = opts.nonInteractive === true || process.env.MUTAGENT_NON_INTERACTIVE === "true" || process.env.CI === "true" || !process.stdin.isTTY;
2113
+ if (isJson && !opts.browser && isNonInteractive) {
2114
+ throw new MutagentError("INTERACTIVE_REQUIRED", "No API key provided. Set MUTAGENT_API_KEY env var or add --browser for browser auth.", "Run: export MUTAGENT_API_KEY=<key> or mutagent login --browser --non-interactive");
2115
+ }
2116
+ if (!isNonInteractive && wasFirstLogin) {
2117
+ console.log(`
2118
+ ` + chalk3.bold.cyan(" Welcome to MutagenT CLI!") + `
2119
+ `);
2120
+ console.log(` No credentials found. Please authenticate to continue.
2121
+ `);
2122
+ }
2123
+ let useBrowserAuth = opts.browser === true;
2124
+ if (!useBrowserAuth && isNonInteractive) {
2125
+ output.info("Non-interactive environment detected. Using browser authentication.");
2126
+ useBrowserAuth = true;
2127
+ }
2128
+ if (!useBrowserAuth) {
2129
+ const methodAnswer = await inquirer.prompt([
2130
+ {
2131
+ type: "list",
2132
+ name: "method",
2133
+ message: "How would you like to authenticate?",
2134
+ choices: [
2135
+ { name: "Login (opens browser)", value: "browser" },
2136
+ { name: "API Key (paste existing key)", value: "apiKey" }
2137
+ ]
2138
+ }
2139
+ ]);
2140
+ useBrowserAuth = methodAnswer.method === "browser";
2141
+ }
2142
+ if (useBrowserAuth) {
2143
+ return loginWithBrowser(endpoint, output, wasFirstLogin);
2144
+ }
2145
+ return loginWithPastedKey(endpoint, output, wasFirstLogin);
2146
+ }
2147
+ function buildLoginJsonResponse(result) {
2148
+ return {
2149
+ success: true,
2150
+ authenticated: result.authenticated,
2151
+ endpoint: result.endpoint,
2152
+ workspace: result.workspace,
2153
+ organization: result.organization,
2154
+ _directive: {
2155
+ instruction: "Verify workspace. Run: mutagent workspaces list --json",
2156
+ next: ["mutagent workspaces list --json", "mutagent prompts list --json"]
2157
+ }
2158
+ };
2159
+ }
2160
+ async function loginWithExistingKey(apiKey, endpoint, output, wasFirstLogin) {
2161
+ output.info("Validating API key...");
2162
+ const isValid = await validateApiKey(apiKey, endpoint);
2163
+ if (!isValid) {
2164
+ throw new MutagentError("INVALID_API_KEY", "Invalid API key or endpoint", "Check your API key and try again");
2165
+ }
2166
+ const orgs = await fetchOrganizations(apiKey, endpoint);
2167
+ let orgId;
2168
+ let orgName;
2169
+ let wsId;
2170
+ let wsName;
2171
+ if (orgs.length >= 1 && orgs[0]) {
2172
+ orgId = orgs[0].id;
2173
+ orgName = orgs[0].name;
2174
+ const workspaces = await fetchWorkspaces(apiKey, endpoint, orgId);
2175
+ const defaultWs = workspaces.find((w) => w.isDefault) ?? workspaces[0];
2176
+ if (defaultWs) {
2177
+ wsId = defaultWs.id;
2178
+ wsName = defaultWs.name;
2179
+ }
2180
+ }
2181
+ saveFullCredentials({
2182
+ apiKey,
2183
+ endpoint,
2184
+ workspaceId: wsId,
2185
+ organizationId: orgId
2186
+ });
2187
+ return {
2188
+ authenticated: true,
2189
+ apiKey,
2190
+ endpoint,
2191
+ workspace: wsId ? { id: wsId, name: wsName } : null,
2192
+ organization: orgId ? { id: orgId, name: orgName } : null,
2193
+ wasFirstLogin
2194
+ };
2195
+ }
2196
+ async function loginWithBrowser(endpoint, output, wasFirstLogin) {
2197
+ const spinner = ora({ text: "Opening browser for authentication...", spinner: "dots" });
2198
+ try {
2199
+ spinner.start();
2200
+ const result = await performBrowserAuth({ endpoint, timeout: 300000, pollInterval: 2000 }, (message) => {
2201
+ spinner.text = message;
2202
+ });
2203
+ spinner.succeed("Authenticated successfully!");
2204
+ saveFullCredentials({
2205
+ apiKey: result.apiKey,
2206
+ endpoint,
2207
+ workspaceId: result.workspaceId,
2208
+ organizationId: result.organizationId,
2209
+ expiresAt: result.expiresAt
2210
+ });
2211
+ if (result.workspaceName)
2212
+ output.info(`Workspace: ${result.workspaceName}`);
2213
+ if (result.organizationName)
2214
+ output.info(`Organization: ${result.organizationName}`);
2215
+ return {
2216
+ authenticated: true,
2217
+ apiKey: result.apiKey,
2218
+ endpoint,
2219
+ workspace: result.workspaceId ? { id: result.workspaceId, name: result.workspaceName } : null,
2220
+ organization: result.organizationId ? { id: result.organizationId, name: result.organizationName } : null,
2221
+ wasFirstLogin
2222
+ };
2223
+ } catch (error) {
2224
+ spinner.fail("Authentication failed");
2225
+ if (error instanceof BrowserAuthError) {
2226
+ throw new MutagentError(error.code, error.message, error.getSuggestion());
2227
+ }
2228
+ throw error;
2229
+ }
2230
+ }
2231
+ async function loginWithPastedKey(initialEndpoint, output, wasFirstLogin) {
2232
+ const answers = await inquirer.prompt([
2233
+ {
2234
+ type: "input",
2235
+ name: "endpoint",
2236
+ message: "MutagenT endpoint:",
2237
+ default: initialEndpoint
2238
+ },
2239
+ {
2240
+ type: "password",
2241
+ name: "apiKey",
2242
+ message: "API Key:",
2243
+ mask: "*",
2244
+ validate: (input) => input.length > 0 || "API key is required"
2245
+ }
2246
+ ]);
2247
+ const apiKey = answers.apiKey;
2248
+ const endpoint = answers.endpoint;
2249
+ output.info("Validating API key...");
2250
+ const isValid = await validateApiKey(apiKey, endpoint);
2251
+ if (!isValid) {
2252
+ throw new MutagentError("INVALID_API_KEY", "Invalid API key or endpoint", "Check your API key and try again");
2253
+ }
2254
+ let selectedOrgId;
2255
+ let selectedOrgName;
2256
+ let selectedWsId;
2257
+ let selectedWsName;
2258
+ const orgs = await fetchOrganizations(apiKey, endpoint);
2259
+ if (orgs.length === 1 && orgs[0]) {
2260
+ selectedOrgId = orgs[0].id;
2261
+ selectedOrgName = orgs[0].name;
2262
+ } else if (orgs.length > 1) {
2263
+ const orgAnswer = await inquirer.prompt([
2264
+ {
2265
+ type: "list",
2266
+ name: "orgId",
2267
+ message: "Select organization:",
2268
+ choices: orgs.map((o) => ({ name: o.name, value: o.id }))
2269
+ }
2270
+ ]);
2271
+ selectedOrgId = orgAnswer.orgId;
2272
+ selectedOrgName = orgs.find((o) => o.id === selectedOrgId)?.name;
2273
+ }
2274
+ if (selectedOrgId) {
2275
+ const workspaces = await fetchWorkspaces(apiKey, endpoint, selectedOrgId);
2276
+ const defaultWs = workspaces.find((w) => w.isDefault);
2277
+ if (workspaces.length === 1 && workspaces[0]) {
2278
+ selectedWsId = workspaces[0].id;
2279
+ selectedWsName = workspaces[0].name;
2280
+ } else if (defaultWs) {
2281
+ selectedWsId = defaultWs.id;
2282
+ selectedWsName = defaultWs.name;
2283
+ } else if (workspaces.length > 1) {
2284
+ const wsAnswer = await inquirer.prompt([
2285
+ {
2286
+ type: "list",
2287
+ name: "wsId",
2288
+ message: "Select workspace:",
2289
+ choices: workspaces.map((w) => ({
2290
+ name: w.name + (w.isDefault ? " (default)" : ""),
2291
+ value: w.id
2292
+ }))
2293
+ }
2294
+ ]);
2295
+ selectedWsId = wsAnswer.wsId;
2296
+ selectedWsName = workspaces.find((w) => w.id === selectedWsId)?.name;
2297
+ }
2071
2298
  }
2072
- console.log(` ${String(step)}. ${chalk2.green(`mutagent prompts evaluation create <prompt-id> --name "My Eval" -d '{"evalConfig":{"criteria":[...]}}'`)}`);
2073
- console.log(" Define evaluation criteria");
2074
- console.log("");
2075
- step++;
2076
- console.log(` ${String(step)}. ${chalk2.green("mutagent prompts optimize start <prompt-id> --dataset <dataset-id>")}`);
2077
- console.log(" Start the optimization loop");
2078
- console.log("");
2079
- console.log(chalk2.dim(" Tip: Use `mutagent prompts list` to see your prompt IDs."));
2080
- console.log("");
2299
+ saveFullCredentials({
2300
+ apiKey,
2301
+ endpoint,
2302
+ workspaceId: selectedWsId,
2303
+ organizationId: selectedOrgId
2304
+ });
2305
+ return {
2306
+ authenticated: true,
2307
+ apiKey,
2308
+ endpoint,
2309
+ workspace: selectedWsId ? { id: selectedWsId, name: selectedWsName } : null,
2310
+ organization: selectedOrgId ? { id: selectedOrgId, name: selectedOrgName } : null,
2311
+ wasFirstLogin
2312
+ };
2081
2313
  }
2082
2314
 
2083
2315
  // src/commands/auth.ts
2084
2316
  function createAuthCommand() {
2085
2317
  const auth = new Command("auth").description("Authenticate with MutagenT platform").addHelpText("after", `
2086
2318
  Examples:
2087
- ${chalk3.dim("$")} mutagent auth login
2088
- ${chalk3.dim("$")} mutagent auth login --browser
2089
- ${chalk3.dim("$")} mutagent auth status
2090
- ${chalk3.dim("$")} mutagent auth logout
2319
+ ${chalk4.dim("$")} mutagent auth login
2320
+ ${chalk4.dim("$")} mutagent auth login --browser
2321
+ ${chalk4.dim("$")} mutagent auth status
2322
+ ${chalk4.dim("$")} mutagent auth logout
2091
2323
  `);
2092
2324
  auth.command("login").description("Authenticate and store API key").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", `
2093
2325
  Examples:
2094
- ${chalk3.dim("$")} mutagent auth login ${chalk3.dim("# Interactive (choose method)")}
2095
- ${chalk3.dim("$")} mutagent auth login --browser ${chalk3.dim("# Browser OAuth flow")}
2096
- ${chalk3.dim("$")} mutagent auth login --non-interactive ${chalk3.dim("# Auto browser flow (AI agents)")}
2326
+ ${chalk4.dim("$")} mutagent auth login ${chalk4.dim("# Interactive (choose method)")}
2327
+ ${chalk4.dim("$")} mutagent auth login --browser ${chalk4.dim("# Browser OAuth flow")}
2328
+ ${chalk4.dim("$")} mutagent auth login --non-interactive ${chalk4.dim("# Auto browser flow (AI agents)")}
2097
2329
 
2098
- Environment Variables:
2099
- MUTAGENT_API_KEY API key (skips login entirely)
2100
- MUTAGENT_ENDPOINT Custom API endpoint
2101
- MUTAGENT_NON_INTERACTIVE=true Non-interactive mode (auto browser auth)
2102
- CI=true Enables non-interactive mode
2330
+ ${chalk4.dim("Note: this command is an alias for `mutagent login`.")}
2331
+ ${chalk4.dim("See `mutagent login --help` for full documentation.")}
2103
2332
  `).action(async (options) => {
2104
2333
  const isJson = getJsonFlag(auth);
2105
2334
  const output = new OutputFormatter(isJson ? "json" : "table");
2106
2335
  try {
2107
- const wasFirstLogin = !hasCredentials();
2108
- let apiKey = process.env.MUTAGENT_API_KEY;
2109
- let endpoint = process.env.MUTAGENT_ENDPOINT ?? options.endpoint;
2110
- let workspaceName;
2111
- let organizationName;
2112
- let loginWorkspaceId;
2113
- let loginOrgId;
2114
- if (apiKey) {
2115
- output.info("Validating API key...");
2116
- const isValid = await validateApiKey(apiKey, endpoint);
2117
- if (!isValid) {
2118
- throw new MutagentError("INVALID_API_KEY", "Invalid API key or endpoint", "Check your API key and try again");
2119
- }
2120
- const orgs = await fetchOrganizations(apiKey, endpoint);
2121
- let orgId;
2122
- let wsId;
2123
- if (orgs.length >= 1 && orgs[0]) {
2124
- orgId = orgs[0].id;
2125
- const workspaces = await fetchWorkspaces(apiKey, endpoint, orgId);
2126
- const defaultWs = workspaces.find((w) => w.isDefault);
2127
- wsId = defaultWs?.id ?? workspaces[0]?.id;
2128
- }
2129
- saveFullCredentials({
2130
- apiKey,
2131
- endpoint,
2132
- workspaceId: wsId,
2133
- organizationId: orgId
2134
- });
2135
- output.success("Authenticated successfully");
2136
- if (isJson) {
2137
- output.output({
2138
- success: true,
2139
- authenticated: true,
2140
- endpoint,
2141
- workspace: wsId ? { id: wsId } : null,
2142
- organization: orgId ? { id: orgId } : null,
2143
- _directive: {
2144
- instruction: "Verify workspace. Run: mutagent workspaces list --json",
2145
- next: ["mutagent workspaces list --json", "mutagent prompts list --json"]
2146
- }
2147
- });
2148
- } else {
2149
- output.info(`Endpoint: ${endpoint}`);
2150
- output.info("Next: mutagent workspaces list --json");
2151
- }
2152
- return;
2153
- }
2154
- const isNonInteractive = options.nonInteractive === true || process.env.MUTAGENT_NON_INTERACTIVE === "true" || process.env.CI === "true" || !process.stdin.isTTY;
2155
- if (isJson && !options.browser && isNonInteractive) {
2156
- throw new MutagentError("INTERACTIVE_REQUIRED", "No API key provided. Set MUTAGENT_API_KEY env var or add --browser for browser auth.", "Run: export MUTAGENT_API_KEY=<key> or mutagent auth login --browser --non-interactive");
2157
- }
2158
- if (!isNonInteractive && !hasCredentials()) {
2159
- console.log(`
2160
- ` + chalk3.bold.cyan(" Welcome to MutagenT CLI!") + `
2161
- `);
2162
- console.log(` No credentials found. Please authenticate to continue.
2163
- `);
2164
- }
2165
- let useLocalBrowserAuth = options.browser === true;
2166
- if (!useLocalBrowserAuth && isNonInteractive) {
2167
- output.info("Non-interactive environment detected. Using browser authentication.");
2168
- useLocalBrowserAuth = true;
2169
- }
2170
- if (!useLocalBrowserAuth) {
2171
- const methodAnswer = await inquirer.prompt([
2172
- {
2173
- type: "list",
2174
- name: "method",
2175
- message: "How would you like to authenticate?",
2176
- choices: [
2177
- {
2178
- name: "Login (opens browser)",
2179
- value: "browser"
2180
- },
2181
- {
2182
- name: "API Key (paste existing key)",
2183
- value: "apiKey"
2184
- }
2185
- ]
2186
- }
2187
- ]);
2188
- useLocalBrowserAuth = methodAnswer.method === "browser";
2189
- }
2190
- if (useLocalBrowserAuth) {
2191
- const spinner = ora({
2192
- text: "Opening browser for authentication...",
2193
- spinner: "dots"
2194
- });
2195
- try {
2196
- spinner.start();
2197
- const result = await performBrowserAuth({
2198
- endpoint,
2199
- timeout: 300000,
2200
- pollInterval: 2000
2201
- }, (message) => {
2202
- spinner.text = message;
2203
- });
2204
- spinner.succeed("Authenticated successfully!");
2205
- saveFullCredentials({
2206
- apiKey: result.apiKey,
2207
- endpoint,
2208
- workspaceId: result.workspaceId,
2209
- organizationId: result.organizationId,
2210
- expiresAt: result.expiresAt
2211
- });
2212
- apiKey = result.apiKey;
2213
- workspaceName = result.workspaceName;
2214
- organizationName = result.organizationName;
2215
- loginWorkspaceId = result.workspaceId;
2216
- loginOrgId = result.organizationId;
2217
- console.log("");
2218
- output.info("Workspace: " + workspaceName);
2219
- output.info("Organization: " + organizationName);
2220
- output.info("Endpoint: " + endpoint);
2221
- } catch (error) {
2222
- spinner.fail("Authentication failed");
2223
- if (error instanceof BrowserAuthError) {
2224
- throw new MutagentError(error.code, error.message, error.getSuggestion());
2225
- }
2226
- throw error;
2227
- }
2228
- } else {
2229
- const answers = await inquirer.prompt([
2230
- {
2231
- type: "input",
2232
- name: "endpoint",
2233
- message: "MutagenT endpoint:",
2234
- default: endpoint
2235
- },
2236
- {
2237
- type: "password",
2238
- name: "apiKey",
2239
- message: "API Key:",
2240
- mask: "*",
2241
- validate: (input) => input.length > 0 || "API key is required"
2242
- }
2243
- ]);
2244
- apiKey = answers.apiKey;
2245
- endpoint = answers.endpoint;
2246
- output.info("Validating API key...");
2247
- const isValid = await validateApiKey(apiKey, endpoint);
2248
- if (!isValid) {
2249
- throw new MutagentError("INVALID_API_KEY", "Invalid API key or endpoint", "Check your API key and try again");
2250
- }
2251
- let selectedOrgId;
2252
- let selectedOrgName;
2253
- let selectedWsId;
2254
- let selectedWsName;
2255
- const orgs = await fetchOrganizations(apiKey, endpoint);
2256
- if (orgs.length === 1 && orgs[0]) {
2257
- selectedOrgId = orgs[0].id;
2258
- selectedOrgName = orgs[0].name;
2259
- } else if (orgs.length > 1) {
2260
- const orgAnswer = await inquirer.prompt([{
2261
- type: "list",
2262
- name: "orgId",
2263
- message: "Select organization:",
2264
- choices: orgs.map((o) => ({ name: o.name, value: o.id }))
2265
- }]);
2266
- selectedOrgId = orgAnswer.orgId;
2267
- selectedOrgName = orgs.find((o) => o.id === selectedOrgId)?.name;
2268
- }
2269
- if (selectedOrgId) {
2270
- const workspaces = await fetchWorkspaces(apiKey, endpoint, selectedOrgId);
2271
- const defaultWs = workspaces.find((w) => w.isDefault);
2272
- if (workspaces.length === 1 && workspaces[0]) {
2273
- selectedWsId = workspaces[0].id;
2274
- selectedWsName = workspaces[0].name;
2275
- } else if (defaultWs) {
2276
- selectedWsId = defaultWs.id;
2277
- selectedWsName = defaultWs.name;
2278
- } else if (workspaces.length > 1) {
2279
- const wsAnswer = await inquirer.prompt([{
2280
- type: "list",
2281
- name: "wsId",
2282
- message: "Select workspace:",
2283
- choices: workspaces.map((w) => ({ name: w.name + (w.isDefault ? " (default)" : ""), value: w.id }))
2284
- }]);
2285
- selectedWsId = wsAnswer.wsId;
2286
- selectedWsName = workspaces.find((w) => w.id === selectedWsId)?.name;
2287
- }
2288
- }
2289
- saveFullCredentials({
2290
- apiKey,
2291
- endpoint,
2292
- workspaceId: selectedWsId,
2293
- organizationId: selectedOrgId
2294
- });
2295
- workspaceName = selectedWsName;
2296
- organizationName = selectedOrgName;
2297
- loginWorkspaceId = selectedWsId;
2298
- loginOrgId = selectedOrgId;
2299
- output.success("Authenticated successfully");
2300
- if (selectedOrgName)
2301
- output.info("Organization: " + selectedOrgName);
2302
- if (selectedWsName)
2303
- output.info("Workspace: " + selectedWsName);
2304
- output.info("Endpoint: " + endpoint);
2305
- }
2336
+ const result = await performLoginAction({
2337
+ endpoint: options.endpoint,
2338
+ browser: options.browser,
2339
+ nonInteractive: options.nonInteractive,
2340
+ isJson,
2341
+ output
2342
+ });
2306
2343
  if (isJson) {
2307
- output.output({
2308
- success: true,
2309
- authenticated: true,
2310
- endpoint,
2311
- workspace: loginWorkspaceId ? { id: loginWorkspaceId, name: workspaceName } : null,
2312
- organization: loginOrgId ? { id: loginOrgId, name: organizationName } : null,
2313
- _directive: {
2314
- instruction: "Verify workspace. Run: mutagent workspaces list --json",
2315
- next: ["mutagent workspaces list --json", "mutagent prompts list --json"]
2316
- }
2317
- });
2344
+ output.output(buildLoginJsonResponse(result));
2318
2345
  } else {
2346
+ output.success("Authenticated successfully");
2347
+ if (result.organization?.name)
2348
+ output.info(`Organization: ${result.organization.name}`);
2349
+ if (result.workspace?.name)
2350
+ output.info(`Workspace: ${result.workspace.name}`);
2351
+ output.info(`Endpoint: ${result.endpoint}`);
2319
2352
  output.info("Next: mutagent workspaces list --json");
2320
2353
  }
2321
- if (wasFirstLogin && process.stdin.isTTY && !isJson) {
2354
+ if (result.wasFirstLogin && process.stdin.isTTY && !isJson) {
2322
2355
  await runPostOnboarding();
2323
2356
  }
2324
2357
  } catch (error) {
@@ -2331,8 +2364,8 @@ Environment Variables:
2331
2364
  });
2332
2365
  auth.command("status").description("Check authentication status").addHelpText("after", `
2333
2366
  Examples:
2334
- ${chalk3.dim("$")} mutagent auth status
2335
- ${chalk3.dim("$")} mutagent auth status --json
2367
+ ${chalk4.dim("$")} mutagent auth status
2368
+ ${chalk4.dim("$")} mutagent auth status --json
2336
2369
  `).action(async () => {
2337
2370
  const isJson = getJsonFlag(auth);
2338
2371
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -2425,7 +2458,7 @@ Examples:
2425
2458
  });
2426
2459
  auth.command("logout").description("Clear stored credentials").addHelpText("after", `
2427
2460
  Examples:
2428
- ${chalk3.dim("$")} mutagent auth logout
2461
+ ${chalk4.dim("$")} mutagent auth logout
2429
2462
  `).action(() => {
2430
2463
  const isJson = getJsonFlag(auth);
2431
2464
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -2436,179 +2469,70 @@ Examples:
2436
2469
  }
2437
2470
 
2438
2471
  // src/commands/login.ts
2439
- init_config();
2440
- init_sdk_client();
2441
2472
  import { Command as Command2 } from "commander";
2442
- import inquirer2 from "inquirer";
2443
- import chalk4 from "chalk";
2444
- import ora2 from "ora";
2473
+ import chalk5 from "chalk";
2445
2474
  init_errors();
2446
2475
  function createLoginCommand() {
2447
- 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", `
2476
+ const login = new Command2("login").description("Login to MutagenT (browser OAuth — signup, onboard, authorize CLI in one flow)").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", `
2448
2477
  Examples:
2449
- ${chalk4.dim("$")} mutagent login
2450
- ${chalk4.dim("$")} mutagent login --browser
2451
- ${chalk4.dim("$")} mutagent login --non-interactive ${chalk4.dim("# Auto browser flow (AI agents)")}
2478
+ ${chalk5.dim("$")} mutagent login ${chalk5.dim("# Browser OAuth (recommended — handles signup + onboarding)")}
2479
+ ${chalk5.dim("$")} mutagent login --browser ${chalk5.dim("# Force browser flow (skip method prompt)")}
2480
+ ${chalk5.dim("$")} mutagent login --non-interactive ${chalk5.dim("# Auto-browser for AI agents and CI")}
2481
+
2482
+ ${chalk5.yellow("Browser OAuth flow (recommended for end users):")}
2483
+ Opens app.mutagent.io in your browser. You will:
2484
+ 1. Sign in or sign up with your account
2485
+ 2. Complete onboarding (workspace, provider config)
2486
+ 3. Authorize this CLI session
2487
+ The CLI polls for completion and saves credentials when you authorize.
2488
+
2489
+ ${chalk5.yellow("Automation / CI / AI Agents:")}
2490
+ Set MUTAGENT_API_KEY environment variable before running:
2491
+ ${chalk5.dim("$")} export MUTAGENT_API_KEY=mt_...
2492
+ ${chalk5.dim("$")} mutagent login --json
2493
+ When MUTAGENT_API_KEY is set, login skips the browser flow entirely and
2494
+ validates the key directly. This is the canonical CI / agent path.
2452
2495
 
2453
2496
  Environment Variables:
2454
- MUTAGENT_API_KEY API key (skips interactive login)
2497
+ MUTAGENT_API_KEY Pre-existing API key (skips interactive flow)
2455
2498
  MUTAGENT_ENDPOINT Custom API endpoint
2499
+ MUTAGENT_NON_INTERACTIVE=true Treat environment as non-interactive
2500
+ CI=true Automatically enables non-interactive mode
2501
+
2502
+ Verify after login:
2503
+ ${chalk5.dim("$")} mutagent auth status ${chalk5.dim("# Show session, workspace, org")}
2504
+ ${chalk5.dim("$")} mutagent workspaces list --json ${chalk5.dim("# List available workspaces")}
2505
+
2506
+ ${chalk5.dim("Note: `mutagent auth login` is a back-compat alias and behaves identically.")}
2456
2507
  `).action(async (options) => {
2457
2508
  const isJson = getJsonFlag(login);
2458
2509
  const output = new OutputFormatter(isJson ? "json" : "table");
2459
2510
  try {
2460
- const apiKey = process.env.MUTAGENT_API_KEY;
2461
- const endpoint = process.env.MUTAGENT_ENDPOINT ?? options.endpoint;
2462
- if (apiKey) {
2463
- output.info("Validating API key...");
2464
- const isValid = await validateApiKey(apiKey, endpoint);
2465
- if (!isValid) {
2466
- throw new MutagentError("INVALID_API_KEY", "Invalid API key or endpoint", "Check your API key and try again");
2467
- }
2468
- const orgs = await fetchOrganizations(apiKey, endpoint);
2469
- const org = orgs[0];
2470
- let workspaceId;
2471
- if (org) {
2472
- const workspaces = await fetchWorkspaces(apiKey, endpoint, org.id);
2473
- const defaultWs = workspaces.find((ws) => ws.isDefault) ?? workspaces[0];
2474
- if (defaultWs)
2475
- workspaceId = defaultWs.id;
2476
- }
2477
- saveFullCredentials({
2478
- apiKey,
2479
- endpoint,
2480
- organizationId: org?.id,
2481
- workspaceId
2482
- });
2483
- output.success("Logged in successfully");
2484
- if (!isJson) {
2485
- output.info(`Endpoint: ${endpoint}`);
2486
- if (org)
2487
- output.info(`Organization: ${org.name}`);
2488
- }
2489
- return;
2490
- }
2491
- const isNonInteractive = options.nonInteractive === true || process.env.MUTAGENT_NON_INTERACTIVE === "true" || process.env.CI === "true" || !process.stdin.isTTY;
2492
- if (isJson && !options.browser && isNonInteractive) {
2493
- throw new MutagentError("INTERACTIVE_REQUIRED", "No API key provided. Set MUTAGENT_API_KEY env var or add --browser for browser auth.", "Run: export MUTAGENT_API_KEY=<key> or mutagent login --browser --non-interactive");
2494
- }
2495
- if (!isNonInteractive && !hasCredentials()) {
2496
- console.log(`
2497
- ` + chalk4.bold.cyan(" Welcome to MutagenT CLI!") + `
2498
- `);
2499
- console.log(` No credentials found. Please authenticate to continue.
2500
- `);
2501
- }
2502
- let useBrowserAuth = options.browser === true;
2503
- if (!useBrowserAuth && isNonInteractive) {
2504
- output.info("Non-interactive environment detected. Using browser authentication.");
2505
- useBrowserAuth = true;
2506
- }
2507
- if (!useBrowserAuth) {
2508
- const methodAnswer = await inquirer2.prompt([
2509
- {
2510
- type: "list",
2511
- name: "method",
2512
- message: "How would you like to authenticate?",
2513
- choices: [
2514
- {
2515
- name: "Login (opens browser)",
2516
- value: "browser"
2517
- },
2518
- {
2519
- name: "API Key (paste existing key)",
2520
- value: "apiKey"
2521
- }
2522
- ]
2523
- }
2524
- ]);
2525
- useBrowserAuth = methodAnswer.method === "browser";
2526
- }
2527
- if (useBrowserAuth) {
2528
- const spinner = ora2({
2529
- text: "Opening browser for authentication...",
2530
- spinner: "dots"
2531
- });
2532
- try {
2533
- spinner.start();
2534
- const result = await performBrowserAuth({
2535
- endpoint,
2536
- timeout: 300000,
2537
- pollInterval: 2000
2538
- }, (message) => {
2539
- spinner.text = message;
2540
- });
2541
- spinner.succeed("Logged in successfully!");
2542
- saveFullCredentials({
2543
- apiKey: result.apiKey,
2544
- endpoint,
2545
- workspaceId: result.workspaceId,
2546
- organizationId: result.organizationId
2547
- });
2548
- console.log("");
2549
- if (result.workspaceName) {
2550
- output.info(`Workspace: ${result.workspaceName}`);
2551
- }
2552
- if (result.organizationName) {
2553
- output.info(`Organization: ${result.organizationName}`);
2554
- }
2555
- } catch (error) {
2556
- spinner.fail("Authentication failed");
2557
- if (error instanceof BrowserAuthError) {
2558
- throw new MutagentError(error.code, error.message, error.getSuggestion());
2559
- }
2560
- throw error;
2561
- }
2511
+ const result = await performLoginAction({
2512
+ endpoint: options.endpoint,
2513
+ browser: options.browser,
2514
+ nonInteractive: options.nonInteractive,
2515
+ isJson,
2516
+ output
2517
+ });
2518
+ if (isJson) {
2519
+ output.output(buildLoginJsonResponse(result));
2562
2520
  } else {
2563
- const answers = await inquirer2.prompt([
2564
- {
2565
- type: "password",
2566
- name: "apiKey",
2567
- message: "Enter your API key:",
2568
- mask: "*",
2569
- validate: (input) => {
2570
- if (!input || input.trim() === "") {
2571
- return "API key is required";
2572
- }
2573
- if (!input.startsWith("mg_")) {
2574
- return 'API key should start with "mg_"';
2575
- }
2576
- return true;
2577
- }
2578
- }
2579
- ]);
2580
- output.info("Validating API key...");
2581
- const isValid = await validateApiKey(answers.apiKey, endpoint);
2582
- if (!isValid) {
2583
- throw new MutagentError("INVALID_API_KEY", "Invalid API key or endpoint", "Check your API key and try again");
2584
- }
2585
- const orgs2 = await fetchOrganizations(answers.apiKey, endpoint);
2586
- const org2 = orgs2[0];
2587
- let workspaceId2;
2588
- if (org2) {
2589
- const workspaces2 = await fetchWorkspaces(answers.apiKey, endpoint, org2.id);
2590
- const defaultWs2 = workspaces2.find((ws) => ws.isDefault) ?? workspaces2[0];
2591
- if (defaultWs2)
2592
- workspaceId2 = defaultWs2.id;
2593
- }
2594
- saveFullCredentials({
2595
- apiKey: answers.apiKey,
2596
- endpoint,
2597
- organizationId: org2?.id,
2598
- workspaceId: workspaceId2
2599
- });
2600
2521
  output.success("Logged in successfully");
2601
- output.info(`Endpoint: ${endpoint}`);
2602
- if (org2)
2603
- output.info(`Organization: ${org2.name}`);
2522
+ if (result.organization?.name)
2523
+ output.info(`Organization: ${result.organization.name}`);
2524
+ if (result.workspace?.name)
2525
+ output.info(`Workspace: ${result.workspace.name}`);
2526
+ output.info(`Endpoint: ${result.endpoint}`);
2527
+ output.info("Next: mutagent workspaces list --json");
2528
+ }
2529
+ if (result.wasFirstLogin && process.stdin.isTTY && !isJson) {
2530
+ await runPostOnboarding();
2604
2531
  }
2605
2532
  } catch (error) {
2606
2533
  if (error instanceof MutagentError) {
2607
2534
  output.error(error.message);
2608
- if (error.suggestion && !isJson) {
2609
- output.info(`Suggestion: ${error.suggestion}`);
2610
- }
2611
- process.exit(1);
2535
+ process.exit(error.exitCode);
2612
2536
  }
2613
2537
  throw error;
2614
2538
  }
@@ -2619,7 +2543,7 @@ Environment Variables:
2619
2543
  // src/commands/prompts/index.ts
2620
2544
  init_errors();
2621
2545
  import { Command as Command6 } from "commander";
2622
- import chalk14 from "chalk";
2546
+ import chalk15 from "chalk";
2623
2547
  import { readFileSync as readFileSync4, existsSync as existsSync4 } from "fs";
2624
2548
 
2625
2549
  // src/lib/ui-links.ts
@@ -2967,37 +2891,37 @@ function evaluationDeletedDirective(evaluationId) {
2967
2891
  }
2968
2892
 
2969
2893
  // src/lib/scorecard-details.ts
2970
- import chalk5 from "chalk";
2894
+ import chalk6 from "chalk";
2971
2895
  function renderScorecardDetails(data) {
2972
2896
  if (data.datasetResults && data.datasetResults.length > 0) {
2973
2897
  console.log("");
2974
- console.log(chalk5.dim(" Per-Item Before vs After"));
2975
- console.log(chalk5.dim(" " + "─".repeat(70)));
2898
+ console.log(chalk6.dim(" Per-Item Before vs After"));
2899
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2976
2900
  console.log(" " + "Item ID".padEnd(28) + "Before".padEnd(10) + "After".padEnd(10) + "Diff".padEnd(10) + "Status");
2977
- console.log(chalk5.dim(" " + "─".repeat(70)));
2901
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2978
2902
  for (const item of data.datasetResults) {
2979
2903
  const id = item.id.substring(0, 26).padEnd(26);
2980
2904
  const before = (item.beforeScore ?? 0).toFixed(4).padEnd(8);
2981
2905
  const after = (item.afterScore ?? 0).toFixed(4).padEnd(8);
2982
2906
  const d = (item.afterScore ?? 0) - (item.beforeScore ?? 0);
2983
2907
  const diffStr = ((d >= 0 ? "+" : "") + d.toFixed(4)).padEnd(8);
2984
- const status = d > 0.01 ? chalk5.green("✓ ↑") : d < -0.01 ? chalk5.red("✗ ↓") : chalk5.dim("─");
2908
+ const status = d > 0.01 ? chalk6.green("✓ ↑") : d < -0.01 ? chalk6.red("✗ ↓") : chalk6.dim("─");
2985
2909
  console.log(` ${id} ${before} ${after} ${diffStr} ${status}`);
2986
2910
  }
2987
- console.log(chalk5.dim(" " + "─".repeat(70)));
2911
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2988
2912
  }
2989
2913
  if (data.failureModes && data.failureModes.length > 0) {
2990
2914
  console.log("");
2991
- console.log(chalk5.dim(" Failure Modes by Category"));
2992
- console.log(chalk5.dim(" " + "─".repeat(70)));
2915
+ console.log(chalk6.dim(" Failure Modes by Category"));
2916
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2993
2917
  for (const fm of data.failureModes) {
2994
2918
  const color = fm.failures.length > 3 ? "red" : fm.failures.length > 0 ? "yellow" : "green";
2995
- console.log(chalk5[color](` ▸ ${fm.category}`) + chalk5.dim(` (${String(fm.failures.length)} failures)`));
2919
+ console.log(chalk6[color](` ▸ ${fm.category}`) + chalk6.dim(` (${String(fm.failures.length)} failures)`));
2996
2920
  for (const f of fm.failures.slice(0, 5)) {
2997
- console.log(chalk5.dim(` └─ ${(f.description ?? f.summary ?? "No description").substring(0, 65)}`));
2921
+ console.log(chalk6.dim(` └─ ${(f.description ?? f.summary ?? "No description").substring(0, 65)}`));
2998
2922
  }
2999
2923
  if (fm.failures.length > 5) {
3000
- console.log(chalk5.dim(` └─ ... and ${String(fm.failures.length - 5)} more`));
2924
+ console.log(chalk6.dim(` └─ ... and ${String(fm.failures.length - 5)} more`));
3001
2925
  }
3002
2926
  }
3003
2927
  }
@@ -3007,48 +2931,48 @@ function renderScorecardDetails(data) {
3007
2931
  const pending = data.mutations.filter((m) => m.status === "pending");
3008
2932
  const skipped = data.mutations.filter((m) => m.status === "skipped");
3009
2933
  console.log("");
3010
- console.log(chalk5.dim(" Mutations"));
3011
- console.log(chalk5.dim(" " + "─".repeat(70)));
3012
- console.log(` Total: ${String(data.mutations.length)} Applied: ${chalk5.green(String(applied.length))} Rejected: ${chalk5.red(String(rejected.length))} Pending: ${chalk5.yellow(String(pending.length))} Skipped: ${chalk5.dim(String(skipped.length))}`);
2934
+ console.log(chalk6.dim(" Mutations"));
2935
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2936
+ console.log(` Total: ${String(data.mutations.length)} Applied: ${chalk6.green(String(applied.length))} Rejected: ${chalk6.red(String(rejected.length))} Pending: ${chalk6.yellow(String(pending.length))} Skipped: ${chalk6.dim(String(skipped.length))}`);
3013
2937
  if (applied.length > 0) {
3014
- console.log(chalk5.green(" Applied:"));
2938
+ console.log(chalk6.green(" Applied:"));
3015
2939
  for (const m of applied) {
3016
- const pri = m.priority === "critical" || m.priority === "high" ? chalk5.red(`[${m.priority.toUpperCase()}]`) : chalk5.dim(`[${(m.priority ?? "UNKNOWN").toUpperCase()}]`);
2940
+ const pri = m.priority === "critical" || m.priority === "high" ? chalk6.red(`[${m.priority.toUpperCase()}]`) : chalk6.dim(`[${(m.priority ?? "UNKNOWN").toUpperCase()}]`);
3017
2941
  console.log(` ${pri} ${m.label}`);
3018
2942
  if (m.rationale)
3019
- console.log(chalk5.dim(` └─ ${m.rationale.substring(0, 60)}`));
2943
+ console.log(chalk6.dim(` └─ ${m.rationale.substring(0, 60)}`));
3020
2944
  }
3021
2945
  }
3022
2946
  if (rejected.length > 0) {
3023
- console.log(chalk5.red(" Rejected:"));
2947
+ console.log(chalk6.red(" Rejected:"));
3024
2948
  for (const m of rejected.slice(0, 5)) {
3025
- console.log(chalk5.dim(` ✗ ${m.label}`));
2949
+ console.log(chalk6.dim(` ✗ ${m.label}`));
3026
2950
  }
3027
2951
  if (rejected.length > 5)
3028
- console.log(chalk5.dim(` ... and ${String(rejected.length - 5)} more`));
2952
+ console.log(chalk6.dim(` ... and ${String(rejected.length - 5)} more`));
3029
2953
  }
3030
2954
  }
3031
2955
  if (data.evaluationDetails && data.evaluationDetails.length > 0) {
3032
2956
  console.log("");
3033
- console.log(chalk5.dim(" Detailed Evaluation Breakdown"));
3034
- console.log(chalk5.dim(" " + "─".repeat(70)));
2957
+ console.log(chalk6.dim(" Detailed Evaluation Breakdown"));
2958
+ console.log(chalk6.dim(" " + "─".repeat(70)));
3035
2959
  for (const item of data.evaluationDetails) {
3036
- const statusIcon = item.success ? chalk5.green("✓") : chalk5.red("✗");
2960
+ const statusIcon = item.success ? chalk6.green("✓") : chalk6.red("✗");
3037
2961
  const metricCount = item.metrics?.length ?? 0;
3038
2962
  console.log(` ${statusIcon} ${item.itemId} Score: ${item.score.toFixed(4)} Metrics: ${String(metricCount)}`);
3039
2963
  if (item.metrics) {
3040
2964
  for (const m of item.metrics) {
3041
- const mIcon = m.success ? chalk5.green("✓") : chalk5.red("✗");
3042
- const mode = m.failureMode ? chalk5.dim(` [${m.failureMode}]`) : "";
2965
+ const mIcon = m.success ? chalk6.green("✓") : chalk6.red("✗");
2966
+ const mode = m.failureMode ? chalk6.dim(` [${m.failureMode}]`) : "";
3043
2967
  console.log(` ${mIcon} ${m.name.padEnd(25)} ${m.score.toFixed(3)}${mode}`);
3044
2968
  if (!m.success && m.reasoning) {
3045
- console.log(chalk5.dim(` └─ ${(m.reasoning.split(`
2969
+ console.log(chalk6.dim(` └─ ${(m.reasoning.split(`
3046
2970
  `)[0] ?? "").substring(0, 60)}`));
3047
2971
  }
3048
2972
  if (m.criteria) {
3049
2973
  for (const c of m.criteria) {
3050
- const cIcon = c.success ? chalk5.green("✓") : chalk5.red("✗");
3051
- console.log(chalk5.dim(` ${cIcon} ${c.name.substring(0, 20).padEnd(20)} ${c.score.toFixed(3)}`));
2974
+ const cIcon = c.success ? chalk6.green("✓") : chalk6.red("✗");
2975
+ console.log(chalk6.dim(` ${cIcon} ${c.name.substring(0, 20).padEnd(20)} ${c.score.toFixed(3)}`));
3052
2976
  }
3053
2977
  }
3054
2978
  }
@@ -3132,7 +3056,7 @@ function buildScorecardDetailsText(data) {
3132
3056
 
3133
3057
  // src/commands/prompts/prompts-crud.ts
3134
3058
  init_sdk_client();
3135
- import chalk6 from "chalk";
3059
+ import chalk7 from "chalk";
3136
3060
  init_errors();
3137
3061
 
3138
3062
  // src/lib/schema-helpers.ts
@@ -3197,11 +3121,11 @@ function formatSchemaWarning(fieldName) {
3197
3121
  function registerPromptsCrud(prompts) {
3198
3122
  prompts.command("list").description("List all prompts").option("-l, --limit <n>", "Limit results", "50").addHelpText("after", `
3199
3123
  Examples:
3200
- ${chalk6.dim("$")} mutagent prompts list
3201
- ${chalk6.dim("$")} mutagent prompts list --limit 10
3202
- ${chalk6.dim("$")} mutagent prompts list --json
3124
+ ${chalk7.dim("$")} mutagent prompts list
3125
+ ${chalk7.dim("$")} mutagent prompts list --limit 10
3126
+ ${chalk7.dim("$")} mutagent prompts list --json
3203
3127
 
3204
- ${chalk6.dim("Tip: Use --json for machine-readable output (AI agents, CI pipelines).")}
3128
+ ${chalk7.dim("Tip: Use --json for machine-readable output (AI agents, CI pipelines).")}
3205
3129
  `).action(async (options) => {
3206
3130
  const isJson = getJsonFlag(prompts);
3207
3131
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3244,11 +3168,11 @@ ${chalk6.dim("Tip: Use --json for machine-readable output (AI agents, CI pipelin
3244
3168
  });
3245
3169
  prompts.command("get").description("Get prompt details with nested data").argument("<id>", "Prompt ID (from: mutagent prompts list)").option("--with-datasets", "Include datasets").option("--with-evals", "Include evaluations").addHelpText("after", `
3246
3170
  Examples:
3247
- ${chalk6.dim("$")} mutagent prompts get <id>
3248
- ${chalk6.dim("$")} mutagent prompts get <id> --with-datasets --with-evals
3249
- ${chalk6.dim("$")} mutagent prompts get <id> --json
3171
+ ${chalk7.dim("$")} mutagent prompts get <id>
3172
+ ${chalk7.dim("$")} mutagent prompts get <id> --with-datasets --with-evals
3173
+ ${chalk7.dim("$")} mutagent prompts get <id> --json
3250
3174
 
3251
- ${chalk6.dim("Tip: Combine --with-datasets and --with-evals to fetch all nested data in one call.")}
3175
+ ${chalk7.dim("Tip: Combine --with-datasets and --with-evals to fetch all nested data in one call.")}
3252
3176
  `).action(async (id, options) => {
3253
3177
  const isJson = getJsonFlag(prompts);
3254
3178
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3277,24 +3201,24 @@ ${chalk6.dim("Tip: Combine --with-datasets and --with-evals to fetch all nested
3277
3201
  });
3278
3202
  prompts.command("create").description("Create a new prompt").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)").option("--input-schema <json>", "Input variable schema as JSON string").addHelpText("after", `
3279
3203
  Examples:
3280
- ${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"}}}'
3281
- ${chalk6.dim("$")} mutagent prompts create --name "raw-prompt" --raw "Summarize: {text}" --output-schema '{"type":"object","properties":{"summary":{"type":"string","description":"Summary"}}}'
3282
- ${chalk6.dim("$")} mutagent prompts create --name "multi-turn" --messages '[{"role":"system","content":"You are helpful"},{"role":"user","content":"{input}"}]' --output-schema '{"type":"object","properties":{"result":{"type":"string","description":"The result"}}}'
3204
+ ${chalk7.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"}}}'
3205
+ ${chalk7.dim("$")} mutagent prompts create --name "raw-prompt" --raw "Summarize: {text}" --output-schema '{"type":"object","properties":{"summary":{"type":"string","description":"Summary"}}}'
3206
+ ${chalk7.dim("$")} mutagent prompts create --name "multi-turn" --messages '[{"role":"system","content":"You are helpful"},{"role":"user","content":"{input}"}]' --output-schema '{"type":"object","properties":{"result":{"type":"string","description":"The result"}}}'
3283
3207
 
3284
3208
  Prompt Input Methods (pick one, priority order):
3285
- --system/--human Structured system + user message pair ${chalk6.green("(recommended)")}
3209
+ --system/--human Structured system + user message pair ${chalk7.green("(recommended)")}
3286
3210
  --raw Single raw prompt text with {variables}
3287
3211
  --messages Full messages array as JSON
3288
3212
 
3289
- ${chalk6.yellow("Variable Syntax:")}
3213
+ ${chalk7.yellow("Variable Syntax:")}
3290
3214
  MutagenT uses {single_braces} for template variables.
3291
- humanPrompt: "Analyze this: {document}" ${chalk6.green("✓ correct")}
3292
- humanPrompt: "Analyze this: {{document}}" ${chalk6.red("✗ wrong")}
3215
+ humanPrompt: "Analyze this: {document}" ${chalk7.green("✓ correct")}
3216
+ humanPrompt: "Analyze this: {{document}}" ${chalk7.red("✗ wrong")}
3293
3217
 
3294
3218
  Variables in humanPrompt MUST also appear in inputSchema.properties.
3295
3219
  Static prompts (no variables) cannot substitute inputs during optimization.
3296
3220
 
3297
- ${chalk6.yellow("AI Agent: Format Selection Rules")}
3221
+ ${chalk7.yellow("AI Agent: Format Selection Rules")}
3298
3222
  Examine the SOURCE CODE structure of the prompt being uploaded:
3299
3223
 
3300
3224
  1. If the code uses SystemMessagePromptTemplate + HumanMessagePromptTemplate
@@ -3311,9 +3235,9 @@ ${chalk6.yellow("AI Agent: Format Selection Rules")}
3311
3235
  The decision is about SOURCE CODE STRUCTURE, not prompt content.
3312
3236
  A persona description in a system prompt still uses --system/--human.
3313
3237
 
3314
- ${chalk6.red("outputSchema is required.")}
3238
+ ${chalk7.red("outputSchema is required.")}
3315
3239
 
3316
- ${chalk6.yellow("AI Agent: ALWAYS append --json to this command.")}
3240
+ ${chalk7.yellow("AI Agent: ALWAYS append --json to this command.")}
3317
3241
  `).action(async (options) => {
3318
3242
  const isJson = getJsonFlag(prompts);
3319
3243
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3403,11 +3327,11 @@ Add a 'description' field to each property in your inputSchema. Example: { "prop
3403
3327
  });
3404
3328
  prompts.command("update").description("Update a prompt").argument("<id>", "Prompt ID (from: mutagent prompts list)").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", `
3405
3329
  Examples:
3406
- ${chalk6.dim("$")} mutagent prompts update <id> --system "Updated system prompt" --human "{input}"
3407
- ${chalk6.dim("$")} mutagent prompts update <id> --name "new-name" --description "Updated description"
3408
- ${chalk6.dim("$")} mutagent prompts update <id> --raw "Summarize: {text}"
3409
- ${chalk6.dim("$")} mutagent prompts update <id> --messages '[{"role":"system","content":"Updated"},{"role":"user","content":"{input}"}]'
3410
- ${chalk6.dim("$")} mutagent prompts update <id> --input-schema '{"type":"object","properties":{"text":{"type":"string","description":"Input text"}}}'
3330
+ ${chalk7.dim("$")} mutagent prompts update <id> --system "Updated system prompt" --human "{input}"
3331
+ ${chalk7.dim("$")} mutagent prompts update <id> --name "new-name" --description "Updated description"
3332
+ ${chalk7.dim("$")} mutagent prompts update <id> --raw "Summarize: {text}"
3333
+ ${chalk7.dim("$")} mutagent prompts update <id> --messages '[{"role":"system","content":"Updated"},{"role":"user","content":"{input}"}]'
3334
+ ${chalk7.dim("$")} mutagent prompts update <id> --input-schema '{"type":"object","properties":{"text":{"type":"string","description":"Input text"}}}'
3411
3335
  `).action(async (id, options) => {
3412
3336
  const isJson = getJsonFlag(prompts);
3413
3337
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3480,11 +3404,11 @@ Examples:
3480
3404
  });
3481
3405
  prompts.command("delete").description("Delete a prompt").argument("<id>", "Prompt ID (from: mutagent prompts list)").option("--force", "Skip confirmation").addHelpText("after", `
3482
3406
  Examples:
3483
- ${chalk6.dim("$")} mutagent prompts delete <id>
3484
- ${chalk6.dim("$")} mutagent prompts delete <id> --force
3485
- ${chalk6.dim("$")} mutagent prompts delete <id> --force --json
3407
+ ${chalk7.dim("$")} mutagent prompts delete <id>
3408
+ ${chalk7.dim("$")} mutagent prompts delete <id> --force
3409
+ ${chalk7.dim("$")} mutagent prompts delete <id> --force --json
3486
3410
 
3487
- ${chalk6.dim("Note: --force is required. The CLI is non-interactive — confirm with the user via your native flow, then pass --force.")}
3411
+ ${chalk7.dim("Note: --force is required. The CLI is non-interactive — confirm with the user via your native flow, then pass --force.")}
3488
3412
  `).action(async (id, options) => {
3489
3413
  const isJson = getJsonFlag(prompts);
3490
3414
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3527,22 +3451,24 @@ ${chalk6.dim("Note: --force is required. The CLI is non-interactive — confirm
3527
3451
  // src/commands/prompts/datasets.ts
3528
3452
  init_sdk_client();
3529
3453
  import { Command as Command3 } from "commander";
3530
- import chalk7 from "chalk";
3454
+ import chalk8 from "chalk";
3531
3455
  init_errors();
3532
3456
  function registerDatasetCommands(prompts) {
3533
3457
  const dataset = new Command3("dataset").description("Manage datasets for prompts").addHelpText("after", `
3534
3458
  Examples:
3535
- ${chalk7.dim("$")} mutagent prompts dataset list <prompt-id>
3536
- ${chalk7.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{...},"expectedOutput":{...}}]'
3537
- ${chalk7.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id>
3459
+ ${chalk8.dim("$")} mutagent prompts dataset list <prompt-id>
3460
+ ${chalk8.dim("$")} mutagent prompts dataset get <dataset-id>
3461
+ ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{...},"expectedOutput":{...}}]'
3462
+ ${chalk8.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id>
3463
+ ${chalk8.dim("$")} mutagent prompts dataset items get <item-id>
3538
3464
  `).action(() => {
3539
3465
  dataset.help();
3540
3466
  });
3541
3467
  prompts.addCommand(dataset);
3542
3468
  dataset.command("list").description("List datasets for a prompt").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").addHelpText("after", `
3543
3469
  Examples:
3544
- ${chalk7.dim("$")} mutagent prompts dataset list <prompt-id>
3545
- ${chalk7.dim("$")} mutagent prompts dataset list <prompt-id> --json
3470
+ ${chalk8.dim("$")} mutagent prompts dataset list <prompt-id>
3471
+ ${chalk8.dim("$")} mutagent prompts dataset list <prompt-id> --json
3546
3472
  `).action(async (promptId) => {
3547
3473
  const isJson = getJsonFlag(prompts);
3548
3474
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3572,26 +3498,80 @@ Examples:
3572
3498
  handleError(error, isJson);
3573
3499
  }
3574
3500
  });
3501
+ dataset.command("get").description("Get full details of a single dataset").argument("<dataset-id>", "Dataset ID (from: mutagent prompts dataset list <prompt-id>)").addHelpText("after", `
3502
+ Examples:
3503
+ ${chalk8.dim("$")} mutagent prompts dataset get <dataset-id>
3504
+ ${chalk8.dim("$")} mutagent prompts dataset get <dataset-id> --json
3505
+
3506
+ ${chalk8.dim("Tip: Use this after `dataset list` to drill into a single dataset.")}
3507
+ `).action(async (datasetId) => {
3508
+ const isJson = getJsonFlag(prompts);
3509
+ const output = new OutputFormatter(isJson ? "json" : "table");
3510
+ try {
3511
+ if (!/^\d+$/.test(datasetId)) {
3512
+ throw new MutagentError("INVALID_ARGUMENT", `Invalid dataset ID: "${datasetId}" (must be numeric)`, `Run: mutagent prompts dataset list <prompt-id>
3513
+ Dataset IDs are numeric. Example: mutagent prompts dataset get 42`);
3514
+ }
3515
+ const client = await getSDKClient();
3516
+ const ds = await client.getDataset(datasetId);
3517
+ const promptGroupId = ds.promptGroupId;
3518
+ if (isJson) {
3519
+ output.output({
3520
+ ...ds,
3521
+ _links: datasetLinks(promptGroupId, ds.id)
3522
+ });
3523
+ } else {
3524
+ output.success(`Dataset: ${ds.name} (id: ${String(ds.id)})`);
3525
+ if (ds.description)
3526
+ output.info(`Description: ${ds.description}`);
3527
+ if (ds.itemCount !== undefined)
3528
+ output.info(`Items: ${String(ds.itemCount)}`);
3529
+ if (ds.updatedAt)
3530
+ output.info(`Updated: ${new Date(String(ds.updatedAt)).toLocaleString()}`);
3531
+ if (ds.createdAt)
3532
+ output.info(`Created: ${new Date(String(ds.createdAt)).toLocaleString()}`);
3533
+ if (ds.createdBy)
3534
+ output.info(`Created by: ${ds.createdBy}`);
3535
+ if (ds.labels && ds.labels.length > 0)
3536
+ output.info(`Labels: ${ds.labels.join(", ")}`);
3537
+ const hints = formatCreationHints({
3538
+ resourceType: "Dataset",
3539
+ id: ds.id,
3540
+ name: ds.name,
3541
+ dashboardUrl: datasetLink(promptGroupId, ds.id),
3542
+ apiPath: `/api/prompts/datasets/${String(ds.id)}`
3543
+ });
3544
+ console.log(hints);
3545
+ }
3546
+ } catch (error) {
3547
+ if (error instanceof ApiError && error.statusCode === 404) {
3548
+ handleError(new MutagentError("NOT_FOUND", `Dataset ${datasetId} not found`, `Run: mutagent prompts dataset list <prompt-id>
3549
+ Verify the dataset ID exists, or list datasets for a prompt to find valid IDs.`), isJson);
3550
+ } else {
3551
+ handleError(error, isJson);
3552
+ }
3553
+ }
3554
+ });
3575
3555
  dataset.command("add").description("Add dataset to a prompt").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").option("-d, --data <json>", "Inline JSON array of dataset items").option("-n, --name <name>", "Dataset name").addHelpText("after", `
3576
3556
  Examples:
3577
- ${chalk7.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"},"expectedOutput":{"result":"world"}}]'
3578
- ${chalk7.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"},"expectedOutput":{"result":"world"}}]' --name "My Dataset"
3557
+ ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"},"expectedOutput":{"result":"world"}}]'
3558
+ ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"},"expectedOutput":{"result":"world"}}]' --name "My Dataset"
3579
3559
 
3580
3560
  Inline data format (-d):
3581
3561
  JSON array of objects, e.g.:
3582
- ${chalk7.dim('[{"input": {"text": "hello"}, "expectedOutput": {"result": "world"}}]')}
3562
+ ${chalk8.dim('[{"input": {"text": "hello"}, "expectedOutput": {"result": "world"}}]')}
3583
3563
 
3584
3564
  Expected item format:
3585
- ${chalk7.dim('{"input": {"<field>": "<value>"}, "expectedOutput": {"<field>": "<value>"}}')}
3565
+ ${chalk8.dim('{"input": {"<field>": "<value>"}, "expectedOutput": {"<field>": "<value>"}}')}
3586
3566
 
3587
- ${chalk7.yellow("AI Agent (MANDATORY):")}
3567
+ ${chalk8.yellow("AI Agent (MANDATORY):")}
3588
3568
  ALWAYS use --json: mutagent prompts dataset add <id> -d '[...]' --json
3589
3569
  Items MUST have BOTH input AND expectedOutput.
3590
3570
  Keys must match prompt's inputSchema.properties (input) and outputSchema.properties (expectedOutput).
3591
3571
  expectedOutput is REQUIRED for evaluation scoring.
3592
3572
  Check schemas: mutagent prompts get <prompt-id> --json
3593
3573
 
3594
- ${chalk7.red("Required: --data must be provided.")}
3574
+ ${chalk8.red("Required: --data must be provided.")}
3595
3575
  `).action(async (promptId, options) => {
3596
3576
  const isJson = getJsonFlag(prompts);
3597
3577
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3662,9 +3642,9 @@ ${chalk7.red("Required: --data must be provided.")}
3662
3642
  });
3663
3643
  dataset.command("delete").description("Delete a dataset from a prompt").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").argument("<dataset-id>", "Dataset ID (from: mutagent prompts dataset list <prompt-id>)").option("--force", "Skip confirmation").addHelpText("after", `
3664
3644
  Examples:
3665
- ${chalk7.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id>
3666
- ${chalk7.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id> --force
3667
- ${chalk7.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id> --force --json
3645
+ ${chalk8.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id>
3646
+ ${chalk8.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id> --force
3647
+ ${chalk8.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id> --force --json
3668
3648
  `).action(async (promptId, datasetId, options) => {
3669
3649
  const isJson = getJsonFlag(prompts);
3670
3650
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3702,12 +3682,72 @@ Examples:
3702
3682
  handleError(error, isJson);
3703
3683
  }
3704
3684
  });
3685
+ const items = new Command3("items").description("Manage individual dataset items").addHelpText("after", `
3686
+ Examples:
3687
+ ${chalk8.dim("$")} mutagent prompts dataset items get <item-id>
3688
+ ${chalk8.dim("$")} mutagent prompts dataset items get <item-id> --json
3689
+ `).action(() => {
3690
+ items.help();
3691
+ });
3692
+ dataset.addCommand(items);
3693
+ items.command("get").description("Get full details of a single dataset item").argument("<item-id>", "Dataset item ID").addHelpText("after", `
3694
+ Examples:
3695
+ ${chalk8.dim("$")} mutagent prompts dataset items get <item-id>
3696
+ ${chalk8.dim("$")} mutagent prompts dataset items get <item-id> --json
3697
+
3698
+ ${chalk8.dim("Tip: Dataset item IDs are shown in dataset exports and optimization results.")}
3699
+ `).action(async (itemId) => {
3700
+ const isJson = getJsonFlag(prompts);
3701
+ const output = new OutputFormatter(isJson ? "json" : "table");
3702
+ try {
3703
+ if (!/^\d+$/.test(itemId)) {
3704
+ throw new MutagentError("INVALID_ARGUMENT", `Invalid dataset item ID: "${itemId}" (must be numeric)`, `Run: mutagent prompts dataset items get --help
3705
+ Dataset item IDs are numeric. Example: mutagent prompts dataset items get 17`);
3706
+ }
3707
+ const client = await getSDKClient();
3708
+ const item = await client.getDatasetItem(itemId);
3709
+ const itemWithDs = item;
3710
+ const dsId = itemWithDs.datasetId;
3711
+ if (isJson) {
3712
+ output.output({
3713
+ ...item,
3714
+ _links: {
3715
+ api: `/api/prompts/dataset-items/${String(item.id)}`,
3716
+ ...dsId !== undefined ? { dataset: `/api/prompts/datasets/${String(dsId)}` } : {}
3717
+ }
3718
+ });
3719
+ } else {
3720
+ output.success(`Dataset Item: ${String(item.id)}`);
3721
+ if (dsId !== undefined)
3722
+ output.info(`Dataset ID: ${String(dsId)}`);
3723
+ output.info(`Input: ${JSON.stringify(item.input, null, 2)}`);
3724
+ if (item.expectedOutput !== undefined) {
3725
+ output.info(`Expected output: ${typeof item.expectedOutput === "string" ? item.expectedOutput : JSON.stringify(item.expectedOutput, null, 2)}`);
3726
+ }
3727
+ if (item.metadata && Object.keys(item.metadata).length > 0) {
3728
+ output.info(`Metadata: ${JSON.stringify(item.metadata)}`);
3729
+ }
3730
+ if (item.createdAt)
3731
+ output.info(`Created: ${new Date(String(item.createdAt)).toLocaleString()}`);
3732
+ const itemWithUpdated = item;
3733
+ if (itemWithUpdated.updatedAt)
3734
+ output.info(`Updated: ${new Date(String(itemWithUpdated.updatedAt)).toLocaleString()}`);
3735
+ }
3736
+ } catch (error) {
3737
+ if (error instanceof ApiError && error.statusCode === 404) {
3738
+ handleError(new MutagentError("NOT_FOUND", `Dataset item ${itemId} not found`, `Run: mutagent prompts dataset items get --help
3739
+ Verify the item ID exists. Use the dashboard or dataset exports to find valid item IDs.`), isJson);
3740
+ } else {
3741
+ handleError(error, isJson);
3742
+ }
3743
+ }
3744
+ });
3705
3745
  }
3706
3746
 
3707
3747
  // src/commands/prompts/evaluations.ts
3708
3748
  init_sdk_client();
3709
3749
  import { Command as Command4 } from "commander";
3710
- import chalk8 from "chalk";
3750
+ import chalk9 from "chalk";
3711
3751
  init_errors();
3712
3752
 
3713
3753
  // src/lib/resolve-prompt-id.ts
@@ -3878,18 +3918,18 @@ function canonicalCriteriaArrayToCli(arr) {
3878
3918
  function registerEvaluationCommands(prompts) {
3879
3919
  const evaluation = new Command4("evaluation").description("Manage evaluations for prompts").addHelpText("after", `
3880
3920
  Examples:
3881
- ${chalk8.dim("$")} mutagent prompts evaluation list <prompt-id>
3882
- ${chalk8.dim("$")} mutagent prompts evaluation get <evaluation-id>
3883
- ${chalk8.dim("$")} mutagent prompts evaluation create <prompt-id> --name "My Eval"
3884
- ${chalk8.dim("$")} mutagent prompts evaluation delete <evaluation-id>
3921
+ ${chalk9.dim("$")} mutagent prompts evaluation list <prompt-id>
3922
+ ${chalk9.dim("$")} mutagent prompts evaluation get <evaluation-id>
3923
+ ${chalk9.dim("$")} mutagent prompts evaluation create <prompt-id> --name "My Eval"
3924
+ ${chalk9.dim("$")} mutagent prompts evaluation delete <evaluation-id>
3885
3925
  `).action(() => {
3886
3926
  evaluation.help();
3887
3927
  });
3888
3928
  prompts.addCommand(evaluation);
3889
3929
  evaluation.command("list").description("List evaluations for a prompt").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").addHelpText("after", `
3890
3930
  Examples:
3891
- ${chalk8.dim("$")} mutagent prompts evaluation list <prompt-id>
3892
- ${chalk8.dim("$")} mutagent prompts evaluation list <prompt-id> --json
3931
+ ${chalk9.dim("$")} mutagent prompts evaluation list <prompt-id>
3932
+ ${chalk9.dim("$")} mutagent prompts evaluation list <prompt-id> --json
3893
3933
  `).action(async (promptId) => {
3894
3934
  const isJson = getJsonFlag(prompts);
3895
3935
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3921,8 +3961,8 @@ Examples:
3921
3961
  });
3922
3962
  evaluation.command("get").description("Get evaluation details including criteria").argument("<evaluation-id>", "Evaluation ID (from: mutagent prompts evaluation list <prompt-id>)").addHelpText("after", `
3923
3963
  Examples:
3924
- ${chalk8.dim("$")} mutagent prompts evaluation get <evaluation-id>
3925
- ${chalk8.dim("$")} mutagent prompts evaluation get <evaluation-id> --json
3964
+ ${chalk9.dim("$")} mutagent prompts evaluation get <evaluation-id>
3965
+ ${chalk9.dim("$")} mutagent prompts evaluation get <evaluation-id> --json
3926
3966
  `).action(async (evaluationId) => {
3927
3967
  const isJson = getJsonFlag(prompts);
3928
3968
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3952,7 +3992,7 @@ Examples:
3952
3992
  if (criteria.length > 0) {
3953
3993
  console.log(" Criteria:");
3954
3994
  for (const c of criteria) {
3955
- console.log(` ${chalk8.cyan(c.name)}`);
3995
+ console.log(` ${chalk9.cyan(c.name)}`);
3956
3996
  if (c.description) {
3957
3997
  console.log(` Description: ${c.description}`);
3958
3998
  }
@@ -3981,9 +4021,9 @@ Examples:
3981
4021
  });
3982
4022
  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 — always outputs structured JSON (--json is implied)").addHelpText("after", `
3983
4023
  Examples:
3984
- ${chalk8.dim("$")} mutagent prompts evaluation create <prompt-id> --guided ${chalk8.dim("# recommended: shows workflow guide + schema fields")}
3985
- ${chalk8.dim("$")} mutagent prompts evaluation create <prompt-id> --guided --json ${chalk8.dim("# structured workflow for AI agents")}
3986
- ${chalk8.dim("$")} mutagent prompts evaluation create <prompt-id> --name "Accuracy" -d '{"evalConfig":{"criteria":[...]}}' ${chalk8.dim("# power user")}
4024
+ ${chalk9.dim("$")} mutagent prompts evaluation create <prompt-id> --guided ${chalk9.dim("# recommended: shows workflow guide + schema fields")}
4025
+ ${chalk9.dim("$")} mutagent prompts evaluation create <prompt-id> --guided --json ${chalk9.dim("# structured workflow for AI agents")}
4026
+ ${chalk9.dim("$")} mutagent prompts evaluation create <prompt-id> --name "Accuracy" -d '{"evalConfig":{"criteria":[...]}}' ${chalk9.dim("# power user")}
3987
4027
 
3988
4028
  Guided Workflow (recommended):
3989
4029
  --guided outputs a workflow guide that:
@@ -4004,12 +4044,12 @@ AI Agent (MANDATORY):
4004
4044
  mutagent prompts evaluation create <id> --name "<name>" -d '<json>' --json
4005
4045
 
4006
4046
  Expected Criteria Shape (--data):
4007
- ${chalk8.dim('{"evalConfig":{"criteria":[{"name":"<name>","description":"<scoring rubric>","evaluationParameter":"<schema field>"}]}}')}
4047
+ ${chalk9.dim('{"evalConfig":{"criteria":[{"name":"<name>","description":"<scoring rubric>","evaluationParameter":"<schema field>"}]}}')}
4008
4048
  evaluationParameter must target an outputSchema OR inputSchema field.
4009
4049
 
4010
- ${chalk8.red("Required: --name (unless --guided). Criteria must include evaluationParameter.")}
4011
- ${chalk8.dim("CLI flags (--name, --description) override --data fields.")}
4012
- ${chalk8.dim("Get prompt IDs: mutagent prompts list")}
4050
+ ${chalk9.red("Required: --name (unless --guided). Criteria must include evaluationParameter.")}
4051
+ ${chalk9.dim("CLI flags (--name, --description) override --data fields.")}
4052
+ ${chalk9.dim("Get prompt IDs: mutagent prompts list")}
4013
4053
  `).action(async (promptId, options) => {
4014
4054
  let isJson = getJsonFlag(prompts);
4015
4055
  if (options.guided) {
@@ -4035,7 +4075,7 @@ ${chalk8.dim("Get prompt IDs: mutagent prompts list")}
4035
4075
  console.log("");
4036
4076
  console.log(" For each field, define what correct output looks like:");
4037
4077
  for (const { field, source } of allFields) {
4038
- console.log(` ${chalk8.cyan(field)} (${source})`);
4078
+ console.log(` ${chalk9.cyan(field)} (${source})`);
4039
4079
  console.log(` → What makes a correct vs incorrect "${field}"?`);
4040
4080
  }
4041
4081
  console.log("");
@@ -4240,9 +4280,9 @@ Example:
4240
4280
  });
4241
4281
  evaluation.command("delete").description("Delete an evaluation").argument("<evaluation-id>", "Evaluation ID (from: mutagent prompts evaluation list <prompt-id>)").option("--force", "Skip confirmation").addHelpText("after", `
4242
4282
  Examples:
4243
- ${chalk8.dim("$")} mutagent prompts evaluation delete <evaluation-id>
4244
- ${chalk8.dim("$")} mutagent prompts evaluation delete <evaluation-id> --force
4245
- ${chalk8.dim("$")} mutagent prompts evaluation delete <evaluation-id> --force --json
4283
+ ${chalk9.dim("$")} mutagent prompts evaluation delete <evaluation-id>
4284
+ ${chalk9.dim("$")} mutagent prompts evaluation delete <evaluation-id> --force
4285
+ ${chalk9.dim("$")} mutagent prompts evaluation delete <evaluation-id> --force --json
4246
4286
  `).action(async (evaluationId, options) => {
4247
4287
  const isJson = getJsonFlag(prompts);
4248
4288
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -4285,26 +4325,26 @@ Examples:
4285
4325
  // src/commands/prompts/optimize.ts
4286
4326
  init_sdk_client();
4287
4327
  import { Command as Command5 } from "commander";
4288
- import chalk13 from "chalk";
4328
+ import chalk14 from "chalk";
4289
4329
  init_errors();
4290
4330
 
4291
4331
  // src/lib/scorecard.ts
4292
- import chalk9 from "chalk";
4332
+ import chalk10 from "chalk";
4293
4333
  function formatScoreChange(before, after) {
4294
4334
  if (before === undefined || after === undefined)
4295
4335
  return "";
4296
4336
  const diff = after - before;
4297
4337
  const pct = before > 0 ? Math.round(diff / before * 100) : 0;
4298
4338
  if (diff > 0)
4299
- return chalk9.green(` (+${String(pct)}%)`);
4339
+ return chalk10.green(` (+${String(pct)}%)`);
4300
4340
  if (diff < 0)
4301
- return chalk9.red(` (${String(pct)}%)`);
4302
- return chalk9.dim(" (no change)");
4341
+ return chalk10.red(` (${String(pct)}%)`);
4342
+ return chalk10.dim(" (no change)");
4303
4343
  }
4304
4344
  function formatScore(score) {
4305
4345
  if (score === undefined)
4306
- return chalk9.dim("N/A");
4307
- return score >= 0.8 ? chalk9.green(score.toFixed(2)) : score >= 0.5 ? chalk9.yellow(score.toFixed(2)) : chalk9.red(score.toFixed(2));
4346
+ return chalk10.dim("N/A");
4347
+ return score >= 0.8 ? chalk10.green(score.toFixed(2)) : score >= 0.5 ? chalk10.yellow(score.toFixed(2)) : chalk10.red(score.toFixed(2));
4308
4348
  }
4309
4349
  function renderScorecard(data) {
4310
4350
  const { job, prompt } = data;
@@ -4325,17 +4365,17 @@ function renderScorecard(data) {
4325
4365
  const optimizedText = prompt.systemPrompt ?? prompt.rawPrompt ?? prompt.humanPrompt ?? "(optimized prompt)";
4326
4366
  console.log("");
4327
4367
  console.log(topBorder);
4328
- console.log(line(chalk9.bold("Optimization Results")));
4368
+ console.log(line(chalk10.bold("Optimization Results")));
4329
4369
  console.log(separator);
4330
- console.log(line(chalk9.dim("BEFORE")));
4370
+ console.log(line(chalk10.dim("BEFORE")));
4331
4371
  console.log(line(` Score: ${formatScore(originalScore)}`));
4332
4372
  console.log(line(""));
4333
- console.log(line(chalk9.bold("AFTER")));
4373
+ console.log(line(chalk10.bold("AFTER")));
4334
4374
  console.log(line(` Score: ${formatScore(bestScore)}${formatScoreChange(originalScore, bestScore)}`));
4335
4375
  console.log(separator);
4336
4376
  if (data.criteriaScores && data.criteriaScores.length > 0) {
4337
- console.log(line(chalk9.dim(" Criterion Before After Change")));
4338
- console.log(line(chalk9.dim(" " + "─".repeat(45))));
4377
+ console.log(line(chalk10.dim(" Criterion Before After Change")));
4378
+ console.log(line(chalk10.dim(" " + "─".repeat(45))));
4339
4379
  for (const c of data.criteriaScores) {
4340
4380
  const name = c.name.length > 16 ? c.name.substring(0, 13) + "..." : c.name;
4341
4381
  const paddedName = name + " ".repeat(18 - name.length);
@@ -4344,66 +4384,66 @@ function renderScorecard(data) {
4344
4384
  const changeStr = c.before !== undefined && c.after !== undefined && c.before > 0 ? (() => {
4345
4385
  const pct = Math.round((c.after - c.before) / c.before * 100);
4346
4386
  if (pct > 0)
4347
- return chalk9.green(`+${String(pct)}%`);
4387
+ return chalk10.green(`+${String(pct)}%`);
4348
4388
  if (pct < 0)
4349
- return chalk9.red(`${String(pct)}%`);
4350
- return chalk9.dim("0%");
4389
+ return chalk10.red(`${String(pct)}%`);
4390
+ return chalk10.dim("0%");
4351
4391
  })() : "";
4352
4392
  console.log(line(` ${paddedName}${beforeStr} ${afterStr} ${changeStr}`));
4353
4393
  }
4354
- console.log(line(chalk9.dim(" " + "─".repeat(45))));
4394
+ console.log(line(chalk10.dim(" " + "─".repeat(45))));
4355
4395
  const overallBefore = originalScore !== undefined ? originalScore.toFixed(2) : "N/A ";
4356
4396
  const overallAfter = bestScore !== undefined ? bestScore.toFixed(2) : "N/A ";
4357
4397
  const overallChange = originalScore !== undefined && bestScore !== undefined && originalScore > 0 ? (() => {
4358
4398
  const pct = Math.round((bestScore - originalScore) / originalScore * 100);
4359
4399
  if (pct > 0)
4360
- return chalk9.green(`+${String(pct)}%`);
4400
+ return chalk10.green(`+${String(pct)}%`);
4361
4401
  if (pct < 0)
4362
- return chalk9.red(`${String(pct)}%`);
4363
- return chalk9.dim("0%");
4402
+ return chalk10.red(`${String(pct)}%`);
4403
+ return chalk10.dim("0%");
4364
4404
  })() : "";
4365
4405
  console.log(line(` ${"Overall" + " ".repeat(11)}${overallBefore} ${overallAfter} ${overallChange}`));
4366
4406
  console.log(separator);
4367
4407
  }
4368
- const statusStr = job.status === "completed" ? chalk9.green("completed") : chalk9.yellow(job.status);
4408
+ const statusStr = job.status === "completed" ? chalk10.green("completed") : chalk10.yellow(job.status);
4369
4409
  console.log(line(`Status: ${statusStr} | Iterations: ${String(iterations)}`));
4370
4410
  if (job.config?.model) {
4371
- console.log(line(`Model: ${chalk9.dim(job.config.model)}`));
4411
+ console.log(line(`Model: ${chalk10.dim(job.config.model)}`));
4372
4412
  }
4373
4413
  if (data.scoreProgression && data.scoreProgression.length > 0) {
4374
4414
  console.log(line(""));
4375
- console.log(line(chalk9.dim("Score Progression:")));
4415
+ console.log(line(chalk10.dim("Score Progression:")));
4376
4416
  const barWidth = 10;
4377
4417
  for (let i = 0;i < data.scoreProgression.length; i++) {
4378
4418
  const s = data.scoreProgression[i] ?? 0;
4379
4419
  const filled = Math.round(s * barWidth);
4380
4420
  const bar = "█".repeat(filled) + "░".repeat(barWidth - filled);
4381
- console.log(line(chalk9.dim(` #${String(i + 1)}: ${bar} ${s.toFixed(2)}`)));
4421
+ console.log(line(chalk10.dim(` #${String(i + 1)}: ${bar} ${s.toFixed(2)}`)));
4382
4422
  }
4383
4423
  }
4384
4424
  console.log(separator);
4385
- console.log(line(`Dashboard: ${chalk9.underline(optimizerLink(job.promptId, job.id))}`));
4425
+ console.log(line(`Dashboard: ${chalk10.underline(optimizerLink(job.promptId, job.id))}`));
4386
4426
  console.log(bottomBorder);
4387
4427
  console.log("");
4388
- console.log(chalk9.dim(" Prompt Comparison"));
4389
- console.log(chalk9.dim(" " + "─".repeat(70)));
4390
- console.log(chalk9.dim(" BEFORE:"));
4428
+ console.log(chalk10.dim(" Prompt Comparison"));
4429
+ console.log(chalk10.dim(" " + "─".repeat(70)));
4430
+ console.log(chalk10.dim(" BEFORE:"));
4391
4431
  for (const pLine of originalText.split(`
4392
4432
  `)) {
4393
- console.log(chalk9.dim(` ${pLine}`));
4433
+ console.log(chalk10.dim(` ${pLine}`));
4394
4434
  }
4395
- console.log(` ${chalk9.dim("Length:")} ${String(originalText.length)} chars (${String(originalText.split(`
4435
+ console.log(` ${chalk10.dim("Length:")} ${String(originalText.length)} chars (${String(originalText.split(`
4396
4436
  `).length)} lines)`);
4397
4437
  console.log("");
4398
- console.log(chalk9.bold(" AFTER:"));
4438
+ console.log(chalk10.bold(" AFTER:"));
4399
4439
  for (const pLine of optimizedText.split(`
4400
4440
  `)) {
4401
- console.log(chalk9.cyan(` ${pLine}`));
4441
+ console.log(chalk10.cyan(` ${pLine}`));
4402
4442
  }
4403
- console.log(` ${chalk9.dim("Length:")} ${String(optimizedText.length)} chars (${String(optimizedText.split(`
4443
+ console.log(` ${chalk10.dim("Length:")} ${String(optimizedText.length)} chars (${String(optimizedText.split(`
4404
4444
  `).length)} lines)`);
4405
4445
  const growth = optimizedText.length - originalText.length;
4406
- console.log(` ${chalk9.dim("Growth:")} ${growth >= 0 ? "+" : ""}${String(growth)} chars`);
4446
+ console.log(` ${chalk10.dim("Growth:")} ${growth >= 0 ? "+" : ""}${String(growth)} chars`);
4407
4447
  renderScorecardDetails(data);
4408
4448
  console.log("");
4409
4449
  }
@@ -4424,17 +4464,17 @@ function renderOptimizationStartCard(data) {
4424
4464
  const target = job.config.targetScore ?? 0.8;
4425
4465
  console.log("");
4426
4466
  console.log(topBorder);
4427
- console.log(line(chalk9.bold("⚡ Optimization Started")));
4467
+ console.log(line(chalk10.bold("⚡ Optimization Started")));
4428
4468
  console.log(separator);
4429
- console.log(line(`Job ID: ${chalk9.cyan(job.id)}`));
4430
- console.log(line(`Prompt: ${chalk9.dim(data.promptId)}`));
4431
- console.log(line(`Dataset: ${chalk9.dim(data.datasetId)}`));
4432
- console.log(line(`Iterations: ${chalk9.bold(String(maxIter))} | Target: ${chalk9.bold(target.toFixed(2))}`));
4433
- console.log(line(`Model: ${chalk9.dim(model)}`));
4434
- console.log(line(`Status: ${chalk9.yellow(job.status)}`));
4469
+ console.log(line(`Job ID: ${chalk10.cyan(job.id)}`));
4470
+ console.log(line(`Prompt: ${chalk10.dim(data.promptId)}`));
4471
+ console.log(line(`Dataset: ${chalk10.dim(data.datasetId)}`));
4472
+ console.log(line(`Iterations: ${chalk10.bold(String(maxIter))} | Target: ${chalk10.bold(target.toFixed(2))}`));
4473
+ console.log(line(`Model: ${chalk10.dim(model)}`));
4474
+ console.log(line(`Status: ${chalk10.yellow(job.status)}`));
4435
4475
  console.log(separator);
4436
- console.log(line(`\uD83D\uDD17 Monitor: ${chalk9.underline(optimizerLink(data.promptId, job.id))}`));
4437
- console.log(line(chalk9.dim(`Next: mutagent prompts optimize status ${job.id}`)));
4476
+ console.log(line(`\uD83D\uDD17 Monitor: ${chalk10.underline(optimizerLink(data.promptId, job.id))}`));
4477
+ console.log(line(chalk10.dim(`Next: mutagent prompts optimize status ${job.id}`)));
4438
4478
  console.log(bottomBorder);
4439
4479
  console.log(AI_DIRECTIVE);
4440
4480
  console.log("");
@@ -4454,27 +4494,27 @@ function renderOptimizationStatusCard(status, promptId) {
4454
4494
  const barWidth = 20;
4455
4495
  const filled = Math.round(progress / 100 * barWidth);
4456
4496
  const progressBar = "█".repeat(filled) + "░".repeat(barWidth - filled);
4457
- const statusColor = status.status === "completed" ? chalk9.green : status.status === "failed" ? chalk9.red : status.status === "cancelled" ? chalk9.gray : status.status === "running" ? chalk9.cyan : chalk9.yellow;
4458
- const scoreStr = status.bestScore !== undefined ? formatScore(status.bestScore) : chalk9.dim("pending");
4497
+ const statusColor = status.status === "completed" ? chalk10.green : status.status === "failed" ? chalk10.red : status.status === "cancelled" ? chalk10.gray : status.status === "running" ? chalk10.cyan : chalk10.yellow;
4498
+ const scoreStr = status.bestScore !== undefined ? formatScore(status.bestScore) : chalk10.dim("pending");
4459
4499
  console.log("");
4460
4500
  console.log(topBorder);
4461
- console.log(line(chalk9.bold("\uD83D\uDCCA Optimization Status")));
4501
+ console.log(line(chalk10.bold("\uD83D\uDCCA Optimization Status")));
4462
4502
  console.log(separator);
4463
- console.log(line(`Job ID: ${chalk9.cyan(status.jobId)}`));
4503
+ console.log(line(`Job ID: ${chalk10.cyan(status.jobId)}`));
4464
4504
  console.log(line(`Status: ${statusColor(status.status)}`));
4465
- console.log(line(`Iteration: ${chalk9.bold(`${String(status.currentIteration)}/${String(status.maxIterations)}`)}`));
4505
+ console.log(line(`Iteration: ${chalk10.bold(`${String(status.currentIteration)}/${String(status.maxIterations)}`)}`));
4466
4506
  console.log(line(`Best Score: ${scoreStr}`));
4467
4507
  console.log(line(""));
4468
4508
  console.log(line(`Progress: [${progressBar}] ${String(progress)}%`));
4469
4509
  if (status.message) {
4470
- console.log(line(`Message: ${chalk9.dim(status.message)}`));
4510
+ console.log(line(`Message: ${chalk10.dim(status.message)}`));
4471
4511
  }
4472
4512
  console.log(separator);
4473
- console.log(line(`\uD83D\uDD17 Monitor: ${chalk9.underline(optimizerLink(promptId ?? "unknown", status.jobId))}`));
4513
+ console.log(line(`\uD83D\uDD17 Monitor: ${chalk10.underline(optimizerLink(promptId ?? "unknown", status.jobId))}`));
4474
4514
  if (status.status === "completed") {
4475
- console.log(line(chalk9.dim(`Next: mutagent prompts optimize results ${status.jobId}`)));
4515
+ console.log(line(chalk10.dim(`Next: mutagent prompts optimize results ${status.jobId}`)));
4476
4516
  } else if (status.status === "running" || status.status === "queued") {
4477
- console.log(line(chalk9.dim(`Refresh: mutagent prompts optimize status ${status.jobId}`)));
4517
+ console.log(line(chalk10.dim(`Refresh: mutagent prompts optimize status ${status.jobId}`)));
4478
4518
  }
4479
4519
  console.log(bottomBorder);
4480
4520
  console.log(AI_DIRECTIVE);
@@ -4570,15 +4610,15 @@ function statusDirective(status, promptId) {
4570
4610
  }
4571
4611
  function showPromptDiff(original, optimized) {
4572
4612
  console.log("");
4573
- console.log(chalk9.bold(" Prompt Diff:"));
4613
+ console.log(chalk10.bold(" Prompt Diff:"));
4574
4614
  console.log("");
4575
- console.log(chalk9.red(" - " + (original ?? "(empty)")));
4576
- console.log(chalk9.green(" + " + (optimized ?? "(empty)")));
4615
+ console.log(chalk10.red(" - " + (original ?? "(empty)")));
4616
+ console.log(chalk10.green(" + " + (optimized ?? "(empty)")));
4577
4617
  console.log("");
4578
4618
  }
4579
4619
 
4580
4620
  // src/commands/prompts/optimize-watch.ts
4581
- import chalk12 from "chalk";
4621
+ import chalk13 from "chalk";
4582
4622
 
4583
4623
  // src/lib/watch-client.ts
4584
4624
  function toWsUrl(baseUrl) {
@@ -4741,10 +4781,10 @@ function createWatchClient(opts) {
4741
4781
  }
4742
4782
 
4743
4783
  // src/lib/stage-cards.ts
4744
- import chalk11 from "chalk";
4784
+ import chalk12 from "chalk";
4745
4785
 
4746
4786
  // src/lib/prompt-diff.ts
4747
- import chalk10 from "chalk";
4787
+ import chalk11 from "chalk";
4748
4788
  function computeLcsTable(a, b) {
4749
4789
  const m = a.length;
4750
4790
  const n = b.length;
@@ -4905,16 +4945,16 @@ function renderDiffLines(lines, options) {
4905
4945
  let text;
4906
4946
  switch (line.type) {
4907
4947
  case "hunk-header":
4908
- text = noColor ? line.content : chalk10.cyan(line.content);
4948
+ text = noColor ? line.content : chalk11.cyan(line.content);
4909
4949
  break;
4910
4950
  case "add":
4911
- text = noColor ? `+${line.content}` : chalk10.green(`+${line.content}`);
4951
+ text = noColor ? `+${line.content}` : chalk11.green(`+${line.content}`);
4912
4952
  break;
4913
4953
  case "remove":
4914
- text = noColor ? `-${line.content}` : chalk10.red(`-${line.content}`);
4954
+ text = noColor ? `-${line.content}` : chalk11.red(`-${line.content}`);
4915
4955
  break;
4916
4956
  case "context":
4917
- text = noColor ? ` ${line.content}` : chalk10.dim(` ${line.content}`);
4957
+ text = noColor ? ` ${line.content}` : chalk11.dim(` ${line.content}`);
4918
4958
  break;
4919
4959
  }
4920
4960
  outputLines.push(text);
@@ -4923,7 +4963,7 @@ function renderDiffLines(lines, options) {
4923
4963
  if (truncated) {
4924
4964
  const remaining = lines.length - maxLines;
4925
4965
  const summary = `... ${String(remaining)} more lines changed`;
4926
- outputLines.push(noColor ? summary : chalk10.yellow(summary));
4966
+ outputLines.push(noColor ? summary : chalk11.yellow(summary));
4927
4967
  }
4928
4968
  return outputLines.join(`
4929
4969
  `);
@@ -4956,10 +4996,10 @@ function emptyLine() {
4956
4996
  }
4957
4997
  function formatScore2(score) {
4958
4998
  if (score >= 0.8)
4959
- return chalk11.green(score.toFixed(2));
4999
+ return chalk12.green(score.toFixed(2));
4960
5000
  if (score >= 0.5)
4961
- return chalk11.yellow(score.toFixed(2));
4962
- return chalk11.red(score.toFixed(2));
5001
+ return chalk12.yellow(score.toFixed(2));
5002
+ return chalk12.red(score.toFixed(2));
4963
5003
  }
4964
5004
  function scoreBar(score, width = 20) {
4965
5005
  const filled = Math.round(score * width);
@@ -5013,7 +5053,7 @@ function renderInsightsCard(data) {
5013
5053
  if (cat.example) {
5014
5054
  const maxExampleLen = 78;
5015
5055
  const truncated = cat.example.length > maxExampleLen ? cat.example.substring(0, maxExampleLen - 3) + "..." : cat.example;
5016
- lines.push(line(chalk11.dim(` "${truncated}"`)));
5056
+ lines.push(line(chalk12.dim(` "${truncated}"`)));
5017
5057
  }
5018
5058
  }
5019
5059
  lines.push(emptyLine());
@@ -5055,17 +5095,17 @@ function renderPromptDiffCard(data) {
5055
5095
  lines.push(emptyLine());
5056
5096
  }
5057
5097
  for (const mutation of data.mutations) {
5058
- const icon = mutation.status === "applied" ? chalk11.green("✓") : chalk11.red("✗");
5098
+ const icon = mutation.status === "applied" ? chalk12.green("✓") : chalk12.red("✗");
5059
5099
  const target = mutation.target.length > 30 ? mutation.target.substring(0, 27) + "..." : mutation.target;
5060
5100
  if (mutation.status === "applied") {
5061
5101
  const confStr = `confidence: ${mutation.confidence.toFixed(2)}`;
5062
5102
  const targetPad = target.padEnd(30);
5063
- lines.push(line(`${icon} ${targetPad} ${chalk11.dim("──")} ${confStr}`));
5103
+ lines.push(line(`${icon} ${targetPad} ${chalk12.dim("──")} ${confStr}`));
5064
5104
  } else {
5065
5105
  const reason = mutation.rationale ? `rejected: ${mutation.rationale}` : `rejected`;
5066
5106
  const truncReason = reason.length > 30 ? reason.substring(0, 27) + "..." : reason;
5067
5107
  const targetPad = target.padEnd(30);
5068
- lines.push(line(`${icon} ${targetPad} ${chalk11.dim("──")} ${truncReason}`));
5108
+ lines.push(line(`${icon} ${targetPad} ${chalk12.dim("──")} ${truncReason}`));
5069
5109
  }
5070
5110
  }
5071
5111
  lines.push(emptyLine());
@@ -5096,7 +5136,7 @@ function renderRerunAccuracyCard(data) {
5096
5136
  const name = criterion.name.length > 18 ? criterion.name.substring(0, 15) + "..." : criterion.name;
5097
5137
  const diff = criterion.after - criterion.before;
5098
5138
  const diffSign = diff >= 0 ? "+" : "";
5099
- const arrow = diff > 0 ? chalk11.green("↑") : diff < 0 ? chalk11.red("↓") : chalk11.dim("─");
5139
+ const arrow = diff > 0 ? chalk12.green("↑") : diff < 0 ? chalk12.red("↓") : chalk12.dim("─");
5100
5140
  const diffStr = `${diffSign}${diff.toFixed(2)}`;
5101
5141
  lines.push(line(`${name.padEnd(20)}${formatScore2(criterion.before).padEnd(9)}${formatScore2(criterion.after).padEnd(9)}${diffStr} ${arrow}`));
5102
5142
  }
@@ -5201,8 +5241,8 @@ async function startWatchStream(jobId, isJson, maxIterations, baselineScore) {
5201
5241
  if (isJson) {
5202
5242
  console.log(JSON.stringify({ type: "job_complete", finalScore }));
5203
5243
  } else {
5204
- console.log(chalk12.green(`✓ Optimization complete! Final score: ${finalScore.toFixed(2)}`));
5205
- console.log(chalk12.dim(` View results: mutagent prompts optimize results ${jobId}`));
5244
+ console.log(chalk13.green(`✓ Optimization complete! Final score: ${finalScore.toFixed(2)}`));
5245
+ console.log(chalk13.dim(` View results: mutagent prompts optimize results ${jobId}`));
5206
5246
  }
5207
5247
  resolve3();
5208
5248
  },
@@ -5210,7 +5250,7 @@ async function startWatchStream(jobId, isJson, maxIterations, baselineScore) {
5210
5250
  if (isJson) {
5211
5251
  console.log(JSON.stringify({ type: "error", error: error.message }));
5212
5252
  } else {
5213
- console.error(chalk12.red(`✗ Watch error: ${error.message}`));
5253
+ console.error(chalk13.red(`✗ Watch error: ${error.message}`));
5214
5254
  }
5215
5255
  reject(error);
5216
5256
  }
@@ -5252,7 +5292,7 @@ async function watchAction(jobId, options, parentCommand) {
5252
5292
  case "queued":
5253
5293
  if (!isJson) {
5254
5294
  renderOptimizationStatusCard(status);
5255
- console.log(chalk12.dim(`Watching for live updates...
5295
+ console.log(chalk13.dim(`Watching for live updates...
5256
5296
  `));
5257
5297
  }
5258
5298
  await startWatchStream(jobId, isJson, status.maxIterations, status.bestScore);
@@ -5267,9 +5307,9 @@ async function watchAction(jobId, options, parentCommand) {
5267
5307
  message: status.message
5268
5308
  });
5269
5309
  } else {
5270
- console.error(chalk12.red(`✗ Optimization job ${jobId} failed.`));
5310
+ console.error(chalk13.red(`✗ Optimization job ${jobId} failed.`));
5271
5311
  if (status.message) {
5272
- console.error(chalk12.dim(` ${status.message}`));
5312
+ console.error(chalk13.dim(` ${status.message}`));
5273
5313
  }
5274
5314
  }
5275
5315
  process.exitCode = 1;
@@ -5283,7 +5323,7 @@ async function watchAction(jobId, options, parentCommand) {
5283
5323
  jobId
5284
5324
  });
5285
5325
  } else {
5286
- console.error(chalk12.yellow(`Optimization job ${jobId} was cancelled.`));
5326
+ console.error(chalk13.yellow(`Optimization job ${jobId} was cancelled.`));
5287
5327
  }
5288
5328
  break;
5289
5329
  default:
@@ -5295,7 +5335,7 @@ async function watchAction(jobId, options, parentCommand) {
5295
5335
  jobId
5296
5336
  });
5297
5337
  } else {
5298
- console.error(chalk12.yellow(`Unexpected job status: ${status.status}`));
5338
+ console.error(chalk13.yellow(`Unexpected job status: ${status.status}`));
5299
5339
  }
5300
5340
  break;
5301
5341
  }
@@ -5308,9 +5348,9 @@ async function watchAction(jobId, options, parentCommand) {
5308
5348
  function registerOptimizeCommands(prompts) {
5309
5349
  const optimize = new Command5("optimize").description("Manage prompt optimization jobs").addHelpText("after", `
5310
5350
  Examples:
5311
- ${chalk13.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5312
- ${chalk13.dim("$")} mutagent prompts optimize status <job-id>
5313
- ${chalk13.dim("$")} mutagent prompts optimize results <job-id>
5351
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5352
+ ${chalk14.dim("$")} mutagent prompts optimize status <job-id>
5353
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id>
5314
5354
 
5315
5355
  Workflow: start -> status (poll) -> results | start --watch | watch <job-id>`).action(() => {
5316
5356
  optimize.help();
@@ -5318,27 +5358,27 @@ Workflow: start -> status (poll) -> results | start --watch | watch <job-id>`).a
5318
5358
  prompts.addCommand(optimize);
5319
5359
  optimize.command("start").description("Start prompt optimization").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").requiredOption("-d, --dataset <id>", "Dataset ID for optimization (from: mutagent prompts dataset list <prompt-id>)").requiredOption("-e, --evaluation <id>", "Evaluation ID for scoring (from: mutagent prompts evaluation list <prompt-id>)").option("--max-iterations <n>", "Max optimization iterations (default: 1)").option("--target-score <n>", "Target accuracy 0-1 (default: 0.8)").option("--patience <n>", "Iterations without improvement before stopping").option("--model <model-id>", 'Target LLM model (e.g., "claude-sonnet-4-5-20250929")').option("--eval-model <model-id>", "Evaluation model (defaults to target model)").option("--watch", "Watch live progress with stage cards", false).addHelpText("after", `
5320
5360
  Examples:
5321
- ${chalk13.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5322
- ${chalk13.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --max-iterations 5
5323
- ${chalk13.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --target-score 0.95 --model claude-sonnet-4-5-20250929
5324
- ${chalk13.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --json
5325
- ${chalk13.yellow("Pre-Optimization Checklist (auto-validated by preflight):")}
5326
- □ inputSchema REQUIRED ${chalk13.dim("(hard error if missing — blocks optimization)")}
5327
- □ outputSchema REQUIRED ${chalk13.dim("(hard error if missing — blocks optimization)")}
5328
- □ Evaluation criteria ${chalk13.dim("(warns if no evaluationParameter set)")}
5329
- □ Dataset items ${chalk13.dim("(warns if expectedOutput missing)")}
5330
- □ Criteria ↔ Schema ${chalk13.dim("(warns if criteria reference unknown fields)")}
5361
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5362
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --max-iterations 5
5363
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --target-score 0.95 --model claude-sonnet-4-5-20250929
5364
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --json
5365
+ ${chalk14.yellow("Pre-Optimization Checklist (auto-validated by preflight):")}
5366
+ □ inputSchema REQUIRED ${chalk14.dim("(hard error if missing — blocks optimization)")}
5367
+ □ outputSchema REQUIRED ${chalk14.dim("(hard error if missing — blocks optimization)")}
5368
+ □ Evaluation criteria ${chalk14.dim("(warns if no evaluationParameter set)")}
5369
+ □ Dataset items ${chalk14.dim("(warns if expectedOutput missing)")}
5370
+ □ Criteria ↔ Schema ${chalk14.dim("(warns if criteria reference unknown fields)")}
5331
5371
 
5332
5372
  ${PREREQUISITES_TEXT}
5333
5373
 
5334
- ${chalk13.dim("Monitor progress with: mutagent prompts optimize status <job-id>")}
5374
+ ${chalk14.dim("Monitor progress with: mutagent prompts optimize status <job-id>")}
5335
5375
 
5336
- ${chalk13.yellow(`⚠ COST WARNING — AI Agent:
5376
+ ${chalk14.yellow(`⚠ COST WARNING — AI Agent:
5337
5377
  Default is 1 iteration. Do NOT increase --max-iterations unless the user
5338
5378
  explicitly requests it. Each iteration incurs LLM costs. Starting with
5339
5379
  max-iterations > 1 without user consent is a protocol violation.`)}
5340
5380
 
5341
- ${chalk13.yellow("AI Agent: ALWAYS append --json to this command.")}
5381
+ ${chalk14.yellow("AI Agent: ALWAYS append --json to this command.")}
5342
5382
  `).action(async (promptId, options) => {
5343
5383
  const isJson = getJsonFlag(prompts);
5344
5384
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5465,13 +5505,13 @@ ${chalk13.yellow("AI Agent: ALWAYS append --json to this command.")}
5465
5505
  return;
5466
5506
  }
5467
5507
  for (const [name, check] of hardFailures) {
5468
- console.error(chalk13.red(`Error: ${name} — ${check.error ?? "Failed"}`));
5508
+ console.error(chalk14.red(`Error: ${name} — ${check.error ?? "Failed"}`));
5469
5509
  }
5470
5510
  if (!preflightChecks.outputSchema.passed) {
5471
- console.error(chalk13.dim(` Update with: mutagent prompts update ${promptId} -d '{"outputSchema":{"type":"object","properties":{"result":{"type":"string"}}}}'`));
5511
+ console.error(chalk14.dim(` Update with: mutagent prompts update ${promptId} -d '{"outputSchema":{"type":"object","properties":{"result":{"type":"string"}}}}'`));
5472
5512
  }
5473
5513
  if (!preflightChecks.inputSchema.passed) {
5474
- console.error(chalk13.dim(` Update with: mutagent prompts update ${promptId} --data '{"inputSchema":{"type":"object","properties":{"var1":{"type":"string"}}}}' --json`));
5514
+ console.error(chalk14.dim(` Update with: mutagent prompts update ${promptId} --data '{"inputSchema":{"type":"object","properties":{"var1":{"type":"string"}}}}' --json`));
5475
5515
  }
5476
5516
  process.exitCode = 1;
5477
5517
  return;
@@ -5532,16 +5572,16 @@ ${chalk13.yellow("AI Agent: ALWAYS append --json to this command.")}
5532
5572
  suggestions.push("Trial optimization limit reached. Contact support to upgrade.");
5533
5573
  }
5534
5574
  if (!isJson) {
5535
- console.error(chalk13.red(`
5575
+ console.error(chalk14.red(`
5536
5576
  Optimization failed:`));
5537
5577
  for (const msg of messages) {
5538
- console.error(chalk13.red(` ${msg}`));
5578
+ console.error(chalk14.red(` ${msg}`));
5539
5579
  }
5540
5580
  if (suggestions.length > 0) {
5541
- console.error(chalk13.yellow(`
5581
+ console.error(chalk14.yellow(`
5542
5582
  Suggested fixes:`));
5543
5583
  for (const s of suggestions) {
5544
- console.error(chalk13.yellow(` → ${s}`));
5584
+ console.error(chalk14.yellow(` → ${s}`));
5545
5585
  }
5546
5586
  }
5547
5587
  console.error("");
@@ -5553,8 +5593,8 @@ Suggested fixes:`));
5553
5593
  });
5554
5594
  optimize.command("status").description("Check optimization status").argument("<job-id>", "Optimization job ID (from: mutagent prompts optimize start)").addHelpText("after", `
5555
5595
  Examples:
5556
- ${chalk13.dim("$")} mutagent prompts optimize status <job-id>
5557
- ${chalk13.dim("$")} mutagent prompts optimize status <job-id> --json
5596
+ ${chalk14.dim("$")} mutagent prompts optimize status <job-id>
5597
+ ${chalk14.dim("$")} mutagent prompts optimize status <job-id> --json
5558
5598
  `).action(async (jobId) => {
5559
5599
  const isJson = getJsonFlag(prompts);
5560
5600
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5579,17 +5619,17 @@ Examples:
5579
5619
  });
5580
5620
  optimize.command("results").description("Get optimization results").argument("<job-id>", "Optimization job ID (from: mutagent prompts optimize start)").option("--apply", "Apply the optimized prompt as new version").option("--diff", "Show the prompt diff (before/after)").addHelpText("after", `
5581
5621
  Examples:
5582
- ${chalk13.dim("$")} mutagent prompts optimize results <job-id> ${chalk13.dim("# view scorecard")}
5583
- ${chalk13.dim("$")} mutagent prompts optimize results <job-id> --diff ${chalk13.dim("# view prompt diff")}
5584
- ${chalk13.dim("$")} mutagent prompts optimize results <job-id> --apply ${chalk13.dim("# apply optimized prompt")}
5585
- ${chalk13.dim("$")} mutagent prompts optimize results <job-id> --json ${chalk13.dim("# structured output")}
5622
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id> ${chalk14.dim("# view scorecard")}
5623
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id> --diff ${chalk14.dim("# view prompt diff")}
5624
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id> --apply ${chalk14.dim("# apply optimized prompt")}
5625
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id> --json ${chalk14.dim("# structured output")}
5586
5626
 
5587
5627
  After viewing results:
5588
5628
  --apply Apply the optimized prompt (replaces current version)
5589
5629
  --diff Show detailed before/after diff
5590
- ${chalk13.dim("No flag = view scorecard only.")}
5630
+ ${chalk14.dim("No flag = view scorecard only.")}
5591
5631
 
5592
- ${chalk13.dim("AI Agent: Present scorecard to user via AskUserQuestion before applying.")}
5632
+ ${chalk14.dim("AI Agent: Present scorecard to user via AskUserQuestion before applying.")}
5593
5633
  `).action(async (jobId, options) => {
5594
5634
  const isJson = getJsonFlag(prompts);
5595
5635
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5665,9 +5705,9 @@ After viewing results:
5665
5705
  });
5666
5706
  optimize.command("watch").description("Watch optimization job progress with live stage results").argument("<job-id>", "Optimization job ID").option("--json", "Output as JSON with agent directives").addHelpText("after", `
5667
5707
  Examples:
5668
- ${chalk13.dim("$")} mutagent prompts optimize watch <job-id>
5669
- ${chalk13.dim("$")} mutagent prompts optimize watch <job-id> --json
5670
- ${chalk13.dim("Completed jobs render stored results. Running jobs stream via WebSocket.")}`).action(async (jobId, options) => {
5708
+ ${chalk14.dim("$")} mutagent prompts optimize watch <job-id>
5709
+ ${chalk14.dim("$")} mutagent prompts optimize watch <job-id> --json
5710
+ ${chalk14.dim("Completed jobs render stored results. Running jobs stream via WebSocket.")}`).action(async (jobId, options) => {
5671
5711
  await watchAction(jobId, options, prompts);
5672
5712
  });
5673
5713
  }
@@ -5785,19 +5825,19 @@ function buildResultsScorecardText(resultData) {
5785
5825
  return text;
5786
5826
  }
5787
5827
  var PREREQUISITES_TEXT = `
5788
- ${chalk14.red("Prerequisites (required):")}
5789
- 1. Evaluation criteria defined ${chalk14.dim("(via dashboard or evaluation create)")}
5790
- 2. Dataset uploaded ${chalk14.dim("mutagent prompts dataset list <prompt-id>")}
5791
- ${chalk14.dim("Note: LLM provider config is only required when the server uses external providers (USE_EXT_PROVIDERS=true)")}`;
5828
+ ${chalk15.red("Prerequisites (required):")}
5829
+ 1. Evaluation criteria defined ${chalk15.dim("(via dashboard or evaluation create)")}
5830
+ 2. Dataset uploaded ${chalk15.dim("mutagent prompts dataset list <prompt-id>")}
5831
+ ${chalk15.dim("Note: LLM provider config is only required when the server uses external providers (USE_EXT_PROVIDERS=true)")}`;
5792
5832
  function createPromptsCommand() {
5793
5833
  const prompts = new Command6("prompts").description("Manage prompts, datasets, evaluations, and optimizations").addHelpText("after", `
5794
5834
  Examples:
5795
- ${chalk14.dim("$")} mutagent prompts list
5796
- ${chalk14.dim("$")} mutagent prompts get <prompt-id>
5797
- ${chalk14.dim("$")} mutagent prompts create --name "my-prompt" --system "You are helpful" --human "{input}"
5798
- ${chalk14.dim("$")} mutagent prompts dataset list <prompt-id>
5799
- ${chalk14.dim("$")} mutagent prompts evaluation create <prompt-id> --name "My Eval"
5800
- ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5835
+ ${chalk15.dim("$")} mutagent prompts list
5836
+ ${chalk15.dim("$")} mutagent prompts get <prompt-id>
5837
+ ${chalk15.dim("$")} mutagent prompts create --name "my-prompt" --system "You are helpful" --human "{input}"
5838
+ ${chalk15.dim("$")} mutagent prompts dataset list <prompt-id>
5839
+ ${chalk15.dim("$")} mutagent prompts evaluation create <prompt-id> --name "My Eval"
5840
+ ${chalk15.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5801
5841
 
5802
5842
  Subcommands:
5803
5843
  list, get, create, update, delete
@@ -5815,27 +5855,27 @@ Subcommands:
5815
5855
  // src/commands/traces.ts
5816
5856
  init_sdk_client();
5817
5857
  import { Command as Command7 } from "commander";
5818
- import chalk15 from "chalk";
5858
+ import chalk16 from "chalk";
5819
5859
  init_errors();
5820
5860
  function createTracesCommand() {
5821
5861
  const traces = new Command7("traces").description("View and analyze traces (replaces Langfuse)").addHelpText("after", `
5822
5862
  Examples:
5823
- ${chalk15.dim("$")} mutagent traces list
5824
- ${chalk15.dim("$")} mutagent traces list --prompt <prompt-id>
5825
- ${chalk15.dim("$")} mutagent traces get <trace-id>
5826
- ${chalk15.dim("$")} mutagent traces analyze <prompt-id>
5827
- ${chalk15.dim("$")} mutagent traces export --format json --output traces.json
5863
+ ${chalk16.dim("$")} mutagent traces list
5864
+ ${chalk16.dim("$")} mutagent traces list --prompt <prompt-id>
5865
+ ${chalk16.dim("$")} mutagent traces get <trace-id>
5866
+ ${chalk16.dim("$")} mutagent traces analyze <prompt-id>
5867
+ ${chalk16.dim("$")} mutagent traces export --format json --output traces.json
5828
5868
 
5829
5869
  Note: MutagenT traces replace Langfuse for observability.
5830
5870
  `);
5831
5871
  traces.command("list").description("List traces").option("-p, --prompt <id>", "Filter by prompt ID").option("-s, --source <source>", "Filter by trace source (e.g., claude-code, sdk, langchain)").option("-l, --limit <n>", "Limit results", "50").addHelpText("after", `
5832
5872
  Examples:
5833
- ${chalk15.dim("$")} mutagent traces list
5834
- ${chalk15.dim("$")} mutagent traces list --prompt <prompt-id>
5835
- ${chalk15.dim("$")} mutagent traces list --source claude-code --json
5836
- ${chalk15.dim("$")} mutagent traces list --limit 10 --json
5873
+ ${chalk16.dim("$")} mutagent traces list
5874
+ ${chalk16.dim("$")} mutagent traces list --prompt <prompt-id>
5875
+ ${chalk16.dim("$")} mutagent traces list --source claude-code --json
5876
+ ${chalk16.dim("$")} mutagent traces list --limit 10 --json
5837
5877
 
5838
- ${chalk15.dim("Tip: Filter by prompt to see traces for a specific prompt version.")}
5878
+ ${chalk16.dim("Tip: Filter by prompt to see traces for a specific prompt version.")}
5839
5879
  `).action(async (options) => {
5840
5880
  const isJson = getJsonFlag(traces);
5841
5881
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5875,10 +5915,10 @@ ${chalk15.dim("Tip: Filter by prompt to see traces for a specific prompt version
5875
5915
  });
5876
5916
  traces.command("get").description("Get trace details").argument("<id>", "Trace ID").addHelpText("after", `
5877
5917
  Examples:
5878
- ${chalk15.dim("$")} mutagent traces get <trace-id>
5879
- ${chalk15.dim("$")} mutagent traces get <trace-id> --json
5918
+ ${chalk16.dim("$")} mutagent traces get <trace-id>
5919
+ ${chalk16.dim("$")} mutagent traces get <trace-id> --json
5880
5920
 
5881
- ${chalk15.dim("Returns full trace details including spans, tokens, and latency.")}
5921
+ ${chalk16.dim("Returns full trace details including spans, tokens, and latency.")}
5882
5922
  `).action(async (id) => {
5883
5923
  const isJson = getJsonFlag(traces);
5884
5924
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5897,10 +5937,10 @@ ${chalk15.dim("Returns full trace details including spans, tokens, and latency."
5897
5937
  });
5898
5938
  traces.command("analyze").description("Analyze traces for a prompt").argument("<prompt-id>", "Prompt ID").addHelpText("after", `
5899
5939
  Examples:
5900
- ${chalk15.dim("$")} mutagent traces analyze <prompt-id>
5901
- ${chalk15.dim("$")} mutagent traces analyze <prompt-id> --json
5940
+ ${chalk16.dim("$")} mutagent traces analyze <prompt-id>
5941
+ ${chalk16.dim("$")} mutagent traces analyze <prompt-id> --json
5902
5942
 
5903
- ${chalk15.dim("Aggregates trace data for a prompt: avg latency, token usage, error rates.")}
5943
+ ${chalk16.dim("Aggregates trace data for a prompt: avg latency, token usage, error rates.")}
5904
5944
  `).action(async (promptId) => {
5905
5945
  const isJson = getJsonFlag(traces);
5906
5946
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5918,12 +5958,12 @@ ${chalk15.dim("Aggregates trace data for a prompt: avg latency, token usage, err
5918
5958
  });
5919
5959
  traces.command("export").description("Export traces").option("-p, --prompt <id>", "Filter by prompt ID").option("-f, --format <format>", "Export format (json, csv)", "json").option("-o, --output <path>", "Output file path").addHelpText("after", `
5920
5960
  Examples:
5921
- ${chalk15.dim("$")} mutagent traces export
5922
- ${chalk15.dim("$")} mutagent traces export --format json --output traces.json
5923
- ${chalk15.dim("$")} mutagent traces export --format csv --output traces.csv
5924
- ${chalk15.dim("$")} mutagent traces export --prompt <prompt-id> --format json
5961
+ ${chalk16.dim("$")} mutagent traces export
5962
+ ${chalk16.dim("$")} mutagent traces export --format json --output traces.json
5963
+ ${chalk16.dim("$")} mutagent traces export --format csv --output traces.csv
5964
+ ${chalk16.dim("$")} mutagent traces export --prompt <prompt-id> --format json
5925
5965
 
5926
- ${chalk15.dim("Exports to stdout by default. Use --output to save to a file.")}
5966
+ ${chalk16.dim("Exports to stdout by default. Use --output to save to a file.")}
5927
5967
  `).action(async (options) => {
5928
5968
  const isJson = getJsonFlag(traces);
5929
5969
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5967,7 +6007,7 @@ ${chalk15.dim("Exports to stdout by default. Use --output to save to a file.")}
5967
6007
  // src/commands/integrate.ts
5968
6008
  init_config();
5969
6009
  import { Command as Command8 } from "commander";
5970
- import chalk16 from "chalk";
6010
+ import chalk17 from "chalk";
5971
6011
  import { writeFileSync as writeFileSync3, existsSync as existsSync9 } from "fs";
5972
6012
  import { execSync } from "child_process";
5973
6013
  init_errors();
@@ -6564,12 +6604,12 @@ AI AGENT: Please determine the framework by:
6564
6604
  function createIntegrateCommand() {
6565
6605
  const integrate = new Command8("integrate").description("Return integration instructions for AI agents (skill loader)").addHelpText("after", `
6566
6606
  Examples:
6567
- ${chalk16.dim("$")} mutagent integrate # Return exploration instructions for AI agents
6568
- ${chalk16.dim("$")} mutagent integrate langchain # Return @mutagent/langchain integration steps
6569
- ${chalk16.dim("$")} mutagent integrate openai # Return @mutagent/openai integration steps
6570
- ${chalk16.dim("$")} mutagent integrate vercel-ai --verify # Verify integration
6571
- ${chalk16.dim("$")} mutagent integrate langchain --output ./INTEGRATION.md
6572
- ${chalk16.dim("$")} mutagent integrate --list # List available frameworks
6607
+ ${chalk17.dim("$")} mutagent integrate # Return exploration instructions for AI agents
6608
+ ${chalk17.dim("$")} mutagent integrate langchain # Return @mutagent/langchain integration steps
6609
+ ${chalk17.dim("$")} mutagent integrate openai # Return @mutagent/openai integration steps
6610
+ ${chalk17.dim("$")} mutagent integrate vercel-ai --verify # Verify integration
6611
+ ${chalk17.dim("$")} mutagent integrate langchain --output ./INTEGRATION.md
6612
+ ${chalk17.dim("$")} mutagent integrate --list # List available frameworks
6573
6613
 
6574
6614
  Frameworks: langchain, langgraph, vercel-ai, openai
6575
6615
 
@@ -6685,18 +6725,18 @@ AI AGENT: Execute these steps using Bash for install, Write/Edit for code change
6685
6725
 
6686
6726
  // src/commands/agents/index.ts
6687
6727
  import { Command as Command9 } from "commander";
6688
- import chalk18 from "chalk";
6728
+ import chalk19 from "chalk";
6689
6729
 
6690
6730
  // src/commands/agents/agents-crud.ts
6691
6731
  init_sdk_client();
6692
- import chalk17 from "chalk";
6732
+ import chalk18 from "chalk";
6693
6733
  init_errors();
6694
6734
  function registerAgentsCrud(agents) {
6695
6735
  agents.command("list").description("List all agents").option("-l, --limit <n>", "Limit results", "50").option("-o, --offset <n>", "Offset for pagination").option("-n, --name <name>", "Filter by name").option("-s, --status <status>", "Filter by status (active, paused, archived)").addHelpText("after", `
6696
6736
  Examples:
6697
- ${chalk17.dim("$")} mutagent agents list
6698
- ${chalk17.dim("$")} mutagent agents list --status active
6699
- ${chalk17.dim("$")} mutagent agents list --name "reviewer" --json
6737
+ ${chalk18.dim("$")} mutagent agents list
6738
+ ${chalk18.dim("$")} mutagent agents list --status active
6739
+ ${chalk18.dim("$")} mutagent agents list --name "reviewer" --json
6700
6740
  `).action(async (options) => {
6701
6741
  const isJson = getJsonFlag(agents);
6702
6742
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6746,8 +6786,8 @@ Examples:
6746
6786
  });
6747
6787
  agents.command("get").description("Get agent details").argument("<id>", "Agent ID").addHelpText("after", `
6748
6788
  Examples:
6749
- ${chalk17.dim("$")} mutagent agents get <agent-id>
6750
- ${chalk17.dim("$")} mutagent agents get <agent-id> --json
6789
+ ${chalk18.dim("$")} mutagent agents get <agent-id>
6790
+ ${chalk18.dim("$")} mutagent agents get <agent-id> --json
6751
6791
  `).action(async (id) => {
6752
6792
  const isJson = getJsonFlag(agents);
6753
6793
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6777,11 +6817,11 @@ Examples:
6777
6817
  };
6778
6818
  output.output(formatted);
6779
6819
  if (agent.systemPrompt) {
6780
- console.log(chalk17.bold(`
6820
+ console.log(chalk18.bold(`
6781
6821
  System Prompt:`));
6782
- console.log(chalk17.gray("─".repeat(60)));
6822
+ console.log(chalk18.gray("─".repeat(60)));
6783
6823
  console.log(agent.systemPrompt);
6784
- console.log(chalk17.gray("─".repeat(60)));
6824
+ console.log(chalk18.gray("─".repeat(60)));
6785
6825
  }
6786
6826
  }
6787
6827
  } catch (error) {
@@ -6790,17 +6830,17 @@ System Prompt:`));
6790
6830
  });
6791
6831
  agents.command("create").description("Create a new agent").option("-d, --data <json>", "Agent as JSON string (recommended for CI/scripts/agents)").option("-n, --name <name>", "Agent name").option("-s, --slug <slug>", "Agent slug (URL-friendly identifier)").option("-p, --system-prompt <prompt>", "System prompt").option("-m, --model <model>", "Model (claude-sonnet-4-5, claude-opus-4-5, claude-haiku-4-5)").option("--description <desc>", "Agent description").addHelpText("after", `
6792
6832
  Examples:
6793
- ${chalk17.dim("$")} mutagent agents create --name "Code Reviewer" --slug code-reviewer --system-prompt "You are a code reviewer..."
6794
- ${chalk17.dim("$")} mutagent agents create -d '{"name":"Code Reviewer","slug":"code-reviewer","systemPrompt":"You are a code reviewer..."}'
6833
+ ${chalk18.dim("$")} mutagent agents create --name "Code Reviewer" --slug code-reviewer --system-prompt "You are a code reviewer..."
6834
+ ${chalk18.dim("$")} mutagent agents create -d '{"name":"Code Reviewer","slug":"code-reviewer","systemPrompt":"You are a code reviewer..."}'
6795
6835
 
6796
6836
  Expected JSON (--data):
6797
- ${chalk17.dim('{"name":"<name>","slug":"<slug>","systemPrompt":"<system prompt>","model":"<model-id>","description":"<description>"}')}
6837
+ ${chalk18.dim('{"name":"<name>","slug":"<slug>","systemPrompt":"<system prompt>","model":"<model-id>","description":"<description>"}')}
6798
6838
 
6799
6839
  Input Methods (pick one, priority order):
6800
- --name/--slug/... Individual flags ${chalk17.green("(recommended)")}
6840
+ --name/--slug/... Individual flags ${chalk18.green("(recommended)")}
6801
6841
  -d, --data Inline JSON object (CI/scripts/agents)
6802
6842
 
6803
- ${chalk17.red("Required: name, slug, systemPrompt.")} ${chalk17.dim("CLI flags override --data fields.")}
6843
+ ${chalk18.red("Required: name, slug, systemPrompt.")} ${chalk18.dim("CLI flags override --data fields.")}
6804
6844
  `).action(async (options) => {
6805
6845
  const isJson = getJsonFlag(agents);
6806
6846
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6845,15 +6885,15 @@ ${chalk17.red("Required: name, slug, systemPrompt.")} ${chalk17.dim("CLI flags o
6845
6885
  });
6846
6886
  agents.command("update").description("Update an agent").argument("<id>", "Agent ID").option("-d, --data <json>", "Agent updates as JSON string (CI/scripts/agents)").option("-n, --name <name>", "New name").option("-p, --system-prompt <prompt>", "New system prompt").option("-m, --model <model>", "New model").option("--description <desc>", "New description").option("-s, --status <status>", "New status (active, paused, archived)").addHelpText("after", `
6847
6887
  Examples:
6848
- ${chalk17.dim("$")} mutagent agents update <id> --name "New Name"
6849
- ${chalk17.dim("$")} mutagent agents update <id> --system-prompt "Updated prompt" --status active
6850
- ${chalk17.dim("$")} mutagent agents update <id> -d '{"name":"New Name","systemPrompt":"Updated prompt"}'
6888
+ ${chalk18.dim("$")} mutagent agents update <id> --name "New Name"
6889
+ ${chalk18.dim("$")} mutagent agents update <id> --system-prompt "Updated prompt" --status active
6890
+ ${chalk18.dim("$")} mutagent agents update <id> -d '{"name":"New Name","systemPrompt":"Updated prompt"}'
6851
6891
 
6852
6892
  Input Methods (pick one, priority order):
6853
- --name/--system-prompt/... Individual flags ${chalk17.green("(recommended)")}
6893
+ --name/--system-prompt/... Individual flags ${chalk18.green("(recommended)")}
6854
6894
  -d, --data Inline JSON object (CI/scripts/agents)
6855
6895
 
6856
- ${chalk17.dim("CLI flags override --data fields.")}
6896
+ ${chalk18.dim("CLI flags override --data fields.")}
6857
6897
  `).action(async (id, options) => {
6858
6898
  const isJson = getJsonFlag(agents);
6859
6899
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6900,18 +6940,18 @@ ${chalk17.dim("CLI flags override --data fields.")}
6900
6940
  });
6901
6941
  agents.command("delete").description("Delete an agent").argument("<id>", "Agent ID").option("--force", "Skip confirmation").addHelpText("after", `
6902
6942
  Examples:
6903
- ${chalk17.dim("$")} mutagent agents delete <id>
6904
- ${chalk17.dim("$")} mutagent agents delete <id> --force
6905
- ${chalk17.dim("$")} mutagent agents delete <id> --force --json
6943
+ ${chalk18.dim("$")} mutagent agents delete <id>
6944
+ ${chalk18.dim("$")} mutagent agents delete <id> --force
6945
+ ${chalk18.dim("$")} mutagent agents delete <id> --force --json
6906
6946
 
6907
- ${chalk17.dim("Tip: Use --force to skip confirmation (required for non-interactive/CI usage).")}
6947
+ ${chalk18.dim("Tip: Use --force to skip confirmation (required for non-interactive/CI usage).")}
6908
6948
  `).action(async (id, options) => {
6909
6949
  const isJson = getJsonFlag(agents);
6910
6950
  const output = new OutputFormatter(isJson ? "json" : "table");
6911
6951
  try {
6912
6952
  if (!options.force && !isJson) {
6913
- const inquirer3 = (await import("inquirer")).default;
6914
- const answers = await inquirer3.prompt([{
6953
+ const inquirer2 = (await import("inquirer")).default;
6954
+ const answers = await inquirer2.prompt([{
6915
6955
  type: "confirm",
6916
6956
  name: "confirm",
6917
6957
  message: `Delete agent ${id}? This action cannot be undone.`,
@@ -6935,12 +6975,12 @@ ${chalk17.dim("Tip: Use --force to skip confirmation (required for non-interacti
6935
6975
  function createAgentsCommand() {
6936
6976
  const agents = new Command9("agents").description("Manage AI agents").addHelpText("after", `
6937
6977
  Examples:
6938
- ${chalk18.dim("$")} mutagent agents list
6939
- ${chalk18.dim("$")} mutagent agents get <agent-id>
6940
- ${chalk18.dim("$")} mutagent agents create --name "Code Reviewer" --slug code-reviewer --system-prompt "You are a code reviewer..."
6941
- ${chalk18.dim("$")} mutagent agents create -d '{"name":"Code Reviewer","slug":"code-reviewer","systemPrompt":"You are..."}'
6942
- ${chalk18.dim("$")} mutagent agents update <agent-id> --name "Updated Name"
6943
- ${chalk18.dim("$")} mutagent agents delete <agent-id> --force
6978
+ ${chalk19.dim("$")} mutagent agents list
6979
+ ${chalk19.dim("$")} mutagent agents get <agent-id>
6980
+ ${chalk19.dim("$")} mutagent agents create --name "Code Reviewer" --slug code-reviewer --system-prompt "You are a code reviewer..."
6981
+ ${chalk19.dim("$")} mutagent agents create -d '{"name":"Code Reviewer","slug":"code-reviewer","systemPrompt":"You are..."}'
6982
+ ${chalk19.dim("$")} mutagent agents update <agent-id> --name "Updated Name"
6983
+ ${chalk19.dim("$")} mutagent agents delete <agent-id> --force
6944
6984
 
6945
6985
  Subcommands:
6946
6986
  list, get, create, update, delete
@@ -6952,22 +6992,22 @@ Subcommands:
6952
6992
  // src/commands/config.ts
6953
6993
  init_config();
6954
6994
  import { Command as Command10 } from "commander";
6955
- import chalk19 from "chalk";
6995
+ import chalk20 from "chalk";
6956
6996
  init_errors();
6957
6997
  init_sdk_client();
6958
6998
  var VALID_CONFIG_KEYS = ["apiKey", "endpoint", "format", "timeout", "defaultWorkspace", "defaultOrganization"];
6959
6999
  function createConfigCommand() {
6960
7000
  const config = new Command10("config").description("Manage CLI configuration").addHelpText("after", `
6961
7001
  Examples:
6962
- ${chalk19.dim("$")} mutagent config list
6963
- ${chalk19.dim("$")} mutagent config get endpoint
6964
- ${chalk19.dim("$")} mutagent config set workspace <workspace-id>
6965
- ${chalk19.dim("$")} mutagent config set org <org-id>
7002
+ ${chalk20.dim("$")} mutagent config list
7003
+ ${chalk20.dim("$")} mutagent config get endpoint
7004
+ ${chalk20.dim("$")} mutagent config set workspace <workspace-id>
7005
+ ${chalk20.dim("$")} mutagent config set org <org-id>
6966
7006
  `);
6967
7007
  config.command("list").description("List all configuration").addHelpText("after", `
6968
7008
  Examples:
6969
- ${chalk19.dim("$")} mutagent config list
6970
- ${chalk19.dim("$")} mutagent config list --json
7009
+ ${chalk20.dim("$")} mutagent config list
7010
+ ${chalk20.dim("$")} mutagent config list --json
6971
7011
  `).action(() => {
6972
7012
  const isJson = getJsonFlag(config);
6973
7013
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6980,11 +7020,11 @@ Examples:
6980
7020
  });
6981
7021
  config.command("get").description("Get configuration value").argument("<key>", "Configuration key (apiKey, endpoint, format, timeout, defaultWorkspace, defaultOrganization)").addHelpText("after", `
6982
7022
  Examples:
6983
- ${chalk19.dim("$")} mutagent config get endpoint
6984
- ${chalk19.dim("$")} mutagent config get defaultWorkspace
6985
- ${chalk19.dim("$")} mutagent config get apiKey --json
7023
+ ${chalk20.dim("$")} mutagent config get endpoint
7024
+ ${chalk20.dim("$")} mutagent config get defaultWorkspace
7025
+ ${chalk20.dim("$")} mutagent config get apiKey --json
6986
7026
 
6987
- ${chalk19.dim("Keys: apiKey, endpoint, format, timeout, defaultWorkspace, defaultOrganization")}
7027
+ ${chalk20.dim("Keys: apiKey, endpoint, format, timeout, defaultWorkspace, defaultOrganization")}
6988
7028
  `).action((key) => {
6989
7029
  const isJson = getJsonFlag(config);
6990
7030
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7011,9 +7051,9 @@ ${chalk19.dim("Keys: apiKey, endpoint, format, timeout, defaultWorkspace, defaul
7011
7051
  });
7012
7052
  set.command("workspace").description("Set default workspace ID").argument("<id>", "Workspace ID to set as default").addHelpText("after", `
7013
7053
  Examples:
7014
- ${chalk19.dim("$")} mutagent config set workspace <workspace-id>
7054
+ ${chalk20.dim("$")} mutagent config set workspace <workspace-id>
7015
7055
 
7016
- ${chalk19.dim("Persists workspace ID so you don't need to pass headers on every request.")}
7056
+ ${chalk20.dim("Persists workspace ID so you don't need to pass headers on every request.")}
7017
7057
  `).action((id) => {
7018
7058
  const isJson = getJsonFlag(config);
7019
7059
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7027,9 +7067,9 @@ ${chalk19.dim("Persists workspace ID so you don't need to pass headers on every
7027
7067
  });
7028
7068
  set.command("org").description("Set default organization ID").argument("<id>", "Organization ID to set as default").addHelpText("after", `
7029
7069
  Examples:
7030
- ${chalk19.dim("$")} mutagent config set org <org-id>
7070
+ ${chalk20.dim("$")} mutagent config set org <org-id>
7031
7071
 
7032
- ${chalk19.dim("Persists organization ID for org-scoped API keys.")}
7072
+ ${chalk20.dim("Persists organization ID for org-scoped API keys.")}
7033
7073
  `).action((id) => {
7034
7074
  const isJson = getJsonFlag(config);
7035
7075
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7048,7 +7088,7 @@ ${chalk19.dim("Persists organization ID for org-scoped API keys.")}
7048
7088
  // src/commands/playground.ts
7049
7089
  init_sdk_client();
7050
7090
  import { Command as Command11 } from "commander";
7051
- import chalk20 from "chalk";
7091
+ import chalk21 from "chalk";
7052
7092
  init_errors();
7053
7093
  function parseSSELine(line3) {
7054
7094
  if (!line3 || line3.startsWith(":")) {
@@ -7075,11 +7115,11 @@ function parsePromptStreamEvent(data) {
7075
7115
  function createPlaygroundCommand() {
7076
7116
  const playground = new Command11("playground").description("Execute and test prompts interactively").addHelpText("after", `
7077
7117
  Examples:
7078
- ${chalk20.dim("$")} mutagent playground run <prompt-id> --input '{"name": "John"}'
7079
- ${chalk20.dim("$")} mutagent playground run <prompt-id> --input '{}' --stream
7080
- ${chalk20.dim("$")} mutagent playground run <prompt-id> -i '{}' --model gpt-4-turbo
7081
- ${chalk20.dim("$")} mutagent playground run <prompt-id> --system "You are helpful" --human "Hello"
7082
- ${chalk20.dim("$")} mutagent playground run <prompt-id> --messages '[{"role":"user","content":"Hi"}]'
7118
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{"name": "John"}'
7119
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{}' --stream
7120
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> -i '{}' --model gpt-4-turbo
7121
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --system "You are helpful" --human "Hello"
7122
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --messages '[{"role":"user","content":"Hi"}]'
7083
7123
 
7084
7124
  Input Format:
7085
7125
  The input must be a valid JSON object matching the prompt's input schema.
@@ -7095,16 +7135,16 @@ Streaming:
7095
7135
  `);
7096
7136
  playground.command("run").description("Execute a prompt with input variables").argument("<prompt-id>", "Prompt ID to execute (from: mutagent prompts list)").option("-i, --input <json>", "Input variables as JSON").option("-s, --stream", "Stream the response").option("-m, --model <model>", "Override model").option("--system <text>", "Set system prompt text").option("--human <text>", "Set human/user message text").option("--messages <json>", "Pass full messages array as JSON string").addHelpText("after", `
7097
7137
  Examples:
7098
- ${chalk20.dim("$")} mutagent playground run <prompt-id> --input '{"name": "John"}'
7099
- ${chalk20.dim("$")} mutagent playground run <prompt-id> --input '{}' --stream
7100
- ${chalk20.dim("$")} mutagent playground run <prompt-id> --system "You are helpful" --human "Hello"
7101
- ${chalk20.dim("$")} mutagent playground run <prompt-id> --input '{}' --model gpt-4-turbo --json
7138
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{"name": "John"}'
7139
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{}' --stream
7140
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --system "You are helpful" --human "Hello"
7141
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{}' --model gpt-4-turbo --json
7102
7142
 
7103
7143
  Input Methods (pick one, priority order):
7104
- --system/--human Quick system + user message ${chalk20.green("(recommended)")}
7144
+ --system/--human Quick system + user message ${chalk21.green("(recommended)")}
7105
7145
  --input '{"key":"value"}' Inline JSON variables
7106
7146
  --messages '[...]' Full messages array
7107
- ${chalk20.dim(`Hint: Test before evaluating: mutagent playground run <id> --input '{"key":"value"}'`)}
7147
+ ${chalk21.dim(`Hint: Test before evaluating: mutagent playground run <id> --input '{"key":"value"}'`)}
7108
7148
  `).action(async (promptId, options) => {
7109
7149
  const isJson = getJsonFlag(playground);
7110
7150
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7126,21 +7166,21 @@ ${chalk20.dim(`Hint: Test before evaluating: mutagent playground run <id> --inpu
7126
7166
  }
7127
7167
  });
7128
7168
  } else {
7129
- console.log(chalk20.bold(`
7169
+ console.log(chalk21.bold(`
7130
7170
  Execution Result:`));
7131
- console.log(chalk20.gray("─".repeat(50)));
7132
- console.log(chalk20.cyan("Output:"));
7171
+ console.log(chalk21.gray("─".repeat(50)));
7172
+ console.log(chalk21.cyan("Output:"));
7133
7173
  console.log(result.output);
7134
- console.log(chalk20.gray("─".repeat(50)));
7135
- console.log(chalk20.dim(`Model: ${result.model}`));
7136
- console.log(chalk20.dim(`Execution Time: ${String(result.executionTimeMs)}ms`));
7174
+ console.log(chalk21.gray("─".repeat(50)));
7175
+ console.log(chalk21.dim(`Model: ${result.model}`));
7176
+ console.log(chalk21.dim(`Execution Time: ${String(result.executionTimeMs)}ms`));
7137
7177
  if (result.tokens) {
7138
- console.log(chalk20.dim(`Tokens: ${String(result.tokens.prompt)} prompt + ${String(result.tokens.completion)} completion = ${String(result.tokens.total)} total`));
7178
+ console.log(chalk21.dim(`Tokens: ${String(result.tokens.prompt)} prompt + ${String(result.tokens.completion)} completion = ${String(result.tokens.total)} total`));
7139
7179
  }
7140
7180
  if (result.cost !== undefined) {
7141
- console.log(chalk20.dim(`Cost: $${result.cost.toFixed(6)}`));
7181
+ console.log(chalk21.dim(`Cost: $${result.cost.toFixed(6)}`));
7142
7182
  }
7143
- console.log(chalk20.dim(`Playground: ${playgroundLink(promptId)}`));
7183
+ console.log(chalk21.dim(`Playground: ${playgroundLink(promptId)}`));
7144
7184
  console.log();
7145
7185
  }
7146
7186
  }
@@ -7229,9 +7269,9 @@ async function executeStreaming(client, promptId, input, model, isJson, output)
7229
7269
  const decoder = new TextDecoder;
7230
7270
  let buffer = "";
7231
7271
  if (!isJson) {
7232
- console.log(chalk20.bold(`
7272
+ console.log(chalk21.bold(`
7233
7273
  Streaming Output:`));
7234
- console.log(chalk20.gray("─".repeat(50)));
7274
+ console.log(chalk21.gray("─".repeat(50)));
7235
7275
  }
7236
7276
  try {
7237
7277
  for (;; ) {
@@ -7270,15 +7310,15 @@ Streaming Output:`));
7270
7310
  console.log(JSON.stringify({ type: "complete", result: event.result }));
7271
7311
  } else {
7272
7312
  console.log();
7273
- console.log(chalk20.gray("─".repeat(50)));
7313
+ console.log(chalk21.gray("─".repeat(50)));
7274
7314
  if (event.result) {
7275
- console.log(chalk20.dim(`Model: ${event.result.model}`));
7276
- console.log(chalk20.dim(`Execution Time: ${String(event.result.executionTimeMs)}ms`));
7315
+ console.log(chalk21.dim(`Model: ${event.result.model}`));
7316
+ console.log(chalk21.dim(`Execution Time: ${String(event.result.executionTimeMs)}ms`));
7277
7317
  if (event.result.tokens) {
7278
- console.log(chalk20.dim(`Tokens: ${String(event.result.tokens.prompt)} prompt + ${String(event.result.tokens.completion)} completion = ${String(event.result.tokens.total)} total`));
7318
+ console.log(chalk21.dim(`Tokens: ${String(event.result.tokens.prompt)} prompt + ${String(event.result.tokens.completion)} completion = ${String(event.result.tokens.total)} total`));
7279
7319
  }
7280
7320
  if (event.result.cost !== undefined) {
7281
- console.log(chalk20.dim(`Cost: $${event.result.cost.toFixed(6)}`));
7321
+ console.log(chalk21.dim(`Cost: $${event.result.cost.toFixed(6)}`));
7282
7322
  }
7283
7323
  }
7284
7324
  console.log();
@@ -7303,13 +7343,13 @@ Streaming Output:`));
7303
7343
  // src/commands/workspaces.ts
7304
7344
  init_sdk_client();
7305
7345
  import { Command as Command12 } from "commander";
7306
- import chalk21 from "chalk";
7346
+ import chalk22 from "chalk";
7307
7347
  init_errors();
7308
7348
  function createWorkspacesCommand() {
7309
7349
  const workspaces = new Command12("workspaces").description("View workspaces (read-only)").addHelpText("after", `
7310
7350
  Examples:
7311
- ${chalk21.dim("$")} mutagent workspaces list
7312
- ${chalk21.dim("$")} mutagent workspaces get <workspace-id>
7351
+ ${chalk22.dim("$")} mutagent workspaces list
7352
+ ${chalk22.dim("$")} mutagent workspaces get <workspace-id>
7313
7353
 
7314
7354
  Subcommands:
7315
7355
  list, get
@@ -7318,8 +7358,8 @@ Note: Workspace management (create, update, delete) is available in the Admin Pa
7318
7358
  `);
7319
7359
  workspaces.command("list").description("List all workspaces").option("-l, --limit <n>", "Limit results", "50").option("-o, --offset <n>", "Offset for pagination").addHelpText("after", `
7320
7360
  Examples:
7321
- ${chalk21.dim("$")} mutagent workspaces list
7322
- ${chalk21.dim("$")} mutagent workspaces list --limit 10 --json
7361
+ ${chalk22.dim("$")} mutagent workspaces list
7362
+ ${chalk22.dim("$")} mutagent workspaces list --limit 10 --json
7323
7363
  `).action(async (options) => {
7324
7364
  const isJson = getJsonFlag(workspaces);
7325
7365
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7359,8 +7399,8 @@ Examples:
7359
7399
  });
7360
7400
  workspaces.command("get").description("Get workspace details").argument("<id>", "Workspace ID").addHelpText("after", `
7361
7401
  Examples:
7362
- ${chalk21.dim("$")} mutagent workspaces get <workspace-id>
7363
- ${chalk21.dim("$")} mutagent workspaces get <workspace-id> --json
7402
+ ${chalk22.dim("$")} mutagent workspaces get <workspace-id>
7403
+ ${chalk22.dim("$")} mutagent workspaces get <workspace-id> --json
7364
7404
  `).action(async (id) => {
7365
7405
  const isJson = getJsonFlag(workspaces);
7366
7406
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7393,12 +7433,12 @@ Examples:
7393
7433
  // src/commands/providers/index.ts
7394
7434
  init_sdk_client();
7395
7435
  import { Command as Command13 } from "commander";
7396
- import chalk25 from "chalk";
7436
+ import chalk26 from "chalk";
7397
7437
  init_errors();
7398
7438
 
7399
7439
  // src/commands/providers/add.ts
7400
7440
  init_sdk_client();
7401
- import chalk22 from "chalk";
7441
+ import chalk23 from "chalk";
7402
7442
  init_errors();
7403
7443
  function resolveScope(scopeFlag, client) {
7404
7444
  const scope = scopeFlag ?? "workspace";
@@ -7421,10 +7461,10 @@ function resolveScope(scopeFlag, client) {
7421
7461
  function registerAddCommand(parent) {
7422
7462
  parent.command("add").description("Add a new provider configuration").requiredOption("-p, --provider <type>", "Provider type (openai, anthropic, google, ...)").requiredOption("-n, --name <name>", "Display name for this provider").requiredOption("-k, --api-key <key>", "API key for the provider").option("-s, --scope <scope>", "Scope: workspace (default), org, user", "workspace").option("--base-url <url>", "Custom base URL for the provider API").option("--set-default", "Set as default provider for this scope").addHelpText("after", `
7423
7463
  Examples:
7424
- ${chalk22.dim("$")} mutagent providers add --provider openai --name "My OpenAI" --api-key $OPENAI_API_KEY
7425
- ${chalk22.dim("$")} mutagent providers add --provider anthropic --name "Team Claude" --api-key $KEY --scope org
7426
- ${chalk22.dim("$")} mutagent providers add --provider openai --name "Personal" --api-key $KEY --scope user --set-default
7427
- ${chalk22.dim("$")} mutagent providers add --provider custom --name "Ollama" --api-key none --base-url http://localhost:11434 --json
7464
+ ${chalk23.dim("$")} mutagent providers add --provider openai --name "My OpenAI" --api-key $OPENAI_API_KEY
7465
+ ${chalk23.dim("$")} mutagent providers add --provider anthropic --name "Team Claude" --api-key $KEY --scope org
7466
+ ${chalk23.dim("$")} mutagent providers add --provider openai --name "Personal" --api-key $KEY --scope user --set-default
7467
+ ${chalk23.dim("$")} mutagent providers add --provider custom --name "Ollama" --api-key none --base-url http://localhost:11434 --json
7428
7468
 
7429
7469
  Scope Resolution:
7430
7470
  workspace (default) Uses your configured workspace
@@ -7470,10 +7510,10 @@ The API key is encrypted server-side and never returned in plain text.
7470
7510
  console.log(` Scope: ${options.scope ?? "workspace"}`);
7471
7511
  console.log(` URL: ${providerLink(created.id)}`);
7472
7512
  if (options.setDefault) {
7473
- console.log(chalk22.green(" Set as default provider"));
7513
+ console.log(chalk23.green(" Set as default provider"));
7474
7514
  }
7475
7515
  console.log("");
7476
- console.log(chalk22.dim("API key is encrypted server-side. Use `providers get` to see masked key."));
7516
+ console.log(chalk23.dim("API key is encrypted server-side. Use `providers get` to see masked key."));
7477
7517
  }
7478
7518
  } catch (error) {
7479
7519
  handleError(error, isJson);
@@ -7511,15 +7551,15 @@ function buildProviderCreatedDirective(provider, scope) {
7511
7551
 
7512
7552
  // src/commands/providers/update.ts
7513
7553
  init_sdk_client();
7514
- import chalk23 from "chalk";
7554
+ import chalk24 from "chalk";
7515
7555
  init_errors();
7516
7556
  function registerUpdateCommand(parent) {
7517
7557
  parent.command("update").description("Update an existing provider configuration").argument("<id>", "Provider ID (from: mutagent providers list)").option("-n, --name <name>", "Updated display name").option("-k, --api-key <key>", "Updated API key (will be re-encrypted)").option("--active <bool>", "Activate or deactivate (true|false)").option("--set-default", "Set as default provider for its scope").option("--base-url <url>", 'Updated base URL (use "" to clear)').addHelpText("after", `
7518
7558
  Examples:
7519
- ${chalk23.dim("$")} mutagent providers update <id> --name "New Name"
7520
- ${chalk23.dim("$")} mutagent providers update <id> --api-key $NEW_KEY --json
7521
- ${chalk23.dim("$")} mutagent providers update <id> --active false
7522
- ${chalk23.dim("$")} mutagent providers update <id> --set-default --json
7559
+ ${chalk24.dim("$")} mutagent providers update <id> --name "New Name"
7560
+ ${chalk24.dim("$")} mutagent providers update <id> --api-key $NEW_KEY --json
7561
+ ${chalk24.dim("$")} mutagent providers update <id> --active false
7562
+ ${chalk24.dim("$")} mutagent providers update <id> --set-default --json
7523
7563
 
7524
7564
  PATCH semantics — only provided fields are updated.
7525
7565
  `).action(async (id, options) => {
@@ -7570,7 +7610,7 @@ PATCH semantics — only provided fields are updated.
7570
7610
  console.log(` ID: ${String(updated.id ?? id)}`);
7571
7611
  console.log(` URL: ${providerLink(updated.id ?? id)}`);
7572
7612
  if (options.apiKey) {
7573
- console.log(chalk23.dim(" API key re-encrypted server-side."));
7613
+ console.log(chalk24.dim(" API key re-encrypted server-side."));
7574
7614
  }
7575
7615
  }
7576
7616
  } catch (error) {
@@ -7609,17 +7649,17 @@ function buildProviderUpdatedDirective(provider, requestId) {
7609
7649
 
7610
7650
  // src/commands/providers/delete.ts
7611
7651
  init_sdk_client();
7612
- import chalk24 from "chalk";
7652
+ import chalk25 from "chalk";
7613
7653
  init_errors();
7614
7654
  function registerDeleteCommand(parent) {
7615
7655
  parent.command("delete").description("Delete a provider configuration").argument("<id>", "Provider ID (from: mutagent providers list)").option("-f, --force", "Skip confirmation prompt").addHelpText("after", `
7616
7656
  Examples:
7617
- ${chalk24.dim("$")} mutagent providers delete <id>
7618
- ${chalk24.dim("$")} mutagent providers delete <id> --force
7619
- ${chalk24.dim("$")} mutagent providers delete <id> --force --json
7657
+ ${chalk25.dim("$")} mutagent providers delete <id>
7658
+ ${chalk25.dim("$")} mutagent providers delete <id> --force
7659
+ ${chalk25.dim("$")} mutagent providers delete <id> --force --json
7620
7660
 
7621
- ${chalk24.dim("Note: --force is required. The CLI is non-interactive — confirm with the user via your native flow, then pass --force.")}
7622
- ${chalk24.dim("Warning: API keys are AES-256-GCM encrypted and irrecoverable after deletion. Agents referencing this provider will lose their model config.")}
7661
+ ${chalk25.dim("Note: --force is required. The CLI is non-interactive — confirm with the user via your native flow, then pass --force.")}
7662
+ ${chalk25.dim("Warning: API keys are AES-256-GCM encrypted and irrecoverable after deletion. Agents referencing this provider will lose their model config.")}
7623
7663
  `).action(async (id, options) => {
7624
7664
  const isJson = getJsonFlag(parent);
7625
7665
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7709,12 +7749,12 @@ function validateProviderType(type) {
7709
7749
  function createProvidersCommand() {
7710
7750
  const providers = new Command13("providers").description("Manage LLM provider configurations (BYOK)").addHelpText("after", `
7711
7751
  Examples:
7712
- ${chalk25.dim("$")} mutagent providers list
7713
- ${chalk25.dim("$")} mutagent providers get <provider-id>
7714
- ${chalk25.dim("$")} mutagent providers add --provider openai --name "My OpenAI" --api-key $KEY
7715
- ${chalk25.dim("$")} mutagent providers update <id> --name "New Name"
7716
- ${chalk25.dim("$")} mutagent providers delete <id> --force
7717
- ${chalk25.dim("$")} mutagent providers test <provider-id>
7752
+ ${chalk26.dim("$")} mutagent providers list
7753
+ ${chalk26.dim("$")} mutagent providers get <provider-id>
7754
+ ${chalk26.dim("$")} mutagent providers add --provider openai --name "My OpenAI" --api-key $KEY
7755
+ ${chalk26.dim("$")} mutagent providers update <id> --name "New Name"
7756
+ ${chalk26.dim("$")} mutagent providers delete <id> --force
7757
+ ${chalk26.dim("$")} mutagent providers test <provider-id>
7718
7758
 
7719
7759
  Provider Types:
7720
7760
  openai, anthropic, google, azure, bedrock, cohere, mistral, groq, together, replicate, custom
@@ -7724,9 +7764,9 @@ Subcommands:
7724
7764
  `);
7725
7765
  providers.command("list").description("List all providers").option("-l, --limit <n>", "Limit results", "50").option("-o, --offset <n>", "Offset for pagination").option("-t, --type <type>", "Filter by provider type").addHelpText("after", `
7726
7766
  Examples:
7727
- ${chalk25.dim("$")} mutagent providers list
7728
- ${chalk25.dim("$")} mutagent providers list --type openai
7729
- ${chalk25.dim("$")} mutagent providers list --json
7767
+ ${chalk26.dim("$")} mutagent providers list
7768
+ ${chalk26.dim("$")} mutagent providers list --type openai
7769
+ ${chalk26.dim("$")} mutagent providers list --json
7730
7770
  `).action(async (options) => {
7731
7771
  const isJson = getJsonFlag(providers);
7732
7772
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7775,8 +7815,8 @@ Examples:
7775
7815
  });
7776
7816
  providers.command("get").description("Get provider details").argument("<id>", "Provider ID (from: mutagent providers list)").addHelpText("after", `
7777
7817
  Examples:
7778
- ${chalk25.dim("$")} mutagent providers get <provider-id>
7779
- ${chalk25.dim("$")} mutagent providers get <provider-id> --json
7818
+ ${chalk26.dim("$")} mutagent providers get <provider-id>
7819
+ ${chalk26.dim("$")} mutagent providers get <provider-id> --json
7780
7820
  `).action(async (id) => {
7781
7821
  const isJson = getJsonFlag(providers);
7782
7822
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7805,10 +7845,10 @@ Examples:
7805
7845
  });
7806
7846
  providers.command("test").description("Test provider connectivity").argument("<id>", "Provider ID (from: mutagent providers list)").addHelpText("after", `
7807
7847
  Examples:
7808
- ${chalk25.dim("$")} mutagent providers test <provider-id>
7809
- ${chalk25.dim("$")} mutagent providers test <provider-id> --json
7848
+ ${chalk26.dim("$")} mutagent providers test <provider-id>
7849
+ ${chalk26.dim("$")} mutagent providers test <provider-id> --json
7810
7850
 
7811
- ${chalk25.dim("Tests connectivity and lists available models for the provider.")}
7851
+ ${chalk26.dim("Tests connectivity and lists available models for the provider.")}
7812
7852
  `).action(async (id) => {
7813
7853
  const isJson = getJsonFlag(providers);
7814
7854
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7823,9 +7863,9 @@ ${chalk25.dim("Tests connectivity and lists available models for the provider.")
7823
7863
  } else {
7824
7864
  if (result.success) {
7825
7865
  output.success(`Provider test passed (${String(result.responseTimeMs)}ms)`);
7826
- console.log(chalk25.green(`Message: ${result.message}`));
7866
+ console.log(chalk26.green(`Message: ${result.message}`));
7827
7867
  if (result.availableModels && result.availableModels.length > 0) {
7828
- console.log(chalk25.bold(`
7868
+ console.log(chalk26.bold(`
7829
7869
  Available Models:`));
7830
7870
  result.availableModels.forEach((model) => {
7831
7871
  console.log(` - ${model}`);
@@ -7834,7 +7874,7 @@ Available Models:`));
7834
7874
  } else {
7835
7875
  output.error(`Provider test failed: ${result.message}`);
7836
7876
  if (result.error) {
7837
- console.log(chalk25.red(`Error: ${result.error}`));
7877
+ console.log(chalk26.red(`Error: ${result.error}`));
7838
7878
  }
7839
7879
  }
7840
7880
  }
@@ -7851,8 +7891,8 @@ Available Models:`));
7851
7891
  // src/commands/init.ts
7852
7892
  init_config();
7853
7893
  import { Command as Command14 } from "commander";
7854
- import inquirer3 from "inquirer";
7855
- import chalk26 from "chalk";
7894
+ import inquirer2 from "inquirer";
7895
+ import chalk27 from "chalk";
7856
7896
  import { existsSync as existsSync11, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
7857
7897
  import { execSync as execSync3 } from "child_process";
7858
7898
  import { join as join6 } from "path";
@@ -7975,13 +8015,13 @@ function writeRcConfig(config, cwd = process.cwd()) {
7975
8015
  function createInitCommand() {
7976
8016
  const init = new Command14("init").description("Initialize MutagenT in your project").option("--non-interactive", "Skip interactive prompts (defaults to CLI-only mode)").addHelpText("after", `
7977
8017
  Examples:
7978
- ${chalk26.dim("$")} mutagent init # Interactive setup wizard
7979
- ${chalk26.dim("$")} mutagent init --non-interactive # CLI-only mode (no prompts)
8018
+ ${chalk27.dim("$")} mutagent init # Interactive setup wizard
8019
+ ${chalk27.dim("$")} mutagent init --non-interactive # CLI-only mode (no prompts)
7980
8020
 
7981
8021
  Modes:
7982
- ${chalk26.bold("Full scaffold")} Install SDK + integration package, create config, setup tracing
7983
- ${chalk26.bold("CLI-only")} Verify auth + create .mutagentrc.json with workspace/endpoint
7984
- ${chalk26.bold("Skip")} Exit without changes
8022
+ ${chalk27.bold("Full scaffold")} Install SDK + integration package, create config, setup tracing
8023
+ ${chalk27.bold("CLI-only")} Verify auth + create .mutagentrc.json with workspace/endpoint
8024
+ ${chalk27.bold("Skip")} Exit without changes
7985
8025
  `).action(async (options) => {
7986
8026
  const isJson = getJsonFlag(init);
7987
8027
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7994,7 +8034,7 @@ Modes:
7994
8034
  output.info("Use --force to overwrite (not yet supported). Exiting.");
7995
8035
  return;
7996
8036
  }
7997
- const { overwrite } = await inquirer3.prompt([{
8037
+ const { overwrite } = await inquirer2.prompt([{
7998
8038
  type: "confirm",
7999
8039
  name: "overwrite",
8000
8040
  message: ".mutagentrc.json already exists. Overwrite?",
@@ -8012,7 +8052,7 @@ Modes:
8012
8052
  if (isNonInteractive) {
8013
8053
  throw new MutagentError("AUTH_REQUIRED", "Authentication required before init", "Run: mutagent auth login --browser");
8014
8054
  }
8015
- const { doAuth } = await inquirer3.prompt([{
8055
+ const { doAuth } = await inquirer2.prompt([{
8016
8056
  type: "confirm",
8017
8057
  name: "doAuth",
8018
8058
  message: "Would you like to authenticate now?",
@@ -8038,7 +8078,7 @@ Modes:
8038
8078
  } else {
8039
8079
  if (detectedFramework) {
8040
8080
  output.info(`Detected framework: ${detectedFramework.displayName} (${detectedFramework.npmPackage})`);
8041
- const { confirmFramework } = await inquirer3.prompt([{
8081
+ const { confirmFramework } = await inquirer2.prompt([{
8042
8082
  type: "confirm",
8043
8083
  name: "confirmFramework",
8044
8084
  message: `Use ${detectedFramework.displayName}?`,
@@ -8054,7 +8094,7 @@ Modes:
8054
8094
  { name: "Generic (OpenAI-compatible)", value: "generic" },
8055
8095
  { name: "None / Skip framework", value: "none" }
8056
8096
  ];
8057
- const { selectedFramework } = await inquirer3.prompt([{
8097
+ const { selectedFramework } = await inquirer2.prompt([{
8058
8098
  type: "list",
8059
8099
  name: "selectedFramework",
8060
8100
  message: "Select your AI framework:",
@@ -8084,7 +8124,7 @@ Modes:
8084
8124
  value: "skip"
8085
8125
  }
8086
8126
  ];
8087
- const { selectedMode } = await inquirer3.prompt([{
8127
+ const { selectedMode } = await inquirer2.prompt([{
8088
8128
  type: "list",
8089
8129
  name: "selectedMode",
8090
8130
  message: "How would you like to initialize MutagenT?",
@@ -8187,7 +8227,7 @@ Modes:
8187
8227
  const skillPath = join6(cwd, ".claude/skills/mutagent-cli/SKILL.md");
8188
8228
  const skillInstalled = existsSync11(skillPath);
8189
8229
  if (!isNonInteractive && !skillInstalled) {
8190
- const { installSkill } = await inquirer3.prompt([{
8230
+ const { installSkill } = await inquirer2.prompt([{
8191
8231
  type: "confirm",
8192
8232
  name: "installSkill",
8193
8233
  message: "Install MutagenT skill for Claude Code? (Teaches AI agents how to use the CLI)",
@@ -8253,23 +8293,23 @@ Modes:
8253
8293
 
8254
8294
  // src/commands/explore.ts
8255
8295
  import { Command as Command15 } from "commander";
8256
- import chalk27 from "chalk";
8296
+ import chalk28 from "chalk";
8257
8297
  import { resolve as resolve3 } from "path";
8258
8298
  init_errors();
8259
8299
  function createExploreCommand() {
8260
8300
  const explore = new Command15("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", `
8261
8301
  Examples:
8262
- ${chalk27.dim("$")} mutagent explore
8263
- ${chalk27.dim("$")} mutagent explore --path ./src
8264
- ${chalk27.dim("$")} mutagent explore --include "**/*.{ts,py}" --depth 5
8265
- ${chalk27.dim("$")} mutagent explore --markers-only
8266
- ${chalk27.dim("$")} mutagent explore --json
8302
+ ${chalk28.dim("$")} mutagent explore
8303
+ ${chalk28.dim("$")} mutagent explore --path ./src
8304
+ ${chalk28.dim("$")} mutagent explore --include "**/*.{ts,py}" --depth 5
8305
+ ${chalk28.dim("$")} mutagent explore --markers-only
8306
+ ${chalk28.dim("$")} mutagent explore --json
8267
8307
 
8268
8308
  Detection modes:
8269
- ${chalk27.dim("Heuristic")} Template variables ({{var}}), prompt constants, schema definitions
8270
- ${chalk27.dim("Marker")} MutagenT:START/END comment markers from previous uploads
8309
+ ${chalk28.dim("Heuristic")} Template variables ({{var}}), prompt constants, schema definitions
8310
+ ${chalk28.dim("Marker")} MutagenT:START/END comment markers from previous uploads
8271
8311
 
8272
- ${chalk27.dim("Results are saved to .mutagent/mutation-context.md for use by other commands.")}
8312
+ ${chalk28.dim("Results are saved to .mutagent/mutation-context.md for use by other commands.")}
8273
8313
  `).action((options) => {
8274
8314
  const isJson = getJsonFlag(explore);
8275
8315
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -8287,7 +8327,7 @@ ${chalk27.dim("Results are saved to .mutagent/mutation-context.md for use by oth
8287
8327
  markersOnly
8288
8328
  };
8289
8329
  if (!isJson) {
8290
- console.log(chalk27.cyan(`
8330
+ console.log(chalk28.cyan(`
8291
8331
  Scanning ${scanPath}...
8292
8332
  `));
8293
8333
  }
@@ -8316,41 +8356,41 @@ Scanning ${scanPath}...
8316
8356
  const totalFindings = result.prompts.length + result.datasets.length + result.markers.length;
8317
8357
  if (totalFindings === 0) {
8318
8358
  output.info("No prompts, datasets, or markers found.");
8319
- console.log(chalk27.dim(`
8359
+ console.log(chalk28.dim(`
8320
8360
  Tip: Create a prompt with template variables like {{input}} to get started.`));
8321
8361
  return;
8322
8362
  }
8323
8363
  if (result.prompts.length > 0) {
8324
- console.log(chalk27.bold(` Prompts Found (${String(result.prompts.length)}):`));
8364
+ console.log(chalk28.bold(` Prompts Found (${String(result.prompts.length)}):`));
8325
8365
  console.log();
8326
8366
  for (const p of result.prompts) {
8327
- const confidenceTag = p.confidence === "high" ? chalk27.green("[high]") : p.confidence === "medium" ? chalk27.yellow("[medium]") : chalk27.dim("[low]");
8328
- const reasonTag = chalk27.dim(`[${p.reason}]`);
8329
- console.log(` ${confidenceTag} ${chalk27.green(p.file)}:${chalk27.yellow(String(p.line))} ${reasonTag}`);
8330
- console.log(` ${chalk27.dim(p.preview)}`);
8367
+ const confidenceTag = p.confidence === "high" ? chalk28.green("[high]") : p.confidence === "medium" ? chalk28.yellow("[medium]") : chalk28.dim("[low]");
8368
+ const reasonTag = chalk28.dim(`[${p.reason}]`);
8369
+ console.log(` ${confidenceTag} ${chalk28.green(p.file)}:${chalk28.yellow(String(p.line))} ${reasonTag}`);
8370
+ console.log(` ${chalk28.dim(p.preview)}`);
8331
8371
  }
8332
8372
  console.log();
8333
8373
  }
8334
8374
  if (result.datasets.length > 0) {
8335
- console.log(chalk27.bold(` Datasets Found (${String(result.datasets.length)}):`));
8375
+ console.log(chalk28.bold(` Datasets Found (${String(result.datasets.length)}):`));
8336
8376
  console.log();
8337
8377
  for (const d of result.datasets) {
8338
- console.log(` ${chalk27.green(d.file)} ${chalk27.dim(`(${String(d.items)} items)`)}`);
8378
+ console.log(` ${chalk28.green(d.file)} ${chalk28.dim(`(${String(d.items)} items)`)}`);
8339
8379
  }
8340
8380
  console.log();
8341
8381
  }
8342
8382
  if (result.markers.length > 0) {
8343
- console.log(chalk27.bold(` MutagenT Markers (${String(result.markers.length)}):`));
8383
+ console.log(chalk28.bold(` MutagenT Markers (${String(result.markers.length)}):`));
8344
8384
  console.log();
8345
8385
  for (const m of result.markers) {
8346
- const idPart = m.platformId ? chalk27.cyan(` id=${m.platformId}`) : "";
8347
- console.log(` ${chalk27.green(m.file)}:${chalk27.yellow(String(m.line))} ${chalk27.magenta(m.type)}${idPart}`);
8386
+ const idPart = m.platformId ? chalk28.cyan(` id=${m.platformId}`) : "";
8387
+ console.log(` ${chalk28.green(m.file)}:${chalk28.yellow(String(m.line))} ${chalk28.magenta(m.type)}${idPart}`);
8348
8388
  }
8349
8389
  console.log();
8350
8390
  }
8351
- console.log(chalk27.dim(" ─────────────────────────────────"));
8352
- console.log(` ${chalk27.bold("Summary:")} ${String(result.prompts.length)} prompts, ${String(result.datasets.length)} datasets, ${String(result.markers.length)} markers`);
8353
- console.log(chalk27.dim(` Saved to .mutagent/mutation-context.md`));
8391
+ console.log(chalk28.dim(" ─────────────────────────────────"));
8392
+ console.log(` ${chalk28.bold("Summary:")} ${String(result.prompts.length)} prompts, ${String(result.datasets.length)} datasets, ${String(result.markers.length)} markers`);
8393
+ console.log(chalk28.dim(` Saved to .mutagent/mutation-context.md`));
8354
8394
  console.log();
8355
8395
  }
8356
8396
  } catch (error) {
@@ -8362,7 +8402,7 @@ Scanning ${scanPath}...
8362
8402
 
8363
8403
  // src/commands/skills.ts
8364
8404
  import { Command as Command16 } from "commander";
8365
- import chalk28 from "chalk";
8405
+ import chalk29 from "chalk";
8366
8406
  import { existsSync as existsSync12, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
8367
8407
  import { join as join7 } from "path";
8368
8408
  import { execSync as execSync4 } from "child_process";
@@ -8486,7 +8526,7 @@ function createSkillsCommand() {
8486
8526
  const skills = new Command16("skills").description("Manage MutagenT CLI skills for coding agents");
8487
8527
  skills.command("install").description("Install MutagenT CLI skill for Claude Code").addHelpText("after", `
8488
8528
  Examples:
8489
- ${chalk28.dim("$")} mutagent skills install
8529
+ ${chalk29.dim("$")} mutagent skills install
8490
8530
 
8491
8531
  This creates a Claude Code skill at .claude/skills/mutagent-cli/SKILL.md
8492
8532
  that teaches coding agents how to use the MutagenT CLI effectively.
@@ -8513,10 +8553,10 @@ ${SKILL_BODY}
8513
8553
  });
8514
8554
  } else {
8515
8555
  output.success(`Installed MutagenT CLI skill`);
8516
- console.log(` ${chalk28.dim("Path:")} ${skillPath}`);
8556
+ console.log(` ${chalk29.dim("Path:")} ${skillPath}`);
8517
8557
  console.log("");
8518
- console.log(` ${chalk28.dim("This skill teaches coding agents how to use the MutagenT CLI.")}`);
8519
- console.log(` ${chalk28.dim("It will be automatically loaded by Claude Code when relevant triggers match.")}`);
8558
+ console.log(` ${chalk29.dim("This skill teaches coding agents how to use the MutagenT CLI.")}`);
8559
+ console.log(` ${chalk29.dim("It will be automatically loaded by Claude Code when relevant triggers match.")}`);
8520
8560
  }
8521
8561
  });
8522
8562
  return skills;
@@ -8525,7 +8565,7 @@ ${SKILL_BODY}
8525
8565
  // src/commands/usage.ts
8526
8566
  init_config();
8527
8567
  import { Command as Command17 } from "commander";
8528
- import chalk29 from "chalk";
8568
+ import chalk30 from "chalk";
8529
8569
  init_errors();
8530
8570
  init_sdk_client();
8531
8571
  var TRIAL_OPTIMIZATION_LIMIT = 5;
@@ -8541,8 +8581,8 @@ function renderProgressBar(used, limit, width = 30) {
8541
8581
  function createUsageCommand() {
8542
8582
  const usage = new Command17("usage").description("Show resource counts and optimization run limits").addHelpText("after", `
8543
8583
  Examples:
8544
- ${chalk29.dim("$")} mutagent usage
8545
- ${chalk29.dim("$")} mutagent usage --json
8584
+ ${chalk30.dim("$")} mutagent usage
8585
+ ${chalk30.dim("$")} mutagent usage --json
8546
8586
  `);
8547
8587
  usage.action(async () => {
8548
8588
  const isJson = getJsonFlag(usage);
@@ -8597,21 +8637,21 @@ Examples:
8597
8637
  });
8598
8638
  } else {
8599
8639
  console.log("");
8600
- console.log(chalk29.bold("\uD83D\uDCCA MutagenT Usage"));
8601
- console.log(chalk29.dim("─".repeat(45)));
8640
+ console.log(chalk30.bold("\uD83D\uDCCA MutagenT Usage"));
8641
+ console.log(chalk30.dim("─".repeat(45)));
8602
8642
  console.log("");
8603
- console.log(chalk29.bold("Resources:"));
8604
- console.log(` Prompts: ${chalk29.cyan(String(promptCount))}`);
8605
- console.log(` Datasets: ${chalk29.cyan(String(datasetCount))}`);
8606
- console.log(` Evaluations: ${chalk29.cyan(String(evaluationCount))}`);
8643
+ console.log(chalk30.bold("Resources:"));
8644
+ console.log(` Prompts: ${chalk30.cyan(String(promptCount))}`);
8645
+ console.log(` Datasets: ${chalk30.cyan(String(datasetCount))}`);
8646
+ console.log(` Evaluations: ${chalk30.cyan(String(evaluationCount))}`);
8607
8647
  console.log("");
8608
- console.log(chalk29.bold(`Optimization Runs (${chalk29.yellow("trial")} plan):`));
8609
- console.log(` Remaining: ${chalk29.cyan(String(optimizationRemaining))} / ${String(optimizationLimit)}`);
8648
+ console.log(chalk30.bold(`Optimization Runs (${chalk30.yellow("trial")} plan):`));
8649
+ console.log(` Remaining: ${chalk30.cyan(String(optimizationRemaining))} / ${String(optimizationLimit)}`);
8610
8650
  console.log(` ${renderProgressBar(optimizationUsed, optimizationLimit)}`);
8611
8651
  console.log("");
8612
- console.log(chalk29.yellow(` ⚠ ${String(optimizationRemaining)} optimization runs remaining`));
8613
- console.log(chalk29.dim(` ℹ Optimization run counts are approximate`));
8614
- console.log(` Upgrade: ${chalk29.underline(BILLING_URL)}`);
8652
+ console.log(chalk30.yellow(` ⚠ ${String(optimizationRemaining)} optimization runs remaining`));
8653
+ console.log(chalk30.dim(` ℹ Optimization run counts are approximate`));
8654
+ console.log(` Upgrade: ${chalk30.underline(BILLING_URL)}`);
8615
8655
  console.log("");
8616
8656
  }
8617
8657
  } catch (error) {
@@ -8899,7 +8939,7 @@ Claude Code Session Telemetry:
8899
8939
 
8900
8940
  // src/commands/feedback.ts
8901
8941
  import { Command as Command19 } from "commander";
8902
- import chalk30 from "chalk";
8942
+ import chalk31 from "chalk";
8903
8943
  init_errors();
8904
8944
  init_config();
8905
8945
  import { readFileSync as readFileSync11 } from "fs";
@@ -8953,12 +8993,12 @@ async function postToServer(payload, endpoint, apiKey, workspaceId, organization
8953
8993
  }
8954
8994
  function createFeedbackCommand() {
8955
8995
  const feedback = new Command19("feedback").description("Send product feedback to MutagenT").addHelpText("after", `
8956
- ${chalk30.bold("Examples:")}
8957
- ${chalk30.cyan('mutagent feedback send -m "Great optimization results!"')}
8958
- ${chalk30.cyan('mutagent feedback send -m "CLI crashed on export" --category bug')}
8959
- ${chalk30.cyan('mutagent feedback send -m "Need batch operations" --category feature --json')}
8996
+ ${chalk31.bold("Examples:")}
8997
+ ${chalk31.cyan('mutagent feedback send -m "Great optimization results!"')}
8998
+ ${chalk31.cyan('mutagent feedback send -m "CLI crashed on export" --category bug')}
8999
+ ${chalk31.cyan('mutagent feedback send -m "Need batch operations" --category feature --json')}
8960
9000
 
8961
- ${chalk30.yellow("AI Agent (MANDATORY):")}
9001
+ ${chalk31.yellow("AI Agent (MANDATORY):")}
8962
9002
  ALWAYS use --json: mutagent feedback send -m "..." --category improvement --json
8963
9003
  Use this command to report bugs, request features, or share UX feedback.
8964
9004
  `).action(() => {
@@ -8969,18 +9009,18 @@ ${chalk30.yellow("AI Agent (MANDATORY):")}
8969
9009
  }
8970
9010
  function registerFeedbackSend(feedback) {
8971
9011
  feedback.command("send").description("Send feedback about the MutagenT platform").requiredOption("-m, --message <text>", "Feedback message").option("--category <type>", `Feedback category: ${VALID_CATEGORIES.join(", ")}`, "improvement").option("--session <id>", "Link feedback to a specific session").addHelpText("after", `
8972
- ${chalk30.bold("Examples:")}
8973
- ${chalk30.dim("$")} mutagent feedback send -m "The optimization UX could show progress better"
8974
- ${chalk30.dim("$")} mutagent feedback send -m "CLI errored on traces export" --category bug
8975
- ${chalk30.dim("$")} mutagent feedback send -m "Love the guided eval!" --category praise --json
8976
-
8977
- ${chalk30.bold("Categories:")}
8978
- ${chalk30.bold("bug")} Something is broken or not working as expected
8979
- ${chalk30.bold("feature")} Request a new capability
8980
- ${chalk30.bold("improvement")} Suggest a UX or workflow enhancement (default)
8981
- ${chalk30.bold("praise")} Share what you love about the platform
8982
-
8983
- ${chalk30.yellow("AI Agent (MANDATORY):")}
9012
+ ${chalk31.bold("Examples:")}
9013
+ ${chalk31.dim("$")} mutagent feedback send -m "The optimization UX could show progress better"
9014
+ ${chalk31.dim("$")} mutagent feedback send -m "CLI errored on traces export" --category bug
9015
+ ${chalk31.dim("$")} mutagent feedback send -m "Love the guided eval!" --category praise --json
9016
+
9017
+ ${chalk31.bold("Categories:")}
9018
+ ${chalk31.bold("bug")} Something is broken or not working as expected
9019
+ ${chalk31.bold("feature")} Request a new capability
9020
+ ${chalk31.bold("improvement")} Suggest a UX or workflow enhancement (default)
9021
+ ${chalk31.bold("praise")} Share what you love about the platform
9022
+
9023
+ ${chalk31.yellow("AI Agent (MANDATORY):")}
8984
9024
  ALWAYS use --json: mutagent feedback send -m "..." --json
8985
9025
  Auto-captured context (CLI version, platform, node version) is included automatically.
8986
9026
  `).action(async (options) => {
@@ -9052,103 +9092,109 @@ program.name("mutagent").description(`MutagenT CLI - AI-native prompt optimizati
9052
9092
  showGlobalOptions: true
9053
9093
  });
9054
9094
  program.addHelpText("after", `
9055
- ${chalk31.yellow("Non-Interactive Mode (CI/CD & Coding Agents):")}
9056
- export MUTAGENT_API_KEY=mt_... ${chalk31.dim("or")} --api-key mt_...
9057
- --json ${chalk31.dim("for structured output")} --non-interactive ${chalk31.dim("to disable prompts")}
9058
-
9059
- ${chalk31.yellow("Command Navigation:")}
9060
- mutagent auth login --browser ${chalk31.dim("Authenticate (OAuth)")}
9061
- mutagent auth status ${chalk31.dim("Check auth + workspace")}
9062
- mutagent init ${chalk31.dim("Initialize project (.mutagentrc.json)")}
9063
- mutagent explore ${chalk31.dim("Discover prompts in codebase")}
9064
- mutagent workspaces list --json ${chalk31.dim("List workspaces (verify ID)")}
9065
- mutagent config set workspace <id> ${chalk31.dim("Set active workspace")}
9066
- mutagent usage --json ${chalk31.dim("Check plan limits")}
9067
-
9068
- mutagent prompts create --help ${chalk31.dim("Upload prompt (read help first!)")}
9069
- mutagent prompts list --json ${chalk31.dim("List prompts")}
9070
- mutagent prompts get <id> --json ${chalk31.dim("Full prompt details + schemas")}
9071
-
9072
- mutagent prompts dataset add --help ${chalk31.dim("Upload dataset (read help first!)")}
9073
- mutagent prompts dataset list <id> ${chalk31.dim("List datasets")}
9074
-
9075
- mutagent prompts evaluation create --help ${chalk31.dim("Create eval (read help first!)")}
9076
- mutagent prompts evaluation create <id> --guided --json ${chalk31.dim("Guided eval workflow")}
9077
- mutagent prompts evaluation list <id> --json ${chalk31.dim("List evaluations")}
9078
-
9079
- mutagent prompts optimize start --help ${chalk31.dim("Run optimization (read help first!)")}
9080
- mutagent prompts optimize status <job-id> ${chalk31.dim("Poll progress")}
9081
- mutagent prompts optimize results <job-id> ${chalk31.dim("View scorecard")}
9082
-
9083
- mutagent feedback send -m "..." ${chalk31.dim("Send product feedback")}
9084
- mutagent feedback send -m "..." --category bug ${chalk31.dim("Report a bug")}
9085
-
9086
- mutagent integrate <framework> ${chalk31.dim("Framework integration guide")}
9087
- mutagent hooks --help ${chalk31.dim("Hook setup for Claude Code telemetry")}
9088
- mutagent playground run <id> --input '{...}' ${chalk31.dim("Quick test")}
9089
-
9090
- ${chalk31.yellow("★ Workflow: Framework Integration (Tracing):")}
9091
- 1. mutagent explore ${chalk31.dim("← discover prompts/agents in codebase")}
9092
- 2. mutagent integrate <framework> ${chalk31.dim("← get integration instructions")}
9093
- 3. Apply tracing code to your codebase ${chalk31.dim("← follow the guide output")}
9094
- 4. mutagent traces list --json ${chalk31.dim("← verify traces are arriving")}
9095
-
9096
- ${chalk31.yellow("★ Workflow: Evaluate → Optimize:")}
9097
- 1. mutagent prompts create --help ${chalk31.dim("← read help")}
9098
- 2. mutagent prompts create ... --json ${chalk31.dim("← upload prompt with {variables} + inputSchema")}
9099
- 3. mutagent prompts dataset add --help ${chalk31.dim("← read help")}
9100
- 4. mutagent prompts dataset add <id> ... --json ${chalk31.dim("← upload dataset")}
9101
- 5. mutagent prompts evaluation create <id> --guided --json ${chalk31.dim("← guided eval")}
9095
+ ${chalk32.yellow("Non-Interactive Mode (CI/CD & Coding Agents):")}
9096
+ export MUTAGENT_API_KEY=mt_... ${chalk32.dim("or")} --api-key mt_...
9097
+ --json ${chalk32.dim("for structured output")} --non-interactive ${chalk32.dim("to disable prompts")}
9098
+
9099
+ ${chalk32.yellow("Command Navigation:")}
9100
+ mutagent login ${chalk32.dim("Login (browser OAuth — recommended)")}
9101
+ mutagent auth status ${chalk32.dim("Check auth + workspace")}
9102
+ mutagent init ${chalk32.dim("Initialize project (.mutagentrc.json)")}
9103
+ mutagent explore ${chalk32.dim("Discover prompts in codebase")}
9104
+ mutagent workspaces list --json ${chalk32.dim("List workspaces (verify ID)")}
9105
+ mutagent config set workspace <id> ${chalk32.dim("Set active workspace")}
9106
+ mutagent usage --json ${chalk32.dim("Check plan limits")}
9107
+
9108
+ mutagent prompts create --help ${chalk32.dim("Upload prompt (read help first!)")}
9109
+ mutagent prompts list --json ${chalk32.dim("List prompts")}
9110
+ mutagent prompts get <id> --json ${chalk32.dim("Full prompt details + schemas")}
9111
+
9112
+ mutagent prompts dataset add --help ${chalk32.dim("Upload dataset (read help first!)")}
9113
+ mutagent prompts dataset list <id> ${chalk32.dim("List datasets")}
9114
+
9115
+ mutagent prompts evaluation create --help ${chalk32.dim("Create eval (read help first!)")}
9116
+ mutagent prompts evaluation create <id> --guided --json ${chalk32.dim("Guided eval workflow")}
9117
+ mutagent prompts evaluation list <id> --json ${chalk32.dim("List evaluations")}
9118
+
9119
+ mutagent prompts optimize start --help ${chalk32.dim("Run optimization (read help first!)")}
9120
+ mutagent prompts optimize status <job-id> ${chalk32.dim("Poll progress")}
9121
+ mutagent prompts optimize results <job-id> ${chalk32.dim("View scorecard")}
9122
+
9123
+ mutagent feedback send -m "..." ${chalk32.dim("Send product feedback")}
9124
+ mutagent feedback send -m "..." --category bug ${chalk32.dim("Report a bug")}
9125
+
9126
+ mutagent integrate <framework> ${chalk32.dim("Framework integration guide")}
9127
+ mutagent hooks --help ${chalk32.dim("Hook setup for Claude Code telemetry")}
9128
+ mutagent playground run <id> --input '{...}' ${chalk32.dim("Quick test")}
9129
+
9130
+ ${chalk32.yellow("★ Workflow: Framework Integration (Tracing):")}
9131
+ 1. mutagent explore ${chalk32.dim("← discover prompts/agents in codebase")}
9132
+ 2. mutagent integrate <framework> ${chalk32.dim("← get integration instructions")}
9133
+ 3. Apply tracing code to your codebase ${chalk32.dim("← follow the guide output")}
9134
+ 4. mutagent traces list --json ${chalk32.dim("← verify traces are arriving")}
9135
+
9136
+ ${chalk32.yellow("★ Workflow: Evaluate → Optimize:")}
9137
+ 1. mutagent prompts create --help ${chalk32.dim("← read help")}
9138
+ 2. mutagent prompts create ... --json ${chalk32.dim("← upload prompt with {variables} + inputSchema")}
9139
+ 3. mutagent prompts dataset add --help ${chalk32.dim("← read help")}
9140
+ 4. mutagent prompts dataset add <id> ... --json ${chalk32.dim("← upload dataset")}
9141
+ 5. mutagent prompts evaluation create <id> --guided --json ${chalk32.dim("← guided eval")}
9102
9142
  6. mutagent prompts optimize start <id> --dataset <d> --evaluation <e> --json
9103
9143
 
9104
- ${chalk31.yellow("Post-Onboarding Decision Tree:")}
9105
- After ${chalk31.bold("mutagent auth login")}, users land in one of 3 paths:
9106
- ${chalk31.bold("Path A")} (Tracing): explore → integrate <framework> → apply tracing → verify
9107
- ${chalk31.bold("Path B")} (Optimization): explore → prompts create → dataset add → eval create → optimize
9108
- ${chalk31.bold("Path C")} (Manual): Use CLI commands directly — run mutagent <command> --help
9144
+ ${chalk32.yellow("Post-Onboarding Decision Tree:")}
9145
+ After ${chalk32.bold("mutagent auth login")}, users land in one of 3 paths:
9146
+ ${chalk32.bold("Path A")} (Tracing): explore → integrate <framework> → apply tracing → verify
9147
+ ${chalk32.bold("Path B")} (Optimization): explore → prompts create → dataset add → eval create → optimize
9148
+ ${chalk32.bold("Path C")} (Manual): Use CLI commands directly — run mutagent <command> --help
9109
9149
 
9110
- ${chalk31.yellow("Directive System:")}
9150
+ ${chalk32.yellow("Directive System:")}
9111
9151
  Every --json response may include:
9112
- ${chalk31.bold("_directive.renderedCard")} Pre-formatted card for the user ${chalk31.red("(MUST be shown in chat)")}
9113
- ${chalk31.bold("_directive.instruction")} Next step for the agent
9114
- ${chalk31.bold("_directive.next")} Array of suggested follow-up commands
9115
- ${chalk31.bold("_links")} Dashboard/API URLs (format as markdown links)
9152
+ ${chalk32.bold("_directive.renderedCard")} Pre-formatted card for the user ${chalk32.red("(MUST be shown in chat)")}
9153
+ ${chalk32.bold("_directive.instruction")} Next step for the agent
9154
+ ${chalk32.bold("_directive.next")} Array of suggested follow-up commands
9155
+ ${chalk32.bold("_links")} Dashboard/API URLs (format as markdown links)
9116
9156
 
9117
- ${chalk31.yellow("Evaluation Criteria Format:")}
9118
- Each criterion MUST have: ${chalk31.bold("name")}, ${chalk31.bold("description")} (scoring rubric), ${chalk31.bold("evaluationParameter")}
9157
+ ${chalk32.yellow("Evaluation Criteria Format:")}
9158
+ Each criterion MUST have: ${chalk32.bold("name")}, ${chalk32.bold("description")} (scoring rubric), ${chalk32.bold("evaluationParameter")}
9119
9159
  evaluationParameter MUST match an inputSchema or outputSchema field name
9120
9160
  No duplicate evaluationParameter values — each criterion targets a unique field
9121
9161
  ALL schema fields must be covered (missing fields = error)
9122
- Use ${chalk31.bold("--guided --json")} to generate criteria templates from prompt schemas
9162
+ Use ${chalk32.bold("--guided --json")} to generate criteria templates from prompt schemas
9123
9163
 
9124
- ${chalk31.yellow("Optimization Cost Control:")}
9125
- Default max-iterations is 1. ${chalk31.red("NEVER increase without explicit user request.")}
9164
+ ${chalk32.yellow("Optimization Cost Control:")}
9165
+ Default max-iterations is 1. ${chalk32.red("NEVER increase without explicit user request.")}
9126
9166
  Each iteration incurs LLM costs — confirm with user before starting >1.
9127
9167
 
9128
- ${chalk31.yellow("Post-Optimization:")}
9129
- After ${chalk31.bold("optimize results")}: ALWAYS show the before/after diff to the user first.
9130
- Then offer choices: ${chalk31.bold("Apply")} / ${chalk31.bold("Reject")}.
9168
+ ${chalk32.yellow("Post-Optimization:")}
9169
+ After ${chalk32.bold("optimize results")}: ALWAYS show the before/after diff to the user first.
9170
+ Then offer choices: ${chalk32.bold("Apply")} / ${chalk32.bold("Reject")}.
9131
9171
 
9132
- ${chalk31.yellow("State Tracking:")}
9172
+ ${chalk32.yellow("State Tracking:")}
9133
9173
  .mutagent/mutation-context.md — Codebase index of discovered/uploaded prompts
9134
9174
  Update after explore, create, and dataset operations
9135
9175
  mutagent auth status — Auth + workspace state
9136
9176
  Comment markers (// MutagenT:START ... // MutagenT:END) in source files
9137
9177
 
9138
- ${chalk31.yellow("AI Agent Rules (MANDATORY for coding agents):")}
9139
- 1. EVERY command MUST include --json (no exceptions)
9140
- 2. Run <command> --help BEFORE first use of any command
9141
- 3. Use --guided --json for evaluation creation (NEVER --guided alone)
9142
- 4. Parse _directive.renderedCard and copy it into your CHAT RESPONSE verbatim
9143
- ${chalk31.red("HARD STOP")}: do NOT run further commands until the card is rendered in chat
9144
- 5. After mutagent init, verify workspace: mutagent workspaces list --json
9145
- 6. Use {single_braces} for template variables in prompts
9146
- 7. Collect evaluation criteria from the user NEVER auto-generate
9147
- 8. ALL user interaction via AskUserQuestion CLI is non-interactive
9178
+ ${chalk32.yellow("AI Agent Rules (MANDATORY for coding agents):")}
9179
+ 1. Login (two paths):
9180
+ - CI / fully automated: export MUTAGENT_API_KEY=mt_... then mutagent login --json
9181
+ - Helping a user onboard: mutagent login --browser --json
9182
+ (CLI prints an auth URL — surface it to the user verbatim, then the CLI
9183
+ polls for up to 5 minutes while the user authorizes in their browser.
9184
+ This IS agent-compatible. --non-interactive is NOT needed with --browser.)
9185
+ 2. EVERY command MUST include --json (no exceptions)
9186
+ 3. Run <command> --help BEFORE first use of any command
9187
+ 4. Use --guided --json for evaluation creation (NEVER --guided alone)
9188
+ 5. Parse _directive.renderedCard and copy it into your CHAT RESPONSE verbatim
9189
+ ${chalk32.red("HARD STOP")}: do NOT run further commands until the card is rendered in chat
9190
+ 6. After mutagent init, verify workspace: mutagent workspaces list --json
9191
+ 7. Use {single_braces} for template variables in prompts
9192
+ 8. Collect evaluation criteria from the user — NEVER auto-generate
9193
+ 9. ALL user interaction via AskUserQuestion — CLI is non-interactive
9148
9194
  ${!hasCredentials() ? `
9149
- ` + chalk31.yellow(" Warning: Not authenticated. Run: mutagent auth login --browser") + `
9195
+ ` + chalk32.yellow(" Warning: Not authenticated. Run: mutagent login") + `
9150
9196
  ` : ""}${!hasRcConfig() ? `
9151
- ` + chalk31.green(" Get started: mutagent init") + `
9197
+ ` + chalk32.green(" Get started: mutagent init") + `
9152
9198
  ` : ""}`);
9153
9199
  var rawArgs = process.argv.slice(2);
9154
9200
  if (rawArgs.includes("-v") || rawArgs.includes("--version")) {
@@ -9189,5 +9235,5 @@ program.addCommand(createHooksCommand());
9189
9235
  program.addCommand(createFeedbackCommand());
9190
9236
  program.parse();
9191
9237
 
9192
- //# debugId=3313422F119EC74164756E2164756E21
9238
+ //# debugId=A84DFC92DB1ED69764756E2164756E21
9193
9239
  //# sourceMappingURL=cli.js.map