pluidr 0.5.0 → 0.6.1

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
@@ -4,127 +4,288 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dm/pluidr)](https://www.npmjs.com/package/pluidr)
5
5
  [![License](https://img.shields.io/npm/l/pluidr)](https://github.com/funara/pluidr/blob/main/LICENSE)
6
6
 
7
- **Explore · Plan · Build · Debug** — opinionated engineering workflow installer for [OpenCode](https://opencode.ai).
7
+ ** Plan · Build · Review ** — opinionated engineering workflow installer for [OpenCode](https://opencode.ai).
8
8
 
9
- ## How it works
9
+ ---
10
10
 
11
- Pluidr sets up a **12-agent** pipeline in OpenCode organized under **2 primary agents**: **Composer** (orchestrating 7 subagents across 3 phases) and **Debugger** (standalone, 3 subagents). Every agent has a strict role, scoped permissions, and no shared subagents.
11
+ ## What is Pluidr?
12
12
 
13
- ### Primary Agents
13
+ Pluidr installs a **17-agent pipeline** into OpenCode — structured around **3 primary agents**, each with their own exclusive subagents, scoped permissions, and enforced workflow rules. No shared subagents. No ad-hoc delegation.
14
14
 
15
- **1. Composer tab** The single entry point for all feature work. Composer runs 3 strict, sequential phases:
15
+ | Primary Agent | Purpose | Subagents |
16
+ |---|---|---|
17
+ | **Composer** | Feature work — Explore → Plan → Build | Researcher, Plan-Writer, Plan-Checker, Coder, Tester, Reviewer, Compose-Reporter |
18
+ | **Debugger** | Bug investigation — Investigate → Fix → Report | Inspector, Fixer, Debug-Reporter |
19
+ | **Prober** | Security audit — Trace → Patch → Audit | Tracer, Patcher, Auditor, Probe-Reporter |
16
20
 
17
- - **EXPLORE phase** (mandatory start) — Brainstorms with you, then delegates ALL research to the Researcher subagent — Composer itself has no read/glob/grep/webfetch/websearch/bash permissions. Produces actionable recommendations with certainty marking. Uses a **guardrail gate**: must ask you "Ready to write the PRD?" before proceeding to Plan.
21
+ ---
18
22
 
19
- - **PLAN phase** — Turns findings into a verified PRD via Plan-Writer → Plan-Checker. Plan-Writer writes the PRD to `docs/plans/`. Plan-Checker validates against your original request (PASS/FAIL + gap list only). On FAIL, surfaces gap remedies to you via the question tool (max 3 loops). On PASS, uses a **guardrail gate**: must ask you "Build from this PRD?" before proceeding to Build.
23
+ ## Agent Workflows
20
24
 
21
- - **BUILD phase**Executes the confirmed PRD via Coder → Tester → Reviewer → Writer in strict sequence. Coder implements, Tester validates (PASS/FAIL/BLOCKED), Reviewer gates against the PRD definition-of-done, Writer produces a completion report to `docs/reports/`. Coder→Coder loops without verification are forbidden. Max 3 consecutive FAILs before surfacing to you.
25
+ ### 🎼 ComposerFeature Work
22
26
 
23
- Composer never edits files or runs bash directly all work is delegated to subagents.
27
+ Composer is the **single entry point for all feature work**. It runs 3 strict, one-directional phases. Phase direction is one-way no going back without explicit user instruction.
24
28
 
25
- After presenting the completion report, Composer resets to EXPLORE phase and asks what you'd like to do next: start a new feature, switch to Debugger for bugs, or iterate on the current result.
26
-
27
- **2. Debugger tab** (standalone, user-triggered at any time) — Root-cause analysis using the **Brooks-Lint methodology** (Iron Law + 6 Decay Risks). Delegates investigation to Inspector, fixes to Fixer, and reports to Reporter. Does not depend on Composer — triggered directly by you.
28
- Debugger never reads files, edits code, or runs bash directly — all investigation, fixes, and reports are delegated to subagents.
29
-
30
- After presenting the investigation outcome, Debugger resets and asks what you'd like to do next: investigate a new bug, switch to Composer for feature work, or re-investigate with new information.
29
+ ```
30
+ You describe a feature / idea
31
+
32
+
33
+ ┌─────────────────────────────────────────┐
34
+ │ EXPLORE PHASE (mandatory start) │
35
+ │ │
36
+ │ Delegate: Researcher │
37
+ │ → deep codebase + web fact-finding │
38
+ │ → confirmed_facts / inferred_facts / │
39
+ │ unknowns / risks │
40
+ │ │
41
+ │ Composer internally assesses: │
42
+ │ Is this feature simple or complex? │
43
+ └──────────┬──────────────────────────────┘
44
+
45
+ ┌────────┴────────┐
46
+ │ Simple feature │ Complex feature
47
+ ▼ ▼
48
+ GUARDRAIL GATE 1a GUARDRAIL GATE 1b
49
+ "Build directly?" "Write a PRD?"
50
+ │ │
51
+ │ Yes │ Yes
52
+ │ ▼
53
+ │ ┌──────────────────────────────┐
54
+ │ │ PLAN PHASE │
55
+ │ │ │
56
+ │ │ Plan-Writer → docs/plans/ │
57
+ │ │ Plan-Checker validates PRD │
58
+ │ │ PASS/FAIL + gap list only │
59
+ │ │ │
60
+ │ │ FAIL → surface gaps to you │
61
+ │ │ (max 5 loops) │
62
+ │ │ │
63
+ │ │ PASS → GUARDRAIL GATE 2 │
64
+ │ │ "Build from this PRD?" │
65
+ │ └──────────┬───────────────────┘
66
+ │ │ Yes
67
+ └──────────┬──────────┘
68
+
69
+ ┌────────────────────────────────────────────┐
70
+ │ BUILD PHASE │
71
+ │ │
72
+ │ Coder → implements from PRD / request │
73
+ │ │ │
74
+ │ ▼ │
75
+ │ Tester → PASS/FAIL/BLOCKED │
76
+ │ │ FAIL → back to Coder (max 5 loops) │
77
+ │ │ PASS ↓ │
78
+ │ ▼ │
79
+ │ Reviewer → PASS/FAIL + gap list │
80
+ │ │ FAIL → back to Coder (max 5 loops) │
81
+ │ │ PASS ↓ │
82
+ │ ▼ │
83
+ │ Compose-Reporter → docs/reports/ │
84
+ └────────────────────────────────────────────┘
85
+
86
+
87
+ You review result
88
+
89
+ Composer resets → asks: New feature? Debug? Iterate?
90
+ ```
31
91
 
32
- ### Exclusive Subagents
92
+ **Key rules:**
93
+ - Composer has **no read/write/bash permissions** — all work delegated to subagents
94
+ - Phase transition only via guardrail gates — no skipping
95
+ - `Coder → Coder` loops without Tester verification are forbidden
96
+ - 5 consecutive FAILs from Tester or Reviewer → surfaces to you
33
97
 
34
- Each subagent belongs to exactly one primary agent and cannot be invoked by anyone else:
98
+ ---
35
99
 
36
- | Primary | Phase | Subagents | Role |
37
- |---------|-------|-----------|------|
38
- | Composer | EXPLORE | Researcher | Technical/codebase fact-finding (confirmed_facts/inferred_facts/unknowns/risks) |
39
- | Composer | PLAN | Plan-Writer | Stateless PRD formatter — writes to `docs/plans/`, missing input = TBD |
40
- | Composer | PLAN | Plan-Checker | **Gate** — validates PRD against original request, PASS/FAIL + gap list only |
41
- | Composer | BUILD | Coder | Writes and edits implementation code |
42
- | Composer | BUILD | Tester | Runs tests, reports PASS/FAIL/BLOCKED + coverage gaps |
43
- | Composer | BUILD | Reviewer | **Gate** — compares implementation against definition-of-done, PASS/FAIL + gap list only |
44
- | Composer | BUILD | Writer | Stateless document formatter — writes completion reports to `docs/reports/` |
45
- | Debugger | DEBUG | Inspector | Brooks-Lint RCA (Iron Law + 6 decay risks + 4 review modes) |
46
- | Debugger | DEBUG | Fixer | Applies minimal, root-cause-targeted fixes |
47
- | Debugger | DEBUG | Reporter | Stateless diagnosis report formatter (Iron Law structure) |
100
+ ### 🐛 Debugger Bug Investigation
48
101
 
49
- ### Workflow
102
+ Debugger is a **standalone primary agent** — does not depend on Composer. Trigger it directly from the Debugger tab whenever you find a bug.
50
103
 
51
104
  ```
52
- You describe a feature / idea
53
-
54
-
55
- Composer — always starts in EXPLORE phase
56
-
57
- ┌───────┤
58
-
59
- [Optional] Researcher deep fact-finding
60
-
61
- Synthesize findings Internally assess complexity
62
- ├── SimpleGUARDRAIL GATE 1a (question tool):
63
- │ "Ready to build directly?"
64
- ├── "Yes" → BUILD phase
65
- │ ├── "Write a PRD first" → PLAN phase
66
- │ └── "More research"continue exploring
67
- │ └── Complex → GUARDRAIL GATE 1b (question tool):
68
- "Ready to write the PRD?"
69
- │ ├── "Yes" → PLAN phase
70
- │ └── "More research" → continue exploring
71
-
72
- (PLAN) (direct BUILD)
73
- Plan-Writer docs/plans/ Coder Tester →
74
- Plan-Checker validates Reviewer Writer → docs/reports/
75
-
76
- ▼ (FAIL, max 3 loops)
77
- Surface gaps → you pick remedy
78
-
79
- (PASS)
80
- GUARDRAIL GATE 2 (question tool):
81
- │ "Build from this PRD?"
82
- └── "Yes" → BUILD phase
83
- Coder → Tester → Reviewer → Writer → docs/reports/
105
+ You report a bug / defect
106
+
107
+
108
+ ┌─────────────────────────────────────────────┐
109
+ INVESTIGATE PHASE │
110
+ │ │
111
+ Delegate: Inspector │
112
+ Review mode (Debugger selects): │
113
+ · PR Review → classify R1-R6 │
114
+ · Architecture dependency analysis │
115
+ · Tech Debt Pain × Spread score │
116
+ · Test Quality → classify T1-T6 │
117
+
118
+ Output: Iron Law chain per finding │
119
+ Symptom SourceConsequence → Remedy │
120
+ └──────────┬──────────────────────────────────┘
121
+
122
+ Root cause identified?
123
+ ┌────────┴────────┐
124
+ Yes No / unknowns remain
125
+
126
+ ┌─────────────┐ Halt surface to you
127
+ FIX PHASE │ with specific questions
128
+
129
+ Delegate: │
130
+ Fixer │
131
+ → minimal
132
+ fix per │
133
+ Iron Law │
134
+ └──────┬──────┘
135
+
136
+
137
+ ┌──────────────────────────────────────┐
138
+ │ REPORT PHASE │
139
+ │ │
140
+ │ Delegate: Debug-Reporter │
141
+ │ → Iron Law diagnosis report │
142
+ │ → saved to docs/reports/ │
143
+ └──────────────────────────────────────┘
84
144
 
85
145
 
86
- You review the result
146
+ You review the diagnosis + fix
87
147
 
88
- (If bug found at any point → Debugger Inspector Fixer Reporter you verify)
148
+ Debugger resetsasks: New bug? Feature work? Re-investigate?
149
+ ```
150
+
151
+ **Key rules:**
152
+ - Debugger has **no read/write/bash permissions** — all delegated to subagents
153
+ - Never delegates Fixer without Inspector confirming root cause first
154
+ - If unknowns remain after investigation → halts and prompts you, does not guess
155
+
156
+ ---
157
+
158
+ ### 🔍 Prober — Security Audit
159
+
160
+ Prober is a **standalone primary agent** — does not depend on Composer or Debugger. Trigger it directly from the Prober tab to audit any codebase for security vulnerabilities and quality decay.
161
+
162
+ ```
163
+ You trigger a security audit
164
+
165
+
166
+ ┌───────────────────────────────────────────────────┐
167
+ │ TRACE PHASE (mandatory start) │
168
+ │ │
169
+ │ Delegate: Tracer │
170
+ │ → WSTG-guided breadth-first recon │
171
+ │ → trace data flows: input → path → sink │
172
+ │ │
173
+ │ Output: │
174
+ │ · Confirmed Vulnerabilities (OWASP category, │
175
+ │ location, data flow) │
176
+ │ · Suspected Vulnerabilities (manual verify) │
177
+ │ · Quality & Decay Risks (e.g. hardcoded │
178
+ │ secrets, missing input validation) │
179
+ └──────────┬────────────────────────────────────────┘
180
+
181
+
182
+ GUARDRAIL GATE (question tool):
183
+ "Audit findings ready. How to proceed?"
184
+ ├── "Patch all confirmed findings" → PATCH PHASE
185
+ ├── "Select specific findings" → PATCH PHASE (you pick)
186
+ ├── "Audit only — no patches" → AUDIT PHASE (skip PATCH)
187
+ └── "Re-investigate attack surface" → re-delegate Tracer
188
+
189
+
190
+ ┌──────────────────────────────────────────────────┐
191
+ │ PATCH PHASE (skipped if audit-only) │
192
+ │ │
193
+ │ Delegate: Patcher │
194
+ │ → Ponytail mindset: smallest correct diff │
195
+ │ → prefer deleting the cause over wrapping it │
196
+ │ → escalates to you if patch > 10 lines │
197
+ └──────────┬───────────────────────────────────────┘
198
+
199
+
200
+ ┌──────────────────────────────────────────────────┐
201
+ │ AUDIT PHASE (max 5 loops) │
202
+ │ │
203
+ │ Delegate: Auditor │
204
+ │ → verify patch resolved vulnerabilities │
205
+ │ → security regression check │
206
+ │ → Ponytail BLOAT analysis (over-engineering) │
207
+ │ │
208
+ │ PASS → proceed to report │
209
+ │ FAIL → re-delegate Patcher with Gap + BLOAT │
210
+ │ lists verbatim (max 5 loops, then you) │
211
+ │ │
212
+ │ Delegate: Probe-Reporter │
213
+ │ → security audit report → docs/reports/ │
214
+ └──────────────────────────────────────────────────┘
215
+
216
+
217
+ You review the audit report
218
+
219
+ Prober resets → asks: New audit? Feature work? Bug investigation?
89
220
  ```
90
221
 
91
- ### Flow Rules
222
+ **Key rules:**
223
+ - Prober has **no read/write/bash permissions** — all delegated to subagents
224
+ - TRACE phase is always mandatory — no patching without recon first
225
+ - GUARDRAIL GATE required before any patches are applied
226
+ - 5 consecutive AUDIT FAILs → surfaces to you
227
+
228
+ ---
229
+
230
+ ## Subagent Reference
231
+
232
+ Each subagent belongs to exactly one primary agent and cannot be invoked by anyone else:
233
+
234
+ | Primary | Phase | Subagent | Role |
235
+ |---------|-------|----------|------|
236
+ | Composer | EXPLORE | Researcher | Fact-finding: confirmed_facts / inferred_facts / unknowns / risks |
237
+ | Composer | PLAN | Plan-Writer | **Formatter** — writes PRD to `docs/plans/`, missing input = TBD |
238
+ | Composer | PLAN | Plan-Checker | **Gate** — PASS/FAIL + gap list only, no suggestions |
239
+ | Composer | BUILD | Coder | Implements code from PRD |
240
+ | Composer | BUILD | Tester | PASS/FAIL/BLOCKED + coverage gaps only |
241
+ | Composer | BUILD | Reviewer | **Gate** — PASS/FAIL + gap list only, no suggestions |
242
+ | Composer | BUILD | Compose-Reporter | **Formatter** — completion report to `docs/reports/` |
243
+ | Debugger | DEBUG | Inspector | Brooks-Lint RCA (Iron Law + 6 decay risks + 4 review modes) |
244
+ | Debugger | DEBUG | Fixer | Minimal, root-cause-targeted fix |
245
+ | Debugger | DEBUG | Debug-Reporter | **Formatter** — Iron Law diagnosis report to `docs/reports/` |
246
+ | Prober | TRACE | Tracer | WSTG recon + vuln path tracing, no remedies |
247
+ | Prober | PATCH | Patcher | Minimal, security-targeted fix (Ponytail, max 10 lines) |
248
+ | Prober | AUDIT | Auditor | **Gate** — PASS/FAIL + Gap List + BLOAT List only |
249
+ | Prober | AUDIT | Probe-Reporter | **Formatter** — security audit report to `docs/reports/` |
250
+
251
+ ---
252
+
253
+ ## Flow Rules
92
254
 
93
255
  | Rule | Detail |
94
256
  |------|--------|
95
- | **Mandatory EXPLORE start** | Composer always starts in EXPLORE phase no skipping to Plan or Build without passing a guardrail gate |
96
- | **Complexity assessment** | Composer internally evaluates if the feature is simple (few files, low risk, clear approach) this is LLM judgment, not user choice |
97
- | **Guardrail Gate 1** | Simple question tool: "Ready to build directly?" Complex question tool: "Ready to write the PRD?" Both paths require user confirmation |
98
- | **Guardrail Gate 2** | PLAN→BUILD: question tool asks "Build from this PRD?" with explicit confirmation |
99
- | **Direct build path** | Simple features can skip PLAN phase Composer determines simplicity, user just confirms |
100
- | **Gate agents** | Plan-Checker and Reviewer output PASS/FAIL + gap list only no improvement suggestions, no decisions |
101
- | **Researcher agents** | Researcher and Inspector output confirmed_facts/inferred_facts/unknowns/risks no recommendations |
102
- | **Writer agents** | Plan-Writer, Writer, and Reporter are stateless formatters missing input = TBD, never invent content |
103
- | **Phase-scoped delegation** | EXPLORE: researcher only. PLAN: plan-writer, plan-checker only. BUILD: coder, tester, reviewer, writer only |
104
- | **Build gate order** | Coder → Tester → Reviewer → Writer — no skipping, no Coder→Coder without verification |
105
- | **Plan-Checker FAIL loop** | Plan-checker FAIL → Composer surfaces gap remedies to you via question tool (MC options) → you pick → Composer routes to Plan-Writer. Max 3 loops, then surfaces to you for direction |
106
- | **Build FAIL loop** | 3 consecutive FAILs from Tester or Reviewer → Composer surfaces to you |
107
- | **Output directories** | Plan-Writer writes to `docs/plans/`. Writer writes to `docs/reports/`. Enforced by permissions |
108
- | **Debugger independence** | Debugger is standalone — does not flow through Composer, triggered directly by you |
109
-
110
- ### Brooks-Lint Methodology (Debugger)
111
-
112
- The Debugger group uses the [Brooks-Lint](https://hyhmrright.github.io/brooks-lint/guide.html) framework:
257
+ | **Mandatory starts** | Composer always starts in EXPLORE. Prober always starts in TRACE. No skipping. |
258
+ | **Guardrail gates** | Composer: Gate 1 (EXPLORE→PLAN/BUILD), Gate 2 (PLAN→BUILD). Prober: Gate after TRACE. All require user confirmation. |
259
+ | **Gate agents** | Plan-Checker, Reviewer, Auditor PASS/FAIL + gap list only. No suggestions, no decisions. |
260
+ | **Formatter agents** | Plan-Writer, Compose-Reporter, Debug-Reporter, Probe-Reporter stateless. Missing input = TBD/NA. Never invent content. |
261
+ | **Fact-finding agents** | Researcher, Inspector, Tracerfacts/inferences/risks only. No recommendations. |
262
+ | **Build gate order** | Coder Tester Reviewer Compose-Reporter. No skipping. No Coder→Coder without verification. |
263
+ | **FAIL loops** | Plan-Checker FAIL: max 5 loops. Build FAIL (Tester/Reviewer): max 5 loops. Prober AUDIT FAIL: max 5 loops. All surface to you after limit. |
264
+ | **Output directories** | PRDs → `docs/plans/`. Reports (Compose-Reporter, Debug-Reporter, Probe-Reporter) `docs/reports/`. Enforced by permissions. |
265
+ | **Independence** | Debugger and Prober are fully standalone triggered directly, do not flow through Composer. |
266
+
267
+ ---
268
+
269
+ ## Brooks-Lint Methodology (Debugger)
270
+
271
+ The Debugger pipeline uses the [Brooks-Lint](https://hyhmrright.github.io/brooks-lint/guide.html) framework:
113
272
 
114
273
  - **Iron Law** per finding: Symptom → Source → Consequence → Remedy
115
- - **6 Decay Risks (R1-R6)**: Cognitive Overload, Change Propagation, Knowledge Duplication, Accidental Complexity, Dependency Disorder, Domain Model Distortion
116
- - **4 Review Modes**: PR Review (R1-R6), Architecture Audit (dependency analysis), Tech Debt Assessment (Pain × Spread), Test Quality (T1-T6)
117
- - **T1-T6 Test Risks**: Test Obscurity, Brittleness, Duplication, Mock Abuse, Coverage Illusion, Architecture Mismatch
274
+ - **6 Decay Risks (R1R6)**: Cognitive Overload, Change Propagation, Knowledge Duplication, Accidental Complexity, Dependency Disorder, Domain Model Distortion
275
+ - **4 Review Modes**: PR Review (R1R6), Architecture Audit, Tech Debt Assessment (Pain × Spread), Test Quality (T1T6)
276
+ - **T1T6 Test Risks**: Test Obscurity, Brittleness, Duplication, Mock Abuse, Coverage Illusion, Architecture Mismatch
277
+
278
+ ## Principle Hierarchy
118
279
 
119
- ### Principle Hierarchy
280
+ All agents resolve conflicts using this priority order (defined in `hierarchy.txt`):
120
281
 
121
- Conflict resolution follows a strict priority order (defined in `hierarchy.txt`):
282
+ 1. **PRD / Spec** explicit requirement text
283
+ 2. **Verdict** — Reviewer / Plan-Checker / Auditor PASS/FAIL
284
+ 3. **Engineering principles** — Fail Fast, Single Responsibility
285
+ 4. **Heuristics** — KISS, DRY, SOLID, Law of Demeter
286
+ 5. **Local optimization** — style preference
122
287
 
123
- 1. **PRD / Spec** (explicit requirement text)
124
- 2. **Verdict** (Reviewer PASS/FAIL, Plan-Checker PASS/FAIL)
125
- 3. **Engineering principles tied to correctness** (Fail Fast, Single Responsibility)
126
- 4. **Heuristics** (KISS, DRY, SOLID, Law of Demeter)
127
- 5. **Local optimization / style preference**
288
+ ---
128
289
 
129
290
  ## Install
130
291
 
@@ -140,63 +301,57 @@ npx pluidr init
140
301
 
141
302
  ## Usage
142
303
 
143
- ### pluidr init
304
+ ### `pluidr init`
144
305
 
145
- Prompts you to select models for two agent tiers, then:
306
+ Prompts you to select models for two agent tiers (reasoning-heavy and fast), then:
146
307
 
147
- - Asks whether to install the pluidr-squeeze plugin (can decline squeeze download)
148
- - Builds a complete opencode.jsonc config with the chosen models injected into the right agents
149
- - Backs up any existing config at ~/.config/opencode/opencode.jsonc to opencode.jsonc.bak
150
- - Writes the new config to ~/.config/opencode/opencode.jsonc
151
- - Copies agent system-prompt files into ~/.config/opencode/prompts/
152
- - Copies the bundled pluidr-flow and pluidr-squeeze plugins into ~/.config/opencode/plugins/
153
- - Writes a package.json into ~/.config/opencode/ declaring @opencode-ai/plugin as a dependency (OpenCode installs it automatically on first launch via its bundled Bun runtime)
308
+ - Asks whether to install the pluidr-squeeze plugin (can decline)
309
+ - Builds a complete `opencode.jsonc` config with the chosen models injected into the right agents
310
+ - Backs up any existing config to `opencode.jsonc.bak.*`
311
+ - Writes the new config to `~/.config/opencode/opencode.jsonc`
312
+ - Copies all 18 agent prompt files into `~/.config/opencode/prompts/`
313
+ - Copies `pluidr-flow` and `pluidr-squeeze` plugins into `~/.config/opencode/plugins/`
314
+ - Writes a `package.json` declaring `@opencode-ai/plugin` as a dependency
154
315
 
155
- On completion, prints:
156
- `
157
- Pluidr setup complete!
158
- You can update your agent model settings later in opencode.jsonc
159
- `
160
- The filename opencode.jsonc (second line) is a clickable terminal hyperlink — Ctrl+click to open the config in your default editor.
316
+ ### `pluidr doctor`
161
317
 
162
- ### pluidr uninstall
318
+ Checks installation health and reports ✓/✗ for each component:
163
319
 
164
- Removes Pluidr artifacts and restores your previous configuration:
320
+ - `opencode.jsonc` exists
321
+ - All 18 prompt files present
322
+ - Both plugin files present
323
+ - `package.json` with `@opencode-ai/plugin` dependency
324
+ - squeeze binary available
325
+ - Config is valid JSON
165
326
 
166
- - Finds the latest timestamped backup (opencode.jsonc.bak.*) in ~/.config/opencode/
167
- - Restores it to opencode.jsonc
168
- - Removes prompts/, plugins/, and bin/ directories
169
- - Does NOT remove opencode.jsonc itself (preserves user customizations)
170
- - Does NOT remove package.json (may be used by other plugins)
171
- - Prints a summary of what was removed and restored
327
+ Exits with code `0` if all pass, `1` if any fail.
172
328
 
173
- ### pluidr update
329
+ ### `pluidr update`
174
330
 
175
- Re-runs the setup wizard (same as pluidr init). Before writing, warns if existing config is found and asks for confirmation.
331
+ Re-runs the setup wizard. Warns if existing config is found and asks for confirmation before overwriting.
176
332
 
177
- ### pluidr doctor
333
+ ### `pluidr uninstall`
178
334
 
179
- Checks installation health and reports PASS/FAIL for each component:
335
+ Restores your previous configuration:
180
336
 
181
- - opencode.jsonc exists
182
- - All 13 prompt files exist
183
- - Both plugin files exist
184
- - package.json with @opencode-ai/plugin dependency
185
- - squeeze binary is available
186
- - Config is valid JSON
337
+ - Finds the latest timestamped backup and restores it to `opencode.jsonc`
338
+ - Removes `prompts/`, `plugins/`, and `bin/` directories
339
+ - Preserves `opencode.jsonc` and `package.json`
187
340
 
188
- Prints a summary table with ✓/✗ status. Exits with code 0 if all pass, 1 if any fail.
341
+ ---
189
342
 
190
- ## Bundled plugins
343
+ ## Bundled Plugins
191
344
 
192
- Pluidr ships with two plugins:
345
+ ### `pluidr-flow`
193
346
 
194
- **`pluidr-flow`** — provides subagents with three tools for cross-session context access:
347
+ Provides subagents with cross-session context access:
195
348
 
196
349
  - `parent_session_messages` — read the parent session's transcript
197
350
  - `session_messages(sessionId)` — read any session by ID
198
351
  - `session_messages_batch(sessionIds)` — read multiple sessions in one call
199
352
 
200
- **`pluidr-squeeze`** — hooks into tool execution to rewrite bash commands through the `squeeze` binary, filtering verbose output and saving 60-90% of tokens across all agents.
353
+ ### `pluidr-squeeze`
354
+
355
+ Hooks into tool execution to rewrite bash commands through the `squeeze` binary, filtering verbose output and saving **60–90% of tokens** across all agents.
201
356
 
202
- `pluidr init` installs both plugins and their dependency declaration automatically no extra user action. `pluidr-squeeze` also downloads the engine to `~/.config/opencode/bin/`. On OpenCode's first launch, the bundled Bun runtime installs `@opencode-ai/plugin` from the generated `package.json`, then both plugins become available to all agents.
357
+ Both plugins and their dependency declaration are installed automatically by `pluidr init` no extra user action required. On OpenCode's first launch, the bundled Bun runtime installs `@opencode-ai/plugin` from the generated `package.json`.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pluidr",
3
- "version": "0.5.0",
4
- "description": "Opinionated Engineering Workflow for OpenCode — Plan, Build, Review.",
3
+ "version": "0.6.1",
4
+ "description": "Opinionated Engineering Workflow for OpenCode — Explore, Plan, Build, Debug, and Security-Audit.",
5
5
  "keywords": [
6
6
  "opencode",
7
7
  "workflow",
@@ -10,6 +10,8 @@
10
10
  "ai-agents",
11
11
  "code-review",
12
12
  "debugging",
13
+ "security-audit",
14
+ "security",
13
15
  "planner",
14
16
  "builder",
15
17
  "cli"
@@ -3,10 +3,10 @@ import { join, dirname } from "node:path"
3
3
  import { fileURLToPath } from "node:url"
4
4
  import { execFileSync } from "node:child_process"
5
5
  import { getConfigDir, getConfigPath, getPromptsDir } from "../../core/paths.js"
6
- import { findRtkPath } from "../../core/squeezeInstaller.js"
6
+ import { findSqueezePath } from "../../core/squeezeInstaller.js"
7
7
 
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url))
9
- const EXPECTED_PROMPT_COUNT = 13
9
+ const EXPECTED_PROMPT_COUNT = 18
10
10
  const PLUGIN_FILES = ["pluidr-flow.js", "pluidr-squeeze.js"]
11
11
 
12
12
  export async function runDoctor() {
@@ -23,7 +23,7 @@ export async function runDoctor() {
23
23
  const configExists = existsSync(configPath)
24
24
  checks.push({ component: "opencode.jsonc", pass: configExists })
25
25
 
26
- // 2. All 13 prompt files exist
26
+ // 2. All 18 prompt files exist
27
27
  let promptCount = 0
28
28
  if (existsSync(promptsDir)) {
29
29
  try {
@@ -33,7 +33,7 @@ export async function runDoctor() {
33
33
  promptCount = 0
34
34
  }
35
35
  }
36
- checks.push({ component: "13 prompt files", pass: promptCount === EXPECTED_PROMPT_COUNT, detail: `${promptCount}/${EXPECTED_PROMPT_COUNT}` })
36
+ checks.push({ component: "18 prompt files", pass: promptCount === EXPECTED_PROMPT_COUNT, detail: `${promptCount}/${EXPECTED_PROMPT_COUNT}` })
37
37
 
38
38
  // 3. Both plugin files exist
39
39
  let pluginsFound = 0
@@ -54,16 +54,16 @@ export async function runDoctor() {
54
54
  }
55
55
  checks.push({ component: "package.json + plugin dep", pass: pkgValid })
56
56
 
57
- // 5. RTK binary exists
58
- let rtkFound = false
59
- const rtkOnPath = findRtkPath()
60
- if (rtkOnPath) {
61
- rtkFound = true
57
+ // 5. Squeeze binary exists
58
+ let squeezeFound = false
59
+ const squeezeOnPath = findSqueezePath()
60
+ if (squeezeOnPath) {
61
+ squeezeFound = true
62
62
  } else {
63
- const binName = process.platform === "win32" ? "rtk.exe" : "rtk"
64
- rtkFound = existsSync(join(binDir, binName))
63
+ const binName = process.platform === "win32" ? "squeeze.exe" : "squeeze"
64
+ squeezeFound = existsSync(join(binDir, binName))
65
65
  }
66
- checks.push({ component: "squeeze binary", pass: rtkFound })
66
+ checks.push({ component: "squeeze binary tested", pass: squeezeFound })
67
67
 
68
68
  // 6. Config is valid JSON/JSONC
69
69
  let configValid = false
@@ -19,21 +19,21 @@ describe("agentPromptWriter", () => {
19
19
  mkdirSync(agentPromptsDir, { recursive: true })
20
20
 
21
21
  writeFileSync(join(agentPromptsDir, "coder.txt"), "test instructions", "utf-8")
22
- writeFileSync(join(agentPromptsDir, "writer.txt"), "write docs", "utf-8")
22
+ writeFileSync(join(agentPromptsDir, "compose-reporter.txt"), "write docs", "utf-8")
23
23
 
24
24
  writeAgentPrompts(tmpDir, destDir)
25
25
 
26
26
  const coderContent = readFileSync(join(destDir, "coder.txt"), "utf-8")
27
- const writerContent = readFileSync(join(destDir, "writer.txt"), "utf-8")
27
+ const composeReporterContent = readFileSync(join(destDir, "compose-reporter.txt"), "utf-8")
28
28
 
29
29
  assert.ok(coderContent.startsWith('You are the "coder" agent.\n\n'),
30
30
  "coder should have identity header")
31
- assert.ok(writerContent.startsWith('You are the "writer" agent.\n\n'),
32
- "writer should have identity header")
31
+ assert.ok(composeReporterContent.startsWith('You are the "compose-reporter" agent.\n\n'),
32
+ "compose-reporter should have identity header")
33
33
  assert.ok(coderContent.includes("test instructions"),
34
34
  "original content preserved in coder")
35
- assert.ok(writerContent.includes("write docs"),
36
- "original content preserved in writer")
35
+ assert.ok(composeReporterContent.includes("write docs"),
36
+ "original content preserved in compose-reporter")
37
37
 
38
38
  rmSync(tmpDir, { recursive: true })
39
39
  })
@@ -5,9 +5,9 @@ import { getConfigPath } from "./paths.js"
5
5
  const MAX_BACKUPS = 5
6
6
 
7
7
  function timestamp() {
8
- const d = new Date()
9
- const pad = (n) => String(n).padStart(2, "0")
10
- return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}_${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`
8
+ // ponytail: simplified formatting using native Date serialization
9
+ const s = new Date().toISOString().replace(/[-:]/g, "")
10
+ return `${s.slice(0, 8)}_${s.slice(9, 15)}`
11
11
  }
12
12
 
13
13
  function rotateBackups(configPath) {
package/src/core/paths.js CHANGED
@@ -5,5 +5,5 @@ const BASE = join(homedir(), ".config", "opencode")
5
5
 
6
6
  export const getConfigDir = () => BASE
7
7
  export const getConfigPath = () => join(BASE, "opencode.jsonc")
8
- export const getBackupPath = () => join(BASE, "opencode.jsonc.bak")
9
8
  export const getPromptsDir = () => join(BASE, "prompts")
9
+ // ponytail: getBackupPath removed (YAGNI)
@@ -2,7 +2,7 @@ import { describe, it } from "node:test"
2
2
  import assert from "node:assert"
3
3
  import { homedir } from "node:os"
4
4
  import { join } from "node:path"
5
- import { getConfigDir, getConfigPath, getBackupPath, getPromptsDir } from "./paths.js"
5
+ import { getConfigDir, getConfigPath, getPromptsDir } from "./paths.js"
6
6
 
7
7
  const BASE = join(homedir(), ".config", "opencode")
8
8
 
@@ -15,10 +15,6 @@ describe("paths", () => {
15
15
  assert.strictEqual(getConfigPath(), join(BASE, "opencode.jsonc"))
16
16
  })
17
17
 
18
- it("getBackupPath returns opencode.jsonc.bak path", () => {
19
- assert.strictEqual(getBackupPath(), join(BASE, "opencode.jsonc.bak"))
20
- })
21
-
22
18
  it("getPromptsDir returns prompts path", () => {
23
19
  assert.strictEqual(getPromptsDir(), join(BASE, "prompts"))
24
20
  })