@mutagent/cli 0.1.194 → 0.1.195

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
@@ -546,31 +546,6 @@ class SDKClientWrapper {
546
546
  }
547
547
  return response.json();
548
548
  }
549
- async requestRaw(path, options) {
550
- const optHeaders = options?.headers;
551
- let extraHeaders = {};
552
- if (optHeaders instanceof Headers) {
553
- optHeaders.forEach((value, key) => {
554
- extraHeaders[key] = value;
555
- });
556
- } else if (optHeaders) {
557
- extraHeaders = optHeaders;
558
- }
559
- const tenancyHeaders = {};
560
- if (this.workspaceId)
561
- tenancyHeaders["x-workspace-id"] = this.workspaceId;
562
- if (this.organizationId)
563
- tenancyHeaders["x-organization-id"] = this.organizationId;
564
- return fetch(`${this.endpoint}${path}`, {
565
- ...options,
566
- headers: {
567
- "x-api-key": this.apiKey,
568
- "Content-Type": "application/json",
569
- ...tenancyHeaders,
570
- ...extraHeaders
571
- }
572
- });
573
- }
574
549
  async listPrompts() {
575
550
  try {
576
551
  const response = await this.sdk.prompt.listPrompts();
@@ -700,24 +675,10 @@ class SDKClientWrapper {
700
675
  metadata: item.metadata
701
676
  }));
702
677
  const missingExpectedOutputCount = mappedItems.filter((item) => item.expectedOutput === undefined).length;
