agentinit 1.12.1 → 1.13.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 +14 -0
- package/README.md +11 -1
- package/dist/cli.js +546 -166
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +15 -2
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +93 -88
- package/dist/commands/skills.js.map +1 -1
- package/dist/core/marketplaceRegistry.d.ts.map +1 -1
- package/dist/core/marketplaceRegistry.js +7 -0
- package/dist/core/marketplaceRegistry.js.map +1 -1
- package/dist/core/pluginManager.d.ts +27 -0
- package/dist/core/pluginManager.d.ts.map +1 -1
- package/dist/core/pluginManager.js +376 -20
- package/dist/core/pluginManager.js.map +1 -1
- package/dist/core/skillsManager.d.ts +1 -0
- package/dist/core/skillsManager.d.ts.map +1 -1
- package/dist/core/skillsManager.js +35 -6
- package/dist/core/skillsManager.js.map +1 -1
- package/dist/types/plugins.d.ts +13 -0
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -16807,6 +16807,13 @@ var init_marketplaceRegistry = __esm(() => {
|
|
|
16807
16807
|
repoUrl: "https://github.com/anthropics/claude-plugins-official.git",
|
|
16808
16808
|
pluginDirs: ["plugins", "external_plugins"],
|
|
16809
16809
|
cacheTtlMs: 3600000
|
|
16810
|
+
},
|
|
16811
|
+
{
|
|
16812
|
+
id: "openai",
|
|
16813
|
+
name: "OpenAI Skills",
|
|
16814
|
+
repoUrl: "https://github.com/openai/skills.git",
|
|
16815
|
+
pluginDirs: ["skills/.curated", "skills/.system", "skills/.experimental"],
|
|
16816
|
+
cacheTtlMs: 3600000
|
|
16810
16817
|
}
|
|
16811
16818
|
];
|
|
16812
16819
|
});
|
|
@@ -16913,12 +16920,36 @@ __export(exports_pluginManager, {
|
|
|
16913
16920
|
{
|
|
16914
16921
|
return PluginManager;
|
|
16915
16922
|
}
|
|
16923
|
+
},
|
|
16924
|
+
MarketplacePluginNotFoundError: () => {
|
|
16925
|
+
{
|
|
16926
|
+
return MarketplacePluginNotFoundError;
|
|
16927
|
+
}
|
|
16916
16928
|
}
|
|
16917
16929
|
});
|
|
16918
|
-
import {resolve as resolve7, join as join3, basename as basename2} from "path";
|
|
16930
|
+
import {resolve as resolve7, join as join3, basename as basename2, relative as relative2, dirname as dirname2} from "path";
|
|
16919
16931
|
import {promises as fs18} from "fs";
|
|
16920
16932
|
import {homedir as homedir3} from "os";
|
|
16921
16933
|
|
|
16934
|
+
class MarketplacePluginNotFoundError extends Error {
|
|
16935
|
+
pluginName;
|
|
16936
|
+
marketplaceId;
|
|
16937
|
+
marketplaceName;
|
|
16938
|
+
suggestions;
|
|
16939
|
+
constructor(pluginName, marketplaceId, marketplaceName, suggestions) {
|
|
16940
|
+
let msg = `Plugin "${pluginName}" not found in ${marketplaceName} marketplace.`;
|
|
16941
|
+
if (suggestions.length > 0) {
|
|
16942
|
+
msg += ` Did you mean: ${suggestions.join(", ")}?`;
|
|
16943
|
+
}
|
|
16944
|
+
super(msg);
|
|
16945
|
+
this.name = "MarketplacePluginNotFoundError";
|
|
16946
|
+
this.pluginName = pluginName;
|
|
16947
|
+
this.marketplaceId = marketplaceId;
|
|
16948
|
+
this.marketplaceName = marketplaceName;
|
|
16949
|
+
this.suggestions = suggestions;
|
|
16950
|
+
}
|
|
16951
|
+
}
|
|
16952
|
+
|
|
16922
16953
|
class PluginManager {
|
|
16923
16954
|
agentManager;
|
|
16924
16955
|
skillsManager;
|
|
@@ -16926,6 +16957,245 @@ class PluginManager {
|
|
|
16926
16957
|
this.agentManager = agentManager2 || new AgentManager;
|
|
16927
16958
|
this.skillsManager = new SkillsManager(this.agentManager);
|
|
16928
16959
|
}
|
|
16960
|
+
parseGitHubRepo(url) {
|
|
16961
|
+
const normalized = url.replace(/\.git$/, "");
|
|
16962
|
+
const match = normalized.match(/github\.com[:/]([^/]+)\/([^/]+)/i);
|
|
16963
|
+
if (!match) {
|
|
16964
|
+
return null;
|
|
16965
|
+
}
|
|
16966
|
+
const [, owner, repo] = match;
|
|
16967
|
+
if (!owner || !repo) {
|
|
16968
|
+
return null;
|
|
16969
|
+
}
|
|
16970
|
+
return {
|
|
16971
|
+
owner,
|
|
16972
|
+
repo
|
|
16973
|
+
};
|
|
16974
|
+
}
|
|
16975
|
+
deriveGitHubFallbackSource(source, marketplaceId) {
|
|
16976
|
+
const repoShorthandMatch = source.match(/^([a-zA-Z0-9._-]+)\/([a-zA-Z0-9._-]+)$/);
|
|
16977
|
+
if (repoShorthandMatch) {
|
|
16978
|
+
const [, owner, repo] = repoShorthandMatch;
|
|
16979
|
+
return {
|
|
16980
|
+
type: "github",
|
|
16981
|
+
url: `https://github.com/${owner}/${repo}.git`,
|
|
16982
|
+
owner,
|
|
16983
|
+
repo
|
|
16984
|
+
};
|
|
16985
|
+
}
|
|
16986
|
+
if (!marketplaceId || !/^[a-zA-Z0-9._-]+$/.test(source)) {
|
|
16987
|
+
return null;
|
|
16988
|
+
}
|
|
16989
|
+
const registry = this.getMarketplace(marketplaceId);
|
|
16990
|
+
const registryRepo = registry ? this.parseGitHubRepo(registry.repoUrl) : null;
|
|
16991
|
+
if (!registryRepo) {
|
|
16992
|
+
return null;
|
|
16993
|
+
}
|
|
16994
|
+
return {
|
|
16995
|
+
type: "github",
|
|
16996
|
+
url: `https://github.com/${registryRepo.owner}/${source}.git`,
|
|
16997
|
+
owner: registryRepo.owner,
|
|
16998
|
+
repo: source
|
|
16999
|
+
};
|
|
17000
|
+
}
|
|
17001
|
+
formatGitHubRepoUrl(source) {
|
|
17002
|
+
if (!source.owner || !source.repo) {
|
|
17003
|
+
return null;
|
|
17004
|
+
}
|
|
17005
|
+
return `https://github.com/${source.owner}/${source.repo}`;
|
|
17006
|
+
}
|
|
17007
|
+
async resolvePreparedPluginDir(pluginDir, source) {
|
|
17008
|
+
const claudeMarketplaceManifestPath = join3(pluginDir, ".claude-plugin", "marketplace.json");
|
|
17009
|
+
if (!await fileExists(claudeMarketplaceManifestPath)) {
|
|
17010
|
+
return { pluginDir, warnings: [] };
|
|
17011
|
+
}
|
|
17012
|
+
const manifestContent = await readFileIfExists(claudeMarketplaceManifestPath);
|
|
17013
|
+
if (!manifestContent) {
|
|
17014
|
+
return { pluginDir, warnings: [] };
|
|
17015
|
+
}
|
|
17016
|
+
let manifest;
|
|
17017
|
+
try {
|
|
17018
|
+
manifest = JSON.parse(manifestContent);
|
|
17019
|
+
} catch {
|
|
17020
|
+
throw new Error(`Invalid .claude-plugin/marketplace.json in ${pluginDir}`);
|
|
17021
|
+
}
|
|
17022
|
+
const entries = Array.isArray(manifest.plugins) ? manifest.plugins.filter((entry) => typeof entry?.name === "string" && typeof entry?.source === "string") : [];
|
|
17023
|
+
if (entries.length === 0) {
|
|
17024
|
+
throw new Error(`No plugins declared in .claude-plugin/marketplace.json for ${pluginDir}`);
|
|
17025
|
+
}
|
|
17026
|
+
const [firstEntry] = entries;
|
|
17027
|
+
if (!firstEntry) {
|
|
17028
|
+
throw new Error(`No plugins declared in .claude-plugin/marketplace.json for ${pluginDir}`);
|
|
17029
|
+
}
|
|
17030
|
+
let selectedEntry = firstEntry;
|
|
17031
|
+
if (entries.length > 1) {
|
|
17032
|
+
const candidates = new Set([source.pluginName, source.repo].filter((value) => !!value).flatMap((value) => [value, basename2(value)]));
|
|
17033
|
+
const matched = entries.find((entry) => candidates.has(entry.name) || candidates.has(basename2(entry.source)));
|
|
17034
|
+
if (!matched) {
|
|
17035
|
+
throw new Error(`Repository "${pluginDir}" is a Claude marketplace bundle with multiple plugins. Select one of: ${entries.map((entry) => entry.name).join(", ")}.`);
|
|
17036
|
+
}
|
|
17037
|
+
selectedEntry = matched;
|
|
17038
|
+
}
|
|
17039
|
+
const selectedPluginDir = resolve7(pluginDir, selectedEntry.source);
|
|
17040
|
+
const relativePath = relative2(resolve7(pluginDir), selectedPluginDir);
|
|
17041
|
+
if (relativePath.startsWith("..") || relativePath.includes("/../") || relativePath.includes("\\..\\")) {
|
|
17042
|
+
throw new Error(`Invalid bundled plugin source path "${selectedEntry.source}" in ${claudeMarketplaceManifestPath}`);
|
|
17043
|
+
}
|
|
17044
|
+
if (!await isDirectory(selectedPluginDir)) {
|
|
17045
|
+
throw new Error(`Bundled plugin path not found: ${selectedPluginDir}`);
|
|
17046
|
+
}
|
|
17047
|
+
const sourceLabel = this.formatGitHubRepoUrl(source) || pluginDir;
|
|
17048
|
+
return {
|
|
17049
|
+
pluginDir: selectedPluginDir,
|
|
17050
|
+
warnings: [
|
|
17051
|
+
`Source "${sourceLabel}" is a Claude Code marketplace bundle; using bundled plugin "${selectedEntry.name}".`
|
|
17052
|
+
],
|
|
17053
|
+
claudeBundle: {
|
|
17054
|
+
bundleName: manifest.name || selectedEntry.name,
|
|
17055
|
+
pluginName: selectedEntry.name
|
|
17056
|
+
}
|
|
17057
|
+
};
|
|
17058
|
+
}
|
|
17059
|
+
async loadPluginFromDirectory(pluginDir, source, warnings = []) {
|
|
17060
|
+
const preparedPlugin = await this.resolvePreparedPluginDir(pluginDir, source);
|
|
17061
|
+
const parsedPlugin = await this.parsePlugin(preparedPlugin.pluginDir, source);
|
|
17062
|
+
return {
|
|
17063
|
+
...parsedPlugin,
|
|
17064
|
+
warnings: [...warnings, ...preparedPlugin.warnings, ...parsedPlugin.warnings],
|
|
17065
|
+
resolvedPluginDir: preparedPlugin.pluginDir,
|
|
17066
|
+
...preparedPlugin.claudeBundle ? { nativeClaudeBundle: preparedPlugin.claudeBundle } : {}
|
|
17067
|
+
};
|
|
17068
|
+
}
|
|
17069
|
+
slugifyPluginNamespace(value) {
|
|
17070
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "plugin";
|
|
17071
|
+
}
|
|
17072
|
+
async getClaudeNativeFeatureKinds(pluginDir, manifest) {
|
|
17073
|
+
const featureChecks = await Promise.all([
|
|
17074
|
+
(async () => !!manifest.commands || await isDirectory(join3(pluginDir, "commands")))(),
|
|
17075
|
+
(async () => !!manifest.hooks || await isDirectory(join3(pluginDir, "hooks")))(),
|
|
17076
|
+
(async () => !!manifest.agents || await isDirectory(join3(pluginDir, "agents")))(),
|
|
17077
|
+
isDirectory(join3(pluginDir, "prompts")),
|
|
17078
|
+
isDirectory(join3(pluginDir, "schemas")),
|
|
17079
|
+
isDirectory(join3(pluginDir, "scripts")),
|
|
17080
|
+
isDirectory(join3(pluginDir, "templates"))
|
|
17081
|
+
]);
|
|
17082
|
+
return [
|
|
17083
|
+
...featureChecks[0] ? ["commands"] : [],
|
|
17084
|
+
...featureChecks[1] ? ["hooks"] : [],
|
|
17085
|
+
...featureChecks[2] ? ["agents"] : [],
|
|
17086
|
+
...featureChecks[3] ? ["prompts"] : [],
|
|
17087
|
+
...featureChecks[4] ? ["schemas"] : [],
|
|
17088
|
+
...featureChecks[5] ? ["scripts"] : [],
|
|
17089
|
+
...featureChecks[6] ? ["templates"] : []
|
|
17090
|
+
];
|
|
17091
|
+
}
|
|
17092
|
+
async getClaudeNativeInstallTarget(plugin, pluginDir) {
|
|
17093
|
+
if (plugin.format !== "claude") {
|
|
17094
|
+
return null;
|
|
17095
|
+
}
|
|
17096
|
+
const manifestContent = await readFileIfExists(join3(pluginDir, ".claude-plugin", "plugin.json"));
|
|
17097
|
+
if (!manifestContent) {
|
|
17098
|
+
return null;
|
|
17099
|
+
}
|
|
17100
|
+
let manifest;
|
|
17101
|
+
try {
|
|
17102
|
+
manifest = JSON.parse(manifestContent);
|
|
17103
|
+
} catch {
|
|
17104
|
+
return null;
|
|
17105
|
+
}
|
|
17106
|
+
const features = await this.getClaudeNativeFeatureKinds(pluginDir, manifest);
|
|
17107
|
+
if (features.length === 0) {
|
|
17108
|
+
return null;
|
|
17109
|
+
}
|
|
17110
|
+
const baseNamespace = plugin.nativeClaudeBundle?.bundleName || plugin.source.marketplace || (plugin.source.owner && plugin.source.repo ? `${plugin.source.owner}-${plugin.source.repo}` : plugin.name);
|
|
17111
|
+
const namespace = `agentinit-${this.slugifyPluginNamespace(baseNamespace)}`;
|
|
17112
|
+
const versionDir = this.slugifyPluginNamespace(plugin.version || "0.0.0");
|
|
17113
|
+
return {
|
|
17114
|
+
namespace,
|
|
17115
|
+
pluginKey: `${plugin.name}@${namespace}`,
|
|
17116
|
+
installPath: join3(homedir3(), ".claude", "plugins", "cache", namespace, plugin.name, versionDir),
|
|
17117
|
+
features
|
|
17118
|
+
};
|
|
17119
|
+
}
|
|
17120
|
+
async readClaudeInstalledPlugins() {
|
|
17121
|
+
const path = getClaudeInstalledPluginsPath();
|
|
17122
|
+
const content = await readFileIfExists(path);
|
|
17123
|
+
if (!content) {
|
|
17124
|
+
return { version: 2, plugins: {} };
|
|
17125
|
+
}
|
|
17126
|
+
try {
|
|
17127
|
+
const parsed = JSON.parse(content);
|
|
17128
|
+
if (!parsed || parsed.version !== 2 || typeof parsed.plugins !== "object" || parsed.plugins === null) {
|
|
17129
|
+
return { version: 2, plugins: {} };
|
|
17130
|
+
}
|
|
17131
|
+
return parsed;
|
|
17132
|
+
} catch {
|
|
17133
|
+
return { version: 2, plugins: {} };
|
|
17134
|
+
}
|
|
17135
|
+
}
|
|
17136
|
+
async saveClaudeInstalledPlugins(state) {
|
|
17137
|
+
await writeFile(getClaudeInstalledPluginsPath(), JSON.stringify(state, null, 2));
|
|
17138
|
+
}
|
|
17139
|
+
async installNativeClaudePlugin(plugin, pluginDir, agents) {
|
|
17140
|
+
const installed = [];
|
|
17141
|
+
const skipped = [];
|
|
17142
|
+
const warnings = [];
|
|
17143
|
+
const nativeTarget = await this.getClaudeNativeInstallTarget(plugin, pluginDir);
|
|
17144
|
+
if (!nativeTarget) {
|
|
17145
|
+
return { installed, skipped, warnings };
|
|
17146
|
+
}
|
|
17147
|
+
const hasClaudeTarget = agents.some((agent) => agent.id === "claude");
|
|
17148
|
+
const featureLabel = nativeTarget.features.join(", ");
|
|
17149
|
+
if (!hasClaudeTarget) {
|
|
17150
|
+
warnings.push(`Claude Code-native plugin components detected (${featureLabel}), but no Claude Code target was selected; skipped native install.`);
|
|
17151
|
+
return { installed, skipped, warnings };
|
|
17152
|
+
}
|
|
17153
|
+
warnings.push(`Claude Code-native plugin components detected (${featureLabel}); they will only work in Claude Code and install into ~/.claude/plugins.`);
|
|
17154
|
+
const claudeInstalled = await this.readClaudeInstalledPlugins();
|
|
17155
|
+
const conflictingKey = Object.keys(claudeInstalled.plugins).find((key) => key !== nativeTarget.pluginKey && key.startsWith(`${plugin.name}@`));
|
|
17156
|
+
if (conflictingKey) {
|
|
17157
|
+
skipped.push({
|
|
17158
|
+
agent: "claude",
|
|
17159
|
+
reason: `Claude plugin "${plugin.name}" is already installed as ${conflictingKey}; skipped native install to avoid duplicates.`
|
|
17160
|
+
});
|
|
17161
|
+
warnings.push(`Skipped native Claude plugin install because Claude already has "${plugin.name}" installed as ${conflictingKey}.`);
|
|
17162
|
+
return { installed, skipped, warnings };
|
|
17163
|
+
}
|
|
17164
|
+
await fs18.rm(nativeTarget.installPath, { recursive: true, force: true }).catch(() => {
|
|
17165
|
+
});
|
|
17166
|
+
await fs18.mkdir(dirname2(nativeTarget.installPath), { recursive: true });
|
|
17167
|
+
await fs18.cp(pluginDir, nativeTarget.installPath, { recursive: true, dereference: true });
|
|
17168
|
+
const now = new Date().toISOString();
|
|
17169
|
+
claudeInstalled.plugins[nativeTarget.pluginKey] = [{
|
|
17170
|
+
scope: "user",
|
|
17171
|
+
installPath: nativeTarget.installPath,
|
|
17172
|
+
version: plugin.version,
|
|
17173
|
+
installedAt: now,
|
|
17174
|
+
lastUpdated: now
|
|
17175
|
+
}];
|
|
17176
|
+
await this.saveClaudeInstalledPlugins(claudeInstalled);
|
|
17177
|
+
installed.push({
|
|
17178
|
+
agent: "claude",
|
|
17179
|
+
pluginKey: nativeTarget.pluginKey,
|
|
17180
|
+
installPath: nativeTarget.installPath
|
|
17181
|
+
});
|
|
17182
|
+
warnings.push("Reload plugins in Claude Code with /reload-plugins to activate native plugin components.");
|
|
17183
|
+
return { installed, skipped, warnings };
|
|
17184
|
+
}
|
|
17185
|
+
async removeNativeClaudePlugin(component) {
|
|
17186
|
+
const claudeInstalled = await this.readClaudeInstalledPlugins();
|
|
17187
|
+
const entries = claudeInstalled.plugins[component.pluginKey] || [];
|
|
17188
|
+
const remainingEntries = entries.filter((entry) => entry.installPath !== component.installPath);
|
|
17189
|
+
if (remainingEntries.length > 0) {
|
|
17190
|
+
claudeInstalled.plugins[component.pluginKey] = remainingEntries;
|
|
17191
|
+
} else {
|
|
17192
|
+
delete claudeInstalled.plugins[component.pluginKey];
|
|
17193
|
+
}
|
|
17194
|
+
await this.saveClaudeInstalledPlugins(claudeInstalled);
|
|
17195
|
+
await fs18.rm(component.installPath, { recursive: true, force: true }).catch(() => {
|
|
17196
|
+
});
|
|
17197
|
+
return true;
|
|
17198
|
+
}
|
|
16929
17199
|
resolveSource(source, options2) {
|
|
16930
17200
|
if (source.startsWith(".") || source.startsWith("/") || source.startsWith("~")) {
|
|
16931
17201
|
return { type: "local", path: source };
|
|
@@ -17045,11 +17315,7 @@ class PluginManager {
|
|
|
17045
17315
|
}
|
|
17046
17316
|
const available = await this.listMarketplacePlugins(registryId);
|
|
17047
17317
|
const suggestions = available.filter((p) => p.name.includes(name) || name.includes(p.name)).map((p) => p.name).slice(0, 5);
|
|
17048
|
-
|
|
17049
|
-
if (suggestions.length > 0) {
|
|
17050
|
-
msg += ` Did you mean: ${suggestions.join(", ")}?`;
|
|
17051
|
-
}
|
|
17052
|
-
throw new Error(msg);
|
|
17318
|
+
throw new MarketplacePluginNotFoundError(name, registryId, registry.name, suggestions);
|
|
17053
17319
|
}
|
|
17054
17320
|
async listMarketplacePlugins(registryId, query, category) {
|
|
17055
17321
|
const registry = this.getMarketplace(registryId);
|
|
@@ -17061,7 +17327,7 @@ class PluginManager {
|
|
|
17061
17327
|
const fullDir = join3(cacheDir, dir);
|
|
17062
17328
|
if (!await isDirectory(fullDir))
|
|
17063
17329
|
continue;
|
|
17064
|
-
const cat = dir === "plugins" ? "official" : dir === "external_plugins" ? "community" : dir;
|
|
17330
|
+
const cat = dir === "plugins" ? "official" : dir === "external_plugins" ? "community" : dir.startsWith("skills/.") ? dir.slice("skills/.".length) : dir;
|
|
17065
17331
|
if (category && cat !== category)
|
|
17066
17332
|
continue;
|
|
17067
17333
|
const entries = await listFiles(fullDir);
|
|
@@ -17152,10 +17418,10 @@ class PluginManager {
|
|
|
17152
17418
|
skills.push(...convertedSkills);
|
|
17153
17419
|
const mcpServers = await this.parseMcpJson(pluginDir);
|
|
17154
17420
|
if (await isDirectory(join3(pluginDir, "hooks")) || manifest.hooks) {
|
|
17155
|
-
warnings.push("Hooks (hooks/) are Claude Code-specific
|
|
17421
|
+
warnings.push("Hooks (hooks/) are Claude Code-specific");
|
|
17156
17422
|
}
|
|
17157
17423
|
if (await isDirectory(join3(pluginDir, "agents")) || manifest.agents) {
|
|
17158
|
-
warnings.push("Agent definitions (agents/) are Claude Code-specific
|
|
17424
|
+
warnings.push("Agent definitions (agents/) are Claude Code-specific");
|
|
17159
17425
|
}
|
|
17160
17426
|
return {
|
|
17161
17427
|
name: manifest.name,
|
|
@@ -17307,10 +17573,35 @@ ${body.trim()}
|
|
|
17307
17573
|
}
|
|
17308
17574
|
async installPlugin(source, projectPath, options2 = {}) {
|
|
17309
17575
|
const resolved = this.resolveSource(source, { from: options2.from });
|
|
17576
|
+
let effectiveSource = resolved;
|
|
17310
17577
|
let pluginDir;
|
|
17311
17578
|
let tempDir = null;
|
|
17579
|
+
const resolutionWarnings = [];
|
|
17312
17580
|
if (resolved.type === "marketplace") {
|
|
17313
|
-
|
|
17581
|
+
try {
|
|
17582
|
+
pluginDir = await this.resolveMarketplacePlugin(resolved.pluginName, resolved.marketplace || "claude");
|
|
17583
|
+
} catch (error) {
|
|
17584
|
+
if (!(error instanceof MarketplacePluginNotFoundError)) {
|
|
17585
|
+
throw error;
|
|
17586
|
+
}
|
|
17587
|
+
const fallbackSource = this.deriveGitHubFallbackSource(source, resolved.marketplace);
|
|
17588
|
+
if (!fallbackSource || !fallbackSource.url) {
|
|
17589
|
+
throw error;
|
|
17590
|
+
}
|
|
17591
|
+
const fallbackUrl = this.formatGitHubRepoUrl(fallbackSource) || fallbackSource.url.replace(/\.git$/, "");
|
|
17592
|
+
resolutionWarnings.push(error.message);
|
|
17593
|
+
resolutionWarnings.push(`Marketplace lookup failed; trying unverified GitHub repository ${fallbackUrl} instead.`);
|
|
17594
|
+
try {
|
|
17595
|
+
tempDir = await this.skillsManager.cloneRepo(fallbackSource.url);
|
|
17596
|
+
} catch (fallbackError) {
|
|
17597
|
+
throw new Error(`${error.message} Tried unverified GitHub repository ${fallbackUrl} but failed: ${fallbackError instanceof Error ? fallbackError.message : "Unknown error"}`);
|
|
17598
|
+
}
|
|
17599
|
+
effectiveSource = {
|
|
17600
|
+
...fallbackSource,
|
|
17601
|
+
...resolved.pluginName ? { pluginName: resolved.pluginName } : {}
|
|
17602
|
+
};
|
|
17603
|
+
pluginDir = tempDir;
|
|
17604
|
+
}
|
|
17314
17605
|
} else if (resolved.type === "github") {
|
|
17315
17606
|
if (!resolved.url)
|
|
17316
17607
|
throw new Error(`Invalid source: ${source}`);
|
|
@@ -17323,12 +17614,13 @@ ${body.trim()}
|
|
|
17323
17614
|
}
|
|
17324
17615
|
}
|
|
17325
17616
|
try {
|
|
17326
|
-
const plugin = await this.
|
|
17617
|
+
const plugin = await this.loadPluginFromDirectory(pluginDir, effectiveSource, resolutionWarnings);
|
|
17327
17618
|
if (options2.list) {
|
|
17328
17619
|
return {
|
|
17329
17620
|
plugin,
|
|
17330
17621
|
skills: { installed: [], skipped: [] },
|
|
17331
17622
|
mcpServers: { applied: [], skipped: [] },
|
|
17623
|
+
nativePlugins: { installed: [], skipped: [] },
|
|
17332
17624
|
warnings: plugin.warnings
|
|
17333
17625
|
};
|
|
17334
17626
|
}
|
|
@@ -17338,25 +17630,29 @@ ${body.trim()}
|
|
|
17338
17630
|
plugin,
|
|
17339
17631
|
skills: { installed: [], skipped: plugin.skills.map((s) => ({ name: s.name, reason: "No target agents found" })) },
|
|
17340
17632
|
mcpServers: { applied: [], skipped: plugin.mcpServers.map((s) => ({ name: s.name, reason: "No target agents found" })) },
|
|
17633
|
+
nativePlugins: { installed: [], skipped: [] },
|
|
17341
17634
|
warnings: plugin.warnings
|
|
17342
17635
|
};
|
|
17343
17636
|
}
|
|
17344
17637
|
const skillResult = await this.installPluginSkills(plugin, projectPath, agents, options2);
|
|
17345
17638
|
const mcpResult = await this.applyPluginMcpServers(plugin, projectPath, agents, options2.global);
|
|
17346
|
-
|
|
17639
|
+
const nativePluginResult = await this.installNativeClaudePlugin(plugin, plugin.resolvedPluginDir, agents);
|
|
17640
|
+
const installWarnings = [...plugin.warnings, ...nativePluginResult.warnings];
|
|
17641
|
+
if (skillResult.installed.length > 0 || mcpResult.applied.length > 0 || nativePluginResult.installed.length > 0) {
|
|
17347
17642
|
const installed = {
|
|
17348
17643
|
name: plugin.name,
|
|
17349
17644
|
version: plugin.version,
|
|
17350
17645
|
description: plugin.description,
|
|
17351
|
-
source:
|
|
17646
|
+
source: effectiveSource,
|
|
17352
17647
|
format: plugin.format,
|
|
17353
17648
|
installedAt: new Date().toISOString(),
|
|
17354
17649
|
scope: options2.global ? "global" : "project",
|
|
17355
17650
|
components: {
|
|
17356
17651
|
skills: skillResult.installed,
|
|
17357
|
-
mcpServers: mcpResult.applied
|
|
17652
|
+
mcpServers: mcpResult.applied,
|
|
17653
|
+
nativePlugins: nativePluginResult.installed
|
|
17358
17654
|
},
|
|
17359
|
-
warnings:
|
|
17655
|
+
warnings: installWarnings
|
|
17360
17656
|
};
|
|
17361
17657
|
await this.addToRegistry(installed, projectPath, options2.global);
|
|
17362
17658
|
}
|
|
@@ -17364,7 +17660,8 @@ ${body.trim()}
|
|
|
17364
17660
|
plugin,
|
|
17365
17661
|
skills: skillResult,
|
|
17366
17662
|
mcpServers: mcpResult,
|
|
17367
|
-
|
|
17663
|
+
nativePlugins: nativePluginResult,
|
|
17664
|
+
warnings: installWarnings
|
|
17368
17665
|
};
|
|
17369
17666
|
} finally {
|
|
17370
17667
|
if (tempDir) {
|
|
@@ -17521,7 +17818,7 @@ ${body.trim()}
|
|
|
17521
17818
|
let plugins = registry.plugins;
|
|
17522
17819
|
if (options2.agents && options2.agents.length > 0) {
|
|
17523
17820
|
const agentSet = new Set(options2.agents);
|
|
17524
|
-
plugins = plugins.filter((p) => p.components.skills.some((s) => agentSet.has(s.agent)) || p.components.mcpServers.some((m) => agentSet.has(m.agent)));
|
|
17821
|
+
plugins = plugins.filter((p) => p.components.skills.some((s) => agentSet.has(s.agent)) || p.components.mcpServers.some((m) => agentSet.has(m.agent)) || (p.components.nativePlugins || []).some((nativePlugin) => agentSet.has(nativePlugin.agent)));
|
|
17525
17822
|
}
|
|
17526
17823
|
return plugins;
|
|
17527
17824
|
}
|
|
@@ -17531,7 +17828,8 @@ ${body.trim()}
|
|
|
17531
17828
|
if (!plugin) {
|
|
17532
17829
|
return { removed: false, details: [`Plugin "${name}" not found in registry`] };
|
|
17533
17830
|
}
|
|
17534
|
-
|
|
17831
|
+
const pluginNativeComponents = plugin.components.nativePlugins || [];
|
|
17832
|
+
if (plugin.components.skills.length === 0 && plugin.components.mcpServers.length === 0 && pluginNativeComponents.length === 0) {
|
|
17535
17833
|
registry.plugins = registry.plugins.filter((p) => p.name !== name);
|
|
17536
17834
|
await this.saveRegistry(registry, projectPath, options2.global);
|
|
17537
17835
|
return {
|
|
@@ -17611,7 +17909,40 @@ ${body.trim()}
|
|
|
17611
17909
|
...retainedMcpServers,
|
|
17612
17910
|
...targetedMcpServers.filter((mcp) => !removedMcpKeys.has(`${mcp.agent}:${mcp.name}`))
|
|
17613
17911
|
];
|
|
17614
|
-
|
|
17912
|
+
const targetedNativePlugins = agentFilter ? pluginNativeComponents.filter((nativePlugin) => agentFilter.has(nativePlugin.agent)) : pluginNativeComponents;
|
|
17913
|
+
const retainedNativePlugins = agentFilter ? pluginNativeComponents.filter((nativePlugin) => !agentFilter.has(nativePlugin.agent)) : [];
|
|
17914
|
+
const otherScopeRegistry = await this.getRegistry(projectPath, !options2.global);
|
|
17915
|
+
const otherRegistryNativePlugins = otherScopeRegistry.plugins.flatMap((entry) => entry.components.nativePlugins || []);
|
|
17916
|
+
const otherPluginNativePlugins = registry.plugins.filter((entry) => entry.name !== plugin.name).flatMap((entry) => entry.components.nativePlugins || []);
|
|
17917
|
+
const remainingNativeRefs = [
|
|
17918
|
+
...retainedNativePlugins,
|
|
17919
|
+
...otherPluginNativePlugins,
|
|
17920
|
+
...otherRegistryNativePlugins
|
|
17921
|
+
];
|
|
17922
|
+
const removedNativeKeys = new Set;
|
|
17923
|
+
for (const nativePlugin of targetedNativePlugins) {
|
|
17924
|
+
const nativeKey = `${nativePlugin.agent}:${nativePlugin.pluginKey}:${nativePlugin.installPath}`;
|
|
17925
|
+
if (removedNativeKeys.has(nativeKey)) {
|
|
17926
|
+
continue;
|
|
17927
|
+
}
|
|
17928
|
+
const sharedNativeInstall = remainingNativeRefs.some((other) => other.installPath === nativePlugin.installPath || other.pluginKey === nativePlugin.pluginKey);
|
|
17929
|
+
if (sharedNativeInstall) {
|
|
17930
|
+
details.push(`Skipped shared native plugin payload: ${nativePlugin.pluginKey} (${nativePlugin.agent})`);
|
|
17931
|
+
continue;
|
|
17932
|
+
}
|
|
17933
|
+
try {
|
|
17934
|
+
await this.removeNativeClaudePlugin(nativePlugin);
|
|
17935
|
+
removedNativeKeys.add(nativeKey);
|
|
17936
|
+
details.push(`Removed native plugin payload: ${nativePlugin.pluginKey} (${nativePlugin.agent})`);
|
|
17937
|
+
} catch {
|
|
17938
|
+
details.push(`Could not remove native plugin payload: ${nativePlugin.pluginKey} (${nativePlugin.agent})`);
|
|
17939
|
+
}
|
|
17940
|
+
}
|
|
17941
|
+
const remainingNativePlugins = [
|
|
17942
|
+
...retainedNativePlugins,
|
|
17943
|
+
...targetedNativePlugins.filter((nativePlugin) => !removedNativeKeys.has(`${nativePlugin.agent}:${nativePlugin.pluginKey}:${nativePlugin.installPath}`))
|
|
17944
|
+
];
|
|
17945
|
+
if (removedSkillPaths.size === 0 && removedMcpKeys.size === 0 && removedNativeKeys.size === 0) {
|
|
17615
17946
|
if (agentFilter) {
|
|
17616
17947
|
details.push(`No removable plugin components matched the requested agents for "${name}"`);
|
|
17617
17948
|
}
|
|
@@ -17621,11 +17952,12 @@ ${body.trim()}
|
|
|
17621
17952
|
...plugin,
|
|
17622
17953
|
components: {
|
|
17623
17954
|
skills: remainingSkills,
|
|
17624
|
-
mcpServers: remainingMcpServers
|
|
17955
|
+
mcpServers: remainingMcpServers,
|
|
17956
|
+
nativePlugins: remainingNativePlugins
|
|
17625
17957
|
}
|
|
17626
17958
|
};
|
|
17627
17959
|
registry.plugins = registry.plugins.filter((p) => p.name !== name);
|
|
17628
|
-
if (updatedPlugin.components.skills.length > 0 || updatedPlugin.components.mcpServers.length > 0) {
|
|
17960
|
+
if (updatedPlugin.components.skills.length > 0 || updatedPlugin.components.mcpServers.length > 0 || (updatedPlugin.components.nativePlugins || []).length > 0) {
|
|
17629
17961
|
registry.plugins.push(updatedPlugin);
|
|
17630
17962
|
details.push("Updated plugin registry");
|
|
17631
17963
|
} else {
|
|
@@ -17635,7 +17967,7 @@ ${body.trim()}
|
|
|
17635
17967
|
return { removed: true, details };
|
|
17636
17968
|
}
|
|
17637
17969
|
}
|
|
17638
|
-
var import_gray_matter, getMarketplaceCacheDir, getRegistryPath;
|
|
17970
|
+
var import_gray_matter, getMarketplaceCacheDir, getRegistryPath, getClaudeInstalledPluginsPath;
|
|
17639
17971
|
var init_pluginManager = __esm(() => {
|
|
17640
17972
|
import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
17641
17973
|
init_fs();
|
|
@@ -17652,10 +17984,13 @@ var init_pluginManager = __esm(() => {
|
|
|
17652
17984
|
}
|
|
17653
17985
|
return join3(projectPath, ".agentinit", "plugins.json");
|
|
17654
17986
|
};
|
|
17987
|
+
getClaudeInstalledPluginsPath = function() {
|
|
17988
|
+
return join3(homedir3(), ".claude", "plugins", "installed_plugins.json");
|
|
17989
|
+
};
|
|
17655
17990
|
});
|
|
17656
17991
|
|
|
17657
17992
|
// dist/core/skillsManager.js
|
|
17658
|
-
import {resolve as resolve8, join as join4, relative as
|
|
17993
|
+
import {resolve as resolve8, join as join4, relative as relative3} from "path";
|
|
17659
17994
|
import {promises as fs20} from "fs";
|
|
17660
17995
|
import {homedir as homedir4, tmpdir} from "os";
|
|
17661
17996
|
import {execFile} from "child_process";
|
|
@@ -17798,8 +18133,8 @@ class SkillsManager {
|
|
|
17798
18133
|
return skills;
|
|
17799
18134
|
}
|
|
17800
18135
|
async cloneRepo(url) {
|
|
17801
|
-
const tempDir = join4(tmpdir(),
|
|
17802
|
-
await fs20.
|
|
18136
|
+
const tempDir = await fs20.mkdtemp(join4(tmpdir(), "agentinit-skills-"));
|
|
18137
|
+
await fs20.rm(tempDir, { recursive: true, force: true });
|
|
17803
18138
|
try {
|
|
17804
18139
|
await execFileAsync("git", ["clone", "--depth", "1", url, tempDir], {
|
|
17805
18140
|
timeout: 60000
|
|
@@ -17842,6 +18177,22 @@ class SkillsManager {
|
|
|
17842
18177
|
warnings
|
|
17843
18178
|
};
|
|
17844
18179
|
}
|
|
18180
|
+
async discoverPortablePluginSkills(repoPath, sourceLabel, source, projectPath) {
|
|
18181
|
+
const { PluginManager: PluginManager2 } = await Promise.resolve().then(() => (init_pluginManager(), exports_pluginManager));
|
|
18182
|
+
const pluginManager = new PluginManager2(this.agentManager);
|
|
18183
|
+
const plugin = await pluginManager.loadPluginFromDirectory(repoPath, source);
|
|
18184
|
+
if (plugin.skills.length === 0 && plugin.mcpServers.length === 0 && plugin.warnings.length === 0) {
|
|
18185
|
+
return null;
|
|
18186
|
+
}
|
|
18187
|
+
const warnings = [...plugin.warnings];
|
|
18188
|
+
if (plugin.mcpServers.length > 0) {
|
|
18189
|
+
warnings.push(`Source "${sourceLabel}" also includes ${plugin.mcpServers.length} MCP server(s); use "agentinit plugins install ${sourceLabel}" to install them.`);
|
|
18190
|
+
}
|
|
18191
|
+
return {
|
|
18192
|
+
skills: plugin.skills,
|
|
18193
|
+
warnings
|
|
18194
|
+
};
|
|
18195
|
+
}
|
|
17845
18196
|
async discoverFromSource(source, projectPath, options2 = {}) {
|
|
17846
18197
|
const request = this.resolveSourceRequest(source, options2);
|
|
17847
18198
|
const resolved = request.source;
|
|
@@ -17864,11 +18215,22 @@ class SkillsManager {
|
|
|
17864
18215
|
}
|
|
17865
18216
|
}
|
|
17866
18217
|
let skills = await this.discoverSkills(repoPath);
|
|
18218
|
+
let pluginWarnings = [];
|
|
18219
|
+
if (skills.length === 0) {
|
|
18220
|
+
const pluginBackedSkills = await this.discoverPortablePluginSkills(repoPath, source, resolved, projectPath);
|
|
18221
|
+
if (pluginBackedSkills) {
|
|
18222
|
+
skills = pluginBackedSkills.skills;
|
|
18223
|
+
pluginWarnings = pluginBackedSkills.warnings;
|
|
18224
|
+
}
|
|
18225
|
+
}
|
|
17867
18226
|
if (request.implicitSkills.length > 0) {
|
|
17868
18227
|
const names = new Set(request.implicitSkills.map((skill) => skill.toLowerCase()));
|
|
17869
18228
|
skills = skills.filter((skill) => names.has(skill.name.toLowerCase()));
|
|
17870
18229
|
}
|
|
17871
|
-
const warnings =
|
|
18230
|
+
const warnings = [
|
|
18231
|
+
...pluginWarnings,
|
|
18232
|
+
...request.implicitSkills.length > 0 ? [`Resolved "${source}" from the default skills catalog ${DEFAULT_SKILLS_CATALOG.owner}/${DEFAULT_SKILLS_CATALOG.repo}. Use "./${source}" for a local path.`] : []
|
|
18233
|
+
];
|
|
17872
18234
|
return { skills, warnings };
|
|
17873
18235
|
} finally {
|
|
17874
18236
|
if (tempDir) {
|
|
@@ -18017,7 +18379,7 @@ class SkillsManager {
|
|
|
18017
18379
|
resolveInstallPath(targetDir, skillName) {
|
|
18018
18380
|
const resolvedTargetDir = resolve8(targetDir);
|
|
18019
18381
|
const destPath = resolve8(resolvedTargetDir, skillName);
|
|
18020
|
-
const relativePath =
|
|
18382
|
+
const relativePath = relative3(resolvedTargetDir, destPath);
|
|
18021
18383
|
if (relativePath === "" || relativePath.startsWith("..") || relativePath.includes("/../") || relativePath.includes("\\..\\")) {
|
|
18022
18384
|
throw new Error(`Refusing to install skill outside target directory: ${skillName}`);
|
|
18023
18385
|
}
|
|
@@ -18032,7 +18394,7 @@ class SkillsManager {
|
|
|
18032
18394
|
await fs20.mkdir(path, { recursive: true });
|
|
18033
18395
|
}
|
|
18034
18396
|
isWithinPath(basePath, targetPath) {
|
|
18035
|
-
const relativePath =
|
|
18397
|
+
const relativePath = relative3(resolve8(basePath), resolve8(targetPath));
|
|
18036
18398
|
return relativePath === "" || !relativePath.startsWith("..") && !relativePath.includes("/../") && !relativePath.includes("\\..\\");
|
|
18037
18399
|
}
|
|
18038
18400
|
async copyDir(src, dest) {
|
|
@@ -18083,7 +18445,7 @@ class SkillsManager {
|
|
|
18083
18445
|
...options2.global !== undefined ? { global: options2.global } : {},
|
|
18084
18446
|
...options2.copy !== undefined ? { copy: options2.copy } : {}
|
|
18085
18447
|
};
|
|
18086
|
-
const installed = await this.installSkillForAgent(skill.path, skill.name, agent, projectPath, installOptions);
|
|
18448
|
+
const installed = skill.generatedContent ? await this.installSkillFromContentForAgent(skill.name, skill.generatedContent, agent, projectPath, installOptions) : await this.installSkillForAgent(skill.path, skill.name, agent, projectPath, installOptions);
|
|
18087
18449
|
result.installed.push({ skill, agent: agent.id, ...installed });
|
|
18088
18450
|
} catch (error) {
|
|
18089
18451
|
result.skipped.push({ skill, reason: error.message });
|
|
@@ -19109,51 +19471,51 @@ var require_uri_all = __commonJS((exports, module) => {
|
|
|
19109
19471
|
}
|
|
19110
19472
|
return uriTokens.join("");
|
|
19111
19473
|
}
|
|
19112
|
-
function resolveComponents(base2,
|
|
19474
|
+
function resolveComponents(base2, relative6) {
|
|
19113
19475
|
var options2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
19114
19476
|
var skipNormalization = arguments[3];
|
|
19115
19477
|
var target = {};
|
|
19116
19478
|
if (!skipNormalization) {
|
|
19117
19479
|
base2 = parse4(serialize(base2, options2), options2);
|
|
19118
|
-
|
|
19480
|
+
relative6 = parse4(serialize(relative6, options2), options2);
|
|
19119
19481
|
}
|
|
19120
19482
|
options2 = options2 || {};
|
|
19121
|
-
if (!options2.tolerant &&
|
|
19122
|
-
target.scheme =
|
|
19123
|
-
target.userinfo =
|
|
19124
|
-
target.host =
|
|
19125
|
-
target.port =
|
|
19126
|
-
target.path = removeDotSegments(
|
|
19127
|
-
target.query =
|
|
19483
|
+
if (!options2.tolerant && relative6.scheme) {
|
|
19484
|
+
target.scheme = relative6.scheme;
|
|
19485
|
+
target.userinfo = relative6.userinfo;
|
|
19486
|
+
target.host = relative6.host;
|
|
19487
|
+
target.port = relative6.port;
|
|
19488
|
+
target.path = removeDotSegments(relative6.path || "");
|
|
19489
|
+
target.query = relative6.query;
|
|
19128
19490
|
} else {
|
|
19129
|
-
if (
|
|
19130
|
-
target.userinfo =
|
|
19131
|
-
target.host =
|
|
19132
|
-
target.port =
|
|
19133
|
-
target.path = removeDotSegments(
|
|
19134
|
-
target.query =
|
|
19491
|
+
if (relative6.userinfo !== undefined || relative6.host !== undefined || relative6.port !== undefined) {
|
|
19492
|
+
target.userinfo = relative6.userinfo;
|
|
19493
|
+
target.host = relative6.host;
|
|
19494
|
+
target.port = relative6.port;
|
|
19495
|
+
target.path = removeDotSegments(relative6.path || "");
|
|
19496
|
+
target.query = relative6.query;
|
|
19135
19497
|
} else {
|
|
19136
|
-
if (!
|
|
19498
|
+
if (!relative6.path) {
|
|
19137
19499
|
target.path = base2.path;
|
|
19138
|
-
if (
|
|
19139
|
-
target.query =
|
|
19500
|
+
if (relative6.query !== undefined) {
|
|
19501
|
+
target.query = relative6.query;
|
|
19140
19502
|
} else {
|
|
19141
19503
|
target.query = base2.query;
|
|
19142
19504
|
}
|
|
19143
19505
|
} else {
|
|
19144
|
-
if (
|
|
19145
|
-
target.path = removeDotSegments(
|
|
19506
|
+
if (relative6.path.charAt(0) === "/") {
|
|
19507
|
+
target.path = removeDotSegments(relative6.path);
|
|
19146
19508
|
} else {
|
|
19147
19509
|
if ((base2.userinfo !== undefined || base2.host !== undefined || base2.port !== undefined) && !base2.path) {
|
|
19148
|
-
target.path = "/" +
|
|
19510
|
+
target.path = "/" + relative6.path;
|
|
19149
19511
|
} else if (!base2.path) {
|
|
19150
|
-
target.path =
|
|
19512
|
+
target.path = relative6.path;
|
|
19151
19513
|
} else {
|
|
19152
|
-
target.path = base2.path.slice(0, base2.path.lastIndexOf("/") + 1) +
|
|
19514
|
+
target.path = base2.path.slice(0, base2.path.lastIndexOf("/") + 1) + relative6.path;
|
|
19153
19515
|
}
|
|
19154
19516
|
target.path = removeDotSegments(target.path);
|
|
19155
19517
|
}
|
|
19156
|
-
target.query =
|
|
19518
|
+
target.query = relative6.query;
|
|
19157
19519
|
}
|
|
19158
19520
|
target.userinfo = base2.userinfo;
|
|
19159
19521
|
target.host = base2.host;
|
|
@@ -19161,7 +19523,7 @@ var require_uri_all = __commonJS((exports, module) => {
|
|
|
19161
19523
|
}
|
|
19162
19524
|
target.scheme = base2.scheme;
|
|
19163
19525
|
}
|
|
19164
|
-
target.fragment =
|
|
19526
|
+
target.fragment = relative6.fragment;
|
|
19165
19527
|
return target;
|
|
19166
19528
|
}
|
|
19167
19529
|
function resolve12(baseURI, relativeURI, options2) {
|
|
@@ -38951,7 +39313,7 @@ async function detectCommand(options2) {
|
|
|
38951
39313
|
}
|
|
38952
39314
|
|
|
38953
39315
|
// dist/commands/sync.js
|
|
38954
|
-
import {relative as
|
|
39316
|
+
import {relative as relative5} from "path";
|
|
38955
39317
|
|
|
38956
39318
|
// dist/core/propagator.js
|
|
38957
39319
|
var import_gray_matter3 = __toESM(require_gray_matter(), 1);
|
|
@@ -41932,7 +42294,7 @@ ${content}
|
|
|
41932
42294
|
// dist/core/managedState.js
|
|
41933
42295
|
init_fs();
|
|
41934
42296
|
import {promises as fs24} from "fs";
|
|
41935
|
-
import {dirname as
|
|
42297
|
+
import {dirname as dirname3, join as join5, relative as relative4, resolve as resolve10} from "path";
|
|
41936
42298
|
var toPosixPath = function(value) {
|
|
41937
42299
|
return value.replace(/\\/g, "/");
|
|
41938
42300
|
};
|
|
@@ -41957,10 +42319,10 @@ async function copyDirectory(src, dest) {
|
|
|
41957
42319
|
await copyDirectory(srcPath, destPath);
|
|
41958
42320
|
} else if (entry.isSymbolicLink()) {
|
|
41959
42321
|
const target = await fs24.readlink(srcPath);
|
|
41960
|
-
await fs24.mkdir(
|
|
42322
|
+
await fs24.mkdir(dirname3(destPath), { recursive: true });
|
|
41961
42323
|
await fs24.symlink(target, destPath);
|
|
41962
42324
|
} else {
|
|
41963
|
-
await fs24.mkdir(
|
|
42325
|
+
await fs24.mkdir(dirname3(destPath), { recursive: true });
|
|
41964
42326
|
await fs24.copyFile(srcPath, destPath);
|
|
41965
42327
|
}
|
|
41966
42328
|
}
|
|
@@ -41970,7 +42332,7 @@ async function copyPath(src, dest) {
|
|
|
41970
42332
|
if (!type2) {
|
|
41971
42333
|
return;
|
|
41972
42334
|
}
|
|
41973
|
-
await fs24.mkdir(
|
|
42335
|
+
await fs24.mkdir(dirname3(dest), { recursive: true });
|
|
41974
42336
|
if (type2 === "symlink") {
|
|
41975
42337
|
const target = await fs24.readlink(src);
|
|
41976
42338
|
await fs24.symlink(target, dest);
|
|
@@ -42016,7 +42378,7 @@ class ManagedStateStore {
|
|
|
42016
42378
|
}
|
|
42017
42379
|
normalizeRelativePath(targetPath, preserveTrailingSlash = false) {
|
|
42018
42380
|
const hasTrailingSlash = preserveTrailingSlash && /[\\/]$/.test(targetPath);
|
|
42019
|
-
const relativePath =
|
|
42381
|
+
const relativePath = relative4(this.projectPath, resolve10(targetPath));
|
|
42020
42382
|
const normalizedPath = toPosixPath(relativePath);
|
|
42021
42383
|
if (hasTrailingSlash && normalizedPath) {
|
|
42022
42384
|
return normalizedPath.endsWith("/") ? normalizedPath : `${normalizedPath}/`;
|
|
@@ -42106,7 +42468,7 @@ class ManagedStateStore {
|
|
|
42106
42468
|
if (!options2.dryRun) {
|
|
42107
42469
|
await fs24.rm(absolutePath, { recursive: true, force: true }).catch(() => {
|
|
42108
42470
|
});
|
|
42109
|
-
await fs24.mkdir(
|
|
42471
|
+
await fs24.mkdir(dirname3(absolutePath), { recursive: true });
|
|
42110
42472
|
await fs24.symlink(backupLinkTarget, absolutePath);
|
|
42111
42473
|
}
|
|
42112
42474
|
summary.restored++;
|
|
@@ -42193,7 +42555,7 @@ async function syncCommand(options2) {
|
|
|
42193
42555
|
for (const change of result.changes) {
|
|
42194
42556
|
const action = change.action === "created" ? "\u2795" : change.action === "updated" ? "\uD83D\uDCDD" : "\uD83D\uDCBE";
|
|
42195
42557
|
const names = change.agents.map((id) => agentManager5.getAgentById(id)?.name || id).join(", ");
|
|
42196
|
-
logger.info(` ${action} ${
|
|
42558
|
+
logger.info(` ${action} ${relative5(cwd, change.file) || change.file}`);
|
|
42197
42559
|
logger.info(` Agents: ${names}`);
|
|
42198
42560
|
}
|
|
42199
42561
|
if (options2.backup && result.changes.some((c) => c.action === "backed_up")) {
|
|
@@ -42222,7 +42584,7 @@ async function syncCommand(options2) {
|
|
|
42222
42584
|
}
|
|
42223
42585
|
|
|
42224
42586
|
// dist/commands/apply.js
|
|
42225
|
-
import {relative as
|
|
42587
|
+
import {relative as relative6} from "path";
|
|
42226
42588
|
|
|
42227
42589
|
// dist/types/index.js
|
|
42228
42590
|
var MCPServerType;
|
|
@@ -42488,11 +42850,11 @@ class MCPParser {
|
|
|
42488
42850
|
// dist/constants/mcp.js
|
|
42489
42851
|
import {readFileSync} from "fs";
|
|
42490
42852
|
import {fileURLToPath} from "url";
|
|
42491
|
-
import {dirname as
|
|
42853
|
+
import {dirname as dirname4, join as join6} from "path";
|
|
42492
42854
|
var getPackageVersion = function() {
|
|
42493
42855
|
try {
|
|
42494
42856
|
const __filename2 = fileURLToPath(import.meta.url);
|
|
42495
|
-
const __dirname2 =
|
|
42857
|
+
const __dirname2 = dirname4(__filename2);
|
|
42496
42858
|
const packageJsonPath = join6(__dirname2, "../../package.json");
|
|
42497
42859
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
42498
42860
|
return packageJson.version || "1.0.0";
|
|
@@ -42524,11 +42886,11 @@ import {readFileSync as readFileSync3} from "fs";
|
|
|
42524
42886
|
|
|
42525
42887
|
// dist/core/rulesTemplateLoader.js
|
|
42526
42888
|
var toml = __toESM(require_toml(), 1);
|
|
42527
|
-
import {resolve as resolve11, dirname as
|
|
42889
|
+
import {resolve as resolve11, dirname as dirname5} from "path";
|
|
42528
42890
|
import {fileURLToPath as fileURLToPath2} from "url";
|
|
42529
42891
|
import {readFileSync as readFileSync2, readdirSync, existsSync} from "fs";
|
|
42530
42892
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
42531
|
-
var __dirname2 =
|
|
42893
|
+
var __dirname2 = dirname5(__filename2);
|
|
42532
42894
|
|
|
42533
42895
|
class RulesTemplateLoader {
|
|
42534
42896
|
templatesPath;
|
|
@@ -50764,10 +51126,10 @@ class MCPVerifier {
|
|
|
50764
51126
|
|
|
50765
51127
|
// dist/core/gitignoreManager.js
|
|
50766
51128
|
import {promises as fs27} from "fs";
|
|
50767
|
-
import {dirname as
|
|
51129
|
+
import {dirname as dirname6, join as join7} from "path";
|
|
50768
51130
|
var normalizeIgnorePath = function(projectPath, value) {
|
|
50769
|
-
const
|
|
50770
|
-
const normalized =
|
|
51131
|
+
const relative6 = value.startsWith(projectPath) ? value.slice(projectPath.length + 1) : value;
|
|
51132
|
+
const normalized = relative6.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
50771
51133
|
if (!normalized) {
|
|
50772
51134
|
return normalized;
|
|
50773
51135
|
}
|
|
@@ -50832,7 +51194,7 @@ async function updateManagedIgnoreFile(projectPath, paths2, options2 = {}) {
|
|
|
50832
51194
|
existingContent = "";
|
|
50833
51195
|
}
|
|
50834
51196
|
const updatedContent = updateManagedBlock(existingContent, normalizedPaths);
|
|
50835
|
-
await fs27.mkdir(
|
|
51197
|
+
await fs27.mkdir(dirname6(ignoreFilePath), { recursive: true });
|
|
50836
51198
|
await fs27.writeFile(ignoreFilePath, updatedContent, "utf8");
|
|
50837
51199
|
return ignoreFilePath;
|
|
50838
51200
|
}
|
|
@@ -50874,7 +51236,7 @@ var END_MARKER = "# END AgentInit Generated Files";
|
|
|
50874
51236
|
init_agentManager();
|
|
50875
51237
|
init_skillsManager();
|
|
50876
51238
|
init_fs();
|
|
50877
|
-
import {dirname as
|
|
51239
|
+
import {dirname as dirname7, join as join8} from "path";
|
|
50878
51240
|
async function discoverProjectSkills(projectPath, skillsManager4) {
|
|
50879
51241
|
const sources = [];
|
|
50880
51242
|
const skills = new Map;
|
|
@@ -50952,7 +51314,7 @@ async function applyProjectSkills(projectPath, targetAgentIds, managedState2, op
|
|
|
50952
51314
|
await managedState2.trackGeneratedPath(generatedPath, {
|
|
50953
51315
|
kind: "directory",
|
|
50954
51316
|
source: "skills",
|
|
50955
|
-
ignorePath: `${
|
|
51317
|
+
ignorePath: `${dirname7(generatedPath)}/`
|
|
50956
51318
|
});
|
|
50957
51319
|
}
|
|
50958
51320
|
}
|
|
@@ -51063,7 +51425,7 @@ async function applyProjectCommand(options2) {
|
|
|
51063
51425
|
if (change.action === "backed_up")
|
|
51064
51426
|
return;
|
|
51065
51427
|
const names = change.agents.map((id) => agentManager7.getAgentById(id)?.name || id).join(", ");
|
|
51066
|
-
logger.info(` ${
|
|
51428
|
+
logger.info(` ${relative6(cwd, change.file) || change.file}`);
|
|
51067
51429
|
logger.info(` Agents: ${names}`);
|
|
51068
51430
|
});
|
|
51069
51431
|
}
|
|
@@ -51081,7 +51443,7 @@ async function applyProjectCommand(options2) {
|
|
|
51081
51443
|
installsByPath.set(item.path, existing);
|
|
51082
51444
|
}
|
|
51083
51445
|
for (const [path, details] of installsByPath) {
|
|
51084
|
-
logger.info(` ${
|
|
51446
|
+
logger.info(` ${relative6(cwd, path) || path}`);
|
|
51085
51447
|
logger.info(` Agents: ${[...details.agents].join(", ")}`);
|
|
51086
51448
|
logger.info(` Skills: ${[...details.skills].join(", ")}`);
|
|
51087
51449
|
}
|
|
@@ -51774,7 +52136,7 @@ async function revertCommand(options2) {
|
|
|
51774
52136
|
// dist/commands/skills.js
|
|
51775
52137
|
var import_prompts2 = __toESM(require_prompts3(), 1);
|
|
51776
52138
|
import {homedir as homedir5} from "os";
|
|
51777
|
-
import {relative as
|
|
52139
|
+
import {relative as relative7, resolve as resolve12} from "path";
|
|
51778
52140
|
init_skillsManager();
|
|
51779
52141
|
init_marketplaceRegistry();
|
|
51780
52142
|
init_agentManager();
|
|
@@ -51791,28 +52153,8 @@ function registerSkillsCommand(program2) {
|
|
|
51791
52153
|
const result = await skillsManager5.discoverFromSource(source, process.cwd(), {
|
|
51792
52154
|
from: options2.from
|
|
51793
52155
|
});
|
|
51794
|
-
const discoveredSkills = result.skills;
|
|
51795
52156
|
spinner2.stop();
|
|
51796
|
-
|
|
51797
|
-
logger.info("No skills found in the source.");
|
|
51798
|
-
for (const warning of result.warnings) {
|
|
51799
|
-
logger.warn(warning);
|
|
51800
|
-
}
|
|
51801
|
-
return;
|
|
51802
|
-
}
|
|
51803
|
-
logger.info(`Found ${green(String(discoveredSkills.length))} skill(s):\n`);
|
|
51804
|
-
logger.info(" Name Description");
|
|
51805
|
-
logger.info(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
51806
|
-
for (const skill of discoveredSkills) {
|
|
51807
|
-
const name = skill.name.padEnd(18);
|
|
51808
|
-
logger.info(` ${green(name)} ${skill.description}`);
|
|
51809
|
-
}
|
|
51810
|
-
if (result.warnings.length > 0) {
|
|
51811
|
-
logger.info("");
|
|
51812
|
-
for (const warning of result.warnings) {
|
|
51813
|
-
logger.warn(warning);
|
|
51814
|
-
}
|
|
51815
|
-
}
|
|
52157
|
+
displayDiscoveredSkills(result.skills, result.warnings);
|
|
51816
52158
|
} catch (error) {
|
|
51817
52159
|
spinner2.fail("Failed to discover skills");
|
|
51818
52160
|
logger.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -51834,73 +52176,18 @@ function registerSkillsCommand(program2) {
|
|
|
51834
52176
|
targetGlobal = selection.global;
|
|
51835
52177
|
}
|
|
51836
52178
|
}
|
|
52179
|
+
const buildInstallOptions = (fromOverride) => ({
|
|
52180
|
+
...fromOverride !== undefined ? { from: fromOverride } : options2.from !== undefined ? { from: options2.from } : {},
|
|
52181
|
+
...targetGlobal !== undefined ? { global: targetGlobal } : {},
|
|
52182
|
+
...targetAgents !== undefined ? { agents: targetAgents } : {},
|
|
52183
|
+
...options2.skill !== undefined ? { skills: options2.skill } : {},
|
|
52184
|
+
...options2.copy !== undefined ? { copy: options2.copy } : {},
|
|
52185
|
+
...options2.yes !== undefined ? { yes: options2.yes } : {}
|
|
52186
|
+
});
|
|
51837
52187
|
const spinner = ora("Installing skills...").start();
|
|
51838
52188
|
try {
|
|
51839
|
-
const
|
|
51840
|
-
|
|
51841
|
-
...targetGlobal !== undefined ? { global: targetGlobal } : {},
|
|
51842
|
-
...targetAgents !== undefined ? { agents: targetAgents } : {},
|
|
51843
|
-
...options2.skill !== undefined ? { skills: options2.skill } : {},
|
|
51844
|
-
...options2.copy !== undefined ? { copy: options2.copy } : {},
|
|
51845
|
-
...options2.yes !== undefined ? { yes: options2.yes } : {}
|
|
51846
|
-
};
|
|
51847
|
-
const result = await skillsManager5.addFromSource(source, process.cwd(), installOptions);
|
|
51848
|
-
if (result.installed.length === 0 && result.skipped.length === 0) {
|
|
51849
|
-
spinner.warn("No skills found in the source.");
|
|
51850
|
-
for (const warning of result.warnings) {
|
|
51851
|
-
logger.warn(warning);
|
|
51852
|
-
}
|
|
51853
|
-
return;
|
|
51854
|
-
}
|
|
51855
|
-
if (result.installed.length === 0 && result.skipped.length > 0 && result.skipped.every((skip) => skip.reason === "No target agents found")) {
|
|
51856
|
-
spinner.warn("No target agents found.");
|
|
51857
|
-
logNoTargetAgentsGuidance(skillsManager5, agentManager9, source, {
|
|
51858
|
-
from: options2.from
|
|
51859
|
-
});
|
|
51860
|
-
if (result.warnings.length > 0) {
|
|
51861
|
-
logger.info("");
|
|
51862
|
-
for (const warning of result.warnings) {
|
|
51863
|
-
logger.warn(warning);
|
|
51864
|
-
}
|
|
51865
|
-
}
|
|
51866
|
-
return;
|
|
51867
|
-
}
|
|
51868
|
-
const uniqueInstallCount = new Set(result.installed.map((item) => `${item.path}:${item.skill.name}`)).size;
|
|
51869
|
-
spinner.succeed(`Installed ${green(String(uniqueInstallCount))} skill(s)`);
|
|
51870
|
-
const byPath = new Map;
|
|
51871
|
-
for (const item of result.installed) {
|
|
51872
|
-
const path = item.path;
|
|
51873
|
-
const existing = byPath.get(path) || {
|
|
51874
|
-
agents: new Set,
|
|
51875
|
-
skills: new Set
|
|
51876
|
-
};
|
|
51877
|
-
existing.agents.add(agentManager9.getAgentById(item.agent)?.name || item.agent);
|
|
51878
|
-
existing.skills.add(item.skill.name);
|
|
51879
|
-
byPath.set(path, existing);
|
|
51880
|
-
}
|
|
51881
|
-
for (const [path, details] of byPath) {
|
|
51882
|
-
logger.info(` ${relative6(process.cwd(), path) || path}`);
|
|
51883
|
-
logger.info(` Agents: ${[...details.agents].join(", ")}`);
|
|
51884
|
-
logger.info(` Skills: ${green(String(details.skills.size))} installed (${[...details.skills].join(", ")})`);
|
|
51885
|
-
}
|
|
51886
|
-
const copiedFallbacks = result.installed.filter((item) => item.symlinkFailed);
|
|
51887
|
-
if (copiedFallbacks.length > 0) {
|
|
51888
|
-
logger.warn(`Symlink creation failed for ${copiedFallbacks.length} install(s); copied the skill files instead.`);
|
|
51889
|
-
}
|
|
51890
|
-
if (result.skipped.length > 0) {
|
|
51891
|
-
logger.info("");
|
|
51892
|
-
logger.warn(`Skipped ${result.skipped.length} skill(s):`);
|
|
51893
|
-
for (const skip of result.skipped) {
|
|
51894
|
-
logger.info(` ${skip.skill.name}: ${skip.reason}`);
|
|
51895
|
-
}
|
|
51896
|
-
}
|
|
51897
|
-
if (result.warnings.length > 0) {
|
|
51898
|
-
logger.info("");
|
|
51899
|
-
for (const warning of result.warnings) {
|
|
51900
|
-
logger.warn(warning);
|
|
51901
|
-
}
|
|
51902
|
-
}
|
|
51903
|
-
logger.success("Skills installation complete.");
|
|
52189
|
+
const result = await skillsManager5.addFromSource(source, process.cwd(), buildInstallOptions());
|
|
52190
|
+
displayInstallResult(result, spinner, agentManager9, skillsManager5, source, { from: options2.from });
|
|
51904
52191
|
} catch (error) {
|
|
51905
52192
|
spinner.fail("Failed to install skills");
|
|
51906
52193
|
logger.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -51942,7 +52229,7 @@ function registerSkillsCommand(program2) {
|
|
|
51942
52229
|
const mode = skill.mode === "symlink" ? " (canonical)" : "";
|
|
51943
52230
|
const scope = skill.scope === "global" ? " [global]" : "";
|
|
51944
52231
|
logger.info(`\n ${green(skill.name)} - ${skill.description}${scope}${mode}`);
|
|
51945
|
-
logger.info(` Path: ${
|
|
52232
|
+
logger.info(` Path: ${relative7(process.cwd(), skill.path) || skill.path}`);
|
|
51946
52233
|
logger.info(` Agents: ${[...skill.agents].join(", ")}`);
|
|
51947
52234
|
}
|
|
51948
52235
|
});
|
|
@@ -52135,7 +52422,7 @@ var formatSkillsDir = function(projectPath, dir) {
|
|
|
52135
52422
|
const normalizedProjectPath = projectPath.replace(/\\/g, "/");
|
|
52136
52423
|
const normalizedHome = homedir5().replace(/\\/g, "/");
|
|
52137
52424
|
if (normalizedDir.startsWith(`${normalizedProjectPath}/`)) {
|
|
52138
|
-
return `${
|
|
52425
|
+
return `${relative7(projectPath, dir).replace(/\\/g, "/").replace(/\/?$/, "/")}`;
|
|
52139
52426
|
}
|
|
52140
52427
|
if (normalizedDir.startsWith(`${normalizedHome}/`)) {
|
|
52141
52428
|
return normalizedDir.replace(normalizedHome, "~");
|
|
@@ -52223,6 +52510,86 @@ var buildSkillsAddCommand = function(source, from, extraArgs) {
|
|
|
52223
52510
|
args.push(...extraArgs);
|
|
52224
52511
|
return args.join(" ");
|
|
52225
52512
|
};
|
|
52513
|
+
var displayDiscoveredSkills = function(skills, warnings) {
|
|
52514
|
+
if (skills.length === 0) {
|
|
52515
|
+
logger.info("No skills found in the source.");
|
|
52516
|
+
for (const warning of warnings) {
|
|
52517
|
+
logger.warn(warning);
|
|
52518
|
+
}
|
|
52519
|
+
return;
|
|
52520
|
+
}
|
|
52521
|
+
logger.info(`Found ${green(String(skills.length))} skill(s):\n`);
|
|
52522
|
+
logger.info(" Name Description");
|
|
52523
|
+
logger.info(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
52524
|
+
for (const skill of skills) {
|
|
52525
|
+
const name = skill.name.padEnd(18);
|
|
52526
|
+
logger.info(` ${green(name)} ${skill.description}`);
|
|
52527
|
+
}
|
|
52528
|
+
if (warnings.length > 0) {
|
|
52529
|
+
logger.info("");
|
|
52530
|
+
for (const warning of warnings) {
|
|
52531
|
+
logger.warn(warning);
|
|
52532
|
+
}
|
|
52533
|
+
}
|
|
52534
|
+
};
|
|
52535
|
+
var displayInstallResult = function(result, spinner, agentManager9, skillsManager5, source, options2) {
|
|
52536
|
+
if (result.installed.length === 0 && result.skipped.length === 0) {
|
|
52537
|
+
spinner.warn("No skills found in the source.");
|
|
52538
|
+
for (const warning of result.warnings) {
|
|
52539
|
+
logger.warn(warning);
|
|
52540
|
+
}
|
|
52541
|
+
return;
|
|
52542
|
+
}
|
|
52543
|
+
if (result.installed.length === 0 && result.skipped.length > 0 && result.skipped.every((skip) => skip.reason === "No target agents found")) {
|
|
52544
|
+
spinner.warn("No target agents found.");
|
|
52545
|
+
logNoTargetAgentsGuidance(skillsManager5, agentManager9, source, {
|
|
52546
|
+
...options2.from !== undefined ? { from: options2.from } : {}
|
|
52547
|
+
});
|
|
52548
|
+
if (result.warnings.length > 0) {
|
|
52549
|
+
logger.info("");
|
|
52550
|
+
for (const warning of result.warnings) {
|
|
52551
|
+
logger.warn(warning);
|
|
52552
|
+
}
|
|
52553
|
+
}
|
|
52554
|
+
return;
|
|
52555
|
+
}
|
|
52556
|
+
const uniqueInstallCount = new Set(result.installed.map((item) => `${item.path}:${item.skill.name}`)).size;
|
|
52557
|
+
spinner.succeed(`Installed ${green(String(uniqueInstallCount))} skill(s)`);
|
|
52558
|
+
const byPath = new Map;
|
|
52559
|
+
for (const item of result.installed) {
|
|
52560
|
+
const path = item.path;
|
|
52561
|
+
const existing = byPath.get(path) || {
|
|
52562
|
+
agents: new Set,
|
|
52563
|
+
skills: new Set
|
|
52564
|
+
};
|
|
52565
|
+
existing.agents.add(agentManager9.getAgentById(item.agent)?.name || item.agent);
|
|
52566
|
+
existing.skills.add(item.skill.name);
|
|
52567
|
+
byPath.set(path, existing);
|
|
52568
|
+
}
|
|
52569
|
+
for (const [path, details] of byPath) {
|
|
52570
|
+
logger.info(` ${relative7(process.cwd(), path) || path}`);
|
|
52571
|
+
logger.info(` Agents: ${[...details.agents].join(", ")}`);
|
|
52572
|
+
logger.info(` Skills: ${green(String(details.skills.size))} installed (${[...details.skills].join(", ")})`);
|
|
52573
|
+
}
|
|
52574
|
+
const copiedFallbacks = result.installed.filter((item) => item.symlinkFailed);
|
|
52575
|
+
if (copiedFallbacks.length > 0) {
|
|
52576
|
+
logger.warn(`Symlink creation failed for ${copiedFallbacks.length} install(s); copied the skill files instead.`);
|
|
52577
|
+
}
|
|
52578
|
+
if (result.skipped.length > 0) {
|
|
52579
|
+
logger.info("");
|
|
52580
|
+
logger.warn(`Skipped ${result.skipped.length} skill(s):`);
|
|
52581
|
+
for (const skip of result.skipped) {
|
|
52582
|
+
logger.info(` ${skip.skill.name}: ${skip.reason}`);
|
|
52583
|
+
}
|
|
52584
|
+
}
|
|
52585
|
+
if (result.warnings.length > 0) {
|
|
52586
|
+
logger.info("");
|
|
52587
|
+
for (const warning of result.warnings) {
|
|
52588
|
+
logger.warn(warning);
|
|
52589
|
+
}
|
|
52590
|
+
}
|
|
52591
|
+
logger.success("Skills installation complete.");
|
|
52592
|
+
};
|
|
52226
52593
|
|
|
52227
52594
|
// dist/commands/mcp.js
|
|
52228
52595
|
init_mcpFilter();
|
|
@@ -53088,7 +53455,8 @@ function registerPluginsCommand(program2) {
|
|
|
53088
53455
|
const p = result.plugin;
|
|
53089
53456
|
const totalSkills = result.skills.installed.length;
|
|
53090
53457
|
const totalMcp = result.mcpServers.applied.length;
|
|
53091
|
-
|
|
53458
|
+
const totalNative = result.nativePlugins.installed.length;
|
|
53459
|
+
if (totalSkills === 0 && totalMcp === 0 && totalNative === 0) {
|
|
53092
53460
|
spinner.warn(`Plugin "${p.name}" has no portable components to install.`);
|
|
53093
53461
|
if (result.warnings.length > 0) {
|
|
53094
53462
|
for (const w of result.warnings) {
|
|
@@ -53122,7 +53490,12 @@ function registerPluginsCommand(program2) {
|
|
|
53122
53490
|
logger.info(` ${agent}: ${cyan(String(servers.length))} MCP server(s) [${servers.join(", ")}]`);
|
|
53123
53491
|
}
|
|
53124
53492
|
}
|
|
53125
|
-
if (
|
|
53493
|
+
if (totalNative > 0) {
|
|
53494
|
+
for (const nativePlugin of result.nativePlugins.installed) {
|
|
53495
|
+
logger.info(` ${nativePlugin.agent}: native plugin payload installed at ${nativePlugin.installPath}`);
|
|
53496
|
+
}
|
|
53497
|
+
}
|
|
53498
|
+
if (result.skills.skipped.length > 0 || result.mcpServers.skipped.length > 0 || result.nativePlugins.skipped.length > 0) {
|
|
53126
53499
|
console.log("");
|
|
53127
53500
|
for (const s of result.skills.skipped) {
|
|
53128
53501
|
logger.debug(`Skipped skill ${s.name}: ${s.reason}`);
|
|
@@ -53130,6 +53503,9 @@ function registerPluginsCommand(program2) {
|
|
|
53130
53503
|
for (const s of result.mcpServers.skipped) {
|
|
53131
53504
|
logger.debug(`Skipped MCP ${s.name}: ${s.reason}`);
|
|
53132
53505
|
}
|
|
53506
|
+
for (const s of result.nativePlugins.skipped) {
|
|
53507
|
+
logger.warn(`Skipped native plugin payload for ${s.agent}: ${s.reason}`);
|
|
53508
|
+
}
|
|
53133
53509
|
}
|
|
53134
53510
|
if (result.warnings.length > 0) {
|
|
53135
53511
|
console.log("");
|
|
@@ -53209,6 +53585,10 @@ function registerPluginsCommand(program2) {
|
|
|
53209
53585
|
const agents = [...new Set(p.components.mcpServers.map((m) => m.agent))];
|
|
53210
53586
|
logger.info(` MCP: ${p.components.mcpServers.length} \u2192 ${agents.join(", ")}`);
|
|
53211
53587
|
}
|
|
53588
|
+
if ((p.components.nativePlugins || []).length > 0) {
|
|
53589
|
+
const agents = [...new Set((p.components.nativePlugins || []).map((nativePlugin) => nativePlugin.agent))];
|
|
53590
|
+
logger.info(` Native Plugins: ${(p.components.nativePlugins || []).length} \u2192 ${agents.join(", ")}`);
|
|
53591
|
+
}
|
|
53212
53592
|
if (p.warnings.length > 0) {
|
|
53213
53593
|
for (const w of p.warnings) {
|
|
53214
53594
|
logger.warn(` ${w}`);
|