@staff0rd/assist 0.159.0 → 0.161.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/dist/index.js +462 -419
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.161.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -337,6 +337,18 @@ function printVerboseDetails(item) {
|
|
|
337
337
|
// src/commands/backlog/run.ts
|
|
338
338
|
import chalk8 from "chalk";
|
|
339
339
|
|
|
340
|
+
// src/commands/backlog/buildCommentLines.ts
|
|
341
|
+
function buildCommentLines(comments2) {
|
|
342
|
+
if (!comments2?.length) return [];
|
|
343
|
+
return ["", "Comments:", ...comments2.map(formatPromptComment)];
|
|
344
|
+
}
|
|
345
|
+
function formatPromptComment(entry) {
|
|
346
|
+
const tag = entry.type === "summary" ? "[summary]" : "[comment]";
|
|
347
|
+
const phase = entry.phase !== void 0 ? ` (phase ${entry.phase + 1})` : "";
|
|
348
|
+
return `${tag}${phase} ${entry.timestamp}
|
|
349
|
+
${entry.text}`;
|
|
350
|
+
}
|
|
351
|
+
|
|
340
352
|
// src/commands/backlog/buildAuthoredPhasePrompt.ts
|
|
341
353
|
function buildAuthoredPhasePrompt(item, phaseIndex, phase) {
|
|
342
354
|
const manualChecks = phase.manualChecks ?? [];
|
|
@@ -349,7 +361,6 @@ function buildAuthoredPhasePrompt(item, phaseIndex, phase) {
|
|
|
349
361
|
"When you have completed all tasks for this phase, run /verify to check your work.",
|
|
350
362
|
...buildManualCheckLines(manualChecks),
|
|
351
363
|
"",
|
|
352
|
-
`You can run \`assist backlog comments ${item.id}\` to read prior phase notes and comments.`,
|
|
353
364
|
`Post concise comments for any notable findings or changes using \`assist backlog comment ${item.id} "<text>"\`.`,
|
|
354
365
|
"",
|
|
355
366
|
`Once verify passes${confirmSuffix}, run: assist backlog phase-done ${item.id} ${phaseIndex} "<summary>"`,
|
|
@@ -365,6 +376,7 @@ function buildContextLines(item, phaseIndex, phase) {
|
|
|
365
376
|
"",
|
|
366
377
|
"Acceptance criteria:",
|
|
367
378
|
ac,
|
|
379
|
+
...buildCommentLines(item.comments),
|
|
368
380
|
"",
|
|
369
381
|
`Phase ${phaseIndex + 1}: ${phase.name}`,
|
|
370
382
|
"Tasks:",
|
|
@@ -403,10 +415,10 @@ function buildReviewPrompt(item, phaseIndex) {
|
|
|
403
415
|
"For each criterion, inspect the code and report PASS or FAIL with a brief explanation:",
|
|
404
416
|
"",
|
|
405
417
|
acLines,
|
|
418
|
+
...buildCommentLines(item.comments),
|
|
406
419
|
"",
|
|
407
420
|
"If any criterion fails, fix the issue and re-verify before proceeding.",
|
|
408
421
|
"",
|
|
409
|
-
`You can run \`assist backlog comments ${item.id}\` to read prior phase notes and comments.`,
|
|
410
422
|
`Post concise comments for any notable findings or changes using \`assist backlog comment ${item.id} "<text>"\`.`,
|
|
411
423
|
"",
|
|
412
424
|
"After all criteria pass, ask the user to confirm any manual checks",
|
|
@@ -1178,6 +1190,9 @@ var assistConfigSchema = z2.strictObject({
|
|
|
1178
1190
|
screenshot: z2.strictObject({
|
|
1179
1191
|
outputDir: z2.string().default("./screenshots")
|
|
1180
1192
|
}).default({ outputDir: "./screenshots" }),
|
|
1193
|
+
sync: z2.strictObject({
|
|
1194
|
+
autoConfirm: z2.boolean().default(false)
|
|
1195
|
+
}).default({ autoConfirm: false }),
|
|
1181
1196
|
voice: z2.strictObject({
|
|
1182
1197
|
wakeWords: z2.array(z2.string()).default(DEFAULT_WAKE_WORDS),
|
|
1183
1198
|
mic: z2.string().optional(),
|
|
@@ -1349,19 +1364,6 @@ function commit(args) {
|
|
|
1349
1364
|
import chalk18 from "chalk";
|
|
1350
1365
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
1351
1366
|
|
|
1352
|
-
// src/commands/config/getNestedValue.ts
|
|
1353
|
-
function isTraversable(value) {
|
|
1354
|
-
return value !== null && value !== void 0 && typeof value === "object";
|
|
1355
|
-
}
|
|
1356
|
-
function stepInto(current, key) {
|
|
1357
|
-
return isTraversable(current) ? current[key] : void 0;
|
|
1358
|
-
}
|
|
1359
|
-
function getNestedValue(obj, path50) {
|
|
1360
|
-
let current = obj;
|
|
1361
|
-
for (const key of path50.split(".")) current = stepInto(current, key);
|
|
1362
|
-
return current;
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
1367
|
// src/commands/config/setNestedValue.ts
|
|
1366
1368
|
function isPlainObject(val) {
|
|
1367
1369
|
return val !== null && typeof val === "object" && !Array.isArray(val);
|
|
@@ -1435,27 +1437,58 @@ function validateConfig(updated, key) {
|
|
|
1435
1437
|
if (!result.success) return exitValidationFailed(result.error.issues, key);
|
|
1436
1438
|
return updated;
|
|
1437
1439
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1440
|
+
var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
1441
|
+
function assertNotGlobalOnly(key, global) {
|
|
1442
|
+
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
1443
|
+
console.error(
|
|
1444
|
+
chalk18.red(
|
|
1445
|
+
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
1446
|
+
)
|
|
1447
|
+
);
|
|
1448
|
+
process.exit(1);
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
function applyConfigSet(key, coerced, global) {
|
|
1452
|
+
assertNotGlobalOnly(key, global);
|
|
1453
|
+
const raw = global ? loadGlobalConfigRaw() : loadProjectConfig();
|
|
1454
|
+
const updated = setNestedValue(raw, key, coerced);
|
|
1455
|
+
validateConfig(updated, key);
|
|
1456
|
+
if (global) {
|
|
1457
|
+
saveGlobalConfig(updated);
|
|
1458
|
+
} else {
|
|
1459
|
+
saveConfig(updated);
|
|
1460
|
+
}
|
|
1441
1461
|
}
|
|
1442
|
-
function configSet(key, value) {
|
|
1462
|
+
function configSet(key, value, options2 = {}) {
|
|
1443
1463
|
const coerced = coerceValue(value);
|
|
1444
|
-
applyConfigSet(key, coerced);
|
|
1445
|
-
|
|
1464
|
+
applyConfigSet(key, coerced, options2.global ?? false);
|
|
1465
|
+
const target = options2.global ? "global" : "project";
|
|
1466
|
+
console.log(
|
|
1467
|
+
chalk18.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
1468
|
+
);
|
|
1446
1469
|
}
|
|
1447
|
-
function
|
|
1448
|
-
|
|
1470
|
+
function configList() {
|
|
1471
|
+
const config = loadConfig();
|
|
1472
|
+
console.log(stringifyYaml3(config, { lineWidth: 0 }).trimEnd());
|
|
1449
1473
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1474
|
+
|
|
1475
|
+
// src/commands/config/configGet.ts
|
|
1476
|
+
import chalk19 from "chalk";
|
|
1477
|
+
|
|
1478
|
+
// src/commands/config/getNestedValue.ts
|
|
1479
|
+
function isTraversable(value) {
|
|
1480
|
+
return value !== null && value !== void 0 && typeof value === "object";
|
|
1453
1481
|
}
|
|
1454
|
-
function
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1482
|
+
function stepInto(current, key) {
|
|
1483
|
+
return isTraversable(current) ? current[key] : void 0;
|
|
1484
|
+
}
|
|
1485
|
+
function getNestedValue(obj, path50) {
|
|
1486
|
+
let current = obj;
|
|
1487
|
+
for (const key of path50.split(".")) current = stepInto(current, key);
|
|
1488
|
+
return current;
|
|
1458
1489
|
}
|
|
1490
|
+
|
|
1491
|
+
// src/commands/config/configGet.ts
|
|
1459
1492
|
function configGet(key) {
|
|
1460
1493
|
console.log(
|
|
1461
1494
|
formatOutput(
|
|
@@ -1463,9 +1496,17 @@ function configGet(key) {
|
|
|
1463
1496
|
)
|
|
1464
1497
|
);
|
|
1465
1498
|
}
|
|
1466
|
-
function
|
|
1467
|
-
|
|
1468
|
-
|
|
1499
|
+
function formatOutput(value) {
|
|
1500
|
+
return typeof value === "object" && value !== null ? JSON.stringify(value, null, 2) : String(value);
|
|
1501
|
+
}
|
|
1502
|
+
function requireNestedValue(config, key) {
|
|
1503
|
+
const value = getNestedValue(config, key);
|
|
1504
|
+
if (value === void 0) return exitKeyNotSet(key);
|
|
1505
|
+
return value;
|
|
1506
|
+
}
|
|
1507
|
+
function exitKeyNotSet(key) {
|
|
1508
|
+
console.error(chalk19.red(`Key "${key}" is not set`));
|
|
1509
|
+
process.exit(1);
|
|
1469
1510
|
}
|
|
1470
1511
|
|
|
1471
1512
|
// src/commands/coverage.ts
|
|
@@ -1484,10 +1525,10 @@ function coverage() {
|
|
|
1484
1525
|
}
|
|
1485
1526
|
|
|
1486
1527
|
// src/commands/verify/init/index.ts
|
|
1487
|
-
import
|
|
1528
|
+
import chalk34 from "chalk";
|
|
1488
1529
|
|
|
1489
1530
|
// src/shared/promptMultiselect.ts
|
|
1490
|
-
import
|
|
1531
|
+
import chalk20 from "chalk";
|
|
1491
1532
|
import enquirer3 from "enquirer";
|
|
1492
1533
|
async function promptMultiselect(message, options2) {
|
|
1493
1534
|
const { selected } = await exitOnCancel(
|
|
@@ -1497,7 +1538,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1497
1538
|
message,
|
|
1498
1539
|
choices: options2.map((opt) => ({
|
|
1499
1540
|
name: opt.value,
|
|
1500
|
-
message: `${opt.name} - ${
|
|
1541
|
+
message: `${opt.name} - ${chalk20.dim(opt.description)}`
|
|
1501
1542
|
})),
|
|
1502
1543
|
// @ts-expect-error - enquirer types don't include symbols but it's supported
|
|
1503
1544
|
symbols: {
|
|
@@ -1514,7 +1555,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1514
1555
|
// src/shared/readPackageJson.ts
|
|
1515
1556
|
import * as fs from "fs";
|
|
1516
1557
|
import * as path from "path";
|
|
1517
|
-
import
|
|
1558
|
+
import chalk21 from "chalk";
|
|
1518
1559
|
function findPackageJson() {
|
|
1519
1560
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1520
1561
|
if (fs.existsSync(packageJsonPath)) {
|
|
@@ -1528,7 +1569,7 @@ function readPackageJson(filePath) {
|
|
|
1528
1569
|
function requirePackageJson() {
|
|
1529
1570
|
const packageJsonPath = findPackageJson();
|
|
1530
1571
|
if (!packageJsonPath) {
|
|
1531
|
-
console.error(
|
|
1572
|
+
console.error(chalk21.red("No package.json found in current directory"));
|
|
1532
1573
|
process.exit(1);
|
|
1533
1574
|
}
|
|
1534
1575
|
const pkg = readPackageJson(packageJsonPath);
|
|
@@ -1559,7 +1600,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1559
1600
|
// src/commands/verify/installPackage.ts
|
|
1560
1601
|
import { execSync as execSync3 } from "child_process";
|
|
1561
1602
|
import { writeFileSync as writeFileSync5 } from "fs";
|
|
1562
|
-
import
|
|
1603
|
+
import chalk22 from "chalk";
|
|
1563
1604
|
function writePackageJson(filePath, pkg) {
|
|
1564
1605
|
writeFileSync5(filePath, `${JSON.stringify(pkg, null, 2)}
|
|
1565
1606
|
`);
|
|
@@ -1574,12 +1615,12 @@ function addScript(pkg, name, command) {
|
|
|
1574
1615
|
};
|
|
1575
1616
|
}
|
|
1576
1617
|
function installPackage(name, cwd) {
|
|
1577
|
-
console.log(
|
|
1618
|
+
console.log(chalk22.dim(`Installing ${name}...`));
|
|
1578
1619
|
try {
|
|
1579
1620
|
execSync3(`npm install -D ${name}`, { stdio: "inherit", cwd });
|
|
1580
1621
|
return true;
|
|
1581
1622
|
} catch {
|
|
1582
|
-
console.error(
|
|
1623
|
+
console.error(chalk22.red(`Failed to install ${name}`));
|
|
1583
1624
|
return false;
|
|
1584
1625
|
}
|
|
1585
1626
|
}
|
|
@@ -1626,9 +1667,9 @@ var expectedScripts = {
|
|
|
1626
1667
|
};
|
|
1627
1668
|
|
|
1628
1669
|
// src/commands/verify/setup/setupBuild.ts
|
|
1629
|
-
import
|
|
1670
|
+
import chalk23 from "chalk";
|
|
1630
1671
|
async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
1631
|
-
console.log(
|
|
1672
|
+
console.log(chalk23.blue("\nSetting up build verification..."));
|
|
1632
1673
|
let command;
|
|
1633
1674
|
if (hasVite && hasTypescript) {
|
|
1634
1675
|
command = "tsc -b && vite build --logLevel error";
|
|
@@ -1637,21 +1678,21 @@ async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
|
1637
1678
|
} else {
|
|
1638
1679
|
command = "npm run build";
|
|
1639
1680
|
}
|
|
1640
|
-
console.log(
|
|
1681
|
+
console.log(chalk23.dim(`Using: ${command}`));
|
|
1641
1682
|
writer("verify:build", command);
|
|
1642
1683
|
}
|
|
1643
1684
|
async function setupTypecheck(_packageJsonPath, writer) {
|
|
1644
|
-
console.log(
|
|
1685
|
+
console.log(chalk23.blue("\nSetting up typecheck verification..."));
|
|
1645
1686
|
const command = "tsc --noEmit";
|
|
1646
|
-
console.log(
|
|
1687
|
+
console.log(chalk23.dim(`Using: ${command}`));
|
|
1647
1688
|
writer("verify:typecheck", command);
|
|
1648
1689
|
}
|
|
1649
1690
|
|
|
1650
1691
|
// src/commands/verify/setup/setupDuplicateCode.ts
|
|
1651
1692
|
import * as path2 from "path";
|
|
1652
|
-
import
|
|
1693
|
+
import chalk24 from "chalk";
|
|
1653
1694
|
async function setupDuplicateCode(packageJsonPath, writer) {
|
|
1654
|
-
console.log(
|
|
1695
|
+
console.log(chalk24.blue("\nSetting up jscpd..."));
|
|
1655
1696
|
const cwd = path2.dirname(packageJsonPath);
|
|
1656
1697
|
const pkg = readPackageJson(packageJsonPath);
|
|
1657
1698
|
const hasJscpd = !!pkg.dependencies?.jscpd || !!pkg.devDependencies?.jscpd;
|
|
@@ -1663,12 +1704,12 @@ async function setupDuplicateCode(packageJsonPath, writer) {
|
|
|
1663
1704
|
|
|
1664
1705
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1665
1706
|
import * as path3 from "path";
|
|
1666
|
-
import
|
|
1707
|
+
import chalk26 from "chalk";
|
|
1667
1708
|
|
|
1668
1709
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
1669
1710
|
import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
1670
1711
|
import { join as join7 } from "path";
|
|
1671
|
-
import
|
|
1712
|
+
import chalk25 from "chalk";
|
|
1672
1713
|
function loadKnipConfig(knipJsonPath) {
|
|
1673
1714
|
if (existsSync9(knipJsonPath)) {
|
|
1674
1715
|
return JSON.parse(readFileSync8(knipJsonPath, "utf-8"));
|
|
@@ -1687,16 +1728,16 @@ function addToKnipIgnoreBinaries(cwd, binary) {
|
|
|
1687
1728
|
`${JSON.stringify(knipConfig, null, " ")}
|
|
1688
1729
|
`
|
|
1689
1730
|
);
|
|
1690
|
-
console.log(
|
|
1731
|
+
console.log(chalk25.dim(`Added '${binary}' to knip.json ignoreBinaries`));
|
|
1691
1732
|
}
|
|
1692
1733
|
} catch {
|
|
1693
|
-
console.log(
|
|
1734
|
+
console.log(chalk25.yellow("Warning: Could not update knip.json"));
|
|
1694
1735
|
}
|
|
1695
1736
|
}
|
|
1696
1737
|
|
|
1697
1738
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1698
1739
|
async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
1699
|
-
console.log(
|
|
1740
|
+
console.log(chalk26.blue("\nSetting up hardcoded colors check..."));
|
|
1700
1741
|
const cwd = path3.dirname(packageJsonPath);
|
|
1701
1742
|
if (!hasOpenColor) {
|
|
1702
1743
|
installPackage("open-color", cwd);
|
|
@@ -1707,9 +1748,9 @@ async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
|
1707
1748
|
|
|
1708
1749
|
// src/commands/verify/setup/setupKnip.ts
|
|
1709
1750
|
import * as path4 from "path";
|
|
1710
|
-
import
|
|
1751
|
+
import chalk27 from "chalk";
|
|
1711
1752
|
async function setupKnip(packageJsonPath, writer) {
|
|
1712
|
-
console.log(
|
|
1753
|
+
console.log(chalk27.blue("\nSetting up knip..."));
|
|
1713
1754
|
const cwd = path4.dirname(packageJsonPath);
|
|
1714
1755
|
const pkg = readPackageJson(packageJsonPath);
|
|
1715
1756
|
if (!pkg.devDependencies?.knip && !installPackage("knip", cwd)) {
|
|
@@ -1720,14 +1761,14 @@ async function setupKnip(packageJsonPath, writer) {
|
|
|
1720
1761
|
|
|
1721
1762
|
// src/commands/verify/setup/setupLint.ts
|
|
1722
1763
|
import * as path5 from "path";
|
|
1723
|
-
import
|
|
1764
|
+
import chalk30 from "chalk";
|
|
1724
1765
|
|
|
1725
1766
|
// src/commands/lint/init.ts
|
|
1726
1767
|
import { execSync as execSync5 } from "child_process";
|
|
1727
1768
|
import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
1728
1769
|
import { dirname as dirname7, join as join8 } from "path";
|
|
1729
1770
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1730
|
-
import
|
|
1771
|
+
import chalk29 from "chalk";
|
|
1731
1772
|
|
|
1732
1773
|
// src/shared/promptConfirm.ts
|
|
1733
1774
|
import enquirer4 from "enquirer";
|
|
@@ -1831,7 +1872,7 @@ function removeEslintScripts(scripts, options2) {
|
|
|
1831
1872
|
}
|
|
1832
1873
|
|
|
1833
1874
|
// src/utils/printDiff.ts
|
|
1834
|
-
import
|
|
1875
|
+
import chalk28 from "chalk";
|
|
1835
1876
|
import * as diff from "diff";
|
|
1836
1877
|
function normalizeJson(content) {
|
|
1837
1878
|
try {
|
|
@@ -1849,11 +1890,11 @@ function printDiff(oldContent, newContent) {
|
|
|
1849
1890
|
const lines = change.value.replace(/\n$/, "").split("\n");
|
|
1850
1891
|
for (const line of lines) {
|
|
1851
1892
|
if (change.added) {
|
|
1852
|
-
console.log(
|
|
1893
|
+
console.log(chalk28.green(`+ ${line}`));
|
|
1853
1894
|
} else if (change.removed) {
|
|
1854
|
-
console.log(
|
|
1895
|
+
console.log(chalk28.red(`- ${line}`));
|
|
1855
1896
|
} else {
|
|
1856
|
-
console.log(
|
|
1897
|
+
console.log(chalk28.dim(` ${line}`));
|
|
1857
1898
|
}
|
|
1858
1899
|
}
|
|
1859
1900
|
}
|
|
@@ -1887,10 +1928,10 @@ async function init() {
|
|
|
1887
1928
|
console.log("biome.json already has the correct linter config");
|
|
1888
1929
|
return;
|
|
1889
1930
|
}
|
|
1890
|
-
console.log(
|
|
1931
|
+
console.log(chalk29.yellow("\n\u26A0\uFE0F biome.json will be updated:"));
|
|
1891
1932
|
console.log();
|
|
1892
1933
|
printDiff(oldContent, newContent);
|
|
1893
|
-
const confirm = await promptConfirm(
|
|
1934
|
+
const confirm = await promptConfirm(chalk29.red("Update biome.json?"));
|
|
1894
1935
|
if (!confirm) {
|
|
1895
1936
|
console.log("Skipped biome.json update");
|
|
1896
1937
|
return;
|
|
@@ -1901,7 +1942,7 @@ async function init() {
|
|
|
1901
1942
|
|
|
1902
1943
|
// src/commands/verify/setup/setupLint.ts
|
|
1903
1944
|
async function setupLint(packageJsonPath, writer) {
|
|
1904
|
-
console.log(
|
|
1945
|
+
console.log(chalk30.blue("\nSetting up biome..."));
|
|
1905
1946
|
const cwd = path5.dirname(packageJsonPath);
|
|
1906
1947
|
const pkg = readPackageJson(packageJsonPath);
|
|
1907
1948
|
if (!pkg.devDependencies?.["@biomejs/biome"]) {
|
|
@@ -1915,9 +1956,9 @@ async function setupLint(packageJsonPath, writer) {
|
|
|
1915
1956
|
|
|
1916
1957
|
// src/commands/verify/setup/setupMadge.ts
|
|
1917
1958
|
import * as path6 from "path";
|
|
1918
|
-
import
|
|
1959
|
+
import chalk31 from "chalk";
|
|
1919
1960
|
async function setupMadge(packageJsonPath, writer) {
|
|
1920
|
-
console.log(
|
|
1961
|
+
console.log(chalk31.blue("\nSetting up madge..."));
|
|
1921
1962
|
const cwd = path6.dirname(packageJsonPath);
|
|
1922
1963
|
const pkg = readPackageJson(packageJsonPath);
|
|
1923
1964
|
const hasMadge = !!pkg.dependencies?.madge || !!pkg.devDependencies?.madge;
|
|
@@ -1929,18 +1970,18 @@ async function setupMadge(packageJsonPath, writer) {
|
|
|
1929
1970
|
|
|
1930
1971
|
// src/commands/verify/setup/setupMaintainability.ts
|
|
1931
1972
|
import * as path7 from "path";
|
|
1932
|
-
import
|
|
1973
|
+
import chalk32 from "chalk";
|
|
1933
1974
|
async function setupMaintainability(packageJsonPath, writer) {
|
|
1934
|
-
console.log(
|
|
1975
|
+
console.log(chalk32.blue("\nSetting up maintainability check..."));
|
|
1935
1976
|
addToKnipIgnoreBinaries(path7.dirname(packageJsonPath), "assist");
|
|
1936
1977
|
writer("verify:maintainability", expectedScripts["verify:maintainability"]);
|
|
1937
1978
|
}
|
|
1938
1979
|
|
|
1939
1980
|
// src/commands/verify/setup/setupTest.ts
|
|
1940
1981
|
import * as path8 from "path";
|
|
1941
|
-
import
|
|
1982
|
+
import chalk33 from "chalk";
|
|
1942
1983
|
async function setupTest(packageJsonPath, writer) {
|
|
1943
|
-
console.log(
|
|
1984
|
+
console.log(chalk33.blue("\nSetting up vitest..."));
|
|
1944
1985
|
const cwd = path8.dirname(packageJsonPath);
|
|
1945
1986
|
const pkg = readPackageJson(packageJsonPath);
|
|
1946
1987
|
if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
|
|
@@ -2109,25 +2150,25 @@ async function runSelectedSetups(selected, packageJsonPath, writer, handlers) {
|
|
|
2109
2150
|
for (const choice of selected) {
|
|
2110
2151
|
await handlers[choice]?.(packageJsonPath, writer);
|
|
2111
2152
|
}
|
|
2112
|
-
console.log(
|
|
2153
|
+
console.log(chalk34.green(`
|
|
2113
2154
|
Added ${selected.length} verify script(s):`));
|
|
2114
2155
|
for (const choice of selected) {
|
|
2115
|
-
console.log(
|
|
2156
|
+
console.log(chalk34.green(` - verify:${choice}`));
|
|
2116
2157
|
}
|
|
2117
|
-
console.log(
|
|
2158
|
+
console.log(chalk34.dim("\nRun 'assist verify' to run all verify scripts"));
|
|
2118
2159
|
}
|
|
2119
2160
|
async function promptForScripts(availableOptions) {
|
|
2120
2161
|
if (availableOptions.length === 0) {
|
|
2121
|
-
console.log(
|
|
2162
|
+
console.log(chalk34.green("All verify scripts are already configured!"));
|
|
2122
2163
|
return null;
|
|
2123
2164
|
}
|
|
2124
|
-
console.log(
|
|
2165
|
+
console.log(chalk34.bold("Available verify scripts to add:\n"));
|
|
2125
2166
|
const selected = await promptMultiselect(
|
|
2126
2167
|
"Select verify scripts to add:",
|
|
2127
2168
|
availableOptions
|
|
2128
2169
|
);
|
|
2129
2170
|
if (selected.length === 0) {
|
|
2130
|
-
console.log(
|
|
2171
|
+
console.log(chalk34.yellow("No scripts selected"));
|
|
2131
2172
|
return null;
|
|
2132
2173
|
}
|
|
2133
2174
|
return selected;
|
|
@@ -2147,17 +2188,17 @@ async function init2() {
|
|
|
2147
2188
|
}
|
|
2148
2189
|
|
|
2149
2190
|
// src/commands/vscode/init/index.ts
|
|
2150
|
-
import
|
|
2191
|
+
import chalk36 from "chalk";
|
|
2151
2192
|
|
|
2152
2193
|
// src/commands/vscode/init/createLaunchJson.ts
|
|
2153
2194
|
import * as fs2 from "fs";
|
|
2154
2195
|
import * as path9 from "path";
|
|
2155
|
-
import
|
|
2196
|
+
import chalk35 from "chalk";
|
|
2156
2197
|
function ensureVscodeFolder() {
|
|
2157
2198
|
const vscodeDir = path9.join(process.cwd(), ".vscode");
|
|
2158
2199
|
if (!fs2.existsSync(vscodeDir)) {
|
|
2159
2200
|
fs2.mkdirSync(vscodeDir);
|
|
2160
|
-
console.log(
|
|
2201
|
+
console.log(chalk35.dim("Created .vscode folder"));
|
|
2161
2202
|
}
|
|
2162
2203
|
}
|
|
2163
2204
|
function removeVscodeFromGitignore() {
|
|
@@ -2172,7 +2213,7 @@ function removeVscodeFromGitignore() {
|
|
|
2172
2213
|
);
|
|
2173
2214
|
if (filteredLines.length !== lines.length) {
|
|
2174
2215
|
fs2.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
2175
|
-
console.log(
|
|
2216
|
+
console.log(chalk35.dim("Removed .vscode references from .gitignore"));
|
|
2176
2217
|
}
|
|
2177
2218
|
}
|
|
2178
2219
|
function createLaunchJson(type) {
|
|
@@ -2191,7 +2232,7 @@ function createLaunchJson(type) {
|
|
|
2191
2232
|
const launchPath = path9.join(process.cwd(), ".vscode", "launch.json");
|
|
2192
2233
|
fs2.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
|
|
2193
2234
|
`);
|
|
2194
|
-
console.log(
|
|
2235
|
+
console.log(chalk35.green("Created .vscode/launch.json"));
|
|
2195
2236
|
}
|
|
2196
2237
|
function createSettingsJson() {
|
|
2197
2238
|
const settings = {
|
|
@@ -2204,7 +2245,7 @@ function createSettingsJson() {
|
|
|
2204
2245
|
const settingsPath = path9.join(process.cwd(), ".vscode", "settings.json");
|
|
2205
2246
|
fs2.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
|
|
2206
2247
|
`);
|
|
2207
|
-
console.log(
|
|
2248
|
+
console.log(chalk35.green("Created .vscode/settings.json"));
|
|
2208
2249
|
}
|
|
2209
2250
|
function createExtensionsJson() {
|
|
2210
2251
|
const extensions = {
|
|
@@ -2216,7 +2257,7 @@ function createExtensionsJson() {
|
|
|
2216
2257
|
`${JSON.stringify(extensions, null, " ")}
|
|
2217
2258
|
`
|
|
2218
2259
|
);
|
|
2219
|
-
console.log(
|
|
2260
|
+
console.log(chalk35.green("Created .vscode/extensions.json"));
|
|
2220
2261
|
}
|
|
2221
2262
|
|
|
2222
2263
|
// src/commands/vscode/init/detectVscodeSetup.ts
|
|
@@ -2273,7 +2314,7 @@ function applySelections(selected, setup2) {
|
|
|
2273
2314
|
for (const choice of selected) handlers[choice]?.();
|
|
2274
2315
|
}
|
|
2275
2316
|
async function promptForOptions(options2) {
|
|
2276
|
-
console.log(
|
|
2317
|
+
console.log(chalk36.bold("Available VS Code configurations to add:\n"));
|
|
2277
2318
|
return promptMultiselect("Select configurations to add:", options2);
|
|
2278
2319
|
}
|
|
2279
2320
|
async function init3({ all = false } = {}) {
|
|
@@ -2281,17 +2322,17 @@ async function init3({ all = false } = {}) {
|
|
|
2281
2322
|
const setup2 = detectVscodeSetup(pkg);
|
|
2282
2323
|
const options2 = getAvailableOptions2(setup2);
|
|
2283
2324
|
if (options2.length === 0) {
|
|
2284
|
-
console.log(
|
|
2325
|
+
console.log(chalk36.green("VS Code configuration already exists!"));
|
|
2285
2326
|
return;
|
|
2286
2327
|
}
|
|
2287
2328
|
const selected = all ? options2.map((o) => o.value) : await promptForOptions(options2);
|
|
2288
2329
|
if (selected.length === 0) {
|
|
2289
|
-
console.log(
|
|
2330
|
+
console.log(chalk36.yellow("No configurations selected"));
|
|
2290
2331
|
return;
|
|
2291
2332
|
}
|
|
2292
2333
|
applySelections(selected, setup2);
|
|
2293
2334
|
console.log(
|
|
2294
|
-
|
|
2335
|
+
chalk36.green(`
|
|
2295
2336
|
Added ${selected.length} VS Code configuration(s)`)
|
|
2296
2337
|
);
|
|
2297
2338
|
}
|
|
@@ -2304,7 +2345,7 @@ async function init4() {
|
|
|
2304
2345
|
|
|
2305
2346
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2306
2347
|
import path16 from "path";
|
|
2307
|
-
import
|
|
2348
|
+
import chalk38 from "chalk";
|
|
2308
2349
|
|
|
2309
2350
|
// src/commands/lint/lint/checkFileNames.ts
|
|
2310
2351
|
import fs5 from "fs";
|
|
@@ -2384,7 +2425,7 @@ function checkFileNames() {
|
|
|
2384
2425
|
}
|
|
2385
2426
|
|
|
2386
2427
|
// src/commands/lint/lint/fixFileNameViolations.ts
|
|
2387
|
-
import
|
|
2428
|
+
import chalk37 from "chalk";
|
|
2388
2429
|
|
|
2389
2430
|
// src/commands/lint/lint/applyMoves.ts
|
|
2390
2431
|
import fs6 from "fs";
|
|
@@ -2469,25 +2510,25 @@ function fixFileNameViolations(moves) {
|
|
|
2469
2510
|
const start3 = performance.now();
|
|
2470
2511
|
const project = createLintProject();
|
|
2471
2512
|
const cwd = process.cwd();
|
|
2472
|
-
applyMoves(project, moves, cwd, (line) => console.log(
|
|
2513
|
+
applyMoves(project, moves, cwd, (line) => console.log(chalk37.green(line)));
|
|
2473
2514
|
const ms = (performance.now() - start3).toFixed(0);
|
|
2474
|
-
console.log(
|
|
2515
|
+
console.log(chalk37.dim(` Done in ${ms}ms`));
|
|
2475
2516
|
}
|
|
2476
2517
|
|
|
2477
2518
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2478
2519
|
function reportViolations(violations) {
|
|
2479
|
-
console.error(
|
|
2520
|
+
console.error(chalk38.red("\nFile name check failed:\n"));
|
|
2480
2521
|
console.error(
|
|
2481
|
-
|
|
2522
|
+
chalk38.red(
|
|
2482
2523
|
" Files without classes or React components should not start with a capital letter.\n"
|
|
2483
2524
|
)
|
|
2484
2525
|
);
|
|
2485
2526
|
for (const violation of violations) {
|
|
2486
|
-
console.error(
|
|
2487
|
-
console.error(
|
|
2527
|
+
console.error(chalk38.red(` ${violation.filePath}`));
|
|
2528
|
+
console.error(chalk38.gray(` Rename to: ${violation.suggestedName}
|
|
2488
2529
|
`));
|
|
2489
2530
|
}
|
|
2490
|
-
console.error(
|
|
2531
|
+
console.error(chalk38.dim(" Run with -f to auto-fix.\n"));
|
|
2491
2532
|
}
|
|
2492
2533
|
function runFileNameCheck(fix = false) {
|
|
2493
2534
|
const violations = checkFileNames();
|
|
@@ -2516,17 +2557,17 @@ function runFileNameCheck(fix = false) {
|
|
|
2516
2557
|
import fs8 from "fs";
|
|
2517
2558
|
|
|
2518
2559
|
// src/commands/lint/shared.ts
|
|
2519
|
-
import
|
|
2560
|
+
import chalk39 from "chalk";
|
|
2520
2561
|
function reportViolations2(violations, checkName, errorMessage, successMessage) {
|
|
2521
2562
|
if (violations.length > 0) {
|
|
2522
|
-
console.error(
|
|
2563
|
+
console.error(chalk39.red(`
|
|
2523
2564
|
${checkName} failed:
|
|
2524
2565
|
`));
|
|
2525
|
-
console.error(
|
|
2566
|
+
console.error(chalk39.red(` ${errorMessage}
|
|
2526
2567
|
`));
|
|
2527
2568
|
for (const violation of violations) {
|
|
2528
|
-
console.error(
|
|
2529
|
-
console.error(
|
|
2569
|
+
console.error(chalk39.red(` ${violation.filePath}:${violation.line}`));
|
|
2570
|
+
console.error(chalk39.gray(` ${violation.content}
|
|
2530
2571
|
`));
|
|
2531
2572
|
}
|
|
2532
2573
|
return false;
|
|
@@ -3006,14 +3047,14 @@ import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSy
|
|
|
3006
3047
|
|
|
3007
3048
|
// src/commands/deploy/init/index.ts
|
|
3008
3049
|
import { execSync as execSync12 } from "child_process";
|
|
3009
|
-
import
|
|
3050
|
+
import chalk41 from "chalk";
|
|
3010
3051
|
import enquirer5 from "enquirer";
|
|
3011
3052
|
|
|
3012
3053
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
3013
3054
|
import { existsSync as existsSync15, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
3014
3055
|
import { dirname as dirname13, join as join11 } from "path";
|
|
3015
3056
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3016
|
-
import
|
|
3057
|
+
import chalk40 from "chalk";
|
|
3017
3058
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
3018
3059
|
var __dirname3 = dirname13(fileURLToPath3(import.meta.url));
|
|
3019
3060
|
function getExistingSiteId() {
|
|
@@ -3038,20 +3079,20 @@ async function updateWorkflow(siteId) {
|
|
|
3038
3079
|
if (existsSync15(WORKFLOW_PATH)) {
|
|
3039
3080
|
const oldContent = readFileSync12(WORKFLOW_PATH, "utf-8");
|
|
3040
3081
|
if (oldContent === newContent) {
|
|
3041
|
-
console.log(
|
|
3082
|
+
console.log(chalk40.green("build.yml is already up to date"));
|
|
3042
3083
|
return;
|
|
3043
3084
|
}
|
|
3044
|
-
console.log(
|
|
3085
|
+
console.log(chalk40.yellow("\nbuild.yml will be updated:"));
|
|
3045
3086
|
console.log();
|
|
3046
3087
|
printDiff(oldContent, newContent);
|
|
3047
|
-
const confirm = await promptConfirm(
|
|
3088
|
+
const confirm = await promptConfirm(chalk40.red("Update build.yml?"));
|
|
3048
3089
|
if (!confirm) {
|
|
3049
3090
|
console.log("Skipped build.yml update");
|
|
3050
3091
|
return;
|
|
3051
3092
|
}
|
|
3052
3093
|
}
|
|
3053
3094
|
writeFileSync12(WORKFLOW_PATH, newContent);
|
|
3054
|
-
console.log(
|
|
3095
|
+
console.log(chalk40.green(`
|
|
3055
3096
|
Created ${WORKFLOW_PATH}`));
|
|
3056
3097
|
}
|
|
3057
3098
|
|
|
@@ -3062,43 +3103,43 @@ async function ensureNetlifyCli() {
|
|
|
3062
3103
|
} catch (error) {
|
|
3063
3104
|
if (!(error instanceof Error) || !error.message.includes("command not found"))
|
|
3064
3105
|
throw error;
|
|
3065
|
-
console.error(
|
|
3106
|
+
console.error(chalk41.red("\nNetlify CLI is not installed.\n"));
|
|
3066
3107
|
const install = await promptConfirm("Would you like to install it now?");
|
|
3067
3108
|
if (!install) {
|
|
3068
3109
|
console.log(
|
|
3069
|
-
|
|
3110
|
+
chalk41.yellow(
|
|
3070
3111
|
"\nInstall it manually with: npm install -g netlify-cli\n"
|
|
3071
3112
|
)
|
|
3072
3113
|
);
|
|
3073
3114
|
process.exit(1);
|
|
3074
3115
|
}
|
|
3075
|
-
console.log(
|
|
3116
|
+
console.log(chalk41.dim("\nInstalling netlify-cli...\n"));
|
|
3076
3117
|
execSync12("npm install -g netlify-cli", { stdio: "inherit" });
|
|
3077
3118
|
console.log();
|
|
3078
3119
|
execSync12("netlify sites:create --disable-linking", { stdio: "inherit" });
|
|
3079
3120
|
}
|
|
3080
3121
|
}
|
|
3081
3122
|
function printSetupInstructions() {
|
|
3082
|
-
console.log(
|
|
3123
|
+
console.log(chalk41.bold("\nDeployment initialized successfully!"));
|
|
3083
3124
|
console.log(
|
|
3084
|
-
|
|
3125
|
+
chalk41.yellow("\nTo complete setup, create a personal access token at:")
|
|
3085
3126
|
);
|
|
3086
3127
|
console.log(
|
|
3087
|
-
|
|
3128
|
+
chalk41.cyan(
|
|
3088
3129
|
"https://app.netlify.com/user/applications#personal-access-tokens"
|
|
3089
3130
|
)
|
|
3090
3131
|
);
|
|
3091
3132
|
console.log(
|
|
3092
|
-
|
|
3133
|
+
chalk41.yellow(
|
|
3093
3134
|
"\nThen add it as NETLIFY_AUTH_TOKEN in your GitHub repository secrets."
|
|
3094
3135
|
)
|
|
3095
3136
|
);
|
|
3096
3137
|
}
|
|
3097
3138
|
async function init5() {
|
|
3098
|
-
console.log(
|
|
3139
|
+
console.log(chalk41.bold("Initializing Netlify deployment...\n"));
|
|
3099
3140
|
const existingSiteId = getExistingSiteId();
|
|
3100
3141
|
if (existingSiteId) {
|
|
3101
|
-
console.log(
|
|
3142
|
+
console.log(chalk41.dim(`Using existing site ID: ${existingSiteId}
|
|
3102
3143
|
`));
|
|
3103
3144
|
await updateWorkflow(existingSiteId);
|
|
3104
3145
|
return;
|
|
@@ -3277,27 +3318,27 @@ async function notify() {
|
|
|
3277
3318
|
}
|
|
3278
3319
|
|
|
3279
3320
|
// src/commands/backlog/comment/index.ts
|
|
3280
|
-
import
|
|
3321
|
+
import chalk42 from "chalk";
|
|
3281
3322
|
function comment(id, text) {
|
|
3282
3323
|
const result = loadAndFindItem(id);
|
|
3283
3324
|
if (!result) process.exit(1);
|
|
3284
3325
|
addComment(result.item, text);
|
|
3285
3326
|
saveBacklog(result.items);
|
|
3286
|
-
console.log(
|
|
3327
|
+
console.log(chalk42.green(`Comment added to item #${id}.`));
|
|
3287
3328
|
}
|
|
3288
3329
|
|
|
3289
3330
|
// src/commands/backlog/comments/index.ts
|
|
3290
|
-
import
|
|
3331
|
+
import chalk43 from "chalk";
|
|
3291
3332
|
function comments(id) {
|
|
3292
3333
|
const result = loadAndFindItem(id);
|
|
3293
3334
|
if (!result) process.exit(1);
|
|
3294
3335
|
const { item } = result;
|
|
3295
3336
|
const entries = item.comments ?? [];
|
|
3296
3337
|
if (entries.length === 0) {
|
|
3297
|
-
console.log(
|
|
3338
|
+
console.log(chalk43.dim(`No comments on item #${id}.`));
|
|
3298
3339
|
return;
|
|
3299
3340
|
}
|
|
3300
|
-
console.log(
|
|
3341
|
+
console.log(chalk43.bold(`Comments for #${id}: ${item.name}
|
|
3301
3342
|
`));
|
|
3302
3343
|
for (const entry of entries) {
|
|
3303
3344
|
console.log(`${formatComment(entry)}
|
|
@@ -3313,11 +3354,11 @@ function registerCommentCommands(cmd) {
|
|
|
3313
3354
|
|
|
3314
3355
|
// src/commands/backlog/add/index.ts
|
|
3315
3356
|
import { existsSync as existsSync17 } from "fs";
|
|
3316
|
-
import
|
|
3357
|
+
import chalk45 from "chalk";
|
|
3317
3358
|
|
|
3318
3359
|
// src/commands/backlog/commitBacklog.ts
|
|
3319
3360
|
import { execSync as execSync14 } from "child_process";
|
|
3320
|
-
import
|
|
3361
|
+
import chalk44 from "chalk";
|
|
3321
3362
|
function commitBacklog(id, name) {
|
|
3322
3363
|
try {
|
|
3323
3364
|
const backlogPath = getBacklogPath();
|
|
@@ -3325,7 +3366,7 @@ function commitBacklog(id, name) {
|
|
|
3325
3366
|
execSync14(`git add ${shellQuote(backlogPath)}`, { stdio: "ignore" });
|
|
3326
3367
|
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3327
3368
|
} catch {
|
|
3328
|
-
console.log(
|
|
3369
|
+
console.log(chalk44.yellow("Warning: could not auto-commit backlog file."));
|
|
3329
3370
|
}
|
|
3330
3371
|
}
|
|
3331
3372
|
|
|
@@ -3403,7 +3444,7 @@ async function promptAcceptanceCriteria() {
|
|
|
3403
3444
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3404
3445
|
async function addFromJson() {
|
|
3405
3446
|
if (process.stdin.isTTY) {
|
|
3406
|
-
console.log(
|
|
3447
|
+
console.log(chalk45.red("--json requires piped input on stdin."));
|
|
3407
3448
|
return;
|
|
3408
3449
|
}
|
|
3409
3450
|
const input = await readStdin();
|
|
@@ -3417,7 +3458,7 @@ async function addFromJson() {
|
|
|
3417
3458
|
items.push({ ...data, id, status: "todo" });
|
|
3418
3459
|
saveBacklog(items);
|
|
3419
3460
|
commitBacklog(id, data.name);
|
|
3420
|
-
console.log(
|
|
3461
|
+
console.log(chalk45.green(`Added item #${id}: ${data.name}`));
|
|
3421
3462
|
}
|
|
3422
3463
|
async function addInteractive() {
|
|
3423
3464
|
const type = await promptType();
|
|
@@ -3436,12 +3477,12 @@ async function addInteractive() {
|
|
|
3436
3477
|
});
|
|
3437
3478
|
saveBacklog(items);
|
|
3438
3479
|
commitBacklog(id, name);
|
|
3439
|
-
console.log(
|
|
3480
|
+
console.log(chalk45.green(`Added item #${id}: ${name}`));
|
|
3440
3481
|
}
|
|
3441
3482
|
async function add(options2) {
|
|
3442
3483
|
if (!existsSync17(getBacklogPath())) {
|
|
3443
3484
|
console.log(
|
|
3444
|
-
|
|
3485
|
+
chalk45.yellow(
|
|
3445
3486
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3446
3487
|
)
|
|
3447
3488
|
);
|
|
@@ -3456,20 +3497,20 @@ async function add(options2) {
|
|
|
3456
3497
|
|
|
3457
3498
|
// src/commands/backlog/init/index.ts
|
|
3458
3499
|
import { existsSync as existsSync18 } from "fs";
|
|
3459
|
-
import
|
|
3500
|
+
import chalk46 from "chalk";
|
|
3460
3501
|
async function init6() {
|
|
3461
3502
|
const backlogPath = getBacklogPath();
|
|
3462
3503
|
if (existsSync18(backlogPath)) {
|
|
3463
|
-
console.log(
|
|
3504
|
+
console.log(chalk46.yellow("assist.backlog.yml already exists."));
|
|
3464
3505
|
return;
|
|
3465
3506
|
}
|
|
3466
3507
|
saveBacklog([]);
|
|
3467
|
-
console.log(
|
|
3508
|
+
console.log(chalk46.green("Created assist.backlog.yml"));
|
|
3468
3509
|
}
|
|
3469
3510
|
|
|
3470
3511
|
// src/commands/backlog/list/index.ts
|
|
3471
3512
|
import { existsSync as existsSync19 } from "fs";
|
|
3472
|
-
import
|
|
3513
|
+
import chalk47 from "chalk";
|
|
3473
3514
|
function filterItems(items, options2) {
|
|
3474
3515
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3475
3516
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
@@ -3478,7 +3519,7 @@ function filterItems(items, options2) {
|
|
|
3478
3519
|
async function list2(options2) {
|
|
3479
3520
|
if (!existsSync19(getBacklogPath())) {
|
|
3480
3521
|
console.log(
|
|
3481
|
-
|
|
3522
|
+
chalk47.yellow(
|
|
3482
3523
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3483
3524
|
)
|
|
3484
3525
|
);
|
|
@@ -3486,12 +3527,12 @@ async function list2(options2) {
|
|
|
3486
3527
|
}
|
|
3487
3528
|
const items = filterItems(loadBacklog(), options2);
|
|
3488
3529
|
if (items.length === 0) {
|
|
3489
|
-
console.log(
|
|
3530
|
+
console.log(chalk47.dim("Backlog is empty."));
|
|
3490
3531
|
return;
|
|
3491
3532
|
}
|
|
3492
3533
|
for (const item of items) {
|
|
3493
3534
|
console.log(
|
|
3494
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3535
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk47.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
|
|
3495
3536
|
);
|
|
3496
3537
|
if (options2.verbose) {
|
|
3497
3538
|
printVerboseDetails(item);
|
|
@@ -3930,11 +3971,11 @@ function assertCliExists(cli) {
|
|
|
3930
3971
|
}
|
|
3931
3972
|
|
|
3932
3973
|
// src/commands/permitCliReads/colorize.ts
|
|
3933
|
-
import
|
|
3974
|
+
import chalk48 from "chalk";
|
|
3934
3975
|
function colorize(plainOutput) {
|
|
3935
3976
|
return plainOutput.split("\n").map((line) => {
|
|
3936
|
-
if (line.startsWith(" R ")) return
|
|
3937
|
-
if (line.startsWith(" W ")) return
|
|
3977
|
+
if (line.startsWith(" R ")) return chalk48.green(line);
|
|
3978
|
+
if (line.startsWith(" W ")) return chalk48.red(line);
|
|
3938
3979
|
return line;
|
|
3939
3980
|
}).join("\n");
|
|
3940
3981
|
}
|
|
@@ -4248,15 +4289,15 @@ function registerCliHook(program2) {
|
|
|
4248
4289
|
}
|
|
4249
4290
|
|
|
4250
4291
|
// src/commands/complexity/analyze.ts
|
|
4251
|
-
import
|
|
4292
|
+
import chalk54 from "chalk";
|
|
4252
4293
|
|
|
4253
4294
|
// src/commands/complexity/cyclomatic.ts
|
|
4254
|
-
import
|
|
4295
|
+
import chalk50 from "chalk";
|
|
4255
4296
|
|
|
4256
4297
|
// src/commands/complexity/shared/index.ts
|
|
4257
4298
|
import fs12 from "fs";
|
|
4258
4299
|
import path20 from "path";
|
|
4259
|
-
import
|
|
4300
|
+
import chalk49 from "chalk";
|
|
4260
4301
|
import ts5 from "typescript";
|
|
4261
4302
|
|
|
4262
4303
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4502,7 +4543,7 @@ function createSourceFromFile(filePath) {
|
|
|
4502
4543
|
function withSourceFiles(pattern2, callback) {
|
|
4503
4544
|
const files = findSourceFiles2(pattern2);
|
|
4504
4545
|
if (files.length === 0) {
|
|
4505
|
-
console.log(
|
|
4546
|
+
console.log(chalk49.yellow("No files found matching pattern"));
|
|
4506
4547
|
return void 0;
|
|
4507
4548
|
}
|
|
4508
4549
|
return callback(files);
|
|
@@ -4535,11 +4576,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4535
4576
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4536
4577
|
for (const { file, name, complexity } of results) {
|
|
4537
4578
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4538
|
-
const color = exceedsThreshold ?
|
|
4539
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4579
|
+
const color = exceedsThreshold ? chalk50.red : chalk50.white;
|
|
4580
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk50.cyan(complexity)}`);
|
|
4540
4581
|
}
|
|
4541
4582
|
console.log(
|
|
4542
|
-
|
|
4583
|
+
chalk50.dim(
|
|
4543
4584
|
`
|
|
4544
4585
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4545
4586
|
)
|
|
@@ -4551,7 +4592,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4551
4592
|
}
|
|
4552
4593
|
|
|
4553
4594
|
// src/commands/complexity/halstead.ts
|
|
4554
|
-
import
|
|
4595
|
+
import chalk51 from "chalk";
|
|
4555
4596
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4556
4597
|
withSourceFiles(pattern2, (files) => {
|
|
4557
4598
|
const results = [];
|
|
@@ -4566,13 +4607,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4566
4607
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4567
4608
|
for (const { file, name, metrics } of results) {
|
|
4568
4609
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4569
|
-
const color = exceedsThreshold ?
|
|
4610
|
+
const color = exceedsThreshold ? chalk51.red : chalk51.white;
|
|
4570
4611
|
console.log(
|
|
4571
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4612
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk51.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk51.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk51.magenta(metrics.effort.toFixed(1))}`
|
|
4572
4613
|
);
|
|
4573
4614
|
}
|
|
4574
4615
|
console.log(
|
|
4575
|
-
|
|
4616
|
+
chalk51.dim(
|
|
4576
4617
|
`
|
|
4577
4618
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4578
4619
|
)
|
|
@@ -4587,28 +4628,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4587
4628
|
import fs13 from "fs";
|
|
4588
4629
|
|
|
4589
4630
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4590
|
-
import
|
|
4631
|
+
import chalk52 from "chalk";
|
|
4591
4632
|
function displayMaintainabilityResults(results, threshold) {
|
|
4592
4633
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4593
4634
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4594
|
-
console.log(
|
|
4635
|
+
console.log(chalk52.green("All files pass maintainability threshold"));
|
|
4595
4636
|
} else {
|
|
4596
4637
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4597
|
-
const color = threshold !== void 0 ?
|
|
4638
|
+
const color = threshold !== void 0 ? chalk52.red : chalk52.white;
|
|
4598
4639
|
console.log(
|
|
4599
|
-
`${color(file)} \u2192 avg: ${
|
|
4640
|
+
`${color(file)} \u2192 avg: ${chalk52.cyan(avgMaintainability.toFixed(1))}, min: ${chalk52.yellow(minMaintainability.toFixed(1))}`
|
|
4600
4641
|
);
|
|
4601
4642
|
}
|
|
4602
4643
|
}
|
|
4603
|
-
console.log(
|
|
4644
|
+
console.log(chalk52.dim(`
|
|
4604
4645
|
Analyzed ${results.length} files`));
|
|
4605
4646
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4606
4647
|
console.error(
|
|
4607
|
-
|
|
4648
|
+
chalk52.red(
|
|
4608
4649
|
`
|
|
4609
4650
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4610
4651
|
|
|
4611
|
-
\u26A0\uFE0F ${
|
|
4652
|
+
\u26A0\uFE0F ${chalk52.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.`
|
|
4612
4653
|
)
|
|
4613
4654
|
);
|
|
4614
4655
|
process.exit(1);
|
|
@@ -4665,7 +4706,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4665
4706
|
|
|
4666
4707
|
// src/commands/complexity/sloc.ts
|
|
4667
4708
|
import fs14 from "fs";
|
|
4668
|
-
import
|
|
4709
|
+
import chalk53 from "chalk";
|
|
4669
4710
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4670
4711
|
withSourceFiles(pattern2, (files) => {
|
|
4671
4712
|
const results = [];
|
|
@@ -4681,12 +4722,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4681
4722
|
results.sort((a, b) => b.lines - a.lines);
|
|
4682
4723
|
for (const { file, lines } of results) {
|
|
4683
4724
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4684
|
-
const color = exceedsThreshold ?
|
|
4685
|
-
console.log(`${color(file)} \u2192 ${
|
|
4725
|
+
const color = exceedsThreshold ? chalk53.red : chalk53.white;
|
|
4726
|
+
console.log(`${color(file)} \u2192 ${chalk53.cyan(lines)} lines`);
|
|
4686
4727
|
}
|
|
4687
4728
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4688
4729
|
console.log(
|
|
4689
|
-
|
|
4730
|
+
chalk53.dim(`
|
|
4690
4731
|
Total: ${total} lines across ${files.length} files`)
|
|
4691
4732
|
);
|
|
4692
4733
|
if (hasViolation) {
|
|
@@ -4700,21 +4741,21 @@ async function analyze(pattern2) {
|
|
|
4700
4741
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4701
4742
|
const files = findSourceFiles2(searchPattern);
|
|
4702
4743
|
if (files.length === 0) {
|
|
4703
|
-
console.log(
|
|
4744
|
+
console.log(chalk54.yellow("No files found matching pattern"));
|
|
4704
4745
|
return;
|
|
4705
4746
|
}
|
|
4706
4747
|
if (files.length === 1) {
|
|
4707
4748
|
const file = files[0];
|
|
4708
|
-
console.log(
|
|
4749
|
+
console.log(chalk54.bold.underline("SLOC"));
|
|
4709
4750
|
await sloc(file);
|
|
4710
4751
|
console.log();
|
|
4711
|
-
console.log(
|
|
4752
|
+
console.log(chalk54.bold.underline("Cyclomatic Complexity"));
|
|
4712
4753
|
await cyclomatic(file);
|
|
4713
4754
|
console.log();
|
|
4714
|
-
console.log(
|
|
4755
|
+
console.log(chalk54.bold.underline("Halstead Metrics"));
|
|
4715
4756
|
await halstead(file);
|
|
4716
4757
|
console.log();
|
|
4717
|
-
console.log(
|
|
4758
|
+
console.log(chalk54.bold.underline("Maintainability Index"));
|
|
4718
4759
|
await maintainability(file);
|
|
4719
4760
|
return;
|
|
4720
4761
|
}
|
|
@@ -4742,7 +4783,7 @@ function registerComplexity(program2) {
|
|
|
4742
4783
|
|
|
4743
4784
|
// src/commands/deploy/redirect.ts
|
|
4744
4785
|
import { existsSync as existsSync23, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
4745
|
-
import
|
|
4786
|
+
import chalk55 from "chalk";
|
|
4746
4787
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4747
4788
|
if (!window.location.pathname.endsWith('/')) {
|
|
4748
4789
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4751,22 +4792,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4751
4792
|
function redirect() {
|
|
4752
4793
|
const indexPath = "index.html";
|
|
4753
4794
|
if (!existsSync23(indexPath)) {
|
|
4754
|
-
console.log(
|
|
4795
|
+
console.log(chalk55.yellow("No index.html found"));
|
|
4755
4796
|
return;
|
|
4756
4797
|
}
|
|
4757
4798
|
const content = readFileSync18(indexPath, "utf-8");
|
|
4758
4799
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4759
|
-
console.log(
|
|
4800
|
+
console.log(chalk55.dim("Trailing slash script already present"));
|
|
4760
4801
|
return;
|
|
4761
4802
|
}
|
|
4762
4803
|
const headCloseIndex = content.indexOf("</head>");
|
|
4763
4804
|
if (headCloseIndex === -1) {
|
|
4764
|
-
console.log(
|
|
4805
|
+
console.log(chalk55.red("Could not find </head> tag in index.html"));
|
|
4765
4806
|
return;
|
|
4766
4807
|
}
|
|
4767
4808
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4768
4809
|
writeFileSync17(indexPath, newContent);
|
|
4769
|
-
console.log(
|
|
4810
|
+
console.log(chalk55.green("Added trailing slash redirect to index.html"));
|
|
4770
4811
|
}
|
|
4771
4812
|
|
|
4772
4813
|
// src/commands/registerDeploy.ts
|
|
@@ -4793,7 +4834,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
4793
4834
|
|
|
4794
4835
|
// src/commands/devlog/shared.ts
|
|
4795
4836
|
import { execSync as execSync17 } from "child_process";
|
|
4796
|
-
import
|
|
4837
|
+
import chalk56 from "chalk";
|
|
4797
4838
|
|
|
4798
4839
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4799
4840
|
import { readdirSync, readFileSync as readFileSync19 } from "fs";
|
|
@@ -4880,13 +4921,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4880
4921
|
}
|
|
4881
4922
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4882
4923
|
for (const commit2 of commits) {
|
|
4883
|
-
console.log(` ${
|
|
4924
|
+
console.log(` ${chalk56.yellow(commit2.hash)} ${commit2.message}`);
|
|
4884
4925
|
if (verbose) {
|
|
4885
4926
|
const visibleFiles = commit2.files.filter(
|
|
4886
4927
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4887
4928
|
);
|
|
4888
4929
|
for (const file of visibleFiles) {
|
|
4889
|
-
console.log(` ${
|
|
4930
|
+
console.log(` ${chalk56.dim(file)}`);
|
|
4890
4931
|
}
|
|
4891
4932
|
}
|
|
4892
4933
|
}
|
|
@@ -4911,15 +4952,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4911
4952
|
}
|
|
4912
4953
|
|
|
4913
4954
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4914
|
-
import
|
|
4955
|
+
import chalk57 from "chalk";
|
|
4915
4956
|
function printDateHeader(date, isSkipped, entries) {
|
|
4916
4957
|
if (isSkipped) {
|
|
4917
|
-
console.log(`${
|
|
4958
|
+
console.log(`${chalk57.bold.blue(date)} ${chalk57.dim("skipped")}`);
|
|
4918
4959
|
} else if (entries && entries.length > 0) {
|
|
4919
|
-
const entryInfo = entries.map((e) => `${
|
|
4920
|
-
console.log(`${
|
|
4960
|
+
const entryInfo = entries.map((e) => `${chalk57.green(e.version)} ${e.title}`).join(" | ");
|
|
4961
|
+
console.log(`${chalk57.bold.blue(date)} ${entryInfo}`);
|
|
4921
4962
|
} else {
|
|
4922
|
-
console.log(`${
|
|
4963
|
+
console.log(`${chalk57.bold.blue(date)} ${chalk57.red("\u26A0 devlog missing")}`);
|
|
4923
4964
|
}
|
|
4924
4965
|
}
|
|
4925
4966
|
|
|
@@ -5022,24 +5063,24 @@ function bumpVersion(version2, type) {
|
|
|
5022
5063
|
|
|
5023
5064
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
5024
5065
|
import { execSync as execSync20 } from "child_process";
|
|
5025
|
-
import
|
|
5066
|
+
import chalk59 from "chalk";
|
|
5026
5067
|
|
|
5027
5068
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
5028
|
-
import
|
|
5069
|
+
import chalk58 from "chalk";
|
|
5029
5070
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
5030
5071
|
if (conventional && firstHash) {
|
|
5031
5072
|
const version2 = getVersionAtCommit(firstHash);
|
|
5032
5073
|
if (version2) {
|
|
5033
|
-
console.log(`${
|
|
5074
|
+
console.log(`${chalk58.bold("version:")} ${stripToMinor(version2)}`);
|
|
5034
5075
|
} else {
|
|
5035
|
-
console.log(`${
|
|
5076
|
+
console.log(`${chalk58.bold("version:")} ${chalk58.red("unknown")}`);
|
|
5036
5077
|
}
|
|
5037
5078
|
} else if (patchVersion && minorVersion) {
|
|
5038
5079
|
console.log(
|
|
5039
|
-
`${
|
|
5080
|
+
`${chalk58.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
5040
5081
|
);
|
|
5041
5082
|
} else {
|
|
5042
|
-
console.log(`${
|
|
5083
|
+
console.log(`${chalk58.bold("version:")} v0.1 (initial)`);
|
|
5043
5084
|
}
|
|
5044
5085
|
}
|
|
5045
5086
|
|
|
@@ -5086,16 +5127,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
5086
5127
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
5087
5128
|
}
|
|
5088
5129
|
function logName(repoName) {
|
|
5089
|
-
console.log(`${
|
|
5130
|
+
console.log(`${chalk59.bold("name:")} ${repoName}`);
|
|
5090
5131
|
}
|
|
5091
5132
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
5092
5133
|
logName(ctx.repoName);
|
|
5093
5134
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
5094
|
-
console.log(
|
|
5135
|
+
console.log(chalk59.bold.blue(targetDate));
|
|
5095
5136
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
5096
5137
|
}
|
|
5097
5138
|
function logNoCommits(lastInfo) {
|
|
5098
|
-
console.log(
|
|
5139
|
+
console.log(chalk59.dim(noCommitsMessage(!!lastInfo)));
|
|
5099
5140
|
}
|
|
5100
5141
|
|
|
5101
5142
|
// src/commands/devlog/next/index.ts
|
|
@@ -5136,11 +5177,11 @@ function next2(options2) {
|
|
|
5136
5177
|
import { execSync as execSync21 } from "child_process";
|
|
5137
5178
|
|
|
5138
5179
|
// src/commands/devlog/repos/printReposTable.ts
|
|
5139
|
-
import
|
|
5180
|
+
import chalk60 from "chalk";
|
|
5140
5181
|
function colorStatus(status2) {
|
|
5141
|
-
if (status2 === "missing") return
|
|
5142
|
-
if (status2 === "outdated") return
|
|
5143
|
-
return
|
|
5182
|
+
if (status2 === "missing") return chalk60.red(status2);
|
|
5183
|
+
if (status2 === "outdated") return chalk60.yellow(status2);
|
|
5184
|
+
return chalk60.green(status2);
|
|
5144
5185
|
}
|
|
5145
5186
|
function formatRow(row, nameWidth) {
|
|
5146
5187
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -5154,8 +5195,8 @@ function printReposTable(rows) {
|
|
|
5154
5195
|
"Last Devlog".padEnd(11),
|
|
5155
5196
|
"Status"
|
|
5156
5197
|
].join(" ");
|
|
5157
|
-
console.log(
|
|
5158
|
-
console.log(
|
|
5198
|
+
console.log(chalk60.dim(header));
|
|
5199
|
+
console.log(chalk60.dim("-".repeat(header.length)));
|
|
5159
5200
|
for (const row of rows) {
|
|
5160
5201
|
console.log(formatRow(row, nameWidth));
|
|
5161
5202
|
}
|
|
@@ -5213,14 +5254,14 @@ function repos(options2) {
|
|
|
5213
5254
|
// src/commands/devlog/skip.ts
|
|
5214
5255
|
import { writeFileSync as writeFileSync18 } from "fs";
|
|
5215
5256
|
import { join as join17 } from "path";
|
|
5216
|
-
import
|
|
5257
|
+
import chalk61 from "chalk";
|
|
5217
5258
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
5218
5259
|
function getBlogConfigPath() {
|
|
5219
5260
|
return join17(BLOG_REPO_ROOT, "assist.yml");
|
|
5220
5261
|
}
|
|
5221
5262
|
function skip(date) {
|
|
5222
5263
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5223
|
-
console.log(
|
|
5264
|
+
console.log(chalk61.red("Invalid date format. Use YYYY-MM-DD"));
|
|
5224
5265
|
process.exit(1);
|
|
5225
5266
|
}
|
|
5226
5267
|
const repoName = getRepoName();
|
|
@@ -5231,7 +5272,7 @@ function skip(date) {
|
|
|
5231
5272
|
const skipDays = skip2[repoName] ?? [];
|
|
5232
5273
|
if (skipDays.includes(date)) {
|
|
5233
5274
|
console.log(
|
|
5234
|
-
|
|
5275
|
+
chalk61.yellow(`${date} is already in skip list for ${repoName}`)
|
|
5235
5276
|
);
|
|
5236
5277
|
return;
|
|
5237
5278
|
}
|
|
@@ -5241,20 +5282,20 @@ function skip(date) {
|
|
|
5241
5282
|
devlog.skip = skip2;
|
|
5242
5283
|
config.devlog = devlog;
|
|
5243
5284
|
writeFileSync18(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
5244
|
-
console.log(
|
|
5285
|
+
console.log(chalk61.green(`Added ${date} to skip list for ${repoName}`));
|
|
5245
5286
|
}
|
|
5246
5287
|
|
|
5247
5288
|
// src/commands/devlog/version.ts
|
|
5248
|
-
import
|
|
5289
|
+
import chalk62 from "chalk";
|
|
5249
5290
|
function version() {
|
|
5250
5291
|
const config = loadConfig();
|
|
5251
5292
|
const name = getRepoName();
|
|
5252
5293
|
const lastInfo = getLastVersionInfo(name, config);
|
|
5253
5294
|
const lastVersion = lastInfo?.version ?? null;
|
|
5254
5295
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
5255
|
-
console.log(`${
|
|
5256
|
-
console.log(`${
|
|
5257
|
-
console.log(`${
|
|
5296
|
+
console.log(`${chalk62.bold("name:")} ${name}`);
|
|
5297
|
+
console.log(`${chalk62.bold("last:")} ${lastVersion ?? chalk62.dim("none")}`);
|
|
5298
|
+
console.log(`${chalk62.bold("next:")} ${nextVersion ?? chalk62.dim("none")}`);
|
|
5258
5299
|
}
|
|
5259
5300
|
|
|
5260
5301
|
// src/commands/registerDevlog.ts
|
|
@@ -5278,7 +5319,7 @@ function registerDevlog(program2) {
|
|
|
5278
5319
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5279
5320
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5280
5321
|
import { join as join18 } from "path";
|
|
5281
|
-
import
|
|
5322
|
+
import chalk63 from "chalk";
|
|
5282
5323
|
|
|
5283
5324
|
// src/shared/findRepoRoot.ts
|
|
5284
5325
|
import { existsSync as existsSync24 } from "fs";
|
|
@@ -5341,14 +5382,14 @@ function checkBuildLocks(startDir) {
|
|
|
5341
5382
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5342
5383
|
if (locked) {
|
|
5343
5384
|
console.error(
|
|
5344
|
-
|
|
5385
|
+
chalk63.red("Build output locked (is VS debugging?): ") + locked
|
|
5345
5386
|
);
|
|
5346
5387
|
process.exit(1);
|
|
5347
5388
|
}
|
|
5348
5389
|
}
|
|
5349
5390
|
async function checkBuildLocksCommand() {
|
|
5350
5391
|
checkBuildLocks();
|
|
5351
|
-
console.log(
|
|
5392
|
+
console.log(chalk63.green("No build locks detected"));
|
|
5352
5393
|
}
|
|
5353
5394
|
|
|
5354
5395
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -5447,30 +5488,30 @@ function escapeRegex(s) {
|
|
|
5447
5488
|
}
|
|
5448
5489
|
|
|
5449
5490
|
// src/commands/dotnet/printTree.ts
|
|
5450
|
-
import
|
|
5491
|
+
import chalk64 from "chalk";
|
|
5451
5492
|
function printNodes(nodes, prefix2) {
|
|
5452
5493
|
for (let i = 0; i < nodes.length; i++) {
|
|
5453
5494
|
const isLast = i === nodes.length - 1;
|
|
5454
5495
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5455
5496
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5456
5497
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5457
|
-
const label2 = isMissing ?
|
|
5498
|
+
const label2 = isMissing ? chalk64.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5458
5499
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5459
5500
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5460
5501
|
}
|
|
5461
5502
|
}
|
|
5462
5503
|
function printTree(tree, totalCount, solutions) {
|
|
5463
|
-
console.log(
|
|
5464
|
-
console.log(
|
|
5504
|
+
console.log(chalk64.bold("\nProject Dependency Tree"));
|
|
5505
|
+
console.log(chalk64.cyan(tree.relativePath));
|
|
5465
5506
|
printNodes(tree.children, "");
|
|
5466
|
-
console.log(
|
|
5507
|
+
console.log(chalk64.dim(`
|
|
5467
5508
|
${totalCount} projects total (including root)`));
|
|
5468
|
-
console.log(
|
|
5509
|
+
console.log(chalk64.bold("\nSolution Membership"));
|
|
5469
5510
|
if (solutions.length === 0) {
|
|
5470
|
-
console.log(
|
|
5511
|
+
console.log(chalk64.yellow(" Not found in any .sln"));
|
|
5471
5512
|
} else {
|
|
5472
5513
|
for (const sln of solutions) {
|
|
5473
|
-
console.log(` ${
|
|
5514
|
+
console.log(` ${chalk64.green(sln)}`);
|
|
5474
5515
|
}
|
|
5475
5516
|
}
|
|
5476
5517
|
console.log();
|
|
@@ -5499,16 +5540,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5499
5540
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5500
5541
|
import { existsSync as existsSync25 } from "fs";
|
|
5501
5542
|
import path24 from "path";
|
|
5502
|
-
import
|
|
5543
|
+
import chalk65 from "chalk";
|
|
5503
5544
|
function resolveCsproj(csprojPath) {
|
|
5504
5545
|
const resolved = path24.resolve(csprojPath);
|
|
5505
5546
|
if (!existsSync25(resolved)) {
|
|
5506
|
-
console.error(
|
|
5547
|
+
console.error(chalk65.red(`File not found: ${resolved}`));
|
|
5507
5548
|
process.exit(1);
|
|
5508
5549
|
}
|
|
5509
5550
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5510
5551
|
if (!repoRoot) {
|
|
5511
|
-
console.error(
|
|
5552
|
+
console.error(chalk65.red("Could not find git repository root"));
|
|
5512
5553
|
process.exit(1);
|
|
5513
5554
|
}
|
|
5514
5555
|
return { resolved, repoRoot };
|
|
@@ -5558,12 +5599,12 @@ function getChangedCsFiles(scope) {
|
|
|
5558
5599
|
}
|
|
5559
5600
|
|
|
5560
5601
|
// src/commands/dotnet/inSln.ts
|
|
5561
|
-
import
|
|
5602
|
+
import chalk66 from "chalk";
|
|
5562
5603
|
async function inSln(csprojPath) {
|
|
5563
5604
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5564
5605
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5565
5606
|
if (solutions.length === 0) {
|
|
5566
|
-
console.log(
|
|
5607
|
+
console.log(chalk66.yellow("Not found in any .sln file"));
|
|
5567
5608
|
process.exit(1);
|
|
5568
5609
|
}
|
|
5569
5610
|
for (const sln of solutions) {
|
|
@@ -5572,7 +5613,7 @@ async function inSln(csprojPath) {
|
|
|
5572
5613
|
}
|
|
5573
5614
|
|
|
5574
5615
|
// src/commands/dotnet/inspect.ts
|
|
5575
|
-
import
|
|
5616
|
+
import chalk72 from "chalk";
|
|
5576
5617
|
|
|
5577
5618
|
// src/shared/formatElapsed.ts
|
|
5578
5619
|
function formatElapsed(ms) {
|
|
@@ -5584,12 +5625,12 @@ function formatElapsed(ms) {
|
|
|
5584
5625
|
}
|
|
5585
5626
|
|
|
5586
5627
|
// src/commands/dotnet/displayIssues.ts
|
|
5587
|
-
import
|
|
5628
|
+
import chalk67 from "chalk";
|
|
5588
5629
|
var SEVERITY_COLOR = {
|
|
5589
|
-
ERROR:
|
|
5590
|
-
WARNING:
|
|
5591
|
-
SUGGESTION:
|
|
5592
|
-
HINT:
|
|
5630
|
+
ERROR: chalk67.red,
|
|
5631
|
+
WARNING: chalk67.yellow,
|
|
5632
|
+
SUGGESTION: chalk67.cyan,
|
|
5633
|
+
HINT: chalk67.dim
|
|
5593
5634
|
};
|
|
5594
5635
|
function groupByFile(issues) {
|
|
5595
5636
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5605,15 +5646,15 @@ function groupByFile(issues) {
|
|
|
5605
5646
|
}
|
|
5606
5647
|
function displayIssues(issues) {
|
|
5607
5648
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5608
|
-
console.log(
|
|
5649
|
+
console.log(chalk67.bold(file));
|
|
5609
5650
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5610
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5651
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk67.white;
|
|
5611
5652
|
console.log(
|
|
5612
|
-
` ${
|
|
5653
|
+
` ${chalk67.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5613
5654
|
);
|
|
5614
5655
|
}
|
|
5615
5656
|
}
|
|
5616
|
-
console.log(
|
|
5657
|
+
console.log(chalk67.dim(`
|
|
5617
5658
|
${issues.length} issue(s) found`));
|
|
5618
5659
|
}
|
|
5619
5660
|
|
|
@@ -5672,12 +5713,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5672
5713
|
// src/commands/dotnet/resolveSolution.ts
|
|
5673
5714
|
import { existsSync as existsSync26 } from "fs";
|
|
5674
5715
|
import path25 from "path";
|
|
5675
|
-
import
|
|
5716
|
+
import chalk69 from "chalk";
|
|
5676
5717
|
|
|
5677
5718
|
// src/commands/dotnet/findSolution.ts
|
|
5678
5719
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5679
5720
|
import { dirname as dirname16, join as join19 } from "path";
|
|
5680
|
-
import
|
|
5721
|
+
import chalk68 from "chalk";
|
|
5681
5722
|
function findSlnInDir(dir) {
|
|
5682
5723
|
try {
|
|
5683
5724
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join19(dir, f));
|
|
@@ -5693,17 +5734,17 @@ function findSolution() {
|
|
|
5693
5734
|
const slnFiles = findSlnInDir(current);
|
|
5694
5735
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5695
5736
|
if (slnFiles.length > 1) {
|
|
5696
|
-
console.error(
|
|
5737
|
+
console.error(chalk68.red(`Multiple .sln files found in ${current}:`));
|
|
5697
5738
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5698
5739
|
console.error(
|
|
5699
|
-
|
|
5740
|
+
chalk68.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5700
5741
|
);
|
|
5701
5742
|
process.exit(1);
|
|
5702
5743
|
}
|
|
5703
5744
|
if (current === ceiling) break;
|
|
5704
5745
|
current = dirname16(current);
|
|
5705
5746
|
}
|
|
5706
|
-
console.error(
|
|
5747
|
+
console.error(chalk68.red("No .sln file found between cwd and repo root"));
|
|
5707
5748
|
process.exit(1);
|
|
5708
5749
|
}
|
|
5709
5750
|
|
|
@@ -5712,7 +5753,7 @@ function resolveSolution(sln) {
|
|
|
5712
5753
|
if (sln) {
|
|
5713
5754
|
const resolved = path25.resolve(sln);
|
|
5714
5755
|
if (!existsSync26(resolved)) {
|
|
5715
|
-
console.error(
|
|
5756
|
+
console.error(chalk69.red(`Solution file not found: ${resolved}`));
|
|
5716
5757
|
process.exit(1);
|
|
5717
5758
|
}
|
|
5718
5759
|
return resolved;
|
|
@@ -5754,14 +5795,14 @@ import { execSync as execSync23 } from "child_process";
|
|
|
5754
5795
|
import { existsSync as existsSync27, readFileSync as readFileSync22, unlinkSync as unlinkSync5 } from "fs";
|
|
5755
5796
|
import { tmpdir as tmpdir2 } from "os";
|
|
5756
5797
|
import path26 from "path";
|
|
5757
|
-
import
|
|
5798
|
+
import chalk70 from "chalk";
|
|
5758
5799
|
function assertJbInstalled() {
|
|
5759
5800
|
try {
|
|
5760
5801
|
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5761
5802
|
} catch {
|
|
5762
|
-
console.error(
|
|
5803
|
+
console.error(chalk70.red("jb is not installed. Install with:"));
|
|
5763
5804
|
console.error(
|
|
5764
|
-
|
|
5805
|
+
chalk70.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5765
5806
|
);
|
|
5766
5807
|
process.exit(1);
|
|
5767
5808
|
}
|
|
@@ -5779,11 +5820,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5779
5820
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5780
5821
|
process.stderr.write(err.stderr);
|
|
5781
5822
|
}
|
|
5782
|
-
console.error(
|
|
5823
|
+
console.error(chalk70.red("jb inspectcode failed"));
|
|
5783
5824
|
process.exit(1);
|
|
5784
5825
|
}
|
|
5785
5826
|
if (!existsSync27(reportPath)) {
|
|
5786
|
-
console.error(
|
|
5827
|
+
console.error(chalk70.red("Report file not generated"));
|
|
5787
5828
|
process.exit(1);
|
|
5788
5829
|
}
|
|
5789
5830
|
const xml = readFileSync22(reportPath, "utf-8");
|
|
@@ -5793,7 +5834,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5793
5834
|
|
|
5794
5835
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5795
5836
|
import { execSync as execSync24 } from "child_process";
|
|
5796
|
-
import
|
|
5837
|
+
import chalk71 from "chalk";
|
|
5797
5838
|
function resolveMsbuildPath() {
|
|
5798
5839
|
const config = loadConfig();
|
|
5799
5840
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5804,9 +5845,9 @@ function assertMsbuildInstalled() {
|
|
|
5804
5845
|
try {
|
|
5805
5846
|
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5806
5847
|
} catch {
|
|
5807
|
-
console.error(
|
|
5848
|
+
console.error(chalk71.red(`msbuild not found at: ${msbuild}`));
|
|
5808
5849
|
console.error(
|
|
5809
|
-
|
|
5850
|
+
chalk71.yellow(
|
|
5810
5851
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5811
5852
|
)
|
|
5812
5853
|
);
|
|
@@ -5853,17 +5894,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5853
5894
|
// src/commands/dotnet/inspect.ts
|
|
5854
5895
|
function logScope(changedFiles) {
|
|
5855
5896
|
if (changedFiles === null) {
|
|
5856
|
-
console.log(
|
|
5897
|
+
console.log(chalk72.dim("Inspecting full solution..."));
|
|
5857
5898
|
} else {
|
|
5858
5899
|
console.log(
|
|
5859
|
-
|
|
5900
|
+
chalk72.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5860
5901
|
);
|
|
5861
5902
|
}
|
|
5862
5903
|
}
|
|
5863
5904
|
function reportResults(issues, elapsed) {
|
|
5864
5905
|
if (issues.length > 0) displayIssues(issues);
|
|
5865
|
-
else console.log(
|
|
5866
|
-
console.log(
|
|
5906
|
+
else console.log(chalk72.green("No issues found"));
|
|
5907
|
+
console.log(chalk72.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5867
5908
|
if (issues.length > 0) process.exit(1);
|
|
5868
5909
|
}
|
|
5869
5910
|
async function inspect(sln, options2) {
|
|
@@ -5874,7 +5915,7 @@ async function inspect(sln, options2) {
|
|
|
5874
5915
|
const scope = parseScope(options2.scope);
|
|
5875
5916
|
const changedFiles = getChangedCsFiles(scope);
|
|
5876
5917
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5877
|
-
console.log(
|
|
5918
|
+
console.log(chalk72.green("No changed .cs files found"));
|
|
5878
5919
|
return;
|
|
5879
5920
|
}
|
|
5880
5921
|
logScope(changedFiles);
|
|
@@ -5900,7 +5941,7 @@ function registerDotnet(program2) {
|
|
|
5900
5941
|
}
|
|
5901
5942
|
|
|
5902
5943
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5903
|
-
import
|
|
5944
|
+
import chalk74 from "chalk";
|
|
5904
5945
|
|
|
5905
5946
|
// src/commands/jira/adfToText.ts
|
|
5906
5947
|
function renderInline(node) {
|
|
@@ -5961,7 +6002,7 @@ function adfToText(doc) {
|
|
|
5961
6002
|
|
|
5962
6003
|
// src/commands/jira/fetchIssue.ts
|
|
5963
6004
|
import { execSync as execSync25 } from "child_process";
|
|
5964
|
-
import
|
|
6005
|
+
import chalk73 from "chalk";
|
|
5965
6006
|
function fetchIssue(issueKey, fields) {
|
|
5966
6007
|
let result;
|
|
5967
6008
|
try {
|
|
@@ -5974,15 +6015,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
5974
6015
|
const stderr = error.stderr;
|
|
5975
6016
|
if (stderr.includes("unauthorized")) {
|
|
5976
6017
|
console.error(
|
|
5977
|
-
|
|
6018
|
+
chalk73.red("Jira authentication expired."),
|
|
5978
6019
|
"Run",
|
|
5979
|
-
|
|
6020
|
+
chalk73.cyan("assist jira auth"),
|
|
5980
6021
|
"to re-authenticate."
|
|
5981
6022
|
);
|
|
5982
6023
|
process.exit(1);
|
|
5983
6024
|
}
|
|
5984
6025
|
}
|
|
5985
|
-
console.error(
|
|
6026
|
+
console.error(chalk73.red(`Failed to fetch ${issueKey}.`));
|
|
5986
6027
|
process.exit(1);
|
|
5987
6028
|
}
|
|
5988
6029
|
return JSON.parse(result);
|
|
@@ -5996,7 +6037,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5996
6037
|
const parsed = fetchIssue(issueKey, field);
|
|
5997
6038
|
const acValue = parsed?.fields?.[field];
|
|
5998
6039
|
if (!acValue) {
|
|
5999
|
-
console.log(
|
|
6040
|
+
console.log(chalk74.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
6000
6041
|
return;
|
|
6001
6042
|
}
|
|
6002
6043
|
if (typeof acValue === "string") {
|
|
@@ -6091,14 +6132,14 @@ async function jiraAuth() {
|
|
|
6091
6132
|
}
|
|
6092
6133
|
|
|
6093
6134
|
// src/commands/jira/viewIssue.ts
|
|
6094
|
-
import
|
|
6135
|
+
import chalk75 from "chalk";
|
|
6095
6136
|
function viewIssue(issueKey) {
|
|
6096
6137
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
6097
6138
|
const fields = parsed?.fields;
|
|
6098
6139
|
const summary = fields?.summary;
|
|
6099
6140
|
const description = fields?.description;
|
|
6100
6141
|
if (summary) {
|
|
6101
|
-
console.log(
|
|
6142
|
+
console.log(chalk75.bold(summary));
|
|
6102
6143
|
}
|
|
6103
6144
|
if (description) {
|
|
6104
6145
|
if (summary) console.log();
|
|
@@ -6112,7 +6153,7 @@ function viewIssue(issueKey) {
|
|
|
6112
6153
|
}
|
|
6113
6154
|
if (!summary && !description) {
|
|
6114
6155
|
console.log(
|
|
6115
|
-
|
|
6156
|
+
chalk75.yellow(`No summary or description found on ${issueKey}.`)
|
|
6116
6157
|
);
|
|
6117
6158
|
}
|
|
6118
6159
|
}
|
|
@@ -6126,7 +6167,7 @@ function registerJira(program2) {
|
|
|
6126
6167
|
}
|
|
6127
6168
|
|
|
6128
6169
|
// src/commands/news/add/index.ts
|
|
6129
|
-
import
|
|
6170
|
+
import chalk76 from "chalk";
|
|
6130
6171
|
import enquirer7 from "enquirer";
|
|
6131
6172
|
async function add2(url) {
|
|
6132
6173
|
if (!url) {
|
|
@@ -6149,17 +6190,17 @@ async function add2(url) {
|
|
|
6149
6190
|
const news = config.news ?? {};
|
|
6150
6191
|
const feeds = news.feeds ?? [];
|
|
6151
6192
|
if (feeds.includes(url)) {
|
|
6152
|
-
console.log(
|
|
6193
|
+
console.log(chalk76.yellow("Feed already exists in config"));
|
|
6153
6194
|
return;
|
|
6154
6195
|
}
|
|
6155
6196
|
feeds.push(url);
|
|
6156
6197
|
config.news = { ...news, feeds };
|
|
6157
6198
|
saveGlobalConfig(config);
|
|
6158
|
-
console.log(
|
|
6199
|
+
console.log(chalk76.green(`Added feed: ${url}`));
|
|
6159
6200
|
}
|
|
6160
6201
|
|
|
6161
6202
|
// src/commands/news/web/handleRequest.ts
|
|
6162
|
-
import
|
|
6203
|
+
import chalk77 from "chalk";
|
|
6163
6204
|
|
|
6164
6205
|
// src/commands/news/web/shared.ts
|
|
6165
6206
|
import { decodeHTML } from "entities";
|
|
@@ -6295,17 +6336,17 @@ function prefetch() {
|
|
|
6295
6336
|
const config = loadConfig();
|
|
6296
6337
|
const total = config.news.feeds.length;
|
|
6297
6338
|
if (total === 0) return;
|
|
6298
|
-
process.stdout.write(
|
|
6339
|
+
process.stdout.write(chalk77.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6299
6340
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6300
6341
|
const width = 20;
|
|
6301
6342
|
const filled = Math.round(done2 / t * width);
|
|
6302
6343
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6303
6344
|
process.stdout.write(
|
|
6304
|
-
`\r${
|
|
6345
|
+
`\r${chalk77.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6305
6346
|
);
|
|
6306
6347
|
}).then((items) => {
|
|
6307
6348
|
process.stdout.write(
|
|
6308
|
-
`\r${
|
|
6349
|
+
`\r${chalk77.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6309
6350
|
`
|
|
6310
6351
|
);
|
|
6311
6352
|
cachedItems = items;
|
|
@@ -6666,20 +6707,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6666
6707
|
}
|
|
6667
6708
|
|
|
6668
6709
|
// src/commands/prs/listComments/printComments.ts
|
|
6669
|
-
import
|
|
6710
|
+
import chalk78 from "chalk";
|
|
6670
6711
|
function formatForHuman(comment3) {
|
|
6671
6712
|
if (comment3.type === "review") {
|
|
6672
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
6713
|
+
const stateColor = comment3.state === "APPROVED" ? chalk78.green : comment3.state === "CHANGES_REQUESTED" ? chalk78.red : chalk78.yellow;
|
|
6673
6714
|
return [
|
|
6674
|
-
`${
|
|
6715
|
+
`${chalk78.cyan("Review")} by ${chalk78.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
6675
6716
|
comment3.body,
|
|
6676
6717
|
""
|
|
6677
6718
|
].join("\n");
|
|
6678
6719
|
}
|
|
6679
6720
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
6680
6721
|
return [
|
|
6681
|
-
`${
|
|
6682
|
-
|
|
6722
|
+
`${chalk78.cyan("Line comment")} by ${chalk78.bold(comment3.user)} on ${chalk78.dim(`${comment3.path}${location}`)}`,
|
|
6723
|
+
chalk78.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6683
6724
|
comment3.body,
|
|
6684
6725
|
""
|
|
6685
6726
|
].join("\n");
|
|
@@ -6769,13 +6810,13 @@ import { execSync as execSync32 } from "child_process";
|
|
|
6769
6810
|
import enquirer8 from "enquirer";
|
|
6770
6811
|
|
|
6771
6812
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6772
|
-
import
|
|
6813
|
+
import chalk79 from "chalk";
|
|
6773
6814
|
var STATUS_MAP = {
|
|
6774
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6775
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6815
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk79.magenta("merged"), date: pr.mergedAt } : null,
|
|
6816
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk79.red("closed"), date: pr.closedAt } : null
|
|
6776
6817
|
};
|
|
6777
6818
|
function defaultStatus(pr) {
|
|
6778
|
-
return { label:
|
|
6819
|
+
return { label: chalk79.green("opened"), date: pr.createdAt };
|
|
6779
6820
|
}
|
|
6780
6821
|
function getStatus2(pr) {
|
|
6781
6822
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6784,11 +6825,11 @@ function formatDate(dateStr) {
|
|
|
6784
6825
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6785
6826
|
}
|
|
6786
6827
|
function formatPrHeader(pr, status2) {
|
|
6787
|
-
return `${
|
|
6828
|
+
return `${chalk79.cyan(`#${pr.number}`)} ${pr.title} ${chalk79.dim(`(${pr.author.login},`)} ${status2.label} ${chalk79.dim(`${formatDate(status2.date)})`)}`;
|
|
6788
6829
|
}
|
|
6789
6830
|
function logPrDetails(pr) {
|
|
6790
6831
|
console.log(
|
|
6791
|
-
|
|
6832
|
+
chalk79.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6792
6833
|
);
|
|
6793
6834
|
console.log();
|
|
6794
6835
|
}
|
|
@@ -6954,10 +6995,10 @@ function registerPrs(program2) {
|
|
|
6954
6995
|
}
|
|
6955
6996
|
|
|
6956
6997
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6957
|
-
import
|
|
6998
|
+
import chalk85 from "chalk";
|
|
6958
6999
|
|
|
6959
7000
|
// src/shared/createConnectionAuth.ts
|
|
6960
|
-
import
|
|
7001
|
+
import chalk80 from "chalk";
|
|
6961
7002
|
function listConnections(connections, format2) {
|
|
6962
7003
|
if (connections.length === 0) {
|
|
6963
7004
|
console.log("No connections configured.");
|
|
@@ -6970,7 +7011,7 @@ function listConnections(connections, format2) {
|
|
|
6970
7011
|
function removeConnection(connections, name, save) {
|
|
6971
7012
|
const filtered = connections.filter((c) => c.name !== name);
|
|
6972
7013
|
if (filtered.length === connections.length) {
|
|
6973
|
-
console.error(
|
|
7014
|
+
console.error(chalk80.red(`Connection "${name}" not found.`));
|
|
6974
7015
|
process.exit(1);
|
|
6975
7016
|
}
|
|
6976
7017
|
save(filtered);
|
|
@@ -7016,15 +7057,15 @@ function saveConnections(connections) {
|
|
|
7016
7057
|
}
|
|
7017
7058
|
|
|
7018
7059
|
// src/commands/ravendb/promptConnection.ts
|
|
7019
|
-
import
|
|
7060
|
+
import chalk83 from "chalk";
|
|
7020
7061
|
|
|
7021
7062
|
// src/commands/ravendb/selectOpSecret.ts
|
|
7022
|
-
import
|
|
7063
|
+
import chalk82 from "chalk";
|
|
7023
7064
|
import Enquirer2 from "enquirer";
|
|
7024
7065
|
|
|
7025
7066
|
// src/commands/ravendb/searchItems.ts
|
|
7026
7067
|
import { execSync as execSync34 } from "child_process";
|
|
7027
|
-
import
|
|
7068
|
+
import chalk81 from "chalk";
|
|
7028
7069
|
function opExec(args) {
|
|
7029
7070
|
return execSync34(`op ${args}`, {
|
|
7030
7071
|
encoding: "utf-8",
|
|
@@ -7037,7 +7078,7 @@ function searchItems(search) {
|
|
|
7037
7078
|
items = JSON.parse(opExec("item list --format=json"));
|
|
7038
7079
|
} catch {
|
|
7039
7080
|
console.error(
|
|
7040
|
-
|
|
7081
|
+
chalk81.red(
|
|
7041
7082
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
7042
7083
|
)
|
|
7043
7084
|
);
|
|
@@ -7051,7 +7092,7 @@ function getItemFields(itemId) {
|
|
|
7051
7092
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
7052
7093
|
return item.fields.filter((f) => f.reference && f.label);
|
|
7053
7094
|
} catch {
|
|
7054
|
-
console.error(
|
|
7095
|
+
console.error(chalk81.red("Failed to get item details from 1Password."));
|
|
7055
7096
|
process.exit(1);
|
|
7056
7097
|
}
|
|
7057
7098
|
}
|
|
@@ -7070,7 +7111,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7070
7111
|
}).run();
|
|
7071
7112
|
const items = searchItems(search);
|
|
7072
7113
|
if (items.length === 0) {
|
|
7073
|
-
console.error(
|
|
7114
|
+
console.error(chalk82.red(`No items found matching "${search}".`));
|
|
7074
7115
|
process.exit(1);
|
|
7075
7116
|
}
|
|
7076
7117
|
const itemId = await selectOne(
|
|
@@ -7079,7 +7120,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7079
7120
|
);
|
|
7080
7121
|
const fields = getItemFields(itemId);
|
|
7081
7122
|
if (fields.length === 0) {
|
|
7082
|
-
console.error(
|
|
7123
|
+
console.error(chalk82.red("No fields with references found on this item."));
|
|
7083
7124
|
process.exit(1);
|
|
7084
7125
|
}
|
|
7085
7126
|
const ref = await selectOne(
|
|
@@ -7093,7 +7134,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7093
7134
|
async function promptConnection(existingNames) {
|
|
7094
7135
|
const name = await promptInput("name", "Connection name:");
|
|
7095
7136
|
if (existingNames.includes(name)) {
|
|
7096
|
-
console.error(
|
|
7137
|
+
console.error(chalk83.red(`Connection "${name}" already exists.`));
|
|
7097
7138
|
process.exit(1);
|
|
7098
7139
|
}
|
|
7099
7140
|
const url = await promptInput(
|
|
@@ -7102,22 +7143,22 @@ async function promptConnection(existingNames) {
|
|
|
7102
7143
|
);
|
|
7103
7144
|
const database = await promptInput("database", "Database name:");
|
|
7104
7145
|
if (!name || !url || !database) {
|
|
7105
|
-
console.error(
|
|
7146
|
+
console.error(chalk83.red("All fields are required."));
|
|
7106
7147
|
process.exit(1);
|
|
7107
7148
|
}
|
|
7108
7149
|
const apiKeyRef = await selectOpSecret();
|
|
7109
|
-
console.log(
|
|
7150
|
+
console.log(chalk83.dim(`Using: ${apiKeyRef}`));
|
|
7110
7151
|
return { name, url, database, apiKeyRef };
|
|
7111
7152
|
}
|
|
7112
7153
|
|
|
7113
7154
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
7114
|
-
import
|
|
7155
|
+
import chalk84 from "chalk";
|
|
7115
7156
|
function ravendbSetConnection(name) {
|
|
7116
7157
|
const raw = loadGlobalConfigRaw();
|
|
7117
7158
|
const ravendb = raw.ravendb ?? {};
|
|
7118
7159
|
const connections = ravendb.connections ?? [];
|
|
7119
7160
|
if (!connections.some((c) => c.name === name)) {
|
|
7120
|
-
console.error(
|
|
7161
|
+
console.error(chalk84.red(`Connection "${name}" not found.`));
|
|
7121
7162
|
console.error(
|
|
7122
7163
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7123
7164
|
);
|
|
@@ -7133,16 +7174,16 @@ function ravendbSetConnection(name) {
|
|
|
7133
7174
|
var ravendbAuth = createConnectionAuth({
|
|
7134
7175
|
load: loadConnections,
|
|
7135
7176
|
save: saveConnections,
|
|
7136
|
-
format: (c) => `${
|
|
7177
|
+
format: (c) => `${chalk85.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
7137
7178
|
promptNew: promptConnection,
|
|
7138
7179
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
7139
7180
|
});
|
|
7140
7181
|
|
|
7141
7182
|
// src/commands/ravendb/ravendbCollections.ts
|
|
7142
|
-
import
|
|
7183
|
+
import chalk89 from "chalk";
|
|
7143
7184
|
|
|
7144
7185
|
// src/commands/ravendb/ravenFetch.ts
|
|
7145
|
-
import
|
|
7186
|
+
import chalk87 from "chalk";
|
|
7146
7187
|
|
|
7147
7188
|
// src/commands/ravendb/getAccessToken.ts
|
|
7148
7189
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -7179,10 +7220,10 @@ ${errorText}`
|
|
|
7179
7220
|
|
|
7180
7221
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
7181
7222
|
import { execSync as execSync35 } from "child_process";
|
|
7182
|
-
import
|
|
7223
|
+
import chalk86 from "chalk";
|
|
7183
7224
|
function resolveOpSecret(reference) {
|
|
7184
7225
|
if (!reference.startsWith("op://")) {
|
|
7185
|
-
console.error(
|
|
7226
|
+
console.error(chalk86.red(`Invalid secret reference: must start with op://`));
|
|
7186
7227
|
process.exit(1);
|
|
7187
7228
|
}
|
|
7188
7229
|
try {
|
|
@@ -7192,7 +7233,7 @@ function resolveOpSecret(reference) {
|
|
|
7192
7233
|
}).trim();
|
|
7193
7234
|
} catch {
|
|
7194
7235
|
console.error(
|
|
7195
|
-
|
|
7236
|
+
chalk86.red(
|
|
7196
7237
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
7197
7238
|
)
|
|
7198
7239
|
);
|
|
@@ -7219,7 +7260,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7219
7260
|
if (!response.ok) {
|
|
7220
7261
|
const body = await response.text();
|
|
7221
7262
|
console.error(
|
|
7222
|
-
|
|
7263
|
+
chalk87.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
7223
7264
|
);
|
|
7224
7265
|
console.error(body.substring(0, 500));
|
|
7225
7266
|
process.exit(1);
|
|
@@ -7228,7 +7269,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7228
7269
|
}
|
|
7229
7270
|
|
|
7230
7271
|
// src/commands/ravendb/resolveConnection.ts
|
|
7231
|
-
import
|
|
7272
|
+
import chalk88 from "chalk";
|
|
7232
7273
|
function loadRavendb() {
|
|
7233
7274
|
const raw = loadGlobalConfigRaw();
|
|
7234
7275
|
const ravendb = raw.ravendb;
|
|
@@ -7242,7 +7283,7 @@ function resolveConnection(name) {
|
|
|
7242
7283
|
const connectionName = name ?? defaultConnection;
|
|
7243
7284
|
if (!connectionName) {
|
|
7244
7285
|
console.error(
|
|
7245
|
-
|
|
7286
|
+
chalk88.red(
|
|
7246
7287
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
7247
7288
|
)
|
|
7248
7289
|
);
|
|
@@ -7250,7 +7291,7 @@ function resolveConnection(name) {
|
|
|
7250
7291
|
}
|
|
7251
7292
|
const connection = connections.find((c) => c.name === connectionName);
|
|
7252
7293
|
if (!connection) {
|
|
7253
|
-
console.error(
|
|
7294
|
+
console.error(chalk88.red(`Connection "${connectionName}" not found.`));
|
|
7254
7295
|
console.error(
|
|
7255
7296
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7256
7297
|
);
|
|
@@ -7281,15 +7322,15 @@ async function ravendbCollections(connectionName) {
|
|
|
7281
7322
|
return;
|
|
7282
7323
|
}
|
|
7283
7324
|
for (const c of collections) {
|
|
7284
|
-
console.log(`${
|
|
7325
|
+
console.log(`${chalk89.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
7285
7326
|
}
|
|
7286
7327
|
}
|
|
7287
7328
|
|
|
7288
7329
|
// src/commands/ravendb/ravendbQuery.ts
|
|
7289
|
-
import
|
|
7330
|
+
import chalk91 from "chalk";
|
|
7290
7331
|
|
|
7291
7332
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7292
|
-
import
|
|
7333
|
+
import chalk90 from "chalk";
|
|
7293
7334
|
|
|
7294
7335
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7295
7336
|
function buildQueryPath(opts) {
|
|
@@ -7327,7 +7368,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7327
7368
|
allResults.push(...results);
|
|
7328
7369
|
start3 += results.length;
|
|
7329
7370
|
process.stderr.write(
|
|
7330
|
-
`\r${
|
|
7371
|
+
`\r${chalk90.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7331
7372
|
);
|
|
7332
7373
|
if (start3 >= totalResults) break;
|
|
7333
7374
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7342,7 +7383,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7342
7383
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7343
7384
|
const resolved = resolveArgs(connectionName, collection);
|
|
7344
7385
|
if (!resolved.collection && !options2.query) {
|
|
7345
|
-
console.error(
|
|
7386
|
+
console.error(chalk91.red("Provide a collection name or --query filter."));
|
|
7346
7387
|
process.exit(1);
|
|
7347
7388
|
}
|
|
7348
7389
|
const { collection: col } = resolved;
|
|
@@ -7380,7 +7421,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7380
7421
|
import * as path27 from "path";
|
|
7381
7422
|
|
|
7382
7423
|
// src/commands/refactor/logViolations.ts
|
|
7383
|
-
import
|
|
7424
|
+
import chalk92 from "chalk";
|
|
7384
7425
|
var DEFAULT_MAX_LINES = 100;
|
|
7385
7426
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7386
7427
|
if (violations.length === 0) {
|
|
@@ -7389,43 +7430,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7389
7430
|
}
|
|
7390
7431
|
return;
|
|
7391
7432
|
}
|
|
7392
|
-
console.error(
|
|
7433
|
+
console.error(chalk92.red(`
|
|
7393
7434
|
Refactor check failed:
|
|
7394
7435
|
`));
|
|
7395
|
-
console.error(
|
|
7436
|
+
console.error(chalk92.red(` The following files exceed ${maxLines} lines:
|
|
7396
7437
|
`));
|
|
7397
7438
|
for (const violation of violations) {
|
|
7398
|
-
console.error(
|
|
7439
|
+
console.error(chalk92.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7399
7440
|
}
|
|
7400
7441
|
console.error(
|
|
7401
|
-
|
|
7442
|
+
chalk92.yellow(
|
|
7402
7443
|
`
|
|
7403
7444
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7404
7445
|
way to refactor it, ignore it with:
|
|
7405
7446
|
`
|
|
7406
7447
|
)
|
|
7407
7448
|
);
|
|
7408
|
-
console.error(
|
|
7449
|
+
console.error(chalk92.gray(` assist refactor ignore <file>
|
|
7409
7450
|
`));
|
|
7410
7451
|
if (process.env.CLAUDECODE) {
|
|
7411
|
-
console.error(
|
|
7452
|
+
console.error(chalk92.cyan(`
|
|
7412
7453
|
## Extracting Code to New Files
|
|
7413
7454
|
`));
|
|
7414
7455
|
console.error(
|
|
7415
|
-
|
|
7456
|
+
chalk92.cyan(
|
|
7416
7457
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7417
7458
|
`
|
|
7418
7459
|
)
|
|
7419
7460
|
);
|
|
7420
7461
|
console.error(
|
|
7421
|
-
|
|
7462
|
+
chalk92.cyan(
|
|
7422
7463
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7423
7464
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7424
7465
|
`
|
|
7425
7466
|
)
|
|
7426
7467
|
);
|
|
7427
7468
|
console.error(
|
|
7428
|
-
|
|
7469
|
+
chalk92.cyan(
|
|
7429
7470
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7430
7471
|
domains, move it to a common/shared folder.
|
|
7431
7472
|
`
|
|
@@ -7581,7 +7622,7 @@ async function check(pattern2, options2) {
|
|
|
7581
7622
|
|
|
7582
7623
|
// src/commands/refactor/extract/index.ts
|
|
7583
7624
|
import path33 from "path";
|
|
7584
|
-
import
|
|
7625
|
+
import chalk95 from "chalk";
|
|
7585
7626
|
|
|
7586
7627
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7587
7628
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -8107,23 +8148,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
8107
8148
|
|
|
8108
8149
|
// src/commands/refactor/extract/displayPlan.ts
|
|
8109
8150
|
import path31 from "path";
|
|
8110
|
-
import
|
|
8151
|
+
import chalk93 from "chalk";
|
|
8111
8152
|
function section(title) {
|
|
8112
8153
|
return `
|
|
8113
|
-
${
|
|
8154
|
+
${chalk93.cyan(title)}`;
|
|
8114
8155
|
}
|
|
8115
8156
|
function displayImporters(plan2, cwd) {
|
|
8116
8157
|
if (plan2.importersToUpdate.length === 0) return;
|
|
8117
8158
|
console.log(section("Update importers:"));
|
|
8118
8159
|
for (const imp of plan2.importersToUpdate) {
|
|
8119
8160
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
8120
|
-
console.log(` ${
|
|
8161
|
+
console.log(` ${chalk93.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
8121
8162
|
}
|
|
8122
8163
|
}
|
|
8123
8164
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
8124
|
-
console.log(
|
|
8165
|
+
console.log(chalk93.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
8125
8166
|
`));
|
|
8126
|
-
console.log(` ${
|
|
8167
|
+
console.log(` ${chalk93.cyan("Functions to move:")}`);
|
|
8127
8168
|
for (const name of plan2.extractedNames) {
|
|
8128
8169
|
console.log(` ${name}`);
|
|
8129
8170
|
}
|
|
@@ -8158,7 +8199,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
8158
8199
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
8159
8200
|
import fs17 from "fs";
|
|
8160
8201
|
import path32 from "path";
|
|
8161
|
-
import
|
|
8202
|
+
import chalk94 from "chalk";
|
|
8162
8203
|
import { Project as Project2 } from "ts-morph";
|
|
8163
8204
|
function findTsConfig(sourcePath) {
|
|
8164
8205
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -8189,7 +8230,7 @@ function loadProjectFile(file) {
|
|
|
8189
8230
|
});
|
|
8190
8231
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
8191
8232
|
if (!sourceFile) {
|
|
8192
|
-
console.log(
|
|
8233
|
+
console.log(chalk94.red(`File not found in project: ${file}`));
|
|
8193
8234
|
process.exit(1);
|
|
8194
8235
|
}
|
|
8195
8236
|
return { project, sourceFile };
|
|
@@ -8212,19 +8253,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
8212
8253
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
8213
8254
|
if (options2.apply) {
|
|
8214
8255
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
8215
|
-
console.log(
|
|
8256
|
+
console.log(chalk95.green("\nExtraction complete"));
|
|
8216
8257
|
} else {
|
|
8217
|
-
console.log(
|
|
8258
|
+
console.log(chalk95.dim("\nDry run. Use --apply to execute."));
|
|
8218
8259
|
}
|
|
8219
8260
|
}
|
|
8220
8261
|
|
|
8221
8262
|
// src/commands/refactor/ignore.ts
|
|
8222
8263
|
import fs18 from "fs";
|
|
8223
|
-
import
|
|
8264
|
+
import chalk96 from "chalk";
|
|
8224
8265
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
8225
8266
|
function ignore(file) {
|
|
8226
8267
|
if (!fs18.existsSync(file)) {
|
|
8227
|
-
console.error(
|
|
8268
|
+
console.error(chalk96.red(`Error: File does not exist: ${file}`));
|
|
8228
8269
|
process.exit(1);
|
|
8229
8270
|
}
|
|
8230
8271
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -8240,7 +8281,7 @@ function ignore(file) {
|
|
|
8240
8281
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
8241
8282
|
}
|
|
8242
8283
|
console.log(
|
|
8243
|
-
|
|
8284
|
+
chalk96.green(
|
|
8244
8285
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
8245
8286
|
)
|
|
8246
8287
|
);
|
|
@@ -8248,26 +8289,26 @@ function ignore(file) {
|
|
|
8248
8289
|
|
|
8249
8290
|
// src/commands/refactor/rename/index.ts
|
|
8250
8291
|
import path34 from "path";
|
|
8251
|
-
import
|
|
8292
|
+
import chalk97 from "chalk";
|
|
8252
8293
|
async function rename(source, destination, options2 = {}) {
|
|
8253
8294
|
const destPath = path34.resolve(destination);
|
|
8254
8295
|
const cwd = process.cwd();
|
|
8255
8296
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
8256
8297
|
const relDest = path34.relative(cwd, destPath);
|
|
8257
8298
|
const { project, sourceFile } = loadProjectFile(source);
|
|
8258
|
-
console.log(
|
|
8299
|
+
console.log(chalk97.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
8259
8300
|
if (options2.apply) {
|
|
8260
8301
|
sourceFile.move(destPath);
|
|
8261
8302
|
await project.save();
|
|
8262
|
-
console.log(
|
|
8303
|
+
console.log(chalk97.green("Done"));
|
|
8263
8304
|
} else {
|
|
8264
|
-
console.log(
|
|
8305
|
+
console.log(chalk97.dim("Dry run. Use --apply to execute."));
|
|
8265
8306
|
}
|
|
8266
8307
|
}
|
|
8267
8308
|
|
|
8268
8309
|
// src/commands/refactor/renameSymbol/index.ts
|
|
8269
8310
|
import path36 from "path";
|
|
8270
|
-
import
|
|
8311
|
+
import chalk98 from "chalk";
|
|
8271
8312
|
import { Project as Project3 } from "ts-morph";
|
|
8272
8313
|
|
|
8273
8314
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8316,38 +8357,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8316
8357
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8317
8358
|
const sourceFile = project.getSourceFile(filePath);
|
|
8318
8359
|
if (!sourceFile) {
|
|
8319
|
-
console.log(
|
|
8360
|
+
console.log(chalk98.red(`File not found in project: ${file}`));
|
|
8320
8361
|
process.exit(1);
|
|
8321
8362
|
}
|
|
8322
8363
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8323
8364
|
if (!symbol) {
|
|
8324
|
-
console.log(
|
|
8365
|
+
console.log(chalk98.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8325
8366
|
process.exit(1);
|
|
8326
8367
|
}
|
|
8327
8368
|
const grouped = groupReferences(symbol, cwd);
|
|
8328
8369
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8329
8370
|
console.log(
|
|
8330
|
-
|
|
8371
|
+
chalk98.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8331
8372
|
`)
|
|
8332
8373
|
);
|
|
8333
8374
|
for (const [refFile, lines] of grouped) {
|
|
8334
8375
|
console.log(
|
|
8335
|
-
` ${
|
|
8376
|
+
` ${chalk98.dim(refFile)}: lines ${chalk98.cyan(lines.join(", "))}`
|
|
8336
8377
|
);
|
|
8337
8378
|
}
|
|
8338
8379
|
if (options2.apply) {
|
|
8339
8380
|
symbol.rename(newName);
|
|
8340
8381
|
await project.save();
|
|
8341
|
-
console.log(
|
|
8382
|
+
console.log(chalk98.green(`
|
|
8342
8383
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8343
8384
|
} else {
|
|
8344
|
-
console.log(
|
|
8385
|
+
console.log(chalk98.dim("\nDry run. Use --apply to execute."));
|
|
8345
8386
|
}
|
|
8346
8387
|
}
|
|
8347
8388
|
|
|
8348
8389
|
// src/commands/refactor/restructure/index.ts
|
|
8349
8390
|
import path45 from "path";
|
|
8350
|
-
import
|
|
8391
|
+
import chalk101 from "chalk";
|
|
8351
8392
|
|
|
8352
8393
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8353
8394
|
import path37 from "path";
|
|
@@ -8590,50 +8631,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8590
8631
|
|
|
8591
8632
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8592
8633
|
import path41 from "path";
|
|
8593
|
-
import
|
|
8634
|
+
import chalk99 from "chalk";
|
|
8594
8635
|
function relPath(filePath) {
|
|
8595
8636
|
return path41.relative(process.cwd(), filePath);
|
|
8596
8637
|
}
|
|
8597
8638
|
function displayMoves(plan2) {
|
|
8598
8639
|
if (plan2.moves.length === 0) return;
|
|
8599
|
-
console.log(
|
|
8640
|
+
console.log(chalk99.bold("\nFile moves:"));
|
|
8600
8641
|
for (const move of plan2.moves) {
|
|
8601
8642
|
console.log(
|
|
8602
|
-
` ${
|
|
8643
|
+
` ${chalk99.red(relPath(move.from))} \u2192 ${chalk99.green(relPath(move.to))}`
|
|
8603
8644
|
);
|
|
8604
|
-
console.log(
|
|
8645
|
+
console.log(chalk99.dim(` ${move.reason}`));
|
|
8605
8646
|
}
|
|
8606
8647
|
}
|
|
8607
8648
|
function displayRewrites(rewrites) {
|
|
8608
8649
|
if (rewrites.length === 0) return;
|
|
8609
8650
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8610
|
-
console.log(
|
|
8651
|
+
console.log(chalk99.bold(`
|
|
8611
8652
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8612
8653
|
for (const file of affectedFiles) {
|
|
8613
|
-
console.log(` ${
|
|
8654
|
+
console.log(` ${chalk99.cyan(relPath(file))}:`);
|
|
8614
8655
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8615
8656
|
(r) => r.file === file
|
|
8616
8657
|
)) {
|
|
8617
8658
|
console.log(
|
|
8618
|
-
` ${
|
|
8659
|
+
` ${chalk99.red(`"${oldSpecifier}"`)} \u2192 ${chalk99.green(`"${newSpecifier}"`)}`
|
|
8619
8660
|
);
|
|
8620
8661
|
}
|
|
8621
8662
|
}
|
|
8622
8663
|
}
|
|
8623
8664
|
function displayPlan2(plan2) {
|
|
8624
8665
|
if (plan2.warnings.length > 0) {
|
|
8625
|
-
console.log(
|
|
8626
|
-
for (const w of plan2.warnings) console.log(
|
|
8666
|
+
console.log(chalk99.yellow("\nWarnings:"));
|
|
8667
|
+
for (const w of plan2.warnings) console.log(chalk99.yellow(` ${w}`));
|
|
8627
8668
|
}
|
|
8628
8669
|
if (plan2.newDirectories.length > 0) {
|
|
8629
|
-
console.log(
|
|
8670
|
+
console.log(chalk99.bold("\nNew directories:"));
|
|
8630
8671
|
for (const dir of plan2.newDirectories)
|
|
8631
|
-
console.log(
|
|
8672
|
+
console.log(chalk99.green(` ${dir}/`));
|
|
8632
8673
|
}
|
|
8633
8674
|
displayMoves(plan2);
|
|
8634
8675
|
displayRewrites(plan2.rewrites);
|
|
8635
8676
|
console.log(
|
|
8636
|
-
|
|
8677
|
+
chalk99.dim(
|
|
8637
8678
|
`
|
|
8638
8679
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8639
8680
|
)
|
|
@@ -8643,18 +8684,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8643
8684
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8644
8685
|
import fs20 from "fs";
|
|
8645
8686
|
import path42 from "path";
|
|
8646
|
-
import
|
|
8687
|
+
import chalk100 from "chalk";
|
|
8647
8688
|
function executePlan(plan2) {
|
|
8648
8689
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8649
8690
|
for (const [file, content] of updatedContents) {
|
|
8650
8691
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8651
8692
|
console.log(
|
|
8652
|
-
|
|
8693
|
+
chalk100.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8653
8694
|
);
|
|
8654
8695
|
}
|
|
8655
8696
|
for (const dir of plan2.newDirectories) {
|
|
8656
8697
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8657
|
-
console.log(
|
|
8698
|
+
console.log(chalk100.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8658
8699
|
}
|
|
8659
8700
|
for (const move of plan2.moves) {
|
|
8660
8701
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8663,7 +8704,7 @@ function executePlan(plan2) {
|
|
|
8663
8704
|
}
|
|
8664
8705
|
fs20.renameSync(move.from, move.to);
|
|
8665
8706
|
console.log(
|
|
8666
|
-
|
|
8707
|
+
chalk100.white(
|
|
8667
8708
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8668
8709
|
)
|
|
8669
8710
|
);
|
|
@@ -8678,7 +8719,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8678
8719
|
if (entries.length === 0) {
|
|
8679
8720
|
fs20.rmdirSync(dir);
|
|
8680
8721
|
console.log(
|
|
8681
|
-
|
|
8722
|
+
chalk100.dim(
|
|
8682
8723
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8683
8724
|
)
|
|
8684
8725
|
);
|
|
@@ -8811,22 +8852,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8811
8852
|
const targetPattern = pattern2 ?? "src";
|
|
8812
8853
|
const files = findSourceFiles2(targetPattern);
|
|
8813
8854
|
if (files.length === 0) {
|
|
8814
|
-
console.log(
|
|
8855
|
+
console.log(chalk101.yellow("No files found matching pattern"));
|
|
8815
8856
|
return;
|
|
8816
8857
|
}
|
|
8817
8858
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8818
8859
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8819
8860
|
if (plan2.moves.length === 0) {
|
|
8820
|
-
console.log(
|
|
8861
|
+
console.log(chalk101.green("No restructuring needed"));
|
|
8821
8862
|
return;
|
|
8822
8863
|
}
|
|
8823
8864
|
displayPlan2(plan2);
|
|
8824
8865
|
if (options2.apply) {
|
|
8825
|
-
console.log(
|
|
8866
|
+
console.log(chalk101.bold("\nApplying changes..."));
|
|
8826
8867
|
executePlan(plan2);
|
|
8827
|
-
console.log(
|
|
8868
|
+
console.log(chalk101.green("\nRestructuring complete"));
|
|
8828
8869
|
} else {
|
|
8829
|
-
console.log(
|
|
8870
|
+
console.log(chalk101.dim("\nDry run. Use --apply to execute."));
|
|
8830
8871
|
}
|
|
8831
8872
|
}
|
|
8832
8873
|
|
|
@@ -8866,7 +8907,7 @@ function registerRefactor(program2) {
|
|
|
8866
8907
|
}
|
|
8867
8908
|
|
|
8868
8909
|
// src/commands/seq/seqAuth.ts
|
|
8869
|
-
import
|
|
8910
|
+
import chalk103 from "chalk";
|
|
8870
8911
|
|
|
8871
8912
|
// src/commands/seq/loadConnections.ts
|
|
8872
8913
|
function loadConnections2() {
|
|
@@ -8895,11 +8936,11 @@ function setDefaultConnection(name) {
|
|
|
8895
8936
|
}
|
|
8896
8937
|
|
|
8897
8938
|
// src/commands/seq/promptConnection.ts
|
|
8898
|
-
import
|
|
8939
|
+
import chalk102 from "chalk";
|
|
8899
8940
|
async function promptConnection2(existingNames) {
|
|
8900
8941
|
const name = await promptInput("name", "Connection name:", "default");
|
|
8901
8942
|
if (existingNames.includes(name)) {
|
|
8902
|
-
console.error(
|
|
8943
|
+
console.error(chalk102.red(`Connection "${name}" already exists.`));
|
|
8903
8944
|
process.exit(1);
|
|
8904
8945
|
}
|
|
8905
8946
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -8911,32 +8952,32 @@ async function promptConnection2(existingNames) {
|
|
|
8911
8952
|
var seqAuth = createConnectionAuth({
|
|
8912
8953
|
load: loadConnections2,
|
|
8913
8954
|
save: saveConnections2,
|
|
8914
|
-
format: (c) => `${
|
|
8955
|
+
format: (c) => `${chalk103.bold(c.name)} ${c.url}`,
|
|
8915
8956
|
promptNew: promptConnection2,
|
|
8916
8957
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
8917
8958
|
});
|
|
8918
8959
|
|
|
8919
8960
|
// src/commands/seq/seqQuery.ts
|
|
8920
|
-
import
|
|
8961
|
+
import chalk106 from "chalk";
|
|
8921
8962
|
|
|
8922
8963
|
// src/commands/seq/formatEvent.ts
|
|
8923
|
-
import
|
|
8964
|
+
import chalk104 from "chalk";
|
|
8924
8965
|
function levelColor(level) {
|
|
8925
8966
|
switch (level) {
|
|
8926
8967
|
case "Fatal":
|
|
8927
|
-
return
|
|
8968
|
+
return chalk104.bgRed.white;
|
|
8928
8969
|
case "Error":
|
|
8929
|
-
return
|
|
8970
|
+
return chalk104.red;
|
|
8930
8971
|
case "Warning":
|
|
8931
|
-
return
|
|
8972
|
+
return chalk104.yellow;
|
|
8932
8973
|
case "Information":
|
|
8933
|
-
return
|
|
8974
|
+
return chalk104.cyan;
|
|
8934
8975
|
case "Debug":
|
|
8935
|
-
return
|
|
8976
|
+
return chalk104.gray;
|
|
8936
8977
|
case "Verbose":
|
|
8937
|
-
return
|
|
8978
|
+
return chalk104.dim;
|
|
8938
8979
|
default:
|
|
8939
|
-
return
|
|
8980
|
+
return chalk104.white;
|
|
8940
8981
|
}
|
|
8941
8982
|
}
|
|
8942
8983
|
function levelAbbrev(level) {
|
|
@@ -8977,31 +9018,31 @@ function formatTimestamp(iso) {
|
|
|
8977
9018
|
function formatEvent(event) {
|
|
8978
9019
|
const color = levelColor(event.Level);
|
|
8979
9020
|
const abbrev = levelAbbrev(event.Level);
|
|
8980
|
-
const ts8 =
|
|
9021
|
+
const ts8 = chalk104.dim(formatTimestamp(event.Timestamp));
|
|
8981
9022
|
const msg = renderMessage(event);
|
|
8982
9023
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
8983
9024
|
if (event.Exception) {
|
|
8984
9025
|
for (const line of event.Exception.split("\n")) {
|
|
8985
|
-
lines.push(
|
|
9026
|
+
lines.push(chalk104.red(` ${line}`));
|
|
8986
9027
|
}
|
|
8987
9028
|
}
|
|
8988
9029
|
return lines.join("\n");
|
|
8989
9030
|
}
|
|
8990
9031
|
|
|
8991
9032
|
// src/commands/seq/resolveConnection.ts
|
|
8992
|
-
import
|
|
9033
|
+
import chalk105 from "chalk";
|
|
8993
9034
|
function resolveConnection2(name) {
|
|
8994
9035
|
const connections = loadConnections2();
|
|
8995
9036
|
if (connections.length === 0) {
|
|
8996
9037
|
console.error(
|
|
8997
|
-
|
|
9038
|
+
chalk105.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
8998
9039
|
);
|
|
8999
9040
|
process.exit(1);
|
|
9000
9041
|
}
|
|
9001
9042
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
9002
9043
|
const connection = connections.find((c) => c.name === target);
|
|
9003
9044
|
if (!connection) {
|
|
9004
|
-
console.error(
|
|
9045
|
+
console.error(chalk105.red(`Seq connection "${target}" not found.`));
|
|
9005
9046
|
process.exit(1);
|
|
9006
9047
|
}
|
|
9007
9048
|
return connection;
|
|
@@ -9021,12 +9062,12 @@ async function seqQuery(filter, options2) {
|
|
|
9021
9062
|
});
|
|
9022
9063
|
if (!response.ok) {
|
|
9023
9064
|
const body = await response.text();
|
|
9024
|
-
console.error(
|
|
9065
|
+
console.error(chalk106.red(`Seq returned ${response.status}: ${body}`));
|
|
9025
9066
|
process.exit(1);
|
|
9026
9067
|
}
|
|
9027
9068
|
const events = await response.json();
|
|
9028
9069
|
if (events.length === 0) {
|
|
9029
|
-
console.log(
|
|
9070
|
+
console.log(chalk106.yellow("No events found."));
|
|
9030
9071
|
return;
|
|
9031
9072
|
}
|
|
9032
9073
|
if (options2.json) {
|
|
@@ -9037,11 +9078,11 @@ async function seqQuery(filter, options2) {
|
|
|
9037
9078
|
for (const event of chronological) {
|
|
9038
9079
|
console.log(formatEvent(event));
|
|
9039
9080
|
}
|
|
9040
|
-
console.log(
|
|
9081
|
+
console.log(chalk106.dim(`
|
|
9041
9082
|
${events.length} events`));
|
|
9042
9083
|
if (events.length >= count) {
|
|
9043
9084
|
console.log(
|
|
9044
|
-
|
|
9085
|
+
chalk106.yellow(
|
|
9045
9086
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
9046
9087
|
)
|
|
9047
9088
|
);
|
|
@@ -9049,11 +9090,11 @@ ${events.length} events`));
|
|
|
9049
9090
|
}
|
|
9050
9091
|
|
|
9051
9092
|
// src/commands/seq/seqSetConnection.ts
|
|
9052
|
-
import
|
|
9093
|
+
import chalk107 from "chalk";
|
|
9053
9094
|
function seqSetConnection(name) {
|
|
9054
9095
|
const connections = loadConnections2();
|
|
9055
9096
|
if (!connections.find((c) => c.name === name)) {
|
|
9056
|
-
console.error(
|
|
9097
|
+
console.error(chalk107.red(`Connection "${name}" not found.`));
|
|
9057
9098
|
process.exit(1);
|
|
9058
9099
|
}
|
|
9059
9100
|
setDefaultConnection(name);
|
|
@@ -9592,14 +9633,14 @@ import {
|
|
|
9592
9633
|
import { dirname as dirname20, join as join30 } from "path";
|
|
9593
9634
|
|
|
9594
9635
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9595
|
-
import
|
|
9636
|
+
import chalk108 from "chalk";
|
|
9596
9637
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9597
9638
|
function validateStagedContent(filename, content) {
|
|
9598
9639
|
const firstLine = content.split("\n")[0];
|
|
9599
9640
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9600
9641
|
if (!match) {
|
|
9601
9642
|
console.error(
|
|
9602
|
-
|
|
9643
|
+
chalk108.red(
|
|
9603
9644
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9604
9645
|
)
|
|
9605
9646
|
);
|
|
@@ -9608,7 +9649,7 @@ function validateStagedContent(filename, content) {
|
|
|
9608
9649
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9609
9650
|
if (!contentAfterLink) {
|
|
9610
9651
|
console.error(
|
|
9611
|
-
|
|
9652
|
+
chalk108.red(
|
|
9612
9653
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9613
9654
|
)
|
|
9614
9655
|
);
|
|
@@ -10001,7 +10042,7 @@ function registerVoice(program2) {
|
|
|
10001
10042
|
|
|
10002
10043
|
// src/commands/roam/auth.ts
|
|
10003
10044
|
import { randomBytes } from "crypto";
|
|
10004
|
-
import
|
|
10045
|
+
import chalk109 from "chalk";
|
|
10005
10046
|
|
|
10006
10047
|
// src/lib/openBrowser.ts
|
|
10007
10048
|
import { execSync as execSync38 } from "child_process";
|
|
@@ -10176,13 +10217,13 @@ async function auth() {
|
|
|
10176
10217
|
saveGlobalConfig(config);
|
|
10177
10218
|
const state = randomBytes(16).toString("hex");
|
|
10178
10219
|
console.log(
|
|
10179
|
-
|
|
10220
|
+
chalk109.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
10180
10221
|
);
|
|
10181
|
-
console.log(
|
|
10182
|
-
console.log(
|
|
10183
|
-
console.log(
|
|
10222
|
+
console.log(chalk109.white("http://localhost:14523/callback\n"));
|
|
10223
|
+
console.log(chalk109.blue("Opening browser for authorization..."));
|
|
10224
|
+
console.log(chalk109.dim("Waiting for authorization callback..."));
|
|
10184
10225
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
10185
|
-
console.log(
|
|
10226
|
+
console.log(chalk109.dim("Exchanging code for tokens..."));
|
|
10186
10227
|
const tokens = await exchangeToken({
|
|
10187
10228
|
code,
|
|
10188
10229
|
clientId,
|
|
@@ -10198,7 +10239,7 @@ async function auth() {
|
|
|
10198
10239
|
};
|
|
10199
10240
|
saveGlobalConfig(config);
|
|
10200
10241
|
console.log(
|
|
10201
|
-
|
|
10242
|
+
chalk109.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
10202
10243
|
);
|
|
10203
10244
|
}
|
|
10204
10245
|
|
|
@@ -10411,7 +10452,7 @@ import { execSync as execSync40 } from "child_process";
|
|
|
10411
10452
|
import { existsSync as existsSync40, mkdirSync as mkdirSync13, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10412
10453
|
import { tmpdir as tmpdir6 } from "os";
|
|
10413
10454
|
import { join as join39, resolve as resolve5 } from "path";
|
|
10414
|
-
import
|
|
10455
|
+
import chalk110 from "chalk";
|
|
10415
10456
|
|
|
10416
10457
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10417
10458
|
var captureWindowPs1 = `
|
|
@@ -10562,22 +10603,22 @@ function screenshot(processName) {
|
|
|
10562
10603
|
const config = loadConfig();
|
|
10563
10604
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10564
10605
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10565
|
-
console.log(
|
|
10606
|
+
console.log(chalk110.gray(`Capturing window for process "${processName}" ...`));
|
|
10566
10607
|
try {
|
|
10567
10608
|
runPowerShellScript(processName, outputPath);
|
|
10568
|
-
console.log(
|
|
10609
|
+
console.log(chalk110.green(`Screenshot saved: ${outputPath}`));
|
|
10569
10610
|
} catch (error) {
|
|
10570
10611
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10571
|
-
console.error(
|
|
10612
|
+
console.error(chalk110.red(`Failed to capture screenshot: ${msg}`));
|
|
10572
10613
|
process.exit(1);
|
|
10573
10614
|
}
|
|
10574
10615
|
}
|
|
10575
10616
|
|
|
10576
10617
|
// src/commands/statusLine.ts
|
|
10577
|
-
import
|
|
10618
|
+
import chalk112 from "chalk";
|
|
10578
10619
|
|
|
10579
10620
|
// src/commands/buildLimitsSegment.ts
|
|
10580
|
-
import
|
|
10621
|
+
import chalk111 from "chalk";
|
|
10581
10622
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10582
10623
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10583
10624
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10600,10 +10641,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10600
10641
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10601
10642
|
const label2 = `${Math.round(pct)}%`;
|
|
10602
10643
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10603
|
-
if (projected == null) return
|
|
10604
|
-
if (projected > 100) return
|
|
10605
|
-
if (projected > 75) return
|
|
10606
|
-
return
|
|
10644
|
+
if (projected == null) return chalk111.green(label2);
|
|
10645
|
+
if (projected > 100) return chalk111.red(label2);
|
|
10646
|
+
if (projected > 75) return chalk111.yellow(label2);
|
|
10647
|
+
return chalk111.green(label2);
|
|
10607
10648
|
}
|
|
10608
10649
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10609
10650
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10629,14 +10670,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10629
10670
|
}
|
|
10630
10671
|
|
|
10631
10672
|
// src/commands/statusLine.ts
|
|
10632
|
-
|
|
10673
|
+
chalk112.level = 3;
|
|
10633
10674
|
function formatNumber(num) {
|
|
10634
10675
|
return num.toLocaleString("en-US");
|
|
10635
10676
|
}
|
|
10636
10677
|
function colorizePercent(pct) {
|
|
10637
10678
|
const label2 = `${Math.round(pct)}%`;
|
|
10638
|
-
if (pct > 80) return
|
|
10639
|
-
if (pct > 40) return
|
|
10679
|
+
if (pct > 80) return chalk112.red(label2);
|
|
10680
|
+
if (pct > 40) return chalk112.yellow(label2);
|
|
10640
10681
|
return label2;
|
|
10641
10682
|
}
|
|
10642
10683
|
async function statusLine() {
|
|
@@ -10659,7 +10700,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10659
10700
|
// src/commands/sync/syncClaudeMd.ts
|
|
10660
10701
|
import * as fs23 from "fs";
|
|
10661
10702
|
import * as path46 from "path";
|
|
10662
|
-
import
|
|
10703
|
+
import chalk113 from "chalk";
|
|
10663
10704
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10664
10705
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10665
10706
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10668,12 +10709,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10668
10709
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10669
10710
|
if (sourceContent !== targetContent) {
|
|
10670
10711
|
console.log(
|
|
10671
|
-
|
|
10712
|
+
chalk113.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10672
10713
|
);
|
|
10673
10714
|
console.log();
|
|
10674
10715
|
printDiff(targetContent, sourceContent);
|
|
10675
10716
|
const confirm = options2?.yes || await promptConfirm(
|
|
10676
|
-
|
|
10717
|
+
chalk113.red("Overwrite existing CLAUDE.md?"),
|
|
10677
10718
|
false
|
|
10678
10719
|
);
|
|
10679
10720
|
if (!confirm) {
|
|
@@ -10689,7 +10730,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10689
10730
|
// src/commands/sync/syncSettings.ts
|
|
10690
10731
|
import * as fs24 from "fs";
|
|
10691
10732
|
import * as path47 from "path";
|
|
10692
|
-
import
|
|
10733
|
+
import chalk114 from "chalk";
|
|
10693
10734
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10694
10735
|
const source = path47.join(claudeDir, "settings.json");
|
|
10695
10736
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10705,14 +10746,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10705
10746
|
if (mergedContent !== normalizedTarget) {
|
|
10706
10747
|
if (!options2?.yes) {
|
|
10707
10748
|
console.log(
|
|
10708
|
-
|
|
10749
|
+
chalk114.yellow(
|
|
10709
10750
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10710
10751
|
)
|
|
10711
10752
|
);
|
|
10712
10753
|
console.log();
|
|
10713
10754
|
printDiff(targetContent, mergedContent);
|
|
10714
10755
|
const confirm = await promptConfirm(
|
|
10715
|
-
|
|
10756
|
+
chalk114.red("Overwrite existing settings.json?"),
|
|
10716
10757
|
false
|
|
10717
10758
|
);
|
|
10718
10759
|
if (!confirm) {
|
|
@@ -10730,11 +10771,13 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10730
10771
|
var __filename4 = fileURLToPath7(import.meta.url);
|
|
10731
10772
|
var __dirname7 = path48.dirname(__filename4);
|
|
10732
10773
|
async function sync(options2) {
|
|
10774
|
+
const config = loadConfig();
|
|
10775
|
+
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
10733
10776
|
const claudeDir = path48.join(__dirname7, "..", "claude");
|
|
10734
10777
|
const targetBase = path48.join(os.homedir(), ".claude");
|
|
10735
10778
|
syncCommands(claudeDir, targetBase);
|
|
10736
|
-
await syncSettings(claudeDir, targetBase, { yes
|
|
10737
|
-
await syncClaudeMd(claudeDir, targetBase, { yes
|
|
10779
|
+
await syncSettings(claudeDir, targetBase, { yes });
|
|
10780
|
+
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
10738
10781
|
}
|
|
10739
10782
|
function syncCommands(claudeDir, targetBase) {
|
|
10740
10783
|
const sourceDir = path48.join(claudeDir, "commands");
|
|
@@ -10774,12 +10817,12 @@ async function update() {
|
|
|
10774
10817
|
console.log("Building...");
|
|
10775
10818
|
execSync41("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
10776
10819
|
console.log("Syncing commands...");
|
|
10777
|
-
execSync41("assist sync
|
|
10820
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
10778
10821
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
10779
10822
|
console.log("Detected global npm installation, updating...");
|
|
10780
10823
|
execSync41("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
10781
10824
|
console.log("Syncing commands...");
|
|
10782
|
-
execSync41("assist sync
|
|
10825
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
10783
10826
|
} else {
|
|
10784
10827
|
console.error(
|
|
10785
10828
|
"Could not determine installation method. Expected a git repo or global npm install."
|
|
@@ -10795,7 +10838,7 @@ program.command("sync").description("Copy command files to ~/.claude/commands").
|
|
|
10795
10838
|
program.command("init").description("Initialize VS Code and verify configurations").action(init4);
|
|
10796
10839
|
program.command("commit").description("Create a git commit with validation").argument("<args...>", "status | <message> [files...]").action(commit);
|
|
10797
10840
|
var configCommand = program.command("config").description("View and modify assist.yml configuration");
|
|
10798
|
-
configCommand.command("set <key> <value>").description("Set a config value (e.g. commit.push true)").action(configSet);
|
|
10841
|
+
configCommand.command("set <key> <value>").description("Set a config value (e.g. commit.push true)").option("-g, --global", "Write to global ~/.assist.yml").action((key, value, options2) => configSet(key, value, options2));
|
|
10799
10842
|
configCommand.command("get <key>").description("Get a config value").action(configGet);
|
|
10800
10843
|
configCommand.command("list").description("List all config values").action(configList);
|
|
10801
10844
|
var runCommand = program.command("run").description("Run a configured command from assist.yml").argument("<name>", "Name of the configured command").argument("[args...]", "Arguments to pass to the command").allowUnknownOption().action((name, args) => {
|