@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/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.615.3",
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
- message: rule.message,
16585
- regex: rawDenyRegex(rule.pattern)
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.regex.test(text18));
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 BODY_FLAGS = /* @__PURE__ */ new Set(["-f", "-F", "--field", "--raw-field", "--input"]);
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 = extractMethod(args);
16725
+ const method = extractGhApiMethod(args);
16665
16726
  if (method) return READ_METHODS.has(method.toUpperCase());
16666
- if (args.some((t) => BODY_FLAGS.has(t))) return false;
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 = extractMethod(args);
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 execFileSync12 } from "child_process";
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 execFileSync11 } from "child_process";
23628
+ import { execFileSync as execFileSync12 } from "child_process";
23512
23629
  function prHeadBranch(number) {
23513
23630
  try {
23514
- const out = execFileSync11(
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
- execFileSync12("gh", ["pr", "checkout", number], { stdio: "inherit" });
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 execFileSync13 } from "child_process";
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
- execFileSync13("gh", args, { stdio: "inherit" });
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 execFileSync14 } from "child_process";
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
- execFileSync14(
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
- execFileSync14("git", args, { stdio: "inherit" });
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
- execFileSync14("gh", args, { stdio: "inherit" });
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 USAGE4 = "Usage: assist prs raise --title <title> --what <what> --why <why> [--how <how>] [--resolves <key>] [--force]";
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, USAGE4);
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 USAGE5 = "Usage: assist slack post [channel] --body <body|->";
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(USAGE5);
31393
+ console.error(USAGE6);
31277
31394
  process.exit(1);
31278
31395
  }
31279
31396
  if (!body) {
31280
- console.error(USAGE5);
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 unquote(value) {
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 ? unquote(descriptionMatch[1]) : name;
32002
+ const description = descriptionMatch ? unquote2(descriptionMatch[1]) : name;
31886
32003
  const argsMatch = frontmatter.match(/^allowed_args:\s*(.*)$/m);
31887
- const argumentHint = argsMatch ? unquote(argsMatch[1]) : void 0;
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 execFileSync15 } from "child_process";
32858
+ import { execFileSync as execFileSync16 } from "child_process";
32742
32859
  function runGit3(args, cwd) {
32743
- return execFileSync15("git", args, {
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 execFileSync16 } from "child_process";
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 = execFileSync16("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
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 execFileSync17 } from "child_process";
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
- execFileSync17("git", ["fetch", "--quiet"], {
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 execFileSync18 } from "child_process";
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
- execFileSync18("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
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 execFileSync19 } from "child_process";
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 = execFileSync19("ps", ["-eo", "pid=,args="], {
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 execFileSync20 } from "child_process";
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 execFileSync20(command, args, {
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 execFileSync21 } from "child_process";
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 = execFileSync21("claude", ["-p", "--model", "haiku", prompt], {
40106
+ const output = execFileSync22("claude", ["-p", "--model", "haiku", prompt], {
39990
40107
  encoding: "utf8",
39991
40108
  timeout: 3e4,
39992
40109
  stdio: ["ignore", "pipe", "ignore"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.615.3",
3
+ "version": "0.616.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {