@mutagent/cli 0.1.9 → 0.1.11
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 +412 -46
- package/dist/bin/cli.js.map +9 -8
- package/dist/index.js +57 -1
- package/dist/index.js.map +4 -4
- package/package.json +2 -2
package/dist/bin/cli.js
CHANGED
|
@@ -19,10 +19,10 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
19
19
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
20
|
|
|
21
21
|
// src/bin/cli.ts
|
|
22
|
-
import { Command as
|
|
23
|
-
import
|
|
24
|
-
import { readFileSync as
|
|
25
|
-
import { join as
|
|
22
|
+
import { Command as Command12 } from "commander";
|
|
23
|
+
import chalk13 from "chalk";
|
|
24
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
25
|
+
import { join as join3, dirname } from "path";
|
|
26
26
|
import { fileURLToPath } from "url";
|
|
27
27
|
|
|
28
28
|
// src/commands/auth.ts
|
|
@@ -211,8 +211,22 @@ class AuthenticationError extends MutagentError {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
class ApiError extends MutagentError {
|
|
214
|
+
statusCode;
|
|
214
215
|
constructor(status, message) {
|
|
215
216
|
super(`API_${status}`, message, status === 401 ? "Check your API key with: mutagent auth status" : undefined, 1);
|
|
217
|
+
this.statusCode = status;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
var WORKSPACE_REMEDIATION_MESSAGE = [
|
|
221
|
+
"Workspace context missing. To fix:",
|
|
222
|
+
" mutagent config set workspace <workspace-id> # Set default workspace",
|
|
223
|
+
" mutagent workspaces list # List available workspaces"
|
|
224
|
+
].join(`
|
|
225
|
+
`);
|
|
226
|
+
|
|
227
|
+
class WorkspaceContextError extends MutagentError {
|
|
228
|
+
constructor(message) {
|
|
229
|
+
super("WORKSPACE_CONTEXT_MISSING", message ?? "Workspace context is required but not configured", "Run: mutagent config set workspace <workspace-id>", 3);
|
|
216
230
|
}
|
|
217
231
|
}
|
|
218
232
|
|
|
@@ -232,12 +246,33 @@ function handleError(error, isJson) {
|
|
|
232
246
|
ciCd: "mutagent auth login --api-key <key>"
|
|
233
247
|
};
|
|
234
248
|
}
|
|
249
|
+
if (error instanceof WorkspaceContextError) {
|
|
250
|
+
jsonOutput.remediation = {
|
|
251
|
+
setWorkspace: "mutagent config set workspace <workspace-id>",
|
|
252
|
+
listWorkspaces: "mutagent workspaces list"
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
if (error instanceof ApiError && error.statusCode === 403) {
|
|
256
|
+
jsonOutput.remediation = {
|
|
257
|
+
interactive: "mutagent auth login --browser",
|
|
258
|
+
nonInteractive: "export MUTAGENT_API_KEY=<your-key>",
|
|
259
|
+
checkPermissions: "Verify your API key has the required permissions"
|
|
260
|
+
};
|
|
261
|
+
}
|
|
235
262
|
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
236
263
|
} else {
|
|
237
264
|
console.error(`Error: ${error.message}`);
|
|
238
265
|
if (error instanceof AuthenticationError) {
|
|
239
266
|
console.error("");
|
|
240
267
|
console.error(AUTH_REMEDIATION_MESSAGE);
|
|
268
|
+
} else if (error instanceof WorkspaceContextError) {
|
|
269
|
+
console.error("");
|
|
270
|
+
console.error(WORKSPACE_REMEDIATION_MESSAGE);
|
|
271
|
+
} else if (error instanceof ApiError && error.statusCode === 403) {
|
|
272
|
+
console.error("");
|
|
273
|
+
console.error("Access denied. To fix:");
|
|
274
|
+
console.error(" mutagent auth login --browser # Re-authenticate");
|
|
275
|
+
console.error(" export MUTAGENT_API_KEY=mt_xxx # Or use a different API key");
|
|
241
276
|
} else if (error instanceof ValidationError) {
|
|
242
277
|
if (error.suggestion) {
|
|
243
278
|
console.error(`Suggestion: ${error.suggestion}`);
|
|
@@ -313,6 +348,13 @@ class SDKClientWrapper {
|
|
|
313
348
|
if (err.statusCode === 401) {
|
|
314
349
|
throw new AuthenticationError;
|
|
315
350
|
}
|
|
351
|
+
if (err.statusCode === 403) {
|
|
352
|
+
throw new ApiError(403, err.message ?? err.body ?? "Access denied");
|
|
353
|
+
}
|
|
354
|
+
const errMessage = (err.message ?? err.body ?? "").toLowerCase();
|
|
355
|
+
if (errMessage.includes("workspace") && (errMessage.includes("missing") || errMessage.includes("required")) || errMessage.includes("x-workspace-id")) {
|
|
356
|
+
throw new WorkspaceContextError(err.message ?? err.body ?? undefined);
|
|
357
|
+
}
|
|
316
358
|
if (err.statusCode) {
|
|
317
359
|
throw new ApiError(err.statusCode, err.message ?? err.body ?? "Unknown error");
|
|
318
360
|
}
|
|
@@ -359,7 +401,14 @@ class SDKClientWrapper {
|
|
|
359
401
|
if (response.status === 401) {
|
|
360
402
|
throw new AuthenticationError;
|
|
361
403
|
}
|
|
404
|
+
if (response.status === 403) {
|
|
405
|
+
throw new ApiError(403, await response.text() || "Access denied");
|
|
406
|
+
}
|
|
362
407
|
const error = await response.text();
|
|
408
|
+
const errorLower = error.toLowerCase();
|
|
409
|
+
if (errorLower.includes("workspace") && (errorLower.includes("missing") || errorLower.includes("required")) || errorLower.includes("x-workspace-id")) {
|
|
410
|
+
throw new WorkspaceContextError(error);
|
|
411
|
+
}
|
|
363
412
|
throw new ApiError(response.status, error);
|
|
364
413
|
}
|
|
365
414
|
return response.json();
|
|
@@ -754,7 +803,14 @@ class SDKClientWrapper {
|
|
|
754
803
|
if (response.status === 401) {
|
|
755
804
|
throw new AuthenticationError;
|
|
756
805
|
}
|
|
806
|
+
if (response.status === 403) {
|
|
807
|
+
throw new ApiError(403, await response.text() || "Access denied");
|
|
808
|
+
}
|
|
757
809
|
const error = await response.text();
|
|
810
|
+
const errorLower = error.toLowerCase();
|
|
811
|
+
if (errorLower.includes("workspace") && (errorLower.includes("missing") || errorLower.includes("required")) || errorLower.includes("x-workspace-id")) {
|
|
812
|
+
throw new WorkspaceContextError(error);
|
|
813
|
+
}
|
|
758
814
|
throw new ApiError(response.status, error);
|
|
759
815
|
}
|
|
760
816
|
return response;
|
|
@@ -1580,10 +1636,10 @@ function promptLinks(promptId) {
|
|
|
1580
1636
|
|
|
1581
1637
|
// src/commands/prompts.ts
|
|
1582
1638
|
var PREREQUISITES_TEXT = `
|
|
1583
|
-
${chalk4.yellow("Prerequisites
|
|
1584
|
-
1.
|
|
1585
|
-
2.
|
|
1586
|
-
|
|
1639
|
+
${chalk4.yellow("Prerequisites:")}
|
|
1640
|
+
1. Evaluation criteria defined ${chalk4.dim("(via dashboard or evaluation create)")}
|
|
1641
|
+
2. Dataset uploaded ${chalk4.dim("mutagent prompts dataset list <prompt-id>")}
|
|
1642
|
+
${chalk4.dim("Note: LLM provider config is only required when the server uses external providers (USE_EXT_PROVIDERS=true)")}`;
|
|
1587
1643
|
function parseValidationErrors(error) {
|
|
1588
1644
|
if (error instanceof ApiError) {
|
|
1589
1645
|
try {
|
|
@@ -1603,6 +1659,17 @@ function parseValidationErrors(error) {
|
|
|
1603
1659
|
}
|
|
1604
1660
|
return ["An unknown error occurred"];
|
|
1605
1661
|
}
|
|
1662
|
+
function isMissingOutputSchema(data) {
|
|
1663
|
+
const schema = data.outputSchema;
|
|
1664
|
+
if (schema === null || schema === undefined)
|
|
1665
|
+
return true;
|
|
1666
|
+
if (typeof schema === "object" && Object.keys(schema).length === 0)
|
|
1667
|
+
return true;
|
|
1668
|
+
return false;
|
|
1669
|
+
}
|
|
1670
|
+
function warnMissingOutputSchema(output) {
|
|
1671
|
+
output.warn("No outputSchema provided. Optimization jobs require an outputSchema to validate outputs. " + "Prompts without outputSchema cannot be optimized.");
|
|
1672
|
+
}
|
|
1606
1673
|
function warnSingleBraceVariables(content, output) {
|
|
1607
1674
|
const singleBracePattern = /(?<!\{)\{([a-zA-Z_][a-zA-Z0-9_]*)\}(?!\})/g;
|
|
1608
1675
|
const matches = [...content.matchAll(singleBracePattern)];
|
|
@@ -1613,14 +1680,6 @@ function warnSingleBraceVariables(content, output) {
|
|
|
1613
1680
|
}
|
|
1614
1681
|
}
|
|
1615
1682
|
}
|
|
1616
|
-
async function checkProviderConfigured() {
|
|
1617
|
-
const client = getSDKClient();
|
|
1618
|
-
const providers = await client.listProviders();
|
|
1619
|
-
if (providers.data.length === 0) {
|
|
1620
|
-
throw new MutagentError("NO_PROVIDER", "No LLM provider configured. Evaluations and optimizations require at least one active provider.", `Configure a provider at: ${providerSettingsLink()}
|
|
1621
|
-
Or check: mutagent providers list`);
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
1683
|
function parseDatasetFile(rawContent, filePath) {
|
|
1625
1684
|
const trimmed = rawContent.trim();
|
|
1626
1685
|
if (filePath.endsWith(".csv")) {
|
|
@@ -1802,6 +1861,9 @@ ${chalk4.dim("Hint: Use --file with JSON or --raw-file for plain text. Get promp
|
|
|
1802
1861
|
if (promptContent && !isJson) {
|
|
1803
1862
|
warnSingleBraceVariables(promptContent, output);
|
|
1804
1863
|
}
|
|
1864
|
+
if (isMissingOutputSchema(data)) {
|
|
1865
|
+
warnMissingOutputSchema(output);
|
|
1866
|
+
}
|
|
1805
1867
|
const client = getSDKClient();
|
|
1806
1868
|
const prompt = await client.createPrompt(data);
|
|
1807
1869
|
if (isJson) {
|
|
@@ -1871,6 +1933,9 @@ Examples:
|
|
|
1871
1933
|
if (promptContent && !isJson) {
|
|
1872
1934
|
warnSingleBraceVariables(promptContent, output);
|
|
1873
1935
|
}
|
|
1936
|
+
if (options.file && isMissingOutputSchema(data)) {
|
|
1937
|
+
warnMissingOutputSchema(output);
|
|
1938
|
+
}
|
|
1874
1939
|
const client = getSDKClient();
|
|
1875
1940
|
const prompt = await client.updatePrompt(id, data);
|
|
1876
1941
|
if (isJson) {
|
|
@@ -2149,8 +2214,13 @@ ${chalk4.dim("Monitor progress with: mutagent prompts optimize status <job-id>")
|
|
|
2149
2214
|
const isJson = getJsonFlag(prompts);
|
|
2150
2215
|
const output = new OutputFormatter(isJson ? "json" : "table");
|
|
2151
2216
|
try {
|
|
2152
|
-
await checkProviderConfigured();
|
|
2153
2217
|
const client = getSDKClient();
|
|
2218
|
+
try {
|
|
2219
|
+
const promptData = await client.getPrompt(promptId);
|
|
2220
|
+
if (isMissingOutputSchema(promptData)) {
|
|
2221
|
+
output.warn("This prompt has no outputSchema defined. Optimization jobs require an outputSchema to validate outputs. " + "The job may fail at the dataset analysis stage. " + "Add an outputSchema via: mutagent prompts update " + promptId + " --file prompt-with-schema.json");
|
|
2222
|
+
}
|
|
2223
|
+
} catch {}
|
|
2154
2224
|
const job = await client.startOptimization(promptId, options.dataset, {
|
|
2155
2225
|
maxIterations: options.maxIterations ? parseInt(options.maxIterations, 10) : undefined,
|
|
2156
2226
|
targetScore: options.targetScore ? parseFloat(options.targetScore) : undefined,
|
|
@@ -4523,15 +4593,308 @@ Available Models:`));
|
|
|
4523
4593
|
return providers;
|
|
4524
4594
|
}
|
|
4525
4595
|
|
|
4596
|
+
// src/commands/init.ts
|
|
4597
|
+
import { Command as Command11 } from "commander";
|
|
4598
|
+
import inquirer3 from "inquirer";
|
|
4599
|
+
import chalk12 from "chalk";
|
|
4600
|
+
import { existsSync as existsSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "fs";
|
|
4601
|
+
import { execSync as execSync2 } from "child_process";
|
|
4602
|
+
import { join as join2 } from "path";
|
|
4603
|
+
var FRAMEWORK_DETECTION_MAP = {
|
|
4604
|
+
"@mastra/core": {
|
|
4605
|
+
name: "mastra",
|
|
4606
|
+
displayName: "Mastra",
|
|
4607
|
+
npmPackage: "@mastra/core"
|
|
4608
|
+
},
|
|
4609
|
+
"@langchain/langgraph": {
|
|
4610
|
+
name: "langgraph",
|
|
4611
|
+
displayName: "LangGraph",
|
|
4612
|
+
npmPackage: "@langchain/langgraph",
|
|
4613
|
+
mutagentPackage: "@mutagent/langgraph"
|
|
4614
|
+
},
|
|
4615
|
+
langchain: {
|
|
4616
|
+
name: "langchain",
|
|
4617
|
+
displayName: "LangChain",
|
|
4618
|
+
npmPackage: "langchain",
|
|
4619
|
+
mutagentPackage: "@mutagent/langchain"
|
|
4620
|
+
},
|
|
4621
|
+
"@langchain/core": {
|
|
4622
|
+
name: "langchain",
|
|
4623
|
+
displayName: "LangChain",
|
|
4624
|
+
npmPackage: "@langchain/core",
|
|
4625
|
+
mutagentPackage: "@mutagent/langchain"
|
|
4626
|
+
},
|
|
4627
|
+
"@ai-sdk/core": {
|
|
4628
|
+
name: "vercel-ai",
|
|
4629
|
+
displayName: "Vercel AI SDK",
|
|
4630
|
+
npmPackage: "@ai-sdk/core",
|
|
4631
|
+
mutagentPackage: "@mutagent/vercel-ai"
|
|
4632
|
+
},
|
|
4633
|
+
ai: {
|
|
4634
|
+
name: "vercel-ai",
|
|
4635
|
+
displayName: "Vercel AI SDK",
|
|
4636
|
+
npmPackage: "ai",
|
|
4637
|
+
mutagentPackage: "@mutagent/vercel-ai"
|
|
4638
|
+
},
|
|
4639
|
+
"@google/genai": {
|
|
4640
|
+
name: "generic",
|
|
4641
|
+
displayName: "Google GenAI",
|
|
4642
|
+
npmPackage: "@google/genai"
|
|
4643
|
+
},
|
|
4644
|
+
openai: {
|
|
4645
|
+
name: "openai",
|
|
4646
|
+
displayName: "OpenAI SDK",
|
|
4647
|
+
npmPackage: "openai",
|
|
4648
|
+
mutagentPackage: "@mutagent/openai"
|
|
4649
|
+
}
|
|
4650
|
+
};
|
|
4651
|
+
function detectPackageManager2(cwd = process.cwd()) {
|
|
4652
|
+
if (existsSync10(join2(cwd, "bun.lockb")) || existsSync10(join2(cwd, "bun.lock"))) {
|
|
4653
|
+
return "bun";
|
|
4654
|
+
}
|
|
4655
|
+
if (existsSync10(join2(cwd, "pnpm-lock.yaml"))) {
|
|
4656
|
+
return "pnpm";
|
|
4657
|
+
}
|
|
4658
|
+
if (existsSync10(join2(cwd, "yarn.lock"))) {
|
|
4659
|
+
return "yarn";
|
|
4660
|
+
}
|
|
4661
|
+
if (existsSync10(join2(cwd, "package-lock.json"))) {
|
|
4662
|
+
return "npm";
|
|
4663
|
+
}
|
|
4664
|
+
try {
|
|
4665
|
+
execSync2("bun --version", { stdio: "ignore" });
|
|
4666
|
+
return "bun";
|
|
4667
|
+
} catch {
|
|
4668
|
+
return "npm";
|
|
4669
|
+
}
|
|
4670
|
+
}
|
|
4671
|
+
function getInstallCommand2(pm, packages) {
|
|
4672
|
+
const pkgList = packages.join(" ");
|
|
4673
|
+
const commands = {
|
|
4674
|
+
bun: `bun add ${pkgList}`,
|
|
4675
|
+
npm: `npm install ${pkgList}`,
|
|
4676
|
+
yarn: `yarn add ${pkgList}`,
|
|
4677
|
+
pnpm: `pnpm add ${pkgList}`
|
|
4678
|
+
};
|
|
4679
|
+
return commands[pm];
|
|
4680
|
+
}
|
|
4681
|
+
function detectFrameworkFromPackageJson(cwd = process.cwd()) {
|
|
4682
|
+
const pkgPath = join2(cwd, "package.json");
|
|
4683
|
+
if (!existsSync10(pkgPath)) {
|
|
4684
|
+
return null;
|
|
4685
|
+
}
|
|
4686
|
+
let pkg;
|
|
4687
|
+
try {
|
|
4688
|
+
pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
|
|
4689
|
+
} catch {
|
|
4690
|
+
return null;
|
|
4691
|
+
}
|
|
4692
|
+
const allDeps = {
|
|
4693
|
+
...pkg.dependencies,
|
|
4694
|
+
...pkg.devDependencies
|
|
4695
|
+
};
|
|
4696
|
+
for (const [depName, framework] of Object.entries(FRAMEWORK_DETECTION_MAP)) {
|
|
4697
|
+
if (depName in allDeps) {
|
|
4698
|
+
return framework;
|
|
4699
|
+
}
|
|
4700
|
+
}
|
|
4701
|
+
return null;
|
|
4702
|
+
}
|
|
4703
|
+
function hasRcConfig(cwd = process.cwd()) {
|
|
4704
|
+
return existsSync10(join2(cwd, ".mutagentrc.json"));
|
|
4705
|
+
}
|
|
4706
|
+
function writeRcConfig(config, cwd = process.cwd()) {
|
|
4707
|
+
const rcPath = join2(cwd, ".mutagentrc.json");
|
|
4708
|
+
writeFileSync3(rcPath, JSON.stringify(config, null, 2) + `
|
|
4709
|
+
`);
|
|
4710
|
+
}
|
|
4711
|
+
function createInitCommand() {
|
|
4712
|
+
const init = new Command11("init").description("Initialize MutagenT in your project").option("--non-interactive", "Skip interactive prompts (defaults to CLI-only mode)").addHelpText("after", `
|
|
4713
|
+
Examples:
|
|
4714
|
+
${chalk12.dim("$")} mutagent init # Interactive setup wizard
|
|
4715
|
+
${chalk12.dim("$")} mutagent init --non-interactive # CLI-only mode (no prompts)
|
|
4716
|
+
|
|
4717
|
+
Modes:
|
|
4718
|
+
${chalk12.bold("Full scaffold")} Install SDK + integration package, create config, setup tracing
|
|
4719
|
+
${chalk12.bold("CLI-only")} Verify auth + create .mutagentrc.json with workspace/endpoint
|
|
4720
|
+
${chalk12.bold("Skip")} Exit without changes
|
|
4721
|
+
`).action(async (options) => {
|
|
4722
|
+
const isJson = getJsonFlag(init);
|
|
4723
|
+
const output = new OutputFormatter(isJson ? "json" : "table");
|
|
4724
|
+
try {
|
|
4725
|
+
const isNonInteractive = options.nonInteractive === true || process.env.MUTAGENT_NON_INTERACTIVE === "true" || process.env.CI === "true" || !process.stdin.isTTY;
|
|
4726
|
+
const cwd = process.cwd();
|
|
4727
|
+
if (hasRcConfig(cwd)) {
|
|
4728
|
+
output.warn(".mutagentrc.json already exists in this directory.");
|
|
4729
|
+
if (isNonInteractive) {
|
|
4730
|
+
output.info("Use --force to overwrite (not yet supported). Exiting.");
|
|
4731
|
+
return;
|
|
4732
|
+
}
|
|
4733
|
+
const { overwrite } = await inquirer3.prompt([{
|
|
4734
|
+
type: "confirm",
|
|
4735
|
+
name: "overwrite",
|
|
4736
|
+
message: ".mutagentrc.json already exists. Overwrite?",
|
|
4737
|
+
default: false
|
|
4738
|
+
}]);
|
|
4739
|
+
if (!overwrite) {
|
|
4740
|
+
output.info("Init cancelled.");
|
|
4741
|
+
return;
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
const authenticated = hasCredentials();
|
|
4745
|
+
if (!authenticated) {
|
|
4746
|
+
output.warn("Not authenticated.");
|
|
4747
|
+
output.info("Run: mutagent auth login --browser");
|
|
4748
|
+
if (isNonInteractive) {
|
|
4749
|
+
throw new MutagentError("AUTH_REQUIRED", "Authentication required before init", "Run: mutagent auth login --browser");
|
|
4750
|
+
}
|
|
4751
|
+
const { doAuth } = await inquirer3.prompt([{
|
|
4752
|
+
type: "confirm",
|
|
4753
|
+
name: "doAuth",
|
|
4754
|
+
message: "Would you like to authenticate now?",
|
|
4755
|
+
default: true
|
|
4756
|
+
}]);
|
|
4757
|
+
if (doAuth) {
|
|
4758
|
+
output.info('Run "mutagent auth login --browser" and then re-run "mutagent init".');
|
|
4759
|
+
return;
|
|
4760
|
+
}
|
|
4761
|
+
}
|
|
4762
|
+
const detectedFramework = detectFrameworkFromPackageJson(cwd);
|
|
4763
|
+
let mode;
|
|
4764
|
+
let confirmedFramework = detectedFramework;
|
|
4765
|
+
if (isNonInteractive) {
|
|
4766
|
+
mode = "cli-only";
|
|
4767
|
+
if (isJson) {
|
|
4768
|
+
output.output({
|
|
4769
|
+
mode: "cli-only",
|
|
4770
|
+
nonInteractive: true,
|
|
4771
|
+
detectedFramework: detectedFramework?.name ?? null
|
|
4772
|
+
});
|
|
4773
|
+
}
|
|
4774
|
+
} else {
|
|
4775
|
+
if (detectedFramework) {
|
|
4776
|
+
output.info(`Detected framework: ${detectedFramework.displayName} (${detectedFramework.npmPackage})`);
|
|
4777
|
+
const { confirmFramework } = await inquirer3.prompt([{
|
|
4778
|
+
type: "confirm",
|
|
4779
|
+
name: "confirmFramework",
|
|
4780
|
+
message: `Use ${detectedFramework.displayName}?`,
|
|
4781
|
+
default: true
|
|
4782
|
+
}]);
|
|
4783
|
+
if (!confirmFramework) {
|
|
4784
|
+
const frameworkChoices = [
|
|
4785
|
+
{ name: "Mastra", value: "mastra" },
|
|
4786
|
+
{ name: "LangChain", value: "langchain" },
|
|
4787
|
+
{ name: "LangGraph", value: "langgraph" },
|
|
4788
|
+
{ name: "Vercel AI SDK", value: "vercel-ai" },
|
|
4789
|
+
{ name: "OpenAI SDK", value: "openai" },
|
|
4790
|
+
{ name: "Generic (OpenAI-compatible)", value: "generic" },
|
|
4791
|
+
{ name: "None / Skip framework", value: "none" }
|
|
4792
|
+
];
|
|
4793
|
+
const { selectedFramework } = await inquirer3.prompt([{
|
|
4794
|
+
type: "list",
|
|
4795
|
+
name: "selectedFramework",
|
|
4796
|
+
message: "Select your AI framework:",
|
|
4797
|
+
choices: frameworkChoices
|
|
4798
|
+
}]);
|
|
4799
|
+
if (selectedFramework === "none") {
|
|
4800
|
+
confirmedFramework = null;
|
|
4801
|
+
} else {
|
|
4802
|
+
const entry = Object.values(FRAMEWORK_DETECTION_MAP).find((f) => f.name === selectedFramework);
|
|
4803
|
+
confirmedFramework = entry ?? null;
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
} else {
|
|
4807
|
+
output.info("No AI framework detected in package.json.");
|
|
4808
|
+
}
|
|
4809
|
+
const modeChoices = [
|
|
4810
|
+
...confirmedFramework?.mutagentPackage ? [{
|
|
4811
|
+
name: `Full scaffold - Install @mutagent/sdk + ${confirmedFramework.mutagentPackage}, create config, setup tracing`,
|
|
4812
|
+
value: "full"
|
|
4813
|
+
}] : [],
|
|
4814
|
+
{
|
|
4815
|
+
name: "CLI-only - Verify auth + create .mutagentrc.json config",
|
|
4816
|
+
value: "cli-only"
|
|
4817
|
+
},
|
|
4818
|
+
{
|
|
4819
|
+
name: "Skip - Exit without changes",
|
|
4820
|
+
value: "skip"
|
|
4821
|
+
}
|
|
4822
|
+
];
|
|
4823
|
+
const { selectedMode } = await inquirer3.prompt([{
|
|
4824
|
+
type: "list",
|
|
4825
|
+
name: "selectedMode",
|
|
4826
|
+
message: "How would you like to initialize MutagenT?",
|
|
4827
|
+
choices: modeChoices
|
|
4828
|
+
}]);
|
|
4829
|
+
mode = selectedMode;
|
|
4830
|
+
}
|
|
4831
|
+
if (mode === "skip") {
|
|
4832
|
+
output.info("Init skipped.");
|
|
4833
|
+
return;
|
|
4834
|
+
}
|
|
4835
|
+
const config = loadConfig();
|
|
4836
|
+
const endpoint = config.endpoint ?? "https://api.mutagent.io";
|
|
4837
|
+
const workspace = config.defaultWorkspace;
|
|
4838
|
+
const rcConfig = {
|
|
4839
|
+
endpoint,
|
|
4840
|
+
...workspace ? { workspace } : {},
|
|
4841
|
+
...confirmedFramework ? { framework: confirmedFramework.name } : {}
|
|
4842
|
+
};
|
|
4843
|
+
if (mode === "full" && confirmedFramework?.mutagentPackage) {
|
|
4844
|
+
const pm = detectPackageManager2(cwd);
|
|
4845
|
+
const packages = ["@mutagent/sdk", confirmedFramework.mutagentPackage];
|
|
4846
|
+
const installCmd = getInstallCommand2(pm, packages);
|
|
4847
|
+
output.info(`Installing: ${packages.join(", ")}`);
|
|
4848
|
+
output.info(`Running: ${installCmd}`);
|
|
4849
|
+
try {
|
|
4850
|
+
execSync2(installCmd, { cwd, stdio: "inherit" });
|
|
4851
|
+
output.success("Packages installed successfully.");
|
|
4852
|
+
} catch {
|
|
4853
|
+
output.error("Package installation failed. You can install manually:");
|
|
4854
|
+
output.info(` ${installCmd}`);
|
|
4855
|
+
}
|
|
4856
|
+
writeRcConfig(rcConfig, cwd);
|
|
4857
|
+
output.success("Created .mutagentrc.json");
|
|
4858
|
+
console.log("");
|
|
4859
|
+
output.info("Next steps:");
|
|
4860
|
+
output.info(` 1. Run: mutagent integrate ${confirmedFramework.name}`);
|
|
4861
|
+
output.info(" 2. Follow the integration guide to add tracing to your code");
|
|
4862
|
+
output.info(" 3. Run: mutagent traces list (to verify traces are arriving)");
|
|
4863
|
+
} else {
|
|
4864
|
+
writeRcConfig(rcConfig, cwd);
|
|
4865
|
+
output.success("Created .mutagentrc.json");
|
|
4866
|
+
if (!authenticated) {
|
|
4867
|
+
output.info("Next: mutagent auth login --browser");
|
|
4868
|
+
} else {
|
|
4869
|
+
output.info('Ready! Run "mutagent --help" to see available commands.');
|
|
4870
|
+
}
|
|
4871
|
+
}
|
|
4872
|
+
if (isJson) {
|
|
4873
|
+
output.output({
|
|
4874
|
+
success: true,
|
|
4875
|
+
mode,
|
|
4876
|
+
configFile: ".mutagentrc.json",
|
|
4877
|
+
config: rcConfig,
|
|
4878
|
+
framework: confirmedFramework?.name ?? null,
|
|
4879
|
+
authenticated
|
|
4880
|
+
});
|
|
4881
|
+
}
|
|
4882
|
+
} catch (error) {
|
|
4883
|
+
handleError(error, isJson);
|
|
4884
|
+
}
|
|
4885
|
+
});
|
|
4886
|
+
return init;
|
|
4887
|
+
}
|
|
4888
|
+
|
|
4526
4889
|
// src/bin/cli.ts
|
|
4527
4890
|
var cliVersion = "0.1.1";
|
|
4528
4891
|
try {
|
|
4529
4892
|
const __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
4530
|
-
const pkgPath =
|
|
4531
|
-
const pkg = JSON.parse(
|
|
4893
|
+
const pkgPath = join3(__dirname2, "..", "..", "package.json");
|
|
4894
|
+
const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
|
|
4532
4895
|
cliVersion = pkg.version ?? cliVersion;
|
|
4533
4896
|
} catch {}
|
|
4534
|
-
var program = new
|
|
4897
|
+
var program = new Command12;
|
|
4535
4898
|
program.name("mutagent").description(`MutagenT CLI - AI-native prompt optimization platform
|
|
4536
4899
|
|
|
4537
4900
|
Documentation: https://docs.mutagent.io/cli
|
|
@@ -4540,43 +4903,45 @@ program.name("mutagent").description(`MutagenT CLI - AI-native prompt optimizati
|
|
|
4540
4903
|
showGlobalOptions: true
|
|
4541
4904
|
});
|
|
4542
4905
|
program.addHelpText("after", `
|
|
4543
|
-
${
|
|
4544
|
-
Export your API key: ${
|
|
4545
|
-
Or pass inline: ${
|
|
4546
|
-
Machine-readable output: ${
|
|
4547
|
-
Disable prompts: ${
|
|
4548
|
-
Set default workspace: ${
|
|
4549
|
-
Set default org: ${
|
|
4906
|
+
${chalk13.yellow("Non-Interactive Mode (CI/CD & Coding Agents):")}
|
|
4907
|
+
Export your API key: ${chalk13.green("export MUTAGENT_API_KEY=mt_your_key_here")}
|
|
4908
|
+
Or pass inline: ${chalk13.green("mutagent prompts list --api-key mt_your_key")}
|
|
4909
|
+
Machine-readable output: ${chalk13.green("mutagent prompts list --json")}
|
|
4910
|
+
Disable prompts: ${chalk13.green("mutagent prompts list --non-interactive")}
|
|
4911
|
+
Set default workspace: ${chalk13.green("mutagent config set workspace <workspace-id>")}
|
|
4912
|
+
Set default org: ${chalk13.green("mutagent config set org <org-id>")}
|
|
4550
4913
|
`);
|
|
4551
4914
|
program.addHelpText("after", `
|
|
4552
|
-
${
|
|
4553
|
-
${
|
|
4915
|
+
${chalk13.yellow("Workflows:")}
|
|
4916
|
+
${chalk13.bold("Evaluate → Optimize Loop:")}
|
|
4554
4917
|
1. mutagent prompts create --name "..." --raw-file prompt.txt
|
|
4555
4918
|
2. mutagent prompts dataset add <prompt-id> --name "..." --file data.json
|
|
4556
4919
|
3. mutagent prompts evaluation create <prompt-id> --name "..." --file criteria.json
|
|
4557
4920
|
4. mutagent prompts optimize start <prompt-id> --dataset <id> --max-iterations 3
|
|
4558
4921
|
|
|
4559
|
-
${
|
|
4922
|
+
${chalk13.bold("Quick Test:")}
|
|
4560
4923
|
mutagent playground run <prompt-id> --input '{"key":"value"}'
|
|
4561
4924
|
|
|
4562
|
-
${
|
|
4563
|
-
${
|
|
4564
|
-
${
|
|
4565
|
-
${
|
|
4566
|
-
${
|
|
4925
|
+
${chalk13.bold("Prerequisites for Optimization:")}
|
|
4926
|
+
${chalk13.green("✓")} Prompt with input/output parameters
|
|
4927
|
+
${chalk13.green("✓")} Dataset with items (input + expectedOutput pairs)
|
|
4928
|
+
${chalk13.green("✓")} Evaluation with criteria (field-level, input/output focused)
|
|
4929
|
+
${chalk13.dim("•")} LLM provider ${chalk13.dim("(only when server uses external providers)")}
|
|
4567
4930
|
`);
|
|
4568
4931
|
program.addHelpText("after", `
|
|
4569
|
-
${
|
|
4570
|
-
${
|
|
4571
|
-
${
|
|
4572
|
-
${
|
|
4573
|
-
${
|
|
4574
|
-
${
|
|
4575
|
-
${
|
|
4576
|
-
${
|
|
4577
|
-
${
|
|
4578
|
-
${!hasCredentials() ?
|
|
4932
|
+
${chalk13.cyan("┌─ AI AGENT INTEGRATION HINT ────────────────────────────────────────────────┐")}
|
|
4933
|
+
${chalk13.cyan("│")} ${chalk13.cyan("│")}
|
|
4934
|
+
${chalk13.cyan("│")} Frameworks: mastra, langchain, langgraph, vercel-ai, claude-code, generic ${chalk13.cyan("│")}
|
|
4935
|
+
${chalk13.cyan("│")} ${chalk13.cyan("│")}
|
|
4936
|
+
${chalk13.cyan("│")} Get integration guide: mutagent integrate <framework> ${chalk13.cyan("│")}
|
|
4937
|
+
${chalk13.cyan("│")} Verify setup: mutagent integrate <framework> --verify ${chalk13.cyan("│")}
|
|
4938
|
+
${chalk13.cyan("│")} Use --json for AI parsing: mutagent <command> --json ${chalk13.cyan("│")}
|
|
4939
|
+
${chalk13.cyan("│")} ${chalk13.cyan("│")}
|
|
4940
|
+
${chalk13.cyan("└────────────────────────────────────────────────────────────────────────────┘")}
|
|
4941
|
+
${!hasCredentials() ? chalk13.yellow(`
|
|
4579
4942
|
Warning: Not authenticated. Run: mutagent auth login --browser
|
|
4943
|
+
`) : ""}${!hasRcConfig() ? chalk13.green(`
|
|
4944
|
+
Get started: mutagent init
|
|
4580
4945
|
`) : ""}`);
|
|
4581
4946
|
program.hook("preAction", (thisCommand) => {
|
|
4582
4947
|
const globalOpts = thisCommand.optsWithGlobals();
|
|
@@ -4590,6 +4955,7 @@ program.hook("preAction", (thisCommand) => {
|
|
|
4590
4955
|
process.env.MUTAGENT_NON_INTERACTIVE = "true";
|
|
4591
4956
|
}
|
|
4592
4957
|
});
|
|
4958
|
+
program.addCommand(createInitCommand());
|
|
4593
4959
|
program.addCommand(createLoginCommand());
|
|
4594
4960
|
program.addCommand(createAuthCommand());
|
|
4595
4961
|
program.addCommand(createConfigCommand());
|
|
@@ -4602,5 +4968,5 @@ program.addCommand(createWorkspacesCommand());
|
|
|
4602
4968
|
program.addCommand(createProvidersCommand());
|
|
4603
4969
|
program.parse();
|
|
4604
4970
|
|
|
4605
|
-
//# debugId=
|
|
4971
|
+
//# debugId=33AA6EB433FA7E6264756E2164756E21
|
|
4606
4972
|
//# sourceMappingURL=cli.js.map
|