@staff0rd/assist 0.136.1 → 0.137.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/claude/commands/draft.md +5 -2
- package/claude/settings.json +2 -4
- package/dist/index.js +424 -365
- package/package.json +1 -1
- package/claude/commands/next-backlog-item.md +0 -17
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.137.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -2290,7 +2290,8 @@ var planTaskSchema = z2.strictObject({
|
|
|
2290
2290
|
});
|
|
2291
2291
|
var planPhaseSchema = z2.strictObject({
|
|
2292
2292
|
name: z2.string(),
|
|
2293
|
-
tasks: z2.array(planTaskSchema)
|
|
2293
|
+
tasks: z2.array(planTaskSchema),
|
|
2294
|
+
manualChecks: z2.array(z2.string()).optional()
|
|
2294
2295
|
});
|
|
2295
2296
|
var backlogItemSchema = z2.strictObject({
|
|
2296
2297
|
id: z2.number(),
|
|
@@ -2601,25 +2602,44 @@ async function list2(options2) {
|
|
|
2601
2602
|
}
|
|
2602
2603
|
|
|
2603
2604
|
// src/commands/backlog/next.ts
|
|
2604
|
-
import
|
|
2605
|
+
import chalk36 from "chalk";
|
|
2605
2606
|
import enquirer6 from "enquirer";
|
|
2606
2607
|
|
|
2607
2608
|
// src/commands/backlog/run.ts
|
|
2608
|
-
import
|
|
2609
|
+
import chalk35 from "chalk";
|
|
2609
2610
|
|
|
2610
2611
|
// src/commands/backlog/executePhase.ts
|
|
2611
|
-
import
|
|
2612
|
-
import { existsSync as existsSync16, unlinkSync as unlinkSync3 } from "fs";
|
|
2613
|
-
import chalk33 from "chalk";
|
|
2614
|
-
import enquirer5 from "enquirer";
|
|
2612
|
+
import chalk34 from "chalk";
|
|
2615
2613
|
|
|
2616
2614
|
// src/commands/backlog/buildPhasePrompt.ts
|
|
2617
|
-
function
|
|
2618
|
-
|
|
2615
|
+
function formatTasks(phase) {
|
|
2616
|
+
return phase.tasks.map((t) => {
|
|
2619
2617
|
let line = `- ${t.task}`;
|
|
2620
2618
|
if (t.verify) line += ` (verify: ${t.verify})`;
|
|
2621
2619
|
return line;
|
|
2622
2620
|
}).join("\n");
|
|
2621
|
+
}
|
|
2622
|
+
function buildManualCheckLines(manualChecks, isLastPhase) {
|
|
2623
|
+
if (manualChecks.length > 0) {
|
|
2624
|
+
return [
|
|
2625
|
+
"",
|
|
2626
|
+
"Before marking this phase as done, ask the user to perform these manual checks:",
|
|
2627
|
+
...manualChecks.map((c) => `- ${c}`),
|
|
2628
|
+
"",
|
|
2629
|
+
"Wait for the user to confirm all manual checks pass before proceeding."
|
|
2630
|
+
];
|
|
2631
|
+
}
|
|
2632
|
+
if (isLastPhase) {
|
|
2633
|
+
return [
|
|
2634
|
+
"",
|
|
2635
|
+
"This is the final phase. Before marking it as done, ask the user to manually verify",
|
|
2636
|
+
"that the feature works end-to-end and all acceptance criteria are met.",
|
|
2637
|
+
"Wait for the user to confirm before proceeding."
|
|
2638
|
+
];
|
|
2639
|
+
}
|
|
2640
|
+
return [];
|
|
2641
|
+
}
|
|
2642
|
+
function buildContextLines(item, phaseIndex, phase) {
|
|
2623
2643
|
const ac = item.acceptanceCriteria.map((c) => `- ${c}`).join("\n");
|
|
2624
2644
|
return [
|
|
2625
2645
|
`You are implementing phase ${phaseIndex + 1} of backlog item #${item.id}: ${item.name}`,
|
|
@@ -2631,14 +2651,31 @@ function buildPhasePrompt(item, phaseIndex, phase) {
|
|
|
2631
2651
|
"",
|
|
2632
2652
|
`Phase ${phaseIndex + 1}: ${phase.name}`,
|
|
2633
2653
|
"Tasks:",
|
|
2634
|
-
|
|
2654
|
+
formatTasks(phase)
|
|
2655
|
+
];
|
|
2656
|
+
}
|
|
2657
|
+
function buildPhasePrompt(item, phaseIndex, phase, totalPhases) {
|
|
2658
|
+
const isLastPhase = phaseIndex === totalPhases - 1;
|
|
2659
|
+
const manualChecks = phase.manualChecks ?? [];
|
|
2660
|
+
const needsConfirmation = manualChecks.length > 0 || isLastPhase;
|
|
2661
|
+
const confirmSuffix = needsConfirmation ? " and the user confirms" : "";
|
|
2662
|
+
return [
|
|
2663
|
+
...buildContextLines(item, phaseIndex, phase),
|
|
2635
2664
|
"",
|
|
2636
2665
|
"Focus ONLY on this phase. Do not work on other phases.",
|
|
2637
|
-
|
|
2638
|
-
|
|
2666
|
+
"When you have completed all tasks for this phase, run /verify to check your work.",
|
|
2667
|
+
...buildManualCheckLines(manualChecks, isLastPhase),
|
|
2668
|
+
"",
|
|
2669
|
+
`Once verify passes${confirmSuffix}, run: assist backlog phase-done ${item.id} ${phaseIndex}`
|
|
2639
2670
|
].filter((line) => line !== void 0).join("\n");
|
|
2640
2671
|
}
|
|
2641
2672
|
|
|
2673
|
+
// src/commands/backlog/resolvePhaseResult.ts
|
|
2674
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
2675
|
+
import { existsSync as existsSync16, unlinkSync as unlinkSync3 } from "fs";
|
|
2676
|
+
import chalk33 from "chalk";
|
|
2677
|
+
import enquirer5 from "enquirer";
|
|
2678
|
+
|
|
2642
2679
|
// src/commands/backlog/phaseDone.ts
|
|
2643
2680
|
import { writeFileSync as writeFileSync13 } from "fs";
|
|
2644
2681
|
import { join as join10 } from "path";
|
|
@@ -2662,19 +2699,7 @@ function phaseDone(id, phase) {
|
|
|
2662
2699
|
console.log(chalk32.green(`Phase ${phase} of item #${id} marked as complete.`));
|
|
2663
2700
|
}
|
|
2664
2701
|
|
|
2665
|
-
// src/commands/backlog/
|
|
2666
|
-
import { spawn as spawn3 } from "child_process";
|
|
2667
|
-
function spawnClaude(prompt) {
|
|
2668
|
-
return new Promise((resolve7, reject) => {
|
|
2669
|
-
const child = spawn3("claude", [prompt], {
|
|
2670
|
-
stdio: "inherit"
|
|
2671
|
-
});
|
|
2672
|
-
child.on("close", (code) => resolve7(code ?? 0));
|
|
2673
|
-
child.on("error", reject);
|
|
2674
|
-
});
|
|
2675
|
-
}
|
|
2676
|
-
|
|
2677
|
-
// src/commands/backlog/executePhase.ts
|
|
2702
|
+
// src/commands/backlog/resolvePhaseResult.ts
|
|
2678
2703
|
function cleanupMarker() {
|
|
2679
2704
|
const statusPath = getPhaseStatusPath();
|
|
2680
2705
|
if (existsSync16(statusPath)) {
|
|
@@ -2726,17 +2751,51 @@ async function resolvePhaseResult(phaseIndex) {
|
|
|
2726
2751
|
if (action === "abort") return -1;
|
|
2727
2752
|
return action === "skip" ? 1 : 0;
|
|
2728
2753
|
}
|
|
2754
|
+
|
|
2755
|
+
// src/commands/backlog/spawnClaude.ts
|
|
2756
|
+
import { spawn as spawn3 } from "child_process";
|
|
2757
|
+
function spawnClaude(prompt) {
|
|
2758
|
+
const child = spawn3("claude", [prompt], {
|
|
2759
|
+
stdio: "inherit"
|
|
2760
|
+
});
|
|
2761
|
+
const done2 = new Promise((resolve7, reject) => {
|
|
2762
|
+
child.on("close", (code) => resolve7(code ?? 0));
|
|
2763
|
+
child.on("error", reject);
|
|
2764
|
+
});
|
|
2765
|
+
return { child, done: done2 };
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
// src/commands/backlog/watchForMarker.ts
|
|
2769
|
+
import { existsSync as existsSync17, unwatchFile, watchFile } from "fs";
|
|
2770
|
+
function watchForMarker(child) {
|
|
2771
|
+
const statusPath = getPhaseStatusPath();
|
|
2772
|
+
watchFile(statusPath, { interval: 1e3 }, () => {
|
|
2773
|
+
if (existsSync17(statusPath)) {
|
|
2774
|
+
unwatchFile(statusPath);
|
|
2775
|
+
child.kill("SIGTERM");
|
|
2776
|
+
}
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
function stopWatching() {
|
|
2780
|
+
unwatchFile(getPhaseStatusPath());
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
// src/commands/backlog/executePhase.ts
|
|
2729
2784
|
async function executePhase(item, phaseIndex, phases) {
|
|
2730
2785
|
const phase = phases[phaseIndex];
|
|
2731
2786
|
console.log(
|
|
2732
|
-
|
|
2787
|
+
chalk34.bold(
|
|
2733
2788
|
`
|
|
2734
2789
|
--- Phase ${phaseIndex + 1}/${phases.length}: ${phase.name} ---
|
|
2735
2790
|
`
|
|
2736
2791
|
)
|
|
2737
2792
|
);
|
|
2738
|
-
|
|
2739
|
-
|
|
2793
|
+
const { child, done: done2 } = spawnClaude(
|
|
2794
|
+
buildPhasePrompt(item, phaseIndex, phase, phases.length)
|
|
2795
|
+
);
|
|
2796
|
+
watchForMarker(child);
|
|
2797
|
+
await done2;
|
|
2798
|
+
stopWatching();
|
|
2740
2799
|
const delta = await resolvePhaseResult(phaseIndex);
|
|
2741
2800
|
return delta < 0 ? -1 : phaseIndex + delta;
|
|
2742
2801
|
}
|
|
@@ -2745,7 +2804,7 @@ async function executePhase(item, phaseIndex, phases) {
|
|
|
2745
2804
|
function validatePlan(item) {
|
|
2746
2805
|
if (!item.plan || item.plan.length === 0) {
|
|
2747
2806
|
console.log(
|
|
2748
|
-
|
|
2807
|
+
chalk35.red("Item has no plan. Use /draft to create one with phases.")
|
|
2749
2808
|
);
|
|
2750
2809
|
return void 0;
|
|
2751
2810
|
}
|
|
@@ -2759,14 +2818,14 @@ async function run2(id) {
|
|
|
2759
2818
|
if (!plan2) return;
|
|
2760
2819
|
setStatus(id, "in-progress");
|
|
2761
2820
|
const startPhase = item.currentPhase ?? 0;
|
|
2762
|
-
console.log(
|
|
2821
|
+
console.log(chalk35.bold(`Running plan for #${id}: ${item.name}`));
|
|
2763
2822
|
if (startPhase > 0) {
|
|
2764
2823
|
console.log(
|
|
2765
|
-
|
|
2824
|
+
chalk35.dim(`Resuming from phase ${startPhase + 1}/${plan2.length}
|
|
2766
2825
|
`)
|
|
2767
2826
|
);
|
|
2768
2827
|
} else {
|
|
2769
|
-
console.log(
|
|
2828
|
+
console.log(chalk35.dim(`${plan2.length} phase(s)
|
|
2770
2829
|
`));
|
|
2771
2830
|
}
|
|
2772
2831
|
let phaseIndex = startPhase;
|
|
@@ -2774,9 +2833,9 @@ async function run2(id) {
|
|
|
2774
2833
|
phaseIndex = await executePhase(item, phaseIndex, plan2);
|
|
2775
2834
|
if (phaseIndex < 0) return;
|
|
2776
2835
|
}
|
|
2777
|
-
console.log(
|
|
2836
|
+
console.log(chalk35.green(`
|
|
2778
2837
|
All phases complete for #${id}: ${item.name}`));
|
|
2779
|
-
console.log(
|
|
2838
|
+
console.log(chalk35.dim("Review the changes, then use /commit when ready."));
|
|
2780
2839
|
}
|
|
2781
2840
|
|
|
2782
2841
|
// src/commands/backlog/next.ts
|
|
@@ -2785,7 +2844,7 @@ async function next() {
|
|
|
2785
2844
|
const inProgress = items.find((i) => i.status === "in-progress" && i.plan);
|
|
2786
2845
|
if (inProgress) {
|
|
2787
2846
|
console.log(
|
|
2788
|
-
|
|
2847
|
+
chalk36.bold(
|
|
2789
2848
|
`Resuming in-progress item #${inProgress.id}: ${inProgress.name}`
|
|
2790
2849
|
)
|
|
2791
2850
|
);
|
|
@@ -2794,7 +2853,7 @@ async function next() {
|
|
|
2794
2853
|
}
|
|
2795
2854
|
const todo = items.filter((i) => i.status === "todo");
|
|
2796
2855
|
if (todo.length === 0) {
|
|
2797
|
-
console.log(
|
|
2856
|
+
console.log(chalk36.dim("No incomplete backlog items. Opening /draft..."));
|
|
2798
2857
|
await spawnClaude("/draft");
|
|
2799
2858
|
return;
|
|
2800
2859
|
}
|
|
@@ -2813,23 +2872,23 @@ async function next() {
|
|
|
2813
2872
|
}
|
|
2814
2873
|
|
|
2815
2874
|
// src/commands/backlog/plan.ts
|
|
2816
|
-
import
|
|
2875
|
+
import chalk37 from "chalk";
|
|
2817
2876
|
function plan(id) {
|
|
2818
2877
|
const result = loadAndFindItem(id);
|
|
2819
2878
|
if (!result) return;
|
|
2820
2879
|
const { item } = result;
|
|
2821
2880
|
if (!item.plan || item.plan.length === 0) {
|
|
2822
|
-
console.log(
|
|
2881
|
+
console.log(chalk37.dim("No plan defined for this item."));
|
|
2823
2882
|
return;
|
|
2824
2883
|
}
|
|
2825
|
-
console.log(
|
|
2884
|
+
console.log(chalk37.bold(item.name));
|
|
2826
2885
|
console.log();
|
|
2827
2886
|
for (const [i, phase] of item.plan.entries()) {
|
|
2828
|
-
console.log(`${
|
|
2887
|
+
console.log(`${chalk37.bold(`Phase ${i + 1}:`)} ${phase.name}`);
|
|
2829
2888
|
for (const task of phase.tasks) {
|
|
2830
2889
|
console.log(` - ${task.task}`);
|
|
2831
2890
|
if (task.verify) {
|
|
2832
|
-
console.log(` ${
|
|
2891
|
+
console.log(` ${chalk37.dim(`verify: ${task.verify}`)}`);
|
|
2833
2892
|
}
|
|
2834
2893
|
}
|
|
2835
2894
|
console.log();
|
|
@@ -2837,11 +2896,11 @@ function plan(id) {
|
|
|
2837
2896
|
}
|
|
2838
2897
|
|
|
2839
2898
|
// src/commands/backlog/start/index.ts
|
|
2840
|
-
import
|
|
2899
|
+
import chalk38 from "chalk";
|
|
2841
2900
|
async function start(id) {
|
|
2842
2901
|
const name = setStatus(id, "in-progress");
|
|
2843
2902
|
if (name) {
|
|
2844
|
-
console.log(
|
|
2903
|
+
console.log(chalk38.green(`Started item #${id}: ${name}`));
|
|
2845
2904
|
}
|
|
2846
2905
|
}
|
|
2847
2906
|
|
|
@@ -2853,7 +2912,7 @@ import {
|
|
|
2853
2912
|
} from "http";
|
|
2854
2913
|
import { dirname as dirname13, join as join11 } from "path";
|
|
2855
2914
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2856
|
-
import
|
|
2915
|
+
import chalk39 from "chalk";
|
|
2857
2916
|
function respondJson(res, status2, data) {
|
|
2858
2917
|
res.writeHead(status2, { "Content-Type": "application/json" });
|
|
2859
2918
|
res.end(JSON.stringify(data));
|
|
@@ -2897,8 +2956,8 @@ function startWebServer(label2, port, handler) {
|
|
|
2897
2956
|
handler(req, res, port);
|
|
2898
2957
|
});
|
|
2899
2958
|
server.listen(port, () => {
|
|
2900
|
-
console.log(
|
|
2901
|
-
console.log(
|
|
2959
|
+
console.log(chalk39.green(`${label2}: ${url}`));
|
|
2960
|
+
console.log(chalk39.dim("Press Ctrl+C to stop"));
|
|
2902
2961
|
exec(`open ${url}`);
|
|
2903
2962
|
});
|
|
2904
2963
|
}
|
|
@@ -3152,7 +3211,7 @@ function extractGraphqlQuery(args) {
|
|
|
3152
3211
|
}
|
|
3153
3212
|
|
|
3154
3213
|
// src/shared/loadCliReads.ts
|
|
3155
|
-
import { existsSync as
|
|
3214
|
+
import { existsSync as existsSync18, readFileSync as readFileSync13, writeFileSync as writeFileSync14 } from "fs";
|
|
3156
3215
|
import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
3157
3216
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3158
3217
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
@@ -3164,7 +3223,7 @@ var cachedLines;
|
|
|
3164
3223
|
function getCliReadsLines() {
|
|
3165
3224
|
if (cachedLines) return cachedLines;
|
|
3166
3225
|
const path44 = getCliReadsPath();
|
|
3167
|
-
if (!
|
|
3226
|
+
if (!existsSync18(path44)) {
|
|
3168
3227
|
cachedLines = [];
|
|
3169
3228
|
return cachedLines;
|
|
3170
3229
|
}
|
|
@@ -3193,7 +3252,7 @@ function findCliRead(command) {
|
|
|
3193
3252
|
}
|
|
3194
3253
|
|
|
3195
3254
|
// src/shared/matchesBashAllow.ts
|
|
3196
|
-
import { existsSync as
|
|
3255
|
+
import { existsSync as existsSync19, readFileSync as readFileSync14 } from "fs";
|
|
3197
3256
|
import { homedir as homedir3 } from "os";
|
|
3198
3257
|
import { join as join12 } from "path";
|
|
3199
3258
|
var cached;
|
|
@@ -3221,7 +3280,7 @@ function collectAllowEntries() {
|
|
|
3221
3280
|
return entries;
|
|
3222
3281
|
}
|
|
3223
3282
|
function readAllowArray(filePath) {
|
|
3224
|
-
if (!
|
|
3283
|
+
if (!existsSync19(filePath)) return [];
|
|
3225
3284
|
try {
|
|
3226
3285
|
const data = JSON.parse(readFileSync14(filePath, "utf-8"));
|
|
3227
3286
|
const allow = data?.permissions?.allow;
|
|
@@ -3371,7 +3430,7 @@ ${reasons.join("\n")}`);
|
|
|
3371
3430
|
}
|
|
3372
3431
|
|
|
3373
3432
|
// src/commands/permitCliReads/index.ts
|
|
3374
|
-
import { existsSync as
|
|
3433
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync4, readFileSync as readFileSync15, writeFileSync as writeFileSync15 } from "fs";
|
|
3375
3434
|
import { homedir as homedir4 } from "os";
|
|
3376
3435
|
import { join as join13 } from "path";
|
|
3377
3436
|
|
|
@@ -3417,11 +3476,11 @@ function assertCliExists(cli) {
|
|
|
3417
3476
|
}
|
|
3418
3477
|
|
|
3419
3478
|
// src/commands/permitCliReads/colorize.ts
|
|
3420
|
-
import
|
|
3479
|
+
import chalk40 from "chalk";
|
|
3421
3480
|
function colorize(plainOutput) {
|
|
3422
3481
|
return plainOutput.split("\n").map((line) => {
|
|
3423
|
-
if (line.startsWith(" R ")) return
|
|
3424
|
-
if (line.startsWith(" W ")) return
|
|
3482
|
+
if (line.startsWith(" R ")) return chalk40.green(line);
|
|
3483
|
+
if (line.startsWith(" W ")) return chalk40.red(line);
|
|
3425
3484
|
return line;
|
|
3426
3485
|
}).join("\n");
|
|
3427
3486
|
}
|
|
@@ -3679,7 +3738,7 @@ function logPath(cli) {
|
|
|
3679
3738
|
}
|
|
3680
3739
|
function readCache(cli) {
|
|
3681
3740
|
const path44 = logPath(cli);
|
|
3682
|
-
if (!
|
|
3741
|
+
if (!existsSync20(path44)) return void 0;
|
|
3683
3742
|
return readFileSync15(path44, "utf-8");
|
|
3684
3743
|
}
|
|
3685
3744
|
function writeCache(cli, output) {
|
|
@@ -3735,15 +3794,15 @@ function registerCliHook(program2) {
|
|
|
3735
3794
|
}
|
|
3736
3795
|
|
|
3737
3796
|
// src/commands/complexity/analyze.ts
|
|
3738
|
-
import
|
|
3797
|
+
import chalk46 from "chalk";
|
|
3739
3798
|
|
|
3740
3799
|
// src/commands/complexity/cyclomatic.ts
|
|
3741
|
-
import
|
|
3800
|
+
import chalk42 from "chalk";
|
|
3742
3801
|
|
|
3743
3802
|
// src/commands/complexity/shared/index.ts
|
|
3744
3803
|
import fs12 from "fs";
|
|
3745
3804
|
import path20 from "path";
|
|
3746
|
-
import
|
|
3805
|
+
import chalk41 from "chalk";
|
|
3747
3806
|
import ts5 from "typescript";
|
|
3748
3807
|
|
|
3749
3808
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -3989,7 +4048,7 @@ function createSourceFromFile(filePath) {
|
|
|
3989
4048
|
function withSourceFiles(pattern2, callback) {
|
|
3990
4049
|
const files = findSourceFiles2(pattern2);
|
|
3991
4050
|
if (files.length === 0) {
|
|
3992
|
-
console.log(
|
|
4051
|
+
console.log(chalk41.yellow("No files found matching pattern"));
|
|
3993
4052
|
return void 0;
|
|
3994
4053
|
}
|
|
3995
4054
|
return callback(files);
|
|
@@ -4022,11 +4081,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4022
4081
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4023
4082
|
for (const { file, name, complexity } of results) {
|
|
4024
4083
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4025
|
-
const color = exceedsThreshold ?
|
|
4026
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4084
|
+
const color = exceedsThreshold ? chalk42.red : chalk42.white;
|
|
4085
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk42.cyan(complexity)}`);
|
|
4027
4086
|
}
|
|
4028
4087
|
console.log(
|
|
4029
|
-
|
|
4088
|
+
chalk42.dim(
|
|
4030
4089
|
`
|
|
4031
4090
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4032
4091
|
)
|
|
@@ -4038,7 +4097,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4038
4097
|
}
|
|
4039
4098
|
|
|
4040
4099
|
// src/commands/complexity/halstead.ts
|
|
4041
|
-
import
|
|
4100
|
+
import chalk43 from "chalk";
|
|
4042
4101
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4043
4102
|
withSourceFiles(pattern2, (files) => {
|
|
4044
4103
|
const results = [];
|
|
@@ -4053,13 +4112,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4053
4112
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4054
4113
|
for (const { file, name, metrics } of results) {
|
|
4055
4114
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4056
|
-
const color = exceedsThreshold ?
|
|
4115
|
+
const color = exceedsThreshold ? chalk43.red : chalk43.white;
|
|
4057
4116
|
console.log(
|
|
4058
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4117
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk43.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk43.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk43.magenta(metrics.effort.toFixed(1))}`
|
|
4059
4118
|
);
|
|
4060
4119
|
}
|
|
4061
4120
|
console.log(
|
|
4062
|
-
|
|
4121
|
+
chalk43.dim(
|
|
4063
4122
|
`
|
|
4064
4123
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4065
4124
|
)
|
|
@@ -4074,28 +4133,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4074
4133
|
import fs13 from "fs";
|
|
4075
4134
|
|
|
4076
4135
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4077
|
-
import
|
|
4136
|
+
import chalk44 from "chalk";
|
|
4078
4137
|
function displayMaintainabilityResults(results, threshold) {
|
|
4079
4138
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4080
4139
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4081
|
-
console.log(
|
|
4140
|
+
console.log(chalk44.green("All files pass maintainability threshold"));
|
|
4082
4141
|
} else {
|
|
4083
4142
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4084
|
-
const color = threshold !== void 0 ?
|
|
4143
|
+
const color = threshold !== void 0 ? chalk44.red : chalk44.white;
|
|
4085
4144
|
console.log(
|
|
4086
|
-
`${color(file)} \u2192 avg: ${
|
|
4145
|
+
`${color(file)} \u2192 avg: ${chalk44.cyan(avgMaintainability.toFixed(1))}, min: ${chalk44.yellow(minMaintainability.toFixed(1))}`
|
|
4087
4146
|
);
|
|
4088
4147
|
}
|
|
4089
4148
|
}
|
|
4090
|
-
console.log(
|
|
4149
|
+
console.log(chalk44.dim(`
|
|
4091
4150
|
Analyzed ${results.length} files`));
|
|
4092
4151
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4093
4152
|
console.error(
|
|
4094
|
-
|
|
4153
|
+
chalk44.red(
|
|
4095
4154
|
`
|
|
4096
4155
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4097
4156
|
|
|
4098
|
-
\u26A0\uFE0F ${
|
|
4157
|
+
\u26A0\uFE0F ${chalk44.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.`
|
|
4099
4158
|
)
|
|
4100
4159
|
);
|
|
4101
4160
|
process.exit(1);
|
|
@@ -4152,7 +4211,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4152
4211
|
|
|
4153
4212
|
// src/commands/complexity/sloc.ts
|
|
4154
4213
|
import fs14 from "fs";
|
|
4155
|
-
import
|
|
4214
|
+
import chalk45 from "chalk";
|
|
4156
4215
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4157
4216
|
withSourceFiles(pattern2, (files) => {
|
|
4158
4217
|
const results = [];
|
|
@@ -4168,12 +4227,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4168
4227
|
results.sort((a, b) => b.lines - a.lines);
|
|
4169
4228
|
for (const { file, lines } of results) {
|
|
4170
4229
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4171
|
-
const color = exceedsThreshold ?
|
|
4172
|
-
console.log(`${color(file)} \u2192 ${
|
|
4230
|
+
const color = exceedsThreshold ? chalk45.red : chalk45.white;
|
|
4231
|
+
console.log(`${color(file)} \u2192 ${chalk45.cyan(lines)} lines`);
|
|
4173
4232
|
}
|
|
4174
4233
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4175
4234
|
console.log(
|
|
4176
|
-
|
|
4235
|
+
chalk45.dim(`
|
|
4177
4236
|
Total: ${total} lines across ${files.length} files`)
|
|
4178
4237
|
);
|
|
4179
4238
|
if (hasViolation) {
|
|
@@ -4187,21 +4246,21 @@ async function analyze(pattern2) {
|
|
|
4187
4246
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4188
4247
|
const files = findSourceFiles2(searchPattern);
|
|
4189
4248
|
if (files.length === 0) {
|
|
4190
|
-
console.log(
|
|
4249
|
+
console.log(chalk46.yellow("No files found matching pattern"));
|
|
4191
4250
|
return;
|
|
4192
4251
|
}
|
|
4193
4252
|
if (files.length === 1) {
|
|
4194
4253
|
const file = files[0];
|
|
4195
|
-
console.log(
|
|
4254
|
+
console.log(chalk46.bold.underline("SLOC"));
|
|
4196
4255
|
await sloc(file);
|
|
4197
4256
|
console.log();
|
|
4198
|
-
console.log(
|
|
4257
|
+
console.log(chalk46.bold.underline("Cyclomatic Complexity"));
|
|
4199
4258
|
await cyclomatic(file);
|
|
4200
4259
|
console.log();
|
|
4201
|
-
console.log(
|
|
4260
|
+
console.log(chalk46.bold.underline("Halstead Metrics"));
|
|
4202
4261
|
await halstead(file);
|
|
4203
4262
|
console.log();
|
|
4204
|
-
console.log(
|
|
4263
|
+
console.log(chalk46.bold.underline("Maintainability Index"));
|
|
4205
4264
|
await maintainability(file);
|
|
4206
4265
|
return;
|
|
4207
4266
|
}
|
|
@@ -4228,8 +4287,8 @@ function registerComplexity(program2) {
|
|
|
4228
4287
|
}
|
|
4229
4288
|
|
|
4230
4289
|
// src/commands/deploy/redirect.ts
|
|
4231
|
-
import { existsSync as
|
|
4232
|
-
import
|
|
4290
|
+
import { existsSync as existsSync21, readFileSync as readFileSync16, writeFileSync as writeFileSync16 } from "fs";
|
|
4291
|
+
import chalk47 from "chalk";
|
|
4233
4292
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4234
4293
|
if (!window.location.pathname.endsWith('/')) {
|
|
4235
4294
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4237,23 +4296,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4237
4296
|
</script>`;
|
|
4238
4297
|
function redirect() {
|
|
4239
4298
|
const indexPath = "index.html";
|
|
4240
|
-
if (!
|
|
4241
|
-
console.log(
|
|
4299
|
+
if (!existsSync21(indexPath)) {
|
|
4300
|
+
console.log(chalk47.yellow("No index.html found"));
|
|
4242
4301
|
return;
|
|
4243
4302
|
}
|
|
4244
4303
|
const content = readFileSync16(indexPath, "utf-8");
|
|
4245
4304
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4246
|
-
console.log(
|
|
4305
|
+
console.log(chalk47.dim("Trailing slash script already present"));
|
|
4247
4306
|
return;
|
|
4248
4307
|
}
|
|
4249
4308
|
const headCloseIndex = content.indexOf("</head>");
|
|
4250
4309
|
if (headCloseIndex === -1) {
|
|
4251
|
-
console.log(
|
|
4310
|
+
console.log(chalk47.red("Could not find </head> tag in index.html"));
|
|
4252
4311
|
return;
|
|
4253
4312
|
}
|
|
4254
4313
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4255
4314
|
writeFileSync16(indexPath, newContent);
|
|
4256
|
-
console.log(
|
|
4315
|
+
console.log(chalk47.green("Added trailing slash redirect to index.html"));
|
|
4257
4316
|
}
|
|
4258
4317
|
|
|
4259
4318
|
// src/commands/registerDeploy.ts
|
|
@@ -4280,7 +4339,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
4280
4339
|
|
|
4281
4340
|
// src/commands/devlog/shared.ts
|
|
4282
4341
|
import { execSync as execSync15 } from "child_process";
|
|
4283
|
-
import
|
|
4342
|
+
import chalk48 from "chalk";
|
|
4284
4343
|
|
|
4285
4344
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4286
4345
|
import { readdirSync, readFileSync as readFileSync17 } from "fs";
|
|
@@ -4367,13 +4426,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4367
4426
|
}
|
|
4368
4427
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4369
4428
|
for (const commit2 of commits) {
|
|
4370
|
-
console.log(` ${
|
|
4429
|
+
console.log(` ${chalk48.yellow(commit2.hash)} ${commit2.message}`);
|
|
4371
4430
|
if (verbose) {
|
|
4372
4431
|
const visibleFiles = commit2.files.filter(
|
|
4373
4432
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4374
4433
|
);
|
|
4375
4434
|
for (const file of visibleFiles) {
|
|
4376
|
-
console.log(` ${
|
|
4435
|
+
console.log(` ${chalk48.dim(file)}`);
|
|
4377
4436
|
}
|
|
4378
4437
|
}
|
|
4379
4438
|
}
|
|
@@ -4398,15 +4457,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4398
4457
|
}
|
|
4399
4458
|
|
|
4400
4459
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4401
|
-
import
|
|
4460
|
+
import chalk49 from "chalk";
|
|
4402
4461
|
function printDateHeader(date, isSkipped, entries) {
|
|
4403
4462
|
if (isSkipped) {
|
|
4404
|
-
console.log(`${
|
|
4463
|
+
console.log(`${chalk49.bold.blue(date)} ${chalk49.dim("skipped")}`);
|
|
4405
4464
|
} else if (entries && entries.length > 0) {
|
|
4406
|
-
const entryInfo = entries.map((e) => `${
|
|
4407
|
-
console.log(`${
|
|
4465
|
+
const entryInfo = entries.map((e) => `${chalk49.green(e.version)} ${e.title}`).join(" | ");
|
|
4466
|
+
console.log(`${chalk49.bold.blue(date)} ${entryInfo}`);
|
|
4408
4467
|
} else {
|
|
4409
|
-
console.log(`${
|
|
4468
|
+
console.log(`${chalk49.bold.blue(date)} ${chalk49.red("\u26A0 devlog missing")}`);
|
|
4410
4469
|
}
|
|
4411
4470
|
}
|
|
4412
4471
|
|
|
@@ -4509,24 +4568,24 @@ function bumpVersion(version2, type) {
|
|
|
4509
4568
|
|
|
4510
4569
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
4511
4570
|
import { execSync as execSync18 } from "child_process";
|
|
4512
|
-
import
|
|
4571
|
+
import chalk51 from "chalk";
|
|
4513
4572
|
|
|
4514
4573
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
4515
|
-
import
|
|
4574
|
+
import chalk50 from "chalk";
|
|
4516
4575
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
4517
4576
|
if (conventional && firstHash) {
|
|
4518
4577
|
const version2 = getVersionAtCommit(firstHash);
|
|
4519
4578
|
if (version2) {
|
|
4520
|
-
console.log(`${
|
|
4579
|
+
console.log(`${chalk50.bold("version:")} ${stripToMinor(version2)}`);
|
|
4521
4580
|
} else {
|
|
4522
|
-
console.log(`${
|
|
4581
|
+
console.log(`${chalk50.bold("version:")} ${chalk50.red("unknown")}`);
|
|
4523
4582
|
}
|
|
4524
4583
|
} else if (patchVersion && minorVersion) {
|
|
4525
4584
|
console.log(
|
|
4526
|
-
`${
|
|
4585
|
+
`${chalk50.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
4527
4586
|
);
|
|
4528
4587
|
} else {
|
|
4529
|
-
console.log(`${
|
|
4588
|
+
console.log(`${chalk50.bold("version:")} v0.1 (initial)`);
|
|
4530
4589
|
}
|
|
4531
4590
|
}
|
|
4532
4591
|
|
|
@@ -4573,16 +4632,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
4573
4632
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
4574
4633
|
}
|
|
4575
4634
|
function logName(repoName) {
|
|
4576
|
-
console.log(`${
|
|
4635
|
+
console.log(`${chalk51.bold("name:")} ${repoName}`);
|
|
4577
4636
|
}
|
|
4578
4637
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
4579
4638
|
logName(ctx.repoName);
|
|
4580
4639
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
4581
|
-
console.log(
|
|
4640
|
+
console.log(chalk51.bold.blue(targetDate));
|
|
4582
4641
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
4583
4642
|
}
|
|
4584
4643
|
function logNoCommits(lastInfo) {
|
|
4585
|
-
console.log(
|
|
4644
|
+
console.log(chalk51.dim(noCommitsMessage(!!lastInfo)));
|
|
4586
4645
|
}
|
|
4587
4646
|
|
|
4588
4647
|
// src/commands/devlog/next/index.ts
|
|
@@ -4623,11 +4682,11 @@ function next2(options2) {
|
|
|
4623
4682
|
import { execSync as execSync19 } from "child_process";
|
|
4624
4683
|
|
|
4625
4684
|
// src/commands/devlog/repos/printReposTable.ts
|
|
4626
|
-
import
|
|
4685
|
+
import chalk52 from "chalk";
|
|
4627
4686
|
function colorStatus(status2) {
|
|
4628
|
-
if (status2 === "missing") return
|
|
4629
|
-
if (status2 === "outdated") return
|
|
4630
|
-
return
|
|
4687
|
+
if (status2 === "missing") return chalk52.red(status2);
|
|
4688
|
+
if (status2 === "outdated") return chalk52.yellow(status2);
|
|
4689
|
+
return chalk52.green(status2);
|
|
4631
4690
|
}
|
|
4632
4691
|
function formatRow(row, nameWidth) {
|
|
4633
4692
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -4641,8 +4700,8 @@ function printReposTable(rows) {
|
|
|
4641
4700
|
"Last Devlog".padEnd(11),
|
|
4642
4701
|
"Status"
|
|
4643
4702
|
].join(" ");
|
|
4644
|
-
console.log(
|
|
4645
|
-
console.log(
|
|
4703
|
+
console.log(chalk52.dim(header));
|
|
4704
|
+
console.log(chalk52.dim("-".repeat(header.length)));
|
|
4646
4705
|
for (const row of rows) {
|
|
4647
4706
|
console.log(formatRow(row, nameWidth));
|
|
4648
4707
|
}
|
|
@@ -4700,14 +4759,14 @@ function repos(options2) {
|
|
|
4700
4759
|
// src/commands/devlog/skip.ts
|
|
4701
4760
|
import { writeFileSync as writeFileSync17 } from "fs";
|
|
4702
4761
|
import { join as join16 } from "path";
|
|
4703
|
-
import
|
|
4762
|
+
import chalk53 from "chalk";
|
|
4704
4763
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
4705
4764
|
function getBlogConfigPath() {
|
|
4706
4765
|
return join16(BLOG_REPO_ROOT, "assist.yml");
|
|
4707
4766
|
}
|
|
4708
4767
|
function skip(date) {
|
|
4709
4768
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
4710
|
-
console.log(
|
|
4769
|
+
console.log(chalk53.red("Invalid date format. Use YYYY-MM-DD"));
|
|
4711
4770
|
process.exit(1);
|
|
4712
4771
|
}
|
|
4713
4772
|
const repoName = getRepoName();
|
|
@@ -4718,7 +4777,7 @@ function skip(date) {
|
|
|
4718
4777
|
const skipDays = skip2[repoName] ?? [];
|
|
4719
4778
|
if (skipDays.includes(date)) {
|
|
4720
4779
|
console.log(
|
|
4721
|
-
|
|
4780
|
+
chalk53.yellow(`${date} is already in skip list for ${repoName}`)
|
|
4722
4781
|
);
|
|
4723
4782
|
return;
|
|
4724
4783
|
}
|
|
@@ -4728,20 +4787,20 @@ function skip(date) {
|
|
|
4728
4787
|
devlog.skip = skip2;
|
|
4729
4788
|
config.devlog = devlog;
|
|
4730
4789
|
writeFileSync17(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
4731
|
-
console.log(
|
|
4790
|
+
console.log(chalk53.green(`Added ${date} to skip list for ${repoName}`));
|
|
4732
4791
|
}
|
|
4733
4792
|
|
|
4734
4793
|
// src/commands/devlog/version.ts
|
|
4735
|
-
import
|
|
4794
|
+
import chalk54 from "chalk";
|
|
4736
4795
|
function version() {
|
|
4737
4796
|
const config = loadConfig();
|
|
4738
4797
|
const name = getRepoName();
|
|
4739
4798
|
const lastInfo = getLastVersionInfo(name, config);
|
|
4740
4799
|
const lastVersion = lastInfo?.version ?? null;
|
|
4741
4800
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
4742
|
-
console.log(`${
|
|
4743
|
-
console.log(`${
|
|
4744
|
-
console.log(`${
|
|
4801
|
+
console.log(`${chalk54.bold("name:")} ${name}`);
|
|
4802
|
+
console.log(`${chalk54.bold("last:")} ${lastVersion ?? chalk54.dim("none")}`);
|
|
4803
|
+
console.log(`${chalk54.bold("next:")} ${nextVersion ?? chalk54.dim("none")}`);
|
|
4745
4804
|
}
|
|
4746
4805
|
|
|
4747
4806
|
// src/commands/registerDevlog.ts
|
|
@@ -4765,15 +4824,15 @@ function registerDevlog(program2) {
|
|
|
4765
4824
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
4766
4825
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
4767
4826
|
import { join as join17 } from "path";
|
|
4768
|
-
import
|
|
4827
|
+
import chalk55 from "chalk";
|
|
4769
4828
|
|
|
4770
4829
|
// src/shared/findRepoRoot.ts
|
|
4771
|
-
import { existsSync as
|
|
4830
|
+
import { existsSync as existsSync22 } from "fs";
|
|
4772
4831
|
import path21 from "path";
|
|
4773
4832
|
function findRepoRoot(dir) {
|
|
4774
4833
|
let current = dir;
|
|
4775
4834
|
while (current !== path21.dirname(current)) {
|
|
4776
|
-
if (
|
|
4835
|
+
if (existsSync22(path21.join(current, ".git"))) {
|
|
4777
4836
|
return current;
|
|
4778
4837
|
}
|
|
4779
4838
|
current = path21.dirname(current);
|
|
@@ -4828,14 +4887,14 @@ function checkBuildLocks(startDir) {
|
|
|
4828
4887
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
4829
4888
|
if (locked) {
|
|
4830
4889
|
console.error(
|
|
4831
|
-
|
|
4890
|
+
chalk55.red("Build output locked (is VS debugging?): ") + locked
|
|
4832
4891
|
);
|
|
4833
4892
|
process.exit(1);
|
|
4834
4893
|
}
|
|
4835
4894
|
}
|
|
4836
4895
|
async function checkBuildLocksCommand() {
|
|
4837
4896
|
checkBuildLocks();
|
|
4838
|
-
console.log(
|
|
4897
|
+
console.log(chalk55.green("No build locks detected"));
|
|
4839
4898
|
}
|
|
4840
4899
|
|
|
4841
4900
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -4934,30 +4993,30 @@ function escapeRegex(s) {
|
|
|
4934
4993
|
}
|
|
4935
4994
|
|
|
4936
4995
|
// src/commands/dotnet/printTree.ts
|
|
4937
|
-
import
|
|
4996
|
+
import chalk56 from "chalk";
|
|
4938
4997
|
function printNodes(nodes, prefix2) {
|
|
4939
4998
|
for (let i = 0; i < nodes.length; i++) {
|
|
4940
4999
|
const isLast = i === nodes.length - 1;
|
|
4941
5000
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
4942
5001
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
4943
5002
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
4944
|
-
const label2 = isMissing ?
|
|
5003
|
+
const label2 = isMissing ? chalk56.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
4945
5004
|
console.log(`${prefix2}${connector}${label2}`);
|
|
4946
5005
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
4947
5006
|
}
|
|
4948
5007
|
}
|
|
4949
5008
|
function printTree(tree, totalCount, solutions) {
|
|
4950
|
-
console.log(
|
|
4951
|
-
console.log(
|
|
5009
|
+
console.log(chalk56.bold("\nProject Dependency Tree"));
|
|
5010
|
+
console.log(chalk56.cyan(tree.relativePath));
|
|
4952
5011
|
printNodes(tree.children, "");
|
|
4953
|
-
console.log(
|
|
5012
|
+
console.log(chalk56.dim(`
|
|
4954
5013
|
${totalCount} projects total (including root)`));
|
|
4955
|
-
console.log(
|
|
5014
|
+
console.log(chalk56.bold("\nSolution Membership"));
|
|
4956
5015
|
if (solutions.length === 0) {
|
|
4957
|
-
console.log(
|
|
5016
|
+
console.log(chalk56.yellow(" Not found in any .sln"));
|
|
4958
5017
|
} else {
|
|
4959
5018
|
for (const sln of solutions) {
|
|
4960
|
-
console.log(` ${
|
|
5019
|
+
console.log(` ${chalk56.green(sln)}`);
|
|
4961
5020
|
}
|
|
4962
5021
|
}
|
|
4963
5022
|
console.log();
|
|
@@ -4984,18 +5043,18 @@ function printJson(tree, totalCount, solutions) {
|
|
|
4984
5043
|
}
|
|
4985
5044
|
|
|
4986
5045
|
// src/commands/dotnet/resolveCsproj.ts
|
|
4987
|
-
import { existsSync as
|
|
5046
|
+
import { existsSync as existsSync23 } from "fs";
|
|
4988
5047
|
import path24 from "path";
|
|
4989
|
-
import
|
|
5048
|
+
import chalk57 from "chalk";
|
|
4990
5049
|
function resolveCsproj(csprojPath) {
|
|
4991
5050
|
const resolved = path24.resolve(csprojPath);
|
|
4992
|
-
if (!
|
|
4993
|
-
console.error(
|
|
5051
|
+
if (!existsSync23(resolved)) {
|
|
5052
|
+
console.error(chalk57.red(`File not found: ${resolved}`));
|
|
4994
5053
|
process.exit(1);
|
|
4995
5054
|
}
|
|
4996
5055
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
4997
5056
|
if (!repoRoot) {
|
|
4998
|
-
console.error(
|
|
5057
|
+
console.error(chalk57.red("Could not find git repository root"));
|
|
4999
5058
|
process.exit(1);
|
|
5000
5059
|
}
|
|
5001
5060
|
return { resolved, repoRoot };
|
|
@@ -5045,12 +5104,12 @@ function getChangedCsFiles(scope) {
|
|
|
5045
5104
|
}
|
|
5046
5105
|
|
|
5047
5106
|
// src/commands/dotnet/inSln.ts
|
|
5048
|
-
import
|
|
5107
|
+
import chalk58 from "chalk";
|
|
5049
5108
|
async function inSln(csprojPath) {
|
|
5050
5109
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5051
5110
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5052
5111
|
if (solutions.length === 0) {
|
|
5053
|
-
console.log(
|
|
5112
|
+
console.log(chalk58.yellow("Not found in any .sln file"));
|
|
5054
5113
|
process.exit(1);
|
|
5055
5114
|
}
|
|
5056
5115
|
for (const sln of solutions) {
|
|
@@ -5059,7 +5118,7 @@ async function inSln(csprojPath) {
|
|
|
5059
5118
|
}
|
|
5060
5119
|
|
|
5061
5120
|
// src/commands/dotnet/inspect.ts
|
|
5062
|
-
import
|
|
5121
|
+
import chalk64 from "chalk";
|
|
5063
5122
|
|
|
5064
5123
|
// src/shared/formatElapsed.ts
|
|
5065
5124
|
function formatElapsed(ms) {
|
|
@@ -5071,12 +5130,12 @@ function formatElapsed(ms) {
|
|
|
5071
5130
|
}
|
|
5072
5131
|
|
|
5073
5132
|
// src/commands/dotnet/displayIssues.ts
|
|
5074
|
-
import
|
|
5133
|
+
import chalk59 from "chalk";
|
|
5075
5134
|
var SEVERITY_COLOR = {
|
|
5076
|
-
ERROR:
|
|
5077
|
-
WARNING:
|
|
5078
|
-
SUGGESTION:
|
|
5079
|
-
HINT:
|
|
5135
|
+
ERROR: chalk59.red,
|
|
5136
|
+
WARNING: chalk59.yellow,
|
|
5137
|
+
SUGGESTION: chalk59.cyan,
|
|
5138
|
+
HINT: chalk59.dim
|
|
5080
5139
|
};
|
|
5081
5140
|
function groupByFile(issues) {
|
|
5082
5141
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5092,15 +5151,15 @@ function groupByFile(issues) {
|
|
|
5092
5151
|
}
|
|
5093
5152
|
function displayIssues(issues) {
|
|
5094
5153
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5095
|
-
console.log(
|
|
5154
|
+
console.log(chalk59.bold(file));
|
|
5096
5155
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5097
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5156
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk59.white;
|
|
5098
5157
|
console.log(
|
|
5099
|
-
` ${
|
|
5158
|
+
` ${chalk59.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5100
5159
|
);
|
|
5101
5160
|
}
|
|
5102
5161
|
}
|
|
5103
|
-
console.log(
|
|
5162
|
+
console.log(chalk59.dim(`
|
|
5104
5163
|
${issues.length} issue(s) found`));
|
|
5105
5164
|
}
|
|
5106
5165
|
|
|
@@ -5157,14 +5216,14 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5157
5216
|
}
|
|
5158
5217
|
|
|
5159
5218
|
// src/commands/dotnet/resolveSolution.ts
|
|
5160
|
-
import { existsSync as
|
|
5219
|
+
import { existsSync as existsSync24 } from "fs";
|
|
5161
5220
|
import path25 from "path";
|
|
5162
|
-
import
|
|
5221
|
+
import chalk61 from "chalk";
|
|
5163
5222
|
|
|
5164
5223
|
// src/commands/dotnet/findSolution.ts
|
|
5165
5224
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5166
5225
|
import { dirname as dirname16, join as join18 } from "path";
|
|
5167
|
-
import
|
|
5226
|
+
import chalk60 from "chalk";
|
|
5168
5227
|
function findSlnInDir(dir) {
|
|
5169
5228
|
try {
|
|
5170
5229
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join18(dir, f));
|
|
@@ -5180,17 +5239,17 @@ function findSolution() {
|
|
|
5180
5239
|
const slnFiles = findSlnInDir(current);
|
|
5181
5240
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5182
5241
|
if (slnFiles.length > 1) {
|
|
5183
|
-
console.error(
|
|
5242
|
+
console.error(chalk60.red(`Multiple .sln files found in ${current}:`));
|
|
5184
5243
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5185
5244
|
console.error(
|
|
5186
|
-
|
|
5245
|
+
chalk60.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5187
5246
|
);
|
|
5188
5247
|
process.exit(1);
|
|
5189
5248
|
}
|
|
5190
5249
|
if (current === ceiling) break;
|
|
5191
5250
|
current = dirname16(current);
|
|
5192
5251
|
}
|
|
5193
|
-
console.error(
|
|
5252
|
+
console.error(chalk60.red("No .sln file found between cwd and repo root"));
|
|
5194
5253
|
process.exit(1);
|
|
5195
5254
|
}
|
|
5196
5255
|
|
|
@@ -5198,8 +5257,8 @@ function findSolution() {
|
|
|
5198
5257
|
function resolveSolution(sln) {
|
|
5199
5258
|
if (sln) {
|
|
5200
5259
|
const resolved = path25.resolve(sln);
|
|
5201
|
-
if (!
|
|
5202
|
-
console.error(
|
|
5260
|
+
if (!existsSync24(resolved)) {
|
|
5261
|
+
console.error(chalk61.red(`Solution file not found: ${resolved}`));
|
|
5203
5262
|
process.exit(1);
|
|
5204
5263
|
}
|
|
5205
5264
|
return resolved;
|
|
@@ -5238,17 +5297,17 @@ function parseInspectReport(json) {
|
|
|
5238
5297
|
|
|
5239
5298
|
// src/commands/dotnet/runInspectCode.ts
|
|
5240
5299
|
import { execSync as execSync21 } from "child_process";
|
|
5241
|
-
import { existsSync as
|
|
5300
|
+
import { existsSync as existsSync25, readFileSync as readFileSync20, unlinkSync as unlinkSync4 } from "fs";
|
|
5242
5301
|
import { tmpdir as tmpdir2 } from "os";
|
|
5243
5302
|
import path26 from "path";
|
|
5244
|
-
import
|
|
5303
|
+
import chalk62 from "chalk";
|
|
5245
5304
|
function assertJbInstalled() {
|
|
5246
5305
|
try {
|
|
5247
5306
|
execSync21("jb inspectcode --version", { stdio: "pipe" });
|
|
5248
5307
|
} catch {
|
|
5249
|
-
console.error(
|
|
5308
|
+
console.error(chalk62.red("jb is not installed. Install with:"));
|
|
5250
5309
|
console.error(
|
|
5251
|
-
|
|
5310
|
+
chalk62.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5252
5311
|
);
|
|
5253
5312
|
process.exit(1);
|
|
5254
5313
|
}
|
|
@@ -5266,11 +5325,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5266
5325
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5267
5326
|
process.stderr.write(err.stderr);
|
|
5268
5327
|
}
|
|
5269
|
-
console.error(
|
|
5328
|
+
console.error(chalk62.red("jb inspectcode failed"));
|
|
5270
5329
|
process.exit(1);
|
|
5271
5330
|
}
|
|
5272
|
-
if (!
|
|
5273
|
-
console.error(
|
|
5331
|
+
if (!existsSync25(reportPath)) {
|
|
5332
|
+
console.error(chalk62.red("Report file not generated"));
|
|
5274
5333
|
process.exit(1);
|
|
5275
5334
|
}
|
|
5276
5335
|
const xml = readFileSync20(reportPath, "utf-8");
|
|
@@ -5280,7 +5339,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5280
5339
|
|
|
5281
5340
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5282
5341
|
import { execSync as execSync22 } from "child_process";
|
|
5283
|
-
import
|
|
5342
|
+
import chalk63 from "chalk";
|
|
5284
5343
|
function resolveMsbuildPath() {
|
|
5285
5344
|
const config = loadConfig();
|
|
5286
5345
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5291,9 +5350,9 @@ function assertMsbuildInstalled() {
|
|
|
5291
5350
|
try {
|
|
5292
5351
|
execSync22(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5293
5352
|
} catch {
|
|
5294
|
-
console.error(
|
|
5353
|
+
console.error(chalk63.red(`msbuild not found at: ${msbuild}`));
|
|
5295
5354
|
console.error(
|
|
5296
|
-
|
|
5355
|
+
chalk63.yellow(
|
|
5297
5356
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5298
5357
|
)
|
|
5299
5358
|
);
|
|
@@ -5340,17 +5399,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5340
5399
|
// src/commands/dotnet/inspect.ts
|
|
5341
5400
|
function logScope(changedFiles) {
|
|
5342
5401
|
if (changedFiles === null) {
|
|
5343
|
-
console.log(
|
|
5402
|
+
console.log(chalk64.dim("Inspecting full solution..."));
|
|
5344
5403
|
} else {
|
|
5345
5404
|
console.log(
|
|
5346
|
-
|
|
5405
|
+
chalk64.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5347
5406
|
);
|
|
5348
5407
|
}
|
|
5349
5408
|
}
|
|
5350
5409
|
function reportResults(issues, elapsed) {
|
|
5351
5410
|
if (issues.length > 0) displayIssues(issues);
|
|
5352
|
-
else console.log(
|
|
5353
|
-
console.log(
|
|
5411
|
+
else console.log(chalk64.green("No issues found"));
|
|
5412
|
+
console.log(chalk64.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5354
5413
|
if (issues.length > 0) process.exit(1);
|
|
5355
5414
|
}
|
|
5356
5415
|
async function inspect(sln, options2) {
|
|
@@ -5361,7 +5420,7 @@ async function inspect(sln, options2) {
|
|
|
5361
5420
|
const scope = parseScope(options2.scope);
|
|
5362
5421
|
const changedFiles = getChangedCsFiles(scope);
|
|
5363
5422
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5364
|
-
console.log(
|
|
5423
|
+
console.log(chalk64.green("No changed .cs files found"));
|
|
5365
5424
|
return;
|
|
5366
5425
|
}
|
|
5367
5426
|
logScope(changedFiles);
|
|
@@ -5387,7 +5446,7 @@ function registerDotnet(program2) {
|
|
|
5387
5446
|
}
|
|
5388
5447
|
|
|
5389
5448
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5390
|
-
import
|
|
5449
|
+
import chalk66 from "chalk";
|
|
5391
5450
|
|
|
5392
5451
|
// src/commands/jira/adfToText.ts
|
|
5393
5452
|
function renderInline(node) {
|
|
@@ -5448,7 +5507,7 @@ function adfToText(doc) {
|
|
|
5448
5507
|
|
|
5449
5508
|
// src/commands/jira/fetchIssue.ts
|
|
5450
5509
|
import { execSync as execSync23 } from "child_process";
|
|
5451
|
-
import
|
|
5510
|
+
import chalk65 from "chalk";
|
|
5452
5511
|
function fetchIssue(issueKey, fields) {
|
|
5453
5512
|
let result;
|
|
5454
5513
|
try {
|
|
@@ -5461,15 +5520,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
5461
5520
|
const stderr = error.stderr;
|
|
5462
5521
|
if (stderr.includes("unauthorized")) {
|
|
5463
5522
|
console.error(
|
|
5464
|
-
|
|
5523
|
+
chalk65.red("Jira authentication expired."),
|
|
5465
5524
|
"Run",
|
|
5466
|
-
|
|
5525
|
+
chalk65.cyan("assist jira auth"),
|
|
5467
5526
|
"to re-authenticate."
|
|
5468
5527
|
);
|
|
5469
5528
|
process.exit(1);
|
|
5470
5529
|
}
|
|
5471
5530
|
}
|
|
5472
|
-
console.error(
|
|
5531
|
+
console.error(chalk65.red(`Failed to fetch ${issueKey}.`));
|
|
5473
5532
|
process.exit(1);
|
|
5474
5533
|
}
|
|
5475
5534
|
return JSON.parse(result);
|
|
@@ -5483,7 +5542,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5483
5542
|
const parsed = fetchIssue(issueKey, field);
|
|
5484
5543
|
const acValue = parsed?.fields?.[field];
|
|
5485
5544
|
if (!acValue) {
|
|
5486
|
-
console.log(
|
|
5545
|
+
console.log(chalk66.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
5487
5546
|
return;
|
|
5488
5547
|
}
|
|
5489
5548
|
if (typeof acValue === "string") {
|
|
@@ -5501,7 +5560,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5501
5560
|
import { execSync as execSync24 } from "child_process";
|
|
5502
5561
|
|
|
5503
5562
|
// src/shared/loadJson.ts
|
|
5504
|
-
import { existsSync as
|
|
5563
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync5, readFileSync as readFileSync21, writeFileSync as writeFileSync18 } from "fs";
|
|
5505
5564
|
import { homedir as homedir6 } from "os";
|
|
5506
5565
|
import { join as join19 } from "path";
|
|
5507
5566
|
function getStoreDir() {
|
|
@@ -5512,7 +5571,7 @@ function getStorePath(filename) {
|
|
|
5512
5571
|
}
|
|
5513
5572
|
function loadJson(filename) {
|
|
5514
5573
|
const path44 = getStorePath(filename);
|
|
5515
|
-
if (
|
|
5574
|
+
if (existsSync26(path44)) {
|
|
5516
5575
|
try {
|
|
5517
5576
|
return JSON.parse(readFileSync21(path44, "utf-8"));
|
|
5518
5577
|
} catch {
|
|
@@ -5523,7 +5582,7 @@ function loadJson(filename) {
|
|
|
5523
5582
|
}
|
|
5524
5583
|
function saveJson(filename, data) {
|
|
5525
5584
|
const dir = getStoreDir();
|
|
5526
|
-
if (!
|
|
5585
|
+
if (!existsSync26(dir)) {
|
|
5527
5586
|
mkdirSync5(dir, { recursive: true });
|
|
5528
5587
|
}
|
|
5529
5588
|
writeFileSync18(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
@@ -5578,14 +5637,14 @@ async function jiraAuth() {
|
|
|
5578
5637
|
}
|
|
5579
5638
|
|
|
5580
5639
|
// src/commands/jira/viewIssue.ts
|
|
5581
|
-
import
|
|
5640
|
+
import chalk67 from "chalk";
|
|
5582
5641
|
function viewIssue(issueKey) {
|
|
5583
5642
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
5584
5643
|
const fields = parsed?.fields;
|
|
5585
5644
|
const summary = fields?.summary;
|
|
5586
5645
|
const description = fields?.description;
|
|
5587
5646
|
if (summary) {
|
|
5588
|
-
console.log(
|
|
5647
|
+
console.log(chalk67.bold(summary));
|
|
5589
5648
|
}
|
|
5590
5649
|
if (description) {
|
|
5591
5650
|
if (summary) console.log();
|
|
@@ -5599,7 +5658,7 @@ function viewIssue(issueKey) {
|
|
|
5599
5658
|
}
|
|
5600
5659
|
if (!summary && !description) {
|
|
5601
5660
|
console.log(
|
|
5602
|
-
|
|
5661
|
+
chalk67.yellow(`No summary or description found on ${issueKey}.`)
|
|
5603
5662
|
);
|
|
5604
5663
|
}
|
|
5605
5664
|
}
|
|
@@ -5613,7 +5672,7 @@ function registerJira(program2) {
|
|
|
5613
5672
|
}
|
|
5614
5673
|
|
|
5615
5674
|
// src/commands/news/add/index.ts
|
|
5616
|
-
import
|
|
5675
|
+
import chalk68 from "chalk";
|
|
5617
5676
|
import enquirer7 from "enquirer";
|
|
5618
5677
|
async function add2(url) {
|
|
5619
5678
|
if (!url) {
|
|
@@ -5636,17 +5695,17 @@ async function add2(url) {
|
|
|
5636
5695
|
const news = config.news ?? {};
|
|
5637
5696
|
const feeds = news.feeds ?? [];
|
|
5638
5697
|
if (feeds.includes(url)) {
|
|
5639
|
-
console.log(
|
|
5698
|
+
console.log(chalk68.yellow("Feed already exists in config"));
|
|
5640
5699
|
return;
|
|
5641
5700
|
}
|
|
5642
5701
|
feeds.push(url);
|
|
5643
5702
|
config.news = { ...news, feeds };
|
|
5644
5703
|
saveGlobalConfig(config);
|
|
5645
|
-
console.log(
|
|
5704
|
+
console.log(chalk68.green(`Added feed: ${url}`));
|
|
5646
5705
|
}
|
|
5647
5706
|
|
|
5648
5707
|
// src/commands/news/web/handleRequest.ts
|
|
5649
|
-
import
|
|
5708
|
+
import chalk69 from "chalk";
|
|
5650
5709
|
|
|
5651
5710
|
// src/commands/news/web/shared.ts
|
|
5652
5711
|
import { decodeHTML } from "entities";
|
|
@@ -5782,17 +5841,17 @@ function prefetch() {
|
|
|
5782
5841
|
const config = loadConfig();
|
|
5783
5842
|
const total = config.news.feeds.length;
|
|
5784
5843
|
if (total === 0) return;
|
|
5785
|
-
process.stdout.write(
|
|
5844
|
+
process.stdout.write(chalk69.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
5786
5845
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
5787
5846
|
const width = 20;
|
|
5788
5847
|
const filled = Math.round(done2 / t * width);
|
|
5789
5848
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
5790
5849
|
process.stdout.write(
|
|
5791
|
-
`\r${
|
|
5850
|
+
`\r${chalk69.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
5792
5851
|
);
|
|
5793
5852
|
}).then((items) => {
|
|
5794
5853
|
process.stdout.write(
|
|
5795
|
-
`\r${
|
|
5854
|
+
`\r${chalk69.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
5796
5855
|
`
|
|
5797
5856
|
);
|
|
5798
5857
|
cachedItems = items;
|
|
@@ -5960,7 +6019,7 @@ import { tmpdir as tmpdir4 } from "os";
|
|
|
5960
6019
|
import { join as join22 } from "path";
|
|
5961
6020
|
|
|
5962
6021
|
// src/commands/prs/loadCommentsCache.ts
|
|
5963
|
-
import { existsSync as
|
|
6022
|
+
import { existsSync as existsSync27, readFileSync as readFileSync22, unlinkSync as unlinkSync6 } from "fs";
|
|
5964
6023
|
import { join as join21 } from "path";
|
|
5965
6024
|
import { parse as parse2 } from "yaml";
|
|
5966
6025
|
function getCachePath(prNumber) {
|
|
@@ -5968,7 +6027,7 @@ function getCachePath(prNumber) {
|
|
|
5968
6027
|
}
|
|
5969
6028
|
function loadCommentsCache(prNumber) {
|
|
5970
6029
|
const cachePath = getCachePath(prNumber);
|
|
5971
|
-
if (!
|
|
6030
|
+
if (!existsSync27(cachePath)) {
|
|
5972
6031
|
return null;
|
|
5973
6032
|
}
|
|
5974
6033
|
const content = readFileSync22(cachePath, "utf-8");
|
|
@@ -5976,7 +6035,7 @@ function loadCommentsCache(prNumber) {
|
|
|
5976
6035
|
}
|
|
5977
6036
|
function deleteCommentsCache(prNumber) {
|
|
5978
6037
|
const cachePath = getCachePath(prNumber);
|
|
5979
|
-
if (
|
|
6038
|
+
if (existsSync27(cachePath)) {
|
|
5980
6039
|
unlinkSync6(cachePath);
|
|
5981
6040
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
5982
6041
|
}
|
|
@@ -6073,7 +6132,7 @@ function fixed(commentId, sha) {
|
|
|
6073
6132
|
}
|
|
6074
6133
|
|
|
6075
6134
|
// src/commands/prs/listComments/index.ts
|
|
6076
|
-
import { existsSync as
|
|
6135
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync6, writeFileSync as writeFileSync22 } from "fs";
|
|
6077
6136
|
import { join as join24 } from "path";
|
|
6078
6137
|
import { stringify } from "yaml";
|
|
6079
6138
|
|
|
@@ -6153,20 +6212,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6153
6212
|
}
|
|
6154
6213
|
|
|
6155
6214
|
// src/commands/prs/listComments/printComments.ts
|
|
6156
|
-
import
|
|
6215
|
+
import chalk70 from "chalk";
|
|
6157
6216
|
function formatForHuman(comment2) {
|
|
6158
6217
|
if (comment2.type === "review") {
|
|
6159
|
-
const stateColor = comment2.state === "APPROVED" ?
|
|
6218
|
+
const stateColor = comment2.state === "APPROVED" ? chalk70.green : comment2.state === "CHANGES_REQUESTED" ? chalk70.red : chalk70.yellow;
|
|
6160
6219
|
return [
|
|
6161
|
-
`${
|
|
6220
|
+
`${chalk70.cyan("Review")} by ${chalk70.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
|
|
6162
6221
|
comment2.body,
|
|
6163
6222
|
""
|
|
6164
6223
|
].join("\n");
|
|
6165
6224
|
}
|
|
6166
6225
|
const location = comment2.line ? `:${comment2.line}` : "";
|
|
6167
6226
|
return [
|
|
6168
|
-
`${
|
|
6169
|
-
|
|
6227
|
+
`${chalk70.cyan("Line comment")} by ${chalk70.bold(comment2.user)} on ${chalk70.dim(`${comment2.path}${location}`)}`,
|
|
6228
|
+
chalk70.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6170
6229
|
comment2.body,
|
|
6171
6230
|
""
|
|
6172
6231
|
].join("\n");
|
|
@@ -6199,7 +6258,7 @@ function printComments(result) {
|
|
|
6199
6258
|
// src/commands/prs/listComments/index.ts
|
|
6200
6259
|
function writeCommentsCache(prNumber, comments) {
|
|
6201
6260
|
const assistDir = join24(process.cwd(), ".assist");
|
|
6202
|
-
if (!
|
|
6261
|
+
if (!existsSync28(assistDir)) {
|
|
6203
6262
|
mkdirSync6(assistDir, { recursive: true });
|
|
6204
6263
|
}
|
|
6205
6264
|
const cacheData = {
|
|
@@ -6256,13 +6315,13 @@ import { execSync as execSync30 } from "child_process";
|
|
|
6256
6315
|
import enquirer8 from "enquirer";
|
|
6257
6316
|
|
|
6258
6317
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6259
|
-
import
|
|
6318
|
+
import chalk71 from "chalk";
|
|
6260
6319
|
var STATUS_MAP = {
|
|
6261
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6262
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6320
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk71.magenta("merged"), date: pr.mergedAt } : null,
|
|
6321
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk71.red("closed"), date: pr.closedAt } : null
|
|
6263
6322
|
};
|
|
6264
6323
|
function defaultStatus(pr) {
|
|
6265
|
-
return { label:
|
|
6324
|
+
return { label: chalk71.green("opened"), date: pr.createdAt };
|
|
6266
6325
|
}
|
|
6267
6326
|
function getStatus2(pr) {
|
|
6268
6327
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6271,11 +6330,11 @@ function formatDate(dateStr) {
|
|
|
6271
6330
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6272
6331
|
}
|
|
6273
6332
|
function formatPrHeader(pr, status2) {
|
|
6274
|
-
return `${
|
|
6333
|
+
return `${chalk71.cyan(`#${pr.number}`)} ${pr.title} ${chalk71.dim(`(${pr.author.login},`)} ${status2.label} ${chalk71.dim(`${formatDate(status2.date)})`)}`;
|
|
6275
6334
|
}
|
|
6276
6335
|
function logPrDetails(pr) {
|
|
6277
6336
|
console.log(
|
|
6278
|
-
|
|
6337
|
+
chalk71.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6279
6338
|
);
|
|
6280
6339
|
console.log();
|
|
6281
6340
|
}
|
|
@@ -6441,10 +6500,10 @@ function registerPrs(program2) {
|
|
|
6441
6500
|
}
|
|
6442
6501
|
|
|
6443
6502
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6444
|
-
import
|
|
6503
|
+
import chalk77 from "chalk";
|
|
6445
6504
|
|
|
6446
6505
|
// src/shared/createConnectionAuth.ts
|
|
6447
|
-
import
|
|
6506
|
+
import chalk72 from "chalk";
|
|
6448
6507
|
function listConnections(connections, format2) {
|
|
6449
6508
|
if (connections.length === 0) {
|
|
6450
6509
|
console.log("No connections configured.");
|
|
@@ -6457,7 +6516,7 @@ function listConnections(connections, format2) {
|
|
|
6457
6516
|
function removeConnection(connections, name, save) {
|
|
6458
6517
|
const filtered = connections.filter((c) => c.name !== name);
|
|
6459
6518
|
if (filtered.length === connections.length) {
|
|
6460
|
-
console.error(
|
|
6519
|
+
console.error(chalk72.red(`Connection "${name}" not found.`));
|
|
6461
6520
|
process.exit(1);
|
|
6462
6521
|
}
|
|
6463
6522
|
save(filtered);
|
|
@@ -6503,15 +6562,15 @@ function saveConnections(connections) {
|
|
|
6503
6562
|
}
|
|
6504
6563
|
|
|
6505
6564
|
// src/commands/ravendb/promptConnection.ts
|
|
6506
|
-
import
|
|
6565
|
+
import chalk75 from "chalk";
|
|
6507
6566
|
|
|
6508
6567
|
// src/commands/ravendb/selectOpSecret.ts
|
|
6509
|
-
import
|
|
6568
|
+
import chalk74 from "chalk";
|
|
6510
6569
|
import Enquirer2 from "enquirer";
|
|
6511
6570
|
|
|
6512
6571
|
// src/commands/ravendb/searchItems.ts
|
|
6513
6572
|
import { execSync as execSync32 } from "child_process";
|
|
6514
|
-
import
|
|
6573
|
+
import chalk73 from "chalk";
|
|
6515
6574
|
function opExec(args) {
|
|
6516
6575
|
return execSync32(`op ${args}`, {
|
|
6517
6576
|
encoding: "utf-8",
|
|
@@ -6524,7 +6583,7 @@ function searchItems(search) {
|
|
|
6524
6583
|
items = JSON.parse(opExec("item list --format=json"));
|
|
6525
6584
|
} catch {
|
|
6526
6585
|
console.error(
|
|
6527
|
-
|
|
6586
|
+
chalk73.red(
|
|
6528
6587
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
6529
6588
|
)
|
|
6530
6589
|
);
|
|
@@ -6538,7 +6597,7 @@ function getItemFields(itemId) {
|
|
|
6538
6597
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
6539
6598
|
return item.fields.filter((f) => f.reference && f.label);
|
|
6540
6599
|
} catch {
|
|
6541
|
-
console.error(
|
|
6600
|
+
console.error(chalk73.red("Failed to get item details from 1Password."));
|
|
6542
6601
|
process.exit(1);
|
|
6543
6602
|
}
|
|
6544
6603
|
}
|
|
@@ -6557,7 +6616,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6557
6616
|
}).run();
|
|
6558
6617
|
const items = searchItems(search);
|
|
6559
6618
|
if (items.length === 0) {
|
|
6560
|
-
console.error(
|
|
6619
|
+
console.error(chalk74.red(`No items found matching "${search}".`));
|
|
6561
6620
|
process.exit(1);
|
|
6562
6621
|
}
|
|
6563
6622
|
const itemId = await selectOne(
|
|
@@ -6566,7 +6625,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6566
6625
|
);
|
|
6567
6626
|
const fields = getItemFields(itemId);
|
|
6568
6627
|
if (fields.length === 0) {
|
|
6569
|
-
console.error(
|
|
6628
|
+
console.error(chalk74.red("No fields with references found on this item."));
|
|
6570
6629
|
process.exit(1);
|
|
6571
6630
|
}
|
|
6572
6631
|
const ref = await selectOne(
|
|
@@ -6580,7 +6639,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6580
6639
|
async function promptConnection(existingNames) {
|
|
6581
6640
|
const name = await promptInput("name", "Connection name:");
|
|
6582
6641
|
if (existingNames.includes(name)) {
|
|
6583
|
-
console.error(
|
|
6642
|
+
console.error(chalk75.red(`Connection "${name}" already exists.`));
|
|
6584
6643
|
process.exit(1);
|
|
6585
6644
|
}
|
|
6586
6645
|
const url = await promptInput(
|
|
@@ -6589,22 +6648,22 @@ async function promptConnection(existingNames) {
|
|
|
6589
6648
|
);
|
|
6590
6649
|
const database = await promptInput("database", "Database name:");
|
|
6591
6650
|
if (!name || !url || !database) {
|
|
6592
|
-
console.error(
|
|
6651
|
+
console.error(chalk75.red("All fields are required."));
|
|
6593
6652
|
process.exit(1);
|
|
6594
6653
|
}
|
|
6595
6654
|
const apiKeyRef = await selectOpSecret();
|
|
6596
|
-
console.log(
|
|
6655
|
+
console.log(chalk75.dim(`Using: ${apiKeyRef}`));
|
|
6597
6656
|
return { name, url, database, apiKeyRef };
|
|
6598
6657
|
}
|
|
6599
6658
|
|
|
6600
6659
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
6601
|
-
import
|
|
6660
|
+
import chalk76 from "chalk";
|
|
6602
6661
|
function ravendbSetConnection(name) {
|
|
6603
6662
|
const raw = loadGlobalConfigRaw();
|
|
6604
6663
|
const ravendb = raw.ravendb ?? {};
|
|
6605
6664
|
const connections = ravendb.connections ?? [];
|
|
6606
6665
|
if (!connections.some((c) => c.name === name)) {
|
|
6607
|
-
console.error(
|
|
6666
|
+
console.error(chalk76.red(`Connection "${name}" not found.`));
|
|
6608
6667
|
console.error(
|
|
6609
6668
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6610
6669
|
);
|
|
@@ -6620,16 +6679,16 @@ function ravendbSetConnection(name) {
|
|
|
6620
6679
|
var ravendbAuth = createConnectionAuth({
|
|
6621
6680
|
load: loadConnections,
|
|
6622
6681
|
save: saveConnections,
|
|
6623
|
-
format: (c) => `${
|
|
6682
|
+
format: (c) => `${chalk77.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
6624
6683
|
promptNew: promptConnection,
|
|
6625
6684
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
6626
6685
|
});
|
|
6627
6686
|
|
|
6628
6687
|
// src/commands/ravendb/ravendbCollections.ts
|
|
6629
|
-
import
|
|
6688
|
+
import chalk81 from "chalk";
|
|
6630
6689
|
|
|
6631
6690
|
// src/commands/ravendb/ravenFetch.ts
|
|
6632
|
-
import
|
|
6691
|
+
import chalk79 from "chalk";
|
|
6633
6692
|
|
|
6634
6693
|
// src/commands/ravendb/getAccessToken.ts
|
|
6635
6694
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -6666,10 +6725,10 @@ ${errorText}`
|
|
|
6666
6725
|
|
|
6667
6726
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
6668
6727
|
import { execSync as execSync33 } from "child_process";
|
|
6669
|
-
import
|
|
6728
|
+
import chalk78 from "chalk";
|
|
6670
6729
|
function resolveOpSecret(reference) {
|
|
6671
6730
|
if (!reference.startsWith("op://")) {
|
|
6672
|
-
console.error(
|
|
6731
|
+
console.error(chalk78.red(`Invalid secret reference: must start with op://`));
|
|
6673
6732
|
process.exit(1);
|
|
6674
6733
|
}
|
|
6675
6734
|
try {
|
|
@@ -6679,7 +6738,7 @@ function resolveOpSecret(reference) {
|
|
|
6679
6738
|
}).trim();
|
|
6680
6739
|
} catch {
|
|
6681
6740
|
console.error(
|
|
6682
|
-
|
|
6741
|
+
chalk78.red(
|
|
6683
6742
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
6684
6743
|
)
|
|
6685
6744
|
);
|
|
@@ -6706,7 +6765,7 @@ async function ravenFetch(connection, path44) {
|
|
|
6706
6765
|
if (!response.ok) {
|
|
6707
6766
|
const body = await response.text();
|
|
6708
6767
|
console.error(
|
|
6709
|
-
|
|
6768
|
+
chalk79.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
6710
6769
|
);
|
|
6711
6770
|
console.error(body.substring(0, 500));
|
|
6712
6771
|
process.exit(1);
|
|
@@ -6715,7 +6774,7 @@ async function ravenFetch(connection, path44) {
|
|
|
6715
6774
|
}
|
|
6716
6775
|
|
|
6717
6776
|
// src/commands/ravendb/resolveConnection.ts
|
|
6718
|
-
import
|
|
6777
|
+
import chalk80 from "chalk";
|
|
6719
6778
|
function loadRavendb() {
|
|
6720
6779
|
const raw = loadGlobalConfigRaw();
|
|
6721
6780
|
const ravendb = raw.ravendb;
|
|
@@ -6729,7 +6788,7 @@ function resolveConnection(name) {
|
|
|
6729
6788
|
const connectionName = name ?? defaultConnection;
|
|
6730
6789
|
if (!connectionName) {
|
|
6731
6790
|
console.error(
|
|
6732
|
-
|
|
6791
|
+
chalk80.red(
|
|
6733
6792
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
6734
6793
|
)
|
|
6735
6794
|
);
|
|
@@ -6737,7 +6796,7 @@ function resolveConnection(name) {
|
|
|
6737
6796
|
}
|
|
6738
6797
|
const connection = connections.find((c) => c.name === connectionName);
|
|
6739
6798
|
if (!connection) {
|
|
6740
|
-
console.error(
|
|
6799
|
+
console.error(chalk80.red(`Connection "${connectionName}" not found.`));
|
|
6741
6800
|
console.error(
|
|
6742
6801
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6743
6802
|
);
|
|
@@ -6768,15 +6827,15 @@ async function ravendbCollections(connectionName) {
|
|
|
6768
6827
|
return;
|
|
6769
6828
|
}
|
|
6770
6829
|
for (const c of collections) {
|
|
6771
|
-
console.log(`${
|
|
6830
|
+
console.log(`${chalk81.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
6772
6831
|
}
|
|
6773
6832
|
}
|
|
6774
6833
|
|
|
6775
6834
|
// src/commands/ravendb/ravendbQuery.ts
|
|
6776
|
-
import
|
|
6835
|
+
import chalk83 from "chalk";
|
|
6777
6836
|
|
|
6778
6837
|
// src/commands/ravendb/fetchAllPages.ts
|
|
6779
|
-
import
|
|
6838
|
+
import chalk82 from "chalk";
|
|
6780
6839
|
|
|
6781
6840
|
// src/commands/ravendb/buildQueryPath.ts
|
|
6782
6841
|
function buildQueryPath(opts) {
|
|
@@ -6814,7 +6873,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
6814
6873
|
allResults.push(...results);
|
|
6815
6874
|
start3 += results.length;
|
|
6816
6875
|
process.stderr.write(
|
|
6817
|
-
`\r${
|
|
6876
|
+
`\r${chalk82.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
6818
6877
|
);
|
|
6819
6878
|
if (start3 >= totalResults) break;
|
|
6820
6879
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -6829,7 +6888,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
6829
6888
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
6830
6889
|
const resolved = resolveArgs(connectionName, collection);
|
|
6831
6890
|
if (!resolved.collection && !options2.query) {
|
|
6832
|
-
console.error(
|
|
6891
|
+
console.error(chalk83.red("Provide a collection name or --query filter."));
|
|
6833
6892
|
process.exit(1);
|
|
6834
6893
|
}
|
|
6835
6894
|
const { collection: col } = resolved;
|
|
@@ -6867,7 +6926,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
6867
6926
|
import * as path27 from "path";
|
|
6868
6927
|
|
|
6869
6928
|
// src/commands/refactor/logViolations.ts
|
|
6870
|
-
import
|
|
6929
|
+
import chalk84 from "chalk";
|
|
6871
6930
|
var DEFAULT_MAX_LINES = 100;
|
|
6872
6931
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
6873
6932
|
if (violations.length === 0) {
|
|
@@ -6876,43 +6935,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
6876
6935
|
}
|
|
6877
6936
|
return;
|
|
6878
6937
|
}
|
|
6879
|
-
console.error(
|
|
6938
|
+
console.error(chalk84.red(`
|
|
6880
6939
|
Refactor check failed:
|
|
6881
6940
|
`));
|
|
6882
|
-
console.error(
|
|
6941
|
+
console.error(chalk84.red(` The following files exceed ${maxLines} lines:
|
|
6883
6942
|
`));
|
|
6884
6943
|
for (const violation of violations) {
|
|
6885
|
-
console.error(
|
|
6944
|
+
console.error(chalk84.red(` ${violation.file} (${violation.lines} lines)`));
|
|
6886
6945
|
}
|
|
6887
6946
|
console.error(
|
|
6888
|
-
|
|
6947
|
+
chalk84.yellow(
|
|
6889
6948
|
`
|
|
6890
6949
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
6891
6950
|
way to refactor it, ignore it with:
|
|
6892
6951
|
`
|
|
6893
6952
|
)
|
|
6894
6953
|
);
|
|
6895
|
-
console.error(
|
|
6954
|
+
console.error(chalk84.gray(` assist refactor ignore <file>
|
|
6896
6955
|
`));
|
|
6897
6956
|
if (process.env.CLAUDECODE) {
|
|
6898
|
-
console.error(
|
|
6957
|
+
console.error(chalk84.cyan(`
|
|
6899
6958
|
## Extracting Code to New Files
|
|
6900
6959
|
`));
|
|
6901
6960
|
console.error(
|
|
6902
|
-
|
|
6961
|
+
chalk84.cyan(
|
|
6903
6962
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
6904
6963
|
`
|
|
6905
6964
|
)
|
|
6906
6965
|
);
|
|
6907
6966
|
console.error(
|
|
6908
|
-
|
|
6967
|
+
chalk84.cyan(
|
|
6909
6968
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
6910
6969
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
6911
6970
|
`
|
|
6912
6971
|
)
|
|
6913
6972
|
);
|
|
6914
6973
|
console.error(
|
|
6915
|
-
|
|
6974
|
+
chalk84.cyan(
|
|
6916
6975
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
6917
6976
|
domains, move it to a common/shared folder.
|
|
6918
6977
|
`
|
|
@@ -7068,11 +7127,11 @@ async function check(pattern2, options2) {
|
|
|
7068
7127
|
|
|
7069
7128
|
// src/commands/refactor/ignore.ts
|
|
7070
7129
|
import fs17 from "fs";
|
|
7071
|
-
import
|
|
7130
|
+
import chalk85 from "chalk";
|
|
7072
7131
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
7073
7132
|
function ignore(file) {
|
|
7074
7133
|
if (!fs17.existsSync(file)) {
|
|
7075
|
-
console.error(
|
|
7134
|
+
console.error(chalk85.red(`Error: File does not exist: ${file}`));
|
|
7076
7135
|
process.exit(1);
|
|
7077
7136
|
}
|
|
7078
7137
|
const content = fs17.readFileSync(file, "utf-8");
|
|
@@ -7088,7 +7147,7 @@ function ignore(file) {
|
|
|
7088
7147
|
fs17.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
7089
7148
|
}
|
|
7090
7149
|
console.log(
|
|
7091
|
-
|
|
7150
|
+
chalk85.green(
|
|
7092
7151
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
7093
7152
|
)
|
|
7094
7153
|
);
|
|
@@ -7096,7 +7155,7 @@ function ignore(file) {
|
|
|
7096
7155
|
|
|
7097
7156
|
// src/commands/refactor/rename/index.ts
|
|
7098
7157
|
import path28 from "path";
|
|
7099
|
-
import
|
|
7158
|
+
import chalk86 from "chalk";
|
|
7100
7159
|
import { Project as Project2 } from "ts-morph";
|
|
7101
7160
|
async function rename(source, destination, options2 = {}) {
|
|
7102
7161
|
const sourcePath = path28.resolve(source);
|
|
@@ -7109,22 +7168,22 @@ async function rename(source, destination, options2 = {}) {
|
|
|
7109
7168
|
});
|
|
7110
7169
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
7111
7170
|
if (!sourceFile) {
|
|
7112
|
-
console.log(
|
|
7171
|
+
console.log(chalk86.red(`File not found in project: ${source}`));
|
|
7113
7172
|
process.exit(1);
|
|
7114
7173
|
}
|
|
7115
|
-
console.log(
|
|
7174
|
+
console.log(chalk86.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
7116
7175
|
if (options2.apply) {
|
|
7117
7176
|
sourceFile.move(destPath);
|
|
7118
7177
|
await project.save();
|
|
7119
|
-
console.log(
|
|
7178
|
+
console.log(chalk86.green("Done"));
|
|
7120
7179
|
} else {
|
|
7121
|
-
console.log(
|
|
7180
|
+
console.log(chalk86.dim("Dry run. Use --apply to execute."));
|
|
7122
7181
|
}
|
|
7123
7182
|
}
|
|
7124
7183
|
|
|
7125
7184
|
// src/commands/refactor/renameSymbol/index.ts
|
|
7126
7185
|
import path30 from "path";
|
|
7127
|
-
import
|
|
7186
|
+
import chalk87 from "chalk";
|
|
7128
7187
|
import { Project as Project3 } from "ts-morph";
|
|
7129
7188
|
|
|
7130
7189
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -7173,38 +7232,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
7173
7232
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
7174
7233
|
const sourceFile = project.getSourceFile(filePath);
|
|
7175
7234
|
if (!sourceFile) {
|
|
7176
|
-
console.log(
|
|
7235
|
+
console.log(chalk87.red(`File not found in project: ${file}`));
|
|
7177
7236
|
process.exit(1);
|
|
7178
7237
|
}
|
|
7179
7238
|
const symbol = findSymbol(sourceFile, oldName);
|
|
7180
7239
|
if (!symbol) {
|
|
7181
|
-
console.log(
|
|
7240
|
+
console.log(chalk87.red(`Symbol "${oldName}" not found in ${file}`));
|
|
7182
7241
|
process.exit(1);
|
|
7183
7242
|
}
|
|
7184
7243
|
const grouped = groupReferences(symbol, cwd);
|
|
7185
7244
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
7186
7245
|
console.log(
|
|
7187
|
-
|
|
7246
|
+
chalk87.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
7188
7247
|
`)
|
|
7189
7248
|
);
|
|
7190
7249
|
for (const [refFile, lines] of grouped) {
|
|
7191
7250
|
console.log(
|
|
7192
|
-
` ${
|
|
7251
|
+
` ${chalk87.dim(refFile)}: lines ${chalk87.cyan(lines.join(", "))}`
|
|
7193
7252
|
);
|
|
7194
7253
|
}
|
|
7195
7254
|
if (options2.apply) {
|
|
7196
7255
|
symbol.rename(newName);
|
|
7197
7256
|
await project.save();
|
|
7198
|
-
console.log(
|
|
7257
|
+
console.log(chalk87.green(`
|
|
7199
7258
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
7200
7259
|
} else {
|
|
7201
|
-
console.log(
|
|
7260
|
+
console.log(chalk87.dim("\nDry run. Use --apply to execute."));
|
|
7202
7261
|
}
|
|
7203
7262
|
}
|
|
7204
7263
|
|
|
7205
7264
|
// src/commands/refactor/restructure/index.ts
|
|
7206
7265
|
import path39 from "path";
|
|
7207
|
-
import
|
|
7266
|
+
import chalk90 from "chalk";
|
|
7208
7267
|
|
|
7209
7268
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
7210
7269
|
import path31 from "path";
|
|
@@ -7447,50 +7506,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
7447
7506
|
|
|
7448
7507
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
7449
7508
|
import path35 from "path";
|
|
7450
|
-
import
|
|
7509
|
+
import chalk88 from "chalk";
|
|
7451
7510
|
function relPath(filePath) {
|
|
7452
7511
|
return path35.relative(process.cwd(), filePath);
|
|
7453
7512
|
}
|
|
7454
7513
|
function displayMoves(plan2) {
|
|
7455
7514
|
if (plan2.moves.length === 0) return;
|
|
7456
|
-
console.log(
|
|
7515
|
+
console.log(chalk88.bold("\nFile moves:"));
|
|
7457
7516
|
for (const move of plan2.moves) {
|
|
7458
7517
|
console.log(
|
|
7459
|
-
` ${
|
|
7518
|
+
` ${chalk88.red(relPath(move.from))} \u2192 ${chalk88.green(relPath(move.to))}`
|
|
7460
7519
|
);
|
|
7461
|
-
console.log(
|
|
7520
|
+
console.log(chalk88.dim(` ${move.reason}`));
|
|
7462
7521
|
}
|
|
7463
7522
|
}
|
|
7464
7523
|
function displayRewrites(rewrites) {
|
|
7465
7524
|
if (rewrites.length === 0) return;
|
|
7466
7525
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
7467
|
-
console.log(
|
|
7526
|
+
console.log(chalk88.bold(`
|
|
7468
7527
|
Import rewrites (${affectedFiles.size} files):`));
|
|
7469
7528
|
for (const file of affectedFiles) {
|
|
7470
|
-
console.log(` ${
|
|
7529
|
+
console.log(` ${chalk88.cyan(relPath(file))}:`);
|
|
7471
7530
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
7472
7531
|
(r) => r.file === file
|
|
7473
7532
|
)) {
|
|
7474
7533
|
console.log(
|
|
7475
|
-
` ${
|
|
7534
|
+
` ${chalk88.red(`"${oldSpecifier}"`)} \u2192 ${chalk88.green(`"${newSpecifier}"`)}`
|
|
7476
7535
|
);
|
|
7477
7536
|
}
|
|
7478
7537
|
}
|
|
7479
7538
|
}
|
|
7480
7539
|
function displayPlan(plan2) {
|
|
7481
7540
|
if (plan2.warnings.length > 0) {
|
|
7482
|
-
console.log(
|
|
7483
|
-
for (const w of plan2.warnings) console.log(
|
|
7541
|
+
console.log(chalk88.yellow("\nWarnings:"));
|
|
7542
|
+
for (const w of plan2.warnings) console.log(chalk88.yellow(` ${w}`));
|
|
7484
7543
|
}
|
|
7485
7544
|
if (plan2.newDirectories.length > 0) {
|
|
7486
|
-
console.log(
|
|
7545
|
+
console.log(chalk88.bold("\nNew directories:"));
|
|
7487
7546
|
for (const dir of plan2.newDirectories)
|
|
7488
|
-
console.log(
|
|
7547
|
+
console.log(chalk88.green(` ${dir}/`));
|
|
7489
7548
|
}
|
|
7490
7549
|
displayMoves(plan2);
|
|
7491
7550
|
displayRewrites(plan2.rewrites);
|
|
7492
7551
|
console.log(
|
|
7493
|
-
|
|
7552
|
+
chalk88.dim(
|
|
7494
7553
|
`
|
|
7495
7554
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
7496
7555
|
)
|
|
@@ -7500,18 +7559,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
7500
7559
|
// src/commands/refactor/restructure/executePlan.ts
|
|
7501
7560
|
import fs19 from "fs";
|
|
7502
7561
|
import path36 from "path";
|
|
7503
|
-
import
|
|
7562
|
+
import chalk89 from "chalk";
|
|
7504
7563
|
function executePlan(plan2) {
|
|
7505
7564
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
7506
7565
|
for (const [file, content] of updatedContents) {
|
|
7507
7566
|
fs19.writeFileSync(file, content, "utf-8");
|
|
7508
7567
|
console.log(
|
|
7509
|
-
|
|
7568
|
+
chalk89.cyan(` Rewrote imports in ${path36.relative(process.cwd(), file)}`)
|
|
7510
7569
|
);
|
|
7511
7570
|
}
|
|
7512
7571
|
for (const dir of plan2.newDirectories) {
|
|
7513
7572
|
fs19.mkdirSync(dir, { recursive: true });
|
|
7514
|
-
console.log(
|
|
7573
|
+
console.log(chalk89.green(` Created ${path36.relative(process.cwd(), dir)}/`));
|
|
7515
7574
|
}
|
|
7516
7575
|
for (const move of plan2.moves) {
|
|
7517
7576
|
const targetDir = path36.dirname(move.to);
|
|
@@ -7520,7 +7579,7 @@ function executePlan(plan2) {
|
|
|
7520
7579
|
}
|
|
7521
7580
|
fs19.renameSync(move.from, move.to);
|
|
7522
7581
|
console.log(
|
|
7523
|
-
|
|
7582
|
+
chalk89.white(
|
|
7524
7583
|
` Moved ${path36.relative(process.cwd(), move.from)} \u2192 ${path36.relative(process.cwd(), move.to)}`
|
|
7525
7584
|
)
|
|
7526
7585
|
);
|
|
@@ -7535,7 +7594,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
7535
7594
|
if (entries.length === 0) {
|
|
7536
7595
|
fs19.rmdirSync(dir);
|
|
7537
7596
|
console.log(
|
|
7538
|
-
|
|
7597
|
+
chalk89.dim(
|
|
7539
7598
|
` Removed empty directory ${path36.relative(process.cwd(), dir)}`
|
|
7540
7599
|
)
|
|
7541
7600
|
);
|
|
@@ -7668,22 +7727,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
7668
7727
|
const targetPattern = pattern2 ?? "src";
|
|
7669
7728
|
const files = findSourceFiles2(targetPattern);
|
|
7670
7729
|
if (files.length === 0) {
|
|
7671
|
-
console.log(
|
|
7730
|
+
console.log(chalk90.yellow("No files found matching pattern"));
|
|
7672
7731
|
return;
|
|
7673
7732
|
}
|
|
7674
7733
|
const tsConfigPath = path39.resolve("tsconfig.json");
|
|
7675
7734
|
const plan2 = buildPlan(files, tsConfigPath);
|
|
7676
7735
|
if (plan2.moves.length === 0) {
|
|
7677
|
-
console.log(
|
|
7736
|
+
console.log(chalk90.green("No restructuring needed"));
|
|
7678
7737
|
return;
|
|
7679
7738
|
}
|
|
7680
7739
|
displayPlan(plan2);
|
|
7681
7740
|
if (options2.apply) {
|
|
7682
|
-
console.log(
|
|
7741
|
+
console.log(chalk90.bold("\nApplying changes..."));
|
|
7683
7742
|
executePlan(plan2);
|
|
7684
|
-
console.log(
|
|
7743
|
+
console.log(chalk90.green("\nRestructuring complete"));
|
|
7685
7744
|
} else {
|
|
7686
|
-
console.log(
|
|
7745
|
+
console.log(chalk90.dim("\nDry run. Use --apply to execute."));
|
|
7687
7746
|
}
|
|
7688
7747
|
}
|
|
7689
7748
|
|
|
@@ -7711,7 +7770,7 @@ function registerRefactor(program2) {
|
|
|
7711
7770
|
}
|
|
7712
7771
|
|
|
7713
7772
|
// src/commands/seq/seqAuth.ts
|
|
7714
|
-
import
|
|
7773
|
+
import chalk92 from "chalk";
|
|
7715
7774
|
|
|
7716
7775
|
// src/commands/seq/loadConnections.ts
|
|
7717
7776
|
function loadConnections2() {
|
|
@@ -7740,11 +7799,11 @@ function setDefaultConnection(name) {
|
|
|
7740
7799
|
}
|
|
7741
7800
|
|
|
7742
7801
|
// src/commands/seq/promptConnection.ts
|
|
7743
|
-
import
|
|
7802
|
+
import chalk91 from "chalk";
|
|
7744
7803
|
async function promptConnection2(existingNames) {
|
|
7745
7804
|
const name = await promptInput("name", "Connection name:", "default");
|
|
7746
7805
|
if (existingNames.includes(name)) {
|
|
7747
|
-
console.error(
|
|
7806
|
+
console.error(chalk91.red(`Connection "${name}" already exists.`));
|
|
7748
7807
|
process.exit(1);
|
|
7749
7808
|
}
|
|
7750
7809
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -7756,32 +7815,32 @@ async function promptConnection2(existingNames) {
|
|
|
7756
7815
|
var seqAuth = createConnectionAuth({
|
|
7757
7816
|
load: loadConnections2,
|
|
7758
7817
|
save: saveConnections2,
|
|
7759
|
-
format: (c) => `${
|
|
7818
|
+
format: (c) => `${chalk92.bold(c.name)} ${c.url}`,
|
|
7760
7819
|
promptNew: promptConnection2,
|
|
7761
7820
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
7762
7821
|
});
|
|
7763
7822
|
|
|
7764
7823
|
// src/commands/seq/seqQuery.ts
|
|
7765
|
-
import
|
|
7824
|
+
import chalk95 from "chalk";
|
|
7766
7825
|
|
|
7767
7826
|
// src/commands/seq/formatEvent.ts
|
|
7768
|
-
import
|
|
7827
|
+
import chalk93 from "chalk";
|
|
7769
7828
|
function levelColor(level) {
|
|
7770
7829
|
switch (level) {
|
|
7771
7830
|
case "Fatal":
|
|
7772
|
-
return
|
|
7831
|
+
return chalk93.bgRed.white;
|
|
7773
7832
|
case "Error":
|
|
7774
|
-
return
|
|
7833
|
+
return chalk93.red;
|
|
7775
7834
|
case "Warning":
|
|
7776
|
-
return
|
|
7835
|
+
return chalk93.yellow;
|
|
7777
7836
|
case "Information":
|
|
7778
|
-
return
|
|
7837
|
+
return chalk93.cyan;
|
|
7779
7838
|
case "Debug":
|
|
7780
|
-
return
|
|
7839
|
+
return chalk93.gray;
|
|
7781
7840
|
case "Verbose":
|
|
7782
|
-
return
|
|
7841
|
+
return chalk93.dim;
|
|
7783
7842
|
default:
|
|
7784
|
-
return
|
|
7843
|
+
return chalk93.white;
|
|
7785
7844
|
}
|
|
7786
7845
|
}
|
|
7787
7846
|
function levelAbbrev(level) {
|
|
@@ -7822,31 +7881,31 @@ function formatTimestamp(iso) {
|
|
|
7822
7881
|
function formatEvent(event) {
|
|
7823
7882
|
const color = levelColor(event.Level);
|
|
7824
7883
|
const abbrev = levelAbbrev(event.Level);
|
|
7825
|
-
const ts8 =
|
|
7884
|
+
const ts8 = chalk93.dim(formatTimestamp(event.Timestamp));
|
|
7826
7885
|
const msg = renderMessage(event);
|
|
7827
7886
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
7828
7887
|
if (event.Exception) {
|
|
7829
7888
|
for (const line of event.Exception.split("\n")) {
|
|
7830
|
-
lines.push(
|
|
7889
|
+
lines.push(chalk93.red(` ${line}`));
|
|
7831
7890
|
}
|
|
7832
7891
|
}
|
|
7833
7892
|
return lines.join("\n");
|
|
7834
7893
|
}
|
|
7835
7894
|
|
|
7836
7895
|
// src/commands/seq/resolveConnection.ts
|
|
7837
|
-
import
|
|
7896
|
+
import chalk94 from "chalk";
|
|
7838
7897
|
function resolveConnection2(name) {
|
|
7839
7898
|
const connections = loadConnections2();
|
|
7840
7899
|
if (connections.length === 0) {
|
|
7841
7900
|
console.error(
|
|
7842
|
-
|
|
7901
|
+
chalk94.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
7843
7902
|
);
|
|
7844
7903
|
process.exit(1);
|
|
7845
7904
|
}
|
|
7846
7905
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
7847
7906
|
const connection = connections.find((c) => c.name === target);
|
|
7848
7907
|
if (!connection) {
|
|
7849
|
-
console.error(
|
|
7908
|
+
console.error(chalk94.red(`Seq connection "${target}" not found.`));
|
|
7850
7909
|
process.exit(1);
|
|
7851
7910
|
}
|
|
7852
7911
|
return connection;
|
|
@@ -7866,12 +7925,12 @@ async function seqQuery(filter, options2) {
|
|
|
7866
7925
|
});
|
|
7867
7926
|
if (!response.ok) {
|
|
7868
7927
|
const body = await response.text();
|
|
7869
|
-
console.error(
|
|
7928
|
+
console.error(chalk95.red(`Seq returned ${response.status}: ${body}`));
|
|
7870
7929
|
process.exit(1);
|
|
7871
7930
|
}
|
|
7872
7931
|
const events = await response.json();
|
|
7873
7932
|
if (events.length === 0) {
|
|
7874
|
-
console.log(
|
|
7933
|
+
console.log(chalk95.yellow("No events found."));
|
|
7875
7934
|
return;
|
|
7876
7935
|
}
|
|
7877
7936
|
if (options2.json) {
|
|
@@ -7882,11 +7941,11 @@ async function seqQuery(filter, options2) {
|
|
|
7882
7941
|
for (const event of chronological) {
|
|
7883
7942
|
console.log(formatEvent(event));
|
|
7884
7943
|
}
|
|
7885
|
-
console.log(
|
|
7944
|
+
console.log(chalk95.dim(`
|
|
7886
7945
|
${events.length} events`));
|
|
7887
7946
|
if (events.length >= count) {
|
|
7888
7947
|
console.log(
|
|
7889
|
-
|
|
7948
|
+
chalk95.yellow(
|
|
7890
7949
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
7891
7950
|
)
|
|
7892
7951
|
);
|
|
@@ -7894,11 +7953,11 @@ ${events.length} events`));
|
|
|
7894
7953
|
}
|
|
7895
7954
|
|
|
7896
7955
|
// src/commands/seq/seqSetConnection.ts
|
|
7897
|
-
import
|
|
7956
|
+
import chalk96 from "chalk";
|
|
7898
7957
|
function seqSetConnection(name) {
|
|
7899
7958
|
const connections = loadConnections2();
|
|
7900
7959
|
if (!connections.find((c) => c.name === name)) {
|
|
7901
|
-
console.error(
|
|
7960
|
+
console.error(chalk96.red(`Connection "${name}" not found.`));
|
|
7902
7961
|
process.exit(1);
|
|
7903
7962
|
}
|
|
7904
7963
|
setDefaultConnection(name);
|
|
@@ -7917,7 +7976,7 @@ function registerSeq(program2) {
|
|
|
7917
7976
|
}
|
|
7918
7977
|
|
|
7919
7978
|
// src/commands/transcript/shared.ts
|
|
7920
|
-
import { existsSync as
|
|
7979
|
+
import { existsSync as existsSync29, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
|
|
7921
7980
|
import { basename as basename4, join as join25, relative } from "path";
|
|
7922
7981
|
import * as readline2 from "readline";
|
|
7923
7982
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
@@ -7933,7 +7992,7 @@ function isValidDatePrefix(filename) {
|
|
|
7933
7992
|
return DATE_PREFIX_REGEX.test(filename);
|
|
7934
7993
|
}
|
|
7935
7994
|
function collectFiles(dir, extension) {
|
|
7936
|
-
if (!
|
|
7995
|
+
if (!existsSync29(dir)) return [];
|
|
7937
7996
|
const results = [];
|
|
7938
7997
|
for (const entry of readdirSync5(dir)) {
|
|
7939
7998
|
const fullPath = join25(dir, entry);
|
|
@@ -8030,7 +8089,7 @@ async function configure() {
|
|
|
8030
8089
|
}
|
|
8031
8090
|
|
|
8032
8091
|
// src/commands/transcript/format/index.ts
|
|
8033
|
-
import { existsSync as
|
|
8092
|
+
import { existsSync as existsSync31 } from "fs";
|
|
8034
8093
|
|
|
8035
8094
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
8036
8095
|
import { dirname as dirname18, join as join27 } from "path";
|
|
@@ -8104,7 +8163,7 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
8104
8163
|
}
|
|
8105
8164
|
|
|
8106
8165
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
8107
|
-
import { existsSync as
|
|
8166
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync7, readFileSync as readFileSync23, writeFileSync as writeFileSync23 } from "fs";
|
|
8108
8167
|
import { basename as basename5, dirname as dirname19, join as join28 } from "path";
|
|
8109
8168
|
|
|
8110
8169
|
// src/commands/transcript/cleanText.ts
|
|
@@ -8329,7 +8388,7 @@ function logSkipped(relativeDir, mdFile) {
|
|
|
8329
8388
|
return "skipped";
|
|
8330
8389
|
}
|
|
8331
8390
|
function ensureDirectory(dir, label2) {
|
|
8332
|
-
if (!
|
|
8391
|
+
if (!existsSync30(dir)) {
|
|
8333
8392
|
mkdirSync7(dir, { recursive: true });
|
|
8334
8393
|
console.log(`Created ${label2}: ${dir}`);
|
|
8335
8394
|
}
|
|
@@ -8365,7 +8424,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
|
|
|
8365
8424
|
logReduction(cues.length, chatMessages.length);
|
|
8366
8425
|
}
|
|
8367
8426
|
function tryProcessVtt(vttFile, paths) {
|
|
8368
|
-
if (
|
|
8427
|
+
if (existsSync30(paths.outputPath))
|
|
8369
8428
|
return logSkipped(paths.relativeDir, paths.mdFile);
|
|
8370
8429
|
convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
|
|
8371
8430
|
return "processed";
|
|
@@ -8391,7 +8450,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
|
|
|
8391
8450
|
logSummary(counts);
|
|
8392
8451
|
}
|
|
8393
8452
|
function requireVttDir(vttDir) {
|
|
8394
|
-
if (!
|
|
8453
|
+
if (!existsSync31(vttDir)) {
|
|
8395
8454
|
console.error(`VTT directory not found: ${vttDir}`);
|
|
8396
8455
|
process.exit(1);
|
|
8397
8456
|
}
|
|
@@ -8423,12 +8482,12 @@ async function format() {
|
|
|
8423
8482
|
}
|
|
8424
8483
|
|
|
8425
8484
|
// src/commands/transcript/summarise/index.ts
|
|
8426
|
-
import { existsSync as
|
|
8485
|
+
import { existsSync as existsSync33 } from "fs";
|
|
8427
8486
|
import { basename as basename6, dirname as dirname21, join as join30, relative as relative2 } from "path";
|
|
8428
8487
|
|
|
8429
8488
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
8430
8489
|
import {
|
|
8431
|
-
existsSync as
|
|
8490
|
+
existsSync as existsSync32,
|
|
8432
8491
|
mkdirSync as mkdirSync8,
|
|
8433
8492
|
readFileSync as readFileSync24,
|
|
8434
8493
|
renameSync as renameSync2,
|
|
@@ -8437,14 +8496,14 @@ import {
|
|
|
8437
8496
|
import { dirname as dirname20, join as join29 } from "path";
|
|
8438
8497
|
|
|
8439
8498
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
8440
|
-
import
|
|
8499
|
+
import chalk97 from "chalk";
|
|
8441
8500
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
8442
8501
|
function validateStagedContent(filename, content) {
|
|
8443
8502
|
const firstLine = content.split("\n")[0];
|
|
8444
8503
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
8445
8504
|
if (!match) {
|
|
8446
8505
|
console.error(
|
|
8447
|
-
|
|
8506
|
+
chalk97.red(
|
|
8448
8507
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
8449
8508
|
)
|
|
8450
8509
|
);
|
|
@@ -8453,7 +8512,7 @@ function validateStagedContent(filename, content) {
|
|
|
8453
8512
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
8454
8513
|
if (!contentAfterLink) {
|
|
8455
8514
|
console.error(
|
|
8456
|
-
|
|
8515
|
+
chalk97.red(
|
|
8457
8516
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
8458
8517
|
)
|
|
8459
8518
|
);
|
|
@@ -8465,7 +8524,7 @@ function validateStagedContent(filename, content) {
|
|
|
8465
8524
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
8466
8525
|
var STAGING_DIR = join29(process.cwd(), ".assist", "transcript");
|
|
8467
8526
|
function processStagedFile() {
|
|
8468
|
-
if (!
|
|
8527
|
+
if (!existsSync32(STAGING_DIR)) {
|
|
8469
8528
|
return false;
|
|
8470
8529
|
}
|
|
8471
8530
|
const stagedFiles = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -8489,7 +8548,7 @@ function processStagedFile() {
|
|
|
8489
8548
|
}
|
|
8490
8549
|
const destPath = join29(summaryDir, matchingTranscript.relativePath);
|
|
8491
8550
|
const destDir = dirname20(destPath);
|
|
8492
|
-
if (!
|
|
8551
|
+
if (!existsSync32(destDir)) {
|
|
8493
8552
|
mkdirSync8(destDir, { recursive: true });
|
|
8494
8553
|
}
|
|
8495
8554
|
renameSync2(stagedFile.absolutePath, destPath);
|
|
@@ -8516,7 +8575,7 @@ function buildSummaryIndex(summaryDir) {
|
|
|
8516
8575
|
function summarise2() {
|
|
8517
8576
|
processStagedFile();
|
|
8518
8577
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
8519
|
-
if (!
|
|
8578
|
+
if (!existsSync33(transcriptsDir)) {
|
|
8520
8579
|
console.log("No transcripts directory found.");
|
|
8521
8580
|
return;
|
|
8522
8581
|
}
|
|
@@ -8620,9 +8679,9 @@ function devices() {
|
|
|
8620
8679
|
}
|
|
8621
8680
|
|
|
8622
8681
|
// src/commands/voice/logs.ts
|
|
8623
|
-
import { existsSync as
|
|
8682
|
+
import { existsSync as existsSync34, readFileSync as readFileSync25 } from "fs";
|
|
8624
8683
|
function logs(options2) {
|
|
8625
|
-
if (!
|
|
8684
|
+
if (!existsSync34(voicePaths.log)) {
|
|
8626
8685
|
console.log("No voice log file found");
|
|
8627
8686
|
return;
|
|
8628
8687
|
}
|
|
@@ -8654,7 +8713,7 @@ import { join as join34 } from "path";
|
|
|
8654
8713
|
|
|
8655
8714
|
// src/commands/voice/checkLockFile.ts
|
|
8656
8715
|
import { execSync as execSync35 } from "child_process";
|
|
8657
|
-
import { existsSync as
|
|
8716
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync26, writeFileSync as writeFileSync24 } from "fs";
|
|
8658
8717
|
import { join as join33 } from "path";
|
|
8659
8718
|
function isProcessAlive(pid) {
|
|
8660
8719
|
try {
|
|
@@ -8666,7 +8725,7 @@ function isProcessAlive(pid) {
|
|
|
8666
8725
|
}
|
|
8667
8726
|
function checkLockFile() {
|
|
8668
8727
|
const lockFile = getLockFile();
|
|
8669
|
-
if (!
|
|
8728
|
+
if (!existsSync35(lockFile)) return;
|
|
8670
8729
|
try {
|
|
8671
8730
|
const lock = JSON.parse(readFileSync26(lockFile, "utf-8"));
|
|
8672
8731
|
if (lock.pid && isProcessAlive(lock.pid)) {
|
|
@@ -8679,7 +8738,7 @@ function checkLockFile() {
|
|
|
8679
8738
|
}
|
|
8680
8739
|
}
|
|
8681
8740
|
function bootstrapVenv() {
|
|
8682
|
-
if (
|
|
8741
|
+
if (existsSync35(getVenvPython())) return;
|
|
8683
8742
|
console.log("Setting up Python environment...");
|
|
8684
8743
|
const pythonDir = getPythonDir();
|
|
8685
8744
|
execSync35(
|
|
@@ -8770,7 +8829,7 @@ function start2(options2) {
|
|
|
8770
8829
|
}
|
|
8771
8830
|
|
|
8772
8831
|
// src/commands/voice/status.ts
|
|
8773
|
-
import { existsSync as
|
|
8832
|
+
import { existsSync as existsSync36, readFileSync as readFileSync27 } from "fs";
|
|
8774
8833
|
function isProcessAlive2(pid) {
|
|
8775
8834
|
try {
|
|
8776
8835
|
process.kill(pid, 0);
|
|
@@ -8780,12 +8839,12 @@ function isProcessAlive2(pid) {
|
|
|
8780
8839
|
}
|
|
8781
8840
|
}
|
|
8782
8841
|
function readRecentLogs(count) {
|
|
8783
|
-
if (!
|
|
8842
|
+
if (!existsSync36(voicePaths.log)) return [];
|
|
8784
8843
|
const lines = readFileSync27(voicePaths.log, "utf-8").trim().split("\n");
|
|
8785
8844
|
return lines.slice(-count);
|
|
8786
8845
|
}
|
|
8787
8846
|
function status() {
|
|
8788
|
-
if (!
|
|
8847
|
+
if (!existsSync36(voicePaths.pid)) {
|
|
8789
8848
|
console.log("Voice daemon: not running (no PID file)");
|
|
8790
8849
|
return;
|
|
8791
8850
|
}
|
|
@@ -8808,9 +8867,9 @@ function status() {
|
|
|
8808
8867
|
}
|
|
8809
8868
|
|
|
8810
8869
|
// src/commands/voice/stop.ts
|
|
8811
|
-
import { existsSync as
|
|
8870
|
+
import { existsSync as existsSync37, readFileSync as readFileSync28, unlinkSync as unlinkSync9 } from "fs";
|
|
8812
8871
|
function stop() {
|
|
8813
|
-
if (!
|
|
8872
|
+
if (!existsSync37(voicePaths.pid)) {
|
|
8814
8873
|
console.log("Voice daemon is not running (no PID file)");
|
|
8815
8874
|
return;
|
|
8816
8875
|
}
|
|
@@ -8827,7 +8886,7 @@ function stop() {
|
|
|
8827
8886
|
}
|
|
8828
8887
|
try {
|
|
8829
8888
|
const lockFile = getLockFile();
|
|
8830
|
-
if (
|
|
8889
|
+
if (existsSync37(lockFile)) unlinkSync9(lockFile);
|
|
8831
8890
|
} catch {
|
|
8832
8891
|
}
|
|
8833
8892
|
console.log("Voice daemon stopped");
|
|
@@ -8846,7 +8905,7 @@ function registerVoice(program2) {
|
|
|
8846
8905
|
|
|
8847
8906
|
// src/commands/roam/auth.ts
|
|
8848
8907
|
import { randomBytes } from "crypto";
|
|
8849
|
-
import
|
|
8908
|
+
import chalk98 from "chalk";
|
|
8850
8909
|
|
|
8851
8910
|
// src/lib/openBrowser.ts
|
|
8852
8911
|
import { execSync as execSync36 } from "child_process";
|
|
@@ -9021,13 +9080,13 @@ async function auth() {
|
|
|
9021
9080
|
saveGlobalConfig(config);
|
|
9022
9081
|
const state = randomBytes(16).toString("hex");
|
|
9023
9082
|
console.log(
|
|
9024
|
-
|
|
9083
|
+
chalk98.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
9025
9084
|
);
|
|
9026
|
-
console.log(
|
|
9027
|
-
console.log(
|
|
9028
|
-
console.log(
|
|
9085
|
+
console.log(chalk98.white("http://localhost:14523/callback\n"));
|
|
9086
|
+
console.log(chalk98.blue("Opening browser for authorization..."));
|
|
9087
|
+
console.log(chalk98.dim("Waiting for authorization callback..."));
|
|
9029
9088
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
9030
|
-
console.log(
|
|
9089
|
+
console.log(chalk98.dim("Exchanging code for tokens..."));
|
|
9031
9090
|
const tokens = await exchangeToken({
|
|
9032
9091
|
code,
|
|
9033
9092
|
clientId,
|
|
@@ -9043,7 +9102,7 @@ async function auth() {
|
|
|
9043
9102
|
};
|
|
9044
9103
|
saveGlobalConfig(config);
|
|
9045
9104
|
console.log(
|
|
9046
|
-
|
|
9105
|
+
chalk98.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
9047
9106
|
);
|
|
9048
9107
|
}
|
|
9049
9108
|
|
|
@@ -9261,10 +9320,10 @@ function run3(name, args) {
|
|
|
9261
9320
|
|
|
9262
9321
|
// src/commands/screenshot/index.ts
|
|
9263
9322
|
import { execSync as execSync38 } from "child_process";
|
|
9264
|
-
import { existsSync as
|
|
9323
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync13, unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
|
|
9265
9324
|
import { tmpdir as tmpdir6 } from "os";
|
|
9266
9325
|
import { join as join38, resolve as resolve5 } from "path";
|
|
9267
|
-
import
|
|
9326
|
+
import chalk99 from "chalk";
|
|
9268
9327
|
|
|
9269
9328
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
9270
9329
|
var captureWindowPs1 = `
|
|
@@ -9393,7 +9452,7 @@ Write-Output $OutputPath
|
|
|
9393
9452
|
|
|
9394
9453
|
// src/commands/screenshot/index.ts
|
|
9395
9454
|
function buildOutputPath(outputDir, processName) {
|
|
9396
|
-
if (!
|
|
9455
|
+
if (!existsSync38(outputDir)) {
|
|
9397
9456
|
mkdirSync13(outputDir, { recursive: true });
|
|
9398
9457
|
}
|
|
9399
9458
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -9415,22 +9474,22 @@ function screenshot(processName) {
|
|
|
9415
9474
|
const config = loadConfig();
|
|
9416
9475
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
9417
9476
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
9418
|
-
console.log(
|
|
9477
|
+
console.log(chalk99.gray(`Capturing window for process "${processName}" ...`));
|
|
9419
9478
|
try {
|
|
9420
9479
|
runPowerShellScript(processName, outputPath);
|
|
9421
|
-
console.log(
|
|
9480
|
+
console.log(chalk99.green(`Screenshot saved: ${outputPath}`));
|
|
9422
9481
|
} catch (error) {
|
|
9423
9482
|
const msg = error instanceof Error ? error.message : String(error);
|
|
9424
|
-
console.error(
|
|
9483
|
+
console.error(chalk99.red(`Failed to capture screenshot: ${msg}`));
|
|
9425
9484
|
process.exit(1);
|
|
9426
9485
|
}
|
|
9427
9486
|
}
|
|
9428
9487
|
|
|
9429
9488
|
// src/commands/statusLine.ts
|
|
9430
|
-
import
|
|
9489
|
+
import chalk101 from "chalk";
|
|
9431
9490
|
|
|
9432
9491
|
// src/commands/buildLimitsSegment.ts
|
|
9433
|
-
import
|
|
9492
|
+
import chalk100 from "chalk";
|
|
9434
9493
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
9435
9494
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
9436
9495
|
function formatTimeLeft(resetsAt) {
|
|
@@ -9453,10 +9512,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
9453
9512
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
9454
9513
|
const label2 = `${Math.round(pct)}%`;
|
|
9455
9514
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
9456
|
-
if (projected == null) return
|
|
9457
|
-
if (projected > 100) return
|
|
9458
|
-
if (projected > 75) return
|
|
9459
|
-
return
|
|
9515
|
+
if (projected == null) return chalk100.green(label2);
|
|
9516
|
+
if (projected > 100) return chalk100.red(label2);
|
|
9517
|
+
if (projected > 75) return chalk100.yellow(label2);
|
|
9518
|
+
return chalk100.green(label2);
|
|
9460
9519
|
}
|
|
9461
9520
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
9462
9521
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -9482,14 +9541,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
9482
9541
|
}
|
|
9483
9542
|
|
|
9484
9543
|
// src/commands/statusLine.ts
|
|
9485
|
-
|
|
9544
|
+
chalk101.level = 3;
|
|
9486
9545
|
function formatNumber(num) {
|
|
9487
9546
|
return num.toLocaleString("en-US");
|
|
9488
9547
|
}
|
|
9489
9548
|
function colorizePercent(pct) {
|
|
9490
9549
|
const label2 = `${Math.round(pct)}%`;
|
|
9491
|
-
if (pct > 80) return
|
|
9492
|
-
if (pct > 40) return
|
|
9550
|
+
if (pct > 80) return chalk101.red(label2);
|
|
9551
|
+
if (pct > 40) return chalk101.yellow(label2);
|
|
9493
9552
|
return label2;
|
|
9494
9553
|
}
|
|
9495
9554
|
async function statusLine() {
|
|
@@ -9512,7 +9571,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
9512
9571
|
// src/commands/sync/syncClaudeMd.ts
|
|
9513
9572
|
import * as fs22 from "fs";
|
|
9514
9573
|
import * as path40 from "path";
|
|
9515
|
-
import
|
|
9574
|
+
import chalk102 from "chalk";
|
|
9516
9575
|
async function syncClaudeMd(claudeDir, targetBase) {
|
|
9517
9576
|
const source = path40.join(claudeDir, "CLAUDE.md");
|
|
9518
9577
|
const target = path40.join(targetBase, "CLAUDE.md");
|
|
@@ -9521,12 +9580,12 @@ async function syncClaudeMd(claudeDir, targetBase) {
|
|
|
9521
9580
|
const targetContent = fs22.readFileSync(target, "utf-8");
|
|
9522
9581
|
if (sourceContent !== targetContent) {
|
|
9523
9582
|
console.log(
|
|
9524
|
-
|
|
9583
|
+
chalk102.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
9525
9584
|
);
|
|
9526
9585
|
console.log();
|
|
9527
9586
|
printDiff(targetContent, sourceContent);
|
|
9528
9587
|
const confirm = await promptConfirm(
|
|
9529
|
-
|
|
9588
|
+
chalk102.red("Overwrite existing CLAUDE.md?"),
|
|
9530
9589
|
false
|
|
9531
9590
|
);
|
|
9532
9591
|
if (!confirm) {
|
|
@@ -9542,7 +9601,7 @@ async function syncClaudeMd(claudeDir, targetBase) {
|
|
|
9542
9601
|
// src/commands/sync/syncSettings.ts
|
|
9543
9602
|
import * as fs23 from "fs";
|
|
9544
9603
|
import * as path41 from "path";
|
|
9545
|
-
import
|
|
9604
|
+
import chalk103 from "chalk";
|
|
9546
9605
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
9547
9606
|
const source = path41.join(claudeDir, "settings.json");
|
|
9548
9607
|
const target = path41.join(targetBase, "settings.json");
|
|
@@ -9558,14 +9617,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
9558
9617
|
if (mergedContent !== normalizedTarget) {
|
|
9559
9618
|
if (!options2?.yes) {
|
|
9560
9619
|
console.log(
|
|
9561
|
-
|
|
9620
|
+
chalk103.yellow(
|
|
9562
9621
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
9563
9622
|
)
|
|
9564
9623
|
);
|
|
9565
9624
|
console.log();
|
|
9566
9625
|
printDiff(targetContent, mergedContent);
|
|
9567
9626
|
const confirm = await promptConfirm(
|
|
9568
|
-
|
|
9627
|
+
chalk103.red("Overwrite existing settings.json?"),
|
|
9569
9628
|
false
|
|
9570
9629
|
);
|
|
9571
9630
|
if (!confirm) {
|