@staff0rd/assist 0.626.0 → 0.628.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.626.0",
9
+ version: "0.628.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -26601,6 +26601,120 @@ async function raise(options2, command) {
26601
26601
  await placePr(existing, title, body, resolved);
26602
26602
  }
26603
26603
 
26604
+ // src/commands/prs/readTime.ts
26605
+ import { execSync as execSync51 } from "child_process";
26606
+ import { readFileSync as readFileSync45 } from "fs";
26607
+
26608
+ // src/commands/prs/countReadingWords.ts
26609
+ var FENCE_PATTERN = /^\s*(```|~~~)/;
26610
+ var IMAGE_PATTERN = /!\[[^\]]*\]\([^)]*\)/g;
26611
+ var HTML_TAG_PATTERN = /<[^\s>][^>]*>/g;
26612
+ var URL_PATTERN3 = /https?:\/\/\S+/g;
26613
+ var SINGLE_WORD_PATTERNS = [IMAGE_PATTERN, HTML_TAG_PATTERN, URL_PATTERN3];
26614
+ function countReadingWords(body) {
26615
+ let prose = 0;
26616
+ let code = 0;
26617
+ let inCode = false;
26618
+ for (const line of body.split("\n")) {
26619
+ if (FENCE_PATTERN.test(line)) {
26620
+ inCode = !inCode;
26621
+ } else if (inCode) {
26622
+ code += countTokens(line);
26623
+ } else {
26624
+ prose += countProseWords(line);
26625
+ }
26626
+ }
26627
+ return { prose, code };
26628
+ }
26629
+ function countProseWords(line) {
26630
+ let singles = 0;
26631
+ let remaining = line;
26632
+ for (const pattern2 of SINGLE_WORD_PATTERNS) {
26633
+ remaining = remaining.replace(pattern2, () => {
26634
+ singles += 1;
26635
+ return " ";
26636
+ });
26637
+ }
26638
+ return singles + countTokens(remaining);
26639
+ }
26640
+ function countTokens(text18) {
26641
+ return text18.split(/\s+/).filter((token) => /[A-Za-z0-9]/.test(token)).length;
26642
+ }
26643
+
26644
+ // src/commands/prs/formatReadDuration.ts
26645
+ function formatReadDuration(seconds) {
26646
+ if (seconds < 60) return `${seconds}s`;
26647
+ const minutes = Math.floor(seconds / 60);
26648
+ const remainder = seconds % 60;
26649
+ return remainder === 0 ? `${minutes}m` : `${minutes}m ${remainder}s`;
26650
+ }
26651
+
26652
+ // src/commands/prs/resolveReadTimeTarget.ts
26653
+ var PR_URL_PATTERN = /^(https:\/\/github\.com\/[^/\s]+\/[^/\s]+)\/pull\/(\d+)(?:[/?#].*)?$/;
26654
+ function resolveReadTimeTarget(target) {
26655
+ const trimmed = target.trim();
26656
+ if (trimmed === "-") return { kind: "stdin" };
26657
+ if (/^\d+$/.test(trimmed)) {
26658
+ return { kind: "pr", number: Number(trimmed), repo: null };
26659
+ }
26660
+ const url = PR_URL_PATTERN.exec(trimmed);
26661
+ if (url) {
26662
+ const repo = parseGitHubUrl(url[1]);
26663
+ if (repo) return { kind: "pr", number: Number(url[2]), repo };
26664
+ }
26665
+ return { kind: "file", path: target };
26666
+ }
26667
+
26668
+ // src/commands/prs/readTime.ts
26669
+ var WORDS_PER_MINUTE = 200;
26670
+ var CODE_SCAN_WORDS_PER_MINUTE = 100;
26671
+ async function readTime(target) {
26672
+ const body = await loadBody(resolveReadTimeTarget(target));
26673
+ const { prose, code } = countReadingWords(body);
26674
+ const words = prose + code;
26675
+ const seconds = Math.round(
26676
+ (prose / WORDS_PER_MINUTE + code / CODE_SCAN_WORDS_PER_MINUTE) * 60
26677
+ );
26678
+ const label2 = words === 1 ? "word" : "words";
26679
+ console.log(`${words} ${label2} \xB7 ~${formatReadDuration(seconds)} read`);
26680
+ }
26681
+ async function loadBody(target) {
26682
+ if (target.kind === "stdin") return readBodyArgument("-");
26683
+ if (target.kind === "file") return readDraftFile(target.path);
26684
+ return fetchPrBody(target.number, target.repo);
26685
+ }
26686
+ function readDraftFile(path90) {
26687
+ try {
26688
+ return readFileSync45(path90, "utf8");
26689
+ } catch {
26690
+ console.error(`Error: Could not read \`${path90}\`.`);
26691
+ console.error(
26692
+ "Pass a pull request number, a GitHub pull request URL, - for stdin, or a path to a file."
26693
+ );
26694
+ process.exit(1);
26695
+ }
26696
+ }
26697
+ function fetchPrBody(number, repo) {
26698
+ const { org, repo: name } = repo ?? getRepoInfo();
26699
+ try {
26700
+ const raw = execSync51(`gh pr view ${number} --json body -R ${org}/${name}`, {
26701
+ encoding: "utf8"
26702
+ });
26703
+ return JSON.parse(raw).body ?? "";
26704
+ } catch (error) {
26705
+ if (isGhNotInstalled(error)) {
26706
+ console.error("Error: GitHub CLI (gh) is not installed.");
26707
+ console.error("Install it from https://cli.github.com/");
26708
+ process.exit(1);
26709
+ }
26710
+ if (isNotFound(error)) {
26711
+ console.error(`Error: Pull request ${org}/${name}#${number} not found.`);
26712
+ process.exit(1);
26713
+ }
26714
+ throw error;
26715
+ }
26716
+ }
26717
+
26604
26718
  // src/commands/prs/reply.ts
