@cannbot-ai/install-helper 1.1.8 → 1.1.9-beta.1
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 -26
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
|
+
}) : x)(function(x) {
|
|
7
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
|
+
});
|
|
4
10
|
var __esm = (fn, res) => function __init() {
|
|
5
11
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
12
|
};
|
|
@@ -164,7 +170,7 @@ var init_embedded_plugins = __esm({
|
|
|
164
170
|
"ascendc-registry",
|
|
165
171
|
"registry"
|
|
166
172
|
],
|
|
167
|
-
skills:
|
|
173
|
+
skills: 30,
|
|
168
174
|
agents: 7,
|
|
169
175
|
description: "\u751F\u4EA7\u7EA7 ACLNN \u6CE8\u518C\u7B97\u5B50\u5168\u6D41\u7A0B\uFF1A\u4EE3\u7801\u2192UT/ST\u2192\u4E0A\u5E93",
|
|
170
176
|
version: "1.2.3",
|
|
@@ -217,6 +223,12 @@ var init_embedded_plugins = __esm({
|
|
|
217
223
|
as: "ops-registry-invoke-workflow"
|
|
218
224
|
}
|
|
219
225
|
]
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
dir: "plugins-official/ops-registry-invoke/skills",
|
|
229
|
+
skills: [
|
|
230
|
+
"spec-to-design"
|
|
231
|
+
]
|
|
220
232
|
}
|
|
221
233
|
],
|
|
222
234
|
installAgents: [
|
|
@@ -2444,8 +2456,8 @@ init_registry();
|
|
|
2444
2456
|
|
|
2445
2457
|
// src/core/metadata-sync.ts
|
|
2446
2458
|
init_registry();
|
|
2447
|
-
import { existsSync as existsSync9, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
|
|
2448
|
-
import { join as join8 } from "path";
|
|
2459
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5, statSync as statSync2, readdirSync as readdirSync3 } from "fs";
|
|
2460
|
+
import { join as join8, sep } from "path";
|
|
2449
2461
|
function readPluginJson(pluginDir) {
|
|
2450
2462
|
const pjPath = join8(pluginDir, ".claude-plugin", "plugin.json");
|
|
2451
2463
|
try {
|
|
@@ -2465,13 +2477,33 @@ function parseIncludedSkills(pluginDir) {
|
|
|
2465
2477
|
return [];
|
|
2466
2478
|
}
|
|
2467
2479
|
}
|
|
2468
|
-
function
|
|
2480
|
+
function parseAllSkills(pluginDir) {
|
|
2481
|
+
const initPath = join8(pluginDir, "init.sh");
|
|
2482
|
+
try {
|
|
2483
|
+
const text = readFileSync5(initPath, "utf-8");
|
|
2484
|
+
const m = text.match(/ALL_SKILLS="([^"]*)"/);
|
|
2485
|
+
if (!m) return [];
|
|
2486
|
+
const val = m[1];
|
|
2487
|
+
if (val.includes("$(") || val.includes("${")) return [];
|
|
2488
|
+
return val.split(/\s+/).filter(Boolean);
|
|
2489
|
+
} catch {
|
|
2490
|
+
return [];
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
function findSkillSourceDir(skillName, repoRoot, scanDirs, pluginDir) {
|
|
2469
2494
|
for (const dir of scanDirs) {
|
|
2470
2495
|
const candidate = join8(repoRoot, dir, skillName);
|
|
2471
2496
|
if (existsSync9(candidate) && statSync2(candidate).isDirectory()) {
|
|
2472
2497
|
return dir;
|
|
2473
2498
|
}
|
|
2474
2499
|
}
|
|
2500
|
+
if (pluginDir) {
|
|
2501
|
+
const localCandidate = join8(pluginDir, "skills", skillName);
|
|
2502
|
+
if (existsSync9(localCandidate) && statSync2(localCandidate).isDirectory()) {
|
|
2503
|
+
const relPluginDir = pluginDir.replace(repoRoot + sep, "").replace(repoRoot + "/", "");
|
|
2504
|
+
return `${relPluginDir}/skills`;
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2475
2507
|
return null;
|
|
2476
2508
|
}
|
|
2477
2509
|
function collectDeclaredSkillNames(installSkills2) {
|
|
@@ -2489,7 +2521,60 @@ function collectDeclaredSkillNames(installSkills2) {
|
|
|
2489
2521
|
}
|
|
2490
2522
|
function resolveAgentsFromPluginJson(pj) {
|
|
2491
2523
|
if (!pj || !Array.isArray(pj.agents)) return [];
|
|
2492
|
-
return pj.agents.map((a) => a.replace(/^\.\/agents\//, "").replace(/\.md$/, "")).filter(Boolean);
|
|
2524
|
+
return pj.agents.filter((a) => a.startsWith("./agents/")).map((a) => a.replace(/^\.\/agents\//, "").replace(/\.md$/, "")).filter(Boolean);
|
|
2525
|
+
}
|
|
2526
|
+
function parseIncludedAgentPattern(initShPath) {
|
|
2527
|
+
try {
|
|
2528
|
+
const text = readFileSync5(initShPath, "utf-8");
|
|
2529
|
+
const m = text.match(/INCLUDED_AGENT_PATTERN="([^"]*)"/);
|
|
2530
|
+
if (!m) return null;
|
|
2531
|
+
return m[1].trim() || null;
|
|
2532
|
+
} catch {
|
|
2533
|
+
return null;
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
function simpleGlobToRegExp(pattern) {
|
|
2537
|
+
let re = "^";
|
|
2538
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
2539
|
+
const c = pattern[i];
|
|
2540
|
+
if (c === "*") re += ".*";
|
|
2541
|
+
else if (c === "?") re += ".";
|
|
2542
|
+
else re += c.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
2543
|
+
}
|
|
2544
|
+
return new RegExp(re + "$");
|
|
2545
|
+
}
|
|
2546
|
+
function matchAgentsByPattern(agentsDir, pattern) {
|
|
2547
|
+
const filePattern = pattern.endsWith(".md") ? pattern : pattern + ".md";
|
|
2548
|
+
try {
|
|
2549
|
+
const fsSync = __require("fs");
|
|
2550
|
+
if (typeof fsSync.globSync === "function") {
|
|
2551
|
+
return fsSync.globSync(filePattern, { cwd: agentsDir }).map((f) => f.replace(/\.md$/, "").replace(/\\/g, "/"));
|
|
2552
|
+
}
|
|
2553
|
+
} catch {
|
|
2554
|
+
}
|
|
2555
|
+
if (filePattern.includes("@(") || filePattern.includes("+(") || filePattern.includes("!(")) {
|
|
2556
|
+
return [];
|
|
2557
|
+
}
|
|
2558
|
+
try {
|
|
2559
|
+
const re = simpleGlobToRegExp(filePattern);
|
|
2560
|
+
return readdirSync3(agentsDir).filter((f) => f.endsWith(".md") && re.test(f)).map((f) => f.replace(/\.md$/, ""));
|
|
2561
|
+
} catch {
|
|
2562
|
+
return [];
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
function discoverAgents(pluginDir, pj, initShPath, fallbackAgents) {
|
|
2566
|
+
const fromPj = resolveAgentsFromPluginJson(pj);
|
|
2567
|
+
if (fromPj.length > 0) return fromPj;
|
|
2568
|
+
if (pj && Array.isArray(pj.agents) && pj.agents.length === 0) return [];
|
|
2569
|
+
const pattern = parseIncludedAgentPattern(initShPath);
|
|
2570
|
+
if (pattern) {
|
|
2571
|
+
const agentsDir = join8(pluginDir, "agents");
|
|
2572
|
+
if (existsSync9(agentsDir)) {
|
|
2573
|
+
const fromPattern = matchAgentsByPattern(agentsDir, pattern);
|
|
2574
|
+
if (fromPattern.length > 0) return fromPattern;
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
return fallbackAgents || [];
|
|
2493
2578
|
}
|
|
2494
2579
|
function countSkills(installSkills2) {
|
|
2495
2580
|
if (!installSkills2) return 0;
|
|
@@ -2500,12 +2585,15 @@ function countSkills(installSkills2) {
|
|
|
2500
2585
|
function mergeInitSkills(existing, pluginDir, repoRoot, scanDirs) {
|
|
2501
2586
|
const base = existing || [];
|
|
2502
2587
|
const seen = collectDeclaredSkillNames(base);
|
|
2503
|
-
|
|
2588
|
+
let initSkills = parseIncludedSkills(pluginDir);
|
|
2589
|
+
if (initSkills.length === 0) {
|
|
2590
|
+
initSkills = parseAllSkills(pluginDir);
|
|
2591
|
+
}
|
|
2504
2592
|
if (initSkills.length === 0) return base;
|
|
2505
2593
|
const merged = base.map((s) => ({ ...s, skills: [...s.skills] }));
|
|
2506
2594
|
for (const skill of initSkills) {
|
|
2507
2595
|
if (seen.has(skill)) continue;
|
|
2508
|
-
const srcDir = findSkillSourceDir(skill, repoRoot, scanDirs);
|
|
2596
|
+
const srcDir = findSkillSourceDir(skill, repoRoot, scanDirs, pluginDir);
|
|
2509
2597
|
if (!srcDir) continue;
|
|
2510
2598
|
let bucket = merged.find((b) => b.dir === srcDir);
|
|
2511
2599
|
if (!bucket) {
|
|
@@ -2532,7 +2620,8 @@ function enrichPluginMetadata(repoPath) {
|
|
|
2532
2620
|
if (pj && pj.name && plugin.displayName === plugin.id) {
|
|
2533
2621
|
plugin.displayName = pj.name;
|
|
2534
2622
|
}
|
|
2535
|
-
|
|
2623
|
+
const initShPath = join8(pluginDir, "init.sh");
|
|
2624
|
+
plugin.installAgents = discoverAgents(pluginDir, pj, initShPath, plugin.installAgents);
|
|
2536
2625
|
const merged = mergeInitSkills(plugin.installSkills, pluginDir, repoPath, scanDirs);
|
|
2537
2626
|
plugin.installSkills = merged;
|
|
2538
2627
|
plugin.skills = countSkills(merged);
|
|
@@ -2676,7 +2765,7 @@ init_fs();
|
|
|
2676
2765
|
init_fs_helpers();
|
|
2677
2766
|
init_logger();
|
|
2678
2767
|
init_i18n();
|
|
2679
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync4, readFileSync as readFileSync7, unlinkSync as unlinkSync3, readdirSync as
|
|
2768
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync4, readFileSync as readFileSync7, unlinkSync as unlinkSync3, readdirSync as readdirSync4 } from "fs";
|
|
2680
2769
|
import { join as join10 } from "path";
|
|
2681
2770
|
function getInstallsDir() {
|
|
2682
2771
|
return join10(getCannbotConfigDir(), "installs");
|
|
@@ -2876,7 +2965,7 @@ function getInstalledSkills(tool, level, installPath, allowFsScan = true) {
|
|
|
2876
2965
|
const fromFs = [];
|
|
2877
2966
|
if (existsSync11(skillsDir)) {
|
|
2878
2967
|
try {
|
|
2879
|
-
const entries =
|
|
2968
|
+
const entries = readdirSync4(skillsDir);
|
|
2880
2969
|
for (const entry of entries) {
|
|
2881
2970
|
if (entry === "." || entry === "..") continue;
|
|
2882
2971
|
const entryPath = join10(skillsDir, entry);
|
|
@@ -2906,7 +2995,7 @@ function getLastBatchSkills(tool, level, installPath) {
|
|
|
2906
2995
|
|
|
2907
2996
|
// src/core/backup.ts
|
|
2908
2997
|
init_manifest();
|
|
2909
|
-
import { existsSync as existsSync12, copyFileSync, readdirSync as
|
|
2998
|
+
import { existsSync as existsSync12, copyFileSync, readdirSync as readdirSync5, unlinkSync as unlinkSync4 } from "fs";
|
|
2910
2999
|
import { join as join11 } from "path";
|
|
2911
3000
|
init_registry();
|
|
2912
3001
|
init_paths();
|
|
@@ -2971,7 +3060,7 @@ function findBackups(configRoot) {
|
|
|
2971
3060
|
if (!existsSync12(configRoot)) {
|
|
2972
3061
|
return [];
|
|
2973
3062
|
}
|
|
2974
|
-
const files =
|
|
3063
|
+
const files = readdirSync5(configRoot);
|
|
2975
3064
|
const backups = [];
|
|
2976
3065
|
for (const file of files) {
|
|
2977
3066
|
if (file.includes(".cannbot-backup.")) {
|
|
@@ -3168,7 +3257,6 @@ async function installExternalRepos(repos, repoPath, configRoot, installPath, le
|
|
|
3168
3257
|
await execa3("git", ["pull", "--quiet"], { cwd: targetDir, timeout: 12e4 });
|
|
3169
3258
|
} catch {
|
|
3170
3259
|
logger.warn(t("external_repo_update_failed").replace("{dir}", repo.dir));
|
|
3171
|
-
continue;
|
|
3172
3260
|
}
|
|
3173
3261
|
} else if (!existsSync13(targetDir)) {
|
|
3174
3262
|
const args = ["clone"];
|
|
@@ -3569,7 +3657,7 @@ init_fs_helpers();
|
|
|
3569
3657
|
init_constants();
|
|
3570
3658
|
init_logger();
|
|
3571
3659
|
init_i18n();
|
|
3572
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync6, symlinkSync as symlinkSync2, readdirSync as
|
|
3660
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, symlinkSync as symlinkSync2, readdirSync as readdirSync6, rmSync as rmSync4, realpathSync as realpathSync2, readlinkSync as readlinkSync2, cpSync as cpSync2 } from "fs";
|
|
3573
3661
|
import { join as join14, dirname as dirname5, isAbsolute } from "path";
|
|
3574
3662
|
import { select as select3, checkbox, Separator as Separator2 } from "@inquirer/prompts";
|
|
3575
3663
|
import chalk5 from "chalk";
|
|
@@ -3669,7 +3757,7 @@ async function uninstallSkills(skillIds, tool, level) {
|
|
|
3669
3757
|
}
|
|
3670
3758
|
if (existsSync15(skillsDir)) {
|
|
3671
3759
|
try {
|
|
3672
|
-
const entries =
|
|
3760
|
+
const entries = readdirSync6(skillsDir);
|
|
3673
3761
|
if (entries.length === 0) {
|
|
3674
3762
|
rmSync4(skillsDir, { recursive: true });
|
|
3675
3763
|
logger.step(` ${t("uninstall_clean_empty_dir")}: skills/`);
|
|
@@ -4432,7 +4520,7 @@ init_manifest();
|
|
|
4432
4520
|
init_paths();
|
|
4433
4521
|
init_i18n();
|
|
4434
4522
|
import chalk8 from "chalk";
|
|
4435
|
-
import { existsSync as existsSync17, readdirSync as
|
|
4523
|
+
import { existsSync as existsSync17, readdirSync as readdirSync7, lstatSync as lstatSync2, unlinkSync as unlinkSync5, mkdirSync as mkdirSync7 } from "fs";
|
|
4436
4524
|
import { join as join16 } from "path";
|
|
4437
4525
|
async function doctorCommand(options = {}) {
|
|
4438
4526
|
console.log();
|
|
@@ -4491,7 +4579,7 @@ async function doctorCommand(options = {}) {
|
|
|
4491
4579
|
if (existsSync17(skillsDir)) {
|
|
4492
4580
|
const brokenLinks = checkBrokenLinks(skillsDir);
|
|
4493
4581
|
if (brokenLinks === 0) {
|
|
4494
|
-
const count =
|
|
4582
|
+
const count = readdirSync7(skillsDir).length;
|
|
4495
4583
|
console.log(chalk8.green(" \u2713") + ` ${skillsDir} \u2014 ${t("doctor_links_valid").replace("{count}", String(count))}`);
|
|
4496
4584
|
} else {
|
|
4497
4585
|
console.log(chalk8.yellow(" \u26A0") + ` ${skillsDir} \u2014 ${t("doctor_broken_links").replace("{count}", String(brokenLinks))}`);
|
|
@@ -4513,7 +4601,7 @@ async function doctorCommand(options = {}) {
|
|
|
4513
4601
|
if (existsSync17(agentsDir)) {
|
|
4514
4602
|
const brokenLinks = checkBrokenLinks(agentsDir);
|
|
4515
4603
|
if (brokenLinks === 0) {
|
|
4516
|
-
const count =
|
|
4604
|
+
const count = readdirSync7(agentsDir).length;
|
|
4517
4605
|
console.log(chalk8.green(" \u2713") + ` ${agentsDir} \u2014 ${t("doctor_links_valid").replace("{count}", String(count))}`);
|
|
4518
4606
|
} else {
|
|
4519
4607
|
console.log(chalk8.yellow(" \u26A0") + ` ${agentsDir} \u2014 ${t("doctor_broken_links").replace("{count}", String(brokenLinks))}`);
|
|
@@ -4560,7 +4648,7 @@ async function doctorCommand(options = {}) {
|
|
|
4560
4648
|
function checkBrokenLinks(dir) {
|
|
4561
4649
|
let broken = 0;
|
|
4562
4650
|
try {
|
|
4563
|
-
const entries =
|
|
4651
|
+
const entries = readdirSync7(dir);
|
|
4564
4652
|
for (const entry of entries) {
|
|
4565
4653
|
const fullPath = join16(dir, entry);
|
|
4566
4654
|
try {
|
|
@@ -4581,7 +4669,7 @@ function checkBrokenLinks(dir) {
|
|
|
4581
4669
|
function fixBrokenLinks(dir) {
|
|
4582
4670
|
let fixed = 0;
|
|
4583
4671
|
try {
|
|
4584
|
-
const entries =
|
|
4672
|
+
const entries = readdirSync7(dir);
|
|
4585
4673
|
for (const entry of entries) {
|
|
4586
4674
|
const fullPath = join16(dir, entry);
|
|
4587
4675
|
try {
|
|
@@ -4968,8 +5056,8 @@ async function installPlugins(pluginIds, tool, level, repoPath, installPath, yes
|
|
|
4968
5056
|
|
|
4969
5057
|
// src/commands/uninstall.ts
|
|
4970
5058
|
init_registry();
|
|
4971
|
-
import { existsSync as existsSync18, unlinkSync as unlinkSync6, rmdirSync, readdirSync as
|
|
4972
|
-
import { resolve, basename as basename3, sep, join as join18 } from "path";
|
|
5059
|
+
import { existsSync as existsSync18, unlinkSync as unlinkSync6, rmdirSync, readdirSync as readdirSync8, readFileSync as readFileSync9 } from "fs";
|
|
5060
|
+
import { resolve, basename as basename3, sep as sep2, join as join18 } from "path";
|
|
4973
5061
|
import chalk11 from "chalk";
|
|
4974
5062
|
import { select as select5, checkbox as checkbox2, Separator as Separator4, confirm as confirm3 } from "@inquirer/prompts";
|
|
4975
5063
|
init_config();
|
|
@@ -5290,7 +5378,7 @@ async function uninstallPluginById(pluginId, batchMode) {
|
|
|
5290
5378
|
const allowedBases = [resolve(configRoot), resolve(record.installPath)];
|
|
5291
5379
|
const isSafePath = (p) => {
|
|
5292
5380
|
const resolved = resolve(p);
|
|
5293
|
-
return allowedBases.some((base) => resolved === base || resolved.startsWith(base +
|
|
5381
|
+
return allowedBases.some((base) => resolved === base || resolved.startsWith(base + sep2));
|
|
5294
5382
|
};
|
|
5295
5383
|
let removedFiles = 0;
|
|
5296
5384
|
let removedDirs = 0;
|
|
@@ -5321,7 +5409,7 @@ async function uninstallPluginById(pluginId, batchMode) {
|
|
|
5321
5409
|
continue;
|
|
5322
5410
|
}
|
|
5323
5411
|
if (existsSync18(dirPath)) {
|
|
5324
|
-
const entries =
|
|
5412
|
+
const entries = readdirSync8(dirPath);
|
|
5325
5413
|
if (entries.length === 0) {
|
|
5326
5414
|
rmdirSync(dirPath);
|
|
5327
5415
|
const name = basename3(dirPath);
|
|
@@ -5482,7 +5570,7 @@ async function updateCommand(pluginNames, options) {
|
|
|
5482
5570
|
// src/commands/info.ts
|
|
5483
5571
|
init_registry();
|
|
5484
5572
|
import chalk13 from "chalk";
|
|
5485
|
-
import { existsSync as existsSync19, readdirSync as
|
|
5573
|
+
import { existsSync as existsSync19, readdirSync as readdirSync9 } from "fs";
|
|
5486
5574
|
import { join as join19 } from "path";
|
|
5487
5575
|
init_manifest();
|
|
5488
5576
|
init_i18n();
|
|
@@ -5516,7 +5604,7 @@ async function infoCommand(pluginName) {
|
|
|
5516
5604
|
}
|
|
5517
5605
|
const agentsDir = join19(repoPath, plugin.dir, "agents");
|
|
5518
5606
|
if (existsSync19(agentsDir)) {
|
|
5519
|
-
const agentFiles =
|
|
5607
|
+
const agentFiles = readdirSync9(agentsDir).filter((f) => f.endsWith(".md"));
|
|
5520
5608
|
if (agentFiles.length > 0) {
|
|
5521
5609
|
console.log();
|
|
5522
5610
|
console.log(` ${chalk13.bold("Agents:")}`);
|