@staff0rd/assist 0.402.0 → 0.403.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/sessions/web/bundle.js +1 -1
- package/dist/index.js +246 -212
- 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.403.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -1577,6 +1577,95 @@ function stageAndCommit(files, message) {
|
|
|
1577
1577
|
return commitStaged(message);
|
|
1578
1578
|
}
|
|
1579
1579
|
|
|
1580
|
+
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
1581
|
+
import * as fs from "fs";
|
|
1582
|
+
|
|
1583
|
+
// src/commands/sessions/summarise/parseUserLine.ts
|
|
1584
|
+
function parseUserLine(line) {
|
|
1585
|
+
let entry;
|
|
1586
|
+
try {
|
|
1587
|
+
entry = JSON.parse(line);
|
|
1588
|
+
} catch {
|
|
1589
|
+
return void 0;
|
|
1590
|
+
}
|
|
1591
|
+
if (entry.type !== "user") return void 0;
|
|
1592
|
+
const msg = entry.message;
|
|
1593
|
+
const c = msg?.content;
|
|
1594
|
+
let text17;
|
|
1595
|
+
if (typeof c === "string") {
|
|
1596
|
+
text17 = c;
|
|
1597
|
+
} else if (Array.isArray(c)) {
|
|
1598
|
+
const collected = c.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n");
|
|
1599
|
+
text17 = collected || void 0;
|
|
1600
|
+
}
|
|
1601
|
+
if (!text17) return void 0;
|
|
1602
|
+
return {
|
|
1603
|
+
text: text17,
|
|
1604
|
+
entrypoint: typeof entry.entrypoint === "string" ? entry.entrypoint : void 0
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
1609
|
+
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
1610
|
+
let content;
|
|
1611
|
+
try {
|
|
1612
|
+
const fd = fs.openSync(filePath, "r");
|
|
1613
|
+
try {
|
|
1614
|
+
const buf = Buffer.alloc(maxBytes);
|
|
1615
|
+
const bytesRead = fs.readSync(fd, buf, 0, buf.length, 0);
|
|
1616
|
+
content = buf.toString("utf8", 0, bytesRead);
|
|
1617
|
+
} finally {
|
|
1618
|
+
fs.closeSync(fd);
|
|
1619
|
+
}
|
|
1620
|
+
} catch {
|
|
1621
|
+
return;
|
|
1622
|
+
}
|
|
1623
|
+
for (const line of content.split("\n")) {
|
|
1624
|
+
if (!line) continue;
|
|
1625
|
+
const entry = parseUserLine(line);
|
|
1626
|
+
if (entry) yield entry.text;
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
// src/commands/sessions/summarise/scanSessionBacklogRefs.ts
|
|
1631
|
+
function scanSessionBacklogRefs(filePath) {
|
|
1632
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1633
|
+
for (const text17 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
|
|
1634
|
+
for (const id of extractBacklogIds(text17)) {
|
|
1635
|
+
ids.add(id);
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
return [...ids].sort((a, b) => a - b);
|
|
1639
|
+
}
|
|
1640
|
+
function extractBacklogIds(text17) {
|
|
1641
|
+
const ids = [];
|
|
1642
|
+
for (const m of text17.matchAll(/backlog\s+run\s+a(\d+)/gi)) {
|
|
1643
|
+
ids.push(Number.parseInt(m[1], 10));
|
|
1644
|
+
}
|
|
1645
|
+
for (const m of text17.matchAll(/backlog\s+(?:item\s+)?a(\d+)/gi)) {
|
|
1646
|
+
ids.push(Number.parseInt(m[1], 10));
|
|
1647
|
+
}
|
|
1648
|
+
for (const m of text17.matchAll(/backlog\s+phase-done\s+a(\d+)/gi)) {
|
|
1649
|
+
ids.push(Number.parseInt(m[1], 10));
|
|
1650
|
+
}
|
|
1651
|
+
for (const m of text17.matchAll(/backlog\s+comment\s+a(\d+)/gi)) {
|
|
1652
|
+
ids.push(Number.parseInt(m[1], 10));
|
|
1653
|
+
}
|
|
1654
|
+
for (const m of text17.matchAll(/(?:^|[\s(])a(\d{1,4})(?=[\s).,;:!?]|$)/gm)) {
|
|
1655
|
+
ids.push(Number.parseInt(m[1], 10));
|
|
1656
|
+
}
|
|
1657
|
+
return ids;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
// src/shared/findBacklogRefs.ts
|
|
1661
|
+
function findBacklogRefs(text17) {
|
|
1662
|
+
return [...new Set(extractBacklogIds(text17))];
|
|
1663
|
+
}
|
|
1664
|
+
function backlogRefError(subject, context, ids) {
|
|
1665
|
+
const refs = ids.map((id) => `a${id}`).join(", ");
|
|
1666
|
+
return `Error: ${subject} must not reference assist backlog items (found ${refs}). Do not include assist references or backlog numbers in ${context} \u2014 the backlog item links to your work, not the other way around.`;
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1580
1669
|
// src/commands/commit/validateMessage.ts
|
|
1581
1670
|
var MAX_MESSAGE_LENGTH = 50;
|
|
1582
1671
|
var CONVENTIONAL_COMMIT_REGEX = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(!)?(\(.+\))?!?: .+$/;
|
|
@@ -1585,6 +1674,13 @@ function validateMessage(message, config) {
|
|
|
1585
1674
|
console.error("Error: Commit message must not reference Claude");
|
|
1586
1675
|
process.exit(1);
|
|
1587
1676
|
}
|
|
1677
|
+
const backlogIds = findBacklogRefs(message);
|
|
1678
|
+
if (backlogIds.length > 0) {
|
|
1679
|
+
console.error(
|
|
1680
|
+
backlogRefError("Commit message", "commit messages", backlogIds)
|
|
1681
|
+
);
|
|
1682
|
+
process.exit(1);
|
|
1683
|
+
}
|
|
1588
1684
|
if (config.commit?.conventional && !CONVENTIONAL_COMMIT_REGEX.test(message)) {
|
|
1589
1685
|
console.error(
|
|
1590
1686
|
"Error: Commit message must follow conventional commit format (e.g., 'feat: add feature', 'fix(scope): fix bug')"
|
|
@@ -1700,18 +1796,18 @@ async function promptMultiselect(message, options2) {
|
|
|
1700
1796
|
}
|
|
1701
1797
|
|
|
1702
1798
|
// src/shared/readPackageJson.ts
|
|
1703
|
-
import * as
|
|
1799
|
+
import * as fs2 from "fs";
|
|
1704
1800
|
import * as path from "path";
|
|
1705
1801
|
import chalk5 from "chalk";
|
|
1706
1802
|
function findPackageJson() {
|
|
1707
1803
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1708
|
-
if (
|
|
1804
|
+
if (fs2.existsSync(packageJsonPath)) {
|
|
1709
1805
|
return packageJsonPath;
|
|
1710
1806
|
}
|
|
1711
1807
|
return null;
|
|
1712
1808
|
}
|
|
1713
1809
|
function readPackageJson(filePath) {
|
|
1714
|
-
return JSON.parse(
|
|
1810
|
+
return JSON.parse(fs2.readFileSync(filePath, "utf8"));
|
|
1715
1811
|
}
|
|
1716
1812
|
function requirePackageJson() {
|
|
1717
1813
|
const packageJsonPath = findPackageJson();
|
|
@@ -1726,8 +1822,8 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1726
1822
|
let currentDir = startDir;
|
|
1727
1823
|
while (true) {
|
|
1728
1824
|
const packageJsonPath = path.join(currentDir, "package.json");
|
|
1729
|
-
if (
|
|
1730
|
-
const packageJson = JSON.parse(
|
|
1825
|
+
if (fs2.existsSync(packageJsonPath)) {
|
|
1826
|
+
const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf8"));
|
|
1731
1827
|
const scripts = packageJson.scripts || {};
|
|
1732
1828
|
const verifyScripts = Object.keys(scripts).filter(
|
|
1733
1829
|
(name) => name.startsWith("verify:")
|
|
@@ -2389,28 +2485,28 @@ async function init3(options2 = {}) {
|
|
|
2389
2485
|
import chalk23 from "chalk";
|
|
2390
2486
|
|
|
2391
2487
|
// src/commands/vscode/init/createLaunchJson.ts
|
|
2392
|
-
import * as
|
|
2488
|
+
import * as fs3 from "fs";
|
|
2393
2489
|
import * as path8 from "path";
|
|
2394
2490
|
import chalk20 from "chalk";
|
|
2395
2491
|
function ensureVscodeFolder() {
|
|
2396
2492
|
const vscodeDir = path8.join(process.cwd(), ".vscode");
|
|
2397
|
-
if (!
|
|
2398
|
-
|
|
2493
|
+
if (!fs3.existsSync(vscodeDir)) {
|
|
2494
|
+
fs3.mkdirSync(vscodeDir);
|
|
2399
2495
|
console.log(chalk20.dim("Created .vscode folder"));
|
|
2400
2496
|
}
|
|
2401
2497
|
}
|
|
2402
2498
|
function removeVscodeFromGitignore() {
|
|
2403
2499
|
const gitignorePath = path8.join(process.cwd(), ".gitignore");
|
|
2404
|
-
if (!
|
|
2500
|
+
if (!fs3.existsSync(gitignorePath)) {
|
|
2405
2501
|
return;
|
|
2406
2502
|
}
|
|
2407
|
-
const content =
|
|
2503
|
+
const content = fs3.readFileSync(gitignorePath, "utf8");
|
|
2408
2504
|
const lines = content.split("\n");
|
|
2409
2505
|
const filteredLines = lines.filter(
|
|
2410
2506
|
(line) => !line.trim().toLowerCase().includes(".vscode")
|
|
2411
2507
|
);
|
|
2412
2508
|
if (filteredLines.length !== lines.length) {
|
|
2413
|
-
|
|
2509
|
+
fs3.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
2414
2510
|
console.log(chalk20.dim("Removed .vscode references from .gitignore"));
|
|
2415
2511
|
}
|
|
2416
2512
|
}
|
|
@@ -2428,20 +2524,20 @@ function createLaunchJson(type) {
|
|
|
2428
2524
|
]
|
|
2429
2525
|
};
|
|
2430
2526
|
const launchPath = path8.join(process.cwd(), ".vscode", "launch.json");
|
|
2431
|
-
|
|
2527
|
+
fs3.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
|
|
2432
2528
|
`);
|
|
2433
2529
|
console.log(chalk20.green("Created .vscode/launch.json"));
|
|
2434
2530
|
}
|
|
2435
2531
|
|
|
2436
2532
|
// src/commands/vscode/init/detectVscodeSetup.ts
|
|
2437
|
-
import * as
|
|
2533
|
+
import * as fs4 from "fs";
|
|
2438
2534
|
import * as path9 from "path";
|
|
2439
2535
|
function detectVscodeSetup(pkg) {
|
|
2440
2536
|
const vscodeDir = path9.join(process.cwd(), ".vscode");
|
|
2441
2537
|
return {
|
|
2442
|
-
hasVscodeFolder:
|
|
2443
|
-
hasLaunchJson:
|
|
2444
|
-
hasSettingsJson:
|
|
2538
|
+
hasVscodeFolder: fs4.existsSync(vscodeDir),
|
|
2539
|
+
hasLaunchJson: fs4.existsSync(path9.join(vscodeDir, "launch.json")),
|
|
2540
|
+
hasSettingsJson: fs4.existsSync(path9.join(vscodeDir, "settings.json")),
|
|
2445
2541
|
hasVite: !!pkg.devDependencies?.vite || !!pkg.dependencies?.vite,
|
|
2446
2542
|
hasTsup: !!pkg.devDependencies?.tsup || !!pkg.dependencies?.tsup
|
|
2447
2543
|
};
|
|
@@ -2473,16 +2569,16 @@ function getAvailableOptions2(setup2) {
|
|
|
2473
2569
|
}
|
|
2474
2570
|
|
|
2475
2571
|
// src/commands/vscode/init/createSettingsJson.ts
|
|
2476
|
-
import * as
|
|
2572
|
+
import * as fs6 from "fs";
|
|
2477
2573
|
import * as path10 from "path";
|
|
2478
2574
|
import chalk21 from "chalk";
|
|
2479
2575
|
|
|
2480
2576
|
// src/commands/vscode/init/readVscodeJson.ts
|
|
2481
|
-
import * as
|
|
2577
|
+
import * as fs5 from "fs";
|
|
2482
2578
|
function readVscodeJson(filePath) {
|
|
2483
|
-
if (!
|
|
2579
|
+
if (!fs5.existsSync(filePath)) return {};
|
|
2484
2580
|
try {
|
|
2485
|
-
return JSON.parse(
|
|
2581
|
+
return JSON.parse(fs5.readFileSync(filePath, "utf8"));
|
|
2486
2582
|
} catch {
|
|
2487
2583
|
return {};
|
|
2488
2584
|
}
|
|
@@ -2501,7 +2597,7 @@ function createSettingsJson() {
|
|
|
2501
2597
|
"source.fixAll.oxc": "explicit"
|
|
2502
2598
|
}
|
|
2503
2599
|
};
|
|
2504
|
-
|
|
2600
|
+
fs6.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
|
|
2505
2601
|
`);
|
|
2506
2602
|
console.log(chalk21.green("Created .vscode/settings.json"));
|
|
2507
2603
|
}
|
|
@@ -2512,7 +2608,7 @@ function existingCodeActions(actions) {
|
|
|
2512
2608
|
}
|
|
2513
2609
|
|
|
2514
2610
|
// src/commands/vscode/init/createExtensionsJson.ts
|
|
2515
|
-
import * as
|
|
2611
|
+
import * as fs7 from "fs";
|
|
2516
2612
|
import * as path11 from "path";
|
|
2517
2613
|
import chalk22 from "chalk";
|
|
2518
2614
|
function createExtensionsJson() {
|
|
@@ -2521,7 +2617,7 @@ function createExtensionsJson() {
|
|
|
2521
2617
|
const previous = Array.isArray(existing.recommendations) ? existing.recommendations : [];
|
|
2522
2618
|
const recommendations = previous.includes("oxc.oxc-vscode") ? previous : [...previous, "oxc.oxc-vscode"];
|
|
2523
2619
|
const extensions = { ...existing, recommendations };
|
|
2524
|
-
|
|
2620
|
+
fs7.writeFileSync(
|
|
2525
2621
|
extensionsPath,
|
|
2526
2622
|
`${JSON.stringify(extensions, null, " ")}
|
|
2527
2623
|
`
|
|
@@ -2578,20 +2674,20 @@ import path17 from "path";
|
|
|
2578
2674
|
import chalk25 from "chalk";
|
|
2579
2675
|
|
|
2580
2676
|
// src/commands/lint/lint/checkFileNames.ts
|
|
2581
|
-
import
|
|
2677
|
+
import fs9 from "fs";
|
|
2582
2678
|
import path13 from "path";
|
|
2583
2679
|
|
|
2584
2680
|
// src/shared/findSourceFiles.ts
|
|
2585
|
-
import
|
|
2681
|
+
import fs8 from "fs";
|
|
2586
2682
|
import path12 from "path";
|
|
2587
2683
|
var EXTENSIONS = [".ts", ".tsx"];
|
|
2588
2684
|
function findSourceFiles(dir, options2 = {}) {
|
|
2589
2685
|
const { includeTests = true } = options2;
|
|
2590
2686
|
const results = [];
|
|
2591
|
-
if (!
|
|
2687
|
+
if (!fs8.existsSync(dir)) {
|
|
2592
2688
|
return results;
|
|
2593
2689
|
}
|
|
2594
|
-
const entries =
|
|
2690
|
+
const entries = fs8.readdirSync(dir, { withFileTypes: true });
|
|
2595
2691
|
for (const entry of entries) {
|
|
2596
2692
|
const fullPath = path12.join(dir, entry.name);
|
|
2597
2693
|
if (entry.isDirectory() && entry.name !== "node_modules") {
|
|
@@ -2641,7 +2737,7 @@ function checkFileNames() {
|
|
|
2641
2737
|
const nameWithoutExt = fileName.replace(/\.(ts|tsx)$/, "");
|
|
2642
2738
|
if (/\.(stories|test)\.(ts|tsx)$/.test(fileName)) continue;
|
|
2643
2739
|
if (/^[A-Z]/.test(nameWithoutExt)) {
|
|
2644
|
-
const content =
|
|
2740
|
+
const content = fs9.readFileSync(filePath, "utf8");
|
|
2645
2741
|
if (!hasClassOrComponent(content) && !hasMatchingTypeExport(content, nameWithoutExt)) {
|
|
2646
2742
|
violations.push({
|
|
2647
2743
|
filePath,
|
|
@@ -2658,7 +2754,7 @@ function checkFileNames() {
|
|
|
2658
2754
|
import chalk24 from "chalk";
|
|
2659
2755
|
|
|
2660
2756
|
// src/commands/lint/lint/applyMoves.ts
|
|
2661
|
-
import
|
|
2757
|
+
import fs10 from "fs";
|
|
2662
2758
|
import path15 from "path";
|
|
2663
2759
|
|
|
2664
2760
|
// src/commands/lint/lint/renameExports.ts
|
|
@@ -2694,8 +2790,8 @@ function isCaseOnly(a, b) {
|
|
|
2694
2790
|
}
|
|
2695
2791
|
function moveCaseInsensitive(absSource, absDest) {
|
|
2696
2792
|
const tmp = `${absSource}.tmp`;
|
|
2697
|
-
|
|
2698
|
-
|
|
2793
|
+
fs10.renameSync(absSource, tmp);
|
|
2794
|
+
fs10.renameSync(tmp, absDest);
|
|
2699
2795
|
}
|
|
2700
2796
|
function applyMoves(project, moves, cwd, emit4) {
|
|
2701
2797
|
for (const { sourcePath, destPath } of moves) {
|
|
@@ -2715,19 +2811,19 @@ function applyMoves(project, moves, cwd, emit4) {
|
|
|
2715
2811
|
for (const { sourcePath, destPath } of moves) {
|
|
2716
2812
|
const absSource = path15.resolve(sourcePath);
|
|
2717
2813
|
const absDest = path15.resolve(destPath);
|
|
2718
|
-
if (isCaseOnly(absSource, absDest) &&
|
|
2814
|
+
if (isCaseOnly(absSource, absDest) && fs10.existsSync(absSource)) {
|
|
2719
2815
|
moveCaseInsensitive(absSource, absDest);
|
|
2720
2816
|
}
|
|
2721
2817
|
}
|
|
2722
2818
|
}
|
|
2723
2819
|
|
|
2724
2820
|
// src/commands/lint/lint/createLintProject.ts
|
|
2725
|
-
import
|
|
2821
|
+
import fs11 from "fs";
|
|
2726
2822
|
import path16 from "path";
|
|
2727
2823
|
import { Project } from "ts-morph";
|
|
2728
2824
|
function createLintProject() {
|
|
2729
2825
|
const tsConfigPath = path16.resolve("tsconfig.json");
|
|
2730
|
-
const project =
|
|
2826
|
+
const project = fs11.existsSync(tsConfigPath) ? new Project({
|
|
2731
2827
|
tsConfigFilePath: tsConfigPath,
|
|
2732
2828
|
skipAddingFilesFromTsConfig: true
|
|
2733
2829
|
}) : new Project();
|
|
@@ -2784,7 +2880,7 @@ function runFileNameCheck(fix = false) {
|
|
|
2784
2880
|
}
|
|
2785
2881
|
|
|
2786
2882
|
// src/commands/lint/lint/runImportExtensionCheck.ts
|
|
2787
|
-
import
|
|
2883
|
+
import fs12 from "fs";
|
|
2788
2884
|
|
|
2789
2885
|
// src/commands/lint/shared.ts
|
|
2790
2886
|
import chalk26 from "chalk";
|
|
@@ -2810,7 +2906,7 @@ ${checkName} failed:
|
|
|
2810
2906
|
|
|
2811
2907
|
// src/commands/lint/lint/runImportExtensionCheck.ts
|
|
2812
2908
|
function checkForImportExtensions(filePath) {
|
|
2813
|
-
const content =
|
|
2909
|
+
const content = fs12.readFileSync(filePath, "utf8");
|
|
2814
2910
|
const lines = content.split("\n");
|
|
2815
2911
|
const violations = [];
|
|
2816
2912
|
const importExtensionPattern = /from\s+["']\..*\.(js|ts)["']/;
|
|
@@ -2844,9 +2940,9 @@ function runImportExtensionCheck() {
|
|
|
2844
2940
|
}
|
|
2845
2941
|
|
|
2846
2942
|
// src/commands/lint/lint/runStaticImportCheck.ts
|
|
2847
|
-
import
|
|
2943
|
+
import fs13 from "fs";
|
|
2848
2944
|
function checkForDynamicImports(filePath) {
|
|
2849
|
-
const content =
|
|
2945
|
+
const content = fs13.readFileSync(filePath, "utf8");
|
|
2850
2946
|
const lines = content.split("\n");
|
|
2851
2947
|
const violations = [];
|
|
2852
2948
|
const requirePattern = /\brequire\s*\(/;
|
|
@@ -2896,7 +2992,7 @@ import { basename as basename2, resolve as resolve5 } from "path";
|
|
|
2896
2992
|
|
|
2897
2993
|
// src/commands/verify/blockComments/findComments.ts
|
|
2898
2994
|
import { execSync as execSync10 } from "child_process";
|
|
2899
|
-
import
|
|
2995
|
+
import fs15 from "fs";
|
|
2900
2996
|
import { minimatch } from "minimatch";
|
|
2901
2997
|
import { Project as Project2 } from "ts-morph";
|
|
2902
2998
|
|
|
@@ -2930,7 +3026,7 @@ function isHashCommentFile(filePath) {
|
|
|
2930
3026
|
}
|
|
2931
3027
|
|
|
2932
3028
|
// src/commands/verify/blockComments/collectFileComments.ts
|
|
2933
|
-
import
|
|
3029
|
+
import fs14 from "fs";
|
|
2934
3030
|
|
|
2935
3031
|
// src/shared/isBicepFile.ts
|
|
2936
3032
|
var BICEP_EXTENSIONS = [".bicep", ".bicepparam"];
|
|
@@ -3085,7 +3181,7 @@ function toFindings(file, lines, raw, exempt) {
|
|
|
3085
3181
|
return findings;
|
|
3086
3182
|
}
|
|
3087
3183
|
function collectFileComments(file, lines, project) {
|
|
3088
|
-
const read = () =>
|
|
3184
|
+
const read = () => fs14.readFileSync(file, "utf8");
|
|
3089
3185
|
if (isYamlFile(file))
|
|
3090
3186
|
return toFindings(file, lines, collectYamlComments(read()), false);
|
|
3091
3187
|
if (isDockerfile(file) || isEnvFile(file) || isShellFile(file))
|
|
@@ -3152,7 +3248,7 @@ function shouldScan(file, ignoreGlobs) {
|
|
|
3152
3248
|
if (!SCANNED_EXTENSIONS.some((ext) => file.endsWith(ext)) && !isHashCommentFile(file))
|
|
3153
3249
|
return false;
|
|
3154
3250
|
if (ignoreGlobs.some((glob) => minimatch(file, glob))) return false;
|
|
3155
|
-
return
|
|
3251
|
+
return fs15.existsSync(file);
|
|
3156
3252
|
}
|
|
3157
3253
|
function findComments(options2) {
|
|
3158
3254
|
const diff2 = execSync10("git diff HEAD", {
|
|
@@ -4230,7 +4326,7 @@ function detectPlatform() {
|
|
|
4230
4326
|
|
|
4231
4327
|
// src/commands/notify/showNotification/showWindowsNotificationFromWsl.ts
|
|
4232
4328
|
import { spawn as spawn2 } from "child_process";
|
|
4233
|
-
import
|
|
4329
|
+
import fs16 from "fs";
|
|
4234
4330
|
import { createRequire } from "module";
|
|
4235
4331
|
import path21 from "path";
|
|
4236
4332
|
var require2 = createRequire(import.meta.url);
|
|
@@ -4242,7 +4338,7 @@ function showWindowsNotificationFromWsl(options2) {
|
|
|
4242
4338
|
const { title, message, sound } = options2;
|
|
4243
4339
|
const snoreToastPath = getSnoreToastPath();
|
|
4244
4340
|
try {
|
|
4245
|
-
|
|
4341
|
+
fs16.chmodSync(snoreToastPath, 493);
|
|
4246
4342
|
} catch {
|
|
4247
4343
|
}
|
|
4248
4344
|
const args = ["-t", title, "-m", message];
|
|
@@ -6684,12 +6780,12 @@ import chalk42 from "chalk";
|
|
|
6684
6780
|
import * as path24 from "path";
|
|
6685
6781
|
|
|
6686
6782
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
6687
|
-
import * as
|
|
6783
|
+
import * as fs18 from "fs";
|
|
6688
6784
|
import * as os2 from "os";
|
|
6689
6785
|
import * as path23 from "path";
|
|
6690
6786
|
|
|
6691
6787
|
// src/commands/sessions/shared/parseSessionFile.ts
|
|
6692
|
-
import * as
|
|
6788
|
+
import * as fs17 from "fs";
|
|
6693
6789
|
import * as path22 from "path";
|
|
6694
6790
|
|
|
6695
6791
|
// src/commands/sessions/shared/deriveHistoryFields.ts
|
|
@@ -6787,10 +6883,10 @@ function matchMarker(text17, tag) {
|
|
|
6787
6883
|
async function parseSessionFile(filePath, origin = "wsl") {
|
|
6788
6884
|
let handle;
|
|
6789
6885
|
try {
|
|
6790
|
-
handle = await
|
|
6886
|
+
handle = await fs17.promises.open(filePath, "r");
|
|
6791
6887
|
const meta = extractSessionMeta(await readHeadLines(handle));
|
|
6792
6888
|
if (!meta.sessionId) return null;
|
|
6793
|
-
const timestamp6 = meta.timestamp || (await
|
|
6889
|
+
const timestamp6 = meta.timestamp || (await fs17.promises.stat(filePath)).mtime.toISOString();
|
|
6794
6890
|
return {
|
|
6795
6891
|
sessionId: meta.sessionId,
|
|
6796
6892
|
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
@@ -6836,7 +6932,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
6836
6932
|
sessionRoots().map(async ({ dir, origin }) => {
|
|
6837
6933
|
let projectDirs;
|
|
6838
6934
|
try {
|
|
6839
|
-
projectDirs = await
|
|
6935
|
+
projectDirs = await fs18.promises.readdir(dir);
|
|
6840
6936
|
} catch {
|
|
6841
6937
|
return;
|
|
6842
6938
|
}
|
|
@@ -6845,7 +6941,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
6845
6941
|
const dirPath = path23.join(dir, dirName);
|
|
6846
6942
|
let entries;
|
|
6847
6943
|
try {
|
|
6848
|
-
entries = await
|
|
6944
|
+
entries = await fs18.promises.readdir(dirPath);
|
|
6849
6945
|
} catch {
|
|
6850
6946
|
return;
|
|
6851
6947
|
}
|
|
@@ -7618,9 +7714,9 @@ function startWebServer(label2, port, handler, initialPath, open = true) {
|
|
|
7618
7714
|
// src/commands/sessions/daemon/ensureDaemonRunning.ts
|
|
7619
7715
|
import { spawn as spawn4 } from "child_process";
|
|
7620
7716
|
import {
|
|
7621
|
-
closeSync,
|
|
7717
|
+
closeSync as closeSync2,
|
|
7622
7718
|
mkdirSync as mkdirSync10,
|
|
7623
|
-
openSync,
|
|
7719
|
+
openSync as openSync2,
|
|
7624
7720
|
statSync,
|
|
7625
7721
|
unlinkSync as unlinkSync5,
|
|
7626
7722
|
writeSync
|
|
@@ -7660,9 +7756,9 @@ function acquireSpawnLock() {
|
|
|
7660
7756
|
}
|
|
7661
7757
|
function tryCreateLock() {
|
|
7662
7758
|
try {
|
|
7663
|
-
const fd =
|
|
7759
|
+
const fd = openSync2(daemonPaths.spawnLock, "wx");
|
|
7664
7760
|
writeSync(fd, String(process.pid));
|
|
7665
|
-
|
|
7761
|
+
closeSync2(fd);
|
|
7666
7762
|
return true;
|
|
7667
7763
|
} catch {
|
|
7668
7764
|
return false;
|
|
@@ -7682,7 +7778,7 @@ function releaseSpawnLock() {
|
|
|
7682
7778
|
}
|
|
7683
7779
|
}
|
|
7684
7780
|
function spawnDaemon(reason) {
|
|
7685
|
-
const log =
|
|
7781
|
+
const log = openSync2(daemonPaths.log, "a");
|
|
7686
7782
|
const child = spawn4(process.execPath, [process.argv[1], "daemon", "run"], {
|
|
7687
7783
|
detached: true,
|
|
7688
7784
|
stdio: ["ignore", log, log],
|
|
@@ -12773,13 +12869,13 @@ import chalk119 from "chalk";
|
|
|
12773
12869
|
import chalk112 from "chalk";
|
|
12774
12870
|
|
|
12775
12871
|
// src/commands/complexity/shared/index.ts
|
|
12776
|
-
import
|
|
12872
|
+
import fs20 from "fs";
|
|
12777
12873
|
import path27 from "path";
|
|
12778
12874
|
import chalk111 from "chalk";
|
|
12779
12875
|
import ts5 from "typescript";
|
|
12780
12876
|
|
|
12781
12877
|
// src/commands/complexity/findSourceFiles.ts
|
|
12782
|
-
import
|
|
12878
|
+
import fs19 from "fs";
|
|
12783
12879
|
import path26 from "path";
|
|
12784
12880
|
import { minimatch as minimatch5 } from "minimatch";
|
|
12785
12881
|
function applyIgnoreGlobs(files, extraIgnore = []) {
|
|
@@ -12788,11 +12884,11 @@ function applyIgnoreGlobs(files, extraIgnore = []) {
|
|
|
12788
12884
|
return files.filter((f) => !ignore3.some((glob) => minimatch5(f, glob)));
|
|
12789
12885
|
}
|
|
12790
12886
|
function walk(dir, results) {
|
|
12791
|
-
if (!
|
|
12887
|
+
if (!fs19.existsSync(dir)) {
|
|
12792
12888
|
return;
|
|
12793
12889
|
}
|
|
12794
12890
|
const extensions = [".ts", ".tsx"];
|
|
12795
|
-
const entries =
|
|
12891
|
+
const entries = fs19.readdirSync(dir, { withFileTypes: true });
|
|
12796
12892
|
for (const entry of entries) {
|
|
12797
12893
|
const fullPath = path26.join(dir, entry.name);
|
|
12798
12894
|
if (entry.isDirectory()) {
|
|
@@ -12813,10 +12909,10 @@ function findSourceFiles2(pattern2, baseDir = ".", extraIgnore = []) {
|
|
|
12813
12909
|
extraIgnore
|
|
12814
12910
|
);
|
|
12815
12911
|
}
|
|
12816
|
-
if (
|
|
12912
|
+
if (fs19.existsSync(pattern2) && fs19.statSync(pattern2).isFile()) {
|
|
12817
12913
|
return [pattern2];
|
|
12818
12914
|
}
|
|
12819
|
-
if (
|
|
12915
|
+
if (fs19.existsSync(pattern2) && fs19.statSync(pattern2).isDirectory()) {
|
|
12820
12916
|
walk(pattern2, results);
|
|
12821
12917
|
return applyIgnoreGlobs(results, extraIgnore);
|
|
12822
12918
|
}
|
|
@@ -13014,7 +13110,7 @@ function countSloc(content) {
|
|
|
13014
13110
|
|
|
13015
13111
|
// src/commands/complexity/shared/index.ts
|
|
13016
13112
|
function createSourceFromFile(filePath) {
|
|
13017
|
-
const content =
|
|
13113
|
+
const content = fs20.readFileSync(filePath, "utf8");
|
|
13018
13114
|
return ts5.createSourceFile(
|
|
13019
13115
|
path27.basename(filePath),
|
|
13020
13116
|
content,
|
|
@@ -13174,7 +13270,7 @@ function printMaintainabilityFormula() {
|
|
|
13174
13270
|
}
|
|
13175
13271
|
|
|
13176
13272
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
13177
|
-
import
|
|
13273
|
+
import fs21 from "fs";
|
|
13178
13274
|
|
|
13179
13275
|
// src/commands/complexity/maintainability/calculateMaintainabilityIndex.ts
|
|
13180
13276
|
function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
|
|
@@ -13189,7 +13285,7 @@ function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, slo
|
|
|
13189
13285
|
function collectFileMetrics(files) {
|
|
13190
13286
|
const fileMetrics = /* @__PURE__ */ new Map();
|
|
13191
13287
|
for (const file of files) {
|
|
13192
|
-
const content =
|
|
13288
|
+
const content = fs21.readFileSync(file, "utf8");
|
|
13193
13289
|
fileMetrics.set(file, {
|
|
13194
13290
|
sloc: countSloc(content),
|
|
13195
13291
|
functions: [],
|
|
@@ -13245,14 +13341,14 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
13245
13341
|
}
|
|
13246
13342
|
|
|
13247
13343
|
// src/commands/complexity/sloc.ts
|
|
13248
|
-
import
|
|
13344
|
+
import fs22 from "fs";
|
|
13249
13345
|
import chalk118 from "chalk";
|
|
13250
13346
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
13251
13347
|
withSourceFiles(pattern2, (files) => {
|
|
13252
13348
|
const results = [];
|
|
13253
13349
|
let hasViolation = false;
|
|
13254
13350
|
for (const file of files) {
|
|
13255
|
-
const content =
|
|
13351
|
+
const content = fs22.readFileSync(file, "utf8");
|
|
13256
13352
|
const lines = countSloc(content);
|
|
13257
13353
|
results.push({ file, lines });
|
|
13258
13354
|
if (options2.threshold !== void 0 && lines > options2.threshold) {
|
|
@@ -14147,7 +14243,7 @@ function registerDevlog(program2) {
|
|
|
14147
14243
|
}
|
|
14148
14244
|
|
|
14149
14245
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
14150
|
-
import { closeSync as
|
|
14246
|
+
import { closeSync as closeSync3, openSync as openSync3, readdirSync as readdirSync5 } from "fs";
|
|
14151
14247
|
import { join as join37 } from "path";
|
|
14152
14248
|
import chalk131 from "chalk";
|
|
14153
14249
|
|
|
@@ -14178,8 +14274,8 @@ function isLockedDll(debugDir) {
|
|
|
14178
14274
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
14179
14275
|
const dllPath = join37(debugDir, file);
|
|
14180
14276
|
try {
|
|
14181
|
-
const fd =
|
|
14182
|
-
|
|
14277
|
+
const fd = openSync3(dllPath, "r+");
|
|
14278
|
+
closeSync3(fd);
|
|
14183
14279
|
} catch {
|
|
14184
14280
|
return dllPath;
|
|
14185
14281
|
}
|
|
@@ -14779,7 +14875,7 @@ function registerDotnet(program2) {
|
|
|
14779
14875
|
}
|
|
14780
14876
|
|
|
14781
14877
|
// src/commands/editHook/index.ts
|
|
14782
|
-
import
|
|
14878
|
+
import fs23 from "fs";
|
|
14783
14879
|
|
|
14784
14880
|
// src/commands/editHook/extractComments.ts
|
|
14785
14881
|
var SOURCE_EXTENSIONS = [
|
|
@@ -14959,7 +15055,7 @@ function tryParseInput2(raw) {
|
|
|
14959
15055
|
function readExisting(filePath) {
|
|
14960
15056
|
if (!filePath) return void 0;
|
|
14961
15057
|
try {
|
|
14962
|
-
return
|
|
15058
|
+
return fs23.readFileSync(filePath, "utf8");
|
|
14963
15059
|
} catch {
|
|
14964
15060
|
return void 0;
|
|
14965
15061
|
}
|
|
@@ -16860,14 +16956,15 @@ ${resolves}` : baseWhy);
|
|
|
16860
16956
|
return serializePrBody(parsed);
|
|
16861
16957
|
}
|
|
16862
16958
|
|
|
16863
|
-
// src/commands/prs/
|
|
16959
|
+
// src/commands/prs/findWallOfText.ts
|
|
16864
16960
|
var MAX_PARAGRAPH_CHARS = 600;
|
|
16865
16961
|
var MAX_PARAGRAPH_SENTENCES = 4;
|
|
16866
|
-
function
|
|
16867
|
-
|
|
16868
|
-
|
|
16869
|
-
|
|
16870
|
-
|
|
16962
|
+
function findWallOfText(body) {
|
|
16963
|
+
const wall = splitParagraphs(body).find((p) => isWallOfText(p.lines));
|
|
16964
|
+
if (!wall) {
|
|
16965
|
+
return void 0;
|
|
16966
|
+
}
|
|
16967
|
+
return { section: wall.section, chars: wall.lines.join(" ").trim().length };
|
|
16871
16968
|
}
|
|
16872
16969
|
function splitParagraphs(body) {
|
|
16873
16970
|
const paragraphs = [];
|
|
@@ -16900,6 +16997,14 @@ function isWallOfText(lines) {
|
|
|
16900
16997
|
const text17 = lines.join(" ").trim();
|
|
16901
16998
|
return text17.length > MAX_PARAGRAPH_CHARS || countSentences(text17) > MAX_PARAGRAPH_SENTENCES;
|
|
16902
16999
|
}
|
|
17000
|
+
function countSentences(paragraph) {
|
|
17001
|
+
return paragraph.match(/[.!?]+(\s|$)/g)?.length ?? 0;
|
|
17002
|
+
}
|
|
17003
|
+
function isListLine(line) {
|
|
17004
|
+
return /^\s*([-*+]|\d+[.)])\s/.test(line);
|
|
17005
|
+
}
|
|
17006
|
+
|
|
17007
|
+
// src/commands/prs/validatePrContent.ts
|
|
16903
17008
|
function validatePrContent(title, body) {
|
|
16904
17009
|
if (title.toLowerCase().includes("claude")) {
|
|
16905
17010
|
console.error("Error: PR title must not reference Claude");
|
|
@@ -16909,11 +17014,20 @@ function validatePrContent(title, body) {
|
|
|
16909
17014
|
console.error("Error: PR body must not reference Claude");
|
|
16910
17015
|
process.exit(1);
|
|
16911
17016
|
}
|
|
16912
|
-
const
|
|
17017
|
+
const titleBacklogIds = findBacklogRefs(title);
|
|
17018
|
+
if (titleBacklogIds.length > 0) {
|
|
17019
|
+
console.error(backlogRefError("PR title", "PRs", titleBacklogIds));
|
|
17020
|
+
process.exit(1);
|
|
17021
|
+
}
|
|
17022
|
+
const bodyBacklogIds = findBacklogRefs(body);
|
|
17023
|
+
if (bodyBacklogIds.length > 0) {
|
|
17024
|
+
console.error(backlogRefError("PR body", "PRs", bodyBacklogIds));
|
|
17025
|
+
process.exit(1);
|
|
17026
|
+
}
|
|
17027
|
+
const wall = findWallOfText(body);
|
|
16913
17028
|
if (wall) {
|
|
16914
|
-
const chars = wall.lines.join(" ").trim().length;
|
|
16915
17029
|
console.error(
|
|
16916
|
-
`Error: the "${wall.section}" section contains a wall-of-text paragraph (${chars} chars). Be concise \u2014 split it into bullet points or trim it.`
|
|
17030
|
+
`Error: the "${wall.section}" section contains a wall-of-text paragraph (${wall.chars} chars). Be concise \u2014 split it into bullet points or trim it.`
|
|
16917
17031
|
);
|
|
16918
17032
|
process.exit(1);
|
|
16919
17033
|
}
|
|
@@ -18116,17 +18230,17 @@ Refactor check failed:
|
|
|
18116
18230
|
|
|
18117
18231
|
// src/commands/refactor/check/getViolations/index.ts
|
|
18118
18232
|
import { execSync as execSync49 } from "child_process";
|
|
18119
|
-
import
|
|
18233
|
+
import fs25 from "fs";
|
|
18120
18234
|
import { minimatch as minimatch6 } from "minimatch";
|
|
18121
18235
|
|
|
18122
18236
|
// src/commands/refactor/check/getViolations/getIgnoredFiles.ts
|
|
18123
|
-
import
|
|
18237
|
+
import fs24 from "fs";
|
|
18124
18238
|
var REFACTOR_YML_PATH = "refactor.yml";
|
|
18125
18239
|
function parseRefactorYml() {
|
|
18126
|
-
if (!
|
|
18240
|
+
if (!fs24.existsSync(REFACTOR_YML_PATH)) {
|
|
18127
18241
|
return [];
|
|
18128
18242
|
}
|
|
18129
|
-
const content =
|
|
18243
|
+
const content = fs24.readFileSync(REFACTOR_YML_PATH, "utf8");
|
|
18130
18244
|
const entries = [];
|
|
18131
18245
|
const lines = content.split("\n");
|
|
18132
18246
|
let currentEntry = {};
|
|
@@ -18156,7 +18270,7 @@ function getIgnoredFiles() {
|
|
|
18156
18270
|
|
|
18157
18271
|
// src/commands/refactor/check/getViolations/index.ts
|
|
18158
18272
|
function countLines(filePath) {
|
|
18159
|
-
const content =
|
|
18273
|
+
const content = fs25.readFileSync(filePath, "utf8");
|
|
18160
18274
|
return content.split("\n").length;
|
|
18161
18275
|
}
|
|
18162
18276
|
function getGitFiles(options2) {
|
|
@@ -18914,12 +19028,12 @@ import chalk170 from "chalk";
|
|
|
18914
19028
|
import { Project as Project4 } from "ts-morph";
|
|
18915
19029
|
|
|
18916
19030
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
18917
|
-
import
|
|
19031
|
+
import fs26 from "fs";
|
|
18918
19032
|
import path39 from "path";
|
|
18919
19033
|
import { Project as Project3 } from "ts-morph";
|
|
18920
19034
|
function findTsConfig(sourcePath) {
|
|
18921
19035
|
const rootConfig = path39.resolve("tsconfig.json");
|
|
18922
|
-
if (!
|
|
19036
|
+
if (!fs26.existsSync(rootConfig)) return rootConfig;
|
|
18923
19037
|
const tried = /* @__PURE__ */ new Set();
|
|
18924
19038
|
const candidates = [rootConfig, ...readReferences(rootConfig)];
|
|
18925
19039
|
for (const candidate of candidates) {
|
|
@@ -18927,7 +19041,7 @@ function findTsConfig(sourcePath) {
|
|
|
18927
19041
|
tried.add(candidate);
|
|
18928
19042
|
if (projectIncludes(candidate, sourcePath)) return candidate;
|
|
18929
19043
|
}
|
|
18930
|
-
const siblings =
|
|
19044
|
+
const siblings = fs26.readdirSync(path39.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path39.resolve(path39.dirname(rootConfig), f));
|
|
18931
19045
|
for (const sibling of siblings) {
|
|
18932
19046
|
if (tried.has(sibling)) continue;
|
|
18933
19047
|
tried.add(sibling);
|
|
@@ -18936,8 +19050,8 @@ function findTsConfig(sourcePath) {
|
|
|
18936
19050
|
return rootConfig;
|
|
18937
19051
|
}
|
|
18938
19052
|
function readReferences(configPath) {
|
|
18939
|
-
if (!
|
|
18940
|
-
const raw =
|
|
19053
|
+
if (!fs26.existsSync(configPath)) return [];
|
|
19054
|
+
const raw = fs26.readFileSync(configPath, "utf8");
|
|
18941
19055
|
const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
18942
19056
|
let parsed;
|
|
18943
19057
|
try {
|
|
@@ -18949,8 +19063,8 @@ function readReferences(configPath) {
|
|
|
18949
19063
|
const cwd = path39.dirname(configPath);
|
|
18950
19064
|
return parsed.references.map((ref) => {
|
|
18951
19065
|
const refPath = path39.resolve(cwd, ref.path);
|
|
18952
|
-
return
|
|
18953
|
-
}).filter((p) =>
|
|
19066
|
+
return fs26.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path39.join(refPath, "tsconfig.json") : refPath;
|
|
19067
|
+
}).filter((p) => fs26.existsSync(p));
|
|
18954
19068
|
}
|
|
18955
19069
|
function projectIncludes(configPath, sourcePath) {
|
|
18956
19070
|
try {
|
|
@@ -19000,25 +19114,25 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
19000
19114
|
}
|
|
19001
19115
|
|
|
19002
19116
|
// src/commands/refactor/ignore.ts
|
|
19003
|
-
import
|
|
19117
|
+
import fs27 from "fs";
|
|
19004
19118
|
import chalk172 from "chalk";
|
|
19005
19119
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
19006
19120
|
function ignore2(file) {
|
|
19007
|
-
if (!
|
|
19121
|
+
if (!fs27.existsSync(file)) {
|
|
19008
19122
|
console.error(chalk172.red(`Error: File does not exist: ${file}`));
|
|
19009
19123
|
process.exit(1);
|
|
19010
19124
|
}
|
|
19011
|
-
const content =
|
|
19125
|
+
const content = fs27.readFileSync(file, "utf8");
|
|
19012
19126
|
const lineCount = content.split("\n").length;
|
|
19013
19127
|
const maxLines = lineCount + 10;
|
|
19014
19128
|
const entry = `- file: ${file}
|
|
19015
19129
|
maxLines: ${maxLines}
|
|
19016
19130
|
`;
|
|
19017
|
-
if (
|
|
19018
|
-
const existing =
|
|
19019
|
-
|
|
19131
|
+
if (fs27.existsSync(REFACTOR_YML_PATH2)) {
|
|
19132
|
+
const existing = fs27.readFileSync(REFACTOR_YML_PATH2, "utf8");
|
|
19133
|
+
fs27.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
|
|
19020
19134
|
} else {
|
|
19021
|
-
|
|
19135
|
+
fs27.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
19022
19136
|
}
|
|
19023
19137
|
console.log(
|
|
19024
19138
|
chalk172.green(
|
|
@@ -19028,12 +19142,12 @@ function ignore2(file) {
|
|
|
19028
19142
|
}
|
|
19029
19143
|
|
|
19030
19144
|
// src/commands/refactor/rename/index.ts
|
|
19031
|
-
import
|
|
19145
|
+
import fs30 from "fs";
|
|
19032
19146
|
import path46 from "path";
|
|
19033
19147
|
import chalk175 from "chalk";
|
|
19034
19148
|
|
|
19035
19149
|
// src/commands/refactor/rename/applyRename.ts
|
|
19036
|
-
import
|
|
19150
|
+
import fs29 from "fs";
|
|
19037
19151
|
import path43 from "path";
|
|
19038
19152
|
import chalk173 from "chalk";
|
|
19039
19153
|
|
|
@@ -19041,7 +19155,7 @@ import chalk173 from "chalk";
|
|
|
19041
19155
|
import path42 from "path";
|
|
19042
19156
|
|
|
19043
19157
|
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
19044
|
-
import
|
|
19158
|
+
import fs28 from "fs";
|
|
19045
19159
|
function getOrCreateList(map, key) {
|
|
19046
19160
|
const list5 = map.get(key) ?? [];
|
|
19047
19161
|
if (!map.has(key)) map.set(key, list5);
|
|
@@ -19060,7 +19174,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
|
19060
19174
|
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
19061
19175
|
}
|
|
19062
19176
|
function applyFileRewrites(file, fileRewrites) {
|
|
19063
|
-
let content =
|
|
19177
|
+
let content = fs28.readFileSync(file, "utf8");
|
|
19064
19178
|
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
19065
19179
|
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
19066
19180
|
}
|
|
@@ -19139,12 +19253,12 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
19139
19253
|
function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
19140
19254
|
const updatedContents = applyRewrites(rewrites);
|
|
19141
19255
|
for (const [file, content] of updatedContents) {
|
|
19142
|
-
|
|
19256
|
+
fs29.writeFileSync(file, content, "utf8");
|
|
19143
19257
|
console.log(chalk173.cyan(` Updated imports in ${path43.relative(cwd, file)}`));
|
|
19144
19258
|
}
|
|
19145
19259
|
const destDir = path43.dirname(destPath);
|
|
19146
|
-
if (!
|
|
19147
|
-
|
|
19260
|
+
if (!fs29.existsSync(destDir)) fs29.mkdirSync(destDir, { recursive: true });
|
|
19261
|
+
fs29.renameSync(sourcePath, destPath);
|
|
19148
19262
|
console.log(
|
|
19149
19263
|
chalk173.white(
|
|
19150
19264
|
` Moved ${path43.relative(cwd, sourcePath)} \u2192 ${path43.relative(cwd, destPath)}`
|
|
@@ -19252,11 +19366,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
19252
19366
|
const cwd = process.cwd();
|
|
19253
19367
|
const relSource = path46.relative(cwd, sourcePath);
|
|
19254
19368
|
const relDest = path46.relative(cwd, destPath);
|
|
19255
|
-
if (!
|
|
19369
|
+
if (!fs30.existsSync(sourcePath)) {
|
|
19256
19370
|
console.log(chalk175.red(`File not found: ${source}`));
|
|
19257
19371
|
process.exit(1);
|
|
19258
19372
|
}
|
|
19259
|
-
if (destPath !== sourcePath &&
|
|
19373
|
+
if (destPath !== sourcePath && fs30.existsSync(destPath)) {
|
|
19260
19374
|
console.log(chalk175.red(`Destination already exists: ${destination}`));
|
|
19261
19375
|
process.exit(1);
|
|
19262
19376
|
}
|
|
@@ -19481,27 +19595,27 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
19481
19595
|
}
|
|
19482
19596
|
|
|
19483
19597
|
// src/commands/refactor/restructure/executePlan.ts
|
|
19484
|
-
import
|
|
19598
|
+
import fs31 from "fs";
|
|
19485
19599
|
import path51 from "path";
|
|
19486
19600
|
import chalk178 from "chalk";
|
|
19487
19601
|
function executePlan(plan2) {
|
|
19488
19602
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
19489
19603
|
for (const [file, content] of updatedContents) {
|
|
19490
|
-
|
|
19604
|
+
fs31.writeFileSync(file, content, "utf8");
|
|
19491
19605
|
console.log(
|
|
19492
19606
|
chalk178.cyan(` Rewrote imports in ${path51.relative(process.cwd(), file)}`)
|
|
19493
19607
|
);
|
|
19494
19608
|
}
|
|
19495
19609
|
for (const dir of plan2.newDirectories) {
|
|
19496
|
-
|
|
19610
|
+
fs31.mkdirSync(dir, { recursive: true });
|
|
19497
19611
|
console.log(chalk178.green(` Created ${path51.relative(process.cwd(), dir)}/`));
|
|
19498
19612
|
}
|
|
19499
19613
|
for (const move2 of plan2.moves) {
|
|
19500
19614
|
const targetDir = path51.dirname(move2.to);
|
|
19501
|
-
if (!
|
|
19502
|
-
|
|
19615
|
+
if (!fs31.existsSync(targetDir)) {
|
|
19616
|
+
fs31.mkdirSync(targetDir, { recursive: true });
|
|
19503
19617
|
}
|
|
19504
|
-
|
|
19618
|
+
fs31.renameSync(move2.from, move2.to);
|
|
19505
19619
|
console.log(
|
|
19506
19620
|
chalk178.white(
|
|
19507
19621
|
` Moved ${path51.relative(process.cwd(), move2.from)} \u2192 ${path51.relative(process.cwd(), move2.to)}`
|
|
@@ -19513,10 +19627,10 @@ function executePlan(plan2) {
|
|
|
19513
19627
|
function removeEmptyDirectories(dirs) {
|
|
19514
19628
|
const unique = [...new Set(dirs)];
|
|
19515
19629
|
for (const dir of unique) {
|
|
19516
|
-
if (!
|
|
19517
|
-
const entries =
|
|
19630
|
+
if (!fs31.existsSync(dir)) continue;
|
|
19631
|
+
const entries = fs31.readdirSync(dir);
|
|
19518
19632
|
if (entries.length === 0) {
|
|
19519
|
-
|
|
19633
|
+
fs31.rmdirSync(dir);
|
|
19520
19634
|
console.log(
|
|
19521
19635
|
chalk178.dim(
|
|
19522
19636
|
` Removed empty directory ${path51.relative(process.cwd(), dir)}`
|
|
@@ -19530,18 +19644,18 @@ function removeEmptyDirectories(dirs) {
|
|
|
19530
19644
|
import path53 from "path";
|
|
19531
19645
|
|
|
19532
19646
|
// src/commands/refactor/restructure/planFileMoves/shared.ts
|
|
19533
|
-
import
|
|
19647
|
+
import fs32 from "fs";
|
|
19534
19648
|
function emptyResult() {
|
|
19535
19649
|
return { moves: [], directories: [], warnings: [] };
|
|
19536
19650
|
}
|
|
19537
19651
|
function checkDirConflict(result, label2, dir) {
|
|
19538
|
-
if (!
|
|
19652
|
+
if (!fs32.existsSync(dir)) return false;
|
|
19539
19653
|
result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
|
|
19540
19654
|
return true;
|
|
19541
19655
|
}
|
|
19542
19656
|
|
|
19543
19657
|
// src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
|
|
19544
|
-
import
|
|
19658
|
+
import fs33 from "fs";
|
|
19545
19659
|
import path52 from "path";
|
|
19546
19660
|
function collectEntry(results, dir, entry) {
|
|
19547
19661
|
const full = path52.join(dir, entry.name);
|
|
@@ -19549,9 +19663,9 @@ function collectEntry(results, dir, entry) {
|
|
|
19549
19663
|
results.push(...items2);
|
|
19550
19664
|
}
|
|
19551
19665
|
function listFilesRecursive(dir) {
|
|
19552
|
-
if (!
|
|
19666
|
+
if (!fs33.existsSync(dir)) return [];
|
|
19553
19667
|
const results = [];
|
|
19554
|
-
for (const entry of
|
|
19668
|
+
for (const entry of fs33.readdirSync(dir, { withFileTypes: true })) {
|
|
19555
19669
|
collectEntry(results, dir, entry);
|
|
19556
19670
|
}
|
|
19557
19671
|
return results;
|
|
@@ -24231,14 +24345,14 @@ function createAssistSession(id, assistArgs, cwd, meta) {
|
|
|
24231
24345
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
24232
24346
|
|
|
24233
24347
|
// src/commands/sessions/daemon/readDesignSystemPrompt.ts
|
|
24234
|
-
import * as
|
|
24348
|
+
import * as fs34 from "fs";
|
|
24235
24349
|
import * as path56 from "path";
|
|
24236
24350
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
24237
24351
|
var __filename4 = fileURLToPath8(import.meta.url);
|
|
24238
24352
|
var __dirname6 = path56.dirname(__filename4);
|
|
24239
24353
|
function readDesignSystemPrompt() {
|
|
24240
24354
|
const promptPath = path56.join(__dirname6, "..", "claude", "system-prompt.md");
|
|
24241
|
-
return
|
|
24355
|
+
return fs34.readFileSync(promptPath, "utf8");
|
|
24242
24356
|
}
|
|
24243
24357
|
|
|
24244
24358
|
// src/commands/sessions/daemon/spawnClaude.ts
|
|
@@ -24617,7 +24731,7 @@ async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
|
|
|
24617
24731
|
}
|
|
24618
24732
|
|
|
24619
24733
|
// src/commands/sessions/shared/transcriptUsage.ts
|
|
24620
|
-
import * as
|
|
24734
|
+
import * as fs35 from "fs";
|
|
24621
24735
|
function transcriptUsage(lines) {
|
|
24622
24736
|
const byId = /* @__PURE__ */ new Map();
|
|
24623
24737
|
for (const line of lines) {
|
|
@@ -24641,7 +24755,7 @@ function transcriptUsage(lines) {
|
|
|
24641
24755
|
return [...byId.values()];
|
|
24642
24756
|
}
|
|
24643
24757
|
async function readTranscriptUsage(transcriptPath) {
|
|
24644
|
-
const content = await
|
|
24758
|
+
const content = await fs35.promises.readFile(transcriptPath, "utf8");
|
|
24645
24759
|
return transcriptUsage(content.split("\n"));
|
|
24646
24760
|
}
|
|
24647
24761
|
|
|
@@ -26099,7 +26213,7 @@ import * as net3 from "net";
|
|
|
26099
26213
|
import { createInterface as createInterface9 } from "readline";
|
|
26100
26214
|
|
|
26101
26215
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
26102
|
-
import * as
|
|
26216
|
+
import * as fs36 from "fs";
|
|
26103
26217
|
|
|
26104
26218
|
// src/commands/sessions/shared/toolTarget.ts
|
|
26105
26219
|
function toolTarget(input) {
|
|
@@ -26151,7 +26265,7 @@ async function parseTranscript(sessionId) {
|
|
|
26151
26265
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
26152
26266
|
if (!filePath) return [];
|
|
26153
26267
|
try {
|
|
26154
|
-
const raw = await
|
|
26268
|
+
const raw = await fs36.promises.readFile(filePath, "utf8");
|
|
26155
26269
|
return parseTranscriptLines(raw.split("\n"));
|
|
26156
26270
|
} catch {
|
|
26157
26271
|
return [];
|
|
@@ -26484,13 +26598,13 @@ import * as fs38 from "fs";
|
|
|
26484
26598
|
import chalk196 from "chalk";
|
|
26485
26599
|
|
|
26486
26600
|
// src/commands/sessions/summarise/shared.ts
|
|
26487
|
-
import * as
|
|
26601
|
+
import * as fs37 from "fs";
|
|
26488
26602
|
function writeSummary(jsonlPath2, summary) {
|
|
26489
|
-
|
|
26603
|
+
fs37.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
26490
26604
|
`, "utf8");
|
|
26491
26605
|
}
|
|
26492
26606
|
function hasSummary(jsonlPath2) {
|
|
26493
|
-
return
|
|
26607
|
+
return fs37.existsSync(summaryPathFor(jsonlPath2));
|
|
26494
26608
|
}
|
|
26495
26609
|
function summaryPathFor(jsonlPath2) {
|
|
26496
26610
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -26499,56 +26613,6 @@ function summaryPathFor(jsonlPath2) {
|
|
|
26499
26613
|
// src/commands/sessions/summarise/summariseSession.ts
|
|
26500
26614
|
import { execFileSync as execFileSync12 } from "child_process";
|
|
26501
26615
|
|
|
26502
|
-
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
26503
|
-
import * as fs37 from "fs";
|
|
26504
|
-
|
|
26505
|
-
// src/commands/sessions/summarise/parseUserLine.ts
|
|
26506
|
-
function parseUserLine(line) {
|
|
26507
|
-
let entry;
|
|
26508
|
-
try {
|
|
26509
|
-
entry = JSON.parse(line);
|
|
26510
|
-
} catch {
|
|
26511
|
-
return void 0;
|
|
26512
|
-
}
|
|
26513
|
-
if (entry.type !== "user") return void 0;
|
|
26514
|
-
const msg = entry.message;
|
|
26515
|
-
const c = msg?.content;
|
|
26516
|
-
let text17;
|
|
26517
|
-
if (typeof c === "string") {
|
|
26518
|
-
text17 = c;
|
|
26519
|
-
} else if (Array.isArray(c)) {
|
|
26520
|
-
const collected = c.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n");
|
|
26521
|
-
text17 = collected || void 0;
|
|
26522
|
-
}
|
|
26523
|
-
if (!text17) return void 0;
|
|
26524
|
-
return {
|
|
26525
|
-
text: text17,
|
|
26526
|
-
entrypoint: typeof entry.entrypoint === "string" ? entry.entrypoint : void 0
|
|
26527
|
-
};
|
|
26528
|
-
}
|
|
26529
|
-
|
|
26530
|
-
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
26531
|
-
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
26532
|
-
let content;
|
|
26533
|
-
try {
|
|
26534
|
-
const fd = fs37.openSync(filePath, "r");
|
|
26535
|
-
try {
|
|
26536
|
-
const buf = Buffer.alloc(maxBytes);
|
|
26537
|
-
const bytesRead = fs37.readSync(fd, buf, 0, buf.length, 0);
|
|
26538
|
-
content = buf.toString("utf8", 0, bytesRead);
|
|
26539
|
-
} finally {
|
|
26540
|
-
fs37.closeSync(fd);
|
|
26541
|
-
}
|
|
26542
|
-
} catch {
|
|
26543
|
-
return;
|
|
26544
|
-
}
|
|
26545
|
-
for (const line of content.split("\n")) {
|
|
26546
|
-
if (!line) continue;
|
|
26547
|
-
const entry = parseUserLine(line);
|
|
26548
|
-
if (entry) yield entry.text;
|
|
26549
|
-
}
|
|
26550
|
-
}
|
|
26551
|
-
|
|
26552
26616
|
// src/commands/sessions/summarise/extractFirstUserMessage.ts
|
|
26553
26617
|
function extractFirstUserMessage(filePath) {
|
|
26554
26618
|
for (const text17 of iterateUserMessages(filePath)) {
|
|
@@ -26562,36 +26626,6 @@ function truncate3(text17, maxChars = 500) {
|
|
|
26562
26626
|
return `${trimmed.slice(0, maxChars)}\u2026`;
|
|
26563
26627
|
}
|
|
26564
26628
|
|
|
26565
|
-
// src/commands/sessions/summarise/scanSessionBacklogRefs.ts
|
|
26566
|
-
function scanSessionBacklogRefs(filePath) {
|
|
26567
|
-
const ids = /* @__PURE__ */ new Set();
|
|
26568
|
-
for (const text17 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
|
|
26569
|
-
for (const id of extractBacklogIds(text17)) {
|
|
26570
|
-
ids.add(id);
|
|
26571
|
-
}
|
|
26572
|
-
}
|
|
26573
|
-
return [...ids].sort((a, b) => a - b);
|
|
26574
|
-
}
|
|
26575
|
-
function extractBacklogIds(text17) {
|
|
26576
|
-
const ids = [];
|
|
26577
|
-
for (const m of text17.matchAll(/backlog\s+run\s+a(\d+)/gi)) {
|
|
26578
|
-
ids.push(Number.parseInt(m[1], 10));
|
|
26579
|
-
}
|
|
26580
|
-
for (const m of text17.matchAll(/backlog\s+(?:item\s+)?a(\d+)/gi)) {
|
|
26581
|
-
ids.push(Number.parseInt(m[1], 10));
|
|
26582
|
-
}
|
|
26583
|
-
for (const m of text17.matchAll(/backlog\s+phase-done\s+a(\d+)/gi)) {
|
|
26584
|
-
ids.push(Number.parseInt(m[1], 10));
|
|
26585
|
-
}
|
|
26586
|
-
for (const m of text17.matchAll(/backlog\s+comment\s+a(\d+)/gi)) {
|
|
26587
|
-
ids.push(Number.parseInt(m[1], 10));
|
|
26588
|
-
}
|
|
26589
|
-
for (const m of text17.matchAll(/(?:^|[\s(])a(\d{1,4})(?=[\s).,;:!?]|$)/gm)) {
|
|
26590
|
-
ids.push(Number.parseInt(m[1], 10));
|
|
26591
|
-
}
|
|
26592
|
-
return ids;
|
|
26593
|
-
}
|
|
26594
|
-
|
|
26595
26629
|
// src/commands/sessions/summarise/summariseSession.ts
|
|
26596
26630
|
function summariseSession(jsonlPath2) {
|
|
26597
26631
|
const firstMessage = extractFirstUserMessage(jsonlPath2);
|