plugins 1.2.4 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +114 -29
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -353,7 +353,7 @@ function detectTarget(def) {
|
|
|
353
353
|
case "claude-code":
|
|
354
354
|
return detectBinary("claude");
|
|
355
355
|
case "cursor":
|
|
356
|
-
return detectBinary("cursor")
|
|
356
|
+
return detectBinary("cursor");
|
|
357
357
|
default:
|
|
358
358
|
return false;
|
|
359
359
|
}
|
|
@@ -441,6 +441,13 @@ function barLine(content = "") {
|
|
|
441
441
|
function barEmpty() {
|
|
442
442
|
console.log(`${c.gray(S.bar)}`);
|
|
443
443
|
}
|
|
444
|
+
var _debug = false;
|
|
445
|
+
function setDebug(enabled) {
|
|
446
|
+
_debug = enabled;
|
|
447
|
+
}
|
|
448
|
+
function barDebug(content = "") {
|
|
449
|
+
if (_debug) barLine(content);
|
|
450
|
+
}
|
|
444
451
|
function step(content) {
|
|
445
452
|
console.log(`${c.gray(S.step)} ${content}`);
|
|
446
453
|
}
|
|
@@ -663,29 +670,18 @@ function banner() {
|
|
|
663
670
|
}
|
|
664
671
|
|
|
665
672
|
// lib/install.ts
|
|
666
|
-
|
|
667
|
-
switch (targetId) {
|
|
668
|
-
case "claude-code":
|
|
669
|
-
case "cursor":
|
|
670
|
-
return "claude-code";
|
|
671
|
-
default:
|
|
672
|
-
return targetId;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
var completedInstallers = /* @__PURE__ */ new Set();
|
|
673
|
+
var cachePopulated = false;
|
|
676
674
|
async function installPlugins(plugins, target, scope, repoPath, source) {
|
|
677
|
-
|
|
678
|
-
if (completedInstallers.has(key)) {
|
|
679
|
-
return;
|
|
680
|
-
}
|
|
681
|
-
switch (key) {
|
|
675
|
+
switch (target.id) {
|
|
682
676
|
case "claude-code":
|
|
683
677
|
await installToClaudeCode(plugins, scope, repoPath, source);
|
|
684
678
|
break;
|
|
679
|
+
case "cursor":
|
|
680
|
+
await installToCursor(plugins, scope, repoPath, source);
|
|
681
|
+
break;
|
|
685
682
|
default:
|
|
686
683
|
throw new Error(`Unsupported target: ${target.id}`);
|
|
687
684
|
}
|
|
688
|
-
completedInstallers.add(key);
|
|
689
685
|
}
|
|
690
686
|
async function installToClaudeCode(plugins, scope, repoPath, source) {
|
|
691
687
|
const marketplaceName = plugins[0]?.marketplace ?? deriveMarketplaceName(source);
|
|
@@ -695,19 +691,19 @@ async function installToClaudeCode(plugins, scope, repoPath, source) {
|
|
|
695
691
|
const marketplaceSource = isAnthropicSource(source) ? normalizeGitUrl(source) : repoPath;
|
|
696
692
|
const claudePath = findClaude();
|
|
697
693
|
step("Adding marketplace");
|
|
698
|
-
|
|
694
|
+
barDebug(c.dim(`Binary: ${claudePath}`));
|
|
699
695
|
try {
|
|
700
696
|
const version = execSync2(`${claudePath} --version`, { encoding: "utf-8", stdio: "pipe" }).trim();
|
|
701
|
-
|
|
697
|
+
barDebug(c.dim(`Version: ${version}`));
|
|
702
698
|
} catch {
|
|
703
|
-
|
|
699
|
+
barDebug(c.dim(`Warning: could not get claude version`));
|
|
704
700
|
}
|
|
705
701
|
try {
|
|
706
702
|
const result = execSync2(`${claudePath} plugin marketplace add ${marketplaceSource}`, {
|
|
707
703
|
encoding: "utf-8",
|
|
708
704
|
stdio: "pipe"
|
|
709
705
|
});
|
|
710
|
-
if (result.trim())
|
|
706
|
+
if (result.trim()) barDebug(c.dim(result.trim()));
|
|
711
707
|
stepDone("Marketplace added");
|
|
712
708
|
} catch (err) {
|
|
713
709
|
const stderr = err.stderr?.toString().trim() ?? "";
|
|
@@ -747,6 +743,84 @@ async function installToClaudeCode(plugins, scope, repoPath, source) {
|
|
|
747
743
|
}
|
|
748
744
|
}
|
|
749
745
|
}
|
|
746
|
+
cachePopulated = true;
|
|
747
|
+
}
|
|
748
|
+
async function installToCursor(plugins, scope, repoPath, source) {
|
|
749
|
+
if (cachePopulated) return;
|
|
750
|
+
const claudePath = findClaudeOrNull();
|
|
751
|
+
if (claudePath) {
|
|
752
|
+
await installToClaudeCode(plugins, scope, repoPath, source);
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
await installToPluginCache(plugins, scope, repoPath, source);
|
|
756
|
+
}
|
|
757
|
+
async function installToPluginCache(plugins, scope, repoPath, source) {
|
|
758
|
+
const marketplaceName = plugins[0]?.marketplace ?? deriveMarketplaceName(source);
|
|
759
|
+
const home = homedir2();
|
|
760
|
+
const pluginsDir = join3(home, ".claude", "plugins");
|
|
761
|
+
const cacheDir = join3(pluginsDir, "cache");
|
|
762
|
+
step("Preparing plugins for Cursor...");
|
|
763
|
+
barEmpty();
|
|
764
|
+
await prepareForClaudeCode(plugins, repoPath, marketplaceName);
|
|
765
|
+
step("Registering marketplace");
|
|
766
|
+
await mkdir(pluginsDir, { recursive: true });
|
|
767
|
+
const knownPath = join3(pluginsDir, "known_marketplaces.json");
|
|
768
|
+
let knownMarketplaces = {};
|
|
769
|
+
if (existsSync2(knownPath)) {
|
|
770
|
+
try {
|
|
771
|
+
knownMarketplaces = JSON.parse(await readFile2(knownPath, "utf-8"));
|
|
772
|
+
} catch {
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
if (knownMarketplaces[marketplaceName]) {
|
|
776
|
+
stepDone(`Marketplace ${c.dim("'" + marketplaceName + "'")} already registered`);
|
|
777
|
+
} else {
|
|
778
|
+
knownMarketplaces[marketplaceName] = {
|
|
779
|
+
source: { source: "directory", path: repoPath },
|
|
780
|
+
installLocation: repoPath,
|
|
781
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
782
|
+
};
|
|
783
|
+
await writeFile(knownPath, JSON.stringify(knownMarketplaces, null, 2));
|
|
784
|
+
stepDone("Marketplace registered");
|
|
785
|
+
}
|
|
786
|
+
barEmpty();
|
|
787
|
+
const installedPath = join3(pluginsDir, "installed_plugins.json");
|
|
788
|
+
let installedData = { version: 2, plugins: {} };
|
|
789
|
+
if (existsSync2(installedPath)) {
|
|
790
|
+
try {
|
|
791
|
+
installedData = JSON.parse(await readFile2(installedPath, "utf-8"));
|
|
792
|
+
} catch {
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
let gitSha;
|
|
796
|
+
try {
|
|
797
|
+
gitSha = execSync2("git rev-parse HEAD", { cwd: repoPath, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
798
|
+
} catch {
|
|
799
|
+
}
|
|
800
|
+
for (const plugin of plugins) {
|
|
801
|
+
const pluginRef = `${plugin.name}@${marketplaceName}`;
|
|
802
|
+
const version = plugin.version ?? "0.0.0";
|
|
803
|
+
step(`Installing ${c.bold(pluginRef)}...`);
|
|
804
|
+
const cacheDest = join3(cacheDir, marketplaceName, plugin.name, version);
|
|
805
|
+
await mkdir(cacheDest, { recursive: true });
|
|
806
|
+
await cp(plugin.path, cacheDest, { recursive: true });
|
|
807
|
+
barDebug(c.dim(`Cached to ${cacheDest}`));
|
|
808
|
+
const pluginKey = `${plugin.name}@${marketplaceName}`;
|
|
809
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
810
|
+
const entry = {
|
|
811
|
+
scope,
|
|
812
|
+
installPath: cacheDest,
|
|
813
|
+
version,
|
|
814
|
+
installedAt: now,
|
|
815
|
+
lastUpdated: now
|
|
816
|
+
};
|
|
817
|
+
if (gitSha) entry.gitCommitSha = gitSha;
|
|
818
|
+
installedData.plugins[pluginKey] = [entry];
|
|
819
|
+
stepDone(`Installed ${c.cyan(pluginRef)}`);
|
|
820
|
+
}
|
|
821
|
+
await writeFile(installedPath, JSON.stringify(installedData, null, 2));
|
|
822
|
+
barDebug(c.dim("Updated installed_plugins.json"));
|
|
823
|
+
cachePopulated = true;
|
|
750
824
|
}
|
|
751
825
|
async function prepareForClaudeCode(plugins, repoPath, marketplaceName) {
|
|
752
826
|
const claudePluginDir = join3(repoPath, ".claude-plugin");
|
|
@@ -773,12 +847,12 @@ async function prepareForClaudeCode(plugins, repoPath, marketplaceName) {
|
|
|
773
847
|
join3(claudePluginDir, "marketplace.json"),
|
|
774
848
|
JSON.stringify(marketplaceJson, null, 2)
|
|
775
849
|
);
|
|
776
|
-
|
|
850
|
+
barDebug(c.dim("Generated .claude-plugin/marketplace.json"));
|
|
777
851
|
for (const plugin of plugins) {
|
|
778
852
|
await preparePluginDirForVendor(plugin, ".claude-plugin", "CLAUDE_PLUGIN_ROOT");
|
|
779
853
|
}
|
|
780
854
|
}
|
|
781
|
-
function
|
|
855
|
+
function findClaudeOrNull() {
|
|
782
856
|
try {
|
|
783
857
|
const path = execSync2("which claude", { encoding: "utf-8", stdio: "pipe" }).trim();
|
|
784
858
|
if (path) return path;
|
|
@@ -793,7 +867,10 @@ function findClaude() {
|
|
|
793
867
|
for (const candidate of candidates) {
|
|
794
868
|
if (existsSync2(candidate)) return candidate;
|
|
795
869
|
}
|
|
796
|
-
return
|
|
870
|
+
return null;
|
|
871
|
+
}
|
|
872
|
+
function findClaude() {
|
|
873
|
+
return findClaudeOrNull() ?? "claude";
|
|
797
874
|
}
|
|
798
875
|
async function preparePluginDirForVendor(plugin, vendorDir, envVar) {
|
|
799
876
|
const pluginPath = plugin.path;
|
|
@@ -803,7 +880,7 @@ async function preparePluginDirForVendor(plugin, vendorDir, envVar) {
|
|
|
803
880
|
const hasVendorPlugin = existsSync2(join3(vendorPluginDir, "plugin.json"));
|
|
804
881
|
if (hasOpenPlugin && !hasVendorPlugin) {
|
|
805
882
|
await cp(openPluginDir, vendorPluginDir, { recursive: true });
|
|
806
|
-
|
|
883
|
+
barDebug(c.dim(`${plugin.name}: translated .plugin/ \u2192 ${vendorDir}/`));
|
|
807
884
|
}
|
|
808
885
|
if (!hasOpenPlugin && !hasVendorPlugin) {
|
|
809
886
|
await mkdir(vendorPluginDir, { recursive: true });
|
|
@@ -819,7 +896,7 @@ async function preparePluginDirForVendor(plugin, vendorDir, envVar) {
|
|
|
819
896
|
2
|
|
820
897
|
)
|
|
821
898
|
);
|
|
822
|
-
|
|
899
|
+
barDebug(c.dim(`${plugin.name}: generated ${vendorDir}/plugin.json`));
|
|
823
900
|
}
|
|
824
901
|
await translateEnvVars(pluginPath, plugin.name, envVar);
|
|
825
902
|
}
|
|
@@ -848,7 +925,7 @@ async function translateEnvVars(pluginPath, pluginName, envVar) {
|
|
|
848
925
|
}
|
|
849
926
|
if (changed) {
|
|
850
927
|
await writeFile(filePath, content);
|
|
851
|
-
|
|
928
|
+
barDebug(
|
|
852
929
|
c.dim(`${pluginName}: translated plugin root \u2192 \${${envVar}} in ${filePath.split("/").pop()}`)
|
|
853
930
|
);
|
|
854
931
|
}
|
|
@@ -935,12 +1012,14 @@ var { values, positionals } = parseArgs({
|
|
|
935
1012
|
target: { type: "string", short: "t" },
|
|
936
1013
|
scope: { type: "string", short: "s", default: "user" },
|
|
937
1014
|
yes: { type: "boolean", short: "y" },
|
|
938
|
-
remote: { type: "boolean" }
|
|
1015
|
+
remote: { type: "boolean" },
|
|
1016
|
+
debug: { type: "boolean" }
|
|
939
1017
|
},
|
|
940
1018
|
allowPositionals: true,
|
|
941
1019
|
strict: true
|
|
942
1020
|
});
|
|
943
1021
|
var [command, ...rest] = positionals;
|
|
1022
|
+
if (values.debug) setDebug(true);
|
|
944
1023
|
if (values.help || !command) {
|
|
945
1024
|
printUsage();
|
|
946
1025
|
process.exit(0);
|
|
@@ -973,6 +1052,7 @@ ${c.dim("Options:")}
|
|
|
973
1052
|
${c.yellow("-s, --scope")} <scope> Install scope: user, project, local. Default: user
|
|
974
1053
|
${c.yellow("-y, --yes")} Skip confirmation prompts
|
|
975
1054
|
${c.yellow("--remote")} Include remote-source plugins in output
|
|
1055
|
+
${c.yellow("--debug")} Show verbose installation output
|
|
976
1056
|
${c.yellow("-h, --help")} Show this help
|
|
977
1057
|
`);
|
|
978
1058
|
}
|
|
@@ -1070,11 +1150,16 @@ async function cmdInstall(source, opts) {
|
|
|
1070
1150
|
footer();
|
|
1071
1151
|
process.exit(1);
|
|
1072
1152
|
}
|
|
1153
|
+
if (!found.detected) {
|
|
1154
|
+
barEmpty();
|
|
1155
|
+
barLine(c.yellow(`Warning: ${found.name} was not detected on this system.`));
|
|
1156
|
+
}
|
|
1073
1157
|
installTargets = [found];
|
|
1074
1158
|
} else if (detectedTargets.length === 0) {
|
|
1075
1159
|
barEmpty();
|
|
1076
1160
|
stepError("No supported targets detected.");
|
|
1077
|
-
barLine(c.dim("
|
|
1161
|
+
barLine(c.dim("Neither 'claude' nor 'cursor' binaries were found on PATH."));
|
|
1162
|
+
barLine(c.dim("Use --target to specify one manually."));
|
|
1078
1163
|
footer();
|
|
1079
1164
|
process.exit(1);
|
|
1080
1165
|
} else {
|