Skip to content

fix(repo): narrow Claude gitignore entry so .claude/skills/ is not ignored (swamp-club#250)#1313

Merged
stack72 merged 1 commit intomainfrom
fix/250-claude-skills-gitignore
May 5, 2026
Merged

fix(repo): narrow Claude gitignore entry so .claude/skills/ is not ignored (swamp-club#250)#1313
stack72 merged 1 commit intomainfrom
fix/250-claude-skills-gitignore

Conversation

@stack72
Copy link
Copy Markdown
Contributor

@stack72 stack72 commented May 5, 2026

Summary

  • The managed .gitignore section wrote .claude/ (entire directory) for Claude repos, but all other tools only ignored their specific skills subdirectory (e.g. .cursor/skills/, .kiro/skills/)
  • This caused .claude/skills/ to be gitignored, so extension authors could not commit skill source files — making swamp extension push fail from any fresh CI/CD clone that didn't already have skills installed locally
  • Replace the broad .claude/ entry with four specific lines that mirror what the swamp repo's own .gitignore already does: .claude/worktrees/, .claude/settings.local.json, .claude/scheduled_tasks.lock, .claude/scheduled_tasks.json

.claude/skills/ is now untracked by the managed section. Extension authors can commit skill sources, swamp extension push packages them correctly, and swamp extension pull installs them to .claude/skills/<name>/ where Claude Code loads them — unchanged.

Test Plan

  • Updated repo_service_test.ts: replaced assertStringIncludes(content, ".claude/") substring assertions with precise checks for each specific entry, added assertEquals(content.split("\n").includes(".claude/"), false) to confirm the broad ignore is absent, added a dedicated Claude block verifying all four entries and that .claude/skills/ is not blocked
  • 110 tests pass across repo_service_test.ts and integration/cli_test.ts
  • deno check, deno lint, deno fmt all clean

🤖 Generated with Claude Code

…nored (swamp-club#250)

The managed gitignore section wrote `.claude/` (the entire directory) for
Claude repos, while every other tool only ignored its specific skills
subdirectory (e.g. `.cursor/skills/`). This meant `.claude/skills/` was
gitignored, so extension authors could not commit skill source files to
their extension repo — making `swamp extension push` fail from any fresh
CI/CD clone that didn't already have the skills installed locally.

Replace the broad `.claude/` entry with four specific lines that mirror
what the swamp repo's own .gitignore already does:

  .claude/worktrees/
  .claude/settings.local.json
  .claude/scheduled_tasks.lock
  .claude/scheduled_tasks.json

`.claude/skills/` is now untracked by the managed section, allowing
extension authors to commit skill sources and have them packaged
correctly by `swamp extension push`. The pull and remove behaviour
(installing to `.claude/skills/<name>/`) is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Clean, well-motivated bug fix. The four specific .claude/ entries exactly mirror the swamp repo's own .gitignore (lines 17, 21–23), and the legacy migration pattern at repo_service.ts:1051 correctly retains .claude/ recognition for migrating old gitignore formats.

Blocking Issues

None.

Suggestions

None — test coverage is thorough (positive assertions for all four entries, negative assertion for the broad .claude/ pattern, tool-switch cleanup verification, and a dedicated Claude-specific test block). The change is minimal and well-scoped.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adversarial Review

Critical / High

None.

Medium

  1. src/domain/repo/repo_service_test.ts:1072-1073 — Tool-switch test only verifies 2 of 4 Claude entries are removed. The "replaces managed section on tool switch" test asserts that .claude/worktrees/ and .claude/settings.local.json are absent after switching to cursor, but does not verify .claude/scheduled_tasks.lock or .claude/scheduled_tasks.json are also gone. In practice this is fine because replaceManagedSection atomically replaces the entire block between markers, so partial removal is impossible — but the test doesn't fully prove the contract for the new four-entry set. Not blocking since the mechanism is sound.

Low

  1. src/domain/repo/repo_service.ts:75 — Future .claude/ files created by Claude Code won't be gitignored. The old .claude/ glob caught everything; the new four entries are specific. If Claude Code adds new ephemeral files (e.g. .claude/todos.json, .claude/cache/), they'll appear as untracked until swamp adds them. This is the intended tradeoff (unblock .claude/skills/), and the entries match the repo's own .gitignore, so this is a conscious design decision rather than an oversight.

Verdict

PASS — Minimal, well-scoped change (1 production line, thorough test updates). The four specific ignore entries match the repo's own .gitignore. Legacy migration correctly recognizes the old .claude/ pattern (line 1051) to transition existing repos. The buildGitignoreSection / replaceManagedSection logic handles all code paths (create, update, migrate, tool-switch) and tests cover each.

@stack72 stack72 merged commit 9b0c9b4 into main May 5, 2026
11 checks passed
@stack72 stack72 deleted the fix/250-claude-skills-gitignore branch May 5, 2026 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant