NAME
Dist::Zilla::Plugin::GatherAgentContext - Snapshot the agent context (.claude/.codex/CLAUDE.md/AGENTS.md/...) into the build for provenance
VERSION
version 0.002
SYNOPSIS
; in your dist.ini
[GatherAgentContext]
; or narrow what is snapshotted
[GatherAgentContext]
harness = claude
exclude_match = (?:^|/)secrets/
DESCRIPTION
Gathers a distribution's agent context from disk into the build under misc/agent-context/ (present in the tarball, but not installed), so that a built distribution records which skills, agents and rules it was built with.
Unlike [Git::GatherDir] this plugin reads from the working directory, not from git, so it also captures skilletor-installed (git-ignored) skills, agents and rules — exactly the content that is not committed in the repository.
Because it reads from disk, it is strict about what it reads there: below a harness directory only known agent content is taken, never the local state a harness keeps next to it. See "WHAT IS SNAPSHOTTED".
harness
Which harness default sets to snapshot: claude, codex (repeatable), or all. Unset means all. Ignored once dir/file are set explicitly.
dir
Directories (repo-relative) to snapshot recursively. Overrides the harness-derived directory defaults. A harness directory (.claude, .codex) is reduced to its agent content even when named here; see "WHAT IS SNAPSHOTTED" for how to take more.
file
Single repo-relative files to snapshot. Overrides the harness-derived file defaults.
to
Base path inside the build. Default misc/agent-context.
exclude_match
Additional exclude regexes (repeatable), applied on top of the built-in ones (see "BUILT-IN EXCLUDES").
prune_gitignore
Skip .gitignore files (skilletor's per-skill management marker). Default 1.
missing_ok
Silently skip a configured dir/file that is absent. Default 1. Set to 0 to make an absent configured path fatal.
WHAT IS SNAPSHOTTED
A harness directory — any directory named .claude or .codex — is not only agent context. The harness and the user also keep local state there: login tokens, session transcripts, todo lists, caches, local overrides, backups. This plugin reads from disk, so a .gitignore does not keep any of that out of the tarball. Directly below a harness directory the plugin therefore takes only these entries and never opens anything else:
the directories
agents/,skills/,rules/,hooks/andcommands/, recursively;the files
CLAUDE.md,skilletor.json,skilletor.lock.jsonandskilletor-rules.md.
So .claude/.credentials.json, .claude/projects/, .claude/todos/, .claude/statsig/, .claude/local/, .codex/auth.json, .codex/config.toml and anything else a harness or a person drops there stay out, whatever the file is called. This holds for a harness directory named explicitly through "dir" and for one met deeper inside a configured tree.
Other directories (.agents/skills, or your own "dir" entries) are taken in full. To snapshot a further subdirectory of a harness directory, configure it by name — it is then an ordinary directory:
[GatherAgentContext]
dir = .claude
dir = .claude/output-styles
dir = .codex
dir = .agents/skills
The "BUILT-IN EXCLUDES" apply on top, everywhere.
BUILT-IN EXCLUDES
These paths are always skipped, wherever they are found and before any "exclude_match" additions:
Any
<name>.local.<ext>file (for examplesettings.local.json,skilletor.local.json,CLAUDE.local.md, or a backup such assettings.local.json.bak) — machine-local overrides, not agent content. Skilletor-installed agents and rules named.local.<name>.md(leading dot) are content and are kept..credentials.jsonandauth.json— harness login tokens.settings.json— editor and permission configuration, not agent content.Any
worktrees/directory — agent worktrees hold full checkouts (thousands of files). Such directories are pruned before descent, not walked and then discarded leaf by leaf..DS_Store..gitignorefiles, unless "prune_gitignore" is set to 0 (skilletor drops a per-skill.gitignoreas a management marker).
Any excluded directory is pruned before the plugin descends into it, so its contents are never stat-walked.
ENCODING AND SYMLINKS
Files are read and decoded as strict UTF-8. A binary or otherwise non-UTF-8 file aborts the build with a fatal error rather than being silently substituted — snapshot textual agent context, not binaries.
Within the recursive directory walk, symlinks are never followed — a symlinked file or subdirectory found while descending is skipped. A top-level path given explicitly through "dir" or "file" is resolved normally, so a configured entry that is itself a symlink is still read.
SUPPORT
Issues
Please report bugs and feature requests at https://github.com/Getty/p5-dist-zilla-plugin-gatheragentcontext/issues.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <getty@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.