feat: canonical skill library with cross-agent push/pull/adopt (0.8.0)#8
Conversation
Build/test commands and big-picture monorepo architecture, deferring governance and per-module detail to AGENTS.md and docs/summaries/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Shift skills to a canonical + transform model so they can be published once and shared across coding agents from any device. - Canonical local skill library at ~/.agentpm/skills (single source of truth); every agent's native skill dir symlinks back to one entry. - push: normalize destinations to skills/<name> by default; add --preserve-layout to keep native target-relative paths. - skill installs transform into the chosen agent's native root (.codex/skills, .claude/skills, .agents/skills), preserving nested collection sub-paths; agent/subagent layouts unchanged. Add the .claude/skills layout. - pull: fetch canonical skills/* from a target repo into the library and symlink into auto-detected agents (multi-select, default all). - adopt: move an existing local skill into the library, replace the origin with a managed symlink, and fan out to other agents. Reuses ensureManagedLink, recordGeneratedTargetInLocalGitExclude, and a backing source row (installs require a non-null source_id). CHANGELOG + workspace versions bumped to 0.8.0; docs and runtime summary updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b68d18fbfb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (await pathExists(libraryPath)) { | ||
| if (!originIsLink) { | ||
| warnings.push( | ||
| `A skill named "${name}" already exists in the library; keeping the existing library copy as the source of truth.`, | ||
| ); | ||
| } | ||
| } else { | ||
| this.reportStatus(`Moving "${name}" into the skill library...`); | ||
| await this.copyTreeInto(contentPath, libraryPath); |
There was a problem hiding this comment.
Avoid deleting adopted skill when library name collides
When agentpm adopt is run for an unmanaged skill whose name already exists in the AgentPM library, this branch only emits a warning and then continues to remove contentPath and replace it with a symlink to the existing library entry. In that collision scenario the newly adopted skill's files are never copied into the library, so the command silently discards the user's local skill contents; it should require confirmation/abort or preserve the incoming content instead of deleting it.
Useful? React with 👍 / 👎.
| return [ | ||
| ...new Map( |
There was a problem hiding this comment.
Detect canonical push destination collisions
With the new default canonicalization, different native skills that share a name (for example .codex/skills/foo and .claude/skills/foo) both map to skills/foo; this Map then keeps only one candidate and silently drops the other during agentpm push --all. Since AgentPM now detects both Codex and Claude skill layouts, this can publish the wrong variant or omit a user-selected skill without any warning; surface the collision and ask/abort rather than deduplicating by destination path.
Useful? React with 👍 / 👎.
|
Addressed the open review findings locally in commit What changed:
Validation run in this environment:
I have not pushed the commit to the PR branch yet. |
Summary
Shifts skills to a canonical + transform model so they can be published once and shared across coding agents (codex, claude, generic) from any device.
~/.agentpm/skills/— the single source of truth. Every agent's native skill dir is a symlink back to one library entry, so a skill is stored once and updates propagate everywhere (reuses the existingensureManagedLinkmachinery).agentpm pushnormalizes to a tidyskills/<name>form by default;--preserve-layoutkeeps native paths. Only skills are canonicalized — agents/subagents keep their native layout so the kind distinction survives round-trips.--target codex|claude|genericmaterializes a skill into that agent's native root (.codex/skills,.claude/skills,.agents/skills) regardless of source, preserving nested-collection sub-paths. Adds the.claude/skillslayout.agentpm pull [skills...] --from <target>— fetch canonical skills and fan them into auto-detected agents (multi-select, default all;--target/--yesoverrides).agentpm adopt <skillOrPath>— move an existing skill (e.g. in.claude) into the library, replace the origin with a symlink, and fan out to your other agents.--yes); one collision never aborts the fan-out.Release impact
Minor → 0.8.0 (pre-1.0), with a deliberate breaking change to
pushdestinations and--targetinstall mapping. CHANGELOG + workspace version bumps land together in the release commit.docs/summaries/runtime-architecture.md,docs/adapter-guide.md, and README updated.Validation
pnpm build,typecheck,lint✓pnpm test— 60 tests pass (4 push tests updated to canonical form; 5 new tests: canonical push,--preserve-layout, pull→multi-agent symlinks, adopt move+symlink, collision-skip)pnpm smoke✓adoptagainst an isolatedAGENTPM_HOMEconfirmed all agent dirs resolve to one library entry🤖 Generated with Claude Code