@staff0rd/assist 0.158.2 → 0.160.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/claude/settings.json +7 -1
- package/dist/index.js +526 -458
- 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.160.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -1178,6 +1178,9 @@ var assistConfigSchema = z2.strictObject({
|
|
|
1178
1178
|
screenshot: z2.strictObject({
|
|
1179
1179
|
outputDir: z2.string().default("./screenshots")
|
|
1180
1180
|
}).default({ outputDir: "./screenshots" }),
|
|
1181
|
+
sync: z2.strictObject({
|
|
1182
|
+
autoConfirm: z2.boolean().default(false)
|
|
1183
|
+
}).default({ autoConfirm: false }),
|
|
1181
1184
|
voice: z2.strictObject({
|
|
1182
1185
|
wakeWords: z2.array(z2.string()).default(DEFAULT_WAKE_WORDS),
|
|
1183
1186
|
mic: z2.string().optional(),
|
|
@@ -1349,19 +1352,6 @@ function commit(args) {
|
|
|
1349
1352
|
import chalk18 from "chalk";
|
|
1350
1353
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
1351
1354
|
|
|
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
1355
|
// src/commands/config/setNestedValue.ts
|
|
1366
1356
|
function isPlainObject(val) {
|
|
1367
1357
|
return val !== null && typeof val === "object" && !Array.isArray(val);
|
|
@@ -1435,27 +1425,58 @@ function validateConfig(updated, key) {
|
|
|
1435
1425
|
if (!result.success) return exitValidationFailed(result.error.issues, key);
|
|
1436
1426
|
return updated;
|
|
1437
1427
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1428
|
+
var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
1429
|
+
function assertNotGlobalOnly(key, global) {
|
|
1430
|
+
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
1431
|
+
console.error(
|
|
1432
|
+
chalk18.red(
|
|
1433
|
+
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
1434
|
+
)
|
|
1435
|
+
);
|
|
1436
|
+
process.exit(1);
|
|
1437
|
+
}
|
|
1441
1438
|
}
|
|
1442
|
-
function
|
|
1439
|
+
function applyConfigSet(key, coerced, global) {
|
|
1440
|
+
assertNotGlobalOnly(key, global);
|
|
1441
|
+
const raw = global ? loadGlobalConfigRaw() : loadProjectConfig();
|
|
1442
|
+
const updated = setNestedValue(raw, key, coerced);
|
|
1443
|
+
validateConfig(updated, key);
|
|
1444
|
+
if (global) {
|
|
1445
|
+
saveGlobalConfig(updated);
|
|
1446
|
+
} else {
|
|
1447
|
+
saveConfig(updated);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
function configSet(key, value, options2 = {}) {
|
|
1443
1451
|
const coerced = coerceValue(value);
|
|
1444
|
-
applyConfigSet(key, coerced);
|
|
1445
|
-
|
|
1452
|
+
applyConfigSet(key, coerced, options2.global ?? false);
|
|
1453
|
+
const target = options2.global ? "global" : "project";
|
|
1454
|
+
console.log(
|
|
1455
|
+
chalk18.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
1456
|
+
);
|
|
1446
1457
|
}
|
|
1447
|
-
function
|
|
1448
|
-
|
|
1458
|
+
function configList() {
|
|
1459
|
+
const config = loadConfig();
|
|
1460
|
+
console.log(stringifyYaml3(config, { lineWidth: 0 }).trimEnd());
|
|
1449
1461
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1462
|
+
|
|
1463
|
+
// src/commands/config/configGet.ts
|
|
1464
|
+
import chalk19 from "chalk";
|
|
1465
|
+
|
|
1466
|
+
// src/commands/config/getNestedValue.ts
|
|
1467
|
+
function isTraversable(value) {
|
|
1468
|
+
return value !== null && value !== void 0 && typeof value === "object";
|
|
1453
1469
|
}
|
|
1454
|
-
function
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1470
|
+
function stepInto(current, key) {
|
|
1471
|
+
return isTraversable(current) ? current[key] : void 0;
|
|
1472
|
+
}
|
|
1473
|
+
function getNestedValue(obj, path50) {
|
|
1474
|
+
let current = obj;
|
|
1475
|
+
for (const key of path50.split(".")) current = stepInto(current, key);
|
|
1476
|
+
return current;
|
|
1458
1477
|
}
|
|
1478
|
+
|
|
1479
|
+
// src/commands/config/configGet.ts
|
|
1459
1480
|
function configGet(key) {
|
|
1460
1481
|
console.log(
|
|
1461
1482
|
formatOutput(
|
|
@@ -1463,9 +1484,17 @@ function configGet(key) {
|
|
|
1463
1484
|
)
|
|
1464
1485
|
);
|
|
1465
1486
|
}
|
|
1466
|
-
function
|
|
1467
|
-
|
|
1468
|
-
|
|
1487
|
+
function formatOutput(value) {
|
|
1488
|
+
return typeof value === "object" && value !== null ? JSON.stringify(value, null, 2) : String(value);
|
|
1489
|
+
}
|
|
1490
|
+
function requireNestedValue(config, key) {
|
|
1491
|
+
const value = getNestedValue(config, key);
|
|
1492
|
+
if (value === void 0) return exitKeyNotSet(key);
|
|
1493
|
+
return value;
|
|
1494
|
+
}
|
|
1495
|
+
function exitKeyNotSet(key) {
|
|
1496
|
+
console.error(chalk19.red(`Key "${key}" is not set`));
|
|
1497
|
+
process.exit(1);
|
|
1469
1498
|
}
|
|
1470
1499
|
|
|
1471
1500
|
// src/commands/coverage.ts
|
|
@@ -1484,10 +1513,10 @@ function coverage() {
|
|
|
1484
1513
|
}
|
|
1485
1514
|
|
|
1486
1515
|
// src/commands/verify/init/index.ts
|
|
1487
|
-
import
|
|
1516
|
+
import chalk34 from "chalk";
|
|
1488
1517
|
|
|
1489
1518
|
// src/shared/promptMultiselect.ts
|
|
1490
|
-
import
|
|
1519
|
+
import chalk20 from "chalk";
|
|
1491
1520
|
import enquirer3 from "enquirer";
|
|
1492
1521
|
async function promptMultiselect(message, options2) {
|
|
1493
1522
|
const { selected } = await exitOnCancel(
|
|
@@ -1497,7 +1526,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1497
1526
|
message,
|
|
1498
1527
|
choices: options2.map((opt) => ({
|
|
1499
1528
|
name: opt.value,
|
|
1500
|
-
message: `${opt.name} - ${
|
|
1529
|
+
message: `${opt.name} - ${chalk20.dim(opt.description)}`
|
|
1501
1530
|
})),
|
|
1502
1531
|
// @ts-expect-error - enquirer types don't include symbols but it's supported
|
|
1503
1532
|
symbols: {
|
|
@@ -1514,7 +1543,7 @@ async function promptMultiselect(message, options2) {
|
|
|
1514
1543
|
// src/shared/readPackageJson.ts
|
|
1515
1544
|
import * as fs from "fs";
|
|
1516
1545
|
import * as path from "path";
|
|
1517
|
-
import
|
|
1546
|
+
import chalk21 from "chalk";
|
|
1518
1547
|
function findPackageJson() {
|
|
1519
1548
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1520
1549
|
if (fs.existsSync(packageJsonPath)) {
|
|
@@ -1528,7 +1557,7 @@ function readPackageJson(filePath) {
|
|
|
1528
1557
|
function requirePackageJson() {
|
|
1529
1558
|
const packageJsonPath = findPackageJson();
|
|
1530
1559
|
if (!packageJsonPath) {
|
|
1531
|
-
console.error(
|
|
1560
|
+
console.error(chalk21.red("No package.json found in current directory"));
|
|
1532
1561
|
process.exit(1);
|
|
1533
1562
|
}
|
|
1534
1563
|
const pkg = readPackageJson(packageJsonPath);
|
|
@@ -1559,7 +1588,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1559
1588
|
// src/commands/verify/installPackage.ts
|
|
1560
1589
|
import { execSync as execSync3 } from "child_process";
|
|
1561
1590
|
import { writeFileSync as writeFileSync5 } from "fs";
|
|
1562
|
-
import
|
|
1591
|
+
import chalk22 from "chalk";
|
|
1563
1592
|
function writePackageJson(filePath, pkg) {
|
|
1564
1593
|
writeFileSync5(filePath, `${JSON.stringify(pkg, null, 2)}
|
|
1565
1594
|
`);
|
|
@@ -1574,12 +1603,12 @@ function addScript(pkg, name, command) {
|
|
|
1574
1603
|
};
|
|
1575
1604
|
}
|
|
1576
1605
|
function installPackage(name, cwd) {
|
|
1577
|
-
console.log(
|
|
1606
|
+
console.log(chalk22.dim(`Installing ${name}...`));
|
|
1578
1607
|
try {
|
|
1579
1608
|
execSync3(`npm install -D ${name}`, { stdio: "inherit", cwd });
|
|
1580
1609
|
return true;
|
|
1581
1610
|
} catch {
|
|
1582
|
-
console.error(
|
|
1611
|
+
console.error(chalk22.red(`Failed to install ${name}`));
|
|
1583
1612
|
return false;
|
|
1584
1613
|
}
|
|
1585
1614
|
}
|
|
@@ -1626,9 +1655,9 @@ var expectedScripts = {
|
|
|
1626
1655
|
};
|
|
1627
1656
|
|
|
1628
1657
|
// src/commands/verify/setup/setupBuild.ts
|
|
1629
|
-
import
|
|
1658
|
+
import chalk23 from "chalk";
|
|
1630
1659
|
async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
1631
|
-
console.log(
|
|
1660
|
+
console.log(chalk23.blue("\nSetting up build verification..."));
|
|
1632
1661
|
let command;
|
|
1633
1662
|
if (hasVite && hasTypescript) {
|
|
1634
1663
|
command = "tsc -b && vite build --logLevel error";
|
|
@@ -1637,21 +1666,21 @@ async function setupBuild(_packageJsonPath, writer, hasVite, hasTypescript) {
|
|
|
1637
1666
|
} else {
|
|
1638
1667
|
command = "npm run build";
|
|
1639
1668
|
}
|
|
1640
|
-
console.log(
|
|
1669
|
+
console.log(chalk23.dim(`Using: ${command}`));
|
|
1641
1670
|
writer("verify:build", command);
|
|
1642
1671
|
}
|
|
1643
1672
|
async function setupTypecheck(_packageJsonPath, writer) {
|
|
1644
|
-
console.log(
|
|
1673
|
+
console.log(chalk23.blue("\nSetting up typecheck verification..."));
|
|
1645
1674
|
const command = "tsc --noEmit";
|
|
1646
|
-
console.log(
|
|
1675
|
+
console.log(chalk23.dim(`Using: ${command}`));
|
|
1647
1676
|
writer("verify:typecheck", command);
|
|
1648
1677
|
}
|
|
1649
1678
|
|
|
1650
1679
|
// src/commands/verify/setup/setupDuplicateCode.ts
|
|
1651
1680
|
import * as path2 from "path";
|
|
1652
|
-
import
|
|
1681
|
+
import chalk24 from "chalk";
|
|
1653
1682
|
async function setupDuplicateCode(packageJsonPath, writer) {
|
|
1654
|
-
console.log(
|
|
1683
|
+
console.log(chalk24.blue("\nSetting up jscpd..."));
|
|
1655
1684
|
const cwd = path2.dirname(packageJsonPath);
|
|
1656
1685
|
const pkg = readPackageJson(packageJsonPath);
|
|
1657
1686
|
const hasJscpd = !!pkg.dependencies?.jscpd || !!pkg.devDependencies?.jscpd;
|
|
@@ -1663,12 +1692,12 @@ async function setupDuplicateCode(packageJsonPath, writer) {
|
|
|
1663
1692
|
|
|
1664
1693
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1665
1694
|
import * as path3 from "path";
|
|
1666
|
-
import
|
|
1695
|
+
import chalk26 from "chalk";
|
|
1667
1696
|
|
|
1668
1697
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
1669
1698
|
import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
1670
1699
|
import { join as join7 } from "path";
|
|
1671
|
-
import
|
|
1700
|
+
import chalk25 from "chalk";
|
|
1672
1701
|
function loadKnipConfig(knipJsonPath) {
|
|
1673
1702
|
if (existsSync9(knipJsonPath)) {
|
|
1674
1703
|
return JSON.parse(readFileSync8(knipJsonPath, "utf-8"));
|
|
@@ -1687,16 +1716,16 @@ function addToKnipIgnoreBinaries(cwd, binary) {
|
|
|
1687
1716
|
`${JSON.stringify(knipConfig, null, " ")}
|
|
1688
1717
|
`
|
|
1689
1718
|
);
|
|
1690
|
-
console.log(
|
|
1719
|
+
console.log(chalk25.dim(`Added '${binary}' to knip.json ignoreBinaries`));
|
|
1691
1720
|
}
|
|
1692
1721
|
} catch {
|
|
1693
|
-
console.log(
|
|
1722
|
+
console.log(chalk25.yellow("Warning: Could not update knip.json"));
|
|
1694
1723
|
}
|
|
1695
1724
|
}
|
|
1696
1725
|
|
|
1697
1726
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1698
1727
|
async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
1699
|
-
console.log(
|
|
1728
|
+
console.log(chalk26.blue("\nSetting up hardcoded colors check..."));
|
|
1700
1729
|
const cwd = path3.dirname(packageJsonPath);
|
|
1701
1730
|
if (!hasOpenColor) {
|
|
1702
1731
|
installPackage("open-color", cwd);
|
|
@@ -1707,9 +1736,9 @@ async function setupHardcodedColors(packageJsonPath, writer, hasOpenColor) {
|
|
|
1707
1736
|
|
|
1708
1737
|
// src/commands/verify/setup/setupKnip.ts
|
|
1709
1738
|
import * as path4 from "path";
|
|
1710
|
-
import
|
|
1739
|
+
import chalk27 from "chalk";
|
|
1711
1740
|
async function setupKnip(packageJsonPath, writer) {
|
|
1712
|
-
console.log(
|
|
1741
|
+
console.log(chalk27.blue("\nSetting up knip..."));
|
|
1713
1742
|
const cwd = path4.dirname(packageJsonPath);
|
|
1714
1743
|
const pkg = readPackageJson(packageJsonPath);
|
|
1715
1744
|
if (!pkg.devDependencies?.knip && !installPackage("knip", cwd)) {
|
|
@@ -1720,14 +1749,14 @@ async function setupKnip(packageJsonPath, writer) {
|
|
|
1720
1749
|
|
|
1721
1750
|
// src/commands/verify/setup/setupLint.ts
|
|
1722
1751
|
import * as path5 from "path";
|
|
1723
|
-
import
|
|
1752
|
+
import chalk30 from "chalk";
|
|
1724
1753
|
|
|
1725
1754
|
// src/commands/lint/init.ts
|
|
1726
1755
|
import { execSync as execSync5 } from "child_process";
|
|
1727
1756
|
import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
1728
1757
|
import { dirname as dirname7, join as join8 } from "path";
|
|
1729
1758
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1730
|
-
import
|
|
1759
|
+
import chalk29 from "chalk";
|
|
1731
1760
|
|
|
1732
1761
|
// src/shared/promptConfirm.ts
|
|
1733
1762
|
import enquirer4 from "enquirer";
|
|
@@ -1831,7 +1860,7 @@ function removeEslintScripts(scripts, options2) {
|
|
|
1831
1860
|
}
|
|
1832
1861
|
|
|
1833
1862
|
// src/utils/printDiff.ts
|
|
1834
|
-
import
|
|
1863
|
+
import chalk28 from "chalk";
|
|
1835
1864
|
import * as diff from "diff";
|
|
1836
1865
|
function normalizeJson(content) {
|
|
1837
1866
|
try {
|
|
@@ -1849,11 +1878,11 @@ function printDiff(oldContent, newContent) {
|
|
|
1849
1878
|
const lines = change.value.replace(/\n$/, "").split("\n");
|
|
1850
1879
|
for (const line of lines) {
|
|
1851
1880
|
if (change.added) {
|
|
1852
|
-
console.log(
|
|
1881
|
+
console.log(chalk28.green(`+ ${line}`));
|
|
1853
1882
|
} else if (change.removed) {
|
|
1854
|
-
console.log(
|
|
1883
|
+
console.log(chalk28.red(`- ${line}`));
|
|
1855
1884
|
} else {
|
|
1856
|
-
console.log(
|
|
1885
|
+
console.log(chalk28.dim(` ${line}`));
|
|
1857
1886
|
}
|
|
1858
1887
|
}
|
|
1859
1888
|
}
|
|
@@ -1887,10 +1916,10 @@ async function init() {
|
|
|
1887
1916
|
console.log("biome.json already has the correct linter config");
|
|
1888
1917
|
return;
|
|
1889
1918
|
}
|
|
1890
|
-
console.log(
|
|
1919
|
+
console.log(chalk29.yellow("\n\u26A0\uFE0F biome.json will be updated:"));
|
|
1891
1920
|
console.log();
|
|
1892
1921
|
printDiff(oldContent, newContent);
|
|
1893
|
-
const confirm = await promptConfirm(
|
|
1922
|
+
const confirm = await promptConfirm(chalk29.red("Update biome.json?"));
|
|
1894
1923
|
if (!confirm) {
|
|
1895
1924
|
console.log("Skipped biome.json update");
|
|
1896
1925
|
return;
|
|
@@ -1901,7 +1930,7 @@ async function init() {
|
|
|
1901
1930
|
|
|
1902
1931
|
// src/commands/verify/setup/setupLint.ts
|
|
1903
1932
|
async function setupLint(packageJsonPath, writer) {
|
|
1904
|
-
console.log(
|
|
1933
|
+
console.log(chalk30.blue("\nSetting up biome..."));
|
|
1905
1934
|
const cwd = path5.dirname(packageJsonPath);
|
|
1906
1935
|
const pkg = readPackageJson(packageJsonPath);
|
|
1907
1936
|
if (!pkg.devDependencies?.["@biomejs/biome"]) {
|
|
@@ -1915,9 +1944,9 @@ async function setupLint(packageJsonPath, writer) {
|
|
|
1915
1944
|
|
|
1916
1945
|
// src/commands/verify/setup/setupMadge.ts
|
|
1917
1946
|
import * as path6 from "path";
|
|
1918
|
-
import
|
|
1947
|
+
import chalk31 from "chalk";
|
|
1919
1948
|
async function setupMadge(packageJsonPath, writer) {
|
|
1920
|
-
console.log(
|
|
1949
|
+
console.log(chalk31.blue("\nSetting up madge..."));
|
|
1921
1950
|
const cwd = path6.dirname(packageJsonPath);
|
|
1922
1951
|
const pkg = readPackageJson(packageJsonPath);
|
|
1923
1952
|
const hasMadge = !!pkg.dependencies?.madge || !!pkg.devDependencies?.madge;
|
|
@@ -1929,18 +1958,18 @@ async function setupMadge(packageJsonPath, writer) {
|
|
|
1929
1958
|
|
|
1930
1959
|
// src/commands/verify/setup/setupMaintainability.ts
|
|
1931
1960
|
import * as path7 from "path";
|
|
1932
|
-
import
|
|
1961
|
+
import chalk32 from "chalk";
|
|
1933
1962
|
async function setupMaintainability(packageJsonPath, writer) {
|
|
1934
|
-
console.log(
|
|
1963
|
+
console.log(chalk32.blue("\nSetting up maintainability check..."));
|
|
1935
1964
|
addToKnipIgnoreBinaries(path7.dirname(packageJsonPath), "assist");
|
|
1936
1965
|
writer("verify:maintainability", expectedScripts["verify:maintainability"]);
|
|
1937
1966
|
}
|
|
1938
1967
|
|
|
1939
1968
|
// src/commands/verify/setup/setupTest.ts
|
|
1940
1969
|
import * as path8 from "path";
|
|
1941
|
-
import
|
|
1970
|
+
import chalk33 from "chalk";
|
|
1942
1971
|
async function setupTest(packageJsonPath, writer) {
|
|
1943
|
-
console.log(
|
|
1972
|
+
console.log(chalk33.blue("\nSetting up vitest..."));
|
|
1944
1973
|
const cwd = path8.dirname(packageJsonPath);
|
|
1945
1974
|
const pkg = readPackageJson(packageJsonPath);
|
|
1946
1975
|
if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
|
|
@@ -2109,25 +2138,25 @@ async function runSelectedSetups(selected, packageJsonPath, writer, handlers) {
|
|
|
2109
2138
|
for (const choice of selected) {
|
|
2110
2139
|
await handlers[choice]?.(packageJsonPath, writer);
|
|
2111
2140
|
}
|
|
2112
|
-
console.log(
|
|
2141
|
+
console.log(chalk34.green(`
|
|
2113
2142
|
Added ${selected.length} verify script(s):`));
|
|
2114
2143
|
for (const choice of selected) {
|
|
2115
|
-
console.log(
|
|
2144
|
+
console.log(chalk34.green(` - verify:${choice}`));
|
|
2116
2145
|
}
|
|
2117
|
-
console.log(
|
|
2146
|
+
console.log(chalk34.dim("\nRun 'assist verify' to run all verify scripts"));
|
|
2118
2147
|
}
|
|
2119
2148
|
async function promptForScripts(availableOptions) {
|
|
2120
2149
|
if (availableOptions.length === 0) {
|
|
2121
|
-
console.log(
|
|
2150
|
+
console.log(chalk34.green("All verify scripts are already configured!"));
|
|
2122
2151
|
return null;
|
|
2123
2152
|
}
|
|
2124
|
-
console.log(
|
|
2153
|
+
console.log(chalk34.bold("Available verify scripts to add:\n"));
|
|
2125
2154
|
const selected = await promptMultiselect(
|
|
2126
2155
|
"Select verify scripts to add:",
|
|
2127
2156
|
availableOptions
|
|
2128
2157
|
);
|
|
2129
2158
|
if (selected.length === 0) {
|
|
2130
|
-
console.log(
|
|
2159
|
+
console.log(chalk34.yellow("No scripts selected"));
|
|
2131
2160
|
return null;
|
|
2132
2161
|
}
|
|
2133
2162
|
return selected;
|
|
@@ -2147,17 +2176,17 @@ async function init2() {
|
|
|
2147
2176
|
}
|
|
2148
2177
|
|
|
2149
2178
|
// src/commands/vscode/init/index.ts
|
|
2150
|
-
import
|
|
2179
|
+
import chalk36 from "chalk";
|
|
2151
2180
|
|
|
2152
2181
|
// src/commands/vscode/init/createLaunchJson.ts
|
|
2153
2182
|
import * as fs2 from "fs";
|
|
2154
2183
|
import * as path9 from "path";
|
|
2155
|
-
import
|
|
2184
|
+
import chalk35 from "chalk";
|
|
2156
2185
|
function ensureVscodeFolder() {
|
|
2157
2186
|
const vscodeDir = path9.join(process.cwd(), ".vscode");
|
|
2158
2187
|
if (!fs2.existsSync(vscodeDir)) {
|
|
2159
2188
|
fs2.mkdirSync(vscodeDir);
|
|
2160
|
-
console.log(
|
|
2189
|
+
console.log(chalk35.dim("Created .vscode folder"));
|
|
2161
2190
|
}
|
|
2162
2191
|
}
|
|
2163
2192
|
function removeVscodeFromGitignore() {
|
|
@@ -2172,7 +2201,7 @@ function removeVscodeFromGitignore() {
|
|
|
2172
2201
|
);
|
|
2173
2202
|
if (filteredLines.length !== lines.length) {
|
|
2174
2203
|
fs2.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
2175
|
-
console.log(
|
|
2204
|
+
console.log(chalk35.dim("Removed .vscode references from .gitignore"));
|
|
2176
2205
|
}
|
|
2177
2206
|
}
|
|
2178
2207
|
function createLaunchJson(type) {
|
|
@@ -2191,7 +2220,7 @@ function createLaunchJson(type) {
|
|
|
2191
2220
|
const launchPath = path9.join(process.cwd(), ".vscode", "launch.json");
|
|
2192
2221
|
fs2.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
|
|
2193
2222
|
`);
|
|
2194
|
-
console.log(
|
|
2223
|
+
console.log(chalk35.green("Created .vscode/launch.json"));
|
|
2195
2224
|
}
|
|
2196
2225
|
function createSettingsJson() {
|
|
2197
2226
|
const settings = {
|
|
@@ -2204,7 +2233,7 @@ function createSettingsJson() {
|
|
|
2204
2233
|
const settingsPath = path9.join(process.cwd(), ".vscode", "settings.json");
|
|
2205
2234
|
fs2.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
|
|
2206
2235
|
`);
|
|
2207
|
-
console.log(
|
|
2236
|
+
console.log(chalk35.green("Created .vscode/settings.json"));
|
|
2208
2237
|
}
|
|
2209
2238
|
function createExtensionsJson() {
|
|
2210
2239
|
const extensions = {
|
|
@@ -2216,7 +2245,7 @@ function createExtensionsJson() {
|
|
|
2216
2245
|
`${JSON.stringify(extensions, null, " ")}
|
|
2217
2246
|
`
|
|
2218
2247
|
);
|
|
2219
|
-
console.log(
|
|
2248
|
+
console.log(chalk35.green("Created .vscode/extensions.json"));
|
|
2220
2249
|
}
|
|
2221
2250
|
|
|
2222
2251
|
// src/commands/vscode/init/detectVscodeSetup.ts
|
|
@@ -2273,7 +2302,7 @@ function applySelections(selected, setup2) {
|
|
|
2273
2302
|
for (const choice of selected) handlers[choice]?.();
|
|
2274
2303
|
}
|
|
2275
2304
|
async function promptForOptions(options2) {
|
|
2276
|
-
console.log(
|
|
2305
|
+
console.log(chalk36.bold("Available VS Code configurations to add:\n"));
|
|
2277
2306
|
return promptMultiselect("Select configurations to add:", options2);
|
|
2278
2307
|
}
|
|
2279
2308
|
async function init3({ all = false } = {}) {
|
|
@@ -2281,17 +2310,17 @@ async function init3({ all = false } = {}) {
|
|
|
2281
2310
|
const setup2 = detectVscodeSetup(pkg);
|
|
2282
2311
|
const options2 = getAvailableOptions2(setup2);
|
|
2283
2312
|
if (options2.length === 0) {
|
|
2284
|
-
console.log(
|
|
2313
|
+
console.log(chalk36.green("VS Code configuration already exists!"));
|
|
2285
2314
|
return;
|
|
2286
2315
|
}
|
|
2287
2316
|
const selected = all ? options2.map((o) => o.value) : await promptForOptions(options2);
|
|
2288
2317
|
if (selected.length === 0) {
|
|
2289
|
-
console.log(
|
|
2318
|
+
console.log(chalk36.yellow("No configurations selected"));
|
|
2290
2319
|
return;
|
|
2291
2320
|
}
|
|
2292
2321
|
applySelections(selected, setup2);
|
|
2293
2322
|
console.log(
|
|
2294
|
-
|
|
2323
|
+
chalk36.green(`
|
|
2295
2324
|
Added ${selected.length} VS Code configuration(s)`)
|
|
2296
2325
|
);
|
|
2297
2326
|
}
|
|
@@ -2304,7 +2333,7 @@ async function init4() {
|
|
|
2304
2333
|
|
|
2305
2334
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2306
2335
|
import path16 from "path";
|
|
2307
|
-
import
|
|
2336
|
+
import chalk38 from "chalk";
|
|
2308
2337
|
|
|
2309
2338
|
// src/commands/lint/lint/checkFileNames.ts
|
|
2310
2339
|
import fs5 from "fs";
|
|
@@ -2384,7 +2413,7 @@ function checkFileNames() {
|
|
|
2384
2413
|
}
|
|
2385
2414
|
|
|
2386
2415
|
// src/commands/lint/lint/fixFileNameViolations.ts
|
|
2387
|
-
import
|
|
2416
|
+
import chalk37 from "chalk";
|
|
2388
2417
|
|
|
2389
2418
|
// src/commands/lint/lint/applyMoves.ts
|
|
2390
2419
|
import fs6 from "fs";
|
|
@@ -2469,25 +2498,25 @@ function fixFileNameViolations(moves) {
|
|
|
2469
2498
|
const start3 = performance.now();
|
|
2470
2499
|
const project = createLintProject();
|
|
2471
2500
|
const cwd = process.cwd();
|
|
2472
|
-
applyMoves(project, moves, cwd, (line) => console.log(
|
|
2501
|
+
applyMoves(project, moves, cwd, (line) => console.log(chalk37.green(line)));
|
|
2473
2502
|
const ms = (performance.now() - start3).toFixed(0);
|
|
2474
|
-
console.log(
|
|
2503
|
+
console.log(chalk37.dim(` Done in ${ms}ms`));
|
|
2475
2504
|
}
|
|
2476
2505
|
|
|
2477
2506
|
// src/commands/lint/lint/runFileNameCheck.ts
|
|
2478
2507
|
function reportViolations(violations) {
|
|
2479
|
-
console.error(
|
|
2508
|
+
console.error(chalk38.red("\nFile name check failed:\n"));
|
|
2480
2509
|
console.error(
|
|
2481
|
-
|
|
2510
|
+
chalk38.red(
|
|
2482
2511
|
" Files without classes or React components should not start with a capital letter.\n"
|
|
2483
2512
|
)
|
|
2484
2513
|
);
|
|
2485
2514
|
for (const violation of violations) {
|
|
2486
|
-
console.error(
|
|
2487
|
-
console.error(
|
|
2515
|
+
console.error(chalk38.red(` ${violation.filePath}`));
|
|
2516
|
+
console.error(chalk38.gray(` Rename to: ${violation.suggestedName}
|
|
2488
2517
|
`));
|
|
2489
2518
|
}
|
|
2490
|
-
console.error(
|
|
2519
|
+
console.error(chalk38.dim(" Run with -f to auto-fix.\n"));
|
|
2491
2520
|
}
|
|
2492
2521
|
function runFileNameCheck(fix = false) {
|
|
2493
2522
|
const violations = checkFileNames();
|
|
@@ -2516,17 +2545,17 @@ function runFileNameCheck(fix = false) {
|
|
|
2516
2545
|
import fs8 from "fs";
|
|
2517
2546
|
|
|
2518
2547
|
// src/commands/lint/shared.ts
|
|
2519
|
-
import
|
|
2548
|
+
import chalk39 from "chalk";
|
|
2520
2549
|
function reportViolations2(violations, checkName, errorMessage, successMessage) {
|
|
2521
2550
|
if (violations.length > 0) {
|
|
2522
|
-
console.error(
|
|
2551
|
+
console.error(chalk39.red(`
|
|
2523
2552
|
${checkName} failed:
|
|
2524
2553
|
`));
|
|
2525
|
-
console.error(
|
|
2554
|
+
console.error(chalk39.red(` ${errorMessage}
|
|
2526
2555
|
`));
|
|
2527
2556
|
for (const violation of violations) {
|
|
2528
|
-
console.error(
|
|
2529
|
-
console.error(
|
|
2557
|
+
console.error(chalk39.red(` ${violation.filePath}:${violation.line}`));
|
|
2558
|
+
console.error(chalk39.gray(` ${violation.content}
|
|
2530
2559
|
`));
|
|
2531
2560
|
}
|
|
2532
2561
|
return false;
|
|
@@ -3006,14 +3035,14 @@ import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSy
|
|
|
3006
3035
|
|
|
3007
3036
|
// src/commands/deploy/init/index.ts
|
|
3008
3037
|
import { execSync as execSync12 } from "child_process";
|
|
3009
|
-
import
|
|
3038
|
+
import chalk41 from "chalk";
|
|
3010
3039
|
import enquirer5 from "enquirer";
|
|
3011
3040
|
|
|
3012
3041
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
3013
3042
|
import { existsSync as existsSync15, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
3014
3043
|
import { dirname as dirname13, join as join11 } from "path";
|
|
3015
3044
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3016
|
-
import
|
|
3045
|
+
import chalk40 from "chalk";
|
|
3017
3046
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
3018
3047
|
var __dirname3 = dirname13(fileURLToPath3(import.meta.url));
|
|
3019
3048
|
function getExistingSiteId() {
|
|
@@ -3038,20 +3067,20 @@ async function updateWorkflow(siteId) {
|
|
|
3038
3067
|
if (existsSync15(WORKFLOW_PATH)) {
|
|
3039
3068
|
const oldContent = readFileSync12(WORKFLOW_PATH, "utf-8");
|
|
3040
3069
|
if (oldContent === newContent) {
|
|
3041
|
-
console.log(
|
|
3070
|
+
console.log(chalk40.green("build.yml is already up to date"));
|
|
3042
3071
|
return;
|
|
3043
3072
|
}
|
|
3044
|
-
console.log(
|
|
3073
|
+
console.log(chalk40.yellow("\nbuild.yml will be updated:"));
|
|
3045
3074
|
console.log();
|
|
3046
3075
|
printDiff(oldContent, newContent);
|
|
3047
|
-
const confirm = await promptConfirm(
|
|
3076
|
+
const confirm = await promptConfirm(chalk40.red("Update build.yml?"));
|
|
3048
3077
|
if (!confirm) {
|
|
3049
3078
|
console.log("Skipped build.yml update");
|
|
3050
3079
|
return;
|
|
3051
3080
|
}
|
|
3052
3081
|
}
|
|
3053
3082
|
writeFileSync12(WORKFLOW_PATH, newContent);
|
|
3054
|
-
console.log(
|
|
3083
|
+
console.log(chalk40.green(`
|
|
3055
3084
|
Created ${WORKFLOW_PATH}`));
|
|
3056
3085
|
}
|
|
3057
3086
|
|
|
@@ -3062,43 +3091,43 @@ async function ensureNetlifyCli() {
|
|
|
3062
3091
|
} catch (error) {
|
|
3063
3092
|
if (!(error instanceof Error) || !error.message.includes("command not found"))
|
|
3064
3093
|
throw error;
|
|
3065
|
-
console.error(
|
|
3094
|
+
console.error(chalk41.red("\nNetlify CLI is not installed.\n"));
|
|
3066
3095
|
const install = await promptConfirm("Would you like to install it now?");
|
|
3067
3096
|
if (!install) {
|
|
3068
3097
|
console.log(
|
|
3069
|
-
|
|
3098
|
+
chalk41.yellow(
|
|
3070
3099
|
"\nInstall it manually with: npm install -g netlify-cli\n"
|
|
3071
3100
|
)
|
|
3072
3101
|
);
|
|
3073
3102
|
process.exit(1);
|
|
3074
3103
|
}
|
|
3075
|
-
console.log(
|
|
3104
|
+
console.log(chalk41.dim("\nInstalling netlify-cli...\n"));
|
|
3076
3105
|
execSync12("npm install -g netlify-cli", { stdio: "inherit" });
|
|
3077
3106
|
console.log();
|
|
3078
3107
|
execSync12("netlify sites:create --disable-linking", { stdio: "inherit" });
|
|
3079
3108
|
}
|
|
3080
3109
|
}
|
|
3081
3110
|
function printSetupInstructions() {
|
|
3082
|
-
console.log(
|
|
3111
|
+
console.log(chalk41.bold("\nDeployment initialized successfully!"));
|
|
3083
3112
|
console.log(
|
|
3084
|
-
|
|
3113
|
+
chalk41.yellow("\nTo complete setup, create a personal access token at:")
|
|
3085
3114
|
);
|
|
3086
3115
|
console.log(
|
|
3087
|
-
|
|
3116
|
+
chalk41.cyan(
|
|
3088
3117
|
"https://app.netlify.com/user/applications#personal-access-tokens"
|
|
3089
3118
|
)
|
|
3090
3119
|
);
|
|
3091
3120
|
console.log(
|
|
3092
|
-
|
|
3121
|
+
chalk41.yellow(
|
|
3093
3122
|
"\nThen add it as NETLIFY_AUTH_TOKEN in your GitHub repository secrets."
|
|
3094
3123
|
)
|
|
3095
3124
|
);
|
|
3096
3125
|
}
|
|
3097
3126
|
async function init5() {
|
|
3098
|
-
console.log(
|
|
3127
|
+
console.log(chalk41.bold("Initializing Netlify deployment...\n"));
|
|
3099
3128
|
const existingSiteId = getExistingSiteId();
|
|
3100
3129
|
if (existingSiteId) {
|
|
3101
|
-
console.log(
|
|
3130
|
+
console.log(chalk41.dim(`Using existing site ID: ${existingSiteId}
|
|
3102
3131
|
`));
|
|
3103
3132
|
await updateWorkflow(existingSiteId);
|
|
3104
3133
|
return;
|
|
@@ -3277,27 +3306,27 @@ async function notify() {
|
|
|
3277
3306
|
}
|
|
3278
3307
|
|
|
3279
3308
|
// src/commands/backlog/comment/index.ts
|
|
3280
|
-
import
|
|
3309
|
+
import chalk42 from "chalk";
|
|
3281
3310
|
function comment(id, text) {
|
|
3282
3311
|
const result = loadAndFindItem(id);
|
|
3283
3312
|
if (!result) process.exit(1);
|
|
3284
3313
|
addComment(result.item, text);
|
|
3285
3314
|
saveBacklog(result.items);
|
|
3286
|
-
console.log(
|
|
3315
|
+
console.log(chalk42.green(`Comment added to item #${id}.`));
|
|
3287
3316
|
}
|
|
3288
3317
|
|
|
3289
3318
|
// src/commands/backlog/comments/index.ts
|
|
3290
|
-
import
|
|
3319
|
+
import chalk43 from "chalk";
|
|
3291
3320
|
function comments(id) {
|
|
3292
3321
|
const result = loadAndFindItem(id);
|
|
3293
3322
|
if (!result) process.exit(1);
|
|
3294
3323
|
const { item } = result;
|
|
3295
3324
|
const entries = item.comments ?? [];
|
|
3296
3325
|
if (entries.length === 0) {
|
|
3297
|
-
console.log(
|
|
3326
|
+
console.log(chalk43.dim(`No comments on item #${id}.`));
|
|
3298
3327
|
return;
|
|
3299
3328
|
}
|
|
3300
|
-
console.log(
|
|
3329
|
+
console.log(chalk43.bold(`Comments for #${id}: ${item.name}
|
|
3301
3330
|
`));
|
|
3302
3331
|
for (const entry of entries) {
|
|
3303
3332
|
console.log(`${formatComment(entry)}
|
|
@@ -3313,11 +3342,11 @@ function registerCommentCommands(cmd) {
|
|
|
3313
3342
|
|
|
3314
3343
|
// src/commands/backlog/add/index.ts
|
|
3315
3344
|
import { existsSync as existsSync17 } from "fs";
|
|
3316
|
-
import
|
|
3345
|
+
import chalk45 from "chalk";
|
|
3317
3346
|
|
|
3318
3347
|
// src/commands/backlog/commitBacklog.ts
|
|
3319
3348
|
import { execSync as execSync14 } from "child_process";
|
|
3320
|
-
import
|
|
3349
|
+
import chalk44 from "chalk";
|
|
3321
3350
|
function commitBacklog(id, name) {
|
|
3322
3351
|
try {
|
|
3323
3352
|
const backlogPath = getBacklogPath();
|
|
@@ -3325,7 +3354,7 @@ function commitBacklog(id, name) {
|
|
|
3325
3354
|
execSync14(`git add ${shellQuote(backlogPath)}`, { stdio: "ignore" });
|
|
3326
3355
|
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3327
3356
|
} catch {
|
|
3328
|
-
console.log(
|
|
3357
|
+
console.log(chalk44.yellow("Warning: could not auto-commit backlog file."));
|
|
3329
3358
|
}
|
|
3330
3359
|
}
|
|
3331
3360
|
|
|
@@ -3403,7 +3432,7 @@ async function promptAcceptanceCriteria() {
|
|
|
3403
3432
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3404
3433
|
async function addFromJson() {
|
|
3405
3434
|
if (process.stdin.isTTY) {
|
|
3406
|
-
console.log(
|
|
3435
|
+
console.log(chalk45.red("--json requires piped input on stdin."));
|
|
3407
3436
|
return;
|
|
3408
3437
|
}
|
|
3409
3438
|
const input = await readStdin();
|
|
@@ -3417,7 +3446,7 @@ async function addFromJson() {
|
|
|
3417
3446
|
items.push({ ...data, id, status: "todo" });
|
|
3418
3447
|
saveBacklog(items);
|
|
3419
3448
|
commitBacklog(id, data.name);
|
|
3420
|
-
console.log(
|
|
3449
|
+
console.log(chalk45.green(`Added item #${id}: ${data.name}`));
|
|
3421
3450
|
}
|
|
3422
3451
|
async function addInteractive() {
|
|
3423
3452
|
const type = await promptType();
|
|
@@ -3436,12 +3465,12 @@ async function addInteractive() {
|
|
|
3436
3465
|
});
|
|
3437
3466
|
saveBacklog(items);
|
|
3438
3467
|
commitBacklog(id, name);
|
|
3439
|
-
console.log(
|
|
3468
|
+
console.log(chalk45.green(`Added item #${id}: ${name}`));
|
|
3440
3469
|
}
|
|
3441
3470
|
async function add(options2) {
|
|
3442
3471
|
if (!existsSync17(getBacklogPath())) {
|
|
3443
3472
|
console.log(
|
|
3444
|
-
|
|
3473
|
+
chalk45.yellow(
|
|
3445
3474
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3446
3475
|
)
|
|
3447
3476
|
);
|
|
@@ -3456,20 +3485,20 @@ async function add(options2) {
|
|
|
3456
3485
|
|
|
3457
3486
|
// src/commands/backlog/init/index.ts
|
|
3458
3487
|
import { existsSync as existsSync18 } from "fs";
|
|
3459
|
-
import
|
|
3488
|
+
import chalk46 from "chalk";
|
|
3460
3489
|
async function init6() {
|
|
3461
3490
|
const backlogPath = getBacklogPath();
|
|
3462
3491
|
if (existsSync18(backlogPath)) {
|
|
3463
|
-
console.log(
|
|
3492
|
+
console.log(chalk46.yellow("assist.backlog.yml already exists."));
|
|
3464
3493
|
return;
|
|
3465
3494
|
}
|
|
3466
3495
|
saveBacklog([]);
|
|
3467
|
-
console.log(
|
|
3496
|
+
console.log(chalk46.green("Created assist.backlog.yml"));
|
|
3468
3497
|
}
|
|
3469
3498
|
|
|
3470
3499
|
// src/commands/backlog/list/index.ts
|
|
3471
3500
|
import { existsSync as existsSync19 } from "fs";
|
|
3472
|
-
import
|
|
3501
|
+
import chalk47 from "chalk";
|
|
3473
3502
|
function filterItems(items, options2) {
|
|
3474
3503
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3475
3504
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
@@ -3478,7 +3507,7 @@ function filterItems(items, options2) {
|
|
|
3478
3507
|
async function list2(options2) {
|
|
3479
3508
|
if (!existsSync19(getBacklogPath())) {
|
|
3480
3509
|
console.log(
|
|
3481
|
-
|
|
3510
|
+
chalk47.yellow(
|
|
3482
3511
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3483
3512
|
)
|
|
3484
3513
|
);
|
|
@@ -3486,12 +3515,12 @@ async function list2(options2) {
|
|
|
3486
3515
|
}
|
|
3487
3516
|
const items = filterItems(loadBacklog(), options2);
|
|
3488
3517
|
if (items.length === 0) {
|
|
3489
|
-
console.log(
|
|
3518
|
+
console.log(chalk47.dim("Backlog is empty."));
|
|
3490
3519
|
return;
|
|
3491
3520
|
}
|
|
3492
3521
|
for (const item of items) {
|
|
3493
3522
|
console.log(
|
|
3494
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3523
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk47.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
|
|
3495
3524
|
);
|
|
3496
3525
|
if (options2.verbose) {
|
|
3497
3526
|
printVerboseDetails(item);
|
|
@@ -3666,23 +3695,39 @@ function findCliRead(command) {
|
|
|
3666
3695
|
return candidates.sort((a, b) => b.length - a.length).find((rc) => command === rc || command.startsWith(`${rc} `));
|
|
3667
3696
|
}
|
|
3668
3697
|
|
|
3669
|
-
// src/shared/
|
|
3698
|
+
// src/shared/matchesAllow.ts
|
|
3670
3699
|
import { existsSync as existsSync21, readFileSync as readFileSync16 } from "fs";
|
|
3671
3700
|
import { homedir as homedir3 } from "os";
|
|
3672
3701
|
import { join as join13 } from "path";
|
|
3673
|
-
var
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3702
|
+
var allowCache;
|
|
3703
|
+
var denyCache;
|
|
3704
|
+
var TOOL_RE = /^(Bash|PowerShell)\((.+?)(?::.*)\)$/;
|
|
3705
|
+
function loadPrefixes(key) {
|
|
3706
|
+
const entries = collectEntries(key);
|
|
3707
|
+
return parsePrefixes(entries);
|
|
3708
|
+
}
|
|
3709
|
+
var SHELL_TOOLS = ["Bash", "PowerShell"];
|
|
3710
|
+
function shellPrefixes(map, toolName) {
|
|
3711
|
+
if (SHELL_TOOLS.includes(toolName)) {
|
|
3712
|
+
return SHELL_TOOLS.flatMap((t) => map.get(t) ?? []);
|
|
3713
|
+
}
|
|
3714
|
+
return map.get(toolName) ?? [];
|
|
3715
|
+
}
|
|
3716
|
+
function matchesAllow(toolName, command) {
|
|
3717
|
+
if (!allowCache) allowCache = loadPrefixes("allow");
|
|
3718
|
+
const prefixes = shellPrefixes(allowCache, toolName);
|
|
3719
|
+
return prefixes.find(
|
|
3720
|
+
(pfx) => command === pfx || command.startsWith(`${pfx} `)
|
|
3721
|
+
);
|
|
3722
|
+
}
|
|
3723
|
+
function matchesDeny(toolName, command) {
|
|
3724
|
+
if (!denyCache) denyCache = loadPrefixes("deny");
|
|
3725
|
+
const prefixes = shellPrefixes(denyCache, toolName);
|
|
3681
3726
|
return prefixes.find(
|
|
3682
3727
|
(pfx) => command === pfx || command.startsWith(`${pfx} `)
|
|
3683
3728
|
);
|
|
3684
3729
|
}
|
|
3685
|
-
function
|
|
3730
|
+
function collectEntries(key) {
|
|
3686
3731
|
const paths = [
|
|
3687
3732
|
join13(homedir3(), ".claude", "settings.json"),
|
|
3688
3733
|
join13(process.cwd(), ".claude", "settings.json"),
|
|
@@ -3690,37 +3735,42 @@ function collectAllowEntries() {
|
|
|
3690
3735
|
];
|
|
3691
3736
|
const entries = [];
|
|
3692
3737
|
for (const p of paths) {
|
|
3693
|
-
entries.push(...
|
|
3738
|
+
entries.push(...readPermissionArray(p, key));
|
|
3694
3739
|
}
|
|
3695
3740
|
return entries;
|
|
3696
3741
|
}
|
|
3697
|
-
function
|
|
3742
|
+
function readPermissionArray(filePath, key) {
|
|
3698
3743
|
if (!existsSync21(filePath)) return [];
|
|
3699
3744
|
try {
|
|
3700
3745
|
const data = JSON.parse(readFileSync16(filePath, "utf-8"));
|
|
3701
|
-
const
|
|
3702
|
-
return Array.isArray(
|
|
3746
|
+
const arr = data?.permissions?.[key];
|
|
3747
|
+
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
3703
3748
|
} catch {
|
|
3704
3749
|
return [];
|
|
3705
3750
|
}
|
|
3706
3751
|
}
|
|
3707
3752
|
function parsePrefixes(entries) {
|
|
3708
|
-
const
|
|
3709
|
-
const prefixes = [];
|
|
3753
|
+
const map = /* @__PURE__ */ new Map();
|
|
3710
3754
|
for (const entry of entries) {
|
|
3711
|
-
const m = entry.match(
|
|
3712
|
-
if (m)
|
|
3755
|
+
const m = entry.match(TOOL_RE);
|
|
3756
|
+
if (m) {
|
|
3757
|
+
const tool = m[1];
|
|
3758
|
+
const prefix2 = m[2];
|
|
3759
|
+
const list4 = map.get(tool) ?? [];
|
|
3760
|
+
list4.push(prefix2);
|
|
3761
|
+
map.set(tool, list4);
|
|
3762
|
+
}
|
|
3713
3763
|
}
|
|
3714
|
-
return
|
|
3764
|
+
return map;
|
|
3715
3765
|
}
|
|
3716
3766
|
|
|
3717
3767
|
// src/shared/isApprovedRead.ts
|
|
3718
|
-
function isApprovedRead(command) {
|
|
3768
|
+
function isApprovedRead(command, toolName = "Bash") {
|
|
3719
3769
|
if (isCdToCwd(command)) return "cd to current directory";
|
|
3720
3770
|
const matched = findCliRead(command);
|
|
3721
3771
|
if (matched) return `Read-only CLI command: ${matched}`;
|
|
3722
3772
|
if (isGhApiRead(command)) return "Read-only gh api command";
|
|
3723
|
-
const allowMatch =
|
|
3773
|
+
const allowMatch = matchesAllow(toolName, command);
|
|
3724
3774
|
if (allowMatch) return `Allowed by settings: ${allowMatch}`;
|
|
3725
3775
|
return void 0;
|
|
3726
3776
|
}
|
|
@@ -3792,6 +3842,28 @@ function stripEnvPrefix(parts) {
|
|
|
3792
3842
|
}
|
|
3793
3843
|
|
|
3794
3844
|
// src/commands/cliHook/index.ts
|
|
3845
|
+
var SUPPORTED_TOOLS = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
3846
|
+
function resolvePermission(toolName, parts) {
|
|
3847
|
+
for (const part of parts) {
|
|
3848
|
+
const denied = matchesDeny(toolName, part);
|
|
3849
|
+
if (denied) {
|
|
3850
|
+
return {
|
|
3851
|
+
permissionDecision: "deny",
|
|
3852
|
+
permissionDecisionReason: `Denied by settings: ${denied}`
|
|
3853
|
+
};
|
|
3854
|
+
}
|
|
3855
|
+
}
|
|
3856
|
+
const reasons = [];
|
|
3857
|
+
for (const part of parts) {
|
|
3858
|
+
const reason = isApprovedRead(part, toolName);
|
|
3859
|
+
if (!reason) return void 0;
|
|
3860
|
+
reasons.push(reason);
|
|
3861
|
+
}
|
|
3862
|
+
return {
|
|
3863
|
+
permissionDecision: "allow",
|
|
3864
|
+
permissionDecisionReason: reasons.join("; ")
|
|
3865
|
+
};
|
|
3866
|
+
}
|
|
3795
3867
|
async function cliHook() {
|
|
3796
3868
|
const inputData = await readStdin2();
|
|
3797
3869
|
let data;
|
|
@@ -3800,24 +3872,18 @@ async function cliHook() {
|
|
|
3800
3872
|
} catch {
|
|
3801
3873
|
return;
|
|
3802
3874
|
}
|
|
3803
|
-
if (data.tool_name
|
|
3875
|
+
if (!SUPPORTED_TOOLS.has(data.tool_name) || !data.tool_input?.command) {
|
|
3804
3876
|
return;
|
|
3805
3877
|
}
|
|
3806
|
-
const
|
|
3807
|
-
const parts = splitCompound(command);
|
|
3878
|
+
const parts = splitCompound(data.tool_input.command.trim());
|
|
3808
3879
|
if (!parts) return;
|
|
3809
|
-
const
|
|
3810
|
-
|
|
3811
|
-
const reason = isApprovedRead(part);
|
|
3812
|
-
if (!reason) return;
|
|
3813
|
-
reasons.push(reason);
|
|
3814
|
-
}
|
|
3880
|
+
const decision = resolvePermission(data.tool_name, parts);
|
|
3881
|
+
if (!decision) return;
|
|
3815
3882
|
console.log(
|
|
3816
3883
|
JSON.stringify({
|
|
3817
3884
|
hookSpecificOutput: {
|
|
3818
3885
|
hookEventName: "PreToolUse",
|
|
3819
|
-
|
|
3820
|
-
permissionDecisionReason: reasons.join("; ")
|
|
3886
|
+
...decision
|
|
3821
3887
|
}
|
|
3822
3888
|
})
|
|
3823
3889
|
);
|
|
@@ -3893,11 +3959,11 @@ function assertCliExists(cli) {
|
|
|
3893
3959
|
}
|
|
3894
3960
|
|
|
3895
3961
|
// src/commands/permitCliReads/colorize.ts
|
|
3896
|
-
import
|
|
3962
|
+
import chalk48 from "chalk";
|
|
3897
3963
|
function colorize(plainOutput) {
|
|
3898
3964
|
return plainOutput.split("\n").map((line) => {
|
|
3899
|
-
if (line.startsWith(" R ")) return
|
|
3900
|
-
if (line.startsWith(" W ")) return
|
|
3965
|
+
if (line.startsWith(" R ")) return chalk48.green(line);
|
|
3966
|
+
if (line.startsWith(" W ")) return chalk48.red(line);
|
|
3901
3967
|
return line;
|
|
3902
3968
|
}).join("\n");
|
|
3903
3969
|
}
|
|
@@ -4123,10 +4189,10 @@ function formatHuman(cli, commands) {
|
|
|
4123
4189
|
}
|
|
4124
4190
|
|
|
4125
4191
|
// src/commands/permitCliReads/parseCached.ts
|
|
4126
|
-
function parseCached(cli,
|
|
4192
|
+
function parseCached(cli, cached) {
|
|
4127
4193
|
const prefix2 = `${cli} `;
|
|
4128
4194
|
const commands = [];
|
|
4129
|
-
for (const line of
|
|
4195
|
+
for (const line of cached.split("\n")) {
|
|
4130
4196
|
const trimmed = line.replace(/^ [RW?] {2}/, "").trim();
|
|
4131
4197
|
if (!trimmed.startsWith(prefix2)) continue;
|
|
4132
4198
|
const rest = trimmed.slice(prefix2.length);
|
|
@@ -4179,10 +4245,10 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
4179
4245
|
const binary = parts[0];
|
|
4180
4246
|
const prefixPath = parts.slice(1);
|
|
4181
4247
|
if (!options2.noCache) {
|
|
4182
|
-
const
|
|
4183
|
-
if (
|
|
4184
|
-
console.log(colorize(
|
|
4185
|
-
updateSettings(binary, parseCached(binary,
|
|
4248
|
+
const cached = readCache(cli);
|
|
4249
|
+
if (cached) {
|
|
4250
|
+
console.log(colorize(cached));
|
|
4251
|
+
updateSettings(binary, parseCached(binary, cached));
|
|
4186
4252
|
return;
|
|
4187
4253
|
}
|
|
4188
4254
|
}
|
|
@@ -4211,15 +4277,15 @@ function registerCliHook(program2) {
|
|
|
4211
4277
|
}
|
|
4212
4278
|
|
|
4213
4279
|
// src/commands/complexity/analyze.ts
|
|
4214
|
-
import
|
|
4280
|
+
import chalk54 from "chalk";
|
|
4215
4281
|
|
|
4216
4282
|
// src/commands/complexity/cyclomatic.ts
|
|
4217
|
-
import
|
|
4283
|
+
import chalk50 from "chalk";
|
|
4218
4284
|
|
|
4219
4285
|
// src/commands/complexity/shared/index.ts
|
|
4220
4286
|
import fs12 from "fs";
|
|
4221
4287
|
import path20 from "path";
|
|
4222
|
-
import
|
|
4288
|
+
import chalk49 from "chalk";
|
|
4223
4289
|
import ts5 from "typescript";
|
|
4224
4290
|
|
|
4225
4291
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4465,7 +4531,7 @@ function createSourceFromFile(filePath) {
|
|
|
4465
4531
|
function withSourceFiles(pattern2, callback) {
|
|
4466
4532
|
const files = findSourceFiles2(pattern2);
|
|
4467
4533
|
if (files.length === 0) {
|
|
4468
|
-
console.log(
|
|
4534
|
+
console.log(chalk49.yellow("No files found matching pattern"));
|
|
4469
4535
|
return void 0;
|
|
4470
4536
|
}
|
|
4471
4537
|
return callback(files);
|
|
@@ -4498,11 +4564,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4498
4564
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4499
4565
|
for (const { file, name, complexity } of results) {
|
|
4500
4566
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4501
|
-
const color = exceedsThreshold ?
|
|
4502
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4567
|
+
const color = exceedsThreshold ? chalk50.red : chalk50.white;
|
|
4568
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk50.cyan(complexity)}`);
|
|
4503
4569
|
}
|
|
4504
4570
|
console.log(
|
|
4505
|
-
|
|
4571
|
+
chalk50.dim(
|
|
4506
4572
|
`
|
|
4507
4573
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4508
4574
|
)
|
|
@@ -4514,7 +4580,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4514
4580
|
}
|
|
4515
4581
|
|
|
4516
4582
|
// src/commands/complexity/halstead.ts
|
|
4517
|
-
import
|
|
4583
|
+
import chalk51 from "chalk";
|
|
4518
4584
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4519
4585
|
withSourceFiles(pattern2, (files) => {
|
|
4520
4586
|
const results = [];
|
|
@@ -4529,13 +4595,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4529
4595
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4530
4596
|
for (const { file, name, metrics } of results) {
|
|
4531
4597
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4532
|
-
const color = exceedsThreshold ?
|
|
4598
|
+
const color = exceedsThreshold ? chalk51.red : chalk51.white;
|
|
4533
4599
|
console.log(
|
|
4534
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4600
|
+
`${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))}`
|
|
4535
4601
|
);
|
|
4536
4602
|
}
|
|
4537
4603
|
console.log(
|
|
4538
|
-
|
|
4604
|
+
chalk51.dim(
|
|
4539
4605
|
`
|
|
4540
4606
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4541
4607
|
)
|
|
@@ -4550,28 +4616,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4550
4616
|
import fs13 from "fs";
|
|
4551
4617
|
|
|
4552
4618
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4553
|
-
import
|
|
4619
|
+
import chalk52 from "chalk";
|
|
4554
4620
|
function displayMaintainabilityResults(results, threshold) {
|
|
4555
4621
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4556
4622
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4557
|
-
console.log(
|
|
4623
|
+
console.log(chalk52.green("All files pass maintainability threshold"));
|
|
4558
4624
|
} else {
|
|
4559
4625
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4560
|
-
const color = threshold !== void 0 ?
|
|
4626
|
+
const color = threshold !== void 0 ? chalk52.red : chalk52.white;
|
|
4561
4627
|
console.log(
|
|
4562
|
-
`${color(file)} \u2192 avg: ${
|
|
4628
|
+
`${color(file)} \u2192 avg: ${chalk52.cyan(avgMaintainability.toFixed(1))}, min: ${chalk52.yellow(minMaintainability.toFixed(1))}`
|
|
4563
4629
|
);
|
|
4564
4630
|
}
|
|
4565
4631
|
}
|
|
4566
|
-
console.log(
|
|
4632
|
+
console.log(chalk52.dim(`
|
|
4567
4633
|
Analyzed ${results.length} files`));
|
|
4568
4634
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4569
4635
|
console.error(
|
|
4570
|
-
|
|
4636
|
+
chalk52.red(
|
|
4571
4637
|
`
|
|
4572
4638
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4573
4639
|
|
|
4574
|
-
\u26A0\uFE0F ${
|
|
4640
|
+
\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.`
|
|
4575
4641
|
)
|
|
4576
4642
|
);
|
|
4577
4643
|
process.exit(1);
|
|
@@ -4628,7 +4694,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4628
4694
|
|
|
4629
4695
|
// src/commands/complexity/sloc.ts
|
|
4630
4696
|
import fs14 from "fs";
|
|
4631
|
-
import
|
|
4697
|
+
import chalk53 from "chalk";
|
|
4632
4698
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4633
4699
|
withSourceFiles(pattern2, (files) => {
|
|
4634
4700
|
const results = [];
|
|
@@ -4644,12 +4710,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4644
4710
|
results.sort((a, b) => b.lines - a.lines);
|
|
4645
4711
|
for (const { file, lines } of results) {
|
|
4646
4712
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4647
|
-
const color = exceedsThreshold ?
|
|
4648
|
-
console.log(`${color(file)} \u2192 ${
|
|
4713
|
+
const color = exceedsThreshold ? chalk53.red : chalk53.white;
|
|
4714
|
+
console.log(`${color(file)} \u2192 ${chalk53.cyan(lines)} lines`);
|
|
4649
4715
|
}
|
|
4650
4716
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4651
4717
|
console.log(
|
|
4652
|
-
|
|
4718
|
+
chalk53.dim(`
|
|
4653
4719
|
Total: ${total} lines across ${files.length} files`)
|
|
4654
4720
|
);
|
|
4655
4721
|
if (hasViolation) {
|
|
@@ -4663,21 +4729,21 @@ async function analyze(pattern2) {
|
|
|
4663
4729
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4664
4730
|
const files = findSourceFiles2(searchPattern);
|
|
4665
4731
|
if (files.length === 0) {
|
|
4666
|
-
console.log(
|
|
4732
|
+
console.log(chalk54.yellow("No files found matching pattern"));
|
|
4667
4733
|
return;
|
|
4668
4734
|
}
|
|
4669
4735
|
if (files.length === 1) {
|
|
4670
4736
|
const file = files[0];
|
|
4671
|
-
console.log(
|
|
4737
|
+
console.log(chalk54.bold.underline("SLOC"));
|
|
4672
4738
|
await sloc(file);
|
|
4673
4739
|
console.log();
|
|
4674
|
-
console.log(
|
|
4740
|
+
console.log(chalk54.bold.underline("Cyclomatic Complexity"));
|
|
4675
4741
|
await cyclomatic(file);
|
|
4676
4742
|
console.log();
|
|
4677
|
-
console.log(
|
|
4743
|
+
console.log(chalk54.bold.underline("Halstead Metrics"));
|
|
4678
4744
|
await halstead(file);
|
|
4679
4745
|
console.log();
|
|
4680
|
-
console.log(
|
|
4746
|
+
console.log(chalk54.bold.underline("Maintainability Index"));
|
|
4681
4747
|
await maintainability(file);
|
|
4682
4748
|
return;
|
|
4683
4749
|
}
|
|
@@ -4705,7 +4771,7 @@ function registerComplexity(program2) {
|
|
|
4705
4771
|
|
|
4706
4772
|
// src/commands/deploy/redirect.ts
|
|
4707
4773
|
import { existsSync as existsSync23, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
4708
|
-
import
|
|
4774
|
+
import chalk55 from "chalk";
|
|
4709
4775
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4710
4776
|
if (!window.location.pathname.endsWith('/')) {
|
|
4711
4777
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4714,22 +4780,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4714
4780
|
function redirect() {
|
|
4715
4781
|
const indexPath = "index.html";
|
|
4716
4782
|
if (!existsSync23(indexPath)) {
|
|
4717
|
-
console.log(
|
|
4783
|
+
console.log(chalk55.yellow("No index.html found"));
|
|
4718
4784
|
return;
|
|
4719
4785
|
}
|
|
4720
4786
|
const content = readFileSync18(indexPath, "utf-8");
|
|
4721
4787
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4722
|
-
console.log(
|
|
4788
|
+
console.log(chalk55.dim("Trailing slash script already present"));
|
|
4723
4789
|
return;
|
|
4724
4790
|
}
|
|
4725
4791
|
const headCloseIndex = content.indexOf("</head>");
|
|
4726
4792
|
if (headCloseIndex === -1) {
|
|
4727
|
-
console.log(
|
|
4793
|
+
console.log(chalk55.red("Could not find </head> tag in index.html"));
|
|
4728
4794
|
return;
|
|
4729
4795
|
}
|
|
4730
4796
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4731
4797
|
writeFileSync17(indexPath, newContent);
|
|
4732
|
-
console.log(
|
|
4798
|
+
console.log(chalk55.green("Added trailing slash redirect to index.html"));
|
|
4733
4799
|
}
|
|
4734
4800
|
|
|
4735
4801
|
// src/commands/registerDeploy.ts
|
|
@@ -4756,7 +4822,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
4756
4822
|
|
|
4757
4823
|
// src/commands/devlog/shared.ts
|
|
4758
4824
|
import { execSync as execSync17 } from "child_process";
|
|
4759
|
-
import
|
|
4825
|
+
import chalk56 from "chalk";
|
|
4760
4826
|
|
|
4761
4827
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4762
4828
|
import { readdirSync, readFileSync as readFileSync19 } from "fs";
|
|
@@ -4843,13 +4909,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4843
4909
|
}
|
|
4844
4910
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4845
4911
|
for (const commit2 of commits) {
|
|
4846
|
-
console.log(` ${
|
|
4912
|
+
console.log(` ${chalk56.yellow(commit2.hash)} ${commit2.message}`);
|
|
4847
4913
|
if (verbose) {
|
|
4848
4914
|
const visibleFiles = commit2.files.filter(
|
|
4849
4915
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4850
4916
|
);
|
|
4851
4917
|
for (const file of visibleFiles) {
|
|
4852
|
-
console.log(` ${
|
|
4918
|
+
console.log(` ${chalk56.dim(file)}`);
|
|
4853
4919
|
}
|
|
4854
4920
|
}
|
|
4855
4921
|
}
|
|
@@ -4874,15 +4940,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4874
4940
|
}
|
|
4875
4941
|
|
|
4876
4942
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4877
|
-
import
|
|
4943
|
+
import chalk57 from "chalk";
|
|
4878
4944
|
function printDateHeader(date, isSkipped, entries) {
|
|
4879
4945
|
if (isSkipped) {
|
|
4880
|
-
console.log(`${
|
|
4946
|
+
console.log(`${chalk57.bold.blue(date)} ${chalk57.dim("skipped")}`);
|
|
4881
4947
|
} else if (entries && entries.length > 0) {
|
|
4882
|
-
const entryInfo = entries.map((e) => `${
|
|
4883
|
-
console.log(`${
|
|
4948
|
+
const entryInfo = entries.map((e) => `${chalk57.green(e.version)} ${e.title}`).join(" | ");
|
|
4949
|
+
console.log(`${chalk57.bold.blue(date)} ${entryInfo}`);
|
|
4884
4950
|
} else {
|
|
4885
|
-
console.log(`${
|
|
4951
|
+
console.log(`${chalk57.bold.blue(date)} ${chalk57.red("\u26A0 devlog missing")}`);
|
|
4886
4952
|
}
|
|
4887
4953
|
}
|
|
4888
4954
|
|
|
@@ -4985,24 +5051,24 @@ function bumpVersion(version2, type) {
|
|
|
4985
5051
|
|
|
4986
5052
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
4987
5053
|
import { execSync as execSync20 } from "child_process";
|
|
4988
|
-
import
|
|
5054
|
+
import chalk59 from "chalk";
|
|
4989
5055
|
|
|
4990
5056
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
4991
|
-
import
|
|
5057
|
+
import chalk58 from "chalk";
|
|
4992
5058
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
4993
5059
|
if (conventional && firstHash) {
|
|
4994
5060
|
const version2 = getVersionAtCommit(firstHash);
|
|
4995
5061
|
if (version2) {
|
|
4996
|
-
console.log(`${
|
|
5062
|
+
console.log(`${chalk58.bold("version:")} ${stripToMinor(version2)}`);
|
|
4997
5063
|
} else {
|
|
4998
|
-
console.log(`${
|
|
5064
|
+
console.log(`${chalk58.bold("version:")} ${chalk58.red("unknown")}`);
|
|
4999
5065
|
}
|
|
5000
5066
|
} else if (patchVersion && minorVersion) {
|
|
5001
5067
|
console.log(
|
|
5002
|
-
`${
|
|
5068
|
+
`${chalk58.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
5003
5069
|
);
|
|
5004
5070
|
} else {
|
|
5005
|
-
console.log(`${
|
|
5071
|
+
console.log(`${chalk58.bold("version:")} v0.1 (initial)`);
|
|
5006
5072
|
}
|
|
5007
5073
|
}
|
|
5008
5074
|
|
|
@@ -5049,16 +5115,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
5049
5115
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
5050
5116
|
}
|
|
5051
5117
|
function logName(repoName) {
|
|
5052
|
-
console.log(`${
|
|
5118
|
+
console.log(`${chalk59.bold("name:")} ${repoName}`);
|
|
5053
5119
|
}
|
|
5054
5120
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
5055
5121
|
logName(ctx.repoName);
|
|
5056
5122
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
5057
|
-
console.log(
|
|
5123
|
+
console.log(chalk59.bold.blue(targetDate));
|
|
5058
5124
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
5059
5125
|
}
|
|
5060
5126
|
function logNoCommits(lastInfo) {
|
|
5061
|
-
console.log(
|
|
5127
|
+
console.log(chalk59.dim(noCommitsMessage(!!lastInfo)));
|
|
5062
5128
|
}
|
|
5063
5129
|
|
|
5064
5130
|
// src/commands/devlog/next/index.ts
|
|
@@ -5099,11 +5165,11 @@ function next2(options2) {
|
|
|
5099
5165
|
import { execSync as execSync21 } from "child_process";
|
|
5100
5166
|
|
|
5101
5167
|
// src/commands/devlog/repos/printReposTable.ts
|
|
5102
|
-
import
|
|
5168
|
+
import chalk60 from "chalk";
|
|
5103
5169
|
function colorStatus(status2) {
|
|
5104
|
-
if (status2 === "missing") return
|
|
5105
|
-
if (status2 === "outdated") return
|
|
5106
|
-
return
|
|
5170
|
+
if (status2 === "missing") return chalk60.red(status2);
|
|
5171
|
+
if (status2 === "outdated") return chalk60.yellow(status2);
|
|
5172
|
+
return chalk60.green(status2);
|
|
5107
5173
|
}
|
|
5108
5174
|
function formatRow(row, nameWidth) {
|
|
5109
5175
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -5117,8 +5183,8 @@ function printReposTable(rows) {
|
|
|
5117
5183
|
"Last Devlog".padEnd(11),
|
|
5118
5184
|
"Status"
|
|
5119
5185
|
].join(" ");
|
|
5120
|
-
console.log(
|
|
5121
|
-
console.log(
|
|
5186
|
+
console.log(chalk60.dim(header));
|
|
5187
|
+
console.log(chalk60.dim("-".repeat(header.length)));
|
|
5122
5188
|
for (const row of rows) {
|
|
5123
5189
|
console.log(formatRow(row, nameWidth));
|
|
5124
5190
|
}
|
|
@@ -5176,14 +5242,14 @@ function repos(options2) {
|
|
|
5176
5242
|
// src/commands/devlog/skip.ts
|
|
5177
5243
|
import { writeFileSync as writeFileSync18 } from "fs";
|
|
5178
5244
|
import { join as join17 } from "path";
|
|
5179
|
-
import
|
|
5245
|
+
import chalk61 from "chalk";
|
|
5180
5246
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
5181
5247
|
function getBlogConfigPath() {
|
|
5182
5248
|
return join17(BLOG_REPO_ROOT, "assist.yml");
|
|
5183
5249
|
}
|
|
5184
5250
|
function skip(date) {
|
|
5185
5251
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5186
|
-
console.log(
|
|
5252
|
+
console.log(chalk61.red("Invalid date format. Use YYYY-MM-DD"));
|
|
5187
5253
|
process.exit(1);
|
|
5188
5254
|
}
|
|
5189
5255
|
const repoName = getRepoName();
|
|
@@ -5194,7 +5260,7 @@ function skip(date) {
|
|
|
5194
5260
|
const skipDays = skip2[repoName] ?? [];
|
|
5195
5261
|
if (skipDays.includes(date)) {
|
|
5196
5262
|
console.log(
|
|
5197
|
-
|
|
5263
|
+
chalk61.yellow(`${date} is already in skip list for ${repoName}`)
|
|
5198
5264
|
);
|
|
5199
5265
|
return;
|
|
5200
5266
|
}
|
|
@@ -5204,20 +5270,20 @@ function skip(date) {
|
|
|
5204
5270
|
devlog.skip = skip2;
|
|
5205
5271
|
config.devlog = devlog;
|
|
5206
5272
|
writeFileSync18(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
5207
|
-
console.log(
|
|
5273
|
+
console.log(chalk61.green(`Added ${date} to skip list for ${repoName}`));
|
|
5208
5274
|
}
|
|
5209
5275
|
|
|
5210
5276
|
// src/commands/devlog/version.ts
|
|
5211
|
-
import
|
|
5277
|
+
import chalk62 from "chalk";
|
|
5212
5278
|
function version() {
|
|
5213
5279
|
const config = loadConfig();
|
|
5214
5280
|
const name = getRepoName();
|
|
5215
5281
|
const lastInfo = getLastVersionInfo(name, config);
|
|
5216
5282
|
const lastVersion = lastInfo?.version ?? null;
|
|
5217
5283
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
5218
|
-
console.log(`${
|
|
5219
|
-
console.log(`${
|
|
5220
|
-
console.log(`${
|
|
5284
|
+
console.log(`${chalk62.bold("name:")} ${name}`);
|
|
5285
|
+
console.log(`${chalk62.bold("last:")} ${lastVersion ?? chalk62.dim("none")}`);
|
|
5286
|
+
console.log(`${chalk62.bold("next:")} ${nextVersion ?? chalk62.dim("none")}`);
|
|
5221
5287
|
}
|
|
5222
5288
|
|
|
5223
5289
|
// src/commands/registerDevlog.ts
|
|
@@ -5241,7 +5307,7 @@ function registerDevlog(program2) {
|
|
|
5241
5307
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5242
5308
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5243
5309
|
import { join as join18 } from "path";
|
|
5244
|
-
import
|
|
5310
|
+
import chalk63 from "chalk";
|
|
5245
5311
|
|
|
5246
5312
|
// src/shared/findRepoRoot.ts
|
|
5247
5313
|
import { existsSync as existsSync24 } from "fs";
|
|
@@ -5304,14 +5370,14 @@ function checkBuildLocks(startDir) {
|
|
|
5304
5370
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5305
5371
|
if (locked) {
|
|
5306
5372
|
console.error(
|
|
5307
|
-
|
|
5373
|
+
chalk63.red("Build output locked (is VS debugging?): ") + locked
|
|
5308
5374
|
);
|
|
5309
5375
|
process.exit(1);
|
|
5310
5376
|
}
|
|
5311
5377
|
}
|
|
5312
5378
|
async function checkBuildLocksCommand() {
|
|
5313
5379
|
checkBuildLocks();
|
|
5314
|
-
console.log(
|
|
5380
|
+
console.log(chalk63.green("No build locks detected"));
|
|
5315
5381
|
}
|
|
5316
5382
|
|
|
5317
5383
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -5410,30 +5476,30 @@ function escapeRegex(s) {
|
|
|
5410
5476
|
}
|
|
5411
5477
|
|
|
5412
5478
|
// src/commands/dotnet/printTree.ts
|
|
5413
|
-
import
|
|
5479
|
+
import chalk64 from "chalk";
|
|
5414
5480
|
function printNodes(nodes, prefix2) {
|
|
5415
5481
|
for (let i = 0; i < nodes.length; i++) {
|
|
5416
5482
|
const isLast = i === nodes.length - 1;
|
|
5417
5483
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5418
5484
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5419
5485
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5420
|
-
const label2 = isMissing ?
|
|
5486
|
+
const label2 = isMissing ? chalk64.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5421
5487
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5422
5488
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5423
5489
|
}
|
|
5424
5490
|
}
|
|
5425
5491
|
function printTree(tree, totalCount, solutions) {
|
|
5426
|
-
console.log(
|
|
5427
|
-
console.log(
|
|
5492
|
+
console.log(chalk64.bold("\nProject Dependency Tree"));
|
|
5493
|
+
console.log(chalk64.cyan(tree.relativePath));
|
|
5428
5494
|
printNodes(tree.children, "");
|
|
5429
|
-
console.log(
|
|
5495
|
+
console.log(chalk64.dim(`
|
|
5430
5496
|
${totalCount} projects total (including root)`));
|
|
5431
|
-
console.log(
|
|
5497
|
+
console.log(chalk64.bold("\nSolution Membership"));
|
|
5432
5498
|
if (solutions.length === 0) {
|
|
5433
|
-
console.log(
|
|
5499
|
+
console.log(chalk64.yellow(" Not found in any .sln"));
|
|
5434
5500
|
} else {
|
|
5435
5501
|
for (const sln of solutions) {
|
|
5436
|
-
console.log(` ${
|
|
5502
|
+
console.log(` ${chalk64.green(sln)}`);
|
|
5437
5503
|
}
|
|
5438
5504
|
}
|
|
5439
5505
|
console.log();
|
|
@@ -5462,16 +5528,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5462
5528
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5463
5529
|
import { existsSync as existsSync25 } from "fs";
|
|
5464
5530
|
import path24 from "path";
|
|
5465
|
-
import
|
|
5531
|
+
import chalk65 from "chalk";
|
|
5466
5532
|
function resolveCsproj(csprojPath) {
|
|
5467
5533
|
const resolved = path24.resolve(csprojPath);
|
|
5468
5534
|
if (!existsSync25(resolved)) {
|
|
5469
|
-
console.error(
|
|
5535
|
+
console.error(chalk65.red(`File not found: ${resolved}`));
|
|
5470
5536
|
process.exit(1);
|
|
5471
5537
|
}
|
|
5472
5538
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5473
5539
|
if (!repoRoot) {
|
|
5474
|
-
console.error(
|
|
5540
|
+
console.error(chalk65.red("Could not find git repository root"));
|
|
5475
5541
|
process.exit(1);
|
|
5476
5542
|
}
|
|
5477
5543
|
return { resolved, repoRoot };
|
|
@@ -5521,12 +5587,12 @@ function getChangedCsFiles(scope) {
|
|
|
5521
5587
|
}
|
|
5522
5588
|
|
|
5523
5589
|
// src/commands/dotnet/inSln.ts
|
|
5524
|
-
import
|
|
5590
|
+
import chalk66 from "chalk";
|
|
5525
5591
|
async function inSln(csprojPath) {
|
|
5526
5592
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5527
5593
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5528
5594
|
if (solutions.length === 0) {
|
|
5529
|
-
console.log(
|
|
5595
|
+
console.log(chalk66.yellow("Not found in any .sln file"));
|
|
5530
5596
|
process.exit(1);
|
|
5531
5597
|
}
|
|
5532
5598
|
for (const sln of solutions) {
|
|
@@ -5535,7 +5601,7 @@ async function inSln(csprojPath) {
|
|
|
5535
5601
|
}
|
|
5536
5602
|
|
|
5537
5603
|
// src/commands/dotnet/inspect.ts
|
|
5538
|
-
import
|
|
5604
|
+
import chalk72 from "chalk";
|
|
5539
5605
|
|
|
5540
5606
|
// src/shared/formatElapsed.ts
|
|
5541
5607
|
function formatElapsed(ms) {
|
|
@@ -5547,12 +5613,12 @@ function formatElapsed(ms) {
|
|
|
5547
5613
|
}
|
|
5548
5614
|
|
|
5549
5615
|
// src/commands/dotnet/displayIssues.ts
|
|
5550
|
-
import
|
|
5616
|
+
import chalk67 from "chalk";
|
|
5551
5617
|
var SEVERITY_COLOR = {
|
|
5552
|
-
ERROR:
|
|
5553
|
-
WARNING:
|
|
5554
|
-
SUGGESTION:
|
|
5555
|
-
HINT:
|
|
5618
|
+
ERROR: chalk67.red,
|
|
5619
|
+
WARNING: chalk67.yellow,
|
|
5620
|
+
SUGGESTION: chalk67.cyan,
|
|
5621
|
+
HINT: chalk67.dim
|
|
5556
5622
|
};
|
|
5557
5623
|
function groupByFile(issues) {
|
|
5558
5624
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5568,15 +5634,15 @@ function groupByFile(issues) {
|
|
|
5568
5634
|
}
|
|
5569
5635
|
function displayIssues(issues) {
|
|
5570
5636
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5571
|
-
console.log(
|
|
5637
|
+
console.log(chalk67.bold(file));
|
|
5572
5638
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5573
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5639
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk67.white;
|
|
5574
5640
|
console.log(
|
|
5575
|
-
` ${
|
|
5641
|
+
` ${chalk67.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5576
5642
|
);
|
|
5577
5643
|
}
|
|
5578
5644
|
}
|
|
5579
|
-
console.log(
|
|
5645
|
+
console.log(chalk67.dim(`
|
|
5580
5646
|
${issues.length} issue(s) found`));
|
|
5581
5647
|
}
|
|
5582
5648
|
|
|
@@ -5635,12 +5701,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5635
5701
|
// src/commands/dotnet/resolveSolution.ts
|
|
5636
5702
|
import { existsSync as existsSync26 } from "fs";
|
|
5637
5703
|
import path25 from "path";
|
|
5638
|
-
import
|
|
5704
|
+
import chalk69 from "chalk";
|
|
5639
5705
|
|
|
5640
5706
|
// src/commands/dotnet/findSolution.ts
|
|
5641
5707
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5642
5708
|
import { dirname as dirname16, join as join19 } from "path";
|
|
5643
|
-
import
|
|
5709
|
+
import chalk68 from "chalk";
|
|
5644
5710
|
function findSlnInDir(dir) {
|
|
5645
5711
|
try {
|
|
5646
5712
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join19(dir, f));
|
|
@@ -5656,17 +5722,17 @@ function findSolution() {
|
|
|
5656
5722
|
const slnFiles = findSlnInDir(current);
|
|
5657
5723
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5658
5724
|
if (slnFiles.length > 1) {
|
|
5659
|
-
console.error(
|
|
5725
|
+
console.error(chalk68.red(`Multiple .sln files found in ${current}:`));
|
|
5660
5726
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5661
5727
|
console.error(
|
|
5662
|
-
|
|
5728
|
+
chalk68.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5663
5729
|
);
|
|
5664
5730
|
process.exit(1);
|
|
5665
5731
|
}
|
|
5666
5732
|
if (current === ceiling) break;
|
|
5667
5733
|
current = dirname16(current);
|
|
5668
5734
|
}
|
|
5669
|
-
console.error(
|
|
5735
|
+
console.error(chalk68.red("No .sln file found between cwd and repo root"));
|
|
5670
5736
|
process.exit(1);
|
|
5671
5737
|
}
|
|
5672
5738
|
|
|
@@ -5675,7 +5741,7 @@ function resolveSolution(sln) {
|
|
|
5675
5741
|
if (sln) {
|
|
5676
5742
|
const resolved = path25.resolve(sln);
|
|
5677
5743
|
if (!existsSync26(resolved)) {
|
|
5678
|
-
console.error(
|
|
5744
|
+
console.error(chalk69.red(`Solution file not found: ${resolved}`));
|
|
5679
5745
|
process.exit(1);
|
|
5680
5746
|
}
|
|
5681
5747
|
return resolved;
|
|
@@ -5717,14 +5783,14 @@ import { execSync as execSync23 } from "child_process";
|
|
|
5717
5783
|
import { existsSync as existsSync27, readFileSync as readFileSync22, unlinkSync as unlinkSync5 } from "fs";
|
|
5718
5784
|
import { tmpdir as tmpdir2 } from "os";
|
|
5719
5785
|
import path26 from "path";
|
|
5720
|
-
import
|
|
5786
|
+
import chalk70 from "chalk";
|
|
5721
5787
|
function assertJbInstalled() {
|
|
5722
5788
|
try {
|
|
5723
5789
|
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5724
5790
|
} catch {
|
|
5725
|
-
console.error(
|
|
5791
|
+
console.error(chalk70.red("jb is not installed. Install with:"));
|
|
5726
5792
|
console.error(
|
|
5727
|
-
|
|
5793
|
+
chalk70.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5728
5794
|
);
|
|
5729
5795
|
process.exit(1);
|
|
5730
5796
|
}
|
|
@@ -5742,11 +5808,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5742
5808
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5743
5809
|
process.stderr.write(err.stderr);
|
|
5744
5810
|
}
|
|
5745
|
-
console.error(
|
|
5811
|
+
console.error(chalk70.red("jb inspectcode failed"));
|
|
5746
5812
|
process.exit(1);
|
|
5747
5813
|
}
|
|
5748
5814
|
if (!existsSync27(reportPath)) {
|
|
5749
|
-
console.error(
|
|
5815
|
+
console.error(chalk70.red("Report file not generated"));
|
|
5750
5816
|
process.exit(1);
|
|
5751
5817
|
}
|
|
5752
5818
|
const xml = readFileSync22(reportPath, "utf-8");
|
|
@@ -5756,7 +5822,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5756
5822
|
|
|
5757
5823
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5758
5824
|
import { execSync as execSync24 } from "child_process";
|
|
5759
|
-
import
|
|
5825
|
+
import chalk71 from "chalk";
|
|
5760
5826
|
function resolveMsbuildPath() {
|
|
5761
5827
|
const config = loadConfig();
|
|
5762
5828
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5767,9 +5833,9 @@ function assertMsbuildInstalled() {
|
|
|
5767
5833
|
try {
|
|
5768
5834
|
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5769
5835
|
} catch {
|
|
5770
|
-
console.error(
|
|
5836
|
+
console.error(chalk71.red(`msbuild not found at: ${msbuild}`));
|
|
5771
5837
|
console.error(
|
|
5772
|
-
|
|
5838
|
+
chalk71.yellow(
|
|
5773
5839
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5774
5840
|
)
|
|
5775
5841
|
);
|
|
@@ -5816,17 +5882,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5816
5882
|
// src/commands/dotnet/inspect.ts
|
|
5817
5883
|
function logScope(changedFiles) {
|
|
5818
5884
|
if (changedFiles === null) {
|
|
5819
|
-
console.log(
|
|
5885
|
+
console.log(chalk72.dim("Inspecting full solution..."));
|
|
5820
5886
|
} else {
|
|
5821
5887
|
console.log(
|
|
5822
|
-
|
|
5888
|
+
chalk72.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5823
5889
|
);
|
|
5824
5890
|
}
|
|
5825
5891
|
}
|
|
5826
5892
|
function reportResults(issues, elapsed) {
|
|
5827
5893
|
if (issues.length > 0) displayIssues(issues);
|
|
5828
|
-
else console.log(
|
|
5829
|
-
console.log(
|
|
5894
|
+
else console.log(chalk72.green("No issues found"));
|
|
5895
|
+
console.log(chalk72.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5830
5896
|
if (issues.length > 0) process.exit(1);
|
|
5831
5897
|
}
|
|
5832
5898
|
async function inspect(sln, options2) {
|
|
@@ -5837,7 +5903,7 @@ async function inspect(sln, options2) {
|
|
|
5837
5903
|
const scope = parseScope(options2.scope);
|
|
5838
5904
|
const changedFiles = getChangedCsFiles(scope);
|
|
5839
5905
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5840
|
-
console.log(
|
|
5906
|
+
console.log(chalk72.green("No changed .cs files found"));
|
|
5841
5907
|
return;
|
|
5842
5908
|
}
|
|
5843
5909
|
logScope(changedFiles);
|
|
@@ -5863,7 +5929,7 @@ function registerDotnet(program2) {
|
|
|
5863
5929
|
}
|
|
5864
5930
|
|
|
5865
5931
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5866
|
-
import
|
|
5932
|
+
import chalk74 from "chalk";
|
|
5867
5933
|
|
|
5868
5934
|
// src/commands/jira/adfToText.ts
|
|
5869
5935
|
function renderInline(node) {
|
|
@@ -5924,7 +5990,7 @@ function adfToText(doc) {
|
|
|
5924
5990
|
|
|
5925
5991
|
// src/commands/jira/fetchIssue.ts
|
|
5926
5992
|
import { execSync as execSync25 } from "child_process";
|
|
5927
|
-
import
|
|
5993
|
+
import chalk73 from "chalk";
|
|
5928
5994
|
function fetchIssue(issueKey, fields) {
|
|
5929
5995
|
let result;
|
|
5930
5996
|
try {
|
|
@@ -5937,15 +6003,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
5937
6003
|
const stderr = error.stderr;
|
|
5938
6004
|
if (stderr.includes("unauthorized")) {
|
|
5939
6005
|
console.error(
|
|
5940
|
-
|
|
6006
|
+
chalk73.red("Jira authentication expired."),
|
|
5941
6007
|
"Run",
|
|
5942
|
-
|
|
6008
|
+
chalk73.cyan("assist jira auth"),
|
|
5943
6009
|
"to re-authenticate."
|
|
5944
6010
|
);
|
|
5945
6011
|
process.exit(1);
|
|
5946
6012
|
}
|
|
5947
6013
|
}
|
|
5948
|
-
console.error(
|
|
6014
|
+
console.error(chalk73.red(`Failed to fetch ${issueKey}.`));
|
|
5949
6015
|
process.exit(1);
|
|
5950
6016
|
}
|
|
5951
6017
|
return JSON.parse(result);
|
|
@@ -5959,7 +6025,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5959
6025
|
const parsed = fetchIssue(issueKey, field);
|
|
5960
6026
|
const acValue = parsed?.fields?.[field];
|
|
5961
6027
|
if (!acValue) {
|
|
5962
|
-
console.log(
|
|
6028
|
+
console.log(chalk74.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
5963
6029
|
return;
|
|
5964
6030
|
}
|
|
5965
6031
|
if (typeof acValue === "string") {
|
|
@@ -6054,14 +6120,14 @@ async function jiraAuth() {
|
|
|
6054
6120
|
}
|
|
6055
6121
|
|
|
6056
6122
|
// src/commands/jira/viewIssue.ts
|
|
6057
|
-
import
|
|
6123
|
+
import chalk75 from "chalk";
|
|
6058
6124
|
function viewIssue(issueKey) {
|
|
6059
6125
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
6060
6126
|
const fields = parsed?.fields;
|
|
6061
6127
|
const summary = fields?.summary;
|
|
6062
6128
|
const description = fields?.description;
|
|
6063
6129
|
if (summary) {
|
|
6064
|
-
console.log(
|
|
6130
|
+
console.log(chalk75.bold(summary));
|
|
6065
6131
|
}
|
|
6066
6132
|
if (description) {
|
|
6067
6133
|
if (summary) console.log();
|
|
@@ -6075,7 +6141,7 @@ function viewIssue(issueKey) {
|
|
|
6075
6141
|
}
|
|
6076
6142
|
if (!summary && !description) {
|
|
6077
6143
|
console.log(
|
|
6078
|
-
|
|
6144
|
+
chalk75.yellow(`No summary or description found on ${issueKey}.`)
|
|
6079
6145
|
);
|
|
6080
6146
|
}
|
|
6081
6147
|
}
|
|
@@ -6089,7 +6155,7 @@ function registerJira(program2) {
|
|
|
6089
6155
|
}
|
|
6090
6156
|
|
|
6091
6157
|
// src/commands/news/add/index.ts
|
|
6092
|
-
import
|
|
6158
|
+
import chalk76 from "chalk";
|
|
6093
6159
|
import enquirer7 from "enquirer";
|
|
6094
6160
|
async function add2(url) {
|
|
6095
6161
|
if (!url) {
|
|
@@ -6112,17 +6178,17 @@ async function add2(url) {
|
|
|
6112
6178
|
const news = config.news ?? {};
|
|
6113
6179
|
const feeds = news.feeds ?? [];
|
|
6114
6180
|
if (feeds.includes(url)) {
|
|
6115
|
-
console.log(
|
|
6181
|
+
console.log(chalk76.yellow("Feed already exists in config"));
|
|
6116
6182
|
return;
|
|
6117
6183
|
}
|
|
6118
6184
|
feeds.push(url);
|
|
6119
6185
|
config.news = { ...news, feeds };
|
|
6120
6186
|
saveGlobalConfig(config);
|
|
6121
|
-
console.log(
|
|
6187
|
+
console.log(chalk76.green(`Added feed: ${url}`));
|
|
6122
6188
|
}
|
|
6123
6189
|
|
|
6124
6190
|
// src/commands/news/web/handleRequest.ts
|
|
6125
|
-
import
|
|
6191
|
+
import chalk77 from "chalk";
|
|
6126
6192
|
|
|
6127
6193
|
// src/commands/news/web/shared.ts
|
|
6128
6194
|
import { decodeHTML } from "entities";
|
|
@@ -6258,17 +6324,17 @@ function prefetch() {
|
|
|
6258
6324
|
const config = loadConfig();
|
|
6259
6325
|
const total = config.news.feeds.length;
|
|
6260
6326
|
if (total === 0) return;
|
|
6261
|
-
process.stdout.write(
|
|
6327
|
+
process.stdout.write(chalk77.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6262
6328
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6263
6329
|
const width = 20;
|
|
6264
6330
|
const filled = Math.round(done2 / t * width);
|
|
6265
6331
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6266
6332
|
process.stdout.write(
|
|
6267
|
-
`\r${
|
|
6333
|
+
`\r${chalk77.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6268
6334
|
);
|
|
6269
6335
|
}).then((items) => {
|
|
6270
6336
|
process.stdout.write(
|
|
6271
|
-
`\r${
|
|
6337
|
+
`\r${chalk77.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6272
6338
|
`
|
|
6273
6339
|
);
|
|
6274
6340
|
cachedItems = items;
|
|
@@ -6629,20 +6695,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6629
6695
|
}
|
|
6630
6696
|
|
|
6631
6697
|
// src/commands/prs/listComments/printComments.ts
|
|
6632
|
-
import
|
|
6698
|
+
import chalk78 from "chalk";
|
|
6633
6699
|
function formatForHuman(comment3) {
|
|
6634
6700
|
if (comment3.type === "review") {
|
|
6635
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
6701
|
+
const stateColor = comment3.state === "APPROVED" ? chalk78.green : comment3.state === "CHANGES_REQUESTED" ? chalk78.red : chalk78.yellow;
|
|
6636
6702
|
return [
|
|
6637
|
-
`${
|
|
6703
|
+
`${chalk78.cyan("Review")} by ${chalk78.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
6638
6704
|
comment3.body,
|
|
6639
6705
|
""
|
|
6640
6706
|
].join("\n");
|
|
6641
6707
|
}
|
|
6642
6708
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
6643
6709
|
return [
|
|
6644
|
-
`${
|
|
6645
|
-
|
|
6710
|
+
`${chalk78.cyan("Line comment")} by ${chalk78.bold(comment3.user)} on ${chalk78.dim(`${comment3.path}${location}`)}`,
|
|
6711
|
+
chalk78.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6646
6712
|
comment3.body,
|
|
6647
6713
|
""
|
|
6648
6714
|
].join("\n");
|
|
@@ -6732,13 +6798,13 @@ import { execSync as execSync32 } from "child_process";
|
|
|
6732
6798
|
import enquirer8 from "enquirer";
|
|
6733
6799
|
|
|
6734
6800
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6735
|
-
import
|
|
6801
|
+
import chalk79 from "chalk";
|
|
6736
6802
|
var STATUS_MAP = {
|
|
6737
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6738
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6803
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk79.magenta("merged"), date: pr.mergedAt } : null,
|
|
6804
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk79.red("closed"), date: pr.closedAt } : null
|
|
6739
6805
|
};
|
|
6740
6806
|
function defaultStatus(pr) {
|
|
6741
|
-
return { label:
|
|
6807
|
+
return { label: chalk79.green("opened"), date: pr.createdAt };
|
|
6742
6808
|
}
|
|
6743
6809
|
function getStatus2(pr) {
|
|
6744
6810
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6747,11 +6813,11 @@ function formatDate(dateStr) {
|
|
|
6747
6813
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6748
6814
|
}
|
|
6749
6815
|
function formatPrHeader(pr, status2) {
|
|
6750
|
-
return `${
|
|
6816
|
+
return `${chalk79.cyan(`#${pr.number}`)} ${pr.title} ${chalk79.dim(`(${pr.author.login},`)} ${status2.label} ${chalk79.dim(`${formatDate(status2.date)})`)}`;
|
|
6751
6817
|
}
|
|
6752
6818
|
function logPrDetails(pr) {
|
|
6753
6819
|
console.log(
|
|
6754
|
-
|
|
6820
|
+
chalk79.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6755
6821
|
);
|
|
6756
6822
|
console.log();
|
|
6757
6823
|
}
|
|
@@ -6917,10 +6983,10 @@ function registerPrs(program2) {
|
|
|
6917
6983
|
}
|
|
6918
6984
|
|
|
6919
6985
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6920
|
-
import
|
|
6986
|
+
import chalk85 from "chalk";
|
|
6921
6987
|
|
|
6922
6988
|
// src/shared/createConnectionAuth.ts
|
|
6923
|
-
import
|
|
6989
|
+
import chalk80 from "chalk";
|
|
6924
6990
|
function listConnections(connections, format2) {
|
|
6925
6991
|
if (connections.length === 0) {
|
|
6926
6992
|
console.log("No connections configured.");
|
|
@@ -6933,7 +6999,7 @@ function listConnections(connections, format2) {
|
|
|
6933
6999
|
function removeConnection(connections, name, save) {
|
|
6934
7000
|
const filtered = connections.filter((c) => c.name !== name);
|
|
6935
7001
|
if (filtered.length === connections.length) {
|
|
6936
|
-
console.error(
|
|
7002
|
+
console.error(chalk80.red(`Connection "${name}" not found.`));
|
|
6937
7003
|
process.exit(1);
|
|
6938
7004
|
}
|
|
6939
7005
|
save(filtered);
|
|
@@ -6979,15 +7045,15 @@ function saveConnections(connections) {
|
|
|
6979
7045
|
}
|
|
6980
7046
|
|
|
6981
7047
|
// src/commands/ravendb/promptConnection.ts
|
|
6982
|
-
import
|
|
7048
|
+
import chalk83 from "chalk";
|
|
6983
7049
|
|
|
6984
7050
|
// src/commands/ravendb/selectOpSecret.ts
|
|
6985
|
-
import
|
|
7051
|
+
import chalk82 from "chalk";
|
|
6986
7052
|
import Enquirer2 from "enquirer";
|
|
6987
7053
|
|
|
6988
7054
|
// src/commands/ravendb/searchItems.ts
|
|
6989
7055
|
import { execSync as execSync34 } from "child_process";
|
|
6990
|
-
import
|
|
7056
|
+
import chalk81 from "chalk";
|
|
6991
7057
|
function opExec(args) {
|
|
6992
7058
|
return execSync34(`op ${args}`, {
|
|
6993
7059
|
encoding: "utf-8",
|
|
@@ -7000,7 +7066,7 @@ function searchItems(search) {
|
|
|
7000
7066
|
items = JSON.parse(opExec("item list --format=json"));
|
|
7001
7067
|
} catch {
|
|
7002
7068
|
console.error(
|
|
7003
|
-
|
|
7069
|
+
chalk81.red(
|
|
7004
7070
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
7005
7071
|
)
|
|
7006
7072
|
);
|
|
@@ -7014,7 +7080,7 @@ function getItemFields(itemId) {
|
|
|
7014
7080
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
7015
7081
|
return item.fields.filter((f) => f.reference && f.label);
|
|
7016
7082
|
} catch {
|
|
7017
|
-
console.error(
|
|
7083
|
+
console.error(chalk81.red("Failed to get item details from 1Password."));
|
|
7018
7084
|
process.exit(1);
|
|
7019
7085
|
}
|
|
7020
7086
|
}
|
|
@@ -7033,7 +7099,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7033
7099
|
}).run();
|
|
7034
7100
|
const items = searchItems(search);
|
|
7035
7101
|
if (items.length === 0) {
|
|
7036
|
-
console.error(
|
|
7102
|
+
console.error(chalk82.red(`No items found matching "${search}".`));
|
|
7037
7103
|
process.exit(1);
|
|
7038
7104
|
}
|
|
7039
7105
|
const itemId = await selectOne(
|
|
@@ -7042,7 +7108,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7042
7108
|
);
|
|
7043
7109
|
const fields = getItemFields(itemId);
|
|
7044
7110
|
if (fields.length === 0) {
|
|
7045
|
-
console.error(
|
|
7111
|
+
console.error(chalk82.red("No fields with references found on this item."));
|
|
7046
7112
|
process.exit(1);
|
|
7047
7113
|
}
|
|
7048
7114
|
const ref = await selectOne(
|
|
@@ -7056,7 +7122,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7056
7122
|
async function promptConnection(existingNames) {
|
|
7057
7123
|
const name = await promptInput("name", "Connection name:");
|
|
7058
7124
|
if (existingNames.includes(name)) {
|
|
7059
|
-
console.error(
|
|
7125
|
+
console.error(chalk83.red(`Connection "${name}" already exists.`));
|
|
7060
7126
|
process.exit(1);
|
|
7061
7127
|
}
|
|
7062
7128
|
const url = await promptInput(
|
|
@@ -7065,22 +7131,22 @@ async function promptConnection(existingNames) {
|
|
|
7065
7131
|
);
|
|
7066
7132
|
const database = await promptInput("database", "Database name:");
|
|
7067
7133
|
if (!name || !url || !database) {
|
|
7068
|
-
console.error(
|
|
7134
|
+
console.error(chalk83.red("All fields are required."));
|
|
7069
7135
|
process.exit(1);
|
|
7070
7136
|
}
|
|
7071
7137
|
const apiKeyRef = await selectOpSecret();
|
|
7072
|
-
console.log(
|
|
7138
|
+
console.log(chalk83.dim(`Using: ${apiKeyRef}`));
|
|
7073
7139
|
return { name, url, database, apiKeyRef };
|
|
7074
7140
|
}
|
|
7075
7141
|
|
|
7076
7142
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
7077
|
-
import
|
|
7143
|
+
import chalk84 from "chalk";
|
|
7078
7144
|
function ravendbSetConnection(name) {
|
|
7079
7145
|
const raw = loadGlobalConfigRaw();
|
|
7080
7146
|
const ravendb = raw.ravendb ?? {};
|
|
7081
7147
|
const connections = ravendb.connections ?? [];
|
|
7082
7148
|
if (!connections.some((c) => c.name === name)) {
|
|
7083
|
-
console.error(
|
|
7149
|
+
console.error(chalk84.red(`Connection "${name}" not found.`));
|
|
7084
7150
|
console.error(
|
|
7085
7151
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7086
7152
|
);
|
|
@@ -7096,16 +7162,16 @@ function ravendbSetConnection(name) {
|
|
|
7096
7162
|
var ravendbAuth = createConnectionAuth({
|
|
7097
7163
|
load: loadConnections,
|
|
7098
7164
|
save: saveConnections,
|
|
7099
|
-
format: (c) => `${
|
|
7165
|
+
format: (c) => `${chalk85.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
7100
7166
|
promptNew: promptConnection,
|
|
7101
7167
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
7102
7168
|
});
|
|
7103
7169
|
|
|
7104
7170
|
// src/commands/ravendb/ravendbCollections.ts
|
|
7105
|
-
import
|
|
7171
|
+
import chalk89 from "chalk";
|
|
7106
7172
|
|
|
7107
7173
|
// src/commands/ravendb/ravenFetch.ts
|
|
7108
|
-
import
|
|
7174
|
+
import chalk87 from "chalk";
|
|
7109
7175
|
|
|
7110
7176
|
// src/commands/ravendb/getAccessToken.ts
|
|
7111
7177
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -7116,9 +7182,9 @@ function clearCachedToken(apiKey) {
|
|
|
7116
7182
|
}
|
|
7117
7183
|
async function getAccessToken(apiKey) {
|
|
7118
7184
|
const now = Date.now();
|
|
7119
|
-
const
|
|
7120
|
-
if (
|
|
7121
|
-
return
|
|
7185
|
+
const cached = tokenCache.get(apiKey);
|
|
7186
|
+
if (cached && now < cached.expiry) {
|
|
7187
|
+
return cached.token;
|
|
7122
7188
|
}
|
|
7123
7189
|
const response = await fetch(OAUTH_URL, {
|
|
7124
7190
|
method: "GET",
|
|
@@ -7142,10 +7208,10 @@ ${errorText}`
|
|
|
7142
7208
|
|
|
7143
7209
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
7144
7210
|
import { execSync as execSync35 } from "child_process";
|
|
7145
|
-
import
|
|
7211
|
+
import chalk86 from "chalk";
|
|
7146
7212
|
function resolveOpSecret(reference) {
|
|
7147
7213
|
if (!reference.startsWith("op://")) {
|
|
7148
|
-
console.error(
|
|
7214
|
+
console.error(chalk86.red(`Invalid secret reference: must start with op://`));
|
|
7149
7215
|
process.exit(1);
|
|
7150
7216
|
}
|
|
7151
7217
|
try {
|
|
@@ -7155,7 +7221,7 @@ function resolveOpSecret(reference) {
|
|
|
7155
7221
|
}).trim();
|
|
7156
7222
|
} catch {
|
|
7157
7223
|
console.error(
|
|
7158
|
-
|
|
7224
|
+
chalk86.red(
|
|
7159
7225
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
7160
7226
|
)
|
|
7161
7227
|
);
|
|
@@ -7182,7 +7248,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7182
7248
|
if (!response.ok) {
|
|
7183
7249
|
const body = await response.text();
|
|
7184
7250
|
console.error(
|
|
7185
|
-
|
|
7251
|
+
chalk87.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
7186
7252
|
);
|
|
7187
7253
|
console.error(body.substring(0, 500));
|
|
7188
7254
|
process.exit(1);
|
|
@@ -7191,7 +7257,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7191
7257
|
}
|
|
7192
7258
|
|
|
7193
7259
|
// src/commands/ravendb/resolveConnection.ts
|
|
7194
|
-
import
|
|
7260
|
+
import chalk88 from "chalk";
|
|
7195
7261
|
function loadRavendb() {
|
|
7196
7262
|
const raw = loadGlobalConfigRaw();
|
|
7197
7263
|
const ravendb = raw.ravendb;
|
|
@@ -7205,7 +7271,7 @@ function resolveConnection(name) {
|
|
|
7205
7271
|
const connectionName = name ?? defaultConnection;
|
|
7206
7272
|
if (!connectionName) {
|
|
7207
7273
|
console.error(
|
|
7208
|
-
|
|
7274
|
+
chalk88.red(
|
|
7209
7275
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
7210
7276
|
)
|
|
7211
7277
|
);
|
|
@@ -7213,7 +7279,7 @@ function resolveConnection(name) {
|
|
|
7213
7279
|
}
|
|
7214
7280
|
const connection = connections.find((c) => c.name === connectionName);
|
|
7215
7281
|
if (!connection) {
|
|
7216
|
-
console.error(
|
|
7282
|
+
console.error(chalk88.red(`Connection "${connectionName}" not found.`));
|
|
7217
7283
|
console.error(
|
|
7218
7284
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7219
7285
|
);
|
|
@@ -7244,15 +7310,15 @@ async function ravendbCollections(connectionName) {
|
|
|
7244
7310
|
return;
|
|
7245
7311
|
}
|
|
7246
7312
|
for (const c of collections) {
|
|
7247
|
-
console.log(`${
|
|
7313
|
+
console.log(`${chalk89.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
7248
7314
|
}
|
|
7249
7315
|
}
|
|
7250
7316
|
|
|
7251
7317
|
// src/commands/ravendb/ravendbQuery.ts
|
|
7252
|
-
import
|
|
7318
|
+
import chalk91 from "chalk";
|
|
7253
7319
|
|
|
7254
7320
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7255
|
-
import
|
|
7321
|
+
import chalk90 from "chalk";
|
|
7256
7322
|
|
|
7257
7323
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7258
7324
|
function buildQueryPath(opts) {
|
|
@@ -7290,7 +7356,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7290
7356
|
allResults.push(...results);
|
|
7291
7357
|
start3 += results.length;
|
|
7292
7358
|
process.stderr.write(
|
|
7293
|
-
`\r${
|
|
7359
|
+
`\r${chalk90.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7294
7360
|
);
|
|
7295
7361
|
if (start3 >= totalResults) break;
|
|
7296
7362
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7305,7 +7371,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7305
7371
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7306
7372
|
const resolved = resolveArgs(connectionName, collection);
|
|
7307
7373
|
if (!resolved.collection && !options2.query) {
|
|
7308
|
-
console.error(
|
|
7374
|
+
console.error(chalk91.red("Provide a collection name or --query filter."));
|
|
7309
7375
|
process.exit(1);
|
|
7310
7376
|
}
|
|
7311
7377
|
const { collection: col } = resolved;
|
|
@@ -7343,7 +7409,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7343
7409
|
import * as path27 from "path";
|
|
7344
7410
|
|
|
7345
7411
|
// src/commands/refactor/logViolations.ts
|
|
7346
|
-
import
|
|
7412
|
+
import chalk92 from "chalk";
|
|
7347
7413
|
var DEFAULT_MAX_LINES = 100;
|
|
7348
7414
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7349
7415
|
if (violations.length === 0) {
|
|
@@ -7352,43 +7418,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7352
7418
|
}
|
|
7353
7419
|
return;
|
|
7354
7420
|
}
|
|
7355
|
-
console.error(
|
|
7421
|
+
console.error(chalk92.red(`
|
|
7356
7422
|
Refactor check failed:
|
|
7357
7423
|
`));
|
|
7358
|
-
console.error(
|
|
7424
|
+
console.error(chalk92.red(` The following files exceed ${maxLines} lines:
|
|
7359
7425
|
`));
|
|
7360
7426
|
for (const violation of violations) {
|
|
7361
|
-
console.error(
|
|
7427
|
+
console.error(chalk92.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7362
7428
|
}
|
|
7363
7429
|
console.error(
|
|
7364
|
-
|
|
7430
|
+
chalk92.yellow(
|
|
7365
7431
|
`
|
|
7366
7432
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7367
7433
|
way to refactor it, ignore it with:
|
|
7368
7434
|
`
|
|
7369
7435
|
)
|
|
7370
7436
|
);
|
|
7371
|
-
console.error(
|
|
7437
|
+
console.error(chalk92.gray(` assist refactor ignore <file>
|
|
7372
7438
|
`));
|
|
7373
7439
|
if (process.env.CLAUDECODE) {
|
|
7374
|
-
console.error(
|
|
7440
|
+
console.error(chalk92.cyan(`
|
|
7375
7441
|
## Extracting Code to New Files
|
|
7376
7442
|
`));
|
|
7377
7443
|
console.error(
|
|
7378
|
-
|
|
7444
|
+
chalk92.cyan(
|
|
7379
7445
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7380
7446
|
`
|
|
7381
7447
|
)
|
|
7382
7448
|
);
|
|
7383
7449
|
console.error(
|
|
7384
|
-
|
|
7450
|
+
chalk92.cyan(
|
|
7385
7451
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7386
7452
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7387
7453
|
`
|
|
7388
7454
|
)
|
|
7389
7455
|
);
|
|
7390
7456
|
console.error(
|
|
7391
|
-
|
|
7457
|
+
chalk92.cyan(
|
|
7392
7458
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7393
7459
|
domains, move it to a common/shared folder.
|
|
7394
7460
|
`
|
|
@@ -7544,7 +7610,7 @@ async function check(pattern2, options2) {
|
|
|
7544
7610
|
|
|
7545
7611
|
// src/commands/refactor/extract/index.ts
|
|
7546
7612
|
import path33 from "path";
|
|
7547
|
-
import
|
|
7613
|
+
import chalk95 from "chalk";
|
|
7548
7614
|
|
|
7549
7615
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7550
7616
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -8070,23 +8136,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
8070
8136
|
|
|
8071
8137
|
// src/commands/refactor/extract/displayPlan.ts
|
|
8072
8138
|
import path31 from "path";
|
|
8073
|
-
import
|
|
8139
|
+
import chalk93 from "chalk";
|
|
8074
8140
|
function section(title) {
|
|
8075
8141
|
return `
|
|
8076
|
-
${
|
|
8142
|
+
${chalk93.cyan(title)}`;
|
|
8077
8143
|
}
|
|
8078
8144
|
function displayImporters(plan2, cwd) {
|
|
8079
8145
|
if (plan2.importersToUpdate.length === 0) return;
|
|
8080
8146
|
console.log(section("Update importers:"));
|
|
8081
8147
|
for (const imp of plan2.importersToUpdate) {
|
|
8082
8148
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
8083
|
-
console.log(` ${
|
|
8149
|
+
console.log(` ${chalk93.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
8084
8150
|
}
|
|
8085
8151
|
}
|
|
8086
8152
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
8087
|
-
console.log(
|
|
8153
|
+
console.log(chalk93.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
8088
8154
|
`));
|
|
8089
|
-
console.log(` ${
|
|
8155
|
+
console.log(` ${chalk93.cyan("Functions to move:")}`);
|
|
8090
8156
|
for (const name of plan2.extractedNames) {
|
|
8091
8157
|
console.log(` ${name}`);
|
|
8092
8158
|
}
|
|
@@ -8121,7 +8187,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
8121
8187
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
8122
8188
|
import fs17 from "fs";
|
|
8123
8189
|
import path32 from "path";
|
|
8124
|
-
import
|
|
8190
|
+
import chalk94 from "chalk";
|
|
8125
8191
|
import { Project as Project2 } from "ts-morph";
|
|
8126
8192
|
function findTsConfig(sourcePath) {
|
|
8127
8193
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -8152,7 +8218,7 @@ function loadProjectFile(file) {
|
|
|
8152
8218
|
});
|
|
8153
8219
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
8154
8220
|
if (!sourceFile) {
|
|
8155
|
-
console.log(
|
|
8221
|
+
console.log(chalk94.red(`File not found in project: ${file}`));
|
|
8156
8222
|
process.exit(1);
|
|
8157
8223
|
}
|
|
8158
8224
|
return { project, sourceFile };
|
|
@@ -8175,19 +8241,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
8175
8241
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
8176
8242
|
if (options2.apply) {
|
|
8177
8243
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
8178
|
-
console.log(
|
|
8244
|
+
console.log(chalk95.green("\nExtraction complete"));
|
|
8179
8245
|
} else {
|
|
8180
|
-
console.log(
|
|
8246
|
+
console.log(chalk95.dim("\nDry run. Use --apply to execute."));
|
|
8181
8247
|
}
|
|
8182
8248
|
}
|
|
8183
8249
|
|
|
8184
8250
|
// src/commands/refactor/ignore.ts
|
|
8185
8251
|
import fs18 from "fs";
|
|
8186
|
-
import
|
|
8252
|
+
import chalk96 from "chalk";
|
|
8187
8253
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
8188
8254
|
function ignore(file) {
|
|
8189
8255
|
if (!fs18.existsSync(file)) {
|
|
8190
|
-
console.error(
|
|
8256
|
+
console.error(chalk96.red(`Error: File does not exist: ${file}`));
|
|
8191
8257
|
process.exit(1);
|
|
8192
8258
|
}
|
|
8193
8259
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -8203,7 +8269,7 @@ function ignore(file) {
|
|
|
8203
8269
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
8204
8270
|
}
|
|
8205
8271
|
console.log(
|
|
8206
|
-
|
|
8272
|
+
chalk96.green(
|
|
8207
8273
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
8208
8274
|
)
|
|
8209
8275
|
);
|
|
@@ -8211,26 +8277,26 @@ function ignore(file) {
|
|
|
8211
8277
|
|
|
8212
8278
|
// src/commands/refactor/rename/index.ts
|
|
8213
8279
|
import path34 from "path";
|
|
8214
|
-
import
|
|
8280
|
+
import chalk97 from "chalk";
|
|
8215
8281
|
async function rename(source, destination, options2 = {}) {
|
|
8216
8282
|
const destPath = path34.resolve(destination);
|
|
8217
8283
|
const cwd = process.cwd();
|
|
8218
8284
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
8219
8285
|
const relDest = path34.relative(cwd, destPath);
|
|
8220
8286
|
const { project, sourceFile } = loadProjectFile(source);
|
|
8221
|
-
console.log(
|
|
8287
|
+
console.log(chalk97.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
8222
8288
|
if (options2.apply) {
|
|
8223
8289
|
sourceFile.move(destPath);
|
|
8224
8290
|
await project.save();
|
|
8225
|
-
console.log(
|
|
8291
|
+
console.log(chalk97.green("Done"));
|
|
8226
8292
|
} else {
|
|
8227
|
-
console.log(
|
|
8293
|
+
console.log(chalk97.dim("Dry run. Use --apply to execute."));
|
|
8228
8294
|
}
|
|
8229
8295
|
}
|
|
8230
8296
|
|
|
8231
8297
|
// src/commands/refactor/renameSymbol/index.ts
|
|
8232
8298
|
import path36 from "path";
|
|
8233
|
-
import
|
|
8299
|
+
import chalk98 from "chalk";
|
|
8234
8300
|
import { Project as Project3 } from "ts-morph";
|
|
8235
8301
|
|
|
8236
8302
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8279,38 +8345,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8279
8345
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8280
8346
|
const sourceFile = project.getSourceFile(filePath);
|
|
8281
8347
|
if (!sourceFile) {
|
|
8282
|
-
console.log(
|
|
8348
|
+
console.log(chalk98.red(`File not found in project: ${file}`));
|
|
8283
8349
|
process.exit(1);
|
|
8284
8350
|
}
|
|
8285
8351
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8286
8352
|
if (!symbol) {
|
|
8287
|
-
console.log(
|
|
8353
|
+
console.log(chalk98.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8288
8354
|
process.exit(1);
|
|
8289
8355
|
}
|
|
8290
8356
|
const grouped = groupReferences(symbol, cwd);
|
|
8291
8357
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8292
8358
|
console.log(
|
|
8293
|
-
|
|
8359
|
+
chalk98.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8294
8360
|
`)
|
|
8295
8361
|
);
|
|
8296
8362
|
for (const [refFile, lines] of grouped) {
|
|
8297
8363
|
console.log(
|
|
8298
|
-
` ${
|
|
8364
|
+
` ${chalk98.dim(refFile)}: lines ${chalk98.cyan(lines.join(", "))}`
|
|
8299
8365
|
);
|
|
8300
8366
|
}
|
|
8301
8367
|
if (options2.apply) {
|
|
8302
8368
|
symbol.rename(newName);
|
|
8303
8369
|
await project.save();
|
|
8304
|
-
console.log(
|
|
8370
|
+
console.log(chalk98.green(`
|
|
8305
8371
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8306
8372
|
} else {
|
|
8307
|
-
console.log(
|
|
8373
|
+
console.log(chalk98.dim("\nDry run. Use --apply to execute."));
|
|
8308
8374
|
}
|
|
8309
8375
|
}
|
|
8310
8376
|
|
|
8311
8377
|
// src/commands/refactor/restructure/index.ts
|
|
8312
8378
|
import path45 from "path";
|
|
8313
|
-
import
|
|
8379
|
+
import chalk101 from "chalk";
|
|
8314
8380
|
|
|
8315
8381
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8316
8382
|
import path37 from "path";
|
|
@@ -8553,50 +8619,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8553
8619
|
|
|
8554
8620
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8555
8621
|
import path41 from "path";
|
|
8556
|
-
import
|
|
8622
|
+
import chalk99 from "chalk";
|
|
8557
8623
|
function relPath(filePath) {
|
|
8558
8624
|
return path41.relative(process.cwd(), filePath);
|
|
8559
8625
|
}
|
|
8560
8626
|
function displayMoves(plan2) {
|
|
8561
8627
|
if (plan2.moves.length === 0) return;
|
|
8562
|
-
console.log(
|
|
8628
|
+
console.log(chalk99.bold("\nFile moves:"));
|
|
8563
8629
|
for (const move of plan2.moves) {
|
|
8564
8630
|
console.log(
|
|
8565
|
-
` ${
|
|
8631
|
+
` ${chalk99.red(relPath(move.from))} \u2192 ${chalk99.green(relPath(move.to))}`
|
|
8566
8632
|
);
|
|
8567
|
-
console.log(
|
|
8633
|
+
console.log(chalk99.dim(` ${move.reason}`));
|
|
8568
8634
|
}
|
|
8569
8635
|
}
|
|
8570
8636
|
function displayRewrites(rewrites) {
|
|
8571
8637
|
if (rewrites.length === 0) return;
|
|
8572
8638
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8573
|
-
console.log(
|
|
8639
|
+
console.log(chalk99.bold(`
|
|
8574
8640
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8575
8641
|
for (const file of affectedFiles) {
|
|
8576
|
-
console.log(` ${
|
|
8642
|
+
console.log(` ${chalk99.cyan(relPath(file))}:`);
|
|
8577
8643
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8578
8644
|
(r) => r.file === file
|
|
8579
8645
|
)) {
|
|
8580
8646
|
console.log(
|
|
8581
|
-
` ${
|
|
8647
|
+
` ${chalk99.red(`"${oldSpecifier}"`)} \u2192 ${chalk99.green(`"${newSpecifier}"`)}`
|
|
8582
8648
|
);
|
|
8583
8649
|
}
|
|
8584
8650
|
}
|
|
8585
8651
|
}
|
|
8586
8652
|
function displayPlan2(plan2) {
|
|
8587
8653
|
if (plan2.warnings.length > 0) {
|
|
8588
|
-
console.log(
|
|
8589
|
-
for (const w of plan2.warnings) console.log(
|
|
8654
|
+
console.log(chalk99.yellow("\nWarnings:"));
|
|
8655
|
+
for (const w of plan2.warnings) console.log(chalk99.yellow(` ${w}`));
|
|
8590
8656
|
}
|
|
8591
8657
|
if (plan2.newDirectories.length > 0) {
|
|
8592
|
-
console.log(
|
|
8658
|
+
console.log(chalk99.bold("\nNew directories:"));
|
|
8593
8659
|
for (const dir of plan2.newDirectories)
|
|
8594
|
-
console.log(
|
|
8660
|
+
console.log(chalk99.green(` ${dir}/`));
|
|
8595
8661
|
}
|
|
8596
8662
|
displayMoves(plan2);
|
|
8597
8663
|
displayRewrites(plan2.rewrites);
|
|
8598
8664
|
console.log(
|
|
8599
|
-
|
|
8665
|
+
chalk99.dim(
|
|
8600
8666
|
`
|
|
8601
8667
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8602
8668
|
)
|
|
@@ -8606,18 +8672,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8606
8672
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8607
8673
|
import fs20 from "fs";
|
|
8608
8674
|
import path42 from "path";
|
|
8609
|
-
import
|
|
8675
|
+
import chalk100 from "chalk";
|
|
8610
8676
|
function executePlan(plan2) {
|
|
8611
8677
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8612
8678
|
for (const [file, content] of updatedContents) {
|
|
8613
8679
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8614
8680
|
console.log(
|
|
8615
|
-
|
|
8681
|
+
chalk100.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8616
8682
|
);
|
|
8617
8683
|
}
|
|
8618
8684
|
for (const dir of plan2.newDirectories) {
|
|
8619
8685
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8620
|
-
console.log(
|
|
8686
|
+
console.log(chalk100.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8621
8687
|
}
|
|
8622
8688
|
for (const move of plan2.moves) {
|
|
8623
8689
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8626,7 +8692,7 @@ function executePlan(plan2) {
|
|
|
8626
8692
|
}
|
|
8627
8693
|
fs20.renameSync(move.from, move.to);
|
|
8628
8694
|
console.log(
|
|
8629
|
-
|
|
8695
|
+
chalk100.white(
|
|
8630
8696
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8631
8697
|
)
|
|
8632
8698
|
);
|
|
@@ -8641,7 +8707,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8641
8707
|
if (entries.length === 0) {
|
|
8642
8708
|
fs20.rmdirSync(dir);
|
|
8643
8709
|
console.log(
|
|
8644
|
-
|
|
8710
|
+
chalk100.dim(
|
|
8645
8711
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8646
8712
|
)
|
|
8647
8713
|
);
|
|
@@ -8774,22 +8840,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8774
8840
|
const targetPattern = pattern2 ?? "src";
|
|
8775
8841
|
const files = findSourceFiles2(targetPattern);
|
|
8776
8842
|
if (files.length === 0) {
|
|
8777
|
-
console.log(
|
|
8843
|
+
console.log(chalk101.yellow("No files found matching pattern"));
|
|
8778
8844
|
return;
|
|
8779
8845
|
}
|
|
8780
8846
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8781
8847
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8782
8848
|
if (plan2.moves.length === 0) {
|
|
8783
|
-
console.log(
|
|
8849
|
+
console.log(chalk101.green("No restructuring needed"));
|
|
8784
8850
|
return;
|
|
8785
8851
|
}
|
|
8786
8852
|
displayPlan2(plan2);
|
|
8787
8853
|
if (options2.apply) {
|
|
8788
|
-
console.log(
|
|
8854
|
+
console.log(chalk101.bold("\nApplying changes..."));
|
|
8789
8855
|
executePlan(plan2);
|
|
8790
|
-
console.log(
|
|
8856
|
+
console.log(chalk101.green("\nRestructuring complete"));
|
|
8791
8857
|
} else {
|
|
8792
|
-
console.log(
|
|
8858
|
+
console.log(chalk101.dim("\nDry run. Use --apply to execute."));
|
|
8793
8859
|
}
|
|
8794
8860
|
}
|
|
8795
8861
|
|
|
@@ -8829,7 +8895,7 @@ function registerRefactor(program2) {
|
|
|
8829
8895
|
}
|
|
8830
8896
|
|
|
8831
8897
|
// src/commands/seq/seqAuth.ts
|
|
8832
|
-
import
|
|
8898
|
+
import chalk103 from "chalk";
|
|
8833
8899
|
|
|
8834
8900
|
// src/commands/seq/loadConnections.ts
|
|
8835
8901
|
function loadConnections2() {
|
|
@@ -8858,11 +8924,11 @@ function setDefaultConnection(name) {
|
|
|
8858
8924
|
}
|
|
8859
8925
|
|
|
8860
8926
|
// src/commands/seq/promptConnection.ts
|
|
8861
|
-
import
|
|
8927
|
+
import chalk102 from "chalk";
|
|
8862
8928
|
async function promptConnection2(existingNames) {
|
|
8863
8929
|
const name = await promptInput("name", "Connection name:", "default");
|
|
8864
8930
|
if (existingNames.includes(name)) {
|
|
8865
|
-
console.error(
|
|
8931
|
+
console.error(chalk102.red(`Connection "${name}" already exists.`));
|
|
8866
8932
|
process.exit(1);
|
|
8867
8933
|
}
|
|
8868
8934
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -8874,32 +8940,32 @@ async function promptConnection2(existingNames) {
|
|
|
8874
8940
|
var seqAuth = createConnectionAuth({
|
|
8875
8941
|
load: loadConnections2,
|
|
8876
8942
|
save: saveConnections2,
|
|
8877
|
-
format: (c) => `${
|
|
8943
|
+
format: (c) => `${chalk103.bold(c.name)} ${c.url}`,
|
|
8878
8944
|
promptNew: promptConnection2,
|
|
8879
8945
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
8880
8946
|
});
|
|
8881
8947
|
|
|
8882
8948
|
// src/commands/seq/seqQuery.ts
|
|
8883
|
-
import
|
|
8949
|
+
import chalk106 from "chalk";
|
|
8884
8950
|
|
|
8885
8951
|
// src/commands/seq/formatEvent.ts
|
|
8886
|
-
import
|
|
8952
|
+
import chalk104 from "chalk";
|
|
8887
8953
|
function levelColor(level) {
|
|
8888
8954
|
switch (level) {
|
|
8889
8955
|
case "Fatal":
|
|
8890
|
-
return
|
|
8956
|
+
return chalk104.bgRed.white;
|
|
8891
8957
|
case "Error":
|
|
8892
|
-
return
|
|
8958
|
+
return chalk104.red;
|
|
8893
8959
|
case "Warning":
|
|
8894
|
-
return
|
|
8960
|
+
return chalk104.yellow;
|
|
8895
8961
|
case "Information":
|
|
8896
|
-
return
|
|
8962
|
+
return chalk104.cyan;
|
|
8897
8963
|
case "Debug":
|
|
8898
|
-
return
|
|
8964
|
+
return chalk104.gray;
|
|
8899
8965
|
case "Verbose":
|
|
8900
|
-
return
|
|
8966
|
+
return chalk104.dim;
|
|
8901
8967
|
default:
|
|
8902
|
-
return
|
|
8968
|
+
return chalk104.white;
|
|
8903
8969
|
}
|
|
8904
8970
|
}
|
|
8905
8971
|
function levelAbbrev(level) {
|
|
@@ -8940,31 +9006,31 @@ function formatTimestamp(iso) {
|
|
|
8940
9006
|
function formatEvent(event) {
|
|
8941
9007
|
const color = levelColor(event.Level);
|
|
8942
9008
|
const abbrev = levelAbbrev(event.Level);
|
|
8943
|
-
const ts8 =
|
|
9009
|
+
const ts8 = chalk104.dim(formatTimestamp(event.Timestamp));
|
|
8944
9010
|
const msg = renderMessage(event);
|
|
8945
9011
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
8946
9012
|
if (event.Exception) {
|
|
8947
9013
|
for (const line of event.Exception.split("\n")) {
|
|
8948
|
-
lines.push(
|
|
9014
|
+
lines.push(chalk104.red(` ${line}`));
|
|
8949
9015
|
}
|
|
8950
9016
|
}
|
|
8951
9017
|
return lines.join("\n");
|
|
8952
9018
|
}
|
|
8953
9019
|
|
|
8954
9020
|
// src/commands/seq/resolveConnection.ts
|
|
8955
|
-
import
|
|
9021
|
+
import chalk105 from "chalk";
|
|
8956
9022
|
function resolveConnection2(name) {
|
|
8957
9023
|
const connections = loadConnections2();
|
|
8958
9024
|
if (connections.length === 0) {
|
|
8959
9025
|
console.error(
|
|
8960
|
-
|
|
9026
|
+
chalk105.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
8961
9027
|
);
|
|
8962
9028
|
process.exit(1);
|
|
8963
9029
|
}
|
|
8964
9030
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
8965
9031
|
const connection = connections.find((c) => c.name === target);
|
|
8966
9032
|
if (!connection) {
|
|
8967
|
-
console.error(
|
|
9033
|
+
console.error(chalk105.red(`Seq connection "${target}" not found.`));
|
|
8968
9034
|
process.exit(1);
|
|
8969
9035
|
}
|
|
8970
9036
|
return connection;
|
|
@@ -8984,12 +9050,12 @@ async function seqQuery(filter, options2) {
|
|
|
8984
9050
|
});
|
|
8985
9051
|
if (!response.ok) {
|
|
8986
9052
|
const body = await response.text();
|
|
8987
|
-
console.error(
|
|
9053
|
+
console.error(chalk106.red(`Seq returned ${response.status}: ${body}`));
|
|
8988
9054
|
process.exit(1);
|
|
8989
9055
|
}
|
|
8990
9056
|
const events = await response.json();
|
|
8991
9057
|
if (events.length === 0) {
|
|
8992
|
-
console.log(
|
|
9058
|
+
console.log(chalk106.yellow("No events found."));
|
|
8993
9059
|
return;
|
|
8994
9060
|
}
|
|
8995
9061
|
if (options2.json) {
|
|
@@ -9000,11 +9066,11 @@ async function seqQuery(filter, options2) {
|
|
|
9000
9066
|
for (const event of chronological) {
|
|
9001
9067
|
console.log(formatEvent(event));
|
|
9002
9068
|
}
|
|
9003
|
-
console.log(
|
|
9069
|
+
console.log(chalk106.dim(`
|
|
9004
9070
|
${events.length} events`));
|
|
9005
9071
|
if (events.length >= count) {
|
|
9006
9072
|
console.log(
|
|
9007
|
-
|
|
9073
|
+
chalk106.yellow(
|
|
9008
9074
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
9009
9075
|
)
|
|
9010
9076
|
);
|
|
@@ -9012,11 +9078,11 @@ ${events.length} events`));
|
|
|
9012
9078
|
}
|
|
9013
9079
|
|
|
9014
9080
|
// src/commands/seq/seqSetConnection.ts
|
|
9015
|
-
import
|
|
9081
|
+
import chalk107 from "chalk";
|
|
9016
9082
|
function seqSetConnection(name) {
|
|
9017
9083
|
const connections = loadConnections2();
|
|
9018
9084
|
if (!connections.find((c) => c.name === name)) {
|
|
9019
|
-
console.error(
|
|
9085
|
+
console.error(chalk107.red(`Connection "${name}" not found.`));
|
|
9020
9086
|
process.exit(1);
|
|
9021
9087
|
}
|
|
9022
9088
|
setDefaultConnection(name);
|
|
@@ -9555,14 +9621,14 @@ import {
|
|
|
9555
9621
|
import { dirname as dirname20, join as join30 } from "path";
|
|
9556
9622
|
|
|
9557
9623
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9558
|
-
import
|
|
9624
|
+
import chalk108 from "chalk";
|
|
9559
9625
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9560
9626
|
function validateStagedContent(filename, content) {
|
|
9561
9627
|
const firstLine = content.split("\n")[0];
|
|
9562
9628
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9563
9629
|
if (!match) {
|
|
9564
9630
|
console.error(
|
|
9565
|
-
|
|
9631
|
+
chalk108.red(
|
|
9566
9632
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9567
9633
|
)
|
|
9568
9634
|
);
|
|
@@ -9571,7 +9637,7 @@ function validateStagedContent(filename, content) {
|
|
|
9571
9637
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9572
9638
|
if (!contentAfterLink) {
|
|
9573
9639
|
console.error(
|
|
9574
|
-
|
|
9640
|
+
chalk108.red(
|
|
9575
9641
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9576
9642
|
)
|
|
9577
9643
|
);
|
|
@@ -9964,7 +10030,7 @@ function registerVoice(program2) {
|
|
|
9964
10030
|
|
|
9965
10031
|
// src/commands/roam/auth.ts
|
|
9966
10032
|
import { randomBytes } from "crypto";
|
|
9967
|
-
import
|
|
10033
|
+
import chalk109 from "chalk";
|
|
9968
10034
|
|
|
9969
10035
|
// src/lib/openBrowser.ts
|
|
9970
10036
|
import { execSync as execSync38 } from "child_process";
|
|
@@ -10139,13 +10205,13 @@ async function auth() {
|
|
|
10139
10205
|
saveGlobalConfig(config);
|
|
10140
10206
|
const state = randomBytes(16).toString("hex");
|
|
10141
10207
|
console.log(
|
|
10142
|
-
|
|
10208
|
+
chalk109.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
10143
10209
|
);
|
|
10144
|
-
console.log(
|
|
10145
|
-
console.log(
|
|
10146
|
-
console.log(
|
|
10210
|
+
console.log(chalk109.white("http://localhost:14523/callback\n"));
|
|
10211
|
+
console.log(chalk109.blue("Opening browser for authorization..."));
|
|
10212
|
+
console.log(chalk109.dim("Waiting for authorization callback..."));
|
|
10147
10213
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
10148
|
-
console.log(
|
|
10214
|
+
console.log(chalk109.dim("Exchanging code for tokens..."));
|
|
10149
10215
|
const tokens = await exchangeToken({
|
|
10150
10216
|
code,
|
|
10151
10217
|
clientId,
|
|
@@ -10161,7 +10227,7 @@ async function auth() {
|
|
|
10161
10227
|
};
|
|
10162
10228
|
saveGlobalConfig(config);
|
|
10163
10229
|
console.log(
|
|
10164
|
-
|
|
10230
|
+
chalk109.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
10165
10231
|
);
|
|
10166
10232
|
}
|
|
10167
10233
|
|
|
@@ -10374,7 +10440,7 @@ import { execSync as execSync40 } from "child_process";
|
|
|
10374
10440
|
import { existsSync as existsSync40, mkdirSync as mkdirSync13, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10375
10441
|
import { tmpdir as tmpdir6 } from "os";
|
|
10376
10442
|
import { join as join39, resolve as resolve5 } from "path";
|
|
10377
|
-
import
|
|
10443
|
+
import chalk110 from "chalk";
|
|
10378
10444
|
|
|
10379
10445
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10380
10446
|
var captureWindowPs1 = `
|
|
@@ -10525,22 +10591,22 @@ function screenshot(processName) {
|
|
|
10525
10591
|
const config = loadConfig();
|
|
10526
10592
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10527
10593
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10528
|
-
console.log(
|
|
10594
|
+
console.log(chalk110.gray(`Capturing window for process "${processName}" ...`));
|
|
10529
10595
|
try {
|
|
10530
10596
|
runPowerShellScript(processName, outputPath);
|
|
10531
|
-
console.log(
|
|
10597
|
+
console.log(chalk110.green(`Screenshot saved: ${outputPath}`));
|
|
10532
10598
|
} catch (error) {
|
|
10533
10599
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10534
|
-
console.error(
|
|
10600
|
+
console.error(chalk110.red(`Failed to capture screenshot: ${msg}`));
|
|
10535
10601
|
process.exit(1);
|
|
10536
10602
|
}
|
|
10537
10603
|
}
|
|
10538
10604
|
|
|
10539
10605
|
// src/commands/statusLine.ts
|
|
10540
|
-
import
|
|
10606
|
+
import chalk112 from "chalk";
|
|
10541
10607
|
|
|
10542
10608
|
// src/commands/buildLimitsSegment.ts
|
|
10543
|
-
import
|
|
10609
|
+
import chalk111 from "chalk";
|
|
10544
10610
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10545
10611
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10546
10612
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10563,10 +10629,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10563
10629
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10564
10630
|
const label2 = `${Math.round(pct)}%`;
|
|
10565
10631
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10566
|
-
if (projected == null) return
|
|
10567
|
-
if (projected > 100) return
|
|
10568
|
-
if (projected > 75) return
|
|
10569
|
-
return
|
|
10632
|
+
if (projected == null) return chalk111.green(label2);
|
|
10633
|
+
if (projected > 100) return chalk111.red(label2);
|
|
10634
|
+
if (projected > 75) return chalk111.yellow(label2);
|
|
10635
|
+
return chalk111.green(label2);
|
|
10570
10636
|
}
|
|
10571
10637
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10572
10638
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10592,14 +10658,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10592
10658
|
}
|
|
10593
10659
|
|
|
10594
10660
|
// src/commands/statusLine.ts
|
|
10595
|
-
|
|
10661
|
+
chalk112.level = 3;
|
|
10596
10662
|
function formatNumber(num) {
|
|
10597
10663
|
return num.toLocaleString("en-US");
|
|
10598
10664
|
}
|
|
10599
10665
|
function colorizePercent(pct) {
|
|
10600
10666
|
const label2 = `${Math.round(pct)}%`;
|
|
10601
|
-
if (pct > 80) return
|
|
10602
|
-
if (pct > 40) return
|
|
10667
|
+
if (pct > 80) return chalk112.red(label2);
|
|
10668
|
+
if (pct > 40) return chalk112.yellow(label2);
|
|
10603
10669
|
return label2;
|
|
10604
10670
|
}
|
|
10605
10671
|
async function statusLine() {
|
|
@@ -10622,7 +10688,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10622
10688
|
// src/commands/sync/syncClaudeMd.ts
|
|
10623
10689
|
import * as fs23 from "fs";
|
|
10624
10690
|
import * as path46 from "path";
|
|
10625
|
-
import
|
|
10691
|
+
import chalk113 from "chalk";
|
|
10626
10692
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10627
10693
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10628
10694
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10631,12 +10697,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10631
10697
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10632
10698
|
if (sourceContent !== targetContent) {
|
|
10633
10699
|
console.log(
|
|
10634
|
-
|
|
10700
|
+
chalk113.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10635
10701
|
);
|
|
10636
10702
|
console.log();
|
|
10637
10703
|
printDiff(targetContent, sourceContent);
|
|
10638
10704
|
const confirm = options2?.yes || await promptConfirm(
|
|
10639
|
-
|
|
10705
|
+
chalk113.red("Overwrite existing CLAUDE.md?"),
|
|
10640
10706
|
false
|
|
10641
10707
|
);
|
|
10642
10708
|
if (!confirm) {
|
|
@@ -10652,7 +10718,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10652
10718
|
// src/commands/sync/syncSettings.ts
|
|
10653
10719
|
import * as fs24 from "fs";
|
|
10654
10720
|
import * as path47 from "path";
|
|
10655
|
-
import
|
|
10721
|
+
import chalk114 from "chalk";
|
|
10656
10722
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10657
10723
|
const source = path47.join(claudeDir, "settings.json");
|
|
10658
10724
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10668,14 +10734,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10668
10734
|
if (mergedContent !== normalizedTarget) {
|
|
10669
10735
|
if (!options2?.yes) {
|
|
10670
10736
|
console.log(
|
|
10671
|
-
|
|
10737
|
+
chalk114.yellow(
|
|
10672
10738
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10673
10739
|
)
|
|
10674
10740
|
);
|
|
10675
10741
|
console.log();
|
|
10676
10742
|
printDiff(targetContent, mergedContent);
|
|
10677
10743
|
const confirm = await promptConfirm(
|
|
10678
|
-
|
|
10744
|
+
chalk114.red("Overwrite existing settings.json?"),
|
|
10679
10745
|
false
|
|
10680
10746
|
);
|
|
10681
10747
|
if (!confirm) {
|
|
@@ -10693,11 +10759,13 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10693
10759
|
var __filename4 = fileURLToPath7(import.meta.url);
|
|
10694
10760
|
var __dirname7 = path48.dirname(__filename4);
|
|
10695
10761
|
async function sync(options2) {
|
|
10762
|
+
const config = loadConfig();
|
|
10763
|
+
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
10696
10764
|
const claudeDir = path48.join(__dirname7, "..", "claude");
|
|
10697
10765
|
const targetBase = path48.join(os.homedir(), ".claude");
|
|
10698
10766
|
syncCommands(claudeDir, targetBase);
|
|
10699
|
-
await syncSettings(claudeDir, targetBase, { yes
|
|
10700
|
-
await syncClaudeMd(claudeDir, targetBase, { yes
|
|
10767
|
+
await syncSettings(claudeDir, targetBase, { yes });
|
|
10768
|
+
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
10701
10769
|
}
|
|
10702
10770
|
function syncCommands(claudeDir, targetBase) {
|
|
10703
10771
|
const sourceDir = path48.join(claudeDir, "commands");
|
|
@@ -10737,12 +10805,12 @@ async function update() {
|
|
|
10737
10805
|
console.log("Building...");
|
|
10738
10806
|
execSync41("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
10739
10807
|
console.log("Syncing commands...");
|
|
10740
|
-
execSync41("assist sync
|
|
10808
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
10741
10809
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
10742
10810
|
console.log("Detected global npm installation, updating...");
|
|
10743
10811
|
execSync41("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
10744
10812
|
console.log("Syncing commands...");
|
|
10745
|
-
execSync41("assist sync
|
|
10813
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
10746
10814
|
} else {
|
|
10747
10815
|
console.error(
|
|
10748
10816
|
"Could not determine installation method. Expected a git repo or global npm install."
|
|
@@ -10758,7 +10826,7 @@ program.command("sync").description("Copy command files to ~/.claude/commands").
|
|
|
10758
10826
|
program.command("init").description("Initialize VS Code and verify configurations").action(init4);
|
|
10759
10827
|
program.command("commit").description("Create a git commit with validation").argument("<args...>", "status | <message> [files...]").action(commit);
|
|
10760
10828
|
var configCommand = program.command("config").description("View and modify assist.yml configuration");
|
|
10761
|
-
configCommand.command("set <key> <value>").description("Set a config value (e.g. commit.push true)").action(configSet);
|
|
10829
|
+
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));
|
|
10762
10830
|
configCommand.command("get <key>").description("Get a config value").action(configGet);
|
|
10763
10831
|
configCommand.command("list").description("List all config values").action(configList);
|
|
10764
10832
|
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) => {
|