@spardutti/claude-skills 2.19.0 → 2.19.2

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/lib/local.mjs CHANGED
@@ -3,6 +3,10 @@
3
3
  // publishing it first.
4
4
  import { readdir, readFile } from "node:fs/promises";
5
5
  import { join } from "node:path";
6
+ import { execFile } from "node:child_process";
7
+ import { promisify } from "node:util";
8
+
9
+ const exec = promisify(execFile);
6
10
 
7
11
  function parseFrontmatter(content, fallbackName) {
8
12
  const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
@@ -25,6 +29,28 @@ async function listDir(dir) {
25
29
  try { return await readdir(dir, { withFileTypes: true }); } catch { return []; }
26
30
  }
27
31
 
32
+ // Build output is not a project. Next.js writes a package.json into .next/,
33
+ // .next/dev/ and .next/standalone/, so a scan that skipped only a hardcoded
34
+ // list reported three phantom projects on a plain Next app — and then filtered
35
+ // the real repo root out as "a root that delegates to a workspace". A second
36
+ // list of build dirs drifts from .gitignore the moment a framework adds one, so
37
+ // ask git the way ship-gate.sh already does. --directory collapses a fully
38
+ // ignored tree to its own name, which is what keeps this output small.
39
+ async function gitIgnoredDirs(projectDir) {
40
+ try {
41
+ const { stdout } = await exec(
42
+ "git",
43
+ ["-C", projectDir, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory"],
44
+ { maxBuffer: 10 * 1024 * 1024 },
45
+ );
46
+ return new Set(
47
+ stdout.split("\n").filter((l) => l.endsWith("/")).map((l) => l.slice(0, -1)),
48
+ );
49
+ } catch {
50
+ return new Set();
51
+ }
52
+ }
53
+
28
54
  export function makeLocalSource(root) {
29
55
  return {
30
56
  async fetchSkills() {
@@ -113,6 +139,8 @@ export async function reportToolNeeds(projectDir) {
113
139
  // needs a tool. A root that delegates is not the place to install, even once
114
140
  // the workspace it delegates to is already set up.
115
141
  const nested = { Stryker: false, mutmut: false };
142
+ // Empty outside a git repo, so the hardcoded list below still carries those.
143
+ const ignored = await gitIgnoredDirs(projectDir);
116
144
 
117
145
  async function scan(rel, depth) {
118
146
  if (depth > 2) return;
@@ -159,7 +187,9 @@ export async function reportToolNeeds(projectDir) {
159
187
  for (const e of entries) {
160
188
  if (!e.isDirectory()) continue;
161
189
  if (["node_modules", ".git", "dist", "build", ".venv", "venv", ".claude"].includes(e.name)) continue;
162
- await scan(rel ? `${rel}/${e.name}` : e.name, depth + 1);
190
+ const child = rel ? `${rel}/${e.name}` : e.name;
191
+ if (ignored.has(child)) continue;
192
+ await scan(child, depth + 1);
163
193
  }
164
194
  }
165
195
 
@@ -810,7 +810,16 @@ for owner in $OWNERS; do
810
810
  TOOL="stryker"
811
811
  # From inside the owning package: npx resolves against ITS node_modules, and
812
812
  # stryker.config.json lives there too. A monorepo root usually has neither.
813
- CMD="\${RUN}npx --no-install stryker run --incremental --force $FLAGS"
813
+ #
814
+ # Deliberately NOT --incremental. --force does rerun every mutant in scope,
815
+ # so the diff itself was always judged fresh — but incremental mode still
816
+ # merges reports/stryker-incremental.json into the REPORT for everything
817
+ # out of scope, and this gate greps the whole report. Survivors recorded
818
+ # months ago came back as findings against a diff that never touched them:
819
+ # 8 of them on one commit, all long since killed. --mutate already scopes
820
+ # the run to the changed hunks, so incremental buys nothing here and costs
821
+ # a cache that goes stale exactly the way mutmut's did.
822
+ CMD="\${RUN}npx --no-install stryker run $FLAGS"
814
823
  elif [ -f "$base"package.json ]; then
815
824
  MISSING="$MISSING $label needs Stryker:
816
825
  npm --prefix \${owner} i -D @stryker-mutator/core @stryker-mutator/vitest-runner
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spardutti/claude-skills",
3
- "version": "2.19.0",
3
+ "version": "2.19.2",
4
4
  "description": "CLI to install Claude Code skills from the claude-skills collection",
5
5
  "type": "module",
6
6
  "repository": {