Pi extension for deterministic, path-scoped context injection from CONTEXT.json files.
pi-context-tree moves context routing out of model behavior and into machine-readable repository config.
Instead of asking an agent to remember to read project docs, each folder can declare which files or URLs must be injected for a target path and operation.
event hook + optional target path
→ parent/all CONTEXT.json files
→ matching injection_rules[] entries
→ source-catalog references with mode-specific excerpts or references
→ bounded context bundle
→ Pi turn, read result, or edit preflight
Implemented MVP:
- simplified
CONTEXT.jsonv1 schema; - implicit scope from
dirname(CONTEXT.json); sourcescatalog plus orderedinjection_rules[];- per-injection
onselectors with concrete hooks, hook groups, arrays, and granular overrides; - rule compatibility validation: rules with
match[]are path-aware; rules withoutmatch[]are runtime/pathless; - hooks:
session:start,agent:start,tool:*,session:spawn,subagent:spawn; - file and URL inject sources;
- user-global injection config via
~/.pi/CONTEXT.jsonorPI_CONTEXT_TREE_GLOBAL; - URL cache under
.pi/context-tree/cache/urls; - markdown section extraction, line ranges, markers, and annotated segments;
- bundle hashing and dedupe;
- read-result context injection;
- edit/write preflight injection;
- self-read skip to avoid reinjecting the file being read;
- scope guard fallback;
- structured TUI status/widget;
- unit tests for schema, matching, extraction, cache, bundles, permissions.
Scope is implicit: a CONTEXT.json applies to its containing folder.
Minimal example:
{
"$schema": "https://raw.githubusercontent.com/ZEDIUM-Off/pi-context-tree/v0.4.0/schemas/context.schema.json",
"sources": {
"domainRules": { "type": "file", "path": "./docs/domain-rules.md" },
"piExtensions": {
"type": "url",
"url": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/docs/extensions.md"
}
},
"injection_rules": [
{
"match": ["**/*.ts", "!**/*.test.ts"],
"inject": [{ "source": "domainRules", "on": "tool:read" }]
},
{
"inject": [{ "source": "piExtensions", "on": "agent:start" }]
}
]
}sources entries default to reference mode. Injection items can override source defaults globally or per hook:
{
"source": "implementation",
"on": [
{ "hooks": ["tool:read"], "mode": { "type": "ref" } },
{
"hooks": ["tool:edit", "tool:write"],
"mode": { "type": "sections", "names": ["Tests unitaires et déterminisme"] }
}
]
}Common modes:
inline: inject full source content;ref: inject only path/URL and load instructions;lines: inject selected line ranges;sections: inject named markdown sections;markers: inject marker-delimited excerpts;segments: inject mixed annotated excerpts.
See docs/schema.md for full schema field behavior and best practices.
/ct-status show scan status and active stack summary
/ct-detail show active stack, resolution history, conflicts, skips, and references
/ct-validate [path] validate configs and list valid/invalid paths
/ct-explain <path> [hook] explain matched injection rules and sources
/ct-fetch <path> compile bundle and fetch/cache inline URLs
/ct-cache-list show URL cache directory
/ct-cache-refresh <path> refresh cached URL sources for target
/ct-toggle on|off toggle entire Context Tree extension runtime
/ct-tui on|off toggle Context Tree widget display only
/ct-init [--resume] initialize editable Context Tree config for current codebase
/ct-init-review <proposal> review agent proposal inside current init flow
/ct-subagent <path> <task> planned subagent handoff via subagent:spawn
subagent is currently a planned interop point for pi-subagents.
Context Tree also registers two model-facing edit tools: ct_edit_request and ct_patch. ct_edit_request authorizes an explicit target set and resolves edit/write context before mutation. ct_patch applies exact replacements only to authorized targets, returns an agent-readable line-count summary plus focused diff, and renders a compact TUI row with a diff preview. In Pi's default keymap, press Ctrl+O on the tool row to expand/collapse the full diff; use your terminal or Pi viewport scrolling for long expanded output.
Init flow is human-controlled and resumable. It scans repository rules/skills, proposes line-scoped rule injections, and proposes Context7-specific doc lookups per scope. It never injects broad root documentation links automatically; use Context7 ctx7 library <name> <query> then ctx7 docs <libraryId> <query> --json to select precise chunks.
Context Tree uses Pi's native UI APIs:
setStatus()for compact footer status;setWidget()for a structured widget above the editor.
Compact widget shows active-stack runtime state:
Context Tree
✓ 11 valid · 0 invalid
active: 8 sources
latest: tool:read src/runtime/state.ts
events: 3 cand · 2 sel
diag: 0 conflicts · 1 skipped
Detailed source list stays on demand:
/ct-detail
Hide widget only:
/ct-tui off
Disable extension runtime:
/ct-toggle off
Context Tree also loads an optional user-global config before project scopes:
~/.pi/CONTEXT.json
Set PI_CONTEXT_TREE_GLOBAL=/path/to/CONTEXT.json to override the location. File sources in the global config resolve relative to the global config file; path-aware matches are evaluated against repository-relative target paths.
Release notes live in CHANGELOG.md. GitHub releases mirror the same version sections.
pnpm install
pnpm validatepnpm validate runs:
typecheck
schema:generate
test
From public GitHub repo:
pi install git:github.com/ZEDIUM-Off/pi-context-treeThen open Pi in a project and check extension:
/ct-status
/ct-validate
package.json exposes the extension entrypoint:
{
"pi": {
"extensions": ["./src/index.ts"]
}
}Try once:
pnpm pi:devInstall locally for self-development:
pnpm pi:install:local
pnpm pi:localUse /reload after source changes.
Test against real external codebases:
pnpm test:workspace <giturl|local-path>For a Git URL, this clones or fast-forwards the target repository under .test-workspaces/. For a local path, it uses that directory directly. Then it launches pi -e <this repo> from the workspace root. Extra args after the source are passed to pi.
This repo uses Context Tree to develop itself:
- root
CONTEXT.jsoninjects README and package metadata at session startup; src/CONTEXT.jsoninjects Pi docs for extension runtime files and implementation-plan sections for core files;scripts/CONTEXT.jsoninjects the canonical schema for schema generation;test/CONTEXT.jsoninjects test strategy sections.
AGENTS.md is not injected by Context Tree because Pi already loads it as project context.