bitfab-cli 0.2.237 → 0.2.238

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.
Files changed (2) hide show
  1. package/dist/index.js +151 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26491,6 +26491,28 @@ import fs18 from "fs";
26491
26491
  import fs19 from "fs";
26492
26492
  import os14 from "os";
26493
26493
  import path16 from "path";
26494
+ var INSTALL_SCOPES = ["user", "project", "local", "managed"];
26495
+ function isInstallScope(value) {
26496
+ return typeof value === "string" && INSTALL_SCOPES.includes(value);
26497
+ }
26498
+ function pluginUpdateScopes(scopes) {
26499
+ return scopes.length > 0 ? [...scopes] : ["user"];
26500
+ }
26501
+ function installScopeAppliesToProject(projectPath, projectDir) {
26502
+ if (typeof projectPath !== "string" || projectPath.trim() === "") {
26503
+ return true;
26504
+ }
26505
+ const project = canonicalPath(projectPath);
26506
+ const current = canonicalPath(projectDir);
26507
+ return current === project || current.startsWith(`${project}${path16.sep}`);
26508
+ }
26509
+ function canonicalPath(target) {
26510
+ try {
26511
+ return fs19.realpathSync(path16.resolve(target));
26512
+ } catch {
26513
+ return path16.resolve(target);
26514
+ }
26515
+ }
26494
26516
 
26495
26517
  // ../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_@cfworker+json-schema@4.1.1_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
26496
26518
  var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
@@ -28481,6 +28503,59 @@ import os15 from "os";
28481
28503
  import path17 from "path";
28482
28504
  import * as p3 from "@clack/prompts";
28483
28505
 
28506
+ // src/claudePlugins.ts
28507
+ function parseJson(text) {
28508
+ try {
28509
+ return JSON.parse(text);
28510
+ } catch {
28511
+ return void 0;
28512
+ }
28513
+ }
28514
+ function parseListArray(output) {
28515
+ const direct = parseJson(output.trim());
28516
+ if (direct !== void 0) {
28517
+ return Array.isArray(direct) ? direct : null;
28518
+ }
28519
+ const start = output.indexOf("[");
28520
+ const end = output.lastIndexOf("]");
28521
+ if (start === -1 || end < start) {
28522
+ return null;
28523
+ }
28524
+ const sliced = parseJson(output.slice(start, end + 1));
28525
+ return Array.isArray(sliced) ? sliced : null;
28526
+ }
28527
+ function resolveClaudePluginInstall(listOutput, pluginKey, cwd) {
28528
+ const parsed = parseListArray(listOutput);
28529
+ if (parsed === null) {
28530
+ return null;
28531
+ }
28532
+ const entries = parsed.filter(
28533
+ (raw) => typeof raw === "object" && raw !== null
28534
+ );
28535
+ if (entries.length > 0 && !entries.some((entry) => typeof entry.id === "string")) {
28536
+ return null;
28537
+ }
28538
+ const scopes = [];
28539
+ let found = false;
28540
+ let enabled = false;
28541
+ for (const entry of entries) {
28542
+ if (entry.id !== pluginKey || !installScopeAppliesToProject(entry.projectPath, cwd)) {
28543
+ continue;
28544
+ }
28545
+ found = true;
28546
+ if (entry.enabled === true) {
28547
+ enabled = true;
28548
+ }
28549
+ if (isInstallScope(entry.scope) && !scopes.includes(entry.scope)) {
28550
+ scopes.push(entry.scope);
28551
+ }
28552
+ }
28553
+ if (!found) {
28554
+ return { state: "missing", scopes: [] };
28555
+ }
28556
+ return { state: enabled ? "enabled" : "disabled", scopes };
28557
+ }
28558
+
28484
28559
  // src/cliEditor.ts
28485
28560
  import * as p2 from "@clack/prompts";
28486
28561
 
@@ -28721,32 +28796,24 @@ function runClaudeInstall() {
28721
28796
  } else {
28722
28797
  s.stop("Auto-updates already enabled");
28723
28798
  }
