@staff0rd/assist 0.122.0 → 0.124.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 +1 -0
- package/dist/index.js +68 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -112,6 +112,7 @@ After installation, the `assist` command will be available globally. You can als
|
|
|
112
112
|
- `assist status-line` - Format Claude Code status line from JSON stdin
|
|
113
113
|
- `assist dotnet inspect [sln]` - Run JetBrains inspections on changed .cs files to find dead code
|
|
114
114
|
- `assist dotnet inspect [sln] --ref <ref>` - Inspect .cs files changed in a specific commit (default: HEAD)
|
|
115
|
+
- `assist dotnet inspect [sln] --base <ref>` - Inspect all .cs files changed since diverging from a base ref (e.g. `--base main` for a full PR)
|
|
115
116
|
- `assist dotnet inspect [sln] --swea` - Enable solution-wide error analysis (slower but more thorough)
|
|
116
117
|
- `assist dotnet check-locks` - Check if build output files are locked by a debugger
|
|
117
118
|
- `assist dotnet deps <csproj>` - Show .csproj project dependency tree and solution membership
|
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.124.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -4819,8 +4819,15 @@ function findSolution() {
|
|
|
4819
4819
|
|
|
4820
4820
|
// src/commands/dotnet/getChangedCsFiles.ts
|
|
4821
4821
|
import { execSync as execSync20 } from "child_process";
|
|
4822
|
-
function getChangedCsFiles(ref) {
|
|
4823
|
-
|
|
4822
|
+
function getChangedCsFiles(ref, base) {
|
|
4823
|
+
let cmd;
|
|
4824
|
+
if (base) {
|
|
4825
|
+
cmd = `git diff --name-only ${base}...HEAD`;
|
|
4826
|
+
} else if (ref) {
|
|
4827
|
+
cmd = `git diff --name-only ${ref}~1 ${ref}`;
|
|
4828
|
+
} else {
|
|
4829
|
+
cmd = "git diff --name-only HEAD";
|
|
4830
|
+
}
|
|
4824
4831
|
const output = execSync20(cmd, { encoding: "utf-8" }).trim();
|
|
4825
4832
|
if (output === "") return [];
|
|
4826
4833
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
@@ -4908,7 +4915,7 @@ async function inspect(sln, options2) {
|
|
|
4908
4915
|
const resolved = resolveSolution(sln);
|
|
4909
4916
|
checkBuildLocks();
|
|
4910
4917
|
assertJbInstalled();
|
|
4911
|
-
const changedFiles = getChangedCsFiles(options2.ref);
|
|
4918
|
+
const changedFiles = getChangedCsFiles(options2.ref, options2.base);
|
|
4912
4919
|
if (changedFiles.length === 0) {
|
|
4913
4920
|
console.log(chalk55.green("No changed .cs files found"));
|
|
4914
4921
|
return;
|
|
@@ -4932,7 +4939,10 @@ function registerDotnet(program2) {
|
|
|
4932
4939
|
const cmd = program2.command("dotnet").description(".NET project utilities");
|
|
4933
4940
|
cmd.command("inspect").description(
|
|
4934
4941
|
"Run JetBrains inspections on changed .cs files to find dead code"
|
|
4935
|
-
).argument("[sln]", "Path to a .sln file (auto-detected if omitted)").option("--ref <ref>", "Git commit to inspect (default: working copy)").option(
|
|
4942
|
+
).argument("[sln]", "Path to a .sln file (auto-detected if omitted)").option("--ref <ref>", "Git commit to inspect (default: working copy)").option(
|
|
4943
|
+
"--base <ref>",
|
|
4944
|
+
"Compare against a base ref using merge-base (e.g. main); inspects all PR changes"
|
|
4945
|
+
).option("--all", "Show all issues, not just dead code").option("--swea", "Enable solution-wide error analysis").action(inspect);
|
|
4936
4946
|
cmd.command("check-locks").description("Check if build output files are locked by a debugger").action(checkBuildLocksCommand);
|
|
4937
4947
|
cmd.command("deps").description("Show .csproj project dependency tree and solution membership").argument("<csproj>", "Path to a .csproj file").option("--json", "Output as JSON").action(deps);
|
|
4938
4948
|
cmd.command("in-sln").description("Check whether a .csproj is referenced by any .sln file").argument("<csproj>", "Path to a .csproj file").action(inSln);
|
|
@@ -8563,10 +8573,12 @@ function run2(name, args) {
|
|
|
8563
8573
|
}
|
|
8564
8574
|
|
|
8565
8575
|
// src/commands/statusLine.ts
|
|
8576
|
+
import chalk84 from "chalk";
|
|
8577
|
+
|
|
8578
|
+
// src/commands/buildLimitsSegment.ts
|
|
8566
8579
|
import chalk83 from "chalk";
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
}
|
|
8580
|
+
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
8581
|
+
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
8570
8582
|
function formatTimeLeft(resetsAt) {
|
|
8571
8583
|
const seconds = Math.max(0, resetsAt - Math.floor(Date.now() / 1e3));
|
|
8572
8584
|
const days = Math.floor(seconds / 86400);
|
|
@@ -8576,29 +8588,55 @@ function formatTimeLeft(resetsAt) {
|
|
|
8576
8588
|
if (hours > 0) return `${hours}h ${minutes}m`;
|
|
8577
8589
|
return `${minutes}m`;
|
|
8578
8590
|
}
|
|
8579
|
-
function
|
|
8591
|
+
function projectUsage(pct, resetsAt, windowSeconds) {
|
|
8592
|
+
if (resetsAt == null) return void 0;
|
|
8593
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
8594
|
+
const timeRemaining = Math.max(0, resetsAt - now);
|
|
8595
|
+
const elapsed = Math.max(0, windowSeconds - timeRemaining) / windowSeconds;
|
|
8596
|
+
if (elapsed < 0.05) return void 0;
|
|
8597
|
+
return pct / elapsed;
|
|
8598
|
+
}
|
|
8599
|
+
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
8580
8600
|
const label2 = `${Math.round(pct)}%`;
|
|
8581
|
-
|
|
8582
|
-
if (
|
|
8583
|
-
return label2;
|
|
8601
|
+
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
8602
|
+
if (projected == null) return chalk83.green(label2);
|
|
8603
|
+
if (projected > 100) return chalk83.red(label2);
|
|
8604
|
+
if (projected > 75) return chalk83.yellow(label2);
|
|
8605
|
+
return chalk83.green(label2);
|
|
8584
8606
|
}
|
|
8585
|
-
function formatLimit(
|
|
8586
|
-
const
|
|
8587
|
-
return `${
|
|
8607
|
+
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
8608
|
+
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
8609
|
+
return `${colorizeRateLimit(pct, resetsAt, windowSeconds)} (${timeLabel})`;
|
|
8588
8610
|
}
|
|
8589
8611
|
function buildLimitsSegment(rateLimits) {
|
|
8590
8612
|
const fiveHrPct = rateLimits?.five_hour?.used_percentage;
|
|
8591
8613
|
const sevenDayPct = rateLimits?.seven_day?.used_percentage;
|
|
8592
8614
|
if (fiveHrPct == null || sevenDayPct == null) return "";
|
|
8593
|
-
const fiveHr =
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
|
|
8601
|
-
|
|
8615
|
+
const fiveHr = formatLimit(
|
|
8616
|
+
fiveHrPct,
|
|
8617
|
+
rateLimits?.five_hour?.resets_at,
|
|
8618
|
+
FIVE_HOUR_SECONDS,
|
|
8619
|
+
"5h"
|
|
8620
|
+
);
|
|
8621
|
+
const sevenDay = formatLimit(
|
|
8622
|
+
sevenDayPct,
|
|
8623
|
+
rateLimits?.seven_day?.resets_at,
|
|
8624
|
+
SEVEN_DAY_SECONDS,
|
|
8625
|
+
"7d"
|
|
8626
|
+
);
|
|
8627
|
+
return ` | Limits - ${fiveHr}, ${sevenDay}`;
|
|
8628
|
+
}
|
|
8629
|
+
|
|
8630
|
+
// src/commands/statusLine.ts
|
|
8631
|
+
chalk84.level = 3;
|
|
8632
|
+
function formatNumber(num) {
|
|
8633
|
+
return num.toLocaleString("en-US");
|
|
8634
|
+
}
|
|
8635
|
+
function colorizePercent(pct) {
|
|
8636
|
+
const label2 = `${Math.round(pct)}%`;
|
|
8637
|
+
if (pct > 80) return chalk84.red(label2);
|
|
8638
|
+
if (pct > 40) return chalk84.yellow(label2);
|
|
8639
|
+
return label2;
|
|
8602
8640
|
}
|
|
8603
8641
|
async function statusLine() {
|
|
8604
8642
|
const inputData = await readStdin();
|
|
@@ -8620,7 +8658,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
8620
8658
|
// src/commands/sync/syncClaudeMd.ts
|
|
8621
8659
|
import * as fs22 from "fs";
|
|
8622
8660
|
import * as path40 from "path";
|
|
8623
|
-
import
|
|
8661
|
+
import chalk85 from "chalk";
|
|
8624
8662
|
async function syncClaudeMd(claudeDir, targetBase) {
|
|
8625
8663
|
const source = path40.join(claudeDir, "CLAUDE.md");
|
|
8626
8664
|
const target = path40.join(targetBase, "CLAUDE.md");
|
|
@@ -8629,12 +8667,12 @@ async function syncClaudeMd(claudeDir, targetBase) {
|
|
|
8629
8667
|
const targetContent = fs22.readFileSync(target, "utf-8");
|
|
8630
8668
|
if (sourceContent !== targetContent) {
|
|
8631
8669
|
console.log(
|
|
8632
|
-
|
|
8670
|
+
chalk85.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
8633
8671
|
);
|
|
8634
8672
|
console.log();
|
|
8635
8673
|
printDiff(targetContent, sourceContent);
|
|
8636
8674
|
const confirm = await promptConfirm(
|
|
8637
|
-
|
|
8675
|
+
chalk85.red("Overwrite existing CLAUDE.md?"),
|
|
8638
8676
|
false
|
|
8639
8677
|
);
|
|
8640
8678
|
if (!confirm) {
|
|
@@ -8650,7 +8688,7 @@ async function syncClaudeMd(claudeDir, targetBase) {
|
|
|
8650
8688
|
// src/commands/sync/syncSettings.ts
|
|
8651
8689
|
import * as fs23 from "fs";
|
|
8652
8690
|
import * as path41 from "path";
|
|
8653
|
-
import
|
|
8691
|
+
import chalk86 from "chalk";
|
|
8654
8692
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
8655
8693
|
const source = path41.join(claudeDir, "settings.json");
|
|
8656
8694
|
const target = path41.join(targetBase, "settings.json");
|
|
@@ -8666,14 +8704,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
8666
8704
|
if (mergedContent !== normalizedTarget) {
|
|
8667
8705
|
if (!options2?.yes) {
|
|
8668
8706
|
console.log(
|
|
8669
|
-
|
|
8707
|
+
chalk86.yellow(
|
|
8670
8708
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
8671
8709
|
)
|
|
8672
8710
|
);
|
|
8673
8711
|
console.log();
|
|
8674
8712
|
printDiff(targetContent, mergedContent);
|
|
8675
8713
|
const confirm = await promptConfirm(
|
|
8676
|
-
|
|
8714
|
+
chalk86.red("Overwrite existing settings.json?"),
|
|
8677
8715
|
false
|
|
8678
8716
|
);
|
|
8679
8717
|
if (!confirm) {
|