feat: ship seodraft as a native pi package - #3
Merged
Merged
Conversation
Pi loads packaged resources in place from the `pi` key in package.json, so
`pi install npm:seodraft` now registers the skill straight out of the
installed package — no copy into the user's repo, and `pi update` keeps it
current.
- declare `pi.skills` (`./skill`) and `pi.prompts` (`./prompts`) plus the
`pi-package` gallery keyword
- add `prompts/seodraft.md`, which restores the literal `/seodraft <command>`
invocation pi would otherwise only expose as `/skill:seodraft`. It sticks to
`$1` / `${@:2}`: released pi builds do not substitute bash-style defaults
like `${1:-status}` and leak the token into the prompt
- add `pi` to the installer's provider registry (`.pi`) for parity, and a test
asserting every provider receives a byte-identical payload
- add a distribution contract test over the manifest, tarball `files` and
template syntax
- fail the tarball smoke test when a `pi` manifest root is missing from the
published `files`, which would make pi load an empty package
The skill payload other harnesses receive is unchanged: `prompts/` lives at
the package root and is never copied.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Pi loads a package's resources in place from the
pikey inpackage.json.Today
pi install npm:seodraftinstalls the package and registers nothing,because our skill directory is
skill/(singular) and there is nopimanifest. This adds the manifest, so the skill is loaded straight out of the
installed package — nothing is copied into the user's repo and
pi updatekeeps it current.
pi.skills=./skill,pi.prompts=./prompts, plus thepi-packagegallery keyword.
prompts/seodraft.mdrestores the literal/seodraft <command>invocationthat Pi would otherwise only expose as
/skill:seodraft.pijoins the installer's provider registry (.pi/skills/) for parity.tests/pi-package.test.mjsis a distribution contract: manifest rootsexist, ship in
files, resolve to exactly one skill, and templates only useargument syntax Pi actually substitutes.
scripts/smoke-tarball.mjsnow fails if anypimanifest root is missingfrom the published tarball — the failure mode is a package that installs
cleanly and loads nothing.
Nothing changes for the harnesses already supported.
prompts/is apackage-root resource that the installer never copies, so the payload landing
in
.claude,.agents,.cursor,.geminiand.opencodeis byte-identicalto 0.1.0. A new test asserts exactly that across every provider.
Checklist
pnpm testpasses — 81 tests, 10 suitesskill/scripts/imports anything butnode:builtins andrelative paths (
pnpm check:deps)README.md(Requirements, Install, new### Pisection),CONTRIBUTING.md,CHANGELOG.mdSeverity, if this adds a rule
No rules added.
How you verified it
Against Pi's own installed implementation (
pi 0.76.0), drivingDefaultPackageManager.resolve(),loadSkillsFromDir()andexpandPromptTemplate()from@earendil-works/pi-coding-agent/dist/core/*directly:npm pack, extracted into a fake~/.pi/agent/npm/node_modules/seodraft, registered as a package: resolvesto exactly
skill/SKILL.md(1 skill, nameseodraft, 0 warnings) andprompts/seodraft.md(1 prompt), with no extensions or themes.node <pkg>/skill/scripts/state.mjs validatefrom a content repo → exit 0,{"ok": true}.every harness folder:
diff -rqbetween the copied trees is identical, andno
prompts/directory appears inside any of them..pi/skills/,.agents/skills/and.claude/skills/layouts each resolve to exactly['seodraft']with 0warnings —
skill/reference/*.mdis never picked up, because Pi stopsrecursing at a directory holding
SKILL.md./seodraft init "focus on pricing pages"expandswith
initand the trailing notes substituted, no tokens left behind. Thisis how the
${1:-status}bug was caught: Pi's docs onmainlistbash-style defaults, but
substituteArgsin released builds only handles$N,$@,$ARGUMENTSand${@:N[:L]}, so${1:-status}reached themodel verbatim. The template now uses
$1and${@:2}, and the newcontract test rejects any other
${...}token.one machine makes Pi emit a
collisiondiagnostic and keep the first skillfound.
README.mdsays to pick one route.