@staff0rd/assist 0.161.0 → 0.163.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/claude/CLAUDE.md +2 -0
- package/dist/index.js +403 -306
- 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.163.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -1190,6 +1190,12 @@ var assistConfigSchema = z2.strictObject({
|
|
|
1190
1190
|
screenshot: z2.strictObject({
|
|
1191
1191
|
outputDir: z2.string().default("./screenshots")
|
|
1192
1192
|
}).default({ outputDir: "./screenshots" }),
|
|
1193
|
+
deny: z2.array(
|
|
1194
|
+
z2.strictObject({
|
|
1195
|
+
pattern: z2.string(),
|
|
1196
|
+
message: z2.string()
|
|
1197
|
+
})
|
|
1198
|
+
).optional(),
|
|
1193
1199
|
sync: z2.strictObject({
|
|
1194
1200
|
autoConfirm: z2.boolean().default(false)
|
|
1195
1201
|
}).default({ autoConfirm: false }),
|
|
@@ -3798,6 +3804,15 @@ function normalizeMsysPath(p) {
|
|
|
3798
3804
|
return m ? `${m[1].toUpperCase()}:${m[2]}` : p;
|
|
3799
3805
|
}
|
|
3800
3806
|
|
|
3807
|
+
// src/shared/matchesConfigDeny.ts
|
|
3808
|
+
function matchesConfigDeny(command) {
|
|
3809
|
+
const config = loadConfig();
|
|
3810
|
+
if (!config.deny) return void 0;
|
|
3811
|
+
return config.deny.find(
|
|
3812
|
+
(rule) => command === rule.pattern || command.startsWith(`${rule.pattern} `)
|
|
3813
|
+
);
|
|
3814
|
+
}
|
|
3815
|
+
|
|
3801
3816
|
// src/shared/splitCompound.ts
|
|
3802
3817
|
import { parse } from "shell-quote";
|
|
3803
3818
|
var SEPARATOR_OPS = /* @__PURE__ */ new Set(["|", "&&", "||", ";"]);
|
|
@@ -3855,7 +3870,16 @@ function stripEnvPrefix(parts) {
|
|
|
3855
3870
|
|
|
3856
3871
|
// src/commands/cliHook/index.ts
|
|
3857
3872
|
var SUPPORTED_TOOLS = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
3858
|
-
function
|
|
3873
|
+
function findDeny(toolName, parts) {
|
|
3874
|
+
for (const part of parts) {
|
|
3875
|
+
const configDeny = matchesConfigDeny(part);
|
|
3876
|
+
if (configDeny) {
|
|
3877
|
+
return {
|
|
3878
|
+
permissionDecision: "deny",
|
|
3879
|
+
permissionDecisionReason: configDeny.message
|
|
3880
|
+
};
|
|
3881
|
+
}
|
|
3882
|
+
}
|
|
3859
3883
|
for (const part of parts) {
|
|
3860
3884
|
const denied = matchesDeny(toolName, part);
|
|
3861
3885
|
if (denied) {
|
|
@@ -3865,6 +3889,11 @@ function resolvePermission(toolName, parts) {
|
|
|
3865
3889
|
};
|
|
3866
3890
|
}
|
|
3867
3891
|
}
|
|
3892
|
+
return void 0;
|
|
3893
|
+
}
|
|
3894
|
+
function resolvePermission(toolName, parts) {
|
|
3895
|
+
const denied = findDeny(toolName, parts);
|
|
3896
|
+
if (denied) return denied;
|
|
3868
3897
|
const reasons = [];
|
|
3869
3898
|
for (const part of parts) {
|
|
3870
3899
|
const reason = isApprovedRead(part, toolName);
|
|
@@ -3876,27 +3905,29 @@ function resolvePermission(toolName, parts) {
|
|
|
3876
3905
|
permissionDecisionReason: reasons.join("; ")
|
|
3877
3906
|
};
|
|
3878
3907
|
}
|
|
3879
|
-
|
|
3880
|
-
const inputData = await readStdin2();
|
|
3881
|
-
let data;
|
|
3908
|
+
function tryParseJson(raw) {
|
|
3882
3909
|
try {
|
|
3883
|
-
|
|
3910
|
+
return JSON.parse(raw);
|
|
3884
3911
|
} catch {
|
|
3885
|
-
return;
|
|
3886
|
-
}
|
|
3887
|
-
if (!SUPPORTED_TOOLS.has(data.tool_name) || !data.tool_input?.command) {
|
|
3888
|
-
return;
|
|
3912
|
+
return void 0;
|
|
3889
3913
|
}
|
|
3914
|
+
}
|
|
3915
|
+
function extractCommand(data) {
|
|
3916
|
+
if (!SUPPORTED_TOOLS.has(data.tool_name) || !data.tool_input?.command)
|
|
3917
|
+
return void 0;
|
|
3890
3918
|
const parts = splitCompound(data.tool_input.command.trim());
|
|
3891
|
-
|
|
3892
|
-
|
|
3919
|
+
return parts ? { toolName: data.tool_name, parts } : void 0;
|
|
3920
|
+
}
|
|
3921
|
+
async function cliHook() {
|
|
3922
|
+
const data = tryParseJson(await readStdin2());
|
|
3923
|
+
if (!data) return;
|
|
3924
|
+
const cmd = extractCommand(data);
|
|
3925
|
+
if (!cmd) return;
|
|
3926
|
+
const decision = resolvePermission(cmd.toolName, cmd.parts);
|
|
3893
3927
|
if (!decision) return;
|
|
3894
3928
|
console.log(
|
|
3895
3929
|
JSON.stringify({
|
|
3896
|
-
hookSpecificOutput: {
|
|
3897
|
-
hookEventName: "PreToolUse",
|
|
3898
|
-
...decision
|
|
3899
|
-
}
|
|
3930
|
+
hookSpecificOutput: { hookEventName: "PreToolUse", ...decision }
|
|
3900
3931
|
})
|
|
3901
3932
|
);
|
|
3902
3933
|
}
|
|
@@ -3910,6 +3941,14 @@ function cliHookCheck(command) {
|
|
|
3910
3941
|
process.exitCode = 1;
|
|
3911
3942
|
return;
|
|
3912
3943
|
}
|
|
3944
|
+
for (const part of parts) {
|
|
3945
|
+
const configDeny = matchesConfigDeny(part);
|
|
3946
|
+
if (configDeny) {
|
|
3947
|
+
console.log(`denied: ${configDeny.message}`);
|
|
3948
|
+
process.exitCode = 1;
|
|
3949
|
+
return;
|
|
3950
|
+
}
|
|
3951
|
+
}
|
|
3913
3952
|
const reasons = [];
|
|
3914
3953
|
for (const part of parts) {
|
|
3915
3954
|
const reason = isApprovedRead(part);
|
|
@@ -3924,6 +3963,51 @@ function cliHookCheck(command) {
|
|
|
3924
3963
|
${reasons.join("\n")}`);
|
|
3925
3964
|
}
|
|
3926
3965
|
|
|
3966
|
+
// src/commands/deny/denyAdd.ts
|
|
3967
|
+
import chalk48 from "chalk";
|
|
3968
|
+
function denyAdd(pattern2, message) {
|
|
3969
|
+
const config = loadProjectConfig();
|
|
3970
|
+
const deny = config.deny ?? [];
|
|
3971
|
+
if (deny.some((r) => r.pattern === pattern2)) {
|
|
3972
|
+
console.log(chalk48.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
3973
|
+
return;
|
|
3974
|
+
}
|
|
3975
|
+
deny.push({ pattern: pattern2, message });
|
|
3976
|
+
config.deny = deny;
|
|
3977
|
+
saveConfig(config);
|
|
3978
|
+
console.log(chalk48.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
3979
|
+
}
|
|
3980
|
+
|
|
3981
|
+
// src/commands/deny/denyList.ts
|
|
3982
|
+
import chalk49 from "chalk";
|
|
3983
|
+
function denyList() {
|
|
3984
|
+
const config = loadConfig();
|
|
3985
|
+
const deny = config.deny;
|
|
3986
|
+
if (!deny || deny.length === 0) {
|
|
3987
|
+
console.log(chalk49.dim("No deny rules configured."));
|
|
3988
|
+
return;
|
|
3989
|
+
}
|
|
3990
|
+
for (const rule of deny) {
|
|
3991
|
+
console.log(`${chalk49.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
|
|
3995
|
+
// src/commands/deny/denyRemove.ts
|
|
3996
|
+
import chalk50 from "chalk";
|
|
3997
|
+
function denyRemove(pattern2) {
|
|
3998
|
+
const config = loadProjectConfig();
|
|
3999
|
+
const deny = config.deny ?? [];
|
|
4000
|
+
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
4001
|
+
if (index === -1) {
|
|
4002
|
+
console.log(chalk50.yellow(`No deny rule found for: ${pattern2}`));
|
|
4003
|
+
return;
|
|
4004
|
+
}
|
|
4005
|
+
deny.splice(index, 1);
|
|
4006
|
+
config.deny = deny.length > 0 ? deny : void 0;
|
|
4007
|
+
saveConfig(config);
|
|
4008
|
+
console.log(chalk50.green(`Removed deny rule: ${pattern2}`));
|
|
4009
|
+
}
|
|
4010
|
+
|
|
3927
4011
|
// src/commands/permitCliReads/index.ts
|
|
3928
4012
|
import { existsSync as existsSync22, mkdirSync as mkdirSync4, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
|
|
3929
4013
|
import { homedir as homedir4 } from "os";
|
|
@@ -3971,11 +4055,11 @@ function assertCliExists(cli) {
|
|
|
3971
4055
|
}
|
|
3972
4056
|
|
|
3973
4057
|
// src/commands/permitCliReads/colorize.ts
|
|
3974
|
-
import
|
|
4058
|
+
import chalk51 from "chalk";
|
|
3975
4059
|
function colorize(plainOutput) {
|
|
3976
4060
|
return plainOutput.split("\n").map((line) => {
|
|
3977
|
-
if (line.startsWith(" R ")) return
|
|
3978
|
-
if (line.startsWith(" W ")) return
|
|
4061
|
+
if (line.startsWith(" R ")) return chalk51.green(line);
|
|
4062
|
+
if (line.startsWith(" W ")) return chalk51.red(line);
|
|
3979
4063
|
return line;
|
|
3980
4064
|
}).join("\n");
|
|
3981
4065
|
}
|
|
@@ -4286,18 +4370,22 @@ function registerCliHook(program2) {
|
|
|
4286
4370
|
).option("--no-cache", "Force fresh discovery, ignoring cached results").action((cli, options2) => {
|
|
4287
4371
|
permitCliReads(cli.join(" "), { noCache: !options2.cache });
|
|
4288
4372
|
});
|
|
4373
|
+
const denyCommand = cmd.command("deny").description("Manage command deny rules").action(denyList);
|
|
4374
|
+
denyCommand.command("add").description("Add a deny rule for a command pattern").argument("<pattern>", "Command prefix to deny").argument("<message>", "Correction message shown to the agent").action(denyAdd);
|
|
4375
|
+
denyCommand.command("remove").description("Remove a deny rule by pattern").argument("<pattern>", "Command prefix to remove").action(denyRemove);
|
|
4376
|
+
denyCommand.command("list").description("List all deny rules").action(denyList);
|
|
4289
4377
|
}
|
|
4290
4378
|
|
|
4291
4379
|
// src/commands/complexity/analyze.ts
|
|
4292
|
-
import
|
|
4380
|
+
import chalk57 from "chalk";
|
|
4293
4381
|
|
|
4294
4382
|
// src/commands/complexity/cyclomatic.ts
|
|
4295
|
-
import
|
|
4383
|
+
import chalk53 from "chalk";
|
|
4296
4384
|
|
|
4297
4385
|
// src/commands/complexity/shared/index.ts
|
|
4298
4386
|
import fs12 from "fs";
|
|
4299
4387
|
import path20 from "path";
|
|
4300
|
-
import
|
|
4388
|
+
import chalk52 from "chalk";
|
|
4301
4389
|
import ts5 from "typescript";
|
|
4302
4390
|
|
|
4303
4391
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -4543,7 +4631,7 @@ function createSourceFromFile(filePath) {
|
|
|
4543
4631
|
function withSourceFiles(pattern2, callback) {
|
|
4544
4632
|
const files = findSourceFiles2(pattern2);
|
|
4545
4633
|
if (files.length === 0) {
|
|
4546
|
-
console.log(
|
|
4634
|
+
console.log(chalk52.yellow("No files found matching pattern"));
|
|
4547
4635
|
return void 0;
|
|
4548
4636
|
}
|
|
4549
4637
|
return callback(files);
|
|
@@ -4576,11 +4664,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4576
4664
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
4577
4665
|
for (const { file, name, complexity } of results) {
|
|
4578
4666
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
4579
|
-
const color = exceedsThreshold ?
|
|
4580
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
4667
|
+
const color = exceedsThreshold ? chalk53.red : chalk53.white;
|
|
4668
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk53.cyan(complexity)}`);
|
|
4581
4669
|
}
|
|
4582
4670
|
console.log(
|
|
4583
|
-
|
|
4671
|
+
chalk53.dim(
|
|
4584
4672
|
`
|
|
4585
4673
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4586
4674
|
)
|
|
@@ -4592,7 +4680,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4592
4680
|
}
|
|
4593
4681
|
|
|
4594
4682
|
// src/commands/complexity/halstead.ts
|
|
4595
|
-
import
|
|
4683
|
+
import chalk54 from "chalk";
|
|
4596
4684
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
4597
4685
|
withSourceFiles(pattern2, (files) => {
|
|
4598
4686
|
const results = [];
|
|
@@ -4607,13 +4695,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4607
4695
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
4608
4696
|
for (const { file, name, metrics } of results) {
|
|
4609
4697
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
4610
|
-
const color = exceedsThreshold ?
|
|
4698
|
+
const color = exceedsThreshold ? chalk54.red : chalk54.white;
|
|
4611
4699
|
console.log(
|
|
4612
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
4700
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk54.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk54.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk54.magenta(metrics.effort.toFixed(1))}`
|
|
4613
4701
|
);
|
|
4614
4702
|
}
|
|
4615
4703
|
console.log(
|
|
4616
|
-
|
|
4704
|
+
chalk54.dim(
|
|
4617
4705
|
`
|
|
4618
4706
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
4619
4707
|
)
|
|
@@ -4628,28 +4716,28 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
4628
4716
|
import fs13 from "fs";
|
|
4629
4717
|
|
|
4630
4718
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
4631
|
-
import
|
|
4719
|
+
import chalk55 from "chalk";
|
|
4632
4720
|
function displayMaintainabilityResults(results, threshold) {
|
|
4633
4721
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
4634
4722
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
4635
|
-
console.log(
|
|
4723
|
+
console.log(chalk55.green("All files pass maintainability threshold"));
|
|
4636
4724
|
} else {
|
|
4637
4725
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
4638
|
-
const color = threshold !== void 0 ?
|
|
4726
|
+
const color = threshold !== void 0 ? chalk55.red : chalk55.white;
|
|
4639
4727
|
console.log(
|
|
4640
|
-
`${color(file)} \u2192 avg: ${
|
|
4728
|
+
`${color(file)} \u2192 avg: ${chalk55.cyan(avgMaintainability.toFixed(1))}, min: ${chalk55.yellow(minMaintainability.toFixed(1))}`
|
|
4641
4729
|
);
|
|
4642
4730
|
}
|
|
4643
4731
|
}
|
|
4644
|
-
console.log(
|
|
4732
|
+
console.log(chalk55.dim(`
|
|
4645
4733
|
Analyzed ${results.length} files`));
|
|
4646
4734
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
4647
4735
|
console.error(
|
|
4648
|
-
|
|
4736
|
+
chalk55.red(
|
|
4649
4737
|
`
|
|
4650
4738
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
4651
4739
|
|
|
4652
|
-
\u26A0\uFE0F ${
|
|
4740
|
+
\u26A0\uFE0F ${chalk55.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.`
|
|
4653
4741
|
)
|
|
4654
4742
|
);
|
|
4655
4743
|
process.exit(1);
|
|
@@ -4706,7 +4794,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4706
4794
|
|
|
4707
4795
|
// src/commands/complexity/sloc.ts
|
|
4708
4796
|
import fs14 from "fs";
|
|
4709
|
-
import
|
|
4797
|
+
import chalk56 from "chalk";
|
|
4710
4798
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
4711
4799
|
withSourceFiles(pattern2, (files) => {
|
|
4712
4800
|
const results = [];
|
|
@@ -4722,12 +4810,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
4722
4810
|
results.sort((a, b) => b.lines - a.lines);
|
|
4723
4811
|
for (const { file, lines } of results) {
|
|
4724
4812
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
4725
|
-
const color = exceedsThreshold ?
|
|
4726
|
-
console.log(`${color(file)} \u2192 ${
|
|
4813
|
+
const color = exceedsThreshold ? chalk56.red : chalk56.white;
|
|
4814
|
+
console.log(`${color(file)} \u2192 ${chalk56.cyan(lines)} lines`);
|
|
4727
4815
|
}
|
|
4728
4816
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
4729
4817
|
console.log(
|
|
4730
|
-
|
|
4818
|
+
chalk56.dim(`
|
|
4731
4819
|
Total: ${total} lines across ${files.length} files`)
|
|
4732
4820
|
);
|
|
4733
4821
|
if (hasViolation) {
|
|
@@ -4741,21 +4829,21 @@ async function analyze(pattern2) {
|
|
|
4741
4829
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
4742
4830
|
const files = findSourceFiles2(searchPattern);
|
|
4743
4831
|
if (files.length === 0) {
|
|
4744
|
-
console.log(
|
|
4832
|
+
console.log(chalk57.yellow("No files found matching pattern"));
|
|
4745
4833
|
return;
|
|
4746
4834
|
}
|
|
4747
4835
|
if (files.length === 1) {
|
|
4748
4836
|
const file = files[0];
|
|
4749
|
-
console.log(
|
|
4837
|
+
console.log(chalk57.bold.underline("SLOC"));
|
|
4750
4838
|
await sloc(file);
|
|
4751
4839
|
console.log();
|
|
4752
|
-
console.log(
|
|
4840
|
+
console.log(chalk57.bold.underline("Cyclomatic Complexity"));
|
|
4753
4841
|
await cyclomatic(file);
|
|
4754
4842
|
console.log();
|
|
4755
|
-
console.log(
|
|
4843
|
+
console.log(chalk57.bold.underline("Halstead Metrics"));
|
|
4756
4844
|
await halstead(file);
|
|
4757
4845
|
console.log();
|
|
4758
|
-
console.log(
|
|
4846
|
+
console.log(chalk57.bold.underline("Maintainability Index"));
|
|
4759
4847
|
await maintainability(file);
|
|
4760
4848
|
return;
|
|
4761
4849
|
}
|
|
@@ -4783,7 +4871,7 @@ function registerComplexity(program2) {
|
|
|
4783
4871
|
|
|
4784
4872
|
// src/commands/deploy/redirect.ts
|
|
4785
4873
|
import { existsSync as existsSync23, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
4786
|
-
import
|
|
4874
|
+
import chalk58 from "chalk";
|
|
4787
4875
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
4788
4876
|
if (!window.location.pathname.endsWith('/')) {
|
|
4789
4877
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -4792,22 +4880,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
4792
4880
|
function redirect() {
|
|
4793
4881
|
const indexPath = "index.html";
|
|
4794
4882
|
if (!existsSync23(indexPath)) {
|
|
4795
|
-
console.log(
|
|
4883
|
+
console.log(chalk58.yellow("No index.html found"));
|
|
4796
4884
|
return;
|
|
4797
4885
|
}
|
|
4798
4886
|
const content = readFileSync18(indexPath, "utf-8");
|
|
4799
4887
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
4800
|
-
console.log(
|
|
4888
|
+
console.log(chalk58.dim("Trailing slash script already present"));
|
|
4801
4889
|
return;
|
|
4802
4890
|
}
|
|
4803
4891
|
const headCloseIndex = content.indexOf("</head>");
|
|
4804
4892
|
if (headCloseIndex === -1) {
|
|
4805
|
-
console.log(
|
|
4893
|
+
console.log(chalk58.red("Could not find </head> tag in index.html"));
|
|
4806
4894
|
return;
|
|
4807
4895
|
}
|
|
4808
4896
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
4809
4897
|
writeFileSync17(indexPath, newContent);
|
|
4810
|
-
console.log(
|
|
4898
|
+
console.log(chalk58.green("Added trailing slash redirect to index.html"));
|
|
4811
4899
|
}
|
|
4812
4900
|
|
|
4813
4901
|
// src/commands/registerDeploy.ts
|
|
@@ -4834,7 +4922,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
4834
4922
|
|
|
4835
4923
|
// src/commands/devlog/shared.ts
|
|
4836
4924
|
import { execSync as execSync17 } from "child_process";
|
|
4837
|
-
import
|
|
4925
|
+
import chalk59 from "chalk";
|
|
4838
4926
|
|
|
4839
4927
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
4840
4928
|
import { readdirSync, readFileSync as readFileSync19 } from "fs";
|
|
@@ -4921,13 +5009,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
4921
5009
|
}
|
|
4922
5010
|
function printCommitsWithFiles(commits, ignore2, verbose) {
|
|
4923
5011
|
for (const commit2 of commits) {
|
|
4924
|
-
console.log(` ${
|
|
5012
|
+
console.log(` ${chalk59.yellow(commit2.hash)} ${commit2.message}`);
|
|
4925
5013
|
if (verbose) {
|
|
4926
5014
|
const visibleFiles = commit2.files.filter(
|
|
4927
5015
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
4928
5016
|
);
|
|
4929
5017
|
for (const file of visibleFiles) {
|
|
4930
|
-
console.log(` ${
|
|
5018
|
+
console.log(` ${chalk59.dim(file)}`);
|
|
4931
5019
|
}
|
|
4932
5020
|
}
|
|
4933
5021
|
}
|
|
@@ -4952,15 +5040,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
4952
5040
|
}
|
|
4953
5041
|
|
|
4954
5042
|
// src/commands/devlog/list/printDateHeader.ts
|
|
4955
|
-
import
|
|
5043
|
+
import chalk60 from "chalk";
|
|
4956
5044
|
function printDateHeader(date, isSkipped, entries) {
|
|
4957
5045
|
if (isSkipped) {
|
|
4958
|
-
console.log(`${
|
|
5046
|
+
console.log(`${chalk60.bold.blue(date)} ${chalk60.dim("skipped")}`);
|
|
4959
5047
|
} else if (entries && entries.length > 0) {
|
|
4960
|
-
const entryInfo = entries.map((e) => `${
|
|
4961
|
-
console.log(`${
|
|
5048
|
+
const entryInfo = entries.map((e) => `${chalk60.green(e.version)} ${e.title}`).join(" | ");
|
|
5049
|
+
console.log(`${chalk60.bold.blue(date)} ${entryInfo}`);
|
|
4962
5050
|
} else {
|
|
4963
|
-
console.log(`${
|
|
5051
|
+
console.log(`${chalk60.bold.blue(date)} ${chalk60.red("\u26A0 devlog missing")}`);
|
|
4964
5052
|
}
|
|
4965
5053
|
}
|
|
4966
5054
|
|
|
@@ -5063,24 +5151,24 @@ function bumpVersion(version2, type) {
|
|
|
5063
5151
|
|
|
5064
5152
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
5065
5153
|
import { execSync as execSync20 } from "child_process";
|
|
5066
|
-
import
|
|
5154
|
+
import chalk62 from "chalk";
|
|
5067
5155
|
|
|
5068
5156
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
5069
|
-
import
|
|
5157
|
+
import chalk61 from "chalk";
|
|
5070
5158
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
5071
5159
|
if (conventional && firstHash) {
|
|
5072
5160
|
const version2 = getVersionAtCommit(firstHash);
|
|
5073
5161
|
if (version2) {
|
|
5074
|
-
console.log(`${
|
|
5162
|
+
console.log(`${chalk61.bold("version:")} ${stripToMinor(version2)}`);
|
|
5075
5163
|
} else {
|
|
5076
|
-
console.log(`${
|
|
5164
|
+
console.log(`${chalk61.bold("version:")} ${chalk61.red("unknown")}`);
|
|
5077
5165
|
}
|
|
5078
5166
|
} else if (patchVersion && minorVersion) {
|
|
5079
5167
|
console.log(
|
|
5080
|
-
`${
|
|
5168
|
+
`${chalk61.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
5081
5169
|
);
|
|
5082
5170
|
} else {
|
|
5083
|
-
console.log(`${
|
|
5171
|
+
console.log(`${chalk61.bold("version:")} v0.1 (initial)`);
|
|
5084
5172
|
}
|
|
5085
5173
|
}
|
|
5086
5174
|
|
|
@@ -5127,16 +5215,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
5127
5215
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
5128
5216
|
}
|
|
5129
5217
|
function logName(repoName) {
|
|
5130
|
-
console.log(`${
|
|
5218
|
+
console.log(`${chalk62.bold("name:")} ${repoName}`);
|
|
5131
5219
|
}
|
|
5132
5220
|
function displayNextEntry(ctx, targetDate, commits) {
|
|
5133
5221
|
logName(ctx.repoName);
|
|
5134
5222
|
printVersionInfo(ctx.config, ctx.lastInfo, commits[0]?.hash);
|
|
5135
|
-
console.log(
|
|
5223
|
+
console.log(chalk62.bold.blue(targetDate));
|
|
5136
5224
|
printCommitsWithFiles(commits, ctx.ignore, ctx.verbose);
|
|
5137
5225
|
}
|
|
5138
5226
|
function logNoCommits(lastInfo) {
|
|
5139
|
-
console.log(
|
|
5227
|
+
console.log(chalk62.dim(noCommitsMessage(!!lastInfo)));
|
|
5140
5228
|
}
|
|
5141
5229
|
|
|
5142
5230
|
// src/commands/devlog/next/index.ts
|
|
@@ -5177,11 +5265,11 @@ function next2(options2) {
|
|
|
5177
5265
|
import { execSync as execSync21 } from "child_process";
|
|
5178
5266
|
|
|
5179
5267
|
// src/commands/devlog/repos/printReposTable.ts
|
|
5180
|
-
import
|
|
5268
|
+
import chalk63 from "chalk";
|
|
5181
5269
|
function colorStatus(status2) {
|
|
5182
|
-
if (status2 === "missing") return
|
|
5183
|
-
if (status2 === "outdated") return
|
|
5184
|
-
return
|
|
5270
|
+
if (status2 === "missing") return chalk63.red(status2);
|
|
5271
|
+
if (status2 === "outdated") return chalk63.yellow(status2);
|
|
5272
|
+
return chalk63.green(status2);
|
|
5185
5273
|
}
|
|
5186
5274
|
function formatRow(row, nameWidth) {
|
|
5187
5275
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -5195,8 +5283,8 @@ function printReposTable(rows) {
|
|
|
5195
5283
|
"Last Devlog".padEnd(11),
|
|
5196
5284
|
"Status"
|
|
5197
5285
|
].join(" ");
|
|
5198
|
-
console.log(
|
|
5199
|
-
console.log(
|
|
5286
|
+
console.log(chalk63.dim(header));
|
|
5287
|
+
console.log(chalk63.dim("-".repeat(header.length)));
|
|
5200
5288
|
for (const row of rows) {
|
|
5201
5289
|
console.log(formatRow(row, nameWidth));
|
|
5202
5290
|
}
|
|
@@ -5254,14 +5342,14 @@ function repos(options2) {
|
|
|
5254
5342
|
// src/commands/devlog/skip.ts
|
|
5255
5343
|
import { writeFileSync as writeFileSync18 } from "fs";
|
|
5256
5344
|
import { join as join17 } from "path";
|
|
5257
|
-
import
|
|
5345
|
+
import chalk64 from "chalk";
|
|
5258
5346
|
import { stringify as stringifyYaml4 } from "yaml";
|
|
5259
5347
|
function getBlogConfigPath() {
|
|
5260
5348
|
return join17(BLOG_REPO_ROOT, "assist.yml");
|
|
5261
5349
|
}
|
|
5262
5350
|
function skip(date) {
|
|
5263
5351
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5264
|
-
console.log(
|
|
5352
|
+
console.log(chalk64.red("Invalid date format. Use YYYY-MM-DD"));
|
|
5265
5353
|
process.exit(1);
|
|
5266
5354
|
}
|
|
5267
5355
|
const repoName = getRepoName();
|
|
@@ -5272,7 +5360,7 @@ function skip(date) {
|
|
|
5272
5360
|
const skipDays = skip2[repoName] ?? [];
|
|
5273
5361
|
if (skipDays.includes(date)) {
|
|
5274
5362
|
console.log(
|
|
5275
|
-
|
|
5363
|
+
chalk64.yellow(`${date} is already in skip list for ${repoName}`)
|
|
5276
5364
|
);
|
|
5277
5365
|
return;
|
|
5278
5366
|
}
|
|
@@ -5282,20 +5370,20 @@ function skip(date) {
|
|
|
5282
5370
|
devlog.skip = skip2;
|
|
5283
5371
|
config.devlog = devlog;
|
|
5284
5372
|
writeFileSync18(configPath, stringifyYaml4(config, { lineWidth: 0 }));
|
|
5285
|
-
console.log(
|
|
5373
|
+
console.log(chalk64.green(`Added ${date} to skip list for ${repoName}`));
|
|
5286
5374
|
}
|
|
5287
5375
|
|
|
5288
5376
|
// src/commands/devlog/version.ts
|
|
5289
|
-
import
|
|
5377
|
+
import chalk65 from "chalk";
|
|
5290
5378
|
function version() {
|
|
5291
5379
|
const config = loadConfig();
|
|
5292
5380
|
const name = getRepoName();
|
|
5293
5381
|
const lastInfo = getLastVersionInfo(name, config);
|
|
5294
5382
|
const lastVersion = lastInfo?.version ?? null;
|
|
5295
5383
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
5296
|
-
console.log(`${
|
|
5297
|
-
console.log(`${
|
|
5298
|
-
console.log(`${
|
|
5384
|
+
console.log(`${chalk65.bold("name:")} ${name}`);
|
|
5385
|
+
console.log(`${chalk65.bold("last:")} ${lastVersion ?? chalk65.dim("none")}`);
|
|
5386
|
+
console.log(`${chalk65.bold("next:")} ${nextVersion ?? chalk65.dim("none")}`);
|
|
5299
5387
|
}
|
|
5300
5388
|
|
|
5301
5389
|
// src/commands/registerDevlog.ts
|
|
@@ -5319,7 +5407,7 @@ function registerDevlog(program2) {
|
|
|
5319
5407
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5320
5408
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5321
5409
|
import { join as join18 } from "path";
|
|
5322
|
-
import
|
|
5410
|
+
import chalk66 from "chalk";
|
|
5323
5411
|
|
|
5324
5412
|
// src/shared/findRepoRoot.ts
|
|
5325
5413
|
import { existsSync as existsSync24 } from "fs";
|
|
@@ -5382,14 +5470,14 @@ function checkBuildLocks(startDir) {
|
|
|
5382
5470
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
5383
5471
|
if (locked) {
|
|
5384
5472
|
console.error(
|
|
5385
|
-
|
|
5473
|
+
chalk66.red("Build output locked (is VS debugging?): ") + locked
|
|
5386
5474
|
);
|
|
5387
5475
|
process.exit(1);
|
|
5388
5476
|
}
|
|
5389
5477
|
}
|
|
5390
5478
|
async function checkBuildLocksCommand() {
|
|
5391
5479
|
checkBuildLocks();
|
|
5392
|
-
console.log(
|
|
5480
|
+
console.log(chalk66.green("No build locks detected"));
|
|
5393
5481
|
}
|
|
5394
5482
|
|
|
5395
5483
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -5488,30 +5576,30 @@ function escapeRegex(s) {
|
|
|
5488
5576
|
}
|
|
5489
5577
|
|
|
5490
5578
|
// src/commands/dotnet/printTree.ts
|
|
5491
|
-
import
|
|
5579
|
+
import chalk67 from "chalk";
|
|
5492
5580
|
function printNodes(nodes, prefix2) {
|
|
5493
5581
|
for (let i = 0; i < nodes.length; i++) {
|
|
5494
5582
|
const isLast = i === nodes.length - 1;
|
|
5495
5583
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5496
5584
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
5497
5585
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
5498
|
-
const label2 = isMissing ?
|
|
5586
|
+
const label2 = isMissing ? chalk67.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
5499
5587
|
console.log(`${prefix2}${connector}${label2}`);
|
|
5500
5588
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
5501
5589
|
}
|
|
5502
5590
|
}
|
|
5503
5591
|
function printTree(tree, totalCount, solutions) {
|
|
5504
|
-
console.log(
|
|
5505
|
-
console.log(
|
|
5592
|
+
console.log(chalk67.bold("\nProject Dependency Tree"));
|
|
5593
|
+
console.log(chalk67.cyan(tree.relativePath));
|
|
5506
5594
|
printNodes(tree.children, "");
|
|
5507
|
-
console.log(
|
|
5595
|
+
console.log(chalk67.dim(`
|
|
5508
5596
|
${totalCount} projects total (including root)`));
|
|
5509
|
-
console.log(
|
|
5597
|
+
console.log(chalk67.bold("\nSolution Membership"));
|
|
5510
5598
|
if (solutions.length === 0) {
|
|
5511
|
-
console.log(
|
|
5599
|
+
console.log(chalk67.yellow(" Not found in any .sln"));
|
|
5512
5600
|
} else {
|
|
5513
5601
|
for (const sln of solutions) {
|
|
5514
|
-
console.log(` ${
|
|
5602
|
+
console.log(` ${chalk67.green(sln)}`);
|
|
5515
5603
|
}
|
|
5516
5604
|
}
|
|
5517
5605
|
console.log();
|
|
@@ -5540,16 +5628,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
5540
5628
|
// src/commands/dotnet/resolveCsproj.ts
|
|
5541
5629
|
import { existsSync as existsSync25 } from "fs";
|
|
5542
5630
|
import path24 from "path";
|
|
5543
|
-
import
|
|
5631
|
+
import chalk68 from "chalk";
|
|
5544
5632
|
function resolveCsproj(csprojPath) {
|
|
5545
5633
|
const resolved = path24.resolve(csprojPath);
|
|
5546
5634
|
if (!existsSync25(resolved)) {
|
|
5547
|
-
console.error(
|
|
5635
|
+
console.error(chalk68.red(`File not found: ${resolved}`));
|
|
5548
5636
|
process.exit(1);
|
|
5549
5637
|
}
|
|
5550
5638
|
const repoRoot = findRepoRoot(path24.dirname(resolved));
|
|
5551
5639
|
if (!repoRoot) {
|
|
5552
|
-
console.error(
|
|
5640
|
+
console.error(chalk68.red("Could not find git repository root"));
|
|
5553
5641
|
process.exit(1);
|
|
5554
5642
|
}
|
|
5555
5643
|
return { resolved, repoRoot };
|
|
@@ -5599,12 +5687,12 @@ function getChangedCsFiles(scope) {
|
|
|
5599
5687
|
}
|
|
5600
5688
|
|
|
5601
5689
|
// src/commands/dotnet/inSln.ts
|
|
5602
|
-
import
|
|
5690
|
+
import chalk69 from "chalk";
|
|
5603
5691
|
async function inSln(csprojPath) {
|
|
5604
5692
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
5605
5693
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
5606
5694
|
if (solutions.length === 0) {
|
|
5607
|
-
console.log(
|
|
5695
|
+
console.log(chalk69.yellow("Not found in any .sln file"));
|
|
5608
5696
|
process.exit(1);
|
|
5609
5697
|
}
|
|
5610
5698
|
for (const sln of solutions) {
|
|
@@ -5613,7 +5701,7 @@ async function inSln(csprojPath) {
|
|
|
5613
5701
|
}
|
|
5614
5702
|
|
|
5615
5703
|
// src/commands/dotnet/inspect.ts
|
|
5616
|
-
import
|
|
5704
|
+
import chalk75 from "chalk";
|
|
5617
5705
|
|
|
5618
5706
|
// src/shared/formatElapsed.ts
|
|
5619
5707
|
function formatElapsed(ms) {
|
|
@@ -5625,12 +5713,12 @@ function formatElapsed(ms) {
|
|
|
5625
5713
|
}
|
|
5626
5714
|
|
|
5627
5715
|
// src/commands/dotnet/displayIssues.ts
|
|
5628
|
-
import
|
|
5716
|
+
import chalk70 from "chalk";
|
|
5629
5717
|
var SEVERITY_COLOR = {
|
|
5630
|
-
ERROR:
|
|
5631
|
-
WARNING:
|
|
5632
|
-
SUGGESTION:
|
|
5633
|
-
HINT:
|
|
5718
|
+
ERROR: chalk70.red,
|
|
5719
|
+
WARNING: chalk70.yellow,
|
|
5720
|
+
SUGGESTION: chalk70.cyan,
|
|
5721
|
+
HINT: chalk70.dim
|
|
5634
5722
|
};
|
|
5635
5723
|
function groupByFile(issues) {
|
|
5636
5724
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -5646,15 +5734,15 @@ function groupByFile(issues) {
|
|
|
5646
5734
|
}
|
|
5647
5735
|
function displayIssues(issues) {
|
|
5648
5736
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
5649
|
-
console.log(
|
|
5737
|
+
console.log(chalk70.bold(file));
|
|
5650
5738
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
5651
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
5739
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk70.white;
|
|
5652
5740
|
console.log(
|
|
5653
|
-
` ${
|
|
5741
|
+
` ${chalk70.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
5654
5742
|
);
|
|
5655
5743
|
}
|
|
5656
5744
|
}
|
|
5657
|
-
console.log(
|
|
5745
|
+
console.log(chalk70.dim(`
|
|
5658
5746
|
${issues.length} issue(s) found`));
|
|
5659
5747
|
}
|
|
5660
5748
|
|
|
@@ -5713,12 +5801,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
5713
5801
|
// src/commands/dotnet/resolveSolution.ts
|
|
5714
5802
|
import { existsSync as existsSync26 } from "fs";
|
|
5715
5803
|
import path25 from "path";
|
|
5716
|
-
import
|
|
5804
|
+
import chalk72 from "chalk";
|
|
5717
5805
|
|
|
5718
5806
|
// src/commands/dotnet/findSolution.ts
|
|
5719
5807
|
import { readdirSync as readdirSync4 } from "fs";
|
|
5720
5808
|
import { dirname as dirname16, join as join19 } from "path";
|
|
5721
|
-
import
|
|
5809
|
+
import chalk71 from "chalk";
|
|
5722
5810
|
function findSlnInDir(dir) {
|
|
5723
5811
|
try {
|
|
5724
5812
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join19(dir, f));
|
|
@@ -5734,17 +5822,17 @@ function findSolution() {
|
|
|
5734
5822
|
const slnFiles = findSlnInDir(current);
|
|
5735
5823
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
5736
5824
|
if (slnFiles.length > 1) {
|
|
5737
|
-
console.error(
|
|
5825
|
+
console.error(chalk71.red(`Multiple .sln files found in ${current}:`));
|
|
5738
5826
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
5739
5827
|
console.error(
|
|
5740
|
-
|
|
5828
|
+
chalk71.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
5741
5829
|
);
|
|
5742
5830
|
process.exit(1);
|
|
5743
5831
|
}
|
|
5744
5832
|
if (current === ceiling) break;
|
|
5745
5833
|
current = dirname16(current);
|
|
5746
5834
|
}
|
|
5747
|
-
console.error(
|
|
5835
|
+
console.error(chalk71.red("No .sln file found between cwd and repo root"));
|
|
5748
5836
|
process.exit(1);
|
|
5749
5837
|
}
|
|
5750
5838
|
|
|
@@ -5753,7 +5841,7 @@ function resolveSolution(sln) {
|
|
|
5753
5841
|
if (sln) {
|
|
5754
5842
|
const resolved = path25.resolve(sln);
|
|
5755
5843
|
if (!existsSync26(resolved)) {
|
|
5756
|
-
console.error(
|
|
5844
|
+
console.error(chalk72.red(`Solution file not found: ${resolved}`));
|
|
5757
5845
|
process.exit(1);
|
|
5758
5846
|
}
|
|
5759
5847
|
return resolved;
|
|
@@ -5795,14 +5883,14 @@ import { execSync as execSync23 } from "child_process";
|
|
|
5795
5883
|
import { existsSync as existsSync27, readFileSync as readFileSync22, unlinkSync as unlinkSync5 } from "fs";
|
|
5796
5884
|
import { tmpdir as tmpdir2 } from "os";
|
|
5797
5885
|
import path26 from "path";
|
|
5798
|
-
import
|
|
5886
|
+
import chalk73 from "chalk";
|
|
5799
5887
|
function assertJbInstalled() {
|
|
5800
5888
|
try {
|
|
5801
5889
|
execSync23("jb inspectcode --version", { stdio: "pipe" });
|
|
5802
5890
|
} catch {
|
|
5803
|
-
console.error(
|
|
5891
|
+
console.error(chalk73.red("jb is not installed. Install with:"));
|
|
5804
5892
|
console.error(
|
|
5805
|
-
|
|
5893
|
+
chalk73.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
5806
5894
|
);
|
|
5807
5895
|
process.exit(1);
|
|
5808
5896
|
}
|
|
@@ -5820,11 +5908,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5820
5908
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
5821
5909
|
process.stderr.write(err.stderr);
|
|
5822
5910
|
}
|
|
5823
|
-
console.error(
|
|
5911
|
+
console.error(chalk73.red("jb inspectcode failed"));
|
|
5824
5912
|
process.exit(1);
|
|
5825
5913
|
}
|
|
5826
5914
|
if (!existsSync27(reportPath)) {
|
|
5827
|
-
console.error(
|
|
5915
|
+
console.error(chalk73.red("Report file not generated"));
|
|
5828
5916
|
process.exit(1);
|
|
5829
5917
|
}
|
|
5830
5918
|
const xml = readFileSync22(reportPath, "utf-8");
|
|
@@ -5834,7 +5922,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
5834
5922
|
|
|
5835
5923
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
5836
5924
|
import { execSync as execSync24 } from "child_process";
|
|
5837
|
-
import
|
|
5925
|
+
import chalk74 from "chalk";
|
|
5838
5926
|
function resolveMsbuildPath() {
|
|
5839
5927
|
const config = loadConfig();
|
|
5840
5928
|
const buildConfig = config.run?.find((r) => r.name === "build");
|
|
@@ -5845,9 +5933,9 @@ function assertMsbuildInstalled() {
|
|
|
5845
5933
|
try {
|
|
5846
5934
|
execSync24(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
5847
5935
|
} catch {
|
|
5848
|
-
console.error(
|
|
5936
|
+
console.error(chalk74.red(`msbuild not found at: ${msbuild}`));
|
|
5849
5937
|
console.error(
|
|
5850
|
-
|
|
5938
|
+
chalk74.yellow(
|
|
5851
5939
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
5852
5940
|
)
|
|
5853
5941
|
);
|
|
@@ -5894,17 +5982,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
5894
5982
|
// src/commands/dotnet/inspect.ts
|
|
5895
5983
|
function logScope(changedFiles) {
|
|
5896
5984
|
if (changedFiles === null) {
|
|
5897
|
-
console.log(
|
|
5985
|
+
console.log(chalk75.dim("Inspecting full solution..."));
|
|
5898
5986
|
} else {
|
|
5899
5987
|
console.log(
|
|
5900
|
-
|
|
5988
|
+
chalk75.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
5901
5989
|
);
|
|
5902
5990
|
}
|
|
5903
5991
|
}
|
|
5904
5992
|
function reportResults(issues, elapsed) {
|
|
5905
5993
|
if (issues.length > 0) displayIssues(issues);
|
|
5906
|
-
else console.log(
|
|
5907
|
-
console.log(
|
|
5994
|
+
else console.log(chalk75.green("No issues found"));
|
|
5995
|
+
console.log(chalk75.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
5908
5996
|
if (issues.length > 0) process.exit(1);
|
|
5909
5997
|
}
|
|
5910
5998
|
async function inspect(sln, options2) {
|
|
@@ -5915,7 +6003,7 @@ async function inspect(sln, options2) {
|
|
|
5915
6003
|
const scope = parseScope(options2.scope);
|
|
5916
6004
|
const changedFiles = getChangedCsFiles(scope);
|
|
5917
6005
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
5918
|
-
console.log(
|
|
6006
|
+
console.log(chalk75.green("No changed .cs files found"));
|
|
5919
6007
|
return;
|
|
5920
6008
|
}
|
|
5921
6009
|
logScope(changedFiles);
|
|
@@ -5941,7 +6029,7 @@ function registerDotnet(program2) {
|
|
|
5941
6029
|
}
|
|
5942
6030
|
|
|
5943
6031
|
// src/commands/jira/acceptanceCriteria.ts
|
|
5944
|
-
import
|
|
6032
|
+
import chalk77 from "chalk";
|
|
5945
6033
|
|
|
5946
6034
|
// src/commands/jira/adfToText.ts
|
|
5947
6035
|
function renderInline(node) {
|
|
@@ -6002,7 +6090,7 @@ function adfToText(doc) {
|
|
|
6002
6090
|
|
|
6003
6091
|
// src/commands/jira/fetchIssue.ts
|
|
6004
6092
|
import { execSync as execSync25 } from "child_process";
|
|
6005
|
-
import
|
|
6093
|
+
import chalk76 from "chalk";
|
|
6006
6094
|
function fetchIssue(issueKey, fields) {
|
|
6007
6095
|
let result;
|
|
6008
6096
|
try {
|
|
@@ -6015,15 +6103,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
6015
6103
|
const stderr = error.stderr;
|
|
6016
6104
|
if (stderr.includes("unauthorized")) {
|
|
6017
6105
|
console.error(
|
|
6018
|
-
|
|
6106
|
+
chalk76.red("Jira authentication expired."),
|
|
6019
6107
|
"Run",
|
|
6020
|
-
|
|
6108
|
+
chalk76.cyan("assist jira auth"),
|
|
6021
6109
|
"to re-authenticate."
|
|
6022
6110
|
);
|
|
6023
6111
|
process.exit(1);
|
|
6024
6112
|
}
|
|
6025
6113
|
}
|
|
6026
|
-
console.error(
|
|
6114
|
+
console.error(chalk76.red(`Failed to fetch ${issueKey}.`));
|
|
6027
6115
|
process.exit(1);
|
|
6028
6116
|
}
|
|
6029
6117
|
return JSON.parse(result);
|
|
@@ -6037,7 +6125,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
6037
6125
|
const parsed = fetchIssue(issueKey, field);
|
|
6038
6126
|
const acValue = parsed?.fields?.[field];
|
|
6039
6127
|
if (!acValue) {
|
|
6040
|
-
console.log(
|
|
6128
|
+
console.log(chalk77.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
6041
6129
|
return;
|
|
6042
6130
|
}
|
|
6043
6131
|
if (typeof acValue === "string") {
|
|
@@ -6132,14 +6220,14 @@ async function jiraAuth() {
|
|
|
6132
6220
|
}
|
|
6133
6221
|
|
|
6134
6222
|
// src/commands/jira/viewIssue.ts
|
|
6135
|
-
import
|
|
6223
|
+
import chalk78 from "chalk";
|
|
6136
6224
|
function viewIssue(issueKey) {
|
|
6137
6225
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
6138
6226
|
const fields = parsed?.fields;
|
|
6139
6227
|
const summary = fields?.summary;
|
|
6140
6228
|
const description = fields?.description;
|
|
6141
6229
|
if (summary) {
|
|
6142
|
-
console.log(
|
|
6230
|
+
console.log(chalk78.bold(summary));
|
|
6143
6231
|
}
|
|
6144
6232
|
if (description) {
|
|
6145
6233
|
if (summary) console.log();
|
|
@@ -6153,7 +6241,7 @@ function viewIssue(issueKey) {
|
|
|
6153
6241
|
}
|
|
6154
6242
|
if (!summary && !description) {
|
|
6155
6243
|
console.log(
|
|
6156
|
-
|
|
6244
|
+
chalk78.yellow(`No summary or description found on ${issueKey}.`)
|
|
6157
6245
|
);
|
|
6158
6246
|
}
|
|
6159
6247
|
}
|
|
@@ -6167,7 +6255,7 @@ function registerJira(program2) {
|
|
|
6167
6255
|
}
|
|
6168
6256
|
|
|
6169
6257
|
// src/commands/news/add/index.ts
|
|
6170
|
-
import
|
|
6258
|
+
import chalk79 from "chalk";
|
|
6171
6259
|
import enquirer7 from "enquirer";
|
|
6172
6260
|
async function add2(url) {
|
|
6173
6261
|
if (!url) {
|
|
@@ -6190,17 +6278,17 @@ async function add2(url) {
|
|
|
6190
6278
|
const news = config.news ?? {};
|
|
6191
6279
|
const feeds = news.feeds ?? [];
|
|
6192
6280
|
if (feeds.includes(url)) {
|
|
6193
|
-
console.log(
|
|
6281
|
+
console.log(chalk79.yellow("Feed already exists in config"));
|
|
6194
6282
|
return;
|
|
6195
6283
|
}
|
|
6196
6284
|
feeds.push(url);
|
|
6197
6285
|
config.news = { ...news, feeds };
|
|
6198
6286
|
saveGlobalConfig(config);
|
|
6199
|
-
console.log(
|
|
6287
|
+
console.log(chalk79.green(`Added feed: ${url}`));
|
|
6200
6288
|
}
|
|
6201
6289
|
|
|
6202
6290
|
// src/commands/news/web/handleRequest.ts
|
|
6203
|
-
import
|
|
6291
|
+
import chalk80 from "chalk";
|
|
6204
6292
|
|
|
6205
6293
|
// src/commands/news/web/shared.ts
|
|
6206
6294
|
import { decodeHTML } from "entities";
|
|
@@ -6336,17 +6424,17 @@ function prefetch() {
|
|
|
6336
6424
|
const config = loadConfig();
|
|
6337
6425
|
const total = config.news.feeds.length;
|
|
6338
6426
|
if (total === 0) return;
|
|
6339
|
-
process.stdout.write(
|
|
6427
|
+
process.stdout.write(chalk80.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
6340
6428
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
6341
6429
|
const width = 20;
|
|
6342
6430
|
const filled = Math.round(done2 / t * width);
|
|
6343
6431
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
6344
6432
|
process.stdout.write(
|
|
6345
|
-
`\r${
|
|
6433
|
+
`\r${chalk80.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
6346
6434
|
);
|
|
6347
6435
|
}).then((items) => {
|
|
6348
6436
|
process.stdout.write(
|
|
6349
|
-
`\r${
|
|
6437
|
+
`\r${chalk80.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
6350
6438
|
`
|
|
6351
6439
|
);
|
|
6352
6440
|
cachedItems = items;
|
|
@@ -6707,20 +6795,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
6707
6795
|
}
|
|
6708
6796
|
|
|
6709
6797
|
// src/commands/prs/listComments/printComments.ts
|
|
6710
|
-
import
|
|
6798
|
+
import chalk81 from "chalk";
|
|
6711
6799
|
function formatForHuman(comment3) {
|
|
6712
6800
|
if (comment3.type === "review") {
|
|
6713
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
6801
|
+
const stateColor = comment3.state === "APPROVED" ? chalk81.green : comment3.state === "CHANGES_REQUESTED" ? chalk81.red : chalk81.yellow;
|
|
6714
6802
|
return [
|
|
6715
|
-
`${
|
|
6803
|
+
`${chalk81.cyan("Review")} by ${chalk81.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
6716
6804
|
comment3.body,
|
|
6717
6805
|
""
|
|
6718
6806
|
].join("\n");
|
|
6719
6807
|
}
|
|
6720
6808
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
6721
6809
|
return [
|
|
6722
|
-
`${
|
|
6723
|
-
|
|
6810
|
+
`${chalk81.cyan("Line comment")} by ${chalk81.bold(comment3.user)} on ${chalk81.dim(`${comment3.path}${location}`)}`,
|
|
6811
|
+
chalk81.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
6724
6812
|
comment3.body,
|
|
6725
6813
|
""
|
|
6726
6814
|
].join("\n");
|
|
@@ -6810,13 +6898,13 @@ import { execSync as execSync32 } from "child_process";
|
|
|
6810
6898
|
import enquirer8 from "enquirer";
|
|
6811
6899
|
|
|
6812
6900
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
6813
|
-
import
|
|
6901
|
+
import chalk82 from "chalk";
|
|
6814
6902
|
var STATUS_MAP = {
|
|
6815
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
6816
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
6903
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk82.magenta("merged"), date: pr.mergedAt } : null,
|
|
6904
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk82.red("closed"), date: pr.closedAt } : null
|
|
6817
6905
|
};
|
|
6818
6906
|
function defaultStatus(pr) {
|
|
6819
|
-
return { label:
|
|
6907
|
+
return { label: chalk82.green("opened"), date: pr.createdAt };
|
|
6820
6908
|
}
|
|
6821
6909
|
function getStatus2(pr) {
|
|
6822
6910
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -6825,11 +6913,11 @@ function formatDate(dateStr) {
|
|
|
6825
6913
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
6826
6914
|
}
|
|
6827
6915
|
function formatPrHeader(pr, status2) {
|
|
6828
|
-
return `${
|
|
6916
|
+
return `${chalk82.cyan(`#${pr.number}`)} ${pr.title} ${chalk82.dim(`(${pr.author.login},`)} ${status2.label} ${chalk82.dim(`${formatDate(status2.date)})`)}`;
|
|
6829
6917
|
}
|
|
6830
6918
|
function logPrDetails(pr) {
|
|
6831
6919
|
console.log(
|
|
6832
|
-
|
|
6920
|
+
chalk82.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
6833
6921
|
);
|
|
6834
6922
|
console.log();
|
|
6835
6923
|
}
|
|
@@ -6995,10 +7083,10 @@ function registerPrs(program2) {
|
|
|
6995
7083
|
}
|
|
6996
7084
|
|
|
6997
7085
|
// src/commands/ravendb/ravendbAuth.ts
|
|
6998
|
-
import
|
|
7086
|
+
import chalk88 from "chalk";
|
|
6999
7087
|
|
|
7000
7088
|
// src/shared/createConnectionAuth.ts
|
|
7001
|
-
import
|
|
7089
|
+
import chalk83 from "chalk";
|
|
7002
7090
|
function listConnections(connections, format2) {
|
|
7003
7091
|
if (connections.length === 0) {
|
|
7004
7092
|
console.log("No connections configured.");
|
|
@@ -7011,7 +7099,7 @@ function listConnections(connections, format2) {
|
|
|
7011
7099
|
function removeConnection(connections, name, save) {
|
|
7012
7100
|
const filtered = connections.filter((c) => c.name !== name);
|
|
7013
7101
|
if (filtered.length === connections.length) {
|
|
7014
|
-
console.error(
|
|
7102
|
+
console.error(chalk83.red(`Connection "${name}" not found.`));
|
|
7015
7103
|
process.exit(1);
|
|
7016
7104
|
}
|
|
7017
7105
|
save(filtered);
|
|
@@ -7057,15 +7145,15 @@ function saveConnections(connections) {
|
|
|
7057
7145
|
}
|
|
7058
7146
|
|
|
7059
7147
|
// src/commands/ravendb/promptConnection.ts
|
|
7060
|
-
import
|
|
7148
|
+
import chalk86 from "chalk";
|
|
7061
7149
|
|
|
7062
7150
|
// src/commands/ravendb/selectOpSecret.ts
|
|
7063
|
-
import
|
|
7151
|
+
import chalk85 from "chalk";
|
|
7064
7152
|
import Enquirer2 from "enquirer";
|
|
7065
7153
|
|
|
7066
7154
|
// src/commands/ravendb/searchItems.ts
|
|
7067
7155
|
import { execSync as execSync34 } from "child_process";
|
|
7068
|
-
import
|
|
7156
|
+
import chalk84 from "chalk";
|
|
7069
7157
|
function opExec(args) {
|
|
7070
7158
|
return execSync34(`op ${args}`, {
|
|
7071
7159
|
encoding: "utf-8",
|
|
@@ -7078,7 +7166,7 @@ function searchItems(search) {
|
|
|
7078
7166
|
items = JSON.parse(opExec("item list --format=json"));
|
|
7079
7167
|
} catch {
|
|
7080
7168
|
console.error(
|
|
7081
|
-
|
|
7169
|
+
chalk84.red(
|
|
7082
7170
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
7083
7171
|
)
|
|
7084
7172
|
);
|
|
@@ -7092,7 +7180,7 @@ function getItemFields(itemId) {
|
|
|
7092
7180
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
7093
7181
|
return item.fields.filter((f) => f.reference && f.label);
|
|
7094
7182
|
} catch {
|
|
7095
|
-
console.error(
|
|
7183
|
+
console.error(chalk84.red("Failed to get item details from 1Password."));
|
|
7096
7184
|
process.exit(1);
|
|
7097
7185
|
}
|
|
7098
7186
|
}
|
|
@@ -7111,7 +7199,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7111
7199
|
}).run();
|
|
7112
7200
|
const items = searchItems(search);
|
|
7113
7201
|
if (items.length === 0) {
|
|
7114
|
-
console.error(
|
|
7202
|
+
console.error(chalk85.red(`No items found matching "${search}".`));
|
|
7115
7203
|
process.exit(1);
|
|
7116
7204
|
}
|
|
7117
7205
|
const itemId = await selectOne(
|
|
@@ -7120,7 +7208,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7120
7208
|
);
|
|
7121
7209
|
const fields = getItemFields(itemId);
|
|
7122
7210
|
if (fields.length === 0) {
|
|
7123
|
-
console.error(
|
|
7211
|
+
console.error(chalk85.red("No fields with references found on this item."));
|
|
7124
7212
|
process.exit(1);
|
|
7125
7213
|
}
|
|
7126
7214
|
const ref = await selectOne(
|
|
@@ -7134,7 +7222,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
7134
7222
|
async function promptConnection(existingNames) {
|
|
7135
7223
|
const name = await promptInput("name", "Connection name:");
|
|
7136
7224
|
if (existingNames.includes(name)) {
|
|
7137
|
-
console.error(
|
|
7225
|
+
console.error(chalk86.red(`Connection "${name}" already exists.`));
|
|
7138
7226
|
process.exit(1);
|
|
7139
7227
|
}
|
|
7140
7228
|
const url = await promptInput(
|
|
@@ -7143,22 +7231,22 @@ async function promptConnection(existingNames) {
|
|
|
7143
7231
|
);
|
|
7144
7232
|
const database = await promptInput("database", "Database name:");
|
|
7145
7233
|
if (!name || !url || !database) {
|
|
7146
|
-
console.error(
|
|
7234
|
+
console.error(chalk86.red("All fields are required."));
|
|
7147
7235
|
process.exit(1);
|
|
7148
7236
|
}
|
|
7149
7237
|
const apiKeyRef = await selectOpSecret();
|
|
7150
|
-
console.log(
|
|
7238
|
+
console.log(chalk86.dim(`Using: ${apiKeyRef}`));
|
|
7151
7239
|
return { name, url, database, apiKeyRef };
|
|
7152
7240
|
}
|
|
7153
7241
|
|
|
7154
7242
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
7155
|
-
import
|
|
7243
|
+
import chalk87 from "chalk";
|
|
7156
7244
|
function ravendbSetConnection(name) {
|
|
7157
7245
|
const raw = loadGlobalConfigRaw();
|
|
7158
7246
|
const ravendb = raw.ravendb ?? {};
|
|
7159
7247
|
const connections = ravendb.connections ?? [];
|
|
7160
7248
|
if (!connections.some((c) => c.name === name)) {
|
|
7161
|
-
console.error(
|
|
7249
|
+
console.error(chalk87.red(`Connection "${name}" not found.`));
|
|
7162
7250
|
console.error(
|
|
7163
7251
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7164
7252
|
);
|
|
@@ -7174,16 +7262,16 @@ function ravendbSetConnection(name) {
|
|
|
7174
7262
|
var ravendbAuth = createConnectionAuth({
|
|
7175
7263
|
load: loadConnections,
|
|
7176
7264
|
save: saveConnections,
|
|
7177
|
-
format: (c) => `${
|
|
7265
|
+
format: (c) => `${chalk88.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
7178
7266
|
promptNew: promptConnection,
|
|
7179
7267
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
7180
7268
|
});
|
|
7181
7269
|
|
|
7182
7270
|
// src/commands/ravendb/ravendbCollections.ts
|
|
7183
|
-
import
|
|
7271
|
+
import chalk92 from "chalk";
|
|
7184
7272
|
|
|
7185
7273
|
// src/commands/ravendb/ravenFetch.ts
|
|
7186
|
-
import
|
|
7274
|
+
import chalk90 from "chalk";
|
|
7187
7275
|
|
|
7188
7276
|
// src/commands/ravendb/getAccessToken.ts
|
|
7189
7277
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -7220,10 +7308,10 @@ ${errorText}`
|
|
|
7220
7308
|
|
|
7221
7309
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
7222
7310
|
import { execSync as execSync35 } from "child_process";
|
|
7223
|
-
import
|
|
7311
|
+
import chalk89 from "chalk";
|
|
7224
7312
|
function resolveOpSecret(reference) {
|
|
7225
7313
|
if (!reference.startsWith("op://")) {
|
|
7226
|
-
console.error(
|
|
7314
|
+
console.error(chalk89.red(`Invalid secret reference: must start with op://`));
|
|
7227
7315
|
process.exit(1);
|
|
7228
7316
|
}
|
|
7229
7317
|
try {
|
|
@@ -7233,7 +7321,7 @@ function resolveOpSecret(reference) {
|
|
|
7233
7321
|
}).trim();
|
|
7234
7322
|
} catch {
|
|
7235
7323
|
console.error(
|
|
7236
|
-
|
|
7324
|
+
chalk89.red(
|
|
7237
7325
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
7238
7326
|
)
|
|
7239
7327
|
);
|
|
@@ -7260,7 +7348,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7260
7348
|
if (!response.ok) {
|
|
7261
7349
|
const body = await response.text();
|
|
7262
7350
|
console.error(
|
|
7263
|
-
|
|
7351
|
+
chalk90.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
7264
7352
|
);
|
|
7265
7353
|
console.error(body.substring(0, 500));
|
|
7266
7354
|
process.exit(1);
|
|
@@ -7269,7 +7357,7 @@ async function ravenFetch(connection, path50) {
|
|
|
7269
7357
|
}
|
|
7270
7358
|
|
|
7271
7359
|
// src/commands/ravendb/resolveConnection.ts
|
|
7272
|
-
import
|
|
7360
|
+
import chalk91 from "chalk";
|
|
7273
7361
|
function loadRavendb() {
|
|
7274
7362
|
const raw = loadGlobalConfigRaw();
|
|
7275
7363
|
const ravendb = raw.ravendb;
|
|
@@ -7283,7 +7371,7 @@ function resolveConnection(name) {
|
|
|
7283
7371
|
const connectionName = name ?? defaultConnection;
|
|
7284
7372
|
if (!connectionName) {
|
|
7285
7373
|
console.error(
|
|
7286
|
-
|
|
7374
|
+
chalk91.red(
|
|
7287
7375
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
7288
7376
|
)
|
|
7289
7377
|
);
|
|
@@ -7291,7 +7379,7 @@ function resolveConnection(name) {
|
|
|
7291
7379
|
}
|
|
7292
7380
|
const connection = connections.find((c) => c.name === connectionName);
|
|
7293
7381
|
if (!connection) {
|
|
7294
|
-
console.error(
|
|
7382
|
+
console.error(chalk91.red(`Connection "${connectionName}" not found.`));
|
|
7295
7383
|
console.error(
|
|
7296
7384
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
7297
7385
|
);
|
|
@@ -7322,15 +7410,15 @@ async function ravendbCollections(connectionName) {
|
|
|
7322
7410
|
return;
|
|
7323
7411
|
}
|
|
7324
7412
|
for (const c of collections) {
|
|
7325
|
-
console.log(`${
|
|
7413
|
+
console.log(`${chalk92.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
7326
7414
|
}
|
|
7327
7415
|
}
|
|
7328
7416
|
|
|
7329
7417
|
// src/commands/ravendb/ravendbQuery.ts
|
|
7330
|
-
import
|
|
7418
|
+
import chalk94 from "chalk";
|
|
7331
7419
|
|
|
7332
7420
|
// src/commands/ravendb/fetchAllPages.ts
|
|
7333
|
-
import
|
|
7421
|
+
import chalk93 from "chalk";
|
|
7334
7422
|
|
|
7335
7423
|
// src/commands/ravendb/buildQueryPath.ts
|
|
7336
7424
|
function buildQueryPath(opts) {
|
|
@@ -7368,7 +7456,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7368
7456
|
allResults.push(...results);
|
|
7369
7457
|
start3 += results.length;
|
|
7370
7458
|
process.stderr.write(
|
|
7371
|
-
`\r${
|
|
7459
|
+
`\r${chalk93.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
7372
7460
|
);
|
|
7373
7461
|
if (start3 >= totalResults) break;
|
|
7374
7462
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -7383,7 +7471,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
7383
7471
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
7384
7472
|
const resolved = resolveArgs(connectionName, collection);
|
|
7385
7473
|
if (!resolved.collection && !options2.query) {
|
|
7386
|
-
console.error(
|
|
7474
|
+
console.error(chalk94.red("Provide a collection name or --query filter."));
|
|
7387
7475
|
process.exit(1);
|
|
7388
7476
|
}
|
|
7389
7477
|
const { collection: col } = resolved;
|
|
@@ -7421,7 +7509,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
7421
7509
|
import * as path27 from "path";
|
|
7422
7510
|
|
|
7423
7511
|
// src/commands/refactor/logViolations.ts
|
|
7424
|
-
import
|
|
7512
|
+
import chalk95 from "chalk";
|
|
7425
7513
|
var DEFAULT_MAX_LINES = 100;
|
|
7426
7514
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
7427
7515
|
if (violations.length === 0) {
|
|
@@ -7430,43 +7518,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
7430
7518
|
}
|
|
7431
7519
|
return;
|
|
7432
7520
|
}
|
|
7433
|
-
console.error(
|
|
7521
|
+
console.error(chalk95.red(`
|
|
7434
7522
|
Refactor check failed:
|
|
7435
7523
|
`));
|
|
7436
|
-
console.error(
|
|
7524
|
+
console.error(chalk95.red(` The following files exceed ${maxLines} lines:
|
|
7437
7525
|
`));
|
|
7438
7526
|
for (const violation of violations) {
|
|
7439
|
-
console.error(
|
|
7527
|
+
console.error(chalk95.red(` ${violation.file} (${violation.lines} lines)`));
|
|
7440
7528
|
}
|
|
7441
7529
|
console.error(
|
|
7442
|
-
|
|
7530
|
+
chalk95.yellow(
|
|
7443
7531
|
`
|
|
7444
7532
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
7445
7533
|
way to refactor it, ignore it with:
|
|
7446
7534
|
`
|
|
7447
7535
|
)
|
|
7448
7536
|
);
|
|
7449
|
-
console.error(
|
|
7537
|
+
console.error(chalk95.gray(` assist refactor ignore <file>
|
|
7450
7538
|
`));
|
|
7451
7539
|
if (process.env.CLAUDECODE) {
|
|
7452
|
-
console.error(
|
|
7540
|
+
console.error(chalk95.cyan(`
|
|
7453
7541
|
## Extracting Code to New Files
|
|
7454
7542
|
`));
|
|
7455
7543
|
console.error(
|
|
7456
|
-
|
|
7544
|
+
chalk95.cyan(
|
|
7457
7545
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
7458
7546
|
`
|
|
7459
7547
|
)
|
|
7460
7548
|
);
|
|
7461
7549
|
console.error(
|
|
7462
|
-
|
|
7550
|
+
chalk95.cyan(
|
|
7463
7551
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
7464
7552
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
7465
7553
|
`
|
|
7466
7554
|
)
|
|
7467
7555
|
);
|
|
7468
7556
|
console.error(
|
|
7469
|
-
|
|
7557
|
+
chalk95.cyan(
|
|
7470
7558
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
7471
7559
|
domains, move it to a common/shared folder.
|
|
7472
7560
|
`
|
|
@@ -7622,7 +7710,7 @@ async function check(pattern2, options2) {
|
|
|
7622
7710
|
|
|
7623
7711
|
// src/commands/refactor/extract/index.ts
|
|
7624
7712
|
import path33 from "path";
|
|
7625
|
-
import
|
|
7713
|
+
import chalk98 from "chalk";
|
|
7626
7714
|
|
|
7627
7715
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
7628
7716
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -8148,23 +8236,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
8148
8236
|
|
|
8149
8237
|
// src/commands/refactor/extract/displayPlan.ts
|
|
8150
8238
|
import path31 from "path";
|
|
8151
|
-
import
|
|
8239
|
+
import chalk96 from "chalk";
|
|
8152
8240
|
function section(title) {
|
|
8153
8241
|
return `
|
|
8154
|
-
${
|
|
8242
|
+
${chalk96.cyan(title)}`;
|
|
8155
8243
|
}
|
|
8156
8244
|
function displayImporters(plan2, cwd) {
|
|
8157
8245
|
if (plan2.importersToUpdate.length === 0) return;
|
|
8158
8246
|
console.log(section("Update importers:"));
|
|
8159
8247
|
for (const imp of plan2.importersToUpdate) {
|
|
8160
8248
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
8161
|
-
console.log(` ${
|
|
8249
|
+
console.log(` ${chalk96.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
8162
8250
|
}
|
|
8163
8251
|
}
|
|
8164
8252
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
8165
|
-
console.log(
|
|
8253
|
+
console.log(chalk96.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
8166
8254
|
`));
|
|
8167
|
-
console.log(` ${
|
|
8255
|
+
console.log(` ${chalk96.cyan("Functions to move:")}`);
|
|
8168
8256
|
for (const name of plan2.extractedNames) {
|
|
8169
8257
|
console.log(` ${name}`);
|
|
8170
8258
|
}
|
|
@@ -8199,7 +8287,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
8199
8287
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
8200
8288
|
import fs17 from "fs";
|
|
8201
8289
|
import path32 from "path";
|
|
8202
|
-
import
|
|
8290
|
+
import chalk97 from "chalk";
|
|
8203
8291
|
import { Project as Project2 } from "ts-morph";
|
|
8204
8292
|
function findTsConfig(sourcePath) {
|
|
8205
8293
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -8230,7 +8318,7 @@ function loadProjectFile(file) {
|
|
|
8230
8318
|
});
|
|
8231
8319
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
8232
8320
|
if (!sourceFile) {
|
|
8233
|
-
console.log(
|
|
8321
|
+
console.log(chalk97.red(`File not found in project: ${file}`));
|
|
8234
8322
|
process.exit(1);
|
|
8235
8323
|
}
|
|
8236
8324
|
return { project, sourceFile };
|
|
@@ -8253,19 +8341,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
8253
8341
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
8254
8342
|
if (options2.apply) {
|
|
8255
8343
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
8256
|
-
console.log(
|
|
8344
|
+
console.log(chalk98.green("\nExtraction complete"));
|
|
8257
8345
|
} else {
|
|
8258
|
-
console.log(
|
|
8346
|
+
console.log(chalk98.dim("\nDry run. Use --apply to execute."));
|
|
8259
8347
|
}
|
|
8260
8348
|
}
|
|
8261
8349
|
|
|
8262
8350
|
// src/commands/refactor/ignore.ts
|
|
8263
8351
|
import fs18 from "fs";
|
|
8264
|
-
import
|
|
8352
|
+
import chalk99 from "chalk";
|
|
8265
8353
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
8266
8354
|
function ignore(file) {
|
|
8267
8355
|
if (!fs18.existsSync(file)) {
|
|
8268
|
-
console.error(
|
|
8356
|
+
console.error(chalk99.red(`Error: File does not exist: ${file}`));
|
|
8269
8357
|
process.exit(1);
|
|
8270
8358
|
}
|
|
8271
8359
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -8281,7 +8369,7 @@ function ignore(file) {
|
|
|
8281
8369
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
8282
8370
|
}
|
|
8283
8371
|
console.log(
|
|
8284
|
-
|
|
8372
|
+
chalk99.green(
|
|
8285
8373
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
8286
8374
|
)
|
|
8287
8375
|
);
|
|
@@ -8289,26 +8377,26 @@ function ignore(file) {
|
|
|
8289
8377
|
|
|
8290
8378
|
// src/commands/refactor/rename/index.ts
|
|
8291
8379
|
import path34 from "path";
|
|
8292
|
-
import
|
|
8380
|
+
import chalk100 from "chalk";
|
|
8293
8381
|
async function rename(source, destination, options2 = {}) {
|
|
8294
8382
|
const destPath = path34.resolve(destination);
|
|
8295
8383
|
const cwd = process.cwd();
|
|
8296
8384
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
8297
8385
|
const relDest = path34.relative(cwd, destPath);
|
|
8298
8386
|
const { project, sourceFile } = loadProjectFile(source);
|
|
8299
|
-
console.log(
|
|
8387
|
+
console.log(chalk100.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
8300
8388
|
if (options2.apply) {
|
|
8301
8389
|
sourceFile.move(destPath);
|
|
8302
8390
|
await project.save();
|
|
8303
|
-
console.log(
|
|
8391
|
+
console.log(chalk100.green("Done"));
|
|
8304
8392
|
} else {
|
|
8305
|
-
console.log(
|
|
8393
|
+
console.log(chalk100.dim("Dry run. Use --apply to execute."));
|
|
8306
8394
|
}
|
|
8307
8395
|
}
|
|
8308
8396
|
|
|
8309
8397
|
// src/commands/refactor/renameSymbol/index.ts
|
|
8310
8398
|
import path36 from "path";
|
|
8311
|
-
import
|
|
8399
|
+
import chalk101 from "chalk";
|
|
8312
8400
|
import { Project as Project3 } from "ts-morph";
|
|
8313
8401
|
|
|
8314
8402
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -8357,38 +8445,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
8357
8445
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
8358
8446
|
const sourceFile = project.getSourceFile(filePath);
|
|
8359
8447
|
if (!sourceFile) {
|
|
8360
|
-
console.log(
|
|
8448
|
+
console.log(chalk101.red(`File not found in project: ${file}`));
|
|
8361
8449
|
process.exit(1);
|
|
8362
8450
|
}
|
|
8363
8451
|
const symbol = findSymbol(sourceFile, oldName);
|
|
8364
8452
|
if (!symbol) {
|
|
8365
|
-
console.log(
|
|
8453
|
+
console.log(chalk101.red(`Symbol "${oldName}" not found in ${file}`));
|
|
8366
8454
|
process.exit(1);
|
|
8367
8455
|
}
|
|
8368
8456
|
const grouped = groupReferences(symbol, cwd);
|
|
8369
8457
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
8370
8458
|
console.log(
|
|
8371
|
-
|
|
8459
|
+
chalk101.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
8372
8460
|
`)
|
|
8373
8461
|
);
|
|
8374
8462
|
for (const [refFile, lines] of grouped) {
|
|
8375
8463
|
console.log(
|
|
8376
|
-
` ${
|
|
8464
|
+
` ${chalk101.dim(refFile)}: lines ${chalk101.cyan(lines.join(", "))}`
|
|
8377
8465
|
);
|
|
8378
8466
|
}
|
|
8379
8467
|
if (options2.apply) {
|
|
8380
8468
|
symbol.rename(newName);
|
|
8381
8469
|
await project.save();
|
|
8382
|
-
console.log(
|
|
8470
|
+
console.log(chalk101.green(`
|
|
8383
8471
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
8384
8472
|
} else {
|
|
8385
|
-
console.log(
|
|
8473
|
+
console.log(chalk101.dim("\nDry run. Use --apply to execute."));
|
|
8386
8474
|
}
|
|
8387
8475
|
}
|
|
8388
8476
|
|
|
8389
8477
|
// src/commands/refactor/restructure/index.ts
|
|
8390
8478
|
import path45 from "path";
|
|
8391
|
-
import
|
|
8479
|
+
import chalk104 from "chalk";
|
|
8392
8480
|
|
|
8393
8481
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
8394
8482
|
import path37 from "path";
|
|
@@ -8631,50 +8719,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
8631
8719
|
|
|
8632
8720
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
8633
8721
|
import path41 from "path";
|
|
8634
|
-
import
|
|
8722
|
+
import chalk102 from "chalk";
|
|
8635
8723
|
function relPath(filePath) {
|
|
8636
8724
|
return path41.relative(process.cwd(), filePath);
|
|
8637
8725
|
}
|
|
8638
8726
|
function displayMoves(plan2) {
|
|
8639
8727
|
if (plan2.moves.length === 0) return;
|
|
8640
|
-
console.log(
|
|
8728
|
+
console.log(chalk102.bold("\nFile moves:"));
|
|
8641
8729
|
for (const move of plan2.moves) {
|
|
8642
8730
|
console.log(
|
|
8643
|
-
` ${
|
|
8731
|
+
` ${chalk102.red(relPath(move.from))} \u2192 ${chalk102.green(relPath(move.to))}`
|
|
8644
8732
|
);
|
|
8645
|
-
console.log(
|
|
8733
|
+
console.log(chalk102.dim(` ${move.reason}`));
|
|
8646
8734
|
}
|
|
8647
8735
|
}
|
|
8648
8736
|
function displayRewrites(rewrites) {
|
|
8649
8737
|
if (rewrites.length === 0) return;
|
|
8650
8738
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
8651
|
-
console.log(
|
|
8739
|
+
console.log(chalk102.bold(`
|
|
8652
8740
|
Import rewrites (${affectedFiles.size} files):`));
|
|
8653
8741
|
for (const file of affectedFiles) {
|
|
8654
|
-
console.log(` ${
|
|
8742
|
+
console.log(` ${chalk102.cyan(relPath(file))}:`);
|
|
8655
8743
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
8656
8744
|
(r) => r.file === file
|
|
8657
8745
|
)) {
|
|
8658
8746
|
console.log(
|
|
8659
|
-
` ${
|
|
8747
|
+
` ${chalk102.red(`"${oldSpecifier}"`)} \u2192 ${chalk102.green(`"${newSpecifier}"`)}`
|
|
8660
8748
|
);
|
|
8661
8749
|
}
|
|
8662
8750
|
}
|
|
8663
8751
|
}
|
|
8664
8752
|
function displayPlan2(plan2) {
|
|
8665
8753
|
if (plan2.warnings.length > 0) {
|
|
8666
|
-
console.log(
|
|
8667
|
-
for (const w of plan2.warnings) console.log(
|
|
8754
|
+
console.log(chalk102.yellow("\nWarnings:"));
|
|
8755
|
+
for (const w of plan2.warnings) console.log(chalk102.yellow(` ${w}`));
|
|
8668
8756
|
}
|
|
8669
8757
|
if (plan2.newDirectories.length > 0) {
|
|
8670
|
-
console.log(
|
|
8758
|
+
console.log(chalk102.bold("\nNew directories:"));
|
|
8671
8759
|
for (const dir of plan2.newDirectories)
|
|
8672
|
-
console.log(
|
|
8760
|
+
console.log(chalk102.green(` ${dir}/`));
|
|
8673
8761
|
}
|
|
8674
8762
|
displayMoves(plan2);
|
|
8675
8763
|
displayRewrites(plan2.rewrites);
|
|
8676
8764
|
console.log(
|
|
8677
|
-
|
|
8765
|
+
chalk102.dim(
|
|
8678
8766
|
`
|
|
8679
8767
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
8680
8768
|
)
|
|
@@ -8684,18 +8772,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
8684
8772
|
// src/commands/refactor/restructure/executePlan.ts
|
|
8685
8773
|
import fs20 from "fs";
|
|
8686
8774
|
import path42 from "path";
|
|
8687
|
-
import
|
|
8775
|
+
import chalk103 from "chalk";
|
|
8688
8776
|
function executePlan(plan2) {
|
|
8689
8777
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
8690
8778
|
for (const [file, content] of updatedContents) {
|
|
8691
8779
|
fs20.writeFileSync(file, content, "utf-8");
|
|
8692
8780
|
console.log(
|
|
8693
|
-
|
|
8781
|
+
chalk103.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
8694
8782
|
);
|
|
8695
8783
|
}
|
|
8696
8784
|
for (const dir of plan2.newDirectories) {
|
|
8697
8785
|
fs20.mkdirSync(dir, { recursive: true });
|
|
8698
|
-
console.log(
|
|
8786
|
+
console.log(chalk103.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
8699
8787
|
}
|
|
8700
8788
|
for (const move of plan2.moves) {
|
|
8701
8789
|
const targetDir = path42.dirname(move.to);
|
|
@@ -8704,7 +8792,7 @@ function executePlan(plan2) {
|
|
|
8704
8792
|
}
|
|
8705
8793
|
fs20.renameSync(move.from, move.to);
|
|
8706
8794
|
console.log(
|
|
8707
|
-
|
|
8795
|
+
chalk103.white(
|
|
8708
8796
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
8709
8797
|
)
|
|
8710
8798
|
);
|
|
@@ -8719,7 +8807,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
8719
8807
|
if (entries.length === 0) {
|
|
8720
8808
|
fs20.rmdirSync(dir);
|
|
8721
8809
|
console.log(
|
|
8722
|
-
|
|
8810
|
+
chalk103.dim(
|
|
8723
8811
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
8724
8812
|
)
|
|
8725
8813
|
);
|
|
@@ -8852,22 +8940,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
8852
8940
|
const targetPattern = pattern2 ?? "src";
|
|
8853
8941
|
const files = findSourceFiles2(targetPattern);
|
|
8854
8942
|
if (files.length === 0) {
|
|
8855
|
-
console.log(
|
|
8943
|
+
console.log(chalk104.yellow("No files found matching pattern"));
|
|
8856
8944
|
return;
|
|
8857
8945
|
}
|
|
8858
8946
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
8859
8947
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
8860
8948
|
if (plan2.moves.length === 0) {
|
|
8861
|
-
console.log(
|
|
8949
|
+
console.log(chalk104.green("No restructuring needed"));
|
|
8862
8950
|
return;
|
|
8863
8951
|
}
|
|
8864
8952
|
displayPlan2(plan2);
|
|
8865
8953
|
if (options2.apply) {
|
|
8866
|
-
console.log(
|
|
8954
|
+
console.log(chalk104.bold("\nApplying changes..."));
|
|
8867
8955
|
executePlan(plan2);
|
|
8868
|
-
console.log(
|
|
8956
|
+
console.log(chalk104.green("\nRestructuring complete"));
|
|
8869
8957
|
} else {
|
|
8870
|
-
console.log(
|
|
8958
|
+
console.log(chalk104.dim("\nDry run. Use --apply to execute."));
|
|
8871
8959
|
}
|
|
8872
8960
|
}
|
|
8873
8961
|
|
|
@@ -8907,7 +8995,7 @@ function registerRefactor(program2) {
|
|
|
8907
8995
|
}
|
|
8908
8996
|
|
|
8909
8997
|
// src/commands/seq/seqAuth.ts
|
|
8910
|
-
import
|
|
8998
|
+
import chalk106 from "chalk";
|
|
8911
8999
|
|
|
8912
9000
|
// src/commands/seq/loadConnections.ts
|
|
8913
9001
|
function loadConnections2() {
|
|
@@ -8936,11 +9024,11 @@ function setDefaultConnection(name) {
|
|
|
8936
9024
|
}
|
|
8937
9025
|
|
|
8938
9026
|
// src/commands/seq/promptConnection.ts
|
|
8939
|
-
import
|
|
9027
|
+
import chalk105 from "chalk";
|
|
8940
9028
|
async function promptConnection2(existingNames) {
|
|
8941
9029
|
const name = await promptInput("name", "Connection name:", "default");
|
|
8942
9030
|
if (existingNames.includes(name)) {
|
|
8943
|
-
console.error(
|
|
9031
|
+
console.error(chalk105.red(`Connection "${name}" already exists.`));
|
|
8944
9032
|
process.exit(1);
|
|
8945
9033
|
}
|
|
8946
9034
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -8952,32 +9040,50 @@ async function promptConnection2(existingNames) {
|
|
|
8952
9040
|
var seqAuth = createConnectionAuth({
|
|
8953
9041
|
load: loadConnections2,
|
|
8954
9042
|
save: saveConnections2,
|
|
8955
|
-
format: (c) => `${
|
|
9043
|
+
format: (c) => `${chalk106.bold(c.name)} ${c.url}`,
|
|
8956
9044
|
promptNew: promptConnection2,
|
|
8957
9045
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
8958
9046
|
});
|
|
8959
9047
|
|
|
8960
9048
|
// src/commands/seq/seqQuery.ts
|
|
8961
|
-
import
|
|
9049
|
+
import chalk110 from "chalk";
|
|
9050
|
+
|
|
9051
|
+
// src/commands/seq/fetchSeqEvents.ts
|
|
9052
|
+
import chalk107 from "chalk";
|
|
9053
|
+
async function fetchSeqEvents(conn, params) {
|
|
9054
|
+
const url = `${conn.url}/api/events?${params}`;
|
|
9055
|
+
const response = await fetch(url, {
|
|
9056
|
+
headers: {
|
|
9057
|
+
Accept: "application/json",
|
|
9058
|
+
"X-Seq-ApiKey": conn.apiToken
|
|
9059
|
+
}
|
|
9060
|
+
});
|
|
9061
|
+
if (!response.ok) {
|
|
9062
|
+
const body = await response.text();
|
|
9063
|
+
console.error(chalk107.red(`Seq returned ${response.status}: ${body}`));
|
|
9064
|
+
process.exit(1);
|
|
9065
|
+
}
|
|
9066
|
+
return response.json();
|
|
9067
|
+
}
|
|
8962
9068
|
|
|
8963
9069
|
// src/commands/seq/formatEvent.ts
|
|
8964
|
-
import
|
|
9070
|
+
import chalk108 from "chalk";
|
|
8965
9071
|
function levelColor(level) {
|
|
8966
9072
|
switch (level) {
|
|
8967
9073
|
case "Fatal":
|
|
8968
|
-
return
|
|
9074
|
+
return chalk108.bgRed.white;
|
|
8969
9075
|
case "Error":
|
|
8970
|
-
return
|
|
9076
|
+
return chalk108.red;
|
|
8971
9077
|
case "Warning":
|
|
8972
|
-
return
|
|
9078
|
+
return chalk108.yellow;
|
|
8973
9079
|
case "Information":
|
|
8974
|
-
return
|
|
9080
|
+
return chalk108.cyan;
|
|
8975
9081
|
case "Debug":
|
|
8976
|
-
return
|
|
9082
|
+
return chalk108.gray;
|
|
8977
9083
|
case "Verbose":
|
|
8978
|
-
return
|
|
9084
|
+
return chalk108.dim;
|
|
8979
9085
|
default:
|
|
8980
|
-
return
|
|
9086
|
+
return chalk108.white;
|
|
8981
9087
|
}
|
|
8982
9088
|
}
|
|
8983
9089
|
function levelAbbrev(level) {
|
|
@@ -9018,31 +9124,31 @@ function formatTimestamp(iso) {
|
|
|
9018
9124
|
function formatEvent(event) {
|
|
9019
9125
|
const color = levelColor(event.Level);
|
|
9020
9126
|
const abbrev = levelAbbrev(event.Level);
|
|
9021
|
-
const ts8 =
|
|
9127
|
+
const ts8 = chalk108.dim(formatTimestamp(event.Timestamp));
|
|
9022
9128
|
const msg = renderMessage(event);
|
|
9023
9129
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
9024
9130
|
if (event.Exception) {
|
|
9025
9131
|
for (const line of event.Exception.split("\n")) {
|
|
9026
|
-
lines.push(
|
|
9132
|
+
lines.push(chalk108.red(` ${line}`));
|
|
9027
9133
|
}
|
|
9028
9134
|
}
|
|
9029
9135
|
return lines.join("\n");
|
|
9030
9136
|
}
|
|
9031
9137
|
|
|
9032
9138
|
// src/commands/seq/resolveConnection.ts
|
|
9033
|
-
import
|
|
9139
|
+
import chalk109 from "chalk";
|
|
9034
9140
|
function resolveConnection2(name) {
|
|
9035
9141
|
const connections = loadConnections2();
|
|
9036
9142
|
if (connections.length === 0) {
|
|
9037
9143
|
console.error(
|
|
9038
|
-
|
|
9144
|
+
chalk109.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
9039
9145
|
);
|
|
9040
9146
|
process.exit(1);
|
|
9041
9147
|
}
|
|
9042
9148
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
9043
9149
|
const connection = connections.find((c) => c.name === target);
|
|
9044
9150
|
if (!connection) {
|
|
9045
|
-
console.error(
|
|
9151
|
+
console.error(chalk109.red(`Seq connection "${target}" not found.`));
|
|
9046
9152
|
process.exit(1);
|
|
9047
9153
|
}
|
|
9048
9154
|
return connection;
|
|
@@ -9053,21 +9159,12 @@ async function seqQuery(filter, options2) {
|
|
|
9053
9159
|
const conn = resolveConnection2(options2.connection);
|
|
9054
9160
|
const count = Number.parseInt(options2.count ?? "1000", 10);
|
|
9055
9161
|
const params = new URLSearchParams({ filter, count: String(count) });
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
headers: {
|
|
9059
|
-
Accept: "application/json",
|
|
9060
|
-
"X-Seq-ApiKey": conn.apiToken
|
|
9061
|
-
}
|
|
9062
|
-
});
|
|
9063
|
-
if (!response.ok) {
|
|
9064
|
-
const body = await response.text();
|
|
9065
|
-
console.error(chalk106.red(`Seq returned ${response.status}: ${body}`));
|
|
9066
|
-
process.exit(1);
|
|
9162
|
+
if (options2.from) {
|
|
9163
|
+
params.set("fromDateUtc", options2.from);
|
|
9067
9164
|
}
|
|
9068
|
-
const events = await
|
|
9165
|
+
const events = await fetchSeqEvents(conn, params);
|
|
9069
9166
|
if (events.length === 0) {
|
|
9070
|
-
console.log(
|
|
9167
|
+
console.log(chalk110.yellow("No events found."));
|
|
9071
9168
|
return;
|
|
9072
9169
|
}
|
|
9073
9170
|
if (options2.json) {
|
|
@@ -9078,11 +9175,11 @@ async function seqQuery(filter, options2) {
|
|
|
9078
9175
|
for (const event of chronological) {
|
|
9079
9176
|
console.log(formatEvent(event));
|
|
9080
9177
|
}
|
|
9081
|
-
console.log(
|
|
9178
|
+
console.log(chalk110.dim(`
|
|
9082
9179
|
${events.length} events`));
|
|
9083
9180
|
if (events.length >= count) {
|
|
9084
9181
|
console.log(
|
|
9085
|
-
|
|
9182
|
+
chalk110.yellow(
|
|
9086
9183
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
9087
9184
|
)
|
|
9088
9185
|
);
|
|
@@ -9090,11 +9187,11 @@ ${events.length} events`));
|
|
|
9090
9187
|
}
|
|
9091
9188
|
|
|
9092
9189
|
// src/commands/seq/seqSetConnection.ts
|
|
9093
|
-
import
|
|
9190
|
+
import chalk111 from "chalk";
|
|
9094
9191
|
function seqSetConnection(name) {
|
|
9095
9192
|
const connections = loadConnections2();
|
|
9096
9193
|
if (!connections.find((c) => c.name === name)) {
|
|
9097
|
-
console.error(
|
|
9194
|
+
console.error(chalk111.red(`Connection "${name}" not found.`));
|
|
9098
9195
|
process.exit(1);
|
|
9099
9196
|
}
|
|
9100
9197
|
setDefaultConnection(name);
|
|
@@ -9109,7 +9206,7 @@ function registerSeq(program2) {
|
|
|
9109
9206
|
auth2.command("list").description("List configured connections").action(() => seqAuth.list());
|
|
9110
9207
|
auth2.command("remove <name>").description("Remove a configured connection").action((name) => seqAuth.remove(name));
|
|
9111
9208
|
cmd.command("set-connection <name>").description("Set the default Seq connection").action((name) => seqSetConnection(name));
|
|
9112
|
-
cmd.command("query <filter>").description("Query Seq events with a filter expression").option("-c, --connection <name>", "Connection to use").option("-n, --count <n>", "Number of events to fetch", "50").option("--json", "Output raw JSON").action((filter, options2) => seqQuery(filter, options2));
|
|
9209
|
+
cmd.command("query <filter>").description("Query Seq events with a filter expression").option("-c, --connection <name>", "Connection to use").option("-n, --count <n>", "Number of events to fetch", "50").option("--from <date>", "Start date (UTC) for the query window").option("--json", "Output raw JSON").action((filter, options2) => seqQuery(filter, options2));
|
|
9113
9210
|
}
|
|
9114
9211
|
|
|
9115
9212
|
// src/commands/transcript/shared.ts
|
|
@@ -9633,14 +9730,14 @@ import {
|
|
|
9633
9730
|
import { dirname as dirname20, join as join30 } from "path";
|
|
9634
9731
|
|
|
9635
9732
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9636
|
-
import
|
|
9733
|
+
import chalk112 from "chalk";
|
|
9637
9734
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
9638
9735
|
function validateStagedContent(filename, content) {
|
|
9639
9736
|
const firstLine = content.split("\n")[0];
|
|
9640
9737
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
9641
9738
|
if (!match) {
|
|
9642
9739
|
console.error(
|
|
9643
|
-
|
|
9740
|
+
chalk112.red(
|
|
9644
9741
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
9645
9742
|
)
|
|
9646
9743
|
);
|
|
@@ -9649,7 +9746,7 @@ function validateStagedContent(filename, content) {
|
|
|
9649
9746
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
9650
9747
|
if (!contentAfterLink) {
|
|
9651
9748
|
console.error(
|
|
9652
|
-
|
|
9749
|
+
chalk112.red(
|
|
9653
9750
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
9654
9751
|
)
|
|
9655
9752
|
);
|
|
@@ -10042,7 +10139,7 @@ function registerVoice(program2) {
|
|
|
10042
10139
|
|
|
10043
10140
|
// src/commands/roam/auth.ts
|
|
10044
10141
|
import { randomBytes } from "crypto";
|
|
10045
|
-
import
|
|
10142
|
+
import chalk113 from "chalk";
|
|
10046
10143
|
|
|
10047
10144
|
// src/lib/openBrowser.ts
|
|
10048
10145
|
import { execSync as execSync38 } from "child_process";
|
|
@@ -10217,13 +10314,13 @@ async function auth() {
|
|
|
10217
10314
|
saveGlobalConfig(config);
|
|
10218
10315
|
const state = randomBytes(16).toString("hex");
|
|
10219
10316
|
console.log(
|
|
10220
|
-
|
|
10317
|
+
chalk113.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
10221
10318
|
);
|
|
10222
|
-
console.log(
|
|
10223
|
-
console.log(
|
|
10224
|
-
console.log(
|
|
10319
|
+
console.log(chalk113.white("http://localhost:14523/callback\n"));
|
|
10320
|
+
console.log(chalk113.blue("Opening browser for authorization..."));
|
|
10321
|
+
console.log(chalk113.dim("Waiting for authorization callback..."));
|
|
10225
10322
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
10226
|
-
console.log(
|
|
10323
|
+
console.log(chalk113.dim("Exchanging code for tokens..."));
|
|
10227
10324
|
const tokens = await exchangeToken({
|
|
10228
10325
|
code,
|
|
10229
10326
|
clientId,
|
|
@@ -10239,7 +10336,7 @@ async function auth() {
|
|
|
10239
10336
|
};
|
|
10240
10337
|
saveGlobalConfig(config);
|
|
10241
10338
|
console.log(
|
|
10242
|
-
|
|
10339
|
+
chalk113.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
10243
10340
|
);
|
|
10244
10341
|
}
|
|
10245
10342
|
|
|
@@ -10452,7 +10549,7 @@ import { execSync as execSync40 } from "child_process";
|
|
|
10452
10549
|
import { existsSync as existsSync40, mkdirSync as mkdirSync13, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10453
10550
|
import { tmpdir as tmpdir6 } from "os";
|
|
10454
10551
|
import { join as join39, resolve as resolve5 } from "path";
|
|
10455
|
-
import
|
|
10552
|
+
import chalk114 from "chalk";
|
|
10456
10553
|
|
|
10457
10554
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
10458
10555
|
var captureWindowPs1 = `
|
|
@@ -10603,22 +10700,22 @@ function screenshot(processName) {
|
|
|
10603
10700
|
const config = loadConfig();
|
|
10604
10701
|
const outputDir = resolve5(config.screenshot.outputDir);
|
|
10605
10702
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
10606
|
-
console.log(
|
|
10703
|
+
console.log(chalk114.gray(`Capturing window for process "${processName}" ...`));
|
|
10607
10704
|
try {
|
|
10608
10705
|
runPowerShellScript(processName, outputPath);
|
|
10609
|
-
console.log(
|
|
10706
|
+
console.log(chalk114.green(`Screenshot saved: ${outputPath}`));
|
|
10610
10707
|
} catch (error) {
|
|
10611
10708
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10612
|
-
console.error(
|
|
10709
|
+
console.error(chalk114.red(`Failed to capture screenshot: ${msg}`));
|
|
10613
10710
|
process.exit(1);
|
|
10614
10711
|
}
|
|
10615
10712
|
}
|
|
10616
10713
|
|
|
10617
10714
|
// src/commands/statusLine.ts
|
|
10618
|
-
import
|
|
10715
|
+
import chalk116 from "chalk";
|
|
10619
10716
|
|
|
10620
10717
|
// src/commands/buildLimitsSegment.ts
|
|
10621
|
-
import
|
|
10718
|
+
import chalk115 from "chalk";
|
|
10622
10719
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
10623
10720
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
10624
10721
|
function formatTimeLeft(resetsAt) {
|
|
@@ -10641,10 +10738,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
10641
10738
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
10642
10739
|
const label2 = `${Math.round(pct)}%`;
|
|
10643
10740
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
10644
|
-
if (projected == null) return
|
|
10645
|
-
if (projected > 100) return
|
|
10646
|
-
if (projected > 75) return
|
|
10647
|
-
return
|
|
10741
|
+
if (projected == null) return chalk115.green(label2);
|
|
10742
|
+
if (projected > 100) return chalk115.red(label2);
|
|
10743
|
+
if (projected > 75) return chalk115.yellow(label2);
|
|
10744
|
+
return chalk115.green(label2);
|
|
10648
10745
|
}
|
|
10649
10746
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
10650
10747
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -10670,14 +10767,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
10670
10767
|
}
|
|
10671
10768
|
|
|
10672
10769
|
// src/commands/statusLine.ts
|
|
10673
|
-
|
|
10770
|
+
chalk116.level = 3;
|
|
10674
10771
|
function formatNumber(num) {
|
|
10675
10772
|
return num.toLocaleString("en-US");
|
|
10676
10773
|
}
|
|
10677
10774
|
function colorizePercent(pct) {
|
|
10678
10775
|
const label2 = `${Math.round(pct)}%`;
|
|
10679
|
-
if (pct > 80) return
|
|
10680
|
-
if (pct > 40) return
|
|
10776
|
+
if (pct > 80) return chalk116.red(label2);
|
|
10777
|
+
if (pct > 40) return chalk116.yellow(label2);
|
|
10681
10778
|
return label2;
|
|
10682
10779
|
}
|
|
10683
10780
|
async function statusLine() {
|
|
@@ -10700,7 +10797,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
10700
10797
|
// src/commands/sync/syncClaudeMd.ts
|
|
10701
10798
|
import * as fs23 from "fs";
|
|
10702
10799
|
import * as path46 from "path";
|
|
10703
|
-
import
|
|
10800
|
+
import chalk117 from "chalk";
|
|
10704
10801
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
10705
10802
|
const source = path46.join(claudeDir, "CLAUDE.md");
|
|
10706
10803
|
const target = path46.join(targetBase, "CLAUDE.md");
|
|
@@ -10709,12 +10806,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10709
10806
|
const targetContent = fs23.readFileSync(target, "utf-8");
|
|
10710
10807
|
if (sourceContent !== targetContent) {
|
|
10711
10808
|
console.log(
|
|
10712
|
-
|
|
10809
|
+
chalk117.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
10713
10810
|
);
|
|
10714
10811
|
console.log();
|
|
10715
10812
|
printDiff(targetContent, sourceContent);
|
|
10716
10813
|
const confirm = options2?.yes || await promptConfirm(
|
|
10717
|
-
|
|
10814
|
+
chalk117.red("Overwrite existing CLAUDE.md?"),
|
|
10718
10815
|
false
|
|
10719
10816
|
);
|
|
10720
10817
|
if (!confirm) {
|
|
@@ -10730,7 +10827,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
10730
10827
|
// src/commands/sync/syncSettings.ts
|
|
10731
10828
|
import * as fs24 from "fs";
|
|
10732
10829
|
import * as path47 from "path";
|
|
10733
|
-
import
|
|
10830
|
+
import chalk118 from "chalk";
|
|
10734
10831
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
10735
10832
|
const source = path47.join(claudeDir, "settings.json");
|
|
10736
10833
|
const target = path47.join(targetBase, "settings.json");
|
|
@@ -10746,14 +10843,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
10746
10843
|
if (mergedContent !== normalizedTarget) {
|
|
10747
10844
|
if (!options2?.yes) {
|
|
10748
10845
|
console.log(
|
|
10749
|
-
|
|
10846
|
+
chalk118.yellow(
|
|
10750
10847
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
10751
10848
|
)
|
|
10752
10849
|
);
|
|
10753
10850
|
console.log();
|
|
10754
10851
|
printDiff(targetContent, mergedContent);
|
|
10755
10852
|
const confirm = await promptConfirm(
|
|
10756
|
-
|
|
10853
|
+
chalk118.red("Overwrite existing settings.json?"),
|
|
10757
10854
|
false
|
|
10758
10855
|
);
|
|
10759
10856
|
if (!confirm) {
|