Dist-Zilla-Plugin-GatherAgentContext
view release on metacpan or search on metacpan
.claude/skills/gatheragentcontext-core/SKILL.md view on Meta::CPAN
a configured tree. Other directories (`.agents/skills`, own `dir` entries) are taken in
full.
## The built-in excludes
Always skipped, wherever they are found, before any `exclude_match` addition:
| Excluded | Why |
|---|---|
| `<name>.local.<ext>` (any depth) | machine-local overrides and their backups. A **leading-dot** `.local.<name>.md` is skilletor content and stays. |
| `.credentials.json`, `auth.json` | harness login tokens |
| `settings.json` | editor and permission config, not agent content |
| any `worktrees/` directory | agent worktrees hold full checkouts (thousands of files) |
| `.DS_Store` | â |
| `.gitignore` | unless `prune_gitignore` is 0 |
An excluded **directory** is pruned before the plugin descends into it, so its contents
are never stat-walked. A rewrite into walk-then-filter re-introduces a full walk of
`.claude/worktrees/` on every build â the thing the prune exists for.
## Encoding and symlinks
Build
Build.bat
pm_to_blib
# XS build artifacts
*.o
*.bs
# Testing
cover_db/
pod2htmd.tmp
# Claude Code â commit: skills/, agents/, hooks/, settings.json
# Ignore: local overrides, credentials, session data
.claude/*.local.*
.claude/local/
.claude/.credentials.json
.claude/statsig/
.claude/todos/
.claude/projects/
# karr materialized task view -- never commit
tasks/
config.yml
# Claude Code worktrees (claude --worktree / isolated agents) -- never commit
/.claude/worktrees/
Release history for Dist-Zilla-Plugin-GatherAgentContext
0.002 2026-10-25 18:38:49Z
- Local state and secrets below a harness directory can no longer end up
in the tarball. Below .claude/ and .codex/ only agent content is
gathered now (agents/, skills/, rules/, hooks/, commands/, CLAUDE.md,
skilletor.json, skilletor.lock.json, skilletor-rules.md); everything
else there (.credentials.json, auth.json, config.toml, projects/,
todos/, statsig/, local/, session logs, backups, ...) is never read,
whatever it is called. To snapshot a further subdirectory, configure it
by name ("dir = .claude/output-styles").
- Built-in excludes cover any <name>.local.<ext> file (settings.local.json,
settings.local.json.bak, CLAUDE.local.md) as well as .credentials.json
and auth.json, at any depth.
0.001 2026-09-29 20:02:51Z
- Initial release: snapshot agent context (.claude/.codex/CLAUDE.md/...)
into the build under misc/agent-context/ for build provenance.
lib/Dist/Zilla/Plugin/GatherAgentContext.pm view on Meta::CPAN
return @files;
}
sub _exclude_res {
my ($self) = @_;
my @res = (
# <name>.local.<ext>: machine-local overrides (settings.local.json,
# skilletor.local.json, CLAUDE.local.md) and their backups (.local.json.bak).
# A leading-dot `.local.<name>.md` is skilletor-installed content and stays.
qr{(?:^|/)[^/]+\.local\.[^/]+$},
qr{(?:^|/)(?:\.credentials|auth)\.json$}, # harness login tokens
qr{(?:^|/)settings\.json$}, # editor/permission config, not agent content
qr{(?:^|/)worktrees/},
qr{(?:^|/)\.DS_Store$},
);
push @res, qr{(?:^|/)\.gitignore$} if $self->prune_gitignore;
push @res, map { qr/$_/ } @{ $self->exclude_match };
return @res;
}
sub _excluded {
lib/Dist/Zilla/Plugin/GatherAgentContext.pm view on Meta::CPAN
the directories C<agents/>, C<skills/>, C<rules/>, C<hooks/> and C<commands/>,
recursively;
=item *
the files C<CLAUDE.md>, C<skilletor.json>, C<skilletor.lock.json> and
C<skilletor-rules.md>.
=back
So C<.claude/.credentials.json>, C<.claude/projects/>, C<.claude/todos/>,
C<.claude/statsig/>, C<.claude/local/>, C<.codex/auth.json>,
C<.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 L</dir> and for one met deeper inside a configured tree.
Other directories (C<.agents/skills>, or your own L</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]
lib/Dist/Zilla/Plugin/GatherAgentContext.pm view on Meta::CPAN
=item *
Any C<< <name>.local.<ext> >> file (for example C<settings.local.json>,
C<skilletor.local.json>, C<CLAUDE.local.md>, or a backup such as
C<settings.local.json.bak>) â machine-local overrides, not agent content.
Skilletor-installed agents and rules named C<< .local.<name>.md >> (leading
dot) are content and are kept.
=item *
C<.credentials.json> and C<auth.json> â harness login tokens.
=item *
C<settings.json> â editor and permission configuration, not agent content.
=item *
Any C<worktrees/> directory â agent worktrees hold full checkouts (thousands
of files). Such directories are pruned before descent, not walked and then
discarded leaf by leaf.
misc/agent-context/.claude/skills/gatheragentcontext-core/SKILL.md view on Meta::CPAN
a configured tree. Other directories (`.agents/skills`, own `dir` entries) are taken in
full.
## The built-in excludes
Always skipped, wherever they are found, before any `exclude_match` addition:
| Excluded | Why |
|---|---|
| `<name>.local.<ext>` (any depth) | machine-local overrides and their backups. A **leading-dot** `.local.<name>.md` is skilletor content and stays. |
| `.credentials.json`, `auth.json` | harness login tokens |
| `settings.json` | editor and permission config, not agent content |
| any `worktrees/` directory | agent worktrees hold full checkouts (thousands of files) |
| `.DS_Store` | â |
| `.gitignore` | unless `prune_gitignore` is 0 |
An excluded **directory** is pruned before the plugin descends into it, so its contents
are never stat-walked. A rewrite into walk-then-filter re-introduces a full walk of
`.claude/worktrees/` on every build â the thing the prune exists for.
## Encoding and symlinks
t/20-excludes.t view on Meta::CPAN
}
# --- Local state and secrets below a harness directory never reach the build.
# The harness and the user park session logs, todos, caches and login tokens in
# .claude/ and .codex/. Nothing of that may be gathered -- including names no
# list anticipated (history.jsonl, a stray backup, a new cache dir): below a
# harness directory only known agent content is taken.
{
my %state = (
# what the fleet .gitignore calls "never track"
'source/.claude/.credentials.json' => "{\"token\":\"s3cret\"}\n",
'source/.claude/projects/-home-x/abc.jsonl' => "session log\n",
'source/.claude/todos/a.json' => "[]\n",
'source/.claude/statsig/cache.json' => "{}\n",
'source/.claude/local/notes.md' => "private\n",
'source/.claude/settings.local.json' => "{}\n",
'source/.claude/settings.local.json.bak' => "{}\n",
'source/.claude/CLAUDE.local.md' => "private memory\n",
'source/.codex/auth.json' => "{\"token\":\"s3cret\"}\n",
# names nobody put on a list
'source/.claude/history.jsonl' => "prompt history\n",
'source/.claude/shell-snapshots/s.sh' => "export TOKEN=s3cret\n",
'source/.claude/notes.txt' => "scratch\n",
'source/.codex/config.toml' => "[mcp_servers.x]\n",
'source/.codex/sessions/2026/s.jsonl' => "session log\n",
# a content name of the wrong kind is not content
'source/.codex/rules' => "a file, not the rules dir\n",
# tokens and local overrides tucked into otherwise gathered directories
'source/.claude/skills/foo/auth.json' => "{}\n",
'source/.claude/skills/foo/.credentials.json' => "{}\n",
'source/.claude/agents/reviewer.local.md' => "local override\n",
'source/.agents/skills/bar/auth.json' => "{}\n",
);
my %content = (
'source/CLAUDE.md' => "c\n",
'source/AGENTS.md' => "a\n",
'source/.claude/CLAUDE.md' => "c\n",
'source/.claude/agents/worker.md' => "agent\n",
'source/.claude/agents/.local.karr-coordinator.md' => "agent\n",
'source/.claude/skills/foo/SKILL.md' => "body\n",
t/20-excludes.t view on Meta::CPAN
'exactly the agent content is gathered, nothing else';
}
# --- An explicitly configured harness directory is filtered the same way:
# `dir = .claude` means "the agent content of .claude", not "all of .claude".
{
my $tzil = build_tzil(
ini => [ 'dir = .claude' ],
files => {
'source/.claude/skills/foo/SKILL.md' => "body\n",
'source/.claude/.credentials.json' => "{}\n",
'source/.claude/projects/p/abc.jsonl' => "session log\n",
},
);
plugin($tzil)->gather_files;
is_deeply [ gathered($tzil) ],
[ 'misc/agent-context/.claude/skills/foo/SKILL.md' ],
'explicit dir = .claude still takes agent content only';
}
# --- A harness directory met deeper in a configured tree is filtered too.
( run in 1.309 second using v1.01-cache-2.11-cpan-3f962061493 )