@sienklogic/plan-build-run 2.56.0 → 2.56.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/CHANGELOG.md +7 -0
- package/README.md +76 -28
- package/package.json +1 -1
- package/plugins/codex-pbr/references/pbr-tools-cli.md +2 -2
- package/plugins/codex-pbr/skills/health/SKILL.md +1 -1
- package/plugins/codex-pbr/skills/shared/state-update.md +1 -1
- package/plugins/copilot-pbr/plugin.json +1 -1
- package/plugins/copilot-pbr/references/pbr-tools-cli.md +2 -2
- package/plugins/copilot-pbr/skills/begin/templates/STATE.md.tmpl +0 -1
- package/plugins/copilot-pbr/skills/health/SKILL.md +1 -1
- package/plugins/copilot-pbr/skills/shared/state-update.md +1 -1
- package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor-pbr/references/pbr-tools-cli.md +2 -2
- package/plugins/cursor-pbr/skills/begin/templates/STATE.md.tmpl +0 -1
- package/plugins/cursor-pbr/skills/health/SKILL.md +1 -1
- package/plugins/cursor-pbr/skills/shared/state-update.md +1 -1
- package/plugins/pbr/.claude-plugin/plugin.json +1 -1
- package/plugins/pbr/references/pbr-tools-cli.md +2 -2
- package/plugins/pbr/scripts/check-plan-format.js +5 -6
- package/plugins/pbr/scripts/check-state-sync.js +0 -5
- package/plugins/pbr/scripts/lib/state.js +1 -3
- package/plugins/pbr/scripts/pbr-tools.js +1 -1
- package/plugins/pbr/scripts/status-line.js +3 -4
- package/plugins/pbr/skills/begin/templates/STATE.md.tmpl +0 -1
- package/plugins/pbr/skills/health/SKILL.md +1 -1
- package/plugins/pbr/skills/shared/state-update.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ All notable changes to Plan-Build-Run will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.56.1](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.56.0...plan-build-run-v2.56.1) (2026-03-03)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* **quick-020:** comprehensively update documentation for v2.56.0 ([82f9177](https://github.com/SienkLogic/plan-build-run/commit/82f917792dd573192c4ce69df8633f13b1050b0a))
|
|
14
|
+
|
|
8
15
|
## [2.56.0](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.55.0...plan-build-run-v2.56.0) (2026-03-02)
|
|
9
16
|
|
|
10
17
|
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<strong>Context-engineered development workflow for Claude Code, Cursor,
|
|
6
|
+
<strong>Context-engineered development workflow for Claude Code, Cursor, GitHub Copilot CLI, OpenAI Codex, and Google Jules.</strong>
|
|
7
7
|
<br />
|
|
8
8
|
Build ambitious multi-phase software without quality degradation.
|
|
9
9
|
<br />
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
<img src="https://img.shields.io/badge/Node.js-18%2B-339933?style=for-the-badge&logo=node.js&logoColor=white" alt="Node.js 18+" />
|
|
28
28
|
<a href="LICENSE"><img src="https://img.shields.io/github/license/SienkLogic/plan-build-run?style=for-the-badge" alt="License" /></a>
|
|
29
29
|
<a href="https://www.npmjs.com/package/@sienklogic/plan-build-run"><img src="https://img.shields.io/npm/v/@sienklogic/plan-build-run?style=for-the-badge&logo=npm&logoColor=white" alt="npm" /></a>
|
|
30
|
-
<img src="https://img.shields.io/badge/Tests-
|
|
30
|
+
<img src="https://img.shields.io/badge/Tests-9283_passing-brightgreen?style=for-the-badge" alt="9283 Tests" />
|
|
31
31
|
</p>
|
|
32
32
|
|
|
33
33
|
---
|
|
@@ -132,6 +132,48 @@ All three plugins share the same `.planning/` directory — start in any tool, c
|
|
|
132
132
|
|
|
133
133
|
</details>
|
|
134
134
|
|
|
135
|
+
<details>
|
|
136
|
+
<summary><strong>Install for OpenAI Codex CLI</strong></summary>
|
|
137
|
+
|
|
138
|
+
Plan-Build-Run also works in OpenAI Codex CLI. Skills and agents are available via the `plugins/codex-pbr/` plugin. No hooks (Codex CLI does not support lifecycle hooks).
|
|
139
|
+
|
|
140
|
+
**macOS / Linux:**
|
|
141
|
+
```bash
|
|
142
|
+
cd /path/to/your/project
|
|
143
|
+
bash /path/to/plan-build-run/plugins/codex-pbr/setup.sh
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Windows (PowerShell):**
|
|
147
|
+
```powershell
|
|
148
|
+
cd C:\path\to\your\project
|
|
149
|
+
powershell -ExecutionPolicy Bypass -File C:\path\to\plan-build-run\plugins\codex-pbr\setup.ps1
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
All five plugins share the same `.planning/` directory. See [`plugins/codex-pbr/README.md`](plugins/codex-pbr/README.md) for full details.
|
|
153
|
+
|
|
154
|
+
</details>
|
|
155
|
+
|
|
156
|
+
<details>
|
|
157
|
+
<summary><strong>Install for Google Jules</strong></summary>
|
|
158
|
+
|
|
159
|
+
Plan-Build-Run also works in Google Jules. Skills and agents are available via the `plugins/jules-pbr/` plugin. No hooks (Jules does not support lifecycle hooks).
|
|
160
|
+
|
|
161
|
+
**macOS / Linux:**
|
|
162
|
+
```bash
|
|
163
|
+
cd /path/to/your/project
|
|
164
|
+
bash /path/to/plan-build-run/plugins/jules-pbr/setup.sh
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Windows (PowerShell):**
|
|
168
|
+
```powershell
|
|
169
|
+
cd C:\path\to\your\project
|
|
170
|
+
powershell -ExecutionPolicy Bypass -File C:\path\to\plan-build-run\plugins\jules-pbr\setup.ps1
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
All five plugins share the same `.planning/` directory. See [`plugins/jules-pbr/README.md`](plugins/jules-pbr/README.md) for full details.
|
|
174
|
+
|
|
175
|
+
</details>
|
|
176
|
+
|
|
135
177
|
<details>
|
|
136
178
|
<summary><strong>Dashboard (Optional)</strong></summary>
|
|
137
179
|
|
|
@@ -219,7 +261,7 @@ Set `depth: quick` in `/pbr:config` to reduce agent spawns across all workflows.
|
|
|
219
261
|
| `/pbr:build <N>` | Build a phase: parallel execution in waves, atomic commits | 2-4 (quick: 1-2) |
|
|
220
262
|
| `/pbr:review <N>` | Verify a phase: automated 3-layer checks + conversational UAT | 1 |
|
|
221
263
|
|
|
222
|
-
See **[Commands](https://github.com/SienkLogic/plan-build-run/wiki/Commands)** for all
|
|
264
|
+
See **[Commands](https://github.com/SienkLogic/plan-build-run/wiki/Commands)** for all 27 commands with flags, cost-by-depth tables, and detailed descriptions.
|
|
223
265
|
|
|
224
266
|
---
|
|
225
267
|
|
|
@@ -292,8 +334,8 @@ Requires a GPU with 6+ GB VRAM for best performance. CPU-only works but adds lat
|
|
|
292
334
|
| Topic | Description |
|
|
293
335
|
|-------|-------------|
|
|
294
336
|
| **[Agents](https://github.com/SienkLogic/plan-build-run/wiki/Agents)** | 12 specialized agents with configurable model profiles and file-based communication |
|
|
295
|
-
| **[Configuration](https://github.com/SienkLogic/plan-build-run/wiki/Configuration)** |
|
|
296
|
-
| **[Hooks](https://github.com/SienkLogic/plan-build-run/wiki/Hooks)** |
|
|
337
|
+
| **[Configuration](https://github.com/SienkLogic/plan-build-run/wiki/Configuration)** | 12 config keys, depth/model profiles, 14+ feature toggles, local LLM settings |
|
|
338
|
+
| **[Hooks](https://github.com/SienkLogic/plan-build-run/wiki/Hooks)** | 41 hook scripts that enforce discipline at zero token cost |
|
|
297
339
|
| **[Local LLM](https://github.com/SienkLogic/plan-build-run/wiki/Configuration#local_llm)** | Offload hook-level inference to Ollama for token savings with automatic fallback |
|
|
298
340
|
| **[Project Structure](https://github.com/SienkLogic/plan-build-run/wiki/Project-Structure)** | The `.planning/` directory layout, key files, and file ownership |
|
|
299
341
|
| **[Dashboard](https://github.com/SienkLogic/plan-build-run/wiki/Dashboard)** | Web UI with live updates for browsing project state |
|
|
@@ -306,28 +348,29 @@ Requires a GPU with 6+ GB VRAM for best performance. CPU-only works but adds lat
|
|
|
306
348
|
|
|
307
349
|
## Platform Compatibility
|
|
308
350
|
|
|
309
|
-
Plan-Build-Run works across
|
|
310
|
-
|
|
311
|
-
| Feature | Claude Code | Copilot CLI | Cursor IDE |
|
|
312
|
-
|
|
313
|
-
| Skills (slash commands) | All
|
|
314
|
-
| Agents (subagent delegation) | All 12 | All 12 | All 12 |
|
|
315
|
-
| `.planning/` state management | Full | Full | Full |
|
|
316
|
-
| **Hook support** | **Full (14 events)** | **Partial (4 events)** | **Unverified** |
|
|
317
|
-
| Commit format enforcement | Hook-enforced | Hook-enforced | Manual |
|
|
318
|
-
| PLAN/SUMMARY quality classification | Hook + skill fallback | Hook + skill fallback | Skill fallback only |
|
|
319
|
-
| Test failure triage | Automatic (hook) | Automatic (hook) | Not available |
|
|
320
|
-
| Context budget tracking | Automatic (hook) | Not available | Not available |
|
|
321
|
-
| Auto-continue between skills | Automatic (hook) | Not available | Not available |
|
|
322
|
-
| Subagent lifecycle logging | Automatic (hook) | Not available | Not available |
|
|
323
|
-
| **Local LLM offloading** | **Full (8 operations)** | **Mostly (6-7 operations)** | **CLI only** |
|
|
324
|
-
| `pbr-tools.js llm` CLI commands | Full | Full | Full |
|
|
351
|
+
Plan-Build-Run works across five platforms with varying levels of hook support. Hooks are the mechanism that fires validation scripts on every tool call — they power local LLM offloading, commit format enforcement, context budget tracking, and workflow gates.
|
|
352
|
+
|
|
353
|
+
| Feature | Claude Code | Copilot CLI | Cursor IDE | Codex CLI | Jules |
|
|
354
|
+
|---------|:-----------:|:-----------:|:----------:|:---------:|:-----:|
|
|
355
|
+
| Skills (slash commands) | All 27 | All 27 | All 27 | All 27 | All 27 |
|
|
356
|
+
| Agents (subagent delegation) | All 12 | All 12 | All 12 | All 12 | All 12 |
|
|
357
|
+
| `.planning/` state management | Full | Full | Full | Full | Full |
|
|
358
|
+
| **Hook support** | **Full (14 events)** | **Partial (4 events)** | **Unverified** | **None** | **None** |
|
|
359
|
+
| Commit format enforcement | Hook-enforced | Hook-enforced | Manual | Manual | Manual |
|
|
360
|
+
| PLAN/SUMMARY quality classification | Hook + skill fallback | Hook + skill fallback | Skill fallback only | Skill fallback only | Skill fallback only |
|
|
361
|
+
| Test failure triage | Automatic (hook) | Automatic (hook) | Not available | Not available | Not available |
|
|
362
|
+
| Context budget tracking | Automatic (hook) | Not available | Not available | Not available | Not available |
|
|
363
|
+
| Auto-continue between skills | Automatic (hook) | Not available | Not available | Not available | Not available |
|
|
364
|
+
| Subagent lifecycle logging | Automatic (hook) | Not available | Not available | Not available | Not available |
|
|
365
|
+
| **Local LLM offloading** | **Full (8 operations)** | **Mostly (6-7 operations)** | **CLI only** | **CLI only** | **CLI only** |
|
|
366
|
+
| `pbr-tools.js llm` CLI commands | Full | Full | Full | Full | Full |
|
|
325
367
|
|
|
326
368
|
**Key differences:**
|
|
327
369
|
|
|
328
370
|
- **Claude Code** has full hook support — all local LLM operations fire automatically on every tool call
|
|
329
371
|
- **Copilot CLI** supports `sessionStart`, `preToolUse`, `postToolUse`, and `sessionEnd` — covers most validation hooks but misses lifecycle events (`SubagentStop`, `PreCompact`, `Stop`)
|
|
330
372
|
- **Cursor IDE** hook support is unverified — hooks.json is configured but whether Cursor actually fires them is unknown. Skills include `pbr-tools.js llm` fallback calls for key operations (plan quality, verification quality) so local LLM classification is available even without hooks
|
|
373
|
+
- **OpenAI Codex CLI** and **Google Jules** do not support hooks. All skills and agents are available via `plugins/codex-pbr/` and `plugins/jules-pbr/` respectively. Agent definitions use AGENTS.md format.
|
|
331
374
|
|
|
332
375
|
All platforms share the same scripts via relative paths — no code duplication. See the [Copilot CLI](plugins/copilot-pbr/README.md) and [Cursor IDE](plugins/cursor-pbr/README.md) READMEs for platform-specific details.
|
|
333
376
|
|
|
@@ -341,7 +384,7 @@ git clone https://github.com/SienkLogic/plan-build-run.git
|
|
|
341
384
|
cd plan-build-run
|
|
342
385
|
npm install
|
|
343
386
|
|
|
344
|
-
# Run tests (
|
|
387
|
+
# Run tests (9283 tests, 281 suites)
|
|
345
388
|
npm test
|
|
346
389
|
|
|
347
390
|
# Lint
|
|
@@ -362,14 +405,19 @@ CI runs on Node 18/20/22 across Windows, macOS, and Linux. See [CONTRIBUTING.md]
|
|
|
362
405
|
|
|
363
406
|
| Metric | Count |
|
|
364
407
|
|--------|-------|
|
|
365
|
-
| Skills (slash commands) |
|
|
408
|
+
| Skills (slash commands) | 27 |
|
|
366
409
|
| Specialized agents | 12 |
|
|
367
|
-
| Hook scripts |
|
|
410
|
+
| Hook scripts | 41 |
|
|
368
411
|
| Local LLM operations | 8 |
|
|
369
|
-
| Supported platforms |
|
|
370
|
-
| Tests |
|
|
371
|
-
| Test suites |
|
|
372
|
-
| Config keys |
|
|
412
|
+
| Supported platforms | 5 (Claude Code, Cursor, Copilot CLI, Codex, Jules) |
|
|
413
|
+
| Tests | 9283 |
|
|
414
|
+
| Test suites | 281 |
|
|
415
|
+
| Config keys | 12 top-level (62+ properties) |
|
|
416
|
+
| Feature toggles | 14 |
|
|
417
|
+
| Lib modules | 19 |
|
|
418
|
+
| Shared fragments | 12 |
|
|
419
|
+
| Templates | 10 |
|
|
420
|
+
| References | 19 |
|
|
373
421
|
|
|
374
422
|
---
|
|
375
423
|
|
package/package.json
CHANGED
|
@@ -361,7 +361,7 @@ All phases with status and completion data.
|
|
|
361
361
|
node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js init progress
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
-
**Output:** `current_phase`, `
|
|
364
|
+
**Output:** `current_phase`, `phase_count`, `status`, `phases` array, `total_plans`, `completed_plans`, `percentage`.
|
|
365
365
|
|
|
366
366
|
---
|
|
367
367
|
|
|
@@ -375,7 +375,7 @@ Multi-field atomic STATE.md update. Updates all fields in a single pass.
|
|
|
375
375
|
node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js state patch '{"status":"executing","last_activity":"now"}'
|
|
376
376
|
```
|
|
377
377
|
|
|
378
|
-
**Valid fields:** `current_phase`, `status`, `plans_complete`, `last_activity`, `progress_percent`, `phase_slug`, `
|
|
378
|
+
**Valid fields:** `current_phase`, `status`, `plans_complete`, `last_activity`, `progress_percent`, `phase_slug`, `last_command`, `blockers`
|
|
379
379
|
|
|
380
380
|
**Output:** `{ "success": true, "updated": ["status", "last_activity"] }`
|
|
381
381
|
|
|
@@ -172,7 +172,7 @@ After running all 10 checks and collecting results, if any of the following auto
|
|
|
172
172
|
|
|
173
173
|
| Pattern | Detection | Fix Action |
|
|
174
174
|
|---------|-----------|------------|
|
|
175
|
-
| Missing STATE.md frontmatter | Check 5 finds STATE.md without `---` block | Regenerate frontmatter from ROADMAP.md phase data (current_phase,
|
|
175
|
+
| Missing STATE.md frontmatter | Check 5 finds STATE.md without `---` block | Regenerate frontmatter from ROADMAP.md phase data (current_phase, phase_slug, status) |
|
|
176
176
|
| STATE.md phase_slug mismatch | Check 5/7 finds phase_slug doesn't match current phase directory name | Correct phase_slug to match the actual directory name in `.planning/phases/` |
|
|
177
177
|
| Missing config.json | Check 1/2 finds no `.planning/config.json` | Create with default config template (same as `$pbr-setup` defaults) |
|
|
178
178
|
| Orphaned .active-skill file | Check 10 or general scan finds `.planning/.active-skill` older than 1 hour | Delete the stale `.active-skill` file |
|
|
@@ -53,7 +53,7 @@ Progress: [{progress_bar}] {percent}%
|
|
|
53
53
|
Phase 3 of 10 = 20% → [████░░░░░░░░░░░░░░░░] 20%
|
|
54
54
|
Phase 7 of 10 = 70% → [██████████████░░░░░░] 70%
|
|
55
55
|
```
|
|
56
|
-
Calculation: `filled = Math.round((completed_phases /
|
|
56
|
+
Calculation: `filled = Math.round((completed_phases / phase_count) * 20)` where `phase_count` is derived from ROADMAP.md (available via `stateLoad` as `phase_count`)
|
|
57
57
|
|
|
58
58
|
### 3. Accumulated Context (lines 16-25)
|
|
59
59
|
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pbr",
|
|
3
3
|
"displayName": "Plan-Build-Run",
|
|
4
|
-
"version": "2.56.
|
|
4
|
+
"version": "2.56.1",
|
|
5
5
|
"description": "Plan-Build-Run — Structured development workflow for GitHub Copilot CLI. Solves context rot through disciplined agent delegation, structured planning, atomic execution, and goal-backward verification.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "SienkLogic",
|
|
@@ -361,7 +361,7 @@ All phases with status and completion data.
|
|
|
361
361
|
node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js init progress
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
-
**Output:** `current_phase`, `
|
|
364
|
+
**Output:** `current_phase`, `phase_count`, `status`, `phases` array, `total_plans`, `completed_plans`, `percentage`.
|
|
365
365
|
|
|
366
366
|
---
|
|
367
367
|
|
|
@@ -375,7 +375,7 @@ Multi-field atomic STATE.md update. Updates all fields in a single pass.
|
|
|
375
375
|
node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js state patch '{"status":"executing","last_activity":"now"}'
|
|
376
376
|
```
|
|
377
377
|
|
|
378
|
-
**Valid fields:** `current_phase`, `status`, `plans_complete`, `last_activity`, `progress_percent`, `phase_slug`, `
|
|
378
|
+
**Valid fields:** `current_phase`, `status`, `plans_complete`, `last_activity`, `progress_percent`, `phase_slug`, `last_command`, `blockers`
|
|
379
379
|
|
|
380
380
|
**Output:** `{ "success": true, "updated": ["status", "last_activity"] }`
|
|
381
381
|
|
|
@@ -172,7 +172,7 @@ After running all 10 checks and collecting results, if any of the following auto
|
|
|
172
172
|
|
|
173
173
|
| Pattern | Detection | Fix Action |
|
|
174
174
|
|---------|-----------|------------|
|
|
175
|
-
| Missing STATE.md frontmatter | Check 5 finds STATE.md without `---` block | Regenerate frontmatter from ROADMAP.md phase data (current_phase,
|
|
175
|
+
| Missing STATE.md frontmatter | Check 5 finds STATE.md without `---` block | Regenerate frontmatter from ROADMAP.md phase data (current_phase, phase_slug, status) |
|
|
176
176
|
| STATE.md phase_slug mismatch | Check 5/7 finds phase_slug doesn't match current phase directory name | Correct phase_slug to match the actual directory name in `.planning/phases/` |
|
|
177
177
|
| Missing config.json | Check 1/2 finds no `.planning/config.json` | Create with default config template (same as `/pbr:setup` defaults) |
|
|
178
178
|
| Orphaned .active-skill file | Check 10 or general scan finds `.planning/.active-skill` older than 1 hour | Delete the stale `.active-skill` file |
|
|
@@ -53,7 +53,7 @@ Progress: [{progress_bar}] {percent}%
|
|
|
53
53
|
Phase 3 of 10 = 20% → [████░░░░░░░░░░░░░░░░] 20%
|
|
54
54
|
Phase 7 of 10 = 70% → [██████████████░░░░░░] 70%
|
|
55
55
|
```
|
|
56
|
-
Calculation: `filled = Math.round((completed_phases /
|
|
56
|
+
Calculation: `filled = Math.round((completed_phases / phase_count) * 20)` where `phase_count` is derived from ROADMAP.md (available via `stateLoad` as `phase_count`)
|
|
57
57
|
|
|
58
58
|
### 3. Accumulated Context (lines 16-25)
|
|
59
59
|
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pbr",
|
|
3
3
|
"displayName": "Plan-Build-Run",
|
|
4
|
-
"version": "2.56.
|
|
4
|
+
"version": "2.56.1",
|
|
5
5
|
"description": "Plan-Build-Run — Structured development workflow for Cursor. Solves context rot through disciplined subagent delegation, structured planning, atomic execution, and goal-backward verification.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "SienkLogic",
|
|
@@ -361,7 +361,7 @@ All phases with status and completion data.
|
|
|
361
361
|
node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js init progress
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
-
**Output:** `current_phase`, `
|
|
364
|
+
**Output:** `current_phase`, `phase_count`, `status`, `phases` array, `total_plans`, `completed_plans`, `percentage`.
|
|
365
365
|
|
|
366
366
|
---
|
|
367
367
|
|
|
@@ -375,7 +375,7 @@ Multi-field atomic STATE.md update. Updates all fields in a single pass.
|
|
|
375
375
|
node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js state patch '{"status":"executing","last_activity":"now"}'
|
|
376
376
|
```
|
|
377
377
|
|
|
378
|
-
**Valid fields:** `current_phase`, `status`, `plans_complete`, `last_activity`, `progress_percent`, `phase_slug`, `
|
|
378
|
+
**Valid fields:** `current_phase`, `status`, `plans_complete`, `last_activity`, `progress_percent`, `phase_slug`, `last_command`, `blockers`
|
|
379
379
|
|
|
380
380
|
**Output:** `{ "success": true, "updated": ["status", "last_activity"] }`
|
|
381
381
|
|
|
@@ -173,7 +173,7 @@ After running all 10 checks and collecting results, if any of the following auto
|
|
|
173
173
|
|
|
174
174
|
| Pattern | Detection | Fix Action |
|
|
175
175
|
|---------|-----------|------------|
|
|
176
|
-
| Missing STATE.md frontmatter | Check 5 finds STATE.md without `---` block | Regenerate frontmatter from ROADMAP.md phase data (current_phase,
|
|
176
|
+
| Missing STATE.md frontmatter | Check 5 finds STATE.md without `---` block | Regenerate frontmatter from ROADMAP.md phase data (current_phase, phase_slug, status) |
|
|
177
177
|
| STATE.md phase_slug mismatch | Check 5/7 finds phase_slug doesn't match current phase directory name | Correct phase_slug to match the actual directory name in `.planning/phases/` |
|
|
178
178
|
| Missing config.json | Check 1/2 finds no `.planning/config.json` | Create with default config template (same as `/pbr:setup` defaults) |
|
|
179
179
|
| Orphaned .active-skill file | Check 10 or general scan finds `.planning/.active-skill` older than 1 hour | Delete the stale `.active-skill` file |
|
|
@@ -53,7 +53,7 @@ Progress: [{progress_bar}] {percent}%
|
|
|
53
53
|
Phase 3 of 10 = 20% → [████░░░░░░░░░░░░░░░░] 20%
|
|
54
54
|
Phase 7 of 10 = 70% → [██████████████░░░░░░] 70%
|
|
55
55
|
```
|
|
56
|
-
Calculation: `filled = Math.round((completed_phases /
|
|
56
|
+
Calculation: `filled = Math.round((completed_phases / phase_count) * 20)` where `phase_count` is derived from ROADMAP.md (available via `stateLoad` as `phase_count`)
|
|
57
57
|
|
|
58
58
|
### 3. Accumulated Context (lines 16-25)
|
|
59
59
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pbr",
|
|
3
|
-
"version": "2.56.
|
|
3
|
+
"version": "2.56.1",
|
|
4
4
|
"description": "Plan-Build-Run — Structured development workflow for Claude Code. Solves context rot through disciplined subagent delegation, structured planning, atomic execution, and goal-backward verification.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SienkLogic",
|
|
@@ -361,7 +361,7 @@ All phases with status and completion data.
|
|
|
361
361
|
node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js init progress
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
-
**Output:** `current_phase`, `
|
|
364
|
+
**Output:** `current_phase`, `phase_count`, `status`, `phases` array, `total_plans`, `completed_plans`, `percentage`.
|
|
365
365
|
|
|
366
366
|
---
|
|
367
367
|
|
|
@@ -375,7 +375,7 @@ Multi-field atomic STATE.md update. Updates all fields in a single pass.
|
|
|
375
375
|
node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js state patch '{"status":"executing","last_activity":"now"}'
|
|
376
376
|
```
|
|
377
377
|
|
|
378
|
-
**Valid fields:** `current_phase`, `status`, `plans_complete`, `last_activity`, `progress_percent`, `phase_slug`, `
|
|
378
|
+
**Valid fields:** `current_phase`, `status`, `plans_complete`, `last_activity`, `progress_percent`, `phase_slug`, `last_command`, `blockers`
|
|
379
379
|
|
|
380
380
|
**Output:** `{ "success": true, "updated": ["status", "last_activity"] }`
|
|
381
381
|
|
|
@@ -347,7 +347,7 @@ function validateState(content, _filePath) {
|
|
|
347
347
|
warnings.push('Unclosed YAML frontmatter');
|
|
348
348
|
} else {
|
|
349
349
|
const frontmatter = content.substring(3, frontmatterEnd);
|
|
350
|
-
const requiredFields = ['version', 'current_phase', '
|
|
350
|
+
const requiredFields = ['version', 'current_phase', 'phase_slug', 'status'];
|
|
351
351
|
for (const field of requiredFields) {
|
|
352
352
|
if (!frontmatter.includes(`${field}:`)) {
|
|
353
353
|
warnings.push(`Frontmatter missing "${field}" field`);
|
|
@@ -440,14 +440,12 @@ function syncStateBody(content, filePath) {
|
|
|
440
440
|
|
|
441
441
|
const fm = content.substring(3, fmEnd);
|
|
442
442
|
const phaseMatch = fm.match(/^current_phase:\s*(\d+)/m);
|
|
443
|
-
const totalMatch = fm.match(/^total_phases:\s*(\d+)/m);
|
|
444
443
|
const slugMatch = fm.match(/^phase_name:\s*"?([^"\r\n]+)"?/m);
|
|
445
444
|
const statusMatch = fm.match(/^status:\s*"?([^"\r\n]+)"?/m);
|
|
446
445
|
|
|
447
446
|
if (!phaseMatch) return null;
|
|
448
447
|
|
|
449
448
|
const fmPhase = phaseMatch[1];
|
|
450
|
-
const fmTotal = totalMatch ? totalMatch[1] : null;
|
|
451
449
|
const fmName = slugMatch ? slugMatch[1] : null;
|
|
452
450
|
const fmStatus = statusMatch ? statusMatch[1] : null;
|
|
453
451
|
|
|
@@ -459,9 +457,10 @@ function syncStateBody(content, filePath) {
|
|
|
459
457
|
|
|
460
458
|
// Fix phase line drift
|
|
461
459
|
if (bodyPhaseMatch && bodyPhaseMatch[1] !== fmPhase) {
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
: `Phase: ${fmPhase} of ${
|
|
460
|
+
const bodyTotal = bodyPhaseMatch ? bodyPhaseMatch[2] : null;
|
|
461
|
+
const newPhaseLine = bodyTotal
|
|
462
|
+
? (fmName ? `Phase: ${fmPhase} of ${bodyTotal} (${fmName})` : `Phase: ${fmPhase} of ${bodyTotal}`)
|
|
463
|
+
: `Phase: ${fmPhase}`;
|
|
465
464
|
updated = updated.replace(/^Phase:\s*\d+\s*of\s*\d+.*/m, newPhaseLine);
|
|
466
465
|
needsFix = true;
|
|
467
466
|
}
|
|
@@ -210,9 +210,6 @@ function updateStatePosition(content, updates) {
|
|
|
210
210
|
if (updates.fmCurrentPhase !== undefined) {
|
|
211
211
|
fm = fm.replace(/^(current_phase:\s*).*/m, (_, p) => `${p}${updates.fmCurrentPhase}`);
|
|
212
212
|
}
|
|
213
|
-
if (updates.fmTotalPhases !== undefined) {
|
|
214
|
-
fm = fm.replace(/^(total_phases:\s*).*/m, (_, p) => `${p}${updates.fmTotalPhases}`);
|
|
215
|
-
}
|
|
216
213
|
if (updates.fmPhaseSlug !== undefined) {
|
|
217
214
|
fm = fm.replace(/^(phase_slug:\s*).*/m, (_, p) => `${p}"${updates.fmPhaseSlug}"`);
|
|
218
215
|
}
|
|
@@ -420,7 +417,6 @@ function checkStateSync(data) {
|
|
|
420
417
|
if (currentPhase !== null && currentPhase !== phaseNumInt) {
|
|
421
418
|
stateUpdates.phaseLine = `${phaseNumInt} of ${totalPhases} (${phaseName})`;
|
|
422
419
|
stateUpdates.fmCurrentPhase = phaseNumInt;
|
|
423
|
-
stateUpdates.fmTotalPhases = totalPhases;
|
|
424
420
|
stateUpdates.fmPhaseSlug = phaseSlug;
|
|
425
421
|
stateUpdates.fmPhaseName = phaseName;
|
|
426
422
|
messages.push(`STATE.md: Phase ${currentPhase} → ${phaseNumInt}`);
|
|
@@ -503,7 +499,6 @@ function checkStateSync(data) {
|
|
|
503
499
|
if (currentPhase !== null && currentPhase !== phaseNumInt) {
|
|
504
500
|
stateUpdates.phaseLine = `${phaseNumInt} of ${totalPhases} (${phaseName})`;
|
|
505
501
|
stateUpdates.fmCurrentPhase = phaseNumInt;
|
|
506
|
-
stateUpdates.fmTotalPhases = totalPhases;
|
|
507
502
|
stateUpdates.fmPhaseSlug = phaseSlug;
|
|
508
503
|
stateUpdates.fmPhaseName = phaseName;
|
|
509
504
|
messages.push(`STATE.md: Phase ${currentPhase} → ${phaseNumInt}`);
|
|
@@ -31,7 +31,6 @@ function parseStateMd(content) {
|
|
|
31
31
|
if (frontmatter.version === 2 || frontmatter.current_phase !== undefined) {
|
|
32
32
|
result.format = 'frontmatter';
|
|
33
33
|
result.current_phase = frontmatter.current_phase || null;
|
|
34
|
-
result.total_phases = frontmatter.total_phases || null;
|
|
35
34
|
result.phase_name = frontmatter.phase_slug || frontmatter.phase_name || null;
|
|
36
35
|
result.status = frontmatter.status || null;
|
|
37
36
|
result.progress = frontmatter.progress_percent !== undefined ? frontmatter.progress_percent : null;
|
|
@@ -301,7 +300,6 @@ function stateUpdate(field, value, planningDir) {
|
|
|
301
300
|
'last_activity',
|
|
302
301
|
'progress_percent',
|
|
303
302
|
'phase_slug',
|
|
304
|
-
'total_phases',
|
|
305
303
|
'last_command',
|
|
306
304
|
'blockers'
|
|
307
305
|
];
|
|
@@ -340,7 +338,7 @@ function statePatch(jsonStr, planningDir) {
|
|
|
340
338
|
if (!fs.existsSync(statePath)) return { success: false, error: "STATE.md not found" };
|
|
341
339
|
let fields;
|
|
342
340
|
try { fields = JSON.parse(jsonStr); } catch (_e) { return { success: false, error: "Invalid JSON" }; }
|
|
343
|
-
const validFields = ["current_phase", "status", "plans_complete", "last_activity", "progress_percent", "phase_slug", "
|
|
341
|
+
const validFields = ["current_phase", "status", "plans_complete", "last_activity", "progress_percent", "phase_slug", "last_command", "blockers"];
|
|
344
342
|
const updates = [], errors = [];
|
|
345
343
|
for (const [field, value] of Object.entries(fields)) {
|
|
346
344
|
if (!validFields.includes(field)) { errors.push("Unknown field: " + field); continue; }
|
|
@@ -539,7 +539,7 @@ async function main() {
|
|
|
539
539
|
const field = args[2];
|
|
540
540
|
const value = args[3];
|
|
541
541
|
if (!field || value === undefined) {
|
|
542
|
-
error('Usage: pbr-tools.js state update <field> <value>\nFields: current_phase, status, plans_complete, last_activity, progress_percent, phase_slug,
|
|
542
|
+
error('Usage: pbr-tools.js state update <field> <value>\nFields: current_phase, status, plans_complete, last_activity, progress_percent, phase_slug, last_command, blockers');
|
|
543
543
|
}
|
|
544
544
|
output(stateUpdate(field, value));
|
|
545
545
|
} else if (command === 'config' && subcommand === 'validate') {
|
|
@@ -242,12 +242,11 @@ function buildStatusLine(content, ctxPercent, cfg, stdinData, planningDir) {
|
|
|
242
242
|
// Phase section (always includes brand text)
|
|
243
243
|
if (sections.includes('phase')) {
|
|
244
244
|
const fmPhase = fm && fm.current_phase;
|
|
245
|
-
const fmTotal = fm && fm.total_phases;
|
|
246
245
|
const fmName = fm && fm.phase_name;
|
|
247
246
|
const phaseMatch = content.match(/Phase:\s*(\d+)\s*of\s*(\d+)\s*(?:\(([^)]+)\))?/);
|
|
248
247
|
|
|
249
248
|
const phaseNum = fmPhase || (phaseMatch && phaseMatch[1]);
|
|
250
|
-
const phaseTotal =
|
|
249
|
+
const phaseTotal = phaseMatch && phaseMatch[2];
|
|
251
250
|
const phaseName = fmName || (phaseMatch && phaseMatch[3]);
|
|
252
251
|
|
|
253
252
|
if (phaseNum && phaseTotal) {
|
|
@@ -263,11 +262,11 @@ function buildStatusLine(content, ctxPercent, cfg, stdinData, planningDir) {
|
|
|
263
262
|
// Plan section
|
|
264
263
|
if (sections.includes('plan')) {
|
|
265
264
|
const fmComplete = fm && fm.plans_complete;
|
|
266
|
-
const
|
|
265
|
+
const fmPlansTotal = fm && fm.plans_total;
|
|
267
266
|
const planMatch = content.match(/Plan:\s*(\d+)\s*of\s*(\d+)/);
|
|
268
267
|
|
|
269
268
|
const done = fmComplete != null ? parseInt(fmComplete, 10) : (planMatch ? parseInt(planMatch[1], 10) : null);
|
|
270
|
-
const total =
|
|
269
|
+
const total = fmPlansTotal != null ? parseInt(fmPlansTotal, 10) : (planMatch ? parseInt(planMatch[2], 10) : null);
|
|
271
270
|
|
|
272
271
|
if (done != null && total != null && total > 0) {
|
|
273
272
|
const planColor = done === total ? c.green : c.white;
|
|
@@ -174,7 +174,7 @@ After running all 10 checks and collecting results, if any of the following auto
|
|
|
174
174
|
|
|
175
175
|
| Pattern | Detection | Fix Action |
|
|
176
176
|
|---------|-----------|------------|
|
|
177
|
-
| Missing STATE.md frontmatter | Check 5 finds STATE.md without `---` block | Regenerate frontmatter from ROADMAP.md phase data (current_phase,
|
|
177
|
+
| Missing STATE.md frontmatter | Check 5 finds STATE.md without `---` block | Regenerate frontmatter from ROADMAP.md phase data (current_phase, phase_slug, status) |
|
|
178
178
|
| STATE.md phase_slug mismatch | Check 5/7 finds phase_slug doesn't match current phase directory name | Correct phase_slug to match the actual directory name in `.planning/phases/` |
|
|
179
179
|
| Missing config.json | Check 1/2 finds no `.planning/config.json` | Create with default config template (same as `/pbr:setup` defaults) |
|
|
180
180
|
| Orphaned .active-skill file | Check 10 or general scan finds `.planning/.active-skill` older than 1 hour | Delete the stale `.active-skill` file |
|
|
@@ -53,7 +53,7 @@ Progress: [{progress_bar}] {percent}%
|
|
|
53
53
|
Phase 3 of 10 = 20% → [████░░░░░░░░░░░░░░░░] 20%
|
|
54
54
|
Phase 7 of 10 = 70% → [██████████████░░░░░░] 70%
|
|
55
55
|
```
|
|
56
|
-
Calculation: `filled = Math.round((completed_phases /
|
|
56
|
+
Calculation: `filled = Math.round((completed_phases / phase_count) * 20)` where `phase_count` is derived from ROADMAP.md (available via `stateLoad` as `phase_count`)
|
|
57
57
|
|
|
58
58
|
### 3. Accumulated Context (lines 16-25)
|
|
59
59
|
```
|