@staff0rd/assist 0.130.0 → 0.132.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 CHANGED
@@ -82,6 +82,7 @@ After installation, the `assist` command will be available globally. You can als
82
82
  - `assist backlog delete <id>` - Delete a backlog item
83
83
  - `assist backlog web [-p, --port <number>]` - Start a web view of the backlog (default port 3000)
84
84
  - `assist roam auth` - Authenticate with Roam via OAuth (opens browser, saves tokens to ~/.assist.yml)
85
+ - `assist roam show-claude-code-icon` - Forward Claude Code hook activity to Roam local API
85
86
  - `assist run <name> [params...]` - Run a configured command from assist.yml (positional params are matched to `params` config; supports `pre` array of commands to run first)
86
87
  - `assist run add` - Add a new run configuration to assist.yml and create a Claude command file
87
88
  - `assist config set <key> <value>` - Set a config value (e.g. commit.push true)
@@ -113,8 +114,10 @@ After installation, the `assist` command will be available globally. You can als
113
114
  - `assist notify` - Show desktop notification from JSON stdin (supports macOS, Windows, WSL)
114
115
  - `assist status-line` - Format Claude Code status line from JSON stdin
115
116
  - `assist dotnet inspect [sln]` - Run JetBrains inspections on changed .cs files to find dead code
116
- - `assist dotnet inspect [sln] --ref <ref>` - Inspect .cs files changed in a specific commit (default: HEAD)
117
- - `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)
117
+ - `assist dotnet inspect [sln] --scope all` - Inspect the full solution
118
+ - `assist dotnet inspect [sln] --scope base:<ref>` - Inspect all .cs files changed since diverging from a base ref (e.g. `--scope base:main` for a full PR)
119
+ - `assist dotnet inspect [sln] --scope commit:<ref>` - Inspect .cs files changed in a specific commit
120
+ - `assist dotnet inspect [sln] --suppress <ids...>` - Suppress specific issue type IDs on the command line
118
121
  - `assist dotnet inspect [sln] --roslyn` - Use Roslyn analyzers via msbuild instead of JetBrains
119
122
  - `assist dotnet inspect [sln] --swea` - Enable solution-wide error analysis (slower but more thorough)
120
123
  - `assist dotnet check-locks` - Check if build output files are locked by a debugger
@@ -46,6 +46,7 @@
46
46
  "Bash(assist ravendb auth list:*)",
47
47
  "Bash(assist seq query:*)",
48
48
  "Bash(assist seq auth list:*)",
49
+ "Bash(assist roam show-claude-code-icon:*)",
49
50
  "SlashCommand(/next-backlog-item)",
50
51
  "SlashCommand(/verify)",
51
52
  "SlashCommand(/commit)",
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.130.0",
9
+ version: "0.132.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -4708,6 +4708,36 @@ async function deps(csprojPath, options2) {
4708
4708
  }
4709
4709
  }
4710
4710
 
4711
+ // src/commands/dotnet/getChangedCsFiles.ts
4712
+ import { execSync as execSync20 } from "child_process";
4713
+ var SCOPE_ALL = "all";
4714
+ var SCOPE_BASE = "base:";
4715
+ var SCOPE_COMMIT = "commit:";
4716
+ var scopeHelpText = `${SCOPE_ALL} | ${SCOPE_BASE}<ref> | ${SCOPE_COMMIT}<ref>`;
4717
+ function parseScope(raw) {
4718
+ if (!raw) return { mode: "working-copy" };
4719
+ if (raw === SCOPE_ALL) return { mode: "full" };
4720
+ if (raw.startsWith(SCOPE_BASE))
4721
+ return { mode: "base", ref: raw.slice(SCOPE_BASE.length) };
4722
+ if (raw.startsWith(SCOPE_COMMIT))
4723
+ return { mode: "commit", ref: raw.slice(SCOPE_COMMIT.length) };
4724
+ throw new Error(`Invalid --scope value: ${raw}. Expected ${scopeHelpText}`);
4725
+ }
4726
+ function getChangedCsFiles(scope) {
4727
+ if (scope.mode === "full") return null;
4728
+ let cmd;
4729
+ if (scope.mode === "base") {
4730
+ cmd = `git diff --name-only ${scope.ref}...HEAD`;
4731
+ } else if (scope.mode === "commit") {
4732
+ cmd = `git diff --name-only ${scope.ref}~1 ${scope.ref}`;
4733
+ } else {
4734
+ cmd = "git diff --name-only HEAD";
4735
+ }
4736
+ const output = execSync20(cmd, { encoding: "utf-8" }).trim();
4737
+ if (output === "") return [];
4738
+ return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
4739
+ }
4740
+
4711
4741
  // src/commands/dotnet/inSln.ts
4712
4742
  import chalk51 from "chalk";
4713
4743
  async function inSln(csprojPath) {
@@ -4809,29 +4839,16 @@ var deadCodeRules = /* @__PURE__ */ new Set([
4809
4839
  ]);
4810
4840
 
4811
4841
  // src/commands/dotnet/filterIssues.ts
4812
- function filterIssues(issues, all) {
4813
- const suppress = new Set(loadConfig().dotnet?.inspect.suppress ?? []);
4842
+ function filterIssues(issues, all, cliSuppress) {
4843
+ const suppress = /* @__PURE__ */ new Set([
4844
+ ...loadConfig().dotnet?.inspect.suppress ?? [],
4845
+ ...cliSuppress
4846
+ ]);
4814
4847
  return issues.filter(
4815
4848
  (i) => (all || deadCodeRules.has(i.typeId)) && !suppress.has(i.typeId)
4816
4849
  );
4817
4850
  }
4818
4851
 
4819
- // src/commands/dotnet/getChangedCsFiles.ts
4820
- import { execSync as execSync20 } from "child_process";
4821
- function getChangedCsFiles(ref, base) {
4822
- let cmd;
4823
- if (base) {
4824
- cmd = `git diff --name-only ${base}...HEAD`;
4825
- } else if (ref) {
4826
- cmd = `git diff --name-only ${ref}~1 ${ref}`;
4827
- } else {
4828
- cmd = "git diff --name-only HEAD";
4829
- }
4830
- const output = execSync20(cmd, { encoding: "utf-8" }).trim();
4831
- if (output === "") return [];
4832
- return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
4833
- }
4834
-
4835
4852
  // src/commands/dotnet/resolveSolution.ts
4836
4853
  import { existsSync as existsSync22 } from "fs";
4837
4854
  import path25 from "path";
@@ -4931,10 +4948,11 @@ function assertJbInstalled() {
4931
4948
  }
4932
4949
  function runInspectCode(slnPath, include, swea) {
4933
4950
  const reportPath = path26.join(tmpdir2(), `inspect-${Date.now()}.xml`);
4951
+ const includeFlag = include ? ` --include="${include}"` : "";
4934
4952
  const sweaFlag = swea ? " --swea" : "";
4935
4953
  try {
4936
4954
  execSync21(
4937
- `jb inspectcode "${slnPath}" -o="${reportPath}" --include="${include}"${sweaFlag} --verbosity=OFF`,
4955
+ `jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
4938
4956
  { stdio: "pipe" }
