agentinit 1.13.4 → 1.15.0
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/CHANGELOG.md +22 -1
- package/README.md +60 -7
- package/dist/agents/Agent.d.ts +5 -1
- package/dist/agents/Agent.d.ts.map +1 -1
- package/dist/agents/Agent.js +6 -0
- package/dist/agents/Agent.js.map +1 -1
- package/dist/agents/HermesAgent.d.ts +14 -0
- package/dist/agents/HermesAgent.d.ts.map +1 -0
- package/dist/agents/HermesAgent.js +64 -0
- package/dist/agents/HermesAgent.js.map +1 -0
- package/dist/agents/OpenClawAgent.d.ts +14 -0
- package/dist/agents/OpenClawAgent.d.ts.map +1 -0
- package/dist/agents/OpenClawAgent.js +64 -0
- package/dist/agents/OpenClawAgent.js.map +1 -0
- package/dist/cli.js +1023 -330
- package/dist/cli.js.map +1 -1
- package/dist/commands/apply.js +2 -2
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/config.d.ts +2 -7
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +208 -3
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/detect.js +1 -1
- package/dist/commands/detect.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +119 -44
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/revert.js +1 -1
- package/dist/commands/revert.js.map +1 -1
- package/dist/commands/rules.js +3 -3
- package/dist/commands/rules.js.map +1 -1
- package/dist/commands/skills.js +4 -4
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/subagents.js +1 -1
- package/dist/commands/subagents.js.map +1 -1
- package/dist/commands/sync.js +1 -1
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/verifyMcp.js +1 -1
- package/dist/commands/verifyMcp.js.map +1 -1
- package/dist/core/agentDetector.d.ts +8 -2
- package/dist/core/agentDetector.d.ts.map +1 -1
- package/dist/core/agentDetector.js +32 -4
- package/dist/core/agentDetector.js.map +1 -1
- package/dist/core/agentManager.d.ts +10 -5
- package/dist/core/agentManager.d.ts.map +1 -1
- package/dist/core/agentManager.js +25 -9
- package/dist/core/agentManager.js.map +1 -1
- package/dist/core/marketplaceRegistry.d.ts +1 -0
- package/dist/core/marketplaceRegistry.d.ts.map +1 -1
- package/dist/core/marketplaceRegistry.js +27 -2
- package/dist/core/marketplaceRegistry.js.map +1 -1
- package/dist/core/mcpClient.js +3 -3
- package/dist/core/mcpClient.js.map +1 -1
- package/dist/core/pluginManager.d.ts +1 -0
- package/dist/core/pluginManager.d.ts.map +1 -1
- package/dist/core/pluginManager.js +14 -6
- package/dist/core/pluginManager.js.map +1 -1
- package/dist/core/skillsManager.d.ts.map +1 -1
- package/dist/core/skillsManager.js +12 -1
- package/dist/core/skillsManager.js.map +1 -1
- package/dist/core/userConfig.d.ts +25 -0
- package/dist/core/userConfig.d.ts.map +1 -0
- package/dist/core/userConfig.js +156 -0
- package/dist/core/userConfig.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/colors.d.ts +10 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +27 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +59 -5
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/symbols.d.ts +27 -0
- package/dist/utils/symbols.d.ts.map +1 -0
- package/dist/utils/symbols.js +27 -0
- package/dist/utils/symbols.js.map +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -8510,6 +8510,74 @@ async function createRelativeSymlink(target, linkPath) {
|
|
|
8510
8510
|
var init_fs = __esm(() => {
|
|
8511
8511
|
});
|
|
8512
8512
|
|
|
8513
|
+
// dist/utils/paths.js
|
|
8514
|
+
import {resolve as resolve2, join as join2} from "path";
|
|
8515
|
+
import {homedir} from "os";
|
|
8516
|
+
function getHomeDirectory() {
|
|
8517
|
+
return homedir();
|
|
8518
|
+
}
|
|
8519
|
+
function getPlatform() {
|
|
8520
|
+
switch (process.platform) {
|
|
8521
|
+
case "win32":
|
|
8522
|
+
return "windows";
|
|
8523
|
+
case "darwin":
|
|
8524
|
+
return "darwin";
|
|
8525
|
+
case "linux":
|
|
8526
|
+
return "linux";
|
|
8527
|
+
default:
|
|
8528
|
+
return "linux";
|
|
8529
|
+
}
|
|
8530
|
+
}
|
|
8531
|
+
function expandTilde(path) {
|
|
8532
|
+
if (path.startsWith("~/")) {
|
|
8533
|
+
return join2(getHomeDirectory(), path.slice(2));
|
|
8534
|
+
}
|
|
8535
|
+
if (path === "~") {
|
|
8536
|
+
return getHomeDirectory();
|
|
8537
|
+
}
|
|
8538
|
+
return path;
|
|
8539
|
+
}
|
|
8540
|
+
function getEnvironmentPath(key) {
|
|
8541
|
+
return process.env[key];
|
|
8542
|
+
}
|
|
8543
|
+
function resolveGlobalConfigPath(globalConfigPath, globalConfigPaths) {
|
|
8544
|
+
if (globalConfigPath) {
|
|
8545
|
+
return expandTilde(globalConfigPath);
|
|
8546
|
+
}
|
|
8547
|
+
if (globalConfigPaths) {
|
|
8548
|
+
const platform2 = getPlatform();
|
|
8549
|
+
const platformPath = globalConfigPaths[platform2];
|
|
8550
|
+
if (platformPath) {
|
|
8551
|
+
return expandTilde(platformPath);
|
|
8552
|
+
}
|
|
8553
|
+
}
|
|
8554
|
+
return null;
|
|
8555
|
+
}
|
|
8556
|
+
function getWindowsAppDataPaths() {
|
|
8557
|
+
return {
|
|
8558
|
+
roaming: getEnvironmentPath("APPDATA"),
|
|
8559
|
+
local: getEnvironmentPath("LOCALAPPDATA"),
|
|
8560
|
+
userProfile: getEnvironmentPath("USERPROFILE")
|
|
8561
|
+
};
|
|
8562
|
+
}
|
|
8563
|
+
function resolveEnvironmentVariables(path) {
|
|
8564
|
+
if (getPlatform() === "windows") {
|
|
8565
|
+
const appDataPaths = getWindowsAppDataPaths();
|
|
8566
|
+
return path.replace(/%APPDATA%/g, appDataPaths.roaming || "").replace(/%LOCALAPPDATA%/g, appDataPaths.local || "").replace(/%USERPROFILE%/g, appDataPaths.userProfile || "");
|
|
8567
|
+
}
|
|
8568
|
+
return path;
|
|
8569
|
+
}
|
|
8570
|
+
function getFullGlobalConfigPath(globalConfigPath, globalConfigPaths) {
|
|
8571
|
+
const path = resolveGlobalConfigPath(globalConfigPath, globalConfigPaths);
|
|
8572
|
+
if (!path) {
|
|
8573
|
+
return null;
|
|
8574
|
+
}
|
|
8575
|
+
const resolvedPath = resolveEnvironmentVariables(path);
|
|
8576
|
+
return resolve2(resolvedPath);
|
|
8577
|
+
}
|
|
8578
|
+
var init_paths = __esm(() => {
|
|
8579
|
+
});
|
|
8580
|
+
|
|
8513
8581
|
// node_modules/kind-of/index.js
|
|
8514
8582
|
var require_kind_of = __commonJS((exports, module) => {
|
|
8515
8583
|
var ctorName = function(val) {
|
|
@@ -11935,74 +12003,6 @@ var require_gray_matter = __commonJS((exports, module) => {
|
|
|
11935
12003
|
module.exports = matter;
|
|
11936
12004
|
});
|
|
11937
12005
|
|
|
11938
|
-
// dist/utils/paths.js
|
|
11939
|
-
import {resolve as resolve5, join as join2} from "path";
|
|
11940
|
-
import {homedir} from "os";
|
|
11941
|
-
function getHomeDirectory() {
|
|
11942
|
-
return homedir();
|
|
11943
|
-
}
|
|
11944
|
-
function getPlatform() {
|
|
11945
|
-
switch (process.platform) {
|
|
11946
|
-
case "win32":
|
|
11947
|
-
return "windows";
|
|
11948
|
-
case "darwin":
|
|
11949
|
-
return "darwin";
|
|
11950
|
-
case "linux":
|
|
11951
|
-
return "linux";
|
|
11952
|
-
default:
|
|
11953
|
-
return "linux";
|
|
11954
|
-
}
|
|
11955
|
-
}
|
|
11956
|
-
function expandTilde(path) {
|
|
11957
|
-
if (path.startsWith("~/")) {
|
|
11958
|
-
return join2(getHomeDirectory(), path.slice(2));
|
|
11959
|
-
}
|
|
11960
|
-
if (path === "~") {
|
|
11961
|
-
return getHomeDirectory();
|
|
11962
|
-
}
|
|
11963
|
-
return path;
|
|
11964
|
-
}
|
|
11965
|
-
function getEnvironmentPath(key) {
|
|
11966
|
-
return process.env[key];
|
|
11967
|
-
}
|
|
11968
|
-
function resolveGlobalConfigPath(globalConfigPath, globalConfigPaths) {
|
|
11969
|
-
if (globalConfigPath) {
|
|
11970
|
-
return expandTilde(globalConfigPath);
|
|
11971
|
-
}
|
|
11972
|
-
if (globalConfigPaths) {
|
|
11973
|
-
const platform2 = getPlatform();
|
|
11974
|
-
const platformPath = globalConfigPaths[platform2];
|
|
11975
|
-
if (platformPath) {
|
|
11976
|
-
return expandTilde(platformPath);
|
|
11977
|
-
}
|
|
11978
|
-
}
|
|
11979
|
-
return null;
|
|
11980
|
-
}
|
|
11981
|
-
function getWindowsAppDataPaths() {
|
|
11982
|
-
return {
|
|
11983
|
-
roaming: getEnvironmentPath("APPDATA"),
|
|
11984
|
-
local: getEnvironmentPath("LOCALAPPDATA"),
|
|
11985
|
-
userProfile: getEnvironmentPath("USERPROFILE")
|
|
11986
|
-
};
|
|
11987
|
-
}
|
|
11988
|
-
function resolveEnvironmentVariables(path) {
|
|
11989
|
-
if (getPlatform() === "windows") {
|
|
11990
|
-
const appDataPaths = getWindowsAppDataPaths();
|
|
11991
|
-
return path.replace(/%APPDATA%/g, appDataPaths.roaming || "").replace(/%LOCALAPPDATA%/g, appDataPaths.local || "").replace(/%USERPROFILE%/g, appDataPaths.userProfile || "");
|
|
11992
|
-
}
|
|
11993
|
-
return path;
|
|
11994
|
-
}
|
|
11995
|
-
function getFullGlobalConfigPath(globalConfigPath, globalConfigPaths) {
|
|
11996
|
-
const path = resolveGlobalConfigPath(globalConfigPath, globalConfigPaths);
|
|
11997
|
-
if (!path) {
|
|
11998
|
-
return null;
|
|
11999
|
-
}
|
|
12000
|
-
const resolvedPath = resolveEnvironmentVariables(path);
|
|
12001
|
-
return resolve5(resolvedPath);
|
|
12002
|
-
}
|
|
12003
|
-
var init_paths = __esm(() => {
|
|
12004
|
-
});
|
|
12005
|
-
|
|
12006
12006
|
// node_modules/contextcalc/dist/lib/index.js
|
|
12007
12007
|
import {get_encoding} from "tiktoken";
|
|
12008
12008
|
async function isBinaryFile(filePath) {
|
|
@@ -12389,6 +12389,9 @@ class Agent {
|
|
|
12389
12389
|
get name() {
|
|
12390
12390
|
return this.definition.name;
|
|
12391
12391
|
}
|
|
12392
|
+
getDetectionScope() {
|
|
12393
|
+
return this.definition.detectionScope || "project";
|
|
12394
|
+
}
|
|
12392
12395
|
get capabilities() {
|
|
12393
12396
|
return this.definition.capabilities;
|
|
12394
12397
|
}
|
|
@@ -15899,6 +15902,140 @@ var init_CopilotAgent = __esm(() => {
|
|
|
15899
15902
|
init_fs();
|
|
15900
15903
|
});
|
|
15901
15904
|
|
|
15905
|
+
// dist/agents/OpenClawAgent.js
|
|
15906
|
+
class OpenClawAgent extends Agent {
|
|
15907
|
+
constructor() {
|
|
15908
|
+
const definition = {
|
|
15909
|
+
id: "openclaw",
|
|
15910
|
+
name: "OpenClaw",
|
|
15911
|
+
capabilities: {
|
|
15912
|
+
mcp: {
|
|
15913
|
+
stdio: false,
|
|
15914
|
+
http: false,
|
|
15915
|
+
sse: false
|
|
15916
|
+
},
|
|
15917
|
+
rules: false,
|
|
15918
|
+
hooks: false,
|
|
15919
|
+
commands: false,
|
|
15920
|
+
subagents: false,
|
|
15921
|
+
statusline: false,
|
|
15922
|
+
skills: true
|
|
15923
|
+
},
|
|
15924
|
+
configFiles: [],
|
|
15925
|
+
nativeConfigPath: ".openclaw/config.json",
|
|
15926
|
+
detectionScope: "environment",
|
|
15927
|
+
skillPaths: {
|
|
15928
|
+
project: ".agents/skills/",
|
|
15929
|
+
global: "~/.openclaw/skills/"
|
|
15930
|
+
},
|
|
15931
|
+
projectStandards: {
|
|
15932
|
+
skills: "agents"
|
|
15933
|
+
}
|
|
15934
|
+
};
|
|
15935
|
+
super(definition);
|
|
15936
|
+
}
|
|
15937
|
+
async detectPresence(_projectPath) {
|
|
15938
|
+
const openClawHome = expandTilde("~/.openclaw");
|
|
15939
|
+
if (!await fileExists(openClawHome)) {
|
|
15940
|
+
return null;
|
|
15941
|
+
}
|
|
15942
|
+
return {
|
|
15943
|
+
agent: this,
|
|
15944
|
+
configPath: openClawHome
|
|
15945
|
+
};
|
|
15946
|
+
}
|
|
15947
|
+
async applyMCPConfig(_projectPath, _servers) {
|
|
15948
|
+
throw new Error("OpenClaw does not support MCP configuration.");
|
|
15949
|
+
}
|
|
15950
|
+
async removeMCPServer(_projectPath, _serverName) {
|
|
15951
|
+
throw new Error("OpenClaw does not support MCP configuration.");
|
|
15952
|
+
}
|
|
15953
|
+
async applyRulesConfig(_configPath, _rules, _existingContent) {
|
|
15954
|
+
throw new Error("OpenClaw does not support rules configuration.");
|
|
15955
|
+
}
|
|
15956
|
+
extractExistingRules(_content) {
|
|
15957
|
+
return [];
|
|
15958
|
+
}
|
|
15959
|
+
extractExistingSections(_content) {
|
|
15960
|
+
return [];
|
|
15961
|
+
}
|
|
15962
|
+
generateRulesContent(_sections) {
|
|
15963
|
+
return "";
|
|
15964
|
+
}
|
|
15965
|
+
}
|
|
15966
|
+
var init_OpenClawAgent = __esm(() => {
|
|
15967
|
+
init_Agent();
|
|
15968
|
+
init_fs();
|
|
15969
|
+
init_paths();
|
|
15970
|
+
});
|
|
15971
|
+
|
|
15972
|
+
// dist/agents/HermesAgent.js
|
|
15973
|
+
class HermesAgent extends Agent {
|
|
15974
|
+
constructor() {
|
|
15975
|
+
const definition = {
|
|
15976
|
+
id: "hermes",
|
|
15977
|
+
name: "Hermes",
|
|
15978
|
+
capabilities: {
|
|
15979
|
+
mcp: {
|
|
15980
|
+
stdio: false,
|
|
15981
|
+
http: false,
|
|
15982
|
+
sse: false
|
|
15983
|
+
},
|
|
15984
|
+
rules: false,
|
|
15985
|
+
hooks: false,
|
|
15986
|
+
commands: false,
|
|
15987
|
+
subagents: false,
|
|
15988
|
+
statusline: false,
|
|
15989
|
+
skills: true
|
|
15990
|
+
},
|
|
15991
|
+
configFiles: [],
|
|
15992
|
+
nativeConfigPath: ".hermes/config.json",
|
|
15993
|
+
detectionScope: "environment",
|
|
15994
|
+
skillPaths: {
|
|
15995
|
+
project: ".agents/skills/",
|
|
15996
|
+
global: "~/.hermes/skills/"
|
|
15997
|
+
},
|
|
15998
|
+
projectStandards: {
|
|
15999
|
+
skills: "agents"
|
|
16000
|
+
}
|
|
16001
|
+
};
|
|
16002
|
+
super(definition);
|
|
16003
|
+
}
|
|
16004
|
+
async detectPresence(_projectPath) {
|
|
16005
|
+
const hermesHome = expandTilde("~/.hermes");
|
|
16006
|
+
if (!await fileExists(hermesHome)) {
|
|
16007
|
+
return null;
|
|
16008
|
+
}
|
|
16009
|
+
return {
|
|
16010
|
+
agent: this,
|
|
16011
|
+
configPath: hermesHome
|
|
16012
|
+
};
|
|
16013
|
+
}
|
|
16014
|
+
async applyMCPConfig(_projectPath, _servers) {
|
|
16015
|
+
throw new Error("Hermes does not support MCP configuration.");
|
|
16016
|
+
}
|
|
16017
|
+
async removeMCPServer(_projectPath, _serverName) {
|
|
16018
|
+
throw new Error("Hermes does not support MCP configuration.");
|
|
16019
|
+
}
|
|
16020
|
+
async applyRulesConfig(_configPath, _rules, _existingContent) {
|
|
16021
|
+
throw new Error("Hermes does not support rules configuration.");
|
|
16022
|
+
}
|
|
16023
|
+
extractExistingRules(_content) {
|
|
16024
|
+
return [];
|
|
16025
|
+
}
|
|
16026
|
+
extractExistingSections(_content) {
|
|
16027
|
+
return [];
|
|
16028
|
+
}
|
|
16029
|
+
generateRulesContent(_sections) {
|
|
16030
|
+
return "";
|
|
16031
|
+
}
|
|
16032
|
+
}
|
|
16033
|
+
var init_HermesAgent = __esm(() => {
|
|
16034
|
+
init_Agent();
|
|
16035
|
+
init_fs();
|
|
16036
|
+
init_paths();
|
|
16037
|
+
});
|
|
16038
|
+
|
|
15902
16039
|
// dist/agents/AiderAgent.js
|
|
15903
16040
|
class AiderAgent extends MarkdownRulesAgent {
|
|
15904
16041
|
constructor() {
|
|
@@ -16493,7 +16630,9 @@ class AgentManager {
|
|
|
16493
16630
|
new WindsurfAgent,
|
|
16494
16631
|
new RooCodeAgent,
|
|
16495
16632
|
new ZedAgent,
|
|
16496
|
-
new DroidAgent
|
|
16633
|
+
new DroidAgent,
|
|
16634
|
+
new OpenClawAgent,
|
|
16635
|
+
new HermesAgent
|
|
16497
16636
|
];
|
|
16498
16637
|
}
|
|
16499
16638
|
getAllAgents() {
|
|
@@ -16505,9 +16644,18 @@ class AgentManager {
|
|
|
16505
16644
|
getSupportedAgentIds() {
|
|
16506
16645
|
return this.agents.map((agent) => agent.id);
|
|
16507
16646
|
}
|
|
16508
|
-
|
|
16647
|
+
shouldIncludeForDetection(agent, options2) {
|
|
16648
|
+
if (options2.includeEnvironment) {
|
|
16649
|
+
return true;
|
|
16650
|
+
}
|
|
16651
|
+
return agent.getDetectionScope() !== "environment";
|
|
16652
|
+
}
|
|
16653
|
+
async detectAgents(projectPath, options2 = {}) {
|
|
16509
16654
|
const results = [];
|
|
16510
16655
|
for (const agent of this.agents) {
|
|
16656
|
+
if (!this.shouldIncludeForDetection(agent, options2)) {
|
|
16657
|
+
continue;
|
|
16658
|
+
}
|
|
16511
16659
|
const detection = await agent.detectPresence(projectPath);
|
|
16512
16660
|
if (detection) {
|
|
16513
16661
|
results.push(detection);
|
|
@@ -16515,27 +16663,30 @@ class AgentManager {
|
|
|
16515
16663
|
}
|
|
16516
16664
|
return results;
|
|
16517
16665
|
}
|
|
16518
|
-
async detectAgentById(projectPath, agentId) {
|
|
16666
|
+
async detectAgentById(projectPath, agentId, options2 = {}) {
|
|
16519
16667
|
const agent = this.getAgentById(agentId);
|
|
16520
16668
|
if (!agent) {
|
|
16521
16669
|
return null;
|
|
16522
16670
|
}
|
|
16671
|
+
if (!this.shouldIncludeForDetection(agent, options2)) {
|
|
16672
|
+
return null;
|
|
16673
|
+
}
|
|
16523
16674
|
return await agent.detectPresence(projectPath);
|
|
16524
16675
|
}
|
|
16525
|
-
async getPrimaryAgent(projectPath) {
|
|
16526
|
-
const detectedAgents = await this.detectAgents(projectPath);
|
|
16676
|
+
async getPrimaryAgent(projectPath, options2 = {}) {
|
|
16677
|
+
const detectedAgents = await this.detectAgents(projectPath, options2);
|
|
16527
16678
|
return detectedAgents.length > 0 ? detectedAgents[0] : null;
|
|
16528
16679
|
}
|
|
16529
16680
|
registerAgent(agent) {
|
|
16530
16681
|
this.agents = this.agents.filter((existing) => existing.id !== agent.id);
|
|
16531
16682
|
this.agents.push(agent);
|
|
16532
16683
|
}
|
|
16533
|
-
async hasAnyAgents(projectPath) {
|
|
16534
|
-
const detected = await this.detectAgents(projectPath);
|
|
16684
|
+
async hasAnyAgents(projectPath, options2 = {}) {
|
|
16685
|
+
const detected = await this.detectAgents(projectPath, options2);
|
|
16535
16686
|
return detected.length > 0;
|
|
16536
16687
|
}
|
|
16537
|
-
async getDetectionSummary(projectPath) {
|
|
16538
|
-
const detected = await this.detectAgents(projectPath);
|
|
16688
|
+
async getDetectionSummary(projectPath, options2 = {}) {
|
|
16689
|
+
const detected = await this.detectAgents(projectPath, options2);
|
|
16539
16690
|
if (detected.length === 0) {
|
|
16540
16691
|
return "No AI coding agents detected in this project.";
|
|
16541
16692
|
}
|
|
@@ -16557,6 +16708,8 @@ var init_agentManager = __esm(() => {
|
|
|
16557
16708
|
init_CursorAgent();
|
|
16558
16709
|
init_DroidAgent();
|
|
16559
16710
|
init_CopilotAgent();
|
|
16711
|
+
init_OpenClawAgent();
|
|
16712
|
+
init_HermesAgent();
|
|
16560
16713
|
init_AiderAgent();
|
|
16561
16714
|
init_ClineAgent();
|
|
16562
16715
|
init_WindsurfAgent();
|
|
@@ -16564,15 +16717,191 @@ var init_agentManager = __esm(() => {
|
|
|
16564
16717
|
init_ZedAgent();
|
|
16565
16718
|
});
|
|
16566
16719
|
|
|
16720
|
+
// dist/core/userConfig.js
|
|
16721
|
+
import {existsSync, readFileSync} from "fs";
|
|
16722
|
+
import {promises as fs20} from "fs";
|
|
16723
|
+
import {homedir as homedir3} from "os";
|
|
16724
|
+
import {join as join3} from "path";
|
|
16725
|
+
function getUserConfigPath() {
|
|
16726
|
+
return join3(homedir3(), ".agentinit", "config.json");
|
|
16727
|
+
}
|
|
16728
|
+
function createDefaultUserConfig() {
|
|
16729
|
+
return {
|
|
16730
|
+
customMarketplaces: [],
|
|
16731
|
+
verifiedGithubRepos: []
|
|
16732
|
+
};
|
|
16733
|
+
}
|
|
16734
|
+
function normalizeMarketplaceIdentifier(identifier) {
|
|
16735
|
+
const normalized = identifier.trim().toLowerCase();
|
|
16736
|
+
if (!MARKETPLACE_IDENTIFIER_PATTERN.test(normalized)) {
|
|
16737
|
+
throw new Error('Invalid marketplace identifier. Use lowercase letters, numbers, ".", "_" or "-".');
|
|
16738
|
+
}
|
|
16739
|
+
return normalized;
|
|
16740
|
+
}
|
|
16741
|
+
function normalizeMarketplaceName(name, identifier) {
|
|
16742
|
+
const normalized = name?.trim();
|
|
16743
|
+
return normalized ? normalized : identifier;
|
|
16744
|
+
}
|
|
16745
|
+
function normalizeMarketplaceRepoUrl(repoUrl) {
|
|
16746
|
+
const normalized = repoUrl.trim().replace(/\/+$/, "");
|
|
16747
|
+
if (!normalized || !GIT_REPO_URL_PATTERN.test(normalized)) {
|
|
16748
|
+
throw new Error("Invalid marketplace repo URL. Use https://..., ssh://..., or git@...");
|
|
16749
|
+
}
|
|
16750
|
+
return normalized;
|
|
16751
|
+
}
|
|
16752
|
+
function normalizeGitHubRepoRef(repo) {
|
|
16753
|
+
const normalized = repo.trim();
|
|
16754
|
+
const match = normalized.match(GITHUB_REPO_PATTERN);
|
|
16755
|
+
if (!match) {
|
|
16756
|
+
throw new Error("Invalid GitHub repo. Use exact owner/repo.");
|
|
16757
|
+
}
|
|
16758
|
+
return `${match[1].toLowerCase()}/${match[2].toLowerCase()}`;
|
|
16759
|
+
}
|
|
16760
|
+
function sanitizeUserConfig(raw) {
|
|
16761
|
+
const defaults = createDefaultUserConfig();
|
|
16762
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
16763
|
+
return defaults;
|
|
16764
|
+
}
|
|
16765
|
+
const parsed = raw;
|
|
16766
|
+
const seenMarketplaces = new Set;
|
|
16767
|
+
const customMarketplaces = [];
|
|
16768
|
+
if (Array.isArray(parsed.customMarketplaces)) {
|
|
16769
|
+
for (const entry of parsed.customMarketplaces) {
|
|
16770
|
+
const sanitized = sanitizeCustomMarketplaceConfig(entry);
|
|
16771
|
+
if (!sanitized || seenMarketplaces.has(sanitized.identifier)) {
|
|
16772
|
+
continue;
|
|
16773
|
+
}
|
|
16774
|
+
seenMarketplaces.add(sanitized.identifier);
|
|
16775
|
+
customMarketplaces.push(sanitized);
|
|
16776
|
+
}
|
|
16777
|
+
}
|
|
16778
|
+
const seenRepos = new Set;
|
|
16779
|
+
const verifiedGithubRepos = [];
|
|
16780
|
+
if (Array.isArray(parsed.verifiedGithubRepos)) {
|
|
16781
|
+
for (const entry of parsed.verifiedGithubRepos) {
|
|
16782
|
+
if (typeof entry !== "string") {
|
|
16783
|
+
continue;
|
|
16784
|
+
}
|
|
16785
|
+
try {
|
|
16786
|
+
const normalized = normalizeGitHubRepoRef(entry);
|
|
16787
|
+
if (seenRepos.has(normalized)) {
|
|
16788
|
+
continue;
|
|
16789
|
+
}
|
|
16790
|
+
seenRepos.add(normalized);
|
|
16791
|
+
verifiedGithubRepos.push(normalized);
|
|
16792
|
+
} catch {
|
|
16793
|
+
continue;
|
|
16794
|
+
}
|
|
16795
|
+
}
|
|
16796
|
+
}
|
|
16797
|
+
let defaultMarketplace;
|
|
16798
|
+
if (typeof parsed.defaultMarketplace === "string") {
|
|
16799
|
+
try {
|
|
16800
|
+
defaultMarketplace = normalizeMarketplaceIdentifier(parsed.defaultMarketplace);
|
|
16801
|
+
} catch {
|
|
16802
|
+
defaultMarketplace = undefined;
|
|
16803
|
+
}
|
|
16804
|
+
}
|
|
16805
|
+
return {
|
|
16806
|
+
...defaultMarketplace ? { defaultMarketplace } : {},
|
|
16807
|
+
customMarketplaces,
|
|
16808
|
+
verifiedGithubRepos
|
|
16809
|
+
};
|
|
16810
|
+
}
|
|
16811
|
+
function readUserConfigSync() {
|
|
16812
|
+
const configPath = getUserConfigPath();
|
|
16813
|
+
if (!existsSync(configPath)) {
|
|
16814
|
+
return createDefaultUserConfig();
|
|
16815
|
+
}
|
|
16816
|
+
try {
|
|
16817
|
+
const content = readFileSync(configPath, "utf8");
|
|
16818
|
+
return sanitizeUserConfig(JSON.parse(content));
|
|
16819
|
+
} catch {
|
|
16820
|
+
return createDefaultUserConfig();
|
|
16821
|
+
}
|
|
16822
|
+
}
|
|
16823
|
+
async function readUserConfig() {
|
|
16824
|
+
const configPath = getUserConfigPath();
|
|
16825
|
+
try {
|
|
16826
|
+
const content = await fs20.readFile(configPath, "utf8");
|
|
16827
|
+
return sanitizeUserConfig(JSON.parse(content));
|
|
16828
|
+
} catch {
|
|
16829
|
+
return createDefaultUserConfig();
|
|
16830
|
+
}
|
|
16831
|
+
}
|
|
16832
|
+
async function writeUserConfig(config) {
|
|
16833
|
+
const sanitized = sanitizeUserConfig(config);
|
|
16834
|
+
await writeFile(getUserConfigPath(), `${JSON.stringify(sanitized, null, 2)}\n`);
|
|
16835
|
+
}
|
|
16836
|
+
function getBuiltInVerifiedGithubRepos() {
|
|
16837
|
+
return [...BUILTIN_VERIFIED_GITHUB_REPOS];
|
|
16838
|
+
}
|
|
16839
|
+
function getEffectiveVerifiedGithubReposSync() {
|
|
16840
|
+
const repos = new Set(BUILTIN_VERIFIED_GITHUB_REPOS);
|
|
16841
|
+
for (const repo of readUserConfigSync().verifiedGithubRepos) {
|
|
16842
|
+
repos.add(repo);
|
|
16843
|
+
}
|
|
16844
|
+
return [...repos];
|
|
16845
|
+
}
|
|
16846
|
+
function isVerifiedGitHubRepoSync(owner, repo) {
|
|
16847
|
+
const normalized = normalizeGitHubRepoRef(`${owner}/${repo}`);
|
|
16848
|
+
return getEffectiveVerifiedGithubReposSync().includes(normalized);
|
|
16849
|
+
}
|
|
16850
|
+
var sanitizeCustomMarketplaceConfig, MARKETPLACE_IDENTIFIER_PATTERN, GITHUB_REPO_PATTERN, GIT_REPO_URL_PATTERN, BUILTIN_VERIFIED_GITHUB_REPOS;
|
|
16851
|
+
var init_userConfig = __esm(() => {
|
|
16852
|
+
init_fs();
|
|
16853
|
+
sanitizeCustomMarketplaceConfig = function(entry) {
|
|
16854
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
16855
|
+
return null;
|
|
16856
|
+
}
|
|
16857
|
+
const candidate = entry;
|
|
16858
|
+
try {
|
|
16859
|
+
const identifier = normalizeMarketplaceIdentifier(String(candidate.identifier || ""));
|
|
16860
|
+
return {
|
|
16861
|
+
identifier,
|
|
16862
|
+
name: normalizeMarketplaceName(typeof candidate.name === "string" ? candidate.name : undefined, identifier),
|
|
16863
|
+
repoUrl: normalizeMarketplaceRepoUrl(String(candidate.repoUrl || ""))
|
|
16864
|
+
};
|
|
16865
|
+
} catch {
|
|
16866
|
+
return null;
|
|
16867
|
+
}
|
|
16868
|
+
};
|
|
16869
|
+
MARKETPLACE_IDENTIFIER_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
|
|
16870
|
+
GITHUB_REPO_PATTERN = /^([A-Za-z0-9._-]+)\/([A-Za-z0-9._-]+)$/;
|
|
16871
|
+
GIT_REPO_URL_PATTERN = /^(https?:\/\/|ssh:\/\/|git@).+/;
|
|
16872
|
+
BUILTIN_VERIFIED_GITHUB_REPOS = ["openai/codex-plugin-cc"];
|
|
16873
|
+
});
|
|
16874
|
+
|
|
16567
16875
|
// dist/core/marketplaceRegistry.js
|
|
16568
16876
|
function getMarketplace(id) {
|
|
16569
|
-
return
|
|
16877
|
+
return getAllMarketplaces().find((marketplace) => marketplace.id === id);
|
|
16570
16878
|
}
|
|
16571
16879
|
function getMarketplaceIds() {
|
|
16572
|
-
return
|
|
16880
|
+
return getAllMarketplaces().map((marketplace) => marketplace.id);
|
|
16573
16881
|
}
|
|
16574
|
-
|
|
16882
|
+
function getConfiguredDefaultMarketplaceId() {
|
|
16883
|
+
const defaultMarketplace = readUserConfigSync().defaultMarketplace;
|
|
16884
|
+
if (!defaultMarketplace) {
|
|
16885
|
+
return;
|
|
16886
|
+
}
|
|
16887
|
+
return getMarketplace(defaultMarketplace)?.id;
|
|
16888
|
+
}
|
|
16889
|
+
var getCustomMarketplaces, getAllMarketplaces, MARKETPLACES, CUSTOM_MARKETPLACE_PLUGIN_DIRS, CUSTOM_MARKETPLACE_CACHE_TTL_MS;
|
|
16575
16890
|
var init_marketplaceRegistry = __esm(() => {
|
|
16891
|
+
init_userConfig();
|
|
16892
|
+
getCustomMarketplaces = function() {
|
|
16893
|
+
const builtInIds = new Set(MARKETPLACES.map((marketplace) => marketplace.id));
|
|
16894
|
+
return readUserConfigSync().customMarketplaces.filter((marketplace) => !builtInIds.has(marketplace.identifier)).map((marketplace) => ({
|
|
16895
|
+
id: marketplace.identifier,
|
|
16896
|
+
name: marketplace.name,
|
|
16897
|
+
repoUrl: marketplace.repoUrl,
|
|
16898
|
+
pluginDirs: [...CUSTOM_MARKETPLACE_PLUGIN_DIRS],
|
|
16899
|
+
cacheTtlMs: CUSTOM_MARKETPLACE_CACHE_TTL_MS
|
|
16900
|
+
}));
|
|
16901
|
+
};
|
|
16902
|
+
getAllMarketplaces = function() {
|
|
16903
|
+
return [...MARKETPLACES, ...getCustomMarketplaces()];
|
|
16904
|
+
};
|
|
16576
16905
|
MARKETPLACES = [
|
|
16577
16906
|
{
|
|
16578
16907
|
id: "agentinit",
|
|
@@ -16596,6 +16925,8 @@ var init_marketplaceRegistry = __esm(() => {
|
|
|
16596
16925
|
cacheTtlMs: 3600000
|
|
16597
16926
|
}
|
|
16598
16927
|
];
|
|
16928
|
+
CUSTOM_MARKETPLACE_PLUGIN_DIRS = ["skills", "mcps", "rules"];
|
|
16929
|
+
CUSTOM_MARKETPLACE_CACHE_TTL_MS = 3600000;
|
|
16599
16930
|
});
|
|
16600
16931
|
|
|
16601
16932
|
// dist/core/mcpFilter.js
|
|
@@ -16707,9 +17038,9 @@ __export(exports_pluginManager, {
|
|
|
16707
17038
|
}
|
|
16708
17039
|
}
|
|
16709
17040
|
});
|
|
16710
|
-
import {resolve as resolve7, join as
|
|
16711
|
-
import {promises as
|
|
16712
|
-
import {homedir as
|
|
17041
|
+
import {resolve as resolve7, join as join4, basename as basename2, relative as relative2, dirname as dirname2} from "path";
|
|
17042
|
+
import {promises as fs22} from "fs";
|
|
17043
|
+
import {homedir as homedir4} from "os";
|
|
16713
17044
|
|
|
16714
17045
|
class MarketplacePluginNotFoundError extends Error {
|
|
16715
17046
|
pluginName;
|
|
@@ -16743,7 +17074,7 @@ class PluginManager {
|
|
|
16743
17074
|
}
|
|
16744
17075
|
async cleanupLoadedPluginContext(context) {
|
|
16745
17076
|
if (context?.tempDir) {
|
|
16746
|
-
await
|
|
17077
|
+
await fs22.rm(context.tempDir, { recursive: true, force: true }).catch(() => {
|
|
16747
17078
|
});
|
|
16748
17079
|
}
|
|
16749
17080
|
}
|
|
@@ -16814,8 +17145,14 @@ class PluginManager {
|
|
|
16814
17145
|
}
|
|
16815
17146
|
return `https://github.com/${source.owner}/${source.repo}`;
|
|
16816
17147
|
}
|
|
17148
|
+
getGitHubFallbackTrust(source) {
|
|
17149
|
+
if (source.owner && source.repo && isVerifiedGitHubRepoSync(source.owner, source.repo)) {
|
|
17150
|
+
return "verified";
|
|
17151
|
+
}
|
|
17152
|
+
return "unverified";
|
|
17153
|
+
}
|
|
16817
17154
|
async resolvePreparedPluginDir(pluginDir, source) {
|
|
16818
|
-
const claudeMarketplaceManifestPath =
|
|
17155
|
+
const claudeMarketplaceManifestPath = join4(pluginDir, ".claude-plugin", "marketplace.json");
|
|
16819
17156
|
if (!await fileExists(claudeMarketplaceManifestPath)) {
|
|
16820
17157
|
return { pluginDir, warnings: [] };
|
|
16821
17158
|
}
|
|
@@ -16894,12 +17231,13 @@ class PluginManager {
|
|
|
16894
17231
|
throw error;
|
|
16895
17232
|
}
|
|
16896
17233
|
const fallbackUrl = this.formatGitHubRepoUrl(fallbackSource) || fallbackSource.url.replace(/\.git$/, "");
|
|
17234
|
+
const fallbackTrust = this.getGitHubFallbackTrust(fallbackSource);
|
|
16897
17235
|
resolutionWarnings.push(error.message);
|
|
16898
|
-
resolutionWarnings.push(`Marketplace lookup failed; trying
|
|
17236
|
+
resolutionWarnings.push(`Marketplace lookup failed; trying ${fallbackTrust} GitHub repository ${fallbackUrl} instead.`);
|
|
16899
17237
|
try {
|
|
16900
17238
|
tempDir = await this.skillsManager.cloneRepo(fallbackSource.url);
|
|
16901
17239
|
} catch (fallbackError) {
|
|
16902
|
-
throw new Error(`${error.message} Tried
|
|
17240
|
+
throw new Error(`${error.message} Tried ${fallbackTrust} GitHub repository ${fallbackUrl} but failed: ${fallbackError instanceof Error ? fallbackError.message : "Unknown error"}`);
|
|
16903
17241
|
}
|
|
16904
17242
|
effectiveSource = {
|
|
16905
17243
|
...fallbackSource,
|
|
@@ -16955,13 +17293,13 @@ class PluginManager {
|
|
|
16955
17293
|
}
|
|
16956
17294
|
async getClaudeNativeFeatureKinds(pluginDir, manifest) {
|
|
16957
17295
|
const featureChecks = await Promise.all([
|
|
16958
|
-
(async () => !!manifest.commands || await isDirectory(
|
|
16959
|
-
(async () => !!manifest.hooks || await isDirectory(
|
|
16960
|
-
(async () => !!manifest.agents || await isDirectory(
|
|
16961
|
-
isDirectory(
|
|
16962
|
-
isDirectory(
|
|
16963
|
-
isDirectory(
|
|
16964
|
-
isDirectory(
|
|
17296
|
+
(async () => !!manifest.commands || await isDirectory(join4(pluginDir, "commands")))(),
|
|
17297
|
+
(async () => !!manifest.hooks || await isDirectory(join4(pluginDir, "hooks")))(),
|
|
17298
|
+
(async () => !!manifest.agents || await isDirectory(join4(pluginDir, "agents")))(),
|
|
17299
|
+
isDirectory(join4(pluginDir, "prompts")),
|
|
17300
|
+
isDirectory(join4(pluginDir, "schemas")),
|
|
17301
|
+
isDirectory(join4(pluginDir, "scripts")),
|
|
17302
|
+
isDirectory(join4(pluginDir, "templates"))
|
|
16965
17303
|
]);
|
|
16966
17304
|
return [
|
|
16967
17305
|
...featureChecks[0] ? ["commands"] : [],
|
|
@@ -16977,7 +17315,7 @@ class PluginManager {
|
|
|
16977
17315
|
if (plugin.format !== "claude") {
|
|
16978
17316
|
return null;
|
|
16979
17317
|
}
|
|
16980
|
-
const manifestContent = await readFileIfExists(
|
|
17318
|
+
const manifestContent = await readFileIfExists(join4(pluginDir, ".claude-plugin", "plugin.json"));
|
|
16981
17319
|
if (!manifestContent) {
|
|
16982
17320
|
return null;
|
|
16983
17321
|
}
|
|
@@ -16997,7 +17335,7 @@ class PluginManager {
|
|
|
16997
17335
|
return {
|
|
16998
17336
|
namespace,
|
|
16999
17337
|
pluginKey: `${plugin.name}@${namespace}`,
|
|
17000
|
-
installPath:
|
|
17338
|
+
installPath: join4(homedir4(), ".claude", "plugins", "cache", namespace, plugin.name, versionDir),
|
|
17001
17339
|
features
|
|
17002
17340
|
};
|
|
17003
17341
|
}
|
|
@@ -17070,10 +17408,10 @@ class PluginManager {
|
|
|
17070
17408
|
warnings.push(`Skipped native Claude plugin install because Claude already has "${plugin.name}" installed as ${conflictingKey}.`);
|
|
17071
17409
|
return { installed, skipped, warnings };
|
|
17072
17410
|
}
|
|
17073
|
-
await
|
|
17411
|
+
await fs22.rm(nativeTarget.installPath, { recursive: true, force: true }).catch(() => {
|
|
17074
17412
|
});
|
|
17075
|
-
await
|
|
17076
|
-
await
|
|
17413
|
+
await fs22.mkdir(dirname2(nativeTarget.installPath), { recursive: true });
|
|
17414
|
+
await fs22.cp(pluginDir, nativeTarget.installPath, { recursive: true, dereference: true });
|
|
17077
17415
|
const now = new Date().toISOString();
|
|
17078
17416
|
claudeInstalled.plugins[nativeTarget.pluginKey] = [{
|
|
17079
17417
|
scope: "user",
|
|
@@ -17121,7 +17459,7 @@ class PluginManager {
|
|
|
17121
17459
|
claudeSettings.enabledPlugins = remainingEnabledPlugins;
|
|
17122
17460
|
await this.saveClaudeSettings(claudeSettings);
|
|
17123
17461
|
}
|
|
17124
|
-
await
|
|
17462
|
+
await fs22.rm(component.installPath, { recursive: true, force: true }).catch(() => {
|
|
17125
17463
|
});
|
|
17126
17464
|
return true;
|
|
17127
17465
|
}
|
|
@@ -17172,7 +17510,7 @@ class PluginManager {
|
|
|
17172
17510
|
repo
|
|
17173
17511
|
};
|
|
17174
17512
|
}
|
|
17175
|
-
const defaultMarketplace = this.getMarketplaceIds()[0];
|
|
17513
|
+
const defaultMarketplace = getConfiguredDefaultMarketplaceId() || this.getMarketplaceIds()[0];
|
|
17176
17514
|
if (defaultMarketplace) {
|
|
17177
17515
|
return {
|
|
17178
17516
|
type: "marketplace",
|
|
@@ -17191,13 +17529,13 @@ class PluginManager {
|
|
|
17191
17529
|
async ensureMarketplaceCache(registryId) {
|
|
17192
17530
|
const registry = this.getMarketplace(registryId);
|
|
17193
17531
|
if (!registry) {
|
|
17194
|
-
throw new Error(`Unknown marketplace: ${registryId}. Available: ${
|
|
17532
|
+
throw new Error(`Unknown marketplace: ${registryId}. Available: ${this.getMarketplaceIds().join(", ")}`);
|
|
17195
17533
|
}
|
|
17196
17534
|
const cacheDir = getMarketplaceCacheDir(registryId);
|
|
17197
|
-
const cacheMetaPath =
|
|
17535
|
+
const cacheMetaPath = join4(cacheDir, ".agentinit-cache-meta.json");
|
|
17198
17536
|
if (await fileExists(cacheMetaPath)) {
|
|
17199
17537
|
try {
|
|
17200
|
-
const meta = JSON.parse(await
|
|
17538
|
+
const meta = JSON.parse(await fs22.readFile(cacheMetaPath, "utf8"));
|
|
17201
17539
|
const age = Date.now() - (meta.fetchedAt || 0);
|
|
17202
17540
|
if (age < registry.cacheTtlMs) {
|
|
17203
17541
|
return cacheDir;
|
|
@@ -17205,29 +17543,29 @@ class PluginManager {
|
|
|
17205
17543
|
} catch {
|
|
17206
17544
|
}
|
|
17207
17545
|
}
|
|
17208
|
-
if (await fileExists(
|
|
17546
|
+
if (await fileExists(join4(cacheDir, ".git"))) {
|
|
17209
17547
|
const { execFile } = await import("child_process");
|
|
17210
17548
|
const { promisify } = await import("util");
|
|
17211
17549
|
const exec = promisify(execFile);
|
|
17212
17550
|
try {
|
|
17213
17551
|
await exec("git", ["pull", "--ff-only"], { cwd: cacheDir, timeout: 30000 });
|
|
17214
17552
|
} catch {
|
|
17215
|
-
await
|
|
17553
|
+
await fs22.rm(cacheDir, { recursive: true, force: true });
|
|
17216
17554
|
await this.cloneMarketplace(registry.repoUrl, cacheDir);
|
|
17217
17555
|
}
|
|
17218
17556
|
} else {
|
|
17219
17557
|
await this.cloneMarketplace(registry.repoUrl, cacheDir);
|
|
17220
17558
|
}
|
|
17221
|
-
await
|
|
17222
|
-
await
|
|
17559
|
+
await fs22.mkdir(cacheDir, { recursive: true });
|
|
17560
|
+
await fs22.writeFile(cacheMetaPath, JSON.stringify({ fetchedAt: Date.now() }));
|
|
17223
17561
|
return cacheDir;
|
|
17224
17562
|
}
|
|
17225
17563
|
async cloneMarketplace(repoUrl, dest) {
|
|
17226
|
-
await
|
|
17564
|
+
await fs22.mkdir(dest, { recursive: true });
|
|
17227
17565
|
const { execFile } = await import("child_process");
|
|
17228
17566
|
const { promisify } = await import("util");
|
|
17229
17567
|
const exec = promisify(execFile);
|
|
17230
|
-
await
|
|
17568
|
+
await fs22.rm(dest, { recursive: true, force: true }).catch(() => {
|
|
17231
17569
|
});
|
|
17232
17570
|
await exec("git", ["clone", "--depth", "1", repoUrl, dest], { timeout: 60000 });
|
|
17233
17571
|
}
|
|
@@ -17237,7 +17575,7 @@ class PluginManager {
|
|
|
17237
17575
|
throw new Error(`Unknown marketplace: ${registryId}`);
|
|
17238
17576
|
const cacheDir = await this.ensureMarketplaceCache(registryId);
|
|
17239
17577
|
for (const dir of registry.pluginDirs) {
|
|
17240
|
-
const pluginPath =
|
|
17578
|
+
const pluginPath = join4(cacheDir, dir, name);
|
|
17241
17579
|
if (await isDirectory(pluginPath)) {
|
|
17242
17580
|
return pluginPath;
|
|
17243
17581
|
}
|
|
@@ -17253,7 +17591,7 @@ class PluginManager {
|
|
|
17253
17591
|
const cacheDir = await this.ensureMarketplaceCache(registryId);
|
|
17254
17592
|
const results = [];
|
|
17255
17593
|
for (const dir of registry.pluginDirs) {
|
|
17256
|
-
const fullDir =
|
|
17594
|
+
const fullDir = join4(cacheDir, dir);
|
|
17257
17595
|
if (!await isDirectory(fullDir))
|
|
17258
17596
|
continue;
|
|
17259
17597
|
const cat = dir === "plugins" ? "official" : dir === "external_plugins" ? "community" : dir.startsWith("skills/.") ? dir.slice("skills/.".length) : dir;
|
|
@@ -17263,26 +17601,26 @@ class PluginManager {
|
|
|
17263
17601
|
for (const entry of entries) {
|
|
17264
17602
|
if (entry.startsWith("."))
|
|
17265
17603
|
continue;
|
|
17266
|
-
const entryPath =
|
|
17604
|
+
const entryPath = join4(fullDir, entry);
|
|
17267
17605
|
if (!await isDirectory(entryPath))
|
|
17268
17606
|
continue;
|
|
17269
|
-
const manifestPath =
|
|
17607
|
+
const manifestPath = join4(entryPath, ".claude-plugin", "plugin.json");
|
|
17270
17608
|
let name = entry;
|
|
17271
17609
|
let description = "";
|
|
17272
17610
|
let version = "0.0.0";
|
|
17273
17611
|
if (await fileExists(manifestPath)) {
|
|
17274
17612
|
try {
|
|
17275
|
-
const manifest = JSON.parse(await
|
|
17613
|
+
const manifest = JSON.parse(await fs22.readFile(manifestPath, "utf8"));
|
|
17276
17614
|
name = manifest.name || entry;
|
|
17277
17615
|
description = manifest.description || "";
|
|
17278
17616
|
version = manifest.version || "0.0.0";
|
|
17279
17617
|
} catch {
|
|
17280
17618
|
}
|
|
17281
17619
|
} else {
|
|
17282
|
-
const skillMdPath =
|
|
17620
|
+
const skillMdPath = join4(entryPath, "SKILL.md");
|
|
17283
17621
|
if (await fileExists(skillMdPath)) {
|
|
17284
17622
|
try {
|
|
17285
|
-
const parsed = import_gray_matter.default(await
|
|
17623
|
+
const parsed = import_gray_matter.default(await fs22.readFile(skillMdPath, "utf8"));
|
|
17286
17624
|
if (parsed.data.name)
|
|
17287
17625
|
name = parsed.data.name;
|
|
17288
17626
|
if (parsed.data.description)
|
|
@@ -17290,10 +17628,10 @@ class PluginManager {
|
|
|
17290
17628
|
} catch {
|
|
17291
17629
|
}
|
|
17292
17630
|
} else {
|
|
17293
|
-
const mcpPath =
|
|
17631
|
+
const mcpPath = join4(entryPath, ".mcp.json");
|
|
17294
17632
|
if (await fileExists(mcpPath)) {
|
|
17295
17633
|
try {
|
|
17296
|
-
const mcpConfig = JSON.parse(await
|
|
17634
|
+
const mcpConfig = JSON.parse(await fs22.readFile(mcpPath, "utf8"));
|
|
17297
17635
|
const serverNames = Object.keys(mcpConfig.mcpServers || mcpConfig);
|
|
17298
17636
|
if (serverNames.length > 0) {
|
|
17299
17637
|
description = `MCP server(s): ${serverNames.join(", ")}`;
|
|
@@ -17315,10 +17653,10 @@ class PluginManager {
|
|
|
17315
17653
|
return results.sort((a, b) => a.name.localeCompare(b.name));
|
|
17316
17654
|
}
|
|
17317
17655
|
async detectFormat(pluginDir) {
|
|
17318
|
-
if (await fileExists(
|
|
17656
|
+
if (await fileExists(join4(pluginDir, ".claude-plugin", "plugin.json"))) {
|
|
17319
17657
|
return "claude";
|
|
17320
17658
|
}
|
|
17321
|
-
if (await fileExists(
|
|
17659
|
+
if (await fileExists(join4(pluginDir, ".cursor-plugin", "plugin.json"))) {
|
|
17322
17660
|
return "cursor";
|
|
17323
17661
|
}
|
|
17324
17662
|
return "generic";
|
|
@@ -17335,7 +17673,7 @@ class PluginManager {
|
|
|
17335
17673
|
}
|
|
17336
17674
|
}
|
|
17337
17675
|
async parseClaudePlugin(pluginDir, source) {
|
|
17338
|
-
const manifestPath =
|
|
17676
|
+
const manifestPath = join4(pluginDir, ".claude-plugin", "plugin.json");
|
|
17339
17677
|
const manifestContent = await readFileIfExists(manifestPath);
|
|
17340
17678
|
if (!manifestContent) {
|
|
17341
17679
|
throw new Error(`Missing .claude-plugin/plugin.json in ${pluginDir}`);
|
|
@@ -17346,10 +17684,10 @@ class PluginManager {
|
|
|
17346
17684
|
const convertedSkills = await this.convertCommandsToSkills(pluginDir, manifest);
|
|
17347
17685
|
skills.push(...convertedSkills);
|
|
17348
17686
|
const mcpServers = await this.parseMcpJson(pluginDir);
|
|
17349
|
-
if (await isDirectory(
|
|
17687
|
+
if (await isDirectory(join4(pluginDir, "hooks")) || manifest.hooks) {
|
|
17350
17688
|
warnings.push("Hooks (hooks/) are Claude Code-specific");
|
|
17351
17689
|
}
|
|
17352
|
-
if (await isDirectory(
|
|
17690
|
+
if (await isDirectory(join4(pluginDir, "agents")) || manifest.agents) {
|
|
17353
17691
|
warnings.push("Agent definitions (agents/) are Claude Code-specific");
|
|
17354
17692
|
}
|
|
17355
17693
|
return {
|
|
@@ -17364,7 +17702,7 @@ class PluginManager {
|
|
|
17364
17702
|
};
|
|
17365
17703
|
}
|
|
17366
17704
|
async parseCursorPlugin(pluginDir, source) {
|
|
17367
|
-
const manifestPath =
|
|
17705
|
+
const manifestPath = join4(pluginDir, ".cursor-plugin", "plugin.json");
|
|
17368
17706
|
const manifestContent = await readFileIfExists(manifestPath);
|
|
17369
17707
|
if (!manifestContent) {
|
|
17370
17708
|
throw new Error(`Missing .cursor-plugin/plugin.json in ${pluginDir}`);
|
|
@@ -17403,7 +17741,7 @@ class PluginManager {
|
|
|
17403
17741
|
};
|
|
17404
17742
|
}
|
|
17405
17743
|
async parseMcpJson(pluginDir) {
|
|
17406
|
-
const mcpPath =
|
|
17744
|
+
const mcpPath = join4(pluginDir, ".mcp.json");
|
|
17407
17745
|
const content = await readFileIfExists(mcpPath);
|
|
17408
17746
|
if (!content)
|
|
17409
17747
|
return [];
|
|
@@ -17450,7 +17788,7 @@ class PluginManager {
|
|
|
17450
17788
|
commandsDirs.push(resolve7(pluginDir, cmd));
|
|
17451
17789
|
}
|
|
17452
17790
|
} else {
|
|
17453
|
-
commandsDirs.push(
|
|
17791
|
+
commandsDirs.push(join4(pluginDir, "commands"));
|
|
17454
17792
|
}
|
|
17455
17793
|
for (const commandsDir of commandsDirs) {
|
|
17456
17794
|
if (!await isDirectory(commandsDir))
|
|
@@ -17459,7 +17797,7 @@ class PluginManager {
|
|
|
17459
17797
|
for (const entry of entries) {
|
|
17460
17798
|
if (!entry.endsWith(".md"))
|
|
17461
17799
|
continue;
|
|
17462
|
-
const cmdPath =
|
|
17800
|
+
const cmdPath = join4(commandsDir, entry);
|
|
17463
17801
|
const skill = await this.convertSingleCommandToSkill(cmdPath, manifest.name);
|
|
17464
17802
|
if (skill)
|
|
17465
17803
|
skills.push(skill);
|
|
@@ -17748,7 +18086,7 @@ ${body.trim()}
|
|
|
17748
18086
|
}
|
|
17749
18087
|
if (!removedSkillPaths.has(skill.path)) {
|
|
17750
18088
|
try {
|
|
17751
|
-
await
|
|
18089
|
+
await fs22.rm(skill.path, { recursive: true, force: true });
|
|
17752
18090
|
removedSkillPaths.add(skill.path);
|
|
17753
18091
|
} catch {
|
|
17754
18092
|
details.push(`Could not remove skill path: ${skill.path}`);
|
|
@@ -17757,7 +18095,7 @@ ${body.trim()}
|
|
|
17757
18095
|
}
|
|
17758
18096
|
if (skill.canonicalPath && skill.canonicalPath !== skill.path && !removedCanonicalPaths.has(skill.canonicalPath) && !sharedCanonicalPath) {
|
|
17759
18097
|
try {
|
|
17760
|
-
await
|
|
18098
|
+
await fs22.rm(skill.canonicalPath, { recursive: true, force: true });
|
|
17761
18099
|
removedCanonicalPaths.add(skill.canonicalPath);
|
|
17762
18100
|
} catch {
|
|
17763
18101
|
details.push(`Could not remove canonical skill path: ${skill.canonicalPath}`);
|
|
@@ -17861,27 +18199,28 @@ var init_pluginManager = __esm(() => {
|
|
|
17861
18199
|
init_mcpFilter();
|
|
17862
18200
|
init_marketplaceRegistry();
|
|
17863
18201
|
init_skillsManager();
|
|
18202
|
+
init_userConfig();
|
|
17864
18203
|
getMarketplaceCacheDir = function(registryId) {
|
|
17865
|
-
return
|
|
18204
|
+
return join4(homedir4(), ".agentinit", "marketplace-cache", registryId);
|
|
17866
18205
|
};
|
|
17867
18206
|
getRegistryPath = function(projectPath, global3) {
|
|
17868
18207
|
if (global3) {
|
|
17869
|
-
return
|
|
18208
|
+
return join4(homedir4(), ".agentinit", "plugins.json");
|
|
17870
18209
|
}
|
|
17871
|
-
return
|
|
18210
|
+
return join4(projectPath, ".agentinit", "plugins.json");
|
|
17872
18211
|
};
|
|
17873
18212
|
getClaudeInstalledPluginsPath = function() {
|
|
17874
|
-
return
|
|
18213
|
+
return join4(homedir4(), ".claude", "plugins", "installed_plugins.json");
|
|
17875
18214
|
};
|
|
17876
18215
|
getClaudeSettingsPath = function() {
|
|
17877
|
-
return
|
|
18216
|
+
return join4(homedir4(), ".claude", "settings.json");
|
|
17878
18217
|
};
|
|
17879
18218
|
});
|
|
17880
18219
|
|
|
17881
18220
|
// dist/core/skillsManager.js
|
|
17882
|
-
import {resolve as resolve8, join as
|
|
17883
|
-
import {promises as
|
|
17884
|
-
import {homedir as
|
|
18221
|
+
import {resolve as resolve8, join as join5, relative as relative3} from "path";
|
|
18222
|
+
import {promises as fs24} from "fs";
|
|
18223
|
+
import {homedir as homedir5, tmpdir} from "os";
|
|
17885
18224
|
import {execFile} from "child_process";
|
|
17886
18225
|
import {promisify} from "util";
|
|
17887
18226
|
|
|
@@ -17948,6 +18287,17 @@ class SkillsManager {
|
|
|
17948
18287
|
}
|
|
17949
18288
|
resolveSourceRequest(source, options2) {
|
|
17950
18289
|
if (this.isImplicitCatalogSkillSource(source, options2)) {
|
|
18290
|
+
const configuredDefaultMarketplace = getConfiguredDefaultMarketplaceId();
|
|
18291
|
+
if (configuredDefaultMarketplace) {
|
|
18292
|
+
return {
|
|
18293
|
+
source: {
|
|
18294
|
+
type: "marketplace",
|
|
18295
|
+
marketplace: configuredDefaultMarketplace,
|
|
18296
|
+
pluginName: source.trim()
|
|
18297
|
+
},
|
|
18298
|
+
implicitSkills: []
|
|
18299
|
+
};
|
|
18300
|
+
}
|
|
17951
18301
|
return {
|
|
17952
18302
|
source: {
|
|
17953
18303
|
type: "github",
|
|
@@ -17984,7 +18334,7 @@ class SkillsManager {
|
|
|
17984
18334
|
const fullDir = resolve8(repoPath, searchDir);
|
|
17985
18335
|
if (!await fileExists(fullDir))
|
|
17986
18336
|
continue;
|
|
17987
|
-
const directSkillMd =
|
|
18337
|
+
const directSkillMd = join5(fullDir, "SKILL.md");
|
|
17988
18338
|
if (await fileExists(directSkillMd)) {
|
|
17989
18339
|
const parsed = await this.parseSkillMd(directSkillMd);
|
|
17990
18340
|
if (parsed && !seen.has(parsed.name)) {
|
|
@@ -17992,7 +18342,7 @@ class SkillsManager {
|
|
|
17992
18342
|
skills.push({ ...parsed, path: resolve8(fullDir) });
|
|
17993
18343
|
}
|
|
17994
18344
|
}
|
|
17995
|
-
const directSkillMdLower =
|
|
18345
|
+
const directSkillMdLower = join5(fullDir, "skill.md");
|
|
17996
18346
|
if (await fileExists(directSkillMdLower)) {
|
|
17997
18347
|
const parsed = await this.parseSkillMd(directSkillMdLower);
|
|
17998
18348
|
if (parsed && !seen.has(parsed.name)) {
|
|
@@ -18004,11 +18354,11 @@ class SkillsManager {
|
|
|
18004
18354
|
continue;
|
|
18005
18355
|
const entries = await listFiles(fullDir);
|
|
18006
18356
|
for (const entry of entries) {
|
|
18007
|
-
const entryPath =
|
|
18357
|
+
const entryPath = join5(fullDir, entry);
|
|
18008
18358
|
if (!await isDirectory(entryPath))
|
|
18009
18359
|
continue;
|
|
18010
|
-
const skillMdPath =
|
|
18011
|
-
const skillMdPathLower =
|
|
18360
|
+
const skillMdPath = join5(entryPath, "SKILL.md");
|
|
18361
|
+
const skillMdPathLower = join5(entryPath, "skill.md");
|
|
18012
18362
|
const skillFile = await fileExists(skillMdPath) ? skillMdPath : await fileExists(skillMdPathLower) ? skillMdPathLower : null;
|
|
18013
18363
|
if (!skillFile)
|
|
18014
18364
|
continue;
|
|
@@ -18022,14 +18372,14 @@ class SkillsManager {
|
|
|
18022
18372
|
return skills;
|
|
18023
18373
|
}
|
|
18024
18374
|
async cloneRepo(url) {
|
|
18025
|
-
const tempDir = await
|
|
18026
|
-
await
|
|
18375
|
+
const tempDir = await fs24.mkdtemp(join5(tmpdir(), "agentinit-skills-"));
|
|
18376
|
+
await fs24.rm(tempDir, { recursive: true, force: true });
|
|
18027
18377
|
try {
|
|
18028
18378
|
await execFileAsync("git", ["clone", "--depth", "1", url, tempDir], {
|
|
18029
18379
|
timeout: 60000
|
|
18030
18380
|
});
|
|
18031
18381
|
} catch (error) {
|
|
18032
|
-
await
|
|
18382
|
+
await fs24.rm(tempDir, { recursive: true, force: true }).catch(() => {
|
|
18033
18383
|
});
|
|
18034
18384
|
throw new Error(`Failed to clone ${url}: ${error.message}`);
|
|
18035
18385
|
}
|
|
@@ -18123,7 +18473,7 @@ class SkillsManager {
|
|
|
18123
18473
|
return { skills, warnings };
|
|
18124
18474
|
} finally {
|
|
18125
18475
|
if (tempDir) {
|
|
18126
|
-
await
|
|
18476
|
+
await fs24.rm(tempDir, { recursive: true, force: true }).catch(() => {
|
|
18127
18477
|
});
|
|
18128
18478
|
}
|
|
18129
18479
|
}
|
|
@@ -18144,30 +18494,30 @@ class SkillsManager {
|
|
|
18144
18494
|
async installSkill(skillPath, skillName, targetDir, copy = false) {
|
|
18145
18495
|
const normalizedSkillName = this.normalizeSkillName(skillName);
|
|
18146
18496
|
const destPath = this.resolveInstallPath(targetDir, normalizedSkillName);
|
|
18147
|
-
await
|
|
18497
|
+
await fs24.mkdir(resolve8(targetDir), { recursive: true });
|
|
18148
18498
|
if (await fileExists(destPath)) {
|
|
18149
|
-
await
|
|
18499
|
+
await fs24.rm(destPath, { recursive: true, force: true });
|
|
18150
18500
|
}
|
|
18151
18501
|
if (copy) {
|
|
18152
18502
|
await this.copyDir(skillPath, destPath);
|
|
18153
18503
|
} else {
|
|
18154
|
-
await
|
|
18504
|
+
await fs24.symlink(skillPath, destPath, "dir");
|
|
18155
18505
|
}
|
|
18156
18506
|
return destPath;
|
|
18157
18507
|
}
|
|
18158
18508
|
async installSkillFromContent(skillName, skillContent, targetDir) {
|
|
18159
18509
|
const normalizedSkillName = this.normalizeSkillName(skillName);
|
|
18160
18510
|
const destPath = this.resolveInstallPath(targetDir, normalizedSkillName);
|
|
18161
|
-
await
|
|
18511
|
+
await fs24.mkdir(resolve8(targetDir), { recursive: true });
|
|
18162
18512
|
if (await fileExists(destPath)) {
|
|
18163
|
-
await
|
|
18513
|
+
await fs24.rm(destPath, { recursive: true, force: true });
|
|
18164
18514
|
}
|
|
18165
|
-
await
|
|
18166
|
-
await
|
|
18515
|
+
await fs24.mkdir(destPath, { recursive: true });
|
|
18516
|
+
await fs24.writeFile(join5(destPath, "SKILL.md"), skillContent, "utf8");
|
|
18167
18517
|
return destPath;
|
|
18168
18518
|
}
|
|
18169
18519
|
getCanonicalSkillsDir(projectPath, global3 = false) {
|
|
18170
|
-
return global3 ? resolve8(
|
|
18520
|
+
return global3 ? resolve8(homedir5(), ".agents/skills") : resolve8(projectPath, ".agents/skills");
|
|
18171
18521
|
}
|
|
18172
18522
|
async getInstallPlan(skillName, agent, projectPath, options2 = {}) {
|
|
18173
18523
|
const normalizedSkillName = this.normalizeSkillName(skillName);
|
|
@@ -18241,7 +18591,7 @@ class SkillsManager {
|
|
|
18241
18591
|
throw new Error(`Missing canonical path for ${skillName}`);
|
|
18242
18592
|
}
|
|
18243
18593
|
await this.cleanAndCreateDirectory(canonicalPath);
|
|
18244
|
-
await
|
|
18594
|
+
await fs24.writeFile(join5(canonicalPath, "SKILL.md"), skillContent, "utf8");
|
|
18245
18595
|
if (plan.path === canonicalPath) {
|
|
18246
18596
|
return plan;
|
|
18247
18597
|
}
|
|
@@ -18278,16 +18628,16 @@ class SkillsManager {
|
|
|
18278
18628
|
return this.resolveInstallPath(targetDir, this.normalizeSkillName(skillName));
|
|
18279
18629
|
}
|
|
18280
18630
|
async cleanAndCreateDirectory(path) {
|
|
18281
|
-
await
|
|
18631
|
+
await fs24.rm(path, { recursive: true, force: true }).catch(() => {
|
|
18282
18632
|
});
|
|
18283
|
-
await
|
|
18633
|
+
await fs24.mkdir(path, { recursive: true });
|
|
18284
18634
|
}
|
|
18285
18635
|
isWithinPath(basePath, targetPath) {
|
|
18286
18636
|
const relativePath = relative3(resolve8(basePath), resolve8(targetPath));
|
|
18287
18637
|
return relativePath === "" || !relativePath.startsWith("..") && !relativePath.includes("/../") && !relativePath.includes("\\..\\");
|
|
18288
18638
|
}
|
|
18289
18639
|
async copyDir(src, dest) {
|
|
18290
|
-
await
|
|
18640
|
+
await fs24.cp(src, dest, { recursive: true, dereference: true });
|
|
18291
18641
|
}
|
|
18292
18642
|
async addFromSource(source, projectPath, options2 = {}) {
|
|
18293
18643
|
const discovered = await this.discoverFromSource(source, projectPath, {
|
|
@@ -18362,11 +18712,11 @@ class SkillsManager {
|
|
|
18362
18712
|
continue;
|
|
18363
18713
|
const entries = await listFiles(dir);
|
|
18364
18714
|
for (const entry of entries) {
|
|
18365
|
-
const entryPath =
|
|
18715
|
+
const entryPath = join5(dir, entry);
|
|
18366
18716
|
if (!await isDirectory(entryPath))
|
|
18367
18717
|
continue;
|
|
18368
|
-
const skillMdPath =
|
|
18369
|
-
const skillMdPathLower =
|
|
18718
|
+
const skillMdPath = join5(entryPath, "SKILL.md");
|
|
18719
|
+
const skillMdPathLower = join5(entryPath, "skill.md");
|
|
18370
18720
|
const skillFile = await fileExists(skillMdPath) ? skillMdPath : await fileExists(skillMdPathLower) ? skillMdPathLower : null;
|
|
18371
18721
|
if (!skillFile)
|
|
18372
18722
|
continue;
|
|
@@ -18376,7 +18726,7 @@ class SkillsManager {
|
|
|
18376
18726
|
let isSymlink = false;
|
|
18377
18727
|
let canonicalPath;
|
|
18378
18728
|
try {
|
|
18379
|
-
const stat = await
|
|
18729
|
+
const stat = await fs24.lstat(entryPath);
|
|
18380
18730
|
isSymlink = stat.isSymbolicLink();
|
|
18381
18731
|
const canonicalBase = this.getCanonicalSkillsDir(projectPath, scope === "global");
|
|
18382
18732
|
const [resolvedEntryPath, resolvedCanonicalBase] = await Promise.all([
|
|
@@ -18442,7 +18792,7 @@ class SkillsManager {
|
|
|
18442
18792
|
}
|
|
18443
18793
|
if (!removedPaths.has(entry.path)) {
|
|
18444
18794
|
try {
|
|
18445
|
-
await
|
|
18795
|
+
await fs24.rm(entry.path, { recursive: true, force: true });
|
|
18446
18796
|
removedPaths.add(entry.path);
|
|
18447
18797
|
} catch {
|
|
18448
18798
|
skipped.push({
|
|
@@ -18455,7 +18805,7 @@ class SkillsManager {
|
|
|
18455
18805
|
if (entry.canonicalPath && entry.canonicalPath !== entry.path && !removedCanonicalPaths.has(entry.canonicalPath)) {
|
|
18456
18806
|
const stillReferenced = remainingEntries.some((other) => other.name.toLowerCase() === entry.name.toLowerCase() && other.canonicalPath === entry.canonicalPath);
|
|
18457
18807
|
if (!stillReferenced) {
|
|
18458
|
-
await
|
|
18808
|
+
await fs24.rm(entry.canonicalPath, { recursive: true, force: true }).catch(() => {
|
|
18459
18809
|
});
|
|
18460
18810
|
removedCanonicalPaths.add(entry.canonicalPath);
|
|
18461
18811
|
}
|
|
@@ -19869,7 +20219,7 @@ var require_util3 = __commonJS((exports, module) => {
|
|
|
19869
20219
|
var path = jsonPointers ? toQuotedString("/" + escapeJsonPointer(prop)) : toQuotedString(getProperty(prop));
|
|
19870
20220
|
return joinPaths(currentPath, path);
|
|
19871
20221
|
};
|
|
19872
|
-
var getData = function($data, lvl,
|
|
20222
|
+
var getData = function($data, lvl, paths5) {
|
|
19873
20223
|
var up, jsonPointer, data, matches;
|
|
19874
20224
|
if ($data === "")
|
|
19875
20225
|
return "rootData";
|
|
@@ -19887,7 +20237,7 @@ var require_util3 = __commonJS((exports, module) => {
|
|
|
19887
20237
|
if (jsonPointer == "#") {
|
|
19888
20238
|
if (up >= lvl)
|
|
19889
20239
|
throw new Error("Cannot access property/index " + up + " levels up, current level is " + lvl);
|
|
19890
|
-
return
|
|
20240
|
+
return paths5[lvl - up];
|
|
19891
20241
|
}
|
|
19892
20242
|
if (up > lvl)
|
|
19893
20243
|
throw new Error("Cannot access data " + up + " levels up, current level is " + lvl);
|
|
@@ -24691,27 +25041,27 @@ var require_windows = __commonJS((exports, module) => {
|
|
|
24691
25041
|
return checkPathExt(path, options2);
|
|
24692
25042
|
};
|
|
24693
25043
|
var isexe = function(path, options2, cb) {
|
|
24694
|
-
|
|
25044
|
+
fs31.stat(path, function(er, stat) {
|
|
24695
25045
|
cb(er, er ? false : checkStat(stat, path, options2));
|
|
24696
25046
|
});
|
|
24697
25047
|
};
|
|
24698
25048
|
var sync = function(path, options2) {
|
|
24699
|
-
return checkStat(
|
|
25049
|
+
return checkStat(fs31.statSync(path), path, options2);
|
|
24700
25050
|
};
|
|
24701
25051
|
module.exports = isexe;
|
|
24702
25052
|
isexe.sync = sync;
|
|
24703
|
-
var
|
|
25053
|
+
var fs31 = __require("fs");
|
|
24704
25054
|
});
|
|
24705
25055
|
|
|
24706
25056
|
// node_modules/isexe/mode.js
|
|
24707
25057
|
var require_mode = __commonJS((exports, module) => {
|
|
24708
25058
|
var isexe = function(path, options2, cb) {
|
|
24709
|
-
|
|
25059
|
+
fs31.stat(path, function(er, stat) {
|
|
24710
25060
|
cb(er, er ? false : checkStat(stat, options2));
|
|
24711
25061
|
});
|
|
24712
25062
|
};
|
|
24713
25063
|
var sync = function(path, options2) {
|
|
24714
|
-
return checkStat(
|
|
25064
|
+
return checkStat(fs31.statSync(path), options2);
|
|
24715
25065
|
};
|
|
24716
25066
|
var checkStat = function(stat, options2) {
|
|
24717
25067
|
return stat.isFile() && checkMode(stat, options2);
|
|
@@ -24731,7 +25081,7 @@ var require_mode = __commonJS((exports, module) => {
|
|
|
24731
25081
|
};
|
|
24732
25082
|
module.exports = isexe;
|
|
24733
25083
|
isexe.sync = sync;
|
|
24734
|
-
var
|
|
25084
|
+
var fs31 = __require("fs");
|
|
24735
25085
|
});
|
|
24736
25086
|
|
|
24737
25087
|
// node_modules/isexe/index.js
|
|
@@ -24776,7 +25126,7 @@ var require_isexe = __commonJS((exports, module) => {
|
|
|
24776
25126
|
}
|
|
24777
25127
|
}
|
|
24778
25128
|
};
|
|
24779
|
-
var
|
|
25129
|
+
var fs31 = __require("fs");
|
|
24780
25130
|
var core2;
|
|
24781
25131
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
24782
25132
|
core2 = require_windows();
|
|
@@ -24983,14 +25333,14 @@ var require_readShebang = __commonJS((exports, module) => {
|
|
|
24983
25333
|
const buffer = Buffer.alloc(size);
|
|
24984
25334
|
let fd;
|
|
24985
25335
|
try {
|
|
24986
|
-
fd =
|
|
24987
|
-
|
|
24988
|
-
|
|
25336
|
+
fd = fs31.openSync(command, "r");
|
|
25337
|
+
fs31.readSync(fd, buffer, 0, size, 0);
|
|
25338
|
+
fs31.closeSync(fd);
|
|
24989
25339
|
} catch (e) {
|
|
24990
25340
|
}
|
|
24991
25341
|
return shebangCommand(buffer.toString());
|
|
24992
25342
|
};
|
|
24993
|
-
var
|
|
25343
|
+
var fs31 = __require("fs");
|
|
24994
25344
|
var shebangCommand = require_shebang_command();
|
|
24995
25345
|
module.exports = readShebang;
|
|
24996
25346
|
});
|
|
@@ -25142,7 +25492,7 @@ var {
|
|
|
25142
25492
|
} = import_.default;
|
|
25143
25493
|
|
|
25144
25494
|
// dist/commands/init.js
|
|
25145
|
-
import {resolve as
|
|
25495
|
+
import {resolve as resolve5} from "path";
|
|
25146
25496
|
|
|
25147
25497
|
// node_modules/ora/index.js
|
|
25148
25498
|
import process9 from "node:process";
|
|
@@ -26493,7 +26843,45 @@ var bgMagenta = init(45, 49);
|
|
|
26493
26843
|
var bgCyan = init(46, 49);
|
|
26494
26844
|
var bgWhite = init(47, 49);
|
|
26495
26845
|
|
|
26846
|
+
// dist/utils/symbols.js
|
|
26847
|
+
var STATUS = {
|
|
26848
|
+
success: "\u2713",
|
|
26849
|
+
error: "\u2717",
|
|
26850
|
+
warning: "\u26A0",
|
|
26851
|
+
info: "\u2139",
|
|
26852
|
+
debug: "\u2022"
|
|
26853
|
+
};
|
|
26854
|
+
var TREE = {
|
|
26855
|
+
branch: "\u251C\u2500",
|
|
26856
|
+
last: "\u2514\u2500"
|
|
26857
|
+
};
|
|
26858
|
+
var BOX = {
|
|
26859
|
+
topLeft: "\u250C",
|
|
26860
|
+
topRight: "\u2510",
|
|
26861
|
+
bottomLeft: "\u2514",
|
|
26862
|
+
bottomRight: "\u2518",
|
|
26863
|
+
horizontal: "\u2500",
|
|
26864
|
+
vertical: "\u2502"
|
|
26865
|
+
};
|
|
26866
|
+
|
|
26496
26867
|
// dist/utils/logger.js
|
|
26868
|
+
var getTerminalWidth = function() {
|
|
26869
|
+
const columns = process.stdout.columns;
|
|
26870
|
+
return typeof columns === "number" && columns > 0 ? columns : 80;
|
|
26871
|
+
};
|
|
26872
|
+
var truncateText = function(text, maxLength) {
|
|
26873
|
+
if (maxLength <= 0) {
|
|
26874
|
+
return "";
|
|
26875
|
+
}
|
|
26876
|
+
if (text.length <= maxLength) {
|
|
26877
|
+
return text;
|
|
26878
|
+
}
|
|
26879
|
+
if (maxLength <= 3) {
|
|
26880
|
+
return ".".repeat(maxLength);
|
|
26881
|
+
}
|
|
26882
|
+
return `${text.slice(0, maxLength - 3)}...`;
|
|
26883
|
+
};
|
|
26884
|
+
|
|
26497
26885
|
class Logger {
|
|
26498
26886
|
static instance;
|
|
26499
26887
|
static getInstance() {
|
|
@@ -26503,22 +26891,22 @@ class Logger {
|
|
|
26503
26891
|
return Logger.instance;
|
|
26504
26892
|
}
|
|
26505
26893
|
info(message) {
|
|
26506
|
-
console.log(cyan(
|
|
26894
|
+
console.log(cyan(STATUS.info), message);
|
|
26507
26895
|
}
|
|
26508
26896
|
success(message) {
|
|
26509
|
-
console.log(green(
|
|
26897
|
+
console.log(green(STATUS.success), message);
|
|
26510
26898
|
}
|
|
26511
26899
|
warning(message) {
|
|
26512
|
-
console.log(yellow(
|
|
26900
|
+
console.log(yellow(STATUS.warning), message);
|
|
26513
26901
|
}
|
|
26514
26902
|
warn(message) {
|
|
26515
26903
|
this.warning(message);
|
|
26516
26904
|
}
|
|
26517
26905
|
error(message) {
|
|
26518
|
-
console.log(red(
|
|
26906
|
+
console.log(red(STATUS.error), message);
|
|
26519
26907
|
}
|
|
26520
26908
|
debug(message) {
|
|
26521
|
-
console.log(dim(
|
|
26909
|
+
console.log(dim(STATUS.debug), dim(message));
|
|
26522
26910
|
}
|
|
26523
26911
|
title(message) {
|
|
26524
26912
|
console.log(bold(cyan(message)));
|
|
@@ -26526,6 +26914,30 @@ class Logger {
|
|
|
26526
26914
|
subtitle(message) {
|
|
26527
26915
|
console.log(bold(message));
|
|
26528
26916
|
}
|
|
26917
|
+
titleBox(message) {
|
|
26918
|
+
const w = getTerminalWidth();
|
|
26919
|
+
if (w < 8) {
|
|
26920
|
+
console.log(bold(cyan(truncateText(message, w))));
|
|
26921
|
+
return;
|
|
26922
|
+
}
|
|
26923
|
+
const maxInner = Math.max(4, w - 2);
|
|
26924
|
+
const inner = Math.min(Math.max(message.length + 4, 40), maxInner);
|
|
26925
|
+
const visibleMessage = truncateText(message, inner - 2);
|
|
26926
|
+
const padR = Math.max(0, inner - visibleMessage.length - 2);
|
|
26927
|
+
console.log(dim(BOX.topLeft + BOX.horizontal.repeat(inner) + BOX.topRight));
|
|
26928
|
+
console.log(dim(BOX.vertical) + " " + bold(cyan(visibleMessage)) + " ".repeat(padR) + " " + dim(BOX.vertical));
|
|
26929
|
+
console.log(dim(BOX.bottomLeft + BOX.horizontal.repeat(inner) + BOX.bottomRight));
|
|
26930
|
+
}
|
|
26931
|
+
section(title) {
|
|
26932
|
+
const w = getTerminalWidth();
|
|
26933
|
+
const lineLen = Math.max(0, w - title.length - 5);
|
|
26934
|
+
console.log("");
|
|
26935
|
+
console.log(bold(`${BOX.horizontal}${BOX.horizontal} ${title} ${BOX.horizontal.repeat(lineLen)}`));
|
|
26936
|
+
}
|
|
26937
|
+
tree(message, isLast) {
|
|
26938
|
+
const connector = isLast ? TREE.last : TREE.branch;
|
|
26939
|
+
console.log(`${connector} ${message}`);
|
|
26940
|
+
}
|
|
26529
26941
|
}
|
|
26530
26942
|
var logger = Logger.getInstance();
|
|
26531
26943
|
|
|
@@ -26534,7 +26946,8 @@ init_fs();
|
|
|
26534
26946
|
|
|
26535
26947
|
// dist/core/agentDetector.js
|
|
26536
26948
|
init_fs();
|
|
26537
|
-
|
|
26949
|
+
init_paths();
|
|
26950
|
+
import {isAbsolute, resolve as resolve3} from "path";
|
|
26538
26951
|
|
|
26539
26952
|
class AgentDetector {
|
|
26540
26953
|
agentConfigs = [
|
|
@@ -26545,14 +26958,19 @@ class AgentDetector {
|
|
|
26545
26958
|
{ name: "codeium", files: [".codeium/config.json"] },
|
|
26546
26959
|
{ name: "codex", files: [".codex/config.toml"] },
|
|
26547
26960
|
{ name: "gemini", files: [".gemini/settings.json"] },
|
|
26961
|
+
{ name: "openclaw", files: ["~/.openclaw"], scope: "environment" },
|
|
26962
|
+
{ name: "hermes", files: ["~/.hermes"], scope: "environment" },
|
|
26548
26963
|
{ name: "aider", files: [".aider.conf.yml"] },
|
|
26549
26964
|
{ name: "cline", files: [".clinerules"] },
|
|
26550
26965
|
{ name: "roo", files: [".roo/mcp.json"] },
|
|
26551
26966
|
{ name: "zed", files: [".zed/settings.json"] }
|
|
26552
26967
|
];
|
|
26553
|
-
async detectAgents(projectPath) {
|
|
26968
|
+
async detectAgents(projectPath, options2 = {}) {
|
|
26554
26969
|
const results = [];
|
|
26555
26970
|
for (const config of this.agentConfigs) {
|
|
26971
|
+
if (!this.shouldCheckScope(config.scope, options2)) {
|
|
26972
|
+
continue;
|
|
26973
|
+
}
|
|
26556
26974
|
const detected = await this.checkAgentFiles(projectPath, config.files);
|
|
26557
26975
|
results.push({
|
|
26558
26976
|
name: config.name,
|
|
@@ -26563,19 +26981,41 @@ class AgentDetector {
|
|
|
26563
26981
|
}
|
|
26564
26982
|
return results;
|
|
26565
26983
|
}
|
|
26984
|
+
shouldCheckScope(scope, options2) {
|
|
26985
|
+
if (options2.includeEnvironment) {
|
|
26986
|
+
return true;
|
|
26987
|
+
}
|
|
26988
|
+
return scope !== "environment";
|
|
26989
|
+
}
|
|
26566
26990
|
async checkAgentFiles(projectPath, files) {
|
|
26567
26991
|
for (const file of files) {
|
|
26568
|
-
const fullPath =
|
|
26992
|
+
const fullPath = this.resolveDetectionPath(projectPath, file);
|
|
26569
26993
|
if (await fileExists(fullPath)) {
|
|
26570
26994
|
return { found: true, path: fullPath };
|
|
26571
26995
|
}
|
|
26572
26996
|
}
|
|
26573
26997
|
return { found: false };
|
|
26574
26998
|
}
|
|
26575
|
-
|
|
26999
|
+
resolveDetectionPath(projectPath, file) {
|
|
27000
|
+
if (file.startsWith("~")) {
|
|
27001
|
+
return expandTilde(file);
|
|
27002
|
+
}
|
|
27003
|
+
if (isAbsolute(file)) {
|
|
27004
|
+
return file;
|
|
27005
|
+
}
|
|
27006
|
+
return resolve3(projectPath, file);
|
|
27007
|
+
}
|
|
27008
|
+
async detectAgentByName(projectPath, agentName, options2 = {}) {
|
|
26576
27009
|
const config = this.agentConfigs.find((c) => c.name === agentName);
|
|
26577
27010
|
if (!config)
|
|
26578
27011
|
return null;
|
|
27012
|
+
if (!this.shouldCheckScope(config.scope, options2)) {
|
|
27013
|
+
return {
|
|
27014
|
+
name: config.name,
|
|
27015
|
+
files: config.files,
|
|
27016
|
+
detected: false
|
|
27017
|
+
};
|
|
27018
|
+
}
|
|
26579
27019
|
const detected = await this.checkAgentFiles(projectPath, config.files);
|
|
26580
27020
|
return {
|
|
26581
27021
|
name: config.name,
|
|
@@ -26591,7 +27031,7 @@ class AgentDetector {
|
|
|
26591
27031
|
|
|
26592
27032
|
// dist/core/stackDetector.js
|
|
26593
27033
|
init_fs();
|
|
26594
|
-
import {resolve as
|
|
27034
|
+
import {resolve as resolve4} from "path";
|
|
26595
27035
|
|
|
26596
27036
|
class StackDetector {
|
|
26597
27037
|
lockFiles = [
|
|
@@ -26637,7 +27077,7 @@ class StackDetector {
|
|
|
26637
27077
|
}
|
|
26638
27078
|
async detectFromLockFiles(projectPath) {
|
|
26639
27079
|
for (const lockFile of this.lockFiles) {
|
|
26640
|
-
const lockPath =
|
|
27080
|
+
const lockPath = resolve4(projectPath, lockFile);
|
|
26641
27081
|
if (await fileExists(lockPath)) {
|
|
26642
27082
|
return this.inferStackFromLockFile(projectPath, lockFile);
|
|
26643
27083
|
}
|
|
@@ -26669,7 +27109,7 @@ class StackDetector {
|
|
|
26669
27109
|
}
|
|
26670
27110
|
async detectFromManifests(projectPath) {
|
|
26671
27111
|
for (const manifest of this.manifestFiles) {
|
|
26672
|
-
const manifestPath =
|
|
27112
|
+
const manifestPath = resolve4(projectPath, manifest);
|
|
26673
27113
|
if (await fileExists(manifestPath)) {
|
|
26674
27114
|
return this.inferStackFromManifest(projectPath, manifest);
|
|
26675
27115
|
}
|
|
@@ -26701,7 +27141,7 @@ class StackDetector {
|
|
|
26701
27141
|
}
|
|
26702
27142
|
async detectFromConfigs(projectPath) {
|
|
26703
27143
|
for (const config of this.configFiles) {
|
|
26704
|
-
const configPath =
|
|
27144
|
+
const configPath = resolve4(projectPath, config);
|
|
26705
27145
|
if (await fileExists(configPath)) {
|
|
26706
27146
|
return this.inferStackFromConfig(projectPath, config);
|
|
26707
27147
|
}
|
|
@@ -26760,7 +27200,7 @@ class StackDetector {
|
|
|
26760
27200
|
};
|
|
26761
27201
|
}
|
|
26762
27202
|
async analyzeJavaScriptProject(projectPath) {
|
|
26763
|
-
const packageJsonPath =
|
|
27203
|
+
const packageJsonPath = resolve4(projectPath, "package.json");
|
|
26764
27204
|
const packageJsonContent = await readFileIfExists(packageJsonPath);
|
|
26765
27205
|
const info = {
|
|
26766
27206
|
language: "javascript",
|
|
@@ -26775,7 +27215,7 @@ class StackDetector {
|
|
|
26775
27215
|
...packageJson.devDependencies
|
|
26776
27216
|
};
|
|
26777
27217
|
info.dependencies = Object.keys(allDeps);
|
|
26778
|
-
if (allDeps.typescript || await fileExists(
|
|
27218
|
+
if (allDeps.typescript || await fileExists(resolve4(projectPath, "tsconfig.json"))) {
|
|
26779
27219
|
info.language = "typescript";
|
|
26780
27220
|
}
|
|
26781
27221
|
if (allDeps.next)
|
|
@@ -26792,11 +27232,11 @@ class StackDetector {
|
|
|
26792
27232
|
info.framework = "express";
|
|
26793
27233
|
else if (allDeps.fastify)
|
|
26794
27234
|
info.framework = "fastify";
|
|
26795
|
-
if (await fileExists(
|
|
27235
|
+
if (await fileExists(resolve4(projectPath, "yarn.lock")))
|
|
26796
27236
|
info.packageManager = "yarn";
|
|
26797
|
-
else if (await fileExists(
|
|
27237
|
+
else if (await fileExists(resolve4(projectPath, "pnpm-lock.yaml")))
|
|
26798
27238
|
info.packageManager = "pnpm";
|
|
26799
|
-
else if (await fileExists(
|
|
27239
|
+
else if (await fileExists(resolve4(projectPath, "bun.lockb")))
|
|
26800
27240
|
info.packageManager = "bun";
|
|
26801
27241
|
else
|
|
26802
27242
|
info.packageManager = "npm";
|
|
@@ -27075,8 +27515,8 @@ This is a {{STACK}} project{{FRAMEWORK_CONTEXT}}. The codebase follows modern de
|
|
|
27075
27515
|
// dist/commands/init.js
|
|
27076
27516
|
async function initCommand(options2) {
|
|
27077
27517
|
const cwd = process.cwd();
|
|
27078
|
-
const agentsPath =
|
|
27079
|
-
logger.
|
|
27518
|
+
const agentsPath = resolve5(cwd, "agents.md");
|
|
27519
|
+
logger.titleBox("AgentInit Initialize Project");
|
|
27080
27520
|
if (!options2.force && await fileExists(agentsPath)) {
|
|
27081
27521
|
const response = await import_prompts.default({
|
|
27082
27522
|
type: "confirm",
|
|
@@ -27153,7 +27593,7 @@ async function initCommand(options2) {
|
|
|
27153
27593
|
}
|
|
27154
27594
|
var getProjectName = function(cwd) {
|
|
27155
27595
|
try {
|
|
27156
|
-
const packageJsonPath =
|
|
27596
|
+
const packageJsonPath = resolve5(cwd, "package.json");
|
|
27157
27597
|
const packageJson = __require(packageJsonPath);
|
|
27158
27598
|
return packageJson.name || cwd.split("/").pop() || "project";
|
|
27159
27599
|
} catch {
|
|
@@ -27166,7 +27606,7 @@ init_skillsManager();
|
|
|
27166
27606
|
init_agentManager();
|
|
27167
27607
|
async function detectCommand(options2) {
|
|
27168
27608
|
const cwd = process.cwd();
|
|
27169
|
-
logger.
|
|
27609
|
+
logger.titleBox("AgentInit Project Detection");
|
|
27170
27610
|
const spinner = ora("Detecting project configuration...").start();
|
|
27171
27611
|
try {
|
|
27172
27612
|
const agentDetector3 = new AgentDetector;
|
|
@@ -27234,7 +27674,7 @@ import {relative as relative5} from "path";
|
|
|
27234
27674
|
|
|
27235
27675
|
// dist/core/propagator.js
|
|
27236
27676
|
var import_gray_matter3 = __toESM(require_gray_matter(), 1);
|
|
27237
|
-
import {promises as
|
|
27677
|
+
import {promises as fs26} from "fs";
|
|
27238
27678
|
import {resolve as resolve9} from "path";
|
|
27239
27679
|
|
|
27240
27680
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
@@ -30002,7 +30442,7 @@ class Propagator {
|
|
|
30002
30442
|
resolvedTargets: []
|
|
30003
30443
|
};
|
|
30004
30444
|
const exists = await fileExists(generatedFile.path);
|
|
30005
|
-
const existingStats = exists ? await
|
|
30445
|
+
const existingStats = exists ? await fs26.lstat(generatedFile.path).catch(() => null) : null;
|
|
30006
30446
|
const existingContent = exists && !existingStats?.isSymbolicLink() ? await readFileIfExists(generatedFile.path) : null;
|
|
30007
30447
|
const existingTarget = existingStats?.isSymbolicLink() ? await readSymlinkTarget(generatedFile.path) : null;
|
|
30008
30448
|
if (options2.managedState && !options2.dryRun) {
|
|
@@ -30033,7 +30473,7 @@ class Propagator {
|
|
|
30033
30473
|
if (!options2.dryRun) {
|
|
30034
30474
|
if (generatedFile.kind === "file") {
|
|
30035
30475
|
if (existingStats?.isSymbolicLink()) {
|
|
30036
|
-
await
|
|
30476
|
+
await fs26.rm(generatedFile.path, { force: true }).catch(() => {
|
|
30037
30477
|
});
|
|
30038
30478
|
}
|
|
30039
30479
|
await writeFile(generatedFile.path, generatedFile.content || "");
|
|
@@ -30210,14 +30650,14 @@ ${content}
|
|
|
30210
30650
|
|
|
30211
30651
|
// dist/core/managedState.js
|
|
30212
30652
|
init_fs();
|
|
30213
|
-
import {promises as
|
|
30214
|
-
import {dirname as dirname3, join as
|
|
30653
|
+
import {promises as fs28} from "fs";
|
|
30654
|
+
import {dirname as dirname3, join as join6, relative as relative4, resolve as resolve10} from "path";
|
|
30215
30655
|
var toPosixPath = function(value) {
|
|
30216
30656
|
return value.replace(/\\/g, "/");
|
|
30217
30657
|
};
|
|
30218
30658
|
async function pathType(targetPath) {
|
|
30219
30659
|
try {
|
|
30220
|
-
const stat = await
|
|
30660
|
+
const stat = await fs28.lstat(targetPath);
|
|
30221
30661
|
if (stat.isSymbolicLink()) {
|
|
30222
30662
|
return "symlink";
|
|
30223
30663
|
}
|
|
@@ -30227,20 +30667,20 @@ async function pathType(targetPath) {
|
|
|
30227
30667
|
}
|
|
30228
30668
|
}
|
|
30229
30669
|
async function copyDirectory(src, dest) {
|
|
30230
|
-
await
|
|
30231
|
-
const entries = await
|
|
30670
|
+
await fs28.mkdir(dest, { recursive: true });
|
|
30671
|
+
const entries = await fs28.readdir(src, { withFileTypes: true });
|
|
30232
30672
|
for (const entry of entries) {
|
|
30233
|
-
const srcPath =
|
|
30234
|
-
const destPath =
|
|
30673
|
+
const srcPath = join6(src, entry.name);
|
|
30674
|
+
const destPath = join6(dest, entry.name);
|
|
30235
30675
|
if (entry.isDirectory()) {
|
|
30236
30676
|
await copyDirectory(srcPath, destPath);
|
|
30237
30677
|
} else if (entry.isSymbolicLink()) {
|
|
30238
|
-
const target = await
|
|
30239
|
-
await
|
|
30240
|
-
await
|
|
30678
|
+
const target = await fs28.readlink(srcPath);
|
|
30679
|
+
await fs28.mkdir(dirname3(destPath), { recursive: true });
|
|
30680
|
+
await fs28.symlink(target, destPath);
|
|
30241
30681
|
} else {
|
|
30242
|
-
await
|
|
30243
|
-
await
|
|
30682
|
+
await fs28.mkdir(dirname3(destPath), { recursive: true });
|
|
30683
|
+
await fs28.copyFile(srcPath, destPath);
|
|
30244
30684
|
}
|
|
30245
30685
|
}
|
|
30246
30686
|
}
|
|
@@ -30249,14 +30689,14 @@ async function copyPath(src, dest) {
|
|
|
30249
30689
|
if (!type2) {
|
|
30250
30690
|
return;
|
|
30251
30691
|
}
|
|
30252
|
-
await
|
|
30692
|
+
await fs28.mkdir(dirname3(dest), { recursive: true });
|
|
30253
30693
|
if (type2 === "symlink") {
|
|
30254
|
-
const target = await
|
|
30255
|
-
await
|
|
30694
|
+
const target = await fs28.readlink(src);
|
|
30695
|
+
await fs28.symlink(target, dest);
|
|
30256
30696
|
} else if (type2 === "directory") {
|
|
30257
30697
|
await copyDirectory(src, dest);
|
|
30258
30698
|
} else {
|
|
30259
|
-
await
|
|
30699
|
+
await fs28.copyFile(src, dest);
|
|
30260
30700
|
}
|
|
30261
30701
|
}
|
|
30262
30702
|
var MANAGED_STATE_FILE = "managed-state.json";
|
|
@@ -30270,11 +30710,11 @@ class ManagedStateStore {
|
|
|
30270
30710
|
this.state = state;
|
|
30271
30711
|
}
|
|
30272
30712
|
static async open(projectPath) {
|
|
30273
|
-
const agentInitDir =
|
|
30274
|
-
const statePath =
|
|
30713
|
+
const agentInitDir = join6(projectPath, ".agentinit");
|
|
30714
|
+
const statePath = join6(agentInitDir, MANAGED_STATE_FILE);
|
|
30275
30715
|
const emptyState = { version: 1, entries: [] };
|
|
30276
30716
|
try {
|
|
30277
|
-
const raw = await
|
|
30717
|
+
const raw = await fs28.readFile(statePath, "utf8");
|
|
30278
30718
|
const parsed = JSON.parse(raw);
|
|
30279
30719
|
if (!parsed || parsed.version !== 1 || !Array.isArray(parsed.entries)) {
|
|
30280
30720
|
return new ManagedStateStore(projectPath, emptyState);
|
|
@@ -30285,13 +30725,13 @@ class ManagedStateStore {
|
|
|
30285
30725
|
}
|
|
30286
30726
|
}
|
|
30287
30727
|
get agentInitDir() {
|
|
30288
|
-
return
|
|
30728
|
+
return join6(this.projectPath, ".agentinit");
|
|
30289
30729
|
}
|
|
30290
30730
|
get stateFilePath() {
|
|
30291
|
-
return
|
|
30731
|
+
return join6(this.agentInitDir, MANAGED_STATE_FILE);
|
|
30292
30732
|
}
|
|
30293
30733
|
get backupsDir() {
|
|
30294
|
-
return
|
|
30734
|
+
return join6(this.agentInitDir, BACKUPS_DIR);
|
|
30295
30735
|
}
|
|
30296
30736
|
normalizeRelativePath(targetPath, preserveTrailingSlash = false) {
|
|
30297
30737
|
const hasTrailingSlash = preserveTrailingSlash && /[\\/]$/.test(targetPath);
|
|
@@ -30313,14 +30753,14 @@ class ManagedStateStore {
|
|
|
30313
30753
|
}
|
|
30314
30754
|
if (type2 === "symlink") {
|
|
30315
30755
|
try {
|
|
30316
|
-
const backupLinkTarget = await
|
|
30756
|
+
const backupLinkTarget = await fs28.readlink(targetPath);
|
|
30317
30757
|
return { backupLinkTarget };
|
|
30318
30758
|
} catch {
|
|
30319
30759
|
return {};
|
|
30320
30760
|
}
|
|
30321
30761
|
}
|
|
30322
30762
|
const relativeTargetPath = this.normalizeRelativePath(targetPath);
|
|
30323
|
-
const backupPath =
|
|
30763
|
+
const backupPath = join6(this.backupsDir, relativeTargetPath);
|
|
30324
30764
|
if (!await fileExists(backupPath)) {
|
|
30325
30765
|
await copyPath(targetPath, backupPath);
|
|
30326
30766
|
}
|
|
@@ -30355,20 +30795,20 @@ class ManagedStateStore {
|
|
|
30355
30795
|
if (this.state.entries.length === 0) {
|
|
30356
30796
|
return [];
|
|
30357
30797
|
}
|
|
30358
|
-
const
|
|
30798
|
+
const paths5 = new Set([
|
|
30359
30799
|
".agentinit/managed-state.json",
|
|
30360
30800
|
".agentinit/backups/"
|
|
30361
30801
|
]);
|
|
30362
30802
|
for (const entry of this.state.entries) {
|
|
30363
30803
|
if (entry.ignorePath) {
|
|
30364
|
-
|
|
30804
|
+
paths5.add(entry.ignorePath);
|
|
30365
30805
|
}
|
|
30366
30806
|
}
|
|
30367
|
-
return [...
|
|
30807
|
+
return [...paths5];
|
|
30368
30808
|
}
|
|
30369
30809
|
async save() {
|
|
30370
|
-
await
|
|
30371
|
-
await
|
|
30810
|
+
await fs28.mkdir(this.agentInitDir, { recursive: true });
|
|
30811
|
+
await fs28.writeFile(this.stateFilePath, JSON.stringify(this.state, null, 2), "utf8");
|
|
30372
30812
|
}
|
|
30373
30813
|
async revertAll(options2 = {}) {
|
|
30374
30814
|
const summary = {
|
|
@@ -30383,29 +30823,29 @@ class ManagedStateStore {
|
|
|
30383
30823
|
const backupLinkTarget = entry.backupLinkTarget;
|
|
30384
30824
|
if (entry.existedBefore && backupLinkTarget !== undefined) {
|
|
30385
30825
|
if (!options2.dryRun) {
|
|
30386
|
-
await
|
|
30826
|
+
await fs28.rm(absolutePath, { recursive: true, force: true }).catch(() => {
|
|
30387
30827
|
});
|
|
30388
|
-
await
|
|
30389
|
-
await
|
|
30828
|
+
await fs28.mkdir(dirname3(absolutePath), { recursive: true });
|
|
30829
|
+
await fs28.symlink(backupLinkTarget, absolutePath);
|
|
30390
30830
|
}
|
|
30391
30831
|
summary.restored++;
|
|
30392
30832
|
} else if (entry.existedBefore && backupPath && await fileExists(backupPath)) {
|
|
30393
30833
|
if (!options2.dryRun) {
|
|
30394
|
-
await
|
|
30834
|
+
await fs28.rm(absolutePath, { recursive: true, force: true }).catch(() => {
|
|
30395
30835
|
});
|
|
30396
30836
|
await copyPath(backupPath, absolutePath);
|
|
30397
30837
|
}
|
|
30398
30838
|
summary.restored++;
|
|
30399
30839
|
} else {
|
|
30400
30840
|
if (!options2.dryRun) {
|
|
30401
|
-
await
|
|
30841
|
+
await fs28.rm(absolutePath, { recursive: true, force: true }).catch(() => {
|
|
30402
30842
|
});
|
|
30403
30843
|
}
|
|
30404
30844
|
summary.removed++;
|
|
30405
30845
|
}
|
|
30406
30846
|
if (!options2.keepBackups && backupPath && await fileExists(backupPath)) {
|
|
30407
30847
|
if (!options2.dryRun) {
|
|
30408
|
-
await
|
|
30848
|
+
await fs28.rm(backupPath, { recursive: true, force: true }).catch(() => {
|
|
30409
30849
|
});
|
|
30410
30850
|
}
|
|
30411
30851
|
summary.backupsRemoved++;
|
|
@@ -30413,16 +30853,16 @@ class ManagedStateStore {
|
|
|
30413
30853
|
}
|
|
30414
30854
|
if (!options2.dryRun) {
|
|
30415
30855
|
this.state.entries.length = 0;
|
|
30416
|
-
await
|
|
30856
|
+
await fs28.rm(this.stateFilePath, { force: true }).catch(() => {
|
|
30417
30857
|
});
|
|
30418
30858
|
if (!options2.keepBackups) {
|
|
30419
|
-
await
|
|
30859
|
+
await fs28.rm(this.backupsDir, { recursive: true, force: true }).catch(() => {
|
|
30420
30860
|
});
|
|
30421
30861
|
}
|
|
30422
30862
|
try {
|
|
30423
|
-
const remainingEntries = await
|
|
30863
|
+
const remainingEntries = await fs28.readdir(this.agentInitDir);
|
|
30424
30864
|
if (remainingEntries.length === 0) {
|
|
30425
|
-
await
|
|
30865
|
+
await fs28.rm(this.agentInitDir, { recursive: true, force: true });
|
|
30426
30866
|
}
|
|
30427
30867
|
} catch {
|
|
30428
30868
|
}
|
|
@@ -30436,7 +30876,7 @@ init_agentManager();
|
|
|
30436
30876
|
async function syncCommand(options2) {
|
|
30437
30877
|
const cwd = process.cwd();
|
|
30438
30878
|
const agentManager5 = new AgentManager;
|
|
30439
|
-
logger.
|
|
30879
|
+
logger.titleBox("AgentInit Sync");
|
|
30440
30880
|
if (options2.dryRun) {
|
|
30441
30881
|
logger.info("Running in dry-run mode - no files will be modified");
|
|
30442
30882
|
}
|
|
@@ -30765,15 +31205,15 @@ class MCPParser {
|
|
|
30765
31205
|
}
|
|
30766
31206
|
|
|
30767
31207
|
// dist/constants/mcp.js
|
|
30768
|
-
import {readFileSync} from "fs";
|
|
31208
|
+
import {readFileSync as readFileSync2} from "fs";
|
|
30769
31209
|
import {fileURLToPath} from "url";
|
|
30770
|
-
import {dirname as dirname4, join as
|
|
31210
|
+
import {dirname as dirname4, join as join7} from "path";
|
|
30771
31211
|
var getPackageVersion = function() {
|
|
30772
31212
|
try {
|
|
30773
31213
|
const __filename2 = fileURLToPath(import.meta.url);
|
|
30774
31214
|
const __dirname2 = dirname4(__filename2);
|
|
30775
|
-
const packageJsonPath =
|
|
30776
|
-
const packageJson = JSON.parse(
|
|
31215
|
+
const packageJsonPath = join7(__dirname2, "../../package.json");
|
|
31216
|
+
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
30777
31217
|
return packageJson.version || "1.0.0";
|
|
30778
31218
|
} catch {
|
|
30779
31219
|
return "1.0.0";
|
|
@@ -30799,13 +31239,13 @@ var TOKEN_COUNT_THRESHOLDS = {
|
|
|
30799
31239
|
};
|
|
30800
31240
|
// dist/core/rulesParser.js
|
|
30801
31241
|
init_fs();
|
|
30802
|
-
import {readFileSync as
|
|
31242
|
+
import {readFileSync as readFileSync4} from "fs";
|
|
30803
31243
|
|
|
30804
31244
|
// dist/core/rulesTemplateLoader.js
|
|
30805
31245
|
var toml = __toESM(require_toml(), 1);
|
|
30806
31246
|
import {resolve as resolve11, dirname as dirname5} from "path";
|
|
30807
31247
|
import {fileURLToPath as fileURLToPath2} from "url";
|
|
30808
|
-
import {readFileSync as
|
|
31248
|
+
import {readFileSync as readFileSync3, readdirSync, existsSync as existsSync2} from "fs";
|
|
30809
31249
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
30810
31250
|
var __dirname2 = dirname5(__filename2);
|
|
30811
31251
|
|
|
@@ -30817,14 +31257,14 @@ class RulesTemplateLoader {
|
|
|
30817
31257
|
this.loadTemplates();
|
|
30818
31258
|
}
|
|
30819
31259
|
loadTemplates() {
|
|
30820
|
-
if (!
|
|
31260
|
+
if (!existsSync2(this.templatesPath)) {
|
|
30821
31261
|
throw new Error(`Rules templates directory not found: ${this.templatesPath}`);
|
|
30822
31262
|
}
|
|
30823
31263
|
const files = readdirSync(this.templatesPath).filter((file) => file.endsWith(".toml"));
|
|
30824
31264
|
for (const file of files) {
|
|
30825
31265
|
try {
|
|
30826
31266
|
const filePath = resolve11(this.templatesPath, file);
|
|
30827
|
-
const content =
|
|
31267
|
+
const content = readFileSync3(filePath, "utf-8");
|
|
30828
31268
|
const parsed = toml.default.parse(content);
|
|
30829
31269
|
const template = {
|
|
30830
31270
|
id: parsed.template.id,
|
|
@@ -30972,7 +31412,7 @@ class RulesParser {
|
|
|
30972
31412
|
throw new RulesParseError(`Rules file not found: ${filePath}`);
|
|
30973
31413
|
}
|
|
30974
31414
|
try {
|
|
30975
|
-
const content =
|
|
31415
|
+
const content = readFileSync4(filePath, "utf-8");
|
|
30976
31416
|
if (filePath.endsWith(".json")) {
|
|
30977
31417
|
const parsed = JSON.parse(content);
|
|
30978
31418
|
return this.extractRulesFromObject(parsed);
|
|
@@ -38960,7 +39400,7 @@ class MCPVerifier {
|
|
|
38960
39400
|
for (const result of results) {
|
|
38961
39401
|
const { server, status, capabilities, error, connectionTime } = result;
|
|
38962
39402
|
if (status === "success" && capabilities) {
|
|
38963
|
-
output.push(`\
|
|
39403
|
+
output.push(`\u2713 MCP Server: ${server.name} (${server.type.toUpperCase()})`);
|
|
38964
39404
|
output.push(` Status: Connected successfully (${connectionTime}ms)`);
|
|
38965
39405
|
if (capabilities.serverInfo) {
|
|
38966
39406
|
output.push(` Version: ${capabilities.serverInfo.version}`);
|
|
@@ -39010,10 +39450,10 @@ class MCPVerifier {
|
|
|
39010
39450
|
}
|
|
39011
39451
|
}
|
|
39012
39452
|
if (capabilities.tools.length === 0 && capabilities.resources.length === 0 && capabilities.prompts.length === 0) {
|
|
39013
|
-
output.push(` \u26A0
|
|
39453
|
+
output.push(` \u26A0 No tools, resources, or prompts available`);
|
|
39014
39454
|
}
|
|
39015
39455
|
} else {
|
|
39016
|
-
const statusIcon = status === "timeout" ? "\
|
|
39456
|
+
const statusIcon = status === "timeout" ? "\u29D7" : "\u2717";
|
|
39017
39457
|
output.push(`${statusIcon} MCP Server: ${server.name} (${server.type.toUpperCase()})`);
|
|
39018
39458
|
output.push(` Status: ${status === "timeout" ? "Connection timeout" : "Failed"} (${connectionTime || 0}ms)`);
|
|
39019
39459
|
if (error) {
|
|
@@ -39042,8 +39482,8 @@ class MCPVerifier {
|
|
|
39042
39482
|
}
|
|
39043
39483
|
|
|
39044
39484
|
// dist/core/gitignoreManager.js
|
|
39045
|
-
import {promises as
|
|
39046
|
-
import {dirname as dirname6, join as
|
|
39485
|
+
import {promises as fs31} from "fs";
|
|
39486
|
+
import {dirname as dirname6, join as join8} from "path";
|
|
39047
39487
|
var normalizeIgnorePath = function(projectPath, value) {
|
|
39048
39488
|
const relative6 = value.startsWith(projectPath) ? value.slice(projectPath.length + 1) : value;
|
|
39049
39489
|
const normalized = relative6.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
@@ -39089,13 +39529,13 @@ var updateManagedBlock = function(existingContent, entries) {
|
|
|
39089
39529
|
}
|
|
39090
39530
|
return content;
|
|
39091
39531
|
};
|
|
39092
|
-
async function updateManagedIgnoreFile(projectPath,
|
|
39093
|
-
const ignoreFile = options2.local ?
|
|
39094
|
-
const ignoreFilePath =
|
|
39532
|
+
async function updateManagedIgnoreFile(projectPath, paths5, options2 = {}) {
|
|
39533
|
+
const ignoreFile = options2.local ? join8(".git", "info", "exclude") : ".gitignore";
|
|
39534
|
+
const ignoreFilePath = join8(projectPath, ignoreFile);
|
|
39095
39535
|
if (options2.local) {
|
|
39096
|
-
const gitDir =
|
|
39536
|
+
const gitDir = join8(projectPath, ".git");
|
|
39097
39537
|
try {
|
|
39098
|
-
const stat = await
|
|
39538
|
+
const stat = await fs31.stat(gitDir);
|
|
39099
39539
|
if (!stat.isDirectory()) {
|
|
39100
39540
|
throw new Error;
|
|
39101
39541
|
}
|
|
@@ -39103,24 +39543,24 @@ async function updateManagedIgnoreFile(projectPath, paths2, options2 = {}) {
|
|
|
39103
39543
|
throw new Error("Cannot update .git/info/exclude because this project is not a Git repository");
|
|
39104
39544
|
}
|
|
39105
39545
|
}
|
|
39106
|
-
const normalizedPaths = [...new Set(
|
|
39546
|
+
const normalizedPaths = [...new Set(paths5.map((path) => normalizeIgnorePath(projectPath, path)).filter(Boolean))].sort();
|
|
39107
39547
|
let existingContent = "";
|
|
39108
39548
|
try {
|
|
39109
|
-
existingContent = await
|
|
39549
|
+
existingContent = await fs31.readFile(ignoreFilePath, "utf8");
|
|
39110
39550
|
} catch {
|
|
39111
39551
|
existingContent = "";
|
|
39112
39552
|
}
|
|
39113
39553
|
const updatedContent = updateManagedBlock(existingContent, normalizedPaths);
|
|
39114
|
-
await
|
|
39115
|
-
await
|
|
39554
|
+
await fs31.mkdir(dirname6(ignoreFilePath), { recursive: true });
|
|
39555
|
+
await fs31.writeFile(ignoreFilePath, updatedContent, "utf8");
|
|
39116
39556
|
return ignoreFilePath;
|
|
39117
39557
|
}
|
|
39118
39558
|
async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
|
|
39119
|
-
const ignoreFile = options2.local ?
|
|
39120
|
-
const ignoreFilePath =
|
|
39559
|
+
const ignoreFile = options2.local ? join8(".git", "info", "exclude") : ".gitignore";
|
|
39560
|
+
const ignoreFilePath = join8(projectPath, ignoreFile);
|
|
39121
39561
|
let content;
|
|
39122
39562
|
try {
|
|
39123
|
-
content = await
|
|
39563
|
+
content = await fs31.readFile(ignoreFilePath, "utf8");
|
|
39124
39564
|
} catch {
|
|
39125
39565
|
return false;
|
|
39126
39566
|
}
|
|
@@ -39136,13 +39576,13 @@ async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
|
|
|
39136
39576
|
const afterBlock = content.slice(endIndex + END_MARKER.length).replace(/^\n+/, "");
|
|
39137
39577
|
let nextContent = `${beforeBlock}${afterBlock}`.replace(/\n{3,}/g, "\n\n").replace(/^\n+/, "");
|
|
39138
39578
|
if (nextContent.trim() === "") {
|
|
39139
|
-
await
|
|
39579
|
+
await fs31.rm(ignoreFilePath, { force: true }).catch(() => {
|
|
39140
39580
|
});
|
|
39141
39581
|
} else {
|
|
39142
39582
|
if (!nextContent.endsWith("\n")) {
|
|
39143
39583
|
nextContent += "\n";
|
|
39144
39584
|
}
|
|
39145
|
-
await
|
|
39585
|
+
await fs31.writeFile(ignoreFilePath, nextContent, "utf8");
|
|
39146
39586
|
}
|
|
39147
39587
|
return true;
|
|
39148
39588
|
}
|
|
@@ -39153,12 +39593,12 @@ var END_MARKER = "# END AgentInit Generated Files";
|
|
|
39153
39593
|
init_agentManager();
|
|
39154
39594
|
init_skillsManager();
|
|
39155
39595
|
init_fs();
|
|
39156
|
-
import {dirname as dirname7, join as
|
|
39596
|
+
import {dirname as dirname7, join as join9} from "path";
|
|
39157
39597
|
async function discoverProjectSkills(projectPath, skillsManager4) {
|
|
39158
39598
|
const sources = [];
|
|
39159
39599
|
const skills = new Map;
|
|
39160
39600
|
for (const sourceDir of PROJECT_SKILL_SOURCE_DIRS) {
|
|
39161
|
-
const absoluteSourceDir =
|
|
39601
|
+
const absoluteSourceDir = join9(projectPath, sourceDir);
|
|
39162
39602
|
if (!await fileExists(absoluteSourceDir)) {
|
|
39163
39603
|
continue;
|
|
39164
39604
|
}
|
|
@@ -39276,7 +39716,7 @@ async function applyProjectCommand(options2) {
|
|
|
39276
39716
|
const cwd = process.cwd();
|
|
39277
39717
|
const agentManager7 = new AgentManager;
|
|
39278
39718
|
let managedState3 = null;
|
|
39279
|
-
logger.
|
|
39719
|
+
logger.titleBox("AgentInit Apply");
|
|
39280
39720
|
if (options2.dryRun) {
|
|
39281
39721
|
logger.info("Running in dry-run mode - no files will be modified");
|
|
39282
39722
|
}
|
|
@@ -39400,7 +39840,7 @@ async function applyProjectCommand(options2) {
|
|
|
39400
39840
|
}
|
|
39401
39841
|
async function applyCommand(args) {
|
|
39402
39842
|
const cwd = process.cwd();
|
|
39403
|
-
logger.
|
|
39843
|
+
logger.titleBox("AgentInit Apply Configuration");
|
|
39404
39844
|
const hasMcpArgs = args.some((arg) => arg.startsWith("--mcp-"));
|
|
39405
39845
|
const hasRulesArgs = args.some((arg) => arg === "--rules" || arg === "--rule-raw" || arg === "--rules-file" || arg === "--rules-remote");
|
|
39406
39846
|
const clientArgIndex = args.findIndex((arg) => arg === "--client" || arg === "--agent");
|
|
@@ -39805,7 +40245,7 @@ var LEGACY_APPLY_FLAGS = new Set([
|
|
|
39805
40245
|
init_agentManager();
|
|
39806
40246
|
async function verifyMcpCommand(args) {
|
|
39807
40247
|
const cwd = process.cwd();
|
|
39808
|
-
logger.
|
|
40248
|
+
logger.titleBox("AgentInit MCP Verification");
|
|
39809
40249
|
const hasAll = args.includes("--all");
|
|
39810
40250
|
const mcpNameIndex = args.findIndex((arg) => arg === "--mcp-name");
|
|
39811
40251
|
const mcpName = mcpNameIndex >= 0 && mcpNameIndex + 1 < args.length ? args[mcpNameIndex + 1] : null;
|
|
@@ -40009,7 +40449,7 @@ async function verifyMcpCommand(args) {
|
|
|
40009
40449
|
// dist/commands/revert.js
|
|
40010
40450
|
async function revertCommand(options2) {
|
|
40011
40451
|
const cwd = process.cwd();
|
|
40012
|
-
logger.
|
|
40452
|
+
logger.titleBox("AgentInit Revert");
|
|
40013
40453
|
if (options2.dryRun) {
|
|
40014
40454
|
logger.info("Running in dry-run mode - no files will be modified");
|
|
40015
40455
|
}
|
|
@@ -40050,9 +40490,193 @@ async function revertCommand(options2) {
|
|
|
40050
40490
|
}
|
|
40051
40491
|
}
|
|
40052
40492
|
|
|
40493
|
+
// dist/utils/colors.js
|
|
40494
|
+
var colorsEnabled = function() {
|
|
40495
|
+
const env2 = process.env || {};
|
|
40496
|
+
const isTTY2 = !!process.stdout?.isTTY;
|
|
40497
|
+
return !env2.NODE_DISABLE_COLORS && env2.NO_COLOR == null && env2.TERM !== "dumb" && (env2.FORCE_COLOR != null && env2.FORCE_COLOR !== "0" || isTTY2);
|
|
40498
|
+
};
|
|
40499
|
+
function orange(text) {
|
|
40500
|
+
if (!colorsEnabled()) {
|
|
40501
|
+
return text;
|
|
40502
|
+
}
|
|
40503
|
+
return `\x1B[38;5;208m${text}\x1B[39m`;
|
|
40504
|
+
}
|
|
40505
|
+
|
|
40506
|
+
// dist/commands/config.js
|
|
40507
|
+
init_marketplaceRegistry();
|
|
40508
|
+
init_userConfig();
|
|
40509
|
+
var sortConfig = function(config) {
|
|
40510
|
+
config.customMarketplaces.sort((left, right) => left.identifier.localeCompare(right.identifier));
|
|
40511
|
+
config.verifiedGithubRepos.sort((left, right) => left.localeCompare(right));
|
|
40512
|
+
return config;
|
|
40513
|
+
};
|
|
40514
|
+
function registerConfigCommand(program2) {
|
|
40515
|
+
const config = program2.command("config").description("Manage AgentInit user configuration");
|
|
40516
|
+
const marketplaces = config.command("marketplaces").description("Manage configured marketplaces");
|
|
40517
|
+
marketplaces.command("list").description("List built-in and custom marketplaces").action(async () => {
|
|
40518
|
+
logger.titleBox("AgentInit Configuration");
|
|
40519
|
+
logger.section("Marketplaces");
|
|
40520
|
+
const defaultMarketplace = getConfiguredDefaultMarketplaceId();
|
|
40521
|
+
const marketplaceIds = getMarketplaceIds();
|
|
40522
|
+
for (let i = 0;i < marketplaceIds.length; i++) {
|
|
40523
|
+
const identifier = marketplaceIds[i];
|
|
40524
|
+
const marketplace = getMarketplace(identifier);
|
|
40525
|
+
if (!marketplace) {
|
|
40526
|
+
continue;
|
|
40527
|
+
}
|
|
40528
|
+
const flags = [
|
|
40529
|
+
BUILT_IN_MARKETPLACE_IDS.has(identifier) ? "built-in" : "custom",
|
|
40530
|
+
defaultMarketplace === identifier ? "default" : null
|
|
40531
|
+
].filter(Boolean).join(", ");
|
|
40532
|
+
logger.tree(`${cyan(identifier)} ${dim(`[${flags}]`)} ${marketplace.name} ${dim(`-> ${marketplace.repoUrl}`)}`, i === marketplaceIds.length - 1);
|
|
40533
|
+
}
|
|
40534
|
+
if (!defaultMarketplace) {
|
|
40535
|
+
logger.info("No default marketplace configured.");
|
|
40536
|
+
}
|
|
40537
|
+
});
|
|
40538
|
+
marketplaces.command("add <identifier> <repoUrl>").description("Add a custom marketplace").option("--name <displayName>", "Display name for this marketplace").option("--default", "Set this marketplace as the default").action(async (identifierArg, repoUrlArg, options2) => {
|
|
40539
|
+
logger.titleBox("AgentInit Configuration");
|
|
40540
|
+
try {
|
|
40541
|
+
const identifier = normalizeMarketplaceIdentifier(identifierArg);
|
|
40542
|
+
const repoUrl = normalizeMarketplaceRepoUrl(repoUrlArg);
|
|
40543
|
+
const configState = await readUserConfig();
|
|
40544
|
+
if (BUILT_IN_MARKETPLACE_IDS.has(identifier)) {
|
|
40545
|
+
throw new Error(`Marketplace "${identifier}" is built in and cannot be redefined.`);
|
|
40546
|
+
}
|
|
40547
|
+
if (configState.customMarketplaces.some((marketplace) => marketplace.identifier === identifier)) {
|
|
40548
|
+
throw new Error(`Marketplace "${identifier}" already exists.`);
|
|
40549
|
+
}
|
|
40550
|
+
configState.customMarketplaces.push({
|
|
40551
|
+
identifier,
|
|
40552
|
+
name: normalizeMarketplaceName(options2.name, identifier),
|
|
40553
|
+
repoUrl
|
|
40554
|
+
});
|
|
40555
|
+
if (options2.default) {
|
|
40556
|
+
configState.defaultMarketplace = identifier;
|
|
40557
|
+
}
|
|
40558
|
+
await writeUserConfig(sortConfig(configState));
|
|
40559
|
+
logger.success(`Added marketplace ${green(identifier)}.`);
|
|
40560
|
+
logger.info(` ${repoUrl}`);
|
|
40561
|
+
if (options2.default) {
|
|
40562
|
+
logger.info(" Set as the configured default marketplace.");
|
|
40563
|
+
}
|
|
40564
|
+
} catch (error) {
|
|
40565
|
+
logger.error(error instanceof Error ? error.message : "Failed to add marketplace.");
|
|
40566
|
+
}
|
|
40567
|
+
});
|
|
40568
|
+
marketplaces.command("remove <identifier>").description("Remove a custom marketplace").action(async (identifierArg) => {
|
|
40569
|
+
logger.titleBox("AgentInit Configuration");
|
|
40570
|
+
try {
|
|
40571
|
+
const identifier = normalizeMarketplaceIdentifier(identifierArg);
|
|
40572
|
+
if (BUILT_IN_MARKETPLACE_IDS.has(identifier)) {
|
|
40573
|
+
throw new Error(`Marketplace "${identifier}" is built in and cannot be removed.`);
|
|
40574
|
+
}
|
|
40575
|
+
const configState = await readUserConfig();
|
|
40576
|
+
const nextMarketplaces = configState.customMarketplaces.filter((marketplace) => marketplace.identifier !== identifier);
|
|
40577
|
+
if (nextMarketplaces.length === configState.customMarketplaces.length) {
|
|
40578
|
+
throw new Error(`Marketplace "${identifier}" is not configured.`);
|
|
40579
|
+
}
|
|
40580
|
+
configState.customMarketplaces = nextMarketplaces;
|
|
40581
|
+
const clearedDefault = configState.defaultMarketplace === identifier;
|
|
40582
|
+
if (clearedDefault) {
|
|
40583
|
+
delete configState.defaultMarketplace;
|
|
40584
|
+
}
|
|
40585
|
+
await writeUserConfig(sortConfig(configState));
|
|
40586
|
+
logger.success(`Removed marketplace ${green(identifier)}.`);
|
|
40587
|
+
if (clearedDefault) {
|
|
40588
|
+
logger.info(" Cleared the configured default marketplace.");
|
|
40589
|
+
}
|
|
40590
|
+
} catch (error) {
|
|
40591
|
+
logger.error(error instanceof Error ? error.message : "Failed to remove marketplace.");
|
|
40592
|
+
}
|
|
40593
|
+
});
|
|
40594
|
+
marketplaces.command("default <identifier>").description("Set the configured default marketplace").action(async (identifierArg) => {
|
|
40595
|
+
logger.titleBox("AgentInit Configuration");
|
|
40596
|
+
try {
|
|
40597
|
+
const identifier = normalizeMarketplaceIdentifier(identifierArg);
|
|
40598
|
+
if (!getMarketplace(identifier)) {
|
|
40599
|
+
throw new Error(`Unknown marketplace: ${identifier}. Available: ${getMarketplaceIds().join(", ")}`);
|
|
40600
|
+
}
|
|
40601
|
+
const configState = await readUserConfig();
|
|
40602
|
+
configState.defaultMarketplace = identifier;
|
|
40603
|
+
await writeUserConfig(sortConfig(configState));
|
|
40604
|
+
logger.success(`Set ${green(identifier)} as the configured default marketplace.`);
|
|
40605
|
+
} catch (error) {
|
|
40606
|
+
logger.error(error instanceof Error ? error.message : "Failed to set default marketplace.");
|
|
40607
|
+
}
|
|
40608
|
+
});
|
|
40609
|
+
marketplaces.command("clear-default").description("Clear the configured default marketplace").action(async () => {
|
|
40610
|
+
logger.titleBox("AgentInit Configuration");
|
|
40611
|
+
const configState = await readUserConfig();
|
|
40612
|
+
if (!configState.defaultMarketplace) {
|
|
40613
|
+
logger.info("No configured default marketplace to clear.");
|
|
40614
|
+
return;
|
|
40615
|
+
}
|
|
40616
|
+
delete configState.defaultMarketplace;
|
|
40617
|
+
await writeUserConfig(sortConfig(configState));
|
|
40618
|
+
logger.success("Cleared the configured default marketplace.");
|
|
40619
|
+
});
|
|
40620
|
+
const verifiedRepos = config.command("verified-repos").description("Manage exact verified GitHub repositories");
|
|
40621
|
+
verifiedRepos.command("list").description("List verified GitHub repositories").action(async () => {
|
|
40622
|
+
logger.titleBox("AgentInit Configuration");
|
|
40623
|
+
logger.section("Verified GitHub Repos");
|
|
40624
|
+
const configState = await readUserConfig();
|
|
40625
|
+
const entries = [
|
|
40626
|
+
...getBuiltInVerifiedGithubRepos().map((repo) => ({ repo, builtIn: true })),
|
|
40627
|
+
...configState.verifiedGithubRepos.filter((repo) => !BUILT_IN_VERIFIED_REPOS.has(repo)).map((repo) => ({ repo, builtIn: false }))
|
|
40628
|
+
];
|
|
40629
|
+
for (let i = 0;i < entries.length; i++) {
|
|
40630
|
+
const entry = entries[i];
|
|
40631
|
+
logger.tree(`${cyan(entry.repo)} ${dim(entry.builtIn ? "[built-in]" : "[custom]")}`, i === entries.length - 1);
|
|
40632
|
+
}
|
|
40633
|
+
});
|
|
40634
|
+
verifiedRepos.command("add <repo>").description("Add an exact verified GitHub repo in owner/repo form").action(async (repoArg) => {
|
|
40635
|
+
logger.titleBox("AgentInit Configuration");
|
|
40636
|
+
try {
|
|
40637
|
+
const repo = normalizeGitHubRepoRef(repoArg);
|
|
40638
|
+
if (BUILT_IN_VERIFIED_REPOS.has(repo)) {
|
|
40639
|
+
logger.info(`${repo} is already verified by AgentInit.`);
|
|
40640
|
+
return;
|
|
40641
|
+
}
|
|
40642
|
+
const configState = await readUserConfig();
|
|
40643
|
+
if (configState.verifiedGithubRepos.includes(repo)) {
|
|
40644
|
+
logger.info(`${repo} is already configured as verified.`);
|
|
40645
|
+
return;
|
|
40646
|
+
}
|
|
40647
|
+
configState.verifiedGithubRepos.push(repo);
|
|
40648
|
+
await writeUserConfig(sortConfig(configState));
|
|
40649
|
+
logger.success(`Added verified GitHub repo ${green(repo)}.`);
|
|
40650
|
+
} catch (error) {
|
|
40651
|
+
logger.error(error instanceof Error ? error.message : "Failed to add verified repo.");
|
|
40652
|
+
}
|
|
40653
|
+
});
|
|
40654
|
+
verifiedRepos.command("remove <repo>").description("Remove a custom verified GitHub repo").action(async (repoArg) => {
|
|
40655
|
+
logger.titleBox("AgentInit Configuration");
|
|
40656
|
+
try {
|
|
40657
|
+
const repo = normalizeGitHubRepoRef(repoArg);
|
|
40658
|
+
if (BUILT_IN_VERIFIED_REPOS.has(repo)) {
|
|
40659
|
+
throw new Error(`${repo} is built in and cannot be removed.`);
|
|
40660
|
+
}
|
|
40661
|
+
const configState = await readUserConfig();
|
|
40662
|
+
const nextRepos = configState.verifiedGithubRepos.filter((entry) => entry !== repo);
|
|
40663
|
+
if (nextRepos.length === configState.verifiedGithubRepos.length) {
|
|
40664
|
+
throw new Error(`${repo} is not configured as verified.`);
|
|
40665
|
+
}
|
|
40666
|
+
configState.verifiedGithubRepos = nextRepos;
|
|
40667
|
+
await writeUserConfig(sortConfig(configState));
|
|
40668
|
+
logger.success(`Removed verified GitHub repo ${green(repo)}.`);
|
|
40669
|
+
} catch (error) {
|
|
40670
|
+
logger.error(error instanceof Error ? error.message : "Failed to remove verified repo.");
|
|
40671
|
+
}
|
|
40672
|
+
});
|
|
40673
|
+
}
|
|
40674
|
+
var BUILT_IN_MARKETPLACE_IDS = new Set(MARKETPLACES.map((marketplace) => marketplace.id));
|
|
40675
|
+
var BUILT_IN_VERIFIED_REPOS = new Set(getBuiltInVerifiedGithubRepos());
|
|
40676
|
+
|
|
40053
40677
|
// dist/commands/skills.js
|
|
40054
40678
|
var import_prompts2 = __toESM(require_prompts3(), 1);
|
|
40055
|
-
import {homedir as
|
|
40679
|
+
import {homedir as homedir6} from "os";
|
|
40056
40680
|
import {relative as relative7, resolve as resolve12} from "path";
|
|
40057
40681
|
init_skillsManager();
|
|
40058
40682
|
init_marketplaceRegistry();
|
|
@@ -40060,8 +40684,8 @@ init_agentManager();
|
|
|
40060
40684
|
function registerSkillsCommand(program2) {
|
|
40061
40685
|
const marketplaceHelp = getMarketplaceIds().join(", ");
|
|
40062
40686
|
const skills = program2.command("skills").description("Manage agent skills");
|
|
40063
|
-
skills.command("add <source>").description("Add skills from a marketplace, GitHub repo, or local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-g, --global", "Install skills globally").option("-a, --agent <agents...>", "Target specific agent(s)").option("-s, --skill <names...>", "Install only specific skills by name").option("-l, --list", "List available skills from the source without installing").option("--copy", "Copy skill files instead of symlinking").option("-y, --yes", "Skip prompts and auto-detect project agents only").action(async (source, options2) => {
|
|
40064
|
-
logger.
|
|
40687
|
+
skills.command("add <source>").description("Add skills from a marketplace, GitHub repo, or local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-g, --global", "Install skills globally").option("-a, --agent <agents...>", "Target specific agent(s)").option("-s, --skill <names...>", "Install only specific skills by name").option("-l, --list", "List available skills from the source without installing").option("--copy", "Copy skill files instead of symlinking").option("-y, --yes", "Skip prompts and auto-detect project-configured agents only").action(async (source, options2) => {
|
|
40688
|
+
logger.titleBox("AgentInit Skills");
|
|
40065
40689
|
const agentManager9 = new AgentManager;
|
|
40066
40690
|
const skillsManager5 = new SkillsManager(agentManager9);
|
|
40067
40691
|
if (options2.list) {
|
|
@@ -40111,7 +40735,7 @@ function registerSkillsCommand(program2) {
|
|
|
40111
40735
|
}
|
|
40112
40736
|
});
|
|
40113
40737
|
skills.command("list").alias("ls").description("List installed skills").option("-g, --global", "List only global skills").option("-a, --agent <agents...>", "Filter by specific agent(s)").action(async (options2) => {
|
|
40114
|
-
logger.
|
|
40738
|
+
logger.titleBox("AgentInit Skills");
|
|
40115
40739
|
const agentManager9 = new AgentManager;
|
|
40116
40740
|
const skillsManager5 = new SkillsManager(agentManager9);
|
|
40117
40741
|
const installed = await skillsManager5.listInstalled(process.cwd(), {
|
|
@@ -40151,7 +40775,7 @@ function registerSkillsCommand(program2) {
|
|
|
40151
40775
|
}
|
|
40152
40776
|
});
|
|
40153
40777
|
skills.command("remove [names...]").alias("rm").description("Remove installed skills by name").option("-g, --global", "Remove from global scope").option("-a, --agent <agents...>", "Target specific agent(s)").option("-y, --yes", "Skip confirmation prompts").action(async (names, options2) => {
|
|
40154
|
-
logger.
|
|
40778
|
+
logger.titleBox("AgentInit Skills");
|
|
40155
40779
|
if (!names || names.length === 0) {
|
|
40156
40780
|
if (!options2.yes) {
|
|
40157
40781
|
logger.error("Please specify skill name(s) to remove.");
|
|
@@ -40337,7 +40961,7 @@ var prependCanonicalGlobalGroup = function(agentManager9, projectPath, groups) {
|
|
|
40337
40961
|
var formatSkillsDir = function(projectPath, dir) {
|
|
40338
40962
|
const normalizedDir = dir.replace(/\\/g, "/").replace(/\/?$/, "/");
|
|
40339
40963
|
const normalizedProjectPath = projectPath.replace(/\\/g, "/");
|
|
40340
|
-
const normalizedHome =
|
|
40964
|
+
const normalizedHome = homedir6().replace(/\\/g, "/");
|
|
40341
40965
|
if (normalizedDir.startsWith(`${normalizedProjectPath}/`)) {
|
|
40342
40966
|
return `${relative7(projectPath, dir).replace(/\\/g, "/").replace(/\/?$/, "/")}`;
|
|
40343
40967
|
}
|
|
@@ -40348,7 +40972,7 @@ var formatSkillsDir = function(projectPath, dir) {
|
|
|
40348
40972
|
};
|
|
40349
40973
|
var formatPromptPath = function(path) {
|
|
40350
40974
|
const normalizedPath = path.replace(/\\/g, "/").replace(/\/?$/, "/");
|
|
40351
|
-
const normalizedHome =
|
|
40975
|
+
const normalizedHome = homedir6().replace(/\\/g, "/");
|
|
40352
40976
|
if (normalizedPath === `${normalizedHome}/`) {
|
|
40353
40977
|
return "~/";
|
|
40354
40978
|
}
|
|
@@ -40358,7 +40982,7 @@ var formatPromptPath = function(path) {
|
|
|
40358
40982
|
return normalizedPath;
|
|
40359
40983
|
};
|
|
40360
40984
|
var getCanonicalGlobalSkillsDir = function() {
|
|
40361
|
-
return resolve12(
|
|
40985
|
+
return resolve12(homedir6(), ".agents/skills");
|
|
40362
40986
|
};
|
|
40363
40987
|
var getCanonicalGlobalSkillsDisplayPath = function() {
|
|
40364
40988
|
return formatPromptPath(getCanonicalGlobalSkillsDir());
|
|
@@ -41073,7 +41697,7 @@ var buildAppliedRules = function(sections) {
|
|
|
41073
41697
|
function registerRulesCommand(program2) {
|
|
41074
41698
|
const rules = program2.command("rules").description("Manage agent rules");
|
|
41075
41699
|
rules.command("add").description("Add rules to agent configuration").option("-t, --template <templates...>", "Rule templates to apply (comma-separated values accepted)").option("-r, --raw <rules...>", "Raw rule strings").option("-f, --file <path>", "Load rules from a file").option("--remote <url>", "Load rules from a remote URL").option("--auth <token>", "Authentication token for remote rules (Bearer token)").option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Apply rules globally").action(async (options2) => {
|
|
41076
|
-
logger.
|
|
41700
|
+
logger.titleBox("AgentInit Rules");
|
|
41077
41701
|
const cwd = process.cwd();
|
|
41078
41702
|
const isGlobal = !!options2.global;
|
|
41079
41703
|
const templates = [];
|
|
@@ -41201,7 +41825,7 @@ function registerRulesCommand(program2) {
|
|
|
41201
41825
|
}
|
|
41202
41826
|
});
|
|
41203
41827
|
rules.command("list").alias("ls").description("List rules configured for each agent").option("-a, --agent <agents...>", "Filter by specific agent(s)").option("-g, --global", "List global rules").action(async (options2) => {
|
|
41204
|
-
logger.
|
|
41828
|
+
logger.titleBox("AgentInit Rules");
|
|
41205
41829
|
const cwd = process.cwd();
|
|
41206
41830
|
const isGlobal = !!options2.global;
|
|
41207
41831
|
const agentManager11 = new AgentManager;
|
|
@@ -41241,7 +41865,7 @@ function registerRulesCommand(program2) {
|
|
|
41241
41865
|
}
|
|
41242
41866
|
});
|
|
41243
41867
|
rules.command("remove [names...]").alias("rm").description("Remove rule sections by template ID (e.g. git, write_docs)").option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Remove from global rules").action(async (names, options2) => {
|
|
41244
|
-
logger.
|
|
41868
|
+
logger.titleBox("AgentInit Rules");
|
|
41245
41869
|
if (!names || names.length === 0) {
|
|
41246
41870
|
logger.error("Please specify rule section name(s) to remove.");
|
|
41247
41871
|
logger.info("Usage: agentinit rules remove <name...>");
|
|
@@ -41302,11 +41926,12 @@ var import_prompts3 = __toESM(require_prompts3(), 1);
|
|
|
41302
41926
|
import {dirname as dirname8, relative as relative8} from "path";
|
|
41303
41927
|
init_pluginManager();
|
|
41304
41928
|
init_agentManager();
|
|
41929
|
+
init_marketplaceRegistry();
|
|
41305
41930
|
function registerPluginsCommand(program2) {
|
|
41306
41931
|
const marketplaceHelp = new PluginManager().getMarketplaceIds().join(", ");
|
|
41307
41932
|
const plugins = program2.command("plugins").description("Install agent-agnostic plugins from any marketplace or source");
|
|
41308
|
-
plugins.command("install <source>").description("Install a plugin from <marketplace>/<name>, a GitHub repo, or a local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Install globally").option("--copy-skills", "Copy plugin skills instead of using canonical symlink installs").option("-l, --list", "Preview plugin contents without installing").option("-y, --yes", "Skip confirmation prompts, auto-detect
|
|
41309
|
-
logger.
|
|
41933
|
+
plugins.command("install <source>").description("Install a plugin from <marketplace>/<name>, a GitHub repo, or a local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Install globally").option("--copy-skills", "Copy plugin skills instead of using canonical symlink installs").option("-l, --list", "Preview plugin contents without installing").option("-y, --yes", "Skip confirmation prompts, auto-detect project-configured agents").action(async (source, options2) => {
|
|
41934
|
+
logger.titleBox("AgentInit Plugins");
|
|
41310
41935
|
const agentManager12 = new AgentManager;
|
|
41311
41936
|
const pluginManager2 = new PluginManager(agentManager12);
|
|
41312
41937
|
if (options2.list) {
|
|
@@ -41422,16 +42047,16 @@ function registerPluginsCommand(program2) {
|
|
|
41422
42047
|
}
|
|
41423
42048
|
});
|
|
41424
42049
|
plugins.command("search [query]").description("Search marketplace plugins").option("--from <marketplace>", `Which marketplace to search (available: ${marketplaceHelp})`).option("--category <category>", "Filter: official, community").action(async (query, options2) => {
|
|
41425
|
-
logger.
|
|
42050
|
+
logger.titleBox("AgentInit Plugin Search");
|
|
41426
42051
|
const pluginManager2 = new PluginManager;
|
|
41427
|
-
|
|
42052
|
+
const registryId = options2.from || getConfiguredDefaultMarketplaceId();
|
|
42053
|
+
if (!registryId) {
|
|
41428
42054
|
logger.info(`Please specify a marketplace with --from <marketplace>. Available: ${marketplaceHelp}`);
|
|
41429
42055
|
logger.info("Examples:");
|
|
41430
42056
|
logger.info(" agentinit plugins search --from claude");
|
|
41431
42057
|
logger.info(" agentinit plugins search code-review --from claude");
|
|
41432
42058
|
return;
|
|
41433
42059
|
}
|
|
41434
|
-
const registryId = options2.from;
|
|
41435
42060
|
const spinner = ora(`Fetching ${registryId} marketplace...`).start();
|
|
41436
42061
|
try {
|
|
41437
42062
|
const results = await pluginManager2.listMarketplacePlugins(registryId, query, options2.category);
|
|
@@ -41463,7 +42088,7 @@ function registerPluginsCommand(program2) {
|
|
|
41463
42088
|
}
|
|
41464
42089
|
});
|
|
41465
42090
|
plugins.command("list").alias("ls").description("List installed plugins").option("-a, --agent <agents...>", "Filter by specific agent(s)").option("-g, --global", "List global plugins").action(async (options2) => {
|
|
41466
|
-
logger.
|
|
42091
|
+
logger.titleBox("AgentInit Installed Plugins");
|
|
41467
42092
|
const pluginManager2 = new PluginManager;
|
|
41468
42093
|
const installed = await pluginManager2.listPlugins(process.cwd(), {
|
|
41469
42094
|
global: options2.global,
|
|
@@ -41499,7 +42124,7 @@ function registerPluginsCommand(program2) {
|
|
|
41499
42124
|
}
|
|
41500
42125
|
});
|
|
41501
42126
|
plugins.command("remove <name>").alias("rm").description("Remove an installed plugin").option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Remove from global scope").option("-y, --yes", "Skip confirmation prompts").action(async (name, options2) => {
|
|
41502
|
-
logger.
|
|
42127
|
+
logger.titleBox("AgentInit Remove Plugin");
|
|
41503
42128
|
const pluginManager2 = new PluginManager;
|
|
41504
42129
|
const spinner = ora(`Removing plugin "${name}"...`).start();
|
|
41505
42130
|
try {
|
|
@@ -41549,28 +42174,40 @@ var getPortableComponentSummary = function(preview) {
|
|
|
41549
42174
|
return parts.length > 0 ? parts.join(", ") : "No portable components";
|
|
41550
42175
|
};
|
|
41551
42176
|
var getSourceWarnings = function(warnings) {
|
|
41552
|
-
const
|
|
42177
|
+
const items = [];
|
|
41553
42178
|
for (const warning of warnings) {
|
|
41554
42179
|
const missingMatch = warning.match(/^Plugin "(.+)" not found in (.+) marketplace\.$/);
|
|
41555
42180
|
if (missingMatch) {
|
|
41556
|
-
|
|
42181
|
+
items.push({
|
|
42182
|
+
type: "marketplace-miss",
|
|
42183
|
+
text: `${missingMatch[2]} marketplace does not contain "${missingMatch[1]}".`
|
|
42184
|
+
});
|
|
41557
42185
|
continue;
|
|
41558
42186
|
}
|
|
41559
|
-
const fallbackMatch = warning.match(/^Marketplace lookup failed; trying unverified GitHub repository (.+) instead\.$/);
|
|
42187
|
+
const fallbackMatch = warning.match(/^Marketplace lookup failed; trying (verified|unverified) GitHub repository (.+) instead\.$/);
|
|
41560
42188
|
if (fallbackMatch) {
|
|
41561
|
-
|
|
42189
|
+
items.push({
|
|
42190
|
+
type: fallbackMatch[1] === "verified" ? "fallback-verified" : "fallback-unverified",
|
|
42191
|
+
text: `${fallbackMatch[1] === "verified" ? "Verified" : "Unverified"} GitHub repository: ${fallbackMatch[2]}`
|
|
42192
|
+
});
|
|
41562
42193
|
continue;
|
|
41563
42194
|
}
|
|
41564
42195
|
const bundleMatch = warning.match(/^Source "(.+)" is a Claude Code marketplace bundle; using bundled plugin "(.+)"\.$/);
|
|
41565
42196
|
if (bundleMatch) {
|
|
41566
|
-
|
|
41567
|
-
|
|
42197
|
+
items.push({
|
|
42198
|
+
type: "bundle-detected",
|
|
42199
|
+
text: `Claude Code marketplace bundle detected: ${bundleMatch[1]}`
|
|
42200
|
+
});
|
|
42201
|
+
items.push({
|
|
42202
|
+
type: "bundle-using",
|
|
42203
|
+
text: `Using bundled plugin "${bundleMatch[2]}".`
|
|
42204
|
+
});
|
|
41568
42205
|
}
|
|
41569
42206
|
}
|
|
41570
|
-
return
|
|
42207
|
+
return items;
|
|
41571
42208
|
};
|
|
41572
42209
|
var getRemainingWarnings = function(warnings) {
|
|
41573
|
-
return warnings.filter((warning) => !/^Plugin "(.+)" not found in (.+) marketplace\.$/.test(warning) && !/^Marketplace lookup failed; trying unverified GitHub repository (.+) instead\.$/.test(warning) && !/^Source "(.+)" is a Claude Code marketplace bundle; using bundled plugin "(.+)"\.$/.test(warning) && !/^Hooks \(hooks\/\) are Claude Code-specific$/.test(warning) && !/^Agent definitions \(agents\/\) are Claude Code-specific$/.test(warning) && !/^Claude Code-native plugin components detected \((.+)\);/.test(warning) && !/^Claude Code-native plugin components detected \((.+)\), but no Claude Code target was selected; skipped native install\.$/.test(warning) && warning !== "Reload plugins in Claude Code with /reload-plugins to activate native plugin components.");
|
|
42210
|
+
return warnings.filter((warning) => !/^Plugin "(.+)" not found in (.+) marketplace\.$/.test(warning) && !/^Marketplace lookup failed; trying (verified|unverified) GitHub repository (.+) instead\.$/.test(warning) && !/^Source "(.+)" is a Claude Code marketplace bundle; using bundled plugin "(.+)"\.$/.test(warning) && !/^Hooks \(hooks\/\) are Claude Code-specific$/.test(warning) && !/^Agent definitions \(agents\/\) are Claude Code-specific$/.test(warning) && !/^Claude Code-native plugin components detected \((.+)\);/.test(warning) && !/^Claude Code-native plugin components detected \((.+)\), but no Claude Code target was selected; skipped native install\.$/.test(warning) && warning !== "Reload plugins in Claude Code with /reload-plugins to activate native plugin components.");
|
|
41574
42211
|
};
|
|
41575
42212
|
var getNativeCompatibilityWarning = function(previewOrResult) {
|
|
41576
42213
|
if ("nativePreview" in previewOrResult) {
|
|
@@ -41606,33 +42243,67 @@ var renderPluginWarnings = function(previewOrResult, projectPath) {
|
|
|
41606
42243
|
const allWarnings = "nativePreview" in previewOrResult ? previewOrResult.plugin.warnings : previewOrResult.warnings;
|
|
41607
42244
|
const sourceWarnings = getSourceWarnings(previewOrResult.plugin.warnings);
|
|
41608
42245
|
if (sourceWarnings.length > 0) {
|
|
41609
|
-
|
|
41610
|
-
|
|
41611
|
-
for (
|
|
41612
|
-
|
|
42246
|
+
logger.section("Source");
|
|
42247
|
+
const lastIdx = sourceWarnings.length - 1;
|
|
42248
|
+
for (let i = 0;i < sourceWarnings.length; i++) {
|
|
42249
|
+
const item = sourceWarnings[i];
|
|
42250
|
+
const isLast = i === lastIdx;
|
|
42251
|
+
if (item.type === "marketplace-miss") {
|
|
42252
|
+
logger.tree(yellow("\u26A0") + ` ${item.text}`, isLast);
|
|
42253
|
+
} else if (item.type === "fallback-verified") {
|
|
42254
|
+
logger.tree(green("\u2713") + ` ${item.text}`, isLast);
|
|
42255
|
+
} else if (item.type === "fallback-unverified") {
|
|
42256
|
+
logger.tree(yellow("\u26A0") + ` ${item.text}`, isLast);
|
|
42257
|
+
} else if (item.type === "bundle-detected") {
|
|
42258
|
+
logger.tree(orange("\u2713") + ` ${orange(item.text)}`, isLast);
|
|
42259
|
+
} else if (item.type === "bundle-using") {
|
|
42260
|
+
logger.tree(green("\u2713") + ` ${item.text}`, isLast);
|
|
42261
|
+
}
|
|
41613
42262
|
}
|
|
41614
42263
|
}
|
|
41615
42264
|
const nativeWarning = getNativeCompatibilityWarning(previewOrResult);
|
|
41616
42265
|
if (nativeWarning) {
|
|
41617
|
-
|
|
41618
|
-
|
|
41619
|
-
|
|
42266
|
+
logger.section("Compatibility");
|
|
42267
|
+
const lines = [];
|
|
42268
|
+
lines.push({
|
|
42269
|
+
text: orange("\u26A0") + ` ${orange("Claude Code")}-only components detected: ${dim(nativeWarning.features.join(", "))}`,
|
|
42270
|
+
isLast: false
|
|
42271
|
+
});
|
|
41620
42272
|
if (nativeWarning.installPath) {
|
|
41621
|
-
|
|
42273
|
+
lines.push({
|
|
42274
|
+
text: orange("\u2139") + ` ${orange("Claude")} native install path: ${dim(formatPathForDisplay(nativeWarning.installPath, projectPath))}`,
|
|
42275
|
+
isLast: false
|
|
42276
|
+
});
|
|
41622
42277
|
}
|
|
41623
42278
|
if (nativeWarning.skipped) {
|
|
41624
|
-
|
|
42279
|
+
lines.push({
|
|
42280
|
+
text: orange("\u26A0") + ` No ${orange("Claude Code")} target selected. Native installation was skipped.`,
|
|
42281
|
+
isLast: true
|
|
42282
|
+
});
|
|
41625
42283
|
} else {
|
|
41626
|
-
|
|
41627
|
-
|
|
42284
|
+
lines.push({
|
|
42285
|
+
text: cyan("\u2139") + " Non-Claude targets install only the portable skills and MCP servers.",
|
|
42286
|
+
isLast: false
|
|
42287
|
+
});
|
|
42288
|
+
const reloadMsg = "nativePreview" in previewOrResult ? ` If you install to ${orange("Claude Code")}, reload plugins with ${bold("/reload-plugins")} afterward.` : ` Reload plugins in ${orange("Claude Code")} with ${bold("/reload-plugins")} after install.`;
|
|
42289
|
+
lines.push({
|
|
42290
|
+
text: orange("\u2139") + reloadMsg,
|
|
42291
|
+
isLast: true
|
|
42292
|
+
});
|
|
42293
|
+
}
|
|
42294
|
+
if (lines.length > 0) {
|
|
42295
|
+
lines[lines.length - 1].isLast = true;
|
|
42296
|
+
}
|
|
42297
|
+
for (const line of lines) {
|
|
42298
|
+
logger.tree(line.text, line.isLast);
|
|
41628
42299
|
}
|
|
41629
42300
|
}
|
|
41630
42301
|
const otherWarnings = getRemainingWarnings(allWarnings);
|
|
41631
42302
|
if (otherWarnings.length > 0) {
|
|
41632
|
-
|
|
41633
|
-
|
|
41634
|
-
for (
|
|
41635
|
-
logger.
|
|
42303
|
+
logger.section("Warnings");
|
|
42304
|
+
const lastIdx = otherWarnings.length - 1;
|
|
42305
|
+
for (let i = 0;i < otherWarnings.length; i++) {
|
|
42306
|
+
logger.tree(yellow("\u26A0") + ` ${otherWarnings[i]}`, i === lastIdx);
|
|
41636
42307
|
}
|
|
41637
42308
|
}
|
|
41638
42309
|
};
|
|
@@ -41646,34 +42317,55 @@ var renderInstalledComponents = function(result, agentManager12, projectPath) {
|
|
|
41646
42317
|
skillGroups.set(targetDir, existing);
|
|
41647
42318
|
}
|
|
41648
42319
|
if (skillGroups.size > 0) {
|
|
41649
|
-
logger.
|
|
41650
|
-
|
|
41651
|
-
logger.info(` ${getAgentLabel([...data.agents], agentManager12)}: ${green(String(data.skillNames.size))} skill(s) -> ${formatPathForDisplay(targetDir, projectPath)}`);
|
|
41652
|
-
}
|
|
42320
|
+
logger.section("Skills");
|
|
42321
|
+
const entries = [...skillGroups.entries()];
|
|
41653
42322
|
const copiedFallbacks = result.skills.installed.filter((item) => item.symlinkFailed);
|
|
42323
|
+
const totalItems = entries.length + (copiedFallbacks.length > 0 ? 1 : 0);
|
|
42324
|
+
let idx = 0;
|
|
42325
|
+
for (const [targetDir, data] of entries) {
|
|
42326
|
+
idx++;
|
|
42327
|
+
const agentLabel = colorAgentLabel([...data.agents], agentManager12);
|
|
42328
|
+
logger.tree(`${agentLabel}: ${green(String(data.skillNames.size))} skill(s) -> ${dim(formatPathForDisplay(targetDir, projectPath))}`, idx === totalItems);
|
|
42329
|
+
}
|
|
41654
42330
|
if (copiedFallbacks.length > 0) {
|
|
41655
|
-
logger.
|
|
42331
|
+
logger.tree(yellow("\u26A0") + ` Symlink creation failed for ${copiedFallbacks.length} skill install(s); copied the files instead.`, true);
|
|
41656
42332
|
}
|
|
41657
42333
|
}
|
|
41658
42334
|
if (result.mcpServers.applied.length > 0) {
|
|
41659
|
-
logger.
|
|
42335
|
+
logger.section("MCP Servers");
|
|
41660
42336
|
const byAgent = new Map;
|
|
41661
42337
|
for (const item of result.mcpServers.applied) {
|
|
41662
42338
|
const list = byAgent.get(item.agent) || [];
|
|
41663
42339
|
list.push(item.name);
|
|
41664
42340
|
byAgent.set(item.agent, list);
|
|
41665
42341
|
}
|
|
41666
|
-
|
|
41667
|
-
|
|
42342
|
+
const entries = [...byAgent.entries()];
|
|
42343
|
+
for (let i = 0;i < entries.length; i++) {
|
|
42344
|
+
const [agent, servers] = entries[i];
|
|
42345
|
+
const agentName = agentManager12.getAgentById(agent)?.name || agent;
|
|
42346
|
+
const coloredName = isClaudeAgent(agent) ? orange(agentName) : agentName;
|
|
42347
|
+
logger.tree(`${coloredName}: ${cyan(String(servers.length))} server(s) [${servers.join(", ")}]`, i === entries.length - 1);
|
|
41668
42348
|
}
|
|
41669
42349
|
}
|
|
41670
42350
|
if (result.nativePlugins.installed.length > 0) {
|
|
41671
|
-
logger.
|
|
41672
|
-
for (
|
|
41673
|
-
|
|
42351
|
+
logger.section("Native Install");
|
|
42352
|
+
for (let i = 0;i < result.nativePlugins.installed.length; i++) {
|
|
42353
|
+
const nativePlugin = result.nativePlugins.installed[i];
|
|
42354
|
+
const agentName = agentManager12.getAgentById(nativePlugin.agent)?.name || nativePlugin.agent;
|
|
42355
|
+
const coloredName = isClaudeAgent(nativePlugin.agent) ? orange(agentName) : agentName;
|
|
42356
|
+
logger.tree(`${coloredName}: ${dim(formatPathForDisplay(nativePlugin.installPath, projectPath))}`, i === result.nativePlugins.installed.length - 1);
|
|
41674
42357
|
}
|
|
41675
42358
|
}
|
|
41676
42359
|
};
|
|
42360
|
+
var isClaudeAgent = function(agentId) {
|
|
42361
|
+
return agentId === "claude" || agentId.startsWith("claude-");
|
|
42362
|
+
};
|
|
42363
|
+
var colorAgentLabel = function(agentIds, agentManager12) {
|
|
42364
|
+
return agentIds.map((agentId) => {
|
|
42365
|
+
const name = agentManager12.getAgentById(agentId)?.name || agentId;
|
|
42366
|
+
return isClaudeAgent(agentId) ? orange(name) : name;
|
|
42367
|
+
}).join(", ");
|
|
42368
|
+
};
|
|
41677
42369
|
var buildGlobalPluginGroups = function(agentManager12, projectPath) {
|
|
41678
42370
|
const dirToAgents = new Map;
|
|
41679
42371
|
for (const agent of agentManager12.getAllAgents()) {
|
|
@@ -41779,6 +42471,7 @@ registerSkillsCommand(program2);
|
|
|
41779
42471
|
registerMcpCommand(program2);
|
|
41780
42472
|
registerRulesCommand(program2);
|
|
41781
42473
|
registerPluginsCommand(program2);
|
|
42474
|
+
registerConfigCommand(program2);
|
|
41782
42475
|
program2.command("init").description("Initialize agents.md configuration for the current project").option("-f, --force", "Overwrite existing configuration").option("-t, --template <template>", "Use specific template (web, cli, library)").action(initCommand);
|
|
41783
42476
|
program2.command("detect").description("Detect current project stack and existing agent configurations").option("-v, --verbose", "Show detailed detection results").action(detectCommand);
|
|
41784
42477
|
program2.command("sync").description("Sync agents.md with agent-specific configuration files").option("-a, --agent <agents...>", "Target specific agent(s)").option("-d, --dry-run", "Show what would be changed without making changes").option("-b, --backup", "Create backup before syncing").action(syncCommand);
|