bitfab-cli 0.2.167 → 0.2.169

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 +364 -321
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1090,20 +1090,20 @@ var require_range = __commonJS({
1090
1090
  };
1091
1091
  var replaceTilde = (comp, options) => {
1092
1092
  const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE];
1093
- return comp.replace(r, (_, M, m, p5, pr) => {
1094
- debug("tilde", comp, _, M, m, p5, pr);
1093
+ return comp.replace(r, (_, M, m, p7, pr) => {
1094
+ debug("tilde", comp, _, M, m, p7, pr);
1095
1095
  let ret;
1096
1096
  if (isX(M)) {
1097
1097
  ret = "";
1098
1098
  } else if (isX(m)) {
1099
1099
  ret = `>=${M}.0.0 <${+M + 1}.0.0-0`;
1100
- } else if (isX(p5)) {
1100
+ } else if (isX(p7)) {
1101
1101
  ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`;
1102
1102
  } else if (pr) {
1103
1103
  debug("replaceTilde pr", pr);
1104
- ret = `>=${M}.${m}.${p5}-${pr} <${M}.${+m + 1}.0-0`;
1104
+ ret = `>=${M}.${m}.${p7}-${pr} <${M}.${+m + 1}.0-0`;
1105
1105
  } else {
1106
- ret = `>=${M}.${m}.${p5} <${M}.${+m + 1}.0-0`;
1106
+ ret = `>=${M}.${m}.${p7} <${M}.${+m + 1}.0-0`;
1107
1107
  }
1108
1108
  debug("tilde return", ret);
1109
1109
  return ret;
@@ -1116,14 +1116,14 @@ var require_range = __commonJS({
1116
1116
  debug("caret", comp, options);
1117
1117
  const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET];
1118
1118
  const z2 = options.includePrerelease ? "-0" : "";
1119
- return comp.replace(r, (_, M, m, p5, pr) => {
1120
- debug("caret", comp, _, M, m, p5, pr);
1119
+ return comp.replace(r, (_, M, m, p7, pr) => {
1120
+ debug("caret", comp, _, M, m, p7, pr);
1121
1121
  let ret;
1122
1122
  if (isX(M)) {
1123
1123
  ret = "";
1124
1124
  } else if (isX(m)) {
1125
1125
  ret = `>=${M}.0.0${z2} <${+M + 1}.0.0-0`;
1126
- } else if (isX(p5)) {
1126
+ } else if (isX(p7)) {
1127
1127
  if (M === "0") {
1128
1128
  ret = `>=${M}.${m}.0${z2} <${M}.${+m + 1}.0-0`;
1129
1129
  } else {
@@ -1133,23 +1133,23 @@ var require_range = __commonJS({
1133
1133
  debug("replaceCaret pr", pr);
1134
1134
  if (M === "0") {
1135
1135
  if (m === "0") {
1136
- ret = `>=${M}.${m}.${p5}-${pr} <${M}.${m}.${+p5 + 1}-0`;
1136
+ ret = `>=${M}.${m}.${p7}-${pr} <${M}.${m}.${+p7 + 1}-0`;
1137
1137
  } else {
1138
- ret = `>=${M}.${m}.${p5}-${pr} <${M}.${+m + 1}.0-0`;
1138
+ ret = `>=${M}.${m}.${p7}-${pr} <${M}.${+m + 1}.0-0`;
1139
1139
  }
1140
1140
  } else {
1141
- ret = `>=${M}.${m}.${p5}-${pr} <${+M + 1}.0.0-0`;
1141
+ ret = `>=${M}.${m}.${p7}-${pr} <${+M + 1}.0.0-0`;
1142
1142
  }
1143
1143
  } else {
1144
1144
  debug("no pr");
1145
1145
  if (M === "0") {
1146
1146
  if (m === "0") {
1147
- ret = `>=${M}.${m}.${p5}${z2} <${M}.${m}.${+p5 + 1}-0`;
1147
+ ret = `>=${M}.${m}.${p7}${z2} <${M}.${m}.${+p7 + 1}-0`;
1148
1148
  } else {
1149
- ret = `>=${M}.${m}.${p5}${z2} <${M}.${+m + 1}.0-0`;
1149
+ ret = `>=${M}.${m}.${p7}${z2} <${M}.${+m + 1}.0-0`;
1150
1150
  }
1151
1151
  } else {
1152
- ret = `>=${M}.${m}.${p5} <${+M + 1}.0.0-0`;
1152
+ ret = `>=${M}.${m}.${p7} <${+M + 1}.0.0-0`;
1153
1153
  }
1154
1154
  }
1155
1155
  debug("caret return", ret);
@@ -1163,11 +1163,11 @@ var require_range = __commonJS({
1163
1163
  var replaceXRange = (comp, options) => {
1164
1164
  comp = comp.trim();
1165
1165
  const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE];
1166
- return comp.replace(r, (ret, gtlt, M, m, p5, pr) => {
1167
- debug("xRange", comp, ret, gtlt, M, m, p5, pr);
1166
+ return comp.replace(r, (ret, gtlt, M, m, p7, pr) => {
1167
+ debug("xRange", comp, ret, gtlt, M, m, p7, pr);
1168
1168
  const xM = isX(M);
1169
1169
  const xm = xM || isX(m);
1170
- const xp = xm || isX(p5);
1170
+ const xp = xm || isX(p7);
1171
1171
  const anyX = xp;
1172
1172
  if (gtlt === "=" && anyX) {
1173
1173
  gtlt = "";
@@ -1183,16 +1183,16 @@ var require_range = __commonJS({
1183
1183
  if (xm) {
1184
1184
  m = 0;
1185
1185
  }
1186
- p5 = 0;
1186
+ p7 = 0;
1187
1187
  if (gtlt === ">") {
1188
1188
  gtlt = ">=";
1189
1189
  if (xm) {
1190
1190
  M = +M + 1;
1191
1191
  m = 0;
1192
- p5 = 0;
1192
+ p7 = 0;
1193
1193
  } else {
1194
1194
  m = +m + 1;
1195
- p5 = 0;
1195
+ p7 = 0;
1196
1196
  }
1197
1197
  } else if (gtlt === "<=") {
1198
1198
  gtlt = "<";
@@ -1205,7 +1205,7 @@ var require_range = __commonJS({
1205
1205
  if (gtlt === "<") {
1206
1206
  pr = "-0";
1207
1207
  }
1208
- ret = `${gtlt + M}.${m}.${p5}${pr}`;
1208
+ ret = `${gtlt + M}.${m}.${p7}${pr}`;
1209
1209
  } else if (xm) {
1210
1210
  ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`;
1211
1211
  } else if (xp) {
@@ -3109,7 +3109,7 @@ var require_util = __commonJS({
3109
3109
  }
3110
3110
  exports.evaluatedPropsToName = evaluatedPropsToName;
3111
3111
  function setEvaluated(gen, props, ps) {
3112
- Object.keys(ps).forEach((p5) => gen.assign((0, codegen_1._)`${props}${(0, codegen_1.getProperty)(p5)}`, true));
3112
+ Object.keys(ps).forEach((p7) => gen.assign((0, codegen_1._)`${props}${(0, codegen_1.getProperty)(p7)}`, true));
3113
3113
  }
3114
3114
  exports.setEvaluated = setEvaluated;
3115
3115
  var snippets = {};
@@ -3682,11 +3682,11 @@ var require_code2 = __commonJS({
3682
3682
  }
3683
3683
  exports.noPropertyInData = noPropertyInData;
3684
3684
  function allSchemaProperties(schemaMap) {
3685
- return schemaMap ? Object.keys(schemaMap).filter((p5) => p5 !== "__proto__") : [];
3685
+ return schemaMap ? Object.keys(schemaMap).filter((p7) => p7 !== "__proto__") : [];
3686
3686
  }
3687
3687
  exports.allSchemaProperties = allSchemaProperties;
3688
3688
  function schemaProperties(it, schemaMap) {
3689
- return allSchemaProperties(schemaMap).filter((p5) => !(0, util_1.alwaysValidSchema)(it, schemaMap[p5]));
3689
+ return allSchemaProperties(schemaMap).filter((p7) => !(0, util_1.alwaysValidSchema)(it, schemaMap[p7]));
3690
3690
  }
3691
3691
  exports.schemaProperties = schemaProperties;
3692
3692
  function callValidateCode({ schemaCode, data, it: { gen, topSchemaRef, schemaPath, errorPath }, it }, func, context, passSchema) {
@@ -4164,12 +4164,12 @@ var require_resolve = __commonJS({
4164
4164
  function getFullPath(resolver, id = "", normalize) {
4165
4165
  if (normalize !== false)
4166
4166
  id = normalizeId(id);
4167
- const p5 = resolver.parse(id);
4168
- return _getFullPath(resolver, p5);
4167
+ const p7 = resolver.parse(id);
4168
+ return _getFullPath(resolver, p7);
4169
4169
  }
4170
4170
  exports.getFullPath = getFullPath;
4171
- function _getFullPath(resolver, p5) {
4172
- const serialized = resolver.serialize(p5);
4171
+ function _getFullPath(resolver, p7) {
4172
+ const serialized = resolver.serialize(p7);
4173
4173
  return serialized.split("#")[0] + "#";
4174
4174
  }
4175
4175
  exports._getFullPath = _getFullPath;
@@ -4944,11 +4944,11 @@ var require_compile = __commonJS({
4944
4944
  return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
4945
4945
  }
4946
4946
  function resolveSchema(root, ref) {
4947
- const p5 = this.opts.uriResolver.parse(ref);
4948
- const refPath = (0, resolve_1._getFullPath)(this.opts.uriResolver, p5);
4947
+ const p7 = this.opts.uriResolver.parse(ref);
4948
+ const refPath = (0, resolve_1._getFullPath)(this.opts.uriResolver, p7);
4949
4949
  let baseId = (0, resolve_1.getFullPath)(this.opts.uriResolver, root.baseId, void 0);
4950
4950
  if (Object.keys(root.schema).length > 0 && refPath === baseId) {
4951
- return getJsonPointer.call(this, p5, root);
4951
+ return getJsonPointer.call(this, p7, root);
4952
4952
  }
4953
4953
  const id = (0, resolve_1.normalizeId)(refPath);
4954
4954
  const schOrRef = this.refs[id] || this.schemas[id];
@@ -4956,7 +4956,7 @@ var require_compile = __commonJS({
4956
4956
  const sch = resolveSchema.call(this, root, schOrRef);
4957
4957
  if (typeof (sch === null || sch === void 0 ? void 0 : sch.schema) !== "object")
4958
4958
  return;
4959
- return getJsonPointer.call(this, p5, sch);
4959
+ return getJsonPointer.call(this, p7, sch);
4960
4960
  }
4961
4961
  if (typeof (schOrRef === null || schOrRef === void 0 ? void 0 : schOrRef.schema) !== "object")
4962
4962
  return;
@@ -4970,7 +4970,7 @@ var require_compile = __commonJS({
4970
4970
  baseId = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, schId);
4971
4971
  return new SchemaEnv({ schema, schemaId, root, baseId });
4972
4972
  }
4973
- return getJsonPointer.call(this, p5, schOrRef);
4973
+ return getJsonPointer.call(this, p7, schOrRef);
4974
4974
  }
4975
4975
  exports.resolveSchema = resolveSchema;
4976
4976
  var PREVENT_SCOPE_CHANGE = /* @__PURE__ */ new Set([
@@ -6062,9 +6062,9 @@ var require_core = __commonJS({
6062
6062
  this.addSchema(_schema, ref, meta3);
6063
6063
  }
6064
6064
  async function _loadSchema(ref) {
6065
- const p5 = this._loading[ref];
6066
- if (p5)
6067
- return p5;
6065
+ const p7 = this._loading[ref];
6066
+ if (p7)
6067
+ return p7;
6068
6068
  try {
6069
6069
  return await (this._loading[ref] = loadSchema(ref));
6070
6070
  } finally {
@@ -6330,11 +6330,11 @@ var require_core = __commonJS({
6330
6330
  Ajv.ValidationError = validation_error_1.default;
6331
6331
  Ajv.MissingRefError = ref_error_1.default;
6332
6332
  exports.default = Ajv;
6333
- function checkOptions(checkOpts, options, msg, log5 = "error") {
6333
+ function checkOptions(checkOpts, options, msg, log7 = "error") {
6334
6334
  for (const key in checkOpts) {
6335
6335
  const opt = key;
6336
6336
  if (opt in options)
6337
- this.logger[log5](`${msg}: option ${key}. ${checkOpts[opt]}`);
6337
+ this.logger[log7](`${msg}: option ${key}. ${checkOpts[opt]}`);
6338
6338
  }
6339
6339
  }
6340
6340
  function getSchEnv(keyRef) {
@@ -7546,12 +7546,12 @@ var require_additionalProperties = __commonJS({
7546
7546
  const propsSchema = (0, util_1.schemaRefOrVal)(it, parentSchema.properties, "properties");
7547
7547
  definedProp = (0, code_1.isOwnProperty)(gen, propsSchema, key);
7548
7548
  } else if (props.length) {
7549
- definedProp = (0, codegen_1.or)(...props.map((p5) => (0, codegen_1._)`${key} === ${p5}`));
7549
+ definedProp = (0, codegen_1.or)(...props.map((p7) => (0, codegen_1._)`${key} === ${p7}`));
7550
7550
  } else {
7551
7551
  definedProp = codegen_1.nil;
7552
7552
  }
7553
7553
  if (patProps.length) {
7554
- definedProp = (0, codegen_1.or)(definedProp, ...patProps.map((p5) => (0, codegen_1._)`${(0, code_1.usePattern)(cxt, p5)}.test(${key})`));
7554
+ definedProp = (0, codegen_1.or)(definedProp, ...patProps.map((p7) => (0, codegen_1._)`${(0, code_1.usePattern)(cxt, p7)}.test(${key})`));
7555
7555
  }
7556
7556
  return (0, codegen_1.not)(definedProp);
7557
7557
  }
@@ -7631,7 +7631,7 @@ var require_properties = __commonJS({
7631
7631
  if (it.opts.unevaluated && allProps.length && it.props !== true) {
7632
7632
  it.props = util_1.mergeEvaluated.props(gen, (0, util_1.toHash)(allProps), it.props);
7633
7633
  }
7634
- const properties = allProps.filter((p5) => !(0, util_1.alwaysValidSchema)(it, schema[p5]));
7634
+ const properties = allProps.filter((p7) => !(0, util_1.alwaysValidSchema)(it, schema[p7]));
7635
7635
  if (properties.length === 0)
7636
7636
  return;
7637
7637
  const valid = gen.name("valid");
@@ -7681,7 +7681,7 @@ var require_patternProperties = __commonJS({
7681
7681
  const { gen, schema, data, parentSchema, it } = cxt;
7682
7682
  const { opts } = it;
7683
7683
  const patterns = (0, code_1.allSchemaProperties)(schema);
7684
- const alwaysValidPatterns = patterns.filter((p5) => (0, util_1.alwaysValidSchema)(it, schema[p5]));
7684
+ const alwaysValidPatterns = patterns.filter((p7) => (0, util_1.alwaysValidSchema)(it, schema[p7]));
7685
7685
  if (patterns.length === 0 || alwaysValidPatterns.length === patterns.length && (!it.opts.unevaluated || it.props === true)) {
7686
7686
  return;
7687
7687
  }
@@ -8820,7 +8820,7 @@ import { cancel as cancel2 } from "@clack/prompts";
8820
8820
 
8821
8821
  // src/init.ts
8822
8822
  import { execSync as execSync3 } from "child_process";
8823
- import * as p4 from "@clack/prompts";
8823
+ import * as p6 from "@clack/prompts";
8824
8824
 
8825
8825
  // ../bitfab-plugin-lib/dist/errors.js
8826
8826
  var NotAuthenticatedError = class extends Error {
@@ -9274,8 +9274,8 @@ function getServiceUrl() {
9274
9274
  if (project && typeof project.serviceUrl === "string") {
9275
9275
  return project.serviceUrl;
9276
9276
  }
9277
- const config2 = getConfigData();
9278
- return typeof config2.serviceUrl === "string" ? config2.serviceUrl : DEFAULT_SERVICE_URL;
9277
+ const config4 = getConfigData();
9278
+ return typeof config4.serviceUrl === "string" ? config4.serviceUrl : DEFAULT_SERVICE_URL;
9279
9279
  }
9280
9280
  function getApiKey() {
9281
9281
  if (process.env.BITFAB_API_KEY) {
@@ -9295,22 +9295,22 @@ function getVerbose() {
9295
9295
  if (process.env.BITFAB_VERBOSE === "false" || process.env.BITFAB_VERBOSE === "0") {
9296
9296
  return false;
9297
9297
  }
9298
- const config2 = getConfigData();
9299
- return config2.verbose === true;
9298
+ const config4 = getConfigData();
9299
+ return config4.verbose === true;
9300
9300
  }
9301
9301
  function getDebug() {
9302
9302
  if (process.env.BITFAB_DEBUG === "true" || process.env.BITFAB_DEBUG === "1") {
9303
9303
  return true;
9304
9304
  }
9305
- const config2 = getConfigData();
9306
- return config2.debug === true;
9305
+ const config4 = getConfigData();
9306
+ return config4.debug === true;
9307
9307
  }
9308
9308
  function getSessionLogConsentValue() {
9309
- const config2 = getConfigData();
9310
- if (config2.sessionLogConsent === true) {
9309
+ const config4 = getConfigData();
9310
+ if (config4.sessionLogConsent === true) {
9311
9311
  return true;
9312
9312
  }
9313
- if (config2.sessionLogConsent === false) {
9313
+ if (config4.sessionLogConsent === false) {
9314
9314
  return false;
9315
9315
  }
9316
9316
  return null;
@@ -9334,6 +9334,28 @@ function getConfig() {
9334
9334
  sessionLogConsent: getSessionLogConsentValue()
9335
9335
  };
9336
9336
  }
9337
+ function isProductionServiceUrl(serviceUrl) {
9338
+ try {
9339
+ const url2 = new URL(serviceUrl);
9340
+ return url2.protocol === "https:" && url2.hostname === "bitfab.ai" && (url2.pathname === "" || url2.pathname === "/");
9341
+ } catch {
9342
+ return false;
9343
+ }
9344
+ }
9345
+ function formatNonProductionEndpointSuffix(serviceUrl) {
9346
+ if (isProductionServiceUrl(serviceUrl)) {
9347
+ return "";
9348
+ }
9349
+ try {
9350
+ const url2 = new URL(serviceUrl);
9351
+ if (!url2.host) {
9352
+ return ` @ ${serviceUrl}`;
9353
+ }
9354
+ return ` @ ${url2.host}`;
9355
+ } catch {
9356
+ return ` @ ${serviceUrl}`;
9357
+ }
9358
+ }
9337
9359
  function saveCredentials(apiKey) {
9338
9360
  const projectFile = findProjectFiles()?.credentialsFile;
9339
9361
  if (projectFile) {
@@ -9355,14 +9377,14 @@ function hasCredentials() {
9355
9377
  return getApiKey() !== null;
9356
9378
  }
9357
9379
  function getOrCreateInstallId() {
9358
- const config2 = getConfigData();
9359
- if (typeof config2.installId === "string" && config2.installId.length > 0) {
9360
- return config2.installId;
9380
+ const config4 = getConfigData();
9381
+ if (typeof config4.installId === "string" && config4.installId.length > 0) {
9382
+ return config4.installId;
9361
9383
  }
9362
9384
  const installId = crypto2.randomUUID();
9363
9385
  try {
9364
9386
  fs3.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
9365
- fs3.writeFileSync(GLOBAL_CONFIG_FILE, `${JSON.stringify({ ...config2, installId }, null, 2)}
9387
+ fs3.writeFileSync(GLOBAL_CONFIG_FILE, `${JSON.stringify({ ...config4, installId }, null, 2)}
9366
9388
  `);
9367
9389
  } catch {
9368
9390
  }
@@ -10191,9 +10213,9 @@ function processIsAlive(pid) {
10191
10213
  }
10192
10214
  }
10193
10215
  function unlinkQuietly(...paths) {
10194
- for (const p5 of paths) {
10216
+ for (const p7 of paths) {
10195
10217
  try {
10196
- fs9.unlinkSync(p5);
10218
+ fs9.unlinkSync(p7);
10197
10219
  } catch {
10198
10220
  }
10199
10221
  }
@@ -10988,19 +11010,19 @@ import path11 from "path";
10988
11010
 
10989
11011
  // ../bitfab-plugin-lib/dist/analytics.js
10990
11012
  async function reportHandoff(apiKey, pluginVersion, platform2, body) {
10991
- const config2 = getConfig();
11013
+ const config4 = getConfig();
10992
11014
  const headers = buildBitfabRequestHeaders(apiKey, pluginVersion, platform2);
10993
11015
  try {
10994
- const response = await fetch(`${config2.serviceUrl}/api/plugin/analytics/handoff`, {
11016
+ const response = await fetch(`${config4.serviceUrl}/api/plugin/analytics/handoff`, {
10995
11017
  method: "POST",
10996
11018
  headers,
10997
11019
  body: JSON.stringify(body)
10998
11020
  });
10999
- if (config2.debug && !response.ok) {
11021
+ if (config4.debug && !response.ok) {
11000
11022
  console.error(`reportHandoff: server returned ${response.status} for ${body.flow}`);
11001
11023
  }
11002
11024
  } catch (err) {
11003
- if (config2.debug) {
11025
+ if (config4.debug) {
11004
11026
  const message = err instanceof Error ? err.message : String(err);
11005
11027
  console.error(`reportHandoff: request failed for ${body.flow}: ${message}`);
11006
11028
  }
@@ -11254,9 +11276,9 @@ function createEventSubscription(channel, sessionId, onEvent, restoreFocus) {
11254
11276
  };
11255
11277
  }
11256
11278
  async function openStudioTo(path20, opts = {}) {
11257
- const config2 = getConfig();
11258
- const serviceUrl = config2.serviceUrl;
11259
- const apiKey = !opts.forceLogin && hasCredentials() ? config2.apiKey : null;
11279
+ const config4 = getConfig();
11280
+ const serviceUrl = config4.serviceUrl;
11281
+ const apiKey = !opts.forceLogin && hasCredentials() ? config4.apiKey : null;
11260
11282
  const key = resolveAgentSessionKey();
11261
11283
  const focusTarget = captureFocusTarget();
11262
11284
  const restoreFocus = () => applyFocusTarget(focusTarget);
@@ -11404,13 +11426,14 @@ async function verifyToken(serviceUrl, token) {
11404
11426
  async function runLogin(platform2, pluginVersion, options) {
11405
11427
  const exitOnComplete = options?.exitOnComplete ?? true;
11406
11428
  const force = options?.force ?? process.argv.includes("--force");
11407
- const config2 = getConfig();
11408
- if (!force && hasCredentials() && config2.apiKey) {
11409
- const who = await verifyToken(config2.serviceUrl, config2.apiKey);
11429
+ const config4 = getConfig();
11430
+ if (!force && hasCredentials() && config4.apiKey) {
11431
+ const who = await verifyToken(config4.serviceUrl, config4.apiKey);
11410
11432
  if (who) {
11411
11433
  const identity = who.user.email ?? "your account";
11434
+ const endpoint = formatNonProductionEndpointSuffix(config4.serviceUrl);
11412
11435
  console.log(`
11413
- Already logged in as ${identity}. Run the login command with --force to re-authenticate.`);
11436
+ Already logged in as ${identity}${endpoint}. Run the login command with --force to re-authenticate.`);
11414
11437
  if (exitOnComplete) {
11415
11438
  process.exit(0);
11416
11439
  }
@@ -11441,8 +11464,9 @@ Already logged in as ${identity}. Run the login command with --force to re-authe
11441
11464
  loopbackAvailable: false,
11442
11465
  ticketAvailable: false
11443
11466
  });
11444
- const who = await verifyToken(config2.serviceUrl, apiKey);
11445
- const greeting = who?.user.email ? `Logged in as ${who.user.email}.` : "Authentication successful.";
11467
+ const who = await verifyToken(config4.serviceUrl, apiKey);
11468
+ const endpoint = formatNonProductionEndpointSuffix(config4.serviceUrl);
11469
+ const greeting = who?.user.email ? `Logged in as ${who.user.email}${endpoint}.` : "Authentication successful.";
11446
11470
  console.log(`
11447
11471
  ${greeting}`);
11448
11472
  console.log("Bitfab MCP tools are now active. (via studio)");
@@ -12649,10 +12673,10 @@ function prefixIssues(path20, issues) {
12649
12673
  function unwrapMessage(message) {
12650
12674
  return typeof message === "string" ? message : message?.message;
12651
12675
  }
12652
- function finalizeIssue(iss, ctx, config2) {
12676
+ function finalizeIssue(iss, ctx, config4) {
12653
12677
  const full = { ...iss, path: iss.path ?? [] };
12654
12678
  if (!iss.message) {
12655
- const message = unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config2.customError?.(iss)) ?? unwrapMessage(config2.localeError?.(iss)) ?? "Invalid input";
12679
+ const message = unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config4.customError?.(iss)) ?? unwrapMessage(config4.localeError?.(iss)) ?? "Invalid input";
12656
12680
  full.message = message;
12657
12681
  }
12658
12682
  delete full.inst;
@@ -14632,7 +14656,7 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
14632
14656
  defineLazy(inst._zod, "pattern", () => {
14633
14657
  if (def.options.every((o) => o._zod.pattern)) {
14634
14658
  const patterns = def.options.map((o) => o._zod.pattern);
14635
- return new RegExp(`^(${patterns.map((p5) => cleanRegex(p5.source)).join("|")})$`);
14659
+ return new RegExp(`^(${patterns.map((p7) => cleanRegex(p7.source)).join("|")})$`);
14636
14660
  }
14637
14661
  return void 0;
14638
14662
  });
@@ -21309,9 +21333,9 @@ var $ZodRegistry = class {
21309
21333
  return this;
21310
21334
  }
21311
21335
  get(schema) {
21312
- const p5 = schema._zod.parent;
21313
- if (p5) {
21314
- const pm = { ...this.get(p5) ?? {} };
21336
+ const p7 = schema._zod.parent;
21337
+ if (p7) {
21338
+ const pm = { ...this.get(p7) ?? {} };
21315
21339
  delete pm.id;
21316
21340
  const f = { ...pm, ...this._map.get(schema) };
21317
21341
  return Object.keys(f).length ? f : void 0;
@@ -30749,11 +30773,113 @@ var tracePlanTreeShape = external_exports.object({
30749
30773
  });
30750
30774
 
30751
30775
  // src/claude.ts
30752
- import { spawn as spawn5, spawnSync } from "child_process";
30776
+ import { spawn as spawn5 } from "child_process";
30753
30777
  import fs20 from "fs";
30754
30778
  import os15 from "os";
30755
30779
  import path17 from "path";
30780
+ import * as p3 from "@clack/prompts";
30781
+
30782
+ // src/cliEditor.ts
30783
+ import * as p2 from "@clack/prompts";
30784
+
30785
+ // src/editorCli.ts
30786
+ import { spawnSync } from "child_process";
30787
+ var SHELL_OPTS = process.platform === "win32" ? { shell: true } : {};
30788
+ function skipFlags(skip, flag) {
30789
+ return skip ? [flag] : [];
30790
+ }
30791
+ function runCli(bin, args) {
30792
+ const result = spawnSync(bin, [...args], { stdio: "pipe", ...SHELL_OPTS });
30793
+ if (result.status !== 0) {
30794
+ throw new Error(
30795
+ `${bin} ${args.join(" ")} failed${result.status === null ? "" : ` with status ${result.status}`}`
30796
+ );
30797
+ }
30798
+ return (result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? "");
30799
+ }
30800
+ function launchCli(bin, args) {
30801
+ spawnSync(bin, [...args], { stdio: "inherit", ...SHELL_OPTS });
30802
+ }
30803
+
30804
+ // src/pluginRefresh.ts
30756
30805
  import * as p from "@clack/prompts";
30806
+ function pluginOutputIsUpToDate(output) {
30807
+ return output.includes("already") || output.includes("up to date");
30808
+ }
30809
+ function extractPluginVersion(output) {
30810
+ const match = /(?:^|[^\d])v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)(?:$|[^\d])/.exec(
30811
+ output
30812
+ );
30813
+ return match?.[1] ?? null;
30814
+ }
30815
+ function formatPluginRefreshResult(output) {
30816
+ const version2 = extractPluginVersion(output);
30817
+ if (pluginOutputIsUpToDate(output)) {
30818
+ return version2 ? `Plugin already up to date (v${version2})` : "Plugin already up to date";
30819
+ }
30820
+ return version2 ? `Plugin updated to v${version2}` : "Plugin updated to latest";
30821
+ }
30822
+ function ensureLatestPlugin(pull) {
30823
+ const s = p.spinner();
30824
+ s.start("Checking for the latest bitfab plugin");
30825
+ try {
30826
+ const out = pull();
30827
+ s.stop(formatPluginRefreshResult(out));
30828
+ } catch (err) {
30829
+ s.stop("Could not check for plugin updates");
30830
+ p.log.warn(
30831
+ `Continuing with the installed plugin version. ${err instanceof Error ? err.message : String(err)}`
30832
+ );
30833
+ }
30834
+ }
30835
+
30836
+ // src/cliEditor.ts
30837
+ function cliSetup(cfg, skipPermissions) {
30838
+ p2.log.info(`Launching ${cfg.setupCommand}...
30839
+ `);
30840
+ launchCli(cfg.cli, [
30841
+ ...skipFlags(skipPermissions, cfg.skipFlag),
30842
+ cfg.setupCommand
30843
+ ]);
30844
+ }
30845
+ function cliAssistant(cfg, args, skipPermissions) {
30846
+ const cmd = [cfg.assistantCommand, ...args].join(" ");
30847
+ p2.log.info(`Launching ${cmd}...
30848
+ `);
30849
+ launchCli(cfg.cli, [
30850
+ ...skipFlags(skipPermissions, cfg.skipFlag),
30851
+ cfg.assistantCommand,
30852
+ ...args
30853
+ ]);
30854
+ }
30855
+ function cliUpdate(cfg, args, skipPermissions) {
30856
+ const mode = args[0] === "plugin" || args[0] === "sdk" ? args[0] : "all";
30857
+ if (mode === "plugin" || mode === "all") {
30858
+ const s = p2.spinner();
30859
+ s.start("Updating bitfab plugin");
30860
+ let out;
30861
+ try {
30862
+ out = cfg.pullLatest();
30863
+ } catch (err) {
30864
+ s.stop("Plugin update failed");
30865
+ throw err;
30866
+ }
30867
+ s.stop(formatPluginRefreshResult(out));
30868
+ }
30869
+ if (mode === "sdk" || mode === "all") {
30870
+ p2.log.info(`Launching ${cfg.updateCommand} sdk...
30871
+ `);
30872
+ launchCli(cfg.cli, [
30873
+ ...skipFlags(skipPermissions, cfg.skipFlag),
30874
+ cfg.updateCommand,
30875
+ "sdk"
30876
+ ]);
30877
+ }
30878
+ }
30879
+
30880
+ // src/claude.ts
30881
+ var CLI = "claude";
30882
+ var SKIP_FLAG = "--dangerously-skip-permissions";
30757
30883
  var REPO = "Project-White-Rabbit/bitfab-claude-plugin";
30758
30884
  var MARKETPLACE = "bitfab";
30759
30885
  var PLUGIN_KEY = "bitfab@bitfab";
@@ -30761,11 +30887,10 @@ var SETUP_COMMAND = "/bitfab:setup";
30761
30887
  var ANALYZE_REPO_COMMAND = "/bitfab:setup analyze-repo";
30762
30888
  var ASSISTANT_COMMAND = "/bitfab:assistant";
30763
30889
  var UPDATE_COMMAND = "/bitfab:update";
30764
- var SHELL_OPTS = process.platform === "win32" ? { shell: true } : {};
30765
30890
  function runClaudeInstall() {
30766
- const s = p.spinner();
30891
+ const s = p3.spinner();
30767
30892
  s.start("Adding bitfab marketplace");
30768
- const marketplaceOut = runClaude(["plugin", "marketplace", "add", REPO]);
30893
+ const marketplaceOut = runCli(CLI, ["plugin", "marketplace", "add", REPO]);
30769
30894
  if (marketplaceOut.includes("already")) {
30770
30895
  s.stop("Marketplace already configured");
30771
30896
  } else {
@@ -30780,33 +30905,26 @@ function runClaudeInstall() {
30780
30905
  } else {
30781
30906
  s.stop("Auto-updates already enabled");
30782
30907
  }
30783
- s.start("Installing bitfab plugin");
30784
- const installOut = runClaude([
30785
- "plugin",
30786
- "install",
30787
- PLUGIN_KEY,
30788
- "--scope",
30789
- "user"
30790
- ]);
30791
- if (installOut.includes("already")) {
30792
- s.stop("Plugin already installed");
30793
- if (isPluginDisabled()) {
30794
- runClaude(["plugin", "enable", PLUGIN_KEY]);
30795
- p.log.step("Plugin enabled");
30796
- }
30797
- } else {
30908
+ const state = pluginState();
30909
+ if (state === "missing") {
30910
+ s.start("Installing bitfab plugin");
30911
+ runCli(CLI, ["plugin", "install", PLUGIN_KEY, "--scope", "user"]);
30798
30912
  s.stop("Plugin installed");
30913
+ } else {
30914
+ if (state === "disabled") {
30915
+ runCli(CLI, ["plugin", "enable", PLUGIN_KEY]);
30916
+ p3.log.step("Plugin enabled");
30917
+ }
30918
+ ensureLatestClaudePlugin();
30799
30919
  }
30800
- p.log.success("Bitfab plugin ready in Claude Code");
30920
+ p3.log.success("Bitfab plugin ready in Claude Code");
30801
30921
  }
30802
- function runClaudeSetup(skipPermissions) {
30803
- p.log.info(`Launching ${SETUP_COMMAND}...
30804
- `);
30805
- const flags = skipPermissions ? ["--dangerously-skip-permissions"] : [];
30806
- spawnSync("claude", [...flags, SETUP_COMMAND], {
30807
- stdio: "inherit",
30808
- ...SHELL_OPTS
30809
- });
30922
+ function pullLatestClaudePlugin() {
30923
+ runCli(CLI, ["plugin", "marketplace", "update", MARKETPLACE]);
30924
+ return runCli(CLI, ["plugin", "update", PLUGIN_KEY, "--scope", "user"]);
30925
+ }
30926
+ function ensureLatestClaudePlugin() {
30927
+ ensureLatestPlugin(pullLatestClaudePlugin);
30810
30928
  }
30811
30929
  async function runClaudeAnalyzeRepo(captureOverride, limit) {
30812
30930
  const logPath = analyzeRepoLogPath();
@@ -30816,20 +30934,20 @@ async function runClaudeAnalyzeRepo(captureOverride, limit) {
30816
30934
  }
30817
30935
  const command = limit === void 0 ? ANALYZE_REPO_COMMAND : `${ANALYZE_REPO_COMMAND} limit=${limit}`;
30818
30936
  const out = fs20.createWriteStream(logPath);
30819
- const spinner3 = p.spinner();
30820
- spinner3.start("Analyzing repo and drafting trace plans");
30937
+ const spinner5 = p3.spinner();
30938
+ spinner5.start("Analyzing repo and drafting trace plans");
30821
30939
  const stdoutChunks = [];
30822
30940
  try {
30823
30941
  const exitCode = await new Promise((resolve2, reject) => {
30824
30942
  const child = spawn5(
30825
- "claude",
30943
+ CLI,
30826
30944
  [
30827
30945
  "-p",
30828
30946
  command,
30829
30947
  "--output-format",
30830
30948
  "stream-json",
30831
30949
  "--verbose",
30832
- "--dangerously-skip-permissions"
30950
+ SKIP_FLAG
30833
30951
  ],
30834
30952
  { stdio: ["ignore", "pipe", "pipe"], env, ...SHELL_OPTS }
30835
30953
  );
@@ -30839,7 +30957,7 @@ async function runClaudeAnalyzeRepo(captureOverride, limit) {
30839
30957
  stdoutChunks.push(text);
30840
30958
  const label = latestActivityLabel(text);
30841
30959
  if (label) {
30842
- spinner3.message(label);
30960
+ spinner5.message(label);
30843
30961
  }
30844
30962
  });
30845
30963
  child.stderr.on("data", (chunk2) => out.write(chunk2));
@@ -30852,16 +30970,16 @@ async function runClaudeAnalyzeRepo(captureOverride, limit) {
30852
30970
  );
30853
30971
  }
30854
30972
  const uploaded = countUploadedTracePlans(stdoutChunks.join(""));
30855
- spinner3.stop(
30973
+ spinner5.stop(
30856
30974
  uploaded === 0 ? "No AI workflows found - nothing to upload" : `Uploaded ${uploaded} draft trace plan${uploaded === 1 ? "" : "s"} to Bitfab`
30857
30975
  );
30858
30976
  } catch (err) {
30859
- spinner3.stop("analyze-repo failed");
30977
+ spinner5.stop("analyze-repo failed");
30860
30978
  throw err;
30861
30979
  } finally {
30862
30980
  out.end();
30863
30981
  }
30864
- p.log.info(`Full run log: ${logPath}`);
30982
+ p3.log.info(`Full run log: ${logPath}`);
30865
30983
  }
30866
30984
  function latestActivityLabel(chunk2) {
30867
30985
  const lines = chunk2.split("\n").filter((l) => l.trim() !== "");
@@ -30973,59 +31091,13 @@ function analyzeRepoLogPath() {
30973
31091
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
30974
31092
  return path17.join(dir, `analyze-repo-${stamp}.jsonl`);
30975
31093
  }
30976
- function runClaudeAssistant(args, skipPermissions) {
30977
- const cmd = [ASSISTANT_COMMAND, ...args].join(" ");
30978
- p.log.info(`Launching ${cmd}...
30979
- `);
30980
- const flags = skipPermissions ? ["--dangerously-skip-permissions"] : [];
30981
- spawnSync("claude", [...flags, ASSISTANT_COMMAND, ...args], {
30982
- stdio: "inherit",
30983
- ...SHELL_OPTS
30984
- });
30985
- }
30986
- function runClaudeUpdate(args, skipPermissions) {
30987
- const mode = args[0] === "plugin" || args[0] === "sdk" ? args[0] : "all";
30988
- if (mode === "plugin" || mode === "all") {
30989
- const s = p.spinner();
30990
- s.start("Refreshing bitfab marketplace");
30991
- runClaude(["plugin", "marketplace", "update", MARKETPLACE]);
30992
- s.stop("Marketplace refreshed");
30993
- s.start("Updating bitfab plugin");
30994
- const out = runClaude(["plugin", "update", PLUGIN_KEY, "--scope", "user"]);
30995
- if (out.includes("already") || out.includes("up to date")) {
30996
- s.stop("Plugin already up to date");
30997
- } else {
30998
- s.stop("Plugin updated");
30999
- }
31094
+ function pluginState() {
31095
+ const listOut = runCli(CLI, ["plugin", "list"]);
31096
+ const key = PLUGIN_KEY.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
31097
+ if (!new RegExp(key).test(listOut)) {
31098
+ return "missing";
31000
31099
  }
31001
- if (mode === "sdk" || mode === "all") {
31002
- p.log.info(`Launching ${UPDATE_COMMAND} sdk...
31003
- `);
31004
- const flags = skipPermissions ? ["--dangerously-skip-permissions"] : [];
31005
- spawnSync("claude", [...flags, UPDATE_COMMAND, "sdk"], {
31006
- stdio: "inherit",
31007
- ...SHELL_OPTS
31008
- });
31009
- }
31010
- }
31011
- function isPluginDisabled() {
31012
- const listOut = runClaude(["plugin", "list"]);
31013
- const pattern = new RegExp(
31014
- `${PLUGIN_KEY.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\n.*\\n.*\\n.*disabled`
31015
- );
31016
- return pattern.test(listOut);
31017
- }
31018
- function runClaude(args) {
31019
- const result = spawnSync("claude", [...args], {
31020
- stdio: "pipe",
31021
- ...SHELL_OPTS
31022
- });
31023
- if (result.status !== 0) {
31024
- throw new Error(
31025
- `claude ${args.join(" ")} failed${result.status === null ? "" : ` with status ${result.status}`}`
31026
- );
31027
- }
31028
- return (result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? "");
31100
+ return new RegExp(`${key}\\n.*\\n.*\\n.*disabled`).test(listOut) ? "disabled" : "enabled";
31029
31101
  }
31030
31102
  function enableAutoUpdate(settingsPath) {
31031
31103
  let settings = {};
@@ -31049,33 +31121,49 @@ function enableAutoUpdate(settingsPath) {
31049
31121
  `);
31050
31122
  return true;
31051
31123
  }
31124
+ var config2 = {
31125
+ cli: CLI,
31126
+ skipFlag: SKIP_FLAG,
31127
+ setupCommand: SETUP_COMMAND,
31128
+ assistantCommand: ASSISTANT_COMMAND,
31129
+ updateCommand: UPDATE_COMMAND,
31130
+ pullLatest: pullLatestClaudePlugin
31131
+ };
31132
+ var claudeAdapter = {
31133
+ label: "Claude Code",
31134
+ install: runClaudeInstall,
31135
+ ensureLatest: ensureLatestClaudePlugin,
31136
+ setup: (skipPermissions) => cliSetup(config2, skipPermissions),
31137
+ analyzeRepo: runClaudeAnalyzeRepo,
31138
+ assistant: (args, skipPermissions) => cliAssistant(config2, args, skipPermissions),
31139
+ update: (args, skipPermissions) => cliUpdate(config2, args, skipPermissions)
31140
+ };
31052
31141
 
31053
31142
  // src/codex.ts
31054
- import { spawnSync as spawnSync2 } from "child_process";
31055
31143
  import fs21 from "fs";
31056
31144
  import os16 from "os";
31057
31145
  import path18 from "path";
31058
- import * as p2 from "@clack/prompts";
31146
+ import * as p4 from "@clack/prompts";
31147
+ var CLI2 = "codex";
31148
+ var SKIP_FLAG2 = "--full-auto";
31059
31149
  var REPO2 = "Project-White-Rabbit/bitfab-codex-plugin";
31150
+ var MARKETPLACE2 = "bitfab";
31060
31151
  var PLUGIN_KEY2 = "bitfab@bitfab";
31061
31152
  var SETUP_COMMAND2 = "$bitfab:setup";
31062
31153
  var ASSISTANT_COMMAND2 = "$bitfab:assistant";
31063
31154
  var UPDATE_COMMAND2 = "$bitfab:update";
31064
- var SHELL_OPTS2 = process.platform === "win32" ? { shell: true } : {};
31155
+ function pullLatestCodexPlugin() {
31156
+ return runCli(CLI2, ["plugin", "marketplace", "upgrade", MARKETPLACE2]);
31157
+ }
31158
+ function ensureLatestCodexPlugin() {
31159
+ ensureLatestPlugin(pullLatestCodexPlugin);
31160
+ }
31065
31161
  function runCodexInstall() {
31066
- const s = p2.spinner();
31162
+ const s = p4.spinner();
31067
31163
  s.start("Adding bitfab marketplace");
31068
- const result = spawnSync2("codex", ["plugin", "marketplace", "add", REPO2], {
31069
- stdio: "pipe",
31070
- ...SHELL_OPTS2
31071
- });
31072
- if (result.status !== 0) {
31073
- throw new Error(
31074
- `codex plugin marketplace add failed${result.status === null ? "" : ` with status ${result.status}`}`
31075
- );
31076
- }
31077
- const out = (result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? "");
31078
- if (out.includes("already")) {
31164
+ const out = runCli(CLI2, ["plugin", "marketplace", "add", REPO2]);
31165
+ const alreadyConfigured = out.includes("already");
31166
+ if (alreadyConfigured) {
31079
31167
  s.stop("Marketplace already configured");
31080
31168
  } else {
31081
31169
  s.stop("Marketplace added");
@@ -31089,68 +31177,19 @@ function runCodexInstall() {
31089
31177
  } else {
31090
31178
  s.stop("Plugin already enabled");
31091
31179
  }
31092
- p2.log.success("Bitfab plugin ready in Codex");
31093
- }
31094
- function runCodexSetup(skipPermissions) {
31095
- p2.log.info(`Launching ${SETUP_COMMAND2}...
31096
- `);
31097
- const flags = skipPermissions ? ["--full-auto"] : [];
31098
- spawnSync2("codex", [...flags, SETUP_COMMAND2], {
31099
- stdio: "inherit",
31100
- ...SHELL_OPTS2
31101
- });
31180
+ if (alreadyConfigured) {
31181
+ ensureLatestCodexPlugin();
31182
+ }
31183
+ p4.log.success("Bitfab plugin ready in Codex");
31102
31184
  }
31103
31185
  function runCodexAnalyzeRepo() {
31104
- p2.log.warn(
31186
+ p4.log.warn(
31105
31187
  "Headless analyze-repo is currently supported for Claude Code only."
31106
31188
  );
31107
- p2.log.info(
31189
+ p4.log.info(
31108
31190
  `To run it in Codex, launch ${SETUP_COMMAND2} analyze-repo interactively.`
31109
31191
  );
31110
31192
  }
31111
- function runCodexAssistant(args, skipPermissions) {
31112
- const cmd = [ASSISTANT_COMMAND2, ...args].join(" ");
31113
- p2.log.info(`Launching ${cmd}...
31114
- `);
31115
- const flags = skipPermissions ? ["--full-auto"] : [];
31116
- spawnSync2("codex", [...flags, ASSISTANT_COMMAND2, ...args], {
31117
- stdio: "inherit",
31118
- ...SHELL_OPTS2
31119
- });
31120
- }
31121
- function runCodexUpdate(args, skipPermissions) {
31122
- const mode = args[0] === "plugin" || args[0] === "sdk" ? args[0] : "all";
31123
- if (mode === "plugin" || mode === "all") {
31124
- const s = p2.spinner();
31125
- s.start("Upgrading bitfab marketplace plugin");
31126
- const result = spawnSync2(
31127
- "codex",
31128
- ["plugin", "marketplace", "upgrade", "bitfab"],
31129
- { stdio: "pipe", ...SHELL_OPTS2 }
31130
- );
31131
- if (result.status !== 0) {
31132
- s.stop("Marketplace upgrade failed");
31133
- throw new Error(
31134
- `codex plugin marketplace upgrade failed${result.status === null ? "" : ` with status ${result.status}`}`
31135
- );
31136
- }
31137
- const out = (result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? "");
31138
- if (out.includes("already") || out.includes("up to date")) {
31139
- s.stop("Plugin already up to date");
31140
- } else {
31141
- s.stop("Plugin updated");
31142
- }
31143
- }
31144
- if (mode === "sdk" || mode === "all") {
31145
- p2.log.info(`Launching ${UPDATE_COMMAND2} sdk...
31146
- `);
31147
- const flags = skipPermissions ? ["--full-auto"] : [];
31148
- spawnSync2("codex", [...flags, UPDATE_COMMAND2, "sdk"], {
31149
- stdio: "inherit",
31150
- ...SHELL_OPTS2
31151
- });
31152
- }
31153
- }
31154
31193
  function enableCodexPlugin(configPath) {
31155
31194
  let content = "";
31156
31195
  if (fs21.existsSync(configPath)) {
@@ -31184,64 +31223,82 @@ ${desiredSection}`;
31184
31223
  function escapeRegex2(s) {
31185
31224
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
31186
31225
  }
31226
+ var config3 = {
31227
+ cli: CLI2,
31228
+ skipFlag: SKIP_FLAG2,
31229
+ setupCommand: SETUP_COMMAND2,
31230
+ assistantCommand: ASSISTANT_COMMAND2,
31231
+ updateCommand: UPDATE_COMMAND2,
31232
+ pullLatest: pullLatestCodexPlugin
31233
+ };
31234
+ var codexAdapter = {
31235
+ label: "Codex",
31236
+ install: runCodexInstall,
31237
+ ensureLatest: ensureLatestCodexPlugin,
31238
+ setup: (skipPermissions) => cliSetup(config3, skipPermissions),
31239
+ analyzeRepo: runCodexAnalyzeRepo,
31240
+ assistant: (args, skipPermissions) => cliAssistant(config3, args, skipPermissions),
31241
+ update: (args, skipPermissions) => cliUpdate(config3, args, skipPermissions)
31242
+ };
31187
31243
 
31188
31244
  // src/cursor.ts
31189
- import { spawn as spawn6, spawnSync as spawnSync3 } from "child_process";
31245
+ import { spawn as spawn6, spawnSync as spawnSync2 } from "child_process";
31190
31246
  import os17 from "os";
31191
- import * as p3 from "@clack/prompts";
31247
+ import * as p5 from "@clack/prompts";
31192
31248
  var REPO3 = "Project-White-Rabbit/bitfab-cursor-plugin";
31193
31249
  var ADD_PLUGIN_CMD = `/add-plugin ${REPO3}`;
31194
31250
  var SETUP_COMMAND3 = "/bitfab-setup";
31195
31251
  var ASSISTANT_COMMAND3 = "/bitfab-assistant";
31196
31252
  var UPDATE_COMMAND3 = "/bitfab-update";
31197
- var SHELL_OPTS3 = process.platform === "win32" ? { shell: true } : {};
31198
31253
  function runCursorInstall() {
31199
31254
  const copied = copyToClipboard(ADD_PLUGIN_CMD);
31200
31255
  if (copied) {
31201
- p3.log.success(`Copied to clipboard: ${ADD_PLUGIN_CMD}`);
31256
+ p5.log.success(`Copied to clipboard: ${ADD_PLUGIN_CMD}`);
31202
31257
  } else {
31203
- p3.log.warn(`Copy this command: ${ADD_PLUGIN_CMD}`);
31258
+ p5.log.warn(`Copy this command: ${ADD_PLUGIN_CMD}`);
31204
31259
  }
31205
- p3.note(
31260
+ p5.note(
31206
31261
  [
31207
31262
  `1. Run ${ADD_PLUGIN_CMD} (already in your clipboard)`,
31208
31263
  `2. Then run ${SETUP_COMMAND3}`
31209
31264
  ].join("\n"),
31210
31265
  "Finish setup in Cursor"
31211
31266
  );
31212
- p3.log.info("Opening Cursor...");
31267
+ p5.log.info("Opening Cursor...");
31213
31268
  const child = spawn6("cursor", ["."], {
31214
31269
  stdio: "ignore",
31215
31270
  detached: true,
31216
31271
  windowsHide: true,
31217
- ...SHELL_OPTS3
31272
+ ...SHELL_OPTS
31218
31273
  });
31219
31274
  child.on("error", () => {
31220
31275
  });
31221
31276
  child.unref();
31222
31277
  }
31278
+ function ensureLatestCursorPlugin() {
31279
+ }
31223
31280
  function runCursorSetup(skipPermissions) {
31224
31281
  if (skipPermissions) {
31225
- p3.log.warn("--skip-permissions is not supported for Cursor");
31282
+ p5.log.warn("--skip-permissions is not supported for Cursor");
31226
31283
  }
31227
- p3.log.info(`To complete setup, run ${SETUP_COMMAND3} in Cursor.`);
31284
+ p5.log.info(`To complete setup, run ${SETUP_COMMAND3} in Cursor.`);
31228
31285
  }
31229
31286
  function runCursorAnalyzeRepo() {
31230
- p3.log.warn(
31287
+ p5.log.warn(
31231
31288
  "Headless analyze-repo is currently supported for Claude Code only."
31232
31289
  );
31233
- p3.log.info(`To run it in Cursor, run ${SETUP_COMMAND3} analyze-repo manually.`);
31290
+ p5.log.info(`To run it in Cursor, run ${SETUP_COMMAND3} analyze-repo manually.`);
31234
31291
  }
31235
31292
  function runCursorAssistant(args, skipPermissions) {
31236
31293
  if (skipPermissions) {
31237
- p3.log.warn("--skip-permissions is not supported for Cursor");
31294
+ p5.log.warn("--skip-permissions is not supported for Cursor");
31238
31295
  }
31239
31296
  const cmd = [ASSISTANT_COMMAND3, ...args].join(" ");
31240
- p3.log.info(`To start the assistant, run ${cmd} in Cursor.`);
31297
+ p5.log.info(`To start the assistant, run ${cmd} in Cursor.`);
31241
31298
  }
31242
31299
  function runCursorUpdate(args, skipPermissions) {
31243
31300
  if (skipPermissions) {
31244
- p3.log.warn("--skip-permissions is not supported for Cursor");
31301
+ p5.log.warn("--skip-permissions is not supported for Cursor");
31245
31302
  }
31246
31303
  const mode = args[0] === "plugin" || args[0] === "sdk" ? args[0] : "all";
31247
31304
  const lines = [];
@@ -31251,14 +31308,14 @@ function runCursorUpdate(args, skipPermissions) {
31251
31308
  if (mode === "sdk" || mode === "all") {
31252
31309
  lines.push(`Run ${UPDATE_COMMAND3} sdk (updates installed SDKs)`);
31253
31310
  }
31254
- p3.note(lines.join("\n"), "Update Bitfab in Cursor");
31311
+ p5.note(lines.join("\n"), "Update Bitfab in Cursor");
31255
31312
  }
31256
31313
  function copyToClipboard(text) {
31257
31314
  const cmd = clipboardCommand();
31258
31315
  if (!cmd) {
31259
31316
  return false;
31260
31317
  }
31261
- const result = spawnSync3(cmd.bin, cmd.args, {
31318
+ const result = spawnSync2(cmd.bin, cmd.args, {
31262
31319
  input: text,
31263
31320
  stdio: ["pipe", "ignore", "ignore"]
31264
31321
  });
@@ -31276,6 +31333,15 @@ function clipboardCommand() {
31276
31333
  }
31277
31334
  return null;
31278
31335
  }
31336
+ var cursorAdapter = {
31337
+ label: "Cursor",
31338
+ install: runCursorInstall,
31339
+ ensureLatest: ensureLatestCursorPlugin,
31340
+ setup: runCursorSetup,
31341
+ analyzeRepo: runCursorAnalyzeRepo,
31342
+ assistant: runCursorAssistant,
31343
+ update: runCursorUpdate
31344
+ };
31279
31345
 
31280
31346
  // src/platform.ts
31281
31347
  var platform = {
@@ -31315,35 +31381,10 @@ async function runLoginCommand(options) {
31315
31381
 
31316
31382
  // src/init.ts
31317
31383
  var EDITORS = ["claude", "codex", "cursor"];
31318
- var EDITOR_LABEL = {
31319
- claude: "Claude Code",
31320
- codex: "Codex",
31321
- cursor: "Cursor"
31322
- };
31323
- var INSTALL_FN = {
31324
- claude: runClaudeInstall,
31325
- codex: runCodexInstall,
31326
- cursor: runCursorInstall
31327
- };
31328
- var SETUP_FN = {
31329
- claude: runClaudeSetup,
31330
- codex: runCodexSetup,
31331
- cursor: runCursorSetup
31332
- };
31333
- var ANALYZE_REPO_FN = {
31334
- claude: runClaudeAnalyzeRepo,
31335
- codex: runCodexAnalyzeRepo,
31336
- cursor: runCursorAnalyzeRepo
31337
- };
31338
- var ASSISTANT_FN = {
31339
- claude: runClaudeAssistant,
31340
- codex: runCodexAssistant,
31341
- cursor: runCursorAssistant
31342
- };
31343
- var UPDATE_FN = {
31344
- claude: runClaudeUpdate,
31345
- codex: runCodexUpdate,
31346
- cursor: runCursorUpdate
31384
+ var ADAPTERS = {
31385
+ claude: claudeAdapter,
31386
+ codex: codexAdapter,
31387
+ cursor: cursorAdapter
31347
31388
  };
31348
31389
  function detectInstalledEditors() {
31349
31390
  return EDITORS.filter((e) => isOnPath(e));
@@ -31359,18 +31400,18 @@ function isOnPath(binary) {
31359
31400
  }
31360
31401
  async function pickEditor(detected) {
31361
31402
  if (detected.length === 1) {
31362
- p4.log.info(`Detected ${EDITOR_LABEL[detected[0]]}`);
31403
+ p6.log.info(`Detected ${ADAPTERS[detected[0]].label}`);
31363
31404
  return detected[0];
31364
31405
  }
31365
- const choice = await p4.select({
31366
- message: "Which editor should we set up?",
31406
+ const choice = await p6.select({
31407
+ message: "Which agent should we use?",
31367
31408
  options: detected.map((e) => ({
31368
31409
  value: e,
31369
- label: EDITOR_LABEL[e]
31410
+ label: ADAPTERS[e].label
31370
31411
  }))
31371
31412
  });
31372
- if (p4.isCancel(choice)) {
31373
- p4.cancel("Setup cancelled.");
31413
+ if (p6.isCancel(choice)) {
31414
+ p6.cancel("Setup cancelled.");
31374
31415
  process.exit(0);
31375
31416
  }
31376
31417
  return choice;
@@ -31379,12 +31420,12 @@ async function resolveSkipPermissions(value) {
31379
31420
  if (value !== void 0) {
31380
31421
  return value;
31381
31422
  }
31382
- const answer = await p4.confirm({
31423
+ const answer = await p6.confirm({
31383
31424
  message: "Skip permission prompts? (runs the agent autonomously)",
31384
31425
  initialValue: false
31385
31426
  });
31386
- if (p4.isCancel(answer)) {
31387
- p4.cancel("Cancelled.");
31427
+ if (p6.isCancel(answer)) {
31428
+ p6.cancel("Cancelled.");
31388
31429
  process.exit(0);
31389
31430
  }
31390
31431
  return answer;
@@ -31395,7 +31436,7 @@ async function resolveCaptureOverride(flag) {
31395
31436
  }
31396
31437
  const existing = getSessionLogConsent();
31397
31438
  if (existing !== null) {
31398
- p4.log.step(
31439
+ p6.log.step(
31399
31440
  existing ? "Session logs: enabled (saved preference)." : "Session logs: disabled (saved preference)."
31400
31441
  );
31401
31442
  return void 0;
@@ -31403,12 +31444,12 @@ async function resolveCaptureOverride(flag) {
31403
31444
  if (!process.stdin.isTTY) {
31404
31445
  return false;
31405
31446
  }
31406
- const answer = await p4.confirm({
31447
+ const answer = await p6.confirm({
31407
31448
  message: "Allow Bitfab to collect session logs? (used to diagnose issues and improve the product)",
31408
31449
  initialValue: true
31409
31450
  });
31410
- if (p4.isCancel(answer)) {
31411
- p4.cancel("Cancelled.");
31451
+ if (p6.isCancel(answer)) {
31452
+ p6.cancel("Cancelled.");
31412
31453
  process.exit(0);
31413
31454
  }
31414
31455
  setSessionLogConsent(answer);
@@ -31417,21 +31458,21 @@ async function resolveCaptureOverride(flag) {
31417
31458
  async function resolveEditor({ editor }) {
31418
31459
  const detected = detectInstalledEditors();
31419
31460
  if (detected.length === 0) {
31420
- p4.cancel(
31461
+ p6.cancel(
31421
31462
  "No supported editor found on PATH. Install Claude Code, Codex, or Cursor and try again."
31422
31463
  );
31423
31464
  process.exit(1);
31424
31465
  }
31425
31466
  if (editor) {
31426
31467
  if (!EDITORS.includes(editor)) {
31427
- p4.cancel(
31468
+ p6.cancel(
31428
31469
  `Unknown editor: ${editor}. Expected one of: ${EDITORS.join(", ")}`
31429
31470
  );
31430
31471
  process.exit(1);
31431
31472
  }
31432
31473
  if (!detected.includes(editor)) {
31433
- p4.cancel(
31434
- `${EDITOR_LABEL[editor]} is not installed ("${editor}" not found on PATH).`
31474
+ p6.cancel(
31475
+ `${ADAPTERS[editor].label} is not installed ("${editor}" not found on PATH).`
31435
31476
  );
31436
31477
  process.exit(1);
31437
31478
  }
@@ -31440,71 +31481,73 @@ async function resolveEditor({ editor }) {
31440
31481
  return pickEditor(detected);
31441
31482
  }
31442
31483
  async function runInstall(opts) {
31443
- p4.intro("bitfab");
31484
+ p6.intro("bitfab");
31444
31485
  const chosen = await resolveEditor(opts);
31445
- p4.log.step(`Installing Bitfab in ${EDITOR_LABEL[chosen]}`);
31446
- INSTALL_FN[chosen]();
31447
- p4.outro("Done!");
31486
+ p6.log.step(`Installing Bitfab in ${ADAPTERS[chosen].label}`);
31487
+ ADAPTERS[chosen].install();
31488
+ p6.outro("Done!");
31448
31489
  }
31449
31490
  async function runSetup(opts) {
31450
31491
  const chosen = await resolveEditor(opts);
31492
+ ADAPTERS[chosen].ensureLatest();
31451
31493
  const skip = await resolveSkipPermissions(opts.skipPermissions);
31452
- SETUP_FN[chosen](skip);
31494
+ ADAPTERS[chosen].setup(skip);
31453
31495
  }
31454
31496
  async function runAssistant(opts, args) {
31455
31497
  const chosen = await resolveEditor(opts);
31498
+ ADAPTERS[chosen].ensureLatest();
31456
31499
  const skip = await resolveSkipPermissions(opts.skipPermissions);
31457
- ASSISTANT_FN[chosen](args, skip);
31500
+ ADAPTERS[chosen].assistant(args, skip);
31458
31501
  }
31459
31502
  async function runUpdate2(opts, args) {
31460
31503
  const chosen = await resolveEditor(opts);
31461
31504
  const skip = await resolveSkipPermissions(opts.skipPermissions);
31462
- UPDATE_FN[chosen](args, skip);
31505
+ ADAPTERS[chosen].update(args, skip);
31463
31506
  }
31464
31507
  async function runInit(opts) {
31465
- p4.intro("bitfab");
31508
+ p6.intro("bitfab");
31466
31509
  const chosen = await resolveEditor(opts);
31467
- p4.log.step(`Setting up Bitfab in ${EDITOR_LABEL[chosen]}`);
31468
- INSTALL_FN[chosen]();
31510
+ p6.log.step(`Setting up Bitfab in ${ADAPTERS[chosen].label}`);
31511
+ ADAPTERS[chosen].install();
31469
31512
  const loggedInEmail = await checkAuth();
31470
31513
  if (loggedInEmail) {
31471
- p4.log.success(`Already logged in as ${loggedInEmail}`);
31514
+ p6.log.success(`Already logged in as ${loggedInEmail}`);
31472
31515
  } else {
31473
- p4.log.step("Signing in to Bitfab");
31516
+ p6.log.step("Signing in to Bitfab");
31474
31517
  await runLoginCommand({ exitOnComplete: false });
31475
31518
  }
31476
31519
  const skip = await resolveSkipPermissions(opts.skipPermissions);
31477
- SETUP_FN[chosen](skip);
31520
+ ADAPTERS[chosen].setup(skip);
31478
31521
  const detected = detectInstalledEditors();
31479
31522
  const others = detected.filter((e) => e !== chosen);
31480
31523
  if (others.length > 0) {
31481
- p4.note(
31524
+ p6.note(
31482
31525
  others.map((e) => `bitfab init --editor ${e}`).join("\n"),
31483
31526
  "Set up another editor"
31484
31527
  );
31485
31528
  }
31486
- p4.outro("Done!");
31529
+ p6.outro("Done!");
31487
31530
  }
31488
31531
  async function runAnalyzeRepo(opts) {
31489
- p4.intro("bitfab");
31532
+ p6.intro("bitfab");
31490
31533
  const chosen = await resolveEditor(opts);
31491
- p4.log.step(`Setting up Bitfab in ${EDITOR_LABEL[chosen]}`);
31492
- INSTALL_FN[chosen]();
31534
+ p6.log.step(`Setting up Bitfab in ${ADAPTERS[chosen].label}`);
31535
+ ADAPTERS[chosen].install();
31493
31536
  if (chosen !== "claude") {
31494
- ANALYZE_REPO_FN[chosen]();
31537
+ ADAPTERS[chosen].analyzeRepo();
31495
31538
  process.exit(1);
31496
31539
  }
31497
31540
  const loggedInEmail = await checkAuth();
31498
31541
  if (!loggedInEmail) {
31499
- p4.cancel(
31542
+ p6.cancel(
31500
31543
  "Not authenticated. Run `bitfab login` (or set BITFAB_API_KEY) before `bitfab analyze-repo` - it is non-interactive and cannot open a browser."
31501
31544
  );
31502
31545
  process.exit(1);
31503
31546
  }
31504
- p4.log.success(`Logged in as ${loggedInEmail}`);
31547
+ p6.log.success(`Logged in as ${loggedInEmail}`);
31505
31548
  const captureOverride = await resolveCaptureOverride(opts.uploadLogs);
31506
- await ANALYZE_REPO_FN[chosen](captureOverride, opts.limit);
31507
- p4.outro("Done!");
31549
+ await ADAPTERS[chosen].analyzeRepo(captureOverride, opts.limit);
31550
+ p6.outro("Done!");
31508
31551
  }
31509
31552
  async function checkAuth() {
31510
31553
  const { apiKey, serviceUrl } = getConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitfab-cli",
3
- "version": "0.2.167",
3
+ "version": "0.2.169",
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",