@spardutti/claude-skills 2.16.1 → 2.17.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.
Files changed (2) hide show
  1. package/lib/setup-hook.mjs +56 -1
  2. package/package.json +1 -1
@@ -565,6 +565,8 @@ const SHIP_GATE_SCRIPT = `#!/usr/bin/env bash
565
565
  # bash .claude/hooks/ship-gate.sh [base-ref]
566
566
  # bash .claude/hooks/ship-gate.sh --key print the receipt key and stop
567
567
  # bash .claude/hooks/ship-gate.sh --force write a FORCED receipt, run nothing
568
+ # bash .claude/hooks/ship-gate.sh --baseline record today's mutmut survivors as
569
+ # accepted debt, write no receipt
568
570
  #
569
571
  # On completion it writes a RECEIPT at /tmp/claude-shipgate-<key>, and the
570
572
  # PreToolUse hook refuses \`git commit\` / \`git push\` without a matching one. The
@@ -594,7 +596,11 @@ const SHIP_GATE_SCRIPT = `#!/usr/bin/env bash
594
596
  set -uo pipefail
595
597
 
596
598
  MODE=""
597
- case "\${1:-}" in --key) MODE=key; shift ;; --force) MODE=force; shift ;; esac
599
+ case "\${1:-}" in
600
+ --key) MODE=key; shift ;;
601
+ --force) MODE=force; shift ;;
602
+ --baseline) MODE=baseline; shift ;;
603
+ esac
598
604
 
599
605
  PROJECT_DIR="\${CLAUDE_PROJECT_DIR:-$PWD}"
600
606
  cd "$PROJECT_DIR" 2>/dev/null || { echo "ship-gate: cannot read $PROJECT_DIR"; exit 1; }
@@ -788,16 +794,59 @@ for owner in $OWNERS; do
788
794
  esac
789
795
  SURVIVED=$(printf '%s\\n' "$OUT" | grep -E "$PATTERN" \\
790
796
  | grep -vE '^[[:space:]]*[#│|+-]|# *surviv' | head -20)
797
+ FIXED=0
798
+ NOTE=""
799
+
800
+ # Stryker takes --mutate per changed hunk, so it already answers "did YOUR
801
+ # change get tested". mutmut cannot be asked that — 3.x dropped 1.x's
802
+ # --use-patch-file and never replaced it — so it mutates all of source_paths
803
+ # and reports the repo's entire backlog. Held to the same bar, the Python half
804
+ # answers "is this repo perfect" instead, which it never is, so it could never
805
+ # go green. The baseline supplies the missing half: survivors recorded once
806
+ # are accepted debt, and only a name that is not in it fails the gate.
807
+ #
808
+ # A mutant name carries an index within its own function, not a line number,
809
+ # so editing elsewhere in the file does not rename it — and editing the
810
+ # function itself DOES, which correctly re-charges its survivors to that edit.
811
+ if [ "$TOOL" = mutmut ]; then
812
+ BL="$base.mutmut-baseline"
813
+ NOWF=$(mktemp)
814
+ printf '%s\\n' "$OUT" \\
815
+ | sed -n 's/^[[:space:]]*\\([^[:space:]]*\\): survived$/\\1/p' | sort -u > "$NOWF"
816
+ if [ "$MODE" = baseline ]; then
817
+ cp "$NOWF" "$BL"
818
+ NOTE=" $label mutmut — baseline set: $(wc -l < "$BL") survivor(s) accepted. Commit $BL."
819
+ SURVIVED=""
820
+ elif [ -f "$BL" ]; then
821
+ # -Fxv against an empty baseline reports every survivor, which is right:
822
+ # an empty baseline means nothing has been accepted.
823
+ SURVIVED=$(grep -Fxv -f "$BL" "$NOWF" | head -20)
824
+ FIXED=$(grep -Fxvc -f "$NOWF" "$BL")
825
+ else
826
+ cp "$NOWF" "$BL"
827
+ NOTE=" $label mutmut — no baseline, so nothing could be compared. Recorded
828
+ $(wc -l < "$BL") existing survivor(s) in $BL — commit it, then run the
829
+ gate again. From here only NEW survivors fail; --baseline accepts more."
830
+ SURVIVED=""
831
+ [ "$STATUS" = 0 ] && STATUS=2
832
+ fi
833
+ rm -f "$NOWF"
834
+ fi
835
+
791
836
  if [ -n "$SURVIVED" ]; then
792
837
  echo " $label $TOOL — surviving mutants; these lines can break and no test notices:"
793
838
  printf '%s\\n' "$SURVIVED" | sed 's/^/ /'
839
+ [ "$FIXED" -gt 0 ] && echo " ($FIXED baselined survivor(s) now killed — --baseline banks them)"
794
840
  STATUS=1
795
841
  elif [ $RC -ne 0 ]; then
796
842
  echo " $label $TOOL — the run failed:"
797
843
  printf '%s\\n' "$OUT" | tail -12 | sed 's/^/ /'
798
844
  [ "$STATUS" = 0 ] && STATUS=2
845
+ elif [ -n "$NOTE" ]; then
846
+ printf '%s\\n' "$NOTE"
799
847
  else
800
848
  echo " $label $TOOL — ok, no surviving mutants in the changed lines"
849
+ [ "$FIXED" -gt 0 ] && echo " ($FIXED baselined survivor(s) now killed — --baseline banks them)"
801
850
  fi
802
851
  done
803
852
 
@@ -808,6 +857,12 @@ if [ -n "$MISSING" ]; then
808
857
  [ "$STATUS" = 0 ] && STATUS=2
809
858
  fi
810
859
 
860
+ if [ "$MODE" = baseline ]; then
861
+ echo
862
+ echo "ship-gate: baselines updated. No receipt written — run the gate for real."
863
+ exit 0
864
+ fi
865
+
811
866
  # The receipt is written by this script and nothing else. A hand-rolled check
812
867
  # produces no receipt, which is the whole point: substituting a weaker check is
813
868
  # a choice that can be argued for, but it cannot be passed off as this one.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spardutti/claude-skills",
3
- "version": "2.16.1",
3
+ "version": "2.17.0",
4
4
  "description": "CLI to install Claude Code skills from the claude-skills collection",
5
5
  "type": "module",
6
6
  "bin": {