@staff0rd/assist 0.572.0 → 0.573.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 +1 -0
- package/claude/commands/github.md +4 -4
- package/dist/commands/sessions/web/bundle.js +2 -2
- package/dist/index.js +269 -107
- 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.
|
|
9
|
+
version: "0.573.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -16726,6 +16726,10 @@ var BUILTIN_DENIES = [
|
|
|
16726
16726
|
pattern: "gh issue create",
|
|
16727
16727
|
message: "Do not run 'gh issue create' directly. Use 'assist github issue create --title <title> --body <body> [-R <owner>/<repo>]' instead \u2014 it validates the title and body before delegating to gh, and gates the issue on the user's approval itself. Run 'assist github issue create --help' and follow its guidance to compose the body; it is authoritative on how approval is handled in this environment."
|
|
16728
16728
|
},
|
|
16729
|
+
{
|
|
16730
|
+
pattern: "gh issue comment",
|
|
16731
|
+
message: "Do not run 'gh issue comment' directly. Use 'assist github issue comment <number> --body <body> [-R <owner>/<repo>]' instead \u2014 it validates the body before delegating to gh, and gates the comment on the user's approval itself. Run 'assist github issue comment --help' and follow its guidance to compose the body; it is authoritative on how approval is handled in this environment."
|
|
16732
|
+
},
|
|
16729
16733
|
{
|
|
16730
16734
|
pattern: "git commit",
|
|
16731
16735
|
message: `Do not run 'git commit' directly. Use 'assist commit "<message>"' instead.`
|
|
@@ -20629,7 +20633,29 @@ function commits(org, options2) {
|
|
|
20629
20633
|
}
|
|
20630
20634
|
}
|
|
20631
20635
|
|
|
20632
|
-
// src/commands/github/
|
|
20636
|
+
// src/commands/github/parseSinceDate.ts
|
|
20637
|
+
import { InvalidArgumentError } from "commander";
|
|
20638
|
+
function parseSinceDate(value) {
|
|
20639
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
20640
|
+
throw new InvalidArgumentError("Expected a date in YYYY-MM-DD format.");
|
|
20641
|
+
}
|
|
20642
|
+
const date = /* @__PURE__ */ new Date(`${value}T00:00:00Z`);
|
|
20643
|
+
if (Number.isNaN(date.getTime()) || date.toISOString().slice(0, 10) !== value) {
|
|
20644
|
+
throw new InvalidArgumentError(`Not a valid calendar date: ${value}.`);
|
|
20645
|
+
}
|
|
20646
|
+
return value;
|
|
20647
|
+
}
|
|
20648
|
+
|
|
20649
|
+
// src/commands/github/parseTopCount.ts
|
|
20650
|
+
import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
20651
|
+
function parseTopCount(value) {
|
|
20652
|
+
if (!/^\d+$/.test(value) || Number.parseInt(value, 10) < 1) {
|
|
20653
|
+
throw new InvalidArgumentError2("Expected a positive integer.");
|
|
20654
|
+
}
|
|
20655
|
+
return Number.parseInt(value, 10);
|
|
20656
|
+
}
|
|
20657
|
+
|
|
20658
|
+
// src/commands/github/issue/commentIssue.ts
|
|
20633
20659
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
20634
20660
|
|
|
20635
20661
|
// src/shared/validateProposedContent.ts
|
|
@@ -20657,14 +20683,58 @@ function validateProposedContent(labels, title, body) {
|
|
|
20657
20683
|
}
|
|
20658
20684
|
}
|
|
20659
20685
|
|
|
20660
|
-
// src/commands/github/issue/
|
|
20686
|
+
// src/commands/github/issue/reviewProposedIssueComment.ts
|
|
20661
20687
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
20688
|
+
async function reviewProposedIssueComment(title, body) {
|
|
20689
|
+
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
20690
|
+
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
|
|
20691
|
+
await awaitPreviewApproval("GitHub issue comment preview", {
|
|
20692
|
+
sessionId,
|
|
20693
|
+
requestId: randomUUID7(),
|
|
20694
|
+
title,
|
|
20695
|
+
body,
|
|
20696
|
+
prNumber: null,
|
|
20697
|
+
kind: "github-issue-comment"
|
|
20698
|
+
});
|
|
20699
|
+
}
|
|
20700
|
+
|
|
20701
|
+
// src/commands/github/issue/commentIssue.ts
|
|
20702
|
+
var USAGE = "Usage: assist github issue comment <number> --body <body> [-R <owner>/<repo>]";
|
|
20703
|
+
async function commentIssue(numberArg, options2) {
|
|
20704
|
+
const number = Number.parseInt(numberArg, 10);
|
|
20705
|
+
if (!Number.isInteger(number) || number <= 0 || !options2.body) {
|
|
20706
|
+
console.error(USAGE);
|
|
20707
|
+
process.exit(1);
|
|
20708
|
+
}
|
|
20709
|
+
const { body } = options2;
|
|
20710
|
+
const target = options2.repo ? `${options2.repo}#${number}` : `issue #${number}`;
|
|
20711
|
+
validateProposedContent(
|
|
20712
|
+
{ subject: "Comment", context: "GitHub issues" },
|
|
20713
|
+
"",
|
|
20714
|
+
body
|
|
20715
|
+
);
|
|
20716
|
+
await reviewProposedIssueComment(`Comment on ${target}`, body);
|
|
20717
|
+
const args = ["issue", "comment", String(number), "--body", body];
|
|
20718
|
+
if (options2.repo) args.push("--repo", options2.repo);
|
|
20719
|
+
try {
|
|
20720
|
+
execFileSync6("gh", args, { stdio: "inherit" });
|
|
20721
|
+
} catch {
|
|
20722
|
+
process.exit(1);
|
|
20723
|
+
}
|
|
20724
|
+
console.log(`Comment posted to ${target}`);
|
|
20725
|
+
}
|
|
20726
|
+
|
|
20727
|
+
// src/commands/github/issue/createIssue.ts
|
|
20728
|
+
import { execFileSync as execFileSync7 } from "child_process";
|
|
20729
|
+
|
|
20730
|
+
// src/commands/github/issue/reviewProposedIssue.ts
|
|
20731
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
20662
20732
|
async function reviewProposedIssue(title, body) {
|
|
20663
20733
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
20664
20734
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
|
|
20665
20735
|
await awaitPreviewApproval("GitHub issue preview", {
|
|
20666
20736
|
sessionId,
|
|
20667
|
-
requestId:
|
|
20737
|
+
requestId: randomUUID8(),
|
|
20668
20738
|
title,
|
|
20669
20739
|
body,
|
|
20670
20740
|
prNumber: null,
|
|
@@ -20673,10 +20743,10 @@ async function reviewProposedIssue(title, body) {
|
|
|
20673
20743
|
}
|
|
20674
20744
|
|
|
20675
20745
|
// src/commands/github/issue/createIssue.ts
|
|
20676
|
-
var
|
|
20746
|
+
var USAGE2 = "Usage: assist github issue create --title <title> --body <body> [-R <owner>/<repo>]";
|
|
20677
20747
|
async function createIssue(options2) {
|
|
20678
20748
|
if (!options2.title || !options2.body) {
|
|
20679
|
-
console.error(
|
|
20749
|
+
console.error(USAGE2);
|
|
20680
20750
|
process.exit(1);
|
|
20681
20751
|
}
|
|
20682
20752
|
const { title, body } = options2;
|
|
@@ -20689,32 +20759,47 @@ async function createIssue(options2) {
|
|
|
20689
20759
|
const args = ["issue", "create", "--title", title, "--body", body];
|
|
20690
20760
|
if (options2.repo) args.push("--repo", options2.repo);
|
|
20691
20761
|
try {
|
|
20692
|
-
|
|
20762
|
+
execFileSync7("gh", args, { stdio: "inherit" });
|
|
20693
20763
|
} catch {
|
|
20694
20764
|
process.exit(1);
|
|
20695
20765
|
}
|
|
20696
20766
|
}
|
|
20697
20767
|
|
|
20698
|
-
// src/commands/
|
|
20699
|
-
|
|
20700
|
-
|
|
20701
|
-
|
|
20702
|
-
|
|
20703
|
-
|
|
20704
|
-
|
|
20705
|
-
if (Number.isNaN(date.getTime()) || date.toISOString().slice(0, 10) !== value) {
|
|
20706
|
-
throw new InvalidArgumentError(`Not a valid calendar date: ${value}.`);
|
|
20768
|
+
// src/commands/prs/readBodyArgument.ts
|
|
20769
|
+
async function readBodyArgument(value) {
|
|
20770
|
+
if (value !== "-") return value;
|
|
20771
|
+
const body = (await readStdinBuffer()).toString("utf8").replace(/\n+$/, "");
|
|
20772
|
+
if (body.trim().length === 0) {
|
|
20773
|
+
console.error("Error: No body was provided on stdin.");
|
|
20774
|
+
process.exit(1);
|
|
20707
20775
|
}
|
|
20708
|
-
return
|
|
20776
|
+
return body;
|
|
20709
20777
|
}
|
|
20710
20778
|
|
|
20711
|
-
// src/commands/
|
|
20712
|
-
|
|
20713
|
-
|
|
20714
|
-
|
|
20715
|
-
|
|
20716
|
-
|
|
20717
|
-
|
|
20779
|
+
// src/commands/registerGithubIssue.ts
|
|
20780
|
+
function registerGithubIssue(githubCommand) {
|
|
20781
|
+
const issueCommand = githubCommand.command("issue").description("GitHub issue utilities");
|
|
20782
|
+
issueCommand.command("create").description("Create a GitHub issue").option("--title <title>", "Issue title").option("--body <body>", "Issue body").option(
|
|
20783
|
+
"-R, --repo <owner/repo>",
|
|
20784
|
+
"Target repository (defaults to the current repo)"
|
|
20785
|
+
).addHelpText(
|
|
20786
|
+
"after",
|
|
20787
|
+
"\nThere is no What/Why/How template: an issue reports a problem, and the target repo's own issue template is unknowable from here. Write the body as the repo's maintainers would expect.\nIn an assist web session the title and body are previewed for approve/reject first (with inline comments); nothing is created until it is approved."
|
|
20788
|
+
).action(createIssue);
|
|
20789
|
+
issueCommand.command("comment <number>").description("Comment on a GitHub issue (body of - reads it from stdin)").option("--body <body>", "Comment body (- reads it from stdin)").option(
|
|
20790
|
+
"-R, --repo <owner/repo>",
|
|
20791
|
+
"Target repository (defaults to the current repo)"
|
|
20792
|
+
).addHelpText(
|
|
20793
|
+
"after",
|
|
20794
|
+
"\nThe comment is outward-facing: write it for the repo's readers, not the team. It is rejected if it references Claude or an assist backlog item.\nIn an assist web session the body is previewed for approve/reject first (with inline comments); nothing is posted until it is approved."
|
|
20795
|
+
).action(
|
|
20796
|
+
async (number, options2) => {
|
|
20797
|
+
await commentIssue(number, {
|
|
20798
|
+
...options2,
|
|
20799
|
+
body: options2.body ? await readBodyArgument(options2.body) : void 0
|
|
20800
|
+
});
|
|
20801
|
+
}
|
|
20802
|
+
);
|
|
20718
20803
|
}
|
|
20719
20804
|
|
|
20720
20805
|
// src/commands/registerGithub.ts
|
|
@@ -20729,14 +20814,7 @@ function registerGithub(program2) {
|
|
|
20729
20814
|
"only report the top <n> repos by commit count",
|
|
20730
20815
|
parseTopCount
|
|
20731
20816
|
).option("--json", "Output as JSON").action(commits);
|
|
20732
|
-
|
|
20733
|
-
issueCommand.command("create").description("Create a GitHub issue").option("--title <title>", "Issue title").option("--body <body>", "Issue body").option(
|
|
20734
|
-
"-R, --repo <owner/repo>",
|
|
20735
|
-
"Target repository (defaults to the current repo)"
|
|
20736
|
-
).addHelpText(
|
|
20737
|
-
"after",
|
|
20738
|
-
"\nThere is no What/Why/How template: an issue reports a problem, and the target repo's own issue template is unknowable from here. Write the body as the repo's maintainers would expect.\nIn an assist web session the title and body are previewed for approve/reject first (with inline comments); nothing is created until it is approved."
|
|
20739
|
-
).action(createIssue);
|
|
20817
|
+
registerGithubIssue(githubCommand);
|
|
20740
20818
|
}
|
|
20741
20819
|
|
|
20742
20820
|
// src/commands/handover/countPendingHandovers.ts
|
|
@@ -21146,10 +21224,10 @@ function registerRefineLaunch(program2, resumeFlag) {
|
|
|
21146
21224
|
}
|
|
21147
21225
|
|
|
21148
21226
|
// src/commands/reviewPrComments.ts
|
|
21149
|
-
import { randomUUID as
|
|
21227
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
21150
21228
|
|
|
21151
21229
|
// src/commands/review/checkoutPr.ts
|
|
21152
|
-
import { execFileSync as
|
|
21230
|
+
import { execFileSync as execFileSync9 } from "child_process";
|
|
21153
21231
|
import chalk164 from "chalk";
|
|
21154
21232
|
|
|
21155
21233
|
// src/commands/sessions/daemon/daemonLog.ts
|
|
@@ -21709,10 +21787,10 @@ async function moveToPrCheckoutTree() {
|
|
|
21709
21787
|
}
|
|
21710
21788
|
|
|
21711
21789
|
// src/commands/review/prHeadBranch.ts
|
|
21712
|
-
import { execFileSync as
|
|
21790
|
+
import { execFileSync as execFileSync8 } from "child_process";
|
|
21713
21791
|
function prHeadBranch(number) {
|
|
21714
21792
|
try {
|
|
21715
|
-
const out =
|
|
21793
|
+
const out = execFileSync8(
|
|
21716
21794
|
"gh",
|
|
21717
21795
|
["pr", "view", number, "--json", "headRefName", "-q", ".headRefName"],
|
|
21718
21796
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -21760,7 +21838,7 @@ async function checkoutPr(number) {
|
|
|
21760
21838
|
if (headRef && moveToExistingCheckout(number, headRef)) return;
|
|
21761
21839
|
await moveToPrCheckoutTree();
|
|
21762
21840
|
try {
|
|
21763
|
-
|
|
21841
|
+
execFileSync9("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
21764
21842
|
} catch {
|
|
21765
21843
|
console.error(chalk164.red(`gh pr checkout ${number} failed; aborting.`));
|
|
21766
21844
|
process.exit(1);
|
|
@@ -21782,7 +21860,7 @@ async function reviewPrComments(number, options2 = {}) {
|
|
|
21782
21860
|
const resumeSessionId = options2.resumeSessionId;
|
|
21783
21861
|
validateAnnounce(number, announce);
|
|
21784
21862
|
if (number && !resumeSessionId) await checkoutPr(number);
|
|
21785
|
-
const claudeSessionId = resumeSessionId ??
|
|
21863
|
+
const claudeSessionId = resumeSessionId ?? randomUUID9();
|
|
21786
21864
|
emitActivity({
|
|
21787
21865
|
kind: "command",
|
|
21788
21866
|
name: "review-pr-comments",
|
|
@@ -21800,14 +21878,14 @@ async function reviewPrComments(number, options2 = {}) {
|
|
|
21800
21878
|
}
|
|
21801
21879
|
|
|
21802
21880
|
// src/commands/fixConflict.ts
|
|
21803
|
-
import { randomUUID as
|
|
21881
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
21804
21882
|
function buildPrompt3(rebase) {
|
|
21805
21883
|
return rebase ? "/fix-conflict --rebase" : "/fix-conflict";
|
|
21806
21884
|
}
|
|
21807
21885
|
async function fixConflict(number, options2 = {}) {
|
|
21808
21886
|
const { resumeSessionId } = options2;
|
|
21809
21887
|
if (number && !resumeSessionId) await checkoutPr(number);
|
|
21810
|
-
const claudeSessionId = resumeSessionId ??
|
|
21888
|
+
const claudeSessionId = resumeSessionId ?? randomUUID10();
|
|
21811
21889
|
emitActivity({
|
|
21812
21890
|
kind: "command",
|
|
21813
21891
|
name: "fix-conflict",
|
|
@@ -22829,13 +22907,13 @@ function postReviewComment(vars) {
|
|
|
22829
22907
|
}
|
|
22830
22908
|
|
|
22831
22909
|
// src/commands/prs/reviewProposedPrComment.ts
|
|
22832
|
-
import { randomUUID as
|
|
22910
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
22833
22911
|
async function reviewProposedPrComment(title, body, prNumber) {
|
|
22834
22912
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
22835
22913
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
|
|
22836
22914
|
await awaitPreviewApproval("PR comment preview", {
|
|
22837
22915
|
sessionId,
|
|
22838
|
-
requestId:
|
|
22916
|
+
requestId: randomUUID11(),
|
|
22839
22917
|
title,
|
|
22840
22918
|
body,
|
|
22841
22919
|
prNumber,
|
|
@@ -22961,7 +23039,7 @@ async function comment2(path80, line, body, startLine) {
|
|
|
22961
23039
|
}
|
|
22962
23040
|
|
|
22963
23041
|
// src/commands/prs/edit.ts
|
|
22964
|
-
import { randomUUID as
|
|
23042
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
22965
23043
|
|
|
22966
23044
|
// src/commands/prs/appendScreenshots.ts
|
|
22967
23045
|
function appendScreenshots(body, screenshots) {
|
|
@@ -22974,13 +23052,13 @@ ${screenshots.join("\n\n")}`;
|
|
|
22974
23052
|
}
|
|
22975
23053
|
|
|
22976
23054
|
// src/commands/prs/applyEdit.ts
|
|
22977
|
-
import { execFileSync as
|
|
23055
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
22978
23056
|
function applyEdit(number, title, body) {
|
|
22979
23057
|
const args = ["pr", "edit", String(number)];
|
|
22980
23058
|
if (title) args.push("--title", title);
|
|
22981
23059
|
args.push("--body", body);
|
|
22982
23060
|
try {
|
|
22983
|
-
|
|
23061
|
+
execFileSync10("gh", args, { stdio: "inherit" });
|
|
22984
23062
|
} catch {
|
|
22985
23063
|
process.exit(1);
|
|
22986
23064
|
}
|
|
@@ -23158,7 +23236,7 @@ async function edit(options2) {
|
|
|
23158
23236
|
if (process.env.ASSIST_SESSION === "1" && sessionId) {
|
|
23159
23237
|
const decision = await awaitPreviewApproval("PR preview", {
|
|
23160
23238
|
sessionId,
|
|
23161
|
-
requestId:
|
|
23239
|
+
requestId: randomUUID12(),
|
|
23162
23240
|
title: options2.title ?? title,
|
|
23163
23241
|
body: newBody,
|
|
23164
23242
|
prNumber: number
|
|
@@ -23776,7 +23854,7 @@ function buildValidatedBody(options2, usage) {
|
|
|
23776
23854
|
}
|
|
23777
23855
|
|
|
23778
23856
|
// src/commands/prs/placePr.ts
|
|
23779
|
-
import { execFileSync as
|
|
23857
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
23780
23858
|
|
|
23781
23859
|
// src/commands/prs/buildCreateArgs.ts
|
|
23782
23860
|
function buildEditArgs(number, title, body) {
|
|
@@ -23843,7 +23921,7 @@ async function recordPrActivity() {
|
|
|
23843
23921
|
// src/commands/prs/placePr.ts
|
|
23844
23922
|
function hasUpstream2() {
|
|
23845
23923
|
try {
|
|
23846
|
-
|
|
23924
|
+
execFileSync11(
|
|
23847
23925
|
"git",
|
|
23848
23926
|
["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"],
|
|
23849
23927
|
{ stdio: "pipe" }
|
|
@@ -23855,13 +23933,13 @@ function hasUpstream2() {
|
|
|
23855
23933
|
}
|
|
23856
23934
|
function ensureBranchPushed() {
|
|
23857
23935
|
const args = hasUpstream2() ? ["push"] : ["push", "--set-upstream", "origin", "HEAD"];
|
|
23858
|
-
|
|
23936
|
+
execFileSync11("git", args, { stdio: "inherit" });
|
|
23859
23937
|
}
|
|
23860
23938
|
async function placePr(prNumber, title, body, options2) {
|
|
23861
23939
|
const args = prNumber !== null ? buildEditArgs(prNumber, title, body) : buildCreateArgs(title, body, options2);
|
|
23862
23940
|
try {
|
|
23863
23941
|
if (prNumber === null && !options2.head) ensureBranchPushed();
|
|
23864
|
-
|
|
23942
|
+
execFileSync11("gh", args, { stdio: "inherit" });
|
|
23865
23943
|
} catch {
|
|
23866
23944
|
process.exit(1);
|
|
23867
23945
|
}
|
|
@@ -23869,7 +23947,7 @@ async function placePr(prNumber, title, body, options2) {
|
|
|
23869
23947
|
}
|
|
23870
23948
|
|
|
23871
23949
|
// src/commands/prs/previewAndPlace.ts
|
|
23872
|
-
import { randomUUID as
|
|
23950
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
23873
23951
|
|
|
23874
23952
|
// src/commands/sessions/shared/requestSession.ts
|
|
23875
23953
|
function parseIncoming(line, type) {
|
|
@@ -24004,7 +24082,7 @@ function warn(reason4) {
|
|
|
24004
24082
|
async function previewAndPlace(args) {
|
|
24005
24083
|
const decision = await awaitPreviewApproval("PR preview", {
|
|
24006
24084
|
sessionId: args.sessionId,
|
|
24007
|
-
requestId:
|
|
24085
|
+
requestId: randomUUID13(),
|
|
24008
24086
|
title: args.title,
|
|
24009
24087
|
body: args.body,
|
|
24010
24088
|
prNumber: args.prNumber,
|
|
@@ -24024,9 +24102,9 @@ function resolveDraftState(options2, command) {
|
|
|
24024
24102
|
}
|
|
24025
24103
|
|
|
24026
24104
|
// src/commands/prs/raise.ts
|
|
24027
|
-
var
|
|
24105
|
+
var USAGE3 = "Usage: assist prs raise --title <title> --what <what> --why <why> [--how <how>] [--resolves <key>] [--force]";
|
|
24028
24106
|
async function raise(options2, command) {
|
|
24029
|
-
const { title, body } = buildValidatedBody(options2,
|
|
24107
|
+
const { title, body } = buildValidatedBody(options2, USAGE3);
|
|
24030
24108
|
const resolved = { ...options2, draft: resolveDraftState(options2, command) };
|
|
24031
24109
|
const existing = findCurrentPrNumber();
|
|
24032
24110
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
@@ -24125,17 +24203,6 @@ async function wontfix(commentId, reason4) {
|
|
|
24125
24203
|
}
|
|
24126
24204
|
}
|
|
24127
24205
|
|
|
24128
|
-
// src/commands/prs/readBodyArgument.ts
|
|
24129
|
-
async function readBodyArgument(value) {
|
|
24130
|
-
if (value !== "-") return value;
|
|
24131
|
-
const body = (await readStdinBuffer()).toString("utf8").replace(/\n+$/, "");
|
|
24132
|
-
if (body.trim().length === 0) {
|
|
24133
|
-
console.error("Error: No body was provided on stdin.");
|
|
24134
|
-
process.exit(1);
|
|
24135
|
-
}
|
|
24136
|
-
return body;
|
|
24137
|
-
}
|
|
24138
|
-
|
|
24139
24206
|
// src/commands/registerPrsComments.ts
|
|
24140
24207
|
function registerPrsComments(prsCommand) {
|
|
24141
24208
|
prsCommand.command("list-comments").description("List all comments on the current branch's pull request").action(() => {
|
|
@@ -26487,10 +26554,10 @@ function registerRefactor(program2) {
|
|
|
26487
26554
|
}
|
|
26488
26555
|
|
|
26489
26556
|
// src/commands/review/checkoutOnlySession.ts
|
|
26490
|
-
import { randomUUID as
|
|
26557
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
26491
26558
|
async function checkoutOnlySession(number) {
|
|
26492
26559
|
await checkoutPr(number);
|
|
26493
|
-
const claudeSessionId =
|
|
26560
|
+
const claudeSessionId = randomUUID14();
|
|
26494
26561
|
emitActivity({ kind: "command", name: "review", claudeSessionId });
|
|
26495
26562
|
const { done: done2 } = spawnClaude("", {
|
|
26496
26563
|
permissionMode: "acceptEdits",
|
|
@@ -30122,9 +30189,9 @@ function registerVoice(program2) {
|
|
|
30122
30189
|
import { join as join83 } from "path";
|
|
30123
30190
|
|
|
30124
30191
|
// src/commands/watch/resolveUpstream.ts
|
|
30125
|
-
import { execFileSync as
|
|
30192
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
30126
30193
|
function runGit2(args, cwd) {
|
|
30127
|
-
return
|
|
30194
|
+
return execFileSync12("git", args, {
|
|
30128
30195
|
encoding: "utf8",
|
|
30129
30196
|
stdio: ["pipe", "pipe", "pipe"],
|
|
30130
30197
|
cwd
|
|
@@ -30485,13 +30552,13 @@ import { spawn as spawn9 } from "child_process";
|
|
|
30485
30552
|
import { existsSync as existsSync68 } from "fs";
|
|
30486
30553
|
|
|
30487
30554
|
// src/commands/run/resolveCommand.ts
|
|
30488
|
-
import { execFileSync as
|
|
30555
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
30489
30556
|
import { existsSync as existsSync67 } from "fs";
|
|
30490
30557
|
import { dirname as dirname35, join as join84, resolve as resolve19 } from "path";
|
|
30491
30558
|
function resolveCommand2(command) {
|
|
30492
30559
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
30493
30560
|
try {
|
|
30494
|
-
const gitPath =
|
|
30561
|
+
const gitPath = execFileSync13("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
30495
30562
|
const gitRoot = resolve19(dirname35(gitPath), "..");
|
|
30496
30563
|
const gitBash = join84(gitRoot, "bin", "bash.exe");
|
|
30497
30564
|
if (existsSync67(gitBash)) return gitBash;
|
|
@@ -30588,11 +30655,11 @@ async function reportBuildOrExit(entry) {
|
|
|
30588
30655
|
}
|
|
30589
30656
|
|
|
30590
30657
|
// src/commands/watch/fetchQuietly.ts
|
|
30591
|
-
import { execFileSync as
|
|
30658
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
30592
30659
|
var MIN_FETCH_TIMEOUT_MS = 6e4;
|
|
30593
30660
|
function fetchQuietly(cwd, intervalMs) {
|
|
30594
30661
|
try {
|
|
30595
|
-
|
|
30662
|
+
execFileSync14("git", ["fetch", "--quiet"], {
|
|
30596
30663
|
stdio: ["pipe", "pipe", "pipe"],
|
|
30597
30664
|
cwd,
|
|
30598
30665
|
timeout: Math.max(intervalMs, MIN_FETCH_TIMEOUT_MS)
|
|
@@ -30892,7 +30959,7 @@ async function auth() {
|
|
|
30892
30959
|
}
|
|
30893
30960
|
|
|
30894
30961
|
// src/commands/roam/postRoamActivity.ts
|
|
30895
|
-
import { execFileSync as
|
|
30962
|
+
import { execFileSync as execFileSync15 } from "child_process";
|
|
30896
30963
|
import { readdirSync as readdirSync20, readFileSync as readFileSync52, statSync as statSync11 } from "fs";
|
|
30897
30964
|
import { join as join85 } from "path";
|
|
30898
30965
|
function findPortFile(roamDir) {
|
|
@@ -30925,7 +30992,7 @@ function postRoamActivity(app, event) {
|
|
|
30925
30992
|
}
|
|
30926
30993
|
const url = `http://127.0.0.1:${port}/api/v1/activity/${app}/${event}?pid=${app === "codex" ? 99998 : 99999}`;
|
|
30927
30994
|
try {
|
|
30928
|
-
|
|
30995
|
+
execFileSync15("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
|
|
30929
30996
|
stdio: "ignore"
|
|
30930
30997
|
});
|
|
30931
30998
|
} catch {
|
|
@@ -31401,11 +31468,11 @@ function screenshot(processName) {
|
|
|
31401
31468
|
}
|
|
31402
31469
|
|
|
31403
31470
|
// src/commands/sessions/daemon/listDaemonPids.ts
|
|
31404
|
-
import { execFileSync as
|
|
31471
|
+
import { execFileSync as execFileSync16 } from "child_process";
|
|
31405
31472
|
function listDaemonPids() {
|
|
31406
31473
|
if (process.platform === "win32") return [];
|
|
31407
31474
|
try {
|
|
31408
|
-
const out =
|
|
31475
|
+
const out = execFileSync16("ps", ["-eo", "pid=,args="], {
|
|
31409
31476
|
encoding: "utf8"
|
|
31410
31477
|
});
|
|
31411
31478
|
return out.split("\n").filter((line) => line.includes("assist") && / daemon run\b/.test(line)).map((line) => Number.parseInt(line.trim(), 10)).filter((pid) => Number.isInteger(pid));
|
|
@@ -31450,17 +31517,9 @@ function applyLine(result, pending, line) {
|
|
|
31450
31517
|
}
|
|
31451
31518
|
}
|
|
31452
31519
|
|
|
31453
|
-
// src/commands/sessions/daemon/
|
|
31520
|
+
// src/commands/sessions/daemon/readDaemonPidFile.ts
|
|
31454
31521
|
import { readFileSync as readFileSync53 } from "fs";
|
|
31455
|
-
function
|
|
31456
|
-
if (!socketPid) return;
|
|
31457
|
-
const filePid = readPidFile();
|
|
31458
|
-
if (filePid === void 0 || filePid === socketPid) return;
|
|
31459
|
-
console.error(
|
|
31460
|
-
`Warning: daemon.pid records PID ${filePid} but the socket is owned by PID ${socketPid} (stolen socket)`
|
|
31461
|
-
);
|
|
31462
|
-
}
|
|
31463
|
-
function readPidFile() {
|
|
31522
|
+
function readDaemonPidFile() {
|
|
31464
31523
|
try {
|
|
31465
31524
|
const pid = Number.parseInt(
|
|
31466
31525
|
readFileSync53(daemonPaths.pid, "utf8").trim(),
|
|
@@ -31471,6 +31530,24 @@ function readPidFile() {
|
|
|
31471
31530
|
return void 0;
|
|
31472
31531
|
}
|
|
31473
31532
|
}
|
|
31533
|
+
function isPidAlive(pid) {
|
|
31534
|
+
try {
|
|
31535
|
+
process.kill(pid, 0);
|
|
31536
|
+
return true;
|
|
31537
|
+
} catch (error) {
|
|
31538
|
+
return error.code === "EPERM";
|
|
31539
|
+
}
|
|
31540
|
+
}
|
|
31541
|
+
|
|
31542
|
+
// src/commands/sessions/daemon/reportStolenSocket.ts
|
|
31543
|
+
function reportStolenSocket(socketPid) {
|
|
31544
|
+
if (!socketPid) return;
|
|
31545
|
+
const filePid = readDaemonPidFile();
|
|
31546
|
+
if (filePid === void 0 || filePid === socketPid) return;
|
|
31547
|
+
console.error(
|
|
31548
|
+
`Warning: daemon.pid records PID ${filePid} but the socket is owned by PID ${socketPid} (stolen socket)`
|
|
31549
|
+
);
|
|
31550
|
+
}
|
|
31474
31551
|
|
|
31475
31552
|
// src/commands/sessions/daemon/daemonStatus.ts
|
|
31476
31553
|
async function daemonStatus() {
|
|
@@ -31852,7 +31929,7 @@ var ClientHub = class extends Set {
|
|
|
31852
31929
|
};
|
|
31853
31930
|
|
|
31854
31931
|
// src/commands/sessions/daemon/createSession.ts
|
|
31855
|
-
import { randomUUID as
|
|
31932
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
31856
31933
|
|
|
31857
31934
|
// src/commands/sessions/daemon/sessionBase.ts
|
|
31858
31935
|
function sessionBase(id, status3) {
|
|
@@ -32048,7 +32125,7 @@ function spawnRun(opts) {
|
|
|
32048
32125
|
function createSession(id, { prompt, cwd, design, auto, harness, holdPty } = {}) {
|
|
32049
32126
|
if (harness && harness !== "claude")
|
|
32050
32127
|
return createHarnessSession(id, harness, prompt, cwd, holdPty);
|
|
32051
|
-
const claudeSessionId =
|
|
32128
|
+
const claudeSessionId = randomUUID15();
|
|
32052
32129
|
return {
|
|
32053
32130
|
...sessionBase(id, prompt ? "running" : "waiting"),
|
|
32054
32131
|
name: `Session ${id}`,
|
|
@@ -32309,7 +32386,10 @@ function holdFailedDiscard(session, reason4, notify2) {
|
|
|
32309
32386
|
// src/commands/sessions/daemon/killPtyTree.ts
|
|
32310
32387
|
function killPtyTree(pty2) {
|
|
32311
32388
|
if (process.platform === "win32") {
|
|
32312
|
-
|
|
32389
|
+
try {
|
|
32390
|
+
pty2.kill();
|
|
32391
|
+
} catch {
|
|
32392
|
+
}
|
|
32313
32393
|
return;
|
|
32314
32394
|
}
|
|
32315
32395
|
try {
|
|
@@ -32641,7 +32721,8 @@ var PREVIEW_KINDS = [
|
|
|
32641
32721
|
"backlog-item",
|
|
32642
32722
|
"backlog-comment",
|
|
32643
32723
|
"pr-comment",
|
|
32644
|
-
"github-issue"
|
|
32724
|
+
"github-issue",
|
|
32725
|
+
"github-issue-comment"
|
|
32645
32726
|
];
|
|
32646
32727
|
function isPreviewKind(value) {
|
|
32647
32728
|
return PREVIEW_KINDS.includes(value);
|
|
@@ -32651,6 +32732,7 @@ function isPreviewKind(value) {
|
|
|
32651
32732
|
function previewTargetLabel(kind, itemType, prNumber, draft) {
|
|
32652
32733
|
if (kind === "backlog-comment") return "backlog comment";
|
|
32653
32734
|
if (kind === "pr-comment") return "pr comment";
|
|
32735
|
+
if (kind === "github-issue-comment") return "github issue comment";
|
|
32654
32736
|
if (kind === "github-issue") return "github issue";
|
|
32655
32737
|
if (kind === "backlog-item") return `backlog ${itemType}`;
|
|
32656
32738
|
if (prNumber !== null) return `edit #${prNumber}`;
|
|
@@ -34111,7 +34193,7 @@ function codexRespawnPlan(session) {
|
|
|
34111
34193
|
}
|
|
34112
34194
|
|
|
34113
34195
|
// src/commands/sessions/daemon/interactiveRespawnPlan.ts
|
|
34114
|
-
import { randomUUID as
|
|
34196
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
34115
34197
|
function interactiveRespawnPlan(session, resumes) {
|
|
34116
34198
|
const { claudeSessionId, cwd, initialPrompt, design, auto } = session;
|
|
34117
34199
|
if (!resumes) return null;
|
|
@@ -34131,7 +34213,7 @@ function interactiveRespawnPlan(session, resumes) {
|
|
|
34131
34213
|
return null;
|
|
34132
34214
|
}
|
|
34133
34215
|
function freshClaudePlan(session, prompt, cwd) {
|
|
34134
|
-
const claudeSessionId =
|
|
34216
|
+
const claudeSessionId = randomUUID16();
|
|
34135
34217
|
return {
|
|
34136
34218
|
spawn: () => {
|
|
34137
34219
|
session.claudeSessionId = claudeSessionId;
|
|
@@ -35016,10 +35098,10 @@ function startReusedRunPty(session, assistArgs, itemId2, hold, clients, onStatus
|
|
|
35016
35098
|
}
|
|
35017
35099
|
|
|
35018
35100
|
// src/commands/sessions/daemon/createWatcherSession.ts
|
|
35019
|
-
import { randomUUID as
|
|
35101
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
35020
35102
|
var WATCH_PROMPT = "/watch";
|
|
35021
35103
|
function createWatcherSession(id, cwd) {
|
|
35022
|
-
const claudeSessionId =
|
|
35104
|
+
const claudeSessionId = randomUUID17();
|
|
35023
35105
|
return {
|
|
35024
35106
|
...sessionBase(id, "running"),
|
|
35025
35107
|
name: `Session ${id}`,
|
|
@@ -35208,9 +35290,23 @@ function reuseSessionForRun(session, itemId2, clients, onStatusChange, tree) {
|
|
|
35208
35290
|
// src/commands/sessions/daemon/shutdownSessions.ts
|
|
35209
35291
|
function shutdownSessions(sessions) {
|
|
35210
35292
|
daemonLog(`shutting down: killing ${sessions.size} session(s)`);
|
|
35293
|
+
let failures = 0;
|
|
35211
35294
|
for (const session of sessions.values()) {
|
|
35212
|
-
if (session.status
|
|
35295
|
+
if (session.status === "done") continue;
|
|
35296
|
+
try {
|
|
35297
|
+
session.pty?.kill();
|
|
35298
|
+
} catch (error) {
|
|
35299
|
+
failures++;
|
|
35300
|
+
const reason4 = error instanceof Error ? error.message : String(error);
|
|
35301
|
+
daemonLog(
|
|
35302
|
+
`shutting down: killing session ${session.name} (${session.id}) failed: ${reason4}`
|
|
35303
|
+
);
|
|
35304
|
+
}
|
|
35213
35305
|
}
|
|
35306
|
+
if (failures > 0)
|
|
35307
|
+
daemonLog(
|
|
35308
|
+
`shutting down: ${failures} session(s) failed to die; continuing so the process still exits and releases its listeners`
|
|
35309
|
+
);
|
|
35214
35310
|
}
|
|
35215
35311
|
|
|
35216
35312
|
// src/commands/sessions/daemon/heldStartBlocked.ts
|
|
@@ -36711,8 +36807,13 @@ function handleFetchTranscript(client, _manager, data) {
|
|
|
36711
36807
|
);
|
|
36712
36808
|
}
|
|
36713
36809
|
async function handleShutdown(client, manager) {
|
|
36714
|
-
|
|
36715
|
-
|
|
36810
|
+
try {
|
|
36811
|
+
await manager.flushActiveMs();
|
|
36812
|
+
manager.shutdown();
|
|
36813
|
+
} catch (error) {
|
|
36814
|
+
const reason4 = error instanceof Error ? error.message : String(error);
|
|
36815
|
+
daemonLog(`shutdown teardown failed: ${reason4}; exiting anyway`);
|
|
36816
|
+
}
|
|
36716
36817
|
sendTo(client, { type: "shutting-down" });
|
|
36717
36818
|
setImmediate(() => process.exit(0));
|
|
36718
36819
|
}
|
|
@@ -36903,7 +37004,12 @@ function onListening(manager, checkAutoExit) {
|
|
|
36903
37004
|
startPidFileWatchdog(() => {
|
|
36904
37005
|
daemonLog("lost daemon.pid ownership; shutting down sessions and exiting");
|
|
36905
37006
|
void manager.flushActiveMs().finally(() => {
|
|
36906
|
-
|
|
37007
|
+
try {
|
|
37008
|
+
manager.shutdown();
|
|
37009
|
+
} catch (error) {
|
|
37010
|
+
const reason4 = error instanceof Error ? error.message : String(error);
|
|
37011
|
+
daemonLog(`shutdown teardown failed: ${reason4}; exiting anyway`);
|
|
37012
|
+
}
|
|
36907
37013
|
process.exit(0);
|
|
36908
37014
|
});
|
|
36909
37015
|
});
|
|
@@ -36933,6 +37039,45 @@ function cleanupOwnedFiles() {
|
|
|
36933
37039
|
|
|
36934
37040
|
// src/commands/sessions/daemon/startWindowsBridge.ts
|
|
36935
37041
|
import * as net3 from "net";
|
|
37042
|
+
|
|
37043
|
+
// src/commands/sessions/daemon/findPortHolderPid.ts
|
|
37044
|
+
import { execFileSync as execFileSync17 } from "child_process";
|
|
37045
|
+
var PROBE_TIMEOUT_MS = 3e3;
|
|
37046
|
+
function findPortHolderPid(port) {
|
|
37047
|
+
try {
|
|
37048
|
+
return process.platform === "win32" ? netstatListenerPid(probe("netstat", ["-ano"]), port) : firstPid(probe("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-t"]));
|
|
37049
|
+
} catch {
|
|
37050
|
+
return void 0;
|
|
37051
|
+
}
|
|
37052
|
+
}
|
|
37053
|
+
function probe(command, args) {
|
|
37054
|
+
return execFileSync17(command, args, {
|
|
37055
|
+
encoding: "utf8",
|
|
37056
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
37057
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
37058
|
+
});
|
|
37059
|
+
}
|
|
37060
|
+
function netstatListenerPid(output, port) {
|
|
37061
|
+
const suffix = `:${port}`;
|
|
37062
|
+
for (const line of output.split("\n")) {
|
|
37063
|
+
const [protocol, local, , state, pid] = line.trim().split(/\s+/);
|
|
37064
|
+
if (protocol?.toUpperCase() !== "TCP") continue;
|
|
37065
|
+
if (state?.toUpperCase() !== "LISTENING") continue;
|
|
37066
|
+
if (!local?.endsWith(suffix)) continue;
|
|
37067
|
+
const holder = Number.parseInt(pid ?? "", 10);
|
|
37068
|
+
if (Number.isInteger(holder)) return holder;
|
|
37069
|
+
}
|
|
37070
|
+
return void 0;
|
|
37071
|
+
}
|
|
37072
|
+
function firstPid(output) {
|
|
37073
|
+
for (const line of output.split("\n")) {
|
|
37074
|
+
const pid = Number.parseInt(line.trim(), 10);
|
|
37075
|
+
if (Number.isInteger(pid)) return pid;
|
|
37076
|
+
}
|
|
37077
|
+
return void 0;
|
|
37078
|
+
}
|
|
37079
|
+
|
|
37080
|
+
// src/commands/sessions/daemon/startWindowsBridge.ts
|
|
36936
37081
|
var BIND_ATTEMPTS = 3;
|
|
36937
37082
|
var BIND_RETRY_DELAY_MS = 250;
|
|
36938
37083
|
var KEEPALIVE_PROBE_MS2 = 1e4;
|
|
@@ -36950,10 +37095,14 @@ async function startWindowsBridge(manager) {
|
|
|
36950
37095
|
if (attempt < BIND_ATTEMPTS) await delay3(BIND_RETRY_DELAY_MS);
|
|
36951
37096
|
}
|
|
36952
37097
|
daemonLog(
|
|
36953
|
-
`${WINDOWS_BRIDGE_FAILURE_PREFIX} could not bind port ${port} after ${BIND_ATTEMPTS} attempts;
|
|
37098
|
+
`${WINDOWS_BRIDGE_FAILURE_PREFIX} could not bind port ${port} after ${BIND_ATTEMPTS} attempts; ${describePortHolder(port)}`
|
|
36954
37099
|
);
|
|
36955
37100
|
return false;
|
|
36956
37101
|
}
|
|
37102
|
+
function describePortHolder(port) {
|
|
37103
|
+
const holder = findPortHolderPid(port);
|
|
37104
|
+
return holder !== void 0 && holder !== process.pid ? `PID ${holder} is listening on it \u2014 kill PID ${holder} to free the port` : "the port is held by another process or reserved by a Hyper-V/WSL dynamic port range \u2014 set sessions.windowsDaemonPort to a free port outside 49152-65535";
|
|
37105
|
+
}
|
|
36957
37106
|
function bindBridge(manager, port) {
|
|
36958
37107
|
return new Promise((resolve24) => {
|
|
36959
37108
|
const bridge = net3.createServer((socket) => {
|
|
@@ -36981,6 +37130,14 @@ function delay3(ms) {
|
|
|
36981
37130
|
return new Promise((resolve24) => setTimeout(resolve24, ms));
|
|
36982
37131
|
}
|
|
36983
37132
|
|
|
37133
|
+
// src/commands/sessions/daemon/describeWedgedHolder.ts
|
|
37134
|
+
function describeWedgedHolder() {
|
|
37135
|
+
const recorded = readDaemonPidFile();
|
|
37136
|
+
if (recorded !== void 0 && recorded !== process.pid && isPidAlive(recorded))
|
|
37137
|
+
return `daemon.pid records PID ${recorded}, which is still alive \u2014 kill PID ${recorded} to free the pipe and the windows bridge port`;
|
|
37138
|
+
return "the holding process could not be identified \u2014 look for a stray assist daemon and kill it";
|
|
37139
|
+
}
|
|
37140
|
+
|
|
36984
37141
|
// src/commands/sessions/daemon/startDaemonServer.ts
|
|
36985
37142
|
async function startDaemonServer(manager, checkAutoExit) {
|
|
36986
37143
|
if (process.platform === "win32" && !await startWindowsBridge(manager)) {
|
|
@@ -37013,12 +37170,17 @@ async function recoverFromAddrInUse(server, manager, checkAutoExit) {
|
|
|
37013
37170
|
daemonLog("another daemon owns the socket; exiting");
|
|
37014
37171
|
process.exit(1);
|
|
37015
37172
|
}
|
|
37173
|
+
if (process.platform === "win32") {
|
|
37174
|
+
daemonLog(
|
|
37175
|
+
`${daemonPaths.socket} is bound but not answering: ${describeWedgedHolder()}; a named pipe cannot be removed, so exiting instead of retrying the bind`
|
|
37176
|
+
);
|
|
37177
|
+
exitAfterFlush(1);
|
|
37178
|
+
return;
|
|
37179
|
+
}
|
|
37016
37180
|
daemonLog("removing stale socket left by a crashed daemon");
|
|
37017
|
-
|
|
37018
|
-
|
|
37019
|
-
|
|
37020
|
-
} catch {
|
|
37021
|
-
}
|
|
37181
|
+
try {
|
|
37182
|
+
unlinkSync24(daemonPaths.socket);
|
|
37183
|
+
} catch {
|
|
37022
37184
|
}
|
|
37023
37185
|
listenWithSingleOnListening(server, manager, checkAutoExit);
|
|
37024
37186
|
}
|
|
@@ -37096,7 +37258,7 @@ function summaryPathFor(jsonlPath2) {
|
|
|
37096
37258
|
}
|
|
37097
37259
|
|
|
37098
37260
|
// src/commands/sessions/summarise/summariseSession.ts
|
|
37099
|
-
import { execFileSync as
|
|
37261
|
+
import { execFileSync as execFileSync18 } from "child_process";
|
|
37100
37262
|
function summariseSession(jsonlPath2) {
|
|
37101
37263
|
const firstMessage = extractFirstUserMessage(jsonlPath2);
|
|
37102
37264
|
const backlogIds = scanSessionBacklogRefs(jsonlPath2);
|
|
@@ -37105,7 +37267,7 @@ function summariseSession(jsonlPath2) {
|
|
|
37105
37267
|
}
|
|
37106
37268
|
const prompt = buildPrompt6(firstMessage, backlogIds);
|
|
37107
37269
|
try {
|
|
37108
|
-
const output =
|
|
37270
|
+
const output = execFileSync18("claude", ["-p", "--model", "haiku", prompt], {
|
|
37109
37271
|
encoding: "utf8",
|
|
37110
37272
|
timeout: 3e4,
|
|
37111
37273
|
stdio: ["ignore", "pipe", "ignore"]
|