@staff0rd/assist 0.319.0 → 0.320.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 +1 -0
- package/claude/settings.json +4 -0
- package/dist/index.js +582 -447
- 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.320.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -1779,6 +1779,23 @@ function collectComments(sourceFile) {
|
|
|
1779
1779
|
return comments3;
|
|
1780
1780
|
}
|
|
1781
1781
|
|
|
1782
|
+
// src/commands/complexity/maintainability/parseMaintainabilityOverride.ts
|
|
1783
|
+
var MAINTAINABILITY_OVERRIDE_MARKER = "assist-maintainability-override";
|
|
1784
|
+
var OVERRIDE_MARKER = /^\s*\/\/\s*assist-maintainability-override:?\s*(-?\d+)\s*$/;
|
|
1785
|
+
function parseMaintainabilityOverride(content) {
|
|
1786
|
+
const lines = content.split("\n").slice(0, 10);
|
|
1787
|
+
for (const line of lines) {
|
|
1788
|
+
const match = line.match(OVERRIDE_MARKER);
|
|
1789
|
+
if (!match) continue;
|
|
1790
|
+
const value = Number(match[1]);
|
|
1791
|
+
if (Number.isInteger(value) && value >= 0 && value <= 100) {
|
|
1792
|
+
return value;
|
|
1793
|
+
}
|
|
1794
|
+
return void 0;
|
|
1795
|
+
}
|
|
1796
|
+
return void 0;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1782
1799
|
// src/commands/verify/commentPolicy/isCommentExempt.ts
|
|
1783
1800
|
var MACHINE_DIRECTIVES = [
|
|
1784
1801
|
"oxlint-disable",
|
|
@@ -1792,7 +1809,8 @@ var MACHINE_DIRECTIVES = [
|
|
|
1792
1809
|
"istanbul ignore",
|
|
1793
1810
|
"v8 ignore",
|
|
1794
1811
|
"c8 ignore",
|
|
1795
|
-
"@vitest-environment"
|
|
1812
|
+
"@vitest-environment",
|
|
1813
|
+
MAINTAINABILITY_OVERRIDE_MARKER
|
|
1796
1814
|
];
|
|
1797
1815
|
function isCommentExempt(text6, markers) {
|
|
1798
1816
|
const lower = text6.toLowerCase();
|
|
@@ -9326,7 +9344,7 @@ function registerCliHook(program2) {
|
|
|
9326
9344
|
}
|
|
9327
9345
|
|
|
9328
9346
|
// src/commands/complexity/analyze.ts
|
|
9329
|
-
import
|
|
9347
|
+
import chalk100 from "chalk";
|
|
9330
9348
|
|
|
9331
9349
|
// src/commands/complexity/cyclomatic.ts
|
|
9332
9350
|
import chalk93 from "chalk";
|
|
@@ -9666,60 +9684,89 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
9666
9684
|
});
|
|
9667
9685
|
}
|
|
9668
9686
|
|
|
9669
|
-
// src/commands/complexity/maintainability/
|
|
9670
|
-
import
|
|
9687
|
+
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
9688
|
+
import chalk97 from "chalk";
|
|
9671
9689
|
|
|
9672
|
-
// src/commands/complexity/maintainability/
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
const
|
|
9678
|
-
return
|
|
9690
|
+
// src/commands/complexity/maintainability/formatResultLine.ts
|
|
9691
|
+
import chalk95 from "chalk";
|
|
9692
|
+
function formatResultLine(entry, failing) {
|
|
9693
|
+
const { file, avgMaintainability, minMaintainability, override } = entry;
|
|
9694
|
+
const name = failing ? chalk95.red(file) : chalk95.white(file);
|
|
9695
|
+
const suffix = failing && override !== void 0 ? chalk95.magenta(` (override threshold ${override})`) : "";
|
|
9696
|
+
return `${name} \u2192 avg: ${chalk95.cyan(avgMaintainability.toFixed(1))}, min: ${chalk95.yellow(minMaintainability.toFixed(1))}${suffix}`;
|
|
9697
|
+
}
|
|
9698
|
+
|
|
9699
|
+
// src/commands/complexity/maintainability/printMaintainabilityFailure.ts
|
|
9700
|
+
import chalk96 from "chalk";
|
|
9701
|
+
function printMaintainabilityFailure(failingCount, threshold) {
|
|
9702
|
+
const thresholdLabel = threshold !== void 0 ? ` ${threshold}` : "";
|
|
9703
|
+
console.error(
|
|
9704
|
+
chalk96.red(
|
|
9705
|
+
`
|
|
9706
|
+
Fail: ${failingCount} file(s) below threshold${thresholdLabel} (files marked "override threshold" were judged against their own marker). Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
9707
|
+
|
|
9708
|
+
\u26A0\uFE0F ${chalk96.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel.
|
|
9709
|
+
|
|
9710
|
+
The score is a property of the whole file, not your diff: any existing logic counts, so the fix is to shrink the file \u2014 not to revert or micro-optimize the lines you just changed. Identify the largest cohesive responsibility (often the biggest function, or a related group of functions) and move it to a new file with 'assist refactor extract'. Run 'assist complexity <file>' for per-function metrics only to locate that responsibility, not to tweak individual lines.`
|
|
9711
|
+
)
|
|
9712
|
+
);
|
|
9679
9713
|
}
|
|
9680
9714
|
|
|
9681
9715
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
9682
|
-
import chalk95 from "chalk";
|
|
9683
9716
|
function displayMaintainabilityResults(results, threshold) {
|
|
9684
|
-
const
|
|
9685
|
-
if (
|
|
9686
|
-
console.log(
|
|
9717
|
+
const gating = threshold !== void 0 || results.some((r) => r.override !== void 0);
|
|
9718
|
+
if (!gating) {
|
|
9719
|
+
for (const entry of results) console.log(formatResultLine(entry, false));
|
|
9720
|
+
console.log(chalk97.dim(`
|
|
9721
|
+
Analyzed ${results.length} files`));
|
|
9722
|
+
return;
|
|
9723
|
+
}
|
|
9724
|
+
const failing = results.filter((r) => {
|
|
9725
|
+
const limit = r.override ?? threshold;
|
|
9726
|
+
return limit !== void 0 && r.minMaintainability < limit;
|
|
9727
|
+
});
|
|
9728
|
+
if (failing.length === 0) {
|
|
9729
|
+
console.log(chalk97.green("All files pass maintainability threshold"));
|
|
9687
9730
|
} else {
|
|
9688
|
-
for (const
|
|
9689
|
-
const color = threshold !== void 0 ? chalk95.red : chalk95.white;
|
|
9690
|
-
console.log(
|
|
9691
|
-
`${color(file)} \u2192 avg: ${chalk95.cyan(avgMaintainability.toFixed(1))}, min: ${chalk95.yellow(minMaintainability.toFixed(1))}`
|
|
9692
|
-
);
|
|
9693
|
-
}
|
|
9731
|
+
for (const entry of failing) console.log(formatResultLine(entry, true));
|
|
9694
9732
|
}
|
|
9695
|
-
console.log(
|
|
9733
|
+
console.log(chalk97.dim(`
|
|
9696
9734
|
Analyzed ${results.length} files`));
|
|
9697
|
-
if (
|
|
9698
|
-
|
|
9699
|
-
chalk95.red(
|
|
9700
|
-
`
|
|
9701
|
-
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
9702
|
-
|
|
9703
|
-
\u26A0\uFE0F ${chalk95.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel. Run 'assist complexity <file>' to see all metrics. For larger files, start by extracting responsibilities into smaller files.`
|
|
9704
|
-
)
|
|
9705
|
-
);
|
|
9735
|
+
if (failing.length > 0) {
|
|
9736
|
+
printMaintainabilityFailure(failing.length, threshold);
|
|
9706
9737
|
process.exit(1);
|
|
9707
9738
|
}
|
|
9708
9739
|
}
|
|
9709
9740
|
|
|
9710
9741
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
9711
|
-
import
|
|
9742
|
+
import chalk98 from "chalk";
|
|
9712
9743
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
9713
9744
|
function printMaintainabilityFormula() {
|
|
9714
|
-
console.log(
|
|
9745
|
+
console.log(chalk98.dim(MI_FORMULA));
|
|
9715
9746
|
}
|
|
9716
9747
|
|
|
9717
|
-
// src/commands/complexity/maintainability/
|
|
9748
|
+
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
9749
|
+
import fs17 from "fs";
|
|
9750
|
+
|
|
9751
|
+
// src/commands/complexity/maintainability/calculateMaintainabilityIndex.ts
|
|
9752
|
+
function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
|
|
9753
|
+
if (halsteadVolume === 0 || sloc2 === 0) {
|
|
9754
|
+
return 100;
|
|
9755
|
+
}
|
|
9756
|
+
const mi = 171 - 5.2 * Math.log(halsteadVolume) - 0.23 * cyclomaticComplexity - 16.2 * Math.log(sloc2);
|
|
9757
|
+
return Math.max(0, Math.min(100, mi));
|
|
9758
|
+
}
|
|
9759
|
+
|
|
9760
|
+
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
9718
9761
|
function collectFileMetrics(files) {
|
|
9719
9762
|
const fileMetrics = /* @__PURE__ */ new Map();
|
|
9720
9763
|
for (const file of files) {
|
|
9721
9764
|
const content = fs17.readFileSync(file, "utf8");
|
|
9722
|
-
fileMetrics.set(file, {
|
|
9765
|
+
fileMetrics.set(file, {
|
|
9766
|
+
sloc: countSloc(content),
|
|
9767
|
+
functions: [],
|
|
9768
|
+
override: parseMaintainabilityOverride(content)
|
|
9769
|
+
});
|
|
9723
9770
|
}
|
|
9724
9771
|
forEachFunction(files, (file, _name, node) => {
|
|
9725
9772
|
const metrics = fileMetrics.get(file);
|
|
@@ -9736,17 +9783,26 @@ function collectFileMetrics(files) {
|
|
|
9736
9783
|
});
|
|
9737
9784
|
return fileMetrics;
|
|
9738
9785
|
}
|
|
9786
|
+
|
|
9787
|
+
// src/commands/complexity/maintainability/aggregateResults.ts
|
|
9739
9788
|
function aggregateResults(fileMetrics) {
|
|
9740
9789
|
const results = [];
|
|
9741
9790
|
for (const [file, metrics] of fileMetrics) {
|
|
9742
9791
|
if (metrics.functions.length === 0) continue;
|
|
9743
9792
|
const avgMaintainability = metrics.functions.reduce((a, b) => a + b, 0) / metrics.functions.length;
|
|
9744
9793
|
const minMaintainability = Math.min(...metrics.functions);
|
|
9745
|
-
results.push({
|
|
9794
|
+
results.push({
|
|
9795
|
+
file,
|
|
9796
|
+
avgMaintainability,
|
|
9797
|
+
minMaintainability,
|
|
9798
|
+
override: metrics.override
|
|
9799
|
+
});
|
|
9746
9800
|
}
|
|
9747
9801
|
results.sort((a, b) => a.minMaintainability - b.minMaintainability);
|
|
9748
9802
|
return results;
|
|
9749
9803
|
}
|
|
9804
|
+
|
|
9805
|
+
// src/commands/complexity/maintainability/index.ts
|
|
9750
9806
|
async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
9751
9807
|
printMaintainabilityFormula();
|
|
9752
9808
|
withSourceFiles(
|
|
@@ -9762,7 +9818,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9762
9818
|
|
|
9763
9819
|
// src/commands/complexity/sloc.ts
|
|
9764
9820
|
import fs18 from "fs";
|
|
9765
|
-
import
|
|
9821
|
+
import chalk99 from "chalk";
|
|
9766
9822
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
9767
9823
|
withSourceFiles(pattern2, (files) => {
|
|
9768
9824
|
const results = [];
|
|
@@ -9778,12 +9834,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9778
9834
|
results.sort((a, b) => b.lines - a.lines);
|
|
9779
9835
|
for (const { file, lines } of results) {
|
|
9780
9836
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
9781
|
-
const color = exceedsThreshold ?
|
|
9782
|
-
console.log(`${color(file)} \u2192 ${
|
|
9837
|
+
const color = exceedsThreshold ? chalk99.red : chalk99.white;
|
|
9838
|
+
console.log(`${color(file)} \u2192 ${chalk99.cyan(lines)} lines`);
|
|
9783
9839
|
}
|
|
9784
9840
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
9785
9841
|
console.log(
|
|
9786
|
-
|
|
9842
|
+
chalk99.dim(`
|
|
9787
9843
|
Total: ${total} lines across ${files.length} files`)
|
|
9788
9844
|
);
|
|
9789
9845
|
if (hasViolation) {
|
|
@@ -9797,25 +9853,25 @@ async function analyze(pattern2) {
|
|
|
9797
9853
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
9798
9854
|
const files = findSourceFiles2(searchPattern);
|
|
9799
9855
|
if (files.length === 0) {
|
|
9800
|
-
console.log(
|
|
9856
|
+
console.log(chalk100.yellow("No files found matching pattern"));
|
|
9801
9857
|
return;
|
|
9802
9858
|
}
|
|
9803
9859
|
if (files.length === 1) {
|
|
9804
9860
|
const file = files[0];
|
|
9805
|
-
console.log(
|
|
9861
|
+
console.log(chalk100.bold.underline("SLOC"));
|
|
9806
9862
|
await sloc(file);
|
|
9807
9863
|
console.log();
|
|
9808
|
-
console.log(
|
|
9864
|
+
console.log(chalk100.bold.underline("Cyclomatic Complexity"));
|
|
9809
9865
|
await cyclomatic(file);
|
|
9810
9866
|
console.log();
|
|
9811
|
-
console.log(
|
|
9867
|
+
console.log(chalk100.bold.underline("Halstead Metrics"));
|
|
9812
9868
|
await halstead(file);
|
|
9813
9869
|
console.log();
|
|
9814
|
-
console.log(
|
|
9870
|
+
console.log(chalk100.bold.underline("Maintainability Index"));
|
|
9815
9871
|
await maintainability(file);
|
|
9816
9872
|
console.log();
|
|
9817
9873
|
console.log(
|
|
9818
|
-
|
|
9874
|
+
chalk100.dim(
|
|
9819
9875
|
"To improve the maintainability index, extract functions and logic out of this file into separate, smaller modules. Collapsing whitespace or removing comments is not the goal."
|
|
9820
9876
|
)
|
|
9821
9877
|
);
|
|
@@ -9849,7 +9905,7 @@ function registerComplexity(program2) {
|
|
|
9849
9905
|
}
|
|
9850
9906
|
|
|
9851
9907
|
// src/commands/config/index.ts
|
|
9852
|
-
import
|
|
9908
|
+
import chalk101 from "chalk";
|
|
9853
9909
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
9854
9910
|
|
|
9855
9911
|
// src/commands/config/setNestedValue.ts
|
|
@@ -9912,7 +9968,7 @@ function formatIssuePath(issue, key) {
|
|
|
9912
9968
|
function printValidationErrors(issues, key) {
|
|
9913
9969
|
for (const issue of issues) {
|
|
9914
9970
|
console.error(
|
|
9915
|
-
|
|
9971
|
+
chalk101.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
9916
9972
|
);
|
|
9917
9973
|
}
|
|
9918
9974
|
}
|
|
@@ -9929,7 +9985,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
9929
9985
|
function assertNotGlobalOnly(key, global) {
|
|
9930
9986
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
9931
9987
|
console.error(
|
|
9932
|
-
|
|
9988
|
+
chalk101.red(
|
|
9933
9989
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
9934
9990
|
)
|
|
9935
9991
|
);
|
|
@@ -9952,7 +10008,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
9952
10008
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
9953
10009
|
const target = options2.global ? "global" : "project";
|
|
9954
10010
|
console.log(
|
|
9955
|
-
|
|
10011
|
+
chalk101.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
9956
10012
|
);
|
|
9957
10013
|
}
|
|
9958
10014
|
function configList() {
|
|
@@ -9961,7 +10017,7 @@ function configList() {
|
|
|
9961
10017
|
}
|
|
9962
10018
|
|
|
9963
10019
|
// src/commands/config/configGet.ts
|
|
9964
|
-
import
|
|
10020
|
+
import chalk102 from "chalk";
|
|
9965
10021
|
|
|
9966
10022
|
// src/commands/config/getNestedValue.ts
|
|
9967
10023
|
function isTraversable(value) {
|
|
@@ -9993,7 +10049,7 @@ function requireNestedValue(config, key) {
|
|
|
9993
10049
|
return value;
|
|
9994
10050
|
}
|
|
9995
10051
|
function exitKeyNotSet(key) {
|
|
9996
|
-
console.error(
|
|
10052
|
+
console.error(chalk102.red(`Key "${key}" is not set`));
|
|
9997
10053
|
process.exit(1);
|
|
9998
10054
|
}
|
|
9999
10055
|
|
|
@@ -10007,7 +10063,7 @@ function registerConfig(program2) {
|
|
|
10007
10063
|
|
|
10008
10064
|
// src/commands/deploy/redirect.ts
|
|
10009
10065
|
import { existsSync as existsSync27, readFileSync as readFileSync22, writeFileSync as writeFileSync22 } from "fs";
|
|
10010
|
-
import
|
|
10066
|
+
import chalk103 from "chalk";
|
|
10011
10067
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
10012
10068
|
if (!window.location.pathname.endsWith('/')) {
|
|
10013
10069
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -10016,23 +10072,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
10016
10072
|
function redirect() {
|
|
10017
10073
|
const indexPath = "index.html";
|
|
10018
10074
|
if (!existsSync27(indexPath)) {
|
|
10019
|
-
console.log(
|
|
10075
|
+
console.log(chalk103.yellow("No index.html found"));
|
|
10020
10076
|
return;
|
|
10021
10077
|
}
|
|
10022
10078
|
const content = readFileSync22(indexPath, "utf8");
|
|
10023
10079
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
10024
|
-
console.log(
|
|
10080
|
+
console.log(chalk103.dim("Trailing slash script already present"));
|
|
10025
10081
|
return;
|
|
10026
10082
|
}
|
|
10027
10083
|
const headCloseIndex = content.indexOf("</head>");
|
|
10028
10084
|
if (headCloseIndex === -1) {
|
|
10029
|
-
console.log(
|
|
10085
|
+
console.log(chalk103.red("Could not find </head> tag in index.html"));
|
|
10030
10086
|
return;
|
|
10031
10087
|
}
|
|
10032
10088
|
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
10033
10089
|
${content.slice(headCloseIndex)}`;
|
|
10034
10090
|
writeFileSync22(indexPath, newContent);
|
|
10035
|
-
console.log(
|
|
10091
|
+
console.log(chalk103.green("Added trailing slash redirect to index.html"));
|
|
10036
10092
|
}
|
|
10037
10093
|
|
|
10038
10094
|
// src/commands/registerDeploy.ts
|
|
@@ -10059,7 +10115,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
10059
10115
|
|
|
10060
10116
|
// src/commands/devlog/shared.ts
|
|
10061
10117
|
import { execSync as execSync23 } from "child_process";
|
|
10062
|
-
import
|
|
10118
|
+
import chalk104 from "chalk";
|
|
10063
10119
|
|
|
10064
10120
|
// src/shared/getRepoName.ts
|
|
10065
10121
|
import { existsSync as existsSync28, readFileSync as readFileSync23 } from "fs";
|
|
@@ -10168,13 +10224,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
10168
10224
|
}
|
|
10169
10225
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
10170
10226
|
for (const commit2 of commits2) {
|
|
10171
|
-
console.log(` ${
|
|
10227
|
+
console.log(` ${chalk104.yellow(commit2.hash)} ${commit2.message}`);
|
|
10172
10228
|
if (verbose) {
|
|
10173
10229
|
const visibleFiles = commit2.files.filter(
|
|
10174
10230
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
10175
10231
|
);
|
|
10176
10232
|
for (const file of visibleFiles) {
|
|
10177
|
-
console.log(` ${
|
|
10233
|
+
console.log(` ${chalk104.dim(file)}`);
|
|
10178
10234
|
}
|
|
10179
10235
|
}
|
|
10180
10236
|
}
|
|
@@ -10199,15 +10255,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
10199
10255
|
}
|
|
10200
10256
|
|
|
10201
10257
|
// src/commands/devlog/list/printDateHeader.ts
|
|
10202
|
-
import
|
|
10258
|
+
import chalk105 from "chalk";
|
|
10203
10259
|
function printDateHeader(date, isSkipped, entries) {
|
|
10204
10260
|
if (isSkipped) {
|
|
10205
|
-
console.log(`${
|
|
10261
|
+
console.log(`${chalk105.bold.blue(date)} ${chalk105.dim("skipped")}`);
|
|
10206
10262
|
} else if (entries && entries.length > 0) {
|
|
10207
|
-
const entryInfo = entries.map((e) => `${
|
|
10208
|
-
console.log(`${
|
|
10263
|
+
const entryInfo = entries.map((e) => `${chalk105.green(e.version)} ${e.title}`).join(" | ");
|
|
10264
|
+
console.log(`${chalk105.bold.blue(date)} ${entryInfo}`);
|
|
10209
10265
|
} else {
|
|
10210
|
-
console.log(`${
|
|
10266
|
+
console.log(`${chalk105.bold.blue(date)} ${chalk105.red("\u26A0 devlog missing")}`);
|
|
10211
10267
|
}
|
|
10212
10268
|
}
|
|
10213
10269
|
|
|
@@ -10311,24 +10367,24 @@ function bumpVersion(version2, type) {
|
|
|
10311
10367
|
|
|
10312
10368
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
10313
10369
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
10314
|
-
import
|
|
10370
|
+
import chalk107 from "chalk";
|
|
10315
10371
|
|
|
10316
10372
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
10317
|
-
import
|
|
10373
|
+
import chalk106 from "chalk";
|
|
10318
10374
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
10319
10375
|
if (conventional && firstHash) {
|
|
10320
10376
|
const version2 = getVersionAtCommit(firstHash);
|
|
10321
10377
|
if (version2) {
|
|
10322
|
-
console.log(`${
|
|
10378
|
+
console.log(`${chalk106.bold("version:")} ${stripToMinor(version2)}`);
|
|
10323
10379
|
} else {
|
|
10324
|
-
console.log(`${
|
|
10380
|
+
console.log(`${chalk106.bold("version:")} ${chalk106.red("unknown")}`);
|
|
10325
10381
|
}
|
|
10326
10382
|
} else if (patchVersion && minorVersion) {
|
|
10327
10383
|
console.log(
|
|
10328
|
-
`${
|
|
10384
|
+
`${chalk106.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
10329
10385
|
);
|
|
10330
10386
|
} else {
|
|
10331
|
-
console.log(`${
|
|
10387
|
+
console.log(`${chalk106.bold("version:")} v0.1 (initial)`);
|
|
10332
10388
|
}
|
|
10333
10389
|
}
|
|
10334
10390
|
|
|
@@ -10376,16 +10432,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
10376
10432
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
10377
10433
|
}
|
|
10378
10434
|
function logName(repoName) {
|
|
10379
|
-
console.log(`${
|
|
10435
|
+
console.log(`${chalk107.bold("name:")} ${repoName}`);
|
|
10380
10436
|
}
|
|
10381
10437
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
10382
10438
|
logName(ctx.repoName);
|
|
10383
10439
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
10384
|
-
console.log(
|
|
10440
|
+
console.log(chalk107.bold.blue(targetDate));
|
|
10385
10441
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
10386
10442
|
}
|
|
10387
10443
|
function logNoCommits(lastInfo) {
|
|
10388
|
-
console.log(
|
|
10444
|
+
console.log(chalk107.dim(noCommitsMessage(!!lastInfo)));
|
|
10389
10445
|
}
|
|
10390
10446
|
|
|
10391
10447
|
// src/commands/devlog/next/index.ts
|
|
@@ -10426,11 +10482,11 @@ function next2(options2) {
|
|
|
10426
10482
|
import { execSync as execSync25 } from "child_process";
|
|
10427
10483
|
|
|
10428
10484
|
// src/commands/devlog/repos/printReposTable.ts
|
|
10429
|
-
import
|
|
10485
|
+
import chalk108 from "chalk";
|
|
10430
10486
|
function colorStatus(status2) {
|
|
10431
|
-
if (status2 === "missing") return
|
|
10432
|
-
if (status2 === "outdated") return
|
|
10433
|
-
return
|
|
10487
|
+
if (status2 === "missing") return chalk108.red(status2);
|
|
10488
|
+
if (status2 === "outdated") return chalk108.yellow(status2);
|
|
10489
|
+
return chalk108.green(status2);
|
|
10434
10490
|
}
|
|
10435
10491
|
function formatRow(row, nameWidth) {
|
|
10436
10492
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -10444,8 +10500,8 @@ function printReposTable(rows) {
|
|
|
10444
10500
|
"Last Devlog".padEnd(11),
|
|
10445
10501
|
"Status"
|
|
10446
10502
|
].join(" ");
|
|
10447
|
-
console.log(
|
|
10448
|
-
console.log(
|
|
10503
|
+
console.log(chalk108.dim(header));
|
|
10504
|
+
console.log(chalk108.dim("-".repeat(header.length)));
|
|
10449
10505
|
for (const row of rows) {
|
|
10450
10506
|
console.log(formatRow(row, nameWidth));
|
|
10451
10507
|
}
|
|
@@ -10503,14 +10559,14 @@ function repos(options2) {
|
|
|
10503
10559
|
// src/commands/devlog/skip.ts
|
|
10504
10560
|
import { writeFileSync as writeFileSync23 } from "fs";
|
|
10505
10561
|
import { join as join28 } from "path";
|
|
10506
|
-
import
|
|
10562
|
+
import chalk109 from "chalk";
|
|
10507
10563
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
10508
10564
|
function getBlogConfigPath() {
|
|
10509
10565
|
return join28(BLOG_REPO_ROOT, "assist.yml");
|
|
10510
10566
|
}
|
|
10511
10567
|
function skip(date) {
|
|
10512
10568
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
10513
|
-
console.log(
|
|
10569
|
+
console.log(chalk109.red("Invalid date format. Use YYYY-MM-DD"));
|
|
10514
10570
|
process.exit(1);
|
|
10515
10571
|
}
|
|
10516
10572
|
const repoName = getRepoName();
|
|
@@ -10521,7 +10577,7 @@ function skip(date) {
|
|
|
10521
10577
|
const skipDays = skip2[repoName] ?? [];
|
|
10522
10578
|
if (skipDays.includes(date)) {
|
|
10523
10579
|
console.log(
|
|
10524
|
-
|
|
10580
|
+
chalk109.yellow(`${date} is already in skip list for ${repoName}`)
|
|
10525
10581
|
);
|
|
10526
10582
|
return;
|
|
10527
10583
|
}
|
|
@@ -10531,20 +10587,20 @@ function skip(date) {
|
|
|
10531
10587
|
devlog.skip = skip2;
|
|
10532
10588
|
config.devlog = devlog;
|
|
10533
10589
|
writeFileSync23(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
10534
|
-
console.log(
|
|
10590
|
+
console.log(chalk109.green(`Added ${date} to skip list for ${repoName}`));
|
|
10535
10591
|
}
|
|
10536
10592
|
|
|
10537
10593
|
// src/commands/devlog/version.ts
|
|
10538
|
-
import
|
|
10594
|
+
import chalk110 from "chalk";
|
|
10539
10595
|
function version() {
|
|
10540
10596
|
const config = loadConfig();
|
|
10541
10597
|
const name = getRepoName();
|
|
10542
10598
|
const lastInfo = getLastVersionInfo(name, config);
|
|
10543
10599
|
const lastVersion = lastInfo?.version ?? null;
|
|
10544
10600
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
10545
|
-
console.log(`${
|
|
10546
|
-
console.log(`${
|
|
10547
|
-
console.log(`${
|
|
10601
|
+
console.log(`${chalk110.bold("name:")} ${name}`);
|
|
10602
|
+
console.log(`${chalk110.bold("last:")} ${lastVersion ?? chalk110.dim("none")}`);
|
|
10603
|
+
console.log(`${chalk110.bold("next:")} ${nextVersion ?? chalk110.dim("none")}`);
|
|
10548
10604
|
}
|
|
10549
10605
|
|
|
10550
10606
|
// src/commands/registerDevlog.ts
|
|
@@ -10568,7 +10624,7 @@ function registerDevlog(program2) {
|
|
|
10568
10624
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
10569
10625
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync2 } from "fs";
|
|
10570
10626
|
import { join as join29 } from "path";
|
|
10571
|
-
import
|
|
10627
|
+
import chalk111 from "chalk";
|
|
10572
10628
|
|
|
10573
10629
|
// src/shared/findRepoRoot.ts
|
|
10574
10630
|
import { existsSync as existsSync29 } from "fs";
|
|
@@ -10631,14 +10687,14 @@ function checkBuildLocks(startDir) {
|
|
|
10631
10687
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
10632
10688
|
if (locked) {
|
|
10633
10689
|
console.error(
|
|
10634
|
-
|
|
10690
|
+
chalk111.red("Build output locked (is VS debugging?): ") + locked
|
|
10635
10691
|
);
|
|
10636
10692
|
process.exit(1);
|
|
10637
10693
|
}
|
|
10638
10694
|
}
|
|
10639
10695
|
async function checkBuildLocksCommand() {
|
|
10640
10696
|
checkBuildLocks();
|
|
10641
|
-
console.log(
|
|
10697
|
+
console.log(chalk111.green("No build locks detected"));
|
|
10642
10698
|
}
|
|
10643
10699
|
|
|
10644
10700
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -10737,30 +10793,30 @@ function escapeRegex(s) {
|
|
|
10737
10793
|
}
|
|
10738
10794
|
|
|
10739
10795
|
// src/commands/dotnet/printTree.ts
|
|
10740
|
-
import
|
|
10796
|
+
import chalk112 from "chalk";
|
|
10741
10797
|
function printNodes(nodes, prefix2) {
|
|
10742
10798
|
for (let i = 0; i < nodes.length; i++) {
|
|
10743
10799
|
const isLast = i === nodes.length - 1;
|
|
10744
10800
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
10745
10801
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
10746
10802
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
10747
|
-
const label2 = isMissing ?
|
|
10803
|
+
const label2 = isMissing ? chalk112.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
10748
10804
|
console.log(`${prefix2}${connector}${label2}`);
|
|
10749
10805
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
10750
10806
|
}
|
|
10751
10807
|
}
|
|
10752
10808
|
function printTree(tree, totalCount, solutions) {
|
|
10753
|
-
console.log(
|
|
10754
|
-
console.log(
|
|
10809
|
+
console.log(chalk112.bold("\nProject Dependency Tree"));
|
|
10810
|
+
console.log(chalk112.cyan(tree.relativePath));
|
|
10755
10811
|
printNodes(tree.children, "");
|
|
10756
|
-
console.log(
|
|
10812
|
+
console.log(chalk112.dim(`
|
|
10757
10813
|
${totalCount} projects total (including root)`));
|
|
10758
|
-
console.log(
|
|
10814
|
+
console.log(chalk112.bold("\nSolution Membership"));
|
|
10759
10815
|
if (solutions.length === 0) {
|
|
10760
|
-
console.log(
|
|
10816
|
+
console.log(chalk112.yellow(" Not found in any .sln"));
|
|
10761
10817
|
} else {
|
|
10762
10818
|
for (const sln of solutions) {
|
|
10763
|
-
console.log(` ${
|
|
10819
|
+
console.log(` ${chalk112.green(sln)}`);
|
|
10764
10820
|
}
|
|
10765
10821
|
}
|
|
10766
10822
|
console.log();
|
|
@@ -10789,16 +10845,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
10789
10845
|
// src/commands/dotnet/resolveCsproj.ts
|
|
10790
10846
|
import { existsSync as existsSync30 } from "fs";
|
|
10791
10847
|
import path25 from "path";
|
|
10792
|
-
import
|
|
10848
|
+
import chalk113 from "chalk";
|
|
10793
10849
|
function resolveCsproj(csprojPath) {
|
|
10794
10850
|
const resolved = path25.resolve(csprojPath);
|
|
10795
10851
|
if (!existsSync30(resolved)) {
|
|
10796
|
-
console.error(
|
|
10852
|
+
console.error(chalk113.red(`File not found: ${resolved}`));
|
|
10797
10853
|
process.exit(1);
|
|
10798
10854
|
}
|
|
10799
10855
|
const repoRoot = findRepoRoot(path25.dirname(resolved));
|
|
10800
10856
|
if (!repoRoot) {
|
|
10801
|
-
console.error(
|
|
10857
|
+
console.error(chalk113.red("Could not find git repository root"));
|
|
10802
10858
|
process.exit(1);
|
|
10803
10859
|
}
|
|
10804
10860
|
return { resolved, repoRoot };
|
|
@@ -10848,12 +10904,12 @@ function getChangedCsFiles(scope) {
|
|
|
10848
10904
|
}
|
|
10849
10905
|
|
|
10850
10906
|
// src/commands/dotnet/inSln.ts
|
|
10851
|
-
import
|
|
10907
|
+
import chalk114 from "chalk";
|
|
10852
10908
|
async function inSln(csprojPath) {
|
|
10853
10909
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
10854
10910
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
10855
10911
|
if (solutions.length === 0) {
|
|
10856
|
-
console.log(
|
|
10912
|
+
console.log(chalk114.yellow("Not found in any .sln file"));
|
|
10857
10913
|
process.exit(1);
|
|
10858
10914
|
}
|
|
10859
10915
|
for (const sln of solutions) {
|
|
@@ -10862,7 +10918,7 @@ async function inSln(csprojPath) {
|
|
|
10862
10918
|
}
|
|
10863
10919
|
|
|
10864
10920
|
// src/commands/dotnet/inspect.ts
|
|
10865
|
-
import
|
|
10921
|
+
import chalk120 from "chalk";
|
|
10866
10922
|
|
|
10867
10923
|
// src/shared/formatElapsed.ts
|
|
10868
10924
|
function formatElapsed(ms) {
|
|
@@ -10874,12 +10930,12 @@ function formatElapsed(ms) {
|
|
|
10874
10930
|
}
|
|
10875
10931
|
|
|
10876
10932
|
// src/commands/dotnet/displayIssues.ts
|
|
10877
|
-
import
|
|
10933
|
+
import chalk115 from "chalk";
|
|
10878
10934
|
var SEVERITY_COLOR = {
|
|
10879
|
-
ERROR:
|
|
10880
|
-
WARNING:
|
|
10881
|
-
SUGGESTION:
|
|
10882
|
-
HINT:
|
|
10935
|
+
ERROR: chalk115.red,
|
|
10936
|
+
WARNING: chalk115.yellow,
|
|
10937
|
+
SUGGESTION: chalk115.cyan,
|
|
10938
|
+
HINT: chalk115.dim
|
|
10883
10939
|
};
|
|
10884
10940
|
function groupByFile(issues) {
|
|
10885
10941
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -10895,15 +10951,15 @@ function groupByFile(issues) {
|
|
|
10895
10951
|
}
|
|
10896
10952
|
function displayIssues(issues) {
|
|
10897
10953
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
10898
|
-
console.log(
|
|
10954
|
+
console.log(chalk115.bold(file));
|
|
10899
10955
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
10900
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
10956
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk115.white;
|
|
10901
10957
|
console.log(
|
|
10902
|
-
` ${
|
|
10958
|
+
` ${chalk115.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
10903
10959
|
);
|
|
10904
10960
|
}
|
|
10905
10961
|
}
|
|
10906
|
-
console.log(
|
|
10962
|
+
console.log(chalk115.dim(`
|
|
10907
10963
|
${issues.length} issue(s) found`));
|
|
10908
10964
|
}
|
|
10909
10965
|
|
|
@@ -10962,12 +11018,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
10962
11018
|
// src/commands/dotnet/resolveSolution.ts
|
|
10963
11019
|
import { existsSync as existsSync31 } from "fs";
|
|
10964
11020
|
import path26 from "path";
|
|
10965
|
-
import
|
|
11021
|
+
import chalk117 from "chalk";
|
|
10966
11022
|
|
|
10967
11023
|
// src/commands/dotnet/findSolution.ts
|
|
10968
11024
|
import { readdirSync as readdirSync4 } from "fs";
|
|
10969
11025
|
import { dirname as dirname18, join as join30 } from "path";
|
|
10970
|
-
import
|
|
11026
|
+
import chalk116 from "chalk";
|
|
10971
11027
|
function findSlnInDir(dir) {
|
|
10972
11028
|
try {
|
|
10973
11029
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join30(dir, f));
|
|
@@ -10983,17 +11039,17 @@ function findSolution() {
|
|
|
10983
11039
|
const slnFiles = findSlnInDir(current);
|
|
10984
11040
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
10985
11041
|
if (slnFiles.length > 1) {
|
|
10986
|
-
console.error(
|
|
11042
|
+
console.error(chalk116.red(`Multiple .sln files found in ${current}:`));
|
|
10987
11043
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
10988
11044
|
console.error(
|
|
10989
|
-
|
|
11045
|
+
chalk116.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
10990
11046
|
);
|
|
10991
11047
|
process.exit(1);
|
|
10992
11048
|
}
|
|
10993
11049
|
if (current === ceiling) break;
|
|
10994
11050
|
current = dirname18(current);
|
|
10995
11051
|
}
|
|
10996
|
-
console.error(
|
|
11052
|
+
console.error(chalk116.red("No .sln file found between cwd and repo root"));
|
|
10997
11053
|
process.exit(1);
|
|
10998
11054
|
}
|
|
10999
11055
|
|
|
@@ -11002,7 +11058,7 @@ function resolveSolution(sln) {
|
|
|
11002
11058
|
if (sln) {
|
|
11003
11059
|
const resolved = path26.resolve(sln);
|
|
11004
11060
|
if (!existsSync31(resolved)) {
|
|
11005
|
-
console.error(
|
|
11061
|
+
console.error(chalk117.red(`Solution file not found: ${resolved}`));
|
|
11006
11062
|
process.exit(1);
|
|
11007
11063
|
}
|
|
11008
11064
|
return resolved;
|
|
@@ -11044,14 +11100,14 @@ import { execSync as execSync27 } from "child_process";
|
|
|
11044
11100
|
import { existsSync as existsSync32, readFileSync as readFileSync27, unlinkSync as unlinkSync7 } from "fs";
|
|
11045
11101
|
import { tmpdir as tmpdir3 } from "os";
|
|
11046
11102
|
import path27 from "path";
|
|
11047
|
-
import
|
|
11103
|
+
import chalk118 from "chalk";
|
|
11048
11104
|
function assertJbInstalled() {
|
|
11049
11105
|
try {
|
|
11050
11106
|
execSync27("jb inspectcode --version", { stdio: "pipe" });
|
|
11051
11107
|
} catch {
|
|
11052
|
-
console.error(
|
|
11108
|
+
console.error(chalk118.red("jb is not installed. Install with:"));
|
|
11053
11109
|
console.error(
|
|
11054
|
-
|
|
11110
|
+
chalk118.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
11055
11111
|
);
|
|
11056
11112
|
process.exit(1);
|
|
11057
11113
|
}
|
|
@@ -11069,11 +11125,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11069
11125
|
if (error && typeof error === "object" && "stderr" in error) {
|
|
11070
11126
|
process.stderr.write(error.stderr);
|
|
11071
11127
|
}
|
|
11072
|
-
console.error(
|
|
11128
|
+
console.error(chalk118.red("jb inspectcode failed"));
|
|
11073
11129
|
process.exit(1);
|
|
11074
11130
|
}
|
|
11075
11131
|
if (!existsSync32(reportPath)) {
|
|
11076
|
-
console.error(
|
|
11132
|
+
console.error(chalk118.red("Report file not generated"));
|
|
11077
11133
|
process.exit(1);
|
|
11078
11134
|
}
|
|
11079
11135
|
const xml = readFileSync27(reportPath, "utf8");
|
|
@@ -11083,7 +11139,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11083
11139
|
|
|
11084
11140
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
11085
11141
|
import { execSync as execSync28 } from "child_process";
|
|
11086
|
-
import
|
|
11142
|
+
import chalk119 from "chalk";
|
|
11087
11143
|
function resolveMsbuildPath() {
|
|
11088
11144
|
const { run: run4 } = loadConfig();
|
|
11089
11145
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -11095,9 +11151,9 @@ function assertMsbuildInstalled() {
|
|
|
11095
11151
|
try {
|
|
11096
11152
|
execSync28(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
11097
11153
|
} catch {
|
|
11098
|
-
console.error(
|
|
11154
|
+
console.error(chalk119.red(`msbuild not found at: ${msbuild}`));
|
|
11099
11155
|
console.error(
|
|
11100
|
-
|
|
11156
|
+
chalk119.yellow(
|
|
11101
11157
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
11102
11158
|
)
|
|
11103
11159
|
);
|
|
@@ -11144,17 +11200,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
11144
11200
|
// src/commands/dotnet/inspect.ts
|
|
11145
11201
|
function logScope(changedFiles) {
|
|
11146
11202
|
if (changedFiles === null) {
|
|
11147
|
-
console.log(
|
|
11203
|
+
console.log(chalk120.dim("Inspecting full solution..."));
|
|
11148
11204
|
} else {
|
|
11149
11205
|
console.log(
|
|
11150
|
-
|
|
11206
|
+
chalk120.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
11151
11207
|
);
|
|
11152
11208
|
}
|
|
11153
11209
|
}
|
|
11154
11210
|
function reportResults(issues, elapsed) {
|
|
11155
11211
|
if (issues.length > 0) displayIssues(issues);
|
|
11156
|
-
else console.log(
|
|
11157
|
-
console.log(
|
|
11212
|
+
else console.log(chalk120.green("No issues found"));
|
|
11213
|
+
console.log(chalk120.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
11158
11214
|
if (issues.length > 0) process.exit(1);
|
|
11159
11215
|
}
|
|
11160
11216
|
async function inspect(sln, options2) {
|
|
@@ -11165,7 +11221,7 @@ async function inspect(sln, options2) {
|
|
|
11165
11221
|
const scope = parseScope(options2.scope);
|
|
11166
11222
|
const changedFiles = getChangedCsFiles(scope);
|
|
11167
11223
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
11168
|
-
console.log(
|
|
11224
|
+
console.log(chalk120.green("No changed .cs files found"));
|
|
11169
11225
|
return;
|
|
11170
11226
|
}
|
|
11171
11227
|
logScope(changedFiles);
|
|
@@ -11190,6 +11246,84 @@ function registerDotnet(program2) {
|
|
|
11190
11246
|
cmd.command("in-sln").description("Check whether a .csproj is referenced by any .sln file").argument("<csproj>", "Path to a .csproj file").action(inSln);
|
|
11191
11247
|
}
|
|
11192
11248
|
|
|
11249
|
+
// src/commands/editHook/index.ts
|
|
11250
|
+
import fs19 from "fs";
|
|
11251
|
+
|
|
11252
|
+
// src/commands/editHook/decideOverrideGuard.ts
|
|
11253
|
+
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.`;
|
|
11254
|
+
function candidateStrings(input, existingContent) {
|
|
11255
|
+
const { tool_name, tool_input } = input;
|
|
11256
|
+
switch (tool_name) {
|
|
11257
|
+
case "Edit":
|
|
11258
|
+
return [tool_input.old_string, tool_input.new_string].filter(
|
|
11259
|
+
(s) => s !== void 0
|
|
11260
|
+
);
|
|
11261
|
+
case "MultiEdit":
|
|
11262
|
+
return (tool_input.edits ?? []).flatMap(
|
|
11263
|
+
(e) => [e.old_string, e.new_string].filter(
|
|
11264
|
+
(s) => s !== void 0
|
|
11265
|
+
)
|
|
11266
|
+
);
|
|
11267
|
+
case "Write":
|
|
11268
|
+
return [tool_input.content, existingContent].filter(
|
|
11269
|
+
(s) => s !== void 0
|
|
11270
|
+
);
|
|
11271
|
+
default:
|
|
11272
|
+
return [];
|
|
11273
|
+
}
|
|
11274
|
+
}
|
|
11275
|
+
function decideOverrideGuard(input, existingContent) {
|
|
11276
|
+
const touchesMarker = candidateStrings(input, existingContent).some(
|
|
11277
|
+
(s) => s.includes(MAINTAINABILITY_OVERRIDE_MARKER)
|
|
11278
|
+
);
|
|
11279
|
+
return touchesMarker ? DENY_REASON : void 0;
|
|
11280
|
+
}
|
|
11281
|
+
|
|
11282
|
+
// src/commands/editHook/index.ts
|
|
11283
|
+
function tryParseInput2(raw) {
|
|
11284
|
+
try {
|
|
11285
|
+
const data = JSON.parse(raw);
|
|
11286
|
+
if (typeof data.tool_name !== "string" || !data.tool_input)
|
|
11287
|
+
return void 0;
|
|
11288
|
+
return data;
|
|
11289
|
+
} catch {
|
|
11290
|
+
return void 0;
|
|
11291
|
+
}
|
|
11292
|
+
}
|
|
11293
|
+
function readExisting(filePath) {
|
|
11294
|
+
if (!filePath) return void 0;
|
|
11295
|
+
try {
|
|
11296
|
+
return fs19.readFileSync(filePath, "utf8");
|
|
11297
|
+
} catch {
|
|
11298
|
+
return void 0;
|
|
11299
|
+
}
|
|
11300
|
+
}
|
|
11301
|
+
async function editHook() {
|
|
11302
|
+
const input = tryParseInput2(await readStdin());
|
|
11303
|
+
if (!input) return;
|
|
11304
|
+
const existing = input.tool_name === "Write" ? readExisting(input.tool_input.file_path) : void 0;
|
|
11305
|
+
const reason = decideOverrideGuard(input, existing);
|
|
11306
|
+
if (!reason) return;
|
|
11307
|
+
console.log(
|
|
11308
|
+
JSON.stringify({
|
|
11309
|
+
hookSpecificOutput: {
|
|
11310
|
+
hookEventName: "PreToolUse",
|
|
11311
|
+
permissionDecision: "deny",
|
|
11312
|
+
permissionDecisionReason: reason
|
|
11313
|
+
}
|
|
11314
|
+
})
|
|
11315
|
+
);
|
|
11316
|
+
}
|
|
11317
|
+
|
|
11318
|
+
// src/commands/registerEditHook.ts
|
|
11319
|
+
function registerEditHook(program2) {
|
|
11320
|
+
program2.command("edit-hook").description(
|
|
11321
|
+
"PreToolUse hook that blocks edits to the maintainability override marker"
|
|
11322
|
+
).action(() => {
|
|
11323
|
+
editHook();
|
|
11324
|
+
});
|
|
11325
|
+
}
|
|
11326
|
+
|
|
11193
11327
|
// src/commands/github/aggregateCommitters.ts
|
|
11194
11328
|
function aggregateCommitters(authorLists) {
|
|
11195
11329
|
const totals = /* @__PURE__ */ new Map();
|
|
@@ -11294,25 +11428,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
11294
11428
|
}
|
|
11295
11429
|
|
|
11296
11430
|
// src/commands/github/printCountTable.ts
|
|
11297
|
-
import
|
|
11431
|
+
import chalk121 from "chalk";
|
|
11298
11432
|
function printCountTable(labelHeader, rows) {
|
|
11299
11433
|
const labelWidth = Math.max(
|
|
11300
11434
|
labelHeader.length,
|
|
11301
11435
|
...rows.map((row) => row.label.length)
|
|
11302
11436
|
);
|
|
11303
11437
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
11304
|
-
console.log(
|
|
11305
|
-
console.log(
|
|
11438
|
+
console.log(chalk121.dim(header));
|
|
11439
|
+
console.log(chalk121.dim("-".repeat(header.length)));
|
|
11306
11440
|
for (const row of rows) {
|
|
11307
11441
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
11308
11442
|
}
|
|
11309
11443
|
}
|
|
11310
11444
|
|
|
11311
11445
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
11312
|
-
import
|
|
11446
|
+
import chalk122 from "chalk";
|
|
11313
11447
|
function printRepoAuthorBreakdown(repos2) {
|
|
11314
11448
|
for (const repo of repos2) {
|
|
11315
|
-
console.log(
|
|
11449
|
+
console.log(chalk122.bold(repo.name));
|
|
11316
11450
|
const authorWidth = Math.max(
|
|
11317
11451
|
0,
|
|
11318
11452
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -11630,7 +11764,7 @@ function registerHandover(program2) {
|
|
|
11630
11764
|
}
|
|
11631
11765
|
|
|
11632
11766
|
// src/commands/jira/acceptanceCriteria.ts
|
|
11633
|
-
import
|
|
11767
|
+
import chalk124 from "chalk";
|
|
11634
11768
|
|
|
11635
11769
|
// src/commands/jira/adfToText.ts
|
|
11636
11770
|
function renderInline(node) {
|
|
@@ -11691,7 +11825,7 @@ function adfToText(doc) {
|
|
|
11691
11825
|
|
|
11692
11826
|
// src/commands/jira/fetchIssue.ts
|
|
11693
11827
|
import { execSync as execSync29 } from "child_process";
|
|
11694
|
-
import
|
|
11828
|
+
import chalk123 from "chalk";
|
|
11695
11829
|
function fetchIssue(issueKey, fields) {
|
|
11696
11830
|
let result;
|
|
11697
11831
|
try {
|
|
@@ -11704,15 +11838,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
11704
11838
|
const stderr = error.stderr;
|
|
11705
11839
|
if (stderr.includes("unauthorized")) {
|
|
11706
11840
|
console.error(
|
|
11707
|
-
|
|
11841
|
+
chalk123.red("Jira authentication expired."),
|
|
11708
11842
|
"Run",
|
|
11709
|
-
|
|
11843
|
+
chalk123.cyan("assist jira auth"),
|
|
11710
11844
|
"to re-authenticate."
|
|
11711
11845
|
);
|
|
11712
11846
|
process.exit(1);
|
|
11713
11847
|
}
|
|
11714
11848
|
}
|
|
11715
|
-
console.error(
|
|
11849
|
+
console.error(chalk123.red(`Failed to fetch ${issueKey}.`));
|
|
11716
11850
|
process.exit(1);
|
|
11717
11851
|
}
|
|
11718
11852
|
return JSON.parse(result);
|
|
@@ -11726,7 +11860,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
11726
11860
|
const parsed = fetchIssue(issueKey, field);
|
|
11727
11861
|
const acValue = parsed?.fields?.[field];
|
|
11728
11862
|
if (!acValue) {
|
|
11729
|
-
console.log(
|
|
11863
|
+
console.log(chalk124.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
11730
11864
|
return;
|
|
11731
11865
|
}
|
|
11732
11866
|
if (typeof acValue === "string") {
|
|
@@ -11821,14 +11955,14 @@ async function jiraAuth() {
|
|
|
11821
11955
|
}
|
|
11822
11956
|
|
|
11823
11957
|
// src/commands/jira/viewIssue.ts
|
|
11824
|
-
import
|
|
11958
|
+
import chalk125 from "chalk";
|
|
11825
11959
|
function viewIssue(issueKey) {
|
|
11826
11960
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
11827
11961
|
const fields = parsed?.fields;
|
|
11828
11962
|
const summary = fields?.summary;
|
|
11829
11963
|
const description = fields?.description;
|
|
11830
11964
|
if (summary) {
|
|
11831
|
-
console.log(
|
|
11965
|
+
console.log(chalk125.bold(summary));
|
|
11832
11966
|
}
|
|
11833
11967
|
if (description) {
|
|
11834
11968
|
if (summary) console.log();
|
|
@@ -11842,7 +11976,7 @@ function viewIssue(issueKey) {
|
|
|
11842
11976
|
}
|
|
11843
11977
|
if (!summary && !description) {
|
|
11844
11978
|
console.log(
|
|
11845
|
-
|
|
11979
|
+
chalk125.yellow(`No summary or description found on ${issueKey}.`)
|
|
11846
11980
|
);
|
|
11847
11981
|
}
|
|
11848
11982
|
}
|
|
@@ -11858,13 +11992,13 @@ function registerJira(program2) {
|
|
|
11858
11992
|
// src/commands/reviewComments.ts
|
|
11859
11993
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
11860
11994
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
11861
|
-
import
|
|
11995
|
+
import chalk126 from "chalk";
|
|
11862
11996
|
async function reviewComments(number) {
|
|
11863
11997
|
if (number) {
|
|
11864
11998
|
try {
|
|
11865
11999
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
11866
12000
|
} catch {
|
|
11867
|
-
console.error(
|
|
12001
|
+
console.error(chalk126.red(`gh pr checkout ${number} failed; aborting.`));
|
|
11868
12002
|
process.exit(1);
|
|
11869
12003
|
}
|
|
11870
12004
|
}
|
|
@@ -11910,15 +12044,15 @@ function registerList(program2) {
|
|
|
11910
12044
|
// src/commands/mermaid/index.ts
|
|
11911
12045
|
import { mkdirSync as mkdirSync12, readdirSync as readdirSync6 } from "fs";
|
|
11912
12046
|
import { resolve as resolve11 } from "path";
|
|
11913
|
-
import
|
|
12047
|
+
import chalk129 from "chalk";
|
|
11914
12048
|
|
|
11915
12049
|
// src/commands/mermaid/exportFile.ts
|
|
11916
12050
|
import { readFileSync as readFileSync30, writeFileSync as writeFileSync26 } from "fs";
|
|
11917
12051
|
import { basename as basename6, extname, resolve as resolve10 } from "path";
|
|
11918
|
-
import
|
|
12052
|
+
import chalk128 from "chalk";
|
|
11919
12053
|
|
|
11920
12054
|
// src/commands/mermaid/renderBlock.ts
|
|
11921
|
-
import
|
|
12055
|
+
import chalk127 from "chalk";
|
|
11922
12056
|
async function renderBlock(krokiUrl, source) {
|
|
11923
12057
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
11924
12058
|
method: "POST",
|
|
@@ -11927,7 +12061,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
11927
12061
|
});
|
|
11928
12062
|
if (!response.ok) {
|
|
11929
12063
|
console.error(
|
|
11930
|
-
|
|
12064
|
+
chalk127.red(
|
|
11931
12065
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
11932
12066
|
)
|
|
11933
12067
|
);
|
|
@@ -11945,19 +12079,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
11945
12079
|
if (onlyIndex !== void 0) {
|
|
11946
12080
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
11947
12081
|
console.error(
|
|
11948
|
-
|
|
12082
|
+
chalk128.red(
|
|
11949
12083
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
11950
12084
|
)
|
|
11951
12085
|
);
|
|
11952
12086
|
process.exit(1);
|
|
11953
12087
|
}
|
|
11954
12088
|
console.log(
|
|
11955
|
-
|
|
12089
|
+
chalk128.gray(
|
|
11956
12090
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
11957
12091
|
)
|
|
11958
12092
|
);
|
|
11959
12093
|
} else {
|
|
11960
|
-
console.log(
|
|
12094
|
+
console.log(chalk128.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
11961
12095
|
}
|
|
11962
12096
|
for (const [i, source] of blocks.entries()) {
|
|
11963
12097
|
const idx = i + 1;
|
|
@@ -11965,7 +12099,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
11965
12099
|
const outPath = resolve10(outDir, `${stem}-${idx}.svg`);
|
|
11966
12100
|
const svg = await renderBlock(krokiUrl, source);
|
|
11967
12101
|
writeFileSync26(outPath, svg, "utf8");
|
|
11968
|
-
console.log(
|
|
12102
|
+
console.log(chalk128.green(` \u2192 ${outPath}`));
|
|
11969
12103
|
}
|
|
11970
12104
|
}
|
|
11971
12105
|
function extractMermaidBlocks(markdown) {
|
|
@@ -11981,18 +12115,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
11981
12115
|
if (options2.index !== void 0) {
|
|
11982
12116
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
11983
12117
|
console.error(
|
|
11984
|
-
|
|
12118
|
+
chalk129.red(`--index must be a positive integer (got ${options2.index})`)
|
|
11985
12119
|
);
|
|
11986
12120
|
process.exit(1);
|
|
11987
12121
|
}
|
|
11988
12122
|
if (!file) {
|
|
11989
|
-
console.error(
|
|
12123
|
+
console.error(chalk129.red("--index requires a file argument"));
|
|
11990
12124
|
process.exit(1);
|
|
11991
12125
|
}
|
|
11992
12126
|
}
|
|
11993
12127
|
const files = file ? [file] : readdirSync6(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
11994
12128
|
if (files.length === 0) {
|
|
11995
|
-
console.log(
|
|
12129
|
+
console.log(chalk129.gray("No markdown files found in current directory."));
|
|
11996
12130
|
return;
|
|
11997
12131
|
}
|
|
11998
12132
|
for (const f of files) {
|
|
@@ -12018,7 +12152,7 @@ function registerMermaid(program2) {
|
|
|
12018
12152
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
12019
12153
|
import { createServer as createServer2 } from "http";
|
|
12020
12154
|
import { dirname as dirname20 } from "path";
|
|
12021
|
-
import
|
|
12155
|
+
import chalk131 from "chalk";
|
|
12022
12156
|
|
|
12023
12157
|
// src/commands/netcap/corsHeaders.ts
|
|
12024
12158
|
var corsHeaders = {
|
|
@@ -12097,7 +12231,7 @@ function createNetcapHandler(options2) {
|
|
|
12097
12231
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
12098
12232
|
import { networkInterfaces } from "os";
|
|
12099
12233
|
import { join as join37 } from "path";
|
|
12100
|
-
import
|
|
12234
|
+
import chalk130 from "chalk";
|
|
12101
12235
|
|
|
12102
12236
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
12103
12237
|
import { dirname as dirname19, join as join36 } from "path";
|
|
@@ -12141,7 +12275,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12141
12275
|
const host = lanIPv4();
|
|
12142
12276
|
if (!host) {
|
|
12143
12277
|
console.log(
|
|
12144
|
-
|
|
12278
|
+
chalk130.yellow("could not determine the WSL IP for the extension")
|
|
12145
12279
|
);
|
|
12146
12280
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
12147
12281
|
return source;
|
|
@@ -12152,7 +12286,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12152
12286
|
return WSL_WINDOWS_PATH;
|
|
12153
12287
|
} catch {
|
|
12154
12288
|
console.log(
|
|
12155
|
-
|
|
12289
|
+
chalk130.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
12156
12290
|
);
|
|
12157
12291
|
return source;
|
|
12158
12292
|
}
|
|
@@ -12185,30 +12319,30 @@ async function netcap(options2) {
|
|
|
12185
12319
|
let count6 = 0;
|
|
12186
12320
|
const handler = createNetcapHandler({
|
|
12187
12321
|
outPath,
|
|
12188
|
-
onPing: () => console.log(
|
|
12322
|
+
onPing: () => console.log(chalk131.dim("ping from extension")),
|
|
12189
12323
|
onCapture: (entry) => {
|
|
12190
12324
|
count6 += 1;
|
|
12191
12325
|
console.log(
|
|
12192
|
-
|
|
12193
|
-
|
|
12326
|
+
chalk131.green(`captured #${count6}`),
|
|
12327
|
+
chalk131.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
12194
12328
|
);
|
|
12195
12329
|
}
|
|
12196
12330
|
});
|
|
12197
12331
|
const server = createServer2(handler);
|
|
12198
12332
|
server.listen(port, () => {
|
|
12199
12333
|
console.log(
|
|
12200
|
-
|
|
12334
|
+
chalk131.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
12201
12335
|
);
|
|
12202
|
-
console.log(
|
|
12336
|
+
console.log(chalk131.dim(`appending captures to ${outPath}`));
|
|
12203
12337
|
if (filter)
|
|
12204
|
-
console.log(
|
|
12205
|
-
console.log(
|
|
12206
|
-
console.log(
|
|
12338
|
+
console.log(chalk131.dim(`forwarding only URLs matching "${filter}"`));
|
|
12339
|
+
console.log(chalk131.dim(`load the unpacked extension from ${extensionPath}`));
|
|
12340
|
+
console.log(chalk131.dim("press Ctrl-C to stop"));
|
|
12207
12341
|
});
|
|
12208
12342
|
process.on("SIGINT", () => {
|
|
12209
12343
|
server.close();
|
|
12210
12344
|
console.log(
|
|
12211
|
-
|
|
12345
|
+
chalk131.bold(
|
|
12212
12346
|
`
|
|
12213
12347
|
netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
12214
12348
|
)
|
|
@@ -12220,7 +12354,7 @@ netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} t
|
|
|
12220
12354
|
// src/commands/netcap/netcapExtract.ts
|
|
12221
12355
|
import { writeFileSync as writeFileSync27 } from "fs";
|
|
12222
12356
|
import { join as join40 } from "path";
|
|
12223
|
-
import
|
|
12357
|
+
import chalk132 from "chalk";
|
|
12224
12358
|
|
|
12225
12359
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
12226
12360
|
import { readFileSync as readFileSync31 } from "fs";
|
|
@@ -12668,8 +12802,8 @@ function netcapExtract(file) {
|
|
|
12668
12802
|
writeFileSync27(outFile, `${JSON.stringify(posts, null, 2)}
|
|
12669
12803
|
`);
|
|
12670
12804
|
console.log(
|
|
12671
|
-
|
|
12672
|
-
|
|
12805
|
+
chalk132.green(`extracted ${posts.length} posts`),
|
|
12806
|
+
chalk132.dim(`-> ${outFile}`)
|
|
12673
12807
|
);
|
|
12674
12808
|
}
|
|
12675
12809
|
|
|
@@ -12690,7 +12824,7 @@ function registerNetcap(program2) {
|
|
|
12690
12824
|
}
|
|
12691
12825
|
|
|
12692
12826
|
// src/commands/news/add/index.ts
|
|
12693
|
-
import
|
|
12827
|
+
import chalk133 from "chalk";
|
|
12694
12828
|
import enquirer8 from "enquirer";
|
|
12695
12829
|
async function add2(url) {
|
|
12696
12830
|
if (!url) {
|
|
@@ -12712,10 +12846,10 @@ async function add2(url) {
|
|
|
12712
12846
|
const { orm } = await getReady();
|
|
12713
12847
|
const added = await addFeed(orm, url);
|
|
12714
12848
|
if (!added) {
|
|
12715
|
-
console.log(
|
|
12849
|
+
console.log(chalk133.yellow("Feed already exists"));
|
|
12716
12850
|
return;
|
|
12717
12851
|
}
|
|
12718
|
-
console.log(
|
|
12852
|
+
console.log(chalk133.green(`Added feed: ${url}`));
|
|
12719
12853
|
}
|
|
12720
12854
|
|
|
12721
12855
|
// src/commands/registerNews.ts
|
|
@@ -12725,7 +12859,7 @@ function registerNews(program2) {
|
|
|
12725
12859
|
}
|
|
12726
12860
|
|
|
12727
12861
|
// src/commands/prompts/printPromptsTable.ts
|
|
12728
|
-
import
|
|
12862
|
+
import chalk134 from "chalk";
|
|
12729
12863
|
function truncate(str, max) {
|
|
12730
12864
|
if (str.length <= max) return str;
|
|
12731
12865
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -12743,14 +12877,14 @@ function printPromptsTable(rows) {
|
|
|
12743
12877
|
"Command".padEnd(commandWidth),
|
|
12744
12878
|
"Repos"
|
|
12745
12879
|
].join(" ");
|
|
12746
|
-
console.log(
|
|
12747
|
-
console.log(
|
|
12880
|
+
console.log(chalk134.dim(header));
|
|
12881
|
+
console.log(chalk134.dim("-".repeat(header.length)));
|
|
12748
12882
|
for (const row of rows) {
|
|
12749
12883
|
const count6 = String(row.count).padStart(countWidth);
|
|
12750
12884
|
const tool = row.tool.padEnd(toolWidth);
|
|
12751
12885
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
12752
12886
|
console.log(
|
|
12753
|
-
`${
|
|
12887
|
+
`${chalk134.yellow(count6)} ${tool} ${command} ${chalk134.dim(row.repos)}`
|
|
12754
12888
|
);
|
|
12755
12889
|
}
|
|
12756
12890
|
}
|
|
@@ -13299,20 +13433,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
13299
13433
|
}
|
|
13300
13434
|
|
|
13301
13435
|
// src/commands/prs/listComments/printComments.ts
|
|
13302
|
-
import
|
|
13436
|
+
import chalk135 from "chalk";
|
|
13303
13437
|
function formatForHuman(comment3) {
|
|
13304
13438
|
if (comment3.type === "review") {
|
|
13305
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
13439
|
+
const stateColor = comment3.state === "APPROVED" ? chalk135.green : comment3.state === "CHANGES_REQUESTED" ? chalk135.red : chalk135.yellow;
|
|
13306
13440
|
return [
|
|
13307
|
-
`${
|
|
13441
|
+
`${chalk135.cyan("Review")} by ${chalk135.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
13308
13442
|
comment3.body,
|
|
13309
13443
|
""
|
|
13310
13444
|
].join("\n");
|
|
13311
13445
|
}
|
|
13312
13446
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
13313
13447
|
return [
|
|
13314
|
-
`${
|
|
13315
|
-
|
|
13448
|
+
`${chalk135.cyan("Line comment")} by ${chalk135.bold(comment3.user)} on ${chalk135.dim(`${comment3.path}${location}`)}`,
|
|
13449
|
+
chalk135.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
13316
13450
|
comment3.body,
|
|
13317
13451
|
""
|
|
13318
13452
|
].join("\n");
|
|
@@ -13402,13 +13536,13 @@ import { execSync as execSync38 } from "child_process";
|
|
|
13402
13536
|
import enquirer9 from "enquirer";
|
|
13403
13537
|
|
|
13404
13538
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
13405
|
-
import
|
|
13539
|
+
import chalk136 from "chalk";
|
|
13406
13540
|
var STATUS_MAP = {
|
|
13407
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
13408
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
13541
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk136.magenta("merged"), date: pr.mergedAt } : null,
|
|
13542
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk136.red("closed"), date: pr.closedAt } : null
|
|
13409
13543
|
};
|
|
13410
13544
|
function defaultStatus(pr) {
|
|
13411
|
-
return { label:
|
|
13545
|
+
return { label: chalk136.green("opened"), date: pr.createdAt };
|
|
13412
13546
|
}
|
|
13413
13547
|
function getStatus2(pr) {
|
|
13414
13548
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -13417,11 +13551,11 @@ function formatDate(dateStr) {
|
|
|
13417
13551
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
13418
13552
|
}
|
|
13419
13553
|
function formatPrHeader(pr, status2) {
|
|
13420
|
-
return `${
|
|
13554
|
+
return `${chalk136.cyan(`#${pr.number}`)} ${pr.title} ${chalk136.dim(`(${pr.author.login},`)} ${status2.label} ${chalk136.dim(`${formatDate(status2.date)})`)}`;
|
|
13421
13555
|
}
|
|
13422
13556
|
function logPrDetails(pr) {
|
|
13423
13557
|
console.log(
|
|
13424
|
-
|
|
13558
|
+
chalk136.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
13425
13559
|
);
|
|
13426
13560
|
console.log();
|
|
13427
13561
|
}
|
|
@@ -13728,10 +13862,10 @@ function registerPrs(program2) {
|
|
|
13728
13862
|
}
|
|
13729
13863
|
|
|
13730
13864
|
// src/commands/ravendb/ravendbAuth.ts
|
|
13731
|
-
import
|
|
13865
|
+
import chalk142 from "chalk";
|
|
13732
13866
|
|
|
13733
13867
|
// src/shared/createConnectionAuth.ts
|
|
13734
|
-
import
|
|
13868
|
+
import chalk137 from "chalk";
|
|
13735
13869
|
function listConnections(connections, format2) {
|
|
13736
13870
|
if (connections.length === 0) {
|
|
13737
13871
|
console.log("No connections configured.");
|
|
@@ -13744,7 +13878,7 @@ function listConnections(connections, format2) {
|
|
|
13744
13878
|
function removeConnection(connections, name, save) {
|
|
13745
13879
|
const filtered = connections.filter((c) => c.name !== name);
|
|
13746
13880
|
if (filtered.length === connections.length) {
|
|
13747
|
-
console.error(
|
|
13881
|
+
console.error(chalk137.red(`Connection "${name}" not found.`));
|
|
13748
13882
|
process.exit(1);
|
|
13749
13883
|
}
|
|
13750
13884
|
save(filtered);
|
|
@@ -13790,15 +13924,15 @@ function saveConnections(connections) {
|
|
|
13790
13924
|
}
|
|
13791
13925
|
|
|
13792
13926
|
// src/commands/ravendb/promptConnection.ts
|
|
13793
|
-
import
|
|
13927
|
+
import chalk140 from "chalk";
|
|
13794
13928
|
|
|
13795
13929
|
// src/commands/ravendb/selectOpSecret.ts
|
|
13796
|
-
import
|
|
13930
|
+
import chalk139 from "chalk";
|
|
13797
13931
|
import Enquirer2 from "enquirer";
|
|
13798
13932
|
|
|
13799
13933
|
// src/commands/ravendb/searchItems.ts
|
|
13800
13934
|
import { execSync as execSync41 } from "child_process";
|
|
13801
|
-
import
|
|
13935
|
+
import chalk138 from "chalk";
|
|
13802
13936
|
function opExec(args) {
|
|
13803
13937
|
return execSync41(`op ${args}`, {
|
|
13804
13938
|
encoding: "utf8",
|
|
@@ -13811,7 +13945,7 @@ function searchItems(search2) {
|
|
|
13811
13945
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
13812
13946
|
} catch {
|
|
13813
13947
|
console.error(
|
|
13814
|
-
|
|
13948
|
+
chalk138.red(
|
|
13815
13949
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
13816
13950
|
)
|
|
13817
13951
|
);
|
|
@@ -13825,7 +13959,7 @@ function getItemFields(itemId) {
|
|
|
13825
13959
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
13826
13960
|
return item.fields.filter((f) => f.reference && f.label);
|
|
13827
13961
|
} catch {
|
|
13828
|
-
console.error(
|
|
13962
|
+
console.error(chalk138.red("Failed to get item details from 1Password."));
|
|
13829
13963
|
process.exit(1);
|
|
13830
13964
|
}
|
|
13831
13965
|
}
|
|
@@ -13844,7 +13978,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
13844
13978
|
}).run();
|
|
13845
13979
|
const items2 = searchItems(search2);
|
|
13846
13980
|
if (items2.length === 0) {
|
|
13847
|
-
console.error(
|
|
13981
|
+
console.error(chalk139.red(`No items found matching "${search2}".`));
|
|
13848
13982
|
process.exit(1);
|
|
13849
13983
|
}
|
|
13850
13984
|
const itemId = await selectOne(
|
|
@@ -13853,7 +13987,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
13853
13987
|
);
|
|
13854
13988
|
const fields = getItemFields(itemId);
|
|
13855
13989
|
if (fields.length === 0) {
|
|
13856
|
-
console.error(
|
|
13990
|
+
console.error(chalk139.red("No fields with references found on this item."));
|
|
13857
13991
|
process.exit(1);
|
|
13858
13992
|
}
|
|
13859
13993
|
const ref = await selectOne(
|
|
@@ -13867,7 +14001,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
13867
14001
|
async function promptConnection(existingNames) {
|
|
13868
14002
|
const name = await promptInput("name", "Connection name:");
|
|
13869
14003
|
if (existingNames.includes(name)) {
|
|
13870
|
-
console.error(
|
|
14004
|
+
console.error(chalk140.red(`Connection "${name}" already exists.`));
|
|
13871
14005
|
process.exit(1);
|
|
13872
14006
|
}
|
|
13873
14007
|
const url = await promptInput(
|
|
@@ -13876,22 +14010,22 @@ async function promptConnection(existingNames) {
|
|
|
13876
14010
|
);
|
|
13877
14011
|
const database = await promptInput("database", "Database name:");
|
|
13878
14012
|
if (!name || !url || !database) {
|
|
13879
|
-
console.error(
|
|
14013
|
+
console.error(chalk140.red("All fields are required."));
|
|
13880
14014
|
process.exit(1);
|
|
13881
14015
|
}
|
|
13882
14016
|
const apiKeyRef = await selectOpSecret();
|
|
13883
|
-
console.log(
|
|
14017
|
+
console.log(chalk140.dim(`Using: ${apiKeyRef}`));
|
|
13884
14018
|
return { name, url, database, apiKeyRef };
|
|
13885
14019
|
}
|
|
13886
14020
|
|
|
13887
14021
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
13888
|
-
import
|
|
14022
|
+
import chalk141 from "chalk";
|
|
13889
14023
|
function ravendbSetConnection(name) {
|
|
13890
14024
|
const raw = loadGlobalConfigRaw();
|
|
13891
14025
|
const ravendb = raw.ravendb ?? {};
|
|
13892
14026
|
const connections = ravendb.connections ?? [];
|
|
13893
14027
|
if (!connections.some((c) => c.name === name)) {
|
|
13894
|
-
console.error(
|
|
14028
|
+
console.error(chalk141.red(`Connection "${name}" not found.`));
|
|
13895
14029
|
console.error(
|
|
13896
14030
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
13897
14031
|
);
|
|
@@ -13907,16 +14041,16 @@ function ravendbSetConnection(name) {
|
|
|
13907
14041
|
var ravendbAuth = createConnectionAuth({
|
|
13908
14042
|
load: loadConnections,
|
|
13909
14043
|
save: saveConnections,
|
|
13910
|
-
format: (c) => `${
|
|
14044
|
+
format: (c) => `${chalk142.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
13911
14045
|
promptNew: promptConnection,
|
|
13912
14046
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
13913
14047
|
});
|
|
13914
14048
|
|
|
13915
14049
|
// src/commands/ravendb/ravendbCollections.ts
|
|
13916
|
-
import
|
|
14050
|
+
import chalk146 from "chalk";
|
|
13917
14051
|
|
|
13918
14052
|
// src/commands/ravendb/ravenFetch.ts
|
|
13919
|
-
import
|
|
14053
|
+
import chalk144 from "chalk";
|
|
13920
14054
|
|
|
13921
14055
|
// src/commands/ravendb/getAccessToken.ts
|
|
13922
14056
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -13953,10 +14087,10 @@ ${errorText}`
|
|
|
13953
14087
|
|
|
13954
14088
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
13955
14089
|
import { execSync as execSync42 } from "child_process";
|
|
13956
|
-
import
|
|
14090
|
+
import chalk143 from "chalk";
|
|
13957
14091
|
function resolveOpSecret(reference) {
|
|
13958
14092
|
if (!reference.startsWith("op://")) {
|
|
13959
|
-
console.error(
|
|
14093
|
+
console.error(chalk143.red(`Invalid secret reference: must start with op://`));
|
|
13960
14094
|
process.exit(1);
|
|
13961
14095
|
}
|
|
13962
14096
|
try {
|
|
@@ -13966,7 +14100,7 @@ function resolveOpSecret(reference) {
|
|
|
13966
14100
|
}).trim();
|
|
13967
14101
|
} catch {
|
|
13968
14102
|
console.error(
|
|
13969
|
-
|
|
14103
|
+
chalk143.red(
|
|
13970
14104
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
13971
14105
|
)
|
|
13972
14106
|
);
|
|
@@ -13993,7 +14127,7 @@ async function ravenFetch(connection, path57) {
|
|
|
13993
14127
|
if (!response.ok) {
|
|
13994
14128
|
const body = await response.text();
|
|
13995
14129
|
console.error(
|
|
13996
|
-
|
|
14130
|
+
chalk144.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
13997
14131
|
);
|
|
13998
14132
|
console.error(body.substring(0, 500));
|
|
13999
14133
|
process.exit(1);
|
|
@@ -14002,7 +14136,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14002
14136
|
}
|
|
14003
14137
|
|
|
14004
14138
|
// src/commands/ravendb/resolveConnection.ts
|
|
14005
|
-
import
|
|
14139
|
+
import chalk145 from "chalk";
|
|
14006
14140
|
function loadRavendb() {
|
|
14007
14141
|
const raw = loadGlobalConfigRaw();
|
|
14008
14142
|
const ravendb = raw.ravendb;
|
|
@@ -14016,7 +14150,7 @@ function resolveConnection(name) {
|
|
|
14016
14150
|
const connectionName = name ?? defaultConnection;
|
|
14017
14151
|
if (!connectionName) {
|
|
14018
14152
|
console.error(
|
|
14019
|
-
|
|
14153
|
+
chalk145.red(
|
|
14020
14154
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
14021
14155
|
)
|
|
14022
14156
|
);
|
|
@@ -14024,7 +14158,7 @@ function resolveConnection(name) {
|
|
|
14024
14158
|
}
|
|
14025
14159
|
const connection = connections.find((c) => c.name === connectionName);
|
|
14026
14160
|
if (!connection) {
|
|
14027
|
-
console.error(
|
|
14161
|
+
console.error(chalk145.red(`Connection "${connectionName}" not found.`));
|
|
14028
14162
|
console.error(
|
|
14029
14163
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14030
14164
|
);
|
|
@@ -14055,15 +14189,15 @@ async function ravendbCollections(connectionName) {
|
|
|
14055
14189
|
return;
|
|
14056
14190
|
}
|
|
14057
14191
|
for (const c of collections) {
|
|
14058
|
-
console.log(`${
|
|
14192
|
+
console.log(`${chalk146.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
14059
14193
|
}
|
|
14060
14194
|
}
|
|
14061
14195
|
|
|
14062
14196
|
// src/commands/ravendb/ravendbQuery.ts
|
|
14063
|
-
import
|
|
14197
|
+
import chalk148 from "chalk";
|
|
14064
14198
|
|
|
14065
14199
|
// src/commands/ravendb/fetchAllPages.ts
|
|
14066
|
-
import
|
|
14200
|
+
import chalk147 from "chalk";
|
|
14067
14201
|
|
|
14068
14202
|
// src/commands/ravendb/buildQueryPath.ts
|
|
14069
14203
|
function buildQueryPath(opts) {
|
|
@@ -14101,7 +14235,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14101
14235
|
allResults.push(...results);
|
|
14102
14236
|
start3 += results.length;
|
|
14103
14237
|
process.stderr.write(
|
|
14104
|
-
`\r${
|
|
14238
|
+
`\r${chalk147.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
14105
14239
|
);
|
|
14106
14240
|
if (start3 >= totalResults) break;
|
|
14107
14241
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -14116,7 +14250,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14116
14250
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
14117
14251
|
const resolved = resolveArgs(connectionName, collection);
|
|
14118
14252
|
if (!resolved.collection && !options2.query) {
|
|
14119
|
-
console.error(
|
|
14253
|
+
console.error(chalk148.red("Provide a collection name or --query filter."));
|
|
14120
14254
|
process.exit(1);
|
|
14121
14255
|
}
|
|
14122
14256
|
const { collection: col } = resolved;
|
|
@@ -14154,7 +14288,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
14154
14288
|
import * as path28 from "path";
|
|
14155
14289
|
|
|
14156
14290
|
// src/commands/refactor/logViolations.ts
|
|
14157
|
-
import
|
|
14291
|
+
import chalk149 from "chalk";
|
|
14158
14292
|
var DEFAULT_MAX_LINES = 100;
|
|
14159
14293
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
14160
14294
|
if (violations.length === 0) {
|
|
@@ -14163,43 +14297,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
14163
14297
|
}
|
|
14164
14298
|
return;
|
|
14165
14299
|
}
|
|
14166
|
-
console.error(
|
|
14300
|
+
console.error(chalk149.red(`
|
|
14167
14301
|
Refactor check failed:
|
|
14168
14302
|
`));
|
|
14169
|
-
console.error(
|
|
14303
|
+
console.error(chalk149.red(` The following files exceed ${maxLines} lines:
|
|
14170
14304
|
`));
|
|
14171
14305
|
for (const violation of violations) {
|
|
14172
|
-
console.error(
|
|
14306
|
+
console.error(chalk149.red(` ${violation.file} (${violation.lines} lines)`));
|
|
14173
14307
|
}
|
|
14174
14308
|
console.error(
|
|
14175
|
-
|
|
14309
|
+
chalk149.yellow(
|
|
14176
14310
|
`
|
|
14177
14311
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
14178
14312
|
way to refactor it, ignore it with:
|
|
14179
14313
|
`
|
|
14180
14314
|
)
|
|
14181
14315
|
);
|
|
14182
|
-
console.error(
|
|
14316
|
+
console.error(chalk149.gray(` assist refactor ignore <file>
|
|
14183
14317
|
`));
|
|
14184
14318
|
if (process.env.CLAUDECODE) {
|
|
14185
|
-
console.error(
|
|
14319
|
+
console.error(chalk149.cyan(`
|
|
14186
14320
|
## Extracting Code to New Files
|
|
14187
14321
|
`));
|
|
14188
14322
|
console.error(
|
|
14189
|
-
|
|
14323
|
+
chalk149.cyan(
|
|
14190
14324
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
14191
14325
|
`
|
|
14192
14326
|
)
|
|
14193
14327
|
);
|
|
14194
14328
|
console.error(
|
|
14195
|
-
|
|
14329
|
+
chalk149.cyan(
|
|
14196
14330
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
14197
14331
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
14198
14332
|
`
|
|
14199
14333
|
)
|
|
14200
14334
|
);
|
|
14201
14335
|
console.error(
|
|
14202
|
-
|
|
14336
|
+
chalk149.cyan(
|
|
14203
14337
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
14204
14338
|
domains, move it to a common/shared folder.
|
|
14205
14339
|
`
|
|
@@ -14210,17 +14344,17 @@ Refactor check failed:
|
|
|
14210
14344
|
|
|
14211
14345
|
// src/commands/refactor/check/getViolations/index.ts
|
|
14212
14346
|
import { execSync as execSync43 } from "child_process";
|
|
14213
|
-
import
|
|
14347
|
+
import fs21 from "fs";
|
|
14214
14348
|
import { minimatch as minimatch6 } from "minimatch";
|
|
14215
14349
|
|
|
14216
14350
|
// src/commands/refactor/check/getViolations/getIgnoredFiles.ts
|
|
14217
|
-
import
|
|
14351
|
+
import fs20 from "fs";
|
|
14218
14352
|
var REFACTOR_YML_PATH = "refactor.yml";
|
|
14219
14353
|
function parseRefactorYml() {
|
|
14220
|
-
if (!
|
|
14354
|
+
if (!fs20.existsSync(REFACTOR_YML_PATH)) {
|
|
14221
14355
|
return [];
|
|
14222
14356
|
}
|
|
14223
|
-
const content =
|
|
14357
|
+
const content = fs20.readFileSync(REFACTOR_YML_PATH, "utf8");
|
|
14224
14358
|
const entries = [];
|
|
14225
14359
|
const lines = content.split("\n");
|
|
14226
14360
|
let currentEntry = {};
|
|
@@ -14250,7 +14384,7 @@ function getIgnoredFiles() {
|
|
|
14250
14384
|
|
|
14251
14385
|
// src/commands/refactor/check/getViolations/index.ts
|
|
14252
14386
|
function countLines(filePath) {
|
|
14253
|
-
const content =
|
|
14387
|
+
const content = fs21.readFileSync(filePath, "utf8");
|
|
14254
14388
|
return content.split("\n").length;
|
|
14255
14389
|
}
|
|
14256
14390
|
function getGitFiles(options2) {
|
|
@@ -14355,7 +14489,7 @@ async function check(pattern2, options2) {
|
|
|
14355
14489
|
|
|
14356
14490
|
// src/commands/refactor/extract/index.ts
|
|
14357
14491
|
import path35 from "path";
|
|
14358
|
-
import
|
|
14492
|
+
import chalk152 from "chalk";
|
|
14359
14493
|
|
|
14360
14494
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
14361
14495
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -14930,23 +15064,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
14930
15064
|
|
|
14931
15065
|
// src/commands/refactor/extract/displayPlan.ts
|
|
14932
15066
|
import path32 from "path";
|
|
14933
|
-
import
|
|
15067
|
+
import chalk150 from "chalk";
|
|
14934
15068
|
function section(title) {
|
|
14935
15069
|
return `
|
|
14936
|
-
${
|
|
15070
|
+
${chalk150.cyan(title)}`;
|
|
14937
15071
|
}
|
|
14938
15072
|
function displayImporters(plan2, cwd) {
|
|
14939
15073
|
if (plan2.importersToUpdate.length === 0) return;
|
|
14940
15074
|
console.log(section("Update importers:"));
|
|
14941
15075
|
for (const imp of plan2.importersToUpdate) {
|
|
14942
15076
|
const rel = path32.relative(cwd, imp.file.getFilePath());
|
|
14943
|
-
console.log(` ${
|
|
15077
|
+
console.log(` ${chalk150.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
14944
15078
|
}
|
|
14945
15079
|
}
|
|
14946
15080
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
14947
|
-
console.log(
|
|
15081
|
+
console.log(chalk150.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
14948
15082
|
`));
|
|
14949
|
-
console.log(` ${
|
|
15083
|
+
console.log(` ${chalk150.cyan("Functions to move:")}`);
|
|
14950
15084
|
for (const name of plan2.extractedNames) {
|
|
14951
15085
|
console.log(` ${name}`);
|
|
14952
15086
|
}
|
|
@@ -14980,16 +15114,16 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
14980
15114
|
|
|
14981
15115
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
14982
15116
|
import path34 from "path";
|
|
14983
|
-
import
|
|
15117
|
+
import chalk151 from "chalk";
|
|
14984
15118
|
import { Project as Project4 } from "ts-morph";
|
|
14985
15119
|
|
|
14986
15120
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
14987
|
-
import
|
|
15121
|
+
import fs22 from "fs";
|
|
14988
15122
|
import path33 from "path";
|
|
14989
15123
|
import { Project as Project3 } from "ts-morph";
|
|
14990
15124
|
function findTsConfig(sourcePath) {
|
|
14991
15125
|
const rootConfig = path33.resolve("tsconfig.json");
|
|
14992
|
-
if (!
|
|
15126
|
+
if (!fs22.existsSync(rootConfig)) return rootConfig;
|
|
14993
15127
|
const tried = /* @__PURE__ */ new Set();
|
|
14994
15128
|
const candidates = [rootConfig, ...readReferences(rootConfig)];
|
|
14995
15129
|
for (const candidate of candidates) {
|
|
@@ -14997,7 +15131,7 @@ function findTsConfig(sourcePath) {
|
|
|
14997
15131
|
tried.add(candidate);
|
|
14998
15132
|
if (projectIncludes(candidate, sourcePath)) return candidate;
|
|
14999
15133
|
}
|
|
15000
|
-
const siblings =
|
|
15134
|
+
const siblings = fs22.readdirSync(path33.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path33.resolve(path33.dirname(rootConfig), f));
|
|
15001
15135
|
for (const sibling of siblings) {
|
|
15002
15136
|
if (tried.has(sibling)) continue;
|
|
15003
15137
|
tried.add(sibling);
|
|
@@ -15006,8 +15140,8 @@ function findTsConfig(sourcePath) {
|
|
|
15006
15140
|
return rootConfig;
|
|
15007
15141
|
}
|
|
15008
15142
|
function readReferences(configPath) {
|
|
15009
|
-
if (!
|
|
15010
|
-
const raw =
|
|
15143
|
+
if (!fs22.existsSync(configPath)) return [];
|
|
15144
|
+
const raw = fs22.readFileSync(configPath, "utf8");
|
|
15011
15145
|
const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
15012
15146
|
let parsed;
|
|
15013
15147
|
try {
|
|
@@ -15019,8 +15153,8 @@ function readReferences(configPath) {
|
|
|
15019
15153
|
const cwd = path33.dirname(configPath);
|
|
15020
15154
|
return parsed.references.map((ref) => {
|
|
15021
15155
|
const refPath = path33.resolve(cwd, ref.path);
|
|
15022
|
-
return
|
|
15023
|
-
}).filter((p) =>
|
|
15156
|
+
return fs22.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path33.join(refPath, "tsconfig.json") : refPath;
|
|
15157
|
+
}).filter((p) => fs22.existsSync(p));
|
|
15024
15158
|
}
|
|
15025
15159
|
function projectIncludes(configPath, sourcePath) {
|
|
15026
15160
|
try {
|
|
@@ -15040,7 +15174,7 @@ function loadProjectFile(file) {
|
|
|
15040
15174
|
});
|
|
15041
15175
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
15042
15176
|
if (!sourceFile) {
|
|
15043
|
-
console.log(
|
|
15177
|
+
console.log(chalk151.red(`File not found in project: ${file}`));
|
|
15044
15178
|
process.exit(1);
|
|
15045
15179
|
}
|
|
15046
15180
|
return { project, sourceFile };
|
|
@@ -15063,55 +15197,55 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
15063
15197
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
15064
15198
|
if (options2.apply) {
|
|
15065
15199
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
15066
|
-
console.log(
|
|
15200
|
+
console.log(chalk152.green("\nExtraction complete"));
|
|
15067
15201
|
} else {
|
|
15068
|
-
console.log(
|
|
15202
|
+
console.log(chalk152.dim("\nDry run. Use --apply to execute."));
|
|
15069
15203
|
}
|
|
15070
15204
|
}
|
|
15071
15205
|
|
|
15072
15206
|
// src/commands/refactor/ignore.ts
|
|
15073
|
-
import
|
|
15074
|
-
import
|
|
15207
|
+
import fs23 from "fs";
|
|
15208
|
+
import chalk153 from "chalk";
|
|
15075
15209
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
15076
15210
|
function ignore(file) {
|
|
15077
|
-
if (!
|
|
15078
|
-
console.error(
|
|
15211
|
+
if (!fs23.existsSync(file)) {
|
|
15212
|
+
console.error(chalk153.red(`Error: File does not exist: ${file}`));
|
|
15079
15213
|
process.exit(1);
|
|
15080
15214
|
}
|
|
15081
|
-
const content =
|
|
15215
|
+
const content = fs23.readFileSync(file, "utf8");
|
|
15082
15216
|
const lineCount = content.split("\n").length;
|
|
15083
15217
|
const maxLines = lineCount + 10;
|
|
15084
15218
|
const entry = `- file: ${file}
|
|
15085
15219
|
maxLines: ${maxLines}
|
|
15086
15220
|
`;
|
|
15087
|
-
if (
|
|
15088
|
-
const existing =
|
|
15089
|
-
|
|
15221
|
+
if (fs23.existsSync(REFACTOR_YML_PATH2)) {
|
|
15222
|
+
const existing = fs23.readFileSync(REFACTOR_YML_PATH2, "utf8");
|
|
15223
|
+
fs23.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
|
|
15090
15224
|
} else {
|
|
15091
|
-
|
|
15225
|
+
fs23.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
15092
15226
|
}
|
|
15093
15227
|
console.log(
|
|
15094
|
-
|
|
15228
|
+
chalk153.green(
|
|
15095
15229
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
15096
15230
|
)
|
|
15097
15231
|
);
|
|
15098
15232
|
}
|
|
15099
15233
|
|
|
15100
15234
|
// src/commands/refactor/rename/index.ts
|
|
15101
|
-
import
|
|
15235
|
+
import fs26 from "fs";
|
|
15102
15236
|
import path40 from "path";
|
|
15103
|
-
import
|
|
15237
|
+
import chalk156 from "chalk";
|
|
15104
15238
|
|
|
15105
15239
|
// src/commands/refactor/rename/applyRename.ts
|
|
15106
|
-
import
|
|
15240
|
+
import fs25 from "fs";
|
|
15107
15241
|
import path37 from "path";
|
|
15108
|
-
import
|
|
15242
|
+
import chalk154 from "chalk";
|
|
15109
15243
|
|
|
15110
15244
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
15111
15245
|
import path36 from "path";
|
|
15112
15246
|
|
|
15113
15247
|
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
15114
|
-
import
|
|
15248
|
+
import fs24 from "fs";
|
|
15115
15249
|
function getOrCreateList(map, key) {
|
|
15116
15250
|
const list4 = map.get(key) ?? [];
|
|
15117
15251
|
if (!map.has(key)) map.set(key, list4);
|
|
@@ -15130,7 +15264,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
|
15130
15264
|
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
15131
15265
|
}
|
|
15132
15266
|
function applyFileRewrites(file, fileRewrites) {
|
|
15133
|
-
let content =
|
|
15267
|
+
let content = fs24.readFileSync(file, "utf8");
|
|
15134
15268
|
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
15135
15269
|
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
15136
15270
|
}
|
|
@@ -15209,14 +15343,14 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
15209
15343
|
function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
15210
15344
|
const updatedContents = applyRewrites(rewrites);
|
|
15211
15345
|
for (const [file, content] of updatedContents) {
|
|
15212
|
-
|
|
15213
|
-
console.log(
|
|
15346
|
+
fs25.writeFileSync(file, content, "utf8");
|
|
15347
|
+
console.log(chalk154.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
15214
15348
|
}
|
|
15215
15349
|
const destDir = path37.dirname(destPath);
|
|
15216
|
-
if (!
|
|
15217
|
-
|
|
15350
|
+
if (!fs25.existsSync(destDir)) fs25.mkdirSync(destDir, { recursive: true });
|
|
15351
|
+
fs25.renameSync(sourcePath, destPath);
|
|
15218
15352
|
console.log(
|
|
15219
|
-
|
|
15353
|
+
chalk154.white(
|
|
15220
15354
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
15221
15355
|
)
|
|
15222
15356
|
);
|
|
@@ -15303,16 +15437,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
15303
15437
|
|
|
15304
15438
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
15305
15439
|
import path39 from "path";
|
|
15306
|
-
import
|
|
15440
|
+
import chalk155 from "chalk";
|
|
15307
15441
|
function printRenamePreview(rewrites, cwd) {
|
|
15308
15442
|
for (const rewrite of rewrites) {
|
|
15309
15443
|
console.log(
|
|
15310
|
-
|
|
15444
|
+
chalk155.dim(
|
|
15311
15445
|
` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
15312
15446
|
)
|
|
15313
15447
|
);
|
|
15314
15448
|
}
|
|
15315
|
-
console.log(
|
|
15449
|
+
console.log(chalk155.dim("Dry run. Use --apply to execute."));
|
|
15316
15450
|
}
|
|
15317
15451
|
|
|
15318
15452
|
// src/commands/refactor/rename/index.ts
|
|
@@ -15322,21 +15456,21 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15322
15456
|
const cwd = process.cwd();
|
|
15323
15457
|
const relSource = path40.relative(cwd, sourcePath);
|
|
15324
15458
|
const relDest = path40.relative(cwd, destPath);
|
|
15325
|
-
if (!
|
|
15326
|
-
console.log(
|
|
15459
|
+
if (!fs26.existsSync(sourcePath)) {
|
|
15460
|
+
console.log(chalk156.red(`File not found: ${source}`));
|
|
15327
15461
|
process.exit(1);
|
|
15328
15462
|
}
|
|
15329
|
-
if (destPath !== sourcePath &&
|
|
15330
|
-
console.log(
|
|
15463
|
+
if (destPath !== sourcePath && fs26.existsSync(destPath)) {
|
|
15464
|
+
console.log(chalk156.red(`Destination already exists: ${destination}`));
|
|
15331
15465
|
process.exit(1);
|
|
15332
15466
|
}
|
|
15333
|
-
console.log(
|
|
15334
|
-
console.log(
|
|
15335
|
-
console.log(
|
|
15467
|
+
console.log(chalk156.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
15468
|
+
console.log(chalk156.dim("Loading project..."));
|
|
15469
|
+
console.log(chalk156.dim("Scanning imports across the project..."));
|
|
15336
15470
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
15337
15471
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
15338
15472
|
console.log(
|
|
15339
|
-
|
|
15473
|
+
chalk156.dim(
|
|
15340
15474
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
15341
15475
|
)
|
|
15342
15476
|
);
|
|
@@ -15345,11 +15479,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15345
15479
|
return;
|
|
15346
15480
|
}
|
|
15347
15481
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
15348
|
-
console.log(
|
|
15482
|
+
console.log(chalk156.green("Done"));
|
|
15349
15483
|
}
|
|
15350
15484
|
|
|
15351
15485
|
// src/commands/refactor/renameSymbol/index.ts
|
|
15352
|
-
import
|
|
15486
|
+
import chalk157 from "chalk";
|
|
15353
15487
|
|
|
15354
15488
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
15355
15489
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -15395,33 +15529,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
15395
15529
|
const { project, sourceFile } = loadProjectFile(file);
|
|
15396
15530
|
const symbol = findSymbol(sourceFile, oldName);
|
|
15397
15531
|
if (!symbol) {
|
|
15398
|
-
console.log(
|
|
15532
|
+
console.log(chalk157.red(`Symbol "${oldName}" not found in ${file}`));
|
|
15399
15533
|
process.exit(1);
|
|
15400
15534
|
}
|
|
15401
15535
|
const grouped = groupReferences(symbol, cwd);
|
|
15402
15536
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
15403
15537
|
console.log(
|
|
15404
|
-
|
|
15538
|
+
chalk157.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
15405
15539
|
`)
|
|
15406
15540
|
);
|
|
15407
15541
|
for (const [refFile, lines] of grouped) {
|
|
15408
15542
|
console.log(
|
|
15409
|
-
` ${
|
|
15543
|
+
` ${chalk157.dim(refFile)}: lines ${chalk157.cyan(lines.join(", "))}`
|
|
15410
15544
|
);
|
|
15411
15545
|
}
|
|
15412
15546
|
if (options2.apply) {
|
|
15413
15547
|
symbol.rename(newName);
|
|
15414
15548
|
await project.save();
|
|
15415
|
-
console.log(
|
|
15549
|
+
console.log(chalk157.green(`
|
|
15416
15550
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
15417
15551
|
} else {
|
|
15418
|
-
console.log(
|
|
15552
|
+
console.log(chalk157.dim("\nDry run. Use --apply to execute."));
|
|
15419
15553
|
}
|
|
15420
15554
|
}
|
|
15421
15555
|
|
|
15422
15556
|
// src/commands/refactor/restructure/index.ts
|
|
15423
15557
|
import path48 from "path";
|
|
15424
|
-
import
|
|
15558
|
+
import chalk160 from "chalk";
|
|
15425
15559
|
|
|
15426
15560
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
15427
15561
|
import path42 from "path";
|
|
@@ -15500,50 +15634,50 @@ function clusterFiles(graph) {
|
|
|
15500
15634
|
|
|
15501
15635
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
15502
15636
|
import path44 from "path";
|
|
15503
|
-
import
|
|
15637
|
+
import chalk158 from "chalk";
|
|
15504
15638
|
function relPath(filePath) {
|
|
15505
15639
|
return path44.relative(process.cwd(), filePath);
|
|
15506
15640
|
}
|
|
15507
15641
|
function displayMoves(plan2) {
|
|
15508
15642
|
if (plan2.moves.length === 0) return;
|
|
15509
|
-
console.log(
|
|
15643
|
+
console.log(chalk158.bold("\nFile moves:"));
|
|
15510
15644
|
for (const move of plan2.moves) {
|
|
15511
15645
|
console.log(
|
|
15512
|
-
` ${
|
|
15646
|
+
` ${chalk158.red(relPath(move.from))} \u2192 ${chalk158.green(relPath(move.to))}`
|
|
15513
15647
|
);
|
|
15514
|
-
console.log(
|
|
15648
|
+
console.log(chalk158.dim(` ${move.reason}`));
|
|
15515
15649
|
}
|
|
15516
15650
|
}
|
|
15517
15651
|
function displayRewrites(rewrites) {
|
|
15518
15652
|
if (rewrites.length === 0) return;
|
|
15519
15653
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
15520
|
-
console.log(
|
|
15654
|
+
console.log(chalk158.bold(`
|
|
15521
15655
|
Import rewrites (${affectedFiles.size} files):`));
|
|
15522
15656
|
for (const file of affectedFiles) {
|
|
15523
|
-
console.log(` ${
|
|
15657
|
+
console.log(` ${chalk158.cyan(relPath(file))}:`);
|
|
15524
15658
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
15525
15659
|
(r) => r.file === file
|
|
15526
15660
|
)) {
|
|
15527
15661
|
console.log(
|
|
15528
|
-
` ${
|
|
15662
|
+
` ${chalk158.red(`"${oldSpecifier}"`)} \u2192 ${chalk158.green(`"${newSpecifier}"`)}`
|
|
15529
15663
|
);
|
|
15530
15664
|
}
|
|
15531
15665
|
}
|
|
15532
15666
|
}
|
|
15533
15667
|
function displayPlan2(plan2) {
|
|
15534
15668
|
if (plan2.warnings.length > 0) {
|
|
15535
|
-
console.log(
|
|
15536
|
-
for (const w of plan2.warnings) console.log(
|
|
15669
|
+
console.log(chalk158.yellow("\nWarnings:"));
|
|
15670
|
+
for (const w of plan2.warnings) console.log(chalk158.yellow(` ${w}`));
|
|
15537
15671
|
}
|
|
15538
15672
|
if (plan2.newDirectories.length > 0) {
|
|
15539
|
-
console.log(
|
|
15673
|
+
console.log(chalk158.bold("\nNew directories:"));
|
|
15540
15674
|
for (const dir of plan2.newDirectories)
|
|
15541
|
-
console.log(
|
|
15675
|
+
console.log(chalk158.green(` ${dir}/`));
|
|
15542
15676
|
}
|
|
15543
15677
|
displayMoves(plan2);
|
|
15544
15678
|
displayRewrites(plan2.rewrites);
|
|
15545
15679
|
console.log(
|
|
15546
|
-
|
|
15680
|
+
chalk158.dim(
|
|
15547
15681
|
`
|
|
15548
15682
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
15549
15683
|
)
|
|
@@ -15551,29 +15685,29 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
15551
15685
|
}
|
|
15552
15686
|
|
|
15553
15687
|
// src/commands/refactor/restructure/executePlan.ts
|
|
15554
|
-
import
|
|
15688
|
+
import fs27 from "fs";
|
|
15555
15689
|
import path45 from "path";
|
|
15556
|
-
import
|
|
15690
|
+
import chalk159 from "chalk";
|
|
15557
15691
|
function executePlan(plan2) {
|
|
15558
15692
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
15559
15693
|
for (const [file, content] of updatedContents) {
|
|
15560
|
-
|
|
15694
|
+
fs27.writeFileSync(file, content, "utf8");
|
|
15561
15695
|
console.log(
|
|
15562
|
-
|
|
15696
|
+
chalk159.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
15563
15697
|
);
|
|
15564
15698
|
}
|
|
15565
15699
|
for (const dir of plan2.newDirectories) {
|
|
15566
|
-
|
|
15567
|
-
console.log(
|
|
15700
|
+
fs27.mkdirSync(dir, { recursive: true });
|
|
15701
|
+
console.log(chalk159.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
15568
15702
|
}
|
|
15569
15703
|
for (const move of plan2.moves) {
|
|
15570
15704
|
const targetDir = path45.dirname(move.to);
|
|
15571
|
-
if (!
|
|
15572
|
-
|
|
15705
|
+
if (!fs27.existsSync(targetDir)) {
|
|
15706
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
15573
15707
|
}
|
|
15574
|
-
|
|
15708
|
+
fs27.renameSync(move.from, move.to);
|
|
15575
15709
|
console.log(
|
|
15576
|
-
|
|
15710
|
+
chalk159.white(
|
|
15577
15711
|
` Moved ${path45.relative(process.cwd(), move.from)} \u2192 ${path45.relative(process.cwd(), move.to)}`
|
|
15578
15712
|
)
|
|
15579
15713
|
);
|
|
@@ -15583,12 +15717,12 @@ function executePlan(plan2) {
|
|
|
15583
15717
|
function removeEmptyDirectories(dirs) {
|
|
15584
15718
|
const unique = [...new Set(dirs)];
|
|
15585
15719
|
for (const dir of unique) {
|
|
15586
|
-
if (!
|
|
15587
|
-
const entries =
|
|
15720
|
+
if (!fs27.existsSync(dir)) continue;
|
|
15721
|
+
const entries = fs27.readdirSync(dir);
|
|
15588
15722
|
if (entries.length === 0) {
|
|
15589
|
-
|
|
15723
|
+
fs27.rmdirSync(dir);
|
|
15590
15724
|
console.log(
|
|
15591
|
-
|
|
15725
|
+
chalk159.dim(
|
|
15592
15726
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
15593
15727
|
)
|
|
15594
15728
|
);
|
|
@@ -15600,18 +15734,18 @@ function removeEmptyDirectories(dirs) {
|
|
|
15600
15734
|
import path47 from "path";
|
|
15601
15735
|
|
|
15602
15736
|
// src/commands/refactor/restructure/planFileMoves/shared.ts
|
|
15603
|
-
import
|
|
15737
|
+
import fs28 from "fs";
|
|
15604
15738
|
function emptyResult() {
|
|
15605
15739
|
return { moves: [], directories: [], warnings: [] };
|
|
15606
15740
|
}
|
|
15607
15741
|
function checkDirConflict(result, label2, dir) {
|
|
15608
|
-
if (!
|
|
15742
|
+
if (!fs28.existsSync(dir)) return false;
|
|
15609
15743
|
result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
|
|
15610
15744
|
return true;
|
|
15611
15745
|
}
|
|
15612
15746
|
|
|
15613
15747
|
// src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
|
|
15614
|
-
import
|
|
15748
|
+
import fs29 from "fs";
|
|
15615
15749
|
import path46 from "path";
|
|
15616
15750
|
function collectEntry(results, dir, entry) {
|
|
15617
15751
|
const full = path46.join(dir, entry.name);
|
|
@@ -15619,9 +15753,9 @@ function collectEntry(results, dir, entry) {
|
|
|
15619
15753
|
results.push(...items2);
|
|
15620
15754
|
}
|
|
15621
15755
|
function listFilesRecursive(dir) {
|
|
15622
|
-
if (!
|
|
15756
|
+
if (!fs29.existsSync(dir)) return [];
|
|
15623
15757
|
const results = [];
|
|
15624
|
-
for (const entry of
|
|
15758
|
+
for (const entry of fs29.readdirSync(dir, { withFileTypes: true })) {
|
|
15625
15759
|
collectEntry(results, dir, entry);
|
|
15626
15760
|
}
|
|
15627
15761
|
return results;
|
|
@@ -15721,22 +15855,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
15721
15855
|
const targetPattern = pattern2 ?? "src";
|
|
15722
15856
|
const files = findSourceFiles2(targetPattern);
|
|
15723
15857
|
if (files.length === 0) {
|
|
15724
|
-
console.log(
|
|
15858
|
+
console.log(chalk160.yellow("No files found matching pattern"));
|
|
15725
15859
|
return;
|
|
15726
15860
|
}
|
|
15727
15861
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
15728
15862
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
15729
15863
|
if (plan2.moves.length === 0) {
|
|
15730
|
-
console.log(
|
|
15864
|
+
console.log(chalk160.green("No restructuring needed"));
|
|
15731
15865
|
return;
|
|
15732
15866
|
}
|
|
15733
15867
|
displayPlan2(plan2);
|
|
15734
15868
|
if (options2.apply) {
|
|
15735
|
-
console.log(
|
|
15869
|
+
console.log(chalk160.bold("\nApplying changes..."));
|
|
15736
15870
|
executePlan(plan2);
|
|
15737
|
-
console.log(
|
|
15871
|
+
console.log(chalk160.green("\nRestructuring complete"));
|
|
15738
15872
|
} else {
|
|
15739
|
-
console.log(
|
|
15873
|
+
console.log(chalk160.dim("\nDry run. Use --apply to execute."));
|
|
15740
15874
|
}
|
|
15741
15875
|
}
|
|
15742
15876
|
|
|
@@ -16305,18 +16439,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
16305
16439
|
}
|
|
16306
16440
|
|
|
16307
16441
|
// src/commands/review/warnOutOfDiff.ts
|
|
16308
|
-
import
|
|
16442
|
+
import chalk161 from "chalk";
|
|
16309
16443
|
function warnOutOfDiff(outOfDiff) {
|
|
16310
16444
|
if (outOfDiff.length === 0) return;
|
|
16311
16445
|
console.warn(
|
|
16312
|
-
|
|
16446
|
+
chalk161.yellow(
|
|
16313
16447
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
16314
16448
|
)
|
|
16315
16449
|
);
|
|
16316
16450
|
for (const finding of outOfDiff) {
|
|
16317
16451
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
16318
16452
|
console.warn(
|
|
16319
|
-
` ${
|
|
16453
|
+
` ${chalk161.yellow("\xB7")} ${finding.title} ${chalk161.dim(
|
|
16320
16454
|
`(${finding.file}:${range})`
|
|
16321
16455
|
)}`
|
|
16322
16456
|
);
|
|
@@ -16335,18 +16469,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
16335
16469
|
}
|
|
16336
16470
|
|
|
16337
16471
|
// src/commands/review/warnUnlocated.ts
|
|
16338
|
-
import
|
|
16472
|
+
import chalk162 from "chalk";
|
|
16339
16473
|
function warnUnlocated(unlocated) {
|
|
16340
16474
|
if (unlocated.length === 0) return;
|
|
16341
16475
|
console.warn(
|
|
16342
|
-
|
|
16476
|
+
chalk162.yellow(
|
|
16343
16477
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
16344
16478
|
)
|
|
16345
16479
|
);
|
|
16346
16480
|
for (const finding of unlocated) {
|
|
16347
|
-
const where = finding.location ||
|
|
16481
|
+
const where = finding.location || chalk162.dim("missing");
|
|
16348
16482
|
console.warn(
|
|
16349
|
-
` ${
|
|
16483
|
+
` ${chalk162.yellow("\xB7")} ${finding.title} ${chalk162.dim(`(${where})`)}`
|
|
16350
16484
|
);
|
|
16351
16485
|
}
|
|
16352
16486
|
}
|
|
@@ -17517,7 +17651,7 @@ function registerReview(program2) {
|
|
|
17517
17651
|
}
|
|
17518
17652
|
|
|
17519
17653
|
// src/commands/seq/seqAuth.ts
|
|
17520
|
-
import
|
|
17654
|
+
import chalk164 from "chalk";
|
|
17521
17655
|
|
|
17522
17656
|
// src/commands/seq/loadConnections.ts
|
|
17523
17657
|
function loadConnections2() {
|
|
@@ -17546,10 +17680,10 @@ function setDefaultConnection(name) {
|
|
|
17546
17680
|
}
|
|
17547
17681
|
|
|
17548
17682
|
// src/shared/assertUniqueName.ts
|
|
17549
|
-
import
|
|
17683
|
+
import chalk163 from "chalk";
|
|
17550
17684
|
function assertUniqueName(existingNames, name) {
|
|
17551
17685
|
if (existingNames.includes(name)) {
|
|
17552
|
-
console.error(
|
|
17686
|
+
console.error(chalk163.red(`Connection "${name}" already exists.`));
|
|
17553
17687
|
process.exit(1);
|
|
17554
17688
|
}
|
|
17555
17689
|
}
|
|
@@ -17567,16 +17701,16 @@ async function promptConnection2(existingNames) {
|
|
|
17567
17701
|
var seqAuth = createConnectionAuth({
|
|
17568
17702
|
load: loadConnections2,
|
|
17569
17703
|
save: saveConnections2,
|
|
17570
|
-
format: (c) => `${
|
|
17704
|
+
format: (c) => `${chalk164.bold(c.name)} ${c.url}`,
|
|
17571
17705
|
promptNew: promptConnection2,
|
|
17572
17706
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
17573
17707
|
});
|
|
17574
17708
|
|
|
17575
17709
|
// src/commands/seq/seqQuery.ts
|
|
17576
|
-
import
|
|
17710
|
+
import chalk168 from "chalk";
|
|
17577
17711
|
|
|
17578
17712
|
// src/commands/seq/fetchSeq.ts
|
|
17579
|
-
import
|
|
17713
|
+
import chalk165 from "chalk";
|
|
17580
17714
|
async function fetchSeq(conn, path57, params) {
|
|
17581
17715
|
const url = `${conn.url}${path57}?${params}`;
|
|
17582
17716
|
const response = await fetch(url, {
|
|
@@ -17587,7 +17721,7 @@ async function fetchSeq(conn, path57, params) {
|
|
|
17587
17721
|
});
|
|
17588
17722
|
if (!response.ok) {
|
|
17589
17723
|
const body = await response.text();
|
|
17590
|
-
console.error(
|
|
17724
|
+
console.error(chalk165.red(`Seq returned ${response.status}: ${body}`));
|
|
17591
17725
|
process.exit(1);
|
|
17592
17726
|
}
|
|
17593
17727
|
return response;
|
|
@@ -17646,23 +17780,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
17646
17780
|
}
|
|
17647
17781
|
|
|
17648
17782
|
// src/commands/seq/formatEvent.ts
|
|
17649
|
-
import
|
|
17783
|
+
import chalk166 from "chalk";
|
|
17650
17784
|
function levelColor(level) {
|
|
17651
17785
|
switch (level) {
|
|
17652
17786
|
case "Fatal":
|
|
17653
|
-
return
|
|
17787
|
+
return chalk166.bgRed.white;
|
|
17654
17788
|
case "Error":
|
|
17655
|
-
return
|
|
17789
|
+
return chalk166.red;
|
|
17656
17790
|
case "Warning":
|
|
17657
|
-
return
|
|
17791
|
+
return chalk166.yellow;
|
|
17658
17792
|
case "Information":
|
|
17659
|
-
return
|
|
17793
|
+
return chalk166.cyan;
|
|
17660
17794
|
case "Debug":
|
|
17661
|
-
return
|
|
17795
|
+
return chalk166.gray;
|
|
17662
17796
|
case "Verbose":
|
|
17663
|
-
return
|
|
17797
|
+
return chalk166.dim;
|
|
17664
17798
|
default:
|
|
17665
|
-
return
|
|
17799
|
+
return chalk166.white;
|
|
17666
17800
|
}
|
|
17667
17801
|
}
|
|
17668
17802
|
function levelAbbrev(level) {
|
|
@@ -17703,12 +17837,12 @@ function formatTimestamp(iso) {
|
|
|
17703
17837
|
function formatEvent(event) {
|
|
17704
17838
|
const color = levelColor(event.Level);
|
|
17705
17839
|
const abbrev = levelAbbrev(event.Level);
|
|
17706
|
-
const ts8 =
|
|
17840
|
+
const ts8 = chalk166.dim(formatTimestamp(event.Timestamp));
|
|
17707
17841
|
const msg = renderMessage(event);
|
|
17708
17842
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
17709
17843
|
if (event.Exception) {
|
|
17710
17844
|
for (const line of event.Exception.split("\n")) {
|
|
17711
|
-
lines.push(
|
|
17845
|
+
lines.push(chalk166.red(` ${line}`));
|
|
17712
17846
|
}
|
|
17713
17847
|
}
|
|
17714
17848
|
return lines.join("\n");
|
|
@@ -17741,11 +17875,11 @@ function rejectTimestampFilter(filter) {
|
|
|
17741
17875
|
}
|
|
17742
17876
|
|
|
17743
17877
|
// src/shared/resolveNamedConnection.ts
|
|
17744
|
-
import
|
|
17878
|
+
import chalk167 from "chalk";
|
|
17745
17879
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
17746
17880
|
if (connections.length === 0) {
|
|
17747
17881
|
console.error(
|
|
17748
|
-
|
|
17882
|
+
chalk167.red(
|
|
17749
17883
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
17750
17884
|
)
|
|
17751
17885
|
);
|
|
@@ -17754,7 +17888,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
17754
17888
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
17755
17889
|
const connection = connections.find((c) => c.name === target);
|
|
17756
17890
|
if (!connection) {
|
|
17757
|
-
console.error(
|
|
17891
|
+
console.error(chalk167.red(`${kind} connection "${target}" not found.`));
|
|
17758
17892
|
process.exit(1);
|
|
17759
17893
|
}
|
|
17760
17894
|
return connection;
|
|
@@ -17783,7 +17917,7 @@ async function seqQuery(filter, options2) {
|
|
|
17783
17917
|
new URLSearchParams({ filter, count: String(count6) })
|
|
17784
17918
|
);
|
|
17785
17919
|
if (events.length === 0) {
|
|
17786
|
-
console.log(
|
|
17920
|
+
console.log(chalk168.yellow("No events found."));
|
|
17787
17921
|
return;
|
|
17788
17922
|
}
|
|
17789
17923
|
if (options2.json) {
|
|
@@ -17794,11 +17928,11 @@ async function seqQuery(filter, options2) {
|
|
|
17794
17928
|
for (const event of chronological) {
|
|
17795
17929
|
console.log(formatEvent(event));
|
|
17796
17930
|
}
|
|
17797
|
-
console.log(
|
|
17931
|
+
console.log(chalk168.dim(`
|
|
17798
17932
|
${events.length} events`));
|
|
17799
17933
|
if (events.length >= count6) {
|
|
17800
17934
|
console.log(
|
|
17801
|
-
|
|
17935
|
+
chalk168.yellow(
|
|
17802
17936
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
17803
17937
|
)
|
|
17804
17938
|
);
|
|
@@ -17806,10 +17940,10 @@ ${events.length} events`));
|
|
|
17806
17940
|
}
|
|
17807
17941
|
|
|
17808
17942
|
// src/shared/setNamedDefaultConnection.ts
|
|
17809
|
-
import
|
|
17943
|
+
import chalk169 from "chalk";
|
|
17810
17944
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
17811
17945
|
if (!connections.find((c) => c.name === name)) {
|
|
17812
|
-
console.error(
|
|
17946
|
+
console.error(chalk169.red(`Connection "${name}" not found.`));
|
|
17813
17947
|
process.exit(1);
|
|
17814
17948
|
}
|
|
17815
17949
|
setDefault(name);
|
|
@@ -17857,7 +17991,7 @@ function registerSignal(program2) {
|
|
|
17857
17991
|
}
|
|
17858
17992
|
|
|
17859
17993
|
// src/commands/sql/sqlAuth.ts
|
|
17860
|
-
import
|
|
17994
|
+
import chalk171 from "chalk";
|
|
17861
17995
|
|
|
17862
17996
|
// src/commands/sql/loadConnections.ts
|
|
17863
17997
|
function loadConnections3() {
|
|
@@ -17886,7 +18020,7 @@ function setDefaultConnection2(name) {
|
|
|
17886
18020
|
}
|
|
17887
18021
|
|
|
17888
18022
|
// src/commands/sql/promptConnection.ts
|
|
17889
|
-
import
|
|
18023
|
+
import chalk170 from "chalk";
|
|
17890
18024
|
async function promptConnection3(existingNames) {
|
|
17891
18025
|
const name = await promptInput("name", "Connection name:", "default");
|
|
17892
18026
|
assertUniqueName(existingNames, name);
|
|
@@ -17894,7 +18028,7 @@ async function promptConnection3(existingNames) {
|
|
|
17894
18028
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
17895
18029
|
const port = Number.parseInt(portStr, 10);
|
|
17896
18030
|
if (!Number.isFinite(port)) {
|
|
17897
|
-
console.error(
|
|
18031
|
+
console.error(chalk170.red(`Invalid port "${portStr}".`));
|
|
17898
18032
|
process.exit(1);
|
|
17899
18033
|
}
|
|
17900
18034
|
const user = await promptInput("user", "User:");
|
|
@@ -17907,13 +18041,13 @@ async function promptConnection3(existingNames) {
|
|
|
17907
18041
|
var sqlAuth = createConnectionAuth({
|
|
17908
18042
|
load: loadConnections3,
|
|
17909
18043
|
save: saveConnections3,
|
|
17910
|
-
format: (c) => `${
|
|
18044
|
+
format: (c) => `${chalk171.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
17911
18045
|
promptNew: promptConnection3,
|
|
17912
18046
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
17913
18047
|
});
|
|
17914
18048
|
|
|
17915
18049
|
// src/commands/sql/printTable.ts
|
|
17916
|
-
import
|
|
18050
|
+
import chalk172 from "chalk";
|
|
17917
18051
|
function formatCell(value) {
|
|
17918
18052
|
if (value === null || value === void 0) return "";
|
|
17919
18053
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -17922,7 +18056,7 @@ function formatCell(value) {
|
|
|
17922
18056
|
}
|
|
17923
18057
|
function printTable(rows) {
|
|
17924
18058
|
if (rows.length === 0) {
|
|
17925
|
-
console.log(
|
|
18059
|
+
console.log(chalk172.yellow("(no rows)"));
|
|
17926
18060
|
return;
|
|
17927
18061
|
}
|
|
17928
18062
|
const columns = Object.keys(rows[0]);
|
|
@@ -17930,13 +18064,13 @@ function printTable(rows) {
|
|
|
17930
18064
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
17931
18065
|
);
|
|
17932
18066
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
17933
|
-
console.log(
|
|
17934
|
-
console.log(
|
|
18067
|
+
console.log(chalk172.dim(header));
|
|
18068
|
+
console.log(chalk172.dim("-".repeat(header.length)));
|
|
17935
18069
|
for (const row of rows) {
|
|
17936
18070
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
17937
18071
|
console.log(line);
|
|
17938
18072
|
}
|
|
17939
|
-
console.log(
|
|
18073
|
+
console.log(chalk172.dim(`
|
|
17940
18074
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
17941
18075
|
}
|
|
17942
18076
|
|
|
@@ -17996,7 +18130,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
17996
18130
|
}
|
|
17997
18131
|
|
|
17998
18132
|
// src/commands/sql/sqlMutate.ts
|
|
17999
|
-
import
|
|
18133
|
+
import chalk173 from "chalk";
|
|
18000
18134
|
|
|
18001
18135
|
// src/commands/sql/isMutation.ts
|
|
18002
18136
|
var MUTATION_KEYWORDS = [
|
|
@@ -18030,7 +18164,7 @@ function isMutation(sql6) {
|
|
|
18030
18164
|
async function sqlMutate(query, connectionName) {
|
|
18031
18165
|
if (!isMutation(query)) {
|
|
18032
18166
|
console.error(
|
|
18033
|
-
|
|
18167
|
+
chalk173.red(
|
|
18034
18168
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
18035
18169
|
)
|
|
18036
18170
|
);
|
|
@@ -18040,18 +18174,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
18040
18174
|
const pool = await sqlConnect(conn);
|
|
18041
18175
|
try {
|
|
18042
18176
|
const result = await pool.request().query(query);
|
|
18043
|
-
console.log(
|
|
18177
|
+
console.log(chalk173.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
18044
18178
|
} finally {
|
|
18045
18179
|
await pool.close();
|
|
18046
18180
|
}
|
|
18047
18181
|
}
|
|
18048
18182
|
|
|
18049
18183
|
// src/commands/sql/sqlQuery.ts
|
|
18050
|
-
import
|
|
18184
|
+
import chalk174 from "chalk";
|
|
18051
18185
|
async function sqlQuery(query, connectionName) {
|
|
18052
18186
|
if (isMutation(query)) {
|
|
18053
18187
|
console.error(
|
|
18054
|
-
|
|
18188
|
+
chalk174.red(
|
|
18055
18189
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
18056
18190
|
)
|
|
18057
18191
|
);
|
|
@@ -18066,7 +18200,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
18066
18200
|
printTable(rows);
|
|
18067
18201
|
} else {
|
|
18068
18202
|
console.log(
|
|
18069
|
-
|
|
18203
|
+
chalk174.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
18070
18204
|
);
|
|
18071
18205
|
}
|
|
18072
18206
|
} finally {
|
|
@@ -18646,14 +18780,14 @@ import {
|
|
|
18646
18780
|
import { dirname as dirname24, join as join50 } from "path";
|
|
18647
18781
|
|
|
18648
18782
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
18649
|
-
import
|
|
18783
|
+
import chalk175 from "chalk";
|
|
18650
18784
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
18651
18785
|
function validateStagedContent(filename, content) {
|
|
18652
18786
|
const firstLine = content.split("\n")[0];
|
|
18653
18787
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
18654
18788
|
if (!match) {
|
|
18655
18789
|
console.error(
|
|
18656
|
-
|
|
18790
|
+
chalk175.red(
|
|
18657
18791
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
18658
18792
|
)
|
|
18659
18793
|
);
|
|
@@ -18662,7 +18796,7 @@ function validateStagedContent(filename, content) {
|
|
|
18662
18796
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
18663
18797
|
if (!contentAfterLink) {
|
|
18664
18798
|
console.error(
|
|
18665
|
-
|
|
18799
|
+
chalk175.red(
|
|
18666
18800
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
18667
18801
|
)
|
|
18668
18802
|
);
|
|
@@ -19064,7 +19198,7 @@ function registerVoice(program2) {
|
|
|
19064
19198
|
|
|
19065
19199
|
// src/commands/roam/auth.ts
|
|
19066
19200
|
import { randomBytes } from "crypto";
|
|
19067
|
-
import
|
|
19201
|
+
import chalk176 from "chalk";
|
|
19068
19202
|
|
|
19069
19203
|
// src/commands/roam/waitForCallback.ts
|
|
19070
19204
|
import { createServer as createServer3 } from "http";
|
|
@@ -19195,13 +19329,13 @@ async function auth() {
|
|
|
19195
19329
|
saveGlobalConfig(config);
|
|
19196
19330
|
const state = randomBytes(16).toString("hex");
|
|
19197
19331
|
console.log(
|
|
19198
|
-
|
|
19332
|
+
chalk176.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
19199
19333
|
);
|
|
19200
|
-
console.log(
|
|
19201
|
-
console.log(
|
|
19202
|
-
console.log(
|
|
19334
|
+
console.log(chalk176.white("http://localhost:14523/callback\n"));
|
|
19335
|
+
console.log(chalk176.blue("Opening browser for authorization..."));
|
|
19336
|
+
console.log(chalk176.dim("Waiting for authorization callback..."));
|
|
19203
19337
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
19204
|
-
console.log(
|
|
19338
|
+
console.log(chalk176.dim("Exchanging code for tokens..."));
|
|
19205
19339
|
const tokens = await exchangeToken({
|
|
19206
19340
|
code,
|
|
19207
19341
|
clientId,
|
|
@@ -19217,7 +19351,7 @@ async function auth() {
|
|
|
19217
19351
|
};
|
|
19218
19352
|
saveGlobalConfig(config);
|
|
19219
19353
|
console.log(
|
|
19220
|
-
|
|
19354
|
+
chalk176.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
19221
19355
|
);
|
|
19222
19356
|
}
|
|
19223
19357
|
|
|
@@ -19669,7 +19803,7 @@ import { execSync as execSync50 } from "child_process";
|
|
|
19669
19803
|
import { existsSync as existsSync51, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync37 } from "fs";
|
|
19670
19804
|
import { tmpdir as tmpdir7 } from "os";
|
|
19671
19805
|
import { join as join61, resolve as resolve15 } from "path";
|
|
19672
|
-
import
|
|
19806
|
+
import chalk177 from "chalk";
|
|
19673
19807
|
|
|
19674
19808
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
19675
19809
|
var captureWindowPs1 = `
|
|
@@ -19820,13 +19954,13 @@ function screenshot(processName) {
|
|
|
19820
19954
|
const config = loadConfig();
|
|
19821
19955
|
const outputDir = resolve15(config.screenshot.outputDir);
|
|
19822
19956
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
19823
|
-
console.log(
|
|
19957
|
+
console.log(chalk177.gray(`Capturing window for process "${processName}" ...`));
|
|
19824
19958
|
try {
|
|
19825
19959
|
runPowerShellScript(processName, outputPath);
|
|
19826
|
-
console.log(
|
|
19960
|
+
console.log(chalk177.green(`Screenshot saved: ${outputPath}`));
|
|
19827
19961
|
} catch (error) {
|
|
19828
19962
|
const msg = error instanceof Error ? error.message : String(error);
|
|
19829
|
-
console.error(
|
|
19963
|
+
console.error(chalk177.red(`Failed to capture screenshot: ${msg}`));
|
|
19830
19964
|
process.exit(1);
|
|
19831
19965
|
}
|
|
19832
19966
|
}
|
|
@@ -21398,12 +21532,12 @@ import * as net3 from "net";
|
|
|
21398
21532
|
import { createInterface as createInterface8 } from "readline";
|
|
21399
21533
|
|
|
21400
21534
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
21401
|
-
import * as
|
|
21535
|
+
import * as fs31 from "fs";
|
|
21402
21536
|
import * as os from "os";
|
|
21403
21537
|
import * as path51 from "path";
|
|
21404
21538
|
|
|
21405
21539
|
// src/commands/sessions/shared/parseSessionFile.ts
|
|
21406
|
-
import * as
|
|
21540
|
+
import * as fs30 from "fs";
|
|
21407
21541
|
import * as path50 from "path";
|
|
21408
21542
|
|
|
21409
21543
|
// src/commands/sessions/shared/deriveHistoryFields.ts
|
|
@@ -21493,10 +21627,10 @@ function matchMarker(text6, tag) {
|
|
|
21493
21627
|
async function parseSessionFile(filePath, origin = "wsl") {
|
|
21494
21628
|
let handle;
|
|
21495
21629
|
try {
|
|
21496
|
-
handle = await
|
|
21630
|
+
handle = await fs30.promises.open(filePath, "r");
|
|
21497
21631
|
const meta = extractSessionMeta(await readHeadLines(handle));
|
|
21498
21632
|
if (!meta.sessionId) return null;
|
|
21499
|
-
const timestamp4 = meta.timestamp || (await
|
|
21633
|
+
const timestamp4 = meta.timestamp || (await fs30.promises.stat(filePath)).mtime.toISOString();
|
|
21500
21634
|
return {
|
|
21501
21635
|
sessionId: meta.sessionId,
|
|
21502
21636
|
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
@@ -21542,7 +21676,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
21542
21676
|
sessionRoots().map(async ({ dir, origin }) => {
|
|
21543
21677
|
let projectDirs;
|
|
21544
21678
|
try {
|
|
21545
|
-
projectDirs = await
|
|
21679
|
+
projectDirs = await fs31.promises.readdir(dir);
|
|
21546
21680
|
} catch {
|
|
21547
21681
|
return;
|
|
21548
21682
|
}
|
|
@@ -21551,7 +21685,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
21551
21685
|
const dirPath = path51.join(dir, dirName);
|
|
21552
21686
|
let entries;
|
|
21553
21687
|
try {
|
|
21554
|
-
entries = await
|
|
21688
|
+
entries = await fs31.promises.readdir(dirPath);
|
|
21555
21689
|
} catch {
|
|
21556
21690
|
return;
|
|
21557
21691
|
}
|
|
@@ -21584,7 +21718,7 @@ async function discoverSessions() {
|
|
|
21584
21718
|
}
|
|
21585
21719
|
|
|
21586
21720
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
21587
|
-
import * as
|
|
21721
|
+
import * as fs32 from "fs";
|
|
21588
21722
|
|
|
21589
21723
|
// src/commands/sessions/shared/toolTarget.ts
|
|
21590
21724
|
function toolTarget(input) {
|
|
@@ -21651,7 +21785,7 @@ async function parseTranscript(sessionId) {
|
|
|
21651
21785
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
21652
21786
|
if (!filePath) return [];
|
|
21653
21787
|
try {
|
|
21654
|
-
const raw = await
|
|
21788
|
+
const raw = await fs32.promises.readFile(filePath, "utf8");
|
|
21655
21789
|
return parseTranscriptLines(raw.split("\n"));
|
|
21656
21790
|
} catch {
|
|
21657
21791
|
return [];
|
|
@@ -21932,17 +22066,17 @@ function registerDaemon(program2) {
|
|
|
21932
22066
|
}
|
|
21933
22067
|
|
|
21934
22068
|
// src/commands/sessions/summarise/index.ts
|
|
21935
|
-
import * as
|
|
21936
|
-
import
|
|
22069
|
+
import * as fs35 from "fs";
|
|
22070
|
+
import chalk178 from "chalk";
|
|
21937
22071
|
|
|
21938
22072
|
// src/commands/sessions/summarise/shared.ts
|
|
21939
|
-
import * as
|
|
22073
|
+
import * as fs33 from "fs";
|
|
21940
22074
|
function writeSummary(jsonlPath2, summary) {
|
|
21941
|
-
|
|
22075
|
+
fs33.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
21942
22076
|
`, "utf8");
|
|
21943
22077
|
}
|
|
21944
22078
|
function hasSummary(jsonlPath2) {
|
|
21945
|
-
return
|
|
22079
|
+
return fs33.existsSync(summaryPathFor(jsonlPath2));
|
|
21946
22080
|
}
|
|
21947
22081
|
function summaryPathFor(jsonlPath2) {
|
|
21948
22082
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -21952,7 +22086,7 @@ function summaryPathFor(jsonlPath2) {
|
|
|
21952
22086
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
21953
22087
|
|
|
21954
22088
|
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
21955
|
-
import * as
|
|
22089
|
+
import * as fs34 from "fs";
|
|
21956
22090
|
|
|
21957
22091
|
// src/commands/sessions/summarise/parseUserLine.ts
|
|
21958
22092
|
function parseUserLine(line) {
|
|
@@ -21983,13 +22117,13 @@ function parseUserLine(line) {
|
|
|
21983
22117
|
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
21984
22118
|
let content;
|
|
21985
22119
|
try {
|
|
21986
|
-
const fd =
|
|
22120
|
+
const fd = fs34.openSync(filePath, "r");
|
|
21987
22121
|
try {
|
|
21988
22122
|
const buf = Buffer.alloc(maxBytes);
|
|
21989
|
-
const bytesRead =
|
|
22123
|
+
const bytesRead = fs34.readSync(fd, buf, 0, buf.length, 0);
|
|
21990
22124
|
content = buf.toString("utf8", 0, bytesRead);
|
|
21991
22125
|
} finally {
|
|
21992
|
-
|
|
22126
|
+
fs34.closeSync(fd);
|
|
21993
22127
|
}
|
|
21994
22128
|
} catch {
|
|
21995
22129
|
return;
|
|
@@ -22087,29 +22221,29 @@ ${firstMessage}`);
|
|
|
22087
22221
|
async function summarise3(options2) {
|
|
22088
22222
|
const files = await discoverSessionFiles();
|
|
22089
22223
|
if (files.length === 0) {
|
|
22090
|
-
console.log(
|
|
22224
|
+
console.log(chalk178.yellow("No sessions found."));
|
|
22091
22225
|
return;
|
|
22092
22226
|
}
|
|
22093
22227
|
const toProcess = selectCandidates(files, options2);
|
|
22094
22228
|
if (toProcess.length === 0) {
|
|
22095
|
-
console.log(
|
|
22229
|
+
console.log(chalk178.green("All sessions already summarised."));
|
|
22096
22230
|
return;
|
|
22097
22231
|
}
|
|
22098
22232
|
console.log(
|
|
22099
|
-
|
|
22233
|
+
chalk178.cyan(
|
|
22100
22234
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
22101
22235
|
)
|
|
22102
22236
|
);
|
|
22103
22237
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
22104
22238
|
console.log(
|
|
22105
|
-
|
|
22239
|
+
chalk178.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk178.yellow(`, ${failed2} skipped`) : "")
|
|
22106
22240
|
);
|
|
22107
22241
|
}
|
|
22108
22242
|
function selectCandidates(files, options2) {
|
|
22109
22243
|
const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
|
|
22110
22244
|
candidates.sort((a, b) => {
|
|
22111
22245
|
try {
|
|
22112
|
-
return
|
|
22246
|
+
return fs35.statSync(b).mtimeMs - fs35.statSync(a).mtimeMs;
|
|
22113
22247
|
} catch {
|
|
22114
22248
|
return 0;
|
|
22115
22249
|
}
|
|
@@ -22122,16 +22256,16 @@ function processSessions(files) {
|
|
|
22122
22256
|
let failed2 = 0;
|
|
22123
22257
|
for (let i = 0; i < files.length; i++) {
|
|
22124
22258
|
const file = files[i];
|
|
22125
|
-
process.stdout.write(
|
|
22259
|
+
process.stdout.write(chalk178.dim(` [${i + 1}/${files.length}] `));
|
|
22126
22260
|
const summary = summariseSession(file);
|
|
22127
22261
|
if (summary) {
|
|
22128
22262
|
writeSummary(file, summary);
|
|
22129
22263
|
succeeded++;
|
|
22130
|
-
process.stdout.write(`${
|
|
22264
|
+
process.stdout.write(`${chalk178.green("\u2713")} ${summary}
|
|
22131
22265
|
`);
|
|
22132
22266
|
} else {
|
|
22133
22267
|
failed2++;
|
|
22134
|
-
process.stdout.write(` ${
|
|
22268
|
+
process.stdout.write(` ${chalk178.yellow("skip")}
|
|
22135
22269
|
`);
|
|
22136
22270
|
}
|
|
22137
22271
|
}
|
|
@@ -22149,10 +22283,10 @@ function registerSessions(program2) {
|
|
|
22149
22283
|
}
|
|
22150
22284
|
|
|
22151
22285
|
// src/commands/statusLine.ts
|
|
22152
|
-
import
|
|
22286
|
+
import chalk180 from "chalk";
|
|
22153
22287
|
|
|
22154
22288
|
// src/commands/buildLimitsSegment.ts
|
|
22155
|
-
import
|
|
22289
|
+
import chalk179 from "chalk";
|
|
22156
22290
|
|
|
22157
22291
|
// src/shared/rateLimitLevel.ts
|
|
22158
22292
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -22183,9 +22317,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
22183
22317
|
|
|
22184
22318
|
// src/commands/buildLimitsSegment.ts
|
|
22185
22319
|
var LEVEL_COLOR = {
|
|
22186
|
-
ok:
|
|
22187
|
-
warn:
|
|
22188
|
-
over:
|
|
22320
|
+
ok: chalk179.green,
|
|
22321
|
+
warn: chalk179.yellow,
|
|
22322
|
+
over: chalk179.red
|
|
22189
22323
|
};
|
|
22190
22324
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
22191
22325
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -22225,14 +22359,14 @@ async function relayRateLimits(rateLimits) {
|
|
|
22225
22359
|
}
|
|
22226
22360
|
|
|
22227
22361
|
// src/commands/statusLine.ts
|
|
22228
|
-
|
|
22362
|
+
chalk180.level = 3;
|
|
22229
22363
|
function formatNumber(num) {
|
|
22230
22364
|
return num.toLocaleString("en-US");
|
|
22231
22365
|
}
|
|
22232
22366
|
function colorizePercent(pct) {
|
|
22233
22367
|
const label2 = `${Math.round(pct)}%`;
|
|
22234
|
-
if (pct > 80) return
|
|
22235
|
-
if (pct > 40) return
|
|
22368
|
+
if (pct > 80) return chalk180.red(label2);
|
|
22369
|
+
if (pct > 40) return chalk180.yellow(label2);
|
|
22236
22370
|
return label2;
|
|
22237
22371
|
}
|
|
22238
22372
|
async function statusLine() {
|
|
@@ -22248,29 +22382,29 @@ async function statusLine() {
|
|
|
22248
22382
|
}
|
|
22249
22383
|
|
|
22250
22384
|
// src/commands/sync.ts
|
|
22251
|
-
import * as
|
|
22385
|
+
import * as fs38 from "fs";
|
|
22252
22386
|
import * as os2 from "os";
|
|
22253
22387
|
import * as path55 from "path";
|
|
22254
22388
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
22255
22389
|
|
|
22256
22390
|
// src/commands/sync/syncClaudeMd.ts
|
|
22257
|
-
import * as
|
|
22391
|
+
import * as fs36 from "fs";
|
|
22258
22392
|
import * as path53 from "path";
|
|
22259
|
-
import
|
|
22393
|
+
import chalk181 from "chalk";
|
|
22260
22394
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
22261
22395
|
const source = path53.join(claudeDir, "CLAUDE.md");
|
|
22262
22396
|
const target = path53.join(targetBase, "CLAUDE.md");
|
|
22263
|
-
const sourceContent =
|
|
22264
|
-
if (
|
|
22265
|
-
const targetContent =
|
|
22397
|
+
const sourceContent = fs36.readFileSync(source, "utf8");
|
|
22398
|
+
if (fs36.existsSync(target)) {
|
|
22399
|
+
const targetContent = fs36.readFileSync(target, "utf8");
|
|
22266
22400
|
if (sourceContent !== targetContent) {
|
|
22267
22401
|
console.log(
|
|
22268
|
-
|
|
22402
|
+
chalk181.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
22269
22403
|
);
|
|
22270
22404
|
console.log();
|
|
22271
22405
|
printDiff(targetContent, sourceContent);
|
|
22272
22406
|
const confirm = options2?.yes || await promptConfirm(
|
|
22273
|
-
|
|
22407
|
+
chalk181.red("Overwrite existing CLAUDE.md?"),
|
|
22274
22408
|
false
|
|
22275
22409
|
);
|
|
22276
22410
|
if (!confirm) {
|
|
@@ -22279,21 +22413,21 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22279
22413
|
}
|
|
22280
22414
|
}
|
|
22281
22415
|
}
|
|
22282
|
-
|
|
22416
|
+
fs36.copyFileSync(source, target);
|
|
22283
22417
|
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
22284
22418
|
}
|
|
22285
22419
|
|
|
22286
22420
|
// src/commands/sync/syncSettings.ts
|
|
22287
|
-
import * as
|
|
22421
|
+
import * as fs37 from "fs";
|
|
22288
22422
|
import * as path54 from "path";
|
|
22289
|
-
import
|
|
22423
|
+
import chalk182 from "chalk";
|
|
22290
22424
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
22291
22425
|
const source = path54.join(claudeDir, "settings.json");
|
|
22292
22426
|
const target = path54.join(targetBase, "settings.json");
|
|
22293
|
-
const sourceContent =
|
|
22427
|
+
const sourceContent = fs37.readFileSync(source, "utf8");
|
|
22294
22428
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
22295
|
-
if (
|
|
22296
|
-
const targetContent =
|
|
22429
|
+
if (fs37.existsSync(target)) {
|
|
22430
|
+
const targetContent = fs37.readFileSync(target, "utf8");
|
|
22297
22431
|
const normalizedTarget = JSON.stringify(
|
|
22298
22432
|
JSON.parse(targetContent),
|
|
22299
22433
|
null,
|
|
@@ -22302,14 +22436,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
22302
22436
|
if (mergedContent !== normalizedTarget) {
|
|
22303
22437
|
if (!options2?.yes) {
|
|
22304
22438
|
console.log(
|
|
22305
|
-
|
|
22439
|
+
chalk182.yellow(
|
|
22306
22440
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
22307
22441
|
)
|
|
22308
22442
|
);
|
|
22309
22443
|
console.log();
|
|
22310
22444
|
printDiff(targetContent, mergedContent);
|
|
22311
22445
|
const confirm = await promptConfirm(
|
|
22312
|
-
|
|
22446
|
+
chalk182.red("Overwrite existing settings.json?"),
|
|
22313
22447
|
false
|
|
22314
22448
|
);
|
|
22315
22449
|
if (!confirm) {
|
|
@@ -22319,7 +22453,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
22319
22453
|
}
|
|
22320
22454
|
}
|
|
22321
22455
|
}
|
|
22322
|
-
|
|
22456
|
+
fs37.writeFileSync(target, mergedContent);
|
|
22323
22457
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
22324
22458
|
}
|
|
22325
22459
|
|
|
@@ -22338,10 +22472,10 @@ async function sync(options2) {
|
|
|
22338
22472
|
function syncCommands(claudeDir, targetBase) {
|
|
22339
22473
|
const sourceDir = path55.join(claudeDir, "commands");
|
|
22340
22474
|
const targetDir = path55.join(targetBase, "commands");
|
|
22341
|
-
|
|
22342
|
-
const files =
|
|
22475
|
+
fs38.mkdirSync(targetDir, { recursive: true });
|
|
22476
|
+
const files = fs38.readdirSync(sourceDir);
|
|
22343
22477
|
for (const file of files) {
|
|
22344
|
-
|
|
22478
|
+
fs38.copyFileSync(path55.join(sourceDir, file), path55.join(targetDir, file));
|
|
22345
22479
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
22346
22480
|
}
|
|
22347
22481
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -22427,6 +22561,7 @@ program.command("screenshot").description("Capture a screenshot of a running app
|
|
|
22427
22561
|
registerActivity(program);
|
|
22428
22562
|
registerBackup(program);
|
|
22429
22563
|
registerCliHook(program);
|
|
22564
|
+
registerEditHook(program);
|
|
22430
22565
|
registerGithub(program);
|
|
22431
22566
|
registerHandover(program);
|
|
22432
22567
|
registerJira(program);
|