@pipemd-core/pipemd 1.0.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.
Files changed (96) hide show
  1. package/AI_SETUP_PIPEMD.md +184 -0
  2. package/CHANGELOG.md +47 -0
  3. package/LICENSE +15 -0
  4. package/README.md +535 -0
  5. package/dist/index.js +6647 -0
  6. package/dist/plugins/opencode-server.js +235 -0
  7. package/dist/plugins/opencode-tui.js +914 -0
  8. package/dist/templates/agent-decision-tree.md +113 -0
  9. package/dist/templates/static-rules.md +7 -0
  10. package/package.json +68 -0
  11. package/scripts/C-CPP/architecture/arch.sh +229 -0
  12. package/scripts/C-CPP/lib/limit.sh +146 -0
  13. package/scripts/C-CPP/project/class-diagram.sh +96 -0
  14. package/scripts/C-CPP/project/cmake-targets.sh +68 -0
  15. package/scripts/C-CPP/project/deps.sh +44 -0
  16. package/scripts/C-CPP/project/find-todos.sh +6 -0
  17. package/scripts/C-CPP/project/include-graph.sh +110 -0
  18. package/scripts/C-CPP/project/interfaces.sh +108 -0
  19. package/scripts/C-CPP/project/tree.sh +5 -0
  20. package/scripts/C-CPP/quality/lint.sh +14 -0
  21. package/scripts/C-CPP/quality/test-summary.sh +22 -0
  22. package/scripts/C-CPP/quality/type-check.sh +26 -0
  23. package/scripts/DevOps/architecture/arch.sh +186 -0
  24. package/scripts/DevOps/devops/aws-context.sh +34 -0
  25. package/scripts/DevOps/devops/docker-stats.sh +42 -0
  26. package/scripts/DevOps/devops/k8s-unhealthy.sh +41 -0
  27. package/scripts/DevOps/devops/tf-state.sh +65 -0
  28. package/scripts/DevOps/lib/limit.sh +143 -0
  29. package/scripts/Generic/architecture/arch.sh +570 -0
  30. package/scripts/Generic/lib/limit.sh +140 -0
  31. package/scripts/Go/architecture/arch.sh +79 -0
  32. package/scripts/Go/lib/limit.sh +142 -0
  33. package/scripts/Go/project/deps.sh +35 -0
  34. package/scripts/Go/project/find-todos.sh +6 -0
  35. package/scripts/Go/project/go-interfaces.sh +18 -0
  36. package/scripts/Go/project/go-packages.sh +28 -0
  37. package/scripts/Go/project/tree.sh +5 -0
  38. package/scripts/Go/quality/lint.sh +16 -0
  39. package/scripts/Go/quality/test-summary.sh +16 -0
  40. package/scripts/Go/quality/type-check.sh +16 -0
  41. package/scripts/Node-TypeScript/api/express-routes.sh +14 -0
  42. package/scripts/Node-TypeScript/api/nest-controllers.sh +18 -0
  43. package/scripts/Node-TypeScript/architecture/arch.sh +174 -0
  44. package/scripts/Node-TypeScript/frontend/angular-routes.sh +15 -0
  45. package/scripts/Node-TypeScript/frontend/nextjs-app-router.sh +13 -0
  46. package/scripts/Node-TypeScript/frontend/react-components.sh +20 -0
  47. package/scripts/Node-TypeScript/lib/limit.sh +146 -0
  48. package/scripts/Node-TypeScript/project/deps.sh +15 -0
  49. package/scripts/Node-TypeScript/project/find-todos.sh +6 -0
  50. package/scripts/Node-TypeScript/quality/lint.sh +10 -0
  51. package/scripts/Node-TypeScript/quality/test-summary.sh +39 -0
  52. package/scripts/Node-TypeScript/quality/type-check.sh +10 -0
  53. package/scripts/Python/api/fastapi-routes.sh +12 -0
  54. package/scripts/Python/architecture/arch.sh +220 -0
  55. package/scripts/Python/db/django-models.sh +12 -0
  56. package/scripts/Python/db/sqlalchemy.sh +17 -0
  57. package/scripts/Python/lib/limit.sh +144 -0
  58. package/scripts/Python/project/deps.sh +28 -0
  59. package/scripts/Python/project/find-todos.sh +6 -0
  60. package/scripts/Python/quality/lint.sh +13 -0
  61. package/scripts/Python/quality/test-summary.sh +11 -0
  62. package/scripts/Python/quality/type-check.sh +10 -0
  63. package/scripts/Rust/architecture/arch.sh +176 -0
  64. package/scripts/Rust/lib/limit.sh +142 -0
  65. package/scripts/Rust/project/cargo-deps.sh +42 -0
  66. package/scripts/Rust/project/cargo-features.sh +26 -0
  67. package/scripts/Rust/project/find-todos.sh +6 -0
  68. package/scripts/Rust/project/tree.sh +5 -0
  69. package/scripts/Rust/quality/lint.sh +16 -0
  70. package/scripts/Rust/quality/test-summary.sh +16 -0
  71. package/scripts/Rust/quality/type-check.sh +16 -0
  72. package/scripts/Shared/api/express-routes.sh +11 -0
  73. package/scripts/Shared/api/fastapi-routes.sh +10 -0
  74. package/scripts/Shared/api/nest-controllers.sh +22 -0
  75. package/scripts/Shared/architecture/normalize.sh +178 -0
  76. package/scripts/Shared/crew/crew.sh +15 -0
  77. package/scripts/Shared/db/django-models.sh +11 -0
  78. package/scripts/Shared/db/prisma.sh +33 -0
  79. package/scripts/Shared/db/sqlalchemy.sh +12 -0
  80. package/scripts/Shared/frontend/angular-routes.sh +11 -0
  81. package/scripts/Shared/frontend/nextjs-app-router.sh +13 -0
  82. package/scripts/Shared/frontend/react-components.sh +11 -0
  83. package/scripts/Shared/git/diff-stat.sh +6 -0
  84. package/scripts/Shared/git/git-branch.sh +16 -0
  85. package/scripts/Shared/git/git-log.sh +6 -0
  86. package/scripts/Shared/git/git-status.sh +6 -0
  87. package/scripts/Shared/lib/limit.sh +144 -0
  88. package/scripts/Shared/project/compose-md.sh +182 -0
  89. package/scripts/Shared/project/deps.sh +69 -0
  90. package/scripts/Shared/project/find-todos.sh +6 -0
  91. package/scripts/Shared/project/tree.sh +5 -0
  92. package/scripts/Shared/quality/lint.sh +81 -0
  93. package/scripts/Shared/quality/test-summary.sh +103 -0
  94. package/scripts/Shared/quality/type-check.sh +114 -0
  95. package/scripts/copy-plugins.mjs +4 -0
  96. package/scripts/copy-templates.mjs +5 -0
