--- name: pi-map description: Generates and maintains hierarchical paired project-analysis artifacts (`.pi-map.index.md` + `.pi-map.md`) so Pi agents can navigate and orient in a codebase without reading every source file. --- # pi-project-map A Pi skill that creates and maintains one paired analysis artifact set per non-ignored directory: - `.pi-map.index.md` — routing-first index - `.pi-map.md` — orientation-first rich map ## What it does - scans the project and emits one paired map/index set per directory - extracts per-file purpose, dependencies, and concepts via an LLM - extracts exact exports/imports via AST parsing where supported - patches artifacts incrementally after source edits - validates stale, missing, broken, or inconsistent paired artifacts - retrieves relevant context on demand via deterministic metadata scoring - injects lightweight project-map guidance into agent context according to a configurable mode ladder ## Operating model ### Tier 0 — protocol Always read the root `.pi-map.index.md` and the `Project Map Protocol` first. ### Tier 1 — routing Use indexes first to decide where to go next. Open the strongest-match `.pi-map.md` files for orientation. ### Tier 2 — source Read actual source, tests, config, and docs before editing or asserting exact runtime behavior. **Trust boundary:** > **index routes, map orients, source decides** ## Agent instructions When project-map artifacts exist in the repo: 1. start with the root `.pi-map.index.md` and the `Project Map Protocol` 2. use indexes first to route into the right directory 3. read the local `.pi-map.md` plus relevant source before editing 4. run `project_map_patch ` (tool) or `project-map patch ` (CLI) after each source edit 5. run `project_map_validate` (tool) or `project-map validate` (CLI) before freshness-sensitive architectural decisions or final handoff 6. if validation shows localized discrepancies, run `project_map_validate` with `fix=true` (tool) or `project-map validate --fix` (CLI) 7. only if discrepancies are widespread or structural, run `project_map_reinit` (tool) or `project-map reinit` (CLI) 8. for targeted exploration, use `project_map_context ` (tool) or `project-map context ` (CLI) 9. in `strict` mode, only bypass the protocol-path guard with an explicit marker: `[PI_MAP_BYPASS: ]` ## Prompt injection modes The Pi extension can inject project-map guidance automatically. Behavior is controlled by `promptInjectionMode` in `.pi-project-map.json`. ### Before init If no `.pi-map.md` / `.pi-map.index.md` artifacts exist, the extension emits a lightweight visible hint to run `project_map_init`. No synthetic or fake map content is injected. ### After init Once real artifacts exist, the runtime guarantees that the **root pair** is loaded first: - root `.pi-map.index.md` - root `.pi-map.md` Additional directory pairs may be expanded while the configured context budget allows, in shallow-first order. ### Mode ladder | Mode | Behavior | |------|----------| | `off` | No automatic injection. Use tools/CLI manually. | | `advisory` | Startup/init hints are shown. Root pair is not auto-loaded; read it manually when needed. | | `strong` (default) | Root pair is auto-loaded, expansion stays within budget, and reinjection runs on relevant turns. | | `strict` | Same as `strong`, but sensitive edits or architectural claims are guarded unless the protocol path is present or a bypass marker is provided. | The **protocol path** means the outgoing context contains the canonical injected root-pair block and the trust-boundary text. ### Context budget Default budget: **15% of the active model context window**, capped at **100k tokens**. The smaller of the relative and absolute values wins. If the runtime cannot discover the context window, it uses the absolute cap. ## Retrieval usage `project_map_context` (tool) and `project-map context` (CLI) are **on-demand retrieval**, separate from automatic injection. They do not call the LLM. They score paired metadata against the query and return a compact markdown bundle with: - relevant indexes - relevant maps - likely files - relevant symbols when useful Always read the suggested indexes first, then maps, then verify critical behavior from source. ## Configuration Create `.pi-project-map.json` in the project root: ```json { "promptInjectionMode": "strong", "contextBudgetPercent": 15, "contextBudgetMaxTokens": 100000, "tagCap": 8, "workflowHintCap": 5, "llmProvider": "openai", "llmModel": "gpt-4o-mini", "reinitFullThresholdPercent": 10, "ignorePatterns": ["node_modules", ".git", "dist", "build"] } ``` Providing `ignorePatterns` replaces the built-in default list, so include any defaults you want to keep. - `reinitFullThresholdPercent` — when `project_map_reinit` targets a subtree that covers more than this percentage of project files, it falls back to full regeneration Knobs that matter in practice: - `promptInjectionMode` — `off` | `advisory` | `strong` | `strict` - `contextBudgetPercent` / `contextBudgetMaxTokens` — caps automatic map/index injection - `tagCap` / `workflowHintCap` — caps routing metadata per directory - `llmProvider` / `llmModel` / `llmBaseUrl` — standalone CLI only - `ignorePatterns` — discovery exclusions ## Tools and commands | Tool (Pi) | CLI command | Purpose | |-----------|-------------|---------| | `project_map_init` | `project-map init [path]` | Generate all paired artifacts. | | `project_map_patch` | `project-map patch ` | Regenerate the pair for the changed file's directory and refresh ancestors. | | `project_map_validate` | `project-map validate [--fix]` | Check paired artifacts for staleness and discrepancies; optionally repair. | | `project_map_reinit` | `project-map reinit [path]` | Smart regeneration: recomputes the target subtree plus ancestors, and only falls back to full regeneration when the subtree covers more than `reinitFullThresholdPercent` of project files (default 10%). | | `project_map_context` | `project-map context ` | Retrieve a ranked context bundle for a natural-language query. |