@staff0rd/assist 0.345.0 → 0.347.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/README.md +5 -2
- package/allowed.cli-writes +1 -0
- package/dist/allowed.cli-writes +1 -0
- package/dist/commands/sessions/web/bundle.js +1 -1
- package/dist/index.js +467 -297
- 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.347.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -201,6 +201,9 @@ var assistConfigSchema = z2.strictObject({
|
|
|
201
201
|
push: z2.boolean().default(false),
|
|
202
202
|
expectedBranch: z2.string().optional()
|
|
203
203
|
}).default({ conventional: false, pull: false, push: false }),
|
|
204
|
+
branch: z2.strictObject({
|
|
205
|
+
prefix: z2.string().optional()
|
|
206
|
+
}).optional(),
|
|
204
207
|
devlog: z2.strictObject({
|
|
205
208
|
name: z2.string().optional(),
|
|
206
209
|
ignore: z2.array(z2.string()).optional(),
|
|
@@ -1755,10 +1758,20 @@ import { basename, resolve as resolve5 } from "path";
|
|
|
1755
1758
|
|
|
1756
1759
|
// src/commands/verify/blockComments/findComments.ts
|
|
1757
1760
|
import { execSync as execSync6 } from "child_process";
|
|
1758
|
-
import
|
|
1761
|
+
import fs14 from "fs";
|
|
1759
1762
|
import { minimatch } from "minimatch";
|
|
1760
1763
|
import { Project as Project2 } from "ts-morph";
|
|
1761
1764
|
|
|
1765
|
+
// src/commands/verify/blockComments/collectFileComments.ts
|
|
1766
|
+
import fs13 from "fs";
|
|
1767
|
+
|
|
1768
|
+
// src/shared/isYamlFile.ts
|
|
1769
|
+
var YAML_EXTENSIONS = [".yml", ".yaml"];
|
|
1770
|
+
function isYamlFile(filePath) {
|
|
1771
|
+
if (!filePath) return false;
|
|
1772
|
+
return YAML_EXTENSIONS.some((ext) => filePath.endsWith(ext));
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1762
1775
|
// src/commands/verify/blockComments/collectComments.ts
|
|
1763
1776
|
function collectComments(sourceFile) {
|
|
1764
1777
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -1779,6 +1792,18 @@ function collectComments(sourceFile) {
|
|
|
1779
1792
|
return comments3;
|
|
1780
1793
|
}
|
|
1781
1794
|
|
|
1795
|
+
// src/commands/verify/blockComments/collectYamlComments.ts
|
|
1796
|
+
import { Lexer } from "yaml";
|
|
1797
|
+
function collectYamlComments(content) {
|
|
1798
|
+
const comments3 = [];
|
|
1799
|
+
let line = 1;
|
|
1800
|
+
for (const token of new Lexer().lex(content)) {
|
|
1801
|
+
if (token.startsWith("#")) comments3.push({ line, text: token });
|
|
1802
|
+
for (const char of token) if (char === "\n") line++;
|
|
1803
|
+
}
|
|
1804
|
+
return comments3;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1782
1807
|
// src/commands/complexity/maintainability/parseMaintainabilityOverride.ts
|
|
1783
1808
|
var MAINTAINABILITY_OVERRIDE_MARKER = "assist-maintainability-override";
|
|
1784
1809
|
var OVERRIDE_MARKER = /^\s*\/\/\s*assist-maintainability-override:?\s*(-?\d+)\s*$/;
|
|
@@ -1817,6 +1842,31 @@ function isCommentExempt(text7) {
|
|
|
1817
1842
|
return MACHINE_DIRECTIVES.some((d) => lower.includes(d));
|
|
1818
1843
|
}
|
|
1819
1844
|
|
|
1845
|
+
// src/commands/verify/blockComments/collectFileComments.ts
|
|
1846
|
+
function toSingleLine(text7) {
|
|
1847
|
+
return text7.replace(/\s+/g, " ").trim();
|
|
1848
|
+
}
|
|
1849
|
+
function collectFileComments(file, lines, project) {
|
|
1850
|
+
const findings = [];
|
|
1851
|
+
if (isYamlFile(file)) {
|
|
1852
|
+
for (const { line, text: text7 } of collectYamlComments(
|
|
1853
|
+
fs13.readFileSync(file, "utf8")
|
|
1854
|
+
)) {
|
|
1855
|
+
if (lines.has(line))
|
|
1856
|
+
findings.push({ file, line, text: toSingleLine(text7) });
|
|
1857
|
+
}
|
|
1858
|
+
return findings;
|
|
1859
|
+
}
|
|
1860
|
+
const sourceFile = project.addSourceFileAtPath(file);
|
|
1861
|
+
for (const { pos, text: text7 } of collectComments(sourceFile)) {
|
|
1862
|
+
const { line } = sourceFile.getLineAndColumnAtPos(pos);
|
|
1863
|
+
if (!lines.has(line)) continue;
|
|
1864
|
+
if (isCommentExempt(text7)) continue;
|
|
1865
|
+
findings.push({ file, line, text: toSingleLine(text7) });
|
|
1866
|
+
}
|
|
1867
|
+
return findings;
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1820
1870
|
// src/commands/verify/blockComments/parseDiffAddedLines.ts
|
|
1821
1871
|
var FILE_HEADER = /^\+\+\+ (?:b\/)?(.+)$/;
|
|
1822
1872
|
var HUNK_HEADER = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
|
|
@@ -1853,14 +1903,20 @@ function parseDiffAddedLines(diff2) {
|
|
|
1853
1903
|
}
|
|
1854
1904
|
|
|
1855
1905
|
// src/commands/verify/blockComments/findComments.ts
|
|
1856
|
-
var
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1906
|
+
var SCANNED_EXTENSIONS = [
|
|
1907
|
+
".ts",
|
|
1908
|
+
".tsx",
|
|
1909
|
+
".cts",
|
|
1910
|
+
".mts",
|
|
1911
|
+
".js",
|
|
1912
|
+
".jsx",
|
|
1913
|
+
".yml",
|
|
1914
|
+
".yaml"
|
|
1915
|
+
];
|
|
1860
1916
|
function shouldScan(file, ignoreGlobs) {
|
|
1861
|
-
if (!
|
|
1917
|
+
if (!SCANNED_EXTENSIONS.some((ext) => file.endsWith(ext))) return false;
|
|
1862
1918
|
if (ignoreGlobs.some((glob) => minimatch(file, glob))) return false;
|
|
1863
|
-
return
|
|
1919
|
+
return fs14.existsSync(file);
|
|
1864
1920
|
}
|
|
1865
1921
|
function findComments(options2) {
|
|
1866
1922
|
const diff2 = execSync6("git diff HEAD", {
|
|
@@ -1875,13 +1931,7 @@ function findComments(options2) {
|
|
|
1875
1931
|
const findings = [];
|
|
1876
1932
|
for (const [file, lines] of addedLines) {
|
|
1877
1933
|
if (!shouldScan(file, options2.ignoreGlobs)) continue;
|
|
1878
|
-
|
|
1879
|
-
for (const { pos, text: text7 } of collectComments(sourceFile)) {
|
|
1880
|
-
const { line } = sourceFile.getLineAndColumnAtPos(pos);
|
|
1881
|
-
if (!lines.has(line)) continue;
|
|
1882
|
-
if (isCommentExempt(text7)) continue;
|
|
1883
|
-
findings.push({ file, line, text: toSingleLine(text7) });
|
|
1884
|
-
}
|
|
1934
|
+
findings.push(...collectFileComments(file, lines, project));
|
|
1885
1935
|
}
|
|
1886
1936
|
findings.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
|
|
1887
1937
|
return findings;
|
|
@@ -2661,7 +2711,7 @@ function detectPlatform() {
|
|
|
2661
2711
|
|
|
2662
2712
|
// src/commands/notify/showNotification/showWindowsNotificationFromWsl.ts
|
|
2663
2713
|
import { spawn as spawn2 } from "child_process";
|
|
2664
|
-
import
|
|
2714
|
+
import fs15 from "fs";
|
|
2665
2715
|
import { createRequire } from "module";
|
|
2666
2716
|
import path19 from "path";
|
|
2667
2717
|
var require2 = createRequire(import.meta.url);
|
|
@@ -2673,7 +2723,7 @@ function showWindowsNotificationFromWsl(options2) {
|
|
|
2673
2723
|
const { title, message, sound } = options2;
|
|
2674
2724
|
const snoreToastPath = getSnoreToastPath();
|
|
2675
2725
|
try {
|
|
2676
|
-
|
|
2726
|
+
fs15.chmodSync(snoreToastPath, 493);
|
|
2677
2727
|
} catch {
|
|
2678
2728
|
}
|
|
2679
2729
|
const args = ["-t", title, "-m", message];
|
|
@@ -6099,8 +6149,8 @@ import { promisify } from "util";
|
|
|
6099
6149
|
// src/commands/sessions/web/findSynthesisForBranch.ts
|
|
6100
6150
|
import { existsSync as existsSync24, readdirSync, statSync as statSync2 } from "fs";
|
|
6101
6151
|
import { basename as basename2, dirname as dirname18, join as join21 } from "path";
|
|
6102
|
-
function findSynthesisForBranch(repoReviewsDir,
|
|
6103
|
-
const branchKeyPath = join21(repoReviewsDir, `${
|
|
6152
|
+
function findSynthesisForBranch(repoReviewsDir, branch2) {
|
|
6153
|
+
const branchKeyPath = join21(repoReviewsDir, `${branch2}-`);
|
|
6104
6154
|
const parent = dirname18(branchKeyPath);
|
|
6105
6155
|
const branchPrefix = basename2(branchKeyPath);
|
|
6106
6156
|
if (!existsSync24(parent)) return null;
|
|
@@ -6137,7 +6187,7 @@ function runGit(cwd, args) {
|
|
|
6137
6187
|
}).then((r) => r.stdout.trim());
|
|
6138
6188
|
}
|
|
6139
6189
|
async function resolveSynthesisPath(cwd) {
|
|
6140
|
-
const [repoRoot,
|
|
6190
|
+
const [repoRoot, branch2] = await Promise.all([
|
|
6141
6191
|
runGit(cwd, ["rev-parse", "--show-toplevel"]),
|
|
6142
6192
|
runGit(cwd, ["rev-parse", "--abbrev-ref", "HEAD"])
|
|
6143
6193
|
]);
|
|
@@ -6147,7 +6197,7 @@ async function resolveSynthesisPath(cwd) {
|
|
|
6147
6197
|
"reviews",
|
|
6148
6198
|
basename3(repoRoot)
|
|
6149
6199
|
);
|
|
6150
|
-
return findSynthesisForBranch(repoReviewsDir,
|
|
6200
|
+
return findSynthesisForBranch(repoReviewsDir, branch2);
|
|
6151
6201
|
}
|
|
6152
6202
|
async function getReviewSynthesis(req, res) {
|
|
6153
6203
|
const cwd = getCwdParam(req, res);
|
|
@@ -8651,6 +8701,96 @@ function registerBacklog(program2) {
|
|
|
8651
8701
|
}
|
|
8652
8702
|
}
|
|
8653
8703
|
|
|
8704
|
+
// src/commands/branch/branch.ts
|
|
8705
|
+
import { execSync as execSync24 } from "child_process";
|
|
8706
|
+
|
|
8707
|
+
// src/commands/branch/buildBranchName.ts
|
|
8708
|
+
function buildBranchName({
|
|
8709
|
+
prefix: prefix2,
|
|
8710
|
+
jira,
|
|
8711
|
+
slug
|
|
8712
|
+
}) {
|
|
8713
|
+
const segments = [];
|
|
8714
|
+
if (prefix2) segments.push(`${prefix2}/`);
|
|
8715
|
+
if (jira) segments.push(`${jira}-`);
|
|
8716
|
+
segments.push(slug);
|
|
8717
|
+
return segments.join("");
|
|
8718
|
+
}
|
|
8719
|
+
|
|
8720
|
+
// src/commands/branch/resolveDefaultBranch.ts
|
|
8721
|
+
import { execSync as execSync23 } from "child_process";
|
|
8722
|
+
function resolveDefaultBranch(cwd) {
|
|
8723
|
+
const ref = execSync23("git symbolic-ref --short refs/remotes/origin/HEAD", {
|
|
8724
|
+
encoding: "utf8",
|
|
8725
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
8726
|
+
cwd
|
|
8727
|
+
}).trim();
|
|
8728
|
+
const [, ...rest] = ref.split("/");
|
|
8729
|
+
const branch2 = rest.join("/");
|
|
8730
|
+
if (!branch2) {
|
|
8731
|
+
throw new Error(`Could not resolve default branch from "${ref}"`);
|
|
8732
|
+
}
|
|
8733
|
+
return branch2;
|
|
8734
|
+
}
|
|
8735
|
+
|
|
8736
|
+
// src/commands/branch/validateSlug.ts
|
|
8737
|
+
var KEBAB_CASE_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
8738
|
+
var HASH_REF_REGEX = /#\d+/;
|
|
8739
|
+
var BACKLOG_NUMBER_SEGMENT_REGEX = /(?:^|-)\d{1,4}(?:-|$)/;
|
|
8740
|
+
function validateSlug(slug) {
|
|
8741
|
+
if (!slug) {
|
|
8742
|
+
return "Slug is required";
|
|
8743
|
+
}
|
|
8744
|
+
if (HASH_REF_REGEX.test(slug)) {
|
|
8745
|
+
return `Slug "${slug}" contains a backlog reference (#<number>); remove it`;
|
|
8746
|
+
}
|
|
8747
|
+
if (!KEBAB_CASE_REGEX.test(slug)) {
|
|
8748
|
+
return `Slug "${slug}" must be kebab-case (lowercase letters, digits, and hyphens)`;
|
|
8749
|
+
}
|
|
8750
|
+
if (BACKLOG_NUMBER_SEGMENT_REGEX.test(slug)) {
|
|
8751
|
+
return `Slug "${slug}" contains a numeric token that looks like a backlog ID; remove or reword it`;
|
|
8752
|
+
}
|
|
8753
|
+
return null;
|
|
8754
|
+
}
|
|
8755
|
+
|
|
8756
|
+
// src/commands/branch/branch.ts
|
|
8757
|
+
function branch(slug, options2) {
|
|
8758
|
+
const slugError = validateSlug(slug);
|
|
8759
|
+
if (slugError) {
|
|
8760
|
+
console.error(`Error: ${slugError}`);
|
|
8761
|
+
process.exit(1);
|
|
8762
|
+
}
|
|
8763
|
+
const config = loadConfig();
|
|
8764
|
+
const branchName = buildBranchName({
|
|
8765
|
+
prefix: config.branch?.prefix,
|
|
8766
|
+
jira: options2.jira,
|
|
8767
|
+
slug
|
|
8768
|
+
});
|
|
8769
|
+
try {
|
|
8770
|
+
const defaultBranch = resolveDefaultBranch();
|
|
8771
|
+
execSync24("git fetch", { stdio: "inherit" });
|
|
8772
|
+
execSync24(
|
|
8773
|
+
`git switch -c ${shellQuote(branchName)} ${shellQuote(`origin/${defaultBranch}`)}`,
|
|
8774
|
+
{ stdio: "inherit" }
|
|
8775
|
+
);
|
|
8776
|
+
console.log(
|
|
8777
|
+
`Created and switched to ${branchName} (from origin/${defaultBranch})`
|
|
8778
|
+
);
|
|
8779
|
+
process.exit(0);
|
|
8780
|
+
} catch {
|
|
8781
|
+
process.exit(1);
|
|
8782
|
+
}
|
|
8783
|
+
}
|
|
8784
|
+
|
|
8785
|
+
// src/commands/registerBranch.ts
|
|
8786
|
+
function registerBranch(program2) {
|
|
8787
|
+
program2.command("branch <slug>").description(
|
|
8788
|
+
"Create and switch to a branch off the fresh remote default branch"
|
|
8789
|
+
).option("--jira <key>", "Jira issue key to include in the branch name").action(
|
|
8790
|
+
(slug, options2) => branch(slug, options2)
|
|
8791
|
+
);
|
|
8792
|
+
}
|
|
8793
|
+
|
|
8654
8794
|
// src/commands/cliHook/index.ts
|
|
8655
8795
|
import { basename as basename4 } from "path";
|
|
8656
8796
|
|
|
@@ -9289,7 +9429,7 @@ import { homedir as homedir12 } from "os";
|
|
|
9289
9429
|
import { join as join26 } from "path";
|
|
9290
9430
|
|
|
9291
9431
|
// src/shared/checkCliAvailable.ts
|
|
9292
|
-
import { execSync as
|
|
9432
|
+
import { execSync as execSync25 } from "child_process";
|
|
9293
9433
|
function checkCliAvailable(cli) {
|
|
9294
9434
|
const binary = cli.split(/\s+/)[0];
|
|
9295
9435
|
const opts = {
|
|
@@ -9297,11 +9437,11 @@ function checkCliAvailable(cli) {
|
|
|
9297
9437
|
stdio: ["ignore", "pipe", "pipe"]
|
|
9298
9438
|
};
|
|
9299
9439
|
try {
|
|
9300
|
-
|
|
9440
|
+
execSync25(`command -v ${binary}`, opts);
|
|
9301
9441
|
return true;
|
|
9302
9442
|
} catch {
|
|
9303
9443
|
try {
|
|
9304
|
-
|
|
9444
|
+
execSync25(`where ${binary}`, opts);
|
|
9305
9445
|
return true;
|
|
9306
9446
|
} catch {
|
|
9307
9447
|
return false;
|
|
@@ -9712,7 +9852,7 @@ function registerCliHook(program2) {
|
|
|
9712
9852
|
}
|
|
9713
9853
|
|
|
9714
9854
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
9715
|
-
import { existsSync as
|
|
9855
|
+
import { existsSync as existsSync29, readFileSync as readFileSync24, unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
9716
9856
|
import chalk95 from "chalk";
|
|
9717
9857
|
|
|
9718
9858
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
@@ -9747,7 +9887,8 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
|
9747
9887
|
}
|
|
9748
9888
|
}
|
|
9749
9889
|
|
|
9750
|
-
// src/commands/codeComment/
|
|
9890
|
+
// src/commands/codeComment/readPinState.ts
|
|
9891
|
+
import { existsSync as existsSync28, readFileSync as readFileSync23 } from "fs";
|
|
9751
9892
|
function readPinState(pin) {
|
|
9752
9893
|
const path57 = getPinStatePath(pin);
|
|
9753
9894
|
if (!existsSync28(path57)) return void 0;
|
|
@@ -9759,6 +9900,8 @@ function readPinState(pin) {
|
|
|
9759
9900
|
return void 0;
|
|
9760
9901
|
}
|
|
9761
9902
|
}
|
|
9903
|
+
|
|
9904
|
+
// src/commands/codeComment/codeCommentConfirm.ts
|
|
9762
9905
|
function codeCommentConfirm(pin) {
|
|
9763
9906
|
sweepRestrictedDir();
|
|
9764
9907
|
const state = readPinState(pin);
|
|
@@ -9767,12 +9910,12 @@ function codeCommentConfirm(pin) {
|
|
|
9767
9910
|
process.exitCode = 1;
|
|
9768
9911
|
return;
|
|
9769
9912
|
}
|
|
9770
|
-
if (!
|
|
9913
|
+
if (!existsSync29(state.file)) {
|
|
9771
9914
|
console.error(chalk95.red(`Target file no longer exists: ${state.file}`));
|
|
9772
9915
|
process.exitCode = 1;
|
|
9773
9916
|
return;
|
|
9774
9917
|
}
|
|
9775
|
-
const original =
|
|
9918
|
+
const original = readFileSync24(state.file, "utf8");
|
|
9776
9919
|
const lines = original.split("\n");
|
|
9777
9920
|
const index3 = state.line - 1;
|
|
9778
9921
|
if (index3 > lines.length) {
|
|
@@ -9784,13 +9927,16 @@ function codeCommentConfirm(pin) {
|
|
|
9784
9927
|
process.exitCode = 1;
|
|
9785
9928
|
return;
|
|
9786
9929
|
}
|
|
9930
|
+
const marker = isYamlFile(state.file) ? "#" : "//";
|
|
9787
9931
|
const indentSource = lines[index3] ?? "";
|
|
9788
9932
|
const indent2 = indentSource.match(/^\s*/)?.[0] ?? "";
|
|
9789
|
-
lines.splice(index3, 0, `${indent2}
|
|
9933
|
+
lines.splice(index3, 0, `${indent2}${marker} ${state.text}`);
|
|
9790
9934
|
writeFileSync22(state.file, lines.join("\n"));
|
|
9791
9935
|
unlinkSync8(getPinStatePath(pin));
|
|
9792
9936
|
console.log(
|
|
9793
|
-
chalk95.green(
|
|
9937
|
+
chalk95.green(
|
|
9938
|
+
`Inserted "${marker} ${state.text}" at ${state.file}:${state.line}`
|
|
9939
|
+
)
|
|
9794
9940
|
);
|
|
9795
9941
|
}
|
|
9796
9942
|
|
|
@@ -9799,15 +9945,15 @@ import chalk96 from "chalk";
|
|
|
9799
9945
|
|
|
9800
9946
|
// src/commands/codeComment/validateCommentText.ts
|
|
9801
9947
|
var MAX_COMMENT_LENGTH = 50;
|
|
9802
|
-
function validateCommentText(raw) {
|
|
9803
|
-
const text7 = raw.replace(/^\/\/\s?/, "");
|
|
9948
|
+
function validateCommentText(raw, isYaml = false) {
|
|
9949
|
+
const text7 = isYaml ? raw.replace(/^#\s?/, "") : raw.replace(/^\/\/\s?/, "");
|
|
9804
9950
|
if (/[\r\n]/.test(text7)) {
|
|
9805
9951
|
return {
|
|
9806
9952
|
ok: false,
|
|
9807
9953
|
reason: "Comment must be a single line \u2014 multi-line comments are not allowed."
|
|
9808
9954
|
};
|
|
9809
9955
|
}
|
|
9810
|
-
if (text7.includes("/*") || text7.includes("*/")) {
|
|
9956
|
+
if (!isYaml && (text7.includes("/*") || text7.includes("*/"))) {
|
|
9811
9957
|
return {
|
|
9812
9958
|
ok: false,
|
|
9813
9959
|
reason: "Block comments (/* */) are not allowed \u2014 only single-line // comments."
|
|
@@ -9850,7 +9996,8 @@ function codeCommentSet(file, line, text7) {
|
|
|
9850
9996
|
process.exitCode = 1;
|
|
9851
9997
|
return;
|
|
9852
9998
|
}
|
|
9853
|
-
const
|
|
9999
|
+
const marker = isYamlFile(file) ? "#" : "//";
|
|
10000
|
+
const validation = validateCommentText(text7, isYamlFile(file));
|
|
9854
10001
|
if (!validation.ok) {
|
|
9855
10002
|
console.error(chalk96.red(`Refused: ${validation.reason}`));
|
|
9856
10003
|
console.error(chalk96.red("No pin issued."));
|
|
@@ -9874,7 +10021,7 @@ function codeCommentSet(file, line, text7) {
|
|
|
9874
10021
|
}
|
|
9875
10022
|
console.log(
|
|
9876
10023
|
`A confirmation pin was sent to your desktop notifications.
|
|
9877
|
-
To insert "
|
|
10024
|
+
To insert "${marker} ${validation.text}" at ${file}:${lineNumber}, run:
|
|
9878
10025
|
${chalk96.cyan(" assist code-comment confirm <PIN>")}
|
|
9879
10026
|
using the pin from that notification.`
|
|
9880
10027
|
);
|
|
@@ -9901,13 +10048,13 @@ import chalk105 from "chalk";
|
|
|
9901
10048
|
import chalk98 from "chalk";
|
|
9902
10049
|
|
|
9903
10050
|
// src/commands/complexity/shared/index.ts
|
|
9904
|
-
import
|
|
10051
|
+
import fs17 from "fs";
|
|
9905
10052
|
import path21 from "path";
|
|
9906
10053
|
import chalk97 from "chalk";
|
|
9907
10054
|
import ts5 from "typescript";
|
|
9908
10055
|
|
|
9909
10056
|
// src/commands/complexity/findSourceFiles.ts
|
|
9910
|
-
import
|
|
10057
|
+
import fs16 from "fs";
|
|
9911
10058
|
import path20 from "path";
|
|
9912
10059
|
import { minimatch as minimatch5 } from "minimatch";
|
|
9913
10060
|
function applyIgnoreGlobs(files, extraIgnore = []) {
|
|
@@ -9916,11 +10063,11 @@ function applyIgnoreGlobs(files, extraIgnore = []) {
|
|
|
9916
10063
|
return files.filter((f) => !ignore2.some((glob) => minimatch5(f, glob)));
|
|
9917
10064
|
}
|
|
9918
10065
|
function walk(dir, results) {
|
|
9919
|
-
if (!
|
|
10066
|
+
if (!fs16.existsSync(dir)) {
|
|
9920
10067
|
return;
|
|
9921
10068
|
}
|
|
9922
10069
|
const extensions = [".ts", ".tsx"];
|
|
9923
|
-
const entries =
|
|
10070
|
+
const entries = fs16.readdirSync(dir, { withFileTypes: true });
|
|
9924
10071
|
for (const entry of entries) {
|
|
9925
10072
|
const fullPath = path20.join(dir, entry.name);
|
|
9926
10073
|
if (entry.isDirectory()) {
|
|
@@ -9941,10 +10088,10 @@ function findSourceFiles2(pattern2, baseDir = ".", extraIgnore = []) {
|
|
|
9941
10088
|
extraIgnore
|
|
9942
10089
|
);
|
|
9943
10090
|
}
|
|
9944
|
-
if (
|
|
10091
|
+
if (fs16.existsSync(pattern2) && fs16.statSync(pattern2).isFile()) {
|
|
9945
10092
|
return [pattern2];
|
|
9946
10093
|
}
|
|
9947
|
-
if (
|
|
10094
|
+
if (fs16.existsSync(pattern2) && fs16.statSync(pattern2).isDirectory()) {
|
|
9948
10095
|
walk(pattern2, results);
|
|
9949
10096
|
return applyIgnoreGlobs(results, extraIgnore);
|
|
9950
10097
|
}
|
|
@@ -10142,7 +10289,7 @@ function countSloc(content) {
|
|
|
10142
10289
|
|
|
10143
10290
|
// src/commands/complexity/shared/index.ts
|
|
10144
10291
|
function createSourceFromFile(filePath) {
|
|
10145
|
-
const content =
|
|
10292
|
+
const content = fs17.readFileSync(filePath, "utf8");
|
|
10146
10293
|
return ts5.createSourceFile(
|
|
10147
10294
|
path21.basename(filePath),
|
|
10148
10295
|
content,
|
|
@@ -10302,7 +10449,7 @@ function printMaintainabilityFormula() {
|
|
|
10302
10449
|
}
|
|
10303
10450
|
|
|
10304
10451
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
10305
|
-
import
|
|
10452
|
+
import fs18 from "fs";
|
|
10306
10453
|
|
|
10307
10454
|
// src/commands/complexity/maintainability/calculateMaintainabilityIndex.ts
|
|
10308
10455
|
function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
|
|
@@ -10317,7 +10464,7 @@ function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, slo
|
|
|
10317
10464
|
function collectFileMetrics(files) {
|
|
10318
10465
|
const fileMetrics = /* @__PURE__ */ new Map();
|
|
10319
10466
|
for (const file of files) {
|
|
10320
|
-
const content =
|
|
10467
|
+
const content = fs18.readFileSync(file, "utf8");
|
|
10321
10468
|
fileMetrics.set(file, {
|
|
10322
10469
|
sloc: countSloc(content),
|
|
10323
10470
|
functions: [],
|
|
@@ -10373,14 +10520,14 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10373
10520
|
}
|
|
10374
10521
|
|
|
10375
10522
|
// src/commands/complexity/sloc.ts
|
|
10376
|
-
import
|
|
10523
|
+
import fs19 from "fs";
|
|
10377
10524
|
import chalk104 from "chalk";
|
|
10378
10525
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
10379
10526
|
withSourceFiles(pattern2, (files) => {
|
|
10380
10527
|
const results = [];
|
|
10381
10528
|
let hasViolation = false;
|
|
10382
10529
|
for (const file of files) {
|
|
10383
|
-
const content =
|
|
10530
|
+
const content = fs19.readFileSync(file, "utf8");
|
|
10384
10531
|
const lines = countSloc(content);
|
|
10385
10532
|
results.push({ file, lines });
|
|
10386
10533
|
if (options2.threshold !== void 0 && lines > options2.threshold) {
|
|
@@ -10618,7 +10765,7 @@ function registerConfig(program2) {
|
|
|
10618
10765
|
}
|
|
10619
10766
|
|
|
10620
10767
|
// src/commands/deploy/redirect.ts
|
|
10621
|
-
import { existsSync as
|
|
10768
|
+
import { existsSync as existsSync30, readFileSync as readFileSync25, writeFileSync as writeFileSync24 } from "fs";
|
|
10622
10769
|
import chalk108 from "chalk";
|
|
10623
10770
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
10624
10771
|
if (!window.location.pathname.endsWith('/')) {
|
|
@@ -10627,11 +10774,11 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
10627
10774
|
</script>`;
|
|
10628
10775
|
function redirect() {
|
|
10629
10776
|
const indexPath = "index.html";
|
|
10630
|
-
if (!
|
|
10777
|
+
if (!existsSync30(indexPath)) {
|
|
10631
10778
|
console.log(chalk108.yellow("No index.html found"));
|
|
10632
10779
|
return;
|
|
10633
10780
|
}
|
|
10634
|
-
const content =
|
|
10781
|
+
const content = readFileSync25(indexPath, "utf8");
|
|
10635
10782
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
10636
10783
|
console.log(chalk108.dim("Trailing slash script already present"));
|
|
10637
10784
|
return;
|
|
@@ -10670,11 +10817,11 @@ function loadBlogSkipDays(repoName) {
|
|
|
10670
10817
|
}
|
|
10671
10818
|
|
|
10672
10819
|
// src/commands/devlog/shared.ts
|
|
10673
|
-
import { execSync as
|
|
10820
|
+
import { execSync as execSync26 } from "child_process";
|
|
10674
10821
|
import chalk109 from "chalk";
|
|
10675
10822
|
|
|
10676
10823
|
// src/shared/getRepoName.ts
|
|
10677
|
-
import { existsSync as
|
|
10824
|
+
import { existsSync as existsSync31, readFileSync as readFileSync26 } from "fs";
|
|
10678
10825
|
import { basename as basename5, join as join30 } from "path";
|
|
10679
10826
|
function getRepoName() {
|
|
10680
10827
|
const config = loadConfig();
|
|
@@ -10682,9 +10829,9 @@ function getRepoName() {
|
|
|
10682
10829
|
return config.devlog.name;
|
|
10683
10830
|
}
|
|
10684
10831
|
const packageJsonPath = join30(process.cwd(), "package.json");
|
|
10685
|
-
if (
|
|
10832
|
+
if (existsSync31(packageJsonPath)) {
|
|
10686
10833
|
try {
|
|
10687
|
-
const content =
|
|
10834
|
+
const content = readFileSync26(packageJsonPath, "utf8");
|
|
10688
10835
|
const pkg = JSON.parse(content);
|
|
10689
10836
|
if (pkg.name) {
|
|
10690
10837
|
return pkg.name;
|
|
@@ -10696,7 +10843,7 @@ function getRepoName() {
|
|
|
10696
10843
|
}
|
|
10697
10844
|
|
|
10698
10845
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
10699
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
10846
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync27 } from "fs";
|
|
10700
10847
|
import { join as join31 } from "path";
|
|
10701
10848
|
var DEVLOG_DIR = join31(BLOG_REPO_ROOT, "src/content/devlog");
|
|
10702
10849
|
function extractFrontmatter(content) {
|
|
@@ -10726,7 +10873,7 @@ function readDevlogFiles(callback) {
|
|
|
10726
10873
|
try {
|
|
10727
10874
|
const files = readdirSync3(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
10728
10875
|
for (const file of files) {
|
|
10729
|
-
const content =
|
|
10876
|
+
const content = readFileSync27(join31(DEVLOG_DIR, file), "utf8");
|
|
10730
10877
|
const parsed = parseFrontmatter(content, file);
|
|
10731
10878
|
if (parsed) callback(parsed);
|
|
10732
10879
|
}
|
|
@@ -10762,7 +10909,7 @@ function loadAllDevlogLatestDates() {
|
|
|
10762
10909
|
// src/commands/devlog/shared.ts
|
|
10763
10910
|
function getCommitFiles(hash) {
|
|
10764
10911
|
try {
|
|
10765
|
-
const output =
|
|
10912
|
+
const output = execSync26(`git show --name-only --format="" ${hash}`, {
|
|
10766
10913
|
encoding: "utf8"
|
|
10767
10914
|
});
|
|
10768
10915
|
return output.trim().split("\n").filter(Boolean);
|
|
@@ -10858,11 +11005,11 @@ function list3(options2) {
|
|
|
10858
11005
|
}
|
|
10859
11006
|
|
|
10860
11007
|
// src/commands/devlog/getLastVersionInfo.ts
|
|
10861
|
-
import { execFileSync as execFileSync3, execSync as
|
|
11008
|
+
import { execFileSync as execFileSync3, execSync as execSync27 } from "child_process";
|
|
10862
11009
|
import semver from "semver";
|
|
10863
11010
|
function getVersionAtCommit(hash) {
|
|
10864
11011
|
try {
|
|
10865
|
-
const content =
|
|
11012
|
+
const content = execSync27(`git show ${hash}:package.json`, {
|
|
10866
11013
|
encoding: "utf8"
|
|
10867
11014
|
});
|
|
10868
11015
|
const pkg = JSON.parse(content);
|
|
@@ -11035,7 +11182,7 @@ function next2(options2) {
|
|
|
11035
11182
|
}
|
|
11036
11183
|
|
|
11037
11184
|
// src/commands/devlog/repos/index.ts
|
|
11038
|
-
import { execSync as
|
|
11185
|
+
import { execSync as execSync28 } from "child_process";
|
|
11039
11186
|
|
|
11040
11187
|
// src/commands/devlog/repos/printReposTable.ts
|
|
11041
11188
|
import chalk113 from "chalk";
|
|
@@ -11070,7 +11217,7 @@ function getStatus(lastPush, lastDevlog) {
|
|
|
11070
11217
|
return lastDevlog < lastPush ? "outdated" : "ok";
|
|
11071
11218
|
}
|
|
11072
11219
|
function fetchRepos(days, all) {
|
|
11073
|
-
const json =
|
|
11220
|
+
const json = execSync28(
|
|
11074
11221
|
"gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
|
|
11075
11222
|
{ encoding: "utf8" }
|
|
11076
11223
|
);
|
|
@@ -11183,12 +11330,12 @@ import { join as join33 } from "path";
|
|
|
11183
11330
|
import chalk116 from "chalk";
|
|
11184
11331
|
|
|
11185
11332
|
// src/shared/findRepoRoot.ts
|
|
11186
|
-
import { existsSync as
|
|
11333
|
+
import { existsSync as existsSync32 } from "fs";
|
|
11187
11334
|
import path22 from "path";
|
|
11188
11335
|
function findRepoRoot(dir) {
|
|
11189
11336
|
let current = dir;
|
|
11190
11337
|
while (current !== path22.dirname(current)) {
|
|
11191
|
-
if (
|
|
11338
|
+
if (existsSync32(path22.join(current, ".git"))) {
|
|
11192
11339
|
return current;
|
|
11193
11340
|
}
|
|
11194
11341
|
current = path22.dirname(current);
|
|
@@ -11254,11 +11401,11 @@ async function checkBuildLocksCommand() {
|
|
|
11254
11401
|
}
|
|
11255
11402
|
|
|
11256
11403
|
// src/commands/dotnet/buildTree.ts
|
|
11257
|
-
import { readFileSync as
|
|
11404
|
+
import { readFileSync as readFileSync28 } from "fs";
|
|
11258
11405
|
import path23 from "path";
|
|
11259
11406
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
11260
11407
|
function getProjectRefs(csprojPath) {
|
|
11261
|
-
const content =
|
|
11408
|
+
const content = readFileSync28(csprojPath, "utf8");
|
|
11262
11409
|
const refs = [];
|
|
11263
11410
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
11264
11411
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -11275,7 +11422,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
11275
11422
|
for (const ref of getProjectRefs(abs)) {
|
|
11276
11423
|
const childAbs = path23.resolve(dir, ref);
|
|
11277
11424
|
try {
|
|
11278
|
-
|
|
11425
|
+
readFileSync28(childAbs);
|
|
11279
11426
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
11280
11427
|
} catch {
|
|
11281
11428
|
node.children.push({
|
|
@@ -11300,7 +11447,7 @@ function collectAllDeps(node) {
|
|
|
11300
11447
|
}
|
|
11301
11448
|
|
|
11302
11449
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
11303
|
-
import { readdirSync as readdirSync5, readFileSync as
|
|
11450
|
+
import { readdirSync as readdirSync5, readFileSync as readFileSync29, statSync as statSync4 } from "fs";
|
|
11304
11451
|
import path24 from "path";
|
|
11305
11452
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
11306
11453
|
if (depth > maxDepth) return [];
|
|
@@ -11335,7 +11482,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
11335
11482
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
11336
11483
|
for (const sln of slnFiles) {
|
|
11337
11484
|
try {
|
|
11338
|
-
const content =
|
|
11485
|
+
const content = readFileSync29(sln, "utf8");
|
|
11339
11486
|
if (pattern2.test(content)) {
|
|
11340
11487
|
matches.push(path24.relative(repoRoot, sln));
|
|
11341
11488
|
}
|
|
@@ -11399,12 +11546,12 @@ function printJson(tree, totalCount, solutions) {
|
|
|
11399
11546
|
}
|
|
11400
11547
|
|
|
11401
11548
|
// src/commands/dotnet/resolveCsproj.ts
|
|
11402
|
-
import { existsSync as
|
|
11549
|
+
import { existsSync as existsSync33 } from "fs";
|
|
11403
11550
|
import path25 from "path";
|
|
11404
11551
|
import chalk118 from "chalk";
|
|
11405
11552
|
function resolveCsproj(csprojPath) {
|
|
11406
11553
|
const resolved = path25.resolve(csprojPath);
|
|
11407
|
-
if (!
|
|
11554
|
+
if (!existsSync33(resolved)) {
|
|
11408
11555
|
console.error(chalk118.red(`File not found: ${resolved}`));
|
|
11409
11556
|
process.exit(1);
|
|
11410
11557
|
}
|
|
@@ -11430,7 +11577,7 @@ async function deps(csprojPath, options2) {
|
|
|
11430
11577
|
}
|
|
11431
11578
|
|
|
11432
11579
|
// src/commands/dotnet/getChangedCsFiles.ts
|
|
11433
|
-
import { execSync as
|
|
11580
|
+
import { execSync as execSync29 } from "child_process";
|
|
11434
11581
|
var SCOPE_ALL = "all";
|
|
11435
11582
|
var SCOPE_BASE = "base:";
|
|
11436
11583
|
var SCOPE_COMMIT = "commit:";
|
|
@@ -11454,7 +11601,7 @@ function getChangedCsFiles(scope) {
|
|
|
11454
11601
|
} else {
|
|
11455
11602
|
cmd = "git diff --name-only HEAD";
|
|
11456
11603
|
}
|
|
11457
|
-
const output =
|
|
11604
|
+
const output = execSync29(cmd, { encoding: "utf8" }).trim();
|
|
11458
11605
|
if (output === "") return [];
|
|
11459
11606
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
11460
11607
|
}
|
|
@@ -11572,7 +11719,7 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
11572
11719
|
}
|
|
11573
11720
|
|
|
11574
11721
|
// src/commands/dotnet/resolveSolution.ts
|
|
11575
|
-
import { existsSync as
|
|
11722
|
+
import { existsSync as existsSync34 } from "fs";
|
|
11576
11723
|
import path26 from "path";
|
|
11577
11724
|
import chalk122 from "chalk";
|
|
11578
11725
|
|
|
@@ -11613,7 +11760,7 @@ function findSolution() {
|
|
|
11613
11760
|
function resolveSolution(sln) {
|
|
11614
11761
|
if (sln) {
|
|
11615
11762
|
const resolved = path26.resolve(sln);
|
|
11616
|
-
if (!
|
|
11763
|
+
if (!existsSync34(resolved)) {
|
|
11617
11764
|
console.error(chalk122.red(`Solution file not found: ${resolved}`));
|
|
11618
11765
|
process.exit(1);
|
|
11619
11766
|
}
|
|
@@ -11652,14 +11799,14 @@ function parseInspectReport(json) {
|
|
|
11652
11799
|
}
|
|
11653
11800
|
|
|
11654
11801
|
// src/commands/dotnet/runInspectCode.ts
|
|
11655
|
-
import { execSync as
|
|
11656
|
-
import { existsSync as
|
|
11802
|
+
import { execSync as execSync30 } from "child_process";
|
|
11803
|
+
import { existsSync as existsSync35, readFileSync as readFileSync30, unlinkSync as unlinkSync9 } from "fs";
|
|
11657
11804
|
import { tmpdir as tmpdir3 } from "os";
|
|
11658
11805
|
import path27 from "path";
|
|
11659
11806
|
import chalk123 from "chalk";
|
|
11660
11807
|
function assertJbInstalled() {
|
|
11661
11808
|
try {
|
|
11662
|
-
|
|
11809
|
+
execSync30("jb inspectcode --version", { stdio: "pipe" });
|
|
11663
11810
|
} catch {
|
|
11664
11811
|
console.error(chalk123.red("jb is not installed. Install with:"));
|
|
11665
11812
|
console.error(
|
|
@@ -11673,7 +11820,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11673
11820
|
const includeFlag = include ? ` --include="${include}"` : "";
|
|
11674
11821
|
const sweaFlag = swea ? " --swea" : "";
|
|
11675
11822
|
try {
|
|
11676
|
-
|
|
11823
|
+
execSync30(
|
|
11677
11824
|
`jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
|
|
11678
11825
|
{ stdio: "pipe" }
|
|
11679
11826
|
);
|
|
@@ -11684,17 +11831,17 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11684
11831
|
console.error(chalk123.red("jb inspectcode failed"));
|
|
11685
11832
|
process.exit(1);
|
|
11686
11833
|
}
|
|
11687
|
-
if (!
|
|
11834
|
+
if (!existsSync35(reportPath)) {
|
|
11688
11835
|
console.error(chalk123.red("Report file not generated"));
|
|
11689
11836
|
process.exit(1);
|
|
11690
11837
|
}
|
|
11691
|
-
const xml =
|
|
11838
|
+
const xml = readFileSync30(reportPath, "utf8");
|
|
11692
11839
|
unlinkSync9(reportPath);
|
|
11693
11840
|
return xml;
|
|
11694
11841
|
}
|
|
11695
11842
|
|
|
11696
11843
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
11697
|
-
import { execSync as
|
|
11844
|
+
import { execSync as execSync31 } from "child_process";
|
|
11698
11845
|
import chalk124 from "chalk";
|
|
11699
11846
|
function resolveMsbuildPath() {
|
|
11700
11847
|
const { run: run4 } = loadConfig();
|
|
@@ -11705,7 +11852,7 @@ function resolveMsbuildPath() {
|
|
|
11705
11852
|
function assertMsbuildInstalled() {
|
|
11706
11853
|
const msbuild = resolveMsbuildPath();
|
|
11707
11854
|
try {
|
|
11708
|
-
|
|
11855
|
+
execSync31(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
11709
11856
|
} catch {
|
|
11710
11857
|
console.error(chalk124.red(`msbuild not found at: ${msbuild}`));
|
|
11711
11858
|
console.error(
|
|
@@ -11731,7 +11878,7 @@ function runRoslynInspect(slnPath) {
|
|
|
11731
11878
|
const msbuild = resolveMsbuildPath();
|
|
11732
11879
|
let output;
|
|
11733
11880
|
try {
|
|
11734
|
-
output =
|
|
11881
|
+
output = execSync31(
|
|
11735
11882
|
`"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
|
|
11736
11883
|
{ encoding: "utf8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
|
|
11737
11884
|
);
|
|
@@ -11803,10 +11950,10 @@ function registerDotnet(program2) {
|
|
|
11803
11950
|
}
|
|
11804
11951
|
|
|
11805
11952
|
// src/commands/editHook/index.ts
|
|
11806
|
-
import
|
|
11953
|
+
import fs20 from "fs";
|
|
11807
11954
|
|
|
11808
11955
|
// src/commands/editHook/extractComments.ts
|
|
11809
|
-
var
|
|
11956
|
+
var SOURCE_EXTENSIONS = [
|
|
11810
11957
|
".ts",
|
|
11811
11958
|
".tsx",
|
|
11812
11959
|
".cts",
|
|
@@ -11818,7 +11965,7 @@ var SOURCE_EXTENSIONS2 = [
|
|
|
11818
11965
|
];
|
|
11819
11966
|
function isSourceFile(filePath) {
|
|
11820
11967
|
if (!filePath) return false;
|
|
11821
|
-
return
|
|
11968
|
+
return SOURCE_EXTENSIONS.some((ext) => filePath.endsWith(ext));
|
|
11822
11969
|
}
|
|
11823
11970
|
function blankNonNewline(text7) {
|
|
11824
11971
|
return text7.replace(/[^\n]/g, " ");
|
|
@@ -11839,6 +11986,22 @@ function extractComments(text7) {
|
|
|
11839
11986
|
return comments3.map((comment3) => comment3.replace(/\s+/g, " ").trim()).filter((comment3) => comment3.length > 0).filter((comment3) => !isCommentExempt(comment3));
|
|
11840
11987
|
}
|
|
11841
11988
|
|
|
11989
|
+
// src/commands/editHook/extractYamlComments.ts
|
|
11990
|
+
function blankNonNewline2(text7) {
|
|
11991
|
+
return text7.replace(/[^\n]/g, " ");
|
|
11992
|
+
}
|
|
11993
|
+
function extractYamlComments(text7) {
|
|
11994
|
+
const work = text7.replace(
|
|
11995
|
+
/"(?:[^"\\]|\\.)*"|'(?:[^']|'')*'/g,
|
|
11996
|
+
blankNonNewline2
|
|
11997
|
+
);
|
|
11998
|
+
const comments3 = [];
|
|
11999
|
+
for (const match of work.matchAll(/(?:^|\s)(#.*)/gm)) {
|
|
12000
|
+
comments3.push(match[1]);
|
|
12001
|
+
}
|
|
12002
|
+
return comments3.map((comment3) => comment3.replace(/\s+/g, " ").trim()).filter((comment3) => comment3.length > 0);
|
|
12003
|
+
}
|
|
12004
|
+
|
|
11842
12005
|
// src/commands/editHook/introducedComments.ts
|
|
11843
12006
|
function introducedComments(added, removed) {
|
|
11844
12007
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -11863,7 +12026,10 @@ function commentWords(comment3) {
|
|
|
11863
12026
|
}
|
|
11864
12027
|
|
|
11865
12028
|
// src/commands/editHook/decideCommentGuard.ts
|
|
11866
|
-
|
|
12029
|
+
function denyReason(marker) {
|
|
12030
|
+
const blockClause = marker === "//" ? ", no block comments" : "";
|
|
12031
|
+
return `This edit introduces a code comment (${marker}), which is blocked by the comment gate. Comments are a last resort \u2014 prefer a clearer name, a smaller function, or a test that makes the comment unnecessary. The comment must not appear in your edit itself. If this one line genuinely earns its keep, use the escape hatch: run \`assist code-comment set <file> <line> "<text>"\` (single line, max 50 chars${blockClause}) to get a pin, then \`assist code-comment confirm <pin>\` to insert it.`;
|
|
12032
|
+
}
|
|
11867
12033
|
function defined(values) {
|
|
11868
12034
|
return values.filter((value) => value != null);
|
|
11869
12035
|
}
|
|
@@ -11892,17 +12058,20 @@ function partitionStrings(input, existingContent) {
|
|
|
11892
12058
|
}
|
|
11893
12059
|
}
|
|
11894
12060
|
function decideCommentGuard(input, existingContent) {
|
|
11895
|
-
|
|
12061
|
+
const filePath = input.tool_input.file_path;
|
|
12062
|
+
const yaml = isYamlFile(filePath);
|
|
12063
|
+
if (!isSourceFile(filePath) && !yaml) return void 0;
|
|
12064
|
+
const extract2 = yaml ? extractYamlComments : extractComments;
|
|
11896
12065
|
const { added, removed } = partitionStrings(input, existingContent);
|
|
11897
12066
|
const introduced = introducedComments(
|
|
11898
|
-
added.flatMap(
|
|
11899
|
-
removed.flatMap(
|
|
12067
|
+
added.flatMap(extract2),
|
|
12068
|
+
removed.flatMap(extract2)
|
|
11900
12069
|
);
|
|
11901
|
-
return introduced.length > 0 ?
|
|
12070
|
+
return introduced.length > 0 ? denyReason(yaml ? "#" : "//") : void 0;
|
|
11902
12071
|
}
|
|
11903
12072
|
|
|
11904
12073
|
// src/commands/editHook/decideOverrideGuard.ts
|
|
11905
|
-
var
|
|
12074
|
+
var DENY_REASON = `Edits touching the '${MAINTAINABILITY_OVERRIDE_MARKER}' marker are blocked. This marker is a human-managed maintainability gate exception \u2014 an agent may not add, change, or remove it. If a file genuinely needs a different threshold, raise it with a human.`;
|
|
11906
12075
|
function candidateStrings(input, existingContent) {
|
|
11907
12076
|
const { tool_name, tool_input } = input;
|
|
11908
12077
|
switch (tool_name) {
|
|
@@ -11928,7 +12097,7 @@ function decideOverrideGuard(input, existingContent) {
|
|
|
11928
12097
|
const touchesMarker = candidateStrings(input, existingContent).some(
|
|
11929
12098
|
(s) => s.includes(MAINTAINABILITY_OVERRIDE_MARKER)
|
|
11930
12099
|
);
|
|
11931
|
-
return touchesMarker ?
|
|
12100
|
+
return touchesMarker ? DENY_REASON : void 0;
|
|
11932
12101
|
}
|
|
11933
12102
|
|
|
11934
12103
|
// src/commands/editHook/index.ts
|
|
@@ -11945,7 +12114,7 @@ function tryParseInput2(raw) {
|
|
|
11945
12114
|
function readExisting(filePath) {
|
|
11946
12115
|
if (!filePath) return void 0;
|
|
11947
12116
|
try {
|
|
11948
|
-
return
|
|
12117
|
+
return fs20.readFileSync(filePath, "utf8");
|
|
11949
12118
|
} catch {
|
|
11950
12119
|
return void 0;
|
|
11951
12120
|
}
|
|
@@ -12203,9 +12372,9 @@ async function countPendingHandovers(orm, origin) {
|
|
|
12203
12372
|
|
|
12204
12373
|
// src/commands/handover/migrateDiskHandovers.ts
|
|
12205
12374
|
import {
|
|
12206
|
-
existsSync as
|
|
12375
|
+
existsSync as existsSync36,
|
|
12207
12376
|
readdirSync as readdirSync7,
|
|
12208
|
-
readFileSync as
|
|
12377
|
+
readFileSync as readFileSync31,
|
|
12209
12378
|
rmSync as rmSync2,
|
|
12210
12379
|
statSync as statSync5
|
|
12211
12380
|
} from "fs";
|
|
@@ -12258,7 +12427,7 @@ function summariseHandoverContent(content) {
|
|
|
12258
12427
|
|
|
12259
12428
|
// src/commands/handover/migrateDiskHandovers.ts
|
|
12260
12429
|
function collectMarkdown(dir) {
|
|
12261
|
-
if (!
|
|
12430
|
+
if (!existsSync36(dir)) return [];
|
|
12262
12431
|
const out = [];
|
|
12263
12432
|
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
12264
12433
|
const full = join38(dir, entry.name);
|
|
@@ -12268,7 +12437,7 @@ function collectMarkdown(dir) {
|
|
|
12268
12437
|
return out;
|
|
12269
12438
|
}
|
|
12270
12439
|
async function migrateFile(orm, origin, file, createdAt) {
|
|
12271
|
-
const content =
|
|
12440
|
+
const content = readFileSync31(file, "utf8");
|
|
12272
12441
|
await saveHandover(orm, {
|
|
12273
12442
|
origin,
|
|
12274
12443
|
summary: summariseHandoverContent(content),
|
|
@@ -12285,7 +12454,7 @@ async function migrateDiskHandovers(orm, origin, cwd = process.cwd()) {
|
|
|
12285
12454
|
migrated++;
|
|
12286
12455
|
}
|
|
12287
12456
|
const handoverPath = getHandoverPath(cwd);
|
|
12288
|
-
if (
|
|
12457
|
+
if (existsSync36(handoverPath)) {
|
|
12289
12458
|
await migrateFile(orm, origin, handoverPath, statSync5(handoverPath).mtime);
|
|
12290
12459
|
migrated++;
|
|
12291
12460
|
}
|
|
@@ -12498,10 +12667,10 @@ function acceptanceCriteria(issueKey) {
|
|
|
12498
12667
|
}
|
|
12499
12668
|
|
|
12500
12669
|
// src/commands/jira/jiraAuth.ts
|
|
12501
|
-
import { execSync as
|
|
12670
|
+
import { execSync as execSync32 } from "child_process";
|
|
12502
12671
|
|
|
12503
12672
|
// src/shared/loadJson.ts
|
|
12504
|
-
import { existsSync as
|
|
12673
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync13, readFileSync as readFileSync32, writeFileSync as writeFileSync27 } from "fs";
|
|
12505
12674
|
import { homedir as homedir15 } from "os";
|
|
12506
12675
|
import { join as join39 } from "path";
|
|
12507
12676
|
function getStoreDir() {
|
|
@@ -12512,9 +12681,9 @@ function getStorePath(filename) {
|
|
|
12512
12681
|
}
|
|
12513
12682
|
function loadJson(filename) {
|
|
12514
12683
|
const path57 = getStorePath(filename);
|
|
12515
|
-
if (
|
|
12684
|
+
if (existsSync37(path57)) {
|
|
12516
12685
|
try {
|
|
12517
|
-
return JSON.parse(
|
|
12686
|
+
return JSON.parse(readFileSync32(path57, "utf8"));
|
|
12518
12687
|
} catch {
|
|
12519
12688
|
return {};
|
|
12520
12689
|
}
|
|
@@ -12523,7 +12692,7 @@ function loadJson(filename) {
|
|
|
12523
12692
|
}
|
|
12524
12693
|
function saveJson(filename, data) {
|
|
12525
12694
|
const dir = getStoreDir();
|
|
12526
|
-
if (!
|
|
12695
|
+
if (!existsSync37(dir)) {
|
|
12527
12696
|
mkdirSync13(dir, { recursive: true });
|
|
12528
12697
|
}
|
|
12529
12698
|
writeFileSync27(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
@@ -12562,7 +12731,7 @@ async function jiraAuth() {
|
|
|
12562
12731
|
console.error("All fields are required.");
|
|
12563
12732
|
process.exit(1);
|
|
12564
12733
|
}
|
|
12565
|
-
|
|
12734
|
+
execSync32(`acli jira auth login --site ${site} --email "${email}" --token`, {
|
|
12566
12735
|
encoding: "utf8",
|
|
12567
12736
|
input: token,
|
|
12568
12737
|
stdio: ["pipe", "inherit", "inherit"]
|
|
@@ -12698,7 +12867,7 @@ import { resolve as resolve11 } from "path";
|
|
|
12698
12867
|
import chalk133 from "chalk";
|
|
12699
12868
|
|
|
12700
12869
|
// src/commands/mermaid/exportFile.ts
|
|
12701
|
-
import { readFileSync as
|
|
12870
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync28 } from "fs";
|
|
12702
12871
|
import { basename as basename8, extname, resolve as resolve10 } from "path";
|
|
12703
12872
|
import chalk132 from "chalk";
|
|
12704
12873
|
|
|
@@ -12724,7 +12893,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
12724
12893
|
|
|
12725
12894
|
// src/commands/mermaid/exportFile.ts
|
|
12726
12895
|
async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
12727
|
-
const content =
|
|
12896
|
+
const content = readFileSync33(file, "utf8");
|
|
12728
12897
|
const blocks = extractMermaidBlocks(content);
|
|
12729
12898
|
const stem = basename8(file, extname(file));
|
|
12730
12899
|
if (onlyIndex !== void 0) {
|
|
@@ -13008,7 +13177,7 @@ import { join as join44 } from "path";
|
|
|
13008
13177
|
import chalk136 from "chalk";
|
|
13009
13178
|
|
|
13010
13179
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
13011
|
-
import { readFileSync as
|
|
13180
|
+
import { readFileSync as readFileSync34 } from "fs";
|
|
13012
13181
|
|
|
13013
13182
|
// src/commands/netcap/parseRscRows.ts
|
|
13014
13183
|
var isRscRef = (v) => typeof v === "string" && /^\$[0-9a-fL@]/.test(v);
|
|
@@ -13404,7 +13573,7 @@ function extractVoyagerPosts(body) {
|
|
|
13404
13573
|
|
|
13405
13574
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
13406
13575
|
function captureEntries(captureFile) {
|
|
13407
|
-
const lines =
|
|
13576
|
+
const lines = readFileSync34(captureFile, "utf8").split("\n").filter(Boolean);
|
|
13408
13577
|
const entries = [];
|
|
13409
13578
|
for (const line of lines) {
|
|
13410
13579
|
let entry;
|
|
@@ -13564,7 +13733,7 @@ function registerPrompts(program2) {
|
|
|
13564
13733
|
}
|
|
13565
13734
|
|
|
13566
13735
|
// src/commands/prs/shared.ts
|
|
13567
|
-
import { execSync as
|
|
13736
|
+
import { execSync as execSync33 } from "child_process";
|
|
13568
13737
|
function isGhNotInstalled(error) {
|
|
13569
13738
|
if (error instanceof Error) {
|
|
13570
13739
|
const msg = error.message.toLowerCase();
|
|
@@ -13582,20 +13751,20 @@ function getRepoInfo() {
|
|
|
13582
13751
|
const preferred = getPreferredRemoteRepo();
|
|
13583
13752
|
if (preferred) return preferred;
|
|
13584
13753
|
const repoInfo = JSON.parse(
|
|
13585
|
-
|
|
13754
|
+
execSync33("gh repo view --json owner,name", { encoding: "utf8" })
|
|
13586
13755
|
);
|
|
13587
13756
|
return { org: repoInfo.owner.login, repo: repoInfo.name };
|
|
13588
13757
|
}
|
|
13589
13758
|
function getCurrentBranch() {
|
|
13590
|
-
return
|
|
13759
|
+
return execSync33("git rev-parse --abbrev-ref HEAD", {
|
|
13591
13760
|
encoding: "utf8"
|
|
13592
13761
|
}).trim();
|
|
13593
13762
|
}
|
|
13594
13763
|
function viewCurrentPr(fields) {
|
|
13595
13764
|
const { org, repo } = getRepoInfo();
|
|
13596
|
-
const
|
|
13765
|
+
const branch2 = getCurrentBranch();
|
|
13597
13766
|
return JSON.parse(
|
|
13598
|
-
|
|
13767
|
+
execSync33(`gh pr view ${branch2} --json ${fields} -R ${org}/${repo}`, {
|
|
13599
13768
|
encoding: "utf8"
|
|
13600
13769
|
})
|
|
13601
13770
|
);
|
|
@@ -13699,7 +13868,7 @@ function comment2(path57, line, body, startLine) {
|
|
|
13699
13868
|
}
|
|
13700
13869
|
|
|
13701
13870
|
// src/commands/prs/edit.ts
|
|
13702
|
-
import { execSync as
|
|
13871
|
+
import { execSync as execSync34 } from "child_process";
|
|
13703
13872
|
|
|
13704
13873
|
// src/commands/prs/buildPrBody.ts
|
|
13705
13874
|
function jiraBrowseUrl(key) {
|
|
@@ -13872,23 +14041,23 @@ function edit(options2) {
|
|
|
13872
14041
|
if (options2.title) args.push(`--title ${shellQuote(options2.title)}`);
|
|
13873
14042
|
args.push(`--body ${shellQuote(newBody)}`);
|
|
13874
14043
|
try {
|
|
13875
|
-
|
|
14044
|
+
execSync34(args.join(" "), { stdio: "inherit" });
|
|
13876
14045
|
} catch {
|
|
13877
14046
|
process.exit(1);
|
|
13878
14047
|
}
|
|
13879
14048
|
}
|
|
13880
14049
|
|
|
13881
14050
|
// src/commands/prs/fixed.ts
|
|
13882
|
-
import { execSync as
|
|
14051
|
+
import { execSync as execSync37 } from "child_process";
|
|
13883
14052
|
|
|
13884
14053
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
13885
|
-
import { execSync as
|
|
14054
|
+
import { execSync as execSync36 } from "child_process";
|
|
13886
14055
|
import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
|
|
13887
14056
|
import { tmpdir as tmpdir5 } from "os";
|
|
13888
14057
|
import { join as join46 } from "path";
|
|
13889
14058
|
|
|
13890
14059
|
// src/commands/prs/loadCommentsCache.ts
|
|
13891
|
-
import { existsSync as
|
|
14060
|
+
import { existsSync as existsSync38, readFileSync as readFileSync35, unlinkSync as unlinkSync11 } from "fs";
|
|
13892
14061
|
import { join as join45 } from "path";
|
|
13893
14062
|
import { parse as parse2 } from "yaml";
|
|
13894
14063
|
function getCachePath(prNumber) {
|
|
@@ -13896,24 +14065,24 @@ function getCachePath(prNumber) {
|
|
|
13896
14065
|
}
|
|
13897
14066
|
function loadCommentsCache(prNumber) {
|
|
13898
14067
|
const cachePath = getCachePath(prNumber);
|
|
13899
|
-
if (!
|
|
14068
|
+
if (!existsSync38(cachePath)) {
|
|
13900
14069
|
return null;
|
|
13901
14070
|
}
|
|
13902
|
-
const content =
|
|
14071
|
+
const content = readFileSync35(cachePath, "utf8");
|
|
13903
14072
|
return parse2(content);
|
|
13904
14073
|
}
|
|
13905
14074
|
function deleteCommentsCache(prNumber) {
|
|
13906
14075
|
const cachePath = getCachePath(prNumber);
|
|
13907
|
-
if (
|
|
14076
|
+
if (existsSync38(cachePath)) {
|
|
13908
14077
|
unlinkSync11(cachePath);
|
|
13909
14078
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
13910
14079
|
}
|
|
13911
14080
|
}
|
|
13912
14081
|
|
|
13913
14082
|
// src/commands/prs/replyToComment.ts
|
|
13914
|
-
import { execSync as
|
|
14083
|
+
import { execSync as execSync35 } from "child_process";
|
|
13915
14084
|
function replyToComment(org, repo, prNumber, commentId, message) {
|
|
13916
|
-
|
|
14085
|
+
execSync35(
|
|
13917
14086
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, String.raw`\"`)}" -F in_reply_to=${commentId}`,
|
|
13918
14087
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
13919
14088
|
);
|
|
@@ -13925,7 +14094,7 @@ function resolveThread(threadId) {
|
|
|
13925
14094
|
const queryFile = join46(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
|
|
13926
14095
|
writeFileSync30(queryFile, mutation);
|
|
13927
14096
|
try {
|
|
13928
|
-
|
|
14097
|
+
execSync36(
|
|
13929
14098
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
13930
14099
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
13931
14100
|
);
|
|
@@ -13977,7 +14146,7 @@ function resolveCommentWithReply(commentId, message) {
|
|
|
13977
14146
|
// src/commands/prs/fixed.ts
|
|
13978
14147
|
function verifySha(sha) {
|
|
13979
14148
|
try {
|
|
13980
|
-
return
|
|
14149
|
+
return execSync37(`git rev-parse --verify ${sha}`, {
|
|
13981
14150
|
encoding: "utf8"
|
|
13982
14151
|
}).trim();
|
|
13983
14152
|
} catch {
|
|
@@ -13991,7 +14160,7 @@ function fixed(commentId, sha) {
|
|
|
13991
14160
|
const { org, repo } = getRepoInfo();
|
|
13992
14161
|
const repoUrl = `https://github.com/${org}/${repo}`;
|
|
13993
14162
|
const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
|
|
13994
|
-
|
|
14163
|
+
execSync37("git push", { stdio: "inherit" });
|
|
13995
14164
|
resolveCommentWithReply(commentId, message);
|
|
13996
14165
|
} catch (error) {
|
|
13997
14166
|
if (isGhNotInstalled(error)) {
|
|
@@ -14004,12 +14173,12 @@ function fixed(commentId, sha) {
|
|
|
14004
14173
|
}
|
|
14005
14174
|
|
|
14006
14175
|
// src/commands/prs/listComments/index.ts
|
|
14007
|
-
import { existsSync as
|
|
14176
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync15, writeFileSync as writeFileSync32 } from "fs";
|
|
14008
14177
|
import { join as join48 } from "path";
|
|
14009
14178
|
import { stringify } from "yaml";
|
|
14010
14179
|
|
|
14011
14180
|
// src/commands/prs/fetchThreadIds.ts
|
|
14012
|
-
import { execSync as
|
|
14181
|
+
import { execSync as execSync38 } from "child_process";
|
|
14013
14182
|
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync31 } from "fs";
|
|
14014
14183
|
import { tmpdir as tmpdir6 } from "os";
|
|
14015
14184
|
import { join as join47 } from "path";
|
|
@@ -14018,7 +14187,7 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
14018
14187
|
const queryFile = join47(tmpdir6(), `gh-query-${Date.now()}.graphql`);
|
|
14019
14188
|
writeFileSync31(queryFile, THREAD_QUERY);
|
|
14020
14189
|
try {
|
|
14021
|
-
const result =
|
|
14190
|
+
const result = execSync38(
|
|
14022
14191
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
14023
14192
|
{ encoding: "utf8" }
|
|
14024
14193
|
);
|
|
@@ -14040,9 +14209,9 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
14040
14209
|
}
|
|
14041
14210
|
|
|
14042
14211
|
// src/commands/prs/listComments/fetchReviewComments.ts
|
|
14043
|
-
import { execSync as
|
|
14212
|
+
import { execSync as execSync39 } from "child_process";
|
|
14044
14213
|
function fetchJson(endpoint) {
|
|
14045
|
-
const result =
|
|
14214
|
+
const result = execSync39(`gh api --paginate ${endpoint}`, {
|
|
14046
14215
|
encoding: "utf8"
|
|
14047
14216
|
});
|
|
14048
14217
|
if (!result.trim()) return [];
|
|
@@ -14130,7 +14299,7 @@ function printComments2(result) {
|
|
|
14130
14299
|
// src/commands/prs/listComments/index.ts
|
|
14131
14300
|
function writeCommentsCache(prNumber, comments3) {
|
|
14132
14301
|
const assistDir = join48(process.cwd(), ".assist");
|
|
14133
|
-
if (!
|
|
14302
|
+
if (!existsSync39(assistDir)) {
|
|
14134
14303
|
mkdirSync15(assistDir, { recursive: true });
|
|
14135
14304
|
}
|
|
14136
14305
|
const cacheData = {
|
|
@@ -14181,7 +14350,7 @@ async function listComments() {
|
|
|
14181
14350
|
}
|
|
14182
14351
|
|
|
14183
14352
|
// src/commands/prs/prs/index.ts
|
|
14184
|
-
import { execSync as
|
|
14353
|
+
import { execSync as execSync40 } from "child_process";
|
|
14185
14354
|
|
|
14186
14355
|
// src/commands/prs/prs/displayPaginated/index.ts
|
|
14187
14356
|
import enquirer9 from "enquirer";
|
|
@@ -14288,7 +14457,7 @@ async function prs(options2) {
|
|
|
14288
14457
|
const state = options2.open ? "open" : options2.closed ? "closed" : "all";
|
|
14289
14458
|
try {
|
|
14290
14459
|
const { org, repo } = getRepoInfo();
|
|
14291
|
-
const result =
|
|
14460
|
+
const result = execSync40(
|
|
14292
14461
|
`gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100 -R ${org}/${repo}`,
|
|
14293
14462
|
{ encoding: "utf8" }
|
|
14294
14463
|
);
|
|
@@ -14311,7 +14480,7 @@ async function prs(options2) {
|
|
|
14311
14480
|
}
|
|
14312
14481
|
|
|
14313
14482
|
// src/commands/prs/raise.ts
|
|
14314
|
-
import { execSync as
|
|
14483
|
+
import { execSync as execSync41 } from "child_process";
|
|
14315
14484
|
|
|
14316
14485
|
// src/commands/prs/buildCreateArgs.ts
|
|
14317
14486
|
function buildCreateArgs(title, body, options2) {
|
|
@@ -14371,7 +14540,7 @@ function raise(options2) {
|
|
|
14371
14540
|
`--body ${shellQuote(body)}`
|
|
14372
14541
|
] : buildCreateArgs(options2.title, body, options2);
|
|
14373
14542
|
try {
|
|
14374
|
-
|
|
14543
|
+
execSync41(args.join(" "), { stdio: "inherit" });
|
|
14375
14544
|
} catch {
|
|
14376
14545
|
process.exit(1);
|
|
14377
14546
|
}
|
|
@@ -14403,7 +14572,7 @@ function reply(commentId, body) {
|
|
|
14403
14572
|
}
|
|
14404
14573
|
|
|
14405
14574
|
// src/commands/prs/wontfix.ts
|
|
14406
|
-
import { execSync as
|
|
14575
|
+
import { execSync as execSync42 } from "child_process";
|
|
14407
14576
|
function validateReason(reason) {
|
|
14408
14577
|
const lowerReason = reason.toLowerCase();
|
|
14409
14578
|
if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
|
|
@@ -14420,7 +14589,7 @@ function validateShaReferences(reason) {
|
|
|
14420
14589
|
const invalidShas = [];
|
|
14421
14590
|
for (const sha of shas) {
|
|
14422
14591
|
try {
|
|
14423
|
-
|
|
14592
|
+
execSync42(`git cat-file -t ${sha}`, { stdio: "pipe" });
|
|
14424
14593
|
} catch {
|
|
14425
14594
|
invalidShas.push(sha);
|
|
14426
14595
|
}
|
|
@@ -14582,10 +14751,10 @@ import chalk143 from "chalk";
|
|
|
14582
14751
|
import Enquirer2 from "enquirer";
|
|
14583
14752
|
|
|
14584
14753
|
// src/commands/ravendb/searchItems.ts
|
|
14585
|
-
import { execSync as
|
|
14754
|
+
import { execSync as execSync43 } from "child_process";
|
|
14586
14755
|
import chalk142 from "chalk";
|
|
14587
14756
|
function opExec(args) {
|
|
14588
|
-
return
|
|
14757
|
+
return execSync43(`op ${args}`, {
|
|
14589
14758
|
encoding: "utf8",
|
|
14590
14759
|
stdio: ["pipe", "pipe", "pipe"]
|
|
14591
14760
|
}).trim();
|
|
@@ -14737,7 +14906,7 @@ ${errorText}`
|
|
|
14737
14906
|
}
|
|
14738
14907
|
|
|
14739
14908
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
14740
|
-
import { execSync as
|
|
14909
|
+
import { execSync as execSync44 } from "child_process";
|
|
14741
14910
|
import chalk147 from "chalk";
|
|
14742
14911
|
function resolveOpSecret(reference) {
|
|
14743
14912
|
if (!reference.startsWith("op://")) {
|
|
@@ -14745,7 +14914,7 @@ function resolveOpSecret(reference) {
|
|
|
14745
14914
|
process.exit(1);
|
|
14746
14915
|
}
|
|
14747
14916
|
try {
|
|
14748
|
-
return
|
|
14917
|
+
return execSync44(`op read "${reference}"`, {
|
|
14749
14918
|
encoding: "utf8",
|
|
14750
14919
|
stdio: ["pipe", "pipe", "pipe"]
|
|
14751
14920
|
}).trim();
|
|
@@ -14994,18 +15163,18 @@ Refactor check failed:
|
|
|
14994
15163
|
}
|
|
14995
15164
|
|
|
14996
15165
|
// src/commands/refactor/check/getViolations/index.ts
|
|
14997
|
-
import { execSync as
|
|
14998
|
-
import
|
|
15166
|
+
import { execSync as execSync45 } from "child_process";
|
|
15167
|
+
import fs22 from "fs";
|
|
14999
15168
|
import { minimatch as minimatch6 } from "minimatch";
|
|
15000
15169
|
|
|
15001
15170
|
// src/commands/refactor/check/getViolations/getIgnoredFiles.ts
|
|
15002
|
-
import
|
|
15171
|
+
import fs21 from "fs";
|
|
15003
15172
|
var REFACTOR_YML_PATH = "refactor.yml";
|
|
15004
15173
|
function parseRefactorYml() {
|
|
15005
|
-
if (!
|
|
15174
|
+
if (!fs21.existsSync(REFACTOR_YML_PATH)) {
|
|
15006
15175
|
return [];
|
|
15007
15176
|
}
|
|
15008
|
-
const content =
|
|
15177
|
+
const content = fs21.readFileSync(REFACTOR_YML_PATH, "utf8");
|
|
15009
15178
|
const entries = [];
|
|
15010
15179
|
const lines = content.split("\n");
|
|
15011
15180
|
let currentEntry = {};
|
|
@@ -15035,7 +15204,7 @@ function getIgnoredFiles() {
|
|
|
15035
15204
|
|
|
15036
15205
|
// src/commands/refactor/check/getViolations/index.ts
|
|
15037
15206
|
function countLines(filePath) {
|
|
15038
|
-
const content =
|
|
15207
|
+
const content = fs22.readFileSync(filePath, "utf8");
|
|
15039
15208
|
return content.split("\n").length;
|
|
15040
15209
|
}
|
|
15041
15210
|
function getGitFiles(options2) {
|
|
@@ -15044,7 +15213,7 @@ function getGitFiles(options2) {
|
|
|
15044
15213
|
}
|
|
15045
15214
|
const files = /* @__PURE__ */ new Set();
|
|
15046
15215
|
if (options2.staged || options2.modified) {
|
|
15047
|
-
const staged =
|
|
15216
|
+
const staged = execSync45("git diff --cached --name-only", {
|
|
15048
15217
|
encoding: "utf8"
|
|
15049
15218
|
});
|
|
15050
15219
|
for (const file of staged.trim().split("\n").filter(Boolean)) {
|
|
@@ -15052,7 +15221,7 @@ function getGitFiles(options2) {
|
|
|
15052
15221
|
}
|
|
15053
15222
|
}
|
|
15054
15223
|
if (options2.unstaged || options2.modified) {
|
|
15055
|
-
const unstaged =
|
|
15224
|
+
const unstaged = execSync45("git diff --name-only", { encoding: "utf8" });
|
|
15056
15225
|
for (const file of unstaged.trim().split("\n").filter(Boolean)) {
|
|
15057
15226
|
files.add(file);
|
|
15058
15227
|
}
|
|
@@ -15769,12 +15938,12 @@ import chalk155 from "chalk";
|
|
|
15769
15938
|
import { Project as Project4 } from "ts-morph";
|
|
15770
15939
|
|
|
15771
15940
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
15772
|
-
import
|
|
15941
|
+
import fs23 from "fs";
|
|
15773
15942
|
import path33 from "path";
|
|
15774
15943
|
import { Project as Project3 } from "ts-morph";
|
|
15775
15944
|
function findTsConfig(sourcePath) {
|
|
15776
15945
|
const rootConfig = path33.resolve("tsconfig.json");
|
|
15777
|
-
if (!
|
|
15946
|
+
if (!fs23.existsSync(rootConfig)) return rootConfig;
|
|
15778
15947
|
const tried = /* @__PURE__ */ new Set();
|
|
15779
15948
|
const candidates = [rootConfig, ...readReferences(rootConfig)];
|
|
15780
15949
|
for (const candidate of candidates) {
|
|
@@ -15782,7 +15951,7 @@ function findTsConfig(sourcePath) {
|
|
|
15782
15951
|
tried.add(candidate);
|
|
15783
15952
|
if (projectIncludes(candidate, sourcePath)) return candidate;
|
|
15784
15953
|
}
|
|
15785
|
-
const siblings =
|
|
15954
|
+
const siblings = fs23.readdirSync(path33.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path33.resolve(path33.dirname(rootConfig), f));
|
|
15786
15955
|
for (const sibling of siblings) {
|
|
15787
15956
|
if (tried.has(sibling)) continue;
|
|
15788
15957
|
tried.add(sibling);
|
|
@@ -15791,8 +15960,8 @@ function findTsConfig(sourcePath) {
|
|
|
15791
15960
|
return rootConfig;
|
|
15792
15961
|
}
|
|
15793
15962
|
function readReferences(configPath) {
|
|
15794
|
-
if (!
|
|
15795
|
-
const raw =
|
|
15963
|
+
if (!fs23.existsSync(configPath)) return [];
|
|
15964
|
+
const raw = fs23.readFileSync(configPath, "utf8");
|
|
15796
15965
|
const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
15797
15966
|
let parsed;
|
|
15798
15967
|
try {
|
|
@@ -15804,8 +15973,8 @@ function readReferences(configPath) {
|
|
|
15804
15973
|
const cwd = path33.dirname(configPath);
|
|
15805
15974
|
return parsed.references.map((ref) => {
|
|
15806
15975
|
const refPath = path33.resolve(cwd, ref.path);
|
|
15807
|
-
return
|
|
15808
|
-
}).filter((p) =>
|
|
15976
|
+
return fs23.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path33.join(refPath, "tsconfig.json") : refPath;
|
|
15977
|
+
}).filter((p) => fs23.existsSync(p));
|
|
15809
15978
|
}
|
|
15810
15979
|
function projectIncludes(configPath, sourcePath) {
|
|
15811
15980
|
try {
|
|
@@ -15855,25 +16024,25 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
15855
16024
|
}
|
|
15856
16025
|
|
|
15857
16026
|
// src/commands/refactor/ignore.ts
|
|
15858
|
-
import
|
|
16027
|
+
import fs24 from "fs";
|
|
15859
16028
|
import chalk157 from "chalk";
|
|
15860
16029
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
15861
16030
|
function ignore(file) {
|
|
15862
|
-
if (!
|
|
16031
|
+
if (!fs24.existsSync(file)) {
|
|
15863
16032
|
console.error(chalk157.red(`Error: File does not exist: ${file}`));
|
|
15864
16033
|
process.exit(1);
|
|
15865
16034
|
}
|
|
15866
|
-
const content =
|
|
16035
|
+
const content = fs24.readFileSync(file, "utf8");
|
|
15867
16036
|
const lineCount = content.split("\n").length;
|
|
15868
16037
|
const maxLines = lineCount + 10;
|
|
15869
16038
|
const entry = `- file: ${file}
|
|
15870
16039
|
maxLines: ${maxLines}
|
|
15871
16040
|
`;
|
|
15872
|
-
if (
|
|
15873
|
-
const existing =
|
|
15874
|
-
|
|
16041
|
+
if (fs24.existsSync(REFACTOR_YML_PATH2)) {
|
|
16042
|
+
const existing = fs24.readFileSync(REFACTOR_YML_PATH2, "utf8");
|
|
16043
|
+
fs24.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
|
|
15875
16044
|
} else {
|
|
15876
|
-
|
|
16045
|
+
fs24.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
15877
16046
|
}
|
|
15878
16047
|
console.log(
|
|
15879
16048
|
chalk157.green(
|
|
@@ -15883,12 +16052,12 @@ function ignore(file) {
|
|
|
15883
16052
|
}
|
|
15884
16053
|
|
|
15885
16054
|
// src/commands/refactor/rename/index.ts
|
|
15886
|
-
import
|
|
16055
|
+
import fs27 from "fs";
|
|
15887
16056
|
import path40 from "path";
|
|
15888
16057
|
import chalk160 from "chalk";
|
|
15889
16058
|
|
|
15890
16059
|
// src/commands/refactor/rename/applyRename.ts
|
|
15891
|
-
import
|
|
16060
|
+
import fs26 from "fs";
|
|
15892
16061
|
import path37 from "path";
|
|
15893
16062
|
import chalk158 from "chalk";
|
|
15894
16063
|
|
|
@@ -15896,7 +16065,7 @@ import chalk158 from "chalk";
|
|
|
15896
16065
|
import path36 from "path";
|
|
15897
16066
|
|
|
15898
16067
|
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
15899
|
-
import
|
|
16068
|
+
import fs25 from "fs";
|
|
15900
16069
|
function getOrCreateList(map, key) {
|
|
15901
16070
|
const list5 = map.get(key) ?? [];
|
|
15902
16071
|
if (!map.has(key)) map.set(key, list5);
|
|
@@ -15915,7 +16084,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
|
15915
16084
|
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
15916
16085
|
}
|
|
15917
16086
|
function applyFileRewrites(file, fileRewrites) {
|
|
15918
|
-
let content =
|
|
16087
|
+
let content = fs25.readFileSync(file, "utf8");
|
|
15919
16088
|
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
15920
16089
|
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
15921
16090
|
}
|
|
@@ -15994,12 +16163,12 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
15994
16163
|
function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
15995
16164
|
const updatedContents = applyRewrites(rewrites);
|
|
15996
16165
|
for (const [file, content] of updatedContents) {
|
|
15997
|
-
|
|
16166
|
+
fs26.writeFileSync(file, content, "utf8");
|
|
15998
16167
|
console.log(chalk158.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
15999
16168
|
}
|
|
16000
16169
|
const destDir = path37.dirname(destPath);
|
|
16001
|
-
if (!
|
|
16002
|
-
|
|
16170
|
+
if (!fs26.existsSync(destDir)) fs26.mkdirSync(destDir, { recursive: true });
|
|
16171
|
+
fs26.renameSync(sourcePath, destPath);
|
|
16003
16172
|
console.log(
|
|
16004
16173
|
chalk158.white(
|
|
16005
16174
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
@@ -16107,11 +16276,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
16107
16276
|
const cwd = process.cwd();
|
|
16108
16277
|
const relSource = path40.relative(cwd, sourcePath);
|
|
16109
16278
|
const relDest = path40.relative(cwd, destPath);
|
|
16110
|
-
if (!
|
|
16279
|
+
if (!fs27.existsSync(sourcePath)) {
|
|
16111
16280
|
console.log(chalk160.red(`File not found: ${source}`));
|
|
16112
16281
|
process.exit(1);
|
|
16113
16282
|
}
|
|
16114
|
-
if (destPath !== sourcePath &&
|
|
16283
|
+
if (destPath !== sourcePath && fs27.existsSync(destPath)) {
|
|
16115
16284
|
console.log(chalk160.red(`Destination already exists: ${destination}`));
|
|
16116
16285
|
process.exit(1);
|
|
16117
16286
|
}
|
|
@@ -16336,27 +16505,27 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
16336
16505
|
}
|
|
16337
16506
|
|
|
16338
16507
|
// src/commands/refactor/restructure/executePlan.ts
|
|
16339
|
-
import
|
|
16508
|
+
import fs28 from "fs";
|
|
16340
16509
|
import path45 from "path";
|
|
16341
16510
|
import chalk163 from "chalk";
|
|
16342
16511
|
function executePlan(plan2) {
|
|
16343
16512
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
16344
16513
|
for (const [file, content] of updatedContents) {
|
|
16345
|
-
|
|
16514
|
+
fs28.writeFileSync(file, content, "utf8");
|
|
16346
16515
|
console.log(
|
|
16347
16516
|
chalk163.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
16348
16517
|
);
|
|
16349
16518
|
}
|
|
16350
16519
|
for (const dir of plan2.newDirectories) {
|
|
16351
|
-
|
|
16520
|
+
fs28.mkdirSync(dir, { recursive: true });
|
|
16352
16521
|
console.log(chalk163.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
16353
16522
|
}
|
|
16354
16523
|
for (const move2 of plan2.moves) {
|
|
16355
16524
|
const targetDir = path45.dirname(move2.to);
|
|
16356
|
-
if (!
|
|
16357
|
-
|
|
16525
|
+
if (!fs28.existsSync(targetDir)) {
|
|
16526
|
+
fs28.mkdirSync(targetDir, { recursive: true });
|
|
16358
16527
|
}
|
|
16359
|
-
|
|
16528
|
+
fs28.renameSync(move2.from, move2.to);
|
|
16360
16529
|
console.log(
|
|
16361
16530
|
chalk163.white(
|
|
16362
16531
|
` Moved ${path45.relative(process.cwd(), move2.from)} \u2192 ${path45.relative(process.cwd(), move2.to)}`
|
|
@@ -16368,10 +16537,10 @@ function executePlan(plan2) {
|
|
|
16368
16537
|
function removeEmptyDirectories(dirs) {
|
|
16369
16538
|
const unique = [...new Set(dirs)];
|
|
16370
16539
|
for (const dir of unique) {
|
|
16371
|
-
if (!
|
|
16372
|
-
const entries =
|
|
16540
|
+
if (!fs28.existsSync(dir)) continue;
|
|
16541
|
+
const entries = fs28.readdirSync(dir);
|
|
16373
16542
|
if (entries.length === 0) {
|
|
16374
|
-
|
|
16543
|
+
fs28.rmdirSync(dir);
|
|
16375
16544
|
console.log(
|
|
16376
16545
|
chalk163.dim(
|
|
16377
16546
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
@@ -16385,18 +16554,18 @@ function removeEmptyDirectories(dirs) {
|
|
|
16385
16554
|
import path47 from "path";
|
|
16386
16555
|
|
|
16387
16556
|
// src/commands/refactor/restructure/planFileMoves/shared.ts
|
|
16388
|
-
import
|
|
16557
|
+
import fs29 from "fs";
|
|
16389
16558
|
function emptyResult() {
|
|
16390
16559
|
return { moves: [], directories: [], warnings: [] };
|
|
16391
16560
|
}
|
|
16392
16561
|
function checkDirConflict(result, label2, dir) {
|
|
16393
|
-
if (!
|
|
16562
|
+
if (!fs29.existsSync(dir)) return false;
|
|
16394
16563
|
result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
|
|
16395
16564
|
return true;
|
|
16396
16565
|
}
|
|
16397
16566
|
|
|
16398
16567
|
// src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
|
|
16399
|
-
import
|
|
16568
|
+
import fs30 from "fs";
|
|
16400
16569
|
import path46 from "path";
|
|
16401
16570
|
function collectEntry(results, dir, entry) {
|
|
16402
16571
|
const full = path46.join(dir, entry.name);
|
|
@@ -16404,9 +16573,9 @@ function collectEntry(results, dir, entry) {
|
|
|
16404
16573
|
results.push(...items2);
|
|
16405
16574
|
}
|
|
16406
16575
|
function listFilesRecursive(dir) {
|
|
16407
|
-
if (!
|
|
16576
|
+
if (!fs30.existsSync(dir)) return [];
|
|
16408
16577
|
const results = [];
|
|
16409
|
-
for (const entry of
|
|
16578
|
+
for (const entry of fs30.readdirSync(dir, { withFileTypes: true })) {
|
|
16410
16579
|
collectEntry(results, dir, entry);
|
|
16411
16580
|
}
|
|
16412
16581
|
return results;
|
|
@@ -16696,9 +16865,9 @@ function buildReviewPaths(repoRoot, key) {
|
|
|
16696
16865
|
}
|
|
16697
16866
|
|
|
16698
16867
|
// src/commands/review/fetchExistingComments.ts
|
|
16699
|
-
import { execSync as
|
|
16868
|
+
import { execSync as execSync46 } from "child_process";
|
|
16700
16869
|
function fetchRawComments(org, repo, prNumber) {
|
|
16701
|
-
const out =
|
|
16870
|
+
const out = execSync46(
|
|
16702
16871
|
`gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
|
|
16703
16872
|
{ encoding: "utf8", maxBuffer: 64 * 1024 * 1024 }
|
|
16704
16873
|
);
|
|
@@ -16729,14 +16898,14 @@ function fetchExistingComments() {
|
|
|
16729
16898
|
}
|
|
16730
16899
|
|
|
16731
16900
|
// src/commands/review/gatherContext.ts
|
|
16732
|
-
import { execSync as
|
|
16901
|
+
import { execSync as execSync49 } from "child_process";
|
|
16733
16902
|
|
|
16734
16903
|
// src/commands/review/fetchPrDiff.ts
|
|
16735
|
-
import { execSync as
|
|
16904
|
+
import { execSync as execSync47 } from "child_process";
|
|
16736
16905
|
function fetchPrDiff(prNumber, baseSha, headSha) {
|
|
16737
16906
|
const { org, repo } = getRepoInfo();
|
|
16738
16907
|
try {
|
|
16739
|
-
return
|
|
16908
|
+
return execSync47(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
|
|
16740
16909
|
encoding: "utf8",
|
|
16741
16910
|
maxBuffer: 256 * 1024 * 1024,
|
|
16742
16911
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -16751,36 +16920,36 @@ function isDiffTooLarge(error) {
|
|
|
16751
16920
|
}
|
|
16752
16921
|
function fetchDiffViaGit(baseSha, headSha) {
|
|
16753
16922
|
try {
|
|
16754
|
-
|
|
16923
|
+
execSync47(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
|
|
16755
16924
|
} catch {
|
|
16756
16925
|
}
|
|
16757
|
-
return
|
|
16926
|
+
return execSync47(`git diff ${baseSha}...${headSha}`, {
|
|
16758
16927
|
encoding: "utf8",
|
|
16759
16928
|
maxBuffer: 256 * 1024 * 1024
|
|
16760
16929
|
});
|
|
16761
16930
|
}
|
|
16762
16931
|
|
|
16763
16932
|
// src/commands/review/fetchPrDiffInfo.ts
|
|
16764
|
-
import { execSync as
|
|
16933
|
+
import { execSync as execSync48 } from "child_process";
|
|
16765
16934
|
function getCurrentBranch2() {
|
|
16766
|
-
return
|
|
16935
|
+
return execSync48("git rev-parse --abbrev-ref HEAD", {
|
|
16767
16936
|
encoding: "utf8"
|
|
16768
16937
|
}).trim();
|
|
16769
16938
|
}
|
|
16770
16939
|
function fetchPrDiffInfo() {
|
|
16771
16940
|
const { org, repo } = getRepoInfo();
|
|
16772
|
-
const
|
|
16941
|
+
const branch2 = getCurrentBranch2();
|
|
16773
16942
|
const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
|
|
16774
16943
|
let raw;
|
|
16775
16944
|
try {
|
|
16776
|
-
raw =
|
|
16945
|
+
raw = execSync48(`gh pr view ${branch2} --json ${fields} -R ${org}/${repo}`, {
|
|
16777
16946
|
encoding: "utf8",
|
|
16778
16947
|
stdio: ["ignore", "pipe", "pipe"]
|
|
16779
16948
|
});
|
|
16780
16949
|
} catch (error) {
|
|
16781
16950
|
if (error instanceof Error && error.message.includes("no pull requests")) {
|
|
16782
16951
|
console.error(
|
|
16783
|
-
`Error: No open pull request found for branch \`${
|
|
16952
|
+
`Error: No open pull request found for branch \`${branch2}\`. Open a PR for this branch before running \`assist review\`.`
|
|
16784
16953
|
);
|
|
16785
16954
|
process.exit(1);
|
|
16786
16955
|
}
|
|
@@ -16797,7 +16966,7 @@ function fetchPrDiffInfo() {
|
|
|
16797
16966
|
}
|
|
16798
16967
|
function fetchPrChangedFiles(prNumber) {
|
|
16799
16968
|
const { org, repo } = getRepoInfo();
|
|
16800
|
-
const out =
|
|
16969
|
+
const out = execSync48(
|
|
16801
16970
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
|
|
16802
16971
|
{
|
|
16803
16972
|
encoding: "utf8",
|
|
@@ -16809,18 +16978,18 @@ function fetchPrChangedFiles(prNumber) {
|
|
|
16809
16978
|
|
|
16810
16979
|
// src/commands/review/gatherContext.ts
|
|
16811
16980
|
function gatherContext() {
|
|
16812
|
-
const
|
|
16981
|
+
const branch2 = execSync49("git rev-parse --abbrev-ref HEAD", {
|
|
16813
16982
|
encoding: "utf8"
|
|
16814
16983
|
}).trim();
|
|
16815
|
-
const sha =
|
|
16816
|
-
const shortSha =
|
|
16984
|
+
const sha = execSync49("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
16985
|
+
const shortSha = execSync49("git rev-parse --short=7 HEAD", {
|
|
16817
16986
|
encoding: "utf8"
|
|
16818
16987
|
}).trim();
|
|
16819
16988
|
const prInfo = fetchPrDiffInfo();
|
|
16820
16989
|
const changedFiles = fetchPrChangedFiles(prInfo.prNumber);
|
|
16821
16990
|
const diff2 = fetchPrDiff(prInfo.prNumber, prInfo.baseSha, prInfo.headSha);
|
|
16822
16991
|
return {
|
|
16823
|
-
branch,
|
|
16992
|
+
branch: branch2,
|
|
16824
16993
|
sha,
|
|
16825
16994
|
shortSha,
|
|
16826
16995
|
prNumber: prInfo.prNumber,
|
|
@@ -16834,7 +17003,7 @@ function gatherContext() {
|
|
|
16834
17003
|
}
|
|
16835
17004
|
|
|
16836
17005
|
// src/commands/review/postReviewToPr.ts
|
|
16837
|
-
import { readFileSync as
|
|
17006
|
+
import { readFileSync as readFileSync36 } from "fs";
|
|
16838
17007
|
|
|
16839
17008
|
// src/commands/review/parseFindings.ts
|
|
16840
17009
|
var SEVERITIES = ["blocker", "major", "minor", "nit"];
|
|
@@ -17149,7 +17318,7 @@ async function confirmPost(prNumber, count7, options2) {
|
|
|
17149
17318
|
async function postReviewToPr(synthesisPath, options2) {
|
|
17150
17319
|
const prInfo = fetchPrDiffInfo();
|
|
17151
17320
|
const prNumber = prInfo.prNumber;
|
|
17152
|
-
const markdown =
|
|
17321
|
+
const markdown = readFileSync36(synthesisPath, "utf8");
|
|
17153
17322
|
const findings = parseFindings(markdown);
|
|
17154
17323
|
if (findings.length === 0) {
|
|
17155
17324
|
console.log("Synthesis contains no findings; nothing to post.");
|
|
@@ -17231,10 +17400,10 @@ async function handlePostSynthesis(synthesisPath, options2) {
|
|
|
17231
17400
|
}
|
|
17232
17401
|
|
|
17233
17402
|
// src/commands/review/prepareReviewDir.ts
|
|
17234
|
-
import { existsSync as
|
|
17403
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync16, unlinkSync as unlinkSync14, writeFileSync as writeFileSync33 } from "fs";
|
|
17235
17404
|
function clearReviewFiles(paths) {
|
|
17236
17405
|
for (const path57 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
17237
|
-
if (
|
|
17406
|
+
if (existsSync40(path57)) unlinkSync14(path57);
|
|
17238
17407
|
}
|
|
17239
17408
|
}
|
|
17240
17409
|
function prepareReviewDir(paths, requestBody, force) {
|
|
@@ -17519,7 +17688,7 @@ function printReviewerFailures(results) {
|
|
|
17519
17688
|
}
|
|
17520
17689
|
|
|
17521
17690
|
// src/commands/review/runAndSynthesise.ts
|
|
17522
|
-
import { existsSync as
|
|
17691
|
+
import { existsSync as existsSync42, unlinkSync as unlinkSync16 } from "fs";
|
|
17523
17692
|
|
|
17524
17693
|
// src/commands/review/buildReviewerStdin.ts
|
|
17525
17694
|
var REVIEW_PROMPT = `You are acting as a reviewer for a proposed code change made by another engineer. The full review request \u2014 branch, base, changed files, and unified diff \u2014 is in the request file whose absolute path is given below.
|
|
@@ -17939,7 +18108,7 @@ function resolveClaude(args) {
|
|
|
17939
18108
|
}
|
|
17940
18109
|
|
|
17941
18110
|
// src/commands/review/runCodexReviewer.ts
|
|
17942
|
-
import { existsSync as
|
|
18111
|
+
import { existsSync as existsSync41, unlinkSync as unlinkSync15 } from "fs";
|
|
17943
18112
|
|
|
17944
18113
|
// src/commands/review/parseCodexEvent.ts
|
|
17945
18114
|
function isItemStarted(value) {
|
|
@@ -17991,7 +18160,7 @@ async function runCodexReviewer(spec) {
|
|
|
17991
18160
|
reportReviewerToolUse(spec.name, event, spinner);
|
|
17992
18161
|
}
|
|
17993
18162
|
});
|
|
17994
|
-
if (result.exitCode !== 0 &&
|
|
18163
|
+
if (result.exitCode !== 0 && existsSync41(spec.outputPath)) {
|
|
17995
18164
|
unlinkSync15(spec.outputPath);
|
|
17996
18165
|
}
|
|
17997
18166
|
return finaliseReviewerRun({ ...spec, command }, spinner, result);
|
|
@@ -18033,7 +18202,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
|
|
|
18033
18202
|
}
|
|
18034
18203
|
|
|
18035
18204
|
// src/commands/review/synthesise.ts
|
|
18036
|
-
import { readFileSync as
|
|
18205
|
+
import { readFileSync as readFileSync37 } from "fs";
|
|
18037
18206
|
|
|
18038
18207
|
// src/commands/review/buildSynthesisStdin.ts
|
|
18039
18208
|
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.
|
|
@@ -18089,7 +18258,7 @@ Files:
|
|
|
18089
18258
|
|
|
18090
18259
|
// src/commands/review/synthesise.ts
|
|
18091
18260
|
function printSummary2(synthesisPath) {
|
|
18092
|
-
const markdown =
|
|
18261
|
+
const markdown = readFileSync37(synthesisPath, "utf8");
|
|
18093
18262
|
console.log("");
|
|
18094
18263
|
console.log(buildReviewSummary(markdown));
|
|
18095
18264
|
console.log("");
|
|
@@ -18137,7 +18306,7 @@ async function runAndSynthesise(args) {
|
|
|
18137
18306
|
console.error("Both reviewers failed; skipping synthesis.");
|
|
18138
18307
|
return { ok: false, failures };
|
|
18139
18308
|
}
|
|
18140
|
-
if (anyFresh &&
|
|
18309
|
+
if (anyFresh && existsSync42(paths.synthesisPath)) {
|
|
18141
18310
|
unlinkSync16(paths.synthesisPath);
|
|
18142
18311
|
}
|
|
18143
18312
|
const synthesisResult = await synthesise(paths, { multi });
|
|
@@ -18987,11 +19156,11 @@ async function configure() {
|
|
|
18987
19156
|
}
|
|
18988
19157
|
|
|
18989
19158
|
// src/commands/transcript/list.ts
|
|
18990
|
-
import { existsSync as
|
|
19159
|
+
import { existsSync as existsSync43, readdirSync as readdirSync9, statSync as statSync7 } from "fs";
|
|
18991
19160
|
import { join as join50 } from "path";
|
|
18992
19161
|
function list4() {
|
|
18993
19162
|
const { vttDir } = getTranscriptConfig();
|
|
18994
|
-
if (!
|
|
19163
|
+
if (!existsSync43(vttDir)) return;
|
|
18995
19164
|
for (const entry of readdirSync9(vttDir)) {
|
|
18996
19165
|
if (!entry.endsWith(".vtt")) continue;
|
|
18997
19166
|
if (statSync7(join50(vttDir, entry)).isDirectory()) continue;
|
|
@@ -19001,9 +19170,9 @@ function list4() {
|
|
|
19001
19170
|
|
|
19002
19171
|
// src/commands/transcript/move.ts
|
|
19003
19172
|
import {
|
|
19004
|
-
existsSync as
|
|
19173
|
+
existsSync as existsSync44,
|
|
19005
19174
|
mkdirSync as mkdirSync17,
|
|
19006
|
-
readFileSync as
|
|
19175
|
+
readFileSync as readFileSync38,
|
|
19007
19176
|
renameSync as renameSync2,
|
|
19008
19177
|
writeFileSync as writeFileSync35
|
|
19009
19178
|
} from "fs";
|
|
@@ -19215,7 +19384,7 @@ function formatChatLog(messages) {
|
|
|
19215
19384
|
// src/commands/transcript/move.ts
|
|
19216
19385
|
var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
19217
19386
|
function convertVttToMarkdown(inputPath) {
|
|
19218
|
-
const cues = parseVtt(
|
|
19387
|
+
const cues = parseVtt(readFileSync38(inputPath, "utf8"));
|
|
19219
19388
|
const messages = cuesToChatMessages(deduplicateCues(cues));
|
|
19220
19389
|
return formatChatLog(messages);
|
|
19221
19390
|
}
|
|
@@ -19233,7 +19402,7 @@ function move(file, options2) {
|
|
|
19233
19402
|
const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
19234
19403
|
const filename = basename10(file);
|
|
19235
19404
|
const sourcePath = join51(vttDir, filename);
|
|
19236
|
-
if (!
|
|
19405
|
+
if (!existsSync44(sourcePath)) {
|
|
19237
19406
|
console.error(`Error: VTT file not found: ${sourcePath}`);
|
|
19238
19407
|
process.exit(1);
|
|
19239
19408
|
}
|
|
@@ -19328,14 +19497,14 @@ function devices() {
|
|
|
19328
19497
|
}
|
|
19329
19498
|
|
|
19330
19499
|
// src/commands/voice/logs.ts
|
|
19331
|
-
import { existsSync as
|
|
19500
|
+
import { existsSync as existsSync45, readFileSync as readFileSync39 } from "fs";
|
|
19332
19501
|
function logs(options2) {
|
|
19333
|
-
if (!
|
|
19502
|
+
if (!existsSync45(voicePaths.log)) {
|
|
19334
19503
|
console.log("No voice log file found");
|
|
19335
19504
|
return;
|
|
19336
19505
|
}
|
|
19337
19506
|
const count7 = Number.parseInt(options2.lines ?? "150", 10);
|
|
19338
|
-
const content =
|
|
19507
|
+
const content = readFileSync39(voicePaths.log, "utf8").trim();
|
|
19339
19508
|
if (!content) {
|
|
19340
19509
|
console.log("Voice log is empty");
|
|
19341
19510
|
return;
|
|
@@ -19361,8 +19530,8 @@ import { mkdirSync as mkdirSync19 } from "fs";
|
|
|
19361
19530
|
import { join as join55 } from "path";
|
|
19362
19531
|
|
|
19363
19532
|
// src/commands/voice/checkLockFile.ts
|
|
19364
|
-
import { execSync as
|
|
19365
|
-
import { existsSync as
|
|
19533
|
+
import { execSync as execSync50 } from "child_process";
|
|
19534
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync18, readFileSync as readFileSync40, writeFileSync as writeFileSync36 } from "fs";
|
|
19366
19535
|
import { join as join54 } from "path";
|
|
19367
19536
|
function isProcessAlive2(pid) {
|
|
19368
19537
|
try {
|
|
@@ -19374,9 +19543,9 @@ function isProcessAlive2(pid) {
|
|
|
19374
19543
|
}
|
|
19375
19544
|
function checkLockFile() {
|
|
19376
19545
|
const lockFile = getLockFile();
|
|
19377
|
-
if (!
|
|
19546
|
+
if (!existsSync46(lockFile)) return;
|
|
19378
19547
|
try {
|
|
19379
|
-
const lock2 = JSON.parse(
|
|
19548
|
+
const lock2 = JSON.parse(readFileSync40(lockFile, "utf8"));
|
|
19380
19549
|
if (lock2.pid && isProcessAlive2(lock2.pid)) {
|
|
19381
19550
|
console.error(
|
|
19382
19551
|
`Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
|
|
@@ -19387,10 +19556,10 @@ function checkLockFile() {
|
|
|
19387
19556
|
}
|
|
19388
19557
|
}
|
|
19389
19558
|
function bootstrapVenv() {
|
|
19390
|
-
if (
|
|
19559
|
+
if (existsSync46(getVenvPython())) return;
|
|
19391
19560
|
console.log("Setting up Python environment...");
|
|
19392
19561
|
const pythonDir = getPythonDir();
|
|
19393
|
-
|
|
19562
|
+
execSync50(
|
|
19394
19563
|
`uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
|
|
19395
19564
|
{
|
|
19396
19565
|
stdio: "inherit",
|
|
@@ -19478,7 +19647,7 @@ function start2(options2) {
|
|
|
19478
19647
|
}
|
|
19479
19648
|
|
|
19480
19649
|
// src/commands/voice/status.ts
|
|
19481
|
-
import { existsSync as
|
|
19650
|
+
import { existsSync as existsSync47, readFileSync as readFileSync41 } from "fs";
|
|
19482
19651
|
function isProcessAlive3(pid) {
|
|
19483
19652
|
try {
|
|
19484
19653
|
process.kill(pid, 0);
|
|
@@ -19488,16 +19657,16 @@ function isProcessAlive3(pid) {
|
|
|
19488
19657
|
}
|
|
19489
19658
|
}
|
|
19490
19659
|
function readRecentLogs(count7) {
|
|
19491
|
-
if (!
|
|
19492
|
-
const lines =
|
|
19660
|
+
if (!existsSync47(voicePaths.log)) return [];
|
|
19661
|
+
const lines = readFileSync41(voicePaths.log, "utf8").trim().split("\n");
|
|
19493
19662
|
return lines.slice(-count7);
|
|
19494
19663
|
}
|
|
19495
19664
|
function status() {
|
|
19496
|
-
if (!
|
|
19665
|
+
if (!existsSync47(voicePaths.pid)) {
|
|
19497
19666
|
console.log("Voice daemon: not running (no PID file)");
|
|
19498
19667
|
return;
|
|
19499
19668
|
}
|
|
19500
|
-
const pid = Number.parseInt(
|
|
19669
|
+
const pid = Number.parseInt(readFileSync41(voicePaths.pid, "utf8").trim(), 10);
|
|
19501
19670
|
const alive = isProcessAlive3(pid);
|
|
19502
19671
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
19503
19672
|
const recent = readRecentLogs(5);
|
|
@@ -19516,13 +19685,13 @@ function status() {
|
|
|
19516
19685
|
}
|
|
19517
19686
|
|
|
19518
19687
|
// src/commands/voice/stop.ts
|
|
19519
|
-
import { existsSync as
|
|
19688
|
+
import { existsSync as existsSync48, readFileSync as readFileSync42, unlinkSync as unlinkSync17 } from "fs";
|
|
19520
19689
|
function stop2() {
|
|
19521
|
-
if (!
|
|
19690
|
+
if (!existsSync48(voicePaths.pid)) {
|
|
19522
19691
|
console.log("Voice daemon is not running (no PID file)");
|
|
19523
19692
|
return;
|
|
19524
19693
|
}
|
|
19525
|
-
const pid = Number.parseInt(
|
|
19694
|
+
const pid = Number.parseInt(readFileSync42(voicePaths.pid, "utf8").trim(), 10);
|
|
19526
19695
|
try {
|
|
19527
19696
|
process.kill(pid, "SIGTERM");
|
|
19528
19697
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -19535,7 +19704,7 @@ function stop2() {
|
|
|
19535
19704
|
}
|
|
19536
19705
|
try {
|
|
19537
19706
|
const lockFile = getLockFile();
|
|
19538
|
-
if (
|
|
19707
|
+
if (existsSync48(lockFile)) unlinkSync17(lockFile);
|
|
19539
19708
|
} catch {
|
|
19540
19709
|
}
|
|
19541
19710
|
console.log("Voice daemon stopped");
|
|
@@ -19713,7 +19882,7 @@ async function auth() {
|
|
|
19713
19882
|
|
|
19714
19883
|
// src/commands/roam/postRoamActivity.ts
|
|
19715
19884
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
19716
|
-
import { readdirSync as readdirSync10, readFileSync as
|
|
19885
|
+
import { readdirSync as readdirSync10, readFileSync as readFileSync43, statSync as statSync8 } from "fs";
|
|
19717
19886
|
import { join as join57 } from "path";
|
|
19718
19887
|
function findPortFile(roamDir) {
|
|
19719
19888
|
let entries;
|
|
@@ -19739,7 +19908,7 @@ function postRoamActivity(app, event) {
|
|
|
19739
19908
|
if (!portFile) return;
|
|
19740
19909
|
let port;
|
|
19741
19910
|
try {
|
|
19742
|
-
port =
|
|
19911
|
+
port = readFileSync43(portFile, "utf8").trim();
|
|
19743
19912
|
} catch {
|
|
19744
19913
|
return;
|
|
19745
19914
|
}
|
|
@@ -19867,11 +20036,11 @@ function resolveParams(params, cliArgs) {
|
|
|
19867
20036
|
}
|
|
19868
20037
|
|
|
19869
20038
|
// src/commands/run/runPreCommands.ts
|
|
19870
|
-
import { execSync as
|
|
20039
|
+
import { execSync as execSync51 } from "child_process";
|
|
19871
20040
|
function runPreCommands(pre, cwd) {
|
|
19872
20041
|
for (const cmd of pre) {
|
|
19873
20042
|
try {
|
|
19874
|
-
|
|
20043
|
+
execSync51(cmd, { stdio: "inherit", cwd });
|
|
19875
20044
|
} catch (error) {
|
|
19876
20045
|
const code = error && typeof error === "object" && "status" in error ? error.status : 1;
|
|
19877
20046
|
process.exit(code);
|
|
@@ -19881,7 +20050,7 @@ function runPreCommands(pre, cwd) {
|
|
|
19881
20050
|
|
|
19882
20051
|
// src/commands/run/spawnRunCommand.ts
|
|
19883
20052
|
import { execFileSync as execFileSync8, spawn as spawn8 } from "child_process";
|
|
19884
|
-
import { existsSync as
|
|
20053
|
+
import { existsSync as existsSync49 } from "fs";
|
|
19885
20054
|
import { dirname as dirname25, join as join58, resolve as resolve13 } from "path";
|
|
19886
20055
|
function resolveCommand2(command) {
|
|
19887
20056
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
@@ -19889,7 +20058,7 @@ function resolveCommand2(command) {
|
|
|
19889
20058
|
const gitPath = execFileSync8("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
19890
20059
|
const gitRoot = resolve13(dirname25(gitPath), "..");
|
|
19891
20060
|
const gitBash = join58(gitRoot, "bin", "bash.exe");
|
|
19892
|
-
if (
|
|
20061
|
+
if (existsSync49(gitBash)) return gitBash;
|
|
19893
20062
|
} catch {
|
|
19894
20063
|
}
|
|
19895
20064
|
return command;
|
|
@@ -20100,7 +20269,7 @@ function link2() {
|
|
|
20100
20269
|
}
|
|
20101
20270
|
|
|
20102
20271
|
// src/commands/run/remove.ts
|
|
20103
|
-
import { existsSync as
|
|
20272
|
+
import { existsSync as existsSync50, unlinkSync as unlinkSync18 } from "fs";
|
|
20104
20273
|
import { join as join60 } from "path";
|
|
20105
20274
|
function findRemoveIndex() {
|
|
20106
20275
|
const idx = process.argv.indexOf("remove");
|
|
@@ -20117,7 +20286,7 @@ function parseRemoveName() {
|
|
|
20117
20286
|
}
|
|
20118
20287
|
function deleteCommandFile(name) {
|
|
20119
20288
|
const filePath = join60(".claude", "commands", `${name}.md`);
|
|
20120
|
-
if (
|
|
20289
|
+
if (existsSync50(filePath)) {
|
|
20121
20290
|
unlinkSync18(filePath);
|
|
20122
20291
|
console.log(`Deleted command file: ${filePath}`);
|
|
20123
20292
|
}
|
|
@@ -20155,8 +20324,8 @@ function registerRun(program2) {
|
|
|
20155
20324
|
}
|
|
20156
20325
|
|
|
20157
20326
|
// src/commands/screenshot/index.ts
|
|
20158
|
-
import { execSync as
|
|
20159
|
-
import { existsSync as
|
|
20327
|
+
import { execSync as execSync52 } from "child_process";
|
|
20328
|
+
import { existsSync as existsSync51, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
|
|
20160
20329
|
import { tmpdir as tmpdir7 } from "os";
|
|
20161
20330
|
import { join as join61, resolve as resolve15 } from "path";
|
|
20162
20331
|
import chalk180 from "chalk";
|
|
@@ -20288,7 +20457,7 @@ Write-Output $OutputPath
|
|
|
20288
20457
|
|
|
20289
20458
|
// src/commands/screenshot/index.ts
|
|
20290
20459
|
function buildOutputPath(outputDir, processName) {
|
|
20291
|
-
if (!
|
|
20460
|
+
if (!existsSync51(outputDir)) {
|
|
20292
20461
|
mkdirSync22(outputDir, { recursive: true });
|
|
20293
20462
|
}
|
|
20294
20463
|
const timestamp4 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -20298,7 +20467,7 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
20298
20467
|
const scriptPath = join61(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
20299
20468
|
writeFileSync39(scriptPath, captureWindowPs1, "utf8");
|
|
20300
20469
|
try {
|
|
20301
|
-
|
|
20470
|
+
execSync52(
|
|
20302
20471
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
20303
20472
|
{ stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" }
|
|
20304
20473
|
);
|
|
@@ -20372,7 +20541,7 @@ function applyLine(result, pending, line) {
|
|
|
20372
20541
|
}
|
|
20373
20542
|
|
|
20374
20543
|
// src/commands/sessions/daemon/reportStolenSocket.ts
|
|
20375
|
-
import { readFileSync as
|
|
20544
|
+
import { readFileSync as readFileSync44 } from "fs";
|
|
20376
20545
|
function reportStolenSocket(socketPid) {
|
|
20377
20546
|
if (!socketPid) return;
|
|
20378
20547
|
const filePid = readPidFile();
|
|
@@ -20384,7 +20553,7 @@ function reportStolenSocket(socketPid) {
|
|
|
20384
20553
|
function readPidFile() {
|
|
20385
20554
|
try {
|
|
20386
20555
|
const pid = Number.parseInt(
|
|
20387
|
-
|
|
20556
|
+
readFileSync44(daemonPaths.pid, "utf8").trim(),
|
|
20388
20557
|
10
|
|
20389
20558
|
);
|
|
20390
20559
|
return Number.isInteger(pid) ? pid : void 0;
|
|
@@ -20738,7 +20907,7 @@ var ClientHub = class extends Set {
|
|
|
20738
20907
|
import * as pty from "node-pty";
|
|
20739
20908
|
|
|
20740
20909
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
20741
|
-
import { chmodSync, existsSync as
|
|
20910
|
+
import { chmodSync, existsSync as existsSync52, statSync as statSync9 } from "fs";
|
|
20742
20911
|
import { createRequire as createRequire3 } from "module";
|
|
20743
20912
|
import path49 from "path";
|
|
20744
20913
|
var require4 = createRequire3(import.meta.url);
|
|
@@ -20753,7 +20922,7 @@ function ensureSpawnHelperExecutable() {
|
|
|
20753
20922
|
`${process.platform}-${process.arch}`,
|
|
20754
20923
|
"spawn-helper"
|
|
20755
20924
|
);
|
|
20756
|
-
if (!
|
|
20925
|
+
if (!existsSync52(helper)) return;
|
|
20757
20926
|
const mode = statSync9(helper).mode;
|
|
20758
20927
|
if ((mode & 73) === 0) chmodSync(helper, mode | 493);
|
|
20759
20928
|
}
|
|
@@ -21288,7 +21457,7 @@ function resumeSession(id2, sessionId, cwd, name) {
|
|
|
21288
21457
|
}
|
|
21289
21458
|
|
|
21290
21459
|
// src/commands/sessions/daemon/watchActivity.ts
|
|
21291
|
-
import { existsSync as
|
|
21460
|
+
import { existsSync as existsSync53, mkdirSync as mkdirSync23, watch } from "fs";
|
|
21292
21461
|
import { dirname as dirname26 } from "path";
|
|
21293
21462
|
|
|
21294
21463
|
// src/commands/sessions/daemon/applyReviewPause.ts
|
|
@@ -21367,7 +21536,7 @@ function watchActivity(session, notify2) {
|
|
|
21367
21536
|
if (timer) clearTimeout(timer);
|
|
21368
21537
|
timer = setTimeout(read, DEBOUNCE_MS);
|
|
21369
21538
|
});
|
|
21370
|
-
if (
|
|
21539
|
+
if (existsSync53(path57)) read();
|
|
21371
21540
|
}
|
|
21372
21541
|
function refreshActivity(session) {
|
|
21373
21542
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -22246,12 +22415,12 @@ import * as net3 from "net";
|
|
|
22246
22415
|
import { createInterface as createInterface9 } from "readline";
|
|
22247
22416
|
|
|
22248
22417
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
22249
|
-
import * as
|
|
22418
|
+
import * as fs32 from "fs";
|
|
22250
22419
|
import * as os from "os";
|
|
22251
22420
|
import * as path51 from "path";
|
|
22252
22421
|
|
|
22253
22422
|
// src/commands/sessions/shared/parseSessionFile.ts
|
|
22254
|
-
import * as
|
|
22423
|
+
import * as fs31 from "fs";
|
|
22255
22424
|
import * as path50 from "path";
|
|
22256
22425
|
|
|
22257
22426
|
// src/commands/sessions/shared/deriveHistoryFields.ts
|
|
@@ -22349,10 +22518,10 @@ function matchMarker(text7, tag) {
|
|
|
22349
22518
|
async function parseSessionFile(filePath, origin = "wsl") {
|
|
22350
22519
|
let handle;
|
|
22351
22520
|
try {
|
|
22352
|
-
handle = await
|
|
22521
|
+
handle = await fs31.promises.open(filePath, "r");
|
|
22353
22522
|
const meta = extractSessionMeta(await readHeadLines(handle));
|
|
22354
22523
|
if (!meta.sessionId) return null;
|
|
22355
|
-
const timestamp4 = meta.timestamp || (await
|
|
22524
|
+
const timestamp4 = meta.timestamp || (await fs31.promises.stat(filePath)).mtime.toISOString();
|
|
22356
22525
|
return {
|
|
22357
22526
|
sessionId: meta.sessionId,
|
|
22358
22527
|
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
@@ -22398,7 +22567,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
22398
22567
|
sessionRoots().map(async ({ dir, origin }) => {
|
|
22399
22568
|
let projectDirs;
|
|
22400
22569
|
try {
|
|
22401
|
-
projectDirs = await
|
|
22570
|
+
projectDirs = await fs32.promises.readdir(dir);
|
|
22402
22571
|
} catch {
|
|
22403
22572
|
return;
|
|
22404
22573
|
}
|
|
@@ -22407,7 +22576,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
22407
22576
|
const dirPath = path51.join(dir, dirName);
|
|
22408
22577
|
let entries;
|
|
22409
22578
|
try {
|
|
22410
|
-
entries = await
|
|
22579
|
+
entries = await fs32.promises.readdir(dirPath);
|
|
22411
22580
|
} catch {
|
|
22412
22581
|
return;
|
|
22413
22582
|
}
|
|
@@ -22440,7 +22609,7 @@ async function discoverSessions() {
|
|
|
22440
22609
|
}
|
|
22441
22610
|
|
|
22442
22611
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
22443
|
-
import * as
|
|
22612
|
+
import * as fs33 from "fs";
|
|
22444
22613
|
|
|
22445
22614
|
// src/commands/sessions/shared/toolTarget.ts
|
|
22446
22615
|
function toolTarget(input) {
|
|
@@ -22507,7 +22676,7 @@ async function parseTranscript(sessionId) {
|
|
|
22507
22676
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
22508
22677
|
if (!filePath) return [];
|
|
22509
22678
|
try {
|
|
22510
|
-
const raw = await
|
|
22679
|
+
const raw = await fs33.promises.readFile(filePath, "utf8");
|
|
22511
22680
|
return parseTranscriptLines(raw.split("\n"));
|
|
22512
22681
|
} catch {
|
|
22513
22682
|
return [];
|
|
@@ -22674,7 +22843,7 @@ function handleConnection(socket, manager) {
|
|
|
22674
22843
|
import { unlinkSync as unlinkSync20, writeFileSync as writeFileSync40 } from "fs";
|
|
22675
22844
|
|
|
22676
22845
|
// src/commands/sessions/daemon/startPidFileWatchdog.ts
|
|
22677
|
-
import { readFileSync as
|
|
22846
|
+
import { readFileSync as readFileSync45 } from "fs";
|
|
22678
22847
|
var WATCHDOG_INTERVAL_MS = 5e3;
|
|
22679
22848
|
function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
22680
22849
|
const timer = setInterval(() => {
|
|
@@ -22685,7 +22854,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
|
22685
22854
|
}
|
|
22686
22855
|
function ownsPidFile() {
|
|
22687
22856
|
try {
|
|
22688
|
-
return
|
|
22857
|
+
return readFileSync45(daemonPaths.pid, "utf8").trim() === String(process.pid);
|
|
22689
22858
|
} catch {
|
|
22690
22859
|
return false;
|
|
22691
22860
|
}
|
|
@@ -22812,17 +22981,17 @@ function registerDaemon(program2) {
|
|
|
22812
22981
|
}
|
|
22813
22982
|
|
|
22814
22983
|
// src/commands/sessions/summarise/index.ts
|
|
22815
|
-
import * as
|
|
22984
|
+
import * as fs36 from "fs";
|
|
22816
22985
|
import chalk181 from "chalk";
|
|
22817
22986
|
|
|
22818
22987
|
// src/commands/sessions/summarise/shared.ts
|
|
22819
|
-
import * as
|
|
22988
|
+
import * as fs34 from "fs";
|
|
22820
22989
|
function writeSummary(jsonlPath2, summary) {
|
|
22821
|
-
|
|
22990
|
+
fs34.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
22822
22991
|
`, "utf8");
|
|
22823
22992
|
}
|
|
22824
22993
|
function hasSummary(jsonlPath2) {
|
|
22825
|
-
return
|
|
22994
|
+
return fs34.existsSync(summaryPathFor(jsonlPath2));
|
|
22826
22995
|
}
|
|
22827
22996
|
function summaryPathFor(jsonlPath2) {
|
|
22828
22997
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -22832,7 +23001,7 @@ function summaryPathFor(jsonlPath2) {
|
|
|
22832
23001
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
22833
23002
|
|
|
22834
23003
|
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
22835
|
-
import * as
|
|
23004
|
+
import * as fs35 from "fs";
|
|
22836
23005
|
|
|
22837
23006
|
// src/commands/sessions/summarise/parseUserLine.ts
|
|
22838
23007
|
function parseUserLine(line) {
|
|
@@ -22863,13 +23032,13 @@ function parseUserLine(line) {
|
|
|
22863
23032
|
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
22864
23033
|
let content;
|
|
22865
23034
|
try {
|
|
22866
|
-
const fd =
|
|
23035
|
+
const fd = fs35.openSync(filePath, "r");
|
|
22867
23036
|
try {
|
|
22868
23037
|
const buf = Buffer.alloc(maxBytes);
|
|
22869
|
-
const bytesRead =
|
|
23038
|
+
const bytesRead = fs35.readSync(fd, buf, 0, buf.length, 0);
|
|
22870
23039
|
content = buf.toString("utf8", 0, bytesRead);
|
|
22871
23040
|
} finally {
|
|
22872
|
-
|
|
23041
|
+
fs35.closeSync(fd);
|
|
22873
23042
|
}
|
|
22874
23043
|
} catch {
|
|
22875
23044
|
return;
|
|
@@ -22989,7 +23158,7 @@ function selectCandidates(files, options2) {
|
|
|
22989
23158
|
const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
|
|
22990
23159
|
candidates.sort((a, b) => {
|
|
22991
23160
|
try {
|
|
22992
|
-
return
|
|
23161
|
+
return fs36.statSync(b).mtimeMs - fs36.statSync(a).mtimeMs;
|
|
22993
23162
|
} catch {
|
|
22994
23163
|
return 0;
|
|
22995
23164
|
}
|
|
@@ -23138,21 +23307,21 @@ async function statusLine() {
|
|
|
23138
23307
|
}
|
|
23139
23308
|
|
|
23140
23309
|
// src/commands/sync.ts
|
|
23141
|
-
import * as
|
|
23310
|
+
import * as fs39 from "fs";
|
|
23142
23311
|
import * as os2 from "os";
|
|
23143
23312
|
import * as path55 from "path";
|
|
23144
23313
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
23145
23314
|
|
|
23146
23315
|
// src/commands/sync/syncClaudeMd.ts
|
|
23147
|
-
import * as
|
|
23316
|
+
import * as fs37 from "fs";
|
|
23148
23317
|
import * as path53 from "path";
|
|
23149
23318
|
import chalk184 from "chalk";
|
|
23150
23319
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
23151
23320
|
const source = path53.join(claudeDir, "CLAUDE.md");
|
|
23152
23321
|
const target = path53.join(targetBase, "CLAUDE.md");
|
|
23153
|
-
const sourceContent =
|
|
23154
|
-
if (
|
|
23155
|
-
const targetContent =
|
|
23322
|
+
const sourceContent = fs37.readFileSync(source, "utf8");
|
|
23323
|
+
if (fs37.existsSync(target)) {
|
|
23324
|
+
const targetContent = fs37.readFileSync(target, "utf8");
|
|
23156
23325
|
if (sourceContent !== targetContent) {
|
|
23157
23326
|
console.log(
|
|
23158
23327
|
chalk184.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
@@ -23169,21 +23338,21 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
23169
23338
|
}
|
|
23170
23339
|
}
|
|
23171
23340
|
}
|
|
23172
|
-
|
|
23341
|
+
fs37.copyFileSync(source, target);
|
|
23173
23342
|
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
23174
23343
|
}
|
|
23175
23344
|
|
|
23176
23345
|
// src/commands/sync/syncSettings.ts
|
|
23177
|
-
import * as
|
|
23346
|
+
import * as fs38 from "fs";
|
|
23178
23347
|
import * as path54 from "path";
|
|
23179
23348
|
import chalk185 from "chalk";
|
|
23180
23349
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
23181
23350
|
const source = path54.join(claudeDir, "settings.json");
|
|
23182
23351
|
const target = path54.join(targetBase, "settings.json");
|
|
23183
|
-
const sourceContent =
|
|
23352
|
+
const sourceContent = fs38.readFileSync(source, "utf8");
|
|
23184
23353
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
23185
|
-
if (
|
|
23186
|
-
const targetContent =
|
|
23354
|
+
if (fs38.existsSync(target)) {
|
|
23355
|
+
const targetContent = fs38.readFileSync(target, "utf8");
|
|
23187
23356
|
const normalizedTarget = JSON.stringify(
|
|
23188
23357
|
JSON.parse(targetContent),
|
|
23189
23358
|
null,
|
|
@@ -23209,7 +23378,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
23209
23378
|
}
|
|
23210
23379
|
}
|
|
23211
23380
|
}
|
|
23212
|
-
|
|
23381
|
+
fs38.writeFileSync(target, mergedContent);
|
|
23213
23382
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
23214
23383
|
}
|
|
23215
23384
|
|
|
@@ -23228,17 +23397,17 @@ async function sync(options2) {
|
|
|
23228
23397
|
function syncCommands(claudeDir, targetBase) {
|
|
23229
23398
|
const sourceDir = path55.join(claudeDir, "commands");
|
|
23230
23399
|
const targetDir = path55.join(targetBase, "commands");
|
|
23231
|
-
|
|
23232
|
-
const files =
|
|
23400
|
+
fs39.mkdirSync(targetDir, { recursive: true });
|
|
23401
|
+
const files = fs39.readdirSync(sourceDir);
|
|
23233
23402
|
for (const file of files) {
|
|
23234
|
-
|
|
23403
|
+
fs39.copyFileSync(path55.join(sourceDir, file), path55.join(targetDir, file));
|
|
23235
23404
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
23236
23405
|
}
|
|
23237
23406
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
23238
23407
|
}
|
|
23239
23408
|
|
|
23240
23409
|
// src/commands/update.ts
|
|
23241
|
-
import { execSync as
|
|
23410
|
+
import { execSync as execSync53 } from "child_process";
|
|
23242
23411
|
import * as path56 from "path";
|
|
23243
23412
|
|
|
23244
23413
|
// src/commands/restartDaemonAfterUpdate.ts
|
|
@@ -23262,7 +23431,7 @@ function isGlobalNpmInstall(dir) {
|
|
|
23262
23431
|
if (resolved.split(path56.sep).includes("node_modules")) {
|
|
23263
23432
|
return true;
|
|
23264
23433
|
}
|
|
23265
|
-
const globalPrefix =
|
|
23434
|
+
const globalPrefix = execSync53("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
23266
23435
|
return resolved.toLowerCase().startsWith(path56.resolve(globalPrefix).toLowerCase());
|
|
23267
23436
|
} catch {
|
|
23268
23437
|
return false;
|
|
@@ -23273,18 +23442,18 @@ async function update2() {
|
|
|
23273
23442
|
console.log(`Assist is installed at: ${installDir}`);
|
|
23274
23443
|
if (isGitRepo(installDir)) {
|
|
23275
23444
|
console.log("Detected git repo installation, pulling latest...");
|
|
23276
|
-
|
|
23445
|
+
execSync53("git pull", { cwd: installDir, stdio: "inherit" });
|
|
23277
23446
|
console.log("Installing dependencies...");
|
|
23278
|
-
|
|
23447
|
+
execSync53("npm i", { cwd: installDir, stdio: "inherit" });
|
|
23279
23448
|
console.log("Building...");
|
|
23280
|
-
|
|
23449
|
+
execSync53("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
23281
23450
|
console.log("Syncing commands...");
|
|
23282
|
-
|
|
23451
|
+
execSync53("assist sync", { stdio: "inherit" });
|
|
23283
23452
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
23284
23453
|
console.log("Detected global npm installation, updating...");
|
|
23285
|
-
|
|
23454
|
+
execSync53("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
23286
23455
|
console.log("Syncing commands...");
|
|
23287
|
-
|
|
23456
|
+
execSync53("assist sync", { stdio: "inherit" });
|
|
23288
23457
|
} else {
|
|
23289
23458
|
console.error(
|
|
23290
23459
|
"Could not determine installation method. Expected a git repo or global npm install."
|
|
@@ -23326,6 +23495,7 @@ registerMermaid(program);
|
|
|
23326
23495
|
registerPrs(program);
|
|
23327
23496
|
registerRoam(program);
|
|
23328
23497
|
registerBacklog(program);
|
|
23498
|
+
registerBranch(program);
|
|
23329
23499
|
registerList(program);
|
|
23330
23500
|
registerVerify(program);
|
|
23331
23501
|
registerRefactor(program);
|