@staff0rd/assist 0.149.1 → 0.149.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +479 -437
- 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.149.
|
|
9
|
+
version: "0.149.3",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -91,10 +91,10 @@ import { stringify as stringifyYaml } from "yaml";
|
|
|
91
91
|
// src/shared/loadRawYaml.ts
|
|
92
92
|
import { existsSync, readFileSync } from "fs";
|
|
93
93
|
import { parse as parseYaml } from "yaml";
|
|
94
|
-
function loadRawYaml(
|
|
95
|
-
if (!existsSync(
|
|
94
|
+
function loadRawYaml(path50) {
|
|
95
|
+
if (!existsSync(path50)) return {};
|
|
96
96
|
try {
|
|
97
|
-
const content = readFileSync(
|
|
97
|
+
const content = readFileSync(path50, "utf-8");
|
|
98
98
|
return parseYaml(content) || {};
|
|
99
99
|
} catch {
|
|
100
100
|
return {};
|
|
@@ -371,9 +371,9 @@ function isTraversable(value) {
|
|
|
371
371
|
function stepInto(current, key) {
|
|
372
372
|
return isTraversable(current) ? current[key] : void 0;
|
|
373
373
|
}
|
|
374
|
-
function getNestedValue(obj,
|
|
374
|
+
function getNestedValue(obj, path50) {
|
|
375
375
|
let current = obj;
|
|
376
|
-
for (const key of
|
|
376
|
+
for (const key of path50.split(".")) current = stepInto(current, key);
|
|
377
377
|
return current;
|
|
378
378
|
}
|
|
379
379
|
|
|
@@ -414,8 +414,8 @@ function stepIntoNested(container, key, nextKey) {
|
|
|
414
414
|
}
|
|
415
415
|
return ensureObject(container, resolved);
|
|
416
416
|
}
|
|
417
|
-
function setNestedValue(obj,
|
|
418
|
-
const keys =
|
|
417
|
+
function setNestedValue(obj, path50, value) {
|
|
418
|
+
const keys = path50.split(".");
|
|
419
419
|
const result = { ...obj };
|
|
420
420
|
let current = result;
|
|
421
421
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -2411,7 +2411,7 @@ async function done(id) {
|
|
|
2411
2411
|
}
|
|
2412
2412
|
|
|
2413
2413
|
// src/commands/backlog/next.ts
|
|
2414
|
-
import
|
|
2414
|
+
import chalk34 from "chalk";
|
|
2415
2415
|
import enquirer5 from "enquirer";
|
|
2416
2416
|
|
|
2417
2417
|
// src/commands/backlog/list/shared.ts
|
|
@@ -2454,7 +2454,7 @@ function printVerboseDetails(item) {
|
|
|
2454
2454
|
}
|
|
2455
2455
|
|
|
2456
2456
|
// src/commands/backlog/run.ts
|
|
2457
|
-
import
|
|
2457
|
+
import chalk33 from "chalk";
|
|
2458
2458
|
|
|
2459
2459
|
// src/commands/backlog/buildAuthoredPhasePrompt.ts
|
|
2460
2460
|
function buildAuthoredPhasePrompt(item, phaseIndex, phase) {
|
|
@@ -2669,6 +2669,9 @@ async function executePhase(item, phaseIndex, phases, spawnOptions) {
|
|
|
2669
2669
|
return delta < 0 ? -1 : phaseIndex + delta;
|
|
2670
2670
|
}
|
|
2671
2671
|
|
|
2672
|
+
// src/commands/backlog/prepareRun.ts
|
|
2673
|
+
import chalk32 from "chalk";
|
|
2674
|
+
|
|
2672
2675
|
// src/commands/backlog/resolvePlan.ts
|
|
2673
2676
|
function resolvePlan(item) {
|
|
2674
2677
|
if (item.plan && item.plan.length > 0) {
|
|
@@ -2682,49 +2685,68 @@ function resolvePlan(item) {
|
|
|
2682
2685
|
];
|
|
2683
2686
|
}
|
|
2684
2687
|
|
|
2685
|
-
// src/commands/backlog/
|
|
2686
|
-
|
|
2688
|
+
// src/commands/backlog/prepareRun.ts
|
|
2689
|
+
function prepareRun(id) {
|
|
2687
2690
|
const result = loadAndFindItem(id);
|
|
2688
|
-
if (!result) return;
|
|
2691
|
+
if (!result) return void 0;
|
|
2689
2692
|
const { item } = result;
|
|
2690
2693
|
const plan2 = resolvePlan(item);
|
|
2691
2694
|
const startPhase = item.currentPhase ?? 0;
|
|
2695
|
+
if (item.status === "done") {
|
|
2696
|
+
console.log(chalk32.green(`Already done: #${id}: ${item.name}`));
|
|
2697
|
+
return void 0;
|
|
2698
|
+
}
|
|
2692
2699
|
if (startPhase > plan2.length) {
|
|
2693
|
-
|
|
2700
|
+
setStatus(id, "done");
|
|
2694
2701
|
console.log(
|
|
2695
2702
|
chalk32.green(`All phases already complete for #${id}: ${item.name}`)
|
|
2696
2703
|
);
|
|
2697
|
-
return;
|
|
2704
|
+
return void 0;
|
|
2698
2705
|
}
|
|
2706
|
+
return { item, plan: plan2, startPhase };
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
// src/commands/backlog/run.ts
|
|
2710
|
+
async function run2(id, spawnOptions) {
|
|
2711
|
+
const prepared = prepareRun(id);
|
|
2712
|
+
if (!prepared) return;
|
|
2713
|
+
const { item, plan: plan2, startPhase } = prepared;
|
|
2699
2714
|
setStatus(id, "in-progress");
|
|
2700
|
-
|
|
2715
|
+
logProgress(id, item.name, startPhase, plan2.length);
|
|
2716
|
+
if (!await runPhases(item, startPhase, plan2, spawnOptions)) return;
|
|
2717
|
+
if (!await runReview(item, plan2, spawnOptions)) return;
|
|
2718
|
+
setStatus(id, "done");
|
|
2719
|
+
console.log(chalk33.green(`
|
|
2720
|
+
All phases complete for #${id}: ${item.name}`));
|
|
2721
|
+
}
|
|
2722
|
+
function logProgress(id, name, startPhase, total) {
|
|
2723
|
+
console.log(chalk33.bold(`Running plan for #${id}: ${name}`));
|
|
2701
2724
|
if (startPhase > 0) {
|
|
2702
|
-
console.log(
|
|
2703
|
-
|
|
2704
|
-
`)
|
|
2705
|
-
);
|
|
2725
|
+
console.log(chalk33.dim(`Resuming from phase ${startPhase + 1}/${total}
|
|
2726
|
+
`));
|
|
2706
2727
|
} else {
|
|
2707
|
-
console.log(
|
|
2728
|
+
console.log(chalk33.dim(`${total} phase(s)
|
|
2708
2729
|
`));
|
|
2709
2730
|
}
|
|
2731
|
+
}
|
|
2732
|
+
async function runPhases(item, startPhase, plan2, spawnOptions) {
|
|
2710
2733
|
let phaseIndex = startPhase;
|
|
2711
2734
|
while (phaseIndex < plan2.length) {
|
|
2712
2735
|
phaseIndex = await executePhase(item, phaseIndex, plan2, spawnOptions);
|
|
2713
|
-
if (phaseIndex < 0) return;
|
|
2736
|
+
if (phaseIndex < 0) return false;
|
|
2714
2737
|
}
|
|
2738
|
+
return true;
|
|
2739
|
+
}
|
|
2740
|
+
async function runReview(item, plan2, spawnOptions) {
|
|
2715
2741
|
const reviewPhase = buildReviewPhase();
|
|
2716
2742
|
const allPhases = [...plan2, reviewPhase];
|
|
2717
|
-
const reviewIndex = plan2.length;
|
|
2718
2743
|
const reviewResult = await executePhase(
|
|
2719
2744
|
item,
|
|
2720
|
-
|
|
2745
|
+
plan2.length,
|
|
2721
2746
|
allPhases,
|
|
2722
2747
|
spawnOptions
|
|
2723
2748
|
);
|
|
2724
|
-
|
|
2725
|
-
if (item.status !== "done") setStatus(id, "done");
|
|
2726
|
-
console.log(chalk32.green(`
|
|
2727
|
-
All phases complete for #${id}: ${item.name}`));
|
|
2749
|
+
return reviewResult >= 0;
|
|
2728
2750
|
}
|
|
2729
2751
|
|
|
2730
2752
|
// src/commands/backlog/next.ts
|
|
@@ -2733,7 +2755,7 @@ async function next(options2) {
|
|
|
2733
2755
|
const inProgress = items.find((i) => i.status === "in-progress" && i.plan);
|
|
2734
2756
|
if (inProgress) {
|
|
2735
2757
|
console.log(
|
|
2736
|
-
|
|
2758
|
+
chalk34.bold(
|
|
2737
2759
|
`Resuming in-progress item #${inProgress.id}: ${inProgress.name}`
|
|
2738
2760
|
)
|
|
2739
2761
|
);
|
|
@@ -2742,13 +2764,13 @@ async function next(options2) {
|
|
|
2742
2764
|
}
|
|
2743
2765
|
const todo = items.filter((i) => i.status === "todo");
|
|
2744
2766
|
if (todo.length === 0) {
|
|
2745
|
-
console.log(
|
|
2767
|
+
console.log(chalk34.dim("No incomplete backlog items. Opening /draft..."));
|
|
2746
2768
|
await spawnClaude("/draft", options2);
|
|
2747
2769
|
return;
|
|
2748
2770
|
}
|
|
2749
2771
|
if (todo.length === 1) {
|
|
2750
2772
|
const only = todo[0];
|
|
2751
|
-
console.log(
|
|
2773
|
+
console.log(chalk34.bold(`Starting #${only.id}: ${only.name}`));
|
|
2752
2774
|
await run2(String(only.id), options2);
|
|
2753
2775
|
return;
|
|
2754
2776
|
}
|
|
@@ -2767,23 +2789,23 @@ async function next(options2) {
|
|
|
2767
2789
|
}
|
|
2768
2790
|
|
|
2769
2791
|
// src/commands/backlog/plan.ts
|
|
2770
|
-
import
|
|
2792
|
+
import chalk35 from "chalk";
|
|
2771
2793
|
function plan(id) {
|
|
2772
2794
|
const result = loadAndFindItem(id);
|
|
2773
2795
|
if (!result) return;
|
|
2774
2796
|
const { item } = result;
|
|
2775
2797
|
if (!item.plan || item.plan.length === 0) {
|
|
2776
|
-
console.log(
|
|
2798
|
+
console.log(chalk35.dim("No plan defined for this item."));
|
|
2777
2799
|
return;
|
|
2778
2800
|
}
|
|
2779
|
-
console.log(
|
|
2801
|
+
console.log(chalk35.bold(item.name));
|
|
2780
2802
|
console.log();
|
|
2781
2803
|
for (const [i, phase] of item.plan.entries()) {
|
|
2782
|
-
console.log(`${
|
|
2804
|
+
console.log(`${chalk35.bold(`Phase ${i + 1}:`)} ${phase.name}`);
|
|
2783
2805
|
for (const task of phase.tasks) {
|
|
2784
2806
|
console.log(` - ${task.task}`);
|
|
2785
2807
|
if (task.verify) {
|
|
2786
|
-
console.log(` ${
|
|
2808
|
+
console.log(` ${chalk35.dim(`verify: ${task.verify}`)}`);
|
|
2787
2809
|
}
|
|
2788
2810
|
}
|
|
2789
2811
|
console.log();
|
|
@@ -2791,11 +2813,11 @@ function plan(id) {
|
|
|
2791
2813
|
}
|
|
2792
2814
|
|
|
2793
2815
|
// src/commands/backlog/start/index.ts
|
|
2794
|
-
import
|
|
2816
|
+
import chalk36 from "chalk";
|
|
2795
2817
|
async function start(id) {
|
|
2796
2818
|
const name = setStatus(id, "in-progress");
|
|
2797
2819
|
if (name) {
|
|
2798
|
-
console.log(
|
|
2820
|
+
console.log(chalk36.green(`Started item #${id}: ${name}`));
|
|
2799
2821
|
}
|
|
2800
2822
|
}
|
|
2801
2823
|
|
|
@@ -2807,7 +2829,7 @@ import {
|
|
|
2807
2829
|
} from "http";
|
|
2808
2830
|
import { dirname as dirname13, join as join10 } from "path";
|
|
2809
2831
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2810
|
-
import
|
|
2832
|
+
import chalk37 from "chalk";
|
|
2811
2833
|
function respondJson(res, status2, data) {
|
|
2812
2834
|
res.writeHead(status2, { "Content-Type": "application/json" });
|
|
2813
2835
|
res.end(JSON.stringify(data));
|
|
@@ -2851,8 +2873,8 @@ function startWebServer(label2, port, handler) {
|
|
|
2851
2873
|
handler(req, res, port);
|
|
2852
2874
|
});
|
|
2853
2875
|
server.listen(port, () => {
|
|
2854
|
-
console.log(
|
|
2855
|
-
console.log(
|
|
2876
|
+
console.log(chalk37.green(`${label2}: ${url}`));
|
|
2877
|
+
console.log(chalk37.dim("Press Ctrl+C to stop"));
|
|
2856
2878
|
exec(`open ${url}`);
|
|
2857
2879
|
});
|
|
2858
2880
|
}
|
|
@@ -3001,7 +3023,7 @@ async function web(options2) {
|
|
|
3001
3023
|
|
|
3002
3024
|
// src/commands/backlog/add/index.ts
|
|
3003
3025
|
import { existsSync as existsSync15 } from "fs";
|
|
3004
|
-
import
|
|
3026
|
+
import chalk38 from "chalk";
|
|
3005
3027
|
|
|
3006
3028
|
// src/commands/backlog/add/shared.ts
|
|
3007
3029
|
import { spawnSync } from "child_process";
|
|
@@ -3077,7 +3099,7 @@ async function promptAcceptanceCriteria() {
|
|
|
3077
3099
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3078
3100
|
async function addFromJson() {
|
|
3079
3101
|
if (process.stdin.isTTY) {
|
|
3080
|
-
console.log(
|
|
3102
|
+
console.log(chalk38.red("--json requires piped input on stdin."));
|
|
3081
3103
|
return;
|
|
3082
3104
|
}
|
|
3083
3105
|
const input = await readStdin2();
|
|
@@ -3090,7 +3112,7 @@ async function addFromJson() {
|
|
|
3090
3112
|
const id = getNextId(items);
|
|
3091
3113
|
items.push({ ...data, id, status: "todo" });
|
|
3092
3114
|
saveBacklog(items);
|
|
3093
|
-
console.log(
|
|
3115
|
+
console.log(chalk38.green(`Added item #${id}: ${data.name}`));
|
|
3094
3116
|
}
|
|
3095
3117
|
async function addInteractive() {
|
|
3096
3118
|
const type = await promptType();
|
|
@@ -3108,12 +3130,12 @@ async function addInteractive() {
|
|
|
3108
3130
|
status: "todo"
|
|
3109
3131
|
});
|
|
3110
3132
|
saveBacklog(items);
|
|
3111
|
-
console.log(
|
|
3133
|
+
console.log(chalk38.green(`Added item #${id}: ${name}`));
|
|
3112
3134
|
}
|
|
3113
3135
|
async function add(options2) {
|
|
3114
3136
|
if (!existsSync15(getBacklogPath())) {
|
|
3115
3137
|
console.log(
|
|
3116
|
-
|
|
3138
|
+
chalk38.yellow(
|
|
3117
3139
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3118
3140
|
)
|
|
3119
3141
|
);
|
|
@@ -3128,20 +3150,20 @@ async function add(options2) {
|
|
|
3128
3150
|
|
|
3129
3151
|
// src/commands/backlog/init/index.ts
|
|
3130
3152
|
import { existsSync as existsSync16 } from "fs";
|
|
3131
|
-
import
|
|
3153
|
+
import chalk39 from "chalk";
|
|
3132
3154
|
async function init6() {
|
|
3133
3155
|
const backlogPath = getBacklogPath();
|
|
3134
3156
|
if (existsSync16(backlogPath)) {
|
|
3135
|
-
console.log(
|
|
3157
|
+
console.log(chalk39.yellow("assist.backlog.yml already exists."));
|
|
3136
3158
|
return;
|
|
3137
3159
|
}
|
|
3138
3160
|
saveBacklog([]);
|
|
3139
|
-
console.log(
|
|
3161
|
+
console.log(chalk39.green("Created assist.backlog.yml"));
|
|
3140
3162
|
}
|
|
3141
3163
|
|
|
3142
3164
|
// src/commands/backlog/list/index.ts
|
|
3143
3165
|
import { existsSync as existsSync17 } from "fs";
|
|
3144
|
-
import
|
|
3166
|
+
import chalk40 from "chalk";
|
|
3145
3167
|
function filterItems(items, options2) {
|
|
3146
3168
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3147
3169
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
@@ -3150,7 +3172,7 @@ function filterItems(items, options2) {
|
|
|
3150
3172
|
async function list2(options2) {
|
|
3151
3173
|
if (!existsSync17(getBacklogPath())) {
|
|
3152
3174
|
console.log(
|
|
3153
|
-
|
|
3175
|
+
chalk40.yellow(
|
|
3154
3176
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3155
3177
|
)
|
|
3156
3178
|
);
|
|
@@ -3158,12 +3180,12 @@ async function list2(options2) {
|
|
|
3158
3180
|
}
|
|
3159
3181
|
const items = filterItems(loadBacklog(), options2);
|
|
3160
3182
|
if (items.length === 0) {
|
|
3161
|
-
console.log(
|
|
3183
|
+
console.log(chalk40.dim("Backlog is empty."));
|
|
3162
3184
|
return;
|
|
3163
3185
|
}
|
|
3164
3186
|
for (const item of items) {
|
|
3165
3187
|
console.log(
|
|
3166
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3188
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk40.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
|
|
3167
3189
|
);
|
|
3168
3190
|
if (options2.verbose) {
|
|
3169
3191
|
printVerboseDetails(item);
|
|
@@ -3298,12 +3320,12 @@ function getCliReadsPath() {
|
|
|
3298
3320
|
var cachedLines;
|
|
3299
3321
|
function getCliReadsLines() {
|
|
3300
3322
|
if (cachedLines) return cachedLines;
|
|
3301
|
-
const
|
|
3302
|
-
if (!existsSync18(
|
|
3323
|
+
const path50 = getCliReadsPath();
|
|
3324
|
+
if (!existsSync18(path50)) {
|
|
3303
3325
|
cachedLines = [];
|
|
3304
3326
|
return cachedLines;
|
|
3305
3327
|
}
|
|
3306
|
-
cachedLines = readFileSync13(
|
|
3328
|
+
cachedLines = readFileSync13(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
3307
3329
|
return cachedLines;
|
|
3308
3330
|
}
|
|
3309
3331
|
function loadCliReads() {
|
|
@@ -3552,11 +3574,11 @@ function assertCliExists(cli) {
|
|
|
3552
3574
|
}
|
|
3553
3575
|
|
|
3554
3576
|
// src/commands/permitCliReads/colorize.ts
|
|
3555
|
-
import
|
|
3577
|
+
import chalk41 from "chalk";
|
|
3556
3578
|
function colorize(plainOutput) {
|
|
3557
3579
|
return plainOutput.split("\n").map((line) => {
|
|
3558
|
-
if (line.startsWith(" R ")) return
|
|
3559
|
-
if (line.startsWith(" W ")) return
|
|
3580
|
+
if (line.startsWith(" R ")) return chalk41.green(line);
|
|
3581
|
+
if (line.startsWith(" W ")) return chalk41.red(line);
|
|
3560
3582
|
return line;
|
|
3561
3583
|
}).join("\n");
|
|
3562
3584
|
}
|
|
@@ -3658,14 +3680,14 @@ function showProgress(p, label2) {
|
|
|
3658
3680
|
const pct = Math.round(p.done / p.total * 100);
|
|
3659
3681
|
process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
|
|
3660
3682
|
}
|
|
3661
|
-
async function resolveCommand(cli,
|
|
3662
|
-
showProgress(p,
|
|
3663
|
-
const subHelp = await runHelp([cli, ...
|
|
3683
|
+
async function resolveCommand(cli, path50, description, depth, p) {
|
|
3684
|
+
showProgress(p, path50.join(" "));
|
|
3685
|
+
const subHelp = await runHelp([cli, ...path50]);
|
|
3664
3686
|
if (!subHelp || !hasSubcommands(subHelp)) {
|
|
3665
|
-
return [{ path:
|
|
3687
|
+
return [{ path: path50, description }];
|
|
3666
3688
|
}
|
|
3667
|
-
const children = await discoverAt(cli,
|
|
3668
|
-
return children.length > 0 ? children : [{ path:
|
|
3689
|
+
const children = await discoverAt(cli, path50, depth + 1, p);
|
|
3690
|
+
return children.length > 0 ? children : [{ path: path50, description }];
|
|
3669
3691
|
}
|
|
3670
3692
|
async function discoverAt(cli, parentPath, depth, p) {
|
|
3671
3693
|
if (depth > SAFETY_DEPTH) return [];
|
|
@@ -3813,9 +3835,9 @@ function logPath(cli) {
|
|
|
3813
3835
|
return join13(homedir4(), ".assist", `cli-discover-${safeName}.log`);
|
|
3814
3836
|
}
|
|
3815
3837
|
function readCache(cli) {
|
|
3816
|
-
const
|
|
3817
|
-
if (!existsSync20(
|
|
3818
|
-
return readFileSync15(
|
|
3838
|
+
const path50 = logPath(cli);
|
|
3839
|
+
if (!existsSync20(path50)) return void 0;
|
|
3840
|
+
return readFileSync15(path50, "utf-8");
|
|
3819
3841
|
}
|
|
3820
3842
|
function writeCache(cli, output) {
|
|
3821
3843
|
const dir = join13(homedir4(), ".assist");
|
|
@@ -3870,15 +3892,15 @@ function registerCliHook(program2) {
|
|
|
3870
3892
|
}
|
|
3871
3893
|
|
|
3872
3894
|
// src/commands/complexity/analyze.ts
|
|
3873
|
-
import
|
|
3895
|
+
import chalk47 from "chalk";
|
|
3874
3896
|
|
|
3875
3897
|
// src/commands/complexity/cyclomatic.ts
|
|
3876
|
-
import
|
|
3898
|
+
import chalk43 from "chalk";
|
|
3877
3899
|
|
|
3878
3900
|
// src/commands/complexity/shared/index.ts
|
|
3879
3901
|
import fs12 from "fs";
|
|
3880
3902
|
import path20 from "path";
|
|
3881
|
-
import
|
|
3903
|
+
import chalk42 from "chalk";
|
|
3882
3904
|
import ts5 from "typescript";
|
|
3883
3905
|
|
|
3884
3906
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4124,7 +4146,7 @@ function createSourceFromFile(filePath) {
|
|
|
4124
4146
|
function withSourceFiles(pattern2, callback) {
|
|
4125
4147
|
const files = findSourceFiles2(pattern2);
|
|
4126
4148
|
if (files.length === 0) {
|
|
4127
|
-
console.log(
|
|
4149
|
+
console.log(chalk42.yellow("No files found matching pattern"));
|
|
4128
4150
|
return void 0;
|
|
4129
4151
|
}
|
|
4130
4152
|
return callback(files);
|
|
@@ -4157,11 +4179,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4157
4179
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4158
4180
|
for (const { file, name, complexity } of results) {
|
|
4159
4181
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4160
|
-
const color = exceedsThreshold ?
|
|
4161
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4182
|
+
const color = exceedsThreshold ? chalk43.red : chalk43.white;
|
|
4183
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk43.cyan(complexity)}`);
|
|
4162
4184
|
}
|
|
4163
4185
|
console.log(
|
|
4164
|
-
|
|
4186
|
+
chalk43.dim(
|
|
4165
4187
|
`
|
|
4166
4188
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4167
4189
|
)
|
|
@@ -4173,7 +4195,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4173
4195
|
}
|
|
4174
4196
|
|
|
4175
4197
|
// src/commands/complexity/halstead.ts
|
|
4176
|
-
import
|
|
4198
|
+
import chalk44 from "chalk";
|
|
4177
4199
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4178
4200
|
withSourceFiles(pattern2, (files) => {
|
|
4179
4201
|
const results = [];
|
|
@@ -4188,13 +4210,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4188
4210
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4189
4211
|
for (const { file, name, metrics } of results) {
|
|
4190
4212
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4191
|
-
const color = exceedsThreshold ?
|
|
4213
|
+
const color = exceedsThreshold ? chalk44.red : chalk44.white;
|
|
4192
4214
|
console.log(
|
|
4193
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4215
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk44.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk44.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk44.magenta(metrics.effort.toFixed(1))}`
|
|
4194
4216
|
);
|
|
4195
4217
|
}
|
|
4196
4218
|
console.log(
|
|
4197
|
-
|
|
4219
|
+
chalk44.dim(
|
|
4198
4220
|
`
|
|
4199
4221
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4200
4222
|
)
|
|
@@ -4209,28 +4231,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4209
4231
|
import fs13 from "fs";
|
|
4210
4232
|
|
|
4211
4233
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4212
|
-
import
|
|
4234
|
+
import chalk45 from "chalk";
|
|
4213
4235
|
function displayMaintainabilityResults(results, threshold) {
|
|
4214
4236
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4215
4237
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4216
|
-
console.log(
|
|
4238
|
+
console.log(chalk45.green("All files pass maintainability threshold"));
|
|
4217
4239
|
} else {
|
|
4218
4240
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4219
|
-
const color = threshold !== void 0 ?
|
|
4241
|
+
const color = threshold !== void 0 ? chalk45.red : chalk45.white;
|
|
4220
4242
|
console.log(
|
|
4221
|
-
`${color(file)} \u2192 avg: ${
|
|
4243
|
+
`${color(file)} \u2192 avg: ${chalk45.cyan(avgMaintainability.toFixed(1))}, min: ${chalk45.yellow(minMaintainability.toFixed(1))}`
|
|
4222
4244
|
);
|
|
4223
4245
|
}
|
|
4224
4246
|
}
|
|
4225
|
-
console.log(
|
|
4247
|
+
console.log(chalk45.dim(`
|
|
4226
4248
|
Analyzed ${results.length} files`));
|
|
4227
4249
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4228
4250
|
console.error(
|
|
4229
|
-
|
|
4251
|
+
chalk45.red(
|
|
4230
4252
|
`
|
|
4231
4253
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4232
4254
|
|
|
4233
|
-
\u26A0\uFE0F ${
|
|
4255
|
+
\u26A0\uFE0F ${chalk45.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.`
|
|
4234
4256
|
)
|
|
4235
4257
|
);
|
|
4236
4258
|
process.exit(1);
|
|
@@ -4287,7 +4309,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4287
4309
|
|
|
4288
4310
|
// src/commands/complexity/sloc.ts
|
|
4289
4311
|
import fs14 from "fs";
|
|
4290
|
-
import
|
|
4312
|
+
import chalk46 from "chalk";
|
|
4291
4313
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4292
4314
|
withSourceFiles(pattern2, (files) => {
|
|
4293
4315
|
const results = [];
|
|
@@ -4303,12 +4325,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4303
4325
|
results.sort((a, b) => b.lines - a.lines);
|
|
4304
4326
|
for (const { file, lines } of results) {
|
|
4305
4327
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4306
|
-
const color = exceedsThreshold ?
|
|
4307
|
-
console.log(`${color(file)} \u2192 ${
|
|
4328
|
+
const color = exceedsThreshold ? chalk46.red : chalk46.white;
|
|
4329
|
+
console.log(`${color(file)} \u2192 ${chalk46.cyan(lines)} lines`);
|
|
4308
4330
|
}
|
|
4309
4331
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4310
4332
|
console.log(
|
|
4311
|
-
|
|
4333
|
+
chalk46.dim(`
|
|
4312
4334
|
Total: ${total} lines across ${files.length} files`)
|
|
4313
4335
|
);
|
|
4314
4336
|
if (hasViolation) {
|
|
@@ -4322,21 +4344,21 @@ async function analyze(pattern2) {
|
|
|
4322
4344
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4323
4345
|
const files = findSourceFiles2(searchPattern);
|
|
4324
4346
|
if (files.length === 0) {
|
|
4325
|
-
console.log(
|
|
4347
|
+
console.log(chalk47.yellow("No files found matching pattern"));
|
|
4326
4348
|
return;
|
|
4327
4349
|
}
|
|
4328
4350
|
if (files.length === 1) {
|
|
4329
4351
|
const file = files[0];
|
|
4330
|
-
console.log(
|
|
4352
|
+
console.log(chalk47.bold.underline("SLOC"));
|
|
4331
4353
|
await sloc(file);
|
|
4332
4354
|
console.log();
|
|
4333
|
-
console.log(
|
|
4355
|
+
console.log(chalk47.bold.underline("Cyclomatic Complexity"));
|
|
4334
4356
|
await cyclomatic(file);
|
|
4335
4357
|
console.log();
|
|
4336
|
-
console.log(
|
|
4358
|
+
console.log(chalk47.bold.underline("Halstead Metrics"));
|
|
4337
4359
|
await halstead(file);
|
|
4338
4360
|
console.log();
|
|
4339
|
-
console.log(
|
|
4361
|
+
console.log(chalk47.bold.underline("Maintainability Index"));
|
|
4340
4362
|
await maintainability(file);
|
|
4341
4363
|
return;
|
|
4342
4364
|
}
|
|
@@ -4364,7 +4386,7 @@ function registerComplexity(program2) {
|
|
|
4364
4386
|
|
|
4365
4387
|
// src/commands/deploy/redirect.ts
|
|
4366
4388
|
import { existsSync as existsSync21, readFileSync as readFileSync16, writeFileSync as writeFileSync16 } from "fs";
|
|
4367
|
-
import
|
|
4389
|
+
import chalk48 from "chalk";
|
|
4368
4390
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4369
4391
|
if (!window.location.pathname.endsWith('/')) {
|
|
4370
4392
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4373,22 +4395,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4373
4395
|
function redirect() {
|
|
4374
4396
|
const indexPath = "index.html";
|
|
4375
4397
|
if (!existsSync21(indexPath)) {
|
|
4376
|
-
console.log(
|
|
4398
|
+
console.log(chalk48.yellow("No index.html found"));
|
|
4377
4399
|
return;
|
|
4378
4400
|
}
|
|
4379
4401
|
const content = readFileSync16(indexPath, "utf-8");
|
|
4380
4402
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4381
|
-
console.log(
|
|
4403
|
+
console.log(chalk48.dim("Trailing slash script already present"));
|
|
4382
4404
|
return;
|
|
4383
4405
|
}
|
|
4384
4406
|
const headCloseIndex = content.indexOf("</head>");
|
|
4385
4407
|
if (headCloseIndex === -1) {
|
|
4386
|
-
console.log(
|
|
4408
|
+
console.log(chalk48.red("Could not find </head> tag in index.html"));
|
|
4387
4409
|
return;
|
|
4388
4410
|
}
|
|
4389
4411
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4390
4412
|
writeFileSync16(indexPath, newContent);
|
|
4391
|
-
console.log(
|
|
4413
|
+
console.log(chalk48.green("Added trailing slash redirect to index.html"));
|
|
4392
4414
|
}
|
|
4393
4415
|
|
|
4394
4416
|
// src/commands/registerDeploy.ts
|
|
@@ -4415,7 +4437,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
4415
4437
|
|
|
4416
4438
|
// src/commands/devlog/shared.ts
|
|
4417
4439
|
import { execSync as execSync16 } from "child_process";
|
|
4418
|
-
import
|
|
4440
|
+
import chalk49 from "chalk";
|
|
4419
4441
|
|
|
4420
4442
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4421
4443
|
import { readdirSync, readFileSync as readFileSync17 } from "fs";
|
|
@@ -4502,13 +4524,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4502
4524
|
}
|
|
4503
4525
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4504
4526
|
for (const commit2 of commits) {
|
|
4505
|
-
console.log(` ${
|
|
4527
|
+
console.log(` ${chalk49.yellow(commit2.hash)} ${commit2.message}`);
|
|
4506
4528
|
if (verbose) {
|
|
4507
4529
|
const visibleFiles = commit2.files.filter(
|
|
4508
4530
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4509
4531
|
);
|
|
4510
4532
|
for (const file of visibleFiles) {
|
|
4511
|
-
console.log(` ${
|
|
4533
|
+
console.log(` ${chalk49.dim(file)}`);
|
|
4512
4534
|
}
|
|
4513
4535
|
}
|
|
4514
4536
|
}
|
|
@@ -4533,15 +4555,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4533
4555
|
}
|
|
4534
4556
|
|
|
4535
4557
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4536
|
-
import
|
|
4558
|
+
import chalk50 from "chalk";
|
|
4537
4559
|
function printDateHeader(date, isSkipped, entries) {
|
|
4538
4560
|
if (isSkipped) {
|
|
4539
|
-
console.log(`${
|
|
4561
|
+
console.log(`${chalk50.bold.blue(date)} ${chalk50.dim("skipped")}`);
|
|
4540
4562
|
} else if (entries && entries.length > 0) {
|
|
4541
|
-
const entryInfo = entries.map((e) => `${
|
|
4542
|
-
console.log(`${
|
|
4563
|
+
const entryInfo = entries.map((e) => `${chalk50.green(e.version)} ${e.title}`).join(" | ");
|
|
4564
|
+
console.log(`${chalk50.bold.blue(date)} ${entryInfo}`);
|
|
4543
4565
|
} else {
|
|
4544
|
-
console.log(`${
|
|
4566
|
+
console.log(`${chalk50.bold.blue(date)} ${chalk50.red("\u26A0 devlog missing")}`);
|
|
4545
4567
|
}
|
|
4546
4568
|
}
|
|
4547
4569
|
|
|
@@ -4644,24 +4666,24 @@ function bumpVersion(version2, type) {
|
|
|
4644
4666
|
|
|
4645
4667
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
4646
4668
|
import { execSync as execSync19 } from "child_process";
|
|
4647
|
-
import
|
|
4669
|
+
import chalk52 from "chalk";
|
|
4648
4670
|
|
|
4649
4671
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
4650
|
-
import
|
|
4672
|
+
import chalk51 from "chalk";
|
|
4651
4673
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
4652
4674
|
if (conventional && firstHash) {
|
|
4653
4675
|
const version2 = getVersionAtCommit(firstHash);
|
|
4654
4676
|
if (version2) {
|
|
4655
|
-
console.log(`${
|
|
4677
|
+
console.log(`${chalk51.bold("version:")} ${stripToMinor(version2)}`);
|
|
4656
4678
|
} else {
|
|
4657
|
-
console.log(`${
|
|
4679
|
+
console.log(`${chalk51.bold("version:")} ${chalk51.red("unknown")}`);
|
|
4658
4680
|
}
|
|
4659
4681
|
} else if (patchVersion && minorVersion) {
|
|
4660
4682
|
console.log(
|
|
4661
|
-
`${
|
|
4683
|
+
`${chalk51.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
4662
4684
|
);
|
|
4663
4685
|
} else {
|
|
4664
|
-
console.log(`${
|
|
4686
|
+
console.log(`${chalk51.bold("version:")} v0.1 (initial)`);
|
|
4665
4687
|
}
|
|
4666
4688
|
}
|
|
4667
4689
|
|
|
@@ -4708,16 +4730,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
4708
4730
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
4709
4731
|
}
|
|
4710
4732
|
function logName(repoName) {
|
|
4711
|
-
console.log(`${
|
|
4733
|
+
console.log(`${chalk52.bold("name:")} ${repoName}`);
|
|
4712
4734
|
}
|
|
4713
4735
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
4714
4736
|
logName(ctx.repoName);
|
|
4715
4737
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
4716
|
-
console.log(
|
|
4738
|
+
console.log(chalk52.bold.blue(targetDate));
|
|
4717
4739
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
4718
4740
|
}
|
|
4719
4741
|
function logNoCommits(lastInfo) {
|
|
4720
|
-
console.log(
|
|
4742
|
+
console.log(chalk52.dim(noCommitsMessage(!!lastInfo)));
|
|
4721
4743
|
}
|
|
4722
4744
|
|
|
4723
4745
|
// src/commands/devlog/next/index.ts
|
|
@@ -4758,11 +4780,11 @@ function next2(options2) {
|
|
|
4758
4780
|
import { execSync as execSync20 } from "child_process";
|
|
4759
4781
|
|
|
4760
4782
|
// src/commands/devlog/repos/printReposTable.ts
|
|
4761
|
-
import
|
|
4783
|
+
import chalk53 from "chalk";
|
|
4762
4784
|
function colorStatus(status2) {
|
|
4763
|
-
if (status2 === "missing") return
|
|
4764
|
-
if (status2 === "outdated") return
|
|
4765
|
-
return
|
|
4785
|
+
if (status2 === "missing") return chalk53.red(status2);
|
|
4786
|
+
if (status2 === "outdated") return chalk53.yellow(status2);
|
|
4787
|
+
return chalk53.green(status2);
|
|
4766
4788
|
}
|
|
4767
4789
|
function formatRow(row, nameWidth) {
|
|
4768
4790
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -4776,8 +4798,8 @@ function printReposTable(rows) {
|
|
|
4776
4798
|
"Last Devlog".padEnd(11),
|
|
4777
4799
|
"Status"
|
|
4778
4800
|
].join(" ");
|
|
4779
|
-
console.log(
|
|
4780
|
-
console.log(
|
|
4801
|
+
console.log(chalk53.dim(header));
|
|
4802
|
+
console.log(chalk53.dim("-".repeat(header.length)));
|
|
4781
4803
|
for (const row of rows) {
|
|
4782
4804
|
console.log(formatRow(row, nameWidth));
|
|
4783
4805
|
}
|
|
@@ -4835,14 +4857,14 @@ function repos(options2) {
|
|
|
4835
4857
|
// src/commands/devlog/skip.ts
|
|
4836
4858
|
import { writeFileSync as writeFileSync17 } from "fs";
|
|
4837
4859
|
import { join as join16 } from "path";
|
|
4838
|
-
import
|
|
4860
|
+
import chalk54 from "chalk";
|
|
4839
4861
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
4840
4862
|
function getBlogConfigPath() {
|
|
4841
4863
|
return join16(BLOG_REPO_ROOT, "assist.yml");
|
|
4842
4864
|
}
|
|
4843
4865
|
function skip(date) {
|
|
4844
4866
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
4845
|
-
console.log(
|
|
4867
|
+
console.log(chalk54.red("Invalid date format. Use YYYY-MM-DD"));
|
|
4846
4868
|
process.exit(1);
|
|
4847
4869
|
}
|
|
4848
4870
|
const repoName = getRepoName();
|
|
@@ -4853,7 +4875,7 @@ function skip(date) {
|
|
|
4853
4875
|
const skipDays = skip2[repoName] ?? [];
|
|
4854
4876
|
if (skipDays.includes(date)) {
|
|
4855
4877
|
console.log(
|
|
4856
|
-
|
|
4878
|
+
chalk54.yellow(`${date} is already in skip list for ${repoName}`)
|
|
4857
4879
|
);
|
|
4858
4880
|
return;
|
|
4859
4881
|
}
|
|
@@ -4863,20 +4885,20 @@ function skip(date) {
|
|
|
4863
4885
|
devlog.skip = skip2;
|
|
4864
4886
|
config.devlog = devlog;
|
|
4865
4887
|
writeFileSync17(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
4866
|
-
console.log(
|
|
4888
|
+
console.log(chalk54.green(`Added ${date} to skip list for ${repoName}`));
|
|
4867
4889
|
}
|
|
4868
4890
|
|
|
4869
4891
|
// src/commands/devlog/version.ts
|
|
4870
|
-
import
|
|
4892
|
+
import chalk55 from "chalk";
|
|
4871
4893
|
function version() {
|
|
4872
4894
|
const config = loadConfig();
|
|
4873
4895
|
const name = getRepoName();
|
|
4874
4896
|
const lastInfo = getLastVersionInfo(name, config);
|
|
4875
4897
|
const lastVersion = lastInfo?.version ?? null;
|
|
4876
4898
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
4877
|
-
console.log(`${
|
|
4878
|
-
console.log(`${
|
|
4879
|
-
console.log(`${
|
|
4899
|
+
console.log(`${chalk55.bold("name:")} ${name}`);
|
|
4900
|
+
console.log(`${chalk55.bold("last:")} ${lastVersion ?? chalk55.dim("none")}`);
|
|
4901
|
+
console.log(`${chalk55.bold("next:")} ${nextVersion ?? chalk55.dim("none")}`);
|
|
4880
4902
|
}
|
|
4881
4903
|
|
|
4882
4904
|
// src/commands/registerDevlog.ts
|
|
@@ -4900,7 +4922,7 @@ function registerDevlog(program2) {
|
|
|
4900
4922
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
4901
4923
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
4902
4924
|
import { join as join17 } from "path";
|
|
4903
|
-
import
|
|
4925
|
+
import chalk56 from "chalk";
|
|
4904
4926
|
|
|
4905
4927
|
// src/shared/findRepoRoot.ts
|
|
4906
4928
|
import { existsSync as existsSync22 } from "fs";
|
|
@@ -4963,14 +4985,14 @@ function checkBuildLocks(startDir) {
|
|
|
4963
4985
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
4964
4986
|
if (locked) {
|
|
4965
4987
|
console.error(
|
|
4966
|
-
|
|
4988
|
+
chalk56.red("Build output locked (is VS debugging?): ") + locked
|
|
4967
4989
|
);
|
|
4968
4990
|
process.exit(1);
|
|
4969
4991
|
}
|
|
4970
4992
|
}
|
|
4971
4993
|
async function checkBuildLocksCommand() {
|
|
4972
4994
|
checkBuildLocks();
|
|
4973
|
-
console.log(
|
|
4995
|
+
console.log(chalk56.green("No build locks detected"));
|
|
4974
4996
|
}
|
|
4975
4997
|
|
|
4976
4998
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -5069,30 +5091,30 @@ function escapeRegex(s) {
|
|
|
5069
5091
|
}
|
|
5070
5092
|
|
|
5071
5093
|
// src/commands/dotnet/printTree.ts
|
|
5072
|
-
import
|
|
5094
|
+
import chalk57 from "chalk";
|
|
5073
5095
|
function printNodes(nodes, prefix2) {
|
|
5074
5096
|
for (let i = 0; i < nodes.length; i++) {
|
|
5075
5097
|
const isLast = i === nodes.length - 1;
|
|
5076
5098
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5077
5099
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5078
5100
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5079
|
-
const label2 = isMissing ?
|
|
5101
|
+
const label2 = isMissing ? chalk57.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5080
5102
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5081
5103
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5082
5104
|
}
|
|
5083
5105
|
}
|
|
5084
5106
|
function printTree(tree, totalCount, solutions) {
|
|
5085
|
-
console.log(
|
|
5086
|
-
console.log(
|
|
5107
|
+
console.log(chalk57.bold("\nProject Dependency Tree"));
|
|
5108
|
+
console.log(chalk57.cyan(tree.relativePath));
|
|
5087
5109
|
printNodes(tree.children, "");
|
|
5088
|
-
console.log(
|
|
5110
|
+
console.log(chalk57.dim(`
|
|
5089
5111
|
${totalCount} projects total (including root)`));
|
|
5090
|
-
console.log(
|
|
5112
|
+
console.log(chalk57.bold("\nSolution Membership"));
|
|
5091
5113
|
if (solutions.length === 0) {
|
|
5092
|
-
console.log(
|
|
5114
|
+
console.log(chalk57.yellow(" Not found in any .sln"));
|
|
5093
5115
|
} else {
|
|
5094
5116
|
for (const sln of solutions) {
|
|
5095
|
-
console.log(` ${
|
|
5117
|
+
console.log(` ${chalk57.green(sln)}`);
|
|
5096
5118
|
}
|
|
5097
5119
|
}
|
|
5098
5120
|
console.log();
|
|
@@ -5121,16 +5143,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5121
5143
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5122
5144
|
import { existsSync as existsSync23 } from "fs";
|
|
5123
5145
|
import path24 from "path";
|
|
5124
|
-
import
|
|
5146
|
+
import chalk58 from "chalk";
|
|
5125
5147
|
function resolveCsproj(csprojPath) {
|
|
5126
5148
|
const resolved = path24.resolve(csprojPath);
|
|
5127
5149
|
if (!existsSync23(resolved)) {
|
|
5128
|
-
console.error(
|
|
5150
|
+
console.error(chalk58.red(`File not found: ${resolved}`));
|
|
5129
5151
|
process.exit(1);
|
|
5130
5152
|
}
|
|
5131
5153
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5132
5154
|
if (!repoRoot) {
|
|
5133
|
-
console.error(
|
|
5155
|
+
console.error(chalk58.red("Could not find git repository root"));
|
|
5134
5156
|
process.exit(1);
|
|
5135
5157
|
}
|
|
5136
5158
|
return { resolved, repoRoot };
|
|
@@ -5180,12 +5202,12 @@ function getChangedCsFiles(scope) {
|
|
|
5180
5202
|
}
|
|
5181
5203
|
|
|
5182
5204
|
// src/commands/dotnet/inSln.ts
|
|
5183
|
-
import
|
|
5205
|
+
import chalk59 from "chalk";
|
|
5184
5206
|
async function inSln(csprojPath) {
|
|
5185
5207
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5186
5208
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5187
5209
|
if (solutions.length === 0) {
|
|
5188
|
-
console.log(
|
|
5210
|
+
console.log(chalk59.yellow("Not found in any .sln file"));
|
|
5189
5211
|
process.exit(1);
|
|
5190
5212
|
}
|
|
5191
5213
|
for (const sln of solutions) {
|
|
@@ -5194,7 +5216,7 @@ async function inSln(csprojPath) {
|
|
|
5194
5216
|
}
|
|
5195
5217
|
|
|
5196
5218
|
// src/commands/dotnet/inspect.ts
|
|
5197
|
-
import
|
|
5219
|
+
import chalk65 from "chalk";
|
|
5198
5220
|
|
|
5199
5221
|
// src/shared/formatElapsed.ts
|
|
5200
5222
|
function formatElapsed(ms) {
|
|
@@ -5206,12 +5228,12 @@ function formatElapsed(ms) {
|
|
|
5206
5228
|
}
|
|
5207
5229
|
|
|
5208
5230
|
// src/commands/dotnet/displayIssues.ts
|
|
5209
|
-
import
|
|
5231
|
+
import chalk60 from "chalk";
|
|
5210
5232
|
var SEVERITY_COLOR = {
|
|
5211
|
-
ERROR:
|
|
5212
|
-
WARNING:
|
|
5213
|
-
SUGGESTION:
|
|
5214
|
-
HINT:
|
|
5233
|
+
ERROR: chalk60.red,
|
|
5234
|
+
WARNING: chalk60.yellow,
|
|
5235
|
+
SUGGESTION: chalk60.cyan,
|
|
5236
|
+
HINT: chalk60.dim
|
|
5215
5237
|
};
|
|
5216
5238
|
function groupByFile(issues) {
|
|
5217
5239
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5227,15 +5249,15 @@ function groupByFile(issues) {
|
|
|
5227
5249
|
}
|
|
5228
5250
|
function displayIssues(issues) {
|
|
5229
5251
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5230
|
-
console.log(
|
|
5252
|
+
console.log(chalk60.bold(file));
|
|
5231
5253
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5232
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5254
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk60.white;
|
|
5233
5255
|
console.log(
|
|
5234
|
-
` ${
|
|
5256
|
+
` ${chalk60.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5235
5257
|
);
|
|
5236
5258
|
}
|
|
5237
5259
|
}
|
|
5238
|
-
console.log(
|
|
5260
|
+
console.log(chalk60.dim(`
|
|
5239
5261
|
${issues.length} issue(s) found`));
|
|
5240
5262
|
}
|
|
5241
5263
|
|
|
@@ -5294,12 +5316,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5294
5316
|
// src/commands/dotnet/resolveSolution.ts
|
|
5295
5317
|
import { existsSync as existsSync24 } from "fs";
|
|
5296
5318
|
import path25 from "path";
|
|
5297
|
-
import
|
|
5319
|
+
import chalk62 from "chalk";
|
|
5298
5320
|
|
|
5299
5321
|
// src/commands/dotnet/findSolution.ts
|
|
5300
5322
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5301
5323
|
import { dirname as dirname16, join as join18 } from "path";
|
|
5302
|
-
import
|
|
5324
|
+
import chalk61 from "chalk";
|
|
5303
5325
|
function findSlnInDir(dir) {
|
|
5304
5326
|
try {
|
|
5305
5327
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join18(dir, f));
|
|
@@ -5315,17 +5337,17 @@ function findSolution() {
|
|
|
5315
5337
|
const slnFiles = findSlnInDir(current);
|
|
5316
5338
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5317
5339
|
if (slnFiles.length > 1) {
|
|
5318
|
-
console.error(
|
|
5340
|
+
console.error(chalk61.red(`Multiple .sln files found in ${current}:`));
|
|
5319
5341
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5320
5342
|
console.error(
|
|
5321
|
-
|
|
5343
|
+
chalk61.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5322
5344
|
);
|
|
5323
5345
|
process.exit(1);
|
|
5324
5346
|
}
|
|
5325
5347
|
if (current === ceiling) break;
|
|
5326
5348
|
current = dirname16(current);
|
|
5327
5349
|
}
|
|
5328
|
-
console.error(
|
|
5350
|
+
console.error(chalk61.red("No .sln file found between cwd and repo root"));
|
|
5329
5351
|
process.exit(1);
|
|
5330
5352
|
}
|
|
5331
5353
|
|
|
@@ -5334,7 +5356,7 @@ function resolveSolution(sln) {
|
|
|
5334
5356
|
if (sln) {
|
|
5335
5357
|
const resolved = path25.resolve(sln);
|
|
5336
5358
|
if (!existsSync24(resolved)) {
|
|
5337
|
-
console.error(
|
|
5359
|
+
console.error(chalk62.red(`Solution file not found: ${resolved}`));
|
|
5338
5360
|
process.exit(1);
|
|
5339
5361
|
}
|
|
5340
5362
|
return resolved;
|
|
@@ -5376,14 +5398,14 @@ import { execSync as execSync22 } from "child_process";
|
|
|
5376
5398
|
import { existsSync as existsSync25, readFileSync as readFileSync20, unlinkSync as unlinkSync4 } from "fs";
|
|
5377
5399
|
import { tmpdir as tmpdir2 } from "os";
|
|
5378
5400
|
import path26 from "path";
|
|
5379
|
-
import
|
|
5401
|
+
import chalk63 from "chalk";
|
|
5380
5402
|
function assertJbInstalled() {
|
|
5381
5403
|
try {
|
|
5382
5404
|
execSync22("jb inspectcode --version", { stdio: "pipe" });
|
|
5383
5405
|
} catch {
|
|
5384
|
-
console.error(
|
|
5406
|
+
console.error(chalk63.red("jb is not installed. Install with:"));
|
|
5385
5407
|
console.error(
|
|
5386
|
-
|
|
5408
|
+
chalk63.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5387
5409
|
);
|
|
5388
5410
|
process.exit(1);
|
|
5389
5411
|
}
|
|
@@ -5401,11 +5423,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5401
5423
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5402
5424
|
process.stderr.write(err.stderr);
|
|
5403
5425
|
}
|
|
5404
|
-
console.error(
|
|
5426
|
+
console.error(chalk63.red("jb inspectcode failed"));
|
|
5405
5427
|
process.exit(1);
|
|
5406
5428
|
}
|
|
5407
5429
|
if (!existsSync25(reportPath)) {
|
|
5408
|
-
console.error(
|
|
5430
|
+
console.error(chalk63.red("Report file not generated"));
|
|
5409
5431
|
process.exit(1);
|
|
5410
5432
|
}
|
|
5411
5433
|
const xml = readFileSync20(reportPath, "utf-8");
|
|
@@ -5415,7 +5437,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5415
5437
|
|
|
5416
5438
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5417
5439
|
import { execSync as execSync23 } from "child_process";
|
|
5418
|
-
import
|
|
5440
|
+
import chalk64 from "chalk";
|
|
5419
5441
|
function resolveMsbuildPath() {
|
|
5420
5442
|
const config = loadConfig();
|
|
5421
5443
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5426,9 +5448,9 @@ function assertMsbuildInstalled() {
|
|
|
5426
5448
|
try {
|
|
5427
5449
|
execSync23(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5428
5450
|
} catch {
|
|
5429
|
-
console.error(
|
|
5451
|
+
console.error(chalk64.red(`msbuild not found at: ${msbuild}`));
|
|
5430
5452
|
console.error(
|
|
5431
|
-
|
|
5453
|
+
chalk64.yellow(
|
|
5432
5454
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5433
5455
|
)
|
|
5434
5456
|
);
|
|
@@ -5475,17 +5497,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5475
5497
|
// src/commands/dotnet/inspect.ts
|
|
5476
5498
|
function logScope(changedFiles) {
|
|
5477
5499
|
if (changedFiles === null) {
|
|
5478
|
-
console.log(
|
|
5500
|
+
console.log(chalk65.dim("Inspecting full solution..."));
|
|
5479
5501
|
} else {
|
|
5480
5502
|
console.log(
|
|
5481
|
-
|
|
5503
|
+
chalk65.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5482
5504
|
);
|
|
5483
5505
|
}
|
|
5484
5506
|
}
|
|
5485
5507
|
function reportResults(issues, elapsed) {
|
|
5486
5508
|
if (issues.length > 0) displayIssues(issues);
|
|
5487
|
-
else console.log(
|
|
5488
|
-
console.log(
|
|
5509
|
+
else console.log(chalk65.green("No issues found"));
|
|
5510
|
+
console.log(chalk65.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5489
5511
|
if (issues.length > 0) process.exit(1);
|
|
5490
5512
|
}
|
|
5491
5513
|
async function inspect(sln, options2) {
|
|
@@ -5496,7 +5518,7 @@ async function inspect(sln, options2) {
|
|
|
5496
5518
|
const scope = parseScope(options2.scope);
|
|
5497
5519
|
const changedFiles = getChangedCsFiles(scope);
|
|
5498
5520
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5499
|
-
console.log(
|
|
5521
|
+
console.log(chalk65.green("No changed .cs files found"));
|
|
5500
5522
|
return;
|
|
5501
5523
|
}
|
|
5502
5524
|
logScope(changedFiles);
|
|
@@ -5522,7 +5544,7 @@ function registerDotnet(program2) {
|
|
|
5522
5544
|
}
|
|
5523
5545
|
|
|
5524
5546
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5525
|
-
import
|
|
5547
|
+
import chalk67 from "chalk";
|
|
5526
5548
|
|
|
5527
5549
|
// src/commands/jira/adfToText.ts
|
|
5528
5550
|
function renderInline(node) {
|
|
@@ -5583,7 +5605,7 @@ function adfToText(doc) {
|
|
|
5583
5605
|
|
|
5584
5606
|
// src/commands/jira/fetchIssue.ts
|
|
5585
5607
|
import { execSync as execSync24 } from "child_process";
|
|
5586
|
-
import
|
|
5608
|
+
import chalk66 from "chalk";
|
|
5587
5609
|
function fetchIssue(issueKey, fields) {
|
|
5588
5610
|
let result;
|
|
5589
5611
|
try {
|
|
@@ -5596,15 +5618,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
5596
5618
|
const stderr = error.stderr;
|
|
5597
5619
|
if (stderr.includes("unauthorized")) {
|
|
5598
5620
|
console.error(
|
|
5599
|
-
|
|
5621
|
+
chalk66.red("Jira authentication expired."),
|
|
5600
5622
|
"Run",
|
|
5601
|
-
|
|
5623
|
+
chalk66.cyan("assist jira auth"),
|
|
5602
5624
|
"to re-authenticate."
|
|
5603
5625
|
);
|
|
5604
5626
|
process.exit(1);
|
|
5605
5627
|
}
|
|
5606
5628
|
}
|
|
5607
|
-
console.error(
|
|
5629
|
+
console.error(chalk66.red(`Failed to fetch ${issueKey}.`));
|
|
5608
5630
|
process.exit(1);
|
|
5609
5631
|
}
|
|
5610
5632
|
return JSON.parse(result);
|
|
@@ -5618,7 +5640,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5618
5640
|
const parsed = fetchIssue(issueKey, field);
|
|
5619
5641
|
const acValue = parsed?.fields?.[field];
|
|
5620
5642
|
if (!acValue) {
|
|
5621
|
-
console.log(
|
|
5643
|
+
console.log(chalk67.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
5622
5644
|
return;
|
|
5623
5645
|
}
|
|
5624
5646
|
if (typeof acValue === "string") {
|
|
@@ -5646,10 +5668,10 @@ function getStorePath(filename) {
|
|
|
5646
5668
|
return join19(getStoreDir(), filename);
|
|
5647
5669
|
}
|
|
5648
5670
|
function loadJson(filename) {
|
|
5649
|
-
const
|
|
5650
|
-
if (existsSync26(
|
|
5671
|
+
const path50 = getStorePath(filename);
|
|
5672
|
+
if (existsSync26(path50)) {
|
|
5651
5673
|
try {
|
|
5652
|
-
return JSON.parse(readFileSync21(
|
|
5674
|
+
return JSON.parse(readFileSync21(path50, "utf-8"));
|
|
5653
5675
|
} catch {
|
|
5654
5676
|
return {};
|
|
5655
5677
|
}
|
|
@@ -5713,14 +5735,14 @@ async function jiraAuth() {
|
|
|
5713
5735
|
}
|
|
5714
5736
|
|
|
5715
5737
|
// src/commands/jira/viewIssue.ts
|
|
5716
|
-
import
|
|
5738
|
+
import chalk68 from "chalk";
|
|
5717
5739
|
function viewIssue(issueKey) {
|
|
5718
5740
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
5719
5741
|
const fields = parsed?.fields;
|
|
5720
5742
|
const summary = fields?.summary;
|
|
5721
5743
|
const description = fields?.description;
|
|
5722
5744
|
if (summary) {
|
|
5723
|
-
console.log(
|
|
5745
|
+
console.log(chalk68.bold(summary));
|
|
5724
5746
|
}
|
|
5725
5747
|
if (description) {
|
|
5726
5748
|
if (summary) console.log();
|
|
@@ -5734,7 +5756,7 @@ function viewIssue(issueKey) {
|
|
|
5734
5756
|
}
|
|
5735
5757
|
if (!summary && !description) {
|
|
5736
5758
|
console.log(
|
|
5737
|
-
|
|
5759
|
+
chalk68.yellow(`No summary or description found on ${issueKey}.`)
|
|
5738
5760
|
);
|
|
5739
5761
|
}
|
|
5740
5762
|
}
|
|
@@ -5748,7 +5770,7 @@ function registerJira(program2) {
|
|
|
5748
5770
|
}
|
|
5749
5771
|
|
|
5750
5772
|
// src/commands/news/add/index.ts
|
|
5751
|
-
import
|
|
5773
|
+
import chalk69 from "chalk";
|
|
5752
5774
|
import enquirer7 from "enquirer";
|
|
5753
5775
|
async function add2(url) {
|
|
5754
5776
|
if (!url) {
|
|
@@ -5771,17 +5793,17 @@ async function add2(url) {
|
|
|
5771
5793
|
const news = config.news ?? {};
|
|
5772
5794
|
const feeds = news.feeds ?? [];
|
|
5773
5795
|
if (feeds.includes(url)) {
|
|
5774
|
-
console.log(
|
|
5796
|
+
console.log(chalk69.yellow("Feed already exists in config"));
|
|
5775
5797
|
return;
|
|
5776
5798
|
}
|
|
5777
5799
|
feeds.push(url);
|
|
5778
5800
|
config.news = { ...news, feeds };
|
|
5779
5801
|
saveGlobalConfig(config);
|
|
5780
|
-
console.log(
|
|
5802
|
+
console.log(chalk69.green(`Added feed: ${url}`));
|
|
5781
5803
|
}
|
|
5782
5804
|
|
|
5783
5805
|
// src/commands/news/web/handleRequest.ts
|
|
5784
|
-
import
|
|
5806
|
+
import chalk70 from "chalk";
|
|
5785
5807
|
|
|
5786
5808
|
// src/commands/news/web/shared.ts
|
|
5787
5809
|
import { decodeHTML } from "entities";
|
|
@@ -5917,17 +5939,17 @@ function prefetch() {
|
|
|
5917
5939
|
const config = loadConfig();
|
|
5918
5940
|
const total = config.news.feeds.length;
|
|
5919
5941
|
if (total === 0) return;
|
|
5920
|
-
process.stdout.write(
|
|
5942
|
+
process.stdout.write(chalk70.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
5921
5943
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
5922
5944
|
const width = 20;
|
|
5923
5945
|
const filled = Math.round(done2 / t * width);
|
|
5924
5946
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
5925
5947
|
process.stdout.write(
|
|
5926
|
-
`\r${
|
|
5948
|
+
`\r${chalk70.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
5927
5949
|
);
|
|
5928
5950
|
}).then((items) => {
|
|
5929
5951
|
process.stdout.write(
|
|
5930
|
-
`\r${
|
|
5952
|
+
`\r${chalk70.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
5931
5953
|
`
|
|
5932
5954
|
);
|
|
5933
5955
|
cachedItems = items;
|
|
@@ -6042,7 +6064,7 @@ function validateLine(line) {
|
|
|
6042
6064
|
process.exit(1);
|
|
6043
6065
|
}
|
|
6044
6066
|
}
|
|
6045
|
-
function comment(
|
|
6067
|
+
function comment(path50, line, body) {
|
|
6046
6068
|
validateBody(body);
|
|
6047
6069
|
validateLine(line);
|
|
6048
6070
|
try {
|
|
@@ -6062,7 +6084,7 @@ function comment(path49, line, body) {
|
|
|
6062
6084
|
"-f",
|
|
6063
6085
|
`body=${body}`,
|
|
6064
6086
|
"-f",
|
|
6065
|
-
`path=${
|
|
6087
|
+
`path=${path50}`,
|
|
6066
6088
|
"-F",
|
|
6067
6089
|
`line=${line}`
|
|
6068
6090
|
],
|
|
@@ -6071,7 +6093,7 @@ function comment(path49, line, body) {
|
|
|
6071
6093
|
if (result.status !== 0) {
|
|
6072
6094
|
throw new Error(result.stderr || result.stdout);
|
|
6073
6095
|
}
|
|
6074
|
-
console.log(`Added review comment on ${
|
|
6096
|
+
console.log(`Added review comment on ${path50}:${line}`);
|
|
6075
6097
|
} finally {
|
|
6076
6098
|
unlinkSync5(queryFile);
|
|
6077
6099
|
}
|
|
@@ -6288,20 +6310,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6288
6310
|
}
|
|
6289
6311
|
|
|
6290
6312
|
// src/commands/prs/listComments/printComments.ts
|
|
6291
|
-
import
|
|
6313
|
+
import chalk71 from "chalk";
|
|
6292
6314
|
function formatForHuman(comment2) {
|
|
6293
6315
|
if (comment2.type === "review") {
|
|
6294
|
-
const stateColor = comment2.state === "APPROVED" ?
|
|
6316
|
+
const stateColor = comment2.state === "APPROVED" ? chalk71.green : comment2.state === "CHANGES_REQUESTED" ? chalk71.red : chalk71.yellow;
|
|
6295
6317
|
return [
|
|
6296
|
-
`${
|
|
6318
|
+
`${chalk71.cyan("Review")} by ${chalk71.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
|
|
6297
6319
|
comment2.body,
|
|
6298
6320
|
""
|
|
6299
6321
|
].join("\n");
|
|
6300
6322
|
}
|
|
6301
6323
|
const location = comment2.line ? `:${comment2.line}` : "";
|
|
6302
6324
|
return [
|
|
6303
|
-
`${
|
|
6304
|
-
|
|
6325
|
+
`${chalk71.cyan("Line comment")} by ${chalk71.bold(comment2.user)} on ${chalk71.dim(`${comment2.path}${location}`)}`,
|
|
6326
|
+
chalk71.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6305
6327
|
comment2.body,
|
|
6306
6328
|
""
|
|
6307
6329
|
].join("\n");
|
|
@@ -6391,13 +6413,13 @@ import { execSync as execSync31 } from "child_process";
|
|
|
6391
6413
|
import enquirer8 from "enquirer";
|
|
6392
6414
|
|
|
6393
6415
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6394
|
-
import
|
|
6416
|
+
import chalk72 from "chalk";
|
|
6395
6417
|
var STATUS_MAP = {
|
|
6396
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6397
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6418
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk72.magenta("merged"), date: pr.mergedAt } : null,
|
|
6419
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk72.red("closed"), date: pr.closedAt } : null
|
|
6398
6420
|
};
|
|
6399
6421
|
function defaultStatus(pr) {
|
|
6400
|
-
return { label:
|
|
6422
|
+
return { label: chalk72.green("opened"), date: pr.createdAt };
|
|
6401
6423
|
}
|
|
6402
6424
|
function getStatus2(pr) {
|
|
6403
6425
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6406,11 +6428,11 @@ function formatDate(dateStr) {
|
|
|
6406
6428
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6407
6429
|
}
|
|
6408
6430
|
function formatPrHeader(pr, status2) {
|
|
6409
|
-
return `${
|
|
6431
|
+
return `${chalk72.cyan(`#${pr.number}`)} ${pr.title} ${chalk72.dim(`(${pr.author.login},`)} ${status2.label} ${chalk72.dim(`${formatDate(status2.date)})`)}`;
|
|
6410
6432
|
}
|
|
6411
6433
|
function logPrDetails(pr) {
|
|
6412
6434
|
console.log(
|
|
6413
|
-
|
|
6435
|
+
chalk72.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6414
6436
|
);
|
|
6415
6437
|
console.log();
|
|
6416
6438
|
}
|
|
@@ -6570,16 +6592,16 @@ function registerPrs(program2) {
|
|
|
6570
6592
|
prsCommand.command("wontfix <comment-id> <reason>").description("Reply with reason and resolve thread").action((commentId, reason) => {
|
|
6571
6593
|
wontfix(Number.parseInt(commentId, 10), reason);
|
|
6572
6594
|
});
|
|
6573
|
-
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((
|
|
6574
|
-
comment(
|
|
6595
|
+
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path50, line, body) => {
|
|
6596
|
+
comment(path50, Number.parseInt(line, 10), body);
|
|
6575
6597
|
});
|
|
6576
6598
|
}
|
|
6577
6599
|
|
|
6578
6600
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6579
|
-
import
|
|
6601
|
+
import chalk78 from "chalk";
|
|
6580
6602
|
|
|
6581
6603
|
// src/shared/createConnectionAuth.ts
|
|
6582
|
-
import
|
|
6604
|
+
import chalk73 from "chalk";
|
|
6583
6605
|
function listConnections(connections, format2) {
|
|
6584
6606
|
if (connections.length === 0) {
|
|
6585
6607
|
console.log("No connections configured.");
|
|
@@ -6592,7 +6614,7 @@ function listConnections(connections, format2) {
|
|
|
6592
6614
|
function removeConnection(connections, name, save) {
|
|
6593
6615
|
const filtered = connections.filter((c) => c.name !== name);
|
|
6594
6616
|
if (filtered.length === connections.length) {
|
|
6595
|
-
console.error(
|
|
6617
|
+
console.error(chalk73.red(`Connection "${name}" not found.`));
|
|
6596
6618
|
process.exit(1);
|
|
6597
6619
|
}
|
|
6598
6620
|
save(filtered);
|
|
@@ -6638,15 +6660,15 @@ function saveConnections(connections) {
|
|
|
6638
6660
|
}
|
|
6639
6661
|
|
|
6640
6662
|
// src/commands/ravendb/promptConnection.ts
|
|
6641
|
-
import
|
|
6663
|
+
import chalk76 from "chalk";
|
|
6642
6664
|
|
|
6643
6665
|
// src/commands/ravendb/selectOpSecret.ts
|
|
6644
|
-
import
|
|
6666
|
+
import chalk75 from "chalk";
|
|
6645
6667
|
import Enquirer2 from "enquirer";
|
|
6646
6668
|
|
|
6647
6669
|
// src/commands/ravendb/searchItems.ts
|
|
6648
6670
|
import { execSync as execSync33 } from "child_process";
|
|
6649
|
-
import
|
|
6671
|
+
import chalk74 from "chalk";
|
|
6650
6672
|
function opExec(args) {
|
|
6651
6673
|
return execSync33(`op ${args}`, {
|
|
6652
6674
|
encoding: "utf-8",
|
|
@@ -6659,7 +6681,7 @@ function searchItems(search) {
|
|
|
6659
6681
|
items = JSON.parse(opExec("item list --format=json"));
|
|
6660
6682
|
} catch {
|
|
6661
6683
|
console.error(
|
|
6662
|
-
|
|
6684
|
+
chalk74.red(
|
|
6663
6685
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
6664
6686
|
)
|
|
6665
6687
|
);
|
|
@@ -6673,7 +6695,7 @@ function getItemFields(itemId) {
|
|
|
6673
6695
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
6674
6696
|
return item.fields.filter((f) => f.reference && f.label);
|
|
6675
6697
|
} catch {
|
|
6676
|
-
console.error(
|
|
6698
|
+
console.error(chalk74.red("Failed to get item details from 1Password."));
|
|
6677
6699
|
process.exit(1);
|
|
6678
6700
|
}
|
|
6679
6701
|
}
|
|
@@ -6692,7 +6714,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6692
6714
|
}).run();
|
|
6693
6715
|
const items = searchItems(search);
|
|
6694
6716
|
if (items.length === 0) {
|
|
6695
|
-
console.error(
|
|
6717
|
+
console.error(chalk75.red(`No items found matching "${search}".`));
|
|
6696
6718
|
process.exit(1);
|
|
6697
6719
|
}
|
|
6698
6720
|
const itemId = await selectOne(
|
|
@@ -6701,7 +6723,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6701
6723
|
);
|
|
6702
6724
|
const fields = getItemFields(itemId);
|
|
6703
6725
|
if (fields.length === 0) {
|
|
6704
|
-
console.error(
|
|
6726
|
+
console.error(chalk75.red("No fields with references found on this item."));
|
|
6705
6727
|
process.exit(1);
|
|
6706
6728
|
}
|
|
6707
6729
|
const ref = await selectOne(
|
|
@@ -6715,7 +6737,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6715
6737
|
async function promptConnection(existingNames) {
|
|
6716
6738
|
const name = await promptInput("name", "Connection name:");
|
|
6717
6739
|
if (existingNames.includes(name)) {
|
|
6718
|
-
console.error(
|
|
6740
|
+
console.error(chalk76.red(`Connection "${name}" already exists.`));
|
|
6719
6741
|
process.exit(1);
|
|
6720
6742
|
}
|
|
6721
6743
|
const url = await promptInput(
|
|
@@ -6724,22 +6746,22 @@ async function promptConnection(existingNames) {
|
|
|
6724
6746
|
);
|
|
6725
6747
|
const database = await promptInput("database", "Database name:");
|
|
6726
6748
|
if (!name || !url || !database) {
|
|
6727
|
-
console.error(
|
|
6749
|
+
console.error(chalk76.red("All fields are required."));
|
|
6728
6750
|
process.exit(1);
|
|
6729
6751
|
}
|
|
6730
6752
|
const apiKeyRef = await selectOpSecret();
|
|
6731
|
-
console.log(
|
|
6753
|
+
console.log(chalk76.dim(`Using: ${apiKeyRef}`));
|
|
6732
6754
|
return { name, url, database, apiKeyRef };
|
|
6733
6755
|
}
|
|
6734
6756
|
|
|
6735
6757
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
6736
|
-
import
|
|
6758
|
+
import chalk77 from "chalk";
|
|
6737
6759
|
function ravendbSetConnection(name) {
|
|
6738
6760
|
const raw = loadGlobalConfigRaw();
|
|
6739
6761
|
const ravendb = raw.ravendb ?? {};
|
|
6740
6762
|
const connections = ravendb.connections ?? [];
|
|
6741
6763
|
if (!connections.some((c) => c.name === name)) {
|
|
6742
|
-
console.error(
|
|
6764
|
+
console.error(chalk77.red(`Connection "${name}" not found.`));
|
|
6743
6765
|
console.error(
|
|
6744
6766
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6745
6767
|
);
|
|
@@ -6755,16 +6777,16 @@ function ravendbSetConnection(name) {
|
|
|
6755
6777
|
var ravendbAuth = createConnectionAuth({
|
|
6756
6778
|
load: loadConnections,
|
|
6757
6779
|
save: saveConnections,
|
|
6758
|
-
format: (c) => `${
|
|
6780
|
+
format: (c) => `${chalk78.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
6759
6781
|
promptNew: promptConnection,
|
|
6760
6782
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
6761
6783
|
});
|
|
6762
6784
|
|
|
6763
6785
|
// src/commands/ravendb/ravendbCollections.ts
|
|
6764
|
-
import
|
|
6786
|
+
import chalk82 from "chalk";
|
|
6765
6787
|
|
|
6766
6788
|
// src/commands/ravendb/ravenFetch.ts
|
|
6767
|
-
import
|
|
6789
|
+
import chalk80 from "chalk";
|
|
6768
6790
|
|
|
6769
6791
|
// src/commands/ravendb/getAccessToken.ts
|
|
6770
6792
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -6801,10 +6823,10 @@ ${errorText}`
|
|
|
6801
6823
|
|
|
6802
6824
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
6803
6825
|
import { execSync as execSync34 } from "child_process";
|
|
6804
|
-
import
|
|
6826
|
+
import chalk79 from "chalk";
|
|
6805
6827
|
function resolveOpSecret(reference) {
|
|
6806
6828
|
if (!reference.startsWith("op://")) {
|
|
6807
|
-
console.error(
|
|
6829
|
+
console.error(chalk79.red(`Invalid secret reference: must start with op://`));
|
|
6808
6830
|
process.exit(1);
|
|
6809
6831
|
}
|
|
6810
6832
|
try {
|
|
@@ -6814,7 +6836,7 @@ function resolveOpSecret(reference) {
|
|
|
6814
6836
|
}).trim();
|
|
6815
6837
|
} catch {
|
|
6816
6838
|
console.error(
|
|
6817
|
-
|
|
6839
|
+
chalk79.red(
|
|
6818
6840
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
6819
6841
|
)
|
|
6820
6842
|
);
|
|
@@ -6823,10 +6845,10 @@ function resolveOpSecret(reference) {
|
|
|
6823
6845
|
}
|
|
6824
6846
|
|
|
6825
6847
|
// src/commands/ravendb/ravenFetch.ts
|
|
6826
|
-
async function ravenFetch(connection,
|
|
6848
|
+
async function ravenFetch(connection, path50) {
|
|
6827
6849
|
const apiKey = resolveOpSecret(connection.apiKeyRef);
|
|
6828
6850
|
let accessToken = await getAccessToken(apiKey);
|
|
6829
|
-
const url = `${connection.url}${
|
|
6851
|
+
const url = `${connection.url}${path50}`;
|
|
6830
6852
|
const headers = {
|
|
6831
6853
|
Authorization: `Bearer ${accessToken}`,
|
|
6832
6854
|
"Content-Type": "application/json"
|
|
@@ -6841,7 +6863,7 @@ async function ravenFetch(connection, path49) {
|
|
|
6841
6863
|
if (!response.ok) {
|
|
6842
6864
|
const body = await response.text();
|
|
6843
6865
|
console.error(
|
|
6844
|
-
|
|
6866
|
+
chalk80.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
6845
6867
|
);
|
|
6846
6868
|
console.error(body.substring(0, 500));
|
|
6847
6869
|
process.exit(1);
|
|
@@ -6850,7 +6872,7 @@ async function ravenFetch(connection, path49) {
|
|
|
6850
6872
|
}
|
|
6851
6873
|
|
|
6852
6874
|
// src/commands/ravendb/resolveConnection.ts
|
|
6853
|
-
import
|
|
6875
|
+
import chalk81 from "chalk";
|
|
6854
6876
|
function loadRavendb() {
|
|
6855
6877
|
const raw = loadGlobalConfigRaw();
|
|
6856
6878
|
const ravendb = raw.ravendb;
|
|
@@ -6864,7 +6886,7 @@ function resolveConnection(name) {
|
|
|
6864
6886
|
const connectionName = name ?? defaultConnection;
|
|
6865
6887
|
if (!connectionName) {
|
|
6866
6888
|
console.error(
|
|
6867
|
-
|
|
6889
|
+
chalk81.red(
|
|
6868
6890
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
6869
6891
|
)
|
|
6870
6892
|
);
|
|
@@ -6872,7 +6894,7 @@ function resolveConnection(name) {
|
|
|
6872
6894
|
}
|
|
6873
6895
|
const connection = connections.find((c) => c.name === connectionName);
|
|
6874
6896
|
if (!connection) {
|
|
6875
|
-
console.error(
|
|
6897
|
+
console.error(chalk81.red(`Connection "${connectionName}" not found.`));
|
|
6876
6898
|
console.error(
|
|
6877
6899
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6878
6900
|
);
|
|
@@ -6903,29 +6925,29 @@ async function ravendbCollections(connectionName) {
|
|
|
6903
6925
|
return;
|
|
6904
6926
|
}
|
|
6905
6927
|
for (const c of collections) {
|
|
6906
|
-
console.log(`${
|
|
6928
|
+
console.log(`${chalk82.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
6907
6929
|
}
|
|
6908
6930
|
}
|
|
6909
6931
|
|
|
6910
6932
|
// src/commands/ravendb/ravendbQuery.ts
|
|
6911
|
-
import
|
|
6933
|
+
import chalk84 from "chalk";
|
|
6912
6934
|
|
|
6913
6935
|
// src/commands/ravendb/fetchAllPages.ts
|
|
6914
|
-
import
|
|
6936
|
+
import chalk83 from "chalk";
|
|
6915
6937
|
|
|
6916
6938
|
// src/commands/ravendb/buildQueryPath.ts
|
|
6917
6939
|
function buildQueryPath(opts) {
|
|
6918
6940
|
const db = encodeURIComponent(opts.db);
|
|
6919
|
-
let
|
|
6941
|
+
let path50;
|
|
6920
6942
|
if (opts.collection) {
|
|
6921
|
-
|
|
6943
|
+
path50 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
|
|
6922
6944
|
} else {
|
|
6923
|
-
|
|
6945
|
+
path50 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
|
|
6924
6946
|
}
|
|
6925
6947
|
if (opts.query) {
|
|
6926
|
-
|
|
6948
|
+
path50 += `&query=${encodeURIComponent(opts.query)}`;
|
|
6927
6949
|
}
|
|
6928
|
-
return
|
|
6950
|
+
return path50;
|
|
6929
6951
|
}
|
|
6930
6952
|
|
|
6931
6953
|
// src/commands/ravendb/fetchAllPages.ts
|
|
@@ -6934,7 +6956,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
6934
6956
|
let start3 = 0;
|
|
6935
6957
|
while (true) {
|
|
6936
6958
|
const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
|
|
6937
|
-
const
|
|
6959
|
+
const path50 = buildQueryPath({
|
|
6938
6960
|
db: connection.database,
|
|
6939
6961
|
collection: opts.collection,
|
|
6940
6962
|
start: start3,
|
|
@@ -6942,14 +6964,14 @@ async function fetchAllPages(connection, opts) {
|
|
|
6942
6964
|
sort: opts.sort,
|
|
6943
6965
|
query: opts.query
|
|
6944
6966
|
});
|
|
6945
|
-
const data = await ravenFetch(connection,
|
|
6967
|
+
const data = await ravenFetch(connection, path50);
|
|
6946
6968
|
const results = data.Results ?? [];
|
|
6947
6969
|
const totalResults = data.TotalResults ?? 0;
|
|
6948
6970
|
if (results.length === 0) break;
|
|
6949
6971
|
allResults.push(...results);
|
|
6950
6972
|
start3 += results.length;
|
|
6951
6973
|
process.stderr.write(
|
|
6952
|
-
`\r${
|
|
6974
|
+
`\r${chalk83.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
6953
6975
|
);
|
|
6954
6976
|
if (start3 >= totalResults) break;
|
|
6955
6977
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -6964,7 +6986,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
6964
6986
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
6965
6987
|
const resolved = resolveArgs(connectionName, collection);
|
|
6966
6988
|
if (!resolved.collection && !options2.query) {
|
|
6967
|
-
console.error(
|
|
6989
|
+
console.error(chalk84.red("Provide a collection name or --query filter."));
|
|
6968
6990
|
process.exit(1);
|
|
6969
6991
|
}
|
|
6970
6992
|
const { collection: col } = resolved;
|
|
@@ -7002,7 +7024,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7002
7024
|
import * as path27 from "path";
|
|
7003
7025
|
|
|
7004
7026
|
// src/commands/refactor/logViolations.ts
|
|
7005
|
-
import
|
|
7027
|
+
import chalk85 from "chalk";
|
|
7006
7028
|
var DEFAULT_MAX_LINES = 100;
|
|
7007
7029
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7008
7030
|
if (violations.length === 0) {
|
|
@@ -7011,43 +7033,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7011
7033
|
}
|
|
7012
7034
|
return;
|
|
7013
7035
|
}
|
|
7014
|
-
console.error(
|
|
7036
|
+
console.error(chalk85.red(`
|
|
7015
7037
|
Refactor check failed:
|
|
7016
7038
|
`));
|
|
7017
|
-
console.error(
|
|
7039
|
+
console.error(chalk85.red(` The following files exceed ${maxLines} lines:
|
|
7018
7040
|
`));
|
|
7019
7041
|
for (const violation of violations) {
|
|
7020
|
-
console.error(
|
|
7042
|
+
console.error(chalk85.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7021
7043
|
}
|
|
7022
7044
|
console.error(
|
|
7023
|
-
|
|
7045
|
+
chalk85.yellow(
|
|
7024
7046
|
`
|
|
7025
7047
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7026
7048
|
way to refactor it, ignore it with:
|
|
7027
7049
|
`
|
|
7028
7050
|
)
|
|
7029
7051
|
);
|
|
7030
|
-
console.error(
|
|
7052
|
+
console.error(chalk85.gray(` assist refactor ignore <file>
|
|
7031
7053
|
`));
|
|
7032
7054
|
if (process.env.CLAUDECODE) {
|
|
7033
|
-
console.error(
|
|
7055
|
+
console.error(chalk85.cyan(`
|
|
7034
7056
|
## Extracting Code to New Files
|
|
7035
7057
|
`));
|
|
7036
7058
|
console.error(
|
|
7037
|
-
|
|
7059
|
+
chalk85.cyan(
|
|
7038
7060
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7039
7061
|
`
|
|
7040
7062
|
)
|
|
7041
7063
|
);
|
|
7042
7064
|
console.error(
|
|
7043
|
-
|
|
7065
|
+
chalk85.cyan(
|
|
7044
7066
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7045
7067
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7046
7068
|
`
|
|
7047
7069
|
)
|
|
7048
7070
|
);
|
|
7049
7071
|
console.error(
|
|
7050
|
-
|
|
7072
|
+
chalk85.cyan(
|
|
7051
7073
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7052
7074
|
domains, move it to a common/shared folder.
|
|
7053
7075
|
`
|
|
@@ -7202,8 +7224,8 @@ async function check(pattern2, options2) {
|
|
|
7202
7224
|
}
|
|
7203
7225
|
|
|
7204
7226
|
// src/commands/refactor/extract/index.ts
|
|
7205
|
-
import
|
|
7206
|
-
import
|
|
7227
|
+
import path33 from "path";
|
|
7228
|
+
import chalk88 from "chalk";
|
|
7207
7229
|
|
|
7208
7230
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7209
7231
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -7651,6 +7673,21 @@ function resolveBarrel(functionName, sourcePath, destPath, project) {
|
|
|
7651
7673
|
};
|
|
7652
7674
|
}
|
|
7653
7675
|
|
|
7676
|
+
// src/commands/refactor/extract/rewriteImportPaths.ts
|
|
7677
|
+
import path30 from "path";
|
|
7678
|
+
function rewriteImportPaths(imports, sourcePath, destPath) {
|
|
7679
|
+
const sourceDir = path30.dirname(sourcePath);
|
|
7680
|
+
const destDir = path30.dirname(destPath);
|
|
7681
|
+
return imports.map((imp) => {
|
|
7682
|
+
if (!imp.moduleSpecifier.startsWith(".")) return imp;
|
|
7683
|
+
const absolute = path30.resolve(sourceDir, imp.moduleSpecifier);
|
|
7684
|
+
let rel = path30.relative(destDir, absolute).replace(/\\/g, "/");
|
|
7685
|
+
if (rel === "") rel = `../${path30.basename(absolute)}`;
|
|
7686
|
+
else if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
7687
|
+
return { ...imp, moduleSpecifier: rel };
|
|
7688
|
+
});
|
|
7689
|
+
}
|
|
7690
|
+
|
|
7654
7691
|
// src/commands/refactor/extract/sourceReferencesName.ts
|
|
7655
7692
|
import { SyntaxKind as SyntaxKind10 } from "ts-morph";
|
|
7656
7693
|
var DECLARATION_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -7686,12 +7723,17 @@ function sourceReferencesName(sourceFile, functionName, extractedNames) {
|
|
|
7686
7723
|
function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
7687
7724
|
const analysis = analyseTarget(sourceFile, functionName);
|
|
7688
7725
|
const sourceRelPath = getRelativeImportPath(destPath, sourcePath);
|
|
7726
|
+
const rewrittenImports = rewriteImportPaths(
|
|
7727
|
+
analysis.imports,
|
|
7728
|
+
sourcePath,
|
|
7729
|
+
destPath
|
|
7730
|
+
);
|
|
7689
7731
|
const { functionTexts: _, ...planFields } = analysis;
|
|
7690
7732
|
return {
|
|
7691
7733
|
...planFields,
|
|
7692
7734
|
destContent: buildDestinationContent(
|
|
7693
7735
|
analysis.functionTexts,
|
|
7694
|
-
|
|
7736
|
+
rewrittenImports,
|
|
7695
7737
|
sourceRelPath,
|
|
7696
7738
|
analysis.exportedDeps
|
|
7697
7739
|
),
|
|
@@ -7708,24 +7750,24 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
7708
7750
|
}
|
|
7709
7751
|
|
|
7710
7752
|
// src/commands/refactor/extract/displayPlan.ts
|
|
7711
|
-
import
|
|
7712
|
-
import
|
|
7753
|
+
import path31 from "path";
|
|
7754
|
+
import chalk86 from "chalk";
|
|
7713
7755
|
function section(title) {
|
|
7714
7756
|
return `
|
|
7715
|
-
${
|
|
7757
|
+
${chalk86.cyan(title)}`;
|
|
7716
7758
|
}
|
|
7717
7759
|
function displayImporters(plan2, cwd) {
|
|
7718
7760
|
if (plan2.importersToUpdate.length === 0) return;
|
|
7719
7761
|
console.log(section("Update importers:"));
|
|
7720
7762
|
for (const imp of plan2.importersToUpdate) {
|
|
7721
|
-
const rel =
|
|
7722
|
-
console.log(` ${
|
|
7763
|
+
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
7764
|
+
console.log(` ${chalk86.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
7723
7765
|
}
|
|
7724
7766
|
}
|
|
7725
7767
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
7726
|
-
console.log(
|
|
7768
|
+
console.log(chalk86.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
7727
7769
|
`));
|
|
7728
|
-
console.log(` ${
|
|
7770
|
+
console.log(` ${chalk86.cyan("Functions to move:")}`);
|
|
7729
7771
|
for (const name of plan2.extractedNames) {
|
|
7730
7772
|
console.log(` ${name}`);
|
|
7731
7773
|
}
|
|
@@ -7759,11 +7801,11 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
7759
7801
|
|
|
7760
7802
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
7761
7803
|
import fs17 from "fs";
|
|
7762
|
-
import
|
|
7763
|
-
import
|
|
7804
|
+
import path32 from "path";
|
|
7805
|
+
import chalk87 from "chalk";
|
|
7764
7806
|
import { Project as Project2 } from "ts-morph";
|
|
7765
7807
|
function findTsConfig(sourcePath) {
|
|
7766
|
-
const rootConfig =
|
|
7808
|
+
const rootConfig = path32.resolve("tsconfig.json");
|
|
7767
7809
|
if (!fs17.existsSync(rootConfig)) return rootConfig;
|
|
7768
7810
|
const raw = fs17.readFileSync(rootConfig, "utf-8");
|
|
7769
7811
|
const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
@@ -7775,8 +7817,8 @@ function findTsConfig(sourcePath) {
|
|
|
7775
7817
|
}
|
|
7776
7818
|
if (!parsed.references?.length) return rootConfig;
|
|
7777
7819
|
for (const ref of parsed.references) {
|
|
7778
|
-
const refPath =
|
|
7779
|
-
const configPath = fs17.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ?
|
|
7820
|
+
const refPath = path32.resolve(ref.path);
|
|
7821
|
+
const configPath = fs17.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path32.join(refPath, "tsconfig.json") : refPath;
|
|
7780
7822
|
if (!fs17.existsSync(configPath)) continue;
|
|
7781
7823
|
const project = new Project2({ tsConfigFilePath: configPath });
|
|
7782
7824
|
if (project.getSourceFile(sourcePath)) return configPath;
|
|
@@ -7784,14 +7826,14 @@ function findTsConfig(sourcePath) {
|
|
|
7784
7826
|
return rootConfig;
|
|
7785
7827
|
}
|
|
7786
7828
|
function loadProjectFile(file) {
|
|
7787
|
-
const sourcePath =
|
|
7829
|
+
const sourcePath = path32.resolve(file);
|
|
7788
7830
|
const tsConfigPath = findTsConfig(sourcePath);
|
|
7789
7831
|
const project = new Project2({
|
|
7790
7832
|
tsConfigFilePath: tsConfigPath
|
|
7791
7833
|
});
|
|
7792
7834
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
7793
7835
|
if (!sourceFile) {
|
|
7794
|
-
console.log(
|
|
7836
|
+
console.log(chalk87.red(`File not found in project: ${file}`));
|
|
7795
7837
|
process.exit(1);
|
|
7796
7838
|
}
|
|
7797
7839
|
return { project, sourceFile };
|
|
@@ -7799,10 +7841,10 @@ function loadProjectFile(file) {
|
|
|
7799
7841
|
|
|
7800
7842
|
// src/commands/refactor/extract/index.ts
|
|
7801
7843
|
async function extract(file, functionName, destination, options2 = {}) {
|
|
7802
|
-
const sourcePath =
|
|
7803
|
-
const destPath =
|
|
7844
|
+
const sourcePath = path33.resolve(file);
|
|
7845
|
+
const destPath = path33.resolve(destination);
|
|
7804
7846
|
const cwd = process.cwd();
|
|
7805
|
-
const relDest =
|
|
7847
|
+
const relDest = path33.relative(cwd, destPath);
|
|
7806
7848
|
const { project, sourceFile } = loadProjectFile(file);
|
|
7807
7849
|
const plan2 = buildPlan(
|
|
7808
7850
|
functionName,
|
|
@@ -7814,19 +7856,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
7814
7856
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
7815
7857
|
if (options2.apply) {
|
|
7816
7858
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
7817
|
-
console.log(
|
|
7859
|
+
console.log(chalk88.green("\nExtraction complete"));
|
|
7818
7860
|
} else {
|
|
7819
|
-
console.log(
|
|
7861
|
+
console.log(chalk88.dim("\nDry run. Use --apply to execute."));
|
|
7820
7862
|
}
|
|
7821
7863
|
}
|
|
7822
7864
|
|
|
7823
7865
|
// src/commands/refactor/ignore.ts
|
|
7824
7866
|
import fs18 from "fs";
|
|
7825
|
-
import
|
|
7867
|
+
import chalk89 from "chalk";
|
|
7826
7868
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
7827
7869
|
function ignore(file) {
|
|
7828
7870
|
if (!fs18.existsSync(file)) {
|
|
7829
|
-
console.error(
|
|
7871
|
+
console.error(chalk89.red(`Error: File does not exist: ${file}`));
|
|
7830
7872
|
process.exit(1);
|
|
7831
7873
|
}
|
|
7832
7874
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -7842,34 +7884,34 @@ function ignore(file) {
|
|
|
7842
7884
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
7843
7885
|
}
|
|
7844
7886
|
console.log(
|
|
7845
|
-
|
|
7887
|
+
chalk89.green(
|
|
7846
7888
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
7847
7889
|
)
|
|
7848
7890
|
);
|
|
7849
7891
|
}
|
|
7850
7892
|
|
|
7851
7893
|
// src/commands/refactor/rename/index.ts
|
|
7852
|
-
import
|
|
7853
|
-
import
|
|
7894
|
+
import path34 from "path";
|
|
7895
|
+
import chalk90 from "chalk";
|
|
7854
7896
|
async function rename(source, destination, options2 = {}) {
|
|
7855
|
-
const destPath =
|
|
7897
|
+
const destPath = path34.resolve(destination);
|
|
7856
7898
|
const cwd = process.cwd();
|
|
7857
|
-
const relSource =
|
|
7858
|
-
const relDest =
|
|
7899
|
+
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
7900
|
+
const relDest = path34.relative(cwd, destPath);
|
|
7859
7901
|
const { project, sourceFile } = loadProjectFile(source);
|
|
7860
|
-
console.log(
|
|
7902
|
+
console.log(chalk90.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
7861
7903
|
if (options2.apply) {
|
|
7862
7904
|
sourceFile.move(destPath);
|
|
7863
7905
|
await project.save();
|
|
7864
|
-
console.log(
|
|
7906
|
+
console.log(chalk90.green("Done"));
|
|
7865
7907
|
} else {
|
|
7866
|
-
console.log(
|
|
7908
|
+
console.log(chalk90.dim("Dry run. Use --apply to execute."));
|
|
7867
7909
|
}
|
|
7868
7910
|
}
|
|
7869
7911
|
|
|
7870
7912
|
// src/commands/refactor/renameSymbol/index.ts
|
|
7871
|
-
import
|
|
7872
|
-
import
|
|
7913
|
+
import path36 from "path";
|
|
7914
|
+
import chalk91 from "chalk";
|
|
7873
7915
|
import { Project as Project3 } from "ts-morph";
|
|
7874
7916
|
|
|
7875
7917
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -7897,12 +7939,12 @@ function findSymbol(sourceFile, symbolName) {
|
|
|
7897
7939
|
}
|
|
7898
7940
|
|
|
7899
7941
|
// src/commands/refactor/renameSymbol/groupReferences.ts
|
|
7900
|
-
import
|
|
7942
|
+
import path35 from "path";
|
|
7901
7943
|
function groupReferences(symbol, cwd) {
|
|
7902
7944
|
const refs = symbol.findReferencesAsNodes();
|
|
7903
7945
|
const grouped = /* @__PURE__ */ new Map();
|
|
7904
7946
|
for (const ref of refs) {
|
|
7905
|
-
const refFile =
|
|
7947
|
+
const refFile = path35.relative(cwd, ref.getSourceFile().getFilePath());
|
|
7906
7948
|
const lines = grouped.get(refFile) ?? [];
|
|
7907
7949
|
if (!grouped.has(refFile)) grouped.set(refFile, lines);
|
|
7908
7950
|
lines.push(ref.getStartLineNumber());
|
|
@@ -7912,47 +7954,47 @@ function groupReferences(symbol, cwd) {
|
|
|
7912
7954
|
|
|
7913
7955
|
// src/commands/refactor/renameSymbol/index.ts
|
|
7914
7956
|
async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
7915
|
-
const filePath =
|
|
7916
|
-
const tsConfigPath =
|
|
7957
|
+
const filePath = path36.resolve(file);
|
|
7958
|
+
const tsConfigPath = path36.resolve("tsconfig.json");
|
|
7917
7959
|
const cwd = process.cwd();
|
|
7918
7960
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
7919
7961
|
const sourceFile = project.getSourceFile(filePath);
|
|
7920
7962
|
if (!sourceFile) {
|
|
7921
|
-
console.log(
|
|
7963
|
+
console.log(chalk91.red(`File not found in project: ${file}`));
|
|
7922
7964
|
process.exit(1);
|
|
7923
7965
|
}
|
|
7924
7966
|
const symbol = findSymbol(sourceFile, oldName);
|
|
7925
7967
|
if (!symbol) {
|
|
7926
|
-
console.log(
|
|
7968
|
+
console.log(chalk91.red(`Symbol "${oldName}" not found in ${file}`));
|
|
7927
7969
|
process.exit(1);
|
|
7928
7970
|
}
|
|
7929
7971
|
const grouped = groupReferences(symbol, cwd);
|
|
7930
7972
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
7931
7973
|
console.log(
|
|
7932
|
-
|
|
7974
|
+
chalk91.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
7933
7975
|
`)
|
|
7934
7976
|
);
|
|
7935
7977
|
for (const [refFile, lines] of grouped) {
|
|
7936
7978
|
console.log(
|
|
7937
|
-
` ${
|
|
7979
|
+
` ${chalk91.dim(refFile)}: lines ${chalk91.cyan(lines.join(", "))}`
|
|
7938
7980
|
);
|
|
7939
7981
|
}
|
|
7940
7982
|
if (options2.apply) {
|
|
7941
7983
|
symbol.rename(newName);
|
|
7942
7984
|
await project.save();
|
|
7943
|
-
console.log(
|
|
7985
|
+
console.log(chalk91.green(`
|
|
7944
7986
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
7945
7987
|
} else {
|
|
7946
|
-
console.log(
|
|
7988
|
+
console.log(chalk91.dim("\nDry run. Use --apply to execute."));
|
|
7947
7989
|
}
|
|
7948
7990
|
}
|
|
7949
7991
|
|
|
7950
7992
|
// src/commands/refactor/restructure/index.ts
|
|
7951
|
-
import
|
|
7952
|
-
import
|
|
7993
|
+
import path45 from "path";
|
|
7994
|
+
import chalk94 from "chalk";
|
|
7953
7995
|
|
|
7954
7996
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
7955
|
-
import
|
|
7997
|
+
import path37 from "path";
|
|
7956
7998
|
import ts7 from "typescript";
|
|
7957
7999
|
|
|
7958
8000
|
// src/commands/refactor/restructure/buildImportGraph/getImportSpecifiers.ts
|
|
@@ -7979,7 +8021,7 @@ function loadParsedConfig(tsConfigPath) {
|
|
|
7979
8021
|
return ts7.parseJsonConfigFileContent(
|
|
7980
8022
|
configFile.config,
|
|
7981
8023
|
ts7.sys,
|
|
7982
|
-
|
|
8024
|
+
path37.dirname(tsConfigPath)
|
|
7983
8025
|
);
|
|
7984
8026
|
}
|
|
7985
8027
|
function addToSetMap(map, key, value) {
|
|
@@ -7995,7 +8037,7 @@ function resolveImport(specifier, filePath, options2) {
|
|
|
7995
8037
|
const resolved = ts7.resolveModuleName(specifier, filePath, options2, ts7.sys);
|
|
7996
8038
|
const resolvedPath = resolved.resolvedModule?.resolvedFileName;
|
|
7997
8039
|
if (!resolvedPath || resolvedPath.includes("node_modules")) return null;
|
|
7998
|
-
return
|
|
8040
|
+
return path37.resolve(resolvedPath);
|
|
7999
8041
|
}
|
|
8000
8042
|
function buildImportGraph(candidateFiles, tsConfigPath) {
|
|
8001
8043
|
const parsed = loadParsedConfig(tsConfigPath);
|
|
@@ -8004,7 +8046,7 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
|
|
|
8004
8046
|
const importedBy = /* @__PURE__ */ new Map();
|
|
8005
8047
|
const imports = /* @__PURE__ */ new Map();
|
|
8006
8048
|
for (const sourceFile of program2.getSourceFiles()) {
|
|
8007
|
-
const filePath =
|
|
8049
|
+
const filePath = path37.resolve(sourceFile.fileName);
|
|
8008
8050
|
if (filePath.includes("node_modules")) continue;
|
|
8009
8051
|
for (const specifier of getImportSpecifiers(sourceFile)) {
|
|
8010
8052
|
const absTarget = resolveImport(specifier, filePath, parsed.options);
|
|
@@ -8018,12 +8060,12 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
|
|
|
8018
8060
|
}
|
|
8019
8061
|
|
|
8020
8062
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
8021
|
-
import
|
|
8063
|
+
import path38 from "path";
|
|
8022
8064
|
function clusterDirectories(graph) {
|
|
8023
8065
|
const dirImportedBy = /* @__PURE__ */ new Map();
|
|
8024
8066
|
for (const edge of graph.edges) {
|
|
8025
|
-
const sourceDir =
|
|
8026
|
-
const targetDir =
|
|
8067
|
+
const sourceDir = path38.dirname(edge.source);
|
|
8068
|
+
const targetDir = path38.dirname(edge.target);
|
|
8027
8069
|
if (sourceDir === targetDir) continue;
|
|
8028
8070
|
if (!graph.files.has(edge.target)) continue;
|
|
8029
8071
|
const existing = dirImportedBy.get(targetDir) ?? /* @__PURE__ */ new Set();
|
|
@@ -8051,20 +8093,20 @@ function clusterDirectories(graph) {
|
|
|
8051
8093
|
return clusters;
|
|
8052
8094
|
}
|
|
8053
8095
|
function isAncestor(ancestor, descendant) {
|
|
8054
|
-
const rel =
|
|
8096
|
+
const rel = path38.relative(ancestor, descendant);
|
|
8055
8097
|
return !rel.startsWith("..") && rel !== "";
|
|
8056
8098
|
}
|
|
8057
8099
|
|
|
8058
8100
|
// src/commands/refactor/restructure/clusterFiles.ts
|
|
8059
|
-
import
|
|
8101
|
+
import path39 from "path";
|
|
8060
8102
|
function findRootParent(file, importedBy, visited) {
|
|
8061
8103
|
const importers = importedBy.get(file);
|
|
8062
8104
|
if (!importers || importers.size !== 1) return file;
|
|
8063
8105
|
const parent = [...importers][0];
|
|
8064
|
-
const parentDir =
|
|
8065
|
-
const fileDir =
|
|
8106
|
+
const parentDir = path39.dirname(parent);
|
|
8107
|
+
const fileDir = path39.dirname(file);
|
|
8066
8108
|
if (parentDir !== fileDir) return file;
|
|
8067
|
-
if (
|
|
8109
|
+
if (path39.basename(parent, path39.extname(parent)) === "index") return file;
|
|
8068
8110
|
if (visited.has(parent)) return file;
|
|
8069
8111
|
visited.add(parent);
|
|
8070
8112
|
return findRootParent(parent, importedBy, visited);
|
|
@@ -8072,16 +8114,16 @@ function findRootParent(file, importedBy, visited) {
|
|
|
8072
8114
|
function clusterFiles(graph) {
|
|
8073
8115
|
const clusters = /* @__PURE__ */ new Map();
|
|
8074
8116
|
for (const file of graph.files) {
|
|
8075
|
-
const basename7 =
|
|
8117
|
+
const basename7 = path39.basename(file, path39.extname(file));
|
|
8076
8118
|
if (basename7 === "index") continue;
|
|
8077
8119
|
const importers = graph.importedBy.get(file);
|
|
8078
8120
|
if (!importers || importers.size !== 1) continue;
|
|
8079
8121
|
const parent = [...importers][0];
|
|
8080
8122
|
if (!graph.files.has(parent)) continue;
|
|
8081
|
-
const parentDir =
|
|
8082
|
-
const fileDir =
|
|
8123
|
+
const parentDir = path39.dirname(parent);
|
|
8124
|
+
const fileDir = path39.dirname(file);
|
|
8083
8125
|
if (parentDir !== fileDir) continue;
|
|
8084
|
-
const parentBasename =
|
|
8126
|
+
const parentBasename = path39.basename(parent, path39.extname(parent));
|
|
8085
8127
|
if (parentBasename === "index") continue;
|
|
8086
8128
|
const root = findRootParent(parent, graph.importedBy, /* @__PURE__ */ new Set([file]));
|
|
8087
8129
|
if (!root || root === file) continue;
|
|
@@ -8093,7 +8135,7 @@ function clusterFiles(graph) {
|
|
|
8093
8135
|
}
|
|
8094
8136
|
|
|
8095
8137
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
8096
|
-
import
|
|
8138
|
+
import path40 from "path";
|
|
8097
8139
|
|
|
8098
8140
|
// src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
|
|
8099
8141
|
import fs19 from "fs";
|
|
@@ -8147,7 +8189,7 @@ function normalizeSpecifier(rel) {
|
|
|
8147
8189
|
);
|
|
8148
8190
|
}
|
|
8149
8191
|
function computeSpecifier(fromFile, toFile) {
|
|
8150
|
-
return normalizeSpecifier(
|
|
8192
|
+
return normalizeSpecifier(path40.relative(path40.dirname(fromFile), toFile));
|
|
8151
8193
|
}
|
|
8152
8194
|
function isAffected(edge, moveMap) {
|
|
8153
8195
|
return moveMap.has(edge.target) || moveMap.has(edge.source);
|
|
@@ -8191,51 +8233,51 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8191
8233
|
}
|
|
8192
8234
|
|
|
8193
8235
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8194
|
-
import
|
|
8195
|
-
import
|
|
8236
|
+
import path41 from "path";
|
|
8237
|
+
import chalk92 from "chalk";
|
|
8196
8238
|
function relPath(filePath) {
|
|
8197
|
-
return
|
|
8239
|
+
return path41.relative(process.cwd(), filePath);
|
|
8198
8240
|
}
|
|
8199
8241
|
function displayMoves(plan2) {
|
|
8200
8242
|
if (plan2.moves.length === 0) return;
|
|
8201
|
-
console.log(
|
|
8243
|
+
console.log(chalk92.bold("\nFile moves:"));
|
|
8202
8244
|
for (const move of plan2.moves) {
|
|
8203
8245
|
console.log(
|
|
8204
|
-
` ${
|
|
8246
|
+
` ${chalk92.red(relPath(move.from))} \u2192 ${chalk92.green(relPath(move.to))}`
|
|
8205
8247
|
);
|
|
8206
|
-
console.log(
|
|
8248
|
+
console.log(chalk92.dim(` ${move.reason}`));
|
|
8207
8249
|
}
|
|
8208
8250
|
}
|
|
8209
8251
|
function displayRewrites(rewrites) {
|
|
8210
8252
|
if (rewrites.length === 0) return;
|
|
8211
8253
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8212
|
-
console.log(
|
|
8254
|
+
console.log(chalk92.bold(`
|
|
8213
8255
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8214
8256
|
for (const file of affectedFiles) {
|
|
8215
|
-
console.log(` ${
|
|
8257
|
+
console.log(` ${chalk92.cyan(relPath(file))}:`);
|
|
8216
8258
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8217
8259
|
(r) => r.file === file
|
|
8218
8260
|
)) {
|
|
8219
8261
|
console.log(
|
|
8220
|
-
` ${
|
|
8262
|
+
` ${chalk92.red(`"${oldSpecifier}"`)} \u2192 ${chalk92.green(`"${newSpecifier}"`)}`
|
|
8221
8263
|
);
|
|
8222
8264
|
}
|
|
8223
8265
|
}
|
|
8224
8266
|
}
|
|
8225
8267
|
function displayPlan2(plan2) {
|
|
8226
8268
|
if (plan2.warnings.length > 0) {
|
|
8227
|
-
console.log(
|
|
8228
|
-
for (const w of plan2.warnings) console.log(
|
|
8269
|
+
console.log(chalk92.yellow("\nWarnings:"));
|
|
8270
|
+
for (const w of plan2.warnings) console.log(chalk92.yellow(` ${w}`));
|
|
8229
8271
|
}
|
|
8230
8272
|
if (plan2.newDirectories.length > 0) {
|
|
8231
|
-
console.log(
|
|
8273
|
+
console.log(chalk92.bold("\nNew directories:"));
|
|
8232
8274
|
for (const dir of plan2.newDirectories)
|
|
8233
|
-
console.log(
|
|
8275
|
+
console.log(chalk92.green(` ${dir}/`));
|
|
8234
8276
|
}
|
|
8235
8277
|
displayMoves(plan2);
|
|
8236
8278
|
displayRewrites(plan2.rewrites);
|
|
8237
8279
|
console.log(
|
|
8238
|
-
|
|
8280
|
+
chalk92.dim(
|
|
8239
8281
|
`
|
|
8240
8282
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8241
8283
|
)
|
|
@@ -8244,33 +8286,33 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8244
8286
|
|
|
8245
8287
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8246
8288
|
import fs20 from "fs";
|
|
8247
|
-
import
|
|
8248
|
-
import
|
|
8289
|
+
import path42 from "path";
|
|
8290
|
+
import chalk93 from "chalk";
|
|
8249
8291
|
function executePlan(plan2) {
|
|
8250
8292
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8251
8293
|
for (const [file, content] of updatedContents) {
|
|
8252
8294
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8253
8295
|
console.log(
|
|
8254
|
-
|
|
8296
|
+
chalk93.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8255
8297
|
);
|
|
8256
8298
|
}
|
|
8257
8299
|
for (const dir of plan2.newDirectories) {
|
|
8258
8300
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8259
|
-
console.log(
|
|
8301
|
+
console.log(chalk93.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8260
8302
|
}
|
|
8261
8303
|
for (const move of plan2.moves) {
|
|
8262
|
-
const targetDir =
|
|
8304
|
+
const targetDir = path42.dirname(move.to);
|
|
8263
8305
|
if (!fs20.existsSync(targetDir)) {
|
|
8264
8306
|
fs20.mkdirSync(targetDir, { recursive: true });
|
|
8265
8307
|
}
|
|
8266
8308
|
fs20.renameSync(move.from, move.to);
|
|
8267
8309
|
console.log(
|
|
8268
|
-
|
|
8269
|
-
` Moved ${
|
|
8310
|
+
chalk93.white(
|
|
8311
|
+
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8270
8312
|
)
|
|
8271
8313
|
);
|
|
8272
8314
|
}
|
|
8273
|
-
removeEmptyDirectories(plan2.moves.map((m) =>
|
|
8315
|
+
removeEmptyDirectories(plan2.moves.map((m) => path42.dirname(m.from)));
|
|
8274
8316
|
}
|
|
8275
8317
|
function removeEmptyDirectories(dirs) {
|
|
8276
8318
|
const unique = [...new Set(dirs)];
|
|
@@ -8280,8 +8322,8 @@ function removeEmptyDirectories(dirs) {
|
|
|
8280
8322
|
if (entries.length === 0) {
|
|
8281
8323
|
fs20.rmdirSync(dir);
|
|
8282
8324
|
console.log(
|
|
8283
|
-
|
|
8284
|
-
` Removed empty directory ${
|
|
8325
|
+
chalk93.dim(
|
|
8326
|
+
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8285
8327
|
)
|
|
8286
8328
|
);
|
|
8287
8329
|
}
|
|
@@ -8289,7 +8331,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8289
8331
|
}
|
|
8290
8332
|
|
|
8291
8333
|
// src/commands/refactor/restructure/planFileMoves/index.ts
|
|
8292
|
-
import
|
|
8334
|
+
import path44 from "path";
|
|
8293
8335
|
|
|
8294
8336
|
// src/commands/refactor/restructure/planFileMoves/shared.ts
|
|
8295
8337
|
import fs21 from "fs";
|
|
@@ -8304,9 +8346,9 @@ function checkDirConflict(result, label2, dir) {
|
|
|
8304
8346
|
|
|
8305
8347
|
// src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
|
|
8306
8348
|
import fs22 from "fs";
|
|
8307
|
-
import
|
|
8349
|
+
import path43 from "path";
|
|
8308
8350
|
function collectEntry(results, dir, entry) {
|
|
8309
|
-
const full =
|
|
8351
|
+
const full = path43.join(dir, entry.name);
|
|
8310
8352
|
const items = entry.isDirectory() ? listFilesRecursive(full) : [full];
|
|
8311
8353
|
results.push(...items);
|
|
8312
8354
|
}
|
|
@@ -8320,15 +8362,15 @@ function listFilesRecursive(dir) {
|
|
|
8320
8362
|
}
|
|
8321
8363
|
function addDirectoryFileMoves(moves, childDir, newLocation, reason) {
|
|
8322
8364
|
for (const file of listFilesRecursive(childDir)) {
|
|
8323
|
-
const rel =
|
|
8324
|
-
moves.push({ from: file, to:
|
|
8365
|
+
const rel = path43.relative(childDir, file);
|
|
8366
|
+
moves.push({ from: file, to: path43.join(newLocation, rel), reason });
|
|
8325
8367
|
}
|
|
8326
8368
|
}
|
|
8327
8369
|
function resolveChildDest(parentDir, childDir) {
|
|
8328
|
-
return
|
|
8370
|
+
return path43.join(parentDir, path43.basename(childDir));
|
|
8329
8371
|
}
|
|
8330
8372
|
function childMoveReason(parentDir) {
|
|
8331
|
-
return `Directory only imported from ${
|
|
8373
|
+
return `Directory only imported from ${path43.basename(parentDir)}/`;
|
|
8332
8374
|
}
|
|
8333
8375
|
function registerDirectoryMove(result, childDir, dest, parentDir) {
|
|
8334
8376
|
result.directories.push(dest);
|
|
@@ -8353,7 +8395,7 @@ function planDirectoryMoves(clusters) {
|
|
|
8353
8395
|
|
|
8354
8396
|
// src/commands/refactor/restructure/planFileMoves/index.ts
|
|
8355
8397
|
function childMoveData(child, newDir, parentBase) {
|
|
8356
|
-
const to =
|
|
8398
|
+
const to = path44.join(newDir, path44.basename(child));
|
|
8357
8399
|
return { from: child, to, reason: `Only imported by ${parentBase}` };
|
|
8358
8400
|
}
|
|
8359
8401
|
function addChildMoves(moves, children, newDir, parentBase) {
|
|
@@ -8361,15 +8403,15 @@ function addChildMoves(moves, children, newDir, parentBase) {
|
|
|
8361
8403
|
moves.push(childMoveData(child, newDir, parentBase));
|
|
8362
8404
|
}
|
|
8363
8405
|
function getBaseName(filePath) {
|
|
8364
|
-
return
|
|
8406
|
+
return path44.basename(filePath, path44.extname(filePath));
|
|
8365
8407
|
}
|
|
8366
8408
|
function resolveClusterDir(parent) {
|
|
8367
|
-
return
|
|
8409
|
+
return path44.join(path44.dirname(parent), getBaseName(parent));
|
|
8368
8410
|
}
|
|
8369
8411
|
function createParentMove(parent, newDir) {
|
|
8370
8412
|
return {
|
|
8371
8413
|
from: parent,
|
|
8372
|
-
to:
|
|
8414
|
+
to: path44.join(newDir, `index${path44.extname(parent)}`),
|
|
8373
8415
|
reason: `Main module of new ${getBaseName(parent)}/ directory`
|
|
8374
8416
|
};
|
|
8375
8417
|
}
|
|
@@ -8393,7 +8435,7 @@ function planFileMoves(clusters) {
|
|
|
8393
8435
|
|
|
8394
8436
|
// src/commands/refactor/restructure/index.ts
|
|
8395
8437
|
function buildPlan2(candidateFiles, tsConfigPath) {
|
|
8396
|
-
const candidates = new Set(candidateFiles.map((f) =>
|
|
8438
|
+
const candidates = new Set(candidateFiles.map((f) => path45.resolve(f)));
|
|
8397
8439
|
const graph = buildImportGraph(candidates, tsConfigPath);
|
|
8398
8440
|
const allProjectFiles = /* @__PURE__ */ new Set([
|
|
8399
8441
|
...graph.importedBy.keys(),
|
|
@@ -8413,22 +8455,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8413
8455
|
const targetPattern = pattern2 ?? "src";
|
|
8414
8456
|
const files = findSourceFiles2(targetPattern);
|
|
8415
8457
|
if (files.length === 0) {
|
|
8416
|
-
console.log(
|
|
8458
|
+
console.log(chalk94.yellow("No files found matching pattern"));
|
|
8417
8459
|
return;
|
|
8418
8460
|
}
|
|
8419
|
-
const tsConfigPath =
|
|
8461
|
+
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8420
8462
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8421
8463
|
if (plan2.moves.length === 0) {
|
|
8422
|
-
console.log(
|
|
8464
|
+
console.log(chalk94.green("No restructuring needed"));
|
|
8423
8465
|
return;
|
|
8424
8466
|
}
|
|
8425
8467
|
displayPlan2(plan2);
|
|
8426
8468
|
if (options2.apply) {
|
|
8427
|
-
console.log(
|
|
8469
|
+
console.log(chalk94.bold("\nApplying changes..."));
|
|
8428
8470
|
executePlan(plan2);
|
|
8429
|
-
console.log(
|
|
8471
|
+
console.log(chalk94.green("\nRestructuring complete"));
|
|
8430
8472
|
} else {
|
|
8431
|
-
console.log(
|
|
8473
|
+
console.log(chalk94.dim("\nDry run. Use --apply to execute."));
|
|
8432
8474
|
}
|
|
8433
8475
|
}
|
|
8434
8476
|
|
|
@@ -8468,7 +8510,7 @@ function registerRefactor(program2) {
|
|
|
8468
8510
|
}
|
|
8469
8511
|
|
|
8470
8512
|
// src/commands/seq/seqAuth.ts
|
|
8471
|
-
import
|
|
8513
|
+
import chalk96 from "chalk";
|
|
8472
8514
|
|
|
8473
8515
|
// src/commands/seq/loadConnections.ts
|
|
8474
8516
|
function loadConnections2() {
|
|
@@ -8497,11 +8539,11 @@ function setDefaultConnection(name) {
|
|
|
8497
8539
|
}
|
|
8498
8540
|
|
|
8499
8541
|
// src/commands/seq/promptConnection.ts
|
|
8500
|
-
import
|
|
8542
|
+
import chalk95 from "chalk";
|
|
8501
8543
|
async function promptConnection2(existingNames) {
|
|
8502
8544
|
const name = await promptInput("name", "Connection name:", "default");
|
|
8503
8545
|
if (existingNames.includes(name)) {
|
|
8504
|
-
console.error(
|
|
8546
|
+
console.error(chalk95.red(`Connection "${name}" already exists.`));
|
|
8505
8547
|
process.exit(1);
|
|
8506
8548
|
}
|
|
8507
8549
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -8513,32 +8555,32 @@ async function promptConnection2(existingNames) {
|
|
|
8513
8555
|
var seqAuth = createConnectionAuth({
|
|
8514
8556
|
load: loadConnections2,
|
|
8515
8557
|
save: saveConnections2,
|
|
8516
|
-
format: (c) => `${
|
|
8558
|
+
format: (c) => `${chalk96.bold(c.name)} ${c.url}`,
|
|
8517
8559
|
promptNew: promptConnection2,
|
|
8518
8560
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
8519
8561
|
});
|
|
8520
8562
|
|
|
8521
8563
|
// src/commands/seq/seqQuery.ts
|
|
8522
|
-
import
|
|
8564
|
+
import chalk99 from "chalk";
|
|
8523
8565
|
|
|
8524
8566
|
// src/commands/seq/formatEvent.ts
|
|
8525
|
-
import
|
|
8567
|
+
import chalk97 from "chalk";
|
|
8526
8568
|
function levelColor(level) {
|
|
8527
8569
|
switch (level) {
|
|
8528
8570
|
case "Fatal":
|
|
8529
|
-
return
|
|
8571
|
+
return chalk97.bgRed.white;
|
|
8530
8572
|
case "Error":
|
|
8531
|
-
return
|
|
8573
|
+
return chalk97.red;
|
|
8532
8574
|
case "Warning":
|
|
8533
|
-
return
|
|
8575
|
+
return chalk97.yellow;
|
|
8534
8576
|
case "Information":
|
|
8535
|
-
return
|
|
8577
|
+
return chalk97.cyan;
|
|
8536
8578
|
case "Debug":
|
|
8537
|
-
return
|
|
8579
|
+
return chalk97.gray;
|
|
8538
8580
|
case "Verbose":
|
|
8539
|
-
return
|
|
8581
|
+
return chalk97.dim;
|
|
8540
8582
|
default:
|
|
8541
|
-
return
|
|
8583
|
+
return chalk97.white;
|
|
8542
8584
|
}
|
|
8543
8585
|
}
|
|
8544
8586
|
function levelAbbrev(level) {
|
|
@@ -8579,31 +8621,31 @@ function formatTimestamp(iso) {
|
|
|
8579
8621
|
function formatEvent(event) {
|
|
8580
8622
|
const color = levelColor(event.Level);
|
|
8581
8623
|
const abbrev = levelAbbrev(event.Level);
|
|
8582
|
-
const ts8 =
|
|
8624
|
+
const ts8 = chalk97.dim(formatTimestamp(event.Timestamp));
|
|
8583
8625
|
const msg = renderMessage(event);
|
|
8584
8626
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
8585
8627
|
if (event.Exception) {
|
|
8586
8628
|
for (const line of event.Exception.split("\n")) {
|
|
8587
|
-
lines.push(
|
|
8629
|
+
lines.push(chalk97.red(` ${line}`));
|
|
8588
8630
|
}
|
|
8589
8631
|
}
|
|
8590
8632
|
return lines.join("\n");
|
|
8591
8633
|
}
|
|
8592
8634
|
|
|
8593
8635
|
// src/commands/seq/resolveConnection.ts
|
|
8594
|
-
import
|
|
8636
|
+
import chalk98 from "chalk";
|
|
8595
8637
|
function resolveConnection2(name) {
|
|
8596
8638
|
const connections = loadConnections2();
|
|
8597
8639
|
if (connections.length === 0) {
|
|
8598
8640
|
console.error(
|
|
8599
|
-
|
|
8641
|
+
chalk98.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
8600
8642
|
);
|
|
8601
8643
|
process.exit(1);
|
|
8602
8644
|
}
|
|
8603
8645
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
8604
8646
|
const connection = connections.find((c) => c.name === target);
|
|
8605
8647
|
if (!connection) {
|
|
8606
|
-
console.error(
|
|
8648
|
+
console.error(chalk98.red(`Seq connection "${target}" not found.`));
|
|
8607
8649
|
process.exit(1);
|
|
8608
8650
|
}
|
|
8609
8651
|
return connection;
|
|
@@ -8623,12 +8665,12 @@ async function seqQuery(filter, options2) {
|
|
|
8623
8665
|
});
|
|
8624
8666
|
if (!response.ok) {
|
|
8625
8667
|
const body = await response.text();
|
|
8626
|
-
console.error(
|
|
8668
|
+
console.error(chalk99.red(`Seq returned ${response.status}: ${body}`));
|
|
8627
8669
|
process.exit(1);
|
|
8628
8670
|
}
|
|
8629
8671
|
const events = await response.json();
|
|
8630
8672
|
if (events.length === 0) {
|
|
8631
|
-
console.log(
|
|
8673
|
+
console.log(chalk99.yellow("No events found."));
|
|
8632
8674
|
return;
|
|
8633
8675
|
}
|
|
8634
8676
|
if (options2.json) {
|
|
@@ -8639,11 +8681,11 @@ async function seqQuery(filter, options2) {
|
|
|
8639
8681
|
for (const event of chronological) {
|
|
8640
8682
|
console.log(formatEvent(event));
|
|
8641
8683
|
}
|
|
8642
|
-
console.log(
|
|
8684
|
+
console.log(chalk99.dim(`
|
|
8643
8685
|
${events.length} events`));
|
|
8644
8686
|
if (events.length >= count) {
|
|
8645
8687
|
console.log(
|
|
8646
|
-
|
|
8688
|
+
chalk99.yellow(
|
|
8647
8689
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
8648
8690
|
)
|
|
8649
8691
|
);
|
|
@@ -8651,11 +8693,11 @@ ${events.length} events`));
|
|
|
8651
8693
|
}
|
|
8652
8694
|
|
|
8653
8695
|
// src/commands/seq/seqSetConnection.ts
|
|
8654
|
-
import
|
|
8696
|
+
import chalk100 from "chalk";
|
|
8655
8697
|
function seqSetConnection(name) {
|
|
8656
8698
|
const connections = loadConnections2();
|
|
8657
8699
|
if (!connections.find((c) => c.name === name)) {
|
|
8658
|
-
console.error(
|
|
8700
|
+
console.error(chalk100.red(`Connection "${name}" not found.`));
|
|
8659
8701
|
process.exit(1);
|
|
8660
8702
|
}
|
|
8661
8703
|
setDefaultConnection(name);
|
|
@@ -9194,14 +9236,14 @@ import {
|
|
|
9194
9236
|
import { dirname as dirname20, join as join29 } from "path";
|
|
9195
9237
|
|
|
9196
9238
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9197
|
-
import
|
|
9239
|
+
import chalk101 from "chalk";
|
|
9198
9240
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9199
9241
|
function validateStagedContent(filename, content) {
|
|
9200
9242
|
const firstLine = content.split("\n")[0];
|
|
9201
9243
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9202
9244
|
if (!match) {
|
|
9203
9245
|
console.error(
|
|
9204
|
-
|
|
9246
|
+
chalk101.red(
|
|
9205
9247
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9206
9248
|
)
|
|
9207
9249
|
);
|
|
@@ -9210,7 +9252,7 @@ function validateStagedContent(filename, content) {
|
|
|
9210
9252
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9211
9253
|
if (!contentAfterLink) {
|
|
9212
9254
|
console.error(
|
|
9213
|
-
|
|
9255
|
+
chalk101.red(
|
|
9214
9256
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9215
9257
|
)
|
|
9216
9258
|
);
|
|
@@ -9603,7 +9645,7 @@ function registerVoice(program2) {
|
|
|
9603
9645
|
|
|
9604
9646
|
// src/commands/roam/auth.ts
|
|
9605
9647
|
import { randomBytes } from "crypto";
|
|
9606
|
-
import
|
|
9648
|
+
import chalk102 from "chalk";
|
|
9607
9649
|
|
|
9608
9650
|
// src/lib/openBrowser.ts
|
|
9609
9651
|
import { execSync as execSync37 } from "child_process";
|
|
@@ -9778,13 +9820,13 @@ async function auth() {
|
|
|
9778
9820
|
saveGlobalConfig(config);
|
|
9779
9821
|
const state = randomBytes(16).toString("hex");
|
|
9780
9822
|
console.log(
|
|
9781
|
-
|
|
9823
|
+
chalk102.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
9782
9824
|
);
|
|
9783
|
-
console.log(
|
|
9784
|
-
console.log(
|
|
9785
|
-
console.log(
|
|
9825
|
+
console.log(chalk102.white("http://localhost:14523/callback\n"));
|
|
9826
|
+
console.log(chalk102.blue("Opening browser for authorization..."));
|
|
9827
|
+
console.log(chalk102.dim("Waiting for authorization callback..."));
|
|
9786
9828
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
9787
|
-
console.log(
|
|
9829
|
+
console.log(chalk102.dim("Exchanging code for tokens..."));
|
|
9788
9830
|
const tokens = await exchangeToken({
|
|
9789
9831
|
code,
|
|
9790
9832
|
clientId,
|
|
@@ -9800,7 +9842,7 @@ async function auth() {
|
|
|
9800
9842
|
};
|
|
9801
9843
|
saveGlobalConfig(config);
|
|
9802
9844
|
console.log(
|
|
9803
|
-
|
|
9845
|
+
chalk102.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
9804
9846
|
);
|
|
9805
9847
|
}
|
|
9806
9848
|
|
|
@@ -10021,7 +10063,7 @@ import { execSync as execSync39 } from "child_process";
|
|
|
10021
10063
|
import { existsSync as existsSync38, mkdirSync as mkdirSync13, unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
|
|
10022
10064
|
import { tmpdir as tmpdir6 } from "os";
|
|
10023
10065
|
import { join as join38, resolve as resolve5 } from "path";
|
|
10024
|
-
import
|
|
10066
|
+
import chalk103 from "chalk";
|
|
10025
10067
|
|
|
10026
10068
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10027
10069
|
var captureWindowPs1 = `
|
|
@@ -10172,22 +10214,22 @@ function screenshot(processName) {
|
|
|
10172
10214
|
const config = loadConfig();
|
|
10173
10215
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10174
10216
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10175
|
-
console.log(
|
|
10217
|
+
console.log(chalk103.gray(`Capturing window for process "${processName}" ...`));
|
|
10176
10218
|
try {
|
|
10177
10219
|
runPowerShellScript(processName, outputPath);
|
|
10178
|
-
console.log(
|
|
10220
|
+
console.log(chalk103.green(`Screenshot saved: ${outputPath}`));
|
|
10179
10221
|
} catch (error) {
|
|
10180
10222
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10181
|
-
console.error(
|
|
10223
|
+
console.error(chalk103.red(`Failed to capture screenshot: ${msg}`));
|
|
10182
10224
|
process.exit(1);
|
|
10183
10225
|
}
|
|
10184
10226
|
}
|
|
10185
10227
|
|
|
10186
10228
|
// src/commands/statusLine.ts
|
|
10187
|
-
import
|
|
10229
|
+
import chalk105 from "chalk";
|
|
10188
10230
|
|
|
10189
10231
|
// src/commands/buildLimitsSegment.ts
|
|
10190
|
-
import
|
|
10232
|
+
import chalk104 from "chalk";
|
|
10191
10233
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10192
10234
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10193
10235
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10210,10 +10252,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10210
10252
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10211
10253
|
const label2 = `${Math.round(pct)}%`;
|
|
10212
10254
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10213
|
-
if (projected == null) return
|
|
10214
|
-
if (projected > 100) return
|
|
10215
|
-
if (projected > 75) return
|
|
10216
|
-
return
|
|
10255
|
+
if (projected == null) return chalk104.green(label2);
|
|
10256
|
+
if (projected > 100) return chalk104.red(label2);
|
|
10257
|
+
if (projected > 75) return chalk104.yellow(label2);
|
|
10258
|
+
return chalk104.green(label2);
|
|
10217
10259
|
}
|
|
10218
10260
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10219
10261
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10239,14 +10281,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10239
10281
|
}
|
|
10240
10282
|
|
|
10241
10283
|
// src/commands/statusLine.ts
|
|
10242
|
-
|
|
10284
|
+
chalk105.level = 3;
|
|
10243
10285
|
function formatNumber(num) {
|
|
10244
10286
|
return num.toLocaleString("en-US");
|
|
10245
10287
|
}
|
|
10246
10288
|
function colorizePercent(pct) {
|
|
10247
10289
|
const label2 = `${Math.round(pct)}%`;
|
|
10248
|
-
if (pct > 80) return
|
|
10249
|
-
if (pct > 40) return
|
|
10290
|
+
if (pct > 80) return chalk105.red(label2);
|
|
10291
|
+
if (pct > 40) return chalk105.yellow(label2);
|
|
10250
10292
|
return label2;
|
|
10251
10293
|
}
|
|
10252
10294
|
async function statusLine() {
|
|
@@ -10263,27 +10305,27 @@ async function statusLine() {
|
|
|
10263
10305
|
// src/commands/sync.ts
|
|
10264
10306
|
import * as fs25 from "fs";
|
|
10265
10307
|
import * as os from "os";
|
|
10266
|
-
import * as
|
|
10308
|
+
import * as path48 from "path";
|
|
10267
10309
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
10268
10310
|
|
|
10269
10311
|
// src/commands/sync/syncClaudeMd.ts
|
|
10270
10312
|
import * as fs23 from "fs";
|
|
10271
|
-
import * as
|
|
10272
|
-
import
|
|
10313
|
+
import * as path46 from "path";
|
|
10314
|
+
import chalk106 from "chalk";
|
|
10273
10315
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10274
|
-
const source =
|
|
10275
|
-
const target =
|
|
10316
|
+
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10317
|
+
const target = path46.join(targetBase, "CLAUDE.md");
|
|
10276
10318
|
const sourceContent = fs23.readFileSync(source, "utf-8");
|
|
10277
10319
|
if (fs23.existsSync(target)) {
|
|
10278
10320
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10279
10321
|
if (sourceContent !== targetContent) {
|
|
10280
10322
|
console.log(
|
|
10281
|
-
|
|
10323
|
+
chalk106.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10282
10324
|
);
|
|
10283
10325
|
console.log();
|
|
10284
10326
|
printDiff(targetContent, sourceContent);
|
|
10285
10327
|
const confirm = options2?.yes || await promptConfirm(
|
|
10286
|
-
|
|
10328
|
+
chalk106.red("Overwrite existing CLAUDE.md?"),
|
|
10287
10329
|
false
|
|
10288
10330
|
);
|
|
10289
10331
|
if (!confirm) {
|
|
@@ -10298,11 +10340,11 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10298
10340
|
|
|
10299
10341
|
// src/commands/sync/syncSettings.ts
|
|
10300
10342
|
import * as fs24 from "fs";
|
|
10301
|
-
import * as
|
|
10302
|
-
import
|
|
10343
|
+
import * as path47 from "path";
|
|
10344
|
+
import chalk107 from "chalk";
|
|
10303
10345
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10304
|
-
const source =
|
|
10305
|
-
const target =
|
|
10346
|
+
const source = path47.join(claudeDir, "settings.json");
|
|
10347
|
+
const target = path47.join(targetBase, "settings.json");
|
|
10306
10348
|
const sourceContent = fs24.readFileSync(source, "utf-8");
|
|
10307
10349
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
10308
10350
|
if (fs24.existsSync(target)) {
|
|
@@ -10315,14 +10357,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10315
10357
|
if (mergedContent !== normalizedTarget) {
|
|
10316
10358
|
if (!options2?.yes) {
|
|
10317
10359
|
console.log(
|
|
10318
|
-
|
|
10360
|
+
chalk107.yellow(
|
|
10319
10361
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10320
10362
|
)
|
|
10321
10363
|
);
|
|
10322
10364
|
console.log();
|
|
10323
10365
|
printDiff(targetContent, mergedContent);
|
|
10324
10366
|
const confirm = await promptConfirm(
|
|
10325
|
-
|
|
10367
|
+
chalk107.red("Overwrite existing settings.json?"),
|
|
10326
10368
|
false
|
|
10327
10369
|
);
|
|
10328
10370
|
if (!confirm) {
|
|
@@ -10338,21 +10380,21 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10338
10380
|
|
|
10339
10381
|
// src/commands/sync.ts
|
|
10340
10382
|
var __filename4 = fileURLToPath7(import.meta.url);
|
|
10341
|
-
var __dirname7 =
|
|
10383
|
+
var __dirname7 = path48.dirname(__filename4);
|
|
10342
10384
|
async function sync(options2) {
|
|
10343
|
-
const claudeDir =
|
|
10344
|
-
const targetBase =
|
|
10385
|
+
const claudeDir = path48.join(__dirname7, "..", "claude");
|
|
10386
|
+
const targetBase = path48.join(os.homedir(), ".claude");
|
|
10345
10387
|
syncCommands(claudeDir, targetBase);
|
|
10346
10388
|
await syncSettings(claudeDir, targetBase, { yes: options2?.yes });
|
|
10347
10389
|
await syncClaudeMd(claudeDir, targetBase, { yes: options2?.yes });
|
|
10348
10390
|
}
|
|
10349
10391
|
function syncCommands(claudeDir, targetBase) {
|
|
10350
|
-
const sourceDir =
|
|
10351
|
-
const targetDir =
|
|
10392
|
+
const sourceDir = path48.join(claudeDir, "commands");
|
|
10393
|
+
const targetDir = path48.join(targetBase, "commands");
|
|
10352
10394
|
fs25.mkdirSync(targetDir, { recursive: true });
|
|
10353
10395
|
const files = fs25.readdirSync(sourceDir);
|
|
10354
10396
|
for (const file of files) {
|
|
10355
|
-
fs25.copyFileSync(
|
|
10397
|
+
fs25.copyFileSync(path48.join(sourceDir, file), path48.join(targetDir, file));
|
|
10356
10398
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
10357
10399
|
}
|
|
10358
10400
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -10360,15 +10402,15 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
10360
10402
|
|
|
10361
10403
|
// src/commands/update.ts
|
|
10362
10404
|
import { execSync as execSync40 } from "child_process";
|
|
10363
|
-
import * as
|
|
10405
|
+
import * as path49 from "path";
|
|
10364
10406
|
function isGlobalNpmInstall(dir) {
|
|
10365
10407
|
try {
|
|
10366
|
-
const resolved =
|
|
10367
|
-
if (resolved.split(
|
|
10408
|
+
const resolved = path49.resolve(dir);
|
|
10409
|
+
if (resolved.split(path49.sep).includes("node_modules")) {
|
|
10368
10410
|
return true;
|
|
10369
10411
|
}
|
|
10370
10412
|
const globalPrefix = execSync40("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
10371
|
-
return resolved.toLowerCase().startsWith(
|
|
10413
|
+
return resolved.toLowerCase().startsWith(path49.resolve(globalPrefix).toLowerCase());
|
|
10372
10414
|
} catch {
|
|
10373
10415
|
return false;
|
|
10374
10416
|
}
|