@staff0rd/assist 0.264.3 → 0.266.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.264.3",
9
+ version: "0.266.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -9445,6 +9445,21 @@ function buildArgs2(queryFile, vars) {
9445
9445
  }
9446
9446
  return args;
9447
9447
  }
9448
+ function throwOnGraphqlErrors(stdout) {
9449
+ let parsed;
9450
+ try {
9451
+ parsed = JSON.parse(stdout);
9452
+ } catch {
9453
+ return;
9454
+ }
9455
+ if (!parsed || typeof parsed !== "object") return;
9456
+ const errors = parsed.errors;
9457
+ if (!Array.isArray(errors) || errors.length === 0) return;
9458
+ const messages = errors.map(
9459
+ (entry) => entry && typeof entry === "object" && "message" in entry ? String(entry.message) : String(entry)
9460
+ ).join("; ");
9461
+ throw new Error(messages || "GraphQL request returned errors");
9462
+ }
9448
9463
  function runGhGraphql(mutation, vars) {
9449
9464
  const queryFile = join28(tmpdir4(), `gh-query-${Date.now()}.graphql`);
9450
9465
  writeFileSync19(queryFile, mutation);
@@ -9453,6 +9468,7 @@ function runGhGraphql(mutation, vars) {
9453
9468
  encoding: "utf-8"
9454
9469
  });
9455
9470
  if (result.status !== 0) throw new Error(result.stderr || result.stdout);
9471
+ throwOnGraphqlErrors(result.stdout);
9456
9472
  return result.stdout;
9457
9473
  } finally {
9458
9474
  unlinkSync7(queryFile);
@@ -10596,13 +10612,24 @@ function validateLine(line) {
10596
10612
  process.exit(1);
10597
10613
  }
10598
10614
  }
10615
+ function assertThreadCreated(stdout) {
10616
+ let parsed;
10617
+ try {
10618
+ parsed = JSON.parse(stdout);
10619
+ } catch {
10620
+ throw new Error(`GitHub returned an unparseable response: ${stdout}`);
10621
+ }
10622
+ const id = parsed.data?.addPullRequestReviewThread?.thread?.id;
10623
+ if (typeof id !== "string" || id.length === 0) {
10624
+ throw new Error(
10625
+ "GitHub did not create a review thread (no thread id returned); the line is likely outside the PR diff."
10626
+ );
10627
+ }
10628
+ }
10599
10629
  function postComment(vars) {
10600
10630
  const { startLine, ...base } = vars;
10601
- if (startLine === void 0) {
10602
- runGhGraphql(MUTATION_SINGLE, base);
10603
- return;
10604
- }
10605
- runGhGraphql(MUTATION_MULTI, { ...base, startLine });
10631
+ const stdout = startLine === void 0 ? runGhGraphql(MUTATION_SINGLE, base) : runGhGraphql(MUTATION_MULTI, { ...base, startLine });
10632
+ assertThreadCreated(stdout);
10606
10633
  }
