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