@cannbot-ai/install-helper 1.2.0-beta.0 → 1.2.0-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 CHANGED
@@ -280,6 +280,7 @@ var init_zh_CN = __esm({
280
280
  cannbot_plugin_not_found: "cannbot \u5B89\u88C5\u5668\u5305\u4E2D\u672A\u627E\u5230\u63D2\u4EF6 {plugin}",
281
281
  cannbot_registry_missing: "\u5B89\u88C5\u540E\u672A\u5728 cannbot-plugin.json \u4E2D\u627E\u5230\u6CE8\u518C\u8BB0\u5F55",
282
282
  cannbot_delegate_failed: "cannbot \u5B89\u88C5\u5668\u6267\u884C\u5931\u8D25\uFF08\u9000\u51FA\u7801 {code}\uFF09\uFF0C\u8F93\u51FA\u89C1\u4E0A\u65B9\u65E5\u5FD7",
283
+ cannbot_bundled_fallback: "\u4E0A\u6E38\u5B89\u88C5\u5668\u6682\u4E0D\u8BC6\u522B\u65B0\u7248 plugins-official \u76EE\u5F55\uFF08\u7B49\u5F85\u5176\u53D1\u7248\u4FEE\u590D\uFF09\uFF0C\u5DF2\u81EA\u52A8\u56DE\u9000\u4E3A\u5B89\u88C5\u5668\u5305\u5185\u7F6E\u5FEB\u7167\uFF08--bundled\uFF09\u5B8C\u6210\u5B89\u88C5",
283
284
  cannbot_migrated_symlink: "\u68C0\u6D4B\u5230 {file} \u4E3A\u65E7\u7248\u63D2\u4EF6\u8F6F\u94FE\uFF0C\u5DF2\u8F6C\u4E3A\u771F\u5B9E\u6587\u4EF6\uFF08\u5185\u5BB9\u4FDD\u7559\u5E76\u5DF2\u5907\u4EFD\uFF09",
284
285
  cannbot_migrate_symlink_failed: "\u65E7\u7248\u8F6F\u94FE {file} \u8F6C\u771F\u5B9E\u6587\u4EF6\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\u540E\u91CD\u8BD5",
285
286
  cannbot_dual_skill_copy: "\u4EE5\u4E0B Skills \u540C\u65F6\u5B58\u5728\u4E8E\u65B0\u65E7\u4E24\u5957\u5E03\u5C40\u4E2D\uFF0CAI \u5DE5\u5177\u4F1A\u770B\u5230\u4E24\u4EFD\u526F\u672C: {skills}",
@@ -530,6 +531,7 @@ var init_en_US = __esm({
530
531
  cannbot_plugin_not_found: "Plugin {plugin} was not found in the cannbot installer package",
531
532
  cannbot_registry_missing: "No cannbot-plugin.json record found after installation",
532
533
  cannbot_delegate_failed: "The cannbot installer exited with code {code}; see the output above",
534
+ cannbot_bundled_fallback: "The upstream installer predates the plugins-official rename (pending its next release); automatically fell back to the installer package's bundled snapshot (--bundled)",
533
535
  cannbot_migrated_symlink: "{file} was a legacy plugin symlink; converted to a real file (content kept, backup saved)",
534
536
  cannbot_migrate_symlink_failed: "Failed to convert the legacy symlink {file} to a real file; resolve it manually and retry",
535
537
  cannbot_dual_skill_copy: "These Skills exist in both the legacy and cannbot layouts, the AI tool will see two copies: {skills}",
@@ -3079,7 +3081,12 @@ function discoverCannbotPlugins() {
3079
3081
  }
3080
3082
  const packageRoot = getCannbotPackageRoot();
3081
3083
  const entries = [];
3082
- const parents = [join10(packageRoot, "dist", "plugins"), join10(packageRoot, "plugins")];
3084
+ const parents = [
3085
+ join10(packageRoot, "dist", "plugins"),
3086
+ join10(packageRoot, "dist", "plugins-official"),
3087
+ join10(packageRoot, "plugins"),
3088
+ join10(packageRoot, "plugins-official")
3089
+ ];
3083
3090
  for (const parent of parents) {
3084
3091
  if (!existsSync11(parent)) continue;
3085
3092
  let names = [];
@@ -3549,6 +3556,45 @@ function cleanCodexNativePlugin(record, pluginId) {
3549
3556
  }
3550
3557
  }
3551
3558
  }
3559
+ function cleanOpenCodePluginRegistration(root) {
3560
+ const configPath = join12(root, ".opencode", "opencode.json");
3561
+ if (!existsSync13(configPath)) return;
3562
+ let config;
3563
+ try {
3564
+ config = JSON.parse(readFileSync9(configPath, "utf-8"));
3565
+ } catch {
3566
+ return;
3567
+ }
3568
+ if (!Array.isArray(config.plugin)) return;
3569
+ const CLEAN_PACKAGE_PREFIX = "@cannbot-plugin/cannbot";
3570
+ config.plugin = config.plugin.filter(
3571
+ (entry) => !(typeof entry === "string" && entry.startsWith(CLEAN_PACKAGE_PREFIX))
3572
+ );
3573
+ try {
3574
+ if (Array.isArray(config.plugin) && config.plugin.length === 0) {
3575
+ delete config.plugin;
3576
+ }
3577
+ if (Object.keys(config).length === 0) {
3578
+ unlinkSync4(configPath);
3579
+ removeOpenCodePluginGitignore(dirname6(configPath));
3580
+ } else {
3581
+ writeFileSync3(configPath, `${JSON.stringify(config, null, 2)}
3582
+ `);
3583
+ }
3584
+ } catch {
3585
+ }
3586
+ }
3587
+ function removeOpenCodePluginGitignore(configDir) {
3588
+ const gitignorePath = join12(configDir, ".gitignore");
3589
+ if (!existsSync13(gitignorePath)) return;
3590
+ try {
3591
+ const content = readFileSync9(gitignorePath, "utf-8");
3592
+ if (content.includes("bun.lock") && content.includes("node_modules")) {
3593
+ unlinkSync4(gitignorePath);
3594
+ }
3595
+ } catch {
3596
+ }
3597
+ }
3552
3598
  function uninstallCannbotPlugin(pluginId, target) {
3553
3599
  const result = {
3554
3600
  success: false,
@@ -3640,6 +3686,9 @@ function uninstallCannbotPlugin(pluginId, target) {
3640
3686
  if (record.nativePlugin && typeof record.nativePlugin === "object" && record.nativePlugin.package) {
3641
3687
  logger.warn(t("cannbot_uninstall_native_hint").replace("{spec}", String(record.nativePlugin.package)));
3642
3688
  }
3689
+ if (record.tool === "opencode" && siblings.length === 0) {
3690
+ cleanOpenCodePluginRegistration(root);
3691
+ }
3643
3692
  try {
3644
3693
  const registry = JSON.parse(readFileSync9(registryPath, "utf-8"));
3645
3694
  registry.plugins = registry.plugins.filter((r) => r?.plugin !== pluginId);
@@ -4489,6 +4538,31 @@ function skillNameFromPath(rel) {
4489
4538
  const parts = rel.split("/");
4490
4539
  return parts[parts.length - 1] || rel;
4491
4540
  }
4541
+ async function runDelegate(args, target) {
4542
+ try {
4543
+ const result = await execa6("node", [getCannbotBinPath(), ...args], {
4544
+ cwd: target,
4545
+ timeout: 6e5
4546
+ });
4547
+ process.stdout.write(result.stdout || "");
4548
+ process.stderr.write(result.stderr || "");
4549
+ return { ok: true, stdout: result.stdout || "", stderr: result.stderr || "", exitCode: 0 };
4550
+ } catch (error) {
4551
+ const err = error;
4552
+ process.stdout.write(err.stdout || "");
4553
+ process.stderr.write(err.stderr || "");
4554
+ if (!err.stdout && !err.stderr && err.message) {
4555
+ process.stderr.write(`${err.message}
4556
+ `);
4557
+ }
4558
+ return {
4559
+ ok: false,
4560
+ stdout: err.stdout || "",
4561
+ stderr: err.stderr || "",
4562
+ exitCode: err.exitCode
4563
+ };
4564
+ }
4565
+ }
4492
4566
  async function delegateInstall(options) {
4493
4567
  const { pluginId, tool, level } = options;
4494
4568
  const target = resolve2(options.target || process.cwd());
@@ -4531,23 +4605,20 @@ async function delegateInstall(options) {
4531
4605
  }
4532
4606
  }
4533
4607
  result.warnings.push(...migrateSymlinkedInstructions(target, tool));
4534
- try {
4535
- await execa6(
4536
- "node",
4537
- [getCannbotBinPath(), "install", pluginId, "--tool", tool, "--target", target],
4538
- {
4539
- cwd: target,
4540
- stdout: "inherit",
4541
- stderr: "inherit",
4542
- timeout: 6e5
4543
- }
4608
+ let run = await runDelegate(["install", pluginId, "--tool", tool, "--target", target], target);
4609
+ const hitRenameGap = !run.ok && (run.stdout.includes(`plugin not found: ${pluginId}`) || run.stderr.includes(`plugin not found: ${pluginId}`));
4610
+ if (hitRenameGap) {
4611
+ result.warnings.push(t("cannbot_bundled_fallback"));
4612
+ run = await runDelegate(
4613
+ ["install", pluginId, "--tool", tool, "--target", target, "--bundled"],
4614
+ target
4544
4615
  );
4545
- } catch (error) {
4546
- const exitCode = error.exitCode;
4616
+ }
4617
+ if (!run.ok) {
4547
4618
  result.errors.push(
4548
4619
  t("cannbot_delegate_failed").replace(
4549
4620
  "{code}",
4550
- exitCode !== void 0 ? String(exitCode) : "?"
4621
+ run.exitCode !== void 0 ? String(run.exitCode) : "?"
4551
4622
  )
4552
4623
  );
4553
4624
  return result;