@staff0rd/assist 0.164.1 → 0.165.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/README.md +2 -2
- package/assist.cli-reads +37 -0
- package/claude/commands/draft.md +3 -3
- package/claude/settings.json +0 -38
- package/dist/index.js +444 -414
- 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.165.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -3326,8 +3326,8 @@ function registerCommentCommands(cmd) {
|
|
|
3326
3326
|
}
|
|
3327
3327
|
|
|
3328
3328
|
// src/commands/backlog/add/index.ts
|
|
3329
|
-
import { existsSync as
|
|
3330
|
-
import
|
|
3329
|
+
import { existsSync as existsSync18 } from "fs";
|
|
3330
|
+
import chalk43 from "chalk";
|
|
3331
3331
|
|
|
3332
3332
|
// src/commands/backlog/commitBacklog.ts
|
|
3333
3333
|
import { execSync as execSync14 } from "child_process";
|
|
@@ -3343,19 +3343,58 @@ function commitBacklog(id, name) {
|
|
|
3343
3343
|
}
|
|
3344
3344
|
}
|
|
3345
3345
|
|
|
3346
|
-
// src/commands/backlog/
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3346
|
+
// src/commands/backlog/add/parseItemFile.ts
|
|
3347
|
+
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
|
|
3348
|
+
import chalk42 from "chalk";
|
|
3349
|
+
import { ZodError } from "zod";
|
|
3350
|
+
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3351
|
+
function readJsonFile(filePath) {
|
|
3352
|
+
if (!existsSync17(filePath)) {
|
|
3353
|
+
console.log(chalk42.red(`File not found: ${filePath}`));
|
|
3354
|
+
process.exitCode = 1;
|
|
3355
|
+
return void 0;
|
|
3356
|
+
}
|
|
3357
|
+
let raw;
|
|
3358
|
+
try {
|
|
3359
|
+
raw = readFileSync14(filePath, "utf-8");
|
|
3360
|
+
} catch {
|
|
3361
|
+
console.log(chalk42.red(`Failed to read file: ${filePath}`));
|
|
3362
|
+
process.exitCode = 1;
|
|
3363
|
+
return void 0;
|
|
3364
|
+
}
|
|
3365
|
+
try {
|
|
3366
|
+
return JSON.parse(raw);
|
|
3367
|
+
} catch {
|
|
3368
|
+
console.log(chalk42.red(`Invalid JSON in file: ${filePath}`));
|
|
3369
|
+
process.exitCode = 1;
|
|
3370
|
+
return void 0;
|
|
3371
|
+
}
|
|
3372
|
+
}
|
|
3373
|
+
function formatZodError(err) {
|
|
3374
|
+
if (err instanceof ZodError) {
|
|
3375
|
+
console.log(chalk42.red("Invalid backlog item schema:"));
|
|
3376
|
+
for (const issue of err.issues) {
|
|
3377
|
+
console.log(chalk42.red(` - ${issue.path.join(".")}: ${issue.message}`));
|
|
3378
|
+
}
|
|
3379
|
+
} else {
|
|
3380
|
+
console.log(chalk42.red("Invalid backlog item schema."));
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
function parseItemFile(filePath) {
|
|
3384
|
+
const parsed = readJsonFile(filePath);
|
|
3385
|
+
if (parsed === void 0) return void 0;
|
|
3386
|
+
try {
|
|
3387
|
+
return addItemSchema.parse(parsed);
|
|
3388
|
+
} catch (err) {
|
|
3389
|
+
formatZodError(err);
|
|
3390
|
+
process.exitCode = 1;
|
|
3391
|
+
return void 0;
|
|
3392
|
+
}
|
|
3354
3393
|
}
|
|
3355
3394
|
|
|
3356
3395
|
// src/commands/backlog/add/shared.ts
|
|
3357
3396
|
import { spawnSync } from "child_process";
|
|
3358
|
-
import { mkdtempSync, readFileSync as
|
|
3397
|
+
import { mkdtempSync, readFileSync as readFileSync15, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "fs";
|
|
3359
3398
|
import { tmpdir } from "os";
|
|
3360
3399
|
import { join as join12 } from "path";
|
|
3361
3400
|
import enquirer6 from "enquirer";
|
|
@@ -3405,7 +3444,7 @@ function openEditor() {
|
|
|
3405
3444
|
unlinkSync4(filePath);
|
|
3406
3445
|
return void 0;
|
|
3407
3446
|
}
|
|
3408
|
-
const content =
|
|
3447
|
+
const content = readFileSync15(filePath, "utf-8").trim();
|
|
3409
3448
|
unlinkSync4(filePath);
|
|
3410
3449
|
return content || void 0;
|
|
3411
3450
|
}
|
|
@@ -3424,24 +3463,15 @@ async function promptAcceptanceCriteria() {
|
|
|
3424
3463
|
}
|
|
3425
3464
|
|
|
3426
3465
|
// src/commands/backlog/add/index.ts
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
if (
|
|
3430
|
-
console.log(chalk42.red("--json requires piped input on stdin."));
|
|
3431
|
-
return;
|
|
3432
|
-
}
|
|
3433
|
-
const input = await readStdin2();
|
|
3434
|
-
const sanitised = input.replace(
|
|
3435
|
-
/"(?:[^"\\]|\\.)*"/g,
|
|
3436
|
-
(match) => match.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t")
|
|
3437
|
-
);
|
|
3438
|
-
const data = addItemSchema.parse(JSON.parse(sanitised));
|
|
3466
|
+
function addFromFile(filePath) {
|
|
3467
|
+
const data = parseItemFile(filePath);
|
|
3468
|
+
if (!data) return;
|
|
3439
3469
|
const items = loadBacklog();
|
|
3440
3470
|
const id = getNextId(items);
|
|
3441
3471
|
items.push({ ...data, id, status: "todo" });
|
|
3442
3472
|
saveBacklog(items);
|
|
3443
3473
|
commitBacklog(id, data.name);
|
|
3444
|
-
console.log(
|
|
3474
|
+
console.log(chalk43.green(`Added item #${id}: ${data.name}`));
|
|
3445
3475
|
}
|
|
3446
3476
|
async function addInteractive() {
|
|
3447
3477
|
const type = await promptType();
|
|
@@ -3460,49 +3490,49 @@ async function addInteractive() {
|
|
|
3460
3490
|
});
|
|
3461
3491
|
saveBacklog(items);
|
|
3462
3492
|
commitBacklog(id, name);
|
|
3463
|
-
console.log(
|
|
3493
|
+
console.log(chalk43.green(`Added item #${id}: ${name}`));
|
|
3464
3494
|
}
|
|
3465
3495
|
async function add(options2) {
|
|
3466
|
-
if (!
|
|
3496
|
+
if (!existsSync18(getBacklogPath())) {
|
|
3467
3497
|
console.log(
|
|
3468
|
-
|
|
3498
|
+
chalk43.yellow(
|
|
3469
3499
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3470
3500
|
)
|
|
3471
3501
|
);
|
|
3472
3502
|
return;
|
|
3473
3503
|
}
|
|
3474
|
-
if (options2.
|
|
3475
|
-
|
|
3504
|
+
if (options2.file) {
|
|
3505
|
+
addFromFile(options2.file);
|
|
3476
3506
|
} else {
|
|
3477
3507
|
await addInteractive();
|
|
3478
3508
|
}
|
|
3479
3509
|
}
|
|
3480
3510
|
|
|
3481
3511
|
// src/commands/backlog/init/index.ts
|
|
3482
|
-
import { existsSync as
|
|
3483
|
-
import
|
|
3512
|
+
import { existsSync as existsSync19 } from "fs";
|
|
3513
|
+
import chalk44 from "chalk";
|
|
3484
3514
|
async function init6() {
|
|
3485
3515
|
const backlogPath = getBacklogPath();
|
|
3486
|
-
if (
|
|
3487
|
-
console.log(
|
|
3516
|
+
if (existsSync19(backlogPath)) {
|
|
3517
|
+
console.log(chalk44.yellow("assist.backlog.yml already exists."));
|
|
3488
3518
|
return;
|
|
3489
3519
|
}
|
|
3490
3520
|
saveBacklog([]);
|
|
3491
|
-
console.log(
|
|
3521
|
+
console.log(chalk44.green("Created assist.backlog.yml"));
|
|
3492
3522
|
}
|
|
3493
3523
|
|
|
3494
3524
|
// src/commands/backlog/list/index.ts
|
|
3495
|
-
import { existsSync as
|
|
3496
|
-
import
|
|
3525
|
+
import { existsSync as existsSync20 } from "fs";
|
|
3526
|
+
import chalk45 from "chalk";
|
|
3497
3527
|
function filterItems(items, options2) {
|
|
3498
3528
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3499
3529
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
3500
3530
|
return items;
|
|
3501
3531
|
}
|
|
3502
3532
|
async function list2(options2) {
|
|
3503
|
-
if (!
|
|
3533
|
+
if (!existsSync20(getBacklogPath())) {
|
|
3504
3534
|
console.log(
|
|
3505
|
-
|
|
3535
|
+
chalk45.yellow(
|
|
3506
3536
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3507
3537
|
)
|
|
3508
3538
|
);
|
|
@@ -3510,12 +3540,12 @@ async function list2(options2) {
|
|
|
3510
3540
|
}
|
|
3511
3541
|
const items = filterItems(loadBacklog(), options2);
|
|
3512
3542
|
if (items.length === 0) {
|
|
3513
|
-
console.log(
|
|
3543
|
+
console.log(chalk45.dim("Backlog is empty."));
|
|
3514
3544
|
return;
|
|
3515
3545
|
}
|
|
3516
3546
|
for (const item of items) {
|
|
3517
3547
|
console.log(
|
|
3518
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3548
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk45.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
|
|
3519
3549
|
);
|
|
3520
3550
|
if (options2.verbose) {
|
|
3521
3551
|
printVerboseDetails(item);
|
|
@@ -3527,20 +3557,20 @@ async function list2(options2) {
|
|
|
3527
3557
|
function registerItemCommands(cmd) {
|
|
3528
3558
|
cmd.command("init").description("Create an empty assist.backlog.yml").action(init6);
|
|
3529
3559
|
cmd.command("list").alias("ls").description("List all backlog items").option("--status <type>", "Filter by status (todo, in-progress, done)").option("-a, --all", "Include done items").option("-v, --verbose", "Show all item details").action(list2);
|
|
3530
|
-
cmd.command("add").description("Add a new backlog item").option("--
|
|
3560
|
+
cmd.command("add").description("Add a new backlog item").option("--file <path>", "Read item as JSON from a file").action(add);
|
|
3531
3561
|
}
|
|
3532
3562
|
|
|
3533
3563
|
// src/commands/backlog/delete/index.ts
|
|
3534
|
-
import
|
|
3564
|
+
import chalk46 from "chalk";
|
|
3535
3565
|
async function del(id) {
|
|
3536
3566
|
const name = removeItem(id);
|
|
3537
3567
|
if (name) {
|
|
3538
|
-
console.log(
|
|
3568
|
+
console.log(chalk46.green(`Deleted item #${id}: ${name}`));
|
|
3539
3569
|
}
|
|
3540
3570
|
}
|
|
3541
3571
|
|
|
3542
3572
|
// src/commands/backlog/done/index.ts
|
|
3543
|
-
import
|
|
3573
|
+
import chalk47 from "chalk";
|
|
3544
3574
|
async function done(id, summary) {
|
|
3545
3575
|
const result = loadAndFindItem(id);
|
|
3546
3576
|
if (!result) return;
|
|
@@ -3550,15 +3580,15 @@ async function done(id, summary) {
|
|
|
3550
3580
|
addPhaseSummary(result.item, summary, phase);
|
|
3551
3581
|
}
|
|
3552
3582
|
saveBacklog(result.items);
|
|
3553
|
-
console.log(
|
|
3583
|
+
console.log(chalk47.green(`Completed item #${id}: ${result.item.name}`));
|
|
3554
3584
|
}
|
|
3555
3585
|
|
|
3556
3586
|
// src/commands/backlog/start/index.ts
|
|
3557
|
-
import
|
|
3587
|
+
import chalk48 from "chalk";
|
|
3558
3588
|
async function start(id) {
|
|
3559
3589
|
const name = setStatus(id, "in-progress");
|
|
3560
3590
|
if (name) {
|
|
3561
|
-
console.log(
|
|
3591
|
+
console.log(chalk48.green(`Started item #${id}: ${name}`));
|
|
3562
3592
|
}
|
|
3563
3593
|
}
|
|
3564
3594
|
|
|
@@ -3686,7 +3716,7 @@ function extractGraphqlQuery(args) {
|
|
|
3686
3716
|
}
|
|
3687
3717
|
|
|
3688
3718
|
// src/shared/loadCliReads.ts
|
|
3689
|
-
import { existsSync as
|
|
3719
|
+
import { existsSync as existsSync21, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
|
|
3690
3720
|
import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
3691
3721
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3692
3722
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
@@ -3698,11 +3728,11 @@ var cachedLines;
|
|
|
3698
3728
|
function getCliReadsLines() {
|
|
3699
3729
|
if (cachedLines) return cachedLines;
|
|
3700
3730
|
const path50 = getCliReadsPath();
|
|
3701
|
-
if (!
|
|
3731
|
+
if (!existsSync21(path50)) {
|
|
3702
3732
|
cachedLines = [];
|
|
3703
3733
|
return cachedLines;
|
|
3704
3734
|
}
|
|
3705
|
-
cachedLines =
|
|
3735
|
+
cachedLines = readFileSync16(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
3706
3736
|
return cachedLines;
|
|
3707
3737
|
}
|
|
3708
3738
|
function loadCliReads() {
|
|
@@ -3727,7 +3757,7 @@ function findCliRead(command) {
|
|
|
3727
3757
|
}
|
|
3728
3758
|
|
|
3729
3759
|
// src/shared/readSettingsPerms.ts
|
|
3730
|
-
import { existsSync as
|
|
3760
|
+
import { existsSync as existsSync22, readFileSync as readFileSync17 } from "fs";
|
|
3731
3761
|
import { homedir as homedir3 } from "os";
|
|
3732
3762
|
import { join as join13 } from "path";
|
|
3733
3763
|
function readSettingsPerms(key) {
|
|
@@ -3743,9 +3773,9 @@ function readSettingsPerms(key) {
|
|
|
3743
3773
|
return entries;
|
|
3744
3774
|
}
|
|
3745
3775
|
function readPermissionArray(filePath, key) {
|
|
3746
|
-
if (!
|
|
3776
|
+
if (!existsSync22(filePath)) return [];
|
|
3747
3777
|
try {
|
|
3748
|
-
const data = JSON.parse(
|
|
3778
|
+
const data = JSON.parse(readFileSync17(filePath, "utf-8"));
|
|
3749
3779
|
const arr = data?.permissions?.[key];
|
|
3750
3780
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
3751
3781
|
} catch {
|
|
@@ -3947,7 +3977,7 @@ async function cliHook() {
|
|
|
3947
3977
|
}
|
|
3948
3978
|
|
|
3949
3979
|
// src/commands/cliHook/cliHookCheck.ts
|
|
3950
|
-
function cliHookCheck(command) {
|
|
3980
|
+
function cliHookCheck(command, toolName = "Bash") {
|
|
3951
3981
|
const trimmed = command.trim();
|
|
3952
3982
|
const parts = splitCompound(trimmed);
|
|
3953
3983
|
if (!parts) {
|
|
@@ -3965,7 +3995,7 @@ function cliHookCheck(command) {
|
|
|
3965
3995
|
}
|
|
3966
3996
|
const reasons = [];
|
|
3967
3997
|
for (const part of parts) {
|
|
3968
|
-
const reason = isApprovedRead(part);
|
|
3998
|
+
const reason = isApprovedRead(part, toolName);
|
|
3969
3999
|
if (!reason) {
|
|
3970
4000
|
console.log(`not approved (unrecognised: ${part})`);
|
|
3971
4001
|
process.exitCode = 1;
|
|
@@ -3978,52 +4008,52 @@ ${reasons.join("\n")}`);
|
|
|
3978
4008
|
}
|
|
3979
4009
|
|
|
3980
4010
|
// src/commands/deny/denyAdd.ts
|
|
3981
|
-
import
|
|
4011
|
+
import chalk49 from "chalk";
|
|
3982
4012
|
function denyAdd(pattern2, message) {
|
|
3983
4013
|
const config = loadProjectConfig();
|
|
3984
4014
|
const deny = config.deny ?? [];
|
|
3985
4015
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
3986
|
-
console.log(
|
|
4016
|
+
console.log(chalk49.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
3987
4017
|
return;
|
|
3988
4018
|
}
|
|
3989
4019
|
deny.push({ pattern: pattern2, message });
|
|
3990
4020
|
config.deny = deny;
|
|
3991
4021
|
saveConfig(config);
|
|
3992
|
-
console.log(
|
|
4022
|
+
console.log(chalk49.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
3993
4023
|
}
|
|
3994
4024
|
|
|
3995
4025
|
// src/commands/deny/denyList.ts
|
|
3996
|
-
import
|
|
4026
|
+
import chalk50 from "chalk";
|
|
3997
4027
|
function denyList() {
|
|
3998
4028
|
const config = loadConfig();
|
|
3999
4029
|
const deny = config.deny;
|
|
4000
4030
|
if (!deny || deny.length === 0) {
|
|
4001
|
-
console.log(
|
|
4031
|
+
console.log(chalk50.dim("No deny rules configured."));
|
|
4002
4032
|
return;
|
|
4003
4033
|
}
|
|
4004
4034
|
for (const rule of deny) {
|
|
4005
|
-
console.log(`${
|
|
4035
|
+
console.log(`${chalk50.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
4006
4036
|
}
|
|
4007
4037
|
}
|
|
4008
4038
|
|
|
4009
4039
|
// src/commands/deny/denyRemove.ts
|
|
4010
|
-
import
|
|
4040
|
+
import chalk51 from "chalk";
|
|
4011
4041
|
function denyRemove(pattern2) {
|
|
4012
4042
|
const config = loadProjectConfig();
|
|
4013
4043
|
const deny = config.deny ?? [];
|
|
4014
4044
|
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
4015
4045
|
if (index === -1) {
|
|
4016
|
-
console.log(
|
|
4046
|
+
console.log(chalk51.yellow(`No deny rule found for: ${pattern2}`));
|
|
4017
4047
|
return;
|
|
4018
4048
|
}
|
|
4019
4049
|
deny.splice(index, 1);
|
|
4020
4050
|
config.deny = deny.length > 0 ? deny : void 0;
|
|
4021
4051
|
saveConfig(config);
|
|
4022
|
-
console.log(
|
|
4052
|
+
console.log(chalk51.green(`Removed deny rule: ${pattern2}`));
|
|
4023
4053
|
}
|
|
4024
4054
|
|
|
4025
4055
|
// src/commands/permitCliReads/index.ts
|
|
4026
|
-
import { existsSync as
|
|
4056
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync4, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
4027
4057
|
import { homedir as homedir4 } from "os";
|
|
4028
4058
|
import { join as join14 } from "path";
|
|
4029
4059
|
|
|
@@ -4069,11 +4099,11 @@ function assertCliExists(cli) {
|
|
|
4069
4099
|
}
|
|
4070
4100
|
|
|
4071
4101
|
// src/commands/permitCliReads/colorize.ts
|
|
4072
|
-
import
|
|
4102
|
+
import chalk52 from "chalk";
|
|
4073
4103
|
function colorize(plainOutput) {
|
|
4074
4104
|
return plainOutput.split("\n").map((line) => {
|
|
4075
|
-
if (line.startsWith(" R ")) return
|
|
4076
|
-
if (line.startsWith(" W ")) return
|
|
4105
|
+
if (line.startsWith(" R ")) return chalk52.green(line);
|
|
4106
|
+
if (line.startsWith(" W ")) return chalk52.red(line);
|
|
4077
4107
|
return line;
|
|
4078
4108
|
}).join("\n");
|
|
4079
4109
|
}
|
|
@@ -4331,8 +4361,8 @@ function logPath(cli) {
|
|
|
4331
4361
|
}
|
|
4332
4362
|
function readCache(cli) {
|
|
4333
4363
|
const path50 = logPath(cli);
|
|
4334
|
-
if (!
|
|
4335
|
-
return
|
|
4364
|
+
if (!existsSync23(path50)) return void 0;
|
|
4365
|
+
return readFileSync18(path50, "utf-8");
|
|
4336
4366
|
}
|
|
4337
4367
|
function writeCache(cli, output) {
|
|
4338
4368
|
const dir = join14(homedir4(), ".assist");
|
|
@@ -4375,8 +4405,8 @@ function registerCliHook(program2) {
|
|
|
4375
4405
|
const cmd = program2.command("cli-hook").description("PreToolUse hook for auto-approving read-only CLI commands").action(() => {
|
|
4376
4406
|
cliHook();
|
|
4377
4407
|
});
|
|
4378
|
-
cmd.command("check <command>").description("Check whether a command would be auto-approved").action((command) => {
|
|
4379
|
-
cliHookCheck(command);
|
|
4408
|
+
cmd.command("check <command>").description("Check whether a command would be auto-approved").option("--tool <tool>", "Tool name to check against", "Bash").action((command, options2) => {
|
|
4409
|
+
cliHookCheck(command, options2.tool);
|
|
4380
4410
|
});
|
|
4381
4411
|
cmd.command("add").description("Discover a CLI's commands and auto-permit read-only ones").argument(
|
|
4382
4412
|
"<cli...>",
|
|
@@ -4391,15 +4421,15 @@ function registerCliHook(program2) {
|
|
|
4391
4421
|
}
|
|
4392
4422
|
|
|
4393
4423
|
// src/commands/complexity/analyze.ts
|
|
4394
|
-
import
|
|
4424
|
+
import chalk58 from "chalk";
|
|
4395
4425
|
|
|
4396
4426
|
// src/commands/complexity/cyclomatic.ts
|
|
4397
|
-
import
|
|
4427
|
+
import chalk54 from "chalk";
|
|
4398
4428
|
|
|
4399
4429
|
// src/commands/complexity/shared/index.ts
|
|
4400
4430
|
import fs12 from "fs";
|
|
4401
4431
|
import path20 from "path";
|
|
4402
|
-
import
|
|
4432
|
+
import chalk53 from "chalk";
|
|
4403
4433
|
import ts5 from "typescript";
|
|
4404
4434
|
|
|
4405
4435
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4645,7 +4675,7 @@ function createSourceFromFile(filePath) {
|
|
|
4645
4675
|
function withSourceFiles(pattern2, callback) {
|
|
4646
4676
|
const files = findSourceFiles2(pattern2);
|
|
4647
4677
|
if (files.length === 0) {
|
|
4648
|
-
console.log(
|
|
4678
|
+
console.log(chalk53.yellow("No files found matching pattern"));
|
|
4649
4679
|
return void 0;
|
|
4650
4680
|
}
|
|
4651
4681
|
return callback(files);
|
|
@@ -4678,11 +4708,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4678
4708
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4679
4709
|
for (const { file, name, complexity } of results) {
|
|
4680
4710
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4681
|
-
const color = exceedsThreshold ?
|
|
4682
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4711
|
+
const color = exceedsThreshold ? chalk54.red : chalk54.white;
|
|
4712
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk54.cyan(complexity)}`);
|
|
4683
4713
|
}
|
|
4684
4714
|
console.log(
|
|
4685
|
-
|
|
4715
|
+
chalk54.dim(
|
|
4686
4716
|
`
|
|
4687
4717
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4688
4718
|
)
|
|
@@ -4694,7 +4724,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4694
4724
|
}
|
|
4695
4725
|
|
|
4696
4726
|
// src/commands/complexity/halstead.ts
|
|
4697
|
-
import
|
|
4727
|
+
import chalk55 from "chalk";
|
|
4698
4728
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4699
4729
|
withSourceFiles(pattern2, (files) => {
|
|
4700
4730
|
const results = [];
|
|
@@ -4709,13 +4739,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4709
4739
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4710
4740
|
for (const { file, name, metrics } of results) {
|
|
4711
4741
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4712
|
-
const color = exceedsThreshold ?
|
|
4742
|
+
const color = exceedsThreshold ? chalk55.red : chalk55.white;
|
|
4713
4743
|
console.log(
|
|
4714
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4744
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk55.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk55.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk55.magenta(metrics.effort.toFixed(1))}`
|
|
4715
4745
|
);
|
|
4716
4746
|
}
|
|
4717
4747
|
console.log(
|
|
4718
|
-
|
|
4748
|
+
chalk55.dim(
|
|
4719
4749
|
`
|
|
4720
4750
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4721
4751
|
)
|
|
@@ -4730,28 +4760,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4730
4760
|
import fs13 from "fs";
|
|
4731
4761
|
|
|
4732
4762
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4733
|
-
import
|
|
4763
|
+
import chalk56 from "chalk";
|
|
4734
4764
|
function displayMaintainabilityResults(results, threshold) {
|
|
4735
4765
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4736
4766
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4737
|
-
console.log(
|
|
4767
|
+
console.log(chalk56.green("All files pass maintainability threshold"));
|
|
4738
4768
|
} else {
|
|
4739
4769
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4740
|
-
const color = threshold !== void 0 ?
|
|
4770
|
+
const color = threshold !== void 0 ? chalk56.red : chalk56.white;
|
|
4741
4771
|
console.log(
|
|
4742
|
-
`${color(file)} \u2192 avg: ${
|
|
4772
|
+
`${color(file)} \u2192 avg: ${chalk56.cyan(avgMaintainability.toFixed(1))}, min: ${chalk56.yellow(minMaintainability.toFixed(1))}`
|
|
4743
4773
|
);
|
|
4744
4774
|
}
|
|
4745
4775
|
}
|
|
4746
|
-
console.log(
|
|
4776
|
+
console.log(chalk56.dim(`
|
|
4747
4777
|
Analyzed ${results.length} files`));
|
|
4748
4778
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4749
4779
|
console.error(
|
|
4750
|
-
|
|
4780
|
+
chalk56.red(
|
|
4751
4781
|
`
|
|
4752
4782
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4753
4783
|
|
|
4754
|
-
\u26A0\uFE0F ${
|
|
4784
|
+
\u26A0\uFE0F ${chalk56.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.`
|
|
4755
4785
|
)
|
|
4756
4786
|
);
|
|
4757
4787
|
process.exit(1);
|
|
@@ -4808,7 +4838,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4808
4838
|
|
|
4809
4839
|
// src/commands/complexity/sloc.ts
|
|
4810
4840
|
import fs14 from "fs";
|
|
4811
|
-
import
|
|
4841
|
+
import chalk57 from "chalk";
|
|
4812
4842
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4813
4843
|
withSourceFiles(pattern2, (files) => {
|
|
4814
4844
|
const results = [];
|
|
@@ -4824,12 +4854,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4824
4854
|
results.sort((a, b) => b.lines - a.lines);
|
|
4825
4855
|
for (const { file, lines } of results) {
|
|
4826
4856
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4827
|
-
const color = exceedsThreshold ?
|
|
4828
|
-
console.log(`${color(file)} \u2192 ${
|
|
4857
|
+
const color = exceedsThreshold ? chalk57.red : chalk57.white;
|
|
4858
|
+
console.log(`${color(file)} \u2192 ${chalk57.cyan(lines)} lines`);
|
|
4829
4859
|
}
|
|
4830
4860
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4831
4861
|
console.log(
|
|
4832
|
-
|
|
4862
|
+
chalk57.dim(`
|
|
4833
4863
|
Total: ${total} lines across ${files.length} files`)
|
|
4834
4864
|
);
|
|
4835
4865
|
if (hasViolation) {
|
|
@@ -4843,21 +4873,21 @@ async function analyze(pattern2) {
|
|
|
4843
4873
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4844
4874
|
const files = findSourceFiles2(searchPattern);
|
|
4845
4875
|
if (files.length === 0) {
|
|
4846
|
-
console.log(
|
|
4876
|
+
console.log(chalk58.yellow("No files found matching pattern"));
|
|
4847
4877
|
return;
|
|
4848
4878
|
}
|
|
4849
4879
|
if (files.length === 1) {
|
|
4850
4880
|
const file = files[0];
|
|
4851
|
-
console.log(
|
|
4881
|
+
console.log(chalk58.bold.underline("SLOC"));
|
|
4852
4882
|
await sloc(file);
|
|
4853
4883
|
console.log();
|
|
4854
|
-
console.log(
|
|
4884
|
+
console.log(chalk58.bold.underline("Cyclomatic Complexity"));
|
|
4855
4885
|
await cyclomatic(file);
|
|
4856
4886
|
console.log();
|
|
4857
|
-
console.log(
|
|
4887
|
+
console.log(chalk58.bold.underline("Halstead Metrics"));
|
|
4858
4888
|
await halstead(file);
|
|
4859
4889
|
console.log();
|
|
4860
|
-
console.log(
|
|
4890
|
+
console.log(chalk58.bold.underline("Maintainability Index"));
|
|
4861
4891
|
await maintainability(file);
|
|
4862
4892
|
return;
|
|
4863
4893
|
}
|
|
@@ -4884,8 +4914,8 @@ function registerComplexity(program2) {
|
|
|
4884
4914
|
}
|
|
4885
4915
|
|
|
4886
4916
|
// src/commands/deploy/redirect.ts
|
|
4887
|
-
import { existsSync as
|
|
4888
|
-
import
|
|
4917
|
+
import { existsSync as existsSync24, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "fs";
|
|
4918
|
+
import chalk59 from "chalk";
|
|
4889
4919
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4890
4920
|
if (!window.location.pathname.endsWith('/')) {
|
|
4891
4921
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4893,23 +4923,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4893
4923
|
</script>`;
|
|
4894
4924
|
function redirect() {
|
|
4895
4925
|
const indexPath = "index.html";
|
|
4896
|
-
if (!
|
|
4897
|
-
console.log(
|
|
4926
|
+
if (!existsSync24(indexPath)) {
|
|
4927
|
+
console.log(chalk59.yellow("No index.html found"));
|
|
4898
4928
|
return;
|
|
4899
4929
|
}
|
|
4900
|
-
const content =
|
|
4930
|
+
const content = readFileSync19(indexPath, "utf-8");
|
|
4901
4931
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4902
|
-
console.log(
|
|
4932
|
+
console.log(chalk59.dim("Trailing slash script already present"));
|
|
4903
4933
|
return;
|
|
4904
4934
|
}
|
|
4905
4935
|
const headCloseIndex = content.indexOf("</head>");
|
|
4906
4936
|
if (headCloseIndex === -1) {
|
|
4907
|
-
console.log(
|
|
4937
|
+
console.log(chalk59.red("Could not find </head> tag in index.html"));
|
|
4908
4938
|
return;
|
|
4909
4939
|
}
|
|
4910
4940
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4911
4941
|
writeFileSync17(indexPath, newContent);
|
|
4912
|
-
console.log(
|
|
4942
|
+
console.log(chalk59.green("Added trailing slash redirect to index.html"));
|
|
4913
4943
|
}
|
|
4914
4944
|
|
|
4915
4945
|
// src/commands/registerDeploy.ts
|
|
@@ -4936,10 +4966,10 @@ function loadBlogSkipDays(repoName) {
|
|
|
4936
4966
|
|
|
4937
4967
|
// src/commands/devlog/shared.ts
|
|
4938
4968
|
import { execSync as execSync17 } from "child_process";
|
|
4939
|
-
import
|
|
4969
|
+
import chalk60 from "chalk";
|
|
4940
4970
|
|
|
4941
4971
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4942
|
-
import { readdirSync, readFileSync as
|
|
4972
|
+
import { readdirSync, readFileSync as readFileSync20 } from "fs";
|
|
4943
4973
|
import { join as join16 } from "path";
|
|
4944
4974
|
var DEVLOG_DIR = join16(BLOG_REPO_ROOT, "src/content/devlog");
|
|
4945
4975
|
function extractFrontmatter(content) {
|
|
@@ -4969,7 +4999,7 @@ function readDevlogFiles(callback) {
|
|
|
4969
4999
|
try {
|
|
4970
5000
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
4971
5001
|
for (const file of files) {
|
|
4972
|
-
const content =
|
|
5002
|
+
const content = readFileSync20(join16(DEVLOG_DIR, file), "utf-8");
|
|
4973
5003
|
const parsed = parseFrontmatter(content, file);
|
|
4974
5004
|
if (parsed) callback(parsed);
|
|
4975
5005
|
}
|
|
@@ -5023,13 +5053,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
5023
5053
|
}
|
|
5024
5054
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
5025
5055
|
for (const commit2 of commits) {
|
|
5026
|
-
console.log(` ${
|
|
5056
|
+
console.log(` ${chalk60.yellow(commit2.hash)} ${commit2.message}`);
|
|
5027
5057
|
if (verbose) {
|
|
5028
5058
|
const visibleFiles = commit2.files.filter(
|
|
5029
5059
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
5030
5060
|
);
|
|
5031
5061
|
for (const file of visibleFiles) {
|
|
5032
|
-
console.log(` ${
|
|
5062
|
+
console.log(` ${chalk60.dim(file)}`);
|
|
5033
5063
|
}
|
|
5034
5064
|
}
|
|
5035
5065
|
}
|
|
@@ -5054,15 +5084,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
5054
5084
|
}
|
|
5055
5085
|
|
|
5056
5086
|
// src/commands/devlog/list/printDateHeader.ts
|
|
5057
|
-
import
|
|
5087
|
+
import chalk61 from "chalk";
|
|
5058
5088
|
function printDateHeader(date, isSkipped, entries) {
|
|
5059
5089
|
if (isSkipped) {
|
|
5060
|
-
console.log(`${
|
|
5090
|
+
console.log(`${chalk61.bold.blue(date)} ${chalk61.dim("skipped")}`);
|
|
5061
5091
|
} else if (entries && entries.length > 0) {
|
|
5062
|
-
const entryInfo = entries.map((e) => `${
|
|
5063
|
-
console.log(`${
|
|
5092
|
+
const entryInfo = entries.map((e) => `${chalk61.green(e.version)} ${e.title}`).join(" | ");
|
|
5093
|
+
console.log(`${chalk61.bold.blue(date)} ${entryInfo}`);
|
|
5064
5094
|
} else {
|
|
5065
|
-
console.log(`${
|
|
5095
|
+
console.log(`${chalk61.bold.blue(date)} ${chalk61.red("\u26A0 devlog missing")}`);
|
|
5066
5096
|
}
|
|
5067
5097
|
}
|
|
5068
5098
|
|
|
@@ -5165,24 +5195,24 @@ function bumpVersion(version2, type) {
|
|
|
5165
5195
|
|
|
5166
5196
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
5167
5197
|
import { execSync as execSync20 } from "child_process";
|
|
5168
|
-
import
|
|
5198
|
+
import chalk63 from "chalk";
|
|
5169
5199
|
|
|
5170
5200
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
5171
|
-
import
|
|
5201
|
+
import chalk62 from "chalk";
|
|
5172
5202
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
5173
5203
|
if (conventional && firstHash) {
|
|
5174
5204
|
const version2 = getVersionAtCommit(firstHash);
|
|
5175
5205
|
if (version2) {
|
|
5176
|
-
console.log(`${
|
|
5206
|
+
console.log(`${chalk62.bold("version:")} ${stripToMinor(version2)}`);
|
|
5177
5207
|
} else {
|
|
5178
|
-
console.log(`${
|
|
5208
|
+
console.log(`${chalk62.bold("version:")} ${chalk62.red("unknown")}`);
|
|
5179
5209
|
}
|
|
5180
5210
|
} else if (patchVersion && minorVersion) {
|
|
5181
5211
|
console.log(
|
|
5182
|
-
`${
|
|
5212
|
+
`${chalk62.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
5183
5213
|
);
|
|
5184
5214
|
} else {
|
|
5185
|
-
console.log(`${
|
|
5215
|
+
console.log(`${chalk62.bold("version:")} v0.1 (initial)`);
|
|
5186
5216
|
}
|
|
5187
5217
|
}
|
|
5188
5218
|
|
|
@@ -5229,16 +5259,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
5229
5259
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
5230
5260
|
}
|
|
5231
5261
|
function logName(repoName) {
|
|
5232
|
-
console.log(`${
|
|
5262
|
+
console.log(`${chalk63.bold("name:")} ${repoName}`);
|
|
5233
5263
|
}
|
|
5234
5264
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
5235
5265
|
logName(ctx.repoName);
|
|
5236
5266
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
5237
|
-
console.log(
|
|
5267
|
+
console.log(chalk63.bold.blue(targetDate));
|
|
5238
5268
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
5239
5269
|
}
|
|
5240
5270
|
function logNoCommits(lastInfo) {
|
|
5241
|
-
console.log(
|
|
5271
|
+
console.log(chalk63.dim(noCommitsMessage(!!lastInfo)));
|
|
5242
5272
|
}
|
|
5243
5273
|
|
|
5244
5274
|
// src/commands/devlog/next/index.ts
|
|
@@ -5279,11 +5309,11 @@ function next2(options2) {
|
|
|
5279
5309
|
import { execSync as execSync21 } from "child_process";
|
|
5280
5310
|
|
|
5281
5311
|
// src/commands/devlog/repos/printReposTable.ts
|
|
5282
|
-
import
|
|
5312
|
+
import chalk64 from "chalk";
|
|
5283
5313
|
function colorStatus(status2) {
|
|
5284
|
-
if (status2 === "missing") return
|
|
5285
|
-
if (status2 === "outdated") return
|
|
5286
|
-
return
|
|
5314
|
+
if (status2 === "missing") return chalk64.red(status2);
|
|
5315
|
+
if (status2 === "outdated") return chalk64.yellow(status2);
|
|
5316
|
+
return chalk64.green(status2);
|
|
5287
5317
|
}
|
|
5288
5318
|
function formatRow(row, nameWidth) {
|
|
5289
5319
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -5297,8 +5327,8 @@ function printReposTable(rows) {
|
|
|
5297
5327
|
"Last Devlog".padEnd(11),
|
|
5298
5328
|
"Status"
|
|
5299
5329
|
].join(" ");
|
|
5300
|
-
console.log(
|
|
5301
|
-
console.log(
|
|
5330
|
+
console.log(chalk64.dim(header));
|
|
5331
|
+
console.log(chalk64.dim("-".repeat(header.length)));
|
|
5302
5332
|
for (const row of rows) {
|
|
5303
5333
|
console.log(formatRow(row, nameWidth));
|
|
5304
5334
|
}
|
|
@@ -5356,14 +5386,14 @@ function repos(options2) {
|
|
|
5356
5386
|
// src/commands/devlog/skip.ts
|
|
5357
5387
|
import { writeFileSync as writeFileSync18 } from "fs";
|
|
5358
5388
|
import { join as join17 } from "path";
|
|
5359
|
-
import
|
|
5389
|
+
import chalk65 from "chalk";
|
|
5360
5390
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
5361
5391
|
function getBlogConfigPath() {
|
|
5362
5392
|
return join17(BLOG_REPO_ROOT, "assist.yml");
|
|
5363
5393
|
}
|
|
5364
5394
|
function skip(date) {
|
|
5365
5395
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5366
|
-
console.log(
|
|
5396
|
+
console.log(chalk65.red("Invalid date format. Use YYYY-MM-DD"));
|
|
5367
5397
|
process.exit(1);
|
|
5368
5398
|
}
|
|
5369
5399
|
const repoName = getRepoName();
|
|
@@ -5374,7 +5404,7 @@ function skip(date) {
|
|
|
5374
5404
|
const skipDays = skip2[repoName] ?? [];
|
|
5375
5405
|
if (skipDays.includes(date)) {
|
|
5376
5406
|
console.log(
|
|
5377
|
-
|
|
5407
|
+
chalk65.yellow(`${date} is already in skip list for ${repoName}`)
|
|
5378
5408
|
);
|
|
5379
5409
|
return;
|
|
5380
5410
|
}
|
|
@@ -5384,20 +5414,20 @@ function skip(date) {
|
|
|
5384
5414
|
devlog.skip = skip2;
|
|
5385
5415
|
config.devlog = devlog;
|
|
5386
5416
|
writeFileSync18(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
5387
|
-
console.log(
|
|
5417
|
+
console.log(chalk65.green(`Added ${date} to skip list for ${repoName}`));
|
|
5388
5418
|
}
|
|
5389
5419
|
|
|
5390
5420
|
// src/commands/devlog/version.ts
|
|
5391
|
-
import
|
|
5421
|
+
import chalk66 from "chalk";
|
|
5392
5422
|
function version() {
|
|
5393
5423
|
const config = loadConfig();
|
|
5394
5424
|
const name = getRepoName();
|
|
5395
5425
|
const lastInfo = getLastVersionInfo(name, config);
|
|
5396
5426
|
const lastVersion = lastInfo?.version ?? null;
|
|
5397
5427
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
5398
|
-
console.log(`${
|
|
5399
|
-
console.log(`${
|
|
5400
|
-
console.log(`${
|
|
5428
|
+
console.log(`${chalk66.bold("name:")} ${name}`);
|
|
5429
|
+
console.log(`${chalk66.bold("last:")} ${lastVersion ?? chalk66.dim("none")}`);
|
|
5430
|
+
console.log(`${chalk66.bold("next:")} ${nextVersion ?? chalk66.dim("none")}`);
|
|
5401
5431
|
}
|
|
5402
5432
|
|
|
5403
5433
|
// src/commands/registerDevlog.ts
|
|
@@ -5421,15 +5451,15 @@ function registerDevlog(program2) {
|
|
|
5421
5451
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5422
5452
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5423
5453
|
import { join as join18 } from "path";
|
|
5424
|
-
import
|
|
5454
|
+
import chalk67 from "chalk";
|
|
5425
5455
|
|
|
5426
5456
|
// src/shared/findRepoRoot.ts
|
|
5427
|
-
import { existsSync as
|
|
5457
|
+
import { existsSync as existsSync25 } from "fs";
|
|
5428
5458
|
import path21 from "path";
|
|
5429
5459
|
function findRepoRoot(dir) {
|
|
5430
5460
|
let current = dir;
|
|
5431
5461
|
while (current !== path21.dirname(current)) {
|
|
5432
|
-
if (
|
|
5462
|
+
if (existsSync25(path21.join(current, ".git"))) {
|
|
5433
5463
|
return current;
|
|
5434
5464
|
}
|
|
5435
5465
|
current = path21.dirname(current);
|
|
@@ -5484,22 +5514,22 @@ function checkBuildLocks(startDir) {
|
|
|
5484
5514
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5485
5515
|
if (locked) {
|
|
5486
5516
|
console.error(
|
|
5487
|
-
|
|
5517
|
+
chalk67.red("Build output locked (is VS debugging?): ") + locked
|
|
5488
5518
|
);
|
|
5489
5519
|
process.exit(1);
|
|
5490
5520
|
}
|
|
5491
5521
|
}
|
|
5492
5522
|
async function checkBuildLocksCommand() {
|
|
5493
5523
|
checkBuildLocks();
|
|
5494
|
-
console.log(
|
|
5524
|
+
console.log(chalk67.green("No build locks detected"));
|
|
5495
5525
|
}
|
|
5496
5526
|
|
|
5497
5527
|
// src/commands/dotnet/buildTree.ts
|
|
5498
|
-
import { readFileSync as
|
|
5528
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
5499
5529
|
import path22 from "path";
|
|
5500
5530
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
5501
5531
|
function getProjectRefs(csprojPath) {
|
|
5502
|
-
const content =
|
|
5532
|
+
const content = readFileSync21(csprojPath, "utf-8");
|
|
5503
5533
|
const refs = [];
|
|
5504
5534
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
5505
5535
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -5516,7 +5546,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
5516
5546
|
for (const ref of getProjectRefs(abs)) {
|
|
5517
5547
|
const childAbs = path22.resolve(dir, ref);
|
|
5518
5548
|
try {
|
|
5519
|
-
|
|
5549
|
+
readFileSync21(childAbs);
|
|
5520
5550
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
5521
5551
|
} catch {
|
|
5522
5552
|
node.children.push({
|
|
@@ -5541,7 +5571,7 @@ function collectAllDeps(node) {
|
|
|
5541
5571
|
}
|
|
5542
5572
|
|
|
5543
5573
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
5544
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
5574
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync22, statSync } from "fs";
|
|
5545
5575
|
import path23 from "path";
|
|
5546
5576
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
5547
5577
|
if (depth > maxDepth) return [];
|
|
@@ -5576,7 +5606,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
5576
5606
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
5577
5607
|
for (const sln of slnFiles) {
|
|
5578
5608
|
try {
|
|
5579
|
-
const content =
|
|
5609
|
+
const content = readFileSync22(sln, "utf-8");
|
|
5580
5610
|
if (pattern2.test(content)) {
|
|
5581
5611
|
matches.push(path23.relative(repoRoot, sln));
|
|
5582
5612
|
}
|
|
@@ -5590,30 +5620,30 @@ function escapeRegex(s) {
|
|
|
5590
5620
|
}
|
|
5591
5621
|
|
|
5592
5622
|
// src/commands/dotnet/printTree.ts
|
|
5593
|
-
import
|
|
5623
|
+
import chalk68 from "chalk";
|
|
5594
5624
|
function printNodes(nodes, prefix2) {
|
|
5595
5625
|
for (let i = 0; i < nodes.length; i++) {
|
|
5596
5626
|
const isLast = i === nodes.length - 1;
|
|
5597
5627
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5598
5628
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5599
5629
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5600
|
-
const label2 = isMissing ?
|
|
5630
|
+
const label2 = isMissing ? chalk68.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5601
5631
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5602
5632
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5603
5633
|
}
|
|
5604
5634
|
}
|
|
5605
5635
|
function printTree(tree, totalCount, solutions) {
|
|
5606
|
-
console.log(
|
|
5607
|
-
console.log(
|
|
5636
|
+
console.log(chalk68.bold("\nProject Dependency Tree"));
|
|
5637
|
+
console.log(chalk68.cyan(tree.relativePath));
|
|
5608
5638
|
printNodes(tree.children, "");
|
|
5609
|
-
console.log(
|
|
5639
|
+
console.log(chalk68.dim(`
|
|
5610
5640
|
${totalCount} projects total (including root)`));
|
|
5611
|
-
console.log(
|
|
5641
|
+
console.log(chalk68.bold("\nSolution Membership"));
|
|
5612
5642
|
if (solutions.length === 0) {
|
|
5613
|
-
console.log(
|
|
5643
|
+
console.log(chalk68.yellow(" Not found in any .sln"));
|
|
5614
5644
|
} else {
|
|
5615
5645
|
for (const sln of solutions) {
|
|
5616
|
-
console.log(` ${
|
|
5646
|
+
console.log(` ${chalk68.green(sln)}`);
|
|
5617
5647
|
}
|
|
5618
5648
|
}
|
|
5619
5649
|
console.log();
|
|
@@ -5640,18 +5670,18 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5640
5670
|
}
|
|
5641
5671
|
|
|
5642
5672
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5643
|
-
import { existsSync as
|
|
5673
|
+
import { existsSync as existsSync26 } from "fs";
|
|
5644
5674
|
import path24 from "path";
|
|
5645
|
-
import
|
|
5675
|
+
import chalk69 from "chalk";
|
|
5646
5676
|
function resolveCsproj(csprojPath) {
|
|
5647
5677
|
const resolved = path24.resolve(csprojPath);
|
|
5648
|
-
if (!
|
|
5649
|
-
console.error(
|
|
5678
|
+
if (!existsSync26(resolved)) {
|
|
5679
|
+
console.error(chalk69.red(`File not found: ${resolved}`));
|
|
5650
5680
|
process.exit(1);
|
|
5651
5681
|
}
|
|
5652
5682
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5653
5683
|
if (!repoRoot) {
|
|
5654
|
-
console.error(
|
|
5684
|
+
console.error(chalk69.red("Could not find git repository root"));
|
|
5655
5685
|
process.exit(1);
|
|
5656
5686
|
}
|
|
5657
5687
|
return { resolved, repoRoot };
|
|
@@ -5701,12 +5731,12 @@ function getChangedCsFiles(scope) {
|
|
|
5701
5731
|
}
|
|
5702
5732
|
|
|
5703
5733
|
// src/commands/dotnet/inSln.ts
|
|
5704
|
-
import
|
|
5734
|
+
import chalk70 from "chalk";
|
|
5705
5735
|
async function inSln(csprojPath) {
|
|
5706
5736
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5707
5737
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5708
5738
|
if (solutions.length === 0) {
|
|
5709
|
-
console.log(
|
|
5739
|
+
console.log(chalk70.yellow("Not found in any .sln file"));
|
|
5710
5740
|
process.exit(1);
|
|
5711
5741
|
}
|
|
5712
5742
|
for (const sln of solutions) {
|
|
@@ -5715,7 +5745,7 @@ async function inSln(csprojPath) {
|
|
|
5715
5745
|
}
|
|
5716
5746
|
|
|
5717
5747
|
// src/commands/dotnet/inspect.ts
|
|
5718
|
-
import
|
|
5748
|
+
import chalk76 from "chalk";
|
|
5719
5749
|
|
|
5720
5750
|
// src/shared/formatElapsed.ts
|
|
5721
5751
|
function formatElapsed(ms) {
|
|
@@ -5727,12 +5757,12 @@ function formatElapsed(ms) {
|
|
|
5727
5757
|
}
|
|
5728
5758
|
|
|
5729
5759
|
// src/commands/dotnet/displayIssues.ts
|
|
5730
|
-
import
|
|
5760
|
+
import chalk71 from "chalk";
|
|
5731
5761
|
var SEVERITY_COLOR = {
|
|
5732
|
-
ERROR:
|
|
5733
|
-
WARNING:
|
|
5734
|
-
SUGGESTION:
|
|
5735
|
-
HINT:
|
|
5762
|
+
ERROR: chalk71.red,
|
|
5763
|
+
WARNING: chalk71.yellow,
|
|
5764
|
+
SUGGESTION: chalk71.cyan,
|
|
5765
|
+
HINT: chalk71.dim
|
|
5736
5766
|
};
|
|
5737
5767
|
function groupByFile(issues) {
|
|
5738
5768
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5748,15 +5778,15 @@ function groupByFile(issues) {
|
|
|
5748
5778
|
}
|
|
5749
5779
|
function displayIssues(issues) {
|
|
5750
5780
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5751
|
-
console.log(
|
|
5781
|
+
console.log(chalk71.bold(file));
|
|
5752
5782
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5753
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5783
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk71.white;
|
|
5754
5784
|
console.log(
|
|
5755
|
-
` ${
|
|
5785
|
+
` ${chalk71.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5756
5786
|
);
|
|
5757
5787
|
}
|
|
5758
5788
|
}
|
|
5759
|
-
console.log(
|
|
5789
|
+
console.log(chalk71.dim(`
|
|
5760
5790
|
${issues.length} issue(s) found`));
|
|
5761
5791
|
}
|
|
5762
5792
|
|
|
@@ -5813,14 +5843,14 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5813
5843
|
}
|
|
5814
5844
|
|
|
5815
5845
|
// src/commands/dotnet/resolveSolution.ts
|
|
5816
|
-
import { existsSync as
|
|
5846
|
+
import { existsSync as existsSync27 } from "fs";
|
|
5817
5847
|
import path25 from "path";
|
|
5818
|
-
import
|
|
5848
|
+
import chalk73 from "chalk";
|
|
5819
5849
|
|
|
5820
5850
|
// src/commands/dotnet/findSolution.ts
|
|
5821
5851
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5822
5852
|
import { dirname as dirname16, join as join19 } from "path";
|
|
5823
|
-
import
|
|
5853
|
+
import chalk72 from "chalk";
|
|
5824
5854
|
function findSlnInDir(dir) {
|
|
5825
5855
|
try {
|
|
5826
5856
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join19(dir, f));
|
|
@@ -5836,17 +5866,17 @@ function findSolution() {
|
|
|
5836
5866
|
const slnFiles = findSlnInDir(current);
|
|
5837
5867
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5838
5868
|
if (slnFiles.length > 1) {
|
|
5839
|
-
console.error(
|
|
5869
|
+
console.error(chalk72.red(`Multiple .sln files found in ${current}:`));
|
|
5840
5870
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5841
5871
|
console.error(
|
|
5842
|
-
|
|
5872
|
+
chalk72.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5843
5873
|
);
|
|
5844
5874
|
process.exit(1);
|
|
5845
5875
|
}
|
|
5846
5876
|
if (current === ceiling) break;
|
|
5847
5877
|
current = dirname16(current);
|
|
5848
5878
|
}
|
|
5849
|
-
console.error(
|
|
5879
|
+
console.error(chalk72.red("No .sln file found between cwd and repo root"));
|
|
5850
5880
|
process.exit(1);
|
|
5851
5881
|
}
|
|
5852
5882
|
|
|
@@ -5854,8 +5884,8 @@ function findSolution() {
|
|
|
5854
5884
|
function resolveSolution(sln) {
|
|
5855
5885
|
if (sln) {
|
|
5856
5886
|
const resolved = path25.resolve(sln);
|
|
5857
|
-
if (!
|
|
5858
|
-
console.error(
|
|
5887
|
+
if (!existsSync27(resolved)) {
|
|
5888
|
+
console.error(chalk73.red(`Solution file not found: ${resolved}`));
|
|
5859
5889
|
process.exit(1);
|
|
5860
5890
|
}
|
|
5861
5891
|
return resolved;
|
|
@@ -5894,17 +5924,17 @@ function parseInspectReport(json) {
|
|
|
5894
5924
|
|
|
5895
5925
|
// src/commands/dotnet/runInspectCode.ts
|
|
5896
5926
|
import { execSync as execSync23 } from "child_process";
|
|
5897
|
-
import { existsSync as
|
|
5927
|
+
import { existsSync as existsSync28, readFileSync as readFileSync23, unlinkSync as unlinkSync5 } from "fs";
|
|
5898
5928
|
import { tmpdir as tmpdir2 } from "os";
|
|
5899
5929
|
import path26 from "path";
|
|
5900
|
-
import
|
|
5930
|
+
import chalk74 from "chalk";
|
|
5901
5931
|
function assertJbInstalled() {
|
|
5902
5932
|
try {
|
|
5903
5933
|
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5904
5934
|
} catch {
|
|
5905
|
-
console.error(
|
|
5935
|
+
console.error(chalk74.red("jb is not installed. Install with:"));
|
|
5906
5936
|
console.error(
|
|
5907
|
-
|
|
5937
|
+
chalk74.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5908
5938
|
);
|
|
5909
5939
|
process.exit(1);
|
|
5910
5940
|
}
|
|
@@ -5922,21 +5952,21 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5922
5952
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5923
5953
|
process.stderr.write(err.stderr);
|
|
5924
5954
|
}
|
|
5925
|
-
console.error(
|
|
5955
|
+
console.error(chalk74.red("jb inspectcode failed"));
|
|
5926
5956
|
process.exit(1);
|
|
5927
5957
|
}
|
|
5928
|
-
if (!
|
|
5929
|
-
console.error(
|
|
5958
|
+
if (!existsSync28(reportPath)) {
|
|
5959
|
+
console.error(chalk74.red("Report file not generated"));
|
|
5930
5960
|
process.exit(1);
|
|
5931
5961
|
}
|
|
5932
|
-
const xml =
|
|
5962
|
+
const xml = readFileSync23(reportPath, "utf-8");
|
|
5933
5963
|
unlinkSync5(reportPath);
|
|
5934
5964
|
return xml;
|
|
5935
5965
|
}
|
|
5936
5966
|
|
|
5937
5967
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5938
5968
|
import { execSync as execSync24 } from "child_process";
|
|
5939
|
-
import
|
|
5969
|
+
import chalk75 from "chalk";
|
|
5940
5970
|
function resolveMsbuildPath() {
|
|
5941
5971
|
const config = loadConfig();
|
|
5942
5972
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5947,9 +5977,9 @@ function assertMsbuildInstalled() {
|
|
|
5947
5977
|
try {
|
|
5948
5978
|
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5949
5979
|
} catch {
|
|
5950
|
-
console.error(
|
|
5980
|
+
console.error(chalk75.red(`msbuild not found at: ${msbuild}`));
|
|
5951
5981
|
console.error(
|
|
5952
|
-
|
|
5982
|
+
chalk75.yellow(
|
|
5953
5983
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5954
5984
|
)
|
|
5955
5985
|
);
|
|
@@ -5996,17 +6026,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5996
6026
|
// src/commands/dotnet/inspect.ts
|
|
5997
6027
|
function logScope(changedFiles) {
|
|
5998
6028
|
if (changedFiles === null) {
|
|
5999
|
-
console.log(
|
|
6029
|
+
console.log(chalk76.dim("Inspecting full solution..."));
|
|
6000
6030
|
} else {
|
|
6001
6031
|
console.log(
|
|
6002
|
-
|
|
6032
|
+
chalk76.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
6003
6033
|
);
|
|
6004
6034
|
}
|
|
6005
6035
|
}
|
|
6006
6036
|
function reportResults(issues, elapsed) {
|
|
6007
6037
|
if (issues.length > 0) displayIssues(issues);
|
|
6008
|
-
else console.log(
|
|
6009
|
-
console.log(
|
|
6038
|
+
else console.log(chalk76.green("No issues found"));
|
|
6039
|
+
console.log(chalk76.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
6010
6040
|
if (issues.length > 0) process.exit(1);
|
|
6011
6041
|
}
|
|
6012
6042
|
async function inspect(sln, options2) {
|
|
@@ -6017,7 +6047,7 @@ async function inspect(sln, options2) {
|
|
|
6017
6047
|
const scope = parseScope(options2.scope);
|
|
6018
6048
|
const changedFiles = getChangedCsFiles(scope);
|
|
6019
6049
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
6020
|
-
console.log(
|
|
6050
|
+
console.log(chalk76.green("No changed .cs files found"));
|
|
6021
6051
|
return;
|
|
6022
6052
|
}
|
|
6023
6053
|
logScope(changedFiles);
|
|
@@ -6043,7 +6073,7 @@ function registerDotnet(program2) {
|
|
|
6043
6073
|
}
|
|
6044
6074
|
|
|
6045
6075
|
// src/commands/jira/acceptanceCriteria.ts
|
|
6046
|
-
import
|
|
6076
|
+
import chalk78 from "chalk";
|
|
6047
6077
|
|
|
6048
6078
|
// src/commands/jira/adfToText.ts
|
|
6049
6079
|
function renderInline(node) {
|
|
@@ -6104,7 +6134,7 @@ function adfToText(doc) {
|
|
|
6104
6134
|
|
|
6105
6135
|
// src/commands/jira/fetchIssue.ts
|
|
6106
6136
|
import { execSync as execSync25 } from "child_process";
|
|
6107
|
-
import
|
|
6137
|
+
import chalk77 from "chalk";
|
|
6108
6138
|
function fetchIssue(issueKey, fields) {
|
|
6109
6139
|
let result;
|
|
6110
6140
|
try {
|
|
@@ -6117,15 +6147,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
6117
6147
|
const stderr = error.stderr;
|
|
6118
6148
|
if (stderr.includes("unauthorized")) {
|
|
6119
6149
|
console.error(
|
|
6120
|
-
|
|
6150
|
+
chalk77.red("Jira authentication expired."),
|
|
6121
6151
|
"Run",
|
|
6122
|
-
|
|
6152
|
+
chalk77.cyan("assist jira auth"),
|
|
6123
6153
|
"to re-authenticate."
|
|
6124
6154
|
);
|
|
6125
6155
|
process.exit(1);
|
|
6126
6156
|
}
|
|
6127
6157
|
}
|
|
6128
|
-
console.error(
|
|
6158
|
+
console.error(chalk77.red(`Failed to fetch ${issueKey}.`));
|
|
6129
6159
|
process.exit(1);
|
|
6130
6160
|
}
|
|
6131
6161
|
return JSON.parse(result);
|
|
@@ -6139,7 +6169,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
6139
6169
|
const parsed = fetchIssue(issueKey, field);
|
|
6140
6170
|
const acValue = parsed?.fields?.[field];
|
|
6141
6171
|
if (!acValue) {
|
|
6142
|
-
console.log(
|
|
6172
|
+
console.log(chalk78.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
6143
6173
|
return;
|
|
6144
6174
|
}
|
|
6145
6175
|
if (typeof acValue === "string") {
|
|
@@ -6157,7 +6187,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
6157
6187
|
import { execSync as execSync26 } from "child_process";
|
|
6158
6188
|
|
|
6159
6189
|
// src/shared/loadJson.ts
|
|
6160
|
-
import { existsSync as
|
|
6190
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync5, readFileSync as readFileSync24, writeFileSync as writeFileSync19 } from "fs";
|
|
6161
6191
|
import { homedir as homedir6 } from "os";
|
|
6162
6192
|
import { join as join20 } from "path";
|
|
6163
6193
|
function getStoreDir() {
|
|
@@ -6168,9 +6198,9 @@ function getStorePath(filename) {
|
|
|
6168
6198
|
}
|
|
6169
6199
|
function loadJson(filename) {
|
|
6170
6200
|
const path50 = getStorePath(filename);
|
|
6171
|
-
if (
|
|
6201
|
+
if (existsSync29(path50)) {
|
|
6172
6202
|
try {
|
|
6173
|
-
return JSON.parse(
|
|
6203
|
+
return JSON.parse(readFileSync24(path50, "utf-8"));
|
|
6174
6204
|
} catch {
|
|
6175
6205
|
return {};
|
|
6176
6206
|
}
|
|
@@ -6179,7 +6209,7 @@ function loadJson(filename) {
|
|
|
6179
6209
|
}
|
|
6180
6210
|
function saveJson(filename, data) {
|
|
6181
6211
|
const dir = getStoreDir();
|
|
6182
|
-
if (!
|
|
6212
|
+
if (!existsSync29(dir)) {
|
|
6183
6213
|
mkdirSync5(dir, { recursive: true });
|
|
6184
6214
|
}
|
|
6185
6215
|
writeFileSync19(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
@@ -6234,14 +6264,14 @@ async function jiraAuth() {
|
|
|
6234
6264
|
}
|
|
6235
6265
|
|
|
6236
6266
|
// src/commands/jira/viewIssue.ts
|
|
6237
|
-
import
|
|
6267
|
+
import chalk79 from "chalk";
|
|
6238
6268
|
function viewIssue(issueKey) {
|
|
6239
6269
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
6240
6270
|
const fields = parsed?.fields;
|
|
6241
6271
|
const summary = fields?.summary;
|
|
6242
6272
|
const description = fields?.description;
|
|
6243
6273
|
if (summary) {
|
|
6244
|
-
console.log(
|
|
6274
|
+
console.log(chalk79.bold(summary));
|
|
6245
6275
|
}
|
|
6246
6276
|
if (description) {
|
|
6247
6277
|
if (summary) console.log();
|
|
@@ -6255,7 +6285,7 @@ function viewIssue(issueKey) {
|
|
|
6255
6285
|
}
|
|
6256
6286
|
if (!summary && !description) {
|
|
6257
6287
|
console.log(
|
|
6258
|
-
|
|
6288
|
+
chalk79.yellow(`No summary or description found on ${issueKey}.`)
|
|
6259
6289
|
);
|
|
6260
6290
|
}
|
|
6261
6291
|
}
|
|
@@ -6269,7 +6299,7 @@ function registerJira(program2) {
|
|
|
6269
6299
|
}
|
|
6270
6300
|
|
|
6271
6301
|
// src/commands/news/add/index.ts
|
|
6272
|
-
import
|
|
6302
|
+
import chalk80 from "chalk";
|
|
6273
6303
|
import enquirer7 from "enquirer";
|
|
6274
6304
|
async function add2(url) {
|
|
6275
6305
|
if (!url) {
|
|
@@ -6292,17 +6322,17 @@ async function add2(url) {
|
|
|
6292
6322
|
const news = config.news ?? {};
|
|
6293
6323
|
const feeds = news.feeds ?? [];
|
|
6294
6324
|
if (feeds.includes(url)) {
|
|
6295
|
-
console.log(
|
|
6325
|
+
console.log(chalk80.yellow("Feed already exists in config"));
|
|
6296
6326
|
return;
|
|
6297
6327
|
}
|
|
6298
6328
|
feeds.push(url);
|
|
6299
6329
|
config.news = { ...news, feeds };
|
|
6300
6330
|
saveGlobalConfig(config);
|
|
6301
|
-
console.log(
|
|
6331
|
+
console.log(chalk80.green(`Added feed: ${url}`));
|
|
6302
6332
|
}
|
|
6303
6333
|
|
|
6304
6334
|
// src/commands/news/web/handleRequest.ts
|
|
6305
|
-
import
|
|
6335
|
+
import chalk81 from "chalk";
|
|
6306
6336
|
|
|
6307
6337
|
// src/commands/news/web/shared.ts
|
|
6308
6338
|
import { decodeHTML } from "entities";
|
|
@@ -6438,17 +6468,17 @@ function prefetch() {
|
|
|
6438
6468
|
const config = loadConfig();
|
|
6439
6469
|
const total = config.news.feeds.length;
|
|
6440
6470
|
if (total === 0) return;
|
|
6441
|
-
process.stdout.write(
|
|
6471
|
+
process.stdout.write(chalk81.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6442
6472
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6443
6473
|
const width = 20;
|
|
6444
6474
|
const filled = Math.round(done2 / t * width);
|
|
6445
6475
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6446
6476
|
process.stdout.write(
|
|
6447
|
-
`\r${
|
|
6477
|
+
`\r${chalk81.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6448
6478
|
);
|
|
6449
6479
|
}).then((items) => {
|
|
6450
6480
|
process.stdout.write(
|
|
6451
|
-
`\r${
|
|
6481
|
+
`\r${chalk81.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6452
6482
|
`
|
|
6453
6483
|
);
|
|
6454
6484
|
cachedItems = items;
|
|
@@ -6616,7 +6646,7 @@ import { tmpdir as tmpdir4 } from "os";
|
|
|
6616
6646
|
import { join as join23 } from "path";
|
|
6617
6647
|
|
|
6618
6648
|
// src/commands/prs/loadCommentsCache.ts
|
|
6619
|
-
import { existsSync as
|
|
6649
|
+
import { existsSync as existsSync30, readFileSync as readFileSync25, unlinkSync as unlinkSync7 } from "fs";
|
|
6620
6650
|
import { join as join22 } from "path";
|
|
6621
6651
|
import { parse as parse2 } from "yaml";
|
|
6622
6652
|
function getCachePath(prNumber) {
|
|
@@ -6624,15 +6654,15 @@ function getCachePath(prNumber) {
|
|
|
6624
6654
|
}
|
|
6625
6655
|
function loadCommentsCache(prNumber) {
|
|
6626
6656
|
const cachePath = getCachePath(prNumber);
|
|
6627
|
-
if (!
|
|
6657
|
+
if (!existsSync30(cachePath)) {
|
|
6628
6658
|
return null;
|
|
6629
6659
|
}
|
|
6630
|
-
const content =
|
|
6660
|
+
const content = readFileSync25(cachePath, "utf-8");
|
|
6631
6661
|
return parse2(content);
|
|
6632
6662
|
}
|
|
6633
6663
|
function deleteCommentsCache(prNumber) {
|
|
6634
6664
|
const cachePath = getCachePath(prNumber);
|
|
6635
|
-
if (
|
|
6665
|
+
if (existsSync30(cachePath)) {
|
|
6636
6666
|
unlinkSync7(cachePath);
|
|
6637
6667
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
6638
6668
|
}
|
|
@@ -6729,7 +6759,7 @@ function fixed(commentId, sha) {
|
|
|
6729
6759
|
}
|
|
6730
6760
|
|
|
6731
6761
|
// src/commands/prs/listComments/index.ts
|
|
6732
|
-
import { existsSync as
|
|
6762
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync6, writeFileSync as writeFileSync23 } from "fs";
|
|
6733
6763
|
import { join as join25 } from "path";
|
|
6734
6764
|
import { stringify } from "yaml";
|
|
6735
6765
|
|
|
@@ -6809,20 +6839,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6809
6839
|
}
|
|
6810
6840
|
|
|
6811
6841
|
// src/commands/prs/listComments/printComments.ts
|
|
6812
|
-
import
|
|
6842
|
+
import chalk82 from "chalk";
|
|
6813
6843
|
function formatForHuman(comment3) {
|
|
6814
6844
|
if (comment3.type === "review") {
|
|
6815
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
6845
|
+
const stateColor = comment3.state === "APPROVED" ? chalk82.green : comment3.state === "CHANGES_REQUESTED" ? chalk82.red : chalk82.yellow;
|
|
6816
6846
|
return [
|
|
6817
|
-
`${
|
|
6847
|
+
`${chalk82.cyan("Review")} by ${chalk82.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
6818
6848
|
comment3.body,
|
|
6819
6849
|
""
|
|
6820
6850
|
].join("\n");
|
|
6821
6851
|
}
|
|
6822
6852
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
6823
6853
|
return [
|
|
6824
|
-
`${
|
|
6825
|
-
|
|
6854
|
+
`${chalk82.cyan("Line comment")} by ${chalk82.bold(comment3.user)} on ${chalk82.dim(`${comment3.path}${location}`)}`,
|
|
6855
|
+
chalk82.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6826
6856
|
comment3.body,
|
|
6827
6857
|
""
|
|
6828
6858
|
].join("\n");
|
|
@@ -6855,7 +6885,7 @@ function printComments2(result) {
|
|
|
6855
6885
|
// src/commands/prs/listComments/index.ts
|
|
6856
6886
|
function writeCommentsCache(prNumber, comments2) {
|
|
6857
6887
|
const assistDir = join25(process.cwd(), ".assist");
|
|
6858
|
-
if (!
|
|
6888
|
+
if (!existsSync31(assistDir)) {
|
|
6859
6889
|
mkdirSync6(assistDir, { recursive: true });
|
|
6860
6890
|
}
|
|
6861
6891
|
const cacheData = {
|
|
@@ -6912,13 +6942,13 @@ import { execSync as execSync32 } from "child_process";
|
|
|
6912
6942
|
import enquirer8 from "enquirer";
|
|
6913
6943
|
|
|
6914
6944
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6915
|
-
import
|
|
6945
|
+
import chalk83 from "chalk";
|
|
6916
6946
|
var STATUS_MAP = {
|
|
6917
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6918
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6947
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk83.magenta("merged"), date: pr.mergedAt } : null,
|
|
6948
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk83.red("closed"), date: pr.closedAt } : null
|
|
6919
6949
|
};
|
|
6920
6950
|
function defaultStatus(pr) {
|
|
6921
|
-
return { label:
|
|
6951
|
+
return { label: chalk83.green("opened"), date: pr.createdAt };
|
|
6922
6952
|
}
|
|
6923
6953
|
function getStatus2(pr) {
|
|
6924
6954
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6927,11 +6957,11 @@ function formatDate(dateStr) {
|
|
|
6927
6957
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6928
6958
|
}
|
|
6929
6959
|
function formatPrHeader(pr, status2) {
|
|
6930
|
-
return `${
|
|
6960
|
+
return `${chalk83.cyan(`#${pr.number}`)} ${pr.title} ${chalk83.dim(`(${pr.author.login},`)} ${status2.label} ${chalk83.dim(`${formatDate(status2.date)})`)}`;
|
|
6931
6961
|
}
|
|
6932
6962
|
function logPrDetails(pr) {
|
|
6933
6963
|
console.log(
|
|
6934
|
-
|
|
6964
|
+
chalk83.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6935
6965
|
);
|
|
6936
6966
|
console.log();
|
|
6937
6967
|
}
|
|
@@ -7097,10 +7127,10 @@ function registerPrs(program2) {
|
|
|
7097
7127
|
}
|
|
7098
7128
|
|
|
7099
7129
|
// src/commands/ravendb/ravendbAuth.ts
|
|
7100
|
-
import
|
|
7130
|
+
import chalk89 from "chalk";
|
|
7101
7131
|
|
|
7102
7132
|
// src/shared/createConnectionAuth.ts
|
|
7103
|
-
import
|
|
7133
|
+
import chalk84 from "chalk";
|
|
7104
7134
|
function listConnections(connections, format2) {
|
|
7105
7135
|
if (connections.length === 0) {
|
|
7106
7136
|
console.log("No connections configured.");
|
|
@@ -7113,7 +7143,7 @@ function listConnections(connections, format2) {
|
|
|
7113
7143
|
function removeConnection(connections, name, save) {
|
|
7114
7144
|
const filtered = connections.filter((c) => c.name !== name);
|
|
7115
7145
|
if (filtered.length === connections.length) {
|
|
7116
|
-
console.error(
|
|
7146
|
+
console.error(chalk84.red(`Connection "${name}" not found.`));
|
|
7117
7147
|
process.exit(1);
|
|
7118
7148
|
}
|
|
7119
7149
|
save(filtered);
|
|
@@ -7159,15 +7189,15 @@ function saveConnections(connections) {
|
|
|
7159
7189
|
}
|
|
7160
7190
|
|
|
7161
7191
|
// src/commands/ravendb/promptConnection.ts
|
|
7162
|
-
import
|
|
7192
|
+
import chalk87 from "chalk";
|
|
7163
7193
|
|
|
7164
7194
|
// src/commands/ravendb/selectOpSecret.ts
|
|
7165
|
-
import
|
|
7195
|
+
import chalk86 from "chalk";
|
|
7166
7196
|
import Enquirer2 from "enquirer";
|
|
7167
7197
|
|
|
7168
7198
|
// src/commands/ravendb/searchItems.ts
|
|
7169
7199
|
import { execSync as execSync34 } from "child_process";
|
|
7170
|
-
import
|
|
7200
|
+
import chalk85 from "chalk";
|
|
7171
7201
|
function opExec(args) {
|
|
7172
7202
|
return execSync34(`op ${args}`, {
|
|
7173
7203
|
encoding: "utf-8",
|
|
@@ -7180,7 +7210,7 @@ function searchItems(search) {
|
|
|
7180
7210
|
items = JSON.parse(opExec("item list --format=json"));
|
|
7181
7211
|
} catch {
|
|
7182
7212
|
console.error(
|
|
7183
|
-
|
|
7213
|
+
chalk85.red(
|
|
7184
7214
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
7185
7215
|
)
|
|
7186
7216
|
);
|
|
@@ -7194,7 +7224,7 @@ function getItemFields(itemId) {
|
|
|
7194
7224
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
7195
7225
|
return item.fields.filter((f) => f.reference && f.label);
|
|
7196
7226
|
} catch {
|
|
7197
|
-
console.error(
|
|
7227
|
+
console.error(chalk85.red("Failed to get item details from 1Password."));
|
|
7198
7228
|
process.exit(1);
|
|
7199
7229
|
}
|
|
7200
7230
|
}
|
|
@@ -7213,7 +7243,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7213
7243
|
}).run();
|
|
7214
7244
|
const items = searchItems(search);
|
|
7215
7245
|
if (items.length === 0) {
|
|
7216
|
-
console.error(
|
|
7246
|
+
console.error(chalk86.red(`No items found matching "${search}".`));
|
|
7217
7247
|
process.exit(1);
|
|
7218
7248
|
}
|
|
7219
7249
|
const itemId = await selectOne(
|
|
@@ -7222,7 +7252,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7222
7252
|
);
|
|
7223
7253
|
const fields = getItemFields(itemId);
|
|
7224
7254
|
if (fields.length === 0) {
|
|
7225
|
-
console.error(
|
|
7255
|
+
console.error(chalk86.red("No fields with references found on this item."));
|
|
7226
7256
|
process.exit(1);
|
|
7227
7257
|
}
|
|
7228
7258
|
const ref = await selectOne(
|
|
@@ -7236,7 +7266,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7236
7266
|
async function promptConnection(existingNames) {
|
|
7237
7267
|
const name = await promptInput("name", "Connection name:");
|
|
7238
7268
|
if (existingNames.includes(name)) {
|
|
7239
|
-
console.error(
|
|
7269
|
+
console.error(chalk87.red(`Connection "${name}" already exists.`));
|
|
7240
7270
|
process.exit(1);
|
|
7241
7271
|
}
|
|
7242
7272
|
const url = await promptInput(
|
|
@@ -7245,22 +7275,22 @@ async function promptConnection(existingNames) {
|
|
|
7245
7275
|
);
|
|
7246
7276
|
const database = await promptInput("database", "Database name:");
|
|
7247
7277
|
if (!name || !url || !database) {
|
|
7248
|
-
console.error(
|
|
7278
|
+
console.error(chalk87.red("All fields are required."));
|
|
7249
7279
|
process.exit(1);
|
|
7250
7280
|
}
|
|
7251
7281
|
const apiKeyRef = await selectOpSecret();
|
|
7252
|
-
console.log(
|
|
7282
|
+
console.log(chalk87.dim(`Using: ${apiKeyRef}`));
|
|
7253
7283
|
return { name, url, database, apiKeyRef };
|
|
7254
7284
|
}
|
|
7255
7285
|
|
|
7256
7286
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
7257
|
-
import
|
|
7287
|
+
import chalk88 from "chalk";
|
|
7258
7288
|
function ravendbSetConnection(name) {
|
|
7259
7289
|
const raw = loadGlobalConfigRaw();
|
|
7260
7290
|
const ravendb = raw.ravendb ?? {};
|
|
7261
7291
|
const connections = ravendb.connections ?? [];
|
|
7262
7292
|
if (!connections.some((c) => c.name === name)) {
|
|
7263
|
-
console.error(
|
|
7293
|
+
console.error(chalk88.red(`Connection "${name}" not found.`));
|
|
7264
7294
|
console.error(
|
|
7265
7295
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7266
7296
|
);
|
|
@@ -7276,16 +7306,16 @@ function ravendbSetConnection(name) {
|
|
|
7276
7306
|
var ravendbAuth = createConnectionAuth({
|
|
7277
7307
|
load: loadConnections,
|
|
7278
7308
|
save: saveConnections,
|
|
7279
|
-
format: (c) => `${
|
|
7309
|
+
format: (c) => `${chalk89.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
7280
7310
|
promptNew: promptConnection,
|
|
7281
7311
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
7282
7312
|
});
|
|
7283
7313
|
|
|
7284
7314
|
// src/commands/ravendb/ravendbCollections.ts
|
|
7285
|
-
import
|
|
7315
|
+
import chalk93 from "chalk";
|
|
7286
7316
|
|
|
7287
7317
|
// src/commands/ravendb/ravenFetch.ts
|
|
7288
|
-
import
|
|
7318
|
+
import chalk91 from "chalk";
|
|
7289
7319
|
|
|
7290
7320
|
// src/commands/ravendb/getAccessToken.ts
|
|
7291
7321
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -7322,10 +7352,10 @@ ${errorText}`
|
|
|
7322
7352
|
|
|
7323
7353
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
7324
7354
|
import { execSync as execSync35 } from "child_process";
|
|
7325
|
-
import
|
|
7355
|
+
import chalk90 from "chalk";
|
|
7326
7356
|
function resolveOpSecret(reference) {
|
|
7327
7357
|
if (!reference.startsWith("op://")) {
|
|
7328
|
-
console.error(
|
|
7358
|
+
console.error(chalk90.red(`Invalid secret reference: must start with op://`));
|
|
7329
7359
|
process.exit(1);
|
|
7330
7360
|
}
|
|
7331
7361
|
try {
|
|
@@ -7335,7 +7365,7 @@ function resolveOpSecret(reference) {
|
|
|
7335
7365
|
}).trim();
|
|
7336
7366
|
} catch {
|
|
7337
7367
|
console.error(
|
|
7338
|
-
|
|
7368
|
+
chalk90.red(
|
|
7339
7369
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
7340
7370
|
)
|
|
7341
7371
|
);
|
|
@@ -7362,7 +7392,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7362
7392
|
if (!response.ok) {
|
|
7363
7393
|
const body = await response.text();
|
|
7364
7394
|
console.error(
|
|
7365
|
-
|
|
7395
|
+
chalk91.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
7366
7396
|
);
|
|
7367
7397
|
console.error(body.substring(0, 500));
|
|
7368
7398
|
process.exit(1);
|
|
@@ -7371,7 +7401,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7371
7401
|
}
|
|
7372
7402
|
|
|
7373
7403
|
// src/commands/ravendb/resolveConnection.ts
|
|
7374
|
-
import
|
|
7404
|
+
import chalk92 from "chalk";
|
|
7375
7405
|
function loadRavendb() {
|
|
7376
7406
|
const raw = loadGlobalConfigRaw();
|
|
7377
7407
|
const ravendb = raw.ravendb;
|
|
@@ -7385,7 +7415,7 @@ function resolveConnection(name) {
|
|
|
7385
7415
|
const connectionName = name ?? defaultConnection;
|
|
7386
7416
|
if (!connectionName) {
|
|
7387
7417
|
console.error(
|
|
7388
|
-
|
|
7418
|
+
chalk92.red(
|
|
7389
7419
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
7390
7420
|
)
|
|
7391
7421
|
);
|
|
@@ -7393,7 +7423,7 @@ function resolveConnection(name) {
|
|
|
7393
7423
|
}
|
|
7394
7424
|
const connection = connections.find((c) => c.name === connectionName);
|
|
7395
7425
|
if (!connection) {
|
|
7396
|
-
console.error(
|
|
7426
|
+
console.error(chalk92.red(`Connection "${connectionName}" not found.`));
|
|
7397
7427
|
console.error(
|
|
7398
7428
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7399
7429
|
);
|
|
@@ -7424,15 +7454,15 @@ async function ravendbCollections(connectionName) {
|
|
|
7424
7454
|
return;
|
|
7425
7455
|
}
|
|
7426
7456
|
for (const c of collections) {
|
|
7427
|
-
console.log(`${
|
|
7457
|
+
console.log(`${chalk93.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
7428
7458
|
}
|
|
7429
7459
|
}
|
|
7430
7460
|
|
|
7431
7461
|
// src/commands/ravendb/ravendbQuery.ts
|
|
7432
|
-
import
|
|
7462
|
+
import chalk95 from "chalk";
|
|
7433
7463
|
|
|
7434
7464
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7435
|
-
import
|
|
7465
|
+
import chalk94 from "chalk";
|
|
7436
7466
|
|
|
7437
7467
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7438
7468
|
function buildQueryPath(opts) {
|
|
@@ -7470,7 +7500,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7470
7500
|
allResults.push(...results);
|
|
7471
7501
|
start3 += results.length;
|
|
7472
7502
|
process.stderr.write(
|
|
7473
|
-
`\r${
|
|
7503
|
+
`\r${chalk94.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7474
7504
|
);
|
|
7475
7505
|
if (start3 >= totalResults) break;
|
|
7476
7506
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7485,7 +7515,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7485
7515
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7486
7516
|
const resolved = resolveArgs(connectionName, collection);
|
|
7487
7517
|
if (!resolved.collection && !options2.query) {
|
|
7488
|
-
console.error(
|
|
7518
|
+
console.error(chalk95.red("Provide a collection name or --query filter."));
|
|
7489
7519
|
process.exit(1);
|
|
7490
7520
|
}
|
|
7491
7521
|
const { collection: col } = resolved;
|
|
@@ -7523,7 +7553,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7523
7553
|
import * as path27 from "path";
|
|
7524
7554
|
|
|
7525
7555
|
// src/commands/refactor/logViolations.ts
|
|
7526
|
-
import
|
|
7556
|
+
import chalk96 from "chalk";
|
|
7527
7557
|
var DEFAULT_MAX_LINES = 100;
|
|
7528
7558
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7529
7559
|
if (violations.length === 0) {
|
|
@@ -7532,43 +7562,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7532
7562
|
}
|
|
7533
7563
|
return;
|
|
7534
7564
|
}
|
|
7535
|
-
console.error(
|
|
7565
|
+
console.error(chalk96.red(`
|
|
7536
7566
|
Refactor check failed:
|
|
7537
7567
|
`));
|
|
7538
|
-
console.error(
|
|
7568
|
+
console.error(chalk96.red(` The following files exceed ${maxLines} lines:
|
|
7539
7569
|
`));
|
|
7540
7570
|
for (const violation of violations) {
|
|
7541
|
-
console.error(
|
|
7571
|
+
console.error(chalk96.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7542
7572
|
}
|
|
7543
7573
|
console.error(
|
|
7544
|
-
|
|
7574
|
+
chalk96.yellow(
|
|
7545
7575
|
`
|
|
7546
7576
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7547
7577
|
way to refactor it, ignore it with:
|
|
7548
7578
|
`
|
|
7549
7579
|
)
|
|
7550
7580
|
);
|
|
7551
|
-
console.error(
|
|
7581
|
+
console.error(chalk96.gray(` assist refactor ignore <file>
|
|
7552
7582
|
`));
|
|
7553
7583
|
if (process.env.CLAUDECODE) {
|
|
7554
|
-
console.error(
|
|
7584
|
+
console.error(chalk96.cyan(`
|
|
7555
7585
|
## Extracting Code to New Files
|
|
7556
7586
|
`));
|
|
7557
7587
|
console.error(
|
|
7558
|
-
|
|
7588
|
+
chalk96.cyan(
|
|
7559
7589
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7560
7590
|
`
|
|
7561
7591
|
)
|
|
7562
7592
|
);
|
|
7563
7593
|
console.error(
|
|
7564
|
-
|
|
7594
|
+
chalk96.cyan(
|
|
7565
7595
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7566
7596
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7567
7597
|
`
|
|
7568
7598
|
)
|
|
7569
7599
|
);
|
|
7570
7600
|
console.error(
|
|
7571
|
-
|
|
7601
|
+
chalk96.cyan(
|
|
7572
7602
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7573
7603
|
domains, move it to a common/shared folder.
|
|
7574
7604
|
`
|
|
@@ -7724,7 +7754,7 @@ async function check(pattern2, options2) {
|
|
|
7724
7754
|
|
|
7725
7755
|
// src/commands/refactor/extract/index.ts
|
|
7726
7756
|
import path33 from "path";
|
|
7727
|
-
import
|
|
7757
|
+
import chalk99 from "chalk";
|
|
7728
7758
|
|
|
7729
7759
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7730
7760
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -8250,23 +8280,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
8250
8280
|
|
|
8251
8281
|
// src/commands/refactor/extract/displayPlan.ts
|
|
8252
8282
|
import path31 from "path";
|
|
8253
|
-
import
|
|
8283
|
+
import chalk97 from "chalk";
|
|
8254
8284
|
function section(title) {
|
|
8255
8285
|
return `
|
|
8256
|
-
${
|
|
8286
|
+
${chalk97.cyan(title)}`;
|
|
8257
8287
|
}
|
|
8258
8288
|
function displayImporters(plan2, cwd) {
|
|
8259
8289
|
if (plan2.importersToUpdate.length === 0) return;
|
|
8260
8290
|
console.log(section("Update importers:"));
|
|
8261
8291
|
for (const imp of plan2.importersToUpdate) {
|
|
8262
8292
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
8263
|
-
console.log(` ${
|
|
8293
|
+
console.log(` ${chalk97.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
8264
8294
|
}
|
|
8265
8295
|
}
|
|
8266
8296
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
8267
|
-
console.log(
|
|
8297
|
+
console.log(chalk97.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
8268
8298
|
`));
|
|
8269
|
-
console.log(` ${
|
|
8299
|
+
console.log(` ${chalk97.cyan("Functions to move:")}`);
|
|
8270
8300
|
for (const name of plan2.extractedNames) {
|
|
8271
8301
|
console.log(` ${name}`);
|
|
8272
8302
|
}
|
|
@@ -8301,7 +8331,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
8301
8331
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
8302
8332
|
import fs17 from "fs";
|
|
8303
8333
|
import path32 from "path";
|
|
8304
|
-
import
|
|
8334
|
+
import chalk98 from "chalk";
|
|
8305
8335
|
import { Project as Project2 } from "ts-morph";
|
|
8306
8336
|
function findTsConfig(sourcePath) {
|
|
8307
8337
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -8332,7 +8362,7 @@ function loadProjectFile(file) {
|
|
|
8332
8362
|
});
|
|
8333
8363
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
8334
8364
|
if (!sourceFile) {
|
|
8335
|
-
console.log(
|
|
8365
|
+
console.log(chalk98.red(`File not found in project: ${file}`));
|
|
8336
8366
|
process.exit(1);
|
|
8337
8367
|
}
|
|
8338
8368
|
return { project, sourceFile };
|
|
@@ -8355,19 +8385,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
8355
8385
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
8356
8386
|
if (options2.apply) {
|
|
8357
8387
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
8358
|
-
console.log(
|
|
8388
|
+
console.log(chalk99.green("\nExtraction complete"));
|
|
8359
8389
|
} else {
|
|
8360
|
-
console.log(
|
|
8390
|
+
console.log(chalk99.dim("\nDry run. Use --apply to execute."));
|
|
8361
8391
|
}
|
|
8362
8392
|
}
|
|
8363
8393
|
|
|
8364
8394
|
// src/commands/refactor/ignore.ts
|
|
8365
8395
|
import fs18 from "fs";
|
|
8366
|
-
import
|
|
8396
|
+
import chalk100 from "chalk";
|
|
8367
8397
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
8368
8398
|
function ignore(file) {
|
|
8369
8399
|
if (!fs18.existsSync(file)) {
|
|
8370
|
-
console.error(
|
|
8400
|
+
console.error(chalk100.red(`Error: File does not exist: ${file}`));
|
|
8371
8401
|
process.exit(1);
|
|
8372
8402
|
}
|
|
8373
8403
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -8383,7 +8413,7 @@ function ignore(file) {
|
|
|
8383
8413
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
8384
8414
|
}
|
|
8385
8415
|
console.log(
|
|
8386
|
-
|
|
8416
|
+
chalk100.green(
|
|
8387
8417
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
8388
8418
|
)
|
|
8389
8419
|
);
|
|
@@ -8391,26 +8421,26 @@ function ignore(file) {
|
|
|
8391
8421
|
|
|
8392
8422
|
// src/commands/refactor/rename/index.ts
|
|
8393
8423
|
import path34 from "path";
|
|
8394
|
-
import
|
|
8424
|
+
import chalk101 from "chalk";
|
|
8395
8425
|
async function rename(source, destination, options2 = {}) {
|
|
8396
8426
|
const destPath = path34.resolve(destination);
|
|
8397
8427
|
const cwd = process.cwd();
|
|
8398
8428
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
8399
8429
|
const relDest = path34.relative(cwd, destPath);
|
|
8400
8430
|
const { project, sourceFile } = loadProjectFile(source);
|
|
8401
|
-
console.log(
|
|
8431
|
+
console.log(chalk101.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
8402
8432
|
if (options2.apply) {
|
|
8403
8433
|
sourceFile.move(destPath);
|
|
8404
8434
|
await project.save();
|
|
8405
|
-
console.log(
|
|
8435
|
+
console.log(chalk101.green("Done"));
|
|
8406
8436
|
} else {
|
|
8407
|
-
console.log(
|
|
8437
|
+
console.log(chalk101.dim("Dry run. Use --apply to execute."));
|
|
8408
8438
|
}
|
|
8409
8439
|
}
|
|
8410
8440
|
|
|
8411
8441
|
// src/commands/refactor/renameSymbol/index.ts
|
|
8412
8442
|
import path36 from "path";
|
|
8413
|
-
import
|
|
8443
|
+
import chalk102 from "chalk";
|
|
8414
8444
|
import { Project as Project3 } from "ts-morph";
|
|
8415
8445
|
|
|
8416
8446
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8459,38 +8489,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8459
8489
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8460
8490
|
const sourceFile = project.getSourceFile(filePath);
|
|
8461
8491
|
if (!sourceFile) {
|
|
8462
|
-
console.log(
|
|
8492
|
+
console.log(chalk102.red(`File not found in project: ${file}`));
|
|
8463
8493
|
process.exit(1);
|
|
8464
8494
|
}
|
|
8465
8495
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8466
8496
|
if (!symbol) {
|
|
8467
|
-
console.log(
|
|
8497
|
+
console.log(chalk102.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8468
8498
|
process.exit(1);
|
|
8469
8499
|
}
|
|
8470
8500
|
const grouped = groupReferences(symbol, cwd);
|
|
8471
8501
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8472
8502
|
console.log(
|
|
8473
|
-
|
|
8503
|
+
chalk102.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8474
8504
|
`)
|
|
8475
8505
|
);
|
|
8476
8506
|
for (const [refFile, lines] of grouped) {
|
|
8477
8507
|
console.log(
|
|
8478
|
-
` ${
|
|
8508
|
+
` ${chalk102.dim(refFile)}: lines ${chalk102.cyan(lines.join(", "))}`
|
|
8479
8509
|
);
|
|
8480
8510
|
}
|
|
8481
8511
|
if (options2.apply) {
|
|
8482
8512
|
symbol.rename(newName);
|
|
8483
8513
|
await project.save();
|
|
8484
|
-
console.log(
|
|
8514
|
+
console.log(chalk102.green(`
|
|
8485
8515
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8486
8516
|
} else {
|
|
8487
|
-
console.log(
|
|
8517
|
+
console.log(chalk102.dim("\nDry run. Use --apply to execute."));
|
|
8488
8518
|
}
|
|
8489
8519
|
}
|
|
8490
8520
|
|
|
8491
8521
|
// src/commands/refactor/restructure/index.ts
|
|
8492
8522
|
import path45 from "path";
|
|
8493
|
-
import
|
|
8523
|
+
import chalk105 from "chalk";
|
|
8494
8524
|
|
|
8495
8525
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8496
8526
|
import path37 from "path";
|
|
@@ -8733,50 +8763,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8733
8763
|
|
|
8734
8764
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8735
8765
|
import path41 from "path";
|
|
8736
|
-
import
|
|
8766
|
+
import chalk103 from "chalk";
|
|
8737
8767
|
function relPath(filePath) {
|
|
8738
8768
|
return path41.relative(process.cwd(), filePath);
|
|
8739
8769
|
}
|
|
8740
8770
|
function displayMoves(plan2) {
|
|
8741
8771
|
if (plan2.moves.length === 0) return;
|
|
8742
|
-
console.log(
|
|
8772
|
+
console.log(chalk103.bold("\nFile moves:"));
|
|
8743
8773
|
for (const move of plan2.moves) {
|
|
8744
8774
|
console.log(
|
|
8745
|
-
` ${
|
|
8775
|
+
` ${chalk103.red(relPath(move.from))} \u2192 ${chalk103.green(relPath(move.to))}`
|
|
8746
8776
|
);
|
|
8747
|
-
console.log(
|
|
8777
|
+
console.log(chalk103.dim(` ${move.reason}`));
|
|
8748
8778
|
}
|
|
8749
8779
|
}
|
|
8750
8780
|
function displayRewrites(rewrites) {
|
|
8751
8781
|
if (rewrites.length === 0) return;
|
|
8752
8782
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8753
|
-
console.log(
|
|
8783
|
+
console.log(chalk103.bold(`
|
|
8754
8784
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8755
8785
|
for (const file of affectedFiles) {
|
|
8756
|
-
console.log(` ${
|
|
8786
|
+
console.log(` ${chalk103.cyan(relPath(file))}:`);
|
|
8757
8787
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8758
8788
|
(r) => r.file === file
|
|
8759
8789
|
)) {
|
|
8760
8790
|
console.log(
|
|
8761
|
-
` ${
|
|
8791
|
+
` ${chalk103.red(`"${oldSpecifier}"`)} \u2192 ${chalk103.green(`"${newSpecifier}"`)}`
|
|
8762
8792
|
);
|
|
8763
8793
|
}
|
|
8764
8794
|
}
|
|
8765
8795
|
}
|
|
8766
8796
|
function displayPlan2(plan2) {
|
|
8767
8797
|
if (plan2.warnings.length > 0) {
|
|
8768
|
-
console.log(
|
|
8769
|
-
for (const w of plan2.warnings) console.log(
|
|
8798
|
+
console.log(chalk103.yellow("\nWarnings:"));
|
|
8799
|
+
for (const w of plan2.warnings) console.log(chalk103.yellow(` ${w}`));
|
|
8770
8800
|
}
|
|
8771
8801
|
if (plan2.newDirectories.length > 0) {
|
|
8772
|
-
console.log(
|
|
8802
|
+
console.log(chalk103.bold("\nNew directories:"));
|
|
8773
8803
|
for (const dir of plan2.newDirectories)
|
|
8774
|
-
console.log(
|
|
8804
|
+
console.log(chalk103.green(` ${dir}/`));
|
|
8775
8805
|
}
|
|
8776
8806
|
displayMoves(plan2);
|
|
8777
8807
|
displayRewrites(plan2.rewrites);
|
|
8778
8808
|
console.log(
|
|
8779
|
-
|
|
8809
|
+
chalk103.dim(
|
|
8780
8810
|
`
|
|
8781
8811
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8782
8812
|
)
|
|
@@ -8786,18 +8816,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8786
8816
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8787
8817
|
import fs20 from "fs";
|
|
8788
8818
|
import path42 from "path";
|
|
8789
|
-
import
|
|
8819
|
+
import chalk104 from "chalk";
|
|
8790
8820
|
function executePlan(plan2) {
|
|
8791
8821
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8792
8822
|
for (const [file, content] of updatedContents) {
|
|
8793
8823
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8794
8824
|
console.log(
|
|
8795
|
-
|
|
8825
|
+
chalk104.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8796
8826
|
);
|
|
8797
8827
|
}
|
|
8798
8828
|
for (const dir of plan2.newDirectories) {
|
|
8799
8829
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8800
|
-
console.log(
|
|
8830
|
+
console.log(chalk104.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8801
8831
|
}
|
|
8802
8832
|
for (const move of plan2.moves) {
|
|
8803
8833
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8806,7 +8836,7 @@ function executePlan(plan2) {
|
|
|
8806
8836
|
}
|
|
8807
8837
|
fs20.renameSync(move.from, move.to);
|
|
8808
8838
|
console.log(
|
|
8809
|
-
|
|
8839
|
+
chalk104.white(
|
|
8810
8840
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8811
8841
|
)
|
|
8812
8842
|
);
|
|
@@ -8821,7 +8851,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8821
8851
|
if (entries.length === 0) {
|
|
8822
8852
|
fs20.rmdirSync(dir);
|
|
8823
8853
|
console.log(
|
|
8824
|
-
|
|
8854
|
+
chalk104.dim(
|
|
8825
8855
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8826
8856
|
)
|
|
8827
8857
|
);
|
|
@@ -8954,22 +8984,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8954
8984
|
const targetPattern = pattern2 ?? "src";
|
|
8955
8985
|
const files = findSourceFiles2(targetPattern);
|
|
8956
8986
|
if (files.length === 0) {
|
|
8957
|
-
console.log(
|
|
8987
|
+
console.log(chalk105.yellow("No files found matching pattern"));
|
|
8958
8988
|
return;
|
|
8959
8989
|
}
|
|
8960
8990
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8961
8991
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8962
8992
|
if (plan2.moves.length === 0) {
|
|
8963
|
-
console.log(
|
|
8993
|
+
console.log(chalk105.green("No restructuring needed"));
|
|
8964
8994
|
return;
|
|
8965
8995
|
}
|
|
8966
8996
|
displayPlan2(plan2);
|
|
8967
8997
|
if (options2.apply) {
|
|
8968
|
-
console.log(
|
|
8998
|
+
console.log(chalk105.bold("\nApplying changes..."));
|
|
8969
8999
|
executePlan(plan2);
|
|
8970
|
-
console.log(
|
|
9000
|
+
console.log(chalk105.green("\nRestructuring complete"));
|
|
8971
9001
|
} else {
|
|
8972
|
-
console.log(
|
|
9002
|
+
console.log(chalk105.dim("\nDry run. Use --apply to execute."));
|
|
8973
9003
|
}
|
|
8974
9004
|
}
|
|
8975
9005
|
|
|
@@ -9009,7 +9039,7 @@ function registerRefactor(program2) {
|
|
|
9009
9039
|
}
|
|
9010
9040
|
|
|
9011
9041
|
// src/commands/seq/seqAuth.ts
|
|
9012
|
-
import
|
|
9042
|
+
import chalk107 from "chalk";
|
|
9013
9043
|
|
|
9014
9044
|
// src/commands/seq/loadConnections.ts
|
|
9015
9045
|
function loadConnections2() {
|
|
@@ -9038,11 +9068,11 @@ function setDefaultConnection(name) {
|
|
|
9038
9068
|
}
|
|
9039
9069
|
|
|
9040
9070
|
// src/commands/seq/promptConnection.ts
|
|
9041
|
-
import
|
|
9071
|
+
import chalk106 from "chalk";
|
|
9042
9072
|
async function promptConnection2(existingNames) {
|
|
9043
9073
|
const name = await promptInput("name", "Connection name:", "default");
|
|
9044
9074
|
if (existingNames.includes(name)) {
|
|
9045
|
-
console.error(
|
|
9075
|
+
console.error(chalk106.red(`Connection "${name}" already exists.`));
|
|
9046
9076
|
process.exit(1);
|
|
9047
9077
|
}
|
|
9048
9078
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -9054,16 +9084,16 @@ async function promptConnection2(existingNames) {
|
|
|
9054
9084
|
var seqAuth = createConnectionAuth({
|
|
9055
9085
|
load: loadConnections2,
|
|
9056
9086
|
save: saveConnections2,
|
|
9057
|
-
format: (c) => `${
|
|
9087
|
+
format: (c) => `${chalk107.bold(c.name)} ${c.url}`,
|
|
9058
9088
|
promptNew: promptConnection2,
|
|
9059
9089
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
9060
9090
|
});
|
|
9061
9091
|
|
|
9062
9092
|
// src/commands/seq/seqQuery.ts
|
|
9063
|
-
import
|
|
9093
|
+
import chalk111 from "chalk";
|
|
9064
9094
|
|
|
9065
9095
|
// src/commands/seq/fetchSeqEvents.ts
|
|
9066
|
-
import
|
|
9096
|
+
import chalk108 from "chalk";
|
|
9067
9097
|
async function fetchSeqEvents(conn, params) {
|
|
9068
9098
|
const url = `${conn.url}/api/events?${params}`;
|
|
9069
9099
|
const response = await fetch(url, {
|
|
@@ -9074,30 +9104,30 @@ async function fetchSeqEvents(conn, params) {
|
|
|
9074
9104
|
});
|
|
9075
9105
|
if (!response.ok) {
|
|
9076
9106
|
const body = await response.text();
|
|
9077
|
-
console.error(
|
|
9107
|
+
console.error(chalk108.red(`Seq returned ${response.status}: ${body}`));
|
|
9078
9108
|
process.exit(1);
|
|
9079
9109
|
}
|
|
9080
9110
|
return response.json();
|
|
9081
9111
|
}
|
|
9082
9112
|
|
|
9083
9113
|
// src/commands/seq/formatEvent.ts
|
|
9084
|
-
import
|
|
9114
|
+
import chalk109 from "chalk";
|
|
9085
9115
|
function levelColor(level) {
|
|
9086
9116
|
switch (level) {
|
|
9087
9117
|
case "Fatal":
|
|
9088
|
-
return
|
|
9118
|
+
return chalk109.bgRed.white;
|
|
9089
9119
|
case "Error":
|
|
9090
|
-
return
|
|
9120
|
+
return chalk109.red;
|
|
9091
9121
|
case "Warning":
|
|
9092
|
-
return
|
|
9122
|
+
return chalk109.yellow;
|
|
9093
9123
|
case "Information":
|
|
9094
|
-
return
|
|
9124
|
+
return chalk109.cyan;
|
|
9095
9125
|
case "Debug":
|
|
9096
|
-
return
|
|
9126
|
+
return chalk109.gray;
|
|
9097
9127
|
case "Verbose":
|
|
9098
|
-
return
|
|
9128
|
+
return chalk109.dim;
|
|
9099
9129
|
default:
|
|
9100
|
-
return
|
|
9130
|
+
return chalk109.white;
|
|
9101
9131
|
}
|
|
9102
9132
|
}
|
|
9103
9133
|
function levelAbbrev(level) {
|
|
@@ -9138,31 +9168,31 @@ function formatTimestamp(iso) {
|
|
|
9138
9168
|
function formatEvent(event) {
|
|
9139
9169
|
const color = levelColor(event.Level);
|
|
9140
9170
|
const abbrev = levelAbbrev(event.Level);
|
|
9141
|
-
const ts8 =
|
|
9171
|
+
const ts8 = chalk109.dim(formatTimestamp(event.Timestamp));
|
|
9142
9172
|
const msg = renderMessage(event);
|
|
9143
9173
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
9144
9174
|
if (event.Exception) {
|
|
9145
9175
|
for (const line of event.Exception.split("\n")) {
|
|
9146
|
-
lines.push(
|
|
9176
|
+
lines.push(chalk109.red(` ${line}`));
|
|
9147
9177
|
}
|
|
9148
9178
|
}
|
|
9149
9179
|
return lines.join("\n");
|
|
9150
9180
|
}
|
|
9151
9181
|
|
|
9152
9182
|
// src/commands/seq/resolveConnection.ts
|
|
9153
|
-
import
|
|
9183
|
+
import chalk110 from "chalk";
|
|
9154
9184
|
function resolveConnection2(name) {
|
|
9155
9185
|
const connections = loadConnections2();
|
|
9156
9186
|
if (connections.length === 0) {
|
|
9157
9187
|
console.error(
|
|
9158
|
-
|
|
9188
|
+
chalk110.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
9159
9189
|
);
|
|
9160
9190
|
process.exit(1);
|
|
9161
9191
|
}
|
|
9162
9192
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
9163
9193
|
const connection = connections.find((c) => c.name === target);
|
|
9164
9194
|
if (!connection) {
|
|
9165
|
-
console.error(
|
|
9195
|
+
console.error(chalk110.red(`Seq connection "${target}" not found.`));
|
|
9166
9196
|
process.exit(1);
|
|
9167
9197
|
}
|
|
9168
9198
|
return connection;
|
|
@@ -9178,7 +9208,7 @@ async function seqQuery(filter, options2) {
|
|
|
9178
9208
|
}
|
|
9179
9209
|
const events = await fetchSeqEvents(conn, params);
|
|
9180
9210
|
if (events.length === 0) {
|
|
9181
|
-
console.log(
|
|
9211
|
+
console.log(chalk111.yellow("No events found."));
|
|
9182
9212
|
return;
|
|
9183
9213
|
}
|
|
9184
9214
|
if (options2.json) {
|
|
@@ -9189,11 +9219,11 @@ async function seqQuery(filter, options2) {
|
|
|
9189
9219
|
for (const event of chronological) {
|
|
9190
9220
|
console.log(formatEvent(event));
|
|
9191
9221
|
}
|
|
9192
|
-
console.log(
|
|
9222
|
+
console.log(chalk111.dim(`
|
|
9193
9223
|
${events.length} events`));
|
|
9194
9224
|
if (events.length >= count) {
|
|
9195
9225
|
console.log(
|
|
9196
|
-
|
|
9226
|
+
chalk111.yellow(
|
|
9197
9227
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
9198
9228
|
)
|
|
9199
9229
|
);
|
|
@@ -9201,11 +9231,11 @@ ${events.length} events`));
|
|
|
9201
9231
|
}
|
|
9202
9232
|
|
|
9203
9233
|
// src/commands/seq/seqSetConnection.ts
|
|
9204
|
-
import
|
|
9234
|
+
import chalk112 from "chalk";
|
|
9205
9235
|
function seqSetConnection(name) {
|
|
9206
9236
|
const connections = loadConnections2();
|
|
9207
9237
|
if (!connections.find((c) => c.name === name)) {
|
|
9208
|
-
console.error(
|
|
9238
|
+
console.error(chalk112.red(`Connection "${name}" not found.`));
|
|
9209
9239
|
process.exit(1);
|
|
9210
9240
|
}
|
|
9211
9241
|
setDefaultConnection(name);
|
|
@@ -9224,7 +9254,7 @@ function registerSeq(program2) {
|
|
|
9224
9254
|
}
|
|
9225
9255
|
|
|
9226
9256
|
// src/commands/transcript/shared.ts
|
|
9227
|
-
import { existsSync as
|
|
9257
|
+
import { existsSync as existsSync32, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
|
|
9228
9258
|
import { basename as basename4, join as join26, relative } from "path";
|
|
9229
9259
|
import * as readline2 from "readline";
|
|
9230
9260
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
@@ -9240,7 +9270,7 @@ function isValidDatePrefix(filename) {
|
|
|
9240
9270
|
return DATE_PREFIX_REGEX.test(filename);
|
|
9241
9271
|
}
|
|
9242
9272
|
function collectFiles(dir, extension) {
|
|
9243
|
-
if (!
|
|
9273
|
+
if (!existsSync32(dir)) return [];
|
|
9244
9274
|
const results = [];
|
|
9245
9275
|
for (const entry of readdirSync5(dir)) {
|
|
9246
9276
|
const fullPath = join26(dir, entry);
|
|
@@ -9337,7 +9367,7 @@ async function configure() {
|
|
|
9337
9367
|
}
|
|
9338
9368
|
|
|
9339
9369
|
// src/commands/transcript/format/index.ts
|
|
9340
|
-
import { existsSync as
|
|
9370
|
+
import { existsSync as existsSync34 } from "fs";
|
|
9341
9371
|
|
|
9342
9372
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
9343
9373
|
import { dirname as dirname18, join as join28 } from "path";
|
|
@@ -9411,7 +9441,7 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
9411
9441
|
}
|
|
9412
9442
|
|
|
9413
9443
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
9414
|
-
import { existsSync as
|
|
9444
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync7, readFileSync as readFileSync26, writeFileSync as writeFileSync24 } from "fs";
|
|
9415
9445
|
import { basename as basename5, dirname as dirname19, join as join29 } from "path";
|
|
9416
9446
|
|
|
9417
9447
|
// src/commands/transcript/cleanText.ts
|
|
@@ -9636,7 +9666,7 @@ function logSkipped(relativeDir, mdFile) {
|
|
|
9636
9666
|
return "skipped";
|
|
9637
9667
|
}
|
|
9638
9668
|
function ensureDirectory(dir, label2) {
|
|
9639
|
-
if (!
|
|
9669
|
+
if (!existsSync33(dir)) {
|
|
9640
9670
|
mkdirSync7(dir, { recursive: true });
|
|
9641
9671
|
console.log(`Created ${label2}: ${dir}`);
|
|
9642
9672
|
}
|
|
@@ -9659,7 +9689,7 @@ function logReduction(cueCount, messageCount) {
|
|
|
9659
9689
|
}
|
|
9660
9690
|
function readAndParseCues(inputPath) {
|
|
9661
9691
|
console.log(`Reading: ${inputPath}`);
|
|
9662
|
-
return processCues(
|
|
9692
|
+
return processCues(readFileSync26(inputPath, "utf-8"));
|
|
9663
9693
|
}
|
|
9664
9694
|
function writeFormatted(outputPath, content) {
|
|
9665
9695
|
writeFileSync24(outputPath, content, "utf-8");
|
|
@@ -9672,7 +9702,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
|
|
|
9672
9702
|
logReduction(cues.length, chatMessages.length);
|
|
9673
9703
|
}
|
|
9674
9704
|
function tryProcessVtt(vttFile, paths) {
|
|
9675
|
-
if (
|
|
9705
|
+
if (existsSync33(paths.outputPath))
|
|
9676
9706
|
return logSkipped(paths.relativeDir, paths.mdFile);
|
|
9677
9707
|
convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
|
|
9678
9708
|
return "processed";
|
|
@@ -9698,7 +9728,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
|
|
|
9698
9728
|
logSummary(counts);
|
|
9699
9729
|
}
|
|
9700
9730
|
function requireVttDir(vttDir) {
|
|
9701
|
-
if (!
|
|
9731
|
+
if (!existsSync34(vttDir)) {
|
|
9702
9732
|
console.error(`VTT directory not found: ${vttDir}`);
|
|
9703
9733
|
process.exit(1);
|
|
9704
9734
|
}
|
|
@@ -9730,28 +9760,28 @@ async function format() {
|
|
|
9730
9760
|
}
|
|
9731
9761
|
|
|
9732
9762
|
// src/commands/transcript/summarise/index.ts
|
|
9733
|
-
import { existsSync as
|
|
9763
|
+
import { existsSync as existsSync36 } from "fs";
|
|
9734
9764
|
import { basename as basename6, dirname as dirname21, join as join31, relative as relative2 } from "path";
|
|
9735
9765
|
|
|
9736
9766
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
9737
9767
|
import {
|
|
9738
|
-
existsSync as
|
|
9768
|
+
existsSync as existsSync35,
|
|
9739
9769
|
mkdirSync as mkdirSync8,
|
|
9740
|
-
readFileSync as
|
|
9770
|
+
readFileSync as readFileSync27,
|
|
9741
9771
|
renameSync as renameSync2,
|
|
9742
9772
|
rmSync
|
|
9743
9773
|
} from "fs";
|
|
9744
9774
|
import { dirname as dirname20, join as join30 } from "path";
|
|
9745
9775
|
|
|
9746
9776
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9747
|
-
import
|
|
9777
|
+
import chalk113 from "chalk";
|
|
9748
9778
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9749
9779
|
function validateStagedContent(filename, content) {
|
|
9750
9780
|
const firstLine = content.split("\n")[0];
|
|
9751
9781
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9752
9782
|
if (!match) {
|
|
9753
9783
|
console.error(
|
|
9754
|
-
|
|
9784
|
+
chalk113.red(
|
|
9755
9785
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9756
9786
|
)
|
|
9757
9787
|
);
|
|
@@ -9760,7 +9790,7 @@ function validateStagedContent(filename, content) {
|
|
|
9760
9790
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9761
9791
|
if (!contentAfterLink) {
|
|
9762
9792
|
console.error(
|
|
9763
|
-
|
|
9793
|
+
chalk113.red(
|
|
9764
9794
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9765
9795
|
)
|
|
9766
9796
|
);
|
|
@@ -9772,7 +9802,7 @@ function validateStagedContent(filename, content) {
|
|
|
9772
9802
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
9773
9803
|
var STAGING_DIR = join30(process.cwd(), ".assist", "transcript");
|
|
9774
9804
|
function processStagedFile() {
|
|
9775
|
-
if (!
|
|
9805
|
+
if (!existsSync35(STAGING_DIR)) {
|
|
9776
9806
|
return false;
|
|
9777
9807
|
}
|
|
9778
9808
|
const stagedFiles = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -9781,7 +9811,7 @@ function processStagedFile() {
|
|
|
9781
9811
|
}
|
|
9782
9812
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
9783
9813
|
const stagedFile = stagedFiles[0];
|
|
9784
|
-
const content =
|
|
9814
|
+
const content = readFileSync27(stagedFile.absolutePath, "utf-8");
|
|
9785
9815
|
validateStagedContent(stagedFile.filename, content);
|
|
9786
9816
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
9787
9817
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -9796,7 +9826,7 @@ function processStagedFile() {
|
|
|
9796
9826
|
}
|
|
9797
9827
|
const destPath = join30(summaryDir, matchingTranscript.relativePath);
|
|
9798
9828
|
const destDir = dirname20(destPath);
|
|
9799
|
-
if (!
|
|
9829
|
+
if (!existsSync35(destDir)) {
|
|
9800
9830
|
mkdirSync8(destDir, { recursive: true });
|
|
9801
9831
|
}
|
|
9802
9832
|
renameSync2(stagedFile.absolutePath, destPath);
|
|
@@ -9823,7 +9853,7 @@ function buildSummaryIndex(summaryDir) {
|
|
|
9823
9853
|
function summarise2() {
|
|
9824
9854
|
processStagedFile();
|
|
9825
9855
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
9826
|
-
if (!
|
|
9856
|
+
if (!existsSync36(transcriptsDir)) {
|
|
9827
9857
|
console.log("No transcripts directory found.");
|
|
9828
9858
|
return;
|
|
9829
9859
|
}
|
|
@@ -9927,14 +9957,14 @@ function devices() {
|
|
|
9927
9957
|
}
|
|
9928
9958
|
|
|
9929
9959
|
// src/commands/voice/logs.ts
|
|
9930
|
-
import { existsSync as
|
|
9960
|
+
import { existsSync as existsSync37, readFileSync as readFileSync28 } from "fs";
|
|
9931
9961
|
function logs(options2) {
|
|
9932
|
-
if (!
|
|
9962
|
+
if (!existsSync37(voicePaths.log)) {
|
|
9933
9963
|
console.log("No voice log file found");
|
|
9934
9964
|
return;
|
|
9935
9965
|
}
|
|
9936
9966
|
const count = Number.parseInt(options2.lines ?? "150", 10);
|
|
9937
|
-
const content =
|
|
9967
|
+
const content = readFileSync28(voicePaths.log, "utf-8").trim();
|
|
9938
9968
|
if (!content) {
|
|
9939
9969
|
console.log("Voice log is empty");
|
|
9940
9970
|
return;
|
|
@@ -9961,7 +9991,7 @@ import { join as join35 } from "path";
|
|
|
9961
9991
|
|
|
9962
9992
|
// src/commands/voice/checkLockFile.ts
|
|
9963
9993
|
import { execSync as execSync37 } from "child_process";
|
|
9964
|
-
import { existsSync as
|
|
9994
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync9, readFileSync as readFileSync29, writeFileSync as writeFileSync25 } from "fs";
|
|
9965
9995
|
import { join as join34 } from "path";
|
|
9966
9996
|
function isProcessAlive2(pid) {
|
|
9967
9997
|
try {
|
|
@@ -9973,9 +10003,9 @@ function isProcessAlive2(pid) {
|
|
|
9973
10003
|
}
|
|
9974
10004
|
function checkLockFile() {
|
|
9975
10005
|
const lockFile = getLockFile();
|
|
9976
|
-
if (!
|
|
10006
|
+
if (!existsSync38(lockFile)) return;
|
|
9977
10007
|
try {
|
|
9978
|
-
const lock = JSON.parse(
|
|
10008
|
+
const lock = JSON.parse(readFileSync29(lockFile, "utf-8"));
|
|
9979
10009
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
9980
10010
|
console.error(
|
|
9981
10011
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -9986,7 +10016,7 @@ function checkLockFile() {
|
|
|
9986
10016
|
}
|
|
9987
10017
|
}
|
|
9988
10018
|
function bootstrapVenv() {
|
|
9989
|
-
if (
|
|
10019
|
+
if (existsSync38(getVenvPython())) return;
|
|
9990
10020
|
console.log("Setting up Python environment...");
|
|
9991
10021
|
const pythonDir = getPythonDir();
|
|
9992
10022
|
execSync37(
|
|
@@ -10077,7 +10107,7 @@ function start2(options2) {
|
|
|
10077
10107
|
}
|
|
10078
10108
|
|
|
10079
10109
|
// src/commands/voice/status.ts
|
|
10080
|
-
import { existsSync as
|
|
10110
|
+
import { existsSync as existsSync39, readFileSync as readFileSync30 } from "fs";
|
|
10081
10111
|
function isProcessAlive3(pid) {
|
|
10082
10112
|
try {
|
|
10083
10113
|
process.kill(pid, 0);
|
|
@@ -10087,16 +10117,16 @@ function isProcessAlive3(pid) {
|
|
|
10087
10117
|
}
|
|
10088
10118
|
}
|
|
10089
10119
|
function readRecentLogs(count) {
|
|
10090
|
-
if (!
|
|
10091
|
-
const lines =
|
|
10120
|
+
if (!existsSync39(voicePaths.log)) return [];
|
|
10121
|
+
const lines = readFileSync30(voicePaths.log, "utf-8").trim().split("\n");
|
|
10092
10122
|
return lines.slice(-count);
|
|
10093
10123
|
}
|
|
10094
10124
|
function status() {
|
|
10095
|
-
if (!
|
|
10125
|
+
if (!existsSync39(voicePaths.pid)) {
|
|
10096
10126
|
console.log("Voice daemon: not running (no PID file)");
|
|
10097
10127
|
return;
|
|
10098
10128
|
}
|
|
10099
|
-
const pid = Number.parseInt(
|
|
10129
|
+
const pid = Number.parseInt(readFileSync30(voicePaths.pid, "utf-8").trim(), 10);
|
|
10100
10130
|
const alive = isProcessAlive3(pid);
|
|
10101
10131
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
10102
10132
|
const recent = readRecentLogs(5);
|
|
@@ -10115,13 +10145,13 @@ function status() {
|
|
|
10115
10145
|
}
|
|
10116
10146
|
|
|
10117
10147
|
// src/commands/voice/stop.ts
|
|
10118
|
-
import { existsSync as
|
|
10148
|
+
import { existsSync as existsSync40, readFileSync as readFileSync31, unlinkSync as unlinkSync10 } from "fs";
|
|
10119
10149
|
function stop() {
|
|
10120
|
-
if (!
|
|
10150
|
+
if (!existsSync40(voicePaths.pid)) {
|
|
10121
10151
|
console.log("Voice daemon is not running (no PID file)");
|
|
10122
10152
|
return;
|
|
10123
10153
|
}
|
|
10124
|
-
const pid = Number.parseInt(
|
|
10154
|
+
const pid = Number.parseInt(readFileSync31(voicePaths.pid, "utf-8").trim(), 10);
|
|
10125
10155
|
try {
|
|
10126
10156
|
process.kill(pid, "SIGTERM");
|
|
10127
10157
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -10134,7 +10164,7 @@ function stop() {
|
|
|
10134
10164
|
}
|
|
10135
10165
|
try {
|
|
10136
10166
|
const lockFile = getLockFile();
|
|
10137
|
-
if (
|
|
10167
|
+
if (existsSync40(lockFile)) unlinkSync10(lockFile);
|
|
10138
10168
|
} catch {
|
|
10139
10169
|
}
|
|
10140
10170
|
console.log("Voice daemon stopped");
|
|
@@ -10153,7 +10183,7 @@ function registerVoice(program2) {
|
|
|
10153
10183
|
|
|
10154
10184
|
// src/commands/roam/auth.ts
|
|
10155
10185
|
import { randomBytes } from "crypto";
|
|
10156
|
-
import
|
|
10186
|
+
import chalk114 from "chalk";
|
|
10157
10187
|
|
|
10158
10188
|
// src/lib/openBrowser.ts
|
|
10159
10189
|
import { execSync as execSync38 } from "child_process";
|
|
@@ -10328,13 +10358,13 @@ async function auth() {
|
|
|
10328
10358
|
saveGlobalConfig(config);
|
|
10329
10359
|
const state = randomBytes(16).toString("hex");
|
|
10330
10360
|
console.log(
|
|
10331
|
-
|
|
10361
|
+
chalk114.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
10332
10362
|
);
|
|
10333
|
-
console.log(
|
|
10334
|
-
console.log(
|
|
10335
|
-
console.log(
|
|
10363
|
+
console.log(chalk114.white("http://localhost:14523/callback\n"));
|
|
10364
|
+
console.log(chalk114.blue("Opening browser for authorization..."));
|
|
10365
|
+
console.log(chalk114.dim("Waiting for authorization callback..."));
|
|
10336
10366
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
10337
|
-
console.log(
|
|
10367
|
+
console.log(chalk114.dim("Exchanging code for tokens..."));
|
|
10338
10368
|
const tokens = await exchangeToken({
|
|
10339
10369
|
code,
|
|
10340
10370
|
clientId,
|
|
@@ -10350,12 +10380,12 @@ async function auth() {
|
|
|
10350
10380
|
};
|
|
10351
10381
|
saveGlobalConfig(config);
|
|
10352
10382
|
console.log(
|
|
10353
|
-
|
|
10383
|
+
chalk114.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
10354
10384
|
);
|
|
10355
10385
|
}
|
|
10356
10386
|
|
|
10357
10387
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
10358
|
-
import { readFileSync as
|
|
10388
|
+
import { readFileSync as readFileSync32 } from "fs";
|
|
10359
10389
|
import { join as join37 } from "path";
|
|
10360
10390
|
async function showClaudeCodeIcon() {
|
|
10361
10391
|
const appData = process.env.APPDATA;
|
|
@@ -10363,7 +10393,7 @@ async function showClaudeCodeIcon() {
|
|
|
10363
10393
|
const portFile = join37(appData, "Roam", "roam-local-api.port");
|
|
10364
10394
|
let port;
|
|
10365
10395
|
try {
|
|
10366
|
-
port =
|
|
10396
|
+
port = readFileSync32(portFile, "utf-8").trim();
|
|
10367
10397
|
} catch {
|
|
10368
10398
|
return;
|
|
10369
10399
|
}
|
|
@@ -10560,10 +10590,10 @@ function run3(name, args) {
|
|
|
10560
10590
|
|
|
10561
10591
|
// src/commands/screenshot/index.ts
|
|
10562
10592
|
import { execSync as execSync40 } from "child_process";
|
|
10563
|
-
import { existsSync as
|
|
10593
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync13, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10564
10594
|
import { tmpdir as tmpdir6 } from "os";
|
|
10565
10595
|
import { join as join39, resolve as resolve5 } from "path";
|
|
10566
|
-
import
|
|
10596
|
+
import chalk115 from "chalk";
|
|
10567
10597
|
|
|
10568
10598
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10569
10599
|
var captureWindowPs1 = `
|
|
@@ -10692,7 +10722,7 @@ Write-Output $OutputPath
|
|
|
10692
10722
|
|
|
10693
10723
|
// src/commands/screenshot/index.ts
|
|
10694
10724
|
function buildOutputPath(outputDir, processName) {
|
|
10695
|
-
if (!
|
|
10725
|
+
if (!existsSync41(outputDir)) {
|
|
10696
10726
|
mkdirSync13(outputDir, { recursive: true });
|
|
10697
10727
|
}
|
|
10698
10728
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -10714,22 +10744,22 @@ function screenshot(processName) {
|
|
|
10714
10744
|
const config = loadConfig();
|
|
10715
10745
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10716
10746
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10717
|
-
console.log(
|
|
10747
|
+
console.log(chalk115.gray(`Capturing window for process "${processName}" ...`));
|
|
10718
10748
|
try {
|
|
10719
10749
|
runPowerShellScript(processName, outputPath);
|
|
10720
|
-
console.log(
|
|
10750
|
+
console.log(chalk115.green(`Screenshot saved: ${outputPath}`));
|
|
10721
10751
|
} catch (error) {
|
|
10722
10752
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10723
|
-
console.error(
|
|
10753
|
+
console.error(chalk115.red(`Failed to capture screenshot: ${msg}`));
|
|
10724
10754
|
process.exit(1);
|
|
10725
10755
|
}
|
|
10726
10756
|
}
|
|
10727
10757
|
|
|
10728
10758
|
// src/commands/statusLine.ts
|
|
10729
|
-
import
|
|
10759
|
+
import chalk117 from "chalk";
|
|
10730
10760
|
|
|
10731
10761
|
// src/commands/buildLimitsSegment.ts
|
|
10732
|
-
import
|
|
10762
|
+
import chalk116 from "chalk";
|
|
10733
10763
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10734
10764
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10735
10765
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10752,10 +10782,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10752
10782
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10753
10783
|
const label2 = `${Math.round(pct)}%`;
|
|
10754
10784
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10755
|
-
if (projected == null) return
|
|
10756
|
-
if (projected > 100) return
|
|
10757
|
-
if (projected > 75) return
|
|
10758
|
-
return
|
|
10785
|
+
if (projected == null) return chalk116.green(label2);
|
|
10786
|
+
if (projected > 100) return chalk116.red(label2);
|
|
10787
|
+
if (projected > 75) return chalk116.yellow(label2);
|
|
10788
|
+
return chalk116.green(label2);
|
|
10759
10789
|
}
|
|
10760
10790
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10761
10791
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10781,14 +10811,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10781
10811
|
}
|
|
10782
10812
|
|
|
10783
10813
|
// src/commands/statusLine.ts
|
|
10784
|
-
|
|
10814
|
+
chalk117.level = 3;
|
|
10785
10815
|
function formatNumber(num) {
|
|
10786
10816
|
return num.toLocaleString("en-US");
|
|
10787
10817
|
}
|
|
10788
10818
|
function colorizePercent(pct) {
|
|
10789
10819
|
const label2 = `${Math.round(pct)}%`;
|
|
10790
|
-
if (pct > 80) return
|
|
10791
|
-
if (pct > 40) return
|
|
10820
|
+
if (pct > 80) return chalk117.red(label2);
|
|
10821
|
+
if (pct > 40) return chalk117.yellow(label2);
|
|
10792
10822
|
return label2;
|
|
10793
10823
|
}
|
|
10794
10824
|
async function statusLine() {
|
|
@@ -10811,7 +10841,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10811
10841
|
// src/commands/sync/syncClaudeMd.ts
|
|
10812
10842
|
import * as fs23 from "fs";
|
|
10813
10843
|
import * as path46 from "path";
|
|
10814
|
-
import
|
|
10844
|
+
import chalk118 from "chalk";
|
|
10815
10845
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10816
10846
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10817
10847
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10820,12 +10850,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10820
10850
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10821
10851
|
if (sourceContent !== targetContent) {
|
|
10822
10852
|
console.log(
|
|
10823
|
-
|
|
10853
|
+
chalk118.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10824
10854
|
);
|
|
10825
10855
|
console.log();
|
|
10826
10856
|
printDiff(targetContent, sourceContent);
|
|
10827
10857
|
const confirm = options2?.yes || await promptConfirm(
|
|
10828
|
-
|
|
10858
|
+
chalk118.red("Overwrite existing CLAUDE.md?"),
|
|
10829
10859
|
false
|
|
10830
10860
|
);
|
|
10831
10861
|
if (!confirm) {
|
|
@@ -10841,7 +10871,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10841
10871
|
// src/commands/sync/syncSettings.ts
|
|
10842
10872
|
import * as fs24 from "fs";
|
|
10843
10873
|
import * as path47 from "path";
|
|
10844
|
-
import
|
|
10874
|
+
import chalk119 from "chalk";
|
|
10845
10875
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10846
10876
|
const source = path47.join(claudeDir, "settings.json");
|
|
10847
10877
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10857,14 +10887,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10857
10887
|
if (mergedContent !== normalizedTarget) {
|
|
10858
10888
|
if (!options2?.yes) {
|
|
10859
10889
|
console.log(
|
|
10860
|
-
|
|
10890
|
+
chalk119.yellow(
|
|
10861
10891
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10862
10892
|
)
|
|
10863
10893
|
);
|
|
10864
10894
|
console.log();
|
|
10865
10895
|
printDiff(targetContent, mergedContent);
|
|
10866
10896
|
const confirm = await promptConfirm(
|
|
10867
|
-
|
|
10897
|
+
chalk119.red("Overwrite existing settings.json?"),
|
|
10868
10898
|
false
|
|
10869
10899
|
);
|
|
10870
10900
|
if (!confirm) {
|