bitfab-cli 0.2.186 → 0.2.187
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +109 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9566,6 +9566,40 @@ function updateActiveStudioSession(updates) {
|
|
|
9566
9566
|
writeStateFile(sessionFilePath(), updated);
|
|
9567
9567
|
return updated;
|
|
9568
9568
|
}
|
|
9569
|
+
function clearActiveStudioSession(sessionId, opts = {}) {
|
|
9570
|
+
try {
|
|
9571
|
+
const current = readStateFile(sessionFilePath());
|
|
9572
|
+
if (!current) {
|
|
9573
|
+
return clearLegacySession(sessionId, opts);
|
|
9574
|
+
}
|
|
9575
|
+
if (current.sessionId !== sessionId) {
|
|
9576
|
+
return false;
|
|
9577
|
+
}
|
|
9578
|
+
if (!opts.force && current.pollerPid != null && current.pollerPid !== process.pid && isProcessAlive(current.pollerPid)) {
|
|
9579
|
+
return false;
|
|
9580
|
+
}
|
|
9581
|
+
fs7.unlinkSync(sessionFilePath());
|
|
9582
|
+
return true;
|
|
9583
|
+
} catch {
|
|
9584
|
+
return false;
|
|
9585
|
+
}
|
|
9586
|
+
}
|
|
9587
|
+
function clearLegacySession(sessionId, opts = {}) {
|
|
9588
|
+
try {
|
|
9589
|
+
const raw = fs7.readFileSync(legacyFilePath(), "utf-8");
|
|
9590
|
+
const parsed = JSON.parse(raw);
|
|
9591
|
+
if (parsed.sessionId !== sessionId) {
|
|
9592
|
+
return false;
|
|
9593
|
+
}
|
|
9594
|
+
if (!opts.force && typeof parsed.pid === "number" && parsed.pid !== process.pid && isProcessAlive(parsed.pid)) {
|
|
9595
|
+
return false;
|
|
9596
|
+
}
|
|
9597
|
+
fs7.unlinkSync(legacyFilePath());
|
|
9598
|
+
return true;
|
|
9599
|
+
} catch {
|
|
9600
|
+
return false;
|
|
9601
|
+
}
|
|
9602
|
+
}
|
|
9569
9603
|
function isProcessAlive(pid) {
|
|
9570
9604
|
try {
|
|
9571
9605
|
process.kill(pid, 0);
|
|
@@ -11003,6 +11037,48 @@ async function resolveChannel(apiKey, serviceUrl) {
|
|
|
11003
11037
|
return new DirectChannel(apiKey, serviceUrl);
|
|
11004
11038
|
}
|
|
11005
11039
|
|
|
11040
|
+
// ../bitfab-plugin-lib/dist/studioTeardown.js
|
|
11041
|
+
function killStudioWindow(sessionId) {
|
|
11042
|
+
const record2 = readActiveStudioSession();
|
|
11043
|
+
if (record2?.sessionId !== sessionId || record2.windowPid == null) {
|
|
11044
|
+
return;
|
|
11045
|
+
}
|
|
11046
|
+
try {
|
|
11047
|
+
process.kill(record2.windowPid, "SIGTERM");
|
|
11048
|
+
} catch {
|
|
11049
|
+
}
|
|
11050
|
+
}
|
|
11051
|
+
function killPollerProcess(sessionId) {
|
|
11052
|
+
const record2 = readActiveStudioSession();
|
|
11053
|
+
if (record2?.sessionId !== sessionId || record2.pollerPid == null || record2.pollerPid === process.pid) {
|
|
11054
|
+
return;
|
|
11055
|
+
}
|
|
11056
|
+
try {
|
|
11057
|
+
process.kill(record2.pollerPid, "SIGTERM");
|
|
11058
|
+
} catch {
|
|
11059
|
+
}
|
|
11060
|
+
}
|
|
11061
|
+
|
|
11062
|
+
// ../bitfab-plugin-lib/dist/commands/clearStudioSession.js
|
|
11063
|
+
async function clearStudioSessionById(sessionId, record2) {
|
|
11064
|
+
killStudioWindow(sessionId);
|
|
11065
|
+
const alreadyClosed = record2?.sessionId === sessionId && record2.windowState === "closed";
|
|
11066
|
+
if (!alreadyClosed) {
|
|
11067
|
+
closeStudioWindowsBySession(sessionId);
|
|
11068
|
+
}
|
|
11069
|
+
killPollerProcess(sessionId);
|
|
11070
|
+
try {
|
|
11071
|
+
const channel = await resolveChannel("", record2?.serviceUrl ?? "");
|
|
11072
|
+
try {
|
|
11073
|
+
await channel.clearSession(sessionId);
|
|
11074
|
+
} finally {
|
|
11075
|
+
channel.destroy();
|
|
11076
|
+
}
|
|
11077
|
+
} catch {
|
|
11078
|
+
}
|
|
11079
|
+
return clearActiveStudioSession(sessionId, { force: true });
|
|
11080
|
+
}
|
|
11081
|
+
|
|
11006
11082
|
// ../bitfab-plugin-lib/dist/replayCapabilities.js
|
|
11007
11083
|
var semver = __toESM(require_semver2(), 1);
|
|
11008
11084
|
|
|
@@ -11451,6 +11527,13 @@ Already logged in as ${identity}${endpoint}. Run the login command with --force
|
|
|
11451
11527
|
return;
|
|
11452
11528
|
}
|
|
11453
11529
|
}
|
|
11530
|
+
if (force) {
|
|
11531
|
+
const record2 = readActiveStudioSession();
|
|
11532
|
+
if (record2) {
|
|
11533
|
+
await clearStudioSessionById(record2.sessionId, record2).catch(() => {
|
|
11534
|
+
});
|
|
11535
|
+
}
|
|
11536
|
+
}
|
|
11454
11537
|
try {
|
|
11455
11538
|
let printedSignInUrl = false;
|
|
11456
11539
|
const result = await openStudioTo("/studio", {
|
|
@@ -11495,7 +11578,7 @@ ${greeting}`);
|
|
|
11495
11578
|
} catch (err) {
|
|
11496
11579
|
if (exitOnComplete) {
|
|
11497
11580
|
if (err instanceof StudioNavigationError && err.staleSessionId) {
|
|
11498
|
-
console.error("\nA Studio window is recorded as open but is not responding. Close
|
|
11581
|
+
console.error("\nA Studio window is recorded as open but is not responding. Close the Studio window and try again. To force-clear a stale session, a user can re-run with `bitfab login --force` (manual recovery - automated agents should not run it).");
|
|
11499
11582
|
} else {
|
|
11500
11583
|
console.error(`
|
|
11501
11584
|
${err.message}`);
|
|
@@ -33004,7 +33087,7 @@ var GLOBAL_HELP_TEXT = `Usage: bitfab <command> [options]
|
|
|
33004
33087
|
Commands:
|
|
33005
33088
|
init [--editor <name>] Full onboarding: plugin-install, login, and setup
|
|
33006
33089
|
plugin-install [--editor <name>] Install the Bitfab plugin in one editor
|
|
33007
|
-
login
|
|
33090
|
+
login [--force] Authenticate with Bitfab (opens browser)
|
|
33008
33091
|
logout Remove stored credentials
|
|
33009
33092
|
session-logs [status|enable|disable] Read or update session log collection
|
|
33010
33093
|
setup [--editor <name>] Launch /bitfab:setup in the editor
|
|
@@ -33021,6 +33104,7 @@ Options:
|
|
|
33021
33104
|
--no-upload-logs analyze-repo: keep session logs local (skips the prompt)
|
|
33022
33105
|
--limit <n> analyze-repo: cap how many draft trace plans to upload (default 5)
|
|
33023
33106
|
--prompt, -p <text> analyze-repo: free-text guidance steering what to focus on
|
|
33107
|
+
--force login: re-authenticate and clear any stale Studio session first
|
|
33024
33108
|
|
|
33025
33109
|
Examples:
|
|
33026
33110
|
bitfab init Full setup (detect editor, install, login, setup)
|
|
@@ -33028,6 +33112,7 @@ Examples:
|
|
|
33028
33112
|
bitfab analyze-repo Scan the repo and upload draft trace plans (headless)
|
|
33029
33113
|
bitfab analyze-repo --limit 3 Scan the repo and upload at most 3 draft trace plans
|
|
33030
33114
|
bitfab analyze-repo "focus on billing" Scan with free-text guidance on what to prioritize
|
|
33115
|
+
bitfab login --force Re-authenticate and clear a stale Studio session
|
|
33031
33116
|
bitfab session-logs enable Enable session log collection
|
|
33032
33117
|
bitfab session-logs disable Disable session log collection
|
|
33033
33118
|
bitfab assistant investigate Investigate traces
|
|
@@ -33060,15 +33145,16 @@ Examples:
|
|
|
33060
33145
|
bitfab plugin-install
|
|
33061
33146
|
bitfab plugin-install --editor cursor
|
|
33062
33147
|
`,
|
|
33063
|
-
login: `Usage: bitfab login
|
|
33148
|
+
login: `Usage: bitfab login [--force]
|
|
33064
33149
|
|
|
33065
33150
|
Authenticate with Bitfab in the browser and save credentials locally.
|
|
33066
33151
|
|
|
33067
33152
|
Options:
|
|
33068
|
-
|
|
33153
|
+
--force Re-authenticate even when already signed in, and clear any stale Studio session first
|
|
33069
33154
|
|
|
33070
33155
|
Examples:
|
|
33071
33156
|
bitfab login
|
|
33157
|
+
bitfab login --force
|
|
33072
33158
|
`,
|
|
33073
33159
|
logout: `Usage: bitfab logout
|
|
33074
33160
|
|
|
@@ -33230,7 +33316,7 @@ function wantsHelp(argv) {
|
|
|
33230
33316
|
var COMMAND_SPECS = {
|
|
33231
33317
|
init: { flags: ["editor", "skipPermissions"], unknownOption: "error" },
|
|
33232
33318
|
"plugin-install": { flags: ["editor"], unknownOption: "error" },
|
|
33233
|
-
login: { flags: [], unknownOption: "error" },
|
|
33319
|
+
login: { flags: ["force"], unknownOption: "error" },
|
|
33234
33320
|
logout: { flags: [], unknownOption: "error" },
|
|
33235
33321
|
"session-logs": { flags: [], unknownOption: "error" },
|
|
33236
33322
|
setup: { flags: ["editor", "skipPermissions"], unknownOption: "error" },
|
|
@@ -33304,6 +33390,12 @@ function applyFlag(key, token, next, values) {
|
|
|
33304
33390
|
return 1;
|
|
33305
33391
|
}
|
|
33306
33392
|
return null;
|
|
33393
|
+
case "force":
|
|
33394
|
+
if (token === "--force") {
|
|
33395
|
+
values.force = true;
|
|
33396
|
+
return 1;
|
|
33397
|
+
}
|
|
33398
|
+
return null;
|
|
33307
33399
|
}
|
|
33308
33400
|
}
|
|
33309
33401
|
function parseArgs2(argv) {
|
|
@@ -33350,6 +33442,7 @@ function parseArgs2(argv) {
|
|
|
33350
33442
|
uploadLogs: values.uploadLogs,
|
|
33351
33443
|
limit: values.limit,
|
|
33352
33444
|
prompt: values.prompt,
|
|
33445
|
+
force: values.force,
|
|
33353
33446
|
rest
|
|
33354
33447
|
};
|
|
33355
33448
|
}
|
|
@@ -33369,7 +33462,16 @@ ${GLOBAL_HELP_TEXT}`
|
|
|
33369
33462
|
process.stdout.write(helpText);
|
|
33370
33463
|
return;
|
|
33371
33464
|
}
|
|
33372
|
-
const {
|
|
33465
|
+
const {
|
|
33466
|
+
command,
|
|
33467
|
+
editor,
|
|
33468
|
+
skipPermissions,
|
|
33469
|
+
uploadLogs,
|
|
33470
|
+
limit,
|
|
33471
|
+
prompt,
|
|
33472
|
+
force,
|
|
33473
|
+
rest
|
|
33474
|
+
} = parseArgs2(argv);
|
|
33373
33475
|
const abortUpdateCheck = startUpdateCheck();
|
|
33374
33476
|
if (command === "init") {
|
|
33375
33477
|
await runInit({ editor, skipPermissions });
|
|
@@ -33382,7 +33484,7 @@ ${GLOBAL_HELP_TEXT}`
|
|
|
33382
33484
|
return;
|
|
33383
33485
|
}
|
|
33384
33486
|
if (command === "login") {
|
|
33385
|
-
await runLoginCommand();
|
|
33487
|
+
await runLoginCommand({ force });
|
|
33386
33488
|
abortUpdateCheck();
|
|
33387
33489
|
return;
|
|
33388
33490
|
}
|