@staff0rd/assist 0.183.0 → 0.184.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +485 -424
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.184.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -875,7 +875,7 @@ function buildReviewPhase() {
|
|
|
875
875
|
import chalk5 from "chalk";
|
|
876
876
|
|
|
877
877
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
878
|
-
import { existsSync as
|
|
878
|
+
import { existsSync as existsSync6, unlinkSync as unlinkSync2 } from "fs";
|
|
879
879
|
import chalk4 from "chalk";
|
|
880
880
|
|
|
881
881
|
// src/commands/backlog/handleIncompletePhase.ts
|
|
@@ -894,6 +894,9 @@ async function handleIncompletePhase() {
|
|
|
894
894
|
return "abort";
|
|
895
895
|
}
|
|
896
896
|
|
|
897
|
+
// src/commands/backlog/readSignal.ts
|
|
898
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
899
|
+
|
|
897
900
|
// src/commands/backlog/writeSignal.ts
|
|
898
901
|
import { writeFileSync as writeFileSync4 } from "fs";
|
|
899
902
|
import { join as join6 } from "path";
|
|
@@ -908,10 +911,21 @@ function writeSignal(event, data) {
|
|
|
908
911
|
writeFileSync4(getSignalPath(), JSON.stringify(signal));
|
|
909
912
|
}
|
|
910
913
|
|
|
914
|
+
// src/commands/backlog/readSignal.ts
|
|
915
|
+
function readSignal() {
|
|
916
|
+
const path50 = getSignalPath();
|
|
917
|
+
if (!existsSync5(path50)) return void 0;
|
|
918
|
+
try {
|
|
919
|
+
return JSON.parse(readFileSync5(path50, "utf-8"));
|
|
920
|
+
} catch {
|
|
921
|
+
return void 0;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
911
925
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
912
926
|
function cleanupSignal() {
|
|
913
927
|
const statusPath = getSignalPath();
|
|
914
|
-
if (
|
|
928
|
+
if (existsSync6(statusPath)) {
|
|
915
929
|
unlinkSync2(statusPath);
|
|
916
930
|
}
|
|
917
931
|
}
|
|
@@ -921,16 +935,23 @@ function isTerminalStatus(itemId) {
|
|
|
921
935
|
return item?.status === "done" || item?.status === "wontdo";
|
|
922
936
|
}
|
|
923
937
|
async function resolvePhaseResult(phaseIndex, itemId) {
|
|
924
|
-
if (!
|
|
938
|
+
if (!existsSync6(getSignalPath())) {
|
|
925
939
|
if (isTerminalStatus(itemId)) return -1;
|
|
926
940
|
const action = await handleIncompletePhase();
|
|
927
941
|
if (action === "abort") return -1;
|
|
928
|
-
return action === "skip" ? 1 :
|
|
942
|
+
return action === "skip" ? phaseIndex + 1 : phaseIndex;
|
|
929
943
|
}
|
|
944
|
+
const signal = readSignal();
|
|
930
945
|
cleanupSignal();
|
|
946
|
+
if (signal?.event === "rewind") {
|
|
947
|
+
const targetPhase = signal.targetPhase;
|
|
948
|
+
console.log(chalk4.yellow(`
|
|
949
|
+
Rewinding to phase ${targetPhase + 1}.`));
|
|
950
|
+
return targetPhase;
|
|
951
|
+
}
|
|
931
952
|
console.log(chalk4.green(`
|
|
932
953
|
Phase ${phaseIndex + 1} completed.`));
|
|
933
|
-
return 1;
|
|
954
|
+
return phaseIndex + 1;
|
|
934
955
|
}
|
|
935
956
|
|
|
936
957
|
// src/commands/backlog/spawnClaude.ts
|
|
@@ -952,20 +973,6 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
952
973
|
|
|
953
974
|
// src/commands/backlog/watchForMarker.ts
|
|
954
975
|
import { existsSync as existsSync7, unwatchFile, watchFile } from "fs";
|
|
955
|
-
|
|
956
|
-
// src/commands/backlog/readSignal.ts
|
|
957
|
-
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
958
|
-
function readSignal() {
|
|
959
|
-
const path50 = getSignalPath();
|
|
960
|
-
if (!existsSync6(path50)) return void 0;
|
|
961
|
-
try {
|
|
962
|
-
return JSON.parse(readFileSync5(path50, "utf-8"));
|
|
963
|
-
} catch {
|
|
964
|
-
return void 0;
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
// src/commands/backlog/watchForMarker.ts
|
|
969
976
|
function watchForMarker(child) {
|
|
970
977
|
const statusPath = getSignalPath();
|
|
971
978
|
watchFile(statusPath, { interval: 1e3 }, () => {
|
|
@@ -999,8 +1006,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions) {
|
|
|
999
1006
|
watchForMarker(child);
|
|
1000
1007
|
await done2;
|
|
1001
1008
|
stopWatching();
|
|
1002
|
-
|
|
1003
|
-
return delta < 0 ? -1 : phaseIndex + delta;
|
|
1009
|
+
return await resolvePhaseResult(phaseIndex, item.id);
|
|
1004
1010
|
}
|
|
1005
1011
|
|
|
1006
1012
|
// src/commands/backlog/prepareRun.ts
|
|
@@ -4192,6 +4198,55 @@ function registerLinkCommands(cmd) {
|
|
|
4192
4198
|
cmd.command("unlink <from> <to>").description("Remove a link between two backlog items").action(unlink);
|
|
4193
4199
|
}
|
|
4194
4200
|
|
|
4201
|
+
// src/commands/backlog/rewindPhase.ts
|
|
4202
|
+
import chalk52 from "chalk";
|
|
4203
|
+
function validateRewind(item, phaseIndex) {
|
|
4204
|
+
if (!item.plan || item.plan.length === 0) {
|
|
4205
|
+
return `Item #${item.id} has no plan phases.`;
|
|
4206
|
+
}
|
|
4207
|
+
if (phaseIndex < 0 || phaseIndex >= item.plan.length) {
|
|
4208
|
+
return `Phase ${phaseIndex} does not exist. Valid range: 0\u2013${item.plan.length - 1}.`;
|
|
4209
|
+
}
|
|
4210
|
+
const currentPhase = item.currentPhase ?? 0;
|
|
4211
|
+
if (phaseIndex >= currentPhase) {
|
|
4212
|
+
return `Phase ${phaseIndex} is not earlier than the current phase (${currentPhase}).`;
|
|
4213
|
+
}
|
|
4214
|
+
return void 0;
|
|
4215
|
+
}
|
|
4216
|
+
function rewindPhase(id, phase, opts) {
|
|
4217
|
+
const phaseIndex = Number.parseInt(phase, 10);
|
|
4218
|
+
const result = loadAndFindItem(id);
|
|
4219
|
+
if (!result) return;
|
|
4220
|
+
const { item } = result;
|
|
4221
|
+
const error = validateRewind(item, phaseIndex);
|
|
4222
|
+
if (error) {
|
|
4223
|
+
console.log(chalk52.red(error));
|
|
4224
|
+
process.exitCode = 1;
|
|
4225
|
+
return;
|
|
4226
|
+
}
|
|
4227
|
+
const phaseName = item.plan?.[phaseIndex].name;
|
|
4228
|
+
addComment(
|
|
4229
|
+
item,
|
|
4230
|
+
`Rewound to phase ${phaseIndex} (${phaseName}): ${opts.reason}`,
|
|
4231
|
+
phaseIndex
|
|
4232
|
+
);
|
|
4233
|
+
saveBacklog(result.items);
|
|
4234
|
+
setCurrentPhase(id, phaseIndex);
|
|
4235
|
+
setStatus(id, "in-progress");
|
|
4236
|
+
writeSignal("rewind", {
|
|
4237
|
+
itemId: Number.parseInt(id, 10),
|
|
4238
|
+
targetPhase: phaseIndex
|
|
4239
|
+
});
|
|
4240
|
+
console.log(
|
|
4241
|
+
chalk52.green(`Rewound item #${id} to phase ${phaseIndex} (${phaseName}).`)
|
|
4242
|
+
);
|
|
4243
|
+
}
|
|
4244
|
+
|
|
4245
|
+
// src/commands/backlog/registerRewindCommand.ts
|
|
4246
|
+
function registerRewindCommand(cmd) {
|
|
4247
|
+
cmd.command("rewind <id> <phase>").description("Rewind a backlog item to an earlier phase").requiredOption("--reason <reason>", "Reason for rewinding").action(rewindPhase);
|
|
4248
|
+
}
|
|
4249
|
+
|
|
4195
4250
|
// src/commands/backlog/registerRunCommand.ts
|
|
4196
4251
|
function registerRunCommand(cmd) {
|
|
4197
4252
|
cmd.command("run <id>").description("Run a backlog item's plan phase-by-phase with Claude").option("-w, --write", "Run Claude with acceptEdits permission mode").action(async (id, opts) => {
|
|
@@ -4200,11 +4255,11 @@ function registerRunCommand(cmd) {
|
|
|
4200
4255
|
}
|
|
4201
4256
|
|
|
4202
4257
|
// src/commands/backlog/search/index.ts
|
|
4203
|
-
import
|
|
4258
|
+
import chalk53 from "chalk";
|
|
4204
4259
|
async function search(query) {
|
|
4205
4260
|
if (!backlogExists()) {
|
|
4206
4261
|
console.log(
|
|
4207
|
-
|
|
4262
|
+
chalk53.yellow(
|
|
4208
4263
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
4209
4264
|
)
|
|
4210
4265
|
);
|
|
@@ -4212,18 +4267,18 @@ async function search(query) {
|
|
|
4212
4267
|
}
|
|
4213
4268
|
const items = searchBacklog(query);
|
|
4214
4269
|
if (items.length === 0) {
|
|
4215
|
-
console.log(
|
|
4270
|
+
console.log(chalk53.dim(`No items matching "${query}".`));
|
|
4216
4271
|
return;
|
|
4217
4272
|
}
|
|
4218
4273
|
console.log(
|
|
4219
|
-
|
|
4274
|
+
chalk53.dim(
|
|
4220
4275
|
`${items.length} item${items.length === 1 ? "" : "s"} matching "${query}":
|
|
4221
4276
|
`
|
|
4222
4277
|
)
|
|
4223
4278
|
);
|
|
4224
4279
|
for (const item of items) {
|
|
4225
4280
|
console.log(
|
|
4226
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
4281
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk53.dim(`#${item.id}`)} ${item.name}`
|
|
4227
4282
|
);
|
|
4228
4283
|
}
|
|
4229
4284
|
}
|
|
@@ -4234,16 +4289,16 @@ function registerSearchCommand(cmd) {
|
|
|
4234
4289
|
}
|
|
4235
4290
|
|
|
4236
4291
|
// src/commands/backlog/delete/index.ts
|
|
4237
|
-
import
|
|
4292
|
+
import chalk54 from "chalk";
|
|
4238
4293
|
async function del(id) {
|
|
4239
4294
|
const name = removeItem(id);
|
|
4240
4295
|
if (name) {
|
|
4241
|
-
console.log(
|
|
4296
|
+
console.log(chalk54.green(`Deleted item #${id}: ${name}`));
|
|
4242
4297
|
}
|
|
4243
4298
|
}
|
|
4244
4299
|
|
|
4245
4300
|
// src/commands/backlog/done/index.ts
|
|
4246
|
-
import
|
|
4301
|
+
import chalk55 from "chalk";
|
|
4247
4302
|
async function done(id, summary) {
|
|
4248
4303
|
const result = loadAndFindItem(id);
|
|
4249
4304
|
if (!result) return;
|
|
@@ -4253,12 +4308,12 @@ async function done(id, summary) {
|
|
|
4253
4308
|
const pending = item.plan.slice(completed);
|
|
4254
4309
|
if (pending.length > 0) {
|
|
4255
4310
|
console.log(
|
|
4256
|
-
|
|
4311
|
+
chalk55.red(
|
|
4257
4312
|
`Cannot complete item #${id}: ${pending.length} pending phase(s):`
|
|
4258
4313
|
)
|
|
4259
4314
|
);
|
|
4260
4315
|
for (const phase of pending) {
|
|
4261
|
-
console.log(
|
|
4316
|
+
console.log(chalk55.yellow(` - ${phase.name}`));
|
|
4262
4317
|
}
|
|
4263
4318
|
process.exitCode = 1;
|
|
4264
4319
|
return;
|
|
@@ -4270,20 +4325,20 @@ async function done(id, summary) {
|
|
|
4270
4325
|
addPhaseSummary(item, summary, phase);
|
|
4271
4326
|
}
|
|
4272
4327
|
saveBacklog(result.items);
|
|
4273
|
-
console.log(
|
|
4328
|
+
console.log(chalk55.green(`Completed item #${id}: ${item.name}`));
|
|
4274
4329
|
}
|
|
4275
4330
|
|
|
4276
4331
|
// src/commands/backlog/start/index.ts
|
|
4277
|
-
import
|
|
4332
|
+
import chalk56 from "chalk";
|
|
4278
4333
|
async function start(id) {
|
|
4279
4334
|
const name = setStatus(id, "in-progress");
|
|
4280
4335
|
if (name) {
|
|
4281
|
-
console.log(
|
|
4336
|
+
console.log(chalk56.green(`Started item #${id}: ${name}`));
|
|
4282
4337
|
}
|
|
4283
4338
|
}
|
|
4284
4339
|
|
|
4285
4340
|
// src/commands/backlog/wontdo/index.ts
|
|
4286
|
-
import
|
|
4341
|
+
import chalk57 from "chalk";
|
|
4287
4342
|
async function wontdo(id, reason) {
|
|
4288
4343
|
const result = loadAndFindItem(id);
|
|
4289
4344
|
if (!result) return;
|
|
@@ -4293,7 +4348,7 @@ async function wontdo(id, reason) {
|
|
|
4293
4348
|
addPhaseSummary(result.item, reason, phase);
|
|
4294
4349
|
}
|
|
4295
4350
|
saveBacklog(result.items);
|
|
4296
|
-
console.log(
|
|
4351
|
+
console.log(chalk57.red(`Won't do item #${id}: ${result.item.name}`));
|
|
4297
4352
|
}
|
|
4298
4353
|
|
|
4299
4354
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -4305,10 +4360,10 @@ function registerStatusCommands(cmd) {
|
|
|
4305
4360
|
}
|
|
4306
4361
|
|
|
4307
4362
|
// src/commands/backlog/removePhase.ts
|
|
4308
|
-
import
|
|
4363
|
+
import chalk59 from "chalk";
|
|
4309
4364
|
|
|
4310
4365
|
// src/commands/backlog/findPhase.ts
|
|
4311
|
-
import
|
|
4366
|
+
import chalk58 from "chalk";
|
|
4312
4367
|
function findPhase(id, phase) {
|
|
4313
4368
|
const result = loadAndFindItem(id);
|
|
4314
4369
|
if (!result) return void 0;
|
|
@@ -4320,7 +4375,7 @@ function findPhase(id, phase) {
|
|
|
4320
4375
|
"SELECT COUNT(*) as cnt FROM plan_phases WHERE item_id = ? AND idx = ?"
|
|
4321
4376
|
).get(itemId, phaseIdx);
|
|
4322
4377
|
if (existing.cnt === 0) {
|
|
4323
|
-
console.log(
|
|
4378
|
+
console.log(chalk58.red(`Phase ${phaseIdx} not found on item #${itemId}.`));
|
|
4324
4379
|
process.exitCode = 1;
|
|
4325
4380
|
return void 0;
|
|
4326
4381
|
}
|
|
@@ -4376,23 +4431,23 @@ function removePhase(id, phase) {
|
|
|
4376
4431
|
run4();
|
|
4377
4432
|
exportToJsonl(db, dir);
|
|
4378
4433
|
commitBacklog(itemId, result.item.name);
|
|
4379
|
-
console.log(
|
|
4434
|
+
console.log(chalk59.green(`Removed phase ${phaseIdx} from item #${itemId}.`));
|
|
4380
4435
|
}
|
|
4381
4436
|
|
|
4382
4437
|
// src/commands/backlog/update/index.ts
|
|
4383
|
-
import
|
|
4438
|
+
import chalk61 from "chalk";
|
|
4384
4439
|
|
|
4385
4440
|
// src/commands/backlog/update/buildUpdateSql.ts
|
|
4386
|
-
import
|
|
4441
|
+
import chalk60 from "chalk";
|
|
4387
4442
|
function buildUpdateSql(options2) {
|
|
4388
4443
|
const { name, desc, type, ac } = options2;
|
|
4389
4444
|
if (!name && !desc && !type && !ac) {
|
|
4390
|
-
console.log(
|
|
4445
|
+
console.log(chalk60.red("Nothing to update. Provide at least one flag."));
|
|
4391
4446
|
process.exitCode = 1;
|
|
4392
4447
|
return void 0;
|
|
4393
4448
|
}
|
|
4394
4449
|
if (type && type !== "story" && type !== "bug") {
|
|
4395
|
-
console.log(
|
|
4450
|
+
console.log(chalk60.red('Invalid type. Must be "story" or "bug".'));
|
|
4396
4451
|
process.exitCode = 1;
|
|
4397
4452
|
return void 0;
|
|
4398
4453
|
}
|
|
@@ -4437,11 +4492,11 @@ function update(id, options2) {
|
|
|
4437
4492
|
);
|
|
4438
4493
|
exportToJsonl(db, dir);
|
|
4439
4494
|
commitBacklog(itemId, options2.name ?? result.item.name);
|
|
4440
|
-
console.log(
|
|
4495
|
+
console.log(chalk61.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
4441
4496
|
}
|
|
4442
4497
|
|
|
4443
4498
|
// src/commands/backlog/updatePhase.ts
|
|
4444
|
-
import
|
|
4499
|
+
import chalk62 from "chalk";
|
|
4445
4500
|
|
|
4446
4501
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
4447
4502
|
function applyPhaseUpdate(db, itemId, phaseIdx, fields) {
|
|
@@ -4475,7 +4530,7 @@ function applyPhaseUpdate(db, itemId, phaseIdx, fields) {
|
|
|
4475
4530
|
function updatePhase(id, phase, options2) {
|
|
4476
4531
|
const { name, task, manualCheck } = options2;
|
|
4477
4532
|
if (!name && !task && !manualCheck) {
|
|
4478
|
-
console.log(
|
|
4533
|
+
console.log(chalk62.red("Nothing to update. Provide at least one flag."));
|
|
4479
4534
|
process.exitCode = 1;
|
|
4480
4535
|
return;
|
|
4481
4536
|
}
|
|
@@ -4491,7 +4546,7 @@ function updatePhase(id, phase, options2) {
|
|
|
4491
4546
|
manualCheck && "manual checks"
|
|
4492
4547
|
].filter(Boolean).join(", ");
|
|
4493
4548
|
console.log(
|
|
4494
|
-
|
|
4549
|
+
chalk62.green(`Updated ${fields} on phase ${phaseIdx} of item #${itemId}.`)
|
|
4495
4550
|
);
|
|
4496
4551
|
}
|
|
4497
4552
|
|
|
@@ -4529,12 +4584,77 @@ function registerBacklog(program2) {
|
|
|
4529
4584
|
registerCommentCommands(cmd);
|
|
4530
4585
|
registerLinkCommands(cmd);
|
|
4531
4586
|
registerPlanCommands(cmd);
|
|
4587
|
+
registerRewindCommand(cmd);
|
|
4532
4588
|
registerNextCommand(cmd);
|
|
4533
4589
|
registerRunCommand(cmd);
|
|
4534
4590
|
registerSearchCommand(cmd);
|
|
4535
4591
|
registerUpdateCommands(cmd);
|
|
4536
4592
|
}
|
|
4537
4593
|
|
|
4594
|
+
// src/shared/splitCompound.ts
|
|
4595
|
+
import { parse } from "shell-quote";
|
|
4596
|
+
|
|
4597
|
+
// src/shared/hasUnquotedBackticks.ts
|
|
4598
|
+
var QUOTED_OR_BACKTICK_RE = /\\.|'[^']*'|"[^"]*"|(`)/g;
|
|
4599
|
+
function hasUnquotedBackticks(command) {
|
|
4600
|
+
QUOTED_OR_BACKTICK_RE.lastIndex = 0;
|
|
4601
|
+
for (let m = QUOTED_OR_BACKTICK_RE.exec(command); m !== null; m = QUOTED_OR_BACKTICK_RE.exec(command)) {
|
|
4602
|
+
if (m[1] !== void 0) return true;
|
|
4603
|
+
}
|
|
4604
|
+
return false;
|
|
4605
|
+
}
|
|
4606
|
+
|
|
4607
|
+
// src/shared/splitCompound.ts
|
|
4608
|
+
var SEPARATOR_OPS = /* @__PURE__ */ new Set(["|", "&&", "||", ";"]);
|
|
4609
|
+
var UNSAFE_OPS = /* @__PURE__ */ new Set(["(", ")", ">", ">>", "<", "<&", "|&", ">&"]);
|
|
4610
|
+
var FD_REDIRECT_RE = /\d+>&\d+/g;
|
|
4611
|
+
var FD_DEVNULL_RE = /\d*>\/dev\/null/g;
|
|
4612
|
+
function splitCompound(command) {
|
|
4613
|
+
const tokens = tokenizeCommand(command);
|
|
4614
|
+
if (!tokens) return void 0;
|
|
4615
|
+
const groups = groupByOperator(tokens);
|
|
4616
|
+
if (!groups) return void 0;
|
|
4617
|
+
const result = groups.map((parts) => stripEnvPrefix(parts).join(" ")).filter((cmd) => cmd !== "");
|
|
4618
|
+
return result.length > 0 ? result : void 0;
|
|
4619
|
+
}
|
|
4620
|
+
function tokenizeCommand(command) {
|
|
4621
|
+
const trimmed = command.trim().replace(FD_DEVNULL_RE, "").replace(FD_REDIRECT_RE, "");
|
|
4622
|
+
if (!trimmed) return void 0;
|
|
4623
|
+
if (hasUnquotedBackticks(trimmed)) return void 0;
|
|
4624
|
+
try {
|
|
4625
|
+
return parse(trimmed);
|
|
4626
|
+
} catch {
|
|
4627
|
+
return void 0;
|
|
4628
|
+
}
|
|
4629
|
+
}
|
|
4630
|
+
function getOp(token) {
|
|
4631
|
+
return typeof token === "object" && token !== null && "op" in token ? token.op : void 0;
|
|
4632
|
+
}
|
|
4633
|
+
function groupByOperator(tokens) {
|
|
4634
|
+
const groups = [[]];
|
|
4635
|
+
for (const token of tokens) {
|
|
4636
|
+
const op = getOp(token);
|
|
4637
|
+
if (op === void 0) {
|
|
4638
|
+
if (typeof token !== "string") return void 0;
|
|
4639
|
+
groups[groups.length - 1].push(token);
|
|
4640
|
+
} else if (op === "glob") {
|
|
4641
|
+
groups[groups.length - 1].push(token.pattern);
|
|
4642
|
+
} else if (SEPARATOR_OPS.has(op)) {
|
|
4643
|
+
groups.push([]);
|
|
4644
|
+
} else if (UNSAFE_OPS.has(op)) {
|
|
4645
|
+
return void 0;
|
|
4646
|
+
} else {
|
|
4647
|
+
return void 0;
|
|
4648
|
+
}
|
|
4649
|
+
}
|
|
4650
|
+
return groups;
|
|
4651
|
+
}
|
|
4652
|
+
function stripEnvPrefix(parts) {
|
|
4653
|
+
let i = 0;
|
|
4654
|
+
while (i < parts.length && /^[A-Za-z_]\w*=/.test(parts[i])) i++;
|
|
4655
|
+
return i > 0 ? parts.slice(i) : parts;
|
|
4656
|
+
}
|
|
4657
|
+
|
|
4538
4658
|
// src/shared/isApprovedRead.ts
|
|
4539
4659
|
import { resolve as resolve3 } from "path";
|
|
4540
4660
|
|
|
@@ -4705,8 +4825,8 @@ var denyCache;
|
|
|
4705
4825
|
var TOOL_RE = /^(Bash|PowerShell)\((.+?)(:.*)?\)$/;
|
|
4706
4826
|
var SHELL_TOOLS = ["Bash", "PowerShell"];
|
|
4707
4827
|
var DOTSLASH_RE = /^\.[\\/]/;
|
|
4708
|
-
var
|
|
4709
|
-
var
|
|
4828
|
+
var FD_REDIRECT_RE2 = /\d+>&\d+/g;
|
|
4829
|
+
var FD_DEVNULL_RE2 = /\d*>\/dev\/null/g;
|
|
4710
4830
|
function loadPerms(key) {
|
|
4711
4831
|
return parsePerms(readSettingsPerms(key));
|
|
4712
4832
|
}
|
|
@@ -4717,7 +4837,7 @@ function shellEntries(map, toolName) {
|
|
|
4717
4837
|
return map.get(toolName) ?? [];
|
|
4718
4838
|
}
|
|
4719
4839
|
function normCmd(cmd) {
|
|
4720
|
-
return cmd.replace(
|
|
4840
|
+
return cmd.replace(FD_DEVNULL_RE2, "").replace(FD_REDIRECT_RE2, "").trim().replace(DOTSLASH_RE, "");
|
|
4721
4841
|
}
|
|
4722
4842
|
function findMatch2(entries, command) {
|
|
4723
4843
|
const norm = normCmd(command);
|
|
@@ -4782,72 +4902,7 @@ function matchesConfigDeny(command) {
|
|
|
4782
4902
|
);
|
|
4783
4903
|
}
|
|
4784
4904
|
|
|
4785
|
-
// src/
|
|
4786
|
-
import { parse } from "shell-quote";
|
|
4787
|
-
|
|
4788
|
-
// src/shared/hasUnquotedBackticks.ts
|
|
4789
|
-
var QUOTED_OR_BACKTICK_RE = /\\.|'[^']*'|"[^"]*"|(`)/g;
|
|
4790
|
-
function hasUnquotedBackticks(command) {
|
|
4791
|
-
QUOTED_OR_BACKTICK_RE.lastIndex = 0;
|
|
4792
|
-
for (let m = QUOTED_OR_BACKTICK_RE.exec(command); m !== null; m = QUOTED_OR_BACKTICK_RE.exec(command)) {
|
|
4793
|
-
if (m[1] !== void 0) return true;
|
|
4794
|
-
}
|
|
4795
|
-
return false;
|
|
4796
|
-
}
|
|
4797
|
-
|
|
4798
|
-
// src/shared/splitCompound.ts
|
|
4799
|
-
var SEPARATOR_OPS = /* @__PURE__ */ new Set(["|", "&&", "||", ";"]);
|
|
4800
|
-
var UNSAFE_OPS = /* @__PURE__ */ new Set(["(", ")", ">", ">>", "<", "<&", "|&", ">&"]);
|
|
4801
|
-
var FD_REDIRECT_RE2 = /\d+>&\d+/g;
|
|
4802
|
-
var FD_DEVNULL_RE2 = /\d*>\/dev\/null/g;
|
|
4803
|
-
function splitCompound(command) {
|
|
4804
|
-
const tokens = tokenizeCommand(command);
|
|
4805
|
-
if (!tokens) return void 0;
|
|
4806
|
-
const groups = groupByOperator(tokens);
|
|
4807
|
-
if (!groups) return void 0;
|
|
4808
|
-
const result = groups.map((parts) => stripEnvPrefix(parts).join(" ")).filter((cmd) => cmd !== "");
|
|
4809
|
-
return result.length > 0 ? result : void 0;
|
|
4810
|
-
}
|
|
4811
|
-
function tokenizeCommand(command) {
|
|
4812
|
-
const trimmed = command.trim().replace(FD_DEVNULL_RE2, "").replace(FD_REDIRECT_RE2, "");
|
|
4813
|
-
if (!trimmed) return void 0;
|
|
4814
|
-
if (hasUnquotedBackticks(trimmed)) return void 0;
|
|
4815
|
-
try {
|
|
4816
|
-
return parse(trimmed);
|
|
4817
|
-
} catch {
|
|
4818
|
-
return void 0;
|
|
4819
|
-
}
|
|
4820
|
-
}
|
|
4821
|
-
function getOp(token) {
|
|
4822
|
-
return typeof token === "object" && token !== null && "op" in token ? token.op : void 0;
|
|
4823
|
-
}
|
|
4824
|
-
function groupByOperator(tokens) {
|
|
4825
|
-
const groups = [[]];
|
|
4826
|
-
for (const token of tokens) {
|
|
4827
|
-
const op = getOp(token);
|
|
4828
|
-
if (op === void 0) {
|
|
4829
|
-
if (typeof token !== "string") return void 0;
|
|
4830
|
-
groups[groups.length - 1].push(token);
|
|
4831
|
-
} else if (op === "glob") {
|
|
4832
|
-
groups[groups.length - 1].push(token.pattern);
|
|
4833
|
-
} else if (SEPARATOR_OPS.has(op)) {
|
|
4834
|
-
groups.push([]);
|
|
4835
|
-
} else if (UNSAFE_OPS.has(op)) {
|
|
4836
|
-
return void 0;
|
|
4837
|
-
} else {
|
|
4838
|
-
return void 0;
|
|
4839
|
-
}
|
|
4840
|
-
}
|
|
4841
|
-
return groups;
|
|
4842
|
-
}
|
|
4843
|
-
function stripEnvPrefix(parts) {
|
|
4844
|
-
let i = 0;
|
|
4845
|
-
while (i < parts.length && /^[A-Za-z_]\w*=/.test(parts[i])) i++;
|
|
4846
|
-
return i > 0 ? parts.slice(i) : parts;
|
|
4847
|
-
}
|
|
4848
|
-
|
|
4849
|
-
// src/commands/cliHook/index.ts
|
|
4850
|
-
var SUPPORTED_TOOLS = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
4905
|
+
// src/commands/cliHook/resolvePermission.ts
|
|
4851
4906
|
function findDeny(toolName, parts) {
|
|
4852
4907
|
for (const part of parts) {
|
|
4853
4908
|
const configDeny = matchesConfigDeny(part);
|
|
@@ -4883,25 +4938,31 @@ function resolvePermission(toolName, parts) {
|
|
|
4883
4938
|
permissionDecisionReason: reasons.join("; ")
|
|
4884
4939
|
};
|
|
4885
4940
|
}
|
|
4886
|
-
|
|
4941
|
+
|
|
4942
|
+
// src/commands/cliHook/index.ts
|
|
4943
|
+
var SUPPORTED_TOOLS = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
4944
|
+
function tryParseInput(raw) {
|
|
4887
4945
|
try {
|
|
4888
|
-
|
|
4946
|
+
const data = JSON.parse(raw);
|
|
4947
|
+
if (!SUPPORTED_TOOLS.has(data.tool_name) || !data.tool_input?.command)
|
|
4948
|
+
return void 0;
|
|
4949
|
+
return {
|
|
4950
|
+
toolName: data.tool_name,
|
|
4951
|
+
command: data.tool_input.command.trim()
|
|
4952
|
+
};
|
|
4889
4953
|
} catch {
|
|
4890
4954
|
return void 0;
|
|
4891
4955
|
}
|
|
4892
4956
|
}
|
|
4893
|
-
function
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
return parts ? { toolName: data.tool_name, parts } : void 0;
|
|
4957
|
+
function decide(toolName, rawCommand) {
|
|
4958
|
+
const parts = splitCompound(rawCommand);
|
|
4959
|
+
if (parts) return resolvePermission(toolName, parts);
|
|
4960
|
+
return findDeny(toolName, [rawCommand]);
|
|
4898
4961
|
}
|
|
4899
4962
|
async function cliHook() {
|
|
4900
|
-
const
|
|
4901
|
-
if (!
|
|
4902
|
-
const
|
|
4903
|
-
if (!cmd) return;
|
|
4904
|
-
const decision = resolvePermission(cmd.toolName, cmd.parts);
|
|
4963
|
+
const input = tryParseInput(await readStdin());
|
|
4964
|
+
if (!input) return;
|
|
4965
|
+
const decision = decide(input.toolName, input.command);
|
|
4905
4966
|
if (!decision) return;
|
|
4906
4967
|
console.log(
|
|
4907
4968
|
JSON.stringify({
|
|
@@ -4988,11 +5049,11 @@ function assertCliExists(cli) {
|
|
|
4988
5049
|
}
|
|
4989
5050
|
|
|
4990
5051
|
// src/commands/permitCliReads/colorize.ts
|
|
4991
|
-
import
|
|
5052
|
+
import chalk63 from "chalk";
|
|
4992
5053
|
function colorize(plainOutput) {
|
|
4993
5054
|
return plainOutput.split("\n").map((line) => {
|
|
4994
|
-
if (line.startsWith(" R ")) return
|
|
4995
|
-
if (line.startsWith(" W ")) return
|
|
5055
|
+
if (line.startsWith(" R ")) return chalk63.green(line);
|
|
5056
|
+
if (line.startsWith(" W ")) return chalk63.red(line);
|
|
4996
5057
|
return line;
|
|
4997
5058
|
}).join("\n");
|
|
4998
5059
|
}
|
|
@@ -5290,48 +5351,48 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
5290
5351
|
}
|
|
5291
5352
|
|
|
5292
5353
|
// src/commands/deny/denyAdd.ts
|
|
5293
|
-
import
|
|
5354
|
+
import chalk64 from "chalk";
|
|
5294
5355
|
function denyAdd(pattern2, message) {
|
|
5295
5356
|
const config = loadProjectConfig();
|
|
5296
5357
|
const deny = config.deny ?? [];
|
|
5297
5358
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
5298
|
-
console.log(
|
|
5359
|
+
console.log(chalk64.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
5299
5360
|
return;
|
|
5300
5361
|
}
|
|
5301
5362
|
deny.push({ pattern: pattern2, message });
|
|
5302
5363
|
config.deny = deny;
|
|
5303
5364
|
saveConfig(config);
|
|
5304
|
-
console.log(
|
|
5365
|
+
console.log(chalk64.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
5305
5366
|
}
|
|
5306
5367
|
|
|
5307
5368
|
// src/commands/deny/denyList.ts
|
|
5308
|
-
import
|
|
5369
|
+
import chalk65 from "chalk";
|
|
5309
5370
|
function denyList() {
|
|
5310
5371
|
const config = loadConfig();
|
|
5311
5372
|
const deny = config.deny;
|
|
5312
5373
|
if (!deny || deny.length === 0) {
|
|
5313
|
-
console.log(
|
|
5374
|
+
console.log(chalk65.dim("No deny rules configured."));
|
|
5314
5375
|
return;
|
|
5315
5376
|
}
|
|
5316
5377
|
for (const rule of deny) {
|
|
5317
|
-
console.log(`${
|
|
5378
|
+
console.log(`${chalk65.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
5318
5379
|
}
|
|
5319
5380
|
}
|
|
5320
5381
|
|
|
5321
5382
|
// src/commands/deny/denyRemove.ts
|
|
5322
|
-
import
|
|
5383
|
+
import chalk66 from "chalk";
|
|
5323
5384
|
function denyRemove(pattern2) {
|
|
5324
5385
|
const config = loadProjectConfig();
|
|
5325
5386
|
const deny = config.deny ?? [];
|
|
5326
5387
|
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
5327
5388
|
if (index === -1) {
|
|
5328
|
-
console.log(
|
|
5389
|
+
console.log(chalk66.yellow(`No deny rule found for: ${pattern2}`));
|
|
5329
5390
|
return;
|
|
5330
5391
|
}
|
|
5331
5392
|
deny.splice(index, 1);
|
|
5332
5393
|
config.deny = deny.length > 0 ? deny : void 0;
|
|
5333
5394
|
saveConfig(config);
|
|
5334
|
-
console.log(
|
|
5395
|
+
console.log(chalk66.green(`Removed deny rule: ${pattern2}`));
|
|
5335
5396
|
}
|
|
5336
5397
|
|
|
5337
5398
|
// src/commands/registerDeny.ts
|
|
@@ -5360,15 +5421,15 @@ function registerCliHook(program2) {
|
|
|
5360
5421
|
}
|
|
5361
5422
|
|
|
5362
5423
|
// src/commands/complexity/analyze.ts
|
|
5363
|
-
import
|
|
5424
|
+
import chalk72 from "chalk";
|
|
5364
5425
|
|
|
5365
5426
|
// src/commands/complexity/cyclomatic.ts
|
|
5366
|
-
import
|
|
5427
|
+
import chalk68 from "chalk";
|
|
5367
5428
|
|
|
5368
5429
|
// src/commands/complexity/shared/index.ts
|
|
5369
5430
|
import fs12 from "fs";
|
|
5370
5431
|
import path20 from "path";
|
|
5371
|
-
import
|
|
5432
|
+
import chalk67 from "chalk";
|
|
5372
5433
|
import ts5 from "typescript";
|
|
5373
5434
|
|
|
5374
5435
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -5614,7 +5675,7 @@ function createSourceFromFile(filePath) {
|
|
|
5614
5675
|
function withSourceFiles(pattern2, callback) {
|
|
5615
5676
|
const files = findSourceFiles2(pattern2);
|
|
5616
5677
|
if (files.length === 0) {
|
|
5617
|
-
console.log(
|
|
5678
|
+
console.log(chalk67.yellow("No files found matching pattern"));
|
|
5618
5679
|
return void 0;
|
|
5619
5680
|
}
|
|
5620
5681
|
return callback(files);
|
|
@@ -5647,11 +5708,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5647
5708
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
5648
5709
|
for (const { file, name, complexity } of results) {
|
|
5649
5710
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
5650
|
-
const color = exceedsThreshold ?
|
|
5651
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
5711
|
+
const color = exceedsThreshold ? chalk68.red : chalk68.white;
|
|
5712
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk68.cyan(complexity)}`);
|
|
5652
5713
|
}
|
|
5653
5714
|
console.log(
|
|
5654
|
-
|
|
5715
|
+
chalk68.dim(
|
|
5655
5716
|
`
|
|
5656
5717
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
5657
5718
|
)
|
|
@@ -5663,7 +5724,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
5663
5724
|
}
|
|
5664
5725
|
|
|
5665
5726
|
// src/commands/complexity/halstead.ts
|
|
5666
|
-
import
|
|
5727
|
+
import chalk69 from "chalk";
|
|
5667
5728
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
5668
5729
|
withSourceFiles(pattern2, (files) => {
|
|
5669
5730
|
const results = [];
|
|
@@ -5678,13 +5739,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5678
5739
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
5679
5740
|
for (const { file, name, metrics } of results) {
|
|
5680
5741
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
5681
|
-
const color = exceedsThreshold ?
|
|
5742
|
+
const color = exceedsThreshold ? chalk69.red : chalk69.white;
|
|
5682
5743
|
console.log(
|
|
5683
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
5744
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk69.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk69.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk69.magenta(metrics.effort.toFixed(1))}`
|
|
5684
5745
|
);
|
|
5685
5746
|
}
|
|
5686
5747
|
console.log(
|
|
5687
|
-
|
|
5748
|
+
chalk69.dim(
|
|
5688
5749
|
`
|
|
5689
5750
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
5690
5751
|
)
|
|
@@ -5699,28 +5760,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
5699
5760
|
import fs13 from "fs";
|
|
5700
5761
|
|
|
5701
5762
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
5702
|
-
import
|
|
5763
|
+
import chalk70 from "chalk";
|
|
5703
5764
|
function displayMaintainabilityResults(results, threshold) {
|
|
5704
5765
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
5705
5766
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
5706
|
-
console.log(
|
|
5767
|
+
console.log(chalk70.green("All files pass maintainability threshold"));
|
|
5707
5768
|
} else {
|
|
5708
5769
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
5709
|
-
const color = threshold !== void 0 ?
|
|
5770
|
+
const color = threshold !== void 0 ? chalk70.red : chalk70.white;
|
|
5710
5771
|
console.log(
|
|
5711
|
-
`${color(file)} \u2192 avg: ${
|
|
5772
|
+
`${color(file)} \u2192 avg: ${chalk70.cyan(avgMaintainability.toFixed(1))}, min: ${chalk70.yellow(minMaintainability.toFixed(1))}`
|
|
5712
5773
|
);
|
|
5713
5774
|
}
|
|
5714
5775
|
}
|
|
5715
|
-
console.log(
|
|
5776
|
+
console.log(chalk70.dim(`
|
|
5716
5777
|
Analyzed ${results.length} files`));
|
|
5717
5778
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
5718
5779
|
console.error(
|
|
5719
|
-
|
|
5780
|
+
chalk70.red(
|
|
5720
5781
|
`
|
|
5721
5782
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
5722
5783
|
|
|
5723
|
-
\u26A0\uFE0F ${
|
|
5784
|
+
\u26A0\uFE0F ${chalk70.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel. Run 'assist complexity <file>' to see all metrics. For larger files, start by extracting responsibilities into smaller files.`
|
|
5724
5785
|
)
|
|
5725
5786
|
);
|
|
5726
5787
|
process.exit(1);
|
|
@@ -5777,7 +5838,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5777
5838
|
|
|
5778
5839
|
// src/commands/complexity/sloc.ts
|
|
5779
5840
|
import fs14 from "fs";
|
|
5780
|
-
import
|
|
5841
|
+
import chalk71 from "chalk";
|
|
5781
5842
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
5782
5843
|
withSourceFiles(pattern2, (files) => {
|
|
5783
5844
|
const results = [];
|
|
@@ -5793,12 +5854,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
5793
5854
|
results.sort((a, b) => b.lines - a.lines);
|
|
5794
5855
|
for (const { file, lines } of results) {
|
|
5795
5856
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
5796
|
-
const color = exceedsThreshold ?
|
|
5797
|
-
console.log(`${color(file)} \u2192 ${
|
|
5857
|
+
const color = exceedsThreshold ? chalk71.red : chalk71.white;
|
|
5858
|
+
console.log(`${color(file)} \u2192 ${chalk71.cyan(lines)} lines`);
|
|
5798
5859
|
}
|
|
5799
5860
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
5800
5861
|
console.log(
|
|
5801
|
-
|
|
5862
|
+
chalk71.dim(`
|
|
5802
5863
|
Total: ${total} lines across ${files.length} files`)
|
|
5803
5864
|
);
|
|
5804
5865
|
if (hasViolation) {
|
|
@@ -5812,21 +5873,21 @@ async function analyze(pattern2) {
|
|
|
5812
5873
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
5813
5874
|
const files = findSourceFiles2(searchPattern);
|
|
5814
5875
|
if (files.length === 0) {
|
|
5815
|
-
console.log(
|
|
5876
|
+
console.log(chalk72.yellow("No files found matching pattern"));
|
|
5816
5877
|
return;
|
|
5817
5878
|
}
|
|
5818
5879
|
if (files.length === 1) {
|
|
5819
5880
|
const file = files[0];
|
|
5820
|
-
console.log(
|
|
5881
|
+
console.log(chalk72.bold.underline("SLOC"));
|
|
5821
5882
|
await sloc(file);
|
|
5822
5883
|
console.log();
|
|
5823
|
-
console.log(
|
|
5884
|
+
console.log(chalk72.bold.underline("Cyclomatic Complexity"));
|
|
5824
5885
|
await cyclomatic(file);
|
|
5825
5886
|
console.log();
|
|
5826
|
-
console.log(
|
|
5887
|
+
console.log(chalk72.bold.underline("Halstead Metrics"));
|
|
5827
5888
|
await halstead(file);
|
|
5828
5889
|
console.log();
|
|
5829
|
-
console.log(
|
|
5890
|
+
console.log(chalk72.bold.underline("Maintainability Index"));
|
|
5830
5891
|
await maintainability(file);
|
|
5831
5892
|
return;
|
|
5832
5893
|
}
|
|
@@ -5853,7 +5914,7 @@ function registerComplexity(program2) {
|
|
|
5853
5914
|
}
|
|
5854
5915
|
|
|
5855
5916
|
// src/commands/config/index.ts
|
|
5856
|
-
import
|
|
5917
|
+
import chalk73 from "chalk";
|
|
5857
5918
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
5858
5919
|
|
|
5859
5920
|
// src/commands/config/setNestedValue.ts
|
|
@@ -5916,7 +5977,7 @@ function formatIssuePath(issue, key) {
|
|
|
5916
5977
|
function printValidationErrors(issues, key) {
|
|
5917
5978
|
for (const issue of issues) {
|
|
5918
5979
|
console.error(
|
|
5919
|
-
|
|
5980
|
+
chalk73.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
5920
5981
|
);
|
|
5921
5982
|
}
|
|
5922
5983
|
}
|
|
@@ -5933,7 +5994,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
5933
5994
|
function assertNotGlobalOnly(key, global) {
|
|
5934
5995
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
5935
5996
|
console.error(
|
|
5936
|
-
|
|
5997
|
+
chalk73.red(
|
|
5937
5998
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
5938
5999
|
)
|
|
5939
6000
|
);
|
|
@@ -5956,7 +6017,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
5956
6017
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
5957
6018
|
const target = options2.global ? "global" : "project";
|
|
5958
6019
|
console.log(
|
|
5959
|
-
|
|
6020
|
+
chalk73.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
5960
6021
|
);
|
|
5961
6022
|
}
|
|
5962
6023
|
function configList() {
|
|
@@ -5965,7 +6026,7 @@ function configList() {
|
|
|
5965
6026
|
}
|
|
5966
6027
|
|
|
5967
6028
|
// src/commands/config/configGet.ts
|
|
5968
|
-
import
|
|
6029
|
+
import chalk74 from "chalk";
|
|
5969
6030
|
|
|
5970
6031
|
// src/commands/config/getNestedValue.ts
|
|
5971
6032
|
function isTraversable(value) {
|
|
@@ -5997,7 +6058,7 @@ function requireNestedValue(config, key) {
|
|
|
5997
6058
|
return value;
|
|
5998
6059
|
}
|
|
5999
6060
|
function exitKeyNotSet(key) {
|
|
6000
|
-
console.error(
|
|
6061
|
+
console.error(chalk74.red(`Key "${key}" is not set`));
|
|
6001
6062
|
process.exit(1);
|
|
6002
6063
|
}
|
|
6003
6064
|
|
|
@@ -6011,7 +6072,7 @@ function registerConfig(program2) {
|
|
|
6011
6072
|
|
|
6012
6073
|
// src/commands/deploy/redirect.ts
|
|
6013
6074
|
import { existsSync as existsSync22, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "fs";
|
|
6014
|
-
import
|
|
6075
|
+
import chalk75 from "chalk";
|
|
6015
6076
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
6016
6077
|
if (!window.location.pathname.endsWith('/')) {
|
|
6017
6078
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -6020,22 +6081,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
6020
6081
|
function redirect() {
|
|
6021
6082
|
const indexPath = "index.html";
|
|
6022
6083
|
if (!existsSync22(indexPath)) {
|
|
6023
|
-
console.log(
|
|
6084
|
+
console.log(chalk75.yellow("No index.html found"));
|
|
6024
6085
|
return;
|
|
6025
6086
|
}
|
|
6026
6087
|
const content = readFileSync19(indexPath, "utf-8");
|
|
6027
6088
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
6028
|
-
console.log(
|
|
6089
|
+
console.log(chalk75.dim("Trailing slash script already present"));
|
|
6029
6090
|
return;
|
|
6030
6091
|
}
|
|
6031
6092
|
const headCloseIndex = content.indexOf("</head>");
|
|
6032
6093
|
if (headCloseIndex === -1) {
|
|
6033
|
-
console.log(
|
|
6094
|
+
console.log(chalk75.red("Could not find </head> tag in index.html"));
|
|
6034
6095
|
return;
|
|
6035
6096
|
}
|
|
6036
6097
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
6037
6098
|
writeFileSync18(indexPath, newContent);
|
|
6038
|
-
console.log(
|
|
6099
|
+
console.log(chalk75.green("Added trailing slash redirect to index.html"));
|
|
6039
6100
|
}
|
|
6040
6101
|
|
|
6041
6102
|
// src/commands/registerDeploy.ts
|
|
@@ -6062,7 +6123,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
6062
6123
|
|
|
6063
6124
|
// src/commands/devlog/shared.ts
|
|
6064
6125
|
import { execSync as execSync18 } from "child_process";
|
|
6065
|
-
import
|
|
6126
|
+
import chalk76 from "chalk";
|
|
6066
6127
|
|
|
6067
6128
|
// src/shared/getRepoName.ts
|
|
6068
6129
|
import { existsSync as existsSync23, readFileSync as readFileSync20 } from "fs";
|
|
@@ -6171,13 +6232,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
6171
6232
|
}
|
|
6172
6233
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
6173
6234
|
for (const commit2 of commits) {
|
|
6174
|
-
console.log(` ${
|
|
6235
|
+
console.log(` ${chalk76.yellow(commit2.hash)} ${commit2.message}`);
|
|
6175
6236
|
if (verbose) {
|
|
6176
6237
|
const visibleFiles = commit2.files.filter(
|
|
6177
6238
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
6178
6239
|
);
|
|
6179
6240
|
for (const file of visibleFiles) {
|
|
6180
|
-
console.log(` ${
|
|
6241
|
+
console.log(` ${chalk76.dim(file)}`);
|
|
6181
6242
|
}
|
|
6182
6243
|
}
|
|
6183
6244
|
}
|
|
@@ -6202,15 +6263,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
6202
6263
|
}
|
|
6203
6264
|
|
|
6204
6265
|
// src/commands/devlog/list/printDateHeader.ts
|
|
6205
|
-
import
|
|
6266
|
+
import chalk77 from "chalk";
|
|
6206
6267
|
function printDateHeader(date, isSkipped, entries) {
|
|
6207
6268
|
if (isSkipped) {
|
|
6208
|
-
console.log(`${
|
|
6269
|
+
console.log(`${chalk77.bold.blue(date)} ${chalk77.dim("skipped")}`);
|
|
6209
6270
|
} else if (entries && entries.length > 0) {
|
|
6210
|
-
const entryInfo = entries.map((e) => `${
|
|
6211
|
-
console.log(`${
|
|
6271
|
+
const entryInfo = entries.map((e) => `${chalk77.green(e.version)} ${e.title}`).join(" | ");
|
|
6272
|
+
console.log(`${chalk77.bold.blue(date)} ${entryInfo}`);
|
|
6212
6273
|
} else {
|
|
6213
|
-
console.log(`${
|
|
6274
|
+
console.log(`${chalk77.bold.blue(date)} ${chalk77.red("\u26A0 devlog missing")}`);
|
|
6214
6275
|
}
|
|
6215
6276
|
}
|
|
6216
6277
|
|
|
@@ -6314,24 +6375,24 @@ function bumpVersion(version2, type) {
|
|
|
6314
6375
|
|
|
6315
6376
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
6316
6377
|
import { execSync as execSync21 } from "child_process";
|
|
6317
|
-
import
|
|
6378
|
+
import chalk79 from "chalk";
|
|
6318
6379
|
|
|
6319
6380
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
6320
|
-
import
|
|
6381
|
+
import chalk78 from "chalk";
|
|
6321
6382
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
6322
6383
|
if (conventional && firstHash) {
|
|
6323
6384
|
const version2 = getVersionAtCommit(firstHash);
|
|
6324
6385
|
if (version2) {
|
|
6325
|
-
console.log(`${
|
|
6386
|
+
console.log(`${chalk78.bold("version:")} ${stripToMinor(version2)}`);
|
|
6326
6387
|
} else {
|
|
6327
|
-
console.log(`${
|
|
6388
|
+
console.log(`${chalk78.bold("version:")} ${chalk78.red("unknown")}`);
|
|
6328
6389
|
}
|
|
6329
6390
|
} else if (patchVersion && minorVersion) {
|
|
6330
6391
|
console.log(
|
|
6331
|
-
`${
|
|
6392
|
+
`${chalk78.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
6332
6393
|
);
|
|
6333
6394
|
} else {
|
|
6334
|
-
console.log(`${
|
|
6395
|
+
console.log(`${chalk78.bold("version:")} v0.1 (initial)`);
|
|
6335
6396
|
}
|
|
6336
6397
|
}
|
|
6337
6398
|
|
|
@@ -6378,16 +6439,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
6378
6439
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
6379
6440
|
}
|
|
6380
6441
|
function logName(repoName) {
|
|
6381
|
-
console.log(`${
|
|
6442
|
+
console.log(`${chalk79.bold("name:")} ${repoName}`);
|
|
6382
6443
|
}
|
|
6383
6444
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
6384
6445
|
logName(ctx.repoName);
|
|
6385
6446
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
6386
|
-
console.log(
|
|
6447
|
+
console.log(chalk79.bold.blue(targetDate));
|
|
6387
6448
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
6388
6449
|
}
|
|
6389
6450
|
function logNoCommits(lastInfo) {
|
|
6390
|
-
console.log(
|
|
6451
|
+
console.log(chalk79.dim(noCommitsMessage(!!lastInfo)));
|
|
6391
6452
|
}
|
|
6392
6453
|
|
|
6393
6454
|
// src/commands/devlog/next/index.ts
|
|
@@ -6428,11 +6489,11 @@ function next2(options2) {
|
|
|
6428
6489
|
import { execSync as execSync22 } from "child_process";
|
|
6429
6490
|
|
|
6430
6491
|
// src/commands/devlog/repos/printReposTable.ts
|
|
6431
|
-
import
|
|
6492
|
+
import chalk80 from "chalk";
|
|
6432
6493
|
function colorStatus(status2) {
|
|
6433
|
-
if (status2 === "missing") return
|
|
6434
|
-
if (status2 === "outdated") return
|
|
6435
|
-
return
|
|
6494
|
+
if (status2 === "missing") return chalk80.red(status2);
|
|
6495
|
+
if (status2 === "outdated") return chalk80.yellow(status2);
|
|
6496
|
+
return chalk80.green(status2);
|
|
6436
6497
|
}
|
|
6437
6498
|
function formatRow(row, nameWidth) {
|
|
6438
6499
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -6446,8 +6507,8 @@ function printReposTable(rows) {
|
|
|
6446
6507
|
"Last Devlog".padEnd(11),
|
|
6447
6508
|
"Status"
|
|
6448
6509
|
].join(" ");
|
|
6449
|
-
console.log(
|
|
6450
|
-
console.log(
|
|
6510
|
+
console.log(chalk80.dim(header));
|
|
6511
|
+
console.log(chalk80.dim("-".repeat(header.length)));
|
|
6451
6512
|
for (const row of rows) {
|
|
6452
6513
|
console.log(formatRow(row, nameWidth));
|
|
6453
6514
|
}
|
|
@@ -6505,14 +6566,14 @@ function repos(options2) {
|
|
|
6505
6566
|
// src/commands/devlog/skip.ts
|
|
6506
6567
|
import { writeFileSync as writeFileSync19 } from "fs";
|
|
6507
6568
|
import { join as join22 } from "path";
|
|
6508
|
-
import
|
|
6569
|
+
import chalk81 from "chalk";
|
|
6509
6570
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
6510
6571
|
function getBlogConfigPath() {
|
|
6511
6572
|
return join22(BLOG_REPO_ROOT, "assist.yml");
|
|
6512
6573
|
}
|
|
6513
6574
|
function skip(date) {
|
|
6514
6575
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
6515
|
-
console.log(
|
|
6576
|
+
console.log(chalk81.red("Invalid date format. Use YYYY-MM-DD"));
|
|
6516
6577
|
process.exit(1);
|
|
6517
6578
|
}
|
|
6518
6579
|
const repoName = getRepoName();
|
|
@@ -6523,7 +6584,7 @@ function skip(date) {
|
|
|
6523
6584
|
const skipDays = skip2[repoName] ?? [];
|
|
6524
6585
|
if (skipDays.includes(date)) {
|
|
6525
6586
|
console.log(
|
|
6526
|
-
|
|
6587
|
+
chalk81.yellow(`${date} is already in skip list for ${repoName}`)
|
|
6527
6588
|
);
|
|
6528
6589
|
return;
|
|
6529
6590
|
}
|
|
@@ -6533,20 +6594,20 @@ function skip(date) {
|
|
|
6533
6594
|
devlog.skip = skip2;
|
|
6534
6595
|
config.devlog = devlog;
|
|
6535
6596
|
writeFileSync19(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
6536
|
-
console.log(
|
|
6597
|
+
console.log(chalk81.green(`Added ${date} to skip list for ${repoName}`));
|
|
6537
6598
|
}
|
|
6538
6599
|
|
|
6539
6600
|
// src/commands/devlog/version.ts
|
|
6540
|
-
import
|
|
6601
|
+
import chalk82 from "chalk";
|
|
6541
6602
|
function version() {
|
|
6542
6603
|
const config = loadConfig();
|
|
6543
6604
|
const name = getRepoName();
|
|
6544
6605
|
const lastInfo = getLastVersionInfo(name, config);
|
|
6545
6606
|
const lastVersion = lastInfo?.version ?? null;
|
|
6546
6607
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
6547
|
-
console.log(`${
|
|
6548
|
-
console.log(`${
|
|
6549
|
-
console.log(`${
|
|
6608
|
+
console.log(`${chalk82.bold("name:")} ${name}`);
|
|
6609
|
+
console.log(`${chalk82.bold("last:")} ${lastVersion ?? chalk82.dim("none")}`);
|
|
6610
|
+
console.log(`${chalk82.bold("next:")} ${nextVersion ?? chalk82.dim("none")}`);
|
|
6550
6611
|
}
|
|
6551
6612
|
|
|
6552
6613
|
// src/commands/registerDevlog.ts
|
|
@@ -6570,7 +6631,7 @@ function registerDevlog(program2) {
|
|
|
6570
6631
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
6571
6632
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
6572
6633
|
import { join as join23 } from "path";
|
|
6573
|
-
import
|
|
6634
|
+
import chalk83 from "chalk";
|
|
6574
6635
|
|
|
6575
6636
|
// src/shared/findRepoRoot.ts
|
|
6576
6637
|
import { existsSync as existsSync24 } from "fs";
|
|
@@ -6633,14 +6694,14 @@ function checkBuildLocks(startDir) {
|
|
|
6633
6694
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
6634
6695
|
if (locked) {
|
|
6635
6696
|
console.error(
|
|
6636
|
-
|
|
6697
|
+
chalk83.red("Build output locked (is VS debugging?): ") + locked
|
|
6637
6698
|
);
|
|
6638
6699
|
process.exit(1);
|
|
6639
6700
|
}
|
|
6640
6701
|
}
|
|
6641
6702
|
async function checkBuildLocksCommand() {
|
|
6642
6703
|
checkBuildLocks();
|
|
6643
|
-
console.log(
|
|
6704
|
+
console.log(chalk83.green("No build locks detected"));
|
|
6644
6705
|
}
|
|
6645
6706
|
|
|
6646
6707
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -6739,30 +6800,30 @@ function escapeRegex(s) {
|
|
|
6739
6800
|
}
|
|
6740
6801
|
|
|
6741
6802
|
// src/commands/dotnet/printTree.ts
|
|
6742
|
-
import
|
|
6803
|
+
import chalk84 from "chalk";
|
|
6743
6804
|
function printNodes(nodes, prefix2) {
|
|
6744
6805
|
for (let i = 0; i < nodes.length; i++) {
|
|
6745
6806
|
const isLast = i === nodes.length - 1;
|
|
6746
6807
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
6747
6808
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
6748
6809
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
6749
|
-
const label2 = isMissing ?
|
|
6810
|
+
const label2 = isMissing ? chalk84.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
6750
6811
|
console.log(`${prefix2}${connector}${label2}`);
|
|
6751
6812
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
6752
6813
|
}
|
|
6753
6814
|
}
|
|
6754
6815
|
function printTree(tree, totalCount, solutions) {
|
|
6755
|
-
console.log(
|
|
6756
|
-
console.log(
|
|
6816
|
+
console.log(chalk84.bold("\nProject Dependency Tree"));
|
|
6817
|
+
console.log(chalk84.cyan(tree.relativePath));
|
|
6757
6818
|
printNodes(tree.children, "");
|
|
6758
|
-
console.log(
|
|
6819
|
+
console.log(chalk84.dim(`
|
|
6759
6820
|
${totalCount} projects total (including root)`));
|
|
6760
|
-
console.log(
|
|
6821
|
+
console.log(chalk84.bold("\nSolution Membership"));
|
|
6761
6822
|
if (solutions.length === 0) {
|
|
6762
|
-
console.log(
|
|
6823
|
+
console.log(chalk84.yellow(" Not found in any .sln"));
|
|
6763
6824
|
} else {
|
|
6764
6825
|
for (const sln of solutions) {
|
|
6765
|
-
console.log(` ${
|
|
6826
|
+
console.log(` ${chalk84.green(sln)}`);
|
|
6766
6827
|
}
|
|
6767
6828
|
}
|
|
6768
6829
|
console.log();
|
|
@@ -6791,16 +6852,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
6791
6852
|
// src/commands/dotnet/resolveCsproj.ts
|
|
6792
6853
|
import { existsSync as existsSync25 } from "fs";
|
|
6793
6854
|
import path24 from "path";
|
|
6794
|
-
import
|
|
6855
|
+
import chalk85 from "chalk";
|
|
6795
6856
|
function resolveCsproj(csprojPath) {
|
|
6796
6857
|
const resolved = path24.resolve(csprojPath);
|
|
6797
6858
|
if (!existsSync25(resolved)) {
|
|
6798
|
-
console.error(
|
|
6859
|
+
console.error(chalk85.red(`File not found: ${resolved}`));
|
|
6799
6860
|
process.exit(1);
|
|
6800
6861
|
}
|
|
6801
6862
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
6802
6863
|
if (!repoRoot) {
|
|
6803
|
-
console.error(
|
|
6864
|
+
console.error(chalk85.red("Could not find git repository root"));
|
|
6804
6865
|
process.exit(1);
|
|
6805
6866
|
}
|
|
6806
6867
|
return { resolved, repoRoot };
|
|
@@ -6850,12 +6911,12 @@ function getChangedCsFiles(scope) {
|
|
|
6850
6911
|
}
|
|
6851
6912
|
|
|
6852
6913
|
// src/commands/dotnet/inSln.ts
|
|
6853
|
-
import
|
|
6914
|
+
import chalk86 from "chalk";
|
|
6854
6915
|
async function inSln(csprojPath) {
|
|
6855
6916
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
6856
6917
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
6857
6918
|
if (solutions.length === 0) {
|
|
6858
|
-
console.log(
|
|
6919
|
+
console.log(chalk86.yellow("Not found in any .sln file"));
|
|
6859
6920
|
process.exit(1);
|
|
6860
6921
|
}
|
|
6861
6922
|
for (const sln of solutions) {
|
|
@@ -6864,7 +6925,7 @@ async function inSln(csprojPath) {
|
|
|
6864
6925
|
}
|
|
6865
6926
|
|
|
6866
6927
|
// src/commands/dotnet/inspect.ts
|
|
6867
|
-
import
|
|
6928
|
+
import chalk92 from "chalk";
|
|
6868
6929
|
|
|
6869
6930
|
// src/shared/formatElapsed.ts
|
|
6870
6931
|
function formatElapsed(ms) {
|
|
@@ -6876,12 +6937,12 @@ function formatElapsed(ms) {
|
|
|
6876
6937
|
}
|
|
6877
6938
|
|
|
6878
6939
|
// src/commands/dotnet/displayIssues.ts
|
|
6879
|
-
import
|
|
6940
|
+
import chalk87 from "chalk";
|
|
6880
6941
|
var SEVERITY_COLOR = {
|
|
6881
|
-
ERROR:
|
|
6882
|
-
WARNING:
|
|
6883
|
-
SUGGESTION:
|
|
6884
|
-
HINT:
|
|
6942
|
+
ERROR: chalk87.red,
|
|
6943
|
+
WARNING: chalk87.yellow,
|
|
6944
|
+
SUGGESTION: chalk87.cyan,
|
|
6945
|
+
HINT: chalk87.dim
|
|
6885
6946
|
};
|
|
6886
6947
|
function groupByFile(issues) {
|
|
6887
6948
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -6897,15 +6958,15 @@ function groupByFile(issues) {
|
|
|
6897
6958
|
}
|
|
6898
6959
|
function displayIssues(issues) {
|
|
6899
6960
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
6900
|
-
console.log(
|
|
6961
|
+
console.log(chalk87.bold(file));
|
|
6901
6962
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
6902
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
6963
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk87.white;
|
|
6903
6964
|
console.log(
|
|
6904
|
-
` ${
|
|
6965
|
+
` ${chalk87.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
6905
6966
|
);
|
|
6906
6967
|
}
|
|
6907
6968
|
}
|
|
6908
|
-
console.log(
|
|
6969
|
+
console.log(chalk87.dim(`
|
|
6909
6970
|
${issues.length} issue(s) found`));
|
|
6910
6971
|
}
|
|
6911
6972
|
|
|
@@ -6964,12 +7025,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
6964
7025
|
// src/commands/dotnet/resolveSolution.ts
|
|
6965
7026
|
import { existsSync as existsSync26 } from "fs";
|
|
6966
7027
|
import path25 from "path";
|
|
6967
|
-
import
|
|
7028
|
+
import chalk89 from "chalk";
|
|
6968
7029
|
|
|
6969
7030
|
// src/commands/dotnet/findSolution.ts
|
|
6970
7031
|
import { readdirSync as readdirSync4 } from "fs";
|
|
6971
7032
|
import { dirname as dirname16, join as join24 } from "path";
|
|
6972
|
-
import
|
|
7033
|
+
import chalk88 from "chalk";
|
|
6973
7034
|
function findSlnInDir(dir) {
|
|
6974
7035
|
try {
|
|
6975
7036
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join24(dir, f));
|
|
@@ -6985,17 +7046,17 @@ function findSolution() {
|
|
|
6985
7046
|
const slnFiles = findSlnInDir(current);
|
|
6986
7047
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
6987
7048
|
if (slnFiles.length > 1) {
|
|
6988
|
-
console.error(
|
|
7049
|
+
console.error(chalk88.red(`Multiple .sln files found in ${current}:`));
|
|
6989
7050
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
6990
7051
|
console.error(
|
|
6991
|
-
|
|
7052
|
+
chalk88.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
6992
7053
|
);
|
|
6993
7054
|
process.exit(1);
|
|
6994
7055
|
}
|
|
6995
7056
|
if (current === ceiling) break;
|
|
6996
7057
|
current = dirname16(current);
|
|
6997
7058
|
}
|
|
6998
|
-
console.error(
|
|
7059
|
+
console.error(chalk88.red("No .sln file found between cwd and repo root"));
|
|
6999
7060
|
process.exit(1);
|
|
7000
7061
|
}
|
|
7001
7062
|
|
|
@@ -7004,7 +7065,7 @@ function resolveSolution(sln) {
|
|
|
7004
7065
|
if (sln) {
|
|
7005
7066
|
const resolved = path25.resolve(sln);
|
|
7006
7067
|
if (!existsSync26(resolved)) {
|
|
7007
|
-
console.error(
|
|
7068
|
+
console.error(chalk89.red(`Solution file not found: ${resolved}`));
|
|
7008
7069
|
process.exit(1);
|
|
7009
7070
|
}
|
|
7010
7071
|
return resolved;
|
|
@@ -7046,14 +7107,14 @@ import { execSync as execSync24 } from "child_process";
|
|
|
7046
7107
|
import { existsSync as existsSync27, readFileSync as readFileSync24, unlinkSync as unlinkSync5 } from "fs";
|
|
7047
7108
|
import { tmpdir as tmpdir2 } from "os";
|
|
7048
7109
|
import path26 from "path";
|
|
7049
|
-
import
|
|
7110
|
+
import chalk90 from "chalk";
|
|
7050
7111
|
function assertJbInstalled() {
|
|
7051
7112
|
try {
|
|
7052
7113
|
execSync24("jb inspectcode --version", { stdio: "pipe" });
|
|
7053
7114
|
} catch {
|
|
7054
|
-
console.error(
|
|
7115
|
+
console.error(chalk90.red("jb is not installed. Install with:"));
|
|
7055
7116
|
console.error(
|
|
7056
|
-
|
|
7117
|
+
chalk90.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
7057
7118
|
);
|
|
7058
7119
|
process.exit(1);
|
|
7059
7120
|
}
|
|
@@ -7071,11 +7132,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
7071
7132
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
7072
7133
|
process.stderr.write(err.stderr);
|
|
7073
7134
|
}
|
|
7074
|
-
console.error(
|
|
7135
|
+
console.error(chalk90.red("jb inspectcode failed"));
|
|
7075
7136
|
process.exit(1);
|
|
7076
7137
|
}
|
|
7077
7138
|
if (!existsSync27(reportPath)) {
|
|
7078
|
-
console.error(
|
|
7139
|
+
console.error(chalk90.red("Report file not generated"));
|
|
7079
7140
|
process.exit(1);
|
|
7080
7141
|
}
|
|
7081
7142
|
const xml = readFileSync24(reportPath, "utf-8");
|
|
@@ -7085,7 +7146,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
7085
7146
|
|
|
7086
7147
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
7087
7148
|
import { execSync as execSync25 } from "child_process";
|
|
7088
|
-
import
|
|
7149
|
+
import chalk91 from "chalk";
|
|
7089
7150
|
function resolveMsbuildPath() {
|
|
7090
7151
|
const config = loadConfig();
|
|
7091
7152
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -7096,9 +7157,9 @@ function assertMsbuildInstalled() {
|
|
|
7096
7157
|
try {
|
|
7097
7158
|
execSync25(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
7098
7159
|
} catch {
|
|
7099
|
-
console.error(
|
|
7160
|
+
console.error(chalk91.red(`msbuild not found at: ${msbuild}`));
|
|
7100
7161
|
console.error(
|
|
7101
|
-
|
|
7162
|
+
chalk91.yellow(
|
|
7102
7163
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
7103
7164
|
)
|
|
7104
7165
|
);
|
|
@@ -7145,17 +7206,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
7145
7206
|
// src/commands/dotnet/inspect.ts
|
|
7146
7207
|
function logScope(changedFiles) {
|
|
7147
7208
|
if (changedFiles === null) {
|
|
7148
|
-
console.log(
|
|
7209
|
+
console.log(chalk92.dim("Inspecting full solution..."));
|
|
7149
7210
|
} else {
|
|
7150
7211
|
console.log(
|
|
7151
|
-
|
|
7212
|
+
chalk92.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
7152
7213
|
);
|
|
7153
7214
|
}
|
|
7154
7215
|
}
|
|
7155
7216
|
function reportResults(issues, elapsed) {
|
|
7156
7217
|
if (issues.length > 0) displayIssues(issues);
|
|
7157
|
-
else console.log(
|
|
7158
|
-
console.log(
|
|
7218
|
+
else console.log(chalk92.green("No issues found"));
|
|
7219
|
+
console.log(chalk92.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
7159
7220
|
if (issues.length > 0) process.exit(1);
|
|
7160
7221
|
}
|
|
7161
7222
|
async function inspect(sln, options2) {
|
|
@@ -7166,7 +7227,7 @@ async function inspect(sln, options2) {
|
|
|
7166
7227
|
const scope = parseScope(options2.scope);
|
|
7167
7228
|
const changedFiles = getChangedCsFiles(scope);
|
|
7168
7229
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
7169
|
-
console.log(
|
|
7230
|
+
console.log(chalk92.green("No changed .cs files found"));
|
|
7170
7231
|
return;
|
|
7171
7232
|
}
|
|
7172
7233
|
logScope(changedFiles);
|
|
@@ -7192,7 +7253,7 @@ function registerDotnet(program2) {
|
|
|
7192
7253
|
}
|
|
7193
7254
|
|
|
7194
7255
|
// src/commands/jira/acceptanceCriteria.ts
|
|
7195
|
-
import
|
|
7256
|
+
import chalk94 from "chalk";
|
|
7196
7257
|
|
|
7197
7258
|
// src/commands/jira/adfToText.ts
|
|
7198
7259
|
function renderInline(node) {
|
|
@@ -7253,7 +7314,7 @@ function adfToText(doc) {
|
|
|
7253
7314
|
|
|
7254
7315
|
// src/commands/jira/fetchIssue.ts
|
|
7255
7316
|
import { execSync as execSync26 } from "child_process";
|
|
7256
|
-
import
|
|
7317
|
+
import chalk93 from "chalk";
|
|
7257
7318
|
function fetchIssue(issueKey, fields) {
|
|
7258
7319
|
let result;
|
|
7259
7320
|
try {
|
|
@@ -7266,15 +7327,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
7266
7327
|
const stderr = error.stderr;
|
|
7267
7328
|
if (stderr.includes("unauthorized")) {
|
|
7268
7329
|
console.error(
|
|
7269
|
-
|
|
7330
|
+
chalk93.red("Jira authentication expired."),
|
|
7270
7331
|
"Run",
|
|
7271
|
-
|
|
7332
|
+
chalk93.cyan("assist jira auth"),
|
|
7272
7333
|
"to re-authenticate."
|
|
7273
7334
|
);
|
|
7274
7335
|
process.exit(1);
|
|
7275
7336
|
}
|
|
7276
7337
|
}
|
|
7277
|
-
console.error(
|
|
7338
|
+
console.error(chalk93.red(`Failed to fetch ${issueKey}.`));
|
|
7278
7339
|
process.exit(1);
|
|
7279
7340
|
}
|
|
7280
7341
|
return JSON.parse(result);
|
|
@@ -7288,7 +7349,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
7288
7349
|
const parsed = fetchIssue(issueKey, field);
|
|
7289
7350
|
const acValue = parsed?.fields?.[field];
|
|
7290
7351
|
if (!acValue) {
|
|
7291
|
-
console.log(
|
|
7352
|
+
console.log(chalk94.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
7292
7353
|
return;
|
|
7293
7354
|
}
|
|
7294
7355
|
if (typeof acValue === "string") {
|
|
@@ -7383,14 +7444,14 @@ async function jiraAuth() {
|
|
|
7383
7444
|
}
|
|
7384
7445
|
|
|
7385
7446
|
// src/commands/jira/viewIssue.ts
|
|
7386
|
-
import
|
|
7447
|
+
import chalk95 from "chalk";
|
|
7387
7448
|
function viewIssue(issueKey) {
|
|
7388
7449
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
7389
7450
|
const fields = parsed?.fields;
|
|
7390
7451
|
const summary = fields?.summary;
|
|
7391
7452
|
const description = fields?.description;
|
|
7392
7453
|
if (summary) {
|
|
7393
|
-
console.log(
|
|
7454
|
+
console.log(chalk95.bold(summary));
|
|
7394
7455
|
}
|
|
7395
7456
|
if (description) {
|
|
7396
7457
|
if (summary) console.log();
|
|
@@ -7404,7 +7465,7 @@ function viewIssue(issueKey) {
|
|
|
7404
7465
|
}
|
|
7405
7466
|
if (!summary && !description) {
|
|
7406
7467
|
console.log(
|
|
7407
|
-
|
|
7468
|
+
chalk95.yellow(`No summary or description found on ${issueKey}.`)
|
|
7408
7469
|
);
|
|
7409
7470
|
}
|
|
7410
7471
|
}
|
|
@@ -7418,7 +7479,7 @@ function registerJira(program2) {
|
|
|
7418
7479
|
}
|
|
7419
7480
|
|
|
7420
7481
|
// src/commands/news/add/index.ts
|
|
7421
|
-
import
|
|
7482
|
+
import chalk96 from "chalk";
|
|
7422
7483
|
import enquirer8 from "enquirer";
|
|
7423
7484
|
async function add2(url) {
|
|
7424
7485
|
if (!url) {
|
|
@@ -7441,17 +7502,17 @@ async function add2(url) {
|
|
|
7441
7502
|
const news = config.news ?? {};
|
|
7442
7503
|
const feeds = news.feeds ?? [];
|
|
7443
7504
|
if (feeds.includes(url)) {
|
|
7444
|
-
console.log(
|
|
7505
|
+
console.log(chalk96.yellow("Feed already exists in config"));
|
|
7445
7506
|
return;
|
|
7446
7507
|
}
|
|
7447
7508
|
feeds.push(url);
|
|
7448
7509
|
config.news = { ...news, feeds };
|
|
7449
7510
|
saveGlobalConfig(config);
|
|
7450
|
-
console.log(
|
|
7511
|
+
console.log(chalk96.green(`Added feed: ${url}`));
|
|
7451
7512
|
}
|
|
7452
7513
|
|
|
7453
7514
|
// src/commands/news/web/handleRequest.ts
|
|
7454
|
-
import
|
|
7515
|
+
import chalk97 from "chalk";
|
|
7455
7516
|
|
|
7456
7517
|
// src/commands/news/web/shared.ts
|
|
7457
7518
|
import { decodeHTML } from "entities";
|
|
@@ -7587,17 +7648,17 @@ function prefetch() {
|
|
|
7587
7648
|
const config = loadConfig();
|
|
7588
7649
|
const total = config.news.feeds.length;
|
|
7589
7650
|
if (total === 0) return;
|
|
7590
|
-
process.stdout.write(
|
|
7651
|
+
process.stdout.write(chalk97.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
7591
7652
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
7592
7653
|
const width = 20;
|
|
7593
7654
|
const filled = Math.round(done2 / t * width);
|
|
7594
7655
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
7595
7656
|
process.stdout.write(
|
|
7596
|
-
`\r${
|
|
7657
|
+
`\r${chalk97.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
7597
7658
|
);
|
|
7598
7659
|
}).then((items) => {
|
|
7599
7660
|
process.stdout.write(
|
|
7600
|
-
`\r${
|
|
7661
|
+
`\r${chalk97.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
7601
7662
|
`
|
|
7602
7663
|
);
|
|
7603
7664
|
cachedItems = items;
|
|
@@ -7958,20 +8019,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
7958
8019
|
}
|
|
7959
8020
|
|
|
7960
8021
|
// src/commands/prs/listComments/printComments.ts
|
|
7961
|
-
import
|
|
8022
|
+
import chalk98 from "chalk";
|
|
7962
8023
|
function formatForHuman(comment3) {
|
|
7963
8024
|
if (comment3.type === "review") {
|
|
7964
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
8025
|
+
const stateColor = comment3.state === "APPROVED" ? chalk98.green : comment3.state === "CHANGES_REQUESTED" ? chalk98.red : chalk98.yellow;
|
|
7965
8026
|
return [
|
|
7966
|
-
`${
|
|
8027
|
+
`${chalk98.cyan("Review")} by ${chalk98.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
7967
8028
|
comment3.body,
|
|
7968
8029
|
""
|
|
7969
8030
|
].join("\n");
|
|
7970
8031
|
}
|
|
7971
8032
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
7972
8033
|
return [
|
|
7973
|
-
`${
|
|
7974
|
-
|
|
8034
|
+
`${chalk98.cyan("Line comment")} by ${chalk98.bold(comment3.user)} on ${chalk98.dim(`${comment3.path}${location}`)}`,
|
|
8035
|
+
chalk98.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
7975
8036
|
comment3.body,
|
|
7976
8037
|
""
|
|
7977
8038
|
].join("\n");
|
|
@@ -8061,13 +8122,13 @@ import { execSync as execSync33 } from "child_process";
|
|
|
8061
8122
|
import enquirer9 from "enquirer";
|
|
8062
8123
|
|
|
8063
8124
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
8064
|
-
import
|
|
8125
|
+
import chalk99 from "chalk";
|
|
8065
8126
|
var STATUS_MAP = {
|
|
8066
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
8067
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
8127
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk99.magenta("merged"), date: pr.mergedAt } : null,
|
|
8128
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk99.red("closed"), date: pr.closedAt } : null
|
|
8068
8129
|
};
|
|
8069
8130
|
function defaultStatus(pr) {
|
|
8070
|
-
return { label:
|
|
8131
|
+
return { label: chalk99.green("opened"), date: pr.createdAt };
|
|
8071
8132
|
}
|
|
8072
8133
|
function getStatus2(pr) {
|
|
8073
8134
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -8076,11 +8137,11 @@ function formatDate(dateStr) {
|
|
|
8076
8137
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
8077
8138
|
}
|
|
8078
8139
|
function formatPrHeader(pr, status2) {
|
|
8079
|
-
return `${
|
|
8140
|
+
return `${chalk99.cyan(`#${pr.number}`)} ${pr.title} ${chalk99.dim(`(${pr.author.login},`)} ${status2.label} ${chalk99.dim(`${formatDate(status2.date)})`)}`;
|
|
8080
8141
|
}
|
|
8081
8142
|
function logPrDetails(pr) {
|
|
8082
8143
|
console.log(
|
|
8083
|
-
|
|
8144
|
+
chalk99.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
8084
8145
|
);
|
|
8085
8146
|
console.log();
|
|
8086
8147
|
}
|
|
@@ -8246,10 +8307,10 @@ function registerPrs(program2) {
|
|
|
8246
8307
|
}
|
|
8247
8308
|
|
|
8248
8309
|
// src/commands/ravendb/ravendbAuth.ts
|
|
8249
|
-
import
|
|
8310
|
+
import chalk105 from "chalk";
|
|
8250
8311
|
|
|
8251
8312
|
// src/shared/createConnectionAuth.ts
|
|
8252
|
-
import
|
|
8313
|
+
import chalk100 from "chalk";
|
|
8253
8314
|
function listConnections(connections, format2) {
|
|
8254
8315
|
if (connections.length === 0) {
|
|
8255
8316
|
console.log("No connections configured.");
|
|
@@ -8262,7 +8323,7 @@ function listConnections(connections, format2) {
|
|
|
8262
8323
|
function removeConnection(connections, name, save) {
|
|
8263
8324
|
const filtered = connections.filter((c) => c.name !== name);
|
|
8264
8325
|
if (filtered.length === connections.length) {
|
|
8265
|
-
console.error(
|
|
8326
|
+
console.error(chalk100.red(`Connection "${name}" not found.`));
|
|
8266
8327
|
process.exit(1);
|
|
8267
8328
|
}
|
|
8268
8329
|
save(filtered);
|
|
@@ -8308,15 +8369,15 @@ function saveConnections(connections) {
|
|
|
8308
8369
|
}
|
|
8309
8370
|
|
|
8310
8371
|
// src/commands/ravendb/promptConnection.ts
|
|
8311
|
-
import
|
|
8372
|
+
import chalk103 from "chalk";
|
|
8312
8373
|
|
|
8313
8374
|
// src/commands/ravendb/selectOpSecret.ts
|
|
8314
|
-
import
|
|
8375
|
+
import chalk102 from "chalk";
|
|
8315
8376
|
import Enquirer2 from "enquirer";
|
|
8316
8377
|
|
|
8317
8378
|
// src/commands/ravendb/searchItems.ts
|
|
8318
8379
|
import { execSync as execSync35 } from "child_process";
|
|
8319
|
-
import
|
|
8380
|
+
import chalk101 from "chalk";
|
|
8320
8381
|
function opExec(args) {
|
|
8321
8382
|
return execSync35(`op ${args}`, {
|
|
8322
8383
|
encoding: "utf-8",
|
|
@@ -8329,7 +8390,7 @@ function searchItems(search2) {
|
|
|
8329
8390
|
items = JSON.parse(opExec("item list --format=json"));
|
|
8330
8391
|
} catch {
|
|
8331
8392
|
console.error(
|
|
8332
|
-
|
|
8393
|
+
chalk101.red(
|
|
8333
8394
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
8334
8395
|
)
|
|
8335
8396
|
);
|
|
@@ -8343,7 +8404,7 @@ function getItemFields(itemId) {
|
|
|
8343
8404
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
8344
8405
|
return item.fields.filter((f) => f.reference && f.label);
|
|
8345
8406
|
} catch {
|
|
8346
|
-
console.error(
|
|
8407
|
+
console.error(chalk101.red("Failed to get item details from 1Password."));
|
|
8347
8408
|
process.exit(1);
|
|
8348
8409
|
}
|
|
8349
8410
|
}
|
|
@@ -8362,7 +8423,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8362
8423
|
}).run();
|
|
8363
8424
|
const items = searchItems(search2);
|
|
8364
8425
|
if (items.length === 0) {
|
|
8365
|
-
console.error(
|
|
8426
|
+
console.error(chalk102.red(`No items found matching "${search2}".`));
|
|
8366
8427
|
process.exit(1);
|
|
8367
8428
|
}
|
|
8368
8429
|
const itemId = await selectOne(
|
|
@@ -8371,7 +8432,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8371
8432
|
);
|
|
8372
8433
|
const fields = getItemFields(itemId);
|
|
8373
8434
|
if (fields.length === 0) {
|
|
8374
|
-
console.error(
|
|
8435
|
+
console.error(chalk102.red("No fields with references found on this item."));
|
|
8375
8436
|
process.exit(1);
|
|
8376
8437
|
}
|
|
8377
8438
|
const ref = await selectOne(
|
|
@@ -8385,7 +8446,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8385
8446
|
async function promptConnection(existingNames) {
|
|
8386
8447
|
const name = await promptInput("name", "Connection name:");
|
|
8387
8448
|
if (existingNames.includes(name)) {
|
|
8388
|
-
console.error(
|
|
8449
|
+
console.error(chalk103.red(`Connection "${name}" already exists.`));
|
|
8389
8450
|
process.exit(1);
|
|
8390
8451
|
}
|
|
8391
8452
|
const url = await promptInput(
|
|
@@ -8394,22 +8455,22 @@ async function promptConnection(existingNames) {
|
|
|
8394
8455
|
);
|
|
8395
8456
|
const database = await promptInput("database", "Database name:");
|
|
8396
8457
|
if (!name || !url || !database) {
|
|
8397
|
-
console.error(
|
|
8458
|
+
console.error(chalk103.red("All fields are required."));
|
|
8398
8459
|
process.exit(1);
|
|
8399
8460
|
}
|
|
8400
8461
|
const apiKeyRef = await selectOpSecret();
|
|
8401
|
-
console.log(
|
|
8462
|
+
console.log(chalk103.dim(`Using: ${apiKeyRef}`));
|
|
8402
8463
|
return { name, url, database, apiKeyRef };
|
|
8403
8464
|
}
|
|
8404
8465
|
|
|
8405
8466
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
8406
|
-
import
|
|
8467
|
+
import chalk104 from "chalk";
|
|
8407
8468
|
function ravendbSetConnection(name) {
|
|
8408
8469
|
const raw = loadGlobalConfigRaw();
|
|
8409
8470
|
const ravendb = raw.ravendb ?? {};
|
|
8410
8471
|
const connections = ravendb.connections ?? [];
|
|
8411
8472
|
if (!connections.some((c) => c.name === name)) {
|
|
8412
|
-
console.error(
|
|
8473
|
+
console.error(chalk104.red(`Connection "${name}" not found.`));
|
|
8413
8474
|
console.error(
|
|
8414
8475
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
8415
8476
|
);
|
|
@@ -8425,16 +8486,16 @@ function ravendbSetConnection(name) {
|
|
|
8425
8486
|
var ravendbAuth = createConnectionAuth({
|
|
8426
8487
|
load: loadConnections,
|
|
8427
8488
|
save: saveConnections,
|
|
8428
|
-
format: (c) => `${
|
|
8489
|
+
format: (c) => `${chalk105.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
8429
8490
|
promptNew: promptConnection,
|
|
8430
8491
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
8431
8492
|
});
|
|
8432
8493
|
|
|
8433
8494
|
// src/commands/ravendb/ravendbCollections.ts
|
|
8434
|
-
import
|
|
8495
|
+
import chalk109 from "chalk";
|
|
8435
8496
|
|
|
8436
8497
|
// src/commands/ravendb/ravenFetch.ts
|
|
8437
|
-
import
|
|
8498
|
+
import chalk107 from "chalk";
|
|
8438
8499
|
|
|
8439
8500
|
// src/commands/ravendb/getAccessToken.ts
|
|
8440
8501
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -8471,10 +8532,10 @@ ${errorText}`
|
|
|
8471
8532
|
|
|
8472
8533
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
8473
8534
|
import { execSync as execSync36 } from "child_process";
|
|
8474
|
-
import
|
|
8535
|
+
import chalk106 from "chalk";
|
|
8475
8536
|
function resolveOpSecret(reference) {
|
|
8476
8537
|
if (!reference.startsWith("op://")) {
|
|
8477
|
-
console.error(
|
|
8538
|
+
console.error(chalk106.red(`Invalid secret reference: must start with op://`));
|
|
8478
8539
|
process.exit(1);
|
|
8479
8540
|
}
|
|
8480
8541
|
try {
|
|
@@ -8484,7 +8545,7 @@ function resolveOpSecret(reference) {
|
|
|
8484
8545
|
}).trim();
|
|
8485
8546
|
} catch {
|
|
8486
8547
|
console.error(
|
|
8487
|
-
|
|
8548
|
+
chalk106.red(
|
|
8488
8549
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
8489
8550
|
)
|
|
8490
8551
|
);
|
|
@@ -8511,7 +8572,7 @@ async function ravenFetch(connection, path50) {
|
|
|
8511
8572
|
if (!response.ok) {
|
|
8512
8573
|
const body = await response.text();
|
|
8513
8574
|
console.error(
|
|
8514
|
-
|
|
8575
|
+
chalk107.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
8515
8576
|
);
|
|
8516
8577
|
console.error(body.substring(0, 500));
|
|
8517
8578
|
process.exit(1);
|
|
@@ -8520,7 +8581,7 @@ async function ravenFetch(connection, path50) {
|
|
|
8520
8581
|
}
|
|
8521
8582
|
|
|
8522
8583
|
// src/commands/ravendb/resolveConnection.ts
|
|
8523
|
-
import
|
|
8584
|
+
import chalk108 from "chalk";
|
|
8524
8585
|
function loadRavendb() {
|
|
8525
8586
|
const raw = loadGlobalConfigRaw();
|
|
8526
8587
|
const ravendb = raw.ravendb;
|
|
@@ -8534,7 +8595,7 @@ function resolveConnection(name) {
|
|
|
8534
8595
|
const connectionName = name ?? defaultConnection;
|
|
8535
8596
|
if (!connectionName) {
|
|
8536
8597
|
console.error(
|
|
8537
|
-
|
|
8598
|
+
chalk108.red(
|
|
8538
8599
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
8539
8600
|
)
|
|
8540
8601
|
);
|
|
@@ -8542,7 +8603,7 @@ function resolveConnection(name) {
|
|
|
8542
8603
|
}
|
|
8543
8604
|
const connection = connections.find((c) => c.name === connectionName);
|
|
8544
8605
|
if (!connection) {
|
|
8545
|
-
console.error(
|
|
8606
|
+
console.error(chalk108.red(`Connection "${connectionName}" not found.`));
|
|
8546
8607
|
console.error(
|
|
8547
8608
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
8548
8609
|
);
|
|
@@ -8573,15 +8634,15 @@ async function ravendbCollections(connectionName) {
|
|
|
8573
8634
|
return;
|
|
8574
8635
|
}
|
|
8575
8636
|
for (const c of collections) {
|
|
8576
|
-
console.log(`${
|
|
8637
|
+
console.log(`${chalk109.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
8577
8638
|
}
|
|
8578
8639
|
}
|
|
8579
8640
|
|
|
8580
8641
|
// src/commands/ravendb/ravendbQuery.ts
|
|
8581
|
-
import
|
|
8642
|
+
import chalk111 from "chalk";
|
|
8582
8643
|
|
|
8583
8644
|
// src/commands/ravendb/fetchAllPages.ts
|
|
8584
|
-
import
|
|
8645
|
+
import chalk110 from "chalk";
|
|
8585
8646
|
|
|
8586
8647
|
// src/commands/ravendb/buildQueryPath.ts
|
|
8587
8648
|
function buildQueryPath(opts) {
|
|
@@ -8619,7 +8680,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8619
8680
|
allResults.push(...results);
|
|
8620
8681
|
start3 += results.length;
|
|
8621
8682
|
process.stderr.write(
|
|
8622
|
-
`\r${
|
|
8683
|
+
`\r${chalk110.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
8623
8684
|
);
|
|
8624
8685
|
if (start3 >= totalResults) break;
|
|
8625
8686
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -8634,7 +8695,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8634
8695
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
8635
8696
|
const resolved = resolveArgs(connectionName, collection);
|
|
8636
8697
|
if (!resolved.collection && !options2.query) {
|
|
8637
|
-
console.error(
|
|
8698
|
+
console.error(chalk111.red("Provide a collection name or --query filter."));
|
|
8638
8699
|
process.exit(1);
|
|
8639
8700
|
}
|
|
8640
8701
|
const { collection: col } = resolved;
|
|
@@ -8672,7 +8733,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
8672
8733
|
import * as path27 from "path";
|
|
8673
8734
|
|
|
8674
8735
|
// src/commands/refactor/logViolations.ts
|
|
8675
|
-
import
|
|
8736
|
+
import chalk112 from "chalk";
|
|
8676
8737
|
var DEFAULT_MAX_LINES = 100;
|
|
8677
8738
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
8678
8739
|
if (violations.length === 0) {
|
|
@@ -8681,43 +8742,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
8681
8742
|
}
|
|
8682
8743
|
return;
|
|
8683
8744
|
}
|
|
8684
|
-
console.error(
|
|
8745
|
+
console.error(chalk112.red(`
|
|
8685
8746
|
Refactor check failed:
|
|
8686
8747
|
`));
|
|
8687
|
-
console.error(
|
|
8748
|
+
console.error(chalk112.red(` The following files exceed ${maxLines} lines:
|
|
8688
8749
|
`));
|
|
8689
8750
|
for (const violation of violations) {
|
|
8690
|
-
console.error(
|
|
8751
|
+
console.error(chalk112.red(` ${violation.file} (${violation.lines} lines)`));
|
|
8691
8752
|
}
|
|
8692
8753
|
console.error(
|
|
8693
|
-
|
|
8754
|
+
chalk112.yellow(
|
|
8694
8755
|
`
|
|
8695
8756
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
8696
8757
|
way to refactor it, ignore it with:
|
|
8697
8758
|
`
|
|
8698
8759
|
)
|
|
8699
8760
|
);
|
|
8700
|
-
console.error(
|
|
8761
|
+
console.error(chalk112.gray(` assist refactor ignore <file>
|
|
8701
8762
|
`));
|
|
8702
8763
|
if (process.env.CLAUDECODE) {
|
|
8703
|
-
console.error(
|
|
8764
|
+
console.error(chalk112.cyan(`
|
|
8704
8765
|
## Extracting Code to New Files
|
|
8705
8766
|
`));
|
|
8706
8767
|
console.error(
|
|
8707
|
-
|
|
8768
|
+
chalk112.cyan(
|
|
8708
8769
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
8709
8770
|
`
|
|
8710
8771
|
)
|
|
8711
8772
|
);
|
|
8712
8773
|
console.error(
|
|
8713
|
-
|
|
8774
|
+
chalk112.cyan(
|
|
8714
8775
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
8715
8776
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
8716
8777
|
`
|
|
8717
8778
|
)
|
|
8718
8779
|
);
|
|
8719
8780
|
console.error(
|
|
8720
|
-
|
|
8781
|
+
chalk112.cyan(
|
|
8721
8782
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
8722
8783
|
domains, move it to a common/shared folder.
|
|
8723
8784
|
`
|
|
@@ -8873,7 +8934,7 @@ async function check(pattern2, options2) {
|
|
|
8873
8934
|
|
|
8874
8935
|
// src/commands/refactor/extract/index.ts
|
|
8875
8936
|
import path33 from "path";
|
|
8876
|
-
import
|
|
8937
|
+
import chalk115 from "chalk";
|
|
8877
8938
|
|
|
8878
8939
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
8879
8940
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -9420,23 +9481,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
9420
9481
|
|
|
9421
9482
|
// src/commands/refactor/extract/displayPlan.ts
|
|
9422
9483
|
import path31 from "path";
|
|
9423
|
-
import
|
|
9484
|
+
import chalk113 from "chalk";
|
|
9424
9485
|
function section(title) {
|
|
9425
9486
|
return `
|
|
9426
|
-
${
|
|
9487
|
+
${chalk113.cyan(title)}`;
|
|
9427
9488
|
}
|
|
9428
9489
|
function displayImporters(plan2, cwd) {
|
|
9429
9490
|
if (plan2.importersToUpdate.length === 0) return;
|
|
9430
9491
|
console.log(section("Update importers:"));
|
|
9431
9492
|
for (const imp of plan2.importersToUpdate) {
|
|
9432
9493
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
9433
|
-
console.log(` ${
|
|
9494
|
+
console.log(` ${chalk113.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
9434
9495
|
}
|
|
9435
9496
|
}
|
|
9436
9497
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
9437
|
-
console.log(
|
|
9498
|
+
console.log(chalk113.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
9438
9499
|
`));
|
|
9439
|
-
console.log(` ${
|
|
9500
|
+
console.log(` ${chalk113.cyan("Functions to move:")}`);
|
|
9440
9501
|
for (const name of plan2.extractedNames) {
|
|
9441
9502
|
console.log(` ${name}`);
|
|
9442
9503
|
}
|
|
@@ -9471,7 +9532,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
9471
9532
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
9472
9533
|
import fs17 from "fs";
|
|
9473
9534
|
import path32 from "path";
|
|
9474
|
-
import
|
|
9535
|
+
import chalk114 from "chalk";
|
|
9475
9536
|
import { Project as Project2 } from "ts-morph";
|
|
9476
9537
|
function findTsConfig(sourcePath) {
|
|
9477
9538
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -9502,7 +9563,7 @@ function loadProjectFile(file) {
|
|
|
9502
9563
|
});
|
|
9503
9564
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
9504
9565
|
if (!sourceFile) {
|
|
9505
|
-
console.log(
|
|
9566
|
+
console.log(chalk114.red(`File not found in project: ${file}`));
|
|
9506
9567
|
process.exit(1);
|
|
9507
9568
|
}
|
|
9508
9569
|
return { project, sourceFile };
|
|
@@ -9525,19 +9586,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
9525
9586
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
9526
9587
|
if (options2.apply) {
|
|
9527
9588
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
9528
|
-
console.log(
|
|
9589
|
+
console.log(chalk115.green("\nExtraction complete"));
|
|
9529
9590
|
} else {
|
|
9530
|
-
console.log(
|
|
9591
|
+
console.log(chalk115.dim("\nDry run. Use --apply to execute."));
|
|
9531
9592
|
}
|
|
9532
9593
|
}
|
|
9533
9594
|
|
|
9534
9595
|
// src/commands/refactor/ignore.ts
|
|
9535
9596
|
import fs18 from "fs";
|
|
9536
|
-
import
|
|
9597
|
+
import chalk116 from "chalk";
|
|
9537
9598
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
9538
9599
|
function ignore(file) {
|
|
9539
9600
|
if (!fs18.existsSync(file)) {
|
|
9540
|
-
console.error(
|
|
9601
|
+
console.error(chalk116.red(`Error: File does not exist: ${file}`));
|
|
9541
9602
|
process.exit(1);
|
|
9542
9603
|
}
|
|
9543
9604
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -9553,7 +9614,7 @@ function ignore(file) {
|
|
|
9553
9614
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
9554
9615
|
}
|
|
9555
9616
|
console.log(
|
|
9556
|
-
|
|
9617
|
+
chalk116.green(
|
|
9557
9618
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
9558
9619
|
)
|
|
9559
9620
|
);
|
|
@@ -9561,26 +9622,26 @@ function ignore(file) {
|
|
|
9561
9622
|
|
|
9562
9623
|
// src/commands/refactor/rename/index.ts
|
|
9563
9624
|
import path34 from "path";
|
|
9564
|
-
import
|
|
9625
|
+
import chalk117 from "chalk";
|
|
9565
9626
|
async function rename(source, destination, options2 = {}) {
|
|
9566
9627
|
const destPath = path34.resolve(destination);
|
|
9567
9628
|
const cwd = process.cwd();
|
|
9568
9629
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
9569
9630
|
const relDest = path34.relative(cwd, destPath);
|
|
9570
9631
|
const { project, sourceFile } = loadProjectFile(source);
|
|
9571
|
-
console.log(
|
|
9632
|
+
console.log(chalk117.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
9572
9633
|
if (options2.apply) {
|
|
9573
9634
|
sourceFile.move(destPath);
|
|
9574
9635
|
await project.save();
|
|
9575
|
-
console.log(
|
|
9636
|
+
console.log(chalk117.green("Done"));
|
|
9576
9637
|
} else {
|
|
9577
|
-
console.log(
|
|
9638
|
+
console.log(chalk117.dim("Dry run. Use --apply to execute."));
|
|
9578
9639
|
}
|
|
9579
9640
|
}
|
|
9580
9641
|
|
|
9581
9642
|
// src/commands/refactor/renameSymbol/index.ts
|
|
9582
9643
|
import path36 from "path";
|
|
9583
|
-
import
|
|
9644
|
+
import chalk118 from "chalk";
|
|
9584
9645
|
import { Project as Project3 } from "ts-morph";
|
|
9585
9646
|
|
|
9586
9647
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -9629,38 +9690,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
9629
9690
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
9630
9691
|
const sourceFile = project.getSourceFile(filePath);
|
|
9631
9692
|
if (!sourceFile) {
|
|
9632
|
-
console.log(
|
|
9693
|
+
console.log(chalk118.red(`File not found in project: ${file}`));
|
|
9633
9694
|
process.exit(1);
|
|
9634
9695
|
}
|
|
9635
9696
|
const symbol = findSymbol(sourceFile, oldName);
|
|
9636
9697
|
if (!symbol) {
|
|
9637
|
-
console.log(
|
|
9698
|
+
console.log(chalk118.red(`Symbol "${oldName}" not found in ${file}`));
|
|
9638
9699
|
process.exit(1);
|
|
9639
9700
|
}
|
|
9640
9701
|
const grouped = groupReferences(symbol, cwd);
|
|
9641
9702
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
9642
9703
|
console.log(
|
|
9643
|
-
|
|
9704
|
+
chalk118.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
9644
9705
|
`)
|
|
9645
9706
|
);
|
|
9646
9707
|
for (const [refFile, lines] of grouped) {
|
|
9647
9708
|
console.log(
|
|
9648
|
-
` ${
|
|
9709
|
+
` ${chalk118.dim(refFile)}: lines ${chalk118.cyan(lines.join(", "))}`
|
|
9649
9710
|
);
|
|
9650
9711
|
}
|
|
9651
9712
|
if (options2.apply) {
|
|
9652
9713
|
symbol.rename(newName);
|
|
9653
9714
|
await project.save();
|
|
9654
|
-
console.log(
|
|
9715
|
+
console.log(chalk118.green(`
|
|
9655
9716
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
9656
9717
|
} else {
|
|
9657
|
-
console.log(
|
|
9718
|
+
console.log(chalk118.dim("\nDry run. Use --apply to execute."));
|
|
9658
9719
|
}
|
|
9659
9720
|
}
|
|
9660
9721
|
|
|
9661
9722
|
// src/commands/refactor/restructure/index.ts
|
|
9662
9723
|
import path45 from "path";
|
|
9663
|
-
import
|
|
9724
|
+
import chalk121 from "chalk";
|
|
9664
9725
|
|
|
9665
9726
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
9666
9727
|
import path37 from "path";
|
|
@@ -9903,50 +9964,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
9903
9964
|
|
|
9904
9965
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
9905
9966
|
import path41 from "path";
|
|
9906
|
-
import
|
|
9967
|
+
import chalk119 from "chalk";
|
|
9907
9968
|
function relPath(filePath) {
|
|
9908
9969
|
return path41.relative(process.cwd(), filePath);
|
|
9909
9970
|
}
|
|
9910
9971
|
function displayMoves(plan2) {
|
|
9911
9972
|
if (plan2.moves.length === 0) return;
|
|
9912
|
-
console.log(
|
|
9973
|
+
console.log(chalk119.bold("\nFile moves:"));
|
|
9913
9974
|
for (const move of plan2.moves) {
|
|
9914
9975
|
console.log(
|
|
9915
|
-
` ${
|
|
9976
|
+
` ${chalk119.red(relPath(move.from))} \u2192 ${chalk119.green(relPath(move.to))}`
|
|
9916
9977
|
);
|
|
9917
|
-
console.log(
|
|
9978
|
+
console.log(chalk119.dim(` ${move.reason}`));
|
|
9918
9979
|
}
|
|
9919
9980
|
}
|
|
9920
9981
|
function displayRewrites(rewrites) {
|
|
9921
9982
|
if (rewrites.length === 0) return;
|
|
9922
9983
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
9923
|
-
console.log(
|
|
9984
|
+
console.log(chalk119.bold(`
|
|
9924
9985
|
Import rewrites (${affectedFiles.size} files):`));
|
|
9925
9986
|
for (const file of affectedFiles) {
|
|
9926
|
-
console.log(` ${
|
|
9987
|
+
console.log(` ${chalk119.cyan(relPath(file))}:`);
|
|
9927
9988
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
9928
9989
|
(r) => r.file === file
|
|
9929
9990
|
)) {
|
|
9930
9991
|
console.log(
|
|
9931
|
-
` ${
|
|
9992
|
+
` ${chalk119.red(`"${oldSpecifier}"`)} \u2192 ${chalk119.green(`"${newSpecifier}"`)}`
|
|
9932
9993
|
);
|
|
9933
9994
|
}
|
|
9934
9995
|
}
|
|
9935
9996
|
}
|
|
9936
9997
|
function displayPlan2(plan2) {
|
|
9937
9998
|
if (plan2.warnings.length > 0) {
|
|
9938
|
-
console.log(
|
|
9939
|
-
for (const w of plan2.warnings) console.log(
|
|
9999
|
+
console.log(chalk119.yellow("\nWarnings:"));
|
|
10000
|
+
for (const w of plan2.warnings) console.log(chalk119.yellow(` ${w}`));
|
|
9940
10001
|
}
|
|
9941
10002
|
if (plan2.newDirectories.length > 0) {
|
|
9942
|
-
console.log(
|
|
10003
|
+
console.log(chalk119.bold("\nNew directories:"));
|
|
9943
10004
|
for (const dir of plan2.newDirectories)
|
|
9944
|
-
console.log(
|
|
10005
|
+
console.log(chalk119.green(` ${dir}/`));
|
|
9945
10006
|
}
|
|
9946
10007
|
displayMoves(plan2);
|
|
9947
10008
|
displayRewrites(plan2.rewrites);
|
|
9948
10009
|
console.log(
|
|
9949
|
-
|
|
10010
|
+
chalk119.dim(
|
|
9950
10011
|
`
|
|
9951
10012
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
9952
10013
|
)
|
|
@@ -9956,18 +10017,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
9956
10017
|
// src/commands/refactor/restructure/executePlan.ts
|
|
9957
10018
|
import fs20 from "fs";
|
|
9958
10019
|
import path42 from "path";
|
|
9959
|
-
import
|
|
10020
|
+
import chalk120 from "chalk";
|
|
9960
10021
|
function executePlan(plan2) {
|
|
9961
10022
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
9962
10023
|
for (const [file, content] of updatedContents) {
|
|
9963
10024
|
fs20.writeFileSync(file, content, "utf-8");
|
|
9964
10025
|
console.log(
|
|
9965
|
-
|
|
10026
|
+
chalk120.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
9966
10027
|
);
|
|
9967
10028
|
}
|
|
9968
10029
|
for (const dir of plan2.newDirectories) {
|
|
9969
10030
|
fs20.mkdirSync(dir, { recursive: true });
|
|
9970
|
-
console.log(
|
|
10031
|
+
console.log(chalk120.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
9971
10032
|
}
|
|
9972
10033
|
for (const move of plan2.moves) {
|
|
9973
10034
|
const targetDir = path42.dirname(move.to);
|
|
@@ -9976,7 +10037,7 @@ function executePlan(plan2) {
|
|
|
9976
10037
|
}
|
|
9977
10038
|
fs20.renameSync(move.from, move.to);
|
|
9978
10039
|
console.log(
|
|
9979
|
-
|
|
10040
|
+
chalk120.white(
|
|
9980
10041
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
9981
10042
|
)
|
|
9982
10043
|
);
|
|
@@ -9991,7 +10052,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
9991
10052
|
if (entries.length === 0) {
|
|
9992
10053
|
fs20.rmdirSync(dir);
|
|
9993
10054
|
console.log(
|
|
9994
|
-
|
|
10055
|
+
chalk120.dim(
|
|
9995
10056
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
9996
10057
|
)
|
|
9997
10058
|
);
|
|
@@ -10124,22 +10185,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
10124
10185
|
const targetPattern = pattern2 ?? "src";
|
|
10125
10186
|
const files = findSourceFiles2(targetPattern);
|
|
10126
10187
|
if (files.length === 0) {
|
|
10127
|
-
console.log(
|
|
10188
|
+
console.log(chalk121.yellow("No files found matching pattern"));
|
|
10128
10189
|
return;
|
|
10129
10190
|
}
|
|
10130
10191
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
10131
10192
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
10132
10193
|
if (plan2.moves.length === 0) {
|
|
10133
|
-
console.log(
|
|
10194
|
+
console.log(chalk121.green("No restructuring needed"));
|
|
10134
10195
|
return;
|
|
10135
10196
|
}
|
|
10136
10197
|
displayPlan2(plan2);
|
|
10137
10198
|
if (options2.apply) {
|
|
10138
|
-
console.log(
|
|
10199
|
+
console.log(chalk121.bold("\nApplying changes..."));
|
|
10139
10200
|
executePlan(plan2);
|
|
10140
|
-
console.log(
|
|
10201
|
+
console.log(chalk121.green("\nRestructuring complete"));
|
|
10141
10202
|
} else {
|
|
10142
|
-
console.log(
|
|
10203
|
+
console.log(chalk121.dim("\nDry run. Use --apply to execute."));
|
|
10143
10204
|
}
|
|
10144
10205
|
}
|
|
10145
10206
|
|
|
@@ -10179,7 +10240,7 @@ function registerRefactor(program2) {
|
|
|
10179
10240
|
}
|
|
10180
10241
|
|
|
10181
10242
|
// src/commands/seq/seqAuth.ts
|
|
10182
|
-
import
|
|
10243
|
+
import chalk123 from "chalk";
|
|
10183
10244
|
|
|
10184
10245
|
// src/commands/seq/loadConnections.ts
|
|
10185
10246
|
function loadConnections2() {
|
|
@@ -10208,11 +10269,11 @@ function setDefaultConnection(name) {
|
|
|
10208
10269
|
}
|
|
10209
10270
|
|
|
10210
10271
|
// src/commands/seq/promptConnection.ts
|
|
10211
|
-
import
|
|
10272
|
+
import chalk122 from "chalk";
|
|
10212
10273
|
async function promptConnection2(existingNames) {
|
|
10213
10274
|
const name = await promptInput("name", "Connection name:", "default");
|
|
10214
10275
|
if (existingNames.includes(name)) {
|
|
10215
|
-
console.error(
|
|
10276
|
+
console.error(chalk122.red(`Connection "${name}" already exists.`));
|
|
10216
10277
|
process.exit(1);
|
|
10217
10278
|
}
|
|
10218
10279
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -10224,16 +10285,16 @@ async function promptConnection2(existingNames) {
|
|
|
10224
10285
|
var seqAuth = createConnectionAuth({
|
|
10225
10286
|
load: loadConnections2,
|
|
10226
10287
|
save: saveConnections2,
|
|
10227
|
-
format: (c) => `${
|
|
10288
|
+
format: (c) => `${chalk123.bold(c.name)} ${c.url}`,
|
|
10228
10289
|
promptNew: promptConnection2,
|
|
10229
10290
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
10230
10291
|
});
|
|
10231
10292
|
|
|
10232
10293
|
// src/commands/seq/seqQuery.ts
|
|
10233
|
-
import
|
|
10294
|
+
import chalk127 from "chalk";
|
|
10234
10295
|
|
|
10235
10296
|
// src/commands/seq/fetchSeq.ts
|
|
10236
|
-
import
|
|
10297
|
+
import chalk124 from "chalk";
|
|
10237
10298
|
async function fetchSeq(conn, path50, params) {
|
|
10238
10299
|
const url = `${conn.url}${path50}?${params}`;
|
|
10239
10300
|
const response = await fetch(url, {
|
|
@@ -10244,7 +10305,7 @@ async function fetchSeq(conn, path50, params) {
|
|
|
10244
10305
|
});
|
|
10245
10306
|
if (!response.ok) {
|
|
10246
10307
|
const body = await response.text();
|
|
10247
|
-
console.error(
|
|
10308
|
+
console.error(chalk124.red(`Seq returned ${response.status}: ${body}`));
|
|
10248
10309
|
process.exit(1);
|
|
10249
10310
|
}
|
|
10250
10311
|
return response;
|
|
@@ -10297,23 +10358,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
10297
10358
|
}
|
|
10298
10359
|
|
|
10299
10360
|
// src/commands/seq/formatEvent.ts
|
|
10300
|
-
import
|
|
10361
|
+
import chalk125 from "chalk";
|
|
10301
10362
|
function levelColor(level) {
|
|
10302
10363
|
switch (level) {
|
|
10303
10364
|
case "Fatal":
|
|
10304
|
-
return
|
|
10365
|
+
return chalk125.bgRed.white;
|
|
10305
10366
|
case "Error":
|
|
10306
|
-
return
|
|
10367
|
+
return chalk125.red;
|
|
10307
10368
|
case "Warning":
|
|
10308
|
-
return
|
|
10369
|
+
return chalk125.yellow;
|
|
10309
10370
|
case "Information":
|
|
10310
|
-
return
|
|
10371
|
+
return chalk125.cyan;
|
|
10311
10372
|
case "Debug":
|
|
10312
|
-
return
|
|
10373
|
+
return chalk125.gray;
|
|
10313
10374
|
case "Verbose":
|
|
10314
|
-
return
|
|
10375
|
+
return chalk125.dim;
|
|
10315
10376
|
default:
|
|
10316
|
-
return
|
|
10377
|
+
return chalk125.white;
|
|
10317
10378
|
}
|
|
10318
10379
|
}
|
|
10319
10380
|
function levelAbbrev(level) {
|
|
@@ -10354,31 +10415,31 @@ function formatTimestamp(iso) {
|
|
|
10354
10415
|
function formatEvent(event) {
|
|
10355
10416
|
const color = levelColor(event.Level);
|
|
10356
10417
|
const abbrev = levelAbbrev(event.Level);
|
|
10357
|
-
const ts8 =
|
|
10418
|
+
const ts8 = chalk125.dim(formatTimestamp(event.Timestamp));
|
|
10358
10419
|
const msg = renderMessage(event);
|
|
10359
10420
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
10360
10421
|
if (event.Exception) {
|
|
10361
10422
|
for (const line of event.Exception.split("\n")) {
|
|
10362
|
-
lines.push(
|
|
10423
|
+
lines.push(chalk125.red(` ${line}`));
|
|
10363
10424
|
}
|
|
10364
10425
|
}
|
|
10365
10426
|
return lines.join("\n");
|
|
10366
10427
|
}
|
|
10367
10428
|
|
|
10368
10429
|
// src/commands/seq/resolveConnection.ts
|
|
10369
|
-
import
|
|
10430
|
+
import chalk126 from "chalk";
|
|
10370
10431
|
function resolveConnection2(name) {
|
|
10371
10432
|
const connections = loadConnections2();
|
|
10372
10433
|
if (connections.length === 0) {
|
|
10373
10434
|
console.error(
|
|
10374
|
-
|
|
10435
|
+
chalk126.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
10375
10436
|
);
|
|
10376
10437
|
process.exit(1);
|
|
10377
10438
|
}
|
|
10378
10439
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
10379
10440
|
const connection = connections.find((c) => c.name === target);
|
|
10380
10441
|
if (!connection) {
|
|
10381
|
-
console.error(
|
|
10442
|
+
console.error(chalk126.red(`Seq connection "${target}" not found.`));
|
|
10382
10443
|
process.exit(1);
|
|
10383
10444
|
}
|
|
10384
10445
|
return connection;
|
|
@@ -10393,7 +10454,7 @@ async function seqQuery(filter, options2) {
|
|
|
10393
10454
|
new URLSearchParams({ filter, count: String(count) })
|
|
10394
10455
|
);
|
|
10395
10456
|
if (events.length === 0) {
|
|
10396
|
-
console.log(
|
|
10457
|
+
console.log(chalk127.yellow("No events found."));
|
|
10397
10458
|
return;
|
|
10398
10459
|
}
|
|
10399
10460
|
if (options2.json) {
|
|
@@ -10404,11 +10465,11 @@ async function seqQuery(filter, options2) {
|
|
|
10404
10465
|
for (const event of chronological) {
|
|
10405
10466
|
console.log(formatEvent(event));
|
|
10406
10467
|
}
|
|
10407
|
-
console.log(
|
|
10468
|
+
console.log(chalk127.dim(`
|
|
10408
10469
|
${events.length} events`));
|
|
10409
10470
|
if (events.length >= count) {
|
|
10410
10471
|
console.log(
|
|
10411
|
-
|
|
10472
|
+
chalk127.yellow(
|
|
10412
10473
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
10413
10474
|
)
|
|
10414
10475
|
);
|
|
@@ -10416,11 +10477,11 @@ ${events.length} events`));
|
|
|
10416
10477
|
}
|
|
10417
10478
|
|
|
10418
10479
|
// src/commands/seq/seqSetConnection.ts
|
|
10419
|
-
import
|
|
10480
|
+
import chalk128 from "chalk";
|
|
10420
10481
|
function seqSetConnection(name) {
|
|
10421
10482
|
const connections = loadConnections2();
|
|
10422
10483
|
if (!connections.find((c) => c.name === name)) {
|
|
10423
|
-
console.error(
|
|
10484
|
+
console.error(chalk128.red(`Connection "${name}" not found.`));
|
|
10424
10485
|
process.exit(1);
|
|
10425
10486
|
}
|
|
10426
10487
|
setDefaultConnection(name);
|
|
@@ -10959,14 +11020,14 @@ import {
|
|
|
10959
11020
|
import { dirname as dirname20, join as join35 } from "path";
|
|
10960
11021
|
|
|
10961
11022
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
10962
|
-
import
|
|
11023
|
+
import chalk129 from "chalk";
|
|
10963
11024
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
10964
11025
|
function validateStagedContent(filename, content) {
|
|
10965
11026
|
const firstLine = content.split("\n")[0];
|
|
10966
11027
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
10967
11028
|
if (!match) {
|
|
10968
11029
|
console.error(
|
|
10969
|
-
|
|
11030
|
+
chalk129.red(
|
|
10970
11031
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
10971
11032
|
)
|
|
10972
11033
|
);
|
|
@@ -10975,7 +11036,7 @@ function validateStagedContent(filename, content) {
|
|
|
10975
11036
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
10976
11037
|
if (!contentAfterLink) {
|
|
10977
11038
|
console.error(
|
|
10978
|
-
|
|
11039
|
+
chalk129.red(
|
|
10979
11040
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
10980
11041
|
)
|
|
10981
11042
|
);
|
|
@@ -11368,7 +11429,7 @@ function registerVoice(program2) {
|
|
|
11368
11429
|
|
|
11369
11430
|
// src/commands/roam/auth.ts
|
|
11370
11431
|
import { randomBytes } from "crypto";
|
|
11371
|
-
import
|
|
11432
|
+
import chalk130 from "chalk";
|
|
11372
11433
|
|
|
11373
11434
|
// src/lib/openBrowser.ts
|
|
11374
11435
|
import { execSync as execSync39 } from "child_process";
|
|
@@ -11543,13 +11604,13 @@ async function auth() {
|
|
|
11543
11604
|
saveGlobalConfig(config);
|
|
11544
11605
|
const state = randomBytes(16).toString("hex");
|
|
11545
11606
|
console.log(
|
|
11546
|
-
|
|
11607
|
+
chalk130.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
11547
11608
|
);
|
|
11548
|
-
console.log(
|
|
11549
|
-
console.log(
|
|
11550
|
-
console.log(
|
|
11609
|
+
console.log(chalk130.white("http://localhost:14523/callback\n"));
|
|
11610
|
+
console.log(chalk130.blue("Opening browser for authorization..."));
|
|
11611
|
+
console.log(chalk130.dim("Waiting for authorization callback..."));
|
|
11551
11612
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
11552
|
-
console.log(
|
|
11613
|
+
console.log(chalk130.dim("Exchanging code for tokens..."));
|
|
11553
11614
|
const tokens = await exchangeToken({
|
|
11554
11615
|
code,
|
|
11555
11616
|
clientId,
|
|
@@ -11565,7 +11626,7 @@ async function auth() {
|
|
|
11565
11626
|
};
|
|
11566
11627
|
saveGlobalConfig(config);
|
|
11567
11628
|
console.log(
|
|
11568
|
-
|
|
11629
|
+
chalk130.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
11569
11630
|
);
|
|
11570
11631
|
}
|
|
11571
11632
|
|
|
@@ -11810,7 +11871,7 @@ import { execSync as execSync41 } from "child_process";
|
|
|
11810
11871
|
import { existsSync as existsSync40, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync29 } from "fs";
|
|
11811
11872
|
import { tmpdir as tmpdir6 } from "os";
|
|
11812
11873
|
import { join as join44, resolve as resolve6 } from "path";
|
|
11813
|
-
import
|
|
11874
|
+
import chalk131 from "chalk";
|
|
11814
11875
|
|
|
11815
11876
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
11816
11877
|
var captureWindowPs1 = `
|
|
@@ -11961,22 +12022,22 @@ function screenshot(processName) {
|
|
|
11961
12022
|
const config = loadConfig();
|
|
11962
12023
|
const outputDir = resolve6(config.screenshot.outputDir);
|
|
11963
12024
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
11964
|
-
console.log(
|
|
12025
|
+
console.log(chalk131.gray(`Capturing window for process "${processName}" ...`));
|
|
11965
12026
|
try {
|
|
11966
12027
|
runPowerShellScript(processName, outputPath);
|
|
11967
|
-
console.log(
|
|
12028
|
+
console.log(chalk131.green(`Screenshot saved: ${outputPath}`));
|
|
11968
12029
|
} catch (error) {
|
|
11969
12030
|
const msg = error instanceof Error ? error.message : String(error);
|
|
11970
|
-
console.error(
|
|
12031
|
+
console.error(chalk131.red(`Failed to capture screenshot: ${msg}`));
|
|
11971
12032
|
process.exit(1);
|
|
11972
12033
|
}
|
|
11973
12034
|
}
|
|
11974
12035
|
|
|
11975
12036
|
// src/commands/statusLine.ts
|
|
11976
|
-
import
|
|
12037
|
+
import chalk133 from "chalk";
|
|
11977
12038
|
|
|
11978
12039
|
// src/commands/buildLimitsSegment.ts
|
|
11979
|
-
import
|
|
12040
|
+
import chalk132 from "chalk";
|
|
11980
12041
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
11981
12042
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
11982
12043
|
function formatTimeLeft(resetsAt) {
|
|
@@ -11999,10 +12060,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
11999
12060
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
12000
12061
|
const label2 = `${Math.round(pct)}%`;
|
|
12001
12062
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
12002
|
-
if (projected == null) return
|
|
12003
|
-
if (projected > 100) return
|
|
12004
|
-
if (projected > 75) return
|
|
12005
|
-
return
|
|
12063
|
+
if (projected == null) return chalk132.green(label2);
|
|
12064
|
+
if (projected > 100) return chalk132.red(label2);
|
|
12065
|
+
if (projected > 75) return chalk132.yellow(label2);
|
|
12066
|
+
return chalk132.green(label2);
|
|
12006
12067
|
}
|
|
12007
12068
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
12008
12069
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -12028,14 +12089,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
12028
12089
|
}
|
|
12029
12090
|
|
|
12030
12091
|
// src/commands/statusLine.ts
|
|
12031
|
-
|
|
12092
|
+
chalk133.level = 3;
|
|
12032
12093
|
function formatNumber(num) {
|
|
12033
12094
|
return num.toLocaleString("en-US");
|
|
12034
12095
|
}
|
|
12035
12096
|
function colorizePercent(pct) {
|
|
12036
12097
|
const label2 = `${Math.round(pct)}%`;
|
|
12037
|
-
if (pct > 80) return
|
|
12038
|
-
if (pct > 40) return
|
|
12098
|
+
if (pct > 80) return chalk133.red(label2);
|
|
12099
|
+
if (pct > 40) return chalk133.yellow(label2);
|
|
12039
12100
|
return label2;
|
|
12040
12101
|
}
|
|
12041
12102
|
async function statusLine() {
|
|
@@ -12058,7 +12119,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
12058
12119
|
// src/commands/sync/syncClaudeMd.ts
|
|
12059
12120
|
import * as fs23 from "fs";
|
|
12060
12121
|
import * as path46 from "path";
|
|
12061
|
-
import
|
|
12122
|
+
import chalk134 from "chalk";
|
|
12062
12123
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
12063
12124
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
12064
12125
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -12067,12 +12128,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
12067
12128
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
12068
12129
|
if (sourceContent !== targetContent) {
|
|
12069
12130
|
console.log(
|
|
12070
|
-
|
|
12131
|
+
chalk134.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
12071
12132
|
);
|
|
12072
12133
|
console.log();
|
|
12073
12134
|
printDiff(targetContent, sourceContent);
|
|
12074
12135
|
const confirm = options2?.yes || await promptConfirm(
|
|
12075
|
-
|
|
12136
|
+
chalk134.red("Overwrite existing CLAUDE.md?"),
|
|
12076
12137
|
false
|
|
12077
12138
|
);
|
|
12078
12139
|
if (!confirm) {
|
|
@@ -12088,7 +12149,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
12088
12149
|
// src/commands/sync/syncSettings.ts
|
|
12089
12150
|
import * as fs24 from "fs";
|
|
12090
12151
|
import * as path47 from "path";
|
|
12091
|
-
import
|
|
12152
|
+
import chalk135 from "chalk";
|
|
12092
12153
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
12093
12154
|
const source = path47.join(claudeDir, "settings.json");
|
|
12094
12155
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -12104,14 +12165,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
12104
12165
|
if (mergedContent !== normalizedTarget) {
|
|
12105
12166
|
if (!options2?.yes) {
|
|
12106
12167
|
console.log(
|
|
12107
|
-
|
|
12168
|
+
chalk135.yellow(
|
|
12108
12169
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
12109
12170
|
)
|
|
12110
12171
|
);
|
|
12111
12172
|
console.log();
|
|
12112
12173
|
printDiff(targetContent, mergedContent);
|
|
12113
12174
|
const confirm = await promptConfirm(
|
|
12114
|
-
|
|
12175
|
+
chalk135.red("Overwrite existing settings.json?"),
|
|
12115
12176
|
false
|
|
12116
12177
|
);
|
|
12117
12178
|
if (!confirm) {
|