Files
Lyu 2041ba5b4f Consolidate insforge-dev skill via a sync script (real copies) + fix drift
The insforge-dev skill is mirrored across .claude/.codex/.agents (each agent
discovers skills only from its own dir) and the hand-synced copies had drifted —
the actively-read .claude copy had fallen behind .agents/.codex.

Symlinks would give a single source but break on Windows checkouts (they
materialize as plain text files) and trip Prettier (errors on explicitly-passed
symlinks). So instead:

- .agents/skills/insforge-dev is the single source of truth; .claude and .codex
  are real copies generated by scripts/sync-skills.sh.
- scripts/sync-skills.sh [--check]: copies canonical -> the two agent dirs, or
  (--check) diffs them and exits non-zero on drift.
- CI runs `sync-skills.sh --check` in lint-and-format.yml so a PR that edits one
  copy without re-syncing fails. This is what actually enforces the single
  source — manual syncing is what drifted before.
- Re-synced all three copies and fixed two drifts vs the codebase:
  - SKILL.md: `npm run typecheck` DOES cover dashboard/shared-schemas (every
    repo task runs through Turborepo; verified via `turbo run typecheck
    --dry-run`).
  - backend/SKILL.md: UserContext is `{ id, role, email? }` (`id` required).
- Documented the canonical + sync workflow in .claude/skills/README.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:04:53 -07:00

63 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# sync-skills.sh — mirror the canonical insforge-dev skill to the per-agent copies.
#
# .agents/skills/insforge-dev is the single source of truth. Claude Code and
# Codex each discover skills from their own directory, so we keep byte-identical
# copies in .claude/ and .codex/. Symlinks are not an option: Windows checkouts
# don't preserve them (they become plain text files), and Prettier errors on
# explicitly-passed symlinks. So we generate real copies and let CI guard drift.
#
# Edit ONLY .agents/skills/insforge-dev, then run this script and commit all
# three trees together.
#
# Usage:
# scripts/sync-skills.sh Copy canonical -> .claude and .codex
# scripts/sync-skills.sh --check Exit non-zero if any copy has drifted (CI)
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CANONICAL="$REPO_ROOT/.agents/skills/insforge-dev"
COPIES=(
"$REPO_ROOT/.claude/skills/insforge-dev"
"$REPO_ROOT/.codex/skills/insforge-dev"
)
CHECK=0
case "${1:-}" in
--check) CHECK=1 ;;
-h|--help) sed -n '2,18p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
"") ;;
*) echo "unknown argument: $1" >&2; exit 2 ;;
esac
[[ -d "$CANONICAL" ]] || { echo "missing canonical skill dir: $CANONICAL" >&2; exit 1; }
status=0
for copy in "${COPIES[@]}"; do
if [[ "$CHECK" -eq 1 ]]; then
if ! diff -r "$CANONICAL" "$copy" >/dev/null 2>&1; then
echo "DRIFT: $copy is out of sync with the canonical $CANONICAL" >&2
diff -ru "$CANONICAL" "$copy" >&2 || true
status=1
fi
else
rm -rf "$copy"
mkdir -p "$(dirname "$copy")"
cp -R "$CANONICAL" "$copy"
echo "synced: $copy"
fi
done
if [[ "$CHECK" -eq 1 ]]; then
if [[ "$status" -eq 0 ]]; then
echo "insforge-dev skill copies are in sync with .agents/"
else
echo "Run 'scripts/sync-skills.sh' and commit the result." >&2
fi
fi
exit "$status"