@cannbot-ai/install-helper 0.0.2-beta.38 → 0.0.2-beta.39

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 CHANGED
@@ -1516,9 +1516,9 @@ function createRepositoryManager(customPath) {
1516
1516
  }
1517
1517
 
1518
1518
  // src/core/installer.ts
1519
- import { existsSync as existsSync11 } from "fs";
1520
- import { join as join11 } from "path";
1521
- import { execa as execa3 } from "execa";
1519
+ import { existsSync as existsSync12 } from "fs";
1520
+ import { join as join12 } from "path";
1521
+ import { execa as execa4 } from "execa";
1522
1522
 
1523
1523
  // src/core/record.ts
1524
1524
  import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync7, unlinkSync as unlinkSync2 } from "fs";
@@ -1850,39 +1850,211 @@ async function showRestorePrompt(backups) {
1850
1850
  return choice;
1851
1851
  }
1852
1852
 
1853
- // src/core/installer.ts
1854
- async function installPlugin(opts) {
1855
- const plugin = getPluginById(opts.pluginId);
1856
- if (!plugin) {
1853
+ // src/core/plugin-installer.ts
1854
+ import { existsSync as existsSync11, mkdirSync as mkdirSync5, symlinkSync, unlinkSync as unlinkSync4, realpathSync, copyFileSync as copyFileSync2, cpSync, writeFileSync as writeFileSync3, readFileSync as readFileSync8 } from "fs";
1855
+ import { join as join11 } from "path";
1856
+ import { execa as execa3 } from "execa";
1857
+ function readPluginManifest(pluginDir) {
1858
+ const manifestPath = join11(pluginDir, "plugin-manifest.json");
1859
+ if (!existsSync11(manifestPath)) return null;
1860
+ try {
1861
+ const content = JSON.parse(readFileSync8(manifestPath, "utf-8"));
1862
+ if (!content || !content.id) return null;
1863
+ return content;
1864
+ } catch {
1865
+ return null;
1866
+ }
1867
+ }
1868
+ function installLink(source, target) {
1869
+ try {
1870
+ const resolved = realpathSync(source);
1871
+ if (existsSync11(target) || isSymlink(target)) {
1872
+ unlinkSync4(target);
1873
+ }
1874
+ try {
1875
+ symlinkSync(resolved, target);
1876
+ return "symlink";
1877
+ } catch (e) {
1878
+ if (e.code === "EPERM") {
1879
+ cpSync(resolved, target, { recursive: true });
1880
+ return "copy";
1881
+ }
1882
+ throw e;
1883
+ }
1884
+ } catch {
1885
+ return "failed";
1886
+ }
1887
+ }
1888
+ function installConfigFile(pluginDir, configFile, tool, level, configRoot, installPath) {
1889
+ const sourcePath = join11(pluginDir, configFile);
1890
+ if (!existsSync11(sourcePath)) return;
1891
+ const agentsFileName = getAgentsFileName(tool);
1892
+ const isProjectLevel = level === "project";
1893
+ let primaryTarget;
1894
+ if (isProjectLevel) {
1895
+ primaryTarget = join11(installPath, agentsFileName);
1896
+ } else {
1897
+ primaryTarget = join11(configRoot, agentsFileName);
1898
+ }
1899
+ if (existsSync11(primaryTarget) || isSymlink(primaryTarget)) {
1900
+ unlinkSync4(primaryTarget);
1901
+ }
1902
+ try {
1903
+ symlinkSync(realpathSync(sourcePath), primaryTarget);
1904
+ } catch (e) {
1905
+ if (e.code === "EPERM") {
1906
+ copyFileSync2(sourcePath, primaryTarget);
1907
+ } else {
1908
+ throw e;
1909
+ }
1910
+ }
1911
+ if (isProjectLevel && primaryTarget !== join11(configRoot, agentsFileName)) {
1912
+ const configRootTarget = join11(configRoot, agentsFileName);
1913
+ if (existsSync11(configRootTarget) || isSymlink(configRootTarget)) {
1914
+ unlinkSync4(configRootTarget);
1915
+ }
1916
+ try {
1917
+ symlinkSync(realpathSync(sourcePath), configRootTarget);
1918
+ } catch (e) {
1919
+ if (e.code === "EPERM") {
1920
+ copyFileSync2(sourcePath, configRootTarget);
1921
+ }
1922
+ }
1923
+ }
1924
+ }
1925
+ async function installExternalRepos(repos, repoPath) {
1926
+ if (!repos || repos.length === 0) return;
1927
+ for (const repo of repos) {
1928
+ const targetDir = join11(repoPath, repo.dir);
1929
+ if (existsSync11(targetDir)) {
1930
+ logger.info(` ${repo.dir} already exists, skipping clone`);
1931
+ continue;
1932
+ }
1933
+ const args = ["clone"];
1934
+ if (repo.depth) {
1935
+ args.push("--depth", String(repo.depth));
1936
+ }
1937
+ if (repo.recursive) {
1938
+ args.push("--recursive");
1939
+ }
1940
+ args.push(repo.url, targetDir);
1941
+ try {
1942
+ await execa3("git", args, { timeout: 12e4 });
1943
+ } catch {
1944
+ logger.warn(` git clone failed: ${repo.url}, clone manually: git clone ${repo.url} ${repo.dir}`);
1945
+ }
1946
+ }
1947
+ }
1948
+ function writeCannbotManifest(configRoot, pluginId, version, level, tool, skills, agents) {
1949
+ const manifest = {
1950
+ brand: "CANNBot",
1951
+ version,
1952
+ team: pluginId,
1953
+ level,
1954
+ tool,
1955
+ installed_skills: skills,
1956
+ installed_agents: agents,
1957
+ brand_dir: configRoot,
1958
+ install_time: (/* @__PURE__ */ new Date()).toISOString()
1959
+ };
1960
+ const manifestPath = join11(configRoot, "cannbot-manifest.json");
1961
+ writeFileSync3(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
1962
+ return manifest;
1963
+ }
1964
+ async function installViaManifest(manifest, pluginDir, repoPath, tool, level, installPath) {
1965
+ const cwd = installPath || process.cwd();
1966
+ const configRoot = getConfigRoot(tool, level, installPath);
1967
+ try {
1968
+ const skillsDir = join11(configRoot, "skills");
1969
+ const agentsDir = join11(configRoot, "agents");
1970
+ mkdirSync5(skillsDir, { recursive: true });
1971
+ mkdirSync5(agentsDir, { recursive: true });
1972
+ const installedSkills = [];
1973
+ const installedAgents = [];
1974
+ for (const source of manifest.skills) {
1975
+ const sourceDir = join11(repoPath, source.dir);
1976
+ if (!existsSync11(sourceDir)) {
1977
+ logger.warn(` Skill source not found: ${source.dir}`);
1978
+ continue;
1979
+ }
1980
+ for (const skillName of source.skills) {
1981
+ const skillPath = join11(sourceDir, skillName);
1982
+ if (!existsSync11(skillPath)) {
1983
+ logger.warn(` Skill not found: ${skillName} in ${source.dir}`);
1984
+ continue;
1985
+ }
1986
+ const targetPath = join11(skillsDir, skillName);
1987
+ const result = installLink(skillPath, targetPath);
1988
+ if (result !== "failed") {
1989
+ installedSkills.push(skillName);
1990
+ } else {
1991
+ logger.warn(` Failed to install skill: ${skillName}`);
1992
+ }
1993
+ }
1994
+ }
1995
+ for (const agentName of manifest.agents) {
1996
+ const agentFile = agentName.endsWith(".md") ? agentName : `${agentName}.md`;
1997
+ const agentPath = join11(pluginDir, "agents", agentFile);
1998
+ if (!existsSync11(agentPath)) {
1999
+ logger.warn(` Agent not found: ${agentFile}`);
2000
+ continue;
2001
+ }
2002
+ const targetPath = join11(agentsDir, agentFile);
2003
+ const result = installLink(agentPath, targetPath);
2004
+ if (result !== "failed") {
2005
+ installedAgents.push(agentFile);
2006
+ } else {
2007
+ logger.warn(` Failed to install agent: ${agentFile}`);
2008
+ }
2009
+ }
2010
+ installConfigFile(pluginDir, manifest.configFile, tool, level, configRoot, cwd);
2011
+ await installExternalRepos(manifest.externalRepos, repoPath);
2012
+ const cannbotManifest = writeCannbotManifest(
2013
+ configRoot,
2014
+ manifest.id,
2015
+ manifest.version || "1.0.0",
2016
+ level,
2017
+ tool,
2018
+ installedSkills,
2019
+ installedAgents
2020
+ );
2021
+ return {
2022
+ success: true,
2023
+ skillsCount: installedSkills.length,
2024
+ agentsCount: installedAgents.length,
2025
+ errors: [],
2026
+ manifest: cannbotManifest
2027
+ };
2028
+ } catch (error) {
1857
2029
  return {
1858
2030
  success: false,
1859
- pluginId: opts.pluginId,
1860
2031
  skillsCount: 0,
1861
2032
  agentsCount: 0,
1862
- errors: [t("error_plugin_not_found") + ": " + opts.pluginId],
1863
- warnings: []
2033
+ errors: [error instanceof Error ? error.message : t("error_unknown")],
2034
+ manifest: null
1864
2035
  };
1865
2036
  }
1866
- const scriptPath = join11(opts.repoPath, plugin.dir, plugin.script);
1867
- if (!existsSync11(scriptPath)) {
2037
+ }
2038
+
2039
+ // src/core/installer.ts
2040
+ async function installPlugin(opts) {
2041
+ const plugin = getPluginById(opts.pluginId);
2042
+ if (!plugin) {
1868
2043
  return {
1869
2044
  success: false,
1870
2045
  pluginId: opts.pluginId,
1871
2046
  skillsCount: 0,
1872
2047
  agentsCount: 0,
1873
- errors: [t("error_script_not_found").replace("{path}", scriptPath)],
2048
+ errors: [t("error_plugin_not_found") + ": " + opts.pluginId],
1874
2049
  warnings: []
1875
2050
  };
1876
2051
  }
1877
- const args = [opts.level, opts.tool];
1878
- if (opts.installPath) {
1879
- args.push(opts.installPath);
1880
- }
2052
+ const pluginDir = join12(opts.repoPath, plugin.dir);
1881
2053
  const cwd = opts.installPath || process.cwd();
1882
2054
  const configRoot = getConfigRoot(opts.tool, opts.level, opts.installPath);
1883
- const agentsFile = join11(configRoot, getAgentsFileName(opts.tool));
2055
+ const agentsFile = join12(configRoot, getAgentsFileName(opts.tool));
1884
2056
  let backupInfo = null;
1885
- if (existsSync11(agentsFile)) {
2057
+ if (existsSync12(agentsFile)) {
1886
2058
  const currentPlugin = detectCurrentPlugin(configRoot, opts.tool);
1887
2059
  if (currentPlugin && currentPlugin.pluginId !== opts.pluginId) {
1888
2060
  let choice = "overwrite";
@@ -1923,6 +2095,73 @@ async function installPlugin(opts) {
1923
2095
  logger.success(`${t("backup_created")}: ${backupInfo.filePath}`);
1924
2096
  }
1925
2097
  }
2098
+ const pluginManifest = readPluginManifest(pluginDir);
2099
+ if (pluginManifest) {
2100
+ const result = await installViaManifest(
2101
+ pluginManifest,
2102
+ pluginDir,
2103
+ opts.repoPath,
2104
+ opts.tool,
2105
+ opts.level,
2106
+ opts.installPath
2107
+ );
2108
+ if (result.success) {
2109
+ try {
2110
+ const record = scanInstalledFiles(
2111
+ opts.pluginId,
2112
+ plugin.displayName,
2113
+ opts.tool,
2114
+ opts.level,
2115
+ cwd,
2116
+ configRoot,
2117
+ result.manifest
2118
+ );
2119
+ if (backupInfo) {
2120
+ record.backup = {
2121
+ filePath: backupInfo.filePath,
2122
+ fromPluginId: backupInfo.pluginId,
2123
+ fromPluginName: backupInfo.pluginName,
2124
+ backupTime: backupInfo.backupTime
2125
+ };
2126
+ }
2127
+ writeRecord(record);
2128
+ } catch {
2129
+ logger.warn(t("record_write_failed"));
2130
+ }
2131
+ return {
2132
+ success: true,
2133
+ pluginId: opts.pluginId,
2134
+ skillsCount: result.skillsCount,
2135
+ agentsCount: result.agentsCount,
2136
+ errors: result.errors,
2137
+ warnings: []
2138
+ };
2139
+ } else {
2140
+ return {
2141
+ success: false,
2142
+ pluginId: opts.pluginId,
2143
+ skillsCount: 0,
2144
+ agentsCount: 0,
2145
+ errors: result.errors,
2146
+ warnings: []
2147
+ };
2148
+ }
2149
+ }
2150
+ const scriptPath = join12(pluginDir, plugin.script);
2151
+ if (!existsSync12(scriptPath)) {
2152
+ return {
2153
+ success: false,
2154
+ pluginId: opts.pluginId,
2155
+ skillsCount: 0,
2156
+ agentsCount: 0,
2157
+ errors: [t("error_script_not_found").replace("{path}", scriptPath)],
2158
+ warnings: []
2159
+ };
2160
+ }
2161
+ const args = [opts.level, opts.tool];
2162
+ if (opts.installPath) {
2163
+ args.push(opts.installPath);
2164
+ }
1926
2165
  try {
1927
2166
  const shell = process.platform === "win32" ? "sh" : "bash";
1928
2167
  const execOptions = {
@@ -1931,7 +2170,7 @@ async function installPlugin(opts) {
1931
2170
  stdio: "pipe",
1932
2171
  input: opts.yes ? "y\n" : void 0
1933
2172
  };
1934
- await execa3(shell, [scriptPath, ...args], execOptions);
2173
+ await execa4(shell, [scriptPath, ...args], execOptions);
1935
2174
  const manifest = readManifest(configRoot);
1936
2175
  let skillsCount = 0;
1937
2176
  let agentsCount = 0;
@@ -1986,17 +2225,17 @@ async function installPlugin(opts) {
1986
2225
  }
1987
2226
 
1988
2227
  // src/core/skill-installer.ts
1989
- import { existsSync as existsSync12, mkdirSync as mkdirSync5, symlinkSync, unlinkSync as unlinkSync4, readdirSync as readdirSync4, rmdirSync, realpathSync } from "fs";
1990
- import { join as join12, dirname as dirname6 } from "path";
2228
+ import { existsSync as existsSync13, mkdirSync as mkdirSync6, symlinkSync as symlinkSync2, unlinkSync as unlinkSync5, readdirSync as readdirSync4, rmdirSync, realpathSync as realpathSync2 } from "fs";
2229
+ import { join as join13, dirname as dirname7 } from "path";
1991
2230
  import { select as select3, checkbox as checkbox2, Separator as Separator2 } from "@inquirer/prompts";
1992
2231
  import chalk5 from "chalk";
1993
2232
  import Table from "cli-table3";
1994
2233
  async function installSkills(skillIds, tool, level, repoPath) {
1995
2234
  const configRoot = getConfigRoot(tool, level);
1996
- const skillsDir = join12(configRoot, "skills");
2235
+ const skillsDir = join13(configRoot, "skills");
1997
2236
  const installPath = level === "project" ? process.cwd() : configRoot;
1998
- if (!existsSync12(skillsDir)) {
1999
- mkdirSync5(skillsDir, { recursive: true });
2237
+ if (!existsSync13(skillsDir)) {
2238
+ mkdirSync6(skillsDir, { recursive: true });
2000
2239
  }
2001
2240
  const results = [];
2002
2241
  const installedIds = [];
@@ -2007,17 +2246,17 @@ async function installSkills(skillIds, tool, level, repoPath) {
2007
2246
  continue;
2008
2247
  }
2009
2248
  const sourcePath = resolveSkillSourcePath(skill, repoPath);
2010
- const targetPath = join12(skillsDir, skillId);
2011
- if (!existsSync12(sourcePath)) {
2249
+ const targetPath = join13(skillsDir, skillId);
2250
+ if (!existsSync13(sourcePath)) {
2012
2251
  results.push({ skillId, success: false, error: t("error_source_not_found").replace("{path}", sourcePath) });
2013
2252
  continue;
2014
2253
  }
2015
2254
  try {
2016
- const resolvedSource = realpathSync(sourcePath);
2017
- if (existsSync12(targetPath) || isSymlink(targetPath)) {
2018
- unlinkSync4(targetPath);
2255
+ const resolvedSource = realpathSync2(sourcePath);
2256
+ if (existsSync13(targetPath) || isSymlink(targetPath)) {
2257
+ unlinkSync5(targetPath);
2019
2258
  }
2020
- symlinkSync(resolvedSource, targetPath);
2259
+ symlinkSync2(resolvedSource, targetPath);
2021
2260
  results.push({ skillId, success: true });
2022
2261
  installedIds.push(skillId);
2023
2262
  } catch (error) {
@@ -2035,15 +2274,15 @@ async function installSkills(skillIds, tool, level, repoPath) {
2035
2274
  }
2036
2275
  async function uninstallSkills(skillIds, tool, level) {
2037
2276
  const configRoot = getConfigRoot(tool, level);
2038
- const skillsDir = join12(configRoot, "skills");
2277
+ const skillsDir = join13(configRoot, "skills");
2039
2278
  const installPath = level === "project" ? process.cwd() : configRoot;
2040
2279
  const results = [];
2041
2280
  const removedIds = [];
2042
2281
  for (const skillId of skillIds) {
2043
- const targetPath = join12(skillsDir, skillId);
2282
+ const targetPath = join13(skillsDir, skillId);
2044
2283
  try {
2045
- if (existsSync12(targetPath) || isSymlink(targetPath)) {
2046
- unlinkSync4(targetPath);
2284
+ if (existsSync13(targetPath) || isSymlink(targetPath)) {
2285
+ unlinkSync5(targetPath);
2047
2286
  results.push({ skillId, success: true });
2048
2287
  removedIds.push(skillId);
2049
2288
  logger.step(` ${t("uninstall_remove_label")}: ${skillId}`);
@@ -2058,7 +2297,7 @@ async function uninstallSkills(skillIds, tool, level) {
2058
2297
  if (removedIds.length > 0) {
2059
2298
  removeSkillsFromRecord(removedIds, tool, level, installPath);
2060
2299
  }
2061
- if (existsSync12(skillsDir)) {
2300
+ if (existsSync13(skillsDir)) {
2062
2301
  try {
2063
2302
  const entries = readdirSync4(skillsDir);
2064
2303
  if (entries.length === 0) {
@@ -2241,12 +2480,12 @@ function listAllSkills() {
2241
2480
  }
2242
2481
  function resolveSkillSourcePath(skill, repoPath) {
2243
2482
  if (skill.filePath) {
2244
- const absPath = skill.filePath.startsWith("/") ? skill.filePath : join12(repoPath, skill.filePath);
2245
- if (existsSync12(absPath)) {
2246
- return dirname6(absPath);
2483
+ const absPath = skill.filePath.startsWith("/") ? skill.filePath : join13(repoPath, skill.filePath);
2484
+ if (existsSync13(absPath)) {
2485
+ return dirname7(absPath);
2247
2486
  }
2248
2487
  }
2249
- return join12(repoPath, skill.source, skill.id);
2488
+ return join13(repoPath, skill.source, skill.id);
2250
2489
  }
2251
2490
 
2252
2491
  // src/ui/display.ts
@@ -2338,13 +2577,13 @@ function printEnhancedSummary(results, tool, configRoot) {
2338
2577
  }
2339
2578
 
2340
2579
  // src/commands/init.ts
2341
- import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
2342
- import { join as join13 } from "path";
2580
+ import { existsSync as existsSync14, readFileSync as readFileSync9 } from "fs";
2581
+ import { join as join14 } from "path";
2343
2582
  async function initCommand() {
2344
2583
  const cwd = process.cwd();
2345
- if (existsSync13(join13(cwd, "package.json")) && (() => {
2584
+ if (existsSync14(join14(cwd, "package.json")) && (() => {
2346
2585
  try {
2347
- const pkg = JSON.parse(readFileSync8(join13(cwd, "package.json"), "utf-8"));
2586
+ const pkg = JSON.parse(readFileSync9(join14(cwd, "package.json"), "utf-8"));
2348
2587
  return pkg.name === "@cannbot-ai/install-helper";
2349
2588
  } catch {
2350
2589
  return false;
@@ -2569,8 +2808,8 @@ async function listCommand() {
2569
2808
 
2570
2809
  // src/commands/doctor.ts
2571
2810
  import chalk8 from "chalk";
2572
- import { existsSync as existsSync14, readdirSync as readdirSync5, lstatSync as lstatSync2, unlinkSync as unlinkSync5, mkdirSync as mkdirSync6 } from "fs";
2573
- import { join as join14 } from "path";
2811
+ import { existsSync as existsSync15, readdirSync as readdirSync5, lstatSync as lstatSync2, unlinkSync as unlinkSync6, mkdirSync as mkdirSync7 } from "fs";
2812
+ import { join as join15 } from "path";
2574
2813
  async function doctorCommand(options = {}) {
2575
2814
  console.log();
2576
2815
  console.log(chalk8.bold(` ${t("doctor_title")}`));
@@ -2612,7 +2851,7 @@ async function doctorCommand(options = {}) {
2612
2851
  const configRoot = getConfigRoot(primaryTool, "project");
2613
2852
  const skillsDir = getSkillsDir(configRoot);
2614
2853
  const agentsDir = getAgentsDir(configRoot);
2615
- if (existsSync14(skillsDir)) {
2854
+ if (existsSync15(skillsDir)) {
2616
2855
  const brokenLinks = checkBrokenLinks(skillsDir);
2617
2856
  if (brokenLinks === 0) {
2618
2857
  const count = readdirSync5(skillsDir).length;
@@ -2629,12 +2868,12 @@ async function doctorCommand(options = {}) {
2629
2868
  } else {
2630
2869
  console.log(chalk8.dim(" \u2014") + ` ${skillsDir} \u2014 ${t("doctor_not_exist")}`);
2631
2870
  if (options.fix) {
2632
- mkdirSync6(skillsDir, { recursive: true });
2871
+ mkdirSync7(skillsDir, { recursive: true });
2633
2872
  fixes++;
2634
2873
  console.log(chalk8.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: ${t("doctor_created").replace("{path}", skillsDir)}`);
2635
2874
  }
2636
2875
  }
2637
- if (existsSync14(agentsDir)) {
2876
+ if (existsSync15(agentsDir)) {
2638
2877
  const brokenLinks = checkBrokenLinks(agentsDir);
2639
2878
  if (brokenLinks === 0) {
2640
2879
  const count = readdirSync5(agentsDir).length;
@@ -2651,7 +2890,7 @@ async function doctorCommand(options = {}) {
2651
2890
  } else {
2652
2891
  console.log(chalk8.dim(" \u2014") + ` ${agentsDir} \u2014 ${t("doctor_not_exist")}`);
2653
2892
  if (options.fix) {
2654
- mkdirSync6(agentsDir, { recursive: true });
2893
+ mkdirSync7(agentsDir, { recursive: true });
2655
2894
  fixes++;
2656
2895
  console.log(chalk8.green(" \u2713") + ` ${t("doctor_fix_rebuilding")}: ${t("doctor_created").replace("{path}", agentsDir)}`);
2657
2896
  }
@@ -2659,8 +2898,8 @@ async function doctorCommand(options = {}) {
2659
2898
  console.log();
2660
2899
  console.log(chalk8.bold(` ${t("doctor_config")}`));
2661
2900
  const configFile = getConfigFileName(primaryTool);
2662
- const configPath = join14(process.cwd(), configFile);
2663
- if (existsSync14(configPath)) {
2901
+ const configPath = join15(process.cwd(), configFile);
2902
+ if (existsSync15(configPath)) {
2664
2903
  console.log(chalk8.green(" \u2713") + ` ${configFile} ${t("doctor_config_exists")}`);
2665
2904
  } else {
2666
2905
  console.log(chalk8.dim(" \u2014") + ` ${configFile} ${t("doctor_config_not_exist")}`);
@@ -2683,11 +2922,11 @@ function checkBrokenLinks(dir) {
2683
2922
  try {
2684
2923
  const entries = readdirSync5(dir);
2685
2924
  for (const entry of entries) {
2686
- const fullPath = join14(dir, entry);
2925
+ const fullPath = join15(dir, entry);
2687
2926
  try {
2688
2927
  const stats = lstatSync2(fullPath);
2689
2928
  if (stats.isSymbolicLink()) {
2690
- if (!existsSync14(fullPath)) {
2929
+ if (!existsSync15(fullPath)) {
2691
2930
  broken++;
2692
2931
  }
2693
2932
  }
@@ -2704,12 +2943,12 @@ function fixBrokenLinks(dir) {
2704
2943
  try {
2705
2944
  const entries = readdirSync5(dir);
2706
2945
  for (const entry of entries) {
2707
- const fullPath = join14(dir, entry);
2946
+ const fullPath = join15(dir, entry);
2708
2947
  try {
2709
2948
  const stats = lstatSync2(fullPath);
2710
2949
  if (stats.isSymbolicLink()) {
2711
- if (!existsSync14(fullPath)) {
2712
- unlinkSync5(fullPath);
2950
+ if (!existsSync15(fullPath)) {
2951
+ unlinkSync6(fullPath);
2713
2952
  fixed++;
2714
2953
  }
2715
2954
  }
@@ -3054,8 +3293,8 @@ async function installPlugins(pluginIds, tool, level, repoPath, installPath, yes
3054
3293
  }
3055
3294
 
3056
3295
  // src/commands/uninstall.ts
3057
- import { existsSync as existsSync15, unlinkSync as unlinkSync6, rmdirSync as rmdirSync2, readdirSync as readdirSync6 } from "fs";
3058
- import { resolve, basename } from "path";
3296
+ import { existsSync as existsSync16, unlinkSync as unlinkSync7, rmdirSync as rmdirSync2, readdirSync as readdirSync6 } from "fs";
3297
+ import { resolve, basename as basename2 } from "path";
3059
3298
  import chalk11 from "chalk";
3060
3299
  async function uninstallCommand(names, options) {
3061
3300
  const tool = options.tool ? validateTool(options.tool) : "opencode";
@@ -3096,9 +3335,9 @@ async function uninstallCommand(names, options) {
3096
3335
  for (const filePath of record.files) {
3097
3336
  if (!isSafePath(filePath)) continue;
3098
3337
  try {
3099
- if (existsSync15(filePath) || isSymlink(filePath)) {
3100
- unlinkSync6(filePath);
3101
- const name = basename(filePath);
3338
+ if (existsSync16(filePath) || isSymlink(filePath)) {
3339
+ unlinkSync7(filePath);
3340
+ const name = basename2(filePath);
3102
3341
  logger.step(` ${t("uninstall_remove_label")}: ${name}`);
3103
3342
  removedFiles++;
3104
3343
  }
@@ -3111,11 +3350,11 @@ async function uninstallCommand(names, options) {
3111
3350
  if (resolve(dirPath) === resolve(configRoot)) {
3112
3351
  continue;
3113
3352
  }
3114
- if (existsSync15(dirPath)) {
3353
+ if (existsSync16(dirPath)) {
3115
3354
  const entries = readdirSync6(dirPath);
3116
3355
  if (entries.length === 0) {
3117
3356
  rmdirSync2(dirPath);
3118
- const name = basename(dirPath);
3357
+ const name = basename2(dirPath);
3119
3358
  logger.step(` ${t("uninstall_clean_empty_dir")}: ${name}/`);
3120
3359
  removedDirs++;
3121
3360
  }
@@ -3250,8 +3489,8 @@ async function updateCommand(pluginNames, options) {
3250
3489
 
3251
3490
  // src/commands/info.ts
3252
3491
  import chalk13 from "chalk";
3253
- import { existsSync as existsSync16, readdirSync as readdirSync7 } from "fs";
3254
- import { join as join15 } from "path";
3492
+ import { existsSync as existsSync17, readdirSync as readdirSync7 } from "fs";
3493
+ import { join as join16 } from "path";
3255
3494
  async function infoCommand(pluginName) {
3256
3495
  const plugin = findPlugin(pluginName);
3257
3496
  if (!plugin) {
@@ -3276,12 +3515,12 @@ async function infoCommand(pluginName) {
3276
3515
  try {
3277
3516
  const repoManager = createRepositoryManager();
3278
3517
  const repoPath = await repoManager.ensureRepo();
3279
- const quickstartPath = join15(repoPath, plugin.dir, "quickstart.md");
3280
- if (existsSync16(quickstartPath)) {
3518
+ const quickstartPath = join16(repoPath, plugin.dir, "quickstart.md");
3519
+ if (existsSync17(quickstartPath)) {
3281
3520
  console.log(` ${chalk13.dim(t("info_quickstart") + ":")} ${quickstartPath}`);
3282
3521
  }
3283
- const agentsDir = join15(repoPath, plugin.dir, "agents");
3284
- if (existsSync16(agentsDir)) {
3522
+ const agentsDir = join16(repoPath, plugin.dir, "agents");
3523
+ if (existsSync17(agentsDir)) {
3285
3524
  const agentFiles = readdirSync7(agentsDir).filter((f) => f.endsWith(".md"));
3286
3525
  if (agentFiles.length > 0) {
3287
3526
  console.log();
@@ -3333,15 +3572,15 @@ async function langCommand(action, value) {
3333
3572
  }
3334
3573
 
3335
3574
  // src/cli.ts
3336
- import { readFileSync as readFileSync9 } from "fs";
3575
+ import { readFileSync as readFileSync10 } from "fs";
3337
3576
  import { fileURLToPath as fileURLToPath5 } from "url";
3338
- import { dirname as dirname7, join as join16 } from "path";
3577
+ import { dirname as dirname8, join as join17 } from "path";
3339
3578
  function readVersion() {
3340
3579
  try {
3341
3580
  const __filename5 = fileURLToPath5(import.meta.url);
3342
- const __dirname5 = dirname7(__filename5);
3343
- const pkgPath = join16(__dirname5, "..", "package.json");
3344
- const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
3581
+ const __dirname5 = dirname8(__filename5);
3582
+ const pkgPath = join17(__dirname5, "..", "package.json");
3583
+ const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
3345
3584
  return pkg.version || "0.0.0";
3346
3585
  } catch {
3347
3586
  return "0.0.0";