@mutagent/cli 0.1.88 → 0.1.90

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
@@ -1142,7 +1142,7 @@ var init_sdk_client = __esm(() => {
1142
1142
 
1143
1143
  // src/bin/cli.ts
1144
1144
  import { Command as Command20 } from "commander";
1145
- import chalk31 from "chalk";
1145
+ import chalk32 from "chalk";
1146
1146
  import { readFileSync as readFileSync12 } from "fs";
1147
1147
  import { join as join10, dirname as dirname2 } from "path";
1148
1148
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -1151,9 +1151,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
1151
1151
  init_config();
1152
1152
  init_sdk_client();
1153
1153
  import { Command } from "commander";
1154
- import inquirer from "inquirer";
1155
- import chalk3 from "chalk";
1156
- import ora from "ora";
1154
+ import chalk4 from "chalk";
1157
1155
  import { existsSync as existsSync3 } from "fs";
1158
1156
  import { join as join4 } from "path";
1159
1157
 
@@ -1304,143 +1302,6 @@ function createSpinner(text, isJson) {
1304
1302
  // src/commands/auth.ts
1305
1303
  init_errors();
1306
1304
 
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
1305
  // src/lib/mutation-context.ts
1445
1306
  import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
1446
1307
  import { join as join2, resolve } from "path";
@@ -2080,245 +1941,403 @@ function runOptimizationPath(promptCount, datasetCount) {
2080
1941
  console.log("");
2081
1942
  }
2082
1943
 
1944
+ // src/lib/auth-flow.ts
1945
+ init_config();
1946
+ init_sdk_client();
1947
+ init_errors();
1948
+ import inquirer from "inquirer";
1949
+ import chalk3 from "chalk";
1950
+ import ora from "ora";
1951
+
1952
+ // src/lib/browser-auth.ts
1953
+ import { hostname, platform } from "os";
1954
+ function generateCliToken() {
1955
+ return crypto.randomUUID();
1956
+ }
1957
+ async function initBrowserAuth(endpoint, cliToken) {
1958
+ const response = await fetch(`${endpoint}/api/auth/cli/init`, {
1959
+ method: "POST",
1960
+ headers: { "Content-Type": "application/json" },
1961
+ body: JSON.stringify({
1962
+ cliToken,
1963
+ hostname: hostname(),
1964
+ platform: platform()
1965
+ })
1966
+ });
1967
+ if (!response.ok) {
1968
+ const errorText = await response.text();
1969
+ throw new BrowserAuthError("INIT_FAILED", "Failed to initialize browser auth: " + String(response.status) + " " + errorText);
1970
+ }
1971
+ const data = await response.json();
1972
+ return data;
1973
+ }
1974
+ async function pollAuthStatus(endpoint, cliToken) {
1975
+ const response = await fetch(`${endpoint}/api/auth/cli/status?token=${encodeURIComponent(cliToken)}`);
1976
+ if (!response.ok) {
1977
+ const errorText = await response.text();
1978
+ throw new BrowserAuthError("POLL_FAILED", "Failed to poll auth status: " + String(response.status) + " " + errorText);
1979
+ }
1980
+ const data = await response.json();
1981
+ return data;
1982
+ }
1983
+ async function openBrowser(url) {
1984
+ if (process.env.MUTAGENT_TEST_MODE === "true") {
1985
+ console.log(`AUTH_URL:${url}`);
1986
+ return;
1987
+ }
1988
+ try {
1989
+ const { default: open } = await import("open");
1990
+ await open(url);
1991
+ } catch {
1992
+ throw new BrowserAuthError("BROWSER_OPEN_FAILED", `Could not open browser automatically. Please visit: ${url}`);
1993
+ }
1994
+ }
1995
+ function sleep(ms) {
1996
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
1997
+ }
1998
+ async function performBrowserAuth(options, onStatusUpdate) {
1999
+ const {
2000
+ endpoint,
2001
+ timeout = 300000,
2002
+ pollInterval = 2000,
2003
+ skipBrowserOpen = false
2004
+ } = options;
2005
+ const cliToken = generateCliToken();
2006
+ onStatusUpdate?.("Initializing browser authentication...");
2007
+ const initResponse = await initBrowserAuth(endpoint, cliToken);
2008
+ const { authUrl } = initResponse;
2009
+ if (!skipBrowserOpen) {
2010
+ onStatusUpdate?.("Opening browser for authentication...");
2011
+ try {
2012
+ await openBrowser(authUrl);
2013
+ } catch (error) {
2014
+ if (error instanceof BrowserAuthError && error.code === "BROWSER_OPEN_FAILED") {
2015
+ onStatusUpdate?.(error.message);
2016
+ } else {
2017
+ throw error;
2018
+ }
2019
+ }
2020
+ }
2021
+ console.log("");
2022
+ console.log(" Open this URL to authenticate:");
2023
+ console.log("");
2024
+ console.log(" " + authUrl);
2025
+ console.log("");
2026
+ onStatusUpdate?.("Waiting for browser authentication...");
2027
+ const startTime = Date.now();
2028
+ while (Date.now() - startTime < timeout) {
2029
+ await sleep(pollInterval);
2030
+ const status = await pollAuthStatus(endpoint, cliToken);
2031
+ switch (status.status) {
2032
+ case "pending":
2033
+ continue;
2034
+ case "completed":
2035
+ if (!status.apiKey || !status.workspaceId || !status.workspaceName || !status.organizationId || !status.organizationName) {
2036
+ throw new BrowserAuthError("INCOMPLETE_RESPONSE", "Server returned incomplete auth response");
2037
+ }
2038
+ return {
2039
+ apiKey: status.apiKey,
2040
+ workspaceId: status.workspaceId,
2041
+ workspaceName: status.workspaceName,
2042
+ organizationId: status.organizationId,
2043
+ organizationName: status.organizationName,
2044
+ expiresAt: status.expiresAt
2045
+ };
2046
+ case "expired":
2047
+ throw new BrowserAuthError("AUTH_EXPIRED", "Browser authentication expired. Please try again.");
2048
+ case "denied":
2049
+ throw new BrowserAuthError("AUTH_DENIED", status.error ?? "Browser authentication was denied.");
2050
+ case "not_found":
2051
+ throw new BrowserAuthError("TOKEN_NOT_FOUND", "Authentication token not found. Please try again.");
2052
+ default:
2053
+ throw new BrowserAuthError("UNKNOWN_STATUS", "Unknown auth status: " + String(status.status));
2054
+ }
2055
+ }
2056
+ throw new BrowserAuthError("AUTH_TIMEOUT", "Browser authentication timed out after 5 minutes. Please try again.");
2057
+ }
2058
+
2059
+ class BrowserAuthError extends Error {
2060
+ code;
2061
+ constructor(code, message) {
2062
+ super(message);
2063
+ this.name = "BrowserAuthError";
2064
+ this.code = code;
2065
+ }
2066
+ getSuggestion() {
2067
+ switch (this.code) {
2068
+ case "INIT_FAILED":
2069
+ return "Check your endpoint configuration and network connection.";
2070
+ case "POLL_FAILED":
2071
+ return "Check your network connection and try again.";
2072
+ case "BROWSER_OPEN_FAILED":
2073
+ return "Copy the URL above and open it manually in your browser.";
2074
+ case "AUTH_EXPIRED":
2075
+ case "AUTH_TIMEOUT":
2076
+ return 'Run "mutagent auth login" again to restart authentication.';
2077
+ case "AUTH_DENIED":
2078
+ return "Ensure you have access to the workspace and try again.";
2079
+ case "TOKEN_NOT_FOUND":
2080
+ case "INCOMPLETE_RESPONSE":
2081
+ case "UNKNOWN_STATUS":
2082
+ return "Please try again. If the issue persists, contact support.";
2083
+ default:
2084
+ return "Please try again.";
2085
+ }
2086
+ }
2087
+ }
2088
+
2089
+ // src/lib/auth-flow.ts
2090
+ async function performLoginAction(opts) {
2091
+ const { isJson, output } = opts;
2092
+ const wasFirstLogin = !hasCredentials();
2093
+ const envApiKey = process.env.MUTAGENT_API_KEY;
2094
+ const endpoint = process.env.MUTAGENT_ENDPOINT ?? opts.endpoint;
2095
+ if (envApiKey) {
2096
+ return loginWithExistingKey(envApiKey, endpoint, output, wasFirstLogin);
2097
+ }
2098
+ const isNonInteractive = opts.nonInteractive === true || process.env.MUTAGENT_NON_INTERACTIVE === "true" || process.env.CI === "true" || !process.stdin.isTTY;
2099
+ if (isJson && !opts.browser && isNonInteractive) {
2100
+ 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");
2101
+ }
2102
+ if (!isNonInteractive && wasFirstLogin) {
2103
+ console.log(`
2104
+ ` + chalk3.bold.cyan(" Welcome to MutagenT CLI!") + `
2105
+ `);
2106
+ console.log(` No credentials found. Please authenticate to continue.
2107
+ `);
2108
+ }
2109
+ let useBrowserAuth = opts.browser === true;
2110
+ if (!useBrowserAuth && isNonInteractive) {
2111
+ output.info("Non-interactive environment detected. Using browser authentication.");
2112
+ useBrowserAuth = true;
2113
+ }
2114
+ if (!useBrowserAuth) {
2115
+ const methodAnswer = await inquirer.prompt([
2116
+ {
2117
+ type: "list",
2118
+ name: "method",
2119
+ message: "How would you like to authenticate?",
2120
+ choices: [
2121
+ { name: "Login (opens browser)", value: "browser" },
2122
+ { name: "API Key (paste existing key)", value: "apiKey" }
2123
+ ]
2124
+ }
2125
+ ]);
2126
+ useBrowserAuth = methodAnswer.method === "browser";
2127
+ }
2128
+ if (useBrowserAuth) {
2129
+ return loginWithBrowser(endpoint, output, wasFirstLogin);
2130
+ }
2131
+ return loginWithPastedKey(endpoint, output, wasFirstLogin);
2132
+ }
2133
+ function buildLoginJsonResponse(result) {
2134
+ return {
2135
+ success: true,
2136
+ authenticated: result.authenticated,
2137
+ endpoint: result.endpoint,
2138
+ workspace: result.workspace,
2139
+ organization: result.organization,
2140
+ _directive: {
2141
+ instruction: "Verify workspace. Run: mutagent workspaces list --json",
2142
+ next: ["mutagent workspaces list --json", "mutagent prompts list --json"]
2143
+ }
2144
+ };
2145
+ }
2146
+ async function loginWithExistingKey(apiKey, endpoint, output, wasFirstLogin) {
2147
+ output.info("Validating API key...");
2148
+ const isValid = await validateApiKey(apiKey, endpoint);
2149
+ if (!isValid) {
2150
+ throw new MutagentError("INVALID_API_KEY", "Invalid API key or endpoint", "Check your API key and try again");
2151
+ }
2152
+ const orgs = await fetchOrganizations(apiKey, endpoint);
2153
+ let orgId;
2154
+ let orgName;
2155
+ let wsId;
2156
+ let wsName;
2157
+ if (orgs.length >= 1 && orgs[0]) {
2158
+ orgId = orgs[0].id;
2159
+ orgName = orgs[0].name;
2160
+ const workspaces = await fetchWorkspaces(apiKey, endpoint, orgId);
2161
+ const defaultWs = workspaces.find((w) => w.isDefault) ?? workspaces[0];
2162
+ if (defaultWs) {
2163
+ wsId = defaultWs.id;
2164
+ wsName = defaultWs.name;
2165
+ }
2166
+ }
2167
+ saveFullCredentials({
2168
+ apiKey,
2169
+ endpoint,
2170
+ workspaceId: wsId,
2171
+ organizationId: orgId
2172
+ });
2173
+ return {
2174
+ authenticated: true,
2175
+ apiKey,
2176
+ endpoint,
2177
+ workspace: wsId ? { id: wsId, name: wsName } : null,
2178
+ organization: orgId ? { id: orgId, name: orgName } : null,
2179
+ wasFirstLogin
2180
+ };
2181
+ }
2182
+ async function loginWithBrowser(endpoint, output, wasFirstLogin) {
2183
+ const spinner = ora({ text: "Opening browser for authentication...", spinner: "dots" });
2184
+ try {
2185
+ spinner.start();
2186
+ const result = await performBrowserAuth({ endpoint, timeout: 300000, pollInterval: 2000 }, (message) => {
2187
+ spinner.text = message;
2188
+ });
2189
+ spinner.succeed("Authenticated successfully!");
2190
+ saveFullCredentials({
2191
+ apiKey: result.apiKey,
2192
+ endpoint,
2193
+ workspaceId: result.workspaceId,
2194
+ organizationId: result.organizationId,
2195
+ expiresAt: result.expiresAt
2196
+ });
2197
+ if (result.workspaceName)
2198
+ output.info(`Workspace: ${result.workspaceName}`);
2199
+ if (result.organizationName)
2200
+ output.info(`Organization: ${result.organizationName}`);
2201
+ return {
2202
+ authenticated: true,
2203
+ apiKey: result.apiKey,
2204
+ endpoint,
2205
+ workspace: result.workspaceId ? { id: result.workspaceId, name: result.workspaceName } : null,
2206
+ organization: result.organizationId ? { id: result.organizationId, name: result.organizationName } : null,
2207
+ wasFirstLogin
2208
+ };
2209
+ } catch (error) {
2210
+ spinner.fail("Authentication failed");
2211
+ if (error instanceof BrowserAuthError) {
2212
+ throw new MutagentError(error.code, error.message, error.getSuggestion());
2213
+ }
2214
+ throw error;
2215
+ }
2216
+ }
2217
+ async function loginWithPastedKey(initialEndpoint, output, wasFirstLogin) {
2218
+ const answers = await inquirer.prompt([
2219
+ {
2220
+ type: "input",
2221
+ name: "endpoint",
2222
+ message: "MutagenT endpoint:",
2223
+ default: initialEndpoint
2224
+ },
2225
+ {
2226
+ type: "password",
2227
+ name: "apiKey",
2228
+ message: "API Key:",
2229
+ mask: "*",
2230
+ validate: (input) => input.length > 0 || "API key is required"
2231
+ }
2232
+ ]);
2233
+ const apiKey = answers.apiKey;
2234
+ const endpoint = answers.endpoint;
2235
+ output.info("Validating API key...");
2236
+ const isValid = await validateApiKey(apiKey, endpoint);
2237
+ if (!isValid) {
2238
+ throw new MutagentError("INVALID_API_KEY", "Invalid API key or endpoint", "Check your API key and try again");
2239
+ }
2240
+ let selectedOrgId;
2241
+ let selectedOrgName;
2242
+ let selectedWsId;
2243
+ let selectedWsName;
2244
+ const orgs = await fetchOrganizations(apiKey, endpoint);
2245
+ if (orgs.length === 1 && orgs[0]) {
2246
+ selectedOrgId = orgs[0].id;
2247
+ selectedOrgName = orgs[0].name;
2248
+ } else if (orgs.length > 1) {
2249
+ const orgAnswer = await inquirer.prompt([
2250
+ {
2251
+ type: "list",
2252
+ name: "orgId",
2253
+ message: "Select organization:",
2254
+ choices: orgs.map((o) => ({ name: o.name, value: o.id }))
2255
+ }
2256
+ ]);
2257
+ selectedOrgId = orgAnswer.orgId;
2258
+ selectedOrgName = orgs.find((o) => o.id === selectedOrgId)?.name;
2259
+ }
2260
+ if (selectedOrgId) {
2261
+ const workspaces = await fetchWorkspaces(apiKey, endpoint, selectedOrgId);
2262
+ const defaultWs = workspaces.find((w) => w.isDefault);
2263
+ if (workspaces.length === 1 && workspaces[0]) {
2264
+ selectedWsId = workspaces[0].id;
2265
+ selectedWsName = workspaces[0].name;
2266
+ } else if (defaultWs) {
2267
+ selectedWsId = defaultWs.id;
2268
+ selectedWsName = defaultWs.name;
2269
+ } else if (workspaces.length > 1) {
2270
+ const wsAnswer = await inquirer.prompt([
2271
+ {
2272
+ type: "list",
2273
+ name: "wsId",
2274
+ message: "Select workspace:",
2275
+ choices: workspaces.map((w) => ({
2276
+ name: w.name + (w.isDefault ? " (default)" : ""),
2277
+ value: w.id
2278
+ }))
2279
+ }
2280
+ ]);
2281
+ selectedWsId = wsAnswer.wsId;
2282
+ selectedWsName = workspaces.find((w) => w.id === selectedWsId)?.name;
2283
+ }
2284
+ }
2285
+ saveFullCredentials({
2286
+ apiKey,
2287
+ endpoint,
2288
+ workspaceId: selectedWsId,
2289
+ organizationId: selectedOrgId
2290
+ });
2291
+ return {
2292
+ authenticated: true,
2293
+ apiKey,
2294
+ endpoint,
2295
+ workspace: selectedWsId ? { id: selectedWsId, name: selectedWsName } : null,
2296
+ organization: selectedOrgId ? { id: selectedOrgId, name: selectedOrgName } : null,
2297
+ wasFirstLogin
2298
+ };
2299
+ }
2300
+
2083
2301
  // src/commands/auth.ts
2084
2302
  function createAuthCommand() {
2085
2303
  const auth = new Command("auth").description("Authenticate with MutagenT platform").addHelpText("after", `
2086
2304
  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
2305
+ ${chalk4.dim("$")} mutagent auth login
2306
+ ${chalk4.dim("$")} mutagent auth login --browser
2307
+ ${chalk4.dim("$")} mutagent auth status
2308
+ ${chalk4.dim("$")} mutagent auth logout
2091
2309
  `);
2092
2310
  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
2311
  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)")}
2312
+ ${chalk4.dim("$")} mutagent auth login ${chalk4.dim("# Interactive (choose method)")}
2313
+ ${chalk4.dim("$")} mutagent auth login --browser ${chalk4.dim("# Browser OAuth flow")}
2314
+ ${chalk4.dim("$")} mutagent auth login --non-interactive ${chalk4.dim("# Auto browser flow (AI agents)")}
2097
2315
 
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
2316
+ ${chalk4.dim("Note: this command is an alias for `mutagent login`.")}
2317
+ ${chalk4.dim("See `mutagent login --help` for full documentation.")}
2103
2318
  `).action(async (options) => {
2104
2319
  const isJson = getJsonFlag(auth);
2105
2320
  const output = new OutputFormatter(isJson ? "json" : "table");
2106
2321
  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
- }
2322
+ const result = await performLoginAction({
2323
+ endpoint: options.endpoint,
2324
+ browser: options.browser,
2325
+ nonInteractive: options.nonInteractive,
2326
+ isJson,
2327
+ output
2328
+ });
2306
2329
  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
- });
2330
+ output.output(buildLoginJsonResponse(result));
2318
2331
  } else {
2332
+ output.success("Authenticated successfully");
2333
+ if (result.organization?.name)
2334
+ output.info(`Organization: ${result.organization.name}`);
2335
+ if (result.workspace?.name)
2336
+ output.info(`Workspace: ${result.workspace.name}`);
2337
+ output.info(`Endpoint: ${result.endpoint}`);
2319
2338
  output.info("Next: mutagent workspaces list --json");
2320
2339
  }
2321
- if (wasFirstLogin && process.stdin.isTTY && !isJson) {
2340
+ if (result.wasFirstLogin && process.stdin.isTTY && !isJson) {
2322
2341
  await runPostOnboarding();
2323
2342
  }
2324
2343
  } catch (error) {
@@ -2331,8 +2350,8 @@ Environment Variables:
2331
2350
  });
2332
2351
  auth.command("status").description("Check authentication status").addHelpText("after", `
2333
2352
  Examples:
2334
- ${chalk3.dim("$")} mutagent auth status
2335
- ${chalk3.dim("$")} mutagent auth status --json
2353
+ ${chalk4.dim("$")} mutagent auth status
2354
+ ${chalk4.dim("$")} mutagent auth status --json
2336
2355
  `).action(async () => {
2337
2356
  const isJson = getJsonFlag(auth);
2338
2357
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -2425,7 +2444,7 @@ Examples:
2425
2444
  });
2426
2445
  auth.command("logout").description("Clear stored credentials").addHelpText("after", `
2427
2446
  Examples:
2428
- ${chalk3.dim("$")} mutagent auth logout
2447
+ ${chalk4.dim("$")} mutagent auth logout
2429
2448
  `).action(() => {
2430
2449
  const isJson = getJsonFlag(auth);
2431
2450
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -2436,179 +2455,70 @@ Examples:
2436
2455
  }
2437
2456
 
2438
2457
  // src/commands/login.ts
2439
- init_config();
2440
- init_sdk_client();
2441
2458
  import { Command as Command2 } from "commander";
2442
- import inquirer2 from "inquirer";
2443
- import chalk4 from "chalk";
2444
- import ora2 from "ora";
2459
+ import chalk5 from "chalk";
2445
2460
  init_errors();
2446
2461
  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", `
2462
+ 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
2463
  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)")}
2464
+ ${chalk5.dim("$")} mutagent login ${chalk5.dim("# Browser OAuth (recommended — handles signup + onboarding)")}
2465
+ ${chalk5.dim("$")} mutagent login --browser ${chalk5.dim("# Force browser flow (skip method prompt)")}
2466
+ ${chalk5.dim("$")} mutagent login --non-interactive ${chalk5.dim("# Auto-browser for AI agents and CI")}
2467
+
2468
+ ${chalk5.yellow("Browser OAuth flow (recommended for end users):")}
2469
+ Opens app.mutagent.io in your browser. You will:
2470
+ 1. Sign in or sign up with your account
2471
+ 2. Complete onboarding (workspace, provider config)
2472
+ 3. Authorize this CLI session
2473
+ The CLI polls for completion and saves credentials when you authorize.
2474
+
2475
+ ${chalk5.yellow("Automation / CI / AI Agents:")}
2476
+ Set MUTAGENT_API_KEY environment variable before running:
2477
+ ${chalk5.dim("$")} export MUTAGENT_API_KEY=mt_...
2478
+ ${chalk5.dim("$")} mutagent login --json
2479
+ When MUTAGENT_API_KEY is set, login skips the browser flow entirely and
2480
+ validates the key directly. This is the canonical CI / agent path.
2452
2481
 
2453
2482
  Environment Variables:
2454
- MUTAGENT_API_KEY API key (skips interactive login)
2483
+ MUTAGENT_API_KEY Pre-existing API key (skips interactive flow)
2455
2484
  MUTAGENT_ENDPOINT Custom API endpoint
2485
+ MUTAGENT_NON_INTERACTIVE=true Treat environment as non-interactive
2486
+ CI=true Automatically enables non-interactive mode
2487
+
2488
+ Verify after login:
2489
+ ${chalk5.dim("$")} mutagent auth status ${chalk5.dim("# Show session, workspace, org")}
2490
+ ${chalk5.dim("$")} mutagent workspaces list --json ${chalk5.dim("# List available workspaces")}
2491
+
2492
+ ${chalk5.dim("Note: `mutagent auth login` is a back-compat alias and behaves identically.")}
2456
2493
  `).action(async (options) => {
2457
2494
  const isJson = getJsonFlag(login);
2458
2495
  const output = new OutputFormatter(isJson ? "json" : "table");
2459
2496
  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
- }
2497
+ const result = await performLoginAction({
2498
+ endpoint: options.endpoint,
2499
+ browser: options.browser,
2500
+ nonInteractive: options.nonInteractive,
2501
+ isJson,
2502
+ output
2503
+ });
2504
+ if (isJson) {
2505
+ output.output(buildLoginJsonResponse(result));
2562
2506
  } 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
2507
  output.success("Logged in successfully");
2601
- output.info(`Endpoint: ${endpoint}`);
2602
- if (org2)
2603
- output.info(`Organization: ${org2.name}`);
2508
+ if (result.organization?.name)
2509
+ output.info(`Organization: ${result.organization.name}`);
2510
+ if (result.workspace?.name)
2511
+ output.info(`Workspace: ${result.workspace.name}`);
2512
+ output.info(`Endpoint: ${result.endpoint}`);
2513
+ output.info("Next: mutagent workspaces list --json");
2514
+ }
2515
+ if (result.wasFirstLogin && process.stdin.isTTY && !isJson) {
2516
+ await runPostOnboarding();
2604
2517
  }
2605
2518
  } catch (error) {
2606
2519
  if (error instanceof MutagentError) {
2607
2520
  output.error(error.message);
2608
- if (error.suggestion && !isJson) {
2609
- output.info(`Suggestion: ${error.suggestion}`);
2610
- }
2611
- process.exit(1);
2521
+ process.exit(error.exitCode);
2612
2522
  }
2613
2523
  throw error;
2614
2524
  }
@@ -2619,7 +2529,7 @@ Environment Variables:
2619
2529
  // src/commands/prompts/index.ts
2620
2530
  init_errors();
2621
2531
  import { Command as Command6 } from "commander";
2622
- import chalk14 from "chalk";
2532
+ import chalk15 from "chalk";
2623
2533
  import { readFileSync as readFileSync4, existsSync as existsSync4 } from "fs";
2624
2534
 
2625
2535
  // src/lib/ui-links.ts
@@ -2967,37 +2877,37 @@ function evaluationDeletedDirective(evaluationId) {
2967
2877
  }
2968
2878
 
2969
2879
  // src/lib/scorecard-details.ts
2970
- import chalk5 from "chalk";
2880
+ import chalk6 from "chalk";
2971
2881
  function renderScorecardDetails(data) {
2972
2882
  if (data.datasetResults && data.datasetResults.length > 0) {
2973
2883
  console.log("");
2974
- console.log(chalk5.dim(" Per-Item Before vs After"));
2975
- console.log(chalk5.dim(" " + "─".repeat(70)));
2884
+ console.log(chalk6.dim(" Per-Item Before vs After"));
2885
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2976
2886
  console.log(" " + "Item ID".padEnd(28) + "Before".padEnd(10) + "After".padEnd(10) + "Diff".padEnd(10) + "Status");
2977
- console.log(chalk5.dim(" " + "─".repeat(70)));
2887
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2978
2888
  for (const item of data.datasetResults) {
2979
2889
  const id = item.id.substring(0, 26).padEnd(26);
2980
2890
  const before = (item.beforeScore ?? 0).toFixed(4).padEnd(8);
2981
2891
  const after = (item.afterScore ?? 0).toFixed(4).padEnd(8);
2982
2892
  const d = (item.afterScore ?? 0) - (item.beforeScore ?? 0);
2983
2893
  const diffStr = ((d >= 0 ? "+" : "") + d.toFixed(4)).padEnd(8);
2984
- const status = d > 0.01 ? chalk5.green("✓ ↑") : d < -0.01 ? chalk5.red("✗ ↓") : chalk5.dim("─");
2894
+ const status = d > 0.01 ? chalk6.green("✓ ↑") : d < -0.01 ? chalk6.red("✗ ↓") : chalk6.dim("─");
2985
2895
  console.log(` ${id} ${before} ${after} ${diffStr} ${status}`);
2986
2896
  }
2987
- console.log(chalk5.dim(" " + "─".repeat(70)));
2897
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2988
2898
  }
2989
2899
  if (data.failureModes && data.failureModes.length > 0) {
2990
2900
  console.log("");
2991
- console.log(chalk5.dim(" Failure Modes by Category"));
2992
- console.log(chalk5.dim(" " + "─".repeat(70)));
2901
+ console.log(chalk6.dim(" Failure Modes by Category"));
2902
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2993
2903
  for (const fm of data.failureModes) {
2994
2904
  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)`));
