@staff0rd/assist 0.626.0 → 0.627.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.627.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -26601,6 +26601,83 @@ 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/formatReadDuration.ts
26609
+ function formatReadDuration(seconds) {
26610
+ if (seconds < 60) return `${seconds}s`;
26611
+ const minutes = Math.floor(seconds / 60);
26612
+ const remainder = seconds % 60;
26613
+ return remainder === 0 ? `${minutes}m` : `${minutes}m ${remainder}s`;
26614
+ }
26615
+
26616
+ // src/commands/prs/resolveReadTimeTarget.ts
26617
+ var PR_URL_PATTERN = /^(https:\/\/github\.com\/[^/\s]+\/[^/\s]+)\/pull\/(\d+)(?:[/?#].*)?$/;
26618
+ function resolveReadTimeTarget(target) {
26619
+ const trimmed = target.trim();
26620
+ if (trimmed === "-") return { kind: "stdin" };
26621
+ if (/^\d+$/.test(trimmed)) {
26622
+ return { kind: "pr", number: Number(trimmed), repo: null };
26623
+ }
26624
+ const url = PR_URL_PATTERN.exec(trimmed);
26625
+ if (url) {
26626
+ const repo = parseGitHubUrl(url[1]);
26627
+ if (repo) return { kind: "pr", number: Number(url[2]), repo };
26628
+ }
26629
+ return { kind: "file", path: target };
26630
+ }
26631
+
26632
+ // src/commands/prs/readTime.ts
26633
+ var WORDS_PER_MINUTE = 200;
26634
+ async function readTime(target) {
26635
+ const body = await loadBody(resolveReadTimeTarget(target));
26636
+ const words = countWords(body);
26637
+ const seconds = Math.round(words / WORDS_PER_MINUTE * 60);
26638
+ const label2 = words === 1 ? "word" : "words";
26639
+ console.log(`${words} ${label2} \xB7 ~${formatReadDuration(seconds)} read`);
26640
+ }
26641
+ function countWords(body) {
26642
+ return body.split(/\s+/).filter(Boolean).length;
26643
+ }
26644
+ async function loadBody(target) {
26645
+ if (target.kind === "stdin") return readBodyArgument("-");
26646
+ if (target.kind === "file") return readDraftFile(target.path);
26647
+ return fetchPrBody(target.number, target.repo);
26648
+ }
26649
+ function readDraftFile(path90) {
26650
+ try {
26651
+ return readFileSync45(path90, "utf8");
26652
+ } catch {
26653
+ console.error(`Error: Could not read \`${path90}\`.`);
26654
+ console.error(
26655
+ "Pass a pull request number, a GitHub pull request URL, - for stdin, or a path to a file."
26656
+ );
26657
+ process.exit(1);
26658
+ }
26659
+ }
26660
+ function fetchPrBody(number, repo) {
26661
+ const { org, repo: name } = repo ?? getRepoInfo();
26662
+ try {
26663
+ const raw = execSync51(`gh pr view ${number} --json body -R ${org}/${name}`, {
26664
+ encoding: "utf8"
26665
+ });
26666
+ return JSON.parse(raw).body ?? "";
26667
+ } catch (error) {
26668
+ if (isGhNotInstalled(error)) {
26669
+ console.error("Error: GitHub CLI (gh) is not installed.");
26670
+ console.error("Install it from https://cli.github.com/");
26671
+ process.exit(1);
26672
+ }
26673
+ if (isNotFound(error)) {
26674
+ console.error(`Error: Pull request ${org}/${name}#${number} not found.`);
26675
+ process.exit(1);
26676
+ }
26677
+ throw error;
26678
+ }
26679
+ }
26680
+
26604
26681
  // src/commands/prs/reply.ts
26605
26682
  function validateBody2(body) {
26606
26683
  const lowerBody = body.toLowerCase();
@@ -26628,7 +26705,7 @@ async function reply(commentId, body) {
26628
26705
  }
26629
26706
 
26630
26707
  // src/commands/prs/wontfix.ts
26631
- import { execSync as execSync51 } from "child_process";
26708
+ import { execSync as execSync52 } from "child_process";
26632
26709
  function validateReason(reason4) {
26633
26710
  const lowerReason = reason4.toLowerCase();
26634
26711
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -26645,7 +26722,7 @@ function validateShaReferences(reason4) {
26645
26722
  const invalidShas = [];
26646
26723
  for (const sha of shas) {
26647
26724
  try {
26648
- execSync51(`git cat-file -t ${sha}`, { stdio: "pipe" });
26725
+ execSync52(`git cat-file -t ${sha}`, { stdio: "pipe" });
26649
26726
  } catch {
26650
26727
  invalidShas.push(sha);
26651
26728
  }
@@ -26912,12 +26989,22 @@ function registerPrsRaise(prsCommand) {
26912
26989
  configHelp(raiseCommand, prsRaiseConfigHelp);
26913
26990
  }
26914
26991
 
26992
+ // src/commands/registerPrsReadTime.ts
26993
+ function registerPrsReadTime(prsCommand) {
26994
+ prsCommand.command("read-time <target>").description(
26995
+ "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)"
26996
+ ).action(async (target) => {
26997
+ await readTime(target);
26998
+ });
26999
+ }
27000
+
26915
27001
  // src/commands/registerPrs.ts
26916
27002
  function registerPrs(program2) {
26917
27003
  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
27004
  registerPrsRaise(prsCommand);
26919
27005
  registerPrsEdit(prsCommand);
26920
27006
  registerPrsComments(prsCommand);
27007
+ registerPrsReadTime(prsCommand);
26921
27008
  configHelp(prsCommand, prsConfigHelp);
26922
27009
  }
26923
27010
 
@@ -26991,10 +27078,10 @@ import chalk187 from "chalk";
26991
27078
  import Enquirer2 from "enquirer";
26992
27079
 
26993
27080
  // src/commands/ravendb/searchItems.ts
26994
- import { execSync as execSync52 } from "child_process";
27081
+ import { execSync as execSync53 } from "child_process";
26995
27082
  import chalk186 from "chalk";
26996
27083
  function opExec(args) {
26997
- return execSync52(`op ${args}`, {
27084
+ return execSync53(`op ${args}`, {
26998
27085
  encoding: "utf8",
26999
27086
  stdio: ["pipe", "pipe", "pipe"]
27000
27087
  }).trim();
@@ -27146,7 +27233,7 @@ ${errorText}`
27146
27233
  }
27147
27234
 
27148
27235
  // src/commands/ravendb/resolveOpSecret.ts
27149
- import { execSync as execSync53 } from "child_process";
27236
+ import { execSync as execSync54 } from "child_process";
27150
27237
  import chalk191 from "chalk";
27151
27238
  function resolveOpSecret(reference) {
27152
27239
  if (!reference.startsWith("op://")) {
@@ -27154,7 +27241,7 @@ function resolveOpSecret(reference) {
27154
27241
  process.exit(1);
27155
27242
  }
27156
27243
  try {
27157
- return execSync53(`op read "${reference}"`, {
27244
+ return execSync54(`op read "${reference}"`, {
27158
27245
  encoding: "utf8",
27159
27246
  stdio: ["pipe", "pipe", "pipe"]
27160
27247
  }).trim();
@@ -27404,7 +27491,7 @@ Refactor check failed:
27404
27491
  }
27405
27492
 
27406
27493
  // src/commands/refactor/check/getViolations/index.ts
27407
- import { execSync as execSync54 } from "child_process";
27494
+ import { execSync as execSync55 } from "child_process";
27408
27495
  import fs30 from "fs";
27409
27496
  import { minimatch as minimatch6 } from "minimatch";
27410
27497
 
@@ -27454,7 +27541,7 @@ function getGitFiles(options2) {
27454
27541
  }
27455
27542
  const files = /* @__PURE__ */ new Set();
27456
27543
  if (options2.staged || options2.modified) {
27457
- const staged = execSync54("git diff --cached --name-only", {
27544
+ const staged = execSync55("git diff --cached --name-only", {
27458
27545
  encoding: "utf8"
27459
27546
  });
27460
27547
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -27462,7 +27549,7 @@ function getGitFiles(options2) {
27462
27549
  }
27463
27550
  }
27464
27551
  if (options2.unstaged || options2.modified) {
27465
- const unstaged = execSync54("git diff --name-only", { encoding: "utf8" });
27552
+ const unstaged = execSync55("git diff --name-only", { encoding: "utf8" });
27466
27553
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
27467
27554
  files.add(file);
27468
27555
  }
@@ -29173,9 +29260,9 @@ function buildReviewPaths(repoRoot2, key) {
29173
29260
  }
29174
29261
 
29175
29262
  // src/commands/review/fetchExistingComments.ts
29176
- import { execSync as execSync55 } from "child_process";
29263
+ import { execSync as execSync56 } from "child_process";
29177
29264
  function fetchRawComments(org, repo, prNumber) {
29178
- const out = execSync55(
29265
+ const out = execSync56(
29179
29266
  `gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
29180
29267
  { encoding: "utf8", maxBuffer: 64 * 1024 * 1024 }
29181
29268
  );
@@ -29206,14 +29293,14 @@ function fetchExistingComments() {
29206
29293
  }
29207
29294
 
29208
29295
  // src/commands/review/gatherContext.ts
29209
- import { execSync as execSync58 } from "child_process";
29296
+ import { execSync as execSync59 } from "child_process";
29210
29297
 
29211
29298
  // src/commands/review/fetchPrDiff.ts
29212
- import { execSync as execSync56 } from "child_process";
29299
+ import { execSync as execSync57 } from "child_process";
29213
29300
  function fetchPrDiff(prNumber, baseSha, headSha) {
29214
29301
  const { org, repo } = getRepoInfo();
29215
29302
  try {
29216
- return execSync56(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
29303
+ return execSync57(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
29217
29304
  encoding: "utf8",
29218
29305
  maxBuffer: 256 * 1024 * 1024,
29219
29306
  stdio: ["ignore", "pipe", "pipe"]
@@ -29228,19 +29315,19 @@ function isDiffTooLarge(error) {
29228
29315
  }
29229
29316
  function fetchDiffViaGit(baseSha, headSha) {
29230
29317
  try {
29231
- execSync56(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
29318
+ execSync57(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
29232
29319
  } catch {
29233
29320
  }
29234
- return execSync56(`git diff ${baseSha}...${headSha}`, {
29321
+ return execSync57(`git diff ${baseSha}...${headSha}`, {
29235
29322
  encoding: "utf8",
29236
29323
  maxBuffer: 256 * 1024 * 1024
29237
29324
  });
29238
29325
  }
29239
29326
 
29240
29327
  // src/commands/review/fetchPrDiffInfo.ts
29241
- import { execSync as execSync57 } from "child_process";
29328
+ import { execSync as execSync58 } from "child_process";
29242
29329
  function getCurrentBranch3() {
29243
- return execSync57("git rev-parse --abbrev-ref HEAD", {
29330
+ return execSync58("git rev-parse --abbrev-ref HEAD", {
29244
29331
  encoding: "utf8"
29245
29332
  }).trim();
29246
29333
  }
@@ -29248,7 +29335,7 @@ function fetchPrDiffInfo() {
29248
29335
  const { org, repo } = getRepoInfo();
29249
29336
  const branch2 = getCurrentBranch3();
29250
29337
  const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
29251
- const raw = execSync57(
29338
+ const raw = execSync58(
29252
29339
  `gh pr list --state open --head ${branch2} --json ${fields} -R ${org}/${repo}`,
29253
29340
  {
29254
29341
  encoding: "utf8",
@@ -29273,7 +29360,7 @@ function fetchPrDiffInfo() {
29273
29360
  }
29274
29361
  function fetchPrChangedFiles(prNumber) {
29275
29362
  const { org, repo } = getRepoInfo();
29276
- const out = execSync57(
29363
+ const out = execSync58(
29277
29364
  `gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
29278
29365
  {
29279
29366
  encoding: "utf8",
@@ -29285,11 +29372,11 @@ function fetchPrChangedFiles(prNumber) {
29285
29372
 
29286
29373
  // src/commands/review/gatherContext.ts
29287
29374
  function gatherContext() {
29288
- const branch2 = execSync58("git rev-parse --abbrev-ref HEAD", {
29375
+ const branch2 = execSync59("git rev-parse --abbrev-ref HEAD", {
29289
29376
  encoding: "utf8"
29290
29377
  }).trim();
29291
- const sha = execSync58("git rev-parse HEAD", { encoding: "utf8" }).trim();
29292
- const shortSha = execSync58("git rev-parse --short=7 HEAD", {
29378
+ const sha = execSync59("git rev-parse HEAD", { encoding: "utf8" }).trim();
29379
+ const shortSha = execSync59("git rev-parse --short=7 HEAD", {
29293
29380
  encoding: "utf8"
29294
29381
  }).trim();
29295
29382
  const prInfo = fetchPrDiffInfo();
@@ -29310,7 +29397,7 @@ function gatherContext() {
29310
29397
  }
29311
29398
 
29312
29399
  // src/commands/review/postReviewToPr.ts
29313
- import { readFileSync as readFileSync45 } from "fs";
29400
+ import { readFileSync as readFileSync46 } from "fs";
29314
29401
 
29315
29402
  // src/commands/review/carriedUnanchoredFindings.ts
29316
29403
  function carriedUnanchoredFindings(unanchored) {
@@ -29758,7 +29845,7 @@ async function confirmPost(prNumber, work, options2) {
29758
29845
  return promptConfirm(`Post ${work} to PR #${prNumber}?`, false);
29759
29846
  }
29760
29847
  async function postFindingsToPr(prInfo, synthesisPath, options2) {
29761
- const markdown = readFileSync45(synthesisPath, "utf8");
29848
+ const markdown = readFileSync46(synthesisPath, "utf8");
29762
29849
  const { inDiff, unanchored } = selectPostableFindings(markdown, prInfo);
29763
29850
  const carried = carriedUnanchoredFindings(unanchored);
29764
29851
  if (inDiff.length === 0 && carried.length === 0) return NOTHING_POSTED;
@@ -30647,7 +30734,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
30647
30734
  }
30648
30735
 
30649
30736
  // src/commands/review/synthesise.ts
30650
- import { readFileSync as readFileSync46 } from "fs";
30737
+ import { readFileSync as readFileSync47 } from "fs";
30651
30738
 
30652
30739
  // src/commands/review/buildSynthesisStdin.ts
30653
30740
  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 +30799,7 @@ Files:
30712
30799
 
30713
30800
  // src/commands/review/synthesise.ts
30714
30801
  function printSummary2(synthesisPath) {
30715
- const markdown = readFileSync46(synthesisPath, "utf8");
30802
+ const markdown = readFileSync47(synthesisPath, "utf8");
30716
30803
  console.log("");
30717
30804
  console.log(buildReviewSummary(markdown));
30718
30805
  console.log("");
@@ -30946,7 +31033,7 @@ function registerReview(program2) {
30946
31033
  }
30947
31034
 
30948
31035
  // src/commands/rules/addRule.ts
30949
- import { existsSync as existsSync66, readFileSync as readFileSync50, writeFileSync as writeFileSync41 } from "fs";
31036
+ import { existsSync as existsSync66, readFileSync as readFileSync51, writeFileSync as writeFileSync41 } from "fs";
30950
31037
  import path71 from "path";
30951
31038
  import chalk211 from "chalk";
30952
31039
 
@@ -30971,7 +31058,7 @@ function insertRuleBullet(content, rule) {
30971
31058
  }
30972
31059
 
30973
31060
  // src/commands/rules/nextRuleCode.ts
30974
- import { readFileSync as readFileSync47 } from "fs";
31061
+ import { readFileSync as readFileSync48 } from "fs";
30975
31062
 
30976
31063
  // src/commands/rules/findClaudeFiles.ts
30977
31064
  import { readdirSync as readdirSync13 } from "fs";
@@ -30995,7 +31082,7 @@ function findClaudeFiles(dir) {
30995
31082
  var CODE_PREFIX = "R";
30996
31083
  function nextRuleCode(root) {
30997
31084
  const numbers = findClaudeFiles(root).flatMap(
30998
- (file) => parseRulesSection(readFileSync47(file, "utf8")).map(
31085
+ (file) => parseRulesSection(readFileSync48(file, "utf8")).map(
30999
31086
  (rule) => Number(/(\d+)\s*$/.exec(rule.code)?.[1] ?? 0)
31000
31087
  )
31001
31088
  );
@@ -31021,15 +31108,15 @@ function resolveRuleScope(target) {
31021
31108
  }
31022
31109
 
31023
31110
  // src/commands/rules/updateScopedRulesIndex.ts
31024
- import { existsSync as existsSync65, readFileSync as readFileSync49, writeFileSync as writeFileSync40 } from "fs";
31111
+ import { existsSync as existsSync65, readFileSync as readFileSync50, writeFileSync as writeFileSync40 } from "fs";
31025
31112
  import path70 from "path";
31026
31113
 
31027
31114
  // src/commands/rules/scopedRuleDirectories.ts
31028
- import { readFileSync as readFileSync48 } from "fs";
31115
+ import { readFileSync as readFileSync49 } from "fs";
31029
31116
  import path69 from "path";
31030
31117
  function scopedRuleDirectories(root) {
31031
31118
  return findClaudeFiles(root).filter(
31032
- (file) => path69.dirname(file) !== root && parseRulesSection(readFileSync48(file, "utf8")).length > 0
31119
+ (file) => path69.dirname(file) !== root && parseRulesSection(readFileSync49(file, "utf8")).length > 0
31033
31120
  ).map(
31034
31121
  (file) => `${path69.relative(root, path69.dirname(file)).split(path69.sep).join("/")}/`
31035
31122
  ).sort();
@@ -31071,7 +31158,7 @@ function upsertScopedRulesPointer(content, directories) {
31071
31158
  function updateScopedRulesIndex(root) {
31072
31159
  const directories = scopedRuleDirectories(root);
31073
31160
  const rootFile = path70.join(root, "CLAUDE.md");
31074
- const before = existsSync65(rootFile) ? readFileSync49(rootFile, "utf8") : "";
31161
+ const before = existsSync65(rootFile) ? readFileSync50(rootFile, "utf8") : "";
31075
31162
  const after = upsertScopedRulesPointer(before, directories);
31076
31163
  if (after !== before) writeFileSync40(rootFile, after);
31077
31164
  return directories;
@@ -31079,7 +31166,7 @@ function updateScopedRulesIndex(root) {
31079
31166
 
31080
31167
  // src/commands/rules/addRule.ts
31081
31168
  function read2(file) {
31082
- return existsSync66(file) ? readFileSync50(file, "utf8") : "";
31169
+ return existsSync66(file) ? readFileSync51(file, "utf8") : "";
31083
31170
  }
31084
31171
  function addRule(text18, options2) {
31085
31172
  const rule = text18.trim();
@@ -32572,9 +32659,9 @@ function formatVttPassages(passages, notes = [], { sourceMarks = true } = {}) {
32572
32659
  }
32573
32660
 
32574
32661
  // src/commands/transcript/convert/readCleanedCues.ts
32575
- import { readFileSync as readFileSync55 } from "fs";
32662
+ import { readFileSync as readFileSync56 } from "fs";
32576
32663
  function readCleanedCues(inputPath) {
32577
- return deduplicateCues(parseVtt(readFileSync55(inputPath, "utf8")));
32664
+ return deduplicateCues(parseVtt(readFileSync56(inputPath, "utf8")));
32578
32665
  }
32579
32666
 
32580
32667
  // src/commands/transcript/clean.ts
@@ -33081,14 +33168,14 @@ function devices() {
33081
33168
  }
33082
33169
 
33083
33170
  // src/commands/voice/logs.ts
33084
- import { existsSync as existsSync75, readFileSync as readFileSync56 } from "fs";
33171
+ import { existsSync as existsSync75, readFileSync as readFileSync57 } from "fs";
33085
33172
  function logs(options2) {
33086
33173
  if (!existsSync75(voicePaths.log)) {
33087
33174
  console.log("No voice log file found");
33088
33175
  return;
33089
33176
  }
33090
33177
  const count8 = Number.parseInt(options2.lines ?? "150", 10);
33091
- const content = readFileSync56(voicePaths.log, "utf8").trim();
33178
+ const content = readFileSync57(voicePaths.log, "utf8").trim();
33092
33179
  if (!content) {
33093
33180
  console.log("Voice log is empty");
33094
33181
  return;
@@ -33114,8 +33201,8 @@ import { mkdirSync as mkdirSync30 } from "fs";
33114
33201
  import { join as join89 } from "path";
33115
33202
 
33116
33203
  // 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";
33204
+ import { execSync as execSync60 } from "child_process";
33205
+ import { existsSync as existsSync76, mkdirSync as mkdirSync29, readFileSync as readFileSync58, writeFileSync as writeFileSync48 } from "fs";
33119
33206
  import { join as join88 } from "path";
33120
33207
  function isProcessAlive2(pid) {
33121
33208
  try {
@@ -33129,7 +33216,7 @@ function checkLockFile() {
33129
33216
  const lockFile = getLockFile();
33130
33217
  if (!existsSync76(lockFile)) return;
33131
33218
  try {
33132
- const lock2 = JSON.parse(readFileSync57(lockFile, "utf8"));
33219
+ const lock2 = JSON.parse(readFileSync58(lockFile, "utf8"));
33133
33220
  if (lock2.pid && isProcessAlive2(lock2.pid)) {
33134
33221
  console.error(
33135
33222
  `Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
@@ -33143,7 +33230,7 @@ function bootstrapVenv() {
33143
33230
  if (existsSync76(getVenvPython())) return;
33144
33231
  console.log("Setting up Python environment...");
33145
33232
  const pythonDir = getPythonDir();
33146
- execSync59(
33233
+ execSync60(
33147
33234
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
33148
33235
  {
33149
33236
  stdio: "inherit",
@@ -33231,7 +33318,7 @@ function start2(options2) {
33231
33318
  }
33232
33319
 
33233
33320
  // src/commands/voice/status.ts
33234
- import { existsSync as existsSync77, readFileSync as readFileSync58 } from "fs";
33321
+ import { existsSync as existsSync77, readFileSync as readFileSync59 } from "fs";
33235
33322
  function isProcessAlive3(pid) {
33236
33323
  try {
33237
33324
  process.kill(pid, 0);
@@ -33242,7 +33329,7 @@ function isProcessAlive3(pid) {
33242
33329
  }
33243
33330
  function readRecentLogs(count8) {
33244
33331
  if (!existsSync77(voicePaths.log)) return [];
33245
- const lines2 = readFileSync58(voicePaths.log, "utf8").trim().split("\n");
33332
+ const lines2 = readFileSync59(voicePaths.log, "utf8").trim().split("\n");
33246
33333
  return lines2.slice(-count8);
33247
33334
  }
33248
33335
  function status2() {
@@ -33250,7 +33337,7 @@ function status2() {
33250
33337
  console.log("Voice daemon: not running (no PID file)");
33251
33338
  return;
33252
33339
  }
33253
- const pid = Number.parseInt(readFileSync58(voicePaths.pid, "utf8").trim(), 10);
33340
+ const pid = Number.parseInt(readFileSync59(voicePaths.pid, "utf8").trim(), 10);
33254
33341
  const alive = isProcessAlive3(pid);
33255
33342
  console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
33256
33343
  const recent = readRecentLogs(5);
@@ -33269,13 +33356,13 @@ function status2() {
33269
33356
  }
33270
33357
 
33271
33358
  // src/commands/voice/stop.ts
33272
- import { existsSync as existsSync78, readFileSync as readFileSync59, unlinkSync as unlinkSync20 } from "fs";
33359
+ import { existsSync as existsSync78, readFileSync as readFileSync60, unlinkSync as unlinkSync20 } from "fs";
33273
33360
  function stop2() {
33274
33361
  if (!existsSync78(voicePaths.pid)) {
33275
33362
  console.log("Voice daemon is not running (no PID file)");
33276
33363
  return;
33277
33364
  }
33278
- const pid = Number.parseInt(readFileSync59(voicePaths.pid, "utf8").trim(), 10);
33365
+ const pid = Number.parseInt(readFileSync60(voicePaths.pid, "utf8").trim(), 10);
33279
33366
  try {
33280
33367
  process.kill(pid, "SIGTERM");
33281
33368
  console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
@@ -33768,11 +33855,11 @@ function runCommandToCompletion(command, args, env, cwd, quiet) {
33768
33855
  }
33769
33856
 
33770
33857
  // src/commands/run/runPreCommands.ts
33771
- import { execSync as execSync60 } from "child_process";
33858
+ import { execSync as execSync61 } from "child_process";
33772
33859
  function runPreCommands(pre, cwd) {
33773
33860
  for (const cmd of pre) {
33774
33861
  try {
33775
- execSync60(cmd, { stdio: "inherit", cwd });
33862
+ execSync61(cmd, { stdio: "inherit", cwd });
33776
33863
  } catch (error) {
33777
33864
  const code = error && typeof error === "object" && "status" in error ? error.status : 1;
33778
33865
  process.exit(code);
@@ -34150,7 +34237,7 @@ async function auth() {
34150
34237
 
34151
34238
  // src/commands/roam/postRoamActivity.ts
34152
34239
  import { execFileSync as execFileSync20 } from "child_process";
34153
- import { readdirSync as readdirSync21, readFileSync as readFileSync60, statSync as statSync12 } from "fs";
34240
+ import { readdirSync as readdirSync21, readFileSync as readFileSync61, statSync as statSync12 } from "fs";
34154
34241
  import { join as join93 } from "path";
34155
34242
  function findPortFile(roamDir) {
34156
34243
  let entries;
@@ -34181,7 +34268,7 @@ function postRoamActivity(app, event) {
34181
34268
  if (!portFile) return;
34182
34269
  let port;
34183
34270
  try {
34184
- port = readFileSync60(portFile, "utf8").trim();
34271
+ port = readFileSync61(portFile, "utf8").trim();
34185
34272
  } catch {
34186
34273
  return;
34187
34274
  }
@@ -34499,7 +34586,7 @@ function registerRun(program2) {
34499
34586
  }
34500
34587
 
34501
34588
  // src/commands/screenshot/index.ts
34502
- import { execSync as execSync61 } from "child_process";
34589
+ import { execSync as execSync62 } from "child_process";
34503
34590
  import { existsSync as existsSync83, mkdirSync as mkdirSync33, unlinkSync as unlinkSync22, writeFileSync as writeFileSync51 } from "fs";
34504
34591
  import { tmpdir as tmpdir9 } from "os";
34505
34592
  import { join as join96, resolve as resolve21 } from "path";
@@ -34642,7 +34729,7 @@ function runPowerShellScript(processName, outputPath) {
34642
34729
  const scriptPath = join96(tmpdir9(), `assist-screenshot-${Date.now()}.ps1`);
34643
34730
  writeFileSync51(scriptPath, captureWindowPs1, "utf8");
34644
34731
  try {
34645
- execSync61(
34732
+ execSync62(
34646
34733
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
34647
34734
  { stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" }
34648
34735
  );
@@ -34716,11 +34803,11 @@ function applyLine(result, pending, line) {
34716
34803
  }
34717
34804
 
34718
34805
  // src/commands/sessions/daemon/readDaemonPidFile.ts
34719
- import { readFileSync as readFileSync61 } from "fs";
34806
+ import { readFileSync as readFileSync62 } from "fs";
34720
34807
  function readDaemonPidFile() {
34721
34808
  try {
34722
34809
  const pid = Number.parseInt(
34723
- readFileSync61(daemonPaths.pid, "utf8").trim(),
34810
+ readFileSync62(daemonPaths.pid, "utf8").trim(),
34724
34811
  10
34725
34812
  );
34726
34813
  return Number.isInteger(pid) ? pid : void 0;
@@ -38896,14 +38983,14 @@ async function defaultConnect() {
38896
38983
  }
38897
38984
 
38898
38985
  // src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
38899
- import { existsSync as existsSync95, readFileSync as readFileSync63 } from "fs";
38986
+ import { existsSync as existsSync95, readFileSync as readFileSync64 } from "fs";
38900
38987
  import { posix as posix3 } from "path";
38901
38988
  function hasPersistedWindowsSessions() {
38902
38989
  const sessionsFile = windowsSessionsFileFromWsl();
38903
38990
  if (!sessionsFile) return false;
38904
38991
  try {
38905
38992
  if (!existsSync95(sessionsFile)) return false;
38906
- const data = JSON.parse(readFileSync63(sessionsFile, "utf8"));
38993
+ const data = JSON.parse(readFileSync64(sessionsFile, "utf8"));
38907
38994
  return Array.isArray(data) && data.length > 0;
38908
38995
  } catch (error) {
38909
38996
  const message3 = error instanceof Error ? error.message : String(error);
@@ -40328,7 +40415,7 @@ function handleConnection(socket, manager) {
40328
40415
  import { unlinkSync as unlinkSync23, writeFileSync as writeFileSync52 } from "fs";
40329
40416
 
40330
40417
  // src/commands/sessions/daemon/startPidFileWatchdog.ts
40331
- import { readFileSync as readFileSync64 } from "fs";
40418
+ import { readFileSync as readFileSync65 } from "fs";
40332
40419
  var WATCHDOG_INTERVAL_MS = 5e3;
40333
40420
  function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
40334
40421
  const timer = setInterval(() => {
@@ -40339,7 +40426,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
40339
40426
  }
40340
40427
  function ownsPidFile() {
40341
40428
  try {
40342
- return readFileSync64(daemonPaths.pid, "utf8").trim() === String(process.pid);
40429
+ return readFileSync65(daemonPaths.pid, "utf8").trim() === String(process.pid);
40343
40430
  } catch {
40344
40431
  return false;
40345
40432
  }
@@ -40832,7 +40919,7 @@ function buildLimitsSegment(rateLimits) {
40832
40919
  }
40833
40920
 
40834
40921
  // src/commands/readGitBranch.ts
40835
- import { readFileSync as readFileSync66, statSync as statSync16 } from "fs";
40922
+ import { readFileSync as readFileSync67, statSync as statSync16 } from "fs";
40836
40923
  import { isAbsolute as isAbsolute5, join as join102, resolve as resolve23 } from "path";
40837
40924
  function resolveGitDir(cwd) {
40838
40925
  const dotGit = join102(cwd, ".git");
@@ -40847,7 +40934,7 @@ function resolveGitDir(cwd) {
40847
40934
  }
40848
40935
  let contents;
40849
40936
  try {
40850
- contents = readFileSync66(dotGit, "utf8");
40937
+ contents = readFileSync67(dotGit, "utf8");
40851
40938
  } catch {
40852
40939
  return null;
40853
40940
  }
@@ -40865,7 +40952,7 @@ function readGitBranch(cwd) {
40865
40952
  }
40866
40953
  let head;
40867
40954
  try {
40868
- head = readFileSync66(join102(gitDir, "HEAD"), "utf8");
40955
+ head = readFileSync67(join102(gitDir, "HEAD"), "utf8");
40869
40956
  } catch {
40870
40957
  return null;
40871
40958
  }
@@ -40933,7 +41020,7 @@ async function statusLine() {
40933
41020
  }
40934
41021
 
40935
41022
  // src/commands/update.ts
40936
- import { execSync as execSync62 } from "child_process";
41023
+ import { execSync as execSync63 } from "child_process";
40937
41024
  import * as path89 from "path";
40938
41025
 
40939
41026
  // src/commands/restartDaemonAfterUpdate.ts
@@ -40957,7 +41044,7 @@ function isGlobalNpmInstall(dir) {
40957
41044
  if (resolved.split(path89.sep).includes("node_modules")) {
40958
41045
  return true;
40959
41046
  }
40960
- const globalPrefix = execSync62("npm prefix -g", { stdio: "pipe" }).toString().trim();
41047
+ const globalPrefix = execSync63("npm prefix -g", { stdio: "pipe" }).toString().trim();
40961
41048
  return resolved.toLowerCase().startsWith(path89.resolve(globalPrefix).toLowerCase());
40962
41049
  } catch {
40963
41050
  return false;
@@ -40968,18 +41055,18 @@ async function update2() {
40968
41055
  console.log(`Assist is installed at: ${installDir}`);
40969
41056
  if (isGitRepo(installDir)) {
40970
41057
  console.log("Detected git repo installation, pulling latest...");
40971
- execSync62("git pull", { cwd: installDir, stdio: "inherit" });
41058
+ execSync63("git pull", { cwd: installDir, stdio: "inherit" });
40972
41059
  console.log("Installing dependencies...");
40973
- execSync62("npm i", { cwd: installDir, stdio: "inherit" });
41060
+ execSync63("npm i", { cwd: installDir, stdio: "inherit" });
40974
41061
  console.log("Building...");
40975
- execSync62("npm run build", { cwd: installDir, stdio: "inherit" });
41062
+ execSync63("npm run build", { cwd: installDir, stdio: "inherit" });
40976
41063
  console.log("Syncing commands...");
40977
- execSync62("assist sync", { stdio: "inherit" });
41064
+ execSync63("assist sync", { stdio: "inherit" });
40978
41065
  } else if (isGlobalNpmInstall(installDir)) {
40979
41066
  console.log("Detected global npm installation, updating...");
40980
- execSync62("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
41067
+ execSync63("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
40981
41068
  console.log("Syncing commands...");
40982
- execSync62("assist sync", { stdio: "inherit" });
41069
+ execSync63("assist sync", { stdio: "inherit" });
40983
41070
  } else {
40984
41071
  console.error(
40985
41072
  "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.627.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {