@staff0rd/assist 0.220.1 → 0.220.2
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 +183 -81
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.220.
|
|
9
|
+
version: "0.220.2",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -4070,10 +4070,10 @@ function printTaskStatuses(tasks) {
|
|
|
4070
4070
|
}
|
|
4071
4071
|
|
|
4072
4072
|
// src/commands/verify/run/createTimerCallback/index.ts
|
|
4073
|
-
function logFailedScripts(
|
|
4073
|
+
function logFailedScripts(failed2) {
|
|
4074
4074
|
console.error(`
|
|
4075
|
-
${
|
|
4076
|
-
for (const f of
|
|
4075
|
+
${failed2.length} script(s) failed:`);
|
|
4076
|
+
for (const f of failed2) {
|
|
4077
4077
|
console.error(` - ${f.script} (exit code ${f.code})`);
|
|
4078
4078
|
}
|
|
4079
4079
|
}
|
|
@@ -4150,9 +4150,9 @@ function runEntry(entry, onComplete) {
|
|
|
4150
4150
|
});
|
|
4151
4151
|
});
|
|
4152
4152
|
}
|
|
4153
|
-
function exitIfFailed(
|
|
4154
|
-
if (
|
|
4155
|
-
logFailedScripts(
|
|
4153
|
+
function exitIfFailed(failed2) {
|
|
4154
|
+
if (failed2.length === 0) return;
|
|
4155
|
+
logFailedScripts(failed2);
|
|
4156
4156
|
process.exit(1);
|
|
4157
4157
|
}
|
|
4158
4158
|
function runAllEntries(entries, timer) {
|
|
@@ -8401,52 +8401,52 @@ function renderInline(node) {
|
|
|
8401
8401
|
if (node.marks?.some((m) => m.type === "code")) return `\`${text}\``;
|
|
8402
8402
|
return text;
|
|
8403
8403
|
}
|
|
8404
|
-
function renderChildren(node,
|
|
8405
|
-
return renderNodes(node.content ?? [],
|
|
8404
|
+
function renderChildren(node, indent2) {
|
|
8405
|
+
return renderNodes(node.content ?? [], indent2);
|
|
8406
8406
|
}
|
|
8407
|
-
function renderOrderedList(node,
|
|
8407
|
+
function renderOrderedList(node, indent2) {
|
|
8408
8408
|
let counter = 0;
|
|
8409
8409
|
return (node.content ?? []).map((item) => {
|
|
8410
8410
|
counter++;
|
|
8411
|
-
return renderListItem(item,
|
|
8411
|
+
return renderListItem(item, indent2, `${counter}.`);
|
|
8412
8412
|
}).join("\n");
|
|
8413
8413
|
}
|
|
8414
|
-
function renderBulletList(node,
|
|
8415
|
-
return (node.content ?? []).map((item) => renderListItem(item,
|
|
8414
|
+
function renderBulletList(node, indent2) {
|
|
8415
|
+
return (node.content ?? []).map((item) => renderListItem(item, indent2, "-")).join("\n");
|
|
8416
8416
|
}
|
|
8417
|
-
function renderHeading(node,
|
|
8417
|
+
function renderHeading(node, indent2) {
|
|
8418
8418
|
const level = node.attrs?.level ?? 1;
|
|
8419
|
-
return `${"#".repeat(level)} ${renderChildren(node,
|
|
8419
|
+
return `${"#".repeat(level)} ${renderChildren(node, indent2)}`;
|
|
8420
8420
|
}
|
|
8421
8421
|
var renderers = {
|
|
8422
8422
|
text: (node) => renderInline(node),
|
|
8423
8423
|
paragraph: renderChildren,
|
|
8424
8424
|
orderedList: renderOrderedList,
|
|
8425
8425
|
bulletList: renderBulletList,
|
|
8426
|
-
listItem: (node,
|
|
8426
|
+
listItem: (node, indent2) => renderListItem(node, indent2, "-"),
|
|
8427
8427
|
heading: renderHeading,
|
|
8428
8428
|
doc: renderChildren
|
|
8429
8429
|
};
|
|
8430
|
-
function renderNode(node,
|
|
8430
|
+
function renderNode(node, indent2) {
|
|
8431
8431
|
const renderer = renderers[node.type];
|
|
8432
|
-
if (renderer) return renderer(node,
|
|
8433
|
-
return node.content ? renderChildren(node,
|
|
8432
|
+
if (renderer) return renderer(node, indent2);
|
|
8433
|
+
return node.content ? renderChildren(node, indent2) : "";
|
|
8434
8434
|
}
|
|
8435
|
-
function renderNodes(nodes,
|
|
8436
|
-
return nodes.map((node) => renderNode(node,
|
|
8435
|
+
function renderNodes(nodes, indent2) {
|
|
8436
|
+
return nodes.map((node) => renderNode(node, indent2)).join("");
|
|
8437
8437
|
}
|
|
8438
8438
|
function isListNode(node) {
|
|
8439
8439
|
return node.type === "orderedList" || node.type === "bulletList";
|
|
8440
8440
|
}
|
|
8441
|
-
function renderListChild(child,
|
|
8442
|
-
if (isListNode(child)) return renderNodes([child],
|
|
8443
|
-
if (child.type !== "paragraph") return renderNode(child,
|
|
8444
|
-
const text = renderChildren(child,
|
|
8441
|
+
function renderListChild(child, indent2, pad, marker, isFirst) {
|
|
8442
|
+
if (isListNode(child)) return renderNodes([child], indent2 + 1);
|
|
8443
|
+
if (child.type !== "paragraph") return renderNode(child, indent2);
|
|
8444
|
+
const text = renderChildren(child, indent2);
|
|
8445
8445
|
return isFirst ? `${pad}${marker} ${text}` : `${pad} ${text}`;
|
|
8446
8446
|
}
|
|
8447
|
-
function renderListItem(node,
|
|
8448
|
-
const pad = " ".repeat(
|
|
8449
|
-
return (node.content ?? []).map((child, i) => renderListChild(child,
|
|
8447
|
+
function renderListItem(node, indent2, marker) {
|
|
8448
|
+
const pad = " ".repeat(indent2);
|
|
8449
|
+
return (node.content ?? []).map((child, i) => renderListChild(child, indent2, pad, marker, i === 0)).join("\n");
|
|
8450
8450
|
}
|
|
8451
8451
|
function adfToText(doc) {
|
|
8452
8452
|
return renderNodes([doc], 0);
|
|
@@ -10283,13 +10283,13 @@ function runScript(script, cwd) {
|
|
|
10283
10283
|
});
|
|
10284
10284
|
});
|
|
10285
10285
|
}
|
|
10286
|
-
function logFailures(
|
|
10287
|
-
for (const f of
|
|
10286
|
+
function logFailures(failed2) {
|
|
10287
|
+
for (const f of failed2) {
|
|
10288
10288
|
console.error(f.output);
|
|
10289
10289
|
}
|
|
10290
10290
|
console.error(`
|
|
10291
|
-
${
|
|
10292
|
-
for (const f of
|
|
10291
|
+
${failed2.length} verify script(s) failed:`);
|
|
10292
|
+
for (const f of failed2) {
|
|
10293
10293
|
console.error(` - ${f.script} (exit code ${f.code})`);
|
|
10294
10294
|
}
|
|
10295
10295
|
}
|
|
@@ -10300,9 +10300,9 @@ async function runVerifyQuietly() {
|
|
|
10300
10300
|
const results = await Promise.all(
|
|
10301
10301
|
result.verifyScripts.map((script) => runScript(script, packageDir))
|
|
10302
10302
|
);
|
|
10303
|
-
const
|
|
10304
|
-
if (
|
|
10305
|
-
logFailures(
|
|
10303
|
+
const failed2 = results.filter((r) => r.code !== 0);
|
|
10304
|
+
if (failed2.length > 0) {
|
|
10305
|
+
logFailures(failed2);
|
|
10306
10306
|
return false;
|
|
10307
10307
|
}
|
|
10308
10308
|
return true;
|
|
@@ -12017,21 +12017,21 @@ function buildCommentBody(finding) {
|
|
|
12017
12017
|
}
|
|
12018
12018
|
function postFindings(findings) {
|
|
12019
12019
|
let posted = 0;
|
|
12020
|
-
let
|
|
12020
|
+
let failed2 = 0;
|
|
12021
12021
|
for (const finding of findings) {
|
|
12022
12022
|
const body = buildCommentBody(finding);
|
|
12023
12023
|
try {
|
|
12024
12024
|
comment2(finding.file, finding.line, body, finding.startLine);
|
|
12025
12025
|
posted++;
|
|
12026
12026
|
} catch (error) {
|
|
12027
|
-
|
|
12027
|
+
failed2++;
|
|
12028
12028
|
const message = error instanceof Error ? error.message : String(error);
|
|
12029
12029
|
console.error(
|
|
12030
12030
|
`Failed to post comment on ${finding.file}:${finding.line}: ${message}`
|
|
12031
12031
|
);
|
|
12032
12032
|
}
|
|
12033
12033
|
}
|
|
12034
|
-
return { posted, failed };
|
|
12034
|
+
return { posted, failed: failed2 };
|
|
12035
12035
|
}
|
|
12036
12036
|
|
|
12037
12037
|
// src/commands/review/submitPendingReview.ts
|
|
@@ -12386,6 +12386,61 @@ function skippedCodexResult(outputPath) {
|
|
|
12386
12386
|
return { name: "codex", outputPath, exitCode: 0, stderr: "" };
|
|
12387
12387
|
}
|
|
12388
12388
|
|
|
12389
|
+
// src/commands/review/formatReviewerFailure.ts
|
|
12390
|
+
var FAST_FAIL_MS = 1e3;
|
|
12391
|
+
var STDOUT_TAIL_LINES = 20;
|
|
12392
|
+
function indent(text) {
|
|
12393
|
+
return text.split(/\r?\n/).map((line) => ` ${line}`);
|
|
12394
|
+
}
|
|
12395
|
+
function tailLines(text, maxLines) {
|
|
12396
|
+
const lines = text.split(/\r?\n/);
|
|
12397
|
+
return lines.length <= maxLines ? text : lines.slice(-maxLines).join("\n");
|
|
12398
|
+
}
|
|
12399
|
+
function isFastFail(input) {
|
|
12400
|
+
return input.exitCode !== 0 && input.elapsedMs !== void 0 && input.elapsedMs < FAST_FAIL_MS;
|
|
12401
|
+
}
|
|
12402
|
+
function fastFailHint(command) {
|
|
12403
|
+
return [
|
|
12404
|
+
`${command} exited almost immediately \u2014 it likely failed to start.`,
|
|
12405
|
+
`Common causes: not installed on PATH, not authenticated, or misconfigured.`,
|
|
12406
|
+
`Try \`${command} --version\` to confirm install, then \`${command} login\` if authentication may be missing.`
|
|
12407
|
+
];
|
|
12408
|
+
}
|
|
12409
|
+
function outputDetail(input) {
|
|
12410
|
+
const stderr = input.stderr.trim();
|
|
12411
|
+
if (stderr) return ["stderr:", ...indent(stderr)];
|
|
12412
|
+
const stdout = (input.stdout ?? "").trim();
|
|
12413
|
+
if (stdout) {
|
|
12414
|
+
return [
|
|
12415
|
+
`stdout (no stderr was captured \u2014 showing last ${STDOUT_TAIL_LINES} lines):`,
|
|
12416
|
+
...indent(tailLines(stdout, STDOUT_TAIL_LINES))
|
|
12417
|
+
];
|
|
12418
|
+
}
|
|
12419
|
+
return [
|
|
12420
|
+
"No stderr or stdout was captured. Check the review folder for partial output, or rerun with --verbose for full streaming output."
|
|
12421
|
+
];
|
|
12422
|
+
}
|
|
12423
|
+
function formatReviewerFailure(input) {
|
|
12424
|
+
const command = input.command ?? input.name;
|
|
12425
|
+
const seconds = Math.round((input.elapsedMs ?? 0) / 1e3);
|
|
12426
|
+
const headerLine = `${command} CLI exited with code ${input.exitCode} after ${seconds}s`;
|
|
12427
|
+
const detailLines = [];
|
|
12428
|
+
if (isFastFail(input)) detailLines.push(...fastFailHint(command));
|
|
12429
|
+
detailLines.push(...outputDetail(input));
|
|
12430
|
+
return { headerLine, detailLines };
|
|
12431
|
+
}
|
|
12432
|
+
function printReviewerFailure(input) {
|
|
12433
|
+
if (input.exitCode === 0) return;
|
|
12434
|
+
const diagnostic = formatReviewerFailure(input);
|
|
12435
|
+
console.error(`[${input.name}] ${diagnostic.headerLine}`);
|
|
12436
|
+
for (const line of diagnostic.detailLines) console.error(line);
|
|
12437
|
+
}
|
|
12438
|
+
|
|
12439
|
+
// src/commands/review/printReviewerFailures.ts
|
|
12440
|
+
function printReviewerFailures(results) {
|
|
12441
|
+
for (const r of results) printReviewerFailure(r);
|
|
12442
|
+
}
|
|
12443
|
+
|
|
12389
12444
|
// src/commands/review/runAndSynthesise.ts
|
|
12390
12445
|
import { existsSync as existsSync35, unlinkSync as unlinkSync12 } from "fs";
|
|
12391
12446
|
|
|
@@ -12450,26 +12505,26 @@ The review request is at: ${requestPath}
|
|
|
12450
12505
|
`;
|
|
12451
12506
|
}
|
|
12452
12507
|
|
|
12453
|
-
// src/commands/review/printReviewerFailures.ts
|
|
12454
|
-
function printReviewerFailures(results) {
|
|
12455
|
-
for (const r of results) {
|
|
12456
|
-
if (r.exitCode === 0) continue;
|
|
12457
|
-
console.error(`[${r.name}] exited with code ${r.exitCode}`);
|
|
12458
|
-
if (r.stderr) console.error(r.stderr.trim());
|
|
12459
|
-
}
|
|
12460
|
-
}
|
|
12461
|
-
|
|
12462
12508
|
// src/commands/review/runClaudeReviewer.ts
|
|
12463
12509
|
import { writeFileSync as writeFileSync27 } from "fs";
|
|
12464
12510
|
|
|
12465
12511
|
// src/commands/review/finaliseReviewerSpinner.ts
|
|
12466
|
-
|
|
12512
|
+
var SUMMARY_MAX_LEN = 80;
|
|
12513
|
+
function summariseStderr(stderr) {
|
|
12514
|
+
const firstLine = stderr.split(/\r?\n/).find((l) => l.trim().length > 0);
|
|
12515
|
+
if (!firstLine) return "";
|
|
12516
|
+
const trimmed = firstLine.trim();
|
|
12517
|
+
return trimmed.length > SUMMARY_MAX_LEN ? `${trimmed.slice(0, SUMMARY_MAX_LEN - 1)}\u2026` : trimmed;
|
|
12518
|
+
}
|
|
12519
|
+
function finaliseReviewerSpinner(spinner, name, exitCode, elapsedMs, stderr = "") {
|
|
12467
12520
|
const elapsed = Math.round(elapsedMs / 1e3);
|
|
12468
12521
|
if (exitCode === 0) {
|
|
12469
12522
|
spinner.succeed(`${name} \u2014 done in ${elapsed}s`);
|
|
12470
12523
|
return;
|
|
12471
12524
|
}
|
|
12472
|
-
|
|
12525
|
+
const summary = summariseStderr(stderr);
|
|
12526
|
+
const suffix = summary ? `: ${summary}` : "";
|
|
12527
|
+
spinner.fail(`${name} \u2014 failed in ${elapsed}s (exit ${exitCode})${suffix}`);
|
|
12473
12528
|
}
|
|
12474
12529
|
|
|
12475
12530
|
// src/commands/review/finaliseReviewerRun.ts
|
|
@@ -12479,13 +12534,17 @@ function finaliseReviewerRun(spec, spinner, result) {
|
|
|
12479
12534
|
spinner,
|
|
12480
12535
|
spec.name,
|
|
12481
12536
|
result.exitCode,
|
|
12482
|
-
result.elapsedMs
|
|
12537
|
+
result.elapsedMs,
|
|
12538
|
+
result.stderr
|
|
12483
12539
|
);
|
|
12484
12540
|
return {
|
|
12485
12541
|
name: spec.name,
|
|
12542
|
+
command: spec.command,
|
|
12486
12543
|
outputPath: spec.outputPath,
|
|
12487
12544
|
exitCode: result.exitCode,
|
|
12488
|
-
stderr: result.stderr
|
|
12545
|
+
stderr: result.stderr,
|
|
12546
|
+
stdout: result.stdout,
|
|
12547
|
+
elapsedMs: result.elapsedMs
|
|
12489
12548
|
};
|
|
12490
12549
|
}
|
|
12491
12550
|
|
|
@@ -12610,14 +12669,35 @@ function attachStderrCollector(child) {
|
|
|
12610
12669
|
return state;
|
|
12611
12670
|
}
|
|
12612
12671
|
|
|
12672
|
+
// src/commands/review/attachStdoutTail.ts
|
|
12673
|
+
function attachStdoutTail(child, maxBytes = 8192) {
|
|
12674
|
+
const state = { value: "" };
|
|
12675
|
+
child.stdout?.on("data", (chunk) => {
|
|
12676
|
+
state.value += chunk.toString("utf-8");
|
|
12677
|
+
if (state.value.length > maxBytes) {
|
|
12678
|
+
state.value = state.value.slice(state.value.length - maxBytes);
|
|
12679
|
+
}
|
|
12680
|
+
});
|
|
12681
|
+
return state;
|
|
12682
|
+
}
|
|
12683
|
+
|
|
12613
12684
|
// src/commands/review/logChildClose.ts
|
|
12614
|
-
function logChildClose(
|
|
12615
|
-
|
|
12616
|
-
|
|
12685
|
+
function logChildClose(args) {
|
|
12686
|
+
const elapsedSeconds = Math.round(args.elapsedMs / 1e3);
|
|
12687
|
+
if (args.exitCode === 0) {
|
|
12688
|
+
console.log(`[${args.name}] done in ${elapsedSeconds}s`);
|
|
12617
12689
|
return;
|
|
12618
12690
|
}
|
|
12619
|
-
|
|
12620
|
-
|
|
12691
|
+
const diagnostic = formatReviewerFailure({
|
|
12692
|
+
name: args.name,
|
|
12693
|
+
command: args.command,
|
|
12694
|
+
exitCode: args.exitCode,
|
|
12695
|
+
stderr: args.stderr,
|
|
12696
|
+
stdout: args.stdout,
|
|
12697
|
+
elapsedMs: args.elapsedMs
|
|
12698
|
+
});
|
|
12699
|
+
console.error(`[${args.name}] ${diagnostic.headerLine}`);
|
|
12700
|
+
for (const line of diagnostic.detailLines) console.error(line);
|
|
12621
12701
|
}
|
|
12622
12702
|
|
|
12623
12703
|
// src/commands/review/handleChildClose.ts
|
|
@@ -12625,8 +12705,14 @@ function handleChildClose(args) {
|
|
|
12625
12705
|
const elapsedMs = Date.now() - args.startedAt;
|
|
12626
12706
|
const exitCode = args.code ?? 0;
|
|
12627
12707
|
if (!args.quiet) {
|
|
12628
|
-
|
|
12629
|
-
|
|
12708
|
+
logChildClose({
|
|
12709
|
+
name: args.name,
|
|
12710
|
+
command: args.command,
|
|
12711
|
+
exitCode,
|
|
12712
|
+
elapsedMs,
|
|
12713
|
+
stderr: args.stderr,
|
|
12714
|
+
stdout: args.stdout
|
|
12715
|
+
});
|
|
12630
12716
|
}
|
|
12631
12717
|
return { exitCode, elapsedMs };
|
|
12632
12718
|
}
|
|
@@ -12644,6 +12730,7 @@ ${message}` : message;
|
|
|
12644
12730
|
return {
|
|
12645
12731
|
exitCode: 127,
|
|
12646
12732
|
stderr,
|
|
12733
|
+
stdout: ctx.stdout,
|
|
12647
12734
|
elapsedMs: Date.now() - ctx.startedAt
|
|
12648
12735
|
};
|
|
12649
12736
|
}
|
|
@@ -12656,6 +12743,7 @@ function onErrorResult(ctx, err) {
|
|
|
12656
12743
|
command: ctx.command,
|
|
12657
12744
|
name: ctx.name,
|
|
12658
12745
|
stderr: ctx.stderr.value,
|
|
12746
|
+
stdout: ctx.stdout.value,
|
|
12659
12747
|
startedAt: ctx.startedAt,
|
|
12660
12748
|
quiet: ctx.quiet
|
|
12661
12749
|
},
|
|
@@ -12668,10 +12756,12 @@ function onCloseResult(ctx, code) {
|
|
|
12668
12756
|
code,
|
|
12669
12757
|
startedAt: ctx.startedAt,
|
|
12670
12758
|
name: ctx.name,
|
|
12759
|
+
command: ctx.command,
|
|
12671
12760
|
stderr: ctx.stderr.value,
|
|
12761
|
+
stdout: ctx.stdout.value,
|
|
12672
12762
|
quiet: ctx.quiet
|
|
12673
12763
|
});
|
|
12674
|
-
return { ...closed, stderr: ctx.stderr.value };
|
|
12764
|
+
return { ...closed, stderr: ctx.stderr.value, stdout: ctx.stdout.value };
|
|
12675
12765
|
}
|
|
12676
12766
|
function waitForChildExit(ctx) {
|
|
12677
12767
|
return new Promise((resolve15) => {
|
|
@@ -12698,21 +12788,24 @@ function writeStdinSafely(child, payload) {
|
|
|
12698
12788
|
}
|
|
12699
12789
|
function startChild(spec) {
|
|
12700
12790
|
const child = spawn6(spec.command, spec.args, {
|
|
12701
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
12791
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
12792
|
+
shell: process.platform === "win32"
|
|
12702
12793
|
});
|
|
12703
12794
|
const flushPending = attachLineParser(child, spec.onLine);
|
|
12704
12795
|
const stderr = attachStderrCollector(child);
|
|
12796
|
+
const stdout = attachStdoutTail(child);
|
|
12705
12797
|
writeStdinSafely(child, spec.stdin);
|
|
12706
|
-
return { child, flushPending, stderr };
|
|
12798
|
+
return { child, flushPending, stderr, stdout };
|
|
12707
12799
|
}
|
|
12708
12800
|
function runStreamingChild(spec) {
|
|
12709
12801
|
const startedAt = Date.now();
|
|
12710
12802
|
if (!spec.quiet) console.log(`[${spec.name}] starting`);
|
|
12711
|
-
const { child, flushPending, stderr } = startChild(spec);
|
|
12803
|
+
const { child, flushPending, stderr, stdout } = startChild(spec);
|
|
12712
12804
|
return waitForChildExit({
|
|
12713
12805
|
child,
|
|
12714
12806
|
flushPending,
|
|
12715
12807
|
stderr,
|
|
12808
|
+
stdout,
|
|
12716
12809
|
name: spec.name,
|
|
12717
12810
|
command: spec.command,
|
|
12718
12811
|
startedAt,
|
|
@@ -12724,9 +12817,10 @@ function runStreamingChild(spec) {
|
|
|
12724
12817
|
async function runClaudeReviewer(spec) {
|
|
12725
12818
|
let finalText = "";
|
|
12726
12819
|
const { spinner } = spec;
|
|
12820
|
+
const command = "claude";
|
|
12727
12821
|
const result = await runStreamingChild({
|
|
12728
12822
|
name: spec.name,
|
|
12729
|
-
command
|
|
12823
|
+
command,
|
|
12730
12824
|
args: [
|
|
12731
12825
|
"-p",
|
|
12732
12826
|
"--add-dir",
|
|
@@ -12749,7 +12843,7 @@ async function runClaudeReviewer(spec) {
|
|
|
12749
12843
|
});
|
|
12750
12844
|
if (result.exitCode === 0 && finalText)
|
|
12751
12845
|
writeFileSync27(spec.outputPath, finalText);
|
|
12752
|
-
return finaliseReviewerRun(spec, spinner, result);
|
|
12846
|
+
return finaliseReviewerRun({ ...spec, command }, spinner, result);
|
|
12753
12847
|
}
|
|
12754
12848
|
|
|
12755
12849
|
// src/commands/review/resolveClaude.ts
|
|
@@ -12807,9 +12901,10 @@ function codexArgs(reviewDir, outputPath) {
|
|
|
12807
12901
|
}
|
|
12808
12902
|
async function runCodexReviewer(spec) {
|
|
12809
12903
|
const { spinner } = spec;
|
|
12904
|
+
const command = "codex";
|
|
12810
12905
|
const result = await runStreamingChild({
|
|
12811
12906
|
name: spec.name,
|
|
12812
|
-
command
|
|
12907
|
+
command,
|
|
12813
12908
|
args: codexArgs(spec.reviewDir, spec.outputPath),
|
|
12814
12909
|
stdin: spec.stdin,
|
|
12815
12910
|
quiet: Boolean(spinner),
|
|
@@ -12822,7 +12917,7 @@ async function runCodexReviewer(spec) {
|
|
|
12822
12917
|
if (result.exitCode !== 0 && existsSync34(spec.outputPath)) {
|
|
12823
12918
|
unlinkSync11(spec.outputPath);
|
|
12824
12919
|
}
|
|
12825
|
-
return finaliseReviewerRun(spec, spinner, result);
|
|
12920
|
+
return finaliseReviewerRun({ ...spec, command }, spinner, result);
|
|
12826
12921
|
}
|
|
12827
12922
|
|
|
12828
12923
|
// src/commands/review/resolveCodex.ts
|
|
@@ -12858,7 +12953,6 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
|
|
|
12858
12953
|
multi: options2.multi
|
|
12859
12954
|
});
|
|
12860
12955
|
const results = await Promise.all([claudePromise, codexPromise]);
|
|
12861
|
-
if (options2.multi) printReviewerFailures(results);
|
|
12862
12956
|
const anyFresh = options2.cachedClaude === null || options2.codexPlan.kind !== "cached";
|
|
12863
12957
|
return { results, anyFresh };
|
|
12864
12958
|
}
|
|
@@ -12946,12 +13040,14 @@ async function synthesise(paths, options2) {
|
|
|
12946
13040
|
outputPath: paths.synthesisPath,
|
|
12947
13041
|
spinner
|
|
12948
13042
|
});
|
|
12949
|
-
if (multi) printReviewerFailures([result]);
|
|
12950
13043
|
if (result.exitCode === 0) printSummary(paths.synthesisPath);
|
|
12951
13044
|
return result;
|
|
12952
13045
|
}
|
|
12953
13046
|
|
|
12954
13047
|
// src/commands/review/runAndSynthesise.ts
|
|
13048
|
+
function failed(results) {
|
|
13049
|
+
return results.filter((r) => r.exitCode !== 0);
|
|
13050
|
+
}
|
|
12955
13051
|
async function runAndSynthesise(args) {
|
|
12956
13052
|
const { paths, multi } = args;
|
|
12957
13053
|
const { results, anyFresh } = await runReviewers(
|
|
@@ -12961,17 +13057,17 @@ async function runAndSynthesise(args) {
|
|
|
12961
13057
|
buildReviewerStdin(paths.requestPath),
|
|
12962
13058
|
{ multi, codexPlan: args.codexPlan, cachedClaude: args.cachedClaude }
|
|
12963
13059
|
);
|
|
13060
|
+
const failures = failed(results);
|
|
12964
13061
|
if (results.every((r) => r.exitCode !== 0)) {
|
|
12965
|
-
console.error(
|
|
12966
|
-
|
|
12967
|
-
);
|
|
12968
|
-
return false;
|
|
13062
|
+
console.error("Both reviewers failed; skipping synthesis.");
|
|
13063
|
+
return { ok: false, failures };
|
|
12969
13064
|
}
|
|
12970
13065
|
if (anyFresh && existsSync35(paths.synthesisPath)) {
|
|
12971
13066
|
unlinkSync12(paths.synthesisPath);
|
|
12972
13067
|
}
|
|
12973
13068
|
const synthesisResult = await synthesise(paths, { multi });
|
|
12974
|
-
|
|
13069
|
+
if (synthesisResult.exitCode !== 0) failures.push(synthesisResult);
|
|
13070
|
+
return { ok: synthesisResult.exitCode === 0, failures };
|
|
12975
13071
|
}
|
|
12976
13072
|
|
|
12977
13073
|
// src/commands/review/useSpinnerUi.ts
|
|
@@ -12994,19 +13090,25 @@ function finishUi(ui, ok) {
|
|
|
12994
13090
|
if (ok) ui.elapsed.succeed(label2);
|
|
12995
13091
|
else ui.elapsed.fail(label2);
|
|
12996
13092
|
}
|
|
13093
|
+
function reportFailures(failures, usingSpinner) {
|
|
13094
|
+
if (failures.length === 0) return;
|
|
13095
|
+
if (!usingSpinner) return;
|
|
13096
|
+
printReviewerFailures(failures);
|
|
13097
|
+
}
|
|
12997
13098
|
async function runReviewPipeline(paths, options2) {
|
|
12998
13099
|
const cachedClaude = cachedReviewerResult("claude", paths.claudePath);
|
|
12999
13100
|
const codexPlan = await planCodexReviewer(paths.codexPath);
|
|
13000
13101
|
const ui = createUi(useSpinnerUi(options2.verbose));
|
|
13001
13102
|
try {
|
|
13002
|
-
const
|
|
13103
|
+
const outcome = await runAndSynthesise({
|
|
13003
13104
|
paths,
|
|
13004
13105
|
cachedClaude,
|
|
13005
13106
|
codexPlan,
|
|
13006
13107
|
multi: ui.multi
|
|
13007
13108
|
});
|
|
13008
|
-
finishUi(ui, ok);
|
|
13009
|
-
|
|
13109
|
+
finishUi(ui, outcome.ok);
|
|
13110
|
+
reportFailures(outcome.failures, ui.multi !== void 0);
|
|
13111
|
+
return outcome.ok;
|
|
13010
13112
|
} catch (err) {
|
|
13011
13113
|
ui.multi?.failRemaining();
|
|
13012
13114
|
throw err;
|
|
@@ -15646,9 +15748,9 @@ async function summarise3(options2) {
|
|
|
15646
15748
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
15647
15749
|
)
|
|
15648
15750
|
);
|
|
15649
|
-
const { succeeded, failed } = processSessions(toProcess);
|
|
15751
|
+
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
15650
15752
|
console.log(
|
|
15651
|
-
chalk145.green(`Done: ${succeeded} summarised`) + (
|
|
15753
|
+
chalk145.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk145.yellow(`, ${failed2} skipped`) : "")
|
|
15652
15754
|
);
|
|
15653
15755
|
}
|
|
15654
15756
|
function selectCandidates(files, options2) {
|
|
@@ -15665,7 +15767,7 @@ function selectCandidates(files, options2) {
|
|
|
15665
15767
|
}
|
|
15666
15768
|
function processSessions(files) {
|
|
15667
15769
|
let succeeded = 0;
|
|
15668
|
-
let
|
|
15770
|
+
let failed2 = 0;
|
|
15669
15771
|
for (let i = 0; i < files.length; i++) {
|
|
15670
15772
|
const file = files[i];
|
|
15671
15773
|
process.stdout.write(chalk145.dim(` [${i + 1}/${files.length}] `));
|
|
@@ -15676,12 +15778,12 @@ function processSessions(files) {
|
|
|
15676
15778
|
process.stdout.write(`${chalk145.green("\u2713")} ${summary}
|
|
15677
15779
|
`);
|
|
15678
15780
|
} else {
|
|
15679
|
-
|
|
15781
|
+
failed2++;
|
|
15680
15782
|
process.stdout.write(` ${chalk145.yellow("skip")}
|
|
15681
15783
|
`);
|
|
15682
15784
|
}
|
|
15683
15785
|
}
|
|
15684
|
-
return { succeeded, failed };
|
|
15786
|
+
return { succeeded, failed: failed2 };
|
|
15685
15787
|
}
|
|
15686
15788
|
|
|
15687
15789
|
// src/commands/sessions/registerSessions.ts
|