10607
10634
  function comment2(path53, line, body, startLine) {
10608
10635
  validateBody(body);
@@ -13180,6 +13207,37 @@ function registerRefactor(program2) {
13180
13207
  // src/commands/review/review.ts
13181
13208
  import { execFileSync as execFileSync6 } from "child_process";
13182
13209
 
13210
+ // src/commands/review/annotateDiffWithLineNumbers.ts
13211
+ var FILE_HEADER2 = /^\+\+\+ (?:b\/)?(.+)$/;
13212
+ var HUNK_HEADER2 = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
13213
+ var GUTTER_WIDTH = 6;
13214
+ function gutter(lineNumber) {
13215
+ const label2 = lineNumber === null ? "" : String(lineNumber);
13216
+ return `${label2.padStart(GUTTER_WIDTH, " ")} `;
13217
+ }
13218
+ function annotateDiffWithLineNumbers(diff2) {
13219
+ let inFile = false;
13220
+ let newLine = 0;
13221
+ return diff2.split("\n").map((line) => {
13222
+ if (FILE_HEADER2.test(line)) {
13223
+ inFile = true;
13224
+ return gutter(null) + line;
13225
+ }
13226
+ const hunkMatch = line.match(HUNK_HEADER2);
13227
+ if (hunkMatch) {
13228
+ newLine = Number(hunkMatch[1]);
13229
+ return gutter(null) + line;
13230
+ }
13231
+ if (!inFile) return gutter(null) + line;
13232
+ if (line.startsWith("+") || line.startsWith(" ")) {
13233
+ const annotated = gutter(newLine) + line;
13234
+ newLine++;
13235
+ return annotated;
13236
+ }
13237
+ return gutter(null) + line;
13238
+ }).join("\n");
13239
+ }
13240
+
13183
13241
  // src/commands/review/formatPriorComments.ts
13184
13242
  function threadKey(c, byId) {
13185
13243
  if (c.threadId) return c.threadId;
@@ -13253,8 +13311,10 @@ ${formatFiles(context.changedFiles)}
13253
13311
  ${priorBlock}
13254
13312
  ## Diff (PR #${context.prNumber}: ${context.baseSha}..${context.headSha})
13255
13313
 
13314
+ Each added or context line is prefixed with a left gutter showing its line number in the new file. When citing a finding as \`file:line\`, use that gutter number \u2014 do **not** count lines in this document. Removed lines (\`-\`) and headers have a blank gutter and cannot be commented on.
13315
+
13256
13316
  \`\`\`diff
13257
- ${context.diff.trimEnd()}
13317
+ ${annotateDiffWithLineNumbers(context.diff.trimEnd())}
13258
13318
  \`\`\`
13259
13319
  `;
13260
13320
  }
@@ -13642,19 +13702,102 @@ async function postAndMaybeSubmit(lineBound, markdown, options2) {
13642
13702
  console.log("Leaving pending review unsubmitted.");
13643
13703
  }
13644
13704
 
13645
- // src/commands/review/warnUnlocated.ts
13705
+ // src/commands/review/buildDiffLineIndex.ts
13706
+ var FILE_HEADER3 = /^\+\+\+ (?:b\/)?(.+)$/;
13707
+ var HUNK_HEADER3 = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
13708
+ function buildDiffLineIndex(diff2) {
13709
+ const index2 = /* @__PURE__ */ new Map();
13710
+ let currentFile = null;
13711
+ let newLine = 0;
13712
+ for (const line of diff2.split("\n")) {
13713
+ const fileMatch = line.match(FILE_HEADER3);
13714
+ if (fileMatch) {
13715
+ currentFile = fileMatch[1] === "/dev/null" ? null : fileMatch[1];
13716
+ continue;
13717
+ }
13718
+ const hunkMatch = line.match(HUNK_HEADER3);
13719
+ if (hunkMatch) {
13720
+ newLine = Number(hunkMatch[1]);
13721
+ continue;
13722
+ }
13723
+ if (currentFile === null) continue;
13724
+ if (line.startsWith("-")) continue;
13725
+ if (line.startsWith("+") || line.startsWith(" ")) {
13726
+ let set = index2.get(currentFile);
13727
+ if (!set) {
13728
+ set = /* @__PURE__ */ new Set();
13729
+ index2.set(currentFile, set);
13730
+ }
13731
+ set.add(newLine);
13732
+ newLine++;
13733
+ }
13734
+ }
13735
+ return index2;
13736
+ }
13737
+
13738
+ // src/commands/review/partitionFindingsByDiff.ts
13739
+ function isWithinDiff(finding, index2) {
13740
+ const lines = index2.get(finding.file);
13741
+ if (!lines) return false;
13742
+ if (!lines.has(finding.line)) return false;
13743
+ if (finding.startLine !== void 0 && !lines.has(finding.startLine)) {
13744
+ return false;
13745
+ }
13746
+ return true;
13747
+ }
13748
+ function partitionFindingsByDiff(findings, index2) {
13749
+ const inDiff = [];
13750
+ const outOfDiff = [];
13751
+ for (const finding of findings) {
13752
+ if (isWithinDiff(finding, index2)) inDiff.push(finding);
13753
+ else outOfDiff.push(finding);
13754
+ }
13755
+ return { inDiff, outOfDiff };
13756
+ }
13757
+
13758
+ // src/commands/review/warnOutOfDiff.ts
13646
13759
  import chalk142 from "chalk";
13760
+ function warnOutOfDiff(outOfDiff) {
13761
+ if (outOfDiff.length === 0) return;
13762
+ console.warn(
13763
+ chalk142.yellow(
13764
+ `Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
13765
+ )
13766
+ );
13767
+ for (const finding of outOfDiff) {
13768
+ const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
13769
+ console.warn(
13770
+ ` ${chalk142.yellow("\xB7")} ${finding.title} ${chalk142.dim(
13771
+ `(${finding.file}:${range})`
13772
+ )}`
13773
+ );
13774
+ }
13775
+ }
13776
+
13777
+ // src/commands/review/selectInDiffFindings.ts
13778
+ function selectInDiffFindings(lineBound, prDiff) {
13779
+ const diff2 = fetchPrDiff(prDiff.prNumber, prDiff.baseSha, prDiff.headSha);
13780
+ const { inDiff, outOfDiff } = partitionFindingsByDiff(
13781
+ lineBound,
13782
+ buildDiffLineIndex(diff2)
13783
+ );
13784
+ warnOutOfDiff(outOfDiff);
13785
+ return inDiff;
13786
+ }
13787
+
13788
+ // src/commands/review/warnUnlocated.ts
13789
+ import chalk143 from "chalk";
13647
13790
  function warnUnlocated(unlocated) {
13648
13791
  if (unlocated.length === 0) return;
13649
13792
  console.warn(
13650
- chalk142.yellow(
13793
+ chalk143.yellow(
13651
13794
  `Skipped ${unlocated.length} finding(s) without a parseable file:line:`
13652
13795
  )
13653
13796
  );
13654
13797
  for (const finding of unlocated) {
13655
- const where = finding.location || chalk142.dim("missing");
13798
+ const where = finding.location || chalk143.dim("missing");
13656
13799
  console.warn(
13657
- ` ${chalk142.yellow("\xB7")} ${finding.title} ${chalk142.dim(`(${where})`)}`
13800
+ ` ${chalk143.yellow("\xB7")} ${finding.title} ${chalk143.dim(`(${where})`)}`
13658
13801
  );
13659
13802
  }
13660
13803
  }
@@ -13665,11 +13808,8 @@ async function confirmPost(prNumber, count6, options2) {
13665
13808
  return promptConfirm(`Post ${count6} comment(s) to PR #${prNumber}?`, false);
13666
13809
  }
13667
13810
  async function postReviewToPr(synthesisPath, options2) {
13668
- const prNumber = findCurrentPrNumber();
13669
- if (prNumber === null) {
13670
- console.log("No PR found for current branch; nothing posted.");
13671
- return;
13672
- }
13811
+ const prInfo = fetchPrDiffInfo();
13812
+ const prNumber = prInfo.prNumber;
13673
13813
  const markdown = readFileSync31(synthesisPath, "utf-8");
13674
13814
  const findings = parseFindings(markdown);
13675
13815
  if (findings.length === 0) {
@@ -13687,15 +13827,20 @@ async function postReviewToPr(synthesisPath, options2) {
13687
13827
  console.log("No line-bound findings to post.");
13688
13828
  return;
13689
13829
  }
13830
+ const inDiff = selectInDiffFindings(lineBound, prInfo);
13831
+ if (inDiff.length === 0) {
13832
+ console.log("No findings fall within the PR diff; nothing to post.");
13833
+ return;
13834
+ }
13690
13835
  console.log(
13691
- `Found PR #${prNumber} with ${lineBound.length} line-bound finding(s).`
13836
+ `Found PR #${prNumber} with ${inDiff.length} line-bound finding(s) in the diff.`
13692
13837
  );
13693
- const confirmed = await confirmPost(prNumber, lineBound.length, options2);
13838
+ const confirmed = await confirmPost(prNumber, inDiff.length, options2);
13694
13839
  if (!confirmed) {
13695
13840
  console.log("Skipped posting.");
13696
13841
  return;
13697
13842
  }
13698
- await postAndMaybeSubmit(lineBound, markdown, options2);
13843
+ await postAndMaybeSubmit(inDiff, markdown, options2);
13699
13844
  }
13700
13845
 
13701
13846
  // src/commands/review/runRefineSession.ts
@@ -14076,7 +14221,7 @@ List every finding that the original author would want to know about and fix. Do
14076
14221
 
14077
14222
  For each finding include:
14078
14223
  - Severity (blocker, major, minor, nit) \u2014 see rubric below
14079
- - File and line (e.g. \`src/foo.ts:42\`) when the finding is tied to a specific location
14224
+ - File and line (e.g. \`src/foo.ts:42\`) when the finding is tied to a specific location. Take the line number from the diff's left gutter (its line in the new file); never count lines in request.md.
14080
14225
  - Impact: what could go wrong, including the conditions under which it manifests
14081
14226
  - Recommendation: a concrete change
14082
14227
 
@@ -14826,7 +14971,7 @@ function registerReview(program2) {
14826
14971
  }
14827
14972
 
14828
14973
  // src/commands/seq/seqAuth.ts
14829
- import chalk144 from "chalk";
14974
+ import chalk145 from "chalk";
14830
14975
 
14831
14976
  // src/commands/seq/loadConnections.ts
14832
14977
  function loadConnections2() {
@@ -14855,10 +15000,10 @@ function setDefaultConnection(name) {
14855
15000
  }
14856
15001
 
14857
15002
  // src/shared/assertUniqueName.ts
14858
- import chalk143 from "chalk";
15003
+ import chalk144 from "chalk";
14859
15004
  function assertUniqueName(existingNames, name) {
14860
15005
  if (existingNames.includes(name)) {
14861
- console.error(chalk143.red(`Connection "${name}" already exists.`));
15006
+ console.error(chalk144.red(`Connection "${name}" already exists.`));
14862
15007
  process.exit(1);
14863
15008
  }
14864
15009
  }
@@ -14876,16 +15021,16 @@ async function promptConnection2(existingNames) {
14876
15021
  var seqAuth = createConnectionAuth({
14877
15022
  load: loadConnections2,
14878
15023
  save: saveConnections2,
14879
- format: (c) => `${chalk144.bold(c.name)} ${c.url}`,
15024
+ format: (c) => `${chalk145.bold(c.name)} ${c.url}`,
14880
15025
  promptNew: promptConnection2,
14881
15026
  onFirst: (c) => setDefaultConnection(c.name)
14882
15027
  });
14883
15028
 
14884
15029
  // src/commands/seq/seqQuery.ts
14885
- import chalk148 from "chalk";
15030
+ import chalk149 from "chalk";
14886
15031
 
14887
15032
  // src/commands/seq/fetchSeq.ts
14888
- import chalk145 from "chalk";
15033
+ import chalk146 from "chalk";
14889
15034
  async function fetchSeq(conn, path53, params) {
14890
15035
  const url = `${conn.url}${path53}?${params}`;
14891
15036
  const response = await fetch(url, {
@@ -14896,7 +15041,7 @@ async function fetchSeq(conn, path53, params) {
14896
15041
  });
14897
15042
  if (!response.ok) {
14898
15043
  const body = await response.text();
14899
- console.error(chalk145.red(`Seq returned ${response.status}: ${body}`));
15044
+ console.error(chalk146.red(`Seq returned ${response.status}: ${body}`));
14900
15045
  process.exit(1);
14901
15046
  }
14902
15047
  return response;
@@ -14951,23 +15096,23 @@ async function fetchSeqEvents(conn, params) {
14951
15096
  }
14952
15097
 
14953
15098
  // src/commands/seq/formatEvent.ts
14954
- import chalk146 from "chalk";
15099
+ import chalk147 from "chalk";
14955
15100
  function levelColor(level) {
14956
15101
  switch (level) {
14957
15102
  case "Fatal":
14958
- return chalk146.bgRed.white;
15103
+ return chalk147.bgRed.white;
14959
15104
  case "Error":
14960
- return chalk146.red;
15105
+ return chalk147.red;
14961
15106
  case "Warning":
14962
- return chalk146.yellow;
15107
+ return chalk147.yellow;
14963
15108
  case "Information":
14964
- return chalk146.cyan;
15109
+ return chalk147.cyan;
14965
15110
  case "Debug":
14966
- return chalk146.gray;
15111
+ return chalk147.gray;
14967
15112
  case "Verbose":
14968
- return chalk146.dim;
15113
+ return chalk147.dim;
14969
15114
  default:
14970
- return chalk146.white;
15115
+ return chalk147.white;
14971
15116
  }
14972
15117
  }
14973
15118
  function levelAbbrev(level) {
@@ -15008,12 +15153,12 @@ function formatTimestamp(iso) {
15008
15153
  function formatEvent(event) {
15009
15154
  const color = levelColor(event.Level);
15010
15155
  const abbrev = levelAbbrev(event.Level);
15011
- const ts8 = chalk146.dim(formatTimestamp(event.Timestamp));
15156
+ const ts8 = chalk147.dim(formatTimestamp(event.Timestamp));
15012
15157
  const msg = renderMessage(event);
15013
15158
  const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
15014
15159
  if (event.Exception) {
15015
15160
  for (const line of event.Exception.split("\n")) {
15016
- lines.push(chalk146.red(` ${line}`));
15161
+ lines.push(chalk147.red(` ${line}`));
15017
15162
  }
15018
15163
  }
15019
15164
  return lines.join("\n");
@@ -15046,11 +15191,11 @@ function rejectTimestampFilter(filter) {
15046
15191
  }
15047
15192
 
15048
15193
  // src/shared/resolveNamedConnection.ts
15049
- import chalk147 from "chalk";
15194
+ import chalk148 from "chalk";
15050
15195
  function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
15051
15196
  if (connections.length === 0) {
15052
15197
  console.error(
15053
- chalk147.red(
15198
+ chalk148.red(
15054
15199
  `No ${kind} connections configured. Run '${authCommand}' first.`
15055
15200
  )
15056
15201
  );
@@ -15059,7 +15204,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
15059
15204
  const target = requested ?? defaultName ?? connections[0].name;
15060
15205
  const connection = connections.find((c) => c.name === target);
15061
15206
  if (!connection) {
15062
- console.error(chalk147.red(`${kind} connection "${target}" not found.`));
15207
+ console.error(chalk148.red(`${kind} connection "${target}" not found.`));
15063
15208
  process.exit(1);
15064
15209
  }
15065
15210
  return connection;
@@ -15088,7 +15233,7 @@ async function seqQuery(filter, options2) {
15088
15233
  new URLSearchParams({ filter, count: String(count6) })
15089
15234
  );
15090
15235
  if (events.length === 0) {
15091
- console.log(chalk148.yellow("No events found."));
15236
+ console.log(chalk149.yellow("No events found."));
15092
15237
  return;
15093
15238
  }
15094
15239
  if (options2.json) {
@@ -15099,11 +15244,11 @@ async function seqQuery(filter, options2) {
15099
15244
  for (const event of chronological) {
15100
15245
  console.log(formatEvent(event));
15101
15246
  }
15102
- console.log(chalk148.dim(`
15247
+ console.log(chalk149.dim(`
15103
15248
  ${events.length} events`));
15104
15249
  if (events.length >= count6) {
15105
15250
  console.log(
15106
- chalk148.yellow(
15251
+ chalk149.yellow(
15107
15252
  `Results limited to ${count6}. Use --count to retrieve more.`
15108
15253
  )
15109
15254
  );
@@ -15111,10 +15256,10 @@ ${events.length} events`));
15111
15256
  }
15112
15257
 
15113
15258
  // src/shared/setNamedDefaultConnection.ts
15114
- import chalk149 from "chalk";
15259
+ import chalk150 from "chalk";
15115
15260
  function setNamedDefaultConnection(connections, name, setDefault, kind) {
15116
15261
  if (!connections.find((c) => c.name === name)) {
15117
- console.error(chalk149.red(`Connection "${name}" not found.`));
15262
+ console.error(chalk150.red(`Connection "${name}" not found.`));
15118
15263
  process.exit(1);
15119
15264
  }
15120
15265
  setDefault(name);
@@ -15162,7 +15307,7 @@ function registerSignal(program2) {
15162
15307
  }
15163
15308
 
15164
15309
  // src/commands/sql/sqlAuth.ts
15165
- import chalk151 from "chalk";
15310
+ import chalk152 from "chalk";
15166
15311
 
15167
15312
  // src/commands/sql/loadConnections.ts
15168
15313
  function loadConnections3() {
@@ -15191,7 +15336,7 @@ function setDefaultConnection2(name) {
15191
15336
  }
15192
15337
 
15193
15338
  // src/commands/sql/promptConnection.ts
15194
- import chalk150 from "chalk";
15339
+ import chalk151 from "chalk";
15195
15340
  async function promptConnection3(existingNames) {
15196
15341
  const name = await promptInput("name", "Connection name:", "default");
15197
15342
  assertUniqueName(existingNames, name);
@@ -15199,7 +15344,7 @@ async function promptConnection3(existingNames) {
15199
15344
  const portStr = await promptInput("port", "Port:", "1433");
15200
15345
  const port = Number.parseInt(portStr, 10);
15201
15346
  if (!Number.isFinite(port)) {
15202
- console.error(chalk150.red(`Invalid port "${portStr}".`));
15347
+ console.error(chalk151.red(`Invalid port "${portStr}".`));
15203
15348
  process.exit(1);
15204
15349
  }
15205
15350
  const user = await promptInput("user", "User:");
@@ -15212,13 +15357,13 @@ async function promptConnection3(existingNames) {
15212
15357
  var sqlAuth = createConnectionAuth({
15213
15358
  load: loadConnections3,
15214
15359
  save: saveConnections3,
15215
- format: (c) => `${chalk151.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
15360
+ format: (c) => `${chalk152.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
15216
15361
  promptNew: promptConnection3,
15217
15362
  onFirst: (c) => setDefaultConnection2(c.name)
15218
15363
  });
15219
15364
 
15220
15365
  // src/commands/sql/printTable.ts
15221
- import chalk152 from "chalk";
15366
+ import chalk153 from "chalk";
15222
15367
  function formatCell(value) {
15223
15368
  if (value === null || value === void 0) return "";
15224
15369
  if (value instanceof Date) return value.toISOString();
@@ -15227,7 +15372,7 @@ function formatCell(value) {
15227
15372
  }
15228
15373
  function printTable(rows) {
15229
15374
  if (rows.length === 0) {
15230
- console.log(chalk152.yellow("(no rows)"));
15375
+ console.log(chalk153.yellow("(no rows)"));
15231
15376
  return;
15232
15377
  }
15233
15378
  const columns = Object.keys(rows[0]);
@@ -15235,13 +15380,13 @@ function printTable(rows) {
15235
15380
  (col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
15236
15381
  );
15237
15382
  const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
15238
- console.log(chalk152.dim(header));
15239
- console.log(chalk152.dim("-".repeat(header.length)));
15383
+ console.log(chalk153.dim(header));
15384
+ console.log(chalk153.dim("-".repeat(header.length)));
15240
15385
  for (const row of rows) {
15241
15386
  const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
15242
15387
  console.log(line);
15243
15388
  }
15244
- console.log(chalk152.dim(`
15389
+ console.log(chalk153.dim(`
15245
15390
  ${rows.length} row${rows.length === 1 ? "" : "s"}`));
15246
15391
  }
15247
15392
 
@@ -15301,7 +15446,7 @@ async function sqlColumns(table, connectionName) {
15301
15446
  }
15302
15447
 
15303
15448
  // src/commands/sql/sqlMutate.ts
15304
- import chalk153 from "chalk";
15449
+ import chalk154 from "chalk";
15305
15450
 
15306
15451
  // src/commands/sql/isMutation.ts
15307
15452
  var MUTATION_KEYWORDS = [
@@ -15335,7 +15480,7 @@ function isMutation(sql4) {
15335
15480
  async function sqlMutate(query, connectionName) {
15336
15481
  if (!isMutation(query)) {
15337
15482
  console.error(
15338
- chalk153.red(
15483
+ chalk154.red(
15339
15484
  "assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
15340
15485
  )
15341
15486
  );
@@ -15345,18 +15490,18 @@ async function sqlMutate(query, connectionName) {
15345
15490
  const pool = await sqlConnect(conn);
15346
15491
  try {
15347
15492
  const result = await pool.request().query(query);
15348
- console.log(chalk153.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
15493
+ console.log(chalk154.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
15349
15494
  } finally {
15350
15495
  await pool.close();
15351
15496
  }
15352
15497
  }
15353
15498
 
15354
15499
  // src/commands/sql/sqlQuery.ts
15355
- import chalk154 from "chalk";
15500
+ import chalk155 from "chalk";
15356
15501
  async function sqlQuery(query, connectionName) {
15357
15502
  if (isMutation(query)) {
15358
15503
  console.error(
15359
- chalk154.red(
15504
+ chalk155.red(
15360
15505
  "assist sql query refuses mutating statements. Use `assist sql mutate` instead."
15361
15506
  )
15362
15507
  );
@@ -15371,7 +15516,7 @@ async function sqlQuery(query, connectionName) {
15371
15516
  printTable(rows);
15372
15517
  } else {
15373
15518
  console.log(
15374
- chalk154.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
15519
+ chalk155.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
15375
15520
  );
15376
15521
  }
15377
15522
  } finally {
@@ -15951,14 +16096,14 @@ import {
15951
16096
  import { dirname as dirname22, join as join42 } from "path";
15952
16097
 
15953
16098
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
15954
- import chalk155 from "chalk";
16099
+ import chalk156 from "chalk";
15955
16100
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
15956
16101
  function validateStagedContent(filename, content) {
15957
16102
  const firstLine = content.split("\n")[0];
15958
16103
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
15959
16104
  if (!match) {
15960
16105
  console.error(
15961
- chalk155.red(
16106
+ chalk156.red(
15962
16107
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
15963
16108
  )
15964
16109
  );
@@ -15967,7 +16112,7 @@ function validateStagedContent(filename, content) {
15967
16112
  const contentAfterLink = content.slice(firstLine.length).trim();
15968
16113
  if (!contentAfterLink) {
15969
16114
  console.error(
15970
- chalk155.red(
16115
+ chalk156.red(
15971
16116
  `Staged file ${filename} has no summary content after the transcript link.`
15972
16117
  )
15973
16118
  );
@@ -16364,7 +16509,7 @@ function registerVoice(program2) {
16364
16509
 
16365
16510
  // src/commands/roam/auth.ts
16366
16511
  import { randomBytes } from "crypto";
16367
- import chalk156 from "chalk";
16512
+ import chalk157 from "chalk";
16368
16513
 
16369
16514
  // src/lib/openBrowser.ts
16370
16515
  import { execSync as execSync46 } from "child_process";
@@ -16539,13 +16684,13 @@ async function auth() {
16539
16684
  saveGlobalConfig(config);
16540
16685
  const state = randomBytes(16).toString("hex");
16541
16686
  console.log(
16542
- chalk156.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
16687
+ chalk157.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
16543
16688
  );
16544
- console.log(chalk156.white("http://localhost:14523/callback\n"));
16545
- console.log(chalk156.blue("Opening browser for authorization..."));
16546
- console.log(chalk156.dim("Waiting for authorization callback..."));
16689
+ console.log(chalk157.white("http://localhost:14523/callback\n"));
16690
+ console.log(chalk157.blue("Opening browser for authorization..."));
16691
+ console.log(chalk157.dim("Waiting for authorization callback..."));
16547
16692
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
16548
- console.log(chalk156.dim("Exchanging code for tokens..."));
16693
+ console.log(chalk157.dim("Exchanging code for tokens..."));
16549
16694
  const tokens = await exchangeToken({
16550
16695
  code,
16551
16696
  clientId,
@@ -16561,7 +16706,7 @@ async function auth() {
16561
16706
  };
16562
16707
  saveGlobalConfig(config);
16563
16708
  console.log(
16564
- chalk156.green("Roam credentials and tokens saved to ~/.assist.yml")
16709
+ chalk157.green("Roam credentials and tokens saved to ~/.assist.yml")
16565
16710
  );
16566
16711
  }
16567
16712
 
@@ -17013,7 +17158,7 @@ import { execSync as execSync48 } from "child_process";
17013
17158
  import { existsSync as existsSync50, mkdirSync as mkdirSync20, unlinkSync as unlinkSync16, writeFileSync as writeFileSync32 } from "fs";
17014
17159
  import { tmpdir as tmpdir7 } from "os";
17015
17160
  import { join as join53, resolve as resolve13 } from "path";
17016
- import chalk157 from "chalk";
17161
+ import chalk158 from "chalk";
17017
17162
 
17018
17163
  // src/commands/screenshot/captureWindowPs1.ts
17019
17164
  var captureWindowPs1 = `
@@ -17164,13 +17309,13 @@ function screenshot(processName) {
17164
17309
  const config = loadConfig();
17165
17310
  const outputDir = resolve13(config.screenshot.outputDir);
17166
17311
  const outputPath = buildOutputPath(outputDir, processName);
17167
- console.log(chalk157.gray(`Capturing window for process "${processName}" ...`));
17312
+ console.log(chalk158.gray(`Capturing window for process "${processName}" ...`));
17168
17313
  try {
17169
17314
  runPowerShellScript(processName, outputPath);
17170
- console.log(chalk157.green(`Screenshot saved: ${outputPath}`));
17315
+ console.log(chalk158.green(`Screenshot saved: ${outputPath}`));
17171
17316
  } catch (error) {
17172
17317
  const msg = error instanceof Error ? error.message : String(error);
17173
- console.error(chalk157.red(`Failed to capture screenshot: ${msg}`));
17318
+ console.error(chalk158.red(`Failed to capture screenshot: ${msg}`));
17174
17319
  process.exit(1);
17175
17320
  }
17176
17321
  }
@@ -18316,7 +18461,7 @@ function registerDaemon(program2) {
18316
18461
 
18317
18462
  // src/commands/sessions/summarise/index.ts
18318
18463
  import * as fs30 from "fs";
18319
- import chalk158 from "chalk";
18464
+ import chalk159 from "chalk";
18320
18465
 
18321
18466
  // src/commands/sessions/summarise/shared.ts
18322
18467
  import * as fs28 from "fs";
@@ -18443,22 +18588,22 @@ ${firstMessage}`);
18443
18588
  async function summarise4(options2) {
18444
18589
  const files = await discoverSessionJsonlPaths();
18445
18590
  if (files.length === 0) {
18446
- console.log(chalk158.yellow("No sessions found."));
18591
+ console.log(chalk159.yellow("No sessions found."));
18447
18592
  return;
18448
18593
  }
18449
18594
  const toProcess = selectCandidates(files, options2);
18450
18595
  if (toProcess.length === 0) {
18451
- console.log(chalk158.green("All sessions already summarised."));
18596
+ console.log(chalk159.green("All sessions already summarised."));
18452
18597
  return;
18453
18598
  }
18454
18599
  console.log(
18455
- chalk158.cyan(
18600
+ chalk159.cyan(
18456
18601
  `Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
18457
18602
  )
18458
18603
  );
18459
18604
  const { succeeded, failed: failed2 } = processSessions(toProcess);
18460
18605
  console.log(
18461
- chalk158.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk158.yellow(`, ${failed2} skipped`) : "")
18606
+ chalk159.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk159.yellow(`, ${failed2} skipped`) : "")
18462
18607
  );
18463
18608
  }
18464
18609
  function selectCandidates(files, options2) {
@@ -18478,16 +18623,16 @@ function processSessions(files) {
18478
18623
  let failed2 = 0;
18479
18624
  for (let i = 0; i < files.length; i++) {
18480
18625
  const file = files[i];
18481
- process.stdout.write(chalk158.dim(` [${i + 1}/${files.length}] `));
18626
+ process.stdout.write(chalk159.dim(` [${i + 1}/${files.length}] `));
18482
18627
  const summary = summariseSession(file);
18483
18628
  if (summary) {
18484
18629
  writeSummary(file, summary);
18485
18630
  succeeded++;
18486
- process.stdout.write(`${chalk158.green("\u2713")} ${summary}
18631
+ process.stdout.write(`${chalk159.green("\u2713")} ${summary}
18487
18632
  `);
18488
18633
  } else {
18489
18634
  failed2++;
18490
- process.stdout.write(` ${chalk158.yellow("skip")}
18635
+ process.stdout.write(` ${chalk159.yellow("skip")}
18491
18636
  `);
18492
18637
  }
18493
18638
  }
@@ -18502,10 +18647,10 @@ function registerSessions(program2) {
18502
18647
  }
18503
18648
 
18504
18649
  // src/commands/statusLine.ts
18505
- import chalk160 from "chalk";
18650
+ import chalk161 from "chalk";
18506
18651
 
18507
18652
  // src/commands/buildLimitsSegment.ts
18508
- import chalk159 from "chalk";
18653
+ import chalk160 from "chalk";
18509
18654
  var FIVE_HOUR_SECONDS = 5 * 3600;
18510
18655
  var SEVEN_DAY_SECONDS = 7 * 86400;
18511
18656
  function formatTimeLeft(resetsAt) {
@@ -18528,10 +18673,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
18528
18673
  function colorizeRateLimit(pct, resetsAt, windowSeconds) {
18529
18674
  const label2 = `${Math.round(pct)}%`;
18530
18675
  const projected = projectUsage(pct, resetsAt, windowSeconds);
18531
- if (projected == null) return chalk159.green(label2);
18532
- if (projected > 100) return chalk159.red(label2);
18533
- if (projected > 75) return chalk159.yellow(label2);
18534
- return chalk159.green(label2);
18676
+ if (projected == null) return chalk160.green(label2);
18677
+ if (projected > 100) return chalk160.red(label2);
18678
+ if (projected > 75) return chalk160.yellow(label2);
18679
+ return chalk160.green(label2);
18535
18680
  }
18536
18681
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
18537
18682
  const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
@@ -18557,14 +18702,14 @@ function buildLimitsSegment(rateLimits) {
18557
18702
  }
18558
18703
 
18559
18704
  // src/commands/statusLine.ts
18560
- chalk160.level = 3;
18705
+ chalk161.level = 3;
18561
18706
  function formatNumber(num) {
18562
18707
  return num.toLocaleString("en-US");
18563
18708
  }
18564
18709
  function colorizePercent(pct) {
18565
18710
  const label2 = `${Math.round(pct)}%`;
18566
- if (pct > 80) return chalk160.red(label2);
18567
- if (pct > 40) return chalk160.yellow(label2);
18711
+ if (pct > 80) return chalk161.red(label2);
18712
+ if (pct > 40) return chalk161.yellow(label2);
18568
18713
  return label2;
18569
18714
  }
18570
18715
  async function statusLine() {
@@ -18587,7 +18732,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
18587
18732
  // src/commands/sync/syncClaudeMd.ts
18588
18733
  import * as fs31 from "fs";
18589
18734
  import * as path49 from "path";
18590
- import chalk161 from "chalk";
18735
+ import chalk162 from "chalk";
18591
18736
  async function syncClaudeMd(claudeDir, targetBase, options2) {
18592
18737
  const source = path49.join(claudeDir, "CLAUDE.md");
18593
18738
  const target = path49.join(targetBase, "CLAUDE.md");
@@ -18596,12 +18741,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
18596
18741
  const targetContent = fs31.readFileSync(target, "utf-8");
18597
18742
  if (sourceContent !== targetContent) {
18598
18743
  console.log(
18599
- chalk161.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
18744
+ chalk162.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
18600
18745
  );
18601
18746
  console.log();
18602
18747
  printDiff(targetContent, sourceContent);
18603
18748
  const confirm = options2?.yes || await promptConfirm(
18604
- chalk161.red("Overwrite existing CLAUDE.md?"),
18749
+ chalk162.red("Overwrite existing CLAUDE.md?"),
18605
18750
  false
18606
18751
  );
18607
18752
  if (!confirm) {
@@ -18617,7 +18762,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
18617
18762
  // src/commands/sync/syncSettings.ts
18618
18763
  import * as fs32 from "fs";
18619
18764
  import * as path50 from "path";
18620
- import chalk162 from "chalk";
18765
+ import chalk163 from "chalk";
18621
18766
  async function syncSettings(claudeDir, targetBase, options2) {
18622
18767
  const source = path50.join(claudeDir, "settings.json");
18623
18768
  const target = path50.join(targetBase, "settings.json");
@@ -18633,14 +18778,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
18633
18778
  if (mergedContent !== normalizedTarget) {
18634
18779
  if (!options2?.yes) {
18635
18780
  console.log(
18636
- chalk162.yellow(
18781
+ chalk163.yellow(
18637
18782
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
18638
18783
  )
18639
18784
  );
18640
18785
  console.log();
18641
18786
  printDiff(targetContent, mergedContent);
18642
18787
  const confirm = await promptConfirm(
18643
- chalk162.red("Overwrite existing settings.json?"),
18788
+ chalk163.red("Overwrite existing settings.json?"),
18644
18789
  false
18645
18790
  );
18646
18791
  if (!confirm) {