@staff0rd/assist 0.155.0 → 0.156.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 -0
- package/claude/commands/next.md +12 -0
- package/claude/settings.json +3 -0
- package/dist/index.js +632 -583
- 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.156.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -204,15 +204,44 @@ async function del(id) {
|
|
|
204
204
|
|
|
205
205
|
// src/commands/backlog/done/index.ts
|
|
206
206
|
import chalk3 from "chalk";
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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);
|
|
211
238
|
}
|
|
239
|
+
saveBacklog(result.items);
|
|
240
|
+
console.log(chalk3.green(`Completed item #${id}: ${result.item.name}`));
|
|
212
241
|
}
|
|
213
242
|
|
|
214
243
|
// src/commands/backlog/next.ts
|
|
215
|
-
import
|
|
244
|
+
import chalk9 from "chalk";
|
|
216
245
|
import enquirer2 from "enquirer";
|
|
217
246
|
|
|
218
247
|
// src/commands/backlog/list/shared.ts
|
|
@@ -255,7 +284,7 @@ function printVerboseDetails(item) {
|
|
|
255
284
|
}
|
|
256
285
|
|
|
257
286
|
// src/commands/backlog/run.ts
|
|
258
|
-
import
|
|
287
|
+
import chalk8 from "chalk";
|
|
259
288
|
|
|
260
289
|
// src/commands/backlog/buildAuthoredPhasePrompt.ts
|
|
261
290
|
function buildAuthoredPhasePrompt(item, phaseIndex, phase) {
|
|
@@ -334,9 +363,9 @@ function buildReviewPrompt(item, phaseIndex) {
|
|
|
334
363
|
"Wait for the user to confirm before proceeding.",
|
|
335
364
|
"",
|
|
336
365
|
"Once the user confirms:",
|
|
337
|
-
`1. Run: assist backlog done ${item.id}`,
|
|
366
|
+
`1. Run: assist backlog done ${item.id} "<summary>"`,
|
|
338
367
|
"2. Run: /commit",
|
|
339
|
-
`3. Run: assist backlog phase-done ${item.id} ${phaseIndex} "
|
|
368
|
+
`3. Run: assist backlog phase-done ${item.id} ${phaseIndex} "done"`
|
|
340
369
|
].filter((line) => line !== void 0).join("\n");
|
|
341
370
|
}
|
|
342
371
|
|
|
@@ -362,11 +391,11 @@ function buildReviewPhase() {
|
|
|
362
391
|
}
|
|
363
392
|
|
|
364
393
|
// src/commands/backlog/executePhase.ts
|
|
365
|
-
import
|
|
394
|
+
import chalk6 from "chalk";
|
|
366
395
|
|
|
367
396
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
368
397
|
import { existsSync as existsSync2, unlinkSync } from "fs";
|
|
369
|
-
import
|
|
398
|
+
import chalk5 from "chalk";
|
|
370
399
|
|
|
371
400
|
// src/commands/backlog/handleIncompletePhase.ts
|
|
372
401
|
import enquirer from "enquirer";
|
|
@@ -382,77 +411,34 @@ async function handleIncompletePhase() {
|
|
|
382
411
|
return "abort";
|
|
383
412
|
}
|
|
384
413
|
|
|
385
|
-
// src/commands/backlog/
|
|
414
|
+
// src/commands/backlog/writeSignal.ts
|
|
386
415
|
import { writeFileSync as writeFileSync2 } from "fs";
|
|
387
416
|
import { join as join2 } from "path";
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
function addComment(item, text, phase) {
|
|
392
|
-
const entry = {
|
|
393
|
-
text,
|
|
394
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
395
|
-
type: "comment",
|
|
396
|
-
...phase !== void 0 && { phase }
|
|
397
|
-
};
|
|
398
|
-
if (!item.comments) item.comments = [];
|
|
399
|
-
item.comments.push(entry);
|
|
400
|
-
}
|
|
401
|
-
function addPhaseSummary(item, text, phase) {
|
|
402
|
-
const entry = {
|
|
403
|
-
text,
|
|
404
|
-
phase,
|
|
405
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
406
|
-
type: "summary"
|
|
407
|
-
};
|
|
408
|
-
if (!item.comments) item.comments = [];
|
|
409
|
-
item.comments.push(entry);
|
|
417
|
+
var SIGNAL_FILE = ".assist-signal.json";
|
|
418
|
+
function getSignalPath() {
|
|
419
|
+
return join2(process.cwd(), SIGNAL_FILE);
|
|
410
420
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
return join2(process.cwd(), PHASE_STATUS_FILE);
|
|
416
|
-
}
|
|
417
|
-
function phaseDone(id, phase, summary) {
|
|
418
|
-
const phaseIndex = Number.parseInt(phase, 10);
|
|
419
|
-
const statusPath = getPhaseStatusPath();
|
|
420
|
-
writeFileSync2(
|
|
421
|
-
statusPath,
|
|
422
|
-
JSON.stringify({
|
|
423
|
-
itemId: Number.parseInt(id, 10),
|
|
424
|
-
phaseIndex,
|
|
425
|
-
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
426
|
-
})
|
|
427
|
-
);
|
|
428
|
-
const result = loadAndFindItem(id);
|
|
429
|
-
if (result) {
|
|
430
|
-
addPhaseSummary(result.item, summary, phaseIndex);
|
|
431
|
-
saveBacklog(result.items);
|
|
432
|
-
}
|
|
433
|
-
if (result?.item.status === "done") {
|
|
434
|
-
console.log(chalk5.dim(`Item #${id} already done, skipping phase advance.`));
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
setCurrentPhase(id, phaseIndex + 1);
|
|
438
|
-
console.log(chalk5.green(`Phase ${phase} of item #${id} marked as complete.`));
|
|
421
|
+
function writeSignal(event, data) {
|
|
422
|
+
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
423
|
+
const signal = { event, ...sessionId && { sessionId }, ...data };
|
|
424
|
+
writeFileSync2(getSignalPath(), JSON.stringify(signal));
|
|
439
425
|
}
|
|
440
426
|
|
|
441
427
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
442
|
-
function
|
|
443
|
-
const statusPath =
|
|
428
|
+
function cleanupSignal() {
|
|
429
|
+
const statusPath = getSignalPath();
|
|
444
430
|
if (existsSync2(statusPath)) {
|
|
445
431
|
unlinkSync(statusPath);
|
|
446
432
|
}
|
|
447
433
|
}
|
|
448
434
|
async function resolvePhaseResult(phaseIndex) {
|
|
449
|
-
if (!existsSync2(
|
|
435
|
+
if (!existsSync2(getSignalPath())) {
|
|
450
436
|
const action = await handleIncompletePhase();
|
|
451
437
|
if (action === "abort") return -1;
|
|
452
438
|
return action === "skip" ? 1 : 0;
|
|
453
439
|
}
|
|
454
|
-
|
|
455
|
-
console.log(
|
|
440
|
+
cleanupSignal();
|
|
441
|
+
console.log(chalk5.green(`
|
|
456
442
|
Phase ${phaseIndex + 1} completed.`));
|
|
457
443
|
return 1;
|
|
458
444
|
}
|
|
@@ -475,30 +461,48 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
475
461
|
}
|
|
476
462
|
|
|
477
463
|
// src/commands/backlog/watchForMarker.ts
|
|
478
|
-
import { existsSync as
|
|
464
|
+
import { existsSync as existsSync4, unwatchFile, watchFile } from "fs";
|
|
465
|
+
|
|
466
|
+
// src/commands/backlog/readSignal.ts
|
|
467
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
468
|
+
function readSignal() {
|
|
469
|
+
const path50 = getSignalPath();
|
|
470
|
+
if (!existsSync3(path50)) return void 0;
|
|
471
|
+
try {
|
|
472
|
+
return JSON.parse(readFileSync2(path50, "utf-8"));
|
|
473
|
+
} catch {
|
|
474
|
+
return void 0;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// src/commands/backlog/watchForMarker.ts
|
|
479
479
|
function watchForMarker(child) {
|
|
480
|
-
const statusPath =
|
|
480
|
+
const statusPath = getSignalPath();
|
|
481
|
+
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
481
482
|
watchFile(statusPath, { interval: 1e3 }, () => {
|
|
482
|
-
if (
|
|
483
|
+
if (!existsSync4(statusPath)) return;
|
|
484
|
+
const signal = readSignal();
|
|
485
|
+
if (signal && (!signal.sessionId || signal.sessionId === sessionId)) {
|
|
483
486
|
unwatchFile(statusPath);
|
|
484
487
|
child.kill("SIGTERM");
|
|
485
488
|
}
|
|
486
489
|
});
|
|
487
490
|
}
|
|
488
491
|
function stopWatching() {
|
|
489
|
-
unwatchFile(
|
|
492
|
+
unwatchFile(getSignalPath());
|
|
490
493
|
}
|
|
491
494
|
|
|
492
495
|
// src/commands/backlog/executePhase.ts
|
|
493
496
|
async function executePhase(item, phaseIndex, phases, spawnOptions) {
|
|
494
497
|
const phase = phases[phaseIndex];
|
|
495
498
|
console.log(
|
|
496
|
-
|
|
499
|
+
chalk6.bold(
|
|
497
500
|
`
|
|
498
501
|
--- Phase ${phaseIndex + 1}/${phases.length}: ${phase.name} ---
|
|
499
502
|
`
|
|
500
503
|
)
|
|
501
504
|
);
|
|
505
|
+
process.env.ASSIST_SESSION_ID = String(process.pid);
|
|
502
506
|
const { child, done: done2 } = spawnClaude(
|
|
503
507
|
buildPhasePrompt(item, phaseIndex, phase),
|
|
504
508
|
spawnOptions
|
|
@@ -511,7 +515,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions) {
|
|
|
511
515
|
}
|
|
512
516
|
|
|
513
517
|
// src/commands/backlog/prepareRun.ts
|
|
514
|
-
import
|
|
518
|
+
import chalk7 from "chalk";
|
|
515
519
|
|
|
516
520
|
// src/commands/backlog/resolvePlan.ts
|
|
517
521
|
function resolvePlan(item) {
|
|
@@ -534,13 +538,13 @@ function prepareRun(id) {
|
|
|
534
538
|
const plan2 = resolvePlan(item);
|
|
535
539
|
const startPhase = item.currentPhase ?? 0;
|
|
536
540
|
if (item.status === "done") {
|
|
537
|
-
console.log(
|
|
541
|
+
console.log(chalk7.green(`Already done: #${id}: ${item.name}`));
|
|
538
542
|
return void 0;
|
|
539
543
|
}
|
|
540
544
|
if (startPhase > plan2.length) {
|
|
541
545
|
setStatus(id, "done");
|
|
542
546
|
console.log(
|
|
543
|
-
|
|
547
|
+
chalk7.green(`All phases already complete for #${id}: ${item.name}`)
|
|
544
548
|
);
|
|
545
549
|
return void 0;
|
|
546
550
|
}
|
|
@@ -557,16 +561,16 @@ async function run(id, spawnOptions) {
|
|
|
557
561
|
if (!await runPhases(item, startPhase, plan2, spawnOptions)) return;
|
|
558
562
|
if (!await runReview(item, plan2, spawnOptions)) return;
|
|
559
563
|
ensureDone(id);
|
|
560
|
-
console.log(
|
|
564
|
+
console.log(chalk8.green(`
|
|
561
565
|
All phases complete for #${id}: ${item.name}`));
|
|
562
566
|
}
|
|
563
567
|
function logProgress(id, name, startPhase, total) {
|
|
564
|
-
console.log(
|
|
568
|
+
console.log(chalk8.bold(`Running plan for #${id}: ${name}`));
|
|
565
569
|
if (startPhase > 0) {
|
|
566
|
-
console.log(
|
|
570
|
+
console.log(chalk8.dim(`Resuming from phase ${startPhase + 1}/${total}
|
|
567
571
|
`));
|
|
568
572
|
} else {
|
|
569
|
-
console.log(
|
|
573
|
+
console.log(chalk8.dim(`${total} phase(s)
|
|
570
574
|
`));
|
|
571
575
|
}
|
|
572
576
|
}
|
|
@@ -602,7 +606,7 @@ async function next(options2) {
|
|
|
602
606
|
const inProgress = items.find((i) => i.status === "in-progress" && i.plan);
|
|
603
607
|
if (inProgress) {
|
|
604
608
|
console.log(
|
|
605
|
-
|
|
609
|
+
chalk9.bold(
|
|
606
610
|
`Resuming in-progress item #${inProgress.id}: ${inProgress.name}`
|
|
607
611
|
)
|
|
608
612
|
);
|
|
@@ -611,13 +615,13 @@ async function next(options2) {
|
|
|
611
615
|
}
|
|
612
616
|
const todo = items.filter((i) => i.status === "todo");
|
|
613
617
|
if (todo.length === 0) {
|
|
614
|
-
console.log(
|
|
618
|
+
console.log(chalk9.dim("No incomplete backlog items. Opening /draft..."));
|
|
615
619
|
await spawnClaude("/draft", options2);
|
|
616
620
|
return;
|
|
617
621
|
}
|
|
618
622
|
if (todo.length === 1) {
|
|
619
623
|
const only = todo[0];
|
|
620
|
-
console.log(
|
|
624
|
+
console.log(chalk9.bold(`Starting #${only.id}: ${only.name}`));
|
|
621
625
|
await run(String(only.id), options2);
|
|
622
626
|
return;
|
|
623
627
|
}
|
|
@@ -635,6 +639,28 @@ async function next(options2) {
|
|
|
635
639
|
await run(id, options2);
|
|
636
640
|
}
|
|
637
641
|
|
|
642
|
+
// src/commands/backlog/phaseDone.ts
|
|
643
|
+
import chalk10 from "chalk";
|
|
644
|
+
function phaseDone(id, phase, summary) {
|
|
645
|
+
const phaseIndex = Number.parseInt(phase, 10);
|
|
646
|
+
writeSignal("phase-done", {
|
|
647
|
+
itemId: Number.parseInt(id, 10),
|
|
648
|
+
phaseIndex,
|
|
649
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
650
|
+
});
|
|
651
|
+
const result = loadAndFindItem(id);
|
|
652
|
+
if (result?.item.status === "done") {
|
|
653
|
+
console.log(chalk10.dim(`Item #${id} already done, skipping phase advance.`));
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
if (result) {
|
|
657
|
+
addPhaseSummary(result.item, summary, phaseIndex);
|
|
658
|
+
saveBacklog(result.items);
|
|
659
|
+
}
|
|
660
|
+
setCurrentPhase(id, phaseIndex + 1);
|
|
661
|
+
console.log(chalk10.green(`Phase ${phase} of item #${id} marked as complete.`));
|
|
662
|
+
}
|
|
663
|
+
|
|
638
664
|
// src/commands/backlog/plan.ts
|
|
639
665
|
import chalk11 from "chalk";
|
|
640
666
|
function plan(id) {
|
|
@@ -755,7 +781,7 @@ async function start(id) {
|
|
|
755
781
|
|
|
756
782
|
// src/shared/web.ts
|
|
757
783
|
import { exec } from "child_process";
|
|
758
|
-
import { readFileSync as
|
|
784
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
759
785
|
import {
|
|
760
786
|
createServer
|
|
761
787
|
} from "http";
|
|
@@ -771,7 +797,7 @@ function createBundleHandler(importMetaUrl, bundlePath) {
|
|
|
771
797
|
let cache;
|
|
772
798
|
return (_req, res) => {
|
|
773
799
|
if (!cache) {
|
|
774
|
-
cache =
|
|
800
|
+
cache = readFileSync3(join3(dir, bundlePath), "utf-8");
|
|
775
801
|
}
|
|
776
802
|
res.writeHead(200, { "Content-Type": "application/javascript" });
|
|
777
803
|
res.end(cache);
|
|
@@ -953,23 +979,39 @@ async function web(options2) {
|
|
|
953
979
|
);
|
|
954
980
|
}
|
|
955
981
|
|
|
982
|
+
// src/commands/backlog/launchMode.ts
|
|
983
|
+
import chalk16 from "chalk";
|
|
984
|
+
async function launchMode(slashCommand) {
|
|
985
|
+
process.env.ASSIST_SESSION_ID = String(process.pid);
|
|
986
|
+
const { child, done: done2 } = spawnClaude(`/${slashCommand}`);
|
|
987
|
+
watchForMarker(child);
|
|
988
|
+
await done2;
|
|
989
|
+
stopWatching();
|
|
990
|
+
const signal = readSignal();
|
|
991
|
+
cleanupSignal();
|
|
992
|
+
if (signal?.event === "next") {
|
|
993
|
+
console.log(chalk16.bold("\nChaining into assist next...\n"));
|
|
994
|
+
await next({ allowEdits: true });
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
|
|
956
998
|
// src/commands/commit.ts
|
|
957
999
|
import { execSync } from "child_process";
|
|
958
1000
|
|
|
959
1001
|
// src/shared/loadConfig.ts
|
|
960
|
-
import { existsSync as
|
|
1002
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
961
1003
|
import { homedir } from "os";
|
|
962
1004
|
import { basename, dirname as dirname2, join as join4 } from "path";
|
|
963
|
-
import
|
|
1005
|
+
import chalk17 from "chalk";
|
|
964
1006
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
965
1007
|
|
|
966
1008
|
// src/shared/loadRawYaml.ts
|
|
967
|
-
import { existsSync as
|
|
1009
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
968
1010
|
import { parse as parseYaml2 } from "yaml";
|
|
969
1011
|
function loadRawYaml(path50) {
|
|
970
|
-
if (!
|
|
1012
|
+
if (!existsSync5(path50)) return {};
|
|
971
1013
|
try {
|
|
972
|
-
const content =
|
|
1014
|
+
const content = readFileSync4(path50, "utf-8");
|
|
973
1015
|
return parseYaml2(content) || {};
|
|
974
1016
|
} catch {
|
|
975
1017
|
return {};
|
|
@@ -1091,9 +1133,9 @@ function findConfigUp(startDir) {
|
|
|
1091
1133
|
let current = startDir;
|
|
1092
1134
|
while (current !== dirname2(current)) {
|
|
1093
1135
|
const claudePath = join4(current, ".claude", "assist.yml");
|
|
1094
|
-
if (
|
|
1136
|
+
if (existsSync6(claudePath)) return claudePath;
|
|
1095
1137
|
const rootPath = join4(current, "assist.yml");
|
|
1096
|
-
if (
|
|
1138
|
+
if (existsSync6(rootPath)) return rootPath;
|
|
1097
1139
|
current = dirname2(current);
|
|
1098
1140
|
}
|
|
1099
1141
|
return null;
|
|
@@ -1131,9 +1173,9 @@ function getRepoName() {
|
|
|
1131
1173
|
return config.devlog.name;
|
|
1132
1174
|
}
|
|
1133
1175
|
const packageJsonPath = join4(process.cwd(), "package.json");
|
|
1134
|
-
if (
|
|
1176
|
+
if (existsSync6(packageJsonPath)) {
|
|
1135
1177
|
try {
|
|
1136
|
-
const content =
|
|
1178
|
+
const content = readFileSync5(packageJsonPath, "utf-8");
|
|
1137
1179
|
const pkg = JSON.parse(content);
|
|
1138
1180
|
if (pkg.name) {
|
|
1139
1181
|
return pkg.name;
|
|
@@ -1147,7 +1189,7 @@ function getTranscriptConfig() {
|
|
|
1147
1189
|
const config = loadConfig();
|
|
1148
1190
|
if (!config.transcript) {
|
|
1149
1191
|
console.error(
|
|
1150
|
-
|
|
1192
|
+
chalk17.red(
|
|
1151
1193
|
"Transcript directories not configured. Run 'assist transcript configure' first."
|
|
1152
1194
|
)
|
|
1153
1195
|
);
|
|
@@ -1236,7 +1278,7 @@ function commit(args) {
|
|
|
1236
1278
|
}
|
|
1237
1279
|
|
|
1238
1280
|
// src/commands/config/index.ts
|
|
1239
|
-
import
|
|
1281
|
+
import chalk18 from "chalk";
|
|
1240
1282
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
1241
1283
|
|
|
1242
1284
|
// src/commands/config/getNestedValue.ts
|
|
@@ -1312,7 +1354,7 @@ function formatIssuePath(issue, key) {
|
|
|
1312
1354
|
function printValidationErrors(issues, key) {
|
|
1313
1355
|
for (const issue of issues) {
|
|
1314
1356
|
console.error(
|
|
1315
|
-
|
|
1357
|
+
chalk18.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
1316
1358
|
);
|
|
1317
1359
|
}
|
|
1318
1360
|
}
|
|
@@ -1332,13 +1374,13 @@ function applyConfigSet(key, coerced) {
|
|
|
1332
1374
|
function configSet(key, value) {
|
|
1333
1375
|
const coerced = coerceValue(value);
|
|
1334
1376
|
applyConfigSet(key, coerced);
|
|
1335
|
-
console.log(
|
|
1377
|
+
console.log(chalk18.green(`Set ${key} = ${JSON.stringify(coerced)}`));
|
|
1336
1378
|
}
|
|
1337
1379
|
function formatOutput(value) {
|
|
1338
1380
|
return typeof value === "object" && value !== null ? JSON.stringify(value, null, 2) : String(value);
|
|
1339
1381
|
}
|
|
1340
1382
|
function exitKeyNotSet(key) {
|
|
1341
|
-
console.error(
|
|
1383
|
+
console.error(chalk18.red(`Key "${key}" is not set`));
|
|
1342
1384
|
process.exit(1);
|
|
1343
1385
|
}
|
|
1344
1386
|
function requireNestedValue(config, key) {
|
|
@@ -1374,10 +1416,10 @@ function coverage() {
|
|
|
1374
1416
|
}
|
|
1375
1417
|
|
|
1376
1418
|
// src/commands/verify/init/index.ts
|
|
1377
|
-
import
|
|
1419
|
+
import chalk33 from "chalk";
|
|
1378
1420
|
|
|
1379
1421
|
// src/shared/promptMultiselect.ts
|
|
1380
|
-
import
|
|
1422
|
+
import chalk19 from "chalk";
|
|
1381
1423
|
import enquirer3 from "enquirer";
|
|
1382
1424
|
async function promptMultiselect(message, options2) {
|
|
1383
1425
|
const { selected } = await enquirer3.prompt({
|
|
@@ -1386,7 +1428,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1386
1428
|
message,
|
|
1387
1429
|
choices: options2.map((opt) => ({
|
|
1388
1430
|
name: opt.value,
|
|
1389
|
-
message: `${opt.name} - ${
|
|
1431
|
+
message: `${opt.name} - ${chalk19.dim(opt.description)}`
|
|
1390
1432
|
})),
|
|
1391
1433
|
// @ts-expect-error - enquirer types don't include symbols but it's supported
|
|
1392
1434
|
symbols: {
|
|
@@ -1402,7 +1444,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1402
1444
|
// src/shared/readPackageJson.ts
|
|
1403
1445
|
import * as fs from "fs";
|
|
1404
1446
|
import * as path from "path";
|
|
1405
|
-
import
|
|
1447
|
+
import chalk20 from "chalk";
|
|
1406
1448
|
function findPackageJson() {
|
|
1407
1449
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1408
1450
|
if (fs.existsSync(packageJsonPath)) {
|
|
@@ -1416,7 +1458,7 @@ function readPackageJson(filePath) {
|
|
|
1416
1458
|
function requirePackageJson() {
|
|
1417
1459
|
const packageJsonPath = findPackageJson();
|
|
1418
1460
|
if (!packageJsonPath) {
|
|
1419
|
-
console.error(
|
|
1461
|
+
console.error(chalk20.red("No package.json found in current directory"));
|
|
1420
1462
|
process.exit(1);
|
|
1421
1463
|
}
|
|
1422
1464
|
const pkg = readPackageJson(packageJsonPath);
|
|
@@ -1447,7 +1489,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1447
1489
|
// src/commands/verify/installPackage.ts
|
|
1448
1490
|
import { execSync as execSync3 } from "child_process";
|
|
1449
1491
|
import { writeFileSync as writeFileSync4 } from "fs";
|
|
1450
|
-
import
|
|
1492
|
+
import chalk21 from "chalk";
|
|
1451
1493
|
function writePackageJson(filePath, pkg) {
|
|
1452
1494
|
writeFileSync4(filePath, `${JSON.stringify(pkg, null, 2)}
|
|
1453
1495
|
`);
|
|
@@ -1462,12 +1504,12 @@ function addScript(pkg, name, command) {
|
|
|
1462
1504
|
};
|
|
1463
1505
|
}
|
|
1464
1506
|
function installPackage(name, cwd) {
|
|
1465
|
-
console.log(
|
|
1507
|
+
console.log(chalk21.dim(`Installing ${name}...`));
|
|
1466
1508
|
try {
|
|
1467
1509
|
execSync3(`npm install -D ${name}`, { stdio: "inherit", cwd });
|
|
1468
1510
|
return true;
|
|
1469
1511
|
} catch {
|
|
1470
|
-
console.error(
|
|
1512
|
+
console.error(chalk21.red(`Failed to install ${name}`));
|
|
1471
1513
|
return false;
|
|
1472
1514
|
}
|
|
1473
1515
|
}
|
|
@@ -1514,9 +1556,9 @@ var expectedScripts = {
|
|
|
1514
1556
|
};
|
|
1515
1557
|
|
|
1516
1558
|
// src/commands/verify/setup/setupBuild.ts
|
|
1517
|
-
import
|
|
1559
|
+
import chalk22 from "chalk";
|
|
1518
1560
|
async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
1519
|
-
console.log(
|
|
1561
|
+
console.log(chalk22.blue("\nSetting up build verification..."));
|
|
1520
1562
|
let command;
|
|
1521
1563
|
if (hasVite && hasTypescript) {
|
|
1522
1564
|
command = "tsc -b && vite build --logLevel error";
|
|
@@ -1525,21 +1567,21 @@ async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
|
1525
1567
|
} else {
|
|
1526
1568
|
command = "npm run build";
|
|
1527
1569
|
}
|
|
1528
|
-
console.log(
|
|
1570
|
+
console.log(chalk22.dim(`Using: ${command}`));
|
|
1529
1571
|
writer("verify:build", command);
|
|
1530
1572
|
}
|
|
1531
1573
|
async function setupTypecheck(_packageJsonPath, writer) {
|
|
1532
|
-
console.log(
|
|
1574
|
+
console.log(chalk22.blue("\nSetting up typecheck verification..."));
|
|
1533
1575
|
const command = "tsc --noEmit";
|
|
1534
|
-
console.log(
|
|
1576
|
+
console.log(chalk22.dim(`Using: ${command}`));
|
|
1535
1577
|
writer("verify:typecheck", command);
|
|
1536
1578
|
}
|
|
1537
1579
|
|
|
1538
1580
|
// src/commands/verify/setup/setupDuplicateCode.ts
|
|
1539
1581
|
import * as path2 from "path";
|
|
1540
|
-
import
|
|
1582
|
+
import chalk23 from "chalk";
|
|
1541
1583
|
async function setupDuplicateCode(packageJsonPath, writer) {
|
|
1542
|
-
console.log(
|
|
1584
|
+
console.log(chalk23.blue("\nSetting up jscpd..."));
|
|
1543
1585
|
const cwd = path2.dirname(packageJsonPath);
|
|
1544
1586
|
const pkg = readPackageJson(packageJsonPath);
|
|
1545
1587
|
const hasJscpd = !!pkg.dependencies?.jscpd || !!pkg.devDependencies?.jscpd;
|
|
@@ -1551,15 +1593,15 @@ async function setupDuplicateCode(packageJsonPath, writer) {
|
|
|
1551
1593
|
|
|
1552
1594
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1553
1595
|
import * as path3 from "path";
|
|
1554
|
-
import
|
|
1596
|
+
import chalk25 from "chalk";
|
|
1555
1597
|
|
|
1556
1598
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
1557
|
-
import { existsSync as
|
|
1599
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
|
|
1558
1600
|
import { join as join6 } from "path";
|
|
1559
|
-
import
|
|
1601
|
+
import chalk24 from "chalk";
|
|
1560
1602
|
function loadKnipConfig(knipJsonPath) {
|
|
1561
|
-
if (
|
|
1562
|
-
return JSON.parse(
|
|
1603
|
+
if (existsSync8(knipJsonPath)) {
|
|
1604
|
+
return JSON.parse(readFileSync7(knipJsonPath, "utf-8"));
|
|
1563
1605
|
}
|
|
1564
1606
|
return { $schema: "https://unpkg.com/knip@5/schema.json" };
|
|
1565
1607
|
}
|
|
@@ -1575,16 +1617,16 @@ function addToKnipIgnoreBinaries(cwd, binary) {
|
|
|
1575
1617
|
`${JSON.stringify(knipConfig, null, " ")}
|
|
1576
1618
|
`
|
|
1577
1619
|
);
|
|
1578
|
-
console.log(
|
|
1620
|
+
console.log(chalk24.dim(`Added '${binary}' to knip.json ignoreBinaries`));
|
|
1579
1621
|
}
|
|
1580
1622
|
} catch {
|
|
1581
|
-
console.log(
|
|
1623
|
+
console.log(chalk24.yellow("Warning: Could not update knip.json"));
|
|
1582
1624
|
}
|
|
1583
1625
|
}
|
|
1584
1626
|
|
|
1585
1627
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1586
1628
|
async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
1587
|
-
console.log(
|
|
1629
|
+
console.log(chalk25.blue("\nSetting up hardcoded colors check..."));
|
|
1588
1630
|
const cwd = path3.dirname(packageJsonPath);
|
|
1589
1631
|
if (!hasOpenColor) {
|
|
1590
1632
|
installPackage("open-color", cwd);
|
|
@@ -1595,9 +1637,9 @@ async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
|
1595
1637
|
|
|
1596
1638
|
// src/commands/verify/setup/setupKnip.ts
|
|
1597
1639
|
import * as path4 from "path";
|
|
1598
|
-
import
|
|
1640
|
+
import chalk26 from "chalk";
|
|
1599
1641
|
async function setupKnip(packageJsonPath, writer) {
|
|
1600
|
-
console.log(
|
|
1642
|
+
console.log(chalk26.blue("\nSetting up knip..."));
|
|
1601
1643
|
const cwd = path4.dirname(packageJsonPath);
|
|
1602
1644
|
const pkg = readPackageJson(packageJsonPath);
|
|
1603
1645
|
if (!pkg.devDependencies?.knip && !installPackage("knip", cwd)) {
|
|
@@ -1608,14 +1650,14 @@ async function setupKnip(packageJsonPath, writer) {
|
|
|
1608
1650
|
|
|
1609
1651
|
// src/commands/verify/setup/setupLint.ts
|
|
1610
1652
|
import * as path5 from "path";
|
|
1611
|
-
import
|
|
1653
|
+
import chalk29 from "chalk";
|
|
1612
1654
|
|
|
1613
1655
|
// src/commands/lint/init.ts
|
|
1614
1656
|
import { execSync as execSync5 } from "child_process";
|
|
1615
|
-
import { existsSync as
|
|
1657
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
1616
1658
|
import { dirname as dirname7, join as join7 } from "path";
|
|
1617
1659
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1618
|
-
import
|
|
1660
|
+
import chalk28 from "chalk";
|
|
1619
1661
|
|
|
1620
1662
|
// src/shared/promptConfirm.ts
|
|
1621
1663
|
import enquirer4 from "enquirer";
|
|
@@ -1636,10 +1678,10 @@ async function promptConfirm(message, initial = true) {
|
|
|
1636
1678
|
|
|
1637
1679
|
// src/shared/removeEslint/index.ts
|
|
1638
1680
|
import { execSync as execSync4 } from "child_process";
|
|
1639
|
-
import { existsSync as
|
|
1681
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
1640
1682
|
|
|
1641
1683
|
// src/shared/removeEslint/removeEslintConfigFiles.ts
|
|
1642
|
-
import { existsSync as
|
|
1684
|
+
import { existsSync as existsSync9, unlinkSync as unlinkSync2 } from "fs";
|
|
1643
1685
|
var ESLINT_CONFIG_FILES = [
|
|
1644
1686
|
"eslint.config.js",
|
|
1645
1687
|
"eslint.config.mjs",
|
|
@@ -1655,7 +1697,7 @@ var ESLINT_CONFIG_FILES = [
|
|
|
1655
1697
|
function removeEslintConfigFiles() {
|
|
1656
1698
|
let removed = false;
|
|
1657
1699
|
for (const configFile of ESLINT_CONFIG_FILES) {
|
|
1658
|
-
if (
|
|
1700
|
+
if (existsSync9(configFile)) {
|
|
1659
1701
|
unlinkSync2(configFile);
|
|
1660
1702
|
console.log(`Removed ${configFile}`);
|
|
1661
1703
|
removed = true;
|
|
@@ -1677,10 +1719,10 @@ function removeEslint(options2 = {}) {
|
|
|
1677
1719
|
}
|
|
1678
1720
|
function removeEslintFromPackageJson(options2) {
|
|
1679
1721
|
const packageJsonPath = "package.json";
|
|
1680
|
-
if (!
|
|
1722
|
+
if (!existsSync10(packageJsonPath)) {
|
|
1681
1723
|
return false;
|
|
1682
1724
|
}
|
|
1683
|
-
const packageJson = JSON.parse(
|
|
1725
|
+
const packageJson = JSON.parse(readFileSync8(packageJsonPath, "utf-8"));
|
|
1684
1726
|
let modified = false;
|
|
1685
1727
|
modified = removeEslintDeps(packageJson.dependencies) || modified;
|
|
1686
1728
|
modified = removeEslintDeps(packageJson.devDependencies) || modified;
|
|
@@ -1717,7 +1759,7 @@ function removeEslintScripts(scripts, options2) {
|
|
|
1717
1759
|
}
|
|
1718
1760
|
|
|
1719
1761
|
// src/utils/printDiff.ts
|
|
1720
|
-
import
|
|
1762
|
+
import chalk27 from "chalk";
|
|
1721
1763
|
import * as diff from "diff";
|
|
1722
1764
|
function normalizeJson(content) {
|
|
1723
1765
|
try {
|
|
@@ -1735,11 +1777,11 @@ function printDiff(oldContent, newContent) {
|
|
|
1735
1777
|
const lines = change.value.replace(/\n$/, "").split("\n");
|
|
1736
1778
|
for (const line of lines) {
|
|
1737
1779
|
if (change.added) {
|
|
1738
|
-
console.log(
|
|
1780
|
+
console.log(chalk27.green(`+ ${line}`));
|
|
1739
1781
|
} else if (change.removed) {
|
|
1740
|
-
console.log(
|
|
1782
|
+
console.log(chalk27.red(`- ${line}`));
|
|
1741
1783
|
} else {
|
|
1742
|
-
console.log(
|
|
1784
|
+
console.log(chalk27.dim(` ${line}`));
|
|
1743
1785
|
}
|
|
1744
1786
|
}
|
|
1745
1787
|
}
|
|
@@ -1750,17 +1792,17 @@ var __dirname2 = dirname7(fileURLToPath2(import.meta.url));
|
|
|
1750
1792
|
async function init() {
|
|
1751
1793
|
removeEslint();
|
|
1752
1794
|
const biomeConfigPath = "biome.json";
|
|
1753
|
-
if (!
|
|
1795
|
+
if (!existsSync11(biomeConfigPath)) {
|
|
1754
1796
|
console.log("Initializing Biome...");
|
|
1755
1797
|
execSync5("npx @biomejs/biome init", { stdio: "inherit" });
|
|
1756
1798
|
}
|
|
1757
|
-
if (!
|
|
1799
|
+
if (!existsSync11(biomeConfigPath)) {
|
|
1758
1800
|
console.log("No biome.json found, skipping linter config");
|
|
1759
1801
|
return;
|
|
1760
1802
|
}
|
|
1761
1803
|
const linterConfigPath = join7(__dirname2, "commands/lint/biome.linter.json");
|
|
1762
|
-
const linterConfig = JSON.parse(
|
|
1763
|
-
const biomeConfig = JSON.parse(
|
|
1804
|
+
const linterConfig = JSON.parse(readFileSync9(linterConfigPath, "utf-8"));
|
|
1805
|
+
const biomeConfig = JSON.parse(readFileSync9(biomeConfigPath, "utf-8"));
|
|
1764
1806
|
const oldContent = `${JSON.stringify(biomeConfig, null, 2)}
|
|
1765
1807
|
`;
|
|
1766
1808
|
biomeConfig.linter = linterConfig.linter;
|
|
@@ -1773,10 +1815,10 @@ async function init() {
|
|
|
1773
1815
|
console.log("biome.json already has the correct linter config");
|
|
1774
1816
|
return;
|
|
1775
1817
|
}
|
|
1776
|
-
console.log(
|
|
1818
|
+
console.log(chalk28.yellow("\n\u26A0\uFE0F biome.json will be updated:"));
|
|
1777
1819
|
console.log();
|
|
1778
1820
|
printDiff(oldContent, newContent);
|
|
1779
|
-
const confirm = await promptConfirm(
|
|
1821
|
+
const confirm = await promptConfirm(chalk28.red("Update biome.json?"));
|
|
1780
1822
|
if (!confirm) {
|
|
1781
1823
|
console.log("Skipped biome.json update");
|
|
1782
1824
|
return;
|
|
@@ -1787,7 +1829,7 @@ async function init() {
|
|
|
1787
1829
|
|
|
1788
1830
|
// src/commands/verify/setup/setupLint.ts
|
|
1789
1831
|
async function setupLint(packageJsonPath, writer) {
|
|
1790
|
-
console.log(
|
|
1832
|
+
console.log(chalk29.blue("\nSetting up biome..."));
|
|
1791
1833
|
const cwd = path5.dirname(packageJsonPath);
|
|
1792
1834
|
const pkg = readPackageJson(packageJsonPath);
|
|
1793
1835
|
if (!pkg.devDependencies?.["@biomejs/biome"]) {
|
|
@@ -1801,9 +1843,9 @@ async function setupLint(packageJsonPath, writer) {
|
|
|
1801
1843
|
|
|
1802
1844
|
// src/commands/verify/setup/setupMadge.ts
|
|
1803
1845
|
import * as path6 from "path";
|
|
1804
|
-
import
|
|
1846
|
+
import chalk30 from "chalk";
|
|
1805
1847
|
async function setupMadge(packageJsonPath, writer) {
|
|
1806
|
-
console.log(
|
|
1848
|
+
console.log(chalk30.blue("\nSetting up madge..."));
|
|
1807
1849
|
const cwd = path6.dirname(packageJsonPath);
|
|
1808
1850
|
const pkg = readPackageJson(packageJsonPath);
|
|
1809
1851
|
const hasMadge = !!pkg.dependencies?.madge || !!pkg.devDependencies?.madge;
|
|
@@ -1815,18 +1857,18 @@ async function setupMadge(packageJsonPath, writer) {
|
|
|
1815
1857
|
|
|
1816
1858
|
// src/commands/verify/setup/setupMaintainability.ts
|
|
1817
1859
|
import * as path7 from "path";
|
|
1818
|
-
import
|
|
1860
|
+
import chalk31 from "chalk";
|
|
1819
1861
|
async function setupMaintainability(packageJsonPath, writer) {
|
|
1820
|
-
console.log(
|
|
1862
|
+
console.log(chalk31.blue("\nSetting up maintainability check..."));
|
|
1821
1863
|
addToKnipIgnoreBinaries(path7.dirname(packageJsonPath), "assist");
|
|
1822
1864
|
writer("verify:maintainability", expectedScripts["verify:maintainability"]);
|
|
1823
1865
|
}
|
|
1824
1866
|
|
|
1825
1867
|
// src/commands/verify/setup/setupTest.ts
|
|
1826
1868
|
import * as path8 from "path";
|
|
1827
|
-
import
|
|
1869
|
+
import chalk32 from "chalk";
|
|
1828
1870
|
async function setupTest(packageJsonPath, writer) {
|
|
1829
|
-
console.log(
|
|
1871
|
+
console.log(chalk32.blue("\nSetting up vitest..."));
|
|
1830
1872
|
const cwd = path8.dirname(packageJsonPath);
|
|
1831
1873
|
const pkg = readPackageJson(packageJsonPath);
|
|
1832
1874
|
if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
|
|
@@ -1995,25 +2037,25 @@ async function runSelectedSetups(selected, packageJsonPath, writer, handlers) {
|
|
|
1995
2037
|
for (const choice of selected) {
|
|
1996
2038
|
await handlers[choice]?.(packageJsonPath, writer);
|
|
1997
2039
|
}
|
|
1998
|
-
console.log(
|
|
2040
|
+
console.log(chalk33.green(`
|
|
1999
2041
|
Added ${selected.length} verify script(s):`));
|
|
2000
2042
|
for (const choice of selected) {
|
|
2001
|
-
console.log(
|
|
2043
|
+
console.log(chalk33.green(` - verify:${choice}`));
|
|
2002
2044
|
}
|
|
2003
|
-
console.log(
|
|
2045
|
+
console.log(chalk33.dim("\nRun 'assist verify' to run all verify scripts"));
|
|
2004
2046
|
}
|
|
2005
2047
|
async function promptForScripts(availableOptions) {
|
|
2006
2048
|
if (availableOptions.length === 0) {
|
|
2007
|
-
console.log(
|
|
2049
|
+
console.log(chalk33.green("All verify scripts are already configured!"));
|
|
2008
2050
|
return null;
|
|
2009
2051
|
}
|
|
2010
|
-
console.log(
|
|
2052
|
+
console.log(chalk33.bold("Available verify scripts to add:\n"));
|
|
2011
2053
|
const selected = await promptMultiselect(
|
|
2012
2054
|
"Select verify scripts to add:",
|
|
2013
2055
|
availableOptions
|
|
2014
2056
|
);
|
|
2015
2057
|
if (selected.length === 0) {
|
|
2016
|
-
console.log(
|
|
2058
|
+
console.log(chalk33.yellow("No scripts selected"));
|
|
2017
2059
|
return null;
|
|
2018
2060
|
}
|
|
2019
2061
|
return selected;
|
|
@@ -2033,17 +2075,17 @@ async function init2() {
|
|
|
2033
2075
|
}
|
|
2034
2076
|
|
|
2035
2077
|
// src/commands/vscode/init/index.ts
|
|
2036
|
-
import
|
|
2078
|
+
import chalk35 from "chalk";
|
|
2037
2079
|
|
|
2038
2080
|
// src/commands/vscode/init/createLaunchJson.ts
|
|
2039
2081
|
import * as fs2 from "fs";
|
|
2040
2082
|
import * as path9 from "path";
|
|
2041
|
-
import
|
|
2083
|
+
import chalk34 from "chalk";
|
|
2042
2084
|
function ensureVscodeFolder() {
|
|
2043
2085
|
const vscodeDir = path9.join(process.cwd(), ".vscode");
|
|
2044
2086
|
if (!fs2.existsSync(vscodeDir)) {
|
|
2045
2087
|
fs2.mkdirSync(vscodeDir);
|
|
2046
|
-
console.log(
|
|
2088
|
+
console.log(chalk34.dim("Created .vscode folder"));
|
|
2047
2089
|
}
|
|
2048
2090
|
}
|
|
2049
2091
|
function removeVscodeFromGitignore() {
|
|
@@ -2058,7 +2100,7 @@ function removeVscodeFromGitignore() {
|
|
|
2058
2100
|
);
|
|
2059
2101
|
if (filteredLines.length !== lines.length) {
|
|
2060
2102
|
fs2.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
2061
|
-
console.log(
|
|
2103
|
+
console.log(chalk34.dim("Removed .vscode references from .gitignore"));
|
|
2062
2104
|
}
|
|
2063
2105
|
}
|
|
2064
2106
|
function createLaunchJson(type) {
|
|
@@ -2077,7 +2119,7 @@ function createLaunchJson(type) {
|
|
|
2077
2119
|
const launchPath = path9.join(process.cwd(), ".vscode", "launch.json");
|
|
2078
2120
|
fs2.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
|
|
2079
2121
|
`);
|
|
2080
|
-
console.log(
|
|
2122
|
+
console.log(chalk34.green("Created .vscode/launch.json"));
|
|
2081
2123
|
}
|
|
2082
2124
|
function createSettingsJson() {
|
|
2083
2125
|
const settings = {
|
|
@@ -2090,7 +2132,7 @@ function createSettingsJson() {
|
|
|
2090
2132
|
const settingsPath = path9.join(process.cwd(), ".vscode", "settings.json");
|
|
2091
2133
|
fs2.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
|
|
2092
2134
|
`);
|
|
2093
|
-
console.log(
|
|
2135
|
+
console.log(chalk34.green("Created .vscode/settings.json"));
|
|
2094
2136
|
}
|
|
2095
2137
|
function createExtensionsJson() {
|
|
2096
2138
|
const extensions = {
|
|
@@ -2102,7 +2144,7 @@ function createExtensionsJson() {
|
|
|
2102
2144
|
`${JSON.stringify(extensions, null, " ")}
|
|
2103
2145
|
`
|
|
2104
2146
|
);
|
|
2105
|
-
console.log(
|
|
2147
|
+
console.log(chalk34.green("Created .vscode/extensions.json"));
|
|
2106
2148
|
}
|
|
2107
2149
|
|
|
2108
2150
|
// src/commands/vscode/init/detectVscodeSetup.ts
|
|
@@ -2159,7 +2201,7 @@ function applySelections(selected, setup2) {
|
|
|
2159
2201
|
for (const choice of selected) handlers[choice]?.();
|
|
2160
2202
|
}
|
|
2161
2203
|
async function promptForOptions(options2) {
|
|
2162
|
-
console.log(
|
|
2204
|
+
console.log(chalk35.bold("Available VS Code configurations to add:\n"));
|
|
2163
2205
|
return promptMultiselect("Select configurations to add:", options2);
|
|
2164
2206
|
}
|
|
2165
2207
|
async function init3({ all = false } = {}) {
|
|
@@ -2167,17 +2209,17 @@ async function init3({ all = false } = {}) {
|
|
|
2167
2209
|
const setup2 = detectVscodeSetup(pkg);
|
|
2168
2210
|
const options2 = getAvailableOptions2(setup2);
|
|
2169
2211
|
if (options2.length === 0) {
|
|
2170
|
-
console.log(
|
|
2212
|
+
console.log(chalk35.green("VS Code configuration already exists!"));
|
|
2171
2213
|
return;
|
|
2172
2214
|
}
|
|
2173
2215
|
const selected = all ? options2.map((o) => o.value) : await promptForOptions(options2);
|
|
2174
2216
|
if (selected.length === 0) {
|
|
2175
|
-
console.log(
|
|
2217
|
+
console.log(chalk35.yellow("No configurations selected"));
|
|
2176
2218
|
return;
|
|
2177
2219
|
}
|
|
2178
2220
|
applySelections(selected, setup2);
|
|
2179
2221
|
console.log(
|
|
2180
|
-
|
|
2222
|
+
chalk35.green(`
|
|
2181
2223
|
Added ${selected.length} VS Code configuration(s)`)
|
|
2182
2224
|
);
|
|
2183
2225
|
}
|
|
@@ -2190,7 +2232,7 @@ async function init4() {
|
|
|
2190
2232
|
|
|
2191
2233
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2192
2234
|
import path16 from "path";
|
|
2193
|
-
import
|
|
2235
|
+
import chalk37 from "chalk";
|
|
2194
2236
|
|
|
2195
2237
|
// src/commands/lint/lint/checkFileNames.ts
|
|
2196
2238
|
import fs5 from "fs";
|
|
@@ -2270,7 +2312,7 @@ function checkFileNames() {
|
|
|
2270
2312
|
}
|
|
2271
2313
|
|
|
2272
2314
|
// src/commands/lint/lint/fixFileNameViolations.ts
|
|
2273
|
-
import
|
|
2315
|
+
import chalk36 from "chalk";
|
|
2274
2316
|
|
|
2275
2317
|
// src/commands/lint/lint/applyMoves.ts
|
|
2276
2318
|
import fs6 from "fs";
|
|
@@ -2355,25 +2397,25 @@ function fixFileNameViolations(moves) {
|
|
|
2355
2397
|
const start3 = performance.now();
|
|
2356
2398
|
const project = createLintProject();
|
|
2357
2399
|
const cwd = process.cwd();
|
|
2358
|
-
applyMoves(project, moves, cwd, (line) => console.log(
|
|
2400
|
+
applyMoves(project, moves, cwd, (line) => console.log(chalk36.green(line)));
|
|
2359
2401
|
const ms = (performance.now() - start3).toFixed(0);
|
|
2360
|
-
console.log(
|
|
2402
|
+
console.log(chalk36.dim(` Done in ${ms}ms`));
|
|
2361
2403
|
}
|
|
2362
2404
|
|
|
2363
2405
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2364
2406
|
function reportViolations(violations) {
|
|
2365
|
-
console.error(
|
|
2407
|
+
console.error(chalk37.red("\nFile name check failed:\n"));
|
|
2366
2408
|
console.error(
|
|
2367
|
-
|
|
2409
|
+
chalk37.red(
|
|
2368
2410
|
" Files without classes or React components should not start with a capital letter.\n"
|
|
2369
2411
|
)
|
|
2370
2412
|
);
|
|
2371
2413
|
for (const violation of violations) {
|
|
2372
|
-
console.error(
|
|
2373
|
-
console.error(
|
|
2414
|
+
console.error(chalk37.red(` ${violation.filePath}`));
|
|
2415
|
+
console.error(chalk37.gray(` Rename to: ${violation.suggestedName}
|
|
2374
2416
|
`));
|
|
2375
2417
|
}
|
|
2376
|
-
console.error(
|
|
2418
|
+
console.error(chalk37.dim(" Run with -f to auto-fix.\n"));
|
|
2377
2419
|
}
|
|
2378
2420
|
function runFileNameCheck(fix = false) {
|
|
2379
2421
|
const violations = checkFileNames();
|
|
@@ -2402,17 +2444,17 @@ function runFileNameCheck(fix = false) {
|
|
|
2402
2444
|
import fs8 from "fs";
|
|
2403
2445
|
|
|
2404
2446
|
// src/commands/lint/shared.ts
|
|
2405
|
-
import
|
|
2447
|
+
import chalk38 from "chalk";
|
|
2406
2448
|
function reportViolations2(violations, checkName, errorMessage, successMessage) {
|
|
2407
2449
|
if (violations.length > 0) {
|
|
2408
|
-
console.error(
|
|
2450
|
+
console.error(chalk38.red(`
|
|
2409
2451
|
${checkName} failed:
|
|
2410
2452
|
`));
|
|
2411
|
-
console.error(
|
|
2453
|
+
console.error(chalk38.red(` ${errorMessage}
|
|
2412
2454
|
`));
|
|
2413
2455
|
for (const violation of violations) {
|
|
2414
|
-
console.error(
|
|
2415
|
-
console.error(
|
|
2456
|
+
console.error(chalk38.red(` ${violation.filePath}:${violation.line}`));
|
|
2457
|
+
console.error(chalk38.gray(` ${violation.content}
|
|
2416
2458
|
`));
|
|
2417
2459
|
}
|
|
2418
2460
|
return false;
|
|
@@ -2888,56 +2930,56 @@ async function newCli() {
|
|
|
2888
2930
|
|
|
2889
2931
|
// src/commands/new/registerNew/newProject.ts
|
|
2890
2932
|
import { execSync as execSync13 } from "child_process";
|
|
2891
|
-
import { existsSync as
|
|
2933
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
2892
2934
|
|
|
2893
2935
|
// src/commands/deploy/init/index.ts
|
|
2894
2936
|
import { execSync as execSync12 } from "child_process";
|
|
2895
|
-
import
|
|
2937
|
+
import chalk40 from "chalk";
|
|
2896
2938
|
import enquirer5 from "enquirer";
|
|
2897
2939
|
|
|
2898
2940
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
2899
|
-
import { existsSync as
|
|
2941
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync3, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "fs";
|
|
2900
2942
|
import { dirname as dirname13, join as join10 } from "path";
|
|
2901
2943
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2902
|
-
import
|
|
2944
|
+
import chalk39 from "chalk";
|
|
2903
2945
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
2904
2946
|
var __dirname3 = dirname13(fileURLToPath3(import.meta.url));
|
|
2905
2947
|
function getExistingSiteId() {
|
|
2906
|
-
if (!
|
|
2948
|
+
if (!existsSync14(WORKFLOW_PATH)) {
|
|
2907
2949
|
return null;
|
|
2908
2950
|
}
|
|
2909
|
-
const content =
|
|
2951
|
+
const content = readFileSync11(WORKFLOW_PATH, "utf-8");
|
|
2910
2952
|
const match = content.match(/-s\s+([a-f0-9-]{36})/);
|
|
2911
2953
|
return match ? match[1] : null;
|
|
2912
2954
|
}
|
|
2913
2955
|
function getTemplateContent(siteId) {
|
|
2914
2956
|
const templatePath = join10(__dirname3, "commands/deploy/build.yml");
|
|
2915
|
-
const template =
|
|
2957
|
+
const template = readFileSync11(templatePath, "utf-8");
|
|
2916
2958
|
return template.replace("{{NETLIFY_SITE_ID}}", siteId);
|
|
2917
2959
|
}
|
|
2918
2960
|
async function updateWorkflow(siteId) {
|
|
2919
2961
|
const newContent = getTemplateContent(siteId);
|
|
2920
2962
|
const workflowDir = ".github/workflows";
|
|
2921
|
-
if (!
|
|
2963
|
+
if (!existsSync14(workflowDir)) {
|
|
2922
2964
|
mkdirSync3(workflowDir, { recursive: true });
|
|
2923
2965
|
}
|
|
2924
|
-
if (
|
|
2925
|
-
const oldContent =
|
|
2966
|
+
if (existsSync14(WORKFLOW_PATH)) {
|
|
2967
|
+
const oldContent = readFileSync11(WORKFLOW_PATH, "utf-8");
|
|
2926
2968
|
if (oldContent === newContent) {
|
|
2927
|
-
console.log(
|
|
2969
|
+
console.log(chalk39.green("build.yml is already up to date"));
|
|
2928
2970
|
return;
|
|
2929
2971
|
}
|
|
2930
|
-
console.log(
|
|
2972
|
+
console.log(chalk39.yellow("\nbuild.yml will be updated:"));
|
|
2931
2973
|
console.log();
|
|
2932
2974
|
printDiff(oldContent, newContent);
|
|
2933
|
-
const confirm = await promptConfirm(
|
|
2975
|
+
const confirm = await promptConfirm(chalk39.red("Update build.yml?"));
|
|
2934
2976
|
if (!confirm) {
|
|
2935
2977
|
console.log("Skipped build.yml update");
|
|
2936
2978
|
return;
|
|
2937
2979
|
}
|
|
2938
2980
|
}
|
|
2939
2981
|
writeFileSync11(WORKFLOW_PATH, newContent);
|
|
2940
|
-
console.log(
|
|
2982
|
+
console.log(chalk39.green(`
|
|
2941
2983
|
Created ${WORKFLOW_PATH}`));
|
|
2942
2984
|
}
|
|
2943
2985
|
|
|
@@ -2948,43 +2990,43 @@ async function ensureNetlifyCli() {
|
|
|
2948
2990
|
} catch (error) {
|
|
2949
2991
|
if (!(error instanceof Error) || !error.message.includes("command not found"))
|
|
2950
2992
|
throw error;
|
|
2951
|
-
console.error(
|
|
2993
|
+
console.error(chalk40.red("\nNetlify CLI is not installed.\n"));
|
|
2952
2994
|
const install = await promptConfirm("Would you like to install it now?");
|
|
2953
2995
|
if (!install) {
|
|
2954
2996
|
console.log(
|
|
2955
|
-
|
|
2997
|
+
chalk40.yellow(
|
|
2956
2998
|
"\nInstall it manually with: npm install -g netlify-cli\n"
|
|
2957
2999
|
)
|
|
2958
3000
|
);
|
|
2959
3001
|
process.exit(1);
|
|
2960
3002
|
}
|
|
2961
|
-
console.log(
|
|
3003
|
+
console.log(chalk40.dim("\nInstalling netlify-cli...\n"));
|
|
2962
3004
|
execSync12("npm install -g netlify-cli", { stdio: "inherit" });
|
|
2963
3005
|
console.log();
|
|
2964
3006
|
execSync12("netlify sites:create --disable-linking", { stdio: "inherit" });
|
|
2965
3007
|
}
|
|
2966
3008
|
}
|
|
2967
3009
|
function printSetupInstructions() {
|
|
2968
|
-
console.log(
|
|
3010
|
+
console.log(chalk40.bold("\nDeployment initialized successfully!"));
|
|
2969
3011
|
console.log(
|
|
2970
|
-
|
|
3012
|
+
chalk40.yellow("\nTo complete setup, create a personal access token at:")
|
|
2971
3013
|
);
|
|
2972
3014
|
console.log(
|
|
2973
|
-
|
|
3015
|
+
chalk40.cyan(
|
|
2974
3016
|
"https://app.netlify.com/user/applications#personal-access-tokens"
|
|
2975
3017
|
)
|
|
2976
3018
|
);
|
|
2977
3019
|
console.log(
|
|
2978
|
-
|
|
3020
|
+
chalk40.yellow(
|
|
2979
3021
|
"\nThen add it as NETLIFY_AUTH_TOKEN in your GitHub repository secrets."
|
|
2980
3022
|
)
|
|
2981
3023
|
);
|
|
2982
3024
|
}
|
|
2983
3025
|
async function init5() {
|
|
2984
|
-
console.log(
|
|
3026
|
+
console.log(chalk40.bold("Initializing Netlify deployment...\n"));
|
|
2985
3027
|
const existingSiteId = getExistingSiteId();
|
|
2986
3028
|
if (existingSiteId) {
|
|
2987
|
-
console.log(
|
|
3029
|
+
console.log(chalk40.dim(`Using existing site ID: ${existingSiteId}
|
|
2988
3030
|
`));
|
|
2989
3031
|
await updateWorkflow(existingSiteId);
|
|
2990
3032
|
return;
|
|
@@ -3016,11 +3058,11 @@ async function newProject() {
|
|
|
3016
3058
|
}
|
|
3017
3059
|
function addViteBaseConfig() {
|
|
3018
3060
|
const viteConfigPath = "vite.config.ts";
|
|
3019
|
-
if (!
|
|
3061
|
+
if (!existsSync15(viteConfigPath)) {
|
|
3020
3062
|
console.log("No vite.config.ts found, skipping base config");
|
|
3021
3063
|
return;
|
|
3022
3064
|
}
|
|
3023
|
-
const content =
|
|
3065
|
+
const content = readFileSync12(viteConfigPath, "utf-8");
|
|
3024
3066
|
if (content.includes("base:")) {
|
|
3025
3067
|
console.log("vite.config.ts already has base config");
|
|
3026
3068
|
return;
|
|
@@ -3163,27 +3205,27 @@ async function notify() {
|
|
|
3163
3205
|
}
|
|
3164
3206
|
|
|
3165
3207
|
// src/commands/backlog/comment/index.ts
|
|
3166
|
-
import
|
|
3208
|
+
import chalk41 from "chalk";
|
|
3167
3209
|
function comment(id, text) {
|
|
3168
3210
|
const result = loadAndFindItem(id);
|
|
3169
3211
|
if (!result) process.exit(1);
|
|
3170
3212
|
addComment(result.item, text);
|
|
3171
3213
|
saveBacklog(result.items);
|
|
3172
|
-
console.log(
|
|
3214
|
+
console.log(chalk41.green(`Comment added to item #${id}.`));
|
|
3173
3215
|
}
|
|
3174
3216
|
|
|
3175
3217
|
// src/commands/backlog/comments/index.ts
|
|
3176
|
-
import
|
|
3218
|
+
import chalk42 from "chalk";
|
|
3177
3219
|
function comments(id) {
|
|
3178
3220
|
const result = loadAndFindItem(id);
|
|
3179
3221
|
if (!result) process.exit(1);
|
|
3180
3222
|
const { item } = result;
|
|
3181
3223
|
const entries = item.comments ?? [];
|
|
3182
3224
|
if (entries.length === 0) {
|
|
3183
|
-
console.log(
|
|
3225
|
+
console.log(chalk42.dim(`No comments on item #${id}.`));
|
|
3184
3226
|
return;
|
|
3185
3227
|
}
|
|
3186
|
-
console.log(
|
|
3228
|
+
console.log(chalk42.bold(`Comments for #${id}: ${item.name}
|
|
3187
3229
|
`));
|
|
3188
3230
|
for (const entry of entries) {
|
|
3189
3231
|
console.log(`${formatComment(entry)}
|
|
@@ -3198,12 +3240,12 @@ function registerCommentCommands(cmd) {
|
|
|
3198
3240
|
}
|
|
3199
3241
|
|
|
3200
3242
|
// src/commands/backlog/add/index.ts
|
|
3201
|
-
import { existsSync as
|
|
3202
|
-
import
|
|
3243
|
+
import { existsSync as existsSync16 } from "fs";
|
|
3244
|
+
import chalk44 from "chalk";
|
|
3203
3245
|
|
|
3204
3246
|
// src/commands/backlog/commitBacklog.ts
|
|
3205
3247
|
import { execSync as execSync14 } from "child_process";
|
|
3206
|
-
import
|
|
3248
|
+
import chalk43 from "chalk";
|
|
3207
3249
|
function commitBacklog(id, name) {
|
|
3208
3250
|
try {
|
|
3209
3251
|
const backlogPath = getBacklogPath();
|
|
@@ -3211,13 +3253,13 @@ function commitBacklog(id, name) {
|
|
|
3211
3253
|
execSync14(`git add ${shellQuote(backlogPath)}`, { stdio: "ignore" });
|
|
3212
3254
|
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3213
3255
|
} catch {
|
|
3214
|
-
console.log(
|
|
3256
|
+
console.log(chalk43.yellow("Warning: could not auto-commit backlog file."));
|
|
3215
3257
|
}
|
|
3216
3258
|
}
|
|
3217
3259
|
|
|
3218
3260
|
// src/commands/backlog/add/shared.ts
|
|
3219
3261
|
import { spawnSync } from "child_process";
|
|
3220
|
-
import { mkdtempSync, readFileSync as
|
|
3262
|
+
import { mkdtempSync, readFileSync as readFileSync13, unlinkSync as unlinkSync3, writeFileSync as writeFileSync13 } from "fs";
|
|
3221
3263
|
import { tmpdir } from "os";
|
|
3222
3264
|
import { join as join11 } from "path";
|
|
3223
3265
|
import enquirer6 from "enquirer";
|
|
@@ -3267,7 +3309,7 @@ function openEditor() {
|
|
|
3267
3309
|
unlinkSync3(filePath);
|
|
3268
3310
|
return void 0;
|
|
3269
3311
|
}
|
|
3270
|
-
const content =
|
|
3312
|
+
const content = readFileSync13(filePath, "utf-8").trim();
|
|
3271
3313
|
unlinkSync3(filePath);
|
|
3272
3314
|
return content || void 0;
|
|
3273
3315
|
}
|
|
@@ -3289,7 +3331,7 @@ async function promptAcceptanceCriteria() {
|
|
|
3289
3331
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3290
3332
|
async function addFromJson() {
|
|
3291
3333
|
if (process.stdin.isTTY) {
|
|
3292
|
-
console.log(
|
|
3334
|
+
console.log(chalk44.red("--json requires piped input on stdin."));
|
|
3293
3335
|
return;
|
|
3294
3336
|
}
|
|
3295
3337
|
const input = await readStdin();
|
|
@@ -3303,7 +3345,7 @@ async function addFromJson() {
|
|
|
3303
3345
|
items.push({ ...data, id, status: "todo" });
|
|
3304
3346
|
saveBacklog(items);
|
|
3305
3347
|
commitBacklog(id, data.name);
|
|
3306
|
-
console.log(
|
|
3348
|
+
console.log(chalk44.green(`Added item #${id}: ${data.name}`));
|
|
3307
3349
|
}
|
|
3308
3350
|
async function addInteractive() {
|
|
3309
3351
|
const type = await promptType();
|
|
@@ -3322,12 +3364,12 @@ async function addInteractive() {
|
|
|
3322
3364
|
});
|
|
3323
3365
|
saveBacklog(items);
|
|
3324
3366
|
commitBacklog(id, name);
|
|
3325
|
-
console.log(
|
|
3367
|
+
console.log(chalk44.green(`Added item #${id}: ${name}`));
|
|
3326
3368
|
}
|
|
3327
3369
|
async function add(options2) {
|
|
3328
|
-
if (!
|
|
3370
|
+
if (!existsSync16(getBacklogPath())) {
|
|
3329
3371
|
console.log(
|
|
3330
|
-
|
|
3372
|
+
chalk44.yellow(
|
|
3331
3373
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3332
3374
|
)
|
|
3333
3375
|
);
|
|
@@ -3341,30 +3383,30 @@ async function add(options2) {
|
|
|
3341
3383
|
}
|
|
3342
3384
|
|
|
3343
3385
|
// src/commands/backlog/init/index.ts
|
|
3344
|
-
import { existsSync as
|
|
3345
|
-
import
|
|
3386
|
+
import { existsSync as existsSync17 } from "fs";
|
|
3387
|
+
import chalk45 from "chalk";
|
|
3346
3388
|
async function init6() {
|
|
3347
3389
|
const backlogPath = getBacklogPath();
|
|
3348
|
-
if (
|
|
3349
|
-
console.log(
|
|
3390
|
+
if (existsSync17(backlogPath)) {
|
|
3391
|
+
console.log(chalk45.yellow("assist.backlog.yml already exists."));
|
|
3350
3392
|
return;
|
|
3351
3393
|
}
|
|
3352
3394
|
saveBacklog([]);
|
|
3353
|
-
console.log(
|
|
3395
|
+
console.log(chalk45.green("Created assist.backlog.yml"));
|
|
3354
3396
|
}
|
|
3355
3397
|
|
|
3356
3398
|
// src/commands/backlog/list/index.ts
|
|
3357
|
-
import { existsSync as
|
|
3358
|
-
import
|
|
3399
|
+
import { existsSync as existsSync18 } from "fs";
|
|
3400
|
+
import chalk46 from "chalk";
|
|
3359
3401
|
function filterItems(items, options2) {
|
|
3360
3402
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3361
3403
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
3362
3404
|
return items;
|
|
3363
3405
|
}
|
|
3364
3406
|
async function list2(options2) {
|
|
3365
|
-
if (!
|
|
3407
|
+
if (!existsSync18(getBacklogPath())) {
|
|
3366
3408
|
console.log(
|
|
3367
|
-
|
|
3409
|
+
chalk46.yellow(
|
|
3368
3410
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3369
3411
|
)
|
|
3370
3412
|
);
|
|
@@ -3372,12 +3414,12 @@ async function list2(options2) {
|
|
|
3372
3414
|
}
|
|
3373
3415
|
const items = filterItems(loadBacklog(), options2);
|
|
3374
3416
|
if (items.length === 0) {
|
|
3375
|
-
console.log(
|
|
3417
|
+
console.log(chalk46.dim("Backlog is empty."));
|
|
3376
3418
|
return;
|
|
3377
3419
|
}
|
|
3378
3420
|
for (const item of items) {
|
|
3379
3421
|
console.log(
|
|
3380
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3422
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk46.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
|
|
3381
3423
|
);
|
|
3382
3424
|
if (options2.verbose) {
|
|
3383
3425
|
printVerboseDetails(item);
|
|
@@ -3398,7 +3440,7 @@ function registerShowCommands(cmd) {
|
|
|
3398
3440
|
}
|
|
3399
3441
|
function registerStatusCommands(cmd) {
|
|
3400
3442
|
cmd.command("start <id>").description("Set a backlog item to in-progress").action(start);
|
|
3401
|
-
cmd.command("done <id>").description("Set a backlog item to done").action(done);
|
|
3443
|
+
cmd.command("done <id> [summary]").description("Set a backlog item to done").action(done);
|
|
3402
3444
|
cmd.command("delete <id>").alias("remove").description("Delete a backlog item").action(del);
|
|
3403
3445
|
}
|
|
3404
3446
|
function registerWebCommand(cmd) {
|
|
@@ -3512,7 +3554,7 @@ function extractGraphqlQuery(args) {
|
|
|
3512
3554
|
}
|
|
3513
3555
|
|
|
3514
3556
|
// src/shared/loadCliReads.ts
|
|
3515
|
-
import { existsSync as
|
|
3557
|
+
import { existsSync as existsSync19, readFileSync as readFileSync14, writeFileSync as writeFileSync14 } from "fs";
|
|
3516
3558
|
import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
3517
3559
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3518
3560
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
@@ -3524,11 +3566,11 @@ var cachedLines;
|
|
|
3524
3566
|
function getCliReadsLines() {
|
|
3525
3567
|
if (cachedLines) return cachedLines;
|
|
3526
3568
|
const path50 = getCliReadsPath();
|
|
3527
|
-
if (!
|
|
3569
|
+
if (!existsSync19(path50)) {
|
|
3528
3570
|
cachedLines = [];
|
|
3529
3571
|
return cachedLines;
|
|
3530
3572
|
}
|
|
3531
|
-
cachedLines =
|
|
3573
|
+
cachedLines = readFileSync14(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
3532
3574
|
return cachedLines;
|
|
3533
3575
|
}
|
|
3534
3576
|
function loadCliReads() {
|
|
@@ -3553,7 +3595,7 @@ function findCliRead(command) {
|
|
|
3553
3595
|
}
|
|
3554
3596
|
|
|
3555
3597
|
// src/shared/matchesBashAllow.ts
|
|
3556
|
-
import { existsSync as
|
|
3598
|
+
import { existsSync as existsSync20, readFileSync as readFileSync15 } from "fs";
|
|
3557
3599
|
import { homedir as homedir3 } from "os";
|
|
3558
3600
|
import { join as join12 } from "path";
|
|
3559
3601
|
var cached;
|
|
@@ -3581,9 +3623,9 @@ function collectAllowEntries() {
|
|
|
3581
3623
|
return entries;
|
|
3582
3624
|
}
|
|
3583
3625
|
function readAllowArray(filePath) {
|
|
3584
|
-
if (!
|
|
3626
|
+
if (!existsSync20(filePath)) return [];
|
|
3585
3627
|
try {
|
|
3586
|
-
const data = JSON.parse(
|
|
3628
|
+
const data = JSON.parse(readFileSync15(filePath, "utf-8"));
|
|
3587
3629
|
const allow = data?.permissions?.allow;
|
|
3588
3630
|
return Array.isArray(allow) ? allow.filter((e) => typeof e === "string") : [];
|
|
3589
3631
|
} catch {
|
|
@@ -3733,7 +3775,7 @@ ${reasons.join("\n")}`);
|
|
|
3733
3775
|
}
|
|
3734
3776
|
|
|
3735
3777
|
// src/commands/permitCliReads/index.ts
|
|
3736
|
-
import { existsSync as
|
|
3778
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync4, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
|
|
3737
3779
|
import { homedir as homedir4 } from "os";
|
|
3738
3780
|
import { join as join13 } from "path";
|
|
3739
3781
|
|
|
@@ -3779,11 +3821,11 @@ function assertCliExists(cli) {
|
|
|
3779
3821
|
}
|
|
3780
3822
|
|
|
3781
3823
|
// src/commands/permitCliReads/colorize.ts
|
|
3782
|
-
import
|
|
3824
|
+
import chalk47 from "chalk";
|
|
3783
3825
|
function colorize(plainOutput) {
|
|
3784
3826
|
return plainOutput.split("\n").map((line) => {
|
|
3785
|
-
if (line.startsWith(" R ")) return
|
|
3786
|
-
if (line.startsWith(" W ")) return
|
|
3827
|
+
if (line.startsWith(" R ")) return chalk47.green(line);
|
|
3828
|
+
if (line.startsWith(" W ")) return chalk47.red(line);
|
|
3787
3829
|
return line;
|
|
3788
3830
|
}).join("\n");
|
|
3789
3831
|
}
|
|
@@ -4041,8 +4083,8 @@ function logPath(cli) {
|
|
|
4041
4083
|
}
|
|
4042
4084
|
function readCache(cli) {
|
|
4043
4085
|
const path50 = logPath(cli);
|
|
4044
|
-
if (!
|
|
4045
|
-
return
|
|
4086
|
+
if (!existsSync21(path50)) return void 0;
|
|
4087
|
+
return readFileSync16(path50, "utf-8");
|
|
4046
4088
|
}
|
|
4047
4089
|
function writeCache(cli, output) {
|
|
4048
4090
|
const dir = join13(homedir4(), ".assist");
|
|
@@ -4097,15 +4139,15 @@ function registerCliHook(program2) {
|
|
|
4097
4139
|
}
|
|
4098
4140
|
|
|
4099
4141
|
// src/commands/complexity/analyze.ts
|
|
4100
|
-
import
|
|
4142
|
+
import chalk53 from "chalk";
|
|
4101
4143
|
|
|
4102
4144
|
// src/commands/complexity/cyclomatic.ts
|
|
4103
|
-
import
|
|
4145
|
+
import chalk49 from "chalk";
|
|
4104
4146
|
|
|
4105
4147
|
// src/commands/complexity/shared/index.ts
|
|
4106
4148
|
import fs12 from "fs";
|
|
4107
4149
|
import path20 from "path";
|
|
4108
|
-
import
|
|
4150
|
+
import chalk48 from "chalk";
|
|
4109
4151
|
import ts5 from "typescript";
|
|
4110
4152
|
|
|
4111
4153
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4351,7 +4393,7 @@ function createSourceFromFile(filePath) {
|
|
|
4351
4393
|
function withSourceFiles(pattern2, callback) {
|
|
4352
4394
|
const files = findSourceFiles2(pattern2);
|
|
4353
4395
|
if (files.length === 0) {
|
|
4354
|
-
console.log(
|
|
4396
|
+
console.log(chalk48.yellow("No files found matching pattern"));
|
|
4355
4397
|
return void 0;
|
|
4356
4398
|
}
|
|
4357
4399
|
return callback(files);
|
|
@@ -4384,11 +4426,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4384
4426
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4385
4427
|
for (const { file, name, complexity } of results) {
|
|
4386
4428
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4387
|
-
const color = exceedsThreshold ?
|
|
4388
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4429
|
+
const color = exceedsThreshold ? chalk49.red : chalk49.white;
|
|
4430
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk49.cyan(complexity)}`);
|
|
4389
4431
|
}
|
|
4390
4432
|
console.log(
|
|
4391
|
-
|
|
4433
|
+
chalk49.dim(
|
|
4392
4434
|
`
|
|
4393
4435
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4394
4436
|
)
|
|
@@ -4400,7 +4442,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4400
4442
|
}
|
|
4401
4443
|
|
|
4402
4444
|
// src/commands/complexity/halstead.ts
|
|
4403
|
-
import
|
|
4445
|
+
import chalk50 from "chalk";
|
|
4404
4446
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4405
4447
|
withSourceFiles(pattern2, (files) => {
|
|
4406
4448
|
const results = [];
|
|
@@ -4415,13 +4457,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4415
4457
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4416
4458
|
for (const { file, name, metrics } of results) {
|
|
4417
4459
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4418
|
-
const color = exceedsThreshold ?
|
|
4460
|
+
const color = exceedsThreshold ? chalk50.red : chalk50.white;
|
|
4419
4461
|
console.log(
|
|
4420
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4462
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk50.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk50.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk50.magenta(metrics.effort.toFixed(1))}`
|
|
4421
4463
|
);
|
|
4422
4464
|
}
|
|
4423
4465
|
console.log(
|
|
4424
|
-
|
|
4466
|
+
chalk50.dim(
|
|
4425
4467
|
`
|
|
4426
4468
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4427
4469
|
)
|
|
@@ -4436,28 +4478,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4436
4478
|
import fs13 from "fs";
|
|
4437
4479
|
|
|
4438
4480
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4439
|
-
import
|
|
4481
|
+
import chalk51 from "chalk";
|
|
4440
4482
|
function displayMaintainabilityResults(results, threshold) {
|
|
4441
4483
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4442
4484
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4443
|
-
console.log(
|
|
4485
|
+
console.log(chalk51.green("All files pass maintainability threshold"));
|
|
4444
4486
|
} else {
|
|
4445
4487
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4446
|
-
const color = threshold !== void 0 ?
|
|
4488
|
+
const color = threshold !== void 0 ? chalk51.red : chalk51.white;
|
|
4447
4489
|
console.log(
|
|
4448
|
-
`${color(file)} \u2192 avg: ${
|
|
4490
|
+
`${color(file)} \u2192 avg: ${chalk51.cyan(avgMaintainability.toFixed(1))}, min: ${chalk51.yellow(minMaintainability.toFixed(1))}`
|
|
4449
4491
|
);
|
|
4450
4492
|
}
|
|
4451
4493
|
}
|
|
4452
|
-
console.log(
|
|
4494
|
+
console.log(chalk51.dim(`
|
|
4453
4495
|
Analyzed ${results.length} files`));
|
|
4454
4496
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4455
4497
|
console.error(
|
|
4456
|
-
|
|
4498
|
+
chalk51.red(
|
|
4457
4499
|
`
|
|
4458
4500
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4459
4501
|
|
|
4460
|
-
\u26A0\uFE0F ${
|
|
4502
|
+
\u26A0\uFE0F ${chalk51.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.`
|
|
4461
4503
|
)
|
|
4462
4504
|
);
|
|
4463
4505
|
process.exit(1);
|
|
@@ -4514,7 +4556,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4514
4556
|
|
|
4515
4557
|
// src/commands/complexity/sloc.ts
|
|
4516
4558
|
import fs14 from "fs";
|
|
4517
|
-
import
|
|
4559
|
+
import chalk52 from "chalk";
|
|
4518
4560
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4519
4561
|
withSourceFiles(pattern2, (files) => {
|
|
4520
4562
|
const results = [];
|
|
@@ -4530,12 +4572,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4530
4572
|
results.sort((a, b) => b.lines - a.lines);
|
|
4531
4573
|
for (const { file, lines } of results) {
|
|
4532
4574
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4533
|
-
const color = exceedsThreshold ?
|
|
4534
|
-
console.log(`${color(file)} \u2192 ${
|
|
4575
|
+
const color = exceedsThreshold ? chalk52.red : chalk52.white;
|
|
4576
|
+
console.log(`${color(file)} \u2192 ${chalk52.cyan(lines)} lines`);
|
|
4535
4577
|
}
|
|
4536
4578
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4537
4579
|
console.log(
|
|
4538
|
-
|
|
4580
|
+
chalk52.dim(`
|
|
4539
4581
|
Total: ${total} lines across ${files.length} files`)
|
|
4540
4582
|
);
|
|
4541
4583
|
if (hasViolation) {
|
|
@@ -4549,21 +4591,21 @@ async function analyze(pattern2) {
|
|
|
4549
4591
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4550
4592
|
const files = findSourceFiles2(searchPattern);
|
|
4551
4593
|
if (files.length === 0) {
|
|
4552
|
-
console.log(
|
|
4594
|
+
console.log(chalk53.yellow("No files found matching pattern"));
|
|
4553
4595
|
return;
|
|
4554
4596
|
}
|
|
4555
4597
|
if (files.length === 1) {
|
|
4556
4598
|
const file = files[0];
|
|
4557
|
-
console.log(
|
|
4599
|
+
console.log(chalk53.bold.underline("SLOC"));
|
|
4558
4600
|
await sloc(file);
|
|
4559
4601
|
console.log();
|
|
4560
|
-
console.log(
|
|
4602
|
+
console.log(chalk53.bold.underline("Cyclomatic Complexity"));
|
|
4561
4603
|
await cyclomatic(file);
|
|
4562
4604
|
console.log();
|
|
4563
|
-
console.log(
|
|
4605
|
+
console.log(chalk53.bold.underline("Halstead Metrics"));
|
|
4564
4606
|
await halstead(file);
|
|
4565
4607
|
console.log();
|
|
4566
|
-
console.log(
|
|
4608
|
+
console.log(chalk53.bold.underline("Maintainability Index"));
|
|
4567
4609
|
await maintainability(file);
|
|
4568
4610
|
return;
|
|
4569
4611
|
}
|
|
@@ -4590,8 +4632,8 @@ function registerComplexity(program2) {
|
|
|
4590
4632
|
}
|
|
4591
4633
|
|
|
4592
4634
|
// src/commands/deploy/redirect.ts
|
|
4593
|
-
import { existsSync as
|
|
4594
|
-
import
|
|
4635
|
+
import { existsSync as existsSync22, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
|
|
4636
|
+
import chalk54 from "chalk";
|
|
4595
4637
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4596
4638
|
if (!window.location.pathname.endsWith('/')) {
|
|
4597
4639
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4599,23 +4641,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4599
4641
|
</script>`;
|
|
4600
4642
|
function redirect() {
|
|
4601
4643
|
const indexPath = "index.html";
|
|
4602
|
-
if (!
|
|
4603
|
-
console.log(
|
|
4644
|
+
if (!existsSync22(indexPath)) {
|
|
4645
|
+
console.log(chalk54.yellow("No index.html found"));
|
|
4604
4646
|
return;
|
|
4605
4647
|
}
|
|
4606
|
-
const content =
|
|
4648
|
+
const content = readFileSync17(indexPath, "utf-8");
|
|
4607
4649
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4608
|
-
console.log(
|
|
4650
|
+
console.log(chalk54.dim("Trailing slash script already present"));
|
|
4609
4651
|
return;
|
|
4610
4652
|
}
|
|
4611
4653
|
const headCloseIndex = content.indexOf("</head>");
|
|
4612
4654
|
if (headCloseIndex === -1) {
|
|
4613
|
-
console.log(
|
|
4655
|
+
console.log(chalk54.red("Could not find </head> tag in index.html"));
|
|
4614
4656
|
return;
|
|
4615
4657
|
}
|
|
4616
4658
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4617
4659
|
writeFileSync16(indexPath, newContent);
|
|
4618
|
-
console.log(
|
|
4660
|
+
console.log(chalk54.green("Added trailing slash redirect to index.html"));
|
|
4619
4661
|
}
|
|
4620
4662
|
|
|
4621
4663
|
// src/commands/registerDeploy.ts
|
|
@@ -4642,10 +4684,10 @@ function loadBlogSkipDays(repoName) {
|
|
|
4642
4684
|
|
|
4643
4685
|
// src/commands/devlog/shared.ts
|
|
4644
4686
|
import { execSync as execSync17 } from "child_process";
|
|
4645
|
-
import
|
|
4687
|
+
import chalk55 from "chalk";
|
|
4646
4688
|
|
|
4647
4689
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4648
|
-
import { readdirSync, readFileSync as
|
|
4690
|
+
import { readdirSync, readFileSync as readFileSync18 } from "fs";
|
|
4649
4691
|
import { join as join15 } from "path";
|
|
4650
4692
|
var DEVLOG_DIR = join15(BLOG_REPO_ROOT, "src/content/devlog");
|
|
4651
4693
|
function extractFrontmatter(content) {
|
|
@@ -4675,7 +4717,7 @@ function readDevlogFiles(callback) {
|
|
|
4675
4717
|
try {
|
|
4676
4718
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
4677
4719
|
for (const file of files) {
|
|
4678
|
-
const content =
|
|
4720
|
+
const content = readFileSync18(join15(DEVLOG_DIR, file), "utf-8");
|
|
4679
4721
|
const parsed = parseFrontmatter(content, file);
|
|
4680
4722
|
if (parsed) callback(parsed);
|
|
4681
4723
|
}
|
|
@@ -4729,13 +4771,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4729
4771
|
}
|
|
4730
4772
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4731
4773
|
for (const commit2 of commits) {
|
|
4732
|
-
console.log(` ${
|
|
4774
|
+
console.log(` ${chalk55.yellow(commit2.hash)} ${commit2.message}`);
|
|
4733
4775
|
if (verbose) {
|
|
4734
4776
|
const visibleFiles = commit2.files.filter(
|
|
4735
4777
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4736
4778
|
);
|
|
4737
4779
|
for (const file of visibleFiles) {
|
|
4738
|
-
console.log(` ${
|
|
4780
|
+
console.log(` ${chalk55.dim(file)}`);
|
|
4739
4781
|
}
|
|
4740
4782
|
}
|
|
4741
4783
|
}
|
|
@@ -4760,15 +4802,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4760
4802
|
}
|
|
4761
4803
|
|
|
4762
4804
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4763
|
-
import
|
|
4805
|
+
import chalk56 from "chalk";
|
|
4764
4806
|
function printDateHeader(date, isSkipped, entries) {
|
|
4765
4807
|
if (isSkipped) {
|
|
4766
|
-
console.log(`${
|
|
4808
|
+
console.log(`${chalk56.bold.blue(date)} ${chalk56.dim("skipped")}`);
|
|
4767
4809
|
} else if (entries && entries.length > 0) {
|
|
4768
|
-
const entryInfo = entries.map((e) => `${
|
|
4769
|
-
console.log(`${
|
|
4810
|
+
const entryInfo = entries.map((e) => `${chalk56.green(e.version)} ${e.title}`).join(" | ");
|
|
4811
|
+
console.log(`${chalk56.bold.blue(date)} ${entryInfo}`);
|
|
4770
4812
|
} else {
|
|
4771
|
-
console.log(`${
|
|
4813
|
+
console.log(`${chalk56.bold.blue(date)} ${chalk56.red("\u26A0 devlog missing")}`);
|
|
4772
4814
|
}
|
|
4773
4815
|
}
|
|
4774
4816
|
|
|
@@ -4871,24 +4913,24 @@ function bumpVersion(version2, type) {
|
|
|
4871
4913
|
|
|
4872
4914
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
4873
4915
|
import { execSync as execSync20 } from "child_process";
|
|
4874
|
-
import
|
|
4916
|
+
import chalk58 from "chalk";
|
|
4875
4917
|
|
|
4876
4918
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
4877
|
-
import
|
|
4919
|
+
import chalk57 from "chalk";
|
|
4878
4920
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
4879
4921
|
if (conventional && firstHash) {
|
|
4880
4922
|
const version2 = getVersionAtCommit(firstHash);
|
|
4881
4923
|
if (version2) {
|
|
4882
|
-
console.log(`${
|
|
4924
|
+
console.log(`${chalk57.bold("version:")} ${stripToMinor(version2)}`);
|
|
4883
4925
|
} else {
|
|
4884
|
-
console.log(`${
|
|
4926
|
+
console.log(`${chalk57.bold("version:")} ${chalk57.red("unknown")}`);
|
|
4885
4927
|
}
|
|
4886
4928
|
} else if (patchVersion && minorVersion) {
|
|
4887
4929
|
console.log(
|
|
4888
|
-
`${
|
|
4930
|
+
`${chalk57.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
4889
4931
|
);
|
|
4890
4932
|
} else {
|
|
4891
|
-
console.log(`${
|
|
4933
|
+
console.log(`${chalk57.bold("version:")} v0.1 (initial)`);
|
|
4892
4934
|
}
|
|
4893
4935
|
}
|
|
4894
4936
|
|
|
@@ -4935,16 +4977,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
4935
4977
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
4936
4978
|
}
|
|
4937
4979
|
function logName(repoName) {
|
|
4938
|
-
console.log(`${
|
|
4980
|
+
console.log(`${chalk58.bold("name:")} ${repoName}`);
|
|
4939
4981
|
}
|
|
4940
4982
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
4941
4983
|
logName(ctx.repoName);
|
|
4942
4984
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
4943
|
-
console.log(
|
|
4985
|
+
console.log(chalk58.bold.blue(targetDate));
|
|
4944
4986
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
4945
4987
|
}
|
|
4946
4988
|
function logNoCommits(lastInfo) {
|
|
4947
|
-
console.log(
|
|
4989
|
+
console.log(chalk58.dim(noCommitsMessage(!!lastInfo)));
|
|
4948
4990
|
}
|
|
4949
4991
|
|
|
4950
4992
|
// src/commands/devlog/next/index.ts
|
|
@@ -4985,11 +5027,11 @@ function next2(options2) {
|
|
|
4985
5027
|
import { execSync as execSync21 } from "child_process";
|
|
4986
5028
|
|
|
4987
5029
|
// src/commands/devlog/repos/printReposTable.ts
|
|
4988
|
-
import
|
|
5030
|
+
import chalk59 from "chalk";
|
|
4989
5031
|
function colorStatus(status2) {
|
|
4990
|
-
if (status2 === "missing") return
|
|
4991
|
-
if (status2 === "outdated") return
|
|
4992
|
-
return
|
|
5032
|
+
if (status2 === "missing") return chalk59.red(status2);
|
|
5033
|
+
if (status2 === "outdated") return chalk59.yellow(status2);
|
|
5034
|
+
return chalk59.green(status2);
|
|
4993
5035
|
}
|
|
4994
5036
|
function formatRow(row, nameWidth) {
|
|
4995
5037
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -5003,8 +5045,8 @@ function printReposTable(rows) {
|
|
|
5003
5045
|
"Last Devlog".padEnd(11),
|
|
5004
5046
|
"Status"
|
|
5005
5047
|
].join(" ");
|
|
5006
|
-
console.log(
|
|
5007
|
-
console.log(
|
|
5048
|
+
console.log(chalk59.dim(header));
|
|
5049
|
+
console.log(chalk59.dim("-".repeat(header.length)));
|
|
5008
5050
|
for (const row of rows) {
|
|
5009
5051
|
console.log(formatRow(row, nameWidth));
|
|
5010
5052
|
}
|
|
@@ -5062,14 +5104,14 @@ function repos(options2) {
|
|
|
5062
5104
|
// src/commands/devlog/skip.ts
|
|
5063
5105
|
import { writeFileSync as writeFileSync17 } from "fs";
|
|
5064
5106
|
import { join as join16 } from "path";
|
|
5065
|
-
import
|
|
5107
|
+
import chalk60 from "chalk";
|
|
5066
5108
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
5067
5109
|
function getBlogConfigPath() {
|
|
5068
5110
|
return join16(BLOG_REPO_ROOT, "assist.yml");
|
|
5069
5111
|
}
|
|
5070
5112
|
function skip(date) {
|
|
5071
5113
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5072
|
-
console.log(
|
|
5114
|
+
console.log(chalk60.red("Invalid date format. Use YYYY-MM-DD"));
|
|
5073
5115
|
process.exit(1);
|
|
5074
5116
|
}
|
|
5075
5117
|
const repoName = getRepoName();
|
|
@@ -5080,7 +5122,7 @@ function skip(date) {
|
|
|
5080
5122
|
const skipDays = skip2[repoName] ?? [];
|
|
5081
5123
|
if (skipDays.includes(date)) {
|
|
5082
5124
|
console.log(
|
|
5083
|
-
|
|
5125
|
+
chalk60.yellow(`${date} is already in skip list for ${repoName}`)
|
|
5084
5126
|
);
|
|
5085
5127
|
return;
|
|
5086
5128
|
}
|
|
@@ -5090,20 +5132,20 @@ function skip(date) {
|
|
|
5090
5132
|
devlog.skip = skip2;
|
|
5091
5133
|
config.devlog = devlog;
|
|
5092
5134
|
writeFileSync17(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
5093
|
-
console.log(
|
|
5135
|
+
console.log(chalk60.green(`Added ${date} to skip list for ${repoName}`));
|
|
5094
5136
|
}
|
|
5095
5137
|
|
|
5096
5138
|
// src/commands/devlog/version.ts
|
|
5097
|
-
import
|
|
5139
|
+
import chalk61 from "chalk";
|
|
5098
5140
|
function version() {
|
|
5099
5141
|
const config = loadConfig();
|
|
5100
5142
|
const name = getRepoName();
|
|
5101
5143
|
const lastInfo = getLastVersionInfo(name, config);
|
|
5102
5144
|
const lastVersion = lastInfo?.version ?? null;
|
|
5103
5145
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
5104
|
-
console.log(`${
|
|
5105
|
-
console.log(`${
|
|
5106
|
-
console.log(`${
|
|
5146
|
+
console.log(`${chalk61.bold("name:")} ${name}`);
|
|
5147
|
+
console.log(`${chalk61.bold("last:")} ${lastVersion ?? chalk61.dim("none")}`);
|
|
5148
|
+
console.log(`${chalk61.bold("next:")} ${nextVersion ?? chalk61.dim("none")}`);
|
|
5107
5149
|
}
|
|
5108
5150
|
|
|
5109
5151
|
// src/commands/registerDevlog.ts
|
|
@@ -5127,15 +5169,15 @@ function registerDevlog(program2) {
|
|
|
5127
5169
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5128
5170
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5129
5171
|
import { join as join17 } from "path";
|
|
5130
|
-
import
|
|
5172
|
+
import chalk62 from "chalk";
|
|
5131
5173
|
|
|
5132
5174
|
// src/shared/findRepoRoot.ts
|
|
5133
|
-
import { existsSync as
|
|
5175
|
+
import { existsSync as existsSync23 } from "fs";
|
|
5134
5176
|
import path21 from "path";
|
|
5135
5177
|
function findRepoRoot(dir) {
|
|
5136
5178
|
let current = dir;
|
|
5137
5179
|
while (current !== path21.dirname(current)) {
|
|
5138
|
-
if (
|
|
5180
|
+
if (existsSync23(path21.join(current, ".git"))) {
|
|
5139
5181
|
return current;
|
|
5140
5182
|
}
|
|
5141
5183
|
current = path21.dirname(current);
|
|
@@ -5190,22 +5232,22 @@ function checkBuildLocks(startDir) {
|
|
|
5190
5232
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5191
5233
|
if (locked) {
|
|
5192
5234
|
console.error(
|
|
5193
|
-
|
|
5235
|
+
chalk62.red("Build output locked (is VS debugging?): ") + locked
|
|
5194
5236
|
);
|
|
5195
5237
|
process.exit(1);
|
|
5196
5238
|
}
|
|
5197
5239
|
}
|
|
5198
5240
|
async function checkBuildLocksCommand() {
|
|
5199
5241
|
checkBuildLocks();
|
|
5200
|
-
console.log(
|
|
5242
|
+
console.log(chalk62.green("No build locks detected"));
|
|
5201
5243
|
}
|
|
5202
5244
|
|
|
5203
5245
|
// src/commands/dotnet/buildTree.ts
|
|
5204
|
-
import { readFileSync as
|
|
5246
|
+
import { readFileSync as readFileSync19 } from "fs";
|
|
5205
5247
|
import path22 from "path";
|
|
5206
5248
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
5207
5249
|
function getProjectRefs(csprojPath) {
|
|
5208
|
-
const content =
|
|
5250
|
+
const content = readFileSync19(csprojPath, "utf-8");
|
|
5209
5251
|
const refs = [];
|
|
5210
5252
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
5211
5253
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -5222,7 +5264,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
5222
5264
|
for (const ref of getProjectRefs(abs)) {
|
|
5223
5265
|
const childAbs = path22.resolve(dir, ref);
|
|
5224
5266
|
try {
|
|
5225
|
-
|
|
5267
|
+
readFileSync19(childAbs);
|
|
5226
5268
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
5227
5269
|
} catch {
|
|
5228
5270
|
node.children.push({
|
|
@@ -5247,7 +5289,7 @@ function collectAllDeps(node) {
|
|
|
5247
5289
|
}
|
|
5248
5290
|
|
|
5249
5291
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
5250
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
5292
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync20, statSync } from "fs";
|
|
5251
5293
|
import path23 from "path";
|
|
5252
5294
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
5253
5295
|
if (depth > maxDepth) return [];
|
|
@@ -5282,7 +5324,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
5282
5324
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
5283
5325
|
for (const sln of slnFiles) {
|
|
5284
5326
|
try {
|
|
5285
|
-
const content =
|
|
5327
|
+
const content = readFileSync20(sln, "utf-8");
|
|
5286
5328
|
if (pattern2.test(content)) {
|
|
5287
5329
|
matches.push(path23.relative(repoRoot, sln));
|
|
5288
5330
|
}
|
|
@@ -5296,30 +5338,30 @@ function escapeRegex(s) {
|
|
|
5296
5338
|
}
|
|
5297
5339
|
|
|
5298
5340
|
// src/commands/dotnet/printTree.ts
|
|
5299
|
-
import
|
|
5341
|
+
import chalk63 from "chalk";
|
|
5300
5342
|
function printNodes(nodes, prefix2) {
|
|
5301
5343
|
for (let i = 0; i < nodes.length; i++) {
|
|
5302
5344
|
const isLast = i === nodes.length - 1;
|
|
5303
5345
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5304
5346
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5305
5347
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5306
|
-
const label2 = isMissing ?
|
|
5348
|
+
const label2 = isMissing ? chalk63.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5307
5349
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5308
5350
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5309
5351
|
}
|
|
5310
5352
|
}
|
|
5311
5353
|
function printTree(tree, totalCount, solutions) {
|
|
5312
|
-
console.log(
|
|
5313
|
-
console.log(
|
|
5354
|
+
console.log(chalk63.bold("\nProject Dependency Tree"));
|
|
5355
|
+
console.log(chalk63.cyan(tree.relativePath));
|
|
5314
5356
|
printNodes(tree.children, "");
|
|
5315
|
-
console.log(
|
|
5357
|
+
console.log(chalk63.dim(`
|
|
5316
5358
|
${totalCount} projects total (including root)`));
|
|
5317
|
-
console.log(
|
|
5359
|
+
console.log(chalk63.bold("\nSolution Membership"));
|
|
5318
5360
|
if (solutions.length === 0) {
|
|
5319
|
-
console.log(
|
|
5361
|
+
console.log(chalk63.yellow(" Not found in any .sln"));
|
|
5320
5362
|
} else {
|
|
5321
5363
|
for (const sln of solutions) {
|
|
5322
|
-
console.log(` ${
|
|
5364
|
+
console.log(` ${chalk63.green(sln)}`);
|
|
5323
5365
|
}
|
|
5324
5366
|
}
|
|
5325
5367
|
console.log();
|
|
@@ -5346,18 +5388,18 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5346
5388
|
}
|
|
5347
5389
|
|
|
5348
5390
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5349
|
-
import { existsSync as
|
|
5391
|
+
import { existsSync as existsSync24 } from "fs";
|
|
5350
5392
|
import path24 from "path";
|
|
5351
|
-
import
|
|
5393
|
+
import chalk64 from "chalk";
|
|
5352
5394
|
function resolveCsproj(csprojPath) {
|
|
5353
5395
|
const resolved = path24.resolve(csprojPath);
|
|
5354
|
-
if (!
|
|
5355
|
-
console.error(
|
|
5396
|
+
if (!existsSync24(resolved)) {
|
|
5397
|
+
console.error(chalk64.red(`File not found: ${resolved}`));
|
|
5356
5398
|
process.exit(1);
|
|
5357
5399
|
}
|
|
5358
5400
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5359
5401
|
if (!repoRoot) {
|
|
5360
|
-
console.error(
|
|
5402
|
+
console.error(chalk64.red("Could not find git repository root"));
|
|
5361
5403
|
process.exit(1);
|
|
5362
5404
|
}
|
|
5363
5405
|
return { resolved, repoRoot };
|
|
@@ -5407,12 +5449,12 @@ function getChangedCsFiles(scope) {
|
|
|
5407
5449
|
}
|
|
5408
5450
|
|
|
5409
5451
|
// src/commands/dotnet/inSln.ts
|
|
5410
|
-
import
|
|
5452
|
+
import chalk65 from "chalk";
|
|
5411
5453
|
async function inSln(csprojPath) {
|
|
5412
5454
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5413
5455
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5414
5456
|
if (solutions.length === 0) {
|
|
5415
|
-
console.log(
|
|
5457
|
+
console.log(chalk65.yellow("Not found in any .sln file"));
|
|
5416
5458
|
process.exit(1);
|
|
5417
5459
|
}
|
|
5418
5460
|
for (const sln of solutions) {
|
|
@@ -5421,7 +5463,7 @@ async function inSln(csprojPath) {
|
|
|
5421
5463
|
}
|
|
5422
5464
|
|
|
5423
5465
|
// src/commands/dotnet/inspect.ts
|
|
5424
|
-
import
|
|
5466
|
+
import chalk71 from "chalk";
|
|
5425
5467
|
|
|
5426
5468
|
// src/shared/formatElapsed.ts
|
|
5427
5469
|
function formatElapsed(ms) {
|
|
@@ -5433,12 +5475,12 @@ function formatElapsed(ms) {
|
|
|
5433
5475
|
}
|
|
5434
5476
|
|
|
5435
5477
|
// src/commands/dotnet/displayIssues.ts
|
|
5436
|
-
import
|
|
5478
|
+
import chalk66 from "chalk";
|
|
5437
5479
|
var SEVERITY_COLOR = {
|
|
5438
|
-
ERROR:
|
|
5439
|
-
WARNING:
|
|
5440
|
-
SUGGESTION:
|
|
5441
|
-
HINT:
|
|
5480
|
+
ERROR: chalk66.red,
|
|
5481
|
+
WARNING: chalk66.yellow,
|
|
5482
|
+
SUGGESTION: chalk66.cyan,
|
|
5483
|
+
HINT: chalk66.dim
|
|
5442
5484
|
};
|
|
5443
5485
|
function groupByFile(issues) {
|
|
5444
5486
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5454,15 +5496,15 @@ function groupByFile(issues) {
|
|
|
5454
5496
|
}
|
|
5455
5497
|
function displayIssues(issues) {
|
|
5456
5498
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5457
|
-
console.log(
|
|
5499
|
+
console.log(chalk66.bold(file));
|
|
5458
5500
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5459
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5501
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk66.white;
|
|
5460
5502
|
console.log(
|
|
5461
|
-
` ${
|
|
5503
|
+
` ${chalk66.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5462
5504
|
);
|
|
5463
5505
|
}
|
|
5464
5506
|
}
|
|
5465
|
-
console.log(
|
|
5507
|
+
console.log(chalk66.dim(`
|
|
5466
5508
|
${issues.length} issue(s) found`));
|
|
5467
5509
|
}
|
|
5468
5510
|
|
|
@@ -5519,14 +5561,14 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5519
5561
|
}
|
|
5520
5562
|
|
|
5521
5563
|
// src/commands/dotnet/resolveSolution.ts
|
|
5522
|
-
import { existsSync as
|
|
5564
|
+
import { existsSync as existsSync25 } from "fs";
|
|
5523
5565
|
import path25 from "path";
|
|
5524
|
-
import
|
|
5566
|
+
import chalk68 from "chalk";
|
|
5525
5567
|
|
|
5526
5568
|
// src/commands/dotnet/findSolution.ts
|
|
5527
5569
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5528
5570
|
import { dirname as dirname16, join as join18 } from "path";
|
|
5529
|
-
import
|
|
5571
|
+
import chalk67 from "chalk";
|
|
5530
5572
|
function findSlnInDir(dir) {
|
|
5531
5573
|
try {
|
|
5532
5574
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join18(dir, f));
|
|
@@ -5542,17 +5584,17 @@ function findSolution() {
|
|
|
5542
5584
|
const slnFiles = findSlnInDir(current);
|
|
5543
5585
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5544
5586
|
if (slnFiles.length > 1) {
|
|
5545
|
-
console.error(
|
|
5587
|
+
console.error(chalk67.red(`Multiple .sln files found in ${current}:`));
|
|
5546
5588
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5547
5589
|
console.error(
|
|
5548
|
-
|
|
5590
|
+
chalk67.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5549
5591
|
);
|
|
5550
5592
|
process.exit(1);
|
|
5551
5593
|
}
|
|
5552
5594
|
if (current === ceiling) break;
|
|
5553
5595
|
current = dirname16(current);
|
|
5554
5596
|
}
|
|
5555
|
-
console.error(
|
|
5597
|
+
console.error(chalk67.red("No .sln file found between cwd and repo root"));
|
|
5556
5598
|
process.exit(1);
|
|
5557
5599
|
}
|
|
5558
5600
|
|
|
@@ -5560,8 +5602,8 @@ function findSolution() {
|
|
|
5560
5602
|
function resolveSolution(sln) {
|
|
5561
5603
|
if (sln) {
|
|
5562
5604
|
const resolved = path25.resolve(sln);
|
|
5563
|
-
if (!
|
|
5564
|
-
console.error(
|
|
5605
|
+
if (!existsSync25(resolved)) {
|
|
5606
|
+
console.error(chalk68.red(`Solution file not found: ${resolved}`));
|
|
5565
5607
|
process.exit(1);
|
|
5566
5608
|
}
|
|
5567
5609
|
return resolved;
|
|
@@ -5600,17 +5642,17 @@ function parseInspectReport(json) {
|
|
|
5600
5642
|
|
|
5601
5643
|
// src/commands/dotnet/runInspectCode.ts
|
|
5602
5644
|
import { execSync as execSync23 } from "child_process";
|
|
5603
|
-
import { existsSync as
|
|
5645
|
+
import { existsSync as existsSync26, readFileSync as readFileSync21, unlinkSync as unlinkSync4 } from "fs";
|
|
5604
5646
|
import { tmpdir as tmpdir2 } from "os";
|
|
5605
5647
|
import path26 from "path";
|
|
5606
|
-
import
|
|
5648
|
+
import chalk69 from "chalk";
|
|
5607
5649
|
function assertJbInstalled() {
|
|
5608
5650
|
try {
|
|
5609
5651
|
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5610
5652
|
} catch {
|
|
5611
|
-
console.error(
|
|
5653
|
+
console.error(chalk69.red("jb is not installed. Install with:"));
|
|
5612
5654
|
console.error(
|
|
5613
|
-
|
|
5655
|
+
chalk69.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5614
5656
|
);
|
|
5615
5657
|
process.exit(1);
|
|
5616
5658
|
}
|
|
@@ -5628,21 +5670,21 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5628
5670
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5629
5671
|
process.stderr.write(err.stderr);
|
|
5630
5672
|
}
|
|
5631
|
-
console.error(
|
|
5673
|
+
console.error(chalk69.red("jb inspectcode failed"));
|
|
5632
5674
|
process.exit(1);
|
|
5633
5675
|
}
|
|
5634
|
-
if (!
|
|
5635
|
-
console.error(
|
|
5676
|
+
if (!existsSync26(reportPath)) {
|
|
5677
|
+
console.error(chalk69.red("Report file not generated"));
|
|
5636
5678
|
process.exit(1);
|
|
5637
5679
|
}
|
|
5638
|
-
const xml =
|
|
5680
|
+
const xml = readFileSync21(reportPath, "utf-8");
|
|
5639
5681
|
unlinkSync4(reportPath);
|
|
5640
5682
|
return xml;
|
|
5641
5683
|
}
|
|
5642
5684
|
|
|
5643
5685
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5644
5686
|
import { execSync as execSync24 } from "child_process";
|
|
5645
|
-
import
|
|
5687
|
+
import chalk70 from "chalk";
|
|
5646
5688
|
function resolveMsbuildPath() {
|
|
5647
5689
|
const config = loadConfig();
|
|
5648
5690
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5653,9 +5695,9 @@ function assertMsbuildInstalled() {
|
|
|
5653
5695
|
try {
|
|
5654
5696
|
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5655
5697
|
} catch {
|
|
5656
|
-
console.error(
|
|
5698
|
+
console.error(chalk70.red(`msbuild not found at: ${msbuild}`));
|
|
5657
5699
|
console.error(
|
|
5658
|
-
|
|
5700
|
+
chalk70.yellow(
|
|
5659
5701
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5660
5702
|
)
|
|
5661
5703
|
);
|
|
@@ -5702,17 +5744,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5702
5744
|
// src/commands/dotnet/inspect.ts
|
|
5703
5745
|
function logScope(changedFiles) {
|
|
5704
5746
|
if (changedFiles === null) {
|
|
5705
|
-
console.log(
|
|
5747
|
+
console.log(chalk71.dim("Inspecting full solution..."));
|
|
5706
5748
|
} else {
|
|
5707
5749
|
console.log(
|
|
5708
|
-
|
|
5750
|
+
chalk71.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5709
5751
|
);
|
|
5710
5752
|
}
|
|
5711
5753
|
}
|
|
5712
5754
|
function reportResults(issues, elapsed) {
|
|
5713
5755
|
if (issues.length > 0) displayIssues(issues);
|
|
5714
|
-
else console.log(
|
|
5715
|
-
console.log(
|
|
5756
|
+
else console.log(chalk71.green("No issues found"));
|
|
5757
|
+
console.log(chalk71.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5716
5758
|
if (issues.length > 0) process.exit(1);
|
|
5717
5759
|
}
|
|
5718
5760
|
async function inspect(sln, options2) {
|
|
@@ -5723,7 +5765,7 @@ async function inspect(sln, options2) {
|
|
|
5723
5765
|
const scope = parseScope(options2.scope);
|
|
5724
5766
|
const changedFiles = getChangedCsFiles(scope);
|
|
5725
5767
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5726
|
-
console.log(
|
|
5768
|
+
console.log(chalk71.green("No changed .cs files found"));
|
|
5727
5769
|
return;
|
|
5728
5770
|
}
|
|
5729
5771
|
logScope(changedFiles);
|
|
@@ -5749,7 +5791,7 @@ function registerDotnet(program2) {
|
|
|
5749
5791
|
}
|
|
5750
5792
|
|
|
5751
5793
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5752
|
-
import
|
|
5794
|
+
import chalk73 from "chalk";
|
|
5753
5795
|
|
|
5754
5796
|
// src/commands/jira/adfToText.ts
|
|
5755
5797
|
function renderInline(node) {
|
|
@@ -5810,7 +5852,7 @@ function adfToText(doc) {
|
|
|
5810
5852
|
|
|
5811
5853
|
// src/commands/jira/fetchIssue.ts
|
|
5812
5854
|
import { execSync as execSync25 } from "child_process";
|
|
5813
|
-
import
|
|
5855
|
+
import chalk72 from "chalk";
|
|
5814
5856
|
function fetchIssue(issueKey, fields) {
|
|
5815
5857
|
let result;
|
|
5816
5858
|
try {
|
|
@@ -5823,15 +5865,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
5823
5865
|
const stderr = error.stderr;
|
|
5824
5866
|
if (stderr.includes("unauthorized")) {
|
|
5825
5867
|
console.error(
|
|
5826
|
-
|
|
5868
|
+
chalk72.red("Jira authentication expired."),
|
|
5827
5869
|
"Run",
|
|
5828
|
-
|
|
5870
|
+
chalk72.cyan("assist jira auth"),
|
|
5829
5871
|
"to re-authenticate."
|
|
5830
5872
|
);
|
|
5831
5873
|
process.exit(1);
|
|
5832
5874
|
}
|
|
5833
5875
|
}
|
|
5834
|
-
console.error(
|
|
5876
|
+
console.error(chalk72.red(`Failed to fetch ${issueKey}.`));
|
|
5835
5877
|
process.exit(1);
|
|
5836
5878
|
}
|
|
5837
5879
|
return JSON.parse(result);
|
|
@@ -5845,7 +5887,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5845
5887
|
const parsed = fetchIssue(issueKey, field);
|
|
5846
5888
|
const acValue = parsed?.fields?.[field];
|
|
5847
5889
|
if (!acValue) {
|
|
5848
|
-
console.log(
|
|
5890
|
+
console.log(chalk73.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
5849
5891
|
return;
|
|
5850
5892
|
}
|
|
5851
5893
|
if (typeof acValue === "string") {
|
|
@@ -5863,7 +5905,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5863
5905
|
import { execSync as execSync26 } from "child_process";
|
|
5864
5906
|
|
|
5865
5907
|
// src/shared/loadJson.ts
|
|
5866
|
-
import { existsSync as
|
|
5908
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync5, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "fs";
|
|
5867
5909
|
import { homedir as homedir6 } from "os";
|
|
5868
5910
|
import { join as join19 } from "path";
|
|
5869
5911
|
function getStoreDir() {
|
|
@@ -5874,9 +5916,9 @@ function getStorePath(filename) {
|
|
|
5874
5916
|
}
|
|
5875
5917
|
function loadJson(filename) {
|
|
5876
5918
|
const path50 = getStorePath(filename);
|
|
5877
|
-
if (
|
|
5919
|
+
if (existsSync27(path50)) {
|
|
5878
5920
|
try {
|
|
5879
|
-
return JSON.parse(
|
|
5921
|
+
return JSON.parse(readFileSync22(path50, "utf-8"));
|
|
5880
5922
|
} catch {
|
|
5881
5923
|
return {};
|
|
5882
5924
|
}
|
|
@@ -5885,7 +5927,7 @@ function loadJson(filename) {
|
|
|
5885
5927
|
}
|
|
5886
5928
|
function saveJson(filename, data) {
|
|
5887
5929
|
const dir = getStoreDir();
|
|
5888
|
-
if (!
|
|
5930
|
+
if (!existsSync27(dir)) {
|
|
5889
5931
|
mkdirSync5(dir, { recursive: true });
|
|
5890
5932
|
}
|
|
5891
5933
|
writeFileSync18(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
@@ -5940,14 +5982,14 @@ async function jiraAuth() {
|
|
|
5940
5982
|
}
|
|
5941
5983
|
|
|
5942
5984
|
// src/commands/jira/viewIssue.ts
|
|
5943
|
-
import
|
|
5985
|
+
import chalk74 from "chalk";
|
|
5944
5986
|
function viewIssue(issueKey) {
|
|
5945
5987
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
5946
5988
|
const fields = parsed?.fields;
|
|
5947
5989
|
const summary = fields?.summary;
|
|
5948
5990
|
const description = fields?.description;
|
|
5949
5991
|
if (summary) {
|
|
5950
|
-
console.log(
|
|
5992
|
+
console.log(chalk74.bold(summary));
|
|
5951
5993
|
}
|
|
5952
5994
|
if (description) {
|
|
5953
5995
|
if (summary) console.log();
|
|
@@ -5961,7 +6003,7 @@ function viewIssue(issueKey) {
|
|
|
5961
6003
|
}
|
|
5962
6004
|
if (!summary && !description) {
|
|
5963
6005
|
console.log(
|
|
5964
|
-
|
|
6006
|
+
chalk74.yellow(`No summary or description found on ${issueKey}.`)
|
|
5965
6007
|
);
|
|
5966
6008
|
}
|
|
5967
6009
|
}
|
|
@@ -5975,7 +6017,7 @@ function registerJira(program2) {
|
|
|
5975
6017
|
}
|
|
5976
6018
|
|
|
5977
6019
|
// src/commands/news/add/index.ts
|
|
5978
|
-
import
|
|
6020
|
+
import chalk75 from "chalk";
|
|
5979
6021
|
import enquirer7 from "enquirer";
|
|
5980
6022
|
async function add2(url) {
|
|
5981
6023
|
if (!url) {
|
|
@@ -5998,17 +6040,17 @@ async function add2(url) {
|
|
|
5998
6040
|
const news = config.news ?? {};
|
|
5999
6041
|
const feeds = news.feeds ?? [];
|
|
6000
6042
|
if (feeds.includes(url)) {
|
|
6001
|
-
console.log(
|
|
6043
|
+
console.log(chalk75.yellow("Feed already exists in config"));
|
|
6002
6044
|
return;
|
|
6003
6045
|
}
|
|
6004
6046
|
feeds.push(url);
|
|
6005
6047
|
config.news = { ...news, feeds };
|
|
6006
6048
|
saveGlobalConfig(config);
|
|
6007
|
-
console.log(
|
|
6049
|
+
console.log(chalk75.green(`Added feed: ${url}`));
|
|
6008
6050
|
}
|
|
6009
6051
|
|
|
6010
6052
|
// src/commands/news/web/handleRequest.ts
|
|
6011
|
-
import
|
|
6053
|
+
import chalk76 from "chalk";
|
|
6012
6054
|
|
|
6013
6055
|
// src/commands/news/web/shared.ts
|
|
6014
6056
|
import { decodeHTML } from "entities";
|
|
@@ -6144,17 +6186,17 @@ function prefetch() {
|
|
|
6144
6186
|
const config = loadConfig();
|
|
6145
6187
|
const total = config.news.feeds.length;
|
|
6146
6188
|
if (total === 0) return;
|
|
6147
|
-
process.stdout.write(
|
|
6189
|
+
process.stdout.write(chalk76.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6148
6190
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6149
6191
|
const width = 20;
|
|
6150
6192
|
const filled = Math.round(done2 / t * width);
|
|
6151
6193
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6152
6194
|
process.stdout.write(
|
|
6153
|
-
`\r${
|
|
6195
|
+
`\r${chalk76.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6154
6196
|
);
|
|
6155
6197
|
}).then((items) => {
|
|
6156
6198
|
process.stdout.write(
|
|
6157
|
-
`\r${
|
|
6199
|
+
`\r${chalk76.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6158
6200
|
`
|
|
6159
6201
|
);
|
|
6160
6202
|
cachedItems = items;
|
|
@@ -6322,7 +6364,7 @@ import { tmpdir as tmpdir4 } from "os";
|
|
|
6322
6364
|
import { join as join22 } from "path";
|
|
6323
6365
|
|
|
6324
6366
|
// src/commands/prs/loadCommentsCache.ts
|
|
6325
|
-
import { existsSync as
|
|
6367
|
+
import { existsSync as existsSync28, readFileSync as readFileSync23, unlinkSync as unlinkSync6 } from "fs";
|
|
6326
6368
|
import { join as join21 } from "path";
|
|
6327
6369
|
import { parse as parse2 } from "yaml";
|
|
6328
6370
|
function getCachePath(prNumber) {
|
|
@@ -6330,15 +6372,15 @@ function getCachePath(prNumber) {
|
|
|
6330
6372
|
}
|
|
6331
6373
|
function loadCommentsCache(prNumber) {
|
|
6332
6374
|
const cachePath = getCachePath(prNumber);
|
|
6333
|
-
if (!
|
|
6375
|
+
if (!existsSync28(cachePath)) {
|
|
6334
6376
|
return null;
|
|
6335
6377
|
}
|
|
6336
|
-
const content =
|
|
6378
|
+
const content = readFileSync23(cachePath, "utf-8");
|
|
6337
6379
|
return parse2(content);
|
|
6338
6380
|
}
|
|
6339
6381
|
function deleteCommentsCache(prNumber) {
|
|
6340
6382
|
const cachePath = getCachePath(prNumber);
|
|
6341
|
-
if (
|
|
6383
|
+
if (existsSync28(cachePath)) {
|
|
6342
6384
|
unlinkSync6(cachePath);
|
|
6343
6385
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
6344
6386
|
}
|
|
@@ -6435,7 +6477,7 @@ function fixed(commentId, sha) {
|
|
|
6435
6477
|
}
|
|
6436
6478
|
|
|
6437
6479
|
// src/commands/prs/listComments/index.ts
|
|
6438
|
-
import { existsSync as
|
|
6480
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync6, writeFileSync as writeFileSync22 } from "fs";
|
|
6439
6481
|
import { join as join24 } from "path";
|
|
6440
6482
|
import { stringify } from "yaml";
|
|
6441
6483
|
|
|
@@ -6515,20 +6557,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6515
6557
|
}
|
|
6516
6558
|
|
|
6517
6559
|
// src/commands/prs/listComments/printComments.ts
|
|
6518
|
-
import
|
|
6560
|
+
import chalk77 from "chalk";
|
|
6519
6561
|
function formatForHuman(comment3) {
|
|
6520
6562
|
if (comment3.type === "review") {
|
|
6521
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
6563
|
+
const stateColor = comment3.state === "APPROVED" ? chalk77.green : comment3.state === "CHANGES_REQUESTED" ? chalk77.red : chalk77.yellow;
|
|
6522
6564
|
return [
|
|
6523
|
-
`${
|
|
6565
|
+
`${chalk77.cyan("Review")} by ${chalk77.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
6524
6566
|
comment3.body,
|
|
6525
6567
|
""
|
|
6526
6568
|
].join("\n");
|
|
6527
6569
|
}
|
|
6528
6570
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
6529
6571
|
return [
|
|
6530
|
-
`${
|
|
6531
|
-
|
|
6572
|
+
`${chalk77.cyan("Line comment")} by ${chalk77.bold(comment3.user)} on ${chalk77.dim(`${comment3.path}${location}`)}`,
|
|
6573
|
+
chalk77.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6532
6574
|
comment3.body,
|
|
6533
6575
|
""
|
|
6534
6576
|
].join("\n");
|
|
@@ -6561,7 +6603,7 @@ function printComments2(result) {
|
|
|
6561
6603
|
// src/commands/prs/listComments/index.ts
|
|
6562
6604
|
function writeCommentsCache(prNumber, comments2) {
|
|
6563
6605
|
const assistDir = join24(process.cwd(), ".assist");
|
|
6564
|
-
if (!
|
|
6606
|
+
if (!existsSync29(assistDir)) {
|
|
6565
6607
|
mkdirSync6(assistDir, { recursive: true });
|
|
6566
6608
|
}
|
|
6567
6609
|
const cacheData = {
|
|
@@ -6618,13 +6660,13 @@ import { execSync as execSync32 } from "child_process";
|
|
|
6618
6660
|
import enquirer8 from "enquirer";
|
|
6619
6661
|
|
|
6620
6662
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6621
|
-
import
|
|
6663
|
+
import chalk78 from "chalk";
|
|
6622
6664
|
var STATUS_MAP = {
|
|
6623
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6624
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6665
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk78.magenta("merged"), date: pr.mergedAt } : null,
|
|
6666
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk78.red("closed"), date: pr.closedAt } : null
|
|
6625
6667
|
};
|
|
6626
6668
|
function defaultStatus(pr) {
|
|
6627
|
-
return { label:
|
|
6669
|
+
return { label: chalk78.green("opened"), date: pr.createdAt };
|
|
6628
6670
|
}
|
|
6629
6671
|
function getStatus2(pr) {
|
|
6630
6672
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6633,11 +6675,11 @@ function formatDate(dateStr) {
|
|
|
6633
6675
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6634
6676
|
}
|
|
6635
6677
|
function formatPrHeader(pr, status2) {
|
|
6636
|
-
return `${
|
|
6678
|
+
return `${chalk78.cyan(`#${pr.number}`)} ${pr.title} ${chalk78.dim(`(${pr.author.login},`)} ${status2.label} ${chalk78.dim(`${formatDate(status2.date)})`)}`;
|
|
6637
6679
|
}
|
|
6638
6680
|
function logPrDetails(pr) {
|
|
6639
6681
|
console.log(
|
|
6640
|
-
|
|
6682
|
+
chalk78.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6641
6683
|
);
|
|
6642
6684
|
console.log();
|
|
6643
6685
|
}
|
|
@@ -6803,10 +6845,10 @@ function registerPrs(program2) {
|
|
|
6803
6845
|
}
|
|
6804
6846
|
|
|
6805
6847
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6806
|
-
import
|
|
6848
|
+
import chalk84 from "chalk";
|
|
6807
6849
|
|
|
6808
6850
|
// src/shared/createConnectionAuth.ts
|
|
6809
|
-
import
|
|
6851
|
+
import chalk79 from "chalk";
|
|
6810
6852
|
function listConnections(connections, format2) {
|
|
6811
6853
|
if (connections.length === 0) {
|
|
6812
6854
|
console.log("No connections configured.");
|
|
@@ -6819,7 +6861,7 @@ function listConnections(connections, format2) {
|
|
|
6819
6861
|
function removeConnection(connections, name, save) {
|
|
6820
6862
|
const filtered = connections.filter((c) => c.name !== name);
|
|
6821
6863
|
if (filtered.length === connections.length) {
|
|
6822
|
-
console.error(
|
|
6864
|
+
console.error(chalk79.red(`Connection "${name}" not found.`));
|
|
6823
6865
|
process.exit(1);
|
|
6824
6866
|
}
|
|
6825
6867
|
save(filtered);
|
|
@@ -6865,15 +6907,15 @@ function saveConnections(connections) {
|
|
|
6865
6907
|
}
|
|
6866
6908
|
|
|
6867
6909
|
// src/commands/ravendb/promptConnection.ts
|
|
6868
|
-
import
|
|
6910
|
+
import chalk82 from "chalk";
|
|
6869
6911
|
|
|
6870
6912
|
// src/commands/ravendb/selectOpSecret.ts
|
|
6871
|
-
import
|
|
6913
|
+
import chalk81 from "chalk";
|
|
6872
6914
|
import Enquirer2 from "enquirer";
|
|
6873
6915
|
|
|
6874
6916
|
// src/commands/ravendb/searchItems.ts
|
|
6875
6917
|
import { execSync as execSync34 } from "child_process";
|
|
6876
|
-
import
|
|
6918
|
+
import chalk80 from "chalk";
|
|
6877
6919
|
function opExec(args) {
|
|
6878
6920
|
return execSync34(`op ${args}`, {
|
|
6879
6921
|
encoding: "utf-8",
|
|
@@ -6886,7 +6928,7 @@ function searchItems(search) {
|
|
|
6886
6928
|
items = JSON.parse(opExec("item list --format=json"));
|
|
6887
6929
|
} catch {
|
|
6888
6930
|
console.error(
|
|
6889
|
-
|
|
6931
|
+
chalk80.red(
|
|
6890
6932
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
6891
6933
|
)
|
|
6892
6934
|
);
|
|
@@ -6900,7 +6942,7 @@ function getItemFields(itemId) {
|
|
|
6900
6942
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
6901
6943
|
return item.fields.filter((f) => f.reference && f.label);
|
|
6902
6944
|
} catch {
|
|
6903
|
-
console.error(
|
|
6945
|
+
console.error(chalk80.red("Failed to get item details from 1Password."));
|
|
6904
6946
|
process.exit(1);
|
|
6905
6947
|
}
|
|
6906
6948
|
}
|
|
@@ -6919,7 +6961,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6919
6961
|
}).run();
|
|
6920
6962
|
const items = searchItems(search);
|
|
6921
6963
|
if (items.length === 0) {
|
|
6922
|
-
console.error(
|
|
6964
|
+
console.error(chalk81.red(`No items found matching "${search}".`));
|
|
6923
6965
|
process.exit(1);
|
|
6924
6966
|
}
|
|
6925
6967
|
const itemId = await selectOne(
|
|
@@ -6928,7 +6970,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6928
6970
|
);
|
|
6929
6971
|
const fields = getItemFields(itemId);
|
|
6930
6972
|
if (fields.length === 0) {
|
|
6931
|
-
console.error(
|
|
6973
|
+
console.error(chalk81.red("No fields with references found on this item."));
|
|
6932
6974
|
process.exit(1);
|
|
6933
6975
|
}
|
|
6934
6976
|
const ref = await selectOne(
|
|
@@ -6942,7 +6984,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6942
6984
|
async function promptConnection(existingNames) {
|
|
6943
6985
|
const name = await promptInput("name", "Connection name:");
|
|
6944
6986
|
if (existingNames.includes(name)) {
|
|
6945
|
-
console.error(
|
|
6987
|
+
console.error(chalk82.red(`Connection "${name}" already exists.`));
|
|
6946
6988
|
process.exit(1);
|
|
6947
6989
|
}
|
|
6948
6990
|
const url = await promptInput(
|
|
@@ -6951,22 +6993,22 @@ async function promptConnection(existingNames) {
|
|
|
6951
6993
|
);
|
|
6952
6994
|
const database = await promptInput("database", "Database name:");
|
|
6953
6995
|
if (!name || !url || !database) {
|
|
6954
|
-
console.error(
|
|
6996
|
+
console.error(chalk82.red("All fields are required."));
|
|
6955
6997
|
process.exit(1);
|
|
6956
6998
|
}
|
|
6957
6999
|
const apiKeyRef = await selectOpSecret();
|
|
6958
|
-
console.log(
|
|
7000
|
+
console.log(chalk82.dim(`Using: ${apiKeyRef}`));
|
|
6959
7001
|
return { name, url, database, apiKeyRef };
|
|
6960
7002
|
}
|
|
6961
7003
|
|
|
6962
7004
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
6963
|
-
import
|
|
7005
|
+
import chalk83 from "chalk";
|
|
6964
7006
|
function ravendbSetConnection(name) {
|
|
6965
7007
|
const raw = loadGlobalConfigRaw();
|
|
6966
7008
|
const ravendb = raw.ravendb ?? {};
|
|
6967
7009
|
const connections = ravendb.connections ?? [];
|
|
6968
7010
|
if (!connections.some((c) => c.name === name)) {
|
|
6969
|
-
console.error(
|
|
7011
|
+
console.error(chalk83.red(`Connection "${name}" not found.`));
|
|
6970
7012
|
console.error(
|
|
6971
7013
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6972
7014
|
);
|
|
@@ -6982,16 +7024,16 @@ function ravendbSetConnection(name) {
|
|
|
6982
7024
|
var ravendbAuth = createConnectionAuth({
|
|
6983
7025
|
load: loadConnections,
|
|
6984
7026
|
save: saveConnections,
|
|
6985
|
-
format: (c) => `${
|
|
7027
|
+
format: (c) => `${chalk84.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
6986
7028
|
promptNew: promptConnection,
|
|
6987
7029
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
6988
7030
|
});
|
|
6989
7031
|
|
|
6990
7032
|
// src/commands/ravendb/ravendbCollections.ts
|
|
6991
|
-
import
|
|
7033
|
+
import chalk88 from "chalk";
|
|
6992
7034
|
|
|
6993
7035
|
// src/commands/ravendb/ravenFetch.ts
|
|
6994
|
-
import
|
|
7036
|
+
import chalk86 from "chalk";
|
|
6995
7037
|
|
|
6996
7038
|
// src/commands/ravendb/getAccessToken.ts
|
|
6997
7039
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -7028,10 +7070,10 @@ ${errorText}`
|
|
|
7028
7070
|
|
|
7029
7071
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
7030
7072
|
import { execSync as execSync35 } from "child_process";
|
|
7031
|
-
import
|
|
7073
|
+
import chalk85 from "chalk";
|
|
7032
7074
|
function resolveOpSecret(reference) {
|
|
7033
7075
|
if (!reference.startsWith("op://")) {
|
|
7034
|
-
console.error(
|
|
7076
|
+
console.error(chalk85.red(`Invalid secret reference: must start with op://`));
|
|
7035
7077
|
process.exit(1);
|
|
7036
7078
|
}
|
|
7037
7079
|
try {
|
|
@@ -7041,7 +7083,7 @@ function resolveOpSecret(reference) {
|
|
|
7041
7083
|
}).trim();
|
|
7042
7084
|
} catch {
|
|
7043
7085
|
console.error(
|
|
7044
|
-
|
|
7086
|
+
chalk85.red(
|
|
7045
7087
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
7046
7088
|
)
|
|
7047
7089
|
);
|
|
@@ -7068,7 +7110,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7068
7110
|
if (!response.ok) {
|
|
7069
7111
|
const body = await response.text();
|
|
7070
7112
|
console.error(
|
|
7071
|
-
|
|
7113
|
+
chalk86.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
7072
7114
|
);
|
|
7073
7115
|
console.error(body.substring(0, 500));
|
|
7074
7116
|
process.exit(1);
|
|
@@ -7077,7 +7119,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7077
7119
|
}
|
|
7078
7120
|
|
|
7079
7121
|
// src/commands/ravendb/resolveConnection.ts
|
|
7080
|
-
import
|
|
7122
|
+
import chalk87 from "chalk";
|
|
7081
7123
|
function loadRavendb() {
|
|
7082
7124
|
const raw = loadGlobalConfigRaw();
|
|
7083
7125
|
const ravendb = raw.ravendb;
|
|
@@ -7091,7 +7133,7 @@ function resolveConnection(name) {
|
|
|
7091
7133
|
const connectionName = name ?? defaultConnection;
|
|
7092
7134
|
if (!connectionName) {
|
|
7093
7135
|
console.error(
|
|
7094
|
-
|
|
7136
|
+
chalk87.red(
|
|
7095
7137
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
7096
7138
|
)
|
|
7097
7139
|
);
|
|
@@ -7099,7 +7141,7 @@ function resolveConnection(name) {
|
|
|
7099
7141
|
}
|
|
7100
7142
|
const connection = connections.find((c) => c.name === connectionName);
|
|
7101
7143
|
if (!connection) {
|
|
7102
|
-
console.error(
|
|
7144
|
+
console.error(chalk87.red(`Connection "${connectionName}" not found.`));
|
|
7103
7145
|
console.error(
|
|
7104
7146
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7105
7147
|
);
|
|
@@ -7130,15 +7172,15 @@ async function ravendbCollections(connectionName) {
|
|
|
7130
7172
|
return;
|
|
7131
7173
|
}
|
|
7132
7174
|
for (const c of collections) {
|
|
7133
|
-
console.log(`${
|
|
7175
|
+
console.log(`${chalk88.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
7134
7176
|
}
|
|
7135
7177
|
}
|
|
7136
7178
|
|
|
7137
7179
|
// src/commands/ravendb/ravendbQuery.ts
|
|
7138
|
-
import
|
|
7180
|
+
import chalk90 from "chalk";
|
|
7139
7181
|
|
|
7140
7182
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7141
|
-
import
|
|
7183
|
+
import chalk89 from "chalk";
|
|
7142
7184
|
|
|
7143
7185
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7144
7186
|
function buildQueryPath(opts) {
|
|
@@ -7176,7 +7218,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7176
7218
|
allResults.push(...results);
|
|
7177
7219
|
start3 += results.length;
|
|
7178
7220
|
process.stderr.write(
|
|
7179
|
-
`\r${
|
|
7221
|
+
`\r${chalk89.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7180
7222
|
);
|
|
7181
7223
|
if (start3 >= totalResults) break;
|
|
7182
7224
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7191,7 +7233,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7191
7233
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7192
7234
|
const resolved = resolveArgs(connectionName, collection);
|
|
7193
7235
|
if (!resolved.collection && !options2.query) {
|
|
7194
|
-
console.error(
|
|
7236
|
+
console.error(chalk90.red("Provide a collection name or --query filter."));
|
|
7195
7237
|
process.exit(1);
|
|
7196
7238
|
}
|
|
7197
7239
|
const { collection: col } = resolved;
|
|
@@ -7229,7 +7271,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7229
7271
|
import * as path27 from "path";
|
|
7230
7272
|
|
|
7231
7273
|
// src/commands/refactor/logViolations.ts
|
|
7232
|
-
import
|
|
7274
|
+
import chalk91 from "chalk";
|
|
7233
7275
|
var DEFAULT_MAX_LINES = 100;
|
|
7234
7276
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7235
7277
|
if (violations.length === 0) {
|
|
@@ -7238,43 +7280,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7238
7280
|
}
|
|
7239
7281
|
return;
|
|
7240
7282
|
}
|
|
7241
|
-
console.error(
|
|
7283
|
+
console.error(chalk91.red(`
|
|
7242
7284
|
Refactor check failed:
|
|
7243
7285
|
`));
|
|
7244
|
-
console.error(
|
|
7286
|
+
console.error(chalk91.red(` The following files exceed ${maxLines} lines:
|
|
7245
7287
|
`));
|
|
7246
7288
|
for (const violation of violations) {
|
|
7247
|
-
console.error(
|
|
7289
|
+
console.error(chalk91.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7248
7290
|
}
|
|
7249
7291
|
console.error(
|
|
7250
|
-
|
|
7292
|
+
chalk91.yellow(
|
|
7251
7293
|
`
|
|
7252
7294
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7253
7295
|
way to refactor it, ignore it with:
|
|
7254
7296
|
`
|
|
7255
7297
|
)
|
|
7256
7298
|
);
|
|
7257
|
-
console.error(
|
|
7299
|
+
console.error(chalk91.gray(` assist refactor ignore <file>
|
|
7258
7300
|
`));
|
|
7259
7301
|
if (process.env.CLAUDECODE) {
|
|
7260
|
-
console.error(
|
|
7302
|
+
console.error(chalk91.cyan(`
|
|
7261
7303
|
## Extracting Code to New Files
|
|
7262
7304
|
`));
|
|
7263
7305
|
console.error(
|
|
7264
|
-
|
|
7306
|
+
chalk91.cyan(
|
|
7265
7307
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7266
7308
|
`
|
|
7267
7309
|
)
|
|
7268
7310
|
);
|
|
7269
7311
|
console.error(
|
|
7270
|
-
|
|
7312
|
+
chalk91.cyan(
|
|
7271
7313
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7272
7314
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7273
7315
|
`
|
|
7274
7316
|
)
|
|
7275
7317
|
);
|
|
7276
7318
|
console.error(
|
|
7277
|
-
|
|
7319
|
+
chalk91.cyan(
|
|
7278
7320
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7279
7321
|
domains, move it to a common/shared folder.
|
|
7280
7322
|
`
|
|
@@ -7430,7 +7472,7 @@ async function check(pattern2, options2) {
|
|
|
7430
7472
|
|
|
7431
7473
|
// src/commands/refactor/extract/index.ts
|
|
7432
7474
|
import path33 from "path";
|
|
7433
|
-
import
|
|
7475
|
+
import chalk94 from "chalk";
|
|
7434
7476
|
|
|
7435
7477
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7436
7478
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -7956,23 +7998,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
7956
7998
|
|
|
7957
7999
|
// src/commands/refactor/extract/displayPlan.ts
|
|
7958
8000
|
import path31 from "path";
|
|
7959
|
-
import
|
|
8001
|
+
import chalk92 from "chalk";
|
|
7960
8002
|
function section(title) {
|
|
7961
8003
|
return `
|
|
7962
|
-
${
|
|
8004
|
+
${chalk92.cyan(title)}`;
|
|
7963
8005
|
}
|
|
7964
8006
|
function displayImporters(plan2, cwd) {
|
|
7965
8007
|
if (plan2.importersToUpdate.length === 0) return;
|
|
7966
8008
|
console.log(section("Update importers:"));
|
|
7967
8009
|
for (const imp of plan2.importersToUpdate) {
|
|
7968
8010
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
7969
|
-
console.log(` ${
|
|
8011
|
+
console.log(` ${chalk92.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
7970
8012
|
}
|
|
7971
8013
|
}
|
|
7972
8014
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
7973
|
-
console.log(
|
|
8015
|
+
console.log(chalk92.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
7974
8016
|
`));
|
|
7975
|
-
console.log(` ${
|
|
8017
|
+
console.log(` ${chalk92.cyan("Functions to move:")}`);
|
|
7976
8018
|
for (const name of plan2.extractedNames) {
|
|
7977
8019
|
console.log(` ${name}`);
|
|
7978
8020
|
}
|
|
@@ -8007,7 +8049,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
8007
8049
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
8008
8050
|
import fs17 from "fs";
|
|
8009
8051
|
import path32 from "path";
|
|
8010
|
-
import
|
|
8052
|
+
import chalk93 from "chalk";
|
|
8011
8053
|
import { Project as Project2 } from "ts-morph";
|
|
8012
8054
|
function findTsConfig(sourcePath) {
|
|
8013
8055
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -8038,7 +8080,7 @@ function loadProjectFile(file) {
|
|
|
8038
8080
|
});
|
|
8039
8081
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
8040
8082
|
if (!sourceFile) {
|
|
8041
|
-
console.log(
|
|
8083
|
+
console.log(chalk93.red(`File not found in project: ${file}`));
|
|
8042
8084
|
process.exit(1);
|
|
8043
8085
|
}
|
|
8044
8086
|
return { project, sourceFile };
|
|
@@ -8061,19 +8103,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
8061
8103
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
8062
8104
|
if (options2.apply) {
|
|
8063
8105
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
8064
|
-
console.log(
|
|
8106
|
+
console.log(chalk94.green("\nExtraction complete"));
|
|
8065
8107
|
} else {
|
|
8066
|
-
console.log(
|
|
8108
|
+
console.log(chalk94.dim("\nDry run. Use --apply to execute."));
|
|
8067
8109
|
}
|
|
8068
8110
|
}
|
|
8069
8111
|
|
|
8070
8112
|
// src/commands/refactor/ignore.ts
|
|
8071
8113
|
import fs18 from "fs";
|
|
8072
|
-
import
|
|
8114
|
+
import chalk95 from "chalk";
|
|
8073
8115
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
8074
8116
|
function ignore(file) {
|
|
8075
8117
|
if (!fs18.existsSync(file)) {
|
|
8076
|
-
console.error(
|
|
8118
|
+
console.error(chalk95.red(`Error: File does not exist: ${file}`));
|
|
8077
8119
|
process.exit(1);
|
|
8078
8120
|
}
|
|
8079
8121
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -8089,7 +8131,7 @@ function ignore(file) {
|
|
|
8089
8131
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
8090
8132
|
}
|
|
8091
8133
|
console.log(
|
|
8092
|
-
|
|
8134
|
+
chalk95.green(
|
|
8093
8135
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
8094
8136
|
)
|
|
8095
8137
|
);
|
|
@@ -8097,26 +8139,26 @@ function ignore(file) {
|
|
|
8097
8139
|
|
|
8098
8140
|
// src/commands/refactor/rename/index.ts
|
|
8099
8141
|
import path34 from "path";
|
|
8100
|
-
import
|
|
8142
|
+
import chalk96 from "chalk";
|
|
8101
8143
|
async function rename(source, destination, options2 = {}) {
|
|
8102
8144
|
const destPath = path34.resolve(destination);
|
|
8103
8145
|
const cwd = process.cwd();
|
|
8104
8146
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
8105
8147
|
const relDest = path34.relative(cwd, destPath);
|
|
8106
8148
|
const { project, sourceFile } = loadProjectFile(source);
|
|
8107
|
-
console.log(
|
|
8149
|
+
console.log(chalk96.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
8108
8150
|
if (options2.apply) {
|
|
8109
8151
|
sourceFile.move(destPath);
|
|
8110
8152
|
await project.save();
|
|
8111
|
-
console.log(
|
|
8153
|
+
console.log(chalk96.green("Done"));
|
|
8112
8154
|
} else {
|
|
8113
|
-
console.log(
|
|
8155
|
+
console.log(chalk96.dim("Dry run. Use --apply to execute."));
|
|
8114
8156
|
}
|
|
8115
8157
|
}
|
|
8116
8158
|
|
|
8117
8159
|
// src/commands/refactor/renameSymbol/index.ts
|
|
8118
8160
|
import path36 from "path";
|
|
8119
|
-
import
|
|
8161
|
+
import chalk97 from "chalk";
|
|
8120
8162
|
import { Project as Project3 } from "ts-morph";
|
|
8121
8163
|
|
|
8122
8164
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8165,38 +8207,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8165
8207
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8166
8208
|
const sourceFile = project.getSourceFile(filePath);
|
|
8167
8209
|
if (!sourceFile) {
|
|
8168
|
-
console.log(
|
|
8210
|
+
console.log(chalk97.red(`File not found in project: ${file}`));
|
|
8169
8211
|
process.exit(1);
|
|
8170
8212
|
}
|
|
8171
8213
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8172
8214
|
if (!symbol) {
|
|
8173
|
-
console.log(
|
|
8215
|
+
console.log(chalk97.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8174
8216
|
process.exit(1);
|
|
8175
8217
|
}
|
|
8176
8218
|
const grouped = groupReferences(symbol, cwd);
|
|
8177
8219
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8178
8220
|
console.log(
|
|
8179
|
-
|
|
8221
|
+
chalk97.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8180
8222
|
`)
|
|
8181
8223
|
);
|
|
8182
8224
|
for (const [refFile, lines] of grouped) {
|
|
8183
8225
|
console.log(
|
|
8184
|
-
` ${
|
|
8226
|
+
` ${chalk97.dim(refFile)}: lines ${chalk97.cyan(lines.join(", "))}`
|
|
8185
8227
|
);
|
|
8186
8228
|
}
|
|
8187
8229
|
if (options2.apply) {
|
|
8188
8230
|
symbol.rename(newName);
|
|
8189
8231
|
await project.save();
|
|
8190
|
-
console.log(
|
|
8232
|
+
console.log(chalk97.green(`
|
|
8191
8233
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8192
8234
|
} else {
|
|
8193
|
-
console.log(
|
|
8235
|
+
console.log(chalk97.dim("\nDry run. Use --apply to execute."));
|
|
8194
8236
|
}
|
|
8195
8237
|
}
|
|
8196
8238
|
|
|
8197
8239
|
// src/commands/refactor/restructure/index.ts
|
|
8198
8240
|
import path45 from "path";
|
|
8199
|
-
import
|
|
8241
|
+
import chalk100 from "chalk";
|
|
8200
8242
|
|
|
8201
8243
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8202
8244
|
import path37 from "path";
|
|
@@ -8439,50 +8481,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8439
8481
|
|
|
8440
8482
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8441
8483
|
import path41 from "path";
|
|
8442
|
-
import
|
|
8484
|
+
import chalk98 from "chalk";
|
|
8443
8485
|
function relPath(filePath) {
|
|
8444
8486
|
return path41.relative(process.cwd(), filePath);
|
|
8445
8487
|
}
|
|
8446
8488
|
function displayMoves(plan2) {
|
|
8447
8489
|
if (plan2.moves.length === 0) return;
|
|
8448
|
-
console.log(
|
|
8490
|
+
console.log(chalk98.bold("\nFile moves:"));
|
|
8449
8491
|
for (const move of plan2.moves) {
|
|
8450
8492
|
console.log(
|
|
8451
|
-
` ${
|
|
8493
|
+
` ${chalk98.red(relPath(move.from))} \u2192 ${chalk98.green(relPath(move.to))}`
|
|
8452
8494
|
);
|
|
8453
|
-
console.log(
|
|
8495
|
+
console.log(chalk98.dim(` ${move.reason}`));
|
|
8454
8496
|
}
|
|
8455
8497
|
}
|
|
8456
8498
|
function displayRewrites(rewrites) {
|
|
8457
8499
|
if (rewrites.length === 0) return;
|
|
8458
8500
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8459
|
-
console.log(
|
|
8501
|
+
console.log(chalk98.bold(`
|
|
8460
8502
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8461
8503
|
for (const file of affectedFiles) {
|
|
8462
|
-
console.log(` ${
|
|
8504
|
+
console.log(` ${chalk98.cyan(relPath(file))}:`);
|
|
8463
8505
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8464
8506
|
(r) => r.file === file
|
|
8465
8507
|
)) {
|
|
8466
8508
|
console.log(
|
|
8467
|
-
` ${
|
|
8509
|
+
` ${chalk98.red(`"${oldSpecifier}"`)} \u2192 ${chalk98.green(`"${newSpecifier}"`)}`
|
|
8468
8510
|
);
|
|
8469
8511
|
}
|
|
8470
8512
|
}
|
|
8471
8513
|
}
|
|
8472
8514
|
function displayPlan2(plan2) {
|
|
8473
8515
|
if (plan2.warnings.length > 0) {
|
|
8474
|
-
console.log(
|
|
8475
|
-
for (const w of plan2.warnings) console.log(
|
|
8516
|
+
console.log(chalk98.yellow("\nWarnings:"));
|
|
8517
|
+
for (const w of plan2.warnings) console.log(chalk98.yellow(` ${w}`));
|
|
8476
8518
|
}
|
|
8477
8519
|
if (plan2.newDirectories.length > 0) {
|
|
8478
|
-
console.log(
|
|
8520
|
+
console.log(chalk98.bold("\nNew directories:"));
|
|
8479
8521
|
for (const dir of plan2.newDirectories)
|
|
8480
|
-
console.log(
|
|
8522
|
+
console.log(chalk98.green(` ${dir}/`));
|
|
8481
8523
|
}
|
|
8482
8524
|
displayMoves(plan2);
|
|
8483
8525
|
displayRewrites(plan2.rewrites);
|
|
8484
8526
|
console.log(
|
|
8485
|
-
|
|
8527
|
+
chalk98.dim(
|
|
8486
8528
|
`
|
|
8487
8529
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8488
8530
|
)
|
|
@@ -8492,18 +8534,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8492
8534
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8493
8535
|
import fs20 from "fs";
|
|
8494
8536
|
import path42 from "path";
|
|
8495
|
-
import
|
|
8537
|
+
import chalk99 from "chalk";
|
|
8496
8538
|
function executePlan(plan2) {
|
|
8497
8539
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8498
8540
|
for (const [file, content] of updatedContents) {
|
|
8499
8541
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8500
8542
|
console.log(
|
|
8501
|
-
|
|
8543
|
+
chalk99.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8502
8544
|
);
|
|
8503
8545
|
}
|
|
8504
8546
|
for (const dir of plan2.newDirectories) {
|
|
8505
8547
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8506
|
-
console.log(
|
|
8548
|
+
console.log(chalk99.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8507
8549
|
}
|
|
8508
8550
|
for (const move of plan2.moves) {
|
|
8509
8551
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8512,7 +8554,7 @@ function executePlan(plan2) {
|
|
|
8512
8554
|
}
|
|
8513
8555
|
fs20.renameSync(move.from, move.to);
|
|
8514
8556
|
console.log(
|
|
8515
|
-
|
|
8557
|
+
chalk99.white(
|
|
8516
8558
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8517
8559
|
)
|
|
8518
8560
|
);
|
|
@@ -8527,7 +8569,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8527
8569
|
if (entries.length === 0) {
|
|
8528
8570
|
fs20.rmdirSync(dir);
|
|
8529
8571
|
console.log(
|
|
8530
|
-
|
|
8572
|
+
chalk99.dim(
|
|
8531
8573
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8532
8574
|
)
|
|
8533
8575
|
);
|
|
@@ -8660,22 +8702,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8660
8702
|
const targetPattern = pattern2 ?? "src";
|
|
8661
8703
|
const files = findSourceFiles2(targetPattern);
|
|
8662
8704
|
if (files.length === 0) {
|
|
8663
|
-
console.log(
|
|
8705
|
+
console.log(chalk100.yellow("No files found matching pattern"));
|
|
8664
8706
|
return;
|
|
8665
8707
|
}
|
|
8666
8708
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8667
8709
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8668
8710
|
if (plan2.moves.length === 0) {
|
|
8669
|
-
console.log(
|
|
8711
|
+
console.log(chalk100.green("No restructuring needed"));
|
|
8670
8712
|
return;
|
|
8671
8713
|
}
|
|
8672
8714
|
displayPlan2(plan2);
|
|
8673
8715
|
if (options2.apply) {
|
|
8674
|
-
console.log(
|
|
8716
|
+
console.log(chalk100.bold("\nApplying changes..."));
|
|
8675
8717
|
executePlan(plan2);
|
|
8676
|
-
console.log(
|
|
8718
|
+
console.log(chalk100.green("\nRestructuring complete"));
|
|
8677
8719
|
} else {
|
|
8678
|
-
console.log(
|
|
8720
|
+
console.log(chalk100.dim("\nDry run. Use --apply to execute."));
|
|
8679
8721
|
}
|
|
8680
8722
|
}
|
|
8681
8723
|
|
|
@@ -8715,7 +8757,7 @@ function registerRefactor(program2) {
|
|
|
8715
8757
|
}
|
|
8716
8758
|
|
|
8717
8759
|
// src/commands/seq/seqAuth.ts
|
|
8718
|
-
import
|
|
8760
|
+
import chalk102 from "chalk";
|
|
8719
8761
|
|
|
8720
8762
|
// src/commands/seq/loadConnections.ts
|
|
8721
8763
|
function loadConnections2() {
|
|
@@ -8744,11 +8786,11 @@ function setDefaultConnection(name) {
|
|
|
8744
8786
|
}
|
|
8745
8787
|
|
|
8746
8788
|
// src/commands/seq/promptConnection.ts
|
|
8747
|
-
import
|
|
8789
|
+
import chalk101 from "chalk";
|
|
8748
8790
|
async function promptConnection2(existingNames) {
|
|
8749
8791
|
const name = await promptInput("name", "Connection name:", "default");
|
|
8750
8792
|
if (existingNames.includes(name)) {
|
|
8751
|
-
console.error(
|
|
8793
|
+
console.error(chalk101.red(`Connection "${name}" already exists.`));
|
|
8752
8794
|
process.exit(1);
|
|
8753
8795
|
}
|
|
8754
8796
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -8760,32 +8802,32 @@ async function promptConnection2(existingNames) {
|
|
|
8760
8802
|
var seqAuth = createConnectionAuth({
|
|
8761
8803
|
load: loadConnections2,
|
|
8762
8804
|
save: saveConnections2,
|
|
8763
|
-
format: (c) => `${
|
|
8805
|
+
format: (c) => `${chalk102.bold(c.name)} ${c.url}`,
|
|
8764
8806
|
promptNew: promptConnection2,
|
|
8765
8807
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
8766
8808
|
});
|
|
8767
8809
|
|
|
8768
8810
|
// src/commands/seq/seqQuery.ts
|
|
8769
|
-
import
|
|
8811
|
+
import chalk105 from "chalk";
|
|
8770
8812
|
|
|
8771
8813
|
// src/commands/seq/formatEvent.ts
|
|
8772
|
-
import
|
|
8814
|
+
import chalk103 from "chalk";
|
|
8773
8815
|
function levelColor(level) {
|
|
8774
8816
|
switch (level) {
|
|
8775
8817
|
case "Fatal":
|
|
8776
|
-
return
|
|
8818
|
+
return chalk103.bgRed.white;
|
|
8777
8819
|
case "Error":
|
|
8778
|
-
return
|
|
8820
|
+
return chalk103.red;
|
|
8779
8821
|
case "Warning":
|
|
8780
|
-
return
|
|
8822
|
+
return chalk103.yellow;
|
|
8781
8823
|
case "Information":
|
|
8782
|
-
return
|
|
8824
|
+
return chalk103.cyan;
|
|
8783
8825
|
case "Debug":
|
|
8784
|
-
return
|
|
8826
|
+
return chalk103.gray;
|
|
8785
8827
|
case "Verbose":
|
|
8786
|
-
return
|
|
8828
|
+
return chalk103.dim;
|
|
8787
8829
|
default:
|
|
8788
|
-
return
|
|
8830
|
+
return chalk103.white;
|
|
8789
8831
|
}
|
|
8790
8832
|
}
|
|
8791
8833
|
function levelAbbrev(level) {
|
|
@@ -8826,31 +8868,31 @@ function formatTimestamp(iso) {
|
|
|
8826
8868
|
function formatEvent(event) {
|
|
8827
8869
|
const color = levelColor(event.Level);
|
|
8828
8870
|
const abbrev = levelAbbrev(event.Level);
|
|
8829
|
-
const ts8 =
|
|
8871
|
+
const ts8 = chalk103.dim(formatTimestamp(event.Timestamp));
|
|
8830
8872
|
const msg = renderMessage(event);
|
|
8831
8873
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
8832
8874
|
if (event.Exception) {
|
|
8833
8875
|
for (const line of event.Exception.split("\n")) {
|
|
8834
|
-
lines.push(
|
|
8876
|
+
lines.push(chalk103.red(` ${line}`));
|
|
8835
8877
|
}
|
|
8836
8878
|
}
|
|
8837
8879
|
return lines.join("\n");
|
|
8838
8880
|
}
|
|
8839
8881
|
|
|
8840
8882
|
// src/commands/seq/resolveConnection.ts
|
|
8841
|
-
import
|
|
8883
|
+
import chalk104 from "chalk";
|
|
8842
8884
|
function resolveConnection2(name) {
|
|
8843
8885
|
const connections = loadConnections2();
|
|
8844
8886
|
if (connections.length === 0) {
|
|
8845
8887
|
console.error(
|
|
8846
|
-
|
|
8888
|
+
chalk104.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
8847
8889
|
);
|
|
8848
8890
|
process.exit(1);
|
|
8849
8891
|
}
|
|
8850
8892
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
8851
8893
|
const connection = connections.find((c) => c.name === target);
|
|
8852
8894
|
if (!connection) {
|
|
8853
|
-
console.error(
|
|
8895
|
+
console.error(chalk104.red(`Seq connection "${target}" not found.`));
|
|
8854
8896
|
process.exit(1);
|
|
8855
8897
|
}
|
|
8856
8898
|
return connection;
|
|
@@ -8870,12 +8912,12 @@ async function seqQuery(filter, options2) {
|
|
|
8870
8912
|
});
|
|
8871
8913
|
if (!response.ok) {
|
|
8872
8914
|
const body = await response.text();
|
|
8873
|
-
console.error(
|
|
8915
|
+
console.error(chalk105.red(`Seq returned ${response.status}: ${body}`));
|
|
8874
8916
|
process.exit(1);
|
|
8875
8917
|
}
|
|
8876
8918
|
const events = await response.json();
|
|
8877
8919
|
if (events.length === 0) {
|
|
8878
|
-
console.log(
|
|
8920
|
+
console.log(chalk105.yellow("No events found."));
|
|
8879
8921
|
return;
|
|
8880
8922
|
}
|
|
8881
8923
|
if (options2.json) {
|
|
@@ -8886,11 +8928,11 @@ async function seqQuery(filter, options2) {
|
|
|
8886
8928
|
for (const event of chronological) {
|
|
8887
8929
|
console.log(formatEvent(event));
|
|
8888
8930
|
}
|
|
8889
|
-
console.log(
|
|
8931
|
+
console.log(chalk105.dim(`
|
|
8890
8932
|
${events.length} events`));
|
|
8891
8933
|
if (events.length >= count) {
|
|
8892
8934
|
console.log(
|
|
8893
|
-
|
|
8935
|
+
chalk105.yellow(
|
|
8894
8936
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
8895
8937
|
)
|
|
8896
8938
|
);
|
|
@@ -8898,11 +8940,11 @@ ${events.length} events`));
|
|
|
8898
8940
|
}
|
|
8899
8941
|
|
|
8900
8942
|
// src/commands/seq/seqSetConnection.ts
|
|
8901
|
-
import
|
|
8943
|
+
import chalk106 from "chalk";
|
|
8902
8944
|
function seqSetConnection(name) {
|
|
8903
8945
|
const connections = loadConnections2();
|
|
8904
8946
|
if (!connections.find((c) => c.name === name)) {
|
|
8905
|
-
console.error(
|
|
8947
|
+
console.error(chalk106.red(`Connection "${name}" not found.`));
|
|
8906
8948
|
process.exit(1);
|
|
8907
8949
|
}
|
|
8908
8950
|
setDefaultConnection(name);
|
|
@@ -8921,7 +8963,7 @@ function registerSeq(program2) {
|
|
|
8921
8963
|
}
|
|
8922
8964
|
|
|
8923
8965
|
// src/commands/transcript/shared.ts
|
|
8924
|
-
import { existsSync as
|
|
8966
|
+
import { existsSync as existsSync30, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
|
|
8925
8967
|
import { basename as basename4, join as join25, relative } from "path";
|
|
8926
8968
|
import * as readline2 from "readline";
|
|
8927
8969
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
@@ -8937,7 +8979,7 @@ function isValidDatePrefix(filename) {
|
|
|
8937
8979
|
return DATE_PREFIX_REGEX.test(filename);
|
|
8938
8980
|
}
|
|
8939
8981
|
function collectFiles(dir, extension) {
|
|
8940
|
-
if (!
|
|
8982
|
+
if (!existsSync30(dir)) return [];
|
|
8941
8983
|
const results = [];
|
|
8942
8984
|
for (const entry of readdirSync5(dir)) {
|
|
8943
8985
|
const fullPath = join25(dir, entry);
|
|
@@ -9034,7 +9076,7 @@ async function configure() {
|
|
|
9034
9076
|
}
|
|
9035
9077
|
|
|
9036
9078
|
// src/commands/transcript/format/index.ts
|
|
9037
|
-
import { existsSync as
|
|
9079
|
+
import { existsSync as existsSync32 } from "fs";
|
|
9038
9080
|
|
|
9039
9081
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
9040
9082
|
import { dirname as dirname18, join as join27 } from "path";
|
|
@@ -9108,7 +9150,7 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
9108
9150
|
}
|
|
9109
9151
|
|
|
9110
9152
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
9111
|
-
import { existsSync as
|
|
9153
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync7, readFileSync as readFileSync24, writeFileSync as writeFileSync23 } from "fs";
|
|
9112
9154
|
import { basename as basename5, dirname as dirname19, join as join28 } from "path";
|
|
9113
9155
|
|
|
9114
9156
|
// src/commands/transcript/cleanText.ts
|
|
@@ -9333,7 +9375,7 @@ function logSkipped(relativeDir, mdFile) {
|
|
|
9333
9375
|
return "skipped";
|
|
9334
9376
|
}
|
|
9335
9377
|
function ensureDirectory(dir, label2) {
|
|
9336
|
-
if (!
|
|
9378
|
+
if (!existsSync31(dir)) {
|
|
9337
9379
|
mkdirSync7(dir, { recursive: true });
|
|
9338
9380
|
console.log(`Created ${label2}: ${dir}`);
|
|
9339
9381
|
}
|
|
@@ -9356,7 +9398,7 @@ function logReduction(cueCount, messageCount) {
|
|
|
9356
9398
|
}
|
|
9357
9399
|
function readAndParseCues(inputPath) {
|
|
9358
9400
|
console.log(`Reading: ${inputPath}`);
|
|
9359
|
-
return processCues(
|
|
9401
|
+
return processCues(readFileSync24(inputPath, "utf-8"));
|
|
9360
9402
|
}
|
|
9361
9403
|
function writeFormatted(outputPath, content) {
|
|
9362
9404
|
writeFileSync23(outputPath, content, "utf-8");
|
|
@@ -9369,7 +9411,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
|
|
|
9369
9411
|
logReduction(cues.length, chatMessages.length);
|
|
9370
9412
|
}
|
|
9371
9413
|
function tryProcessVtt(vttFile, paths) {
|
|
9372
|
-
if (
|
|
9414
|
+
if (existsSync31(paths.outputPath))
|
|
9373
9415
|
return logSkipped(paths.relativeDir, paths.mdFile);
|
|
9374
9416
|
convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
|
|
9375
9417
|
return "processed";
|
|
@@ -9395,7 +9437,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
|
|
|
9395
9437
|
logSummary(counts);
|
|
9396
9438
|
}
|
|
9397
9439
|
function requireVttDir(vttDir) {
|
|
9398
|
-
if (!
|
|
9440
|
+
if (!existsSync32(vttDir)) {
|
|
9399
9441
|
console.error(`VTT directory not found: ${vttDir}`);
|
|
9400
9442
|
process.exit(1);
|
|
9401
9443
|
}
|
|
@@ -9427,28 +9469,28 @@ async function format() {
|
|
|
9427
9469
|
}
|
|
9428
9470
|
|
|
9429
9471
|
// src/commands/transcript/summarise/index.ts
|
|
9430
|
-
import { existsSync as
|
|
9472
|
+
import { existsSync as existsSync34 } from "fs";
|
|
9431
9473
|
import { basename as basename6, dirname as dirname21, join as join30, relative as relative2 } from "path";
|
|
9432
9474
|
|
|
9433
9475
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
9434
9476
|
import {
|
|
9435
|
-
existsSync as
|
|
9477
|
+
existsSync as existsSync33,
|
|
9436
9478
|
mkdirSync as mkdirSync8,
|
|
9437
|
-
readFileSync as
|
|
9479
|
+
readFileSync as readFileSync25,
|
|
9438
9480
|
renameSync as renameSync2,
|
|
9439
9481
|
rmSync
|
|
9440
9482
|
} from "fs";
|
|
9441
9483
|
import { dirname as dirname20, join as join29 } from "path";
|
|
9442
9484
|
|
|
9443
9485
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9444
|
-
import
|
|
9486
|
+
import chalk107 from "chalk";
|
|
9445
9487
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9446
9488
|
function validateStagedContent(filename, content) {
|
|
9447
9489
|
const firstLine = content.split("\n")[0];
|
|
9448
9490
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9449
9491
|
if (!match) {
|
|
9450
9492
|
console.error(
|
|
9451
|
-
|
|
9493
|
+
chalk107.red(
|
|
9452
9494
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9453
9495
|
)
|
|
9454
9496
|
);
|
|
@@ -9457,7 +9499,7 @@ function validateStagedContent(filename, content) {
|
|
|
9457
9499
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9458
9500
|
if (!contentAfterLink) {
|
|
9459
9501
|
console.error(
|
|
9460
|
-
|
|
9502
|
+
chalk107.red(
|
|
9461
9503
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9462
9504
|
)
|
|
9463
9505
|
);
|
|
@@ -9469,7 +9511,7 @@ function validateStagedContent(filename, content) {
|
|
|
9469
9511
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
9470
9512
|
var STAGING_DIR = join29(process.cwd(), ".assist", "transcript");
|
|
9471
9513
|
function processStagedFile() {
|
|
9472
|
-
if (!
|
|
9514
|
+
if (!existsSync33(STAGING_DIR)) {
|
|
9473
9515
|
return false;
|
|
9474
9516
|
}
|
|
9475
9517
|
const stagedFiles = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -9478,7 +9520,7 @@ function processStagedFile() {
|
|
|
9478
9520
|
}
|
|
9479
9521
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
9480
9522
|
const stagedFile = stagedFiles[0];
|
|
9481
|
-
const content =
|
|
9523
|
+
const content = readFileSync25(stagedFile.absolutePath, "utf-8");
|
|
9482
9524
|
validateStagedContent(stagedFile.filename, content);
|
|
9483
9525
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
9484
9526
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -9493,7 +9535,7 @@ function processStagedFile() {
|
|
|
9493
9535
|
}
|
|
9494
9536
|
const destPath = join29(summaryDir, matchingTranscript.relativePath);
|
|
9495
9537
|
const destDir = dirname20(destPath);
|
|
9496
|
-
if (!
|
|
9538
|
+
if (!existsSync33(destDir)) {
|
|
9497
9539
|
mkdirSync8(destDir, { recursive: true });
|
|
9498
9540
|
}
|
|
9499
9541
|
renameSync2(stagedFile.absolutePath, destPath);
|
|
@@ -9520,7 +9562,7 @@ function buildSummaryIndex(summaryDir) {
|
|
|
9520
9562
|
function summarise2() {
|
|
9521
9563
|
processStagedFile();
|
|
9522
9564
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
9523
|
-
if (!
|
|
9565
|
+
if (!existsSync34(transcriptsDir)) {
|
|
9524
9566
|
console.log("No transcripts directory found.");
|
|
9525
9567
|
return;
|
|
9526
9568
|
}
|
|
@@ -9624,14 +9666,14 @@ function devices() {
|
|
|
9624
9666
|
}
|
|
9625
9667
|
|
|
9626
9668
|
// src/commands/voice/logs.ts
|
|
9627
|
-
import { existsSync as
|
|
9669
|
+
import { existsSync as existsSync35, readFileSync as readFileSync26 } from "fs";
|
|
9628
9670
|
function logs(options2) {
|
|
9629
|
-
if (!
|
|
9671
|
+
if (!existsSync35(voicePaths.log)) {
|
|
9630
9672
|
console.log("No voice log file found");
|
|
9631
9673
|
return;
|
|
9632
9674
|
}
|
|
9633
9675
|
const count = Number.parseInt(options2.lines ?? "150", 10);
|
|
9634
|
-
const content =
|
|
9676
|
+
const content = readFileSync26(voicePaths.log, "utf-8").trim();
|
|
9635
9677
|
if (!content) {
|
|
9636
9678
|
console.log("Voice log is empty");
|
|
9637
9679
|
return;
|
|
@@ -9658,7 +9700,7 @@ import { join as join34 } from "path";
|
|
|
9658
9700
|
|
|
9659
9701
|
// src/commands/voice/checkLockFile.ts
|
|
9660
9702
|
import { execSync as execSync37 } from "child_process";
|
|
9661
|
-
import { existsSync as
|
|
9703
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync9, readFileSync as readFileSync27, writeFileSync as writeFileSync24 } from "fs";
|
|
9662
9704
|
import { join as join33 } from "path";
|
|
9663
9705
|
function isProcessAlive(pid) {
|
|
9664
9706
|
try {
|
|
@@ -9670,9 +9712,9 @@ function isProcessAlive(pid) {
|
|
|
9670
9712
|
}
|
|
9671
9713
|
function checkLockFile() {
|
|
9672
9714
|
const lockFile = getLockFile();
|
|
9673
|
-
if (!
|
|
9715
|
+
if (!existsSync36(lockFile)) return;
|
|
9674
9716
|
try {
|
|
9675
|
-
const lock = JSON.parse(
|
|
9717
|
+
const lock = JSON.parse(readFileSync27(lockFile, "utf-8"));
|
|
9676
9718
|
if (lock.pid && isProcessAlive(lock.pid)) {
|
|
9677
9719
|
console.error(
|
|
9678
9720
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -9683,7 +9725,7 @@ function checkLockFile() {
|
|
|
9683
9725
|
}
|
|
9684
9726
|
}
|
|
9685
9727
|
function bootstrapVenv() {
|
|
9686
|
-
if (
|
|
9728
|
+
if (existsSync36(getVenvPython())) return;
|
|
9687
9729
|
console.log("Setting up Python environment...");
|
|
9688
9730
|
const pythonDir = getPythonDir();
|
|
9689
9731
|
execSync37(
|
|
@@ -9774,7 +9816,7 @@ function start2(options2) {
|
|
|
9774
9816
|
}
|
|
9775
9817
|
|
|
9776
9818
|
// src/commands/voice/status.ts
|
|
9777
|
-
import { existsSync as
|
|
9819
|
+
import { existsSync as existsSync37, readFileSync as readFileSync28 } from "fs";
|
|
9778
9820
|
function isProcessAlive2(pid) {
|
|
9779
9821
|
try {
|
|
9780
9822
|
process.kill(pid, 0);
|
|
@@ -9784,16 +9826,16 @@ function isProcessAlive2(pid) {
|
|
|
9784
9826
|
}
|
|
9785
9827
|
}
|
|
9786
9828
|
function readRecentLogs(count) {
|
|
9787
|
-
if (!
|
|
9788
|
-
const lines =
|
|
9829
|
+
if (!existsSync37(voicePaths.log)) return [];
|
|
9830
|
+
const lines = readFileSync28(voicePaths.log, "utf-8").trim().split("\n");
|
|
9789
9831
|
return lines.slice(-count);
|
|
9790
9832
|
}
|
|
9791
9833
|
function status() {
|
|
9792
|
-
if (!
|
|
9834
|
+
if (!existsSync37(voicePaths.pid)) {
|
|
9793
9835
|
console.log("Voice daemon: not running (no PID file)");
|
|
9794
9836
|
return;
|
|
9795
9837
|
}
|
|
9796
|
-
const pid = Number.parseInt(
|
|
9838
|
+
const pid = Number.parseInt(readFileSync28(voicePaths.pid, "utf-8").trim(), 10);
|
|
9797
9839
|
const alive = isProcessAlive2(pid);
|
|
9798
9840
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
9799
9841
|
const recent = readRecentLogs(5);
|
|
@@ -9812,13 +9854,13 @@ function status() {
|
|
|
9812
9854
|
}
|
|
9813
9855
|
|
|
9814
9856
|
// src/commands/voice/stop.ts
|
|
9815
|
-
import { existsSync as
|
|
9857
|
+
import { existsSync as existsSync38, readFileSync as readFileSync29, unlinkSync as unlinkSync9 } from "fs";
|
|
9816
9858
|
function stop() {
|
|
9817
|
-
if (!
|
|
9859
|
+
if (!existsSync38(voicePaths.pid)) {
|
|
9818
9860
|
console.log("Voice daemon is not running (no PID file)");
|
|
9819
9861
|
return;
|
|
9820
9862
|
}
|
|
9821
|
-
const pid = Number.parseInt(
|
|
9863
|
+
const pid = Number.parseInt(readFileSync29(voicePaths.pid, "utf-8").trim(), 10);
|
|
9822
9864
|
try {
|
|
9823
9865
|
process.kill(pid, "SIGTERM");
|
|
9824
9866
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -9831,7 +9873,7 @@ function stop() {
|
|
|
9831
9873
|
}
|
|
9832
9874
|
try {
|
|
9833
9875
|
const lockFile = getLockFile();
|
|
9834
|
-
if (
|
|
9876
|
+
if (existsSync38(lockFile)) unlinkSync9(lockFile);
|
|
9835
9877
|
} catch {
|
|
9836
9878
|
}
|
|
9837
9879
|
console.log("Voice daemon stopped");
|
|
@@ -9850,7 +9892,7 @@ function registerVoice(program2) {
|
|
|
9850
9892
|
|
|
9851
9893
|
// src/commands/roam/auth.ts
|
|
9852
9894
|
import { randomBytes } from "crypto";
|
|
9853
|
-
import
|
|
9895
|
+
import chalk108 from "chalk";
|
|
9854
9896
|
|
|
9855
9897
|
// src/lib/openBrowser.ts
|
|
9856
9898
|
import { execSync as execSync38 } from "child_process";
|
|
@@ -10025,13 +10067,13 @@ async function auth() {
|
|
|
10025
10067
|
saveGlobalConfig(config);
|
|
10026
10068
|
const state = randomBytes(16).toString("hex");
|
|
10027
10069
|
console.log(
|
|
10028
|
-
|
|
10070
|
+
chalk108.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
10029
10071
|
);
|
|
10030
|
-
console.log(
|
|
10031
|
-
console.log(
|
|
10032
|
-
console.log(
|
|
10072
|
+
console.log(chalk108.white("http://localhost:14523/callback\n"));
|
|
10073
|
+
console.log(chalk108.blue("Opening browser for authorization..."));
|
|
10074
|
+
console.log(chalk108.dim("Waiting for authorization callback..."));
|
|
10033
10075
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
10034
|
-
console.log(
|
|
10076
|
+
console.log(chalk108.dim("Exchanging code for tokens..."));
|
|
10035
10077
|
const tokens = await exchangeToken({
|
|
10036
10078
|
code,
|
|
10037
10079
|
clientId,
|
|
@@ -10047,12 +10089,12 @@ async function auth() {
|
|
|
10047
10089
|
};
|
|
10048
10090
|
saveGlobalConfig(config);
|
|
10049
10091
|
console.log(
|
|
10050
|
-
|
|
10092
|
+
chalk108.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
10051
10093
|
);
|
|
10052
10094
|
}
|
|
10053
10095
|
|
|
10054
10096
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
10055
|
-
import { readFileSync as
|
|
10097
|
+
import { readFileSync as readFileSync30 } from "fs";
|
|
10056
10098
|
import { join as join36 } from "path";
|
|
10057
10099
|
async function showClaudeCodeIcon() {
|
|
10058
10100
|
const appData = process.env.APPDATA;
|
|
@@ -10060,7 +10102,7 @@ async function showClaudeCodeIcon() {
|
|
|
10060
10102
|
const portFile = join36(appData, "Roam", "roam-local-api.port");
|
|
10061
10103
|
let port;
|
|
10062
10104
|
try {
|
|
10063
|
-
port =
|
|
10105
|
+
port = readFileSync30(portFile, "utf-8").trim();
|
|
10064
10106
|
} catch {
|
|
10065
10107
|
return;
|
|
10066
10108
|
}
|
|
@@ -10257,10 +10299,10 @@ function run3(name, args) {
|
|
|
10257
10299
|
|
|
10258
10300
|
// src/commands/screenshot/index.ts
|
|
10259
10301
|
import { execSync as execSync40 } from "child_process";
|
|
10260
|
-
import { existsSync as
|
|
10302
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync13, unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
|
|
10261
10303
|
import { tmpdir as tmpdir6 } from "os";
|
|
10262
10304
|
import { join as join38, resolve as resolve5 } from "path";
|
|
10263
|
-
import
|
|
10305
|
+
import chalk109 from "chalk";
|
|
10264
10306
|
|
|
10265
10307
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10266
10308
|
var captureWindowPs1 = `
|
|
@@ -10389,7 +10431,7 @@ Write-Output $OutputPath
|
|
|
10389
10431
|
|
|
10390
10432
|
// src/commands/screenshot/index.ts
|
|
10391
10433
|
function buildOutputPath(outputDir, processName) {
|
|
10392
|
-
if (!
|
|
10434
|
+
if (!existsSync39(outputDir)) {
|
|
10393
10435
|
mkdirSync13(outputDir, { recursive: true });
|
|
10394
10436
|
}
|
|
10395
10437
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -10411,22 +10453,22 @@ function screenshot(processName) {
|
|
|
10411
10453
|
const config = loadConfig();
|
|
10412
10454
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10413
10455
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10414
|
-
console.log(
|
|
10456
|
+
console.log(chalk109.gray(`Capturing window for process "${processName}" ...`));
|
|
10415
10457
|
try {
|
|
10416
10458
|
runPowerShellScript(processName, outputPath);
|
|
10417
|
-
console.log(
|
|
10459
|
+
console.log(chalk109.green(`Screenshot saved: ${outputPath}`));
|
|
10418
10460
|
} catch (error) {
|
|
10419
10461
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10420
|
-
console.error(
|
|
10462
|
+
console.error(chalk109.red(`Failed to capture screenshot: ${msg}`));
|
|
10421
10463
|
process.exit(1);
|
|
10422
10464
|
}
|
|
10423
10465
|
}
|
|
10424
10466
|
|
|
10425
10467
|
// src/commands/statusLine.ts
|
|
10426
|
-
import
|
|
10468
|
+
import chalk111 from "chalk";
|
|
10427
10469
|
|
|
10428
10470
|
// src/commands/buildLimitsSegment.ts
|
|
10429
|
-
import
|
|
10471
|
+
import chalk110 from "chalk";
|
|
10430
10472
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10431
10473
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10432
10474
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10449,10 +10491,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10449
10491
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10450
10492
|
const label2 = `${Math.round(pct)}%`;
|
|
10451
10493
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10452
|
-
if (projected == null) return
|
|
10453
|
-
if (projected > 100) return
|
|
10454
|
-
if (projected > 75) return
|
|
10455
|
-
return
|
|
10494
|
+
if (projected == null) return chalk110.green(label2);
|
|
10495
|
+
if (projected > 100) return chalk110.red(label2);
|
|
10496
|
+
if (projected > 75) return chalk110.yellow(label2);
|
|
10497
|
+
return chalk110.green(label2);
|
|
10456
10498
|
}
|
|
10457
10499
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10458
10500
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10478,14 +10520,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10478
10520
|
}
|
|
10479
10521
|
|
|
10480
10522
|
// src/commands/statusLine.ts
|
|
10481
|
-
|
|
10523
|
+
chalk111.level = 3;
|
|
10482
10524
|
function formatNumber(num) {
|
|
10483
10525
|
return num.toLocaleString("en-US");
|
|
10484
10526
|
}
|
|
10485
10527
|
function colorizePercent(pct) {
|
|
10486
10528
|
const label2 = `${Math.round(pct)}%`;
|
|
10487
|
-
if (pct > 80) return
|
|
10488
|
-
if (pct > 40) return
|
|
10529
|
+
if (pct > 80) return chalk111.red(label2);
|
|
10530
|
+
if (pct > 40) return chalk111.yellow(label2);
|
|
10489
10531
|
return label2;
|
|
10490
10532
|
}
|
|
10491
10533
|
async function statusLine() {
|
|
@@ -10508,7 +10550,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10508
10550
|
// src/commands/sync/syncClaudeMd.ts
|
|
10509
10551
|
import * as fs23 from "fs";
|
|
10510
10552
|
import * as path46 from "path";
|
|
10511
|
-
import
|
|
10553
|
+
import chalk112 from "chalk";
|
|
10512
10554
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10513
10555
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10514
10556
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10517,12 +10559,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10517
10559
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10518
10560
|
if (sourceContent !== targetContent) {
|
|
10519
10561
|
console.log(
|
|
10520
|
-
|
|
10562
|
+
chalk112.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10521
10563
|
);
|
|
10522
10564
|
console.log();
|
|
10523
10565
|
printDiff(targetContent, sourceContent);
|
|
10524
10566
|
const confirm = options2?.yes || await promptConfirm(
|
|
10525
|
-
|
|
10567
|
+
chalk112.red("Overwrite existing CLAUDE.md?"),
|
|
10526
10568
|
false
|
|
10527
10569
|
);
|
|
10528
10570
|
if (!confirm) {
|
|
@@ -10538,7 +10580,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10538
10580
|
// src/commands/sync/syncSettings.ts
|
|
10539
10581
|
import * as fs24 from "fs";
|
|
10540
10582
|
import * as path47 from "path";
|
|
10541
|
-
import
|
|
10583
|
+
import chalk113 from "chalk";
|
|
10542
10584
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10543
10585
|
const source = path47.join(claudeDir, "settings.json");
|
|
10544
10586
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10554,14 +10596,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10554
10596
|
if (mergedContent !== normalizedTarget) {
|
|
10555
10597
|
if (!options2?.yes) {
|
|
10556
10598
|
console.log(
|
|
10557
|
-
|
|
10599
|
+
chalk113.yellow(
|
|
10558
10600
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10559
10601
|
)
|
|
10560
10602
|
);
|
|
10561
10603
|
console.log();
|
|
10562
10604
|
printDiff(targetContent, mergedContent);
|
|
10563
10605
|
const confirm = await promptConfirm(
|
|
10564
|
-
|
|
10606
|
+
chalk113.red("Overwrite existing settings.json?"),
|
|
10565
10607
|
false
|
|
10566
10608
|
);
|
|
10567
10609
|
if (!confirm) {
|
|
@@ -10684,4 +10726,11 @@ registerSeq(program);
|
|
|
10684
10726
|
registerTranscript(program);
|
|
10685
10727
|
registerVoice(program);
|
|
10686
10728
|
program.command("next").description("Alias for backlog next -w").action(() => next({ allowEdits: true }));
|
|
10729
|
+
program.command("draft").description("Launch Claude in /draft mode, chain into next on /next signal").action(() => launchMode("draft"));
|
|
10730
|
+
program.command("bug").description("Launch Claude in /bug mode, chain into next on /next signal").action(() => launchMode("bug"));
|
|
10731
|
+
var signalCommand = program.command("signal").description("Write an assist signal file");
|
|
10732
|
+
signalCommand.command("next").description("Write a next signal to chain into assist next").action(() => {
|
|
10733
|
+
writeSignal("next");
|
|
10734
|
+
console.log("Signal written.");
|
|
10735
|
+
});
|
|
10687
10736
|
program.parse();
|