@staff0rd/assist 0.186.0 → 0.187.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/commands/backlog/web/bundle.js +1 -1
- package/dist/index.js +502 -410
- 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.187.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -439,11 +439,7 @@ function ensureGitignore(dir) {
|
|
|
439
439
|
`);
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
-
// src/commands/backlog/
|
|
443
|
-
var _db;
|
|
444
|
-
function getDbPath(dir) {
|
|
445
|
-
return join3(dir, ".assist", "backlog.db");
|
|
446
|
-
}
|
|
442
|
+
// src/commands/backlog/migrateCommentsAddId.ts
|
|
447
443
|
function migrateCommentsAddId(db) {
|
|
448
444
|
const cols = db.pragma("table_info(comments)");
|
|
449
445
|
if (cols.length === 0 || cols.some((c) => c.name === "id")) return;
|
|
@@ -463,6 +459,24 @@ function migrateCommentsAddId(db) {
|
|
|
463
459
|
ALTER TABLE comments_new RENAME TO comments;
|
|
464
460
|
`);
|
|
465
461
|
}
|
|
462
|
+
function migrateToOneBasedPhases(db) {
|
|
463
|
+
const row = db.prepare(
|
|
464
|
+
"SELECT value FROM metadata WHERE key = 'one_based_phases_migrated'"
|
|
465
|
+
).get();
|
|
466
|
+
if (row) return;
|
|
467
|
+
db.exec(`
|
|
468
|
+
UPDATE items SET current_phase = current_phase + 1 WHERE current_phase IS NOT NULL;
|
|
469
|
+
UPDATE comments SET phase = phase + 1 WHERE phase IS NOT NULL;
|
|
470
|
+
INSERT INTO metadata (key, value) VALUES ('one_based_phases_migrated', '1')
|
|
471
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value;
|
|
472
|
+
`);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// src/commands/backlog/openDb.ts
|
|
476
|
+
var _db;
|
|
477
|
+
function getDbPath(dir) {
|
|
478
|
+
return join3(dir, ".assist", "backlog.db");
|
|
479
|
+
}
|
|
466
480
|
function initSchema(db) {
|
|
467
481
|
db.exec(`
|
|
468
482
|
CREATE TABLE IF NOT EXISTS items (
|
|
@@ -524,6 +538,7 @@ function openDb(dir) {
|
|
|
524
538
|
db.pragma("foreign_keys = ON");
|
|
525
539
|
initSchema(db);
|
|
526
540
|
migrateCommentsAddId(db);
|
|
541
|
+
migrateToOneBasedPhases(db);
|
|
527
542
|
ensureGitignore(dir);
|
|
528
543
|
_db = db;
|
|
529
544
|
return db;
|
|
@@ -700,9 +715,7 @@ function typeLabel(type) {
|
|
|
700
715
|
}
|
|
701
716
|
function phaseLabel(item) {
|
|
702
717
|
if (!item.plan) return "";
|
|
703
|
-
return chalk2.dim(
|
|
704
|
-
` (phase ${(item.currentPhase ?? 0) + 1}/${item.plan.length})`
|
|
705
|
-
);
|
|
718
|
+
return chalk2.dim(` (phase ${item.currentPhase ?? 1}/${item.plan.length})`);
|
|
706
719
|
}
|
|
707
720
|
function isBlocked(item, items) {
|
|
708
721
|
const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
|
|
@@ -766,18 +779,18 @@ function buildCommentLines(comments2) {
|
|
|
766
779
|
function formatPromptComment(entry) {
|
|
767
780
|
const id = entry.id !== void 0 ? `#${entry.id} ` : "";
|
|
768
781
|
const tag = entry.type === "summary" ? "[summary]" : "[comment]";
|
|
769
|
-
const phase = entry.phase !== void 0 ? ` (phase ${entry.phase
|
|
782
|
+
const phase = entry.phase !== void 0 ? ` (phase ${entry.phase})` : "";
|
|
770
783
|
return `${id}${tag}${phase} ${entry.timestamp}
|
|
771
784
|
${entry.text}`;
|
|
772
785
|
}
|
|
773
786
|
|
|
774
787
|
// src/commands/backlog/buildAuthoredPhasePrompt.ts
|
|
775
|
-
function buildAuthoredPhasePrompt(item,
|
|
788
|
+
function buildAuthoredPhasePrompt(item, phaseNumber, phase) {
|
|
776
789
|
const manualChecks = phase.manualChecks ?? [];
|
|
777
790
|
const needsConfirmation = manualChecks.length > 0;
|
|
778
791
|
const confirmSuffix = needsConfirmation ? " and the user confirms" : "";
|
|
779
792
|
return [
|
|
780
|
-
...buildContextLines(item,
|
|
793
|
+
...buildContextLines(item, phaseNumber, phase),
|
|
781
794
|
"",
|
|
782
795
|
"Focus ONLY on this phase. Do not work on other phases.",
|
|
783
796
|
"When you have completed all tasks for this phase, run /verify to check your work.",
|
|
@@ -785,14 +798,14 @@ function buildAuthoredPhasePrompt(item, phaseIndex, phase) {
|
|
|
785
798
|
"",
|
|
786
799
|
`Post concise comments for any notable findings or changes using \`assist backlog comment ${item.id} "<text>"\`.`,
|
|
787
800
|
"",
|
|
788
|
-
`Once verify passes${confirmSuffix}, run: assist backlog phase-done ${item.id} ${
|
|
801
|
+
`Once verify passes${confirmSuffix}, run: assist backlog phase-done ${item.id} ${phaseNumber} "<summary>"`,
|
|
789
802
|
"Replace <summary> with a concise summary of what was done in this phase."
|
|
790
803
|
].filter((line) => line !== void 0).join("\n");
|
|
791
804
|
}
|
|
792
|
-
function buildContextLines(item,
|
|
805
|
+
function buildContextLines(item, phaseNumber, phase) {
|
|
793
806
|
const ac = item.acceptanceCriteria.map((c, i) => `${i + 1}. ${c}`).join("\n");
|
|
794
807
|
return [
|
|
795
|
-
`You are implementing phase ${
|
|
808
|
+
`You are implementing phase ${phaseNumber} of backlog item #${item.id}: ${item.name}`,
|
|
796
809
|
"",
|
|
797
810
|
item.description ? `Description: ${item.description}` : "",
|
|
798
811
|
"",
|
|
@@ -800,7 +813,7 @@ function buildContextLines(item, phaseIndex, phase) {
|
|
|
800
813
|
ac,
|
|
801
814
|
...buildCommentLines(item.comments),
|
|
802
815
|
"",
|
|
803
|
-
`Phase ${
|
|
816
|
+
`Phase ${phaseNumber}: ${phase.name}`,
|
|
804
817
|
"Tasks:",
|
|
805
818
|
formatTasks(phase)
|
|
806
819
|
];
|
|
@@ -822,7 +835,7 @@ function formatTasks(phase) {
|
|
|
822
835
|
}
|
|
823
836
|
|
|
824
837
|
// src/commands/backlog/buildReviewPrompt.ts
|
|
825
|
-
function buildReviewPrompt(item,
|
|
838
|
+
function buildReviewPrompt(item, phaseNumber) {
|
|
826
839
|
const acLines = item.acceptanceCriteria.map((ac, i) => `${i + 1}. ${ac}`).join("\n");
|
|
827
840
|
return [
|
|
828
841
|
`You are reviewing backlog item #${item.id}: ${item.name}`,
|
|
@@ -846,17 +859,17 @@ function buildReviewPrompt(item, phaseIndex) {
|
|
|
846
859
|
"Once the user confirms:",
|
|
847
860
|
`1. Run: assist backlog done ${item.id} "<summary>"`,
|
|
848
861
|
"2. Run: /commit",
|
|
849
|
-
`3. Run: assist backlog phase-done ${item.id} ${
|
|
862
|
+
`3. Run: assist backlog phase-done ${item.id} ${phaseNumber} "done"`
|
|
850
863
|
].filter((line) => line !== void 0).join("\n");
|
|
851
864
|
}
|
|
852
865
|
|
|
853
866
|
// src/commands/backlog/buildPhasePrompt.ts
|
|
854
867
|
var REVIEW_PHASE_NAME = "Review";
|
|
855
|
-
function buildPhasePrompt(item,
|
|
868
|
+
function buildPhasePrompt(item, phaseNumber, phase) {
|
|
856
869
|
if (phase.name === REVIEW_PHASE_NAME) {
|
|
857
|
-
return buildReviewPrompt(item,
|
|
870
|
+
return buildReviewPrompt(item, phaseNumber);
|
|
858
871
|
}
|
|
859
|
-
return buildAuthoredPhasePrompt(item,
|
|
872
|
+
return buildAuthoredPhasePrompt(item, phaseNumber, phase);
|
|
860
873
|
}
|
|
861
874
|
|
|
862
875
|
// src/commands/backlog/buildReviewPhase.ts
|
|
@@ -945,12 +958,14 @@ async function resolvePhaseResult(phaseIndex, itemId) {
|
|
|
945
958
|
cleanupSignal();
|
|
946
959
|
if (signal?.event === "rewind") {
|
|
947
960
|
const targetPhase = signal.targetPhase;
|
|
961
|
+
const targetPhaseNumber = targetPhase + 1;
|
|
948
962
|
console.log(chalk4.yellow(`
|
|
949
|
-
Rewinding to phase ${
|
|
963
|
+
Rewinding to phase ${targetPhaseNumber}.`));
|
|
950
964
|
return targetPhase;
|
|
951
965
|
}
|
|
966
|
+
const phaseNumber = phaseIndex + 1;
|
|
952
967
|
console.log(chalk4.green(`
|
|
953
|
-
Phase ${
|
|
968
|
+
Phase ${phaseNumber} completed.`));
|
|
954
969
|
return phaseIndex + 1;
|
|
955
970
|
}
|
|
956
971
|
|
|
@@ -991,16 +1006,17 @@ function stopWatching() {
|
|
|
991
1006
|
// src/commands/backlog/executePhase.ts
|
|
992
1007
|
async function executePhase(item, phaseIndex, phases, spawnOptions) {
|
|
993
1008
|
const phase = phases[phaseIndex];
|
|
1009
|
+
const phaseNumber = phaseIndex + 1;
|
|
994
1010
|
console.log(
|
|
995
1011
|
chalk5.bold(
|
|
996
1012
|
`
|
|
997
|
-
--- Phase ${
|
|
1013
|
+
--- Phase ${phaseNumber}/${phases.length}: ${phase.name} ---
|
|
998
1014
|
`
|
|
999
1015
|
)
|
|
1000
1016
|
);
|
|
1001
1017
|
process.env.ASSIST_SESSION_ID = String(process.pid);
|
|
1002
1018
|
const { child, done: done2 } = spawnClaude(
|
|
1003
|
-
buildPhasePrompt(item,
|
|
1019
|
+
buildPhasePrompt(item, phaseNumber, phase),
|
|
1004
1020
|
spawnOptions
|
|
1005
1021
|
);
|
|
1006
1022
|
watchForMarker(child);
|
|
@@ -1031,7 +1047,7 @@ function prepareRun(id) {
|
|
|
1031
1047
|
if (!result) return void 0;
|
|
1032
1048
|
const { item } = result;
|
|
1033
1049
|
const plan2 = resolvePlan(item);
|
|
1034
|
-
const startPhase = item.currentPhase ??
|
|
1050
|
+
const startPhase = (item.currentPhase ?? 1) - 1;
|
|
1035
1051
|
if (item.status === "done") {
|
|
1036
1052
|
console.log(chalk6.green(`Already done: #${id}: ${item.name}`));
|
|
1037
1053
|
return void 0;
|
|
@@ -1066,7 +1082,8 @@ async function run(id, spawnOptions) {
|
|
|
1066
1082
|
function logProgress(id, name, startPhase, total) {
|
|
1067
1083
|
console.log(chalk7.bold(`Running plan for #${id}: ${name}`));
|
|
1068
1084
|
if (startPhase > 0) {
|
|
1069
|
-
|
|
1085
|
+
const phaseNumber = startPhase + 1;
|
|
1086
|
+
console.log(chalk7.dim(`Resuming from phase ${phaseNumber}/${total}
|
|
1070
1087
|
`));
|
|
1071
1088
|
} else {
|
|
1072
1089
|
console.log(chalk7.dim(`${total} phase(s)
|
|
@@ -1173,7 +1190,8 @@ function addPhaseSummary(item, text, phase) {
|
|
|
1173
1190
|
|
|
1174
1191
|
// src/commands/backlog/phaseDone.ts
|
|
1175
1192
|
function phaseDone(id, phase, summary) {
|
|
1176
|
-
const
|
|
1193
|
+
const phaseNumber = Number.parseInt(phase, 10);
|
|
1194
|
+
const phaseIndex = phaseNumber - 1;
|
|
1177
1195
|
writeSignal("phase-done", {
|
|
1178
1196
|
itemId: Number.parseInt(id, 10),
|
|
1179
1197
|
phaseIndex,
|
|
@@ -1185,11 +1203,13 @@ function phaseDone(id, phase, summary) {
|
|
|
1185
1203
|
return;
|
|
1186
1204
|
}
|
|
1187
1205
|
if (result) {
|
|
1188
|
-
addPhaseSummary(result.item, summary,
|
|
1206
|
+
addPhaseSummary(result.item, summary, phaseNumber);
|
|
1189
1207
|
saveBacklog(result.items);
|
|
1190
1208
|
}
|
|
1191
|
-
setCurrentPhase(id,
|
|
1192
|
-
console.log(
|
|
1209
|
+
setCurrentPhase(id, phaseNumber + 1);
|
|
1210
|
+
console.log(
|
|
1211
|
+
chalk9.green(`Phase ${phaseNumber} of item #${id} marked as complete.`)
|
|
1212
|
+
);
|
|
1193
1213
|
}
|
|
1194
1214
|
|
|
1195
1215
|
// src/commands/backlog/plan.ts
|
|
@@ -1221,7 +1241,7 @@ import chalk11 from "chalk";
|
|
|
1221
1241
|
function formatComment(entry) {
|
|
1222
1242
|
const id = entry.id !== void 0 ? chalk11.dim(`#${entry.id} `) : "";
|
|
1223
1243
|
const tag = entry.type === "summary" ? chalk11.magenta("[summary]") : chalk11.cyan("[comment]");
|
|
1224
|
-
const phase = entry.phase !== void 0 ? chalk11.dim(` (phase ${entry.phase
|
|
1244
|
+
const phase = entry.phase !== void 0 ? chalk11.dim(` (phase ${entry.phase})`) : "";
|
|
1225
1245
|
const time = chalk11.dim(entry.timestamp);
|
|
1226
1246
|
return `${id}${tag}${phase} ${time}
|
|
1227
1247
|
${entry.text}`;
|
|
@@ -1268,14 +1288,15 @@ function printPlan(item) {
|
|
|
1268
1288
|
if (!item.plan || item.plan.length === 0) return;
|
|
1269
1289
|
console.log(chalk14.bold("Plan"));
|
|
1270
1290
|
for (const [i, phase] of item.plan.entries()) {
|
|
1271
|
-
const isCurrent = item.currentPhase === i;
|
|
1291
|
+
const isCurrent = item.currentPhase === i + 1;
|
|
1272
1292
|
printPhase(phase, i, isCurrent);
|
|
1273
1293
|
}
|
|
1274
1294
|
console.log();
|
|
1275
1295
|
}
|
|
1276
1296
|
function phaseHeader(index, name, isCurrent) {
|
|
1297
|
+
const phaseNumber = index + 1;
|
|
1277
1298
|
const marker = isCurrent ? chalk14.green("\u25B6 ") : " ";
|
|
1278
|
-
const label2 = isCurrent ? chalk14.green.bold(`Phase ${
|
|
1299
|
+
const label2 = isCurrent ? chalk14.green.bold(`Phase ${phaseNumber}: ${name}`) : `${chalk14.bold(`Phase ${phaseNumber}:`)} ${name}`;
|
|
1279
1300
|
return `${marker}${label2}`;
|
|
1280
1301
|
}
|
|
1281
1302
|
function printPhase(phase, index, isCurrent) {
|
|
@@ -3987,53 +4008,112 @@ async function add(options2) {
|
|
|
3987
4008
|
}
|
|
3988
4009
|
|
|
3989
4010
|
// src/commands/backlog/addPhase.ts
|
|
4011
|
+
import chalk47 from "chalk";
|
|
4012
|
+
|
|
4013
|
+
// src/commands/backlog/insertPhaseAt.ts
|
|
4014
|
+
function insertPhaseAt(db, itemId, phaseIdx, name, tasks, manualChecks, currentPhase) {
|
|
4015
|
+
const run4 = db.transaction(() => {
|
|
4016
|
+
db.pragma("defer_foreign_keys = ON");
|
|
4017
|
+
const toShift = db.prepare(
|
|
4018
|
+
"SELECT idx FROM plan_phases WHERE item_id = ? AND idx >= ? ORDER BY idx DESC"
|
|
4019
|
+
).all(itemId, phaseIdx);
|
|
4020
|
+
for (const p of toShift) {
|
|
4021
|
+
db.prepare(
|
|
4022
|
+
"UPDATE plan_tasks SET phase_idx = ? WHERE item_id = ? AND phase_idx = ?"
|
|
4023
|
+
).run(p.idx + 1, itemId, p.idx);
|
|
4024
|
+
db.prepare(
|
|
4025
|
+
"UPDATE plan_phases SET idx = ? WHERE item_id = ? AND idx = ?"
|
|
4026
|
+
).run(p.idx + 1, itemId, p.idx);
|
|
4027
|
+
}
|
|
4028
|
+
db.prepare(
|
|
4029
|
+
"INSERT INTO plan_phases (item_id, idx, name, manual_checks) VALUES (?, ?, ?, ?)"
|
|
4030
|
+
).run(itemId, phaseIdx, name, manualChecks);
|
|
4031
|
+
const taskStmt = db.prepare(
|
|
4032
|
+
"INSERT INTO plan_tasks (item_id, phase_idx, idx, task) VALUES (?, ?, ?, ?)"
|
|
4033
|
+
);
|
|
4034
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
4035
|
+
taskStmt.run(itemId, phaseIdx, i, tasks[i]);
|
|
4036
|
+
}
|
|
4037
|
+
if (currentPhase !== void 0 && currentPhase - 1 >= phaseIdx) {
|
|
4038
|
+
db.prepare("UPDATE items SET current_phase = ? WHERE id = ?").run(
|
|
4039
|
+
currentPhase + 1,
|
|
4040
|
+
itemId
|
|
4041
|
+
);
|
|
4042
|
+
}
|
|
4043
|
+
});
|
|
4044
|
+
run4();
|
|
4045
|
+
}
|
|
4046
|
+
|
|
4047
|
+
// src/commands/backlog/resolveInsertPosition.ts
|
|
3990
4048
|
import chalk46 from "chalk";
|
|
4049
|
+
function resolveInsertPosition(db, itemId, position) {
|
|
4050
|
+
const { cnt: phaseCount } = db.prepare("SELECT COUNT(*) as cnt FROM plan_phases WHERE item_id = ?").get(itemId);
|
|
4051
|
+
if (position === void 0) return phaseCount;
|
|
4052
|
+
const pos = Number.parseInt(position, 10);
|
|
4053
|
+
if (pos < 1 || pos > phaseCount + 1) {
|
|
4054
|
+
console.log(
|
|
4055
|
+
chalk46.red(
|
|
4056
|
+
`Position ${pos} is out of range. Must be between 1 and ${phaseCount + 1}.`
|
|
4057
|
+
)
|
|
4058
|
+
);
|
|
4059
|
+
process.exitCode = 1;
|
|
4060
|
+
return void 0;
|
|
4061
|
+
}
|
|
4062
|
+
return pos - 1;
|
|
4063
|
+
}
|
|
4064
|
+
|
|
4065
|
+
// src/commands/backlog/serializeManualChecks.ts
|
|
4066
|
+
function serializeManualChecks(manualCheck) {
|
|
4067
|
+
return manualCheck && manualCheck.length > 0 ? JSON.stringify(manualCheck) : null;
|
|
4068
|
+
}
|
|
4069
|
+
|
|
4070
|
+
// src/commands/backlog/addPhase.ts
|
|
3991
4071
|
function addPhase(id, name, options2) {
|
|
3992
4072
|
const result = loadAndFindItem(id);
|
|
3993
4073
|
if (!result) return;
|
|
3994
4074
|
const tasks = options2.task ?? [];
|
|
3995
4075
|
if (tasks.length === 0) {
|
|
3996
|
-
console.log(
|
|
4076
|
+
console.log(chalk47.red("At least one --task is required."));
|
|
3997
4077
|
process.exitCode = 1;
|
|
3998
4078
|
return;
|
|
3999
4079
|
}
|
|
4000
4080
|
const dir = getBacklogDir();
|
|
4001
4081
|
const db = openDb(dir);
|
|
4002
4082
|
const itemId = result.item.id;
|
|
4003
|
-
const
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4083
|
+
const phaseIdx = resolveInsertPosition(db, itemId, options2.position);
|
|
4084
|
+
if (phaseIdx === void 0) return;
|
|
4085
|
+
insertPhaseAt(
|
|
4086
|
+
db,
|
|
4087
|
+
itemId,
|
|
4088
|
+
phaseIdx,
|
|
4089
|
+
name,
|
|
4090
|
+
tasks,
|
|
4091
|
+
serializeManualChecks(options2.manualCheck),
|
|
4092
|
+
result.item.currentPhase
|
|
4011
4093
|
);
|
|
4012
|
-
for (let i = 0; i < tasks.length; i++) {
|
|
4013
|
-
taskStmt.run(itemId, phaseIdx, i, tasks[i]);
|
|
4014
|
-
}
|
|
4015
4094
|
exportToJsonl(db, dir);
|
|
4016
4095
|
commitBacklog(itemId, result.item.name);
|
|
4096
|
+
const verb = options2.position !== void 0 ? "Inserted" : "Added";
|
|
4017
4097
|
console.log(
|
|
4018
|
-
|
|
4019
|
-
|
|
4098
|
+
chalk47.green(
|
|
4099
|
+
`${verb} phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
|
|
4020
4100
|
)
|
|
4021
4101
|
);
|
|
4022
4102
|
}
|
|
4023
4103
|
|
|
4024
4104
|
// src/commands/backlog/init/index.ts
|
|
4025
|
-
import
|
|
4105
|
+
import chalk48 from "chalk";
|
|
4026
4106
|
async function init6() {
|
|
4027
4107
|
if (backlogExists()) {
|
|
4028
|
-
console.log(
|
|
4108
|
+
console.log(chalk48.yellow("Backlog already exists."));
|
|
4029
4109
|
return;
|
|
4030
4110
|
}
|
|
4031
4111
|
saveBacklog([]);
|
|
4032
|
-
console.log(
|
|
4112
|
+
console.log(chalk48.green("Created backlog."));
|
|
4033
4113
|
}
|
|
4034
4114
|
|
|
4035
4115
|
// src/commands/backlog/list/index.ts
|
|
4036
|
-
import
|
|
4116
|
+
import chalk49 from "chalk";
|
|
4037
4117
|
function filterItems(items, options2) {
|
|
4038
4118
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
4039
4119
|
if (!options2.all)
|
|
@@ -4043,7 +4123,7 @@ function filterItems(items, options2) {
|
|
|
4043
4123
|
async function list2(options2) {
|
|
4044
4124
|
if (!backlogExists()) {
|
|
4045
4125
|
console.log(
|
|
4046
|
-
|
|
4126
|
+
chalk49.yellow(
|
|
4047
4127
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
4048
4128
|
)
|
|
4049
4129
|
);
|
|
@@ -4052,12 +4132,12 @@ async function list2(options2) {
|
|
|
4052
4132
|
const allItems = loadBacklog();
|
|
4053
4133
|
const items = filterItems(allItems, options2);
|
|
4054
4134
|
if (items.length === 0) {
|
|
4055
|
-
console.log(
|
|
4135
|
+
console.log(chalk49.dim("Backlog is empty."));
|
|
4056
4136
|
return;
|
|
4057
4137
|
}
|
|
4058
4138
|
for (const item of items) {
|
|
4059
4139
|
console.log(
|
|
4060
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
4140
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk49.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
4061
4141
|
);
|
|
4062
4142
|
if (options2.verbose) {
|
|
4063
4143
|
printVerboseDetails(item);
|
|
@@ -4076,11 +4156,14 @@ function registerItemCommands(cmd) {
|
|
|
4076
4156
|
cmd.command("add-phase <id> <name>").description("Add a phase to an existing backlog item").option("--task <task...>", "Task description (repeatable)").option(
|
|
4077
4157
|
"--manual-check <check...>",
|
|
4078
4158
|
"Manual check description (repeatable)"
|
|
4159
|
+
).option(
|
|
4160
|
+
"--position <position>",
|
|
4161
|
+
"1-indexed position to insert at (default: append)"
|
|
4079
4162
|
).action(addPhase);
|
|
4080
4163
|
}
|
|
4081
4164
|
|
|
4082
4165
|
// src/commands/backlog/link.ts
|
|
4083
|
-
import
|
|
4166
|
+
import chalk51 from "chalk";
|
|
4084
4167
|
|
|
4085
4168
|
// src/commands/backlog/hasCycle.ts
|
|
4086
4169
|
function hasCycle(items, fromId, toId) {
|
|
@@ -4103,11 +4186,11 @@ function hasCycle(items, fromId, toId) {
|
|
|
4103
4186
|
}
|
|
4104
4187
|
|
|
4105
4188
|
// src/commands/backlog/validateLinkTarget.ts
|
|
4106
|
-
import
|
|
4189
|
+
import chalk50 from "chalk";
|
|
4107
4190
|
function validateLinkTarget(items, fromItem, fromId, toId, toNum, linkType) {
|
|
4108
4191
|
const toItem = items.find((i) => i.id === toNum);
|
|
4109
4192
|
if (!toItem) {
|
|
4110
|
-
console.log(
|
|
4193
|
+
console.log(chalk50.red(`Item #${toId} not found.`));
|
|
4111
4194
|
return void 0;
|
|
4112
4195
|
}
|
|
4113
4196
|
if (!fromItem.links) fromItem.links = [];
|
|
@@ -4116,7 +4199,7 @@ function validateLinkTarget(items, fromItem, fromId, toId, toNum, linkType) {
|
|
|
4116
4199
|
);
|
|
4117
4200
|
if (duplicate) {
|
|
4118
4201
|
console.log(
|
|
4119
|
-
|
|
4202
|
+
chalk50.yellow(`Link already exists: #${fromId} ${linkType} #${toId}`)
|
|
4120
4203
|
);
|
|
4121
4204
|
return void 0;
|
|
4122
4205
|
}
|
|
@@ -4127,13 +4210,13 @@ function validateLinkTarget(items, fromItem, fromId, toId, toNum, linkType) {
|
|
|
4127
4210
|
function link(fromId, toId, opts) {
|
|
4128
4211
|
const linkType = opts.type ?? "relates-to";
|
|
4129
4212
|
if (linkType !== "relates-to" && linkType !== "depends-on") {
|
|
4130
|
-
console.log(
|
|
4213
|
+
console.log(chalk51.red(`Invalid link type: ${linkType}`));
|
|
4131
4214
|
return;
|
|
4132
4215
|
}
|
|
4133
4216
|
const fromNum = Number.parseInt(fromId, 10);
|
|
4134
4217
|
const toNum = Number.parseInt(toId, 10);
|
|
4135
4218
|
if (fromNum === toNum) {
|
|
4136
|
-
console.log(
|
|
4219
|
+
console.log(chalk51.red("Cannot link an item to itself."));
|
|
4137
4220
|
return;
|
|
4138
4221
|
}
|
|
4139
4222
|
const result = loadAndFindItem(fromId);
|
|
@@ -4150,7 +4233,7 @@ function link(fromId, toId, opts) {
|
|
|
4150
4233
|
if (!toItem) return;
|
|
4151
4234
|
if (linkType === "depends-on" && hasCycle(items, fromNum, toNum)) {
|
|
4152
4235
|
console.log(
|
|
4153
|
-
|
|
4236
|
+
chalk51.red(
|
|
4154
4237
|
`Cannot add dependency: #${fromId} \u2192 #${toId} would create a circular dependency.`
|
|
4155
4238
|
)
|
|
4156
4239
|
);
|
|
@@ -4160,32 +4243,32 @@ function link(fromId, toId, opts) {
|
|
|
4160
4243
|
fromItem.links.push({ type: linkType, targetId: toNum });
|
|
4161
4244
|
saveBacklog(items);
|
|
4162
4245
|
console.log(
|
|
4163
|
-
|
|
4246
|
+
chalk51.green(`Linked #${fromId} ${linkType} #${toId} (${toItem.name})`)
|
|
4164
4247
|
);
|
|
4165
4248
|
}
|
|
4166
4249
|
|
|
4167
4250
|
// src/commands/backlog/unlink.ts
|
|
4168
|
-
import
|
|
4251
|
+
import chalk52 from "chalk";
|
|
4169
4252
|
function unlink(fromId, toId) {
|
|
4170
4253
|
const toNum = Number.parseInt(toId, 10);
|
|
4171
4254
|
const result = loadAndFindItem(fromId);
|
|
4172
4255
|
if (!result) return;
|
|
4173
4256
|
const { items, item: fromItem } = result;
|
|
4174
4257
|
if (!fromItem.links || fromItem.links.length === 0) {
|
|
4175
|
-
console.log(
|
|
4258
|
+
console.log(chalk52.yellow(`No links found on item #${fromId}.`));
|
|
4176
4259
|
return;
|
|
4177
4260
|
}
|
|
4178
4261
|
const before = fromItem.links.length;
|
|
4179
4262
|
fromItem.links = fromItem.links.filter((l) => l.targetId !== toNum);
|
|
4180
4263
|
if (fromItem.links.length === before) {
|
|
4181
|
-
console.log(
|
|
4264
|
+
console.log(chalk52.yellow(`No link from #${fromId} to #${toId} found.`));
|
|
4182
4265
|
return;
|
|
4183
4266
|
}
|
|
4184
4267
|
if (fromItem.links.length === 0) {
|
|
4185
4268
|
fromItem.links = void 0;
|
|
4186
4269
|
}
|
|
4187
4270
|
saveBacklog(items);
|
|
4188
|
-
console.log(
|
|
4271
|
+
console.log(chalk52.green(`Removed link from #${fromId} to #${toId}.`));
|
|
4189
4272
|
}
|
|
4190
4273
|
|
|
4191
4274
|
// src/commands/backlog/registerLinkCommands.ts
|
|
@@ -4199,46 +4282,47 @@ function registerLinkCommands(cmd) {
|
|
|
4199
4282
|
}
|
|
4200
4283
|
|
|
4201
4284
|
// src/commands/backlog/rewindPhase.ts
|
|
4202
|
-
import
|
|
4203
|
-
function validateRewind(item,
|
|
4285
|
+
import chalk53 from "chalk";
|
|
4286
|
+
function validateRewind(item, phaseNumber) {
|
|
4204
4287
|
if (!item.plan || item.plan.length === 0) {
|
|
4205
4288
|
return `Item #${item.id} has no plan phases.`;
|
|
4206
4289
|
}
|
|
4207
|
-
if (
|
|
4208
|
-
return `Phase ${
|
|
4290
|
+
if (phaseNumber < 1 || phaseNumber > item.plan.length) {
|
|
4291
|
+
return `Phase ${phaseNumber} does not exist. Valid range: 1\u2013${item.plan.length}.`;
|
|
4209
4292
|
}
|
|
4210
|
-
const currentPhase = item.currentPhase ??
|
|
4211
|
-
if (
|
|
4212
|
-
return `Phase ${
|
|
4293
|
+
const currentPhase = item.currentPhase ?? 1;
|
|
4294
|
+
if (phaseNumber >= currentPhase) {
|
|
4295
|
+
return `Phase ${phaseNumber} is not earlier than the current phase (${currentPhase}).`;
|
|
4213
4296
|
}
|
|
4214
4297
|
return void 0;
|
|
4215
4298
|
}
|
|
4216
4299
|
function rewindPhase(id, phase, opts) {
|
|
4217
|
-
const
|
|
4300
|
+
const phaseNumber = Number.parseInt(phase, 10);
|
|
4301
|
+
const phaseIndex = phaseNumber - 1;
|
|
4218
4302
|
const result = loadAndFindItem(id);
|
|
4219
4303
|
if (!result) return;
|
|
4220
4304
|
const { item } = result;
|
|
4221
|
-
const error = validateRewind(item,
|
|
4305
|
+
const error = validateRewind(item, phaseNumber);
|
|
4222
4306
|
if (error) {
|
|
4223
|
-
console.log(
|
|
4307
|
+
console.log(chalk53.red(error));
|
|
4224
4308
|
process.exitCode = 1;
|
|
4225
4309
|
return;
|
|
4226
4310
|
}
|
|
4227
4311
|
const phaseName = item.plan?.[phaseIndex].name;
|
|
4228
4312
|
addComment(
|
|
4229
4313
|
item,
|
|
4230
|
-
`Rewound to phase ${
|
|
4231
|
-
|
|
4314
|
+
`Rewound to phase ${phaseNumber} (${phaseName}): ${opts.reason}`,
|
|
4315
|
+
phaseNumber
|
|
4232
4316
|
);
|
|
4233
4317
|
saveBacklog(result.items);
|
|
4234
|
-
setCurrentPhase(id,
|
|
4318
|
+
setCurrentPhase(id, phaseNumber);
|
|
4235
4319
|
setStatus(id, "in-progress");
|
|
4236
4320
|
writeSignal("rewind", {
|
|
4237
4321
|
itemId: Number.parseInt(id, 10),
|
|
4238
4322
|
targetPhase: phaseIndex
|
|
4239
4323
|
});
|
|
4240
4324
|
console.log(
|
|
4241
|
-
|
|
4325
|
+
chalk53.green(`Rewound item #${id} to phase ${phaseNumber} (${phaseName}).`)
|
|
4242
4326
|
);
|
|
4243
4327
|
}
|
|
4244
4328
|
|
|
@@ -4255,11 +4339,11 @@ function registerRunCommand(cmd) {
|
|
|
4255
4339
|
}
|
|
4256
4340
|
|
|
4257
4341
|
// src/commands/backlog/search/index.ts
|
|
4258
|
-
import
|
|
4342
|
+
import chalk54 from "chalk";
|
|
4259
4343
|
async function search(query) {
|
|
4260
4344
|
if (!backlogExists()) {
|
|
4261
4345
|
console.log(
|
|
4262
|
-
|
|
4346
|
+
chalk54.yellow(
|
|
4263
4347
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
4264
4348
|
)
|
|
4265
4349
|
);
|
|
@@ -4267,18 +4351,18 @@ async function search(query) {
|
|
|
4267
4351
|
}
|
|
4268
4352
|
const items = searchBacklog(query);
|
|
4269
4353
|
if (items.length === 0) {
|
|
4270
|
-
console.log(
|
|
4354
|
+
console.log(chalk54.dim(`No items matching "${query}".`));
|
|
4271
4355
|
return;
|
|
4272
4356
|
}
|
|
4273
4357
|
console.log(
|
|
4274
|
-
|
|
4358
|
+
chalk54.dim(
|
|
4275
4359
|
`${items.length} item${items.length === 1 ? "" : "s"} matching "${query}":
|
|
4276
4360
|
`
|
|
4277
4361
|
)
|
|
4278
4362
|
);
|
|
4279
4363
|
for (const item of items) {
|
|
4280
4364
|
console.log(
|
|
4281
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
4365
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk54.dim(`#${item.id}`)} ${item.name}`
|
|
4282
4366
|
);
|
|
4283
4367
|
}
|
|
4284
4368
|
}
|
|
@@ -4289,31 +4373,31 @@ function registerSearchCommand(cmd) {
|
|
|
4289
4373
|
}
|
|
4290
4374
|
|
|
4291
4375
|
// src/commands/backlog/delete/index.ts
|
|
4292
|
-
import
|
|
4376
|
+
import chalk55 from "chalk";
|
|
4293
4377
|
async function del(id) {
|
|
4294
4378
|
const name = removeItem(id);
|
|
4295
4379
|
if (name) {
|
|
4296
|
-
console.log(
|
|
4380
|
+
console.log(chalk55.green(`Deleted item #${id}: ${name}`));
|
|
4297
4381
|
}
|
|
4298
4382
|
}
|
|
4299
4383
|
|
|
4300
4384
|
// src/commands/backlog/done/index.ts
|
|
4301
|
-
import
|
|
4385
|
+
import chalk56 from "chalk";
|
|
4302
4386
|
async function done(id, summary) {
|
|
4303
4387
|
const result = loadAndFindItem(id);
|
|
4304
4388
|
if (!result) return;
|
|
4305
4389
|
const { item } = result;
|
|
4306
4390
|
if (item.plan && item.plan.length > 0) {
|
|
4307
|
-
const
|
|
4308
|
-
const pending = item.plan.slice(
|
|
4391
|
+
const completedCount = (item.currentPhase ?? 1) - 1;
|
|
4392
|
+
const pending = item.plan.slice(completedCount);
|
|
4309
4393
|
if (pending.length > 0) {
|
|
4310
4394
|
console.log(
|
|
4311
|
-
|
|
4395
|
+
chalk56.red(
|
|
4312
4396
|
`Cannot complete item #${id}: ${pending.length} pending phase(s):`
|
|
4313
4397
|
)
|
|
4314
4398
|
);
|
|
4315
4399
|
for (const phase of pending) {
|
|
4316
|
-
console.log(
|
|
4400
|
+
console.log(chalk56.yellow(` - ${phase.name}`));
|
|
4317
4401
|
}
|
|
4318
4402
|
process.exitCode = 1;
|
|
4319
4403
|
return;
|
|
@@ -4321,34 +4405,34 @@ async function done(id, summary) {
|
|
|
4321
4405
|
}
|
|
4322
4406
|
item.status = "done";
|
|
4323
4407
|
if (summary) {
|
|
4324
|
-
const phase = item.currentPhase ??
|
|
4408
|
+
const phase = item.currentPhase ?? 1;
|
|
4325
4409
|
addPhaseSummary(item, summary, phase);
|
|
4326
4410
|
}
|
|
4327
4411
|
saveBacklog(result.items);
|
|
4328
|
-
console.log(
|
|
4412
|
+
console.log(chalk56.green(`Completed item #${id}: ${item.name}`));
|
|
4329
4413
|
}
|
|
4330
4414
|
|
|
4331
4415
|
// src/commands/backlog/start/index.ts
|
|
4332
|
-
import
|
|
4416
|
+
import chalk57 from "chalk";
|
|
4333
4417
|
async function start(id) {
|
|
4334
4418
|
const name = setStatus(id, "in-progress");
|
|
4335
4419
|
if (name) {
|
|
4336
|
-
console.log(
|
|
4420
|
+
console.log(chalk57.green(`Started item #${id}: ${name}`));
|
|
4337
4421
|
}
|
|
4338
4422
|
}
|
|
4339
4423
|
|
|
4340
4424
|
// src/commands/backlog/wontdo/index.ts
|
|
4341
|
-
import
|
|
4425
|
+
import chalk58 from "chalk";
|
|
4342
4426
|
async function wontdo(id, reason) {
|
|
4343
4427
|
const result = loadAndFindItem(id);
|
|
4344
4428
|
if (!result) return;
|
|
4345
4429
|
result.item.status = "wontdo";
|
|
4346
4430
|
if (reason) {
|
|
4347
|
-
const phase = result.item.currentPhase ??
|
|
4431
|
+
const phase = result.item.currentPhase ?? 1;
|
|
4348
4432
|
addPhaseSummary(result.item, reason, phase);
|
|
4349
4433
|
}
|
|
4350
4434
|
saveBacklog(result.items);
|
|
4351
|
-
console.log(
|
|
4435
|
+
console.log(chalk58.red(`Won't do item #${id}: ${result.item.name}`));
|
|
4352
4436
|
}
|
|
4353
4437
|
|
|
4354
4438
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -4360,22 +4444,25 @@ function registerStatusCommands(cmd) {
|
|
|
4360
4444
|
}
|
|
4361
4445
|
|
|
4362
4446
|
// src/commands/backlog/removePhase.ts
|
|
4363
|
-
import
|
|
4447
|
+
import chalk60 from "chalk";
|
|
4364
4448
|
|
|
4365
4449
|
// src/commands/backlog/findPhase.ts
|
|
4366
|
-
import
|
|
4450
|
+
import chalk59 from "chalk";
|
|
4367
4451
|
function findPhase(id, phase) {
|
|
4368
4452
|
const result = loadAndFindItem(id);
|
|
4369
4453
|
if (!result) return void 0;
|
|
4370
4454
|
const dir = getBacklogDir();
|
|
4371
4455
|
const db = openDb(dir);
|
|
4372
4456
|
const itemId = result.item.id;
|
|
4373
|
-
const
|
|
4457
|
+
const phaseNumber = Number.parseInt(phase, 10);
|
|
4458
|
+
const phaseIdx = phaseNumber - 1;
|
|
4374
4459
|
const existing = db.prepare(
|
|
4375
4460
|
"SELECT COUNT(*) as cnt FROM plan_phases WHERE item_id = ? AND idx = ?"
|
|
4376
4461
|
).get(itemId, phaseIdx);
|
|
4377
4462
|
if (existing.cnt === 0) {
|
|
4378
|
-
console.log(
|
|
4463
|
+
console.log(
|
|
4464
|
+
chalk59.red(`Phase ${phaseNumber} not found on item #${itemId}.`)
|
|
4465
|
+
);
|
|
4379
4466
|
process.exitCode = 1;
|
|
4380
4467
|
return void 0;
|
|
4381
4468
|
}
|
|
@@ -4397,14 +4484,15 @@ function reindexPhases(db, itemId) {
|
|
|
4397
4484
|
}
|
|
4398
4485
|
function adjustCurrentPhase(db, item, removedIdx) {
|
|
4399
4486
|
if (item.currentPhase === void 0) return;
|
|
4400
|
-
|
|
4487
|
+
const currentIdx = item.currentPhase - 1;
|
|
4488
|
+
if (removedIdx < currentIdx) {
|
|
4401
4489
|
db.prepare("UPDATE items SET current_phase = ? WHERE id = ?").run(
|
|
4402
4490
|
item.currentPhase - 1,
|
|
4403
4491
|
item.id
|
|
4404
4492
|
);
|
|
4405
|
-
} else if (removedIdx ===
|
|
4493
|
+
} else if (removedIdx === currentIdx) {
|
|
4406
4494
|
const { cnt } = db.prepare("SELECT COUNT(*) as cnt FROM plan_phases WHERE item_id = ?").get(item.id);
|
|
4407
|
-
const newPhase = cnt === 0 ? null : Math.min(item.currentPhase, cnt
|
|
4495
|
+
const newPhase = cnt === 0 ? null : Math.min(item.currentPhase, cnt);
|
|
4408
4496
|
db.prepare("UPDATE items SET current_phase = ? WHERE id = ?").run(
|
|
4409
4497
|
newPhase,
|
|
4410
4498
|
item.id
|
|
@@ -4431,23 +4519,25 @@ function removePhase(id, phase) {
|
|
|
4431
4519
|
run4();
|
|
4432
4520
|
exportToJsonl(db, dir);
|
|
4433
4521
|
commitBacklog(itemId, result.item.name);
|
|
4434
|
-
console.log(
|
|
4522
|
+
console.log(
|
|
4523
|
+
chalk60.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
4524
|
+
);
|
|
4435
4525
|
}
|
|
4436
4526
|
|
|
4437
4527
|
// src/commands/backlog/update/index.ts
|
|
4438
|
-
import
|
|
4528
|
+
import chalk62 from "chalk";
|
|
4439
4529
|
|
|
4440
4530
|
// src/commands/backlog/update/buildUpdateSql.ts
|
|
4441
|
-
import
|
|
4531
|
+
import chalk61 from "chalk";
|
|
4442
4532
|
function buildUpdateSql(options2) {
|
|
4443
4533
|
const { name, desc, type, ac } = options2;
|
|
4444
4534
|
if (!name && !desc && !type && !ac) {
|
|
4445
|
-
console.log(
|
|
4535
|
+
console.log(chalk61.red("Nothing to update. Provide at least one flag."));
|
|
4446
4536
|
process.exitCode = 1;
|
|
4447
4537
|
return void 0;
|
|
4448
4538
|
}
|
|
4449
4539
|
if (type && type !== "story" && type !== "bug") {
|
|
4450
|
-
console.log(
|
|
4540
|
+
console.log(chalk61.red('Invalid type. Must be "story" or "bug".'));
|
|
4451
4541
|
process.exitCode = 1;
|
|
4452
4542
|
return void 0;
|
|
4453
4543
|
}
|
|
@@ -4492,11 +4582,11 @@ function update(id, options2) {
|
|
|
4492
4582
|
);
|
|
4493
4583
|
exportToJsonl(db, dir);
|
|
4494
4584
|
commitBacklog(itemId, options2.name ?? result.item.name);
|
|
4495
|
-
console.log(
|
|
4585
|
+
console.log(chalk62.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
4496
4586
|
}
|
|
4497
4587
|
|
|
4498
4588
|
// src/commands/backlog/updatePhase.ts
|
|
4499
|
-
import
|
|
4589
|
+
import chalk63 from "chalk";
|
|
4500
4590
|
|
|
4501
4591
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
4502
4592
|
function applyPhaseUpdate(db, itemId, phaseIdx, fields) {
|
|
@@ -4530,7 +4620,7 @@ function applyPhaseUpdate(db, itemId, phaseIdx, fields) {
|
|
|
4530
4620
|
function updatePhase(id, phase, options2) {
|
|
4531
4621
|
const { name, task, manualCheck } = options2;
|
|
4532
4622
|
if (!name && !task && !manualCheck) {
|
|
4533
|
-
console.log(
|
|
4623
|
+
console.log(chalk63.red("Nothing to update. Provide at least one flag."));
|
|
4534
4624
|
process.exitCode = 1;
|
|
4535
4625
|
return;
|
|
4536
4626
|
}
|
|
@@ -4546,7 +4636,9 @@ function updatePhase(id, phase, options2) {
|
|
|
4546
4636
|
manualCheck && "manual checks"
|
|
4547
4637
|
].filter(Boolean).join(", ");
|
|
4548
4638
|
console.log(
|
|
4549
|
-
|
|
4639
|
+
chalk63.green(
|
|
4640
|
+
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
4641
|
+
)
|
|
4550
4642
|
);
|
|
4551
4643
|
}
|
|
4552
4644
|
|
|
@@ -5049,11 +5141,11 @@ function assertCliExists(cli) {
|
|
|
5049
5141
|
}
|
|
5050
5142
|
|
|
5051
5143
|
// src/commands/permitCliReads/colorize.ts
|
|
5052
|
-
import
|
|
5144
|
+
import chalk64 from "chalk";
|
|
5053
5145
|
function colorize(plainOutput) {
|
|
5054
5146
|
return plainOutput.split("\n").map((line) => {
|
|
5055
|
-
if (line.startsWith(" R ")) return
|
|
5056
|
-
if (line.startsWith(" W ")) return
|
|
5147
|
+
if (line.startsWith(" R ")) return chalk64.green(line);
|
|
5148
|
+
if (line.startsWith(" W ")) return chalk64.red(line);
|
|
5057
5149
|
return line;
|
|
5058
5150
|
}).join("\n");
|
|
5059
5151
|
}
|
|
@@ -5351,48 +5443,48 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
5351
5443
|
}
|
|
5352
5444
|
|
|
5353
5445
|
// src/commands/deny/denyAdd.ts
|
|
5354
|
-
import
|
|
5446
|
+
import chalk65 from "chalk";
|
|
5355
5447
|
function denyAdd(pattern2, message) {
|
|
5356
5448
|
const config = loadProjectConfig();
|
|
5357
5449
|
const deny = config.deny ?? [];
|
|
5358
5450
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
5359
|
-
console.log(
|
|
5451
|
+
console.log(chalk65.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
5360
5452
|
return;
|
|
5361
5453
|
}
|
|
5362
5454
|
deny.push({ pattern: pattern2, message });
|
|
5363
5455
|
config.deny = deny;
|
|
5364
5456
|
saveConfig(config);
|
|
5365
|
-
console.log(
|
|
5457
|
+
console.log(chalk65.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
5366
5458
|
}
|
|
5367
5459
|
|
|
5368
5460
|
// src/commands/deny/denyList.ts
|
|
5369
|
-
import
|
|
5461
|
+
import chalk66 from "chalk";
|
|
5370
5462
|
function denyList() {
|
|
5371
5463
|
const config = loadConfig();
|
|
5372
5464
|
const deny = config.deny;
|
|
5373
5465
|
if (!deny || deny.length === 0) {
|
|
5374
|
-
console.log(
|
|
5466
|
+
console.log(chalk66.dim("No deny rules configured."));
|
|
5375
5467
|
return;
|
|
5376
5468
|
}
|
|
5377
5469
|
for (const rule of deny) {
|
|
5378
|
-
console.log(`${
|
|
5470
|
+
console.log(`${chalk66.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
5379
5471
|
}
|
|
5380
5472
|
}
|
|
5381
5473
|
|
|
5382
5474
|
// src/commands/deny/denyRemove.ts
|
|
5383
|
-
import
|
|
5475
|
+
import chalk67 from "chalk";
|
|
5384
5476
|
function denyRemove(pattern2) {
|
|
5385
5477
|
const config = loadProjectConfig();
|
|
5386
5478
|
const deny = config.deny ?? [];
|
|
5387
5479
|
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
5388
5480
|
if (index === -1) {
|
|
5389
|
-
console.log(
|
|
5481
|
+
console.log(chalk67.yellow(`No deny rule found for: ${pattern2}`));
|
|
5390
5482
|
return;
|
|
5391
5483
|
}
|
|
5392
5484
|
deny.splice(index, 1);
|
|
5393
5485
|
config.deny = deny.length > 0 ? deny : void 0;
|
|
5394
5486
|
saveConfig(config);
|
|
5395
|
-
console.log(
|
|
5487
|
+
console.log(chalk67.green(`Removed deny rule: ${pattern2}`));
|
|
5396
5488
|
}
|
|
5397
5489
|
|
|
5398
5490
|
// src/commands/registerDeny.ts
|
|
@@ -5421,15 +5513,15 @@ function registerCliHook(program2) {
|
|
|
5421
5513
|
}
|
|
5422
5514
|
|
|
5423
5515
|
// src/commands/complexity/analyze.ts
|
|
5424
|
-
import
|
|
5516
|
+
import chalk73 from "chalk";
|
|
5425
5517
|
|
|
5426
5518
|
// src/commands/complexity/cyclomatic.ts
|
|
5427
|
-
import
|
|
5519
|
+
import chalk69 from "chalk";
|
|
5428
5520
|
|
|
5429
5521
|
// src/commands/complexity/shared/index.ts
|
|
5430
5522
|
import fs12 from "fs";
|
|
5431
5523
|
import path20 from "path";
|
|
5432
|
-
import
|
|
5524
|
+
import chalk68 from "chalk";
|
|
5433
5525
|
import ts5 from "typescript";
|
|
5434
5526
|
|
|
5435
5527
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -5675,7 +5767,7 @@ function createSourceFromFile(filePath) {
|
|
|
5675
5767
|
function withSourceFiles(pattern2, callback) {
|
|
5676
5768
|
const files = findSourceFiles2(pattern2);
|
|
5677
5769
|
if (files.length === 0) {
|
|
5678
|
-
console.log(
|
|
5770
|
+
console.log(chalk68.yellow("No files found matching pattern"));
|
|
5679
5771
|
return void 0;
|
|
5680
5772
|
}
|
|
5681
5773
|
return callback(files);
|
|
@@ -5708,11 +5800,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5708
5800
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
5709
5801
|
for (const { file, name, complexity } of results) {
|
|
5710
5802
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
5711
|
-
const color = exceedsThreshold ?
|
|
5712
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
5803
|
+
const color = exceedsThreshold ? chalk69.red : chalk69.white;
|
|
5804
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk69.cyan(complexity)}`);
|
|
5713
5805
|
}
|
|
5714
5806
|
console.log(
|
|
5715
|
-
|
|
5807
|
+
chalk69.dim(
|
|
5716
5808
|
`
|
|
5717
5809
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
5718
5810
|
)
|
|
@@ -5724,7 +5816,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
5724
5816
|
}
|
|
5725
5817
|
|
|
5726
5818
|
// src/commands/complexity/halstead.ts
|
|
5727
|
-
import
|
|
5819
|
+
import chalk70 from "chalk";
|
|
5728
5820
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
5729
5821
|
withSourceFiles(pattern2, (files) => {
|
|
5730
5822
|
const results = [];
|
|
@@ -5739,13 +5831,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5739
5831
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
5740
5832
|
for (const { file, name, metrics } of results) {
|
|
5741
5833
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
5742
|
-
const color = exceedsThreshold ?
|
|
5834
|
+
const color = exceedsThreshold ? chalk70.red : chalk70.white;
|
|
5743
5835
|
console.log(
|
|
5744
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
5836
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk70.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk70.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk70.magenta(metrics.effort.toFixed(1))}`
|
|
5745
5837
|
);
|
|
5746
5838
|
}
|
|
5747
5839
|
console.log(
|
|
5748
|
-
|
|
5840
|
+
chalk70.dim(
|
|
5749
5841
|
`
|
|
5750
5842
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
5751
5843
|
)
|
|
@@ -5760,28 +5852,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
5760
5852
|
import fs13 from "fs";
|
|
5761
5853
|
|
|
5762
5854
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
5763
|
-
import
|
|
5855
|
+
import chalk71 from "chalk";
|
|
5764
5856
|
function displayMaintainabilityResults(results, threshold) {
|
|
5765
5857
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
5766
5858
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
5767
|
-
console.log(
|
|
5859
|
+
console.log(chalk71.green("All files pass maintainability threshold"));
|
|
5768
5860
|
} else {
|
|
5769
5861
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
5770
|
-
const color = threshold !== void 0 ?
|
|
5862
|
+
const color = threshold !== void 0 ? chalk71.red : chalk71.white;
|
|
5771
5863
|
console.log(
|
|
5772
|
-
`${color(file)} \u2192 avg: ${
|
|
5864
|
+
`${color(file)} \u2192 avg: ${chalk71.cyan(avgMaintainability.toFixed(1))}, min: ${chalk71.yellow(minMaintainability.toFixed(1))}`
|
|
5773
5865
|
);
|
|
5774
5866
|
}
|
|
5775
5867
|
}
|
|
5776
|
-
console.log(
|
|
5868
|
+
console.log(chalk71.dim(`
|
|
5777
5869
|
Analyzed ${results.length} files`));
|
|
5778
5870
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
5779
5871
|
console.error(
|
|
5780
|
-
|
|
5872
|
+
chalk71.red(
|
|
5781
5873
|
`
|
|
5782
5874
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
5783
5875
|
|
|
5784
|
-
\u26A0\uFE0F ${
|
|
5876
|
+
\u26A0\uFE0F ${chalk71.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.`
|
|
5785
5877
|
)
|
|
5786
5878
|
);
|
|
5787
5879
|
process.exit(1);
|
|
@@ -5838,7 +5930,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5838
5930
|
|
|
5839
5931
|
// src/commands/complexity/sloc.ts
|
|
5840
5932
|
import fs14 from "fs";
|
|
5841
|
-
import
|
|
5933
|
+
import chalk72 from "chalk";
|
|
5842
5934
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
5843
5935
|
withSourceFiles(pattern2, (files) => {
|
|
5844
5936
|
const results = [];
|
|
@@ -5854,12 +5946,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5854
5946
|
results.sort((a, b) => b.lines - a.lines);
|
|
5855
5947
|
for (const { file, lines } of results) {
|
|
5856
5948
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
5857
|
-
const color = exceedsThreshold ?
|
|
5858
|
-
console.log(`${color(file)} \u2192 ${
|
|
5949
|
+
const color = exceedsThreshold ? chalk72.red : chalk72.white;
|
|
5950
|
+
console.log(`${color(file)} \u2192 ${chalk72.cyan(lines)} lines`);
|
|
5859
5951
|
}
|
|
5860
5952
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
5861
5953
|
console.log(
|
|
5862
|
-
|
|
5954
|
+
chalk72.dim(`
|
|
5863
5955
|
Total: ${total} lines across ${files.length} files`)
|
|
5864
5956
|
);
|
|
5865
5957
|
if (hasViolation) {
|
|
@@ -5873,21 +5965,21 @@ async function analyze(pattern2) {
|
|
|
5873
5965
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
5874
5966
|
const files = findSourceFiles2(searchPattern);
|
|
5875
5967
|
if (files.length === 0) {
|
|
5876
|
-
console.log(
|
|
5968
|
+
console.log(chalk73.yellow("No files found matching pattern"));
|
|
5877
5969
|
return;
|
|
5878
5970
|
}
|
|
5879
5971
|
if (files.length === 1) {
|
|
5880
5972
|
const file = files[0];
|
|
5881
|
-
console.log(
|
|
5973
|
+
console.log(chalk73.bold.underline("SLOC"));
|
|
5882
5974
|
await sloc(file);
|
|
5883
5975
|
console.log();
|
|
5884
|
-
console.log(
|
|
5976
|
+
console.log(chalk73.bold.underline("Cyclomatic Complexity"));
|
|
5885
5977
|
await cyclomatic(file);
|
|
5886
5978
|
console.log();
|
|
5887
|
-
console.log(
|
|
5979
|
+
console.log(chalk73.bold.underline("Halstead Metrics"));
|
|
5888
5980
|
await halstead(file);
|
|
5889
5981
|
console.log();
|
|
5890
|
-
console.log(
|
|
5982
|
+
console.log(chalk73.bold.underline("Maintainability Index"));
|
|
5891
5983
|
await maintainability(file);
|
|
5892
5984
|
return;
|
|
5893
5985
|
}
|
|
@@ -5914,7 +6006,7 @@ function registerComplexity(program2) {
|
|
|
5914
6006
|
}
|
|
5915
6007
|
|
|
5916
6008
|
// src/commands/config/index.ts
|
|
5917
|
-
import
|
|
6009
|
+
import chalk74 from "chalk";
|
|
5918
6010
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
5919
6011
|
|
|
5920
6012
|
// src/commands/config/setNestedValue.ts
|
|
@@ -5977,7 +6069,7 @@ function formatIssuePath(issue, key) {
|
|
|
5977
6069
|
function printValidationErrors(issues, key) {
|
|
5978
6070
|
for (const issue of issues) {
|
|
5979
6071
|
console.error(
|
|
5980
|
-
|
|
6072
|
+
chalk74.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
5981
6073
|
);
|
|
5982
6074
|
}
|
|
5983
6075
|
}
|
|
@@ -5994,7 +6086,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
5994
6086
|
function assertNotGlobalOnly(key, global) {
|
|
5995
6087
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
5996
6088
|
console.error(
|
|
5997
|
-
|
|
6089
|
+
chalk74.red(
|
|
5998
6090
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
5999
6091
|
)
|
|
6000
6092
|
);
|
|
@@ -6017,7 +6109,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
6017
6109
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
6018
6110
|
const target = options2.global ? "global" : "project";
|
|
6019
6111
|
console.log(
|
|
6020
|
-
|
|
6112
|
+
chalk74.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
6021
6113
|
);
|
|
6022
6114
|
}
|
|
6023
6115
|
function configList() {
|
|
@@ -6026,7 +6118,7 @@ function configList() {
|
|
|
6026
6118
|
}
|
|
6027
6119
|
|
|
6028
6120
|
// src/commands/config/configGet.ts
|
|
6029
|
-
import
|
|
6121
|
+
import chalk75 from "chalk";
|
|
6030
6122
|
|
|
6031
6123
|
// src/commands/config/getNestedValue.ts
|
|
6032
6124
|
function isTraversable(value) {
|
|
@@ -6058,7 +6150,7 @@ function requireNestedValue(config, key) {
|
|
|
6058
6150
|
return value;
|
|
6059
6151
|
}
|
|
6060
6152
|
function exitKeyNotSet(key) {
|
|
6061
|
-
console.error(
|
|
6153
|
+
console.error(chalk75.red(`Key "${key}" is not set`));
|
|
6062
6154
|
process.exit(1);
|
|
6063
6155
|
}
|
|
6064
6156
|
|
|
@@ -6072,7 +6164,7 @@ function registerConfig(program2) {
|
|
|
6072
6164
|
|
|
6073
6165
|
// src/commands/deploy/redirect.ts
|
|
6074
6166
|
import { existsSync as existsSync22, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "fs";
|
|
6075
|
-
import
|
|
6167
|
+
import chalk76 from "chalk";
|
|
6076
6168
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
6077
6169
|
if (!window.location.pathname.endsWith('/')) {
|
|
6078
6170
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -6081,22 +6173,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
6081
6173
|
function redirect() {
|
|
6082
6174
|
const indexPath = "index.html";
|
|
6083
6175
|
if (!existsSync22(indexPath)) {
|
|
6084
|
-
console.log(
|
|
6176
|
+
console.log(chalk76.yellow("No index.html found"));
|
|
6085
6177
|
return;
|
|
6086
6178
|
}
|
|
6087
6179
|
const content = readFileSync19(indexPath, "utf-8");
|
|
6088
6180
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
6089
|
-
console.log(
|
|
6181
|
+
console.log(chalk76.dim("Trailing slash script already present"));
|
|
6090
6182
|
return;
|
|
6091
6183
|
}
|
|
6092
6184
|
const headCloseIndex = content.indexOf("</head>");
|
|
6093
6185
|
if (headCloseIndex === -1) {
|
|
6094
|
-
console.log(
|
|
6186
|
+
console.log(chalk76.red("Could not find </head> tag in index.html"));
|
|
6095
6187
|
return;
|
|
6096
6188
|
}
|
|
6097
6189
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
6098
6190
|
writeFileSync18(indexPath, newContent);
|
|
6099
|
-
console.log(
|
|
6191
|
+
console.log(chalk76.green("Added trailing slash redirect to index.html"));
|
|
6100
6192
|
}
|
|
6101
6193
|
|
|
6102
6194
|
// src/commands/registerDeploy.ts
|
|
@@ -6123,7 +6215,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
6123
6215
|
|
|
6124
6216
|
// src/commands/devlog/shared.ts
|
|
6125
6217
|
import { execSync as execSync18 } from "child_process";
|
|
6126
|
-
import
|
|
6218
|
+
import chalk77 from "chalk";
|
|
6127
6219
|
|
|
6128
6220
|
// src/shared/getRepoName.ts
|
|
6129
6221
|
import { existsSync as existsSync23, readFileSync as readFileSync20 } from "fs";
|
|
@@ -6232,13 +6324,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
6232
6324
|
}
|
|
6233
6325
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
6234
6326
|
for (const commit2 of commits) {
|
|
6235
|
-
console.log(` ${
|
|
6327
|
+
console.log(` ${chalk77.yellow(commit2.hash)} ${commit2.message}`);
|
|
6236
6328
|
if (verbose) {
|
|
6237
6329
|
const visibleFiles = commit2.files.filter(
|
|
6238
6330
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
6239
6331
|
);
|
|
6240
6332
|
for (const file of visibleFiles) {
|
|
6241
|
-
console.log(` ${
|
|
6333
|
+
console.log(` ${chalk77.dim(file)}`);
|
|
6242
6334
|
}
|
|
6243
6335
|
}
|
|
6244
6336
|
}
|
|
@@ -6263,15 +6355,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
6263
6355
|
}
|
|
6264
6356
|
|
|
6265
6357
|
// src/commands/devlog/list/printDateHeader.ts
|
|
6266
|
-
import
|
|
6358
|
+
import chalk78 from "chalk";
|
|
6267
6359
|
function printDateHeader(date, isSkipped, entries) {
|
|
6268
6360
|
if (isSkipped) {
|
|
6269
|
-
console.log(`${
|
|
6361
|
+
console.log(`${chalk78.bold.blue(date)} ${chalk78.dim("skipped")}`);
|
|
6270
6362
|
} else if (entries && entries.length > 0) {
|
|
6271
|
-
const entryInfo = entries.map((e) => `${
|
|
6272
|
-
console.log(`${
|
|
6363
|
+
const entryInfo = entries.map((e) => `${chalk78.green(e.version)} ${e.title}`).join(" | ");
|
|
6364
|
+
console.log(`${chalk78.bold.blue(date)} ${entryInfo}`);
|
|
6273
6365
|
} else {
|
|
6274
|
-
console.log(`${
|
|
6366
|
+
console.log(`${chalk78.bold.blue(date)} ${chalk78.red("\u26A0 devlog missing")}`);
|
|
6275
6367
|
}
|
|
6276
6368
|
}
|
|
6277
6369
|
|
|
@@ -6375,24 +6467,24 @@ function bumpVersion(version2, type) {
|
|
|
6375
6467
|
|
|
6376
6468
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
6377
6469
|
import { execSync as execSync21 } from "child_process";
|
|
6378
|
-
import
|
|
6470
|
+
import chalk80 from "chalk";
|
|
6379
6471
|
|
|
6380
6472
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
6381
|
-
import
|
|
6473
|
+
import chalk79 from "chalk";
|
|
6382
6474
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
6383
6475
|
if (conventional && firstHash) {
|
|
6384
6476
|
const version2 = getVersionAtCommit(firstHash);
|
|
6385
6477
|
if (version2) {
|
|
6386
|
-
console.log(`${
|
|
6478
|
+
console.log(`${chalk79.bold("version:")} ${stripToMinor(version2)}`);
|
|
6387
6479
|
} else {
|
|
6388
|
-
console.log(`${
|
|
6480
|
+
console.log(`${chalk79.bold("version:")} ${chalk79.red("unknown")}`);
|
|
6389
6481
|
}
|
|
6390
6482
|
} else if (patchVersion && minorVersion) {
|
|
6391
6483
|
console.log(
|
|
6392
|
-
`${
|
|
6484
|
+
`${chalk79.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
6393
6485
|
);
|
|
6394
6486
|
} else {
|
|
6395
|
-
console.log(`${
|
|
6487
|
+
console.log(`${chalk79.bold("version:")} v0.1 (initial)`);
|
|
6396
6488
|
}
|
|
6397
6489
|
}
|
|
6398
6490
|
|
|
@@ -6439,16 +6531,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
6439
6531
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
6440
6532
|
}
|
|
6441
6533
|
function logName(repoName) {
|
|
6442
|
-
console.log(`${
|
|
6534
|
+
console.log(`${chalk80.bold("name:")} ${repoName}`);
|
|
6443
6535
|
}
|
|
6444
6536
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
6445
6537
|
logName(ctx.repoName);
|
|
6446
6538
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
6447
|
-
console.log(
|
|
6539
|
+
console.log(chalk80.bold.blue(targetDate));
|
|
6448
6540
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
6449
6541
|
}
|
|
6450
6542
|
function logNoCommits(lastInfo) {
|
|
6451
|
-
console.log(
|
|
6543
|
+
console.log(chalk80.dim(noCommitsMessage(!!lastInfo)));
|
|
6452
6544
|
}
|
|
6453
6545
|
|
|
6454
6546
|
// src/commands/devlog/next/index.ts
|
|
@@ -6489,11 +6581,11 @@ function next2(options2) {
|
|
|
6489
6581
|
import { execSync as execSync22 } from "child_process";
|
|
6490
6582
|
|
|
6491
6583
|
// src/commands/devlog/repos/printReposTable.ts
|
|
6492
|
-
import
|
|
6584
|
+
import chalk81 from "chalk";
|
|
6493
6585
|
function colorStatus(status2) {
|
|
6494
|
-
if (status2 === "missing") return
|
|
6495
|
-
if (status2 === "outdated") return
|
|
6496
|
-
return
|
|
6586
|
+
if (status2 === "missing") return chalk81.red(status2);
|
|
6587
|
+
if (status2 === "outdated") return chalk81.yellow(status2);
|
|
6588
|
+
return chalk81.green(status2);
|
|
6497
6589
|
}
|
|
6498
6590
|
function formatRow(row, nameWidth) {
|
|
6499
6591
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -6507,8 +6599,8 @@ function printReposTable(rows) {
|
|
|
6507
6599
|
"Last Devlog".padEnd(11),
|
|
6508
6600
|
"Status"
|
|
6509
6601
|
].join(" ");
|
|
6510
|
-
console.log(
|
|
6511
|
-
console.log(
|
|
6602
|
+
console.log(chalk81.dim(header));
|
|
6603
|
+
console.log(chalk81.dim("-".repeat(header.length)));
|
|
6512
6604
|
for (const row of rows) {
|
|
6513
6605
|
console.log(formatRow(row, nameWidth));
|
|
6514
6606
|
}
|
|
@@ -6566,14 +6658,14 @@ function repos(options2) {
|
|
|
6566
6658
|
// src/commands/devlog/skip.ts
|
|
6567
6659
|
import { writeFileSync as writeFileSync19 } from "fs";
|
|
6568
6660
|
import { join as join22 } from "path";
|
|
6569
|
-
import
|
|
6661
|
+
import chalk82 from "chalk";
|
|
6570
6662
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
6571
6663
|
function getBlogConfigPath() {
|
|
6572
6664
|
return join22(BLOG_REPO_ROOT, "assist.yml");
|
|
6573
6665
|
}
|
|
6574
6666
|
function skip(date) {
|
|
6575
6667
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
6576
|
-
console.log(
|
|
6668
|
+
console.log(chalk82.red("Invalid date format. Use YYYY-MM-DD"));
|
|
6577
6669
|
process.exit(1);
|
|
6578
6670
|
}
|
|
6579
6671
|
const repoName = getRepoName();
|
|
@@ -6584,7 +6676,7 @@ function skip(date) {
|
|
|
6584
6676
|
const skipDays = skip2[repoName] ?? [];
|
|
6585
6677
|
if (skipDays.includes(date)) {
|
|
6586
6678
|
console.log(
|
|
6587
|
-
|
|
6679
|
+
chalk82.yellow(`${date} is already in skip list for ${repoName}`)
|
|
6588
6680
|
);
|
|
6589
6681
|
return;
|
|
6590
6682
|
}
|
|
@@ -6594,20 +6686,20 @@ function skip(date) {
|
|
|
6594
6686
|
devlog.skip = skip2;
|
|
6595
6687
|
config.devlog = devlog;
|
|
6596
6688
|
writeFileSync19(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
6597
|
-
console.log(
|
|
6689
|
+
console.log(chalk82.green(`Added ${date} to skip list for ${repoName}`));
|
|
6598
6690
|
}
|
|
6599
6691
|
|
|
6600
6692
|
// src/commands/devlog/version.ts
|
|
6601
|
-
import
|
|
6693
|
+
import chalk83 from "chalk";
|
|
6602
6694
|
function version() {
|
|
6603
6695
|
const config = loadConfig();
|
|
6604
6696
|
const name = getRepoName();
|
|
6605
6697
|
const lastInfo = getLastVersionInfo(name, config);
|
|
6606
6698
|
const lastVersion = lastInfo?.version ?? null;
|
|
6607
6699
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
6608
|
-
console.log(`${
|
|
6609
|
-
console.log(`${
|
|
6610
|
-
console.log(`${
|
|
6700
|
+
console.log(`${chalk83.bold("name:")} ${name}`);
|
|
6701
|
+
console.log(`${chalk83.bold("last:")} ${lastVersion ?? chalk83.dim("none")}`);
|
|
6702
|
+
console.log(`${chalk83.bold("next:")} ${nextVersion ?? chalk83.dim("none")}`);
|
|
6611
6703
|
}
|
|
6612
6704
|
|
|
6613
6705
|
// src/commands/registerDevlog.ts
|
|
@@ -6631,7 +6723,7 @@ function registerDevlog(program2) {
|
|
|
6631
6723
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
6632
6724
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
6633
6725
|
import { join as join23 } from "path";
|
|
6634
|
-
import
|
|
6726
|
+
import chalk84 from "chalk";
|
|
6635
6727
|
|
|
6636
6728
|
// src/shared/findRepoRoot.ts
|
|
6637
6729
|
import { existsSync as existsSync24 } from "fs";
|
|
@@ -6694,14 +6786,14 @@ function checkBuildLocks(startDir) {
|
|
|
6694
6786
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
6695
6787
|
if (locked) {
|
|
6696
6788
|
console.error(
|
|
6697
|
-
|
|
6789
|
+
chalk84.red("Build output locked (is VS debugging?): ") + locked
|
|
6698
6790
|
);
|
|
6699
6791
|
process.exit(1);
|
|
6700
6792
|
}
|
|
6701
6793
|
}
|
|
6702
6794
|
async function checkBuildLocksCommand() {
|
|
6703
6795
|
checkBuildLocks();
|
|
6704
|
-
console.log(
|
|
6796
|
+
console.log(chalk84.green("No build locks detected"));
|
|
6705
6797
|
}
|
|
6706
6798
|
|
|
6707
6799
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -6800,30 +6892,30 @@ function escapeRegex(s) {
|
|
|
6800
6892
|
}
|
|
6801
6893
|
|
|
6802
6894
|
// src/commands/dotnet/printTree.ts
|
|
6803
|
-
import
|
|
6895
|
+
import chalk85 from "chalk";
|
|
6804
6896
|
function printNodes(nodes, prefix2) {
|
|
6805
6897
|
for (let i = 0; i < nodes.length; i++) {
|
|
6806
6898
|
const isLast = i === nodes.length - 1;
|
|
6807
6899
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
6808
6900
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
6809
6901
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
6810
|
-
const label2 = isMissing ?
|
|
6902
|
+
const label2 = isMissing ? chalk85.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
6811
6903
|
console.log(`${prefix2}${connector}${label2}`);
|
|
6812
6904
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
6813
6905
|
}
|
|
6814
6906
|
}
|
|
6815
6907
|
function printTree(tree, totalCount, solutions) {
|
|
6816
|
-
console.log(
|
|
6817
|
-
console.log(
|
|
6908
|
+
console.log(chalk85.bold("\nProject Dependency Tree"));
|
|
6909
|
+
console.log(chalk85.cyan(tree.relativePath));
|
|
6818
6910
|
printNodes(tree.children, "");
|
|
6819
|
-
console.log(
|
|
6911
|
+
console.log(chalk85.dim(`
|
|
6820
6912
|
${totalCount} projects total (including root)`));
|
|
6821
|
-
console.log(
|
|
6913
|
+
console.log(chalk85.bold("\nSolution Membership"));
|
|
6822
6914
|
if (solutions.length === 0) {
|
|
6823
|
-
console.log(
|
|
6915
|
+
console.log(chalk85.yellow(" Not found in any .sln"));
|
|
6824
6916
|
} else {
|
|
6825
6917
|
for (const sln of solutions) {
|
|
6826
|
-
console.log(` ${
|
|
6918
|
+
console.log(` ${chalk85.green(sln)}`);
|
|
6827
6919
|
}
|
|
6828
6920
|
}
|
|
6829
6921
|
console.log();
|
|
@@ -6852,16 +6944,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
6852
6944
|
// src/commands/dotnet/resolveCsproj.ts
|
|
6853
6945
|
import { existsSync as existsSync25 } from "fs";
|
|
6854
6946
|
import path24 from "path";
|
|
6855
|
-
import
|
|
6947
|
+
import chalk86 from "chalk";
|
|
6856
6948
|
function resolveCsproj(csprojPath) {
|
|
6857
6949
|
const resolved = path24.resolve(csprojPath);
|
|
6858
6950
|
if (!existsSync25(resolved)) {
|
|
6859
|
-
console.error(
|
|
6951
|
+
console.error(chalk86.red(`File not found: ${resolved}`));
|
|
6860
6952
|
process.exit(1);
|
|
6861
6953
|
}
|
|
6862
6954
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
6863
6955
|
if (!repoRoot) {
|
|
6864
|
-
console.error(
|
|
6956
|
+
console.error(chalk86.red("Could not find git repository root"));
|
|
6865
6957
|
process.exit(1);
|
|
6866
6958
|
}
|
|
6867
6959
|
return { resolved, repoRoot };
|
|
@@ -6911,12 +7003,12 @@ function getChangedCsFiles(scope) {
|
|
|
6911
7003
|
}
|
|
6912
7004
|
|
|
6913
7005
|
// src/commands/dotnet/inSln.ts
|
|
6914
|
-
import
|
|
7006
|
+
import chalk87 from "chalk";
|
|
6915
7007
|
async function inSln(csprojPath) {
|
|
6916
7008
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
6917
7009
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
6918
7010
|
if (solutions.length === 0) {
|
|
6919
|
-
console.log(
|
|
7011
|
+
console.log(chalk87.yellow("Not found in any .sln file"));
|
|
6920
7012
|
process.exit(1);
|
|
6921
7013
|
}
|
|
6922
7014
|
for (const sln of solutions) {
|
|
@@ -6925,7 +7017,7 @@ async function inSln(csprojPath) {
|
|
|
6925
7017
|
}
|
|
6926
7018
|
|
|
6927
7019
|
// src/commands/dotnet/inspect.ts
|
|
6928
|
-
import
|
|
7020
|
+
import chalk93 from "chalk";
|
|
6929
7021
|
|
|
6930
7022
|
// src/shared/formatElapsed.ts
|
|
6931
7023
|
function formatElapsed(ms) {
|
|
@@ -6937,12 +7029,12 @@ function formatElapsed(ms) {
|
|
|
6937
7029
|
}
|
|
6938
7030
|
|
|
6939
7031
|
// src/commands/dotnet/displayIssues.ts
|
|
6940
|
-
import
|
|
7032
|
+
import chalk88 from "chalk";
|
|
6941
7033
|
var SEVERITY_COLOR = {
|
|
6942
|
-
ERROR:
|
|
6943
|
-
WARNING:
|
|
6944
|
-
SUGGESTION:
|
|
6945
|
-
HINT:
|
|
7034
|
+
ERROR: chalk88.red,
|
|
7035
|
+
WARNING: chalk88.yellow,
|
|
7036
|
+
SUGGESTION: chalk88.cyan,
|
|
7037
|
+
HINT: chalk88.dim
|
|
6946
7038
|
};
|
|
6947
7039
|
function groupByFile(issues) {
|
|
6948
7040
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -6958,15 +7050,15 @@ function groupByFile(issues) {
|
|
|
6958
7050
|
}
|
|
6959
7051
|
function displayIssues(issues) {
|
|
6960
7052
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
6961
|
-
console.log(
|
|
7053
|
+
console.log(chalk88.bold(file));
|
|
6962
7054
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
6963
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
7055
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk88.white;
|
|
6964
7056
|
console.log(
|
|
6965
|
-
` ${
|
|
7057
|
+
` ${chalk88.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
6966
7058
|
);
|
|
6967
7059
|
}
|
|
6968
7060
|
}
|
|
6969
|
-
console.log(
|
|
7061
|
+
console.log(chalk88.dim(`
|
|
6970
7062
|
${issues.length} issue(s) found`));
|
|
6971
7063
|
}
|
|
6972
7064
|
|
|
@@ -7025,12 +7117,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
7025
7117
|
// src/commands/dotnet/resolveSolution.ts
|
|
7026
7118
|
import { existsSync as existsSync26 } from "fs";
|
|
7027
7119
|
import path25 from "path";
|
|
7028
|
-
import
|
|
7120
|
+
import chalk90 from "chalk";
|
|
7029
7121
|
|
|
7030
7122
|
// src/commands/dotnet/findSolution.ts
|
|
7031
7123
|
import { readdirSync as readdirSync4 } from "fs";
|
|
7032
7124
|
import { dirname as dirname16, join as join24 } from "path";
|
|
7033
|
-
import
|
|
7125
|
+
import chalk89 from "chalk";
|
|
7034
7126
|
function findSlnInDir(dir) {
|
|
7035
7127
|
try {
|
|
7036
7128
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join24(dir, f));
|
|
@@ -7046,17 +7138,17 @@ function findSolution() {
|
|
|
7046
7138
|
const slnFiles = findSlnInDir(current);
|
|
7047
7139
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
7048
7140
|
if (slnFiles.length > 1) {
|
|
7049
|
-
console.error(
|
|
7141
|
+
console.error(chalk89.red(`Multiple .sln files found in ${current}:`));
|
|
7050
7142
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
7051
7143
|
console.error(
|
|
7052
|
-
|
|
7144
|
+
chalk89.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
7053
7145
|
);
|
|
7054
7146
|
process.exit(1);
|
|
7055
7147
|
}
|
|
7056
7148
|
if (current === ceiling) break;
|
|
7057
7149
|
current = dirname16(current);
|
|
7058
7150
|
}
|
|
7059
|
-
console.error(
|
|
7151
|
+
console.error(chalk89.red("No .sln file found between cwd and repo root"));
|
|
7060
7152
|
process.exit(1);
|
|
7061
7153
|
}
|
|
7062
7154
|
|
|
@@ -7065,7 +7157,7 @@ function resolveSolution(sln) {
|
|
|
7065
7157
|
if (sln) {
|
|
7066
7158
|
const resolved = path25.resolve(sln);
|
|
7067
7159
|
if (!existsSync26(resolved)) {
|
|
7068
|
-
console.error(
|
|
7160
|
+
console.error(chalk90.red(`Solution file not found: ${resolved}`));
|
|
7069
7161
|
process.exit(1);
|
|
7070
7162
|
}
|
|
7071
7163
|
return resolved;
|
|
@@ -7107,14 +7199,14 @@ import { execSync as execSync24 } from "child_process";
|
|
|
7107
7199
|
import { existsSync as existsSync27, readFileSync as readFileSync24, unlinkSync as unlinkSync5 } from "fs";
|
|
7108
7200
|
import { tmpdir as tmpdir2 } from "os";
|
|
7109
7201
|
import path26 from "path";
|
|
7110
|
-
import
|
|
7202
|
+
import chalk91 from "chalk";
|
|
7111
7203
|
function assertJbInstalled() {
|
|
7112
7204
|
try {
|
|
7113
7205
|
execSync24("jb inspectcode --version", { stdio: "pipe" });
|
|
7114
7206
|
} catch {
|
|
7115
|
-
console.error(
|
|
7207
|
+
console.error(chalk91.red("jb is not installed. Install with:"));
|
|
7116
7208
|
console.error(
|
|
7117
|
-
|
|
7209
|
+
chalk91.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
7118
7210
|
);
|
|
7119
7211
|
process.exit(1);
|
|
7120
7212
|
}
|
|
@@ -7132,11 +7224,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
7132
7224
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
7133
7225
|
process.stderr.write(err.stderr);
|
|
7134
7226
|
}
|
|
7135
|
-
console.error(
|
|
7227
|
+
console.error(chalk91.red("jb inspectcode failed"));
|
|
7136
7228
|
process.exit(1);
|
|
7137
7229
|
}
|
|
7138
7230
|
if (!existsSync27(reportPath)) {
|
|
7139
|
-
console.error(
|
|
7231
|
+
console.error(chalk91.red("Report file not generated"));
|
|
7140
7232
|
process.exit(1);
|
|
7141
7233
|
}
|
|
7142
7234
|
const xml = readFileSync24(reportPath, "utf-8");
|
|
@@ -7146,7 +7238,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
7146
7238
|
|
|
7147
7239
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
7148
7240
|
import { execSync as execSync25 } from "child_process";
|
|
7149
|
-
import
|
|
7241
|
+
import chalk92 from "chalk";
|
|
7150
7242
|
function resolveMsbuildPath() {
|
|
7151
7243
|
const config = loadConfig();
|
|
7152
7244
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -7157,9 +7249,9 @@ function assertMsbuildInstalled() {
|
|
|
7157
7249
|
try {
|
|
7158
7250
|
execSync25(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
7159
7251
|
} catch {
|
|
7160
|
-
console.error(
|
|
7252
|
+
console.error(chalk92.red(`msbuild not found at: ${msbuild}`));
|
|
7161
7253
|
console.error(
|
|
7162
|
-
|
|
7254
|
+
chalk92.yellow(
|
|
7163
7255
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
7164
7256
|
)
|
|
7165
7257
|
);
|
|
@@ -7206,17 +7298,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
7206
7298
|
// src/commands/dotnet/inspect.ts
|
|
7207
7299
|
function logScope(changedFiles) {
|
|
7208
7300
|
if (changedFiles === null) {
|
|
7209
|
-
console.log(
|
|
7301
|
+
console.log(chalk93.dim("Inspecting full solution..."));
|
|
7210
7302
|
} else {
|
|
7211
7303
|
console.log(
|
|
7212
|
-
|
|
7304
|
+
chalk93.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
7213
7305
|
);
|
|
7214
7306
|
}
|
|
7215
7307
|
}
|
|
7216
7308
|
function reportResults(issues, elapsed) {
|
|
7217
7309
|
if (issues.length > 0) displayIssues(issues);
|
|
7218
|
-
else console.log(
|
|
7219
|
-
console.log(
|
|
7310
|
+
else console.log(chalk93.green("No issues found"));
|
|
7311
|
+
console.log(chalk93.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
7220
7312
|
if (issues.length > 0) process.exit(1);
|
|
7221
7313
|
}
|
|
7222
7314
|
async function inspect(sln, options2) {
|
|
@@ -7227,7 +7319,7 @@ async function inspect(sln, options2) {
|
|
|
7227
7319
|
const scope = parseScope(options2.scope);
|
|
7228
7320
|
const changedFiles = getChangedCsFiles(scope);
|
|
7229
7321
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
7230
|
-
console.log(
|
|
7322
|
+
console.log(chalk93.green("No changed .cs files found"));
|
|
7231
7323
|
return;
|
|
7232
7324
|
}
|
|
7233
7325
|
logScope(changedFiles);
|
|
@@ -7253,7 +7345,7 @@ function registerDotnet(program2) {
|
|
|
7253
7345
|
}
|
|
7254
7346
|
|
|
7255
7347
|
// src/commands/jira/acceptanceCriteria.ts
|
|
7256
|
-
import
|
|
7348
|
+
import chalk95 from "chalk";
|
|
7257
7349
|
|
|
7258
7350
|
// src/commands/jira/adfToText.ts
|
|
7259
7351
|
function renderInline(node) {
|
|
@@ -7314,7 +7406,7 @@ function adfToText(doc) {
|
|
|
7314
7406
|
|
|
7315
7407
|
// src/commands/jira/fetchIssue.ts
|
|
7316
7408
|
import { execSync as execSync26 } from "child_process";
|
|
7317
|
-
import
|
|
7409
|
+
import chalk94 from "chalk";
|
|
7318
7410
|
function fetchIssue(issueKey, fields) {
|
|
7319
7411
|
let result;
|
|
7320
7412
|
try {
|
|
@@ -7327,15 +7419,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
7327
7419
|
const stderr = error.stderr;
|
|
7328
7420
|
if (stderr.includes("unauthorized")) {
|
|
7329
7421
|
console.error(
|
|
7330
|
-
|
|
7422
|
+
chalk94.red("Jira authentication expired."),
|
|
7331
7423
|
"Run",
|
|
7332
|
-
|
|
7424
|
+
chalk94.cyan("assist jira auth"),
|
|
7333
7425
|
"to re-authenticate."
|
|
7334
7426
|
);
|
|
7335
7427
|
process.exit(1);
|
|
7336
7428
|
}
|
|
7337
7429
|
}
|
|
7338
|
-
console.error(
|
|
7430
|
+
console.error(chalk94.red(`Failed to fetch ${issueKey}.`));
|
|
7339
7431
|
process.exit(1);
|
|
7340
7432
|
}
|
|
7341
7433
|
return JSON.parse(result);
|
|
@@ -7349,7 +7441,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
7349
7441
|
const parsed = fetchIssue(issueKey, field);
|
|
7350
7442
|
const acValue = parsed?.fields?.[field];
|
|
7351
7443
|
if (!acValue) {
|
|
7352
|
-
console.log(
|
|
7444
|
+
console.log(chalk95.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
7353
7445
|
return;
|
|
7354
7446
|
}
|
|
7355
7447
|
if (typeof acValue === "string") {
|
|
@@ -7444,14 +7536,14 @@ async function jiraAuth() {
|
|
|
7444
7536
|
}
|
|
7445
7537
|
|
|
7446
7538
|
// src/commands/jira/viewIssue.ts
|
|
7447
|
-
import
|
|
7539
|
+
import chalk96 from "chalk";
|
|
7448
7540
|
function viewIssue(issueKey) {
|
|
7449
7541
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
7450
7542
|
const fields = parsed?.fields;
|
|
7451
7543
|
const summary = fields?.summary;
|
|
7452
7544
|
const description = fields?.description;
|
|
7453
7545
|
if (summary) {
|
|
7454
|
-
console.log(
|
|
7546
|
+
console.log(chalk96.bold(summary));
|
|
7455
7547
|
}
|
|
7456
7548
|
if (description) {
|
|
7457
7549
|
if (summary) console.log();
|
|
@@ -7465,7 +7557,7 @@ function viewIssue(issueKey) {
|
|
|
7465
7557
|
}
|
|
7466
7558
|
if (!summary && !description) {
|
|
7467
7559
|
console.log(
|
|
7468
|
-
|
|
7560
|
+
chalk96.yellow(`No summary or description found on ${issueKey}.`)
|
|
7469
7561
|
);
|
|
7470
7562
|
}
|
|
7471
7563
|
}
|
|
@@ -7479,7 +7571,7 @@ function registerJira(program2) {
|
|
|
7479
7571
|
}
|
|
7480
7572
|
|
|
7481
7573
|
// src/commands/news/add/index.ts
|
|
7482
|
-
import
|
|
7574
|
+
import chalk97 from "chalk";
|
|
7483
7575
|
import enquirer8 from "enquirer";
|
|
7484
7576
|
async function add2(url) {
|
|
7485
7577
|
if (!url) {
|
|
@@ -7502,17 +7594,17 @@ async function add2(url) {
|
|
|
7502
7594
|
const news = config.news ?? {};
|
|
7503
7595
|
const feeds = news.feeds ?? [];
|
|
7504
7596
|
if (feeds.includes(url)) {
|
|
7505
|
-
console.log(
|
|
7597
|
+
console.log(chalk97.yellow("Feed already exists in config"));
|
|
7506
7598
|
return;
|
|
7507
7599
|
}
|
|
7508
7600
|
feeds.push(url);
|
|
7509
7601
|
config.news = { ...news, feeds };
|
|
7510
7602
|
saveGlobalConfig(config);
|
|
7511
|
-
console.log(
|
|
7603
|
+
console.log(chalk97.green(`Added feed: ${url}`));
|
|
7512
7604
|
}
|
|
7513
7605
|
|
|
7514
7606
|
// src/commands/news/web/handleRequest.ts
|
|
7515
|
-
import
|
|
7607
|
+
import chalk98 from "chalk";
|
|
7516
7608
|
|
|
7517
7609
|
// src/commands/news/web/shared.ts
|
|
7518
7610
|
import { decodeHTML } from "entities";
|
|
@@ -7648,17 +7740,17 @@ function prefetch() {
|
|
|
7648
7740
|
const config = loadConfig();
|
|
7649
7741
|
const total = config.news.feeds.length;
|
|
7650
7742
|
if (total === 0) return;
|
|
7651
|
-
process.stdout.write(
|
|
7743
|
+
process.stdout.write(chalk98.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
7652
7744
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
7653
7745
|
const width = 20;
|
|
7654
7746
|
const filled = Math.round(done2 / t * width);
|
|
7655
7747
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
7656
7748
|
process.stdout.write(
|
|
7657
|
-
`\r${
|
|
7749
|
+
`\r${chalk98.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
7658
7750
|
);
|
|
7659
7751
|
}).then((items) => {
|
|
7660
7752
|
process.stdout.write(
|
|
7661
|
-
`\r${
|
|
7753
|
+
`\r${chalk98.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
7662
7754
|
`
|
|
7663
7755
|
);
|
|
7664
7756
|
cachedItems = items;
|
|
@@ -8019,20 +8111,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
8019
8111
|
}
|
|
8020
8112
|
|
|
8021
8113
|
// src/commands/prs/listComments/printComments.ts
|
|
8022
|
-
import
|
|
8114
|
+
import chalk99 from "chalk";
|
|
8023
8115
|
function formatForHuman(comment3) {
|
|
8024
8116
|
if (comment3.type === "review") {
|
|
8025
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
8117
|
+
const stateColor = comment3.state === "APPROVED" ? chalk99.green : comment3.state === "CHANGES_REQUESTED" ? chalk99.red : chalk99.yellow;
|
|
8026
8118
|
return [
|
|
8027
|
-
`${
|
|
8119
|
+
`${chalk99.cyan("Review")} by ${chalk99.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
8028
8120
|
comment3.body,
|
|
8029
8121
|
""
|
|
8030
8122
|
].join("\n");
|
|
8031
8123
|
}
|
|
8032
8124
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
8033
8125
|
return [
|
|
8034
|
-
`${
|
|
8035
|
-
|
|
8126
|
+
`${chalk99.cyan("Line comment")} by ${chalk99.bold(comment3.user)} on ${chalk99.dim(`${comment3.path}${location}`)}`,
|
|
8127
|
+
chalk99.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
8036
8128
|
comment3.body,
|
|
8037
8129
|
""
|
|
8038
8130
|
].join("\n");
|
|
@@ -8122,13 +8214,13 @@ import { execSync as execSync33 } from "child_process";
|
|
|
8122
8214
|
import enquirer9 from "enquirer";
|
|
8123
8215
|
|
|
8124
8216
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
8125
|
-
import
|
|
8217
|
+
import chalk100 from "chalk";
|
|
8126
8218
|
var STATUS_MAP = {
|
|
8127
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
8128
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
8219
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk100.magenta("merged"), date: pr.mergedAt } : null,
|
|
8220
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk100.red("closed"), date: pr.closedAt } : null
|
|
8129
8221
|
};
|
|
8130
8222
|
function defaultStatus(pr) {
|
|
8131
|
-
return { label:
|
|
8223
|
+
return { label: chalk100.green("opened"), date: pr.createdAt };
|
|
8132
8224
|
}
|
|
8133
8225
|
function getStatus2(pr) {
|
|
8134
8226
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -8137,11 +8229,11 @@ function formatDate(dateStr) {
|
|
|
8137
8229
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
8138
8230
|
}
|
|
8139
8231
|
function formatPrHeader(pr, status2) {
|
|
8140
|
-
return `${
|
|
8232
|
+
return `${chalk100.cyan(`#${pr.number}`)} ${pr.title} ${chalk100.dim(`(${pr.author.login},`)} ${status2.label} ${chalk100.dim(`${formatDate(status2.date)})`)}`;
|
|
8141
8233
|
}
|
|
8142
8234
|
function logPrDetails(pr) {
|
|
8143
8235
|
console.log(
|
|
8144
|
-
|
|
8236
|
+
chalk100.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
8145
8237
|
);
|
|
8146
8238
|
console.log();
|
|
8147
8239
|
}
|
|
@@ -8307,10 +8399,10 @@ function registerPrs(program2) {
|
|
|
8307
8399
|
}
|
|
8308
8400
|
|
|
8309
8401
|
// src/commands/ravendb/ravendbAuth.ts
|
|
8310
|
-
import
|
|
8402
|
+
import chalk106 from "chalk";
|
|
8311
8403
|
|
|
8312
8404
|
// src/shared/createConnectionAuth.ts
|
|
8313
|
-
import
|
|
8405
|
+
import chalk101 from "chalk";
|
|
8314
8406
|
function listConnections(connections, format2) {
|
|
8315
8407
|
if (connections.length === 0) {
|
|
8316
8408
|
console.log("No connections configured.");
|
|
@@ -8323,7 +8415,7 @@ function listConnections(connections, format2) {
|
|
|
8323
8415
|
function removeConnection(connections, name, save) {
|
|
8324
8416
|
const filtered = connections.filter((c) => c.name !== name);
|
|
8325
8417
|
if (filtered.length === connections.length) {
|
|
8326
|
-
console.error(
|
|
8418
|
+
console.error(chalk101.red(`Connection "${name}" not found.`));
|
|
8327
8419
|
process.exit(1);
|
|
8328
8420
|
}
|
|
8329
8421
|
save(filtered);
|
|
@@ -8369,15 +8461,15 @@ function saveConnections(connections) {
|
|
|
8369
8461
|
}
|
|
8370
8462
|
|
|
8371
8463
|
// src/commands/ravendb/promptConnection.ts
|
|
8372
|
-
import
|
|
8464
|
+
import chalk104 from "chalk";
|
|
8373
8465
|
|
|
8374
8466
|
// src/commands/ravendb/selectOpSecret.ts
|
|
8375
|
-
import
|
|
8467
|
+
import chalk103 from "chalk";
|
|
8376
8468
|
import Enquirer2 from "enquirer";
|
|
8377
8469
|
|
|
8378
8470
|
// src/commands/ravendb/searchItems.ts
|
|
8379
8471
|
import { execSync as execSync35 } from "child_process";
|
|
8380
|
-
import
|
|
8472
|
+
import chalk102 from "chalk";
|
|
8381
8473
|
function opExec(args) {
|
|
8382
8474
|
return execSync35(`op ${args}`, {
|
|
8383
8475
|
encoding: "utf-8",
|
|
@@ -8390,7 +8482,7 @@ function searchItems(search2) {
|
|
|
8390
8482
|
items = JSON.parse(opExec("item list --format=json"));
|
|
8391
8483
|
} catch {
|
|
8392
8484
|
console.error(
|
|
8393
|
-
|
|
8485
|
+
chalk102.red(
|
|
8394
8486
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
8395
8487
|
)
|
|
8396
8488
|
);
|
|
@@ -8404,7 +8496,7 @@ function getItemFields(itemId) {
|
|
|
8404
8496
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
8405
8497
|
return item.fields.filter((f) => f.reference && f.label);
|
|
8406
8498
|
} catch {
|
|
8407
|
-
console.error(
|
|
8499
|
+
console.error(chalk102.red("Failed to get item details from 1Password."));
|
|
8408
8500
|
process.exit(1);
|
|
8409
8501
|
}
|
|
8410
8502
|
}
|
|
@@ -8423,7 +8515,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8423
8515
|
}).run();
|
|
8424
8516
|
const items = searchItems(search2);
|
|
8425
8517
|
if (items.length === 0) {
|
|
8426
|
-
console.error(
|
|
8518
|
+
console.error(chalk103.red(`No items found matching "${search2}".`));
|
|
8427
8519
|
process.exit(1);
|
|
8428
8520
|
}
|
|
8429
8521
|
const itemId = await selectOne(
|
|
@@ -8432,7 +8524,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8432
8524
|
);
|
|
8433
8525
|
const fields = getItemFields(itemId);
|
|
8434
8526
|
if (fields.length === 0) {
|
|
8435
|
-
console.error(
|
|
8527
|
+
console.error(chalk103.red("No fields with references found on this item."));
|
|
8436
8528
|
process.exit(1);
|
|
8437
8529
|
}
|
|
8438
8530
|
const ref = await selectOne(
|
|
@@ -8446,7 +8538,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8446
8538
|
async function promptConnection(existingNames) {
|
|
8447
8539
|
const name = await promptInput("name", "Connection name:");
|
|
8448
8540
|
if (existingNames.includes(name)) {
|
|
8449
|
-
console.error(
|
|
8541
|
+
console.error(chalk104.red(`Connection "${name}" already exists.`));
|
|
8450
8542
|
process.exit(1);
|
|
8451
8543
|
}
|
|
8452
8544
|
const url = await promptInput(
|
|
@@ -8455,22 +8547,22 @@ async function promptConnection(existingNames) {
|
|
|
8455
8547
|
);
|
|
8456
8548
|
const database = await promptInput("database", "Database name:");
|
|
8457
8549
|
if (!name || !url || !database) {
|
|
8458
|
-
console.error(
|
|
8550
|
+
console.error(chalk104.red("All fields are required."));
|
|
8459
8551
|
process.exit(1);
|
|
8460
8552
|
}
|
|
8461
8553
|
const apiKeyRef = await selectOpSecret();
|
|
8462
|
-
console.log(
|
|
8554
|
+
console.log(chalk104.dim(`Using: ${apiKeyRef}`));
|
|
8463
8555
|
return { name, url, database, apiKeyRef };
|
|
8464
8556
|
}
|
|
8465
8557
|
|
|
8466
8558
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
8467
|
-
import
|
|
8559
|
+
import chalk105 from "chalk";
|
|
8468
8560
|
function ravendbSetConnection(name) {
|
|
8469
8561
|
const raw = loadGlobalConfigRaw();
|
|
8470
8562
|
const ravendb = raw.ravendb ?? {};
|
|
8471
8563
|
const connections = ravendb.connections ?? [];
|
|
8472
8564
|
if (!connections.some((c) => c.name === name)) {
|
|
8473
|
-
console.error(
|
|
8565
|
+
console.error(chalk105.red(`Connection "${name}" not found.`));
|
|
8474
8566
|
console.error(
|
|
8475
8567
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
8476
8568
|
);
|
|
@@ -8486,16 +8578,16 @@ function ravendbSetConnection(name) {
|
|
|
8486
8578
|
var ravendbAuth = createConnectionAuth({
|
|
8487
8579
|
load: loadConnections,
|
|
8488
8580
|
save: saveConnections,
|
|
8489
|
-
format: (c) => `${
|
|
8581
|
+
format: (c) => `${chalk106.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
8490
8582
|
promptNew: promptConnection,
|
|
8491
8583
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
8492
8584
|
});
|
|
8493
8585
|
|
|
8494
8586
|
// src/commands/ravendb/ravendbCollections.ts
|
|
8495
|
-
import
|
|
8587
|
+
import chalk110 from "chalk";
|
|
8496
8588
|
|
|
8497
8589
|
// src/commands/ravendb/ravenFetch.ts
|
|
8498
|
-
import
|
|
8590
|
+
import chalk108 from "chalk";
|
|
8499
8591
|
|
|
8500
8592
|
// src/commands/ravendb/getAccessToken.ts
|
|
8501
8593
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -8532,10 +8624,10 @@ ${errorText}`
|
|
|
8532
8624
|
|
|
8533
8625
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
8534
8626
|
import { execSync as execSync36 } from "child_process";
|
|
8535
|
-
import
|
|
8627
|
+
import chalk107 from "chalk";
|
|
8536
8628
|
function resolveOpSecret(reference) {
|
|
8537
8629
|
if (!reference.startsWith("op://")) {
|
|
8538
|
-
console.error(
|
|
8630
|
+
console.error(chalk107.red(`Invalid secret reference: must start with op://`));
|
|
8539
8631
|
process.exit(1);
|
|
8540
8632
|
}
|
|
8541
8633
|
try {
|
|
@@ -8545,7 +8637,7 @@ function resolveOpSecret(reference) {
|
|
|
8545
8637
|
}).trim();
|
|
8546
8638
|
} catch {
|
|
8547
8639
|
console.error(
|
|
8548
|
-
|
|
8640
|
+
chalk107.red(
|
|
8549
8641
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
8550
8642
|
)
|
|
8551
8643
|
);
|
|
@@ -8572,7 +8664,7 @@ async function ravenFetch(connection, path50) {
|
|
|
8572
8664
|
if (!response.ok) {
|
|
8573
8665
|
const body = await response.text();
|
|
8574
8666
|
console.error(
|
|
8575
|
-
|
|
8667
|
+
chalk108.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
8576
8668
|
);
|
|
8577
8669
|
console.error(body.substring(0, 500));
|
|
8578
8670
|
process.exit(1);
|
|
@@ -8581,7 +8673,7 @@ async function ravenFetch(connection, path50) {
|
|
|
8581
8673
|
}
|
|
8582
8674
|
|
|
8583
8675
|
// src/commands/ravendb/resolveConnection.ts
|
|
8584
|
-
import
|
|
8676
|
+
import chalk109 from "chalk";
|
|
8585
8677
|
function loadRavendb() {
|
|
8586
8678
|
const raw = loadGlobalConfigRaw();
|
|
8587
8679
|
const ravendb = raw.ravendb;
|
|
@@ -8595,7 +8687,7 @@ function resolveConnection(name) {
|
|
|
8595
8687
|
const connectionName = name ?? defaultConnection;
|
|
8596
8688
|
if (!connectionName) {
|
|
8597
8689
|
console.error(
|
|
8598
|
-
|
|
8690
|
+
chalk109.red(
|
|
8599
8691
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
8600
8692
|
)
|
|
8601
8693
|
);
|
|
@@ -8603,7 +8695,7 @@ function resolveConnection(name) {
|
|
|
8603
8695
|
}
|
|
8604
8696
|
const connection = connections.find((c) => c.name === connectionName);
|
|
8605
8697
|
if (!connection) {
|
|
8606
|
-
console.error(
|
|
8698
|
+
console.error(chalk109.red(`Connection "${connectionName}" not found.`));
|
|
8607
8699
|
console.error(
|
|
8608
8700
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
8609
8701
|
);
|
|
@@ -8634,15 +8726,15 @@ async function ravendbCollections(connectionName) {
|
|
|
8634
8726
|
return;
|
|
8635
8727
|
}
|
|
8636
8728
|
for (const c of collections) {
|
|
8637
|
-
console.log(`${
|
|
8729
|
+
console.log(`${chalk110.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
8638
8730
|
}
|
|
8639
8731
|
}
|
|
8640
8732
|
|
|
8641
8733
|
// src/commands/ravendb/ravendbQuery.ts
|
|
8642
|
-
import
|
|
8734
|
+
import chalk112 from "chalk";
|
|
8643
8735
|
|
|
8644
8736
|
// src/commands/ravendb/fetchAllPages.ts
|
|
8645
|
-
import
|
|
8737
|
+
import chalk111 from "chalk";
|
|
8646
8738
|
|
|
8647
8739
|
// src/commands/ravendb/buildQueryPath.ts
|
|
8648
8740
|
function buildQueryPath(opts) {
|
|
@@ -8680,7 +8772,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8680
8772
|
allResults.push(...results);
|
|
8681
8773
|
start3 += results.length;
|
|
8682
8774
|
process.stderr.write(
|
|
8683
|
-
`\r${
|
|
8775
|
+
`\r${chalk111.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
8684
8776
|
);
|
|
8685
8777
|
if (start3 >= totalResults) break;
|
|
8686
8778
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -8695,7 +8787,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8695
8787
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
8696
8788
|
const resolved = resolveArgs(connectionName, collection);
|
|
8697
8789
|
if (!resolved.collection && !options2.query) {
|
|
8698
|
-
console.error(
|
|
8790
|
+
console.error(chalk112.red("Provide a collection name or --query filter."));
|
|
8699
8791
|
process.exit(1);
|
|
8700
8792
|
}
|
|
8701
8793
|
const { collection: col } = resolved;
|
|
@@ -8733,7 +8825,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
8733
8825
|
import * as path27 from "path";
|
|
8734
8826
|
|
|
8735
8827
|
// src/commands/refactor/logViolations.ts
|
|
8736
|
-
import
|
|
8828
|
+
import chalk113 from "chalk";
|
|
8737
8829
|
var DEFAULT_MAX_LINES = 100;
|
|
8738
8830
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
8739
8831
|
if (violations.length === 0) {
|
|
@@ -8742,43 +8834,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
8742
8834
|
}
|
|
8743
8835
|
return;
|
|
8744
8836
|
}
|
|
8745
|
-
console.error(
|
|
8837
|
+
console.error(chalk113.red(`
|
|
8746
8838
|
Refactor check failed:
|
|
8747
8839
|
`));
|
|
8748
|
-
console.error(
|
|
8840
|
+
console.error(chalk113.red(` The following files exceed ${maxLines} lines:
|
|
8749
8841
|
`));
|
|
8750
8842
|
for (const violation of violations) {
|
|
8751
|
-
console.error(
|
|
8843
|
+
console.error(chalk113.red(` ${violation.file} (${violation.lines} lines)`));
|
|
8752
8844
|
}
|
|
8753
8845
|
console.error(
|
|
8754
|
-
|
|
8846
|
+
chalk113.yellow(
|
|
8755
8847
|
`
|
|
8756
8848
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
8757
8849
|
way to refactor it, ignore it with:
|
|
8758
8850
|
`
|
|
8759
8851
|
)
|
|
8760
8852
|
);
|
|
8761
|
-
console.error(
|
|
8853
|
+
console.error(chalk113.gray(` assist refactor ignore <file>
|
|
8762
8854
|
`));
|
|
8763
8855
|
if (process.env.CLAUDECODE) {
|
|
8764
|
-
console.error(
|
|
8856
|
+
console.error(chalk113.cyan(`
|
|
8765
8857
|
## Extracting Code to New Files
|
|
8766
8858
|
`));
|
|
8767
8859
|
console.error(
|
|
8768
|
-
|
|
8860
|
+
chalk113.cyan(
|
|
8769
8861
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
8770
8862
|
`
|
|
8771
8863
|
)
|
|
8772
8864
|
);
|
|
8773
8865
|
console.error(
|
|
8774
|
-
|
|
8866
|
+
chalk113.cyan(
|
|
8775
8867
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
8776
8868
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
8777
8869
|
`
|
|
8778
8870
|
)
|
|
8779
8871
|
);
|
|
8780
8872
|
console.error(
|
|
8781
|
-
|
|
8873
|
+
chalk113.cyan(
|
|
8782
8874
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
8783
8875
|
domains, move it to a common/shared folder.
|
|
8784
8876
|
`
|
|
@@ -8934,7 +9026,7 @@ async function check(pattern2, options2) {
|
|
|
8934
9026
|
|
|
8935
9027
|
// src/commands/refactor/extract/index.ts
|
|
8936
9028
|
import path33 from "path";
|
|
8937
|
-
import
|
|
9029
|
+
import chalk116 from "chalk";
|
|
8938
9030
|
|
|
8939
9031
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
8940
9032
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -9481,23 +9573,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
9481
9573
|
|
|
9482
9574
|
// src/commands/refactor/extract/displayPlan.ts
|
|
9483
9575
|
import path31 from "path";
|
|
9484
|
-
import
|
|
9576
|
+
import chalk114 from "chalk";
|
|
9485
9577
|
function section(title) {
|
|
9486
9578
|
return `
|
|
9487
|
-
${
|
|
9579
|
+
${chalk114.cyan(title)}`;
|
|
9488
9580
|
}
|
|
9489
9581
|
function displayImporters(plan2, cwd) {
|
|
9490
9582
|
if (plan2.importersToUpdate.length === 0) return;
|
|
9491
9583
|
console.log(section("Update importers:"));
|
|
9492
9584
|
for (const imp of plan2.importersToUpdate) {
|
|
9493
9585
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
9494
|
-
console.log(` ${
|
|
9586
|
+
console.log(` ${chalk114.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
9495
9587
|
}
|
|
9496
9588
|
}
|
|
9497
9589
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
9498
|
-
console.log(
|
|
9590
|
+
console.log(chalk114.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
9499
9591
|
`));
|
|
9500
|
-
console.log(` ${
|
|
9592
|
+
console.log(` ${chalk114.cyan("Functions to move:")}`);
|
|
9501
9593
|
for (const name of plan2.extractedNames) {
|
|
9502
9594
|
console.log(` ${name}`);
|
|
9503
9595
|
}
|
|
@@ -9532,7 +9624,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
9532
9624
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
9533
9625
|
import fs17 from "fs";
|
|
9534
9626
|
import path32 from "path";
|
|
9535
|
-
import
|
|
9627
|
+
import chalk115 from "chalk";
|
|
9536
9628
|
import { Project as Project2 } from "ts-morph";
|
|
9537
9629
|
function findTsConfig(sourcePath) {
|
|
9538
9630
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -9563,7 +9655,7 @@ function loadProjectFile(file) {
|
|
|
9563
9655
|
});
|
|
9564
9656
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
9565
9657
|
if (!sourceFile) {
|
|
9566
|
-
console.log(
|
|
9658
|
+
console.log(chalk115.red(`File not found in project: ${file}`));
|
|
9567
9659
|
process.exit(1);
|
|
9568
9660
|
}
|
|
9569
9661
|
return { project, sourceFile };
|
|
@@ -9586,19 +9678,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
9586
9678
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
9587
9679
|
if (options2.apply) {
|
|
9588
9680
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
9589
|
-
console.log(
|
|
9681
|
+
console.log(chalk116.green("\nExtraction complete"));
|
|
9590
9682
|
} else {
|
|
9591
|
-
console.log(
|
|
9683
|
+
console.log(chalk116.dim("\nDry run. Use --apply to execute."));
|
|
9592
9684
|
}
|
|
9593
9685
|
}
|
|
9594
9686
|
|
|
9595
9687
|
// src/commands/refactor/ignore.ts
|
|
9596
9688
|
import fs18 from "fs";
|
|
9597
|
-
import
|
|
9689
|
+
import chalk117 from "chalk";
|
|
9598
9690
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
9599
9691
|
function ignore(file) {
|
|
9600
9692
|
if (!fs18.existsSync(file)) {
|
|
9601
|
-
console.error(
|
|
9693
|
+
console.error(chalk117.red(`Error: File does not exist: ${file}`));
|
|
9602
9694
|
process.exit(1);
|
|
9603
9695
|
}
|
|
9604
9696
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -9614,7 +9706,7 @@ function ignore(file) {
|
|
|
9614
9706
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
9615
9707
|
}
|
|
9616
9708
|
console.log(
|
|
9617
|
-
|
|
9709
|
+
chalk117.green(
|
|
9618
9710
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
9619
9711
|
)
|
|
9620
9712
|
);
|
|
@@ -9622,26 +9714,26 @@ function ignore(file) {
|
|
|
9622
9714
|
|
|
9623
9715
|
// src/commands/refactor/rename/index.ts
|
|
9624
9716
|
import path34 from "path";
|
|
9625
|
-
import
|
|
9717
|
+
import chalk118 from "chalk";
|
|
9626
9718
|
async function rename(source, destination, options2 = {}) {
|
|
9627
9719
|
const destPath = path34.resolve(destination);
|
|
9628
9720
|
const cwd = process.cwd();
|
|
9629
9721
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
9630
9722
|
const relDest = path34.relative(cwd, destPath);
|
|
9631
9723
|
const { project, sourceFile } = loadProjectFile(source);
|
|
9632
|
-
console.log(
|
|
9724
|
+
console.log(chalk118.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
9633
9725
|
if (options2.apply) {
|
|
9634
9726
|
sourceFile.move(destPath);
|
|
9635
9727
|
await project.save();
|
|
9636
|
-
console.log(
|
|
9728
|
+
console.log(chalk118.green("Done"));
|
|
9637
9729
|
} else {
|
|
9638
|
-
console.log(
|
|
9730
|
+
console.log(chalk118.dim("Dry run. Use --apply to execute."));
|
|
9639
9731
|
}
|
|
9640
9732
|
}
|
|
9641
9733
|
|
|
9642
9734
|
// src/commands/refactor/renameSymbol/index.ts
|
|
9643
9735
|
import path36 from "path";
|
|
9644
|
-
import
|
|
9736
|
+
import chalk119 from "chalk";
|
|
9645
9737
|
import { Project as Project3 } from "ts-morph";
|
|
9646
9738
|
|
|
9647
9739
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -9690,38 +9782,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
9690
9782
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
9691
9783
|
const sourceFile = project.getSourceFile(filePath);
|
|
9692
9784
|
if (!sourceFile) {
|
|
9693
|
-
console.log(
|
|
9785
|
+
console.log(chalk119.red(`File not found in project: ${file}`));
|
|
9694
9786
|
process.exit(1);
|
|
9695
9787
|
}
|
|
9696
9788
|
const symbol = findSymbol(sourceFile, oldName);
|
|
9697
9789
|
if (!symbol) {
|
|
9698
|
-
console.log(
|
|
9790
|
+
console.log(chalk119.red(`Symbol "${oldName}" not found in ${file}`));
|
|
9699
9791
|
process.exit(1);
|
|
9700
9792
|
}
|
|
9701
9793
|
const grouped = groupReferences(symbol, cwd);
|
|
9702
9794
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
9703
9795
|
console.log(
|
|
9704
|
-
|
|
9796
|
+
chalk119.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
9705
9797
|
`)
|
|
9706
9798
|
);
|
|
9707
9799
|
for (const [refFile, lines] of grouped) {
|
|
9708
9800
|
console.log(
|
|
9709
|
-
` ${
|
|
9801
|
+
` ${chalk119.dim(refFile)}: lines ${chalk119.cyan(lines.join(", "))}`
|
|
9710
9802
|
);
|
|
9711
9803
|
}
|
|
9712
9804
|
if (options2.apply) {
|
|
9713
9805
|
symbol.rename(newName);
|
|
9714
9806
|
await project.save();
|
|
9715
|
-
console.log(
|
|
9807
|
+
console.log(chalk119.green(`
|
|
9716
9808
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
9717
9809
|
} else {
|
|
9718
|
-
console.log(
|
|
9810
|
+
console.log(chalk119.dim("\nDry run. Use --apply to execute."));
|
|
9719
9811
|
}
|
|
9720
9812
|
}
|
|
9721
9813
|
|
|
9722
9814
|
// src/commands/refactor/restructure/index.ts
|
|
9723
9815
|
import path45 from "path";
|
|
9724
|
-
import
|
|
9816
|
+
import chalk122 from "chalk";
|
|
9725
9817
|
|
|
9726
9818
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
9727
9819
|
import path37 from "path";
|
|
@@ -9964,50 +10056,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
9964
10056
|
|
|
9965
10057
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
9966
10058
|
import path41 from "path";
|
|
9967
|
-
import
|
|
10059
|
+
import chalk120 from "chalk";
|
|
9968
10060
|
function relPath(filePath) {
|
|
9969
10061
|
return path41.relative(process.cwd(), filePath);
|
|
9970
10062
|
}
|
|
9971
10063
|
function displayMoves(plan2) {
|
|
9972
10064
|
if (plan2.moves.length === 0) return;
|
|
9973
|
-
console.log(
|
|
10065
|
+
console.log(chalk120.bold("\nFile moves:"));
|
|
9974
10066
|
for (const move of plan2.moves) {
|
|
9975
10067
|
console.log(
|
|
9976
|
-
` ${
|
|
10068
|
+
` ${chalk120.red(relPath(move.from))} \u2192 ${chalk120.green(relPath(move.to))}`
|
|
9977
10069
|
);
|
|
9978
|
-
console.log(
|
|
10070
|
+
console.log(chalk120.dim(` ${move.reason}`));
|
|
9979
10071
|
}
|
|
9980
10072
|
}
|
|
9981
10073
|
function displayRewrites(rewrites) {
|
|
9982
10074
|
if (rewrites.length === 0) return;
|
|
9983
10075
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
9984
|
-
console.log(
|
|
10076
|
+
console.log(chalk120.bold(`
|
|
9985
10077
|
Import rewrites (${affectedFiles.size} files):`));
|
|
9986
10078
|
for (const file of affectedFiles) {
|
|
9987
|
-
console.log(` ${
|
|
10079
|
+
console.log(` ${chalk120.cyan(relPath(file))}:`);
|
|
9988
10080
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
9989
10081
|
(r) => r.file === file
|
|
9990
10082
|
)) {
|
|
9991
10083
|
console.log(
|
|
9992
|
-
` ${
|
|
10084
|
+
` ${chalk120.red(`"${oldSpecifier}"`)} \u2192 ${chalk120.green(`"${newSpecifier}"`)}`
|
|
9993
10085
|
);
|
|
9994
10086
|
}
|
|
9995
10087
|
}
|
|
9996
10088
|
}
|
|
9997
10089
|
function displayPlan2(plan2) {
|
|
9998
10090
|
if (plan2.warnings.length > 0) {
|
|
9999
|
-
console.log(
|
|
10000
|
-
for (const w of plan2.warnings) console.log(
|
|
10091
|
+
console.log(chalk120.yellow("\nWarnings:"));
|
|
10092
|
+
for (const w of plan2.warnings) console.log(chalk120.yellow(` ${w}`));
|
|
10001
10093
|
}
|
|
10002
10094
|
if (plan2.newDirectories.length > 0) {
|
|
10003
|
-
console.log(
|
|
10095
|
+
console.log(chalk120.bold("\nNew directories:"));
|
|
10004
10096
|
for (const dir of plan2.newDirectories)
|
|
10005
|
-
console.log(
|
|
10097
|
+
console.log(chalk120.green(` ${dir}/`));
|
|
10006
10098
|
}
|
|
10007
10099
|
displayMoves(plan2);
|
|
10008
10100
|
displayRewrites(plan2.rewrites);
|
|
10009
10101
|
console.log(
|
|
10010
|
-
|
|
10102
|
+
chalk120.dim(
|
|
10011
10103
|
`
|
|
10012
10104
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
10013
10105
|
)
|
|
@@ -10017,18 +10109,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
10017
10109
|
// src/commands/refactor/restructure/executePlan.ts
|
|
10018
10110
|
import fs20 from "fs";
|
|
10019
10111
|
import path42 from "path";
|
|
10020
|
-
import
|
|
10112
|
+
import chalk121 from "chalk";
|
|
10021
10113
|
function executePlan(plan2) {
|
|
10022
10114
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
10023
10115
|
for (const [file, content] of updatedContents) {
|
|
10024
10116
|
fs20.writeFileSync(file, content, "utf-8");
|
|
10025
10117
|
console.log(
|
|
10026
|
-
|
|
10118
|
+
chalk121.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
10027
10119
|
);
|
|
10028
10120
|
}
|
|
10029
10121
|
for (const dir of plan2.newDirectories) {
|
|
10030
10122
|
fs20.mkdirSync(dir, { recursive: true });
|
|
10031
|
-
console.log(
|
|
10123
|
+
console.log(chalk121.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
10032
10124
|
}
|
|
10033
10125
|
for (const move of plan2.moves) {
|
|
10034
10126
|
const targetDir = path42.dirname(move.to);
|
|
@@ -10037,7 +10129,7 @@ function executePlan(plan2) {
|
|
|
10037
10129
|
}
|
|
10038
10130
|
fs20.renameSync(move.from, move.to);
|
|
10039
10131
|
console.log(
|
|
10040
|
-
|
|
10132
|
+
chalk121.white(
|
|
10041
10133
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
10042
10134
|
)
|
|
10043
10135
|
);
|
|
@@ -10052,7 +10144,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
10052
10144
|
if (entries.length === 0) {
|
|
10053
10145
|
fs20.rmdirSync(dir);
|
|
10054
10146
|
console.log(
|
|
10055
|
-
|
|
10147
|
+
chalk121.dim(
|
|
10056
10148
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
10057
10149
|
)
|
|
10058
10150
|
);
|
|
@@ -10185,22 +10277,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
10185
10277
|
const targetPattern = pattern2 ?? "src";
|
|
10186
10278
|
const files = findSourceFiles2(targetPattern);
|
|
10187
10279
|
if (files.length === 0) {
|
|
10188
|
-
console.log(
|
|
10280
|
+
console.log(chalk122.yellow("No files found matching pattern"));
|
|
10189
10281
|
return;
|
|
10190
10282
|
}
|
|
10191
10283
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
10192
10284
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
10193
10285
|
if (plan2.moves.length === 0) {
|
|
10194
|
-
console.log(
|
|
10286
|
+
console.log(chalk122.green("No restructuring needed"));
|
|
10195
10287
|
return;
|
|
10196
10288
|
}
|
|
10197
10289
|
displayPlan2(plan2);
|
|
10198
10290
|
if (options2.apply) {
|
|
10199
|
-
console.log(
|
|
10291
|
+
console.log(chalk122.bold("\nApplying changes..."));
|
|
10200
10292
|
executePlan(plan2);
|
|
10201
|
-
console.log(
|
|
10293
|
+
console.log(chalk122.green("\nRestructuring complete"));
|
|
10202
10294
|
} else {
|
|
10203
|
-
console.log(
|
|
10295
|
+
console.log(chalk122.dim("\nDry run. Use --apply to execute."));
|
|
10204
10296
|
}
|
|
10205
10297
|
}
|
|
10206
10298
|
|
|
@@ -10240,7 +10332,7 @@ function registerRefactor(program2) {
|
|
|
10240
10332
|
}
|
|
10241
10333
|
|
|
10242
10334
|
// src/commands/seq/seqAuth.ts
|
|
10243
|
-
import
|
|
10335
|
+
import chalk124 from "chalk";
|
|
10244
10336
|
|
|
10245
10337
|
// src/commands/seq/loadConnections.ts
|
|
10246
10338
|
function loadConnections2() {
|
|
@@ -10269,11 +10361,11 @@ function setDefaultConnection(name) {
|
|
|
10269
10361
|
}
|
|
10270
10362
|
|
|
10271
10363
|
// src/commands/seq/promptConnection.ts
|
|
10272
|
-
import
|
|
10364
|
+
import chalk123 from "chalk";
|
|
10273
10365
|
async function promptConnection2(existingNames) {
|
|
10274
10366
|
const name = await promptInput("name", "Connection name:", "default");
|
|
10275
10367
|
if (existingNames.includes(name)) {
|
|
10276
|
-
console.error(
|
|
10368
|
+
console.error(chalk123.red(`Connection "${name}" already exists.`));
|
|
10277
10369
|
process.exit(1);
|
|
10278
10370
|
}
|
|
10279
10371
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -10285,16 +10377,16 @@ async function promptConnection2(existingNames) {
|
|
|
10285
10377
|
var seqAuth = createConnectionAuth({
|
|
10286
10378
|
load: loadConnections2,
|
|
10287
10379
|
save: saveConnections2,
|
|
10288
|
-
format: (c) => `${
|
|
10380
|
+
format: (c) => `${chalk124.bold(c.name)} ${c.url}`,
|
|
10289
10381
|
promptNew: promptConnection2,
|
|
10290
10382
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
10291
10383
|
});
|
|
10292
10384
|
|
|
10293
10385
|
// src/commands/seq/seqQuery.ts
|
|
10294
|
-
import
|
|
10386
|
+
import chalk128 from "chalk";
|
|
10295
10387
|
|
|
10296
10388
|
// src/commands/seq/fetchSeq.ts
|
|
10297
|
-
import
|
|
10389
|
+
import chalk125 from "chalk";
|
|
10298
10390
|
async function fetchSeq(conn, path50, params) {
|
|
10299
10391
|
const url = `${conn.url}${path50}?${params}`;
|
|
10300
10392
|
const response = await fetch(url, {
|
|
@@ -10305,7 +10397,7 @@ async function fetchSeq(conn, path50, params) {
|
|
|
10305
10397
|
});
|
|
10306
10398
|
if (!response.ok) {
|
|
10307
10399
|
const body = await response.text();
|
|
10308
|
-
console.error(
|
|
10400
|
+
console.error(chalk125.red(`Seq returned ${response.status}: ${body}`));
|
|
10309
10401
|
process.exit(1);
|
|
10310
10402
|
}
|
|
10311
10403
|
return response;
|
|
@@ -10358,23 +10450,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
10358
10450
|
}
|
|
10359
10451
|
|
|
10360
10452
|
// src/commands/seq/formatEvent.ts
|
|
10361
|
-
import
|
|
10453
|
+
import chalk126 from "chalk";
|
|
10362
10454
|
function levelColor(level) {
|
|
10363
10455
|
switch (level) {
|
|
10364
10456
|
case "Fatal":
|
|
10365
|
-
return
|
|
10457
|
+
return chalk126.bgRed.white;
|
|
10366
10458
|
case "Error":
|
|
10367
|
-
return
|
|
10459
|
+
return chalk126.red;
|
|
10368
10460
|
case "Warning":
|
|
10369
|
-
return
|
|
10461
|
+
return chalk126.yellow;
|
|
10370
10462
|
case "Information":
|
|
10371
|
-
return
|
|
10463
|
+
return chalk126.cyan;
|
|
10372
10464
|
case "Debug":
|
|
10373
|
-
return
|
|
10465
|
+
return chalk126.gray;
|
|
10374
10466
|
case "Verbose":
|
|
10375
|
-
return
|
|
10467
|
+
return chalk126.dim;
|
|
10376
10468
|
default:
|
|
10377
|
-
return
|
|
10469
|
+
return chalk126.white;
|
|
10378
10470
|
}
|
|
10379
10471
|
}
|
|
10380
10472
|
function levelAbbrev(level) {
|
|
@@ -10415,31 +10507,31 @@ function formatTimestamp(iso) {
|
|
|
10415
10507
|
function formatEvent(event) {
|
|
10416
10508
|
const color = levelColor(event.Level);
|
|
10417
10509
|
const abbrev = levelAbbrev(event.Level);
|
|
10418
|
-
const ts8 =
|
|
10510
|
+
const ts8 = chalk126.dim(formatTimestamp(event.Timestamp));
|
|
10419
10511
|
const msg = renderMessage(event);
|
|
10420
10512
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
10421
10513
|
if (event.Exception) {
|
|
10422
10514
|
for (const line of event.Exception.split("\n")) {
|
|
10423
|
-
lines.push(
|
|
10515
|
+
lines.push(chalk126.red(` ${line}`));
|
|
10424
10516
|
}
|
|
10425
10517
|
}
|
|
10426
10518
|
return lines.join("\n");
|
|
10427
10519
|
}
|
|
10428
10520
|
|
|
10429
10521
|
// src/commands/seq/resolveConnection.ts
|
|
10430
|
-
import
|
|
10522
|
+
import chalk127 from "chalk";
|
|
10431
10523
|
function resolveConnection2(name) {
|
|
10432
10524
|
const connections = loadConnections2();
|
|
10433
10525
|
if (connections.length === 0) {
|
|
10434
10526
|
console.error(
|
|
10435
|
-
|
|
10527
|
+
chalk127.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
10436
10528
|
);
|
|
10437
10529
|
process.exit(1);
|
|
10438
10530
|
}
|
|
10439
10531
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
10440
10532
|
const connection = connections.find((c) => c.name === target);
|
|
10441
10533
|
if (!connection) {
|
|
10442
|
-
console.error(
|
|
10534
|
+
console.error(chalk127.red(`Seq connection "${target}" not found.`));
|
|
10443
10535
|
process.exit(1);
|
|
10444
10536
|
}
|
|
10445
10537
|
return connection;
|
|
@@ -10454,7 +10546,7 @@ async function seqQuery(filter, options2) {
|
|
|
10454
10546
|
new URLSearchParams({ filter, count: String(count) })
|
|
10455
10547
|
);
|
|
10456
10548
|
if (events.length === 0) {
|
|
10457
|
-
console.log(
|
|
10549
|
+
console.log(chalk128.yellow("No events found."));
|
|
10458
10550
|
return;
|
|
10459
10551
|
}
|
|
10460
10552
|
if (options2.json) {
|
|
@@ -10465,11 +10557,11 @@ async function seqQuery(filter, options2) {
|
|
|
10465
10557
|
for (const event of chronological) {
|
|
10466
10558
|
console.log(formatEvent(event));
|
|
10467
10559
|
}
|
|
10468
|
-
console.log(
|
|
10560
|
+
console.log(chalk128.dim(`
|
|
10469
10561
|
${events.length} events`));
|
|
10470
10562
|
if (events.length >= count) {
|
|
10471
10563
|
console.log(
|
|
10472
|
-
|
|
10564
|
+
chalk128.yellow(
|
|
10473
10565
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
10474
10566
|
)
|
|
10475
10567
|
);
|
|
@@ -10477,11 +10569,11 @@ ${events.length} events`));
|
|
|
10477
10569
|
}
|
|
10478
10570
|
|
|
10479
10571
|
// src/commands/seq/seqSetConnection.ts
|
|
10480
|
-
import
|
|
10572
|
+
import chalk129 from "chalk";
|
|
10481
10573
|
function seqSetConnection(name) {
|
|
10482
10574
|
const connections = loadConnections2();
|
|
10483
10575
|
if (!connections.find((c) => c.name === name)) {
|
|
10484
|
-
console.error(
|
|
10576
|
+
console.error(chalk129.red(`Connection "${name}" not found.`));
|
|
10485
10577
|
process.exit(1);
|
|
10486
10578
|
}
|
|
10487
10579
|
setDefaultConnection(name);
|
|
@@ -11020,14 +11112,14 @@ import {
|
|
|
11020
11112
|
import { dirname as dirname20, join as join35 } from "path";
|
|
11021
11113
|
|
|
11022
11114
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
11023
|
-
import
|
|
11115
|
+
import chalk130 from "chalk";
|
|
11024
11116
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
11025
11117
|
function validateStagedContent(filename, content) {
|
|
11026
11118
|
const firstLine = content.split("\n")[0];
|
|
11027
11119
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
11028
11120
|
if (!match) {
|
|
11029
11121
|
console.error(
|
|
11030
|
-
|
|
11122
|
+
chalk130.red(
|
|
11031
11123
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
11032
11124
|
)
|
|
11033
11125
|
);
|
|
@@ -11036,7 +11128,7 @@ function validateStagedContent(filename, content) {
|
|
|
11036
11128
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
11037
11129
|
if (!contentAfterLink) {
|
|
11038
11130
|
console.error(
|
|
11039
|
-
|
|
11131
|
+
chalk130.red(
|
|
11040
11132
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
11041
11133
|
)
|
|
11042
11134
|
);
|
|
@@ -11429,7 +11521,7 @@ function registerVoice(program2) {
|
|
|
11429
11521
|
|
|
11430
11522
|
// src/commands/roam/auth.ts
|
|
11431
11523
|
import { randomBytes } from "crypto";
|
|
11432
|
-
import
|
|
11524
|
+
import chalk131 from "chalk";
|
|
11433
11525
|
|
|
11434
11526
|
// src/lib/openBrowser.ts
|
|
11435
11527
|
import { execSync as execSync39 } from "child_process";
|
|
@@ -11604,13 +11696,13 @@ async function auth() {
|
|
|
11604
11696
|
saveGlobalConfig(config);
|
|
11605
11697
|
const state = randomBytes(16).toString("hex");
|
|
11606
11698
|
console.log(
|
|
11607
|
-
|
|
11699
|
+
chalk131.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
11608
11700
|
);
|
|
11609
|
-
console.log(
|
|
11610
|
-
console.log(
|
|
11611
|
-
console.log(
|
|
11701
|
+
console.log(chalk131.white("http://localhost:14523/callback\n"));
|
|
11702
|
+
console.log(chalk131.blue("Opening browser for authorization..."));
|
|
11703
|
+
console.log(chalk131.dim("Waiting for authorization callback..."));
|
|
11612
11704
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
11613
|
-
console.log(
|
|
11705
|
+
console.log(chalk131.dim("Exchanging code for tokens..."));
|
|
11614
11706
|
const tokens = await exchangeToken({
|
|
11615
11707
|
code,
|
|
11616
11708
|
clientId,
|
|
@@ -11626,7 +11718,7 @@ async function auth() {
|
|
|
11626
11718
|
};
|
|
11627
11719
|
saveGlobalConfig(config);
|
|
11628
11720
|
console.log(
|
|
11629
|
-
|
|
11721
|
+
chalk131.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
11630
11722
|
);
|
|
11631
11723
|
}
|
|
11632
11724
|
|
|
@@ -11922,7 +12014,7 @@ import { execSync as execSync41 } from "child_process";
|
|
|
11922
12014
|
import { existsSync as existsSync41, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as writeFileSync29 } from "fs";
|
|
11923
12015
|
import { tmpdir as tmpdir6 } from "os";
|
|
11924
12016
|
import { join as join45, resolve as resolve6 } from "path";
|
|
11925
|
-
import
|
|
12017
|
+
import chalk132 from "chalk";
|
|
11926
12018
|
|
|
11927
12019
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
11928
12020
|
var captureWindowPs1 = `
|
|
@@ -12073,22 +12165,22 @@ function screenshot(processName) {
|
|
|
12073
12165
|
const config = loadConfig();
|
|
12074
12166
|
const outputDir = resolve6(config.screenshot.outputDir);
|
|
12075
12167
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
12076
|
-
console.log(
|
|
12168
|
+
console.log(chalk132.gray(`Capturing window for process "${processName}" ...`));
|
|
12077
12169
|
try {
|
|
12078
12170
|
runPowerShellScript(processName, outputPath);
|
|
12079
|
-
console.log(
|
|
12171
|
+
console.log(chalk132.green(`Screenshot saved: ${outputPath}`));
|
|
12080
12172
|
} catch (error) {
|
|
12081
12173
|
const msg = error instanceof Error ? error.message : String(error);
|
|
12082
|
-
console.error(
|
|
12174
|
+
console.error(chalk132.red(`Failed to capture screenshot: ${msg}`));
|
|
12083
12175
|
process.exit(1);
|
|
12084
12176
|
}
|
|
12085
12177
|
}
|
|
12086
12178
|
|
|
12087
12179
|
// src/commands/statusLine.ts
|
|
12088
|
-
import
|
|
12180
|
+
import chalk134 from "chalk";
|
|
12089
12181
|
|
|
12090
12182
|
// src/commands/buildLimitsSegment.ts
|
|
12091
|
-
import
|
|
12183
|
+
import chalk133 from "chalk";
|
|
12092
12184
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
12093
12185
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
12094
12186
|
function formatTimeLeft(resetsAt) {
|
|
@@ -12111,10 +12203,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
12111
12203
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
12112
12204
|
const label2 = `${Math.round(pct)}%`;
|
|
12113
12205
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
12114
|
-
if (projected == null) return
|
|
12115
|
-
if (projected > 100) return
|
|
12116
|
-
if (projected > 75) return
|
|
12117
|
-
return
|
|
12206
|
+
if (projected == null) return chalk133.green(label2);
|
|
12207
|
+
if (projected > 100) return chalk133.red(label2);
|
|
12208
|
+
if (projected > 75) return chalk133.yellow(label2);
|
|
12209
|
+
return chalk133.green(label2);
|
|
12118
12210
|
}
|
|
12119
12211
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
12120
12212
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -12140,14 +12232,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
12140
12232
|
}
|
|
12141
12233
|
|
|
12142
12234
|
// src/commands/statusLine.ts
|
|
12143
|
-
|
|
12235
|
+
chalk134.level = 3;
|
|
12144
12236
|
function formatNumber(num) {
|
|
12145
12237
|
return num.toLocaleString("en-US");
|
|
12146
12238
|
}
|
|
12147
12239
|
function colorizePercent(pct) {
|
|
12148
12240
|
const label2 = `${Math.round(pct)}%`;
|
|
12149
|
-
if (pct > 80) return
|
|
12150
|
-
if (pct > 40) return
|
|
12241
|
+
if (pct > 80) return chalk134.red(label2);
|
|
12242
|
+
if (pct > 40) return chalk134.yellow(label2);
|
|
12151
12243
|
return label2;
|
|
12152
12244
|
}
|
|
12153
12245
|
async function statusLine() {
|
|
@@ -12170,7 +12262,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
12170
12262
|
// src/commands/sync/syncClaudeMd.ts
|
|
12171
12263
|
import * as fs23 from "fs";
|
|
12172
12264
|
import * as path46 from "path";
|
|
12173
|
-
import
|
|
12265
|
+
import chalk135 from "chalk";
|
|
12174
12266
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
12175
12267
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
12176
12268
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -12179,12 +12271,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
12179
12271
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
12180
12272
|
if (sourceContent !== targetContent) {
|
|
12181
12273
|
console.log(
|
|
12182
|
-
|
|
12274
|
+
chalk135.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
12183
12275
|
);
|
|
12184
12276
|
console.log();
|
|
12185
12277
|
printDiff(targetContent, sourceContent);
|
|
12186
12278
|
const confirm = options2?.yes || await promptConfirm(
|
|
12187
|
-
|
|
12279
|
+
chalk135.red("Overwrite existing CLAUDE.md?"),
|
|
12188
12280
|
false
|
|
12189
12281
|
);
|
|
12190
12282
|
if (!confirm) {
|
|
@@ -12200,7 +12292,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
12200
12292
|
// src/commands/sync/syncSettings.ts
|
|
12201
12293
|
import * as fs24 from "fs";
|
|
12202
12294
|
import * as path47 from "path";
|
|
12203
|
-
import
|
|
12295
|
+
import chalk136 from "chalk";
|
|
12204
12296
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
12205
12297
|
const source = path47.join(claudeDir, "settings.json");
|
|
12206
12298
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -12216,14 +12308,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
12216
12308
|
if (mergedContent !== normalizedTarget) {
|
|
12217
12309
|
if (!options2?.yes) {
|
|
12218
12310
|
console.log(
|
|
12219
|
-
|
|
12311
|
+
chalk136.yellow(
|
|
12220
12312
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
12221
12313
|
)
|
|
12222
12314
|
);
|
|
12223
12315
|
console.log();
|
|
12224
12316
|
printDiff(targetContent, mergedContent);
|
|
12225
12317
|
const confirm = await promptConfirm(
|
|
12226
|
-
|
|
12318
|
+
chalk136.red("Overwrite existing settings.json?"),
|
|
12227
12319
|
false
|
|
12228
12320
|
);
|
|
12229
12321
|
if (!confirm) {
|