@staff0rd/assist 0.166.1 → 0.168.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/{assist.cli-reads → allowed.cli-reads} +0 -13
- package/allowed.cli-writes +15 -0
- package/dist/index.js +635 -460
- package/package.json +3 -2
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.168.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -17,7 +17,8 @@ var package_default = {
|
|
|
17
17
|
files: [
|
|
18
18
|
"dist",
|
|
19
19
|
"claude",
|
|
20
|
-
"
|
|
20
|
+
"allowed.cli-reads",
|
|
21
|
+
"allowed.cli-writes"
|
|
21
22
|
],
|
|
22
23
|
publishConfig: {
|
|
23
24
|
access: "public"
|
|
@@ -125,6 +126,11 @@ var backlogCommentSchema = z.strictObject({
|
|
|
125
126
|
timestamp: z.string(),
|
|
126
127
|
type: backlogCommentTypeSchema
|
|
127
128
|
});
|
|
129
|
+
var backlogLinkTypeSchema = z.enum(["relates-to", "depends-on"]);
|
|
130
|
+
var backlogLinkSchema = z.strictObject({
|
|
131
|
+
type: backlogLinkTypeSchema,
|
|
132
|
+
targetId: z.number()
|
|
133
|
+
});
|
|
128
134
|
var backlogItemSchema = z.strictObject({
|
|
129
135
|
id: z.number(),
|
|
130
136
|
type: backlogTypeSchema.default("story"),
|
|
@@ -134,7 +140,8 @@ var backlogItemSchema = z.strictObject({
|
|
|
134
140
|
plan: z.array(planPhaseSchema).optional(),
|
|
135
141
|
currentPhase: z.number().optional(),
|
|
136
142
|
status: backlogStatusSchema,
|
|
137
|
-
comments: z.array(backlogCommentSchema).optional()
|
|
143
|
+
comments: z.array(backlogCommentSchema).optional(),
|
|
144
|
+
links: z.array(backlogLinkSchema).optional()
|
|
138
145
|
});
|
|
139
146
|
var backlogFileSchema = z.array(backlogItemSchema);
|
|
140
147
|
|
|
@@ -273,6 +280,11 @@ function phaseLabel(item) {
|
|
|
273
280
|
` (phase ${(item.currentPhase ?? 0) + 1}/${item.plan.length})`
|
|
274
281
|
);
|
|
275
282
|
}
|
|
283
|
+
function dependencyLabel(item) {
|
|
284
|
+
const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
|
|
285
|
+
if (deps2.length === 0) return "";
|
|
286
|
+
return chalk2.dim(` [${deps2.length} dep${deps2.length > 1 ? "s" : ""}]`);
|
|
287
|
+
}
|
|
276
288
|
function printVerboseDetails(item) {
|
|
277
289
|
if (item.description) {
|
|
278
290
|
console.log(` ${chalk2.dim("Description:")} ${item.description}`);
|
|
@@ -742,7 +754,7 @@ function plan(id) {
|
|
|
742
754
|
}
|
|
743
755
|
|
|
744
756
|
// src/commands/backlog/show/index.ts
|
|
745
|
-
import
|
|
757
|
+
import chalk13 from "chalk";
|
|
746
758
|
|
|
747
759
|
// src/commands/backlog/formatComment.ts
|
|
748
760
|
import chalk10 from "chalk";
|
|
@@ -754,49 +766,74 @@ function formatComment(entry) {
|
|
|
754
766
|
${entry.text}`;
|
|
755
767
|
}
|
|
756
768
|
|
|
757
|
-
// src/commands/backlog/show/
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
769
|
+
// src/commands/backlog/show/printLinks.ts
|
|
770
|
+
import chalk11 from "chalk";
|
|
771
|
+
function printLinks(item, items) {
|
|
772
|
+
const links = item.links ?? [];
|
|
773
|
+
if (links.length === 0) return;
|
|
774
|
+
console.log(chalk11.bold("Links"));
|
|
775
|
+
for (const link2 of links) {
|
|
776
|
+
const target = items.find((i) => i.id === link2.targetId);
|
|
777
|
+
const typeLabel2 = link2.type === "depends-on" ? chalk11.red("depends-on") : chalk11.blue("relates-to");
|
|
778
|
+
if (target) {
|
|
779
|
+
console.log(
|
|
780
|
+
` ${typeLabel2} #${target.id} ${target.name} ${chalk11.dim(`(${target.status})`)}`
|
|
781
|
+
);
|
|
782
|
+
} else {
|
|
783
|
+
console.log(
|
|
784
|
+
` ${typeLabel2} #${link2.targetId} ${chalk11.dim("(not found)")}`
|
|
785
|
+
);
|
|
786
|
+
}
|
|
764
787
|
}
|
|
765
788
|
console.log();
|
|
766
789
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
return `${marker}${label2}`;
|
|
771
|
-
}
|
|
790
|
+
|
|
791
|
+
// src/commands/backlog/show/printPhaseTasks.ts
|
|
792
|
+
import chalk12 from "chalk";
|
|
772
793
|
function printPhaseTasks(phase) {
|
|
773
794
|
for (const task of phase.tasks) {
|
|
774
795
|
console.log(` - ${task.task}`);
|
|
775
796
|
if (task.verify) {
|
|
776
|
-
console.log(` ${
|
|
797
|
+
console.log(` ${chalk12.dim(`verify: ${task.verify}`)}`);
|
|
777
798
|
}
|
|
778
799
|
}
|
|
779
800
|
if (phase.manualChecks && phase.manualChecks.length > 0) {
|
|
780
|
-
console.log(` ${
|
|
801
|
+
console.log(` ${chalk12.dim("Manual checks:")}`);
|
|
781
802
|
for (const check2 of phase.manualChecks) {
|
|
782
|
-
console.log(` ${
|
|
803
|
+
console.log(` ${chalk12.dim(`- ${check2}`)}`);
|
|
783
804
|
}
|
|
784
805
|
}
|
|
785
806
|
}
|
|
807
|
+
|
|
808
|
+
// src/commands/backlog/show/index.ts
|
|
809
|
+
function printPlan(item) {
|
|
810
|
+
if (!item.plan || item.plan.length === 0) return;
|
|
811
|
+
console.log(chalk13.bold("Plan"));
|
|
812
|
+
for (const [i, phase] of item.plan.entries()) {
|
|
813
|
+
const isCurrent = item.currentPhase === i;
|
|
814
|
+
printPhase(phase, i, isCurrent);
|
|
815
|
+
}
|
|
816
|
+
console.log();
|
|
817
|
+
}
|
|
818
|
+
function phaseHeader(index, name, isCurrent) {
|
|
819
|
+
const marker = isCurrent ? chalk13.green("\u25B6 ") : " ";
|
|
820
|
+
const label2 = isCurrent ? chalk13.green.bold(`Phase ${index + 1}: ${name}`) : `${chalk13.bold(`Phase ${index + 1}:`)} ${name}`;
|
|
821
|
+
return `${marker}${label2}`;
|
|
822
|
+
}
|
|
786
823
|
function printPhase(phase, index, isCurrent) {
|
|
787
824
|
console.log(phaseHeader(index, phase.name, isCurrent));
|
|
788
825
|
printPhaseTasks(phase);
|
|
789
826
|
}
|
|
790
827
|
function printHeader(item) {
|
|
791
|
-
console.log(
|
|
828
|
+
console.log(chalk13.bold(`#${item.id} ${item.name}`));
|
|
792
829
|
console.log(
|
|
793
|
-
`${
|
|
830
|
+
`${chalk13.dim("Type:")} ${item.type} ${chalk13.dim("Status:")} ${item.status}`
|
|
794
831
|
);
|
|
795
832
|
console.log();
|
|
796
833
|
}
|
|
797
834
|
function printAcceptanceCriteria(criteria) {
|
|
798
835
|
if (criteria.length === 0) return;
|
|
799
|
-
console.log(
|
|
836
|
+
console.log(chalk13.bold("Acceptance Criteria"));
|
|
800
837
|
for (const [i, ac] of criteria.entries()) {
|
|
801
838
|
console.log(` ${i + 1}. ${ac}`);
|
|
802
839
|
}
|
|
@@ -805,21 +842,22 @@ function printAcceptanceCriteria(criteria) {
|
|
|
805
842
|
function show(id) {
|
|
806
843
|
const result = loadAndFindItem(id);
|
|
807
844
|
if (!result) process.exit(1);
|
|
808
|
-
const { item } = result;
|
|
845
|
+
const { item, items } = result;
|
|
809
846
|
printHeader(item);
|
|
810
847
|
if (item.description) {
|
|
811
|
-
console.log(
|
|
848
|
+
console.log(chalk13.bold("Description"));
|
|
812
849
|
console.log(item.description);
|
|
813
850
|
console.log();
|
|
814
851
|
}
|
|
815
852
|
printAcceptanceCriteria(item.acceptanceCriteria);
|
|
853
|
+
printLinks(item, items);
|
|
816
854
|
printPlan(item);
|
|
817
855
|
printComments(item);
|
|
818
856
|
}
|
|
819
857
|
function printComments(item) {
|
|
820
858
|
const entries = item.comments ?? [];
|
|
821
859
|
if (entries.length === 0) return;
|
|
822
|
-
console.log(
|
|
860
|
+
console.log(chalk13.bold("Comments"));
|
|
823
861
|
for (const entry of entries) {
|
|
824
862
|
console.log(` ${formatComment(entry)}`);
|
|
825
863
|
}
|
|
@@ -834,7 +872,7 @@ import {
|
|
|
834
872
|
} from "http";
|
|
835
873
|
import { dirname, join as join4 } from "path";
|
|
836
874
|
import { fileURLToPath } from "url";
|
|
837
|
-
import
|
|
875
|
+
import chalk14 from "chalk";
|
|
838
876
|
function respondJson(res, status2, data) {
|
|
839
877
|
res.writeHead(status2, { "Content-Type": "application/json" });
|
|
840
878
|
res.end(JSON.stringify(data));
|
|
@@ -878,8 +916,8 @@ function startWebServer(label2, port, handler) {
|
|
|
878
916
|
handler(req, res, port);
|
|
879
917
|
});
|
|
880
918
|
server.listen(port, () => {
|
|
881
|
-
console.log(
|
|
882
|
-
console.log(
|
|
919
|
+
console.log(chalk14.green(`${label2}: ${url}`));
|
|
920
|
+
console.log(chalk14.dim("Press Ctrl+C to stop"));
|
|
883
921
|
exec(`open ${url}`);
|
|
884
922
|
});
|
|
885
923
|
}
|
|
@@ -1027,7 +1065,7 @@ async function web(options2) {
|
|
|
1027
1065
|
}
|
|
1028
1066
|
|
|
1029
1067
|
// src/commands/backlog/launchMode.ts
|
|
1030
|
-
import
|
|
1068
|
+
import chalk15 from "chalk";
|
|
1031
1069
|
async function launchMode(slashCommand) {
|
|
1032
1070
|
process.env.ASSIST_SESSION_ID = String(process.pid);
|
|
1033
1071
|
const { child, done: done2 } = spawnClaude(`/${slashCommand}`);
|
|
@@ -1037,7 +1075,7 @@ async function launchMode(slashCommand) {
|
|
|
1037
1075
|
const signal = readSignal();
|
|
1038
1076
|
cleanupSignal();
|
|
1039
1077
|
if (signal?.event === "next") {
|
|
1040
|
-
console.log(
|
|
1078
|
+
console.log(chalk15.bold("\nChaining into assist next...\n"));
|
|
1041
1079
|
await next({ allowEdits: true });
|
|
1042
1080
|
}
|
|
1043
1081
|
}
|
|
@@ -1049,7 +1087,7 @@ import { execSync } from "child_process";
|
|
|
1049
1087
|
import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
1050
1088
|
import { homedir } from "os";
|
|
1051
1089
|
import { basename, dirname as dirname2, join as join5 } from "path";
|
|
1052
|
-
import
|
|
1090
|
+
import chalk16 from "chalk";
|
|
1053
1091
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
1054
1092
|
|
|
1055
1093
|
// src/shared/loadRawYaml.ts
|
|
@@ -1245,7 +1283,7 @@ function getTranscriptConfig() {
|
|
|
1245
1283
|
const config = loadConfig();
|
|
1246
1284
|
if (!config.transcript) {
|
|
1247
1285
|
console.error(
|
|
1248
|
-
|
|
1286
|
+
chalk16.red(
|
|
1249
1287
|
"Transcript directories not configured. Run 'assist transcript configure' first."
|
|
1250
1288
|
)
|
|
1251
1289
|
);
|
|
@@ -1334,7 +1372,7 @@ function commit(args) {
|
|
|
1334
1372
|
}
|
|
1335
1373
|
|
|
1336
1374
|
// src/commands/config/index.ts
|
|
1337
|
-
import
|
|
1375
|
+
import chalk17 from "chalk";
|
|
1338
1376
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
1339
1377
|
|
|
1340
1378
|
// src/commands/config/setNestedValue.ts
|
|
@@ -1397,7 +1435,7 @@ function formatIssuePath(issue, key) {
|
|
|
1397
1435
|
function printValidationErrors(issues, key) {
|
|
1398
1436
|
for (const issue of issues) {
|
|
1399
1437
|
console.error(
|
|
1400
|
-
|
|
1438
|
+
chalk17.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
1401
1439
|
);
|
|
1402
1440
|
}
|
|
1403
1441
|
}
|
|
@@ -1414,7 +1452,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
1414
1452
|
function assertNotGlobalOnly(key, global) {
|
|
1415
1453
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
1416
1454
|
console.error(
|
|
1417
|
-
|
|
1455
|
+
chalk17.red(
|
|
1418
1456
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
1419
1457
|
)
|
|
1420
1458
|
);
|
|
@@ -1437,7 +1475,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
1437
1475
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
1438
1476
|
const target = options2.global ? "global" : "project";
|
|
1439
1477
|
console.log(
|
|
1440
|
-
|
|
1478
|
+
chalk17.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
1441
1479
|
);
|
|
1442
1480
|
}
|
|
1443
1481
|
function configList() {
|
|
@@ -1446,7 +1484,7 @@ function configList() {
|
|
|
1446
1484
|
}
|
|
1447
1485
|
|
|
1448
1486
|
// src/commands/config/configGet.ts
|
|
1449
|
-
import
|
|
1487
|
+
import chalk18 from "chalk";
|
|
1450
1488
|
|
|
1451
1489
|
// src/commands/config/getNestedValue.ts
|
|
1452
1490
|
function isTraversable(value) {
|
|
@@ -1478,7 +1516,7 @@ function requireNestedValue(config, key) {
|
|
|
1478
1516
|
return value;
|
|
1479
1517
|
}
|
|
1480
1518
|
function exitKeyNotSet(key) {
|
|
1481
|
-
console.error(
|
|
1519
|
+
console.error(chalk18.red(`Key "${key}" is not set`));
|
|
1482
1520
|
process.exit(1);
|
|
1483
1521
|
}
|
|
1484
1522
|
|
|
@@ -1498,10 +1536,10 @@ function coverage() {
|
|
|
1498
1536
|
}
|
|
1499
1537
|
|
|
1500
1538
|
// src/commands/verify/init/index.ts
|
|
1501
|
-
import
|
|
1539
|
+
import chalk33 from "chalk";
|
|
1502
1540
|
|
|
1503
1541
|
// src/shared/promptMultiselect.ts
|
|
1504
|
-
import
|
|
1542
|
+
import chalk19 from "chalk";
|
|
1505
1543
|
import enquirer3 from "enquirer";
|
|
1506
1544
|
async function promptMultiselect(message, options2) {
|
|
1507
1545
|
const { selected } = await exitOnCancel(
|
|
@@ -1511,7 +1549,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1511
1549
|
message,
|
|
1512
1550
|
choices: options2.map((opt) => ({
|
|
1513
1551
|
name: opt.value,
|
|
1514
|
-
message: `${opt.name} - ${
|
|
1552
|
+
message: `${opt.name} - ${chalk19.dim(opt.description)}`
|
|
1515
1553
|
})),
|
|
1516
1554
|
// @ts-expect-error - enquirer types don't include symbols but it's supported
|
|
1517
1555
|
symbols: {
|
|
@@ -1528,7 +1566,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1528
1566
|
// src/shared/readPackageJson.ts
|
|
1529
1567
|
import * as fs from "fs";
|
|
1530
1568
|
import * as path from "path";
|
|
1531
|
-
import
|
|
1569
|
+
import chalk20 from "chalk";
|
|
1532
1570
|
function findPackageJson() {
|
|
1533
1571
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1534
1572
|
if (fs.existsSync(packageJsonPath)) {
|
|
@@ -1542,7 +1580,7 @@ function readPackageJson(filePath) {
|
|
|
1542
1580
|
function requirePackageJson() {
|
|
1543
1581
|
const packageJsonPath = findPackageJson();
|
|
1544
1582
|
if (!packageJsonPath) {
|
|
1545
|
-
console.error(
|
|
1583
|
+
console.error(chalk20.red("No package.json found in current directory"));
|
|
1546
1584
|
process.exit(1);
|
|
1547
1585
|
}
|
|
1548
1586
|
const pkg = readPackageJson(packageJsonPath);
|
|
@@ -1573,7 +1611,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1573
1611
|
// src/commands/verify/installPackage.ts
|
|
1574
1612
|
import { execSync as execSync3 } from "child_process";
|
|
1575
1613
|
import { writeFileSync as writeFileSync5 } from "fs";
|
|
1576
|
-
import
|
|
1614
|
+
import chalk21 from "chalk";
|
|
1577
1615
|
function writePackageJson(filePath, pkg) {
|
|
1578
1616
|
writeFileSync5(filePath, `${JSON.stringify(pkg, null, 2)}
|
|
1579
1617
|
`);
|
|
@@ -1588,12 +1626,12 @@ function addScript(pkg, name, command) {
|
|
|
1588
1626
|
};
|
|
1589
1627
|
}
|
|
1590
1628
|
function installPackage(name, cwd) {
|
|
1591
|
-
console.log(
|
|
1629
|
+
console.log(chalk21.dim(`Installing ${name}...`));
|
|
1592
1630
|
try {
|
|
1593
1631
|
execSync3(`npm install -D ${name}`, { stdio: "inherit", cwd });
|
|
1594
1632
|
return true;
|
|
1595
1633
|
} catch {
|
|
1596
|
-
console.error(
|
|
1634
|
+
console.error(chalk21.red(`Failed to install ${name}`));
|
|
1597
1635
|
return false;
|
|
1598
1636
|
}
|
|
1599
1637
|
}
|
|
@@ -1640,9 +1678,9 @@ var expectedScripts = {
|
|
|
1640
1678
|
};
|
|
1641
1679
|
|
|
1642
1680
|
// src/commands/verify/setup/setupBuild.ts
|
|
1643
|
-
import
|
|
1681
|
+
import chalk22 from "chalk";
|
|
1644
1682
|
async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
1645
|
-
console.log(
|
|
1683
|
+
console.log(chalk22.blue("\nSetting up build verification..."));
|
|
1646
1684
|
let command;
|
|
1647
1685
|
if (hasVite && hasTypescript) {
|
|
1648
1686
|
command = "tsc -b && vite build --logLevel error";
|
|
@@ -1651,21 +1689,21 @@ async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
|
1651
1689
|
} else {
|
|
1652
1690
|
command = "npm run build";
|
|
1653
1691
|
}
|
|
1654
|
-
console.log(
|
|
1692
|
+
console.log(chalk22.dim(`Using: ${command}`));
|
|
1655
1693
|
writer("verify:build", command);
|
|
1656
1694
|
}
|
|
1657
1695
|
async function setupTypecheck(_packageJsonPath, writer) {
|
|
1658
|
-
console.log(
|
|
1696
|
+
console.log(chalk22.blue("\nSetting up typecheck verification..."));
|
|
1659
1697
|
const command = "tsc --noEmit";
|
|
1660
|
-
console.log(
|
|
1698
|
+
console.log(chalk22.dim(`Using: ${command}`));
|
|
1661
1699
|
writer("verify:typecheck", command);
|
|
1662
1700
|
}
|
|
1663
1701
|
|
|
1664
1702
|
// src/commands/verify/setup/setupDuplicateCode.ts
|
|
1665
1703
|
import * as path2 from "path";
|
|
1666
|
-
import
|
|
1704
|
+
import chalk23 from "chalk";
|
|
1667
1705
|
async function setupDuplicateCode(packageJsonPath, writer) {
|
|
1668
|
-
console.log(
|
|
1706
|
+
console.log(chalk23.blue("\nSetting up jscpd..."));
|
|
1669
1707
|
const cwd = path2.dirname(packageJsonPath);
|
|
1670
1708
|
const pkg = readPackageJson(packageJsonPath);
|
|
1671
1709
|
const hasJscpd = !!pkg.dependencies?.jscpd || !!pkg.devDependencies?.jscpd;
|
|
@@ -1677,12 +1715,12 @@ async function setupDuplicateCode(packageJsonPath, writer) {
|
|
|
1677
1715
|
|
|
1678
1716
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1679
1717
|
import * as path3 from "path";
|
|
1680
|
-
import
|
|
1718
|
+
import chalk25 from "chalk";
|
|
1681
1719
|
|
|
1682
1720
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
1683
1721
|
import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
1684
1722
|
import { join as join7 } from "path";
|
|
1685
|
-
import
|
|
1723
|
+
import chalk24 from "chalk";
|
|
1686
1724
|
function loadKnipConfig(knipJsonPath) {
|
|
1687
1725
|
if (existsSync9(knipJsonPath)) {
|
|
1688
1726
|
return JSON.parse(readFileSync8(knipJsonPath, "utf-8"));
|
|
@@ -1701,16 +1739,16 @@ function addToKnipIgnoreBinaries(cwd, binary) {
|
|
|
1701
1739
|
`${JSON.stringify(knipConfig, null, " ")}
|
|
1702
1740
|
`
|
|
1703
1741
|
);
|
|
1704
|
-
console.log(
|
|
1742
|
+
console.log(chalk24.dim(`Added '${binary}' to knip.json ignoreBinaries`));
|
|
1705
1743
|
}
|
|
1706
1744
|
} catch {
|
|
1707
|
-
console.log(
|
|
1745
|
+
console.log(chalk24.yellow("Warning: Could not update knip.json"));
|
|
1708
1746
|
}
|
|
1709
1747
|
}
|
|
1710
1748
|
|
|
1711
1749
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1712
1750
|
async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
1713
|
-
console.log(
|
|
1751
|
+
console.log(chalk25.blue("\nSetting up hardcoded colors check..."));
|
|
1714
1752
|
const cwd = path3.dirname(packageJsonPath);
|
|
1715
1753
|
if (!hasOpenColor) {
|
|
1716
1754
|
installPackage("open-color", cwd);
|
|
@@ -1721,9 +1759,9 @@ async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
|
1721
1759
|
|
|
1722
1760
|
// src/commands/verify/setup/setupKnip.ts
|
|
1723
1761
|
import * as path4 from "path";
|
|
1724
|
-
import
|
|
1762
|
+
import chalk26 from "chalk";
|
|
1725
1763
|
async function setupKnip(packageJsonPath, writer) {
|
|
1726
|
-
console.log(
|
|
1764
|
+
console.log(chalk26.blue("\nSetting up knip..."));
|
|
1727
1765
|
const cwd = path4.dirname(packageJsonPath);
|
|
1728
1766
|
const pkg = readPackageJson(packageJsonPath);
|
|
1729
1767
|
if (!pkg.devDependencies?.knip && !installPackage("knip", cwd)) {
|
|
@@ -1734,14 +1772,14 @@ async function setupKnip(packageJsonPath, writer) {
|
|
|
1734
1772
|
|
|
1735
1773
|
// src/commands/verify/setup/setupLint.ts
|
|
1736
1774
|
import * as path5 from "path";
|
|
1737
|
-
import
|
|
1775
|
+
import chalk29 from "chalk";
|
|
1738
1776
|
|
|
1739
1777
|
// src/commands/lint/init.ts
|
|
1740
1778
|
import { execSync as execSync5 } from "child_process";
|
|
1741
1779
|
import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
1742
1780
|
import { dirname as dirname7, join as join8 } from "path";
|
|
1743
1781
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1744
|
-
import
|
|
1782
|
+
import chalk28 from "chalk";
|
|
1745
1783
|
|
|
1746
1784
|
// src/shared/promptConfirm.ts
|
|
1747
1785
|
import enquirer4 from "enquirer";
|
|
@@ -1845,7 +1883,7 @@ function removeEslintScripts(scripts, options2) {
|
|
|
1845
1883
|
}
|
|
1846
1884
|
|
|
1847
1885
|
// src/utils/printDiff.ts
|
|
1848
|
-
import
|
|
1886
|
+
import chalk27 from "chalk";
|
|
1849
1887
|
import * as diff from "diff";
|
|
1850
1888
|
function normalizeJson(content) {
|
|
1851
1889
|
try {
|
|
@@ -1863,11 +1901,11 @@ function printDiff(oldContent, newContent) {
|
|
|
1863
1901
|
const lines = change.value.replace(/\n$/, "").split("\n");
|
|
1864
1902
|
for (const line of lines) {
|
|
1865
1903
|
if (change.added) {
|
|
1866
|
-
console.log(
|
|
1904
|
+
console.log(chalk27.green(`+ ${line}`));
|
|
1867
1905
|
} else if (change.removed) {
|
|
1868
|
-
console.log(
|
|
1906
|
+
console.log(chalk27.red(`- ${line}`));
|
|
1869
1907
|
} else {
|
|
1870
|
-
console.log(
|
|
1908
|
+
console.log(chalk27.dim(` ${line}`));
|
|
1871
1909
|
}
|
|
1872
1910
|
}
|
|
1873
1911
|
}
|
|
@@ -1901,10 +1939,10 @@ async function init() {
|
|
|
1901
1939
|
console.log("biome.json already has the correct linter config");
|
|
1902
1940
|
return;
|
|
1903
1941
|
}
|
|
1904
|
-
console.log(
|
|
1942
|
+
console.log(chalk28.yellow("\n\u26A0\uFE0F biome.json will be updated:"));
|
|
1905
1943
|
console.log();
|
|
1906
1944
|
printDiff(oldContent, newContent);
|
|
1907
|
-
const confirm = await promptConfirm(
|
|
1945
|
+
const confirm = await promptConfirm(chalk28.red("Update biome.json?"));
|
|
1908
1946
|
if (!confirm) {
|
|
1909
1947
|
console.log("Skipped biome.json update");
|
|
1910
1948
|
return;
|
|
@@ -1915,7 +1953,7 @@ async function init() {
|
|
|
1915
1953
|
|
|
1916
1954
|
// src/commands/verify/setup/setupLint.ts
|
|
1917
1955
|
async function setupLint(packageJsonPath, writer) {
|
|
1918
|
-
console.log(
|
|
1956
|
+
console.log(chalk29.blue("\nSetting up biome..."));
|
|
1919
1957
|
const cwd = path5.dirname(packageJsonPath);
|
|
1920
1958
|
const pkg = readPackageJson(packageJsonPath);
|
|
1921
1959
|
if (!pkg.devDependencies?.["@biomejs/biome"]) {
|
|
@@ -1929,9 +1967,9 @@ async function setupLint(packageJsonPath, writer) {
|
|
|
1929
1967
|
|
|
1930
1968
|
// src/commands/verify/setup/setupMadge.ts
|
|
1931
1969
|
import * as path6 from "path";
|
|
1932
|
-
import
|
|
1970
|
+
import chalk30 from "chalk";
|
|
1933
1971
|
async function setupMadge(packageJsonPath, writer) {
|
|
1934
|
-
console.log(
|
|
1972
|
+
console.log(chalk30.blue("\nSetting up madge..."));
|
|
1935
1973
|
const cwd = path6.dirname(packageJsonPath);
|
|
1936
1974
|
const pkg = readPackageJson(packageJsonPath);
|
|
1937
1975
|
const hasMadge = !!pkg.dependencies?.madge || !!pkg.devDependencies?.madge;
|
|
@@ -1943,18 +1981,18 @@ async function setupMadge(packageJsonPath, writer) {
|
|
|
1943
1981
|
|
|
1944
1982
|
// src/commands/verify/setup/setupMaintainability.ts
|
|
1945
1983
|
import * as path7 from "path";
|
|
1946
|
-
import
|
|
1984
|
+
import chalk31 from "chalk";
|
|
1947
1985
|
async function setupMaintainability(packageJsonPath, writer) {
|
|
1948
|
-
console.log(
|
|
1986
|
+
console.log(chalk31.blue("\nSetting up maintainability check..."));
|
|
1949
1987
|
addToKnipIgnoreBinaries(path7.dirname(packageJsonPath), "assist");
|
|
1950
1988
|
writer("verify:maintainability", expectedScripts["verify:maintainability"]);
|
|
1951
1989
|
}
|
|
1952
1990
|
|
|
1953
1991
|
// src/commands/verify/setup/setupTest.ts
|
|
1954
1992
|
import * as path8 from "path";
|
|
1955
|
-
import
|
|
1993
|
+
import chalk32 from "chalk";
|
|
1956
1994
|
async function setupTest(packageJsonPath, writer) {
|
|
1957
|
-
console.log(
|
|
1995
|
+
console.log(chalk32.blue("\nSetting up vitest..."));
|
|
1958
1996
|
const cwd = path8.dirname(packageJsonPath);
|
|
1959
1997
|
const pkg = readPackageJson(packageJsonPath);
|
|
1960
1998
|
if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
|
|
@@ -2123,25 +2161,25 @@ async function runSelectedSetups(selected, packageJsonPath, writer, handlers) {
|
|
|
2123
2161
|
for (const choice of selected) {
|
|
2124
2162
|
await handlers[choice]?.(packageJsonPath, writer);
|
|
2125
2163
|
}
|
|
2126
|
-
console.log(
|
|
2164
|
+
console.log(chalk33.green(`
|
|
2127
2165
|
Added ${selected.length} verify script(s):`));
|
|
2128
2166
|
for (const choice of selected) {
|
|
2129
|
-
console.log(
|
|
2167
|
+
console.log(chalk33.green(` - verify:${choice}`));
|
|
2130
2168
|
}
|
|
2131
|
-
console.log(
|
|
2169
|
+
console.log(chalk33.dim("\nRun 'assist verify' to run all verify scripts"));
|
|
2132
2170
|
}
|
|
2133
2171
|
async function promptForScripts(availableOptions) {
|
|
2134
2172
|
if (availableOptions.length === 0) {
|
|
2135
|
-
console.log(
|
|
2173
|
+
console.log(chalk33.green("All verify scripts are already configured!"));
|
|
2136
2174
|
return null;
|
|
2137
2175
|
}
|
|
2138
|
-
console.log(
|
|
2176
|
+
console.log(chalk33.bold("Available verify scripts to add:\n"));
|
|
2139
2177
|
const selected = await promptMultiselect(
|
|
2140
2178
|
"Select verify scripts to add:",
|
|
2141
2179
|
availableOptions
|
|
2142
2180
|
);
|
|
2143
2181
|
if (selected.length === 0) {
|
|
2144
|
-
console.log(
|
|
2182
|
+
console.log(chalk33.yellow("No scripts selected"));
|
|
2145
2183
|
return null;
|
|
2146
2184
|
}
|
|
2147
2185
|
return selected;
|
|
@@ -2161,17 +2199,17 @@ async function init2() {
|
|
|
2161
2199
|
}
|
|
2162
2200
|
|
|
2163
2201
|
// src/commands/vscode/init/index.ts
|
|
2164
|
-
import
|
|
2202
|
+
import chalk35 from "chalk";
|
|
2165
2203
|
|
|
2166
2204
|
// src/commands/vscode/init/createLaunchJson.ts
|
|
2167
2205
|
import * as fs2 from "fs";
|
|
2168
2206
|
import * as path9 from "path";
|
|
2169
|
-
import
|
|
2207
|
+
import chalk34 from "chalk";
|
|
2170
2208
|
function ensureVscodeFolder() {
|
|
2171
2209
|
const vscodeDir = path9.join(process.cwd(), ".vscode");
|
|
2172
2210
|
if (!fs2.existsSync(vscodeDir)) {
|
|
2173
2211
|
fs2.mkdirSync(vscodeDir);
|
|
2174
|
-
console.log(
|
|
2212
|
+
console.log(chalk34.dim("Created .vscode folder"));
|
|
2175
2213
|
}
|
|
2176
2214
|
}
|
|
2177
2215
|
function removeVscodeFromGitignore() {
|
|
@@ -2186,7 +2224,7 @@ function removeVscodeFromGitignore() {
|
|
|
2186
2224
|
);
|
|
2187
2225
|
if (filteredLines.length !== lines.length) {
|
|
2188
2226
|
fs2.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
2189
|
-
console.log(
|
|
2227
|
+
console.log(chalk34.dim("Removed .vscode references from .gitignore"));
|
|
2190
2228
|
}
|
|
2191
2229
|
}
|
|
2192
2230
|
function createLaunchJson(type) {
|
|
@@ -2205,7 +2243,7 @@ function createLaunchJson(type) {
|
|
|
2205
2243
|
const launchPath = path9.join(process.cwd(), ".vscode", "launch.json");
|
|
2206
2244
|
fs2.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
|
|
2207
2245
|
`);
|
|
2208
|
-
console.log(
|
|
2246
|
+
console.log(chalk34.green("Created .vscode/launch.json"));
|
|
2209
2247
|
}
|
|
2210
2248
|
function createSettingsJson() {
|
|
2211
2249
|
const settings = {
|
|
@@ -2218,7 +2256,7 @@ function createSettingsJson() {
|
|
|
2218
2256
|
const settingsPath = path9.join(process.cwd(), ".vscode", "settings.json");
|
|
2219
2257
|
fs2.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
|
|
2220
2258
|
`);
|
|
2221
|
-
console.log(
|
|
2259
|
+
console.log(chalk34.green("Created .vscode/settings.json"));
|
|
2222
2260
|
}
|
|
2223
2261
|
function createExtensionsJson() {
|
|
2224
2262
|
const extensions = {
|
|
@@ -2230,7 +2268,7 @@ function createExtensionsJson() {
|
|
|
2230
2268
|
`${JSON.stringify(extensions, null, " ")}
|
|
2231
2269
|
`
|
|
2232
2270
|
);
|
|
2233
|
-
console.log(
|
|
2271
|
+
console.log(chalk34.green("Created .vscode/extensions.json"));
|
|
2234
2272
|
}
|
|
2235
2273
|
|
|
2236
2274
|
// src/commands/vscode/init/detectVscodeSetup.ts
|
|
@@ -2287,7 +2325,7 @@ function applySelections(selected, setup2) {
|
|
|
2287
2325
|
for (const choice of selected) handlers[choice]?.();
|
|
2288
2326
|
}
|
|
2289
2327
|
async function promptForOptions(options2) {
|
|
2290
|
-
console.log(
|
|
2328
|
+
console.log(chalk35.bold("Available VS Code configurations to add:\n"));
|
|
2291
2329
|
return promptMultiselect("Select configurations to add:", options2);
|
|
2292
2330
|
}
|
|
2293
2331
|
async function init3({ all = false } = {}) {
|
|
@@ -2295,17 +2333,17 @@ async function init3({ all = false } = {}) {
|
|
|
2295
2333
|
const setup2 = detectVscodeSetup(pkg);
|
|
2296
2334
|
const options2 = getAvailableOptions2(setup2);
|
|
2297
2335
|
if (options2.length === 0) {
|
|
2298
|
-
console.log(
|
|
2336
|
+
console.log(chalk35.green("VS Code configuration already exists!"));
|
|
2299
2337
|
return;
|
|
2300
2338
|
}
|
|
2301
2339
|
const selected = all ? options2.map((o) => o.value) : await promptForOptions(options2);
|
|
2302
2340
|
if (selected.length === 0) {
|
|
2303
|
-
console.log(
|
|
2341
|
+
console.log(chalk35.yellow("No configurations selected"));
|
|
2304
2342
|
return;
|
|
2305
2343
|
}
|
|
2306
2344
|
applySelections(selected, setup2);
|
|
2307
2345
|
console.log(
|
|
2308
|
-
|
|
2346
|
+
chalk35.green(`
|
|
2309
2347
|
Added ${selected.length} VS Code configuration(s)`)
|
|
2310
2348
|
);
|
|
2311
2349
|
}
|
|
@@ -2318,7 +2356,7 @@ async function init4() {
|
|
|
2318
2356
|
|
|
2319
2357
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2320
2358
|
import path16 from "path";
|
|
2321
|
-
import
|
|
2359
|
+
import chalk37 from "chalk";
|
|
2322
2360
|
|
|
2323
2361
|
// src/commands/lint/lint/checkFileNames.ts
|
|
2324
2362
|
import fs5 from "fs";
|
|
@@ -2398,7 +2436,7 @@ function checkFileNames() {
|
|
|
2398
2436
|
}
|
|
2399
2437
|
|
|
2400
2438
|
// src/commands/lint/lint/fixFileNameViolations.ts
|
|
2401
|
-
import
|
|
2439
|
+
import chalk36 from "chalk";
|
|
2402
2440
|
|
|
2403
2441
|
// src/commands/lint/lint/applyMoves.ts
|
|
2404
2442
|
import fs6 from "fs";
|
|
@@ -2483,25 +2521,25 @@ function fixFileNameViolations(moves) {
|
|
|
2483
2521
|
const start3 = performance.now();
|
|
2484
2522
|
const project = createLintProject();
|
|
2485
2523
|
const cwd = process.cwd();
|
|
2486
|
-
applyMoves(project, moves, cwd, (line) => console.log(
|
|
2524
|
+
applyMoves(project, moves, cwd, (line) => console.log(chalk36.green(line)));
|
|
2487
2525
|
const ms = (performance.now() - start3).toFixed(0);
|
|
2488
|
-
console.log(
|
|
2526
|
+
console.log(chalk36.dim(` Done in ${ms}ms`));
|
|
2489
2527
|
}
|
|
2490
2528
|
|
|
2491
2529
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2492
2530
|
function reportViolations(violations) {
|
|
2493
|
-
console.error(
|
|
2531
|
+
console.error(chalk37.red("\nFile name check failed:\n"));
|
|
2494
2532
|
console.error(
|
|
2495
|
-
|
|
2533
|
+
chalk37.red(
|
|
2496
2534
|
" Files without classes or React components should not start with a capital letter.\n"
|
|
2497
2535
|
)
|
|
2498
2536
|
);
|
|
2499
2537
|
for (const violation of violations) {
|
|
2500
|
-
console.error(
|
|
2501
|
-
console.error(
|
|
2538
|
+
console.error(chalk37.red(` ${violation.filePath}`));
|
|
2539
|
+
console.error(chalk37.gray(` Rename to: ${violation.suggestedName}
|
|
2502
2540
|
`));
|
|
2503
2541
|
}
|
|
2504
|
-
console.error(
|
|
2542
|
+
console.error(chalk37.dim(" Run with -f to auto-fix.\n"));
|
|
2505
2543
|
}
|
|
2506
2544
|
function runFileNameCheck(fix = false) {
|
|
2507
2545
|
const violations = checkFileNames();
|
|
@@ -2530,17 +2568,17 @@ function runFileNameCheck(fix = false) {
|
|
|
2530
2568
|
import fs8 from "fs";
|
|
2531
2569
|
|
|
2532
2570
|
// src/commands/lint/shared.ts
|
|
2533
|
-
import
|
|
2571
|
+
import chalk38 from "chalk";
|
|
2534
2572
|
function reportViolations2(violations, checkName, errorMessage, successMessage) {
|
|
2535
2573
|
if (violations.length > 0) {
|
|
2536
|
-
console.error(
|
|
2574
|
+
console.error(chalk38.red(`
|
|
2537
2575
|
${checkName} failed:
|
|
2538
2576
|
`));
|
|
2539
|
-
console.error(
|
|
2577
|
+
console.error(chalk38.red(` ${errorMessage}
|
|
2540
2578
|
`));
|
|
2541
2579
|
for (const violation of violations) {
|
|
2542
|
-
console.error(
|
|
2543
|
-
console.error(
|
|
2580
|
+
console.error(chalk38.red(` ${violation.filePath}:${violation.line}`));
|
|
2581
|
+
console.error(chalk38.gray(` ${violation.content}
|
|
2544
2582
|
`));
|
|
2545
2583
|
}
|
|
2546
2584
|
return false;
|
|
@@ -3020,14 +3058,14 @@ import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSy
|
|
|
3020
3058
|
|
|
3021
3059
|
// src/commands/deploy/init/index.ts
|
|
3022
3060
|
import { execSync as execSync12 } from "child_process";
|
|
3023
|
-
import
|
|
3061
|
+
import chalk40 from "chalk";
|
|
3024
3062
|
import enquirer5 from "enquirer";
|
|
3025
3063
|
|
|
3026
3064
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
3027
3065
|
import { existsSync as existsSync15, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
3028
3066
|
import { dirname as dirname13, join as join11 } from "path";
|
|
3029
3067
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3030
|
-
import
|
|
3068
|
+
import chalk39 from "chalk";
|
|
3031
3069
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
3032
3070
|
var __dirname3 = dirname13(fileURLToPath3(import.meta.url));
|
|
3033
3071
|
function getExistingSiteId() {
|
|
@@ -3052,20 +3090,20 @@ async function updateWorkflow(siteId) {
|
|
|
3052
3090
|
if (existsSync15(WORKFLOW_PATH)) {
|
|
3053
3091
|
const oldContent = readFileSync12(WORKFLOW_PATH, "utf-8");
|
|
3054
3092
|
if (oldContent === newContent) {
|
|
3055
|
-
console.log(
|
|
3093
|
+
console.log(chalk39.green("build.yml is already up to date"));
|
|
3056
3094
|
return;
|
|
3057
3095
|
}
|
|
3058
|
-
console.log(
|
|
3096
|
+
console.log(chalk39.yellow("\nbuild.yml will be updated:"));
|
|
3059
3097
|
console.log();
|
|
3060
3098
|
printDiff(oldContent, newContent);
|
|
3061
|
-
const confirm = await promptConfirm(
|
|
3099
|
+
const confirm = await promptConfirm(chalk39.red("Update build.yml?"));
|
|
3062
3100
|
if (!confirm) {
|
|
3063
3101
|
console.log("Skipped build.yml update");
|
|
3064
3102
|
return;
|
|
3065
3103
|
}
|
|
3066
3104
|
}
|
|
3067
3105
|
writeFileSync12(WORKFLOW_PATH, newContent);
|
|
3068
|
-
console.log(
|
|
3106
|
+
console.log(chalk39.green(`
|
|
3069
3107
|
Created ${WORKFLOW_PATH}`));
|
|
3070
3108
|
}
|
|
3071
3109
|
|
|
@@ -3076,43 +3114,43 @@ async function ensureNetlifyCli() {
|
|
|
3076
3114
|
} catch (error) {
|
|
3077
3115
|
if (!(error instanceof Error) || !error.message.includes("command not found"))
|
|
3078
3116
|
throw error;
|
|
3079
|
-
console.error(
|
|
3117
|
+
console.error(chalk40.red("\nNetlify CLI is not installed.\n"));
|
|
3080
3118
|
const install = await promptConfirm("Would you like to install it now?");
|
|
3081
3119
|
if (!install) {
|
|
3082
3120
|
console.log(
|
|
3083
|
-
|
|
3121
|
+
chalk40.yellow(
|
|
3084
3122
|
"\nInstall it manually with: npm install -g netlify-cli\n"
|
|
3085
3123
|
)
|
|
3086
3124
|
);
|
|
3087
3125
|
process.exit(1);
|
|
3088
3126
|
}
|
|
3089
|
-
console.log(
|
|
3127
|
+
console.log(chalk40.dim("\nInstalling netlify-cli...\n"));
|
|
3090
3128
|
execSync12("npm install -g netlify-cli", { stdio: "inherit" });
|
|
3091
3129
|
console.log();
|
|
3092
3130
|
execSync12("netlify sites:create --disable-linking", { stdio: "inherit" });
|
|
3093
3131
|
}
|
|
3094
3132
|
}
|
|
3095
3133
|
function printSetupInstructions() {
|
|
3096
|
-
console.log(
|
|
3134
|
+
console.log(chalk40.bold("\nDeployment initialized successfully!"));
|
|
3097
3135
|
console.log(
|
|
3098
|
-
|
|
3136
|
+
chalk40.yellow("\nTo complete setup, create a personal access token at:")
|
|
3099
3137
|
);
|
|
3100
3138
|
console.log(
|
|
3101
|
-
|
|
3139
|
+
chalk40.cyan(
|
|
3102
3140
|
"https://app.netlify.com/user/applications#personal-access-tokens"
|
|
3103
3141
|
)
|
|
3104
3142
|
);
|
|
3105
3143
|
console.log(
|
|
3106
|
-
|
|
3144
|
+
chalk40.yellow(
|
|
3107
3145
|
"\nThen add it as NETLIFY_AUTH_TOKEN in your GitHub repository secrets."
|
|
3108
3146
|
)
|
|
3109
3147
|
);
|
|
3110
3148
|
}
|
|
3111
3149
|
async function init5() {
|
|
3112
|
-
console.log(
|
|
3150
|
+
console.log(chalk40.bold("Initializing Netlify deployment...\n"));
|
|
3113
3151
|
const existingSiteId = getExistingSiteId();
|
|
3114
3152
|
if (existingSiteId) {
|
|
3115
|
-
console.log(
|
|
3153
|
+
console.log(chalk40.dim(`Using existing site ID: ${existingSiteId}
|
|
3116
3154
|
`));
|
|
3117
3155
|
await updateWorkflow(existingSiteId);
|
|
3118
3156
|
return;
|
|
@@ -3291,27 +3329,27 @@ async function notify() {
|
|
|
3291
3329
|
}
|
|
3292
3330
|
|
|
3293
3331
|
// src/commands/backlog/comment/index.ts
|
|
3294
|
-
import
|
|
3332
|
+
import chalk41 from "chalk";
|
|
3295
3333
|
function comment(id, text) {
|
|
3296
3334
|
const result = loadAndFindItem(id);
|
|
3297
3335
|
if (!result) process.exit(1);
|
|
3298
3336
|
addComment(result.item, text);
|
|
3299
3337
|
saveBacklog(result.items);
|
|
3300
|
-
console.log(
|
|
3338
|
+
console.log(chalk41.green(`Comment added to item #${id}.`));
|
|
3301
3339
|
}
|
|
3302
3340
|
|
|
3303
3341
|
// src/commands/backlog/comments/index.ts
|
|
3304
|
-
import
|
|
3342
|
+
import chalk42 from "chalk";
|
|
3305
3343
|
function comments(id) {
|
|
3306
3344
|
const result = loadAndFindItem(id);
|
|
3307
3345
|
if (!result) process.exit(1);
|
|
3308
3346
|
const { item } = result;
|
|
3309
3347
|
const entries = item.comments ?? [];
|
|
3310
3348
|
if (entries.length === 0) {
|
|
3311
|
-
console.log(
|
|
3349
|
+
console.log(chalk42.dim(`No comments on item #${id}.`));
|
|
3312
3350
|
return;
|
|
3313
3351
|
}
|
|
3314
|
-
console.log(
|
|
3352
|
+
console.log(chalk42.bold(`Comments for #${id}: ${item.name}
|
|
3315
3353
|
`));
|
|
3316
3354
|
for (const entry of entries) {
|
|
3317
3355
|
console.log(`${formatComment(entry)}
|
|
@@ -3327,11 +3365,11 @@ function registerCommentCommands(cmd) {
|
|
|
3327
3365
|
|
|
3328
3366
|
// src/commands/backlog/add/index.ts
|
|
3329
3367
|
import { existsSync as existsSync18 } from "fs";
|
|
3330
|
-
import
|
|
3368
|
+
import chalk45 from "chalk";
|
|
3331
3369
|
|
|
3332
3370
|
// src/commands/backlog/commitBacklog.ts
|
|
3333
3371
|
import { execSync as execSync14 } from "child_process";
|
|
3334
|
-
import
|
|
3372
|
+
import chalk43 from "chalk";
|
|
3335
3373
|
function commitBacklog(id, name) {
|
|
3336
3374
|
try {
|
|
3337
3375
|
const backlogPath = getBacklogPath();
|
|
@@ -3339,18 +3377,18 @@ function commitBacklog(id, name) {
|
|
|
3339
3377
|
execSync14(`git add ${shellQuote(backlogPath)}`, { stdio: "ignore" });
|
|
3340
3378
|
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3341
3379
|
} catch {
|
|
3342
|
-
console.log(
|
|
3380
|
+
console.log(chalk43.yellow("Warning: could not auto-commit backlog file."));
|
|
3343
3381
|
}
|
|
3344
3382
|
}
|
|
3345
3383
|
|
|
3346
3384
|
// src/commands/backlog/add/parseItemFile.ts
|
|
3347
3385
|
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
|
|
3348
|
-
import
|
|
3386
|
+
import chalk44 from "chalk";
|
|
3349
3387
|
import { ZodError } from "zod";
|
|
3350
3388
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3351
3389
|
function readJsonFile(filePath) {
|
|
3352
3390
|
if (!existsSync17(filePath)) {
|
|
3353
|
-
console.log(
|
|
3391
|
+
console.log(chalk44.red(`File not found: ${filePath}`));
|
|
3354
3392
|
process.exitCode = 1;
|
|
3355
3393
|
return void 0;
|
|
3356
3394
|
}
|
|
@@ -3358,26 +3396,26 @@ function readJsonFile(filePath) {
|
|
|
3358
3396
|
try {
|
|
3359
3397
|
raw = readFileSync14(filePath, "utf-8");
|
|
3360
3398
|
} catch {
|
|
3361
|
-
console.log(
|
|
3399
|
+
console.log(chalk44.red(`Failed to read file: ${filePath}`));
|
|
3362
3400
|
process.exitCode = 1;
|
|
3363
3401
|
return void 0;
|
|
3364
3402
|
}
|
|
3365
3403
|
try {
|
|
3366
3404
|
return JSON.parse(raw);
|
|
3367
3405
|
} catch {
|
|
3368
|
-
console.log(
|
|
3406
|
+
console.log(chalk44.red(`Invalid JSON in file: ${filePath}`));
|
|
3369
3407
|
process.exitCode = 1;
|
|
3370
3408
|
return void 0;
|
|
3371
3409
|
}
|
|
3372
3410
|
}
|
|
3373
3411
|
function formatZodError(err) {
|
|
3374
3412
|
if (err instanceof ZodError) {
|
|
3375
|
-
console.log(
|
|
3413
|
+
console.log(chalk44.red("Invalid backlog item schema:"));
|
|
3376
3414
|
for (const issue of err.issues) {
|
|
3377
|
-
console.log(
|
|
3415
|
+
console.log(chalk44.red(` - ${issue.path.join(".")}: ${issue.message}`));
|
|
3378
3416
|
}
|
|
3379
3417
|
} else {
|
|
3380
|
-
console.log(
|
|
3418
|
+
console.log(chalk44.red("Invalid backlog item schema."));
|
|
3381
3419
|
}
|
|
3382
3420
|
}
|
|
3383
3421
|
function parseItemFile(filePath) {
|
|
@@ -3471,7 +3509,7 @@ function addFromFile(filePath) {
|
|
|
3471
3509
|
items.push({ ...data, id, status: "todo" });
|
|
3472
3510
|
saveBacklog(items);
|
|
3473
3511
|
commitBacklog(id, data.name);
|
|
3474
|
-
console.log(
|
|
3512
|
+
console.log(chalk45.green(`Added item #${id}: ${data.name}`));
|
|
3475
3513
|
}
|
|
3476
3514
|
async function addInteractive() {
|
|
3477
3515
|
const type = await promptType();
|
|
@@ -3490,12 +3528,12 @@ async function addInteractive() {
|
|
|
3490
3528
|
});
|
|
3491
3529
|
saveBacklog(items);
|
|
3492
3530
|
commitBacklog(id, name);
|
|
3493
|
-
console.log(
|
|
3531
|
+
console.log(chalk45.green(`Added item #${id}: ${name}`));
|
|
3494
3532
|
}
|
|
3495
3533
|
async function add(options2) {
|
|
3496
3534
|
if (!existsSync18(getBacklogPath())) {
|
|
3497
3535
|
console.log(
|
|
3498
|
-
|
|
3536
|
+
chalk45.yellow(
|
|
3499
3537
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3500
3538
|
)
|
|
3501
3539
|
);
|
|
@@ -3510,20 +3548,20 @@ async function add(options2) {
|
|
|
3510
3548
|
|
|
3511
3549
|
// src/commands/backlog/init/index.ts
|
|
3512
3550
|
import { existsSync as existsSync19 } from "fs";
|
|
3513
|
-
import
|
|
3551
|
+
import chalk46 from "chalk";
|
|
3514
3552
|
async function init6() {
|
|
3515
3553
|
const backlogPath = getBacklogPath();
|
|
3516
3554
|
if (existsSync19(backlogPath)) {
|
|
3517
|
-
console.log(
|
|
3555
|
+
console.log(chalk46.yellow("assist.backlog.yml already exists."));
|
|
3518
3556
|
return;
|
|
3519
3557
|
}
|
|
3520
3558
|
saveBacklog([]);
|
|
3521
|
-
console.log(
|
|
3559
|
+
console.log(chalk46.green("Created assist.backlog.yml"));
|
|
3522
3560
|
}
|
|
3523
3561
|
|
|
3524
3562
|
// src/commands/backlog/list/index.ts
|
|
3525
3563
|
import { existsSync as existsSync20 } from "fs";
|
|
3526
|
-
import
|
|
3564
|
+
import chalk47 from "chalk";
|
|
3527
3565
|
function filterItems(items, options2) {
|
|
3528
3566
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3529
3567
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
@@ -3532,7 +3570,7 @@ function filterItems(items, options2) {
|
|
|
3532
3570
|
async function list2(options2) {
|
|
3533
3571
|
if (!existsSync20(getBacklogPath())) {
|
|
3534
3572
|
console.log(
|
|
3535
|
-
|
|
3573
|
+
chalk47.yellow(
|
|
3536
3574
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3537
3575
|
)
|
|
3538
3576
|
);
|
|
@@ -3540,12 +3578,12 @@ async function list2(options2) {
|
|
|
3540
3578
|
}
|
|
3541
3579
|
const items = filterItems(loadBacklog(), options2);
|
|
3542
3580
|
if (items.length === 0) {
|
|
3543
|
-
console.log(
|
|
3581
|
+
console.log(chalk47.dim("Backlog is empty."));
|
|
3544
3582
|
return;
|
|
3545
3583
|
}
|
|
3546
3584
|
for (const item of items) {
|
|
3547
3585
|
console.log(
|
|
3548
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3586
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk47.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}${dependencyLabel(item)}`
|
|
3549
3587
|
);
|
|
3550
3588
|
if (options2.verbose) {
|
|
3551
3589
|
printVerboseDetails(item);
|
|
@@ -3560,17 +3598,136 @@ function registerItemCommands(cmd) {
|
|
|
3560
3598
|
cmd.command("add").description("Add a new backlog item").option("--file <path>", "Read item as JSON from a file").action(add);
|
|
3561
3599
|
}
|
|
3562
3600
|
|
|
3601
|
+
// src/commands/backlog/link.ts
|
|
3602
|
+
import chalk49 from "chalk";
|
|
3603
|
+
|
|
3604
|
+
// src/commands/backlog/hasCycle.ts
|
|
3605
|
+
function hasCycle(items, fromId, toId) {
|
|
3606
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3607
|
+
const stack = [toId];
|
|
3608
|
+
while (stack.length > 0) {
|
|
3609
|
+
const current = stack.pop();
|
|
3610
|
+
if (current === fromId) return true;
|
|
3611
|
+
if (visited.has(current)) continue;
|
|
3612
|
+
visited.add(current);
|
|
3613
|
+
const item = items.find((i) => i.id === current);
|
|
3614
|
+
if (!item?.links) continue;
|
|
3615
|
+
for (const link2 of item.links) {
|
|
3616
|
+
if (link2.type === "depends-on") {
|
|
3617
|
+
stack.push(link2.targetId);
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
return false;
|
|
3622
|
+
}
|
|
3623
|
+
|
|
3624
|
+
// src/commands/backlog/validateLinkTarget.ts
|
|
3625
|
+
import chalk48 from "chalk";
|
|
3626
|
+
function validateLinkTarget(items, fromItem, fromId, toId, toNum, linkType) {
|
|
3627
|
+
const toItem = items.find((i) => i.id === toNum);
|
|
3628
|
+
if (!toItem) {
|
|
3629
|
+
console.log(chalk48.red(`Item #${toId} not found.`));
|
|
3630
|
+
return void 0;
|
|
3631
|
+
}
|
|
3632
|
+
if (!fromItem.links) fromItem.links = [];
|
|
3633
|
+
const duplicate = fromItem.links.some(
|
|
3634
|
+
(l) => l.targetId === toNum && l.type === linkType
|
|
3635
|
+
);
|
|
3636
|
+
if (duplicate) {
|
|
3637
|
+
console.log(
|
|
3638
|
+
chalk48.yellow(`Link already exists: #${fromId} ${linkType} #${toId}`)
|
|
3639
|
+
);
|
|
3640
|
+
return void 0;
|
|
3641
|
+
}
|
|
3642
|
+
return toItem;
|
|
3643
|
+
}
|
|
3644
|
+
|
|
3645
|
+
// src/commands/backlog/link.ts
|
|
3646
|
+
function link(fromId, toId, opts) {
|
|
3647
|
+
const linkType = opts.type ?? "relates-to";
|
|
3648
|
+
if (linkType !== "relates-to" && linkType !== "depends-on") {
|
|
3649
|
+
console.log(chalk49.red(`Invalid link type: ${linkType}`));
|
|
3650
|
+
return;
|
|
3651
|
+
}
|
|
3652
|
+
const fromNum = Number.parseInt(fromId, 10);
|
|
3653
|
+
const toNum = Number.parseInt(toId, 10);
|
|
3654
|
+
if (fromNum === toNum) {
|
|
3655
|
+
console.log(chalk49.red("Cannot link an item to itself."));
|
|
3656
|
+
return;
|
|
3657
|
+
}
|
|
3658
|
+
const result = loadAndFindItem(fromId);
|
|
3659
|
+
if (!result) return;
|
|
3660
|
+
const { items, item: fromItem } = result;
|
|
3661
|
+
const toItem = validateLinkTarget(
|
|
3662
|
+
items,
|
|
3663
|
+
fromItem,
|
|
3664
|
+
fromId,
|
|
3665
|
+
toId,
|
|
3666
|
+
toNum,
|
|
3667
|
+
linkType
|
|
3668
|
+
);
|
|
3669
|
+
if (!toItem) return;
|
|
3670
|
+
if (linkType === "depends-on" && hasCycle(items, fromNum, toNum)) {
|
|
3671
|
+
console.log(
|
|
3672
|
+
chalk49.red(
|
|
3673
|
+
`Cannot add dependency: #${fromId} \u2192 #${toId} would create a circular dependency.`
|
|
3674
|
+
)
|
|
3675
|
+
);
|
|
3676
|
+
return;
|
|
3677
|
+
}
|
|
3678
|
+
if (!fromItem.links) fromItem.links = [];
|
|
3679
|
+
fromItem.links.push({ type: linkType, targetId: toNum });
|
|
3680
|
+
saveBacklog(items);
|
|
3681
|
+
console.log(
|
|
3682
|
+
chalk49.green(`Linked #${fromId} ${linkType} #${toId} (${toItem.name})`)
|
|
3683
|
+
);
|
|
3684
|
+
}
|
|
3685
|
+
|
|
3686
|
+
// src/commands/backlog/unlink.ts
|
|
3687
|
+
import chalk50 from "chalk";
|
|
3688
|
+
function unlink(fromId, toId) {
|
|
3689
|
+
const toNum = Number.parseInt(toId, 10);
|
|
3690
|
+
const result = loadAndFindItem(fromId);
|
|
3691
|
+
if (!result) return;
|
|
3692
|
+
const { items, item: fromItem } = result;
|
|
3693
|
+
if (!fromItem.links || fromItem.links.length === 0) {
|
|
3694
|
+
console.log(chalk50.yellow(`No links found on item #${fromId}.`));
|
|
3695
|
+
return;
|
|
3696
|
+
}
|
|
3697
|
+
const before = fromItem.links.length;
|
|
3698
|
+
fromItem.links = fromItem.links.filter((l) => l.targetId !== toNum);
|
|
3699
|
+
if (fromItem.links.length === before) {
|
|
3700
|
+
console.log(chalk50.yellow(`No link from #${fromId} to #${toId} found.`));
|
|
3701
|
+
return;
|
|
3702
|
+
}
|
|
3703
|
+
if (fromItem.links.length === 0) {
|
|
3704
|
+
fromItem.links = void 0;
|
|
3705
|
+
}
|
|
3706
|
+
saveBacklog(items);
|
|
3707
|
+
console.log(chalk50.green(`Removed link from #${fromId} to #${toId}.`));
|
|
3708
|
+
}
|
|
3709
|
+
|
|
3710
|
+
// src/commands/backlog/registerLinkCommands.ts
|
|
3711
|
+
function registerLinkCommands(cmd) {
|
|
3712
|
+
cmd.command("link <from> <to>").description("Link two backlog items").option(
|
|
3713
|
+
"--type <type>",
|
|
3714
|
+
"Link type (relates-to or depends-on)",
|
|
3715
|
+
"relates-to"
|
|
3716
|
+
).action(link);
|
|
3717
|
+
cmd.command("unlink <from> <to>").description("Remove a link between two backlog items").action(unlink);
|
|
3718
|
+
}
|
|
3719
|
+
|
|
3563
3720
|
// src/commands/backlog/delete/index.ts
|
|
3564
|
-
import
|
|
3721
|
+
import chalk51 from "chalk";
|
|
3565
3722
|
async function del(id) {
|
|
3566
3723
|
const name = removeItem(id);
|
|
3567
3724
|
if (name) {
|
|
3568
|
-
console.log(
|
|
3725
|
+
console.log(chalk51.green(`Deleted item #${id}: ${name}`));
|
|
3569
3726
|
}
|
|
3570
3727
|
}
|
|
3571
3728
|
|
|
3572
3729
|
// src/commands/backlog/done/index.ts
|
|
3573
|
-
import
|
|
3730
|
+
import chalk52 from "chalk";
|
|
3574
3731
|
async function done(id, summary) {
|
|
3575
3732
|
const result = loadAndFindItem(id);
|
|
3576
3733
|
if (!result) return;
|
|
@@ -3580,15 +3737,15 @@ async function done(id, summary) {
|
|
|
3580
3737
|
addPhaseSummary(result.item, summary, phase);
|
|
3581
3738
|
}
|
|
3582
3739
|
saveBacklog(result.items);
|
|
3583
|
-
console.log(
|
|
3740
|
+
console.log(chalk52.green(`Completed item #${id}: ${result.item.name}`));
|
|
3584
3741
|
}
|
|
3585
3742
|
|
|
3586
3743
|
// src/commands/backlog/start/index.ts
|
|
3587
|
-
import
|
|
3744
|
+
import chalk53 from "chalk";
|
|
3588
3745
|
async function start(id) {
|
|
3589
3746
|
const name = setStatus(id, "in-progress");
|
|
3590
3747
|
if (name) {
|
|
3591
|
-
console.log(
|
|
3748
|
+
console.log(chalk53.green(`Started item #${id}: ${name}`));
|
|
3592
3749
|
}
|
|
3593
3750
|
}
|
|
3594
3751
|
|
|
@@ -3629,6 +3786,7 @@ function registerBacklog(program2) {
|
|
|
3629
3786
|
registerStatusCommands(cmd);
|
|
3630
3787
|
registerWebCommand(cmd);
|
|
3631
3788
|
registerCommentCommands(cmd);
|
|
3789
|
+
registerLinkCommands(cmd);
|
|
3632
3790
|
registerPlanCommands(cmd);
|
|
3633
3791
|
registerNextCommand(cmd);
|
|
3634
3792
|
registerRunCommand(cmd);
|
|
@@ -3721,32 +3879,41 @@ import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
|
3721
3879
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3722
3880
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
3723
3881
|
var __dirname4 = dirname14(__filename2);
|
|
3724
|
-
function
|
|
3725
|
-
return resolve2(__dirname4, ".."
|
|
3882
|
+
function packageRoot() {
|
|
3883
|
+
return resolve2(__dirname4, "..");
|
|
3726
3884
|
}
|
|
3727
|
-
|
|
3885
|
+
function readLines(path50) {
|
|
3886
|
+
if (!existsSync21(path50)) return [];
|
|
3887
|
+
return readFileSync16(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
3888
|
+
}
|
|
3889
|
+
var cachedReads;
|
|
3890
|
+
var cachedWrites;
|
|
3728
3891
|
function getCliReadsLines() {
|
|
3729
|
-
if (
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3892
|
+
if (!cachedReads) {
|
|
3893
|
+
cachedReads = readLines(resolve2(packageRoot(), "allowed.cli-reads"));
|
|
3894
|
+
}
|
|
3895
|
+
return cachedReads;
|
|
3896
|
+
}
|
|
3897
|
+
function getCliWritesLines() {
|
|
3898
|
+
if (!cachedWrites) {
|
|
3899
|
+
cachedWrites = readLines(resolve2(packageRoot(), "allowed.cli-writes"));
|
|
3734
3900
|
}
|
|
3735
|
-
|
|
3736
|
-
return cachedLines;
|
|
3901
|
+
return cachedWrites;
|
|
3737
3902
|
}
|
|
3738
3903
|
function loadCliReads() {
|
|
3739
3904
|
return getCliReadsLines();
|
|
3740
3905
|
}
|
|
3741
3906
|
function saveCliReads(commands) {
|
|
3742
|
-
writeFileSync15(
|
|
3743
|
-
|
|
3744
|
-
|
|
3907
|
+
writeFileSync15(
|
|
3908
|
+
resolve2(packageRoot(), "allowed.cli-reads"),
|
|
3909
|
+
`${commands.join("\n")}
|
|
3910
|
+
`
|
|
3911
|
+
);
|
|
3912
|
+
cachedReads = void 0;
|
|
3745
3913
|
}
|
|
3746
|
-
function
|
|
3914
|
+
function findMatch(command, lines) {
|
|
3747
3915
|
const words = command.split(/\s+/);
|
|
3748
3916
|
if (words.length === 0) return void 0;
|
|
3749
|
-
const lines = getCliReadsLines();
|
|
3750
3917
|
if (lines.includes(words[0])) return words[0];
|
|
3751
3918
|
if (words.length < 2) return void 0;
|
|
3752
3919
|
const prefix2 = `${words[0]} ${words[1]}`;
|
|
@@ -3755,6 +3922,12 @@ function findCliRead(command) {
|
|
|
3755
3922
|
);
|
|
3756
3923
|
return candidates.sort((a, b) => b.length - a.length).find((rc) => command === rc || command.startsWith(`${rc} `));
|
|
3757
3924
|
}
|
|
3925
|
+
function findCliRead(command) {
|
|
3926
|
+
return findMatch(command, getCliReadsLines());
|
|
3927
|
+
}
|
|
3928
|
+
function findCliWrite(command) {
|
|
3929
|
+
return findMatch(command, getCliWritesLines());
|
|
3930
|
+
}
|
|
3758
3931
|
|
|
3759
3932
|
// src/shared/readSettingsPerms.ts
|
|
3760
3933
|
import { existsSync as existsSync22, readFileSync as readFileSync17 } from "fs";
|
|
@@ -3801,7 +3974,7 @@ function shellEntries(map, toolName) {
|
|
|
3801
3974
|
function normCmd(cmd) {
|
|
3802
3975
|
return cmd.replace(DOTSLASH_RE, "");
|
|
3803
3976
|
}
|
|
3804
|
-
function
|
|
3977
|
+
function findMatch2(entries, command) {
|
|
3805
3978
|
const norm = normCmd(command);
|
|
3806
3979
|
return entries.find(
|
|
3807
3980
|
(e) => e.wildcard ? norm === e.command || norm.startsWith(`${e.command} `) : norm === e.command
|
|
@@ -3809,11 +3982,11 @@ function findMatch(entries, command) {
|
|
|
3809
3982
|
}
|
|
3810
3983
|
function matchesAllow(toolName, command) {
|
|
3811
3984
|
if (!allowCache) allowCache = loadPerms("allow");
|
|
3812
|
-
return
|
|
3985
|
+
return findMatch2(shellEntries(allowCache, toolName), command);
|
|
3813
3986
|
}
|
|
3814
3987
|
function matchesDeny(toolName, command) {
|
|
3815
3988
|
if (!denyCache) denyCache = loadPerms("deny");
|
|
3816
|
-
return
|
|
3989
|
+
return findMatch2(shellEntries(denyCache, toolName), command);
|
|
3817
3990
|
}
|
|
3818
3991
|
function parsePerms(entries) {
|
|
3819
3992
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -3834,8 +4007,10 @@ function parsePerms(entries) {
|
|
|
3834
4007
|
// src/shared/isApprovedRead.ts
|
|
3835
4008
|
function isApprovedRead(command, toolName = "Bash") {
|
|
3836
4009
|
if (isCdToCwd(command)) return "cd to current directory";
|
|
3837
|
-
const
|
|
3838
|
-
if (
|
|
4010
|
+
const matchedRead = findCliRead(command);
|
|
4011
|
+
if (matchedRead) return `Read-only CLI command: ${matchedRead}`;
|
|
4012
|
+
const matchedWrite = findCliWrite(command);
|
|
4013
|
+
if (matchedWrite) return `Allowed CLI write: ${matchedWrite}`;
|
|
3839
4014
|
if (isGhApiRead(command)) return "Read-only gh api command";
|
|
3840
4015
|
const allowMatch = matchesAllow(toolName, command);
|
|
3841
4016
|
if (allowMatch) return `Allowed by settings: ${allowMatch}`;
|
|
@@ -4013,48 +4188,48 @@ ${reasons.join("\n")}`);
|
|
|
4013
4188
|
}
|
|
4014
4189
|
|
|
4015
4190
|
// src/commands/deny/denyAdd.ts
|
|
4016
|
-
import
|
|
4191
|
+
import chalk54 from "chalk";
|
|
4017
4192
|
function denyAdd(pattern2, message) {
|
|
4018
4193
|
const config = loadProjectConfig();
|
|
4019
4194
|
const deny = config.deny ?? [];
|
|
4020
4195
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
4021
|
-
console.log(
|
|
4196
|
+
console.log(chalk54.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
4022
4197
|
return;
|
|
4023
4198
|
}
|
|
4024
4199
|
deny.push({ pattern: pattern2, message });
|
|
4025
4200
|
config.deny = deny;
|
|
4026
4201
|
saveConfig(config);
|
|
4027
|
-
console.log(
|
|
4202
|
+
console.log(chalk54.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
4028
4203
|
}
|
|
4029
4204
|
|
|
4030
4205
|
// src/commands/deny/denyList.ts
|
|
4031
|
-
import
|
|
4206
|
+
import chalk55 from "chalk";
|
|
4032
4207
|
function denyList() {
|
|
4033
4208
|
const config = loadConfig();
|
|
4034
4209
|
const deny = config.deny;
|
|
4035
4210
|
if (!deny || deny.length === 0) {
|
|
4036
|
-
console.log(
|
|
4211
|
+
console.log(chalk55.dim("No deny rules configured."));
|
|
4037
4212
|
return;
|
|
4038
4213
|
}
|
|
4039
4214
|
for (const rule of deny) {
|
|
4040
|
-
console.log(`${
|
|
4215
|
+
console.log(`${chalk55.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
4041
4216
|
}
|
|
4042
4217
|
}
|
|
4043
4218
|
|
|
4044
4219
|
// src/commands/deny/denyRemove.ts
|
|
4045
|
-
import
|
|
4220
|
+
import chalk56 from "chalk";
|
|
4046
4221
|
function denyRemove(pattern2) {
|
|
4047
4222
|
const config = loadProjectConfig();
|
|
4048
4223
|
const deny = config.deny ?? [];
|
|
4049
4224
|
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
4050
4225
|
if (index === -1) {
|
|
4051
|
-
console.log(
|
|
4226
|
+
console.log(chalk56.yellow(`No deny rule found for: ${pattern2}`));
|
|
4052
4227
|
return;
|
|
4053
4228
|
}
|
|
4054
4229
|
deny.splice(index, 1);
|
|
4055
4230
|
config.deny = deny.length > 0 ? deny : void 0;
|
|
4056
4231
|
saveConfig(config);
|
|
4057
|
-
console.log(
|
|
4232
|
+
console.log(chalk56.green(`Removed deny rule: ${pattern2}`));
|
|
4058
4233
|
}
|
|
4059
4234
|
|
|
4060
4235
|
// src/commands/permitCliReads/index.ts
|
|
@@ -4104,11 +4279,11 @@ function assertCliExists(cli) {
|
|
|
4104
4279
|
}
|
|
4105
4280
|
|
|
4106
4281
|
// src/commands/permitCliReads/colorize.ts
|
|
4107
|
-
import
|
|
4282
|
+
import chalk57 from "chalk";
|
|
4108
4283
|
function colorize(plainOutput) {
|
|
4109
4284
|
return plainOutput.split("\n").map((line) => {
|
|
4110
|
-
if (line.startsWith(" R ")) return
|
|
4111
|
-
if (line.startsWith(" W ")) return
|
|
4285
|
+
if (line.startsWith(" R ")) return chalk57.green(line);
|
|
4286
|
+
if (line.startsWith(" W ")) return chalk57.red(line);
|
|
4112
4287
|
return line;
|
|
4113
4288
|
}).join("\n");
|
|
4114
4289
|
}
|
|
@@ -4426,15 +4601,15 @@ function registerCliHook(program2) {
|
|
|
4426
4601
|
}
|
|
4427
4602
|
|
|
4428
4603
|
// src/commands/complexity/analyze.ts
|
|
4429
|
-
import
|
|
4604
|
+
import chalk63 from "chalk";
|
|
4430
4605
|
|
|
4431
4606
|
// src/commands/complexity/cyclomatic.ts
|
|
4432
|
-
import
|
|
4607
|
+
import chalk59 from "chalk";
|
|
4433
4608
|
|
|
4434
4609
|
// src/commands/complexity/shared/index.ts
|
|
4435
4610
|
import fs12 from "fs";
|
|
4436
4611
|
import path20 from "path";
|
|
4437
|
-
import
|
|
4612
|
+
import chalk58 from "chalk";
|
|
4438
4613
|
import ts5 from "typescript";
|
|
4439
4614
|
|
|
4440
4615
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4680,7 +4855,7 @@ function createSourceFromFile(filePath) {
|
|
|
4680
4855
|
function withSourceFiles(pattern2, callback) {
|
|
4681
4856
|
const files = findSourceFiles2(pattern2);
|
|
4682
4857
|
if (files.length === 0) {
|
|
4683
|
-
console.log(
|
|
4858
|
+
console.log(chalk58.yellow("No files found matching pattern"));
|
|
4684
4859
|
return void 0;
|
|
4685
4860
|
}
|
|
4686
4861
|
return callback(files);
|
|
@@ -4713,11 +4888,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4713
4888
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4714
4889
|
for (const { file, name, complexity } of results) {
|
|
4715
4890
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4716
|
-
const color = exceedsThreshold ?
|
|
4717
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4891
|
+
const color = exceedsThreshold ? chalk59.red : chalk59.white;
|
|
4892
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk59.cyan(complexity)}`);
|
|
4718
4893
|
}
|
|
4719
4894
|
console.log(
|
|
4720
|
-
|
|
4895
|
+
chalk59.dim(
|
|
4721
4896
|
`
|
|
4722
4897
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4723
4898
|
)
|
|
@@ -4729,7 +4904,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4729
4904
|
}
|
|
4730
4905
|
|
|
4731
4906
|
// src/commands/complexity/halstead.ts
|
|
4732
|
-
import
|
|
4907
|
+
import chalk60 from "chalk";
|
|
4733
4908
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4734
4909
|
withSourceFiles(pattern2, (files) => {
|
|
4735
4910
|
const results = [];
|
|
@@ -4744,13 +4919,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4744
4919
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4745
4920
|
for (const { file, name, metrics } of results) {
|
|
4746
4921
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4747
|
-
const color = exceedsThreshold ?
|
|
4922
|
+
const color = exceedsThreshold ? chalk60.red : chalk60.white;
|
|
4748
4923
|
console.log(
|
|
4749
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4924
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk60.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk60.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk60.magenta(metrics.effort.toFixed(1))}`
|
|
4750
4925
|
);
|
|
4751
4926
|
}
|
|
4752
4927
|
console.log(
|
|
4753
|
-
|
|
4928
|
+
chalk60.dim(
|
|
4754
4929
|
`
|
|
4755
4930
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4756
4931
|
)
|
|
@@ -4765,28 +4940,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4765
4940
|
import fs13 from "fs";
|
|
4766
4941
|
|
|
4767
4942
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4768
|
-
import
|
|
4943
|
+
import chalk61 from "chalk";
|
|
4769
4944
|
function displayMaintainabilityResults(results, threshold) {
|
|
4770
4945
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4771
4946
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4772
|
-
console.log(
|
|
4947
|
+
console.log(chalk61.green("All files pass maintainability threshold"));
|
|
4773
4948
|
} else {
|
|
4774
4949
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4775
|
-
const color = threshold !== void 0 ?
|
|
4950
|
+
const color = threshold !== void 0 ? chalk61.red : chalk61.white;
|
|
4776
4951
|
console.log(
|
|
4777
|
-
`${color(file)} \u2192 avg: ${
|
|
4952
|
+
`${color(file)} \u2192 avg: ${chalk61.cyan(avgMaintainability.toFixed(1))}, min: ${chalk61.yellow(minMaintainability.toFixed(1))}`
|
|
4778
4953
|
);
|
|
4779
4954
|
}
|
|
4780
4955
|
}
|
|
4781
|
-
console.log(
|
|
4956
|
+
console.log(chalk61.dim(`
|
|
4782
4957
|
Analyzed ${results.length} files`));
|
|
4783
4958
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4784
4959
|
console.error(
|
|
4785
|
-
|
|
4960
|
+
chalk61.red(
|
|
4786
4961
|
`
|
|
4787
4962
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4788
4963
|
|
|
4789
|
-
\u26A0\uFE0F ${
|
|
4964
|
+
\u26A0\uFE0F ${chalk61.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.`
|
|
4790
4965
|
)
|
|
4791
4966
|
);
|
|
4792
4967
|
process.exit(1);
|
|
@@ -4843,7 +5018,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4843
5018
|
|
|
4844
5019
|
// src/commands/complexity/sloc.ts
|
|
4845
5020
|
import fs14 from "fs";
|
|
4846
|
-
import
|
|
5021
|
+
import chalk62 from "chalk";
|
|
4847
5022
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4848
5023
|
withSourceFiles(pattern2, (files) => {
|
|
4849
5024
|
const results = [];
|
|
@@ -4859,12 +5034,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4859
5034
|
results.sort((a, b) => b.lines - a.lines);
|
|
4860
5035
|
for (const { file, lines } of results) {
|
|
4861
5036
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4862
|
-
const color = exceedsThreshold ?
|
|
4863
|
-
console.log(`${color(file)} \u2192 ${
|
|
5037
|
+
const color = exceedsThreshold ? chalk62.red : chalk62.white;
|
|
5038
|
+
console.log(`${color(file)} \u2192 ${chalk62.cyan(lines)} lines`);
|
|
4864
5039
|
}
|
|
4865
5040
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4866
5041
|
console.log(
|
|
4867
|
-
|
|
5042
|
+
chalk62.dim(`
|
|
4868
5043
|
Total: ${total} lines across ${files.length} files`)
|
|
4869
5044
|
);
|
|
4870
5045
|
if (hasViolation) {
|
|
@@ -4878,21 +5053,21 @@ async function analyze(pattern2) {
|
|
|
4878
5053
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4879
5054
|
const files = findSourceFiles2(searchPattern);
|
|
4880
5055
|
if (files.length === 0) {
|
|
4881
|
-
console.log(
|
|
5056
|
+
console.log(chalk63.yellow("No files found matching pattern"));
|
|
4882
5057
|
return;
|
|
4883
5058
|
}
|
|
4884
5059
|
if (files.length === 1) {
|
|
4885
5060
|
const file = files[0];
|
|
4886
|
-
console.log(
|
|
5061
|
+
console.log(chalk63.bold.underline("SLOC"));
|
|
4887
5062
|
await sloc(file);
|
|
4888
5063
|
console.log();
|
|
4889
|
-
console.log(
|
|
5064
|
+
console.log(chalk63.bold.underline("Cyclomatic Complexity"));
|
|
4890
5065
|
await cyclomatic(file);
|
|
4891
5066
|
console.log();
|
|
4892
|
-
console.log(
|
|
5067
|
+
console.log(chalk63.bold.underline("Halstead Metrics"));
|
|
4893
5068
|
await halstead(file);
|
|
4894
5069
|
console.log();
|
|
4895
|
-
console.log(
|
|
5070
|
+
console.log(chalk63.bold.underline("Maintainability Index"));
|
|
4896
5071
|
await maintainability(file);
|
|
4897
5072
|
return;
|
|
4898
5073
|
}
|
|
@@ -4920,7 +5095,7 @@ function registerComplexity(program2) {
|
|
|
4920
5095
|
|
|
4921
5096
|
// src/commands/deploy/redirect.ts
|
|
4922
5097
|
import { existsSync as existsSync24, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "fs";
|
|
4923
|
-
import
|
|
5098
|
+
import chalk64 from "chalk";
|
|
4924
5099
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4925
5100
|
if (!window.location.pathname.endsWith('/')) {
|
|
4926
5101
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4929,22 +5104,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4929
5104
|
function redirect() {
|
|
4930
5105
|
const indexPath = "index.html";
|
|
4931
5106
|
if (!existsSync24(indexPath)) {
|
|
4932
|
-
console.log(
|
|
5107
|
+
console.log(chalk64.yellow("No index.html found"));
|
|
4933
5108
|
return;
|
|
4934
5109
|
}
|
|
4935
5110
|
const content = readFileSync19(indexPath, "utf-8");
|
|
4936
5111
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4937
|
-
console.log(
|
|
5112
|
+
console.log(chalk64.dim("Trailing slash script already present"));
|
|
4938
5113
|
return;
|
|
4939
5114
|
}
|
|
4940
5115
|
const headCloseIndex = content.indexOf("</head>");
|
|
4941
5116
|
if (headCloseIndex === -1) {
|
|
4942
|
-
console.log(
|
|
5117
|
+
console.log(chalk64.red("Could not find </head> tag in index.html"));
|
|
4943
5118
|
return;
|
|
4944
5119
|
}
|
|
4945
5120
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4946
5121
|
writeFileSync17(indexPath, newContent);
|
|
4947
|
-
console.log(
|
|
5122
|
+
console.log(chalk64.green("Added trailing slash redirect to index.html"));
|
|
4948
5123
|
}
|
|
4949
5124
|
|
|
4950
5125
|
// src/commands/registerDeploy.ts
|
|
@@ -4971,7 +5146,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
4971
5146
|
|
|
4972
5147
|
// src/commands/devlog/shared.ts
|
|
4973
5148
|
import { execSync as execSync17 } from "child_process";
|
|
4974
|
-
import
|
|
5149
|
+
import chalk65 from "chalk";
|
|
4975
5150
|
|
|
4976
5151
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4977
5152
|
import { readdirSync, readFileSync as readFileSync20 } from "fs";
|
|
@@ -5058,13 +5233,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
5058
5233
|
}
|
|
5059
5234
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
5060
5235
|
for (const commit2 of commits) {
|
|
5061
|
-
console.log(` ${
|
|
5236
|
+
console.log(` ${chalk65.yellow(commit2.hash)} ${commit2.message}`);
|
|
5062
5237
|
if (verbose) {
|
|
5063
5238
|
const visibleFiles = commit2.files.filter(
|
|
5064
5239
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
5065
5240
|
);
|
|
5066
5241
|
for (const file of visibleFiles) {
|
|
5067
|
-
console.log(` ${
|
|
5242
|
+
console.log(` ${chalk65.dim(file)}`);
|
|
5068
5243
|
}
|
|
5069
5244
|
}
|
|
5070
5245
|
}
|
|
@@ -5089,15 +5264,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
5089
5264
|
}
|
|
5090
5265
|
|
|
5091
5266
|
// src/commands/devlog/list/printDateHeader.ts
|
|
5092
|
-
import
|
|
5267
|
+
import chalk66 from "chalk";
|
|
5093
5268
|
function printDateHeader(date, isSkipped, entries) {
|
|
5094
5269
|
if (isSkipped) {
|
|
5095
|
-
console.log(`${
|
|
5270
|
+
console.log(`${chalk66.bold.blue(date)} ${chalk66.dim("skipped")}`);
|
|
5096
5271
|
} else if (entries && entries.length > 0) {
|
|
5097
|
-
const entryInfo = entries.map((e) => `${
|
|
5098
|
-
console.log(`${
|
|
5272
|
+
const entryInfo = entries.map((e) => `${chalk66.green(e.version)} ${e.title}`).join(" | ");
|
|
5273
|
+
console.log(`${chalk66.bold.blue(date)} ${entryInfo}`);
|
|
5099
5274
|
} else {
|
|
5100
|
-
console.log(`${
|
|
5275
|
+
console.log(`${chalk66.bold.blue(date)} ${chalk66.red("\u26A0 devlog missing")}`);
|
|
5101
5276
|
}
|
|
5102
5277
|
}
|
|
5103
5278
|
|
|
@@ -5200,24 +5375,24 @@ function bumpVersion(version2, type) {
|
|
|
5200
5375
|
|
|
5201
5376
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
5202
5377
|
import { execSync as execSync20 } from "child_process";
|
|
5203
|
-
import
|
|
5378
|
+
import chalk68 from "chalk";
|
|
5204
5379
|
|
|
5205
5380
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
5206
|
-
import
|
|
5381
|
+
import chalk67 from "chalk";
|
|
5207
5382
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
5208
5383
|
if (conventional && firstHash) {
|
|
5209
5384
|
const version2 = getVersionAtCommit(firstHash);
|
|
5210
5385
|
if (version2) {
|
|
5211
|
-
console.log(`${
|
|
5386
|
+
console.log(`${chalk67.bold("version:")} ${stripToMinor(version2)}`);
|
|
5212
5387
|
} else {
|
|
5213
|
-
console.log(`${
|
|
5388
|
+
console.log(`${chalk67.bold("version:")} ${chalk67.red("unknown")}`);
|
|
5214
5389
|
}
|
|
5215
5390
|
} else if (patchVersion && minorVersion) {
|
|
5216
5391
|
console.log(
|
|
5217
|
-
`${
|
|
5392
|
+
`${chalk67.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
5218
5393
|
);
|
|
5219
5394
|
} else {
|
|
5220
|
-
console.log(`${
|
|
5395
|
+
console.log(`${chalk67.bold("version:")} v0.1 (initial)`);
|
|
5221
5396
|
}
|
|
5222
5397
|
}
|
|
5223
5398
|
|
|
@@ -5264,16 +5439,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
5264
5439
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
5265
5440
|
}
|
|
5266
5441
|
function logName(repoName) {
|
|
5267
|
-
console.log(`${
|
|
5442
|
+
console.log(`${chalk68.bold("name:")} ${repoName}`);
|
|
5268
5443
|
}
|
|
5269
5444
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
5270
5445
|
logName(ctx.repoName);
|
|
5271
5446
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
5272
|
-
console.log(
|
|
5447
|
+
console.log(chalk68.bold.blue(targetDate));
|
|
5273
5448
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
5274
5449
|
}
|
|
5275
5450
|
function logNoCommits(lastInfo) {
|
|
5276
|
-
console.log(
|
|
5451
|
+
console.log(chalk68.dim(noCommitsMessage(!!lastInfo)));
|
|
5277
5452
|
}
|
|
5278
5453
|
|
|
5279
5454
|
// src/commands/devlog/next/index.ts
|
|
@@ -5314,11 +5489,11 @@ function next2(options2) {
|
|
|
5314
5489
|
import { execSync as execSync21 } from "child_process";
|
|
5315
5490
|
|
|
5316
5491
|
// src/commands/devlog/repos/printReposTable.ts
|
|
5317
|
-
import
|
|
5492
|
+
import chalk69 from "chalk";
|
|
5318
5493
|
function colorStatus(status2) {
|
|
5319
|
-
if (status2 === "missing") return
|
|
5320
|
-
if (status2 === "outdated") return
|
|
5321
|
-
return
|
|
5494
|
+
if (status2 === "missing") return chalk69.red(status2);
|
|
5495
|
+
if (status2 === "outdated") return chalk69.yellow(status2);
|
|
5496
|
+
return chalk69.green(status2);
|
|
5322
5497
|
}
|
|
5323
5498
|
function formatRow(row, nameWidth) {
|
|
5324
5499
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -5332,8 +5507,8 @@ function printReposTable(rows) {
|
|
|
5332
5507
|
"Last Devlog".padEnd(11),
|
|
5333
5508
|
"Status"
|
|
5334
5509
|
].join(" ");
|
|
5335
|
-
console.log(
|
|
5336
|
-
console.log(
|
|
5510
|
+
console.log(chalk69.dim(header));
|
|
5511
|
+
console.log(chalk69.dim("-".repeat(header.length)));
|
|
5337
5512
|
for (const row of rows) {
|
|
5338
5513
|
console.log(formatRow(row, nameWidth));
|
|
5339
5514
|
}
|
|
@@ -5391,14 +5566,14 @@ function repos(options2) {
|
|
|
5391
5566
|
// src/commands/devlog/skip.ts
|
|
5392
5567
|
import { writeFileSync as writeFileSync18 } from "fs";
|
|
5393
5568
|
import { join as join17 } from "path";
|
|
5394
|
-
import
|
|
5569
|
+
import chalk70 from "chalk";
|
|
5395
5570
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
5396
5571
|
function getBlogConfigPath() {
|
|
5397
5572
|
return join17(BLOG_REPO_ROOT, "assist.yml");
|
|
5398
5573
|
}
|
|
5399
5574
|
function skip(date) {
|
|
5400
5575
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5401
|
-
console.log(
|
|
5576
|
+
console.log(chalk70.red("Invalid date format. Use YYYY-MM-DD"));
|
|
5402
5577
|
process.exit(1);
|
|
5403
5578
|
}
|
|
5404
5579
|
const repoName = getRepoName();
|
|
@@ -5409,7 +5584,7 @@ function skip(date) {
|
|
|
5409
5584
|
const skipDays = skip2[repoName] ?? [];
|
|
5410
5585
|
if (skipDays.includes(date)) {
|
|
5411
5586
|
console.log(
|
|
5412
|
-
|
|
5587
|
+
chalk70.yellow(`${date} is already in skip list for ${repoName}`)
|
|
5413
5588
|
);
|
|
5414
5589
|
return;
|
|
5415
5590
|
}
|
|
@@ -5419,20 +5594,20 @@ function skip(date) {
|
|
|
5419
5594
|
devlog.skip = skip2;
|
|
5420
5595
|
config.devlog = devlog;
|
|
5421
5596
|
writeFileSync18(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
5422
|
-
console.log(
|
|
5597
|
+
console.log(chalk70.green(`Added ${date} to skip list for ${repoName}`));
|
|
5423
5598
|
}
|
|
5424
5599
|
|
|
5425
5600
|
// src/commands/devlog/version.ts
|
|
5426
|
-
import
|
|
5601
|
+
import chalk71 from "chalk";
|
|
5427
5602
|
function version() {
|
|
5428
5603
|
const config = loadConfig();
|
|
5429
5604
|
const name = getRepoName();
|
|
5430
5605
|
const lastInfo = getLastVersionInfo(name, config);
|
|
5431
5606
|
const lastVersion = lastInfo?.version ?? null;
|
|
5432
5607
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
5433
|
-
console.log(`${
|
|
5434
|
-
console.log(`${
|
|
5435
|
-
console.log(`${
|
|
5608
|
+
console.log(`${chalk71.bold("name:")} ${name}`);
|
|
5609
|
+
console.log(`${chalk71.bold("last:")} ${lastVersion ?? chalk71.dim("none")}`);
|
|
5610
|
+
console.log(`${chalk71.bold("next:")} ${nextVersion ?? chalk71.dim("none")}`);
|
|
5436
5611
|
}
|
|
5437
5612
|
|
|
5438
5613
|
// src/commands/registerDevlog.ts
|
|
@@ -5456,7 +5631,7 @@ function registerDevlog(program2) {
|
|
|
5456
5631
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5457
5632
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5458
5633
|
import { join as join18 } from "path";
|
|
5459
|
-
import
|
|
5634
|
+
import chalk72 from "chalk";
|
|
5460
5635
|
|
|
5461
5636
|
// src/shared/findRepoRoot.ts
|
|
5462
5637
|
import { existsSync as existsSync25 } from "fs";
|
|
@@ -5519,14 +5694,14 @@ function checkBuildLocks(startDir) {
|
|
|
5519
5694
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5520
5695
|
if (locked) {
|
|
5521
5696
|
console.error(
|
|
5522
|
-
|
|
5697
|
+
chalk72.red("Build output locked (is VS debugging?): ") + locked
|
|
5523
5698
|
);
|
|
5524
5699
|
process.exit(1);
|
|
5525
5700
|
}
|
|
5526
5701
|
}
|
|
5527
5702
|
async function checkBuildLocksCommand() {
|
|
5528
5703
|
checkBuildLocks();
|
|
5529
|
-
console.log(
|
|
5704
|
+
console.log(chalk72.green("No build locks detected"));
|
|
5530
5705
|
}
|
|
5531
5706
|
|
|
5532
5707
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -5625,30 +5800,30 @@ function escapeRegex(s) {
|
|
|
5625
5800
|
}
|
|
5626
5801
|
|
|
5627
5802
|
// src/commands/dotnet/printTree.ts
|
|
5628
|
-
import
|
|
5803
|
+
import chalk73 from "chalk";
|
|
5629
5804
|
function printNodes(nodes, prefix2) {
|
|
5630
5805
|
for (let i = 0; i < nodes.length; i++) {
|
|
5631
5806
|
const isLast = i === nodes.length - 1;
|
|
5632
5807
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5633
5808
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5634
5809
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5635
|
-
const label2 = isMissing ?
|
|
5810
|
+
const label2 = isMissing ? chalk73.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5636
5811
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5637
5812
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5638
5813
|
}
|
|
5639
5814
|
}
|
|
5640
5815
|
function printTree(tree, totalCount, solutions) {
|
|
5641
|
-
console.log(
|
|
5642
|
-
console.log(
|
|
5816
|
+
console.log(chalk73.bold("\nProject Dependency Tree"));
|
|
5817
|
+
console.log(chalk73.cyan(tree.relativePath));
|
|
5643
5818
|
printNodes(tree.children, "");
|
|
5644
|
-
console.log(
|
|
5819
|
+
console.log(chalk73.dim(`
|
|
5645
5820
|
${totalCount} projects total (including root)`));
|
|
5646
|
-
console.log(
|
|
5821
|
+
console.log(chalk73.bold("\nSolution Membership"));
|
|
5647
5822
|
if (solutions.length === 0) {
|
|
5648
|
-
console.log(
|
|
5823
|
+
console.log(chalk73.yellow(" Not found in any .sln"));
|
|
5649
5824
|
} else {
|
|
5650
5825
|
for (const sln of solutions) {
|
|
5651
|
-
console.log(` ${
|
|
5826
|
+
console.log(` ${chalk73.green(sln)}`);
|
|
5652
5827
|
}
|
|
5653
5828
|
}
|
|
5654
5829
|
console.log();
|
|
@@ -5677,16 +5852,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5677
5852
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5678
5853
|
import { existsSync as existsSync26 } from "fs";
|
|
5679
5854
|
import path24 from "path";
|
|
5680
|
-
import
|
|
5855
|
+
import chalk74 from "chalk";
|
|
5681
5856
|
function resolveCsproj(csprojPath) {
|
|
5682
5857
|
const resolved = path24.resolve(csprojPath);
|
|
5683
5858
|
if (!existsSync26(resolved)) {
|
|
5684
|
-
console.error(
|
|
5859
|
+
console.error(chalk74.red(`File not found: ${resolved}`));
|
|
5685
5860
|
process.exit(1);
|
|
5686
5861
|
}
|
|
5687
5862
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5688
5863
|
if (!repoRoot) {
|
|
5689
|
-
console.error(
|
|
5864
|
+
console.error(chalk74.red("Could not find git repository root"));
|
|
5690
5865
|
process.exit(1);
|
|
5691
5866
|
}
|
|
5692
5867
|
return { resolved, repoRoot };
|
|
@@ -5736,12 +5911,12 @@ function getChangedCsFiles(scope) {
|
|
|
5736
5911
|
}
|
|
5737
5912
|
|
|
5738
5913
|
// src/commands/dotnet/inSln.ts
|
|
5739
|
-
import
|
|
5914
|
+
import chalk75 from "chalk";
|
|
5740
5915
|
async function inSln(csprojPath) {
|
|
5741
5916
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5742
5917
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5743
5918
|
if (solutions.length === 0) {
|
|
5744
|
-
console.log(
|
|
5919
|
+
console.log(chalk75.yellow("Not found in any .sln file"));
|
|
5745
5920
|
process.exit(1);
|
|
5746
5921
|
}
|
|
5747
5922
|
for (const sln of solutions) {
|
|
@@ -5750,7 +5925,7 @@ async function inSln(csprojPath) {
|
|
|
5750
5925
|
}
|
|
5751
5926
|
|
|
5752
5927
|
// src/commands/dotnet/inspect.ts
|
|
5753
|
-
import
|
|
5928
|
+
import chalk81 from "chalk";
|
|
5754
5929
|
|
|
5755
5930
|
// src/shared/formatElapsed.ts
|
|
5756
5931
|
function formatElapsed(ms) {
|
|
@@ -5762,12 +5937,12 @@ function formatElapsed(ms) {
|
|
|
5762
5937
|
}
|
|
5763
5938
|
|
|
5764
5939
|
// src/commands/dotnet/displayIssues.ts
|
|
5765
|
-
import
|
|
5940
|
+
import chalk76 from "chalk";
|
|
5766
5941
|
var SEVERITY_COLOR = {
|
|
5767
|
-
ERROR:
|
|
5768
|
-
WARNING:
|
|
5769
|
-
SUGGESTION:
|
|
5770
|
-
HINT:
|
|
5942
|
+
ERROR: chalk76.red,
|
|
5943
|
+
WARNING: chalk76.yellow,
|
|
5944
|
+
SUGGESTION: chalk76.cyan,
|
|
5945
|
+
HINT: chalk76.dim
|
|
5771
5946
|
};
|
|
5772
5947
|
function groupByFile(issues) {
|
|
5773
5948
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5783,15 +5958,15 @@ function groupByFile(issues) {
|
|
|
5783
5958
|
}
|
|
5784
5959
|
function displayIssues(issues) {
|
|
5785
5960
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5786
|
-
console.log(
|
|
5961
|
+
console.log(chalk76.bold(file));
|
|
5787
5962
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5788
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5963
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk76.white;
|
|
5789
5964
|
console.log(
|
|
5790
|
-
` ${
|
|
5965
|
+
` ${chalk76.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5791
5966
|
);
|
|
5792
5967
|
}
|
|
5793
5968
|
}
|
|
5794
|
-
console.log(
|
|
5969
|
+
console.log(chalk76.dim(`
|
|
5795
5970
|
${issues.length} issue(s) found`));
|
|
5796
5971
|
}
|
|
5797
5972
|
|
|
@@ -5850,12 +6025,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5850
6025
|
// src/commands/dotnet/resolveSolution.ts
|
|
5851
6026
|
import { existsSync as existsSync27 } from "fs";
|
|
5852
6027
|
import path25 from "path";
|
|
5853
|
-
import
|
|
6028
|
+
import chalk78 from "chalk";
|
|
5854
6029
|
|
|
5855
6030
|
// src/commands/dotnet/findSolution.ts
|
|
5856
6031
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5857
6032
|
import { dirname as dirname16, join as join19 } from "path";
|
|
5858
|
-
import
|
|
6033
|
+
import chalk77 from "chalk";
|
|
5859
6034
|
function findSlnInDir(dir) {
|
|
5860
6035
|
try {
|
|
5861
6036
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join19(dir, f));
|
|
@@ -5871,17 +6046,17 @@ function findSolution() {
|
|
|
5871
6046
|
const slnFiles = findSlnInDir(current);
|
|
5872
6047
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5873
6048
|
if (slnFiles.length > 1) {
|
|
5874
|
-
console.error(
|
|
6049
|
+
console.error(chalk77.red(`Multiple .sln files found in ${current}:`));
|
|
5875
6050
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5876
6051
|
console.error(
|
|
5877
|
-
|
|
6052
|
+
chalk77.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5878
6053
|
);
|
|
5879
6054
|
process.exit(1);
|
|
5880
6055
|
}
|
|
5881
6056
|
if (current === ceiling) break;
|
|
5882
6057
|
current = dirname16(current);
|
|
5883
6058
|
}
|
|
5884
|
-
console.error(
|
|
6059
|
+
console.error(chalk77.red("No .sln file found between cwd and repo root"));
|
|
5885
6060
|
process.exit(1);
|
|
5886
6061
|
}
|
|
5887
6062
|
|
|
@@ -5890,7 +6065,7 @@ function resolveSolution(sln) {
|
|
|
5890
6065
|
if (sln) {
|
|
5891
6066
|
const resolved = path25.resolve(sln);
|
|
5892
6067
|
if (!existsSync27(resolved)) {
|
|
5893
|
-
console.error(
|
|
6068
|
+
console.error(chalk78.red(`Solution file not found: ${resolved}`));
|
|
5894
6069
|
process.exit(1);
|
|
5895
6070
|
}
|
|
5896
6071
|
return resolved;
|
|
@@ -5932,14 +6107,14 @@ import { execSync as execSync23 } from "child_process";
|
|
|
5932
6107
|
import { existsSync as existsSync28, readFileSync as readFileSync23, unlinkSync as unlinkSync5 } from "fs";
|
|
5933
6108
|
import { tmpdir as tmpdir2 } from "os";
|
|
5934
6109
|
import path26 from "path";
|
|
5935
|
-
import
|
|
6110
|
+
import chalk79 from "chalk";
|
|
5936
6111
|
function assertJbInstalled() {
|
|
5937
6112
|
try {
|
|
5938
6113
|
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5939
6114
|
} catch {
|
|
5940
|
-
console.error(
|
|
6115
|
+
console.error(chalk79.red("jb is not installed. Install with:"));
|
|
5941
6116
|
console.error(
|
|
5942
|
-
|
|
6117
|
+
chalk79.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5943
6118
|
);
|
|
5944
6119
|
process.exit(1);
|
|
5945
6120
|
}
|
|
@@ -5957,11 +6132,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5957
6132
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5958
6133
|
process.stderr.write(err.stderr);
|
|
5959
6134
|
}
|
|
5960
|
-
console.error(
|
|
6135
|
+
console.error(chalk79.red("jb inspectcode failed"));
|
|
5961
6136
|
process.exit(1);
|
|
5962
6137
|
}
|
|
5963
6138
|
if (!existsSync28(reportPath)) {
|
|
5964
|
-
console.error(
|
|
6139
|
+
console.error(chalk79.red("Report file not generated"));
|
|
5965
6140
|
process.exit(1);
|
|
5966
6141
|
}
|
|
5967
6142
|
const xml = readFileSync23(reportPath, "utf-8");
|
|
@@ -5971,7 +6146,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5971
6146
|
|
|
5972
6147
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5973
6148
|
import { execSync as execSync24 } from "child_process";
|
|
5974
|
-
import
|
|
6149
|
+
import chalk80 from "chalk";
|
|
5975
6150
|
function resolveMsbuildPath() {
|
|
5976
6151
|
const config = loadConfig();
|
|
5977
6152
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5982,9 +6157,9 @@ function assertMsbuildInstalled() {
|
|
|
5982
6157
|
try {
|
|
5983
6158
|
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5984
6159
|
} catch {
|
|
5985
|
-
console.error(
|
|
6160
|
+
console.error(chalk80.red(`msbuild not found at: ${msbuild}`));
|
|
5986
6161
|
console.error(
|
|
5987
|
-
|
|
6162
|
+
chalk80.yellow(
|
|
5988
6163
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5989
6164
|
)
|
|
5990
6165
|
);
|
|
@@ -6031,17 +6206,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
6031
6206
|
// src/commands/dotnet/inspect.ts
|
|
6032
6207
|
function logScope(changedFiles) {
|
|
6033
6208
|
if (changedFiles === null) {
|
|
6034
|
-
console.log(
|
|
6209
|
+
console.log(chalk81.dim("Inspecting full solution..."));
|
|
6035
6210
|
} else {
|
|
6036
6211
|
console.log(
|
|
6037
|
-
|
|
6212
|
+
chalk81.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
6038
6213
|
);
|
|
6039
6214
|
}
|
|
6040
6215
|
}
|
|
6041
6216
|
function reportResults(issues, elapsed) {
|
|
6042
6217
|
if (issues.length > 0) displayIssues(issues);
|
|
6043
|
-
else console.log(
|
|
6044
|
-
console.log(
|
|
6218
|
+
else console.log(chalk81.green("No issues found"));
|
|
6219
|
+
console.log(chalk81.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
6045
6220
|
if (issues.length > 0) process.exit(1);
|
|
6046
6221
|
}
|
|
6047
6222
|
async function inspect(sln, options2) {
|
|
@@ -6052,7 +6227,7 @@ async function inspect(sln, options2) {
|
|
|
6052
6227
|
const scope = parseScope(options2.scope);
|
|
6053
6228
|
const changedFiles = getChangedCsFiles(scope);
|
|
6054
6229
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
6055
|
-
console.log(
|
|
6230
|
+
console.log(chalk81.green("No changed .cs files found"));
|
|
6056
6231
|
return;
|
|
6057
6232
|
}
|
|
6058
6233
|
logScope(changedFiles);
|
|
@@ -6078,7 +6253,7 @@ function registerDotnet(program2) {
|
|
|
6078
6253
|
}
|
|
6079
6254
|
|
|
6080
6255
|
// src/commands/jira/acceptanceCriteria.ts
|
|
6081
|
-
import
|
|
6256
|
+
import chalk83 from "chalk";
|
|
6082
6257
|
|
|
6083
6258
|
// src/commands/jira/adfToText.ts
|
|
6084
6259
|
function renderInline(node) {
|
|
@@ -6139,7 +6314,7 @@ function adfToText(doc) {
|
|
|
6139
6314
|
|
|
6140
6315
|
// src/commands/jira/fetchIssue.ts
|
|
6141
6316
|
import { execSync as execSync25 } from "child_process";
|
|
6142
|
-
import
|
|
6317
|
+
import chalk82 from "chalk";
|
|
6143
6318
|
function fetchIssue(issueKey, fields) {
|
|
6144
6319
|
let result;
|
|
6145
6320
|
try {
|
|
@@ -6152,15 +6327,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
6152
6327
|
const stderr = error.stderr;
|
|
6153
6328
|
if (stderr.includes("unauthorized")) {
|
|
6154
6329
|
console.error(
|
|
6155
|
-
|
|
6330
|
+
chalk82.red("Jira authentication expired."),
|
|
6156
6331
|
"Run",
|
|
6157
|
-
|
|
6332
|
+
chalk82.cyan("assist jira auth"),
|
|
6158
6333
|
"to re-authenticate."
|
|
6159
6334
|
);
|
|
6160
6335
|
process.exit(1);
|
|
6161
6336
|
}
|
|
6162
6337
|
}
|
|
6163
|
-
console.error(
|
|
6338
|
+
console.error(chalk82.red(`Failed to fetch ${issueKey}.`));
|
|
6164
6339
|
process.exit(1);
|
|
6165
6340
|
}
|
|
6166
6341
|
return JSON.parse(result);
|
|
@@ -6174,7 +6349,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
6174
6349
|
const parsed = fetchIssue(issueKey, field);
|
|
6175
6350
|
const acValue = parsed?.fields?.[field];
|
|
6176
6351
|
if (!acValue) {
|
|
6177
|
-
console.log(
|
|
6352
|
+
console.log(chalk83.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
6178
6353
|
return;
|
|
6179
6354
|
}
|
|
6180
6355
|
if (typeof acValue === "string") {
|
|
@@ -6269,14 +6444,14 @@ async function jiraAuth() {
|
|
|
6269
6444
|
}
|
|
6270
6445
|
|
|
6271
6446
|
// src/commands/jira/viewIssue.ts
|
|
6272
|
-
import
|
|
6447
|
+
import chalk84 from "chalk";
|
|
6273
6448
|
function viewIssue(issueKey) {
|
|
6274
6449
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
6275
6450
|
const fields = parsed?.fields;
|
|
6276
6451
|
const summary = fields?.summary;
|
|
6277
6452
|
const description = fields?.description;
|
|
6278
6453
|
if (summary) {
|
|
6279
|
-
console.log(
|
|
6454
|
+
console.log(chalk84.bold(summary));
|
|
6280
6455
|
}
|
|
6281
6456
|
if (description) {
|
|
6282
6457
|
if (summary) console.log();
|
|
@@ -6290,7 +6465,7 @@ function viewIssue(issueKey) {
|
|
|
6290
6465
|
}
|
|
6291
6466
|
if (!summary && !description) {
|
|
6292
6467
|
console.log(
|
|
6293
|
-
|
|
6468
|
+
chalk84.yellow(`No summary or description found on ${issueKey}.`)
|
|
6294
6469
|
);
|
|
6295
6470
|
}
|
|
6296
6471
|
}
|
|
@@ -6304,7 +6479,7 @@ function registerJira(program2) {
|
|
|
6304
6479
|
}
|
|
6305
6480
|
|
|
6306
6481
|
// src/commands/news/add/index.ts
|
|
6307
|
-
import
|
|
6482
|
+
import chalk85 from "chalk";
|
|
6308
6483
|
import enquirer7 from "enquirer";
|
|
6309
6484
|
async function add2(url) {
|
|
6310
6485
|
if (!url) {
|
|
@@ -6327,17 +6502,17 @@ async function add2(url) {
|
|
|
6327
6502
|
const news = config.news ?? {};
|
|
6328
6503
|
const feeds = news.feeds ?? [];
|
|
6329
6504
|
if (feeds.includes(url)) {
|
|
6330
|
-
console.log(
|
|
6505
|
+
console.log(chalk85.yellow("Feed already exists in config"));
|
|
6331
6506
|
return;
|
|
6332
6507
|
}
|
|
6333
6508
|
feeds.push(url);
|
|
6334
6509
|
config.news = { ...news, feeds };
|
|
6335
6510
|
saveGlobalConfig(config);
|
|
6336
|
-
console.log(
|
|
6511
|
+
console.log(chalk85.green(`Added feed: ${url}`));
|
|
6337
6512
|
}
|
|
6338
6513
|
|
|
6339
6514
|
// src/commands/news/web/handleRequest.ts
|
|
6340
|
-
import
|
|
6515
|
+
import chalk86 from "chalk";
|
|
6341
6516
|
|
|
6342
6517
|
// src/commands/news/web/shared.ts
|
|
6343
6518
|
import { decodeHTML } from "entities";
|
|
@@ -6473,17 +6648,17 @@ function prefetch() {
|
|
|
6473
6648
|
const config = loadConfig();
|
|
6474
6649
|
const total = config.news.feeds.length;
|
|
6475
6650
|
if (total === 0) return;
|
|
6476
|
-
process.stdout.write(
|
|
6651
|
+
process.stdout.write(chalk86.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6477
6652
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6478
6653
|
const width = 20;
|
|
6479
6654
|
const filled = Math.round(done2 / t * width);
|
|
6480
6655
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6481
6656
|
process.stdout.write(
|
|
6482
|
-
`\r${
|
|
6657
|
+
`\r${chalk86.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6483
6658
|
);
|
|
6484
6659
|
}).then((items) => {
|
|
6485
6660
|
process.stdout.write(
|
|
6486
|
-
`\r${
|
|
6661
|
+
`\r${chalk86.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6487
6662
|
`
|
|
6488
6663
|
);
|
|
6489
6664
|
cachedItems = items;
|
|
@@ -6844,20 +7019,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6844
7019
|
}
|
|
6845
7020
|
|
|
6846
7021
|
// src/commands/prs/listComments/printComments.ts
|
|
6847
|
-
import
|
|
7022
|
+
import chalk87 from "chalk";
|
|
6848
7023
|
function formatForHuman(comment3) {
|
|
6849
7024
|
if (comment3.type === "review") {
|
|
6850
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
7025
|
+
const stateColor = comment3.state === "APPROVED" ? chalk87.green : comment3.state === "CHANGES_REQUESTED" ? chalk87.red : chalk87.yellow;
|
|
6851
7026
|
return [
|
|
6852
|
-
`${
|
|
7027
|
+
`${chalk87.cyan("Review")} by ${chalk87.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
6853
7028
|
comment3.body,
|
|
6854
7029
|
""
|
|
6855
7030
|
].join("\n");
|
|
6856
7031
|
}
|
|
6857
7032
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
6858
7033
|
return [
|
|
6859
|
-
`${
|
|
6860
|
-
|
|
7034
|
+
`${chalk87.cyan("Line comment")} by ${chalk87.bold(comment3.user)} on ${chalk87.dim(`${comment3.path}${location}`)}`,
|
|
7035
|
+
chalk87.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6861
7036
|
comment3.body,
|
|
6862
7037
|
""
|
|
6863
7038
|
].join("\n");
|
|
@@ -6947,13 +7122,13 @@ import { execSync as execSync32 } from "child_process";
|
|
|
6947
7122
|
import enquirer8 from "enquirer";
|
|
6948
7123
|
|
|
6949
7124
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6950
|
-
import
|
|
7125
|
+
import chalk88 from "chalk";
|
|
6951
7126
|
var STATUS_MAP = {
|
|
6952
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6953
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
7127
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk88.magenta("merged"), date: pr.mergedAt } : null,
|
|
7128
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk88.red("closed"), date: pr.closedAt } : null
|
|
6954
7129
|
};
|
|
6955
7130
|
function defaultStatus(pr) {
|
|
6956
|
-
return { label:
|
|
7131
|
+
return { label: chalk88.green("opened"), date: pr.createdAt };
|
|
6957
7132
|
}
|
|
6958
7133
|
function getStatus2(pr) {
|
|
6959
7134
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6962,11 +7137,11 @@ function formatDate(dateStr) {
|
|
|
6962
7137
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6963
7138
|
}
|
|
6964
7139
|
function formatPrHeader(pr, status2) {
|
|
6965
|
-
return `${
|
|
7140
|
+
return `${chalk88.cyan(`#${pr.number}`)} ${pr.title} ${chalk88.dim(`(${pr.author.login},`)} ${status2.label} ${chalk88.dim(`${formatDate(status2.date)})`)}`;
|
|
6966
7141
|
}
|
|
6967
7142
|
function logPrDetails(pr) {
|
|
6968
7143
|
console.log(
|
|
6969
|
-
|
|
7144
|
+
chalk88.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6970
7145
|
);
|
|
6971
7146
|
console.log();
|
|
6972
7147
|
}
|
|
@@ -7132,10 +7307,10 @@ function registerPrs(program2) {
|
|
|
7132
7307
|
}
|
|
7133
7308
|
|
|
7134
7309
|
// src/commands/ravendb/ravendbAuth.ts
|
|
7135
|
-
import
|
|
7310
|
+
import chalk94 from "chalk";
|
|
7136
7311
|
|
|
7137
7312
|
// src/shared/createConnectionAuth.ts
|
|
7138
|
-
import
|
|
7313
|
+
import chalk89 from "chalk";
|
|
7139
7314
|
function listConnections(connections, format2) {
|
|
7140
7315
|
if (connections.length === 0) {
|
|
7141
7316
|
console.log("No connections configured.");
|
|
@@ -7148,7 +7323,7 @@ function listConnections(connections, format2) {
|
|
|
7148
7323
|
function removeConnection(connections, name, save) {
|
|
7149
7324
|
const filtered = connections.filter((c) => c.name !== name);
|
|
7150
7325
|
if (filtered.length === connections.length) {
|
|
7151
|
-
console.error(
|
|
7326
|
+
console.error(chalk89.red(`Connection "${name}" not found.`));
|
|
7152
7327
|
process.exit(1);
|
|
7153
7328
|
}
|
|
7154
7329
|
save(filtered);
|
|
@@ -7194,15 +7369,15 @@ function saveConnections(connections) {
|
|
|
7194
7369
|
}
|
|
7195
7370
|
|
|
7196
7371
|
// src/commands/ravendb/promptConnection.ts
|
|
7197
|
-
import
|
|
7372
|
+
import chalk92 from "chalk";
|
|
7198
7373
|
|
|
7199
7374
|
// src/commands/ravendb/selectOpSecret.ts
|
|
7200
|
-
import
|
|
7375
|
+
import chalk91 from "chalk";
|
|
7201
7376
|
import Enquirer2 from "enquirer";
|
|
7202
7377
|
|
|
7203
7378
|
// src/commands/ravendb/searchItems.ts
|
|
7204
7379
|
import { execSync as execSync34 } from "child_process";
|
|
7205
|
-
import
|
|
7380
|
+
import chalk90 from "chalk";
|
|
7206
7381
|
function opExec(args) {
|
|
7207
7382
|
return execSync34(`op ${args}`, {
|
|
7208
7383
|
encoding: "utf-8",
|
|
@@ -7215,7 +7390,7 @@ function searchItems(search) {
|
|
|
7215
7390
|
items = JSON.parse(opExec("item list --format=json"));
|
|
7216
7391
|
} catch {
|
|
7217
7392
|
console.error(
|
|
7218
|
-
|
|
7393
|
+
chalk90.red(
|
|
7219
7394
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
7220
7395
|
)
|
|
7221
7396
|
);
|
|
@@ -7229,7 +7404,7 @@ function getItemFields(itemId) {
|
|
|
7229
7404
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
7230
7405
|
return item.fields.filter((f) => f.reference && f.label);
|
|
7231
7406
|
} catch {
|
|
7232
|
-
console.error(
|
|
7407
|
+
console.error(chalk90.red("Failed to get item details from 1Password."));
|
|
7233
7408
|
process.exit(1);
|
|
7234
7409
|
}
|
|
7235
7410
|
}
|
|
@@ -7248,7 +7423,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7248
7423
|
}).run();
|
|
7249
7424
|
const items = searchItems(search);
|
|
7250
7425
|
if (items.length === 0) {
|
|
7251
|
-
console.error(
|
|
7426
|
+
console.error(chalk91.red(`No items found matching "${search}".`));
|
|
7252
7427
|
process.exit(1);
|
|
7253
7428
|
}
|
|
7254
7429
|
const itemId = await selectOne(
|
|
@@ -7257,7 +7432,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7257
7432
|
);
|
|
7258
7433
|
const fields = getItemFields(itemId);
|
|
7259
7434
|
if (fields.length === 0) {
|
|
7260
|
-
console.error(
|
|
7435
|
+
console.error(chalk91.red("No fields with references found on this item."));
|
|
7261
7436
|
process.exit(1);
|
|
7262
7437
|
}
|
|
7263
7438
|
const ref = await selectOne(
|
|
@@ -7271,7 +7446,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7271
7446
|
async function promptConnection(existingNames) {
|
|
7272
7447
|
const name = await promptInput("name", "Connection name:");
|
|
7273
7448
|
if (existingNames.includes(name)) {
|
|
7274
|
-
console.error(
|
|
7449
|
+
console.error(chalk92.red(`Connection "${name}" already exists.`));
|
|
7275
7450
|
process.exit(1);
|
|
7276
7451
|
}
|
|
7277
7452
|
const url = await promptInput(
|
|
@@ -7280,22 +7455,22 @@ async function promptConnection(existingNames) {
|
|
|
7280
7455
|
);
|
|
7281
7456
|
const database = await promptInput("database", "Database name:");
|
|
7282
7457
|
if (!name || !url || !database) {
|
|
7283
|
-
console.error(
|
|
7458
|
+
console.error(chalk92.red("All fields are required."));
|
|
7284
7459
|
process.exit(1);
|
|
7285
7460
|
}
|
|
7286
7461
|
const apiKeyRef = await selectOpSecret();
|
|
7287
|
-
console.log(
|
|
7462
|
+
console.log(chalk92.dim(`Using: ${apiKeyRef}`));
|
|
7288
7463
|
return { name, url, database, apiKeyRef };
|
|
7289
7464
|
}
|
|
7290
7465
|
|
|
7291
7466
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
7292
|
-
import
|
|
7467
|
+
import chalk93 from "chalk";
|
|
7293
7468
|
function ravendbSetConnection(name) {
|
|
7294
7469
|
const raw = loadGlobalConfigRaw();
|
|
7295
7470
|
const ravendb = raw.ravendb ?? {};
|
|
7296
7471
|
const connections = ravendb.connections ?? [];
|
|
7297
7472
|
if (!connections.some((c) => c.name === name)) {
|
|
7298
|
-
console.error(
|
|
7473
|
+
console.error(chalk93.red(`Connection "${name}" not found.`));
|
|
7299
7474
|
console.error(
|
|
7300
7475
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7301
7476
|
);
|
|
@@ -7311,16 +7486,16 @@ function ravendbSetConnection(name) {
|
|
|
7311
7486
|
var ravendbAuth = createConnectionAuth({
|
|
7312
7487
|
load: loadConnections,
|
|
7313
7488
|
save: saveConnections,
|
|
7314
|
-
format: (c) => `${
|
|
7489
|
+
format: (c) => `${chalk94.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
7315
7490
|
promptNew: promptConnection,
|
|
7316
7491
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
7317
7492
|
});
|
|
7318
7493
|
|
|
7319
7494
|
// src/commands/ravendb/ravendbCollections.ts
|
|
7320
|
-
import
|
|
7495
|
+
import chalk98 from "chalk";
|
|
7321
7496
|
|
|
7322
7497
|
// src/commands/ravendb/ravenFetch.ts
|
|
7323
|
-
import
|
|
7498
|
+
import chalk96 from "chalk";
|
|
7324
7499
|
|
|
7325
7500
|
// src/commands/ravendb/getAccessToken.ts
|
|
7326
7501
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -7357,10 +7532,10 @@ ${errorText}`
|
|
|
7357
7532
|
|
|
7358
7533
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
7359
7534
|
import { execSync as execSync35 } from "child_process";
|
|
7360
|
-
import
|
|
7535
|
+
import chalk95 from "chalk";
|
|
7361
7536
|
function resolveOpSecret(reference) {
|
|
7362
7537
|
if (!reference.startsWith("op://")) {
|
|
7363
|
-
console.error(
|
|
7538
|
+
console.error(chalk95.red(`Invalid secret reference: must start with op://`));
|
|
7364
7539
|
process.exit(1);
|
|
7365
7540
|
}
|
|
7366
7541
|
try {
|
|
@@ -7370,7 +7545,7 @@ function resolveOpSecret(reference) {
|
|
|
7370
7545
|
}).trim();
|
|
7371
7546
|
} catch {
|
|
7372
7547
|
console.error(
|
|
7373
|
-
|
|
7548
|
+
chalk95.red(
|
|
7374
7549
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
7375
7550
|
)
|
|
7376
7551
|
);
|
|
@@ -7397,7 +7572,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7397
7572
|
if (!response.ok) {
|
|
7398
7573
|
const body = await response.text();
|
|
7399
7574
|
console.error(
|
|
7400
|
-
|
|
7575
|
+
chalk96.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
7401
7576
|
);
|
|
7402
7577
|
console.error(body.substring(0, 500));
|
|
7403
7578
|
process.exit(1);
|
|
@@ -7406,7 +7581,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7406
7581
|
}
|
|
7407
7582
|
|
|
7408
7583
|
// src/commands/ravendb/resolveConnection.ts
|
|
7409
|
-
import
|
|
7584
|
+
import chalk97 from "chalk";
|
|
7410
7585
|
function loadRavendb() {
|
|
7411
7586
|
const raw = loadGlobalConfigRaw();
|
|
7412
7587
|
const ravendb = raw.ravendb;
|
|
@@ -7420,7 +7595,7 @@ function resolveConnection(name) {
|
|
|
7420
7595
|
const connectionName = name ?? defaultConnection;
|
|
7421
7596
|
if (!connectionName) {
|
|
7422
7597
|
console.error(
|
|
7423
|
-
|
|
7598
|
+
chalk97.red(
|
|
7424
7599
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
7425
7600
|
)
|
|
7426
7601
|
);
|
|
@@ -7428,7 +7603,7 @@ function resolveConnection(name) {
|
|
|
7428
7603
|
}
|
|
7429
7604
|
const connection = connections.find((c) => c.name === connectionName);
|
|
7430
7605
|
if (!connection) {
|
|
7431
|
-
console.error(
|
|
7606
|
+
console.error(chalk97.red(`Connection "${connectionName}" not found.`));
|
|
7432
7607
|
console.error(
|
|
7433
7608
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7434
7609
|
);
|
|
@@ -7459,15 +7634,15 @@ async function ravendbCollections(connectionName) {
|
|
|
7459
7634
|
return;
|
|
7460
7635
|
}
|
|
7461
7636
|
for (const c of collections) {
|
|
7462
|
-
console.log(`${
|
|
7637
|
+
console.log(`${chalk98.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
7463
7638
|
}
|
|
7464
7639
|
}
|
|
7465
7640
|
|
|
7466
7641
|
// src/commands/ravendb/ravendbQuery.ts
|
|
7467
|
-
import
|
|
7642
|
+
import chalk100 from "chalk";
|
|
7468
7643
|
|
|
7469
7644
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7470
|
-
import
|
|
7645
|
+
import chalk99 from "chalk";
|
|
7471
7646
|
|
|
7472
7647
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7473
7648
|
function buildQueryPath(opts) {
|
|
@@ -7505,7 +7680,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7505
7680
|
allResults.push(...results);
|
|
7506
7681
|
start3 += results.length;
|
|
7507
7682
|
process.stderr.write(
|
|
7508
|
-
`\r${
|
|
7683
|
+
`\r${chalk99.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7509
7684
|
);
|
|
7510
7685
|
if (start3 >= totalResults) break;
|
|
7511
7686
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7520,7 +7695,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7520
7695
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7521
7696
|
const resolved = resolveArgs(connectionName, collection);
|
|
7522
7697
|
if (!resolved.collection && !options2.query) {
|
|
7523
|
-
console.error(
|
|
7698
|
+
console.error(chalk100.red("Provide a collection name or --query filter."));
|
|
7524
7699
|
process.exit(1);
|
|
7525
7700
|
}
|
|
7526
7701
|
const { collection: col } = resolved;
|
|
@@ -7558,7 +7733,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7558
7733
|
import * as path27 from "path";
|
|
7559
7734
|
|
|
7560
7735
|
// src/commands/refactor/logViolations.ts
|
|
7561
|
-
import
|
|
7736
|
+
import chalk101 from "chalk";
|
|
7562
7737
|
var DEFAULT_MAX_LINES = 100;
|
|
7563
7738
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7564
7739
|
if (violations.length === 0) {
|
|
@@ -7567,43 +7742,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7567
7742
|
}
|
|
7568
7743
|
return;
|
|
7569
7744
|
}
|
|
7570
|
-
console.error(
|
|
7745
|
+
console.error(chalk101.red(`
|
|
7571
7746
|
Refactor check failed:
|
|
7572
7747
|
`));
|
|
7573
|
-
console.error(
|
|
7748
|
+
console.error(chalk101.red(` The following files exceed ${maxLines} lines:
|
|
7574
7749
|
`));
|
|
7575
7750
|
for (const violation of violations) {
|
|
7576
|
-
console.error(
|
|
7751
|
+
console.error(chalk101.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7577
7752
|
}
|
|
7578
7753
|
console.error(
|
|
7579
|
-
|
|
7754
|
+
chalk101.yellow(
|
|
7580
7755
|
`
|
|
7581
7756
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7582
7757
|
way to refactor it, ignore it with:
|
|
7583
7758
|
`
|
|
7584
7759
|
)
|
|
7585
7760
|
);
|
|
7586
|
-
console.error(
|
|
7761
|
+
console.error(chalk101.gray(` assist refactor ignore <file>
|
|
7587
7762
|
`));
|
|
7588
7763
|
if (process.env.CLAUDECODE) {
|
|
7589
|
-
console.error(
|
|
7764
|
+
console.error(chalk101.cyan(`
|
|
7590
7765
|
## Extracting Code to New Files
|
|
7591
7766
|
`));
|
|
7592
7767
|
console.error(
|
|
7593
|
-
|
|
7768
|
+
chalk101.cyan(
|
|
7594
7769
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7595
7770
|
`
|
|
7596
7771
|
)
|
|
7597
7772
|
);
|
|
7598
7773
|
console.error(
|
|
7599
|
-
|
|
7774
|
+
chalk101.cyan(
|
|
7600
7775
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7601
7776
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7602
7777
|
`
|
|
7603
7778
|
)
|
|
7604
7779
|
);
|
|
7605
7780
|
console.error(
|
|
7606
|
-
|
|
7781
|
+
chalk101.cyan(
|
|
7607
7782
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7608
7783
|
domains, move it to a common/shared folder.
|
|
7609
7784
|
`
|
|
@@ -7759,7 +7934,7 @@ async function check(pattern2, options2) {
|
|
|
7759
7934
|
|
|
7760
7935
|
// src/commands/refactor/extract/index.ts
|
|
7761
7936
|
import path33 from "path";
|
|
7762
|
-
import
|
|
7937
|
+
import chalk104 from "chalk";
|
|
7763
7938
|
|
|
7764
7939
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7765
7940
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -8285,23 +8460,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
8285
8460
|
|
|
8286
8461
|
// src/commands/refactor/extract/displayPlan.ts
|
|
8287
8462
|
import path31 from "path";
|
|
8288
|
-
import
|
|
8463
|
+
import chalk102 from "chalk";
|
|
8289
8464
|
function section(title) {
|
|
8290
8465
|
return `
|
|
8291
|
-
${
|
|
8466
|
+
${chalk102.cyan(title)}`;
|
|
8292
8467
|
}
|
|
8293
8468
|
function displayImporters(plan2, cwd) {
|
|
8294
8469
|
if (plan2.importersToUpdate.length === 0) return;
|
|
8295
8470
|
console.log(section("Update importers:"));
|
|
8296
8471
|
for (const imp of plan2.importersToUpdate) {
|
|
8297
8472
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
8298
|
-
console.log(` ${
|
|
8473
|
+
console.log(` ${chalk102.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
8299
8474
|
}
|
|
8300
8475
|
}
|
|
8301
8476
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
8302
|
-
console.log(
|
|
8477
|
+
console.log(chalk102.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
8303
8478
|
`));
|
|
8304
|
-
console.log(` ${
|
|
8479
|
+
console.log(` ${chalk102.cyan("Functions to move:")}`);
|
|
8305
8480
|
for (const name of plan2.extractedNames) {
|
|
8306
8481
|
console.log(` ${name}`);
|
|
8307
8482
|
}
|
|
@@ -8336,7 +8511,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
8336
8511
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
8337
8512
|
import fs17 from "fs";
|
|
8338
8513
|
import path32 from "path";
|
|
8339
|
-
import
|
|
8514
|
+
import chalk103 from "chalk";
|
|
8340
8515
|
import { Project as Project2 } from "ts-morph";
|
|
8341
8516
|
function findTsConfig(sourcePath) {
|
|
8342
8517
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -8367,7 +8542,7 @@ function loadProjectFile(file) {
|
|
|
8367
8542
|
});
|
|
8368
8543
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
8369
8544
|
if (!sourceFile) {
|
|
8370
|
-
console.log(
|
|
8545
|
+
console.log(chalk103.red(`File not found in project: ${file}`));
|
|
8371
8546
|
process.exit(1);
|
|
8372
8547
|
}
|
|
8373
8548
|
return { project, sourceFile };
|
|
@@ -8390,19 +8565,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
8390
8565
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
8391
8566
|
if (options2.apply) {
|
|
8392
8567
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
8393
|
-
console.log(
|
|
8568
|
+
console.log(chalk104.green("\nExtraction complete"));
|
|
8394
8569
|
} else {
|
|
8395
|
-
console.log(
|
|
8570
|
+
console.log(chalk104.dim("\nDry run. Use --apply to execute."));
|
|
8396
8571
|
}
|
|
8397
8572
|
}
|
|
8398
8573
|
|
|
8399
8574
|
// src/commands/refactor/ignore.ts
|
|
8400
8575
|
import fs18 from "fs";
|
|
8401
|
-
import
|
|
8576
|
+
import chalk105 from "chalk";
|
|
8402
8577
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
8403
8578
|
function ignore(file) {
|
|
8404
8579
|
if (!fs18.existsSync(file)) {
|
|
8405
|
-
console.error(
|
|
8580
|
+
console.error(chalk105.red(`Error: File does not exist: ${file}`));
|
|
8406
8581
|
process.exit(1);
|
|
8407
8582
|
}
|
|
8408
8583
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -8418,7 +8593,7 @@ function ignore(file) {
|
|
|
8418
8593
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
8419
8594
|
}
|
|
8420
8595
|
console.log(
|
|
8421
|
-
|
|
8596
|
+
chalk105.green(
|
|
8422
8597
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
8423
8598
|
)
|
|
8424
8599
|
);
|
|
@@ -8426,26 +8601,26 @@ function ignore(file) {
|
|
|
8426
8601
|
|
|
8427
8602
|
// src/commands/refactor/rename/index.ts
|
|
8428
8603
|
import path34 from "path";
|
|
8429
|
-
import
|
|
8604
|
+
import chalk106 from "chalk";
|
|
8430
8605
|
async function rename(source, destination, options2 = {}) {
|
|
8431
8606
|
const destPath = path34.resolve(destination);
|
|
8432
8607
|
const cwd = process.cwd();
|
|
8433
8608
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
8434
8609
|
const relDest = path34.relative(cwd, destPath);
|
|
8435
8610
|
const { project, sourceFile } = loadProjectFile(source);
|
|
8436
|
-
console.log(
|
|
8611
|
+
console.log(chalk106.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
8437
8612
|
if (options2.apply) {
|
|
8438
8613
|
sourceFile.move(destPath);
|
|
8439
8614
|
await project.save();
|
|
8440
|
-
console.log(
|
|
8615
|
+
console.log(chalk106.green("Done"));
|
|
8441
8616
|
} else {
|
|
8442
|
-
console.log(
|
|
8617
|
+
console.log(chalk106.dim("Dry run. Use --apply to execute."));
|
|
8443
8618
|
}
|
|
8444
8619
|
}
|
|
8445
8620
|
|
|
8446
8621
|
// src/commands/refactor/renameSymbol/index.ts
|
|
8447
8622
|
import path36 from "path";
|
|
8448
|
-
import
|
|
8623
|
+
import chalk107 from "chalk";
|
|
8449
8624
|
import { Project as Project3 } from "ts-morph";
|
|
8450
8625
|
|
|
8451
8626
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8494,38 +8669,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8494
8669
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8495
8670
|
const sourceFile = project.getSourceFile(filePath);
|
|
8496
8671
|
if (!sourceFile) {
|
|
8497
|
-
console.log(
|
|
8672
|
+
console.log(chalk107.red(`File not found in project: ${file}`));
|
|
8498
8673
|
process.exit(1);
|
|
8499
8674
|
}
|
|
8500
8675
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8501
8676
|
if (!symbol) {
|
|
8502
|
-
console.log(
|
|
8677
|
+
console.log(chalk107.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8503
8678
|
process.exit(1);
|
|
8504
8679
|
}
|
|
8505
8680
|
const grouped = groupReferences(symbol, cwd);
|
|
8506
8681
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8507
8682
|
console.log(
|
|
8508
|
-
|
|
8683
|
+
chalk107.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8509
8684
|
`)
|
|
8510
8685
|
);
|
|
8511
8686
|
for (const [refFile, lines] of grouped) {
|
|
8512
8687
|
console.log(
|
|
8513
|
-
` ${
|
|
8688
|
+
` ${chalk107.dim(refFile)}: lines ${chalk107.cyan(lines.join(", "))}`
|
|
8514
8689
|
);
|
|
8515
8690
|
}
|
|
8516
8691
|
if (options2.apply) {
|
|
8517
8692
|
symbol.rename(newName);
|
|
8518
8693
|
await project.save();
|
|
8519
|
-
console.log(
|
|
8694
|
+
console.log(chalk107.green(`
|
|
8520
8695
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8521
8696
|
} else {
|
|
8522
|
-
console.log(
|
|
8697
|
+
console.log(chalk107.dim("\nDry run. Use --apply to execute."));
|
|
8523
8698
|
}
|
|
8524
8699
|
}
|
|
8525
8700
|
|
|
8526
8701
|
// src/commands/refactor/restructure/index.ts
|
|
8527
8702
|
import path45 from "path";
|
|
8528
|
-
import
|
|
8703
|
+
import chalk110 from "chalk";
|
|
8529
8704
|
|
|
8530
8705
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8531
8706
|
import path37 from "path";
|
|
@@ -8768,50 +8943,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8768
8943
|
|
|
8769
8944
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8770
8945
|
import path41 from "path";
|
|
8771
|
-
import
|
|
8946
|
+
import chalk108 from "chalk";
|
|
8772
8947
|
function relPath(filePath) {
|
|
8773
8948
|
return path41.relative(process.cwd(), filePath);
|
|
8774
8949
|
}
|
|
8775
8950
|
function displayMoves(plan2) {
|
|
8776
8951
|
if (plan2.moves.length === 0) return;
|
|
8777
|
-
console.log(
|
|
8952
|
+
console.log(chalk108.bold("\nFile moves:"));
|
|
8778
8953
|
for (const move of plan2.moves) {
|
|
8779
8954
|
console.log(
|
|
8780
|
-
` ${
|
|
8955
|
+
` ${chalk108.red(relPath(move.from))} \u2192 ${chalk108.green(relPath(move.to))}`
|
|
8781
8956
|
);
|
|
8782
|
-
console.log(
|
|
8957
|
+
console.log(chalk108.dim(` ${move.reason}`));
|
|
8783
8958
|
}
|
|
8784
8959
|
}
|
|
8785
8960
|
function displayRewrites(rewrites) {
|
|
8786
8961
|
if (rewrites.length === 0) return;
|
|
8787
8962
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8788
|
-
console.log(
|
|
8963
|
+
console.log(chalk108.bold(`
|
|
8789
8964
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8790
8965
|
for (const file of affectedFiles) {
|
|
8791
|
-
console.log(` ${
|
|
8966
|
+
console.log(` ${chalk108.cyan(relPath(file))}:`);
|
|
8792
8967
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8793
8968
|
(r) => r.file === file
|
|
8794
8969
|
)) {
|
|
8795
8970
|
console.log(
|
|
8796
|
-
` ${
|
|
8971
|
+
` ${chalk108.red(`"${oldSpecifier}"`)} \u2192 ${chalk108.green(`"${newSpecifier}"`)}`
|
|
8797
8972
|
);
|
|
8798
8973
|
}
|
|
8799
8974
|
}
|
|
8800
8975
|
}
|
|
8801
8976
|
function displayPlan2(plan2) {
|
|
8802
8977
|
if (plan2.warnings.length > 0) {
|
|
8803
|
-
console.log(
|
|
8804
|
-
for (const w of plan2.warnings) console.log(
|
|
8978
|
+
console.log(chalk108.yellow("\nWarnings:"));
|
|
8979
|
+
for (const w of plan2.warnings) console.log(chalk108.yellow(` ${w}`));
|
|
8805
8980
|
}
|
|
8806
8981
|
if (plan2.newDirectories.length > 0) {
|
|
8807
|
-
console.log(
|
|
8982
|
+
console.log(chalk108.bold("\nNew directories:"));
|
|
8808
8983
|
for (const dir of plan2.newDirectories)
|
|
8809
|
-
console.log(
|
|
8984
|
+
console.log(chalk108.green(` ${dir}/`));
|
|
8810
8985
|
}
|
|
8811
8986
|
displayMoves(plan2);
|
|
8812
8987
|
displayRewrites(plan2.rewrites);
|
|
8813
8988
|
console.log(
|
|
8814
|
-
|
|
8989
|
+
chalk108.dim(
|
|
8815
8990
|
`
|
|
8816
8991
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8817
8992
|
)
|
|
@@ -8821,18 +8996,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8821
8996
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8822
8997
|
import fs20 from "fs";
|
|
8823
8998
|
import path42 from "path";
|
|
8824
|
-
import
|
|
8999
|
+
import chalk109 from "chalk";
|
|
8825
9000
|
function executePlan(plan2) {
|
|
8826
9001
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8827
9002
|
for (const [file, content] of updatedContents) {
|
|
8828
9003
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8829
9004
|
console.log(
|
|
8830
|
-
|
|
9005
|
+
chalk109.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8831
9006
|
);
|
|
8832
9007
|
}
|
|
8833
9008
|
for (const dir of plan2.newDirectories) {
|
|
8834
9009
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8835
|
-
console.log(
|
|
9010
|
+
console.log(chalk109.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8836
9011
|
}
|
|
8837
9012
|
for (const move of plan2.moves) {
|
|
8838
9013
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8841,7 +9016,7 @@ function executePlan(plan2) {
|
|
|
8841
9016
|
}
|
|
8842
9017
|
fs20.renameSync(move.from, move.to);
|
|
8843
9018
|
console.log(
|
|
8844
|
-
|
|
9019
|
+
chalk109.white(
|
|
8845
9020
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8846
9021
|
)
|
|
8847
9022
|
);
|
|
@@ -8856,7 +9031,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8856
9031
|
if (entries.length === 0) {
|
|
8857
9032
|
fs20.rmdirSync(dir);
|
|
8858
9033
|
console.log(
|
|
8859
|
-
|
|
9034
|
+
chalk109.dim(
|
|
8860
9035
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8861
9036
|
)
|
|
8862
9037
|
);
|
|
@@ -8989,22 +9164,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8989
9164
|
const targetPattern = pattern2 ?? "src";
|
|
8990
9165
|
const files = findSourceFiles2(targetPattern);
|
|
8991
9166
|
if (files.length === 0) {
|
|
8992
|
-
console.log(
|
|
9167
|
+
console.log(chalk110.yellow("No files found matching pattern"));
|
|
8993
9168
|
return;
|
|
8994
9169
|
}
|
|
8995
9170
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8996
9171
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8997
9172
|
if (plan2.moves.length === 0) {
|
|
8998
|
-
console.log(
|
|
9173
|
+
console.log(chalk110.green("No restructuring needed"));
|
|
8999
9174
|
return;
|
|
9000
9175
|
}
|
|
9001
9176
|
displayPlan2(plan2);
|
|
9002
9177
|
if (options2.apply) {
|
|
9003
|
-
console.log(
|
|
9178
|
+
console.log(chalk110.bold("\nApplying changes..."));
|
|
9004
9179
|
executePlan(plan2);
|
|
9005
|
-
console.log(
|
|
9180
|
+
console.log(chalk110.green("\nRestructuring complete"));
|
|
9006
9181
|
} else {
|
|
9007
|
-
console.log(
|
|
9182
|
+
console.log(chalk110.dim("\nDry run. Use --apply to execute."));
|
|
9008
9183
|
}
|
|
9009
9184
|
}
|
|
9010
9185
|
|
|
@@ -9044,7 +9219,7 @@ function registerRefactor(program2) {
|
|
|
9044
9219
|
}
|
|
9045
9220
|
|
|
9046
9221
|
// src/commands/seq/seqAuth.ts
|
|
9047
|
-
import
|
|
9222
|
+
import chalk112 from "chalk";
|
|
9048
9223
|
|
|
9049
9224
|
// src/commands/seq/loadConnections.ts
|
|
9050
9225
|
function loadConnections2() {
|
|
@@ -9073,11 +9248,11 @@ function setDefaultConnection(name) {
|
|
|
9073
9248
|
}
|
|
9074
9249
|
|
|
9075
9250
|
// src/commands/seq/promptConnection.ts
|
|
9076
|
-
import
|
|
9251
|
+
import chalk111 from "chalk";
|
|
9077
9252
|
async function promptConnection2(existingNames) {
|
|
9078
9253
|
const name = await promptInput("name", "Connection name:", "default");
|
|
9079
9254
|
if (existingNames.includes(name)) {
|
|
9080
|
-
console.error(
|
|
9255
|
+
console.error(chalk111.red(`Connection "${name}" already exists.`));
|
|
9081
9256
|
process.exit(1);
|
|
9082
9257
|
}
|
|
9083
9258
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -9089,16 +9264,16 @@ async function promptConnection2(existingNames) {
|
|
|
9089
9264
|
var seqAuth = createConnectionAuth({
|
|
9090
9265
|
load: loadConnections2,
|
|
9091
9266
|
save: saveConnections2,
|
|
9092
|
-
format: (c) => `${
|
|
9267
|
+
format: (c) => `${chalk112.bold(c.name)} ${c.url}`,
|
|
9093
9268
|
promptNew: promptConnection2,
|
|
9094
9269
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
9095
9270
|
});
|
|
9096
9271
|
|
|
9097
9272
|
// src/commands/seq/seqQuery.ts
|
|
9098
|
-
import
|
|
9273
|
+
import chalk116 from "chalk";
|
|
9099
9274
|
|
|
9100
9275
|
// src/commands/seq/fetchSeq.ts
|
|
9101
|
-
import
|
|
9276
|
+
import chalk113 from "chalk";
|
|
9102
9277
|
async function fetchSeq(conn, path50, params) {
|
|
9103
9278
|
const url = `${conn.url}${path50}?${params}`;
|
|
9104
9279
|
const response = await fetch(url, {
|
|
@@ -9109,7 +9284,7 @@ async function fetchSeq(conn, path50, params) {
|
|
|
9109
9284
|
});
|
|
9110
9285
|
if (!response.ok) {
|
|
9111
9286
|
const body = await response.text();
|
|
9112
|
-
console.error(
|
|
9287
|
+
console.error(chalk113.red(`Seq returned ${response.status}: ${body}`));
|
|
9113
9288
|
process.exit(1);
|
|
9114
9289
|
}
|
|
9115
9290
|
return response;
|
|
@@ -9162,23 +9337,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
9162
9337
|
}
|
|
9163
9338
|
|
|
9164
9339
|
// src/commands/seq/formatEvent.ts
|
|
9165
|
-
import
|
|
9340
|
+
import chalk114 from "chalk";
|
|
9166
9341
|
function levelColor(level) {
|
|
9167
9342
|
switch (level) {
|
|
9168
9343
|
case "Fatal":
|
|
9169
|
-
return
|
|
9344
|
+
return chalk114.bgRed.white;
|
|
9170
9345
|
case "Error":
|
|
9171
|
-
return
|
|
9346
|
+
return chalk114.red;
|
|
9172
9347
|
case "Warning":
|
|
9173
|
-
return
|
|
9348
|
+
return chalk114.yellow;
|
|
9174
9349
|
case "Information":
|
|
9175
|
-
return
|
|
9350
|
+
return chalk114.cyan;
|
|
9176
9351
|
case "Debug":
|
|
9177
|
-
return
|
|
9352
|
+
return chalk114.gray;
|
|
9178
9353
|
case "Verbose":
|
|
9179
|
-
return
|
|
9354
|
+
return chalk114.dim;
|
|
9180
9355
|
default:
|
|
9181
|
-
return
|
|
9356
|
+
return chalk114.white;
|
|
9182
9357
|
}
|
|
9183
9358
|
}
|
|
9184
9359
|
function levelAbbrev(level) {
|
|
@@ -9219,31 +9394,31 @@ function formatTimestamp(iso) {
|
|
|
9219
9394
|
function formatEvent(event) {
|
|
9220
9395
|
const color = levelColor(event.Level);
|
|
9221
9396
|
const abbrev = levelAbbrev(event.Level);
|
|
9222
|
-
const ts8 =
|
|
9397
|
+
const ts8 = chalk114.dim(formatTimestamp(event.Timestamp));
|
|
9223
9398
|
const msg = renderMessage(event);
|
|
9224
9399
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
9225
9400
|
if (event.Exception) {
|
|
9226
9401
|
for (const line of event.Exception.split("\n")) {
|
|
9227
|
-
lines.push(
|
|
9402
|
+
lines.push(chalk114.red(` ${line}`));
|
|
9228
9403
|
}
|
|
9229
9404
|
}
|
|
9230
9405
|
return lines.join("\n");
|
|
9231
9406
|
}
|
|
9232
9407
|
|
|
9233
9408
|
// src/commands/seq/resolveConnection.ts
|
|
9234
|
-
import
|
|
9409
|
+
import chalk115 from "chalk";
|
|
9235
9410
|
function resolveConnection2(name) {
|
|
9236
9411
|
const connections = loadConnections2();
|
|
9237
9412
|
if (connections.length === 0) {
|
|
9238
9413
|
console.error(
|
|
9239
|
-
|
|
9414
|
+
chalk115.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
9240
9415
|
);
|
|
9241
9416
|
process.exit(1);
|
|
9242
9417
|
}
|
|
9243
9418
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
9244
9419
|
const connection = connections.find((c) => c.name === target);
|
|
9245
9420
|
if (!connection) {
|
|
9246
|
-
console.error(
|
|
9421
|
+
console.error(chalk115.red(`Seq connection "${target}" not found.`));
|
|
9247
9422
|
process.exit(1);
|
|
9248
9423
|
}
|
|
9249
9424
|
return connection;
|
|
@@ -9258,7 +9433,7 @@ async function seqQuery(filter, options2) {
|
|
|
9258
9433
|
new URLSearchParams({ filter, count: String(count) })
|
|
9259
9434
|
);
|
|
9260
9435
|
if (events.length === 0) {
|
|
9261
|
-
console.log(
|
|
9436
|
+
console.log(chalk116.yellow("No events found."));
|
|
9262
9437
|
return;
|
|
9263
9438
|
}
|
|
9264
9439
|
if (options2.json) {
|
|
@@ -9269,11 +9444,11 @@ async function seqQuery(filter, options2) {
|
|
|
9269
9444
|
for (const event of chronological) {
|
|
9270
9445
|
console.log(formatEvent(event));
|
|
9271
9446
|
}
|
|
9272
|
-
console.log(
|
|
9447
|
+
console.log(chalk116.dim(`
|
|
9273
9448
|
${events.length} events`));
|
|
9274
9449
|
if (events.length >= count) {
|
|
9275
9450
|
console.log(
|
|
9276
|
-
|
|
9451
|
+
chalk116.yellow(
|
|
9277
9452
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
9278
9453
|
)
|
|
9279
9454
|
);
|
|
@@ -9281,11 +9456,11 @@ ${events.length} events`));
|
|
|
9281
9456
|
}
|
|
9282
9457
|
|
|
9283
9458
|
// src/commands/seq/seqSetConnection.ts
|
|
9284
|
-
import
|
|
9459
|
+
import chalk117 from "chalk";
|
|
9285
9460
|
function seqSetConnection(name) {
|
|
9286
9461
|
const connections = loadConnections2();
|
|
9287
9462
|
if (!connections.find((c) => c.name === name)) {
|
|
9288
|
-
console.error(
|
|
9463
|
+
console.error(chalk117.red(`Connection "${name}" not found.`));
|
|
9289
9464
|
process.exit(1);
|
|
9290
9465
|
}
|
|
9291
9466
|
setDefaultConnection(name);
|
|
@@ -9824,14 +9999,14 @@ import {
|
|
|
9824
9999
|
import { dirname as dirname20, join as join30 } from "path";
|
|
9825
10000
|
|
|
9826
10001
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9827
|
-
import
|
|
10002
|
+
import chalk118 from "chalk";
|
|
9828
10003
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9829
10004
|
function validateStagedContent(filename, content) {
|
|
9830
10005
|
const firstLine = content.split("\n")[0];
|
|
9831
10006
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9832
10007
|
if (!match) {
|
|
9833
10008
|
console.error(
|
|
9834
|
-
|
|
10009
|
+
chalk118.red(
|
|
9835
10010
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9836
10011
|
)
|
|
9837
10012
|
);
|
|
@@ -9840,7 +10015,7 @@ function validateStagedContent(filename, content) {
|
|
|
9840
10015
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9841
10016
|
if (!contentAfterLink) {
|
|
9842
10017
|
console.error(
|
|
9843
|
-
|
|
10018
|
+
chalk118.red(
|
|
9844
10019
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9845
10020
|
)
|
|
9846
10021
|
);
|
|
@@ -10233,7 +10408,7 @@ function registerVoice(program2) {
|
|
|
10233
10408
|
|
|
10234
10409
|
// src/commands/roam/auth.ts
|
|
10235
10410
|
import { randomBytes } from "crypto";
|
|
10236
|
-
import
|
|
10411
|
+
import chalk119 from "chalk";
|
|
10237
10412
|
|
|
10238
10413
|
// src/lib/openBrowser.ts
|
|
10239
10414
|
import { execSync as execSync38 } from "child_process";
|
|
@@ -10408,13 +10583,13 @@ async function auth() {
|
|
|
10408
10583
|
saveGlobalConfig(config);
|
|
10409
10584
|
const state = randomBytes(16).toString("hex");
|
|
10410
10585
|
console.log(
|
|
10411
|
-
|
|
10586
|
+
chalk119.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
10412
10587
|
);
|
|
10413
|
-
console.log(
|
|
10414
|
-
console.log(
|
|
10415
|
-
console.log(
|
|
10588
|
+
console.log(chalk119.white("http://localhost:14523/callback\n"));
|
|
10589
|
+
console.log(chalk119.blue("Opening browser for authorization..."));
|
|
10590
|
+
console.log(chalk119.dim("Waiting for authorization callback..."));
|
|
10416
10591
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
10417
|
-
console.log(
|
|
10592
|
+
console.log(chalk119.dim("Exchanging code for tokens..."));
|
|
10418
10593
|
const tokens = await exchangeToken({
|
|
10419
10594
|
code,
|
|
10420
10595
|
clientId,
|
|
@@ -10430,7 +10605,7 @@ async function auth() {
|
|
|
10430
10605
|
};
|
|
10431
10606
|
saveGlobalConfig(config);
|
|
10432
10607
|
console.log(
|
|
10433
|
-
|
|
10608
|
+
chalk119.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
10434
10609
|
);
|
|
10435
10610
|
}
|
|
10436
10611
|
|
|
@@ -10643,7 +10818,7 @@ import { execSync as execSync40 } from "child_process";
|
|
|
10643
10818
|
import { existsSync as existsSync41, mkdirSync as mkdirSync13, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10644
10819
|
import { tmpdir as tmpdir6 } from "os";
|
|
10645
10820
|
import { join as join39, resolve as resolve5 } from "path";
|
|
10646
|
-
import
|
|
10821
|
+
import chalk120 from "chalk";
|
|
10647
10822
|
|
|
10648
10823
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10649
10824
|
var captureWindowPs1 = `
|
|
@@ -10794,22 +10969,22 @@ function screenshot(processName) {
|
|
|
10794
10969
|
const config = loadConfig();
|
|
10795
10970
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10796
10971
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10797
|
-
console.log(
|
|
10972
|
+
console.log(chalk120.gray(`Capturing window for process "${processName}" ...`));
|
|
10798
10973
|
try {
|
|
10799
10974
|
runPowerShellScript(processName, outputPath);
|
|
10800
|
-
console.log(
|
|
10975
|
+
console.log(chalk120.green(`Screenshot saved: ${outputPath}`));
|
|
10801
10976
|
} catch (error) {
|
|
10802
10977
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10803
|
-
console.error(
|
|
10978
|
+
console.error(chalk120.red(`Failed to capture screenshot: ${msg}`));
|
|
10804
10979
|
process.exit(1);
|
|
10805
10980
|
}
|
|
10806
10981
|
}
|
|
10807
10982
|
|
|
10808
10983
|
// src/commands/statusLine.ts
|
|
10809
|
-
import
|
|
10984
|
+
import chalk122 from "chalk";
|
|
10810
10985
|
|
|
10811
10986
|
// src/commands/buildLimitsSegment.ts
|
|
10812
|
-
import
|
|
10987
|
+
import chalk121 from "chalk";
|
|
10813
10988
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10814
10989
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10815
10990
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10832,10 +11007,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10832
11007
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10833
11008
|
const label2 = `${Math.round(pct)}%`;
|
|
10834
11009
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10835
|
-
if (projected == null) return
|
|
10836
|
-
if (projected > 100) return
|
|
10837
|
-
if (projected > 75) return
|
|
10838
|
-
return
|
|
11010
|
+
if (projected == null) return chalk121.green(label2);
|
|
11011
|
+
if (projected > 100) return chalk121.red(label2);
|
|
11012
|
+
if (projected > 75) return chalk121.yellow(label2);
|
|
11013
|
+
return chalk121.green(label2);
|
|
10839
11014
|
}
|
|
10840
11015
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10841
11016
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10861,14 +11036,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10861
11036
|
}
|
|
10862
11037
|
|
|
10863
11038
|
// src/commands/statusLine.ts
|
|
10864
|
-
|
|
11039
|
+
chalk122.level = 3;
|
|
10865
11040
|
function formatNumber(num) {
|
|
10866
11041
|
return num.toLocaleString("en-US");
|
|
10867
11042
|
}
|
|
10868
11043
|
function colorizePercent(pct) {
|
|
10869
11044
|
const label2 = `${Math.round(pct)}%`;
|
|
10870
|
-
if (pct > 80) return
|
|
10871
|
-
if (pct > 40) return
|
|
11045
|
+
if (pct > 80) return chalk122.red(label2);
|
|
11046
|
+
if (pct > 40) return chalk122.yellow(label2);
|
|
10872
11047
|
return label2;
|
|
10873
11048
|
}
|
|
10874
11049
|
async function statusLine() {
|
|
@@ -10891,7 +11066,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10891
11066
|
// src/commands/sync/syncClaudeMd.ts
|
|
10892
11067
|
import * as fs23 from "fs";
|
|
10893
11068
|
import * as path46 from "path";
|
|
10894
|
-
import
|
|
11069
|
+
import chalk123 from "chalk";
|
|
10895
11070
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10896
11071
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10897
11072
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10900,12 +11075,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10900
11075
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10901
11076
|
if (sourceContent !== targetContent) {
|
|
10902
11077
|
console.log(
|
|
10903
|
-
|
|
11078
|
+
chalk123.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10904
11079
|
);
|
|
10905
11080
|
console.log();
|
|
10906
11081
|
printDiff(targetContent, sourceContent);
|
|
10907
11082
|
const confirm = options2?.yes || await promptConfirm(
|
|
10908
|
-
|
|
11083
|
+
chalk123.red("Overwrite existing CLAUDE.md?"),
|
|
10909
11084
|
false
|
|
10910
11085
|
);
|
|
10911
11086
|
if (!confirm) {
|
|
@@ -10921,7 +11096,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10921
11096
|
// src/commands/sync/syncSettings.ts
|
|
10922
11097
|
import * as fs24 from "fs";
|
|
10923
11098
|
import * as path47 from "path";
|
|
10924
|
-
import
|
|
11099
|
+
import chalk124 from "chalk";
|
|
10925
11100
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10926
11101
|
const source = path47.join(claudeDir, "settings.json");
|
|
10927
11102
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10937,14 +11112,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10937
11112
|
if (mergedContent !== normalizedTarget) {
|
|
10938
11113
|
if (!options2?.yes) {
|
|
10939
11114
|
console.log(
|
|
10940
|
-
|
|
11115
|
+
chalk124.yellow(
|
|
10941
11116
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10942
11117
|
)
|
|
10943
11118
|
);
|
|
10944
11119
|
console.log();
|
|
10945
11120
|
printDiff(targetContent, mergedContent);
|
|
10946
11121
|
const confirm = await promptConfirm(
|
|
10947
|
-
|
|
11122
|
+
chalk124.red("Overwrite existing settings.json?"),
|
|
10948
11123
|
false
|
|
10949
11124
|
);
|
|
10950
11125
|
if (!confirm) {
|