@staff0rd/assist 0.182.0 → 0.184.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/allowed.cli-writes +1 -0
- package/dist/allowed.cli-writes +1 -0
- package/dist/commands/backlog/web/bundle.js +6 -6
- package/dist/index.js +522 -378
- 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.184.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -136,10 +136,11 @@ import { join } from "path";
|
|
|
136
136
|
// src/commands/backlog/loadComments.ts
|
|
137
137
|
function loadComments(db, itemId) {
|
|
138
138
|
const rows = db.prepare(
|
|
139
|
-
"SELECT text, phase, timestamp, type FROM comments WHERE item_id = ? ORDER BY idx"
|
|
139
|
+
"SELECT id, text, phase, timestamp, type FROM comments WHERE item_id = ? ORDER BY idx"
|
|
140
140
|
).all(itemId);
|
|
141
141
|
return rows.map((r) => {
|
|
142
142
|
const c = {
|
|
143
|
+
id: r.id,
|
|
143
144
|
text: r.text,
|
|
144
145
|
timestamp: r.timestamp,
|
|
145
146
|
type: r.type
|
|
@@ -220,12 +221,27 @@ import { readFileSync, statSync as statSync2 } from "fs";
|
|
|
220
221
|
// src/commands/backlog/insertItemRelations.ts
|
|
221
222
|
function insertComments(db, item) {
|
|
222
223
|
if (!item.comments) return;
|
|
223
|
-
const
|
|
224
|
+
const stmtWithId = db.prepare(
|
|
225
|
+
"INSERT INTO comments (id, item_id, idx, text, phase, timestamp, type) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
|
226
|
+
);
|
|
227
|
+
const stmtNoId = db.prepare(
|
|
224
228
|
"INSERT INTO comments (item_id, idx, text, phase, timestamp, type) VALUES (?, ?, ?, ?, ?, ?)"
|
|
225
229
|
);
|
|
226
230
|
for (let i = 0; i < item.comments.length; i++) {
|
|
227
231
|
const c = item.comments[i];
|
|
228
|
-
|
|
232
|
+
if (c.id !== void 0) {
|
|
233
|
+
stmtWithId.run(
|
|
234
|
+
c.id,
|
|
235
|
+
item.id,
|
|
236
|
+
i,
|
|
237
|
+
c.text,
|
|
238
|
+
c.phase ?? null,
|
|
239
|
+
c.timestamp,
|
|
240
|
+
c.type
|
|
241
|
+
);
|
|
242
|
+
} else {
|
|
243
|
+
stmtNoId.run(item.id, i, c.text, c.phase ?? null, c.timestamp, c.type);
|
|
244
|
+
}
|
|
229
245
|
}
|
|
230
246
|
}
|
|
231
247
|
function insertLinks(db, item) {
|
|
@@ -320,6 +336,7 @@ var planPhaseSchema = z.strictObject({
|
|
|
320
336
|
});
|
|
321
337
|
var backlogCommentTypeSchema = z.enum(["comment", "summary"]);
|
|
322
338
|
var backlogCommentSchema = z.strictObject({
|
|
339
|
+
id: z.number().optional(),
|
|
323
340
|
text: z.string(),
|
|
324
341
|
phase: z.number().optional(),
|
|
325
342
|
timestamp: z.string(),
|
|
@@ -427,6 +444,25 @@ var _db;
|
|
|
427
444
|
function getDbPath(dir) {
|
|
428
445
|
return join3(dir, ".assist", "backlog.db");
|
|
429
446
|
}
|
|
447
|
+
function migrateCommentsAddId(db) {
|
|
448
|
+
const cols = db.pragma("table_info(comments)");
|
|
449
|
+
if (cols.length === 0 || cols.some((c) => c.name === "id")) return;
|
|
450
|
+
db.exec(`
|
|
451
|
+
CREATE TABLE comments_new (
|
|
452
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
453
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
454
|
+
idx INTEGER NOT NULL,
|
|
455
|
+
text TEXT NOT NULL,
|
|
456
|
+
phase INTEGER,
|
|
457
|
+
timestamp TEXT NOT NULL,
|
|
458
|
+
type TEXT NOT NULL DEFAULT 'comment'
|
|
459
|
+
);
|
|
460
|
+
INSERT INTO comments_new (item_id, idx, text, phase, timestamp, type)
|
|
461
|
+
SELECT item_id, idx, text, phase, timestamp, type FROM comments;
|
|
462
|
+
DROP TABLE comments;
|
|
463
|
+
ALTER TABLE comments_new RENAME TO comments;
|
|
464
|
+
`);
|
|
465
|
+
}
|
|
430
466
|
function initSchema(db) {
|
|
431
467
|
db.exec(`
|
|
432
468
|
CREATE TABLE IF NOT EXISTS items (
|
|
@@ -440,13 +476,13 @@ function initSchema(db) {
|
|
|
440
476
|
);
|
|
441
477
|
|
|
442
478
|
CREATE TABLE IF NOT EXISTS comments (
|
|
479
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
443
480
|
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
444
481
|
idx INTEGER NOT NULL,
|
|
445
482
|
text TEXT NOT NULL,
|
|
446
483
|
phase INTEGER,
|
|
447
484
|
timestamp TEXT NOT NULL,
|
|
448
|
-
type TEXT NOT NULL DEFAULT 'comment'
|
|
449
|
-
PRIMARY KEY (item_id, idx)
|
|
485
|
+
type TEXT NOT NULL DEFAULT 'comment'
|
|
450
486
|
);
|
|
451
487
|
|
|
452
488
|
CREATE TABLE IF NOT EXISTS links (
|
|
@@ -487,6 +523,7 @@ function openDb(dir) {
|
|
|
487
523
|
db.pragma("journal_mode = WAL");
|
|
488
524
|
db.pragma("foreign_keys = ON");
|
|
489
525
|
initSchema(db);
|
|
526
|
+
migrateCommentsAddId(db);
|
|
490
527
|
ensureGitignore(dir);
|
|
491
528
|
_db = db;
|
|
492
529
|
return db;
|
|
@@ -727,9 +764,10 @@ function buildCommentLines(comments2) {
|
|
|
727
764
|
return ["", "Comments:", ...comments2.map(formatPromptComment)];
|
|
728
765
|
}
|
|
729
766
|
function formatPromptComment(entry) {
|
|
767
|
+
const id = entry.id !== void 0 ? `#${entry.id} ` : "";
|
|
730
768
|
const tag = entry.type === "summary" ? "[summary]" : "[comment]";
|
|
731
769
|
const phase = entry.phase !== void 0 ? ` (phase ${entry.phase + 1})` : "";
|
|
732
|
-
return `${tag}${phase} ${entry.timestamp}
|
|
770
|
+
return `${id}${tag}${phase} ${entry.timestamp}
|
|
733
771
|
${entry.text}`;
|
|
734
772
|
}
|
|
735
773
|
|
|
@@ -837,7 +875,7 @@ function buildReviewPhase() {
|
|
|
837
875
|
import chalk5 from "chalk";
|
|
838
876
|
|
|
839
877
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
840
|
-
import { existsSync as
|
|
878
|
+
import { existsSync as existsSync6, unlinkSync as unlinkSync2 } from "fs";
|
|
841
879
|
import chalk4 from "chalk";
|
|
842
880
|
|
|
843
881
|
// src/commands/backlog/handleIncompletePhase.ts
|
|
@@ -856,6 +894,9 @@ async function handleIncompletePhase() {
|
|
|
856
894
|
return "abort";
|
|
857
895
|
}
|
|
858
896
|
|
|
897
|
+
// src/commands/backlog/readSignal.ts
|
|
898
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
899
|
+
|
|
859
900
|
// src/commands/backlog/writeSignal.ts
|
|
860
901
|
import { writeFileSync as writeFileSync4 } from "fs";
|
|
861
902
|
import { join as join6 } from "path";
|
|
@@ -870,10 +911,21 @@ function writeSignal(event, data) {
|
|
|
870
911
|
writeFileSync4(getSignalPath(), JSON.stringify(signal));
|
|
871
912
|
}
|
|
872
913
|
|
|
914
|
+
// src/commands/backlog/readSignal.ts
|
|
915
|
+
function readSignal() {
|
|
916
|
+
const path50 = getSignalPath();
|
|
917
|
+
if (!existsSync5(path50)) return void 0;
|
|
918
|
+
try {
|
|
919
|
+
return JSON.parse(readFileSync5(path50, "utf-8"));
|
|
920
|
+
} catch {
|
|
921
|
+
return void 0;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
873
925
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
874
926
|
function cleanupSignal() {
|
|
875
927
|
const statusPath = getSignalPath();
|
|
876
|
-
if (
|
|
928
|
+
if (existsSync6(statusPath)) {
|
|
877
929
|
unlinkSync2(statusPath);
|
|
878
930
|
}
|
|
879
931
|
}
|
|
@@ -883,16 +935,23 @@ function isTerminalStatus(itemId) {
|
|
|
883
935
|
return item?.status === "done" || item?.status === "wontdo";
|
|
884
936
|
}
|
|
885
937
|
async function resolvePhaseResult(phaseIndex, itemId) {
|
|
886
|
-
if (!
|
|
938
|
+
if (!existsSync6(getSignalPath())) {
|
|
887
939
|
if (isTerminalStatus(itemId)) return -1;
|
|
888
940
|
const action = await handleIncompletePhase();
|
|
889
941
|
if (action === "abort") return -1;
|
|
890
|
-
return action === "skip" ? 1 :
|
|
942
|
+
return action === "skip" ? phaseIndex + 1 : phaseIndex;
|
|
891
943
|
}
|
|
944
|
+
const signal = readSignal();
|
|
892
945
|
cleanupSignal();
|
|
946
|
+
if (signal?.event === "rewind") {
|
|
947
|
+
const targetPhase = signal.targetPhase;
|
|
948
|
+
console.log(chalk4.yellow(`
|
|
949
|
+
Rewinding to phase ${targetPhase + 1}.`));
|
|
950
|
+
return targetPhase;
|
|
951
|
+
}
|
|
893
952
|
console.log(chalk4.green(`
|
|
894
953
|
Phase ${phaseIndex + 1} completed.`));
|
|
895
|
-
return 1;
|
|
954
|
+
return phaseIndex + 1;
|
|
896
955
|
}
|
|
897
956
|
|
|
898
957
|
// src/commands/backlog/spawnClaude.ts
|
|
@@ -914,20 +973,6 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
914
973
|
|
|
915
974
|
// src/commands/backlog/watchForMarker.ts
|
|
916
975
|
import { existsSync as existsSync7, unwatchFile, watchFile } from "fs";
|
|
917
|
-
|
|
918
|
-
// src/commands/backlog/readSignal.ts
|
|
919
|
-
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
920
|
-
function readSignal() {
|
|
921
|
-
const path50 = getSignalPath();
|
|
922
|
-
if (!existsSync6(path50)) return void 0;
|
|
923
|
-
try {
|
|
924
|
-
return JSON.parse(readFileSync5(path50, "utf-8"));
|
|
925
|
-
} catch {
|
|
926
|
-
return void 0;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
// src/commands/backlog/watchForMarker.ts
|
|
931
976
|
function watchForMarker(child) {
|
|
932
977
|
const statusPath = getSignalPath();
|
|
933
978
|
watchFile(statusPath, { interval: 1e3 }, () => {
|
|
@@ -961,8 +1006,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions) {
|
|
|
961
1006
|
watchForMarker(child);
|
|
962
1007
|
await done2;
|
|
963
1008
|
stopWatching();
|
|
964
|
-
|
|
965
|
-
return delta < 0 ? -1 : phaseIndex + delta;
|
|
1009
|
+
return await resolvePhaseResult(phaseIndex, item.id);
|
|
966
1010
|
}
|
|
967
1011
|
|
|
968
1012
|
// src/commands/backlog/prepareRun.ts
|
|
@@ -1175,10 +1219,11 @@ import chalk14 from "chalk";
|
|
|
1175
1219
|
// src/commands/backlog/formatComment.ts
|
|
1176
1220
|
import chalk11 from "chalk";
|
|
1177
1221
|
function formatComment(entry) {
|
|
1222
|
+
const id = entry.id !== void 0 ? chalk11.dim(`#${entry.id} `) : "";
|
|
1178
1223
|
const tag = entry.type === "summary" ? chalk11.magenta("[summary]") : chalk11.cyan("[comment]");
|
|
1179
1224
|
const phase = entry.phase !== void 0 ? chalk11.dim(` (phase ${entry.phase + 1})`) : "";
|
|
1180
1225
|
const time = chalk11.dim(entry.timestamp);
|
|
1181
|
-
return `${tag}${phase} ${time}
|
|
1226
|
+
return `${id}${tag}${phase} ${time}
|
|
1182
1227
|
${entry.text}`;
|
|
1183
1228
|
}
|
|
1184
1229
|
|
|
@@ -3757,24 +3802,73 @@ function comments(id) {
|
|
|
3757
3802
|
}
|
|
3758
3803
|
}
|
|
3759
3804
|
|
|
3805
|
+
// src/commands/backlog/delete-comment/index.ts
|
|
3806
|
+
import chalk43 from "chalk";
|
|
3807
|
+
|
|
3808
|
+
// src/commands/backlog/deleteComment.ts
|
|
3809
|
+
function deleteComment(db, itemId, commentId) {
|
|
3810
|
+
const row = db.prepare("SELECT type FROM comments WHERE id = ? AND item_id = ?").get(commentId, itemId);
|
|
3811
|
+
if (!row) return "not-found";
|
|
3812
|
+
if (row.type === "summary") return "is-summary";
|
|
3813
|
+
db.prepare("DELETE FROM comments WHERE id = ? AND item_id = ?").run(
|
|
3814
|
+
commentId,
|
|
3815
|
+
itemId
|
|
3816
|
+
);
|
|
3817
|
+
return "deleted";
|
|
3818
|
+
}
|
|
3819
|
+
|
|
3820
|
+
// src/commands/backlog/delete-comment/index.ts
|
|
3821
|
+
function deleteCommentCmd(id, commentId) {
|
|
3822
|
+
const result = loadAndFindItem(id);
|
|
3823
|
+
if (!result) process.exit(1);
|
|
3824
|
+
const dir = getBacklogDir();
|
|
3825
|
+
const db = openDb(dir);
|
|
3826
|
+
const outcome = deleteComment(
|
|
3827
|
+
db,
|
|
3828
|
+
result.item.id,
|
|
3829
|
+
Number.parseInt(commentId, 10)
|
|
3830
|
+
);
|
|
3831
|
+
switch (outcome) {
|
|
3832
|
+
case "deleted":
|
|
3833
|
+
exportToJsonl(db, dir);
|
|
3834
|
+
console.log(
|
|
3835
|
+
chalk43.green(`Comment #${commentId} deleted from item #${id}.`)
|
|
3836
|
+
);
|
|
3837
|
+
break;
|
|
3838
|
+
case "not-found":
|
|
3839
|
+
console.log(chalk43.red(`Comment #${commentId} not found on item #${id}.`));
|
|
3840
|
+
process.exit(1);
|
|
3841
|
+
break;
|
|
3842
|
+
case "is-summary":
|
|
3843
|
+
console.log(
|
|
3844
|
+
chalk43.red(
|
|
3845
|
+
`Comment #${commentId} is a phase summary and cannot be deleted.`
|
|
3846
|
+
)
|
|
3847
|
+
);
|
|
3848
|
+
process.exit(1);
|
|
3849
|
+
break;
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3760
3853
|
// src/commands/backlog/registerCommentCommands.ts
|
|
3761
3854
|
function registerCommentCommands(cmd) {
|
|
3762
3855
|
cmd.command("comment <id> <text>").description("Add a comment to a backlog item").action(comment);
|
|
3763
3856
|
cmd.command("comments <id>").description("List comments and summaries for a backlog item").action(comments);
|
|
3857
|
+
cmd.command("delete-comment <id> <comment-id>").description("Delete a comment from a backlog item").action(deleteCommentCmd);
|
|
3764
3858
|
}
|
|
3765
3859
|
|
|
3766
3860
|
// src/commands/backlog/add/index.ts
|
|
3767
|
-
import
|
|
3861
|
+
import chalk45 from "chalk";
|
|
3768
3862
|
|
|
3769
3863
|
// src/commands/backlog/commitBacklog.ts
|
|
3770
3864
|
import { execSync as execSync15 } from "child_process";
|
|
3771
3865
|
import { join as join15 } from "path";
|
|
3772
|
-
import
|
|
3866
|
+
import chalk44 from "chalk";
|
|
3773
3867
|
function commitBacklog(id, name) {
|
|
3774
3868
|
const config = loadConfig();
|
|
3775
3869
|
if (!config.backlog.autoCommit) {
|
|
3776
3870
|
console.log(
|
|
3777
|
-
|
|
3871
|
+
chalk44.yellow(
|
|
3778
3872
|
"Warning: auto-commit is disabled. Stage and commit the backlog file manually."
|
|
3779
3873
|
)
|
|
3780
3874
|
);
|
|
@@ -3786,7 +3880,7 @@ function commitBacklog(id, name) {
|
|
|
3786
3880
|
execSync15(`git add ${shellQuote(jsonlPath)}`, { stdio: "ignore" });
|
|
3787
3881
|
execSync15(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3788
3882
|
} catch {
|
|
3789
|
-
console.log(
|
|
3883
|
+
console.log(chalk44.yellow("Warning: could not auto-commit backlog file."));
|
|
3790
3884
|
}
|
|
3791
3885
|
}
|
|
3792
3886
|
|
|
@@ -3878,12 +3972,12 @@ async function addFromOptions(options2) {
|
|
|
3878
3972
|
});
|
|
3879
3973
|
saveBacklog(items);
|
|
3880
3974
|
commitBacklog(id, name);
|
|
3881
|
-
console.log(
|
|
3975
|
+
console.log(chalk45.green(`Added item #${id}: ${name}`));
|
|
3882
3976
|
}
|
|
3883
3977
|
async function add(options2) {
|
|
3884
3978
|
if (!backlogExists()) {
|
|
3885
3979
|
console.log(
|
|
3886
|
-
|
|
3980
|
+
chalk45.yellow(
|
|
3887
3981
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3888
3982
|
)
|
|
3889
3983
|
);
|
|
@@ -3893,13 +3987,13 @@ async function add(options2) {
|
|
|
3893
3987
|
}
|
|
3894
3988
|
|
|
3895
3989
|
// src/commands/backlog/addPhase.ts
|
|
3896
|
-
import
|
|
3990
|
+
import chalk46 from "chalk";
|
|
3897
3991
|
function addPhase(id, name, options2) {
|
|
3898
3992
|
const result = loadAndFindItem(id);
|
|
3899
3993
|
if (!result) return;
|
|
3900
3994
|
const tasks = options2.task ?? [];
|
|
3901
3995
|
if (tasks.length === 0) {
|
|
3902
|
-
console.log(
|
|
3996
|
+
console.log(chalk46.red("At least one --task is required."));
|
|
3903
3997
|
process.exitCode = 1;
|
|
3904
3998
|
return;
|
|
3905
3999
|
}
|
|
@@ -3921,25 +4015,25 @@ function addPhase(id, name, options2) {
|
|
|
3921
4015
|
exportToJsonl(db, dir);
|
|
3922
4016
|
commitBacklog(itemId, result.item.name);
|
|
3923
4017
|
console.log(
|
|
3924
|
-
|
|
4018
|
+
chalk46.green(
|
|
3925
4019
|
`Added phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
|
|
3926
4020
|
)
|
|
3927
4021
|
);
|
|
3928
4022
|
}
|
|
3929
4023
|
|
|
3930
4024
|
// src/commands/backlog/init/index.ts
|
|
3931
|
-
import
|
|
4025
|
+
import chalk47 from "chalk";
|
|
3932
4026
|
async function init6() {
|
|
3933
4027
|
if (backlogExists()) {
|
|
3934
|
-
console.log(
|
|
4028
|
+
console.log(chalk47.yellow("Backlog already exists."));
|
|
3935
4029
|
return;
|
|
3936
4030
|
}
|
|
3937
4031
|
saveBacklog([]);
|
|
3938
|
-
console.log(
|
|
4032
|
+
console.log(chalk47.green("Created backlog."));
|
|
3939
4033
|
}
|
|
3940
4034
|
|
|
3941
4035
|
// src/commands/backlog/list/index.ts
|
|
3942
|
-
import
|
|
4036
|
+
import chalk48 from "chalk";
|
|
3943
4037
|
function filterItems(items, options2) {
|
|
3944
4038
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3945
4039
|
if (!options2.all)
|
|
@@ -3949,7 +4043,7 @@ function filterItems(items, options2) {
|
|
|
3949
4043
|
async function list2(options2) {
|
|
3950
4044
|
if (!backlogExists()) {
|
|
3951
4045
|
console.log(
|
|
3952
|
-
|
|
4046
|
+
chalk48.yellow(
|
|
3953
4047
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3954
4048
|
)
|
|
3955
4049
|
);
|
|
@@ -3958,12 +4052,12 @@ async function list2(options2) {
|
|
|
3958
4052
|
const allItems = loadBacklog();
|
|
3959
4053
|
const items = filterItems(allItems, options2);
|
|
3960
4054
|
if (items.length === 0) {
|
|
3961
|
-
console.log(
|
|
4055
|
+
console.log(chalk48.dim("Backlog is empty."));
|
|
3962
4056
|
return;
|
|
3963
4057
|
}
|
|
3964
4058
|
for (const item of items) {
|
|
3965
4059
|
console.log(
|
|
3966
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
4060
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk48.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
3967
4061
|
);
|
|
3968
4062
|
if (options2.verbose) {
|
|
3969
4063
|
printVerboseDetails(item);
|
|
@@ -3986,7 +4080,7 @@ function registerItemCommands(cmd) {
|
|
|
3986
4080
|
}
|
|
3987
4081
|
|
|
3988
4082
|
// src/commands/backlog/link.ts
|
|
3989
|
-
import
|
|
4083
|
+
import chalk50 from "chalk";
|
|
3990
4084
|
|
|
3991
4085
|
// src/commands/backlog/hasCycle.ts
|
|
3992
4086
|
function hasCycle(items, fromId, toId) {
|
|
@@ -4009,11 +4103,11 @@ function hasCycle(items, fromId, toId) {
|
|
|
4009
4103
|
}
|
|
4010
4104
|
|
|
4011
4105
|
// src/commands/backlog/validateLinkTarget.ts
|
|
4012
|
-
import
|
|
4106
|
+
import chalk49 from "chalk";
|
|
4013
4107
|
function validateLinkTarget(items, fromItem, fromId, toId, toNum, linkType) {
|
|
4014
4108
|
const toItem = items.find((i) => i.id === toNum);
|
|
4015
4109
|
if (!toItem) {
|
|
4016
|
-
console.log(
|
|
4110
|
+
console.log(chalk49.red(`Item #${toId} not found.`));
|
|
4017
4111
|
return void 0;
|
|
4018
4112
|
}
|
|
4019
4113
|
if (!fromItem.links) fromItem.links = [];
|
|
@@ -4022,7 +4116,7 @@ function validateLinkTarget(items, fromItem, fromId, toId, toNum, linkType) {
|
|
|
4022
4116
|
);
|
|
4023
4117
|
if (duplicate) {
|
|
4024
4118
|
console.log(
|
|
4025
|
-
|
|
4119
|
+
chalk49.yellow(`Link already exists: #${fromId} ${linkType} #${toId}`)
|
|
4026
4120
|
);
|
|
4027
4121
|
return void 0;
|
|
4028
4122
|
}
|
|
@@ -4033,13 +4127,13 @@ function validateLinkTarget(items, fromItem, fromId, toId, toNum, linkType) {
|
|
|
4033
4127
|
function link(fromId, toId, opts) {
|
|
4034
4128
|
const linkType = opts.type ?? "relates-to";
|
|
4035
4129
|
if (linkType !== "relates-to" && linkType !== "depends-on") {
|
|
4036
|
-
console.log(
|
|
4130
|
+
console.log(chalk50.red(`Invalid link type: ${linkType}`));
|
|
4037
4131
|
return;
|
|
4038
4132
|
}
|
|
4039
4133
|
const fromNum = Number.parseInt(fromId, 10);
|
|
4040
4134
|
const toNum = Number.parseInt(toId, 10);
|
|
4041
4135
|
if (fromNum === toNum) {
|
|
4042
|
-
console.log(
|
|
4136
|
+
console.log(chalk50.red("Cannot link an item to itself."));
|
|
4043
4137
|
return;
|
|
4044
4138
|
}
|
|
4045
4139
|
const result = loadAndFindItem(fromId);
|
|
@@ -4056,7 +4150,7 @@ function link(fromId, toId, opts) {
|
|
|
4056
4150
|
if (!toItem) return;
|
|
4057
4151
|
if (linkType === "depends-on" && hasCycle(items, fromNum, toNum)) {
|
|
4058
4152
|
console.log(
|
|
4059
|
-
|
|
4153
|
+
chalk50.red(
|
|
4060
4154
|
`Cannot add dependency: #${fromId} \u2192 #${toId} would create a circular dependency.`
|
|
4061
4155
|
)
|
|
4062
4156
|
);
|
|
@@ -4066,32 +4160,32 @@ function link(fromId, toId, opts) {
|
|
|
4066
4160
|
fromItem.links.push({ type: linkType, targetId: toNum });
|
|
4067
4161
|
saveBacklog(items);
|
|
4068
4162
|
console.log(
|
|
4069
|
-
|
|
4163
|
+
chalk50.green(`Linked #${fromId} ${linkType} #${toId} (${toItem.name})`)
|
|
4070
4164
|
);
|
|
4071
4165
|
}
|
|
4072
4166
|
|
|
4073
4167
|
// src/commands/backlog/unlink.ts
|
|
4074
|
-
import
|
|
4168
|
+
import chalk51 from "chalk";
|
|
4075
4169
|
function unlink(fromId, toId) {
|
|
4076
4170
|
const toNum = Number.parseInt(toId, 10);
|
|
4077
4171
|
const result = loadAndFindItem(fromId);
|
|
4078
4172
|
if (!result) return;
|
|
4079
4173
|
const { items, item: fromItem } = result;
|
|
4080
4174
|
if (!fromItem.links || fromItem.links.length === 0) {
|
|
4081
|
-
console.log(
|
|
4175
|
+
console.log(chalk51.yellow(`No links found on item #${fromId}.`));
|
|
4082
4176
|
return;
|
|
4083
4177
|
}
|
|
4084
4178
|
const before = fromItem.links.length;
|
|
4085
4179
|
fromItem.links = fromItem.links.filter((l) => l.targetId !== toNum);
|
|
4086
4180
|
if (fromItem.links.length === before) {
|
|
4087
|
-
console.log(
|
|
4181
|
+
console.log(chalk51.yellow(`No link from #${fromId} to #${toId} found.`));
|
|
4088
4182
|
return;
|
|
4089
4183
|
}
|
|
4090
4184
|
if (fromItem.links.length === 0) {
|
|
4091
4185
|
fromItem.links = void 0;
|
|
4092
4186
|
}
|
|
4093
4187
|
saveBacklog(items);
|
|
4094
|
-
console.log(
|
|
4188
|
+
console.log(chalk51.green(`Removed link from #${fromId} to #${toId}.`));
|
|
4095
4189
|
}
|
|
4096
4190
|
|
|
4097
4191
|
// src/commands/backlog/registerLinkCommands.ts
|
|
@@ -4104,6 +4198,55 @@ function registerLinkCommands(cmd) {
|
|
|
4104
4198
|
cmd.command("unlink <from> <to>").description("Remove a link between two backlog items").action(unlink);
|
|
4105
4199
|
}
|
|
4106
4200
|
|
|
4201
|
+
// src/commands/backlog/rewindPhase.ts
|
|
4202
|
+
import chalk52 from "chalk";
|
|
4203
|
+
function validateRewind(item, phaseIndex) {
|
|
4204
|
+
if (!item.plan || item.plan.length === 0) {
|
|
4205
|
+
return `Item #${item.id} has no plan phases.`;
|
|
4206
|
+
}
|
|
4207
|
+
if (phaseIndex < 0 || phaseIndex >= item.plan.length) {
|
|
4208
|
+
return `Phase ${phaseIndex} does not exist. Valid range: 0\u2013${item.plan.length - 1}.`;
|
|
4209
|
+
}
|
|
4210
|
+
const currentPhase = item.currentPhase ?? 0;
|
|
4211
|
+
if (phaseIndex >= currentPhase) {
|
|
4212
|
+
return `Phase ${phaseIndex} is not earlier than the current phase (${currentPhase}).`;
|
|
4213
|
+
}
|
|
4214
|
+
return void 0;
|
|
4215
|
+
}
|
|
4216
|
+
function rewindPhase(id, phase, opts) {
|
|
4217
|
+
const phaseIndex = Number.parseInt(phase, 10);
|
|
4218
|
+
const result = loadAndFindItem(id);
|
|
4219
|
+
if (!result) return;
|
|
4220
|
+
const { item } = result;
|
|
4221
|
+
const error = validateRewind(item, phaseIndex);
|
|
4222
|
+
if (error) {
|
|
4223
|
+
console.log(chalk52.red(error));
|
|
4224
|
+
process.exitCode = 1;
|
|
4225
|
+
return;
|
|
4226
|
+
}
|
|
4227
|
+
const phaseName = item.plan?.[phaseIndex].name;
|
|
4228
|
+
addComment(
|
|
4229
|
+
item,
|
|
4230
|
+
`Rewound to phase ${phaseIndex} (${phaseName}): ${opts.reason}`,
|
|
4231
|
+
phaseIndex
|
|
4232
|
+
);
|
|
4233
|
+
saveBacklog(result.items);
|
|
4234
|
+
setCurrentPhase(id, phaseIndex);
|
|
4235
|
+
setStatus(id, "in-progress");
|
|
4236
|
+
writeSignal("rewind", {
|
|
4237
|
+
itemId: Number.parseInt(id, 10),
|
|
4238
|
+
targetPhase: phaseIndex
|
|
4239
|
+
});
|
|
4240
|
+
console.log(
|
|
4241
|
+
chalk52.green(`Rewound item #${id} to phase ${phaseIndex} (${phaseName}).`)
|
|
4242
|
+
);
|
|
4243
|
+
}
|
|
4244
|
+
|
|
4245
|
+
// src/commands/backlog/registerRewindCommand.ts
|
|
4246
|
+
function registerRewindCommand(cmd) {
|
|
4247
|
+
cmd.command("rewind <id> <phase>").description("Rewind a backlog item to an earlier phase").requiredOption("--reason <reason>", "Reason for rewinding").action(rewindPhase);
|
|
4248
|
+
}
|
|
4249
|
+
|
|
4107
4250
|
// src/commands/backlog/registerRunCommand.ts
|
|
4108
4251
|
function registerRunCommand(cmd) {
|
|
4109
4252
|
cmd.command("run <id>").description("Run a backlog item's plan phase-by-phase with Claude").option("-w, --write", "Run Claude with acceptEdits permission mode").action(async (id, opts) => {
|
|
@@ -4112,11 +4255,11 @@ function registerRunCommand(cmd) {
|
|
|
4112
4255
|
}
|
|
4113
4256
|
|
|
4114
4257
|
// src/commands/backlog/search/index.ts
|
|
4115
|
-
import
|
|
4258
|
+
import chalk53 from "chalk";
|
|
4116
4259
|
async function search(query) {
|
|
4117
4260
|
if (!backlogExists()) {
|
|
4118
4261
|
console.log(
|
|
4119
|
-
|
|
4262
|
+
chalk53.yellow(
|
|
4120
4263
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
4121
4264
|
)
|
|
4122
4265
|
);
|
|
@@ -4124,18 +4267,18 @@ async function search(query) {
|
|
|
4124
4267
|
}
|
|
4125
4268
|
const items = searchBacklog(query);
|
|
4126
4269
|
if (items.length === 0) {
|
|
4127
|
-
console.log(
|
|
4270
|
+
console.log(chalk53.dim(`No items matching "${query}".`));
|
|
4128
4271
|
return;
|
|
4129
4272
|
}
|
|
4130
4273
|
console.log(
|
|
4131
|
-
|
|
4274
|
+
chalk53.dim(
|
|
4132
4275
|
`${items.length} item${items.length === 1 ? "" : "s"} matching "${query}":
|
|
4133
4276
|
`
|
|
4134
4277
|
)
|
|
4135
4278
|
);
|
|
4136
4279
|
for (const item of items) {
|
|
4137
4280
|
console.log(
|
|
4138
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
4281
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk53.dim(`#${item.id}`)} ${item.name}`
|
|
4139
4282
|
);
|
|
4140
4283
|
}
|
|
4141
4284
|
}
|
|
@@ -4146,16 +4289,16 @@ function registerSearchCommand(cmd) {
|
|
|
4146
4289
|
}
|
|
4147
4290
|
|
|
4148
4291
|
// src/commands/backlog/delete/index.ts
|
|
4149
|
-
import
|
|
4292
|
+
import chalk54 from "chalk";
|
|
4150
4293
|
async function del(id) {
|
|
4151
4294
|
const name = removeItem(id);
|
|
4152
4295
|
if (name) {
|
|
4153
|
-
console.log(
|
|
4296
|
+
console.log(chalk54.green(`Deleted item #${id}: ${name}`));
|
|
4154
4297
|
}
|
|
4155
4298
|
}
|
|
4156
4299
|
|
|
4157
4300
|
// src/commands/backlog/done/index.ts
|
|
4158
|
-
import
|
|
4301
|
+
import chalk55 from "chalk";
|
|
4159
4302
|
async function done(id, summary) {
|
|
4160
4303
|
const result = loadAndFindItem(id);
|
|
4161
4304
|
if (!result) return;
|
|
@@ -4165,12 +4308,12 @@ async function done(id, summary) {
|
|
|
4165
4308
|
const pending = item.plan.slice(completed);
|
|
4166
4309
|
if (pending.length > 0) {
|
|
4167
4310
|
console.log(
|
|
4168
|
-
|
|
4311
|
+
chalk55.red(
|
|
4169
4312
|
`Cannot complete item #${id}: ${pending.length} pending phase(s):`
|
|
4170
4313
|
)
|
|
4171
4314
|
);
|
|
4172
4315
|
for (const phase of pending) {
|
|
4173
|
-
console.log(
|
|
4316
|
+
console.log(chalk55.yellow(` - ${phase.name}`));
|
|
4174
4317
|
}
|
|
4175
4318
|
process.exitCode = 1;
|
|
4176
4319
|
return;
|
|
@@ -4182,20 +4325,20 @@ async function done(id, summary) {
|
|
|
4182
4325
|
addPhaseSummary(item, summary, phase);
|
|
4183
4326
|
}
|
|
4184
4327
|
saveBacklog(result.items);
|
|
4185
|
-
console.log(
|
|
4328
|
+
console.log(chalk55.green(`Completed item #${id}: ${item.name}`));
|
|
4186
4329
|
}
|
|
4187
4330
|
|
|
4188
4331
|
// src/commands/backlog/start/index.ts
|
|
4189
|
-
import
|
|
4332
|
+
import chalk56 from "chalk";
|
|
4190
4333
|
async function start(id) {
|
|
4191
4334
|
const name = setStatus(id, "in-progress");
|
|
4192
4335
|
if (name) {
|
|
4193
|
-
console.log(
|
|
4336
|
+
console.log(chalk56.green(`Started item #${id}: ${name}`));
|
|
4194
4337
|
}
|
|
4195
4338
|
}
|
|
4196
4339
|
|
|
4197
4340
|
// src/commands/backlog/wontdo/index.ts
|
|
4198
|
-
import
|
|
4341
|
+
import chalk57 from "chalk";
|
|
4199
4342
|
async function wontdo(id, reason) {
|
|
4200
4343
|
const result = loadAndFindItem(id);
|
|
4201
4344
|
if (!result) return;
|
|
@@ -4205,7 +4348,7 @@ async function wontdo(id, reason) {
|
|
|
4205
4348
|
addPhaseSummary(result.item, reason, phase);
|
|
4206
4349
|
}
|
|
4207
4350
|
saveBacklog(result.items);
|
|
4208
|
-
console.log(
|
|
4351
|
+
console.log(chalk57.red(`Won't do item #${id}: ${result.item.name}`));
|
|
4209
4352
|
}
|
|
4210
4353
|
|
|
4211
4354
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -4217,10 +4360,10 @@ function registerStatusCommands(cmd) {
|
|
|
4217
4360
|
}
|
|
4218
4361
|
|
|
4219
4362
|
// src/commands/backlog/removePhase.ts
|
|
4220
|
-
import
|
|
4363
|
+
import chalk59 from "chalk";
|
|
4221
4364
|
|
|
4222
4365
|
// src/commands/backlog/findPhase.ts
|
|
4223
|
-
import
|
|
4366
|
+
import chalk58 from "chalk";
|
|
4224
4367
|
function findPhase(id, phase) {
|
|
4225
4368
|
const result = loadAndFindItem(id);
|
|
4226
4369
|
if (!result) return void 0;
|
|
@@ -4232,7 +4375,7 @@ function findPhase(id, phase) {
|
|
|
4232
4375
|
"SELECT COUNT(*) as cnt FROM plan_phases WHERE item_id = ? AND idx = ?"
|
|
4233
4376
|
).get(itemId, phaseIdx);
|
|
4234
4377
|
if (existing.cnt === 0) {
|
|
4235
|
-
console.log(
|
|
4378
|
+
console.log(chalk58.red(`Phase ${phaseIdx} not found on item #${itemId}.`));
|
|
4236
4379
|
process.exitCode = 1;
|
|
4237
4380
|
return void 0;
|
|
4238
4381
|
}
|
|
@@ -4288,23 +4431,23 @@ function removePhase(id, phase) {
|
|
|
4288
4431
|
run4();
|
|
4289
4432
|
exportToJsonl(db, dir);
|
|
4290
4433
|
commitBacklog(itemId, result.item.name);
|
|
4291
|
-
console.log(
|
|
4434
|
+
console.log(chalk59.green(`Removed phase ${phaseIdx} from item #${itemId}.`));
|
|
4292
4435
|
}
|
|
4293
4436
|
|
|
4294
4437
|
// src/commands/backlog/update/index.ts
|
|
4295
|
-
import
|
|
4438
|
+
import chalk61 from "chalk";
|
|
4296
4439
|
|
|
4297
4440
|
// src/commands/backlog/update/buildUpdateSql.ts
|
|
4298
|
-
import
|
|
4441
|
+
import chalk60 from "chalk";
|
|
4299
4442
|
function buildUpdateSql(options2) {
|
|
4300
4443
|
const { name, desc, type, ac } = options2;
|
|
4301
4444
|
if (!name && !desc && !type && !ac) {
|
|
4302
|
-
console.log(
|
|
4445
|
+
console.log(chalk60.red("Nothing to update. Provide at least one flag."));
|
|
4303
4446
|
process.exitCode = 1;
|
|
4304
4447
|
return void 0;
|
|
4305
4448
|
}
|
|
4306
4449
|
if (type && type !== "story" && type !== "bug") {
|
|
4307
|
-
console.log(
|
|
4450
|
+
console.log(chalk60.red('Invalid type. Must be "story" or "bug".'));
|
|
4308
4451
|
process.exitCode = 1;
|
|
4309
4452
|
return void 0;
|
|
4310
4453
|
}
|
|
@@ -4349,11 +4492,11 @@ function update(id, options2) {
|
|
|
4349
4492
|
);
|
|
4350
4493
|
exportToJsonl(db, dir);
|
|
4351
4494
|
commitBacklog(itemId, options2.name ?? result.item.name);
|
|
4352
|
-
console.log(
|
|
4495
|
+
console.log(chalk61.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
4353
4496
|
}
|
|
4354
4497
|
|
|
4355
4498
|
// src/commands/backlog/updatePhase.ts
|
|
4356
|
-
import
|
|
4499
|
+
import chalk62 from "chalk";
|
|
4357
4500
|
|
|
4358
4501
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
4359
4502
|
function applyPhaseUpdate(db, itemId, phaseIdx, fields) {
|
|
@@ -4387,7 +4530,7 @@ function applyPhaseUpdate(db, itemId, phaseIdx, fields) {
|
|
|
4387
4530
|
function updatePhase(id, phase, options2) {
|
|
4388
4531
|
const { name, task, manualCheck } = options2;
|
|
4389
4532
|
if (!name && !task && !manualCheck) {
|
|
4390
|
-
console.log(
|
|
4533
|
+
console.log(chalk62.red("Nothing to update. Provide at least one flag."));
|
|
4391
4534
|
process.exitCode = 1;
|
|
4392
4535
|
return;
|
|
4393
4536
|
}
|
|
@@ -4403,7 +4546,7 @@ function updatePhase(id, phase, options2) {
|
|
|
4403
4546
|
manualCheck && "manual checks"
|
|
4404
4547
|
].filter(Boolean).join(", ");
|
|
4405
4548
|
console.log(
|
|
4406
|
-
|
|
4549
|
+
chalk62.green(`Updated ${fields} on phase ${phaseIdx} of item #${itemId}.`)
|
|
4407
4550
|
);
|
|
4408
4551
|
}
|
|
4409
4552
|
|
|
@@ -4441,6 +4584,7 @@ function registerBacklog(program2) {
|
|
|
4441
4584
|
registerCommentCommands(cmd);
|
|
4442
4585
|
registerLinkCommands(cmd);
|
|
4443
4586
|
registerPlanCommands(cmd);
|
|
4587
|
+
registerRewindCommand(cmd);
|
|
4444
4588
|
registerNextCommand(cmd);
|
|
4445
4589
|
registerRunCommand(cmd);
|
|
4446
4590
|
registerSearchCommand(cmd);
|
|
@@ -4900,11 +5044,11 @@ function assertCliExists(cli) {
|
|
|
4900
5044
|
}
|
|
4901
5045
|
|
|
4902
5046
|
// src/commands/permitCliReads/colorize.ts
|
|
4903
|
-
import
|
|
5047
|
+
import chalk63 from "chalk";
|
|
4904
5048
|
function colorize(plainOutput) {
|
|
4905
5049
|
return plainOutput.split("\n").map((line) => {
|
|
4906
|
-
if (line.startsWith(" R ")) return
|
|
4907
|
-
if (line.startsWith(" W ")) return
|
|
5050
|
+
if (line.startsWith(" R ")) return chalk63.green(line);
|
|
5051
|
+
if (line.startsWith(" W ")) return chalk63.red(line);
|
|
4908
5052
|
return line;
|
|
4909
5053
|
}).join("\n");
|
|
4910
5054
|
}
|
|
@@ -5202,48 +5346,48 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
5202
5346
|
}
|
|
5203
5347
|
|
|
5204
5348
|
// src/commands/deny/denyAdd.ts
|
|
5205
|
-
import
|
|
5349
|
+
import chalk64 from "chalk";
|
|
5206
5350
|
function denyAdd(pattern2, message) {
|
|
5207
5351
|
const config = loadProjectConfig();
|
|
5208
5352
|
const deny = config.deny ?? [];
|
|
5209
5353
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
5210
|
-
console.log(
|
|
5354
|
+
console.log(chalk64.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
5211
5355
|
return;
|
|
5212
5356
|
}
|
|
5213
5357
|
deny.push({ pattern: pattern2, message });
|
|
5214
5358
|
config.deny = deny;
|
|
5215
5359
|
saveConfig(config);
|
|
5216
|
-
console.log(
|
|
5360
|
+
console.log(chalk64.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
5217
5361
|
}
|
|
5218
5362
|
|
|
5219
5363
|
// src/commands/deny/denyList.ts
|
|
5220
|
-
import
|
|
5364
|
+
import chalk65 from "chalk";
|
|
5221
5365
|
function denyList() {
|
|
5222
5366
|
const config = loadConfig();
|
|
5223
5367
|
const deny = config.deny;
|
|
5224
5368
|
if (!deny || deny.length === 0) {
|
|
5225
|
-
console.log(
|
|
5369
|
+
console.log(chalk65.dim("No deny rules configured."));
|
|
5226
5370
|
return;
|
|
5227
5371
|
}
|
|
5228
5372
|
for (const rule of deny) {
|
|
5229
|
-
console.log(`${
|
|
5373
|
+
console.log(`${chalk65.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
5230
5374
|
}
|
|
5231
5375
|
}
|
|
5232
5376
|
|
|
5233
5377
|
// src/commands/deny/denyRemove.ts
|
|
5234
|
-
import
|
|
5378
|
+
import chalk66 from "chalk";
|
|
5235
5379
|
function denyRemove(pattern2) {
|
|
5236
5380
|
const config = loadProjectConfig();
|
|
5237
5381
|
const deny = config.deny ?? [];
|
|
5238
5382
|
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
5239
5383
|
if (index === -1) {
|
|
5240
|
-
console.log(
|
|
5384
|
+
console.log(chalk66.yellow(`No deny rule found for: ${pattern2}`));
|
|
5241
5385
|
return;
|
|
5242
5386
|
}
|
|
5243
5387
|
deny.splice(index, 1);
|
|
5244
5388
|
config.deny = deny.length > 0 ? deny : void 0;
|
|
5245
5389
|
saveConfig(config);
|
|
5246
|
-
console.log(
|
|
5390
|
+
console.log(chalk66.green(`Removed deny rule: ${pattern2}`));
|
|
5247
5391
|
}
|
|
5248
5392
|
|
|
5249
5393
|
// src/commands/registerDeny.ts
|
|
@@ -5272,15 +5416,15 @@ function registerCliHook(program2) {
|
|
|
5272
5416
|
}
|
|
5273
5417
|
|
|
5274
5418
|
// src/commands/complexity/analyze.ts
|
|
5275
|
-
import
|
|
5419
|
+
import chalk72 from "chalk";
|
|
5276
5420
|
|
|
5277
5421
|
// src/commands/complexity/cyclomatic.ts
|
|
5278
|
-
import
|
|
5422
|
+
import chalk68 from "chalk";
|
|
5279
5423
|
|
|
5280
5424
|
// src/commands/complexity/shared/index.ts
|
|
5281
5425
|
import fs12 from "fs";
|
|
5282
5426
|
import path20 from "path";
|
|
5283
|
-
import
|
|
5427
|
+
import chalk67 from "chalk";
|
|
5284
5428
|
import ts5 from "typescript";
|
|
5285
5429
|
|
|
5286
5430
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -5526,7 +5670,7 @@ function createSourceFromFile(filePath) {
|
|
|
5526
5670
|
function withSourceFiles(pattern2, callback) {
|
|
5527
5671
|
const files = findSourceFiles2(pattern2);
|
|
5528
5672
|
if (files.length === 0) {
|
|
5529
|
-
console.log(
|
|
5673
|
+
console.log(chalk67.yellow("No files found matching pattern"));
|
|
5530
5674
|
return void 0;
|
|
5531
5675
|
}
|
|
5532
5676
|
return callback(files);
|
|
@@ -5559,11 +5703,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5559
5703
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
5560
5704
|
for (const { file, name, complexity } of results) {
|
|
5561
5705
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
5562
|
-
const color = exceedsThreshold ?
|
|
5563
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
5706
|
+
const color = exceedsThreshold ? chalk68.red : chalk68.white;
|
|
5707
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk68.cyan(complexity)}`);
|
|
5564
5708
|
}
|
|
5565
5709
|
console.log(
|
|
5566
|
-
|
|
5710
|
+
chalk68.dim(
|
|
5567
5711
|
`
|
|
5568
5712
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
5569
5713
|
)
|
|
@@ -5575,7 +5719,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
5575
5719
|
}
|
|
5576
5720
|
|
|
5577
5721
|
// src/commands/complexity/halstead.ts
|
|
5578
|
-
import
|
|
5722
|
+
import chalk69 from "chalk";
|
|
5579
5723
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
5580
5724
|
withSourceFiles(pattern2, (files) => {
|
|
5581
5725
|
const results = [];
|
|
@@ -5590,13 +5734,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5590
5734
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
5591
5735
|
for (const { file, name, metrics } of results) {
|
|
5592
5736
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
5593
|
-
const color = exceedsThreshold ?
|
|
5737
|
+
const color = exceedsThreshold ? chalk69.red : chalk69.white;
|
|
5594
5738
|
console.log(
|
|
5595
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
5739
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk69.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk69.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk69.magenta(metrics.effort.toFixed(1))}`
|
|
5596
5740
|
);
|
|
5597
5741
|
}
|
|
5598
5742
|
console.log(
|
|
5599
|
-
|
|
5743
|
+
chalk69.dim(
|
|
5600
5744
|
`
|
|
5601
5745
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
5602
5746
|
)
|
|
@@ -5611,28 +5755,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
5611
5755
|
import fs13 from "fs";
|
|
5612
5756
|
|
|
5613
5757
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
5614
|
-
import
|
|
5758
|
+
import chalk70 from "chalk";
|
|
5615
5759
|
function displayMaintainabilityResults(results, threshold) {
|
|
5616
5760
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
5617
5761
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
5618
|
-
console.log(
|
|
5762
|
+
console.log(chalk70.green("All files pass maintainability threshold"));
|
|
5619
5763
|
} else {
|
|
5620
5764
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
5621
|
-
const color = threshold !== void 0 ?
|
|
5765
|
+
const color = threshold !== void 0 ? chalk70.red : chalk70.white;
|
|
5622
5766
|
console.log(
|
|
5623
|
-
`${color(file)} \u2192 avg: ${
|
|
5767
|
+
`${color(file)} \u2192 avg: ${chalk70.cyan(avgMaintainability.toFixed(1))}, min: ${chalk70.yellow(minMaintainability.toFixed(1))}`
|
|
5624
5768
|
);
|
|
5625
5769
|
}
|
|
5626
5770
|
}
|
|
5627
|
-
console.log(
|
|
5771
|
+
console.log(chalk70.dim(`
|
|
5628
5772
|
Analyzed ${results.length} files`));
|
|
5629
5773
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
5630
5774
|
console.error(
|
|
5631
|
-
|
|
5775
|
+
chalk70.red(
|
|
5632
5776
|
`
|
|
5633
5777
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
5634
5778
|
|
|
5635
|
-
\u26A0\uFE0F ${
|
|
5779
|
+
\u26A0\uFE0F ${chalk70.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.`
|
|
5636
5780
|
)
|
|
5637
5781
|
);
|
|
5638
5782
|
process.exit(1);
|
|
@@ -5689,7 +5833,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5689
5833
|
|
|
5690
5834
|
// src/commands/complexity/sloc.ts
|
|
5691
5835
|
import fs14 from "fs";
|
|
5692
|
-
import
|
|
5836
|
+
import chalk71 from "chalk";
|
|
5693
5837
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
5694
5838
|
withSourceFiles(pattern2, (files) => {
|
|
5695
5839
|
const results = [];
|
|
@@ -5705,12 +5849,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5705
5849
|
results.sort((a, b) => b.lines - a.lines);
|
|
5706
5850
|
for (const { file, lines } of results) {
|
|
5707
5851
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
5708
|
-
const color = exceedsThreshold ?
|
|
5709
|
-
console.log(`${color(file)} \u2192 ${
|
|
5852
|
+
const color = exceedsThreshold ? chalk71.red : chalk71.white;
|
|
5853
|
+
console.log(`${color(file)} \u2192 ${chalk71.cyan(lines)} lines`);
|
|
5710
5854
|
}
|
|
5711
5855
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
5712
5856
|
console.log(
|
|
5713
|
-
|
|
5857
|
+
chalk71.dim(`
|
|
5714
5858
|
Total: ${total} lines across ${files.length} files`)
|
|
5715
5859
|
);
|
|
5716
5860
|
if (hasViolation) {
|
|
@@ -5724,21 +5868,21 @@ async function analyze(pattern2) {
|
|
|
5724
5868
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
5725
5869
|
const files = findSourceFiles2(searchPattern);
|
|
5726
5870
|
if (files.length === 0) {
|
|
5727
|
-
console.log(
|
|
5871
|
+
console.log(chalk72.yellow("No files found matching pattern"));
|
|
5728
5872
|
return;
|
|
5729
5873
|
}
|
|
5730
5874
|
if (files.length === 1) {
|
|
5731
5875
|
const file = files[0];
|
|
5732
|
-
console.log(
|
|
5876
|
+
console.log(chalk72.bold.underline("SLOC"));
|
|
5733
5877
|
await sloc(file);
|
|
5734
5878
|
console.log();
|
|
5735
|
-
console.log(
|
|
5879
|
+
console.log(chalk72.bold.underline("Cyclomatic Complexity"));
|
|
5736
5880
|
await cyclomatic(file);
|
|
5737
5881
|
console.log();
|
|
5738
|
-
console.log(
|
|
5882
|
+
console.log(chalk72.bold.underline("Halstead Metrics"));
|
|
5739
5883
|
await halstead(file);
|
|
5740
5884
|
console.log();
|
|
5741
|
-
console.log(
|
|
5885
|
+
console.log(chalk72.bold.underline("Maintainability Index"));
|
|
5742
5886
|
await maintainability(file);
|
|
5743
5887
|
return;
|
|
5744
5888
|
}
|
|
@@ -5765,7 +5909,7 @@ function registerComplexity(program2) {
|
|
|
5765
5909
|
}
|
|
5766
5910
|
|
|
5767
5911
|
// src/commands/config/index.ts
|
|
5768
|
-
import
|
|
5912
|
+
import chalk73 from "chalk";
|
|
5769
5913
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
5770
5914
|
|
|
5771
5915
|
// src/commands/config/setNestedValue.ts
|
|
@@ -5828,7 +5972,7 @@ function formatIssuePath(issue, key) {
|
|
|
5828
5972
|
function printValidationErrors(issues, key) {
|
|
5829
5973
|
for (const issue of issues) {
|
|
5830
5974
|
console.error(
|
|
5831
|
-
|
|
5975
|
+
chalk73.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
5832
5976
|
);
|
|
5833
5977
|
}
|
|
5834
5978
|
}
|
|
@@ -5845,7 +5989,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
5845
5989
|
function assertNotGlobalOnly(key, global) {
|
|
5846
5990
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
5847
5991
|
console.error(
|
|
5848
|
-
|
|
5992
|
+
chalk73.red(
|
|
5849
5993
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
5850
5994
|
)
|
|
5851
5995
|
);
|
|
@@ -5868,7 +6012,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
5868
6012
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
5869
6013
|
const target = options2.global ? "global" : "project";
|
|
5870
6014
|
console.log(
|
|
5871
|
-
|
|
6015
|
+
chalk73.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
5872
6016
|
);
|
|
5873
6017
|
}
|
|
5874
6018
|
function configList() {
|
|
@@ -5877,7 +6021,7 @@ function configList() {
|
|
|
5877
6021
|
}
|
|
5878
6022
|
|
|
5879
6023
|
// src/commands/config/configGet.ts
|
|
5880
|
-
import
|
|
6024
|
+
import chalk74 from "chalk";
|
|
5881
6025
|
|
|
5882
6026
|
// src/commands/config/getNestedValue.ts
|
|
5883
6027
|
function isTraversable(value) {
|
|
@@ -5909,7 +6053,7 @@ function requireNestedValue(config, key) {
|
|
|
5909
6053
|
return value;
|
|
5910
6054
|
}
|
|
5911
6055
|
function exitKeyNotSet(key) {
|
|
5912
|
-
console.error(
|
|
6056
|
+
console.error(chalk74.red(`Key "${key}" is not set`));
|
|
5913
6057
|
process.exit(1);
|
|
5914
6058
|
}
|
|
5915
6059
|
|
|
@@ -5923,7 +6067,7 @@ function registerConfig(program2) {
|
|
|
5923
6067
|
|
|
5924
6068
|
// src/commands/deploy/redirect.ts
|
|
5925
6069
|
import { existsSync as existsSync22, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "fs";
|
|
5926
|
-
import
|
|
6070
|
+
import chalk75 from "chalk";
|
|
5927
6071
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
5928
6072
|
if (!window.location.pathname.endsWith('/')) {
|
|
5929
6073
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -5932,22 +6076,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
5932
6076
|
function redirect() {
|
|
5933
6077
|
const indexPath = "index.html";
|
|
5934
6078
|
if (!existsSync22(indexPath)) {
|
|
5935
|
-
console.log(
|
|
6079
|
+
console.log(chalk75.yellow("No index.html found"));
|
|
5936
6080
|
return;
|
|
5937
6081
|
}
|
|
5938
6082
|
const content = readFileSync19(indexPath, "utf-8");
|
|
5939
6083
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
5940
|
-
console.log(
|
|
6084
|
+
console.log(chalk75.dim("Trailing slash script already present"));
|
|
5941
6085
|
return;
|
|
5942
6086
|
}
|
|
5943
6087
|
const headCloseIndex = content.indexOf("</head>");
|
|
5944
6088
|
if (headCloseIndex === -1) {
|
|
5945
|
-
console.log(
|
|
6089
|
+
console.log(chalk75.red("Could not find </head> tag in index.html"));
|
|
5946
6090
|
return;
|
|
5947
6091
|
}
|
|
5948
6092
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
5949
6093
|
writeFileSync18(indexPath, newContent);
|
|
5950
|
-
console.log(
|
|
6094
|
+
console.log(chalk75.green("Added trailing slash redirect to index.html"));
|
|
5951
6095
|
}
|
|
5952
6096
|
|
|
5953
6097
|
// src/commands/registerDeploy.ts
|
|
@@ -5974,7 +6118,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
5974
6118
|
|
|
5975
6119
|
// src/commands/devlog/shared.ts
|
|
5976
6120
|
import { execSync as execSync18 } from "child_process";
|
|
5977
|
-
import
|
|
6121
|
+
import chalk76 from "chalk";
|
|
5978
6122
|
|
|
5979
6123
|
// src/shared/getRepoName.ts
|
|
5980
6124
|
import { existsSync as existsSync23, readFileSync as readFileSync20 } from "fs";
|
|
@@ -6083,13 +6227,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
6083
6227
|
}
|
|
6084
6228
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
6085
6229
|
for (const commit2 of commits) {
|
|
6086
|
-
console.log(` ${
|
|
6230
|
+
console.log(` ${chalk76.yellow(commit2.hash)} ${commit2.message}`);
|
|
6087
6231
|
if (verbose) {
|
|
6088
6232
|
const visibleFiles = commit2.files.filter(
|
|
6089
6233
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
6090
6234
|
);
|
|
6091
6235
|
for (const file of visibleFiles) {
|
|
6092
|
-
console.log(` ${
|
|
6236
|
+
console.log(` ${chalk76.dim(file)}`);
|
|
6093
6237
|
}
|
|
6094
6238
|
}
|
|
6095
6239
|
}
|
|
@@ -6114,15 +6258,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
6114
6258
|
}
|
|
6115
6259
|
|
|
6116
6260
|
// src/commands/devlog/list/printDateHeader.ts
|
|
6117
|
-
import
|
|
6261
|
+
import chalk77 from "chalk";
|
|
6118
6262
|
function printDateHeader(date, isSkipped, entries) {
|
|
6119
6263
|
if (isSkipped) {
|
|
6120
|
-
console.log(`${
|
|
6264
|
+
console.log(`${chalk77.bold.blue(date)} ${chalk77.dim("skipped")}`);
|
|
6121
6265
|
} else if (entries && entries.length > 0) {
|
|
6122
|
-
const entryInfo = entries.map((e) => `${
|
|
6123
|
-
console.log(`${
|
|
6266
|
+
const entryInfo = entries.map((e) => `${chalk77.green(e.version)} ${e.title}`).join(" | ");
|
|
6267
|
+
console.log(`${chalk77.bold.blue(date)} ${entryInfo}`);
|
|
6124
6268
|
} else {
|
|
6125
|
-
console.log(`${
|
|
6269
|
+
console.log(`${chalk77.bold.blue(date)} ${chalk77.red("\u26A0 devlog missing")}`);
|
|
6126
6270
|
}
|
|
6127
6271
|
}
|
|
6128
6272
|
|
|
@@ -6226,24 +6370,24 @@ function bumpVersion(version2, type) {
|
|
|
6226
6370
|
|
|
6227
6371
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
6228
6372
|
import { execSync as execSync21 } from "child_process";
|
|
6229
|
-
import
|
|
6373
|
+
import chalk79 from "chalk";
|
|
6230
6374
|
|
|
6231
6375
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
6232
|
-
import
|
|
6376
|
+
import chalk78 from "chalk";
|
|
6233
6377
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
6234
6378
|
if (conventional && firstHash) {
|
|
6235
6379
|
const version2 = getVersionAtCommit(firstHash);
|
|
6236
6380
|
if (version2) {
|
|
6237
|
-
console.log(`${
|
|
6381
|
+
console.log(`${chalk78.bold("version:")} ${stripToMinor(version2)}`);
|
|
6238
6382
|
} else {
|
|
6239
|
-
console.log(`${
|
|
6383
|
+
console.log(`${chalk78.bold("version:")} ${chalk78.red("unknown")}`);
|
|
6240
6384
|
}
|
|
6241
6385
|
} else if (patchVersion && minorVersion) {
|
|
6242
6386
|
console.log(
|
|
6243
|
-
`${
|
|
6387
|
+
`${chalk78.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
6244
6388
|
);
|
|
6245
6389
|
} else {
|
|
6246
|
-
console.log(`${
|
|
6390
|
+
console.log(`${chalk78.bold("version:")} v0.1 (initial)`);
|
|
6247
6391
|
}
|
|
6248
6392
|
}
|
|
6249
6393
|
|
|
@@ -6290,16 +6434,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
6290
6434
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
6291
6435
|
}
|
|
6292
6436
|
function logName(repoName) {
|
|
6293
|
-
console.log(`${
|
|
6437
|
+
console.log(`${chalk79.bold("name:")} ${repoName}`);
|
|
6294
6438
|
}
|
|
6295
6439
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
6296
6440
|
logName(ctx.repoName);
|
|
6297
6441
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
6298
|
-
console.log(
|
|
6442
|
+
console.log(chalk79.bold.blue(targetDate));
|
|
6299
6443
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
6300
6444
|
}
|
|
6301
6445
|
function logNoCommits(lastInfo) {
|
|
6302
|
-
console.log(
|
|
6446
|
+
console.log(chalk79.dim(noCommitsMessage(!!lastInfo)));
|
|
6303
6447
|
}
|
|
6304
6448
|
|
|
6305
6449
|
// src/commands/devlog/next/index.ts
|
|
@@ -6340,11 +6484,11 @@ function next2(options2) {
|
|
|
6340
6484
|
import { execSync as execSync22 } from "child_process";
|
|
6341
6485
|
|
|
6342
6486
|
// src/commands/devlog/repos/printReposTable.ts
|
|
6343
|
-
import
|
|
6487
|
+
import chalk80 from "chalk";
|
|
6344
6488
|
function colorStatus(status2) {
|
|
6345
|
-
if (status2 === "missing") return
|
|
6346
|
-
if (status2 === "outdated") return
|
|
6347
|
-
return
|
|
6489
|
+
if (status2 === "missing") return chalk80.red(status2);
|
|
6490
|
+
if (status2 === "outdated") return chalk80.yellow(status2);
|
|
6491
|
+
return chalk80.green(status2);
|
|
6348
6492
|
}
|
|
6349
6493
|
function formatRow(row, nameWidth) {
|
|
6350
6494
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -6358,8 +6502,8 @@ function printReposTable(rows) {
|
|
|
6358
6502
|
"Last Devlog".padEnd(11),
|
|
6359
6503
|
"Status"
|
|
6360
6504
|
].join(" ");
|
|
6361
|
-
console.log(
|
|
6362
|
-
console.log(
|
|
6505
|
+
console.log(chalk80.dim(header));
|
|
6506
|
+
console.log(chalk80.dim("-".repeat(header.length)));
|
|
6363
6507
|
for (const row of rows) {
|
|
6364
6508
|
console.log(formatRow(row, nameWidth));
|
|
6365
6509
|
}
|
|
@@ -6417,14 +6561,14 @@ function repos(options2) {
|
|
|
6417
6561
|
// src/commands/devlog/skip.ts
|
|
6418
6562
|
import { writeFileSync as writeFileSync19 } from "fs";
|
|
6419
6563
|
import { join as join22 } from "path";
|
|
6420
|
-
import
|
|
6564
|
+
import chalk81 from "chalk";
|
|
6421
6565
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
6422
6566
|
function getBlogConfigPath() {
|
|
6423
6567
|
return join22(BLOG_REPO_ROOT, "assist.yml");
|
|
6424
6568
|
}
|
|
6425
6569
|
function skip(date) {
|
|
6426
6570
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
6427
|
-
console.log(
|
|
6571
|
+
console.log(chalk81.red("Invalid date format. Use YYYY-MM-DD"));
|
|
6428
6572
|
process.exit(1);
|
|
6429
6573
|
}
|
|
6430
6574
|
const repoName = getRepoName();
|
|
@@ -6435,7 +6579,7 @@ function skip(date) {
|
|
|
6435
6579
|
const skipDays = skip2[repoName] ?? [];
|
|
6436
6580
|
if (skipDays.includes(date)) {
|
|
6437
6581
|
console.log(
|
|
6438
|
-
|
|
6582
|
+
chalk81.yellow(`${date} is already in skip list for ${repoName}`)
|
|
6439
6583
|
);
|
|
6440
6584
|
return;
|
|
6441
6585
|
}
|
|
@@ -6445,20 +6589,20 @@ function skip(date) {
|
|
|
6445
6589
|
devlog.skip = skip2;
|
|
6446
6590
|
config.devlog = devlog;
|
|
6447
6591
|
writeFileSync19(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
6448
|
-
console.log(
|
|
6592
|
+
console.log(chalk81.green(`Added ${date} to skip list for ${repoName}`));
|
|
6449
6593
|
}
|
|
6450
6594
|
|
|
6451
6595
|
// src/commands/devlog/version.ts
|
|
6452
|
-
import
|
|
6596
|
+
import chalk82 from "chalk";
|
|
6453
6597
|
function version() {
|
|
6454
6598
|
const config = loadConfig();
|
|
6455
6599
|
const name = getRepoName();
|
|
6456
6600
|
const lastInfo = getLastVersionInfo(name, config);
|
|
6457
6601
|
const lastVersion = lastInfo?.version ?? null;
|
|
6458
6602
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
6459
|
-
console.log(`${
|
|
6460
|
-
console.log(`${
|
|
6461
|
-
console.log(`${
|
|
6603
|
+
console.log(`${chalk82.bold("name:")} ${name}`);
|
|
6604
|
+
console.log(`${chalk82.bold("last:")} ${lastVersion ?? chalk82.dim("none")}`);
|
|
6605
|
+
console.log(`${chalk82.bold("next:")} ${nextVersion ?? chalk82.dim("none")}`);
|
|
6462
6606
|
}
|
|
6463
6607
|
|
|
6464
6608
|
// src/commands/registerDevlog.ts
|
|
@@ -6482,7 +6626,7 @@ function registerDevlog(program2) {
|
|
|
6482
6626
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
6483
6627
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
6484
6628
|
import { join as join23 } from "path";
|
|
6485
|
-
import
|
|
6629
|
+
import chalk83 from "chalk";
|
|
6486
6630
|
|
|
6487
6631
|
// src/shared/findRepoRoot.ts
|
|
6488
6632
|
import { existsSync as existsSync24 } from "fs";
|
|
@@ -6545,14 +6689,14 @@ function checkBuildLocks(startDir) {
|
|
|
6545
6689
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
6546
6690
|
if (locked) {
|
|
6547
6691
|
console.error(
|
|
6548
|
-
|
|
6692
|
+
chalk83.red("Build output locked (is VS debugging?): ") + locked
|
|
6549
6693
|
);
|
|
6550
6694
|
process.exit(1);
|
|
6551
6695
|
}
|
|
6552
6696
|
}
|
|
6553
6697
|
async function checkBuildLocksCommand() {
|
|
6554
6698
|
checkBuildLocks();
|
|
6555
|
-
console.log(
|
|
6699
|
+
console.log(chalk83.green("No build locks detected"));
|
|
6556
6700
|
}
|
|
6557
6701
|
|
|
6558
6702
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -6651,30 +6795,30 @@ function escapeRegex(s) {
|
|
|
6651
6795
|
}
|
|
6652
6796
|
|
|
6653
6797
|
// src/commands/dotnet/printTree.ts
|
|
6654
|
-
import
|
|
6798
|
+
import chalk84 from "chalk";
|
|
6655
6799
|
function printNodes(nodes, prefix2) {
|
|
6656
6800
|
for (let i = 0; i < nodes.length; i++) {
|
|
6657
6801
|
const isLast = i === nodes.length - 1;
|
|
6658
6802
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
6659
6803
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
6660
6804
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
6661
|
-
const label2 = isMissing ?
|
|
6805
|
+
const label2 = isMissing ? chalk84.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
6662
6806
|
console.log(`${prefix2}${connector}${label2}`);
|
|
6663
6807
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
6664
6808
|
}
|
|
6665
6809
|
}
|
|
6666
6810
|
function printTree(tree, totalCount, solutions) {
|
|
6667
|
-
console.log(
|
|
6668
|
-
console.log(
|
|
6811
|
+
console.log(chalk84.bold("\nProject Dependency Tree"));
|
|
6812
|
+
console.log(chalk84.cyan(tree.relativePath));
|
|
6669
6813
|
printNodes(tree.children, "");
|
|
6670
|
-
console.log(
|
|
6814
|
+
console.log(chalk84.dim(`
|
|
6671
6815
|
${totalCount} projects total (including root)`));
|
|
6672
|
-
console.log(
|
|
6816
|
+
console.log(chalk84.bold("\nSolution Membership"));
|
|
6673
6817
|
if (solutions.length === 0) {
|
|
6674
|
-
console.log(
|
|
6818
|
+
console.log(chalk84.yellow(" Not found in any .sln"));
|
|
6675
6819
|
} else {
|
|
6676
6820
|
for (const sln of solutions) {
|
|
6677
|
-
console.log(` ${
|
|
6821
|
+
console.log(` ${chalk84.green(sln)}`);
|
|
6678
6822
|
}
|
|
6679
6823
|
}
|
|
6680
6824
|
console.log();
|
|
@@ -6703,16 +6847,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
6703
6847
|
// src/commands/dotnet/resolveCsproj.ts
|
|
6704
6848
|
import { existsSync as existsSync25 } from "fs";
|
|
6705
6849
|
import path24 from "path";
|
|
6706
|
-
import
|
|
6850
|
+
import chalk85 from "chalk";
|
|
6707
6851
|
function resolveCsproj(csprojPath) {
|
|
6708
6852
|
const resolved = path24.resolve(csprojPath);
|
|
6709
6853
|
if (!existsSync25(resolved)) {
|
|
6710
|
-
console.error(
|
|
6854
|
+
console.error(chalk85.red(`File not found: ${resolved}`));
|
|
6711
6855
|
process.exit(1);
|
|
6712
6856
|
}
|
|
6713
6857
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
6714
6858
|
if (!repoRoot) {
|
|
6715
|
-
console.error(
|
|
6859
|
+
console.error(chalk85.red("Could not find git repository root"));
|
|
6716
6860
|
process.exit(1);
|
|
6717
6861
|
}
|
|
6718
6862
|
return { resolved, repoRoot };
|
|
@@ -6762,12 +6906,12 @@ function getChangedCsFiles(scope) {
|
|
|
6762
6906
|
}
|
|
6763
6907
|
|
|
6764
6908
|
// src/commands/dotnet/inSln.ts
|
|
6765
|
-
import
|
|
6909
|
+
import chalk86 from "chalk";
|
|
6766
6910
|
async function inSln(csprojPath) {
|
|
6767
6911
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
6768
6912
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
6769
6913
|
if (solutions.length === 0) {
|
|
6770
|
-
console.log(
|
|
6914
|
+
console.log(chalk86.yellow("Not found in any .sln file"));
|
|
6771
6915
|
process.exit(1);
|
|
6772
6916
|
}
|
|
6773
6917
|
for (const sln of solutions) {
|
|
@@ -6776,7 +6920,7 @@ async function inSln(csprojPath) {
|
|
|
6776
6920
|
}
|
|
6777
6921
|
|
|
6778
6922
|
// src/commands/dotnet/inspect.ts
|
|
6779
|
-
import
|
|
6923
|
+
import chalk92 from "chalk";
|
|
6780
6924
|
|
|
6781
6925
|
// src/shared/formatElapsed.ts
|
|
6782
6926
|
function formatElapsed(ms) {
|
|
@@ -6788,12 +6932,12 @@ function formatElapsed(ms) {
|
|
|
6788
6932
|
}
|
|
6789
6933
|
|
|
6790
6934
|
// src/commands/dotnet/displayIssues.ts
|
|
6791
|
-
import
|
|
6935
|
+
import chalk87 from "chalk";
|
|
6792
6936
|
var SEVERITY_COLOR = {
|
|
6793
|
-
ERROR:
|
|
6794
|
-
WARNING:
|
|
6795
|
-
SUGGESTION:
|
|
6796
|
-
HINT:
|
|
6937
|
+
ERROR: chalk87.red,
|
|
6938
|
+
WARNING: chalk87.yellow,
|
|
6939
|
+
SUGGESTION: chalk87.cyan,
|
|
6940
|
+
HINT: chalk87.dim
|
|
6797
6941
|
};
|
|
6798
6942
|
function groupByFile(issues) {
|
|
6799
6943
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -6809,15 +6953,15 @@ function groupByFile(issues) {
|
|
|
6809
6953
|
}
|
|
6810
6954
|
function displayIssues(issues) {
|
|
6811
6955
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
6812
|
-
console.log(
|
|
6956
|
+
console.log(chalk87.bold(file));
|
|
6813
6957
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
6814
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
6958
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk87.white;
|
|
6815
6959
|
console.log(
|
|
6816
|
-
` ${
|
|
6960
|
+
` ${chalk87.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
6817
6961
|
);
|
|
6818
6962
|
}
|
|
6819
6963
|
}
|
|
6820
|
-
console.log(
|
|
6964
|
+
console.log(chalk87.dim(`
|
|
6821
6965
|
${issues.length} issue(s) found`));
|
|
6822
6966
|
}
|
|
6823
6967
|
|
|
@@ -6876,12 +7020,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
6876
7020
|
// src/commands/dotnet/resolveSolution.ts
|
|
6877
7021
|
import { existsSync as existsSync26 } from "fs";
|
|
6878
7022
|
import path25 from "path";
|
|
6879
|
-
import
|
|
7023
|
+
import chalk89 from "chalk";
|
|
6880
7024
|
|
|
6881
7025
|
// src/commands/dotnet/findSolution.ts
|
|
6882
7026
|
import { readdirSync as readdirSync4 } from "fs";
|
|
6883
7027
|
import { dirname as dirname16, join as join24 } from "path";
|
|
6884
|
-
import
|
|
7028
|
+
import chalk88 from "chalk";
|
|
6885
7029
|
function findSlnInDir(dir) {
|
|
6886
7030
|
try {
|
|
6887
7031
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join24(dir, f));
|
|
@@ -6897,17 +7041,17 @@ function findSolution() {
|
|
|
6897
7041
|
const slnFiles = findSlnInDir(current);
|
|
6898
7042
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
6899
7043
|
if (slnFiles.length > 1) {
|
|
6900
|
-
console.error(
|
|
7044
|
+
console.error(chalk88.red(`Multiple .sln files found in ${current}:`));
|
|
6901
7045
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
6902
7046
|
console.error(
|
|
6903
|
-
|
|
7047
|
+
chalk88.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
6904
7048
|
);
|
|
6905
7049
|
process.exit(1);
|
|
6906
7050
|
}
|
|
6907
7051
|
if (current === ceiling) break;
|
|
6908
7052
|
current = dirname16(current);
|
|
6909
7053
|
}
|
|
6910
|
-
console.error(
|
|
7054
|
+
console.error(chalk88.red("No .sln file found between cwd and repo root"));
|
|
6911
7055
|
process.exit(1);
|
|
6912
7056
|
}
|
|
6913
7057
|
|
|
@@ -6916,7 +7060,7 @@ function resolveSolution(sln) {
|
|
|
6916
7060
|
if (sln) {
|
|
6917
7061
|
const resolved = path25.resolve(sln);
|
|
6918
7062
|
if (!existsSync26(resolved)) {
|
|
6919
|
-
console.error(
|
|
7063
|
+
console.error(chalk89.red(`Solution file not found: ${resolved}`));
|
|
6920
7064
|
process.exit(1);
|
|
6921
7065
|
}
|
|
6922
7066
|
return resolved;
|
|
@@ -6958,14 +7102,14 @@ import { execSync as execSync24 } from "child_process";
|
|
|
6958
7102
|
import { existsSync as existsSync27, readFileSync as readFileSync24, unlinkSync as unlinkSync5 } from "fs";
|
|
6959
7103
|
import { tmpdir as tmpdir2 } from "os";
|
|
6960
7104
|
import path26 from "path";
|
|
6961
|
-
import
|
|
7105
|
+
import chalk90 from "chalk";
|
|
6962
7106
|
function assertJbInstalled() {
|
|
6963
7107
|
try {
|
|
6964
7108
|
execSync24("jb inspectcode --version", { stdio: "pipe" });
|
|
6965
7109
|
} catch {
|
|
6966
|
-
console.error(
|
|
7110
|
+
console.error(chalk90.red("jb is not installed. Install with:"));
|
|
6967
7111
|
console.error(
|
|
6968
|
-
|
|
7112
|
+
chalk90.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
6969
7113
|
);
|
|
6970
7114
|
process.exit(1);
|
|
6971
7115
|
}
|
|
@@ -6983,11 +7127,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
6983
7127
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
6984
7128
|
process.stderr.write(err.stderr);
|
|
6985
7129
|
}
|
|
6986
|
-
console.error(
|
|
7130
|
+
console.error(chalk90.red("jb inspectcode failed"));
|
|
6987
7131
|
process.exit(1);
|
|
6988
7132
|
}
|
|
6989
7133
|
if (!existsSync27(reportPath)) {
|
|
6990
|
-
console.error(
|
|
7134
|
+
console.error(chalk90.red("Report file not generated"));
|
|
6991
7135
|
process.exit(1);
|
|
6992
7136
|
}
|
|
6993
7137
|
const xml = readFileSync24(reportPath, "utf-8");
|
|
@@ -6997,7 +7141,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
6997
7141
|
|
|
6998
7142
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
6999
7143
|
import { execSync as execSync25 } from "child_process";
|
|
7000
|
-
import
|
|
7144
|
+
import chalk91 from "chalk";
|
|
7001
7145
|
function resolveMsbuildPath() {
|
|
7002
7146
|
const config = loadConfig();
|
|
7003
7147
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -7008,9 +7152,9 @@ function assertMsbuildInstalled() {
|
|
|
7008
7152
|
try {
|
|
7009
7153
|
execSync25(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
7010
7154
|
} catch {
|
|
7011
|
-
console.error(
|
|
7155
|
+
console.error(chalk91.red(`msbuild not found at: ${msbuild}`));
|
|
7012
7156
|
console.error(
|
|
7013
|
-
|
|
7157
|
+
chalk91.yellow(
|
|
7014
7158
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
7015
7159
|
)
|
|
7016
7160
|
);
|
|
@@ -7057,17 +7201,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
7057
7201
|
// src/commands/dotnet/inspect.ts
|
|
7058
7202
|
function logScope(changedFiles) {
|
|
7059
7203
|
if (changedFiles === null) {
|
|
7060
|
-
console.log(
|
|
7204
|
+
console.log(chalk92.dim("Inspecting full solution..."));
|
|
7061
7205
|
} else {
|
|
7062
7206
|
console.log(
|
|
7063
|
-
|
|
7207
|
+
chalk92.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
7064
7208
|
);
|
|
7065
7209
|
}
|
|
7066
7210
|
}
|
|
7067
7211
|
function reportResults(issues, elapsed) {
|
|
7068
7212
|
if (issues.length > 0) displayIssues(issues);
|
|
7069
|
-
else console.log(
|
|
7070
|
-
console.log(
|
|
7213
|
+
else console.log(chalk92.green("No issues found"));
|
|
7214
|
+
console.log(chalk92.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
7071
7215
|
if (issues.length > 0) process.exit(1);
|
|
7072
7216
|
}
|
|
7073
7217
|
async function inspect(sln, options2) {
|
|
@@ -7078,7 +7222,7 @@ async function inspect(sln, options2) {
|
|
|
7078
7222
|
const scope = parseScope(options2.scope);
|
|
7079
7223
|
const changedFiles = getChangedCsFiles(scope);
|
|
7080
7224
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
7081
|
-
console.log(
|
|
7225
|
+
console.log(chalk92.green("No changed .cs files found"));
|
|
7082
7226
|
return;
|
|
7083
7227
|
}
|
|
7084
7228
|
logScope(changedFiles);
|
|
@@ -7104,7 +7248,7 @@ function registerDotnet(program2) {
|
|
|
7104
7248
|
}
|
|
7105
7249
|
|
|
7106
7250
|
// src/commands/jira/acceptanceCriteria.ts
|
|
7107
|
-
import
|
|
7251
|
+
import chalk94 from "chalk";
|
|
7108
7252
|
|
|
7109
7253
|
// src/commands/jira/adfToText.ts
|
|
7110
7254
|
function renderInline(node) {
|
|
@@ -7165,7 +7309,7 @@ function adfToText(doc) {
|
|
|
7165
7309
|
|
|
7166
7310
|
// src/commands/jira/fetchIssue.ts
|
|
7167
7311
|
import { execSync as execSync26 } from "child_process";
|
|
7168
|
-
import
|
|
7312
|
+
import chalk93 from "chalk";
|
|
7169
7313
|
function fetchIssue(issueKey, fields) {
|
|
7170
7314
|
let result;
|
|
7171
7315
|
try {
|
|
@@ -7178,15 +7322,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
7178
7322
|
const stderr = error.stderr;
|
|
7179
7323
|
if (stderr.includes("unauthorized")) {
|
|
7180
7324
|
console.error(
|
|
7181
|
-
|
|
7325
|
+
chalk93.red("Jira authentication expired."),
|
|
7182
7326
|
"Run",
|
|
7183
|
-
|
|
7327
|
+
chalk93.cyan("assist jira auth"),
|
|
7184
7328
|
"to re-authenticate."
|
|
7185
7329
|
);
|
|
7186
7330
|
process.exit(1);
|
|
7187
7331
|
}
|
|
7188
7332
|
}
|
|
7189
|
-
console.error(
|
|
7333
|
+
console.error(chalk93.red(`Failed to fetch ${issueKey}.`));
|
|
7190
7334
|
process.exit(1);
|
|
7191
7335
|
}
|
|
7192
7336
|
return JSON.parse(result);
|
|
@@ -7200,7 +7344,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
7200
7344
|
const parsed = fetchIssue(issueKey, field);
|
|
7201
7345
|
const acValue = parsed?.fields?.[field];
|
|
7202
7346
|
if (!acValue) {
|
|
7203
|
-
console.log(
|
|
7347
|
+
console.log(chalk94.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
7204
7348
|
return;
|
|
7205
7349
|
}
|
|
7206
7350
|
if (typeof acValue === "string") {
|
|
@@ -7295,14 +7439,14 @@ async function jiraAuth() {
|
|
|
7295
7439
|
}
|
|
7296
7440
|
|
|
7297
7441
|
// src/commands/jira/viewIssue.ts
|
|
7298
|
-
import
|
|
7442
|
+
import chalk95 from "chalk";
|
|
7299
7443
|
function viewIssue(issueKey) {
|
|
7300
7444
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
7301
7445
|
const fields = parsed?.fields;
|
|
7302
7446
|
const summary = fields?.summary;
|
|
7303
7447
|
const description = fields?.description;
|
|
7304
7448
|
if (summary) {
|
|
7305
|
-
console.log(
|
|
7449
|
+
console.log(chalk95.bold(summary));
|
|
7306
7450
|
}
|
|
7307
7451
|
if (description) {
|
|
7308
7452
|
if (summary) console.log();
|
|
@@ -7316,7 +7460,7 @@ function viewIssue(issueKey) {
|
|
|
7316
7460
|
}
|
|
7317
7461
|
if (!summary && !description) {
|
|
7318
7462
|
console.log(
|
|
7319
|
-
|
|
7463
|
+
chalk95.yellow(`No summary or description found on ${issueKey}.`)
|
|
7320
7464
|
);
|
|
7321
7465
|
}
|
|
7322
7466
|
}
|
|
@@ -7330,7 +7474,7 @@ function registerJira(program2) {
|
|
|
7330
7474
|
}
|
|
7331
7475
|
|
|
7332
7476
|
// src/commands/news/add/index.ts
|
|
7333
|
-
import
|
|
7477
|
+
import chalk96 from "chalk";
|
|
7334
7478
|
import enquirer8 from "enquirer";
|
|
7335
7479
|
async function add2(url) {
|
|
7336
7480
|
if (!url) {
|
|
@@ -7353,17 +7497,17 @@ async function add2(url) {
|
|
|
7353
7497
|
const news = config.news ?? {};
|
|
7354
7498
|
const feeds = news.feeds ?? [];
|
|
7355
7499
|
if (feeds.includes(url)) {
|
|
7356
|
-
console.log(
|
|
7500
|
+
console.log(chalk96.yellow("Feed already exists in config"));
|
|
7357
7501
|
return;
|
|
7358
7502
|
}
|
|
7359
7503
|
feeds.push(url);
|
|
7360
7504
|
config.news = { ...news, feeds };
|
|
7361
7505
|
saveGlobalConfig(config);
|
|
7362
|
-
console.log(
|
|
7506
|
+
console.log(chalk96.green(`Added feed: ${url}`));
|
|
7363
7507
|
}
|
|
7364
7508
|
|
|
7365
7509
|
// src/commands/news/web/handleRequest.ts
|
|
7366
|
-
import
|
|
7510
|
+
import chalk97 from "chalk";
|
|
7367
7511
|
|
|
7368
7512
|
// src/commands/news/web/shared.ts
|
|
7369
7513
|
import { decodeHTML } from "entities";
|
|
@@ -7499,17 +7643,17 @@ function prefetch() {
|
|
|
7499
7643
|
const config = loadConfig();
|
|
7500
7644
|
const total = config.news.feeds.length;
|
|
7501
7645
|
if (total === 0) return;
|
|
7502
|
-
process.stdout.write(
|
|
7646
|
+
process.stdout.write(chalk97.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
7503
7647
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
7504
7648
|
const width = 20;
|
|
7505
7649
|
const filled = Math.round(done2 / t * width);
|
|
7506
7650
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
7507
7651
|
process.stdout.write(
|
|
7508
|
-
`\r${
|
|
7652
|
+
`\r${chalk97.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
7509
7653
|
);
|
|
7510
7654
|
}).then((items) => {
|
|
7511
7655
|
process.stdout.write(
|
|
7512
|
-
`\r${
|
|
7656
|
+
`\r${chalk97.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
7513
7657
|
`
|
|
7514
7658
|
);
|
|
7515
7659
|
cachedItems = items;
|
|
@@ -7870,20 +8014,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
7870
8014
|
}
|
|
7871
8015
|
|
|
7872
8016
|
// src/commands/prs/listComments/printComments.ts
|
|
7873
|
-
import
|
|
8017
|
+
import chalk98 from "chalk";
|
|
7874
8018
|
function formatForHuman(comment3) {
|
|
7875
8019
|
if (comment3.type === "review") {
|
|
7876
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
8020
|
+
const stateColor = comment3.state === "APPROVED" ? chalk98.green : comment3.state === "CHANGES_REQUESTED" ? chalk98.red : chalk98.yellow;
|
|
7877
8021
|
return [
|
|
7878
|
-
`${
|
|
8022
|
+
`${chalk98.cyan("Review")} by ${chalk98.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
7879
8023
|
comment3.body,
|
|
7880
8024
|
""
|
|
7881
8025
|
].join("\n");
|
|
7882
8026
|
}
|
|
7883
8027
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
7884
8028
|
return [
|
|
7885
|
-
`${
|
|
7886
|
-
|
|
8029
|
+
`${chalk98.cyan("Line comment")} by ${chalk98.bold(comment3.user)} on ${chalk98.dim(`${comment3.path}${location}`)}`,
|
|
8030
|
+
chalk98.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
7887
8031
|
comment3.body,
|
|
7888
8032
|
""
|
|
7889
8033
|
].join("\n");
|
|
@@ -7973,13 +8117,13 @@ import { execSync as execSync33 } from "child_process";
|
|
|
7973
8117
|
import enquirer9 from "enquirer";
|
|
7974
8118
|
|
|
7975
8119
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
7976
|
-
import
|
|
8120
|
+
import chalk99 from "chalk";
|
|
7977
8121
|
var STATUS_MAP = {
|
|
7978
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
7979
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
8122
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk99.magenta("merged"), date: pr.mergedAt } : null,
|
|
8123
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk99.red("closed"), date: pr.closedAt } : null
|
|
7980
8124
|
};
|
|
7981
8125
|
function defaultStatus(pr) {
|
|
7982
|
-
return { label:
|
|
8126
|
+
return { label: chalk99.green("opened"), date: pr.createdAt };
|
|
7983
8127
|
}
|
|
7984
8128
|
function getStatus2(pr) {
|
|
7985
8129
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -7988,11 +8132,11 @@ function formatDate(dateStr) {
|
|
|
7988
8132
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
7989
8133
|
}
|
|
7990
8134
|
function formatPrHeader(pr, status2) {
|
|
7991
|
-
return `${
|
|
8135
|
+
return `${chalk99.cyan(`#${pr.number}`)} ${pr.title} ${chalk99.dim(`(${pr.author.login},`)} ${status2.label} ${chalk99.dim(`${formatDate(status2.date)})`)}`;
|
|
7992
8136
|
}
|
|
7993
8137
|
function logPrDetails(pr) {
|
|
7994
8138
|
console.log(
|
|
7995
|
-
|
|
8139
|
+
chalk99.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
7996
8140
|
);
|
|
7997
8141
|
console.log();
|
|
7998
8142
|
}
|
|
@@ -8158,10 +8302,10 @@ function registerPrs(program2) {
|
|
|
8158
8302
|
}
|
|
8159
8303
|
|
|
8160
8304
|
// src/commands/ravendb/ravendbAuth.ts
|
|
8161
|
-
import
|
|
8305
|
+
import chalk105 from "chalk";
|
|
8162
8306
|
|
|
8163
8307
|
// src/shared/createConnectionAuth.ts
|
|
8164
|
-
import
|
|
8308
|
+
import chalk100 from "chalk";
|
|
8165
8309
|
function listConnections(connections, format2) {
|
|
8166
8310
|
if (connections.length === 0) {
|
|
8167
8311
|
console.log("No connections configured.");
|
|
@@ -8174,7 +8318,7 @@ function listConnections(connections, format2) {
|
|
|
8174
8318
|
function removeConnection(connections, name, save) {
|
|
8175
8319
|
const filtered = connections.filter((c) => c.name !== name);
|
|
8176
8320
|
if (filtered.length === connections.length) {
|
|
8177
|
-
console.error(
|
|
8321
|
+
console.error(chalk100.red(`Connection "${name}" not found.`));
|
|
8178
8322
|
process.exit(1);
|
|
8179
8323
|
}
|
|
8180
8324
|
save(filtered);
|
|
@@ -8220,15 +8364,15 @@ function saveConnections(connections) {
|
|
|
8220
8364
|
}
|
|
8221
8365
|
|
|
8222
8366
|
// src/commands/ravendb/promptConnection.ts
|
|
8223
|
-
import
|
|
8367
|
+
import chalk103 from "chalk";
|
|
8224
8368
|
|
|
8225
8369
|
// src/commands/ravendb/selectOpSecret.ts
|
|
8226
|
-
import
|
|
8370
|
+
import chalk102 from "chalk";
|
|
8227
8371
|
import Enquirer2 from "enquirer";
|
|
8228
8372
|
|
|
8229
8373
|
// src/commands/ravendb/searchItems.ts
|
|
8230
8374
|
import { execSync as execSync35 } from "child_process";
|
|
8231
|
-
import
|
|
8375
|
+
import chalk101 from "chalk";
|
|
8232
8376
|
function opExec(args) {
|
|
8233
8377
|
return execSync35(`op ${args}`, {
|
|
8234
8378
|
encoding: "utf-8",
|
|
@@ -8241,7 +8385,7 @@ function searchItems(search2) {
|
|
|
8241
8385
|
items = JSON.parse(opExec("item list --format=json"));
|
|
8242
8386
|
} catch {
|
|
8243
8387
|
console.error(
|
|
8244
|
-
|
|
8388
|
+
chalk101.red(
|
|
8245
8389
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
8246
8390
|
)
|
|
8247
8391
|
);
|
|
@@ -8255,7 +8399,7 @@ function getItemFields(itemId) {
|
|
|
8255
8399
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
8256
8400
|
return item.fields.filter((f) => f.reference && f.label);
|
|
8257
8401
|
} catch {
|
|
8258
|
-
console.error(
|
|
8402
|
+
console.error(chalk101.red("Failed to get item details from 1Password."));
|
|
8259
8403
|
process.exit(1);
|
|
8260
8404
|
}
|
|
8261
8405
|
}
|
|
@@ -8274,7 +8418,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8274
8418
|
}).run();
|
|
8275
8419
|
const items = searchItems(search2);
|
|
8276
8420
|
if (items.length === 0) {
|
|
8277
|
-
console.error(
|
|
8421
|
+
console.error(chalk102.red(`No items found matching "${search2}".`));
|
|
8278
8422
|
process.exit(1);
|
|
8279
8423
|
}
|
|
8280
8424
|
const itemId = await selectOne(
|
|
@@ -8283,7 +8427,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8283
8427
|
);
|
|
8284
8428
|
const fields = getItemFields(itemId);
|
|
8285
8429
|
if (fields.length === 0) {
|
|
8286
|
-
console.error(
|
|
8430
|
+
console.error(chalk102.red("No fields with references found on this item."));
|
|
8287
8431
|
process.exit(1);
|
|
8288
8432
|
}
|
|
8289
8433
|
const ref = await selectOne(
|
|
@@ -8297,7 +8441,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8297
8441
|
async function promptConnection(existingNames) {
|
|
8298
8442
|
const name = await promptInput("name", "Connection name:");
|
|
8299
8443
|
if (existingNames.includes(name)) {
|
|
8300
|
-
console.error(
|
|
8444
|
+
console.error(chalk103.red(`Connection "${name}" already exists.`));
|
|
8301
8445
|
process.exit(1);
|
|
8302
8446
|
}
|
|
8303
8447
|
const url = await promptInput(
|
|
@@ -8306,22 +8450,22 @@ async function promptConnection(existingNames) {
|
|
|
8306
8450
|
);
|
|
8307
8451
|
const database = await promptInput("database", "Database name:");
|
|
8308
8452
|
if (!name || !url || !database) {
|
|
8309
|
-
console.error(
|
|
8453
|
+
console.error(chalk103.red("All fields are required."));
|
|
8310
8454
|
process.exit(1);
|
|
8311
8455
|
}
|
|
8312
8456
|
const apiKeyRef = await selectOpSecret();
|
|
8313
|
-
console.log(
|
|
8457
|
+
console.log(chalk103.dim(`Using: ${apiKeyRef}`));
|
|
8314
8458
|
return { name, url, database, apiKeyRef };
|
|
8315
8459
|
}
|
|
8316
8460
|
|
|
8317
8461
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
8318
|
-
import
|
|
8462
|
+
import chalk104 from "chalk";
|
|
8319
8463
|
function ravendbSetConnection(name) {
|
|
8320
8464
|
const raw = loadGlobalConfigRaw();
|
|
8321
8465
|
const ravendb = raw.ravendb ?? {};
|
|
8322
8466
|
const connections = ravendb.connections ?? [];
|
|
8323
8467
|
if (!connections.some((c) => c.name === name)) {
|
|
8324
|
-
console.error(
|
|
8468
|
+
console.error(chalk104.red(`Connection "${name}" not found.`));
|
|
8325
8469
|
console.error(
|
|
8326
8470
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
8327
8471
|
);
|
|
@@ -8337,16 +8481,16 @@ function ravendbSetConnection(name) {
|
|
|
8337
8481
|
var ravendbAuth = createConnectionAuth({
|
|
8338
8482
|
load: loadConnections,
|
|
8339
8483
|
save: saveConnections,
|
|
8340
|
-
format: (c) => `${
|
|
8484
|
+
format: (c) => `${chalk105.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
8341
8485
|
promptNew: promptConnection,
|
|
8342
8486
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
8343
8487
|
});
|
|
8344
8488
|
|
|
8345
8489
|
// src/commands/ravendb/ravendbCollections.ts
|
|
8346
|
-
import
|
|
8490
|
+
import chalk109 from "chalk";
|
|
8347
8491
|
|
|
8348
8492
|
// src/commands/ravendb/ravenFetch.ts
|
|
8349
|
-
import
|
|
8493
|
+
import chalk107 from "chalk";
|
|
8350
8494
|
|
|
8351
8495
|
// src/commands/ravendb/getAccessToken.ts
|
|
8352
8496
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -8383,10 +8527,10 @@ ${errorText}`
|
|
|
8383
8527
|
|
|
8384
8528
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
8385
8529
|
import { execSync as execSync36 } from "child_process";
|
|
8386
|
-
import
|
|
8530
|
+
import chalk106 from "chalk";
|
|
8387
8531
|
function resolveOpSecret(reference) {
|
|
8388
8532
|
if (!reference.startsWith("op://")) {
|
|
8389
|
-
console.error(
|
|
8533
|
+
console.error(chalk106.red(`Invalid secret reference: must start with op://`));
|
|
8390
8534
|
process.exit(1);
|
|
8391
8535
|
}
|
|
8392
8536
|
try {
|
|
@@ -8396,7 +8540,7 @@ function resolveOpSecret(reference) {
|
|
|
8396
8540
|
}).trim();
|
|
8397
8541
|
} catch {
|
|
8398
8542
|
console.error(
|
|
8399
|
-
|
|
8543
|
+
chalk106.red(
|
|
8400
8544
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
8401
8545
|
)
|
|
8402
8546
|
);
|
|
@@ -8423,7 +8567,7 @@ async function ravenFetch(connection, path50) {
|
|
|
8423
8567
|
if (!response.ok) {
|
|
8424
8568
|
const body = await response.text();
|
|
8425
8569
|
console.error(
|
|
8426
|
-
|
|
8570
|
+
chalk107.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
8427
8571
|
);
|
|
8428
8572
|
console.error(body.substring(0, 500));
|
|
8429
8573
|
process.exit(1);
|
|
@@ -8432,7 +8576,7 @@ async function ravenFetch(connection, path50) {
|
|
|
8432
8576
|
}
|
|
8433
8577
|
|
|
8434
8578
|
// src/commands/ravendb/resolveConnection.ts
|
|
8435
|
-
import
|
|
8579
|
+
import chalk108 from "chalk";
|
|
8436
8580
|
function loadRavendb() {
|
|
8437
8581
|
const raw = loadGlobalConfigRaw();
|
|
8438
8582
|
const ravendb = raw.ravendb;
|
|
@@ -8446,7 +8590,7 @@ function resolveConnection(name) {
|
|
|
8446
8590
|
const connectionName = name ?? defaultConnection;
|
|
8447
8591
|
if (!connectionName) {
|
|
8448
8592
|
console.error(
|
|
8449
|
-
|
|
8593
|
+
chalk108.red(
|
|
8450
8594
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
8451
8595
|
)
|
|
8452
8596
|
);
|
|
@@ -8454,7 +8598,7 @@ function resolveConnection(name) {
|
|
|
8454
8598
|
}
|
|
8455
8599
|
const connection = connections.find((c) => c.name === connectionName);
|
|
8456
8600
|
if (!connection) {
|
|
8457
|
-
console.error(
|
|
8601
|
+
console.error(chalk108.red(`Connection "${connectionName}" not found.`));
|
|
8458
8602
|
console.error(
|
|
8459
8603
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
8460
8604
|
);
|
|
@@ -8485,15 +8629,15 @@ async function ravendbCollections(connectionName) {
|
|
|
8485
8629
|
return;
|
|
8486
8630
|
}
|
|
8487
8631
|
for (const c of collections) {
|
|
8488
|
-
console.log(`${
|
|
8632
|
+
console.log(`${chalk109.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
8489
8633
|
}
|
|
8490
8634
|
}
|
|
8491
8635
|
|
|
8492
8636
|
// src/commands/ravendb/ravendbQuery.ts
|
|
8493
|
-
import
|
|
8637
|
+
import chalk111 from "chalk";
|
|
8494
8638
|
|
|
8495
8639
|
// src/commands/ravendb/fetchAllPages.ts
|
|
8496
|
-
import
|
|
8640
|
+
import chalk110 from "chalk";
|
|
8497
8641
|
|
|
8498
8642
|
// src/commands/ravendb/buildQueryPath.ts
|
|
8499
8643
|
function buildQueryPath(opts) {
|
|
@@ -8531,7 +8675,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8531
8675
|
allResults.push(...results);
|
|
8532
8676
|
start3 += results.length;
|
|
8533
8677
|
process.stderr.write(
|
|
8534
|
-
`\r${
|
|
8678
|
+
`\r${chalk110.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
8535
8679
|
);
|
|
8536
8680
|
if (start3 >= totalResults) break;
|
|
8537
8681
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -8546,7 +8690,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8546
8690
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
8547
8691
|
const resolved = resolveArgs(connectionName, collection);
|
|
8548
8692
|
if (!resolved.collection && !options2.query) {
|
|
8549
|
-
console.error(
|
|
8693
|
+
console.error(chalk111.red("Provide a collection name or --query filter."));
|
|
8550
8694
|
process.exit(1);
|
|
8551
8695
|
}
|
|
8552
8696
|
const { collection: col } = resolved;
|
|
@@ -8584,7 +8728,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
8584
8728
|
import * as path27 from "path";
|
|
8585
8729
|
|
|
8586
8730
|
// src/commands/refactor/logViolations.ts
|
|
8587
|
-
import
|
|
8731
|
+
import chalk112 from "chalk";
|
|
8588
8732
|
var DEFAULT_MAX_LINES = 100;
|
|
8589
8733
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
8590
8734
|
if (violations.length === 0) {
|
|
@@ -8593,43 +8737,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
8593
8737
|
}
|
|
8594
8738
|
return;
|
|
8595
8739
|
}
|
|
8596
|
-
console.error(
|
|
8740
|
+
console.error(chalk112.red(`
|
|
8597
8741
|
Refactor check failed:
|
|
8598
8742
|
`));
|
|
8599
|
-
console.error(
|
|
8743
|
+
console.error(chalk112.red(` The following files exceed ${maxLines} lines:
|
|
8600
8744
|
`));
|
|
8601
8745
|
for (const violation of violations) {
|
|
8602
|
-
console.error(
|
|
8746
|
+
console.error(chalk112.red(` ${violation.file} (${violation.lines} lines)`));
|
|
8603
8747
|
}
|
|
8604
8748
|
console.error(
|
|
8605
|
-
|
|
8749
|
+
chalk112.yellow(
|
|
8606
8750
|
`
|
|
8607
8751
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
8608
8752
|
way to refactor it, ignore it with:
|
|
8609
8753
|
`
|
|
8610
8754
|
)
|
|
8611
8755
|
);
|
|
8612
|
-
console.error(
|
|
8756
|
+
console.error(chalk112.gray(` assist refactor ignore <file>
|
|
8613
8757
|
`));
|
|
8614
8758
|
if (process.env.CLAUDECODE) {
|
|
8615
|
-
console.error(
|
|
8759
|
+
console.error(chalk112.cyan(`
|
|
8616
8760
|
## Extracting Code to New Files
|
|
8617
8761
|
`));
|
|
8618
8762
|
console.error(
|
|
8619
|
-
|
|
8763
|
+
chalk112.cyan(
|
|
8620
8764
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
8621
8765
|
`
|
|
8622
8766
|
)
|
|
8623
8767
|
);
|
|
8624
8768
|
console.error(
|
|
8625
|
-
|
|
8769
|
+
chalk112.cyan(
|
|
8626
8770
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
8627
8771
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
8628
8772
|
`
|
|
8629
8773
|
)
|
|
8630
8774
|
);
|
|
8631
8775
|
console.error(
|
|
8632
|
-
|
|
8776
|
+
chalk112.cyan(
|
|
8633
8777
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
8634
8778
|
domains, move it to a common/shared folder.
|
|
8635
8779
|
`
|
|
@@ -8785,7 +8929,7 @@ async function check(pattern2, options2) {
|
|
|
8785
8929
|
|
|
8786
8930
|
// src/commands/refactor/extract/index.ts
|
|
8787
8931
|
import path33 from "path";
|
|
8788
|
-
import
|
|
8932
|
+
import chalk115 from "chalk";
|
|
8789
8933
|
|
|
8790
8934
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
8791
8935
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -9332,23 +9476,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
9332
9476
|
|
|
9333
9477
|
// src/commands/refactor/extract/displayPlan.ts
|
|
9334
9478
|
import path31 from "path";
|
|
9335
|
-
import
|
|
9479
|
+
import chalk113 from "chalk";
|
|
9336
9480
|
function section(title) {
|
|
9337
9481
|
return `
|
|
9338
|
-
${
|
|
9482
|
+
${chalk113.cyan(title)}`;
|
|
9339
9483
|
}
|
|
9340
9484
|
function displayImporters(plan2, cwd) {
|
|
9341
9485
|
if (plan2.importersToUpdate.length === 0) return;
|
|
9342
9486
|
console.log(section("Update importers:"));
|
|
9343
9487
|
for (const imp of plan2.importersToUpdate) {
|
|
9344
9488
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
9345
|
-
console.log(` ${
|
|
9489
|
+
console.log(` ${chalk113.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
9346
9490
|
}
|
|
9347
9491
|
}
|
|
9348
9492
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
9349
|
-
console.log(
|
|
9493
|
+
console.log(chalk113.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
9350
9494
|
`));
|
|
9351
|
-
console.log(` ${
|
|
9495
|
+
console.log(` ${chalk113.cyan("Functions to move:")}`);
|
|
9352
9496
|
for (const name of plan2.extractedNames) {
|
|
9353
9497
|
console.log(` ${name}`);
|
|
9354
9498
|
}
|
|
@@ -9383,7 +9527,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
9383
9527
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
9384
9528
|
import fs17 from "fs";
|
|
9385
9529
|
import path32 from "path";
|
|
9386
|
-
import
|
|
9530
|
+
import chalk114 from "chalk";
|
|
9387
9531
|
import { Project as Project2 } from "ts-morph";
|
|
9388
9532
|
function findTsConfig(sourcePath) {
|
|
9389
9533
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -9414,7 +9558,7 @@ function loadProjectFile(file) {
|
|
|
9414
9558
|
});
|
|
9415
9559
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
9416
9560
|
if (!sourceFile) {
|
|
9417
|
-
console.log(
|
|
9561
|
+
console.log(chalk114.red(`File not found in project: ${file}`));
|
|
9418
9562
|
process.exit(1);
|
|
9419
9563
|
}
|
|
9420
9564
|
return { project, sourceFile };
|
|
@@ -9437,19 +9581,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
9437
9581
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
9438
9582
|
if (options2.apply) {
|
|
9439
9583
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
9440
|
-
console.log(
|
|
9584
|
+
console.log(chalk115.green("\nExtraction complete"));
|
|
9441
9585
|
} else {
|
|
9442
|
-
console.log(
|
|
9586
|
+
console.log(chalk115.dim("\nDry run. Use --apply to execute."));
|
|
9443
9587
|
}
|
|
9444
9588
|
}
|
|
9445
9589
|
|
|
9446
9590
|
// src/commands/refactor/ignore.ts
|
|
9447
9591
|
import fs18 from "fs";
|
|
9448
|
-
import
|
|
9592
|
+
import chalk116 from "chalk";
|
|
9449
9593
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
9450
9594
|
function ignore(file) {
|
|
9451
9595
|
if (!fs18.existsSync(file)) {
|
|
9452
|
-
console.error(
|
|
9596
|
+
console.error(chalk116.red(`Error: File does not exist: ${file}`));
|
|
9453
9597
|
process.exit(1);
|
|
9454
9598
|
}
|
|
9455
9599
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -9465,7 +9609,7 @@ function ignore(file) {
|
|
|
9465
9609
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
9466
9610
|
}
|
|
9467
9611
|
console.log(
|
|
9468
|
-
|
|
9612
|
+
chalk116.green(
|
|
9469
9613
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
9470
9614
|
)
|
|
9471
9615
|
);
|
|
@@ -9473,26 +9617,26 @@ function ignore(file) {
|
|
|
9473
9617
|
|
|
9474
9618
|
// src/commands/refactor/rename/index.ts
|
|
9475
9619
|
import path34 from "path";
|
|
9476
|
-
import
|
|
9620
|
+
import chalk117 from "chalk";
|
|
9477
9621
|
async function rename(source, destination, options2 = {}) {
|
|
9478
9622
|
const destPath = path34.resolve(destination);
|
|
9479
9623
|
const cwd = process.cwd();
|
|
9480
9624
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
9481
9625
|
const relDest = path34.relative(cwd, destPath);
|
|
9482
9626
|
const { project, sourceFile } = loadProjectFile(source);
|
|
9483
|
-
console.log(
|
|
9627
|
+
console.log(chalk117.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
9484
9628
|
if (options2.apply) {
|
|
9485
9629
|
sourceFile.move(destPath);
|
|
9486
9630
|
await project.save();
|
|
9487
|
-
console.log(
|
|
9631
|
+
console.log(chalk117.green("Done"));
|
|
9488
9632
|
} else {
|
|
9489
|
-
console.log(
|
|
9633
|
+
console.log(chalk117.dim("Dry run. Use --apply to execute."));
|
|
9490
9634
|
}
|
|
9491
9635
|
}
|
|
9492
9636
|
|
|
9493
9637
|
// src/commands/refactor/renameSymbol/index.ts
|
|
9494
9638
|
import path36 from "path";
|
|
9495
|
-
import
|
|
9639
|
+
import chalk118 from "chalk";
|
|
9496
9640
|
import { Project as Project3 } from "ts-morph";
|
|
9497
9641
|
|
|
9498
9642
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -9541,38 +9685,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
9541
9685
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
9542
9686
|
const sourceFile = project.getSourceFile(filePath);
|
|
9543
9687
|
if (!sourceFile) {
|
|
9544
|
-
console.log(
|
|
9688
|
+
console.log(chalk118.red(`File not found in project: ${file}`));
|
|
9545
9689
|
process.exit(1);
|
|
9546
9690
|
}
|
|
9547
9691
|
const symbol = findSymbol(sourceFile, oldName);
|
|
9548
9692
|
if (!symbol) {
|
|
9549
|
-
console.log(
|
|
9693
|
+
console.log(chalk118.red(`Symbol "${oldName}" not found in ${file}`));
|
|
9550
9694
|
process.exit(1);
|
|
9551
9695
|
}
|
|
9552
9696
|
const grouped = groupReferences(symbol, cwd);
|
|
9553
9697
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
9554
9698
|
console.log(
|
|
9555
|
-
|
|
9699
|
+
chalk118.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
9556
9700
|
`)
|
|
9557
9701
|
);
|
|
9558
9702
|
for (const [refFile, lines] of grouped) {
|
|
9559
9703
|
console.log(
|
|
9560
|
-
` ${
|
|
9704
|
+
` ${chalk118.dim(refFile)}: lines ${chalk118.cyan(lines.join(", "))}`
|
|
9561
9705
|
);
|
|
9562
9706
|
}
|
|
9563
9707
|
if (options2.apply) {
|
|
9564
9708
|
symbol.rename(newName);
|
|
9565
9709
|
await project.save();
|
|
9566
|
-
console.log(
|
|
9710
|
+
console.log(chalk118.green(`
|
|
9567
9711
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
9568
9712
|
} else {
|
|
9569
|
-
console.log(
|
|
9713
|
+
console.log(chalk118.dim("\nDry run. Use --apply to execute."));
|
|
9570
9714
|
}
|
|
9571
9715
|
}
|
|
9572
9716
|
|
|
9573
9717
|
// src/commands/refactor/restructure/index.ts
|
|
9574
9718
|
import path45 from "path";
|
|
9575
|
-
import
|
|
9719
|
+
import chalk121 from "chalk";
|
|
9576
9720
|
|
|
9577
9721
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
9578
9722
|
import path37 from "path";
|
|
@@ -9815,50 +9959,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
9815
9959
|
|
|
9816
9960
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
9817
9961
|
import path41 from "path";
|
|
9818
|
-
import
|
|
9962
|
+
import chalk119 from "chalk";
|
|
9819
9963
|
function relPath(filePath) {
|
|
9820
9964
|
return path41.relative(process.cwd(), filePath);
|
|
9821
9965
|
}
|
|
9822
9966
|
function displayMoves(plan2) {
|
|
9823
9967
|
if (plan2.moves.length === 0) return;
|
|
9824
|
-
console.log(
|
|
9968
|
+
console.log(chalk119.bold("\nFile moves:"));
|
|
9825
9969
|
for (const move of plan2.moves) {
|
|
9826
9970
|
console.log(
|
|
9827
|
-
` ${
|
|
9971
|
+
` ${chalk119.red(relPath(move.from))} \u2192 ${chalk119.green(relPath(move.to))}`
|
|
9828
9972
|
);
|
|
9829
|
-
console.log(
|
|
9973
|
+
console.log(chalk119.dim(` ${move.reason}`));
|
|
9830
9974
|
}
|
|
9831
9975
|
}
|
|
9832
9976
|
function displayRewrites(rewrites) {
|
|
9833
9977
|
if (rewrites.length === 0) return;
|
|
9834
9978
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
9835
|
-
console.log(
|
|
9979
|
+
console.log(chalk119.bold(`
|
|
9836
9980
|
Import rewrites (${affectedFiles.size} files):`));
|
|
9837
9981
|
for (const file of affectedFiles) {
|
|
9838
|
-
console.log(` ${
|
|
9982
|
+
console.log(` ${chalk119.cyan(relPath(file))}:`);
|
|
9839
9983
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
9840
9984
|
(r) => r.file === file
|
|
9841
9985
|
)) {
|
|
9842
9986
|
console.log(
|
|
9843
|
-
` ${
|
|
9987
|
+
` ${chalk119.red(`"${oldSpecifier}"`)} \u2192 ${chalk119.green(`"${newSpecifier}"`)}`
|
|
9844
9988
|
);
|
|
9845
9989
|
}
|
|
9846
9990
|
}
|
|
9847
9991
|
}
|
|
9848
9992
|
function displayPlan2(plan2) {
|
|
9849
9993
|
if (plan2.warnings.length > 0) {
|
|
9850
|
-
console.log(
|
|
9851
|
-
for (const w of plan2.warnings) console.log(
|
|
9994
|
+
console.log(chalk119.yellow("\nWarnings:"));
|
|
9995
|
+
for (const w of plan2.warnings) console.log(chalk119.yellow(` ${w}`));
|
|
9852
9996
|
}
|
|
9853
9997
|
if (plan2.newDirectories.length > 0) {
|
|
9854
|
-
console.log(
|
|
9998
|
+
console.log(chalk119.bold("\nNew directories:"));
|
|
9855
9999
|
for (const dir of plan2.newDirectories)
|
|
9856
|
-
console.log(
|
|
10000
|
+
console.log(chalk119.green(` ${dir}/`));
|
|
9857
10001
|
}
|
|
9858
10002
|
displayMoves(plan2);
|
|
9859
10003
|
displayRewrites(plan2.rewrites);
|
|
9860
10004
|
console.log(
|
|
9861
|
-
|
|
10005
|
+
chalk119.dim(
|
|
9862
10006
|
`
|
|
9863
10007
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
9864
10008
|
)
|
|
@@ -9868,18 +10012,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
9868
10012
|
// src/commands/refactor/restructure/executePlan.ts
|
|
9869
10013
|
import fs20 from "fs";
|
|
9870
10014
|
import path42 from "path";
|
|
9871
|
-
import
|
|
10015
|
+
import chalk120 from "chalk";
|
|
9872
10016
|
function executePlan(plan2) {
|
|
9873
10017
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
9874
10018
|
for (const [file, content] of updatedContents) {
|
|
9875
10019
|
fs20.writeFileSync(file, content, "utf-8");
|
|
9876
10020
|
console.log(
|
|
9877
|
-
|
|
10021
|
+
chalk120.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
9878
10022
|
);
|
|
9879
10023
|
}
|
|
9880
10024
|
for (const dir of plan2.newDirectories) {
|
|
9881
10025
|
fs20.mkdirSync(dir, { recursive: true });
|
|
9882
|
-
console.log(
|
|
10026
|
+
console.log(chalk120.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
9883
10027
|
}
|
|
9884
10028
|
for (const move of plan2.moves) {
|
|
9885
10029
|
const targetDir = path42.dirname(move.to);
|
|
@@ -9888,7 +10032,7 @@ function executePlan(plan2) {
|
|
|
9888
10032
|
}
|
|
9889
10033
|
fs20.renameSync(move.from, move.to);
|
|
9890
10034
|
console.log(
|
|
9891
|
-
|
|
10035
|
+
chalk120.white(
|
|
9892
10036
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
9893
10037
|
)
|
|
9894
10038
|
);
|
|
@@ -9903,7 +10047,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
9903
10047
|
if (entries.length === 0) {
|
|
9904
10048
|
fs20.rmdirSync(dir);
|
|
9905
10049
|
console.log(
|
|
9906
|
-
|
|
10050
|
+
chalk120.dim(
|
|
9907
10051
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
9908
10052
|
)
|
|
9909
10053
|
);
|
|
@@ -10036,22 +10180,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
10036
10180
|
const targetPattern = pattern2 ?? "src";
|
|
10037
10181
|
const files = findSourceFiles2(targetPattern);
|
|
10038
10182
|
if (files.length === 0) {
|
|
10039
|
-
console.log(
|
|
10183
|
+
console.log(chalk121.yellow("No files found matching pattern"));
|
|
10040
10184
|
return;
|
|
10041
10185
|
}
|
|
10042
10186
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
10043
10187
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
10044
10188
|
if (plan2.moves.length === 0) {
|
|
10045
|
-
console.log(
|
|
10189
|
+
console.log(chalk121.green("No restructuring needed"));
|
|
10046
10190
|
return;
|
|
10047
10191
|
}
|
|
10048
10192
|
displayPlan2(plan2);
|
|
10049
10193
|
if (options2.apply) {
|
|
10050
|
-
console.log(
|
|
10194
|
+
console.log(chalk121.bold("\nApplying changes..."));
|
|
10051
10195
|
executePlan(plan2);
|
|
10052
|
-
console.log(
|
|
10196
|
+
console.log(chalk121.green("\nRestructuring complete"));
|
|
10053
10197
|
} else {
|
|
10054
|
-
console.log(
|
|
10198
|
+
console.log(chalk121.dim("\nDry run. Use --apply to execute."));
|
|
10055
10199
|
}
|
|
10056
10200
|
}
|
|
10057
10201
|
|
|
@@ -10091,7 +10235,7 @@ function registerRefactor(program2) {
|
|
|
10091
10235
|
}
|
|
10092
10236
|
|
|
10093
10237
|
// src/commands/seq/seqAuth.ts
|
|
10094
|
-
import
|
|
10238
|
+
import chalk123 from "chalk";
|
|
10095
10239
|
|
|
10096
10240
|
// src/commands/seq/loadConnections.ts
|
|
10097
10241
|
function loadConnections2() {
|
|
@@ -10120,11 +10264,11 @@ function setDefaultConnection(name) {
|
|
|
10120
10264
|
}
|
|
10121
10265
|
|
|
10122
10266
|
// src/commands/seq/promptConnection.ts
|
|
10123
|
-
import
|
|
10267
|
+
import chalk122 from "chalk";
|
|
10124
10268
|
async function promptConnection2(existingNames) {
|
|
10125
10269
|
const name = await promptInput("name", "Connection name:", "default");
|
|
10126
10270
|
if (existingNames.includes(name)) {
|
|
10127
|
-
console.error(
|
|
10271
|
+
console.error(chalk122.red(`Connection "${name}" already exists.`));
|
|
10128
10272
|
process.exit(1);
|
|
10129
10273
|
}
|
|
10130
10274
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -10136,16 +10280,16 @@ async function promptConnection2(existingNames) {
|
|
|
10136
10280
|
var seqAuth = createConnectionAuth({
|
|
10137
10281
|
load: loadConnections2,
|
|
10138
10282
|
save: saveConnections2,
|
|
10139
|
-
format: (c) => `${
|
|
10283
|
+
format: (c) => `${chalk123.bold(c.name)} ${c.url}`,
|
|
10140
10284
|
promptNew: promptConnection2,
|
|
10141
10285
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
10142
10286
|
});
|
|
10143
10287
|
|
|
10144
10288
|
// src/commands/seq/seqQuery.ts
|
|
10145
|
-
import
|
|
10289
|
+
import chalk127 from "chalk";
|
|
10146
10290
|
|
|
10147
10291
|
// src/commands/seq/fetchSeq.ts
|
|
10148
|
-
import
|
|
10292
|
+
import chalk124 from "chalk";
|
|
10149
10293
|
async function fetchSeq(conn, path50, params) {
|
|
10150
10294
|
const url = `${conn.url}${path50}?${params}`;
|
|
10151
10295
|
const response = await fetch(url, {
|
|
@@ -10156,7 +10300,7 @@ async function fetchSeq(conn, path50, params) {
|
|
|
10156
10300
|
});
|
|
10157
10301
|
if (!response.ok) {
|
|
10158
10302
|
const body = await response.text();
|
|
10159
|
-
console.error(
|
|
10303
|
+
console.error(chalk124.red(`Seq returned ${response.status}: ${body}`));
|
|
10160
10304
|
process.exit(1);
|
|
10161
10305
|
}
|
|
10162
10306
|
return response;
|
|
@@ -10209,23 +10353,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
10209
10353
|
}
|
|
10210
10354
|
|
|
10211
10355
|
// src/commands/seq/formatEvent.ts
|
|
10212
|
-
import
|
|
10356
|
+
import chalk125 from "chalk";
|
|
10213
10357
|
function levelColor(level) {
|
|
10214
10358
|
switch (level) {
|
|
10215
10359
|
case "Fatal":
|
|
10216
|
-
return
|
|
10360
|
+
return chalk125.bgRed.white;
|
|
10217
10361
|
case "Error":
|
|
10218
|
-
return
|
|
10362
|
+
return chalk125.red;
|
|
10219
10363
|
case "Warning":
|
|
10220
|
-
return
|
|
10364
|
+
return chalk125.yellow;
|
|
10221
10365
|
case "Information":
|
|
10222
|
-
return
|
|
10366
|
+
return chalk125.cyan;
|
|
10223
10367
|
case "Debug":
|
|
10224
|
-
return
|
|
10368
|
+
return chalk125.gray;
|
|
10225
10369
|
case "Verbose":
|
|
10226
|
-
return
|
|
10370
|
+
return chalk125.dim;
|
|
10227
10371
|
default:
|
|
10228
|
-
return
|
|
10372
|
+
return chalk125.white;
|
|
10229
10373
|
}
|
|
10230
10374
|
}
|
|
10231
10375
|
function levelAbbrev(level) {
|
|
@@ -10266,31 +10410,31 @@ function formatTimestamp(iso) {
|
|
|
10266
10410
|
function formatEvent(event) {
|
|
10267
10411
|
const color = levelColor(event.Level);
|
|
10268
10412
|
const abbrev = levelAbbrev(event.Level);
|
|
10269
|
-
const ts8 =
|
|
10413
|
+
const ts8 = chalk125.dim(formatTimestamp(event.Timestamp));
|
|
10270
10414
|
const msg = renderMessage(event);
|
|
10271
10415
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
10272
10416
|
if (event.Exception) {
|
|
10273
10417
|
for (const line of event.Exception.split("\n")) {
|
|
10274
|
-
lines.push(
|
|
10418
|
+
lines.push(chalk125.red(` ${line}`));
|
|
10275
10419
|
}
|
|
10276
10420
|
}
|
|
10277
10421
|
return lines.join("\n");
|
|
10278
10422
|
}
|
|
10279
10423
|
|
|
10280
10424
|
// src/commands/seq/resolveConnection.ts
|
|
10281
|
-
import
|
|
10425
|
+
import chalk126 from "chalk";
|
|
10282
10426
|
function resolveConnection2(name) {
|
|
10283
10427
|
const connections = loadConnections2();
|
|
10284
10428
|
if (connections.length === 0) {
|
|
10285
10429
|
console.error(
|
|
10286
|
-
|
|
10430
|
+
chalk126.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
10287
10431
|
);
|
|
10288
10432
|
process.exit(1);
|
|
10289
10433
|
}
|
|
10290
10434
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
10291
10435
|
const connection = connections.find((c) => c.name === target);
|
|
10292
10436
|
if (!connection) {
|
|
10293
|
-
console.error(
|
|
10437
|
+
console.error(chalk126.red(`Seq connection "${target}" not found.`));
|
|
10294
10438
|
process.exit(1);
|
|
10295
10439
|
}
|
|
10296
10440
|
return connection;
|
|
@@ -10305,7 +10449,7 @@ async function seqQuery(filter, options2) {
|
|
|
10305
10449
|
new URLSearchParams({ filter, count: String(count) })
|
|
10306
10450
|
);
|
|
10307
10451
|
if (events.length === 0) {
|
|
10308
|
-
console.log(
|
|
10452
|
+
console.log(chalk127.yellow("No events found."));
|
|
10309
10453
|
return;
|
|
10310
10454
|
}
|
|
10311
10455
|
if (options2.json) {
|
|
@@ -10316,11 +10460,11 @@ async function seqQuery(filter, options2) {
|
|
|
10316
10460
|
for (const event of chronological) {
|
|
10317
10461
|
console.log(formatEvent(event));
|
|
10318
10462
|
}
|
|
10319
|
-
console.log(
|
|
10463
|
+
console.log(chalk127.dim(`
|
|
10320
10464
|
${events.length} events`));
|
|
10321
10465
|
if (events.length >= count) {
|
|
10322
10466
|
console.log(
|
|
10323
|
-
|
|
10467
|
+
chalk127.yellow(
|
|
10324
10468
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
10325
10469
|
)
|
|
10326
10470
|
);
|
|
@@ -10328,11 +10472,11 @@ ${events.length} events`));
|
|
|
10328
10472
|
}
|
|
10329
10473
|
|
|
10330
10474
|
// src/commands/seq/seqSetConnection.ts
|
|
10331
|
-
import
|
|
10475
|
+
import chalk128 from "chalk";
|
|
10332
10476
|
function seqSetConnection(name) {
|
|
10333
10477
|
const connections = loadConnections2();
|
|
10334
10478
|
if (!connections.find((c) => c.name === name)) {
|
|
10335
|
-
console.error(
|
|
10479
|
+
console.error(chalk128.red(`Connection "${name}" not found.`));
|
|
10336
10480
|
process.exit(1);
|
|
10337
10481
|
}
|
|
10338
10482
|
setDefaultConnection(name);
|
|
@@ -10871,14 +11015,14 @@ import {
|
|
|
10871
11015
|
import { dirname as dirname20, join as join35 } from "path";
|
|
10872
11016
|
|
|
10873
11017
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
10874
|
-
import
|
|
11018
|
+
import chalk129 from "chalk";
|
|
10875
11019
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
10876
11020
|
function validateStagedContent(filename, content) {
|
|
10877
11021
|
const firstLine = content.split("\n")[0];
|
|
10878
11022
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
10879
11023
|
if (!match) {
|
|
10880
11024
|
console.error(
|
|
10881
|
-
|
|
11025
|
+
chalk129.red(
|
|
10882
11026
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
10883
11027
|
)
|
|
10884
11028
|
);
|
|
@@ -10887,7 +11031,7 @@ function validateStagedContent(filename, content) {
|
|
|
10887
11031
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
10888
11032
|
if (!contentAfterLink) {
|
|
10889
11033
|
console.error(
|
|
10890
|
-
|
|
11034
|
+
chalk129.red(
|
|
10891
11035
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
10892
11036
|
)
|
|
10893
11037
|
);
|
|
@@ -11280,7 +11424,7 @@ function registerVoice(program2) {
|
|
|
11280
11424
|
|
|
11281
11425
|
// src/commands/roam/auth.ts
|
|
11282
11426
|
import { randomBytes } from "crypto";
|
|
11283
|
-
import
|
|
11427
|
+
import chalk130 from "chalk";
|
|
11284
11428
|
|
|
11285
11429
|
// src/lib/openBrowser.ts
|
|
11286
11430
|
import { execSync as execSync39 } from "child_process";
|
|
@@ -11455,13 +11599,13 @@ async function auth() {
|
|
|
11455
11599
|
saveGlobalConfig(config);
|
|
11456
11600
|
const state = randomBytes(16).toString("hex");
|
|
11457
11601
|
console.log(
|
|
11458
|
-
|
|
11602
|
+
chalk130.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
11459
11603
|
);
|
|
11460
|
-
console.log(
|
|
11461
|
-
console.log(
|
|
11462
|
-
console.log(
|
|
11604
|
+
console.log(chalk130.white("http://localhost:14523/callback\n"));
|
|
11605
|
+
console.log(chalk130.blue("Opening browser for authorization..."));
|
|
11606
|
+
console.log(chalk130.dim("Waiting for authorization callback..."));
|
|
11463
11607
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
11464
|
-
console.log(
|
|
11608
|
+
console.log(chalk130.dim("Exchanging code for tokens..."));
|
|
11465
11609
|
const tokens = await exchangeToken({
|
|
11466
11610
|
code,
|
|
11467
11611
|
clientId,
|
|
@@ -11477,7 +11621,7 @@ async function auth() {
|
|
|
11477
11621
|
};
|
|
11478
11622
|
saveGlobalConfig(config);
|
|
11479
11623
|
console.log(
|
|
11480
|
-
|
|
11624
|
+
chalk130.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
11481
11625
|
);
|
|
11482
11626
|
}
|
|
11483
11627
|
|
|
@@ -11722,7 +11866,7 @@ import { execSync as execSync41 } from "child_process";
|
|
|
11722
11866
|
import { existsSync as existsSync40, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync29 } from "fs";
|
|
11723
11867
|
import { tmpdir as tmpdir6 } from "os";
|
|
11724
11868
|
import { join as join44, resolve as resolve6 } from "path";
|
|
11725
|
-
import
|
|
11869
|
+
import chalk131 from "chalk";
|
|
11726
11870
|
|
|
11727
11871
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
11728
11872
|
var captureWindowPs1 = `
|
|
@@ -11873,22 +12017,22 @@ function screenshot(processName) {
|
|
|
11873
12017
|
const config = loadConfig();
|
|
11874
12018
|
const outputDir = resolve6(config.screenshot.outputDir);
|
|
11875
12019
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
11876
|
-
console.log(
|
|
12020
|
+
console.log(chalk131.gray(`Capturing window for process "${processName}" ...`));
|
|
11877
12021
|
try {
|
|
11878
12022
|
runPowerShellScript(processName, outputPath);
|
|
11879
|
-
console.log(
|
|
12023
|
+
console.log(chalk131.green(`Screenshot saved: ${outputPath}`));
|
|
11880
12024
|
} catch (error) {
|
|
11881
12025
|
const msg = error instanceof Error ? error.message : String(error);
|
|
11882
|
-
console.error(
|
|
12026
|
+
console.error(chalk131.red(`Failed to capture screenshot: ${msg}`));
|
|
11883
12027
|
process.exit(1);
|
|
11884
12028
|
}
|
|
11885
12029
|
}
|
|
11886
12030
|
|
|
11887
12031
|
// src/commands/statusLine.ts
|
|
11888
|
-
import
|
|
12032
|
+
import chalk133 from "chalk";
|
|
11889
12033
|
|
|
11890
12034
|
// src/commands/buildLimitsSegment.ts
|
|
11891
|
-
import
|
|
12035
|
+
import chalk132 from "chalk";
|
|
11892
12036
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
11893
12037
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
11894
12038
|
function formatTimeLeft(resetsAt) {
|
|
@@ -11911,10 +12055,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
11911
12055
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
11912
12056
|
const label2 = `${Math.round(pct)}%`;
|
|
11913
12057
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
11914
|
-
if (projected == null) return
|
|
11915
|
-
if (projected > 100) return
|
|
11916
|
-
if (projected > 75) return
|
|
11917
|
-
return
|
|
12058
|
+
if (projected == null) return chalk132.green(label2);
|
|
12059
|
+
if (projected > 100) return chalk132.red(label2);
|
|
12060
|
+
if (projected > 75) return chalk132.yellow(label2);
|
|
12061
|
+
return chalk132.green(label2);
|
|
11918
12062
|
}
|
|
11919
12063
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
11920
12064
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -11940,14 +12084,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
11940
12084
|
}
|
|
11941
12085
|
|
|
11942
12086
|
// src/commands/statusLine.ts
|
|
11943
|
-
|
|
12087
|
+
chalk133.level = 3;
|
|
11944
12088
|
function formatNumber(num) {
|
|
11945
12089
|
return num.toLocaleString("en-US");
|
|
11946
12090
|
}
|
|
11947
12091
|
function colorizePercent(pct) {
|
|
11948
12092
|
const label2 = `${Math.round(pct)}%`;
|
|
11949
|
-
if (pct > 80) return
|
|
11950
|
-
if (pct > 40) return
|
|
12093
|
+
if (pct > 80) return chalk133.red(label2);
|
|
12094
|
+
if (pct > 40) return chalk133.yellow(label2);
|
|
11951
12095
|
return label2;
|
|
11952
12096
|
}
|
|
11953
12097
|
async function statusLine() {
|
|
@@ -11970,7 +12114,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
11970
12114
|
// src/commands/sync/syncClaudeMd.ts
|
|
11971
12115
|
import * as fs23 from "fs";
|
|
11972
12116
|
import * as path46 from "path";
|
|
11973
|
-
import
|
|
12117
|
+
import chalk134 from "chalk";
|
|
11974
12118
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
11975
12119
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
11976
12120
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -11979,12 +12123,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
11979
12123
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
11980
12124
|
if (sourceContent !== targetContent) {
|
|
11981
12125
|
console.log(
|
|
11982
|
-
|
|
12126
|
+
chalk134.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
11983
12127
|
);
|
|
11984
12128
|
console.log();
|
|
11985
12129
|
printDiff(targetContent, sourceContent);
|
|
11986
12130
|
const confirm = options2?.yes || await promptConfirm(
|
|
11987
|
-
|
|
12131
|
+
chalk134.red("Overwrite existing CLAUDE.md?"),
|
|
11988
12132
|
false
|
|
11989
12133
|
);
|
|
11990
12134
|
if (!confirm) {
|
|
@@ -12000,7 +12144,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
12000
12144
|
// src/commands/sync/syncSettings.ts
|
|
12001
12145
|
import * as fs24 from "fs";
|
|
12002
12146
|
import * as path47 from "path";
|
|
12003
|
-
import
|
|
12147
|
+
import chalk135 from "chalk";
|
|
12004
12148
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
12005
12149
|
const source = path47.join(claudeDir, "settings.json");
|
|
12006
12150
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -12016,14 +12160,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
12016
12160
|
if (mergedContent !== normalizedTarget) {
|
|
12017
12161
|
if (!options2?.yes) {
|
|
12018
12162
|
console.log(
|
|
12019
|
-
|
|
12163
|
+
chalk135.yellow(
|
|
12020
12164
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
12021
12165
|
)
|
|
12022
12166
|
);
|
|
12023
12167
|
console.log();
|
|
12024
12168
|
printDiff(targetContent, mergedContent);
|
|
12025
12169
|
const confirm = await promptConfirm(
|
|
12026
|
-
|
|
12170
|
+
chalk135.red("Overwrite existing settings.json?"),
|
|
12027
12171
|
false
|
|
12028
12172
|
);
|
|
12029
12173
|
if (!confirm) {
|