@staff0rd/assist 0.151.1 → 0.152.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +375 -359
- 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.152.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -3081,7 +3081,21 @@ async function notify() {
|
|
|
3081
3081
|
|
|
3082
3082
|
// src/commands/backlog/add/index.ts
|
|
3083
3083
|
import { existsSync as existsSync15 } from "fs";
|
|
3084
|
+
import chalk40 from "chalk";
|
|
3085
|
+
|
|
3086
|
+
// src/commands/backlog/commitBacklog.ts
|
|
3087
|
+
import { execSync as execSync14 } from "child_process";
|
|
3084
3088
|
import chalk39 from "chalk";
|
|
3089
|
+
function commitBacklog(id, name) {
|
|
3090
|
+
try {
|
|
3091
|
+
const backlogPath = getBacklogPath();
|
|
3092
|
+
const message = `chore: add backlog item #${id} \u2014 ${name}`;
|
|
3093
|
+
execSync14(`git add ${shellQuote(backlogPath)}`, { stdio: "ignore" });
|
|
3094
|
+
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3095
|
+
} catch {
|
|
3096
|
+
console.log(chalk39.yellow("Warning: could not auto-commit backlog file."));
|
|
3097
|
+
}
|
|
3098
|
+
}
|
|
3085
3099
|
|
|
3086
3100
|
// src/commands/backlog/add/shared.ts
|
|
3087
3101
|
import { spawnSync } from "child_process";
|
|
@@ -3157,7 +3171,7 @@ async function promptAcceptanceCriteria() {
|
|
|
3157
3171
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3158
3172
|
async function addFromJson() {
|
|
3159
3173
|
if (process.stdin.isTTY) {
|
|
3160
|
-
console.log(
|
|
3174
|
+
console.log(chalk40.red("--json requires piped input on stdin."));
|
|
3161
3175
|
return;
|
|
3162
3176
|
}
|
|
3163
3177
|
const input = await readStdin();
|
|
@@ -3170,7 +3184,8 @@ async function addFromJson() {
|
|
|
3170
3184
|
const id = getNextId(items);
|
|
3171
3185
|
items.push({ ...data, id, status: "todo" });
|
|
3172
3186
|
saveBacklog(items);
|
|
3173
|
-
|
|
3187
|
+
commitBacklog(id, data.name);
|
|
3188
|
+
console.log(chalk40.green(`Added item #${id}: ${data.name}`));
|
|
3174
3189
|
}
|
|
3175
3190
|
async function addInteractive() {
|
|
3176
3191
|
const type = await promptType();
|
|
@@ -3188,12 +3203,13 @@ async function addInteractive() {
|
|
|
3188
3203
|
status: "todo"
|
|
3189
3204
|
});
|
|
3190
3205
|
saveBacklog(items);
|
|
3191
|
-
|
|
3206
|
+
commitBacklog(id, name);
|
|
3207
|
+
console.log(chalk40.green(`Added item #${id}: ${name}`));
|
|
3192
3208
|
}
|
|
3193
3209
|
async function add(options2) {
|
|
3194
3210
|
if (!existsSync15(getBacklogPath())) {
|
|
3195
3211
|
console.log(
|
|
3196
|
-
|
|
3212
|
+
chalk40.yellow(
|
|
3197
3213
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3198
3214
|
)
|
|
3199
3215
|
);
|
|
@@ -3208,20 +3224,20 @@ async function add(options2) {
|
|
|
3208
3224
|
|
|
3209
3225
|
// src/commands/backlog/init/index.ts
|
|
3210
3226
|
import { existsSync as existsSync16 } from "fs";
|
|
3211
|
-
import
|
|
3227
|
+
import chalk41 from "chalk";
|
|
3212
3228
|
async function init6() {
|
|
3213
3229
|
const backlogPath = getBacklogPath();
|
|
3214
3230
|
if (existsSync16(backlogPath)) {
|
|
3215
|
-
console.log(
|
|
3231
|
+
console.log(chalk41.yellow("assist.backlog.yml already exists."));
|
|
3216
3232
|
return;
|
|
3217
3233
|
}
|
|
3218
3234
|
saveBacklog([]);
|
|
3219
|
-
console.log(
|
|
3235
|
+
console.log(chalk41.green("Created assist.backlog.yml"));
|
|
3220
3236
|
}
|
|
3221
3237
|
|
|
3222
3238
|
// src/commands/backlog/list/index.ts
|
|
3223
3239
|
import { existsSync as existsSync17 } from "fs";
|
|
3224
|
-
import
|
|
3240
|
+
import chalk42 from "chalk";
|
|
3225
3241
|
function filterItems(items, options2) {
|
|
3226
3242
|
if (options2.status) return items.filter((i) => i.status === options2.status);
|
|
3227
3243
|
if (!options2.all) return items.filter((i) => i.status !== "done");
|
|
@@ -3230,7 +3246,7 @@ function filterItems(items, options2) {
|
|
|
3230
3246
|
async function list2(options2) {
|
|
3231
3247
|
if (!existsSync17(getBacklogPath())) {
|
|
3232
3248
|
console.log(
|
|
3233
|
-
|
|
3249
|
+
chalk42.yellow(
|
|
3234
3250
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3235
3251
|
)
|
|
3236
3252
|
);
|
|
@@ -3238,12 +3254,12 @@ async function list2(options2) {
|
|
|
3238
3254
|
}
|
|
3239
3255
|
const items = filterItems(loadBacklog(), options2);
|
|
3240
3256
|
if (items.length === 0) {
|
|
3241
|
-
console.log(
|
|
3257
|
+
console.log(chalk42.dim("Backlog is empty."));
|
|
3242
3258
|
return;
|
|
3243
3259
|
}
|
|
3244
3260
|
for (const item of items) {
|
|
3245
3261
|
console.log(
|
|
3246
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
3262
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk42.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}`
|
|
3247
3263
|
);
|
|
3248
3264
|
if (options2.verbose) {
|
|
3249
3265
|
printVerboseDetails(item);
|
|
@@ -3597,7 +3613,7 @@ import { homedir as homedir4 } from "os";
|
|
|
3597
3613
|
import { join as join13 } from "path";
|
|
3598
3614
|
|
|
3599
3615
|
// src/shared/getInstallDir.ts
|
|
3600
|
-
import { execSync as
|
|
3616
|
+
import { execSync as execSync15 } from "child_process";
|
|
3601
3617
|
import { dirname as dirname15, resolve as resolve4 } from "path";
|
|
3602
3618
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
3603
3619
|
var __filename3 = fileURLToPath5(import.meta.url);
|
|
@@ -3607,7 +3623,7 @@ function getInstallDir() {
|
|
|
3607
3623
|
}
|
|
3608
3624
|
function isGitRepo(dir) {
|
|
3609
3625
|
try {
|
|
3610
|
-
const result =
|
|
3626
|
+
const result = execSync15("git rev-parse --show-toplevel", {
|
|
3611
3627
|
cwd: dir,
|
|
3612
3628
|
stdio: "pipe"
|
|
3613
3629
|
}).toString().trim();
|
|
@@ -3618,7 +3634,7 @@ function isGitRepo(dir) {
|
|
|
3618
3634
|
}
|
|
3619
3635
|
|
|
3620
3636
|
// src/commands/permitCliReads/assertCliExists.ts
|
|
3621
|
-
import { execSync as
|
|
3637
|
+
import { execSync as execSync16 } from "child_process";
|
|
3622
3638
|
function assertCliExists(cli) {
|
|
3623
3639
|
const binary = cli.split(/\s+/)[0];
|
|
3624
3640
|
const opts = {
|
|
@@ -3626,10 +3642,10 @@ function assertCliExists(cli) {
|
|
|
3626
3642
|
stdio: ["ignore", "pipe", "pipe"]
|
|
3627
3643
|
};
|
|
3628
3644
|
try {
|
|
3629
|
-
|
|
3645
|
+
execSync16(`command -v ${binary}`, opts);
|
|
3630
3646
|
} catch {
|
|
3631
3647
|
try {
|
|
3632
|
-
|
|
3648
|
+
execSync16(`where ${binary}`, opts);
|
|
3633
3649
|
} catch {
|
|
3634
3650
|
console.error(`CLI "${cli}" not found in PATH`);
|
|
3635
3651
|
process.exit(1);
|
|
@@ -3638,11 +3654,11 @@ function assertCliExists(cli) {
|
|
|
3638
3654
|
}
|
|
3639
3655
|
|
|
3640
3656
|
// src/commands/permitCliReads/colorize.ts
|
|
3641
|
-
import
|
|
3657
|
+
import chalk43 from "chalk";
|
|
3642
3658
|
function colorize(plainOutput) {
|
|
3643
3659
|
return plainOutput.split("\n").map((line) => {
|
|
3644
|
-
if (line.startsWith(" R ")) return
|
|
3645
|
-
if (line.startsWith(" W ")) return
|
|
3660
|
+
if (line.startsWith(" R ")) return chalk43.green(line);
|
|
3661
|
+
if (line.startsWith(" W ")) return chalk43.red(line);
|
|
3646
3662
|
return line;
|
|
3647
3663
|
}).join("\n");
|
|
3648
3664
|
}
|
|
@@ -3956,15 +3972,15 @@ function registerCliHook(program2) {
|
|
|
3956
3972
|
}
|
|
3957
3973
|
|
|
3958
3974
|
// src/commands/complexity/analyze.ts
|
|
3959
|
-
import
|
|
3975
|
+
import chalk49 from "chalk";
|
|
3960
3976
|
|
|
3961
3977
|
// src/commands/complexity/cyclomatic.ts
|
|
3962
|
-
import
|
|
3978
|
+
import chalk45 from "chalk";
|
|
3963
3979
|
|
|
3964
3980
|
// src/commands/complexity/shared/index.ts
|
|
3965
3981
|
import fs12 from "fs";
|
|
3966
3982
|
import path20 from "path";
|
|
3967
|
-
import
|
|
3983
|
+
import chalk44 from "chalk";
|
|
3968
3984
|
import ts5 from "typescript";
|
|
3969
3985
|
|
|
3970
3986
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4210,7 +4226,7 @@ function createSourceFromFile(filePath) {
|
|
|
4210
4226
|
function withSourceFiles(pattern2, callback) {
|
|
4211
4227
|
const files = findSourceFiles2(pattern2);
|
|
4212
4228
|
if (files.length === 0) {
|
|
4213
|
-
console.log(
|
|
4229
|
+
console.log(chalk44.yellow("No files found matching pattern"));
|
|
4214
4230
|
return void 0;
|
|
4215
4231
|
}
|
|
4216
4232
|
return callback(files);
|
|
@@ -4243,11 +4259,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4243
4259
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4244
4260
|
for (const { file, name, complexity } of results) {
|
|
4245
4261
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4246
|
-
const color = exceedsThreshold ?
|
|
4247
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4262
|
+
const color = exceedsThreshold ? chalk45.red : chalk45.white;
|
|
4263
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk45.cyan(complexity)}`);
|
|
4248
4264
|
}
|
|
4249
4265
|
console.log(
|
|
4250
|
-
|
|
4266
|
+
chalk45.dim(
|
|
4251
4267
|
`
|
|
4252
4268
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4253
4269
|
)
|
|
@@ -4259,7 +4275,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4259
4275
|
}
|
|
4260
4276
|
|
|
4261
4277
|
// src/commands/complexity/halstead.ts
|
|
4262
|
-
import
|
|
4278
|
+
import chalk46 from "chalk";
|
|
4263
4279
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4264
4280
|
withSourceFiles(pattern2, (files) => {
|
|
4265
4281
|
const results = [];
|
|
@@ -4274,13 +4290,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4274
4290
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4275
4291
|
for (const { file, name, metrics } of results) {
|
|
4276
4292
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4277
|
-
const color = exceedsThreshold ?
|
|
4293
|
+
const color = exceedsThreshold ? chalk46.red : chalk46.white;
|
|
4278
4294
|
console.log(
|
|
4279
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4295
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk46.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk46.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk46.magenta(metrics.effort.toFixed(1))}`
|
|
4280
4296
|
);
|
|
4281
4297
|
}
|
|
4282
4298
|
console.log(
|
|
4283
|
-
|
|
4299
|
+
chalk46.dim(
|
|
4284
4300
|
`
|
|
4285
4301
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4286
4302
|
)
|
|
@@ -4295,28 +4311,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4295
4311
|
import fs13 from "fs";
|
|
4296
4312
|
|
|
4297
4313
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4298
|
-
import
|
|
4314
|
+
import chalk47 from "chalk";
|
|
4299
4315
|
function displayMaintainabilityResults(results, threshold) {
|
|
4300
4316
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4301
4317
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4302
|
-
console.log(
|
|
4318
|
+
console.log(chalk47.green("All files pass maintainability threshold"));
|
|
4303
4319
|
} else {
|
|
4304
4320
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4305
|
-
const color = threshold !== void 0 ?
|
|
4321
|
+
const color = threshold !== void 0 ? chalk47.red : chalk47.white;
|
|
4306
4322
|
console.log(
|
|
4307
|
-
`${color(file)} \u2192 avg: ${
|
|
4323
|
+
`${color(file)} \u2192 avg: ${chalk47.cyan(avgMaintainability.toFixed(1))}, min: ${chalk47.yellow(minMaintainability.toFixed(1))}`
|
|
4308
4324
|
);
|
|
4309
4325
|
}
|
|
4310
4326
|
}
|
|
4311
|
-
console.log(
|
|
4327
|
+
console.log(chalk47.dim(`
|
|
4312
4328
|
Analyzed ${results.length} files`));
|
|
4313
4329
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4314
4330
|
console.error(
|
|
4315
|
-
|
|
4331
|
+
chalk47.red(
|
|
4316
4332
|
`
|
|
4317
4333
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4318
4334
|
|
|
4319
|
-
\u26A0\uFE0F ${
|
|
4335
|
+
\u26A0\uFE0F ${chalk47.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.`
|
|
4320
4336
|
)
|
|
4321
4337
|
);
|
|
4322
4338
|
process.exit(1);
|
|
@@ -4373,7 +4389,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4373
4389
|
|
|
4374
4390
|
// src/commands/complexity/sloc.ts
|
|
4375
4391
|
import fs14 from "fs";
|
|
4376
|
-
import
|
|
4392
|
+
import chalk48 from "chalk";
|
|
4377
4393
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4378
4394
|
withSourceFiles(pattern2, (files) => {
|
|
4379
4395
|
const results = [];
|
|
@@ -4389,12 +4405,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4389
4405
|
results.sort((a, b) => b.lines - a.lines);
|
|
4390
4406
|
for (const { file, lines } of results) {
|
|
4391
4407
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4392
|
-
const color = exceedsThreshold ?
|
|
4393
|
-
console.log(`${color(file)} \u2192 ${
|
|
4408
|
+
const color = exceedsThreshold ? chalk48.red : chalk48.white;
|
|
4409
|
+
console.log(`${color(file)} \u2192 ${chalk48.cyan(lines)} lines`);
|
|
4394
4410
|
}
|
|
4395
4411
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4396
4412
|
console.log(
|
|
4397
|
-
|
|
4413
|
+
chalk48.dim(`
|
|
4398
4414
|
Total: ${total} lines across ${files.length} files`)
|
|
4399
4415
|
);
|
|
4400
4416
|
if (hasViolation) {
|
|
@@ -4408,21 +4424,21 @@ async function analyze(pattern2) {
|
|
|
4408
4424
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4409
4425
|
const files = findSourceFiles2(searchPattern);
|
|
4410
4426
|
if (files.length === 0) {
|
|
4411
|
-
console.log(
|
|
4427
|
+
console.log(chalk49.yellow("No files found matching pattern"));
|
|
4412
4428
|
return;
|
|
4413
4429
|
}
|
|
4414
4430
|
if (files.length === 1) {
|
|
4415
4431
|
const file = files[0];
|
|
4416
|
-
console.log(
|
|
4432
|
+
console.log(chalk49.bold.underline("SLOC"));
|
|
4417
4433
|
await sloc(file);
|
|
4418
4434
|
console.log();
|
|
4419
|
-
console.log(
|
|
4435
|
+
console.log(chalk49.bold.underline("Cyclomatic Complexity"));
|
|
4420
4436
|
await cyclomatic(file);
|
|
4421
4437
|
console.log();
|
|
4422
|
-
console.log(
|
|
4438
|
+
console.log(chalk49.bold.underline("Halstead Metrics"));
|
|
4423
4439
|
await halstead(file);
|
|
4424
4440
|
console.log();
|
|
4425
|
-
console.log(
|
|
4441
|
+
console.log(chalk49.bold.underline("Maintainability Index"));
|
|
4426
4442
|
await maintainability(file);
|
|
4427
4443
|
return;
|
|
4428
4444
|
}
|
|
@@ -4450,7 +4466,7 @@ function registerComplexity(program2) {
|
|
|
4450
4466
|
|
|
4451
4467
|
// src/commands/deploy/redirect.ts
|
|
4452
4468
|
import { existsSync as existsSync21, readFileSync as readFileSync16, writeFileSync as writeFileSync16 } from "fs";
|
|
4453
|
-
import
|
|
4469
|
+
import chalk50 from "chalk";
|
|
4454
4470
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4455
4471
|
if (!window.location.pathname.endsWith('/')) {
|
|
4456
4472
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4459,22 +4475,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4459
4475
|
function redirect() {
|
|
4460
4476
|
const indexPath = "index.html";
|
|
4461
4477
|
if (!existsSync21(indexPath)) {
|
|
4462
|
-
console.log(
|
|
4478
|
+
console.log(chalk50.yellow("No index.html found"));
|
|
4463
4479
|
return;
|
|
4464
4480
|
}
|
|
4465
4481
|
const content = readFileSync16(indexPath, "utf-8");
|
|
4466
4482
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4467
|
-
console.log(
|
|
4483
|
+
console.log(chalk50.dim("Trailing slash script already present"));
|
|
4468
4484
|
return;
|
|
4469
4485
|
}
|
|
4470
4486
|
const headCloseIndex = content.indexOf("</head>");
|
|
4471
4487
|
if (headCloseIndex === -1) {
|
|
4472
|
-
console.log(
|
|
4488
|
+
console.log(chalk50.red("Could not find </head> tag in index.html"));
|
|
4473
4489
|
return;
|
|
4474
4490
|
}
|
|
4475
4491
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4476
4492
|
writeFileSync16(indexPath, newContent);
|
|
4477
|
-
console.log(
|
|
4493
|
+
console.log(chalk50.green("Added trailing slash redirect to index.html"));
|
|
4478
4494
|
}
|
|
4479
4495
|
|
|
4480
4496
|
// src/commands/registerDeploy.ts
|
|
@@ -4485,7 +4501,7 @@ function registerDeploy(program2) {
|
|
|
4485
4501
|
}
|
|
4486
4502
|
|
|
4487
4503
|
// src/commands/devlog/list/index.ts
|
|
4488
|
-
import { execSync as
|
|
4504
|
+
import { execSync as execSync18 } from "child_process";
|
|
4489
4505
|
import { basename as basename3 } from "path";
|
|
4490
4506
|
|
|
4491
4507
|
// src/commands/devlog/loadBlogSkipDays.ts
|
|
@@ -4500,8 +4516,8 @@ function loadBlogSkipDays(repoName) {
|
|
|
4500
4516
|
}
|
|
4501
4517
|
|
|
4502
4518
|
// src/commands/devlog/shared.ts
|
|
4503
|
-
import { execSync as
|
|
4504
|
-
import
|
|
4519
|
+
import { execSync as execSync17 } from "child_process";
|
|
4520
|
+
import chalk51 from "chalk";
|
|
4505
4521
|
|
|
4506
4522
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4507
4523
|
import { readdirSync, readFileSync as readFileSync17 } from "fs";
|
|
@@ -4570,7 +4586,7 @@ function loadAllDevlogLatestDates() {
|
|
|
4570
4586
|
// src/commands/devlog/shared.ts
|
|
4571
4587
|
function getCommitFiles(hash) {
|
|
4572
4588
|
try {
|
|
4573
|
-
const output =
|
|
4589
|
+
const output = execSync17(`git show --name-only --format="" ${hash}`, {
|
|
4574
4590
|
encoding: "utf-8"
|
|
4575
4591
|
});
|
|
4576
4592
|
return output.trim().split("\n").filter(Boolean);
|
|
@@ -4588,13 +4604,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4588
4604
|
}
|
|
4589
4605
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4590
4606
|
for (const commit2 of commits) {
|
|
4591
|
-
console.log(` ${
|
|
4607
|
+
console.log(` ${chalk51.yellow(commit2.hash)} ${commit2.message}`);
|
|
4592
4608
|
if (verbose) {
|
|
4593
4609
|
const visibleFiles = commit2.files.filter(
|
|
4594
4610
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4595
4611
|
);
|
|
4596
4612
|
for (const file of visibleFiles) {
|
|
4597
|
-
console.log(` ${
|
|
4613
|
+
console.log(` ${chalk51.dim(file)}`);
|
|
4598
4614
|
}
|
|
4599
4615
|
}
|
|
4600
4616
|
}
|
|
@@ -4619,15 +4635,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4619
4635
|
}
|
|
4620
4636
|
|
|
4621
4637
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4622
|
-
import
|
|
4638
|
+
import chalk52 from "chalk";
|
|
4623
4639
|
function printDateHeader(date, isSkipped, entries) {
|
|
4624
4640
|
if (isSkipped) {
|
|
4625
|
-
console.log(`${
|
|
4641
|
+
console.log(`${chalk52.bold.blue(date)} ${chalk52.dim("skipped")}`);
|
|
4626
4642
|
} else if (entries && entries.length > 0) {
|
|
4627
|
-
const entryInfo = entries.map((e) => `${
|
|
4628
|
-
console.log(`${
|
|
4643
|
+
const entryInfo = entries.map((e) => `${chalk52.green(e.version)} ${e.title}`).join(" | ");
|
|
4644
|
+
console.log(`${chalk52.bold.blue(date)} ${entryInfo}`);
|
|
4629
4645
|
} else {
|
|
4630
|
-
console.log(`${
|
|
4646
|
+
console.log(`${chalk52.bold.blue(date)} ${chalk52.red("\u26A0 devlog missing")}`);
|
|
4631
4647
|
}
|
|
4632
4648
|
}
|
|
4633
4649
|
|
|
@@ -4641,7 +4657,7 @@ function list3(options2) {
|
|
|
4641
4657
|
const devlogEntries = loadDevlogEntries(repoName);
|
|
4642
4658
|
const reverseFlag = options2.reverse ? "--reverse " : "";
|
|
4643
4659
|
const limitFlag = options2.reverse ? "" : "-n 500 ";
|
|
4644
|
-
const output =
|
|
4660
|
+
const output = execSync18(
|
|
4645
4661
|
`git log ${reverseFlag}${limitFlag}--pretty=format:'%ad|%h|%s' --date=short`,
|
|
4646
4662
|
{ encoding: "utf-8" }
|
|
4647
4663
|
);
|
|
@@ -4667,11 +4683,11 @@ function list3(options2) {
|
|
|
4667
4683
|
}
|
|
4668
4684
|
|
|
4669
4685
|
// src/commands/devlog/getLastVersionInfo.ts
|
|
4670
|
-
import { execSync as
|
|
4686
|
+
import { execSync as execSync19 } from "child_process";
|
|
4671
4687
|
import semver from "semver";
|
|
4672
4688
|
function getVersionAtCommit(hash) {
|
|
4673
4689
|
try {
|
|
4674
|
-
const content =
|
|
4690
|
+
const content = execSync19(`git show ${hash}:package.json`, {
|
|
4675
4691
|
encoding: "utf-8"
|
|
4676
4692
|
});
|
|
4677
4693
|
const pkg = JSON.parse(content);
|
|
@@ -4686,7 +4702,7 @@ function stripToMinor(version2) {
|
|
|
4686
4702
|
}
|
|
4687
4703
|
function getLastVersionInfoFromGit() {
|
|
4688
4704
|
try {
|
|
4689
|
-
const output =
|
|
4705
|
+
const output = execSync19(
|
|
4690
4706
|
"git log -1 --pretty=format:'%ad|%h' --date=short",
|
|
4691
4707
|
{
|
|
4692
4708
|
encoding: "utf-8"
|
|
@@ -4729,25 +4745,25 @@ function bumpVersion(version2, type) {
|
|
|
4729
4745
|
}
|
|
4730
4746
|
|
|
4731
4747
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
4732
|
-
import { execSync as
|
|
4733
|
-
import
|
|
4748
|
+
import { execSync as execSync20 } from "child_process";
|
|
4749
|
+
import chalk54 from "chalk";
|
|
4734
4750
|
|
|
4735
4751
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
4736
|
-
import
|
|
4752
|
+
import chalk53 from "chalk";
|
|
4737
4753
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
4738
4754
|
if (conventional && firstHash) {
|
|
4739
4755
|
const version2 = getVersionAtCommit(firstHash);
|
|
4740
4756
|
if (version2) {
|
|
4741
|
-
console.log(`${
|
|
4757
|
+
console.log(`${chalk53.bold("version:")} ${stripToMinor(version2)}`);
|
|
4742
4758
|
} else {
|
|
4743
|
-
console.log(`${
|
|
4759
|
+
console.log(`${chalk53.bold("version:")} ${chalk53.red("unknown")}`);
|
|
4744
4760
|
}
|
|
4745
4761
|
} else if (patchVersion && minorVersion) {
|
|
4746
4762
|
console.log(
|
|
4747
|
-
`${
|
|
4763
|
+
`${chalk53.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
4748
4764
|
);
|
|
4749
4765
|
} else {
|
|
4750
|
-
console.log(`${
|
|
4766
|
+
console.log(`${chalk53.bold("version:")} v0.1 (initial)`);
|
|
4751
4767
|
}
|
|
4752
4768
|
}
|
|
4753
4769
|
|
|
@@ -4763,7 +4779,7 @@ function findTargetDate(commitsByDate, skipDays) {
|
|
|
4763
4779
|
return Array.from(commitsByDate.keys()).filter((d) => !skipDays.has(d)).sort()[0];
|
|
4764
4780
|
}
|
|
4765
4781
|
function fetchCommitsByDate(ignore2, lastDate) {
|
|
4766
|
-
const output =
|
|
4782
|
+
const output = execSync20(
|
|
4767
4783
|
"git log --pretty=format:'%ad|%h|%s' --date=short -n 500",
|
|
4768
4784
|
{ encoding: "utf-8" }
|
|
4769
4785
|
);
|
|
@@ -4794,16 +4810,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
4794
4810
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
4795
4811
|
}
|
|
4796
4812
|
function logName(repoName) {
|
|
4797
|
-
console.log(`${
|
|
4813
|
+
console.log(`${chalk54.bold("name:")} ${repoName}`);
|
|
4798
4814
|
}
|
|
4799
4815
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
4800
4816
|
logName(ctx.repoName);
|
|
4801
4817
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
4802
|
-
console.log(
|
|
4818
|
+
console.log(chalk54.bold.blue(targetDate));
|
|
4803
4819
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
4804
4820
|
}
|
|
4805
4821
|
function logNoCommits(lastInfo) {
|
|
4806
|
-
console.log(
|
|
4822
|
+
console.log(chalk54.dim(noCommitsMessage(!!lastInfo)));
|
|
4807
4823
|
}
|
|
4808
4824
|
|
|
4809
4825
|
// src/commands/devlog/next/index.ts
|
|
@@ -4841,14 +4857,14 @@ function next2(options2) {
|
|
|
4841
4857
|
}
|
|
4842
4858
|
|
|
4843
4859
|
// src/commands/devlog/repos/index.ts
|
|
4844
|
-
import { execSync as
|
|
4860
|
+
import { execSync as execSync21 } from "child_process";
|
|
4845
4861
|
|
|
4846
4862
|
// src/commands/devlog/repos/printReposTable.ts
|
|
4847
|
-
import
|
|
4863
|
+
import chalk55 from "chalk";
|
|
4848
4864
|
function colorStatus(status2) {
|
|
4849
|
-
if (status2 === "missing") return
|
|
4850
|
-
if (status2 === "outdated") return
|
|
4851
|
-
return
|
|
4865
|
+
if (status2 === "missing") return chalk55.red(status2);
|
|
4866
|
+
if (status2 === "outdated") return chalk55.yellow(status2);
|
|
4867
|
+
return chalk55.green(status2);
|
|
4852
4868
|
}
|
|
4853
4869
|
function formatRow(row, nameWidth) {
|
|
4854
4870
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -4862,8 +4878,8 @@ function printReposTable(rows) {
|
|
|
4862
4878
|
"Last Devlog".padEnd(11),
|
|
4863
4879
|
"Status"
|
|
4864
4880
|
].join(" ");
|
|
4865
|
-
console.log(
|
|
4866
|
-
console.log(
|
|
4881
|
+
console.log(chalk55.dim(header));
|
|
4882
|
+
console.log(chalk55.dim("-".repeat(header.length)));
|
|
4867
4883
|
for (const row of rows) {
|
|
4868
4884
|
console.log(formatRow(row, nameWidth));
|
|
4869
4885
|
}
|
|
@@ -4876,7 +4892,7 @@ function getStatus(lastPush, lastDevlog) {
|
|
|
4876
4892
|
return lastDevlog < lastPush ? "outdated" : "ok";
|
|
4877
4893
|
}
|
|
4878
4894
|
function fetchRepos(days, all) {
|
|
4879
|
-
const json =
|
|
4895
|
+
const json = execSync21(
|
|
4880
4896
|
"gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
|
|
4881
4897
|
{ encoding: "utf-8" }
|
|
4882
4898
|
);
|
|
@@ -4921,14 +4937,14 @@ function repos(options2) {
|
|
|
4921
4937
|
// src/commands/devlog/skip.ts
|
|
4922
4938
|
import { writeFileSync as writeFileSync17 } from "fs";
|
|
4923
4939
|
import { join as join16 } from "path";
|
|
4924
|
-
import
|
|
4940
|
+
import chalk56 from "chalk";
|
|
4925
4941
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
4926
4942
|
function getBlogConfigPath() {
|
|
4927
4943
|
return join16(BLOG_REPO_ROOT, "assist.yml");
|
|
4928
4944
|
}
|
|
4929
4945
|
function skip(date) {
|
|
4930
4946
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
4931
|
-
console.log(
|
|
4947
|
+
console.log(chalk56.red("Invalid date format. Use YYYY-MM-DD"));
|
|
4932
4948
|
process.exit(1);
|
|
4933
4949
|
}
|
|
4934
4950
|
const repoName = getRepoName();
|
|
@@ -4939,7 +4955,7 @@ function skip(date) {
|
|
|
4939
4955
|
const skipDays = skip2[repoName] ?? [];
|
|
4940
4956
|
if (skipDays.includes(date)) {
|
|
4941
4957
|
console.log(
|
|
4942
|
-
|
|
4958
|
+
chalk56.yellow(`${date} is already in skip list for ${repoName}`)
|
|
4943
4959
|
);
|
|
4944
4960
|
return;
|
|
4945
4961
|
}
|
|
@@ -4949,20 +4965,20 @@ function skip(date) {
|
|
|
4949
4965
|
devlog.skip = skip2;
|
|
4950
4966
|
config.devlog = devlog;
|
|
4951
4967
|
writeFileSync17(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
4952
|
-
console.log(
|
|
4968
|
+
console.log(chalk56.green(`Added ${date} to skip list for ${repoName}`));
|
|
4953
4969
|
}
|
|
4954
4970
|
|
|
4955
4971
|
// src/commands/devlog/version.ts
|
|
4956
|
-
import
|
|
4972
|
+
import chalk57 from "chalk";
|
|
4957
4973
|
function version() {
|
|
4958
4974
|
const config = loadConfig();
|
|
4959
4975
|
const name = getRepoName();
|
|
4960
4976
|
const lastInfo = getLastVersionInfo(name, config);
|
|
4961
4977
|
const lastVersion = lastInfo?.version ?? null;
|
|
4962
4978
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
4963
|
-
console.log(`${
|
|
4964
|
-
console.log(`${
|
|
4965
|
-
console.log(`${
|
|
4979
|
+
console.log(`${chalk57.bold("name:")} ${name}`);
|
|
4980
|
+
console.log(`${chalk57.bold("last:")} ${lastVersion ?? chalk57.dim("none")}`);
|
|
4981
|
+
console.log(`${chalk57.bold("next:")} ${nextVersion ?? chalk57.dim("none")}`);
|
|
4966
4982
|
}
|
|
4967
4983
|
|
|
4968
4984
|
// src/commands/registerDevlog.ts
|
|
@@ -4986,7 +5002,7 @@ function registerDevlog(program2) {
|
|
|
4986
5002
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
4987
5003
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
4988
5004
|
import { join as join17 } from "path";
|
|
4989
|
-
import
|
|
5005
|
+
import chalk58 from "chalk";
|
|
4990
5006
|
|
|
4991
5007
|
// src/shared/findRepoRoot.ts
|
|
4992
5008
|
import { existsSync as existsSync22 } from "fs";
|
|
@@ -5049,14 +5065,14 @@ function checkBuildLocks(startDir) {
|
|
|
5049
5065
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5050
5066
|
if (locked) {
|
|
5051
5067
|
console.error(
|
|
5052
|
-
|
|
5068
|
+
chalk58.red("Build output locked (is VS debugging?): ") + locked
|
|
5053
5069
|
);
|
|
5054
5070
|
process.exit(1);
|
|
5055
5071
|
}
|
|
5056
5072
|
}
|
|
5057
5073
|
async function checkBuildLocksCommand() {
|
|
5058
5074
|
checkBuildLocks();
|
|
5059
|
-
console.log(
|
|
5075
|
+
console.log(chalk58.green("No build locks detected"));
|
|
5060
5076
|
}
|
|
5061
5077
|
|
|
5062
5078
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -5155,30 +5171,30 @@ function escapeRegex(s) {
|
|
|
5155
5171
|
}
|
|
5156
5172
|
|
|
5157
5173
|
// src/commands/dotnet/printTree.ts
|
|
5158
|
-
import
|
|
5174
|
+
import chalk59 from "chalk";
|
|
5159
5175
|
function printNodes(nodes, prefix2) {
|
|
5160
5176
|
for (let i = 0; i < nodes.length; i++) {
|
|
5161
5177
|
const isLast = i === nodes.length - 1;
|
|
5162
5178
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5163
5179
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5164
5180
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5165
|
-
const label2 = isMissing ?
|
|
5181
|
+
const label2 = isMissing ? chalk59.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5166
5182
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5167
5183
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5168
5184
|
}
|
|
5169
5185
|
}
|
|
5170
5186
|
function printTree(tree, totalCount, solutions) {
|
|
5171
|
-
console.log(
|
|
5172
|
-
console.log(
|
|
5187
|
+
console.log(chalk59.bold("\nProject Dependency Tree"));
|
|
5188
|
+
console.log(chalk59.cyan(tree.relativePath));
|
|
5173
5189
|
printNodes(tree.children, "");
|
|
5174
|
-
console.log(
|
|
5190
|
+
console.log(chalk59.dim(`
|
|
5175
5191
|
${totalCount} projects total (including root)`));
|
|
5176
|
-
console.log(
|
|
5192
|
+
console.log(chalk59.bold("\nSolution Membership"));
|
|
5177
5193
|
if (solutions.length === 0) {
|
|
5178
|
-
console.log(
|
|
5194
|
+
console.log(chalk59.yellow(" Not found in any .sln"));
|
|
5179
5195
|
} else {
|
|
5180
5196
|
for (const sln of solutions) {
|
|
5181
|
-
console.log(` ${
|
|
5197
|
+
console.log(` ${chalk59.green(sln)}`);
|
|
5182
5198
|
}
|
|
5183
5199
|
}
|
|
5184
5200
|
console.log();
|
|
@@ -5207,16 +5223,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5207
5223
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5208
5224
|
import { existsSync as existsSync23 } from "fs";
|
|
5209
5225
|
import path24 from "path";
|
|
5210
|
-
import
|
|
5226
|
+
import chalk60 from "chalk";
|
|
5211
5227
|
function resolveCsproj(csprojPath) {
|
|
5212
5228
|
const resolved = path24.resolve(csprojPath);
|
|
5213
5229
|
if (!existsSync23(resolved)) {
|
|
5214
|
-
console.error(
|
|
5230
|
+
console.error(chalk60.red(`File not found: ${resolved}`));
|
|
5215
5231
|
process.exit(1);
|
|
5216
5232
|
}
|
|
5217
5233
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5218
5234
|
if (!repoRoot) {
|
|
5219
|
-
console.error(
|
|
5235
|
+
console.error(chalk60.red("Could not find git repository root"));
|
|
5220
5236
|
process.exit(1);
|
|
5221
5237
|
}
|
|
5222
5238
|
return { resolved, repoRoot };
|
|
@@ -5236,7 +5252,7 @@ async function deps(csprojPath, options2) {
|
|
|
5236
5252
|
}
|
|
5237
5253
|
|
|
5238
5254
|
// src/commands/dotnet/getChangedCsFiles.ts
|
|
5239
|
-
import { execSync as
|
|
5255
|
+
import { execSync as execSync22 } from "child_process";
|
|
5240
5256
|
var SCOPE_ALL = "all";
|
|
5241
5257
|
var SCOPE_BASE = "base:";
|
|
5242
5258
|
var SCOPE_COMMIT = "commit:";
|
|
@@ -5260,18 +5276,18 @@ function getChangedCsFiles(scope) {
|
|
|
5260
5276
|
} else {
|
|
5261
5277
|
cmd = "git diff --name-only HEAD";
|
|
5262
5278
|
}
|
|
5263
|
-
const output =
|
|
5279
|
+
const output = execSync22(cmd, { encoding: "utf-8" }).trim();
|
|
5264
5280
|
if (output === "") return [];
|
|
5265
5281
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
5266
5282
|
}
|
|
5267
5283
|
|
|
5268
5284
|
// src/commands/dotnet/inSln.ts
|
|
5269
|
-
import
|
|
5285
|
+
import chalk61 from "chalk";
|
|
5270
5286
|
async function inSln(csprojPath) {
|
|
5271
5287
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5272
5288
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5273
5289
|
if (solutions.length === 0) {
|
|
5274
|
-
console.log(
|
|
5290
|
+
console.log(chalk61.yellow("Not found in any .sln file"));
|
|
5275
5291
|
process.exit(1);
|
|
5276
5292
|
}
|
|
5277
5293
|
for (const sln of solutions) {
|
|
@@ -5280,7 +5296,7 @@ async function inSln(csprojPath) {
|
|
|
5280
5296
|
}
|
|
5281
5297
|
|
|
5282
5298
|
// src/commands/dotnet/inspect.ts
|
|
5283
|
-
import
|
|
5299
|
+
import chalk67 from "chalk";
|
|
5284
5300
|
|
|
5285
5301
|
// src/shared/formatElapsed.ts
|
|
5286
5302
|
function formatElapsed(ms) {
|
|
@@ -5292,12 +5308,12 @@ function formatElapsed(ms) {
|
|
|
5292
5308
|
}
|
|
5293
5309
|
|
|
5294
5310
|
// src/commands/dotnet/displayIssues.ts
|
|
5295
|
-
import
|
|
5311
|
+
import chalk62 from "chalk";
|
|
5296
5312
|
var SEVERITY_COLOR = {
|
|
5297
|
-
ERROR:
|
|
5298
|
-
WARNING:
|
|
5299
|
-
SUGGESTION:
|
|
5300
|
-
HINT:
|
|
5313
|
+
ERROR: chalk62.red,
|
|
5314
|
+
WARNING: chalk62.yellow,
|
|
5315
|
+
SUGGESTION: chalk62.cyan,
|
|
5316
|
+
HINT: chalk62.dim
|
|
5301
5317
|
};
|
|
5302
5318
|
function groupByFile(issues) {
|
|
5303
5319
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5313,15 +5329,15 @@ function groupByFile(issues) {
|
|
|
5313
5329
|
}
|
|
5314
5330
|
function displayIssues(issues) {
|
|
5315
5331
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5316
|
-
console.log(
|
|
5332
|
+
console.log(chalk62.bold(file));
|
|
5317
5333
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5318
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5334
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk62.white;
|
|
5319
5335
|
console.log(
|
|
5320
|
-
` ${
|
|
5336
|
+
` ${chalk62.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5321
5337
|
);
|
|
5322
5338
|
}
|
|
5323
5339
|
}
|
|
5324
|
-
console.log(
|
|
5340
|
+
console.log(chalk62.dim(`
|
|
5325
5341
|
${issues.length} issue(s) found`));
|
|
5326
5342
|
}
|
|
5327
5343
|
|
|
@@ -5380,12 +5396,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5380
5396
|
// src/commands/dotnet/resolveSolution.ts
|
|
5381
5397
|
import { existsSync as existsSync24 } from "fs";
|
|
5382
5398
|
import path25 from "path";
|
|
5383
|
-
import
|
|
5399
|
+
import chalk64 from "chalk";
|
|
5384
5400
|
|
|
5385
5401
|
// src/commands/dotnet/findSolution.ts
|
|
5386
5402
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5387
5403
|
import { dirname as dirname16, join as join18 } from "path";
|
|
5388
|
-
import
|
|
5404
|
+
import chalk63 from "chalk";
|
|
5389
5405
|
function findSlnInDir(dir) {
|
|
5390
5406
|
try {
|
|
5391
5407
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join18(dir, f));
|
|
@@ -5401,17 +5417,17 @@ function findSolution() {
|
|
|
5401
5417
|
const slnFiles = findSlnInDir(current);
|
|
5402
5418
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5403
5419
|
if (slnFiles.length > 1) {
|
|
5404
|
-
console.error(
|
|
5420
|
+
console.error(chalk63.red(`Multiple .sln files found in ${current}:`));
|
|
5405
5421
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5406
5422
|
console.error(
|
|
5407
|
-
|
|
5423
|
+
chalk63.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5408
5424
|
);
|
|
5409
5425
|
process.exit(1);
|
|
5410
5426
|
}
|
|
5411
5427
|
if (current === ceiling) break;
|
|
5412
5428
|
current = dirname16(current);
|
|
5413
5429
|
}
|
|
5414
|
-
console.error(
|
|
5430
|
+
console.error(chalk63.red("No .sln file found between cwd and repo root"));
|
|
5415
5431
|
process.exit(1);
|
|
5416
5432
|
}
|
|
5417
5433
|
|
|
@@ -5420,7 +5436,7 @@ function resolveSolution(sln) {
|
|
|
5420
5436
|
if (sln) {
|
|
5421
5437
|
const resolved = path25.resolve(sln);
|
|
5422
5438
|
if (!existsSync24(resolved)) {
|
|
5423
|
-
console.error(
|
|
5439
|
+
console.error(chalk64.red(`Solution file not found: ${resolved}`));
|
|
5424
5440
|
process.exit(1);
|
|
5425
5441
|
}
|
|
5426
5442
|
return resolved;
|
|
@@ -5458,18 +5474,18 @@ function parseInspectReport(json) {
|
|
|
5458
5474
|
}
|
|
5459
5475
|
|
|
5460
5476
|
// src/commands/dotnet/runInspectCode.ts
|
|
5461
|
-
import { execSync as
|
|
5477
|
+
import { execSync as execSync23 } from "child_process";
|
|
5462
5478
|
import { existsSync as existsSync25, readFileSync as readFileSync20, unlinkSync as unlinkSync4 } from "fs";
|
|
5463
5479
|
import { tmpdir as tmpdir2 } from "os";
|
|
5464
5480
|
import path26 from "path";
|
|
5465
|
-
import
|
|
5481
|
+
import chalk65 from "chalk";
|
|
5466
5482
|
function assertJbInstalled() {
|
|
5467
5483
|
try {
|
|
5468
|
-
|
|
5484
|
+
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5469
5485
|
} catch {
|
|
5470
|
-
console.error(
|
|
5486
|
+
console.error(chalk65.red("jb is not installed. Install with:"));
|
|
5471
5487
|
console.error(
|
|
5472
|
-
|
|
5488
|
+
chalk65.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5473
5489
|
);
|
|
5474
5490
|
process.exit(1);
|
|
5475
5491
|
}
|
|
@@ -5479,7 +5495,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5479
5495
|
const includeFlag = include ? ` --include="${include}"` : "";
|
|
5480
5496
|
const sweaFlag = swea ? " --swea" : "";
|
|
5481
5497
|
try {
|
|
5482
|
-
|
|
5498
|
+
execSync23(
|
|
5483
5499
|
`jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
|
|
5484
5500
|
{ stdio: "pipe" }
|
|
5485
5501
|
);
|
|
@@ -5487,11 +5503,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5487
5503
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5488
5504
|
process.stderr.write(err.stderr);
|
|
5489
5505
|
}
|
|
5490
|
-
console.error(
|
|
5506
|
+
console.error(chalk65.red("jb inspectcode failed"));
|
|
5491
5507
|
process.exit(1);
|
|
5492
5508
|
}
|
|
5493
5509
|
if (!existsSync25(reportPath)) {
|
|
5494
|
-
console.error(
|
|
5510
|
+
console.error(chalk65.red("Report file not generated"));
|
|
5495
5511
|
process.exit(1);
|
|
5496
5512
|
}
|
|
5497
5513
|
const xml = readFileSync20(reportPath, "utf-8");
|
|
@@ -5500,8 +5516,8 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5500
5516
|
}
|
|
5501
5517
|
|
|
5502
5518
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5503
|
-
import { execSync as
|
|
5504
|
-
import
|
|
5519
|
+
import { execSync as execSync24 } from "child_process";
|
|
5520
|
+
import chalk66 from "chalk";
|
|
5505
5521
|
function resolveMsbuildPath() {
|
|
5506
5522
|
const config = loadConfig();
|
|
5507
5523
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5510,11 +5526,11 @@ function resolveMsbuildPath() {
|
|
|
5510
5526
|
function assertMsbuildInstalled() {
|
|
5511
5527
|
const msbuild = resolveMsbuildPath();
|
|
5512
5528
|
try {
|
|
5513
|
-
|
|
5529
|
+
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5514
5530
|
} catch {
|
|
5515
|
-
console.error(
|
|
5531
|
+
console.error(chalk66.red(`msbuild not found at: ${msbuild}`));
|
|
5516
5532
|
console.error(
|
|
5517
|
-
|
|
5533
|
+
chalk66.yellow(
|
|
5518
5534
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5519
5535
|
)
|
|
5520
5536
|
);
|
|
@@ -5536,7 +5552,7 @@ function runRoslynInspect(slnPath) {
|
|
|
5536
5552
|
const msbuild = resolveMsbuildPath();
|
|
5537
5553
|
let output;
|
|
5538
5554
|
try {
|
|
5539
|
-
output =
|
|
5555
|
+
output = execSync24(
|
|
5540
5556
|
`"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
|
|
5541
5557
|
{ encoding: "utf-8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
|
|
5542
5558
|
);
|
|
@@ -5561,17 +5577,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5561
5577
|
// src/commands/dotnet/inspect.ts
|
|
5562
5578
|
function logScope(changedFiles) {
|
|
5563
5579
|
if (changedFiles === null) {
|
|
5564
|
-
console.log(
|
|
5580
|
+
console.log(chalk67.dim("Inspecting full solution..."));
|
|
5565
5581
|
} else {
|
|
5566
5582
|
console.log(
|
|
5567
|
-
|
|
5583
|
+
chalk67.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5568
5584
|
);
|
|
5569
5585
|
}
|
|
5570
5586
|
}
|
|
5571
5587
|
function reportResults(issues, elapsed) {
|
|
5572
5588
|
if (issues.length > 0) displayIssues(issues);
|
|
5573
|
-
else console.log(
|
|
5574
|
-
console.log(
|
|
5589
|
+
else console.log(chalk67.green("No issues found"));
|
|
5590
|
+
console.log(chalk67.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5575
5591
|
if (issues.length > 0) process.exit(1);
|
|
5576
5592
|
}
|
|
5577
5593
|
async function inspect(sln, options2) {
|
|
@@ -5582,7 +5598,7 @@ async function inspect(sln, options2) {
|
|
|
5582
5598
|
const scope = parseScope(options2.scope);
|
|
5583
5599
|
const changedFiles = getChangedCsFiles(scope);
|
|
5584
5600
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5585
|
-
console.log(
|
|
5601
|
+
console.log(chalk67.green("No changed .cs files found"));
|
|
5586
5602
|
return;
|
|
5587
5603
|
}
|
|
5588
5604
|
logScope(changedFiles);
|
|
@@ -5608,7 +5624,7 @@ function registerDotnet(program2) {
|
|
|
5608
5624
|
}
|
|
5609
5625
|
|
|
5610
5626
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5611
|
-
import
|
|
5627
|
+
import chalk69 from "chalk";
|
|
5612
5628
|
|
|
5613
5629
|
// src/commands/jira/adfToText.ts
|
|
5614
5630
|
function renderInline(node) {
|
|
@@ -5668,12 +5684,12 @@ function adfToText(doc) {
|
|
|
5668
5684
|
}
|
|
5669
5685
|
|
|
5670
5686
|
// src/commands/jira/fetchIssue.ts
|
|
5671
|
-
import { execSync as
|
|
5672
|
-
import
|
|
5687
|
+
import { execSync as execSync25 } from "child_process";
|
|
5688
|
+
import chalk68 from "chalk";
|
|
5673
5689
|
function fetchIssue(issueKey, fields) {
|
|
5674
5690
|
let result;
|
|
5675
5691
|
try {
|
|
5676
|
-
result =
|
|
5692
|
+
result = execSync25(
|
|
5677
5693
|
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
5678
5694
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
5679
5695
|
);
|
|
@@ -5682,15 +5698,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
5682
5698
|
const stderr = error.stderr;
|
|
5683
5699
|
if (stderr.includes("unauthorized")) {
|
|
5684
5700
|
console.error(
|
|
5685
|
-
|
|
5701
|
+
chalk68.red("Jira authentication expired."),
|
|
5686
5702
|
"Run",
|
|
5687
|
-
|
|
5703
|
+
chalk68.cyan("assist jira auth"),
|
|
5688
5704
|
"to re-authenticate."
|
|
5689
5705
|
);
|
|
5690
5706
|
process.exit(1);
|
|
5691
5707
|
}
|
|
5692
5708
|
}
|
|
5693
|
-
console.error(
|
|
5709
|
+
console.error(chalk68.red(`Failed to fetch ${issueKey}.`));
|
|
5694
5710
|
process.exit(1);
|
|
5695
5711
|
}
|
|
5696
5712
|
return JSON.parse(result);
|
|
@@ -5704,7 +5720,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5704
5720
|
const parsed = fetchIssue(issueKey, field);
|
|
5705
5721
|
const acValue = parsed?.fields?.[field];
|
|
5706
5722
|
if (!acValue) {
|
|
5707
|
-
console.log(
|
|
5723
|
+
console.log(chalk69.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
5708
5724
|
return;
|
|
5709
5725
|
}
|
|
5710
5726
|
if (typeof acValue === "string") {
|
|
@@ -5719,7 +5735,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
5719
5735
|
}
|
|
5720
5736
|
|
|
5721
5737
|
// src/commands/jira/jiraAuth.ts
|
|
5722
|
-
import { execSync as
|
|
5738
|
+
import { execSync as execSync26 } from "child_process";
|
|
5723
5739
|
|
|
5724
5740
|
// src/shared/loadJson.ts
|
|
5725
5741
|
import { existsSync as existsSync26, mkdirSync as mkdirSync5, readFileSync as readFileSync21, writeFileSync as writeFileSync18 } from "fs";
|
|
@@ -5783,7 +5799,7 @@ async function jiraAuth() {
|
|
|
5783
5799
|
console.error("All fields are required.");
|
|
5784
5800
|
process.exit(1);
|
|
5785
5801
|
}
|
|
5786
|
-
|
|
5802
|
+
execSync26(`acli jira auth login --site ${site} --email "${email}" --token`, {
|
|
5787
5803
|
encoding: "utf-8",
|
|
5788
5804
|
input: token,
|
|
5789
5805
|
stdio: ["pipe", "inherit", "inherit"]
|
|
@@ -5799,14 +5815,14 @@ async function jiraAuth() {
|
|
|
5799
5815
|
}
|
|
5800
5816
|
|
|
5801
5817
|
// src/commands/jira/viewIssue.ts
|
|
5802
|
-
import
|
|
5818
|
+
import chalk70 from "chalk";
|
|
5803
5819
|
function viewIssue(issueKey) {
|
|
5804
5820
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
5805
5821
|
const fields = parsed?.fields;
|
|
5806
5822
|
const summary = fields?.summary;
|
|
5807
5823
|
const description = fields?.description;
|
|
5808
5824
|
if (summary) {
|
|
5809
|
-
console.log(
|
|
5825
|
+
console.log(chalk70.bold(summary));
|
|
5810
5826
|
}
|
|
5811
5827
|
if (description) {
|
|
5812
5828
|
if (summary) console.log();
|
|
@@ -5820,7 +5836,7 @@ function viewIssue(issueKey) {
|
|
|
5820
5836
|
}
|
|
5821
5837
|
if (!summary && !description) {
|
|
5822
5838
|
console.log(
|
|
5823
|
-
|
|
5839
|
+
chalk70.yellow(`No summary or description found on ${issueKey}.`)
|
|
5824
5840
|
);
|
|
5825
5841
|
}
|
|
5826
5842
|
}
|
|
@@ -5834,7 +5850,7 @@ function registerJira(program2) {
|
|
|
5834
5850
|
}
|
|
5835
5851
|
|
|
5836
5852
|
// src/commands/news/add/index.ts
|
|
5837
|
-
import
|
|
5853
|
+
import chalk71 from "chalk";
|
|
5838
5854
|
import enquirer7 from "enquirer";
|
|
5839
5855
|
async function add2(url) {
|
|
5840
5856
|
if (!url) {
|
|
@@ -5857,17 +5873,17 @@ async function add2(url) {
|
|
|
5857
5873
|
const news = config.news ?? {};
|
|
5858
5874
|
const feeds = news.feeds ?? [];
|
|
5859
5875
|
if (feeds.includes(url)) {
|
|
5860
|
-
console.log(
|
|
5876
|
+
console.log(chalk71.yellow("Feed already exists in config"));
|
|
5861
5877
|
return;
|
|
5862
5878
|
}
|
|
5863
5879
|
feeds.push(url);
|
|
5864
5880
|
config.news = { ...news, feeds };
|
|
5865
5881
|
saveGlobalConfig(config);
|
|
5866
|
-
console.log(
|
|
5882
|
+
console.log(chalk71.green(`Added feed: ${url}`));
|
|
5867
5883
|
}
|
|
5868
5884
|
|
|
5869
5885
|
// src/commands/news/web/handleRequest.ts
|
|
5870
|
-
import
|
|
5886
|
+
import chalk72 from "chalk";
|
|
5871
5887
|
|
|
5872
5888
|
// src/commands/news/web/shared.ts
|
|
5873
5889
|
import { decodeHTML } from "entities";
|
|
@@ -6003,17 +6019,17 @@ function prefetch() {
|
|
|
6003
6019
|
const config = loadConfig();
|
|
6004
6020
|
const total = config.news.feeds.length;
|
|
6005
6021
|
if (total === 0) return;
|
|
6006
|
-
process.stdout.write(
|
|
6022
|
+
process.stdout.write(chalk72.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6007
6023
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6008
6024
|
const width = 20;
|
|
6009
6025
|
const filled = Math.round(done2 / t * width);
|
|
6010
6026
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6011
6027
|
process.stdout.write(
|
|
6012
|
-
`\r${
|
|
6028
|
+
`\r${chalk72.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6013
6029
|
);
|
|
6014
6030
|
}).then((items) => {
|
|
6015
6031
|
process.stdout.write(
|
|
6016
|
-
`\r${
|
|
6032
|
+
`\r${chalk72.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6017
6033
|
`
|
|
6018
6034
|
);
|
|
6019
6035
|
cachedItems = items;
|
|
@@ -6064,7 +6080,7 @@ import { tmpdir as tmpdir3 } from "os";
|
|
|
6064
6080
|
import { join as join20 } from "path";
|
|
6065
6081
|
|
|
6066
6082
|
// src/commands/prs/shared.ts
|
|
6067
|
-
import { execSync as
|
|
6083
|
+
import { execSync as execSync27 } from "child_process";
|
|
6068
6084
|
function isGhNotInstalled(error) {
|
|
6069
6085
|
if (error instanceof Error) {
|
|
6070
6086
|
const msg = error.message.toLowerCase();
|
|
@@ -6080,14 +6096,14 @@ function isNotFound(error) {
|
|
|
6080
6096
|
}
|
|
6081
6097
|
function getRepoInfo() {
|
|
6082
6098
|
const repoInfo = JSON.parse(
|
|
6083
|
-
|
|
6099
|
+
execSync27("gh repo view --json owner,name", { encoding: "utf-8" })
|
|
6084
6100
|
);
|
|
6085
6101
|
return { org: repoInfo.owner.login, repo: repoInfo.name };
|
|
6086
6102
|
}
|
|
6087
6103
|
function getCurrentPrNumber() {
|
|
6088
6104
|
try {
|
|
6089
6105
|
const prInfo = JSON.parse(
|
|
6090
|
-
|
|
6106
|
+
execSync27("gh pr view --json number", { encoding: "utf-8" })
|
|
6091
6107
|
);
|
|
6092
6108
|
return prInfo.number;
|
|
6093
6109
|
} catch (error) {
|
|
@@ -6101,7 +6117,7 @@ function getCurrentPrNumber() {
|
|
|
6101
6117
|
function getCurrentPrNodeId() {
|
|
6102
6118
|
try {
|
|
6103
6119
|
const prInfo = JSON.parse(
|
|
6104
|
-
|
|
6120
|
+
execSync27("gh pr view --json id", { encoding: "utf-8" })
|
|
6105
6121
|
);
|
|
6106
6122
|
return prInfo.id;
|
|
6107
6123
|
} catch (error) {
|
|
@@ -6172,10 +6188,10 @@ function comment(path50, line, body) {
|
|
|
6172
6188
|
}
|
|
6173
6189
|
|
|
6174
6190
|
// src/commands/prs/fixed.ts
|
|
6175
|
-
import { execSync as
|
|
6191
|
+
import { execSync as execSync29 } from "child_process";
|
|
6176
6192
|
|
|
6177
6193
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
6178
|
-
import { execSync as
|
|
6194
|
+
import { execSync as execSync28 } from "child_process";
|
|
6179
6195
|
import { unlinkSync as unlinkSync7, writeFileSync as writeFileSync20 } from "fs";
|
|
6180
6196
|
import { tmpdir as tmpdir4 } from "os";
|
|
6181
6197
|
import { join as join22 } from "path";
|
|
@@ -6205,7 +6221,7 @@ function deleteCommentsCache(prNumber) {
|
|
|
6205
6221
|
|
|
6206
6222
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
6207
6223
|
function replyToComment(org, repo, prNumber, commentId, message) {
|
|
6208
|
-
|
|
6224
|
+
execSync28(
|
|
6209
6225
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, '\\"')}" -F in_reply_to=${commentId}`,
|
|
6210
6226
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
6211
6227
|
);
|
|
@@ -6215,7 +6231,7 @@ function resolveThread(threadId) {
|
|
|
6215
6231
|
const queryFile = join22(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
|
|
6216
6232
|
writeFileSync20(queryFile, mutation);
|
|
6217
6233
|
try {
|
|
6218
|
-
|
|
6234
|
+
execSync28(
|
|
6219
6235
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
6220
6236
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
6221
6237
|
);
|
|
@@ -6267,7 +6283,7 @@ function resolveCommentWithReply(commentId, message) {
|
|
|
6267
6283
|
// src/commands/prs/fixed.ts
|
|
6268
6284
|
function verifySha(sha) {
|
|
6269
6285
|
try {
|
|
6270
|
-
return
|
|
6286
|
+
return execSync29(`git rev-parse --verify ${sha}`, {
|
|
6271
6287
|
encoding: "utf-8"
|
|
6272
6288
|
}).trim();
|
|
6273
6289
|
} catch {
|
|
@@ -6281,7 +6297,7 @@ function fixed(commentId, sha) {
|
|
|
6281
6297
|
const { org, repo } = getRepoInfo();
|
|
6282
6298
|
const repoUrl = `https://github.com/${org}/${repo}`;
|
|
6283
6299
|
const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
|
|
6284
|
-
|
|
6300
|
+
execSync29("git push", { stdio: "inherit" });
|
|
6285
6301
|
resolveCommentWithReply(commentId, message);
|
|
6286
6302
|
} catch (error) {
|
|
6287
6303
|
if (isGhNotInstalled(error)) {
|
|
@@ -6299,7 +6315,7 @@ import { join as join24 } from "path";
|
|
|
6299
6315
|
import { stringify } from "yaml";
|
|
6300
6316
|
|
|
6301
6317
|
// src/commands/prs/fetchThreadIds.ts
|
|
6302
|
-
import { execSync as
|
|
6318
|
+
import { execSync as execSync30 } from "child_process";
|
|
6303
6319
|
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "fs";
|
|
6304
6320
|
import { tmpdir as tmpdir5 } from "os";
|
|
6305
6321
|
import { join as join23 } from "path";
|
|
@@ -6308,7 +6324,7 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
6308
6324
|
const queryFile = join23(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
6309
6325
|
writeFileSync21(queryFile, THREAD_QUERY);
|
|
6310
6326
|
try {
|
|
6311
|
-
const result =
|
|
6327
|
+
const result = execSync30(
|
|
6312
6328
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
6313
6329
|
{ encoding: "utf-8" }
|
|
6314
6330
|
);
|
|
@@ -6330,9 +6346,9 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
6330
6346
|
}
|
|
6331
6347
|
|
|
6332
6348
|
// src/commands/prs/listComments/fetchReviewComments.ts
|
|
6333
|
-
import { execSync as
|
|
6349
|
+
import { execSync as execSync31 } from "child_process";
|
|
6334
6350
|
function fetchJson(endpoint) {
|
|
6335
|
-
const result =
|
|
6351
|
+
const result = execSync31(`gh api --paginate ${endpoint}`, {
|
|
6336
6352
|
encoding: "utf-8"
|
|
6337
6353
|
});
|
|
6338
6354
|
if (!result.trim()) return [];
|
|
@@ -6374,20 +6390,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6374
6390
|
}
|
|
6375
6391
|
|
|
6376
6392
|
// src/commands/prs/listComments/printComments.ts
|
|
6377
|
-
import
|
|
6393
|
+
import chalk73 from "chalk";
|
|
6378
6394
|
function formatForHuman(comment2) {
|
|
6379
6395
|
if (comment2.type === "review") {
|
|
6380
|
-
const stateColor = comment2.state === "APPROVED" ?
|
|
6396
|
+
const stateColor = comment2.state === "APPROVED" ? chalk73.green : comment2.state === "CHANGES_REQUESTED" ? chalk73.red : chalk73.yellow;
|
|
6381
6397
|
return [
|
|
6382
|
-
`${
|
|
6398
|
+
`${chalk73.cyan("Review")} by ${chalk73.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
|
|
6383
6399
|
comment2.body,
|
|
6384
6400
|
""
|
|
6385
6401
|
].join("\n");
|
|
6386
6402
|
}
|
|
6387
6403
|
const location = comment2.line ? `:${comment2.line}` : "";
|
|
6388
6404
|
return [
|
|
6389
|
-
`${
|
|
6390
|
-
|
|
6405
|
+
`${chalk73.cyan("Line comment")} by ${chalk73.bold(comment2.user)} on ${chalk73.dim(`${comment2.path}${location}`)}`,
|
|
6406
|
+
chalk73.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6391
6407
|
comment2.body,
|
|
6392
6408
|
""
|
|
6393
6409
|
].join("\n");
|
|
@@ -6471,19 +6487,19 @@ async function listComments() {
|
|
|
6471
6487
|
}
|
|
6472
6488
|
|
|
6473
6489
|
// src/commands/prs/prs/index.ts
|
|
6474
|
-
import { execSync as
|
|
6490
|
+
import { execSync as execSync32 } from "child_process";
|
|
6475
6491
|
|
|
6476
6492
|
// src/commands/prs/prs/displayPaginated/index.ts
|
|
6477
6493
|
import enquirer8 from "enquirer";
|
|
6478
6494
|
|
|
6479
6495
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6480
|
-
import
|
|
6496
|
+
import chalk74 from "chalk";
|
|
6481
6497
|
var STATUS_MAP = {
|
|
6482
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6483
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6498
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk74.magenta("merged"), date: pr.mergedAt } : null,
|
|
6499
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk74.red("closed"), date: pr.closedAt } : null
|
|
6484
6500
|
};
|
|
6485
6501
|
function defaultStatus(pr) {
|
|
6486
|
-
return { label:
|
|
6502
|
+
return { label: chalk74.green("opened"), date: pr.createdAt };
|
|
6487
6503
|
}
|
|
6488
6504
|
function getStatus2(pr) {
|
|
6489
6505
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6492,11 +6508,11 @@ function formatDate(dateStr) {
|
|
|
6492
6508
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6493
6509
|
}
|
|
6494
6510
|
function formatPrHeader(pr, status2) {
|
|
6495
|
-
return `${
|
|
6511
|
+
return `${chalk74.cyan(`#${pr.number}`)} ${pr.title} ${chalk74.dim(`(${pr.author.login},`)} ${status2.label} ${chalk74.dim(`${formatDate(status2.date)})`)}`;
|
|
6496
6512
|
}
|
|
6497
6513
|
function logPrDetails(pr) {
|
|
6498
6514
|
console.log(
|
|
6499
|
-
|
|
6515
|
+
chalk74.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6500
6516
|
);
|
|
6501
6517
|
console.log();
|
|
6502
6518
|
}
|
|
@@ -6577,7 +6593,7 @@ async function displayPaginated(pullRequests) {
|
|
|
6577
6593
|
async function prs(options2) {
|
|
6578
6594
|
const state = options2.open ? "open" : options2.closed ? "closed" : "all";
|
|
6579
6595
|
try {
|
|
6580
|
-
const result =
|
|
6596
|
+
const result = execSync32(
|
|
6581
6597
|
`gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100`,
|
|
6582
6598
|
{ encoding: "utf-8" }
|
|
6583
6599
|
);
|
|
@@ -6600,7 +6616,7 @@ async function prs(options2) {
|
|
|
6600
6616
|
}
|
|
6601
6617
|
|
|
6602
6618
|
// src/commands/prs/wontfix.ts
|
|
6603
|
-
import { execSync as
|
|
6619
|
+
import { execSync as execSync33 } from "child_process";
|
|
6604
6620
|
function validateReason(reason) {
|
|
6605
6621
|
const lowerReason = reason.toLowerCase();
|
|
6606
6622
|
if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
|
|
@@ -6617,7 +6633,7 @@ function validateShaReferences(reason) {
|
|
|
6617
6633
|
const invalidShas = [];
|
|
6618
6634
|
for (const sha of shas) {
|
|
6619
6635
|
try {
|
|
6620
|
-
|
|
6636
|
+
execSync33(`git cat-file -t ${sha}`, { stdio: "pipe" });
|
|
6621
6637
|
} catch {
|
|
6622
6638
|
invalidShas.push(sha);
|
|
6623
6639
|
}
|
|
@@ -6662,10 +6678,10 @@ function registerPrs(program2) {
|
|
|
6662
6678
|
}
|
|
6663
6679
|
|
|
6664
6680
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6665
|
-
import
|
|
6681
|
+
import chalk80 from "chalk";
|
|
6666
6682
|
|
|
6667
6683
|
// src/shared/createConnectionAuth.ts
|
|
6668
|
-
import
|
|
6684
|
+
import chalk75 from "chalk";
|
|
6669
6685
|
function listConnections(connections, format2) {
|
|
6670
6686
|
if (connections.length === 0) {
|
|
6671
6687
|
console.log("No connections configured.");
|
|
@@ -6678,7 +6694,7 @@ function listConnections(connections, format2) {
|
|
|
6678
6694
|
function removeConnection(connections, name, save) {
|
|
6679
6695
|
const filtered = connections.filter((c) => c.name !== name);
|
|
6680
6696
|
if (filtered.length === connections.length) {
|
|
6681
|
-
console.error(
|
|
6697
|
+
console.error(chalk75.red(`Connection "${name}" not found.`));
|
|
6682
6698
|
process.exit(1);
|
|
6683
6699
|
}
|
|
6684
6700
|
save(filtered);
|
|
@@ -6724,17 +6740,17 @@ function saveConnections(connections) {
|
|
|
6724
6740
|
}
|
|
6725
6741
|
|
|
6726
6742
|
// src/commands/ravendb/promptConnection.ts
|
|
6727
|
-
import
|
|
6743
|
+
import chalk78 from "chalk";
|
|
6728
6744
|
|
|
6729
6745
|
// src/commands/ravendb/selectOpSecret.ts
|
|
6730
|
-
import
|
|
6746
|
+
import chalk77 from "chalk";
|
|
6731
6747
|
import Enquirer2 from "enquirer";
|
|
6732
6748
|
|
|
6733
6749
|
// src/commands/ravendb/searchItems.ts
|
|
6734
|
-
import { execSync as
|
|
6735
|
-
import
|
|
6750
|
+
import { execSync as execSync34 } from "child_process";
|
|
6751
|
+
import chalk76 from "chalk";
|
|
6736
6752
|
function opExec(args) {
|
|
6737
|
-
return
|
|
6753
|
+
return execSync34(`op ${args}`, {
|
|
6738
6754
|
encoding: "utf-8",
|
|
6739
6755
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6740
6756
|
}).trim();
|
|
@@ -6745,7 +6761,7 @@ function searchItems(search) {
|
|
|
6745
6761
|
items = JSON.parse(opExec("item list --format=json"));
|
|
6746
6762
|
} catch {
|
|
6747
6763
|
console.error(
|
|
6748
|
-
|
|
6764
|
+
chalk76.red(
|
|
6749
6765
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
6750
6766
|
)
|
|
6751
6767
|
);
|
|
@@ -6759,7 +6775,7 @@ function getItemFields(itemId) {
|
|
|
6759
6775
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
6760
6776
|
return item.fields.filter((f) => f.reference && f.label);
|
|
6761
6777
|
} catch {
|
|
6762
|
-
console.error(
|
|
6778
|
+
console.error(chalk76.red("Failed to get item details from 1Password."));
|
|
6763
6779
|
process.exit(1);
|
|
6764
6780
|
}
|
|
6765
6781
|
}
|
|
@@ -6778,7 +6794,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6778
6794
|
}).run();
|
|
6779
6795
|
const items = searchItems(search);
|
|
6780
6796
|
if (items.length === 0) {
|
|
6781
|
-
console.error(
|
|
6797
|
+
console.error(chalk77.red(`No items found matching "${search}".`));
|
|
6782
6798
|
process.exit(1);
|
|
6783
6799
|
}
|
|
6784
6800
|
const itemId = await selectOne(
|
|
@@ -6787,7 +6803,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6787
6803
|
);
|
|
6788
6804
|
const fields = getItemFields(itemId);
|
|
6789
6805
|
if (fields.length === 0) {
|
|
6790
|
-
console.error(
|
|
6806
|
+
console.error(chalk77.red("No fields with references found on this item."));
|
|
6791
6807
|
process.exit(1);
|
|
6792
6808
|
}
|
|
6793
6809
|
const ref = await selectOne(
|
|
@@ -6801,7 +6817,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
6801
6817
|
async function promptConnection(existingNames) {
|
|
6802
6818
|
const name = await promptInput("name", "Connection name:");
|
|
6803
6819
|
if (existingNames.includes(name)) {
|
|
6804
|
-
console.error(
|
|
6820
|
+
console.error(chalk78.red(`Connection "${name}" already exists.`));
|
|
6805
6821
|
process.exit(1);
|
|
6806
6822
|
}
|
|
6807
6823
|
const url = await promptInput(
|
|
@@ -6810,22 +6826,22 @@ async function promptConnection(existingNames) {
|
|
|
6810
6826
|
);
|
|
6811
6827
|
const database = await promptInput("database", "Database name:");
|
|
6812
6828
|
if (!name || !url || !database) {
|
|
6813
|
-
console.error(
|
|
6829
|
+
console.error(chalk78.red("All fields are required."));
|
|
6814
6830
|
process.exit(1);
|
|
6815
6831
|
}
|
|
6816
6832
|
const apiKeyRef = await selectOpSecret();
|
|
6817
|
-
console.log(
|
|
6833
|
+
console.log(chalk78.dim(`Using: ${apiKeyRef}`));
|
|
6818
6834
|
return { name, url, database, apiKeyRef };
|
|
6819
6835
|
}
|
|
6820
6836
|
|
|
6821
6837
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
6822
|
-
import
|
|
6838
|
+
import chalk79 from "chalk";
|
|
6823
6839
|
function ravendbSetConnection(name) {
|
|
6824
6840
|
const raw = loadGlobalConfigRaw();
|
|
6825
6841
|
const ravendb = raw.ravendb ?? {};
|
|
6826
6842
|
const connections = ravendb.connections ?? [];
|
|
6827
6843
|
if (!connections.some((c) => c.name === name)) {
|
|
6828
|
-
console.error(
|
|
6844
|
+
console.error(chalk79.red(`Connection "${name}" not found.`));
|
|
6829
6845
|
console.error(
|
|
6830
6846
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6831
6847
|
);
|
|
@@ -6841,16 +6857,16 @@ function ravendbSetConnection(name) {
|
|
|
6841
6857
|
var ravendbAuth = createConnectionAuth({
|
|
6842
6858
|
load: loadConnections,
|
|
6843
6859
|
save: saveConnections,
|
|
6844
|
-
format: (c) => `${
|
|
6860
|
+
format: (c) => `${chalk80.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
6845
6861
|
promptNew: promptConnection,
|
|
6846
6862
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
6847
6863
|
});
|
|
6848
6864
|
|
|
6849
6865
|
// src/commands/ravendb/ravendbCollections.ts
|
|
6850
|
-
import
|
|
6866
|
+
import chalk84 from "chalk";
|
|
6851
6867
|
|
|
6852
6868
|
// src/commands/ravendb/ravenFetch.ts
|
|
6853
|
-
import
|
|
6869
|
+
import chalk82 from "chalk";
|
|
6854
6870
|
|
|
6855
6871
|
// src/commands/ravendb/getAccessToken.ts
|
|
6856
6872
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -6886,21 +6902,21 @@ ${errorText}`
|
|
|
6886
6902
|
}
|
|
6887
6903
|
|
|
6888
6904
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
6889
|
-
import { execSync as
|
|
6890
|
-
import
|
|
6905
|
+
import { execSync as execSync35 } from "child_process";
|
|
6906
|
+
import chalk81 from "chalk";
|
|
6891
6907
|
function resolveOpSecret(reference) {
|
|
6892
6908
|
if (!reference.startsWith("op://")) {
|
|
6893
|
-
console.error(
|
|
6909
|
+
console.error(chalk81.red(`Invalid secret reference: must start with op://`));
|
|
6894
6910
|
process.exit(1);
|
|
6895
6911
|
}
|
|
6896
6912
|
try {
|
|
6897
|
-
return
|
|
6913
|
+
return execSync35(`op read "${reference}"`, {
|
|
6898
6914
|
encoding: "utf-8",
|
|
6899
6915
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6900
6916
|
}).trim();
|
|
6901
6917
|
} catch {
|
|
6902
6918
|
console.error(
|
|
6903
|
-
|
|
6919
|
+
chalk81.red(
|
|
6904
6920
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
6905
6921
|
)
|
|
6906
6922
|
);
|
|
@@ -6927,7 +6943,7 @@ async function ravenFetch(connection, path50) {
|
|
|
6927
6943
|
if (!response.ok) {
|
|
6928
6944
|
const body = await response.text();
|
|
6929
6945
|
console.error(
|
|
6930
|
-
|
|
6946
|
+
chalk82.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
6931
6947
|
);
|
|
6932
6948
|
console.error(body.substring(0, 500));
|
|
6933
6949
|
process.exit(1);
|
|
@@ -6936,7 +6952,7 @@ async function ravenFetch(connection, path50) {
|
|
|
6936
6952
|
}
|
|
6937
6953
|
|
|
6938
6954
|
// src/commands/ravendb/resolveConnection.ts
|
|
6939
|
-
import
|
|
6955
|
+
import chalk83 from "chalk";
|
|
6940
6956
|
function loadRavendb() {
|
|
6941
6957
|
const raw = loadGlobalConfigRaw();
|
|
6942
6958
|
const ravendb = raw.ravendb;
|
|
@@ -6950,7 +6966,7 @@ function resolveConnection(name) {
|
|
|
6950
6966
|
const connectionName = name ?? defaultConnection;
|
|
6951
6967
|
if (!connectionName) {
|
|
6952
6968
|
console.error(
|
|
6953
|
-
|
|
6969
|
+
chalk83.red(
|
|
6954
6970
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
6955
6971
|
)
|
|
6956
6972
|
);
|
|
@@ -6958,7 +6974,7 @@ function resolveConnection(name) {
|
|
|
6958
6974
|
}
|
|
6959
6975
|
const connection = connections.find((c) => c.name === connectionName);
|
|
6960
6976
|
if (!connection) {
|
|
6961
|
-
console.error(
|
|
6977
|
+
console.error(chalk83.red(`Connection "${connectionName}" not found.`));
|
|
6962
6978
|
console.error(
|
|
6963
6979
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
6964
6980
|
);
|
|
@@ -6989,15 +7005,15 @@ async function ravendbCollections(connectionName) {
|
|
|
6989
7005
|
return;
|
|
6990
7006
|
}
|
|
6991
7007
|
for (const c of collections) {
|
|
6992
|
-
console.log(`${
|
|
7008
|
+
console.log(`${chalk84.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
6993
7009
|
}
|
|
6994
7010
|
}
|
|
6995
7011
|
|
|
6996
7012
|
// src/commands/ravendb/ravendbQuery.ts
|
|
6997
|
-
import
|
|
7013
|
+
import chalk86 from "chalk";
|
|
6998
7014
|
|
|
6999
7015
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7000
|
-
import
|
|
7016
|
+
import chalk85 from "chalk";
|
|
7001
7017
|
|
|
7002
7018
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7003
7019
|
function buildQueryPath(opts) {
|
|
@@ -7035,7 +7051,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7035
7051
|
allResults.push(...results);
|
|
7036
7052
|
start3 += results.length;
|
|
7037
7053
|
process.stderr.write(
|
|
7038
|
-
`\r${
|
|
7054
|
+
`\r${chalk85.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7039
7055
|
);
|
|
7040
7056
|
if (start3 >= totalResults) break;
|
|
7041
7057
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7050,7 +7066,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7050
7066
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7051
7067
|
const resolved = resolveArgs(connectionName, collection);
|
|
7052
7068
|
if (!resolved.collection && !options2.query) {
|
|
7053
|
-
console.error(
|
|
7069
|
+
console.error(chalk86.red("Provide a collection name or --query filter."));
|
|
7054
7070
|
process.exit(1);
|
|
7055
7071
|
}
|
|
7056
7072
|
const { collection: col } = resolved;
|
|
@@ -7088,7 +7104,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7088
7104
|
import * as path27 from "path";
|
|
7089
7105
|
|
|
7090
7106
|
// src/commands/refactor/logViolations.ts
|
|
7091
|
-
import
|
|
7107
|
+
import chalk87 from "chalk";
|
|
7092
7108
|
var DEFAULT_MAX_LINES = 100;
|
|
7093
7109
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7094
7110
|
if (violations.length === 0) {
|
|
@@ -7097,43 +7113,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7097
7113
|
}
|
|
7098
7114
|
return;
|
|
7099
7115
|
}
|
|
7100
|
-
console.error(
|
|
7116
|
+
console.error(chalk87.red(`
|
|
7101
7117
|
Refactor check failed:
|
|
7102
7118
|
`));
|
|
7103
|
-
console.error(
|
|
7119
|
+
console.error(chalk87.red(` The following files exceed ${maxLines} lines:
|
|
7104
7120
|
`));
|
|
7105
7121
|
for (const violation of violations) {
|
|
7106
|
-
console.error(
|
|
7122
|
+
console.error(chalk87.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7107
7123
|
}
|
|
7108
7124
|
console.error(
|
|
7109
|
-
|
|
7125
|
+
chalk87.yellow(
|
|
7110
7126
|
`
|
|
7111
7127
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7112
7128
|
way to refactor it, ignore it with:
|
|
7113
7129
|
`
|
|
7114
7130
|
)
|
|
7115
7131
|
);
|
|
7116
|
-
console.error(
|
|
7132
|
+
console.error(chalk87.gray(` assist refactor ignore <file>
|
|
7117
7133
|
`));
|
|
7118
7134
|
if (process.env.CLAUDECODE) {
|
|
7119
|
-
console.error(
|
|
7135
|
+
console.error(chalk87.cyan(`
|
|
7120
7136
|
## Extracting Code to New Files
|
|
7121
7137
|
`));
|
|
7122
7138
|
console.error(
|
|
7123
|
-
|
|
7139
|
+
chalk87.cyan(
|
|
7124
7140
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7125
7141
|
`
|
|
7126
7142
|
)
|
|
7127
7143
|
);
|
|
7128
7144
|
console.error(
|
|
7129
|
-
|
|
7145
|
+
chalk87.cyan(
|
|
7130
7146
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7131
7147
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7132
7148
|
`
|
|
7133
7149
|
)
|
|
7134
7150
|
);
|
|
7135
7151
|
console.error(
|
|
7136
|
-
|
|
7152
|
+
chalk87.cyan(
|
|
7137
7153
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7138
7154
|
domains, move it to a common/shared folder.
|
|
7139
7155
|
`
|
|
@@ -7143,7 +7159,7 @@ Refactor check failed:
|
|
|
7143
7159
|
}
|
|
7144
7160
|
|
|
7145
7161
|
// src/commands/refactor/check/getViolations/index.ts
|
|
7146
|
-
import { execSync as
|
|
7162
|
+
import { execSync as execSync36 } from "child_process";
|
|
7147
7163
|
import fs16 from "fs";
|
|
7148
7164
|
import { minimatch as minimatch4 } from "minimatch";
|
|
7149
7165
|
|
|
@@ -7193,7 +7209,7 @@ function getGitFiles(options2) {
|
|
|
7193
7209
|
}
|
|
7194
7210
|
const files = /* @__PURE__ */ new Set();
|
|
7195
7211
|
if (options2.staged || options2.modified) {
|
|
7196
|
-
const staged =
|
|
7212
|
+
const staged = execSync36("git diff --cached --name-only", {
|
|
7197
7213
|
encoding: "utf-8"
|
|
7198
7214
|
});
|
|
7199
7215
|
for (const file of staged.trim().split("\n").filter(Boolean)) {
|
|
@@ -7201,7 +7217,7 @@ function getGitFiles(options2) {
|
|
|
7201
7217
|
}
|
|
7202
7218
|
}
|
|
7203
7219
|
if (options2.unstaged || options2.modified) {
|
|
7204
|
-
const unstaged =
|
|
7220
|
+
const unstaged = execSync36("git diff --name-only", { encoding: "utf-8" });
|
|
7205
7221
|
for (const file of unstaged.trim().split("\n").filter(Boolean)) {
|
|
7206
7222
|
files.add(file);
|
|
7207
7223
|
}
|
|
@@ -7289,7 +7305,7 @@ async function check(pattern2, options2) {
|
|
|
7289
7305
|
|
|
7290
7306
|
// src/commands/refactor/extract/index.ts
|
|
7291
7307
|
import path33 from "path";
|
|
7292
|
-
import
|
|
7308
|
+
import chalk90 from "chalk";
|
|
7293
7309
|
|
|
7294
7310
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7295
7311
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -7815,23 +7831,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
7815
7831
|
|
|
7816
7832
|
// src/commands/refactor/extract/displayPlan.ts
|
|
7817
7833
|
import path31 from "path";
|
|
7818
|
-
import
|
|
7834
|
+
import chalk88 from "chalk";
|
|
7819
7835
|
function section(title) {
|
|
7820
7836
|
return `
|
|
7821
|
-
${
|
|
7837
|
+
${chalk88.cyan(title)}`;
|
|
7822
7838
|
}
|
|
7823
7839
|
function displayImporters(plan2, cwd) {
|
|
7824
7840
|
if (plan2.importersToUpdate.length === 0) return;
|
|
7825
7841
|
console.log(section("Update importers:"));
|
|
7826
7842
|
for (const imp of plan2.importersToUpdate) {
|
|
7827
7843
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
7828
|
-
console.log(` ${
|
|
7844
|
+
console.log(` ${chalk88.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
7829
7845
|
}
|
|
7830
7846
|
}
|
|
7831
7847
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
7832
|
-
console.log(
|
|
7848
|
+
console.log(chalk88.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
7833
7849
|
`));
|
|
7834
|
-
console.log(` ${
|
|
7850
|
+
console.log(` ${chalk88.cyan("Functions to move:")}`);
|
|
7835
7851
|
for (const name of plan2.extractedNames) {
|
|
7836
7852
|
console.log(` ${name}`);
|
|
7837
7853
|
}
|
|
@@ -7866,7 +7882,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
7866
7882
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
7867
7883
|
import fs17 from "fs";
|
|
7868
7884
|
import path32 from "path";
|
|
7869
|
-
import
|
|
7885
|
+
import chalk89 from "chalk";
|
|
7870
7886
|
import { Project as Project2 } from "ts-morph";
|
|
7871
7887
|
function findTsConfig(sourcePath) {
|
|
7872
7888
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -7897,7 +7913,7 @@ function loadProjectFile(file) {
|
|
|
7897
7913
|
});
|
|
7898
7914
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
7899
7915
|
if (!sourceFile) {
|
|
7900
|
-
console.log(
|
|
7916
|
+
console.log(chalk89.red(`File not found in project: ${file}`));
|
|
7901
7917
|
process.exit(1);
|
|
7902
7918
|
}
|
|
7903
7919
|
return { project, sourceFile };
|
|
@@ -7920,19 +7936,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
7920
7936
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
7921
7937
|
if (options2.apply) {
|
|
7922
7938
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
7923
|
-
console.log(
|
|
7939
|
+
console.log(chalk90.green("\nExtraction complete"));
|
|
7924
7940
|
} else {
|
|
7925
|
-
console.log(
|
|
7941
|
+
console.log(chalk90.dim("\nDry run. Use --apply to execute."));
|
|
7926
7942
|
}
|
|
7927
7943
|
}
|
|
7928
7944
|
|
|
7929
7945
|
// src/commands/refactor/ignore.ts
|
|
7930
7946
|
import fs18 from "fs";
|
|
7931
|
-
import
|
|
7947
|
+
import chalk91 from "chalk";
|
|
7932
7948
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
7933
7949
|
function ignore(file) {
|
|
7934
7950
|
if (!fs18.existsSync(file)) {
|
|
7935
|
-
console.error(
|
|
7951
|
+
console.error(chalk91.red(`Error: File does not exist: ${file}`));
|
|
7936
7952
|
process.exit(1);
|
|
7937
7953
|
}
|
|
7938
7954
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -7948,7 +7964,7 @@ function ignore(file) {
|
|
|
7948
7964
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
7949
7965
|
}
|
|
7950
7966
|
console.log(
|
|
7951
|
-
|
|
7967
|
+
chalk91.green(
|
|
7952
7968
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
7953
7969
|
)
|
|
7954
7970
|
);
|
|
@@ -7956,26 +7972,26 @@ function ignore(file) {
|
|
|
7956
7972
|
|
|
7957
7973
|
// src/commands/refactor/rename/index.ts
|
|
7958
7974
|
import path34 from "path";
|
|
7959
|
-
import
|
|
7975
|
+
import chalk92 from "chalk";
|
|
7960
7976
|
async function rename(source, destination, options2 = {}) {
|
|
7961
7977
|
const destPath = path34.resolve(destination);
|
|
7962
7978
|
const cwd = process.cwd();
|
|
7963
7979
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
7964
7980
|
const relDest = path34.relative(cwd, destPath);
|
|
7965
7981
|
const { project, sourceFile } = loadProjectFile(source);
|
|
7966
|
-
console.log(
|
|
7982
|
+
console.log(chalk92.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
7967
7983
|
if (options2.apply) {
|
|
7968
7984
|
sourceFile.move(destPath);
|
|
7969
7985
|
await project.save();
|
|
7970
|
-
console.log(
|
|
7986
|
+
console.log(chalk92.green("Done"));
|
|
7971
7987
|
} else {
|
|
7972
|
-
console.log(
|
|
7988
|
+
console.log(chalk92.dim("Dry run. Use --apply to execute."));
|
|
7973
7989
|
}
|
|
7974
7990
|
}
|
|
7975
7991
|
|
|
7976
7992
|
// src/commands/refactor/renameSymbol/index.ts
|
|
7977
7993
|
import path36 from "path";
|
|
7978
|
-
import
|
|
7994
|
+
import chalk93 from "chalk";
|
|
7979
7995
|
import { Project as Project3 } from "ts-morph";
|
|
7980
7996
|
|
|
7981
7997
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8024,38 +8040,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8024
8040
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8025
8041
|
const sourceFile = project.getSourceFile(filePath);
|
|
8026
8042
|
if (!sourceFile) {
|
|
8027
|
-
console.log(
|
|
8043
|
+
console.log(chalk93.red(`File not found in project: ${file}`));
|
|
8028
8044
|
process.exit(1);
|
|
8029
8045
|
}
|
|
8030
8046
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8031
8047
|
if (!symbol) {
|
|
8032
|
-
console.log(
|
|
8048
|
+
console.log(chalk93.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8033
8049
|
process.exit(1);
|
|
8034
8050
|
}
|
|
8035
8051
|
const grouped = groupReferences(symbol, cwd);
|
|
8036
8052
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8037
8053
|
console.log(
|
|
8038
|
-
|
|
8054
|
+
chalk93.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8039
8055
|
`)
|
|
8040
8056
|
);
|
|
8041
8057
|
for (const [refFile, lines] of grouped) {
|
|
8042
8058
|
console.log(
|
|
8043
|
-
` ${
|
|
8059
|
+
` ${chalk93.dim(refFile)}: lines ${chalk93.cyan(lines.join(", "))}`
|
|
8044
8060
|
);
|
|
8045
8061
|
}
|
|
8046
8062
|
if (options2.apply) {
|
|
8047
8063
|
symbol.rename(newName);
|
|
8048
8064
|
await project.save();
|
|
8049
|
-
console.log(
|
|
8065
|
+
console.log(chalk93.green(`
|
|
8050
8066
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8051
8067
|
} else {
|
|
8052
|
-
console.log(
|
|
8068
|
+
console.log(chalk93.dim("\nDry run. Use --apply to execute."));
|
|
8053
8069
|
}
|
|
8054
8070
|
}
|
|
8055
8071
|
|
|
8056
8072
|
// src/commands/refactor/restructure/index.ts
|
|
8057
8073
|
import path45 from "path";
|
|
8058
|
-
import
|
|
8074
|
+
import chalk96 from "chalk";
|
|
8059
8075
|
|
|
8060
8076
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8061
8077
|
import path37 from "path";
|
|
@@ -8298,50 +8314,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8298
8314
|
|
|
8299
8315
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8300
8316
|
import path41 from "path";
|
|
8301
|
-
import
|
|
8317
|
+
import chalk94 from "chalk";
|
|
8302
8318
|
function relPath(filePath) {
|
|
8303
8319
|
return path41.relative(process.cwd(), filePath);
|
|
8304
8320
|
}
|
|
8305
8321
|
function displayMoves(plan2) {
|
|
8306
8322
|
if (plan2.moves.length === 0) return;
|
|
8307
|
-
console.log(
|
|
8323
|
+
console.log(chalk94.bold("\nFile moves:"));
|
|
8308
8324
|
for (const move of plan2.moves) {
|
|
8309
8325
|
console.log(
|
|
8310
|
-
` ${
|
|
8326
|
+
` ${chalk94.red(relPath(move.from))} \u2192 ${chalk94.green(relPath(move.to))}`
|
|
8311
8327
|
);
|
|
8312
|
-
console.log(
|
|
8328
|
+
console.log(chalk94.dim(` ${move.reason}`));
|
|
8313
8329
|
}
|
|
8314
8330
|
}
|
|
8315
8331
|
function displayRewrites(rewrites) {
|
|
8316
8332
|
if (rewrites.length === 0) return;
|
|
8317
8333
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8318
|
-
console.log(
|
|
8334
|
+
console.log(chalk94.bold(`
|
|
8319
8335
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8320
8336
|
for (const file of affectedFiles) {
|
|
8321
|
-
console.log(` ${
|
|
8337
|
+
console.log(` ${chalk94.cyan(relPath(file))}:`);
|
|
8322
8338
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8323
8339
|
(r) => r.file === file
|
|
8324
8340
|
)) {
|
|
8325
8341
|
console.log(
|
|
8326
|
-
` ${
|
|
8342
|
+
` ${chalk94.red(`"${oldSpecifier}"`)} \u2192 ${chalk94.green(`"${newSpecifier}"`)}`
|
|
8327
8343
|
);
|
|
8328
8344
|
}
|
|
8329
8345
|
}
|
|
8330
8346
|
}
|
|
8331
8347
|
function displayPlan2(plan2) {
|
|
8332
8348
|
if (plan2.warnings.length > 0) {
|
|
8333
|
-
console.log(
|
|
8334
|
-
for (const w of plan2.warnings) console.log(
|
|
8349
|
+
console.log(chalk94.yellow("\nWarnings:"));
|
|
8350
|
+
for (const w of plan2.warnings) console.log(chalk94.yellow(` ${w}`));
|
|
8335
8351
|
}
|
|
8336
8352
|
if (plan2.newDirectories.length > 0) {
|
|
8337
|
-
console.log(
|
|
8353
|
+
console.log(chalk94.bold("\nNew directories:"));
|
|
8338
8354
|
for (const dir of plan2.newDirectories)
|
|
8339
|
-
console.log(
|
|
8355
|
+
console.log(chalk94.green(` ${dir}/`));
|
|
8340
8356
|
}
|
|
8341
8357
|
displayMoves(plan2);
|
|
8342
8358
|
displayRewrites(plan2.rewrites);
|
|
8343
8359
|
console.log(
|
|
8344
|
-
|
|
8360
|
+
chalk94.dim(
|
|
8345
8361
|
`
|
|
8346
8362
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8347
8363
|
)
|
|
@@ -8351,18 +8367,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8351
8367
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8352
8368
|
import fs20 from "fs";
|
|
8353
8369
|
import path42 from "path";
|
|
8354
|
-
import
|
|
8370
|
+
import chalk95 from "chalk";
|
|
8355
8371
|
function executePlan(plan2) {
|
|
8356
8372
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8357
8373
|
for (const [file, content] of updatedContents) {
|
|
8358
8374
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8359
8375
|
console.log(
|
|
8360
|
-
|
|
8376
|
+
chalk95.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8361
8377
|
);
|
|
8362
8378
|
}
|
|
8363
8379
|
for (const dir of plan2.newDirectories) {
|
|
8364
8380
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8365
|
-
console.log(
|
|
8381
|
+
console.log(chalk95.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8366
8382
|
}
|
|
8367
8383
|
for (const move of plan2.moves) {
|
|
8368
8384
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8371,7 +8387,7 @@ function executePlan(plan2) {
|
|
|
8371
8387
|
}
|
|
8372
8388
|
fs20.renameSync(move.from, move.to);
|
|
8373
8389
|
console.log(
|
|
8374
|
-
|
|
8390
|
+
chalk95.white(
|
|
8375
8391
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8376
8392
|
)
|
|
8377
8393
|
);
|
|
@@ -8386,7 +8402,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8386
8402
|
if (entries.length === 0) {
|
|
8387
8403
|
fs20.rmdirSync(dir);
|
|
8388
8404
|
console.log(
|
|
8389
|
-
|
|
8405
|
+
chalk95.dim(
|
|
8390
8406
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8391
8407
|
)
|
|
8392
8408
|
);
|
|
@@ -8519,22 +8535,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8519
8535
|
const targetPattern = pattern2 ?? "src";
|
|
8520
8536
|
const files = findSourceFiles2(targetPattern);
|
|
8521
8537
|
if (files.length === 0) {
|
|
8522
|
-
console.log(
|
|
8538
|
+
console.log(chalk96.yellow("No files found matching pattern"));
|
|
8523
8539
|
return;
|
|
8524
8540
|
}
|
|
8525
8541
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8526
8542
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8527
8543
|
if (plan2.moves.length === 0) {
|
|
8528
|
-
console.log(
|
|
8544
|
+
console.log(chalk96.green("No restructuring needed"));
|
|
8529
8545
|
return;
|
|
8530
8546
|
}
|
|
8531
8547
|
displayPlan2(plan2);
|
|
8532
8548
|
if (options2.apply) {
|
|
8533
|
-
console.log(
|
|
8549
|
+
console.log(chalk96.bold("\nApplying changes..."));
|
|
8534
8550
|
executePlan(plan2);
|
|
8535
|
-
console.log(
|
|
8551
|
+
console.log(chalk96.green("\nRestructuring complete"));
|
|
8536
8552
|
} else {
|
|
8537
|
-
console.log(
|
|
8553
|
+
console.log(chalk96.dim("\nDry run. Use --apply to execute."));
|
|
8538
8554
|
}
|
|
8539
8555
|
}
|
|
8540
8556
|
|
|
@@ -8574,7 +8590,7 @@ function registerRefactor(program2) {
|
|
|
8574
8590
|
}
|
|
8575
8591
|
|
|
8576
8592
|
// src/commands/seq/seqAuth.ts
|
|
8577
|
-
import
|
|
8593
|
+
import chalk98 from "chalk";
|
|
8578
8594
|
|
|
8579
8595
|
// src/commands/seq/loadConnections.ts
|
|
8580
8596
|
function loadConnections2() {
|
|
@@ -8603,11 +8619,11 @@ function setDefaultConnection(name) {
|
|
|
8603
8619
|
}
|
|
8604
8620
|
|
|
8605
8621
|
// src/commands/seq/promptConnection.ts
|
|
8606
|
-
import
|
|
8622
|
+
import chalk97 from "chalk";
|
|
8607
8623
|
async function promptConnection2(existingNames) {
|
|
8608
8624
|
const name = await promptInput("name", "Connection name:", "default");
|
|
8609
8625
|
if (existingNames.includes(name)) {
|
|
8610
|
-
console.error(
|
|
8626
|
+
console.error(chalk97.red(`Connection "${name}" already exists.`));
|
|
8611
8627
|
process.exit(1);
|
|
8612
8628
|
}
|
|
8613
8629
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -8619,32 +8635,32 @@ async function promptConnection2(existingNames) {
|
|
|
8619
8635
|
var seqAuth = createConnectionAuth({
|
|
8620
8636
|
load: loadConnections2,
|
|
8621
8637
|
save: saveConnections2,
|
|
8622
|
-
format: (c) => `${
|
|
8638
|
+
format: (c) => `${chalk98.bold(c.name)} ${c.url}`,
|
|
8623
8639
|
promptNew: promptConnection2,
|
|
8624
8640
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
8625
8641
|
});
|
|
8626
8642
|
|
|
8627
8643
|
// src/commands/seq/seqQuery.ts
|
|
8628
|
-
import
|
|
8644
|
+
import chalk101 from "chalk";
|
|
8629
8645
|
|
|
8630
8646
|
// src/commands/seq/formatEvent.ts
|
|
8631
|
-
import
|
|
8647
|
+
import chalk99 from "chalk";
|
|
8632
8648
|
function levelColor(level) {
|
|
8633
8649
|
switch (level) {
|
|
8634
8650
|
case "Fatal":
|
|
8635
|
-
return
|
|
8651
|
+
return chalk99.bgRed.white;
|
|
8636
8652
|
case "Error":
|
|
8637
|
-
return
|
|
8653
|
+
return chalk99.red;
|
|
8638
8654
|
case "Warning":
|
|
8639
|
-
return
|
|
8655
|
+
return chalk99.yellow;
|
|
8640
8656
|
case "Information":
|
|
8641
|
-
return
|
|
8657
|
+
return chalk99.cyan;
|
|
8642
8658
|
case "Debug":
|
|
8643
|
-
return
|
|
8659
|
+
return chalk99.gray;
|
|
8644
8660
|
case "Verbose":
|
|
8645
|
-
return
|
|
8661
|
+
return chalk99.dim;
|
|
8646
8662
|
default:
|
|
8647
|
-
return
|
|
8663
|
+
return chalk99.white;
|
|
8648
8664
|
}
|
|
8649
8665
|
}
|
|
8650
8666
|
function levelAbbrev(level) {
|
|
@@ -8685,31 +8701,31 @@ function formatTimestamp(iso) {
|
|
|
8685
8701
|
function formatEvent(event) {
|
|
8686
8702
|
const color = levelColor(event.Level);
|
|
8687
8703
|
const abbrev = levelAbbrev(event.Level);
|
|
8688
|
-
const ts8 =
|
|
8704
|
+
const ts8 = chalk99.dim(formatTimestamp(event.Timestamp));
|
|
8689
8705
|
const msg = renderMessage(event);
|
|
8690
8706
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
8691
8707
|
if (event.Exception) {
|
|
8692
8708
|
for (const line of event.Exception.split("\n")) {
|
|
8693
|
-
lines.push(
|
|
8709
|
+
lines.push(chalk99.red(` ${line}`));
|
|
8694
8710
|
}
|
|
8695
8711
|
}
|
|
8696
8712
|
return lines.join("\n");
|
|
8697
8713
|
}
|
|
8698
8714
|
|
|
8699
8715
|
// src/commands/seq/resolveConnection.ts
|
|
8700
|
-
import
|
|
8716
|
+
import chalk100 from "chalk";
|
|
8701
8717
|
function resolveConnection2(name) {
|
|
8702
8718
|
const connections = loadConnections2();
|
|
8703
8719
|
if (connections.length === 0) {
|
|
8704
8720
|
console.error(
|
|
8705
|
-
|
|
8721
|
+
chalk100.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
8706
8722
|
);
|
|
8707
8723
|
process.exit(1);
|
|
8708
8724
|
}
|
|
8709
8725
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
8710
8726
|
const connection = connections.find((c) => c.name === target);
|
|
8711
8727
|
if (!connection) {
|
|
8712
|
-
console.error(
|
|
8728
|
+
console.error(chalk100.red(`Seq connection "${target}" not found.`));
|
|
8713
8729
|
process.exit(1);
|
|
8714
8730
|
}
|
|
8715
8731
|
return connection;
|
|
@@ -8729,12 +8745,12 @@ async function seqQuery(filter, options2) {
|
|
|
8729
8745
|
});
|
|
8730
8746
|
if (!response.ok) {
|
|
8731
8747
|
const body = await response.text();
|
|
8732
|
-
console.error(
|
|
8748
|
+
console.error(chalk101.red(`Seq returned ${response.status}: ${body}`));
|
|
8733
8749
|
process.exit(1);
|
|
8734
8750
|
}
|
|
8735
8751
|
const events = await response.json();
|
|
8736
8752
|
if (events.length === 0) {
|
|
8737
|
-
console.log(
|
|
8753
|
+
console.log(chalk101.yellow("No events found."));
|
|
8738
8754
|
return;
|
|
8739
8755
|
}
|
|
8740
8756
|
if (options2.json) {
|
|
@@ -8745,11 +8761,11 @@ async function seqQuery(filter, options2) {
|
|
|
8745
8761
|
for (const event of chronological) {
|
|
8746
8762
|
console.log(formatEvent(event));
|
|
8747
8763
|
}
|
|
8748
|
-
console.log(
|
|
8764
|
+
console.log(chalk101.dim(`
|
|
8749
8765
|
${events.length} events`));
|
|
8750
8766
|
if (events.length >= count) {
|
|
8751
8767
|
console.log(
|
|
8752
|
-
|
|
8768
|
+
chalk101.yellow(
|
|
8753
8769
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
8754
8770
|
)
|
|
8755
8771
|
);
|
|
@@ -8757,11 +8773,11 @@ ${events.length} events`));
|
|
|
8757
8773
|
}
|
|
8758
8774
|
|
|
8759
8775
|
// src/commands/seq/seqSetConnection.ts
|
|
8760
|
-
import
|
|
8776
|
+
import chalk102 from "chalk";
|
|
8761
8777
|
function seqSetConnection(name) {
|
|
8762
8778
|
const connections = loadConnections2();
|
|
8763
8779
|
if (!connections.find((c) => c.name === name)) {
|
|
8764
|
-
console.error(
|
|
8780
|
+
console.error(chalk102.red(`Connection "${name}" not found.`));
|
|
8765
8781
|
process.exit(1);
|
|
8766
8782
|
}
|
|
8767
8783
|
setDefaultConnection(name);
|
|
@@ -9300,14 +9316,14 @@ import {
|
|
|
9300
9316
|
import { dirname as dirname20, join as join29 } from "path";
|
|
9301
9317
|
|
|
9302
9318
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9303
|
-
import
|
|
9319
|
+
import chalk103 from "chalk";
|
|
9304
9320
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9305
9321
|
function validateStagedContent(filename, content) {
|
|
9306
9322
|
const firstLine = content.split("\n")[0];
|
|
9307
9323
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9308
9324
|
if (!match) {
|
|
9309
9325
|
console.error(
|
|
9310
|
-
|
|
9326
|
+
chalk103.red(
|
|
9311
9327
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9312
9328
|
)
|
|
9313
9329
|
);
|
|
@@ -9316,7 +9332,7 @@ function validateStagedContent(filename, content) {
|
|
|
9316
9332
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9317
9333
|
if (!contentAfterLink) {
|
|
9318
9334
|
console.error(
|
|
9319
|
-
|
|
9335
|
+
chalk103.red(
|
|
9320
9336
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9321
9337
|
)
|
|
9322
9338
|
);
|
|
@@ -9516,7 +9532,7 @@ import { mkdirSync as mkdirSync10 } from "fs";
|
|
|
9516
9532
|
import { join as join34 } from "path";
|
|
9517
9533
|
|
|
9518
9534
|
// src/commands/voice/checkLockFile.ts
|
|
9519
|
-
import { execSync as
|
|
9535
|
+
import { execSync as execSync37 } from "child_process";
|
|
9520
9536
|
import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync26, writeFileSync as writeFileSync24 } from "fs";
|
|
9521
9537
|
import { join as join33 } from "path";
|
|
9522
9538
|
function isProcessAlive(pid) {
|
|
@@ -9545,7 +9561,7 @@ function bootstrapVenv() {
|
|
|
9545
9561
|
if (existsSync35(getVenvPython())) return;
|
|
9546
9562
|
console.log("Setting up Python environment...");
|
|
9547
9563
|
const pythonDir = getPythonDir();
|
|
9548
|
-
|
|
9564
|
+
execSync37(
|
|
9549
9565
|
`uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
|
|
9550
9566
|
{
|
|
9551
9567
|
stdio: "inherit",
|
|
@@ -9709,14 +9725,14 @@ function registerVoice(program2) {
|
|
|
9709
9725
|
|
|
9710
9726
|
// src/commands/roam/auth.ts
|
|
9711
9727
|
import { randomBytes } from "crypto";
|
|
9712
|
-
import
|
|
9728
|
+
import chalk104 from "chalk";
|
|
9713
9729
|
|
|
9714
9730
|
// src/lib/openBrowser.ts
|
|
9715
|
-
import { execSync as
|
|
9731
|
+
import { execSync as execSync38 } from "child_process";
|
|
9716
9732
|
function tryExec(commands) {
|
|
9717
9733
|
for (const cmd of commands) {
|
|
9718
9734
|
try {
|
|
9719
|
-
|
|
9735
|
+
execSync38(cmd);
|
|
9720
9736
|
return true;
|
|
9721
9737
|
} catch {
|
|
9722
9738
|
}
|
|
@@ -9884,13 +9900,13 @@ async function auth() {
|
|
|
9884
9900
|
saveGlobalConfig(config);
|
|
9885
9901
|
const state = randomBytes(16).toString("hex");
|
|
9886
9902
|
console.log(
|
|
9887
|
-
|
|
9903
|
+
chalk104.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
9888
9904
|
);
|
|
9889
|
-
console.log(
|
|
9890
|
-
console.log(
|
|
9891
|
-
console.log(
|
|
9905
|
+
console.log(chalk104.white("http://localhost:14523/callback\n"));
|
|
9906
|
+
console.log(chalk104.blue("Opening browser for authorization..."));
|
|
9907
|
+
console.log(chalk104.dim("Waiting for authorization callback..."));
|
|
9892
9908
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
9893
|
-
console.log(
|
|
9909
|
+
console.log(chalk104.dim("Exchanging code for tokens..."));
|
|
9894
9910
|
const tokens = await exchangeToken({
|
|
9895
9911
|
code,
|
|
9896
9912
|
clientId,
|
|
@@ -9906,7 +9922,7 @@ async function auth() {
|
|
|
9906
9922
|
};
|
|
9907
9923
|
saveGlobalConfig(config);
|
|
9908
9924
|
console.log(
|
|
9909
|
-
|
|
9925
|
+
chalk104.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
9910
9926
|
);
|
|
9911
9927
|
}
|
|
9912
9928
|
|
|
@@ -9942,7 +9958,7 @@ function registerRoam(program2) {
|
|
|
9942
9958
|
}
|
|
9943
9959
|
|
|
9944
9960
|
// src/commands/run/index.ts
|
|
9945
|
-
import { execSync as
|
|
9961
|
+
import { execSync as execSync39 } from "child_process";
|
|
9946
9962
|
|
|
9947
9963
|
// src/commands/run/resolveParams.ts
|
|
9948
9964
|
function resolveParams(params, cliArgs) {
|
|
@@ -10097,7 +10113,7 @@ function listRunConfigs() {
|
|
|
10097
10113
|
function runPreCommands(pre) {
|
|
10098
10114
|
for (const cmd of pre) {
|
|
10099
10115
|
try {
|
|
10100
|
-
|
|
10116
|
+
execSync39(cmd, { stdio: "inherit" });
|
|
10101
10117
|
} catch (err) {
|
|
10102
10118
|
const code = err && typeof err === "object" && "status" in err ? err.status : 1;
|
|
10103
10119
|
process.exit(code);
|
|
@@ -10115,11 +10131,11 @@ function run3(name, args) {
|
|
|
10115
10131
|
}
|
|
10116
10132
|
|
|
10117
10133
|
// src/commands/screenshot/index.ts
|
|
10118
|
-
import { execSync as
|
|
10134
|
+
import { execSync as execSync40 } from "child_process";
|
|
10119
10135
|
import { existsSync as existsSync38, mkdirSync as mkdirSync13, unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
|
|
10120
10136
|
import { tmpdir as tmpdir6 } from "os";
|
|
10121
10137
|
import { join as join38, resolve as resolve5 } from "path";
|
|
10122
|
-
import
|
|
10138
|
+
import chalk105 from "chalk";
|
|
10123
10139
|
|
|
10124
10140
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10125
10141
|
var captureWindowPs1 = `
|
|
@@ -10258,7 +10274,7 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
10258
10274
|
const scriptPath = join38(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
|
|
10259
10275
|
writeFileSync27(scriptPath, captureWindowPs1, "utf-8");
|
|
10260
10276
|
try {
|
|
10261
|
-
|
|
10277
|
+
execSync40(
|
|
10262
10278
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
10263
10279
|
{ stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }
|
|
10264
10280
|
);
|
|
@@ -10270,22 +10286,22 @@ function screenshot(processName) {
|
|
|
10270
10286
|
const config = loadConfig();
|
|
10271
10287
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10272
10288
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10273
|
-
console.log(
|
|
10289
|
+
console.log(chalk105.gray(`Capturing window for process "${processName}" ...`));
|
|
10274
10290
|
try {
|
|
10275
10291
|
runPowerShellScript(processName, outputPath);
|
|
10276
|
-
console.log(
|
|
10292
|
+
console.log(chalk105.green(`Screenshot saved: ${outputPath}`));
|
|
10277
10293
|
} catch (error) {
|
|
10278
10294
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10279
|
-
console.error(
|
|
10295
|
+
console.error(chalk105.red(`Failed to capture screenshot: ${msg}`));
|
|
10280
10296
|
process.exit(1);
|
|
10281
10297
|
}
|
|
10282
10298
|
}
|
|
10283
10299
|
|
|
10284
10300
|
// src/commands/statusLine.ts
|
|
10285
|
-
import
|
|
10301
|
+
import chalk107 from "chalk";
|
|
10286
10302
|
|
|
10287
10303
|
// src/commands/buildLimitsSegment.ts
|
|
10288
|
-
import
|
|
10304
|
+
import chalk106 from "chalk";
|
|
10289
10305
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10290
10306
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10291
10307
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10308,10 +10324,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10308
10324
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10309
10325
|
const label2 = `${Math.round(pct)}%`;
|
|
10310
10326
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10311
|
-
if (projected == null) return
|
|
10312
|
-
if (projected > 100) return
|
|
10313
|
-
if (projected > 75) return
|
|
10314
|
-
return
|
|
10327
|
+
if (projected == null) return chalk106.green(label2);
|
|
10328
|
+
if (projected > 100) return chalk106.red(label2);
|
|
10329
|
+
if (projected > 75) return chalk106.yellow(label2);
|
|
10330
|
+
return chalk106.green(label2);
|
|
10315
10331
|
}
|
|
10316
10332
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10317
10333
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10337,14 +10353,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10337
10353
|
}
|
|
10338
10354
|
|
|
10339
10355
|
// src/commands/statusLine.ts
|
|
10340
|
-
|
|
10356
|
+
chalk107.level = 3;
|
|
10341
10357
|
function formatNumber(num) {
|
|
10342
10358
|
return num.toLocaleString("en-US");
|
|
10343
10359
|
}
|
|
10344
10360
|
function colorizePercent(pct) {
|
|
10345
10361
|
const label2 = `${Math.round(pct)}%`;
|
|
10346
|
-
if (pct > 80) return
|
|
10347
|
-
if (pct > 40) return
|
|
10362
|
+
if (pct > 80) return chalk107.red(label2);
|
|
10363
|
+
if (pct > 40) return chalk107.yellow(label2);
|
|
10348
10364
|
return label2;
|
|
10349
10365
|
}
|
|
10350
10366
|
async function statusLine() {
|
|
@@ -10367,7 +10383,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10367
10383
|
// src/commands/sync/syncClaudeMd.ts
|
|
10368
10384
|
import * as fs23 from "fs";
|
|
10369
10385
|
import * as path46 from "path";
|
|
10370
|
-
import
|
|
10386
|
+
import chalk108 from "chalk";
|
|
10371
10387
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10372
10388
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10373
10389
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10376,12 +10392,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10376
10392
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10377
10393
|
if (sourceContent !== targetContent) {
|
|
10378
10394
|
console.log(
|
|
10379
|
-
|
|
10395
|
+
chalk108.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10380
10396
|
);
|
|
10381
10397
|
console.log();
|
|
10382
10398
|
printDiff(targetContent, sourceContent);
|
|
10383
10399
|
const confirm = options2?.yes || await promptConfirm(
|
|
10384
|
-
|
|
10400
|
+
chalk108.red("Overwrite existing CLAUDE.md?"),
|
|
10385
10401
|
false
|
|
10386
10402
|
);
|
|
10387
10403
|
if (!confirm) {
|
|
@@ -10397,7 +10413,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10397
10413
|
// src/commands/sync/syncSettings.ts
|
|
10398
10414
|
import * as fs24 from "fs";
|
|
10399
10415
|
import * as path47 from "path";
|
|
10400
|
-
import
|
|
10416
|
+
import chalk109 from "chalk";
|
|
10401
10417
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10402
10418
|
const source = path47.join(claudeDir, "settings.json");
|
|
10403
10419
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10413,14 +10429,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10413
10429
|
if (mergedContent !== normalizedTarget) {
|
|
10414
10430
|
if (!options2?.yes) {
|
|
10415
10431
|
console.log(
|
|
10416
|
-
|
|
10432
|
+
chalk109.yellow(
|
|
10417
10433
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10418
10434
|
)
|
|
10419
10435
|
);
|
|
10420
10436
|
console.log();
|
|
10421
10437
|
printDiff(targetContent, mergedContent);
|
|
10422
10438
|
const confirm = await promptConfirm(
|
|
10423
|
-
|
|
10439
|
+
chalk109.red("Overwrite existing settings.json?"),
|
|
10424
10440
|
false
|
|
10425
10441
|
);
|
|
10426
10442
|
if (!confirm) {
|
|
@@ -10457,7 +10473,7 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
10457
10473
|
}
|
|
10458
10474
|
|
|
10459
10475
|
// src/commands/update.ts
|
|
10460
|
-
import { execSync as
|
|
10476
|
+
import { execSync as execSync41 } from "child_process";
|
|
10461
10477
|
import * as path49 from "path";
|
|
10462
10478
|
function isGlobalNpmInstall(dir) {
|
|
10463
10479
|
try {
|
|
@@ -10465,7 +10481,7 @@ function isGlobalNpmInstall(dir) {
|
|
|
10465
10481
|
if (resolved.split(path49.sep).includes("node_modules")) {
|
|
10466
10482
|
return true;
|
|
10467
10483
|
}
|
|
10468
|
-
const globalPrefix =
|
|
10484
|
+
const globalPrefix = execSync41("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
10469
10485
|
return resolved.toLowerCase().startsWith(path49.resolve(globalPrefix).toLowerCase());
|
|
10470
10486
|
} catch {
|
|
10471
10487
|
return false;
|
|
@@ -10476,18 +10492,18 @@ async function update() {
|
|
|
10476
10492
|
console.log(`Assist is installed at: ${installDir}`);
|
|
10477
10493
|
if (isGitRepo(installDir)) {
|
|
10478
10494
|
console.log("Detected git repo installation, pulling latest...");
|
|
10479
|
-
|
|
10495
|
+
execSync41("git pull", { cwd: installDir, stdio: "inherit" });
|
|
10480
10496
|
console.log("Installing dependencies...");
|
|
10481
|
-
|
|
10497
|
+
execSync41("npm i", { cwd: installDir, stdio: "inherit" });
|
|
10482
10498
|
console.log("Building...");
|
|
10483
|
-
|
|
10499
|
+
execSync41("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
10484
10500
|
console.log("Syncing commands...");
|
|
10485
|
-
|
|
10501
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
10486
10502
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
10487
10503
|
console.log("Detected global npm installation, updating...");
|
|
10488
|
-
|
|
10504
|
+
execSync41("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
10489
10505
|
console.log("Syncing commands...");
|
|
10490
|
-
|
|
10506
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
10491
10507
|
} else {
|
|
10492
10508
|
console.error(
|
|
10493
10509
|
"Could not determine installation method. Expected a git repo or global npm install."
|