@staff0rd/assist 0.239.0 → 0.240.0
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/README.md +3 -2
- package/dist/index.js +103 -115
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -91,13 +91,14 @@ After installation, the `assist` command will be available globally. You can als
|
|
|
91
91
|
- `assist prs fixed <comment-id> <sha>` - Reply with commit link and resolve thread
|
|
92
92
|
- `assist prs wontfix <comment-id> <reason>` - Reply with reason and resolve thread
|
|
93
93
|
- `assist prs comment <path> <line> <body>` - Add a line comment to the pending review
|
|
94
|
-
- `assist review [
|
|
95
|
-
- `[
|
|
94
|
+
- `assist review [number] [options]` - Run Claude and Codex in parallel to review the open PR for the current branch. The diff is fetched from GitHub (base SHA → head SHA via `gh pr diff`), so stale local base branches don't pollute the review; fails fast if no PR is open. By default, prompts before posting line-bound comments and then prompts again to submit the pending review (defaulting to no). Cached `claude.md` / `codex.md` / `synthesis.md` are reused when present; if any reviewer is re-run, the synthesis is invalidated.
|
|
95
|
+
- `[number]` - Run `gh pr checkout <number>` first, then review that PR's branch. If the checkout fails (dirty working tree, unknown PR number), the review aborts
|
|
96
96
|
- `--no-prompt` - Skip all confirmations
|
|
97
97
|
- `--submit` - Default the submit prompt to yes (or auto-submit when combined with `--no-prompt`)
|
|
98
98
|
- `--force` - Clear all cached files and re-run every phase
|
|
99
99
|
- `--refine` - Skip posting; launch an interactive Claude session that walks through `synthesis.md` and edits it in place. A subsequent `assist review` reuses the refined file and posts only the surviving findings
|
|
100
100
|
- `--apply` - Skip posting; launch an interactive Claude session that walks through each finding asking apply/skip. Applied findings are fixed in the working tree (unstaged) and removed from `synthesis.md`; skipped findings stay so a subsequent `assist review` posts them. Cannot be combined with `--refine`
|
|
101
|
+
- `--backlog` - Skip posting; launch an interactive Claude session running `/bug` that files all findings (including `already-raised`) as a single bug backlog item with one phase per finding. `synthesis.md` is left untouched; `--submit` is ignored. Cannot be combined with `--refine` or `--apply`
|
|
101
102
|
- `--verbose` - Disable the stacked-spinner UI and fall back to per-line log output. Non-TTY environments (CI) automatically use this mode
|
|
102
103
|
- `assist news` - Start the news web UI showing latest RSS feed items (same as `news web`)
|
|
103
104
|
- `assist news add [url]` - Add an RSS feed URL to the config
|
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.
|
|
9
|
+
version: "0.240.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -12863,6 +12863,9 @@ function registerRefactor(program2) {
|
|
|
12863
12863
|
registerRestructure(refactorCommand);
|
|
12864
12864
|
}
|
|
12865
12865
|
|
|
12866
|
+
// src/commands/review/review.ts
|
|
12867
|
+
import { execFileSync as execFileSync6 } from "child_process";
|
|
12868
|
+
|
|
12866
12869
|
// src/commands/review/formatPriorComments.ts
|
|
12867
12870
|
function threadKey(c, byId) {
|
|
12868
12871
|
if (c.threadId) return c.threadId;
|
|
@@ -12936,23 +12939,6 @@ ${formatFiles(context.changedFiles)}
|
|
|
12936
12939
|
${priorBlock}
|
|
12937
12940
|
## Diff (PR #${context.prNumber}: ${context.baseSha}..${context.headSha})
|
|
12938
12941
|
|
|
12939
|
-
\`\`\`diff
|
|
12940
|
-
${context.diff.trimEnd()}
|
|
12941
|
-
\`\`\`
|
|
12942
|
-
`;
|
|
12943
|
-
}
|
|
12944
|
-
function buildShaRequest(context) {
|
|
12945
|
-
return `# Code review request
|
|
12946
|
-
|
|
12947
|
-
- Commit: \`${context.sha}\`
|
|
12948
|
-
- Parent: \`${context.parentSha}\`
|
|
12949
|
-
|
|
12950
|
-
## Changed files
|
|
12951
|
-
|
|
12952
|
-
${formatFiles(context.changedFiles)}
|
|
12953
|
-
|
|
12954
|
-
## Diff (commit ${context.sha}: ${context.parentSha}..${context.sha})
|
|
12955
|
-
|
|
12956
12942
|
\`\`\`diff
|
|
12957
12943
|
${context.diff.trimEnd()}
|
|
12958
12944
|
\`\`\`
|
|
@@ -13006,12 +12992,41 @@ function fetchExistingComments() {
|
|
|
13006
12992
|
}
|
|
13007
12993
|
|
|
13008
12994
|
// src/commands/review/gatherContext.ts
|
|
13009
|
-
import { execSync as
|
|
12995
|
+
import { execSync as execSync43 } from "child_process";
|
|
13010
12996
|
|
|
13011
|
-
// src/commands/review/
|
|
12997
|
+
// src/commands/review/fetchPrDiff.ts
|
|
13012
12998
|
import { execSync as execSync41 } from "child_process";
|
|
12999
|
+
function fetchPrDiff(prNumber, baseSha, headSha) {
|
|
13000
|
+
const { org, repo } = getRepoInfo();
|
|
13001
|
+
try {
|
|
13002
|
+
return execSync41(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
|
|
13003
|
+
encoding: "utf-8",
|
|
13004
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
13005
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
13006
|
+
});
|
|
13007
|
+
} catch (error) {
|
|
13008
|
+
if (!isDiffTooLarge(error)) throw error;
|
|
13009
|
+
return fetchDiffViaGit(baseSha, headSha);
|
|
13010
|
+
}
|
|
13011
|
+
}
|
|
13012
|
+
function isDiffTooLarge(error) {
|
|
13013
|
+
return error instanceof Error && (error.message.includes("too_large") || error.message.includes("maximum number of files"));
|
|
13014
|
+
}
|
|
13015
|
+
function fetchDiffViaGit(baseSha, headSha) {
|
|
13016
|
+
try {
|
|
13017
|
+
execSync41(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
|
|
13018
|
+
} catch {
|
|
13019
|
+
}
|
|
13020
|
+
return execSync41(`git diff ${baseSha}...${headSha}`, {
|
|
13021
|
+
encoding: "utf-8",
|
|
13022
|
+
maxBuffer: 256 * 1024 * 1024
|
|
13023
|
+
});
|
|
13024
|
+
}
|
|
13025
|
+
|
|
13026
|
+
// src/commands/review/fetchPrDiffInfo.ts
|
|
13027
|
+
import { execSync as execSync42 } from "child_process";
|
|
13013
13028
|
function getCurrentBranch2() {
|
|
13014
|
-
return
|
|
13029
|
+
return execSync42("git rev-parse --abbrev-ref HEAD", {
|
|
13015
13030
|
encoding: "utf-8"
|
|
13016
13031
|
}).trim();
|
|
13017
13032
|
}
|
|
@@ -13021,7 +13036,7 @@ function fetchPrDiffInfo() {
|
|
|
13021
13036
|
const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
|
|
13022
13037
|
let raw;
|
|
13023
13038
|
try {
|
|
13024
|
-
raw =
|
|
13039
|
+
raw = execSync42(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
|
|
13025
13040
|
encoding: "utf-8",
|
|
13026
13041
|
stdio: ["ignore", "pipe", "pipe"]
|
|
13027
13042
|
});
|
|
@@ -13045,32 +13060,28 @@ function fetchPrDiffInfo() {
|
|
|
13045
13060
|
}
|
|
13046
13061
|
function fetchPrChangedFiles(prNumber) {
|
|
13047
13062
|
const { org, repo } = getRepoInfo();
|
|
13048
|
-
const out =
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13063
|
+
const out = execSync42(
|
|
13064
|
+
`gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
|
|
13065
|
+
{
|
|
13066
|
+
encoding: "utf-8",
|
|
13067
|
+
maxBuffer: 64 * 1024 * 1024
|
|
13068
|
+
}
|
|
13069
|
+
);
|
|
13052
13070
|
return out.trim().split("\n").filter(Boolean);
|
|
13053
13071
|
}
|
|
13054
|
-
function fetchPrDiff(prNumber) {
|
|
13055
|
-
const { org, repo } = getRepoInfo();
|
|
13056
|
-
return execSync41(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
|
|
13057
|
-
encoding: "utf-8",
|
|
13058
|
-
maxBuffer: 256 * 1024 * 1024
|
|
13059
|
-
});
|
|
13060
|
-
}
|
|
13061
13072
|
|
|
13062
13073
|
// src/commands/review/gatherContext.ts
|
|
13063
13074
|
function gatherContext() {
|
|
13064
|
-
const branch =
|
|
13075
|
+
const branch = execSync43("git rev-parse --abbrev-ref HEAD", {
|
|
13065
13076
|
encoding: "utf-8"
|
|
13066
13077
|
}).trim();
|
|
13067
|
-
const sha =
|
|
13068
|
-
const shortSha =
|
|
13078
|
+
const sha = execSync43("git rev-parse HEAD", { encoding: "utf-8" }).trim();
|
|
13079
|
+
const shortSha = execSync43("git rev-parse --short=7 HEAD", {
|
|
13069
13080
|
encoding: "utf-8"
|
|
13070
13081
|
}).trim();
|
|
13071
13082
|
const prInfo = fetchPrDiffInfo();
|
|
13072
13083
|
const changedFiles = fetchPrChangedFiles(prInfo.prNumber);
|
|
13073
|
-
const diff2 = fetchPrDiff(prInfo.prNumber);
|
|
13084
|
+
const diff2 = fetchPrDiff(prInfo.prNumber, prInfo.baseSha, prInfo.headSha);
|
|
13074
13085
|
return {
|
|
13075
13086
|
branch,
|
|
13076
13087
|
sha,
|
|
@@ -13440,6 +13451,29 @@ async function runApplySession(synthesisPath) {
|
|
|
13440
13451
|
await done2;
|
|
13441
13452
|
}
|
|
13442
13453
|
|
|
13454
|
+
// src/commands/review/runBacklogSession.ts
|
|
13455
|
+
function buildBacklogPrompt(synthesisPath) {
|
|
13456
|
+
return `/bug add each finding in ${synthesisPath} as a phase
|
|
13457
|
+
|
|
13458
|
+
Read ${synthesisPath}. It contains a list of findings under the \`## Findings\` heading, each in a \`### Finding:\` block with Severity, Source, Location, Impact, and Recommendation fields.
|
|
13459
|
+
|
|
13460
|
+
File ONE bug backlog item covering the review findings:
|
|
13461
|
+
- Include EVERY finding in the file as a phase on that single item \u2014 including findings whose Source is \`already-raised\`.
|
|
13462
|
+
- Each phase should be named after its finding's title and its tasks should capture the finding's Location, Impact, and Recommendation.
|
|
13463
|
+
- Use \`assist backlog add\` to create the item, then \`assist backlog add-phase\` for each finding.
|
|
13464
|
+
|
|
13465
|
+
Important constraints:
|
|
13466
|
+
- Do not edit ${synthesisPath} \u2014 leave it untouched.
|
|
13467
|
+
- Do not post anything to a PR.
|
|
13468
|
+
- Do not stage, commit, or push any changes.`;
|
|
13469
|
+
}
|
|
13470
|
+
async function runBacklogSession(synthesisPath) {
|
|
13471
|
+
const { done: done2 } = spawnClaude(buildBacklogPrompt(synthesisPath), {
|
|
13472
|
+
allowEdits: true
|
|
13473
|
+
});
|
|
13474
|
+
await done2;
|
|
13475
|
+
}
|
|
13476
|
+
|
|
13443
13477
|
// src/commands/review/cachedReviewerResult.ts
|
|
13444
13478
|
import { statSync as statSync2 } from "fs";
|
|
13445
13479
|
function cachedReviewerResult(name, outputPath) {
|
|
@@ -14356,6 +14390,10 @@ function setupReviewDir(repoRoot, context, force) {
|
|
|
14356
14390
|
return paths;
|
|
14357
14391
|
}
|
|
14358
14392
|
async function runPostSynthesis(synthesisPath, options2) {
|
|
14393
|
+
if (options2.backlog) {
|
|
14394
|
+
await runBacklogSession(synthesisPath);
|
|
14395
|
+
return;
|
|
14396
|
+
}
|
|
14359
14397
|
if (options2.apply) {
|
|
14360
14398
|
await runApplySession(synthesisPath);
|
|
14361
14399
|
return;
|
|
@@ -14376,58 +14414,6 @@ async function reviewPr(repoRoot, options2) {
|
|
|
14376
14414
|
console.log(`Done. Review folder: ${paths.reviewDir}`);
|
|
14377
14415
|
}
|
|
14378
14416
|
|
|
14379
|
-
// src/commands/review/gatherShaContext.ts
|
|
14380
|
-
import { execSync as execSync43 } from "child_process";
|
|
14381
|
-
function resolveSha(ref, format2) {
|
|
14382
|
-
const flag = format2 === "short" ? "--short=7 " : "";
|
|
14383
|
-
try {
|
|
14384
|
-
return execSync43(`git rev-parse --verify ${flag}${ref}^{commit}`, {
|
|
14385
|
-
encoding: "utf-8",
|
|
14386
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
14387
|
-
}).trim();
|
|
14388
|
-
} catch {
|
|
14389
|
-
console.error(`Error: could not resolve commit \`${ref}\`.`);
|
|
14390
|
-
process.exit(1);
|
|
14391
|
-
}
|
|
14392
|
-
}
|
|
14393
|
-
function gatherShaContext(ref) {
|
|
14394
|
-
const sha = resolveSha(ref, "long");
|
|
14395
|
-
const shortSha = resolveSha(sha, "short");
|
|
14396
|
-
const parentSha = resolveSha(`${sha}^`, "long");
|
|
14397
|
-
const range = `${parentSha}..${sha}`;
|
|
14398
|
-
const changedFiles = execSync43(`git diff --name-only ${range}`, {
|
|
14399
|
-
encoding: "utf-8",
|
|
14400
|
-
maxBuffer: 64 * 1024 * 1024
|
|
14401
|
-
}).trim().split("\n").filter(Boolean);
|
|
14402
|
-
const diff2 = execSync43(`git diff ${range}`, {
|
|
14403
|
-
encoding: "utf-8",
|
|
14404
|
-
maxBuffer: 256 * 1024 * 1024
|
|
14405
|
-
});
|
|
14406
|
-
return { sha, shortSha, parentSha, changedFiles, diff: diff2 };
|
|
14407
|
-
}
|
|
14408
|
-
|
|
14409
|
-
// src/commands/review/reviewSha.ts
|
|
14410
|
-
function gatherShaChangedContext(ref) {
|
|
14411
|
-
const context = gatherShaContext(ref);
|
|
14412
|
-
if (context.changedFiles.length > 0) return context;
|
|
14413
|
-
console.error(
|
|
14414
|
-
`Error: commit ${context.sha} has no changed files \u2014 nothing to review.`
|
|
14415
|
-
);
|
|
14416
|
-
process.exit(1);
|
|
14417
|
-
}
|
|
14418
|
-
function setupShaReviewDir(repoRoot, context, force) {
|
|
14419
|
-
const paths = buildReviewPaths(repoRoot, context.shortSha);
|
|
14420
|
-
prepareReviewDir(paths, buildShaRequest(context), force);
|
|
14421
|
-
console.log(`Review folder: ${paths.reviewDir}`);
|
|
14422
|
-
return paths;
|
|
14423
|
-
}
|
|
14424
|
-
async function reviewSha(repoRoot, options2) {
|
|
14425
|
-
const context = gatherShaChangedContext(options2.sha);
|
|
14426
|
-
const paths = setupShaReviewDir(repoRoot, context, options2.force ?? false);
|
|
14427
|
-
await runReviewPipeline(paths, { verbose: options2.verbose ?? false });
|
|
14428
|
-
console.log(`Done. Review folder: ${paths.reviewDir}`);
|
|
14429
|
-
}
|
|
14430
|
-
|
|
14431
14417
|
// src/commands/review/review.ts
|
|
14432
14418
|
function resolveRepoRoot() {
|
|
14433
14419
|
const repoRoot = findRepoRoot(process.cwd());
|
|
@@ -14435,41 +14421,40 @@ function resolveRepoRoot() {
|
|
|
14435
14421
|
console.error("Error: not inside a git repository.");
|
|
14436
14422
|
process.exit(1);
|
|
14437
14423
|
}
|
|
14438
|
-
function rejectShaFlag(flag) {
|
|
14439
|
-
console.error(`Error: ${flag} cannot be combined with a SHA argument.`);
|
|
14440
|
-
process.exit(1);
|
|
14441
|
-
}
|
|
14442
14424
|
function validateOptions(options2) {
|
|
14443
14425
|
if (options2.apply && options2.refine) {
|
|
14444
14426
|
console.error("Error: --apply cannot be combined with --refine.");
|
|
14445
14427
|
process.exit(1);
|
|
14446
14428
|
}
|
|
14447
|
-
if (
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14429
|
+
if (options2.backlog && (options2.refine || options2.apply)) {
|
|
14430
|
+
console.error(
|
|
14431
|
+
"Error: --backlog cannot be combined with --refine or --apply."
|
|
14432
|
+
);
|
|
14433
|
+
process.exit(1);
|
|
14434
|
+
}
|
|
14435
|
+
}
|
|
14436
|
+
function checkoutPr(number) {
|
|
14437
|
+
try {
|
|
14438
|
+
execFileSync6("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
14439
|
+
} catch {
|
|
14440
|
+
console.error(`gh pr checkout ${number} failed; aborting.`);
|
|
14441
|
+
process.exit(1);
|
|
14442
|
+
}
|
|
14451
14443
|
}
|
|
14452
14444
|
async function review(options2 = {}) {
|
|
14453
14445
|
validateOptions(options2);
|
|
14454
14446
|
const repoRoot = resolveRepoRoot();
|
|
14455
|
-
if (options2.
|
|
14456
|
-
await reviewSha(repoRoot, {
|
|
14457
|
-
sha: options2.sha,
|
|
14458
|
-
force: options2.force,
|
|
14459
|
-
verbose: options2.verbose
|
|
14460
|
-
});
|
|
14461
|
-
return;
|
|
14462
|
-
}
|
|
14447
|
+
if (options2.number) checkoutPr(options2.number);
|
|
14463
14448
|
await reviewPr(repoRoot, options2);
|
|
14464
14449
|
}
|
|
14465
14450
|
|
|
14466
14451
|
// src/commands/registerReview.ts
|
|
14467
14452
|
function registerReview(program2) {
|
|
14468
14453
|
program2.command("review").description(
|
|
14469
|
-
"Run Claude and Codex in parallel to review the current branch, or a
|
|
14454
|
+
"Run Claude and Codex in parallel to review the current branch's PR, or check out a PR by number first when given"
|
|
14470
14455
|
).argument(
|
|
14471
|
-
"[
|
|
14472
|
-
"Optional
|
|
14456
|
+
"[number]",
|
|
14457
|
+
"Optional PR number; when provided, runs `gh pr checkout <number>` before reviewing"
|
|
14473
14458
|
).option(
|
|
14474
14459
|
"--no-prompt",
|
|
14475
14460
|
"Skip confirmation prompts; use flag defaults non-interactively"
|
|
@@ -14485,11 +14470,14 @@ function registerReview(program2) {
|
|
|
14485
14470
|
).option(
|
|
14486
14471
|
"--apply",
|
|
14487
14472
|
"After synthesis, launch an interactive Claude session to apply fixes for each finding; applied findings are removed from synthesis, skipped ones remain for a later post"
|
|
14473
|
+
).option(
|
|
14474
|
+
"--backlog",
|
|
14475
|
+
"After synthesis, launch an interactive Claude session running /bug to file all findings as a single backlog item with one phase per finding, instead of posting to the PR"
|
|
14488
14476
|
).option(
|
|
14489
14477
|
"--verbose",
|
|
14490
14478
|
"Disable spinner UI and use per-line log output (per-tool lines, starting/done lines)"
|
|
14491
14479
|
).action(
|
|
14492
|
-
(
|
|
14480
|
+
(number, options2) => review({ ...options2, number })
|
|
14493
14481
|
);
|
|
14494
14482
|
}
|
|
14495
14483
|
|
|
@@ -16229,7 +16217,7 @@ async function auth() {
|
|
|
16229
16217
|
}
|
|
16230
16218
|
|
|
16231
16219
|
// src/commands/roam/postRoamActivity.ts
|
|
16232
|
-
import { execFileSync as
|
|
16220
|
+
import { execFileSync as execFileSync7 } from "child_process";
|
|
16233
16221
|
import { readdirSync as readdirSync7, readFileSync as readFileSync37, statSync as statSync4 } from "fs";
|
|
16234
16222
|
import { join as join47 } from "path";
|
|
16235
16223
|
function findPortFile(roamDir) {
|
|
@@ -16262,7 +16250,7 @@ function postRoamActivity(app, event) {
|
|
|
16262
16250
|
}
|
|
16263
16251
|
const url = `http://127.0.0.1:${port}/api/v1/activity/${app}/${event}?pid=${app === "codex" ? 99998 : 99999}`;
|
|
16264
16252
|
try {
|
|
16265
|
-
|
|
16253
|
+
execFileSync7("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
|
|
16266
16254
|
stdio: "ignore"
|
|
16267
16255
|
});
|
|
16268
16256
|
} catch {
|
|
@@ -16389,13 +16377,13 @@ function runPreCommands(pre, cwd) {
|
|
|
16389
16377
|
}
|
|
16390
16378
|
|
|
16391
16379
|
// src/commands/run/spawnRunCommand.ts
|
|
16392
|
-
import { execFileSync as
|
|
16380
|
+
import { execFileSync as execFileSync8, spawn as spawn8 } from "child_process";
|
|
16393
16381
|
import { existsSync as existsSync47 } from "fs";
|
|
16394
16382
|
import { dirname as dirname25, join as join48, resolve as resolve11 } from "path";
|
|
16395
16383
|
function resolveCommand2(command) {
|
|
16396
16384
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
16397
16385
|
try {
|
|
16398
|
-
const gitPath =
|
|
16386
|
+
const gitPath = execFileSync8("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
16399
16387
|
const gitRoot = resolve11(dirname25(gitPath), "..");
|
|
16400
16388
|
const gitBash = join48(gitRoot, "bin", "bash.exe");
|
|
16401
16389
|
if (existsSync47(gitBash)) return gitBash;
|
|
@@ -16827,7 +16815,7 @@ function summaryPathFor(jsonlPath2) {
|
|
|
16827
16815
|
}
|
|
16828
16816
|
|
|
16829
16817
|
// src/commands/sessions/summarise/summariseSession.ts
|
|
16830
|
-
import { execFileSync as
|
|
16818
|
+
import { execFileSync as execFileSync9 } from "child_process";
|
|
16831
16819
|
|
|
16832
16820
|
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
16833
16821
|
import * as fs27 from "fs";
|
|
@@ -16904,7 +16892,7 @@ function summariseSession(jsonlPath2) {
|
|
|
16904
16892
|
}
|
|
16905
16893
|
const prompt = buildPrompt2(firstMessage, backlogIds);
|
|
16906
16894
|
try {
|
|
16907
|
-
const output =
|
|
16895
|
+
const output = execFileSync9("claude", ["-p", "--model", "haiku", prompt], {
|
|
16908
16896
|
encoding: "utf8",
|
|
16909
16897
|
timeout: 3e4,
|
|
16910
16898
|
stdio: ["ignore", "pipe", "ignore"]
|