Skip to content

Add install.exclude frontmatter to keep companion files out of platform copies (#103) - #109

Merged
devrimcavusoglu merged 3 commits into
mainfrom
feature/install-exclude
Aug 19, 2026
Merged

Add install.exclude frontmatter to keep companion files out of platform copies (#103)#109
devrimcavusoglu merged 3 commits into
mainfrom
feature/install-exclude

Conversation

@devrimcavusoglu

Copy link
Copy Markdown
Owner

Summary

Fixes #103. Stacked on #106 (base branch fix/frontmatter-passthrough) — it needs #100's modeled-key machinery so the install: block survives registry writes. Once #106 merges, retarget this PR to main (GitHub will do it automatically on branch deletion).

  • New top-level frontmatter block, author-owned:
    install:
      exclude: [eval, fixtures/*, "*.draft.md"]
    Modeled as Skill.Install.Exclude (InstallConfig), omitted from output when empty.
  • skill.MatchExclude(patterns, rel) — stdlib path.Match against the slash-relative path and each leading directory, so a bare dir name excludes its subtree, fixtures/* its children, *.draft.md top-level files by suffix. No ** (documented, no new deps). SKILL.md can never be excluded.
  • Platform.Install(skillDir, name, scope, opts InstallOptions)copyDir takes a skip func and prunes matched directories with filepath.SkipDir. skill_install.go already had the parsed skill from reg.Get (it was discarding it); it now passes s.Install.Exclude. Registry copies (create --from-template, import) are untouched — the registry keeps everything.
  • skill validate: errors for empty / absolute / .. / malformed-glob / matches-SKILL.md patterns; warnings (in ValidateFolder) when a pattern matches no file, or when a body-referenced file would be excluded (exists in registry, missing from every install).
  • Docs: skill-format "Install-time exclusions" section + table row, validation reference, platform-adapters how-it-works, commands install, AGENTS.md format block + design decision 3 wording; CHANGELOG [Unreleased] › Added.

Issue DoD

  • Named directories/globs under a skill can be excluded from skill install while staying in the registry
  • skill diff accounts for intentionally-excluded paths — nothing to change: diff compares manifests (frontmatter + body), never file trees, so excluded files cannot surface as drift. TestSkillInstall_HonorsInstallExclude asserts diff reports identical after an excluding install. Documented in the new section.

Test plan

  • TestMatchExclude (17 cases), TestValidateExcludePattern, TestExcludedFiles, TestValidate_InstallExclude, TestValidateFolder_InstallExcludeWarnings, TestAdapter_Install_Exclude, TestCopyDir_SkipFuncPrunesDirectories, TestSkillInstall_HonorsInstallExclude (issue scenario end-to-end incl. round-trip of the block), TestSkillValidate_InstallExcludeErrors
  • go test ./..., make lint green
  • Manual: template with install.exclude: [eval] + eval/s1.md → registry has eval/s1.md, .claude/skills/demo.skill/ has only SKILL.md; bad patterns → validate exit 2

🤖 Generated with Claude Code

@devrimcavusoglu
devrimcavusoglu force-pushed the feature/install-exclude branch from 9b32ede to 7b935cf Compare August 19, 2026 13:11
devrimcavusoglu added a commit that referenced this pull request Aug 19, 2026
#108 removed the then-unused skill import from skill_install.go and #109
needs it again for ValidateExcludePatterns. The four near-term roadmap
entries are all closed by this stack, so the group heading goes too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@devrimcavusoglu
devrimcavusoglu force-pushed the feature/install-exclude branch from 7b935cf to 810aa3d Compare August 19, 2026 13:14
@devrimcavusoglu
devrimcavusoglu changed the base branch from fix/frontmatter-passthrough to feature/install-tag-filter August 19, 2026 13:14
@devrimcavusoglu

Copy link
Copy Markdown
Owner Author

Review (adversarial pass against #103)

DoD 1 holds across every registry write path (create, from-template, import keep everything; install trims). DoD 2 — file trees never show as drift (no skern surface walks installed trees), but the PR had introduced a regression in the same area, now fixed (8a78dad):

Sev Finding Resolution
Medium skill diff went blind to install.exclude changes — install became a modeled key so it left Extra, and compareSkills never looked at it install.exclude diffed as a field; install.* extras diffed too (TestSkillDiff_InstallExcludeAndExtras)
Medium Unmodeled keys under install: (install.mode, …) were dropped — undoing #100's guarantee for that subtree InstallConfig.Extra inline map + collision guard; exclude: eval (bare string) accepted as a one-element list
Low/Med skill install silently ignored an invalid pattern (path.Match just returns false → the file the author meant to exclude gets installed) Install refuses the skill with a per-skill error pointing at skill validate (TestSkillInstall_RefusesInvalidExcludePattern)
Low ** silently degraded to * (works on a shallow fixture tree, fails deeper) ** is a validation error with an explanatory message
Low Rejecting every pattern that could match SKILL.md (*, *.md) contradicted "SKILL.md is never excluded" — validate exited 2 for a config install honored correctly Only the literal SKILL.md is an error; * = "everything except SKILL.md"
Low Backslash→slash normalization broke path.Match's \ escape Backslashes left alone; documented
Low Docs cited a nonexistent skill show --files; compatibility note for non-mapping install: missing Fixed; CHANGELOG carries the compatibility note
Nit Multi-entry error messages lacked an index; json:"…,omitempty" on a struct is a no-op install.exclude[N]; omitzero

Stacked on #108 (base feature/install-tag-filter) and rebased onto the updated #106; CI runs once the base becomes main. Full suite + lint green locally at the stack tip.

@devrimcavusoglu
devrimcavusoglu force-pushed the feature/install-tag-filter branch from 3fa77bc to 3c155ae Compare August 19, 2026 13:50
devrimcavusoglu and others added 3 commits August 19, 2026 16:52
…rm copies (#103)

skill install copied the whole skill tree, so eval corpora and fixtures
landed in every agent's context. Model an author-owned `install.exclude`
list of path.Match globs on Skill/frontmatter; match each relative path
and its leading directories in skill.MatchExclude; thread the patterns
through a new platform.InstallOptions argument on Platform.Install so
copyDir prunes matched files and directories. The registry always keeps
the full directory. skill validate errors on malformed, absolute, or
`..` patterns and anything matching SKILL.md, and warns when a pattern
matches nothing or excludes a body-referenced file.

Closes #103

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…refuse bad patterns at install

- skill diff reports a changed install.exclude list (it went blind once
  install became a modeled key) and diffs install.* extras.
- InstallConfig gets an inline Extra map (+ collision guard) so other keys
  under install: round-trip like every other unmodeled key; `exclude`
  accepts a bare string as a one-element list.
- skill install refuses a skill whose patterns fail validation instead of
  silently copying what path.Match could not parse; `**` is rejected
  outright rather than degrading to `*`.
- Only the literal SKILL.md is an error: wildcards that also match it are
  legal since MatchExclude never excludes the manifest. Backslashes are
  left alone (path.Match escape), validator field carries [index] for
  multi-entry lists.
- Docs: no `--files` flag; exact matching/escape/compat rules; roadmap
  line dropped; json tag omitzero.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#108 removed the then-unused skill import from skill_install.go and #109
needs it again for ValidateExcludePatterns. The four near-term roadmap
entries are all closed by this stack, so the group heading goes too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@devrimcavusoglu
devrimcavusoglu changed the base branch from feature/install-tag-filter to main August 19, 2026 13:52
@devrimcavusoglu
devrimcavusoglu force-pushed the feature/install-exclude branch from 810aa3d to 2d9f568 Compare August 19, 2026 13:52
@devrimcavusoglu
devrimcavusoglu merged commit 41e0288 into main Aug 19, 2026
5 checks passed
@devrimcavusoglu
devrimcavusoglu deleted the feature/install-exclude branch August 19, 2026 13:54
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.

skill install copies companion directories verbatim, with no exclusion mechanism

1 participant