@pipemd-core/pipemd 1.0.0 β†’ 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,535 +1,319 @@
1
1
  <p align="center">
2
- <picture>
3
- <img src="PipeMD.jpg" alt="PipeMD Banner" width="100%" style="border-radius: 8px; max-width: 800px;" />
4
- </picture>
2
+ <img src="PipeMD.jpg" alt="PipeMD" width="100%" style="border-radius: 8px; max-width: 800px;" />
5
3
  </p>
6
4
 
7
5
  <h1 align="center">PipeMD</h1>
8
6
 
9
7
  <p align="center">
10
- <strong>The Dynamic Context Harness for AI Coding Agents.</strong><br>
11
- <em>Never let Claude, Cursor, or Aider hallucinate on stale project state again.</em>
8
+ <strong>Real-time project context for AI coding agents.</strong><br>
9
+ Zero git churn. Always fresh. Works with any agent.
12
10
  </p>
13
11
 
14
12
  <p align="center">
15
- <a href="#the-magic-render-on-read"><img src="https://img.shields.io/badge/Architecture-Render--on--Read%20%2B%20Smart%20Injection-blue?style=flat-square" alt="Architecture"></a>
16
- <a href="#prompt-cache-optimization"><img src="https://img.shields.io/badge/Prompt%20Caching-Optimized-success?style=flat-square" alt="Prompt Cache Optimized"></a>
17
- <a href="#compatibility"><img src="https://img.shields.io/badge/Works%20With-Claude%20%7C%20Cursor%20%7C%20Aider%20%7C%20Gemini-orange?style=flat-square" alt="Works With"></a>
18
- <a href="https://opensource.org/licenses/ISC"><img src="https://img.shields.io/badge/License-ISC-purple?style=flat-square" alt="License"></a>
13
+ <a href="https://www.npmjs.com/package/@pipemd-core/pipemd"><img src="https://img.shields.io/npm/v/@pipemd-core/pipemd?style=flat-square" alt="npm"></a>
14
+ <a href="https://opensource.org/licenses/ISC"><img src="https://img.shields.io/badge/license-ISC-purple?style=flat-square" alt="License"></a>
15
+ <img src="https://img.shields.io/badge/node-%3E%3D18-339933?style=flat-square" alt="Node">
16
+ <img src="https://img.shields.io/badge/works_with-Claude%20%7C%20Gemini%20%7C%20OpenCode%20%7C%20Cursor%20%7C%20Aider-orange?style=flat-square" alt="Compatibility">
19
17
  </p>
20
18
 
21
19
  ---
22
20
 
