@spardutti/claude-skills 2.35.0 → 2.36.1

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.
@@ -36,12 +36,16 @@ owner_of() {
36
36
  # Blaming an unreachable database for that sent one agent chasing Docker for 20 minutes.
37
37
  mutmut_unchecked() { # mutmut_unchecked <label> <base> <count> <run log>
38
38
  echo " $1 mutmut — UNPROVEN: $3 mutant(s) were never run."
39
- stop='Failed to run clean test|failed to collect stats|Failed to collect list of tests|Stopping early'
39
+ # "Failed to run pytest with args" is one line carrying every selected test id — 20KB of
40
+ # them on one repo — so the line is cut. Unlisted, the gate blamed a database instead.
41
+ stop='Failed to run clean test|failed to collect stats|Failed to collect list of tests|Stopping early|Failed to run pytest with args|BadTestExecutionCommandsException'
40
42
  if grep -aqsE "$stop" "$4"; then
41
43
  echo " mutmut stopped before testing a single mutant:"
42
- grep -aE "^(FAILED|ERROR) |^[A-Za-z]*Error: |$stop" "$4" | tail -8 | sed 's/^/ /'
44
+ grep -aE "^(FAILED|ERROR) |^[A-Za-z]*Error: |$stop" "$4" | tail -8 | cut -c1-200 | sed 's/^/ /'
43
45
  echo " It runs the whole suite, then these tests again in one process, so a"
44
46
  echo " test that passes alone can fail here on state an earlier test left."
47
+ echo " mutmut hides pytest's own error: set debug = true under [tool.mutmut]"
48
+ echo " and run it again to read it."
45
49
  return
46
50
  fi
47
51
  echo " They are recorded \"not checked\", so the suite proved nothing"
@@ -105,3 +109,17 @@ project_key() { # project_key <owner> <tool>
105
109
  case "$(family_of "$f")" in "$fam"|any) printf '%s\n' "$f"; [ -f "$f" ] && cat "$f" ;; esac
106
110
  done; } | git hash-object --stdin
107
111
  }
112
+
113
+ # A page test renders a whole screen, so it "kills" mutants in every util that screen calls.
114
+ # Backoffice ran 23 minutes that way, and hid 104 mutants no logic test checked.
115
+ stryker_page_tests() { # stryker_page_tests <base> <label>
116
+ grep -qs configFile "$1"stryker.conf* && return 0
117
+ pages=$(git ls-files -co --exclude-standard -- "${1:-.}" | grep -E '\.test\.[jt]sx$' \
118
+ | grep -vE '/(hooks|queries)/|(^|/)\.stryker-tmp/' | head -3)
119
+ [ -n "$pages" ] || return 0
120
+ echo " $2 stryker — UNPROVEN: page tests count as proof for logic, e.g."
121
+ printf '%s\n' "$pages" | sed 's/^/ /'
122
+ echo " Give Stryker a Vitest config that runs logic tests only — see"
123
+ echo " testing-best-practices/MUTATION-TESTING.md, \"Keep Page Tests Out Of The Run\"."
124
+ [ "$STATUS" = 0 ] && STATUS=2
125
+ }
@@ -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.1",
4
4
  "description": "Guardrails for Claude Code — best-practice skills, planning commands, and delivery gates.",
5
5
  "type": "module",
6
6
  "repository": {