package/README.md ADDED
@@ -0,0 +1,535 @@
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>
5
+ </p>
6
+
7
+ <h1 align="center">PipeMD</h1>
8
+
9
+ <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>
12
+ </p>
13
+
14
+ <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>
19
+ </p>
20
+
21
+ ---
22
+
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 │
79
+
80
+ Two operational modes:
81
+
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`.
85
+
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.
88
+
89
+
90
+ ---
91
+
92
+ ## ✨ Features: Built for Vibe Coding
93
+
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.
103
+
104
+ ---
105
+
106
+ ## 🚀 Quick Start
107
+
108
+ Get your dynamic context harness running in under 60 seconds:
109
+
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
+ ```
120
+
121
+ > **Bash Required:** PipeMD's context scripts rely on a Bash environment. Windows users must use WSL or Git Bash.
122
+
123
+ *The setup wizard will auto-detect your ecosystem and configure the optimal `.pipemd/template.md` and context scripts for your workspace.*
124
+
125
+ *The setup wizard will also ask how to deliver context — **Active** (recommended for most agents) or **Passive** (for Cursor, Aider, or CI).*
126
+
127
+ ---
128
+
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
+ └────────────────────────────────────────────────────────┘
168
+ ```
169
+
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.
171
+
172
+ ---
173
+
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:
179
+
180
+ ```text
181
+ Agent is about to READ a file:
182
+ → Hook fires → "Crew: this file is unclaimed. Safe to read."
183
+
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"
188
+
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)"
192
+
193
+ Agent has been idle for 10 seconds:
194
+ → "Crew: Gemini session joined. Git: 1 new uncommitted file."
195
+ ```
196
+
197
+ ### Three Delivery Modes
198
+
199
+ During `pmd init`, choose how PipeMD delivers context to your agent:
200
+
201
+ | Mode | How it works | Best for |
202
+ |------|-------------|----------|
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 |
205
+ | **Expert** | Full control over injection rules via `.pipemd/injection.yml`. | Teams with custom workflows |
206
+
207
+ ### What gets injected
208
+
209
+ Active mode injects context at four moments:
210
+
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)
221
+
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
+ ```
237
+
238
+ ---
239
+
240
+ ## 🛠️ Commands
241
+
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. |
256
+
257
+ ---
258
+
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.
267
+
268
+ | Command | Description |
269
+ |---------|-------------|
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`.
301
+
302
+ ---
303
+
304
+ ## 🏗️ What Gets Generated?
305
+
306
+ PipeMD keeps your root directory pristine. Everything lives in `.pipemd/`.
307
+
308
+ ```text
309
+ your-project/
310
+ ├── .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
318
+ │ │ ├── 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`
331
+ ```
332
+
333
+ > Only `config.yml`, `base.md`, `template.md`, and `scripts/` are committed —
334
+ > everything your team needs to reproduce the harness, and nothing ephemeral.
335
+
336
+ ---
337
+
338
+ ## 🎯 The Template (`.pipemd/template.md`)
339
+
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.
341
+
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`.
343
+
344
+ ```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
+ ```
359
+
360
+ ```
361
+ <!-- /pmd -->
362
+
363
+ ## 📁 Project Structure
364
+ <!-- pmd: tree -->
365
+ <!-- /pmd -->
366
+
367
+ ## 📝 TODOs
368
+ <!-- pmd: todos -->
369
+ <!-- /pmd -->
370
+
371
+ ---
372
+ ## 🚨 Volatile State
373
+ <!-- pmd: diff-stat -->
374
+ <!-- /pmd -->
375
+ ```
376
+
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
+ ---
380
+
381
+ ## ⚙️ Configuration (`config.yml`)
382
+
383
+ The `config.yml` connects the `pmd:` tags in your template to the actual scripts that fetch the data.
384
+
385
+ ```yaml
386
+ 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
+ base: ".pipemd/base.md"
394
+
395
+ commands:
396
+ arch: "bash .pipemd/scripts/architecture/arch.sh"
397
+ tree: "bash .pipemd/scripts/project/tree.sh"
398
+ diff-stat: "bash .pipemd/scripts/git/diff-stat.sh"
399
+ todos: "bash .pipemd/scripts/project/find-todos.sh"
400
+
401
+ pipes:
402
+ - file: "AGENTS.md" # The file the AI Agent reads
403
+ render: ".pipemd/template.md" # The template to populate
404
+ ```
405
+
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.
408
+
409
+ ---
410
+
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.
418
+
419
+ **Editing.** The file is split by a `<!-- pmd-context -->` separator:
420
+
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).
437
+
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:
439
+
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
443
+
444
+ ---
445
+
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:
451
+
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.
456
+
457
+ ---
458
+
459
+ ## 🧑‍💻 For Developers
460
+
461
+ PipeMD is strict TypeScript, **ESM-only** (imports use `.js` extensions,
462
+ `NodeNext` resolution), built with `tsup`, and targets Node.js 18+.
463
+
464
+ ### Build & test
465
+
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
+ ```
476
+
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/
505
+ ```
506
+
507
+ ### The render pipeline
508
+
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`.
518
+
519
+ ### Smart injection pipeline (Active/Expert mode)
520
+
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
529
+
530
+ PRs welcome — see `CLAUDE.md` for conventions and gotchas, `SPEC.md` for the
531
+ full specification.
532
+
533
+ ## 📜 License
534
+
535
+ **ISC License** © Ivann Rudrauf