|
2 | 2 |
|
3 | 3 | ## Project |
4 | 4 |
|
5 | | -`pi-context-tree` is a Pi extension for folder-scoped contextualization. |
| 5 | +`pi-context-tree` is a Pi extension for deterministic, path-scoped contextualization. |
6 | 6 |
|
7 | | -Goal: move routing/context-loading responsibility out of LLM prose and into machine-readable `CONTEXT.json` files. Agents should receive required folder context automatically when they read or touch files under matching scopes. |
| 7 | +Goal: move routing/context-loading responsibility out of LLM prose and into machine-readable `CONTEXT.json` files. Agents receive required folder context automatically when they read, edit, write, or start work on files under matching scopes. |
8 | 8 |
|
9 | 9 | ## Core idea |
10 | 10 |
|
11 | | -- `CONTEXT.json` is machine contract: routing, includes, runtime hints. |
12 | | -- `CONTEXT.md` is optional human summary: short scope description only. |
13 | | -- Reference markdown/code files hold actual reusable context. |
14 | | -- Extension resolves context by file path, not by asking model to discover it. |
| 11 | +```text |
| 12 | +path + operation |
| 13 | +→ parent CONTEXT.json files |
| 14 | +→ matching context[] entries |
| 15 | +→ local files / cached URLs / extracted sections |
| 16 | +→ context bundle |
| 17 | +→ Pi injection point |
| 18 | +``` |
| 19 | + |
| 20 | +`CONTEXT.json` is the machine contract. There is no special `CONTEXT.md` convention anymore; markdown files are normal inject sources referenced from JSON. |
| 21 | + |
| 22 | +## Current schema direction |
15 | 23 |
|
16 | | -Expected flow: |
| 24 | +Scope is implicit: |
17 | 25 |
|
18 | 26 | ```text |
19 | | -file path -> parent scope CONTEXT.json files -> merged context bundle -> injected into Pi turn/tool result |
| 27 | +dirname(CONTEXT.json) |
20 | 28 | ``` |
21 | 29 |
|
22 | | -## Design principles |
| 30 | +A config uses: |
23 | 31 |
|
24 | | -- Keep routing machine-readable and validated. |
25 | | -- Keep context minimal and path-scoped. |
26 | | -- Prefer canonical sources over duplicated rules. |
27 | | -- Do not put large business rules inside `CONTEXT.json`; link files instead. |
28 | | -- Default to conservative injection: once per turn, deduped, token-capped. |
29 | | -- Start with explainable behavior before automation-heavy behavior. |
| 32 | +```json |
| 33 | +{ |
| 34 | + "version": 1, |
| 35 | + "context": [ |
| 36 | + { |
| 37 | + "match": ["**/*.ts", "!**/*.test.ts"], |
| 38 | + "operations": ["agent_start", "read", "edit"], |
| 39 | + "inject": ["./docs/rules.md"] |
| 40 | + } |
| 41 | + ] |
| 42 | +} |
| 43 | +``` |
30 | 44 |
|
31 | | -## Planned MVP |
| 45 | +Rules: |
32 | 46 |
|
33 | | -1. Scan repository for `CONTEXT.json` files. |
34 | | -2. Resolve applicable scopes from a target file path. |
35 | | -3. Load `context.include[]` files. |
36 | | -4. Inject context for `read` results or next provider context. |
37 | | -5. Add `/context-tree status`, `/context-tree explain <path>`, `/context-tree validate`. |
| 47 | +- `context[]` is the primary routing array. |
| 48 | +- `match[]` uses glob patterns, with `!` for exclusions. |
| 49 | +- `operations[]` is required and may contain `"*"`. |
| 50 | +- `inject[]` accepts shorthand strings or typed objects. |
| 51 | +- Paths are resolved relative to the owning `CONTEXT.json`. |
| 52 | +- URLs are cached under `.pi/context-tree/cache/urls`. |
| 53 | +- File extraction supports markdown sections, line ranges, markers, and annotated segments. |
38 | 54 |
|
39 | | -## Future runtime features |
| 55 | +## Operations |
40 | 56 |
|
41 | | -- Section extraction from markdown references. |
42 | | -- Runtime hints for model and thinking level. |
43 | | -- Tool policy suggestions and later enforcement. |
44 | | -- Skill file inclusion by scope. |
45 | | -- UI status showing active scope and loaded context. |
| 57 | +Supported operations: |
| 58 | + |
| 59 | +```text |
| 60 | +* |
| 61 | +agent_start |
| 62 | +read |
| 63 | +edit |
| 64 | +write |
| 65 | +grep |
| 66 | +find |
| 67 | +ls |
| 68 | +bash |
| 69 | +session_spawn |
| 70 | +subagent_spawn |
| 71 | +``` |
| 72 | + |
| 73 | +Behavior implemented: |
| 74 | + |
| 75 | +- `agent_start`: injects bundles when prompt references paths such as `@src/index.ts`. |
| 76 | +- `read`: appends context bundle to read tool results. |
| 77 | +- `edit` / `write`: preflight injects context once, blocks initial mutation, then allows retry. |
| 78 | +- `session_spawn`: used by `/context-tree new <path> [prompt]`. |
| 79 | +- `subagent_spawn`: schema/config concept; runner interop still planned. |
| 80 | + |
| 81 | +## Design principles |
| 82 | + |
| 83 | +- Keep routing machine-readable and validated. |
| 84 | +- Keep context minimal and path-scoped. |
| 85 | +- Prefer canonical sources over duplicated rules. |
| 86 | +- Do not inject `AGENTS.md` from `CONTEXT.json`; Pi already loads it. |
| 87 | +- Do not inject README on every read/edit; keep broad orientation for startup/session only. |
| 88 | +- Avoid self-read duplication: when reading a file, do not inject that same file as context. |
| 89 | +- Default to explainable behavior before automation-heavy behavior. |
| 90 | +- Core resolver logic must remain testable without Pi. |
46 | 91 |
|
47 | 92 | ## Repository conventions |
48 | 93 |
|
49 | 94 | - Source lives in `src/`. |
| 95 | +- Tests live in `test/` and use Node's built-in test runner with `tsx`. |
| 96 | +- Generated JSON schema lives in `schemas/context.schema.json`. |
50 | 97 | - Pi package manifest lives in `package.json` under `pi.extensions`. |
51 | 98 | - Use TypeScript strict mode. |
52 | 99 | - Use Pi extension APIs from `@mariozechner/pi-coding-agent`. |
53 | | -- Use CLI commands for tool-owned files when available, e.g. `pnpm init`, `pnpm add`, `tsc --init`, `pi install`. |
54 | | -- Prefer self-dev via local Pi package install: `pnpm pi:install:local`, then run `pnpm pi:local` and use `/reload` after source changes. |
| 100 | +- Prefer self-dev via local Pi package install: `pnpm pi:install:local`, then `pnpm pi:local` and `/reload` after source changes. |
55 | 101 | - Use `pnpm pi:dev` (`pi -e .`) only for quick one-off runs. |
56 | | -- Before edits, understand Pi docs in `docs/extensions.md` and package docs when packaging changes. |
57 | 102 |
|
58 | | -## Context contract draft |
| 103 | +## Commands |
59 | 104 |
|
60 | | -Example scope file: |
| 105 | +Implemented commands: |
61 | 106 |
|
62 | | -```json |
63 | | -{ |
64 | | - "version": 1, |
65 | | - "scope": "src/features/billing", |
66 | | - "applies": ["**/*.ts", "**/*.tsx"], |
67 | | - "priority": 40, |
68 | | - "context": { |
69 | | - "mode": "once_per_turn", |
70 | | - "maxTokens": 4000, |
71 | | - "include": [ |
72 | | - { |
73 | | - "path": "./CONTEXT.md", |
74 | | - "kind": "summary", |
75 | | - "required": true |
76 | | - }, |
77 | | - { |
78 | | - "path": "./references/domain-rules.md", |
79 | | - "kind": "reference", |
80 | | - "sections": ["Billing invariants"], |
81 | | - "required": true |
82 | | - }, |
83 | | - { |
84 | | - "path": "./billing.types.ts", |
85 | | - "kind": "code", |
86 | | - "reason": "Canonical billing domain types", |
87 | | - "required": true |
88 | | - } |
89 | | - ] |
90 | | - }, |
91 | | - "runtime": { |
92 | | - "model": { |
93 | | - "provider": "anthropic", |
94 | | - "id": "claude-sonnet-4-5", |
95 | | - "policy": "suggest" |
96 | | - }, |
97 | | - "thinking": "medium", |
98 | | - "tools": { |
99 | | - "policy": "suggest", |
100 | | - "enable": ["read", "grep", "edit"], |
101 | | - "disable": ["bash"] |
102 | | - } |
103 | | - } |
104 | | -} |
| 107 | +```text |
| 108 | +/context-tree help |
| 109 | +/context-tree status |
| 110 | +/context-tree reload |
| 111 | +/context-tree validate [path] |
| 112 | +/context-tree explain <path> [operation] |
| 113 | +/context-tree fetch <path> |
| 114 | +/context-tree cache list |
| 115 | +/context-tree cache refresh <path> |
| 116 | +/context-tree tui on|off|compact|verbose |
| 117 | +/context-tree new <path> [prompt] |
| 118 | +``` |
| 119 | + |
| 120 | +Planned command: |
| 121 | + |
| 122 | +```text |
| 123 | +/context-tree subagent <path> <task> |
| 124 | +``` |
| 125 | + |
| 126 | +## TUI |
| 127 | + |
| 128 | +Context Tree uses Pi TUI APIs: |
| 129 | + |
| 130 | +- `ctx.ui.setStatus()` for footer status; |
| 131 | +- `ctx.ui.setWidget()` for a structured widget. |
| 132 | + |
| 133 | +Widget shows: |
| 134 | + |
| 135 | +- valid/invalid `CONTEXT.json` count; |
| 136 | +- last target; |
| 137 | +- operation; |
| 138 | +- source count; |
| 139 | +- context count; |
| 140 | +- bundle hash; |
| 141 | +- warning count; |
| 142 | +- source list in verbose mode. |
| 143 | + |
| 144 | +Modes: |
| 145 | + |
| 146 | +```text |
| 147 | +/context-tree tui compact |
| 148 | +/context-tree tui verbose |
| 149 | +/context-tree tui off |
| 150 | +/context-tree tui on |
| 151 | +``` |
| 152 | + |
| 153 | +## Self-context layout |
| 154 | + |
| 155 | +This repo uses its own extension config: |
| 156 | + |
| 157 | +- `CONTEXT.json`: startup README and config-file schema/implementation context. |
| 158 | +- `src/CONTEXT.json`: Pi docs for extension entrypoint; implementation-plan sections for resolver/schema/core files. |
| 159 | +- `scripts/CONTEXT.json`: schema source for schema generation scripts. |
| 160 | +- `test/CONTEXT.json`: test strategy section for test files. |
| 161 | + |
| 162 | +## Validation |
| 163 | + |
| 164 | +Before considering work complete, run: |
| 165 | + |
| 166 | +```bash |
| 167 | +pnpm validate |
105 | 168 | ``` |
| 169 | + |
| 170 | +This runs: |
| 171 | + |
| 172 | +```text |
| 173 | +pnpm typecheck |
| 174 | +pnpm schema:generate |
| 175 | +pnpm test |
| 176 | +``` |
| 177 | + |
| 178 | +## Future work |
| 179 | + |
| 180 | +- Richer custom TUI component instead of line widget. |
| 181 | +- Real `pi-subagents` interop for `subagent_spawn`. |
| 182 | +- Real `pi-guardrails` interop for permission policy sharing. |
| 183 | +- Agentic config maintenance commands with history/rollback. |
| 184 | +- More detailed `/context-tree explain` output showing final/skipped/deduped bundle sources. |
0 commit comments