@spardutti/claude-skills 2.35.0 → 2.36.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.
@@ -105,3 +105,17 @@ project_key() { # project_key <owner> <tool>
105
105
  case "$(family_of "$f")" in "$fam"|any) printf '%s\n' "$f"; [ -f "$f" ] && cat "$f" ;; esac
106
106
  done; } | git hash-object --stdin
107
107
  }
108
+
109
+ # A page test renders a whole screen, so it "kills" mutants in every util that screen calls.
110
+ # Backoffice ran 23 minutes that way, and hid 104 mutants no logic test checked.
111
+ stryker_page_tests() { # stryker_page_tests <base> <label>
112
+ grep -qs configFile "$1"stryker.conf* && return 0
113
+ pages=$(git ls-files -co --exclude-standard -- "${1:-.}" | grep -E '\.test\.[jt]sx$' \
114
+ | grep -vE '/(hooks|queries)/|(^|/)\.stryker-tmp/' | head -3)
115
+ [ -n "$pages" ] || return 0
116
+ echo " $2 stryker — UNPROVEN: page tests count as proof for logic, e.g."
117
+ printf '%s\n' "$pages" | sed 's/^/ /'
118
+ echo " Give Stryker a Vitest config that runs logic tests only — see"
119
+ echo " testing-best-practices/MUTATION-TESTING.md, \"Keep Page Tests Out Of The Run\"."
120
+ [ "$STATUS" = 0 ] && STATUS=2
121
+ }
@@ -12,8 +12,9 @@ added_files() {
12
12
  git ls-files --others --exclude-standard 2>/dev/null; } | sort -u
13
13
  }
14
14
 
15
- has_subject() { # has_subject <test path>: a file the test is named for, in the same folder
15
+ has_subject() { # has_subject <test path>: a file the test is named for, beside it or above its __tests__/
16
16
  d=$(dirname "$1")
17
+ [ "${d##*/}" = __tests__ ] && d=$(dirname "$d")
17
18
  stem=$(basename "$1" | sed -E 's/\.(test|spec)\.[^.]+$//')
18
19
  while :; do
19
20
  for e in ts tsx js jsx mjs cjs astro; do [ -f "$d/$stem.$e" ] && return 0; done
@@ -25,8 +25,8 @@
25
25
  # Exit codes:
26
26
  # 0 clean — nothing over the line limit, nothing survived, nothing uncovered
27
27
  # 1 findings that must be dealt with before shipping
28
- # 2 ran, but could not prove the tests (a mutation tool is missing) — report,
29
- # don't block; the output names exactly what to install and where
28
+ # 2 ran, but could not prove the tests (a mutation tool is missing, or page tests
29
+ # count as proof) — report, don't block; the output names the fix and where
30
30
  #
31
31
  # Config: the same .claude/gauntlet.conf as the Stop hook.
32
32
  # GAUNTLET_MAX_LINES=200 the per-file limit; 0 turns the check off
@@ -271,7 +271,7 @@ for owner in $OWNERS; do
271
271
  # 8 of them on one commit, all long since killed. --mutate already scopes
272
272
  # the run to the changed hunks, so incremental buys nothing here and costs
273
273
  # a cache that goes stale exactly the way mutmut's did.
274
- CMD="${RUN}npx --no-install stryker run --mutate '${FLAGS#,}'"
274
+ CMD="${RUN}npx --no-install stryker run --mutate '${FLAGS#,}'"; stryker_page_tests "$base" "$label"
275
275
  elif [ -f "$base"package.json ]; then
276
276
  MISSING="$MISSING $label needs Stryker:
277
277
  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.35.0",
3
+ "version": "2.36.0",
4
4
  "description": "Guardrails for Claude Code — best-practice skills, planning commands, and delivery gates.",
5
5
  "type": "module",
6
6
  "repository": {