bitfab-cli 0.2.170 → 0.2.172

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 (3) hide show
  1. package/README.md +2 -0
  2. package/dist/index.js +308 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -12,4 +12,6 @@ npx bitfab-cli init --editor cursor # Install for Cursor
12
12
  npx bitfab-cli session-logs enable # Enable session log collection
13
13
  npx bitfab-cli session-logs disable # Disable session log collection
14
14
  npx bitfab-cli session-logs status # Show the saved session log setting
15
+ npx bitfab-cli analyze-repo --help # Show help for analyze-repo
16
+ npx bitfab-cli help setup # Show help for setup
15
17
  ```
package/dist/index.js CHANGED
@@ -8816,6 +8816,7 @@ var require_dist = __commonJS({
8816
8816
  });
8817
8817
 
8818
8818
  // src/index.ts
8819
+ import { pathToFileURL } from "url";
8819
8820
  import { cancel as cancel2 } from "@clack/prompts";
8820
8821
 
8821
8822
  // src/init.ts
@@ -30789,13 +30790,23 @@ function skipFlags(skip, flag) {
30789
30790
  return skip ? [flag] : [];
30790
30791
  }
30791
30792
  function runCli(bin, args) {
30792
- const result = spawnSync(bin, [...args], { stdio: "pipe", ...SHELL_OPTS });
30793
- if (result.status !== 0) {
30793
+ const result = runCliResult(bin, args);
30794
+ if (result.status !== 0 || result.error) {
30795
+ const output = result.output.trim();
30794
30796
  throw new Error(
30795
- `${bin} ${args.join(" ")} failed${result.status === null ? "" : ` with status ${result.status}`}`
30797
+ `${bin} ${args.join(" ")} failed${result.status === null ? "" : ` with status ${result.status}`}${output ? `
30798
+ ${output}` : ""}`
30796
30799
  );
30797
30800
  }
30798
- return (result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? "");
30801
+ return result.output;
30802
+ }
30803
+ function runCliResult(bin, args) {
30804
+ const result = spawnSync(bin, [...args], { stdio: "pipe", ...SHELL_OPTS });
30805
+ return {
30806
+ status: result.status,
30807
+ output: (result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? ""),
30808
+ error: result.error
30809
+ };
30799
30810
  }
30800
30811
  function launchCli(bin, args) {
30801
30812
  spawnSync(bin, [...args], { stdio: "inherit", ...SHELL_OPTS });
@@ -30834,7 +30845,44 @@ function ensureLatestPlugin(pull) {
30834
30845
  }
30835
30846
 
30836
30847
  // src/cliEditor.ts
30848
+ function makeCliAuthCheck({
30849
+ cli,
30850
+ args,
30851
+ label,
30852
+ loginCommand,
30853
+ parseAuthenticated
30854
+ }) {
30855
+ return () => {
30856
+ const result = runCliResult(cli, args);
30857
+ if (result.error) {
30858
+ return {
30859
+ ok: false,
30860
+ message: `Failed to run ${cli}: ${result.error.message}`
30861
+ };
30862
+ }
30863
+ if (result.status === 0 && parseAuthenticated(result.output)) {
30864
+ return { ok: true };
30865
+ }
30866
+ const output = result.output.trim();
30867
+ return {
30868
+ ok: false,
30869
+ message: [
30870
+ `${label} is not logged in. Run \`${loginCommand}\` and try again before launching the Bitfab agent.`,
30871
+ output ? `
30872
+ ${label} said:
30873
+ ${output}` : ""
30874
+ ].join("")
30875
+ };
30876
+ };
30877
+ }
30878
+ function ensureCliAuthenticated(cfg) {
30879
+ const result = cfg.authCheck?.();
30880
+ if (result?.ok === false) {
30881
+ throw new Error(result.message);
30882
+ }
30883
+ }
30837
30884
  function cliSetup(cfg, skipPermissions) {
30885
+ ensureCliAuthenticated(cfg);
30838
30886
  p2.log.info(`Launching ${cfg.setupCommand}...
30839
30887
  `);
30840
30888
  launchCli(cfg.cli, [
@@ -30843,6 +30891,7 @@ function cliSetup(cfg, skipPermissions) {
30843
30891
  ]);
30844
30892
  }
30845
30893
  function cliAssistant(cfg, args, skipPermissions) {
30894
+ ensureCliAuthenticated(cfg);
30846
30895
  const cmd = [cfg.assistantCommand, ...args].join(" ");
30847
30896
  p2.log.info(`Launching ${cmd}...
30848
30897
  `);
@@ -30867,6 +30916,7 @@ function cliUpdate(cfg, args, skipPermissions) {
30867
30916
  s.stop(formatPluginRefreshResult(out));
30868
30917
  }
30869
30918
  if (mode === "sdk" || mode === "all") {
30919
+ ensureCliAuthenticated(cfg);
30870
30920
  p2.log.info(`Launching ${cfg.updateCommand} sdk...
30871
30921
  `);
30872
30922
  launchCli(cfg.cli, [
@@ -30887,6 +30937,21 @@ var SETUP_COMMAND = "/bitfab:setup";
30887
30937
  var ANALYZE_REPO_COMMAND = "/bitfab:setup analyze-repo";
30888
30938
  var ASSISTANT_COMMAND = "/bitfab:assistant";
30889
30939
  var UPDATE_COMMAND = "/bitfab:update";
30940
+ function isClaudeAuthStatusLoggedIn(output) {
30941
+ try {
30942
+ const status = JSON.parse(output);
30943
+ return status.loggedIn === true;
30944
+ } catch {
30945
+ return false;
30946
+ }
30947
+ }
30948
+ var checkClaudeAuth = makeCliAuthCheck({
30949
+ cli: CLI,
30950
+ args: ["auth", "status"],
30951
+ label: "Claude Code",
30952
+ loginCommand: "claude auth login",
30953
+ parseAuthenticated: isClaudeAuthStatusLoggedIn
30954
+ });
30890
30955
  function runClaudeInstall() {
30891
30956
  const s = p3.spinner();
30892
30957
  s.start("Adding bitfab marketplace");
@@ -30927,6 +30992,10 @@ function ensureLatestClaudePlugin() {
30927
30992
  ensureLatestPlugin(pullLatestClaudePlugin);
30928
30993
  }
30929
30994
  async function runClaudeAnalyzeRepo(captureOverride, limit) {
30995
+ const auth = checkClaudeAuth();
30996
+ if (!auth.ok) {
30997
+ throw new Error(auth.message);
30998
+ }
30930
30999
  const logPath = analyzeRepoLogPath();
30931
31000
  const env = { ...process.env };
30932
31001
  if (captureOverride !== void 0) {
@@ -31127,6 +31196,7 @@ var config2 = {
31127
31196
  setupCommand: SETUP_COMMAND,
31128
31197
  assistantCommand: ASSISTANT_COMMAND,
31129
31198
  updateCommand: UPDATE_COMMAND,
31199
+ authCheck: checkClaudeAuth,
31130
31200
  pullLatest: pullLatestClaudePlugin
31131
31201
  };
31132
31202
  var claudeAdapter = {
@@ -31152,6 +31222,16 @@ var PLUGIN_KEY2 = "bitfab@bitfab";
31152
31222
  var SETUP_COMMAND2 = "$bitfab:setup";
31153
31223
  var ASSISTANT_COMMAND2 = "$bitfab:assistant";
31154
31224
  var UPDATE_COMMAND2 = "$bitfab:update";
31225
+ function isCodexLoginStatusLoggedIn(output) {
31226
+ return /logged in/i.test(output) && !/not logged in/i.test(output);
31227
+ }
31228
+ var checkCodexAuth = makeCliAuthCheck({
31229
+ cli: CLI2,
31230
+ args: ["login", "status"],
31231
+ label: "Codex",
31232
+ loginCommand: "codex login",
31233
+ parseAuthenticated: isCodexLoginStatusLoggedIn
31234
+ });
31155
31235
  function pullLatestCodexPlugin() {
31156
31236
  return runCli(CLI2, ["plugin", "marketplace", "upgrade", MARKETPLACE2]);
31157
31237
  }
@@ -31229,6 +31309,7 @@ var config3 = {
31229
31309
  setupCommand: SETUP_COMMAND2,
31230
31310
  assistantCommand: ASSISTANT_COMMAND2,
31231
31311
  updateCommand: UPDATE_COMMAND2,
31312
+ authCheck: checkCodexAuth,
31232
31313
  pullLatest: pullLatestCodexPlugin
31233
31314
  };
31234
31315
  var codexAdapter = {
@@ -31250,6 +31331,27 @@ var ADD_PLUGIN_CMD = `/add-plugin ${REPO3}`;
31250
31331
  var SETUP_COMMAND3 = "/bitfab-setup";
31251
31332
  var ASSISTANT_COMMAND3 = "/bitfab-assistant";
31252
31333
  var UPDATE_COMMAND3 = "/bitfab-update";
31334
+ function isCursorAgentStatusAuthenticated(output) {
31335
+ try {
31336
+ const status = JSON.parse(output);
31337
+ return status.isAuthenticated === true || status.status === "authenticated";
31338
+ } catch {
31339
+ return false;
31340
+ }
31341
+ }
31342
+ var checkCursorAuth = makeCliAuthCheck({
31343
+ cli: "cursor",
31344
+ args: ["agent", "status", "--format", "json"],
31345
+ label: "Cursor Agent",
31346
+ loginCommand: "cursor agent login",
31347
+ parseAuthenticated: isCursorAgentStatusAuthenticated
31348
+ });
31349
+ function ensureCursorAuthenticated() {
31350
+ const result = checkCursorAuth();
31351
+ if (result.ok === false) {
31352
+ throw new Error(result.message);
31353
+ }
31354
+ }
31253
31355
  function runCursorInstall() {
31254
31356
  const copied = copyToClipboard(ADD_PLUGIN_CMD);
31255
31357
  if (copied) {
@@ -31278,6 +31380,7 @@ function runCursorInstall() {
31278
31380
  function ensureLatestCursorPlugin() {
31279
31381
  }
31280
31382
  function runCursorSetup(skipPermissions) {
31383
+ ensureCursorAuthenticated();
31281
31384
  if (skipPermissions) {
31282
31385
  p5.log.warn("--skip-permissions is not supported for Cursor");
31283
31386
  }
@@ -31290,6 +31393,7 @@ function runCursorAnalyzeRepo() {
31290
31393
  p5.log.info(`To run it in Cursor, run ${SETUP_COMMAND3} analyze-repo manually.`);
31291
31394
  }
31292
31395
  function runCursorAssistant(args, skipPermissions) {
31396
+ ensureCursorAuthenticated();
31293
31397
  if (skipPermissions) {
31294
31398
  p5.log.warn("--skip-permissions is not supported for Cursor");
31295
31399
  }
@@ -31297,6 +31401,7 @@ function runCursorAssistant(args, skipPermissions) {
31297
31401
  p5.log.info(`To start the assistant, run ${cmd} in Cursor.`);
31298
31402
  }
31299
31403
  function runCursorUpdate(args, skipPermissions) {
31404
+ ensureCursorAuthenticated();
31300
31405
  if (skipPermissions) {
31301
31406
  p5.log.warn("--skip-permissions is not supported for Cursor");
31302
31407
  }
@@ -31665,7 +31770,7 @@ function startUpdateCheck() {
31665
31770
  }
31666
31771
 
31667
31772
  // src/index.ts
31668
- var HELP_TEXT = `Usage: bitfab <command> [options]
31773
+ var GLOBAL_HELP_TEXT = `Usage: bitfab <command> [options]
31669
31774
 
31670
31775
  Commands:
31671
31776
  init [--editor <name>] Full onboarding: plugin-install, login, and setup
@@ -31698,6 +31803,143 @@ Examples:
31698
31803
  bitfab setup --skip-permissions Setup without permission prompts
31699
31804
  bitfab assistant --skip-permissions Run assistant autonomously
31700
31805
  `;
31806
+ var COMMAND_HELP_TEXT = {
31807
+ init: `Usage: bitfab init [--editor <name>] [--skip-permissions | --no-skip-permissions]
31808
+
31809
+ Full onboarding: install the Bitfab plugin, authenticate with Bitfab, and launch setup in the selected editor.
31810
+
31811
+ Options:
31812
+ --editor, -e <name> Target editor: claude, codex, cursor
31813
+ --skip-permissions Skip permission prompts when launching the setup agent
31814
+ --no-skip-permissions Keep permission prompts without being asked
31815
+
31816
+ Examples:
31817
+ bitfab init
31818
+ bitfab init --editor claude
31819
+ bitfab init --editor codex --no-skip-permissions
31820
+ `,
31821
+ "plugin-install": `Usage: bitfab plugin-install [--editor <name>]
31822
+
31823
+ Install the Bitfab plugin in one editor without authenticating or launching setup.
31824
+
31825
+ Options:
31826
+ --editor, -e <name> Target editor: claude, codex, cursor
31827
+
31828
+ Examples:
31829
+ bitfab plugin-install
31830
+ bitfab plugin-install --editor cursor
31831
+ `,
31832
+ login: `Usage: bitfab login
31833
+
31834
+ Authenticate with Bitfab in the browser and save credentials locally.
31835
+
31836
+ Options:
31837
+ This command has no options.
31838
+
31839
+ Examples:
31840
+ bitfab login
31841
+ `,
31842
+ logout: `Usage: bitfab logout
31843
+
31844
+ Remove locally stored Bitfab credentials.
31845
+
31846
+ Options:
31847
+ This command has no options.
31848
+
31849
+ Examples:
31850
+ bitfab logout
31851
+ `,
31852
+ "session-logs": `Usage: bitfab session-logs [status|enable|disable|set true|set false]
31853
+
31854
+ Read or update the saved session-log collection preference used by setup and analyze-repo.
31855
+
31856
+ Arguments:
31857
+ status Show the saved setting (default)
31858
+ enable Enable session log collection
31859
+ disable Disable session log collection
31860
+ set true Enable session log collection
31861
+ set false Disable session log collection
31862
+
31863
+ Examples:
31864
+ bitfab session-logs status
31865
+ bitfab session-logs enable
31866
+ bitfab session-logs disable
31867
+ `,
31868
+ setup: `Usage: bitfab setup [--editor <name>] [--skip-permissions | --no-skip-permissions]
31869
+
31870
+ Launch the Bitfab setup command in the selected editor without reinstalling the plugin.
31871
+
31872
+ Options:
31873
+ --editor, -e <name> Target editor: claude, codex, cursor
31874
+ --skip-permissions Skip permission prompts when launching the setup agent
31875
+ --no-skip-permissions Keep permission prompts without being asked
31876
+
31877
+ Examples:
31878
+ bitfab setup
31879
+ bitfab setup --editor codex
31880
+ bitfab setup --skip-permissions
31881
+ `,
31882
+ "analyze-repo": `Usage: bitfab analyze-repo [--editor <name>] [--limit <n>] [--upload-logs | --no-upload-logs]
31883
+
31884
+ Headlessly scan the repository for AI workflows and upload draft trace plans for the top candidates, with no prompts and no code edits.
31885
+
31886
+ Options:
31887
+ --editor, -e <name> Target editor: claude, codex, cursor
31888
+ --limit <n> Cap how many draft trace plans to upload (default 5)
31889
+ --upload-logs Upload this run's session logs to Bitfab
31890
+ --no-upload-logs Keep this run's session logs local
31891
+
31892
+ Examples:
31893
+ bitfab analyze-repo
31894
+ bitfab analyze-repo --limit 3
31895
+ bitfab analyze-repo --no-upload-logs
31896
+ `,
31897
+ assistant: `Usage: bitfab assistant [--editor <name>] [--skip-permissions | --no-skip-permissions] [args...]
31898
+
31899
+ Launch the Bitfab assistant in the selected editor. Extra arguments are passed through to the editor command.
31900
+
31901
+ Options:
31902
+ --editor, -e <name> Target editor: claude, codex, cursor
31903
+ --skip-permissions Skip permission prompts when launching the assistant agent
31904
+ --no-skip-permissions Keep permission prompts without being asked
31905
+
31906
+ Examples:
31907
+ bitfab assistant
31908
+ bitfab assistant investigate
31909
+ bitfab assistant --editor claude --skip-permissions
31910
+ `,
31911
+ update: `Usage: bitfab update [--editor <name>] [--skip-permissions | --no-skip-permissions] [all|plugin|sdk]
31912
+
31913
+ Update the Bitfab plugin, then launch the SDK update flow in the selected editor.
31914
+
31915
+ Arguments:
31916
+ all Update plugin and SDKs (default)
31917
+ plugin Update only the plugin
31918
+ sdk Update only SDKs
31919
+
31920
+ Options:
31921
+ --editor, -e <name> Target editor: claude, codex, cursor
31922
+ --skip-permissions Skip permission prompts when launching the update agent
31923
+ --no-skip-permissions Keep permission prompts without being asked
31924
+
31925
+ Examples:
31926
+ bitfab update
31927
+ bitfab update plugin
31928
+ bitfab update --editor codex sdk
31929
+ `,
31930
+ help: `Usage: bitfab help [command]
31931
+
31932
+ Show global help or help for a specific command.
31933
+
31934
+ Arguments:
31935
+ command One of: init, plugin-install, login, logout, session-logs, setup, analyze-repo, assistant, update, help
31936
+
31937
+ Examples:
31938
+ bitfab help
31939
+ bitfab help analyze-repo
31940
+ bitfab setup --help
31941
+ `
31942
+ };
31701
31943
  function parseLimit(raw) {
31702
31944
  const n = Number(raw);
31703
31945
  if (!Number.isInteger(n) || n < 1) {
@@ -31705,9 +31947,39 @@ function parseLimit(raw) {
31705
31947
  }
31706
31948
  return n;
31707
31949
  }
31950
+ function isHelpCommand(command) {
31951
+ return command !== void 0 && Object.hasOwn(COMMAND_HELP_TEXT, command);
31952
+ }
31953
+ function getHelpTopic(argv) {
31954
+ const [command, maybeTopic] = argv;
31955
+ if (command === void 0) {
31956
+ return void 0;
31957
+ }
31958
+ if (command === "help") {
31959
+ if (maybeTopic === "-h" || maybeTopic === "--help") {
31960
+ return "help";
31961
+ }
31962
+ return maybeTopic;
31963
+ }
31964
+ if (command === "-h" || command === "--help") {
31965
+ return void 0;
31966
+ }
31967
+ if (argv.includes("-h") || argv.includes("--help")) {
31968
+ return command;
31969
+ }
31970
+ return null;
31971
+ }
31972
+ function getHelpText(topic) {
31973
+ if (topic === void 0) {
31974
+ return GLOBAL_HELP_TEXT;
31975
+ }
31976
+ if (isHelpCommand(topic)) {
31977
+ return COMMAND_HELP_TEXT[topic];
31978
+ }
31979
+ return void 0;
31980
+ }
31708
31981
  function wantsHelp(argv) {
31709
- const command = argv[0];
31710
- return !command || command === "help" || argv.includes("-h") || argv.includes("--help");
31982
+ return getHelpTopic(argv) !== null;
31711
31983
  }
31712
31984
  function parseArgs2(argv) {
31713
31985
  const [command, ...tail] = argv;
@@ -31751,13 +32023,23 @@ function parseArgs2(argv) {
31751
32023
  return { command, editor, skipPermissions, uploadLogs, limit, rest };
31752
32024
  }
31753
32025
  async function main() {
31754
- const { command, editor, skipPermissions, uploadLogs, limit, rest } = parseArgs2(process.argv.slice(2));
31755
- const abortUpdateCheck = startUpdateCheck();
31756
- if (wantsHelp(process.argv.slice(2))) {
31757
- process.stdout.write(HELP_TEXT);
31758
- abortUpdateCheck();
32026
+ const argv = process.argv.slice(2);
32027
+ const helpTopic = getHelpTopic(argv);
32028
+ if (helpTopic !== null) {
32029
+ const helpText = getHelpText(helpTopic);
32030
+ if (helpText === void 0) {
32031
+ process.stderr.write(
32032
+ `Unknown command: ${helpTopic}
32033
+
32034
+ ${GLOBAL_HELP_TEXT}`
32035
+ );
32036
+ process.exit(1);
32037
+ }
32038
+ process.stdout.write(helpText);
31759
32039
  return;
31760
32040
  }
32041
+ const { command, editor, skipPermissions, uploadLogs, limit, rest } = parseArgs2(argv);
32042
+ const abortUpdateCheck = startUpdateCheck();
31761
32043
  if (command === "init") {
31762
32044
  await runInit({ editor, skipPermissions });
31763
32045
  abortUpdateCheck();
@@ -31805,16 +32087,24 @@ async function main() {
31805
32087
  }
31806
32088
  process.stderr.write(`Unknown command: ${command}
31807
32089
 
31808
- ${HELP_TEXT}`);
32090
+ ${GLOBAL_HELP_TEXT}`);
31809
32091
  abortUpdateCheck();
31810
32092
  process.exit(1);
31811
32093
  }
31812
- main().catch((err) => {
31813
- const message = err instanceof Error ? err.message : String(err);
31814
- cancel2(message);
31815
- process.exit(1);
31816
- });
32094
+ function isDirectRun() {
32095
+ const entrypoint = process.argv[1];
32096
+ return entrypoint !== void 0 && import.meta.url === pathToFileURL(entrypoint).href;
32097
+ }
32098
+ if (isDirectRun()) {
32099
+ main().catch((err) => {
32100
+ const message = err instanceof Error ? err.message : String(err);
32101
+ cancel2(message);
32102
+ process.exit(1);
32103
+ });
32104
+ }
31817
32105
  export {
32106
+ getHelpText,
32107
+ getHelpTopic,
31818
32108
  parseArgs2 as parseArgs,
31819
32109
  wantsHelp
31820
32110
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitfab-cli",
3
- "version": "0.2.170",
3
+ "version": "0.2.172",
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",