@staff0rd/assist 0.151.1 → 0.153.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 +3 -1
- package/claude/settings.json +2 -0
- package/dist/commands/backlog/web/bundle.js +23 -23
- package/dist/index.js +650 -516
- 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.153.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -100,6 +100,13 @@ var planPhaseSchema = z.strictObject({
|
|
|
100
100
|
tasks: z.array(planTaskSchema),
|
|
101
101
|
manualChecks: z.array(z.string()).optional()
|
|
102
102
|
});
|
|
103
|
+
var backlogCommentTypeSchema = z.enum(["comment", "summary"]);
|
|
104
|
+
var backlogCommentSchema = z.strictObject({
|
|
105
|
+
text: z.string(),
|
|
106
|
+
phase: z.number().optional(),
|
|
107
|
+
timestamp: z.string(),
|
|
108
|
+
type: backlogCommentTypeSchema
|
|
109
|
+
});
|
|
103
110
|
var backlogItemSchema = z.strictObject({
|
|
104
111
|
id: z.number(),
|
|
105
112
|
type: backlogTypeSchema.default("story"),
|
|
@@ -108,7 +115,8 @@ var backlogItemSchema = z.strictObject({
|
|
|
108
115
|
acceptanceCriteria: z.array(z.string()),
|
|
109
116
|
plan: z.array(planPhaseSchema).optional(),
|
|
110
117
|
currentPhase: z.number().optional(),
|
|
111
|
-
status: backlogStatusSchema
|
|
118
|
+
status: backlogStatusSchema,
|
|
119
|
+
comments: z.array(backlogCommentSchema).optional()
|
|
112
120
|
});
|
|
113
121
|
var backlogFileSchema = z.array(backlogItemSchema);
|
|
114
122
|
|
|
@@ -260,7 +268,11 @@ function buildAuthoredPhasePrompt(item, phaseIndex, phase) {
|
|
|
260
268
|
"When you have completed all tasks for this phase, run /verify to check your work.",
|
|
261
269
|
...buildManualCheckLines(manualChecks),
|
|
262
270
|
"",
|
|
263
|
-
`
|
|
271
|
+
`You can run \`assist backlog comments ${item.id}\` to read prior phase notes and comments.`,
|
|
272
|
+
`You can run \`assist backlog comment ${item.id} "<text>"\` to post findings or changes worth noting.`,
|
|
273
|
+
"",
|
|
274
|
+
`Once verify passes${confirmSuffix}, run: assist backlog phase-done ${item.id} ${phaseIndex} "<summary>"`,
|
|
275
|
+
"Replace <summary> with a concise summary of what was done in this phase."
|
|
264
276
|
].filter((line) => line !== void 0).join("\n");
|
|
265
277
|
}
|
|
266
278
|
function buildContextLines(item, phaseIndex, phase) {
|
|
@@ -313,6 +325,9 @@ function buildReviewPrompt(item, phaseIndex) {
|
|
|
313
325
|
"",
|
|
314
326
|
"If any criterion fails, fix the issue and re-verify before proceeding.",
|
|
315
327
|
"",
|
|
328
|
+
`You can run \`assist backlog comments ${item.id}\` to read prior phase notes and comments.`,
|
|
329
|
+
`You can run \`assist backlog comment ${item.id} "<text>"\` to post findings or changes worth noting.`,
|
|
330
|
+
"",
|
|
316
331
|
"After all criteria pass, ask the user to confirm any manual checks",
|
|
317
332
|
"(e.g. end-to-end behaviour they need to verify themselves).",
|
|
318
333
|
"Wait for the user to confirm before proceeding.",
|
|
@@ -320,7 +335,7 @@ function buildReviewPrompt(item, phaseIndex) {
|
|
|
320
335
|
"Once the user confirms:",
|
|
321
336
|
`1. Run: assist backlog done ${item.id}`,
|
|
322
337
|
"2. Run: /commit",
|
|
323
|
-
`3. Run: assist backlog phase-done ${item.id} ${phaseIndex}`
|
|
338
|
+
`3. Run: assist backlog phase-done ${item.id} ${phaseIndex} "<summary>"`
|
|
324
339
|
].filter((line) => line !== void 0).join("\n");
|
|
325
340
|
}
|
|
326
341
|
|
|
@@ -370,11 +385,35 @@ async function handleIncompletePhase() {
|
|
|
370
385
|
import { writeFileSync as writeFileSync2 } from "fs";
|
|
371
386
|
import { join as join2 } from "path";
|
|
372
387
|
import chalk5 from "chalk";
|
|
388
|
+
|
|
389
|
+
// src/commands/backlog/addComment.ts
|
|
390
|
+
function addComment(item, text, phase) {
|
|
391
|
+
const entry = {
|
|
392
|
+
text,
|
|
393
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
394
|
+
type: "comment",
|
|
395
|
+
...phase !== void 0 && { phase }
|
|
396
|
+
};
|
|
397
|
+
if (!item.comments) item.comments = [];
|
|
398
|
+
item.comments.push(entry);
|
|
399
|
+
}
|
|
400
|
+
function addPhaseSummary(item, text, phase) {
|
|
401
|
+
const entry = {
|
|
402
|
+
text,
|
|
403
|
+
phase,
|
|
404
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
405
|
+
type: "summary"
|
|
406
|
+
};
|
|
407
|
+
if (!item.comments) item.comments = [];
|
|
408
|
+
item.comments.push(entry);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// src/commands/backlog/phaseDone.ts
|
|
373
412
|
var PHASE_STATUS_FILE = ".assist-phase-status.json";
|
|
374
413
|
function getPhaseStatusPath() {
|
|
375
414
|
return join2(process.cwd(), PHASE_STATUS_FILE);
|
|
376
415
|
}
|
|
377
|
-
function phaseDone(id, phase) {
|
|
416
|
+
function phaseDone(id, phase, summary) {
|
|
378
417
|
const phaseIndex = Number.parseInt(phase, 10);
|
|
379
418
|
const statusPath = getPhaseStatusPath();
|
|
380
419
|
writeFileSync2(
|
|
@@ -390,6 +429,10 @@ function phaseDone(id, phase) {
|
|
|
390
429
|
console.log(chalk5.dim(`Item #${id} already done, skipping phase advance.`));
|
|
391
430
|
return;
|
|
392
431
|
}
|
|
432
|
+
if (result) {
|
|
433
|
+
addPhaseSummary(result.item, summary, phaseIndex);
|
|
434
|
+
saveBacklog(result.items);
|
|
435
|
+
}
|
|
393
436
|
setCurrentPhase(id, phaseIndex + 1);
|
|
394
437
|
console.log(chalk5.green(`Phase ${phase} of item #${id} marked as complete.`));
|
|
395
438
|
}
|
|
@@ -610,63 +653,96 @@ function plan(id) {
|
|
|
610
653
|
}
|
|
611
654
|
|
|
612
655
|
// src/commands/backlog/show/index.ts
|
|
656
|
+
import chalk13 from "chalk";
|
|
657
|
+
|
|
658
|
+
// src/commands/backlog/formatComment.ts
|
|
613
659
|
import chalk12 from "chalk";
|
|
660
|
+
function formatComment(entry) {
|
|
661
|
+
const tag = entry.type === "summary" ? chalk12.magenta("[summary]") : chalk12.cyan("[comment]");
|
|
662
|
+
const phase = entry.phase !== void 0 ? chalk12.dim(` (phase ${entry.phase + 1})`) : "";
|
|
663
|
+
const time = chalk12.dim(entry.timestamp);
|
|
664
|
+
return `${tag}${phase} ${time}
|
|
665
|
+
${entry.text}`;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// src/commands/backlog/show/index.ts
|
|
614
669
|
function printPlan(item) {
|
|
615
670
|
if (!item.plan || item.plan.length === 0) return;
|
|
616
|
-
console.log(
|
|
671
|
+
console.log(chalk13.bold("Plan"));
|
|
617
672
|
for (const [i, phase] of item.plan.entries()) {
|
|
618
673
|
const isCurrent = item.currentPhase === i;
|
|
619
674
|
printPhase(phase, i, isCurrent);
|
|
620
675
|
}
|
|
621
676
|
console.log();
|
|
622
677
|
}
|
|
623
|
-
function
|
|
624
|
-
const marker = isCurrent ?
|
|
625
|
-
const label2 = isCurrent ?
|
|
626
|
-
|
|
678
|
+
function phaseHeader(index, name, isCurrent) {
|
|
679
|
+
const marker = isCurrent ? chalk13.green("\u25B6 ") : " ";
|
|
680
|
+
const label2 = isCurrent ? chalk13.green.bold(`Phase ${index + 1}: ${name}`) : `${chalk13.bold(`Phase ${index + 1}:`)} ${name}`;
|
|
681
|
+
return `${marker}${label2}`;
|
|
682
|
+
}
|
|
683
|
+
function printPhaseTasks(phase) {
|
|
627
684
|
for (const task of phase.tasks) {
|
|
628
685
|
console.log(` - ${task.task}`);
|
|
629
686
|
if (task.verify) {
|
|
630
|
-
console.log(` ${
|
|
687
|
+
console.log(` ${chalk13.dim(`verify: ${task.verify}`)}`);
|
|
631
688
|
}
|
|
632
689
|
}
|
|
633
690
|
if (phase.manualChecks && phase.manualChecks.length > 0) {
|
|
634
|
-
console.log(` ${
|
|
691
|
+
console.log(` ${chalk13.dim("Manual checks:")}`);
|
|
635
692
|
for (const check2 of phase.manualChecks) {
|
|
636
|
-
console.log(` ${
|
|
693
|
+
console.log(` ${chalk13.dim(`- ${check2}`)}`);
|
|
637
694
|
}
|
|
638
695
|
}
|
|
639
696
|
}
|
|
697
|
+
function printPhase(phase, index, isCurrent) {
|
|
698
|
+
console.log(phaseHeader(index, phase.name, isCurrent));
|
|
699
|
+
printPhaseTasks(phase);
|
|
700
|
+
}
|
|
701
|
+
function printHeader(item) {
|
|
702
|
+
console.log(chalk13.bold(`#${item.id} ${item.name}`));
|
|
703
|
+
console.log(
|
|
704
|
+
`${chalk13.dim("Type:")} ${item.type} ${chalk13.dim("Status:")} ${item.status}`
|
|
705
|
+
);
|
|
706
|
+
console.log();
|
|
707
|
+
}
|
|
708
|
+
function printAcceptanceCriteria(criteria) {
|
|
709
|
+
if (criteria.length === 0) return;
|
|
710
|
+
console.log(chalk13.bold("Acceptance Criteria"));
|
|
711
|
+
for (const [i, ac] of criteria.entries()) {
|
|
712
|
+
console.log(` ${i + 1}. ${ac}`);
|
|
713
|
+
}
|
|
714
|
+
console.log();
|
|
715
|
+
}
|
|
640
716
|
function show(id) {
|
|
641
717
|
const result = loadAndFindItem(id);
|
|
642
718
|
if (!result) process.exit(1);
|
|
643
719
|
const { item } = result;
|
|
644
|
-
|
|
645
|
-
console.log(
|
|
646
|
-
`${chalk12.dim("Type:")} ${item.type} ${chalk12.dim("Status:")} ${item.status}`
|
|
647
|
-
);
|
|
648
|
-
console.log();
|
|
720
|
+
printHeader(item);
|
|
649
721
|
if (item.description) {
|
|
650
|
-
console.log(
|
|
722
|
+
console.log(chalk13.bold("Description"));
|
|
651
723
|
console.log(item.description);
|
|
652
724
|
console.log();
|
|
653
725
|
}
|
|
654
|
-
|
|
655
|
-
console.log(chalk12.bold("Acceptance Criteria"));
|
|
656
|
-
for (const [i, ac] of item.acceptanceCriteria.entries()) {
|
|
657
|
-
console.log(` ${i + 1}. ${ac}`);
|
|
658
|
-
}
|
|
659
|
-
console.log();
|
|
660
|
-
}
|
|
726
|
+
printAcceptanceCriteria(item.acceptanceCriteria);
|
|
661
727
|
printPlan(item);
|
|
728
|
+
printComments(item);
|
|
729
|
+
}
|
|
730
|
+
function printComments(item) {
|
|
731
|
+
const entries = item.comments ?? [];
|
|
732
|
+
if (entries.length === 0) return;
|
|
733
|
+
console.log(chalk13.bold("Comments"));
|
|
734
|
+
for (const entry of entries) {
|
|
735
|
+
console.log(` ${formatComment(entry)}`);
|
|
736
|
+
}
|
|
737
|
+
console.log();
|
|
662
738
|
}
|
|
663
739
|
|
|
664
740
|
// src/commands/backlog/start/index.ts
|
|
665
|
-
import
|
|
741
|
+
import chalk14 from "chalk";
|
|
666
742
|
async function start(id) {
|
|
667
743
|
const name = setStatus(id, "in-progress");
|
|
668
744
|
if (name) {
|
|
669
|
-
console.log(
|
|
745
|
+
console.log(chalk14.green(`Started item #${id}: ${name}`));
|
|
670
746
|
}
|
|
671
747
|
}
|
|
672
748
|
|
|
@@ -678,7 +754,7 @@ import {
|
|
|
678
754
|
} from "http";
|
|
679
755
|
import { dirname, join as join3 } from "path";
|
|
680
756
|
import { fileURLToPath } from "url";
|
|
681
|
-
import
|
|
757
|
+
import chalk15 from "chalk";
|
|
682
758
|
function respondJson(res, status2, data) {
|
|
683
759
|
res.writeHead(status2, { "Content-Type": "application/json" });
|
|
684
760
|
res.end(JSON.stringify(data));
|
|
@@ -722,8 +798,8 @@ function startWebServer(label2, port, handler) {
|
|
|
722
798
|
handler(req, res, port);
|
|
723
799
|
});
|
|
724
800
|
server.listen(port, () => {
|
|
725
|
-
console.log(
|
|
726
|
-
console.log(
|
|
801
|
+
console.log(chalk15.green(`${label2}: ${url}`));
|
|
802
|
+
console.log(chalk15.dim("Press Ctrl+C to stop"));
|
|
727
803
|
exec(`open ${url}`);
|
|
728
804
|
});
|
|
729
805
|
}
|
|
@@ -877,7 +953,7 @@ import { execSync } from "child_process";
|
|
|
877
953
|
import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
878
954
|
import { homedir } from "os";
|
|
879
955
|
import { basename, dirname as dirname2, join as join4 } from "path";
|
|
880
|
-
import
|
|
956
|
+
import chalk16 from "chalk";
|
|
881
957
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
882
958
|
|
|
883
959
|
// src/shared/loadRawYaml.ts
|
|
@@ -1064,7 +1140,7 @@ function getTranscriptConfig() {
|
|
|
1064
1140
|
const config = loadConfig();
|
|
1065
1141
|
if (!config.transcript) {
|
|
1066
1142
|
console.error(
|
|
1067
|
-
|
|
1143
|
+
chalk16.red(
|
|
1068
1144
|
"Transcript directories not configured. Run 'assist transcript configure' first."
|
|
1069
1145
|
)
|
|
1070
1146
|
);
|
|
@@ -1153,7 +1229,7 @@ function commit(args) {
|
|
|
1153
1229
|
}
|
|
1154
1230
|
|
|
1155
1231
|
// src/commands/config/index.ts
|
|
1156
|
-
import
|
|
1232
|
+
import chalk17 from "chalk";
|
|
1157
1233
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
1158
1234
|
|
|
1159
1235
|
// src/commands/config/getNestedValue.ts
|
|
@@ -1229,7 +1305,7 @@ function formatIssuePath(issue, key) {
|
|
|
1229
1305
|
function printValidationErrors(issues, key) {
|
|
1230
1306
|
for (const issue of issues) {
|
|
1231
1307
|
console.error(
|
|
1232
|
-
|
|
1308
|
+
chalk17.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
1233
1309
|
);
|
|
1234
1310
|
}
|
|
1235
1311
|
}
|
|
@@ -1249,13 +1325,13 @@ function applyConfigSet(key, coerced) {
|
|
|
1249
1325
|
function configSet(key, value) {
|
|
1250
1326
|
const coerced = coerceValue(value);
|
|
1251
1327
|
applyConfigSet(key, coerced);
|
|
1252
|
-
console.log(
|
|
1328
|
+
console.log(chalk17.green(`Set ${key} = ${JSON.stringify(coerced)}`));
|
|
1253
1329
|
}
|
|
1254
1330
|
function formatOutput(value) {
|
|
1255
1331
|
return typeof value === "object" && value !== null ? JSON.stringify(value, null, 2) : String(value);
|
|
1256
1332
|
}
|
|
1257
1333
|
function exitKeyNotSet(key) {
|
|
1258
|
-
console.error(
|
|
1334
|
+
console.error(chalk17.red(`Key "${key}" is not set`));
|
|
1259
1335
|
process.exit(1);
|
|
1260
1336
|
}
|
|
1261
1337
|
function requireNestedValue(config, key) {
|
|
@@ -1291,10 +1367,10 @@ function coverage() {
|
|
|
1291
1367
|
}
|
|
1292
1368
|
|
|
1293
1369
|
// src/commands/verify/init/index.ts
|
|
1294
|
-
import
|
|
1370
|
+
import chalk32 from "chalk";
|
|
1295
1371
|
|
|
1296
1372
|
// src/shared/promptMultiselect.ts
|
|
1297
|
-
import
|
|
1373
|
+
import chalk18 from "chalk";
|
|
1298
1374
|
import enquirer3 from "enquirer";
|
|
1299
1375
|
async function promptMultiselect(message, options2) {
|
|
1300
1376
|
const { selected } = await enquirer3.prompt({
|
|
@@ -1303,7 +1379,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1303
1379
|
message,
|
|
1304
1380
|
choices: options2.map((opt) => ({
|
|
1305
1381
|
name: opt.value,
|
|
1306
|
-
message: `${opt.name} - ${
|
|
1382
|
+
message: `${opt.name} - ${chalk18.dim(opt.description)}`
|
|
1307
1383
|
})),
|
|
1308
1384
|
// @ts-expect-error - enquirer types don't include symbols but it's supported
|
|
1309
1385
|
symbols: {
|
|
@@ -1319,7 +1395,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1319
1395
|
// src/shared/readPackageJson.ts
|
|
1320
1396
|
import * as fs from "fs";
|
|
1321
1397
|
import * as path from "path";
|
|
1322
|
-
import
|
|
1398
|
+
import chalk19 from "chalk";
|
|
1323
1399
|
function findPackageJson() {
|
|
1324
1400
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1325
1401
|
if (fs.existsSync(packageJsonPath)) {
|
|
@@ -1333,7 +1409,7 @@ function readPackageJson(filePath) {
|
|
|
1333
1409
|
function requirePackageJson() {
|
|
1334
1410
|
const packageJsonPath = findPackageJson();
|
|
1335
1411
|
if (!packageJsonPath) {
|
|
1336
|
-
console.error(
|
|
1412
|
+
console.error(chalk19.red("No package.json found in current directory"));
|
|
1337
1413
|
process.exit(1);
|
|
1338
1414
|
}
|
|
1339
1415
|
const pkg = readPackageJson(packageJsonPath);
|
|
@@ -1364,7 +1440,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1364
1440
|
// src/commands/verify/installPackage.ts
|
|
1365
1441
|
import { execSync as execSync3 } from "child_process";
|
|
1366
1442
|
import { writeFileSync as writeFileSync4 } from "fs";
|
|
1367
|
-
import
|
|
1443
|
+
import chalk20 from "chalk";
|
|
1368
1444
|
function writePackageJson(filePath, pkg) {
|
|
1369
1445
|
writeFileSync4(filePath, `${JSON.stringify(pkg, null, 2)}
|
|
1370
1446
|
`);
|
|
@@ -1379,12 +1455,12 @@ function addScript(pkg, name, command) {
|
|
|
1379
1455
|
};
|
|
1380
1456
|
}
|
|
1381
1457
|
function installPackage(name, cwd) {
|
|
1382
|
-
console.log(
|
|
1458
|
+
console.log(chalk20.dim(`Installing ${name}...`));
|
|
1383
1459
|
try {
|
|
1384
1460
|
execSync3(`npm install -D ${name}`, { stdio: "inherit", cwd });
|
|
1385
1461
|
return true;
|
|
1386
1462
|
} catch {
|
|
1387
|
-
console.error(
|
|
1463
|
+
console.error(chalk20.red(`Failed to install ${name}`));
|
|
1388
1464
|
return false;
|
|
1389
1465
|
}
|
|
1390
1466
|
}
|
|
@@ -1431,9 +1507,9 @@ var expectedScripts = {
|
|
|
1431
1507
|
};
|
|
1432
1508
|
|
|
1433
1509
|
// src/commands/verify/setup/setupBuild.ts
|
|
1434
|
-
import
|
|
1510
|
+
import chalk21 from "chalk";
|
|
1435
1511
|
async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
1436
|
-
console.log(
|
|
1512
|
+
console.log(chalk21.blue("\nSetting up build verification..."));
|
|
1437
1513
|
let command;
|
|
1438
1514
|
if (hasVite && hasTypescript) {
|
|
1439
1515
|
command = "tsc -b && vite build --logLevel error";
|
|
@@ -1442,21 +1518,21 @@ async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
|
1442
1518
|
} else {
|
|
1443
1519
|
command = "npm run build";
|
|
1444
1520
|
}
|
|
1445
|
-
console.log(
|
|
1521
|
+
console.log(chalk21.dim(`Using: ${command}`));
|
|
1446
1522
|
writer("verify:build", command);
|
|
1447
1523
|
}
|
|
1448
1524
|
async function setupTypecheck(_packageJsonPath, writer) {
|
|
1449
|
-
console.log(
|
|
1525
|
+
console.log(chalk21.blue("\nSetting up typecheck verification..."));
|
|
1450
1526
|
const command = "tsc --noEmit";
|
|
1451
|
-
console.log(
|
|
1527
|
+
console.log(chalk21.dim(`Using: ${command}`));
|
|
1452
1528
|
writer("verify:typecheck", command);
|
|
1453
1529
|
}
|
|
1454
1530
|
|
|
1455
1531
|
// src/commands/verify/setup/setupDuplicateCode.ts
|
|
1456
1532
|
import * as path2 from "path";
|
|
1457
|
-
import
|
|
1533
|
+
import chalk22 from "chalk";
|
|
1458
1534
|
async function setupDuplicateCode(packageJsonPath, writer) {
|
|
1459
|
-
console.log(
|
|
1535
|
+
console.log(chalk22.blue("\nSetting up jscpd..."));
|
|
1460
1536
|
const cwd = path2.dirname(packageJsonPath);
|
|
1461
1537
|
const pkg = readPackageJson(packageJsonPath);
|
|
1462
1538
|
const hasJscpd = !!pkg.dependencies?.jscpd || !!pkg.devDependencies?.jscpd;
|
|
@@ -1468,12 +1544,12 @@ async function setupDuplicateCode(packageJsonPath, writer) {
|
|
|
1468
1544
|
|
|
1469
1545
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1470
1546
|
import * as path3 from "path";
|
|
1471
|
-
import
|
|
1547
|
+
import chalk24 from "chalk";
|
|
1472
1548
|
|
|
1473
1549
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
1474
1550
|
import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
1475
1551
|
import { join as join6 } from "path";
|
|
1476
|
-
import
|
|
1552
|
+
import chalk23 from "chalk";
|
|
1477
1553
|
function loadKnipConfig(knipJsonPath) {
|
|
1478
1554
|
if (existsSync7(knipJsonPath)) {
|
|
1479
1555
|
return JSON.parse(readFileSync6(knipJsonPath, "utf-8"));
|
|
@@ -1492,16 +1568,16 @@ function addToKnipIgnoreBinaries(cwd, binary) {
|
|
|
1492
1568
|
`${JSON.stringify(knipConfig, null, " ")}
|
|
1493
1569
|
`
|
|
1494
1570
|
);
|
|
1495
|
-
console.log(
|
|
1571
|
+
console.log(chalk23.dim(`Added '${binary}' to knip.json ignoreBinaries`));
|
|
1496
1572
|
}
|
|
1497
1573
|
} catch {
|
|
1498
|
-
console.log(
|
|
1574
|
+
console.log(chalk23.yellow("Warning: Could not update knip.json"));
|
|
1499
1575
|
}
|
|
1500
1576
|
}
|
|
1501
1577
|
|
|
1502
1578
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1503
1579
|
async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
1504
|
-
console.log(
|
|
1580
|
+
console.log(chalk24.blue("\nSetting up hardcoded colors check..."));
|
|
1505
1581
|
const cwd = path3.dirname(packageJsonPath);
|
|
1506
1582
|
if (!hasOpenColor) {
|
|
1507
1583
|
installPackage("open-color", cwd);
|
|
@@ -1512,9 +1588,9 @@ async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
|
1512
1588
|
|
|
1513
1589
|
// src/commands/verify/setup/setupKnip.ts
|
|
1514
1590
|
import * as path4 from "path";
|
|
1515
|
-
import
|
|
1591
|
+
import chalk25 from "chalk";
|
|
1516
1592
|
async function setupKnip(packageJsonPath, writer) {
|
|
1517
|
-
console.log(
|
|
1593
|
+
console.log(chalk25.blue("\nSetting up knip..."));
|
|
1518
1594
|
const cwd = path4.dirname(packageJsonPath);
|
|
1519
1595
|
const pkg = readPackageJson(packageJsonPath);
|
|
1520
1596
|
if (!pkg.devDependencies?.knip && !installPackage("knip", cwd)) {
|
|
@@ -1525,14 +1601,14 @@ async function setupKnip(packageJsonPath, writer) {
|
|
|
1525
1601
|
|
|
1526
1602
|
// src/commands/verify/setup/setupLint.ts
|
|
1527
1603
|
import * as path5 from "path";
|
|
1528
|
-
import
|
|
1604
|
+
import chalk28 from "chalk";
|
|
1529
1605
|
|
|
1530
1606
|
// src/commands/lint/init.ts
|
|
1531
1607
|
import { execSync as execSync5 } from "child_process";
|
|
1532
1608
|
import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
1533
1609
|
import { dirname as dirname7, join as join7 } from "path";
|
|
1534
1610
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1535
|
-
import
|
|
1611
|
+
import chalk27 from "chalk";
|
|
1536
1612
|
|
|
1537
1613
|
// src/shared/promptConfirm.ts
|
|
1538
1614
|
import enquirer4 from "enquirer";
|
|
@@ -1634,7 +1710,7 @@ function removeEslintScripts(scripts, options2) {
|
|
|
1634
1710
|
}
|
|
1635
1711
|
|
|
1636
1712
|
// src/utils/printDiff.ts
|
|
1637
|
-
import
|
|
1713
|
+
import chalk26 from "chalk";
|
|
1638
1714
|
import * as diff from "diff";
|
|
1639
1715
|
function normalizeJson(content) {
|
|
1640
1716
|
try {
|
|
@@ -1652,11 +1728,11 @@ function printDiff(oldContent, newContent) {
|
|
|
1652
1728
|
const lines = change.value.replace(/\n$/, "").split("\n");
|
|
1653
1729
|
for (const line of lines) {
|
|
1654
1730
|
if (change.added) {
|
|
1655
|
-
console.log(
|
|
1731
|
+
console.log(chalk26.green(`+ ${line}`));
|
|
1656
1732
|
} else if (change.removed) {
|
|
1657
|
-
console.log(
|
|
1733
|
+
console.log(chalk26.red(`- ${line}`));
|
|
1658
1734
|
} else {
|
|
1659
|
-
console.log(
|
|
1735
|
+
console.log(chalk26.dim(` ${line}`));
|
|
1660
1736
|
}
|
|
1661
1737
|
}
|
|
1662
1738
|
}
|
|
@@ -1690,10 +1766,10 @@ async function init() {
|
|
|
1690
1766
|
console.log("biome.json already has the correct linter config");
|
|
1691
1767
|
return;
|
|
1692
1768
|
}
|
|
1693
|
-
console.log(
|
|
1769
|
+
console.log(chalk27.yellow("\n\u26A0\uFE0F biome.json will be updated:"));
|
|
1694
1770
|
console.log();
|
|
1695
1771
|
printDiff(oldContent, newContent);
|
|
1696
|
-
const confirm = await promptConfirm(
|
|
1772
|
+
const confirm = await promptConfirm(chalk27.red("Update biome.json?"));
|
|
1697
1773
|
if (!confirm) {
|
|
1698
1774
|
console.log("Skipped biome.json update");
|
|
1699
1775
|
return;
|
|
@@ -1704,7 +1780,7 @@ async function init() {
|
|
|
1704
1780
|
|
|
1705
1781
|
// src/commands/verify/setup/setupLint.ts
|
|
1706
1782
|
async function setupLint(packageJsonPath, writer) {
|
|
1707
|
-
console.log(
|
|
1783
|
+
console.log(chalk28.blue("\nSetting up biome..."));
|
|
1708
1784
|
const cwd = path5.dirname(packageJsonPath);
|
|
1709
1785
|
const pkg = readPackageJson(packageJsonPath);
|
|
1710
1786
|
if (!pkg.devDependencies?.["@biomejs/biome"]) {
|
|
@@ -1718,9 +1794,9 @@ async function setupLint(packageJsonPath, writer) {
|
|
|
1718
1794
|
|
|
1719
1795
|
// src/commands/verify/setup/setupMadge.ts
|
|
1720
1796
|
import * as path6 from "path";
|
|
1721
|
-
import
|
|
1797
|
+
import chalk29 from "chalk";
|
|
1722
1798
|
async function setupMadge(packageJsonPath, writer) {
|
|
1723
|
-
console.log(
|
|
1799
|
+
console.log(chalk29.blue("\nSetting up madge..."));
|
|
1724
1800
|
const cwd = path6.dirname(packageJsonPath);
|
|
1725
1801
|
const pkg = readPackageJson(packageJsonPath);
|
|
1726
1802
|
const hasMadge = !!pkg.dependencies?.madge || !!pkg.devDependencies?.madge;
|
|
@@ -1732,18 +1808,18 @@ async function setupMadge(packageJsonPath, writer) {
|
|
|
1732
1808
|
|
|
1733
1809
|
// src/commands/verify/setup/setupMaintainability.ts
|
|
1734
1810
|
import * as path7 from "path";
|
|
1735
|
-
import
|
|
1811
|
+
import chalk30 from "chalk";
|
|
1736
1812
|
async function setupMaintainability(packageJsonPath, writer) {
|
|
1737
|
-
console.log(
|
|
1813
|
+
console.log(chalk30.blue("\nSetting up maintainability check..."));
|
|
1738
1814
|
addToKnipIgnoreBinaries(path7.dirname(packageJsonPath), "assist");
|
|
1739
1815
|
writer("verify:maintainability", expectedScripts["verify:maintainability"]);
|
|
1740
1816
|
}
|
|
1741
1817
|
|
|
1742
1818
|
// src/commands/verify/setup/setupTest.ts
|
|
1743
1819
|
import * as path8 from "path";
|
|
1744
|
-
import
|
|
1820
|
+
import chalk31 from "chalk";
|
|
1745
1821
|
async function setupTest(packageJsonPath, writer) {
|
|
1746
|
-
console.log(
|
|
1822
|
+
console.log(chalk31.blue("\nSetting up vitest..."));
|
|
1747
1823
|
const cwd = path8.dirname(packageJsonPath);
|
|
1748
1824
|
const pkg = readPackageJson(packageJsonPath);
|
|
1749
1825
|
if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
|
|
@@ -1912,25 +1988,25 @@ async function runSelectedSetups(selected, packageJsonPath, writer, handlers) {
|
|
|
1912
1988
|
for (const choice of selected) {
|
|
1913
1989
|
await handlers[choice]?.(packageJsonPath, writer);
|
|
1914
1990
|
}
|
|
1915
|
-
console.log(
|
|
1991
|
+
console.log(chalk32.green(`
|
|
1916
1992
|
Added ${selected.length} verify script(s):`));
|
|
1917
1993
|
for (const choice of selected) {
|
|
1918
|
-
console.log(
|
|
1994
|
+
console.log(chalk32.green(` - verify:${choice}`));
|
|
1919
1995
|
}
|
|
1920
|
-
console.log(
|
|
1996
|
+
console.log(chalk32.dim("\nRun 'assist verify' to run all verify scripts"));
|
|
1921
1997
|
}
|
|
1922
1998
|
async function promptForScripts(availableOptions) {
|
|
1923
1999
|
if (availableOptions.length === 0) {
|
|
1924
|
-
console.log(
|
|
2000
|
+
console.log(chalk32.green("All verify scripts are already configured!"));
|
|
1925
2001
|
return null;
|
|
1926
2002
|
}
|
|
1927
|
-
console.log(
|
|
2003
|
+
console.log(chalk32.bold("Available verify scripts to add:\n"));
|
|
1928
2004
|
const selected = await promptMultiselect(
|
|
1929
2005
|
"Select verify scripts to add:",
|
|
1930
2006
|
availableOptions
|
|
1931
2007
|
);
|
|
1932
2008
|
if (selected.length === 0) {
|
|
1933
|
-
console.log(
|
|
2009
|
+
console.log(chalk32.yellow("No scripts selected"));
|
|
1934
2010
|
return null;
|
|
1935
2011
|
}
|
|
1936
2012
|
return selected;
|
|
@@ -1950,17 +2026,17 @@ async function init2() {
|
|
|
1950
2026
|
}
|
|
1951
2027
|
|
|
1952
2028
|
// src/commands/vscode/init/index.ts
|
|
1953
|
-
import
|
|
2029
|
+
import chalk34 from "chalk";
|
|
1954
2030
|
|
|
1955
2031
|
// src/commands/vscode/init/createLaunchJson.ts
|
|
1956
2032
|
import * as fs2 from "fs";
|
|
1957
2033
|
import * as path9 from "path";
|
|
1958
|
-
import
|
|
2034
|
+
import chalk33 from "chalk";
|
|
1959
2035
|
function ensureVscodeFolder() {
|
|
1960
2036
|
const vscodeDir = path9.join(process.cwd(), ".vscode");
|
|
1961
2037
|
if (!fs2.existsSync(vscodeDir)) {
|
|
1962
2038
|
fs2.mkdirSync(vscodeDir);
|
|
1963
|
-
console.log(
|
|
2039
|
+
console.log(chalk33.dim("Created .vscode folder"));
|
|
1964
2040
|
}
|
|
1965
2041
|
}
|
|
1966
2042
|
function removeVscodeFromGitignore() {
|
|
@@ -1975,7 +2051,7 @@ function removeVscodeFromGitignore() {
|
|
|
1975
2051
|
);
|
|
1976
2052
|
if (filteredLines.length !== lines.length) {
|
|
1977
2053
|
fs2.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
1978
|
-
console.log(
|
|
2054
|
+
console.log(chalk33.dim("Removed .vscode references from .gitignore"));
|
|
1979
2055
|
}
|
|
1980
2056
|
}
|
|
1981
2057
|
function createLaunchJson(type) {
|
|
@@ -1994,7 +2070,7 @@ function createLaunchJson(type) {
|
|
|
1994
2070
|
const launchPath = path9.join(process.cwd(), ".vscode", "launch.json");
|
|
1995
2071
|
fs2.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
|
|
1996
2072
|
`);
|
|
1997
|
-
console.log(
|
|
2073
|
+
console.log(chalk33.green("Created .vscode/launch.json"));
|
|
1998
2074
|
}
|
|
1999
2075
|
function createSettingsJson() {
|
|
2000
2076
|
const settings = {
|
|
@@ -2007,7 +2083,7 @@ function createSettingsJson() {
|
|
|
2007
2083
|
const settingsPath = path9.join(process.cwd(), ".vscode", "settings.json");
|
|
2008
2084
|
fs2.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
|
|
2009
2085
|
`);
|
|
2010
|
-
console.log(
|
|
2086
|
+
console.log(chalk33.green("Created .vscode/settings.json"));
|
|
2011
2087
|
}
|
|
2012
2088
|
function createExtensionsJson() {
|
|
2013
2089
|
const extensions = {
|
|
@@ -2019,7 +2095,7 @@ function createExtensionsJson() {
|
|
|
2019
2095
|
`${JSON.stringify(extensions, null, " ")}
|
|
2020
2096
|
`
|
|
2021
2097
|
);
|
|
2022
|
-
console.log(
|
|
2098
|
+
console.log(chalk33.green("Created .vscode/extensions.json"));
|
|
2023
2099
|
}
|
|
2024
2100
|
|
|
2025
2101
|
// src/commands/vscode/init/detectVscodeSetup.ts
|
|
@@ -2076,7 +2152,7 @@ function applySelections(selected, setup2) {
|
|
|
2076
2152
|
for (const choice of selected) handlers[choice]?.();
|
|
2077
2153
|
}
|
|
2078
2154
|
async function promptForOptions(options2) {
|
|
2079
|
-
console.log(
|
|
2155
|
+
console.log(chalk34.bold("Available VS Code configurations to add:\n"));
|
|
2080
2156
|
return promptMultiselect("Select configurations to add:", options2);
|
|
2081
2157
|
}
|
|
2082
2158
|
async function init3({ all = false } = {}) {
|
|
@@ -2084,17 +2160,17 @@ async function init3({ all = false } = {}) {
|
|
|
2084
2160
|
const setup2 = detectVscodeSetup(pkg);
|
|
2085
2161
|
const options2 = getAvailableOptions2(setup2);
|
|
2086
2162
|
if (options2.length === 0) {
|
|
2087
|
-
console.log(
|
|
2163
|
+
console.log(chalk34.green("VS Code configuration already exists!"));
|
|
2088
2164
|
return;
|
|
2089
2165
|
}
|
|
2090
2166
|
const selected = all ? options2.map((o) => o.value) : await promptForOptions(options2);
|
|
2091
2167
|
if (selected.length === 0) {
|
|
2092
|
-
console.log(
|
|
2168
|
+
console.log(chalk34.yellow("No configurations selected"));
|
|
2093
2169
|
return;
|
|
2094
2170
|
}
|
|
2095
2171
|
applySelections(selected, setup2);
|
|
2096
2172
|
console.log(
|
|
2097
|
-
|
|
2173
|
+
chalk34.green(`
|
|
2098
2174
|
Added ${selected.length} VS Code configuration(s)`)
|
|
2099
2175
|
);
|
|
2100
2176
|
}
|
|
@@ -2107,7 +2183,7 @@ async function init4() {
|
|
|
2107
2183
|
|
|
2108
2184
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2109
2185
|
import path16 from "path";
|
|
2110
|
-
import
|
|
2186
|
+
import chalk36 from "chalk";
|
|
2111
2187
|
|
|
2112
2188
|
// src/commands/lint/lint/checkFileNames.ts
|
|
2113
2189
|
import fs5 from "fs";
|
|
@@ -2187,7 +2263,7 @@ function checkFileNames() {
|
|
|
2187
2263
|
}
|
|
2188
2264
|
|
|
2189
2265
|
// src/commands/lint/lint/fixFileNameViolations.ts
|
|
2190
|
-
import
|
|
2266
|
+
import chalk35 from "chalk";
|
|
2191
2267
|
|
|
2192
2268
|
// src/commands/lint/lint/applyMoves.ts
|
|
2193
2269
|
import fs6 from "fs";
|
|
@@ -2272,25 +2348,25 @@ function fixFileNameViolations(moves) {
|
|
|
2272
2348
|
const start3 = performance.now();
|
|
2273
2349
|
const project = createLintProject();
|
|
2274
2350
|
const cwd = process.cwd();
|
|
2275
|
-
applyMoves(project, moves, cwd, (line) => console.log(
|
|
2351
|
+
applyMoves(project, moves, cwd, (line) => console.log(chalk35.green(line)));
|
|
2276
2352
|
const ms = (performance.now() - start3).toFixed(0);
|
|
2277
|
-
console.log(
|
|
2353
|
+
console.log(chalk35.dim(` Done in ${ms}ms`));
|
|
2278
2354
|
}
|
|
2279
2355
|
|
|
2280
2356
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2281
2357
|
function reportViolations(violations) {
|
|
2282
|
-
console.error(
|
|
2358
|
+
console.error(chalk36.red("\nFile name check failed:\n"));
|
|
2283
2359
|
console.error(
|
|
2284
|
-
|
|
2360
|
+
chalk36.red(
|
|
2285
2361
|
" Files without classes or React components should not start with a capital letter.\n"
|
|
2286
2362
|
)
|
|
2287
2363
|
);
|
|
2288
2364
|
for (const violation of violations) {
|
|
2289
|
-
console.error(
|
|
2290
|
-
console.error(
|
|
2365
|
+
console.error(chalk36.red(` ${violation.filePath}`));
|
|
2366
|
+
console.error(chalk36.gray(` Rename to: ${violation.suggestedName}
|
|
2291
2367
|
`));
|
|
2292
2368
|
}
|
|
2293
|
-
console.error(
|
|
2369
|
+
console.error(chalk36.dim(" Run with -f to auto-fix.\n"));
|
|
2294
2370
|
}
|
|
2295
2371
|
function runFileNameCheck(fix = false) {
|
|
2296
2372
|
const violations = checkFileNames();
|
|
@@ -2319,17 +2395,17 @@ function runFileNameCheck(fix = false) {
|
|
|
2319
2395
|
import fs8 from "fs";
|
|
2320
2396
|
|
|
2321
2397
|
// src/commands/lint/shared.ts
|
|
2322
|
-
import
|
|
2398
|
+
import chalk37 from "chalk";
|
|
2323
2399
|
function reportViolations2(violations, checkName, errorMessage, successMessage) {
|
|
2324
2400
|
if (violations.length > 0) {
|
|
2325
|
-
console.error(
|
|
2401
|
+
console.error(chalk37.red(`
|
|
2326
2402
|
${checkName} failed:
|
|
2327
2403
|
`));
|
|
2328
|
-
console.error(
|
|
2404
|
+
console.error(chalk37.red(` ${errorMessage}
|
|
2329
2405
|
`));
|
|
2330
2406
|
for (const violation of violations) {
|
|
2331
|
-
console.error(
|
|
2332
|
-
console.error(
|
|
2407
|
+
console.error(chalk37.red(` ${violation.filePath}:${violation.line}`));
|
|
2408
|
+
console.error(chalk37.gray(` ${violation.content}
|
|
2333
2409
|
`));
|
|
2334
2410
|
}
|
|
2335
2411
|
return false;
|
|
@@ -2809,14 +2885,14 @@ import { existsSync as existsSync14, readFileSync as readFileSync11, writeFileSy
|
|
|
2809
2885
|
|
|
2810
2886
|
// src/commands/deploy/init/index.ts
|
|
2811
2887
|
import { execSync as execSync12 } from "child_process";
|
|
2812
|
-
import
|
|
2888
|
+
import chalk39 from "chalk";
|
|
2813
2889
|
import enquirer5 from "enquirer";
|
|
2814
2890
|
|
|
2815
2891
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
2816
2892
|
import { existsSync as existsSync13, mkdirSync as mkdirSync3, readFileSync as readFileSync10, writeFileSync as writeFileSync11 } from "fs";
|
|
2817
2893
|
import { dirname as dirname13, join as join10 } from "path";
|
|
2818
2894
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2819
|
-
import
|
|
2895
|
+
import chalk38 from "chalk";
|
|
2820
2896
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
2821
2897
|
var __dirname3 = dirname13(fileURLToPath3(import.meta.url));
|
|
2822
2898
|
function getExistingSiteId() {
|
|
@@ -2841,20 +2917,20 @@ async function updateWorkflow(siteId) {
|
|
|
2841
2917
|
if (existsSync13(WORKFLOW_PATH)) {
|
|
2842
2918
|
const oldContent = readFileSync10(WORKFLOW_PATH, "utf-8");
|
|
2843
2919
|
if (oldContent === newContent) {
|
|
2844
|
-
console.log(
|
|
2920
|
+
console.log(chalk38.green("build.yml is already up to date"));
|
|
2845
2921
|
return;
|
|
2846
2922
|
}
|
|
2847
|
-
console.log(
|
|
2923
|
+
console.log(chalk38.yellow("\nbuild.yml will be updated:"));
|
|
2848
2924
|
console.log();
|
|
2849
2925
|
printDiff(oldContent, newContent);
|
|
2850
|
-
const confirm = await promptConfirm(
|
|
2926
|
+
const confirm = await promptConfirm(chalk38.red("Update build.yml?"));
|
|
2851
2927
|
if (!confirm) {
|
|
2852
2928
|
console.log("Skipped build.yml update");
|
|
2853
2929
|
return;
|
|
2854
2930
|
}
|
|
2855
2931
|
}
|
|
2856
2932
|
writeFileSync11(WORKFLOW_PATH, newContent);
|
|
2857
|
-
console.log(
|
|
2933
|
+
console.log(chalk38.green(`
|
|
2858
2934
|
Created ${WORKFLOW_PATH}`));
|
|
2859
2935
|
}
|
|
2860
2936
|
|
|
@@ -2865,43 +2941,43 @@ async function ensureNetlifyCli() {
|
|
|
2865
2941
|
} catch (error) {
|
|
2866
2942
|
if (!(error instanceof Error) || !error.message.includes("command not found"))
|
|
2867
2943
|
throw error;
|
|
2868
|
-
console.error(
|
|
2944
|
+
console.error(chalk39.red("\nNetlify CLI is not installed.\n"));
|
|
2869
2945
|
const install = await promptConfirm("Would you like to install it now?");
|
|
2870
2946
|
if (!install) {
|
|
2871
2947
|
console.log(
|
|
2872
|
-
|
|
2948
|
+
chalk39.yellow(
|
|
2873
2949
|
"\nInstall it manually with: npm install -g netlify-cli\n"
|
|
2874
2950
|
)
|
|
2875
2951
|
);
|
|
2876
2952
|
process.exit(1);
|
|
2877
2953
|
}
|
|
2878
|
-
console.log(
|
|
2954
|
+
console.log(chalk39.dim("\nInstalling netlify-cli...\n"));
|
|
2879
2955
|
execSync12("npm install -g netlify-cli", { stdio: "inherit" });
|
|
2880
2956
|
console.log();
|
|
2881
2957
|
execSync12("netlify sites:create --disable-linking", { stdio: "inherit" });
|
|
2882
2958
|
}
|
|
2883
2959
|
}
|
|
2884
2960
|
function printSetupInstructions() {
|
|
2885
|
-
console.log(
|
|
2961
|
+
console.log(chalk39.bold("\nDeployment initialized successfully!"));
|
|
2886
2962
|
console.log(
|
|
2887
|
-
|
|
2963
|
+
chalk39.yellow("\nTo complete setup, create a personal access token at:")
|
|
2888
2964
|
);
|
|
2889
2965
|
console.log(
|
|
2890
|
-
|
|
2966
|
+
chalk39.cyan(
|
|
2891
2967
|
"https://app.netlify.com/user/applications#personal-access-tokens"
|
|
2892
2968
|
)
|
|
2893
2969
|
);
|
|
2894
2970
|
console.log(
|
|
2895
|
-
|
|
2971
|
+
chalk39.yellow(
|
|
2896
2972
|
"\nThen add it as NETLIFY_AUTH_TOKEN in your GitHub repository secrets."
|
|
2897
2973
|
)
|
|
2898
2974
|
);
|
|
2899
2975
|
}
|
|
2900
2976
|
async function init5() {
|
|
2901
|
-
console.log(
|
|
2977
|
+
console.log(chalk39.bold("Initializing Netlify deployment...\n"));
|
|
2902
2978
|
const existingSiteId = getExistingSiteId();
|
|
2903
2979
|
if (existingSiteId) {
|
|
2904
|
-
console.log(
|
|
2980
|
+
console.log(chalk39.dim(`Using existing site ID: ${existingSiteId}
|
|
2905
2981
|
`));
|
|
2906
2982
|
await updateWorkflow(existingSiteId);
|
|
2907
2983
|
return;
|
|
@@ -3079,9 +3155,58 @@ async function notify() {
|
|
|
3079
3155
|
console.log(`Notification sent: ${notification_type} for ${projectName}`);
|
|
3080
3156
|
}
|
|
3081
3157
|
|
|
3158
|
+
// src/commands/backlog/comment/index.ts
|
|
3159
|
+
import chalk40 from "chalk";
|
|
3160
|
+
function comment(id, text) {
|
|
3161
|
+
const result = loadAndFindItem(id);
|
|
3162
|
+
if (!result) process.exit(1);
|
|
3163
|
+
addComment(result.item, text);
|
|
3164
|
+
saveBacklog(result.items);
|
|
3165
|
+
console.log(chalk40.green(`Comment added to item #${id}.`));
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
// src/commands/backlog/comments/index.ts
|
|
3169
|
+
import chalk41 from "chalk";
|
|
3170
|
+
function comments(id) {
|
|
3171
|
+
const result = loadAndFindItem(id);
|
|
3172
|
+
if (!result) process.exit(1);
|
|
3173
|
+
const { item } = result;
|
|
3174
|
+
const entries = item.comments ?? [];
|
|
3175
|
+
if (entries.length === 0) {
|
|
3176
|
+
console.log(chalk41.dim(`No comments on item #${id}.`));
|
|
3177
|
+
return;
|
|
3178
|
+
}
|
|
3179
|
+
console.log(chalk41.bold(`Comments for #${id}: ${item.name}
|
|
3180
|
+
`));
|
|
3181
|
+
for (const entry of entries) {
|
|
3182
|
+
console.log(`${formatComment(entry)}
|
|
3183
|
+
`);
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
|
|
3187
|
+
// src/commands/backlog/registerCommentCommands.ts
|
|
3188
|
+
function registerCommentCommands(cmd) {
|
|
3189
|
+
cmd.command("comment <id> <text>").description("Add a comment to a backlog item").action(comment);
|
|
3190
|
+
cmd.command("comments <id>").description("List comments and summaries for a backlog item").action(comments);
|
|
3191
|
+
}
|
|
3192
|
+
|
|
3082
3193
|
// src/commands/backlog/add/index.ts
|
|
3083
3194
|
import { existsSync as existsSync15 } from "fs";
|
|
3084
|
-
import
|
|
3195
|
+
import chalk43 from "chalk";
|
|
3196
|
+
|
|
3197
|
+
// src/commands/backlog/commitBacklog.ts
|
|
3198
|
+
import { execSync as execSync14 } from "child_process";
|
|
3199
|
+
import chalk42 from "chalk";
|
|
3200
|
+
function commitBacklog(id, name) {
|
|
3201
|
+
try {
|
|
3202
|
+
const backlogPath = getBacklogPath();
|
|
3203
|
+
const message = `chore: add backlog item #${id} \u2014 ${name}`;
|
|
3204
|
+
execSync14(`git add ${shellQuote(backlogPath)}`, { stdio: "ignore" });
|
|
3205
|
+
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3206
|
+
} catch {
|
|
3207
|
+
console.log(chalk42.yellow("Warning: could not auto-commit backlog file."));
|
|
3208
|
+
}
|
|
3209
|
+
}
|
|
3085
3210
|
|
|
3086
3211
|
// src/commands/backlog/add/shared.ts
|
|
3087
3212
|
import { spawnSync } from "child_process";
|
|
@@ -3157,7 +3282,7 @@ async function promptAcceptanceCriteria() {
|
|
|
3157
3282
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3158
3283
|
async function addFromJson() {
|
|
3159
3284
|
if (process.stdin.isTTY) {
|
|
3160
|
-
console.log(
|
|
3285
|
+
console.log(chalk43.red("--json requires piped input on stdin."));
|
|
3161
3286
|
return;
|
|
3162
3287
|
}
|
|
3163
3288
|
const input = await readStdin();
|
|
@@ -3170,7 +3295,8 @@ async function addFromJson() {
|
|
|
3170
3295
|
const id = getNextId(items);
|
|
3171
3296
|
items.push({ ...data, id, status: "todo" });
|
|
3172
3297
|
saveBacklog(items);
|
|
3173
|
-
|
|
3298
|
+
commitBacklog(id, data.name);
|
|
3299
|
+
console.log(chalk43.green(`Added item #${id}: ${data.name}`));
|
|
3174
3300
|
}
|
|
3175
3301
|
async function addInteractive() {
|
|
3176
3302
|
const type = await promptType();
|
|
@@ -3188,12 +3314,13 @@ async function addInteractive() {
|
|
|
3188
3314
|
status: "todo"
|
|
3189
3315
|
});
|
|
3190
3316
|
saveBacklog(items);
|
|
3191
|
-
|
|
3317
|
+
commitBacklog(id, name);
|
|
3318
|
+
console.log(chalk43.green(`Added item #${id}: ${name}`));
|
|
3192
3319
|
}
|
|
3193
3320
|
async function add(options2) {
|
|
3194
3321
|
if (!existsSync15(getBacklogPath())) {
|
|
3195
3322
|
console.log(
|
|
3196
|
-
|
|
3323
|
+
chalk43.yellow(
|
|
3197
3324
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3198
3325
|
)
|
|
3199
3326
|
);
|
|
@@ -3208,20 +3335,20 @@ async function add(options2) {
|
|
|
3208
3335
|
|
|
3209
3336
|
// src/commands/backlog/init/index.ts
|
|
3210
3337
|
import { existsSync as existsSync16 } from "fs";
|
|
3211
|
-
import
|
|
3338
|
+
import chalk44 from "chalk";
|
|
3212
3339
|
async function init6() {
|
|
3213
3340
|
const backlogPath = getBacklogPath();
|
|
3214
3341
|
if (existsSync16(backlogPath)) {
|
|
3215
|
-
console.log(
|
|
3342
|
+
console.log(chalk44.yellow("assist.backlog.yml already exists."));
|
|
3216
3343
|
return;
|
|
3217
3344
|
}
|
|
3218
3345
|
saveBacklog([]);
|
|
3219
|
-
console.log(
|
|
3346
|
+
console.log(chalk44.green("Created assist.backlog.yml"));
|
|
3220
3347
|
}
|
|
3221
3348
|
|
|
3222
3349
|
// src/commands/backlog/list/index.ts
|
|
3223
3350
|
import { existsSync as existsSync17 } from "fs";
|
|
3224
|
-
import
|
|
3351
|
+
import chalk45 from "chalk";
|
|
3225
3352
|
function filterItems(items, options2) {
|
|
3226
3353
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3227
3354
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
@@ -3230,7 +3357,7 @@ function filterItems(items, options2) {
|
|
|
3230
3357
|
async function list2(options2) {
|
|
3231
3358
|
if (!existsSync17(getBacklogPath())) {
|
|
3232
3359
|
console.log(
|
|
3233
|
-
|
|
3360
|
+
chalk45.yellow(
|
|
3234
3361
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3235
3362
|
)
|
|
3236
3363
|
);
|
|
@@ -3238,12 +3365,12 @@ async function list2(options2) {
|
|
|
3238
3365
|
}
|
|
3239
3366
|
const items = filterItems(loadBacklog(), options2);
|
|
3240
3367
|
if (items.length === 0) {
|
|
3241
|
-
console.log(
|
|
3368
|
+
console.log(chalk45.dim("Backlog is empty."));
|
|
3242
3369
|
return;
|
|
3243
3370
|
}
|
|
3244
3371
|
for (const item of items) {
|
|
3245
3372
|
console.log(
|
|
3246
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3373
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk45.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
|
|
3247
3374
|
);
|
|
3248
3375
|
if (options2.verbose) {
|
|
3249
3376
|
printVerboseDetails(item);
|
|
@@ -3266,16 +3393,20 @@ function registerStatusCommands(cmd) {
|
|
|
3266
3393
|
cmd.command("start <id>").description("Set a backlog item to in-progress").action(start);
|
|
3267
3394
|
cmd.command("done <id>").description("Set a backlog item to done").action(done);
|
|
3268
3395
|
cmd.command("delete <id>").alias("remove").description("Delete a backlog item").action(del);
|
|
3396
|
+
}
|
|
3397
|
+
function registerWebCommand(cmd) {
|
|
3269
3398
|
cmd.command("web").description("Start a web view of the backlog").option("-p, --port <number>", "Port to listen on", "3000").action(web);
|
|
3270
3399
|
}
|
|
3271
3400
|
function registerPlanCommands(cmd) {
|
|
3272
3401
|
cmd.command("plan <id>").description("Display the plan for a backlog item").action(plan);
|
|
3273
|
-
cmd.command("phase-done <id> <phase>").description("Signal that a plan phase is complete").action(phaseDone);
|
|
3402
|
+
cmd.command("phase-done <id> <phase> <summary>").description("Signal that a plan phase is complete").action(phaseDone);
|
|
3274
3403
|
}
|
|
3275
|
-
function
|
|
3404
|
+
function registerNextCommand(cmd) {
|
|
3276
3405
|
cmd.command("next").description("Pick and run the next backlog item, or open /draft if none").option("-w, --write", "Run Claude with acceptEdits permission mode").action(
|
|
3277
3406
|
(opts) => next({ allowEdits: opts.write })
|
|
3278
3407
|
);
|
|
3408
|
+
}
|
|
3409
|
+
function registerRunCommand(cmd) {
|
|
3279
3410
|
cmd.command("run <id>").description("Run a backlog item's plan phase-by-phase with Claude").option("-w, --write", "Run Claude with acceptEdits permission mode").action(
|
|
3280
3411
|
(id, opts) => run(id, { allowEdits: opts.write })
|
|
3281
3412
|
);
|
|
@@ -3285,8 +3416,11 @@ function registerBacklog(program2) {
|
|
|
3285
3416
|
registerItemCommands(cmd);
|
|
3286
3417
|
registerShowCommands(cmd);
|
|
3287
3418
|
registerStatusCommands(cmd);
|
|
3419
|
+
registerWebCommand(cmd);
|
|
3420
|
+
registerCommentCommands(cmd);
|
|
3288
3421
|
registerPlanCommands(cmd);
|
|
3289
|
-
|
|
3422
|
+
registerNextCommand(cmd);
|
|
3423
|
+
registerRunCommand(cmd);
|
|
3290
3424
|
}
|
|
3291
3425
|
|
|
3292
3426
|
// src/shared/isApprovedRead.ts
|
|
@@ -3597,7 +3731,7 @@ import { homedir as homedir4 } from "os";
|
|
|
3597
3731
|
import { join as join13 } from "path";
|
|
3598
3732
|
|
|
3599
3733
|
// src/shared/getInstallDir.ts
|
|
3600
|
-
import { execSync as
|
|
3734
|
+
import { execSync as execSync15 } from "child_process";
|
|
3601
3735
|
import { dirname as dirname15, resolve as resolve4 } from "path";
|
|
3602
3736
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
3603
3737
|
var __filename3 = fileURLToPath5(import.meta.url);
|
|
@@ -3607,7 +3741,7 @@ function getInstallDir() {
|
|
|
3607
3741
|
}
|
|
3608
3742
|
function isGitRepo(dir) {
|
|
3609
3743
|
try {
|
|
3610
|
-
const result =
|
|
3744
|
+
const result = execSync15("git rev-parse --show-toplevel", {
|
|
3611
3745
|
cwd: dir,
|
|
3612
3746
|
stdio: "pipe"
|
|
3613
3747
|
}).toString().trim();
|
|
@@ -3618,7 +3752,7 @@ function isGitRepo(dir) {
|
|
|
3618
3752
|
}
|
|
3619
3753
|
|
|
3620
3754
|
// src/commands/permitCliReads/assertCliExists.ts
|
|
3621
|
-
import { execSync as
|
|
3755
|
+
import { execSync as execSync16 } from "child_process";
|
|
3622
3756
|
function assertCliExists(cli) {
|
|
3623
3757
|
const binary = cli.split(/\s+/)[0];
|
|
3624
3758
|
const opts = {
|
|
@@ -3626,10 +3760,10 @@ function assertCliExists(cli) {
|
|
|
3626
3760
|
stdio: ["ignore", "pipe", "pipe"]
|
|
3627
3761
|
};
|
|
3628
3762
|
try {
|
|
3629
|
-
|
|
3763
|
+
execSync16(`command -v ${binary}`, opts);
|
|
3630
3764
|
} catch {
|
|
3631
3765
|
try {
|
|
3632
|
-
|
|
3766
|
+
execSync16(`where ${binary}`, opts);
|
|
3633
3767
|
} catch {
|
|
3634
3768
|
console.error(`CLI "${cli}" not found in PATH`);
|
|
3635
3769
|
process.exit(1);
|
|
@@ -3638,11 +3772,11 @@ function assertCliExists(cli) {
|
|
|
3638
3772
|
}
|
|
3639
3773
|
|
|
3640
3774
|
// src/commands/permitCliReads/colorize.ts
|
|
3641
|
-
import
|
|
3775
|
+
import chalk46 from "chalk";
|
|
3642
3776
|
function colorize(plainOutput) {
|
|
3643
3777
|
return plainOutput.split("\n").map((line) => {
|
|
3644
|
-
if (line.startsWith(" R ")) return
|
|
3645
|
-
if (line.startsWith(" W ")) return
|
|
3778
|
+
if (line.startsWith(" R ")) return chalk46.green(line);
|
|
3779
|
+
if (line.startsWith(" W ")) return chalk46.red(line);
|
|
3646
3780
|
return line;
|
|
3647
3781
|
}).join("\n");
|
|
3648
3782
|
}
|
|
@@ -3956,15 +4090,15 @@ function registerCliHook(program2) {
|
|
|
3956
4090
|
}
|
|
3957
4091
|
|
|
3958
4092
|
// src/commands/complexity/analyze.ts
|
|
3959
|
-
import
|
|
4093
|
+
import chalk52 from "chalk";
|
|
3960
4094
|
|
|
3961
4095
|
// src/commands/complexity/cyclomatic.ts
|
|
3962
|
-
import
|
|
4096
|
+
import chalk48 from "chalk";
|
|
3963
4097
|
|
|
3964
4098
|
// src/commands/complexity/shared/index.ts
|
|
3965
4099
|
import fs12 from "fs";
|
|
3966
4100
|
import path20 from "path";
|
|
3967
|
-
import
|
|
4101
|
+
import chalk47 from "chalk";
|
|
3968
4102
|
import ts5 from "typescript";
|
|
3969
4103
|
|
|
3970
4104
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4210,7 +4344,7 @@ function createSourceFromFile(filePath) {
|
|
|
4210
4344
|
function withSourceFiles(pattern2, callback) {
|
|
4211
4345
|
const files = findSourceFiles2(pattern2);
|
|
4212
4346
|
if (files.length === 0) {
|
|
4213
|
-
console.log(
|
|
4347
|
+
console.log(chalk47.yellow("No files found matching pattern"));
|
|
4214
4348
|
return void 0;
|
|
4215
4349
|
}
|
|
4216
4350
|
return callback(files);
|
|
@@ -4243,11 +4377,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4243
4377
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4244
4378
|
for (const { file, name, complexity } of results) {
|
|
4245
4379
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4246
|
-
const color = exceedsThreshold ?
|
|
4247
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4380
|
+
const color = exceedsThreshold ? chalk48.red : chalk48.white;
|
|
4381
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk48.cyan(complexity)}`);
|
|
4248
4382
|
}
|
|
4249
4383
|
console.log(
|
|
4250
|
-
|
|
4384
|
+
chalk48.dim(
|
|
4251
4385
|
`
|
|
4252
4386
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4253
4387
|
)
|
|
@@ -4259,7 +4393,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4259
4393
|
}
|
|
4260
4394
|
|
|
4261
4395
|
// src/commands/complexity/halstead.ts
|
|
4262
|
-
import
|
|
4396
|
+
import chalk49 from "chalk";
|
|
4263
4397
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4264
4398
|
withSourceFiles(pattern2, (files) => {
|
|
4265
4399
|
const results = [];
|
|
@@ -4274,13 +4408,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4274
4408
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4275
4409
|
for (const { file, name, metrics } of results) {
|
|
4276
4410
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4277
|
-
const color = exceedsThreshold ?
|
|
4411
|
+
const color = exceedsThreshold ? chalk49.red : chalk49.white;
|
|
4278
4412
|
console.log(
|
|
4279
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4413
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk49.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk49.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk49.magenta(metrics.effort.toFixed(1))}`
|
|
4280
4414
|
);
|
|
4281
4415
|
}
|
|
4282
4416
|
console.log(
|
|
4283
|
-
|
|
4417
|
+
chalk49.dim(
|
|
4284
4418
|
`
|
|
4285
4419
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4286
4420
|
)
|
|
@@ -4295,28 +4429,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4295
4429
|
import fs13 from "fs";
|
|
4296
4430
|
|
|
4297
4431
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4298
|
-
import
|
|
4432
|
+
import chalk50 from "chalk";
|
|
4299
4433
|
function displayMaintainabilityResults(results, threshold) {
|
|
4300
4434
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4301
4435
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4302
|
-
console.log(
|
|
4436
|
+
console.log(chalk50.green("All files pass maintainability threshold"));
|
|
4303
4437
|
} else {
|
|
4304
4438
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4305
|
-
const color = threshold !== void 0 ?
|
|
4439
|
+
const color = threshold !== void 0 ? chalk50.red : chalk50.white;
|
|
4306
4440
|
console.log(
|
|
4307
|
-
`${color(file)} \u2192 avg: ${
|
|
4441
|
+
`${color(file)} \u2192 avg: ${chalk50.cyan(avgMaintainability.toFixed(1))}, min: ${chalk50.yellow(minMaintainability.toFixed(1))}`
|
|
4308
4442
|
);
|
|
4309
4443
|
}
|
|
4310
4444
|
}
|
|
4311
|
-
console.log(
|
|
4445
|
+
console.log(chalk50.dim(`
|
|
4312
4446
|
Analyzed ${results.length} files`));
|
|
4313
4447
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4314
4448
|
console.error(
|
|
4315
|
-
|
|
4449
|
+
chalk50.red(
|
|
4316
4450
|
`
|
|
4317
4451
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4318
4452
|
|
|
4319
|
-
\u26A0\uFE0F ${
|
|
4453
|
+
\u26A0\uFE0F ${chalk50.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.`
|
|
4320
4454
|
)
|
|
4321
4455
|
);
|
|
4322
4456
|
process.exit(1);
|
|
@@ -4373,7 +4507,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4373
4507
|
|
|
4374
4508
|
// src/commands/complexity/sloc.ts
|
|
4375
4509
|
import fs14 from "fs";
|
|
4376
|
-
import
|
|
4510
|
+
import chalk51 from "chalk";
|
|
4377
4511
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4378
4512
|
withSourceFiles(pattern2, (files) => {
|
|
4379
4513
|
const results = [];
|
|
@@ -4389,12 +4523,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4389
4523
|
results.sort((a, b) => b.lines - a.lines);
|
|
4390
4524
|
for (const { file, lines } of results) {
|
|
4391
4525
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4392
|
-
const color = exceedsThreshold ?
|
|
4393
|
-
console.log(`${color(file)} \u2192 ${
|
|
4526
|
+
const color = exceedsThreshold ? chalk51.red : chalk51.white;
|
|
4527
|
+
console.log(`${color(file)} \u2192 ${chalk51.cyan(lines)} lines`);
|
|
4394
4528
|
}
|
|
4395
4529
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4396
4530
|
console.log(
|
|
4397
|
-
|
|
4531
|
+
chalk51.dim(`
|
|
4398
4532
|
Total: ${total} lines across ${files.length} files`)
|
|
4399
4533
|
);
|
|
4400
4534
|
if (hasViolation) {
|
|
@@ -4408,21 +4542,21 @@ async function analyze(pattern2) {
|
|
|
4408
4542
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4409
4543
|
const files = findSourceFiles2(searchPattern);
|
|
4410
4544
|
if (files.length === 0) {
|
|
4411
|
-
console.log(
|
|
4545
|
+
console.log(chalk52.yellow("No files found matching pattern"));
|
|
4412
4546
|
return;
|
|
4413
4547
|
}
|
|
4414
4548
|
if (files.length === 1) {
|
|
4415
4549
|
const file = files[0];
|
|
4416
|
-
console.log(
|
|
4550
|
+
console.log(chalk52.bold.underline("SLOC"));
|
|
4417
4551
|
await sloc(file);
|
|
4418
4552
|
console.log();
|
|
4419
|
-
console.log(
|
|
4553
|
+
console.log(chalk52.bold.underline("Cyclomatic Complexity"));
|
|
4420
4554
|
await cyclomatic(file);
|
|
4421
4555
|
console.log();
|
|
4422
|
-
console.log(
|
|
4556
|
+
console.log(chalk52.bold.underline("Halstead Metrics"));
|
|
4423
4557
|
await halstead(file);
|
|
4424
4558
|
console.log();
|
|
4425
|
-
console.log(
|
|
4559
|
+
console.log(chalk52.bold.underline("Maintainability Index"));
|
|
4426
4560
|
await maintainability(file);
|
|
4427
4561
|
return;
|
|
4428
4562
|
}
|
|
@@ -4450,7 +4584,7 @@ function registerComplexity(program2) {
|
|
|
4450
4584
|
|
|
4451
4585
|
// src/commands/deploy/redirect.ts
|
|
4452
4586
|
import { existsSync as existsSync21, readFileSync as readFileSync16, writeFileSync as writeFileSync16 } from "fs";
|
|
4453
|
-
import
|
|
4587
|
+
import chalk53 from "chalk";
|
|
4454
4588
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4455
4589
|
if (!window.location.pathname.endsWith('/')) {
|
|
4456
4590
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4459,22 +4593,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4459
4593
|
function redirect() {
|
|
4460
4594
|
const indexPath = "index.html";
|
|
4461
4595
|
if (!existsSync21(indexPath)) {
|
|
4462
|
-
console.log(
|
|
4596
|
+
console.log(chalk53.yellow("No index.html found"));
|
|
4463
4597
|
return;
|
|
4464
4598
|
}
|
|
4465
4599
|
const content = readFileSync16(indexPath, "utf-8");
|
|
4466
4600
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4467
|
-
console.log(
|
|
4601
|
+
console.log(chalk53.dim("Trailing slash script already present"));
|
|
4468
4602
|
return;
|
|
4469
4603
|
}
|
|
4470
4604
|
const headCloseIndex = content.indexOf("</head>");
|
|
4471
4605
|
if (headCloseIndex === -1) {
|
|
4472
|
-
console.log(
|
|
4606
|
+
console.log(chalk53.red("Could not find </head> tag in index.html"));
|
|
4473
4607
|
return;
|
|
4474
4608
|
}
|
|
4475
4609
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4476
4610
|
writeFileSync16(indexPath, newContent);
|
|
4477
|
-
console.log(
|
|
4611
|
+
console.log(chalk53.green("Added trailing slash redirect to index.html"));
|
|
4478
4612
|
}
|
|
4479
4613
|
|
|
4480
4614
|
// src/commands/registerDeploy.ts
|
|
@@ -4485,7 +4619,7 @@ function registerDeploy(program2) {
|
|
|
4485
4619
|
}
|
|
4486
4620
|
|
|
4487
4621
|
// src/commands/devlog/list/index.ts
|
|
4488
|
-
import { execSync as
|
|
4622
|
+
import { execSync as execSync18 } from "child_process";
|
|
4489
4623
|
import { basename as basename3 } from "path";
|
|
4490
4624
|
|
|
4491
4625
|
// src/commands/devlog/loadBlogSkipDays.ts
|
|
@@ -4500,8 +4634,8 @@ function loadBlogSkipDays(repoName) {
|
|
|
4500
4634
|
}
|
|
4501
4635
|
|
|
4502
4636
|
// src/commands/devlog/shared.ts
|
|
4503
|
-
import { execSync as
|
|
4504
|
-
import
|
|
4637
|
+
import { execSync as execSync17 } from "child_process";
|
|
4638
|
+
import chalk54 from "chalk";
|
|
4505
4639
|
|
|
4506
4640
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4507
4641
|
import { readdirSync, readFileSync as readFileSync17 } from "fs";
|
|
@@ -4570,7 +4704,7 @@ function loadAllDevlogLatestDates() {
|
|
|
4570
4704
|
// src/commands/devlog/shared.ts
|
|
4571
4705
|
function getCommitFiles(hash) {
|
|
4572
4706
|
try {
|
|
4573
|
-
const output =
|
|
4707
|
+
const output = execSync17(`git show --name-only --format="" ${hash}`, {
|
|
4574
4708
|
encoding: "utf-8"
|
|
4575
4709
|
});
|
|
4576
4710
|
return output.trim().split("\n").filter(Boolean);
|
|
@@ -4588,13 +4722,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4588
4722
|
}
|
|
4589
4723
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4590
4724
|
for (const commit2 of commits) {
|
|
4591
|
-
console.log(` ${
|
|
4725
|
+
console.log(` ${chalk54.yellow(commit2.hash)} ${commit2.message}`);
|
|
4592
4726
|
if (verbose) {
|
|
4593
4727
|
const visibleFiles = commit2.files.filter(
|
|
4594
4728
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4595
4729
|
);
|
|
4596
4730
|
for (const file of visibleFiles) {
|
|
4597
|
-
console.log(` ${
|
|
4731
|
+
console.log(` ${chalk54.dim(file)}`);
|
|
4598
4732
|
}
|
|
4599
4733
|
}
|
|
4600
4734
|
}
|
|
@@ -4619,15 +4753,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4619
4753
|
}
|
|
4620
4754
|
|
|
4621
4755
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4622
|
-
import
|
|
4756
|
+
import chalk55 from "chalk";
|
|
4623
4757
|
function printDateHeader(date, isSkipped, entries) {
|
|
4624
4758
|
if (isSkipped) {
|
|
4625
|
-
console.log(`${
|
|
4759
|
+
console.log(`${chalk55.bold.blue(date)} ${chalk55.dim("skipped")}`);
|
|
4626
4760
|
} else if (entries && entries.length > 0) {
|
|
4627
|
-
const entryInfo = entries.map((e) => `${
|
|
4628
|
-
console.log(`${
|
|
4761
|
+
const entryInfo = entries.map((e) => `${chalk55.green(e.version)} ${e.title}`).join(" | ");
|
|
4762
|
+
console.log(`${chalk55.bold.blue(date)} ${entryInfo}`);
|
|
4629
4763
|
} else {
|
|
4630
|
-
console.log(`${
|
|
4764
|
+
console.log(`${chalk55.bold.blue(date)} ${chalk55.red("\u26A0 devlog missing")}`);
|
|
4631
4765
|
}
|
|
4632
4766
|
}
|
|
4633
4767
|
|
|
@@ -4641,7 +4775,7 @@ function list3(options2) {
|
|
|
4641
4775
|
const devlogEntries = loadDevlogEntries(repoName);
|
|
4642
4776
|
const reverseFlag = options2.reverse ? "--reverse " : "";
|
|
4643
4777
|
const limitFlag = options2.reverse ? "" : "-n 500 ";
|
|
4644
|
-
const output =
|
|
4778
|
+
const output = execSync18(
|
|
4645
4779
|
`git log ${reverseFlag}${limitFlag}--pretty=format:'%ad|%h|%s' --date=short`,
|
|
4646
4780
|
{ encoding: "utf-8" }
|
|
4647
4781
|
);
|
|
@@ -4667,11 +4801,11 @@ function list3(options2) {
|
|
|
4667
4801
|
}
|
|
4668
4802
|
|
|
4669
4803
|
// src/commands/devlog/getLastVersionInfo.ts
|
|
4670
|
-
import { execSync as
|
|
4804
|
+
import { execSync as execSync19 } from "child_process";
|
|
4671
4805
|
import semver from "semver";
|
|
4672
4806
|
function getVersionAtCommit(hash) {
|
|
4673
4807
|
try {
|
|
4674
|
-
const content =
|
|
4808
|
+
const content = execSync19(`git show ${hash}:package.json`, {
|
|
4675
4809
|
encoding: "utf-8"
|
|
4676
4810
|
});
|
|
4677
4811
|
const pkg = JSON.parse(content);
|
|
@@ -4686,7 +4820,7 @@ function stripToMinor(version2) {
|
|
|
4686
4820
|
}
|
|
4687
4821
|
function getLastVersionInfoFromGit() {
|
|
4688
4822
|
try {
|
|
4689
|
-
const output =
|
|
4823
|
+
const output = execSync19(
|
|
4690
4824
|
"git log -1 --pretty=format:'%ad|%h' --date=short",
|
|
4691
4825
|
{
|
|
4692
4826
|
encoding: "utf-8"
|
|
@@ -4729,25 +4863,25 @@ function bumpVersion(version2, type) {
|
|
|
4729
4863
|
}
|
|
4730
4864
|
|
|
4731
4865
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
4732
|
-
import { execSync as
|
|
4733
|
-
import
|
|
4866
|
+
import { execSync as execSync20 } from "child_process";
|
|
4867
|
+
import chalk57 from "chalk";
|
|
4734
4868
|
|
|
4735
4869
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
4736
|
-
import
|
|
4870
|
+
import chalk56 from "chalk";
|
|
4737
4871
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
4738
4872
|
if (conventional && firstHash) {
|
|
4739
4873
|
const version2 = getVersionAtCommit(firstHash);
|
|
4740
4874
|
if (version2) {
|
|
4741
|
-
console.log(`${
|
|
4875
|
+
console.log(`${chalk56.bold("version:")} ${stripToMinor(version2)}`);
|
|
4742
4876
|
} else {
|
|
4743
|
-
console.log(`${
|
|
4877
|
+
console.log(`${chalk56.bold("version:")} ${chalk56.red("unknown")}`);
|
|
4744
4878
|
}
|
|
4745
4879
|
} else if (patchVersion && minorVersion) {
|
|
4746
4880
|
console.log(
|
|
4747
|
-
`${
|
|
4881
|
+
`${chalk56.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
4748
4882
|
);
|
|
4749
4883
|
} else {
|
|
4750
|
-
console.log(`${
|
|
4884
|
+
console.log(`${chalk56.bold("version:")} v0.1 (initial)`);
|
|
4751
4885
|
}
|
|
4752
4886
|
}
|
|
4753
4887
|
|
|
@@ -4763,7 +4897,7 @@ function findTargetDate(commitsByDate, skipDays) {
|
|
|
4763
4897
|
return Array.from(commitsByDate.keys()).filter((d) => !skipDays.has(d)).sort()[0];
|
|
4764
4898
|
}
|
|
4765
4899
|
function fetchCommitsByDate(ignore2, lastDate) {
|
|
4766
|
-
const output =
|
|
4900
|
+
const output = execSync20(
|
|
4767
4901
|
"git log --pretty=format:'%ad|%h|%s' --date=short -n 500",
|
|
4768
4902
|
{ encoding: "utf-8" }
|
|
4769
4903
|
);
|
|
@@ -4794,16 +4928,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
4794
4928
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
4795
4929
|
}
|
|
4796
4930
|
function logName(repoName) {
|
|
4797
|
-
console.log(`${
|
|
4931
|
+
console.log(`${chalk57.bold("name:")} ${repoName}`);
|
|
4798
4932
|
}
|
|
4799
4933
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
4800
4934
|
logName(ctx.repoName);
|
|
4801
4935
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
4802
|
-
console.log(
|
|
4936
|
+
console.log(chalk57.bold.blue(targetDate));
|
|
4803
4937
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
4804
4938
|
}
|
|
4805
4939
|
function logNoCommits(lastInfo) {
|
|
4806
|
-
console.log(
|
|
4940
|
+
console.log(chalk57.dim(noCommitsMessage(!!lastInfo)));
|
|
4807
4941
|
}
|
|
4808
4942
|
|
|
4809
4943
|
// src/commands/devlog/next/index.ts
|
|
@@ -4841,14 +4975,14 @@ function next2(options2) {
|
|
|
4841
4975
|
}
|
|
4842
4976
|
|
|
4843
4977
|
// src/commands/devlog/repos/index.ts
|
|
4844
|
-
import { execSync as
|
|
4978
|
+
import { execSync as execSync21 } from "child_process";
|
|
4845
4979
|
|
|
4846
4980
|
// src/commands/devlog/repos/printReposTable.ts
|
|
4847
|
-
import
|
|
4981
|
+
import chalk58 from "chalk";
|
|
4848
4982
|
function colorStatus(status2) {
|
|
4849
|
-
if (status2 === "missing") return
|
|
4850
|
-
if (status2 === "outdated") return
|
|
4851
|
-
return
|
|
4983
|
+
if (status2 === "missing") return chalk58.red(status2);
|
|
4984
|
+
if (status2 === "outdated") return chalk58.yellow(status2);
|
|
4985
|
+
return chalk58.green(status2);
|
|
4852
4986
|
}
|
|
4853
4987
|
function formatRow(row, nameWidth) {
|
|
4854
4988
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -4862,8 +4996,8 @@ function printReposTable(rows) {
|
|
|
4862
4996
|
"Last Devlog".padEnd(11),
|
|
4863
4997
|
"Status"
|
|
4864
4998
|
].join(" ");
|
|
4865
|
-
console.log(
|
|
4866
|
-
console.log(
|
|
4999
|
+
console.log(chalk58.dim(header));
|
|
5000
|
+
console.log(chalk58.dim("-".repeat(header.length)));
|
|
4867
5001
|
for (const row of rows) {
|
|
4868
5002
|
console.log(formatRow(row, nameWidth));
|
|
4869
5003
|
}
|
|
@@ -4876,7 +5010,7 @@ function getStatus(lastPush, lastDevlog) {
|
|
|
4876
5010
|
return lastDevlog < lastPush ? "outdated" : "ok";
|
|
4877
5011
|
}
|
|
4878
5012
|
function fetchRepos(days, all) {
|
|
4879
|
-
const json =
|
|
5013
|
+
const json = execSync21(
|
|
4880
5014
|
"gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
|
|
4881
5015
|
{ encoding: "utf-8" }
|
|
4882
5016
|
);
|
|
@@ -4921,14 +5055,14 @@ function repos(options2) {
|
|
|
4921
5055
|
// src/commands/devlog/skip.ts
|
|
4922
5056
|
import { writeFileSync as writeFileSync17 } from "fs";
|
|
4923
5057
|
import { join as join16 } from "path";
|
|
4924
|
-
import
|
|
5058
|
+
import chalk59 from "chalk";
|
|
4925
5059
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
4926
5060
|
function getBlogConfigPath() {
|
|
4927
5061
|
return join16(BLOG_REPO_ROOT, "assist.yml");
|
|
4928
5062
|
}
|
|
4929
5063
|
function skip(date) {
|
|
4930
5064
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
4931
|
-
console.log(
|
|
5065
|
+
console.log(chalk59.red("Invalid date format. Use YYYY-MM-DD"));
|
|
4932
5066
|
process.exit(1);
|
|
4933
5067
|
}
|
|
4934
5068
|
const repoName = getRepoName();
|
|
@@ -4939,7 +5073,7 @@ function skip(date) {
|
|
|
4939
5073
|
const skipDays = skip2[repoName] ?? [];
|
|
4940
5074
|
if (skipDays.includes(date)) {
|
|
4941
5075
|
console.log(
|
|
4942
|
-
|
|
5076
|
+
chalk59.yellow(`${date} is already in skip list for ${repoName}`)
|
|
4943
5077
|
);
|
|
4944
5078
|
return;
|
|
4945
5079
|
}
|
|
@@ -4949,20 +5083,20 @@ function skip(date) {
|
|
|
4949
5083
|
devlog.skip = skip2;
|
|
4950
5084
|
config.devlog = devlog;
|
|
4951
5085
|
writeFileSync17(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
4952
|
-
console.log(
|
|
5086
|
+
console.log(chalk59.green(`Added ${date} to skip list for ${repoName}`));
|
|
4953
5087
|
}
|
|
4954
5088
|
|
|
4955
5089
|
// src/commands/devlog/version.ts
|
|
4956
|
-
import
|
|
5090
|
+
import chalk60 from "chalk";
|
|
4957
5091
|
function version() {
|
|
4958
5092
|
const config = loadConfig();
|
|
4959
5093
|
const name = getRepoName();
|
|
4960
5094
|
const lastInfo = getLastVersionInfo(name, config);
|
|
4961
5095
|
const lastVersion = lastInfo?.version ?? null;
|
|
4962
5096
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
4963
|
-
console.log(`${
|
|
4964
|
-
console.log(`${
|
|
4965
|
-
console.log(`${
|
|
5097
|
+
console.log(`${chalk60.bold("name:")} ${name}`);
|
|
5098
|
+
console.log(`${chalk60.bold("last:")} ${lastVersion ?? chalk60.dim("none")}`);
|
|
5099
|
+
console.log(`${chalk60.bold("next:")} ${nextVersion ?? chalk60.dim("none")}`);
|
|
4966
5100
|
}
|
|
4967
5101
|
|
|
4968
5102
|
// src/commands/registerDevlog.ts
|
|
@@ -4986,7 +5120,7 @@ function registerDevlog(program2) {
|
|
|
4986
5120
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
4987
5121
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
4988
5122
|
import { join as join17 } from "path";
|
|
4989
|
-
import
|
|
5123
|
+
import chalk61 from "chalk";
|
|
4990
5124
|
|
|
4991
5125
|
// src/shared/findRepoRoot.ts
|
|
4992
5126
|
import { existsSync as existsSync22 } from "fs";
|
|
@@ -5049,14 +5183,14 @@ function checkBuildLocks(startDir) {
|
|
|
5049
5183
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5050
5184
|
if (locked) {
|
|
5051
5185
|
console.error(
|
|
5052
|
-
|
|
5186
|
+
chalk61.red("Build output locked (is VS debugging?): ") + locked
|
|
5053
5187
|
);
|
|
5054
5188
|
process.exit(1);
|
|
5055
5189
|
}
|
|
5056
5190
|
}
|
|
5057
5191
|
async function checkBuildLocksCommand() {
|
|
5058
5192
|
checkBuildLocks();
|
|
5059
|
-
console.log(
|
|
5193
|
+
console.log(chalk61.green("No build locks detected"));
|
|
5060
5194
|
}
|
|
5061
5195
|
|
|
5062
5196
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -5155,30 +5289,30 @@ function escapeRegex(s) {
|
|
|
5155
5289
|
}
|
|
5156
5290
|
|
|
5157
5291
|
// src/commands/dotnet/printTree.ts
|
|
5158
|
-
import
|
|
5292
|
+
import chalk62 from "chalk";
|
|
5159
5293
|
function printNodes(nodes, prefix2) {
|
|
5160
5294
|
for (let i = 0; i < nodes.length; i++) {
|
|
5161
5295
|
const isLast = i === nodes.length - 1;
|
|
5162
5296
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5163
5297
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5164
5298
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5165
|
-
const label2 = isMissing ?
|
|
5299
|
+
const label2 = isMissing ? chalk62.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5166
5300
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5167
5301
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5168
5302
|
}
|
|
5169
5303
|
}
|
|
5170
5304
|
function printTree(tree, totalCount, solutions) {
|
|
5171
|
-
console.log(
|
|
5172
|
-
console.log(
|
|
5305
|
+
console.log(chalk62.bold("\nProject Dependency Tree"));
|
|
5306
|
+
console.log(chalk62.cyan(tree.relativePath));
|
|
5173
5307
|
printNodes(tree.children, "");
|
|
5174
|
-
console.log(
|
|
5308
|
+
console.log(chalk62.dim(`
|
|
5175
5309
|
${totalCount} projects total (including root)`));
|
|
5176
|
-
console.log(
|
|
5310
|
+
console.log(chalk62.bold("\nSolution Membership"));
|
|
5177
5311
|
if (solutions.length === 0) {
|
|
5178
|
-
console.log(
|
|
5312
|
+
console.log(chalk62.yellow(" Not found in any .sln"));
|
|
5179
5313
|
} else {
|
|
5180
5314
|
for (const sln of solutions) {
|
|
5181
|
-
console.log(` ${
|
|
5315
|
+
console.log(` ${chalk62.green(sln)}`);
|
|
5182
5316
|
}
|
|
5183
5317
|
}
|
|
5184
5318
|
console.log();
|
|
@@ -5207,16 +5341,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5207
5341
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5208
5342
|
import { existsSync as existsSync23 } from "fs";
|
|
5209
5343
|
import path24 from "path";
|
|
5210
|
-
import
|
|
5344
|
+
import chalk63 from "chalk";
|
|
5211
5345
|
function resolveCsproj(csprojPath) {
|
|
5212
5346
|
const resolved = path24.resolve(csprojPath);
|
|
5213
5347
|
if (!existsSync23(resolved)) {
|
|
5214
|
-
console.error(
|
|
5348
|
+
console.error(chalk63.red(`File not found: ${resolved}`));
|
|
5215
5349
|
process.exit(1);
|
|
5216
5350
|
}
|
|
5217
5351
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5218
5352
|
if (!repoRoot) {
|
|
5219
|
-
console.error(
|
|
5353
|
+
console.error(chalk63.red("Could not find git repository root"));
|
|
5220
5354
|
process.exit(1);
|
|
5221
5355
|
}
|
|
5222
5356
|
return { resolved, repoRoot };
|
|
@@ -5236,7 +5370,7 @@ async function deps(csprojPath, options2) {
|
|
|
5236
5370
|
}
|
|
5237
5371
|
|
|
5238
5372
|
// src/commands/dotnet/getChangedCsFiles.ts
|
|
5239
|
-
import { execSync as
|
|
5373
|
+
import { execSync as execSync22 } from "child_process";
|
|
5240
5374
|
var SCOPE_ALL = "all";
|
|
5241
5375
|
var SCOPE_BASE = "base:";
|
|
5242
5376
|
var SCOPE_COMMIT = "commit:";
|
|
@@ -5260,18 +5394,18 @@ function getChangedCsFiles(scope) {
|
|
|
5260
5394
|
} else {
|
|
5261
5395
|
cmd = "git diff --name-only HEAD";
|
|
5262
5396
|
}
|
|
5263
|
-
const output =
|
|
5397
|
+
const output = execSync22(cmd, { encoding: "utf-8" }).trim();
|
|
5264
5398
|
if (output === "") return [];
|
|
5265
5399
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
5266
5400
|
}
|
|
5267
5401
|
|
|
5268
5402
|
// src/commands/dotnet/inSln.ts
|
|
5269
|
-
import
|
|
5403
|
+
import chalk64 from "chalk";
|
|
5270
5404
|
async function inSln(csprojPath) {
|
|
5271
5405
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5272
5406
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5273
5407
|
if (solutions.length === 0) {
|
|
5274
|
-
console.log(
|
|
5408
|
+
console.log(chalk64.yellow("Not found in any .sln file"));
|
|
5275
5409
|
process.exit(1);
|
|
5276
5410
|
}
|
|
5277
5411
|
for (const sln of solutions) {
|
|
@@ -5280,7 +5414,7 @@ async function inSln(csprojPath) {
|
|
|
5280
5414
|
}
|
|
5281
5415
|
|
|
5282
5416
|
// src/commands/dotnet/inspect.ts
|
|
5283
|
-
import
|
|
5417
|
+
import chalk70 from "chalk";
|
|
5284
5418
|
|
|
5285
5419
|
// src/shared/formatElapsed.ts
|
|
5286
5420
|
function formatElapsed(ms) {
|
|
@@ -5292,12 +5426,12 @@ function formatElapsed(ms) {
|
|
|
5292
5426
|
}
|
|
5293
5427
|
|
|
5294
5428
|
// src/commands/dotnet/displayIssues.ts
|
|
5295
|
-
import
|
|
5429
|
+
import chalk65 from "chalk";
|
|
5296
5430
|
var SEVERITY_COLOR = {
|
|
5297
|
-
ERROR:
|
|
5298
|
-
WARNING:
|
|
5299
|
-
SUGGESTION:
|
|
5300
|
-
HINT:
|
|
5431
|
+
ERROR: chalk65.red,
|
|
5432
|
+
WARNING: chalk65.yellow,
|
|
5433
|
+
SUGGESTION: chalk65.cyan,
|
|
5434
|
+
HINT: chalk65.dim
|
|
5301
5435
|
};
|
|
5302
5436
|
function groupByFile(issues) {
|
|
5303
5437
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5313,15 +5447,15 @@ function groupByFile(issues) {
|
|
|
5313
5447
|
}
|
|
5314
5448
|
function displayIssues(issues) {
|
|
5315
5449
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5316
|
-
console.log(
|
|
5450
|
+
console.log(chalk65.bold(file));
|
|
5317
5451
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5318
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5452
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk65.white;
|
|
5319
5453
|
console.log(
|
|
5320
|
-
` ${
|
|
5454
|
+
` ${chalk65.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5321
5455
|
);
|
|
5322
5456
|
}
|
|
5323
5457
|
}
|
|
5324
|
-
console.log(
|
|
5458
|
+
console.log(chalk65.dim(`
|
|
5325
5459
|
${issues.length} issue(s) found`));
|
|
5326
5460
|
}
|
|
5327
5461
|
|
|
@@ -5380,12 +5514,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5380
5514
|
// src/commands/dotnet/resolveSolution.ts
|
|
5381
5515
|
import { existsSync as existsSync24 } from "fs";
|
|
5382
5516
|
import path25 from "path";
|
|
5383
|
-
import
|
|
5517
|
+
import chalk67 from "chalk";
|
|
5384
5518
|
|
|
5385
5519
|
// src/commands/dotnet/findSolution.ts
|
|
5386
5520
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5387
5521
|
import { dirname as dirname16, join as join18 } from "path";
|
|
5388
|
-
import
|
|
5522
|
+
import chalk66 from "chalk";
|
|
5389
5523
|
function findSlnInDir(dir) {
|
|
5390
5524
|
try {
|
|
5391
5525
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join18(dir, f));
|
|
@@ -5401,17 +5535,17 @@ function findSolution() {
|
|
|
5401
5535
|
const slnFiles = findSlnInDir(current);
|
|
5402
5536
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5403
5537
|
if (slnFiles.length > 1) {
|
|
5404
|
-
console.error(
|
|
5538
|
+
console.error(chalk66.red(`Multiple .sln files found in ${current}:`));
|
|
5405
5539
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5406
5540
|
console.error(
|
|
5407
|
-
|
|
5541
|
+
chalk66.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5408
5542
|
);
|
|
5409
5543
|
process.exit(1);
|
|
5410
5544
|
}
|
|
5411
5545
|
if (current === ceiling) break;
|
|
5412
5546
|
current = dirname16(current);
|
|
5413
5547
|
}
|
|
5414
|
-
console.error(
|
|
5548
|
+
console.error(chalk66.red("No .sln file found between cwd and repo root"));
|
|
5415
5549
|
process.exit(1);
|
|
5416
5550
|
}
|
|
5417
5551
|
|
|
@@ -5420,7 +5554,7 @@ function resolveSolution(sln) {
|
|
|
5420
5554
|
if (sln) {
|
|
5421
5555
|
const resolved = path25.resolve(sln);
|
|
5422
5556
|
if (!existsSync24(resolved)) {
|
|
5423
|
-
console.error(
|
|
5557
|
+
console.error(chalk67.red(`Solution file not found: ${resolved}`));
|
|
5424
5558
|
process.exit(1);
|
|
5425
5559
|
}
|
|
5426
5560
|
return resolved;
|
|
@@ -5458,18 +5592,18 @@ function parseInspectReport(json) {
|
|
|
5458
5592
|
}
|
|
5459
5593
|
|
|
5460
5594
|
// src/commands/dotnet/runInspectCode.ts
|
|
5461
|
-
import { execSync as
|
|
5595
|
+
import { execSync as execSync23 } from "child_process";
|
|
5462
5596
|
import { existsSync as existsSync25, readFileSync as readFileSync20, unlinkSync as unlinkSync4 } from "fs";
|
|
5463
5597
|
import { tmpdir as tmpdir2 } from "os";
|
|
5464
5598
|
import path26 from "path";
|
|
5465
|
-
import
|
|
5599
|
+
import chalk68 from "chalk";
|
|
5466
5600
|
function assertJbInstalled() {
|
|
5467
5601
|
try {
|
|
5468
|
-
|
|
5602
|
+
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5469
5603
|
} catch {
|
|
5470
|
-
console.error(
|
|
5604
|
+
console.error(chalk68.red("jb is not installed. Install with:"));
|
|
5471
5605
|
console.error(
|
|
5472
|
-
|
|
5606
|
+
chalk68.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5473
5607
|
);
|
|
5474
5608
|
process.exit(1);
|
|
5475
5609
|
}
|
|
@@ -5479,7 +5613,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5479
5613
|
const includeFlag = include ? ` --include="${include}"` : "";
|
|
5480
5614
|
const sweaFlag = swea ? " --swea" : "";
|
|
5481
5615
|
try {
|
|
5482
|
-
|
|
5616
|
+
execSync23(
|
|
5483
5617
|
`jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
|
|
5484
5618
|
{ stdio: "pipe" }
|
|
5485
5619
|
);
|
|
@@ -5487,11 +5621,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5487
5621
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5488
5622
|
process.stderr.write(err.stderr);
|
|
5489
5623
|
}
|
|
5490
|
-
console.error(
|
|
5624
|
+
console.error(chalk68.red("jb inspectcode failed"));
|
|
5491
5625
|
process.exit(1);
|
|
5492
5626
|
}
|
|
5493
5627
|
if (!existsSync25(reportPath)) {
|
|
5494
|
-
console.error(
|
|
5628
|
+
console.error(chalk68.red("Report file not generated"));
|
|
5495
5629
|
process.exit(1);
|
|
5496
5630
|
}
|
|
5497
5631
|
const xml = readFileSync20(reportPath, "utf-8");
|
|
@@ -5500,8 +5634,8 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5500
5634
|
}
|
|
5501
5635
|
|
|
5502
5636
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5503
|
-
import { execSync as
|
|
5504
|
-
import
|
|
5637
|
+
import { execSync as execSync24 } from "child_process";
|
|
5638
|
+
import chalk69 from "chalk";
|
|
5505
5639
|
function resolveMsbuildPath() {
|
|
5506
5640
|
const config = loadConfig();
|
|
5507
5641
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5510,11 +5644,11 @@ function resolveMsbuildPath() {
|
|
|
5510
5644
|
function assertMsbuildInstalled() {
|
|
5511
5645
|
const msbuild = resolveMsbuildPath();
|
|
5512
5646
|
try {
|
|
5513
|
-
|
|
5647
|
+
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5514
5648
|
} catch {
|
|
5515
|
-
console.error(
|
|
5649
|
+
console.error(chalk69.red(`msbuild not found at: ${msbuild}`));
|
|
5516
5650
|
console.error(
|
|
5517
|
-
|
|
5651
|
+
chalk69.yellow(
|
|
5518
5652
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5519
5653
|
)
|
|
5520
5654
|
);
|
|
@@ -5536,7 +5670,7 @@ function runRoslynInspect(slnPath) {
|
|
|
5536
5670
|
const msbuild = resolveMsbuildPath();
|
|
5537
5671
|
let output;
|
|
5538
5672
|
try {
|
|
5539
|
-
output =
|
|
5673
|
+
output = execSync24(
|
|
5540
5674
|
`"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
|
|
5541
5675
|
{ encoding: "utf-8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
|
|
5542
5676
|
);
|
|
@@ -5561,17 +5695,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5561
5695
|
// src/commands/dotnet/inspect.ts
|
|
5562
5696
|
function logScope(changedFiles) {
|
|
5563
5697
|
if (changedFiles === null) {
|
|
5564
|
-
console.log(
|
|
5698
|
+
console.log(chalk70.dim("Inspecting full solution..."));
|
|
5565
5699
|
} else {
|
|
5566
5700
|
console.log(
|
|
5567
|
-
|
|
5701
|
+
chalk70.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5568
5702
|
);
|
|
5569
5703
|
}
|
|
5570
5704
|
}
|
|
5571
5705
|
function reportResults(issues, elapsed) {
|
|
5572
5706
|
if (issues.length > 0) displayIssues(issues);
|
|
5573
|
-
else console.log(
|
|
5574
|
-
console.log(
|
|
5707
|
+
else console.log(chalk70.green("No issues found"));
|
|
5708
|
+
console.log(chalk70.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5575
5709
|
if (issues.length > 0) process.exit(1);
|
|
5576
5710
|
}
|
|
5577
5711
|
async function inspect(sln, options2) {
|
|
@@ -5582,7 +5716,7 @@ async function inspect(sln, options2) {
|
|
|
5582
5716
|
const scope = parseScope(options2.scope);
|
|
5583
5717
|
const changedFiles = getChangedCsFiles(scope);
|
|
5584
5718
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5585
|
-
console.log(
|
|
5719
|
+
console.log(chalk70.green("No changed .cs files found"));
|
|
5586
5720
|
return;
|
|
5587
5721
|
}
|
|
5588
5722
|
logScope(changedFiles);
|
|
@@ -5608,7 +5742,7 @@ function registerDotnet(program2) {
|
|
|
5608
5742
|
}
|
|
5609
5743
|
|
|
5610
5744
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5611
|
-
import
|
|
5745
|
+
import chalk72 from "chalk";
|
|
5612
5746
|
|
|
5613
5747
|
// src/commands/jira/adfToText.ts
|
|
5614
5748
|
function renderInline(node) {
|
|
@@ -5668,12 +5802,12 @@ function adfToText(doc) {
|
|
|
5668
5802
|
}
|
|
5669
5803
|
|
|
5670
5804
|
// src/commands/jira/fetchIssue.ts
|
|
5671
|
-
import { execSync as
|
|
5672
|
-
import
|
|
5805
|
+
import { execSync as execSync25 } from "child_process";
|
|
5806
|
+
import chalk71 from "chalk";
|
|
5673
5807
|
function fetchIssue(issueKey, fields) {
|
|
5674
5808
|
let result;
|
|
5675
5809
|
try {
|
|
5676
|
-
result =
|
|
5810
|
+
result = execSync25(
|
|
5677
5811
|
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
5678
5812
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
5679
5813
|
);
|
|
@@ -5682,15 +5816,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
5682
5816
|
const stderr = error.stderr;
|
|
5683
5817
|
if (stderr.includes("unauthorized")) {
|
|
5684
5818
|
console.error(
|
|
5685
|
-
|
|
5819
|
+
chalk71.red("Jira authentication expired."),
|
|
5686
5820
|
"Run",
|
|
5687
|
-
|
|
5821
|
+
chalk71.cyan("assist jira auth"),
|
|
5688
5822
|
"to re-authenticate."
|
|
5689
5823
|
);
|
|
5690
5824
|
process.exit(1);
|
|
5691
5825
|
}
|
|
5692
5826
|
}
|
|
5693
|
-
console.error(
|
|
5827
|
+
console.error(chalk71.red(`Failed to fetch ${issueKey}.`));
|
|
5694
5828
|
process.exit(1);
|
|
5695
5829
|
}
|
|
5696
5830
|
return JSON.parse(result);
|
|
@@ -5704,7 +5838,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5704
5838
|
const parsed = fetchIssue(issueKey, field);
|
|
5705
5839
|
const acValue = parsed?.fields?.[field];
|
|
5706
5840
|
if (!acValue) {
|
|
5707
|
-
console.log(
|
|
5841
|
+
console.log(chalk72.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
5708
5842
|
return;
|
|
5709
5843
|
}
|
|
5710
5844
|
if (typeof acValue === "string") {
|
|
@@ -5719,7 +5853,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5719
5853
|
}
|
|
5720
5854
|
|
|
5721
5855
|
// src/commands/jira/jiraAuth.ts
|
|
5722
|
-
import { execSync as
|
|
5856
|
+
import { execSync as execSync26 } from "child_process";
|
|
5723
5857
|
|
|
5724
5858
|
// src/shared/loadJson.ts
|
|
5725
5859
|
import { existsSync as existsSync26, mkdirSync as mkdirSync5, readFileSync as readFileSync21, writeFileSync as writeFileSync18 } from "fs";
|
|
@@ -5783,7 +5917,7 @@ async function jiraAuth() {
|
|
|
5783
5917
|
console.error("All fields are required.");
|
|
5784
5918
|
process.exit(1);
|
|
5785
5919
|
}
|
|
5786
|
-
|
|
5920
|
+
execSync26(`acli jira auth login --site ${site} --email "${email}" --token`, {
|
|
5787
5921
|
encoding: "utf-8",
|
|
5788
5922
|
input: token,
|
|
5789
5923
|
stdio: ["pipe", "inherit", "inherit"]
|
|
@@ -5799,14 +5933,14 @@ async function jiraAuth() {
|
|
|
5799
5933
|
}
|
|
5800
5934
|
|
|
5801
5935
|
// src/commands/jira/viewIssue.ts
|
|
5802
|
-
import
|
|
5936
|
+
import chalk73 from "chalk";
|
|
5803
5937
|
function viewIssue(issueKey) {
|
|
5804
5938
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
5805
5939
|
const fields = parsed?.fields;
|
|
5806
5940
|
const summary = fields?.summary;
|
|
5807
5941
|
const description = fields?.description;
|
|
5808
5942
|
if (summary) {
|
|
5809
|
-
console.log(
|
|
5943
|
+
console.log(chalk73.bold(summary));
|
|
5810
5944
|
}
|
|
5811
5945
|
if (description) {
|
|
5812
5946
|
if (summary) console.log();
|
|
@@ -5820,7 +5954,7 @@ function viewIssue(issueKey) {
|
|
|
5820
5954
|
}
|
|
5821
5955
|
if (!summary && !description) {
|
|
5822
5956
|
console.log(
|
|
5823
|
-
|
|
5957
|
+
chalk73.yellow(`No summary or description found on ${issueKey}.`)
|
|
5824
5958
|
);
|
|
5825
5959
|
}
|
|
5826
5960
|
}
|
|
@@ -5834,7 +5968,7 @@ function registerJira(program2) {
|
|
|
5834
5968
|
}
|
|
5835
5969
|
|
|
5836
5970
|
// src/commands/news/add/index.ts
|
|
5837
|
-
import
|
|
5971
|
+
import chalk74 from "chalk";
|
|
5838
5972
|
import enquirer7 from "enquirer";
|
|
5839
5973
|
async function add2(url) {
|
|
5840
5974
|
if (!url) {
|
|
@@ -5857,17 +5991,17 @@ async function add2(url) {
|
|
|
5857
5991
|
const news = config.news ?? {};
|
|
5858
5992
|
const feeds = news.feeds ?? [];
|
|
5859
5993
|
if (feeds.includes(url)) {
|
|
5860
|
-
console.log(
|
|
5994
|
+
console.log(chalk74.yellow("Feed already exists in config"));
|
|
5861
5995
|
return;
|
|
5862
5996
|
}
|
|
5863
5997
|
feeds.push(url);
|
|
5864
5998
|
config.news = { ...news, feeds };
|
|
5865
5999
|
saveGlobalConfig(config);
|
|
5866
|
-
console.log(
|
|
6000
|
+
console.log(chalk74.green(`Added feed: ${url}`));
|
|
5867
6001
|
}
|
|
5868
6002
|
|
|
5869
6003
|
// src/commands/news/web/handleRequest.ts
|
|
5870
|
-
import
|
|
6004
|
+
import chalk75 from "chalk";
|
|
5871
6005
|
|
|
5872
6006
|
// src/commands/news/web/shared.ts
|
|
5873
6007
|
import { decodeHTML } from "entities";
|
|
@@ -6003,17 +6137,17 @@ function prefetch() {
|
|
|
6003
6137
|
const config = loadConfig();
|
|
6004
6138
|
const total = config.news.feeds.length;
|
|
6005
6139
|
if (total === 0) return;
|
|
6006
|
-
process.stdout.write(
|
|
6140
|
+
process.stdout.write(chalk75.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6007
6141
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6008
6142
|
const width = 20;
|
|
6009
6143
|
const filled = Math.round(done2 / t * width);
|
|
6010
6144
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6011
6145
|
process.stdout.write(
|
|
6012
|
-
`\r${
|
|
6146
|
+
`\r${chalk75.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6013
6147
|
);
|
|
6014
6148
|
}).then((items) => {
|
|
6015
6149
|
process.stdout.write(
|
|
6016
|
-
`\r${
|
|
6150
|
+
`\r${chalk75.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6017
6151
|
`
|
|
6018
6152
|
);
|
|
6019
6153
|
cachedItems = items;
|
|
@@ -6064,7 +6198,7 @@ import { tmpdir as tmpdir3 } from "os";
|
|
|
6064
6198
|
import { join as join20 } from "path";
|
|
6065
6199
|
|
|
6066
6200
|
// src/commands/prs/shared.ts
|
|
6067
|
-
import { execSync as
|
|
6201
|
+
import { execSync as execSync27 } from "child_process";
|
|
6068
6202
|
function isGhNotInstalled(error) {
|
|
6069
6203
|
if (error instanceof Error) {
|
|
6070
6204
|
const msg = error.message.toLowerCase();
|
|
@@ -6080,14 +6214,14 @@ function isNotFound(error) {
|
|
|
6080
6214
|
}
|
|
6081
6215
|
function getRepoInfo() {
|
|
6082
6216
|
const repoInfo = JSON.parse(
|
|
6083
|
-
|
|
6217
|
+
execSync27("gh repo view --json owner,name", { encoding: "utf-8" })
|
|
6084
6218
|
);
|
|
6085
6219
|
return { org: repoInfo.owner.login, repo: repoInfo.name };
|
|
6086
6220
|
}
|
|
6087
6221
|
function getCurrentPrNumber() {
|
|
6088
6222
|
try {
|
|
6089
6223
|
const prInfo = JSON.parse(
|
|
6090
|
-
|
|
6224
|
+
execSync27("gh pr view --json number", { encoding: "utf-8" })
|
|
6091
6225
|
);
|
|
6092
6226
|
return prInfo.number;
|
|
6093
6227
|
} catch (error) {
|
|
@@ -6101,7 +6235,7 @@ function getCurrentPrNumber() {
|
|
|
6101
6235
|
function getCurrentPrNodeId() {
|
|
6102
6236
|
try {
|
|
6103
6237
|
const prInfo = JSON.parse(
|
|
6104
|
-
|
|
6238
|
+
execSync27("gh pr view --json id", { encoding: "utf-8" })
|
|
6105
6239
|
);
|
|
6106
6240
|
return prInfo.id;
|
|
6107
6241
|
} catch (error) {
|
|
@@ -6128,7 +6262,7 @@ function validateLine(line) {
|
|
|
6128
6262
|
process.exit(1);
|
|
6129
6263
|
}
|
|
6130
6264
|
}
|
|
6131
|
-
function
|
|
6265
|
+
function comment2(path50, line, body) {
|
|
6132
6266
|
validateBody(body);
|
|
6133
6267
|
validateLine(line);
|
|
6134
6268
|
try {
|
|
@@ -6172,10 +6306,10 @@ function comment(path50, line, body) {
|
|
|
6172
6306
|
}
|
|
6173
6307
|
|
|
6174
6308
|
// src/commands/prs/fixed.ts
|
|
6175
|
-
import { execSync as
|
|
6309
|
+
import { execSync as execSync29 } from "child_process";
|
|
6176
6310
|
|
|
6177
6311
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
6178
|
-
import { execSync as
|
|
6312
|
+
import { execSync as execSync28 } from "child_process";
|
|
6179
6313
|
import { unlinkSync as unlinkSync7, writeFileSync as writeFileSync20 } from "fs";
|
|
6180
6314
|
import { tmpdir as tmpdir4 } from "os";
|
|
6181
6315
|
import { join as join22 } from "path";
|
|
@@ -6205,7 +6339,7 @@ function deleteCommentsCache(prNumber) {
|
|
|
6205
6339
|
|
|
6206
6340
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
6207
6341
|
function replyToComment(org, repo, prNumber, commentId, message) {
|
|
6208
|
-
|
|
6342
|
+
execSync28(
|
|
6209
6343
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, '\\"')}" -F in_reply_to=${commentId}`,
|
|
6210
6344
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
6211
6345
|
);
|
|
@@ -6215,7 +6349,7 @@ function resolveThread(threadId) {
|
|
|
6215
6349
|
const queryFile = join22(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
|
|
6216
6350
|
writeFileSync20(queryFile, mutation);
|
|
6217
6351
|
try {
|
|
6218
|
-
|
|
6352
|
+
execSync28(
|
|
6219
6353
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
6220
6354
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
6221
6355
|
);
|
|
@@ -6233,18 +6367,18 @@ function requireCache(prNumber) {
|
|
|
6233
6367
|
}
|
|
6234
6368
|
return cache;
|
|
6235
6369
|
}
|
|
6236
|
-
function findLineComment(
|
|
6237
|
-
return
|
|
6370
|
+
function findLineComment(comments2, commentId) {
|
|
6371
|
+
return comments2.find((c) => c.type === "line" && c.id === commentId);
|
|
6238
6372
|
}
|
|
6239
6373
|
function requireLineComment(cache, commentId) {
|
|
6240
|
-
const
|
|
6241
|
-
if (!
|
|
6374
|
+
const comment3 = findLineComment(cache.comments, commentId);
|
|
6375
|
+
if (!comment3 || comment3.type !== "line" || !comment3.threadId) {
|
|
6242
6376
|
console.error(
|
|
6243
6377
|
`Error: Comment #${commentId} not found or has no thread ID.`
|
|
6244
6378
|
);
|
|
6245
6379
|
process.exit(1);
|
|
6246
6380
|
}
|
|
6247
|
-
return
|
|
6381
|
+
return comment3;
|
|
6248
6382
|
}
|
|
6249
6383
|
function cleanupCacheIfDone(cache, prNumber, commentId) {
|
|
6250
6384
|
const hasRemaining = cache.comments.some(
|
|
@@ -6256,10 +6390,10 @@ function resolveCommentWithReply(commentId, message) {
|
|
|
6256
6390
|
const prNumber = getCurrentPrNumber();
|
|
6257
6391
|
const { org, repo } = getRepoInfo();
|
|
6258
6392
|
const cache = requireCache(prNumber);
|
|
6259
|
-
const
|
|
6393
|
+
const comment3 = requireLineComment(cache, commentId);
|
|
6260
6394
|
replyToComment(org, repo, prNumber, commentId, message);
|
|
6261
6395
|
console.log("Reply posted successfully.");
|
|
6262
|
-
resolveThread(
|
|
6396
|
+
resolveThread(comment3.threadId);
|
|
6263
6397
|
console.log("Thread resolved successfully.");
|
|
6264
6398
|
cleanupCacheIfDone(cache, prNumber, commentId);
|
|
6265
6399
|
}
|
|
@@ -6267,7 +6401,7 @@ function resolveCommentWithReply(commentId, message) {
|
|
|
6267
6401
|
// src/commands/prs/fixed.ts
|
|
6268
6402
|
function verifySha(sha) {
|
|
6269
6403
|
try {
|
|
6270
|
-
return
|
|
6404
|
+
return execSync29(`git rev-parse --verify ${sha}`, {
|
|
6271
6405
|
encoding: "utf-8"
|
|
6272
6406
|
}).trim();
|
|
6273
6407
|
} catch {
|
|
@@ -6281,7 +6415,7 @@ function fixed(commentId, sha) {
|
|
|
6281
6415
|
const { org, repo } = getRepoInfo();
|
|
6282
6416
|
const repoUrl = `https://github.com/${org}/${repo}`;
|
|
6283
6417
|
const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
|
|
6284
|
-
|
|
6418
|
+
execSync29("git push", { stdio: "inherit" });
|
|
6285
6419
|
resolveCommentWithReply(commentId, message);
|
|
6286
6420
|
} catch (error) {
|
|
6287
6421
|
if (isGhNotInstalled(error)) {
|
|
@@ -6299,7 +6433,7 @@ import { join as join24 } from "path";
|
|
|
6299
6433
|
import { stringify } from "yaml";
|
|
6300
6434
|
|
|
6301
6435
|
// src/commands/prs/fetchThreadIds.ts
|
|
6302
|
-
import { execSync as
|
|
6436
|
+
import { execSync as execSync30 } from "child_process";
|
|
6303
6437
|
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "fs";
|
|
6304
6438
|
import { tmpdir as tmpdir5 } from "os";
|
|
6305
6439
|
import { join as join23 } from "path";
|
|
@@ -6308,7 +6442,7 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
6308
6442
|
const queryFile = join23(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
6309
6443
|
writeFileSync21(queryFile, THREAD_QUERY);
|
|
6310
6444
|
try {
|
|
6311
|
-
const result =
|
|
6445
|
+
const result = execSync30(
|
|
6312
6446
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
6313
6447
|
{ encoding: "utf-8" }
|
|
6314
6448
|
);
|
|
@@ -6319,8 +6453,8 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
6319
6453
|
if (thread.isResolved) {
|
|
6320
6454
|
resolvedThreadIds.add(thread.id);
|
|
6321
6455
|
}
|
|
6322
|
-
for (const
|
|
6323
|
-
threadMap.set(
|
|
6456
|
+
for (const comment3 of thread.comments.nodes) {
|
|
6457
|
+
threadMap.set(comment3.databaseId, thread.id);
|
|
6324
6458
|
}
|
|
6325
6459
|
}
|
|
6326
6460
|
return { threadMap, resolvedThreadIds };
|
|
@@ -6330,9 +6464,9 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
6330
6464
|
}
|
|
6331
6465
|
|
|
6332
6466
|
// src/commands/prs/listComments/fetchReviewComments.ts
|
|
6333
|
-
import { execSync as
|
|
6467
|
+
import { execSync as execSync31 } from "child_process";
|
|
6334
6468
|
function fetchJson(endpoint) {
|
|
6335
|
-
const result =
|
|
6469
|
+
const result = execSync31(`gh api --paginate ${endpoint}`, {
|
|
6336
6470
|
encoding: "utf-8"
|
|
6337
6471
|
});
|
|
6338
6472
|
if (!result.trim()) return [];
|
|
@@ -6367,58 +6501,58 @@ function mapLineComment(c, threadInfo) {
|
|
|
6367
6501
|
};
|
|
6368
6502
|
}
|
|
6369
6503
|
function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
6370
|
-
const
|
|
6371
|
-
return
|
|
6504
|
+
const comments2 = fetchJson(`repos/${org}/${repo}/pulls/${prNumber}/comments`);
|
|
6505
|
+
return comments2.map(
|
|
6372
6506
|
(c) => mapLineComment(c, threadInfo)
|
|
6373
6507
|
);
|
|
6374
6508
|
}
|
|
6375
6509
|
|
|
6376
6510
|
// src/commands/prs/listComments/printComments.ts
|
|
6377
|
-
import
|
|
6378
|
-
function formatForHuman(
|
|
6379
|
-
if (
|
|
6380
|
-
const stateColor =
|
|
6511
|
+
import chalk76 from "chalk";
|
|
6512
|
+
function formatForHuman(comment3) {
|
|
6513
|
+
if (comment3.type === "review") {
|
|
6514
|
+
const stateColor = comment3.state === "APPROVED" ? chalk76.green : comment3.state === "CHANGES_REQUESTED" ? chalk76.red : chalk76.yellow;
|
|
6381
6515
|
return [
|
|
6382
|
-
`${
|
|
6383
|
-
|
|
6516
|
+
`${chalk76.cyan("Review")} by ${chalk76.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
6517
|
+
comment3.body,
|
|
6384
6518
|
""
|
|
6385
6519
|
].join("\n");
|
|
6386
6520
|
}
|
|
6387
|
-
const location =
|
|
6521
|
+
const location = comment3.line ? `:${comment3.line}` : "";
|
|
6388
6522
|
return [
|
|
6389
|
-
`${
|
|
6390
|
-
|
|
6391
|
-
|
|
6523
|
+
`${chalk76.cyan("Line comment")} by ${chalk76.bold(comment3.user)} on ${chalk76.dim(`${comment3.path}${location}`)}`,
|
|
6524
|
+
chalk76.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6525
|
+
comment3.body,
|
|
6392
6526
|
""
|
|
6393
6527
|
].join("\n");
|
|
6394
6528
|
}
|
|
6395
|
-
function summarise(
|
|
6396
|
-
const lineCount =
|
|
6397
|
-
const reviewCount =
|
|
6529
|
+
function summarise(comments2) {
|
|
6530
|
+
const lineCount = comments2.filter((c) => c.type === "line").length;
|
|
6531
|
+
const reviewCount = comments2.filter((c) => c.type === "review").length;
|
|
6398
6532
|
const parts = [];
|
|
6399
6533
|
if (lineCount > 0) parts.push(`${lineCount} line`);
|
|
6400
6534
|
if (reviewCount > 0) parts.push(`${reviewCount} review`);
|
|
6401
|
-
return `Found ${parts.join(" and ")} comment${
|
|
6535
|
+
return `Found ${parts.join(" and ")} comment${comments2.length === 1 ? "" : "s"}.`;
|
|
6402
6536
|
}
|
|
6403
|
-
function
|
|
6404
|
-
const { comments, cachePath } = result;
|
|
6405
|
-
if (
|
|
6537
|
+
function printComments2(result) {
|
|
6538
|
+
const { comments: comments2, cachePath } = result;
|
|
6539
|
+
if (comments2.length === 0) {
|
|
6406
6540
|
console.log("No comments found.");
|
|
6407
6541
|
return;
|
|
6408
6542
|
}
|
|
6409
6543
|
if (!isClaudeCode()) {
|
|
6410
|
-
for (const
|
|
6411
|
-
console.log(formatForHuman(
|
|
6544
|
+
for (const comment3 of comments2) {
|
|
6545
|
+
console.log(formatForHuman(comment3));
|
|
6412
6546
|
}
|
|
6413
6547
|
}
|
|
6414
|
-
console.log(summarise(
|
|
6548
|
+
console.log(summarise(comments2));
|
|
6415
6549
|
if (cachePath) {
|
|
6416
6550
|
console.log(`Saved to ${cachePath}`);
|
|
6417
6551
|
}
|
|
6418
6552
|
}
|
|
6419
6553
|
|
|
6420
6554
|
// src/commands/prs/listComments/index.ts
|
|
6421
|
-
function writeCommentsCache(prNumber,
|
|
6555
|
+
function writeCommentsCache(prNumber, comments2) {
|
|
6422
6556
|
const assistDir = join24(process.cwd(), ".assist");
|
|
6423
6557
|
if (!existsSync28(assistDir)) {
|
|
6424
6558
|
mkdirSync6(assistDir, { recursive: true });
|
|
@@ -6426,7 +6560,7 @@ function writeCommentsCache(prNumber, comments) {
|
|
|
6426
6560
|
const cacheData = {
|
|
6427
6561
|
prNumber,
|
|
6428
6562
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6429
|
-
comments
|
|
6563
|
+
comments: comments2
|
|
6430
6564
|
};
|
|
6431
6565
|
const cachePath = join24(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
6432
6566
|
writeFileSync22(cachePath, stringify(cacheData));
|
|
@@ -6443,9 +6577,9 @@ function handleKnownErrors(error) {
|
|
|
6443
6577
|
}
|
|
6444
6578
|
return null;
|
|
6445
6579
|
}
|
|
6446
|
-
function updateCache(prNumber,
|
|
6447
|
-
if (
|
|
6448
|
-
writeCommentsCache(prNumber,
|
|
6580
|
+
function updateCache(prNumber, comments2) {
|
|
6581
|
+
if (comments2.some((c) => c.type === "line")) {
|
|
6582
|
+
writeCommentsCache(prNumber, comments2);
|
|
6449
6583
|
} else {
|
|
6450
6584
|
deleteCommentsCache(prNumber);
|
|
6451
6585
|
}
|
|
@@ -6471,19 +6605,19 @@ async function listComments() {
|
|
|
6471
6605
|
}
|
|
6472
6606
|
|
|
6473
6607
|
// src/commands/prs/prs/index.ts
|
|
6474
|
-
import { execSync as
|
|
6608
|
+
import { execSync as execSync32 } from "child_process";
|
|
6475
6609
|
|
|
6476
6610
|
// src/commands/prs/prs/displayPaginated/index.ts
|
|
6477
6611
|
import enquirer8 from "enquirer";
|
|
6478
6612
|
|
|
6479
6613
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6480
|
-
import
|
|
6614
|
+
import chalk77 from "chalk";
|
|
6481
6615
|
var STATUS_MAP = {
|
|
6482
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6483
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6616
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk77.magenta("merged"), date: pr.mergedAt } : null,
|
|
6617
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk77.red("closed"), date: pr.closedAt } : null
|
|
6484
6618
|
};
|
|
6485
6619
|
function defaultStatus(pr) {
|
|
6486
|
-
return { label:
|
|
6620
|
+
return { label: chalk77.green("opened"), date: pr.createdAt };
|
|
6487
6621
|
}
|
|
6488
6622
|
function getStatus2(pr) {
|
|
6489
6623
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6492,11 +6626,11 @@ function formatDate(dateStr) {
|
|
|
6492
6626
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6493
6627
|
}
|
|
6494
6628
|
function formatPrHeader(pr, status2) {
|
|
6495
|
-
return `${
|
|
6629
|
+
return `${chalk77.cyan(`#${pr.number}`)} ${pr.title} ${chalk77.dim(`(${pr.author.login},`)} ${status2.label} ${chalk77.dim(`${formatDate(status2.date)})`)}`;
|
|
6496
6630
|
}
|
|
6497
6631
|
function logPrDetails(pr) {
|
|
6498
6632
|
console.log(
|
|
6499
|
-
|
|
6633
|
+
chalk77.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6500
6634
|
);
|
|
6501
6635
|
console.log();
|
|
6502
6636
|
}
|
|
@@ -6577,7 +6711,7 @@ async function displayPaginated(pullRequests) {
|
|
|
6577
6711
|
async function prs(options2) {
|
|
6578
6712
|
const state = options2.open ? "open" : options2.closed ? "closed" : "all";
|
|
6579
6713
|
try {
|
|
6580
|
-
const result =
|
|
6714
|
+
const result = execSync32(
|
|
6581
6715
|
`gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100`,
|
|
6582
6716
|
{ encoding: "utf-8" }
|
|
6583
6717
|
);
|
|
@@ -6600,7 +6734,7 @@ async function prs(options2) {
|
|
|
6600
6734
|
}
|
|
6601
6735
|
|
|
6602
6736
|
// src/commands/prs/wontfix.ts
|
|
6603
|
-
import { execSync as
|
|
6737
|
+
import { execSync as execSync33 } from "child_process";
|
|
6604
6738
|
function validateReason(reason) {
|
|
6605
6739
|
const lowerReason = reason.toLowerCase();
|
|
6606
6740
|
if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
|
|
@@ -6617,7 +6751,7 @@ function validateShaReferences(reason) {
|
|
|
6617
6751
|
const invalidShas = [];
|
|
6618
6752
|
for (const sha of shas) {
|
|
6619
6753
|
try {
|
|
6620
|
-
|
|
6754
|
+
execSync33(`git cat-file -t ${sha}`, { stdio: "pipe" });
|
|
6621
6755
|
} catch {
|
|
6622
6756
|
invalidShas.push(sha);
|
|
6623
6757
|
}
|
|
@@ -6648,7 +6782,7 @@ function wontfix(commentId, reason) {
|
|
|
6648
6782
|
function registerPrs(program2) {
|
|
6649
6783
|
const prsCommand = program2.command("prs").description("Pull request utilities").option("--open", "List only open pull requests").option("--closed", "List only closed pull requests").action(prs);
|
|
6650
6784
|
prsCommand.command("list-comments").description("List all comments on the current branch's pull request").action(() => {
|
|
6651
|
-
listComments().then(
|
|
6785
|
+
listComments().then(printComments2);
|
|
6652
6786
|
});
|
|
6653
6787
|
prsCommand.command("fixed <comment-id> <sha>").description("Reply with commit link and resolve thread").action((commentId, sha) => {
|
|
6654
6788
|
fixed(Number.parseInt(commentId, 10), sha);
|
|
@@ -6657,15 +6791,15 @@ function registerPrs(program2) {
|
|
|
6657
6791
|
wontfix(Number.parseInt(commentId, 10), reason);
|
|
6658
6792
|
});
|
|
6659
6793
|
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path50, line, body) => {
|
|
6660
|
-
|
|
6794
|
+
comment2(path50, Number.parseInt(line, 10), body);
|
|
6661
6795
|
});
|
|
6662
6796
|
}
|
|
6663
6797
|
|
|
6664
6798
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6665
|
-
import
|
|
6799
|
+
import chalk83 from "chalk";
|
|
6666
6800
|
|
|
6667
6801
|
// src/shared/createConnectionAuth.ts
|
|
6668
|
-
import
|
|
6802
|
+
import chalk78 from "chalk";
|
|
6669
6803
|
function listConnections(connections, format2) {
|
|
6670
6804
|
if (connections.length === 0) {
|
|
6671
6805
|
console.log("No connections configured.");
|
|
@@ -6678,7 +6812,7 @@ function listConnections(connections, format2) {
|
|
|
6678
6812
|
function removeConnection(connections, name, save) {
|
|
6679
6813
|
const filtered = connections.filter((c) => c.name !== name);
|
|
6680
6814
|
if (filtered.length === connections.length) {
|
|
6681
|
-
console.error(
|
|
6815
|
+
console.error(chalk78.red(`Connection "${name}" not found.`));
|
|
6682
6816
|
process.exit(1);
|
|
6683
6817
|
}
|
|
6684
6818
|
save(filtered);
|
|
@@ -6724,17 +6858,17 @@ function saveConnections(connections) {
|
|
|
6724
6858
|
}
|
|
6725
6859
|
|
|
6726
6860
|
// src/commands/ravendb/promptConnection.ts
|
|
6727
|
-
import
|
|
6861
|
+
import chalk81 from "chalk";
|
|
6728
6862
|
|
|
6729
6863
|
// src/commands/ravendb/selectOpSecret.ts
|
|
6730
|
-
import
|
|
6864
|
+
import chalk80 from "chalk";
|
|
6731
6865
|
import Enquirer2 from "enquirer";
|
|
6732
6866
|
|
|
6733
6867
|
// src/commands/ravendb/searchItems.ts
|
|
6734
|
-
import { execSync as
|
|
6735
|
-
import
|
|
6868
|
+
import { execSync as execSync34 } from "child_process";
|
|
6869
|
+
import chalk79 from "chalk";
|
|
6736
6870
|
function opExec(args) {
|
|
6737
|
-
return
|
|
6871
|
+
return execSync34(`op ${args}`, {
|
|
6738
6872
|
encoding: "utf-8",
|
|
6739
6873
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6740
6874
|
}).trim();
|
|
@@ -6745,7 +6879,7 @@ function searchItems(search) {
|
|
|
6745
6879
|
items = JSON.parse(opExec("item list --format=json"));
|
|
6746
6880
|
} catch {
|
|
6747
6881
|
console.error(
|
|
6748
|
-
|
|
6882
|
+
chalk79.red(
|
|
6749
6883
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
6750
6884
|
)
|
|
6751
6885
|
);
|
|
@@ -6759,7 +6893,7 @@ function getItemFields(itemId) {
|
|
|
6759
6893
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
6760
6894
|
return item.fields.filter((f) => f.reference && f.label);
|
|
6761
6895
|
} catch {
|
|
6762
|
-
console.error(
|
|
6896
|
+
console.error(chalk79.red("Failed to get item details from 1Password."));
|
|
6763
6897
|
process.exit(1);
|
|
6764
6898
|
}
|
|
6765
6899
|
}
|
|
@@ -6778,7 +6912,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6778
6912
|
}).run();
|
|
6779
6913
|
const items = searchItems(search);
|
|
6780
6914
|
if (items.length === 0) {
|
|
6781
|
-
console.error(
|
|
6915
|
+
console.error(chalk80.red(`No items found matching "${search}".`));
|
|
6782
6916
|
process.exit(1);
|
|
6783
6917
|
}
|
|
6784
6918
|
const itemId = await selectOne(
|
|
@@ -6787,7 +6921,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6787
6921
|
);
|
|
6788
6922
|
const fields = getItemFields(itemId);
|
|
6789
6923
|
if (fields.length === 0) {
|
|
6790
|
-
console.error(
|
|
6924
|
+
console.error(chalk80.red("No fields with references found on this item."));
|
|
6791
6925
|
process.exit(1);
|
|
6792
6926
|
}
|
|
6793
6927
|
const ref = await selectOne(
|
|
@@ -6801,7 +6935,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6801
6935
|
async function promptConnection(existingNames) {
|
|
6802
6936
|
const name = await promptInput("name", "Connection name:");
|
|
6803
6937
|
if (existingNames.includes(name)) {
|
|
6804
|
-
console.error(
|
|
6938
|
+
console.error(chalk81.red(`Connection "${name}" already exists.`));
|
|
6805
6939
|
process.exit(1);
|
|
6806
6940
|
}
|
|
6807
6941
|
const url = await promptInput(
|
|
@@ -6810,22 +6944,22 @@ async function promptConnection(existingNames) {
|
|
|
6810
6944
|
);
|
|
6811
6945
|
const database = await promptInput("database", "Database name:");
|
|
6812
6946
|
if (!name || !url || !database) {
|
|
6813
|
-
console.error(
|
|
6947
|
+
console.error(chalk81.red("All fields are required."));
|
|
6814
6948
|
process.exit(1);
|
|
6815
6949
|
}
|
|
6816
6950
|
const apiKeyRef = await selectOpSecret();
|
|
6817
|
-
console.log(
|
|
6951
|
+
console.log(chalk81.dim(`Using: ${apiKeyRef}`));
|
|
6818
6952
|
return { name, url, database, apiKeyRef };
|
|
6819
6953
|
}
|
|
6820
6954
|
|
|
6821
6955
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
6822
|
-
import
|
|
6956
|
+
import chalk82 from "chalk";
|
|
6823
6957
|
function ravendbSetConnection(name) {
|
|
6824
6958
|
const raw = loadGlobalConfigRaw();
|
|
6825
6959
|
const ravendb = raw.ravendb ?? {};
|
|
6826
6960
|
const connections = ravendb.connections ?? [];
|
|
6827
6961
|
if (!connections.some((c) => c.name === name)) {
|
|
6828
|
-
console.error(
|
|
6962
|
+
console.error(chalk82.red(`Connection "${name}" not found.`));
|
|
6829
6963
|
console.error(
|
|
6830
6964
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6831
6965
|
);
|
|
@@ -6841,16 +6975,16 @@ function ravendbSetConnection(name) {
|
|
|
6841
6975
|
var ravendbAuth = createConnectionAuth({
|
|
6842
6976
|
load: loadConnections,
|
|
6843
6977
|
save: saveConnections,
|
|
6844
|
-
format: (c) => `${
|
|
6978
|
+
format: (c) => `${chalk83.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
6845
6979
|
promptNew: promptConnection,
|
|
6846
6980
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
6847
6981
|
});
|
|
6848
6982
|
|
|
6849
6983
|
// src/commands/ravendb/ravendbCollections.ts
|
|
6850
|
-
import
|
|
6984
|
+
import chalk87 from "chalk";
|
|
6851
6985
|
|
|
6852
6986
|
// src/commands/ravendb/ravenFetch.ts
|
|
6853
|
-
import
|
|
6987
|
+
import chalk85 from "chalk";
|
|
6854
6988
|
|
|
6855
6989
|
// src/commands/ravendb/getAccessToken.ts
|
|
6856
6990
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -6886,21 +7020,21 @@ ${errorText}`
|
|
|
6886
7020
|
}
|
|
6887
7021
|
|
|
6888
7022
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
6889
|
-
import { execSync as
|
|
6890
|
-
import
|
|
7023
|
+
import { execSync as execSync35 } from "child_process";
|
|
7024
|
+
import chalk84 from "chalk";
|
|
6891
7025
|
function resolveOpSecret(reference) {
|
|
6892
7026
|
if (!reference.startsWith("op://")) {
|
|
6893
|
-
console.error(
|
|
7027
|
+
console.error(chalk84.red(`Invalid secret reference: must start with op://`));
|
|
6894
7028
|
process.exit(1);
|
|
6895
7029
|
}
|
|
6896
7030
|
try {
|
|
6897
|
-
return
|
|
7031
|
+
return execSync35(`op read "${reference}"`, {
|
|
6898
7032
|
encoding: "utf-8",
|
|
6899
7033
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6900
7034
|
}).trim();
|
|
6901
7035
|
} catch {
|
|
6902
7036
|
console.error(
|
|
6903
|
-
|
|
7037
|
+
chalk84.red(
|
|
6904
7038
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
6905
7039
|
)
|
|
6906
7040
|
);
|
|
@@ -6927,7 +7061,7 @@ async function ravenFetch(connection, path50) {
|
|
|
6927
7061
|
if (!response.ok) {
|
|
6928
7062
|
const body = await response.text();
|
|
6929
7063
|
console.error(
|
|
6930
|
-
|
|
7064
|
+
chalk85.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
6931
7065
|
);
|
|
6932
7066
|
console.error(body.substring(0, 500));
|
|
6933
7067
|
process.exit(1);
|
|
@@ -6936,7 +7070,7 @@ async function ravenFetch(connection, path50) {
|
|
|
6936
7070
|
}
|
|
6937
7071
|
|
|
6938
7072
|
// src/commands/ravendb/resolveConnection.ts
|
|
6939
|
-
import
|
|
7073
|
+
import chalk86 from "chalk";
|
|
6940
7074
|
function loadRavendb() {
|
|
6941
7075
|
const raw = loadGlobalConfigRaw();
|
|
6942
7076
|
const ravendb = raw.ravendb;
|
|
@@ -6950,7 +7084,7 @@ function resolveConnection(name) {
|
|
|
6950
7084
|
const connectionName = name ?? defaultConnection;
|
|
6951
7085
|
if (!connectionName) {
|
|
6952
7086
|
console.error(
|
|
6953
|
-
|
|
7087
|
+
chalk86.red(
|
|
6954
7088
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
6955
7089
|
)
|
|
6956
7090
|
);
|
|
@@ -6958,7 +7092,7 @@ function resolveConnection(name) {
|
|
|
6958
7092
|
}
|
|
6959
7093
|
const connection = connections.find((c) => c.name === connectionName);
|
|
6960
7094
|
if (!connection) {
|
|
6961
|
-
console.error(
|
|
7095
|
+
console.error(chalk86.red(`Connection "${connectionName}" not found.`));
|
|
6962
7096
|
console.error(
|
|
6963
7097
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6964
7098
|
);
|
|
@@ -6989,15 +7123,15 @@ async function ravendbCollections(connectionName) {
|
|
|
6989
7123
|
return;
|
|
6990
7124
|
}
|
|
6991
7125
|
for (const c of collections) {
|
|
6992
|
-
console.log(`${
|
|
7126
|
+
console.log(`${chalk87.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
6993
7127
|
}
|
|
6994
7128
|
}
|
|
6995
7129
|
|
|
6996
7130
|
// src/commands/ravendb/ravendbQuery.ts
|
|
6997
|
-
import
|
|
7131
|
+
import chalk89 from "chalk";
|
|
6998
7132
|
|
|
6999
7133
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7000
|
-
import
|
|
7134
|
+
import chalk88 from "chalk";
|
|
7001
7135
|
|
|
7002
7136
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7003
7137
|
function buildQueryPath(opts) {
|
|
@@ -7035,7 +7169,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7035
7169
|
allResults.push(...results);
|
|
7036
7170
|
start3 += results.length;
|
|
7037
7171
|
process.stderr.write(
|
|
7038
|
-
`\r${
|
|
7172
|
+
`\r${chalk88.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7039
7173
|
);
|
|
7040
7174
|
if (start3 >= totalResults) break;
|
|
7041
7175
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7050,7 +7184,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7050
7184
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7051
7185
|
const resolved = resolveArgs(connectionName, collection);
|
|
7052
7186
|
if (!resolved.collection && !options2.query) {
|
|
7053
|
-
console.error(
|
|
7187
|
+
console.error(chalk89.red("Provide a collection name or --query filter."));
|
|
7054
7188
|
process.exit(1);
|
|
7055
7189
|
}
|
|
7056
7190
|
const { collection: col } = resolved;
|
|
@@ -7088,7 +7222,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7088
7222
|
import * as path27 from "path";
|
|
7089
7223
|
|
|
7090
7224
|
// src/commands/refactor/logViolations.ts
|
|
7091
|
-
import
|
|
7225
|
+
import chalk90 from "chalk";
|
|
7092
7226
|
var DEFAULT_MAX_LINES = 100;
|
|
7093
7227
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7094
7228
|
if (violations.length === 0) {
|
|
@@ -7097,43 +7231,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7097
7231
|
}
|
|
7098
7232
|
return;
|
|
7099
7233
|
}
|
|
7100
|
-
console.error(
|
|
7234
|
+
console.error(chalk90.red(`
|
|
7101
7235
|
Refactor check failed:
|
|
7102
7236
|
`));
|
|
7103
|
-
console.error(
|
|
7237
|
+
console.error(chalk90.red(` The following files exceed ${maxLines} lines:
|
|
7104
7238
|
`));
|
|
7105
7239
|
for (const violation of violations) {
|
|
7106
|
-
console.error(
|
|
7240
|
+
console.error(chalk90.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7107
7241
|
}
|
|
7108
7242
|
console.error(
|
|
7109
|
-
|
|
7243
|
+
chalk90.yellow(
|
|
7110
7244
|
`
|
|
7111
7245
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7112
7246
|
way to refactor it, ignore it with:
|
|
7113
7247
|
`
|
|
7114
7248
|
)
|
|
7115
7249
|
);
|
|
7116
|
-
console.error(
|
|
7250
|
+
console.error(chalk90.gray(` assist refactor ignore <file>
|
|
7117
7251
|
`));
|
|
7118
7252
|
if (process.env.CLAUDECODE) {
|
|
7119
|
-
console.error(
|
|
7253
|
+
console.error(chalk90.cyan(`
|
|
7120
7254
|
## Extracting Code to New Files
|
|
7121
7255
|
`));
|
|
7122
7256
|
console.error(
|
|
7123
|
-
|
|
7257
|
+
chalk90.cyan(
|
|
7124
7258
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7125
7259
|
`
|
|
7126
7260
|
)
|
|
7127
7261
|
);
|
|
7128
7262
|
console.error(
|
|
7129
|
-
|
|
7263
|
+
chalk90.cyan(
|
|
7130
7264
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7131
7265
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7132
7266
|
`
|
|
7133
7267
|
)
|
|
7134
7268
|
);
|
|
7135
7269
|
console.error(
|
|
7136
|
-
|
|
7270
|
+
chalk90.cyan(
|
|
7137
7271
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7138
7272
|
domains, move it to a common/shared folder.
|
|
7139
7273
|
`
|
|
@@ -7143,7 +7277,7 @@ Refactor check failed:
|
|
|
7143
7277
|
}
|
|
7144
7278
|
|
|
7145
7279
|
// src/commands/refactor/check/getViolations/index.ts
|
|
7146
|
-
import { execSync as
|
|
7280
|
+
import { execSync as execSync36 } from "child_process";
|
|
7147
7281
|
import fs16 from "fs";
|
|
7148
7282
|
import { minimatch as minimatch4 } from "minimatch";
|
|
7149
7283
|
|
|
@@ -7193,7 +7327,7 @@ function getGitFiles(options2) {
|
|
|
7193
7327
|
}
|
|
7194
7328
|
const files = /* @__PURE__ */ new Set();
|
|
7195
7329
|
if (options2.staged || options2.modified) {
|
|
7196
|
-
const staged =
|
|
7330
|
+
const staged = execSync36("git diff --cached --name-only", {
|
|
7197
7331
|
encoding: "utf-8"
|
|
7198
7332
|
});
|
|
7199
7333
|
for (const file of staged.trim().split("\n").filter(Boolean)) {
|
|
@@ -7201,7 +7335,7 @@ function getGitFiles(options2) {
|
|
|
7201
7335
|
}
|
|
7202
7336
|
}
|
|
7203
7337
|
if (options2.unstaged || options2.modified) {
|
|
7204
|
-
const unstaged =
|
|
7338
|
+
const unstaged = execSync36("git diff --name-only", { encoding: "utf-8" });
|
|
7205
7339
|
for (const file of unstaged.trim().split("\n").filter(Boolean)) {
|
|
7206
7340
|
files.add(file);
|
|
7207
7341
|
}
|
|
@@ -7289,7 +7423,7 @@ async function check(pattern2, options2) {
|
|
|
7289
7423
|
|
|
7290
7424
|
// src/commands/refactor/extract/index.ts
|
|
7291
7425
|
import path33 from "path";
|
|
7292
|
-
import
|
|
7426
|
+
import chalk93 from "chalk";
|
|
7293
7427
|
|
|
7294
7428
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7295
7429
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -7815,23 +7949,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
7815
7949
|
|
|
7816
7950
|
// src/commands/refactor/extract/displayPlan.ts
|
|
7817
7951
|
import path31 from "path";
|
|
7818
|
-
import
|
|
7952
|
+
import chalk91 from "chalk";
|
|
7819
7953
|
function section(title) {
|
|
7820
7954
|
return `
|
|
7821
|
-
${
|
|
7955
|
+
${chalk91.cyan(title)}`;
|
|
7822
7956
|
}
|
|
7823
7957
|
function displayImporters(plan2, cwd) {
|
|
7824
7958
|
if (plan2.importersToUpdate.length === 0) return;
|
|
7825
7959
|
console.log(section("Update importers:"));
|
|
7826
7960
|
for (const imp of plan2.importersToUpdate) {
|
|
7827
7961
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
7828
|
-
console.log(` ${
|
|
7962
|
+
console.log(` ${chalk91.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
7829
7963
|
}
|
|
7830
7964
|
}
|
|
7831
7965
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
7832
|
-
console.log(
|
|
7966
|
+
console.log(chalk91.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
7833
7967
|
`));
|
|
7834
|
-
console.log(` ${
|
|
7968
|
+
console.log(` ${chalk91.cyan("Functions to move:")}`);
|
|
7835
7969
|
for (const name of plan2.extractedNames) {
|
|
7836
7970
|
console.log(` ${name}`);
|
|
7837
7971
|
}
|
|
@@ -7866,7 +8000,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
7866
8000
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
7867
8001
|
import fs17 from "fs";
|
|
7868
8002
|
import path32 from "path";
|
|
7869
|
-
import
|
|
8003
|
+
import chalk92 from "chalk";
|
|
7870
8004
|
import { Project as Project2 } from "ts-morph";
|
|
7871
8005
|
function findTsConfig(sourcePath) {
|
|
7872
8006
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -7897,7 +8031,7 @@ function loadProjectFile(file) {
|
|
|
7897
8031
|
});
|
|
7898
8032
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
7899
8033
|
if (!sourceFile) {
|
|
7900
|
-
console.log(
|
|
8034
|
+
console.log(chalk92.red(`File not found in project: ${file}`));
|
|
7901
8035
|
process.exit(1);
|
|
7902
8036
|
}
|
|
7903
8037
|
return { project, sourceFile };
|
|
@@ -7920,19 +8054,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
7920
8054
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
7921
8055
|
if (options2.apply) {
|
|
7922
8056
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
7923
|
-
console.log(
|
|
8057
|
+
console.log(chalk93.green("\nExtraction complete"));
|
|
7924
8058
|
} else {
|
|
7925
|
-
console.log(
|
|
8059
|
+
console.log(chalk93.dim("\nDry run. Use --apply to execute."));
|
|
7926
8060
|
}
|
|
7927
8061
|
}
|
|
7928
8062
|
|
|
7929
8063
|
// src/commands/refactor/ignore.ts
|
|
7930
8064
|
import fs18 from "fs";
|
|
7931
|
-
import
|
|
8065
|
+
import chalk94 from "chalk";
|
|
7932
8066
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
7933
8067
|
function ignore(file) {
|
|
7934
8068
|
if (!fs18.existsSync(file)) {
|
|
7935
|
-
console.error(
|
|
8069
|
+
console.error(chalk94.red(`Error: File does not exist: ${file}`));
|
|
7936
8070
|
process.exit(1);
|
|
7937
8071
|
}
|
|
7938
8072
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -7948,7 +8082,7 @@ function ignore(file) {
|
|
|
7948
8082
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
7949
8083
|
}
|
|
7950
8084
|
console.log(
|
|
7951
|
-
|
|
8085
|
+
chalk94.green(
|
|
7952
8086
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
7953
8087
|
)
|
|
7954
8088
|
);
|
|
@@ -7956,26 +8090,26 @@ function ignore(file) {
|
|
|
7956
8090
|
|
|
7957
8091
|
// src/commands/refactor/rename/index.ts
|
|
7958
8092
|
import path34 from "path";
|
|
7959
|
-
import
|
|
8093
|
+
import chalk95 from "chalk";
|
|
7960
8094
|
async function rename(source, destination, options2 = {}) {
|
|
7961
8095
|
const destPath = path34.resolve(destination);
|
|
7962
8096
|
const cwd = process.cwd();
|
|
7963
8097
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
7964
8098
|
const relDest = path34.relative(cwd, destPath);
|
|
7965
8099
|
const { project, sourceFile } = loadProjectFile(source);
|
|
7966
|
-
console.log(
|
|
8100
|
+
console.log(chalk95.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
7967
8101
|
if (options2.apply) {
|
|
7968
8102
|
sourceFile.move(destPath);
|
|
7969
8103
|
await project.save();
|
|
7970
|
-
console.log(
|
|
8104
|
+
console.log(chalk95.green("Done"));
|
|
7971
8105
|
} else {
|
|
7972
|
-
console.log(
|
|
8106
|
+
console.log(chalk95.dim("Dry run. Use --apply to execute."));
|
|
7973
8107
|
}
|
|
7974
8108
|
}
|
|
7975
8109
|
|
|
7976
8110
|
// src/commands/refactor/renameSymbol/index.ts
|
|
7977
8111
|
import path36 from "path";
|
|
7978
|
-
import
|
|
8112
|
+
import chalk96 from "chalk";
|
|
7979
8113
|
import { Project as Project3 } from "ts-morph";
|
|
7980
8114
|
|
|
7981
8115
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8024,38 +8158,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8024
8158
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8025
8159
|
const sourceFile = project.getSourceFile(filePath);
|
|
8026
8160
|
if (!sourceFile) {
|
|
8027
|
-
console.log(
|
|
8161
|
+
console.log(chalk96.red(`File not found in project: ${file}`));
|
|
8028
8162
|
process.exit(1);
|
|
8029
8163
|
}
|
|
8030
8164
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8031
8165
|
if (!symbol) {
|
|
8032
|
-
console.log(
|
|
8166
|
+
console.log(chalk96.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8033
8167
|
process.exit(1);
|
|
8034
8168
|
}
|
|
8035
8169
|
const grouped = groupReferences(symbol, cwd);
|
|
8036
8170
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8037
8171
|
console.log(
|
|
8038
|
-
|
|
8172
|
+
chalk96.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8039
8173
|
`)
|
|
8040
8174
|
);
|
|
8041
8175
|
for (const [refFile, lines] of grouped) {
|
|
8042
8176
|
console.log(
|
|
8043
|
-
` ${
|
|
8177
|
+
` ${chalk96.dim(refFile)}: lines ${chalk96.cyan(lines.join(", "))}`
|
|
8044
8178
|
);
|
|
8045
8179
|
}
|
|
8046
8180
|
if (options2.apply) {
|
|
8047
8181
|
symbol.rename(newName);
|
|
8048
8182
|
await project.save();
|
|
8049
|
-
console.log(
|
|
8183
|
+
console.log(chalk96.green(`
|
|
8050
8184
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8051
8185
|
} else {
|
|
8052
|
-
console.log(
|
|
8186
|
+
console.log(chalk96.dim("\nDry run. Use --apply to execute."));
|
|
8053
8187
|
}
|
|
8054
8188
|
}
|
|
8055
8189
|
|
|
8056
8190
|
// src/commands/refactor/restructure/index.ts
|
|
8057
8191
|
import path45 from "path";
|
|
8058
|
-
import
|
|
8192
|
+
import chalk99 from "chalk";
|
|
8059
8193
|
|
|
8060
8194
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8061
8195
|
import path37 from "path";
|
|
@@ -8298,50 +8432,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8298
8432
|
|
|
8299
8433
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8300
8434
|
import path41 from "path";
|
|
8301
|
-
import
|
|
8435
|
+
import chalk97 from "chalk";
|
|
8302
8436
|
function relPath(filePath) {
|
|
8303
8437
|
return path41.relative(process.cwd(), filePath);
|
|
8304
8438
|
}
|
|
8305
8439
|
function displayMoves(plan2) {
|
|
8306
8440
|
if (plan2.moves.length === 0) return;
|
|
8307
|
-
console.log(
|
|
8441
|
+
console.log(chalk97.bold("\nFile moves:"));
|
|
8308
8442
|
for (const move of plan2.moves) {
|
|
8309
8443
|
console.log(
|
|
8310
|
-
` ${
|
|
8444
|
+
` ${chalk97.red(relPath(move.from))} \u2192 ${chalk97.green(relPath(move.to))}`
|
|
8311
8445
|
);
|
|
8312
|
-
console.log(
|
|
8446
|
+
console.log(chalk97.dim(` ${move.reason}`));
|
|
8313
8447
|
}
|
|
8314
8448
|
}
|
|
8315
8449
|
function displayRewrites(rewrites) {
|
|
8316
8450
|
if (rewrites.length === 0) return;
|
|
8317
8451
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8318
|
-
console.log(
|
|
8452
|
+
console.log(chalk97.bold(`
|
|
8319
8453
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8320
8454
|
for (const file of affectedFiles) {
|
|
8321
|
-
console.log(` ${
|
|
8455
|
+
console.log(` ${chalk97.cyan(relPath(file))}:`);
|
|
8322
8456
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8323
8457
|
(r) => r.file === file
|
|
8324
8458
|
)) {
|
|
8325
8459
|
console.log(
|
|
8326
|
-
` ${
|
|
8460
|
+
` ${chalk97.red(`"${oldSpecifier}"`)} \u2192 ${chalk97.green(`"${newSpecifier}"`)}`
|
|
8327
8461
|
);
|
|
8328
8462
|
}
|
|
8329
8463
|
}
|
|
8330
8464
|
}
|
|
8331
8465
|
function displayPlan2(plan2) {
|
|
8332
8466
|
if (plan2.warnings.length > 0) {
|
|
8333
|
-
console.log(
|
|
8334
|
-
for (const w of plan2.warnings) console.log(
|
|
8467
|
+
console.log(chalk97.yellow("\nWarnings:"));
|
|
8468
|
+
for (const w of plan2.warnings) console.log(chalk97.yellow(` ${w}`));
|
|
8335
8469
|
}
|
|
8336
8470
|
if (plan2.newDirectories.length > 0) {
|
|
8337
|
-
console.log(
|
|
8471
|
+
console.log(chalk97.bold("\nNew directories:"));
|
|
8338
8472
|
for (const dir of plan2.newDirectories)
|
|
8339
|
-
console.log(
|
|
8473
|
+
console.log(chalk97.green(` ${dir}/`));
|
|
8340
8474
|
}
|
|
8341
8475
|
displayMoves(plan2);
|
|
8342
8476
|
displayRewrites(plan2.rewrites);
|
|
8343
8477
|
console.log(
|
|
8344
|
-
|
|
8478
|
+
chalk97.dim(
|
|
8345
8479
|
`
|
|
8346
8480
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8347
8481
|
)
|
|
@@ -8351,18 +8485,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8351
8485
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8352
8486
|
import fs20 from "fs";
|
|
8353
8487
|
import path42 from "path";
|
|
8354
|
-
import
|
|
8488
|
+
import chalk98 from "chalk";
|
|
8355
8489
|
function executePlan(plan2) {
|
|
8356
8490
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8357
8491
|
for (const [file, content] of updatedContents) {
|
|
8358
8492
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8359
8493
|
console.log(
|
|
8360
|
-
|
|
8494
|
+
chalk98.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8361
8495
|
);
|
|
8362
8496
|
}
|
|
8363
8497
|
for (const dir of plan2.newDirectories) {
|
|
8364
8498
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8365
|
-
console.log(
|
|
8499
|
+
console.log(chalk98.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8366
8500
|
}
|
|
8367
8501
|
for (const move of plan2.moves) {
|
|
8368
8502
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8371,7 +8505,7 @@ function executePlan(plan2) {
|
|
|
8371
8505
|
}
|
|
8372
8506
|
fs20.renameSync(move.from, move.to);
|
|
8373
8507
|
console.log(
|
|
8374
|
-
|
|
8508
|
+
chalk98.white(
|
|
8375
8509
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8376
8510
|
)
|
|
8377
8511
|
);
|
|
@@ -8386,7 +8520,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8386
8520
|
if (entries.length === 0) {
|
|
8387
8521
|
fs20.rmdirSync(dir);
|
|
8388
8522
|
console.log(
|
|
8389
|
-
|
|
8523
|
+
chalk98.dim(
|
|
8390
8524
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8391
8525
|
)
|
|
8392
8526
|
);
|
|
@@ -8519,22 +8653,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8519
8653
|
const targetPattern = pattern2 ?? "src";
|
|
8520
8654
|
const files = findSourceFiles2(targetPattern);
|
|
8521
8655
|
if (files.length === 0) {
|
|
8522
|
-
console.log(
|
|
8656
|
+
console.log(chalk99.yellow("No files found matching pattern"));
|
|
8523
8657
|
return;
|
|
8524
8658
|
}
|
|
8525
8659
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8526
8660
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8527
8661
|
if (plan2.moves.length === 0) {
|
|
8528
|
-
console.log(
|
|
8662
|
+
console.log(chalk99.green("No restructuring needed"));
|
|
8529
8663
|
return;
|
|
8530
8664
|
}
|
|
8531
8665
|
displayPlan2(plan2);
|
|
8532
8666
|
if (options2.apply) {
|
|
8533
|
-
console.log(
|
|
8667
|
+
console.log(chalk99.bold("\nApplying changes..."));
|
|
8534
8668
|
executePlan(plan2);
|
|
8535
|
-
console.log(
|
|
8669
|
+
console.log(chalk99.green("\nRestructuring complete"));
|
|
8536
8670
|
} else {
|
|
8537
|
-
console.log(
|
|
8671
|
+
console.log(chalk99.dim("\nDry run. Use --apply to execute."));
|
|
8538
8672
|
}
|
|
8539
8673
|
}
|
|
8540
8674
|
|
|
@@ -8574,7 +8708,7 @@ function registerRefactor(program2) {
|
|
|
8574
8708
|
}
|
|
8575
8709
|
|
|
8576
8710
|
// src/commands/seq/seqAuth.ts
|
|
8577
|
-
import
|
|
8711
|
+
import chalk101 from "chalk";
|
|
8578
8712
|
|
|
8579
8713
|
// src/commands/seq/loadConnections.ts
|
|
8580
8714
|
function loadConnections2() {
|
|
@@ -8603,11 +8737,11 @@ function setDefaultConnection(name) {
|
|
|
8603
8737
|
}
|
|
8604
8738
|
|
|
8605
8739
|
// src/commands/seq/promptConnection.ts
|
|
8606
|
-
import
|
|
8740
|
+
import chalk100 from "chalk";
|
|
8607
8741
|
async function promptConnection2(existingNames) {
|
|
8608
8742
|
const name = await promptInput("name", "Connection name:", "default");
|
|
8609
8743
|
if (existingNames.includes(name)) {
|
|
8610
|
-
console.error(
|
|
8744
|
+
console.error(chalk100.red(`Connection "${name}" already exists.`));
|
|
8611
8745
|
process.exit(1);
|
|
8612
8746
|
}
|
|
8613
8747
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -8619,32 +8753,32 @@ async function promptConnection2(existingNames) {
|
|
|
8619
8753
|
var seqAuth = createConnectionAuth({
|
|
8620
8754
|
load: loadConnections2,
|
|
8621
8755
|
save: saveConnections2,
|
|
8622
|
-
format: (c) => `${
|
|
8756
|
+
format: (c) => `${chalk101.bold(c.name)} ${c.url}`,
|
|
8623
8757
|
promptNew: promptConnection2,
|
|
8624
8758
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
8625
8759
|
});
|
|
8626
8760
|
|
|
8627
8761
|
// src/commands/seq/seqQuery.ts
|
|
8628
|
-
import
|
|
8762
|
+
import chalk104 from "chalk";
|
|
8629
8763
|
|
|
8630
8764
|
// src/commands/seq/formatEvent.ts
|
|
8631
|
-
import
|
|
8765
|
+
import chalk102 from "chalk";
|
|
8632
8766
|
function levelColor(level) {
|
|
8633
8767
|
switch (level) {
|
|
8634
8768
|
case "Fatal":
|
|
8635
|
-
return
|
|
8769
|
+
return chalk102.bgRed.white;
|
|
8636
8770
|
case "Error":
|
|
8637
|
-
return
|
|
8771
|
+
return chalk102.red;
|
|
8638
8772
|
case "Warning":
|
|
8639
|
-
return
|
|
8773
|
+
return chalk102.yellow;
|
|
8640
8774
|
case "Information":
|
|
8641
|
-
return
|
|
8775
|
+
return chalk102.cyan;
|
|
8642
8776
|
case "Debug":
|
|
8643
|
-
return
|
|
8777
|
+
return chalk102.gray;
|
|
8644
8778
|
case "Verbose":
|
|
8645
|
-
return
|
|
8779
|
+
return chalk102.dim;
|
|
8646
8780
|
default:
|
|
8647
|
-
return
|
|
8781
|
+
return chalk102.white;
|
|
8648
8782
|
}
|
|
8649
8783
|
}
|
|
8650
8784
|
function levelAbbrev(level) {
|
|
@@ -8685,31 +8819,31 @@ function formatTimestamp(iso) {
|
|
|
8685
8819
|
function formatEvent(event) {
|
|
8686
8820
|
const color = levelColor(event.Level);
|
|
8687
8821
|
const abbrev = levelAbbrev(event.Level);
|
|
8688
|
-
const ts8 =
|
|
8822
|
+
const ts8 = chalk102.dim(formatTimestamp(event.Timestamp));
|
|
8689
8823
|
const msg = renderMessage(event);
|
|
8690
8824
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
8691
8825
|
if (event.Exception) {
|
|
8692
8826
|
for (const line of event.Exception.split("\n")) {
|
|
8693
|
-
lines.push(
|
|
8827
|
+
lines.push(chalk102.red(` ${line}`));
|
|
8694
8828
|
}
|
|
8695
8829
|
}
|
|
8696
8830
|
return lines.join("\n");
|
|
8697
8831
|
}
|
|
8698
8832
|
|
|
8699
8833
|
// src/commands/seq/resolveConnection.ts
|
|
8700
|
-
import
|
|
8834
|
+
import chalk103 from "chalk";
|
|
8701
8835
|
function resolveConnection2(name) {
|
|
8702
8836
|
const connections = loadConnections2();
|
|
8703
8837
|
if (connections.length === 0) {
|
|
8704
8838
|
console.error(
|
|
8705
|
-
|
|
8839
|
+
chalk103.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
8706
8840
|
);
|
|
8707
8841
|
process.exit(1);
|
|
8708
8842
|
}
|
|
8709
8843
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
8710
8844
|
const connection = connections.find((c) => c.name === target);
|
|
8711
8845
|
if (!connection) {
|
|
8712
|
-
console.error(
|
|
8846
|
+
console.error(chalk103.red(`Seq connection "${target}" not found.`));
|
|
8713
8847
|
process.exit(1);
|
|
8714
8848
|
}
|
|
8715
8849
|
return connection;
|
|
@@ -8729,12 +8863,12 @@ async function seqQuery(filter, options2) {
|
|
|
8729
8863
|
});
|
|
8730
8864
|
if (!response.ok) {
|
|
8731
8865
|
const body = await response.text();
|
|
8732
|
-
console.error(
|
|
8866
|
+
console.error(chalk104.red(`Seq returned ${response.status}: ${body}`));
|
|
8733
8867
|
process.exit(1);
|
|
8734
8868
|
}
|
|
8735
8869
|
const events = await response.json();
|
|
8736
8870
|
if (events.length === 0) {
|
|
8737
|
-
console.log(
|
|
8871
|
+
console.log(chalk104.yellow("No events found."));
|
|
8738
8872
|
return;
|
|
8739
8873
|
}
|
|
8740
8874
|
if (options2.json) {
|
|
@@ -8745,11 +8879,11 @@ async function seqQuery(filter, options2) {
|
|
|
8745
8879
|
for (const event of chronological) {
|
|
8746
8880
|
console.log(formatEvent(event));
|
|
8747
8881
|
}
|
|
8748
|
-
console.log(
|
|
8882
|
+
console.log(chalk104.dim(`
|
|
8749
8883
|
${events.length} events`));
|
|
8750
8884
|
if (events.length >= count) {
|
|
8751
8885
|
console.log(
|
|
8752
|
-
|
|
8886
|
+
chalk104.yellow(
|
|
8753
8887
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
8754
8888
|
)
|
|
8755
8889
|
);
|
|
@@ -8757,11 +8891,11 @@ ${events.length} events`));
|
|
|
8757
8891
|
}
|
|
8758
8892
|
|
|
8759
8893
|
// src/commands/seq/seqSetConnection.ts
|
|
8760
|
-
import
|
|
8894
|
+
import chalk105 from "chalk";
|
|
8761
8895
|
function seqSetConnection(name) {
|
|
8762
8896
|
const connections = loadConnections2();
|
|
8763
8897
|
if (!connections.find((c) => c.name === name)) {
|
|
8764
|
-
console.error(
|
|
8898
|
+
console.error(chalk105.red(`Connection "${name}" not found.`));
|
|
8765
8899
|
process.exit(1);
|
|
8766
8900
|
}
|
|
8767
8901
|
setDefaultConnection(name);
|
|
@@ -9300,14 +9434,14 @@ import {
|
|
|
9300
9434
|
import { dirname as dirname20, join as join29 } from "path";
|
|
9301
9435
|
|
|
9302
9436
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9303
|
-
import
|
|
9437
|
+
import chalk106 from "chalk";
|
|
9304
9438
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9305
9439
|
function validateStagedContent(filename, content) {
|
|
9306
9440
|
const firstLine = content.split("\n")[0];
|
|
9307
9441
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9308
9442
|
if (!match) {
|
|
9309
9443
|
console.error(
|
|
9310
|
-
|
|
9444
|
+
chalk106.red(
|
|
9311
9445
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9312
9446
|
)
|
|
9313
9447
|
);
|
|
@@ -9316,7 +9450,7 @@ function validateStagedContent(filename, content) {
|
|
|
9316
9450
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9317
9451
|
if (!contentAfterLink) {
|
|
9318
9452
|
console.error(
|
|
9319
|
-
|
|
9453
|
+
chalk106.red(
|
|
9320
9454
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9321
9455
|
)
|
|
9322
9456
|
);
|
|
@@ -9516,7 +9650,7 @@ import { mkdirSync as mkdirSync10 } from "fs";
|
|
|
9516
9650
|
import { join as join34 } from "path";
|
|
9517
9651
|
|
|
9518
9652
|
// src/commands/voice/checkLockFile.ts
|
|
9519
|
-
import { execSync as
|
|
9653
|
+
import { execSync as execSync37 } from "child_process";
|
|
9520
9654
|
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync26, writeFileSync as writeFileSync24 } from "fs";
|
|
9521
9655
|
import { join as join33 } from "path";
|
|
9522
9656
|
function isProcessAlive(pid) {
|
|
@@ -9545,7 +9679,7 @@ function bootstrapVenv() {
|
|
|
9545
9679
|
if (existsSync35(getVenvPython())) return;
|
|
9546
9680
|
console.log("Setting up Python environment...");
|
|
9547
9681
|
const pythonDir = getPythonDir();
|
|
9548
|
-
|
|
9682
|
+
execSync37(
|
|
9549
9683
|
`uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
|
|
9550
9684
|
{
|
|
9551
9685
|
stdio: "inherit",
|
|
@@ -9709,14 +9843,14 @@ function registerVoice(program2) {
|
|
|
9709
9843
|
|
|
9710
9844
|
// src/commands/roam/auth.ts
|
|
9711
9845
|
import { randomBytes } from "crypto";
|
|
9712
|
-
import
|
|
9846
|
+
import chalk107 from "chalk";
|
|
9713
9847
|
|
|
9714
9848
|
// src/lib/openBrowser.ts
|
|
9715
|
-
import { execSync as
|
|
9849
|
+
import { execSync as execSync38 } from "child_process";
|
|
9716
9850
|
function tryExec(commands) {
|
|
9717
9851
|
for (const cmd of commands) {
|
|
9718
9852
|
try {
|
|
9719
|
-
|
|
9853
|
+
execSync38(cmd);
|
|
9720
9854
|
return true;
|
|
9721
9855
|
} catch {
|
|
9722
9856
|
}
|
|
@@ -9884,13 +10018,13 @@ async function auth() {
|
|
|
9884
10018
|
saveGlobalConfig(config);
|
|
9885
10019
|
const state = randomBytes(16).toString("hex");
|
|
9886
10020
|
console.log(
|
|
9887
|
-
|
|
10021
|
+
chalk107.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
9888
10022
|
);
|
|
9889
|
-
console.log(
|
|
9890
|
-
console.log(
|
|
9891
|
-
console.log(
|
|
10023
|
+
console.log(chalk107.white("http://localhost:14523/callback\n"));
|
|
10024
|
+
console.log(chalk107.blue("Opening browser for authorization..."));
|
|
10025
|
+
console.log(chalk107.dim("Waiting for authorization callback..."));
|
|
9892
10026
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
9893
|
-
console.log(
|
|
10027
|
+
console.log(chalk107.dim("Exchanging code for tokens..."));
|
|
9894
10028
|
const tokens = await exchangeToken({
|
|
9895
10029
|
code,
|
|
9896
10030
|
clientId,
|
|
@@ -9906,7 +10040,7 @@ async function auth() {
|
|
|
9906
10040
|
};
|
|
9907
10041
|
saveGlobalConfig(config);
|
|
9908
10042
|
console.log(
|
|
9909
|
-
|
|
10043
|
+
chalk107.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
9910
10044
|
);
|
|
9911
10045
|
}
|
|
9912
10046
|
|
|
@@ -9942,7 +10076,7 @@ function registerRoam(program2) {
|
|
|
9942
10076
|
}
|
|
9943
10077
|
|
|
9944
10078
|
// src/commands/run/index.ts
|
|
9945
|
-
import { execSync as
|
|
10079
|
+
import { execSync as execSync39 } from "child_process";
|
|
9946
10080
|
|
|
9947
10081
|
// src/commands/run/resolveParams.ts
|
|
9948
10082
|
function resolveParams(params, cliArgs) {
|
|
@@ -10097,7 +10231,7 @@ function listRunConfigs() {
|
|
|
10097
10231
|
function runPreCommands(pre) {
|
|
10098
10232
|
for (const cmd of pre) {
|
|
10099
10233
|
try {
|
|
10100
|
-
|
|
10234
|
+
execSync39(cmd, { stdio: "inherit" });
|
|
10101
10235
|
} catch (err) {
|
|
10102
10236
|
const code = err && typeof err === "object" && "status" in err ? err.status : 1;
|
|
10103
10237
|
process.exit(code);
|
|
@@ -10115,11 +10249,11 @@ function run3(name, args) {
|
|
|
10115
10249
|
}
|
|
10116
10250
|
|
|
10117
10251
|
// src/commands/screenshot/index.ts
|
|
10118
|
-
import { execSync as
|
|
10252
|
+
import { execSync as execSync40 } from "child_process";
|
|
10119
10253
|
import { existsSync as existsSync38, mkdirSync as mkdirSync13, unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
|
|
10120
10254
|
import { tmpdir as tmpdir6 } from "os";
|
|
10121
10255
|
import { join as join38, resolve as resolve5 } from "path";
|
|
10122
|
-
import
|
|
10256
|
+
import chalk108 from "chalk";
|
|
10123
10257
|
|
|
10124
10258
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10125
10259
|
var captureWindowPs1 = `
|
|
@@ -10258,7 +10392,7 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
10258
10392
|
const scriptPath = join38(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
|
|
10259
10393
|
writeFileSync27(scriptPath, captureWindowPs1, "utf-8");
|
|
10260
10394
|
try {
|
|
10261
|
-
|
|
10395
|
+
execSync40(
|
|
10262
10396
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
10263
10397
|
{ stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }
|
|
10264
10398
|
);
|
|
@@ -10270,22 +10404,22 @@ function screenshot(processName) {
|
|
|
10270
10404
|
const config = loadConfig();
|
|
10271
10405
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10272
10406
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10273
|
-
console.log(
|
|
10407
|
+
console.log(chalk108.gray(`Capturing window for process "${processName}" ...`));
|
|
10274
10408
|
try {
|
|
10275
10409
|
runPowerShellScript(processName, outputPath);
|
|
10276
|
-
console.log(
|
|
10410
|
+
console.log(chalk108.green(`Screenshot saved: ${outputPath}`));
|
|
10277
10411
|
} catch (error) {
|
|
10278
10412
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10279
|
-
console.error(
|
|
10413
|
+
console.error(chalk108.red(`Failed to capture screenshot: ${msg}`));
|
|
10280
10414
|
process.exit(1);
|
|
10281
10415
|
}
|
|
10282
10416
|
}
|
|
10283
10417
|
|
|
10284
10418
|
// src/commands/statusLine.ts
|
|
10285
|
-
import
|
|
10419
|
+
import chalk110 from "chalk";
|
|
10286
10420
|
|
|
10287
10421
|
// src/commands/buildLimitsSegment.ts
|
|
10288
|
-
import
|
|
10422
|
+
import chalk109 from "chalk";
|
|
10289
10423
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10290
10424
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10291
10425
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10308,10 +10442,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10308
10442
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10309
10443
|
const label2 = `${Math.round(pct)}%`;
|
|
10310
10444
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10311
|
-
if (projected == null) return
|
|
10312
|
-
if (projected > 100) return
|
|
10313
|
-
if (projected > 75) return
|
|
10314
|
-
return
|
|
10445
|
+
if (projected == null) return chalk109.green(label2);
|
|
10446
|
+
if (projected > 100) return chalk109.red(label2);
|
|
10447
|
+
if (projected > 75) return chalk109.yellow(label2);
|
|
10448
|
+
return chalk109.green(label2);
|
|
10315
10449
|
}
|
|
10316
10450
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10317
10451
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10337,14 +10471,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10337
10471
|
}
|
|
10338
10472
|
|
|
10339
10473
|
// src/commands/statusLine.ts
|
|
10340
|
-
|
|
10474
|
+
chalk110.level = 3;
|
|
10341
10475
|
function formatNumber(num) {
|
|
10342
10476
|
return num.toLocaleString("en-US");
|
|
10343
10477
|
}
|
|
10344
10478
|
function colorizePercent(pct) {
|
|
10345
10479
|
const label2 = `${Math.round(pct)}%`;
|
|
10346
|
-
if (pct > 80) return
|
|
10347
|
-
if (pct > 40) return
|
|
10480
|
+
if (pct > 80) return chalk110.red(label2);
|
|
10481
|
+
if (pct > 40) return chalk110.yellow(label2);
|
|
10348
10482
|
return label2;
|
|
10349
10483
|
}
|
|
10350
10484
|
async function statusLine() {
|
|
@@ -10367,7 +10501,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10367
10501
|
// src/commands/sync/syncClaudeMd.ts
|
|
10368
10502
|
import * as fs23 from "fs";
|
|
10369
10503
|
import * as path46 from "path";
|
|
10370
|
-
import
|
|
10504
|
+
import chalk111 from "chalk";
|
|
10371
10505
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10372
10506
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10373
10507
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10376,12 +10510,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10376
10510
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10377
10511
|
if (sourceContent !== targetContent) {
|
|
10378
10512
|
console.log(
|
|
10379
|
-
|
|
10513
|
+
chalk111.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10380
10514
|
);
|
|
10381
10515
|
console.log();
|
|
10382
10516
|
printDiff(targetContent, sourceContent);
|
|
10383
10517
|
const confirm = options2?.yes || await promptConfirm(
|
|
10384
|
-
|
|
10518
|
+
chalk111.red("Overwrite existing CLAUDE.md?"),
|
|
10385
10519
|
false
|
|
10386
10520
|
);
|
|
10387
10521
|
if (!confirm) {
|
|
@@ -10397,7 +10531,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10397
10531
|
// src/commands/sync/syncSettings.ts
|
|
10398
10532
|
import * as fs24 from "fs";
|
|
10399
10533
|
import * as path47 from "path";
|
|
10400
|
-
import
|
|
10534
|
+
import chalk112 from "chalk";
|
|
10401
10535
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10402
10536
|
const source = path47.join(claudeDir, "settings.json");
|
|
10403
10537
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10413,14 +10547,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10413
10547
|
if (mergedContent !== normalizedTarget) {
|
|
10414
10548
|
if (!options2?.yes) {
|
|
10415
10549
|
console.log(
|
|
10416
|
-
|
|
10550
|
+
chalk112.yellow(
|
|
10417
10551
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10418
10552
|
)
|
|
10419
10553
|
);
|
|
10420
10554
|
console.log();
|
|
10421
10555
|
printDiff(targetContent, mergedContent);
|
|
10422
10556
|
const confirm = await promptConfirm(
|
|
10423
|
-
|
|
10557
|
+
chalk112.red("Overwrite existing settings.json?"),
|
|
10424
10558
|
false
|
|
10425
10559
|
);
|
|
10426
10560
|
if (!confirm) {
|
|
@@ -10457,7 +10591,7 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
10457
10591
|
}
|
|
10458
10592
|
|
|
10459
10593
|
// src/commands/update.ts
|
|
10460
|
-
import { execSync as
|
|
10594
|
+
import { execSync as execSync41 } from "child_process";
|
|
10461
10595
|
import * as path49 from "path";
|
|
10462
10596
|
function isGlobalNpmInstall(dir) {
|
|
10463
10597
|
try {
|
|
@@ -10465,7 +10599,7 @@ function isGlobalNpmInstall(dir) {
|
|
|
10465
10599
|
if (resolved.split(path49.sep).includes("node_modules")) {
|
|
10466
10600
|
return true;
|
|
10467
10601
|
}
|
|
10468
|
-
const globalPrefix =
|
|
10602
|
+
const globalPrefix = execSync41("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
10469
10603
|
return resolved.toLowerCase().startsWith(path49.resolve(globalPrefix).toLowerCase());
|
|
10470
10604
|
} catch {
|
|
10471
10605
|
return false;
|
|
@@ -10476,18 +10610,18 @@ async function update() {
|
|
|
10476
10610
|
console.log(`Assist is installed at: ${installDir}`);
|
|
10477
10611
|
if (isGitRepo(installDir)) {
|
|
10478
10612
|
console.log("Detected git repo installation, pulling latest...");
|
|
10479
|
-
|
|
10613
|
+
execSync41("git pull", { cwd: installDir, stdio: "inherit" });
|
|
10480
10614
|
console.log("Installing dependencies...");
|
|
10481
|
-
|
|
10615
|
+
execSync41("npm i", { cwd: installDir, stdio: "inherit" });
|
|
10482
10616
|
console.log("Building...");
|
|
10483
|
-
|
|
10617
|
+
execSync41("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
10484
10618
|
console.log("Syncing commands...");
|
|
10485
|
-
|
|
10619
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
10486
10620
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
10487
10621
|
console.log("Detected global npm installation, updating...");
|
|
10488
|
-
|
|
10622
|
+
execSync41("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
10489
10623
|
console.log("Syncing commands...");
|
|
10490
|
-
|
|
10624
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
10491
10625
|
} else {
|
|
10492
10626
|
console.error(
|
|
10493
10627
|
"Could not determine installation method. Expected a git repo or global npm install."
|