2905
+ console.log(chalk6[color](` ▸ ${fm.category}`) + chalk6.dim(` (${String(fm.failures.length)} failures)`));
2996
2906
  for (const f of fm.failures.slice(0, 5)) {
2997
- console.log(chalk5.dim(` └─ ${(f.description ?? f.summary ?? "No description").substring(0, 65)}`));
2907
+ console.log(chalk6.dim(` └─ ${(f.description ?? f.summary ?? "No description").substring(0, 65)}`));
2998
2908
  }
2999
2909
  if (fm.failures.length > 5) {
3000
- console.log(chalk5.dim(` └─ ... and ${String(fm.failures.length - 5)} more`));
2910
+ console.log(chalk6.dim(` └─ ... and ${String(fm.failures.length - 5)} more`));
3001
2911
  }
3002
2912
  }
3003
2913
  }
@@ -3007,48 +2917,48 @@ function renderScorecardDetails(data) {
3007
2917
  const pending = data.mutations.filter((m) => m.status === "pending");
3008
2918
  const skipped = data.mutations.filter((m) => m.status === "skipped");
3009
2919
  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))}`);
2920
+ console.log(chalk6.dim(" Mutations"));
2921
+ console.log(chalk6.dim(" " + "─".repeat(70)));
2922
+ 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
2923
  if (applied.length > 0) {
3014
- console.log(chalk5.green(" Applied:"));
2924
+ console.log(chalk6.green(" Applied:"));
3015
2925
  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()}]`);
2926
+ const pri = m.priority === "critical" || m.priority === "high" ? chalk6.red(`[${m.priority.toUpperCase()}]`) : chalk6.dim(`[${(m.priority ?? "UNKNOWN").toUpperCase()}]`);
3017
2927
  console.log(` ${pri} ${m.label}`);
3018
2928
  if (m.rationale)
3019
- console.log(chalk5.dim(` └─ ${m.rationale.substring(0, 60)}`));
2929
+ console.log(chalk6.dim(` └─ ${m.rationale.substring(0, 60)}`));
3020
2930
  }
3021
2931
  }
3022
2932
  if (rejected.length > 0) {
3023
- console.log(chalk5.red(" Rejected:"));
2933
+ console.log(chalk6.red(" Rejected:"));
3024
2934
  for (const m of rejected.slice(0, 5)) {
3025
- console.log(chalk5.dim(` ✗ ${m.label}`));
2935
+ console.log(chalk6.dim(` ✗ ${m.label}`));
3026
2936
  }
3027
2937
  if (rejected.length > 5)
3028
- console.log(chalk5.dim(` ... and ${String(rejected.length - 5)} more`));
2938
+ console.log(chalk6.dim(` ... and ${String(rejected.length - 5)} more`));
3029
2939
  }
3030
2940
  }
