bitfab-cli 0.2.8 → 0.2.10

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 +128 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6839,6 +6839,7 @@ var GLOBAL_CONFIG_DIR = path3.join(os3.homedir(), ".config", "bitfab");
6839
6839
  var GLOBAL_CONFIG_FILE = path3.join(GLOBAL_CONFIG_DIR, "config.json");
6840
6840
  var GLOBAL_CREDENTIALS_FILE = path3.join(GLOBAL_CONFIG_DIR, "credentials.json");
6841
6841
  var PROJECT_CONFIG_RELATIVE = path3.join(".bitfab", "config.local.json");
6842
+ var PROJECT_CREDENTIALS_RELATIVE = path3.join(".bitfab", "credentials.local.json");
6842
6843
  function readJsonFile(filePath) {
6843
6844
  try {
6844
6845
  const content = fs3.readFileSync(filePath, "utf-8");
@@ -6847,10 +6848,10 @@ function readJsonFile(filePath) {
6847
6848
  return null;
6848
6849
  }
6849
6850
  }
6850
- function findProjectConfigPath(startDir = process.cwd()) {
6851
+ function findProjectFile(relativePath, startDir = process.cwd()) {
6851
6852
  let dir = startDir;
6852
6853
  while (true) {
6853
- const candidate = path3.join(dir, PROJECT_CONFIG_RELATIVE);
6854
+ const candidate = path3.join(dir, relativePath);
6854
6855
  if (fs3.existsSync(candidate)) {
6855
6856
  return candidate;
6856
6857
  }
@@ -6862,12 +6863,19 @@ function findProjectConfigPath(startDir = process.cwd()) {
6862
6863
  }
6863
6864
  }
6864
6865
  function getProjectConfigData() {
6865
- const filePath = findProjectConfigPath();
6866
+ const filePath = findProjectFile(PROJECT_CONFIG_RELATIVE);
6866
6867
  if (!filePath) {
6867
6868
  return null;
6868
6869
  }
6869
6870
  return readJsonFile(filePath);
6870
6871
  }
6872
+ function getProjectCredentialsData() {
6873
+ const filePath = findProjectFile(PROJECT_CREDENTIALS_RELATIVE);
6874
+ if (!filePath) {
6875
+ return null;
6876
+ }
6877
+ return readJsonFile(filePath) ?? {};
6878
+ }
6871
6879
  function getConfigData() {
6872
6880
  return readJsonFile(GLOBAL_CONFIG_FILE) ?? {};
6873
6881
  }
@@ -6889,6 +6897,10 @@ function getApiKey() {
6889
6897
  if (process.env.BITFAB_API_KEY) {
6890
6898
  return process.env.BITFAB_API_KEY;
6891
6899
  }
6900
+ const projectCreds = getProjectCredentialsData();
6901
+ if (projectCreds !== null) {
6902
+ return typeof projectCreds.apiKey === "string" ? projectCreds.apiKey : null;
6903
+ }
6892
6904
  const creds = getCredentialsData();
6893
6905
  return typeof creds.apiKey === "string" ? creds.apiKey : null;
6894
6906
  }
@@ -26831,14 +26843,29 @@ function runClaudeAssistant(args, skipPermissions) {
26831
26843
  });
26832
26844
  }
26833
26845
  function runClaudeUpdate(args, skipPermissions) {
26834
- const cmd = [UPDATE_COMMAND, ...args].join(" ");
26835
- p.log.info(`Launching ${cmd}...
26846
+ const mode = args[0] === "plugin" || args[0] === "sdk" ? args[0] : "all";
26847
+ if (mode === "plugin" || mode === "all") {
26848
+ const s = p.spinner();
26849
+ s.start("Refreshing bitfab marketplace");
26850
+ runClaude(["plugin", "marketplace", "update", MARKETPLACE]);
26851
+ s.stop("Marketplace refreshed");
26852
+ s.start("Updating bitfab plugin");
26853
+ const out = runClaude(["plugin", "update", PLUGIN_KEY, "--scope", "user"]);
26854
+ if (out.includes("already") || out.includes("up to date")) {
26855
+ s.stop("Plugin already up to date");
26856
+ } else {
26857
+ s.stop("Plugin updated");
26858
+ }
26859
+ }
26860
+ if (mode === "sdk" || mode === "all") {
26861
+ p.log.info(`Launching ${UPDATE_COMMAND} sdk...
26836
26862
  `);
26837
- const flags = skipPermissions ? ["--dangerously-skip-permissions"] : [];
26838
- spawnSync("claude", [...flags, UPDATE_COMMAND, ...args], {
26839
- stdio: "inherit",
26840
- ...SHELL_OPTS
26841
- });
26863
+ const flags = skipPermissions ? ["--dangerously-skip-permissions"] : [];
26864
+ spawnSync("claude", [...flags, UPDATE_COMMAND, "sdk"], {
26865
+ stdio: "inherit",
26866
+ ...SHELL_OPTS
26867
+ });
26868
+ }
26842
26869
  }
26843
26870
  function isPluginDisabled() {
26844
26871
  const listOut = runClaude(["plugin", "list"]);
@@ -26943,14 +26970,37 @@ function runCodexAssistant(args, skipPermissions) {
26943
26970
  });
26944
26971
  }
26945
26972
  function runCodexUpdate(args, skipPermissions) {
26946
- const cmd = [UPDATE_COMMAND2, ...args].join(" ");
26947
- p2.log.info(`Launching ${cmd}...
26973
+ const mode = args[0] === "plugin" || args[0] === "sdk" ? args[0] : "all";
26974
+ if (mode === "plugin" || mode === "all") {
26975
+ const s = p2.spinner();
26976
+ s.start("Upgrading bitfab marketplace plugin");
26977
+ const result = spawnSync2(
26978
+ "codex",
26979
+ ["plugin", "marketplace", "upgrade", "bitfab"],
26980
+ { stdio: "pipe", ...SHELL_OPTS2 }
26981
+ );
26982
+ if (result.status !== 0) {
26983
+ s.stop("Marketplace upgrade failed");
26984
+ throw new Error(
26985
+ `codex plugin marketplace upgrade failed${result.status === null ? "" : ` with status ${result.status}`}`
26986
+ );
26987
+ }
26988
+ const out = (result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? "");
26989
+ if (out.includes("already") || out.includes("up to date")) {
26990
+ s.stop("Plugin already up to date");
26991
+ } else {
26992
+ s.stop("Plugin updated");
26993
+ }
26994
+ }
26995
+ if (mode === "sdk" || mode === "all") {
26996
+ p2.log.info(`Launching ${UPDATE_COMMAND2} sdk...
26948
26997
  `);
26949
- const flags = skipPermissions ? ["--full-auto"] : [];
26950
- spawnSync2("codex", [...flags, UPDATE_COMMAND2, ...args], {
26951
- stdio: "inherit",
26952
- ...SHELL_OPTS2
26953
- });
26998
+ const flags = skipPermissions ? ["--full-auto"] : [];
26999
+ spawnSync2("codex", [...flags, UPDATE_COMMAND2, "sdk"], {
27000
+ stdio: "inherit",
27001
+ ...SHELL_OPTS2
27002
+ });
27003
+ }
26954
27004
  }
26955
27005
  function enableCodexPlugin(configPath) {
26956
27006
  let content = "";
@@ -27038,8 +27088,15 @@ function runCursorUpdate(args, skipPermissions) {
27038
27088
  if (skipPermissions) {
27039
27089
  p3.log.warn("--skip-permissions is not supported for Cursor");
27040
27090
  }
27041
- const cmd = [UPDATE_COMMAND3, ...args].join(" ");
27042
- p3.log.info(`To update, run ${cmd} in Cursor.`);
27091
+ const mode = args[0] === "plugin" || args[0] === "sdk" ? args[0] : "all";
27092
+ const lines = [];
27093
+ if (mode === "plugin" || mode === "all") {
27094
+ lines.push(`Run ${UPDATE_COMMAND3} plugin (updates the plugin)`);
27095
+ }
27096
+ if (mode === "sdk" || mode === "all") {
27097
+ lines.push(`Run ${UPDATE_COMMAND3} sdk (updates installed SDKs)`);
27098
+ }
27099
+ p3.note(lines.join("\n"), "Update Bitfab in Cursor");
27043
27100
  }
27044
27101
  function copyToClipboard(text) {
27045
27102
  const cmd = clipboardCommand();
@@ -27267,6 +27324,47 @@ function runLogoutCommand() {
27267
27324
  runLogout();
27268
27325
  }
27269
27326
 
27327
+ // src/updateCheck.ts
27328
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/bitfab-cli/latest";
27329
+ var TIMEOUT_MS = 3e3;
27330
+ function isNewer(latest, current) {
27331
+ const parse3 = (v) => v.split(".").map(Number);
27332
+ const [lMaj = 0, lMin = 0, lPat = 0] = parse3(latest);
27333
+ const [cMaj = 0, cMin = 0, cPat = 0] = parse3(current);
27334
+ if (lMaj !== cMaj) {
27335
+ return lMaj > cMaj;
27336
+ }
27337
+ if (lMin !== cMin) {
27338
+ return lMin > cMin;
27339
+ }
27340
+ return lPat > cPat;
27341
+ }
27342
+ function startUpdateCheck() {
27343
+ const controller = new AbortController();
27344
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
27345
+ const current = getVersion();
27346
+ const done = fetch(NPM_REGISTRY_URL, { signal: controller.signal }).then(
27347
+ (res) => res.ok ? res.json() : null
27348
+ ).then((data) => {
27349
+ const latest = data?.version;
27350
+ if (latest && isNewer(latest, current)) {
27351
+ process.stderr.write(
27352
+ `
27353
+ Update available: ${current} -> ${latest}
27354
+ Run \`npx bitfab-cli@latest\` to get the newest version.
27355
+
27356
+ `
27357
+ );
27358
+ }
27359
+ }).catch(() => {
27360
+ }).finally(() => clearTimeout(timer));
27361
+ return () => {
27362
+ controller.abort();
27363
+ done.catch(() => {
27364
+ });
27365
+ };
27366
+ }
27367
+
27270
27368
  // src/index.ts
27271
27369
  var HELP_TEXT = `Usage: bitfab <command> [options]
27272
27370
 
@@ -27277,7 +27375,7 @@ Commands:
27277
27375
  logout Remove stored credentials
27278
27376
  setup [--editor <name>] Launch /bitfab:setup in the editor
27279
27377
  assistant [--editor <name>] [args] Launch /bitfab:assistant in the editor
27280
- update [--editor <name>] [args] Launch /bitfab:update in the editor
27378
+ update [--editor <name>] [mode] Update plugin, then launch SDK update (mode: all|plugin|sdk)
27281
27379
  help Show this help
27282
27380
 
27283
27381
  Options:
@@ -27322,41 +27420,51 @@ async function main() {
27322
27420
  const { command, editor, skipPermissions, rest } = parseArgs(
27323
27421
  process.argv.slice(2)
27324
27422
  );
27423
+ const abortUpdateCheck = startUpdateCheck();
27325
27424
  if (!command || command === "help" || command === "--help" || command === "-h") {
27326
27425
  process.stdout.write(HELP_TEXT);
27426
+ abortUpdateCheck();
27327
27427
  return;
27328
27428
  }
27329
27429
  if (command === "init") {
27330
27430
  await runInit({ editor, skipPermissions });
27431
+ abortUpdateCheck();
27331
27432
  return;
27332
27433
  }
27333
27434
  if (command === "plugin-install") {
27334
27435
  await runInstall({ editor, skipPermissions });
27436
+ abortUpdateCheck();
27335
27437
  return;
27336
27438
  }
27337
27439
  if (command === "login") {
27338
27440
  await runLoginCommand();
27441
+ abortUpdateCheck();
27339
27442
  return;
27340
27443
  }
27341
27444
  if (command === "logout") {
27342
27445
  runLogoutCommand();
27446
+ abortUpdateCheck();
27343
27447
  return;
27344
27448
  }
27345
27449
  if (command === "setup") {
27346
27450
  await runSetup({ editor, skipPermissions });
27451
+ abortUpdateCheck();
27347
27452
  return;
27348
27453
  }
27349
27454
  if (command === "assistant") {
27350
27455
  await runAssistant({ editor, skipPermissions }, rest);
27456
+ abortUpdateCheck();
27351
27457
  return;
27352
27458
  }
27353
27459
  if (command === "update") {
27354
27460
  await runUpdate2({ editor, skipPermissions }, rest);
27461
+ abortUpdateCheck();
27355
27462
  return;
27356
27463
  }
27357
27464
  process.stderr.write(`Unknown command: ${command}
27358
27465
 
27359
27466
  ${HELP_TEXT}`);
27467
+ abortUpdateCheck();
27360
27468
  process.exit(1);
27361
27469
  }
27362
27470
  main().catch((err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitfab-cli",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
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",