703
- const bulkResult = await this.requestRaw(`/api/prompts/datasets/${String(dataset.id)}/items/bulk`, {
678
+ await this.request(`/api/prompts/datasets/${String(dataset.id)}/items/bulk`, {
704
679
  method: "POST",
705
680
  body: JSON.stringify({ items: mappedItems })
706
681
  });
707
- if (!bulkResult.ok) {
708
- const bodyText = await bulkResult.text();
709
- let parsed2;
710
- try {
711
- parsed2 = JSON.parse(bodyText);
712
- } catch {}
713
- const typed = parsed2;
714
- if (typed && typed.kind === "bulk_insert_rollback") {
715
- const constraint = typeof typed.failingConstraint === "string" ? typed.failingConstraint : "unknown";
716
- const rowIndex = typeof typed.failingRowIndex === "number" ? typed.failingRowIndex : null;
717
- throw new ApiError(bulkResult.status, `Bulk insert rolled back — constraint: ${constraint}` + (rowIndex !== null ? `, first failing row: ${String(rowIndex)}` : ""));
718
- }
719
- throw new ApiError(bulkResult.status, bodyText || "Bulk insert failed");
720
- }
721
682
  itemCount = mappedItems.length;
722
683
  return { ...dataset, itemCount, missingExpectedOutputCount };
723
684
  }
@@ -878,9 +839,10 @@ class SDKClientWrapper {
878
839
  maxIterations: config?.maxIterations ?? 1,
879
840
  targetScore: config?.targetScore ?? 0.8,
880
841
  patience: config?.patience,
881
- ...config?.executionModel ? { executionModel: config.executionModel } : {},
882
- ...config?.evaluationModel ? { evaluationModel: config.evaluationModel } : {},
883
- ...config?.optimizationModel ? { optimizationModel: config.optimizationModel } : {},
842
+ ...config?.execModel ? { executionModel: config.execModel } : {},
843
+ ...config?.model ? { model: config.model } : {},
844
+ ...config?.evalModel ? { evaluationModel: config.evalModel } : {},
845
+ ...config?.optModel ? { optimizationModel: config.optModel } : {},
884
846
  ...config?.providerId ? { executionProviderId: config.providerId } : {},
885
847
  ...config?.evalProviderId ? { evaluationProviderId: config.evalProviderId } : {},
886
848
  ...config?.optProviderId ? { optimizationProviderId: config.optProviderId } : {}
@@ -1309,7 +1271,7 @@ var init_sdk_client = __esm(() => {
1309
1271
  // src/bin/cli.ts
1310
1272
  import { Command as Command21 } from "commander";
1311
1273
  import chalk39 from "chalk";
1312
- import { readFileSync as readFileSync15, existsSync as existsSync18 } from "fs";
1274
+ import { readFileSync as readFileSync14, existsSync as existsSync17 } from "fs";
1313
1275
  import { join as join12, dirname as dirname3 } from "path";
1314
1276
  import { fileURLToPath as fileURLToPath2 } from "url";
1315
1277
 
@@ -2885,7 +2847,7 @@ init_errors();
2885
2847
  init_sdk_client();
2886
2848
  import { Command as Command7 } from "commander";
2887
2849
  import chalk18 from "chalk";
2888
- import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
2850
+ import { readFileSync as readFileSync5, existsSync as existsSync5 } from "fs";
2889
2851
 
2890
2852
  // src/lib/ui-links.ts
2891
2853
  function getAppBaseUrl() {
@@ -3655,14 +3617,10 @@ inputSchema must be provided. Pass it via the API or dashboard.`);
3655
3617
  Add a 'description' field to each property in your inputSchema. Example: { "properties": { "field": { "type": "string", "description": "What this field contains" } } }`);
3656
3618
  }
3657
3619
  }
3658
- if (!isValidJsonSchema(data.outputSchema)) {
3620
+ if (isSchemaEmpty(data.outputSchema)) {
3621
+ output.warn("No outputSchema provided. This may limit optimization effectiveness.");
3622
+ } else if (!isValidJsonSchema(data.outputSchema)) {
3659
3623
  output.warn(formatSchemaWarning("outputSchema"));
3660
- } else {
3661
- const missingOutputDescs = validateSchemaDescriptions(data.outputSchema);
3662
- if (missingOutputDescs.length > 0) {
3663
- throw new MutagentError("VALIDATION_ERROR", `outputSchema properties missing descriptions: ${missingOutputDescs.join(", ")}`, `Run: mutagent prompts create --help
3664
- Add a 'description' field to each property in your outputSchema. Example: { "properties": { "field": { "type": "string", "description": "What this field contains" } } }`);
3665
- }
3666
3624
  }
3667
3625
  const client = await getSDKClient();
3668
3626
  const prompt = await client.createPrompt(data);
@@ -3738,13 +3696,6 @@ Examples:
3738
3696
  ` + `Add a 'description' field to each property in your inputSchema. Example: { "properties": { "field": { "type": "string", "description": "What this field contains" } } }`);
3739
3697
  }
3740
3698
  }
3741
- if (data.outputSchema && isValidJsonSchema(data.outputSchema)) {
3742
- const missingOutputDescs = validateSchemaDescriptions(data.outputSchema);
3743
- if (missingOutputDescs.length > 0) {
3744
- throw new MutagentError("VALIDATION_ERROR", `outputSchema properties missing descriptions: ${missingOutputDescs.join(", ")}`, `Run: mutagent prompts update --help
3745
- ` + `Add a 'description' field to each property in your outputSchema. Example: { "properties": { "field": { "type": "string", "description": "What this field contains" } } }`);
3746
- }
3747
- }
3748
3699
  if (Object.keys(data).length === 0) {
3749
3700
  throw new MutagentError("MISSING_ARGUMENTS", "No update data provided", `Run: mutagent prompts update --help
3750
3701
  ` + "Use --name, --raw, --system/--human, --messages, --input-schema, or --output-schema");
@@ -4166,76 +4117,7 @@ async function fetchAndBuildGuidedDatasetWorkflow(promptId) {
4166
4117
  return result;
4167
4118
  }
4168
4119
 
4169
- // src/commands/prompts/dataset-file-utils.ts
4170
- init_errors();
4171
- import { readFileSync as readFileSync5, existsSync as existsSync5 } from "fs";
4172
- function parseDatasetFile(rawContent, filePath) {
4173
- const trimmed = rawContent.trim();
4174
- if (filePath.endsWith(".csv")) {
4175
- return rawContent;
4176
- }
4177
- if (trimmed.startsWith("[")) {
4178
- try {
4179
- const parsed = JSON.parse(trimmed);
4180
- if (!Array.isArray(parsed)) {
4181
- throw new MutagentError("INVALID_JSON", "Expected a JSON array in dataset file", `Run: mutagent prompts dataset add --help
4182
- Dataset JSON files should contain an array of objects: [{...}, {...}]`);
4183
- }
4184
- return trimmed;
4185
- } catch (e) {
4186
- if (e instanceof MutagentError)
4187
- throw e;
4188
- throw new MutagentError("INVALID_JSON", `Failed to parse JSON array from ${filePath}`, `Run: mutagent prompts dataset add --help
4189
- Ensure the file contains valid JSON. For line-delimited JSON, use .jsonl extension or put one object per line.`);
4190
- }
4191
- }
4192
- const lines = trimmed.split(`
4193
- `).filter((line) => line.trim().length > 0);
4194
- const items = [];
4195
- for (let i = 0;i < lines.length; i++) {
4196
- const line = lines[i];
4197
- if (!line)
4198
- continue;
4199
- const trimmedLine = line.trim();
4200
- try {
4201
- items.push(JSON.parse(trimmedLine));
4202
- } catch {
4203
- throw new MutagentError("INVALID_JSONL", `Invalid JSON on line ${String(i + 1)} of ${filePath}`, `Run: mutagent prompts dataset add --help
4204
- Each line must be valid JSON. Problem line: "${trimmedLine.substring(0, 80)}${trimmedLine.length > 80 ? "..." : ""}"`);
4205
- }
4206
- }
4207
- return JSON.stringify(items);
4208
- }
4209
- function readDatasetFile(filePath) {
4210
- if (!existsSync5(filePath)) {
4211
- throw new MutagentError("FILE_NOT_FOUND", `File not found: ${filePath}`, `Run: mutagent prompts dataset add --help
4212
- Verify the file path exists and is readable.`);
4213
- }
4214
- const rawContent = readFileSync5(filePath, "utf-8");
4215
- const content = parseDatasetFile(rawContent, filePath);
4216
- if (filePath.endsWith(".csv")) {
4217
- return { content, expectedItemCount: null };
4218
- }
4219
- const expectedItemCount = JSON.parse(content).length;
4220
- return { content, expectedItemCount };
4221
- }
4222
-
4223
4120
  // src/commands/prompts/datasets.ts
4224
- async function verifyItemCount(client, datasetId, expectedItemCount, isJson, output, uploadHint) {
4225
- try {
4226
- const fetched = await client.getDataset(datasetId);
4227
- const serverCount = fetched.itemCount;
4228
- if (serverCount !== undefined && serverCount !== expectedItemCount) {
4229
- throw new MutagentError("ITEM_COUNT_MISMATCH", `Dataset created but itemCount mismatch: expected ${String(expectedItemCount)}, server reports ${String(serverCount)}`, `The server may have rolled back part of the bulk insert. Re-upload with:
4230
- ${uploadHint}`);
4231
- }
4232
- } catch (err) {
4233
- if (err instanceof MutagentError)
4234
- throw err;
4235
- if (!isJson)
4236
- output.warn("Could not verify itemCount after upload (re-fetch failed)");
4237
- }
4238
- }
4239
4121
  function registerDatasetCommands(prompts) {
4240
4122
  const dataset = new Command3("dataset").description("Manage datasets for prompts").addHelpText("after", `
4241
4123
  Examples:
@@ -4335,21 +4217,12 @@ Verify the dataset ID exists, or list datasets for a prompt to find valid IDs.`)
4335
4217
  }
4336
4218
  }
4337
4219
  });
4338
- dataset.command("add").description("Add dataset to a prompt").argument("[prompt-id]", "Prompt ID (from: mutagent prompts list) — optional when --guided is set").option("-d, --data <json>", "Inline JSON array of dataset items").option("-f, --file <path>", "Path to a JSONL or JSON file. JSONL: one JSON object per line. JSON: array of objects. Avoids shell ARG_MAX limits for large datasets.").option("-n, --name <name>", "Dataset name").option("--guided", "Guided mode — analyze prompt schema and suggest dataset categories. prompt-id is optional when --guided is set.").option("--allow-missing-expected", "Skip the expectedOutput requirement (backwards-compat escape hatch). Items missing expectedOutput are uploaded but evaluation scoring will be broken.").addHelpText("after", `
4220
+ dataset.command("add").description("Add dataset to a prompt").argument("[prompt-id]", "Prompt ID (from: mutagent prompts list) — optional when --guided is set").option("-d, --data <json>", "Inline JSON array of dataset items").option("-n, --name <name>", "Dataset name").option("--guided", "Guided mode — analyze prompt schema and suggest dataset categories. prompt-id is optional when --guided is set.").addHelpText("after", `
4339
4221
  Examples:
4340
4222
  ${chalk8.dim("$")} mutagent prompts dataset add --guided --json # no prompt-id: returns generic workflow + upload instructions
4341
4223
  ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> --guided --json # recommended: schema-aware category suggestions
4342
4224
  ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"},"expectedOutput":{"result":"world"}}]'
4343
4225
  ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"},"expectedOutput":{"result":"world"}}]' --name "My Dataset"
4344
- ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -f ./items.jsonl --name "My Dataset" # recommended for large datasets (avoids ARG_MAX)
4345
- ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -f ./items.json --name "My Dataset" # JSON array file
4346
- ${chalk8.dim("$")} mutagent prompts dataset add <prompt-id> -d '[{"input":{"text":"hello"}}]' --name "legacy" --allow-missing-expected
4347
-
4348
- File mode (-f / --file):
4349
- Streams the file line-by-line (JSONL) or parses it as a JSON array, then submits as a
4350
- single bulk request. Throws with the line number on any malformed line.
4351
- Avoids the macOS ARG_MAX limit that truncates large -d payloads.
4352
- After upload, re-fetches the created dataset and verifies itemCount matches the file.
4353
4226
 
4354
4227
  Guided mode (--guided):
4355
4228
  Fetches the prompt's inputSchema + outputSchema and returns structured JSON
@@ -4371,8 +4244,7 @@ ${chalk8.yellow("AI Agent (MANDATORY):")}
4371
4244
  expectedOutput is REQUIRED for evaluation scoring.
4372
4245
  Check schemas: mutagent prompts get <prompt-id> --json
4373
4246
 
4374
- ${chalk8.red("Required: --data, --file, or --guided must be provided.")}
4375
- ${chalk8.yellow("--allow-missing-expected: Use ONLY for legacy datasets where expectedOutput cannot be provided. Evaluation will not work without it.")}
4247
+ ${chalk8.red("Required: --data or --guided must be provided.")}
4376
4248
  `).action(async (promptId, options) => {
4377
4249
  const isJson = options.guided ? true : getJsonFlag(prompts);
4378
4250
  const output = new OutputFormatter(isJson ? "json" : "table");
@@ -4392,30 +4264,23 @@ ${chalk8.yellow("--allow-missing-expected: Use ONLY for legacy datasets where ex
4392
4264
  ` + `Usage: mutagent prompts dataset add <prompt-id> [options]
4393
4265
  ` + "With --guided: mutagent prompts dataset add --guided --json (returns generic workflow)");
4394
4266
  }
4395
- if (!options.data && !options.file) {
4396
- throw new MutagentError("MISSING_ARGUMENTS", "-d/--data or -f/--file is required", `Run: mutagent prompts dataset add --help
4397
- ` + "Use -d '[{...}]' for inline JSON, or -f ./items.jsonl for file upload (recommended for large datasets)");
4267
+ if (!options.data) {
4268
+ throw new MutagentError("MISSING_ARGUMENTS", "-d/--data is required", `Run: mutagent prompts dataset add --help
4269
+ ` + "Use -d '[{...}]' to provide inline JSON data");
4398
4270
  }
4399
4271
  let content;
4400
- let expectedItemCount = null;
4401
- if (options.file) {
4402
- const result = readDatasetFile(options.file);
4403
- content = result.content;
4404
- expectedItemCount = result.expectedItemCount;
4405
- } else {
4406
- try {
4407
- const parsed = JSON.parse(options.data);
4408
- if (!Array.isArray(parsed)) {
4409
- throw new MutagentError("INVALID_JSON", "Inline data must be a JSON array", `Run: mutagent prompts dataset add --help
4272
+ try {
4273
+ const parsed = JSON.parse(options.data);
4274
+ if (!Array.isArray(parsed)) {
4275
+ throw new MutagentError("INVALID_JSON", "Inline data must be a JSON array", `Run: mutagent prompts dataset add --help
4410
4276
  ` + `Provide a JSON array, e.g., '[{"input": {...}, "expectedOutput": {...}}]'`);
4411
- }
4412
- content = options.data;
4413
- } catch (e) {
4414
- if (e instanceof MutagentError)
4415
- throw e;
4416
- throw new MutagentError("INVALID_JSON", "Invalid JSON in -d/--data flag", `Run: mutagent prompts dataset add --help
4417
- ` + `Provide a valid JSON array, e.g., '[{"input": {...}, "expectedOutput": {...}}]'`);
4418
4277
  }
4278
+ content = options.data;
4279
+ } catch (e) {
4280
+ if (e instanceof MutagentError)
4281
+ throw e;
4282
+ throw new MutagentError("INVALID_JSON", "Invalid JSON in -d/--data flag", `Run: mutagent prompts dataset add --help
4283
+ ` + `Provide a valid JSON array, e.g., '[{"input": {...}, "expectedOutput": {...}}]'`);
4419
4284
  }
4420
4285
  const parsedItems = JSON.parse(content);
4421
4286
  if (parsedItems.length === 0) {
@@ -4423,7 +4288,6 @@ ${chalk8.yellow("--allow-missing-expected: Use ONLY for legacy datasets where ex
4423
4288
  Provide at least one item in the array.`);
4424
4289
  }
4425
4290
  const warnings = [];
4426
- const missingExpectedIndices = [];
4427
4291
  for (let i = 0;i < parsedItems.length; i++) {
4428
4292
  const item = parsedItems[i];
4429
4293
  if (!("input" in item)) {
@@ -4435,18 +4299,9 @@ Each item must have: {"input": {...}, "expectedOutput": {...}}`);
4435
4299
  "input" must be a JSON object: {"input": {"field": "value"}}`);
4436
4300
  }
4437
4301
  if (!("expectedOutput" in item)) {
4438
- missingExpectedIndices.push(i);
4302
+ warnings.push(`Item at index ${i} is missing "expectedOutput" (recommended for evaluation scoring)`);
4439
4303
  }
4440
4304
  }
4441
- if (missingExpectedIndices.length > 0) {
4442
- if (!options.allowMissingExpected) {
4443
- throw new MutagentError("VALIDATION_ERROR", `${missingExpectedIndices.length} dataset item(s) are missing "expectedOutput" at indices: ${missingExpectedIndices.join(", ")}`, `Run: mutagent prompts dataset add --help
4444
- ` + `Each item must have: {"input": {...}, "expectedOutput": {...}}
4445
- ` + `"expectedOutput" is required for evaluation scoring.
4446
- ` + "If you intentionally want to upload items without expectedOutput, use: --allow-missing-expected");
4447
- }
4448
- warnings.push(`${missingExpectedIndices.length} item(s) missing "expectedOutput" at indices: ${missingExpectedIndices.join(", ")}. Evaluation scoring will not work.`);
4449
- }
4450
4305
  const datasetName = options.name;
4451
4306
  if (!datasetName) {
4452
4307
  throw new MutagentError("MISSING_ARGUMENTS", "Dataset name is required", `Run: mutagent prompts dataset add --help
@@ -4456,10 +4311,6 @@ Each item must have: {"input": {...}, "expectedOutput": {...}}`);
4456
4311
  const resolvedPromptId = promptId;
4457
4312
  const client = await getSDKClient();
4458
4313
  const datasetResult = await client.addDataset(resolvedPromptId, content, datasetName);
4459
- if (expectedItemCount !== null && datasetResult.id !== undefined) {
4460
- const hint = `mutagent prompts dataset add ${resolvedPromptId} -f ${options.file ?? "<file>"} --name "${datasetName}"`;
4461
- await verifyItemCount(client, datasetResult.id, expectedItemCount, isJson, output, hint);
4462
- }
4463
4314
  if (isJson) {
4464
4315
  let rsState;
4465
4316
  try {
@@ -4493,10 +4344,9 @@ Each item must have: {"input": {...}, "expectedOutput": {...}}`);
4493
4344
  });
4494
4345
  console.log(hints);
4495
4346
  }
4496
- const dataSource = options.file ? `file:${options.file}` : "inline-data";
4497
4347
  updateMutationContext((ctx) => {
4498
- ctx.addDiscoveredDataset(dataSource, datasetResult.name, datasetResult.itemCount ?? 0);
4499
- ctx.markDatasetUploaded(dataSource, String(datasetResult.id), resolvedPromptId);
4348
+ ctx.addDiscoveredDataset("inline-data", datasetResult.name, datasetResult.itemCount ?? 0);
4349
+ ctx.markDatasetUploaded("inline-data", String(datasetResult.id), resolvedPromptId);
4500
4350
  });
4501
4351
  } catch (error) {
4502
4352
  handleError(error, isJson);
@@ -6469,21 +6319,14 @@ ${chalk16.bold("Hit a bug or unexpected result?")}
6469
6319
  output.warn("--optimizer-model is deprecated, use --opt-model");
6470
6320
  options.optModel = options.optModel ?? options.optimizerModel;
6471
6321
  }
6472
- const resolvedExecModel = options.execModel ?? options.model;
6473
- const resolvedEvalModel = options.evalModel ?? options.model;
6474
- const resolvedOptModel = options.optModel ?? options.model;
6475
- if (resolvedOptModel) {
6476
- validateOptimizerModel(resolvedOptModel);
6322
+ if (options.optModel) {
6323
+ validateOptimizerModel(options.optModel);
6477
6324
  }
6478
- if (!resolvedExecModel && !isJson) {
6479
- output.warn("No --model specified. Server will use workspace defaults. Pass --model <id> to control costs.");
6325
+ const execModel = options.execModel ?? options.model;
6326
+ if (!execModel && !isJson) {
6327
+ output.warn("No --model specified. Server will use default. Pass --model <id> to control costs.");
6480
6328
  }
6481
- const modelsToValidate = [
6482
- ...resolvedExecModel ? [{ slot: "exec", model: resolvedExecModel }] : [],
6483
- ...resolvedEvalModel && resolvedEvalModel !== resolvedExecModel ? [{ slot: "eval", model: resolvedEvalModel }] : [],
6484
- ...resolvedOptModel && resolvedOptModel !== resolvedExecModel && resolvedOptModel !== resolvedEvalModel ? [{ slot: "opt", model: resolvedOptModel }] : []
6485
- ];
6486
- if (modelsToValidate.length > 0) {
6329
+ if (execModel) {
6487
6330
  try {
6488
6331
  const providers = await client.listProviders();
6489
6332
  if (providers.data && providers.data.length > 0) {
@@ -6496,20 +6339,18 @@ ${chalk16.bold("Hit a bug or unexpected result?")}
6496
6339
  }
6497
6340
  } else {
6498
6341
  const modelFamilies = getModelFamiliesForProviderTypes(configuredTypes);
6499
- for (const { slot, model } of modelsToValidate) {
6500
- const modelLower = model.toLowerCase();
6501
- const matchedFamily = modelFamilies.find(({ prefixes }) => prefixes.some((prefix) => modelLower.startsWith(prefix)));
6502
- if (!matchedFamily) {
6503
- const supportedModels = modelFamilies.flatMap((f) => f.examples).join(", ");
6504
- const errorMsg = `${slot} model '${model}' is not supported by any configured provider. ` + `Your providers: [${configuredTypes.join(", ")}]. ` + `Supported models: ${supportedModels || "(unknown — check mutagent providers list --json)"}. ` + `Run: mutagent providers list --json`;
6505
- if (isJson) {
6506
- output.output({ success: false, error: errorMsg, code: "MODEL_NOT_SUPPORTED" });
6507
- return;
6508
- }
6509
- output.error(errorMsg);
6510
- process.exitCode = 1;
6342
+ const modelLower = execModel.toLowerCase();
6343
+ const matchedFamily = modelFamilies.find(({ prefixes }) => prefixes.some((prefix) => modelLower.startsWith(prefix)));
6344
+ if (!matchedFamily) {
6345
+ const supportedModels = modelFamilies.flatMap((f) => f.examples).join(", ");
6346
+ const errorMsg = `Model '${execModel}' is not supported by any configured provider. ` + `Your providers: [${configuredTypes.join(", ")}]. ` + `Supported models: ${supportedModels || "(unknown — check mutagent providers list --json)"}. ` + `Run: mutagent providers list --json`;
6347
+ if (isJson) {
6348
+ output.output({ success: false, error: errorMsg, code: "MODEL_NOT_SUPPORTED" });
6511
6349
  return;
6512
6350
  }
6351
+ output.error(errorMsg);
6352
+ process.exitCode = 1;
6353
+ return;
6513
6354
  }
6514
6355
  }
6515
6356
  }
@@ -6666,9 +6507,10 @@ ${chalk16.bold("Hit a bug or unexpected result?")}
6666
6507
  maxIterations: options.maxIterations ? parseInt(options.maxIterations, 10) : 1,
6667
6508
  targetScore: options.targetScore ? parseFloat(options.targetScore) : undefined,
6668
6509
  patience: options.patience ? parseInt(options.patience, 10) : undefined,
6669
- executionModel: resolvedExecModel,
6670
- evaluationModel: resolvedEvalModel,
6671
- optimizationModel: resolvedOptModel,
6510
+ model: options.execModel ? undefined : options.model,
6511
+ execModel: options.execModel,
6512
+ evalModel: options.evalModel,
6513
+ optModel: options.optModel,
6672
6514
  providerId: options.providerId,
6673
6515
  evalProviderId: options.evalProviderId,
6674
6516
  optProviderId: options.optProviderId
@@ -7117,12 +6959,12 @@ Provide a valid JSON Schema, e.g., '{"type":"object","properties":{"field":{"typ
7117
6959
  }
7118
6960
  }
7119
6961
  if (filePath) {
7120
- if (!existsSync6(filePath)) {
6962
+ if (!existsSync5(filePath)) {
7121
6963
  throw new MutagentError("FILE_NOT_FOUND", `File not found: ${filePath}`, `Run: ${helpCommand}
7122
6964
  Check the file path and try again`);
7123
6965
  }
7124
6966
  try {
7125
- return JSON.parse(readFileSync6(filePath, "utf-8"));
6967
+ return JSON.parse(readFileSync5(filePath, "utf-8"));
7126
6968
  } catch {
7127
6969
  throw new MutagentError("INVALID_JSON", `Failed to parse JSON from ${filePath}`, `Run: ${helpCommand}
7128
6970
  Ensure the file contains valid JSON Schema`);
@@ -7420,20 +7262,20 @@ ${chalk22.dim("Returns full trace details including spans, tokens, and latency."
7420
7262
  init_config();
7421
7263
  import { Command as Command9 } from "commander";
7422
7264
  import chalk23 from "chalk";
7423
- import { writeFileSync as writeFileSync3, existsSync as existsSync11 } from "fs";
7265
+ import { writeFileSync as writeFileSync3, existsSync as existsSync10 } from "fs";
7424
7266
  import { execSync } from "child_process";
7425
7267
  init_errors();
7426
7268
 
7427
7269
  // src/lib/integrations/langchain.ts
7428
- import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
7270
+ import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
7429
7271
  var langchainIntegration = {
7430
7272
  name: "langchain",
7431
7273
  description: "LangChain framework",
7432
7274
  detect() {
7433
7275
  let hasLangchain = false;
7434
- if (existsSync7("package.json")) {
7276
+ if (existsSync6("package.json")) {
7435
7277
  try {
7436
- const pkg = JSON.parse(readFileSync7("package.json", "utf-8"));
7278
+ const pkg = JSON.parse(readFileSync6("package.json", "utf-8"));
7437
7279
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
7438
7280
  hasLangchain = "langchain" in deps || "@langchain/core" in deps;
7439
7281
  } catch {}
@@ -7565,15 +7407,15 @@ mutagent traces analyze <prompt-id>
7565
7407
  };
7566
7408
 
7567
7409
  // src/lib/integrations/langgraph.ts
7568
- import { readFileSync as readFileSync8, existsSync as existsSync8 } from "fs";
7410
+ import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
7569
7411
  var langgraphIntegration = {
7570
7412
  name: "langgraph",
7571
7413
  description: "LangGraph agent workflow framework",
7572
7414
  detect() {
7573
7415
  let hasLanggraph = false;
7574
- if (existsSync8("package.json")) {
7416
+ if (existsSync7("package.json")) {
7575
7417
  try {
7576
- const pkg = JSON.parse(readFileSync8("package.json", "utf-8"));
7418
+ const pkg = JSON.parse(readFileSync7("package.json", "utf-8"));
7577
7419
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
7578
7420
  hasLanggraph = "@langchain/langgraph" in deps;
7579
7421
  } catch {}
@@ -7655,15 +7497,15 @@ mutagent integrate langgraph --verify
7655
7497
  };
7656
7498
 
7657
7499
  // src/lib/integrations/vercel-ai.ts
7658
- import { readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
7500
+ import { readFileSync as readFileSync8, existsSync as existsSync8 } from "fs";
7659
7501
  var vercelAiIntegration = {
7660
7502
  name: "vercel-ai",
7661
7503
  description: "Vercel AI SDK",
7662
7504
  detect() {
7663
7505
  let hasAiSdk = false;
7664
- if (existsSync9("package.json")) {
7506
+ if (existsSync8("package.json")) {
7665
7507
  try {
7666
- const pkg = JSON.parse(readFileSync9("package.json", "utf-8"));
7508
+ const pkg = JSON.parse(readFileSync8("package.json", "utf-8"));
7667
7509
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
7668
7510
  hasAiSdk = "ai" in deps;
7669
7511
  } catch {}
@@ -7805,15 +7647,15 @@ mutagent integrate vercel-ai --verify
7805
7647
  };
7806
7648
 
7807
7649
  // src/lib/integrations/openai.ts
7808
- import { readFileSync as readFileSync10, existsSync as existsSync10 } from "fs";
7650
+ import { readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
7809
7651
  var openaiIntegration = {
7810
7652
  name: "openai",
7811
7653
  description: "OpenAI SDK integration with automatic tracing",
7812
7654
  detect() {
7813
7655
  let hasOpenAI = false;
7814
- if (existsSync10("package.json")) {
7656
+ if (existsSync9("package.json")) {
7815
7657
  try {
7816
- const pkg = JSON.parse(readFileSync10("package.json", "utf-8"));
7658
+ const pkg = JSON.parse(readFileSync9("package.json", "utf-8"));
7817
7659
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
7818
7660
  hasOpenAI = "openai" in deps;
7819
7661
  } catch {}
@@ -7962,16 +7804,16 @@ function getFrameworkMetadata(name) {
7962
7804
 
7963
7805
  // src/commands/integrate.ts
7964
7806
  function detectPackageManager() {
7965
- if (existsSync11("bun.lockb") || existsSync11("bun.lock")) {
7807
+ if (existsSync10("bun.lockb") || existsSync10("bun.lock")) {
7966
7808
  return "bun";
7967
7809
  }
7968
- if (existsSync11("pnpm-lock.yaml")) {
7810
+ if (existsSync10("pnpm-lock.yaml")) {
7969
7811
  return "pnpm";
7970
7812
  }
7971
- if (existsSync11("yarn.lock")) {
7813
+ if (existsSync10("yarn.lock")) {
7972
7814
  return "yarn";
7973
7815
  }
7974
- if (existsSync11("package-lock.json")) {
7816
+ if (existsSync10("package-lock.json")) {
7975
7817
  return "npm";
7976
7818
  }
7977
7819
  try {
@@ -9357,13 +9199,13 @@ init_config();
9357
9199
  import { Command as Command15 } from "commander";
9358
9200
  import inquirer2 from "inquirer";
9359
9201
  import chalk34 from "chalk";
9360
- import { existsSync as existsSync13, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
9202
+ import { existsSync as existsSync12, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
9361
9203
  import { execSync as execSync3 } from "child_process";
9362
9204
  import { join as join7 } from "path";
9363
9205
  init_errors();
9364
9206
 
9365
9207
  // src/lib/framework-detection.ts
9366
- import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
9208
+ import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
9367
9209
  import { execSync as execSync2 } from "child_process";
9368
9210
  import { join as join6 } from "path";
9369
9211
  var FRAMEWORK_DETECTION_MAP = {
@@ -9415,16 +9257,16 @@ var FRAMEWORK_DETECTION_MAP = {
9415
9257
  }
9416
9258
  };
9417
9259
  function detectPackageManager2(cwd = process.cwd()) {
9418
- if (existsSync12(join6(cwd, "bun.lockb")) || existsSync12(join6(cwd, "bun.lock"))) {
9260
+ if (existsSync11(join6(cwd, "bun.lockb")) || existsSync11(join6(cwd, "bun.lock"))) {
9419
9261
  return "bun";
9420
9262
  }
9421
- if (existsSync12(join6(cwd, "pnpm-lock.yaml"))) {
9263
+ if (existsSync11(join6(cwd, "pnpm-lock.yaml"))) {
9422
9264
  return "pnpm";
9423
9265
  }
9424
- if (existsSync12(join6(cwd, "yarn.lock"))) {
9266
+ if (existsSync11(join6(cwd, "yarn.lock"))) {
9425
9267
  return "yarn";
9426
9268
  }
9427
- if (existsSync12(join6(cwd, "package-lock.json"))) {
9269
+ if (existsSync11(join6(cwd, "package-lock.json"))) {
9428
9270
  return "npm";
9429
9271
  }
9430
9272
  try {
@@ -9446,12 +9288,12 @@ function getInstallCommand2(pm, packages) {
9446
9288
  }
9447
9289
  function detectFrameworkFromPackageJson(cwd = process.cwd()) {
9448
9290
  const pkgPath = join6(cwd, "package.json");
9449
- if (!existsSync12(pkgPath)) {
9291
+ if (!existsSync11(pkgPath)) {
9450
9292
  return null;
9451
9293
  }
9452
9294
  let pkg;
9453
9295
  try {
9454
- pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
9296
+ pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
9455
9297
  } catch {
9456
9298
  return null;
9457
9299
  }
@@ -9467,7 +9309,7 @@ function detectFrameworkFromPackageJson(cwd = process.cwd()) {
9467
9309
  return null;
9468
9310
  }
9469
9311
  function hasRcConfig(cwd = process.cwd()) {
9470
- return existsSync12(join6(cwd, ".mutagentrc.json"));
9312
+ return existsSync11(join6(cwd, ".mutagentrc.json"));
9471
9313
  }
9472
9314
 
9473
9315
  // src/commands/init.ts
@@ -9689,7 +9531,7 @@ Modes:
9689
9531
  }
9690
9532
  }
9691
9533
  const skillPath = join7(cwd, ".claude/skills/mutagent-cli/SKILL.md");
9692
- const skillInstalled = existsSync13(skillPath);
9534
+ const skillInstalled = existsSync12(skillPath);
9693
9535
  if (!isNonInteractive && !skillInstalled) {
9694
9536
  const { installSkill } = await inquirer2.prompt([{
9695
9537
  type: "confirm",
@@ -9700,7 +9542,7 @@ Modes:
9700
9542
  if (installSkill) {
9701
9543
  try {
9702
9544
  const skillDir = join7(cwd, ".claude/skills/mutagent-cli");
9703
- if (!existsSync13(skillDir)) {
9545
+ if (!existsSync12(skillDir)) {
9704
9546
  mkdirSync3(skillDir, { recursive: true });
9705
9547
  }
9706
9548
  execSync3("node " + join7(cwd, "node_modules/.bin/mutagent") + " skills install", {
@@ -9751,7 +9593,7 @@ Modes:
9751
9593
  framework: confirmedFramework?.name ?? null,
9752
9594
  authenticated,
9753
9595
  workspaceValidation: workspaceValidation ?? null,
9754
- skillInstalled: skillInstalled || existsSync13(skillPath),
9596
+ skillInstalled: skillInstalled || existsSync12(skillPath),
9755
9597
  _directive: initDirective
9756
9598
  };
9757
9599
  output.output(summary);
@@ -9925,7 +9767,7 @@ Scanning ${scanPath}...
9925
9767
  // src/commands/skills.ts
9926
9768
  import { Command as Command17 } from "commander";
9927
9769
  import chalk36 from "chalk";
9928
- import { existsSync as existsSync14, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
9770
+ import { existsSync as existsSync13, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
9929
9771
  import { dirname, join as join8 } from "path";
9930
9772
  import { execSync as execSync4 } from "child_process";
9931
9773
 
@@ -12452,7 +12294,7 @@ that teaches coding agents how to use the MutagenT CLI effectively.
12452
12294
  for (const relPath of sortedKeys) {
12453
12295
  const destPath = join8(skillDir, relPath);
12454
12296
  const parentDir = dirname(destPath);
12455
- if (!existsSync14(parentDir)) {
12297
+ if (!existsSync13(parentDir)) {
12456
12298
  mkdirSync4(parentDir, { recursive: true });
12457
12299
  }
12458
12300
  const raw = files[relPath] ?? "";
@@ -12586,7 +12428,7 @@ import { Command as Command19 } from "commander";
12586
12428
  import { randomUUID } from "crypto";
12587
12429
 
12588
12430
  // src/commands/hooks/state.ts
12589
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, renameSync, unlinkSync, existsSync as existsSync15 } from "fs";
12431
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, renameSync, unlinkSync, existsSync as existsSync14 } from "fs";
12590
12432
  import { join as join9 } from "path";
12591
12433
  import { tmpdir } from "os";
12592
12434
  function stateFilePath(sessionId) {
@@ -12594,10 +12436,10 @@ function stateFilePath(sessionId) {
12594
12436
  }
12595
12437
  function readState(sessionId) {
12596
12438
  const path = stateFilePath(sessionId);
12597
- if (!existsSync15(path))
12439
+ if (!existsSync14(path))
12598
12440
  return null;
12599
12441
  try {
12600
- const raw = JSON.parse(readFileSync12(path, "utf-8"));
12442
+ const raw = JSON.parse(readFileSync11(path, "utf-8"));
12601
12443
  if (!Array.isArray(raw.parentStack)) {
12602
12444
  raw.parentStack = [];
12603
12445
  }
@@ -12617,7 +12459,7 @@ function writeState(sessionId, state) {
12617
12459
  }
12618
12460
  function deleteState(sessionId) {
12619
12461
  const path = stateFilePath(sessionId);
12620
- if (existsSync15(path)) {
12462
+ if (existsSync14(path)) {
12621
12463
  try {
12622
12464
  unlinkSync(path);
12623
12465
  } catch {}
@@ -13264,7 +13106,7 @@ async function handlePostToolUseFailure() {
13264
13106
  }
13265
13107
 
13266
13108
  // src/commands/hooks/install.ts
13267
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync7, existsSync as existsSync16, mkdirSync as mkdirSync5 } from "fs";
13109
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, existsSync as existsSync15, mkdirSync as mkdirSync5 } from "fs";
13268
13110
  import { join as join10 } from "path";
13269
13111
 
13270
13112
  class SettingsParseError extends Error {
@@ -13329,10 +13171,10 @@ function migrateV1Hooks(settings) {
13329
13171
  function installHooks(cwd) {
13330
13172
  const claudeDir = join10(cwd, ".claude");
13331
13173
  const settingsPath = join10(claudeDir, "settings.local.json");
13332
- const existed = existsSync16(settingsPath);
13174
+ const existed = existsSync15(settingsPath);
13333
13175
  let settings = {};
13334
13176
  if (existed) {
13335
- const raw = readFileSync13(settingsPath, "utf-8");
13177
+ const raw = readFileSync12(settingsPath, "utf-8");
13336
13178
  try {
13337
13179
  settings = JSON.parse(raw);
13338
13180
  } catch (err) {
@@ -13367,7 +13209,7 @@ function installHooks(cwd) {
13367
13209
  }
13368
13210
  let userWarning;
13369
13211
  if (added.length > 0 || migrated.length > 0) {
13370
- if (!existsSync16(claudeDir)) {
13212
+ if (!existsSync15(claudeDir)) {
13371
13213
  mkdirSync5(claudeDir, { recursive: true });
13372
13214
  }
13373
13215
  writeFileSync7(settingsPath, JSON.stringify(settings, null, 2) + `
@@ -13517,7 +13359,7 @@ import { Command as Command20 } from "commander";
13517
13359
  import chalk38 from "chalk";
13518
13360
  init_errors();
13519
13361
  init_config();
13520
- import { readFileSync as readFileSync14, existsSync as existsSync17 } from "fs";
13362
+ import { readFileSync as readFileSync13, existsSync as existsSync16 } from "fs";
13521
13363
  import { join as join11, dirname as dirname2 } from "path";
13522
13364
  import { fileURLToPath } from "url";
13523
13365
  var VALID_CATEGORIES = ["bug", "feature", "improvement", "praise"];
@@ -13528,7 +13370,7 @@ function getCliVersion() {
13528
13370
  try {
13529
13371
  const __dirname2 = dirname2(fileURLToPath(import.meta.url));
13530
13372
  const pkgPath = join11(__dirname2, "..", "..", "package.json");
13531
- const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
13373
+ const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
13532
13374
  return pkg.version ?? "0.1.1";
13533
13375
  } catch {
13534
13376
  return "0.1.1";
@@ -13559,12 +13401,12 @@ async function resolveContextSource(source, _readStdinOverride) {
13559
13401
  raw = await (_readStdinOverride ?? readStdin2)();
13560
13402
  } else if (source.startsWith("@")) {
13561
13403
  const filePath = source.slice(1);
13562
- if (!existsSync17(filePath)) {
13404
+ if (!existsSync16(filePath)) {
13563
13405
  throw new MutagentError("INVALID_ARGUMENTS", `Context file not found: ${filePath}`, `Verify the path exists: ls -la "${filePath}"
13564
13406
  Or use inline JSON: --context '{"key":"value"}'`);
13565
13407
  }
13566
13408
  try {
13567
- raw = readFileSync14(filePath, "utf-8").trim();
13409
+ raw = readFileSync13(filePath, "utf-8").trim();
13568
13410
  } catch (err) {
13569
13411
  const msg = err instanceof Error ? err.message : String(err);
13570
13412
  throw new MutagentError("INVALID_ARGUMENTS", `Cannot read context file "${filePath}": ${msg}`, `Check file permissions: ls -la "${filePath}"`);
@@ -13717,7 +13559,7 @@ if (process.env.CLI_VERSION) {
13717
13559
  try {
13718
13560
  const __dirname2 = dirname3(fileURLToPath2(import.meta.url));
13719
13561
  const pkgPath = join12(__dirname2, "..", "..", "package.json");
13720
- const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
13562
+ const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
13721
13563
  cliVersion = pkg.version ?? cliVersion;
13722
13564
  } catch {}
13723
13565
  }
@@ -13912,11 +13754,11 @@ var isInteractive = process.stdin.isTTY && !rawArgs.includes("--json") && proces
13912
13754
  var isSkillCommand = rawArgs[0] === "skills" || rawArgs[0] === "hooks";
13913
13755
  if (isInteractive && !isSkillCommand) {
13914
13756
  const skillPath = join12(process.cwd(), ".claude/skills/mutagent-cli/SKILL.md");
13915
- if (!existsSync18(skillPath)) {
13757
+ if (!existsSync17(skillPath)) {
13916
13758
  console.log(chalk39.dim("MutagenT SKILL not installed. Install it for AI agent support? Run:"), chalk39.cyan("mutagent skills install"));
13917
13759
  }
13918
13760
  }
13919
13761
  program.parse();
13920
13762
 
13921
- //# debugId=62DF92692E0B964164756E2164756E21
13763
+ //# debugId=A09C6E604196CA3164756E2164756E21
13922
13764
  //# sourceMappingURL=cli.js.map