28724
- const state = pluginState();
28725
- if (state === "missing") {
28799
+ const install = pluginInstall();
28800
+ if (install.state === "missing") {
28726
28801
  s.start("Installing bitfab plugin");
28727
28802
  runCli(CLI, ["plugin", "install", PLUGIN_KEY, "--scope", "user"]);
28728
28803
  s.stop("Plugin installed");
28729
28804
  } else {
28730
- if (state === "disabled") {
28805
+ if (install.state === "disabled") {
28731
28806
  runCli(CLI, ["plugin", "enable", PLUGIN_KEY]);
28732
28807
  p3.log.step("Plugin enabled");
28733
28808
  }
28734
- ensureLatestClaudePlugin();
28809
+ ensureLatestPlugin(() => pullLatestClaudePlugin(install.scopes));
28735
28810
  }
28736
28811
  p3.log.success("Bitfab plugin ready in Claude Code");
28737
28812
  }
28738
- function activeLocalClaudeBitfabPlugin() {
28739
- const settingsPath = path17.join(
28740
- process.cwd(),
28741
- ".claude",
28742
- "settings.local.json"
28743
- );
28744
- if (!fs20.existsSync(settingsPath)) {
28745
- return null;
28746
- }
28813
+ function enabledForeignBitfabPlugin(settingsJson) {
28747
28814
  let settings;
28748
28815
  try {
28749
- settings = JSON.parse(fs20.readFileSync(settingsPath, "utf-8"));
28816
+ settings = JSON.parse(settingsJson);
28750
28817
  } catch {
28751
28818
  return null;
28752
28819
  }
@@ -28766,12 +28833,57 @@ function activeLocalClaudeBitfabPlugin() {
28766
28833
  }
28767
28834
  return null;
28768
28835
  }
28769
- function pullLatestClaudePlugin() {
28836
+ function activeLocalClaudeBitfabPlugin() {
28837
+ const settingsPaths = [
28838
+ path17.join(process.cwd(), ".claude", "settings.local.json"),
28839
+ path17.join(process.cwd(), ".claude", "settings.json"),
28840
+ path17.join(os15.homedir(), ".claude", "settings.json")
28841
+ ];
28842
+ for (const settingsPath of settingsPaths) {
28843
+ if (!fs20.existsSync(settingsPath)) {
28844
+ continue;
28845
+ }
28846
+ let contents;
28847
+ try {
28848
+ contents = fs20.readFileSync(settingsPath, "utf-8");
28849
+ } catch {
28850
+ continue;
28851
+ }
28852
+ const key = enabledForeignBitfabPlugin(contents);
28853
+ if (key !== null) {
28854
+ return key;
28855
+ }
28856
+ }
28857
+ return null;
28858
+ }
28859
+ function pullLatestClaudePlugin(scopes = pluginInstall().scopes) {
28770
28860
  runCli(CLI, ["plugin", "marketplace", "update", MARKETPLACE]);
28771
- return runCli(CLI, ["plugin", "update", PLUGIN_KEY, "--scope", "user"]);
28861
+ const targets = pluginUpdateScopes(scopes);
28862
+ const outputs = [];
28863
+ const failures = [];
28864
+ for (const scope of targets) {
28865
+ const args = ["plugin", "update", PLUGIN_KEY, "--scope", scope];
28866
+ const result = runCliResult(CLI, args);
28867
+ if (result.status === 0 && !result.error) {
28868
+ outputs.push(result.output);
28869
+ } else {
28870
+ failures.push(
28871
+ `${CLI} ${args.join(" ")} failed${result.status === null ? "" : ` with status ${result.status}`}${result.output.trim() ? `
28872
+ ${result.output.trim()}` : ""}`
28873
+ );
28874
+ }
28875
+ }
28876
+ return pluginRefreshOutput(outputs, failures, targets.length);
28877
+ }
28878
+ function pluginRefreshOutput(outputs, failures, scopeCount) {
28879
+ if (failures.length > 0) {
28880
+ const partial2 = outputs.length > 0 ? [`${outputs.length} of ${scopeCount} scopes updated.`] : [];
28881
+ throw new Error([...failures, ...partial2].join("\n"));
28882
+ }
28883
+ return outputs.find((out) => !pluginOutputIsUpToDate(out)) ?? outputs[outputs.length - 1] ?? "";
28772
28884
  }
28773
28885
  function ensureLatestClaudePlugin() {
28774
- ensureLatestPlugin(pullLatestClaudePlugin);
28886
+ ensureLatestPlugin(() => pullLatestClaudePlugin());
28775
28887
  }
28776
28888
  async function runClaudeAnalyzeRepo(captureOverride, limit, prompt) {
28777
28889
  const auth = checkClaudeAuth();
@@ -29542,13 +29654,30 @@ function analyzeRepoLogPath() {
29542
29654
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
29543
29655
  return path17.join(dir, `analyze-repo-${stamp}.jsonl`);
29544
29656
  }
29545
- function pluginState() {
29546
- const listOut = runCli(CLI, ["plugin", "list"]);
29657
+ function pluginInstall() {
29658
+ const jsonOut = runCliOrNull(["plugin", "list", "--json"]);
29659
+ const resolved = jsonOut === null ? null : resolveClaudePluginInstall(jsonOut, PLUGIN_KEY, process.cwd());
29660
+ if (resolved !== null) {
29661
+ return resolved;
29662
+ }
29663
+ return {
29664
+ state: pluginStateFromText(runCli(CLI, ["plugin", "list"])),
29665
+ scopes: []
29666
+ };
29667
+ }
29668
+ function runCliOrNull(args) {
29669
+ try {
29670
+ return runCli(CLI, args);
29671
+ } catch {
29672
+ return null;
29673
+ }
29674
+ }
29675
+ function pluginStateFromText(listOut) {
29547
29676
  const key = PLUGIN_KEY.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
29548
- if (!new RegExp(key).test(listOut)) {
29677
+ if (!new RegExp(`${key}\\s*\\n`).test(listOut)) {
29549
29678
  return "missing";
29550
29679
  }
29551
- return new RegExp(`${key}\\n.*\\n.*\\n.*disabled`).test(listOut) ? "disabled" : "enabled";
29680
+ return new RegExp(`${key}\\s*\\n.*\\n.*\\n.*disabled`).test(listOut) ? "disabled" : "enabled";
29552
29681
  }
29553
29682
  function enableAutoUpdate(settingsPath) {
29554
29683
  let settings = {};
@@ -29579,7 +29708,7 @@ var config2 = {
29579
29708
  assistantCommand: ASSISTANT_COMMAND,
29580
29709
  updateCommand: UPDATE_COMMAND,
29581
29710
  authCheck: checkClaudeAuth,
29582
- pullLatest: pullLatestClaudePlugin
29711
+ pullLatest: () => pullLatestClaudePlugin()
29583
29712
  };
29584
29713
  var claudeAdapter = {
29585
29714
  label: "Claude Code",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitfab-cli",
3
- "version": "0.2.237",
3
+ "version": "0.2.238",
4
4
  "description": "Install and configure the Bitfab plugin in Claude Code, Codex, or Cursor.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",