bitfab-cli 0.2.163 → 0.2.164
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 +285 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9315,6 +9315,16 @@ function getSessionLogConsentValue() {
|
|
|
9315
9315
|
}
|
|
9316
9316
|
return null;
|
|
9317
9317
|
}
|
|
9318
|
+
function getSessionLogConsent() {
|
|
9319
|
+
return getSessionLogConsentValue();
|
|
9320
|
+
}
|
|
9321
|
+
function setSessionLogConsent(value) {
|
|
9322
|
+
fs3.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
|
|
9323
|
+
const existing = readJsonFile(GLOBAL_CONFIG_FILE) ?? {};
|
|
9324
|
+
existing.sessionLogConsent = value;
|
|
9325
|
+
fs3.writeFileSync(GLOBAL_CONFIG_FILE, `${JSON.stringify(existing, null, 2)}
|
|
9326
|
+
`);
|
|
9327
|
+
}
|
|
9318
9328
|
function getConfig() {
|
|
9319
9329
|
return {
|
|
9320
9330
|
serviceUrl: getServiceUrl(),
|
|
@@ -30739,7 +30749,7 @@ var tracePlanTreeShape = external_exports.object({
|
|
|
30739
30749
|
});
|
|
30740
30750
|
|
|
30741
30751
|
// src/claude.ts
|
|
30742
|
-
import { spawnSync } from "child_process";
|
|
30752
|
+
import { spawn as spawn5, spawnSync } from "child_process";
|
|
30743
30753
|
import fs20 from "fs";
|
|
30744
30754
|
import os15 from "os";
|
|
30745
30755
|
import path17 from "path";
|
|
@@ -30748,6 +30758,7 @@ var REPO = "Project-White-Rabbit/bitfab-claude-plugin";
|
|
|
30748
30758
|
var MARKETPLACE = "bitfab";
|
|
30749
30759
|
var PLUGIN_KEY = "bitfab@bitfab";
|
|
30750
30760
|
var SETUP_COMMAND = "/bitfab:setup";
|
|
30761
|
+
var ANALYZE_REPO_COMMAND = "/bitfab:setup analyze-repo";
|
|
30751
30762
|
var ASSISTANT_COMMAND = "/bitfab:assistant";
|
|
30752
30763
|
var UPDATE_COMMAND = "/bitfab:update";
|
|
30753
30764
|
var SHELL_OPTS = process.platform === "win32" ? { shell: true } : {};
|
|
@@ -30797,6 +30808,171 @@ function runClaudeSetup(skipPermissions) {
|
|
|
30797
30808
|
...SHELL_OPTS
|
|
30798
30809
|
});
|
|
30799
30810
|
}
|
|
30811
|
+
async function runClaudeAnalyzeRepo(captureOverride, limit) {
|
|
30812
|
+
const logPath = analyzeRepoLogPath();
|
|
30813
|
+
const env = { ...process.env };
|
|
30814
|
+
if (captureOverride !== void 0) {
|
|
30815
|
+
env.BITFAB_CAPTURE_SESSIONS = captureOverride ? "1" : "0";
|
|
30816
|
+
}
|
|
30817
|
+
const command = limit === void 0 ? ANALYZE_REPO_COMMAND : `${ANALYZE_REPO_COMMAND} limit=${limit}`;
|
|
30818
|
+
const out = fs20.createWriteStream(logPath);
|
|
30819
|
+
const spinner3 = p.spinner();
|
|
30820
|
+
spinner3.start("Analyzing repo and drafting trace plans");
|
|
30821
|
+
const stdoutChunks = [];
|
|
30822
|
+
try {
|
|
30823
|
+
const exitCode = await new Promise((resolve2, reject) => {
|
|
30824
|
+
const child = spawn5(
|
|
30825
|
+
"claude",
|
|
30826
|
+
[
|
|
30827
|
+
"-p",
|
|
30828
|
+
command,
|
|
30829
|
+
"--output-format",
|
|
30830
|
+
"stream-json",
|
|
30831
|
+
"--verbose",
|
|
30832
|
+
"--dangerously-skip-permissions"
|
|
30833
|
+
],
|
|
30834
|
+
{ stdio: ["ignore", "pipe", "pipe"], env, ...SHELL_OPTS }
|
|
30835
|
+
);
|
|
30836
|
+
child.stdout.on("data", (chunk2) => {
|
|
30837
|
+
out.write(chunk2);
|
|
30838
|
+
const text = chunk2.toString();
|
|
30839
|
+
stdoutChunks.push(text);
|
|
30840
|
+
const label = latestActivityLabel(text);
|
|
30841
|
+
if (label) {
|
|
30842
|
+
spinner3.message(label);
|
|
30843
|
+
}
|
|
30844
|
+
});
|
|
30845
|
+
child.stderr.on("data", (chunk2) => out.write(chunk2));
|
|
30846
|
+
child.on("error", reject);
|
|
30847
|
+
child.on("close", (code) => resolve2(code ?? 0));
|
|
30848
|
+
});
|
|
30849
|
+
if (exitCode !== 0) {
|
|
30850
|
+
throw new Error(
|
|
30851
|
+
`analyze-repo exited with status ${exitCode}. See ${logPath}`
|
|
30852
|
+
);
|
|
30853
|
+
}
|
|
30854
|
+
const uploaded = countUploadedTracePlans(stdoutChunks.join(""));
|
|
30855
|
+
spinner3.stop(
|
|
30856
|
+
uploaded === 0 ? "No AI workflows found - nothing to upload" : `Uploaded ${uploaded} draft trace plan${uploaded === 1 ? "" : "s"} to Bitfab`
|
|
30857
|
+
);
|
|
30858
|
+
} catch (err) {
|
|
30859
|
+
spinner3.stop("analyze-repo failed");
|
|
30860
|
+
throw err;
|
|
30861
|
+
} finally {
|
|
30862
|
+
out.end();
|
|
30863
|
+
}
|
|
30864
|
+
p.log.info(`Full run log: ${logPath}`);
|
|
30865
|
+
}
|
|
30866
|
+
function latestActivityLabel(chunk2) {
|
|
30867
|
+
const lines = chunk2.split("\n").filter((l) => l.trim() !== "");
|
|
30868
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
30869
|
+
let event;
|
|
30870
|
+
try {
|
|
30871
|
+
event = JSON.parse(lines[i]);
|
|
30872
|
+
} catch {
|
|
30873
|
+
continue;
|
|
30874
|
+
}
|
|
30875
|
+
const label = activityLabelFromEvent(event);
|
|
30876
|
+
if (label) {
|
|
30877
|
+
return label;
|
|
30878
|
+
}
|
|
30879
|
+
}
|
|
30880
|
+
return null;
|
|
30881
|
+
}
|
|
30882
|
+
function activityLabelFromEvent(event) {
|
|
30883
|
+
const content = eventMessageContent(event);
|
|
30884
|
+
if (!content) {
|
|
30885
|
+
return null;
|
|
30886
|
+
}
|
|
30887
|
+
for (const block of content) {
|
|
30888
|
+
if (typeof block !== "object" || block === null) {
|
|
30889
|
+
continue;
|
|
30890
|
+
}
|
|
30891
|
+
if (block.type !== "tool_use") {
|
|
30892
|
+
continue;
|
|
30893
|
+
}
|
|
30894
|
+
const label = friendlyToolLabel(block);
|
|
30895
|
+
if (label) {
|
|
30896
|
+
return label;
|
|
30897
|
+
}
|
|
30898
|
+
}
|
|
30899
|
+
return null;
|
|
30900
|
+
}
|
|
30901
|
+
function friendlyToolLabel(block) {
|
|
30902
|
+
const name = typeof block.name === "string" ? block.name : "";
|
|
30903
|
+
if (name.includes("create_trace_plan")) {
|
|
30904
|
+
return "Uploading a draft trace plan";
|
|
30905
|
+
}
|
|
30906
|
+
if (name.includes("get_bitfab_api_key")) {
|
|
30907
|
+
return "Checking authentication";
|
|
30908
|
+
}
|
|
30909
|
+
const input = typeof block.input === "object" && block.input !== null ? block.input : {};
|
|
30910
|
+
switch (name) {
|
|
30911
|
+
case "Read": {
|
|
30912
|
+
const file2 = typeof input.file_path === "string" ? path17.basename(input.file_path) : "";
|
|
30913
|
+
return file2 ? `Reading ${file2}` : "Reading files";
|
|
30914
|
+
}
|
|
30915
|
+
case "Grep":
|
|
30916
|
+
case "Glob":
|
|
30917
|
+
return "Searching the codebase";
|
|
30918
|
+
case "WebFetch":
|
|
30919
|
+
return "Reading SDK docs";
|
|
30920
|
+
default:
|
|
30921
|
+
return null;
|
|
30922
|
+
}
|
|
30923
|
+
}
|
|
30924
|
+
function eventMessageContent(event) {
|
|
30925
|
+
if (typeof event !== "object" || event === null) {
|
|
30926
|
+
return null;
|
|
30927
|
+
}
|
|
30928
|
+
const message = event.message;
|
|
30929
|
+
const content = typeof message === "object" && message !== null ? message.content : void 0;
|
|
30930
|
+
return Array.isArray(content) ? content : null;
|
|
30931
|
+
}
|
|
30932
|
+
function countUploadedTracePlans(logText) {
|
|
30933
|
+
const planToolUseIds = /* @__PURE__ */ new Set();
|
|
30934
|
+
const nonErrorResultIds = /* @__PURE__ */ new Set();
|
|
30935
|
+
for (const line of logText.split("\n")) {
|
|
30936
|
+
if (line.trim() === "") {
|
|
30937
|
+
continue;
|
|
30938
|
+
}
|
|
30939
|
+
let event;
|
|
30940
|
+
try {
|
|
30941
|
+
event = JSON.parse(line);
|
|
30942
|
+
} catch {
|
|
30943
|
+
continue;
|
|
30944
|
+
}
|
|
30945
|
+
const content = eventMessageContent(event);
|
|
30946
|
+
if (!content) {
|
|
30947
|
+
continue;
|
|
30948
|
+
}
|
|
30949
|
+
for (const block of content) {
|
|
30950
|
+
if (typeof block !== "object" || block === null) {
|
|
30951
|
+
continue;
|
|
30952
|
+
}
|
|
30953
|
+
const b = block;
|
|
30954
|
+
if (b.type === "tool_use" && typeof b.id === "string" && typeof b.name === "string" && b.name.includes("create_trace_plan")) {
|
|
30955
|
+
planToolUseIds.add(b.id);
|
|
30956
|
+
}
|
|
30957
|
+
if (b.type === "tool_result" && typeof b.tool_use_id === "string" && b.is_error !== true) {
|
|
30958
|
+
nonErrorResultIds.add(b.tool_use_id);
|
|
30959
|
+
}
|
|
30960
|
+
}
|
|
30961
|
+
}
|
|
30962
|
+
let count = 0;
|
|
30963
|
+
for (const id of planToolUseIds) {
|
|
30964
|
+
if (nonErrorResultIds.has(id)) {
|
|
30965
|
+
count++;
|
|
30966
|
+
}
|
|
30967
|
+
}
|
|
30968
|
+
return count;
|
|
30969
|
+
}
|
|
30970
|
+
function analyzeRepoLogPath() {
|
|
30971
|
+
const dir = path17.join(process.cwd(), ".bitfab", "logs");
|
|
30972
|
+
fs20.mkdirSync(dir, { recursive: true });
|
|
30973
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
30974
|
+
return path17.join(dir, `analyze-repo-${stamp}.jsonl`);
|
|
30975
|
+
}
|
|
30800
30976
|
function runClaudeAssistant(args, skipPermissions) {
|
|
30801
30977
|
const cmd = [ASSISTANT_COMMAND, ...args].join(" ");
|
|
30802
30978
|
p.log.info(`Launching ${cmd}...
|
|
@@ -30924,6 +31100,14 @@ function runCodexSetup(skipPermissions) {
|
|
|
30924
31100
|
...SHELL_OPTS2
|
|
30925
31101
|
});
|
|
30926
31102
|
}
|
|
31103
|
+
function runCodexAnalyzeRepo() {
|
|
31104
|
+
p2.log.warn(
|
|
31105
|
+
"Headless analyze-repo is currently supported for Claude Code only."
|
|
31106
|
+
);
|
|
31107
|
+
p2.log.info(
|
|
31108
|
+
`To run it in Codex, launch ${SETUP_COMMAND2} analyze-repo interactively.`
|
|
31109
|
+
);
|
|
31110
|
+
}
|
|
30927
31111
|
function runCodexAssistant(args, skipPermissions) {
|
|
30928
31112
|
const cmd = [ASSISTANT_COMMAND2, ...args].join(" ");
|
|
30929
31113
|
p2.log.info(`Launching ${cmd}...
|
|
@@ -31002,7 +31186,7 @@ function escapeRegex2(s) {
|
|
|
31002
31186
|
}
|
|
31003
31187
|
|
|
31004
31188
|
// src/cursor.ts
|
|
31005
|
-
import { spawn as
|
|
31189
|
+
import { spawn as spawn6, spawnSync as spawnSync3 } from "child_process";
|
|
31006
31190
|
import os17 from "os";
|
|
31007
31191
|
import * as p3 from "@clack/prompts";
|
|
31008
31192
|
var REPO3 = "Project-White-Rabbit/bitfab-cursor-plugin";
|
|
@@ -31026,7 +31210,7 @@ function runCursorInstall() {
|
|
|
31026
31210
|
"Finish setup in Cursor"
|
|
31027
31211
|
);
|
|
31028
31212
|
p3.log.info("Opening Cursor...");
|
|
31029
|
-
const child =
|
|
31213
|
+
const child = spawn6("cursor", ["."], {
|
|
31030
31214
|
stdio: "ignore",
|
|
31031
31215
|
detached: true,
|
|
31032
31216
|
windowsHide: true,
|
|
@@ -31042,6 +31226,12 @@ function runCursorSetup(skipPermissions) {
|
|
|
31042
31226
|
}
|
|
31043
31227
|
p3.log.info(`To complete setup, run ${SETUP_COMMAND3} in Cursor.`);
|
|
31044
31228
|
}
|
|
31229
|
+
function runCursorAnalyzeRepo() {
|
|
31230
|
+
p3.log.warn(
|
|
31231
|
+
"Headless analyze-repo is currently supported for Claude Code only."
|
|
31232
|
+
);
|
|
31233
|
+
p3.log.info(`To run it in Cursor, run ${SETUP_COMMAND3} analyze-repo manually.`);
|
|
31234
|
+
}
|
|
31045
31235
|
function runCursorAssistant(args, skipPermissions) {
|
|
31046
31236
|
if (skipPermissions) {
|
|
31047
31237
|
p3.log.warn("--skip-permissions is not supported for Cursor");
|
|
@@ -31140,6 +31330,11 @@ var SETUP_FN = {
|
|
|
31140
31330
|
codex: runCodexSetup,
|
|
31141
31331
|
cursor: runCursorSetup
|
|
31142
31332
|
};
|
|
31333
|
+
var ANALYZE_REPO_FN = {
|
|
31334
|
+
claude: runClaudeAnalyzeRepo,
|
|
31335
|
+
codex: runCodexAnalyzeRepo,
|
|
31336
|
+
cursor: runCursorAnalyzeRepo
|
|
31337
|
+
};
|
|
31143
31338
|
var ASSISTANT_FN = {
|
|
31144
31339
|
claude: runClaudeAssistant,
|
|
31145
31340
|
codex: runCodexAssistant,
|
|
@@ -31194,6 +31389,31 @@ async function resolveSkipPermissions(value) {
|
|
|
31194
31389
|
}
|
|
31195
31390
|
return answer;
|
|
31196
31391
|
}
|
|
31392
|
+
async function resolveCaptureOverride(flag) {
|
|
31393
|
+
if (flag !== void 0) {
|
|
31394
|
+
return flag;
|
|
31395
|
+
}
|
|
31396
|
+
const existing = getSessionLogConsent();
|
|
31397
|
+
if (existing !== null) {
|
|
31398
|
+
p4.log.step(
|
|
31399
|
+
existing ? "Session logs: enabled (saved preference)." : "Session logs: disabled (saved preference)."
|
|
31400
|
+
);
|
|
31401
|
+
return void 0;
|
|
31402
|
+
}
|
|
31403
|
+
if (!process.stdin.isTTY) {
|
|
31404
|
+
return false;
|
|
31405
|
+
}
|
|
31406
|
+
const answer = await p4.confirm({
|
|
31407
|
+
message: "Allow Bitfab to collect session logs? (used to diagnose issues and improve the product)",
|
|
31408
|
+
initialValue: true
|
|
31409
|
+
});
|
|
31410
|
+
if (p4.isCancel(answer)) {
|
|
31411
|
+
p4.cancel("Cancelled.");
|
|
31412
|
+
process.exit(0);
|
|
31413
|
+
}
|
|
31414
|
+
setSessionLogConsent(answer);
|
|
31415
|
+
return void 0;
|
|
31416
|
+
}
|
|
31197
31417
|
async function resolveEditor({ editor }) {
|
|
31198
31418
|
const detected = detectInstalledEditors();
|
|
31199
31419
|
if (detected.length === 0) {
|
|
@@ -31265,6 +31485,27 @@ async function runInit(opts) {
|
|
|
31265
31485
|
}
|
|
31266
31486
|
p4.outro("Done!");
|
|
31267
31487
|
}
|
|
31488
|
+
async function runAnalyzeRepo(opts) {
|
|
31489
|
+
p4.intro("bitfab");
|
|
31490
|
+
const chosen = await resolveEditor(opts);
|
|
31491
|
+
p4.log.step(`Setting up Bitfab in ${EDITOR_LABEL[chosen]}`);
|
|
31492
|
+
INSTALL_FN[chosen]();
|
|
31493
|
+
if (chosen !== "claude") {
|
|
31494
|
+
ANALYZE_REPO_FN[chosen]();
|
|
31495
|
+
process.exit(1);
|
|
31496
|
+
}
|
|
31497
|
+
const loggedInEmail = await checkAuth();
|
|
31498
|
+
if (!loggedInEmail) {
|
|
31499
|
+
p4.cancel(
|
|
31500
|
+
"Not authenticated. Run `bitfab login` (or set BITFAB_API_KEY) before `bitfab analyze-repo` - it is non-interactive and cannot open a browser."
|
|
31501
|
+
);
|
|
31502
|
+
process.exit(1);
|
|
31503
|
+
}
|
|
31504
|
+
p4.log.success(`Logged in as ${loggedInEmail}`);
|
|
31505
|
+
const captureOverride = await resolveCaptureOverride(opts.uploadLogs);
|
|
31506
|
+
await ANALYZE_REPO_FN[chosen](captureOverride, opts.limit);
|
|
31507
|
+
p4.outro("Done!");
|
|
31508
|
+
}
|
|
31268
31509
|
async function checkAuth() {
|
|
31269
31510
|
const { apiKey, serviceUrl } = getConfig();
|
|
31270
31511
|
if (!apiKey) {
|
|
@@ -31308,18 +31549,17 @@ function startUpdateCheck() {
|
|
|
31308
31549
|
const controller = new AbortController();
|
|
31309
31550
|
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
31310
31551
|
const current = getVersion();
|
|
31552
|
+
let notice = null;
|
|
31311
31553
|
const done = fetch(NPM_REGISTRY_URL, { signal: controller.signal }).then(
|
|
31312
31554
|
(res) => res.ok ? res.json() : null
|
|
31313
31555
|
).then((data) => {
|
|
31314
31556
|
const latest = data?.version;
|
|
31315
31557
|
if (latest && isNewer(latest, current)) {
|
|
31316
|
-
|
|
31317
|
-
`
|
|
31558
|
+
notice = `
|
|
31318
31559
|
Update available: ${current} -> ${latest}
|
|
31319
31560
|
Run \`npx bitfab-cli@latest\` to get the newest version.
|
|
31320
31561
|
|
|
31321
|
-
|
|
31322
|
-
);
|
|
31562
|
+
`;
|
|
31323
31563
|
}
|
|
31324
31564
|
}).catch(() => {
|
|
31325
31565
|
}).finally(() => clearTimeout(timer));
|
|
@@ -31327,6 +31567,9 @@ function startUpdateCheck() {
|
|
|
31327
31567
|
controller.abort();
|
|
31328
31568
|
done.catch(() => {
|
|
31329
31569
|
});
|
|
31570
|
+
if (notice) {
|
|
31571
|
+
process.stderr.write(notice);
|
|
31572
|
+
}
|
|
31330
31573
|
};
|
|
31331
31574
|
}
|
|
31332
31575
|
|
|
@@ -31339,6 +31582,7 @@ Commands:
|
|
|
31339
31582
|
login Authenticate with Bitfab (opens browser)
|
|
31340
31583
|
logout Remove stored credentials
|
|
31341
31584
|
setup [--editor <name>] Launch /bitfab:setup in the editor
|
|
31585
|
+
analyze-repo [--editor <name>] Headless scan: draft + upload trace plans (no prompts, no code edits)
|
|
31342
31586
|
assistant [--editor <name>] [args] Launch /bitfab:assistant in the editor
|
|
31343
31587
|
update [--editor <name>] [mode] Update plugin, then launch SDK update (mode: all|plugin|sdk)
|
|
31344
31588
|
help Show this help
|
|
@@ -31347,14 +31591,26 @@ Options:
|
|
|
31347
31591
|
--editor, -e <name> Target editor: claude, codex, cursor
|
|
31348
31592
|
--skip-permissions Skip permission prompts (runs the agent autonomously)
|
|
31349
31593
|
--no-skip-permissions Keep permission prompts (default, skips the interactive question)
|
|
31594
|
+
--upload-logs analyze-repo: upload the run's session logs to Bitfab (skips the prompt)
|
|
31595
|
+
--no-upload-logs analyze-repo: keep session logs local (skips the prompt)
|
|
31596
|
+
--limit <n> analyze-repo: cap how many draft trace plans to upload (default 5)
|
|
31350
31597
|
|
|
31351
31598
|
Examples:
|
|
31352
31599
|
bitfab init Full setup (detect editor, install, login, setup)
|
|
31353
31600
|
bitfab init --editor claude Full setup for Claude Code
|
|
31601
|
+
bitfab analyze-repo Scan the repo and upload draft trace plans (headless)
|
|
31602
|
+
bitfab analyze-repo --limit 3 Scan the repo and upload at most 3 draft trace plans
|
|
31354
31603
|
bitfab assistant investigate Investigate traces
|
|
31355
31604
|
bitfab setup --skip-permissions Setup without permission prompts
|
|
31356
31605
|
bitfab assistant --skip-permissions Run assistant autonomously
|
|
31357
31606
|
`;
|
|
31607
|
+
function parseLimit(raw) {
|
|
31608
|
+
const n = Number(raw);
|
|
31609
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
31610
|
+
throw new Error(`--limit must be a positive integer, got "${raw}"`);
|
|
31611
|
+
}
|
|
31612
|
+
return n;
|
|
31613
|
+
}
|
|
31358
31614
|
function wantsHelp(argv) {
|
|
31359
31615
|
const command = argv[0];
|
|
31360
31616
|
return !command || command === "help" || argv.includes("-h") || argv.includes("--help");
|
|
@@ -31363,6 +31619,8 @@ function parseArgs2(argv) {
|
|
|
31363
31619
|
const [command, ...tail] = argv;
|
|
31364
31620
|
let editor;
|
|
31365
31621
|
let skipPermissions;
|
|
31622
|
+
let uploadLogs;
|
|
31623
|
+
let limit;
|
|
31366
31624
|
const rest = [];
|
|
31367
31625
|
for (let i = 0; i < tail.length; i++) {
|
|
31368
31626
|
const arg = tail[i];
|
|
@@ -31379,16 +31637,27 @@ function parseArgs2(argv) {
|
|
|
31379
31637
|
skipPermissions = true;
|
|
31380
31638
|
} else if (arg === "--no-skip-permissions") {
|
|
31381
31639
|
skipPermissions = false;
|
|
31640
|
+
} else if (arg === "--upload-logs") {
|
|
31641
|
+
uploadLogs = true;
|
|
31642
|
+
} else if (arg === "--no-upload-logs") {
|
|
31643
|
+
uploadLogs = false;
|
|
31644
|
+
} else if (arg === "--limit") {
|
|
31645
|
+
if (i + 1 < tail.length) {
|
|
31646
|
+
limit = parseLimit(tail[i + 1]);
|
|
31647
|
+
i++;
|
|
31648
|
+
} else {
|
|
31649
|
+
throw new Error("--limit flag requires a value");
|
|
31650
|
+
}
|
|
31651
|
+
} else if (arg?.startsWith("--limit=")) {
|
|
31652
|
+
limit = parseLimit(arg.slice("--limit=".length));
|
|
31382
31653
|
} else if (arg !== void 0) {
|
|
31383
31654
|
rest.push(arg);
|
|
31384
31655
|
}
|
|
31385
31656
|
}
|
|
31386
|
-
return { command, editor, skipPermissions, rest };
|
|
31657
|
+
return { command, editor, skipPermissions, uploadLogs, limit, rest };
|
|
31387
31658
|
}
|
|
31388
31659
|
async function main() {
|
|
31389
|
-
const { command, editor, skipPermissions, rest } = parseArgs2(
|
|
31390
|
-
process.argv.slice(2)
|
|
31391
|
-
);
|
|
31660
|
+
const { command, editor, skipPermissions, uploadLogs, limit, rest } = parseArgs2(process.argv.slice(2));
|
|
31392
31661
|
const abortUpdateCheck = startUpdateCheck();
|
|
31393
31662
|
if (wantsHelp(process.argv.slice(2))) {
|
|
31394
31663
|
process.stdout.write(HELP_TEXT);
|
|
@@ -31420,6 +31689,11 @@ async function main() {
|
|
|
31420
31689
|
abortUpdateCheck();
|
|
31421
31690
|
return;
|
|
31422
31691
|
}
|
|
31692
|
+
if (command === "analyze-repo") {
|
|
31693
|
+
await runAnalyzeRepo({ editor, skipPermissions, uploadLogs, limit });
|
|
31694
|
+
abortUpdateCheck();
|
|
31695
|
+
return;
|
|
31696
|
+
}
|
|
31423
31697
|
if (command === "assistant") {
|
|
31424
31698
|
await runAssistant({ editor, skipPermissions }, rest);
|
|
31425
31699
|
abortUpdateCheck();
|