@staff0rd/assist 0.615.3 → 0.616.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 +2 -1
- package/dist/commands/sessions/web/bundle.js +287 -287
- package/dist/index.js +201 -84
- 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.616.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -16541,6 +16541,84 @@ function stripEnvPrefix(parts) {
|
|
|
16541
16541
|
return i > 0 ? parts.slice(i) : parts;
|
|
16542
16542
|
}
|
|
16543
16543
|
|
|
16544
|
+
// src/shared/extractGhApiMethod.ts
|
|
16545
|
+
function extractGhApiMethod(args) {
|
|
16546
|
+
for (let i = 0; i < args.length; i++) {
|
|
16547
|
+
const arg = args[i];
|
|
16548
|
+
if (arg.startsWith("--method=")) return arg.slice("--method=".length);
|
|
16549
|
+
if (arg.startsWith("-X=")) return arg.slice("-X=".length);
|
|
16550
|
+
if (arg.startsWith("-X") && arg.length > 2) return arg.slice(2);
|
|
16551
|
+
if ((arg === "--method" || arg === "-X") && i + 1 < args.length) {
|
|
16552
|
+
return args[i + 1];
|
|
16553
|
+
}
|
|
16554
|
+
}
|
|
16555
|
+
return void 0;
|
|
16556
|
+
}
|
|
16557
|
+
|
|
16558
|
+
// src/shared/tokenize.ts
|
|
16559
|
+
function tokenize(command) {
|
|
16560
|
+
const tokens = [];
|
|
16561
|
+
let current = "";
|
|
16562
|
+
let inSingle = false;
|
|
16563
|
+
let inDouble = false;
|
|
16564
|
+
for (let i = 0; i < command.length; i++) {
|
|
16565
|
+
const ch = command[i];
|
|
16566
|
+
if (ch === "'" && !inDouble) {
|
|
16567
|
+
inSingle = !inSingle;
|
|
16568
|
+
current += ch;
|
|
16569
|
+
} else if (ch === '"' && !inSingle) {
|
|
16570
|
+
inDouble = !inDouble;
|
|
16571
|
+
current += ch;
|
|
16572
|
+
} else if (ch === "\\" && inDouble && i + 1 < command.length) {
|
|
16573
|
+
current += ch + command[++i];
|
|
16574
|
+
} else if (/\s/.test(ch) && !inSingle && !inDouble) {
|
|
16575
|
+
if (current) {
|
|
16576
|
+
tokens.push(current);
|
|
16577
|
+
current = "";
|
|
16578
|
+
}
|
|
16579
|
+
} else {
|
|
16580
|
+
current += ch;
|
|
16581
|
+
}
|
|
16582
|
+
}
|
|
16583
|
+
if (current) tokens.push(current);
|
|
16584
|
+
return tokens;
|
|
16585
|
+
}
|
|
16586
|
+
|
|
16587
|
+
// src/commands/cliHook/isGhIssueApiWrite.ts
|
|
16588
|
+
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PATCH", "PUT", "DELETE"]);
|
|
16589
|
+
var BODY_FLAGS = ["-f", "-F", "--field", "--raw-field", "--input"];
|
|
16590
|
+
var COMMAND_OPERATORS = /* @__PURE__ */ new Set(["&&", "||", ";", "|", "&"]);
|
|
16591
|
+
var ISSUE_ENDPOINT = /(?:^|[/"'`])repos\/[^/\s"'`]+\/[^/\s"'`]+\/issues(?:$|[/?"'`])/;
|
|
16592
|
+
function isGhIssueApiWrite(command) {
|
|
16593
|
+
const tokens = tokenize(command);
|
|
16594
|
+
for (let i = 0; i + 1 < tokens.length; i++) {
|
|
16595
|
+
if (tokens[i] !== "gh" || tokens[i + 1] !== "api") continue;
|
|
16596
|
+
const args = argsUntilNextCommand(tokens.slice(i + 2));
|
|
16597
|
+
if (targetsIssueEndpoint(args) && isWrite(args)) return true;
|
|
16598
|
+
}
|
|
16599
|
+
return false;
|
|
16600
|
+
}
|
|
16601
|
+
function argsUntilNextCommand(tokens) {
|
|
16602
|
+
const end = tokens.findIndex((token) => COMMAND_OPERATORS.has(token));
|
|
16603
|
+
return end === -1 ? tokens : tokens.slice(0, end);
|
|
16604
|
+
}
|
|
16605
|
+
function targetsIssueEndpoint(args) {
|
|
16606
|
+
return args.some((arg) => ISSUE_ENDPOINT.test(arg));
|
|
16607
|
+
}
|
|
16608
|
+
function isWrite(args) {
|
|
16609
|
+
const method = extractGhApiMethod(args);
|
|
16610
|
+
if (method) return WRITE_METHODS.has(unquote(method).toUpperCase());
|
|
16611
|
+
return args.some(isBodyFlag);
|
|
16612
|
+
}
|
|
16613
|
+
function isBodyFlag(arg) {
|
|
16614
|
+
return BODY_FLAGS.some(
|
|
16615
|
+
(flag) => arg === flag || arg.startsWith(`${flag}=`) || flag.length === 2 && arg.length > 2 && arg.startsWith(flag)
|
|
16616
|
+
);
|
|
16617
|
+
}
|
|
16618
|
+
function unquote(value) {
|
|
16619
|
+
return value.replace(/^['"]|['"]$/g, "");
|
|
16620
|
+
}
|
|
16621
|
+
|
|
16544
16622
|
// src/commands/cliHook/findBuiltinDeny.ts
|
|
16545
16623
|
var BUILTIN_DENIES = [
|
|
16546
16624
|
{
|
|
@@ -16555,6 +16633,10 @@ var BUILTIN_DENIES = [
|
|
|
16555
16633
|
pattern: "gh issue create",
|
|
16556
16634
|
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."
|
|
16557
16635
|
},
|
|
16636
|
+
{
|
|
16637
|
+
pattern: "gh issue edit",
|
|
16638
|
+
message: "Do not run 'gh issue edit' directly. Use 'assist github issue edit <number> [-R <owner>/<repo>]' instead \u2014 it fetches the issue's current body, opens it in the assist web preview pane, and pushes nothing back until the user approves it. Run 'assist github issue edit --help' for how the working file and the preview pane fit together; it is authoritative on how approval is handled in this environment."
|
|
16639
|
+
},
|
|
16558
16640
|
{
|
|
16559
16641
|
pattern: "gh issue comment",
|
|
16560
16642
|
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."
|
|
@@ -16564,6 +16646,7 @@ var BUILTIN_DENIES = [
|
|
|
16564
16646
|
message: `Do not run 'git commit' directly. Use 'assist commit "<message>"' instead.`
|
|
16565
16647
|
}
|
|
16566
16648
|
];
|
|
16649
|
+
var GH_ISSUE_API_MESSAGE = "Do not write to GitHub issue endpoints with 'gh api' \u2014 it bypasses the content validation and the approval pane that every outward-facing issue write goes through. Use 'assist github issue create --title <title> --body <body>' to open an issue, 'assist github issue edit <number>' to rework one's body, 'assist github issue comment <number> --body <body>' to post a comment, or 'assist github issue edit-comment <comment-id> --body <body>' to amend a comment that is already posted. Each validates the content and gates it on the user's approval before anything reaches GitHub; run the command's --help for how to compose it.";
|
|
16567
16650
|
var BRANCH_CREATION_MESSAGE = "Do not create branches with raw git. Use the /branch command, or 'assist branch <slug> [--jira <KEY>]' \u2014 it branches off the fresh remote default and enforces the team naming convention.";
|
|
16568
16651
|
var COMMAND_BOUNDARY = String.raw`(?<=(?:^|[;&|(\n])\s*)`;
|
|
16569
16652
|
var BRANCH_CREATION_REGEXES = [
|
|
@@ -16580,17 +16663,24 @@ function rawDenyRegex(pattern2) {
|
|
|
16580
16663
|
return new RegExp(`(?<=^|\\s)${tokens}(?=\\s|$)`);
|
|
16581
16664
|
}
|
|
16582
16665
|
var RAW_BUILTIN_DENIES = [
|
|
16583
|
-
...BUILTIN_DENIES.map((rule) =>
|
|
16584
|
-
|
|
16585
|
-
|
|
16586
|
-
|
|
16666
|
+
...BUILTIN_DENIES.map((rule) => {
|
|
16667
|
+
const regex = rawDenyRegex(rule.pattern);
|
|
16668
|
+
return {
|
|
16669
|
+
message: rule.message,
|
|
16670
|
+
matches: (text18) => regex.test(text18)
|
|
16671
|
+
};
|
|
16672
|
+
}),
|
|
16587
16673
|
...BRANCH_CREATION_REGEXES.map((regex) => ({
|
|
16588
16674
|
message: BRANCH_CREATION_MESSAGE,
|
|
16589
|
-
regex
|
|
16590
|
-
}))
|
|
16675
|
+
matches: (text18) => regex.test(text18)
|
|
16676
|
+
})),
|
|
16677
|
+
{
|
|
16678
|
+
message: GH_ISSUE_API_MESSAGE,
|
|
16679
|
+
matches: isGhIssueApiWrite
|
|
16680
|
+
}
|
|
16591
16681
|
];
|
|
16592
16682
|
function matchBuiltinDeny(text18) {
|
|
16593
|
-
return RAW_BUILTIN_DENIES.find((rule) => rule.
|
|
16683
|
+
return RAW_BUILTIN_DENIES.find((rule) => rule.matches(text18));
|
|
16594
16684
|
}
|
|
16595
16685
|
function toDecision(rule) {
|
|
16596
16686
|
if (!rule) return void 0;
|
|
@@ -16619,38 +16709,9 @@ function appliesFixStructure(command) {
|
|
|
16619
16709
|
return APPLY_RE.test(command);
|
|
16620
16710
|
}
|
|
16621
16711
|
|
|
16622
|
-
// src/shared/tokenize.ts
|
|
16623
|
-
function tokenize(command) {
|
|
16624
|
-
const tokens = [];
|
|
16625
|
-
let current = "";
|
|
16626
|
-
let inSingle = false;
|
|
16627
|
-
let inDouble = false;
|
|
16628
|
-
for (let i = 0; i < command.length; i++) {
|
|
16629
|
-
const ch = command[i];
|
|
16630
|
-
if (ch === "'" && !inDouble) {
|
|
16631
|
-
inSingle = !inSingle;
|
|
16632
|
-
current += ch;
|
|
16633
|
-
} else if (ch === '"' && !inSingle) {
|
|
16634
|
-
inDouble = !inDouble;
|
|
16635
|
-
current += ch;
|
|
16636
|
-
} else if (ch === "\\" && inDouble && i + 1 < command.length) {
|
|
16637
|
-
current += ch + command[++i];
|
|
16638
|
-
} else if (/\s/.test(ch) && !inSingle && !inDouble) {
|
|
16639
|
-
if (current) {
|
|
16640
|
-
tokens.push(current);
|
|
16641
|
-
current = "";
|
|
16642
|
-
}
|
|
16643
|
-
} else {
|
|
16644
|
-
current += ch;
|
|
16645
|
-
}
|
|
16646
|
-
}
|
|
16647
|
-
if (current) tokens.push(current);
|
|
16648
|
-
return tokens;
|
|
16649
|
-
}
|
|
16650
|
-
|
|
16651
16712
|
// src/shared/isGhApiRead.ts
|
|
16652
16713
|
var READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
|
|
16653
|
-
var
|
|
16714
|
+
var BODY_FLAGS2 = /* @__PURE__ */ new Set(["-f", "-F", "--field", "--raw-field", "--input"]);
|
|
16654
16715
|
var FIELD_FLAGS = /* @__PURE__ */ new Set(["-f", "--field", "-F"]);
|
|
16655
16716
|
function isGhApiRead(command) {
|
|
16656
16717
|
const tokens = tokenize(command);
|
|
@@ -16661,24 +16722,13 @@ function isGhApiRead(command) {
|
|
|
16661
16722
|
if (args.includes("graphql")) {
|
|
16662
16723
|
return isGraphqlRead(args);
|
|
16663
16724
|
}
|
|
16664
|
-
const method =
|
|
16725
|
+
const method = extractGhApiMethod(args);
|
|
16665
16726
|
if (method) return READ_METHODS.has(method.toUpperCase());
|
|
16666
|
-
if (args.some((t) =>
|
|
16727
|
+
if (args.some((t) => BODY_FLAGS2.has(t))) return false;
|
|
16667
16728
|
return true;
|
|
16668
16729
|
}
|
|
16669
|
-
function extractMethod(args) {
|
|
16670
|
-
for (let i = 0; i < args.length; i++) {
|
|
16671
|
-
const arg = args[i];
|
|
16672
|
-
if (arg.startsWith("--method=")) return arg.slice("--method=".length);
|
|
16673
|
-
if (arg.startsWith("-X=")) return arg.slice("-X=".length);
|
|
16674
|
-
if ((arg === "--method" || arg === "-X") && i + 1 < args.length) {
|
|
16675
|
-
return args[i + 1];
|
|
16676
|
-
}
|
|
16677
|
-
}
|
|
16678
|
-
return void 0;
|
|
16679
|
-
}
|
|
16680
16730
|
function isGraphqlRead(args) {
|
|
16681
|
-
const method =
|
|
16731
|
+
const method = extractGhApiMethod(args);
|
|
16682
16732
|
if (method) return READ_METHODS.has(method.toUpperCase());
|
|
16683
16733
|
const queryBody = extractGraphqlQuery(args);
|
|
16684
16734
|
if (!queryBody) return false;
|
|
@@ -22514,12 +22564,79 @@ function registerEditIssue(issueCommand) {
|
|
|
22514
22564
|
).action(editIssue);
|
|
22515
22565
|
}
|
|
22516
22566
|
|
|
22567
|
+
// src/commands/github/issue/editIssueComment.ts
|
|
22568
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
22569
|
+
var USAGE4 = "Usage: assist github issue edit-comment <comment-id> --body <body> [-R <owner>/<repo>]";
|
|
22570
|
+
async function editIssueComment(commentIdArg, options2) {
|
|
22571
|
+
const commentId = Number.parseInt(commentIdArg, 10);
|
|
22572
|
+
if (!Number.isInteger(commentId) || commentId <= 0 || !options2.body) {
|
|
22573
|
+
console.error(USAGE4);
|
|
22574
|
+
process.exit(1);
|
|
22575
|
+
}
|
|
22576
|
+
const { body } = options2;
|
|
22577
|
+
const { owner, repo } = resolveIssueRepoTarget(options2.repo);
|
|
22578
|
+
const target = `${owner}/${repo} comment ${commentId}`;
|
|
22579
|
+
validateProposedContent(
|
|
22580
|
+
{ subject: "Comment", context: "GitHub issues" },
|
|
22581
|
+
"",
|
|
22582
|
+
body
|
|
22583
|
+
);
|
|
22584
|
+
await reviewProposedIssueComment(`Amend ${target}`, body);
|
|
22585
|
+
const args = [
|
|
22586
|
+
"api",
|
|
22587
|
+
"-X",
|
|
22588
|
+
"PATCH",
|
|
22589
|
+
`repos/${owner}/${repo}/issues/comments/${commentId}`,
|
|
22590
|
+
"--input",
|
|
22591
|
+
"-"
|
|
22592
|
+
];
|
|
22593
|
+
let raw;
|
|
22594
|
+
try {
|
|
22595
|
+
raw = execFileSync11("gh", args, {
|
|
22596
|
+
input: JSON.stringify({ body }),
|
|
22597
|
+
encoding: "utf8"
|
|
22598
|
+
});
|
|
22599
|
+
} catch {
|
|
22600
|
+
process.exit(1);
|
|
22601
|
+
}
|
|
22602
|
+
console.log(`Comment updated: ${commentUrl(raw) ?? target}`);
|
|
22603
|
+
}
|
|
22604
|
+
function commentUrl(raw) {
|
|
22605
|
+
try {
|
|
22606
|
+
const parsed = JSON.parse(raw);
|
|
22607
|
+
return parsed.html_url;
|
|
22608
|
+
} catch {
|
|
22609
|
+
return void 0;
|
|
22610
|
+
}
|
|
22611
|
+
}
|
|
22612
|
+
|
|
22613
|
+
// src/commands/github/issue/registerEditIssueComment.ts
|
|
22614
|
+
function registerEditIssueComment(issueCommand) {
|
|
22615
|
+
issueCommand.command("edit-comment <comment-id>").description(
|
|
22616
|
+
"Replace the body of a posted GitHub issue comment (body of - reads it from stdin)"
|
|
22617
|
+
).option("--body <body>", "Replacement comment body (- reads it from stdin)").option(
|
|
22618
|
+
"-R, --repo <owner/repo>",
|
|
22619
|
+
"Target repository (defaults to the current repo)"
|
|
22620
|
+
).addHelpText(
|
|
22621
|
+
"after",
|
|
22622
|
+
"\nThe comment id is the numeric id from the comment's API url or the #issuecomment-<id> anchor on github.com, not the issue number.\nThe replacement 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 replacement is previewed for approve/reject first (with inline comments); the published comment is left alone until it is approved. The replacement is the whole body \u2014 what is there now is overwritten, so fetch it first if it should be built on."
|
|
22623
|
+
).action(
|
|
22624
|
+
async (commentId, options2) => {
|
|
22625
|
+
await editIssueComment(commentId, {
|
|
22626
|
+
...options2,
|
|
22627
|
+
body: options2.body ? await readBodyArgument(options2.body) : void 0
|
|
22628
|
+
});
|
|
22629
|
+
}
|
|
22630
|
+
);
|
|
22631
|
+
}
|
|
22632
|
+
|
|
22517
22633
|
// src/commands/registerGithubIssue.ts
|
|
22518
22634
|
function registerGithubIssue(githubCommand) {
|
|
22519
22635
|
const issueCommand = githubCommand.command("issue").description("GitHub issue utilities");
|
|
22520
22636
|
registerCreateIssue(issueCommand);
|
|
22521
22637
|
registerEditIssue(issueCommand);
|
|
22522
22638
|
registerCommentIssue(issueCommand);
|
|
22639
|
+
registerEditIssueComment(issueCommand);
|
|
22523
22640
|
registerFixStructure(issueCommand);
|
|
22524
22641
|
}
|
|
22525
22642
|
|
|
@@ -22948,7 +23065,7 @@ function registerRefineLaunch(program2, resumeFlag) {
|
|
|
22948
23065
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
22949
23066
|
|
|
22950
23067
|
// src/commands/review/checkoutPr.ts
|
|
22951
|
-
import { execFileSync as
|
|
23068
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
22952
23069
|
import chalk170 from "chalk";
|
|
22953
23070
|
|
|
22954
23071
|
// src/commands/sessions/daemon/daemonLog.ts
|
|
@@ -23508,10 +23625,10 @@ async function moveToPrCheckoutTree() {
|
|
|
23508
23625
|
}
|
|
23509
23626
|
|
|
23510
23627
|
// src/commands/review/prHeadBranch.ts
|
|
23511
|
-
import { execFileSync as
|
|
23628
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
23512
23629
|
function prHeadBranch(number) {
|
|
23513
23630
|
try {
|
|
23514
|
-
const out =
|
|
23631
|
+
const out = execFileSync12(
|
|
23515
23632
|
"gh",
|
|
23516
23633
|
["pr", "view", number, "--json", "headRefName", "-q", ".headRefName"],
|
|
23517
23634
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -23559,7 +23676,7 @@ async function checkoutPr(number) {
|
|
|
23559
23676
|
if (headRef && moveToExistingCheckout(number, headRef)) return;
|
|
23560
23677
|
await moveToPrCheckoutTree();
|
|
23561
23678
|
try {
|
|
23562
|
-
|
|
23679
|
+
execFileSync13("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
23563
23680
|
} catch {
|
|
23564
23681
|
console.error(chalk170.red(`gh pr checkout ${number} failed; aborting.`));
|
|
23565
23682
|
process.exit(1);
|
|
@@ -25221,13 +25338,13 @@ async function comment2(path90, line, body, startLine) {
|
|
|
25221
25338
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
25222
25339
|
|
|
25223
25340
|
// src/commands/prs/applyEdit.ts
|
|
25224
|
-
import { execFileSync as
|
|
25341
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
25225
25342
|
function applyEdit(number, title, body) {
|
|
25226
25343
|
const args = ["pr", "edit", String(number)];
|
|
25227
25344
|
if (title) args.push("--title", title);
|
|
25228
25345
|
args.push("--body", body);
|
|
25229
25346
|
try {
|
|
25230
|
-
|
|
25347
|
+
execFileSync14("gh", args, { stdio: "inherit" });
|
|
25231
25348
|
} catch {
|
|
25232
25349
|
process.exit(1);
|
|
25233
25350
|
}
|
|
@@ -26023,7 +26140,7 @@ function buildValidatedBody(options2, usage) {
|
|
|
26023
26140
|
}
|
|
26024
26141
|
|
|
26025
26142
|
// src/commands/prs/placePr.ts
|
|
26026
|
-
import { execFileSync as
|
|
26143
|
+
import { execFileSync as execFileSync15 } from "child_process";
|
|
26027
26144
|
|
|
26028
26145
|
// src/commands/prs/buildCreateArgs.ts
|
|
26029
26146
|
function buildEditArgs(number, title, body) {
|
|
@@ -26090,7 +26207,7 @@ async function recordPrActivity() {
|
|
|
26090
26207
|
// src/commands/prs/placePr.ts
|
|
26091
26208
|
function hasUpstream2() {
|
|
26092
26209
|
try {
|
|
26093
|
-
|
|
26210
|
+
execFileSync15(
|
|
26094
26211
|
"git",
|
|
26095
26212
|
["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"],
|
|
26096
26213
|
{ stdio: "pipe" }
|
|
@@ -26102,13 +26219,13 @@ function hasUpstream2() {
|
|
|
26102
26219
|
}
|
|
26103
26220
|
function ensureBranchPushed() {
|
|
26104
26221
|
const args = hasUpstream2() ? ["push"] : ["push", "--set-upstream", "origin", "HEAD"];
|
|
26105
|
-
|
|
26222
|
+
execFileSync15("git", args, { stdio: "inherit" });
|
|
26106
26223
|
}
|
|
26107
26224
|
async function placePr(prNumber, title, body, options2) {
|
|
26108
26225
|
const args = prNumber !== null ? buildEditArgs(prNumber, title, body) : buildCreateArgs(title, body, options2);
|
|
26109
26226
|
try {
|
|
26110
26227
|
if (prNumber === null && !options2.head) ensureBranchPushed();
|
|
26111
|
-
|
|
26228
|
+
execFileSync15("gh", args, { stdio: "inherit" });
|
|
26112
26229
|
} catch {
|
|
26113
26230
|
process.exit(1);
|
|
26114
26231
|
}
|
|
@@ -26271,9 +26388,9 @@ function resolveDraftState(options2, command) {
|
|
|
26271
26388
|
}
|
|
26272
26389
|
|
|
26273
26390
|
// src/commands/prs/raise.ts
|
|
26274
|
-
var
|
|
26391
|
+
var USAGE5 = "Usage: assist prs raise --title <title> --what <what> --why <why> [--how <how>] [--resolves <key>] [--force]";
|
|
26275
26392
|
async function raise(options2, command) {
|
|
26276
|
-
const { title, body } = buildValidatedBody(options2,
|
|
26393
|
+
const { title, body } = buildValidatedBody(options2, USAGE5);
|
|
26277
26394
|
const resolved = { ...options2, draft: resolveDraftState(options2, command) };
|
|
26278
26395
|
const existing = findCurrentPrNumber();
|
|
26279
26396
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
@@ -31265,7 +31382,7 @@ function slackWorkingFile(channel) {
|
|
|
31265
31382
|
}
|
|
31266
31383
|
|
|
31267
31384
|
// src/commands/slack/postSlackMessage.ts
|
|
31268
|
-
var
|
|
31385
|
+
var USAGE6 = "Usage: assist slack post [channel] --body <body|->";
|
|
31269
31386
|
async function postSlackMessage(channelArg, options2) {
|
|
31270
31387
|
const channel = (channelArg ?? loadConfig().slack?.channel ?? "").trim();
|
|
31271
31388
|
const body = options2.body?.trim();
|
|
@@ -31273,11 +31390,11 @@ async function postSlackMessage(channelArg, options2) {
|
|
|
31273
31390
|
console.error(
|
|
31274
31391
|
'No channel given and slack.channel is not set. Pass one, or set a default with: assist config set slack.channel "#general"'
|
|
31275
31392
|
);
|
|
31276
|
-
console.error(
|
|
31393
|
+
console.error(USAGE6);
|
|
31277
31394
|
process.exit(1);
|
|
31278
31395
|
}
|
|
31279
31396
|
if (!body) {
|
|
31280
|
-
console.error(
|
|
31397
|
+
console.error(USAGE6);
|
|
31281
31398
|
process.exit(1);
|
|
31282
31399
|
}
|
|
31283
31400
|
const threadTs = options2.thread;
|
|
@@ -31874,7 +31991,7 @@ function syncPiHooks(sourceDir) {
|
|
|
31874
31991
|
}
|
|
31875
31992
|
|
|
31876
31993
|
// src/commands/sync/syncPi.ts
|
|
31877
|
-
function
|
|
31994
|
+
function unquote2(value) {
|
|
31878
31995
|
return value.trim().replace(/^["']|["']$/g, "");
|
|
31879
31996
|
}
|
|
31880
31997
|
function commandToPrompt(name, content) {
|
|
@@ -31882,9 +31999,9 @@ function commandToPrompt(name, content) {
|
|
|
31882
31999
|
const frontmatter = match ? match[1] : "";
|
|
31883
32000
|
const body = match ? content.slice(match[0].length) : content;
|
|
31884
32001
|
const descriptionMatch = frontmatter.match(/^description:\s*(.*)$/m);
|
|
31885
|
-
const description = descriptionMatch ?
|
|
32002
|
+
const description = descriptionMatch ? unquote2(descriptionMatch[1]) : name;
|
|
31886
32003
|
const argsMatch = frontmatter.match(/^allowed_args:\s*(.*)$/m);
|
|
31887
|
-
const argumentHint = argsMatch ?
|
|
32004
|
+
const argumentHint = argsMatch ? unquote2(argsMatch[1]) : void 0;
|
|
31888
32005
|
const header = [
|
|
31889
32006
|
"---",
|
|
31890
32007
|
`description: ${description}`,
|
|
@@ -32738,9 +32855,9 @@ function registerVoice(program2) {
|
|
|
32738
32855
|
}
|
|
32739
32856
|
|
|
32740
32857
|
// src/commands/watch/resolveUpstream.ts
|
|
32741
|
-
import { execFileSync as
|
|
32858
|
+
import { execFileSync as execFileSync16 } from "child_process";
|
|
32742
32859
|
function runGit3(args, cwd) {
|
|
32743
|
-
return
|
|
32860
|
+
return execFileSync16("git", args, {
|
|
32744
32861
|
encoding: "utf8",
|
|
32745
32862
|
stdio: ["pipe", "pipe", "pipe"],
|
|
32746
32863
|
cwd
|
|
@@ -33146,13 +33263,13 @@ import { spawn as spawn9 } from "child_process";
|
|
|
33146
33263
|
import { existsSync as existsSync80 } from "fs";
|
|
33147
33264
|
|
|
33148
33265
|
// src/commands/run/resolveCommand.ts
|
|
33149
|
-
import { execFileSync as
|
|
33266
|
+
import { execFileSync as execFileSync17 } from "child_process";
|
|
33150
33267
|
import { existsSync as existsSync79 } from "fs";
|
|
33151
33268
|
import { dirname as dirname37, join as join92, resolve as resolve20 } from "path";
|
|
33152
33269
|
function resolveCommand2(command) {
|
|
33153
33270
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
33154
33271
|
try {
|
|
33155
|
-
const gitPath =
|
|
33272
|
+
const gitPath = execFileSync17("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
33156
33273
|
const gitRoot = resolve20(dirname37(gitPath), "..");
|
|
33157
33274
|
const gitBash = join92(gitRoot, "bin", "bash.exe");
|
|
33158
33275
|
if (existsSync79(gitBash)) return gitBash;
|
|
@@ -33274,11 +33391,11 @@ async function reportSyncOrExit() {
|
|
|
33274
33391
|
}
|
|
33275
33392
|
|
|
33276
33393
|
// src/commands/watch/fetchQuietly.ts
|
|
33277
|
-
import { execFileSync as
|
|
33394
|
+
import { execFileSync as execFileSync18 } from "child_process";
|
|
33278
33395
|
var MIN_FETCH_TIMEOUT_MS = 6e4;
|
|
33279
33396
|
function fetchQuietly(cwd, intervalMs) {
|
|
33280
33397
|
try {
|
|
33281
|
-
|
|
33398
|
+
execFileSync18("git", ["fetch", "--quiet"], {
|
|
33282
33399
|
stdio: ["pipe", "pipe", "pipe"],
|
|
33283
33400
|
cwd,
|
|
33284
33401
|
timeout: Math.max(intervalMs, MIN_FETCH_TIMEOUT_MS)
|
|
@@ -33580,7 +33697,7 @@ async function auth() {
|
|
|
33580
33697
|
}
|
|
33581
33698
|
|
|
33582
33699
|
// src/commands/roam/postRoamActivity.ts
|
|
33583
|
-
import { execFileSync as
|
|
33700
|
+
import { execFileSync as execFileSync19 } from "child_process";
|
|
33584
33701
|
import { readdirSync as readdirSync21, readFileSync as readFileSync60, statSync as statSync12 } from "fs";
|
|
33585
33702
|
import { join as join93 } from "path";
|
|
33586
33703
|
function findPortFile(roamDir) {
|
|
@@ -33619,7 +33736,7 @@ function postRoamActivity(app, event) {
|
|
|
33619
33736
|
const pid = PID_BY_APP[app] ?? 99999;
|
|
33620
33737
|
const url = `http://127.0.0.1:${port}/api/v1/activity/${app}/${event}?pid=${pid}`;
|
|
33621
33738
|
try {
|
|
33622
|
-
|
|
33739
|
+
execFileSync19("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
|
|
33623
33740
|
stdio: "ignore"
|
|
33624
33741
|
});
|
|
33625
33742
|
} catch {
|
|
@@ -34097,11 +34214,11 @@ function screenshot(processName) {
|
|
|
34097
34214
|
}
|
|
34098
34215
|
|
|
34099
34216
|
// src/commands/sessions/daemon/listDaemonPids.ts
|
|
34100
|
-
import { execFileSync as
|
|
34217
|
+
import { execFileSync as execFileSync20 } from "child_process";
|
|
34101
34218
|
function listDaemonPids() {
|
|
34102
34219
|
if (process.platform === "win32") return [];
|
|
34103
34220
|
try {
|
|
34104
|
-
const out =
|
|
34221
|
+
const out = execFileSync20("ps", ["-eo", "pid=,args="], {
|
|
34105
34222
|
encoding: "utf8"
|
|
34106
34223
|
});
|
|
34107
34224
|
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));
|
|
@@ -39728,7 +39845,7 @@ function cleanupOwnedFiles() {
|
|
|
39728
39845
|
import * as net3 from "net";
|
|
39729
39846
|
|
|
39730
39847
|
// src/commands/sessions/daemon/findPortHolderPid.ts
|
|
39731
|
-
import { execFileSync as
|
|
39848
|
+
import { execFileSync as execFileSync21 } from "child_process";
|
|
39732
39849
|
var PROBE_TIMEOUT_MS = 3e3;
|
|
39733
39850
|
function findPortHolderPid(port) {
|
|
39734
39851
|
try {
|
|
@@ -39738,7 +39855,7 @@ function findPortHolderPid(port) {
|
|
|
39738
39855
|
}
|
|
39739
39856
|
}
|
|
39740
39857
|
function probe(command, args) {
|
|
39741
|
-
return
|
|
39858
|
+
return execFileSync21(command, args, {
|
|
39742
39859
|
encoding: "utf8",
|
|
39743
39860
|
timeout: PROBE_TIMEOUT_MS,
|
|
39744
39861
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -39977,7 +40094,7 @@ function summaryPathFor(jsonlPath2) {
|
|
|
39977
40094
|
}
|
|
39978
40095
|
|
|
39979
40096
|
// src/commands/sessions/summarise/summariseSession.ts
|
|
39980
|
-
import { execFileSync as
|
|
40097
|
+
import { execFileSync as execFileSync22 } from "child_process";
|
|
39981
40098
|
function summariseSession(jsonlPath2) {
|
|
39982
40099
|
const firstMessage = extractFirstUserMessage(jsonlPath2);
|
|
39983
40100
|
const backlogIds = scanSessionBacklogRefs(jsonlPath2);
|
|
@@ -39986,7 +40103,7 @@ function summariseSession(jsonlPath2) {
|
|
|
39986
40103
|
}
|
|
39987
40104
|
const prompt = buildPrompt6(firstMessage, backlogIds);
|
|
39988
40105
|
try {
|
|
39989
|
-
const output =
|
|
40106
|
+
const output = execFileSync22("claude", ["-p", "--model", "haiku", prompt], {
|
|
39990
40107
|
encoding: "utf8",
|
|
39991
40108
|
timeout: 3e4,
|
|
39992
40109
|
stdio: ["ignore", "pipe", "ignore"]
|