pi-doc-injector
v0.3.1
Published
Auto-inject relevant project documentation into Pi's LLM context based on keyword matching
Maintainers
Readme
Pi Doc Injector
A Pi extension that automatically injects relevant project documentation into the LLM system prompt by monitoring streaming output for keyword matches.
Installation
Via npm (recommended)
pi install npm:pi-doc-injectorVia git
pi install git:github.com/lmn451/pi-doc-injectorManual
Copy this repository into your project's .pi/extensions/doc-injector/ folder, or clone directly:
git clone https://github.com/yourname/pi-doc-injector.git .pi/extensions/doc-injectorQuick Start
- Create a
docs/folder in your project root. - Add markdown files with YAML frontmatter:
---
title: "Testing Workflow"
keywords: [test, testing, jest, vitest]
---
# Testing Workflow
Your documentation here...Keywords can also be specified in block format:
---
title: "Testing Workflow"
keywords:
- test
- testing
- jest
- vitest
---- Start Pi. The extension scans
docs/on session start. - When the user mentions a keyword, the matching doc is injected into the system prompt before the assistant responds — no one-turn delay.
- If the assistant mentions a NEW keyword mid-response, generation is automatically aborted and restarted with the doc injected immediately.
Configuration
Create .pi/doc-injector.json in your project root to customize behavior:
{
"docsPath": "./docs",
"matchThreshold": 1,
"contextThreshold": 80,
"recursive": true
}| Option | Default | Description |
| ------------------ | ---------- | -------------------------------------------------------- |
| docsPath | "./docs" | Path to docs folder (relative to project root) |
| matchThreshold | 1 | Minimum keyword matches required to inject a doc |
| contextThreshold | 80 | Skip injection when context usage exceeds this % (0–100) |
| recursive | true | Scan docs subdirectories recursively |
Keyword Matching
Matching is case-insensitive and respects word boundaries by default. Once a document is injected, it won't re-match until you run /doc-inject reset.
Injection is also skipped if the current context usage exceeds 80% of the token budget.
Commands
| Command | Description |
| -------------------- | ---------------------------------------------------- |
| /doc-inject on | Enable doc injection |
| /doc-inject off | Disable doc injection |
| /doc-inject toggle | Toggle doc injection on/off |
| /doc-inject list | List all registered docs and their injection status |
| /doc-inject reset | Reset all injected flags (docs become re-injectable) |
| /doc-inject status | Show current injection status and config |
| /doc-reload | Re-scan docs folder and rebuild registry |
Injection Lifecycle
The extension uses a per-session injection model:
- On
session_start, the registry scansdocs/and indexes all valid documents. - Within a session, once a document is injected, it won't be re-injected automatically.
- Use
/doc-inject resetto manually reset all flags and allow docs to be injected again. - Use
/doc-inject listto see which docs have been injected (✅) and which are pending (⬜).
Injection Timing
- User messages: matched via the
inputevent, injected before the assistant responds — same turn, no delay. - Assistant streaming: if the assistant mentions a NEW keyword mid-response, generation is aborted and restarted with the doc injected immediately.
System Prompt Lifecycle
Pi reconstructs the system prompt from source files each turn (verified against pi v0.70.6).
When before_agent_start fires, the systemPrompt passed to the extension is a freshly rebuilt prompt from AGENTS.md, SYSTEM.md, skills, and tool snippets. It is not accumulated from previous turns.
This means:
- Injections apply to the current turn only and do not persist in subsequent turns.
- There is no risk of duplicate injection sections stacking up over time.
- The
injectedflag alone is sufficient to prevent re-injection — no additional deduplication or marker-based stripping is needed.
For the full source-level verification, see the JSDoc block in index.ts.
Development
# Run tests
npm test
# Run tests in watch mode
npm run test:watchLicense
MIT