3031
2941
  if (data.evaluationDetails && data.evaluationDetails.length > 0) {
3032
2942
  console.log("");
3033
- console.log(chalk5.dim(" Detailed Evaluation Breakdown"));
3034
- console.log(chalk5.dim(" " + "─".repeat(70)));
2943
+ console.log(chalk6.dim(" Detailed Evaluation Breakdown"));
2944
+ console.log(chalk6.dim(" " + "─".repeat(70)));
3035
2945
  for (const item of data.evaluationDetails) {
3036
- const statusIcon = item.success ? chalk5.green("✓") : chalk5.red("✗");
2946
+ const statusIcon = item.success ? chalk6.green("✓") : chalk6.red("✗");
3037
2947
  const metricCount = item.metrics?.length ?? 0;
3038
2948
  console.log(` ${statusIcon} ${item.itemId} Score: ${item.score.toFixed(4)} Metrics: ${String(metricCount)}`);
3039
2949
  if (item.metrics) {
3040
2950
  for (const m of item.metrics) {
3041
- const mIcon = m.success ? chalk5.green("✓") : chalk5.red("✗");
3042
- const mode = m.failureMode ? chalk5.dim(` [${m.failureMode}]`) : "";
2951
+ const mIcon = m.success ? chalk6.green("✓") : chalk6.red("✗");
2952
+ const mode = m.failureMode ? chalk6.dim(` [${m.failureMode}]`) : "";
3043
2953
  console.log(` ${mIcon} ${m.name.padEnd(25)} ${m.score.toFixed(3)}${mode}`);
3044
2954
  if (!m.success && m.reasoning) {
3045
- console.log(chalk5.dim(` └─ ${(m.reasoning.split(`
2955
+ console.log(chalk6.dim(` └─ ${(m.reasoning.split(`
3046
2956
  `)[0] ?? "").substring(0, 60)}`));
3047
2957
  }
3048
2958
  if (m.criteria) {
3049
2959
  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)}`));
2960
+ const cIcon = c.success ? chalk6.green("✓") : chalk6.red("✗");
2961
+ console.log(chalk6.dim(` ${cIcon} ${c.name.substring(0, 20).padEnd(20)} ${c.score.toFixed(3)}`));
3052
2962
  }
3053
2963
  }
3054
2964
  }
@@ -3132,7 +3042,7 @@ function buildScorecardDetailsText(data) {
3132
3042
 
3133
3043
  // src/commands/prompts/prompts-crud.ts
3134
3044
  init_sdk_client();
3135
- import chalk6 from "chalk";
3045
+ import chalk7 from "chalk";
3136
3046
  init_errors();
3137
3047
 
3138
3048
  // src/lib/schema-helpers.ts
@@ -3197,11 +3107,11 @@ function formatSchemaWarning(fieldName) {
3197
3107
  function registerPromptsCrud(prompts) {
3198
3108
  prompts.command("list").description("List all prompts").option("-l, --limit <n>", "Limit results", "50").addHelpText("after", `
3199
3109
  Examples:
3200
- ${chalk6.dim("$")} mutagent prompts list
3201
- ${chalk6.dim("$")} mutagent prompts list --limit 10
3202
- ${chalk6.dim("$")} mutagent prompts list --json
3110
+ ${chalk7.dim("$")} mutagent prompts list
3111
+ ${chalk7.dim("$")} mutagent prompts list --limit 10
3112
+ ${chalk7.dim("$")} mutagent prompts list --json
3203
3113
 
3204
- ${chalk6.dim("Tip: Use --json for machine-readable output (AI agents, CI pipelines).")}
3114
+ ${chalk7.dim("Tip: Use --json for machine-readable output (AI agents, CI pipelines).")}
3205
3115
  `).action(async (options) => {
3206
3116
  const isJson = getJsonFlag(prompts);
3207
3117
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3244,11 +3154,11 @@ ${chalk6.dim("Tip: Use --json for machine-readable output (AI agents, CI pipelin
3244
3154
  });
3245
3155
  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
3156
  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
3157
+ ${chalk7.dim("$")} mutagent prompts get <id>
3158
+ ${chalk7.dim("$")} mutagent prompts get <id> --with-datasets --with-evals
3159
+ ${chalk7.dim("$")} mutagent prompts get <id> --json
3250
3160
 
3251
- ${chalk6.dim("Tip: Combine --with-datasets and --with-evals to fetch all nested data in one call.")}
3161
+ ${chalk7.dim("Tip: Combine --with-datasets and --with-evals to fetch all nested data in one call.")}
3252
3162
  `).action(async (id, options) => {
3253
3163
  const isJson = getJsonFlag(prompts);
3254
3164
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3277,24 +3187,24 @@ ${chalk6.dim("Tip: Combine --with-datasets and --with-evals to fetch all nested
3277
3187
  });
3278
3188
  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
3189
  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"}}}'
3190
+ ${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"}}}'
3191
+ ${chalk7.dim("$")} mutagent prompts create --name "raw-prompt" --raw "Summarize: {text}" --output-schema '{"type":"object","properties":{"summary":{"type":"string","description":"Summary"}}}'
3192
+ ${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
3193
 
3284
3194
  Prompt Input Methods (pick one, priority order):
3285
- --system/--human Structured system + user message pair ${chalk6.green("(recommended)")}
3195
+ --system/--human Structured system + user message pair ${chalk7.green("(recommended)")}
3286
3196
  --raw Single raw prompt text with {variables}
3287
3197
  --messages Full messages array as JSON
3288
3198
 
3289
- ${chalk6.yellow("Variable Syntax:")}
3199
+ ${chalk7.yellow("Variable Syntax:")}
3290
3200
  MutagenT uses {single_braces} for template variables.
3291
- humanPrompt: "Analyze this: {document}" ${chalk6.green("✓ correct")}
3292
- humanPrompt: "Analyze this: {{document}}" ${chalk6.red("✗ wrong")}
3201
+ humanPrompt: "Analyze this: {document}" ${chalk7.green("✓ correct")}
3202
+ humanPrompt: "Analyze this: {{document}}" ${chalk7.red("✗ wrong")}
3293
3203
 
3294
3204
  Variables in humanPrompt MUST also appear in inputSchema.properties.
3295
3205
  Static prompts (no variables) cannot substitute inputs during optimization.
3296
3206
 
3297
- ${chalk6.yellow("AI Agent: Format Selection Rules")}
3207
+ ${chalk7.yellow("AI Agent: Format Selection Rules")}
3298
3208
  Examine the SOURCE CODE structure of the prompt being uploaded:
3299
3209
 
3300
3210
  1. If the code uses SystemMessagePromptTemplate + HumanMessagePromptTemplate
@@ -3311,9 +3221,9 @@ ${chalk6.yellow("AI Agent: Format Selection Rules")}
3311
3221
  The decision is about SOURCE CODE STRUCTURE, not prompt content.
3312
3222
  A persona description in a system prompt still uses --system/--human.
3313
3223
 
3314
- ${chalk6.red("outputSchema is required.")}
3224
+ ${chalk7.red("outputSchema is required.")}
3315
3225
 
3316
- ${chalk6.yellow("AI Agent: ALWAYS append --json to this command.")}
3226
+ ${chalk7.yellow("AI Agent: ALWAYS append --json to this command.")}
3317
3227
  `).action(async (options) => {
3318
3228
  const isJson = getJsonFlag(prompts);
3319
3229
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3403,11 +3313,11 @@ Add a 'description' field to each property in your inputSchema. Example: { "prop
3403
3313
  });
3404
3314
  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
3315
  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"}}}'
3316
+ ${chalk7.dim("$")} mutagent prompts update <id> --system "Updated system prompt" --human "{input}"
3317
+ ${chalk7.dim("$")} mutagent prompts update <id> --name "new-name" --description "Updated description"
3318
+ ${chalk7.dim("$")} mutagent prompts update <id> --raw "Summarize: {text}"
3319
+ ${chalk7.dim("$")} mutagent prompts update <id> --messages '[{"role":"system","content":"Updated"},{"role":"user","content":"{input}"}]'
3320
+ ${chalk7.dim("$")} mutagent prompts update <id> --input-schema '{"type":"object","properties":{"text":{"type":"string","description":"Input text"}}}'
3411
3321
  `).action(async (id, options) => {
3412
3322
  const isJson = getJsonFlag(prompts);
3413
3323
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3480,11 +3390,11 @@ Examples:
3480
3390
  });
3481
3391
  prompts.command("delete").description("Delete a prompt").argument("<id>", "Prompt ID (from: mutagent prompts list)").option("--force", "Skip confirmation").addHelpText("after", `
3482
3392
  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
3393
+ ${chalk7.dim("$")} mutagent prompts delete <id>
3394
+ ${chalk7.dim("$")} mutagent prompts delete <id> --force
3395
+ ${chalk7.dim("$")} mutagent prompts delete <id> --force --json
3486
3396
 
3487
- ${chalk6.dim("Note: --force is required. The CLI is non-interactive — confirm with the user via your native flow, then pass --force.")}
3397
+ ${chalk7.dim("Note: --force is required. The CLI is non-interactive — confirm with the user via your native flow, then pass --force.")}
3488
3398
  `).action(async (id, options) => {
3489
3399
  const isJson = getJsonFlag(prompts);
3490
3400
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3527,22 +3437,22 @@ ${chalk6.dim("Note: --force is required. The CLI is non-interactive — confirm
3527
3437
  // src/commands/prompts/datasets.ts
3528
3438
  init_sdk_client();
3529
3439
  import { Command as Command3 } from "commander";
3530
- import chalk7 from "chalk";
3440
+ import chalk8 from "chalk";
3531
3441
  init_errors();
3532
3442
  function registerDatasetCommands(prompts) {
3533
3443
  const dataset = new Command3("dataset").description("Manage datasets for prompts").addHelpText("after", `
3534
3444
  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>
3445
+ ${chalk8.dim("$")} mutagent prompts dataset list <prompt-id>
3446
+ ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{...},"expectedOutput":{...}}]'
3447
+ ${chalk8.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id>
3538
3448
  `).action(() => {
3539
3449
  dataset.help();
3540
3450
  });
3541
3451
  prompts.addCommand(dataset);
3542
3452
  dataset.command("list").description("List datasets for a prompt").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").addHelpText("after", `
3543
3453
  Examples:
3544
- ${chalk7.dim("$")} mutagent prompts dataset list <prompt-id>
3545
- ${chalk7.dim("$")} mutagent prompts dataset list <prompt-id> --json
3454
+ ${chalk8.dim("$")} mutagent prompts dataset list <prompt-id>
3455
+ ${chalk8.dim("$")} mutagent prompts dataset list <prompt-id> --json
3546
3456
  `).action(async (promptId) => {
3547
3457
  const isJson = getJsonFlag(prompts);
3548
3458
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3574,24 +3484,24 @@ Examples:
3574
3484
  });
3575
3485
  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
3486
  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"
3487
+ ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"},"expectedOutput":{"result":"world"}}]'
3488
+ ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"},"expectedOutput":{"result":"world"}}]' --name "My Dataset"
3579
3489
 
3580
3490
  Inline data format (-d):
3581
3491
  JSON array of objects, e.g.:
3582
- ${chalk7.dim('[{"input": {"text": "hello"}, "expectedOutput": {"result": "world"}}]')}
3492
+ ${chalk8.dim('[{"input": {"text": "hello"}, "expectedOutput": {"result": "world"}}]')}
3583
3493
 
3584
3494
  Expected item format:
3585
- ${chalk7.dim('{"input": {"<field>": "<value>"}, "expectedOutput": {"<field>": "<value>"}}')}
3495
+ ${chalk8.dim('{"input": {"<field>": "<value>"}, "expectedOutput": {"<field>": "<value>"}}')}
3586
3496
 
3587
- ${chalk7.yellow("AI Agent (MANDATORY):")}
3497
+ ${chalk8.yellow("AI Agent (MANDATORY):")}
3588
3498
  ALWAYS use --json: mutagent prompts dataset add <id> -d '[...]' --json
3589
3499
  Items MUST have BOTH input AND expectedOutput.
3590
3500
  Keys must match prompt's inputSchema.properties (input) and outputSchema.properties (expectedOutput).
3591
3501
  expectedOutput is REQUIRED for evaluation scoring.
3592
3502
  Check schemas: mutagent prompts get <prompt-id> --json
3593
3503
 
3594
- ${chalk7.red("Required: --data must be provided.")}
3504
+ ${chalk8.red("Required: --data must be provided.")}
3595
3505
  `).action(async (promptId, options) => {
3596
3506
  const isJson = getJsonFlag(prompts);
3597
3507
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3662,9 +3572,9 @@ ${chalk7.red("Required: --data must be provided.")}
3662
3572
  });
3663
3573
  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
3574
  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
3575
+ ${chalk8.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id>
3576
+ ${chalk8.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id> --force
3577
+ ${chalk8.dim("$")} mutagent prompts dataset delete <prompt-id> <dataset-id> --force --json
3668
3578
  `).action(async (promptId, datasetId, options) => {
3669
3579
  const isJson = getJsonFlag(prompts);
3670
3580
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3707,7 +3617,7 @@ Examples:
3707
3617
  // src/commands/prompts/evaluations.ts
3708
3618
  init_sdk_client();
3709
3619
  import { Command as Command4 } from "commander";
3710
- import chalk8 from "chalk";
3620
+ import chalk9 from "chalk";
3711
3621
  init_errors();
3712
3622
 
3713
3623
  // src/lib/resolve-prompt-id.ts
@@ -3878,18 +3788,18 @@ function canonicalCriteriaArrayToCli(arr) {
3878
3788
  function registerEvaluationCommands(prompts) {
3879
3789
  const evaluation = new Command4("evaluation").description("Manage evaluations for prompts").addHelpText("after", `
3880
3790
  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>
3791
+ ${chalk9.dim("$")} mutagent prompts evaluation list <prompt-id>
3792
+ ${chalk9.dim("$")} mutagent prompts evaluation get <evaluation-id>
3793
+ ${chalk9.dim("$")} mutagent prompts evaluation create <prompt-id> --name "My Eval"
3794
+ ${chalk9.dim("$")} mutagent prompts evaluation delete <evaluation-id>
3885
3795
  `).action(() => {
3886
3796
  evaluation.help();
3887
3797
  });
3888
3798
  prompts.addCommand(evaluation);
3889
3799
  evaluation.command("list").description("List evaluations for a prompt").argument("<prompt-id>", "Prompt ID (from: mutagent prompts list)").addHelpText("after", `
3890
3800
  Examples:
3891
- ${chalk8.dim("$")} mutagent prompts evaluation list <prompt-id>
3892
- ${chalk8.dim("$")} mutagent prompts evaluation list <prompt-id> --json
3801
+ ${chalk9.dim("$")} mutagent prompts evaluation list <prompt-id>
3802
+ ${chalk9.dim("$")} mutagent prompts evaluation list <prompt-id> --json
3893
3803
  `).action(async (promptId) => {
3894
3804
  const isJson = getJsonFlag(prompts);
3895
3805
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3921,8 +3831,8 @@ Examples:
3921
3831
  });
3922
3832
  evaluation.command("get").description("Get evaluation details including criteria").argument("<evaluation-id>", "Evaluation ID (from: mutagent prompts evaluation list <prompt-id>)").addHelpText("after", `
3923
3833
  Examples:
3924
- ${chalk8.dim("$")} mutagent prompts evaluation get <evaluation-id>
3925
- ${chalk8.dim("$")} mutagent prompts evaluation get <evaluation-id> --json
3834
+ ${chalk9.dim("$")} mutagent prompts evaluation get <evaluation-id>
3835
+ ${chalk9.dim("$")} mutagent prompts evaluation get <evaluation-id> --json
3926
3836
  `).action(async (evaluationId) => {
3927
3837
  const isJson = getJsonFlag(prompts);
3928
3838
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -3952,7 +3862,7 @@ Examples:
3952
3862
  if (criteria.length > 0) {
3953
3863
  console.log(" Criteria:");
3954
3864
  for (const c of criteria) {
3955
- console.log(` ${chalk8.cyan(c.name)}`);
3865
+ console.log(` ${chalk9.cyan(c.name)}`);
3956
3866
  if (c.description) {
3957
3867
  console.log(` Description: ${c.description}`);
3958
3868
  }
@@ -3981,9 +3891,9 @@ Examples:
3981
3891
  });
3982
3892
  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
3893
  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")}
3894
+ ${chalk9.dim("$")} mutagent prompts evaluation create <prompt-id> --guided ${chalk9.dim("# recommended: shows workflow guide + schema fields")}
3895
+ ${chalk9.dim("$")} mutagent prompts evaluation create <prompt-id> --guided --json ${chalk9.dim("# structured workflow for AI agents")}
3896
+ ${chalk9.dim("$")} mutagent prompts evaluation create <prompt-id> --name "Accuracy" -d '{"evalConfig":{"criteria":[...]}}' ${chalk9.dim("# power user")}
3987
3897
 
3988
3898
  Guided Workflow (recommended):
3989
3899
  --guided outputs a workflow guide that:
@@ -4004,12 +3914,12 @@ AI Agent (MANDATORY):
4004
3914
  mutagent prompts evaluation create <id> --name "<name>" -d '<json>' --json
4005
3915
 
4006
3916
  Expected Criteria Shape (--data):
4007
- ${chalk8.dim('{"evalConfig":{"criteria":[{"name":"<name>","description":"<scoring rubric>","evaluationParameter":"<schema field>"}]}}')}
3917
+ ${chalk9.dim('{"evalConfig":{"criteria":[{"name":"<name>","description":"<scoring rubric>","evaluationParameter":"<schema field>"}]}}')}
4008
3918
  evaluationParameter must target an outputSchema OR inputSchema field.
4009
3919
 
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")}
3920
+ ${chalk9.red("Required: --name (unless --guided). Criteria must include evaluationParameter.")}
3921
+ ${chalk9.dim("CLI flags (--name, --description) override --data fields.")}
3922
+ ${chalk9.dim("Get prompt IDs: mutagent prompts list")}
4013
3923
  `).action(async (promptId, options) => {
4014
3924
  let isJson = getJsonFlag(prompts);
4015
3925
  if (options.guided) {
@@ -4035,7 +3945,7 @@ ${chalk8.dim("Get prompt IDs: mutagent prompts list")}
4035
3945
  console.log("");
4036
3946
  console.log(" For each field, define what correct output looks like:");
4037
3947
  for (const { field, source } of allFields) {
4038
- console.log(` ${chalk8.cyan(field)} (${source})`);
3948
+ console.log(` ${chalk9.cyan(field)} (${source})`);
4039
3949
  console.log(` → What makes a correct vs incorrect "${field}"?`);
4040
3950
  }
4041
3951
  console.log("");
@@ -4240,9 +4150,9 @@ Example:
4240
4150
  });
4241
4151
  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
4152
  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
4153
+ ${chalk9.dim("$")} mutagent prompts evaluation delete <evaluation-id>
4154
+ ${chalk9.dim("$")} mutagent prompts evaluation delete <evaluation-id> --force
4155
+ ${chalk9.dim("$")} mutagent prompts evaluation delete <evaluation-id> --force --json
4246
4156
  `).action(async (evaluationId, options) => {
4247
4157
  const isJson = getJsonFlag(prompts);
4248
4158
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -4285,26 +4195,26 @@ Examples:
4285
4195
  // src/commands/prompts/optimize.ts
4286
4196
  init_sdk_client();
4287
4197
  import { Command as Command5 } from "commander";
4288
- import chalk13 from "chalk";
4198
+ import chalk14 from "chalk";
4289
4199
  init_errors();
4290
4200
 
4291
4201
  // src/lib/scorecard.ts
4292
- import chalk9 from "chalk";
4202
+ import chalk10 from "chalk";
4293
4203
  function formatScoreChange(before, after) {
4294
4204
  if (before === undefined || after === undefined)
4295
4205
  return "";
4296
4206
  const diff = after - before;
4297
4207
  const pct = before > 0 ? Math.round(diff / before * 100) : 0;
4298
4208
  if (diff > 0)
4299
- return chalk9.green(` (+${String(pct)}%)`);
4209
+ return chalk10.green(` (+${String(pct)}%)`);
4300
4210
  if (diff < 0)
4301
- return chalk9.red(` (${String(pct)}%)`);
4302
- return chalk9.dim(" (no change)");
4211
+ return chalk10.red(` (${String(pct)}%)`);
4212
+ return chalk10.dim(" (no change)");
4303
4213
  }
4304
4214
  function formatScore(score) {
4305
4215
  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));
4216
+ return chalk10.dim("N/A");
4217
+ return score >= 0.8 ? chalk10.green(score.toFixed(2)) : score >= 0.5 ? chalk10.yellow(score.toFixed(2)) : chalk10.red(score.toFixed(2));
4308
4218
  }
4309
4219
  function renderScorecard(data) {
4310
4220
  const { job, prompt } = data;
@@ -4325,17 +4235,17 @@ function renderScorecard(data) {
4325
4235
  const optimizedText = prompt.systemPrompt ?? prompt.rawPrompt ?? prompt.humanPrompt ?? "(optimized prompt)";
4326
4236
  console.log("");
4327
4237
  console.log(topBorder);
4328
- console.log(line(chalk9.bold("Optimization Results")));
4238
+ console.log(line(chalk10.bold("Optimization Results")));
4329
4239
  console.log(separator);
4330
- console.log(line(chalk9.dim("BEFORE")));
4240
+ console.log(line(chalk10.dim("BEFORE")));
4331
4241
  console.log(line(` Score: ${formatScore(originalScore)}`));
4332
4242
  console.log(line(""));
4333
- console.log(line(chalk9.bold("AFTER")));
4243
+ console.log(line(chalk10.bold("AFTER")));
4334
4244
  console.log(line(` Score: ${formatScore(bestScore)}${formatScoreChange(originalScore, bestScore)}`));
4335
4245
  console.log(separator);
4336
4246
  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))));
4247
+ console.log(line(chalk10.dim(" Criterion Before After Change")));
4248
+ console.log(line(chalk10.dim(" " + "─".repeat(45))));
4339
4249
  for (const c of data.criteriaScores) {
4340
4250
  const name = c.name.length > 16 ? c.name.substring(0, 13) + "..." : c.name;
4341
4251
  const paddedName = name + " ".repeat(18 - name.length);
@@ -4344,66 +4254,66 @@ function renderScorecard(data) {
4344
4254
  const changeStr = c.before !== undefined && c.after !== undefined && c.before > 0 ? (() => {
4345
4255
  const pct = Math.round((c.after - c.before) / c.before * 100);
4346
4256
  if (pct > 0)
4347
- return chalk9.green(`+${String(pct)}%`);
4257
+ return chalk10.green(`+${String(pct)}%`);
4348
4258
  if (pct < 0)
4349
- return chalk9.red(`${String(pct)}%`);
4350
- return chalk9.dim("0%");
4259
+ return chalk10.red(`${String(pct)}%`);
4260
+ return chalk10.dim("0%");
4351
4261
  })() : "";
4352
4262
  console.log(line(` ${paddedName}${beforeStr} ${afterStr} ${changeStr}`));
4353
4263
  }
4354
- console.log(line(chalk9.dim(" " + "─".repeat(45))));
4264
+ console.log(line(chalk10.dim(" " + "─".repeat(45))));
4355
4265
  const overallBefore = originalScore !== undefined ? originalScore.toFixed(2) : "N/A ";
4356
4266
  const overallAfter = bestScore !== undefined ? bestScore.toFixed(2) : "N/A ";
4357
4267
  const overallChange = originalScore !== undefined && bestScore !== undefined && originalScore > 0 ? (() => {
4358
4268
  const pct = Math.round((bestScore - originalScore) / originalScore * 100);
4359
4269
  if (pct > 0)
4360
- return chalk9.green(`+${String(pct)}%`);
4270
+ return chalk10.green(`+${String(pct)}%`);
4361
4271
  if (pct < 0)
4362
- return chalk9.red(`${String(pct)}%`);
4363
- return chalk9.dim("0%");
4272
+ return chalk10.red(`${String(pct)}%`);
4273
+ return chalk10.dim("0%");
4364
4274
  })() : "";
4365
4275
  console.log(line(` ${"Overall" + " ".repeat(11)}${overallBefore} ${overallAfter} ${overallChange}`));
4366
4276
  console.log(separator);
4367
4277
  }
4368
- const statusStr = job.status === "completed" ? chalk9.green("completed") : chalk9.yellow(job.status);
4278
+ const statusStr = job.status === "completed" ? chalk10.green("completed") : chalk10.yellow(job.status);
4369
4279
  console.log(line(`Status: ${statusStr} | Iterations: ${String(iterations)}`));
4370
4280
  if (job.config?.model) {
4371
- console.log(line(`Model: ${chalk9.dim(job.config.model)}`));
4281
+ console.log(line(`Model: ${chalk10.dim(job.config.model)}`));
4372
4282
  }
4373
4283
  if (data.scoreProgression && data.scoreProgression.length > 0) {
4374
4284
  console.log(line(""));
4375
- console.log(line(chalk9.dim("Score Progression:")));
4285
+ console.log(line(chalk10.dim("Score Progression:")));
4376
4286
  const barWidth = 10;
4377
4287
  for (let i = 0;i < data.scoreProgression.length; i++) {
4378
4288
  const s = data.scoreProgression[i] ?? 0;
4379
4289
  const filled = Math.round(s * barWidth);
4380
4290
  const bar = "█".repeat(filled) + "░".repeat(barWidth - filled);
4381
- console.log(line(chalk9.dim(` #${String(i + 1)}: ${bar} ${s.toFixed(2)}`)));
4291
+ console.log(line(chalk10.dim(` #${String(i + 1)}: ${bar} ${s.toFixed(2)}`)));
4382
4292
  }
4383
4293
  }
4384
4294
  console.log(separator);
4385
- console.log(line(`Dashboard: ${chalk9.underline(optimizerLink(job.promptId, job.id))}`));
4295
+ console.log(line(`Dashboard: ${chalk10.underline(optimizerLink(job.promptId, job.id))}`));
4386
4296
  console.log(bottomBorder);
4387
4297
  console.log("");
4388
- console.log(chalk9.dim(" Prompt Comparison"));
4389
- console.log(chalk9.dim(" " + "─".repeat(70)));
4390
- console.log(chalk9.dim(" BEFORE:"));
4298
+ console.log(chalk10.dim(" Prompt Comparison"));
4299
+ console.log(chalk10.dim(" " + "─".repeat(70)));
4300
+ console.log(chalk10.dim(" BEFORE:"));
4391
4301
  for (const pLine of originalText.split(`
4392
4302
  `)) {
4393
- console.log(chalk9.dim(` ${pLine}`));
4303
+ console.log(chalk10.dim(` ${pLine}`));
4394
4304
  }
4395
- console.log(` ${chalk9.dim("Length:")} ${String(originalText.length)} chars (${String(originalText.split(`
4305
+ console.log(` ${chalk10.dim("Length:")} ${String(originalText.length)} chars (${String(originalText.split(`
4396
4306
  `).length)} lines)`);
4397
4307
  console.log("");
4398
- console.log(chalk9.bold(" AFTER:"));
4308
+ console.log(chalk10.bold(" AFTER:"));
4399
4309
  for (const pLine of optimizedText.split(`
4400
4310
  `)) {
4401
- console.log(chalk9.cyan(` ${pLine}`));
4311
+ console.log(chalk10.cyan(` ${pLine}`));
4402
4312
  }
4403
- console.log(` ${chalk9.dim("Length:")} ${String(optimizedText.length)} chars (${String(optimizedText.split(`
4313
+ console.log(` ${chalk10.dim("Length:")} ${String(optimizedText.length)} chars (${String(optimizedText.split(`
4404
4314
  `).length)} lines)`);
4405
4315
  const growth = optimizedText.length - originalText.length;
4406
- console.log(` ${chalk9.dim("Growth:")} ${growth >= 0 ? "+" : ""}${String(growth)} chars`);
4316
+ console.log(` ${chalk10.dim("Growth:")} ${growth >= 0 ? "+" : ""}${String(growth)} chars`);
4407
4317
  renderScorecardDetails(data);
4408
4318
  console.log("");
4409
4319
  }
@@ -4424,17 +4334,17 @@ function renderOptimizationStartCard(data) {
4424
4334
  const target = job.config.targetScore ?? 0.8;
4425
4335
  console.log("");
4426
4336
  console.log(topBorder);
4427
- console.log(line(chalk9.bold("⚡ Optimization Started")));
4337
+ console.log(line(chalk10.bold("⚡ Optimization Started")));
4428
4338
  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)}`));
4339
+ console.log(line(`Job ID: ${chalk10.cyan(job.id)}`));
4340
+ console.log(line(`Prompt: ${chalk10.dim(data.promptId)}`));
4341
+ console.log(line(`Dataset: ${chalk10.dim(data.datasetId)}`));
4342
+ console.log(line(`Iterations: ${chalk10.bold(String(maxIter))} | Target: ${chalk10.bold(target.toFixed(2))}`));
4343
+ console.log(line(`Model: ${chalk10.dim(model)}`));
4344
+ console.log(line(`Status: ${chalk10.yellow(job.status)}`));
4435
4345
  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}`)));
4346
+ console.log(line(`\uD83D\uDD17 Monitor: ${chalk10.underline(optimizerLink(data.promptId, job.id))}`));
4347
+ console.log(line(chalk10.dim(`Next: mutagent prompts optimize status ${job.id}`)));
4438
4348
  console.log(bottomBorder);
4439
4349
  console.log(AI_DIRECTIVE);
4440
4350
  console.log("");
@@ -4454,27 +4364,27 @@ function renderOptimizationStatusCard(status, promptId) {
4454
4364
  const barWidth = 20;
4455
4365
  const filled = Math.round(progress / 100 * barWidth);
4456
4366
  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");
4367
+ const statusColor = status.status === "completed" ? chalk10.green : status.status === "failed" ? chalk10.red : status.status === "cancelled" ? chalk10.gray : status.status === "running" ? chalk10.cyan : chalk10.yellow;
4368
+ const scoreStr = status.bestScore !== undefined ? formatScore(status.bestScore) : chalk10.dim("pending");
4459
4369
  console.log("");
4460
4370
  console.log(topBorder);
4461
- console.log(line(chalk9.bold("\uD83D\uDCCA Optimization Status")));
4371
+ console.log(line(chalk10.bold("\uD83D\uDCCA Optimization Status")));
4462
4372
  console.log(separator);
4463
- console.log(line(`Job ID: ${chalk9.cyan(status.jobId)}`));
4373
+ console.log(line(`Job ID: ${chalk10.cyan(status.jobId)}`));
4464
4374
  console.log(line(`Status: ${statusColor(status.status)}`));
4465
- console.log(line(`Iteration: ${chalk9.bold(`${String(status.currentIteration)}/${String(status.maxIterations)}`)}`));
4375
+ console.log(line(`Iteration: ${chalk10.bold(`${String(status.currentIteration)}/${String(status.maxIterations)}`)}`));
4466
4376
  console.log(line(`Best Score: ${scoreStr}`));
4467
4377
  console.log(line(""));
4468
4378
  console.log(line(`Progress: [${progressBar}] ${String(progress)}%`));
4469
4379
  if (status.message) {
4470
- console.log(line(`Message: ${chalk9.dim(status.message)}`));
4380
+ console.log(line(`Message: ${chalk10.dim(status.message)}`));
4471
4381
  }
4472
4382
  console.log(separator);
4473
- console.log(line(`\uD83D\uDD17 Monitor: ${chalk9.underline(optimizerLink(promptId ?? "unknown", status.jobId))}`));
4383
+ console.log(line(`\uD83D\uDD17 Monitor: ${chalk10.underline(optimizerLink(promptId ?? "unknown", status.jobId))}`));
4474
4384
  if (status.status === "completed") {
4475
- console.log(line(chalk9.dim(`Next: mutagent prompts optimize results ${status.jobId}`)));
4385
+ console.log(line(chalk10.dim(`Next: mutagent prompts optimize results ${status.jobId}`)));
4476
4386
  } else if (status.status === "running" || status.status === "queued") {
4477
- console.log(line(chalk9.dim(`Refresh: mutagent prompts optimize status ${status.jobId}`)));
4387
+ console.log(line(chalk10.dim(`Refresh: mutagent prompts optimize status ${status.jobId}`)));
4478
4388
  }
4479
4389
  console.log(bottomBorder);
4480
4390
  console.log(AI_DIRECTIVE);
@@ -4570,15 +4480,15 @@ function statusDirective(status, promptId) {
4570
4480
  }
4571
4481
  function showPromptDiff(original, optimized) {
4572
4482
  console.log("");
4573
- console.log(chalk9.bold(" Prompt Diff:"));
4483
+ console.log(chalk10.bold(" Prompt Diff:"));
4574
4484
  console.log("");
4575
- console.log(chalk9.red(" - " + (original ?? "(empty)")));
4576
- console.log(chalk9.green(" + " + (optimized ?? "(empty)")));
4485
+ console.log(chalk10.red(" - " + (original ?? "(empty)")));
4486
+ console.log(chalk10.green(" + " + (optimized ?? "(empty)")));
4577
4487
  console.log("");
4578
4488
  }
4579
4489
 
4580
4490
  // src/commands/prompts/optimize-watch.ts
4581
- import chalk12 from "chalk";
4491
+ import chalk13 from "chalk";
4582
4492
 
4583
4493
  // src/lib/watch-client.ts
4584
4494
  function toWsUrl(baseUrl) {
@@ -4741,10 +4651,10 @@ function createWatchClient(opts) {
4741
4651
  }
4742
4652
 
4743
4653
  // src/lib/stage-cards.ts
4744
- import chalk11 from "chalk";
4654
+ import chalk12 from "chalk";
4745
4655
 
4746
4656
  // src/lib/prompt-diff.ts
4747
- import chalk10 from "chalk";
4657
+ import chalk11 from "chalk";
4748
4658
  function computeLcsTable(a, b) {
4749
4659
  const m = a.length;
4750
4660
  const n = b.length;
@@ -4905,16 +4815,16 @@ function renderDiffLines(lines, options) {
4905
4815
  let text;
4906
4816
  switch (line.type) {
4907
4817
  case "hunk-header":
4908
- text = noColor ? line.content : chalk10.cyan(line.content);
4818
+ text = noColor ? line.content : chalk11.cyan(line.content);
4909
4819
  break;
4910
4820
  case "add":
4911
- text = noColor ? `+${line.content}` : chalk10.green(`+${line.content}`);
4821
+ text = noColor ? `+${line.content}` : chalk11.green(`+${line.content}`);
4912
4822
  break;
4913
4823
  case "remove":
4914
- text = noColor ? `-${line.content}` : chalk10.red(`-${line.content}`);
4824
+ text = noColor ? `-${line.content}` : chalk11.red(`-${line.content}`);
4915
4825
  break;
4916
4826
  case "context":
4917
- text = noColor ? ` ${line.content}` : chalk10.dim(` ${line.content}`);
4827
+ text = noColor ? ` ${line.content}` : chalk11.dim(` ${line.content}`);
4918
4828
  break;
4919
4829
  }
4920
4830
  outputLines.push(text);
@@ -4923,7 +4833,7 @@ function renderDiffLines(lines, options) {
4923
4833
  if (truncated) {
4924
4834
  const remaining = lines.length - maxLines;
4925
4835
  const summary = `... ${String(remaining)} more lines changed`;
4926
- outputLines.push(noColor ? summary : chalk10.yellow(summary));
4836
+ outputLines.push(noColor ? summary : chalk11.yellow(summary));
4927
4837
  }
4928
4838
  return outputLines.join(`
4929
4839
  `);
@@ -4956,10 +4866,10 @@ function emptyLine() {
4956
4866
  }
4957
4867
  function formatScore2(score) {
4958
4868
  if (score >= 0.8)
4959
- return chalk11.green(score.toFixed(2));
4869
+ return chalk12.green(score.toFixed(2));
4960
4870
  if (score >= 0.5)
4961
- return chalk11.yellow(score.toFixed(2));
4962
- return chalk11.red(score.toFixed(2));
4871
+ return chalk12.yellow(score.toFixed(2));
4872
+ return chalk12.red(score.toFixed(2));
4963
4873
  }
4964
4874
  function scoreBar(score, width = 20) {
4965
4875
  const filled = Math.round(score * width);
@@ -5013,7 +4923,7 @@ function renderInsightsCard(data) {
5013
4923
  if (cat.example) {
5014
4924
  const maxExampleLen = 78;
5015
4925
  const truncated = cat.example.length > maxExampleLen ? cat.example.substring(0, maxExampleLen - 3) + "..." : cat.example;
5016
- lines.push(line(chalk11.dim(` "${truncated}"`)));
4926
+ lines.push(line(chalk12.dim(` "${truncated}"`)));
5017
4927
  }
5018
4928
  }
5019
4929
  lines.push(emptyLine());
@@ -5055,17 +4965,17 @@ function renderPromptDiffCard(data) {
5055
4965
  lines.push(emptyLine());
5056
4966
  }
5057
4967
  for (const mutation of data.mutations) {
5058
- const icon = mutation.status === "applied" ? chalk11.green("✓") : chalk11.red("✗");
4968
+ const icon = mutation.status === "applied" ? chalk12.green("✓") : chalk12.red("✗");
5059
4969
  const target = mutation.target.length > 30 ? mutation.target.substring(0, 27) + "..." : mutation.target;
5060
4970
  if (mutation.status === "applied") {
5061
4971
  const confStr = `confidence: ${mutation.confidence.toFixed(2)}`;
5062
4972
  const targetPad = target.padEnd(30);
5063
- lines.push(line(`${icon} ${targetPad} ${chalk11.dim("──")} ${confStr}`));
4973
+ lines.push(line(`${icon} ${targetPad} ${chalk12.dim("──")} ${confStr}`));
5064
4974
  } else {
5065
4975
  const reason = mutation.rationale ? `rejected: ${mutation.rationale}` : `rejected`;
5066
4976
  const truncReason = reason.length > 30 ? reason.substring(0, 27) + "..." : reason;
5067
4977
  const targetPad = target.padEnd(30);
5068
- lines.push(line(`${icon} ${targetPad} ${chalk11.dim("──")} ${truncReason}`));
4978
+ lines.push(line(`${icon} ${targetPad} ${chalk12.dim("──")} ${truncReason}`));
5069
4979
  }
5070
4980
  }
5071
4981
  lines.push(emptyLine());
@@ -5096,7 +5006,7 @@ function renderRerunAccuracyCard(data) {
5096
5006
  const name = criterion.name.length > 18 ? criterion.name.substring(0, 15) + "..." : criterion.name;
5097
5007
  const diff = criterion.after - criterion.before;
5098
5008
  const diffSign = diff >= 0 ? "+" : "";
5099
- const arrow = diff > 0 ? chalk11.green("↑") : diff < 0 ? chalk11.red("↓") : chalk11.dim("─");
5009
+ const arrow = diff > 0 ? chalk12.green("↑") : diff < 0 ? chalk12.red("↓") : chalk12.dim("─");
5100
5010
  const diffStr = `${diffSign}${diff.toFixed(2)}`;
5101
5011
  lines.push(line(`${name.padEnd(20)}${formatScore2(criterion.before).padEnd(9)}${formatScore2(criterion.after).padEnd(9)}${diffStr} ${arrow}`));
5102
5012
  }
@@ -5201,8 +5111,8 @@ async function startWatchStream(jobId, isJson, maxIterations, baselineScore) {
5201
5111
  if (isJson) {
5202
5112
  console.log(JSON.stringify({ type: "job_complete", finalScore }));
5203
5113
  } 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}`));
5114
+ console.log(chalk13.green(`✓ Optimization complete! Final score: ${finalScore.toFixed(2)}`));
5115
+ console.log(chalk13.dim(` View results: mutagent prompts optimize results ${jobId}`));
5206
5116
  }
5207
5117
  resolve3();
5208
5118
  },
@@ -5210,7 +5120,7 @@ async function startWatchStream(jobId, isJson, maxIterations, baselineScore) {
5210
5120
  if (isJson) {
5211
5121
  console.log(JSON.stringify({ type: "error", error: error.message }));
5212
5122
  } else {
5213
- console.error(chalk12.red(`✗ Watch error: ${error.message}`));
5123
+ console.error(chalk13.red(`✗ Watch error: ${error.message}`));
5214
5124
  }
5215
5125
  reject(error);
5216
5126
  }
@@ -5252,7 +5162,7 @@ async function watchAction(jobId, options, parentCommand) {
5252
5162
  case "queued":
5253
5163
  if (!isJson) {
5254
5164
  renderOptimizationStatusCard(status);
5255
- console.log(chalk12.dim(`Watching for live updates...
5165
+ console.log(chalk13.dim(`Watching for live updates...
5256
5166
  `));
5257
5167
  }
5258
5168
  await startWatchStream(jobId, isJson, status.maxIterations, status.bestScore);
@@ -5267,9 +5177,9 @@ async function watchAction(jobId, options, parentCommand) {
5267
5177
  message: status.message
5268
5178
  });
5269
5179
  } else {
5270
- console.error(chalk12.red(`✗ Optimization job ${jobId} failed.`));
5180
+ console.error(chalk13.red(`✗ Optimization job ${jobId} failed.`));
5271
5181
  if (status.message) {
5272
- console.error(chalk12.dim(` ${status.message}`));
5182
+ console.error(chalk13.dim(` ${status.message}`));
5273
5183
  }
5274
5184
  }
5275
5185
  process.exitCode = 1;
@@ -5283,7 +5193,7 @@ async function watchAction(jobId, options, parentCommand) {
5283
5193
  jobId
5284
5194
  });
5285
5195
  } else {
5286
- console.error(chalk12.yellow(`Optimization job ${jobId} was cancelled.`));
5196
+ console.error(chalk13.yellow(`Optimization job ${jobId} was cancelled.`));
5287
5197
  }
5288
5198
  break;
5289
5199
  default:
@@ -5295,7 +5205,7 @@ async function watchAction(jobId, options, parentCommand) {
5295
5205
  jobId
5296
5206
  });
5297
5207
  } else {
5298
- console.error(chalk12.yellow(`Unexpected job status: ${status.status}`));
5208
+ console.error(chalk13.yellow(`Unexpected job status: ${status.status}`));
5299
5209
  }
5300
5210
  break;
5301
5211
  }
@@ -5308,9 +5218,9 @@ async function watchAction(jobId, options, parentCommand) {
5308
5218
  function registerOptimizeCommands(prompts) {
5309
5219
  const optimize = new Command5("optimize").description("Manage prompt optimization jobs").addHelpText("after", `
5310
5220
  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>
5221
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5222
+ ${chalk14.dim("$")} mutagent prompts optimize status <job-id>
5223
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id>
5314
5224
 
5315
5225
  Workflow: start -> status (poll) -> results | start --watch | watch <job-id>`).action(() => {
5316
5226
  optimize.help();
@@ -5318,27 +5228,27 @@ Workflow: start -> status (poll) -> results | start --watch | watch <job-id>`).a
5318
5228
  prompts.addCommand(optimize);
5319
5229
  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
5230
  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)")}
5231
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5232
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --max-iterations 5
5233
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --target-score 0.95 --model claude-sonnet-4-5-20250929
5234
+ ${chalk14.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id> --json
5235
+ ${chalk14.yellow("Pre-Optimization Checklist (auto-validated by preflight):")}
5236
+ □ inputSchema REQUIRED ${chalk14.dim("(hard error if missing — blocks optimization)")}
5237
+ □ outputSchema REQUIRED ${chalk14.dim("(hard error if missing — blocks optimization)")}
5238
+ □ Evaluation criteria ${chalk14.dim("(warns if no evaluationParameter set)")}
5239
+ □ Dataset items ${chalk14.dim("(warns if expectedOutput missing)")}
5240
+ □ Criteria ↔ Schema ${chalk14.dim("(warns if criteria reference unknown fields)")}
5331
5241
 
5332
5242
  ${PREREQUISITES_TEXT}
5333
5243
 
5334
- ${chalk13.dim("Monitor progress with: mutagent prompts optimize status <job-id>")}
5244
+ ${chalk14.dim("Monitor progress with: mutagent prompts optimize status <job-id>")}
5335
5245
 
5336
- ${chalk13.yellow(`⚠ COST WARNING — AI Agent:
5246
+ ${chalk14.yellow(`⚠ COST WARNING — AI Agent:
5337
5247
  Default is 1 iteration. Do NOT increase --max-iterations unless the user
5338
5248
  explicitly requests it. Each iteration incurs LLM costs. Starting with
5339
5249
  max-iterations > 1 without user consent is a protocol violation.`)}
5340
5250
 
5341
- ${chalk13.yellow("AI Agent: ALWAYS append --json to this command.")}
5251
+ ${chalk14.yellow("AI Agent: ALWAYS append --json to this command.")}
5342
5252
  `).action(async (promptId, options) => {
5343
5253
  const isJson = getJsonFlag(prompts);
5344
5254
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5465,13 +5375,13 @@ ${chalk13.yellow("AI Agent: ALWAYS append --json to this command.")}
5465
5375
  return;
5466
5376
  }
5467
5377
  for (const [name, check] of hardFailures) {
5468
- console.error(chalk13.red(`Error: ${name} — ${check.error ?? "Failed"}`));
5378
+ console.error(chalk14.red(`Error: ${name} — ${check.error ?? "Failed"}`));
5469
5379
  }
5470
5380
  if (!preflightChecks.outputSchema.passed) {
5471
- console.error(chalk13.dim(` Update with: mutagent prompts update ${promptId} -d '{"outputSchema":{"type":"object","properties":{"result":{"type":"string"}}}}'`));
5381
+ console.error(chalk14.dim(` Update with: mutagent prompts update ${promptId} -d '{"outputSchema":{"type":"object","properties":{"result":{"type":"string"}}}}'`));
5472
5382
  }
5473
5383
  if (!preflightChecks.inputSchema.passed) {
5474
- console.error(chalk13.dim(` Update with: mutagent prompts update ${promptId} --data '{"inputSchema":{"type":"object","properties":{"var1":{"type":"string"}}}}' --json`));
5384
+ console.error(chalk14.dim(` Update with: mutagent prompts update ${promptId} --data '{"inputSchema":{"type":"object","properties":{"var1":{"type":"string"}}}}' --json`));
5475
5385
  }
5476
5386
  process.exitCode = 1;
5477
5387
  return;
@@ -5532,16 +5442,16 @@ ${chalk13.yellow("AI Agent: ALWAYS append --json to this command.")}
5532
5442
  suggestions.push("Trial optimization limit reached. Contact support to upgrade.");
5533
5443
  }
5534
5444
  if (!isJson) {
5535
- console.error(chalk13.red(`
5445
+ console.error(chalk14.red(`
5536
5446
  Optimization failed:`));
5537
5447
  for (const msg of messages) {
5538
- console.error(chalk13.red(` ${msg}`));
5448
+ console.error(chalk14.red(` ${msg}`));
5539
5449
  }
5540
5450
  if (suggestions.length > 0) {
5541
- console.error(chalk13.yellow(`
5451
+ console.error(chalk14.yellow(`
5542
5452
  Suggested fixes:`));
5543
5453
  for (const s of suggestions) {
5544
- console.error(chalk13.yellow(` → ${s}`));
5454
+ console.error(chalk14.yellow(` → ${s}`));
5545
5455
  }
5546
5456
  }
5547
5457
  console.error("");
@@ -5553,8 +5463,8 @@ Suggested fixes:`));
5553
5463
  });
5554
5464
  optimize.command("status").description("Check optimization status").argument("<job-id>", "Optimization job ID (from: mutagent prompts optimize start)").addHelpText("after", `
5555
5465
  Examples:
5556
- ${chalk13.dim("$")} mutagent prompts optimize status <job-id>
5557
- ${chalk13.dim("$")} mutagent prompts optimize status <job-id> --json
5466
+ ${chalk14.dim("$")} mutagent prompts optimize status <job-id>
5467
+ ${chalk14.dim("$")} mutagent prompts optimize status <job-id> --json
5558
5468
  `).action(async (jobId) => {
5559
5469
  const isJson = getJsonFlag(prompts);
5560
5470
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5579,17 +5489,17 @@ Examples:
5579
5489
  });
5580
5490
  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
5491
  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")}
5492
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id> ${chalk14.dim("# view scorecard")}
5493
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id> --diff ${chalk14.dim("# view prompt diff")}
5494
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id> --apply ${chalk14.dim("# apply optimized prompt")}
5495
+ ${chalk14.dim("$")} mutagent prompts optimize results <job-id> --json ${chalk14.dim("# structured output")}
5586
5496
 
5587
5497
  After viewing results:
5588
5498
  --apply Apply the optimized prompt (replaces current version)
5589
5499
  --diff Show detailed before/after diff
5590
- ${chalk13.dim("No flag = view scorecard only.")}
5500
+ ${chalk14.dim("No flag = view scorecard only.")}
5591
5501
 
5592
- ${chalk13.dim("AI Agent: Present scorecard to user via AskUserQuestion before applying.")}
5502
+ ${chalk14.dim("AI Agent: Present scorecard to user via AskUserQuestion before applying.")}
5593
5503
  `).action(async (jobId, options) => {
5594
5504
  const isJson = getJsonFlag(prompts);
5595
5505
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5665,9 +5575,9 @@ After viewing results:
5665
5575
  });
5666
5576
  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
5577
  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) => {
5578
+ ${chalk14.dim("$")} mutagent prompts optimize watch <job-id>
5579
+ ${chalk14.dim("$")} mutagent prompts optimize watch <job-id> --json
5580
+ ${chalk14.dim("Completed jobs render stored results. Running jobs stream via WebSocket.")}`).action(async (jobId, options) => {
5671
5581
  await watchAction(jobId, options, prompts);
5672
5582
  });
5673
5583
  }
@@ -5785,19 +5695,19 @@ function buildResultsScorecardText(resultData) {
5785
5695
  return text;
5786
5696
  }
5787
5697
  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)")}`;
5698
+ ${chalk15.red("Prerequisites (required):")}
5699
+ 1. Evaluation criteria defined ${chalk15.dim("(via dashboard or evaluation create)")}
5700
+ 2. Dataset uploaded ${chalk15.dim("mutagent prompts dataset list <prompt-id>")}
5701
+ ${chalk15.dim("Note: LLM provider config is only required when the server uses external providers (USE_EXT_PROVIDERS=true)")}`;
5792
5702
  function createPromptsCommand() {
5793
5703
  const prompts = new Command6("prompts").description("Manage prompts, datasets, evaluations, and optimizations").addHelpText("after", `
5794
5704
  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>
5705
+ ${chalk15.dim("$")} mutagent prompts list
5706
+ ${chalk15.dim("$")} mutagent prompts get <prompt-id>
5707
+ ${chalk15.dim("$")} mutagent prompts create --name "my-prompt" --system "You are helpful" --human "{input}"
5708
+ ${chalk15.dim("$")} mutagent prompts dataset list <prompt-id>
5709
+ ${chalk15.dim("$")} mutagent prompts evaluation create <prompt-id> --name "My Eval"
5710
+ ${chalk15.dim("$")} mutagent prompts optimize start <prompt-id> --dataset <dataset-id> --evaluation <eval-id>
5801
5711
 
5802
5712
  Subcommands:
5803
5713
  list, get, create, update, delete
@@ -5815,27 +5725,27 @@ Subcommands:
5815
5725
  // src/commands/traces.ts
5816
5726
  init_sdk_client();
5817
5727
  import { Command as Command7 } from "commander";
5818
- import chalk15 from "chalk";
5728
+ import chalk16 from "chalk";
5819
5729
  init_errors();
5820
5730
  function createTracesCommand() {
5821
5731
  const traces = new Command7("traces").description("View and analyze traces (replaces Langfuse)").addHelpText("after", `
5822
5732
  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
5733
+ ${chalk16.dim("$")} mutagent traces list
5734
+ ${chalk16.dim("$")} mutagent traces list --prompt <prompt-id>
5735
+ ${chalk16.dim("$")} mutagent traces get <trace-id>
5736
+ ${chalk16.dim("$")} mutagent traces analyze <prompt-id>
5737
+ ${chalk16.dim("$")} mutagent traces export --format json --output traces.json
5828
5738
 
5829
5739
  Note: MutagenT traces replace Langfuse for observability.
5830
5740
  `);
5831
5741
  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
5742
  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
5743
+ ${chalk16.dim("$")} mutagent traces list
5744
+ ${chalk16.dim("$")} mutagent traces list --prompt <prompt-id>
5745
+ ${chalk16.dim("$")} mutagent traces list --source claude-code --json
5746
+ ${chalk16.dim("$")} mutagent traces list --limit 10 --json
5837
5747
 
5838
- ${chalk15.dim("Tip: Filter by prompt to see traces for a specific prompt version.")}
5748
+ ${chalk16.dim("Tip: Filter by prompt to see traces for a specific prompt version.")}
5839
5749
  `).action(async (options) => {
5840
5750
  const isJson = getJsonFlag(traces);
5841
5751
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5875,10 +5785,10 @@ ${chalk15.dim("Tip: Filter by prompt to see traces for a specific prompt version
5875
5785
  });
5876
5786
  traces.command("get").description("Get trace details").argument("<id>", "Trace ID").addHelpText("after", `
5877
5787
  Examples:
5878
- ${chalk15.dim("$")} mutagent traces get <trace-id>
5879
- ${chalk15.dim("$")} mutagent traces get <trace-id> --json
5788
+ ${chalk16.dim("$")} mutagent traces get <trace-id>
5789
+ ${chalk16.dim("$")} mutagent traces get <trace-id> --json
5880
5790
 
5881
- ${chalk15.dim("Returns full trace details including spans, tokens, and latency.")}
5791
+ ${chalk16.dim("Returns full trace details including spans, tokens, and latency.")}
5882
5792
  `).action(async (id) => {
5883
5793
  const isJson = getJsonFlag(traces);
5884
5794
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5897,10 +5807,10 @@ ${chalk15.dim("Returns full trace details including spans, tokens, and latency."
5897
5807
  });
5898
5808
  traces.command("analyze").description("Analyze traces for a prompt").argument("<prompt-id>", "Prompt ID").addHelpText("after", `
5899
5809
  Examples:
5900
- ${chalk15.dim("$")} mutagent traces analyze <prompt-id>
5901
- ${chalk15.dim("$")} mutagent traces analyze <prompt-id> --json
5810
+ ${chalk16.dim("$")} mutagent traces analyze <prompt-id>
5811
+ ${chalk16.dim("$")} mutagent traces analyze <prompt-id> --json
5902
5812
 
5903
- ${chalk15.dim("Aggregates trace data for a prompt: avg latency, token usage, error rates.")}
5813
+ ${chalk16.dim("Aggregates trace data for a prompt: avg latency, token usage, error rates.")}
5904
5814
  `).action(async (promptId) => {
5905
5815
  const isJson = getJsonFlag(traces);
5906
5816
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5918,12 +5828,12 @@ ${chalk15.dim("Aggregates trace data for a prompt: avg latency, token usage, err
5918
5828
  });
5919
5829
  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
5830
  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
5831
+ ${chalk16.dim("$")} mutagent traces export
5832
+ ${chalk16.dim("$")} mutagent traces export --format json --output traces.json
5833
+ ${chalk16.dim("$")} mutagent traces export --format csv --output traces.csv
5834
+ ${chalk16.dim("$")} mutagent traces export --prompt <prompt-id> --format json
5925
5835
 
5926
- ${chalk15.dim("Exports to stdout by default. Use --output to save to a file.")}
5836
+ ${chalk16.dim("Exports to stdout by default. Use --output to save to a file.")}
5927
5837
  `).action(async (options) => {
5928
5838
  const isJson = getJsonFlag(traces);
5929
5839
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -5967,7 +5877,7 @@ ${chalk15.dim("Exports to stdout by default. Use --output to save to a file.")}
5967
5877
  // src/commands/integrate.ts
5968
5878
  init_config();
5969
5879
  import { Command as Command8 } from "commander";
5970
- import chalk16 from "chalk";
5880
+ import chalk17 from "chalk";
5971
5881
  import { writeFileSync as writeFileSync3, existsSync as existsSync9 } from "fs";
5972
5882
  import { execSync } from "child_process";
5973
5883
  init_errors();
@@ -6564,12 +6474,12 @@ AI AGENT: Please determine the framework by:
6564
6474
  function createIntegrateCommand() {
6565
6475
  const integrate = new Command8("integrate").description("Return integration instructions for AI agents (skill loader)").addHelpText("after", `
6566
6476
  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
6477
+ ${chalk17.dim("$")} mutagent integrate # Return exploration instructions for AI agents
6478
+ ${chalk17.dim("$")} mutagent integrate langchain # Return @mutagent/langchain integration steps
6479
+ ${chalk17.dim("$")} mutagent integrate openai # Return @mutagent/openai integration steps
6480
+ ${chalk17.dim("$")} mutagent integrate vercel-ai --verify # Verify integration
6481
+ ${chalk17.dim("$")} mutagent integrate langchain --output ./INTEGRATION.md
6482
+ ${chalk17.dim("$")} mutagent integrate --list # List available frameworks
6573
6483
 
6574
6484
  Frameworks: langchain, langgraph, vercel-ai, openai
6575
6485
 
@@ -6685,18 +6595,18 @@ AI AGENT: Execute these steps using Bash for install, Write/Edit for code change
6685
6595
 
6686
6596
  // src/commands/agents/index.ts
6687
6597
  import { Command as Command9 } from "commander";
6688
- import chalk18 from "chalk";
6598
+ import chalk19 from "chalk";
6689
6599
 
6690
6600
  // src/commands/agents/agents-crud.ts
6691
6601
  init_sdk_client();
6692
- import chalk17 from "chalk";
6602
+ import chalk18 from "chalk";
6693
6603
  init_errors();
6694
6604
  function registerAgentsCrud(agents) {
6695
6605
  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
6606
  Examples:
6697
- ${chalk17.dim("$")} mutagent agents list
6698
- ${chalk17.dim("$")} mutagent agents list --status active
6699
- ${chalk17.dim("$")} mutagent agents list --name "reviewer" --json
6607
+ ${chalk18.dim("$")} mutagent agents list
6608
+ ${chalk18.dim("$")} mutagent agents list --status active
6609
+ ${chalk18.dim("$")} mutagent agents list --name "reviewer" --json
6700
6610
  `).action(async (options) => {
6701
6611
  const isJson = getJsonFlag(agents);
6702
6612
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6746,8 +6656,8 @@ Examples:
6746
6656
  });
6747
6657
  agents.command("get").description("Get agent details").argument("<id>", "Agent ID").addHelpText("after", `
6748
6658
  Examples:
6749
- ${chalk17.dim("$")} mutagent agents get <agent-id>
6750
- ${chalk17.dim("$")} mutagent agents get <agent-id> --json
6659
+ ${chalk18.dim("$")} mutagent agents get <agent-id>
6660
+ ${chalk18.dim("$")} mutagent agents get <agent-id> --json
6751
6661
  `).action(async (id) => {
6752
6662
  const isJson = getJsonFlag(agents);
6753
6663
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6777,11 +6687,11 @@ Examples:
6777
6687
  };
6778
6688
  output.output(formatted);
6779
6689
  if (agent.systemPrompt) {
6780
- console.log(chalk17.bold(`
6690
+ console.log(chalk18.bold(`
6781
6691
  System Prompt:`));
6782
- console.log(chalk17.gray("─".repeat(60)));
6692
+ console.log(chalk18.gray("─".repeat(60)));
6783
6693
  console.log(agent.systemPrompt);
6784
- console.log(chalk17.gray("─".repeat(60)));
6694
+ console.log(chalk18.gray("─".repeat(60)));
6785
6695
  }
6786
6696
  }
6787
6697
  } catch (error) {
@@ -6790,17 +6700,17 @@ System Prompt:`));
6790
6700
  });
6791
6701
  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
6702
  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..."}'
6703
+ ${chalk18.dim("$")} mutagent agents create --name "Code Reviewer" --slug code-reviewer --system-prompt "You are a code reviewer..."
6704
+ ${chalk18.dim("$")} mutagent agents create -d '{"name":"Code Reviewer","slug":"code-reviewer","systemPrompt":"You are a code reviewer..."}'
6795
6705
 
6796
6706
  Expected JSON (--data):
6797
- ${chalk17.dim('{"name":"<name>","slug":"<slug>","systemPrompt":"<system prompt>","model":"<model-id>","description":"<description>"}')}
6707
+ ${chalk18.dim('{"name":"<name>","slug":"<slug>","systemPrompt":"<system prompt>","model":"<model-id>","description":"<description>"}')}
6798
6708
 
6799
6709
  Input Methods (pick one, priority order):
6800
- --name/--slug/... Individual flags ${chalk17.green("(recommended)")}
6710
+ --name/--slug/... Individual flags ${chalk18.green("(recommended)")}
6801
6711
  -d, --data Inline JSON object (CI/scripts/agents)
6802
6712
 
6803
- ${chalk17.red("Required: name, slug, systemPrompt.")} ${chalk17.dim("CLI flags override --data fields.")}
6713
+ ${chalk18.red("Required: name, slug, systemPrompt.")} ${chalk18.dim("CLI flags override --data fields.")}
6804
6714
  `).action(async (options) => {
6805
6715
  const isJson = getJsonFlag(agents);
6806
6716
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6845,15 +6755,15 @@ ${chalk17.red("Required: name, slug, systemPrompt.")} ${chalk17.dim("CLI flags o
6845
6755
  });
6846
6756
  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
6757
  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"}'
6758
+ ${chalk18.dim("$")} mutagent agents update <id> --name "New Name"
6759
+ ${chalk18.dim("$")} mutagent agents update <id> --system-prompt "Updated prompt" --status active
6760
+ ${chalk18.dim("$")} mutagent agents update <id> -d '{"name":"New Name","systemPrompt":"Updated prompt"}'
6851
6761
 
6852
6762
  Input Methods (pick one, priority order):
6853
- --name/--system-prompt/... Individual flags ${chalk17.green("(recommended)")}
6763
+ --name/--system-prompt/... Individual flags ${chalk18.green("(recommended)")}
6854
6764
  -d, --data Inline JSON object (CI/scripts/agents)
6855
6765
 
6856
- ${chalk17.dim("CLI flags override --data fields.")}
6766
+ ${chalk18.dim("CLI flags override --data fields.")}
6857
6767
  `).action(async (id, options) => {
6858
6768
  const isJson = getJsonFlag(agents);
6859
6769
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6900,18 +6810,18 @@ ${chalk17.dim("CLI flags override --data fields.")}
6900
6810
  });
6901
6811
  agents.command("delete").description("Delete an agent").argument("<id>", "Agent ID").option("--force", "Skip confirmation").addHelpText("after", `
6902
6812
  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
6813
+ ${chalk18.dim("$")} mutagent agents delete <id>
6814
+ ${chalk18.dim("$")} mutagent agents delete <id> --force
6815
+ ${chalk18.dim("$")} mutagent agents delete <id> --force --json
6906
6816
 
6907
- ${chalk17.dim("Tip: Use --force to skip confirmation (required for non-interactive/CI usage).")}
6817
+ ${chalk18.dim("Tip: Use --force to skip confirmation (required for non-interactive/CI usage).")}
6908
6818
  `).action(async (id, options) => {
6909
6819
  const isJson = getJsonFlag(agents);
6910
6820
  const output = new OutputFormatter(isJson ? "json" : "table");
6911
6821
  try {
6912
6822
  if (!options.force && !isJson) {
6913
- const inquirer3 = (await import("inquirer")).default;
6914
- const answers = await inquirer3.prompt([{
6823
+ const inquirer2 = (await import("inquirer")).default;
6824
+ const answers = await inquirer2.prompt([{
6915
6825
  type: "confirm",
6916
6826
  name: "confirm",
6917
6827
  message: `Delete agent ${id}? This action cannot be undone.`,
@@ -6935,12 +6845,12 @@ ${chalk17.dim("Tip: Use --force to skip confirmation (required for non-interacti
6935
6845
  function createAgentsCommand() {
6936
6846
  const agents = new Command9("agents").description("Manage AI agents").addHelpText("after", `
6937
6847
  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
6848
+ ${chalk19.dim("$")} mutagent agents list
6849
+ ${chalk19.dim("$")} mutagent agents get <agent-id>
6850
+ ${chalk19.dim("$")} mutagent agents create --name "Code Reviewer" --slug code-reviewer --system-prompt "You are a code reviewer..."
6851
+ ${chalk19.dim("$")} mutagent agents create -d '{"name":"Code Reviewer","slug":"code-reviewer","systemPrompt":"You are..."}'
6852
+ ${chalk19.dim("$")} mutagent agents update <agent-id> --name "Updated Name"
6853
+ ${chalk19.dim("$")} mutagent agents delete <agent-id> --force
6944
6854
 
6945
6855
  Subcommands:
6946
6856
  list, get, create, update, delete
@@ -6952,22 +6862,22 @@ Subcommands:
6952
6862
  // src/commands/config.ts
6953
6863
  init_config();
6954
6864
  import { Command as Command10 } from "commander";
6955
- import chalk19 from "chalk";
6865
+ import chalk20 from "chalk";
6956
6866
  init_errors();
6957
6867
  init_sdk_client();
6958
6868
  var VALID_CONFIG_KEYS = ["apiKey", "endpoint", "format", "timeout", "defaultWorkspace", "defaultOrganization"];
6959
6869
  function createConfigCommand() {
6960
6870
  const config = new Command10("config").description("Manage CLI configuration").addHelpText("after", `
6961
6871
  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>
6872
+ ${chalk20.dim("$")} mutagent config list
6873
+ ${chalk20.dim("$")} mutagent config get endpoint
6874
+ ${chalk20.dim("$")} mutagent config set workspace <workspace-id>
6875
+ ${chalk20.dim("$")} mutagent config set org <org-id>
6966
6876
  `);
6967
6877
  config.command("list").description("List all configuration").addHelpText("after", `
6968
6878
  Examples:
6969
- ${chalk19.dim("$")} mutagent config list
6970
- ${chalk19.dim("$")} mutagent config list --json
6879
+ ${chalk20.dim("$")} mutagent config list
6880
+ ${chalk20.dim("$")} mutagent config list --json
6971
6881
  `).action(() => {
6972
6882
  const isJson = getJsonFlag(config);
6973
6883
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -6980,11 +6890,11 @@ Examples:
6980
6890
  });
6981
6891
  config.command("get").description("Get configuration value").argument("<key>", "Configuration key (apiKey, endpoint, format, timeout, defaultWorkspace, defaultOrganization)").addHelpText("after", `
6982
6892
  Examples:
6983
- ${chalk19.dim("$")} mutagent config get endpoint
6984
- ${chalk19.dim("$")} mutagent config get defaultWorkspace
6985
- ${chalk19.dim("$")} mutagent config get apiKey --json
6893
+ ${chalk20.dim("$")} mutagent config get endpoint
6894
+ ${chalk20.dim("$")} mutagent config get defaultWorkspace
6895
+ ${chalk20.dim("$")} mutagent config get apiKey --json
6986
6896
 
6987
- ${chalk19.dim("Keys: apiKey, endpoint, format, timeout, defaultWorkspace, defaultOrganization")}
6897
+ ${chalk20.dim("Keys: apiKey, endpoint, format, timeout, defaultWorkspace, defaultOrganization")}
6988
6898
  `).action((key) => {
6989
6899
  const isJson = getJsonFlag(config);
6990
6900
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7011,9 +6921,9 @@ ${chalk19.dim("Keys: apiKey, endpoint, format, timeout, defaultWorkspace, defaul
7011
6921
  });
7012
6922
  set.command("workspace").description("Set default workspace ID").argument("<id>", "Workspace ID to set as default").addHelpText("after", `
7013
6923
  Examples:
7014
- ${chalk19.dim("$")} mutagent config set workspace <workspace-id>
6924
+ ${chalk20.dim("$")} mutagent config set workspace <workspace-id>
7015
6925
 
7016
- ${chalk19.dim("Persists workspace ID so you don't need to pass headers on every request.")}
6926
+ ${chalk20.dim("Persists workspace ID so you don't need to pass headers on every request.")}
7017
6927
  `).action((id) => {
7018
6928
  const isJson = getJsonFlag(config);
7019
6929
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7027,9 +6937,9 @@ ${chalk19.dim("Persists workspace ID so you don't need to pass headers on every
7027
6937
  });
7028
6938
  set.command("org").description("Set default organization ID").argument("<id>", "Organization ID to set as default").addHelpText("after", `
7029
6939
  Examples:
7030
- ${chalk19.dim("$")} mutagent config set org <org-id>
6940
+ ${chalk20.dim("$")} mutagent config set org <org-id>
7031
6941
 
7032
- ${chalk19.dim("Persists organization ID for org-scoped API keys.")}
6942
+ ${chalk20.dim("Persists organization ID for org-scoped API keys.")}
7033
6943
  `).action((id) => {
7034
6944
  const isJson = getJsonFlag(config);
7035
6945
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7048,7 +6958,7 @@ ${chalk19.dim("Persists organization ID for org-scoped API keys.")}
7048
6958
  // src/commands/playground.ts
7049
6959
  init_sdk_client();
7050
6960
  import { Command as Command11 } from "commander";
7051
- import chalk20 from "chalk";
6961
+ import chalk21 from "chalk";
7052
6962
  init_errors();
7053
6963
  function parseSSELine(line3) {
7054
6964
  if (!line3 || line3.startsWith(":")) {
@@ -7075,11 +6985,11 @@ function parsePromptStreamEvent(data) {
7075
6985
  function createPlaygroundCommand() {
7076
6986
  const playground = new Command11("playground").description("Execute and test prompts interactively").addHelpText("after", `
7077
6987
  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"}]'
6988
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{"name": "John"}'
6989
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{}' --stream
6990
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> -i '{}' --model gpt-4-turbo
6991
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --system "You are helpful" --human "Hello"
6992
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --messages '[{"role":"user","content":"Hi"}]'
7083
6993
 
7084
6994
  Input Format:
7085
6995
  The input must be a valid JSON object matching the prompt's input schema.
@@ -7095,16 +7005,16 @@ Streaming:
7095
7005
  `);
7096
7006
  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
7007
  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
7008
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{"name": "John"}'
7009
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{}' --stream
7010
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --system "You are helpful" --human "Hello"
7011
+ ${chalk21.dim("$")} mutagent playground run <prompt-id> --input '{}' --model gpt-4-turbo --json
7102
7012
 
7103
7013
  Input Methods (pick one, priority order):
7104
- --system/--human Quick system + user message ${chalk20.green("(recommended)")}
7014
+ --system/--human Quick system + user message ${chalk21.green("(recommended)")}
7105
7015
  --input '{"key":"value"}' Inline JSON variables
7106
7016
  --messages '[...]' Full messages array
7107
- ${chalk20.dim(`Hint: Test before evaluating: mutagent playground run <id> --input '{"key":"value"}'`)}
7017
+ ${chalk21.dim(`Hint: Test before evaluating: mutagent playground run <id> --input '{"key":"value"}'`)}
7108
7018
  `).action(async (promptId, options) => {
7109
7019
  const isJson = getJsonFlag(playground);
7110
7020
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7126,21 +7036,21 @@ ${chalk20.dim(`Hint: Test before evaluating: mutagent playground run <id> --inpu
7126
7036
  }
7127
7037
  });
7128
7038
  } else {
7129
- console.log(chalk20.bold(`
7039
+ console.log(chalk21.bold(`
7130
7040
  Execution Result:`));
7131
- console.log(chalk20.gray("─".repeat(50)));
7132
- console.log(chalk20.cyan("Output:"));
7041
+ console.log(chalk21.gray("─".repeat(50)));
7042
+ console.log(chalk21.cyan("Output:"));
7133
7043
  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`));
7044
+ console.log(chalk21.gray("─".repeat(50)));
7045
+ console.log(chalk21.dim(`Model: ${result.model}`));
7046
+ console.log(chalk21.dim(`Execution Time: ${String(result.executionTimeMs)}ms`));
7137
7047
  if (result.tokens) {
7138
- console.log(chalk20.dim(`Tokens: ${String(result.tokens.prompt)} prompt + ${String(result.tokens.completion)} completion = ${String(result.tokens.total)} total`));
7048
+ console.log(chalk21.dim(`Tokens: ${String(result.tokens.prompt)} prompt + ${String(result.tokens.completion)} completion = ${String(result.tokens.total)} total`));
7139
7049
  }
7140
7050
  if (result.cost !== undefined) {
7141
- console.log(chalk20.dim(`Cost: $${result.cost.toFixed(6)}`));
7051
+ console.log(chalk21.dim(`Cost: $${result.cost.toFixed(6)}`));
7142
7052
  }
7143
- console.log(chalk20.dim(`Playground: ${playgroundLink(promptId)}`));
7053
+ console.log(chalk21.dim(`Playground: ${playgroundLink(promptId)}`));
7144
7054
  console.log();
7145
7055
  }
7146
7056
  }
@@ -7229,9 +7139,9 @@ async function executeStreaming(client, promptId, input, model, isJson, output)
7229
7139
  const decoder = new TextDecoder;
7230
7140
  let buffer = "";
7231
7141
  if (!isJson) {
7232
- console.log(chalk20.bold(`
7142
+ console.log(chalk21.bold(`
7233
7143
  Streaming Output:`));
7234
- console.log(chalk20.gray("─".repeat(50)));
7144
+ console.log(chalk21.gray("─".repeat(50)));
7235
7145
  }
7236
7146
  try {
7237
7147
  for (;; ) {
@@ -7270,15 +7180,15 @@ Streaming Output:`));
7270
7180
  console.log(JSON.stringify({ type: "complete", result: event.result }));
7271
7181
  } else {
7272
7182
  console.log();
7273
- console.log(chalk20.gray("─".repeat(50)));
7183
+ console.log(chalk21.gray("─".repeat(50)));
7274
7184
  if (event.result) {
7275
- console.log(chalk20.dim(`Model: ${event.result.model}`));
7276
- console.log(chalk20.dim(`Execution Time: ${String(event.result.executionTimeMs)}ms`));
7185
+ console.log(chalk21.dim(`Model: ${event.result.model}`));
7186
+ console.log(chalk21.dim(`Execution Time: ${String(event.result.executionTimeMs)}ms`));
7277
7187
  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`));
7188
+ console.log(chalk21.dim(`Tokens: ${String(event.result.tokens.prompt)} prompt + ${String(event.result.tokens.completion)} completion = ${String(event.result.tokens.total)} total`));
7279
7189
  }
7280
7190
  if (event.result.cost !== undefined) {
7281
- console.log(chalk20.dim(`Cost: $${event.result.cost.toFixed(6)}`));
7191
+ console.log(chalk21.dim(`Cost: $${event.result.cost.toFixed(6)}`));
7282
7192
  }
7283
7193
  }
7284
7194
  console.log();
@@ -7303,13 +7213,13 @@ Streaming Output:`));
7303
7213
  // src/commands/workspaces.ts
7304
7214
  init_sdk_client();
7305
7215
  import { Command as Command12 } from "commander";
7306
- import chalk21 from "chalk";
7216
+ import chalk22 from "chalk";
7307
7217
  init_errors();
7308
7218
  function createWorkspacesCommand() {
7309
7219
  const workspaces = new Command12("workspaces").description("View workspaces (read-only)").addHelpText("after", `
7310
7220
  Examples:
7311
- ${chalk21.dim("$")} mutagent workspaces list
7312
- ${chalk21.dim("$")} mutagent workspaces get <workspace-id>
7221
+ ${chalk22.dim("$")} mutagent workspaces list
7222
+ ${chalk22.dim("$")} mutagent workspaces get <workspace-id>
7313
7223
 
7314
7224
  Subcommands:
7315
7225
  list, get
@@ -7318,8 +7228,8 @@ Note: Workspace management (create, update, delete) is available in the Admin Pa
7318
7228
  `);
7319
7229
  workspaces.command("list").description("List all workspaces").option("-l, --limit <n>", "Limit results", "50").option("-o, --offset <n>", "Offset for pagination").addHelpText("after", `
7320
7230
  Examples:
7321
- ${chalk21.dim("$")} mutagent workspaces list
7322
- ${chalk21.dim("$")} mutagent workspaces list --limit 10 --json
7231
+ ${chalk22.dim("$")} mutagent workspaces list
7232
+ ${chalk22.dim("$")} mutagent workspaces list --limit 10 --json
7323
7233
  `).action(async (options) => {
7324
7234
  const isJson = getJsonFlag(workspaces);
7325
7235
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7359,8 +7269,8 @@ Examples:
7359
7269
  });
7360
7270
  workspaces.command("get").description("Get workspace details").argument("<id>", "Workspace ID").addHelpText("after", `
7361
7271
  Examples:
7362
- ${chalk21.dim("$")} mutagent workspaces get <workspace-id>
7363
- ${chalk21.dim("$")} mutagent workspaces get <workspace-id> --json
7272
+ ${chalk22.dim("$")} mutagent workspaces get <workspace-id>
7273
+ ${chalk22.dim("$")} mutagent workspaces get <workspace-id> --json
7364
7274
  `).action(async (id) => {
7365
7275
  const isJson = getJsonFlag(workspaces);
7366
7276
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7393,12 +7303,12 @@ Examples:
7393
7303
  // src/commands/providers/index.ts
7394
7304
  init_sdk_client();
7395
7305
  import { Command as Command13 } from "commander";
7396
- import chalk25 from "chalk";
7306
+ import chalk26 from "chalk";
7397
7307
  init_errors();
7398
7308
 
7399
7309
  // src/commands/providers/add.ts
7400
7310
  init_sdk_client();
7401
- import chalk22 from "chalk";
7311
+ import chalk23 from "chalk";
7402
7312
  init_errors();
7403
7313
  function resolveScope(scopeFlag, client) {
7404
7314
  const scope = scopeFlag ?? "workspace";
@@ -7421,10 +7331,10 @@ function resolveScope(scopeFlag, client) {
7421
7331
  function registerAddCommand(parent) {
7422
7332
  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
7333
  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
7334
+ ${chalk23.dim("$")} mutagent providers add --provider openai --name "My OpenAI" --api-key $OPENAI_API_KEY
7335
+ ${chalk23.dim("$")} mutagent providers add --provider anthropic --name "Team Claude" --api-key $KEY --scope org
7336
+ ${chalk23.dim("$")} mutagent providers add --provider openai --name "Personal" --api-key $KEY --scope user --set-default
7337
+ ${chalk23.dim("$")} mutagent providers add --provider custom --name "Ollama" --api-key none --base-url http://localhost:11434 --json
7428
7338
 
7429
7339
  Scope Resolution:
7430
7340
  workspace (default) Uses your configured workspace
@@ -7470,10 +7380,10 @@ The API key is encrypted server-side and never returned in plain text.
7470
7380
  console.log(` Scope: ${options.scope ?? "workspace"}`);
7471
7381
  console.log(` URL: ${providerLink(created.id)}`);
7472
7382
  if (options.setDefault) {
7473
- console.log(chalk22.green(" Set as default provider"));
7383
+ console.log(chalk23.green(" Set as default provider"));
7474
7384
  }
7475
7385
  console.log("");
7476
- console.log(chalk22.dim("API key is encrypted server-side. Use `providers get` to see masked key."));
7386
+ console.log(chalk23.dim("API key is encrypted server-side. Use `providers get` to see masked key."));
7477
7387
  }
7478
7388
  } catch (error) {
7479
7389
  handleError(error, isJson);
@@ -7511,15 +7421,15 @@ function buildProviderCreatedDirective(provider, scope) {
7511
7421
 
7512
7422
  // src/commands/providers/update.ts
7513
7423
  init_sdk_client();
7514
- import chalk23 from "chalk";
7424
+ import chalk24 from "chalk";
7515
7425
  init_errors();
7516
7426
  function registerUpdateCommand(parent) {
7517
7427
  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
7428
  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
7429
+ ${chalk24.dim("$")} mutagent providers update <id> --name "New Name"
7430
+ ${chalk24.dim("$")} mutagent providers update <id> --api-key $NEW_KEY --json
7431
+ ${chalk24.dim("$")} mutagent providers update <id> --active false
7432
+ ${chalk24.dim("$")} mutagent providers update <id> --set-default --json
7523
7433
 
7524
7434
  PATCH semantics — only provided fields are updated.
7525
7435
  `).action(async (id, options) => {
@@ -7570,7 +7480,7 @@ PATCH semantics — only provided fields are updated.
7570
7480
  console.log(` ID: ${String(updated.id ?? id)}`);
7571
7481
  console.log(` URL: ${providerLink(updated.id ?? id)}`);
7572
7482
  if (options.apiKey) {
7573
- console.log(chalk23.dim(" API key re-encrypted server-side."));
7483
+ console.log(chalk24.dim(" API key re-encrypted server-side."));
7574
7484
  }
7575
7485
  }
7576
7486
  } catch (error) {
@@ -7609,17 +7519,17 @@ function buildProviderUpdatedDirective(provider, requestId) {
7609
7519
 
7610
7520
  // src/commands/providers/delete.ts
7611
7521
  init_sdk_client();
7612
- import chalk24 from "chalk";
7522
+ import chalk25 from "chalk";
7613
7523
  init_errors();
7614
7524
  function registerDeleteCommand(parent) {
7615
7525
  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
7526
  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
7527
+ ${chalk25.dim("$")} mutagent providers delete <id>
7528
+ ${chalk25.dim("$")} mutagent providers delete <id> --force
7529
+ ${chalk25.dim("$")} mutagent providers delete <id> --force --json
7620
7530
 
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.")}
7531
+ ${chalk25.dim("Note: --force is required. The CLI is non-interactive — confirm with the user via your native flow, then pass --force.")}
7532
+ ${chalk25.dim("Warning: API keys are AES-256-GCM encrypted and irrecoverable after deletion. Agents referencing this provider will lose their model config.")}
7623
7533
  `).action(async (id, options) => {
7624
7534
  const isJson = getJsonFlag(parent);
7625
7535
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7709,12 +7619,12 @@ function validateProviderType(type) {
7709
7619
  function createProvidersCommand() {
7710
7620
  const providers = new Command13("providers").description("Manage LLM provider configurations (BYOK)").addHelpText("after", `
7711
7621
  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>
7622
+ ${chalk26.dim("$")} mutagent providers list
7623
+ ${chalk26.dim("$")} mutagent providers get <provider-id>
7624
+ ${chalk26.dim("$")} mutagent providers add --provider openai --name "My OpenAI" --api-key $KEY
7625
+ ${chalk26.dim("$")} mutagent providers update <id> --name "New Name"
7626
+ ${chalk26.dim("$")} mutagent providers delete <id> --force
7627
+ ${chalk26.dim("$")} mutagent providers test <provider-id>
7718
7628
 
7719
7629
  Provider Types:
7720
7630
  openai, anthropic, google, azure, bedrock, cohere, mistral, groq, together, replicate, custom
@@ -7724,9 +7634,9 @@ Subcommands:
7724
7634
  `);
7725
7635
  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
7636
  Examples:
7727
- ${chalk25.dim("$")} mutagent providers list
7728
- ${chalk25.dim("$")} mutagent providers list --type openai
7729
- ${chalk25.dim("$")} mutagent providers list --json
7637
+ ${chalk26.dim("$")} mutagent providers list
7638
+ ${chalk26.dim("$")} mutagent providers list --type openai
7639
+ ${chalk26.dim("$")} mutagent providers list --json
7730
7640
  `).action(async (options) => {
7731
7641
  const isJson = getJsonFlag(providers);
7732
7642
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7775,8 +7685,8 @@ Examples:
7775
7685
  });
7776
7686
  providers.command("get").description("Get provider details").argument("<id>", "Provider ID (from: mutagent providers list)").addHelpText("after", `
7777
7687
  Examples:
7778
- ${chalk25.dim("$")} mutagent providers get <provider-id>
7779
- ${chalk25.dim("$")} mutagent providers get <provider-id> --json
7688
+ ${chalk26.dim("$")} mutagent providers get <provider-id>
7689
+ ${chalk26.dim("$")} mutagent providers get <provider-id> --json
7780
7690
  `).action(async (id) => {
7781
7691
  const isJson = getJsonFlag(providers);
7782
7692
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7805,10 +7715,10 @@ Examples:
7805
7715
  });
7806
7716
  providers.command("test").description("Test provider connectivity").argument("<id>", "Provider ID (from: mutagent providers list)").addHelpText("after", `
7807
7717
  Examples:
7808
- ${chalk25.dim("$")} mutagent providers test <provider-id>
7809
- ${chalk25.dim("$")} mutagent providers test <provider-id> --json
7718
+ ${chalk26.dim("$")} mutagent providers test <provider-id>
7719
+ ${chalk26.dim("$")} mutagent providers test <provider-id> --json
7810
7720
 
7811
- ${chalk25.dim("Tests connectivity and lists available models for the provider.")}
7721
+ ${chalk26.dim("Tests connectivity and lists available models for the provider.")}
7812
7722
  `).action(async (id) => {
7813
7723
  const isJson = getJsonFlag(providers);
7814
7724
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7823,9 +7733,9 @@ ${chalk25.dim("Tests connectivity and lists available models for the provider.")
7823
7733
  } else {
7824
7734
  if (result.success) {
7825
7735
  output.success(`Provider test passed (${String(result.responseTimeMs)}ms)`);
7826
- console.log(chalk25.green(`Message: ${result.message}`));
7736
+ console.log(chalk26.green(`Message: ${result.message}`));
7827
7737
  if (result.availableModels && result.availableModels.length > 0) {
7828
- console.log(chalk25.bold(`
7738
+ console.log(chalk26.bold(`
7829
7739
  Available Models:`));
7830
7740
  result.availableModels.forEach((model) => {
7831
7741
  console.log(` - ${model}`);
@@ -7834,7 +7744,7 @@ Available Models:`));
7834
7744
  } else {
7835
7745
  output.error(`Provider test failed: ${result.message}`);
7836
7746
  if (result.error) {
7837
- console.log(chalk25.red(`Error: ${result.error}`));
7747
+ console.log(chalk26.red(`Error: ${result.error}`));
7838
7748
  }
7839
7749
  }
7840
7750
  }
@@ -7851,8 +7761,8 @@ Available Models:`));
7851
7761
  // src/commands/init.ts
7852
7762
  init_config();
7853
7763
  import { Command as Command14 } from "commander";
7854
- import inquirer3 from "inquirer";
7855
- import chalk26 from "chalk";
7764
+ import inquirer2 from "inquirer";
7765
+ import chalk27 from "chalk";
7856
7766
  import { existsSync as existsSync11, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
7857
7767
  import { execSync as execSync3 } from "child_process";
7858
7768
  import { join as join6 } from "path";
@@ -7975,13 +7885,13 @@ function writeRcConfig(config, cwd = process.cwd()) {
7975
7885
  function createInitCommand() {
7976
7886
  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
7887
  Examples:
7978
- ${chalk26.dim("$")} mutagent init # Interactive setup wizard
7979
- ${chalk26.dim("$")} mutagent init --non-interactive # CLI-only mode (no prompts)
7888
+ ${chalk27.dim("$")} mutagent init # Interactive setup wizard
7889
+ ${chalk27.dim("$")} mutagent init --non-interactive # CLI-only mode (no prompts)
7980
7890
 
7981
7891
  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
7892
+ ${chalk27.bold("Full scaffold")} Install SDK + integration package, create config, setup tracing
7893
+ ${chalk27.bold("CLI-only")} Verify auth + create .mutagentrc.json with workspace/endpoint
7894
+ ${chalk27.bold("Skip")} Exit without changes
7985
7895
  `).action(async (options) => {
7986
7896
  const isJson = getJsonFlag(init);
7987
7897
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -7994,7 +7904,7 @@ Modes:
7994
7904
  output.info("Use --force to overwrite (not yet supported). Exiting.");
7995
7905
  return;
7996
7906
  }
7997
- const { overwrite } = await inquirer3.prompt([{
7907
+ const { overwrite } = await inquirer2.prompt([{
7998
7908
  type: "confirm",
7999
7909
  name: "overwrite",
8000
7910
  message: ".mutagentrc.json already exists. Overwrite?",
@@ -8012,7 +7922,7 @@ Modes:
8012
7922
  if (isNonInteractive) {
8013
7923
  throw new MutagentError("AUTH_REQUIRED", "Authentication required before init", "Run: mutagent auth login --browser");
8014
7924
  }
8015
- const { doAuth } = await inquirer3.prompt([{
7925
+ const { doAuth } = await inquirer2.prompt([{
8016
7926
  type: "confirm",
8017
7927
  name: "doAuth",
8018
7928
  message: "Would you like to authenticate now?",
@@ -8038,7 +7948,7 @@ Modes:
8038
7948
  } else {
8039
7949
  if (detectedFramework) {
8040
7950
  output.info(`Detected framework: ${detectedFramework.displayName} (${detectedFramework.npmPackage})`);
8041
- const { confirmFramework } = await inquirer3.prompt([{
7951
+ const { confirmFramework } = await inquirer2.prompt([{
8042
7952
  type: "confirm",
8043
7953
  name: "confirmFramework",
8044
7954
  message: `Use ${detectedFramework.displayName}?`,
@@ -8054,7 +7964,7 @@ Modes:
8054
7964
  { name: "Generic (OpenAI-compatible)", value: "generic" },
8055
7965
  { name: "None / Skip framework", value: "none" }
8056
7966
  ];
8057
- const { selectedFramework } = await inquirer3.prompt([{
7967
+ const { selectedFramework } = await inquirer2.prompt([{
8058
7968
  type: "list",
8059
7969
  name: "selectedFramework",
8060
7970
  message: "Select your AI framework:",
@@ -8084,7 +7994,7 @@ Modes:
8084
7994
  value: "skip"
8085
7995
  }
8086
7996
  ];
8087
- const { selectedMode } = await inquirer3.prompt([{
7997
+ const { selectedMode } = await inquirer2.prompt([{
8088
7998
  type: "list",
8089
7999
  name: "selectedMode",
8090
8000
  message: "How would you like to initialize MutagenT?",
@@ -8187,7 +8097,7 @@ Modes:
8187
8097
  const skillPath = join6(cwd, ".claude/skills/mutagent-cli/SKILL.md");
8188
8098
  const skillInstalled = existsSync11(skillPath);
8189
8099
  if (!isNonInteractive && !skillInstalled) {
8190
- const { installSkill } = await inquirer3.prompt([{
8100
+ const { installSkill } = await inquirer2.prompt([{
8191
8101
  type: "confirm",
8192
8102
  name: "installSkill",
8193
8103
  message: "Install MutagenT skill for Claude Code? (Teaches AI agents how to use the CLI)",
@@ -8253,23 +8163,23 @@ Modes:
8253
8163
 
8254
8164
  // src/commands/explore.ts
8255
8165
  import { Command as Command15 } from "commander";
8256
- import chalk27 from "chalk";
8166
+ import chalk28 from "chalk";
8257
8167
  import { resolve as resolve3 } from "path";
8258
8168
  init_errors();
8259
8169
  function createExploreCommand() {
8260
8170
  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
8171
  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
8172
+ ${chalk28.dim("$")} mutagent explore
8173
+ ${chalk28.dim("$")} mutagent explore --path ./src
8174
+ ${chalk28.dim("$")} mutagent explore --include "**/*.{ts,py}" --depth 5
8175
+ ${chalk28.dim("$")} mutagent explore --markers-only
8176
+ ${chalk28.dim("$")} mutagent explore --json
8267
8177
 
8268
8178
  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
8179
+ ${chalk28.dim("Heuristic")} Template variables ({{var}}), prompt constants, schema definitions
8180
+ ${chalk28.dim("Marker")} MutagenT:START/END comment markers from previous uploads
8271
8181
 
8272
- ${chalk27.dim("Results are saved to .mutagent/mutation-context.md for use by other commands.")}
8182
+ ${chalk28.dim("Results are saved to .mutagent/mutation-context.md for use by other commands.")}
8273
8183
  `).action((options) => {
8274
8184
  const isJson = getJsonFlag(explore);
8275
8185
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -8287,7 +8197,7 @@ ${chalk27.dim("Results are saved to .mutagent/mutation-context.md for use by oth
8287
8197
  markersOnly
8288
8198
  };
8289
8199
  if (!isJson) {
8290
- console.log(chalk27.cyan(`
8200
+ console.log(chalk28.cyan(`
8291
8201
  Scanning ${scanPath}...
8292
8202
  `));
8293
8203
  }
@@ -8316,41 +8226,41 @@ Scanning ${scanPath}...
8316
8226
  const totalFindings = result.prompts.length + result.datasets.length + result.markers.length;
8317
8227
  if (totalFindings === 0) {
8318
8228
  output.info("No prompts, datasets, or markers found.");
8319
- console.log(chalk27.dim(`
8229
+ console.log(chalk28.dim(`
8320
8230
  Tip: Create a prompt with template variables like {{input}} to get started.`));
8321
8231
  return;
8322
8232
  }
8323
8233
  if (result.prompts.length > 0) {
8324
- console.log(chalk27.bold(` Prompts Found (${String(result.prompts.length)}):`));
8234
+ console.log(chalk28.bold(` Prompts Found (${String(result.prompts.length)}):`));
8325
8235
  console.log();
8326
8236
  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)}`);
8237
+ const confidenceTag = p.confidence === "high" ? chalk28.green("[high]") : p.confidence === "medium" ? chalk28.yellow("[medium]") : chalk28.dim("[low]");
8238
+ const reasonTag = chalk28.dim(`[${p.reason}]`);
8239
+ console.log(` ${confidenceTag} ${chalk28.green(p.file)}:${chalk28.yellow(String(p.line))} ${reasonTag}`);
8240
+ console.log(` ${chalk28.dim(p.preview)}`);
8331
8241
  }
8332
8242
  console.log();
8333
8243
  }
8334
8244
  if (result.datasets.length > 0) {
8335
- console.log(chalk27.bold(` Datasets Found (${String(result.datasets.length)}):`));
8245
+ console.log(chalk28.bold(` Datasets Found (${String(result.datasets.length)}):`));
8336
8246
  console.log();
8337
8247
  for (const d of result.datasets) {
8338
- console.log(` ${chalk27.green(d.file)} ${chalk27.dim(`(${String(d.items)} items)`)}`);
8248
+ console.log(` ${chalk28.green(d.file)} ${chalk28.dim(`(${String(d.items)} items)`)}`);
8339
8249
  }
8340
8250
  console.log();
8341
8251
  }
8342
8252
  if (result.markers.length > 0) {
8343
- console.log(chalk27.bold(` MutagenT Markers (${String(result.markers.length)}):`));
8253
+ console.log(chalk28.bold(` MutagenT Markers (${String(result.markers.length)}):`));
8344
8254
  console.log();
8345
8255
  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}`);
8256
+ const idPart = m.platformId ? chalk28.cyan(` id=${m.platformId}`) : "";
8257
+ console.log(` ${chalk28.green(m.file)}:${chalk28.yellow(String(m.line))} ${chalk28.magenta(m.type)}${idPart}`);
8348
8258
  }
8349
8259
  console.log();
8350
8260
  }
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`));
8261
+ console.log(chalk28.dim(" ─────────────────────────────────"));
8262
+ console.log(` ${chalk28.bold("Summary:")} ${String(result.prompts.length)} prompts, ${String(result.datasets.length)} datasets, ${String(result.markers.length)} markers`);
8263
+ console.log(chalk28.dim(` Saved to .mutagent/mutation-context.md`));
8354
8264
  console.log();
8355
8265
  }
8356
8266
  } catch (error) {
@@ -8362,7 +8272,7 @@ Scanning ${scanPath}...
8362
8272
 
8363
8273
  // src/commands/skills.ts
8364
8274
  import { Command as Command16 } from "commander";
8365
- import chalk28 from "chalk";
8275
+ import chalk29 from "chalk";
8366
8276
  import { existsSync as existsSync12, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
8367
8277
  import { join as join7 } from "path";
8368
8278
  import { execSync as execSync4 } from "child_process";
@@ -8486,7 +8396,7 @@ function createSkillsCommand() {
8486
8396
  const skills = new Command16("skills").description("Manage MutagenT CLI skills for coding agents");
8487
8397
  skills.command("install").description("Install MutagenT CLI skill for Claude Code").addHelpText("after", `
8488
8398
  Examples:
8489
- ${chalk28.dim("$")} mutagent skills install
8399
+ ${chalk29.dim("$")} mutagent skills install
8490
8400
 
8491
8401
  This creates a Claude Code skill at .claude/skills/mutagent-cli/SKILL.md
8492
8402
  that teaches coding agents how to use the MutagenT CLI effectively.
@@ -8513,10 +8423,10 @@ ${SKILL_BODY}
8513
8423
  });
8514
8424
  } else {
8515
8425
  output.success(`Installed MutagenT CLI skill`);
8516
- console.log(` ${chalk28.dim("Path:")} ${skillPath}`);
8426
+ console.log(` ${chalk29.dim("Path:")} ${skillPath}`);
8517
8427
  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.")}`);
8428
+ console.log(` ${chalk29.dim("This skill teaches coding agents how to use the MutagenT CLI.")}`);
8429
+ console.log(` ${chalk29.dim("It will be automatically loaded by Claude Code when relevant triggers match.")}`);
8520
8430
  }
8521
8431
  });
8522
8432
  return skills;
@@ -8525,7 +8435,7 @@ ${SKILL_BODY}
8525
8435
  // src/commands/usage.ts
8526
8436
  init_config();
8527
8437
  import { Command as Command17 } from "commander";
8528
- import chalk29 from "chalk";
8438
+ import chalk30 from "chalk";
8529
8439
  init_errors();
8530
8440
  init_sdk_client();
8531
8441
  var TRIAL_OPTIMIZATION_LIMIT = 5;
@@ -8541,8 +8451,8 @@ function renderProgressBar(used, limit, width = 30) {
8541
8451
  function createUsageCommand() {
8542
8452
  const usage = new Command17("usage").description("Show resource counts and optimization run limits").addHelpText("after", `
8543
8453
  Examples:
8544
- ${chalk29.dim("$")} mutagent usage
8545
- ${chalk29.dim("$")} mutagent usage --json
8454
+ ${chalk30.dim("$")} mutagent usage
8455
+ ${chalk30.dim("$")} mutagent usage --json
8546
8456
  `);
8547
8457
  usage.action(async () => {
8548
8458
  const isJson = getJsonFlag(usage);
@@ -8597,21 +8507,21 @@ Examples:
8597
8507
  });
8598
8508
  } else {
8599
8509
  console.log("");
8600
- console.log(chalk29.bold("\uD83D\uDCCA MutagenT Usage"));
8601
- console.log(chalk29.dim("─".repeat(45)));
8510
+ console.log(chalk30.bold("\uD83D\uDCCA MutagenT Usage"));
8511
+ console.log(chalk30.dim("─".repeat(45)));
8602
8512
  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))}`);
8513
+ console.log(chalk30.bold("Resources:"));
8514
+ console.log(` Prompts: ${chalk30.cyan(String(promptCount))}`);
8515
+ console.log(` Datasets: ${chalk30.cyan(String(datasetCount))}`);
8516
+ console.log(` Evaluations: ${chalk30.cyan(String(evaluationCount))}`);
8607
8517
  console.log("");
8608
- console.log(chalk29.bold(`Optimization Runs (${chalk29.yellow("trial")} plan):`));
8609
- console.log(` Remaining: ${chalk29.cyan(String(optimizationRemaining))} / ${String(optimizationLimit)}`);
8518
+ console.log(chalk30.bold(`Optimization Runs (${chalk30.yellow("trial")} plan):`));
8519
+ console.log(` Remaining: ${chalk30.cyan(String(optimizationRemaining))} / ${String(optimizationLimit)}`);
8610
8520
  console.log(` ${renderProgressBar(optimizationUsed, optimizationLimit)}`);
8611
8521
  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)}`);
8522
+ console.log(chalk30.yellow(` ⚠ ${String(optimizationRemaining)} optimization runs remaining`));
8523
+ console.log(chalk30.dim(` ℹ Optimization run counts are approximate`));
8524
+ console.log(` Upgrade: ${chalk30.underline(BILLING_URL)}`);
8615
8525
  console.log("");
8616
8526
  }
8617
8527
  } catch (error) {
@@ -8899,7 +8809,7 @@ Claude Code Session Telemetry:
8899
8809
 
8900
8810
  // src/commands/feedback.ts
8901
8811
  import { Command as Command19 } from "commander";
8902
- import chalk30 from "chalk";
8812
+ import chalk31 from "chalk";
8903
8813
  init_errors();
8904
8814
  init_config();
8905
8815
  import { readFileSync as readFileSync11 } from "fs";
@@ -8953,12 +8863,12 @@ async function postToServer(payload, endpoint, apiKey, workspaceId, organization
8953
8863
  }
8954
8864
  function createFeedbackCommand() {
8955
8865
  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')}
8866
+ ${chalk31.bold("Examples:")}
8867
+ ${chalk31.cyan('mutagent feedback send -m "Great optimization results!"')}
8868
+ ${chalk31.cyan('mutagent feedback send -m "CLI crashed on export" --category bug')}
8869
+ ${chalk31.cyan('mutagent feedback send -m "Need batch operations" --category feature --json')}
8960
8870
 
8961
- ${chalk30.yellow("AI Agent (MANDATORY):")}
8871
+ ${chalk31.yellow("AI Agent (MANDATORY):")}
8962
8872
  ALWAYS use --json: mutagent feedback send -m "..." --category improvement --json
8963
8873
  Use this command to report bugs, request features, or share UX feedback.
8964
8874
  `).action(() => {
@@ -8969,18 +8879,18 @@ ${chalk30.yellow("AI Agent (MANDATORY):")}
8969
8879
  }
8970
8880
  function registerFeedbackSend(feedback) {
8971
8881
  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):")}
8882
+ ${chalk31.bold("Examples:")}
8883
+ ${chalk31.dim("$")} mutagent feedback send -m "The optimization UX could show progress better"
8884
+ ${chalk31.dim("$")} mutagent feedback send -m "CLI errored on traces export" --category bug
8885
+ ${chalk31.dim("$")} mutagent feedback send -m "Love the guided eval!" --category praise --json
8886
+
8887
+ ${chalk31.bold("Categories:")}
8888
+ ${chalk31.bold("bug")} Something is broken or not working as expected
8889
+ ${chalk31.bold("feature")} Request a new capability
8890
+ ${chalk31.bold("improvement")} Suggest a UX or workflow enhancement (default)
8891
+ ${chalk31.bold("praise")} Share what you love about the platform
8892
+
8893
+ ${chalk31.yellow("AI Agent (MANDATORY):")}
8984
8894
  ALWAYS use --json: mutagent feedback send -m "..." --json
8985
8895
  Auto-captured context (CLI version, platform, node version) is included automatically.
8986
8896
  `).action(async (options) => {
@@ -9052,103 +8962,109 @@ program.name("mutagent").description(`MutagenT CLI - AI-native prompt optimizati
9052
8962
  showGlobalOptions: true
9053
8963
  });
9054
8964
  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")}
8965
+ ${chalk32.yellow("Non-Interactive Mode (CI/CD & Coding Agents):")}
8966
+ export MUTAGENT_API_KEY=mt_... ${chalk32.dim("or")} --api-key mt_...
8967
+ --json ${chalk32.dim("for structured output")} --non-interactive ${chalk32.dim("to disable prompts")}
8968
+
8969
+ ${chalk32.yellow("Command Navigation:")}
8970
+ mutagent login ${chalk32.dim("Login (browser OAuth — recommended)")}
8971
+ mutagent auth status ${chalk32.dim("Check auth + workspace")}
8972
+ mutagent init ${chalk32.dim("Initialize project (.mutagentrc.json)")}
8973
+ mutagent explore ${chalk32.dim("Discover prompts in codebase")}
8974
+ mutagent workspaces list --json ${chalk32.dim("List workspaces (verify ID)")}
8975
+ mutagent config set workspace <id> ${chalk32.dim("Set active workspace")}
8976
+ mutagent usage --json ${chalk32.dim("Check plan limits")}
8977
+
8978
+ mutagent prompts create --help ${chalk32.dim("Upload prompt (read help first!)")}
8979
+ mutagent prompts list --json ${chalk32.dim("List prompts")}
8980
+ mutagent prompts get <id> --json ${chalk32.dim("Full prompt details + schemas")}
8981
+
8982
+ mutagent prompts dataset add --help ${chalk32.dim("Upload dataset (read help first!)")}
8983
+ mutagent prompts dataset list <id> ${chalk32.dim("List datasets")}
8984
+
8985
+ mutagent prompts evaluation create --help ${chalk32.dim("Create eval (read help first!)")}
8986
+ mutagent prompts evaluation create <id> --guided --json ${chalk32.dim("Guided eval workflow")}
8987
+ mutagent prompts evaluation list <id> --json ${chalk32.dim("List evaluations")}
8988
+
8989
+ mutagent prompts optimize start --help ${chalk32.dim("Run optimization (read help first!)")}
8990
+ mutagent prompts optimize status <job-id> ${chalk32.dim("Poll progress")}
8991
+ mutagent prompts optimize results <job-id> ${chalk32.dim("View scorecard")}
8992
+
8993
+ mutagent feedback send -m "..." ${chalk32.dim("Send product feedback")}
8994
+ mutagent feedback send -m "..." --category bug ${chalk32.dim("Report a bug")}
8995
+
8996
+ mutagent integrate <framework> ${chalk32.dim("Framework integration guide")}
8997
+ mutagent hooks --help ${chalk32.dim("Hook setup for Claude Code telemetry")}
8998
+ mutagent playground run <id> --input '{...}' ${chalk32.dim("Quick test")}
8999
+
9000
+ ${chalk32.yellow("★ Workflow: Framework Integration (Tracing):")}
9001
+ 1. mutagent explore ${chalk32.dim("← discover prompts/agents in codebase")}
9002
+ 2. mutagent integrate <framework> ${chalk32.dim("← get integration instructions")}
9003
+ 3. Apply tracing code to your codebase ${chalk32.dim("← follow the guide output")}
9004
+ 4. mutagent traces list --json ${chalk32.dim("← verify traces are arriving")}
9005
+
9006
+ ${chalk32.yellow("★ Workflow: Evaluate → Optimize:")}
9007
+ 1. mutagent prompts create --help ${chalk32.dim("← read help")}
9008
+ 2. mutagent prompts create ... --json ${chalk32.dim("← upload prompt with {variables} + inputSchema")}
9009
+ 3. mutagent prompts dataset add --help ${chalk32.dim("← read help")}
9010
+ 4. mutagent prompts dataset add <id> ... --json ${chalk32.dim("← upload dataset")}
9011
+ 5. mutagent prompts evaluation create <id> --guided --json ${chalk32.dim("← guided eval")}
9102
9012
  6. mutagent prompts optimize start <id> --dataset <d> --evaluation <e> --json
9103
9013
 
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
9014
+ ${chalk32.yellow("Post-Onboarding Decision Tree:")}
9015
+ After ${chalk32.bold("mutagent auth login")}, users land in one of 3 paths:
9016
+ ${chalk32.bold("Path A")} (Tracing): explore → integrate <framework> → apply tracing → verify
9017
+ ${chalk32.bold("Path B")} (Optimization): explore → prompts create → dataset add → eval create → optimize
9018
+ ${chalk32.bold("Path C")} (Manual): Use CLI commands directly — run mutagent <command> --help
9109
9019
 
9110
- ${chalk31.yellow("Directive System:")}
9020
+ ${chalk32.yellow("Directive System:")}
9111
9021
  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)
9022
+ ${chalk32.bold("_directive.renderedCard")} Pre-formatted card for the user ${chalk32.red("(MUST be shown in chat)")}
9023
+ ${chalk32.bold("_directive.instruction")} Next step for the agent
9024
+ ${chalk32.bold("_directive.next")} Array of suggested follow-up commands
9025
+ ${chalk32.bold("_links")} Dashboard/API URLs (format as markdown links)
9116
9026
 
9117
- ${chalk31.yellow("Evaluation Criteria Format:")}
9118
- Each criterion MUST have: ${chalk31.bold("name")}, ${chalk31.bold("description")} (scoring rubric), ${chalk31.bold("evaluationParameter")}
9027
+ ${chalk32.yellow("Evaluation Criteria Format:")}
9028
+ Each criterion MUST have: ${chalk32.bold("name")}, ${chalk32.bold("description")} (scoring rubric), ${chalk32.bold("evaluationParameter")}
9119
9029
  evaluationParameter MUST match an inputSchema or outputSchema field name
9120
9030
  No duplicate evaluationParameter values — each criterion targets a unique field
9121
9031
  ALL schema fields must be covered (missing fields = error)
9122
- Use ${chalk31.bold("--guided --json")} to generate criteria templates from prompt schemas
9032
+ Use ${chalk32.bold("--guided --json")} to generate criteria templates from prompt schemas
9123
9033
 
9124
- ${chalk31.yellow("Optimization Cost Control:")}
9125
- Default max-iterations is 1. ${chalk31.red("NEVER increase without explicit user request.")}
9034
+ ${chalk32.yellow("Optimization Cost Control:")}
9035
+ Default max-iterations is 1. ${chalk32.red("NEVER increase without explicit user request.")}
9126
9036
  Each iteration incurs LLM costs — confirm with user before starting >1.
9127
9037
 
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")}.
9038
+ ${chalk32.yellow("Post-Optimization:")}
9039
+ After ${chalk32.bold("optimize results")}: ALWAYS show the before/after diff to the user first.
9040
+ Then offer choices: ${chalk32.bold("Apply")} / ${chalk32.bold("Reject")}.
9131
9041
 
9132
- ${chalk31.yellow("State Tracking:")}
9042
+ ${chalk32.yellow("State Tracking:")}
9133
9043
  .mutagent/mutation-context.md — Codebase index of discovered/uploaded prompts
9134
9044
  Update after explore, create, and dataset operations
9135
9045
  mutagent auth status — Auth + workspace state
9136
9046
  Comment markers (// MutagenT:START ... // MutagenT:END) in source files
9137
9047
 
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
9048
+ ${chalk32.yellow("AI Agent Rules (MANDATORY for coding agents):")}
9049
+ 1. Login (two paths):
9050
+ - CI / fully automated: export MUTAGENT_API_KEY=mt_... then mutagent login --json
9051
+ - Helping a user onboard: mutagent login --browser --json
9052
+ (CLI prints an auth URL — surface it to the user verbatim, then the CLI
9053
+ polls for up to 5 minutes while the user authorizes in their browser.
9054
+ This IS agent-compatible. --non-interactive is NOT needed with --browser.)
9055
+ 2. EVERY command MUST include --json (no exceptions)
9056
+ 3. Run <command> --help BEFORE first use of any command
9057
+ 4. Use --guided --json for evaluation creation (NEVER --guided alone)
9058
+ 5. Parse _directive.renderedCard and copy it into your CHAT RESPONSE verbatim
9059
+ ${chalk32.red("HARD STOP")}: do NOT run further commands until the card is rendered in chat
9060
+ 6. After mutagent init, verify workspace: mutagent workspaces list --json
9061
+ 7. Use {single_braces} for template variables in prompts
9062
+ 8. Collect evaluation criteria from the user — NEVER auto-generate
9063
+ 9. ALL user interaction via AskUserQuestion — CLI is non-interactive
9148
9064
  ${!hasCredentials() ? `
9149
- ` + chalk31.yellow(" Warning: Not authenticated. Run: mutagent auth login --browser") + `
9065
+ ` + chalk32.yellow(" Warning: Not authenticated. Run: mutagent login") + `
9150
9066
  ` : ""}${!hasRcConfig() ? `
9151
- ` + chalk31.green(" Get started: mutagent init") + `
9067
+ ` + chalk32.green(" Get started: mutagent init") + `
9152
9068
  ` : ""}`);
9153
9069
  var rawArgs = process.argv.slice(2);
9154
9070
  if (rawArgs.includes("-v") || rawArgs.includes("--version")) {
@@ -9189,5 +9105,5 @@ program.addCommand(createHooksCommand());
9189
9105
  program.addCommand(createFeedbackCommand());
9190
9106
  program.parse();
9191
9107
 
9192
- //# debugId=3313422F119EC74164756E2164756E21
9108
+ //# debugId=A8E80F0BEF0DA5B364756E2164756E21
9193
9109
  //# sourceMappingURL=cli.js.map