@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/CHANGELOG.md +25 -0
- package/CONTRIBUTING.md +73 -0
- package/README.md +192 -408
- package/dist/index.js +727 -32
- package/dist/plugins/opencode-server.js +23 -1
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -1,535 +1,319 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
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>
|
|
11
|
-
|
|
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="
|
|
16
|
-
<a href="
|
|
17
|
-
<
|
|
18
|
-
<
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
39
|
+
```bash
|
|
40
|
+
npx @pipemd-core/pipemd init
|
|
41
|
+
npx @pipemd-core/pipemd start
|
|
42
|
+
```
|
|
93
43
|
|
|
94
|
-
|
|
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
|
-
##
|
|
48
|
+
## What Your AI Sees
|
|
107
49
|
|
|
108
|
-
|
|
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
|
-
```
|
|
111
|
-
#
|
|
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
|
-
>
|
|
55
|
+
> This file refreshes automatically. Content inside `<!-- pmd: -->` blocks
|
|
56
|
+
> is read-only β everything else is yours to edit.
|
|
122
57
|
|
|
123
|
-
|
|
58
|
+
## Architecture
|
|
59
|
+
<!-- pmd: arch -->
|
|
60
|
+
graph TD
|
|
61
|
+
src/index --> chalk
|
|
62
|
+
src/index --> commander
|
|
63
|
+
<!-- /pmd -->
|
|
124
64
|
|
|
125
|
-
|
|
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
|
-
##
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
```
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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
|
-
|
|
194
|
-
β "Crew: Gemini session joined. Git: 1 new uncommitted file."
|
|
195
|
-
```
|
|
128
|
+
---
|
|
196
129
|
|
|
197
|
-
|
|
130
|
+
## Delivery Modes
|
|
198
131
|
|
|
199
|
-
|
|
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
|
-
| **
|
|
204
|
-
| **
|
|
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 |
|
|
212
|
-
|
|
213
|
-
|
|
|
214
|
-
|
|
|
215
|
-
|
|
|
216
|
-
|
|
|
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
|
-
|
|
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
|
-
##
|
|
153
|
+
## Features
|
|
241
154
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
-
##
|
|
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
|
|
271
|
-
| `pmd
|
|
272
|
-
| `pmd
|
|
273
|
-
| `pmd
|
|
274
|
-
| `pmd
|
|
275
|
-
| `pmd
|
|
276
|
-
| `pmd
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
##
|
|
183
|
+
## What Gets Generated
|
|
305
184
|
|
|
306
|
-
|
|
185
|
+
Everything lives in `.pipemd/`. Your root directory stays clean.
|
|
307
186
|
|
|
308
|
-
```
|
|
187
|
+
```
|
|
309
188
|
your-project/
|
|
310
189
|
βββ .pipemd/
|
|
311
|
-
β βββ config.yml #
|
|
312
|
-
β βββ base.md #
|
|
313
|
-
β βββ template.md #
|
|
314
|
-
β βββ
|
|
315
|
-
β
|
|
316
|
-
β β βββ
|
|
317
|
-
β β βββ
|
|
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
|
|
320
|
-
β βββ
|
|
321
|
-
β βββ
|
|
322
|
-
β
|
|
323
|
-
|
|
324
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
211
|
+
## Configuration
|
|
339
212
|
|
|
340
|
-
|
|
213
|
+
### The Template (`.pipemd/template.md`)
|
|
341
214
|
|
|
342
|
-
|
|
215
|
+
Your source of truth. Use `<!-- pmd: command_name -->` tags where you want live data injected.
|
|
343
216
|
|
|
344
217
|
```markdown
|
|
345
|
-
#
|
|
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
|
-
##
|
|
224
|
+
## Project Structure
|
|
364
225
|
<!-- pmd: tree -->
|
|
365
226
|
<!-- /pmd -->
|
|
366
227
|
|
|
367
|
-
## π TODOs
|
|
368
|
-
<!-- pmd: todos -->
|
|
369
|
-
<!-- /pmd -->
|
|
370
|
-
|
|
371
228
|
---
|
|
372
|
-
##
|
|
229
|
+
## Volatile State
|
|
373
230
|
<!-- pmd: diff-stat -->
|
|
374
231
|
<!-- /pmd -->
|
|
375
232
|
```
|
|
376
233
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
---
|
|
234
|
+
Volatile data at the bottom keeps your LLM prompt cache warm.
|
|
380
235
|
|
|
381
|
-
|
|
236
|
+
### Config (`config.yml`)
|
|
382
237
|
|
|
383
|
-
|
|
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"
|
|
403
|
-
render: ".pipemd/template.md"
|
|
250
|
+
- file: "AGENTS.md"
|
|
251
|
+
render: ".pipemd/template.md"
|
|
404
252
|
```
|
|
405
253
|
|
|
406
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
290
|
+
```
|
|
291
|
+
Unknown: FileSystem.readAlloc (30)
|
|
292
|
+
```
|
|
460
293
|
|
|
461
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
311
|
+
---
|
|
520
312
|
|
|
521
|
-
|
|
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
|
-
|
|
531
|
-
full specification.
|
|
315
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for build instructions, source layout, and architecture details.
|
|
532
316
|
|
|
533
|
-
##
|
|
317
|
+
## License
|
|
534
318
|
|
|
535
|
-
|
|
319
|
+
ISC License β see [LICENSE](./LICENSE).
|