@staff0rd/assist 0.162.0 → 0.164.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 +4 -1
- package/claude/CLAUDE.md +2 -0
- package/dist/index.js +653 -552
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.164.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -79,8 +79,25 @@ var package_default = {
|
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
-
// src/commands/backlog/
|
|
83
|
-
import
|
|
82
|
+
// src/commands/backlog/next.ts
|
|
83
|
+
import chalk7 from "chalk";
|
|
84
|
+
import enquirer2 from "enquirer";
|
|
85
|
+
|
|
86
|
+
// src/shared/exitOnCancel.ts
|
|
87
|
+
async function exitOnCancel(promise) {
|
|
88
|
+
try {
|
|
89
|
+
return await promise;
|
|
90
|
+
} catch (err) {
|
|
91
|
+
if (err === "" || err === void 0) {
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/commands/backlog/acquireLock.ts
|
|
99
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
100
|
+
import { join as join2 } from "path";
|
|
84
101
|
|
|
85
102
|
// src/commands/backlog/shared.ts
|
|
86
103
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -122,8 +139,15 @@ var backlogItemSchema = z.strictObject({
|
|
|
122
139
|
var backlogFileSchema = z.array(backlogItemSchema);
|
|
123
140
|
|
|
124
141
|
// src/commands/backlog/shared.ts
|
|
142
|
+
var _backlogDir;
|
|
143
|
+
function setBacklogDir(dir) {
|
|
144
|
+
_backlogDir = dir;
|
|
145
|
+
}
|
|
146
|
+
function getBacklogDir() {
|
|
147
|
+
return _backlogDir ?? process.cwd();
|
|
148
|
+
}
|
|
125
149
|
function getBacklogPath() {
|
|
126
|
-
return join(
|
|
150
|
+
return join(getBacklogDir(), "assist.backlog.yml");
|
|
127
151
|
}
|
|
128
152
|
function loadBacklog() {
|
|
129
153
|
const backlogPath = getBacklogPath();
|
|
@@ -185,82 +209,10 @@ function getNextId(items) {
|
|
|
185
209
|
if (items.length === 0) return 1;
|
|
186
210
|
return Math.max(...items.map((item) => item.id)) + 1;
|
|
187
211
|
}
|
|
188
|
-
function readStdin() {
|
|
189
|
-
return new Promise((resolve7, reject) => {
|
|
190
|
-
const chunks = [];
|
|
191
|
-
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
192
|
-
process.stdin.on("end", () => resolve7(Buffer.concat(chunks).toString()));
|
|
193
|
-
process.stdin.on("error", reject);
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// src/commands/backlog/delete/index.ts
|
|
198
|
-
async function del(id) {
|
|
199
|
-
const name = removeItem(id);
|
|
200
|
-
if (name) {
|
|
201
|
-
console.log(chalk2.green(`Deleted item #${id}: ${name}`));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// src/commands/backlog/done/index.ts
|
|
206
|
-
import chalk3 from "chalk";
|
|
207
|
-
|
|
208
|
-
// src/commands/backlog/addComment.ts
|
|
209
|
-
function addComment(item, text, phase) {
|
|
210
|
-
const entry = {
|
|
211
|
-
text,
|
|
212
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
213
|
-
type: "comment",
|
|
214
|
-
...phase !== void 0 && { phase }
|
|
215
|
-
};
|
|
216
|
-
if (!item.comments) item.comments = [];
|
|
217
|
-
item.comments.push(entry);
|
|
218
|
-
}
|
|
219
|
-
function addPhaseSummary(item, text, phase) {
|
|
220
|
-
const entry = {
|
|
221
|
-
text,
|
|
222
|
-
phase,
|
|
223
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
224
|
-
type: "summary"
|
|
225
|
-
};
|
|
226
|
-
if (!item.comments) item.comments = [];
|
|
227
|
-
item.comments.push(entry);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// src/commands/backlog/done/index.ts
|
|
231
|
-
async function done(id, summary) {
|
|
232
|
-
const result = loadAndFindItem(id);
|
|
233
|
-
if (!result) return;
|
|
234
|
-
result.item.status = "done";
|
|
235
|
-
if (summary) {
|
|
236
|
-
const phase = result.item.currentPhase ?? 0;
|
|
237
|
-
addPhaseSummary(result.item, summary, phase);
|
|
238
|
-
}
|
|
239
|
-
saveBacklog(result.items);
|
|
240
|
-
console.log(chalk3.green(`Completed item #${id}: ${result.item.name}`));
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// src/commands/backlog/next.ts
|
|
244
|
-
import chalk9 from "chalk";
|
|
245
|
-
import enquirer2 from "enquirer";
|
|
246
|
-
|
|
247
|
-
// src/shared/exitOnCancel.ts
|
|
248
|
-
async function exitOnCancel(promise) {
|
|
249
|
-
try {
|
|
250
|
-
return await promise;
|
|
251
|
-
} catch (err) {
|
|
252
|
-
if (err === "" || err === void 0) {
|
|
253
|
-
process.exit(0);
|
|
254
|
-
}
|
|
255
|
-
throw err;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
212
|
|
|
259
213
|
// src/commands/backlog/acquireLock.ts
|
|
260
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
261
|
-
import { join as join2 } from "path";
|
|
262
214
|
function getLockPath(itemId) {
|
|
263
|
-
return join2(
|
|
215
|
+
return join2(getBacklogDir(), `.assist-lock-${itemId}.json`);
|
|
264
216
|
}
|
|
265
217
|
function isProcessAlive(pid) {
|
|
266
218
|
try {
|
|
@@ -296,37 +248,37 @@ function releaseLock(itemId) {
|
|
|
296
248
|
}
|
|
297
249
|
|
|
298
250
|
// src/commands/backlog/list/shared.ts
|
|
299
|
-
import
|
|
251
|
+
import chalk2 from "chalk";
|
|
300
252
|
function statusIcon(status2) {
|
|
301
253
|
switch (status2) {
|
|
302
254
|
case "todo":
|
|
303
|
-
return
|
|
255
|
+
return chalk2.dim("[ ]");
|
|
304
256
|
case "in-progress":
|
|
305
|
-
return
|
|
257
|
+
return chalk2.yellow("[~]");
|
|
306
258
|
case "done":
|
|
307
|
-
return
|
|
259
|
+
return chalk2.green("[x]");
|
|
308
260
|
}
|
|
309
261
|
}
|
|
310
262
|
function typeLabel(type) {
|
|
311
263
|
switch (type) {
|
|
312
264
|
case "bug":
|
|
313
|
-
return
|
|
265
|
+
return chalk2.magenta("Bug");
|
|
314
266
|
case "story":
|
|
315
|
-
return
|
|
267
|
+
return chalk2.cyan("Story");
|
|
316
268
|
}
|
|
317
269
|
}
|
|
318
270
|
function phaseLabel(item) {
|
|
319
271
|
if (!item.plan) return "";
|
|
320
|
-
return
|
|
272
|
+
return chalk2.dim(
|
|
321
273
|
` (phase ${(item.currentPhase ?? 0) + 1}/${item.plan.length})`
|
|
322
274
|
);
|
|
323
275
|
}
|
|
324
276
|
function printVerboseDetails(item) {
|
|
325
277
|
if (item.description) {
|
|
326
|
-
console.log(` ${
|
|
278
|
+
console.log(` ${chalk2.dim("Description:")} ${item.description}`);
|
|
327
279
|
}
|
|
328
280
|
if (item.acceptanceCriteria.length > 0) {
|
|
329
|
-
console.log(` ${
|
|
281
|
+
console.log(` ${chalk2.dim("Acceptance criteria:")}`);
|
|
330
282
|
for (const [i, criterion] of item.acceptanceCriteria.entries()) {
|
|
331
283
|
console.log(` ${i + 1}. ${criterion}`);
|
|
332
284
|
}
|
|
@@ -335,7 +287,7 @@ function printVerboseDetails(item) {
|
|
|
335
287
|
}
|
|
336
288
|
|
|
337
289
|
// src/commands/backlog/run.ts
|
|
338
|
-
import
|
|
290
|
+
import chalk6 from "chalk";
|
|
339
291
|
|
|
340
292
|
// src/commands/backlog/buildCommentLines.ts
|
|
341
293
|
function buildCommentLines(comments2) {
|
|
@@ -454,11 +406,11 @@ function buildReviewPhase() {
|
|
|
454
406
|
}
|
|
455
407
|
|
|
456
408
|
// src/commands/backlog/executePhase.ts
|
|
457
|
-
import
|
|
409
|
+
import chalk4 from "chalk";
|
|
458
410
|
|
|
459
411
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
460
412
|
import { existsSync as existsSync3, unlinkSync as unlinkSync2 } from "fs";
|
|
461
|
-
import
|
|
413
|
+
import chalk3 from "chalk";
|
|
462
414
|
|
|
463
415
|
// src/commands/backlog/handleIncompletePhase.ts
|
|
464
416
|
import enquirer from "enquirer";
|
|
@@ -481,7 +433,7 @@ import { writeFileSync as writeFileSync3 } from "fs";
|
|
|
481
433
|
import { join as join3 } from "path";
|
|
482
434
|
var SIGNAL_FILE = ".assist-signal.json";
|
|
483
435
|
function getSignalPath() {
|
|
484
|
-
return join3(
|
|
436
|
+
return join3(getBacklogDir(), SIGNAL_FILE);
|
|
485
437
|
}
|
|
486
438
|
function writeSignal(event, data) {
|
|
487
439
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
@@ -503,7 +455,7 @@ async function resolvePhaseResult(phaseIndex) {
|
|
|
503
455
|
return action === "skip" ? 1 : 0;
|
|
504
456
|
}
|
|
505
457
|
cleanupSignal();
|
|
506
|
-
console.log(
|
|
458
|
+
console.log(chalk3.green(`
|
|
507
459
|
Phase ${phaseIndex + 1} completed.`));
|
|
508
460
|
return 1;
|
|
509
461
|
}
|
|
@@ -561,7 +513,7 @@ function stopWatching() {
|
|
|
561
513
|
async function executePhase(item, phaseIndex, phases, spawnOptions) {
|
|
562
514
|
const phase = phases[phaseIndex];
|
|
563
515
|
console.log(
|
|
564
|
-
|
|
516
|
+
chalk4.bold(
|
|
565
517
|
`
|
|
566
518
|
--- Phase ${phaseIndex + 1}/${phases.length}: ${phase.name} ---
|
|
567
519
|
`
|
|
@@ -580,7 +532,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions) {
|
|
|
580
532
|
}
|
|
581
533
|
|
|
582
534
|
// src/commands/backlog/prepareRun.ts
|
|
583
|
-
import
|
|
535
|
+
import chalk5 from "chalk";
|
|
584
536
|
|
|
585
537
|
// src/commands/backlog/resolvePlan.ts
|
|
586
538
|
function resolvePlan(item) {
|
|
@@ -603,13 +555,13 @@ function prepareRun(id) {
|
|
|
603
555
|
const plan2 = resolvePlan(item);
|
|
604
556
|
const startPhase = item.currentPhase ?? 0;
|
|
605
557
|
if (item.status === "done") {
|
|
606
|
-
console.log(
|
|
558
|
+
console.log(chalk5.green(`Already done: #${id}: ${item.name}`));
|
|
607
559
|
return void 0;
|
|
608
560
|
}
|
|
609
561
|
if (startPhase > plan2.length) {
|
|
610
562
|
setStatus(id, "done");
|
|
611
563
|
console.log(
|
|
612
|
-
|
|
564
|
+
chalk5.green(`All phases already complete for #${id}: ${item.name}`)
|
|
613
565
|
);
|
|
614
566
|
return void 0;
|
|
615
567
|
}
|
|
@@ -634,12 +586,12 @@ async function run(id, spawnOptions) {
|
|
|
634
586
|
}
|
|
635
587
|
}
|
|
636
588
|
function logProgress(id, name, startPhase, total) {
|
|
637
|
-
console.log(
|
|
589
|
+
console.log(chalk6.bold(`Running plan for #${id}: ${name}`));
|
|
638
590
|
if (startPhase > 0) {
|
|
639
|
-
console.log(
|
|
591
|
+
console.log(chalk6.dim(`Resuming from phase ${startPhase + 1}/${total}
|
|
640
592
|
`));
|
|
641
593
|
} else {
|
|
642
|
-
console.log(
|
|
594
|
+
console.log(chalk6.dim(`${total} phase(s)
|
|
643
595
|
`));
|
|
644
596
|
}
|
|
645
597
|
}
|
|
@@ -693,7 +645,7 @@ async function next(options2) {
|
|
|
693
645
|
const inProgress = findResumable(items);
|
|
694
646
|
if (inProgress) {
|
|
695
647
|
console.log(
|
|
696
|
-
|
|
648
|
+
chalk7.bold(
|
|
697
649
|
`Resuming in-progress item #${inProgress.id}: ${inProgress.name}`
|
|
698
650
|
)
|
|
699
651
|
);
|
|
@@ -703,13 +655,13 @@ async function next(options2) {
|
|
|
703
655
|
}
|
|
704
656
|
const todo = items.filter((i) => i.status === "todo");
|
|
705
657
|
if (todo.length === 0) {
|
|
706
|
-
console.log(
|
|
658
|
+
console.log(chalk7.green("All backlog items complete."));
|
|
707
659
|
return;
|
|
708
660
|
}
|
|
709
661
|
let id;
|
|
710
662
|
if (todo.length === 1) {
|
|
711
663
|
const only = todo[0];
|
|
712
|
-
console.log(
|
|
664
|
+
console.log(chalk7.bold(`Starting #${only.id}: ${only.name}`));
|
|
713
665
|
id = String(only.id);
|
|
714
666
|
} else {
|
|
715
667
|
id = await selectItem(todo);
|
|
@@ -720,7 +672,31 @@ async function next(options2) {
|
|
|
720
672
|
}
|
|
721
673
|
|
|
722
674
|
// src/commands/backlog/phaseDone.ts
|
|
723
|
-
import
|
|
675
|
+
import chalk8 from "chalk";
|
|
676
|
+
|
|
677
|
+
// src/commands/backlog/addComment.ts
|
|
678
|
+
function addComment(item, text, phase) {
|
|
679
|
+
const entry = {
|
|
680
|
+
text,
|
|
681
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
682
|
+
type: "comment",
|
|
683
|
+
...phase !== void 0 && { phase }
|
|
684
|
+
};
|
|
685
|
+
if (!item.comments) item.comments = [];
|
|
686
|
+
item.comments.push(entry);
|
|
687
|
+
}
|
|
688
|
+
function addPhaseSummary(item, text, phase) {
|
|
689
|
+
const entry = {
|
|
690
|
+
text,
|
|
691
|
+
phase,
|
|
692
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
693
|
+
type: "summary"
|
|
694
|
+
};
|
|
695
|
+
if (!item.comments) item.comments = [];
|
|
696
|
+
item.comments.push(entry);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// src/commands/backlog/phaseDone.ts
|
|
724
700
|
function phaseDone(id, phase, summary) {
|
|
725
701
|
const phaseIndex = Number.parseInt(phase, 10);
|
|
726
702
|
writeSignal("phase-done", {
|
|
@@ -730,7 +706,7 @@ function phaseDone(id, phase, summary) {
|
|
|
730
706
|
});
|
|
731
707
|
const result = loadAndFindItem(id);
|
|
732
708
|
if (result?.item.status === "done") {
|
|
733
|
-
console.log(
|
|
709
|
+
console.log(chalk8.dim(`Item #${id} already done, skipping phase advance.`));
|
|
734
710
|
return;
|
|
735
711
|
}
|
|
736
712
|
if (result) {
|
|
@@ -738,27 +714,27 @@ function phaseDone(id, phase, summary) {
|
|
|
738
714
|
saveBacklog(result.items);
|
|
739
715
|
}
|
|
740
716
|
setCurrentPhase(id, phaseIndex + 1);
|
|
741
|
-
console.log(
|
|
717
|
+
console.log(chalk8.green(`Phase ${phase} of item #${id} marked as complete.`));
|
|
742
718
|
}
|
|
743
719
|
|
|
744
720
|
// src/commands/backlog/plan.ts
|
|
745
|
-
import
|
|
721
|
+
import chalk9 from "chalk";
|
|
746
722
|
function plan(id) {
|
|
747
723
|
const result = loadAndFindItem(id);
|
|
748
724
|
if (!result) return;
|
|
749
725
|
const { item } = result;
|
|
750
726
|
if (!item.plan || item.plan.length === 0) {
|
|
751
|
-
console.log(
|
|
727
|
+
console.log(chalk9.dim("No plan defined for this item."));
|
|
752
728
|
return;
|
|
753
729
|
}
|
|
754
|
-
console.log(
|
|
730
|
+
console.log(chalk9.bold(item.name));
|
|
755
731
|
console.log();
|
|
756
732
|
for (const [i, phase] of item.plan.entries()) {
|
|
757
|
-
console.log(`${
|
|
733
|
+
console.log(`${chalk9.bold(`Phase ${i + 1}:`)} ${phase.name}`);
|
|
758
734
|
for (const task of phase.tasks) {
|
|
759
735
|
console.log(` - ${task.task}`);
|
|
760
736
|
if (task.verify) {
|
|
761
|
-
console.log(` ${
|
|
737
|
+
console.log(` ${chalk9.dim(`verify: ${task.verify}`)}`);
|
|
762
738
|
}
|
|
763
739
|
}
|
|
764
740
|
console.log();
|
|
@@ -766,14 +742,14 @@ function plan(id) {
|
|
|
766
742
|
}
|
|
767
743
|
|
|
768
744
|
// src/commands/backlog/show/index.ts
|
|
769
|
-
import
|
|
745
|
+
import chalk11 from "chalk";
|
|
770
746
|
|
|
771
747
|
// src/commands/backlog/formatComment.ts
|
|
772
|
-
import
|
|
748
|
+
import chalk10 from "chalk";
|
|
773
749
|
function formatComment(entry) {
|
|
774
|
-
const tag = entry.type === "summary" ?
|
|
775
|
-
const phase = entry.phase !== void 0 ?
|
|
776
|
-
const time =
|
|
750
|
+
const tag = entry.type === "summary" ? chalk10.magenta("[summary]") : chalk10.cyan("[comment]");
|
|
751
|
+
const phase = entry.phase !== void 0 ? chalk10.dim(` (phase ${entry.phase + 1})`) : "";
|
|
752
|
+
const time = chalk10.dim(entry.timestamp);
|
|
777
753
|
return `${tag}${phase} ${time}
|
|
778
754
|
${entry.text}`;
|
|
779
755
|
}
|
|
@@ -781,7 +757,7 @@ function formatComment(entry) {
|
|
|
781
757
|
// src/commands/backlog/show/index.ts
|
|
782
758
|
function printPlan(item) {
|
|
783
759
|
if (!item.plan || item.plan.length === 0) return;
|
|
784
|
-
console.log(
|
|
760
|
+
console.log(chalk11.bold("Plan"));
|
|
785
761
|
for (const [i, phase] of item.plan.entries()) {
|
|
786
762
|
const isCurrent = item.currentPhase === i;
|
|
787
763
|
printPhase(phase, i, isCurrent);
|
|
@@ -789,21 +765,21 @@ function printPlan(item) {
|
|
|
789
765
|
console.log();
|
|
790
766
|
}
|
|
791
767
|
function phaseHeader(index, name, isCurrent) {
|
|
792
|
-
const marker = isCurrent ?
|
|
793
|
-
const label2 = isCurrent ?
|
|
768
|
+
const marker = isCurrent ? chalk11.green("\u25B6 ") : " ";
|
|
769
|
+
const label2 = isCurrent ? chalk11.green.bold(`Phase ${index + 1}: ${name}`) : `${chalk11.bold(`Phase ${index + 1}:`)} ${name}`;
|
|
794
770
|
return `${marker}${label2}`;
|
|
795
771
|
}
|
|
796
772
|
function printPhaseTasks(phase) {
|
|
797
773
|
for (const task of phase.tasks) {
|
|
798
774
|
console.log(` - ${task.task}`);
|
|
799
775
|
if (task.verify) {
|
|
800
|
-
console.log(` ${
|
|
776
|
+
console.log(` ${chalk11.dim(`verify: ${task.verify}`)}`);
|
|
801
777
|
}
|
|
802
778
|
}
|
|
803
779
|
if (phase.manualChecks && phase.manualChecks.length > 0) {
|
|
804
|
-
console.log(` ${
|
|
780
|
+
console.log(` ${chalk11.dim("Manual checks:")}`);
|
|
805
781
|
for (const check2 of phase.manualChecks) {
|
|
806
|
-
console.log(` ${
|
|
782
|
+
console.log(` ${chalk11.dim(`- ${check2}`)}`);
|
|
807
783
|
}
|
|
808
784
|
}
|
|
809
785
|
}
|
|
@@ -812,15 +788,15 @@ function printPhase(phase, index, isCurrent) {
|
|
|
812
788
|
printPhaseTasks(phase);
|
|
813
789
|
}
|
|
814
790
|
function printHeader(item) {
|
|
815
|
-
console.log(
|
|
791
|
+
console.log(chalk11.bold(`#${item.id} ${item.name}`));
|
|
816
792
|
console.log(
|
|
817
|
-
`${
|
|
793
|
+
`${chalk11.dim("Type:")} ${item.type} ${chalk11.dim("Status:")} ${item.status}`
|
|
818
794
|
);
|
|
819
795
|
console.log();
|
|
820
796
|
}
|
|
821
797
|
function printAcceptanceCriteria(criteria) {
|
|
822
798
|
if (criteria.length === 0) return;
|
|
823
|
-
console.log(
|
|
799
|
+
console.log(chalk11.bold("Acceptance Criteria"));
|
|
824
800
|
for (const [i, ac] of criteria.entries()) {
|
|
825
801
|
console.log(` ${i + 1}. ${ac}`);
|
|
826
802
|
}
|
|
@@ -832,7 +808,7 @@ function show(id) {
|
|
|
832
808
|
const { item } = result;
|
|
833
809
|
printHeader(item);
|
|
834
810
|
if (item.description) {
|
|
835
|
-
console.log(
|
|
811
|
+
console.log(chalk11.bold("Description"));
|
|
836
812
|
console.log(item.description);
|
|
837
813
|
console.log();
|
|
838
814
|
}
|
|
@@ -843,22 +819,13 @@ function show(id) {
|
|
|
843
819
|
function printComments(item) {
|
|
844
820
|
const entries = item.comments ?? [];
|
|
845
821
|
if (entries.length === 0) return;
|
|
846
|
-
console.log(
|
|
822
|
+
console.log(chalk11.bold("Comments"));
|
|
847
823
|
for (const entry of entries) {
|
|
848
824
|
console.log(` ${formatComment(entry)}`);
|
|
849
825
|
}
|
|
850
826
|
console.log();
|
|
851
827
|
}
|
|
852
828
|
|
|
853
|
-
// src/commands/backlog/start/index.ts
|
|
854
|
-
import chalk14 from "chalk";
|
|
855
|
-
async function start(id) {
|
|
856
|
-
const name = setStatus(id, "in-progress");
|
|
857
|
-
if (name) {
|
|
858
|
-
console.log(chalk14.green(`Started item #${id}: ${name}`));
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
|
|
862
829
|
// src/shared/web.ts
|
|
863
830
|
import { exec } from "child_process";
|
|
864
831
|
import { readFileSync as readFileSync4 } from "fs";
|
|
@@ -867,7 +834,7 @@ import {
|
|
|
867
834
|
} from "http";
|
|
868
835
|
import { dirname, join as join4 } from "path";
|
|
869
836
|
import { fileURLToPath } from "url";
|
|
870
|
-
import
|
|
837
|
+
import chalk12 from "chalk";
|
|
871
838
|
function respondJson(res, status2, data) {
|
|
872
839
|
res.writeHead(status2, { "Content-Type": "application/json" });
|
|
873
840
|
res.end(JSON.stringify(data));
|
|
@@ -911,8 +878,8 @@ function startWebServer(label2, port, handler) {
|
|
|
911
878
|
handler(req, res, port);
|
|
912
879
|
});
|
|
913
880
|
server.listen(port, () => {
|
|
914
|
-
console.log(
|
|
915
|
-
console.log(
|
|
881
|
+
console.log(chalk12.green(`${label2}: ${url}`));
|
|
882
|
+
console.log(chalk12.dim("Press Ctrl+C to stop"));
|
|
916
883
|
exec(`open ${url}`);
|
|
917
884
|
});
|
|
918
885
|
}
|
|
@@ -1060,7 +1027,7 @@ async function web(options2) {
|
|
|
1060
1027
|
}
|
|
1061
1028
|
|
|
1062
1029
|
// src/commands/backlog/launchMode.ts
|
|
1063
|
-
import
|
|
1030
|
+
import chalk13 from "chalk";
|
|
1064
1031
|
async function launchMode(slashCommand) {
|
|
1065
1032
|
process.env.ASSIST_SESSION_ID = String(process.pid);
|
|
1066
1033
|
const { child, done: done2 } = spawnClaude(`/${slashCommand}`);
|
|
@@ -1070,7 +1037,7 @@ async function launchMode(slashCommand) {
|
|
|
1070
1037
|
const signal = readSignal();
|
|
1071
1038
|
cleanupSignal();
|
|
1072
1039
|
if (signal?.event === "next") {
|
|
1073
|
-
console.log(
|
|
1040
|
+
console.log(chalk13.bold("\nChaining into assist next...\n"));
|
|
1074
1041
|
await next({ allowEdits: true });
|
|
1075
1042
|
}
|
|
1076
1043
|
}
|
|
@@ -1082,7 +1049,7 @@ import { execSync } from "child_process";
|
|
|
1082
1049
|
import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
1083
1050
|
import { homedir } from "os";
|
|
1084
1051
|
import { basename, dirname as dirname2, join as join5 } from "path";
|
|
1085
|
-
import
|
|
1052
|
+
import chalk14 from "chalk";
|
|
1086
1053
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
1087
1054
|
|
|
1088
1055
|
// src/shared/loadRawYaml.ts
|
|
@@ -1190,6 +1157,12 @@ var assistConfigSchema = z2.strictObject({
|
|
|
1190
1157
|
screenshot: z2.strictObject({
|
|
1191
1158
|
outputDir: z2.string().default("./screenshots")
|
|
1192
1159
|
}).default({ outputDir: "./screenshots" }),
|
|
1160
|
+
deny: z2.array(
|
|
1161
|
+
z2.strictObject({
|
|
1162
|
+
pattern: z2.string(),
|
|
1163
|
+
message: z2.string()
|
|
1164
|
+
})
|
|
1165
|
+
).optional(),
|
|
1193
1166
|
sync: z2.strictObject({
|
|
1194
1167
|
autoConfirm: z2.boolean().default(false)
|
|
1195
1168
|
}).default({ autoConfirm: false }),
|
|
@@ -1272,7 +1245,7 @@ function getTranscriptConfig() {
|
|
|
1272
1245
|
const config = loadConfig();
|
|
1273
1246
|
if (!config.transcript) {
|
|
1274
1247
|
console.error(
|
|
1275
|
-
|
|
1248
|
+
chalk14.red(
|
|
1276
1249
|
"Transcript directories not configured. Run 'assist transcript configure' first."
|
|
1277
1250
|
)
|
|
1278
1251
|
);
|
|
@@ -1361,7 +1334,7 @@ function commit(args) {
|
|
|
1361
1334
|
}
|
|
1362
1335
|
|
|
1363
1336
|
// src/commands/config/index.ts
|
|
1364
|
-
import
|
|
1337
|
+
import chalk15 from "chalk";
|
|
1365
1338
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
1366
1339
|
|
|
1367
1340
|
// src/commands/config/setNestedValue.ts
|
|
@@ -1424,7 +1397,7 @@ function formatIssuePath(issue, key) {
|
|
|
1424
1397
|
function printValidationErrors(issues, key) {
|
|
1425
1398
|
for (const issue of issues) {
|
|
1426
1399
|
console.error(
|
|
1427
|
-
|
|
1400
|
+
chalk15.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
1428
1401
|
);
|
|
1429
1402
|
}
|
|
1430
1403
|
}
|
|
@@ -1441,7 +1414,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
1441
1414
|
function assertNotGlobalOnly(key, global) {
|
|
1442
1415
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
1443
1416
|
console.error(
|
|
1444
|
-
|
|
1417
|
+
chalk15.red(
|
|
1445
1418
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
1446
1419
|
)
|
|
1447
1420
|
);
|
|
@@ -1464,7 +1437,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
1464
1437
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
1465
1438
|
const target = options2.global ? "global" : "project";
|
|
1466
1439
|
console.log(
|
|
1467
|
-
|
|
1440
|
+
chalk15.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
1468
1441
|
);
|
|
1469
1442
|
}
|
|
1470
1443
|
function configList() {
|
|
@@ -1473,7 +1446,7 @@ function configList() {
|
|
|
1473
1446
|
}
|
|
1474
1447
|
|
|
1475
1448
|
// src/commands/config/configGet.ts
|
|
1476
|
-
import
|
|
1449
|
+
import chalk16 from "chalk";
|
|
1477
1450
|
|
|
1478
1451
|
// src/commands/config/getNestedValue.ts
|
|
1479
1452
|
function isTraversable(value) {
|
|
@@ -1505,7 +1478,7 @@ function requireNestedValue(config, key) {
|
|
|
1505
1478
|
return value;
|
|
1506
1479
|
}
|
|
1507
1480
|
function exitKeyNotSet(key) {
|
|
1508
|
-
console.error(
|
|
1481
|
+
console.error(chalk16.red(`Key "${key}" is not set`));
|
|
1509
1482
|
process.exit(1);
|
|
1510
1483
|
}
|
|
1511
1484
|
|
|
@@ -1525,10 +1498,10 @@ function coverage() {
|
|
|
1525
1498
|
}
|
|
1526
1499
|
|
|
1527
1500
|
// src/commands/verify/init/index.ts
|
|
1528
|
-
import
|
|
1501
|
+
import chalk31 from "chalk";
|
|
1529
1502
|
|
|
1530
1503
|
// src/shared/promptMultiselect.ts
|
|
1531
|
-
import
|
|
1504
|
+
import chalk17 from "chalk";
|
|
1532
1505
|
import enquirer3 from "enquirer";
|
|
1533
1506
|
async function promptMultiselect(message, options2) {
|
|
1534
1507
|
const { selected } = await exitOnCancel(
|
|
@@ -1538,7 +1511,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1538
1511
|
message,
|
|
1539
1512
|
choices: options2.map((opt) => ({
|
|
1540
1513
|
name: opt.value,
|
|
1541
|
-
message: `${opt.name} - ${
|
|
1514
|
+
message: `${opt.name} - ${chalk17.dim(opt.description)}`
|
|
1542
1515
|
})),
|
|
1543
1516
|
// @ts-expect-error - enquirer types don't include symbols but it's supported
|
|
1544
1517
|
symbols: {
|
|
@@ -1555,7 +1528,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1555
1528
|
// src/shared/readPackageJson.ts
|
|
1556
1529
|
import * as fs from "fs";
|
|
1557
1530
|
import * as path from "path";
|
|
1558
|
-
import
|
|
1531
|
+
import chalk18 from "chalk";
|
|
1559
1532
|
function findPackageJson() {
|
|
1560
1533
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1561
1534
|
if (fs.existsSync(packageJsonPath)) {
|
|
@@ -1569,7 +1542,7 @@ function readPackageJson(filePath) {
|
|
|
1569
1542
|
function requirePackageJson() {
|
|
1570
1543
|
const packageJsonPath = findPackageJson();
|
|
1571
1544
|
if (!packageJsonPath) {
|
|
1572
|
-
console.error(
|
|
1545
|
+
console.error(chalk18.red("No package.json found in current directory"));
|
|
1573
1546
|
process.exit(1);
|
|
1574
1547
|
}
|
|
1575
1548
|
const pkg = readPackageJson(packageJsonPath);
|
|
@@ -1600,7 +1573,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1600
1573
|
// src/commands/verify/installPackage.ts
|
|
1601
1574
|
import { execSync as execSync3 } from "child_process";
|
|
1602
1575
|
import { writeFileSync as writeFileSync5 } from "fs";
|
|
1603
|
-
import
|
|
1576
|
+
import chalk19 from "chalk";
|
|
1604
1577
|
function writePackageJson(filePath, pkg) {
|
|
1605
1578
|
writeFileSync5(filePath, `${JSON.stringify(pkg, null, 2)}
|
|
1606
1579
|
`);
|
|
@@ -1615,12 +1588,12 @@ function addScript(pkg, name, command) {
|
|
|
1615
1588
|
};
|
|
1616
1589
|
}
|
|
1617
1590
|
function installPackage(name, cwd) {
|
|
1618
|
-
console.log(
|
|
1591
|
+
console.log(chalk19.dim(`Installing ${name}...`));
|
|
1619
1592
|
try {
|
|
1620
1593
|
execSync3(`npm install -D ${name}`, { stdio: "inherit", cwd });
|
|
1621
1594
|
return true;
|
|
1622
1595
|
} catch {
|
|
1623
|
-
console.error(
|
|
1596
|
+
console.error(chalk19.red(`Failed to install ${name}`));
|
|
1624
1597
|
return false;
|
|
1625
1598
|
}
|
|
1626
1599
|
}
|
|
@@ -1667,9 +1640,9 @@ var expectedScripts = {
|
|
|
1667
1640
|
};
|
|
1668
1641
|
|
|
1669
1642
|
// src/commands/verify/setup/setupBuild.ts
|
|
1670
|
-
import
|
|
1643
|
+
import chalk20 from "chalk";
|
|
1671
1644
|
async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
1672
|
-
console.log(
|
|
1645
|
+
console.log(chalk20.blue("\nSetting up build verification..."));
|
|
1673
1646
|
let command;
|
|
1674
1647
|
if (hasVite && hasTypescript) {
|
|
1675
1648
|
command = "tsc -b && vite build --logLevel error";
|
|
@@ -1678,21 +1651,21 @@ async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
|
1678
1651
|
} else {
|
|
1679
1652
|
command = "npm run build";
|
|
1680
1653
|
}
|
|
1681
|
-
console.log(
|
|
1654
|
+
console.log(chalk20.dim(`Using: ${command}`));
|
|
1682
1655
|
writer("verify:build", command);
|
|
1683
1656
|
}
|
|
1684
1657
|
async function setupTypecheck(_packageJsonPath, writer) {
|
|
1685
|
-
console.log(
|
|
1658
|
+
console.log(chalk20.blue("\nSetting up typecheck verification..."));
|
|
1686
1659
|
const command = "tsc --noEmit";
|
|
1687
|
-
console.log(
|
|
1660
|
+
console.log(chalk20.dim(`Using: ${command}`));
|
|
1688
1661
|
writer("verify:typecheck", command);
|
|
1689
1662
|
}
|
|
1690
1663
|
|
|
1691
1664
|
// src/commands/verify/setup/setupDuplicateCode.ts
|
|
1692
1665
|
import * as path2 from "path";
|
|
1693
|
-
import
|
|
1666
|
+
import chalk21 from "chalk";
|
|
1694
1667
|
async function setupDuplicateCode(packageJsonPath, writer) {
|
|
1695
|
-
console.log(
|
|
1668
|
+
console.log(chalk21.blue("\nSetting up jscpd..."));
|
|
1696
1669
|
const cwd = path2.dirname(packageJsonPath);
|
|
1697
1670
|
const pkg = readPackageJson(packageJsonPath);
|
|
1698
1671
|
const hasJscpd = !!pkg.dependencies?.jscpd || !!pkg.devDependencies?.jscpd;
|
|
@@ -1704,12 +1677,12 @@ async function setupDuplicateCode(packageJsonPath, writer) {
|
|
|
1704
1677
|
|
|
1705
1678
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1706
1679
|
import * as path3 from "path";
|
|
1707
|
-
import
|
|
1680
|
+
import chalk23 from "chalk";
|
|
1708
1681
|
|
|
1709
1682
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
1710
1683
|
import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
1711
1684
|
import { join as join7 } from "path";
|
|
1712
|
-
import
|
|
1685
|
+
import chalk22 from "chalk";
|
|
1713
1686
|
function loadKnipConfig(knipJsonPath) {
|
|
1714
1687
|
if (existsSync9(knipJsonPath)) {
|
|
1715
1688
|
return JSON.parse(readFileSync8(knipJsonPath, "utf-8"));
|
|
@@ -1728,16 +1701,16 @@ function addToKnipIgnoreBinaries(cwd, binary) {
|
|
|
1728
1701
|
`${JSON.stringify(knipConfig, null, " ")}
|
|
1729
1702
|
`
|
|
1730
1703
|
);
|
|
1731
|
-
console.log(
|
|
1704
|
+
console.log(chalk22.dim(`Added '${binary}' to knip.json ignoreBinaries`));
|
|
1732
1705
|
}
|
|
1733
1706
|
} catch {
|
|
1734
|
-
console.log(
|
|
1707
|
+
console.log(chalk22.yellow("Warning: Could not update knip.json"));
|
|
1735
1708
|
}
|
|
1736
1709
|
}
|
|
1737
1710
|
|
|
1738
1711
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1739
1712
|
async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
1740
|
-
console.log(
|
|
1713
|
+
console.log(chalk23.blue("\nSetting up hardcoded colors check..."));
|
|
1741
1714
|
const cwd = path3.dirname(packageJsonPath);
|
|
1742
1715
|
if (!hasOpenColor) {
|
|
1743
1716
|
installPackage("open-color", cwd);
|
|
@@ -1748,9 +1721,9 @@ async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
|
1748
1721
|
|
|
1749
1722
|
// src/commands/verify/setup/setupKnip.ts
|
|
1750
1723
|
import * as path4 from "path";
|
|
1751
|
-
import
|
|
1724
|
+
import chalk24 from "chalk";
|
|
1752
1725
|
async function setupKnip(packageJsonPath, writer) {
|
|
1753
|
-
console.log(
|
|
1726
|
+
console.log(chalk24.blue("\nSetting up knip..."));
|
|
1754
1727
|
const cwd = path4.dirname(packageJsonPath);
|
|
1755
1728
|
const pkg = readPackageJson(packageJsonPath);
|
|
1756
1729
|
if (!pkg.devDependencies?.knip && !installPackage("knip", cwd)) {
|
|
@@ -1761,14 +1734,14 @@ async function setupKnip(packageJsonPath, writer) {
|
|
|
1761
1734
|
|
|
1762
1735
|
// src/commands/verify/setup/setupLint.ts
|
|
1763
1736
|
import * as path5 from "path";
|
|
1764
|
-
import
|
|
1737
|
+
import chalk27 from "chalk";
|
|
1765
1738
|
|
|
1766
1739
|
// src/commands/lint/init.ts
|
|
1767
1740
|
import { execSync as execSync5 } from "child_process";
|
|
1768
1741
|
import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
1769
1742
|
import { dirname as dirname7, join as join8 } from "path";
|
|
1770
1743
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1771
|
-
import
|
|
1744
|
+
import chalk26 from "chalk";
|
|
1772
1745
|
|
|
1773
1746
|
// src/shared/promptConfirm.ts
|
|
1774
1747
|
import enquirer4 from "enquirer";
|
|
@@ -1872,7 +1845,7 @@ function removeEslintScripts(scripts, options2) {
|
|
|
1872
1845
|
}
|
|
1873
1846
|
|
|
1874
1847
|
// src/utils/printDiff.ts
|
|
1875
|
-
import
|
|
1848
|
+
import chalk25 from "chalk";
|
|
1876
1849
|
import * as diff from "diff";
|
|
1877
1850
|
function normalizeJson(content) {
|
|
1878
1851
|
try {
|
|
@@ -1890,11 +1863,11 @@ function printDiff(oldContent, newContent) {
|
|
|
1890
1863
|
const lines = change.value.replace(/\n$/, "").split("\n");
|
|
1891
1864
|
for (const line of lines) {
|
|
1892
1865
|
if (change.added) {
|
|
1893
|
-
console.log(
|
|
1866
|
+
console.log(chalk25.green(`+ ${line}`));
|
|
1894
1867
|
} else if (change.removed) {
|
|
1895
|
-
console.log(
|
|
1868
|
+
console.log(chalk25.red(`- ${line}`));
|
|
1896
1869
|
} else {
|
|
1897
|
-
console.log(
|
|
1870
|
+
console.log(chalk25.dim(` ${line}`));
|
|
1898
1871
|
}
|
|
1899
1872
|
}
|
|
1900
1873
|
}
|
|
@@ -1928,10 +1901,10 @@ async function init() {
|
|
|
1928
1901
|
console.log("biome.json already has the correct linter config");
|
|
1929
1902
|
return;
|
|
1930
1903
|
}
|
|
1931
|
-
console.log(
|
|
1904
|
+
console.log(chalk26.yellow("\n\u26A0\uFE0F biome.json will be updated:"));
|
|
1932
1905
|
console.log();
|
|
1933
1906
|
printDiff(oldContent, newContent);
|
|
1934
|
-
const confirm = await promptConfirm(
|
|
1907
|
+
const confirm = await promptConfirm(chalk26.red("Update biome.json?"));
|
|
1935
1908
|
if (!confirm) {
|
|
1936
1909
|
console.log("Skipped biome.json update");
|
|
1937
1910
|
return;
|
|
@@ -1942,7 +1915,7 @@ async function init() {
|
|
|
1942
1915
|
|
|
1943
1916
|
// src/commands/verify/setup/setupLint.ts
|
|
1944
1917
|
async function setupLint(packageJsonPath, writer) {
|
|
1945
|
-
console.log(
|
|
1918
|
+
console.log(chalk27.blue("\nSetting up biome..."));
|
|
1946
1919
|
const cwd = path5.dirname(packageJsonPath);
|
|
1947
1920
|
const pkg = readPackageJson(packageJsonPath);
|
|
1948
1921
|
if (!pkg.devDependencies?.["@biomejs/biome"]) {
|
|
@@ -1956,9 +1929,9 @@ async function setupLint(packageJsonPath, writer) {
|
|
|
1956
1929
|
|
|
1957
1930
|
// src/commands/verify/setup/setupMadge.ts
|
|
1958
1931
|
import * as path6 from "path";
|
|
1959
|
-
import
|
|
1932
|
+
import chalk28 from "chalk";
|
|
1960
1933
|
async function setupMadge(packageJsonPath, writer) {
|
|
1961
|
-
console.log(
|
|
1934
|
+
console.log(chalk28.blue("\nSetting up madge..."));
|
|
1962
1935
|
const cwd = path6.dirname(packageJsonPath);
|
|
1963
1936
|
const pkg = readPackageJson(packageJsonPath);
|
|
1964
1937
|
const hasMadge = !!pkg.dependencies?.madge || !!pkg.devDependencies?.madge;
|
|
@@ -1970,18 +1943,18 @@ async function setupMadge(packageJsonPath, writer) {
|
|
|
1970
1943
|
|
|
1971
1944
|
// src/commands/verify/setup/setupMaintainability.ts
|
|
1972
1945
|
import * as path7 from "path";
|
|
1973
|
-
import
|
|
1946
|
+
import chalk29 from "chalk";
|
|
1974
1947
|
async function setupMaintainability(packageJsonPath, writer) {
|
|
1975
|
-
console.log(
|
|
1948
|
+
console.log(chalk29.blue("\nSetting up maintainability check..."));
|
|
1976
1949
|
addToKnipIgnoreBinaries(path7.dirname(packageJsonPath), "assist");
|
|
1977
1950
|
writer("verify:maintainability", expectedScripts["verify:maintainability"]);
|
|
1978
1951
|
}
|
|
1979
1952
|
|
|
1980
1953
|
// src/commands/verify/setup/setupTest.ts
|
|
1981
1954
|
import * as path8 from "path";
|
|
1982
|
-
import
|
|
1955
|
+
import chalk30 from "chalk";
|
|
1983
1956
|
async function setupTest(packageJsonPath, writer) {
|
|
1984
|
-
console.log(
|
|
1957
|
+
console.log(chalk30.blue("\nSetting up vitest..."));
|
|
1985
1958
|
const cwd = path8.dirname(packageJsonPath);
|
|
1986
1959
|
const pkg = readPackageJson(packageJsonPath);
|
|
1987
1960
|
if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
|
|
@@ -2150,25 +2123,25 @@ async function runSelectedSetups(selected, packageJsonPath, writer, handlers) {
|
|
|
2150
2123
|
for (const choice of selected) {
|
|
2151
2124
|
await handlers[choice]?.(packageJsonPath, writer);
|
|
2152
2125
|
}
|
|
2153
|
-
console.log(
|
|
2126
|
+
console.log(chalk31.green(`
|
|
2154
2127
|
Added ${selected.length} verify script(s):`));
|
|
2155
2128
|
for (const choice of selected) {
|
|
2156
|
-
console.log(
|
|
2129
|
+
console.log(chalk31.green(` - verify:${choice}`));
|
|
2157
2130
|
}
|
|
2158
|
-
console.log(
|
|
2131
|
+
console.log(chalk31.dim("\nRun 'assist verify' to run all verify scripts"));
|
|
2159
2132
|
}
|
|
2160
2133
|
async function promptForScripts(availableOptions) {
|
|
2161
2134
|
if (availableOptions.length === 0) {
|
|
2162
|
-
console.log(
|
|
2135
|
+
console.log(chalk31.green("All verify scripts are already configured!"));
|
|
2163
2136
|
return null;
|
|
2164
2137
|
}
|
|
2165
|
-
console.log(
|
|
2138
|
+
console.log(chalk31.bold("Available verify scripts to add:\n"));
|
|
2166
2139
|
const selected = await promptMultiselect(
|
|
2167
2140
|
"Select verify scripts to add:",
|
|
2168
2141
|
availableOptions
|
|
2169
2142
|
);
|
|
2170
2143
|
if (selected.length === 0) {
|
|
2171
|
-
console.log(
|
|
2144
|
+
console.log(chalk31.yellow("No scripts selected"));
|
|
2172
2145
|
return null;
|
|
2173
2146
|
}
|
|
2174
2147
|
return selected;
|
|
@@ -2188,17 +2161,17 @@ async function init2() {
|
|
|
2188
2161
|
}
|
|
2189
2162
|
|
|
2190
2163
|
// src/commands/vscode/init/index.ts
|
|
2191
|
-
import
|
|
2164
|
+
import chalk33 from "chalk";
|
|
2192
2165
|
|
|
2193
2166
|
// src/commands/vscode/init/createLaunchJson.ts
|
|
2194
2167
|
import * as fs2 from "fs";
|
|
2195
2168
|
import * as path9 from "path";
|
|
2196
|
-
import
|
|
2169
|
+
import chalk32 from "chalk";
|
|
2197
2170
|
function ensureVscodeFolder() {
|
|
2198
2171
|
const vscodeDir = path9.join(process.cwd(), ".vscode");
|
|
2199
2172
|
if (!fs2.existsSync(vscodeDir)) {
|
|
2200
2173
|
fs2.mkdirSync(vscodeDir);
|
|
2201
|
-
console.log(
|
|
2174
|
+
console.log(chalk32.dim("Created .vscode folder"));
|
|
2202
2175
|
}
|
|
2203
2176
|
}
|
|
2204
2177
|
function removeVscodeFromGitignore() {
|
|
@@ -2213,7 +2186,7 @@ function removeVscodeFromGitignore() {
|
|
|
2213
2186
|
);
|
|
2214
2187
|
if (filteredLines.length !== lines.length) {
|
|
2215
2188
|
fs2.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
2216
|
-
console.log(
|
|
2189
|
+
console.log(chalk32.dim("Removed .vscode references from .gitignore"));
|
|
2217
2190
|
}
|
|
2218
2191
|
}
|
|
2219
2192
|
function createLaunchJson(type) {
|
|
@@ -2232,7 +2205,7 @@ function createLaunchJson(type) {
|
|
|
2232
2205
|
const launchPath = path9.join(process.cwd(), ".vscode", "launch.json");
|
|
2233
2206
|
fs2.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
|
|
2234
2207
|
`);
|
|
2235
|
-
console.log(
|
|
2208
|
+
console.log(chalk32.green("Created .vscode/launch.json"));
|
|
2236
2209
|
}
|
|
2237
2210
|
function createSettingsJson() {
|
|
2238
2211
|
const settings = {
|
|
@@ -2245,7 +2218,7 @@ function createSettingsJson() {
|
|
|
2245
2218
|
const settingsPath = path9.join(process.cwd(), ".vscode", "settings.json");
|
|
2246
2219
|
fs2.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
|
|
2247
2220
|
`);
|
|
2248
|
-
console.log(
|
|
2221
|
+
console.log(chalk32.green("Created .vscode/settings.json"));
|
|
2249
2222
|
}
|
|
2250
2223
|
function createExtensionsJson() {
|
|
2251
2224
|
const extensions = {
|
|
@@ -2257,7 +2230,7 @@ function createExtensionsJson() {
|
|
|
2257
2230
|
`${JSON.stringify(extensions, null, " ")}
|
|
2258
2231
|
`
|
|
2259
2232
|
);
|
|
2260
|
-
console.log(
|
|
2233
|
+
console.log(chalk32.green("Created .vscode/extensions.json"));
|
|
2261
2234
|
}
|
|
2262
2235
|
|
|
2263
2236
|
// src/commands/vscode/init/detectVscodeSetup.ts
|
|
@@ -2314,7 +2287,7 @@ function applySelections(selected, setup2) {
|
|
|
2314
2287
|
for (const choice of selected) handlers[choice]?.();
|
|
2315
2288
|
}
|
|
2316
2289
|
async function promptForOptions(options2) {
|
|
2317
|
-
console.log(
|
|
2290
|
+
console.log(chalk33.bold("Available VS Code configurations to add:\n"));
|
|
2318
2291
|
return promptMultiselect("Select configurations to add:", options2);
|
|
2319
2292
|
}
|
|
2320
2293
|
async function init3({ all = false } = {}) {
|
|
@@ -2322,17 +2295,17 @@ async function init3({ all = false } = {}) {
|
|
|
2322
2295
|
const setup2 = detectVscodeSetup(pkg);
|
|
2323
2296
|
const options2 = getAvailableOptions2(setup2);
|
|
2324
2297
|
if (options2.length === 0) {
|
|
2325
|
-
console.log(
|
|
2298
|
+
console.log(chalk33.green("VS Code configuration already exists!"));
|
|
2326
2299
|
return;
|
|
2327
2300
|
}
|
|
2328
2301
|
const selected = all ? options2.map((o) => o.value) : await promptForOptions(options2);
|
|
2329
2302
|
if (selected.length === 0) {
|
|
2330
|
-
console.log(
|
|
2303
|
+
console.log(chalk33.yellow("No configurations selected"));
|
|
2331
2304
|
return;
|
|
2332
2305
|
}
|
|
2333
2306
|
applySelections(selected, setup2);
|
|
2334
2307
|
console.log(
|
|
2335
|
-
|
|
2308
|
+
chalk33.green(`
|
|
2336
2309
|
Added ${selected.length} VS Code configuration(s)`)
|
|
2337
2310
|
);
|
|
2338
2311
|
}
|
|
@@ -2345,7 +2318,7 @@ async function init4() {
|
|
|
2345
2318
|
|
|
2346
2319
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2347
2320
|
import path16 from "path";
|
|
2348
|
-
import
|
|
2321
|
+
import chalk35 from "chalk";
|
|
2349
2322
|
|
|
2350
2323
|
// src/commands/lint/lint/checkFileNames.ts
|
|
2351
2324
|
import fs5 from "fs";
|
|
@@ -2425,7 +2398,7 @@ function checkFileNames() {
|
|
|
2425
2398
|
}
|
|
2426
2399
|
|
|
2427
2400
|
// src/commands/lint/lint/fixFileNameViolations.ts
|
|
2428
|
-
import
|
|
2401
|
+
import chalk34 from "chalk";
|
|
2429
2402
|
|
|
2430
2403
|
// src/commands/lint/lint/applyMoves.ts
|
|
2431
2404
|
import fs6 from "fs";
|
|
@@ -2510,25 +2483,25 @@ function fixFileNameViolations(moves) {
|
|
|
2510
2483
|
const start3 = performance.now();
|
|
2511
2484
|
const project = createLintProject();
|
|
2512
2485
|
const cwd = process.cwd();
|
|
2513
|
-
applyMoves(project, moves, cwd, (line) => console.log(
|
|
2486
|
+
applyMoves(project, moves, cwd, (line) => console.log(chalk34.green(line)));
|
|
2514
2487
|
const ms = (performance.now() - start3).toFixed(0);
|
|
2515
|
-
console.log(
|
|
2488
|
+
console.log(chalk34.dim(` Done in ${ms}ms`));
|
|
2516
2489
|
}
|
|
2517
2490
|
|
|
2518
2491
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2519
2492
|
function reportViolations(violations) {
|
|
2520
|
-
console.error(
|
|
2493
|
+
console.error(chalk35.red("\nFile name check failed:\n"));
|
|
2521
2494
|
console.error(
|
|
2522
|
-
|
|
2495
|
+
chalk35.red(
|
|
2523
2496
|
" Files without classes or React components should not start with a capital letter.\n"
|
|
2524
2497
|
)
|
|
2525
2498
|
);
|
|
2526
2499
|
for (const violation of violations) {
|
|
2527
|
-
console.error(
|
|
2528
|
-
console.error(
|
|
2500
|
+
console.error(chalk35.red(` ${violation.filePath}`));
|
|
2501
|
+
console.error(chalk35.gray(` Rename to: ${violation.suggestedName}
|
|
2529
2502
|
`));
|
|
2530
2503
|
}
|
|
2531
|
-
console.error(
|
|
2504
|
+
console.error(chalk35.dim(" Run with -f to auto-fix.\n"));
|
|
2532
2505
|
}
|
|
2533
2506
|
function runFileNameCheck(fix = false) {
|
|
2534
2507
|
const violations = checkFileNames();
|
|
@@ -2557,17 +2530,17 @@ function runFileNameCheck(fix = false) {
|
|
|
2557
2530
|
import fs8 from "fs";
|
|
2558
2531
|
|
|
2559
2532
|
// src/commands/lint/shared.ts
|
|
2560
|
-
import
|
|
2533
|
+
import chalk36 from "chalk";
|
|
2561
2534
|
function reportViolations2(violations, checkName, errorMessage, successMessage) {
|
|
2562
2535
|
if (violations.length > 0) {
|
|
2563
|
-
console.error(
|
|
2536
|
+
console.error(chalk36.red(`
|
|
2564
2537
|
${checkName} failed:
|
|
2565
2538
|
`));
|
|
2566
|
-
console.error(
|
|
2539
|
+
console.error(chalk36.red(` ${errorMessage}
|
|
2567
2540
|
`));
|
|
2568
2541
|
for (const violation of violations) {
|
|
2569
|
-
console.error(
|
|
2570
|
-
console.error(
|
|
2542
|
+
console.error(chalk36.red(` ${violation.filePath}:${violation.line}`));
|
|
2543
|
+
console.error(chalk36.gray(` ${violation.content}
|
|
2571
2544
|
`));
|
|
2572
2545
|
}
|
|
2573
2546
|
return false;
|
|
@@ -3047,14 +3020,14 @@ import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSy
|
|
|
3047
3020
|
|
|
3048
3021
|
// src/commands/deploy/init/index.ts
|
|
3049
3022
|
import { execSync as execSync12 } from "child_process";
|
|
3050
|
-
import
|
|
3023
|
+
import chalk38 from "chalk";
|
|
3051
3024
|
import enquirer5 from "enquirer";
|
|
3052
3025
|
|
|
3053
3026
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
3054
3027
|
import { existsSync as existsSync15, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
3055
3028
|
import { dirname as dirname13, join as join11 } from "path";
|
|
3056
3029
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3057
|
-
import
|
|
3030
|
+
import chalk37 from "chalk";
|
|
3058
3031
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
3059
3032
|
var __dirname3 = dirname13(fileURLToPath3(import.meta.url));
|
|
3060
3033
|
function getExistingSiteId() {
|
|
@@ -3079,20 +3052,20 @@ async function updateWorkflow(siteId) {
|
|
|
3079
3052
|
if (existsSync15(WORKFLOW_PATH)) {
|
|
3080
3053
|
const oldContent = readFileSync12(WORKFLOW_PATH, "utf-8");
|
|
3081
3054
|
if (oldContent === newContent) {
|
|
3082
|
-
console.log(
|
|
3055
|
+
console.log(chalk37.green("build.yml is already up to date"));
|
|
3083
3056
|
return;
|
|
3084
3057
|
}
|
|
3085
|
-
console.log(
|
|
3058
|
+
console.log(chalk37.yellow("\nbuild.yml will be updated:"));
|
|
3086
3059
|
console.log();
|
|
3087
3060
|
printDiff(oldContent, newContent);
|
|
3088
|
-
const confirm = await promptConfirm(
|
|
3061
|
+
const confirm = await promptConfirm(chalk37.red("Update build.yml?"));
|
|
3089
3062
|
if (!confirm) {
|
|
3090
3063
|
console.log("Skipped build.yml update");
|
|
3091
3064
|
return;
|
|
3092
3065
|
}
|
|
3093
3066
|
}
|
|
3094
3067
|
writeFileSync12(WORKFLOW_PATH, newContent);
|
|
3095
|
-
console.log(
|
|
3068
|
+
console.log(chalk37.green(`
|
|
3096
3069
|
Created ${WORKFLOW_PATH}`));
|
|
3097
3070
|
}
|
|
3098
3071
|
|
|
@@ -3103,43 +3076,43 @@ async function ensureNetlifyCli() {
|
|
|
3103
3076
|
} catch (error) {
|
|
3104
3077
|
if (!(error instanceof Error) || !error.message.includes("command not found"))
|
|
3105
3078
|
throw error;
|
|
3106
|
-
console.error(
|
|
3079
|
+
console.error(chalk38.red("\nNetlify CLI is not installed.\n"));
|
|
3107
3080
|
const install = await promptConfirm("Would you like to install it now?");
|
|
3108
3081
|
if (!install) {
|
|
3109
3082
|
console.log(
|
|
3110
|
-
|
|
3083
|
+
chalk38.yellow(
|
|
3111
3084
|
"\nInstall it manually with: npm install -g netlify-cli\n"
|
|
3112
3085
|
)
|
|
3113
3086
|
);
|
|
3114
3087
|
process.exit(1);
|
|
3115
3088
|
}
|
|
3116
|
-
console.log(
|
|
3089
|
+
console.log(chalk38.dim("\nInstalling netlify-cli...\n"));
|
|
3117
3090
|
execSync12("npm install -g netlify-cli", { stdio: "inherit" });
|
|
3118
3091
|
console.log();
|
|
3119
3092
|
execSync12("netlify sites:create --disable-linking", { stdio: "inherit" });
|
|
3120
3093
|
}
|
|
3121
3094
|
}
|
|
3122
3095
|
function printSetupInstructions() {
|
|
3123
|
-
console.log(
|
|
3096
|
+
console.log(chalk38.bold("\nDeployment initialized successfully!"));
|
|
3124
3097
|
console.log(
|
|
3125
|
-
|
|
3098
|
+
chalk38.yellow("\nTo complete setup, create a personal access token at:")
|
|
3126
3099
|
);
|
|
3127
3100
|
console.log(
|
|
3128
|
-
|
|
3101
|
+
chalk38.cyan(
|
|
3129
3102
|
"https://app.netlify.com/user/applications#personal-access-tokens"
|
|
3130
3103
|
)
|
|
3131
3104
|
);
|
|
3132
3105
|
console.log(
|
|
3133
|
-
|
|
3106
|
+
chalk38.yellow(
|
|
3134
3107
|
"\nThen add it as NETLIFY_AUTH_TOKEN in your GitHub repository secrets."
|
|
3135
3108
|
)
|
|
3136
3109
|
);
|
|
3137
3110
|
}
|
|
3138
3111
|
async function init5() {
|
|
3139
|
-
console.log(
|
|
3112
|
+
console.log(chalk38.bold("Initializing Netlify deployment...\n"));
|
|
3140
3113
|
const existingSiteId = getExistingSiteId();
|
|
3141
3114
|
if (existingSiteId) {
|
|
3142
|
-
console.log(
|
|
3115
|
+
console.log(chalk38.dim(`Using existing site ID: ${existingSiteId}
|
|
3143
3116
|
`));
|
|
3144
3117
|
await updateWorkflow(existingSiteId);
|
|
3145
3118
|
return;
|
|
@@ -3199,7 +3172,7 @@ function registerNew(program2) {
|
|
|
3199
3172
|
|
|
3200
3173
|
// src/lib/readStdin.ts
|
|
3201
3174
|
import * as readline from "readline";
|
|
3202
|
-
async function
|
|
3175
|
+
async function readStdin() {
|
|
3203
3176
|
const rl = readline.createInterface({
|
|
3204
3177
|
input: process.stdin,
|
|
3205
3178
|
output: process.stdout,
|
|
@@ -3290,7 +3263,7 @@ async function notify() {
|
|
|
3290
3263
|
if (!config.notify?.enabled) {
|
|
3291
3264
|
return;
|
|
3292
3265
|
}
|
|
3293
|
-
const inputData = await
|
|
3266
|
+
const inputData = await readStdin();
|
|
3294
3267
|
const data = JSON.parse(inputData);
|
|
3295
3268
|
const { notification_type, cwd, message } = data;
|
|
3296
3269
|
const projectName = cwd?.split(/[/\\]/).pop() ?? "Unknown Project";
|
|
@@ -3318,27 +3291,27 @@ async function notify() {
|
|
|
3318
3291
|
}
|
|
3319
3292
|
|
|
3320
3293
|
// src/commands/backlog/comment/index.ts
|
|
3321
|
-
import
|
|
3294
|
+
import chalk39 from "chalk";
|
|
3322
3295
|
function comment(id, text) {
|
|
3323
3296
|
const result = loadAndFindItem(id);
|
|
3324
3297
|
if (!result) process.exit(1);
|
|
3325
3298
|
addComment(result.item, text);
|
|
3326
3299
|
saveBacklog(result.items);
|
|
3327
|
-
console.log(
|
|
3300
|
+
console.log(chalk39.green(`Comment added to item #${id}.`));
|
|
3328
3301
|
}
|
|
3329
3302
|
|
|
3330
3303
|
// src/commands/backlog/comments/index.ts
|
|
3331
|
-
import
|
|
3304
|
+
import chalk40 from "chalk";
|
|
3332
3305
|
function comments(id) {
|
|
3333
3306
|
const result = loadAndFindItem(id);
|
|
3334
3307
|
if (!result) process.exit(1);
|
|
3335
3308
|
const { item } = result;
|
|
3336
3309
|
const entries = item.comments ?? [];
|
|
3337
3310
|
if (entries.length === 0) {
|
|
3338
|
-
console.log(
|
|
3311
|
+
console.log(chalk40.dim(`No comments on item #${id}.`));
|
|
3339
3312
|
return;
|
|
3340
3313
|
}
|
|
3341
|
-
console.log(
|
|
3314
|
+
console.log(chalk40.bold(`Comments for #${id}: ${item.name}
|
|
3342
3315
|
`));
|
|
3343
3316
|
for (const entry of entries) {
|
|
3344
3317
|
console.log(`${formatComment(entry)}
|
|
@@ -3354,11 +3327,11 @@ function registerCommentCommands(cmd) {
|
|
|
3354
3327
|
|
|
3355
3328
|
// src/commands/backlog/add/index.ts
|
|
3356
3329
|
import { existsSync as existsSync17 } from "fs";
|
|
3357
|
-
import
|
|
3330
|
+
import chalk42 from "chalk";
|
|
3358
3331
|
|
|
3359
3332
|
// src/commands/backlog/commitBacklog.ts
|
|
3360
3333
|
import { execSync as execSync14 } from "child_process";
|
|
3361
|
-
import
|
|
3334
|
+
import chalk41 from "chalk";
|
|
3362
3335
|
function commitBacklog(id, name) {
|
|
3363
3336
|
try {
|
|
3364
3337
|
const backlogPath = getBacklogPath();
|
|
@@ -3366,10 +3339,20 @@ function commitBacklog(id, name) {
|
|
|
3366
3339
|
execSync14(`git add ${shellQuote(backlogPath)}`, { stdio: "ignore" });
|
|
3367
3340
|
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3368
3341
|
} catch {
|
|
3369
|
-
console.log(
|
|
3342
|
+
console.log(chalk41.yellow("Warning: could not auto-commit backlog file."));
|
|
3370
3343
|
}
|
|
3371
3344
|
}
|
|
3372
3345
|
|
|
3346
|
+
// src/commands/backlog/readStdin.ts
|
|
3347
|
+
function readStdin2() {
|
|
3348
|
+
return new Promise((resolve7, reject) => {
|
|
3349
|
+
const chunks = [];
|
|
3350
|
+
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
3351
|
+
process.stdin.on("end", () => resolve7(Buffer.concat(chunks).toString()));
|
|
3352
|
+
process.stdin.on("error", reject);
|
|
3353
|
+
});
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3373
3356
|
// src/commands/backlog/add/shared.ts
|
|
3374
3357
|
import { spawnSync } from "child_process";
|
|
3375
3358
|
import { mkdtempSync, readFileSync as readFileSync14, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "fs";
|
|
@@ -3444,10 +3427,10 @@ async function promptAcceptanceCriteria() {
|
|
|
3444
3427
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3445
3428
|
async function addFromJson() {
|
|
3446
3429
|
if (process.stdin.isTTY) {
|
|
3447
|
-
console.log(
|
|
3430
|
+
console.log(chalk42.red("--json requires piped input on stdin."));
|
|
3448
3431
|
return;
|
|
3449
3432
|
}
|
|
3450
|
-
const input = await
|
|
3433
|
+
const input = await readStdin2();
|
|
3451
3434
|
const sanitised = input.replace(
|
|
3452
3435
|
/"(?:[^"\\]|\\.)*"/g,
|
|
3453
3436
|
(match) => match.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t")
|
|
@@ -3458,7 +3441,7 @@ async function addFromJson() {
|
|
|
3458
3441
|
items.push({ ...data, id, status: "todo" });
|
|
3459
3442
|
saveBacklog(items);
|
|
3460
3443
|
commitBacklog(id, data.name);
|
|
3461
|
-
console.log(
|
|
3444
|
+
console.log(chalk42.green(`Added item #${id}: ${data.name}`));
|
|
3462
3445
|
}
|
|
3463
3446
|
async function addInteractive() {
|
|
3464
3447
|
const type = await promptType();
|
|
@@ -3477,12 +3460,12 @@ async function addInteractive() {
|
|
|
3477
3460
|
});
|
|
3478
3461
|
saveBacklog(items);
|
|
3479
3462
|
commitBacklog(id, name);
|
|
3480
|
-
console.log(
|
|
3463
|
+
console.log(chalk42.green(`Added item #${id}: ${name}`));
|
|
3481
3464
|
}
|
|
3482
3465
|
async function add(options2) {
|
|
3483
3466
|
if (!existsSync17(getBacklogPath())) {
|
|
3484
3467
|
console.log(
|
|
3485
|
-
|
|
3468
|
+
chalk42.yellow(
|
|
3486
3469
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3487
3470
|
)
|
|
3488
3471
|
);
|
|
@@ -3497,20 +3480,20 @@ async function add(options2) {
|
|
|
3497
3480
|
|
|
3498
3481
|
// src/commands/backlog/init/index.ts
|
|
3499
3482
|
import { existsSync as existsSync18 } from "fs";
|
|
3500
|
-
import
|
|
3483
|
+
import chalk43 from "chalk";
|
|
3501
3484
|
async function init6() {
|
|
3502
3485
|
const backlogPath = getBacklogPath();
|
|
3503
3486
|
if (existsSync18(backlogPath)) {
|
|
3504
|
-
console.log(
|
|
3487
|
+
console.log(chalk43.yellow("assist.backlog.yml already exists."));
|
|
3505
3488
|
return;
|
|
3506
3489
|
}
|
|
3507
3490
|
saveBacklog([]);
|
|
3508
|
-
console.log(
|
|
3491
|
+
console.log(chalk43.green("Created assist.backlog.yml"));
|
|
3509
3492
|
}
|
|
3510
3493
|
|
|
3511
3494
|
// src/commands/backlog/list/index.ts
|
|
3512
3495
|
import { existsSync as existsSync19 } from "fs";
|
|
3513
|
-
import
|
|
3496
|
+
import chalk44 from "chalk";
|
|
3514
3497
|
function filterItems(items, options2) {
|
|
3515
3498
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3516
3499
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
@@ -3519,7 +3502,7 @@ function filterItems(items, options2) {
|
|
|
3519
3502
|
async function list2(options2) {
|
|
3520
3503
|
if (!existsSync19(getBacklogPath())) {
|
|
3521
3504
|
console.log(
|
|
3522
|
-
|
|
3505
|
+
chalk44.yellow(
|
|
3523
3506
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3524
3507
|
)
|
|
3525
3508
|
);
|
|
@@ -3527,12 +3510,12 @@ async function list2(options2) {
|
|
|
3527
3510
|
}
|
|
3528
3511
|
const items = filterItems(loadBacklog(), options2);
|
|
3529
3512
|
if (items.length === 0) {
|
|
3530
|
-
console.log(
|
|
3513
|
+
console.log(chalk44.dim("Backlog is empty."));
|
|
3531
3514
|
return;
|
|
3532
3515
|
}
|
|
3533
3516
|
for (const item of items) {
|
|
3534
3517
|
console.log(
|
|
3535
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3518
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk44.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
|
|
3536
3519
|
);
|
|
3537
3520
|
if (options2.verbose) {
|
|
3538
3521
|
printVerboseDetails(item);
|
|
@@ -3547,15 +3530,49 @@ function registerItemCommands(cmd) {
|
|
|
3547
3530
|
cmd.command("add").description("Add a new backlog item").option("--json", "Read item as JSON from stdin").action(add);
|
|
3548
3531
|
}
|
|
3549
3532
|
|
|
3550
|
-
// src/commands/
|
|
3551
|
-
|
|
3552
|
-
|
|
3533
|
+
// src/commands/backlog/delete/index.ts
|
|
3534
|
+
import chalk45 from "chalk";
|
|
3535
|
+
async function del(id) {
|
|
3536
|
+
const name = removeItem(id);
|
|
3537
|
+
if (name) {
|
|
3538
|
+
console.log(chalk45.green(`Deleted item #${id}: ${name}`));
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
|
|
3542
|
+
// src/commands/backlog/done/index.ts
|
|
3543
|
+
import chalk46 from "chalk";
|
|
3544
|
+
async function done(id, summary) {
|
|
3545
|
+
const result = loadAndFindItem(id);
|
|
3546
|
+
if (!result) return;
|
|
3547
|
+
result.item.status = "done";
|
|
3548
|
+
if (summary) {
|
|
3549
|
+
const phase = result.item.currentPhase ?? 0;
|
|
3550
|
+
addPhaseSummary(result.item, summary, phase);
|
|
3551
|
+
}
|
|
3552
|
+
saveBacklog(result.items);
|
|
3553
|
+
console.log(chalk46.green(`Completed item #${id}: ${result.item.name}`));
|
|
3554
|
+
}
|
|
3555
|
+
|
|
3556
|
+
// src/commands/backlog/start/index.ts
|
|
3557
|
+
import chalk47 from "chalk";
|
|
3558
|
+
async function start(id) {
|
|
3559
|
+
const name = setStatus(id, "in-progress");
|
|
3560
|
+
if (name) {
|
|
3561
|
+
console.log(chalk47.green(`Started item #${id}: ${name}`));
|
|
3562
|
+
}
|
|
3553
3563
|
}
|
|
3564
|
+
|
|
3565
|
+
// src/commands/backlog/registerStatusCommands.ts
|
|
3554
3566
|
function registerStatusCommands(cmd) {
|
|
3555
3567
|
cmd.command("start <id>").description("Set a backlog item to in-progress").action(start);
|
|
3556
3568
|
cmd.command("done <id> [summary]").description("Set a backlog item to done").action(done);
|
|
3557
3569
|
cmd.command("delete <id>").alias("remove").description("Delete a backlog item").action(del);
|
|
3558
3570
|
}
|
|
3571
|
+
|
|
3572
|
+
// src/commands/registerBacklog.ts
|
|
3573
|
+
function registerShowCommands(cmd) {
|
|
3574
|
+
cmd.command("show <id>").alias("view").description("Show full detail for a backlog item").action(show);
|
|
3575
|
+
}
|
|
3559
3576
|
function registerWebCommand(cmd) {
|
|
3560
3577
|
cmd.command("web").description("Start a web view of the backlog").option("-p, --port <number>", "Port to listen on", "3000").action(web);
|
|
3561
3578
|
}
|
|
@@ -3574,7 +3591,9 @@ function registerRunCommand(cmd) {
|
|
|
3574
3591
|
});
|
|
3575
3592
|
}
|
|
3576
3593
|
function registerBacklog(program2) {
|
|
3577
|
-
const cmd = program2.command("backlog").description("Manage a backlog of work items").
|
|
3594
|
+
const cmd = program2.command("backlog").description("Manage a backlog of work items").option("--dir <path>", "Override directory for backlog file discovery").hook("preAction", (thisCommand) => {
|
|
3595
|
+
setBacklogDir(thisCommand.opts().dir);
|
|
3596
|
+
}).action(() => web({ port: "3000" }));
|
|
3578
3597
|
registerItemCommands(cmd);
|
|
3579
3598
|
registerShowCommands(cmd);
|
|
3580
3599
|
registerStatusCommands(cmd);
|
|
@@ -3798,6 +3817,15 @@ function normalizeMsysPath(p) {
|
|
|
3798
3817
|
return m ? `${m[1].toUpperCase()}:${m[2]}` : p;
|
|
3799
3818
|
}
|
|
3800
3819
|
|
|
3820
|
+
// src/shared/matchesConfigDeny.ts
|
|
3821
|
+
function matchesConfigDeny(command) {
|
|
3822
|
+
const config = loadConfig();
|
|
3823
|
+
if (!config.deny) return void 0;
|
|
3824
|
+
return config.deny.find(
|
|
3825
|
+
(rule) => command === rule.pattern || command.startsWith(`${rule.pattern} `)
|
|
3826
|
+
);
|
|
3827
|
+
}
|
|
3828
|
+
|
|
3801
3829
|
// src/shared/splitCompound.ts
|
|
3802
3830
|
import { parse } from "shell-quote";
|
|
3803
3831
|
var SEPARATOR_OPS = /* @__PURE__ */ new Set(["|", "&&", "||", ";"]);
|
|
@@ -3855,7 +3883,16 @@ function stripEnvPrefix(parts) {
|
|
|
3855
3883
|
|
|
3856
3884
|
// src/commands/cliHook/index.ts
|
|
3857
3885
|
var SUPPORTED_TOOLS = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
3858
|
-
function
|
|
3886
|
+
function findDeny(toolName, parts) {
|
|
3887
|
+
for (const part of parts) {
|
|
3888
|
+
const configDeny = matchesConfigDeny(part);
|
|
3889
|
+
if (configDeny) {
|
|
3890
|
+
return {
|
|
3891
|
+
permissionDecision: "deny",
|
|
3892
|
+
permissionDecisionReason: configDeny.message
|
|
3893
|
+
};
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3859
3896
|
for (const part of parts) {
|
|
3860
3897
|
const denied = matchesDeny(toolName, part);
|
|
3861
3898
|
if (denied) {
|
|
@@ -3865,6 +3902,11 @@ function resolvePermission(toolName, parts) {
|
|
|
3865
3902
|
};
|
|
3866
3903
|
}
|
|
3867
3904
|
}
|
|
3905
|
+
return void 0;
|
|
3906
|
+
}
|
|
3907
|
+
function resolvePermission(toolName, parts) {
|
|
3908
|
+
const denied = findDeny(toolName, parts);
|
|
3909
|
+
if (denied) return denied;
|
|
3868
3910
|
const reasons = [];
|
|
3869
3911
|
for (const part of parts) {
|
|
3870
3912
|
const reason = isApprovedRead(part, toolName);
|
|
@@ -3876,27 +3918,29 @@ function resolvePermission(toolName, parts) {
|
|
|
3876
3918
|
permissionDecisionReason: reasons.join("; ")
|
|
3877
3919
|
};
|
|
3878
3920
|
}
|
|
3879
|
-
|
|
3880
|
-
const inputData = await readStdin2();
|
|
3881
|
-
let data;
|
|
3921
|
+
function tryParseJson(raw) {
|
|
3882
3922
|
try {
|
|
3883
|
-
|
|
3923
|
+
return JSON.parse(raw);
|
|
3884
3924
|
} catch {
|
|
3885
|
-
return;
|
|
3886
|
-
}
|
|
3887
|
-
if (!SUPPORTED_TOOLS.has(data.tool_name) || !data.tool_input?.command) {
|
|
3888
|
-
return;
|
|
3925
|
+
return void 0;
|
|
3889
3926
|
}
|
|
3927
|
+
}
|
|
3928
|
+
function extractCommand(data) {
|
|
3929
|
+
if (!SUPPORTED_TOOLS.has(data.tool_name) || !data.tool_input?.command)
|
|
3930
|
+
return void 0;
|
|
3890
3931
|
const parts = splitCompound(data.tool_input.command.trim());
|
|
3891
|
-
|
|
3892
|
-
|
|
3932
|
+
return parts ? { toolName: data.tool_name, parts } : void 0;
|
|
3933
|
+
}
|
|
3934
|
+
async function cliHook() {
|
|
3935
|
+
const data = tryParseJson(await readStdin());
|
|
3936
|
+
if (!data) return;
|
|
3937
|
+
const cmd = extractCommand(data);
|
|
3938
|
+
if (!cmd) return;
|
|
3939
|
+
const decision = resolvePermission(cmd.toolName, cmd.parts);
|
|
3893
3940
|
if (!decision) return;
|
|
3894
3941
|
console.log(
|
|
3895
3942
|
JSON.stringify({
|
|
3896
|
-
hookSpecificOutput: {
|
|
3897
|
-
hookEventName: "PreToolUse",
|
|
3898
|
-
...decision
|
|
3899
|
-
}
|
|
3943
|
+
hookSpecificOutput: { hookEventName: "PreToolUse", ...decision }
|
|
3900
3944
|
})
|
|
3901
3945
|
);
|
|
3902
3946
|
}
|
|
@@ -3910,6 +3954,14 @@ function cliHookCheck(command) {
|
|
|
3910
3954
|
process.exitCode = 1;
|
|
3911
3955
|
return;
|
|
3912
3956
|
}
|
|
3957
|
+
for (const part of parts) {
|
|
3958
|
+
const configDeny = matchesConfigDeny(part);
|
|
3959
|
+
if (configDeny) {
|
|
3960
|
+
console.log(`denied: ${configDeny.message}`);
|
|
3961
|
+
process.exitCode = 1;
|
|
3962
|
+
return;
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3913
3965
|
const reasons = [];
|
|
3914
3966
|
for (const part of parts) {
|
|
3915
3967
|
const reason = isApprovedRead(part);
|
|
@@ -3924,6 +3976,51 @@ function cliHookCheck(command) {
|
|
|
3924
3976
|
${reasons.join("\n")}`);
|
|
3925
3977
|
}
|
|
3926
3978
|
|
|
3979
|
+
// src/commands/deny/denyAdd.ts
|
|
3980
|
+
import chalk48 from "chalk";
|
|
3981
|
+
function denyAdd(pattern2, message) {
|
|
3982
|
+
const config = loadProjectConfig();
|
|
3983
|
+
const deny = config.deny ?? [];
|
|
3984
|
+
if (deny.some((r) => r.pattern === pattern2)) {
|
|
3985
|
+
console.log(chalk48.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
3986
|
+
return;
|
|
3987
|
+
}
|
|
3988
|
+
deny.push({ pattern: pattern2, message });
|
|
3989
|
+
config.deny = deny;
|
|
3990
|
+
saveConfig(config);
|
|
3991
|
+
console.log(chalk48.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
3992
|
+
}
|
|
3993
|
+
|
|
3994
|
+
// src/commands/deny/denyList.ts
|
|
3995
|
+
import chalk49 from "chalk";
|
|
3996
|
+
function denyList() {
|
|
3997
|
+
const config = loadConfig();
|
|
3998
|
+
const deny = config.deny;
|
|
3999
|
+
if (!deny || deny.length === 0) {
|
|
4000
|
+
console.log(chalk49.dim("No deny rules configured."));
|
|
4001
|
+
return;
|
|
4002
|
+
}
|
|
4003
|
+
for (const rule of deny) {
|
|
4004
|
+
console.log(`${chalk49.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
|
|
4008
|
+
// src/commands/deny/denyRemove.ts
|
|
4009
|
+
import chalk50 from "chalk";
|
|
4010
|
+
function denyRemove(pattern2) {
|
|
4011
|
+
const config = loadProjectConfig();
|
|
4012
|
+
const deny = config.deny ?? [];
|
|
4013
|
+
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
4014
|
+
if (index === -1) {
|
|
4015
|
+
console.log(chalk50.yellow(`No deny rule found for: ${pattern2}`));
|
|
4016
|
+
return;
|
|
4017
|
+
}
|
|
4018
|
+
deny.splice(index, 1);
|
|
4019
|
+
config.deny = deny.length > 0 ? deny : void 0;
|
|
4020
|
+
saveConfig(config);
|
|
4021
|
+
console.log(chalk50.green(`Removed deny rule: ${pattern2}`));
|
|
4022
|
+
}
|
|
4023
|
+
|
|
3927
4024
|
// src/commands/permitCliReads/index.ts
|
|
3928
4025
|
import { existsSync as existsSync22, mkdirSync as mkdirSync4, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
|
|
3929
4026
|
import { homedir as homedir4 } from "os";
|
|
@@ -3971,11 +4068,11 @@ function assertCliExists(cli) {
|
|
|
3971
4068
|
}
|
|
3972
4069
|
|
|
3973
4070
|
// src/commands/permitCliReads/colorize.ts
|
|
3974
|
-
import
|
|
4071
|
+
import chalk51 from "chalk";
|
|
3975
4072
|
function colorize(plainOutput) {
|
|
3976
4073
|
return plainOutput.split("\n").map((line) => {
|
|
3977
|
-
if (line.startsWith(" R ")) return
|
|
3978
|
-
if (line.startsWith(" W ")) return
|
|
4074
|
+
if (line.startsWith(" R ")) return chalk51.green(line);
|
|
4075
|
+
if (line.startsWith(" W ")) return chalk51.red(line);
|
|
3979
4076
|
return line;
|
|
3980
4077
|
}).join("\n");
|
|
3981
4078
|
}
|
|
@@ -4286,18 +4383,22 @@ function registerCliHook(program2) {
|
|
|
4286
4383
|
).option("--no-cache", "Force fresh discovery, ignoring cached results").action((cli, options2) => {
|
|
4287
4384
|
permitCliReads(cli.join(" "), { noCache: !options2.cache });
|
|
4288
4385
|
});
|
|
4386
|
+
const denyCommand = cmd.command("deny").description("Manage command deny rules").action(denyList);
|
|
4387
|
+
denyCommand.command("add").description("Add a deny rule for a command pattern").argument("<pattern>", "Command prefix to deny").argument("<message>", "Correction message shown to the agent").action(denyAdd);
|
|
4388
|
+
denyCommand.command("remove").description("Remove a deny rule by pattern").argument("<pattern>", "Command prefix to remove").action(denyRemove);
|
|
4389
|
+
denyCommand.command("list").description("List all deny rules").action(denyList);
|
|
4289
4390
|
}
|
|
4290
4391
|
|
|
4291
4392
|
// src/commands/complexity/analyze.ts
|
|
4292
|
-
import
|
|
4393
|
+
import chalk57 from "chalk";
|
|
4293
4394
|
|
|
4294
4395
|
// src/commands/complexity/cyclomatic.ts
|
|
4295
|
-
import
|
|
4396
|
+
import chalk53 from "chalk";
|
|
4296
4397
|
|
|
4297
4398
|
// src/commands/complexity/shared/index.ts
|
|
4298
4399
|
import fs12 from "fs";
|
|
4299
4400
|
import path20 from "path";
|
|
4300
|
-
import
|
|
4401
|
+
import chalk52 from "chalk";
|
|
4301
4402
|
import ts5 from "typescript";
|
|
4302
4403
|
|
|
4303
4404
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4543,7 +4644,7 @@ function createSourceFromFile(filePath) {
|
|
|
4543
4644
|
function withSourceFiles(pattern2, callback) {
|
|
4544
4645
|
const files = findSourceFiles2(pattern2);
|
|
4545
4646
|
if (files.length === 0) {
|
|
4546
|
-
console.log(
|
|
4647
|
+
console.log(chalk52.yellow("No files found matching pattern"));
|
|
4547
4648
|
return void 0;
|
|
4548
4649
|
}
|
|
4549
4650
|
return callback(files);
|
|
@@ -4576,11 +4677,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4576
4677
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4577
4678
|
for (const { file, name, complexity } of results) {
|
|
4578
4679
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4579
|
-
const color = exceedsThreshold ?
|
|
4580
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4680
|
+
const color = exceedsThreshold ? chalk53.red : chalk53.white;
|
|
4681
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk53.cyan(complexity)}`);
|
|
4581
4682
|
}
|
|
4582
4683
|
console.log(
|
|
4583
|
-
|
|
4684
|
+
chalk53.dim(
|
|
4584
4685
|
`
|
|
4585
4686
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4586
4687
|
)
|
|
@@ -4592,7 +4693,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4592
4693
|
}
|
|
4593
4694
|
|
|
4594
4695
|
// src/commands/complexity/halstead.ts
|
|
4595
|
-
import
|
|
4696
|
+
import chalk54 from "chalk";
|
|
4596
4697
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4597
4698
|
withSourceFiles(pattern2, (files) => {
|
|
4598
4699
|
const results = [];
|
|
@@ -4607,13 +4708,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4607
4708
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4608
4709
|
for (const { file, name, metrics } of results) {
|
|
4609
4710
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4610
|
-
const color = exceedsThreshold ?
|
|
4711
|
+
const color = exceedsThreshold ? chalk54.red : chalk54.white;
|
|
4611
4712
|
console.log(
|
|
4612
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4713
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk54.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk54.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk54.magenta(metrics.effort.toFixed(1))}`
|
|
4613
4714
|
);
|
|
4614
4715
|
}
|
|
4615
4716
|
console.log(
|
|
4616
|
-
|
|
4717
|
+
chalk54.dim(
|
|
4617
4718
|
`
|
|
4618
4719
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4619
4720
|
)
|
|
@@ -4628,28 +4729,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4628
4729
|
import fs13 from "fs";
|
|
4629
4730
|
|
|
4630
4731
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4631
|
-
import
|
|
4732
|
+
import chalk55 from "chalk";
|
|
4632
4733
|
function displayMaintainabilityResults(results, threshold) {
|
|
4633
4734
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4634
4735
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4635
|
-
console.log(
|
|
4736
|
+
console.log(chalk55.green("All files pass maintainability threshold"));
|
|
4636
4737
|
} else {
|
|
4637
4738
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4638
|
-
const color = threshold !== void 0 ?
|
|
4739
|
+
const color = threshold !== void 0 ? chalk55.red : chalk55.white;
|
|
4639
4740
|
console.log(
|
|
4640
|
-
`${color(file)} \u2192 avg: ${
|
|
4741
|
+
`${color(file)} \u2192 avg: ${chalk55.cyan(avgMaintainability.toFixed(1))}, min: ${chalk55.yellow(minMaintainability.toFixed(1))}`
|
|
4641
4742
|
);
|
|
4642
4743
|
}
|
|
4643
4744
|
}
|
|
4644
|
-
console.log(
|
|
4745
|
+
console.log(chalk55.dim(`
|
|
4645
4746
|
Analyzed ${results.length} files`));
|
|
4646
4747
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4647
4748
|
console.error(
|
|
4648
|
-
|
|
4749
|
+
chalk55.red(
|
|
4649
4750
|
`
|
|
4650
4751
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4651
4752
|
|
|
4652
|
-
\u26A0\uFE0F ${
|
|
4753
|
+
\u26A0\uFE0F ${chalk55.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.`
|
|
4653
4754
|
)
|
|
4654
4755
|
);
|
|
4655
4756
|
process.exit(1);
|
|
@@ -4706,7 +4807,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4706
4807
|
|
|
4707
4808
|
// src/commands/complexity/sloc.ts
|
|
4708
4809
|
import fs14 from "fs";
|
|
4709
|
-
import
|
|
4810
|
+
import chalk56 from "chalk";
|
|
4710
4811
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4711
4812
|
withSourceFiles(pattern2, (files) => {
|
|
4712
4813
|
const results = [];
|
|
@@ -4722,12 +4823,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4722
4823
|
results.sort((a, b) => b.lines - a.lines);
|
|
4723
4824
|
for (const { file, lines } of results) {
|
|
4724
4825
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4725
|
-
const color = exceedsThreshold ?
|
|
4726
|
-
console.log(`${color(file)} \u2192 ${
|
|
4826
|
+
const color = exceedsThreshold ? chalk56.red : chalk56.white;
|
|
4827
|
+
console.log(`${color(file)} \u2192 ${chalk56.cyan(lines)} lines`);
|
|
4727
4828
|
}
|
|
4728
4829
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4729
4830
|
console.log(
|
|
4730
|
-
|
|
4831
|
+
chalk56.dim(`
|
|
4731
4832
|
Total: ${total} lines across ${files.length} files`)
|
|
4732
4833
|
);
|
|
4733
4834
|
if (hasViolation) {
|
|
@@ -4741,21 +4842,21 @@ async function analyze(pattern2) {
|
|
|
4741
4842
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4742
4843
|
const files = findSourceFiles2(searchPattern);
|
|
4743
4844
|
if (files.length === 0) {
|
|
4744
|
-
console.log(
|
|
4845
|
+
console.log(chalk57.yellow("No files found matching pattern"));
|
|
4745
4846
|
return;
|
|
4746
4847
|
}
|
|
4747
4848
|
if (files.length === 1) {
|
|
4748
4849
|
const file = files[0];
|
|
4749
|
-
console.log(
|
|
4850
|
+
console.log(chalk57.bold.underline("SLOC"));
|
|
4750
4851
|
await sloc(file);
|
|
4751
4852
|
console.log();
|
|
4752
|
-
console.log(
|
|
4853
|
+
console.log(chalk57.bold.underline("Cyclomatic Complexity"));
|
|
4753
4854
|
await cyclomatic(file);
|
|
4754
4855
|
console.log();
|
|
4755
|
-
console.log(
|
|
4856
|
+
console.log(chalk57.bold.underline("Halstead Metrics"));
|
|
4756
4857
|
await halstead(file);
|
|
4757
4858
|
console.log();
|
|
4758
|
-
console.log(
|
|
4859
|
+
console.log(chalk57.bold.underline("Maintainability Index"));
|
|
4759
4860
|
await maintainability(file);
|
|
4760
4861
|
return;
|
|
4761
4862
|
}
|
|
@@ -4783,7 +4884,7 @@ function registerComplexity(program2) {
|
|
|
4783
4884
|
|
|
4784
4885
|
// src/commands/deploy/redirect.ts
|
|
4785
4886
|
import { existsSync as existsSync23, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
4786
|
-
import
|
|
4887
|
+
import chalk58 from "chalk";
|
|
4787
4888
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4788
4889
|
if (!window.location.pathname.endsWith('/')) {
|
|
4789
4890
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4792,22 +4893,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4792
4893
|
function redirect() {
|
|
4793
4894
|
const indexPath = "index.html";
|
|
4794
4895
|
if (!existsSync23(indexPath)) {
|
|
4795
|
-
console.log(
|
|
4896
|
+
console.log(chalk58.yellow("No index.html found"));
|
|
4796
4897
|
return;
|
|
4797
4898
|
}
|
|
4798
4899
|
const content = readFileSync18(indexPath, "utf-8");
|
|
4799
4900
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4800
|
-
console.log(
|
|
4901
|
+
console.log(chalk58.dim("Trailing slash script already present"));
|
|
4801
4902
|
return;
|
|
4802
4903
|
}
|
|
4803
4904
|
const headCloseIndex = content.indexOf("</head>");
|
|
4804
4905
|
if (headCloseIndex === -1) {
|
|
4805
|
-
console.log(
|
|
4906
|
+
console.log(chalk58.red("Could not find </head> tag in index.html"));
|
|
4806
4907
|
return;
|
|
4807
4908
|
}
|
|
4808
4909
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4809
4910
|
writeFileSync17(indexPath, newContent);
|
|
4810
|
-
console.log(
|
|
4911
|
+
console.log(chalk58.green("Added trailing slash redirect to index.html"));
|
|
4811
4912
|
}
|
|
4812
4913
|
|
|
4813
4914
|
// src/commands/registerDeploy.ts
|
|
@@ -4834,7 +4935,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
4834
4935
|
|
|
4835
4936
|
// src/commands/devlog/shared.ts
|
|
4836
4937
|
import { execSync as execSync17 } from "child_process";
|
|
4837
|
-
import
|
|
4938
|
+
import chalk59 from "chalk";
|
|
4838
4939
|
|
|
4839
4940
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4840
4941
|
import { readdirSync, readFileSync as readFileSync19 } from "fs";
|
|
@@ -4921,13 +5022,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4921
5022
|
}
|
|
4922
5023
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4923
5024
|
for (const commit2 of commits) {
|
|
4924
|
-
console.log(` ${
|
|
5025
|
+
console.log(` ${chalk59.yellow(commit2.hash)} ${commit2.message}`);
|
|
4925
5026
|
if (verbose) {
|
|
4926
5027
|
const visibleFiles = commit2.files.filter(
|
|
4927
5028
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4928
5029
|
);
|
|
4929
5030
|
for (const file of visibleFiles) {
|
|
4930
|
-
console.log(` ${
|
|
5031
|
+
console.log(` ${chalk59.dim(file)}`);
|
|
4931
5032
|
}
|
|
4932
5033
|
}
|
|
4933
5034
|
}
|
|
@@ -4952,15 +5053,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4952
5053
|
}
|
|
4953
5054
|
|
|
4954
5055
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4955
|
-
import
|
|
5056
|
+
import chalk60 from "chalk";
|
|
4956
5057
|
function printDateHeader(date, isSkipped, entries) {
|
|
4957
5058
|
if (isSkipped) {
|
|
4958
|
-
console.log(`${
|
|
5059
|
+
console.log(`${chalk60.bold.blue(date)} ${chalk60.dim("skipped")}`);
|
|
4959
5060
|
} else if (entries && entries.length > 0) {
|
|
4960
|
-
const entryInfo = entries.map((e) => `${
|
|
4961
|
-
console.log(`${
|
|
5061
|
+
const entryInfo = entries.map((e) => `${chalk60.green(e.version)} ${e.title}`).join(" | ");
|
|
5062
|
+
console.log(`${chalk60.bold.blue(date)} ${entryInfo}`);
|
|
4962
5063
|
} else {
|
|
4963
|
-
console.log(`${
|
|
5064
|
+
console.log(`${chalk60.bold.blue(date)} ${chalk60.red("\u26A0 devlog missing")}`);
|
|
4964
5065
|
}
|
|
4965
5066
|
}
|
|
4966
5067
|
|
|
@@ -5063,24 +5164,24 @@ function bumpVersion(version2, type) {
|
|
|
5063
5164
|
|
|
5064
5165
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
5065
5166
|
import { execSync as execSync20 } from "child_process";
|
|
5066
|
-
import
|
|
5167
|
+
import chalk62 from "chalk";
|
|
5067
5168
|
|
|
5068
5169
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
5069
|
-
import
|
|
5170
|
+
import chalk61 from "chalk";
|
|
5070
5171
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
5071
5172
|
if (conventional && firstHash) {
|
|
5072
5173
|
const version2 = getVersionAtCommit(firstHash);
|
|
5073
5174
|
if (version2) {
|
|
5074
|
-
console.log(`${
|
|
5175
|
+
console.log(`${chalk61.bold("version:")} ${stripToMinor(version2)}`);
|
|
5075
5176
|
} else {
|
|
5076
|
-
console.log(`${
|
|
5177
|
+
console.log(`${chalk61.bold("version:")} ${chalk61.red("unknown")}`);
|
|
5077
5178
|
}
|
|
5078
5179
|
} else if (patchVersion && minorVersion) {
|
|
5079
5180
|
console.log(
|
|
5080
|
-
`${
|
|
5181
|
+
`${chalk61.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
5081
5182
|
);
|
|
5082
5183
|
} else {
|
|
5083
|
-
console.log(`${
|
|
5184
|
+
console.log(`${chalk61.bold("version:")} v0.1 (initial)`);
|
|
5084
5185
|
}
|
|
5085
5186
|
}
|
|
5086
5187
|
|
|
@@ -5127,16 +5228,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
5127
5228
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
5128
5229
|
}
|
|
5129
5230
|
function logName(repoName) {
|
|
5130
|
-
console.log(`${
|
|
5231
|
+
console.log(`${chalk62.bold("name:")} ${repoName}`);
|
|
5131
5232
|
}
|
|
5132
5233
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
5133
5234
|
logName(ctx.repoName);
|
|
5134
5235
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
5135
|
-
console.log(
|
|
5236
|
+
console.log(chalk62.bold.blue(targetDate));
|
|
5136
5237
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
5137
5238
|
}
|
|
5138
5239
|
function logNoCommits(lastInfo) {
|
|
5139
|
-
console.log(
|
|
5240
|
+
console.log(chalk62.dim(noCommitsMessage(!!lastInfo)));
|
|
5140
5241
|
}
|
|
5141
5242
|
|
|
5142
5243
|
// src/commands/devlog/next/index.ts
|
|
@@ -5177,11 +5278,11 @@ function next2(options2) {
|
|
|
5177
5278
|
import { execSync as execSync21 } from "child_process";
|
|
5178
5279
|
|
|
5179
5280
|
// src/commands/devlog/repos/printReposTable.ts
|
|
5180
|
-
import
|
|
5281
|
+
import chalk63 from "chalk";
|
|
5181
5282
|
function colorStatus(status2) {
|
|
5182
|
-
if (status2 === "missing") return
|
|
5183
|
-
if (status2 === "outdated") return
|
|
5184
|
-
return
|
|
5283
|
+
if (status2 === "missing") return chalk63.red(status2);
|
|
5284
|
+
if (status2 === "outdated") return chalk63.yellow(status2);
|
|
5285
|
+
return chalk63.green(status2);
|
|
5185
5286
|
}
|
|
5186
5287
|
function formatRow(row, nameWidth) {
|
|
5187
5288
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -5195,8 +5296,8 @@ function printReposTable(rows) {
|
|
|
5195
5296
|
"Last Devlog".padEnd(11),
|
|
5196
5297
|
"Status"
|
|
5197
5298
|
].join(" ");
|
|
5198
|
-
console.log(
|
|
5199
|
-
console.log(
|
|
5299
|
+
console.log(chalk63.dim(header));
|
|
5300
|
+
console.log(chalk63.dim("-".repeat(header.length)));
|
|
5200
5301
|
for (const row of rows) {
|
|
5201
5302
|
console.log(formatRow(row, nameWidth));
|
|
5202
5303
|
}
|
|
@@ -5254,14 +5355,14 @@ function repos(options2) {
|
|
|
5254
5355
|
// src/commands/devlog/skip.ts
|
|
5255
5356
|
import { writeFileSync as writeFileSync18 } from "fs";
|
|
5256
5357
|
import { join as join17 } from "path";
|
|
5257
|
-
import
|
|
5358
|
+
import chalk64 from "chalk";
|
|
5258
5359
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
5259
5360
|
function getBlogConfigPath() {
|
|
5260
5361
|
return join17(BLOG_REPO_ROOT, "assist.yml");
|
|
5261
5362
|
}
|
|
5262
5363
|
function skip(date) {
|
|
5263
5364
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5264
|
-
console.log(
|
|
5365
|
+
console.log(chalk64.red("Invalid date format. Use YYYY-MM-DD"));
|
|
5265
5366
|
process.exit(1);
|
|
5266
5367
|
}
|
|
5267
5368
|
const repoName = getRepoName();
|
|
@@ -5272,7 +5373,7 @@ function skip(date) {
|
|
|
5272
5373
|
const skipDays = skip2[repoName] ?? [];
|
|
5273
5374
|
if (skipDays.includes(date)) {
|
|
5274
5375
|
console.log(
|
|
5275
|
-
|
|
5376
|
+
chalk64.yellow(`${date} is already in skip list for ${repoName}`)
|
|
5276
5377
|
);
|
|
5277
5378
|
return;
|
|
5278
5379
|
}
|
|
@@ -5282,20 +5383,20 @@ function skip(date) {
|
|
|
5282
5383
|
devlog.skip = skip2;
|
|
5283
5384
|
config.devlog = devlog;
|
|
5284
5385
|
writeFileSync18(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
5285
|
-
console.log(
|
|
5386
|
+
console.log(chalk64.green(`Added ${date} to skip list for ${repoName}`));
|
|
5286
5387
|
}
|
|
5287
5388
|
|
|
5288
5389
|
// src/commands/devlog/version.ts
|
|
5289
|
-
import
|
|
5390
|
+
import chalk65 from "chalk";
|
|
5290
5391
|
function version() {
|
|
5291
5392
|
const config = loadConfig();
|
|
5292
5393
|
const name = getRepoName();
|
|
5293
5394
|
const lastInfo = getLastVersionInfo(name, config);
|
|
5294
5395
|
const lastVersion = lastInfo?.version ?? null;
|
|
5295
5396
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
5296
|
-
console.log(`${
|
|
5297
|
-
console.log(`${
|
|
5298
|
-
console.log(`${
|
|
5397
|
+
console.log(`${chalk65.bold("name:")} ${name}`);
|
|
5398
|
+
console.log(`${chalk65.bold("last:")} ${lastVersion ?? chalk65.dim("none")}`);
|
|
5399
|
+
console.log(`${chalk65.bold("next:")} ${nextVersion ?? chalk65.dim("none")}`);
|
|
5299
5400
|
}
|
|
5300
5401
|
|
|
5301
5402
|
// src/commands/registerDevlog.ts
|
|
@@ -5319,7 +5420,7 @@ function registerDevlog(program2) {
|
|
|
5319
5420
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5320
5421
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5321
5422
|
import { join as join18 } from "path";
|
|
5322
|
-
import
|
|
5423
|
+
import chalk66 from "chalk";
|
|
5323
5424
|
|
|
5324
5425
|
// src/shared/findRepoRoot.ts
|
|
5325
5426
|
import { existsSync as existsSync24 } from "fs";
|
|
@@ -5382,14 +5483,14 @@ function checkBuildLocks(startDir) {
|
|
|
5382
5483
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5383
5484
|
if (locked) {
|
|
5384
5485
|
console.error(
|
|
5385
|
-
|
|
5486
|
+
chalk66.red("Build output locked (is VS debugging?): ") + locked
|
|
5386
5487
|
);
|
|
5387
5488
|
process.exit(1);
|
|
5388
5489
|
}
|
|
5389
5490
|
}
|
|
5390
5491
|
async function checkBuildLocksCommand() {
|
|
5391
5492
|
checkBuildLocks();
|
|
5392
|
-
console.log(
|
|
5493
|
+
console.log(chalk66.green("No build locks detected"));
|
|
5393
5494
|
}
|
|
5394
5495
|
|
|
5395
5496
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -5488,30 +5589,30 @@ function escapeRegex(s) {
|
|
|
5488
5589
|
}
|
|
5489
5590
|
|
|
5490
5591
|
// src/commands/dotnet/printTree.ts
|
|
5491
|
-
import
|
|
5592
|
+
import chalk67 from "chalk";
|
|
5492
5593
|
function printNodes(nodes, prefix2) {
|
|
5493
5594
|
for (let i = 0; i < nodes.length; i++) {
|
|
5494
5595
|
const isLast = i === nodes.length - 1;
|
|
5495
5596
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5496
5597
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5497
5598
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5498
|
-
const label2 = isMissing ?
|
|
5599
|
+
const label2 = isMissing ? chalk67.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5499
5600
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5500
5601
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5501
5602
|
}
|
|
5502
5603
|
}
|
|
5503
5604
|
function printTree(tree, totalCount, solutions) {
|
|
5504
|
-
console.log(
|
|
5505
|
-
console.log(
|
|
5605
|
+
console.log(chalk67.bold("\nProject Dependency Tree"));
|
|
5606
|
+
console.log(chalk67.cyan(tree.relativePath));
|
|
5506
5607
|
printNodes(tree.children, "");
|
|
5507
|
-
console.log(
|
|
5608
|
+
console.log(chalk67.dim(`
|
|
5508
5609
|
${totalCount} projects total (including root)`));
|
|
5509
|
-
console.log(
|
|
5610
|
+
console.log(chalk67.bold("\nSolution Membership"));
|
|
5510
5611
|
if (solutions.length === 0) {
|
|
5511
|
-
console.log(
|
|
5612
|
+
console.log(chalk67.yellow(" Not found in any .sln"));
|
|
5512
5613
|
} else {
|
|
5513
5614
|
for (const sln of solutions) {
|
|
5514
|
-
console.log(` ${
|
|
5615
|
+
console.log(` ${chalk67.green(sln)}`);
|
|
5515
5616
|
}
|
|
5516
5617
|
}
|
|
5517
5618
|
console.log();
|
|
@@ -5540,16 +5641,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5540
5641
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5541
5642
|
import { existsSync as existsSync25 } from "fs";
|
|
5542
5643
|
import path24 from "path";
|
|
5543
|
-
import
|
|
5644
|
+
import chalk68 from "chalk";
|
|
5544
5645
|
function resolveCsproj(csprojPath) {
|
|
5545
5646
|
const resolved = path24.resolve(csprojPath);
|
|
5546
5647
|
if (!existsSync25(resolved)) {
|
|
5547
|
-
console.error(
|
|
5648
|
+
console.error(chalk68.red(`File not found: ${resolved}`));
|
|
5548
5649
|
process.exit(1);
|
|
5549
5650
|
}
|
|
5550
5651
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5551
5652
|
if (!repoRoot) {
|
|
5552
|
-
console.error(
|
|
5653
|
+
console.error(chalk68.red("Could not find git repository root"));
|
|
5553
5654
|
process.exit(1);
|
|
5554
5655
|
}
|
|
5555
5656
|
return { resolved, repoRoot };
|
|
@@ -5599,12 +5700,12 @@ function getChangedCsFiles(scope) {
|
|
|
5599
5700
|
}
|
|
5600
5701
|
|
|
5601
5702
|
// src/commands/dotnet/inSln.ts
|
|
5602
|
-
import
|
|
5703
|
+
import chalk69 from "chalk";
|
|
5603
5704
|
async function inSln(csprojPath) {
|
|
5604
5705
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5605
5706
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5606
5707
|
if (solutions.length === 0) {
|
|
5607
|
-
console.log(
|
|
5708
|
+
console.log(chalk69.yellow("Not found in any .sln file"));
|
|
5608
5709
|
process.exit(1);
|
|
5609
5710
|
}
|
|
5610
5711
|
for (const sln of solutions) {
|
|
@@ -5613,7 +5714,7 @@ async function inSln(csprojPath) {
|
|
|
5613
5714
|
}
|
|
5614
5715
|
|
|
5615
5716
|
// src/commands/dotnet/inspect.ts
|
|
5616
|
-
import
|
|
5717
|
+
import chalk75 from "chalk";
|
|
5617
5718
|
|
|
5618
5719
|
// src/shared/formatElapsed.ts
|
|
5619
5720
|
function formatElapsed(ms) {
|
|
@@ -5625,12 +5726,12 @@ function formatElapsed(ms) {
|
|
|
5625
5726
|
}
|
|
5626
5727
|
|
|
5627
5728
|
// src/commands/dotnet/displayIssues.ts
|
|
5628
|
-
import
|
|
5729
|
+
import chalk70 from "chalk";
|
|
5629
5730
|
var SEVERITY_COLOR = {
|
|
5630
|
-
ERROR:
|
|
5631
|
-
WARNING:
|
|
5632
|
-
SUGGESTION:
|
|
5633
|
-
HINT:
|
|
5731
|
+
ERROR: chalk70.red,
|
|
5732
|
+
WARNING: chalk70.yellow,
|
|
5733
|
+
SUGGESTION: chalk70.cyan,
|
|
5734
|
+
HINT: chalk70.dim
|
|
5634
5735
|
};
|
|
5635
5736
|
function groupByFile(issues) {
|
|
5636
5737
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5646,15 +5747,15 @@ function groupByFile(issues) {
|
|
|
5646
5747
|
}
|
|
5647
5748
|
function displayIssues(issues) {
|
|
5648
5749
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5649
|
-
console.log(
|
|
5750
|
+
console.log(chalk70.bold(file));
|
|
5650
5751
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5651
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5752
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk70.white;
|
|
5652
5753
|
console.log(
|
|
5653
|
-
` ${
|
|
5754
|
+
` ${chalk70.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5654
5755
|
);
|
|
5655
5756
|
}
|
|
5656
5757
|
}
|
|
5657
|
-
console.log(
|
|
5758
|
+
console.log(chalk70.dim(`
|
|
5658
5759
|
${issues.length} issue(s) found`));
|
|
5659
5760
|
}
|
|
5660
5761
|
|
|
@@ -5713,12 +5814,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5713
5814
|
// src/commands/dotnet/resolveSolution.ts
|
|
5714
5815
|
import { existsSync as existsSync26 } from "fs";
|
|
5715
5816
|
import path25 from "path";
|
|
5716
|
-
import
|
|
5817
|
+
import chalk72 from "chalk";
|
|
5717
5818
|
|
|
5718
5819
|
// src/commands/dotnet/findSolution.ts
|
|
5719
5820
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5720
5821
|
import { dirname as dirname16, join as join19 } from "path";
|
|
5721
|
-
import
|
|
5822
|
+
import chalk71 from "chalk";
|
|
5722
5823
|
function findSlnInDir(dir) {
|
|
5723
5824
|
try {
|
|
5724
5825
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join19(dir, f));
|
|
@@ -5734,17 +5835,17 @@ function findSolution() {
|
|
|
5734
5835
|
const slnFiles = findSlnInDir(current);
|
|
5735
5836
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5736
5837
|
if (slnFiles.length > 1) {
|
|
5737
|
-
console.error(
|
|
5838
|
+
console.error(chalk71.red(`Multiple .sln files found in ${current}:`));
|
|
5738
5839
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5739
5840
|
console.error(
|
|
5740
|
-
|
|
5841
|
+
chalk71.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5741
5842
|
);
|
|
5742
5843
|
process.exit(1);
|
|
5743
5844
|
}
|
|
5744
5845
|
if (current === ceiling) break;
|
|
5745
5846
|
current = dirname16(current);
|
|
5746
5847
|
}
|
|
5747
|
-
console.error(
|
|
5848
|
+
console.error(chalk71.red("No .sln file found between cwd and repo root"));
|
|
5748
5849
|
process.exit(1);
|
|
5749
5850
|
}
|
|
5750
5851
|
|
|
@@ -5753,7 +5854,7 @@ function resolveSolution(sln) {
|
|
|
5753
5854
|
if (sln) {
|
|
5754
5855
|
const resolved = path25.resolve(sln);
|
|
5755
5856
|
if (!existsSync26(resolved)) {
|
|
5756
|
-
console.error(
|
|
5857
|
+
console.error(chalk72.red(`Solution file not found: ${resolved}`));
|
|
5757
5858
|
process.exit(1);
|
|
5758
5859
|
}
|
|
5759
5860
|
return resolved;
|
|
@@ -5795,14 +5896,14 @@ import { execSync as execSync23 } from "child_process";
|
|
|
5795
5896
|
import { existsSync as existsSync27, readFileSync as readFileSync22, unlinkSync as unlinkSync5 } from "fs";
|
|
5796
5897
|
import { tmpdir as tmpdir2 } from "os";
|
|
5797
5898
|
import path26 from "path";
|
|
5798
|
-
import
|
|
5899
|
+
import chalk73 from "chalk";
|
|
5799
5900
|
function assertJbInstalled() {
|
|
5800
5901
|
try {
|
|
5801
5902
|
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5802
5903
|
} catch {
|
|
5803
|
-
console.error(
|
|
5904
|
+
console.error(chalk73.red("jb is not installed. Install with:"));
|
|
5804
5905
|
console.error(
|
|
5805
|
-
|
|
5906
|
+
chalk73.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5806
5907
|
);
|
|
5807
5908
|
process.exit(1);
|
|
5808
5909
|
}
|
|
@@ -5820,11 +5921,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5820
5921
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5821
5922
|
process.stderr.write(err.stderr);
|
|
5822
5923
|
}
|
|
5823
|
-
console.error(
|
|
5924
|
+
console.error(chalk73.red("jb inspectcode failed"));
|
|
5824
5925
|
process.exit(1);
|
|
5825
5926
|
}
|
|
5826
5927
|
if (!existsSync27(reportPath)) {
|
|
5827
|
-
console.error(
|
|
5928
|
+
console.error(chalk73.red("Report file not generated"));
|
|
5828
5929
|
process.exit(1);
|
|
5829
5930
|
}
|
|
5830
5931
|
const xml = readFileSync22(reportPath, "utf-8");
|
|
@@ -5834,7 +5935,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5834
5935
|
|
|
5835
5936
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5836
5937
|
import { execSync as execSync24 } from "child_process";
|
|
5837
|
-
import
|
|
5938
|
+
import chalk74 from "chalk";
|
|
5838
5939
|
function resolveMsbuildPath() {
|
|
5839
5940
|
const config = loadConfig();
|
|
5840
5941
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5845,9 +5946,9 @@ function assertMsbuildInstalled() {
|
|
|
5845
5946
|
try {
|
|
5846
5947
|
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5847
5948
|
} catch {
|
|
5848
|
-
console.error(
|
|
5949
|
+
console.error(chalk74.red(`msbuild not found at: ${msbuild}`));
|
|
5849
5950
|
console.error(
|
|
5850
|
-
|
|
5951
|
+
chalk74.yellow(
|
|
5851
5952
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5852
5953
|
)
|
|
5853
5954
|
);
|
|
@@ -5894,17 +5995,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5894
5995
|
// src/commands/dotnet/inspect.ts
|
|
5895
5996
|
function logScope(changedFiles) {
|
|
5896
5997
|
if (changedFiles === null) {
|
|
5897
|
-
console.log(
|
|
5998
|
+
console.log(chalk75.dim("Inspecting full solution..."));
|
|
5898
5999
|
} else {
|
|
5899
6000
|
console.log(
|
|
5900
|
-
|
|
6001
|
+
chalk75.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5901
6002
|
);
|
|
5902
6003
|
}
|
|
5903
6004
|
}
|
|
5904
6005
|
function reportResults(issues, elapsed) {
|
|
5905
6006
|
if (issues.length > 0) displayIssues(issues);
|
|
5906
|
-
else console.log(
|
|
5907
|
-
console.log(
|
|
6007
|
+
else console.log(chalk75.green("No issues found"));
|
|
6008
|
+
console.log(chalk75.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5908
6009
|
if (issues.length > 0) process.exit(1);
|
|
5909
6010
|
}
|
|
5910
6011
|
async function inspect(sln, options2) {
|
|
@@ -5915,7 +6016,7 @@ async function inspect(sln, options2) {
|
|
|
5915
6016
|
const scope = parseScope(options2.scope);
|
|
5916
6017
|
const changedFiles = getChangedCsFiles(scope);
|
|
5917
6018
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5918
|
-
console.log(
|
|
6019
|
+
console.log(chalk75.green("No changed .cs files found"));
|
|
5919
6020
|
return;
|
|
5920
6021
|
}
|
|
5921
6022
|
logScope(changedFiles);
|
|
@@ -5941,7 +6042,7 @@ function registerDotnet(program2) {
|
|
|
5941
6042
|
}
|
|
5942
6043
|
|
|
5943
6044
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5944
|
-
import
|
|
6045
|
+
import chalk77 from "chalk";
|
|
5945
6046
|
|
|
5946
6047
|
// src/commands/jira/adfToText.ts
|
|
5947
6048
|
function renderInline(node) {
|
|
@@ -6002,7 +6103,7 @@ function adfToText(doc) {
|
|
|
6002
6103
|
|
|
6003
6104
|
// src/commands/jira/fetchIssue.ts
|
|
6004
6105
|
import { execSync as execSync25 } from "child_process";
|
|
6005
|
-
import
|
|
6106
|
+
import chalk76 from "chalk";
|
|
6006
6107
|
function fetchIssue(issueKey, fields) {
|
|
6007
6108
|
let result;
|
|
6008
6109
|
try {
|
|
@@ -6015,15 +6116,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
6015
6116
|
const stderr = error.stderr;
|
|
6016
6117
|
if (stderr.includes("unauthorized")) {
|
|
6017
6118
|
console.error(
|
|
6018
|
-
|
|
6119
|
+
chalk76.red("Jira authentication expired."),
|
|
6019
6120
|
"Run",
|
|
6020
|
-
|
|
6121
|
+
chalk76.cyan("assist jira auth"),
|
|
6021
6122
|
"to re-authenticate."
|
|
6022
6123
|
);
|
|
6023
6124
|
process.exit(1);
|
|
6024
6125
|
}
|
|
6025
6126
|
}
|
|
6026
|
-
console.error(
|
|
6127
|
+
console.error(chalk76.red(`Failed to fetch ${issueKey}.`));
|
|
6027
6128
|
process.exit(1);
|
|
6028
6129
|
}
|
|
6029
6130
|
return JSON.parse(result);
|
|
@@ -6037,7 +6138,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
6037
6138
|
const parsed = fetchIssue(issueKey, field);
|
|
6038
6139
|
const acValue = parsed?.fields?.[field];
|
|
6039
6140
|
if (!acValue) {
|
|
6040
|
-
console.log(
|
|
6141
|
+
console.log(chalk77.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
6041
6142
|
return;
|
|
6042
6143
|
}
|
|
6043
6144
|
if (typeof acValue === "string") {
|
|
@@ -6132,14 +6233,14 @@ async function jiraAuth() {
|
|
|
6132
6233
|
}
|
|
6133
6234
|
|
|
6134
6235
|
// src/commands/jira/viewIssue.ts
|
|
6135
|
-
import
|
|
6236
|
+
import chalk78 from "chalk";
|
|
6136
6237
|
function viewIssue(issueKey) {
|
|
6137
6238
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
6138
6239
|
const fields = parsed?.fields;
|
|
6139
6240
|
const summary = fields?.summary;
|
|
6140
6241
|
const description = fields?.description;
|
|
6141
6242
|
if (summary) {
|
|
6142
|
-
console.log(
|
|
6243
|
+
console.log(chalk78.bold(summary));
|
|
6143
6244
|
}
|
|
6144
6245
|
if (description) {
|
|
6145
6246
|
if (summary) console.log();
|
|
@@ -6153,7 +6254,7 @@ function viewIssue(issueKey) {
|
|
|
6153
6254
|
}
|
|
6154
6255
|
if (!summary && !description) {
|
|
6155
6256
|
console.log(
|
|
6156
|
-
|
|
6257
|
+
chalk78.yellow(`No summary or description found on ${issueKey}.`)
|
|
6157
6258
|
);
|
|
6158
6259
|
}
|
|
6159
6260
|
}
|
|
@@ -6167,7 +6268,7 @@ function registerJira(program2) {
|
|
|
6167
6268
|
}
|
|
6168
6269
|
|
|
6169
6270
|
// src/commands/news/add/index.ts
|
|
6170
|
-
import
|
|
6271
|
+
import chalk79 from "chalk";
|
|
6171
6272
|
import enquirer7 from "enquirer";
|
|
6172
6273
|
async function add2(url) {
|
|
6173
6274
|
if (!url) {
|
|
@@ -6190,17 +6291,17 @@ async function add2(url) {
|
|
|
6190
6291
|
const news = config.news ?? {};
|
|
6191
6292
|
const feeds = news.feeds ?? [];
|
|
6192
6293
|
if (feeds.includes(url)) {
|
|
6193
|
-
console.log(
|
|
6294
|
+
console.log(chalk79.yellow("Feed already exists in config"));
|
|
6194
6295
|
return;
|
|
6195
6296
|
}
|
|
6196
6297
|
feeds.push(url);
|
|
6197
6298
|
config.news = { ...news, feeds };
|
|
6198
6299
|
saveGlobalConfig(config);
|
|
6199
|
-
console.log(
|
|
6300
|
+
console.log(chalk79.green(`Added feed: ${url}`));
|
|
6200
6301
|
}
|
|
6201
6302
|
|
|
6202
6303
|
// src/commands/news/web/handleRequest.ts
|
|
6203
|
-
import
|
|
6304
|
+
import chalk80 from "chalk";
|
|
6204
6305
|
|
|
6205
6306
|
// src/commands/news/web/shared.ts
|
|
6206
6307
|
import { decodeHTML } from "entities";
|
|
@@ -6336,17 +6437,17 @@ function prefetch() {
|
|
|
6336
6437
|
const config = loadConfig();
|
|
6337
6438
|
const total = config.news.feeds.length;
|
|
6338
6439
|
if (total === 0) return;
|
|
6339
|
-
process.stdout.write(
|
|
6440
|
+
process.stdout.write(chalk80.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6340
6441
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6341
6442
|
const width = 20;
|
|
6342
6443
|
const filled = Math.round(done2 / t * width);
|
|
6343
6444
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6344
6445
|
process.stdout.write(
|
|
6345
|
-
`\r${
|
|
6446
|
+
`\r${chalk80.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6346
6447
|
);
|
|
6347
6448
|
}).then((items) => {
|
|
6348
6449
|
process.stdout.write(
|
|
6349
|
-
`\r${
|
|
6450
|
+
`\r${chalk80.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6350
6451
|
`
|
|
6351
6452
|
);
|
|
6352
6453
|
cachedItems = items;
|
|
@@ -6707,20 +6808,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6707
6808
|
}
|
|
6708
6809
|
|
|
6709
6810
|
// src/commands/prs/listComments/printComments.ts
|
|
6710
|
-
import
|
|
6811
|
+
import chalk81 from "chalk";
|
|
6711
6812
|
function formatForHuman(comment3) {
|
|
6712
6813
|
if (comment3.type === "review") {
|
|
6713
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
6814
|
+
const stateColor = comment3.state === "APPROVED" ? chalk81.green : comment3.state === "CHANGES_REQUESTED" ? chalk81.red : chalk81.yellow;
|
|
6714
6815
|
return [
|
|
6715
|
-
`${
|
|
6816
|
+
`${chalk81.cyan("Review")} by ${chalk81.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
6716
6817
|
comment3.body,
|
|
6717
6818
|
""
|
|
6718
6819
|
].join("\n");
|
|
6719
6820
|
}
|
|
6720
6821
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
6721
6822
|
return [
|
|
6722
|
-
`${
|
|
6723
|
-
|
|
6823
|
+
`${chalk81.cyan("Line comment")} by ${chalk81.bold(comment3.user)} on ${chalk81.dim(`${comment3.path}${location}`)}`,
|
|
6824
|
+
chalk81.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6724
6825
|
comment3.body,
|
|
6725
6826
|
""
|
|
6726
6827
|
].join("\n");
|
|
@@ -6810,13 +6911,13 @@ import { execSync as execSync32 } from "child_process";
|
|
|
6810
6911
|
import enquirer8 from "enquirer";
|
|
6811
6912
|
|
|
6812
6913
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6813
|
-
import
|
|
6914
|
+
import chalk82 from "chalk";
|
|
6814
6915
|
var STATUS_MAP = {
|
|
6815
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6816
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6916
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk82.magenta("merged"), date: pr.mergedAt } : null,
|
|
6917
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk82.red("closed"), date: pr.closedAt } : null
|
|
6817
6918
|
};
|
|
6818
6919
|
function defaultStatus(pr) {
|
|
6819
|
-
return { label:
|
|
6920
|
+
return { label: chalk82.green("opened"), date: pr.createdAt };
|
|
6820
6921
|
}
|
|
6821
6922
|
function getStatus2(pr) {
|
|
6822
6923
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6825,11 +6926,11 @@ function formatDate(dateStr) {
|
|
|
6825
6926
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6826
6927
|
}
|
|
6827
6928
|
function formatPrHeader(pr, status2) {
|
|
6828
|
-
return `${
|
|
6929
|
+
return `${chalk82.cyan(`#${pr.number}`)} ${pr.title} ${chalk82.dim(`(${pr.author.login},`)} ${status2.label} ${chalk82.dim(`${formatDate(status2.date)})`)}`;
|
|
6829
6930
|
}
|
|
6830
6931
|
function logPrDetails(pr) {
|
|
6831
6932
|
console.log(
|
|
6832
|
-
|
|
6933
|
+
chalk82.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6833
6934
|
);
|
|
6834
6935
|
console.log();
|
|
6835
6936
|
}
|
|
@@ -6995,10 +7096,10 @@ function registerPrs(program2) {
|
|
|
6995
7096
|
}
|
|
6996
7097
|
|
|
6997
7098
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6998
|
-
import
|
|
7099
|
+
import chalk88 from "chalk";
|
|
6999
7100
|
|
|
7000
7101
|
// src/shared/createConnectionAuth.ts
|
|
7001
|
-
import
|
|
7102
|
+
import chalk83 from "chalk";
|
|
7002
7103
|
function listConnections(connections, format2) {
|
|
7003
7104
|
if (connections.length === 0) {
|
|
7004
7105
|
console.log("No connections configured.");
|
|
@@ -7011,7 +7112,7 @@ function listConnections(connections, format2) {
|
|
|
7011
7112
|
function removeConnection(connections, name, save) {
|
|
7012
7113
|
const filtered = connections.filter((c) => c.name !== name);
|
|
7013
7114
|
if (filtered.length === connections.length) {
|
|
7014
|
-
console.error(
|
|
7115
|
+
console.error(chalk83.red(`Connection "${name}" not found.`));
|
|
7015
7116
|
process.exit(1);
|
|
7016
7117
|
}
|
|
7017
7118
|
save(filtered);
|
|
@@ -7057,15 +7158,15 @@ function saveConnections(connections) {
|
|
|
7057
7158
|
}
|
|
7058
7159
|
|
|
7059
7160
|
// src/commands/ravendb/promptConnection.ts
|
|
7060
|
-
import
|
|
7161
|
+
import chalk86 from "chalk";
|
|
7061
7162
|
|
|
7062
7163
|
// src/commands/ravendb/selectOpSecret.ts
|
|
7063
|
-
import
|
|
7164
|
+
import chalk85 from "chalk";
|
|
7064
7165
|
import Enquirer2 from "enquirer";
|
|
7065
7166
|
|
|
7066
7167
|
// src/commands/ravendb/searchItems.ts
|
|
7067
7168
|
import { execSync as execSync34 } from "child_process";
|
|
7068
|
-
import
|
|
7169
|
+
import chalk84 from "chalk";
|
|
7069
7170
|
function opExec(args) {
|
|
7070
7171
|
return execSync34(`op ${args}`, {
|
|
7071
7172
|
encoding: "utf-8",
|
|
@@ -7078,7 +7179,7 @@ function searchItems(search) {
|
|
|
7078
7179
|
items = JSON.parse(opExec("item list --format=json"));
|
|
7079
7180
|
} catch {
|
|
7080
7181
|
console.error(
|
|
7081
|
-
|
|
7182
|
+
chalk84.red(
|
|
7082
7183
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
7083
7184
|
)
|
|
7084
7185
|
);
|
|
@@ -7092,7 +7193,7 @@ function getItemFields(itemId) {
|
|
|
7092
7193
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
7093
7194
|
return item.fields.filter((f) => f.reference && f.label);
|
|
7094
7195
|
} catch {
|
|
7095
|
-
console.error(
|
|
7196
|
+
console.error(chalk84.red("Failed to get item details from 1Password."));
|
|
7096
7197
|
process.exit(1);
|
|
7097
7198
|
}
|
|
7098
7199
|
}
|
|
@@ -7111,7 +7212,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7111
7212
|
}).run();
|
|
7112
7213
|
const items = searchItems(search);
|
|
7113
7214
|
if (items.length === 0) {
|
|
7114
|
-
console.error(
|
|
7215
|
+
console.error(chalk85.red(`No items found matching "${search}".`));
|
|
7115
7216
|
process.exit(1);
|
|
7116
7217
|
}
|
|
7117
7218
|
const itemId = await selectOne(
|
|
@@ -7120,7 +7221,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7120
7221
|
);
|
|
7121
7222
|
const fields = getItemFields(itemId);
|
|
7122
7223
|
if (fields.length === 0) {
|
|
7123
|
-
console.error(
|
|
7224
|
+
console.error(chalk85.red("No fields with references found on this item."));
|
|
7124
7225
|
process.exit(1);
|
|
7125
7226
|
}
|
|
7126
7227
|
const ref = await selectOne(
|
|
@@ -7134,7 +7235,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7134
7235
|
async function promptConnection(existingNames) {
|
|
7135
7236
|
const name = await promptInput("name", "Connection name:");
|
|
7136
7237
|
if (existingNames.includes(name)) {
|
|
7137
|
-
console.error(
|
|
7238
|
+
console.error(chalk86.red(`Connection "${name}" already exists.`));
|
|
7138
7239
|
process.exit(1);
|
|
7139
7240
|
}
|
|
7140
7241
|
const url = await promptInput(
|
|
@@ -7143,22 +7244,22 @@ async function promptConnection(existingNames) {
|
|
|
7143
7244
|
);
|
|
7144
7245
|
const database = await promptInput("database", "Database name:");
|
|
7145
7246
|
if (!name || !url || !database) {
|
|
7146
|
-
console.error(
|
|
7247
|
+
console.error(chalk86.red("All fields are required."));
|
|
7147
7248
|
process.exit(1);
|
|
7148
7249
|
}
|
|
7149
7250
|
const apiKeyRef = await selectOpSecret();
|
|
7150
|
-
console.log(
|
|
7251
|
+
console.log(chalk86.dim(`Using: ${apiKeyRef}`));
|
|
7151
7252
|
return { name, url, database, apiKeyRef };
|
|
7152
7253
|
}
|
|
7153
7254
|
|
|
7154
7255
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
7155
|
-
import
|
|
7256
|
+
import chalk87 from "chalk";
|
|
7156
7257
|
function ravendbSetConnection(name) {
|
|
7157
7258
|
const raw = loadGlobalConfigRaw();
|
|
7158
7259
|
const ravendb = raw.ravendb ?? {};
|
|
7159
7260
|
const connections = ravendb.connections ?? [];
|
|
7160
7261
|
if (!connections.some((c) => c.name === name)) {
|
|
7161
|
-
console.error(
|
|
7262
|
+
console.error(chalk87.red(`Connection "${name}" not found.`));
|
|
7162
7263
|
console.error(
|
|
7163
7264
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7164
7265
|
);
|
|
@@ -7174,16 +7275,16 @@ function ravendbSetConnection(name) {
|
|
|
7174
7275
|
var ravendbAuth = createConnectionAuth({
|
|
7175
7276
|
load: loadConnections,
|
|
7176
7277
|
save: saveConnections,
|
|
7177
|
-
format: (c) => `${
|
|
7278
|
+
format: (c) => `${chalk88.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
7178
7279
|
promptNew: promptConnection,
|
|
7179
7280
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
7180
7281
|
});
|
|
7181
7282
|
|
|
7182
7283
|
// src/commands/ravendb/ravendbCollections.ts
|
|
7183
|
-
import
|
|
7284
|
+
import chalk92 from "chalk";
|
|
7184
7285
|
|
|
7185
7286
|
// src/commands/ravendb/ravenFetch.ts
|
|
7186
|
-
import
|
|
7287
|
+
import chalk90 from "chalk";
|
|
7187
7288
|
|
|
7188
7289
|
// src/commands/ravendb/getAccessToken.ts
|
|
7189
7290
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -7220,10 +7321,10 @@ ${errorText}`
|
|
|
7220
7321
|
|
|
7221
7322
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
7222
7323
|
import { execSync as execSync35 } from "child_process";
|
|
7223
|
-
import
|
|
7324
|
+
import chalk89 from "chalk";
|
|
7224
7325
|
function resolveOpSecret(reference) {
|
|
7225
7326
|
if (!reference.startsWith("op://")) {
|
|
7226
|
-
console.error(
|
|
7327
|
+
console.error(chalk89.red(`Invalid secret reference: must start with op://`));
|
|
7227
7328
|
process.exit(1);
|
|
7228
7329
|
}
|
|
7229
7330
|
try {
|
|
@@ -7233,7 +7334,7 @@ function resolveOpSecret(reference) {
|
|
|
7233
7334
|
}).trim();
|
|
7234
7335
|
} catch {
|
|
7235
7336
|
console.error(
|
|
7236
|
-
|
|
7337
|
+
chalk89.red(
|
|
7237
7338
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
7238
7339
|
)
|
|
7239
7340
|
);
|
|
@@ -7260,7 +7361,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7260
7361
|
if (!response.ok) {
|
|
7261
7362
|
const body = await response.text();
|
|
7262
7363
|
console.error(
|
|
7263
|
-
|
|
7364
|
+
chalk90.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
7264
7365
|
);
|
|
7265
7366
|
console.error(body.substring(0, 500));
|
|
7266
7367
|
process.exit(1);
|
|
@@ -7269,7 +7370,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7269
7370
|
}
|
|
7270
7371
|
|
|
7271
7372
|
// src/commands/ravendb/resolveConnection.ts
|
|
7272
|
-
import
|
|
7373
|
+
import chalk91 from "chalk";
|
|
7273
7374
|
function loadRavendb() {
|
|
7274
7375
|
const raw = loadGlobalConfigRaw();
|
|
7275
7376
|
const ravendb = raw.ravendb;
|
|
@@ -7283,7 +7384,7 @@ function resolveConnection(name) {
|
|
|
7283
7384
|
const connectionName = name ?? defaultConnection;
|
|
7284
7385
|
if (!connectionName) {
|
|
7285
7386
|
console.error(
|
|
7286
|
-
|
|
7387
|
+
chalk91.red(
|
|
7287
7388
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
7288
7389
|
)
|
|
7289
7390
|
);
|
|
@@ -7291,7 +7392,7 @@ function resolveConnection(name) {
|
|
|
7291
7392
|
}
|
|
7292
7393
|
const connection = connections.find((c) => c.name === connectionName);
|
|
7293
7394
|
if (!connection) {
|
|
7294
|
-
console.error(
|
|
7395
|
+
console.error(chalk91.red(`Connection "${connectionName}" not found.`));
|
|
7295
7396
|
console.error(
|
|
7296
7397
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7297
7398
|
);
|
|
@@ -7322,15 +7423,15 @@ async function ravendbCollections(connectionName) {
|
|
|
7322
7423
|
return;
|
|
7323
7424
|
}
|
|
7324
7425
|
for (const c of collections) {
|
|
7325
|
-
console.log(`${
|
|
7426
|
+
console.log(`${chalk92.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
7326
7427
|
}
|
|
7327
7428
|
}
|
|
7328
7429
|
|
|
7329
7430
|
// src/commands/ravendb/ravendbQuery.ts
|
|
7330
|
-
import
|
|
7431
|
+
import chalk94 from "chalk";
|
|
7331
7432
|
|
|
7332
7433
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7333
|
-
import
|
|
7434
|
+
import chalk93 from "chalk";
|
|
7334
7435
|
|
|
7335
7436
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7336
7437
|
function buildQueryPath(opts) {
|
|
@@ -7368,7 +7469,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7368
7469
|
allResults.push(...results);
|
|
7369
7470
|
start3 += results.length;
|
|
7370
7471
|
process.stderr.write(
|
|
7371
|
-
`\r${
|
|
7472
|
+
`\r${chalk93.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7372
7473
|
);
|
|
7373
7474
|
if (start3 >= totalResults) break;
|
|
7374
7475
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7383,7 +7484,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7383
7484
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7384
7485
|
const resolved = resolveArgs(connectionName, collection);
|
|
7385
7486
|
if (!resolved.collection && !options2.query) {
|
|
7386
|
-
console.error(
|
|
7487
|
+
console.error(chalk94.red("Provide a collection name or --query filter."));
|
|
7387
7488
|
process.exit(1);
|
|
7388
7489
|
}
|
|
7389
7490
|
const { collection: col } = resolved;
|
|
@@ -7421,7 +7522,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7421
7522
|
import * as path27 from "path";
|
|
7422
7523
|
|
|
7423
7524
|
// src/commands/refactor/logViolations.ts
|
|
7424
|
-
import
|
|
7525
|
+
import chalk95 from "chalk";
|
|
7425
7526
|
var DEFAULT_MAX_LINES = 100;
|
|
7426
7527
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7427
7528
|
if (violations.length === 0) {
|
|
@@ -7430,43 +7531,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7430
7531
|
}
|
|
7431
7532
|
return;
|
|
7432
7533
|
}
|
|
7433
|
-
console.error(
|
|
7534
|
+
console.error(chalk95.red(`
|
|
7434
7535
|
Refactor check failed:
|
|
7435
7536
|
`));
|
|
7436
|
-
console.error(
|
|
7537
|
+
console.error(chalk95.red(` The following files exceed ${maxLines} lines:
|
|
7437
7538
|
`));
|
|
7438
7539
|
for (const violation of violations) {
|
|
7439
|
-
console.error(
|
|
7540
|
+
console.error(chalk95.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7440
7541
|
}
|
|
7441
7542
|
console.error(
|
|
7442
|
-
|
|
7543
|
+
chalk95.yellow(
|
|
7443
7544
|
`
|
|
7444
7545
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7445
7546
|
way to refactor it, ignore it with:
|
|
7446
7547
|
`
|
|
7447
7548
|
)
|
|
7448
7549
|
);
|
|
7449
|
-
console.error(
|
|
7550
|
+
console.error(chalk95.gray(` assist refactor ignore <file>
|
|
7450
7551
|
`));
|
|
7451
7552
|
if (process.env.CLAUDECODE) {
|
|
7452
|
-
console.error(
|
|
7553
|
+
console.error(chalk95.cyan(`
|
|
7453
7554
|
## Extracting Code to New Files
|
|
7454
7555
|
`));
|
|
7455
7556
|
console.error(
|
|
7456
|
-
|
|
7557
|
+
chalk95.cyan(
|
|
7457
7558
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7458
7559
|
`
|
|
7459
7560
|
)
|
|
7460
7561
|
);
|
|
7461
7562
|
console.error(
|
|
7462
|
-
|
|
7563
|
+
chalk95.cyan(
|
|
7463
7564
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7464
7565
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7465
7566
|
`
|
|
7466
7567
|
)
|
|
7467
7568
|
);
|
|
7468
7569
|
console.error(
|
|
7469
|
-
|
|
7570
|
+
chalk95.cyan(
|
|
7470
7571
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7471
7572
|
domains, move it to a common/shared folder.
|
|
7472
7573
|
`
|
|
@@ -7622,7 +7723,7 @@ async function check(pattern2, options2) {
|
|
|
7622
7723
|
|
|
7623
7724
|
// src/commands/refactor/extract/index.ts
|
|
7624
7725
|
import path33 from "path";
|
|
7625
|
-
import
|
|
7726
|
+
import chalk98 from "chalk";
|
|
7626
7727
|
|
|
7627
7728
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7628
7729
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -8148,23 +8249,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
8148
8249
|
|
|
8149
8250
|
// src/commands/refactor/extract/displayPlan.ts
|
|
8150
8251
|
import path31 from "path";
|
|
8151
|
-
import
|
|
8252
|
+
import chalk96 from "chalk";
|
|
8152
8253
|
function section(title) {
|
|
8153
8254
|
return `
|
|
8154
|
-
${
|
|
8255
|
+
${chalk96.cyan(title)}`;
|
|
8155
8256
|
}
|
|
8156
8257
|
function displayImporters(plan2, cwd) {
|
|
8157
8258
|
if (plan2.importersToUpdate.length === 0) return;
|
|
8158
8259
|
console.log(section("Update importers:"));
|
|
8159
8260
|
for (const imp of plan2.importersToUpdate) {
|
|
8160
8261
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
8161
|
-
console.log(` ${
|
|
8262
|
+
console.log(` ${chalk96.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
8162
8263
|
}
|
|
8163
8264
|
}
|
|
8164
8265
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
8165
|
-
console.log(
|
|
8266
|
+
console.log(chalk96.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
8166
8267
|
`));
|
|
8167
|
-
console.log(` ${
|
|
8268
|
+
console.log(` ${chalk96.cyan("Functions to move:")}`);
|
|
8168
8269
|
for (const name of plan2.extractedNames) {
|
|
8169
8270
|
console.log(` ${name}`);
|
|
8170
8271
|
}
|
|
@@ -8199,7 +8300,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
8199
8300
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
8200
8301
|
import fs17 from "fs";
|
|
8201
8302
|
import path32 from "path";
|
|
8202
|
-
import
|
|
8303
|
+
import chalk97 from "chalk";
|
|
8203
8304
|
import { Project as Project2 } from "ts-morph";
|
|
8204
8305
|
function findTsConfig(sourcePath) {
|
|
8205
8306
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -8230,7 +8331,7 @@ function loadProjectFile(file) {
|
|
|
8230
8331
|
});
|
|
8231
8332
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
8232
8333
|
if (!sourceFile) {
|
|
8233
|
-
console.log(
|
|
8334
|
+
console.log(chalk97.red(`File not found in project: ${file}`));
|
|
8234
8335
|
process.exit(1);
|
|
8235
8336
|
}
|
|
8236
8337
|
return { project, sourceFile };
|
|
@@ -8253,19 +8354,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
8253
8354
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
8254
8355
|
if (options2.apply) {
|
|
8255
8356
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
8256
|
-
console.log(
|
|
8357
|
+
console.log(chalk98.green("\nExtraction complete"));
|
|
8257
8358
|
} else {
|
|
8258
|
-
console.log(
|
|
8359
|
+
console.log(chalk98.dim("\nDry run. Use --apply to execute."));
|
|
8259
8360
|
}
|
|
8260
8361
|
}
|
|
8261
8362
|
|
|
8262
8363
|
// src/commands/refactor/ignore.ts
|
|
8263
8364
|
import fs18 from "fs";
|
|
8264
|
-
import
|
|
8365
|
+
import chalk99 from "chalk";
|
|
8265
8366
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
8266
8367
|
function ignore(file) {
|
|
8267
8368
|
if (!fs18.existsSync(file)) {
|
|
8268
|
-
console.error(
|
|
8369
|
+
console.error(chalk99.red(`Error: File does not exist: ${file}`));
|
|
8269
8370
|
process.exit(1);
|
|
8270
8371
|
}
|
|
8271
8372
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -8281,7 +8382,7 @@ function ignore(file) {
|
|
|
8281
8382
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
8282
8383
|
}
|
|
8283
8384
|
console.log(
|
|
8284
|
-
|
|
8385
|
+
chalk99.green(
|
|
8285
8386
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
8286
8387
|
)
|
|
8287
8388
|
);
|
|
@@ -8289,26 +8390,26 @@ function ignore(file) {
|
|
|
8289
8390
|
|
|
8290
8391
|
// src/commands/refactor/rename/index.ts
|
|
8291
8392
|
import path34 from "path";
|
|
8292
|
-
import
|
|
8393
|
+
import chalk100 from "chalk";
|
|
8293
8394
|
async function rename(source, destination, options2 = {}) {
|
|
8294
8395
|
const destPath = path34.resolve(destination);
|
|
8295
8396
|
const cwd = process.cwd();
|
|
8296
8397
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
8297
8398
|
const relDest = path34.relative(cwd, destPath);
|
|
8298
8399
|
const { project, sourceFile } = loadProjectFile(source);
|
|
8299
|
-
console.log(
|
|
8400
|
+
console.log(chalk100.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
8300
8401
|
if (options2.apply) {
|
|
8301
8402
|
sourceFile.move(destPath);
|
|
8302
8403
|
await project.save();
|
|
8303
|
-
console.log(
|
|
8404
|
+
console.log(chalk100.green("Done"));
|
|
8304
8405
|
} else {
|
|
8305
|
-
console.log(
|
|
8406
|
+
console.log(chalk100.dim("Dry run. Use --apply to execute."));
|
|
8306
8407
|
}
|
|
8307
8408
|
}
|
|
8308
8409
|
|
|
8309
8410
|
// src/commands/refactor/renameSymbol/index.ts
|
|
8310
8411
|
import path36 from "path";
|
|
8311
|
-
import
|
|
8412
|
+
import chalk101 from "chalk";
|
|
8312
8413
|
import { Project as Project3 } from "ts-morph";
|
|
8313
8414
|
|
|
8314
8415
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8357,38 +8458,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8357
8458
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8358
8459
|
const sourceFile = project.getSourceFile(filePath);
|
|
8359
8460
|
if (!sourceFile) {
|
|
8360
|
-
console.log(
|
|
8461
|
+
console.log(chalk101.red(`File not found in project: ${file}`));
|
|
8361
8462
|
process.exit(1);
|
|
8362
8463
|
}
|
|
8363
8464
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8364
8465
|
if (!symbol) {
|
|
8365
|
-
console.log(
|
|
8466
|
+
console.log(chalk101.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8366
8467
|
process.exit(1);
|
|
8367
8468
|
}
|
|
8368
8469
|
const grouped = groupReferences(symbol, cwd);
|
|
8369
8470
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8370
8471
|
console.log(
|
|
8371
|
-
|
|
8472
|
+
chalk101.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8372
8473
|
`)
|
|
8373
8474
|
);
|
|
8374
8475
|
for (const [refFile, lines] of grouped) {
|
|
8375
8476
|
console.log(
|
|
8376
|
-
` ${
|
|
8477
|
+
` ${chalk101.dim(refFile)}: lines ${chalk101.cyan(lines.join(", "))}`
|
|
8377
8478
|
);
|
|
8378
8479
|
}
|
|
8379
8480
|
if (options2.apply) {
|
|
8380
8481
|
symbol.rename(newName);
|
|
8381
8482
|
await project.save();
|
|
8382
|
-
console.log(
|
|
8483
|
+
console.log(chalk101.green(`
|
|
8383
8484
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8384
8485
|
} else {
|
|
8385
|
-
console.log(
|
|
8486
|
+
console.log(chalk101.dim("\nDry run. Use --apply to execute."));
|
|
8386
8487
|
}
|
|
8387
8488
|
}
|
|
8388
8489
|
|
|
8389
8490
|
// src/commands/refactor/restructure/index.ts
|
|
8390
8491
|
import path45 from "path";
|
|
8391
|
-
import
|
|
8492
|
+
import chalk104 from "chalk";
|
|
8392
8493
|
|
|
8393
8494
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8394
8495
|
import path37 from "path";
|
|
@@ -8631,50 +8732,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8631
8732
|
|
|
8632
8733
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8633
8734
|
import path41 from "path";
|
|
8634
|
-
import
|
|
8735
|
+
import chalk102 from "chalk";
|
|
8635
8736
|
function relPath(filePath) {
|
|
8636
8737
|
return path41.relative(process.cwd(), filePath);
|
|
8637
8738
|
}
|
|
8638
8739
|
function displayMoves(plan2) {
|
|
8639
8740
|
if (plan2.moves.length === 0) return;
|
|
8640
|
-
console.log(
|
|
8741
|
+
console.log(chalk102.bold("\nFile moves:"));
|
|
8641
8742
|
for (const move of plan2.moves) {
|
|
8642
8743
|
console.log(
|
|
8643
|
-
` ${
|
|
8744
|
+
` ${chalk102.red(relPath(move.from))} \u2192 ${chalk102.green(relPath(move.to))}`
|
|
8644
8745
|
);
|
|
8645
|
-
console.log(
|
|
8746
|
+
console.log(chalk102.dim(` ${move.reason}`));
|
|
8646
8747
|
}
|
|
8647
8748
|
}
|
|
8648
8749
|
function displayRewrites(rewrites) {
|
|
8649
8750
|
if (rewrites.length === 0) return;
|
|
8650
8751
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8651
|
-
console.log(
|
|
8752
|
+
console.log(chalk102.bold(`
|
|
8652
8753
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8653
8754
|
for (const file of affectedFiles) {
|
|
8654
|
-
console.log(` ${
|
|
8755
|
+
console.log(` ${chalk102.cyan(relPath(file))}:`);
|
|
8655
8756
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8656
8757
|
(r) => r.file === file
|
|
8657
8758
|
)) {
|
|
8658
8759
|
console.log(
|
|
8659
|
-
` ${
|
|
8760
|
+
` ${chalk102.red(`"${oldSpecifier}"`)} \u2192 ${chalk102.green(`"${newSpecifier}"`)}`
|
|
8660
8761
|
);
|
|
8661
8762
|
}
|
|
8662
8763
|
}
|
|
8663
8764
|
}
|
|
8664
8765
|
function displayPlan2(plan2) {
|
|
8665
8766
|
if (plan2.warnings.length > 0) {
|
|
8666
|
-
console.log(
|
|
8667
|
-
for (const w of plan2.warnings) console.log(
|
|
8767
|
+
console.log(chalk102.yellow("\nWarnings:"));
|
|
8768
|
+
for (const w of plan2.warnings) console.log(chalk102.yellow(` ${w}`));
|
|
8668
8769
|
}
|
|
8669
8770
|
if (plan2.newDirectories.length > 0) {
|
|
8670
|
-
console.log(
|
|
8771
|
+
console.log(chalk102.bold("\nNew directories:"));
|
|
8671
8772
|
for (const dir of plan2.newDirectories)
|
|
8672
|
-
console.log(
|
|
8773
|
+
console.log(chalk102.green(` ${dir}/`));
|
|
8673
8774
|
}
|
|
8674
8775
|
displayMoves(plan2);
|
|
8675
8776
|
displayRewrites(plan2.rewrites);
|
|
8676
8777
|
console.log(
|
|
8677
|
-
|
|
8778
|
+
chalk102.dim(
|
|
8678
8779
|
`
|
|
8679
8780
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8680
8781
|
)
|
|
@@ -8684,18 +8785,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8684
8785
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8685
8786
|
import fs20 from "fs";
|
|
8686
8787
|
import path42 from "path";
|
|
8687
|
-
import
|
|
8788
|
+
import chalk103 from "chalk";
|
|
8688
8789
|
function executePlan(plan2) {
|
|
8689
8790
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8690
8791
|
for (const [file, content] of updatedContents) {
|
|
8691
8792
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8692
8793
|
console.log(
|
|
8693
|
-
|
|
8794
|
+
chalk103.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8694
8795
|
);
|
|
8695
8796
|
}
|
|
8696
8797
|
for (const dir of plan2.newDirectories) {
|
|
8697
8798
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8698
|
-
console.log(
|
|
8799
|
+
console.log(chalk103.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8699
8800
|
}
|
|
8700
8801
|
for (const move of plan2.moves) {
|
|
8701
8802
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8704,7 +8805,7 @@ function executePlan(plan2) {
|
|
|
8704
8805
|
}
|
|
8705
8806
|
fs20.renameSync(move.from, move.to);
|
|
8706
8807
|
console.log(
|
|
8707
|
-
|
|
8808
|
+
chalk103.white(
|
|
8708
8809
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8709
8810
|
)
|
|
8710
8811
|
);
|
|
@@ -8719,7 +8820,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8719
8820
|
if (entries.length === 0) {
|
|
8720
8821
|
fs20.rmdirSync(dir);
|
|
8721
8822
|
console.log(
|
|
8722
|
-
|
|
8823
|
+
chalk103.dim(
|
|
8723
8824
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8724
8825
|
)
|
|
8725
8826
|
);
|
|
@@ -8852,22 +8953,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8852
8953
|
const targetPattern = pattern2 ?? "src";
|
|
8853
8954
|
const files = findSourceFiles2(targetPattern);
|
|
8854
8955
|
if (files.length === 0) {
|
|
8855
|
-
console.log(
|
|
8956
|
+
console.log(chalk104.yellow("No files found matching pattern"));
|
|
8856
8957
|
return;
|
|
8857
8958
|
}
|
|
8858
8959
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8859
8960
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8860
8961
|
if (plan2.moves.length === 0) {
|
|
8861
|
-
console.log(
|
|
8962
|
+
console.log(chalk104.green("No restructuring needed"));
|
|
8862
8963
|
return;
|
|
8863
8964
|
}
|
|
8864
8965
|
displayPlan2(plan2);
|
|
8865
8966
|
if (options2.apply) {
|
|
8866
|
-
console.log(
|
|
8967
|
+
console.log(chalk104.bold("\nApplying changes..."));
|
|
8867
8968
|
executePlan(plan2);
|
|
8868
|
-
console.log(
|
|
8969
|
+
console.log(chalk104.green("\nRestructuring complete"));
|
|
8869
8970
|
} else {
|
|
8870
|
-
console.log(
|
|
8971
|
+
console.log(chalk104.dim("\nDry run. Use --apply to execute."));
|
|
8871
8972
|
}
|
|
8872
8973
|
}
|
|
8873
8974
|
|
|
@@ -8907,7 +9008,7 @@ function registerRefactor(program2) {
|
|
|
8907
9008
|
}
|
|
8908
9009
|
|
|
8909
9010
|
// src/commands/seq/seqAuth.ts
|
|
8910
|
-
import
|
|
9011
|
+
import chalk106 from "chalk";
|
|
8911
9012
|
|
|
8912
9013
|
// src/commands/seq/loadConnections.ts
|
|
8913
9014
|
function loadConnections2() {
|
|
@@ -8936,11 +9037,11 @@ function setDefaultConnection(name) {
|
|
|
8936
9037
|
}
|
|
8937
9038
|
|
|
8938
9039
|
// src/commands/seq/promptConnection.ts
|
|
8939
|
-
import
|
|
9040
|
+
import chalk105 from "chalk";
|
|
8940
9041
|
async function promptConnection2(existingNames) {
|
|
8941
9042
|
const name = await promptInput("name", "Connection name:", "default");
|
|
8942
9043
|
if (existingNames.includes(name)) {
|
|
8943
|
-
console.error(
|
|
9044
|
+
console.error(chalk105.red(`Connection "${name}" already exists.`));
|
|
8944
9045
|
process.exit(1);
|
|
8945
9046
|
}
|
|
8946
9047
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -8952,16 +9053,16 @@ async function promptConnection2(existingNames) {
|
|
|
8952
9053
|
var seqAuth = createConnectionAuth({
|
|
8953
9054
|
load: loadConnections2,
|
|
8954
9055
|
save: saveConnections2,
|
|
8955
|
-
format: (c) => `${
|
|
9056
|
+
format: (c) => `${chalk106.bold(c.name)} ${c.url}`,
|
|
8956
9057
|
promptNew: promptConnection2,
|
|
8957
9058
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
8958
9059
|
});
|
|
8959
9060
|
|
|
8960
9061
|
// src/commands/seq/seqQuery.ts
|
|
8961
|
-
import
|
|
9062
|
+
import chalk110 from "chalk";
|
|
8962
9063
|
|
|
8963
9064
|
// src/commands/seq/fetchSeqEvents.ts
|
|
8964
|
-
import
|
|
9065
|
+
import chalk107 from "chalk";
|
|
8965
9066
|
async function fetchSeqEvents(conn, params) {
|
|
8966
9067
|
const url = `${conn.url}/api/events?${params}`;
|
|
8967
9068
|
const response = await fetch(url, {
|
|
@@ -8972,30 +9073,30 @@ async function fetchSeqEvents(conn, params) {
|
|
|
8972
9073
|
});
|
|
8973
9074
|
if (!response.ok) {
|
|
8974
9075
|
const body = await response.text();
|
|
8975
|
-
console.error(
|
|
9076
|
+
console.error(chalk107.red(`Seq returned ${response.status}: ${body}`));
|
|
8976
9077
|
process.exit(1);
|
|
8977
9078
|
}
|
|
8978
9079
|
return response.json();
|
|
8979
9080
|
}
|
|
8980
9081
|
|
|
8981
9082
|
// src/commands/seq/formatEvent.ts
|
|
8982
|
-
import
|
|
9083
|
+
import chalk108 from "chalk";
|
|
8983
9084
|
function levelColor(level) {
|
|
8984
9085
|
switch (level) {
|
|
8985
9086
|
case "Fatal":
|
|
8986
|
-
return
|
|
9087
|
+
return chalk108.bgRed.white;
|
|
8987
9088
|
case "Error":
|
|
8988
|
-
return
|
|
9089
|
+
return chalk108.red;
|
|
8989
9090
|
case "Warning":
|
|
8990
|
-
return
|
|
9091
|
+
return chalk108.yellow;
|
|
8991
9092
|
case "Information":
|
|
8992
|
-
return
|
|
9093
|
+
return chalk108.cyan;
|
|
8993
9094
|
case "Debug":
|
|
8994
|
-
return
|
|
9095
|
+
return chalk108.gray;
|
|
8995
9096
|
case "Verbose":
|
|
8996
|
-
return
|
|
9097
|
+
return chalk108.dim;
|
|
8997
9098
|
default:
|
|
8998
|
-
return
|
|
9099
|
+
return chalk108.white;
|
|
8999
9100
|
}
|
|
9000
9101
|
}
|
|
9001
9102
|
function levelAbbrev(level) {
|
|
@@ -9036,31 +9137,31 @@ function formatTimestamp(iso) {
|
|
|
9036
9137
|
function formatEvent(event) {
|
|
9037
9138
|
const color = levelColor(event.Level);
|
|
9038
9139
|
const abbrev = levelAbbrev(event.Level);
|
|
9039
|
-
const ts8 =
|
|
9140
|
+
const ts8 = chalk108.dim(formatTimestamp(event.Timestamp));
|
|
9040
9141
|
const msg = renderMessage(event);
|
|
9041
9142
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
9042
9143
|
if (event.Exception) {
|
|
9043
9144
|
for (const line of event.Exception.split("\n")) {
|
|
9044
|
-
lines.push(
|
|
9145
|
+
lines.push(chalk108.red(` ${line}`));
|
|
9045
9146
|
}
|
|
9046
9147
|
}
|
|
9047
9148
|
return lines.join("\n");
|
|
9048
9149
|
}
|
|
9049
9150
|
|
|
9050
9151
|
// src/commands/seq/resolveConnection.ts
|
|
9051
|
-
import
|
|
9152
|
+
import chalk109 from "chalk";
|
|
9052
9153
|
function resolveConnection2(name) {
|
|
9053
9154
|
const connections = loadConnections2();
|
|
9054
9155
|
if (connections.length === 0) {
|
|
9055
9156
|
console.error(
|
|
9056
|
-
|
|
9157
|
+
chalk109.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
9057
9158
|
);
|
|
9058
9159
|
process.exit(1);
|
|
9059
9160
|
}
|
|
9060
9161
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
9061
9162
|
const connection = connections.find((c) => c.name === target);
|
|
9062
9163
|
if (!connection) {
|
|
9063
|
-
console.error(
|
|
9164
|
+
console.error(chalk109.red(`Seq connection "${target}" not found.`));
|
|
9064
9165
|
process.exit(1);
|
|
9065
9166
|
}
|
|
9066
9167
|
return connection;
|
|
@@ -9076,7 +9177,7 @@ async function seqQuery(filter, options2) {
|
|
|
9076
9177
|
}
|
|
9077
9178
|
const events = await fetchSeqEvents(conn, params);
|
|
9078
9179
|
if (events.length === 0) {
|
|
9079
|
-
console.log(
|
|
9180
|
+
console.log(chalk110.yellow("No events found."));
|
|
9080
9181
|
return;
|
|
9081
9182
|
}
|
|
9082
9183
|
if (options2.json) {
|
|
@@ -9087,11 +9188,11 @@ async function seqQuery(filter, options2) {
|
|
|
9087
9188
|
for (const event of chronological) {
|
|
9088
9189
|
console.log(formatEvent(event));
|
|
9089
9190
|
}
|
|
9090
|
-
console.log(
|
|
9191
|
+
console.log(chalk110.dim(`
|
|
9091
9192
|
${events.length} events`));
|
|
9092
9193
|
if (events.length >= count) {
|
|
9093
9194
|
console.log(
|
|
9094
|
-
|
|
9195
|
+
chalk110.yellow(
|
|
9095
9196
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
9096
9197
|
)
|
|
9097
9198
|
);
|
|
@@ -9099,11 +9200,11 @@ ${events.length} events`));
|
|
|
9099
9200
|
}
|
|
9100
9201
|
|
|
9101
9202
|
// src/commands/seq/seqSetConnection.ts
|
|
9102
|
-
import
|
|
9203
|
+
import chalk111 from "chalk";
|
|
9103
9204
|
function seqSetConnection(name) {
|
|
9104
9205
|
const connections = loadConnections2();
|
|
9105
9206
|
if (!connections.find((c) => c.name === name)) {
|
|
9106
|
-
console.error(
|
|
9207
|
+
console.error(chalk111.red(`Connection "${name}" not found.`));
|
|
9107
9208
|
process.exit(1);
|
|
9108
9209
|
}
|
|
9109
9210
|
setDefaultConnection(name);
|
|
@@ -9642,14 +9743,14 @@ import {
|
|
|
9642
9743
|
import { dirname as dirname20, join as join30 } from "path";
|
|
9643
9744
|
|
|
9644
9745
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9645
|
-
import
|
|
9746
|
+
import chalk112 from "chalk";
|
|
9646
9747
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9647
9748
|
function validateStagedContent(filename, content) {
|
|
9648
9749
|
const firstLine = content.split("\n")[0];
|
|
9649
9750
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9650
9751
|
if (!match) {
|
|
9651
9752
|
console.error(
|
|
9652
|
-
|
|
9753
|
+
chalk112.red(
|
|
9653
9754
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9654
9755
|
)
|
|
9655
9756
|
);
|
|
@@ -9658,7 +9759,7 @@ function validateStagedContent(filename, content) {
|
|
|
9658
9759
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9659
9760
|
if (!contentAfterLink) {
|
|
9660
9761
|
console.error(
|
|
9661
|
-
|
|
9762
|
+
chalk112.red(
|
|
9662
9763
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9663
9764
|
)
|
|
9664
9765
|
);
|
|
@@ -10051,7 +10152,7 @@ function registerVoice(program2) {
|
|
|
10051
10152
|
|
|
10052
10153
|
// src/commands/roam/auth.ts
|
|
10053
10154
|
import { randomBytes } from "crypto";
|
|
10054
|
-
import
|
|
10155
|
+
import chalk113 from "chalk";
|
|
10055
10156
|
|
|
10056
10157
|
// src/lib/openBrowser.ts
|
|
10057
10158
|
import { execSync as execSync38 } from "child_process";
|
|
@@ -10226,13 +10327,13 @@ async function auth() {
|
|
|
10226
10327
|
saveGlobalConfig(config);
|
|
10227
10328
|
const state = randomBytes(16).toString("hex");
|
|
10228
10329
|
console.log(
|
|
10229
|
-
|
|
10330
|
+
chalk113.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
10230
10331
|
);
|
|
10231
|
-
console.log(
|
|
10232
|
-
console.log(
|
|
10233
|
-
console.log(
|
|
10332
|
+
console.log(chalk113.white("http://localhost:14523/callback\n"));
|
|
10333
|
+
console.log(chalk113.blue("Opening browser for authorization..."));
|
|
10334
|
+
console.log(chalk113.dim("Waiting for authorization callback..."));
|
|
10234
10335
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
10235
|
-
console.log(
|
|
10336
|
+
console.log(chalk113.dim("Exchanging code for tokens..."));
|
|
10236
10337
|
const tokens = await exchangeToken({
|
|
10237
10338
|
code,
|
|
10238
10339
|
clientId,
|
|
@@ -10248,7 +10349,7 @@ async function auth() {
|
|
|
10248
10349
|
};
|
|
10249
10350
|
saveGlobalConfig(config);
|
|
10250
10351
|
console.log(
|
|
10251
|
-
|
|
10352
|
+
chalk113.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
10252
10353
|
);
|
|
10253
10354
|
}
|
|
10254
10355
|
|
|
@@ -10265,7 +10366,7 @@ async function showClaudeCodeIcon() {
|
|
|
10265
10366
|
} catch {
|
|
10266
10367
|
return;
|
|
10267
10368
|
}
|
|
10268
|
-
const body = process.stdin.isTTY ? "{}" : await
|
|
10369
|
+
const body = process.stdin.isTTY ? "{}" : await readStdin();
|
|
10269
10370
|
try {
|
|
10270
10371
|
await fetch(`http://localhost:${port}/api/v1/activity`, {
|
|
10271
10372
|
method: "POST",
|
|
@@ -10461,7 +10562,7 @@ import { execSync as execSync40 } from "child_process";
|
|
|
10461
10562
|
import { existsSync as existsSync40, mkdirSync as mkdirSync13, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10462
10563
|
import { tmpdir as tmpdir6 } from "os";
|
|
10463
10564
|
import { join as join39, resolve as resolve5 } from "path";
|
|
10464
|
-
import
|
|
10565
|
+
import chalk114 from "chalk";
|
|
10465
10566
|
|
|
10466
10567
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10467
10568
|
var captureWindowPs1 = `
|
|
@@ -10612,22 +10713,22 @@ function screenshot(processName) {
|
|
|
10612
10713
|
const config = loadConfig();
|
|
10613
10714
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10614
10715
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10615
|
-
console.log(
|
|
10716
|
+
console.log(chalk114.gray(`Capturing window for process "${processName}" ...`));
|
|
10616
10717
|
try {
|
|
10617
10718
|
runPowerShellScript(processName, outputPath);
|
|
10618
|
-
console.log(
|
|
10719
|
+
console.log(chalk114.green(`Screenshot saved: ${outputPath}`));
|
|
10619
10720
|
} catch (error) {
|
|
10620
10721
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10621
|
-
console.error(
|
|
10722
|
+
console.error(chalk114.red(`Failed to capture screenshot: ${msg}`));
|
|
10622
10723
|
process.exit(1);
|
|
10623
10724
|
}
|
|
10624
10725
|
}
|
|
10625
10726
|
|
|
10626
10727
|
// src/commands/statusLine.ts
|
|
10627
|
-
import
|
|
10728
|
+
import chalk116 from "chalk";
|
|
10628
10729
|
|
|
10629
10730
|
// src/commands/buildLimitsSegment.ts
|
|
10630
|
-
import
|
|
10731
|
+
import chalk115 from "chalk";
|
|
10631
10732
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10632
10733
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10633
10734
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10650,10 +10751,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10650
10751
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10651
10752
|
const label2 = `${Math.round(pct)}%`;
|
|
10652
10753
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10653
|
-
if (projected == null) return
|
|
10654
|
-
if (projected > 100) return
|
|
10655
|
-
if (projected > 75) return
|
|
10656
|
-
return
|
|
10754
|
+
if (projected == null) return chalk115.green(label2);
|
|
10755
|
+
if (projected > 100) return chalk115.red(label2);
|
|
10756
|
+
if (projected > 75) return chalk115.yellow(label2);
|
|
10757
|
+
return chalk115.green(label2);
|
|
10657
10758
|
}
|
|
10658
10759
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10659
10760
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10679,18 +10780,18 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10679
10780
|
}
|
|
10680
10781
|
|
|
10681
10782
|
// src/commands/statusLine.ts
|
|
10682
|
-
|
|
10783
|
+
chalk116.level = 3;
|
|
10683
10784
|
function formatNumber(num) {
|
|
10684
10785
|
return num.toLocaleString("en-US");
|
|
10685
10786
|
}
|
|
10686
10787
|
function colorizePercent(pct) {
|
|
10687
10788
|
const label2 = `${Math.round(pct)}%`;
|
|
10688
|
-
if (pct > 80) return
|
|
10689
|
-
if (pct > 40) return
|
|
10789
|
+
if (pct > 80) return chalk116.red(label2);
|
|
10790
|
+
if (pct > 40) return chalk116.yellow(label2);
|
|
10690
10791
|
return label2;
|
|
10691
10792
|
}
|
|
10692
10793
|
async function statusLine() {
|
|
10693
|
-
const inputData = await
|
|
10794
|
+
const inputData = await readStdin();
|
|
10694
10795
|
const data = JSON.parse(inputData);
|
|
10695
10796
|
const model = data.model.display_name;
|
|
10696
10797
|
const { total_input_tokens: totalIn, total_output_tokens: totalOut } = data.context_window;
|
|
@@ -10709,7 +10810,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10709
10810
|
// src/commands/sync/syncClaudeMd.ts
|
|
10710
10811
|
import * as fs23 from "fs";
|
|
10711
10812
|
import * as path46 from "path";
|
|
10712
|
-
import
|
|
10813
|
+
import chalk117 from "chalk";
|
|
10713
10814
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10714
10815
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10715
10816
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10718,12 +10819,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10718
10819
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10719
10820
|
if (sourceContent !== targetContent) {
|
|
10720
10821
|
console.log(
|
|
10721
|
-
|
|
10822
|
+
chalk117.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10722
10823
|
);
|
|
10723
10824
|
console.log();
|
|
10724
10825
|
printDiff(targetContent, sourceContent);
|
|
10725
10826
|
const confirm = options2?.yes || await promptConfirm(
|
|
10726
|
-
|
|
10827
|
+
chalk117.red("Overwrite existing CLAUDE.md?"),
|
|
10727
10828
|
false
|
|
10728
10829
|
);
|
|
10729
10830
|
if (!confirm) {
|
|
@@ -10739,7 +10840,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10739
10840
|
// src/commands/sync/syncSettings.ts
|
|
10740
10841
|
import * as fs24 from "fs";
|
|
10741
10842
|
import * as path47 from "path";
|
|
10742
|
-
import
|
|
10843
|
+
import chalk118 from "chalk";
|
|
10743
10844
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10744
10845
|
const source = path47.join(claudeDir, "settings.json");
|
|
10745
10846
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10755,14 +10856,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10755
10856
|
if (mergedContent !== normalizedTarget) {
|
|
10756
10857
|
if (!options2?.yes) {
|
|
10757
10858
|
console.log(
|
|
10758
|
-
|
|
10859
|
+
chalk118.yellow(
|
|
10759
10860
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10760
10861
|
)
|
|
10761
10862
|
);
|
|
10762
10863
|
console.log();
|
|
10763
10864
|
printDiff(targetContent, mergedContent);
|
|
10764
10865
|
const confirm = await promptConfirm(
|
|
10765
|
-
|
|
10866
|
+
chalk118.red("Overwrite existing settings.json?"),
|
|
10766
10867
|
false
|
|
10767
10868
|
);
|
|
10768
10869
|
if (!confirm) {
|