@staff0rd/assist 0.173.1 → 0.174.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/backlog/web/bundle.js +20 -20
- package/dist/index.js +652 -567
- 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.174.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -100,12 +100,12 @@ async function exitOnCancel(promise) {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// src/commands/backlog/acquireLock.ts
|
|
103
|
-
import { existsSync as
|
|
104
|
-
import { join as
|
|
103
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
104
|
+
import { join as join5 } from "path";
|
|
105
105
|
|
|
106
106
|
// src/commands/backlog/shared.ts
|
|
107
|
-
import { existsSync as
|
|
108
|
-
import { join as
|
|
107
|
+
import { existsSync as existsSync3 } from "fs";
|
|
108
|
+
import { join as join4 } from "path";
|
|
109
109
|
import chalk from "chalk";
|
|
110
110
|
|
|
111
111
|
// src/commands/backlog/deleteItemRelations.ts
|
|
@@ -395,11 +395,32 @@ function migrateYamlIfNeeded(db, yamlPath) {
|
|
|
395
395
|
|
|
396
396
|
// src/commands/backlog/openDb.ts
|
|
397
397
|
import { mkdirSync } from "fs";
|
|
398
|
-
import { join as
|
|
398
|
+
import { join as join3 } from "path";
|
|
399
399
|
import Database from "better-sqlite3";
|
|
400
|
+
|
|
401
|
+
// src/commands/backlog/ensureGitignore.ts
|
|
402
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
403
|
+
import { join as join2 } from "path";
|
|
404
|
+
var gitignoreEntries = [
|
|
405
|
+
".assist/backlog.db",
|
|
406
|
+
".assist/backlog.db-shm",
|
|
407
|
+
".assist/backlog.db-wal"
|
|
408
|
+
];
|
|
409
|
+
function ensureGitignore(dir) {
|
|
410
|
+
const gitignorePath = join2(dir, ".gitignore");
|
|
411
|
+
const existing = existsSync2(gitignorePath) ? readFileSync3(gitignorePath, "utf-8") : "";
|
|
412
|
+
const lines = existing.split("\n");
|
|
413
|
+
const missing = gitignoreEntries.filter((entry) => !lines.includes(entry));
|
|
414
|
+
if (missing.length === 0) return;
|
|
415
|
+
const suffix = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
|
|
416
|
+
writeFileSync2(gitignorePath, `${existing}${suffix}${missing.join("\n")}
|
|
417
|
+
`);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// src/commands/backlog/openDb.ts
|
|
400
421
|
var _db;
|
|
401
422
|
function getDbPath(dir) {
|
|
402
|
-
return
|
|
423
|
+
return join3(dir, ".assist", "backlog.db");
|
|
403
424
|
}
|
|
404
425
|
function initSchema(db) {
|
|
405
426
|
db.exec(`
|
|
@@ -456,15 +477,35 @@ function initSchema(db) {
|
|
|
456
477
|
function openDb(dir) {
|
|
457
478
|
if (_db) return _db;
|
|
458
479
|
const dbPath = getDbPath(dir);
|
|
459
|
-
mkdirSync(
|
|
480
|
+
mkdirSync(join3(dir, ".assist"), { recursive: true });
|
|
460
481
|
const db = new Database(dbPath);
|
|
461
482
|
db.pragma("journal_mode = WAL");
|
|
462
483
|
db.pragma("foreign_keys = ON");
|
|
463
484
|
initSchema(db);
|
|
485
|
+
ensureGitignore(dir);
|
|
464
486
|
_db = db;
|
|
465
487
|
return db;
|
|
466
488
|
}
|
|
467
489
|
|
|
490
|
+
// src/commands/backlog/searchItemIds.ts
|
|
491
|
+
function searchItemIds(db, query) {
|
|
492
|
+
const pattern2 = `%${query}%`;
|
|
493
|
+
const rows = db.prepare(
|
|
494
|
+
`SELECT DISTINCT id FROM items
|
|
495
|
+
WHERE name LIKE ? COLLATE NOCASE
|
|
496
|
+
OR description LIKE ? COLLATE NOCASE
|
|
497
|
+
OR acceptance_criteria LIKE ? COLLATE NOCASE
|
|
498
|
+
UNION
|
|
499
|
+
SELECT DISTINCT item_id AS id FROM comments
|
|
500
|
+
WHERE text LIKE ? COLLATE NOCASE
|
|
501
|
+
UNION
|
|
502
|
+
SELECT DISTINCT item_id AS id FROM plan_phases
|
|
503
|
+
WHERE name LIKE ? COLLATE NOCASE
|
|
504
|
+
ORDER BY id`
|
|
505
|
+
).all(pattern2, pattern2, pattern2, pattern2, pattern2);
|
|
506
|
+
return rows.map((r) => r.id);
|
|
507
|
+
}
|
|
508
|
+
|
|
468
509
|
// src/commands/backlog/updateCurrentPhase.ts
|
|
469
510
|
function updateCurrentPhase(db, id, phase) {
|
|
470
511
|
const result = db.prepare("UPDATE items SET current_phase = ? WHERE id = ?").run(phase, id);
|
|
@@ -486,11 +527,11 @@ function getBacklogDir() {
|
|
|
486
527
|
return _backlogDir ?? process.cwd();
|
|
487
528
|
}
|
|
488
529
|
function getBacklogPath() {
|
|
489
|
-
return
|
|
530
|
+
return join4(getBacklogDir(), "assist.backlog.yml");
|
|
490
531
|
}
|
|
491
532
|
function backlogExists() {
|
|
492
533
|
const dir = getBacklogDir();
|
|
493
|
-
return
|
|
534
|
+
return existsSync3(join4(dir, ".assist", "backlog.db")) || existsSync3(join4(dir, ".assist", "backlog.jsonl")) || existsSync3(join4(dir, "assist.backlog.yml"));
|
|
494
535
|
}
|
|
495
536
|
function getDb() {
|
|
496
537
|
const dir = getBacklogDir();
|
|
@@ -504,6 +545,13 @@ function loadBacklog() {
|
|
|
504
545
|
importFromJsonlIfNeeded(db, getBacklogDir());
|
|
505
546
|
return loadAllItems(db);
|
|
506
547
|
}
|
|
548
|
+
function searchBacklog(query) {
|
|
549
|
+
const db = getDb();
|
|
550
|
+
importFromJsonlIfNeeded(db, getBacklogDir());
|
|
551
|
+
const ids = searchItemIds(db, query);
|
|
552
|
+
const allItems = loadAllItems(db);
|
|
553
|
+
return allItems.filter((item) => ids.includes(item.id));
|
|
554
|
+
}
|
|
507
555
|
function saveBacklog(items) {
|
|
508
556
|
const db = getDb();
|
|
509
557
|
saveAllItems(db, items);
|
|
@@ -551,7 +599,7 @@ function getNextId(items) {
|
|
|
551
599
|
|
|
552
600
|
// src/commands/backlog/acquireLock.ts
|
|
553
601
|
function getLockPath(itemId) {
|
|
554
|
-
return
|
|
602
|
+
return join5(getBacklogDir(), `.assist-lock-${itemId}.json`);
|
|
555
603
|
}
|
|
556
604
|
function isProcessAlive(pid) {
|
|
557
605
|
try {
|
|
@@ -563,9 +611,9 @@ function isProcessAlive(pid) {
|
|
|
563
611
|
}
|
|
564
612
|
function isLockedByOther(itemId) {
|
|
565
613
|
const lockPath = getLockPath(itemId);
|
|
566
|
-
if (!
|
|
614
|
+
if (!existsSync4(lockPath)) return false;
|
|
567
615
|
try {
|
|
568
|
-
const lock = JSON.parse(
|
|
616
|
+
const lock = JSON.parse(readFileSync4(lockPath, "utf-8"));
|
|
569
617
|
if (lock.pid === process.pid) return false;
|
|
570
618
|
return isProcessAlive(lock.pid);
|
|
571
619
|
} catch {
|
|
@@ -573,7 +621,7 @@ function isLockedByOther(itemId) {
|
|
|
573
621
|
}
|
|
574
622
|
}
|
|
575
623
|
function acquireLock(itemId) {
|
|
576
|
-
|
|
624
|
+
writeFileSync3(
|
|
577
625
|
getLockPath(itemId),
|
|
578
626
|
JSON.stringify({ pid: process.pid, timestamp: (/* @__PURE__ */ new Date()).toISOString() })
|
|
579
627
|
);
|
|
@@ -759,7 +807,7 @@ function buildReviewPhase() {
|
|
|
759
807
|
import chalk4 from "chalk";
|
|
760
808
|
|
|
761
809
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
762
|
-
import { existsSync as
|
|
810
|
+
import { existsSync as existsSync5, unlinkSync as unlinkSync2 } from "fs";
|
|
763
811
|
import chalk3 from "chalk";
|
|
764
812
|
|
|
765
813
|
// src/commands/backlog/handleIncompletePhase.ts
|
|
@@ -779,22 +827,22 @@ async function handleIncompletePhase() {
|
|
|
779
827
|
}
|
|
780
828
|
|
|
781
829
|
// src/commands/backlog/writeSignal.ts
|
|
782
|
-
import { writeFileSync as
|
|
783
|
-
import { join as
|
|
830
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
831
|
+
import { join as join6 } from "path";
|
|
784
832
|
var SIGNAL_FILE = ".assist-signal.json";
|
|
785
833
|
function getSignalPath() {
|
|
786
|
-
return
|
|
834
|
+
return join6(getBacklogDir(), SIGNAL_FILE);
|
|
787
835
|
}
|
|
788
836
|
function writeSignal(event, data) {
|
|
789
837
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
790
838
|
const signal = { event, ...sessionId && { sessionId }, ...data };
|
|
791
|
-
|
|
839
|
+
writeFileSync4(getSignalPath(), JSON.stringify(signal));
|
|
792
840
|
}
|
|
793
841
|
|
|
794
842
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
795
843
|
function cleanupSignal() {
|
|
796
844
|
const statusPath = getSignalPath();
|
|
797
|
-
if (
|
|
845
|
+
if (existsSync5(statusPath)) {
|
|
798
846
|
unlinkSync2(statusPath);
|
|
799
847
|
}
|
|
800
848
|
}
|
|
@@ -804,7 +852,7 @@ function isTerminalStatus(itemId) {
|
|
|
804
852
|
return item?.status === "done" || item?.status === "wontdo";
|
|
805
853
|
}
|
|
806
854
|
async function resolvePhaseResult(phaseIndex, itemId) {
|
|
807
|
-
if (!
|
|
855
|
+
if (!existsSync5(getSignalPath())) {
|
|
808
856
|
if (isTerminalStatus(itemId)) return -1;
|
|
809
857
|
const action = await handleIncompletePhase();
|
|
810
858
|
if (action === "abort") return -1;
|
|
@@ -834,15 +882,15 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
834
882
|
}
|
|
835
883
|
|
|
836
884
|
// src/commands/backlog/watchForMarker.ts
|
|
837
|
-
import { existsSync as
|
|
885
|
+
import { existsSync as existsSync7, unwatchFile, watchFile } from "fs";
|
|
838
886
|
|
|
839
887
|
// src/commands/backlog/readSignal.ts
|
|
840
|
-
import { existsSync as
|
|
888
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
841
889
|
function readSignal() {
|
|
842
890
|
const path50 = getSignalPath();
|
|
843
|
-
if (!
|
|
891
|
+
if (!existsSync6(path50)) return void 0;
|
|
844
892
|
try {
|
|
845
|
-
return JSON.parse(
|
|
893
|
+
return JSON.parse(readFileSync5(path50, "utf-8"));
|
|
846
894
|
} catch {
|
|
847
895
|
return void 0;
|
|
848
896
|
}
|
|
@@ -853,7 +901,7 @@ function watchForMarker(child) {
|
|
|
853
901
|
const statusPath = getSignalPath();
|
|
854
902
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
855
903
|
watchFile(statusPath, { interval: 1e3 }, () => {
|
|
856
|
-
if (!
|
|
904
|
+
if (!existsSync7(statusPath)) return;
|
|
857
905
|
const signal = readSignal();
|
|
858
906
|
if (signal && (!signal.sessionId || signal.sessionId === sessionId)) {
|
|
859
907
|
unwatchFile(statusPath);
|
|
@@ -1207,11 +1255,11 @@ function printComments(item) {
|
|
|
1207
1255
|
|
|
1208
1256
|
// src/shared/web.ts
|
|
1209
1257
|
import { exec } from "child_process";
|
|
1210
|
-
import { readFileSync as
|
|
1258
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
1211
1259
|
import {
|
|
1212
1260
|
createServer
|
|
1213
1261
|
} from "http";
|
|
1214
|
-
import { dirname, join as
|
|
1262
|
+
import { dirname, join as join7 } from "path";
|
|
1215
1263
|
import { fileURLToPath } from "url";
|
|
1216
1264
|
import chalk14 from "chalk";
|
|
1217
1265
|
function respondJson(res, status2, data) {
|
|
@@ -1223,7 +1271,7 @@ function createBundleHandler(importMetaUrl, bundlePath) {
|
|
|
1223
1271
|
let cache;
|
|
1224
1272
|
return (_req, res) => {
|
|
1225
1273
|
if (!cache) {
|
|
1226
|
-
cache =
|
|
1274
|
+
cache = readFileSync6(join7(dir, bundlePath), "utf-8");
|
|
1227
1275
|
}
|
|
1228
1276
|
res.writeHead(200, { "Content-Type": "application/javascript" });
|
|
1229
1277
|
res.end(cache);
|
|
@@ -1305,8 +1353,10 @@ async function parseStatusBody(req) {
|
|
|
1305
1353
|
}
|
|
1306
1354
|
|
|
1307
1355
|
// src/commands/backlog/web/shared.ts
|
|
1308
|
-
function listItems(
|
|
1309
|
-
|
|
1356
|
+
function listItems(req, res) {
|
|
1357
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
1358
|
+
const q = url.searchParams.get("q");
|
|
1359
|
+
respondJson(res, 200, q ? searchBacklog(q) : loadBacklog());
|
|
1310
1360
|
}
|
|
1311
1361
|
function findItemOr404(res, id) {
|
|
1312
1362
|
const items = loadBacklog();
|
|
@@ -1435,19 +1485,19 @@ async function launchMode(slashCommand) {
|
|
|
1435
1485
|
import { execSync } from "child_process";
|
|
1436
1486
|
|
|
1437
1487
|
// src/shared/loadConfig.ts
|
|
1438
|
-
import { existsSync as
|
|
1488
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
1439
1489
|
import { homedir } from "os";
|
|
1440
|
-
import { basename, dirname as dirname2, join as
|
|
1490
|
+
import { basename, dirname as dirname2, join as join8 } from "path";
|
|
1441
1491
|
import chalk16 from "chalk";
|
|
1442
1492
|
import { stringify as stringifyYaml } from "yaml";
|
|
1443
1493
|
|
|
1444
1494
|
// src/shared/loadRawYaml.ts
|
|
1445
|
-
import { existsSync as
|
|
1495
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
1446
1496
|
import { parse as parseYaml2 } from "yaml";
|
|
1447
1497
|
function loadRawYaml(path50) {
|
|
1448
|
-
if (!
|
|
1498
|
+
if (!existsSync8(path50)) return {};
|
|
1449
1499
|
try {
|
|
1450
|
-
const content =
|
|
1500
|
+
const content = readFileSync7(path50, "utf-8");
|
|
1451
1501
|
return parseYaml2(content) || {};
|
|
1452
1502
|
} catch {
|
|
1453
1503
|
return {};
|
|
@@ -1577,10 +1627,10 @@ var assistConfigSchema = z2.strictObject({
|
|
|
1577
1627
|
function findConfigUp(startDir) {
|
|
1578
1628
|
let current = startDir;
|
|
1579
1629
|
while (current !== dirname2(current)) {
|
|
1580
|
-
const claudePath =
|
|
1581
|
-
if (
|
|
1582
|
-
const rootPath =
|
|
1583
|
-
if (
|
|
1630
|
+
const claudePath = join8(current, ".claude", "assist.yml");
|
|
1631
|
+
if (existsSync9(claudePath)) return claudePath;
|
|
1632
|
+
const rootPath = join8(current, "assist.yml");
|
|
1633
|
+
if (existsSync9(rootPath)) return rootPath;
|
|
1584
1634
|
current = dirname2(current);
|
|
1585
1635
|
}
|
|
1586
1636
|
return null;
|
|
@@ -1588,10 +1638,10 @@ function findConfigUp(startDir) {
|
|
|
1588
1638
|
function getConfigPath() {
|
|
1589
1639
|
const found = findConfigUp(process.cwd());
|
|
1590
1640
|
if (found) return found;
|
|
1591
|
-
return
|
|
1641
|
+
return join8(process.cwd(), "assist.yml");
|
|
1592
1642
|
}
|
|
1593
1643
|
function getGlobalConfigPath() {
|
|
1594
|
-
return
|
|
1644
|
+
return join8(homedir(), ".assist.yml");
|
|
1595
1645
|
}
|
|
1596
1646
|
function loadConfig() {
|
|
1597
1647
|
const globalRaw = loadRawYaml(getGlobalConfigPath());
|
|
@@ -1606,21 +1656,21 @@ function loadGlobalConfigRaw() {
|
|
|
1606
1656
|
return loadRawYaml(getGlobalConfigPath());
|
|
1607
1657
|
}
|
|
1608
1658
|
function saveGlobalConfig(config) {
|
|
1609
|
-
|
|
1659
|
+
writeFileSync5(getGlobalConfigPath(), stringifyYaml(config, { lineWidth: 0 }));
|
|
1610
1660
|
}
|
|
1611
1661
|
function saveConfig(config) {
|
|
1612
1662
|
const configPath = getConfigPath();
|
|
1613
|
-
|
|
1663
|
+
writeFileSync5(configPath, stringifyYaml(config, { lineWidth: 0 }));
|
|
1614
1664
|
}
|
|
1615
1665
|
function getRepoName() {
|
|
1616
1666
|
const config = loadConfig();
|
|
1617
1667
|
if (config.devlog?.name) {
|
|
1618
1668
|
return config.devlog.name;
|
|
1619
1669
|
}
|
|
1620
|
-
const packageJsonPath =
|
|
1621
|
-
if (
|
|
1670
|
+
const packageJsonPath = join8(process.cwd(), "package.json");
|
|
1671
|
+
if (existsSync9(packageJsonPath)) {
|
|
1622
1672
|
try {
|
|
1623
|
-
const content =
|
|
1673
|
+
const content = readFileSync8(packageJsonPath, "utf-8");
|
|
1624
1674
|
const pkg = JSON.parse(content);
|
|
1625
1675
|
if (pkg.name) {
|
|
1626
1676
|
return pkg.name;
|
|
@@ -1961,10 +2011,10 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1961
2011
|
|
|
1962
2012
|
// src/commands/verify/installPackage.ts
|
|
1963
2013
|
import { execSync as execSync3 } from "child_process";
|
|
1964
|
-
import { writeFileSync as
|
|
2014
|
+
import { writeFileSync as writeFileSync6 } from "fs";
|
|
1965
2015
|
import chalk21 from "chalk";
|
|
1966
2016
|
function writePackageJson(filePath, pkg) {
|
|
1967
|
-
|
|
2017
|
+
writeFileSync6(filePath, `${JSON.stringify(pkg, null, 2)}
|
|
1968
2018
|
`);
|
|
1969
2019
|
}
|
|
1970
2020
|
function addScript(pkg, name, command) {
|
|
@@ -2069,23 +2119,23 @@ import * as path3 from "path";
|
|
|
2069
2119
|
import chalk25 from "chalk";
|
|
2070
2120
|
|
|
2071
2121
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
2072
|
-
import { existsSync as
|
|
2073
|
-
import { join as
|
|
2122
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "fs";
|
|
2123
|
+
import { join as join10 } from "path";
|
|
2074
2124
|
import chalk24 from "chalk";
|
|
2075
2125
|
function loadKnipConfig(knipJsonPath) {
|
|
2076
|
-
if (
|
|
2077
|
-
return JSON.parse(
|
|
2126
|
+
if (existsSync11(knipJsonPath)) {
|
|
2127
|
+
return JSON.parse(readFileSync10(knipJsonPath, "utf-8"));
|
|
2078
2128
|
}
|
|
2079
2129
|
return { $schema: "https://unpkg.com/knip@5/schema.json" };
|
|
2080
2130
|
}
|
|
2081
2131
|
function addToKnipIgnoreBinaries(cwd, binary) {
|
|
2082
|
-
const knipJsonPath =
|
|
2132
|
+
const knipJsonPath = join10(cwd, "knip.json");
|
|
2083
2133
|
try {
|
|
2084
2134
|
const knipConfig = loadKnipConfig(knipJsonPath);
|
|
2085
2135
|
const ignoreBinaries = knipConfig.ignoreBinaries ?? [];
|
|
2086
2136
|
if (!ignoreBinaries.includes(binary)) {
|
|
2087
2137
|
knipConfig.ignoreBinaries = [...ignoreBinaries, binary];
|
|
2088
|
-
|
|
2138
|
+
writeFileSync7(
|
|
2089
2139
|
knipJsonPath,
|
|
2090
2140
|
`${JSON.stringify(knipConfig, null, " ")}
|
|
2091
2141
|
`
|
|
@@ -2127,8 +2177,8 @@ import chalk29 from "chalk";
|
|
|
2127
2177
|
|
|
2128
2178
|
// src/commands/lint/init.ts
|
|
2129
2179
|
import { execSync as execSync5 } from "child_process";
|
|
2130
|
-
import { existsSync as
|
|
2131
|
-
import { dirname as dirname7, join as
|
|
2180
|
+
import { existsSync as existsSync14, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
|
|
2181
|
+
import { dirname as dirname7, join as join11 } from "path";
|
|
2132
2182
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2133
2183
|
import chalk28 from "chalk";
|
|
2134
2184
|
|
|
@@ -2153,10 +2203,10 @@ async function promptConfirm(message, initial = true) {
|
|
|
2153
2203
|
|
|
2154
2204
|
// src/shared/removeEslint/index.ts
|
|
2155
2205
|
import { execSync as execSync4 } from "child_process";
|
|
2156
|
-
import { existsSync as
|
|
2206
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
2157
2207
|
|
|
2158
2208
|
// src/shared/removeEslint/removeEslintConfigFiles.ts
|
|
2159
|
-
import { existsSync as
|
|
2209
|
+
import { existsSync as existsSync12, unlinkSync as unlinkSync3 } from "fs";
|
|
2160
2210
|
var ESLINT_CONFIG_FILES = [
|
|
2161
2211
|
"eslint.config.js",
|
|
2162
2212
|
"eslint.config.mjs",
|
|
@@ -2172,7 +2222,7 @@ var ESLINT_CONFIG_FILES = [
|
|
|
2172
2222
|
function removeEslintConfigFiles() {
|
|
2173
2223
|
let removed = false;
|
|
2174
2224
|
for (const configFile of ESLINT_CONFIG_FILES) {
|
|
2175
|
-
if (
|
|
2225
|
+
if (existsSync12(configFile)) {
|
|
2176
2226
|
unlinkSync3(configFile);
|
|
2177
2227
|
console.log(`Removed ${configFile}`);
|
|
2178
2228
|
removed = true;
|
|
@@ -2194,16 +2244,16 @@ function removeEslint(options2 = {}) {
|
|
|
2194
2244
|
}
|
|
2195
2245
|
function removeEslintFromPackageJson(options2) {
|
|
2196
2246
|
const packageJsonPath = "package.json";
|
|
2197
|
-
if (!
|
|
2247
|
+
if (!existsSync13(packageJsonPath)) {
|
|
2198
2248
|
return false;
|
|
2199
2249
|
}
|
|
2200
|
-
const packageJson = JSON.parse(
|
|
2250
|
+
const packageJson = JSON.parse(readFileSync11(packageJsonPath, "utf-8"));
|
|
2201
2251
|
let modified = false;
|
|
2202
2252
|
modified = removeEslintDeps(packageJson.dependencies) || modified;
|
|
2203
2253
|
modified = removeEslintDeps(packageJson.devDependencies) || modified;
|
|
2204
2254
|
modified = removeEslintScripts(packageJson.scripts, options2) || modified;
|
|
2205
2255
|
if (modified) {
|
|
2206
|
-
|
|
2256
|
+
writeFileSync8(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
2207
2257
|
`);
|
|
2208
2258
|
console.log("Removed eslint references from package.json");
|
|
2209
2259
|
}
|
|
@@ -2267,17 +2317,17 @@ var __dirname2 = dirname7(fileURLToPath2(import.meta.url));
|
|
|
2267
2317
|
async function init() {
|
|
2268
2318
|
removeEslint();
|
|
2269
2319
|
const biomeConfigPath = "biome.json";
|
|
2270
|
-
if (!
|
|
2320
|
+
if (!existsSync14(biomeConfigPath)) {
|
|
2271
2321
|
console.log("Initializing Biome...");
|
|
2272
2322
|
execSync5("npx @biomejs/biome init", { stdio: "inherit" });
|
|
2273
2323
|
}
|
|
2274
|
-
if (!
|
|
2324
|
+
if (!existsSync14(biomeConfigPath)) {
|
|
2275
2325
|
console.log("No biome.json found, skipping linter config");
|
|
2276
2326
|
return;
|
|
2277
2327
|
}
|
|
2278
|
-
const linterConfigPath =
|
|
2279
|
-
const linterConfig = JSON.parse(
|
|
2280
|
-
const biomeConfig = JSON.parse(
|
|
2328
|
+
const linterConfigPath = join11(__dirname2, "commands/lint/biome.linter.json");
|
|
2329
|
+
const linterConfig = JSON.parse(readFileSync12(linterConfigPath, "utf-8"));
|
|
2330
|
+
const biomeConfig = JSON.parse(readFileSync12(biomeConfigPath, "utf-8"));
|
|
2281
2331
|
const oldContent = `${JSON.stringify(biomeConfig, null, 2)}
|
|
2282
2332
|
`;
|
|
2283
2333
|
biomeConfig.linter = linterConfig.linter;
|
|
@@ -2298,7 +2348,7 @@ async function init() {
|
|
|
2298
2348
|
console.log("Skipped biome.json update");
|
|
2299
2349
|
return;
|
|
2300
2350
|
}
|
|
2301
|
-
|
|
2351
|
+
writeFileSync9(biomeConfigPath, newContent);
|
|
2302
2352
|
console.log("Updated biome.json with linter config");
|
|
2303
2353
|
}
|
|
2304
2354
|
|
|
@@ -3312,11 +3362,11 @@ async function run2(options2 = {}) {
|
|
|
3312
3362
|
|
|
3313
3363
|
// src/commands/new/registerNew/initGit.ts
|
|
3314
3364
|
import { execSync as execSync9 } from "child_process";
|
|
3315
|
-
import { writeFileSync as
|
|
3365
|
+
import { writeFileSync as writeFileSync11 } from "fs";
|
|
3316
3366
|
function initGit() {
|
|
3317
3367
|
console.log("Initializing git repository...");
|
|
3318
3368
|
execSync9("git init", { stdio: "inherit" });
|
|
3319
|
-
|
|
3369
|
+
writeFileSync11(".gitignore", "dist\nnode_modules\n");
|
|
3320
3370
|
}
|
|
3321
3371
|
|
|
3322
3372
|
// src/commands/new/registerNew/newCli/initPackageJson.ts
|
|
@@ -3335,10 +3385,10 @@ function initPackageJson(name) {
|
|
|
3335
3385
|
}
|
|
3336
3386
|
|
|
3337
3387
|
// src/commands/new/registerNew/newCli/writeCliTemplate.ts
|
|
3338
|
-
import { mkdirSync as mkdirSync3, writeFileSync as
|
|
3388
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync12 } from "fs";
|
|
3339
3389
|
function writeCliTemplate(name) {
|
|
3340
3390
|
console.log("Writing tsconfig.json...");
|
|
3341
|
-
|
|
3391
|
+
writeFileSync12(
|
|
3342
3392
|
"tsconfig.json",
|
|
3343
3393
|
JSON.stringify(
|
|
3344
3394
|
{
|
|
@@ -3362,7 +3412,7 @@ function writeCliTemplate(name) {
|
|
|
3362
3412
|
)
|
|
3363
3413
|
);
|
|
3364
3414
|
console.log("Writing tsup.config.ts...");
|
|
3365
|
-
|
|
3415
|
+
writeFileSync12(
|
|
3366
3416
|
"tsup.config.ts",
|
|
3367
3417
|
`import { defineConfig } from "tsup";
|
|
3368
3418
|
export default defineConfig({
|
|
@@ -3377,7 +3427,7 @@ export default defineConfig({
|
|
|
3377
3427
|
);
|
|
3378
3428
|
console.log("Writing src/index.ts...");
|
|
3379
3429
|
mkdirSync3("src", { recursive: true });
|
|
3380
|
-
|
|
3430
|
+
writeFileSync12(
|
|
3381
3431
|
"src/index.ts",
|
|
3382
3432
|
`#!/usr/bin/env node
|
|
3383
3433
|
import { Command } from "commander";
|
|
@@ -3405,7 +3455,7 @@ async function newCli() {
|
|
|
3405
3455
|
|
|
3406
3456
|
// src/commands/new/registerNew/newProject.ts
|
|
3407
3457
|
import { execSync as execSync13 } from "child_process";
|
|
3408
|
-
import { existsSync as
|
|
3458
|
+
import { existsSync as existsSync18, readFileSync as readFileSync15, writeFileSync as writeFileSync14 } from "fs";
|
|
3409
3459
|
|
|
3410
3460
|
// src/commands/deploy/init/index.ts
|
|
3411
3461
|
import { execSync as execSync12 } from "child_process";
|
|
@@ -3413,33 +3463,33 @@ import chalk40 from "chalk";
|
|
|
3413
3463
|
import enquirer5 from "enquirer";
|
|
3414
3464
|
|
|
3415
3465
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
3416
|
-
import { existsSync as
|
|
3417
|
-
import { dirname as dirname13, join as
|
|
3466
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync4, readFileSync as readFileSync14, writeFileSync as writeFileSync13 } from "fs";
|
|
3467
|
+
import { dirname as dirname13, join as join14 } from "path";
|
|
3418
3468
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3419
3469
|
import chalk39 from "chalk";
|
|
3420
3470
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
3421
3471
|
var __dirname3 = dirname13(fileURLToPath3(import.meta.url));
|
|
3422
3472
|
function getExistingSiteId() {
|
|
3423
|
-
if (!
|
|
3473
|
+
if (!existsSync17(WORKFLOW_PATH)) {
|
|
3424
3474
|
return null;
|
|
3425
3475
|
}
|
|
3426
|
-
const content =
|
|
3476
|
+
const content = readFileSync14(WORKFLOW_PATH, "utf-8");
|
|
3427
3477
|
const match = content.match(/-s\s+([a-f0-9-]{36})/);
|
|
3428
3478
|
return match ? match[1] : null;
|
|
3429
3479
|
}
|
|
3430
3480
|
function getTemplateContent(siteId) {
|
|
3431
|
-
const templatePath =
|
|
3432
|
-
const template =
|
|
3481
|
+
const templatePath = join14(__dirname3, "commands/deploy/build.yml");
|
|
3482
|
+
const template = readFileSync14(templatePath, "utf-8");
|
|
3433
3483
|
return template.replace("{{NETLIFY_SITE_ID}}", siteId);
|
|
3434
3484
|
}
|
|
3435
3485
|
async function updateWorkflow(siteId) {
|
|
3436
3486
|
const newContent = getTemplateContent(siteId);
|
|
3437
3487
|
const workflowDir = ".github/workflows";
|
|
3438
|
-
if (!
|
|
3488
|
+
if (!existsSync17(workflowDir)) {
|
|
3439
3489
|
mkdirSync4(workflowDir, { recursive: true });
|
|
3440
3490
|
}
|
|
3441
|
-
if (
|
|
3442
|
-
const oldContent =
|
|
3491
|
+
if (existsSync17(WORKFLOW_PATH)) {
|
|
3492
|
+
const oldContent = readFileSync14(WORKFLOW_PATH, "utf-8");
|
|
3443
3493
|
if (oldContent === newContent) {
|
|
3444
3494
|
console.log(chalk39.green("build.yml is already up to date"));
|
|
3445
3495
|
return;
|
|
@@ -3453,7 +3503,7 @@ async function updateWorkflow(siteId) {
|
|
|
3453
3503
|
return;
|
|
3454
3504
|
}
|
|
3455
3505
|
}
|
|
3456
|
-
|
|
3506
|
+
writeFileSync13(WORKFLOW_PATH, newContent);
|
|
3457
3507
|
console.log(chalk39.green(`
|
|
3458
3508
|
Created ${WORKFLOW_PATH}`));
|
|
3459
3509
|
}
|
|
@@ -3533,11 +3583,11 @@ async function newProject() {
|
|
|
3533
3583
|
}
|
|
3534
3584
|
function addViteBaseConfig() {
|
|
3535
3585
|
const viteConfigPath = "vite.config.ts";
|
|
3536
|
-
if (!
|
|
3586
|
+
if (!existsSync18(viteConfigPath)) {
|
|
3537
3587
|
console.log("No vite.config.ts found, skipping base config");
|
|
3538
3588
|
return;
|
|
3539
3589
|
}
|
|
3540
|
-
const content =
|
|
3590
|
+
const content = readFileSync15(viteConfigPath, "utf-8");
|
|
3541
3591
|
if (content.includes("base:")) {
|
|
3542
3592
|
console.log("vite.config.ts already has base config");
|
|
3543
3593
|
return;
|
|
@@ -3547,7 +3597,7 @@ function addViteBaseConfig() {
|
|
|
3547
3597
|
'defineConfig({\n base: "./",'
|
|
3548
3598
|
);
|
|
3549
3599
|
if (updated !== content) {
|
|
3550
|
-
|
|
3600
|
+
writeFileSync14(viteConfigPath, updated);
|
|
3551
3601
|
console.log('Added base: "./" to vite.config.ts');
|
|
3552
3602
|
}
|
|
3553
3603
|
}
|
|
@@ -3719,11 +3769,11 @@ import chalk44 from "chalk";
|
|
|
3719
3769
|
|
|
3720
3770
|
// src/commands/backlog/commitBacklog.ts
|
|
3721
3771
|
import { execSync as execSync14 } from "child_process";
|
|
3722
|
-
import { join as
|
|
3772
|
+
import { join as join15 } from "path";
|
|
3723
3773
|
import chalk43 from "chalk";
|
|
3724
3774
|
function commitBacklog(id, name) {
|
|
3725
3775
|
try {
|
|
3726
|
-
const jsonlPath =
|
|
3776
|
+
const jsonlPath = join15(getBacklogDir(), ".assist", "backlog.jsonl");
|
|
3727
3777
|
const message = `chore: add backlog item #${id} \u2014 ${name}`;
|
|
3728
3778
|
execSync14(`git add ${shellQuote(jsonlPath)}`, { stdio: "ignore" });
|
|
3729
3779
|
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
@@ -3734,9 +3784,9 @@ function commitBacklog(id, name) {
|
|
|
3734
3784
|
|
|
3735
3785
|
// src/commands/backlog/add/shared.ts
|
|
3736
3786
|
import { spawnSync } from "child_process";
|
|
3737
|
-
import { mkdtempSync, readFileSync as
|
|
3787
|
+
import { mkdtempSync, readFileSync as readFileSync16, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
|
|
3738
3788
|
import { tmpdir } from "os";
|
|
3739
|
-
import { join as
|
|
3789
|
+
import { join as join16 } from "path";
|
|
3740
3790
|
import enquirer6 from "enquirer";
|
|
3741
3791
|
async function promptType() {
|
|
3742
3792
|
const { type } = await enquirer6.prompt({
|
|
@@ -3776,15 +3826,15 @@ async function promptDescription() {
|
|
|
3776
3826
|
}
|
|
3777
3827
|
function openEditor() {
|
|
3778
3828
|
const editor = process.env.EDITOR || process.env.VISUAL || "vi";
|
|
3779
|
-
const dir = mkdtempSync(
|
|
3780
|
-
const filePath =
|
|
3781
|
-
|
|
3829
|
+
const dir = mkdtempSync(join16(tmpdir(), "assist-"));
|
|
3830
|
+
const filePath = join16(dir, "description.md");
|
|
3831
|
+
writeFileSync15(filePath, "");
|
|
3782
3832
|
const result = spawnSync(editor, [filePath], { stdio: "inherit" });
|
|
3783
3833
|
if (result.status !== 0) {
|
|
3784
3834
|
unlinkSync4(filePath);
|
|
3785
3835
|
return void 0;
|
|
3786
3836
|
}
|
|
3787
|
-
const content =
|
|
3837
|
+
const content = readFileSync16(filePath, "utf-8").trim();
|
|
3788
3838
|
unlinkSync4(filePath);
|
|
3789
3839
|
return content || void 0;
|
|
3790
3840
|
}
|
|
@@ -4046,17 +4096,51 @@ function registerLinkCommands(cmd) {
|
|
|
4046
4096
|
cmd.command("unlink <from> <to>").description("Remove a link between two backlog items").action(unlink);
|
|
4047
4097
|
}
|
|
4048
4098
|
|
|
4049
|
-
// src/commands/backlog/
|
|
4099
|
+
// src/commands/backlog/search/index.ts
|
|
4050
4100
|
import chalk51 from "chalk";
|
|
4101
|
+
async function search(query) {
|
|
4102
|
+
if (!backlogExists()) {
|
|
4103
|
+
console.log(
|
|
4104
|
+
chalk51.yellow(
|
|
4105
|
+
"No backlog found. Run 'assist backlog init' to create one."
|
|
4106
|
+
)
|
|
4107
|
+
);
|
|
4108
|
+
return;
|
|
4109
|
+
}
|
|
4110
|
+
const items = searchBacklog(query);
|
|
4111
|
+
if (items.length === 0) {
|
|
4112
|
+
console.log(chalk51.dim(`No items matching "${query}".`));
|
|
4113
|
+
return;
|
|
4114
|
+
}
|
|
4115
|
+
console.log(
|
|
4116
|
+
chalk51.dim(
|
|
4117
|
+
`${items.length} item${items.length === 1 ? "" : "s"} matching "${query}":
|
|
4118
|
+
`
|
|
4119
|
+
)
|
|
4120
|
+
);
|
|
4121
|
+
for (const item of items) {
|
|
4122
|
+
console.log(
|
|
4123
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk51.dim(`#${item.id}`)} ${item.name}`
|
|
4124
|
+
);
|
|
4125
|
+
}
|
|
4126
|
+
}
|
|
4127
|
+
|
|
4128
|
+
// src/commands/backlog/registerSearchCommand.ts
|
|
4129
|
+
function registerSearchCommand(cmd) {
|
|
4130
|
+
cmd.command("search <query>").description("Search backlog items by keyword").action(search);
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4133
|
+
// src/commands/backlog/delete/index.ts
|
|
4134
|
+
import chalk52 from "chalk";
|
|
4051
4135
|
async function del(id) {
|
|
4052
4136
|
const name = removeItem(id);
|
|
4053
4137
|
if (name) {
|
|
4054
|
-
console.log(
|
|
4138
|
+
console.log(chalk52.green(`Deleted item #${id}: ${name}`));
|
|
4055
4139
|
}
|
|
4056
4140
|
}
|
|
4057
4141
|
|
|
4058
4142
|
// src/commands/backlog/done/index.ts
|
|
4059
|
-
import
|
|
4143
|
+
import chalk53 from "chalk";
|
|
4060
4144
|
async function done(id, summary) {
|
|
4061
4145
|
const result = loadAndFindItem(id);
|
|
4062
4146
|
if (!result) return;
|
|
@@ -4066,20 +4150,20 @@ async function done(id, summary) {
|
|
|
4066
4150
|
addPhaseSummary(result.item, summary, phase);
|
|
4067
4151
|
}
|
|
4068
4152
|
saveBacklog(result.items);
|
|
4069
|
-
console.log(
|
|
4153
|
+
console.log(chalk53.green(`Completed item #${id}: ${result.item.name}`));
|
|
4070
4154
|
}
|
|
4071
4155
|
|
|
4072
4156
|
// src/commands/backlog/start/index.ts
|
|
4073
|
-
import
|
|
4157
|
+
import chalk54 from "chalk";
|
|
4074
4158
|
async function start(id) {
|
|
4075
4159
|
const name = setStatus(id, "in-progress");
|
|
4076
4160
|
if (name) {
|
|
4077
|
-
console.log(
|
|
4161
|
+
console.log(chalk54.green(`Started item #${id}: ${name}`));
|
|
4078
4162
|
}
|
|
4079
4163
|
}
|
|
4080
4164
|
|
|
4081
4165
|
// src/commands/backlog/wontdo/index.ts
|
|
4082
|
-
import
|
|
4166
|
+
import chalk55 from "chalk";
|
|
4083
4167
|
async function wontdo(id, reason) {
|
|
4084
4168
|
const result = loadAndFindItem(id);
|
|
4085
4169
|
if (!result) return;
|
|
@@ -4089,7 +4173,7 @@ async function wontdo(id, reason) {
|
|
|
4089
4173
|
addPhaseSummary(result.item, reason, phase);
|
|
4090
4174
|
}
|
|
4091
4175
|
saveBacklog(result.items);
|
|
4092
|
-
console.log(
|
|
4176
|
+
console.log(chalk55.red(`Won't do item #${id}: ${result.item.name}`));
|
|
4093
4177
|
}
|
|
4094
4178
|
|
|
4095
4179
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -4134,6 +4218,7 @@ function registerBacklog(program2) {
|
|
|
4134
4218
|
registerPlanCommands(cmd);
|
|
4135
4219
|
registerNextCommand(cmd);
|
|
4136
4220
|
registerRunCommand(cmd);
|
|
4221
|
+
registerSearchCommand(cmd);
|
|
4137
4222
|
}
|
|
4138
4223
|
|
|
4139
4224
|
// src/shared/isApprovedRead.ts
|
|
@@ -4218,7 +4303,7 @@ function extractGraphqlQuery(args) {
|
|
|
4218
4303
|
}
|
|
4219
4304
|
|
|
4220
4305
|
// src/shared/loadCliReads.ts
|
|
4221
|
-
import { existsSync as
|
|
4306
|
+
import { existsSync as existsSync19, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
|
|
4222
4307
|
import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
4223
4308
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
4224
4309
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
@@ -4227,8 +4312,8 @@ function packageRoot() {
|
|
|
4227
4312
|
return __dirname4;
|
|
4228
4313
|
}
|
|
4229
4314
|
function readLines(path50) {
|
|
4230
|
-
if (!
|
|
4231
|
-
return
|
|
4315
|
+
if (!existsSync19(path50)) return [];
|
|
4316
|
+
return readFileSync17(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
4232
4317
|
}
|
|
4233
4318
|
var cachedReads;
|
|
4234
4319
|
var cachedWrites;
|
|
@@ -4248,7 +4333,7 @@ function loadCliReads() {
|
|
|
4248
4333
|
return getCliReadsLines();
|
|
4249
4334
|
}
|
|
4250
4335
|
function saveCliReads(commands) {
|
|
4251
|
-
|
|
4336
|
+
writeFileSync16(
|
|
4252
4337
|
resolve2(packageRoot(), "allowed.cli-reads"),
|
|
4253
4338
|
`${commands.join("\n")}
|
|
4254
4339
|
`
|
|
@@ -4274,14 +4359,14 @@ function findCliWrite(command) {
|
|
|
4274
4359
|
}
|
|
4275
4360
|
|
|
4276
4361
|
// src/shared/readSettingsPerms.ts
|
|
4277
|
-
import { existsSync as
|
|
4362
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
|
|
4278
4363
|
import { homedir as homedir3 } from "os";
|
|
4279
|
-
import { join as
|
|
4364
|
+
import { join as join17 } from "path";
|
|
4280
4365
|
function readSettingsPerms(key) {
|
|
4281
4366
|
const paths = [
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4367
|
+
join17(homedir3(), ".claude", "settings.json"),
|
|
4368
|
+
join17(process.cwd(), ".claude", "settings.json"),
|
|
4369
|
+
join17(process.cwd(), ".claude", "settings.local.json")
|
|
4285
4370
|
];
|
|
4286
4371
|
const entries = [];
|
|
4287
4372
|
for (const p of paths) {
|
|
@@ -4290,9 +4375,9 @@ function readSettingsPerms(key) {
|
|
|
4290
4375
|
return entries;
|
|
4291
4376
|
}
|
|
4292
4377
|
function readPermissionArray(filePath, key) {
|
|
4293
|
-
if (!
|
|
4378
|
+
if (!existsSync20(filePath)) return [];
|
|
4294
4379
|
try {
|
|
4295
|
-
const data = JSON.parse(
|
|
4380
|
+
const data = JSON.parse(readFileSync18(filePath, "utf-8"));
|
|
4296
4381
|
const arr = data?.permissions?.[key];
|
|
4297
4382
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
4298
4383
|
} catch {
|
|
@@ -4541,54 +4626,54 @@ ${reasons.join("\n")}`);
|
|
|
4541
4626
|
}
|
|
4542
4627
|
|
|
4543
4628
|
// src/commands/deny/denyAdd.ts
|
|
4544
|
-
import
|
|
4629
|
+
import chalk56 from "chalk";
|
|
4545
4630
|
function denyAdd(pattern2, message) {
|
|
4546
4631
|
const config = loadProjectConfig();
|
|
4547
4632
|
const deny = config.deny ?? [];
|
|
4548
4633
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
4549
|
-
console.log(
|
|
4634
|
+
console.log(chalk56.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
4550
4635
|
return;
|
|
4551
4636
|
}
|
|
4552
4637
|
deny.push({ pattern: pattern2, message });
|
|
4553
4638
|
config.deny = deny;
|
|
4554
4639
|
saveConfig(config);
|
|
4555
|
-
console.log(
|
|
4640
|
+
console.log(chalk56.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
4556
4641
|
}
|
|
4557
4642
|
|
|
4558
4643
|
// src/commands/deny/denyList.ts
|
|
4559
|
-
import
|
|
4644
|
+
import chalk57 from "chalk";
|
|
4560
4645
|
function denyList() {
|
|
4561
4646
|
const config = loadConfig();
|
|
4562
4647
|
const deny = config.deny;
|
|
4563
4648
|
if (!deny || deny.length === 0) {
|
|
4564
|
-
console.log(
|
|
4649
|
+
console.log(chalk57.dim("No deny rules configured."));
|
|
4565
4650
|
return;
|
|
4566
4651
|
}
|
|
4567
4652
|
for (const rule of deny) {
|
|
4568
|
-
console.log(`${
|
|
4653
|
+
console.log(`${chalk57.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
4569
4654
|
}
|
|
4570
4655
|
}
|
|
4571
4656
|
|
|
4572
4657
|
// src/commands/deny/denyRemove.ts
|
|
4573
|
-
import
|
|
4658
|
+
import chalk58 from "chalk";
|
|
4574
4659
|
function denyRemove(pattern2) {
|
|
4575
4660
|
const config = loadProjectConfig();
|
|
4576
4661
|
const deny = config.deny ?? [];
|
|
4577
4662
|
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
4578
4663
|
if (index === -1) {
|
|
4579
|
-
console.log(
|
|
4664
|
+
console.log(chalk58.yellow(`No deny rule found for: ${pattern2}`));
|
|
4580
4665
|
return;
|
|
4581
4666
|
}
|
|
4582
4667
|
deny.splice(index, 1);
|
|
4583
4668
|
config.deny = deny.length > 0 ? deny : void 0;
|
|
4584
4669
|
saveConfig(config);
|
|
4585
|
-
console.log(
|
|
4670
|
+
console.log(chalk58.green(`Removed deny rule: ${pattern2}`));
|
|
4586
4671
|
}
|
|
4587
4672
|
|
|
4588
4673
|
// src/commands/permitCliReads/index.ts
|
|
4589
|
-
import { existsSync as
|
|
4674
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync5, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "fs";
|
|
4590
4675
|
import { homedir as homedir4 } from "os";
|
|
4591
|
-
import { join as
|
|
4676
|
+
import { join as join18 } from "path";
|
|
4592
4677
|
|
|
4593
4678
|
// src/shared/getInstallDir.ts
|
|
4594
4679
|
import { execSync as execSync15 } from "child_process";
|
|
@@ -4632,11 +4717,11 @@ function assertCliExists(cli) {
|
|
|
4632
4717
|
}
|
|
4633
4718
|
|
|
4634
4719
|
// src/commands/permitCliReads/colorize.ts
|
|
4635
|
-
import
|
|
4720
|
+
import chalk59 from "chalk";
|
|
4636
4721
|
function colorize(plainOutput) {
|
|
4637
4722
|
return plainOutput.split("\n").map((line) => {
|
|
4638
|
-
if (line.startsWith(" R ")) return
|
|
4639
|
-
if (line.startsWith(" W ")) return
|
|
4723
|
+
if (line.startsWith(" R ")) return chalk59.green(line);
|
|
4724
|
+
if (line.startsWith(" W ")) return chalk59.red(line);
|
|
4640
4725
|
return line;
|
|
4641
4726
|
}).join("\n");
|
|
4642
4727
|
}
|
|
@@ -4890,17 +4975,17 @@ function updateSettings(cli, commands) {
|
|
|
4890
4975
|
// src/commands/permitCliReads/index.ts
|
|
4891
4976
|
function logPath(cli) {
|
|
4892
4977
|
const safeName = cli.replace(/\s+/g, "-");
|
|
4893
|
-
return
|
|
4978
|
+
return join18(homedir4(), ".assist", `cli-discover-${safeName}.log`);
|
|
4894
4979
|
}
|
|
4895
4980
|
function readCache(cli) {
|
|
4896
4981
|
const path50 = logPath(cli);
|
|
4897
|
-
if (!
|
|
4898
|
-
return
|
|
4982
|
+
if (!existsSync21(path50)) return void 0;
|
|
4983
|
+
return readFileSync19(path50, "utf-8");
|
|
4899
4984
|
}
|
|
4900
4985
|
function writeCache(cli, output) {
|
|
4901
|
-
const dir =
|
|
4986
|
+
const dir = join18(homedir4(), ".assist");
|
|
4902
4987
|
mkdirSync5(dir, { recursive: true });
|
|
4903
|
-
|
|
4988
|
+
writeFileSync17(logPath(cli), output);
|
|
4904
4989
|
}
|
|
4905
4990
|
async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
4906
4991
|
if (!cli) {
|
|
@@ -4954,15 +5039,15 @@ function registerCliHook(program2) {
|
|
|
4954
5039
|
}
|
|
4955
5040
|
|
|
4956
5041
|
// src/commands/complexity/analyze.ts
|
|
4957
|
-
import
|
|
5042
|
+
import chalk65 from "chalk";
|
|
4958
5043
|
|
|
4959
5044
|
// src/commands/complexity/cyclomatic.ts
|
|
4960
|
-
import
|
|
5045
|
+
import chalk61 from "chalk";
|
|
4961
5046
|
|
|
4962
5047
|
// src/commands/complexity/shared/index.ts
|
|
4963
5048
|
import fs12 from "fs";
|
|
4964
5049
|
import path20 from "path";
|
|
4965
|
-
import
|
|
5050
|
+
import chalk60 from "chalk";
|
|
4966
5051
|
import ts5 from "typescript";
|
|
4967
5052
|
|
|
4968
5053
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -5208,7 +5293,7 @@ function createSourceFromFile(filePath) {
|
|
|
5208
5293
|
function withSourceFiles(pattern2, callback) {
|
|
5209
5294
|
const files = findSourceFiles2(pattern2);
|
|
5210
5295
|
if (files.length === 0) {
|
|
5211
|
-
console.log(
|
|
5296
|
+
console.log(chalk60.yellow("No files found matching pattern"));
|
|
5212
5297
|
return void 0;
|
|
5213
5298
|
}
|
|
5214
5299
|
return callback(files);
|
|
@@ -5241,11 +5326,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5241
5326
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
5242
5327
|
for (const { file, name, complexity } of results) {
|
|
5243
5328
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
5244
|
-
const color = exceedsThreshold ?
|
|
5245
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
5329
|
+
const color = exceedsThreshold ? chalk61.red : chalk61.white;
|
|
5330
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk61.cyan(complexity)}`);
|
|
5246
5331
|
}
|
|
5247
5332
|
console.log(
|
|
5248
|
-
|
|
5333
|
+
chalk61.dim(
|
|
5249
5334
|
`
|
|
5250
5335
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
5251
5336
|
)
|
|
@@ -5257,7 +5342,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
5257
5342
|
}
|
|
5258
5343
|
|
|
5259
5344
|
// src/commands/complexity/halstead.ts
|
|
5260
|
-
import
|
|
5345
|
+
import chalk62 from "chalk";
|
|
5261
5346
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
5262
5347
|
withSourceFiles(pattern2, (files) => {
|
|
5263
5348
|
const results = [];
|
|
@@ -5272,13 +5357,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5272
5357
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
5273
5358
|
for (const { file, name, metrics } of results) {
|
|
5274
5359
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
5275
|
-
const color = exceedsThreshold ?
|
|
5360
|
+
const color = exceedsThreshold ? chalk62.red : chalk62.white;
|
|
5276
5361
|
console.log(
|
|
5277
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
5362
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk62.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk62.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk62.magenta(metrics.effort.toFixed(1))}`
|
|
5278
5363
|
);
|
|
5279
5364
|
}
|
|
5280
5365
|
console.log(
|
|
5281
|
-
|
|
5366
|
+
chalk62.dim(
|
|
5282
5367
|
`
|
|
5283
5368
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
5284
5369
|
)
|
|
@@ -5293,28 +5378,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
5293
5378
|
import fs13 from "fs";
|
|
5294
5379
|
|
|
5295
5380
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
5296
|
-
import
|
|
5381
|
+
import chalk63 from "chalk";
|
|
5297
5382
|
function displayMaintainabilityResults(results, threshold) {
|
|
5298
5383
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
5299
5384
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
5300
|
-
console.log(
|
|
5385
|
+
console.log(chalk63.green("All files pass maintainability threshold"));
|
|
5301
5386
|
} else {
|
|
5302
5387
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
5303
|
-
const color = threshold !== void 0 ?
|
|
5388
|
+
const color = threshold !== void 0 ? chalk63.red : chalk63.white;
|
|
5304
5389
|
console.log(
|
|
5305
|
-
`${color(file)} \u2192 avg: ${
|
|
5390
|
+
`${color(file)} \u2192 avg: ${chalk63.cyan(avgMaintainability.toFixed(1))}, min: ${chalk63.yellow(minMaintainability.toFixed(1))}`
|
|
5306
5391
|
);
|
|
5307
5392
|
}
|
|
5308
5393
|
}
|
|
5309
|
-
console.log(
|
|
5394
|
+
console.log(chalk63.dim(`
|
|
5310
5395
|
Analyzed ${results.length} files`));
|
|
5311
5396
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
5312
5397
|
console.error(
|
|
5313
|
-
|
|
5398
|
+
chalk63.red(
|
|
5314
5399
|
`
|
|
5315
5400
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
5316
5401
|
|
|
5317
|
-
\u26A0\uFE0F ${
|
|
5402
|
+
\u26A0\uFE0F ${chalk63.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.`
|
|
5318
5403
|
)
|
|
5319
5404
|
);
|
|
5320
5405
|
process.exit(1);
|
|
@@ -5371,7 +5456,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5371
5456
|
|
|
5372
5457
|
// src/commands/complexity/sloc.ts
|
|
5373
5458
|
import fs14 from "fs";
|
|
5374
|
-
import
|
|
5459
|
+
import chalk64 from "chalk";
|
|
5375
5460
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
5376
5461
|
withSourceFiles(pattern2, (files) => {
|
|
5377
5462
|
const results = [];
|
|
@@ -5387,12 +5472,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5387
5472
|
results.sort((a, b) => b.lines - a.lines);
|
|
5388
5473
|
for (const { file, lines } of results) {
|
|
5389
5474
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
5390
|
-
const color = exceedsThreshold ?
|
|
5391
|
-
console.log(`${color(file)} \u2192 ${
|
|
5475
|
+
const color = exceedsThreshold ? chalk64.red : chalk64.white;
|
|
5476
|
+
console.log(`${color(file)} \u2192 ${chalk64.cyan(lines)} lines`);
|
|
5392
5477
|
}
|
|
5393
5478
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
5394
5479
|
console.log(
|
|
5395
|
-
|
|
5480
|
+
chalk64.dim(`
|
|
5396
5481
|
Total: ${total} lines across ${files.length} files`)
|
|
5397
5482
|
);
|
|
5398
5483
|
if (hasViolation) {
|
|
@@ -5406,21 +5491,21 @@ async function analyze(pattern2) {
|
|
|
5406
5491
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
5407
5492
|
const files = findSourceFiles2(searchPattern);
|
|
5408
5493
|
if (files.length === 0) {
|
|
5409
|
-
console.log(
|
|
5494
|
+
console.log(chalk65.yellow("No files found matching pattern"));
|
|
5410
5495
|
return;
|
|
5411
5496
|
}
|
|
5412
5497
|
if (files.length === 1) {
|
|
5413
5498
|
const file = files[0];
|
|
5414
|
-
console.log(
|
|
5499
|
+
console.log(chalk65.bold.underline("SLOC"));
|
|
5415
5500
|
await sloc(file);
|
|
5416
5501
|
console.log();
|
|
5417
|
-
console.log(
|
|
5502
|
+
console.log(chalk65.bold.underline("Cyclomatic Complexity"));
|
|
5418
5503
|
await cyclomatic(file);
|
|
5419
5504
|
console.log();
|
|
5420
|
-
console.log(
|
|
5505
|
+
console.log(chalk65.bold.underline("Halstead Metrics"));
|
|
5421
5506
|
await halstead(file);
|
|
5422
5507
|
console.log();
|
|
5423
|
-
console.log(
|
|
5508
|
+
console.log(chalk65.bold.underline("Maintainability Index"));
|
|
5424
5509
|
await maintainability(file);
|
|
5425
5510
|
return;
|
|
5426
5511
|
}
|
|
@@ -5447,8 +5532,8 @@ function registerComplexity(program2) {
|
|
|
5447
5532
|
}
|
|
5448
5533
|
|
|
5449
5534
|
// src/commands/deploy/redirect.ts
|
|
5450
|
-
import { existsSync as
|
|
5451
|
-
import
|
|
5535
|
+
import { existsSync as existsSync22, readFileSync as readFileSync20, writeFileSync as writeFileSync18 } from "fs";
|
|
5536
|
+
import chalk66 from "chalk";
|
|
5452
5537
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
5453
5538
|
if (!window.location.pathname.endsWith('/')) {
|
|
5454
5539
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -5456,23 +5541,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
5456
5541
|
</script>`;
|
|
5457
5542
|
function redirect() {
|
|
5458
5543
|
const indexPath = "index.html";
|
|
5459
|
-
if (!
|
|
5460
|
-
console.log(
|
|
5544
|
+
if (!existsSync22(indexPath)) {
|
|
5545
|
+
console.log(chalk66.yellow("No index.html found"));
|
|
5461
5546
|
return;
|
|
5462
5547
|
}
|
|
5463
|
-
const content =
|
|
5548
|
+
const content = readFileSync20(indexPath, "utf-8");
|
|
5464
5549
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
5465
|
-
console.log(
|
|
5550
|
+
console.log(chalk66.dim("Trailing slash script already present"));
|
|
5466
5551
|
return;
|
|
5467
5552
|
}
|
|
5468
5553
|
const headCloseIndex = content.indexOf("</head>");
|
|
5469
5554
|
if (headCloseIndex === -1) {
|
|
5470
|
-
console.log(
|
|
5555
|
+
console.log(chalk66.red("Could not find </head> tag in index.html"));
|
|
5471
5556
|
return;
|
|
5472
5557
|
}
|
|
5473
5558
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
5474
|
-
|
|
5475
|
-
console.log(
|
|
5559
|
+
writeFileSync18(indexPath, newContent);
|
|
5560
|
+
console.log(chalk66.green("Added trailing slash redirect to index.html"));
|
|
5476
5561
|
}
|
|
5477
5562
|
|
|
5478
5563
|
// src/commands/registerDeploy.ts
|
|
@@ -5488,10 +5573,10 @@ import { basename as basename3 } from "path";
|
|
|
5488
5573
|
|
|
5489
5574
|
// src/commands/devlog/loadBlogSkipDays.ts
|
|
5490
5575
|
import { homedir as homedir5 } from "os";
|
|
5491
|
-
import { join as
|
|
5492
|
-
var BLOG_REPO_ROOT =
|
|
5576
|
+
import { join as join19 } from "path";
|
|
5577
|
+
var BLOG_REPO_ROOT = join19(homedir5(), "git/blog");
|
|
5493
5578
|
function loadBlogSkipDays(repoName) {
|
|
5494
|
-
const config = loadRawYaml(
|
|
5579
|
+
const config = loadRawYaml(join19(BLOG_REPO_ROOT, "assist.yml"));
|
|
5495
5580
|
const devlog = config.devlog;
|
|
5496
5581
|
const skip2 = devlog?.skip;
|
|
5497
5582
|
return new Set(skip2?.[repoName] ?? []);
|
|
@@ -5499,12 +5584,12 @@ function loadBlogSkipDays(repoName) {
|
|
|
5499
5584
|
|
|
5500
5585
|
// src/commands/devlog/shared.ts
|
|
5501
5586
|
import { execSync as execSync17 } from "child_process";
|
|
5502
|
-
import
|
|
5587
|
+
import chalk67 from "chalk";
|
|
5503
5588
|
|
|
5504
5589
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
5505
|
-
import { readdirSync, readFileSync as
|
|
5506
|
-
import { join as
|
|
5507
|
-
var DEVLOG_DIR =
|
|
5590
|
+
import { readdirSync, readFileSync as readFileSync21 } from "fs";
|
|
5591
|
+
import { join as join20 } from "path";
|
|
5592
|
+
var DEVLOG_DIR = join20(BLOG_REPO_ROOT, "src/content/devlog");
|
|
5508
5593
|
function extractFrontmatter(content) {
|
|
5509
5594
|
const fm = content.match(/^---\n([\s\S]*?)\n---/);
|
|
5510
5595
|
return fm?.[1] ?? null;
|
|
@@ -5532,7 +5617,7 @@ function readDevlogFiles(callback) {
|
|
|
5532
5617
|
try {
|
|
5533
5618
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
5534
5619
|
for (const file of files) {
|
|
5535
|
-
const content =
|
|
5620
|
+
const content = readFileSync21(join20(DEVLOG_DIR, file), "utf-8");
|
|
5536
5621
|
const parsed = parseFrontmatter(content, file);
|
|
5537
5622
|
if (parsed) callback(parsed);
|
|
5538
5623
|
}
|
|
@@ -5586,13 +5671,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
5586
5671
|
}
|
|
5587
5672
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
5588
5673
|
for (const commit2 of commits) {
|
|
5589
|
-
console.log(` ${
|
|
5674
|
+
console.log(` ${chalk67.yellow(commit2.hash)} ${commit2.message}`);
|
|
5590
5675
|
if (verbose) {
|
|
5591
5676
|
const visibleFiles = commit2.files.filter(
|
|
5592
5677
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
5593
5678
|
);
|
|
5594
5679
|
for (const file of visibleFiles) {
|
|
5595
|
-
console.log(` ${
|
|
5680
|
+
console.log(` ${chalk67.dim(file)}`);
|
|
5596
5681
|
}
|
|
5597
5682
|
}
|
|
5598
5683
|
}
|
|
@@ -5617,15 +5702,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
5617
5702
|
}
|
|
5618
5703
|
|
|
5619
5704
|
// src/commands/devlog/list/printDateHeader.ts
|
|
5620
|
-
import
|
|
5705
|
+
import chalk68 from "chalk";
|
|
5621
5706
|
function printDateHeader(date, isSkipped, entries) {
|
|
5622
5707
|
if (isSkipped) {
|
|
5623
|
-
console.log(`${
|
|
5708
|
+
console.log(`${chalk68.bold.blue(date)} ${chalk68.dim("skipped")}`);
|
|
5624
5709
|
} else if (entries && entries.length > 0) {
|
|
5625
|
-
const entryInfo = entries.map((e) => `${
|
|
5626
|
-
console.log(`${
|
|
5710
|
+
const entryInfo = entries.map((e) => `${chalk68.green(e.version)} ${e.title}`).join(" | ");
|
|
5711
|
+
console.log(`${chalk68.bold.blue(date)} ${entryInfo}`);
|
|
5627
5712
|
} else {
|
|
5628
|
-
console.log(`${
|
|
5713
|
+
console.log(`${chalk68.bold.blue(date)} ${chalk68.red("\u26A0 devlog missing")}`);
|
|
5629
5714
|
}
|
|
5630
5715
|
}
|
|
5631
5716
|
|
|
@@ -5729,24 +5814,24 @@ function bumpVersion(version2, type) {
|
|
|
5729
5814
|
|
|
5730
5815
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
5731
5816
|
import { execSync as execSync20 } from "child_process";
|
|
5732
|
-
import
|
|
5817
|
+
import chalk70 from "chalk";
|
|
5733
5818
|
|
|
5734
5819
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
5735
|
-
import
|
|
5820
|
+
import chalk69 from "chalk";
|
|
5736
5821
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
5737
5822
|
if (conventional && firstHash) {
|
|
5738
5823
|
const version2 = getVersionAtCommit(firstHash);
|
|
5739
5824
|
if (version2) {
|
|
5740
|
-
console.log(`${
|
|
5825
|
+
console.log(`${chalk69.bold("version:")} ${stripToMinor(version2)}`);
|
|
5741
5826
|
} else {
|
|
5742
|
-
console.log(`${
|
|
5827
|
+
console.log(`${chalk69.bold("version:")} ${chalk69.red("unknown")}`);
|
|
5743
5828
|
}
|
|
5744
5829
|
} else if (patchVersion && minorVersion) {
|
|
5745
5830
|
console.log(
|
|
5746
|
-
`${
|
|
5831
|
+
`${chalk69.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
5747
5832
|
);
|
|
5748
5833
|
} else {
|
|
5749
|
-
console.log(`${
|
|
5834
|
+
console.log(`${chalk69.bold("version:")} v0.1 (initial)`);
|
|
5750
5835
|
}
|
|
5751
5836
|
}
|
|
5752
5837
|
|
|
@@ -5793,16 +5878,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
5793
5878
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
5794
5879
|
}
|
|
5795
5880
|
function logName(repoName) {
|
|
5796
|
-
console.log(`${
|
|
5881
|
+
console.log(`${chalk70.bold("name:")} ${repoName}`);
|
|
5797
5882
|
}
|
|
5798
5883
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
5799
5884
|
logName(ctx.repoName);
|
|
5800
5885
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
5801
|
-
console.log(
|
|
5886
|
+
console.log(chalk70.bold.blue(targetDate));
|
|
5802
5887
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
5803
5888
|
}
|
|
5804
5889
|
function logNoCommits(lastInfo) {
|
|
5805
|
-
console.log(
|
|
5890
|
+
console.log(chalk70.dim(noCommitsMessage(!!lastInfo)));
|
|
5806
5891
|
}
|
|
5807
5892
|
|
|
5808
5893
|
// src/commands/devlog/next/index.ts
|
|
@@ -5843,11 +5928,11 @@ function next2(options2) {
|
|
|
5843
5928
|
import { execSync as execSync21 } from "child_process";
|
|
5844
5929
|
|
|
5845
5930
|
// src/commands/devlog/repos/printReposTable.ts
|
|
5846
|
-
import
|
|
5931
|
+
import chalk71 from "chalk";
|
|
5847
5932
|
function colorStatus(status2) {
|
|
5848
|
-
if (status2 === "missing") return
|
|
5849
|
-
if (status2 === "outdated") return
|
|
5850
|
-
return
|
|
5933
|
+
if (status2 === "missing") return chalk71.red(status2);
|
|
5934
|
+
if (status2 === "outdated") return chalk71.yellow(status2);
|
|
5935
|
+
return chalk71.green(status2);
|
|
5851
5936
|
}
|
|
5852
5937
|
function formatRow(row, nameWidth) {
|
|
5853
5938
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -5861,8 +5946,8 @@ function printReposTable(rows) {
|
|
|
5861
5946
|
"Last Devlog".padEnd(11),
|
|
5862
5947
|
"Status"
|
|
5863
5948
|
].join(" ");
|
|
5864
|
-
console.log(
|
|
5865
|
-
console.log(
|
|
5949
|
+
console.log(chalk71.dim(header));
|
|
5950
|
+
console.log(chalk71.dim("-".repeat(header.length)));
|
|
5866
5951
|
for (const row of rows) {
|
|
5867
5952
|
console.log(formatRow(row, nameWidth));
|
|
5868
5953
|
}
|
|
@@ -5918,16 +6003,16 @@ function repos(options2) {
|
|
|
5918
6003
|
}
|
|
5919
6004
|
|
|
5920
6005
|
// src/commands/devlog/skip.ts
|
|
5921
|
-
import { writeFileSync as
|
|
5922
|
-
import { join as
|
|
5923
|
-
import
|
|
6006
|
+
import { writeFileSync as writeFileSync19 } from "fs";
|
|
6007
|
+
import { join as join21 } from "path";
|
|
6008
|
+
import chalk72 from "chalk";
|
|
5924
6009
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
5925
6010
|
function getBlogConfigPath() {
|
|
5926
|
-
return
|
|
6011
|
+
return join21(BLOG_REPO_ROOT, "assist.yml");
|
|
5927
6012
|
}
|
|
5928
6013
|
function skip(date) {
|
|
5929
6014
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5930
|
-
console.log(
|
|
6015
|
+
console.log(chalk72.red("Invalid date format. Use YYYY-MM-DD"));
|
|
5931
6016
|
process.exit(1);
|
|
5932
6017
|
}
|
|
5933
6018
|
const repoName = getRepoName();
|
|
@@ -5938,7 +6023,7 @@ function skip(date) {
|
|
|
5938
6023
|
const skipDays = skip2[repoName] ?? [];
|
|
5939
6024
|
if (skipDays.includes(date)) {
|
|
5940
6025
|
console.log(
|
|
5941
|
-
|
|
6026
|
+
chalk72.yellow(`${date} is already in skip list for ${repoName}`)
|
|
5942
6027
|
);
|
|
5943
6028
|
return;
|
|
5944
6029
|
}
|
|
@@ -5947,21 +6032,21 @@ function skip(date) {
|
|
|
5947
6032
|
skip2[repoName] = skipDays;
|
|
5948
6033
|
devlog.skip = skip2;
|
|
5949
6034
|
config.devlog = devlog;
|
|
5950
|
-
|
|
5951
|
-
console.log(
|
|
6035
|
+
writeFileSync19(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
6036
|
+
console.log(chalk72.green(`Added ${date} to skip list for ${repoName}`));
|
|
5952
6037
|
}
|
|
5953
6038
|
|
|
5954
6039
|
// src/commands/devlog/version.ts
|
|
5955
|
-
import
|
|
6040
|
+
import chalk73 from "chalk";
|
|
5956
6041
|
function version() {
|
|
5957
6042
|
const config = loadConfig();
|
|
5958
6043
|
const name = getRepoName();
|
|
5959
6044
|
const lastInfo = getLastVersionInfo(name, config);
|
|
5960
6045
|
const lastVersion = lastInfo?.version ?? null;
|
|
5961
6046
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
5962
|
-
console.log(`${
|
|
5963
|
-
console.log(`${
|
|
5964
|
-
console.log(`${
|
|
6047
|
+
console.log(`${chalk73.bold("name:")} ${name}`);
|
|
6048
|
+
console.log(`${chalk73.bold("last:")} ${lastVersion ?? chalk73.dim("none")}`);
|
|
6049
|
+
console.log(`${chalk73.bold("next:")} ${nextVersion ?? chalk73.dim("none")}`);
|
|
5965
6050
|
}
|
|
5966
6051
|
|
|
5967
6052
|
// src/commands/registerDevlog.ts
|
|
@@ -5984,16 +6069,16 @@ function registerDevlog(program2) {
|
|
|
5984
6069
|
|
|
5985
6070
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5986
6071
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5987
|
-
import { join as
|
|
5988
|
-
import
|
|
6072
|
+
import { join as join22 } from "path";
|
|
6073
|
+
import chalk74 from "chalk";
|
|
5989
6074
|
|
|
5990
6075
|
// src/shared/findRepoRoot.ts
|
|
5991
|
-
import { existsSync as
|
|
6076
|
+
import { existsSync as existsSync23 } from "fs";
|
|
5992
6077
|
import path21 from "path";
|
|
5993
6078
|
function findRepoRoot(dir) {
|
|
5994
6079
|
let current = dir;
|
|
5995
6080
|
while (current !== path21.dirname(current)) {
|
|
5996
|
-
if (
|
|
6081
|
+
if (existsSync23(path21.join(current, ".git"))) {
|
|
5997
6082
|
return current;
|
|
5998
6083
|
}
|
|
5999
6084
|
current = path21.dirname(current);
|
|
@@ -6012,7 +6097,7 @@ function isLockedDll(debugDir) {
|
|
|
6012
6097
|
}
|
|
6013
6098
|
for (const file of files) {
|
|
6014
6099
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
6015
|
-
const dllPath =
|
|
6100
|
+
const dllPath = join22(debugDir, file);
|
|
6016
6101
|
try {
|
|
6017
6102
|
const fd = openSync(dllPath, "r+");
|
|
6018
6103
|
closeSync(fd);
|
|
@@ -6030,13 +6115,13 @@ function findFirstLockedDll(dir) {
|
|
|
6030
6115
|
return null;
|
|
6031
6116
|
}
|
|
6032
6117
|
if (entries.includes("bin")) {
|
|
6033
|
-
const locked = isLockedDll(
|
|
6118
|
+
const locked = isLockedDll(join22(dir, "bin", "Debug"));
|
|
6034
6119
|
if (locked) return locked;
|
|
6035
6120
|
}
|
|
6036
6121
|
for (const entry of entries) {
|
|
6037
6122
|
if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
|
|
6038
6123
|
continue;
|
|
6039
|
-
const found = findFirstLockedDll(
|
|
6124
|
+
const found = findFirstLockedDll(join22(dir, entry));
|
|
6040
6125
|
if (found) return found;
|
|
6041
6126
|
}
|
|
6042
6127
|
return null;
|
|
@@ -6048,22 +6133,22 @@ function checkBuildLocks(startDir) {
|
|
|
6048
6133
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
6049
6134
|
if (locked) {
|
|
6050
6135
|
console.error(
|
|
6051
|
-
|
|
6136
|
+
chalk74.red("Build output locked (is VS debugging?): ") + locked
|
|
6052
6137
|
);
|
|
6053
6138
|
process.exit(1);
|
|
6054
6139
|
}
|
|
6055
6140
|
}
|
|
6056
6141
|
async function checkBuildLocksCommand() {
|
|
6057
6142
|
checkBuildLocks();
|
|
6058
|
-
console.log(
|
|
6143
|
+
console.log(chalk74.green("No build locks detected"));
|
|
6059
6144
|
}
|
|
6060
6145
|
|
|
6061
6146
|
// src/commands/dotnet/buildTree.ts
|
|
6062
|
-
import { readFileSync as
|
|
6147
|
+
import { readFileSync as readFileSync22 } from "fs";
|
|
6063
6148
|
import path22 from "path";
|
|
6064
6149
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
6065
6150
|
function getProjectRefs(csprojPath) {
|
|
6066
|
-
const content =
|
|
6151
|
+
const content = readFileSync22(csprojPath, "utf-8");
|
|
6067
6152
|
const refs = [];
|
|
6068
6153
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
6069
6154
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -6080,7 +6165,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
6080
6165
|
for (const ref of getProjectRefs(abs)) {
|
|
6081
6166
|
const childAbs = path22.resolve(dir, ref);
|
|
6082
6167
|
try {
|
|
6083
|
-
|
|
6168
|
+
readFileSync22(childAbs);
|
|
6084
6169
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
6085
6170
|
} catch {
|
|
6086
6171
|
node.children.push({
|
|
@@ -6105,7 +6190,7 @@ function collectAllDeps(node) {
|
|
|
6105
6190
|
}
|
|
6106
6191
|
|
|
6107
6192
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
6108
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
6193
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync23, statSync as statSync3 } from "fs";
|
|
6109
6194
|
import path23 from "path";
|
|
6110
6195
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
6111
6196
|
if (depth > maxDepth) return [];
|
|
@@ -6140,7 +6225,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
6140
6225
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
6141
6226
|
for (const sln of slnFiles) {
|
|
6142
6227
|
try {
|
|
6143
|
-
const content =
|
|
6228
|
+
const content = readFileSync23(sln, "utf-8");
|
|
6144
6229
|
if (pattern2.test(content)) {
|
|
6145
6230
|
matches.push(path23.relative(repoRoot, sln));
|
|
6146
6231
|
}
|
|
@@ -6154,30 +6239,30 @@ function escapeRegex(s) {
|
|
|
6154
6239
|
}
|
|
6155
6240
|
|
|
6156
6241
|
// src/commands/dotnet/printTree.ts
|
|
6157
|
-
import
|
|
6242
|
+
import chalk75 from "chalk";
|
|
6158
6243
|
function printNodes(nodes, prefix2) {
|
|
6159
6244
|
for (let i = 0; i < nodes.length; i++) {
|
|
6160
6245
|
const isLast = i === nodes.length - 1;
|
|
6161
6246
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
6162
6247
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
6163
6248
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
6164
|
-
const label2 = isMissing ?
|
|
6249
|
+
const label2 = isMissing ? chalk75.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
6165
6250
|
console.log(`${prefix2}${connector}${label2}`);
|
|
6166
6251
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
6167
6252
|
}
|
|
6168
6253
|
}
|
|
6169
6254
|
function printTree(tree, totalCount, solutions) {
|
|
6170
|
-
console.log(
|
|
6171
|
-
console.log(
|
|
6255
|
+
console.log(chalk75.bold("\nProject Dependency Tree"));
|
|
6256
|
+
console.log(chalk75.cyan(tree.relativePath));
|
|
6172
6257
|
printNodes(tree.children, "");
|
|
6173
|
-
console.log(
|
|
6258
|
+
console.log(chalk75.dim(`
|
|
6174
6259
|
${totalCount} projects total (including root)`));
|
|
6175
|
-
console.log(
|
|
6260
|
+
console.log(chalk75.bold("\nSolution Membership"));
|
|
6176
6261
|
if (solutions.length === 0) {
|
|
6177
|
-
console.log(
|
|
6262
|
+
console.log(chalk75.yellow(" Not found in any .sln"));
|
|
6178
6263
|
} else {
|
|
6179
6264
|
for (const sln of solutions) {
|
|
6180
|
-
console.log(` ${
|
|
6265
|
+
console.log(` ${chalk75.green(sln)}`);
|
|
6181
6266
|
}
|
|
6182
6267
|
}
|
|
6183
6268
|
console.log();
|
|
@@ -6204,18 +6289,18 @@ function printJson(tree, totalCount, solutions) {
|
|
|
6204
6289
|
}
|
|
6205
6290
|
|
|
6206
6291
|
// src/commands/dotnet/resolveCsproj.ts
|
|
6207
|
-
import { existsSync as
|
|
6292
|
+
import { existsSync as existsSync24 } from "fs";
|
|
6208
6293
|
import path24 from "path";
|
|
6209
|
-
import
|
|
6294
|
+
import chalk76 from "chalk";
|
|
6210
6295
|
function resolveCsproj(csprojPath) {
|
|
6211
6296
|
const resolved = path24.resolve(csprojPath);
|
|
6212
|
-
if (!
|
|
6213
|
-
console.error(
|
|
6297
|
+
if (!existsSync24(resolved)) {
|
|
6298
|
+
console.error(chalk76.red(`File not found: ${resolved}`));
|
|
6214
6299
|
process.exit(1);
|
|
6215
6300
|
}
|
|
6216
6301
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
6217
6302
|
if (!repoRoot) {
|
|
6218
|
-
console.error(
|
|
6303
|
+
console.error(chalk76.red("Could not find git repository root"));
|
|
6219
6304
|
process.exit(1);
|
|
6220
6305
|
}
|
|
6221
6306
|
return { resolved, repoRoot };
|
|
@@ -6265,12 +6350,12 @@ function getChangedCsFiles(scope) {
|
|
|
6265
6350
|
}
|
|
6266
6351
|
|
|
6267
6352
|
// src/commands/dotnet/inSln.ts
|
|
6268
|
-
import
|
|
6353
|
+
import chalk77 from "chalk";
|
|
6269
6354
|
async function inSln(csprojPath) {
|
|
6270
6355
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
6271
6356
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
6272
6357
|
if (solutions.length === 0) {
|
|
6273
|
-
console.log(
|
|
6358
|
+
console.log(chalk77.yellow("Not found in any .sln file"));
|
|
6274
6359
|
process.exit(1);
|
|
6275
6360
|
}
|
|
6276
6361
|
for (const sln of solutions) {
|
|
@@ -6279,7 +6364,7 @@ async function inSln(csprojPath) {
|
|
|
6279
6364
|
}
|
|
6280
6365
|
|
|
6281
6366
|
// src/commands/dotnet/inspect.ts
|
|
6282
|
-
import
|
|
6367
|
+
import chalk83 from "chalk";
|
|
6283
6368
|
|
|
6284
6369
|
// src/shared/formatElapsed.ts
|
|
6285
6370
|
function formatElapsed(ms) {
|
|
@@ -6291,12 +6376,12 @@ function formatElapsed(ms) {
|
|
|
6291
6376
|
}
|
|
6292
6377
|
|
|
6293
6378
|
// src/commands/dotnet/displayIssues.ts
|
|
6294
|
-
import
|
|
6379
|
+
import chalk78 from "chalk";
|
|
6295
6380
|
var SEVERITY_COLOR = {
|
|
6296
|
-
ERROR:
|
|
6297
|
-
WARNING:
|
|
6298
|
-
SUGGESTION:
|
|
6299
|
-
HINT:
|
|
6381
|
+
ERROR: chalk78.red,
|
|
6382
|
+
WARNING: chalk78.yellow,
|
|
6383
|
+
SUGGESTION: chalk78.cyan,
|
|
6384
|
+
HINT: chalk78.dim
|
|
6300
6385
|
};
|
|
6301
6386
|
function groupByFile(issues) {
|
|
6302
6387
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -6312,15 +6397,15 @@ function groupByFile(issues) {
|
|
|
6312
6397
|
}
|
|
6313
6398
|
function displayIssues(issues) {
|
|
6314
6399
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
6315
|
-
console.log(
|
|
6400
|
+
console.log(chalk78.bold(file));
|
|
6316
6401
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
6317
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
6402
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk78.white;
|
|
6318
6403
|
console.log(
|
|
6319
|
-
` ${
|
|
6404
|
+
` ${chalk78.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
6320
6405
|
);
|
|
6321
6406
|
}
|
|
6322
6407
|
}
|
|
6323
|
-
console.log(
|
|
6408
|
+
console.log(chalk78.dim(`
|
|
6324
6409
|
${issues.length} issue(s) found`));
|
|
6325
6410
|
}
|
|
6326
6411
|
|
|
@@ -6377,17 +6462,17 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
6377
6462
|
}
|
|
6378
6463
|
|
|
6379
6464
|
// src/commands/dotnet/resolveSolution.ts
|
|
6380
|
-
import { existsSync as
|
|
6465
|
+
import { existsSync as existsSync25 } from "fs";
|
|
6381
6466
|
import path25 from "path";
|
|
6382
|
-
import
|
|
6467
|
+
import chalk80 from "chalk";
|
|
6383
6468
|
|
|
6384
6469
|
// src/commands/dotnet/findSolution.ts
|
|
6385
6470
|
import { readdirSync as readdirSync4 } from "fs";
|
|
6386
|
-
import { dirname as dirname16, join as
|
|
6387
|
-
import
|
|
6471
|
+
import { dirname as dirname16, join as join23 } from "path";
|
|
6472
|
+
import chalk79 from "chalk";
|
|
6388
6473
|
function findSlnInDir(dir) {
|
|
6389
6474
|
try {
|
|
6390
|
-
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) =>
|
|
6475
|
+
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join23(dir, f));
|
|
6391
6476
|
} catch {
|
|
6392
6477
|
return [];
|
|
6393
6478
|
}
|
|
@@ -6400,17 +6485,17 @@ function findSolution() {
|
|
|
6400
6485
|
const slnFiles = findSlnInDir(current);
|
|
6401
6486
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
6402
6487
|
if (slnFiles.length > 1) {
|
|
6403
|
-
console.error(
|
|
6488
|
+
console.error(chalk79.red(`Multiple .sln files found in ${current}:`));
|
|
6404
6489
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
6405
6490
|
console.error(
|
|
6406
|
-
|
|
6491
|
+
chalk79.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
6407
6492
|
);
|
|
6408
6493
|
process.exit(1);
|
|
6409
6494
|
}
|
|
6410
6495
|
if (current === ceiling) break;
|
|
6411
6496
|
current = dirname16(current);
|
|
6412
6497
|
}
|
|
6413
|
-
console.error(
|
|
6498
|
+
console.error(chalk79.red("No .sln file found between cwd and repo root"));
|
|
6414
6499
|
process.exit(1);
|
|
6415
6500
|
}
|
|
6416
6501
|
|
|
@@ -6418,8 +6503,8 @@ function findSolution() {
|
|
|
6418
6503
|
function resolveSolution(sln) {
|
|
6419
6504
|
if (sln) {
|
|
6420
6505
|
const resolved = path25.resolve(sln);
|
|
6421
|
-
if (!
|
|
6422
|
-
console.error(
|
|
6506
|
+
if (!existsSync25(resolved)) {
|
|
6507
|
+
console.error(chalk80.red(`Solution file not found: ${resolved}`));
|
|
6423
6508
|
process.exit(1);
|
|
6424
6509
|
}
|
|
6425
6510
|
return resolved;
|
|
@@ -6458,17 +6543,17 @@ function parseInspectReport(json) {
|
|
|
6458
6543
|
|
|
6459
6544
|
// src/commands/dotnet/runInspectCode.ts
|
|
6460
6545
|
import { execSync as execSync23 } from "child_process";
|
|
6461
|
-
import { existsSync as
|
|
6546
|
+
import { existsSync as existsSync26, readFileSync as readFileSync24, unlinkSync as unlinkSync5 } from "fs";
|
|
6462
6547
|
import { tmpdir as tmpdir2 } from "os";
|
|
6463
6548
|
import path26 from "path";
|
|
6464
|
-
import
|
|
6549
|
+
import chalk81 from "chalk";
|
|
6465
6550
|
function assertJbInstalled() {
|
|
6466
6551
|
try {
|
|
6467
6552
|
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
6468
6553
|
} catch {
|
|
6469
|
-
console.error(
|
|
6554
|
+
console.error(chalk81.red("jb is not installed. Install with:"));
|
|
6470
6555
|
console.error(
|
|
6471
|
-
|
|
6556
|
+
chalk81.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
6472
6557
|
);
|
|
6473
6558
|
process.exit(1);
|
|
6474
6559
|
}
|
|
@@ -6486,21 +6571,21 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
6486
6571
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
6487
6572
|
process.stderr.write(err.stderr);
|
|
6488
6573
|
}
|
|
6489
|
-
console.error(
|
|
6574
|
+
console.error(chalk81.red("jb inspectcode failed"));
|
|
6490
6575
|
process.exit(1);
|
|
6491
6576
|
}
|
|
6492
|
-
if (!
|
|
6493
|
-
console.error(
|
|
6577
|
+
if (!existsSync26(reportPath)) {
|
|
6578
|
+
console.error(chalk81.red("Report file not generated"));
|
|
6494
6579
|
process.exit(1);
|
|
6495
6580
|
}
|
|
6496
|
-
const xml =
|
|
6581
|
+
const xml = readFileSync24(reportPath, "utf-8");
|
|
6497
6582
|
unlinkSync5(reportPath);
|
|
6498
6583
|
return xml;
|
|
6499
6584
|
}
|
|
6500
6585
|
|
|
6501
6586
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
6502
6587
|
import { execSync as execSync24 } from "child_process";
|
|
6503
|
-
import
|
|
6588
|
+
import chalk82 from "chalk";
|
|
6504
6589
|
function resolveMsbuildPath() {
|
|
6505
6590
|
const config = loadConfig();
|
|
6506
6591
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -6511,9 +6596,9 @@ function assertMsbuildInstalled() {
|
|
|
6511
6596
|
try {
|
|
6512
6597
|
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
6513
6598
|
} catch {
|
|
6514
|
-
console.error(
|
|
6599
|
+
console.error(chalk82.red(`msbuild not found at: ${msbuild}`));
|
|
6515
6600
|
console.error(
|
|
6516
|
-
|
|
6601
|
+
chalk82.yellow(
|
|
6517
6602
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
6518
6603
|
)
|
|
6519
6604
|
);
|
|
@@ -6560,17 +6645,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
6560
6645
|
// src/commands/dotnet/inspect.ts
|
|
6561
6646
|
function logScope(changedFiles) {
|
|
6562
6647
|
if (changedFiles === null) {
|
|
6563
|
-
console.log(
|
|
6648
|
+
console.log(chalk83.dim("Inspecting full solution..."));
|
|
6564
6649
|
} else {
|
|
6565
6650
|
console.log(
|
|
6566
|
-
|
|
6651
|
+
chalk83.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
6567
6652
|
);
|
|
6568
6653
|
}
|
|
6569
6654
|
}
|
|
6570
6655
|
function reportResults(issues, elapsed) {
|
|
6571
6656
|
if (issues.length > 0) displayIssues(issues);
|
|
6572
|
-
else console.log(
|
|
6573
|
-
console.log(
|
|
6657
|
+
else console.log(chalk83.green("No issues found"));
|
|
6658
|
+
console.log(chalk83.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
6574
6659
|
if (issues.length > 0) process.exit(1);
|
|
6575
6660
|
}
|
|
6576
6661
|
async function inspect(sln, options2) {
|
|
@@ -6581,7 +6666,7 @@ async function inspect(sln, options2) {
|
|
|
6581
6666
|
const scope = parseScope(options2.scope);
|
|
6582
6667
|
const changedFiles = getChangedCsFiles(scope);
|
|
6583
6668
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
6584
|
-
console.log(
|
|
6669
|
+
console.log(chalk83.green("No changed .cs files found"));
|
|
6585
6670
|
return;
|
|
6586
6671
|
}
|
|
6587
6672
|
logScope(changedFiles);
|
|
@@ -6607,7 +6692,7 @@ function registerDotnet(program2) {
|
|
|
6607
6692
|
}
|
|
6608
6693
|
|
|
6609
6694
|
// src/commands/jira/acceptanceCriteria.ts
|
|
6610
|
-
import
|
|
6695
|
+
import chalk85 from "chalk";
|
|
6611
6696
|
|
|
6612
6697
|
// src/commands/jira/adfToText.ts
|
|
6613
6698
|
function renderInline(node) {
|
|
@@ -6668,7 +6753,7 @@ function adfToText(doc) {
|
|
|
6668
6753
|
|
|
6669
6754
|
// src/commands/jira/fetchIssue.ts
|
|
6670
6755
|
import { execSync as execSync25 } from "child_process";
|
|
6671
|
-
import
|
|
6756
|
+
import chalk84 from "chalk";
|
|
6672
6757
|
function fetchIssue(issueKey, fields) {
|
|
6673
6758
|
let result;
|
|
6674
6759
|
try {
|
|
@@ -6681,15 +6766,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
6681
6766
|
const stderr = error.stderr;
|
|
6682
6767
|
if (stderr.includes("unauthorized")) {
|
|
6683
6768
|
console.error(
|
|
6684
|
-
|
|
6769
|
+
chalk84.red("Jira authentication expired."),
|
|
6685
6770
|
"Run",
|
|
6686
|
-
|
|
6771
|
+
chalk84.cyan("assist jira auth"),
|
|
6687
6772
|
"to re-authenticate."
|
|
6688
6773
|
);
|
|
6689
6774
|
process.exit(1);
|
|
6690
6775
|
}
|
|
6691
6776
|
}
|
|
6692
|
-
console.error(
|
|
6777
|
+
console.error(chalk84.red(`Failed to fetch ${issueKey}.`));
|
|
6693
6778
|
process.exit(1);
|
|
6694
6779
|
}
|
|
6695
6780
|
return JSON.parse(result);
|
|
@@ -6703,7 +6788,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
6703
6788
|
const parsed = fetchIssue(issueKey, field);
|
|
6704
6789
|
const acValue = parsed?.fields?.[field];
|
|
6705
6790
|
if (!acValue) {
|
|
6706
|
-
console.log(
|
|
6791
|
+
console.log(chalk85.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
6707
6792
|
return;
|
|
6708
6793
|
}
|
|
6709
6794
|
if (typeof acValue === "string") {
|
|
@@ -6721,20 +6806,20 @@ function acceptanceCriteria(issueKey) {
|
|
|
6721
6806
|
import { execSync as execSync26 } from "child_process";
|
|
6722
6807
|
|
|
6723
6808
|
// src/shared/loadJson.ts
|
|
6724
|
-
import { existsSync as
|
|
6809
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync6, readFileSync as readFileSync25, writeFileSync as writeFileSync20 } from "fs";
|
|
6725
6810
|
import { homedir as homedir6 } from "os";
|
|
6726
|
-
import { join as
|
|
6811
|
+
import { join as join24 } from "path";
|
|
6727
6812
|
function getStoreDir() {
|
|
6728
|
-
return
|
|
6813
|
+
return join24(homedir6(), ".assist");
|
|
6729
6814
|
}
|
|
6730
6815
|
function getStorePath(filename) {
|
|
6731
|
-
return
|
|
6816
|
+
return join24(getStoreDir(), filename);
|
|
6732
6817
|
}
|
|
6733
6818
|
function loadJson(filename) {
|
|
6734
6819
|
const path50 = getStorePath(filename);
|
|
6735
|
-
if (
|
|
6820
|
+
if (existsSync27(path50)) {
|
|
6736
6821
|
try {
|
|
6737
|
-
return JSON.parse(
|
|
6822
|
+
return JSON.parse(readFileSync25(path50, "utf-8"));
|
|
6738
6823
|
} catch {
|
|
6739
6824
|
return {};
|
|
6740
6825
|
}
|
|
@@ -6743,10 +6828,10 @@ function loadJson(filename) {
|
|
|
6743
6828
|
}
|
|
6744
6829
|
function saveJson(filename, data) {
|
|
6745
6830
|
const dir = getStoreDir();
|
|
6746
|
-
if (!
|
|
6831
|
+
if (!existsSync27(dir)) {
|
|
6747
6832
|
mkdirSync6(dir, { recursive: true });
|
|
6748
6833
|
}
|
|
6749
|
-
|
|
6834
|
+
writeFileSync20(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
6750
6835
|
}
|
|
6751
6836
|
|
|
6752
6837
|
// src/shared/promptInput.ts
|
|
@@ -6798,14 +6883,14 @@ async function jiraAuth() {
|
|
|
6798
6883
|
}
|
|
6799
6884
|
|
|
6800
6885
|
// src/commands/jira/viewIssue.ts
|
|
6801
|
-
import
|
|
6886
|
+
import chalk86 from "chalk";
|
|
6802
6887
|
function viewIssue(issueKey) {
|
|
6803
6888
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
6804
6889
|
const fields = parsed?.fields;
|
|
6805
6890
|
const summary = fields?.summary;
|
|
6806
6891
|
const description = fields?.description;
|
|
6807
6892
|
if (summary) {
|
|
6808
|
-
console.log(
|
|
6893
|
+
console.log(chalk86.bold(summary));
|
|
6809
6894
|
}
|
|
6810
6895
|
if (description) {
|
|
6811
6896
|
if (summary) console.log();
|
|
@@ -6819,7 +6904,7 @@ function viewIssue(issueKey) {
|
|
|
6819
6904
|
}
|
|
6820
6905
|
if (!summary && !description) {
|
|
6821
6906
|
console.log(
|
|
6822
|
-
|
|
6907
|
+
chalk86.yellow(`No summary or description found on ${issueKey}.`)
|
|
6823
6908
|
);
|
|
6824
6909
|
}
|
|
6825
6910
|
}
|
|
@@ -6833,7 +6918,7 @@ function registerJira(program2) {
|
|
|
6833
6918
|
}
|
|
6834
6919
|
|
|
6835
6920
|
// src/commands/news/add/index.ts
|
|
6836
|
-
import
|
|
6921
|
+
import chalk87 from "chalk";
|
|
6837
6922
|
import enquirer7 from "enquirer";
|
|
6838
6923
|
async function add2(url) {
|
|
6839
6924
|
if (!url) {
|
|
@@ -6856,17 +6941,17 @@ async function add2(url) {
|
|
|
6856
6941
|
const news = config.news ?? {};
|
|
6857
6942
|
const feeds = news.feeds ?? [];
|
|
6858
6943
|
if (feeds.includes(url)) {
|
|
6859
|
-
console.log(
|
|
6944
|
+
console.log(chalk87.yellow("Feed already exists in config"));
|
|
6860
6945
|
return;
|
|
6861
6946
|
}
|
|
6862
6947
|
feeds.push(url);
|
|
6863
6948
|
config.news = { ...news, feeds };
|
|
6864
6949
|
saveGlobalConfig(config);
|
|
6865
|
-
console.log(
|
|
6950
|
+
console.log(chalk87.green(`Added feed: ${url}`));
|
|
6866
6951
|
}
|
|
6867
6952
|
|
|
6868
6953
|
// src/commands/news/web/handleRequest.ts
|
|
6869
|
-
import
|
|
6954
|
+
import chalk88 from "chalk";
|
|
6870
6955
|
|
|
6871
6956
|
// src/commands/news/web/shared.ts
|
|
6872
6957
|
import { decodeHTML } from "entities";
|
|
@@ -7002,17 +7087,17 @@ function prefetch() {
|
|
|
7002
7087
|
const config = loadConfig();
|
|
7003
7088
|
const total = config.news.feeds.length;
|
|
7004
7089
|
if (total === 0) return;
|
|
7005
|
-
process.stdout.write(
|
|
7090
|
+
process.stdout.write(chalk88.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
7006
7091
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
7007
7092
|
const width = 20;
|
|
7008
7093
|
const filled = Math.round(done2 / t * width);
|
|
7009
7094
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
7010
7095
|
process.stdout.write(
|
|
7011
|
-
`\r${
|
|
7096
|
+
`\r${chalk88.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
7012
7097
|
);
|
|
7013
7098
|
}).then((items) => {
|
|
7014
7099
|
process.stdout.write(
|
|
7015
|
-
`\r${
|
|
7100
|
+
`\r${chalk88.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
7016
7101
|
`
|
|
7017
7102
|
);
|
|
7018
7103
|
cachedItems = items;
|
|
@@ -7058,9 +7143,9 @@ function registerNews(program2) {
|
|
|
7058
7143
|
|
|
7059
7144
|
// src/commands/prs/comment.ts
|
|
7060
7145
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
7061
|
-
import { unlinkSync as unlinkSync6, writeFileSync as
|
|
7146
|
+
import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync21 } from "fs";
|
|
7062
7147
|
import { tmpdir as tmpdir3 } from "os";
|
|
7063
|
-
import { join as
|
|
7148
|
+
import { join as join25 } from "path";
|
|
7064
7149
|
|
|
7065
7150
|
// src/commands/prs/shared.ts
|
|
7066
7151
|
import { execSync as execSync27 } from "child_process";
|
|
@@ -7132,8 +7217,8 @@ function comment2(path50, line, body) {
|
|
|
7132
7217
|
validateLine(line);
|
|
7133
7218
|
try {
|
|
7134
7219
|
const prId = getCurrentPrNodeId();
|
|
7135
|
-
const queryFile =
|
|
7136
|
-
|
|
7220
|
+
const queryFile = join25(tmpdir3(), `gh-query-${Date.now()}.graphql`);
|
|
7221
|
+
writeFileSync21(queryFile, MUTATION);
|
|
7137
7222
|
try {
|
|
7138
7223
|
const result = spawnSync2(
|
|
7139
7224
|
"gh",
|
|
@@ -7175,28 +7260,28 @@ import { execSync as execSync29 } from "child_process";
|
|
|
7175
7260
|
|
|
7176
7261
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
7177
7262
|
import { execSync as execSync28 } from "child_process";
|
|
7178
|
-
import { unlinkSync as unlinkSync8, writeFileSync as
|
|
7263
|
+
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
7179
7264
|
import { tmpdir as tmpdir4 } from "os";
|
|
7180
|
-
import { join as
|
|
7265
|
+
import { join as join27 } from "path";
|
|
7181
7266
|
|
|
7182
7267
|
// src/commands/prs/loadCommentsCache.ts
|
|
7183
|
-
import { existsSync as
|
|
7184
|
-
import { join as
|
|
7268
|
+
import { existsSync as existsSync28, readFileSync as readFileSync26, unlinkSync as unlinkSync7 } from "fs";
|
|
7269
|
+
import { join as join26 } from "path";
|
|
7185
7270
|
import { parse as parse2 } from "yaml";
|
|
7186
7271
|
function getCachePath(prNumber) {
|
|
7187
|
-
return
|
|
7272
|
+
return join26(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
|
|
7188
7273
|
}
|
|
7189
7274
|
function loadCommentsCache(prNumber) {
|
|
7190
7275
|
const cachePath = getCachePath(prNumber);
|
|
7191
|
-
if (!
|
|
7276
|
+
if (!existsSync28(cachePath)) {
|
|
7192
7277
|
return null;
|
|
7193
7278
|
}
|
|
7194
|
-
const content =
|
|
7279
|
+
const content = readFileSync26(cachePath, "utf-8");
|
|
7195
7280
|
return parse2(content);
|
|
7196
7281
|
}
|
|
7197
7282
|
function deleteCommentsCache(prNumber) {
|
|
7198
7283
|
const cachePath = getCachePath(prNumber);
|
|
7199
|
-
if (
|
|
7284
|
+
if (existsSync28(cachePath)) {
|
|
7200
7285
|
unlinkSync7(cachePath);
|
|
7201
7286
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
7202
7287
|
}
|
|
@@ -7211,8 +7296,8 @@ function replyToComment(org, repo, prNumber, commentId, message) {
|
|
|
7211
7296
|
}
|
|
7212
7297
|
function resolveThread(threadId) {
|
|
7213
7298
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
7214
|
-
const queryFile =
|
|
7215
|
-
|
|
7299
|
+
const queryFile = join27(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
|
|
7300
|
+
writeFileSync22(queryFile, mutation);
|
|
7216
7301
|
try {
|
|
7217
7302
|
execSync28(
|
|
7218
7303
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
@@ -7293,19 +7378,19 @@ function fixed(commentId, sha) {
|
|
|
7293
7378
|
}
|
|
7294
7379
|
|
|
7295
7380
|
// src/commands/prs/listComments/index.ts
|
|
7296
|
-
import { existsSync as
|
|
7297
|
-
import { join as
|
|
7381
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync7, writeFileSync as writeFileSync24 } from "fs";
|
|
7382
|
+
import { join as join29 } from "path";
|
|
7298
7383
|
import { stringify } from "yaml";
|
|
7299
7384
|
|
|
7300
7385
|
// src/commands/prs/fetchThreadIds.ts
|
|
7301
7386
|
import { execSync as execSync30 } from "child_process";
|
|
7302
|
-
import { unlinkSync as unlinkSync9, writeFileSync as
|
|
7387
|
+
import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync23 } from "fs";
|
|
7303
7388
|
import { tmpdir as tmpdir5 } from "os";
|
|
7304
|
-
import { join as
|
|
7389
|
+
import { join as join28 } from "path";
|
|
7305
7390
|
var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
|
|
7306
7391
|
function fetchThreadIds(org, repo, prNumber) {
|
|
7307
|
-
const queryFile =
|
|
7308
|
-
|
|
7392
|
+
const queryFile = join28(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
7393
|
+
writeFileSync23(queryFile, THREAD_QUERY);
|
|
7309
7394
|
try {
|
|
7310
7395
|
const result = execSync30(
|
|
7311
7396
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
@@ -7373,20 +7458,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
7373
7458
|
}
|
|
7374
7459
|
|
|
7375
7460
|
// src/commands/prs/listComments/printComments.ts
|
|
7376
|
-
import
|
|
7461
|
+
import chalk89 from "chalk";
|
|
7377
7462
|
function formatForHuman(comment3) {
|
|
7378
7463
|
if (comment3.type === "review") {
|
|
7379
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
7464
|
+
const stateColor = comment3.state === "APPROVED" ? chalk89.green : comment3.state === "CHANGES_REQUESTED" ? chalk89.red : chalk89.yellow;
|
|
7380
7465
|
return [
|
|
7381
|
-
`${
|
|
7466
|
+
`${chalk89.cyan("Review")} by ${chalk89.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
7382
7467
|
comment3.body,
|
|
7383
7468
|
""
|
|
7384
7469
|
].join("\n");
|
|
7385
7470
|
}
|
|
7386
7471
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
7387
7472
|
return [
|
|
7388
|
-
`${
|
|
7389
|
-
|
|
7473
|
+
`${chalk89.cyan("Line comment")} by ${chalk89.bold(comment3.user)} on ${chalk89.dim(`${comment3.path}${location}`)}`,
|
|
7474
|
+
chalk89.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
7390
7475
|
comment3.body,
|
|
7391
7476
|
""
|
|
7392
7477
|
].join("\n");
|
|
@@ -7418,8 +7503,8 @@ function printComments2(result) {
|
|
|
7418
7503
|
|
|
7419
7504
|
// src/commands/prs/listComments/index.ts
|
|
7420
7505
|
function writeCommentsCache(prNumber, comments2) {
|
|
7421
|
-
const assistDir =
|
|
7422
|
-
if (!
|
|
7506
|
+
const assistDir = join29(process.cwd(), ".assist");
|
|
7507
|
+
if (!existsSync29(assistDir)) {
|
|
7423
7508
|
mkdirSync7(assistDir, { recursive: true });
|
|
7424
7509
|
}
|
|
7425
7510
|
const cacheData = {
|
|
@@ -7427,8 +7512,8 @@ function writeCommentsCache(prNumber, comments2) {
|
|
|
7427
7512
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7428
7513
|
comments: comments2
|
|
7429
7514
|
};
|
|
7430
|
-
const cachePath =
|
|
7431
|
-
|
|
7515
|
+
const cachePath = join29(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
7516
|
+
writeFileSync24(cachePath, stringify(cacheData));
|
|
7432
7517
|
}
|
|
7433
7518
|
function handleKnownErrors(error) {
|
|
7434
7519
|
if (isGhNotInstalled(error)) {
|
|
@@ -7460,7 +7545,7 @@ async function listComments() {
|
|
|
7460
7545
|
];
|
|
7461
7546
|
updateCache(prNumber, allComments);
|
|
7462
7547
|
const hasLineComments = allComments.some((c) => c.type === "line");
|
|
7463
|
-
const cachePath = hasLineComments ?
|
|
7548
|
+
const cachePath = hasLineComments ? join29(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
|
|
7464
7549
|
return { comments: allComments, cachePath };
|
|
7465
7550
|
} catch (error) {
|
|
7466
7551
|
const handled = handleKnownErrors(error);
|
|
@@ -7476,13 +7561,13 @@ import { execSync as execSync32 } from "child_process";
|
|
|
7476
7561
|
import enquirer8 from "enquirer";
|
|
7477
7562
|
|
|
7478
7563
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
7479
|
-
import
|
|
7564
|
+
import chalk90 from "chalk";
|
|
7480
7565
|
var STATUS_MAP = {
|
|
7481
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
7482
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
7566
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk90.magenta("merged"), date: pr.mergedAt } : null,
|
|
7567
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk90.red("closed"), date: pr.closedAt } : null
|
|
7483
7568
|
};
|
|
7484
7569
|
function defaultStatus(pr) {
|
|
7485
|
-
return { label:
|
|
7570
|
+
return { label: chalk90.green("opened"), date: pr.createdAt };
|
|
7486
7571
|
}
|
|
7487
7572
|
function getStatus2(pr) {
|
|
7488
7573
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -7491,11 +7576,11 @@ function formatDate(dateStr) {
|
|
|
7491
7576
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
7492
7577
|
}
|
|
7493
7578
|
function formatPrHeader(pr, status2) {
|
|
7494
|
-
return `${
|
|
7579
|
+
return `${chalk90.cyan(`#${pr.number}`)} ${pr.title} ${chalk90.dim(`(${pr.author.login},`)} ${status2.label} ${chalk90.dim(`${formatDate(status2.date)})`)}`;
|
|
7495
7580
|
}
|
|
7496
7581
|
function logPrDetails(pr) {
|
|
7497
7582
|
console.log(
|
|
7498
|
-
|
|
7583
|
+
chalk90.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
7499
7584
|
);
|
|
7500
7585
|
console.log();
|
|
7501
7586
|
}
|
|
@@ -7661,10 +7746,10 @@ function registerPrs(program2) {
|
|
|
7661
7746
|
}
|
|
7662
7747
|
|
|
7663
7748
|
// src/commands/ravendb/ravendbAuth.ts
|
|
7664
|
-
import
|
|
7749
|
+
import chalk96 from "chalk";
|
|
7665
7750
|
|
|
7666
7751
|
// src/shared/createConnectionAuth.ts
|
|
7667
|
-
import
|
|
7752
|
+
import chalk91 from "chalk";
|
|
7668
7753
|
function listConnections(connections, format2) {
|
|
7669
7754
|
if (connections.length === 0) {
|
|
7670
7755
|
console.log("No connections configured.");
|
|
@@ -7677,7 +7762,7 @@ function listConnections(connections, format2) {
|
|
|
7677
7762
|
function removeConnection(connections, name, save) {
|
|
7678
7763
|
const filtered = connections.filter((c) => c.name !== name);
|
|
7679
7764
|
if (filtered.length === connections.length) {
|
|
7680
|
-
console.error(
|
|
7765
|
+
console.error(chalk91.red(`Connection "${name}" not found.`));
|
|
7681
7766
|
process.exit(1);
|
|
7682
7767
|
}
|
|
7683
7768
|
save(filtered);
|
|
@@ -7723,34 +7808,34 @@ function saveConnections(connections) {
|
|
|
7723
7808
|
}
|
|
7724
7809
|
|
|
7725
7810
|
// src/commands/ravendb/promptConnection.ts
|
|
7726
|
-
import
|
|
7811
|
+
import chalk94 from "chalk";
|
|
7727
7812
|
|
|
7728
7813
|
// src/commands/ravendb/selectOpSecret.ts
|
|
7729
|
-
import
|
|
7814
|
+
import chalk93 from "chalk";
|
|
7730
7815
|
import Enquirer2 from "enquirer";
|
|
7731
7816
|
|
|
7732
7817
|
// src/commands/ravendb/searchItems.ts
|
|
7733
7818
|
import { execSync as execSync34 } from "child_process";
|
|
7734
|
-
import
|
|
7819
|
+
import chalk92 from "chalk";
|
|
7735
7820
|
function opExec(args) {
|
|
7736
7821
|
return execSync34(`op ${args}`, {
|
|
7737
7822
|
encoding: "utf-8",
|
|
7738
7823
|
stdio: ["pipe", "pipe", "pipe"]
|
|
7739
7824
|
}).trim();
|
|
7740
7825
|
}
|
|
7741
|
-
function searchItems(
|
|
7826
|
+
function searchItems(search2) {
|
|
7742
7827
|
let items;
|
|
7743
7828
|
try {
|
|
7744
7829
|
items = JSON.parse(opExec("item list --format=json"));
|
|
7745
7830
|
} catch {
|
|
7746
7831
|
console.error(
|
|
7747
|
-
|
|
7832
|
+
chalk92.red(
|
|
7748
7833
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
7749
7834
|
)
|
|
7750
7835
|
);
|
|
7751
7836
|
process.exit(1);
|
|
7752
7837
|
}
|
|
7753
|
-
const lower =
|
|
7838
|
+
const lower = search2.toLowerCase();
|
|
7754
7839
|
return items.filter((i) => i.title.toLowerCase().includes(lower));
|
|
7755
7840
|
}
|
|
7756
7841
|
function getItemFields(itemId) {
|
|
@@ -7758,7 +7843,7 @@ function getItemFields(itemId) {
|
|
|
7758
7843
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
7759
7844
|
return item.fields.filter((f) => f.reference && f.label);
|
|
7760
7845
|
} catch {
|
|
7761
|
-
console.error(
|
|
7846
|
+
console.error(chalk92.red("Failed to get item details from 1Password."));
|
|
7762
7847
|
process.exit(1);
|
|
7763
7848
|
}
|
|
7764
7849
|
}
|
|
@@ -7771,13 +7856,13 @@ async function selectOne(message, choices) {
|
|
|
7771
7856
|
return choices.find((c) => c.name === selected)?.value ?? selected;
|
|
7772
7857
|
}
|
|
7773
7858
|
async function selectOpSecret(searchTerm) {
|
|
7774
|
-
const
|
|
7859
|
+
const search2 = searchTerm ?? await new Input({
|
|
7775
7860
|
name: "search",
|
|
7776
7861
|
message: "Search 1Password for API key item:"
|
|
7777
7862
|
}).run();
|
|
7778
|
-
const items = searchItems(
|
|
7863
|
+
const items = searchItems(search2);
|
|
7779
7864
|
if (items.length === 0) {
|
|
7780
|
-
console.error(
|
|
7865
|
+
console.error(chalk93.red(`No items found matching "${search2}".`));
|
|
7781
7866
|
process.exit(1);
|
|
7782
7867
|
}
|
|
7783
7868
|
const itemId = await selectOne(
|
|
@@ -7786,7 +7871,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7786
7871
|
);
|
|
7787
7872
|
const fields = getItemFields(itemId);
|
|
7788
7873
|
if (fields.length === 0) {
|
|
7789
|
-
console.error(
|
|
7874
|
+
console.error(chalk93.red("No fields with references found on this item."));
|
|
7790
7875
|
process.exit(1);
|
|
7791
7876
|
}
|
|
7792
7877
|
const ref = await selectOne(
|
|
@@ -7800,7 +7885,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7800
7885
|
async function promptConnection(existingNames) {
|
|
7801
7886
|
const name = await promptInput("name", "Connection name:");
|
|
7802
7887
|
if (existingNames.includes(name)) {
|
|
7803
|
-
console.error(
|
|
7888
|
+
console.error(chalk94.red(`Connection "${name}" already exists.`));
|
|
7804
7889
|
process.exit(1);
|
|
7805
7890
|
}
|
|
7806
7891
|
const url = await promptInput(
|
|
@@ -7809,22 +7894,22 @@ async function promptConnection(existingNames) {
|
|
|
7809
7894
|
);
|
|
7810
7895
|
const database = await promptInput("database", "Database name:");
|
|
7811
7896
|
if (!name || !url || !database) {
|
|
7812
|
-
console.error(
|
|
7897
|
+
console.error(chalk94.red("All fields are required."));
|
|
7813
7898
|
process.exit(1);
|
|
7814
7899
|
}
|
|
7815
7900
|
const apiKeyRef = await selectOpSecret();
|
|
7816
|
-
console.log(
|
|
7901
|
+
console.log(chalk94.dim(`Using: ${apiKeyRef}`));
|
|
7817
7902
|
return { name, url, database, apiKeyRef };
|
|
7818
7903
|
}
|
|
7819
7904
|
|
|
7820
7905
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
7821
|
-
import
|
|
7906
|
+
import chalk95 from "chalk";
|
|
7822
7907
|
function ravendbSetConnection(name) {
|
|
7823
7908
|
const raw = loadGlobalConfigRaw();
|
|
7824
7909
|
const ravendb = raw.ravendb ?? {};
|
|
7825
7910
|
const connections = ravendb.connections ?? [];
|
|
7826
7911
|
if (!connections.some((c) => c.name === name)) {
|
|
7827
|
-
console.error(
|
|
7912
|
+
console.error(chalk95.red(`Connection "${name}" not found.`));
|
|
7828
7913
|
console.error(
|
|
7829
7914
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7830
7915
|
);
|
|
@@ -7840,16 +7925,16 @@ function ravendbSetConnection(name) {
|
|
|
7840
7925
|
var ravendbAuth = createConnectionAuth({
|
|
7841
7926
|
load: loadConnections,
|
|
7842
7927
|
save: saveConnections,
|
|
7843
|
-
format: (c) => `${
|
|
7928
|
+
format: (c) => `${chalk96.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
7844
7929
|
promptNew: promptConnection,
|
|
7845
7930
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
7846
7931
|
});
|
|
7847
7932
|
|
|
7848
7933
|
// src/commands/ravendb/ravendbCollections.ts
|
|
7849
|
-
import
|
|
7934
|
+
import chalk100 from "chalk";
|
|
7850
7935
|
|
|
7851
7936
|
// src/commands/ravendb/ravenFetch.ts
|
|
7852
|
-
import
|
|
7937
|
+
import chalk98 from "chalk";
|
|
7853
7938
|
|
|
7854
7939
|
// src/commands/ravendb/getAccessToken.ts
|
|
7855
7940
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -7886,10 +7971,10 @@ ${errorText}`
|
|
|
7886
7971
|
|
|
7887
7972
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
7888
7973
|
import { execSync as execSync35 } from "child_process";
|
|
7889
|
-
import
|
|
7974
|
+
import chalk97 from "chalk";
|
|
7890
7975
|
function resolveOpSecret(reference) {
|
|
7891
7976
|
if (!reference.startsWith("op://")) {
|
|
7892
|
-
console.error(
|
|
7977
|
+
console.error(chalk97.red(`Invalid secret reference: must start with op://`));
|
|
7893
7978
|
process.exit(1);
|
|
7894
7979
|
}
|
|
7895
7980
|
try {
|
|
@@ -7899,7 +7984,7 @@ function resolveOpSecret(reference) {
|
|
|
7899
7984
|
}).trim();
|
|
7900
7985
|
} catch {
|
|
7901
7986
|
console.error(
|
|
7902
|
-
|
|
7987
|
+
chalk97.red(
|
|
7903
7988
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
7904
7989
|
)
|
|
7905
7990
|
);
|
|
@@ -7926,7 +8011,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7926
8011
|
if (!response.ok) {
|
|
7927
8012
|
const body = await response.text();
|
|
7928
8013
|
console.error(
|
|
7929
|
-
|
|
8014
|
+
chalk98.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
7930
8015
|
);
|
|
7931
8016
|
console.error(body.substring(0, 500));
|
|
7932
8017
|
process.exit(1);
|
|
@@ -7935,7 +8020,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7935
8020
|
}
|
|
7936
8021
|
|
|
7937
8022
|
// src/commands/ravendb/resolveConnection.ts
|
|
7938
|
-
import
|
|
8023
|
+
import chalk99 from "chalk";
|
|
7939
8024
|
function loadRavendb() {
|
|
7940
8025
|
const raw = loadGlobalConfigRaw();
|
|
7941
8026
|
const ravendb = raw.ravendb;
|
|
@@ -7949,7 +8034,7 @@ function resolveConnection(name) {
|
|
|
7949
8034
|
const connectionName = name ?? defaultConnection;
|
|
7950
8035
|
if (!connectionName) {
|
|
7951
8036
|
console.error(
|
|
7952
|
-
|
|
8037
|
+
chalk99.red(
|
|
7953
8038
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
7954
8039
|
)
|
|
7955
8040
|
);
|
|
@@ -7957,7 +8042,7 @@ function resolveConnection(name) {
|
|
|
7957
8042
|
}
|
|
7958
8043
|
const connection = connections.find((c) => c.name === connectionName);
|
|
7959
8044
|
if (!connection) {
|
|
7960
|
-
console.error(
|
|
8045
|
+
console.error(chalk99.red(`Connection "${connectionName}" not found.`));
|
|
7961
8046
|
console.error(
|
|
7962
8047
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7963
8048
|
);
|
|
@@ -7988,15 +8073,15 @@ async function ravendbCollections(connectionName) {
|
|
|
7988
8073
|
return;
|
|
7989
8074
|
}
|
|
7990
8075
|
for (const c of collections) {
|
|
7991
|
-
console.log(`${
|
|
8076
|
+
console.log(`${chalk100.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
7992
8077
|
}
|
|
7993
8078
|
}
|
|
7994
8079
|
|
|
7995
8080
|
// src/commands/ravendb/ravendbQuery.ts
|
|
7996
|
-
import
|
|
8081
|
+
import chalk102 from "chalk";
|
|
7997
8082
|
|
|
7998
8083
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7999
|
-
import
|
|
8084
|
+
import chalk101 from "chalk";
|
|
8000
8085
|
|
|
8001
8086
|
// src/commands/ravendb/buildQueryPath.ts
|
|
8002
8087
|
function buildQueryPath(opts) {
|
|
@@ -8034,7 +8119,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8034
8119
|
allResults.push(...results);
|
|
8035
8120
|
start3 += results.length;
|
|
8036
8121
|
process.stderr.write(
|
|
8037
|
-
`\r${
|
|
8122
|
+
`\r${chalk101.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
8038
8123
|
);
|
|
8039
8124
|
if (start3 >= totalResults) break;
|
|
8040
8125
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -8049,7 +8134,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8049
8134
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
8050
8135
|
const resolved = resolveArgs(connectionName, collection);
|
|
8051
8136
|
if (!resolved.collection && !options2.query) {
|
|
8052
|
-
console.error(
|
|
8137
|
+
console.error(chalk102.red("Provide a collection name or --query filter."));
|
|
8053
8138
|
process.exit(1);
|
|
8054
8139
|
}
|
|
8055
8140
|
const { collection: col } = resolved;
|
|
@@ -8087,7 +8172,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
8087
8172
|
import * as path27 from "path";
|
|
8088
8173
|
|
|
8089
8174
|
// src/commands/refactor/logViolations.ts
|
|
8090
|
-
import
|
|
8175
|
+
import chalk103 from "chalk";
|
|
8091
8176
|
var DEFAULT_MAX_LINES = 100;
|
|
8092
8177
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
8093
8178
|
if (violations.length === 0) {
|
|
@@ -8096,43 +8181,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
8096
8181
|
}
|
|
8097
8182
|
return;
|
|
8098
8183
|
}
|
|
8099
|
-
console.error(
|
|
8184
|
+
console.error(chalk103.red(`
|
|
8100
8185
|
Refactor check failed:
|
|
8101
8186
|
`));
|
|
8102
|
-
console.error(
|
|
8187
|
+
console.error(chalk103.red(` The following files exceed ${maxLines} lines:
|
|
8103
8188
|
`));
|
|
8104
8189
|
for (const violation of violations) {
|
|
8105
|
-
console.error(
|
|
8190
|
+
console.error(chalk103.red(` ${violation.file} (${violation.lines} lines)`));
|
|
8106
8191
|
}
|
|
8107
8192
|
console.error(
|
|
8108
|
-
|
|
8193
|
+
chalk103.yellow(
|
|
8109
8194
|
`
|
|
8110
8195
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
8111
8196
|
way to refactor it, ignore it with:
|
|
8112
8197
|
`
|
|
8113
8198
|
)
|
|
8114
8199
|
);
|
|
8115
|
-
console.error(
|
|
8200
|
+
console.error(chalk103.gray(` assist refactor ignore <file>
|
|
8116
8201
|
`));
|
|
8117
8202
|
if (process.env.CLAUDECODE) {
|
|
8118
|
-
console.error(
|
|
8203
|
+
console.error(chalk103.cyan(`
|
|
8119
8204
|
## Extracting Code to New Files
|
|
8120
8205
|
`));
|
|
8121
8206
|
console.error(
|
|
8122
|
-
|
|
8207
|
+
chalk103.cyan(
|
|
8123
8208
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
8124
8209
|
`
|
|
8125
8210
|
)
|
|
8126
8211
|
);
|
|
8127
8212
|
console.error(
|
|
8128
|
-
|
|
8213
|
+
chalk103.cyan(
|
|
8129
8214
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
8130
8215
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
8131
8216
|
`
|
|
8132
8217
|
)
|
|
8133
8218
|
);
|
|
8134
8219
|
console.error(
|
|
8135
|
-
|
|
8220
|
+
chalk103.cyan(
|
|
8136
8221
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
8137
8222
|
domains, move it to a common/shared folder.
|
|
8138
8223
|
`
|
|
@@ -8288,7 +8373,7 @@ async function check(pattern2, options2) {
|
|
|
8288
8373
|
|
|
8289
8374
|
// src/commands/refactor/extract/index.ts
|
|
8290
8375
|
import path33 from "path";
|
|
8291
|
-
import
|
|
8376
|
+
import chalk106 from "chalk";
|
|
8292
8377
|
|
|
8293
8378
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
8294
8379
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -8835,23 +8920,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
8835
8920
|
|
|
8836
8921
|
// src/commands/refactor/extract/displayPlan.ts
|
|
8837
8922
|
import path31 from "path";
|
|
8838
|
-
import
|
|
8923
|
+
import chalk104 from "chalk";
|
|
8839
8924
|
function section(title) {
|
|
8840
8925
|
return `
|
|
8841
|
-
${
|
|
8926
|
+
${chalk104.cyan(title)}`;
|
|
8842
8927
|
}
|
|
8843
8928
|
function displayImporters(plan2, cwd) {
|
|
8844
8929
|
if (plan2.importersToUpdate.length === 0) return;
|
|
8845
8930
|
console.log(section("Update importers:"));
|
|
8846
8931
|
for (const imp of plan2.importersToUpdate) {
|
|
8847
8932
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
8848
|
-
console.log(` ${
|
|
8933
|
+
console.log(` ${chalk104.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
8849
8934
|
}
|
|
8850
8935
|
}
|
|
8851
8936
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
8852
|
-
console.log(
|
|
8937
|
+
console.log(chalk104.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
8853
8938
|
`));
|
|
8854
|
-
console.log(` ${
|
|
8939
|
+
console.log(` ${chalk104.cyan("Functions to move:")}`);
|
|
8855
8940
|
for (const name of plan2.extractedNames) {
|
|
8856
8941
|
console.log(` ${name}`);
|
|
8857
8942
|
}
|
|
@@ -8886,7 +8971,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
8886
8971
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
8887
8972
|
import fs17 from "fs";
|
|
8888
8973
|
import path32 from "path";
|
|
8889
|
-
import
|
|
8974
|
+
import chalk105 from "chalk";
|
|
8890
8975
|
import { Project as Project2 } from "ts-morph";
|
|
8891
8976
|
function findTsConfig(sourcePath) {
|
|
8892
8977
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -8917,7 +9002,7 @@ function loadProjectFile(file) {
|
|
|
8917
9002
|
});
|
|
8918
9003
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
8919
9004
|
if (!sourceFile) {
|
|
8920
|
-
console.log(
|
|
9005
|
+
console.log(chalk105.red(`File not found in project: ${file}`));
|
|
8921
9006
|
process.exit(1);
|
|
8922
9007
|
}
|
|
8923
9008
|
return { project, sourceFile };
|
|
@@ -8940,19 +9025,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
8940
9025
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
8941
9026
|
if (options2.apply) {
|
|
8942
9027
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
8943
|
-
console.log(
|
|
9028
|
+
console.log(chalk106.green("\nExtraction complete"));
|
|
8944
9029
|
} else {
|
|
8945
|
-
console.log(
|
|
9030
|
+
console.log(chalk106.dim("\nDry run. Use --apply to execute."));
|
|
8946
9031
|
}
|
|
8947
9032
|
}
|
|
8948
9033
|
|
|
8949
9034
|
// src/commands/refactor/ignore.ts
|
|
8950
9035
|
import fs18 from "fs";
|
|
8951
|
-
import
|
|
9036
|
+
import chalk107 from "chalk";
|
|
8952
9037
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
8953
9038
|
function ignore(file) {
|
|
8954
9039
|
if (!fs18.existsSync(file)) {
|
|
8955
|
-
console.error(
|
|
9040
|
+
console.error(chalk107.red(`Error: File does not exist: ${file}`));
|
|
8956
9041
|
process.exit(1);
|
|
8957
9042
|
}
|
|
8958
9043
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -8968,7 +9053,7 @@ function ignore(file) {
|
|
|
8968
9053
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
8969
9054
|
}
|
|
8970
9055
|
console.log(
|
|
8971
|
-
|
|
9056
|
+
chalk107.green(
|
|
8972
9057
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
8973
9058
|
)
|
|
8974
9059
|
);
|
|
@@ -8976,26 +9061,26 @@ function ignore(file) {
|
|
|
8976
9061
|
|
|
8977
9062
|
// src/commands/refactor/rename/index.ts
|
|
8978
9063
|
import path34 from "path";
|
|
8979
|
-
import
|
|
9064
|
+
import chalk108 from "chalk";
|
|
8980
9065
|
async function rename(source, destination, options2 = {}) {
|
|
8981
9066
|
const destPath = path34.resolve(destination);
|
|
8982
9067
|
const cwd = process.cwd();
|
|
8983
9068
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
8984
9069
|
const relDest = path34.relative(cwd, destPath);
|
|
8985
9070
|
const { project, sourceFile } = loadProjectFile(source);
|
|
8986
|
-
console.log(
|
|
9071
|
+
console.log(chalk108.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
8987
9072
|
if (options2.apply) {
|
|
8988
9073
|
sourceFile.move(destPath);
|
|
8989
9074
|
await project.save();
|
|
8990
|
-
console.log(
|
|
9075
|
+
console.log(chalk108.green("Done"));
|
|
8991
9076
|
} else {
|
|
8992
|
-
console.log(
|
|
9077
|
+
console.log(chalk108.dim("Dry run. Use --apply to execute."));
|
|
8993
9078
|
}
|
|
8994
9079
|
}
|
|
8995
9080
|
|
|
8996
9081
|
// src/commands/refactor/renameSymbol/index.ts
|
|
8997
9082
|
import path36 from "path";
|
|
8998
|
-
import
|
|
9083
|
+
import chalk109 from "chalk";
|
|
8999
9084
|
import { Project as Project3 } from "ts-morph";
|
|
9000
9085
|
|
|
9001
9086
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -9044,38 +9129,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
9044
9129
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
9045
9130
|
const sourceFile = project.getSourceFile(filePath);
|
|
9046
9131
|
if (!sourceFile) {
|
|
9047
|
-
console.log(
|
|
9132
|
+
console.log(chalk109.red(`File not found in project: ${file}`));
|
|
9048
9133
|
process.exit(1);
|
|
9049
9134
|
}
|
|
9050
9135
|
const symbol = findSymbol(sourceFile, oldName);
|
|
9051
9136
|
if (!symbol) {
|
|
9052
|
-
console.log(
|
|
9137
|
+
console.log(chalk109.red(`Symbol "${oldName}" not found in ${file}`));
|
|
9053
9138
|
process.exit(1);
|
|
9054
9139
|
}
|
|
9055
9140
|
const grouped = groupReferences(symbol, cwd);
|
|
9056
9141
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
9057
9142
|
console.log(
|
|
9058
|
-
|
|
9143
|
+
chalk109.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
9059
9144
|
`)
|
|
9060
9145
|
);
|
|
9061
9146
|
for (const [refFile, lines] of grouped) {
|
|
9062
9147
|
console.log(
|
|
9063
|
-
` ${
|
|
9148
|
+
` ${chalk109.dim(refFile)}: lines ${chalk109.cyan(lines.join(", "))}`
|
|
9064
9149
|
);
|
|
9065
9150
|
}
|
|
9066
9151
|
if (options2.apply) {
|
|
9067
9152
|
symbol.rename(newName);
|
|
9068
9153
|
await project.save();
|
|
9069
|
-
console.log(
|
|
9154
|
+
console.log(chalk109.green(`
|
|
9070
9155
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
9071
9156
|
} else {
|
|
9072
|
-
console.log(
|
|
9157
|
+
console.log(chalk109.dim("\nDry run. Use --apply to execute."));
|
|
9073
9158
|
}
|
|
9074
9159
|
}
|
|
9075
9160
|
|
|
9076
9161
|
// src/commands/refactor/restructure/index.ts
|
|
9077
9162
|
import path45 from "path";
|
|
9078
|
-
import
|
|
9163
|
+
import chalk112 from "chalk";
|
|
9079
9164
|
|
|
9080
9165
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
9081
9166
|
import path37 from "path";
|
|
@@ -9318,50 +9403,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
9318
9403
|
|
|
9319
9404
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
9320
9405
|
import path41 from "path";
|
|
9321
|
-
import
|
|
9406
|
+
import chalk110 from "chalk";
|
|
9322
9407
|
function relPath(filePath) {
|
|
9323
9408
|
return path41.relative(process.cwd(), filePath);
|
|
9324
9409
|
}
|
|
9325
9410
|
function displayMoves(plan2) {
|
|
9326
9411
|
if (plan2.moves.length === 0) return;
|
|
9327
|
-
console.log(
|
|
9412
|
+
console.log(chalk110.bold("\nFile moves:"));
|
|
9328
9413
|
for (const move of plan2.moves) {
|
|
9329
9414
|
console.log(
|
|
9330
|
-
` ${
|
|
9415
|
+
` ${chalk110.red(relPath(move.from))} \u2192 ${chalk110.green(relPath(move.to))}`
|
|
9331
9416
|
);
|
|
9332
|
-
console.log(
|
|
9417
|
+
console.log(chalk110.dim(` ${move.reason}`));
|
|
9333
9418
|
}
|
|
9334
9419
|
}
|
|
9335
9420
|
function displayRewrites(rewrites) {
|
|
9336
9421
|
if (rewrites.length === 0) return;
|
|
9337
9422
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
9338
|
-
console.log(
|
|
9423
|
+
console.log(chalk110.bold(`
|
|
9339
9424
|
Import rewrites (${affectedFiles.size} files):`));
|
|
9340
9425
|
for (const file of affectedFiles) {
|
|
9341
|
-
console.log(` ${
|
|
9426
|
+
console.log(` ${chalk110.cyan(relPath(file))}:`);
|
|
9342
9427
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
9343
9428
|
(r) => r.file === file
|
|
9344
9429
|
)) {
|
|
9345
9430
|
console.log(
|
|
9346
|
-
` ${
|
|
9431
|
+
` ${chalk110.red(`"${oldSpecifier}"`)} \u2192 ${chalk110.green(`"${newSpecifier}"`)}`
|
|
9347
9432
|
);
|
|
9348
9433
|
}
|
|
9349
9434
|
}
|
|
9350
9435
|
}
|
|
9351
9436
|
function displayPlan2(plan2) {
|
|
9352
9437
|
if (plan2.warnings.length > 0) {
|
|
9353
|
-
console.log(
|
|
9354
|
-
for (const w of plan2.warnings) console.log(
|
|
9438
|
+
console.log(chalk110.yellow("\nWarnings:"));
|
|
9439
|
+
for (const w of plan2.warnings) console.log(chalk110.yellow(` ${w}`));
|
|
9355
9440
|
}
|
|
9356
9441
|
if (plan2.newDirectories.length > 0) {
|
|
9357
|
-
console.log(
|
|
9442
|
+
console.log(chalk110.bold("\nNew directories:"));
|
|
9358
9443
|
for (const dir of plan2.newDirectories)
|
|
9359
|
-
console.log(
|
|
9444
|
+
console.log(chalk110.green(` ${dir}/`));
|
|
9360
9445
|
}
|
|
9361
9446
|
displayMoves(plan2);
|
|
9362
9447
|
displayRewrites(plan2.rewrites);
|
|
9363
9448
|
console.log(
|
|
9364
|
-
|
|
9449
|
+
chalk110.dim(
|
|
9365
9450
|
`
|
|
9366
9451
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
9367
9452
|
)
|
|
@@ -9371,18 +9456,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
9371
9456
|
// src/commands/refactor/restructure/executePlan.ts
|
|
9372
9457
|
import fs20 from "fs";
|
|
9373
9458
|
import path42 from "path";
|
|
9374
|
-
import
|
|
9459
|
+
import chalk111 from "chalk";
|
|
9375
9460
|
function executePlan(plan2) {
|
|
9376
9461
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
9377
9462
|
for (const [file, content] of updatedContents) {
|
|
9378
9463
|
fs20.writeFileSync(file, content, "utf-8");
|
|
9379
9464
|
console.log(
|
|
9380
|
-
|
|
9465
|
+
chalk111.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
9381
9466
|
);
|
|
9382
9467
|
}
|
|
9383
9468
|
for (const dir of plan2.newDirectories) {
|
|
9384
9469
|
fs20.mkdirSync(dir, { recursive: true });
|
|
9385
|
-
console.log(
|
|
9470
|
+
console.log(chalk111.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
9386
9471
|
}
|
|
9387
9472
|
for (const move of plan2.moves) {
|
|
9388
9473
|
const targetDir = path42.dirname(move.to);
|
|
@@ -9391,7 +9476,7 @@ function executePlan(plan2) {
|
|
|
9391
9476
|
}
|
|
9392
9477
|
fs20.renameSync(move.from, move.to);
|
|
9393
9478
|
console.log(
|
|
9394
|
-
|
|
9479
|
+
chalk111.white(
|
|
9395
9480
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
9396
9481
|
)
|
|
9397
9482
|
);
|
|
@@ -9406,7 +9491,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
9406
9491
|
if (entries.length === 0) {
|
|
9407
9492
|
fs20.rmdirSync(dir);
|
|
9408
9493
|
console.log(
|
|
9409
|
-
|
|
9494
|
+
chalk111.dim(
|
|
9410
9495
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
9411
9496
|
)
|
|
9412
9497
|
);
|
|
@@ -9539,22 +9624,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
9539
9624
|
const targetPattern = pattern2 ?? "src";
|
|
9540
9625
|
const files = findSourceFiles2(targetPattern);
|
|
9541
9626
|
if (files.length === 0) {
|
|
9542
|
-
console.log(
|
|
9627
|
+
console.log(chalk112.yellow("No files found matching pattern"));
|
|
9543
9628
|
return;
|
|
9544
9629
|
}
|
|
9545
9630
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
9546
9631
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
9547
9632
|
if (plan2.moves.length === 0) {
|
|
9548
|
-
console.log(
|
|
9633
|
+
console.log(chalk112.green("No restructuring needed"));
|
|
9549
9634
|
return;
|
|
9550
9635
|
}
|
|
9551
9636
|
displayPlan2(plan2);
|
|
9552
9637
|
if (options2.apply) {
|
|
9553
|
-
console.log(
|
|
9638
|
+
console.log(chalk112.bold("\nApplying changes..."));
|
|
9554
9639
|
executePlan(plan2);
|
|
9555
|
-
console.log(
|
|
9640
|
+
console.log(chalk112.green("\nRestructuring complete"));
|
|
9556
9641
|
} else {
|
|
9557
|
-
console.log(
|
|
9642
|
+
console.log(chalk112.dim("\nDry run. Use --apply to execute."));
|
|
9558
9643
|
}
|
|
9559
9644
|
}
|
|
9560
9645
|
|
|
@@ -9594,7 +9679,7 @@ function registerRefactor(program2) {
|
|
|
9594
9679
|
}
|
|
9595
9680
|
|
|
9596
9681
|
// src/commands/seq/seqAuth.ts
|
|
9597
|
-
import
|
|
9682
|
+
import chalk114 from "chalk";
|
|
9598
9683
|
|
|
9599
9684
|
// src/commands/seq/loadConnections.ts
|
|
9600
9685
|
function loadConnections2() {
|
|
@@ -9623,11 +9708,11 @@ function setDefaultConnection(name) {
|
|
|
9623
9708
|
}
|
|
9624
9709
|
|
|
9625
9710
|
// src/commands/seq/promptConnection.ts
|
|
9626
|
-
import
|
|
9711
|
+
import chalk113 from "chalk";
|
|
9627
9712
|
async function promptConnection2(existingNames) {
|
|
9628
9713
|
const name = await promptInput("name", "Connection name:", "default");
|
|
9629
9714
|
if (existingNames.includes(name)) {
|
|
9630
|
-
console.error(
|
|
9715
|
+
console.error(chalk113.red(`Connection "${name}" already exists.`));
|
|
9631
9716
|
process.exit(1);
|
|
9632
9717
|
}
|
|
9633
9718
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -9639,16 +9724,16 @@ async function promptConnection2(existingNames) {
|
|
|
9639
9724
|
var seqAuth = createConnectionAuth({
|
|
9640
9725
|
load: loadConnections2,
|
|
9641
9726
|
save: saveConnections2,
|
|
9642
|
-
format: (c) => `${
|
|
9727
|
+
format: (c) => `${chalk114.bold(c.name)} ${c.url}`,
|
|
9643
9728
|
promptNew: promptConnection2,
|
|
9644
9729
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
9645
9730
|
});
|
|
9646
9731
|
|
|
9647
9732
|
// src/commands/seq/seqQuery.ts
|
|
9648
|
-
import
|
|
9733
|
+
import chalk118 from "chalk";
|
|
9649
9734
|
|
|
9650
9735
|
// src/commands/seq/fetchSeq.ts
|
|
9651
|
-
import
|
|
9736
|
+
import chalk115 from "chalk";
|
|
9652
9737
|
async function fetchSeq(conn, path50, params) {
|
|
9653
9738
|
const url = `${conn.url}${path50}?${params}`;
|
|
9654
9739
|
const response = await fetch(url, {
|
|
@@ -9659,7 +9744,7 @@ async function fetchSeq(conn, path50, params) {
|
|
|
9659
9744
|
});
|
|
9660
9745
|
if (!response.ok) {
|
|
9661
9746
|
const body = await response.text();
|
|
9662
|
-
console.error(
|
|
9747
|
+
console.error(chalk115.red(`Seq returned ${response.status}: ${body}`));
|
|
9663
9748
|
process.exit(1);
|
|
9664
9749
|
}
|
|
9665
9750
|
return response;
|
|
@@ -9712,23 +9797,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
9712
9797
|
}
|
|
9713
9798
|
|
|
9714
9799
|
// src/commands/seq/formatEvent.ts
|
|
9715
|
-
import
|
|
9800
|
+
import chalk116 from "chalk";
|
|
9716
9801
|
function levelColor(level) {
|
|
9717
9802
|
switch (level) {
|
|
9718
9803
|
case "Fatal":
|
|
9719
|
-
return
|
|
9804
|
+
return chalk116.bgRed.white;
|
|
9720
9805
|
case "Error":
|
|
9721
|
-
return
|
|
9806
|
+
return chalk116.red;
|
|
9722
9807
|
case "Warning":
|
|
9723
|
-
return
|
|
9808
|
+
return chalk116.yellow;
|
|
9724
9809
|
case "Information":
|
|
9725
|
-
return
|
|
9810
|
+
return chalk116.cyan;
|
|
9726
9811
|
case "Debug":
|
|
9727
|
-
return
|
|
9812
|
+
return chalk116.gray;
|
|
9728
9813
|
case "Verbose":
|
|
9729
|
-
return
|
|
9814
|
+
return chalk116.dim;
|
|
9730
9815
|
default:
|
|
9731
|
-
return
|
|
9816
|
+
return chalk116.white;
|
|
9732
9817
|
}
|
|
9733
9818
|
}
|
|
9734
9819
|
function levelAbbrev(level) {
|
|
@@ -9769,31 +9854,31 @@ function formatTimestamp(iso) {
|
|
|
9769
9854
|
function formatEvent(event) {
|
|
9770
9855
|
const color = levelColor(event.Level);
|
|
9771
9856
|
const abbrev = levelAbbrev(event.Level);
|
|
9772
|
-
const ts8 =
|
|
9857
|
+
const ts8 = chalk116.dim(formatTimestamp(event.Timestamp));
|
|
9773
9858
|
const msg = renderMessage(event);
|
|
9774
9859
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
9775
9860
|
if (event.Exception) {
|
|
9776
9861
|
for (const line of event.Exception.split("\n")) {
|
|
9777
|
-
lines.push(
|
|
9862
|
+
lines.push(chalk116.red(` ${line}`));
|
|
9778
9863
|
}
|
|
9779
9864
|
}
|
|
9780
9865
|
return lines.join("\n");
|
|
9781
9866
|
}
|
|
9782
9867
|
|
|
9783
9868
|
// src/commands/seq/resolveConnection.ts
|
|
9784
|
-
import
|
|
9869
|
+
import chalk117 from "chalk";
|
|
9785
9870
|
function resolveConnection2(name) {
|
|
9786
9871
|
const connections = loadConnections2();
|
|
9787
9872
|
if (connections.length === 0) {
|
|
9788
9873
|
console.error(
|
|
9789
|
-
|
|
9874
|
+
chalk117.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
9790
9875
|
);
|
|
9791
9876
|
process.exit(1);
|
|
9792
9877
|
}
|
|
9793
9878
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
9794
9879
|
const connection = connections.find((c) => c.name === target);
|
|
9795
9880
|
if (!connection) {
|
|
9796
|
-
console.error(
|
|
9881
|
+
console.error(chalk117.red(`Seq connection "${target}" not found.`));
|
|
9797
9882
|
process.exit(1);
|
|
9798
9883
|
}
|
|
9799
9884
|
return connection;
|
|
@@ -9808,7 +9893,7 @@ async function seqQuery(filter, options2) {
|
|
|
9808
9893
|
new URLSearchParams({ filter, count: String(count) })
|
|
9809
9894
|
);
|
|
9810
9895
|
if (events.length === 0) {
|
|
9811
|
-
console.log(
|
|
9896
|
+
console.log(chalk118.yellow("No events found."));
|
|
9812
9897
|
return;
|
|
9813
9898
|
}
|
|
9814
9899
|
if (options2.json) {
|
|
@@ -9819,11 +9904,11 @@ async function seqQuery(filter, options2) {
|
|
|
9819
9904
|
for (const event of chronological) {
|
|
9820
9905
|
console.log(formatEvent(event));
|
|
9821
9906
|
}
|
|
9822
|
-
console.log(
|
|
9907
|
+
console.log(chalk118.dim(`
|
|
9823
9908
|
${events.length} events`));
|
|
9824
9909
|
if (events.length >= count) {
|
|
9825
9910
|
console.log(
|
|
9826
|
-
|
|
9911
|
+
chalk118.yellow(
|
|
9827
9912
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
9828
9913
|
)
|
|
9829
9914
|
);
|
|
@@ -9831,11 +9916,11 @@ ${events.length} events`));
|
|
|
9831
9916
|
}
|
|
9832
9917
|
|
|
9833
9918
|
// src/commands/seq/seqSetConnection.ts
|
|
9834
|
-
import
|
|
9919
|
+
import chalk119 from "chalk";
|
|
9835
9920
|
function seqSetConnection(name) {
|
|
9836
9921
|
const connections = loadConnections2();
|
|
9837
9922
|
if (!connections.find((c) => c.name === name)) {
|
|
9838
|
-
console.error(
|
|
9923
|
+
console.error(chalk119.red(`Connection "${name}" not found.`));
|
|
9839
9924
|
process.exit(1);
|
|
9840
9925
|
}
|
|
9841
9926
|
setDefaultConnection(name);
|
|
@@ -9854,8 +9939,8 @@ function registerSeq(program2) {
|
|
|
9854
9939
|
}
|
|
9855
9940
|
|
|
9856
9941
|
// src/commands/transcript/shared.ts
|
|
9857
|
-
import { existsSync as
|
|
9858
|
-
import { basename as basename4, join as
|
|
9942
|
+
import { existsSync as existsSync30, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
9943
|
+
import { basename as basename4, join as join30, relative } from "path";
|
|
9859
9944
|
import * as readline2 from "readline";
|
|
9860
9945
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
9861
9946
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -9870,10 +9955,10 @@ function isValidDatePrefix(filename) {
|
|
|
9870
9955
|
return DATE_PREFIX_REGEX.test(filename);
|
|
9871
9956
|
}
|
|
9872
9957
|
function collectFiles(dir, extension) {
|
|
9873
|
-
if (!
|
|
9958
|
+
if (!existsSync30(dir)) return [];
|
|
9874
9959
|
const results = [];
|
|
9875
9960
|
for (const entry of readdirSync5(dir)) {
|
|
9876
|
-
const fullPath =
|
|
9961
|
+
const fullPath = join30(dir, entry);
|
|
9877
9962
|
if (statSync4(fullPath).isDirectory()) {
|
|
9878
9963
|
results.push(...collectFiles(fullPath, extension));
|
|
9879
9964
|
} else if (entry.endsWith(extension)) {
|
|
@@ -9967,14 +10052,14 @@ async function configure() {
|
|
|
9967
10052
|
}
|
|
9968
10053
|
|
|
9969
10054
|
// src/commands/transcript/format/index.ts
|
|
9970
|
-
import { existsSync as
|
|
10055
|
+
import { existsSync as existsSync32 } from "fs";
|
|
9971
10056
|
|
|
9972
10057
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
9973
|
-
import { dirname as dirname18, join as
|
|
10058
|
+
import { dirname as dirname18, join as join32 } from "path";
|
|
9974
10059
|
|
|
9975
10060
|
// src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
|
|
9976
10061
|
import { renameSync as renameSync2 } from "fs";
|
|
9977
|
-
import { join as
|
|
10062
|
+
import { join as join31 } from "path";
|
|
9978
10063
|
async function resolveDate(rl, choice) {
|
|
9979
10064
|
if (choice === "1") return getDatePrefix(0);
|
|
9980
10065
|
if (choice === "2") return getDatePrefix(-1);
|
|
@@ -9989,7 +10074,7 @@ async function resolveDate(rl, choice) {
|
|
|
9989
10074
|
}
|
|
9990
10075
|
function renameWithPrefix(vttDir, vttFile, prefix2) {
|
|
9991
10076
|
const newFilename = `${prefix2}.${vttFile}`;
|
|
9992
|
-
renameSync2(
|
|
10077
|
+
renameSync2(join31(vttDir, vttFile), join31(vttDir, newFilename));
|
|
9993
10078
|
console.log(`Renamed to: ${newFilename}`);
|
|
9994
10079
|
return newFilename;
|
|
9995
10080
|
}
|
|
@@ -10023,12 +10108,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
10023
10108
|
const vttFileDir = dirname18(vttFile.absolutePath);
|
|
10024
10109
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
10025
10110
|
if (newFilename) {
|
|
10026
|
-
const newRelativePath =
|
|
10111
|
+
const newRelativePath = join32(
|
|
10027
10112
|
dirname18(vttFile.relativePath),
|
|
10028
10113
|
newFilename
|
|
10029
10114
|
);
|
|
10030
10115
|
vttFiles[i] = {
|
|
10031
|
-
absolutePath:
|
|
10116
|
+
absolutePath: join32(vttFileDir, newFilename),
|
|
10032
10117
|
relativePath: newRelativePath,
|
|
10033
10118
|
filename: newFilename
|
|
10034
10119
|
};
|
|
@@ -10041,8 +10126,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
10041
10126
|
}
|
|
10042
10127
|
|
|
10043
10128
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
10044
|
-
import { existsSync as
|
|
10045
|
-
import { basename as basename5, dirname as dirname19, join as
|
|
10129
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync25 } from "fs";
|
|
10130
|
+
import { basename as basename5, dirname as dirname19, join as join33 } from "path";
|
|
10046
10131
|
|
|
10047
10132
|
// src/commands/transcript/cleanText.ts
|
|
10048
10133
|
function cleanText(text) {
|
|
@@ -10252,21 +10337,21 @@ function toMdFilename(vttFilename) {
|
|
|
10252
10337
|
return `${basename5(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
10253
10338
|
}
|
|
10254
10339
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
10255
|
-
return relativeDir === "." ? transcriptsDir :
|
|
10340
|
+
return relativeDir === "." ? transcriptsDir : join33(transcriptsDir, relativeDir);
|
|
10256
10341
|
}
|
|
10257
10342
|
function buildOutputPaths(vttFile, transcriptsDir) {
|
|
10258
10343
|
const mdFile = toMdFilename(vttFile.filename);
|
|
10259
10344
|
const relativeDir = dirname19(vttFile.relativePath);
|
|
10260
10345
|
const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
|
|
10261
|
-
const outputPath =
|
|
10346
|
+
const outputPath = join33(outputDir, mdFile);
|
|
10262
10347
|
return { outputDir, outputPath, mdFile, relativeDir };
|
|
10263
10348
|
}
|
|
10264
10349
|
function logSkipped(relativeDir, mdFile) {
|
|
10265
|
-
console.log(`Skipping (already exists): ${
|
|
10350
|
+
console.log(`Skipping (already exists): ${join33(relativeDir, mdFile)}`);
|
|
10266
10351
|
return "skipped";
|
|
10267
10352
|
}
|
|
10268
10353
|
function ensureDirectory(dir, label2) {
|
|
10269
|
-
if (!
|
|
10354
|
+
if (!existsSync31(dir)) {
|
|
10270
10355
|
mkdirSync8(dir, { recursive: true });
|
|
10271
10356
|
console.log(`Created ${label2}: ${dir}`);
|
|
10272
10357
|
}
|
|
@@ -10289,10 +10374,10 @@ function logReduction(cueCount, messageCount) {
|
|
|
10289
10374
|
}
|
|
10290
10375
|
function readAndParseCues(inputPath) {
|
|
10291
10376
|
console.log(`Reading: ${inputPath}`);
|
|
10292
|
-
return processCues(
|
|
10377
|
+
return processCues(readFileSync27(inputPath, "utf-8"));
|
|
10293
10378
|
}
|
|
10294
10379
|
function writeFormatted(outputPath, content) {
|
|
10295
|
-
|
|
10380
|
+
writeFileSync25(outputPath, content, "utf-8");
|
|
10296
10381
|
console.log(`Written: ${outputPath}`);
|
|
10297
10382
|
}
|
|
10298
10383
|
function convertVttToMarkdown(inputPath, outputPath) {
|
|
@@ -10302,7 +10387,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
|
|
|
10302
10387
|
logReduction(cues.length, chatMessages.length);
|
|
10303
10388
|
}
|
|
10304
10389
|
function tryProcessVtt(vttFile, paths) {
|
|
10305
|
-
if (
|
|
10390
|
+
if (existsSync31(paths.outputPath))
|
|
10306
10391
|
return logSkipped(paths.relativeDir, paths.mdFile);
|
|
10307
10392
|
convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
|
|
10308
10393
|
return "processed";
|
|
@@ -10328,7 +10413,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
|
|
|
10328
10413
|
logSummary(counts);
|
|
10329
10414
|
}
|
|
10330
10415
|
function requireVttDir(vttDir) {
|
|
10331
|
-
if (!
|
|
10416
|
+
if (!existsSync32(vttDir)) {
|
|
10332
10417
|
console.error(`VTT directory not found: ${vttDir}`);
|
|
10333
10418
|
process.exit(1);
|
|
10334
10419
|
}
|
|
@@ -10360,28 +10445,28 @@ async function format() {
|
|
|
10360
10445
|
}
|
|
10361
10446
|
|
|
10362
10447
|
// src/commands/transcript/summarise/index.ts
|
|
10363
|
-
import { existsSync as
|
|
10364
|
-
import { basename as basename6, dirname as dirname21, join as
|
|
10448
|
+
import { existsSync as existsSync34 } from "fs";
|
|
10449
|
+
import { basename as basename6, dirname as dirname21, join as join35, relative as relative2 } from "path";
|
|
10365
10450
|
|
|
10366
10451
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10367
10452
|
import {
|
|
10368
|
-
existsSync as
|
|
10453
|
+
existsSync as existsSync33,
|
|
10369
10454
|
mkdirSync as mkdirSync9,
|
|
10370
|
-
readFileSync as
|
|
10455
|
+
readFileSync as readFileSync28,
|
|
10371
10456
|
renameSync as renameSync3,
|
|
10372
10457
|
rmSync
|
|
10373
10458
|
} from "fs";
|
|
10374
|
-
import { dirname as dirname20, join as
|
|
10459
|
+
import { dirname as dirname20, join as join34 } from "path";
|
|
10375
10460
|
|
|
10376
10461
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
10377
|
-
import
|
|
10462
|
+
import chalk120 from "chalk";
|
|
10378
10463
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
10379
10464
|
function validateStagedContent(filename, content) {
|
|
10380
10465
|
const firstLine = content.split("\n")[0];
|
|
10381
10466
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
10382
10467
|
if (!match) {
|
|
10383
10468
|
console.error(
|
|
10384
|
-
|
|
10469
|
+
chalk120.red(
|
|
10385
10470
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
10386
10471
|
)
|
|
10387
10472
|
);
|
|
@@ -10390,7 +10475,7 @@ function validateStagedContent(filename, content) {
|
|
|
10390
10475
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
10391
10476
|
if (!contentAfterLink) {
|
|
10392
10477
|
console.error(
|
|
10393
|
-
|
|
10478
|
+
chalk120.red(
|
|
10394
10479
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
10395
10480
|
)
|
|
10396
10481
|
);
|
|
@@ -10400,9 +10485,9 @@ function validateStagedContent(filename, content) {
|
|
|
10400
10485
|
}
|
|
10401
10486
|
|
|
10402
10487
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10403
|
-
var STAGING_DIR =
|
|
10488
|
+
var STAGING_DIR = join34(process.cwd(), ".assist", "transcript");
|
|
10404
10489
|
function processStagedFile() {
|
|
10405
|
-
if (!
|
|
10490
|
+
if (!existsSync33(STAGING_DIR)) {
|
|
10406
10491
|
return false;
|
|
10407
10492
|
}
|
|
10408
10493
|
const stagedFiles = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -10411,7 +10496,7 @@ function processStagedFile() {
|
|
|
10411
10496
|
}
|
|
10412
10497
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
10413
10498
|
const stagedFile = stagedFiles[0];
|
|
10414
|
-
const content =
|
|
10499
|
+
const content = readFileSync28(stagedFile.absolutePath, "utf-8");
|
|
10415
10500
|
validateStagedContent(stagedFile.filename, content);
|
|
10416
10501
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
10417
10502
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -10424,9 +10509,9 @@ function processStagedFile() {
|
|
|
10424
10509
|
);
|
|
10425
10510
|
process.exit(1);
|
|
10426
10511
|
}
|
|
10427
|
-
const destPath =
|
|
10512
|
+
const destPath = join34(summaryDir, matchingTranscript.relativePath);
|
|
10428
10513
|
const destDir = dirname20(destPath);
|
|
10429
|
-
if (!
|
|
10514
|
+
if (!existsSync33(destDir)) {
|
|
10430
10515
|
mkdirSync9(destDir, { recursive: true });
|
|
10431
10516
|
}
|
|
10432
10517
|
renameSync3(stagedFile.absolutePath, destPath);
|
|
@@ -10440,7 +10525,7 @@ function processStagedFile() {
|
|
|
10440
10525
|
// src/commands/transcript/summarise/index.ts
|
|
10441
10526
|
function buildRelativeKey(relativePath, baseName) {
|
|
10442
10527
|
const relDir = dirname21(relativePath);
|
|
10443
|
-
return relDir === "." ? baseName :
|
|
10528
|
+
return relDir === "." ? baseName : join35(relDir, baseName);
|
|
10444
10529
|
}
|
|
10445
10530
|
function buildSummaryIndex(summaryDir) {
|
|
10446
10531
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
@@ -10453,7 +10538,7 @@ function buildSummaryIndex(summaryDir) {
|
|
|
10453
10538
|
function summarise2() {
|
|
10454
10539
|
processStagedFile();
|
|
10455
10540
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
10456
|
-
if (!
|
|
10541
|
+
if (!existsSync34(transcriptsDir)) {
|
|
10457
10542
|
console.log("No transcripts directory found.");
|
|
10458
10543
|
return;
|
|
10459
10544
|
}
|
|
@@ -10474,8 +10559,8 @@ function summarise2() {
|
|
|
10474
10559
|
}
|
|
10475
10560
|
const next3 = missing[0];
|
|
10476
10561
|
const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
|
|
10477
|
-
const outputPath =
|
|
10478
|
-
const summaryFileDir =
|
|
10562
|
+
const outputPath = join35(STAGING_DIR, outputFilename);
|
|
10563
|
+
const summaryFileDir = join35(summaryDir, dirname21(next3.relativePath));
|
|
10479
10564
|
const relativeTranscriptPath = encodeURI(
|
|
10480
10565
|
relative2(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
|
|
10481
10566
|
);
|
|
@@ -10521,50 +10606,50 @@ function registerVerify(program2) {
|
|
|
10521
10606
|
|
|
10522
10607
|
// src/commands/voice/devices.ts
|
|
10523
10608
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
10524
|
-
import { join as
|
|
10609
|
+
import { join as join37 } from "path";
|
|
10525
10610
|
|
|
10526
10611
|
// src/commands/voice/shared.ts
|
|
10527
10612
|
import { homedir as homedir7 } from "os";
|
|
10528
|
-
import { dirname as dirname22, join as
|
|
10613
|
+
import { dirname as dirname22, join as join36 } from "path";
|
|
10529
10614
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
10530
10615
|
var __dirname6 = dirname22(fileURLToPath6(import.meta.url));
|
|
10531
|
-
var VOICE_DIR =
|
|
10616
|
+
var VOICE_DIR = join36(homedir7(), ".assist", "voice");
|
|
10532
10617
|
var voicePaths = {
|
|
10533
10618
|
dir: VOICE_DIR,
|
|
10534
|
-
pid:
|
|
10535
|
-
log:
|
|
10536
|
-
venv:
|
|
10537
|
-
lock:
|
|
10619
|
+
pid: join36(VOICE_DIR, "voice.pid"),
|
|
10620
|
+
log: join36(VOICE_DIR, "voice.log"),
|
|
10621
|
+
venv: join36(VOICE_DIR, ".venv"),
|
|
10622
|
+
lock: join36(VOICE_DIR, "voice.lock")
|
|
10538
10623
|
};
|
|
10539
10624
|
function getPythonDir() {
|
|
10540
|
-
return
|
|
10625
|
+
return join36(__dirname6, "commands", "voice", "python");
|
|
10541
10626
|
}
|
|
10542
10627
|
function getVenvPython() {
|
|
10543
|
-
return process.platform === "win32" ?
|
|
10628
|
+
return process.platform === "win32" ? join36(voicePaths.venv, "Scripts", "python.exe") : join36(voicePaths.venv, "bin", "python");
|
|
10544
10629
|
}
|
|
10545
10630
|
function getLockDir() {
|
|
10546
10631
|
const config = loadConfig();
|
|
10547
10632
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
10548
10633
|
}
|
|
10549
10634
|
function getLockFile() {
|
|
10550
|
-
return
|
|
10635
|
+
return join36(getLockDir(), "voice.lock");
|
|
10551
10636
|
}
|
|
10552
10637
|
|
|
10553
10638
|
// src/commands/voice/devices.ts
|
|
10554
10639
|
function devices() {
|
|
10555
|
-
const script =
|
|
10640
|
+
const script = join37(getPythonDir(), "list_devices.py");
|
|
10556
10641
|
spawnSync3(getVenvPython(), [script], { stdio: "inherit" });
|
|
10557
10642
|
}
|
|
10558
10643
|
|
|
10559
10644
|
// src/commands/voice/logs.ts
|
|
10560
|
-
import { existsSync as
|
|
10645
|
+
import { existsSync as existsSync35, readFileSync as readFileSync29 } from "fs";
|
|
10561
10646
|
function logs(options2) {
|
|
10562
|
-
if (!
|
|
10647
|
+
if (!existsSync35(voicePaths.log)) {
|
|
10563
10648
|
console.log("No voice log file found");
|
|
10564
10649
|
return;
|
|
10565
10650
|
}
|
|
10566
10651
|
const count = Number.parseInt(options2.lines ?? "150", 10);
|
|
10567
|
-
const content =
|
|
10652
|
+
const content = readFileSync29(voicePaths.log, "utf-8").trim();
|
|
10568
10653
|
if (!content) {
|
|
10569
10654
|
console.log("Voice log is empty");
|
|
10570
10655
|
return;
|
|
@@ -10587,12 +10672,12 @@ function logs(options2) {
|
|
|
10587
10672
|
// src/commands/voice/setup.ts
|
|
10588
10673
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
10589
10674
|
import { mkdirSync as mkdirSync11 } from "fs";
|
|
10590
|
-
import { join as
|
|
10675
|
+
import { join as join39 } from "path";
|
|
10591
10676
|
|
|
10592
10677
|
// src/commands/voice/checkLockFile.ts
|
|
10593
10678
|
import { execSync as execSync37 } from "child_process";
|
|
10594
|
-
import { existsSync as
|
|
10595
|
-
import { join as
|
|
10679
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync30, writeFileSync as writeFileSync26 } from "fs";
|
|
10680
|
+
import { join as join38 } from "path";
|
|
10596
10681
|
function isProcessAlive2(pid) {
|
|
10597
10682
|
try {
|
|
10598
10683
|
process.kill(pid, 0);
|
|
@@ -10603,9 +10688,9 @@ function isProcessAlive2(pid) {
|
|
|
10603
10688
|
}
|
|
10604
10689
|
function checkLockFile() {
|
|
10605
10690
|
const lockFile = getLockFile();
|
|
10606
|
-
if (!
|
|
10691
|
+
if (!existsSync36(lockFile)) return;
|
|
10607
10692
|
try {
|
|
10608
|
-
const lock = JSON.parse(
|
|
10693
|
+
const lock = JSON.parse(readFileSync30(lockFile, "utf-8"));
|
|
10609
10694
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
10610
10695
|
console.error(
|
|
10611
10696
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -10616,7 +10701,7 @@ function checkLockFile() {
|
|
|
10616
10701
|
}
|
|
10617
10702
|
}
|
|
10618
10703
|
function bootstrapVenv() {
|
|
10619
|
-
if (
|
|
10704
|
+
if (existsSync36(getVenvPython())) return;
|
|
10620
10705
|
console.log("Setting up Python environment...");
|
|
10621
10706
|
const pythonDir = getPythonDir();
|
|
10622
10707
|
execSync37(
|
|
@@ -10629,8 +10714,8 @@ function bootstrapVenv() {
|
|
|
10629
10714
|
}
|
|
10630
10715
|
function writeLockFile(pid) {
|
|
10631
10716
|
const lockFile = getLockFile();
|
|
10632
|
-
mkdirSync10(
|
|
10633
|
-
|
|
10717
|
+
mkdirSync10(join38(lockFile, ".."), { recursive: true });
|
|
10718
|
+
writeFileSync26(
|
|
10634
10719
|
lockFile,
|
|
10635
10720
|
JSON.stringify({
|
|
10636
10721
|
pid,
|
|
@@ -10645,7 +10730,7 @@ function setup() {
|
|
|
10645
10730
|
mkdirSync11(voicePaths.dir, { recursive: true });
|
|
10646
10731
|
bootstrapVenv();
|
|
10647
10732
|
console.log("\nDownloading models...\n");
|
|
10648
|
-
const script =
|
|
10733
|
+
const script = join39(getPythonDir(), "setup_models.py");
|
|
10649
10734
|
const result = spawnSync4(getVenvPython(), [script], {
|
|
10650
10735
|
stdio: "inherit",
|
|
10651
10736
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -10658,8 +10743,8 @@ function setup() {
|
|
|
10658
10743
|
|
|
10659
10744
|
// src/commands/voice/start.ts
|
|
10660
10745
|
import { spawn as spawn5 } from "child_process";
|
|
10661
|
-
import { mkdirSync as mkdirSync12, writeFileSync as
|
|
10662
|
-
import { join as
|
|
10746
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync27 } from "fs";
|
|
10747
|
+
import { join as join40 } from "path";
|
|
10663
10748
|
|
|
10664
10749
|
// src/commands/voice/buildDaemonEnv.ts
|
|
10665
10750
|
function buildDaemonEnv(options2) {
|
|
@@ -10687,7 +10772,7 @@ function spawnBackground(python, script, env) {
|
|
|
10687
10772
|
console.error("Failed to start voice daemon");
|
|
10688
10773
|
process.exit(1);
|
|
10689
10774
|
}
|
|
10690
|
-
|
|
10775
|
+
writeFileSync27(voicePaths.pid, String(pid));
|
|
10691
10776
|
writeLockFile(pid);
|
|
10692
10777
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
10693
10778
|
}
|
|
@@ -10697,7 +10782,7 @@ function start2(options2) {
|
|
|
10697
10782
|
bootstrapVenv();
|
|
10698
10783
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
10699
10784
|
const env = buildDaemonEnv({ debug });
|
|
10700
|
-
const script =
|
|
10785
|
+
const script = join40(getPythonDir(), "voice_daemon.py");
|
|
10701
10786
|
const python = getVenvPython();
|
|
10702
10787
|
if (options2.foreground) {
|
|
10703
10788
|
spawnForeground(python, script, env);
|
|
@@ -10707,7 +10792,7 @@ function start2(options2) {
|
|
|
10707
10792
|
}
|
|
10708
10793
|
|
|
10709
10794
|
// src/commands/voice/status.ts
|
|
10710
|
-
import { existsSync as
|
|
10795
|
+
import { existsSync as existsSync37, readFileSync as readFileSync31 } from "fs";
|
|
10711
10796
|
function isProcessAlive3(pid) {
|
|
10712
10797
|
try {
|
|
10713
10798
|
process.kill(pid, 0);
|
|
@@ -10717,16 +10802,16 @@ function isProcessAlive3(pid) {
|
|
|
10717
10802
|
}
|
|
10718
10803
|
}
|
|
10719
10804
|
function readRecentLogs(count) {
|
|
10720
|
-
if (!
|
|
10721
|
-
const lines =
|
|
10805
|
+
if (!existsSync37(voicePaths.log)) return [];
|
|
10806
|
+
const lines = readFileSync31(voicePaths.log, "utf-8").trim().split("\n");
|
|
10722
10807
|
return lines.slice(-count);
|
|
10723
10808
|
}
|
|
10724
10809
|
function status() {
|
|
10725
|
-
if (!
|
|
10810
|
+
if (!existsSync37(voicePaths.pid)) {
|
|
10726
10811
|
console.log("Voice daemon: not running (no PID file)");
|
|
10727
10812
|
return;
|
|
10728
10813
|
}
|
|
10729
|
-
const pid = Number.parseInt(
|
|
10814
|
+
const pid = Number.parseInt(readFileSync31(voicePaths.pid, "utf-8").trim(), 10);
|
|
10730
10815
|
const alive = isProcessAlive3(pid);
|
|
10731
10816
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
10732
10817
|
const recent = readRecentLogs(5);
|
|
@@ -10745,13 +10830,13 @@ function status() {
|
|
|
10745
10830
|
}
|
|
10746
10831
|
|
|
10747
10832
|
// src/commands/voice/stop.ts
|
|
10748
|
-
import { existsSync as
|
|
10833
|
+
import { existsSync as existsSync38, readFileSync as readFileSync32, unlinkSync as unlinkSync10 } from "fs";
|
|
10749
10834
|
function stop() {
|
|
10750
|
-
if (!
|
|
10835
|
+
if (!existsSync38(voicePaths.pid)) {
|
|
10751
10836
|
console.log("Voice daemon is not running (no PID file)");
|
|
10752
10837
|
return;
|
|
10753
10838
|
}
|
|
10754
|
-
const pid = Number.parseInt(
|
|
10839
|
+
const pid = Number.parseInt(readFileSync32(voicePaths.pid, "utf-8").trim(), 10);
|
|
10755
10840
|
try {
|
|
10756
10841
|
process.kill(pid, "SIGTERM");
|
|
10757
10842
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -10764,7 +10849,7 @@ function stop() {
|
|
|
10764
10849
|
}
|
|
10765
10850
|
try {
|
|
10766
10851
|
const lockFile = getLockFile();
|
|
10767
|
-
if (
|
|
10852
|
+
if (existsSync38(lockFile)) unlinkSync10(lockFile);
|
|
10768
10853
|
} catch {
|
|
10769
10854
|
}
|
|
10770
10855
|
console.log("Voice daemon stopped");
|
|
@@ -10783,7 +10868,7 @@ function registerVoice(program2) {
|
|
|
10783
10868
|
|
|
10784
10869
|
// src/commands/roam/auth.ts
|
|
10785
10870
|
import { randomBytes } from "crypto";
|
|
10786
|
-
import
|
|
10871
|
+
import chalk121 from "chalk";
|
|
10787
10872
|
|
|
10788
10873
|
// src/lib/openBrowser.ts
|
|
10789
10874
|
import { execSync as execSync38 } from "child_process";
|
|
@@ -10958,13 +11043,13 @@ async function auth() {
|
|
|
10958
11043
|
saveGlobalConfig(config);
|
|
10959
11044
|
const state = randomBytes(16).toString("hex");
|
|
10960
11045
|
console.log(
|
|
10961
|
-
|
|
11046
|
+
chalk121.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
10962
11047
|
);
|
|
10963
|
-
console.log(
|
|
10964
|
-
console.log(
|
|
10965
|
-
console.log(
|
|
11048
|
+
console.log(chalk121.white("http://localhost:14523/callback\n"));
|
|
11049
|
+
console.log(chalk121.blue("Opening browser for authorization..."));
|
|
11050
|
+
console.log(chalk121.dim("Waiting for authorization callback..."));
|
|
10966
11051
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
10967
|
-
console.log(
|
|
11052
|
+
console.log(chalk121.dim("Exchanging code for tokens..."));
|
|
10968
11053
|
const tokens = await exchangeToken({
|
|
10969
11054
|
code,
|
|
10970
11055
|
clientId,
|
|
@@ -10980,20 +11065,20 @@ async function auth() {
|
|
|
10980
11065
|
};
|
|
10981
11066
|
saveGlobalConfig(config);
|
|
10982
11067
|
console.log(
|
|
10983
|
-
|
|
11068
|
+
chalk121.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
10984
11069
|
);
|
|
10985
11070
|
}
|
|
10986
11071
|
|
|
10987
11072
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
10988
|
-
import { readFileSync as
|
|
10989
|
-
import { join as
|
|
11073
|
+
import { readFileSync as readFileSync33 } from "fs";
|
|
11074
|
+
import { join as join41 } from "path";
|
|
10990
11075
|
async function showClaudeCodeIcon() {
|
|
10991
11076
|
const appData = process.env.APPDATA;
|
|
10992
11077
|
if (!appData) return;
|
|
10993
|
-
const portFile =
|
|
11078
|
+
const portFile = join41(appData, "Roam", "roam-local-api.port");
|
|
10994
11079
|
let port;
|
|
10995
11080
|
try {
|
|
10996
|
-
port =
|
|
11081
|
+
port = readFileSync33(portFile, "utf-8").trim();
|
|
10997
11082
|
} catch {
|
|
10998
11083
|
return;
|
|
10999
11084
|
}
|
|
@@ -11064,8 +11149,8 @@ Done in ${elapsed}`);
|
|
|
11064
11149
|
}
|
|
11065
11150
|
|
|
11066
11151
|
// src/commands/run/add.ts
|
|
11067
|
-
import { mkdirSync as mkdirSync13, writeFileSync as
|
|
11068
|
-
import { join as
|
|
11152
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync28 } from "fs";
|
|
11153
|
+
import { join as join42 } from "path";
|
|
11069
11154
|
function findAddIndex() {
|
|
11070
11155
|
const addIndex = process.argv.indexOf("add");
|
|
11071
11156
|
if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
|
|
@@ -11111,7 +11196,7 @@ function saveNewRunConfig(name, command, args) {
|
|
|
11111
11196
|
saveConfig(config);
|
|
11112
11197
|
}
|
|
11113
11198
|
function createCommandFile(name) {
|
|
11114
|
-
const dir =
|
|
11199
|
+
const dir = join42(".claude", "commands");
|
|
11115
11200
|
mkdirSync13(dir, { recursive: true });
|
|
11116
11201
|
const content = `---
|
|
11117
11202
|
description: Run ${name}
|
|
@@ -11119,8 +11204,8 @@ description: Run ${name}
|
|
|
11119
11204
|
|
|
11120
11205
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
11121
11206
|
`;
|
|
11122
|
-
const filePath =
|
|
11123
|
-
|
|
11207
|
+
const filePath = join42(dir, `${name}.md`);
|
|
11208
|
+
writeFileSync28(filePath, content);
|
|
11124
11209
|
console.log(`Created command file: ${filePath}`);
|
|
11125
11210
|
}
|
|
11126
11211
|
function add3() {
|
|
@@ -11190,10 +11275,10 @@ function run3(name, args) {
|
|
|
11190
11275
|
|
|
11191
11276
|
// src/commands/screenshot/index.ts
|
|
11192
11277
|
import { execSync as execSync40 } from "child_process";
|
|
11193
|
-
import { existsSync as
|
|
11278
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync29 } from "fs";
|
|
11194
11279
|
import { tmpdir as tmpdir6 } from "os";
|
|
11195
|
-
import { join as
|
|
11196
|
-
import
|
|
11280
|
+
import { join as join43, resolve as resolve5 } from "path";
|
|
11281
|
+
import chalk122 from "chalk";
|
|
11197
11282
|
|
|
11198
11283
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
11199
11284
|
var captureWindowPs1 = `
|
|
@@ -11322,15 +11407,15 @@ Write-Output $OutputPath
|
|
|
11322
11407
|
|
|
11323
11408
|
// src/commands/screenshot/index.ts
|
|
11324
11409
|
function buildOutputPath(outputDir, processName) {
|
|
11325
|
-
if (!
|
|
11410
|
+
if (!existsSync39(outputDir)) {
|
|
11326
11411
|
mkdirSync14(outputDir, { recursive: true });
|
|
11327
11412
|
}
|
|
11328
11413
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11329
11414
|
return resolve5(outputDir, `${processName}-${timestamp}.png`);
|
|
11330
11415
|
}
|
|
11331
11416
|
function runPowerShellScript(processName, outputPath) {
|
|
11332
|
-
const scriptPath =
|
|
11333
|
-
|
|
11417
|
+
const scriptPath = join43(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
|
|
11418
|
+
writeFileSync29(scriptPath, captureWindowPs1, "utf-8");
|
|
11334
11419
|
try {
|
|
11335
11420
|
execSync40(
|
|
11336
11421
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
@@ -11344,22 +11429,22 @@ function screenshot(processName) {
|
|
|
11344
11429
|
const config = loadConfig();
|
|
11345
11430
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
11346
11431
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
11347
|
-
console.log(
|
|
11432
|
+
console.log(chalk122.gray(`Capturing window for process "${processName}" ...`));
|
|
11348
11433
|
try {
|
|
11349
11434
|
runPowerShellScript(processName, outputPath);
|
|
11350
|
-
console.log(
|
|
11435
|
+
console.log(chalk122.green(`Screenshot saved: ${outputPath}`));
|
|
11351
11436
|
} catch (error) {
|
|
11352
11437
|
const msg = error instanceof Error ? error.message : String(error);
|
|
11353
|
-
console.error(
|
|
11438
|
+
console.error(chalk122.red(`Failed to capture screenshot: ${msg}`));
|
|
11354
11439
|
process.exit(1);
|
|
11355
11440
|
}
|
|
11356
11441
|
}
|
|
11357
11442
|
|
|
11358
11443
|
// src/commands/statusLine.ts
|
|
11359
|
-
import
|
|
11444
|
+
import chalk124 from "chalk";
|
|
11360
11445
|
|
|
11361
11446
|
// src/commands/buildLimitsSegment.ts
|
|
11362
|
-
import
|
|
11447
|
+
import chalk123 from "chalk";
|
|
11363
11448
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
11364
11449
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
11365
11450
|
function formatTimeLeft(resetsAt) {
|
|
@@ -11382,10 +11467,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
11382
11467
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
11383
11468
|
const label2 = `${Math.round(pct)}%`;
|
|
11384
11469
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
11385
|
-
if (projected == null) return
|
|
11386
|
-
if (projected > 100) return
|
|
11387
|
-
if (projected > 75) return
|
|
11388
|
-
return
|
|
11470
|
+
if (projected == null) return chalk123.green(label2);
|
|
11471
|
+
if (projected > 100) return chalk123.red(label2);
|
|
11472
|
+
if (projected > 75) return chalk123.yellow(label2);
|
|
11473
|
+
return chalk123.green(label2);
|
|
11389
11474
|
}
|
|
11390
11475
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
11391
11476
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -11411,14 +11496,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
11411
11496
|
}
|
|
11412
11497
|
|
|
11413
11498
|
// src/commands/statusLine.ts
|
|
11414
|
-
|
|
11499
|
+
chalk124.level = 3;
|
|
11415
11500
|
function formatNumber(num) {
|
|
11416
11501
|
return num.toLocaleString("en-US");
|
|
11417
11502
|
}
|
|
11418
11503
|
function colorizePercent(pct) {
|
|
11419
11504
|
const label2 = `${Math.round(pct)}%`;
|
|
11420
|
-
if (pct > 80) return
|
|
11421
|
-
if (pct > 40) return
|
|
11505
|
+
if (pct > 80) return chalk124.red(label2);
|
|
11506
|
+
if (pct > 40) return chalk124.yellow(label2);
|
|
11422
11507
|
return label2;
|
|
11423
11508
|
}
|
|
11424
11509
|
async function statusLine() {
|
|
@@ -11441,7 +11526,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
11441
11526
|
// src/commands/sync/syncClaudeMd.ts
|
|
11442
11527
|
import * as fs23 from "fs";
|
|
11443
11528
|
import * as path46 from "path";
|
|
11444
|
-
import
|
|
11529
|
+
import chalk125 from "chalk";
|
|
11445
11530
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
11446
11531
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
11447
11532
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -11450,12 +11535,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
11450
11535
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
11451
11536
|
if (sourceContent !== targetContent) {
|
|
11452
11537
|
console.log(
|
|
11453
|
-
|
|
11538
|
+
chalk125.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
11454
11539
|
);
|
|
11455
11540
|
console.log();
|
|
11456
11541
|
printDiff(targetContent, sourceContent);
|
|
11457
11542
|
const confirm = options2?.yes || await promptConfirm(
|
|
11458
|
-
|
|
11543
|
+
chalk125.red("Overwrite existing CLAUDE.md?"),
|
|
11459
11544
|
false
|
|
11460
11545
|
);
|
|
11461
11546
|
if (!confirm) {
|
|
@@ -11471,7 +11556,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
11471
11556
|
// src/commands/sync/syncSettings.ts
|
|
11472
11557
|
import * as fs24 from "fs";
|
|
11473
11558
|
import * as path47 from "path";
|
|
11474
|
-
import
|
|
11559
|
+
import chalk126 from "chalk";
|
|
11475
11560
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
11476
11561
|
const source = path47.join(claudeDir, "settings.json");
|
|
11477
11562
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -11487,14 +11572,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
11487
11572
|
if (mergedContent !== normalizedTarget) {
|
|
11488
11573
|
if (!options2?.yes) {
|
|
11489
11574
|
console.log(
|
|
11490
|
-
|
|
11575
|
+
chalk126.yellow(
|
|
11491
11576
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
11492
11577
|
)
|
|
11493
11578
|
);
|
|
11494
11579
|
console.log();
|
|
11495
11580
|
printDiff(targetContent, mergedContent);
|
|
11496
11581
|
const confirm = await promptConfirm(
|
|
11497
|
-
|
|
11582
|
+
chalk126.red("Overwrite existing settings.json?"),
|
|
11498
11583
|
false
|
|
11499
11584
|
);
|
|
11500
11585
|
if (!confirm) {
|