26605
26719
  function validateBody2(body) {
26606
26720
  const lowerBody = body.toLowerCase();
@@ -26628,7 +26742,7 @@ async function reply(commentId, body) {
26628
26742
  }
26629
26743
 
26630
26744
  // src/commands/prs/wontfix.ts
26631
- import { execSync as execSync51 } from "child_process";
26745
+ import { execSync as execSync52 } from "child_process";
26632
26746
  function validateReason(reason4) {
26633
26747
  const lowerReason = reason4.toLowerCase();
26634
26748
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -26645,7 +26759,7 @@ function validateShaReferences(reason4) {
26645
26759
  const invalidShas = [];
26646
26760
  for (const sha of shas) {
26647
26761
  try {
26648
- execSync51(`git cat-file -t ${sha}`, { stdio: "pipe" });
26762
+ execSync52(`git cat-file -t ${sha}`, { stdio: "pipe" });
26649
26763
  } catch {
26650
26764
  invalidShas.push(sha);
26651
26765
  }
@@ -26912,12 +27026,22 @@ function registerPrsRaise(prsCommand) {
26912
27026
  configHelp(raiseCommand, prsRaiseConfigHelp);
26913
27027
  }
26914
27028
 
27029
+ // src/commands/registerPrsReadTime.ts
27030
+ function registerPrsReadTime(prsCommand) {
27031
+ prsCommand.command("read-time <target>").description(
27032
+ "Estimate how long a pull request description takes to read (target is a PR number, a GitHub PR URL, - for stdin, or a file path)"
27033
+ ).action(async (target) => {
27034
+ await readTime(target);
27035
+ });
27036
+ }
27037
+
26915
27038
  // src/commands/registerPrs.ts
26916
27039
  function registerPrs(program2) {
26917
27040
  const prsCommand = program2.command("prs").description("Pull request utilities").option("--open", "List only open pull requests").option("--closed", "List only closed pull requests").action(prs);
26918
27041
  registerPrsRaise(prsCommand);
26919
27042
  registerPrsEdit(prsCommand);
26920
27043
  registerPrsComments(prsCommand);
27044
+ registerPrsReadTime(prsCommand);
26921
27045
  configHelp(prsCommand, prsConfigHelp);
26922
27046
  }
26923
27047
 
@@ -26991,10 +27115,10 @@ import chalk187 from "chalk";
26991
27115
  import Enquirer2 from "enquirer";
26992
27116
 
26993
27117
  // src/commands/ravendb/searchItems.ts
26994
- import { execSync as execSync52 } from "child_process";
27118
+ import { execSync as execSync53 } from "child_process";
26995
27119
  import chalk186 from "chalk";
26996
27120
  function opExec(args) {
26997
- return execSync52(`op ${args}`, {
27121
+ return execSync53(`op ${args}`, {
26998
27122
  encoding: "utf8",
26999
27123
  stdio: ["pipe", "pipe", "pipe"]
27000
27124
  }).trim();
@@ -27146,7 +27270,7 @@ ${errorText}`
27146
27270
  }
27147
27271
 
27148
27272
  // src/commands/ravendb/resolveOpSecret.ts
27149
- import { execSync as execSync53 } from "child_process";
27273
+ import { execSync as execSync54 } from "child_process";
27150
27274
  import chalk191 from "chalk";
27151
27275
  function resolveOpSecret(reference) {
27152
27276
  if (!reference.startsWith("op://")) {
@@ -27154,7 +27278,7 @@ function resolveOpSecret(reference) {
27154
27278
  process.exit(1);
27155
27279
  }
27156
27280
  try {
27157
- return execSync53(`op read "${reference}"`, {
27281
+ return execSync54(`op read "${reference}"`, {
27158
27282
  encoding: "utf8",
27159
27283
  stdio: ["pipe", "pipe", "pipe"]
27160
27284
  }).trim();
@@ -27404,7 +27528,7 @@ Refactor check failed:
27404
27528
  }
27405
27529
 
27406
27530
  // src/commands/refactor/check/getViolations/index.ts
27407
- import { execSync as execSync54 } from "child_process";
27531
+ import { execSync as execSync55 } from "child_process";
27408
27532
  import fs30 from "fs";
27409
27533
  import { minimatch as minimatch6 } from "minimatch";
27410
27534
 
@@ -27454,7 +27578,7 @@ function getGitFiles(options2) {
27454
27578
  }
27455
27579
  const files = /* @__PURE__ */ new Set();
27456
27580
  if (options2.staged || options2.modified) {
27457
- const staged = execSync54("git diff --cached --name-only", {
27581
+ const staged = execSync55("git diff --cached --name-only", {
27458
27582
  encoding: "utf8"
27459
27583
  });
27460
27584
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -27462,7 +27586,7 @@ function getGitFiles(options2) {
27462
27586
  }
27463
27587
  }
27464
27588
  if (options2.unstaged || options2.modified) {
27465
- const unstaged = execSync54("git diff --name-only", { encoding: "utf8" });
27589
+ const unstaged = execSync55("git diff --name-only", { encoding: "utf8" });
27466
27590
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
27467
27591
  files.add(file);
27468
27592
  }
@@ -29173,9 +29297,9 @@ function buildReviewPaths(repoRoot2, key) {
29173
29297
  }
29174
29298
 
29175
29299
  // src/commands/review/fetchExistingComments.ts
29176
- import { execSync as execSync55 } from "child_process";
29300
+ import { execSync as execSync56 } from "child_process";
29177
29301
  function fetchRawComments(org, repo, prNumber) {
29178
- const out = execSync55(
29302
+ const out = execSync56(
29179
29303
  `gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
29180
29304
  { encoding: "utf8", maxBuffer: 64 * 1024 * 1024 }
29181
29305
  );
@@ -29206,14 +29330,14 @@ function fetchExistingComments() {
29206
29330
  }
29207
29331
 
29208
29332
  // src/commands/review/gatherContext.ts
29209
- import { execSync as execSync58 } from "child_process";
29333
+ import { execSync as execSync59 } from "child_process";
29210
29334
 
29211
29335
  // src/commands/review/fetchPrDiff.ts
29212
- import { execSync as execSync56 } from "child_process";
29336
+ import { execSync as execSync57 } from "child_process";
29213
29337
  function fetchPrDiff(prNumber, baseSha, headSha) {
29214
29338
  const { org, repo } = getRepoInfo();
29215
29339
  try {
29216
- return execSync56(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
29340
+ return execSync57(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
29217
29341
  encoding: "utf8",
29218
29342
  maxBuffer: 256 * 1024 * 1024,
29219
29343
  stdio: ["ignore", "pipe", "pipe"]
@@ -29228,19 +29352,19 @@ function isDiffTooLarge(error) {
29228
29352
  }
29229
29353
  function fetchDiffViaGit(baseSha, headSha) {
29230
29354
  try {
29231
- execSync56(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
29355
+ execSync57(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
29232
29356
  } catch {
29233
29357
  }
29234
- return execSync56(`git diff ${baseSha}...${headSha}`, {
29358
+ return execSync57(`git diff ${baseSha}...${headSha}`, {
29235
29359
  encoding: "utf8",
29236
29360
  maxBuffer: 256 * 1024 * 1024
29237
29361
  });
29238
29362
  }
29239
29363
 
29240
29364
  // src/commands/review/fetchPrDiffInfo.ts
29241
- import { execSync as execSync57 } from "child_process";
29365
+ import { execSync as execSync58 } from "child_process";
29242
29366
  function getCurrentBranch3() {
29243
- return execSync57("git rev-parse --abbrev-ref HEAD", {
29367
+ return execSync58("git rev-parse --abbrev-ref HEAD", {
29244
29368
  encoding: "utf8"
29245
29369
  }).trim();
29246
29370
  }
@@ -29248,7 +29372,7 @@ function fetchPrDiffInfo() {
29248
29372
  const { org, repo } = getRepoInfo();
29249
29373
  const branch2 = getCurrentBranch3();
29250
29374
  const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
29251
- const raw = execSync57(
29375
+ const raw = execSync58(
29252
29376
  `gh pr list --state open --head ${branch2} --json ${fields} -R ${org}/${repo}`,
29253
29377
  {
29254
29378
  encoding: "utf8",
@@ -29273,7 +29397,7 @@ function fetchPrDiffInfo() {
29273
29397
  }
29274
29398
  function fetchPrChangedFiles(prNumber) {
29275
29399
  const { org, repo } = getRepoInfo();
29276
- const out = execSync57(
29400
+ const out = execSync58(
29277
29401
  `gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
29278
29402
  {
29279
29403
  encoding: "utf8",
@@ -29285,11 +29409,11 @@ function fetchPrChangedFiles(prNumber) {
29285
29409
 
29286
29410
  // src/commands/review/gatherContext.ts
29287
29411
  function gatherContext() {
29288
- const branch2 = execSync58("git rev-parse --abbrev-ref HEAD", {
29412
+ const branch2 = execSync59("git rev-parse --abbrev-ref HEAD", {
29289
29413
  encoding: "utf8"
29290
29414
  }).trim();
29291
- const sha = execSync58("git rev-parse HEAD", { encoding: "utf8" }).trim();
29292
- const shortSha = execSync58("git rev-parse --short=7 HEAD", {
29415
+ const sha = execSync59("git rev-parse HEAD", { encoding: "utf8" }).trim();
29416
+ const shortSha = execSync59("git rev-parse --short=7 HEAD", {
29293
29417
  encoding: "utf8"
29294
29418
  }).trim();
29295
29419
  const prInfo = fetchPrDiffInfo();
@@ -29310,7 +29434,7 @@ function gatherContext() {
29310
29434
  }
29311
29435
 
29312
29436
  // src/commands/review/postReviewToPr.ts
29313
- import { readFileSync as readFileSync45 } from "fs";
29437
+ import { readFileSync as readFileSync46 } from "fs";
29314
29438
 
29315
29439
  // src/commands/review/carriedUnanchoredFindings.ts
29316
29440
  function carriedUnanchoredFindings(unanchored) {
@@ -29758,7 +29882,7 @@ async function confirmPost(prNumber, work, options2) {
29758
29882
  return promptConfirm(`Post ${work} to PR #${prNumber}?`, false);
29759
29883
  }
29760
29884
  async function postFindingsToPr(prInfo, synthesisPath, options2) {
29761
- const markdown = readFileSync45(synthesisPath, "utf8");
29885
+ const markdown = readFileSync46(synthesisPath, "utf8");
29762
29886
  const { inDiff, unanchored } = selectPostableFindings(markdown, prInfo);
29763
29887
  const carried = carriedUnanchoredFindings(unanchored);
29764
29888
  if (inDiff.length === 0 && carried.length === 0) return NOTHING_POSTED;
@@ -30647,7 +30771,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
30647
30771
  }
30648
30772
 
30649
30773
  // src/commands/review/synthesise.ts
30650
- import { readFileSync as readFileSync46 } from "fs";
30774
+ import { readFileSync as readFileSync47 } from "fs";
30651
30775
 
30652
30776
  // src/commands/review/buildSynthesisStdin.ts
30653
30777
  var SYNTHESIS_PROMPT = `You are consolidating two independent code reviews of the same change. The original review request is in request.md. The two reviews are in claude.md and codex.md in the current working directory.
@@ -30712,7 +30836,7 @@ Files:
30712
30836
 
30713
30837
  // src/commands/review/synthesise.ts
30714
30838
  function printSummary2(synthesisPath) {
30715
- const markdown = readFileSync46(synthesisPath, "utf8");
30839
+ const markdown = readFileSync47(synthesisPath, "utf8");
30716
30840
  console.log("");
30717
30841
  console.log(buildReviewSummary(markdown));
30718
30842
  console.log("");
@@ -30946,7 +31070,7 @@ function registerReview(program2) {
30946
31070
  }
30947
31071
 
30948
31072
  // src/commands/rules/addRule.ts
30949
- import { existsSync as existsSync66, readFileSync as readFileSync50, writeFileSync as writeFileSync41 } from "fs";
31073
+ import { existsSync as existsSync66, readFileSync as readFileSync51, writeFileSync as writeFileSync41 } from "fs";
30950
31074
  import path71 from "path";
30951
31075
  import chalk211 from "chalk";
30952
31076
 
@@ -30971,7 +31095,7 @@ function insertRuleBullet(content, rule) {
30971
31095
  }
30972
31096
 
30973
31097
  // src/commands/rules/nextRuleCode.ts
30974
- import { readFileSync as readFileSync47 } from "fs";
31098
+ import { readFileSync as readFileSync48 } from "fs";
30975
31099
 
30976
31100
  // src/commands/rules/findClaudeFiles.ts
30977
31101
  import { readdirSync as readdirSync13 } from "fs";
@@ -30995,7 +31119,7 @@ function findClaudeFiles(dir) {
30995
31119
  var CODE_PREFIX = "R";
30996
31120
  function nextRuleCode(root) {
30997
31121
  const numbers = findClaudeFiles(root).flatMap(
30998
- (file) => parseRulesSection(readFileSync47(file, "utf8")).map(
31122
+ (file) => parseRulesSection(readFileSync48(file, "utf8")).map(
30999
31123
  (rule) => Number(/(\d+)\s*$/.exec(rule.code)?.[1] ?? 0)
31000
31124
  )
31001
31125
  );
@@ -31021,15 +31145,15 @@ function resolveRuleScope(target) {
31021
31145
  }
31022
31146
 
31023
31147
  // src/commands/rules/updateScopedRulesIndex.ts
31024
- import { existsSync as existsSync65, readFileSync as readFileSync49, writeFileSync as writeFileSync40 } from "fs";
31148
+ import { existsSync as existsSync65, readFileSync as readFileSync50, writeFileSync as writeFileSync40 } from "fs";
31025
31149
  import path70 from "path";
31026
31150
 
31027
31151
  // src/commands/rules/scopedRuleDirectories.ts
31028
- import { readFileSync as readFileSync48 } from "fs";
31152
+ import { readFileSync as readFileSync49 } from "fs";
31029
31153
  import path69 from "path";
31030
31154
  function scopedRuleDirectories(root) {
31031
31155
  return findClaudeFiles(root).filter(
31032
- (file) => path69.dirname(file) !== root && parseRulesSection(readFileSync48(file, "utf8")).length > 0
31156
+ (file) => path69.dirname(file) !== root && parseRulesSection(readFileSync49(file, "utf8")).length > 0
31033
31157
  ).map(
31034
31158
  (file) => `${path69.relative(root, path69.dirname(file)).split(path69.sep).join("/")}/`
31035
31159
  ).sort();
@@ -31071,7 +31195,7 @@ function upsertScopedRulesPointer(content, directories) {
31071
31195
  function updateScopedRulesIndex(root) {
31072
31196
  const directories = scopedRuleDirectories(root);
31073
31197
  const rootFile = path70.join(root, "CLAUDE.md");
31074
- const before = existsSync65(rootFile) ? readFileSync49(rootFile, "utf8") : "";
31198
+ const before = existsSync65(rootFile) ? readFileSync50(rootFile, "utf8") : "";
31075
31199
  const after = upsertScopedRulesPointer(before, directories);
31076
31200
  if (after !== before) writeFileSync40(rootFile, after);
31077
31201
  return directories;
@@ -31079,7 +31203,7 @@ function updateScopedRulesIndex(root) {
31079
31203
 
31080
31204
  // src/commands/rules/addRule.ts
31081
31205
  function read2(file) {
31082
- return existsSync66(file) ? readFileSync50(file, "utf8") : "";
31206
+ return existsSync66(file) ? readFileSync51(file, "utf8") : "";
31083
31207
  }
31084
31208
  function addRule(text18, options2) {
31085
31209
  const rule = text18.trim();
@@ -32572,9 +32696,9 @@ function formatVttPassages(passages, notes = [], { sourceMarks = true } = {}) {
32572
32696
  }
32573
32697
 
32574
32698
  // src/commands/transcript/convert/readCleanedCues.ts
32575
- import { readFileSync as readFileSync55 } from "fs";
32699
+ import { readFileSync as readFileSync56 } from "fs";
32576
32700
  function readCleanedCues(inputPath) {
32577
- return deduplicateCues(parseVtt(readFileSync55(inputPath, "utf8")));
32701
+ return deduplicateCues(parseVtt(readFileSync56(inputPath, "utf8")));
32578
32702
  }
32579
32703
 
32580
32704
  // src/commands/transcript/clean.ts
@@ -33081,14 +33205,14 @@ function devices() {
33081
33205
  }
33082
33206
 
33083
33207
  // src/commands/voice/logs.ts
33084
- import { existsSync as existsSync75, readFileSync as readFileSync56 } from "fs";
33208
+ import { existsSync as existsSync75, readFileSync as readFileSync57 } from "fs";
33085
33209
  function logs(options2) {
33086
33210
  if (!existsSync75(voicePaths.log)) {
33087
33211
  console.log("No voice log file found");
33088
33212
  return;
33089
33213
  }
33090
33214
  const count8 = Number.parseInt(options2.lines ?? "150", 10);
33091
- const content = readFileSync56(voicePaths.log, "utf8").trim();
33215
+ const content = readFileSync57(voicePaths.log, "utf8").trim();
33092
33216
  if (!content) {
33093
33217
  console.log("Voice log is empty");
33094
33218
  return;
@@ -33114,8 +33238,8 @@ import { mkdirSync as mkdirSync30 } from "fs";
33114
33238
  import { join as join89 } from "path";
33115
33239
 
33116
33240
  // src/commands/voice/checkLockFile.ts
33117
- import { execSync as execSync59 } from "child_process";
33118
- import { existsSync as existsSync76, mkdirSync as mkdirSync29, readFileSync as readFileSync57, writeFileSync as writeFileSync48 } from "fs";
33241
+ import { execSync as execSync60 } from "child_process";
33242
+ import { existsSync as existsSync76, mkdirSync as mkdirSync29, readFileSync as readFileSync58, writeFileSync as writeFileSync48 } from "fs";
33119
33243
  import { join as join88 } from "path";
33120
33244
  function isProcessAlive2(pid) {
33121
33245
  try {
@@ -33129,7 +33253,7 @@ function checkLockFile() {
33129
33253
  const lockFile = getLockFile();
33130
33254
  if (!existsSync76(lockFile)) return;
33131
33255
  try {
33132
- const lock2 = JSON.parse(readFileSync57(lockFile, "utf8"));
33256
+ const lock2 = JSON.parse(readFileSync58(lockFile, "utf8"));
33133
33257
  if (lock2.pid && isProcessAlive2(lock2.pid)) {
33134
33258
  console.error(
33135
33259
  `Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
@@ -33143,7 +33267,7 @@ function bootstrapVenv() {
33143
33267
  if (existsSync76(getVenvPython())) return;
33144
33268
  console.log("Setting up Python environment...");
33145
33269
  const pythonDir = getPythonDir();
33146
- execSync59(
33270
+ execSync60(
33147
33271
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
33148
33272
  {
33149
33273
  stdio: "inherit",
@@ -33231,7 +33355,7 @@ function start2(options2) {
33231
33355
  }
33232
33356
 
33233
33357
  // src/commands/voice/status.ts
33234
- import { existsSync as existsSync77, readFileSync as readFileSync58 } from "fs";
33358
+ import { existsSync as existsSync77, readFileSync as readFileSync59 } from "fs";
33235
33359
  function isProcessAlive3(pid) {
33236
33360
  try {
33237
33361
  process.kill(pid, 0);
@@ -33242,7 +33366,7 @@ function isProcessAlive3(pid) {
33242
33366
  }
33243
33367
  function readRecentLogs(count8) {
33244
33368
  if (!existsSync77(voicePaths.log)) return [];
33245
- const lines2 = readFileSync58(voicePaths.log, "utf8").trim().split("\n");
33369
+ const lines2 = readFileSync59(voicePaths.log, "utf8").trim().split("\n");
33246
33370
  return lines2.slice(-count8);
33247
33371
  }
33248
33372
  function status2() {
@@ -33250,7 +33374,7 @@ function status2() {
33250
33374
  console.log("Voice daemon: not running (no PID file)");
33251
33375
  return;
33252
33376
  }
33253
- const pid = Number.parseInt(readFileSync58(voicePaths.pid, "utf8").trim(), 10);
33377
+ const pid = Number.parseInt(readFileSync59(voicePaths.pid, "utf8").trim(), 10);
33254
33378
  const alive = isProcessAlive3(pid);
33255
33379
  console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
33256
33380
  const recent = readRecentLogs(5);
@@ -33269,13 +33393,13 @@ function status2() {
33269
33393
  }
33270
33394
 
33271
33395
  // src/commands/voice/stop.ts
33272
- import { existsSync as existsSync78, readFileSync as readFileSync59, unlinkSync as unlinkSync20 } from "fs";
33396
+ import { existsSync as existsSync78, readFileSync as readFileSync60, unlinkSync as unlinkSync20 } from "fs";
33273
33397
  function stop2() {
33274
33398
  if (!existsSync78(voicePaths.pid)) {
33275
33399
  console.log("Voice daemon is not running (no PID file)");
33276
33400
  return;
33277
33401
  }
33278
- const pid = Number.parseInt(readFileSync59(voicePaths.pid, "utf8").trim(), 10);
33402
+ const pid = Number.parseInt(readFileSync60(voicePaths.pid, "utf8").trim(), 10);
33279
33403
  try {
33280
33404
  process.kill(pid, "SIGTERM");
33281
33405
  console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
@@ -33768,11 +33892,11 @@ function runCommandToCompletion(command, args, env, cwd, quiet) {
33768
33892
  }
33769
33893
 
33770
33894
  // src/commands/run/runPreCommands.ts
33771
- import { execSync as execSync60 } from "child_process";
33895
+ import { execSync as execSync61 } from "child_process";
33772
33896
  function runPreCommands(pre, cwd) {
33773
33897
  for (const cmd of pre) {
33774
33898
  try {
33775
- execSync60(cmd, { stdio: "inherit", cwd });
33899
+ execSync61(cmd, { stdio: "inherit", cwd });
33776
33900
  } catch (error) {
33777
33901
  const code = error && typeof error === "object" && "status" in error ? error.status : 1;
33778
33902
  process.exit(code);
@@ -34150,7 +34274,7 @@ async function auth() {
34150
34274
 
34151
34275
  // src/commands/roam/postRoamActivity.ts
34152
34276
  import { execFileSync as execFileSync20 } from "child_process";
34153
- import { readdirSync as readdirSync21, readFileSync as readFileSync60, statSync as statSync12 } from "fs";
34277
+ import { readdirSync as readdirSync21, readFileSync as readFileSync61, statSync as statSync12 } from "fs";
34154
34278
  import { join as join93 } from "path";
34155
34279
  function findPortFile(roamDir) {
34156
34280
  let entries;
@@ -34181,7 +34305,7 @@ function postRoamActivity(app, event) {
34181
34305
  if (!portFile) return;
34182
34306
  let port;
34183
34307
  try {
34184
- port = readFileSync60(portFile, "utf8").trim();
34308
+ port = readFileSync61(portFile, "utf8").trim();
34185
34309
  } catch {
34186
34310
  return;
34187
34311
  }
@@ -34499,7 +34623,7 @@ function registerRun(program2) {
34499
34623
  }
34500
34624
 
34501
34625
  // src/commands/screenshot/index.ts
34502
- import { execSync as execSync61 } from "child_process";
34626
+ import { execSync as execSync62 } from "child_process";
34503
34627
  import { existsSync as existsSync83, mkdirSync as mkdirSync33, unlinkSync as unlinkSync22, writeFileSync as writeFileSync51 } from "fs";
34504
34628
  import { tmpdir as tmpdir9 } from "os";
34505
34629
  import { join as join96, resolve as resolve21 } from "path";
@@ -34642,7 +34766,7 @@ function runPowerShellScript(processName, outputPath) {
34642
34766
  const scriptPath = join96(tmpdir9(), `assist-screenshot-${Date.now()}.ps1`);
34643
34767
  writeFileSync51(scriptPath, captureWindowPs1, "utf8");
34644
34768
  try {
34645
- execSync61(
34769
+ execSync62(
34646
34770
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
34647
34771
  { stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" }
34648
34772
  );
@@ -34716,11 +34840,11 @@ function applyLine(result, pending, line) {
34716
34840
  }
34717
34841
 
34718
34842
  // src/commands/sessions/daemon/readDaemonPidFile.ts
34719
- import { readFileSync as readFileSync61 } from "fs";
34843
+ import { readFileSync as readFileSync62 } from "fs";
34720
34844
  function readDaemonPidFile() {
34721
34845
  try {
34722
34846
  const pid = Number.parseInt(
34723
- readFileSync61(daemonPaths.pid, "utf8").trim(),
34847
+ readFileSync62(daemonPaths.pid, "utf8").trim(),
34724
34848
  10
34725
34849
  );
34726
34850
  return Number.isInteger(pid) ? pid : void 0;
@@ -38896,14 +39020,14 @@ async function defaultConnect() {
38896
39020
  }
38897
39021
 
38898
39022
  // src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
38899
- import { existsSync as existsSync95, readFileSync as readFileSync63 } from "fs";
39023
+ import { existsSync as existsSync95, readFileSync as readFileSync64 } from "fs";
38900
39024
  import { posix as posix3 } from "path";
38901
39025
  function hasPersistedWindowsSessions() {
38902
39026
  const sessionsFile = windowsSessionsFileFromWsl();
38903
39027
  if (!sessionsFile) return false;
38904
39028
  try {
38905
39029
  if (!existsSync95(sessionsFile)) return false;
38906
- const data = JSON.parse(readFileSync63(sessionsFile, "utf8"));
39030
+ const data = JSON.parse(readFileSync64(sessionsFile, "utf8"));
38907
39031
  return Array.isArray(data) && data.length > 0;
38908
39032
  } catch (error) {
38909
39033
  const message3 = error instanceof Error ? error.message : String(error);
@@ -40328,7 +40452,7 @@ function handleConnection(socket, manager) {
40328
40452
  import { unlinkSync as unlinkSync23, writeFileSync as writeFileSync52 } from "fs";
40329
40453
 
40330
40454
  // src/commands/sessions/daemon/startPidFileWatchdog.ts
40331
- import { readFileSync as readFileSync64 } from "fs";
40455
+ import { readFileSync as readFileSync65 } from "fs";
40332
40456
  var WATCHDOG_INTERVAL_MS = 5e3;
40333
40457
  function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
40334
40458
  const timer = setInterval(() => {
@@ -40339,7 +40463,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
40339
40463
  }
40340
40464
  function ownsPidFile() {
40341
40465
  try {
40342
- return readFileSync64(daemonPaths.pid, "utf8").trim() === String(process.pid);
40466
+ return readFileSync65(daemonPaths.pid, "utf8").trim() === String(process.pid);
40343
40467
  } catch {
40344
40468
  return false;
40345
40469
  }
@@ -40832,7 +40956,7 @@ function buildLimitsSegment(rateLimits) {
40832
40956
  }
40833
40957
 
40834
40958
  // src/commands/readGitBranch.ts
40835
- import { readFileSync as readFileSync66, statSync as statSync16 } from "fs";
40959
+ import { readFileSync as readFileSync67, statSync as statSync16 } from "fs";
40836
40960
  import { isAbsolute as isAbsolute5, join as join102, resolve as resolve23 } from "path";
40837
40961
  function resolveGitDir(cwd) {
40838
40962
  const dotGit = join102(cwd, ".git");
@@ -40847,7 +40971,7 @@ function resolveGitDir(cwd) {
40847
40971
  }
40848
40972
  let contents;
40849
40973
  try {
40850
- contents = readFileSync66(dotGit, "utf8");
40974
+ contents = readFileSync67(dotGit, "utf8");
40851
40975
  } catch {
40852
40976
  return null;
40853
40977
  }
@@ -40865,7 +40989,7 @@ function readGitBranch(cwd) {
40865
40989
  }
40866
40990
  let head;
40867
40991
  try {
40868
- head = readFileSync66(join102(gitDir, "HEAD"), "utf8");
40992
+ head = readFileSync67(join102(gitDir, "HEAD"), "utf8");
40869
40993
  } catch {
40870
40994
  return null;
40871
40995
  }
@@ -40933,7 +41057,7 @@ async function statusLine() {
40933
41057
  }
40934
41058
 
40935
41059
  // src/commands/update.ts
40936
- import { execSync as execSync62 } from "child_process";
41060
+ import { execSync as execSync63 } from "child_process";
40937
41061
  import * as path89 from "path";
40938
41062
 
40939
41063
  // src/commands/restartDaemonAfterUpdate.ts
@@ -40957,7 +41081,7 @@ function isGlobalNpmInstall(dir) {
40957
41081
  if (resolved.split(path89.sep).includes("node_modules")) {
40958
41082
  return true;
40959
41083
  }
40960
- const globalPrefix = execSync62("npm prefix -g", { stdio: "pipe" }).toString().trim();
41084
+ const globalPrefix = execSync63("npm prefix -g", { stdio: "pipe" }).toString().trim();
40961
41085
  return resolved.toLowerCase().startsWith(path89.resolve(globalPrefix).toLowerCase());
40962
41086
  } catch {
40963
41087
  return false;
@@ -40968,18 +41092,18 @@ async function update2() {
40968
41092
  console.log(`Assist is installed at: ${installDir}`);
40969
41093
  if (isGitRepo(installDir)) {
40970
41094
  console.log("Detected git repo installation, pulling latest...");
40971
- execSync62("git pull", { cwd: installDir, stdio: "inherit" });
41095
+ execSync63("git pull", { cwd: installDir, stdio: "inherit" });
40972
41096
  console.log("Installing dependencies...");
40973
- execSync62("npm i", { cwd: installDir, stdio: "inherit" });
41097
+ execSync63("npm i", { cwd: installDir, stdio: "inherit" });
40974
41098
  console.log("Building...");
40975
- execSync62("npm run build", { cwd: installDir, stdio: "inherit" });
41099
+ execSync63("npm run build", { cwd: installDir, stdio: "inherit" });
40976
41100
  console.log("Syncing commands...");
40977
- execSync62("assist sync", { stdio: "inherit" });
41101
+ execSync63("assist sync", { stdio: "inherit" });
40978
41102
  } else if (isGlobalNpmInstall(installDir)) {
40979
41103
  console.log("Detected global npm installation, updating...");
40980
- execSync62("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
41104
+ execSync63("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
40981
41105
  console.log("Syncing commands...");
40982
- execSync62("assist sync", { stdio: "inherit" });
41106
+ execSync63("assist sync", { stdio: "inherit" });
40983
41107
  } else {
40984
41108
  console.error(
40985
41109
  "Could not determine installation method. Expected a git repo or global npm install."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.626.0",
3
+ "version": "0.628.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {