@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/commands/sessions/web/bundle.js +1 -1
- package/dist/index.js +196 -72
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.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
|
|
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
|
-
|
|
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
|
|
27118
|
+
import { execSync as execSync53 } from "child_process";
|
|
26995
27119
|
import chalk186 from "chalk";
|
|
26996
27120
|
function opExec(args) {
|
|
26997
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
29300
|
+
import { execSync as execSync56 } from "child_process";
|
|
29177
29301
|
function fetchRawComments(org, repo, prNumber) {
|
|
29178
|
-
const out =
|
|
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
|
|
29333
|
+
import { execSync as execSync59 } from "child_process";
|
|
29210
29334
|
|
|
29211
29335
|
// src/commands/review/fetchPrDiff.ts
|
|
29212
|
-
import { execSync as
|
|
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
|
|
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
|
-
|
|
29355
|
+
execSync57(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
|
|
29232
29356
|
} catch {
|
|
29233
29357
|
}
|
|
29234
|
-
return
|
|
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
|
|
29365
|
+
import { execSync as execSync58 } from "child_process";
|
|
29242
29366
|
function getCurrentBranch3() {
|
|
29243
|
-
return
|
|
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 =
|
|
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 =
|
|
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 =
|
|
29412
|
+
const branch2 = execSync59("git rev-parse --abbrev-ref HEAD", {
|
|
29289
29413
|
encoding: "utf8"
|
|
29290
29414
|
}).trim();
|
|
29291
|
-
const sha =
|
|
29292
|
-
const shortSha =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
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) ?
|
|
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) ?
|
|
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
|
|
32699
|
+
import { readFileSync as readFileSync56 } from "fs";
|
|
32576
32700
|
function readCleanedCues(inputPath) {
|
|
32577
|
-
return deduplicateCues(parseVtt(
|
|
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
|
|
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 =
|
|
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
|
|
33118
|
-
import { existsSync as existsSync76, mkdirSync as mkdirSync29, readFileSync as
|
|
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(
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
34843
|
+
import { readFileSync as readFileSync62 } from "fs";
|
|
34720
34844
|
function readDaemonPidFile() {
|
|
34721
34845
|
try {
|
|
34722
34846
|
const pid = Number.parseInt(
|
|
34723
|
-
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
-
|
|
41095
|
+
execSync63("git pull", { cwd: installDir, stdio: "inherit" });
|
|
40972
41096
|
console.log("Installing dependencies...");
|
|
40973
|
-
|
|
41097
|
+
execSync63("npm i", { cwd: installDir, stdio: "inherit" });
|
|
40974
41098
|
console.log("Building...");
|
|
40975
|
-
|
|
41099
|
+
execSync63("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
40976
41100
|
console.log("Syncing commands...");
|
|
40977
|
-
|
|
41101
|
+
execSync63("assist sync", { stdio: "inherit" });
|
|
40978
41102
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
40979
41103
|
console.log("Detected global npm installation, updating...");
|
|
40980
|
-
|
|
41104
|
+
execSync63("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
40981
41105
|
console.log("Syncing commands...");
|
|
40982
|
-
|
|
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."
|