fix: plugin agents not deployed due to directory nesting bug#214
fix: plugin agents not deployed due to directory nesting bug#214danielmeppiel merged 3 commits intomainfrom
Conversation
When plugin.json declares agents as a custom list (e.g. "agents": ["./agents"]), _map_plugin_artifacts preserved the directory name, creating .apm/agents/agents/ instead of .apm/agents/. This caused agent files to be silently dropped during integration. Root cause: unlike skills (named directories), agents are flat files — the custom list branch should merge directory contents directly, not nest by dir name. Also: - Harden find_agent_files with rglob for subdirectory resilience - Fix Plugin.from_path to discover plain .md agents (not just .agent.md) Fixes agent deployment for plugins like awesome-copilot/context-engineering.
There was a problem hiding this comment.
Pull request overview
Fixes plugin agent deployment when plugin.json uses a custom agents directory list (e.g. "agents": ["./agents"]), ensuring mapped agent files end up where AgentIntegrator can discover and integrate them.
Changes:
- Flatten agent directory contents into
.apm/agents/in plugin artifact mapping to avoid.apm/agents/agents/nesting. - Make
AgentIntegrator.find_agent_files()resilient to nested agent directories by switchingglob()→rglob(). - Expand plugin agent discovery to include plain
.mdfiles underagents/(not only*.agent.md), plus add/adjust regression tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/apm_cli/deps/plugin_parser.py |
Fixes agent mapping so custom agent directories are merged directly into .apm/agents/. |
src/apm_cli/integration/agent_integrator.py |
Switches to recursive discovery for .apm/agents to avoid silent drops when nesting occurs. |
src/apm_cli/models/plugin.py |
Broadens Plugin.from_path() agent discovery to include plain .md files. |
tests/unit/test_plugin_parser.py |
Updates/extends mapping tests to assert flattened agents behavior and prevent regression. |
tests/unit/integration/test_agent_integrator.py |
Adds tests for nested agent discovery and plain .md → .agent.md target naming. |
| # Map agents/ | ||
| # Unlike skills (which are named directories containing SKILL.md), agents | ||
| # are flat files — each .md is one agent. So we always merge directory | ||
| # contents directly into .apm/agents/ (no nesting by dir name). | ||
| agent_sources = _resolve_sources("agents", "agents") |
There was a problem hiding this comment.
Docs appear to be out of sync with this change: docs/plugins.md currently states that when a custom component path array contains directories, each directory is preserved as a named subdirectory. With this update agents directories are always flattened into .apm/agents/ (no agents/<dir-name>/ nesting). Please update docs/plugins.md to clarify that agents are an exception (flattened), while skills keep the named-subdir behavior.
There was a problem hiding this comment.
Good catch — fixed in afb01d6. docs/plugins.md now clarifies that agents are flattened into .apm/agents/ while skills keep the named-subdirectory behavior.
All .md files in an agents/ directory should be respected regardless of filename. The directory semantics already imply the file type.
Problem
When
plugin.jsondeclares agents as a custom list (e.g."agents": ["./agents"]),_map_plugin_artifactspreserved the directory name, creating.apm/agents/agents/instead of.apm/agents/. This caused agent files to be silently dropped during integration — they never reached theAgentIntegrator.Real-world impact: The
context-engineeringplugin fromgithub/awesome-copilothas acontext-architect.mdagent that was never deployed to.github/agents/.Root Cause
Unlike skills (which are named directories containing
SKILL.md), agents are flat files — each.mdis one agent. The custom-list branch in_map_plugin_artifactswas usingcopytree(d, target / d.name)which nests the directory, but should usecopytree(d, target)to merge contents directly — matching how the non-custom (default) path already worked.Changes
Fix 1 —
plugin_parser.py(root cause)Agents custom-list branch now merges directory contents into
.apm/agents/directly instead of preserving the directory name as a subdirectory.Fix 2 —
agent_integrator.py(defensive)Changed
glob()→rglob()infind_agent_filesso agents in subdirectories are still discovered even if nesting occurs from other sources.Fix 3 —
plugin.py(consistency)Plugin.from_pathonly discovered*.agent.mdfiles. Now also discovers plain.mdfiles (excluding known non-agent names like README.md), matching whatAgentIntegrator.find_agent_filesalready does.Tests
test_mixed_files_and_dirsto assert flattened (correct) behaviortest_custom_agents_dir_list_flattens_contents— regression test for the exactcontext-engineeringplugin patterntest_find_agent_files_discovers_nested_subdirectories— validates rglob resiliencetest_get_target_filename_plain_md— confirms.md→.agent.mdrename for.github/agents/Verification
apm installin sample project now correctly deployscontext-architect.agent.mdto.github/agents/