Files
claude-skills/.tasks/bootstrap-claude-md-merge.md
vitya 68fe9a8c1c feat(project-bootstrap): v1.3.0 — idempotent CLAUDE.md merge on upgrade
Step 5 was binary on upgrade (append whole template / leave alone), so
projects bootstrapped before v1.2.0 silently missed new canonical triggers
(`check across all projects`, `we're on Windows`) on re-run. Now upgrade
reads existing CLAUDE.md, substring-diffs vs template, preserves a
deliberately-pinned platform line, and appends only missing lines after
explicit confirm. Re-runs are no-ops.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 15:06:06 +03:00

3.2 KiB

bootstrap-claude-md-merge

Goal

project-bootstrap upgrade mode currently treats CLAUDE.md as binary: either append the entire template (causing duplicate trigger lines) or leave it untouched. Result: projects bootstrapped before v1.2.0 silently miss new canonical triggers like check across all projects (→ using-projects-meta) and we're on Windows (→ active-platform) when re-run on the upgrade path. Fix: turn Step 5 into an idempotent merge — read existing CLAUDE.md, diff against the template, append only missing canonical lines after user confirm. Re-runs become no-ops.

Key files

  • skills/project-bootstrap/SKILL.md:220-249 — Step 5 (the broken binary choice)
  • skills/project-bootstrap/assets/CLAUDE.md.template — canonical trigger set
  • skills/project-bootstrap/README.md — public surface, mention idempotency
  • dist/project-bootstrap.skill — rebuild after install
  • ~/.claude/skills/project-bootstrap/ — reinstall target

Decisions log

  • 2026-04-30: Diff strategy — substring match per template line against existing file (trim + lowercase). A trigger is "present" if any existing line contains the template trigger text. Avoids false-positive duplicates when user has rephrased a trigger but preserves canonical wording for missing ones. Rejected: full line-equality match (too brittle — user comments / case differences would re-add).
  • 2026-04-30: Confirmation gate stays — show user the diff (N lines to append) before touching the file. Idempotent run with no missing lines = silent no-op.
  • 2026-04-30: Version bump 1.2.0 → 1.3.0. Behavior change visible to users on every upgrade — minor bump fits semver intent.

Open questions

  • Should the platform line (we're on Windows) be substituted to match the host during merge, the same way init does it? Decision: yes — if existing file has no we're on (Windows|Linux|macOS) line, append the host-appropriate one. If it has any of the three, leave it (user may have intentionally pinned a different platform).

Completed steps

  • open task
  • patch Step 5 in SKILL.md (read → diff → confirm → append) — split Init / Upgrade-merge
  • bump version 1.2.0 → 1.3.0 in SKILL.md frontmatter
  • update skills/project-bootstrap/README.md CLAUDE.md row to note idempotent merge
  • update root README.md + README.ru.md upgrade-mode paragraph
  • reinstall + rebuild dist (bash scripts/install.sh project-bootstrap && bash scripts/build.sh project-bootstrap); verified version: 1.3.0 on disk + Step 5 split
  • wiki: concept page .wiki/concepts/bootstrap-claude-md-merge.md, index entry, log entry
  • commit
  • STATUS.md: 🔴🟢
  • decision on platform line — preserve if user pinned non-host one (case-insensitive we're on (windows|linux|macos) match)

Notes

Existing related task [bootstrap-recommend-projects-meta] (Step 5.7) is machine-level detection (recommend setup-projects-meta if MCP server not registered). This task is project-level merge of the trigger line into the project's CLAUDE.md. They compose cleanly: 5.7 makes the trigger functional on the host, this task ensures the trigger is actually present in the file.