@mutagent/cli 0.1.208 → 0.1.210
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 +229 -362
- package/dist/bin/cli.js.map +16 -16
- package/dist/index.js +2 -2
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -379,7 +379,7 @@ class SDKClientWrapper {
|
|
|
379
379
|
}
|
|
380
380
|
if (error instanceof TypeError && typeof error.message === "string") {
|
|
381
381
|
if (error.message.includes("fetch") || error.message.includes("network") || error.message.includes("ECONNREFUSED")) {
|
|
382
|
-
throw new MutagentError("NETWORK_ERROR", "Unable to connect to the
|
|
382
|
+
throw new MutagentError("NETWORK_ERROR", "Unable to connect to the Mutagent server", "Check your internet connection and verify the server URL with: mutagent config list");
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
385
|
if (error instanceof Error) {
|
|
@@ -728,8 +728,8 @@ var init_sdk_client = __esm(() => {
|
|
|
728
728
|
// src/bin/cli.ts
|
|
729
729
|
import { Command as Command12 } from "commander";
|
|
730
730
|
import chalk18 from "chalk";
|
|
731
|
-
import { readFileSync as
|
|
732
|
-
import { join as
|
|
731
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
732
|
+
import { join as join13, dirname as dirname3 } from "path";
|
|
733
733
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
734
734
|
|
|
735
735
|
// src/commands/auth.ts
|
|
@@ -946,70 +946,6 @@ import { writeFileSync as writeFileSync2 } from "fs";
|
|
|
946
946
|
// src/lib/framework-detection.ts
|
|
947
947
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
948
948
|
import { join as join3 } from "path";
|
|
949
|
-
var FRAMEWORK_DETECTION_MAP = {
|
|
950
|
-
"@mastra/core": {
|
|
951
|
-
name: "mastra",
|
|
952
|
-
displayName: "Mastra",
|
|
953
|
-
npmPackage: "@mastra/core"
|
|
954
|
-
},
|
|
955
|
-
"@langchain/langgraph": {
|
|
956
|
-
name: "langgraph",
|
|
957
|
-
displayName: "LangGraph",
|
|
958
|
-
npmPackage: "@langchain/langgraph"
|
|
959
|
-
},
|
|
960
|
-
langchain: {
|
|
961
|
-
name: "langchain",
|
|
962
|
-
displayName: "LangChain",
|
|
963
|
-
npmPackage: "langchain"
|
|
964
|
-
},
|
|
965
|
-
"@langchain/core": {
|
|
966
|
-
name: "langchain",
|
|
967
|
-
displayName: "LangChain",
|
|
968
|
-
npmPackage: "@langchain/core"
|
|
969
|
-
},
|
|
970
|
-
"@ai-sdk/core": {
|
|
971
|
-
name: "vercel-ai",
|
|
972
|
-
displayName: "Vercel AI SDK",
|
|
973
|
-
npmPackage: "@ai-sdk/core"
|
|
974
|
-
},
|
|
975
|
-
ai: {
|
|
976
|
-
name: "vercel-ai",
|
|
977
|
-
displayName: "Vercel AI SDK",
|
|
978
|
-
npmPackage: "ai"
|
|
979
|
-
},
|
|
980
|
-
"@google/genai": {
|
|
981
|
-
name: "generic",
|
|
982
|
-
displayName: "Google GenAI",
|
|
983
|
-
npmPackage: "@google/genai"
|
|
984
|
-
},
|
|
985
|
-
openai: {
|
|
986
|
-
name: "openai",
|
|
987
|
-
displayName: "OpenAI SDK",
|
|
988
|
-
npmPackage: "openai"
|
|
989
|
-
}
|
|
990
|
-
};
|
|
991
|
-
function detectFrameworkFromPackageJson(cwd = process.cwd()) {
|
|
992
|
-
const pkgPath = join3(cwd, "package.json");
|
|
993
|
-
if (!existsSync3(pkgPath)) {
|
|
994
|
-
return null;
|
|
995
|
-
}
|
|
996
|
-
let pkg;
|
|
997
|
-
try {
|
|
998
|
-
pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
|
|
999
|
-
} catch {
|
|
1000
|
-
return null;
|
|
1001
|
-
}
|
|
1002
|
-
const allDeps = {
|
|
1003
|
-
...pkg.dependencies,
|
|
1004
|
-
...pkg.devDependencies
|
|
1005
|
-
};
|
|
1006
|
-
for (const [depName, framework] of Object.entries(FRAMEWORK_DETECTION_MAP)) {
|
|
1007
|
-
if (depName in allDeps) {
|
|
1008
|
-
return framework;
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
return null;
|
|
1012
|
-
}
|
|
1013
949
|
function hasRcConfig(cwd = process.cwd()) {
|
|
1014
950
|
return existsSync3(join3(cwd, ".mutagentrc.json"));
|
|
1015
951
|
}
|
|
@@ -1145,7 +1081,7 @@ async function fetchDescriptor(fetchImpl, auth, version) {
|
|
|
1145
1081
|
headers: { "x-api-key": auth.apiKey, ...auth.headers }
|
|
1146
1082
|
});
|
|
1147
1083
|
} catch {
|
|
1148
|
-
throw new MutagentError("SERVER_UNAVAILABLE", "Could not reach the
|
|
1084
|
+
throw new MutagentError("SERVER_UNAVAILABLE", "Could not reach the Mutagent plugin broker.", "Check your network connection or verify the endpoint with: mutagent config show");
|
|
1149
1085
|
}
|
|
1150
1086
|
if (res.status === 401) {
|
|
1151
1087
|
throw new MutagentError("AUTH_REQUIRED", "The plugin broker rejected your credentials.", "Re-authenticate: mutagent login");
|
|
@@ -1568,7 +1504,7 @@ async function performLoginAction(opts) {
|
|
|
1568
1504
|
}
|
|
1569
1505
|
if (!isNonInteractive && wasFirstLogin) {
|
|
1570
1506
|
console.log(`
|
|
1571
|
-
` + chalk3.bold.cyan(" Welcome to
|
|
1507
|
+
` + chalk3.bold.cyan(" Welcome to Mutagent CLI!") + `
|
|
1572
1508
|
`);
|
|
1573
1509
|
console.log(` No credentials found. Please authenticate to continue.
|
|
1574
1510
|
`);
|
|
@@ -1686,7 +1622,7 @@ async function loginWithPastedKey(initialEndpoint, output, wasFirstLogin) {
|
|
|
1686
1622
|
{
|
|
1687
1623
|
type: "input",
|
|
1688
1624
|
name: "endpoint",
|
|
1689
|
-
message: "
|
|
1625
|
+
message: "Mutagent endpoint:",
|
|
1690
1626
|
default: initialEndpoint
|
|
1691
1627
|
},
|
|
1692
1628
|
{
|
|
@@ -1767,7 +1703,7 @@ async function loginWithPastedKey(initialEndpoint, output, wasFirstLogin) {
|
|
|
1767
1703
|
|
|
1768
1704
|
// src/commands/auth.ts
|
|
1769
1705
|
function createAuthCommand() {
|
|
1770
|
-
const auth = new Command("auth").description("Authenticate with
|
|
1706
|
+
const auth = new Command("auth").description("Authenticate with Mutagent platform").addHelpText("after", `
|
|
1771
1707
|
Examples:
|
|
1772
1708
|
${chalk4.dim("$")} mutagent auth login
|
|
1773
1709
|
${chalk4.dim("$")} mutagent auth login --browser
|
|
@@ -1901,7 +1837,7 @@ import { Command as Command2 } from "commander";
|
|
|
1901
1837
|
import chalk5 from "chalk";
|
|
1902
1838
|
init_errors();
|
|
1903
1839
|
function createLoginCommand() {
|
|
1904
|
-
const login = new Command2("login").description("Login to
|
|
1840
|
+
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", `
|
|
1905
1841
|
Examples:
|
|
1906
1842
|
${chalk5.dim("$")} mutagent login ${chalk5.dim("# Browser OAuth (recommended — handles signup + onboarding)")}
|
|
1907
1843
|
${chalk5.dim("$")} mutagent login --browser ${chalk5.dim("# Force browser flow (skip method prompt)")}
|
|
@@ -2737,210 +2673,15 @@ Available Models:`));
|
|
|
2737
2673
|
|
|
2738
2674
|
// src/commands/init.ts
|
|
2739
2675
|
init_config();
|
|
2740
|
-
import { Command as
|
|
2741
|
-
import
|
|
2742
|
-
import
|
|
2676
|
+
import { Command as Command7 } from "commander";
|
|
2677
|
+
import chalk13 from "chalk";
|
|
2678
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
2679
|
+
import { join as join8 } from "path";
|
|
2743
2680
|
init_errors();
|
|
2744
|
-
function createInitCommand() {
|
|
2745
|
-
const init = new Command6("init").description("Initialize MutagenT in your project").option("--non-interactive", "Skip interactive prompts (defaults to CLI-only mode)").addHelpText("after", `
|
|
2746
|
-
Examples:
|
|
2747
|
-
${chalk12.dim("$")} mutagent init # Interactive setup wizard
|
|
2748
|
-
${chalk12.dim("$")} mutagent init --non-interactive # CLI-only mode (no prompts)
|
|
2749
|
-
|
|
2750
|
-
Modes:
|
|
2751
|
-
${chalk12.bold("CLI-only")} Verify auth + create .mutagentrc.json with workspace/endpoint
|
|
2752
|
-
${chalk12.bold("Skip")} Exit without changes
|
|
2753
|
-
`).action(async (options) => {
|
|
2754
|
-
const isJson = getJsonFlag(init);
|
|
2755
|
-
const output = new OutputFormatter(isJson ? "json" : "table");
|
|
2756
|
-
try {
|
|
2757
|
-
const isNonInteractive = options.nonInteractive === true || process.env.MUTAGENT_NON_INTERACTIVE === "true" || process.env.CI === "true" || !process.stdin.isTTY;
|
|
2758
|
-
const cwd = process.cwd();
|
|
2759
|
-
if (hasRcConfig(cwd)) {
|
|
2760
|
-
output.warn(".mutagentrc.json already exists in this directory.");
|
|
2761
|
-
if (isNonInteractive) {
|
|
2762
|
-
output.info("Use --force to overwrite (not yet supported). Exiting.");
|
|
2763
|
-
return;
|
|
2764
|
-
}
|
|
2765
|
-
const { overwrite } = await inquirer2.prompt([{
|
|
2766
|
-
type: "confirm",
|
|
2767
|
-
name: "overwrite",
|
|
2768
|
-
message: ".mutagentrc.json already exists. Overwrite?",
|
|
2769
|
-
default: false
|
|
2770
|
-
}]);
|
|
2771
|
-
if (!overwrite) {
|
|
2772
|
-
output.info("Init cancelled.");
|
|
2773
|
-
return;
|
|
2774
|
-
}
|
|
2775
|
-
}
|
|
2776
|
-
const authenticated = hasCredentials();
|
|
2777
|
-
if (!authenticated) {
|
|
2778
|
-
output.warn("Not authenticated.");
|
|
2779
|
-
output.info("Run: mutagent auth login --browser");
|
|
2780
|
-
if (isNonInteractive) {
|
|
2781
|
-
throw new MutagentError("AUTH_REQUIRED", "Authentication required before init", "Run: mutagent auth login --browser");
|
|
2782
|
-
}
|
|
2783
|
-
const { doAuth } = await inquirer2.prompt([{
|
|
2784
|
-
type: "confirm",
|
|
2785
|
-
name: "doAuth",
|
|
2786
|
-
message: "Would you like to authenticate now?",
|
|
2787
|
-
default: true
|
|
2788
|
-
}]);
|
|
2789
|
-
if (doAuth) {
|
|
2790
|
-
output.info('Run "mutagent auth login --browser" and then re-run "mutagent init".');
|
|
2791
|
-
return;
|
|
2792
|
-
}
|
|
2793
|
-
}
|
|
2794
|
-
const detectedFramework = detectFrameworkFromPackageJson(cwd);
|
|
2795
|
-
let mode;
|
|
2796
|
-
let confirmedFramework = detectedFramework;
|
|
2797
|
-
if (isNonInteractive) {
|
|
2798
|
-
mode = "cli-only";
|
|
2799
|
-
if (isJson) {
|
|
2800
|
-
output.output({
|
|
2801
|
-
mode: "cli-only",
|
|
2802
|
-
nonInteractive: true,
|
|
2803
|
-
detectedFramework: detectedFramework?.name ?? null
|
|
2804
|
-
});
|
|
2805
|
-
}
|
|
2806
|
-
} else {
|
|
2807
|
-
if (detectedFramework) {
|
|
2808
|
-
output.info(`Detected framework: ${detectedFramework.displayName} (${detectedFramework.npmPackage})`);
|
|
2809
|
-
const { confirmFramework } = await inquirer2.prompt([{
|
|
2810
|
-
type: "confirm",
|
|
2811
|
-
name: "confirmFramework",
|
|
2812
|
-
message: `Use ${detectedFramework.displayName}?`,
|
|
2813
|
-
default: true
|
|
2814
|
-
}]);
|
|
2815
|
-
if (!confirmFramework) {
|
|
2816
|
-
const frameworkChoices = [
|
|
2817
|
-
{ name: "Mastra", value: "mastra" },
|
|
2818
|
-
{ name: "LangChain", value: "langchain" },
|
|
2819
|
-
{ name: "LangGraph", value: "langgraph" },
|
|
2820
|
-
{ name: "Vercel AI SDK", value: "vercel-ai" },
|
|
2821
|
-
{ name: "OpenAI SDK", value: "openai" },
|
|
2822
|
-
{ name: "Generic (OpenAI-compatible)", value: "generic" },
|
|
2823
|
-
{ name: "None / Skip framework", value: "none" }
|
|
2824
|
-
];
|
|
2825
|
-
const { selectedFramework } = await inquirer2.prompt([{
|
|
2826
|
-
type: "list",
|
|
2827
|
-
name: "selectedFramework",
|
|
2828
|
-
message: "Select your AI framework:",
|
|
2829
|
-
choices: frameworkChoices
|
|
2830
|
-
}]);
|
|
2831
|
-
if (selectedFramework === "none") {
|
|
2832
|
-
confirmedFramework = null;
|
|
2833
|
-
} else {
|
|
2834
|
-
const entry = Object.values(FRAMEWORK_DETECTION_MAP).find((f) => f.name === selectedFramework);
|
|
2835
|
-
confirmedFramework = entry ?? null;
|
|
2836
|
-
}
|
|
2837
|
-
}
|
|
2838
|
-
} else {
|
|
2839
|
-
output.info("No AI framework detected in package.json.");
|
|
2840
|
-
}
|
|
2841
|
-
const modeChoices = [
|
|
2842
|
-
{
|
|
2843
|
-
name: "CLI-only - Verify auth + create .mutagentrc.json config",
|
|
2844
|
-
value: "cli-only"
|
|
2845
|
-
},
|
|
2846
|
-
{
|
|
2847
|
-
name: "Skip - Exit without changes",
|
|
2848
|
-
value: "skip"
|
|
2849
|
-
}
|
|
2850
|
-
];
|
|
2851
|
-
const { selectedMode } = await inquirer2.prompt([{
|
|
2852
|
-
type: "list",
|
|
2853
|
-
name: "selectedMode",
|
|
2854
|
-
message: "How would you like to initialize MutagenT?",
|
|
2855
|
-
choices: modeChoices
|
|
2856
|
-
}]);
|
|
2857
|
-
mode = selectedMode;
|
|
2858
|
-
}
|
|
2859
|
-
if (mode === "skip") {
|
|
2860
|
-
output.info("Init skipped.");
|
|
2861
|
-
return;
|
|
2862
|
-
}
|
|
2863
|
-
const config = loadConfig();
|
|
2864
|
-
const endpoint = config.endpoint ?? "https://api.mutagent.io";
|
|
2865
|
-
let workspace = config.defaultWorkspace;
|
|
2866
|
-
let workspaceValidation;
|
|
2867
|
-
let resolvedOrgId;
|
|
2868
|
-
if (authenticated) {
|
|
2869
|
-
try {
|
|
2870
|
-
const apiKey = getApiKey();
|
|
2871
|
-
if (apiKey) {
|
|
2872
|
-
const { fetchOrganizations: fetchOrganizations2, fetchWorkspaces: fetchWorkspaces2 } = await Promise.resolve().then(() => (init_sdk_client(), exports_sdk_client));
|
|
2873
|
-
let orgId = config.defaultOrganization;
|
|
2874
|
-
if (!orgId) {
|
|
2875
|
-
const orgs = await fetchOrganizations2(apiKey, endpoint);
|
|
2876
|
-
orgId = orgs[0]?.id;
|
|
2877
|
-
}
|
|
2878
|
-
if (orgId) {
|
|
2879
|
-
resolvedOrgId = orgId;
|
|
2880
|
-
const workspaces = await fetchWorkspaces2(apiKey, endpoint, orgId);
|
|
2881
|
-
if (workspaces.length > 0) {
|
|
2882
|
-
const found = workspace ? workspaces.find((w) => w.id === workspace) : undefined;
|
|
2883
|
-
if (found) {
|
|
2884
|
-
workspaceValidation = { id: found.id, name: found.name, validated: true, corrected: false };
|
|
2885
|
-
} else if (workspaces[0]) {
|
|
2886
|
-
const first = workspaces[0];
|
|
2887
|
-
setDefaultWorkspace(first.id);
|
|
2888
|
-
workspace = first.id;
|
|
2889
|
-
workspaceValidation = { id: first.id, name: first.name, validated: true, corrected: true };
|
|
2890
|
-
}
|
|
2891
|
-
}
|
|
2892
|
-
}
|
|
2893
|
-
}
|
|
2894
|
-
} catch {}
|
|
2895
|
-
}
|
|
2896
|
-
const rcConfig = {
|
|
2897
|
-
endpoint,
|
|
2898
|
-
...workspace ? { defaultWorkspace: workspace } : {},
|
|
2899
|
-
...resolvedOrgId ? { defaultOrganization: resolvedOrgId } : {},
|
|
2900
|
-
...confirmedFramework ? { framework: confirmedFramework.name } : {}
|
|
2901
|
-
};
|
|
2902
|
-
writeRcConfig(rcConfig, cwd);
|
|
2903
|
-
output.success("Created .mutagentrc.json");
|
|
2904
|
-
if (!isJson && workspaceValidation) {
|
|
2905
|
-
if (workspaceValidation.corrected) {
|
|
2906
|
-
output.warn(`Workspace auto-corrected to: ${workspaceValidation.name} (${workspaceValidation.id})`);
|
|
2907
|
-
} else {
|
|
2908
|
-
output.info(`Workspace: ${workspaceValidation.name} (${workspaceValidation.id})`);
|
|
2909
|
-
}
|
|
2910
|
-
}
|
|
2911
|
-
if (!authenticated) {
|
|
2912
|
-
output.info("Next: mutagent auth login --browser");
|
|
2913
|
-
} else {
|
|
2914
|
-
output.info('Ready! Run "mutagent --help" to see available commands.');
|
|
2915
|
-
if (!isJson) {
|
|
2916
|
-
output.info("Verify workspace: mutagent workspaces list --json");
|
|
2917
|
-
}
|
|
2918
|
-
}
|
|
2919
|
-
const initDirective = {
|
|
2920
|
-
instruction: "Verify workspace. Run: mutagent workspaces list --json",
|
|
2921
|
-
next: ["mutagent workspaces list --json", "mutagent providers list --json"]
|
|
2922
|
-
};
|
|
2923
|
-
const summary = {
|
|
2924
|
-
success: true,
|
|
2925
|
-
mode,
|
|
2926
|
-
configFile: ".mutagentrc.json",
|
|
2927
|
-
config: rcConfig,
|
|
2928
|
-
framework: confirmedFramework?.name ?? null,
|
|
2929
|
-
authenticated,
|
|
2930
|
-
workspaceValidation: workspaceValidation ?? null,
|
|
2931
|
-
_directive: initDirective
|
|
2932
|
-
};
|
|
2933
|
-
output.output(summary);
|
|
2934
|
-
} catch (error) {
|
|
2935
|
-
handleError(error, isJson);
|
|
2936
|
-
}
|
|
2937
|
-
});
|
|
2938
|
-
return init;
|
|
2939
|
-
}
|
|
2940
2681
|
|
|
2941
2682
|
// src/commands/skills.ts
|
|
2942
|
-
import { Command as
|
|
2943
|
-
import
|
|
2683
|
+
import { Command as Command6 } from "commander";
|
|
2684
|
+
import chalk12 from "chalk";
|
|
2944
2685
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
2945
2686
|
import { dirname, join as join7 } from "path";
|
|
2946
2687
|
import { execSync } from "child_process";
|
|
@@ -2950,9 +2691,9 @@ var SKILL_FILES = {
|
|
|
2950
2691
|
"SKILL.md": `---
|
|
2951
2692
|
name: mutagent-cli
|
|
2952
2693
|
description: |
|
|
2953
|
-
|
|
2694
|
+
Mutagent CLI - the command-line client for the Mutagent platform.
|
|
2954
2695
|
Guides coding agents through setup (login, init, providers, workspaces),
|
|
2955
|
-
installing
|
|
2696
|
+
installing Mutagent packages (helix, diagnostics, evaluator), and sending
|
|
2956
2697
|
product feedback.
|
|
2957
2698
|
Triggers: "mutagent", "mutagent cli", "mutagent login", "set up mutagent",
|
|
2958
2699
|
"install diagnostics", "install evaluator", "install helix", "mutagent install",
|
|
@@ -2964,7 +2705,7 @@ metadata:
|
|
|
2964
2705
|
skill_min_cli_version: "0.1.163"
|
|
2965
2706
|
---
|
|
2966
2707
|
|
|
2967
|
-
#
|
|
2708
|
+
# Mutagent CLI Skill
|
|
2968
2709
|
|
|
2969
2710
|
> **Canonical source**: \`mutagent-cli/.claude/skills/mutagent-cli/SKILL.md\`
|
|
2970
2711
|
> Packed into the CLI binary via \`scripts/sync-skill.ts\`. Installed to end-user
|
|
@@ -2999,7 +2740,7 @@ If no lockfile and the user is in a non-JS project (e.g. Python, Go), ask which
|
|
|
2999
2740
|
|
|
3000
2741
|
**2b. Ask the user via AskUserQuestion** (do NOT auto-install without consent):
|
|
3001
2742
|
|
|
3002
|
-
> "The
|
|
2743
|
+
> "The Mutagent CLI is not installed yet. I can install it globally via \`<detected-pm>\`. Proceed?"
|
|
3003
2744
|
|
|
3004
2745
|
Options to present:
|
|
3005
2746
|
1. **Yes, install globally with \`<detected-pm>\`** (Recommended) -- runs \`<pm> add -g @mutagent/cli\` (or \`npm install -g @mutagent/cli\` for npm)
|
|
@@ -3036,7 +2777,7 @@ yarn global add @mutagent/cli
|
|
|
3036
2777
|
npm install -g @mutagent/cli
|
|
3037
2778
|
\`\`\`
|
|
3038
2779
|
|
|
3039
|
-
**Why proactive install (not just "stop and tell")**: a user invoking this Skill has already shown intent to use
|
|
2780
|
+
**Why proactive install (not just "stop and tell")**: a user invoking this Skill has already shown intent to use Mutagent. Forcing them to context-switch to a separate terminal, copy-paste an install command, and re-invoke the agent is friction that often loses the user. Asking once + installing on consent is the smoother path. The opt-out (option 3/4) preserves user control.
|
|
3040
2781
|
|
|
3041
2782
|
**Step 3 -- Version compatibility check:**
|
|
3042
2783
|
Parse \`_compat.cliVersion\` from the \`--version --json\` output and compare against
|
|
@@ -3118,7 +2859,7 @@ Match the user's first request. Load ONLY the matching subfile per the table. Do
|
|
|
3118
2859
|
| File | WHEN to load | WHY |
|
|
3119
2860
|
|---|---|---|
|
|
3120
2861
|
| [workflows/setup.md](./workflows/setup.md) | User is onboarding: login, init, config, workspaces, providers, usage, skill/hooks install | Auth + configuration + discovery |
|
|
3121
|
-
| [workflows/install.md](./workflows/install.md) | User wants to install a
|
|
2862
|
+
| [workflows/install.md](./workflows/install.md) | User wants to install a Mutagent package | \`install <helix\\|diagnostics\\|evaluator>\` meta-command |
|
|
3122
2863
|
| [workflows/feedback.md](./workflows/feedback.md) | User wants to send feedback or report a bug | \`feedback send\` + \`--attach-transcript\` |
|
|
3123
2864
|
|
|
3124
2865
|
---
|
|
@@ -3201,7 +2942,7 @@ triggers:
|
|
|
3201
2942
|
# Workflow — Feedback
|
|
3202
2943
|
|
|
3203
2944
|
> **Scope**: sends a feedback message (and optionally your session transcript)
|
|
3204
|
-
> to the
|
|
2945
|
+
> to the Mutagent platform. Login-gated.
|
|
3205
2946
|
|
|
3206
2947
|
Read the **Core Rules** in [SKILL.md](../SKILL.md) first. Key reminders:
|
|
3207
2948
|
- \`--json\` on every command
|
|
@@ -3308,7 +3049,7 @@ When a mutagent command fails, this is the canonical bug-report path:
|
|
|
3308
3049
|
"workflows/install.md": `---
|
|
3309
3050
|
name: mutagent-cli-workflows-install
|
|
3310
3051
|
description: |
|
|
3311
|
-
Meta-installer workflow. Installs a
|
|
3052
|
+
Meta-installer workflow. Installs a Mutagent package (helix, diagnostics, or
|
|
3312
3053
|
evaluator) into the user's environment via \`mutagent install <package>\`.
|
|
3313
3054
|
Login-gated. diagnostics/evaluator come from public npm; helix is fetched
|
|
3314
3055
|
from a private registry via a login-brokered signed URL (no static secret).
|
|
@@ -3324,7 +3065,7 @@ triggers:
|
|
|
3324
3065
|
|
|
3325
3066
|
# Workflow — Install (Meta-Installer)
|
|
3326
3067
|
|
|
3327
|
-
> **Scope**: installs a
|
|
3068
|
+
> **Scope**: installs a Mutagent package globally (or per the target harness).
|
|
3328
3069
|
> This WRITES to the user's machine — confirm before running (Core Rule 5).
|
|
3329
3070
|
|
|
3330
3071
|
Read the **Core Rules** in [SKILL.md](../SKILL.md) first. Key reminders:
|
|
@@ -3464,15 +3205,17 @@ mutagent auth logout --json # clear stored credentials
|
|
|
3464
3205
|
|
|
3465
3206
|
---
|
|
3466
3207
|
|
|
3467
|
-
## 2. init (
|
|
3208
|
+
## 2. init (config + skill install)
|
|
3468
3209
|
|
|
3469
3210
|
\`\`\`bash
|
|
3470
3211
|
mutagent init --help
|
|
3471
|
-
mutagent init --json #
|
|
3212
|
+
mutagent init --json # writes .mutagentrc.json + installs this skill
|
|
3472
3213
|
\`\`\`
|
|
3473
3214
|
|
|
3474
|
-
\`init\`
|
|
3475
|
-
|
|
3215
|
+
\`init\` writes \`.mutagentrc.json\` (endpoint / workspace / org — skipped if
|
|
3216
|
+
present) and installs the Mutagent CLI skill into \`.claude/skills/mutagent-cli/\`.
|
|
3217
|
+
It never prompts. If the user is not logged in, it prints login guidance and
|
|
3218
|
+
exits — run \`mutagent login\` first, then re-run \`mutagent init\`.
|
|
3476
3219
|
|
|
3477
3220
|
---
|
|
3478
3221
|
|
|
@@ -3584,74 +3327,198 @@ function getSkillFiles() {
|
|
|
3584
3327
|
assertSkillFilesValid();
|
|
3585
3328
|
return SKILL_FILES;
|
|
3586
3329
|
}
|
|
3330
|
+
function installCliSkill(targetRoot) {
|
|
3331
|
+
const files = getSkillFiles();
|
|
3332
|
+
const skillDir = join7(targetRoot, SKILL_DIR);
|
|
3333
|
+
const writtenFiles = [];
|
|
3334
|
+
let totalBytes = 0;
|
|
3335
|
+
const sortedKeys = Object.keys(files).sort((a, b) => {
|
|
3336
|
+
if (a === SKILL_ENTRY_FILE)
|
|
3337
|
+
return -1;
|
|
3338
|
+
if (b === SKILL_ENTRY_FILE)
|
|
3339
|
+
return 1;
|
|
3340
|
+
return a.localeCompare(b);
|
|
3341
|
+
});
|
|
3342
|
+
for (const relPath of sortedKeys) {
|
|
3343
|
+
const destPath = join7(skillDir, relPath);
|
|
3344
|
+
const parentDir = dirname(destPath);
|
|
3345
|
+
if (!existsSync6(parentDir)) {
|
|
3346
|
+
mkdirSync3(parentDir, { recursive: true });
|
|
3347
|
+
}
|
|
3348
|
+
const raw = files[relPath] ?? "";
|
|
3349
|
+
const finalContent = raw.endsWith(`
|
|
3350
|
+
`) ? raw : `${raw}
|
|
3351
|
+
`;
|
|
3352
|
+
writeFileSync4(destPath, finalContent, "utf-8");
|
|
3353
|
+
writtenFiles.push({ relPath, destPath, bytes: finalContent.length });
|
|
3354
|
+
totalBytes += finalContent.length;
|
|
3355
|
+
}
|
|
3356
|
+
return { skillDir, files: writtenFiles, totalBytes };
|
|
3357
|
+
}
|
|
3587
3358
|
function createSkillsCommand() {
|
|
3588
|
-
const skills = new
|
|
3589
|
-
skills.command("install").description("Install
|
|
3359
|
+
const skills = new Command6("skills").description("Manage Mutagent CLI skills for coding agents");
|
|
3360
|
+
skills.command("install").description("Install Mutagent CLI skill for Claude Code").addHelpText("after", `
|
|
3590
3361
|
Examples:
|
|
3591
|
-
${
|
|
3362
|
+
${chalk12.dim("$")} mutagent skills install
|
|
3592
3363
|
|
|
3593
3364
|
This creates a Claude Code skill at .claude/skills/mutagent-cli/SKILL.md
|
|
3594
|
-
that teaches coding agents how to use the
|
|
3365
|
+
that teaches coding agents how to use the Mutagent CLI effectively.
|
|
3595
3366
|
`).action((_options, cmd) => {
|
|
3596
3367
|
const parentCmd = cmd.parent?.parent;
|
|
3597
3368
|
const isJson = parentCmd ? getJsonFlag(parentCmd) : false;
|
|
3598
3369
|
const output = new OutputFormatter(isJson ? "json" : "table");
|
|
3599
3370
|
const repoRoot = findRepoRoot();
|
|
3600
|
-
const
|
|
3601
|
-
const files = getSkillFiles();
|
|
3602
|
-
const writtenFiles = [];
|
|
3603
|
-
let totalBytes = 0;
|
|
3604
|
-
const sortedKeys = Object.keys(files).sort((a, b) => {
|
|
3605
|
-
if (a === SKILL_ENTRY_FILE)
|
|
3606
|
-
return -1;
|
|
3607
|
-
if (b === SKILL_ENTRY_FILE)
|
|
3608
|
-
return 1;
|
|
3609
|
-
return a.localeCompare(b);
|
|
3610
|
-
});
|
|
3611
|
-
for (const relPath of sortedKeys) {
|
|
3612
|
-
const destPath = join7(skillDir, relPath);
|
|
3613
|
-
const parentDir = dirname(destPath);
|
|
3614
|
-
if (!existsSync6(parentDir)) {
|
|
3615
|
-
mkdirSync3(parentDir, { recursive: true });
|
|
3616
|
-
}
|
|
3617
|
-
const raw = files[relPath] ?? "";
|
|
3618
|
-
const finalContent = raw.endsWith(`
|
|
3619
|
-
`) ? raw : `${raw}
|
|
3620
|
-
`;
|
|
3621
|
-
writeFileSync4(destPath, finalContent, "utf-8");
|
|
3622
|
-
writtenFiles.push({ path: destPath, bytes: finalContent.length });
|
|
3623
|
-
totalBytes += finalContent.length;
|
|
3624
|
-
}
|
|
3371
|
+
const result = installCliSkill(repoRoot);
|
|
3625
3372
|
if (isJson) {
|
|
3626
3373
|
output.output({
|
|
3627
3374
|
installed: true,
|
|
3628
3375
|
name: "mutagent-cli",
|
|
3629
|
-
skillDir,
|
|
3630
|
-
files:
|
|
3631
|
-
totalBytes
|
|
3376
|
+
skillDir: result.skillDir,
|
|
3377
|
+
files: result.files.map((f) => ({ path: f.destPath, bytes: f.bytes })),
|
|
3378
|
+
totalBytes: result.totalBytes
|
|
3632
3379
|
});
|
|
3633
3380
|
} else {
|
|
3634
|
-
output.success(`Installed
|
|
3635
|
-
console.log(` ${
|
|
3381
|
+
output.success(`Installed Mutagent CLI skill`);
|
|
3382
|
+
console.log(` ${chalk12.dim("Dir:")} ${result.skillDir}`);
|
|
3636
3383
|
console.log("");
|
|
3637
|
-
for (let i = 0;i <
|
|
3638
|
-
const entry =
|
|
3384
|
+
for (let i = 0;i < result.files.length; i++) {
|
|
3385
|
+
const entry = result.files[i];
|
|
3639
3386
|
if (!entry)
|
|
3640
3387
|
continue;
|
|
3641
|
-
const
|
|
3642
|
-
const isLast = i === writtenFiles.length - 1;
|
|
3388
|
+
const isLast = i === result.files.length - 1;
|
|
3643
3389
|
const prefix = isLast ? "└─" : "├─";
|
|
3644
|
-
console.log(` ${
|
|
3390
|
+
console.log(` ${chalk12.dim(prefix)} ${entry.relPath} ${chalk12.dim(`(${String(entry.bytes)} bytes)`)}`);
|
|
3645
3391
|
}
|
|
3646
3392
|
console.log("");
|
|
3647
|
-
console.log(` ${
|
|
3648
|
-
console.log(` ${
|
|
3649
|
-
console.log(` ${
|
|
3393
|
+
console.log(` ${chalk12.dim(`${String(result.files.length)} file(s), ${String(result.totalBytes)} bytes total.`)}`);
|
|
3394
|
+
console.log(` ${chalk12.dim("This skill teaches coding agents how to use the Mutagent CLI.")}`);
|
|
3395
|
+
console.log(` ${chalk12.dim("It will be automatically loaded by Claude Code when relevant triggers match.")}`);
|
|
3650
3396
|
}
|
|
3651
3397
|
});
|
|
3652
3398
|
return skills;
|
|
3653
3399
|
}
|
|
3654
3400
|
|
|
3401
|
+
// src/commands/init.ts
|
|
3402
|
+
var LOGIN_GUIDANCE = "Run: mutagent login — sign-up happens in the browser. Then re-run mutagent init.";
|
|
3403
|
+
function createInitCommand(deps = {}) {
|
|
3404
|
+
const init = new Command7("init").description("Initialize Mutagent in your project").option("--non-interactive", "No-op kept for back-compat (init never prompts)").addHelpText("after", `
|
|
3405
|
+
Examples:
|
|
3406
|
+
${chalk13.dim("$")} mutagent init # Write .mutagentrc.json + install the CLI skill
|
|
3407
|
+
|
|
3408
|
+
What it does:
|
|
3409
|
+
1. Writes .mutagentrc.json (endpoint / workspace / org) — skipped if present
|
|
3410
|
+
2. Installs the Mutagent CLI skill into ${SKILL_DIR}/
|
|
3411
|
+
`).action(async (options) => {
|
|
3412
|
+
const isJson = getJsonFlag(init);
|
|
3413
|
+
const output = new OutputFormatter(isJson ? "json" : "table");
|
|
3414
|
+
try {
|
|
3415
|
+
const cwd = process.cwd();
|
|
3416
|
+
const rcExists = hasRcConfig(cwd);
|
|
3417
|
+
if (rcExists && !isJson) {
|
|
3418
|
+
output.info(".mutagentrc.json already exists — already initialized. Leaving it untouched.");
|
|
3419
|
+
}
|
|
3420
|
+
if (!(deps.hasCredentials ?? hasCredentials)()) {
|
|
3421
|
+
if (isJson) {
|
|
3422
|
+
output.output({
|
|
3423
|
+
success: false,
|
|
3424
|
+
authenticated: false,
|
|
3425
|
+
message: `Not authenticated. ${LOGIN_GUIDANCE}`,
|
|
3426
|
+
nextSteps: ["mutagent login", "mutagent init"]
|
|
3427
|
+
});
|
|
3428
|
+
} else {
|
|
3429
|
+
output.warn("Not authenticated.");
|
|
3430
|
+
output.info(LOGIN_GUIDANCE);
|
|
3431
|
+
}
|
|
3432
|
+
return;
|
|
3433
|
+
}
|
|
3434
|
+
let rcConfig;
|
|
3435
|
+
if (rcExists) {
|
|
3436
|
+
try {
|
|
3437
|
+
rcConfig = JSON.parse(readFileSync5(join8(cwd, ".mutagentrc.json"), "utf-8"));
|
|
3438
|
+
} catch {
|
|
3439
|
+
rcConfig = {};
|
|
3440
|
+
}
|
|
3441
|
+
} else {
|
|
3442
|
+
const config = (deps.loadConfig ?? loadConfig)();
|
|
3443
|
+
const endpoint = config.endpoint ?? "https://api.mutagent.io";
|
|
3444
|
+
let workspace = config.defaultWorkspace;
|
|
3445
|
+
let workspaceValidation;
|
|
3446
|
+
let resolvedOrgId;
|
|
3447
|
+
try {
|
|
3448
|
+
const apiKey = (deps.getApiKey ?? getApiKey)();
|
|
3449
|
+
if (apiKey) {
|
|
3450
|
+
const sdk = await Promise.resolve().then(() => (init_sdk_client(), exports_sdk_client));
|
|
3451
|
+
const fetchOrgs = deps.fetchOrganizations ?? sdk.fetchOrganizations;
|
|
3452
|
+
const fetchWs = deps.fetchWorkspaces ?? sdk.fetchWorkspaces;
|
|
3453
|
+
let orgId = config.defaultOrganization;
|
|
3454
|
+
if (!orgId) {
|
|
3455
|
+
const orgs = await fetchOrgs(apiKey, endpoint);
|
|
3456
|
+
orgId = orgs[0]?.id;
|
|
3457
|
+
}
|
|
3458
|
+
if (orgId) {
|
|
3459
|
+
resolvedOrgId = orgId;
|
|
3460
|
+
const workspaces = await fetchWs(apiKey, endpoint, orgId);
|
|
3461
|
+
if (workspaces.length > 0) {
|
|
3462
|
+
const found = workspace ? workspaces.find((w) => w.id === workspace) : undefined;
|
|
3463
|
+
if (found) {
|
|
3464
|
+
workspaceValidation = { id: found.id, name: found.name, validated: true, corrected: false };
|
|
3465
|
+
} else if (workspaces[0]) {
|
|
3466
|
+
const first = workspaces[0];
|
|
3467
|
+
(deps.setDefaultWorkspace ?? setDefaultWorkspace)(first.id);
|
|
3468
|
+
workspace = first.id;
|
|
3469
|
+
workspaceValidation = { id: first.id, name: first.name, validated: true, corrected: true };
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
} catch {}
|
|
3475
|
+
rcConfig = {
|
|
3476
|
+
endpoint,
|
|
3477
|
+
...workspace ? { defaultWorkspace: workspace } : {},
|
|
3478
|
+
...resolvedOrgId ? { defaultOrganization: resolvedOrgId } : {}
|
|
3479
|
+
};
|
|
3480
|
+
writeRcConfig(rcConfig, cwd);
|
|
3481
|
+
if (!isJson) {
|
|
3482
|
+
output.success("Created .mutagentrc.json");
|
|
3483
|
+
if (workspaceValidation) {
|
|
3484
|
+
if (workspaceValidation.corrected) {
|
|
3485
|
+
output.warn(`Workspace auto-corrected to: ${workspaceValidation.name} (${workspaceValidation.id})`);
|
|
3486
|
+
} else {
|
|
3487
|
+
output.info(`Workspace: ${workspaceValidation.name} (${workspaceValidation.id})`);
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
(deps.installSkill ?? installCliSkill)(cwd);
|
|
3493
|
+
if (!isJson) {
|
|
3494
|
+
output.success(`Installed the Mutagent CLI skill → ${SKILL_DIR}/`);
|
|
3495
|
+
}
|
|
3496
|
+
if (isJson) {
|
|
3497
|
+
output.output({
|
|
3498
|
+
success: true,
|
|
3499
|
+
configFile: ".mutagentrc.json",
|
|
3500
|
+
config: rcConfig,
|
|
3501
|
+
skillInstalled: true,
|
|
3502
|
+
skillPath: `${SKILL_DIR}/`,
|
|
3503
|
+
nextSteps: ["mutagent install helix"]
|
|
3504
|
+
});
|
|
3505
|
+
} else {
|
|
3506
|
+
console.log("");
|
|
3507
|
+
console.log(chalk13.bold(` What's next:`));
|
|
3508
|
+
console.log(` ${chalk13.cyan("mutagent install helix".padEnd(30))}${chalk13.dim("# the ADL lifecycle conductor")}`);
|
|
3509
|
+
console.log(` ${chalk13.cyan("mutagent install diagnostics".padEnd(30))}${chalk13.dim("# trace diagnosis (optional)")}`);
|
|
3510
|
+
console.log(` ${chalk13.cyan("mutagent install evaluator".padEnd(30))}${chalk13.dim("# eval mining + judging (optional)")}`);
|
|
3511
|
+
console.log("");
|
|
3512
|
+
console.log(chalk13.dim(" Your coding agent now knows these workflows — restart it to pick up"));
|
|
3513
|
+
console.log(chalk13.dim(' the skill, then just say "set up Mutagent on this project".'));
|
|
3514
|
+
}
|
|
3515
|
+
} catch (error) {
|
|
3516
|
+
handleError(error, isJson);
|
|
3517
|
+
}
|
|
3518
|
+
});
|
|
3519
|
+
return init;
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3655
3522
|
// src/commands/usage.ts
|
|
3656
3523
|
init_config();
|
|
3657
3524
|
import { Command as Command8 } from "commander";
|
|
@@ -3697,7 +3564,7 @@ Examples:
|
|
|
3697
3564
|
});
|
|
3698
3565
|
} else {
|
|
3699
3566
|
console.log("");
|
|
3700
|
-
console.log(chalk14.bold("\uD83D\uDCCA
|
|
3567
|
+
console.log(chalk14.bold("\uD83D\uDCCA Mutagent Usage"));
|
|
3701
3568
|
console.log(chalk14.dim("─".repeat(45)));
|
|
3702
3569
|
console.log("");
|
|
3703
3570
|
console.log(chalk14.bold("Resources:"));
|
|
@@ -3721,18 +3588,18 @@ import { Command as Command9 } from "commander";
|
|
|
3721
3588
|
import { randomUUID } from "crypto";
|
|
3722
3589
|
|
|
3723
3590
|
// src/commands/hooks/state.ts
|
|
3724
|
-
import { readFileSync as
|
|
3725
|
-
import { join as
|
|
3591
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, renameSync as renameSync2, unlinkSync, existsSync as existsSync7 } from "fs";
|
|
3592
|
+
import { join as join9 } from "path";
|
|
3726
3593
|
import { tmpdir } from "os";
|
|
3727
3594
|
function stateFilePath(sessionId) {
|
|
3728
|
-
return
|
|
3595
|
+
return join9(tmpdir(), `mutagent-hook-${sessionId}.json`);
|
|
3729
3596
|
}
|
|
3730
3597
|
function readState(sessionId) {
|
|
3731
3598
|
const path = stateFilePath(sessionId);
|
|
3732
3599
|
if (!existsSync7(path))
|
|
3733
3600
|
return null;
|
|
3734
3601
|
try {
|
|
3735
|
-
const raw = JSON.parse(
|
|
3602
|
+
const raw = JSON.parse(readFileSync6(path, "utf-8"));
|
|
3736
3603
|
if (!Array.isArray(raw.parentStack)) {
|
|
3737
3604
|
raw.parentStack = [];
|
|
3738
3605
|
}
|
|
@@ -4399,8 +4266,8 @@ async function handlePostToolUseFailure() {
|
|
|
4399
4266
|
}
|
|
4400
4267
|
|
|
4401
4268
|
// src/commands/hooks/install.ts
|
|
4402
|
-
import { readFileSync as
|
|
4403
|
-
import { join as
|
|
4269
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
4270
|
+
import { join as join10 } from "path";
|
|
4404
4271
|
|
|
4405
4272
|
class SettingsParseError extends Error {
|
|
4406
4273
|
settingsPath;
|
|
@@ -4462,12 +4329,12 @@ function migrateV1Hooks(settings) {
|
|
|
4462
4329
|
return migrated;
|
|
4463
4330
|
}
|
|
4464
4331
|
function installHooks(cwd) {
|
|
4465
|
-
const claudeDir =
|
|
4466
|
-
const settingsPath =
|
|
4332
|
+
const claudeDir = join10(cwd, ".claude");
|
|
4333
|
+
const settingsPath = join10(claudeDir, "settings.local.json");
|
|
4467
4334
|
const existed = existsSync8(settingsPath);
|
|
4468
4335
|
let settings = {};
|
|
4469
4336
|
if (existed) {
|
|
4470
|
-
const raw =
|
|
4337
|
+
const raw = readFileSync7(settingsPath, "utf-8");
|
|
4471
4338
|
try {
|
|
4472
4339
|
settings = JSON.parse(raw);
|
|
4473
4340
|
} catch (err) {
|
|
@@ -4513,7 +4380,7 @@ function installHooks(cwd) {
|
|
|
4513
4380
|
const parts = cmd.split(" ");
|
|
4514
4381
|
return parts[parts.length - 1] ?? cmd;
|
|
4515
4382
|
}).join(", ");
|
|
4516
|
-
userWarning = `
|
|
4383
|
+
userWarning = `Mutagent hooks installed into .claude/settings.local.json
|
|
4517
4384
|
` + ` Added: ${addedList}
|
|
4518
4385
|
` + ` This file was modified. Review with: git diff .claude/settings.local.json
|
|
4519
4386
|
` + ` (To remove hooks, edit .claude/settings.local.json and delete the mutagent entries)`;
|
|
@@ -4525,7 +4392,7 @@ function installHooks(cwd) {
|
|
|
4525
4392
|
function createHooksCommand() {
|
|
4526
4393
|
const hooks = new Command9("hooks").description("Hook handlers for AI coding assistants").addHelpText("after", `
|
|
4527
4394
|
Claude Code Session Telemetry:
|
|
4528
|
-
Sends lightweight session activity to the
|
|
4395
|
+
Sends lightweight session activity to the Mutagent traces API for observability.
|
|
4529
4396
|
|
|
4530
4397
|
Install by adding to .claude/settings.local.json:
|
|
4531
4398
|
|
|
@@ -4546,9 +4413,9 @@ Claude Code Session Telemetry:
|
|
|
4546
4413
|
|
|
4547
4414
|
Or run: mutagent hooks install
|
|
4548
4415
|
`);
|
|
4549
|
-
hooks.command("install").description("Install
|
|
4416
|
+
hooks.command("install").description("Install Mutagent hooks into .claude/settings.local.json (safe merge — never overwrites existing hooks)").option("--cwd <dir>", "Target directory (defaults to cwd)", process.cwd()).addHelpText("after", `
|
|
4550
4417
|
Reads existing .claude/settings.local.json (if present) and deep-merges
|
|
4551
|
-
|
|
4418
|
+
Mutagent telemetry hooks into each event array (all 10 events). Skips any
|
|
4552
4419
|
hook already present (checked by command string) so running this multiple
|
|
4553
4420
|
times is safe.
|
|
4554
4421
|
`).action((opts) => {
|
|
@@ -4651,8 +4518,8 @@ times is safe.
|
|
|
4651
4518
|
import { Command as Command10 } from "commander";
|
|
4652
4519
|
import chalk16 from "chalk";
|
|
4653
4520
|
import { type as osType, release as osRelease } from "os";
|
|
4654
|
-
import { readFileSync as
|
|
4655
|
-
import { join as
|
|
4521
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
4522
|
+
import { join as join12, dirname as dirname2 } from "path";
|
|
4656
4523
|
import { fileURLToPath } from "url";
|
|
4657
4524
|
init_errors();
|
|
4658
4525
|
init_config();
|
|
@@ -4660,11 +4527,11 @@ init_config();
|
|
|
4660
4527
|
// src/lib/transcript.ts
|
|
4661
4528
|
init_errors();
|
|
4662
4529
|
import { homedir as osHomedir } from "os";
|
|
4663
|
-
import { join as
|
|
4530
|
+
import { join as join11 } from "path";
|
|
4664
4531
|
import {
|
|
4665
4532
|
existsSync as fsExistsSync,
|
|
4666
4533
|
statSync as fsStatSync,
|
|
4667
|
-
readFileSync as
|
|
4534
|
+
readFileSync as readFileSync8,
|
|
4668
4535
|
readdirSync,
|
|
4669
4536
|
openSync,
|
|
4670
4537
|
readSync,
|
|
@@ -4675,7 +4542,7 @@ var TAIL_BYTES = 200000;
|
|
|
4675
4542
|
function defaultReadTail(path, tailBytes) {
|
|
4676
4543
|
const { size } = fsStatSync(path);
|
|
4677
4544
|
if (size <= tailBytes) {
|
|
4678
|
-
return { content:
|
|
4545
|
+
return { content: readFileSync8(path, "utf-8"), truncated: false };
|
|
4679
4546
|
}
|
|
4680
4547
|
const fd = openSync(path, "r");
|
|
4681
4548
|
try {
|
|
@@ -4698,7 +4565,7 @@ function defaultScan(dir) {
|
|
|
4698
4565
|
return;
|
|
4699
4566
|
}
|
|
4700
4567
|
for (const entry of entries) {
|
|
4701
|
-
const full =
|
|
4568
|
+
const full = join11(current, entry.name);
|
|
4702
4569
|
if (entry.isDirectory())
|
|
4703
4570
|
walk(full);
|
|
4704
4571
|
else if (entry.isFile() && entry.name.endsWith(".jsonl"))
|
|
@@ -4709,11 +4576,11 @@ function defaultScan(dir) {
|
|
|
4709
4576
|
return out;
|
|
4710
4577
|
}
|
|
4711
4578
|
function buildSources(env, home) {
|
|
4712
|
-
const ompBase = env.PI_CODING_AGENT_DIR ??
|
|
4579
|
+
const ompBase = env.PI_CODING_AGENT_DIR ?? join11(home, ".omp", "agent");
|
|
4713
4580
|
return [
|
|
4714
|
-
{ harness: "claude-code", dir:
|
|
4715
|
-
{ harness: "codex", dir:
|
|
4716
|
-
{ harness: "omp", dir:
|
|
4581
|
+
{ harness: "claude-code", dir: join11(home, ".claude", "projects") },
|
|
4582
|
+
{ harness: "codex", dir: join11(home, ".codex", "sessions") },
|
|
4583
|
+
{ harness: "omp", dir: join11(ompBase, "sessions") }
|
|
4717
4584
|
];
|
|
4718
4585
|
}
|
|
4719
4586
|
function resolveTranscript(attach, deps = {}) {
|
|
@@ -4767,8 +4634,8 @@ function getCliVersion() {
|
|
|
4767
4634
|
return process.env.CLI_VERSION;
|
|
4768
4635
|
try {
|
|
4769
4636
|
const __dirname2 = dirname2(fileURLToPath(import.meta.url));
|
|
4770
|
-
const pkgPath =
|
|
4771
|
-
const pkg = JSON.parse(
|
|
4637
|
+
const pkgPath = join12(__dirname2, "..", "..", "package.json");
|
|
4638
|
+
const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
|
|
4772
4639
|
return pkg.version ?? "0.1.1";
|
|
4773
4640
|
} catch {
|
|
4774
4641
|
return "0.1.1";
|
|
@@ -4843,7 +4710,7 @@ function buildPayload(feedback, category, title, session, transcript) {
|
|
|
4843
4710
|
return payload;
|
|
4844
4711
|
}
|
|
4845
4712
|
function createFeedbackCommand() {
|
|
4846
|
-
const feedback = new Command10("feedback").description("Send product feedback to
|
|
4713
|
+
const feedback = new Command10("feedback").description("Send product feedback to Mutagent").addHelpText("after", `
|
|
4847
4714
|
${chalk16.bold("Examples:")}
|
|
4848
4715
|
${chalk16.cyan('mutagent feedback send "Optimizer results were great"')}
|
|
4849
4716
|
${chalk16.cyan('mutagent feedback send "Eval gate was confusing" --category stage:evaluate')}
|
|
@@ -4859,7 +4726,7 @@ ${chalk16.yellow("AI Agent (MANDATORY):")}
|
|
|
4859
4726
|
return feedback;
|
|
4860
4727
|
}
|
|
4861
4728
|
function registerFeedbackSend(feedback) {
|
|
4862
|
-
feedback.command("send").description("Send product feedback about the
|
|
4729
|
+
feedback.command("send").description("Send product feedback about the Mutagent platform or CLI").argument("<feedback>", "The feedback body (content), max 10000 characters").option("--title <string>", "Optional 5–8 word summary of the session timeline").option("--category <value>", `Feedback category: 'cli', 'helix', or 'stage:<${VALID_STAGES.join("|")}>'`, "cli").option("--session <id>", "Link this feedback to a session id (maps to server sessionId)").option("--attach-transcript [path]", "Attach the coding-agent session JSONL. Bare = auto-detect newest; or pass an explicit path.").addHelpText("after", `
|
|
4863
4730
|
${chalk16.bold("Arguments & flags:")}
|
|
4864
4731
|
${chalk16.bold("<feedback>")} Feedback body / content (required, ≤10000 chars)
|
|
4865
4732
|
${chalk16.bold("--title <string>")} Optional 5–8 word summary of the session timeline
|
|
@@ -4934,7 +4801,7 @@ import { Command as Command11 } from "commander";
|
|
|
4934
4801
|
import chalk17 from "chalk";
|
|
4935
4802
|
init_errors();
|
|
4936
4803
|
function createInstallCommand(deps) {
|
|
4937
|
-
const install = new Command11("install").description("Install a
|
|
4804
|
+
const install = new Command11("install").description("Install a Mutagent package (helix, diagnostics, evaluator)").argument("<package>", `Package to install: ${VALID_PACKAGES.join(", ")}`).option("--harness <harness>", `Target harness: ${VALID_HARNESSES.join(", ")}`, "claude-code").option("--global", "Install to ~/.claude instead of this project", false).option("--version <version>", "Package version to install (default: latest)").addHelpText("after", `
|
|
4938
4805
|
${chalk17.bold("Arguments & flags:")}
|
|
4939
4806
|
${chalk17.bold("<package>")} ${VALID_PACKAGES.join(" | ")}
|
|
4940
4807
|
${chalk17.bold("--harness <h>")} ${VALID_HARNESSES.join(" | ")} ${chalk17.dim("(default: claude-code)")}
|
|
@@ -5061,17 +4928,17 @@ if (process.env.CLI_VERSION) {
|
|
|
5061
4928
|
} else {
|
|
5062
4929
|
try {
|
|
5063
4930
|
const __dirname2 = dirname3(fileURLToPath2(import.meta.url));
|
|
5064
|
-
const pkgPath =
|
|
5065
|
-
const pkg = JSON.parse(
|
|
4931
|
+
const pkgPath = join13(__dirname2, "..", "..", "package.json");
|
|
4932
|
+
const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
5066
4933
|
cliVersion = pkg.version ?? cliVersion;
|
|
5067
4934
|
} catch {}
|
|
5068
4935
|
}
|
|
5069
4936
|
setCliVersion(cliVersion);
|
|
5070
4937
|
var program = new Command12;
|
|
5071
|
-
program.name("mutagent").description(`
|
|
4938
|
+
program.name("mutagent").description(`Mutagent CLI - command-line client for the Mutagent platform
|
|
5072
4939
|
|
|
5073
4940
|
Documentation: https://docs.mutagent.io/cli
|
|
5074
|
-
Dashboard: https://app.mutagent.io`).option("-v, --version", "Display the version number").option("--json", "Output results as JSON (for AI agents)").option("--api-key <key>", "
|
|
4941
|
+
Dashboard: https://app.mutagent.io`).option("-v, --version", "Display the version number").option("--json", "Output results as JSON (for AI agents)").option("--api-key <key>", "Mutagent API key").option("--endpoint <url>", "Mutagent server endpoint").option("--non-interactive", "Disable interactive prompts (for CI/AI agents)").configureHelp({
|
|
5075
4942
|
sortSubcommands: true,
|
|
5076
4943
|
showGlobalOptions: true
|
|
5077
4944
|
});
|
|
@@ -5177,5 +5044,5 @@ program.addCommand(createInstallCommand());
|
|
|
5177
5044
|
program.addCommand(createFeedbackCommand());
|
|
5178
5045
|
program.parse();
|
|
5179
5046
|
|
|
5180
|
-
//# debugId=
|
|
5047
|
+
//# debugId=EC56D6215B8176D364756E2164756E21
|
|
5181
5048
|
//# sourceMappingURL=cli.js.map
|