Imported from edxeth/pi-better-skills (
AGENTS.md). Install upstream withnpx skills add edxeth/pi-better-skills. Copyright stays with the author.
AGENTS.md
-
Test with
bun test(bun:test, real temp dirs; see tests/). No tsconfig:bun run buildchecks bundling, not types; delete theindex.jsartifact it leaves in the repo root (it is not committed). When TypeScript is available, typecheck the extension withtsc --noEmit --module NodeNext --moduleResolution NodeNext --target ES2022 --skipLibCheck src/index.ts. -
This directory is a live-installed extension: editing files here changes the user's running pi. Live-check features with
pi -p --session-dir <tmp> --session-id <id> --model <provider/model>and read usage from the session JSONL (.message.usage). -
pi API facts learned the hard way (pi 0.84.x): at
before_agent_start,event.systemPromptis the base prompt without the skills section (pi appends it after handlers run), whileevent.systemPromptOptions.skillsis the authoritative loaded set.systemPromptOptions.selectedToolsdoes not reflect the prompt-build toolset (an exec_command-based toolset lists no "read" yet still renders skills) — do not gate on it. ExtensionskillPathsbypass--no-skills; honor the flag yourself. -
The pi-docs block template lives in pi's
dist/core/system-prompt.js; when the strip stops matching after a pi update, update the anchors insrc/pi-docs.tsand theREAL_BLOCKfixture intests/pi-docs.test.ts. Keep capture state per extension instance and usepi.getCommands()(not eventctx) to verify the generated skill's loaded path. -
General skill guidance rides as the named
agent_skillssection of the leading system message on every request viacontext_with_system(src/agent-skills-prompt.ts): request-clone only, set-by-name so repeats are no-ops. Pi applies abefore_agent_start-returnedsystemPromptafter that hook — the whole head is replaced for that run's normal turns, while idle turns skip the hook and keep the section. Test via real provider-facing requests, including an idle turn and its tool continuation, never only the first response. -
Skill bodies carry a dirs-only
<skill_context>(skill_dir + workspace_dir); skip insertion only when that exact generated block is present — an authored<skill_context>example is not proof. Never embed executable placeholder examples in guidance text: direct-read delivery executes dynamic placeholders in decorated text. -
Stripping a later
sections.docspatch must setdocs: null; deleting the key revives an earlier, superseded value. -
Residency checks must use public session APIs:
buildSessionContext(ctx.sessionManager.getBranch(), ctx.sessionManager.getLeafId()), not an unexposed method on the readonly manager. Test lifecycle changes with a real in-memorySessionManager. -
Both
tool_resultandmessage_endare chained: later extensions can replace or delay a message before persistence. Confirm residency from final session context before suppression decisions, and keep reservations until a result is persisted or the run ends. IdlesendMessagerows can bypass extensionmessage_endentirely.