@staff0rd/assist 0.319.0 → 0.321.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 +2 -1
- package/claude/CLAUDE.md +1 -1
- package/claude/settings.json +4 -0
- package/dist/index.js +642 -470
- 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.321.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,94 @@ 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 = override !== void 0 ? chalk95.magenta(` (override: ${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: N)" 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
|
-
|
|
9733
|
+
const passingOverrides = results.filter(
|
|
9734
|
+
(r) => r.override !== void 0 && !failing.includes(r)
|
|
9735
|
+
);
|
|
9736
|
+
for (const entry of passingOverrides)
|
|
9737
|
+
console.log(formatResultLine(entry, false));
|
|
9738
|
+
console.log(chalk97.dim(`
|
|
9696
9739
|
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
|
-
);
|
|
9740
|
+
if (failing.length > 0) {
|
|
9741
|
+
printMaintainabilityFailure(failing.length, threshold);
|
|
9706
9742
|
process.exit(1);
|
|
9707
9743
|
}
|
|
9708
9744
|
}
|
|
9709
9745
|
|
|
9710
9746
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
9711
|
-
import
|
|
9747
|
+
import chalk98 from "chalk";
|
|
9712
9748
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
9713
9749
|
function printMaintainabilityFormula() {
|
|
9714
|
-
console.log(
|
|
9750
|
+
console.log(chalk98.dim(MI_FORMULA));
|
|
9715
9751
|
}
|
|
9716
9752
|
|
|
9717
|
-
// src/commands/complexity/maintainability/
|
|
9753
|
+
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
9754
|
+
import fs17 from "fs";
|
|
9755
|
+
|
|
9756
|
+
// src/commands/complexity/maintainability/calculateMaintainabilityIndex.ts
|
|
9757
|
+
function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
|
|
9758
|
+
if (halsteadVolume === 0 || sloc2 === 0) {
|
|
9759
|
+
return 100;
|
|
9760
|
+
}
|
|
9761
|
+
const mi = 171 - 5.2 * Math.log(halsteadVolume) - 0.23 * cyclomaticComplexity - 16.2 * Math.log(sloc2);
|
|
9762
|
+
return Math.max(0, Math.min(100, mi));
|
|
9763
|
+
}
|
|
9764
|
+
|
|
9765
|
+
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
9718
9766
|
function collectFileMetrics(files) {
|
|
9719
9767
|
const fileMetrics = /* @__PURE__ */ new Map();
|
|
9720
9768
|
for (const file of files) {
|
|
9721
9769
|
const content = fs17.readFileSync(file, "utf8");
|
|
9722
|
-
fileMetrics.set(file, {
|
|
9770
|
+
fileMetrics.set(file, {
|
|
9771
|
+
sloc: countSloc(content),
|
|
9772
|
+
functions: [],
|
|
9773
|
+
override: parseMaintainabilityOverride(content)
|
|
9774
|
+
});
|
|
9723
9775
|
}
|
|
9724
9776
|
forEachFunction(files, (file, _name, node) => {
|
|
9725
9777
|
const metrics = fileMetrics.get(file);
|
|
@@ -9736,17 +9788,26 @@ function collectFileMetrics(files) {
|
|
|
9736
9788
|
});
|
|
9737
9789
|
return fileMetrics;
|
|
9738
9790
|
}
|
|
9791
|
+
|
|
9792
|
+
// src/commands/complexity/maintainability/aggregateResults.ts
|
|
9739
9793
|
function aggregateResults(fileMetrics) {
|
|
9740
9794
|
const results = [];
|
|
9741
9795
|
for (const [file, metrics] of fileMetrics) {
|
|
9742
9796
|
if (metrics.functions.length === 0) continue;
|
|
9743
9797
|
const avgMaintainability = metrics.functions.reduce((a, b) => a + b, 0) / metrics.functions.length;
|
|
9744
9798
|
const minMaintainability = Math.min(...metrics.functions);
|
|
9745
|
-
results.push({
|
|
9799
|
+
results.push({
|
|
9800
|
+
file,
|
|
9801
|
+
avgMaintainability,
|
|
9802
|
+
minMaintainability,
|
|
9803
|
+
override: metrics.override
|
|
9804
|
+
});
|
|
9746
9805
|
}
|
|
9747
9806
|
results.sort((a, b) => a.minMaintainability - b.minMaintainability);
|
|
9748
9807
|
return results;
|
|
9749
9808
|
}
|
|
9809
|
+
|
|
9810
|
+
// src/commands/complexity/maintainability/index.ts
|
|
9750
9811
|
async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
9751
9812
|
printMaintainabilityFormula();
|
|
9752
9813
|
withSourceFiles(
|
|
@@ -9762,7 +9823,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9762
9823
|
|
|
9763
9824
|
// src/commands/complexity/sloc.ts
|
|
9764
9825
|
import fs18 from "fs";
|
|
9765
|
-
import
|
|
9826
|
+
import chalk99 from "chalk";
|
|
9766
9827
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
9767
9828
|
withSourceFiles(pattern2, (files) => {
|
|
9768
9829
|
const results = [];
|
|
@@ -9778,12 +9839,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9778
9839
|
results.sort((a, b) => b.lines - a.lines);
|
|
9779
9840
|
for (const { file, lines } of results) {
|
|
9780
9841
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
9781
|
-
const color = exceedsThreshold ?
|
|
9782
|
-
console.log(`${color(file)} \u2192 ${
|
|
9842
|
+
const color = exceedsThreshold ? chalk99.red : chalk99.white;
|
|
9843
|
+
console.log(`${color(file)} \u2192 ${chalk99.cyan(lines)} lines`);
|
|
9783
9844
|
}
|
|
9784
9845
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
9785
9846
|
console.log(
|
|
9786
|
-
|
|
9847
|
+
chalk99.dim(`
|
|
9787
9848
|
Total: ${total} lines across ${files.length} files`)
|
|
9788
9849
|
);
|
|
9789
9850
|
if (hasViolation) {
|
|
@@ -9797,25 +9858,25 @@ async function analyze(pattern2) {
|
|
|
9797
9858
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
9798
9859
|
const files = findSourceFiles2(searchPattern);
|
|
9799
9860
|
if (files.length === 0) {
|
|
9800
|
-
console.log(
|
|
9861
|
+
console.log(chalk100.yellow("No files found matching pattern"));
|
|
9801
9862
|
return;
|
|
9802
9863
|
}
|
|
9803
9864
|
if (files.length === 1) {
|
|
9804
9865
|
const file = files[0];
|
|
9805
|
-
console.log(
|
|
9866
|
+
console.log(chalk100.bold.underline("SLOC"));
|
|
9806
9867
|
await sloc(file);
|
|
9807
9868
|
console.log();
|
|
9808
|
-
console.log(
|
|
9869
|
+
console.log(chalk100.bold.underline("Cyclomatic Complexity"));
|
|
9809
9870
|
await cyclomatic(file);
|
|
9810
9871
|
console.log();
|
|
9811
|
-
console.log(
|
|
9872
|
+
console.log(chalk100.bold.underline("Halstead Metrics"));
|
|
9812
9873
|
await halstead(file);
|
|
9813
9874
|
console.log();
|
|
9814
|
-
console.log(
|
|
9875
|
+
console.log(chalk100.bold.underline("Maintainability Index"));
|
|
9815
9876
|
await maintainability(file);
|
|
9816
9877
|
console.log();
|
|
9817
9878
|
console.log(
|
|
9818
|
-
|
|
9879
|
+
chalk100.dim(
|
|
9819
9880
|
"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
9881
|
)
|
|
9821
9882
|
);
|
|
@@ -9849,7 +9910,7 @@ function registerComplexity(program2) {
|
|
|
9849
9910
|
}
|
|
9850
9911
|
|
|
9851
9912
|
// src/commands/config/index.ts
|
|
9852
|
-
import
|
|
9913
|
+
import chalk101 from "chalk";
|
|
9853
9914
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
9854
9915
|
|
|
9855
9916
|
// src/commands/config/setNestedValue.ts
|
|
@@ -9912,7 +9973,7 @@ function formatIssuePath(issue, key) {
|
|
|
9912
9973
|
function printValidationErrors(issues, key) {
|
|
9913
9974
|
for (const issue of issues) {
|
|
9914
9975
|
console.error(
|
|
9915
|
-
|
|
9976
|
+
chalk101.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
9916
9977
|
);
|
|
9917
9978
|
}
|
|
9918
9979
|
}
|
|
@@ -9929,7 +9990,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
9929
9990
|
function assertNotGlobalOnly(key, global) {
|
|
9930
9991
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
9931
9992
|
console.error(
|
|
9932
|
-
|
|
9993
|
+
chalk101.red(
|
|
9933
9994
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
9934
9995
|
)
|
|
9935
9996
|
);
|
|
@@ -9952,7 +10013,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
9952
10013
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
9953
10014
|
const target = options2.global ? "global" : "project";
|
|
9954
10015
|
console.log(
|
|
9955
|
-
|
|
10016
|
+
chalk101.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
9956
10017
|
);
|
|
9957
10018
|
}
|
|
9958
10019
|
function configList() {
|
|
@@ -9961,7 +10022,7 @@ function configList() {
|
|
|
9961
10022
|
}
|
|
9962
10023
|
|
|
9963
10024
|
// src/commands/config/configGet.ts
|
|
9964
|
-
import
|
|
10025
|
+
import chalk102 from "chalk";
|
|
9965
10026
|
|
|
9966
10027
|
// src/commands/config/getNestedValue.ts
|
|
9967
10028
|
function isTraversable(value) {
|
|
@@ -9993,7 +10054,7 @@ function requireNestedValue(config, key) {
|
|
|
9993
10054
|
return value;
|
|
9994
10055
|
}
|
|
9995
10056
|
function exitKeyNotSet(key) {
|
|
9996
|
-
console.error(
|
|
10057
|
+
console.error(chalk102.red(`Key "${key}" is not set`));
|
|
9997
10058
|
process.exit(1);
|
|
9998
10059
|
}
|
|
9999
10060
|
|
|
@@ -10007,7 +10068,7 @@ function registerConfig(program2) {
|
|
|
10007
10068
|
|
|
10008
10069
|
// src/commands/deploy/redirect.ts
|
|
10009
10070
|
import { existsSync as existsSync27, readFileSync as readFileSync22, writeFileSync as writeFileSync22 } from "fs";
|
|
10010
|
-
import
|
|
10071
|
+
import chalk103 from "chalk";
|
|
10011
10072
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
10012
10073
|
if (!window.location.pathname.endsWith('/')) {
|
|
10013
10074
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -10016,23 +10077,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
10016
10077
|
function redirect() {
|
|
10017
10078
|
const indexPath = "index.html";
|
|
10018
10079
|
if (!existsSync27(indexPath)) {
|
|
10019
|
-
console.log(
|
|
10080
|
+
console.log(chalk103.yellow("No index.html found"));
|
|
10020
10081
|
return;
|
|
10021
10082
|
}
|
|
10022
10083
|
const content = readFileSync22(indexPath, "utf8");
|
|
10023
10084
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
10024
|
-
console.log(
|
|
10085
|
+
console.log(chalk103.dim("Trailing slash script already present"));
|
|
10025
10086
|
return;
|
|
10026
10087
|
}
|
|
10027
10088
|
const headCloseIndex = content.indexOf("</head>");
|
|
10028
10089
|
if (headCloseIndex === -1) {
|
|
10029
|
-
console.log(
|
|
10090
|
+
console.log(chalk103.red("Could not find </head> tag in index.html"));
|
|
10030
10091
|
return;
|
|
10031
10092
|
}
|
|
10032
10093
|
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
10033
10094
|
${content.slice(headCloseIndex)}`;
|
|
10034
10095
|
writeFileSync22(indexPath, newContent);
|
|
10035
|
-
console.log(
|
|
10096
|
+
console.log(chalk103.green("Added trailing slash redirect to index.html"));
|
|
10036
10097
|
}
|
|
10037
10098
|
|
|
10038
10099
|
// src/commands/registerDeploy.ts
|
|
@@ -10059,7 +10120,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
10059
10120
|
|
|
10060
10121
|
// src/commands/devlog/shared.ts
|
|
10061
10122
|
import { execSync as execSync23 } from "child_process";
|
|
10062
|
-
import
|
|
10123
|
+
import chalk104 from "chalk";
|
|
10063
10124
|
|
|
10064
10125
|
// src/shared/getRepoName.ts
|
|
10065
10126
|
import { existsSync as existsSync28, readFileSync as readFileSync23 } from "fs";
|
|
@@ -10168,13 +10229,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
10168
10229
|
}
|
|
10169
10230
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
10170
10231
|
for (const commit2 of commits2) {
|
|
10171
|
-
console.log(` ${
|
|
10232
|
+
console.log(` ${chalk104.yellow(commit2.hash)} ${commit2.message}`);
|
|
10172
10233
|
if (verbose) {
|
|
10173
10234
|
const visibleFiles = commit2.files.filter(
|
|
10174
10235
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
10175
10236
|
);
|
|
10176
10237
|
for (const file of visibleFiles) {
|
|
10177
|
-
console.log(` ${
|
|
10238
|
+
console.log(` ${chalk104.dim(file)}`);
|
|
10178
10239
|
}
|
|
10179
10240
|
}
|
|
10180
10241
|
}
|
|
@@ -10199,15 +10260,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
10199
10260
|
}
|
|
10200
10261
|
|
|
10201
10262
|
// src/commands/devlog/list/printDateHeader.ts
|
|
10202
|
-
import
|
|
10263
|
+
import chalk105 from "chalk";
|
|
10203
10264
|
function printDateHeader(date, isSkipped, entries) {
|
|
10204
10265
|
if (isSkipped) {
|
|
10205
|
-
console.log(`${
|
|
10266
|
+
console.log(`${chalk105.bold.blue(date)} ${chalk105.dim("skipped")}`);
|
|
10206
10267
|
} else if (entries && entries.length > 0) {
|
|
10207
|
-
const entryInfo = entries.map((e) => `${
|
|
10208
|
-
console.log(`${
|
|
10268
|
+
const entryInfo = entries.map((e) => `${chalk105.green(e.version)} ${e.title}`).join(" | ");
|
|
10269
|
+
console.log(`${chalk105.bold.blue(date)} ${entryInfo}`);
|
|
10209
10270
|
} else {
|
|
10210
|
-
console.log(`${
|
|
10271
|
+
console.log(`${chalk105.bold.blue(date)} ${chalk105.red("\u26A0 devlog missing")}`);
|
|
10211
10272
|
}
|
|
10212
10273
|
}
|
|
10213
10274
|
|
|
@@ -10311,24 +10372,24 @@ function bumpVersion(version2, type) {
|
|
|
10311
10372
|
|
|
10312
10373
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
10313
10374
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
10314
|
-
import
|
|
10375
|
+
import chalk107 from "chalk";
|
|
10315
10376
|
|
|
10316
10377
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
10317
|
-
import
|
|
10378
|
+
import chalk106 from "chalk";
|
|
10318
10379
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
10319
10380
|
if (conventional && firstHash) {
|
|
10320
10381
|
const version2 = getVersionAtCommit(firstHash);
|
|
10321
10382
|
if (version2) {
|
|
10322
|
-
console.log(`${
|
|
10383
|
+
console.log(`${chalk106.bold("version:")} ${stripToMinor(version2)}`);
|
|
10323
10384
|
} else {
|
|
10324
|
-
console.log(`${
|
|
10385
|
+
console.log(`${chalk106.bold("version:")} ${chalk106.red("unknown")}`);
|
|
10325
10386
|
}
|
|
10326
10387
|
} else if (patchVersion && minorVersion) {
|
|
10327
10388
|
console.log(
|
|
10328
|
-
`${
|
|
10389
|
+
`${chalk106.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
10329
10390
|
);
|
|
10330
10391
|
} else {
|
|
10331
|
-
console.log(`${
|
|
10392
|
+
console.log(`${chalk106.bold("version:")} v0.1 (initial)`);
|
|
10332
10393
|
}
|
|
10333
10394
|
}
|
|
10334
10395
|
|
|
@@ -10376,16 +10437,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
10376
10437
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
10377
10438
|
}
|
|
10378
10439
|
function logName(repoName) {
|
|
10379
|
-
console.log(`${
|
|
10440
|
+
console.log(`${chalk107.bold("name:")} ${repoName}`);
|
|
10380
10441
|
}
|
|
10381
10442
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
10382
10443
|
logName(ctx.repoName);
|
|
10383
10444
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
10384
|
-
console.log(
|
|
10445
|
+
console.log(chalk107.bold.blue(targetDate));
|
|
10385
10446
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
10386
10447
|
}
|
|
10387
10448
|
function logNoCommits(lastInfo) {
|
|
10388
|
-
console.log(
|
|
10449
|
+
console.log(chalk107.dim(noCommitsMessage(!!lastInfo)));
|
|
10389
10450
|
}
|
|
10390
10451
|
|
|
10391
10452
|
// src/commands/devlog/next/index.ts
|
|
@@ -10426,11 +10487,11 @@ function next2(options2) {
|
|
|
10426
10487
|
import { execSync as execSync25 } from "child_process";
|
|
10427
10488
|
|
|
10428
10489
|
// src/commands/devlog/repos/printReposTable.ts
|
|
10429
|
-
import
|
|
10490
|
+
import chalk108 from "chalk";
|
|
10430
10491
|
function colorStatus(status2) {
|
|
10431
|
-
if (status2 === "missing") return
|
|
10432
|
-
if (status2 === "outdated") return
|
|
10433
|
-
return
|
|
10492
|
+
if (status2 === "missing") return chalk108.red(status2);
|
|
10493
|
+
if (status2 === "outdated") return chalk108.yellow(status2);
|
|
10494
|
+
return chalk108.green(status2);
|
|
10434
10495
|
}
|
|
10435
10496
|
function formatRow(row, nameWidth) {
|
|
10436
10497
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -10444,8 +10505,8 @@ function printReposTable(rows) {
|
|
|
10444
10505
|
"Last Devlog".padEnd(11),
|
|
10445
10506
|
"Status"
|
|
10446
10507
|
].join(" ");
|
|
10447
|
-
console.log(
|
|
10448
|
-
console.log(
|
|
10508
|
+
console.log(chalk108.dim(header));
|
|
10509
|
+
console.log(chalk108.dim("-".repeat(header.length)));
|
|
10449
10510
|
for (const row of rows) {
|
|
10450
10511
|
console.log(formatRow(row, nameWidth));
|
|
10451
10512
|
}
|
|
@@ -10503,14 +10564,14 @@ function repos(options2) {
|
|
|
10503
10564
|
// src/commands/devlog/skip.ts
|
|
10504
10565
|
import { writeFileSync as writeFileSync23 } from "fs";
|
|
10505
10566
|
import { join as join28 } from "path";
|
|
10506
|
-
import
|
|
10567
|
+
import chalk109 from "chalk";
|
|
10507
10568
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
10508
10569
|
function getBlogConfigPath() {
|
|
10509
10570
|
return join28(BLOG_REPO_ROOT, "assist.yml");
|
|
10510
10571
|
}
|
|
10511
10572
|
function skip(date) {
|
|
10512
10573
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
10513
|
-
console.log(
|
|
10574
|
+
console.log(chalk109.red("Invalid date format. Use YYYY-MM-DD"));
|
|
10514
10575
|
process.exit(1);
|
|
10515
10576
|
}
|
|
10516
10577
|
const repoName = getRepoName();
|
|
@@ -10521,7 +10582,7 @@ function skip(date) {
|
|
|
10521
10582
|
const skipDays = skip2[repoName] ?? [];
|
|
10522
10583
|
if (skipDays.includes(date)) {
|
|
10523
10584
|
console.log(
|
|
10524
|
-
|
|
10585
|
+
chalk109.yellow(`${date} is already in skip list for ${repoName}`)
|
|
10525
10586
|
);
|
|
10526
10587
|
return;
|
|
10527
10588
|
}
|
|
@@ -10531,20 +10592,20 @@ function skip(date) {
|
|
|
10531
10592
|
devlog.skip = skip2;
|
|
10532
10593
|
config.devlog = devlog;
|
|
10533
10594
|
writeFileSync23(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
10534
|
-
console.log(
|
|
10595
|
+
console.log(chalk109.green(`Added ${date} to skip list for ${repoName}`));
|
|
10535
10596
|
}
|
|
10536
10597
|
|
|
10537
10598
|
// src/commands/devlog/version.ts
|
|
10538
|
-
import
|
|
10599
|
+
import chalk110 from "chalk";
|
|
10539
10600
|
function version() {
|
|
10540
10601
|
const config = loadConfig();
|
|
10541
10602
|
const name = getRepoName();
|
|
10542
10603
|
const lastInfo = getLastVersionInfo(name, config);
|
|
10543
10604
|
const lastVersion = lastInfo?.version ?? null;
|
|
10544
10605
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
10545
|
-
console.log(`${
|
|
10546
|
-
console.log(`${
|
|
10547
|
-
console.log(`${
|
|
10606
|
+
console.log(`${chalk110.bold("name:")} ${name}`);
|
|
10607
|
+
console.log(`${chalk110.bold("last:")} ${lastVersion ?? chalk110.dim("none")}`);
|
|
10608
|
+
console.log(`${chalk110.bold("next:")} ${nextVersion ?? chalk110.dim("none")}`);
|
|
10548
10609
|
}
|
|
10549
10610
|
|
|
10550
10611
|
// src/commands/registerDevlog.ts
|
|
@@ -10568,7 +10629,7 @@ function registerDevlog(program2) {
|
|
|
10568
10629
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
10569
10630
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync2 } from "fs";
|
|
10570
10631
|
import { join as join29 } from "path";
|
|
10571
|
-
import
|
|
10632
|
+
import chalk111 from "chalk";
|
|
10572
10633
|
|
|
10573
10634
|
// src/shared/findRepoRoot.ts
|
|
10574
10635
|
import { existsSync as existsSync29 } from "fs";
|
|
@@ -10631,14 +10692,14 @@ function checkBuildLocks(startDir) {
|
|
|
10631
10692
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
10632
10693
|
if (locked) {
|
|
10633
10694
|
console.error(
|
|
10634
|
-
|
|
10695
|
+
chalk111.red("Build output locked (is VS debugging?): ") + locked
|
|
10635
10696
|
);
|
|
10636
10697
|
process.exit(1);
|
|
10637
10698
|
}
|
|
10638
10699
|
}
|
|
10639
10700
|
async function checkBuildLocksCommand() {
|
|
10640
10701
|
checkBuildLocks();
|
|
10641
|
-
console.log(
|
|
10702
|
+
console.log(chalk111.green("No build locks detected"));
|
|
10642
10703
|
}
|
|
10643
10704
|
|
|
10644
10705
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -10737,30 +10798,30 @@ function escapeRegex(s) {
|
|
|
10737
10798
|
}
|
|
10738
10799
|
|
|
10739
10800
|
// src/commands/dotnet/printTree.ts
|
|
10740
|
-
import
|
|
10801
|
+
import chalk112 from "chalk";
|
|
10741
10802
|
function printNodes(nodes, prefix2) {
|
|
10742
10803
|
for (let i = 0; i < nodes.length; i++) {
|
|
10743
10804
|
const isLast = i === nodes.length - 1;
|
|
10744
10805
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
10745
10806
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
10746
10807
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
10747
|
-
const label2 = isMissing ?
|
|
10808
|
+
const label2 = isMissing ? chalk112.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
10748
10809
|
console.log(`${prefix2}${connector}${label2}`);
|
|
10749
10810
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
10750
10811
|
}
|
|
10751
10812
|
}
|
|
10752
10813
|
function printTree(tree, totalCount, solutions) {
|
|
10753
|
-
console.log(
|
|
10754
|
-
console.log(
|
|
10814
|
+
console.log(chalk112.bold("\nProject Dependency Tree"));
|
|
10815
|
+
console.log(chalk112.cyan(tree.relativePath));
|
|
10755
10816
|
printNodes(tree.children, "");
|
|
10756
|
-
console.log(
|
|
10817
|
+
console.log(chalk112.dim(`
|
|
10757
10818
|
${totalCount} projects total (including root)`));
|
|
10758
|
-
console.log(
|
|
10819
|
+
console.log(chalk112.bold("\nSolution Membership"));
|
|
10759
10820
|
if (solutions.length === 0) {
|
|
10760
|
-
console.log(
|
|
10821
|
+
console.log(chalk112.yellow(" Not found in any .sln"));
|
|
10761
10822
|
} else {
|
|
10762
10823
|
for (const sln of solutions) {
|
|
10763
|
-
console.log(` ${
|
|
10824
|
+
console.log(` ${chalk112.green(sln)}`);
|
|
10764
10825
|
}
|
|
10765
10826
|
}
|
|
10766
10827
|
console.log();
|
|
@@ -10789,16 +10850,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
10789
10850
|
// src/commands/dotnet/resolveCsproj.ts
|
|
10790
10851
|
import { existsSync as existsSync30 } from "fs";
|
|
10791
10852
|
import path25 from "path";
|
|
10792
|
-
import
|
|
10853
|
+
import chalk113 from "chalk";
|
|
10793
10854
|
function resolveCsproj(csprojPath) {
|
|
10794
10855
|
const resolved = path25.resolve(csprojPath);
|
|
10795
10856
|
if (!existsSync30(resolved)) {
|
|
10796
|
-
console.error(
|
|
10857
|
+
console.error(chalk113.red(`File not found: ${resolved}`));
|
|
10797
10858
|
process.exit(1);
|
|
10798
10859
|
}
|
|
10799
10860
|
const repoRoot = findRepoRoot(path25.dirname(resolved));
|
|
10800
10861
|
if (!repoRoot) {
|
|
10801
|
-
console.error(
|
|
10862
|
+
console.error(chalk113.red("Could not find git repository root"));
|
|
10802
10863
|
process.exit(1);
|
|
10803
10864
|
}
|
|
10804
10865
|
return { resolved, repoRoot };
|
|
@@ -10848,12 +10909,12 @@ function getChangedCsFiles(scope) {
|
|
|
10848
10909
|
}
|
|
10849
10910
|
|
|
10850
10911
|
// src/commands/dotnet/inSln.ts
|
|
10851
|
-
import
|
|
10912
|
+
import chalk114 from "chalk";
|
|
10852
10913
|
async function inSln(csprojPath) {
|
|
10853
10914
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
10854
10915
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
10855
10916
|
if (solutions.length === 0) {
|
|
10856
|
-
console.log(
|
|
10917
|
+
console.log(chalk114.yellow("Not found in any .sln file"));
|
|
10857
10918
|
process.exit(1);
|
|
10858
10919
|
}
|
|
10859
10920
|
for (const sln of solutions) {
|
|
@@ -10862,7 +10923,7 @@ async function inSln(csprojPath) {
|
|
|
10862
10923
|
}
|
|
10863
10924
|
|
|
10864
10925
|
// src/commands/dotnet/inspect.ts
|
|
10865
|
-
import
|
|
10926
|
+
import chalk120 from "chalk";
|
|
10866
10927
|
|
|
10867
10928
|
// src/shared/formatElapsed.ts
|
|
10868
10929
|
function formatElapsed(ms) {
|
|
@@ -10874,12 +10935,12 @@ function formatElapsed(ms) {
|
|
|
10874
10935
|
}
|
|
10875
10936
|
|
|
10876
10937
|
// src/commands/dotnet/displayIssues.ts
|
|
10877
|
-
import
|
|
10938
|
+
import chalk115 from "chalk";
|
|
10878
10939
|
var SEVERITY_COLOR = {
|
|
10879
|
-
ERROR:
|
|
10880
|
-
WARNING:
|
|
10881
|
-
SUGGESTION:
|
|
10882
|
-
HINT:
|
|
10940
|
+
ERROR: chalk115.red,
|
|
10941
|
+
WARNING: chalk115.yellow,
|
|
10942
|
+
SUGGESTION: chalk115.cyan,
|
|
10943
|
+
HINT: chalk115.dim
|
|
10883
10944
|
};
|
|
10884
10945
|
function groupByFile(issues) {
|
|
10885
10946
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -10895,15 +10956,15 @@ function groupByFile(issues) {
|
|
|
10895
10956
|
}
|
|
10896
10957
|
function displayIssues(issues) {
|
|
10897
10958
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
10898
|
-
console.log(
|
|
10959
|
+
console.log(chalk115.bold(file));
|
|
10899
10960
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
10900
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
10961
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk115.white;
|
|
10901
10962
|
console.log(
|
|
10902
|
-
` ${
|
|
10963
|
+
` ${chalk115.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
10903
10964
|
);
|
|
10904
10965
|
}
|
|
10905
10966
|
}
|
|
10906
|
-
console.log(
|
|
10967
|
+
console.log(chalk115.dim(`
|
|
10907
10968
|
${issues.length} issue(s) found`));
|
|
10908
10969
|
}
|
|
10909
10970
|
|
|
@@ -10962,12 +11023,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
10962
11023
|
// src/commands/dotnet/resolveSolution.ts
|
|
10963
11024
|
import { existsSync as existsSync31 } from "fs";
|
|
10964
11025
|
import path26 from "path";
|
|
10965
|
-
import
|
|
11026
|
+
import chalk117 from "chalk";
|
|
10966
11027
|
|
|
10967
11028
|
// src/commands/dotnet/findSolution.ts
|
|
10968
11029
|
import { readdirSync as readdirSync4 } from "fs";
|
|
10969
11030
|
import { dirname as dirname18, join as join30 } from "path";
|
|
10970
|
-
import
|
|
11031
|
+
import chalk116 from "chalk";
|
|
10971
11032
|
function findSlnInDir(dir) {
|
|
10972
11033
|
try {
|
|
10973
11034
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join30(dir, f));
|
|
@@ -10983,17 +11044,17 @@ function findSolution() {
|
|
|
10983
11044
|
const slnFiles = findSlnInDir(current);
|
|
10984
11045
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
10985
11046
|
if (slnFiles.length > 1) {
|
|
10986
|
-
console.error(
|
|
11047
|
+
console.error(chalk116.red(`Multiple .sln files found in ${current}:`));
|
|
10987
11048
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
10988
11049
|
console.error(
|
|
10989
|
-
|
|
11050
|
+
chalk116.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
10990
11051
|
);
|
|
10991
11052
|
process.exit(1);
|
|
10992
11053
|
}
|
|
10993
11054
|
if (current === ceiling) break;
|
|
10994
11055
|
current = dirname18(current);
|
|
10995
11056
|
}
|
|
10996
|
-
console.error(
|
|
11057
|
+
console.error(chalk116.red("No .sln file found between cwd and repo root"));
|
|
10997
11058
|
process.exit(1);
|
|
10998
11059
|
}
|
|
10999
11060
|
|
|
@@ -11002,7 +11063,7 @@ function resolveSolution(sln) {
|
|
|
11002
11063
|
if (sln) {
|
|
11003
11064
|
const resolved = path26.resolve(sln);
|
|
11004
11065
|
if (!existsSync31(resolved)) {
|
|
11005
|
-
console.error(
|
|
11066
|
+
console.error(chalk117.red(`Solution file not found: ${resolved}`));
|
|
11006
11067
|
process.exit(1);
|
|
11007
11068
|
}
|
|
11008
11069
|
return resolved;
|
|
@@ -11044,14 +11105,14 @@ import { execSync as execSync27 } from "child_process";
|
|
|
11044
11105
|
import { existsSync as existsSync32, readFileSync as readFileSync27, unlinkSync as unlinkSync7 } from "fs";
|
|
11045
11106
|
import { tmpdir as tmpdir3 } from "os";
|
|
11046
11107
|
import path27 from "path";
|
|
11047
|
-
import
|
|
11108
|
+
import chalk118 from "chalk";
|
|
11048
11109
|
function assertJbInstalled() {
|
|
11049
11110
|
try {
|
|
11050
11111
|
execSync27("jb inspectcode --version", { stdio: "pipe" });
|
|
11051
11112
|
} catch {
|
|
11052
|
-
console.error(
|
|
11113
|
+
console.error(chalk118.red("jb is not installed. Install with:"));
|
|
11053
11114
|
console.error(
|
|
11054
|
-
|
|
11115
|
+
chalk118.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
11055
11116
|
);
|
|
11056
11117
|
process.exit(1);
|
|
11057
11118
|
}
|
|
@@ -11069,11 +11130,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11069
11130
|
if (error && typeof error === "object" && "stderr" in error) {
|
|
11070
11131
|
process.stderr.write(error.stderr);
|
|
11071
11132
|
}
|
|
11072
|
-
console.error(
|
|
11133
|
+
console.error(chalk118.red("jb inspectcode failed"));
|
|
11073
11134
|
process.exit(1);
|
|
11074
11135
|
}
|
|
11075
11136
|
if (!existsSync32(reportPath)) {
|
|
11076
|
-
console.error(
|
|
11137
|
+
console.error(chalk118.red("Report file not generated"));
|
|
11077
11138
|
process.exit(1);
|
|
11078
11139
|
}
|
|
11079
11140
|
const xml = readFileSync27(reportPath, "utf8");
|
|
@@ -11083,7 +11144,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11083
11144
|
|
|
11084
11145
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
11085
11146
|
import { execSync as execSync28 } from "child_process";
|
|
11086
|
-
import
|
|
11147
|
+
import chalk119 from "chalk";
|
|
11087
11148
|
function resolveMsbuildPath() {
|
|
11088
11149
|
const { run: run4 } = loadConfig();
|
|
11089
11150
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -11095,9 +11156,9 @@ function assertMsbuildInstalled() {
|
|
|
11095
11156
|
try {
|
|
11096
11157
|
execSync28(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
11097
11158
|
} catch {
|
|
11098
|
-
console.error(
|
|
11159
|
+
console.error(chalk119.red(`msbuild not found at: ${msbuild}`));
|
|
11099
11160
|
console.error(
|
|
11100
|
-
|
|
11161
|
+
chalk119.yellow(
|
|
11101
11162
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
11102
11163
|
)
|
|
11103
11164
|
);
|
|
@@ -11144,17 +11205,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
11144
11205
|
// src/commands/dotnet/inspect.ts
|
|
11145
11206
|
function logScope(changedFiles) {
|
|
11146
11207
|
if (changedFiles === null) {
|
|
11147
|
-
console.log(
|
|
11208
|
+
console.log(chalk120.dim("Inspecting full solution..."));
|
|
11148
11209
|
} else {
|
|
11149
11210
|
console.log(
|
|
11150
|
-
|
|
11211
|
+
chalk120.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
11151
11212
|
);
|
|
11152
11213
|
}
|
|
11153
11214
|
}
|
|
11154
11215
|
function reportResults(issues, elapsed) {
|
|
11155
11216
|
if (issues.length > 0) displayIssues(issues);
|
|
11156
|
-
else console.log(
|
|
11157
|
-
console.log(
|
|
11217
|
+
else console.log(chalk120.green("No issues found"));
|
|
11218
|
+
console.log(chalk120.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
11158
11219
|
if (issues.length > 0) process.exit(1);
|
|
11159
11220
|
}
|
|
11160
11221
|
async function inspect(sln, options2) {
|
|
@@ -11165,7 +11226,7 @@ async function inspect(sln, options2) {
|
|
|
11165
11226
|
const scope = parseScope(options2.scope);
|
|
11166
11227
|
const changedFiles = getChangedCsFiles(scope);
|
|
11167
11228
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
11168
|
-
console.log(
|
|
11229
|
+
console.log(chalk120.green("No changed .cs files found"));
|
|
11169
11230
|
return;
|
|
11170
11231
|
}
|
|
11171
11232
|
logScope(changedFiles);
|
|
@@ -11190,6 +11251,84 @@ function registerDotnet(program2) {
|
|
|
11190
11251
|
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
11252
|
}
|
|
11192
11253
|
|
|
11254
|
+
// src/commands/editHook/index.ts
|
|
11255
|
+
import fs19 from "fs";
|
|
11256
|
+
|
|
11257
|
+
// src/commands/editHook/decideOverrideGuard.ts
|
|
11258
|
+
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.`;
|
|
11259
|
+
function candidateStrings(input, existingContent) {
|
|
11260
|
+
const { tool_name, tool_input } = input;
|
|
11261
|
+
switch (tool_name) {
|
|
11262
|
+
case "Edit":
|
|
11263
|
+
return [tool_input.old_string, tool_input.new_string].filter(
|
|
11264
|
+
(s) => s !== void 0
|
|
11265
|
+
);
|
|
11266
|
+
case "MultiEdit":
|
|
11267
|
+
return (tool_input.edits ?? []).flatMap(
|
|
11268
|
+
(e) => [e.old_string, e.new_string].filter(
|
|
11269
|
+
(s) => s !== void 0
|
|
11270
|
+
)
|
|
11271
|
+
);
|
|
11272
|
+
case "Write":
|
|
11273
|
+
return [tool_input.content, existingContent].filter(
|
|
11274
|
+
(s) => s !== void 0
|
|
11275
|
+
);
|
|
11276
|
+
default:
|
|
11277
|
+
return [];
|
|
11278
|
+
}
|
|
11279
|
+
}
|
|
11280
|
+
function decideOverrideGuard(input, existingContent) {
|
|
11281
|
+
const touchesMarker = candidateStrings(input, existingContent).some(
|
|
11282
|
+
(s) => s.includes(MAINTAINABILITY_OVERRIDE_MARKER)
|
|
11283
|
+
);
|
|
11284
|
+
return touchesMarker ? DENY_REASON : void 0;
|
|
11285
|
+
}
|
|
11286
|
+
|
|
11287
|
+
// src/commands/editHook/index.ts
|
|
11288
|
+
function tryParseInput2(raw) {
|
|
11289
|
+
try {
|
|
11290
|
+
const data = JSON.parse(raw);
|
|
11291
|
+
if (typeof data.tool_name !== "string" || !data.tool_input)
|
|
11292
|
+
return void 0;
|
|
11293
|
+
return data;
|
|
11294
|
+
} catch {
|
|
11295
|
+
return void 0;
|
|
11296
|
+
}
|
|
11297
|
+
}
|
|
11298
|
+
function readExisting(filePath) {
|
|
11299
|
+
if (!filePath) return void 0;
|
|
11300
|
+
try {
|
|
11301
|
+
return fs19.readFileSync(filePath, "utf8");
|
|
11302
|
+
} catch {
|
|
11303
|
+
return void 0;
|
|
11304
|
+
}
|
|
11305
|
+
}
|
|
11306
|
+
async function editHook() {
|
|
11307
|
+
const input = tryParseInput2(await readStdin());
|
|
11308
|
+
if (!input) return;
|
|
11309
|
+
const existing = input.tool_name === "Write" ? readExisting(input.tool_input.file_path) : void 0;
|
|
11310
|
+
const reason = decideOverrideGuard(input, existing);
|
|
11311
|
+
if (!reason) return;
|
|
11312
|
+
console.log(
|
|
11313
|
+
JSON.stringify({
|
|
11314
|
+
hookSpecificOutput: {
|
|
11315
|
+
hookEventName: "PreToolUse",
|
|
11316
|
+
permissionDecision: "deny",
|
|
11317
|
+
permissionDecisionReason: reason
|
|
11318
|
+
}
|
|
11319
|
+
})
|
|
11320
|
+
);
|
|
11321
|
+
}
|
|
11322
|
+
|
|
11323
|
+
// src/commands/registerEditHook.ts
|
|
11324
|
+
function registerEditHook(program2) {
|
|
11325
|
+
program2.command("edit-hook").description(
|
|
11326
|
+
"PreToolUse hook that blocks edits to the maintainability override marker"
|
|
11327
|
+
).action(() => {
|
|
11328
|
+
editHook();
|
|
11329
|
+
});
|
|
11330
|
+
}
|
|
11331
|
+
|
|
11193
11332
|
// src/commands/github/aggregateCommitters.ts
|
|
11194
11333
|
function aggregateCommitters(authorLists) {
|
|
11195
11334
|
const totals = /* @__PURE__ */ new Map();
|
|
@@ -11294,25 +11433,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
11294
11433
|
}
|
|
11295
11434
|
|
|
11296
11435
|
// src/commands/github/printCountTable.ts
|
|
11297
|
-
import
|
|
11436
|
+
import chalk121 from "chalk";
|
|
11298
11437
|
function printCountTable(labelHeader, rows) {
|
|
11299
11438
|
const labelWidth = Math.max(
|
|
11300
11439
|
labelHeader.length,
|
|
11301
11440
|
...rows.map((row) => row.label.length)
|
|
11302
11441
|
);
|
|
11303
11442
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
11304
|
-
console.log(
|
|
11305
|
-
console.log(
|
|
11443
|
+
console.log(chalk121.dim(header));
|
|
11444
|
+
console.log(chalk121.dim("-".repeat(header.length)));
|
|
11306
11445
|
for (const row of rows) {
|
|
11307
11446
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
11308
11447
|
}
|
|
11309
11448
|
}
|
|
11310
11449
|
|
|
11311
11450
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
11312
|
-
import
|
|
11451
|
+
import chalk122 from "chalk";
|
|
11313
11452
|
function printRepoAuthorBreakdown(repos2) {
|
|
11314
11453
|
for (const repo of repos2) {
|
|
11315
|
-
console.log(
|
|
11454
|
+
console.log(chalk122.bold(repo.name));
|
|
11316
11455
|
const authorWidth = Math.max(
|
|
11317
11456
|
0,
|
|
11318
11457
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -11630,7 +11769,7 @@ function registerHandover(program2) {
|
|
|
11630
11769
|
}
|
|
11631
11770
|
|
|
11632
11771
|
// src/commands/jira/acceptanceCriteria.ts
|
|
11633
|
-
import
|
|
11772
|
+
import chalk124 from "chalk";
|
|
11634
11773
|
|
|
11635
11774
|
// src/commands/jira/adfToText.ts
|
|
11636
11775
|
function renderInline(node) {
|
|
@@ -11691,7 +11830,7 @@ function adfToText(doc) {
|
|
|
11691
11830
|
|
|
11692
11831
|
// src/commands/jira/fetchIssue.ts
|
|
11693
11832
|
import { execSync as execSync29 } from "child_process";
|
|
11694
|
-
import
|
|
11833
|
+
import chalk123 from "chalk";
|
|
11695
11834
|
function fetchIssue(issueKey, fields) {
|
|
11696
11835
|
let result;
|
|
11697
11836
|
try {
|
|
@@ -11704,15 +11843,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
11704
11843
|
const stderr = error.stderr;
|
|
11705
11844
|
if (stderr.includes("unauthorized")) {
|
|
11706
11845
|
console.error(
|
|
11707
|
-
|
|
11846
|
+
chalk123.red("Jira authentication expired."),
|
|
11708
11847
|
"Run",
|
|
11709
|
-
|
|
11848
|
+
chalk123.cyan("assist jira auth"),
|
|
11710
11849
|
"to re-authenticate."
|
|
11711
11850
|
);
|
|
11712
11851
|
process.exit(1);
|
|
11713
11852
|
}
|
|
11714
11853
|
}
|
|
11715
|
-
console.error(
|
|
11854
|
+
console.error(chalk123.red(`Failed to fetch ${issueKey}.`));
|
|
11716
11855
|
process.exit(1);
|
|
11717
11856
|
}
|
|
11718
11857
|
return JSON.parse(result);
|
|
@@ -11726,7 +11865,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
11726
11865
|
const parsed = fetchIssue(issueKey, field);
|
|
11727
11866
|
const acValue = parsed?.fields?.[field];
|
|
11728
11867
|
if (!acValue) {
|
|
11729
|
-
console.log(
|
|
11868
|
+
console.log(chalk124.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
11730
11869
|
return;
|
|
11731
11870
|
}
|
|
11732
11871
|
if (typeof acValue === "string") {
|
|
@@ -11821,14 +11960,14 @@ async function jiraAuth() {
|
|
|
11821
11960
|
}
|
|
11822
11961
|
|
|
11823
11962
|
// src/commands/jira/viewIssue.ts
|
|
11824
|
-
import
|
|
11963
|
+
import chalk125 from "chalk";
|
|
11825
11964
|
function viewIssue(issueKey) {
|
|
11826
11965
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
11827
11966
|
const fields = parsed?.fields;
|
|
11828
11967
|
const summary = fields?.summary;
|
|
11829
11968
|
const description = fields?.description;
|
|
11830
11969
|
if (summary) {
|
|
11831
|
-
console.log(
|
|
11970
|
+
console.log(chalk125.bold(summary));
|
|
11832
11971
|
}
|
|
11833
11972
|
if (description) {
|
|
11834
11973
|
if (summary) console.log();
|
|
@@ -11842,7 +11981,7 @@ function viewIssue(issueKey) {
|
|
|
11842
11981
|
}
|
|
11843
11982
|
if (!summary && !description) {
|
|
11844
11983
|
console.log(
|
|
11845
|
-
|
|
11984
|
+
chalk125.yellow(`No summary or description found on ${issueKey}.`)
|
|
11846
11985
|
);
|
|
11847
11986
|
}
|
|
11848
11987
|
}
|
|
@@ -11858,13 +11997,13 @@ function registerJira(program2) {
|
|
|
11858
11997
|
// src/commands/reviewComments.ts
|
|
11859
11998
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
11860
11999
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
11861
|
-
import
|
|
12000
|
+
import chalk126 from "chalk";
|
|
11862
12001
|
async function reviewComments(number) {
|
|
11863
12002
|
if (number) {
|
|
11864
12003
|
try {
|
|
11865
12004
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
11866
12005
|
} catch {
|
|
11867
|
-
console.error(
|
|
12006
|
+
console.error(chalk126.red(`gh pr checkout ${number} failed; aborting.`));
|
|
11868
12007
|
process.exit(1);
|
|
11869
12008
|
}
|
|
11870
12009
|
}
|
|
@@ -11910,15 +12049,15 @@ function registerList(program2) {
|
|
|
11910
12049
|
// src/commands/mermaid/index.ts
|
|
11911
12050
|
import { mkdirSync as mkdirSync12, readdirSync as readdirSync6 } from "fs";
|
|
11912
12051
|
import { resolve as resolve11 } from "path";
|
|
11913
|
-
import
|
|
12052
|
+
import chalk129 from "chalk";
|
|
11914
12053
|
|
|
11915
12054
|
// src/commands/mermaid/exportFile.ts
|
|
11916
12055
|
import { readFileSync as readFileSync30, writeFileSync as writeFileSync26 } from "fs";
|
|
11917
12056
|
import { basename as basename6, extname, resolve as resolve10 } from "path";
|
|
11918
|
-
import
|
|
12057
|
+
import chalk128 from "chalk";
|
|
11919
12058
|
|
|
11920
12059
|
// src/commands/mermaid/renderBlock.ts
|
|
11921
|
-
import
|
|
12060
|
+
import chalk127 from "chalk";
|
|
11922
12061
|
async function renderBlock(krokiUrl, source) {
|
|
11923
12062
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
11924
12063
|
method: "POST",
|
|
@@ -11927,7 +12066,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
11927
12066
|
});
|
|
11928
12067
|
if (!response.ok) {
|
|
11929
12068
|
console.error(
|
|
11930
|
-
|
|
12069
|
+
chalk127.red(
|
|
11931
12070
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
11932
12071
|
)
|
|
11933
12072
|
);
|
|
@@ -11945,19 +12084,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
11945
12084
|
if (onlyIndex !== void 0) {
|
|
11946
12085
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
11947
12086
|
console.error(
|
|
11948
|
-
|
|
12087
|
+
chalk128.red(
|
|
11949
12088
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
11950
12089
|
)
|
|
11951
12090
|
);
|
|
11952
12091
|
process.exit(1);
|
|
11953
12092
|
}
|
|
11954
12093
|
console.log(
|
|
11955
|
-
|
|
12094
|
+
chalk128.gray(
|
|
11956
12095
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
11957
12096
|
)
|
|
11958
12097
|
);
|
|
11959
12098
|
} else {
|
|
11960
|
-
console.log(
|
|
12099
|
+
console.log(chalk128.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
11961
12100
|
}
|
|
11962
12101
|
for (const [i, source] of blocks.entries()) {
|
|
11963
12102
|
const idx = i + 1;
|
|
@@ -11965,7 +12104,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
11965
12104
|
const outPath = resolve10(outDir, `${stem}-${idx}.svg`);
|
|
11966
12105
|
const svg = await renderBlock(krokiUrl, source);
|
|
11967
12106
|
writeFileSync26(outPath, svg, "utf8");
|
|
11968
|
-
console.log(
|
|
12107
|
+
console.log(chalk128.green(` \u2192 ${outPath}`));
|
|
11969
12108
|
}
|
|
11970
12109
|
}
|
|
11971
12110
|
function extractMermaidBlocks(markdown) {
|
|
@@ -11981,18 +12120,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
11981
12120
|
if (options2.index !== void 0) {
|
|
11982
12121
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
11983
12122
|
console.error(
|
|
11984
|
-
|
|
12123
|
+
chalk129.red(`--index must be a positive integer (got ${options2.index})`)
|
|
11985
12124
|
);
|
|
11986
12125
|
process.exit(1);
|
|
11987
12126
|
}
|
|
11988
12127
|
if (!file) {
|
|
11989
|
-
console.error(
|
|
12128
|
+
console.error(chalk129.red("--index requires a file argument"));
|
|
11990
12129
|
process.exit(1);
|
|
11991
12130
|
}
|
|
11992
12131
|
}
|
|
11993
12132
|
const files = file ? [file] : readdirSync6(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
11994
12133
|
if (files.length === 0) {
|
|
11995
|
-
console.log(
|
|
12134
|
+
console.log(chalk129.gray("No markdown files found in current directory."));
|
|
11996
12135
|
return;
|
|
11997
12136
|
}
|
|
11998
12137
|
for (const f of files) {
|
|
@@ -12018,7 +12157,7 @@ function registerMermaid(program2) {
|
|
|
12018
12157
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
12019
12158
|
import { createServer as createServer2 } from "http";
|
|
12020
12159
|
import { dirname as dirname20 } from "path";
|
|
12021
|
-
import
|
|
12160
|
+
import chalk131 from "chalk";
|
|
12022
12161
|
|
|
12023
12162
|
// src/commands/netcap/corsHeaders.ts
|
|
12024
12163
|
var corsHeaders = {
|
|
@@ -12097,7 +12236,7 @@ function createNetcapHandler(options2) {
|
|
|
12097
12236
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
12098
12237
|
import { networkInterfaces } from "os";
|
|
12099
12238
|
import { join as join37 } from "path";
|
|
12100
|
-
import
|
|
12239
|
+
import chalk130 from "chalk";
|
|
12101
12240
|
|
|
12102
12241
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
12103
12242
|
import { dirname as dirname19, join as join36 } from "path";
|
|
@@ -12141,7 +12280,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12141
12280
|
const host = lanIPv4();
|
|
12142
12281
|
if (!host) {
|
|
12143
12282
|
console.log(
|
|
12144
|
-
|
|
12283
|
+
chalk130.yellow("could not determine the WSL IP for the extension")
|
|
12145
12284
|
);
|
|
12146
12285
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
12147
12286
|
return source;
|
|
@@ -12152,7 +12291,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12152
12291
|
return WSL_WINDOWS_PATH;
|
|
12153
12292
|
} catch {
|
|
12154
12293
|
console.log(
|
|
12155
|
-
|
|
12294
|
+
chalk130.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
12156
12295
|
);
|
|
12157
12296
|
return source;
|
|
12158
12297
|
}
|
|
@@ -12185,30 +12324,30 @@ async function netcap(options2) {
|
|
|
12185
12324
|
let count6 = 0;
|
|
12186
12325
|
const handler = createNetcapHandler({
|
|
12187
12326
|
outPath,
|
|
12188
|
-
onPing: () => console.log(
|
|
12327
|
+
onPing: () => console.log(chalk131.dim("ping from extension")),
|
|
12189
12328
|
onCapture: (entry) => {
|
|
12190
12329
|
count6 += 1;
|
|
12191
12330
|
console.log(
|
|
12192
|
-
|
|
12193
|
-
|
|
12331
|
+
chalk131.green(`captured #${count6}`),
|
|
12332
|
+
chalk131.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
12194
12333
|
);
|
|
12195
12334
|
}
|
|
12196
12335
|
});
|
|
12197
12336
|
const server = createServer2(handler);
|
|
12198
12337
|
server.listen(port, () => {
|
|
12199
12338
|
console.log(
|
|
12200
|
-
|
|
12339
|
+
chalk131.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
12201
12340
|
);
|
|
12202
|
-
console.log(
|
|
12341
|
+
console.log(chalk131.dim(`appending captures to ${outPath}`));
|
|
12203
12342
|
if (filter)
|
|
12204
|
-
console.log(
|
|
12205
|
-
console.log(
|
|
12206
|
-
console.log(
|
|
12343
|
+
console.log(chalk131.dim(`forwarding only URLs matching "${filter}"`));
|
|
12344
|
+
console.log(chalk131.dim(`load the unpacked extension from ${extensionPath}`));
|
|
12345
|
+
console.log(chalk131.dim("press Ctrl-C to stop"));
|
|
12207
12346
|
});
|
|
12208
12347
|
process.on("SIGINT", () => {
|
|
12209
12348
|
server.close();
|
|
12210
12349
|
console.log(
|
|
12211
|
-
|
|
12350
|
+
chalk131.bold(
|
|
12212
12351
|
`
|
|
12213
12352
|
netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
12214
12353
|
)
|
|
@@ -12220,7 +12359,7 @@ netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} t
|
|
|
12220
12359
|
// src/commands/netcap/netcapExtract.ts
|
|
12221
12360
|
import { writeFileSync as writeFileSync27 } from "fs";
|
|
12222
12361
|
import { join as join40 } from "path";
|
|
12223
|
-
import
|
|
12362
|
+
import chalk132 from "chalk";
|
|
12224
12363
|
|
|
12225
12364
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
12226
12365
|
import { readFileSync as readFileSync31 } from "fs";
|
|
@@ -12668,8 +12807,8 @@ function netcapExtract(file) {
|
|
|
12668
12807
|
writeFileSync27(outFile, `${JSON.stringify(posts, null, 2)}
|
|
12669
12808
|
`);
|
|
12670
12809
|
console.log(
|
|
12671
|
-
|
|
12672
|
-
|
|
12810
|
+
chalk132.green(`extracted ${posts.length} posts`),
|
|
12811
|
+
chalk132.dim(`-> ${outFile}`)
|
|
12673
12812
|
);
|
|
12674
12813
|
}
|
|
12675
12814
|
|
|
@@ -12690,7 +12829,7 @@ function registerNetcap(program2) {
|
|
|
12690
12829
|
}
|
|
12691
12830
|
|
|
12692
12831
|
// src/commands/news/add/index.ts
|
|
12693
|
-
import
|
|
12832
|
+
import chalk133 from "chalk";
|
|
12694
12833
|
import enquirer8 from "enquirer";
|
|
12695
12834
|
async function add2(url) {
|
|
12696
12835
|
if (!url) {
|
|
@@ -12712,10 +12851,10 @@ async function add2(url) {
|
|
|
12712
12851
|
const { orm } = await getReady();
|
|
12713
12852
|
const added = await addFeed(orm, url);
|
|
12714
12853
|
if (!added) {
|
|
12715
|
-
console.log(
|
|
12854
|
+
console.log(chalk133.yellow("Feed already exists"));
|
|
12716
12855
|
return;
|
|
12717
12856
|
}
|
|
12718
|
-
console.log(
|
|
12857
|
+
console.log(chalk133.green(`Added feed: ${url}`));
|
|
12719
12858
|
}
|
|
12720
12859
|
|
|
12721
12860
|
// src/commands/registerNews.ts
|
|
@@ -12725,7 +12864,7 @@ function registerNews(program2) {
|
|
|
12725
12864
|
}
|
|
12726
12865
|
|
|
12727
12866
|
// src/commands/prompts/printPromptsTable.ts
|
|
12728
|
-
import
|
|
12867
|
+
import chalk134 from "chalk";
|
|
12729
12868
|
function truncate(str, max) {
|
|
12730
12869
|
if (str.length <= max) return str;
|
|
12731
12870
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -12743,14 +12882,14 @@ function printPromptsTable(rows) {
|
|
|
12743
12882
|
"Command".padEnd(commandWidth),
|
|
12744
12883
|
"Repos"
|
|
12745
12884
|
].join(" ");
|
|
12746
|
-
console.log(
|
|
12747
|
-
console.log(
|
|
12885
|
+
console.log(chalk134.dim(header));
|
|
12886
|
+
console.log(chalk134.dim("-".repeat(header.length)));
|
|
12748
12887
|
for (const row of rows) {
|
|
12749
12888
|
const count6 = String(row.count).padStart(countWidth);
|
|
12750
12889
|
const tool = row.tool.padEnd(toolWidth);
|
|
12751
12890
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
12752
12891
|
console.log(
|
|
12753
|
-
`${
|
|
12892
|
+
`${chalk134.yellow(count6)} ${tool} ${command} ${chalk134.dim(row.repos)}`
|
|
12754
12893
|
);
|
|
12755
12894
|
}
|
|
12756
12895
|
}
|
|
@@ -13299,20 +13438,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
13299
13438
|
}
|
|
13300
13439
|
|
|
13301
13440
|
// src/commands/prs/listComments/printComments.ts
|
|
13302
|
-
import
|
|
13441
|
+
import chalk135 from "chalk";
|
|
13303
13442
|
function formatForHuman(comment3) {
|
|
13304
13443
|
if (comment3.type === "review") {
|
|
13305
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
13444
|
+
const stateColor = comment3.state === "APPROVED" ? chalk135.green : comment3.state === "CHANGES_REQUESTED" ? chalk135.red : chalk135.yellow;
|
|
13306
13445
|
return [
|
|
13307
|
-
`${
|
|
13446
|
+
`${chalk135.cyan("Review")} by ${chalk135.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
13308
13447
|
comment3.body,
|
|
13309
13448
|
""
|
|
13310
13449
|
].join("\n");
|
|
13311
13450
|
}
|
|
13312
13451
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
13313
13452
|
return [
|
|
13314
|
-
`${
|
|
13315
|
-
|
|
13453
|
+
`${chalk135.cyan("Line comment")} by ${chalk135.bold(comment3.user)} on ${chalk135.dim(`${comment3.path}${location}`)}`,
|
|
13454
|
+
chalk135.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
13316
13455
|
comment3.body,
|
|
13317
13456
|
""
|
|
13318
13457
|
].join("\n");
|
|
@@ -13402,13 +13541,13 @@ import { execSync as execSync38 } from "child_process";
|
|
|
13402
13541
|
import enquirer9 from "enquirer";
|
|
13403
13542
|
|
|
13404
13543
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
13405
|
-
import
|
|
13544
|
+
import chalk136 from "chalk";
|
|
13406
13545
|
var STATUS_MAP = {
|
|
13407
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
13408
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
13546
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk136.magenta("merged"), date: pr.mergedAt } : null,
|
|
13547
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk136.red("closed"), date: pr.closedAt } : null
|
|
13409
13548
|
};
|
|
13410
13549
|
function defaultStatus(pr) {
|
|
13411
|
-
return { label:
|
|
13550
|
+
return { label: chalk136.green("opened"), date: pr.createdAt };
|
|
13412
13551
|
}
|
|
13413
13552
|
function getStatus2(pr) {
|
|
13414
13553
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -13417,11 +13556,11 @@ function formatDate(dateStr) {
|
|
|
13417
13556
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
13418
13557
|
}
|
|
13419
13558
|
function formatPrHeader(pr, status2) {
|
|
13420
|
-
return `${
|
|
13559
|
+
return `${chalk136.cyan(`#${pr.number}`)} ${pr.title} ${chalk136.dim(`(${pr.author.login},`)} ${status2.label} ${chalk136.dim(`${formatDate(status2.date)})`)}`;
|
|
13421
13560
|
}
|
|
13422
13561
|
function logPrDetails(pr) {
|
|
13423
13562
|
console.log(
|
|
13424
|
-
|
|
13563
|
+
chalk136.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
13425
13564
|
);
|
|
13426
13565
|
console.log();
|
|
13427
13566
|
}
|
|
@@ -13728,10 +13867,10 @@ function registerPrs(program2) {
|
|
|
13728
13867
|
}
|
|
13729
13868
|
|
|
13730
13869
|
// src/commands/ravendb/ravendbAuth.ts
|
|
13731
|
-
import
|
|
13870
|
+
import chalk142 from "chalk";
|
|
13732
13871
|
|
|
13733
13872
|
// src/shared/createConnectionAuth.ts
|
|
13734
|
-
import
|
|
13873
|
+
import chalk137 from "chalk";
|
|
13735
13874
|
function listConnections(connections, format2) {
|
|
13736
13875
|
if (connections.length === 0) {
|
|
13737
13876
|
console.log("No connections configured.");
|
|
@@ -13744,7 +13883,7 @@ function listConnections(connections, format2) {
|
|
|
13744
13883
|
function removeConnection(connections, name, save) {
|
|
13745
13884
|
const filtered = connections.filter((c) => c.name !== name);
|
|
13746
13885
|
if (filtered.length === connections.length) {
|
|
13747
|
-
console.error(
|
|
13886
|
+
console.error(chalk137.red(`Connection "${name}" not found.`));
|
|
13748
13887
|
process.exit(1);
|
|
13749
13888
|
}
|
|
13750
13889
|
save(filtered);
|
|
@@ -13790,15 +13929,15 @@ function saveConnections(connections) {
|
|
|
13790
13929
|
}
|
|
13791
13930
|
|
|
13792
13931
|
// src/commands/ravendb/promptConnection.ts
|
|
13793
|
-
import
|
|
13932
|
+
import chalk140 from "chalk";
|
|
13794
13933
|
|
|
13795
13934
|
// src/commands/ravendb/selectOpSecret.ts
|
|
13796
|
-
import
|
|
13935
|
+
import chalk139 from "chalk";
|
|
13797
13936
|
import Enquirer2 from "enquirer";
|
|
13798
13937
|
|
|
13799
13938
|
// src/commands/ravendb/searchItems.ts
|
|
13800
13939
|
import { execSync as execSync41 } from "child_process";
|
|
13801
|
-
import
|
|
13940
|
+
import chalk138 from "chalk";
|
|
13802
13941
|
function opExec(args) {
|
|
13803
13942
|
return execSync41(`op ${args}`, {
|
|
13804
13943
|
encoding: "utf8",
|
|
@@ -13811,7 +13950,7 @@ function searchItems(search2) {
|
|
|
13811
13950
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
13812
13951
|
} catch {
|
|
13813
13952
|
console.error(
|
|
13814
|
-
|
|
13953
|
+
chalk138.red(
|
|
13815
13954
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
13816
13955
|
)
|
|
13817
13956
|
);
|
|
@@ -13825,7 +13964,7 @@ function getItemFields(itemId) {
|
|
|
13825
13964
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
13826
13965
|
return item.fields.filter((f) => f.reference && f.label);
|
|
13827
13966
|
} catch {
|
|
13828
|
-
console.error(
|
|
13967
|
+
console.error(chalk138.red("Failed to get item details from 1Password."));
|
|
13829
13968
|
process.exit(1);
|
|
13830
13969
|
}
|
|
13831
13970
|
}
|
|
@@ -13844,7 +13983,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
13844
13983
|
}).run();
|
|
13845
13984
|
const items2 = searchItems(search2);
|
|
13846
13985
|
if (items2.length === 0) {
|
|
13847
|
-
console.error(
|
|
13986
|
+
console.error(chalk139.red(`No items found matching "${search2}".`));
|
|
13848
13987
|
process.exit(1);
|
|
13849
13988
|
}
|
|
13850
13989
|
const itemId = await selectOne(
|
|
@@ -13853,7 +13992,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
13853
13992
|
);
|
|
13854
13993
|
const fields = getItemFields(itemId);
|
|
13855
13994
|
if (fields.length === 0) {
|
|
13856
|
-
console.error(
|
|
13995
|
+
console.error(chalk139.red("No fields with references found on this item."));
|
|
13857
13996
|
process.exit(1);
|
|
13858
13997
|
}
|
|
13859
13998
|
const ref = await selectOne(
|
|
@@ -13867,7 +14006,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
13867
14006
|
async function promptConnection(existingNames) {
|
|
13868
14007
|
const name = await promptInput("name", "Connection name:");
|
|
13869
14008
|
if (existingNames.includes(name)) {
|
|
13870
|
-
console.error(
|
|
14009
|
+
console.error(chalk140.red(`Connection "${name}" already exists.`));
|
|
13871
14010
|
process.exit(1);
|
|
13872
14011
|
}
|
|
13873
14012
|
const url = await promptInput(
|
|
@@ -13876,22 +14015,22 @@ async function promptConnection(existingNames) {
|
|
|
13876
14015
|
);
|
|
13877
14016
|
const database = await promptInput("database", "Database name:");
|
|
13878
14017
|
if (!name || !url || !database) {
|
|
13879
|
-
console.error(
|
|
14018
|
+
console.error(chalk140.red("All fields are required."));
|
|
13880
14019
|
process.exit(1);
|
|
13881
14020
|
}
|
|
13882
14021
|
const apiKeyRef = await selectOpSecret();
|
|
13883
|
-
console.log(
|
|
14022
|
+
console.log(chalk140.dim(`Using: ${apiKeyRef}`));
|
|
13884
14023
|
return { name, url, database, apiKeyRef };
|
|
13885
14024
|
}
|
|
13886
14025
|
|
|
13887
14026
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
13888
|
-
import
|
|
14027
|
+
import chalk141 from "chalk";
|
|
13889
14028
|
function ravendbSetConnection(name) {
|
|
13890
14029
|
const raw = loadGlobalConfigRaw();
|
|
13891
14030
|
const ravendb = raw.ravendb ?? {};
|
|
13892
14031
|
const connections = ravendb.connections ?? [];
|
|
13893
14032
|
if (!connections.some((c) => c.name === name)) {
|
|
13894
|
-
console.error(
|
|
14033
|
+
console.error(chalk141.red(`Connection "${name}" not found.`));
|
|
13895
14034
|
console.error(
|
|
13896
14035
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
13897
14036
|
);
|
|
@@ -13907,16 +14046,16 @@ function ravendbSetConnection(name) {
|
|
|
13907
14046
|
var ravendbAuth = createConnectionAuth({
|
|
13908
14047
|
load: loadConnections,
|
|
13909
14048
|
save: saveConnections,
|
|
13910
|
-
format: (c) => `${
|
|
14049
|
+
format: (c) => `${chalk142.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
13911
14050
|
promptNew: promptConnection,
|
|
13912
14051
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
13913
14052
|
});
|
|
13914
14053
|
|
|
13915
14054
|
// src/commands/ravendb/ravendbCollections.ts
|
|
13916
|
-
import
|
|
14055
|
+
import chalk146 from "chalk";
|
|
13917
14056
|
|
|
13918
14057
|
// src/commands/ravendb/ravenFetch.ts
|
|
13919
|
-
import
|
|
14058
|
+
import chalk144 from "chalk";
|
|
13920
14059
|
|
|
13921
14060
|
// src/commands/ravendb/getAccessToken.ts
|
|
13922
14061
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -13953,10 +14092,10 @@ ${errorText}`
|
|
|
13953
14092
|
|
|
13954
14093
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
13955
14094
|
import { execSync as execSync42 } from "child_process";
|
|
13956
|
-
import
|
|
14095
|
+
import chalk143 from "chalk";
|
|
13957
14096
|
function resolveOpSecret(reference) {
|
|
13958
14097
|
if (!reference.startsWith("op://")) {
|
|
13959
|
-
console.error(
|
|
14098
|
+
console.error(chalk143.red(`Invalid secret reference: must start with op://`));
|
|
13960
14099
|
process.exit(1);
|
|
13961
14100
|
}
|
|
13962
14101
|
try {
|
|
@@ -13966,7 +14105,7 @@ function resolveOpSecret(reference) {
|
|
|
13966
14105
|
}).trim();
|
|
13967
14106
|
} catch {
|
|
13968
14107
|
console.error(
|
|
13969
|
-
|
|
14108
|
+
chalk143.red(
|
|
13970
14109
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
13971
14110
|
)
|
|
13972
14111
|
);
|
|
@@ -13993,7 +14132,7 @@ async function ravenFetch(connection, path57) {
|
|
|
13993
14132
|
if (!response.ok) {
|
|
13994
14133
|
const body = await response.text();
|
|
13995
14134
|
console.error(
|
|
13996
|
-
|
|
14135
|
+
chalk144.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
13997
14136
|
);
|
|
13998
14137
|
console.error(body.substring(0, 500));
|
|
13999
14138
|
process.exit(1);
|
|
@@ -14002,7 +14141,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14002
14141
|
}
|
|
14003
14142
|
|
|
14004
14143
|
// src/commands/ravendb/resolveConnection.ts
|
|
14005
|
-
import
|
|
14144
|
+
import chalk145 from "chalk";
|
|
14006
14145
|
function loadRavendb() {
|
|
14007
14146
|
const raw = loadGlobalConfigRaw();
|
|
14008
14147
|
const ravendb = raw.ravendb;
|
|
@@ -14016,7 +14155,7 @@ function resolveConnection(name) {
|
|
|
14016
14155
|
const connectionName = name ?? defaultConnection;
|
|
14017
14156
|
if (!connectionName) {
|
|
14018
14157
|
console.error(
|
|
14019
|
-
|
|
14158
|
+
chalk145.red(
|
|
14020
14159
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
14021
14160
|
)
|
|
14022
14161
|
);
|
|
@@ -14024,7 +14163,7 @@ function resolveConnection(name) {
|
|
|
14024
14163
|
}
|
|
14025
14164
|
const connection = connections.find((c) => c.name === connectionName);
|
|
14026
14165
|
if (!connection) {
|
|
14027
|
-
console.error(
|
|
14166
|
+
console.error(chalk145.red(`Connection "${connectionName}" not found.`));
|
|
14028
14167
|
console.error(
|
|
14029
14168
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14030
14169
|
);
|
|
@@ -14055,15 +14194,15 @@ async function ravendbCollections(connectionName) {
|
|
|
14055
14194
|
return;
|
|
14056
14195
|
}
|
|
14057
14196
|
for (const c of collections) {
|
|
14058
|
-
console.log(`${
|
|
14197
|
+
console.log(`${chalk146.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
14059
14198
|
}
|
|
14060
14199
|
}
|
|
14061
14200
|
|
|
14062
14201
|
// src/commands/ravendb/ravendbQuery.ts
|
|
14063
|
-
import
|
|
14202
|
+
import chalk148 from "chalk";
|
|
14064
14203
|
|
|
14065
14204
|
// src/commands/ravendb/fetchAllPages.ts
|
|
14066
|
-
import
|
|
14205
|
+
import chalk147 from "chalk";
|
|
14067
14206
|
|
|
14068
14207
|
// src/commands/ravendb/buildQueryPath.ts
|
|
14069
14208
|
function buildQueryPath(opts) {
|
|
@@ -14101,7 +14240,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14101
14240
|
allResults.push(...results);
|
|
14102
14241
|
start3 += results.length;
|
|
14103
14242
|
process.stderr.write(
|
|
14104
|
-
`\r${
|
|
14243
|
+
`\r${chalk147.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
14105
14244
|
);
|
|
14106
14245
|
if (start3 >= totalResults) break;
|
|
14107
14246
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -14116,7 +14255,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14116
14255
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
14117
14256
|
const resolved = resolveArgs(connectionName, collection);
|
|
14118
14257
|
if (!resolved.collection && !options2.query) {
|
|
14119
|
-
console.error(
|
|
14258
|
+
console.error(chalk148.red("Provide a collection name or --query filter."));
|
|
14120
14259
|
process.exit(1);
|
|
14121
14260
|
}
|
|
14122
14261
|
const { collection: col } = resolved;
|
|
@@ -14154,7 +14293,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
14154
14293
|
import * as path28 from "path";
|
|
14155
14294
|
|
|
14156
14295
|
// src/commands/refactor/logViolations.ts
|
|
14157
|
-
import
|
|
14296
|
+
import chalk149 from "chalk";
|
|
14158
14297
|
var DEFAULT_MAX_LINES = 100;
|
|
14159
14298
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
14160
14299
|
if (violations.length === 0) {
|
|
@@ -14163,43 +14302,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
14163
14302
|
}
|
|
14164
14303
|
return;
|
|
14165
14304
|
}
|
|
14166
|
-
console.error(
|
|
14305
|
+
console.error(chalk149.red(`
|
|
14167
14306
|
Refactor check failed:
|
|
14168
14307
|
`));
|
|
14169
|
-
console.error(
|
|
14308
|
+
console.error(chalk149.red(` The following files exceed ${maxLines} lines:
|
|
14170
14309
|
`));
|
|
14171
14310
|
for (const violation of violations) {
|
|
14172
|
-
console.error(
|
|
14311
|
+
console.error(chalk149.red(` ${violation.file} (${violation.lines} lines)`));
|
|
14173
14312
|
}
|
|
14174
14313
|
console.error(
|
|
14175
|
-
|
|
14314
|
+
chalk149.yellow(
|
|
14176
14315
|
`
|
|
14177
14316
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
14178
14317
|
way to refactor it, ignore it with:
|
|
14179
14318
|
`
|
|
14180
14319
|
)
|
|
14181
14320
|
);
|
|
14182
|
-
console.error(
|
|
14321
|
+
console.error(chalk149.gray(` assist refactor ignore <file>
|
|
14183
14322
|
`));
|
|
14184
14323
|
if (process.env.CLAUDECODE) {
|
|
14185
|
-
console.error(
|
|
14324
|
+
console.error(chalk149.cyan(`
|
|
14186
14325
|
## Extracting Code to New Files
|
|
14187
14326
|
`));
|
|
14188
14327
|
console.error(
|
|
14189
|
-
|
|
14328
|
+
chalk149.cyan(
|
|
14190
14329
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
14191
14330
|
`
|
|
14192
14331
|
)
|
|
14193
14332
|
);
|
|
14194
14333
|
console.error(
|
|
14195
|
-
|
|
14334
|
+
chalk149.cyan(
|
|
14196
14335
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
14197
14336
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
14198
14337
|
`
|
|
14199
14338
|
)
|
|
14200
14339
|
);
|
|
14201
14340
|
console.error(
|
|
14202
|
-
|
|
14341
|
+
chalk149.cyan(
|
|
14203
14342
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
14204
14343
|
domains, move it to a common/shared folder.
|
|
14205
14344
|
`
|
|
@@ -14210,17 +14349,17 @@ Refactor check failed:
|
|
|
14210
14349
|
|
|
14211
14350
|
// src/commands/refactor/check/getViolations/index.ts
|
|
14212
14351
|
import { execSync as execSync43 } from "child_process";
|
|
14213
|
-
import
|
|
14352
|
+
import fs21 from "fs";
|
|
14214
14353
|
import { minimatch as minimatch6 } from "minimatch";
|
|
14215
14354
|
|
|
14216
14355
|
// src/commands/refactor/check/getViolations/getIgnoredFiles.ts
|
|
14217
|
-
import
|
|
14356
|
+
import fs20 from "fs";
|
|
14218
14357
|
var REFACTOR_YML_PATH = "refactor.yml";
|
|
14219
14358
|
function parseRefactorYml() {
|
|
14220
|
-
if (!
|
|
14359
|
+
if (!fs20.existsSync(REFACTOR_YML_PATH)) {
|
|
14221
14360
|
return [];
|
|
14222
14361
|
}
|
|
14223
|
-
const content =
|
|
14362
|
+
const content = fs20.readFileSync(REFACTOR_YML_PATH, "utf8");
|
|
14224
14363
|
const entries = [];
|
|
14225
14364
|
const lines = content.split("\n");
|
|
14226
14365
|
let currentEntry = {};
|
|
@@ -14250,7 +14389,7 @@ function getIgnoredFiles() {
|
|
|
14250
14389
|
|
|
14251
14390
|
// src/commands/refactor/check/getViolations/index.ts
|
|
14252
14391
|
function countLines(filePath) {
|
|
14253
|
-
const content =
|
|
14392
|
+
const content = fs21.readFileSync(filePath, "utf8");
|
|
14254
14393
|
return content.split("\n").length;
|
|
14255
14394
|
}
|
|
14256
14395
|
function getGitFiles(options2) {
|
|
@@ -14355,7 +14494,7 @@ async function check(pattern2, options2) {
|
|
|
14355
14494
|
|
|
14356
14495
|
// src/commands/refactor/extract/index.ts
|
|
14357
14496
|
import path35 from "path";
|
|
14358
|
-
import
|
|
14497
|
+
import chalk152 from "chalk";
|
|
14359
14498
|
|
|
14360
14499
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
14361
14500
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -14930,23 +15069,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
14930
15069
|
|
|
14931
15070
|
// src/commands/refactor/extract/displayPlan.ts
|
|
14932
15071
|
import path32 from "path";
|
|
14933
|
-
import
|
|
15072
|
+
import chalk150 from "chalk";
|
|
14934
15073
|
function section(title) {
|
|
14935
15074
|
return `
|
|
14936
|
-
${
|
|
15075
|
+
${chalk150.cyan(title)}`;
|
|
14937
15076
|
}
|
|
14938
15077
|
function displayImporters(plan2, cwd) {
|
|
14939
15078
|
if (plan2.importersToUpdate.length === 0) return;
|
|
14940
15079
|
console.log(section("Update importers:"));
|
|
14941
15080
|
for (const imp of plan2.importersToUpdate) {
|
|
14942
15081
|
const rel = path32.relative(cwd, imp.file.getFilePath());
|
|
14943
|
-
console.log(` ${
|
|
15082
|
+
console.log(` ${chalk150.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
14944
15083
|
}
|
|
14945
15084
|
}
|
|
14946
15085
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
14947
|
-
console.log(
|
|
15086
|
+
console.log(chalk150.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
14948
15087
|
`));
|
|
14949
|
-
console.log(` ${
|
|
15088
|
+
console.log(` ${chalk150.cyan("Functions to move:")}`);
|
|
14950
15089
|
for (const name of plan2.extractedNames) {
|
|
14951
15090
|
console.log(` ${name}`);
|
|
14952
15091
|
}
|
|
@@ -14980,16 +15119,16 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
14980
15119
|
|
|
14981
15120
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
14982
15121
|
import path34 from "path";
|
|
14983
|
-
import
|
|
15122
|
+
import chalk151 from "chalk";
|
|
14984
15123
|
import { Project as Project4 } from "ts-morph";
|
|
14985
15124
|
|
|
14986
15125
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
14987
|
-
import
|
|
15126
|
+
import fs22 from "fs";
|
|
14988
15127
|
import path33 from "path";
|
|
14989
15128
|
import { Project as Project3 } from "ts-morph";
|
|
14990
15129
|
function findTsConfig(sourcePath) {
|
|
14991
15130
|
const rootConfig = path33.resolve("tsconfig.json");
|
|
14992
|
-
if (!
|
|
15131
|
+
if (!fs22.existsSync(rootConfig)) return rootConfig;
|
|
14993
15132
|
const tried = /* @__PURE__ */ new Set();
|
|
14994
15133
|
const candidates = [rootConfig, ...readReferences(rootConfig)];
|
|
14995
15134
|
for (const candidate of candidates) {
|
|
@@ -14997,7 +15136,7 @@ function findTsConfig(sourcePath) {
|
|
|
14997
15136
|
tried.add(candidate);
|
|
14998
15137
|
if (projectIncludes(candidate, sourcePath)) return candidate;
|
|
14999
15138
|
}
|
|
15000
|
-
const siblings =
|
|
15139
|
+
const siblings = fs22.readdirSync(path33.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path33.resolve(path33.dirname(rootConfig), f));
|
|
15001
15140
|
for (const sibling of siblings) {
|
|
15002
15141
|
if (tried.has(sibling)) continue;
|
|
15003
15142
|
tried.add(sibling);
|
|
@@ -15006,8 +15145,8 @@ function findTsConfig(sourcePath) {
|
|
|
15006
15145
|
return rootConfig;
|
|
15007
15146
|
}
|
|
15008
15147
|
function readReferences(configPath) {
|
|
15009
|
-
if (!
|
|
15010
|
-
const raw =
|
|
15148
|
+
if (!fs22.existsSync(configPath)) return [];
|
|
15149
|
+
const raw = fs22.readFileSync(configPath, "utf8");
|
|
15011
15150
|
const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
15012
15151
|
let parsed;
|
|
15013
15152
|
try {
|
|
@@ -15019,8 +15158,8 @@ function readReferences(configPath) {
|
|
|
15019
15158
|
const cwd = path33.dirname(configPath);
|
|
15020
15159
|
return parsed.references.map((ref) => {
|
|
15021
15160
|
const refPath = path33.resolve(cwd, ref.path);
|
|
15022
|
-
return
|
|
15023
|
-
}).filter((p) =>
|
|
15161
|
+
return fs22.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path33.join(refPath, "tsconfig.json") : refPath;
|
|
15162
|
+
}).filter((p) => fs22.existsSync(p));
|
|
15024
15163
|
}
|
|
15025
15164
|
function projectIncludes(configPath, sourcePath) {
|
|
15026
15165
|
try {
|
|
@@ -15040,7 +15179,7 @@ function loadProjectFile(file) {
|
|
|
15040
15179
|
});
|
|
15041
15180
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
15042
15181
|
if (!sourceFile) {
|
|
15043
|
-
console.log(
|
|
15182
|
+
console.log(chalk151.red(`File not found in project: ${file}`));
|
|
15044
15183
|
process.exit(1);
|
|
15045
15184
|
}
|
|
15046
15185
|
return { project, sourceFile };
|
|
@@ -15063,55 +15202,55 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
15063
15202
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
15064
15203
|
if (options2.apply) {
|
|
15065
15204
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
15066
|
-
console.log(
|
|
15205
|
+
console.log(chalk152.green("\nExtraction complete"));
|
|
15067
15206
|
} else {
|
|
15068
|
-
console.log(
|
|
15207
|
+
console.log(chalk152.dim("\nDry run. Use --apply to execute."));
|
|
15069
15208
|
}
|
|
15070
15209
|
}
|
|
15071
15210
|
|
|
15072
15211
|
// src/commands/refactor/ignore.ts
|
|
15073
|
-
import
|
|
15074
|
-
import
|
|
15212
|
+
import fs23 from "fs";
|
|
15213
|
+
import chalk153 from "chalk";
|
|
15075
15214
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
15076
15215
|
function ignore(file) {
|
|
15077
|
-
if (!
|
|
15078
|
-
console.error(
|
|
15216
|
+
if (!fs23.existsSync(file)) {
|
|
15217
|
+
console.error(chalk153.red(`Error: File does not exist: ${file}`));
|
|
15079
15218
|
process.exit(1);
|
|
15080
15219
|
}
|
|
15081
|
-
const content =
|
|
15220
|
+
const content = fs23.readFileSync(file, "utf8");
|
|
15082
15221
|
const lineCount = content.split("\n").length;
|
|
15083
15222
|
const maxLines = lineCount + 10;
|
|
15084
15223
|
const entry = `- file: ${file}
|
|
15085
15224
|
maxLines: ${maxLines}
|
|
15086
15225
|
`;
|
|
15087
|
-
if (
|
|
15088
|
-
const existing =
|
|
15089
|
-
|
|
15226
|
+
if (fs23.existsSync(REFACTOR_YML_PATH2)) {
|
|
15227
|
+
const existing = fs23.readFileSync(REFACTOR_YML_PATH2, "utf8");
|
|
15228
|
+
fs23.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
|
|
15090
15229
|
} else {
|
|
15091
|
-
|
|
15230
|
+
fs23.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
15092
15231
|
}
|
|
15093
15232
|
console.log(
|
|
15094
|
-
|
|
15233
|
+
chalk153.green(
|
|
15095
15234
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
15096
15235
|
)
|
|
15097
15236
|
);
|
|
15098
15237
|
}
|
|
15099
15238
|
|
|
15100
15239
|
// src/commands/refactor/rename/index.ts
|
|
15101
|
-
import
|
|
15240
|
+
import fs26 from "fs";
|
|
15102
15241
|
import path40 from "path";
|
|
15103
|
-
import
|
|
15242
|
+
import chalk156 from "chalk";
|
|
15104
15243
|
|
|
15105
15244
|
// src/commands/refactor/rename/applyRename.ts
|
|
15106
|
-
import
|
|
15245
|
+
import fs25 from "fs";
|
|
15107
15246
|
import path37 from "path";
|
|
15108
|
-
import
|
|
15247
|
+
import chalk154 from "chalk";
|
|
15109
15248
|
|
|
15110
15249
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
15111
15250
|
import path36 from "path";
|
|
15112
15251
|
|
|
15113
15252
|
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
15114
|
-
import
|
|
15253
|
+
import fs24 from "fs";
|
|
15115
15254
|
function getOrCreateList(map, key) {
|
|
15116
15255
|
const list4 = map.get(key) ?? [];
|
|
15117
15256
|
if (!map.has(key)) map.set(key, list4);
|
|
@@ -15130,7 +15269,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
|
15130
15269
|
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
15131
15270
|
}
|
|
15132
15271
|
function applyFileRewrites(file, fileRewrites) {
|
|
15133
|
-
let content =
|
|
15272
|
+
let content = fs24.readFileSync(file, "utf8");
|
|
15134
15273
|
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
15135
15274
|
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
15136
15275
|
}
|
|
@@ -15209,14 +15348,14 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
15209
15348
|
function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
15210
15349
|
const updatedContents = applyRewrites(rewrites);
|
|
15211
15350
|
for (const [file, content] of updatedContents) {
|
|
15212
|
-
|
|
15213
|
-
console.log(
|
|
15351
|
+
fs25.writeFileSync(file, content, "utf8");
|
|
15352
|
+
console.log(chalk154.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
15214
15353
|
}
|
|
15215
15354
|
const destDir = path37.dirname(destPath);
|
|
15216
|
-
if (!
|
|
15217
|
-
|
|
15355
|
+
if (!fs25.existsSync(destDir)) fs25.mkdirSync(destDir, { recursive: true });
|
|
15356
|
+
fs25.renameSync(sourcePath, destPath);
|
|
15218
15357
|
console.log(
|
|
15219
|
-
|
|
15358
|
+
chalk154.white(
|
|
15220
15359
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
15221
15360
|
)
|
|
15222
15361
|
);
|
|
@@ -15303,16 +15442,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
15303
15442
|
|
|
15304
15443
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
15305
15444
|
import path39 from "path";
|
|
15306
|
-
import
|
|
15445
|
+
import chalk155 from "chalk";
|
|
15307
15446
|
function printRenamePreview(rewrites, cwd) {
|
|
15308
15447
|
for (const rewrite of rewrites) {
|
|
15309
15448
|
console.log(
|
|
15310
|
-
|
|
15449
|
+
chalk155.dim(
|
|
15311
15450
|
` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
15312
15451
|
)
|
|
15313
15452
|
);
|
|
15314
15453
|
}
|
|
15315
|
-
console.log(
|
|
15454
|
+
console.log(chalk155.dim("Dry run. Use --apply to execute."));
|
|
15316
15455
|
}
|
|
15317
15456
|
|
|
15318
15457
|
// src/commands/refactor/rename/index.ts
|
|
@@ -15322,21 +15461,21 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15322
15461
|
const cwd = process.cwd();
|
|
15323
15462
|
const relSource = path40.relative(cwd, sourcePath);
|
|
15324
15463
|
const relDest = path40.relative(cwd, destPath);
|
|
15325
|
-
if (!
|
|
15326
|
-
console.log(
|
|
15464
|
+
if (!fs26.existsSync(sourcePath)) {
|
|
15465
|
+
console.log(chalk156.red(`File not found: ${source}`));
|
|
15327
15466
|
process.exit(1);
|
|
15328
15467
|
}
|
|
15329
|
-
if (destPath !== sourcePath &&
|
|
15330
|
-
console.log(
|
|
15468
|
+
if (destPath !== sourcePath && fs26.existsSync(destPath)) {
|
|
15469
|
+
console.log(chalk156.red(`Destination already exists: ${destination}`));
|
|
15331
15470
|
process.exit(1);
|
|
15332
15471
|
}
|
|
15333
|
-
console.log(
|
|
15334
|
-
console.log(
|
|
15335
|
-
console.log(
|
|
15472
|
+
console.log(chalk156.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
15473
|
+
console.log(chalk156.dim("Loading project..."));
|
|
15474
|
+
console.log(chalk156.dim("Scanning imports across the project..."));
|
|
15336
15475
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
15337
15476
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
15338
15477
|
console.log(
|
|
15339
|
-
|
|
15478
|
+
chalk156.dim(
|
|
15340
15479
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
15341
15480
|
)
|
|
15342
15481
|
);
|
|
@@ -15345,11 +15484,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15345
15484
|
return;
|
|
15346
15485
|
}
|
|
15347
15486
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
15348
|
-
console.log(
|
|
15487
|
+
console.log(chalk156.green("Done"));
|
|
15349
15488
|
}
|
|
15350
15489
|
|
|
15351
15490
|
// src/commands/refactor/renameSymbol/index.ts
|
|
15352
|
-
import
|
|
15491
|
+
import chalk157 from "chalk";
|
|
15353
15492
|
|
|
15354
15493
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
15355
15494
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -15395,33 +15534,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
15395
15534
|
const { project, sourceFile } = loadProjectFile(file);
|
|
15396
15535
|
const symbol = findSymbol(sourceFile, oldName);
|
|
15397
15536
|
if (!symbol) {
|
|
15398
|
-
console.log(
|
|
15537
|
+
console.log(chalk157.red(`Symbol "${oldName}" not found in ${file}`));
|
|
15399
15538
|
process.exit(1);
|
|
15400
15539
|
}
|
|
15401
15540
|
const grouped = groupReferences(symbol, cwd);
|
|
15402
15541
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
15403
15542
|
console.log(
|
|
15404
|
-
|
|
15543
|
+
chalk157.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
15405
15544
|
`)
|
|
15406
15545
|
);
|
|
15407
15546
|
for (const [refFile, lines] of grouped) {
|
|
15408
15547
|
console.log(
|
|
15409
|
-
` ${
|
|
15548
|
+
` ${chalk157.dim(refFile)}: lines ${chalk157.cyan(lines.join(", "))}`
|
|
15410
15549
|
);
|
|
15411
15550
|
}
|
|
15412
15551
|
if (options2.apply) {
|
|
15413
15552
|
symbol.rename(newName);
|
|
15414
15553
|
await project.save();
|
|
15415
|
-
console.log(
|
|
15554
|
+
console.log(chalk157.green(`
|
|
15416
15555
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
15417
15556
|
} else {
|
|
15418
|
-
console.log(
|
|
15557
|
+
console.log(chalk157.dim("\nDry run. Use --apply to execute."));
|
|
15419
15558
|
}
|
|
15420
15559
|
}
|
|
15421
15560
|
|
|
15422
15561
|
// src/commands/refactor/restructure/index.ts
|
|
15423
15562
|
import path48 from "path";
|
|
15424
|
-
import
|
|
15563
|
+
import chalk160 from "chalk";
|
|
15425
15564
|
|
|
15426
15565
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
15427
15566
|
import path42 from "path";
|
|
@@ -15500,50 +15639,50 @@ function clusterFiles(graph) {
|
|
|
15500
15639
|
|
|
15501
15640
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
15502
15641
|
import path44 from "path";
|
|
15503
|
-
import
|
|
15642
|
+
import chalk158 from "chalk";
|
|
15504
15643
|
function relPath(filePath) {
|
|
15505
15644
|
return path44.relative(process.cwd(), filePath);
|
|
15506
15645
|
}
|
|
15507
15646
|
function displayMoves(plan2) {
|
|
15508
15647
|
if (plan2.moves.length === 0) return;
|
|
15509
|
-
console.log(
|
|
15648
|
+
console.log(chalk158.bold("\nFile moves:"));
|
|
15510
15649
|
for (const move of plan2.moves) {
|
|
15511
15650
|
console.log(
|
|
15512
|
-
` ${
|
|
15651
|
+
` ${chalk158.red(relPath(move.from))} \u2192 ${chalk158.green(relPath(move.to))}`
|
|
15513
15652
|
);
|
|
15514
|
-
console.log(
|
|
15653
|
+
console.log(chalk158.dim(` ${move.reason}`));
|
|
15515
15654
|
}
|
|
15516
15655
|
}
|
|
15517
15656
|
function displayRewrites(rewrites) {
|
|
15518
15657
|
if (rewrites.length === 0) return;
|
|
15519
15658
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
15520
|
-
console.log(
|
|
15659
|
+
console.log(chalk158.bold(`
|
|
15521
15660
|
Import rewrites (${affectedFiles.size} files):`));
|
|
15522
15661
|
for (const file of affectedFiles) {
|
|
15523
|
-
console.log(` ${
|
|
15662
|
+
console.log(` ${chalk158.cyan(relPath(file))}:`);
|
|
15524
15663
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
15525
15664
|
(r) => r.file === file
|
|
15526
15665
|
)) {
|
|
15527
15666
|
console.log(
|
|
15528
|
-
` ${
|
|
15667
|
+
` ${chalk158.red(`"${oldSpecifier}"`)} \u2192 ${chalk158.green(`"${newSpecifier}"`)}`
|
|
15529
15668
|
);
|
|
15530
15669
|
}
|
|
15531
15670
|
}
|
|
15532
15671
|
}
|
|
15533
15672
|
function displayPlan2(plan2) {
|
|
15534
15673
|
if (plan2.warnings.length > 0) {
|
|
15535
|
-
console.log(
|
|
15536
|
-
for (const w of plan2.warnings) console.log(
|
|
15674
|
+
console.log(chalk158.yellow("\nWarnings:"));
|
|
15675
|
+
for (const w of plan2.warnings) console.log(chalk158.yellow(` ${w}`));
|
|
15537
15676
|
}
|
|
15538
15677
|
if (plan2.newDirectories.length > 0) {
|
|
15539
|
-
console.log(
|
|
15678
|
+
console.log(chalk158.bold("\nNew directories:"));
|
|
15540
15679
|
for (const dir of plan2.newDirectories)
|
|
15541
|
-
console.log(
|
|
15680
|
+
console.log(chalk158.green(` ${dir}/`));
|
|
15542
15681
|
}
|
|
15543
15682
|
displayMoves(plan2);
|
|
15544
15683
|
displayRewrites(plan2.rewrites);
|
|
15545
15684
|
console.log(
|
|
15546
|
-
|
|
15685
|
+
chalk158.dim(
|
|
15547
15686
|
`
|
|
15548
15687
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
15549
15688
|
)
|
|
@@ -15551,29 +15690,29 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
15551
15690
|
}
|
|
15552
15691
|
|
|
15553
15692
|
// src/commands/refactor/restructure/executePlan.ts
|
|
15554
|
-
import
|
|
15693
|
+
import fs27 from "fs";
|
|
15555
15694
|
import path45 from "path";
|
|
15556
|
-
import
|
|
15695
|
+
import chalk159 from "chalk";
|
|
15557
15696
|
function executePlan(plan2) {
|
|
15558
15697
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
15559
15698
|
for (const [file, content] of updatedContents) {
|
|
15560
|
-
|
|
15699
|
+
fs27.writeFileSync(file, content, "utf8");
|
|
15561
15700
|
console.log(
|
|
15562
|
-
|
|
15701
|
+
chalk159.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
15563
15702
|
);
|
|
15564
15703
|
}
|
|
15565
15704
|
for (const dir of plan2.newDirectories) {
|
|
15566
|
-
|
|
15567
|
-
console.log(
|
|
15705
|
+
fs27.mkdirSync(dir, { recursive: true });
|
|
15706
|
+
console.log(chalk159.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
15568
15707
|
}
|
|
15569
15708
|
for (const move of plan2.moves) {
|
|
15570
15709
|
const targetDir = path45.dirname(move.to);
|
|
15571
|
-
if (!
|
|
15572
|
-
|
|
15710
|
+
if (!fs27.existsSync(targetDir)) {
|
|
15711
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
15573
15712
|
}
|
|
15574
|
-
|
|
15713
|
+
fs27.renameSync(move.from, move.to);
|
|
15575
15714
|
console.log(
|
|
15576
|
-
|
|
15715
|
+
chalk159.white(
|
|
15577
15716
|
` Moved ${path45.relative(process.cwd(), move.from)} \u2192 ${path45.relative(process.cwd(), move.to)}`
|
|
15578
15717
|
)
|
|
15579
15718
|
);
|
|
@@ -15583,12 +15722,12 @@ function executePlan(plan2) {
|
|
|
15583
15722
|
function removeEmptyDirectories(dirs) {
|
|
15584
15723
|
const unique = [...new Set(dirs)];
|
|
15585
15724
|
for (const dir of unique) {
|
|
15586
|
-
if (!
|
|
15587
|
-
const entries =
|
|
15725
|
+
if (!fs27.existsSync(dir)) continue;
|
|
15726
|
+
const entries = fs27.readdirSync(dir);
|
|
15588
15727
|
if (entries.length === 0) {
|
|
15589
|
-
|
|
15728
|
+
fs27.rmdirSync(dir);
|
|
15590
15729
|
console.log(
|
|
15591
|
-
|
|
15730
|
+
chalk159.dim(
|
|
15592
15731
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
15593
15732
|
)
|
|
15594
15733
|
);
|
|
@@ -15600,18 +15739,18 @@ function removeEmptyDirectories(dirs) {
|
|
|
15600
15739
|
import path47 from "path";
|
|
15601
15740
|
|
|
15602
15741
|
// src/commands/refactor/restructure/planFileMoves/shared.ts
|
|
15603
|
-
import
|
|
15742
|
+
import fs28 from "fs";
|
|
15604
15743
|
function emptyResult() {
|
|
15605
15744
|
return { moves: [], directories: [], warnings: [] };
|
|
15606
15745
|
}
|
|
15607
15746
|
function checkDirConflict(result, label2, dir) {
|
|
15608
|
-
if (!
|
|
15747
|
+
if (!fs28.existsSync(dir)) return false;
|
|
15609
15748
|
result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
|
|
15610
15749
|
return true;
|
|
15611
15750
|
}
|
|
15612
15751
|
|
|
15613
15752
|
// src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
|
|
15614
|
-
import
|
|
15753
|
+
import fs29 from "fs";
|
|
15615
15754
|
import path46 from "path";
|
|
15616
15755
|
function collectEntry(results, dir, entry) {
|
|
15617
15756
|
const full = path46.join(dir, entry.name);
|
|
@@ -15619,9 +15758,9 @@ function collectEntry(results, dir, entry) {
|
|
|
15619
15758
|
results.push(...items2);
|
|
15620
15759
|
}
|
|
15621
15760
|
function listFilesRecursive(dir) {
|
|
15622
|
-
if (!
|
|
15761
|
+
if (!fs29.existsSync(dir)) return [];
|
|
15623
15762
|
const results = [];
|
|
15624
|
-
for (const entry of
|
|
15763
|
+
for (const entry of fs29.readdirSync(dir, { withFileTypes: true })) {
|
|
15625
15764
|
collectEntry(results, dir, entry);
|
|
15626
15765
|
}
|
|
15627
15766
|
return results;
|
|
@@ -15721,22 +15860,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
15721
15860
|
const targetPattern = pattern2 ?? "src";
|
|
15722
15861
|
const files = findSourceFiles2(targetPattern);
|
|
15723
15862
|
if (files.length === 0) {
|
|
15724
|
-
console.log(
|
|
15863
|
+
console.log(chalk160.yellow("No files found matching pattern"));
|
|
15725
15864
|
return;
|
|
15726
15865
|
}
|
|
15727
15866
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
15728
15867
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
15729
15868
|
if (plan2.moves.length === 0) {
|
|
15730
|
-
console.log(
|
|
15869
|
+
console.log(chalk160.green("No restructuring needed"));
|
|
15731
15870
|
return;
|
|
15732
15871
|
}
|
|
15733
15872
|
displayPlan2(plan2);
|
|
15734
15873
|
if (options2.apply) {
|
|
15735
|
-
console.log(
|
|
15874
|
+
console.log(chalk160.bold("\nApplying changes..."));
|
|
15736
15875
|
executePlan(plan2);
|
|
15737
|
-
console.log(
|
|
15876
|
+
console.log(chalk160.green("\nRestructuring complete"));
|
|
15738
15877
|
} else {
|
|
15739
|
-
console.log(
|
|
15878
|
+
console.log(chalk160.dim("\nDry run. Use --apply to execute."));
|
|
15740
15879
|
}
|
|
15741
15880
|
}
|
|
15742
15881
|
|
|
@@ -16305,18 +16444,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
16305
16444
|
}
|
|
16306
16445
|
|
|
16307
16446
|
// src/commands/review/warnOutOfDiff.ts
|
|
16308
|
-
import
|
|
16447
|
+
import chalk161 from "chalk";
|
|
16309
16448
|
function warnOutOfDiff(outOfDiff) {
|
|
16310
16449
|
if (outOfDiff.length === 0) return;
|
|
16311
16450
|
console.warn(
|
|
16312
|
-
|
|
16451
|
+
chalk161.yellow(
|
|
16313
16452
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
16314
16453
|
)
|
|
16315
16454
|
);
|
|
16316
16455
|
for (const finding of outOfDiff) {
|
|
16317
16456
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
16318
16457
|
console.warn(
|
|
16319
|
-
` ${
|
|
16458
|
+
` ${chalk161.yellow("\xB7")} ${finding.title} ${chalk161.dim(
|
|
16320
16459
|
`(${finding.file}:${range})`
|
|
16321
16460
|
)}`
|
|
16322
16461
|
);
|
|
@@ -16335,18 +16474,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
16335
16474
|
}
|
|
16336
16475
|
|
|
16337
16476
|
// src/commands/review/warnUnlocated.ts
|
|
16338
|
-
import
|
|
16477
|
+
import chalk162 from "chalk";
|
|
16339
16478
|
function warnUnlocated(unlocated) {
|
|
16340
16479
|
if (unlocated.length === 0) return;
|
|
16341
16480
|
console.warn(
|
|
16342
|
-
|
|
16481
|
+
chalk162.yellow(
|
|
16343
16482
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
16344
16483
|
)
|
|
16345
16484
|
);
|
|
16346
16485
|
for (const finding of unlocated) {
|
|
16347
|
-
const where = finding.location ||
|
|
16486
|
+
const where = finding.location || chalk162.dim("missing");
|
|
16348
16487
|
console.warn(
|
|
16349
|
-
` ${
|
|
16488
|
+
` ${chalk162.yellow("\xB7")} ${finding.title} ${chalk162.dim(`(${where})`)}`
|
|
16350
16489
|
);
|
|
16351
16490
|
}
|
|
16352
16491
|
}
|
|
@@ -17517,7 +17656,7 @@ function registerReview(program2) {
|
|
|
17517
17656
|
}
|
|
17518
17657
|
|
|
17519
17658
|
// src/commands/seq/seqAuth.ts
|
|
17520
|
-
import
|
|
17659
|
+
import chalk164 from "chalk";
|
|
17521
17660
|
|
|
17522
17661
|
// src/commands/seq/loadConnections.ts
|
|
17523
17662
|
function loadConnections2() {
|
|
@@ -17546,10 +17685,10 @@ function setDefaultConnection(name) {
|
|
|
17546
17685
|
}
|
|
17547
17686
|
|
|
17548
17687
|
// src/shared/assertUniqueName.ts
|
|
17549
|
-
import
|
|
17688
|
+
import chalk163 from "chalk";
|
|
17550
17689
|
function assertUniqueName(existingNames, name) {
|
|
17551
17690
|
if (existingNames.includes(name)) {
|
|
17552
|
-
console.error(
|
|
17691
|
+
console.error(chalk163.red(`Connection "${name}" already exists.`));
|
|
17553
17692
|
process.exit(1);
|
|
17554
17693
|
}
|
|
17555
17694
|
}
|
|
@@ -17567,16 +17706,16 @@ async function promptConnection2(existingNames) {
|
|
|
17567
17706
|
var seqAuth = createConnectionAuth({
|
|
17568
17707
|
load: loadConnections2,
|
|
17569
17708
|
save: saveConnections2,
|
|
17570
|
-
format: (c) => `${
|
|
17709
|
+
format: (c) => `${chalk164.bold(c.name)} ${c.url}`,
|
|
17571
17710
|
promptNew: promptConnection2,
|
|
17572
17711
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
17573
17712
|
});
|
|
17574
17713
|
|
|
17575
17714
|
// src/commands/seq/seqQuery.ts
|
|
17576
|
-
import
|
|
17715
|
+
import chalk168 from "chalk";
|
|
17577
17716
|
|
|
17578
17717
|
// src/commands/seq/fetchSeq.ts
|
|
17579
|
-
import
|
|
17718
|
+
import chalk165 from "chalk";
|
|
17580
17719
|
async function fetchSeq(conn, path57, params) {
|
|
17581
17720
|
const url = `${conn.url}${path57}?${params}`;
|
|
17582
17721
|
const response = await fetch(url, {
|
|
@@ -17587,7 +17726,7 @@ async function fetchSeq(conn, path57, params) {
|
|
|
17587
17726
|
});
|
|
17588
17727
|
if (!response.ok) {
|
|
17589
17728
|
const body = await response.text();
|
|
17590
|
-
console.error(
|
|
17729
|
+
console.error(chalk165.red(`Seq returned ${response.status}: ${body}`));
|
|
17591
17730
|
process.exit(1);
|
|
17592
17731
|
}
|
|
17593
17732
|
return response;
|
|
@@ -17646,23 +17785,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
17646
17785
|
}
|
|
17647
17786
|
|
|
17648
17787
|
// src/commands/seq/formatEvent.ts
|
|
17649
|
-
import
|
|
17788
|
+
import chalk166 from "chalk";
|
|
17650
17789
|
function levelColor(level) {
|
|
17651
17790
|
switch (level) {
|
|
17652
17791
|
case "Fatal":
|
|
17653
|
-
return
|
|
17792
|
+
return chalk166.bgRed.white;
|
|
17654
17793
|
case "Error":
|
|
17655
|
-
return
|
|
17794
|
+
return chalk166.red;
|
|
17656
17795
|
case "Warning":
|
|
17657
|
-
return
|
|
17796
|
+
return chalk166.yellow;
|
|
17658
17797
|
case "Information":
|
|
17659
|
-
return
|
|
17798
|
+
return chalk166.cyan;
|
|
17660
17799
|
case "Debug":
|
|
17661
|
-
return
|
|
17800
|
+
return chalk166.gray;
|
|
17662
17801
|
case "Verbose":
|
|
17663
|
-
return
|
|
17802
|
+
return chalk166.dim;
|
|
17664
17803
|
default:
|
|
17665
|
-
return
|
|
17804
|
+
return chalk166.white;
|
|
17666
17805
|
}
|
|
17667
17806
|
}
|
|
17668
17807
|
function levelAbbrev(level) {
|
|
@@ -17703,12 +17842,12 @@ function formatTimestamp(iso) {
|
|
|
17703
17842
|
function formatEvent(event) {
|
|
17704
17843
|
const color = levelColor(event.Level);
|
|
17705
17844
|
const abbrev = levelAbbrev(event.Level);
|
|
17706
|
-
const ts8 =
|
|
17845
|
+
const ts8 = chalk166.dim(formatTimestamp(event.Timestamp));
|
|
17707
17846
|
const msg = renderMessage(event);
|
|
17708
17847
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
17709
17848
|
if (event.Exception) {
|
|
17710
17849
|
for (const line of event.Exception.split("\n")) {
|
|
17711
|
-
lines.push(
|
|
17850
|
+
lines.push(chalk166.red(` ${line}`));
|
|
17712
17851
|
}
|
|
17713
17852
|
}
|
|
17714
17853
|
return lines.join("\n");
|
|
@@ -17741,11 +17880,11 @@ function rejectTimestampFilter(filter) {
|
|
|
17741
17880
|
}
|
|
17742
17881
|
|
|
17743
17882
|
// src/shared/resolveNamedConnection.ts
|
|
17744
|
-
import
|
|
17883
|
+
import chalk167 from "chalk";
|
|
17745
17884
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
17746
17885
|
if (connections.length === 0) {
|
|
17747
17886
|
console.error(
|
|
17748
|
-
|
|
17887
|
+
chalk167.red(
|
|
17749
17888
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
17750
17889
|
)
|
|
17751
17890
|
);
|
|
@@ -17754,7 +17893,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
17754
17893
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
17755
17894
|
const connection = connections.find((c) => c.name === target);
|
|
17756
17895
|
if (!connection) {
|
|
17757
|
-
console.error(
|
|
17896
|
+
console.error(chalk167.red(`${kind} connection "${target}" not found.`));
|
|
17758
17897
|
process.exit(1);
|
|
17759
17898
|
}
|
|
17760
17899
|
return connection;
|
|
@@ -17783,7 +17922,7 @@ async function seqQuery(filter, options2) {
|
|
|
17783
17922
|
new URLSearchParams({ filter, count: String(count6) })
|
|
17784
17923
|
);
|
|
17785
17924
|
if (events.length === 0) {
|
|
17786
|
-
console.log(
|
|
17925
|
+
console.log(chalk168.yellow("No events found."));
|
|
17787
17926
|
return;
|
|
17788
17927
|
}
|
|
17789
17928
|
if (options2.json) {
|
|
@@ -17794,11 +17933,11 @@ async function seqQuery(filter, options2) {
|
|
|
17794
17933
|
for (const event of chronological) {
|
|
17795
17934
|
console.log(formatEvent(event));
|
|
17796
17935
|
}
|
|
17797
|
-
console.log(
|
|
17936
|
+
console.log(chalk168.dim(`
|
|
17798
17937
|
${events.length} events`));
|
|
17799
17938
|
if (events.length >= count6) {
|
|
17800
17939
|
console.log(
|
|
17801
|
-
|
|
17940
|
+
chalk168.yellow(
|
|
17802
17941
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
17803
17942
|
)
|
|
17804
17943
|
);
|
|
@@ -17806,10 +17945,10 @@ ${events.length} events`));
|
|
|
17806
17945
|
}
|
|
17807
17946
|
|
|
17808
17947
|
// src/shared/setNamedDefaultConnection.ts
|
|
17809
|
-
import
|
|
17948
|
+
import chalk169 from "chalk";
|
|
17810
17949
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
17811
17950
|
if (!connections.find((c) => c.name === name)) {
|
|
17812
|
-
console.error(
|
|
17951
|
+
console.error(chalk169.red(`Connection "${name}" not found.`));
|
|
17813
17952
|
process.exit(1);
|
|
17814
17953
|
}
|
|
17815
17954
|
setDefault(name);
|
|
@@ -17857,7 +17996,7 @@ function registerSignal(program2) {
|
|
|
17857
17996
|
}
|
|
17858
17997
|
|
|
17859
17998
|
// src/commands/sql/sqlAuth.ts
|
|
17860
|
-
import
|
|
17999
|
+
import chalk171 from "chalk";
|
|
17861
18000
|
|
|
17862
18001
|
// src/commands/sql/loadConnections.ts
|
|
17863
18002
|
function loadConnections3() {
|
|
@@ -17886,7 +18025,7 @@ function setDefaultConnection2(name) {
|
|
|
17886
18025
|
}
|
|
17887
18026
|
|
|
17888
18027
|
// src/commands/sql/promptConnection.ts
|
|
17889
|
-
import
|
|
18028
|
+
import chalk170 from "chalk";
|
|
17890
18029
|
async function promptConnection3(existingNames) {
|
|
17891
18030
|
const name = await promptInput("name", "Connection name:", "default");
|
|
17892
18031
|
assertUniqueName(existingNames, name);
|
|
@@ -17894,7 +18033,7 @@ async function promptConnection3(existingNames) {
|
|
|
17894
18033
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
17895
18034
|
const port = Number.parseInt(portStr, 10);
|
|
17896
18035
|
if (!Number.isFinite(port)) {
|
|
17897
|
-
console.error(
|
|
18036
|
+
console.error(chalk170.red(`Invalid port "${portStr}".`));
|
|
17898
18037
|
process.exit(1);
|
|
17899
18038
|
}
|
|
17900
18039
|
const user = await promptInput("user", "User:");
|
|
@@ -17907,13 +18046,13 @@ async function promptConnection3(existingNames) {
|
|
|
17907
18046
|
var sqlAuth = createConnectionAuth({
|
|
17908
18047
|
load: loadConnections3,
|
|
17909
18048
|
save: saveConnections3,
|
|
17910
|
-
format: (c) => `${
|
|
18049
|
+
format: (c) => `${chalk171.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
17911
18050
|
promptNew: promptConnection3,
|
|
17912
18051
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
17913
18052
|
});
|
|
17914
18053
|
|
|
17915
18054
|
// src/commands/sql/printTable.ts
|
|
17916
|
-
import
|
|
18055
|
+
import chalk172 from "chalk";
|
|
17917
18056
|
function formatCell(value) {
|
|
17918
18057
|
if (value === null || value === void 0) return "";
|
|
17919
18058
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -17922,7 +18061,7 @@ function formatCell(value) {
|
|
|
17922
18061
|
}
|
|
17923
18062
|
function printTable(rows) {
|
|
17924
18063
|
if (rows.length === 0) {
|
|
17925
|
-
console.log(
|
|
18064
|
+
console.log(chalk172.yellow("(no rows)"));
|
|
17926
18065
|
return;
|
|
17927
18066
|
}
|
|
17928
18067
|
const columns = Object.keys(rows[0]);
|
|
@@ -17930,13 +18069,13 @@ function printTable(rows) {
|
|
|
17930
18069
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
17931
18070
|
);
|
|
17932
18071
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
17933
|
-
console.log(
|
|
17934
|
-
console.log(
|
|
18072
|
+
console.log(chalk172.dim(header));
|
|
18073
|
+
console.log(chalk172.dim("-".repeat(header.length)));
|
|
17935
18074
|
for (const row of rows) {
|
|
17936
18075
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
17937
18076
|
console.log(line);
|
|
17938
18077
|
}
|
|
17939
|
-
console.log(
|
|
18078
|
+
console.log(chalk172.dim(`
|
|
17940
18079
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
17941
18080
|
}
|
|
17942
18081
|
|
|
@@ -17996,7 +18135,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
17996
18135
|
}
|
|
17997
18136
|
|
|
17998
18137
|
// src/commands/sql/sqlMutate.ts
|
|
17999
|
-
import
|
|
18138
|
+
import chalk173 from "chalk";
|
|
18000
18139
|
|
|
18001
18140
|
// src/commands/sql/isMutation.ts
|
|
18002
18141
|
var MUTATION_KEYWORDS = [
|
|
@@ -18030,7 +18169,7 @@ function isMutation(sql6) {
|
|
|
18030
18169
|
async function sqlMutate(query, connectionName) {
|
|
18031
18170
|
if (!isMutation(query)) {
|
|
18032
18171
|
console.error(
|
|
18033
|
-
|
|
18172
|
+
chalk173.red(
|
|
18034
18173
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
18035
18174
|
)
|
|
18036
18175
|
);
|
|
@@ -18040,18 +18179,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
18040
18179
|
const pool = await sqlConnect(conn);
|
|
18041
18180
|
try {
|
|
18042
18181
|
const result = await pool.request().query(query);
|
|
18043
|
-
console.log(
|
|
18182
|
+
console.log(chalk173.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
18044
18183
|
} finally {
|
|
18045
18184
|
await pool.close();
|
|
18046
18185
|
}
|
|
18047
18186
|
}
|
|
18048
18187
|
|
|
18049
18188
|
// src/commands/sql/sqlQuery.ts
|
|
18050
|
-
import
|
|
18189
|
+
import chalk174 from "chalk";
|
|
18051
18190
|
async function sqlQuery(query, connectionName) {
|
|
18052
18191
|
if (isMutation(query)) {
|
|
18053
18192
|
console.error(
|
|
18054
|
-
|
|
18193
|
+
chalk174.red(
|
|
18055
18194
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
18056
18195
|
)
|
|
18057
18196
|
);
|
|
@@ -18066,7 +18205,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
18066
18205
|
printTable(rows);
|
|
18067
18206
|
} else {
|
|
18068
18207
|
console.log(
|
|
18069
|
-
|
|
18208
|
+
chalk174.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
18070
18209
|
);
|
|
18071
18210
|
}
|
|
18072
18211
|
} finally {
|
|
@@ -18646,14 +18785,14 @@ import {
|
|
|
18646
18785
|
import { dirname as dirname24, join as join50 } from "path";
|
|
18647
18786
|
|
|
18648
18787
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
18649
|
-
import
|
|
18788
|
+
import chalk175 from "chalk";
|
|
18650
18789
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
18651
18790
|
function validateStagedContent(filename, content) {
|
|
18652
18791
|
const firstLine = content.split("\n")[0];
|
|
18653
18792
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
18654
18793
|
if (!match) {
|
|
18655
18794
|
console.error(
|
|
18656
|
-
|
|
18795
|
+
chalk175.red(
|
|
18657
18796
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
18658
18797
|
)
|
|
18659
18798
|
);
|
|
@@ -18662,7 +18801,7 @@ function validateStagedContent(filename, content) {
|
|
|
18662
18801
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
18663
18802
|
if (!contentAfterLink) {
|
|
18664
18803
|
console.error(
|
|
18665
|
-
|
|
18804
|
+
chalk175.red(
|
|
18666
18805
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
18667
18806
|
)
|
|
18668
18807
|
);
|
|
@@ -19064,7 +19203,7 @@ function registerVoice(program2) {
|
|
|
19064
19203
|
|
|
19065
19204
|
// src/commands/roam/auth.ts
|
|
19066
19205
|
import { randomBytes } from "crypto";
|
|
19067
|
-
import
|
|
19206
|
+
import chalk176 from "chalk";
|
|
19068
19207
|
|
|
19069
19208
|
// src/commands/roam/waitForCallback.ts
|
|
19070
19209
|
import { createServer as createServer3 } from "http";
|
|
@@ -19195,13 +19334,13 @@ async function auth() {
|
|
|
19195
19334
|
saveGlobalConfig(config);
|
|
19196
19335
|
const state = randomBytes(16).toString("hex");
|
|
19197
19336
|
console.log(
|
|
19198
|
-
|
|
19337
|
+
chalk176.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
19199
19338
|
);
|
|
19200
|
-
console.log(
|
|
19201
|
-
console.log(
|
|
19202
|
-
console.log(
|
|
19339
|
+
console.log(chalk176.white("http://localhost:14523/callback\n"));
|
|
19340
|
+
console.log(chalk176.blue("Opening browser for authorization..."));
|
|
19341
|
+
console.log(chalk176.dim("Waiting for authorization callback..."));
|
|
19203
19342
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
19204
|
-
console.log(
|
|
19343
|
+
console.log(chalk176.dim("Exchanging code for tokens..."));
|
|
19205
19344
|
const tokens = await exchangeToken({
|
|
19206
19345
|
code,
|
|
19207
19346
|
clientId,
|
|
@@ -19217,7 +19356,7 @@ async function auth() {
|
|
|
19217
19356
|
};
|
|
19218
19357
|
saveGlobalConfig(config);
|
|
19219
19358
|
console.log(
|
|
19220
|
-
|
|
19359
|
+
chalk176.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
19221
19360
|
);
|
|
19222
19361
|
}
|
|
19223
19362
|
|
|
@@ -19669,7 +19808,7 @@ import { execSync as execSync50 } from "child_process";
|
|
|
19669
19808
|
import { existsSync as existsSync51, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync37 } from "fs";
|
|
19670
19809
|
import { tmpdir as tmpdir7 } from "os";
|
|
19671
19810
|
import { join as join61, resolve as resolve15 } from "path";
|
|
19672
|
-
import
|
|
19811
|
+
import chalk177 from "chalk";
|
|
19673
19812
|
|
|
19674
19813
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
19675
19814
|
var captureWindowPs1 = `
|
|
@@ -19820,13 +19959,13 @@ function screenshot(processName) {
|
|
|
19820
19959
|
const config = loadConfig();
|
|
19821
19960
|
const outputDir = resolve15(config.screenshot.outputDir);
|
|
19822
19961
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
19823
|
-
console.log(
|
|
19962
|
+
console.log(chalk177.gray(`Capturing window for process "${processName}" ...`));
|
|
19824
19963
|
try {
|
|
19825
19964
|
runPowerShellScript(processName, outputPath);
|
|
19826
|
-
console.log(
|
|
19965
|
+
console.log(chalk177.green(`Screenshot saved: ${outputPath}`));
|
|
19827
19966
|
} catch (error) {
|
|
19828
19967
|
const msg = error instanceof Error ? error.message : String(error);
|
|
19829
|
-
console.error(
|
|
19968
|
+
console.error(chalk177.red(`Failed to capture screenshot: ${msg}`));
|
|
19830
19969
|
process.exit(1);
|
|
19831
19970
|
}
|
|
19832
19971
|
}
|
|
@@ -19939,6 +20078,13 @@ import { createInterface as createInterface5 } from "readline";
|
|
|
19939
20078
|
|
|
19940
20079
|
// src/commands/sessions/daemon/loadPersistedSessions.ts
|
|
19941
20080
|
import { z as z5 } from "zod";
|
|
20081
|
+
|
|
20082
|
+
// src/commands/sessions/daemon/daemonLog.ts
|
|
20083
|
+
function daemonLog(message) {
|
|
20084
|
+
console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message}`);
|
|
20085
|
+
}
|
|
20086
|
+
|
|
20087
|
+
// src/commands/sessions/daemon/loadPersistedSessions.ts
|
|
19942
20088
|
var SESSIONS_FILE = "sessions.json";
|
|
19943
20089
|
var persistedSessionSchema = z5.object({
|
|
19944
20090
|
name: z5.string(),
|
|
@@ -19964,8 +20110,19 @@ function savePersistedSessions(sessions) {
|
|
|
19964
20110
|
saveJson(SESSIONS_FILE, sessions);
|
|
19965
20111
|
}
|
|
19966
20112
|
function persistLiveSessions(sessions) {
|
|
19967
|
-
|
|
19968
|
-
|
|
20113
|
+
const live = [...sessions.values()].filter(
|
|
20114
|
+
(s) => s.pty && s.status !== "done"
|
|
20115
|
+
);
|
|
20116
|
+
savePersistedSessions(live.map(toPersistedSession));
|
|
20117
|
+
logPersist(live);
|
|
20118
|
+
}
|
|
20119
|
+
var lastPersistSignature = "";
|
|
20120
|
+
function logPersist(live) {
|
|
20121
|
+
const signature = live.map((s) => `${s.id}:${s.status}`).join(",");
|
|
20122
|
+
if (signature === lastPersistSignature) return;
|
|
20123
|
+
lastPersistSignature = signature;
|
|
20124
|
+
daemonLog(
|
|
20125
|
+
live.length > 0 ? `persisted ${live.length} session(s): ${live.map((s) => s.name).join(", ")}` : "persisted 0 sessions (sessions.json cleared)"
|
|
19969
20126
|
);
|
|
19970
20127
|
}
|
|
19971
20128
|
function toPersistedSession(session) {
|
|
@@ -20039,11 +20196,6 @@ function createAutoExit(exit, graceMs = DEFAULT_GRACE_MS) {
|
|
|
20039
20196
|
};
|
|
20040
20197
|
}
|
|
20041
20198
|
|
|
20042
|
-
// src/commands/sessions/daemon/daemonLog.ts
|
|
20043
|
-
function daemonLog(message) {
|
|
20044
|
-
console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message}`);
|
|
20045
|
-
}
|
|
20046
|
-
|
|
20047
20199
|
// src/commands/sessions/daemon/loadActiveSelection.ts
|
|
20048
20200
|
import { z as z6 } from "zod";
|
|
20049
20201
|
var ACTIVE_FILE = "active.json";
|
|
@@ -20250,6 +20402,29 @@ function createAssistSession(id2, assistArgs, cwd) {
|
|
|
20250
20402
|
};
|
|
20251
20403
|
}
|
|
20252
20404
|
|
|
20405
|
+
// src/commands/sessions/daemon/dismissSession.ts
|
|
20406
|
+
function dismissSession(sessions, id2) {
|
|
20407
|
+
const s = sessions.get(id2);
|
|
20408
|
+
if (!s) return false;
|
|
20409
|
+
if (s.status !== "done") s.pty?.kill();
|
|
20410
|
+
s.activityWatcher?.close();
|
|
20411
|
+
removeActivity(s.id);
|
|
20412
|
+
if (s.activity?.itemId != null) releaseLock(s.activity.itemId);
|
|
20413
|
+
sessions.delete(id2);
|
|
20414
|
+
daemonLog(`session ${id2} dismissed (${s.name})`);
|
|
20415
|
+
return true;
|
|
20416
|
+
}
|
|
20417
|
+
function drainSessions(sessions, onDrained) {
|
|
20418
|
+
const names = [...sessions.values()].map((s) => s.name);
|
|
20419
|
+
const ids = [...sessions.keys()];
|
|
20420
|
+
for (const id2 of ids) dismissSession(sessions, id2);
|
|
20421
|
+
onDrained();
|
|
20422
|
+
daemonLog(
|
|
20423
|
+
ids.length > 0 ? `drained ${ids.length} session(s): ${names.join(", ")}` : "drained 0 sessions"
|
|
20424
|
+
);
|
|
20425
|
+
return ids.length;
|
|
20426
|
+
}
|
|
20427
|
+
|
|
20253
20428
|
// src/commands/sessions/daemon/createSession.ts
|
|
20254
20429
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
20255
20430
|
|
|
@@ -20324,6 +20499,13 @@ function greetClient(client, sessions, windowsProxy) {
|
|
|
20324
20499
|
void windowsProxy.discover();
|
|
20325
20500
|
}
|
|
20326
20501
|
|
|
20502
|
+
// src/commands/sessions/daemon/logSpawnedSession.ts
|
|
20503
|
+
function logSpawnedSession(session) {
|
|
20504
|
+
daemonLog(
|
|
20505
|
+
`session ${session.id} spawned: ${session.name} [${session.commandType}] ${session.cwd ?? ""}`
|
|
20506
|
+
);
|
|
20507
|
+
}
|
|
20508
|
+
|
|
20327
20509
|
// src/commands/sessions/daemon/setStatus.ts
|
|
20328
20510
|
function setStatus2(session, newStatus) {
|
|
20329
20511
|
const now = Date.now();
|
|
@@ -20687,6 +20869,7 @@ function retrySession(session, clients, onStatusChange) {
|
|
|
20687
20869
|
session.pty = respawn();
|
|
20688
20870
|
broadcast(clients, { type: "clear", sessionId: session.id });
|
|
20689
20871
|
wirePtyEvents(session, clients, onStatusChange);
|
|
20872
|
+
daemonLog(`session ${session.id} retried: ${session.name}`);
|
|
20690
20873
|
return true;
|
|
20691
20874
|
}
|
|
20692
20875
|
function respawnThunk(session) {
|
|
@@ -20716,6 +20899,7 @@ function reuseSessionForRun(session, itemId, clients, onStatusChange) {
|
|
|
20716
20899
|
|
|
20717
20900
|
// src/commands/sessions/daemon/shutdownSessions.ts
|
|
20718
20901
|
function shutdownSessions(sessions) {
|
|
20902
|
+
daemonLog(`shutting down: killing ${sessions.size} session(s)`);
|
|
20719
20903
|
for (const session of sessions.values()) {
|
|
20720
20904
|
if (session.status !== "done") session.pty?.kill();
|
|
20721
20905
|
}
|
|
@@ -21266,6 +21450,7 @@ function setAutoRun(sessions, id2, enabled) {
|
|
|
21266
21450
|
const s = sessions.get(id2);
|
|
21267
21451
|
if (!s) return false;
|
|
21268
21452
|
s.autoRun = enabled;
|
|
21453
|
+
daemonLog(`session ${id2} autorun ${enabled ? "on" : "off"}`);
|
|
21269
21454
|
return true;
|
|
21270
21455
|
}
|
|
21271
21456
|
function setAutoAdvance(sessions, id2, enabled) {
|
|
@@ -21277,24 +21462,9 @@ function setAutoAdvance(sessions, id2, enabled) {
|
|
|
21277
21462
|
if (enabled) clearPause(itemId);
|
|
21278
21463
|
else requestPause(itemId);
|
|
21279
21464
|
}
|
|
21465
|
+
daemonLog(`session ${id2} autoadvance ${enabled ? "on" : "off"}`);
|
|
21280
21466
|
return true;
|
|
21281
21467
|
}
|
|
21282
|
-
function dismissSession(sessions, id2) {
|
|
21283
|
-
const s = sessions.get(id2);
|
|
21284
|
-
if (!s) return false;
|
|
21285
|
-
if (s.status !== "done") s.pty?.kill();
|
|
21286
|
-
s.activityWatcher?.close();
|
|
21287
|
-
removeActivity(s.id);
|
|
21288
|
-
if (s.activity?.itemId != null) releaseLock(s.activity.itemId);
|
|
21289
|
-
sessions.delete(id2);
|
|
21290
|
-
return true;
|
|
21291
|
-
}
|
|
21292
|
-
function drainSessions(sessions, onDrained) {
|
|
21293
|
-
const ids = [...sessions.keys()];
|
|
21294
|
-
for (const id2 of ids) dismissSession(sessions, id2);
|
|
21295
|
-
onDrained();
|
|
21296
|
-
return ids.length;
|
|
21297
|
-
}
|
|
21298
21468
|
|
|
21299
21469
|
// src/commands/sessions/daemon/SessionManager.ts
|
|
21300
21470
|
var SessionManager = class {
|
|
@@ -21330,6 +21500,7 @@ var SessionManager = class {
|
|
|
21330
21500
|
add(session) {
|
|
21331
21501
|
this.wire(session);
|
|
21332
21502
|
watchActivity(session, this.notify);
|
|
21503
|
+
logSpawnedSession(session);
|
|
21333
21504
|
return session.id;
|
|
21334
21505
|
}
|
|
21335
21506
|
spawnWith = (create) => this.add(create(sessionLimits.nextId(this.sessions.size, this.idCounter)));
|
|
@@ -21398,12 +21569,12 @@ import * as net3 from "net";
|
|
|
21398
21569
|
import { createInterface as createInterface8 } from "readline";
|
|
21399
21570
|
|
|
21400
21571
|
// src/commands/sessions/shared/discoverSessions.ts
|
|
21401
|
-
import * as
|
|
21572
|
+
import * as fs31 from "fs";
|
|
21402
21573
|
import * as os from "os";
|
|
21403
21574
|
import * as path51 from "path";
|
|
21404
21575
|
|
|
21405
21576
|
// src/commands/sessions/shared/parseSessionFile.ts
|
|
21406
|
-
import * as
|
|
21577
|
+
import * as fs30 from "fs";
|
|
21407
21578
|
import * as path50 from "path";
|
|
21408
21579
|
|
|
21409
21580
|
// src/commands/sessions/shared/deriveHistoryFields.ts
|
|
@@ -21493,10 +21664,10 @@ function matchMarker(text6, tag) {
|
|
|
21493
21664
|
async function parseSessionFile(filePath, origin = "wsl") {
|
|
21494
21665
|
let handle;
|
|
21495
21666
|
try {
|
|
21496
|
-
handle = await
|
|
21667
|
+
handle = await fs30.promises.open(filePath, "r");
|
|
21497
21668
|
const meta = extractSessionMeta(await readHeadLines(handle));
|
|
21498
21669
|
if (!meta.sessionId) return null;
|
|
21499
|
-
const timestamp4 = meta.timestamp || (await
|
|
21670
|
+
const timestamp4 = meta.timestamp || (await fs30.promises.stat(filePath)).mtime.toISOString();
|
|
21500
21671
|
return {
|
|
21501
21672
|
sessionId: meta.sessionId,
|
|
21502
21673
|
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
@@ -21542,7 +21713,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
21542
21713
|
sessionRoots().map(async ({ dir, origin }) => {
|
|
21543
21714
|
let projectDirs;
|
|
21544
21715
|
try {
|
|
21545
|
-
projectDirs = await
|
|
21716
|
+
projectDirs = await fs31.promises.readdir(dir);
|
|
21546
21717
|
} catch {
|
|
21547
21718
|
return;
|
|
21548
21719
|
}
|
|
@@ -21551,7 +21722,7 @@ async function discoverSessionJsonlPaths() {
|
|
|
21551
21722
|
const dirPath = path51.join(dir, dirName);
|
|
21552
21723
|
let entries;
|
|
21553
21724
|
try {
|
|
21554
|
-
entries = await
|
|
21725
|
+
entries = await fs31.promises.readdir(dirPath);
|
|
21555
21726
|
} catch {
|
|
21556
21727
|
return;
|
|
21557
21728
|
}
|
|
@@ -21584,7 +21755,7 @@ async function discoverSessions() {
|
|
|
21584
21755
|
}
|
|
21585
21756
|
|
|
21586
21757
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
21587
|
-
import * as
|
|
21758
|
+
import * as fs32 from "fs";
|
|
21588
21759
|
|
|
21589
21760
|
// src/commands/sessions/shared/toolTarget.ts
|
|
21590
21761
|
function toolTarget(input) {
|
|
@@ -21651,7 +21822,7 @@ async function parseTranscript(sessionId) {
|
|
|
21651
21822
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
21652
21823
|
if (!filePath) return [];
|
|
21653
21824
|
try {
|
|
21654
|
-
const raw = await
|
|
21825
|
+
const raw = await fs32.promises.readFile(filePath, "utf8");
|
|
21655
21826
|
return parseTranscriptLines(raw.split("\n"));
|
|
21656
21827
|
} catch {
|
|
21657
21828
|
return [];
|
|
@@ -21932,17 +22103,17 @@ function registerDaemon(program2) {
|
|
|
21932
22103
|
}
|
|
21933
22104
|
|
|
21934
22105
|
// src/commands/sessions/summarise/index.ts
|
|
21935
|
-
import * as
|
|
21936
|
-
import
|
|
22106
|
+
import * as fs35 from "fs";
|
|
22107
|
+
import chalk178 from "chalk";
|
|
21937
22108
|
|
|
21938
22109
|
// src/commands/sessions/summarise/shared.ts
|
|
21939
|
-
import * as
|
|
22110
|
+
import * as fs33 from "fs";
|
|
21940
22111
|
function writeSummary(jsonlPath2, summary) {
|
|
21941
|
-
|
|
22112
|
+
fs33.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
21942
22113
|
`, "utf8");
|
|
21943
22114
|
}
|
|
21944
22115
|
function hasSummary(jsonlPath2) {
|
|
21945
|
-
return
|
|
22116
|
+
return fs33.existsSync(summaryPathFor(jsonlPath2));
|
|
21946
22117
|
}
|
|
21947
22118
|
function summaryPathFor(jsonlPath2) {
|
|
21948
22119
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -21952,7 +22123,7 @@ function summaryPathFor(jsonlPath2) {
|
|
|
21952
22123
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
21953
22124
|
|
|
21954
22125
|
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
21955
|
-
import * as
|
|
22126
|
+
import * as fs34 from "fs";
|
|
21956
22127
|
|
|
21957
22128
|
// src/commands/sessions/summarise/parseUserLine.ts
|
|
21958
22129
|
function parseUserLine(line) {
|
|
@@ -21983,13 +22154,13 @@ function parseUserLine(line) {
|
|
|
21983
22154
|
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
21984
22155
|
let content;
|
|
21985
22156
|
try {
|
|
21986
|
-
const fd =
|
|
22157
|
+
const fd = fs34.openSync(filePath, "r");
|
|
21987
22158
|
try {
|
|
21988
22159
|
const buf = Buffer.alloc(maxBytes);
|
|
21989
|
-
const bytesRead =
|
|
22160
|
+
const bytesRead = fs34.readSync(fd, buf, 0, buf.length, 0);
|
|
21990
22161
|
content = buf.toString("utf8", 0, bytesRead);
|
|
21991
22162
|
} finally {
|
|
21992
|
-
|
|
22163
|
+
fs34.closeSync(fd);
|
|
21993
22164
|
}
|
|
21994
22165
|
} catch {
|
|
21995
22166
|
return;
|
|
@@ -22087,29 +22258,29 @@ ${firstMessage}`);
|
|
|
22087
22258
|
async function summarise3(options2) {
|
|
22088
22259
|
const files = await discoverSessionFiles();
|
|
22089
22260
|
if (files.length === 0) {
|
|
22090
|
-
console.log(
|
|
22261
|
+
console.log(chalk178.yellow("No sessions found."));
|
|
22091
22262
|
return;
|
|
22092
22263
|
}
|
|
22093
22264
|
const toProcess = selectCandidates(files, options2);
|
|
22094
22265
|
if (toProcess.length === 0) {
|
|
22095
|
-
console.log(
|
|
22266
|
+
console.log(chalk178.green("All sessions already summarised."));
|
|
22096
22267
|
return;
|
|
22097
22268
|
}
|
|
22098
22269
|
console.log(
|
|
22099
|
-
|
|
22270
|
+
chalk178.cyan(
|
|
22100
22271
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
22101
22272
|
)
|
|
22102
22273
|
);
|
|
22103
22274
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
22104
22275
|
console.log(
|
|
22105
|
-
|
|
22276
|
+
chalk178.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk178.yellow(`, ${failed2} skipped`) : "")
|
|
22106
22277
|
);
|
|
22107
22278
|
}
|
|
22108
22279
|
function selectCandidates(files, options2) {
|
|
22109
22280
|
const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
|
|
22110
22281
|
candidates.sort((a, b) => {
|
|
22111
22282
|
try {
|
|
22112
|
-
return
|
|
22283
|
+
return fs35.statSync(b).mtimeMs - fs35.statSync(a).mtimeMs;
|
|
22113
22284
|
} catch {
|
|
22114
22285
|
return 0;
|
|
22115
22286
|
}
|
|
@@ -22122,16 +22293,16 @@ function processSessions(files) {
|
|
|
22122
22293
|
let failed2 = 0;
|
|
22123
22294
|
for (let i = 0; i < files.length; i++) {
|
|
22124
22295
|
const file = files[i];
|
|
22125
|
-
process.stdout.write(
|
|
22296
|
+
process.stdout.write(chalk178.dim(` [${i + 1}/${files.length}] `));
|
|
22126
22297
|
const summary = summariseSession(file);
|
|
22127
22298
|
if (summary) {
|
|
22128
22299
|
writeSummary(file, summary);
|
|
22129
22300
|
succeeded++;
|
|
22130
|
-
process.stdout.write(`${
|
|
22301
|
+
process.stdout.write(`${chalk178.green("\u2713")} ${summary}
|
|
22131
22302
|
`);
|
|
22132
22303
|
} else {
|
|
22133
22304
|
failed2++;
|
|
22134
|
-
process.stdout.write(` ${
|
|
22305
|
+
process.stdout.write(` ${chalk178.yellow("skip")}
|
|
22135
22306
|
`);
|
|
22136
22307
|
}
|
|
22137
22308
|
}
|
|
@@ -22149,10 +22320,10 @@ function registerSessions(program2) {
|
|
|
22149
22320
|
}
|
|
22150
22321
|
|
|
22151
22322
|
// src/commands/statusLine.ts
|
|
22152
|
-
import
|
|
22323
|
+
import chalk180 from "chalk";
|
|
22153
22324
|
|
|
22154
22325
|
// src/commands/buildLimitsSegment.ts
|
|
22155
|
-
import
|
|
22326
|
+
import chalk179 from "chalk";
|
|
22156
22327
|
|
|
22157
22328
|
// src/shared/rateLimitLevel.ts
|
|
22158
22329
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -22183,9 +22354,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
22183
22354
|
|
|
22184
22355
|
// src/commands/buildLimitsSegment.ts
|
|
22185
22356
|
var LEVEL_COLOR = {
|
|
22186
|
-
ok:
|
|
22187
|
-
warn:
|
|
22188
|
-
over:
|
|
22357
|
+
ok: chalk179.green,
|
|
22358
|
+
warn: chalk179.yellow,
|
|
22359
|
+
over: chalk179.red
|
|
22189
22360
|
};
|
|
22190
22361
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
22191
22362
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -22225,14 +22396,14 @@ async function relayRateLimits(rateLimits) {
|
|
|
22225
22396
|
}
|
|
22226
22397
|
|
|
22227
22398
|
// src/commands/statusLine.ts
|
|
22228
|
-
|
|
22399
|
+
chalk180.level = 3;
|
|
22229
22400
|
function formatNumber(num) {
|
|
22230
22401
|
return num.toLocaleString("en-US");
|
|
22231
22402
|
}
|
|
22232
22403
|
function colorizePercent(pct) {
|
|
22233
22404
|
const label2 = `${Math.round(pct)}%`;
|
|
22234
|
-
if (pct > 80) return
|
|
22235
|
-
if (pct > 40) return
|
|
22405
|
+
if (pct > 80) return chalk180.red(label2);
|
|
22406
|
+
if (pct > 40) return chalk180.yellow(label2);
|
|
22236
22407
|
return label2;
|
|
22237
22408
|
}
|
|
22238
22409
|
async function statusLine() {
|
|
@@ -22248,29 +22419,29 @@ async function statusLine() {
|
|
|
22248
22419
|
}
|
|
22249
22420
|
|
|
22250
22421
|
// src/commands/sync.ts
|
|
22251
|
-
import * as
|
|
22422
|
+
import * as fs38 from "fs";
|
|
22252
22423
|
import * as os2 from "os";
|
|
22253
22424
|
import * as path55 from "path";
|
|
22254
22425
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
22255
22426
|
|
|
22256
22427
|
// src/commands/sync/syncClaudeMd.ts
|
|
22257
|
-
import * as
|
|
22428
|
+
import * as fs36 from "fs";
|
|
22258
22429
|
import * as path53 from "path";
|
|
22259
|
-
import
|
|
22430
|
+
import chalk181 from "chalk";
|
|
22260
22431
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
22261
22432
|
const source = path53.join(claudeDir, "CLAUDE.md");
|
|
22262
22433
|
const target = path53.join(targetBase, "CLAUDE.md");
|
|
22263
|
-
const sourceContent =
|
|
22264
|
-
if (
|
|
22265
|
-
const targetContent =
|
|
22434
|
+
const sourceContent = fs36.readFileSync(source, "utf8");
|
|
22435
|
+
if (fs36.existsSync(target)) {
|
|
22436
|
+
const targetContent = fs36.readFileSync(target, "utf8");
|
|
22266
22437
|
if (sourceContent !== targetContent) {
|
|
22267
22438
|
console.log(
|
|
22268
|
-
|
|
22439
|
+
chalk181.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
22269
22440
|
);
|
|
22270
22441
|
console.log();
|
|
22271
22442
|
printDiff(targetContent, sourceContent);
|
|
22272
22443
|
const confirm = options2?.yes || await promptConfirm(
|
|
22273
|
-
|
|
22444
|
+
chalk181.red("Overwrite existing CLAUDE.md?"),
|
|
22274
22445
|
false
|
|
22275
22446
|
);
|
|
22276
22447
|
if (!confirm) {
|
|
@@ -22279,21 +22450,21 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22279
22450
|
}
|
|
22280
22451
|
}
|
|
22281
22452
|
}
|
|
22282
|
-
|
|
22453
|
+
fs36.copyFileSync(source, target);
|
|
22283
22454
|
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
22284
22455
|
}
|
|
22285
22456
|
|
|
22286
22457
|
// src/commands/sync/syncSettings.ts
|
|
22287
|
-
import * as
|
|
22458
|
+
import * as fs37 from "fs";
|
|
22288
22459
|
import * as path54 from "path";
|
|
22289
|
-
import
|
|
22460
|
+
import chalk182 from "chalk";
|
|
22290
22461
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
22291
22462
|
const source = path54.join(claudeDir, "settings.json");
|
|
22292
22463
|
const target = path54.join(targetBase, "settings.json");
|
|
22293
|
-
const sourceContent =
|
|
22464
|
+
const sourceContent = fs37.readFileSync(source, "utf8");
|
|
22294
22465
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
22295
|
-
if (
|
|
22296
|
-
const targetContent =
|
|
22466
|
+
if (fs37.existsSync(target)) {
|
|
22467
|
+
const targetContent = fs37.readFileSync(target, "utf8");
|
|
22297
22468
|
const normalizedTarget = JSON.stringify(
|
|
22298
22469
|
JSON.parse(targetContent),
|
|
22299
22470
|
null,
|
|
@@ -22302,14 +22473,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
22302
22473
|
if (mergedContent !== normalizedTarget) {
|
|
22303
22474
|
if (!options2?.yes) {
|
|
22304
22475
|
console.log(
|
|
22305
|
-
|
|
22476
|
+
chalk182.yellow(
|
|
22306
22477
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
22307
22478
|
)
|
|
22308
22479
|
);
|
|
22309
22480
|
console.log();
|
|
22310
22481
|
printDiff(targetContent, mergedContent);
|
|
22311
22482
|
const confirm = await promptConfirm(
|
|
22312
|
-
|
|
22483
|
+
chalk182.red("Overwrite existing settings.json?"),
|
|
22313
22484
|
false
|
|
22314
22485
|
);
|
|
22315
22486
|
if (!confirm) {
|
|
@@ -22319,7 +22490,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
22319
22490
|
}
|
|
22320
22491
|
}
|
|
22321
22492
|
}
|
|
22322
|
-
|
|
22493
|
+
fs37.writeFileSync(target, mergedContent);
|
|
22323
22494
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
22324
22495
|
}
|
|
22325
22496
|
|
|
@@ -22338,10 +22509,10 @@ async function sync(options2) {
|
|
|
22338
22509
|
function syncCommands(claudeDir, targetBase) {
|
|
22339
22510
|
const sourceDir = path55.join(claudeDir, "commands");
|
|
22340
22511
|
const targetDir = path55.join(targetBase, "commands");
|
|
22341
|
-
|
|
22342
|
-
const files =
|
|
22512
|
+
fs38.mkdirSync(targetDir, { recursive: true });
|
|
22513
|
+
const files = fs38.readdirSync(sourceDir);
|
|
22343
22514
|
for (const file of files) {
|
|
22344
|
-
|
|
22515
|
+
fs38.copyFileSync(path55.join(sourceDir, file), path55.join(targetDir, file));
|
|
22345
22516
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
22346
22517
|
}
|
|
22347
22518
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -22427,6 +22598,7 @@ program.command("screenshot").description("Capture a screenshot of a running app
|
|
|
22427
22598
|
registerActivity(program);
|
|
22428
22599
|
registerBackup(program);
|
|
22429
22600
|
registerCliHook(program);
|
|
22601
|
+
registerEditHook(program);
|
|
22430
22602
|
registerGithub(program);
|
|
22431
22603
|
registerHandover(program);
|
|
22432
22604
|
registerJira(program);
|