23
- ## πŸ›‘ The Problem: Stale Context & Git Churn
24
-
25
- AI coding agents need to know your current project state (git status, lint errors, TODOs) to be effective.
26
- Currently, you have two bad options:
27
- 1. **Static Files:** You give the AI a `README.md` or `CONTEXT.md`. It goes stale after your first commit. The AI hallucinates.
28
- 2. **Automated Scripts:** You run a script to update `CONTEXT.md` continuously. Your `git status` is ruined, merge conflicts run rampant, and your file history is a mess.
29
-
30
- ## ⚑ The Solution: PipeMD
31
-
32
- PipeMD uses a brilliantly simple OS-level trick: **Named Pipes**.
33
-
34
- It creates an `AGENTS.md` file in your root directory that is actually a `mkfifo` pipe. When your AI agent attempts to read it, PipeMD intercepts the read, executes your bash scripts concurrently, injects real-time project state into a clean template, and streams it straight to the AI.
35
-
36
- * **Zero Git Churn:** The template is clean. The live output is completely ephemeral.
37
- * **Always Fresh:** The AI gets up-to-the-millisecond data *only* exactly when it reads.
38
- * **Secure:** Commands run from your own `config.yml` β€” no need to grant the AI unsafe terminal execution permissions.
39
-
40
- But named pipes only solve half the problem: most AI agents read their context file only once at session start, then cache it. PipeMD's **Smart Context Injection** solves this by installing lightweight hooks that inject fresh, scoped context directly into the agent's working memory on every tool call β€” crew locks before edits, file errors before edits, validation results after edits, and status updates during idle time.
41
-
42
- PipeMD is a render-on-read daemon that uses OS-level named pipes (mkfifo) to serve real-time project context to
43
- AI coding agents. The key innovation: the file the AI reads (AGENTS.md or AI_CONTEXT.md) is itself a named pipe --
44
- when the AI opens it, the daemon intercepts the read, executes all configured shell commands concurrently,
45
- assembles the output into a Markdown template, prepends any base instructions (from `.pipemd/base.md`), and streams it back.
46
-
47
- Data flow:
48
-
49
- The Full Data Flow
50
- Agent tool call
51
- β†’ Harness hook fires (Claude: settings.json entry, OpenCode: plugin handler, Gemini: settings.json entry)
52
- β†’ `pmd inject --trigger <X> --file <Y> --session <Z> --format <F>`
53
- β†’ `resolveInjections()` in injection-engine.ts
54
- β†’ Loads injection.yml config
55
- β†’ Gets rules for trigger
56
- β†’ For each rule, runs the resolver (crew-status, file-errors, git-context, etc.)
57
- β†’ `checkInjectionStatus()` in dedup.ts -- checks `.pipemd/cache/injected/<session>.json`
58
- β†’ If "unchanged": skip (no payload returned)
59
- β†’ If "new"/"changed": `recordInjection()` -- writes hash to `.pipemd/cache/injected/<session>.json`
60
- β†’ Returns `InjectionPayload[]`
61
- β†’ `bumpInjectStats()` in statusline-data.ts -- writes `.pipemd/.inject-stats.json`
62
- β†’ Output in requested format (plain, claude-hook JSON, gemini JSON)
63
- β†’ OpenCode only (plugin side):
64
- β†’ Also calls `pushEvent()` which writes `.pipemd/.tui-stats.json`
65
- β†’ TUI panel reads `.pipemd/.tui-stats.json` every 2s
66
- β†’ `pmd statusline` (called by Claude Code automatically, or Gemini AfterAgent):
67
- β†’ Reads `.pipemd/.inject-stats.json`, `.pipemd/.status.json`, `.pipemd/.crew-status.json`
68
- β†’ Renders status line to developer
69
-
70
- .pipemd/base.md (committed, agent's own instructions)
71
- ─────────────────────────────────────────────────────┐
72
- β”‚
73
- .pipemd/template.md (committed, static) β”‚
74
- β†’ daemon reads tags like <!-- pmd: git-status --> β”‚
75
- β†’ runs commands concurrently via Promise.allSettled β”‚
76
- β†’ assembles rendered Markdown β”‚
77
- β†’ composes: base + "---\n\n<!-- pmd-context -->\n" + rendered template
78
- β†’ serves via named pipe (AGENTS.md) on read β”‚
21
+ ## TL;DR
79
22
 
80
- Two operational modes:
23
+ AI coding agents need to know your project state β€” git status, lint errors, TODOs, who else is editing. Static context files go stale. Auto-updated files pollute your git history.
81
24
 
82
- 1. Pipe Mode (macOS, Linux, WSL): Uses mkfifo to create named pipes. The root context file IS the pipe. Zero git
83
- churn. Supports bidirectional write-back β€” edits above `<!-- pmd-context -->` are saved to `base.md`,
84
- edits outside `<!-- pmd: -->` blocks in the template section are de-rendered and saved back to `template.md`.
25
+ **PipeMD makes `AGENTS.md` a named pipe.** When your AI reads it, PipeMD intercepts the read, runs your scripts concurrently, and streams live context straight to the agent. Zero files change on disk. The output is completely ephemeral.
85
26
 
86
- 2. Legacy Mode (native Windows fallback): Uses chokidar to watch template.md, writes rendered output to a regular
87
- file marked read-only (0o444). This causes git churn. Also supports write-back via file watcher.
27
+ ---
88
28
 
29
+ ## Quick Start
89
30
 
90
- ---
31
+ ```bash
32
+ npm install -g @pipemd-core/pipemd
33
+ pmd init # Interactive setup β€” detects your ecosystem and harness
34
+ pmd start # Spawns the daemon β€” your AI now gets live context
35
+ ```
36
+
37
+ Or run without installing:
91
38
 
92
- ## ✨ Features: Built for Vibe Coding
39
+ ```bash
40
+ npx @pipemd-core/pipemd init
41
+ npx @pipemd-core/pipemd start
42
+ ```
93
43
 
94
- - **πŸ”Œ Universal AI Compatibility:** Claude Code, Gemini CLI, OpenCode, Cursor, Aiderβ€”it doesn't matter. If your AI agent can read a Markdown file, it works flawlessly with PipeMD. No plugins required.
95
- - **πŸ—οΈ Architecture Maps:** PipeMD generates live Mermaid dependency graphs (`graph TD`) for 7 ecosystems. AI agents get an instant mental model of your project's module structure β€” no need to read dozens of files to understand how things connect.
96
- - **🦾 Self-Improving Context:** Because your fetch scripts and templates live as plain text in `.pipemd/`, you can simply ask your AI to *edit its own context harness* to feed itself better data on the fly. Meta-coding at its finest.
97
- - **πŸ›‘οΈ Non-Destructive Setup:** Worried about losing your carefully crafted system prompts? `pmd init` is completely non-destructive. If an `AGENTS.md` or `AI_CONTEXT.md` already exists, PipeMD saves your instructions to `.pipemd/base.md` and keeps them separate from the template. Nothing gets overwritten.
98
- - **πŸ‘» Ephemeral & Git-Clean:** Output is generated in memory and streamed via the named pipe. The target file is automatically `.gitignored` and vanishes the second you stop the daemon. Zero commit noise.
99
- - **🧠 Prompt Cache Optimized:** Static rules stay at the top; highly volatile data (like `git status`) is anchored to the bottom. Your LLM prefix cache stays warm, giving you instant responses and saving massive amounts of tokens.
100
- - **🏎️ Concurrent & Fail-Safe:** Data-gathering scripts run concurrently so your AI isn't left waiting. Built-in 10-second timeouts and isolated failures mean one broken script won't crash your entire context stream.
101
- - **πŸ€– Smart Scaffolding:** Run `pmd init` and watch it automatically detect your ecosystem (Node, Python, TS, etc.) to scaffold the exact bash scripts you need to hit flow state immediately.
102
- - **🎯 Smart Context Injection:** Goes beyond render-on-read. Hooks inject fresh, scoped context into your agent's working memory on every tool call β€” crew locks, file errors, validation results β€” so the agent always knows the current state even mid-session.
44
+ > **Bash required.** Windows users: use WSL or Git Bash.
103
45
 
104
46
  ---
105
47
 
106
- ## πŸš€ Quick Start
48
+ ## What Your AI Sees
107
49
 
108
- Get your dynamic context harness running in under 60 seconds:
50
+ When your agent reads `AGENTS.md`, it gets a live-rendered Markdown document β€” not a static file. Here's what that looks like:
109
51
 
110
- ```bash
111
- # Option 1: Global Install
112
- npm install -g pipemd
113
- pmd init
114
- pmd start
115
-
116
- # Option 2: Run via NPX (No global install required)
117
- npx pipemd init
118
- npx pipemd start
119
- ```
52
+ ```markdown
53
+ # AI Context β€” powered by PipeMD
120
54
 
121
- > **Bash Required:** PipeMD's context scripts rely on a Bash environment. Windows users must use WSL or Git Bash.
55
+ > This file refreshes automatically. Content inside `<!-- pmd: -->` blocks
56
+ > is read-only β€” everything else is yours to edit.
122
57
 
123
- *The setup wizard will auto-detect your ecosystem and configure the optimal `.pipemd/template.md` and context scripts for your workspace.*
58
+ ## Architecture
59
+ <!-- pmd: arch -->
60
+ graph TD
61
+ src/index --> chalk
62
+ src/index --> commander
63
+ <!-- /pmd -->
124
64
 
125
- *The setup wizard will also ask how to deliver context β€” **Active** (recommended for most agents) or **Passive** (for Cursor, Aider, or CI).*
65
+ ## Project Structure
66
+ <!-- pmd: tree -->
67
+ .
68
+ β”œβ”€β”€ src/
69
+ β”‚ β”œβ”€β”€ commands/
70
+ β”‚ β”œβ”€β”€ core/
71
+ β”‚ └── index.ts
72
+ β”œβ”€β”€ tests/
73
+ └── package.json
74
+ <!-- /pmd -->
126
75
 
127
- ---
76
+ ## Git Status
77
+ <!-- pmd: git-status -->
78
+ ## main...origin/main
79
+ M src/index.ts
80
+ ?? CONTRIBUTING.md
81
+ <!-- /pmd -->
128
82
 
129
- ## 🧠 How the Magic Works
130
-
131
- PipeMD bridges the gap between your static developer notes and the dynamic reality of your repository.
132
-
133
- ```text
134
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
135
- β”‚ 1. You edit: .pipemd/template.md β”‚
136
- β”‚ (Clean, committed to Git, your source of truth) β”‚
137
- β”‚ β”‚
138
- β”‚ ## Rules β”‚
139
- β”‚ Never use `any` in TypeScript. β”‚
140
- β”‚ β”‚
141
- β”‚ ## Live Diff β”‚
142
- β”‚ <!-- pmd: diff --> <── PipeMD placeholder β”‚
143
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
144
- β”‚
145
- (Agent reads AGENTS.md from root)
146
- β”‚
147
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
148
- β”‚ 2. PipeMD Daemon (Intercepts read) β”‚
149
- β”‚ Prepends base.md + separator, renders template... β”‚
150
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
151
- β”‚
152
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
153
- β”‚ 3. The AI receives: (Streamed instantly) β”‚
154
- β”‚ β”‚
155
- β”‚ [Base instructions from .pipemd/base.md] β”‚
156
- β”‚ β”‚
157
- β”‚ --- β”‚
158
- β”‚ β”‚
159
- β”‚ <!-- pmd-context --> β”‚
160
- β”‚ β”‚
161
- β”‚ ## Rules β”‚
162
- β”‚ Never use `any` in TypeScript. β”‚
163
- β”‚ β”‚
164
- β”‚ ## Live Diff β”‚
165
- β”‚ + const daemon = new PipeMD(); β”‚
166
- β”‚ - const daemon = null; β”‚
167
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
83
+ ## Type Errors
84
+ <!-- pmd: type-check -->
85
+ No type errors
86
+ <!-- /pmd -->
168
87
  ```
169
88
 
170
- > **Note for Windows Users:** Native Windows lacks `mkfifo`. PipeMD falls back to **Legacy Mode**, gracefully watching your template and writing read-only (`0o444`) updates.
89
+ Every block is live. The AI reads up-to-the-millisecond data β€” no stale context, no hallucinations.
171
90
 
172
91
  ---
173
92
 
174
- ## 🧠 Smart Context Injection
175
-
176
- Most AI coding agents load their context file once at session start and never re-read it. This means even with named pipes serving fresh data, the agent works with stale information for the entire session.
177
-
178
- PipeMD's Smart Context Injection solves this by installing per-harness hooks that inject relevant context **on every tool call**, scoped to what the agent is about to do:
93
+ ## How It Works
179
94
 
180
- ```text
181
- Agent is about to READ a file:
182
- β†’ Hook fires β†’ "Crew: this file is unclaimed. Safe to read."
95
+ ```
96
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
97
+ β”‚ .pipemd/template.md β”‚
98
+ β”‚ Your committed template with pmd: tags β”‚
99
+ β”‚ β”‚
100
+ β”‚ ## Live Diff β”‚
101
+ β”‚ <!-- pmd: diff-stat --> ← placeholder β”‚
102
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
103
+ β”‚
104
+ AI agent reads AGENTS.md from root
105
+ β”‚
106
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
107
+ β”‚ PipeMD Daemon intercepts the read β”‚
108
+ β”‚ 1. Reads template.md β”‚
109
+ β”‚ 2. Runs all scripts concurrently β”‚
110
+ β”‚ 3. Injects results into pmd: blocks β”‚
111
+ β”‚ 4. Prepends base.md (your custom rules) β”‚
112
+ β”‚ 5. Streams the result to the agent β”‚
113
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
114
+ β”‚
115
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
116
+ β”‚ The AI receives a complete, live document β”‚
117
+ β”‚ No file written to disk. Zero git churn. β”‚
118
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
119
+ ```
183
120
 
184
- Agent is about to EDIT src/foo.ts:
185
- β†’ Hook fires β†’ "File src/foo.ts: claimed by OpenCode (cr_abc123) 45s ago
186
- Type-check: 2 errors in this file
187
- Last edit: you, 2 minutes ago"
121
+ Two operational modes:
188
122
 
189
- Agent just EDITED src/foo.ts:
190
- β†’ Background validation triggers β†’ next tool call shows:
191
- "After your edit to src/foo.ts: 1 error remaining (was 2)"
123
+ | Mode | Platform | Mechanism |
124
+ |------|----------|-----------|
125
+ | **Pipe Mode** | macOS, Linux, WSL | `mkfifo` named pipes β€” zero disk writes |
126
+ | **Legacy Mode** | Native Windows | File watcher + read-only output |
192
127
 
193
- Agent has been idle for 10 seconds:
194
- β†’ "Crew: Gemini session joined. Git: 1 new uncommitted file."
195
- ```
128
+ ---
196
129
 
197
- ### Three Delivery Modes
130
+ ## Delivery Modes
198
131
 
199
- During `pmd init`, choose how PipeMD delivers context to your agent:
132
+ PipeMD can deliver context two ways: passively (the AI reads the pipe at session start) or actively (hooks inject scoped context on every tool call).
200
133
 
201
134
  | Mode | How it works | Best for |
202
135
  |------|-------------|----------|
203
- | **Active** (recommended) | Hooks installed. Fresh context injected on every tool call. Zero config. | Claude Code, OpenCode, Gemini CLI |
204
- | **Passive** | Context rendered to file/pipe. Agent reads at session start. No hooks. | Cursor, Aider, CI/CD |
136
+ | **Passive** | Context rendered to pipe/file. Agent reads at session start. | Cursor, Aider, CI/CD |
137
+ | **Active** | Hooks inject fresh context on every tool call. Zero config. | Claude Code, OpenCode, Gemini CLI |
205
138
  | **Expert** | Full control over injection rules via `.pipemd/injection.yml`. | Teams with custom workflows |
206
139
 
207
- ### What gets injected
208
-
209
140
  Active mode injects context at four moments:
210
141
 
211
- | Trigger | Sources |
212
- |---------|---------|
213
- | **Before Read** | Crew status (who's working, any conflicts) |
214
- | **Before Edit** | Crew locks for target file, lint/type errors for target file, git context |
215
- | **After Edit** | Async validation: run lint + type-check on edited file, deliver results on next call |
216
- | **On Idle** | Crew status changes, git delta since last check |
217
-
218
- All injection is **deduplicated** β€” unchanged data is skipped, saving tokens. Results are cached with per-source TTL for sub-5ms hook latency.
219
-
220
- ### The injection.yml file (Expert mode)
142
+ | Trigger | What the AI gets |
143
+ |---------|-----------------|
144
+ | Before Read | Crew status β€” who's working, any conflicts |
145
+ | Before Edit | File-specific: crew locks, lint/type errors, git context |
146
+ | After Edit | Async validation results (lint + type-check on edited file) |
147
+ | On Idle | Crew changes, git delta since last check |
221
148
 
222
- ```yaml
223
- # .pipemd/injection.yml β€” customize injection rules
224
- delivery: expert
225
- rules:
226
- before-edit:
227
- - source: crew-locks
228
- scope: target-file
229
- - source: file-errors
230
- scope: target-file
231
- max-lines: 5
232
- after-edit:
233
- - source: validate-file
234
- scope: target-file
235
- async: true
236
- ```
149
+ All injection is deduplicated β€” unchanged data is skipped, saving tokens.
237
150
 
238
151
  ---
239
152
 
240
- ## πŸ› οΈ Commands
153
+ ## Features
241
154
 
242
- PipeMD is designed to stay out of your way.
243
-
244
- | Command | Description |
245
- |---------|-------------|
246
- | `pmd init` | **Interactive setup:** Auto-detects ecosystem + harnesses, scaffolds the template, scripts, and `.gitignore` entries. `--headless` for CI. |
247
- | `pmd start` | **Spawns daemon:** Creates the named pipe(s) and silently serves context on read. Daemon detaches and stores its PID in `.pipemd/.daemon.pid`. |
248
- | `pmd stop` | **Kills daemon:** Safely removes all pipes and cleans up the PID file. |
249
- | `pmd restart` | **Stop + start:** Reloads `config.yml` (use after editing config). |
250
- | `pmd status` | **System health:** Shows active daemon PID, watched files, active pipes, and recent log lines. |
251
- | `pmd run` | **One-shot render:** Renders the resolved template to `stdout` or a file (`-o`). No daemon required β€” ideal for CI and pre-commit hooks. |
252
- | `pmd refresh` | **Sync scripts:** Pulls newer bundled scripts into `.pipemd/scripts/`, offers newly added ones (e.g. **Crew Activity**), and rewrites `config.yml`. |
253
- | `pmd doctor` | **Diagnose:** Checks for `mkfifo`, stale PIDs, missing scripts, and config drift. |
254
- | `pmd crew` | **Multi-harness coordination:** Register agents, claim files, surface conflicts (see below). |
255
- | `pmd uninstall` | **Clean removal:** Restores the original context file and strips PipeMD artifacts. |
155
+ - **Universal compatibility** β€” Claude Code, Gemini CLI, OpenCode, Cursor, Aider. If it can read Markdown, it works.
156
+ - **Architecture maps** β€” Live Mermaid dependency graphs for 7 ecosystems. The AI gets an instant mental model of your project.
157
+ - **Smart Context Injection** β€” Hooks deliver scoped, file-specific context on every tool call, not just at session start.
158
+ - **Crew coordination** β€” Multiple agents working the same repo see each other's file claims and get conflict warnings in real time.
159
+ - **Bidirectional write-back** β€” AI edits outside `<!-- pmd: -->` blocks persist to disk. The agent can tune its own context.
160
+ - **Prompt cache optimized** β€” Static rules at the top, volatile data at the bottom. Your LLM prefix cache stays warm.
161
+ - **Non-destructive setup** β€” Existing `AGENTS.md` content is preserved to `.pipemd/base.md`. Nothing gets overwritten.
162
+ - **Self-improving** β€” Scripts and templates are plain text in `.pipemd/`. Ask your AI to edit its own context harness.
256
163
 
257
164
  ---
258
165
 
259
- ## πŸ‘₯ Crew: Coordinating Parallel Agents
260
-
261
- When several AI harnesses work the same repo at once (e.g. OpenCode with 8
262
- sub-agents plus a Claude CLI session), they edit blind to each other. PipeMD
263
- Crew turns the live context file into a shared awareness layer.
264
-
265
- The model is **Harness β†’ Coordinator β†’ sub-agents**: one coordinator per
266
- harness, with PipeMD as the neutral meta-coordinator that renders the union.
166
+ ## Commands
267
167
 
268
168
  | Command | Description |
269
169
  |---------|-------------|
270
- | `pmd crew join` | Register this agent (`--role coordinator\|worker`, `--label`). |
271
- | `pmd crew claim <file…>` | Mark files as being worked on (`--note "<task>"`). |
272
- | `pmd crew release <file…>` | Release claims (`--all` for everything). |
273
- | `pmd crew note "<text>"` | Post the current task/status. |
274
- | `pmd crew status` | Show the live crew tree. |
275
- | `pmd crew leave` | Deregister this agent. |
276
- | `pmd crew install-hooks` | Auto-wire harness hooks so edits self-report. |
277
-
278
- **Two signal layers.** *Passive* (always on, zero cooperation): observed git
279
- churn and running harness processes. *Active* (opt-in): the `pmd crew` CLI,
280
- fired automatically by `pmd crew install-hooks`:
281
-
282
- | Harness | Events | Wired into |
283
- |---------|---------|------------|
284
- | Claude Code | `SessionStart` β†’ join, `PreToolUse` β†’ heartbeat, `PostToolUse` β†’ claim, `SubagentStart/Stop` β†’ worker lifecycle, `SessionEnd` β†’ leave, `statusLine` β†’ live PipeMD statusline | `.claude/settings.json` |
285
- | OpenCode | `tool.execute.before` β†’ heartbeat, `tool.execute.after` β†’ claim, `session.idle` β†’ keep-alive | `.opencode/plugin/pmd-crew.js` |
286
- | Gemini CLI | `BeforeTool` β†’ heartbeat, `AfterTool` β†’ claim, `SessionStart`/`AfterAgent` β†’ live PipeMD statusline via hook `systemMessage` (v0.26+) | `.gemini/settings.json` |
287
- | Cursor / Aider / others | no edit-event API | injected Coordination Protocol text |
288
-
289
- The crew block (`<!-- pmd: crew -->`) is rendered into every harness's context
290
- file, so a `⚠️ CONFLICT` β€” two agents claiming the same file β€” appears for
291
- everyone within one broadcast cycle. Add it via `pmd refresh` (select **Crew
292
- Activity**) or pick it during `pmd init`.
293
-
294
- **Claude Code statusline.** OpenCode gets a live TUI sidebar panel; Claude Code
295
- has no pluggable panel, so `install-hooks` instead registers a `statusLine` that
296
- renders the same dev-side state β€” daemon up/down, crew session count, passive
297
- agents, file conflicts, context size, injection counts β€” on a single line at the
298
- bottom of the Claude Code UI. It is invoked automatically by the harness on every
299
- update; a pre-existing custom `statusLine` is never overwritten. Preview it any
300
- time with `pmd statusline --plain`.
170
+ | `pmd init` | Interactive setup. Detects ecosystem + harnesses, scaffolds everything. Use `--headless` for CI. |
171
+ | `pmd start` | Spawn the daemon. Creates named pipes and serves context on read. |
172
+ | `pmd stop` | Kill the daemon. Removes pipes and cleans up. |
173
+ | `pmd restart` | Stop + start. Reloads config after edits. |
174
+ | `pmd status` | Daemon health: PID, active pipes, recent log lines. |
175
+ | `pmd run` | One-shot render to stdout or file (`-o`). No daemon needed β€” ideal for CI. |
176
+ | `pmd refresh` | Pull newer bundled scripts. Add newly available blocks without re-init. |
177
+ | `pmd doctor` | Diagnose: `mkfifo`, stale PIDs, missing scripts, config drift. |
178
+ | `pmd crew` | Multi-agent coordination: join, claim files, surface conflicts. See below. |
179
+ | `pmd uninstall` | Clean removal. Restores original context file. |
301
180
 
302
181
  ---
303
182
 
304
- ## πŸ—οΈ What Gets Generated?
183
+ ## What Gets Generated
305
184
 
306
- PipeMD keeps your root directory pristine. Everything lives in `.pipemd/`.
185
+ Everything lives in `.pipemd/`. Your root directory stays clean.
307
186
 
308
- ```text
187
+ ```
309
188
  your-project/
310
189
  β”œβ”€β”€ .pipemd/
311
- β”‚ β”œβ”€β”€ config.yml # βœ… Committed β€” pipe routing + script definitions
312
- β”‚ β”œβ”€β”€ base.md # βœ… Committed β€” agent's own instructions (prepended to context)
313
- β”‚ β”œβ”€β”€ template.md # βœ… Committed β€” πŸ“ edit this! The static wrapper for your context.
314
- β”‚ β”œβ”€β”€ scripts/ # βœ… Committed β€” Bash/Python/Node data-gathering scripts
315
- β”‚ β”‚ β”œβ”€β”€ architecture/ # πŸ—οΈ Architecture map (Mermaid graph TD)
316
- β”‚ β”‚ β”œβ”€β”€ project/ # Project structure, deps, todos
317
- β”‚ β”‚ β”œβ”€β”€ git/ # Git state scripts
190
+ β”‚ β”œβ”€β”€ config.yml # Committed β€” script definitions + pipe routing
191
+ β”‚ β”œβ”€β”€ base.md # Committed β€” your custom AI instructions
192
+ β”‚ β”œβ”€β”€ template.md # Committed β€” edit this! Tags + static content
193
+ β”‚ β”œβ”€β”€ injection.yml # Committed β€” injection rules (active/expert mode)
194
+ β”‚ β”œβ”€β”€ scripts/ # Committed β€” data-gathering scripts by category
195
+ β”‚ β”‚ β”œβ”€β”€ architecture/ # Mermaid dependency graphs
196
+ β”‚ β”‚ β”œβ”€β”€ project/ # Tree, deps, TODOs
197
+ β”‚ β”‚ β”œβ”€β”€ git/ # Git state
318
198
  β”‚ β”‚ β”œβ”€β”€ quality/ # Type checking, linting, tests
319
- β”‚ β”‚ └── crew/ # Crew coordination block
320
- β”‚ β”œβ”€β”€ injection.yml # βœ… Committed β€” Smart injection rules (active/expert mode)
321
- β”‚ β”œβ”€β”€ cache/ # (Gitignored) Per-source render cache for injection
322
- β”‚ β”‚ β”œβ”€β”€ sources/ # Cached command outputs with TTL
323
- β”‚ β”‚ β”œβ”€β”€ validation/ # Per-file validation results
324
- β”‚ β”‚ └── injected/ # Per-session dedup records
325
- β”‚ β”œβ”€β”€ live/ # (Gitignored) Ephemeral named pipes
326
- β”‚ β”œβ”€β”€ crew/ # (Gitignored) Per-agent coordination ledger (JSON)
327
- β”‚ β”œβ”€β”€ daemon.log # (Gitignored) Daemon activity log
328
- β”‚ └── .daemon.pid # (Gitignored) Running daemon's PID
329
- β”œβ”€β”€ AGENTS.md # (Gitignored) πŸ΄β€β˜ οΈ The Named Pipe. The AI reads this.
330
- └── .gitignore # Updated automatically by `pmd init`
199
+ β”‚ β”‚ └── crew/ # Crew coordination
200
+ β”‚ β”œβ”€β”€ cache/ # Gitignored β€” render cache for injection
201
+ β”‚ β”œβ”€β”€ live/ # Gitignored β€” ephemeral named pipes
202
+ β”‚ └── crew/ # Gitignored β€” per-agent coordination ledger
203
+ β”œβ”€β”€ AGENTS.md # Gitignored β€” the named pipe your AI reads
204
+ └── .gitignore # Updated automatically by pmd init
331
205
  ```
332
206
 
333
- > Only `config.yml`, `base.md`, `template.md`, and `scripts/` are committed β€”
334
- > everything your team needs to reproduce the harness, and nothing ephemeral.
207
+ Only `config.yml`, `base.md`, `template.md`, `injection.yml`, and `scripts/` are committed β€” everything your team needs, nothing ephemeral.
335
208
 
336
209
  ---
337
210
 
338
- ## 🎯 The Template (`.pipemd/template.md`)
211
+ ## Configuration
339
212
 
340
- This is your source of truth. Edit it, commit it, share it with your team. Use `<!-- pmd: command_name -->` to tell the daemon where to inject live data.
213
+ ### The Template (`.pipemd/template.md`)
341
214
 
342
- The served context file is composed of two parts: **base instructions** (from `.pipemd/base.md`) and the **rendered template**. They are separated by `---` + `<!-- pmd-context -->`. AI edits above the separator go back to `base.md`; edits in the template section outside `<!-- pmd: -->` blocks go back to `template.md`.
215
+ Your source of truth. Use `<!-- pmd: command_name -->` tags where you want live data injected.
343
216
 
344
217
  ```markdown
345
- # πŸ΄β€β˜ οΈ AI Context β€” powered by PipeMD
346
-
347
- > **πŸ€– PipeMD Context File**
348
- >
349
- > This file is maintained by PipeMD. It refreshes automatically.
350
- >
351
- > - Content inside `<!-- pmd: -->` blocks is **read-only** β€” the daemon overwrites it every cycle.
352
- > - Everything else is **yours to edit**. Edits persist via bidirectional write-back.
353
- > - Edits above `<!-- pmd-context -->` route to `.pipemd/base.md`. Edits below it route to `.pipemd/template.md`.
354
- > - For full details, read `.pipemd/AI_SETUP_PIPEMD.md`.
355
-
356
- ## πŸ—οΈ Architecture
357
- <!-- pmd: arch -->
358
- ```
218
+ # AI Context β€” powered by PipeMD
359
219
 
360
- ```
220
+ ## Architecture
221
+ <!-- pmd: arch -->
361
222
  <!-- /pmd -->
362
223
 
363
- ## πŸ“ Project Structure
224
+ ## Project Structure
364
225
  <!-- pmd: tree -->
365
226
  <!-- /pmd -->
366
227
 
367
- ## πŸ“ TODOs
368
- <!-- pmd: todos -->
369
- <!-- /pmd -->
370
-
371
228
  ---
372
- ## 🚨 Volatile State
229
+ ## Volatile State
373
230
  <!-- pmd: diff-stat -->
374
231
  <!-- /pmd -->
375
232
  ```
376
233
 
377
- *(Notice how volatile data like `diff-stat` is placed at the bottom? This ensures your LLM Prompt Cache hits for the top 90% of the document!)*
378
-
379
- ---
234
+ Volatile data at the bottom keeps your LLM prompt cache warm.
380
235
 
381
- ## βš™οΈ Configuration (`config.yml`)
236
+ ### Config (`config.yml`)
382
237
 
383
- The `config.yml` connects the `pmd:` tags in your template to the actual scripts that fetch the data.
238
+ Connects template tags to the scripts that fetch the data.
384
239
 
385
240
  ```yaml
386
241
  version: "1.0"
387
-
388
- # ⚠️ Security Warning: PipeMD executes the commands below exactly as written.
389
- # Do not run PipeMD in an untrusted repository.
390
-
391
- # Optional: Base instructions file, prepended to the served context.
392
- # AI edits to the base section are written back here.
393
242
  base: ".pipemd/base.md"
394
243
 
395
244
  commands:
396
245
  arch: "bash .pipemd/scripts/architecture/arch.sh"
397
246
  tree: "bash .pipemd/scripts/project/tree.sh"
398
247
  diff-stat: "bash .pipemd/scripts/git/diff-stat.sh"
399
- todos: "bash .pipemd/scripts/project/find-todos.sh"
400
248
 
401
249
  pipes:
402
- - file: "AGENTS.md" # The file the AI Agent reads
403
- render: ".pipemd/template.md" # The template to populate
250
+ - file: "AGENTS.md"
251
+ render: ".pipemd/template.md"
404
252
  ```
405
253
 
406
- ### Shared Scripts
407
- Because `.pipemd/scripts/` is committed to git, your whole team gets the exact same context harness. Drop any language script in there (`.sh`, `.py`, `.js`) to pull test results, type-check errors, or database schemas.
254
+ > **Security:** PipeMD executes commands from `config.yml` as-is. Do not run in untrusted repositories.
408
255
 
409
256
  ---
410
257
 
411
- ## πŸ€– For AI Agents
412
-
413
- If you are an AI agent reading a PipeMD context file, here is the contract:
414
-
415
- **Reading.** The file you read (`CLAUDE.md`, `AGENTS.md`, …) is a *live render*.
416
- Prefer the data inside `<!-- pmd: -->` blocks over running your own shell
417
- commands β€” it is current as of the moment you opened the file.
258
+ ## Crew: Multi-Agent Coordination
418
259
 
419
- **Editing.** The file is split by a `<!-- pmd-context -->` separator:
260
+ When multiple AI agents work the same repo, PipeMD Crew gives them shared awareness β€” file claims, conflict detection, and status broadcasts β€” rendered into every agent's context file.
420
261
 
421
- | Where you edit | Where it persists | Notes |
422
- |---|---|---|
423
- | Above the separator | `.pipemd/base.md` | Your own rules and instructions. |
424
- | Below it, *outside* `<!-- pmd: -->` blocks | `.pipemd/template.md` | Section headers, notes, checkboxes. |
425
- | *Inside* a `<!-- pmd: -->` block | **nowhere** | Overwritten every refresh cycle β€” never edit here. |
426
-
427
- **Self-improvement.** Because the harness is plain text, you can tune your own
428
- context: add/remove `<!-- pmd: -->` blocks in `.pipemd/template.md`, change
429
- which scripts run in `.pipemd/config.yml`, or adjust the token profile. See
430
- `.pipemd/AI_SETUP_PIPEMD.md` (scaffolded into every project) for the full guide.
431
-
432
- **Working alongside other agents.** If a **Crew Activity** block is present,
433
- read it before editing β€” it lists which files other agents hold. A
434
- `⚠️ CONFLICT` line means another agent claimed a file you are about to touch;
435
- treat it as blocking. Announce your own work with `pmd crew claim <file>` and
436
- `pmd crew note "<task>"` (or let the installed hooks do it automatically).
262
+ ```bash
263
+ pmd crew join --role coordinator --label "Claude"
264
+ pmd crew claim src/auth.ts --note "refactoring login"
265
+ pmd crew note "rewriting the auth middleware"
266
+ pmd crew release src/auth.ts
267
+ pmd crew leave
268
+ ```
437
269
 
438
- **Smart Injection.** If the project uses Active or Expert delivery mode, PipeMD hooks inject fresh context into your working memory on every tool call. You'll see messages like `[pmd:crew-locks β†’ src/foo.ts]` before edits and `[pmd:validate-file β†’ src/foo.ts]` after edits. This data is:
270
+ | Command | Description |
271
+ |---------|-------------|
272
+ | `pmd crew join` | Register this agent (`--role`, `--label`) |
273
+ | `pmd crew claim <file>` | Mark files as being worked on |
274
+ | `pmd crew release <file>` | Release claims (`--all` for everything) |
275
+ | `pmd crew note "<text>"` | Post current task/status |
276
+ | `pmd crew status` | Show live crew tree |
277
+ | `pmd crew leave` | Deregister this agent |
278
+ | `pmd crew install-hooks` | Auto-wire harness hooks for self-reporting |
439
279
 
440
- - **Scoped**: you only see context relevant to the file you're about to touch
441
- - **Deduplicated**: repeated unchanged data is silently skipped
442
- - **Cache-backed**: hook latency is under 5ms
280
+ Crew hooks are available for Claude Code, OpenCode, and Gemini CLI β€” agents automatically report their activity without manual commands.
443
281
 
444
282
  ---
445
283
 
446
- ## πŸ”’ Safety & Edge Cases Handled
447
-
448
- > **⚠️ Security Warning:** PipeMD executes the commands in `config.yml` exactly as written. Do not run PipeMD in an untrusted repository.
449
-
450
- Building a background daemon that streams live data into AI systems requires aggressive safety guardrails. PipeMD includes:
284
+ ## Known Limitations
451
285
 
452
- * **10-Second Timeouts:** No runaway `grep` commands hanging your AI. If a script stalls, it gets killed.
453
- * **Isolated Rendering:** Built on `Promise.allSettled`. If your `test-summary.sh` fails, the error is rendered *in-place* inside the markdown file, and the rest of the document loads perfectly.
454
- * **EPIPE Catching:** If Claude Code closes the stream mid-read to save tokens, PipeMD safely catches the `EPIPE` disconnect without crashing the daemon.
455
- * **Stale PID Recovery:** If your machine forcefully reboots, `pmd start` instantly detects the dead process, cleans up the old pipes, and starts fresh.
286
+ ### FIFO (Named Pipe) Read Errors with Some Agents
456
287
 
457
- ---
288
+ Agents backed by Effect.js (e.g. OpenCode) may fail to read pipe-mode context files with errors like:
458
289
 
459
- ## πŸ§‘β€πŸ’» For Developers
290
+ ```
291
+ Unknown: FileSystem.readAlloc (30)
292
+ ```
460
293
 
461
- PipeMD is strict TypeScript, **ESM-only** (imports use `.js` extensions,
462
- `NodeNext` resolution), built with `tsup`, and targets Node.js 18+.
294
+ **Root cause:** These agents use Effect.js's `FileSystem.readAlloc`, which expects regular file semantics (seekable, known size). PipeMD's named pipes are FIFOs β€” stream-oriented, unseekable, and `stat()` reports size 0. When the agent passes `limit`/`offset`, Effect.js tries to `seek()` on the FIFO and fails.
463
295
 
464
- ### Build & test
296
+ **Mitigation:** The PipeMD OpenCode plugin automatically detects FIFO reads and redirects them to a regular temp file rendered by `pmd run`. This should resolve the error for most setups. Make sure your plugin is up to date (`pmd crew install-hooks` or `pmd init`).
465
297
 
466
- ```bash
467
- pnpm install # Install dependencies
468
- pnpm build # Production build β†’ dist/ (run before any e2e test)
469
- pnpm dev # Watch mode β€” rebuilds on change
470
- tsc --noEmit # Type-check only
471
-
472
- pnpm test # Full suite: unit β†’ e2e β†’ bidir β†’ scripts β†’ arch β†’ compose β†’ crew
473
- pnpm test:unit # reverseInject logic (pure Node, no build needed)
474
- pnpm test:crew # Crew coordination lifecycle (needs build)
475
- ```
298
+ **Fallback workaround:** If the plugin fix doesn't cover your case, switch the affected pipe to legacy mode in `.pipemd/config.yml`:
476
299
 
477
- There is no test framework: unit tests use `node:assert`, e2e tests are Bash
478
- scripts with custom assertion helpers in `tests/`.
479
-
480
- ### Source layout
481
-
482
- ```text
483
- src/
484
- β”œβ”€β”€ index.ts # CLI entry β€” Commander program, registers all commands
485
- β”œβ”€β”€ config.ts # PipeConfig type + DEFAULT_CONFIG
486
- β”œβ”€β”€ commands/ # One file per command: init, start, stop, restart,
487
- β”‚ # status, run, refresh, doctor, uninstall, crew
488
- └── core/
489
- β”œβ”€β”€ daemon.ts # Daemon loop β€” pipe mode (mkfifo) + legacy mode (chokidar)
490
- β”œβ”€β”€ injector.ts # Renders <!-- pmd: --> blocks; reverseInject write-back
491
- β”œβ”€β”€ cache.ts # Per-source render cache with TTL + invalidation
492
- β”œβ”€β”€ injection-types.ts # Injection config schema, types, defaults
493
- β”œβ”€β”€ injection-engine.ts # Rules engine β€” resolves sources, dedup, truncation
494
- β”œβ”€β”€ dedup.ts # Per-session dedup β€” skips unchanged content
495
- β”œβ”€β”€ detect.ts # Ecosystem auto-detection (Node, Python, Rust, …)
496
- β”œβ”€β”€ detectHarness.ts # AI-harness detection (Claude Code, OpenCode, …)
497
- β”œβ”€β”€ crew.ts # Crew ledger, conflict detection, block rendering
498
- β”œβ”€β”€ hooks.ts # Per-harness hook installers (crew + injection)
499
- β”œβ”€β”€ actions.ts # start/stop/cleanup logic
500
- └── logger.ts # File logger β†’ .pipemd/daemon.log
501
-
502
- scripts/ # Bundled Bash library, by ecosystem & category
503
- templates/ # Per-ecosystem Markdown templates
504
- tests/ # e2e-*.sh suites + test-reverse-inject.mjs + fixtures/
300
+ ```yaml
301
+ pipes:
302
+ - file: AGENTS.md
303
+ render: .pipemd/template.md
304
+ mode: legacy # writes a regular file instead of a FIFO
505
305
  ```
506
306
 
507
- ### The render pipeline
307
+ Legacy mode writes a real file to disk, so agents read it normally. You lose zero-disk-write semantics, but context stays live.
508
308
 
509
- 1. `daemon.ts` reads `.pipemd/template.md` and finds `<!-- pmd: name -->` tags.
510
- 2. `injector.ts` runs each tag's command (from `config.commands`) concurrently
511
- via `Promise.allSettled`, with a 10 s timeout per command.
512
- 3. Rendered blocks replace the tags; `base.md` is prepended with the
513
- `<!-- pmd-context -->` separator.
514
- 4. The composed Markdown is served on the named pipe (or written in legacy mode)
515
- to every harness's context file.
516
- 5. AI edits flow back: `reverseInject` de-renders `pmd` blocks and persists
517
- edits to `base.md` / `template.md`.
309
+ **Tracking:** If you hit this, please comment on or open an issue so we can track which agents are affected.
518
310
 
519
- ### Smart injection pipeline (Active/Expert mode)
311
+ ---
520
312
 
521
- 1. Harness hook fires (e.g., Claude Code `PreToolUse:Edit` on `src/foo.ts`)
522
- 2. Hook calls `pmd inject --trigger before-edit --file src/foo.ts`
523
- 3. Injection engine loads rules from `injection.yml`
524
- 4. For each matching rule, runs the source resolver (crew-locks, file-errors, git-context...)
525
- 5. Each resolver reads from the render cache (sub-5ms)
526
- 6. Dedup layer checks: skip if content unchanged since last injection
527
- 7. Payloads printed to stdout β†’ agent sees them as hook output
528
- 8. For after-edit triggers: async validation (eslint + tsc) runs in background, cached for next call
313
+ ## Contributing
529
314
 
530
- PRs welcome β€” see `CLAUDE.md` for conventions and gotchas, `SPEC.md` for the
531
- full specification.
315
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for build instructions, source layout, and architecture details.
532
316
 
533
- ## πŸ“œ License
317
+ ## License
534
318
 
535
- **ISC License** Β© Ivann Rudrauf
319
+ ISC License β€” see [LICENSE](./LICENSE).