4939
4957
  );
4940
4958
  } catch (err) {
@@ -5004,10 +5022,11 @@ function runRoslynInspect(slnPath) {
5004
5022
  // src/commands/dotnet/runEngine.ts
5005
5023
  function runEngine(resolved, changedFiles, options2) {
5006
5024
  if (options2.roslyn) {
5007
- return filterToChangedFiles(runRoslynInspect(resolved), changedFiles);
5025
+ const issues = runRoslynInspect(resolved);
5026
+ return changedFiles ? filterToChangedFiles(issues, changedFiles) : issues;
5008
5027
  }
5009
5028
  return parseInspectReport(
5010
- runInspectCode(resolved, changedFiles.join(";"), !!options2.swea)
5029
+ runInspectCode(resolved, changedFiles?.join(";") ?? null, !!options2.swea)
5011
5030
  );
5012
5031
  }
5013
5032
 
@@ -5023,18 +5042,26 @@ async function inspect(sln, options2) {
5023
5042
  checkBuildLocks();
5024
5043
  if (options2.roslyn) assertMsbuildInstalled();
5025
5044
  else assertJbInstalled();
5026
- const changedFiles = getChangedCsFiles(options2.ref, options2.base);
5027
- if (changedFiles.length === 0) {
5045
+ const scope = parseScope(options2.scope);
5046
+ const changedFiles = getChangedCsFiles(scope);
5047
+ if (changedFiles !== null && changedFiles.length === 0) {
5028
5048
  console.log(chalk57.green("No changed .cs files found"));
5029
5049
  return;
5030
5050
  }
5031
- console.log(
5032
- chalk57.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
5033
- );
5051
+ if (changedFiles === null) {
5052
+ console.log(chalk57.dim("Inspecting full solution..."));
5053
+ } else {
5054
+ console.log(
5055
+ chalk57.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
5056
+ );
5057
+ }
5034
5058
  const start3 = Date.now();
5035
5059
  const issues = runEngine(resolved, changedFiles, options2);
5036
5060
  const elapsed = Date.now() - start3;
5037
- reportResults(filterIssues(issues, !!options2.all), elapsed);
5061
+ reportResults(
5062
+ filterIssues(issues, !!options2.all, options2.suppress ?? []),
5063
+ elapsed
5064
+ );
5038
5065
  }
5039
5066
 
5040
5067
  // src/commands/registerDotnet.ts
@@ -5042,10 +5069,10 @@ function registerDotnet(program2) {
5042
5069
  const cmd = program2.command("dotnet").description(".NET project utilities");
5043
5070
  cmd.command("inspect").description(
5044
5071
  "Run JetBrains inspections on changed .cs files to find dead code"
5045
- ).argument("[sln]", "Path to a .sln file (auto-detected if omitted)").option("--ref <ref>", "Git commit to inspect (default: working copy)").option(
5046
- "--base <ref>",
5047
- "Compare against a base ref using merge-base (e.g. main); inspects all PR changes"
5048
- ).option("--all", "Show all issues, not just dead code").option("--swea", "Enable solution-wide error analysis").option("--roslyn", "Use Roslyn analyzers via msbuild instead of JetBrains").action(inspect);
5072
+ ).argument("[sln]", "Path to a .sln file (auto-detected if omitted)").option(
5073
+ "--scope <mode>",
5074
+ `File scope: ${scopeHelpText} (default: working copy diff)`
5075
+ ).option("--all", "Show all issues, not just dead code").option("--suppress <ids...>", "Suppress specific issue type IDs").option("--swea", "Enable solution-wide error analysis").option("--roslyn", "Use Roslyn analyzers via msbuild instead of JetBrains").action(inspect);
5049
5076
  cmd.command("check-locks").description("Check if build output files are locked by a debugger").action(checkBuildLocksCommand);
5050
5077
  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);
5051
5078
  cmd.command("in-sln").description("Check whether a .csproj is referenced by any .sln file").argument("<csproj>", "Path to a .csproj file").action(inSln);
@@ -8712,10 +8739,35 @@ async function auth() {
8712
8739
  );
8713
8740
  }
8714
8741
 
8742
+ // src/commands/roam/showClaudeCodeIcon.ts
8743
+ import { readFileSync as readFileSync29 } from "fs";
8744
+ import { join as join35 } from "path";
8745
+ async function showClaudeCodeIcon() {
8746
+ const appData = process.env.APPDATA;
8747
+ if (!appData) return;
8748
+ const portFile = join35(appData, "Roam", "roam-local-api.port");
8749
+ let port;
8750
+ try {
8751
+ port = readFileSync29(portFile, "utf-8").trim();
8752
+ } catch {
8753
+ return;
8754
+ }
8755
+ const body = process.stdin.isTTY ? "{}" : await readStdin();
8756
+ try {
8757
+ await fetch(`http://localhost:${port}/api/v1/activity`, {
8758
+ method: "POST",
8759
+ headers: { "Content-Type": "application/json" },
8760
+ body
8761
+ });
8762
+ } catch {
8763
+ }
8764
+ }
8765
+
8715
8766
  // src/commands/roam/registerRoam.ts
8716
8767
  function registerRoam(program2) {
8717
8768
  const roamCommand = program2.command("roam").description("Roam Research utilities");
8718
8769
  roamCommand.command("auth").description("Configure Roam API credentials").action(auth);
8770
+ roamCommand.command("show-claude-code-icon").description("Forward Claude Code hook activity to Roam local API").action(showClaudeCodeIcon);
8719
8771
  }
8720
8772
 
8721
8773
  // src/commands/run/index.ts
@@ -8768,7 +8820,7 @@ Done in ${elapsed}`);
8768
8820
 
8769
8821
  // src/commands/run/add.ts
8770
8822
  import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync25 } from "fs";
8771
- import { join as join35 } from "path";
8823
+ import { join as join36 } from "path";
8772
8824
  function findAddIndex() {
8773
8825
  const addIndex = process.argv.indexOf("add");
8774
8826
  if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
@@ -8822,7 +8874,7 @@ function saveNewRunConfig(name, command, args) {
8822
8874
  saveConfig(config);
8823
8875
  }
8824
8876
  function createCommandFile(name) {
8825
- const dir = join35(".claude", "commands");
8877
+ const dir = join36(".claude", "commands");
8826
8878
  mkdirSync12(dir, { recursive: true });
8827
8879
  const content = `---
8828
8880
  description: Run ${name}
@@ -8830,7 +8882,7 @@ description: Run ${name}
8830
8882
 
8831
8883
  Run \`assist run ${name} $ARGUMENTS 2>&1\`.
8832
8884
  `;
8833
- const filePath = join35(dir, `${name}.md`);
8885
+ const filePath = join36(dir, `${name}.md`);
8834
8886
  writeFileSync25(filePath, content);
8835
8887
  console.log(`Created command file: ${filePath}`);
8836
8888
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.130.0",
3
+ "version": "0.132.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {