@sienklogic/plan-build-run 2.61.0 → 2.62.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 (31) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/package.json +2 -2
  3. package/plugins/copilot-pbr/hooks/hooks.json +24 -48
  4. package/plugins/copilot-pbr/plugin.json +1 -1
  5. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
  6. package/plugins/cursor-pbr/hooks/hooks.json +12 -32
  7. package/plugins/pbr/.claude-plugin/plugin.json +1 -1
  8. package/plugins/pbr/hooks/hooks.json +12 -32
  9. package/plugins/pbr/scripts/check-config-change.js +26 -1
  10. package/plugins/pbr/scripts/check-subagent-output.js +89 -1
  11. package/plugins/pbr/scripts/config-schema.json +24 -0
  12. package/plugins/pbr/scripts/context-bridge.js +59 -0
  13. package/plugins/pbr/scripts/context-budget-check.js +65 -1
  14. package/plugins/pbr/scripts/enforce-pbr-workflow.js +2 -1
  15. package/plugins/pbr/scripts/event-handler.js +49 -1
  16. package/plugins/pbr/scripts/hook-server-client.js +213 -0
  17. package/plugins/pbr/scripts/hook-server.js +334 -0
  18. package/plugins/pbr/scripts/instructions-loaded.js +32 -1
  19. package/plugins/pbr/scripts/log-subagent.js +75 -1
  20. package/plugins/pbr/scripts/log-tool-failure.js +37 -0
  21. package/plugins/pbr/scripts/post-bash-triage.js +20 -1
  22. package/plugins/pbr/scripts/post-write-dispatch.js +117 -88
  23. package/plugins/pbr/scripts/pre-bash-dispatch.js +7 -0
  24. package/plugins/pbr/scripts/progress-tracker.js +112 -3
  25. package/plugins/pbr/scripts/run-hook.js +45 -8
  26. package/plugins/pbr/scripts/session-cleanup.js +36 -1
  27. package/plugins/pbr/scripts/suggest-compact.js +3 -1
  28. package/plugins/pbr/scripts/task-completed.js +35 -1
  29. package/plugins/pbr/scripts/track-context-budget.js +167 -117
  30. package/plugins/pbr/scripts/worktree-create.js +49 -1
  31. package/plugins/pbr/scripts/worktree-remove.js +46 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,25 @@ 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.62.0](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.61.1...plan-build-run-v2.62.0) (2026-03-06)
9
+
10
+
11
+ ### Features
12
+
13
+ * **hook-server:** add GET /context endpoint and SessionStart enrichment ([802253d](https://github.com/SienkLogic/plan-build-run/commit/802253da7af9087a10c8218f762593a2d048cfe1))
14
+ * **hook-server:** add handleHttp to 5 remaining medium-frequency hooks ([41f0cd7](https://github.com/SienkLogic/plan-build-run/commit/41f0cd7e98cf3c1019b42c27afed500b19fe4dd2))
15
+ * **hook-server:** add handleHttp to post-write-dispatch and post-bash-triage ([b4d794f](https://github.com/SienkLogic/plan-build-run/commit/b4d794faff1a588a9016a19ebeb354dfd57f5caa))
16
+ * **hook-server:** add handleHttp to track-context-budget and context-bridge ([8212131](https://github.com/SienkLogic/plan-build-run/commit/8212131a6b057a487a6ee837cb999eeee5d10ebc))
17
+ * **hook-server:** add HTTP hook server and client with JSONL event log ([bf1a15b](https://github.com/SienkLogic/plan-build-run/commit/bf1a15bf8993211db2801af429e9680dd220a521))
18
+ * **hook-server:** complete hook migration — all enrichment hooks export handleHttp ([647561f](https://github.com/SienkLogic/plan-build-run/commit/647561f7c6c863d1ef177b7a3ddc88c0f7c3489f))
19
+
20
+ ## [2.61.1](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.61.0...plan-build-run-v2.61.1) (2026-03-06)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * **hooks:** resolve script path before .planning/ early-exit check ([06487f7](https://github.com/SienkLogic/plan-build-run/commit/06487f78799a521f6d9041dc1323d36bfdf4a1d8))
26
+
8
27
  ## [2.61.0](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.60.0...plan-build-run-v2.61.0) (2026-03-06)
9
28
 
10
29
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sienklogic/plan-build-run",
3
- "version": "2.61.0",
3
+ "version": "2.62.0",
4
4
  "description": "Plan it, Build it, Run it — structured development workflow for Claude Code",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -50,7 +50,7 @@
50
50
  "coverageThreshold": {
51
51
  "global": {
52
52
  "statements": 70,
53
- "branches": 67,
53
+ "branches": 65,
54
54
  "functions": 70,
55
55
  "lines": 70
56
56
  }
@@ -20,8 +20,8 @@
20
20
  "hooks": [
21
21
  {
22
22
  "type": "command",
23
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" instructions-loaded.js",
24
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') instructions-loaded.js",
23
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js instructions-loaded",
24
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js instructions-loaded",
25
25
  "cwd": ".",
26
26
  "timeoutSec": 15
27
27
  }
@@ -33,8 +33,8 @@
33
33
  "hooks": [
34
34
  {
35
35
  "type": "command",
36
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" worktree-create.js",
37
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') worktree-create.js",
36
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js worktree-create",
37
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js worktree-create",
38
38
  "cwd": ".",
39
39
  "timeoutSec": 15
40
40
  }
@@ -46,8 +46,8 @@
46
46
  "hooks": [
47
47
  {
48
48
  "type": "command",
49
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" worktree-remove.js",
50
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') worktree-remove.js",
49
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js worktree-remove",
50
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js worktree-remove",
51
51
  "cwd": ".",
52
52
  "timeoutSec": 15
53
53
  }
@@ -72,20 +72,8 @@
72
72
  "hooks": [
73
73
  {
74
74
  "type": "command",
75
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" check-subagent-output.js",
76
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') check-subagent-output.js",
77
- "cwd": ".",
78
- "timeoutSec": 15
79
- }
80
- ]
81
- },
82
- {
83
- "matcher": "Write|Edit",
84
- "hooks": [
85
- {
86
- "type": "command",
87
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" suggest-compact.js",
88
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') suggest-compact.js",
75
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js check-subagent-output",
76
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js check-subagent-output",
89
77
  "cwd": ".",
90
78
  "timeoutSec": 15
91
79
  }
@@ -133,8 +121,8 @@
133
121
  "hooks": [
134
122
  {
135
123
  "type": "command",
136
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" log-tool-failure.js",
137
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') log-tool-failure.js",
124
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js log-tool-failure",
125
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js log-tool-failure",
138
126
  "cwd": ".",
139
127
  "timeoutSec": 15
140
128
  }
@@ -166,18 +154,6 @@
166
154
  }
167
155
  ]
168
156
  },
169
- {
170
- "matcher": "Bash",
171
- "hooks": [
172
- {
173
- "type": "command",
174
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" check-cross-plugin-sync.js",
175
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') check-cross-plugin-sync.js",
176
- "cwd": ".",
177
- "timeoutSec": 15
178
- }
179
- ]
180
- },
181
157
  {
182
158
  "matcher": "Write|Edit",
183
159
  "hooks": [
@@ -232,8 +208,8 @@
232
208
  "hooks": [
233
209
  {
234
210
  "type": "command",
235
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" context-budget-check.js",
236
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') context-budget-check.js",
211
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js context-budget-check",
212
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js context-budget-check",
237
213
  "cwd": ".",
238
214
  "timeoutSec": 15
239
215
  }
@@ -258,8 +234,8 @@
258
234
  "hooks": [
259
235
  {
260
236
  "type": "command",
261
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" log-subagent.js start",
262
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') log-subagent.js start",
237
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js log-subagent-start",
238
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js log-subagent-start",
263
239
  "cwd": ".",
264
240
  "timeoutSec": 15
265
241
  }
@@ -271,8 +247,8 @@
271
247
  "hooks": [
272
248
  {
273
249
  "type": "command",
274
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" log-subagent.js stop",
275
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') log-subagent.js stop",
250
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js log-subagent",
251
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js log-subagent",
276
252
  "cwd": ".",
277
253
  "timeoutSec": 15
278
254
  }
@@ -282,8 +258,8 @@
282
258
  "hooks": [
283
259
  {
284
260
  "type": "command",
285
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" event-handler.js",
286
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') event-handler.js",
261
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js event-handler",
262
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js event-handler",
287
263
  "cwd": ".",
288
264
  "timeoutSec": 15
289
265
  }
@@ -295,8 +271,8 @@
295
271
  "hooks": [
296
272
  {
297
273
  "type": "command",
298
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" task-completed.js",
299
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') task-completed.js",
274
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js task-completed",
275
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js task-completed",
300
276
  "cwd": ".",
301
277
  "timeoutSec": 15
302
278
  }
@@ -308,8 +284,8 @@
308
284
  "hooks": [
309
285
  {
310
286
  "type": "command",
311
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" check-config-change.js",
312
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') check-config-change.js",
287
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js check-config-change",
288
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js check-config-change",
313
289
  "cwd": ".",
314
290
  "timeoutSec": 15
315
291
  }
@@ -321,8 +297,8 @@
321
297
  "hooks": [
322
298
  {
323
299
  "type": "command",
324
- "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" session-cleanup.js",
325
- "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') session-cleanup.js",
300
+ "bash": "node \"$(cd \"$(dirname \"$0\")\" && pwd)/../../pbr/scripts/run-hook.js\" hook-server-client.js session-cleanup",
301
+ "powershell": "node (Join-Path (Split-Path -Parent $PSScriptRoot) 'pbr\\scripts\\run-hook.js') hook-server-client.js session-cleanup",
326
302
  "cwd": ".",
327
303
  "timeoutSec": 30
328
304
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pbr",
3
3
  "displayName": "Plan-Build-Run",
4
- "version": "2.61.0",
4
+ "version": "2.62.0",
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",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pbr",
3
3
  "displayName": "Plan-Build-Run",
4
- "version": "2.61.0",
4
+ "version": "2.62.0",
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",
@@ -18,7 +18,7 @@
18
18
  "hooks": [
19
19
  {
20
20
  "type": "command",
21
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" instructions-loaded.js",
21
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js instructions-loaded",
22
22
  "statusMessage": "Detecting instruction reload..."
23
23
  }
24
24
  ]
@@ -29,7 +29,7 @@
29
29
  "hooks": [
30
30
  {
31
31
  "type": "command",
32
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" worktree-create.js",
32
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js worktree-create",
33
33
  "statusMessage": "Initializing worktree .planning/..."
34
34
  }
35
35
  ]
@@ -40,7 +40,7 @@
40
40
  "hooks": [
41
41
  {
42
42
  "type": "command",
43
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" worktree-remove.js",
43
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js worktree-remove",
44
44
  "statusMessage": "Cleaning up worktree state..."
45
45
  }
46
46
  ]
@@ -62,21 +62,11 @@
62
62
  "hooks": [
63
63
  {
64
64
  "type": "command",
65
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" check-subagent-output.js",
65
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js check-subagent-output",
66
66
  "statusMessage": "Validating agent output..."
67
67
  }
68
68
  ]
69
69
  },
70
- {
71
- "matcher": "Write|Edit",
72
- "hooks": [
73
- {
74
- "type": "command",
75
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" suggest-compact.js",
76
- "statusMessage": "Checking context budget..."
77
- }
78
- ]
79
- },
80
70
  {
81
71
  "matcher": "Bash",
82
72
  "hooks": [
@@ -113,7 +103,7 @@
113
103
  "hooks": [
114
104
  {
115
105
  "type": "command",
116
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" log-tool-failure.js",
106
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js log-tool-failure",
117
107
  "statusMessage": "Logging tool failure..."
118
108
  }
119
109
  ]
@@ -140,16 +130,6 @@
140
130
  }
141
131
  ]
142
132
  },
143
- {
144
- "matcher": "Bash",
145
- "hooks": [
146
- {
147
- "type": "command",
148
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" check-cross-plugin-sync.js",
149
- "statusMessage": "Checking cross-plugin sync..."
150
- }
151
- ]
152
- },
153
133
  {
154
134
  "matcher": "Write|Edit",
155
135
  "hooks": [
@@ -196,7 +176,7 @@
196
176
  "hooks": [
197
177
  {
198
178
  "type": "command",
199
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" context-budget-check.js",
179
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js context-budget-check",
200
180
  "statusMessage": "Preserving state before compaction..."
201
181
  }
202
182
  ]
@@ -218,7 +198,7 @@
218
198
  "hooks": [
219
199
  {
220
200
  "type": "command",
221
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" log-subagent.js start",
201
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js log-subagent-start",
222
202
  "statusMessage": "Logging agent spawn..."
223
203
  }
224
204
  ]
@@ -229,7 +209,7 @@
229
209
  "hooks": [
230
210
  {
231
211
  "type": "command",
232
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" log-subagent.js stop",
212
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js log-subagent",
233
213
  "statusMessage": "Logging agent completion..."
234
214
  }
235
215
  ]
@@ -238,7 +218,7 @@
238
218
  "hooks": [
239
219
  {
240
220
  "type": "command",
241
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" event-handler.js",
221
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js event-handler",
242
222
  "statusMessage": "Checking for auto-verification..."
243
223
  }
244
224
  ]
@@ -249,7 +229,7 @@
249
229
  "hooks": [
250
230
  {
251
231
  "type": "command",
252
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" task-completed.js",
232
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js task-completed",
253
233
  "statusMessage": "Processing task completion..."
254
234
  }
255
235
  ]
@@ -260,7 +240,7 @@
260
240
  "hooks": [
261
241
  {
262
242
  "type": "command",
263
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" check-config-change.js",
243
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js check-config-change",
264
244
  "statusMessage": "Validating configuration..."
265
245
  }
266
246
  ]
@@ -271,7 +251,7 @@
271
251
  "hooks": [
272
252
  {
273
253
  "type": "command",
274
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" session-cleanup.js",
254
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'..','pbr','scripts','run-hook.js'))\" hook-server-client.js session-cleanup",
275
255
  "statusMessage": "Cleaning up session..."
276
256
  }
277
257
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pbr",
3
- "version": "2.61.0",
3
+ "version": "2.62.0",
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",
@@ -23,7 +23,7 @@
23
23
  "hooks": [
24
24
  {
25
25
  "type": "command",
26
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" instructions-loaded.js",
26
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js instructions-loaded",
27
27
  "statusMessage": "Detecting instruction reload..."
28
28
  }
29
29
  ]
@@ -34,7 +34,7 @@
34
34
  "hooks": [
35
35
  {
36
36
  "type": "command",
37
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" worktree-create.js",
37
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js worktree-create",
38
38
  "statusMessage": "Initializing worktree .planning/..."
39
39
  }
40
40
  ]
@@ -45,7 +45,7 @@
45
45
  "hooks": [
46
46
  {
47
47
  "type": "command",
48
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" worktree-remove.js",
48
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js worktree-remove",
49
49
  "statusMessage": "Cleaning up worktree state..."
50
50
  }
51
51
  ]
@@ -67,21 +67,11 @@
67
67
  "hooks": [
68
68
  {
69
69
  "type": "command",
70
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" check-subagent-output.js",
70
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js check-subagent-output",
71
71
  "statusMessage": "Validating agent output..."
72
72
  }
73
73
  ]
74
74
  },
75
- {
76
- "matcher": "Write|Edit",
77
- "hooks": [
78
- {
79
- "type": "command",
80
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" suggest-compact.js",
81
- "statusMessage": "Checking context budget..."
82
- }
83
- ]
84
- },
85
75
  {
86
76
  "matcher": "Bash",
87
77
  "hooks": [
@@ -118,7 +108,7 @@
118
108
  "hooks": [
119
109
  {
120
110
  "type": "command",
121
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" log-tool-failure.js",
111
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js log-tool-failure",
122
112
  "statusMessage": "Logging tool failure..."
123
113
  }
124
114
  ]
@@ -145,16 +135,6 @@
145
135
  }
146
136
  ]
147
137
  },
148
- {
149
- "matcher": "Bash",
150
- "hooks": [
151
- {
152
- "type": "command",
153
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" check-cross-plugin-sync.js",
154
- "statusMessage": "Checking cross-plugin sync..."
155
- }
156
- ]
157
- },
158
138
  {
159
139
  "matcher": "Write|Edit",
160
140
  "hooks": [
@@ -201,7 +181,7 @@
201
181
  "hooks": [
202
182
  {
203
183
  "type": "command",
204
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" context-budget-check.js",
184
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js context-budget-check",
205
185
  "statusMessage": "Preserving state before compaction..."
206
186
  }
207
187
  ]
@@ -223,7 +203,7 @@
223
203
  "hooks": [
224
204
  {
225
205
  "type": "command",
226
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" log-subagent.js start",
206
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js log-subagent-start",
227
207
  "statusMessage": "Logging agent spawn..."
228
208
  }
229
209
  ]
@@ -234,7 +214,7 @@
234
214
  "hooks": [
235
215
  {
236
216
  "type": "command",
237
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" log-subagent.js stop",
217
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js log-subagent",
238
218
  "statusMessage": "Logging agent completion..."
239
219
  }
240
220
  ]
@@ -243,7 +223,7 @@
243
223
  "hooks": [
244
224
  {
245
225
  "type": "command",
246
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" event-handler.js",
226
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js event-handler",
247
227
  "statusMessage": "Checking for auto-verification..."
248
228
  }
249
229
  ]
@@ -254,7 +234,7 @@
254
234
  "hooks": [
255
235
  {
256
236
  "type": "command",
257
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" task-completed.js",
237
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js task-completed",
258
238
  "statusMessage": "Processing task completion..."
259
239
  }
260
240
  ]
@@ -265,7 +245,7 @@
265
245
  "hooks": [
266
246
  {
267
247
  "type": "command",
268
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" check-config-change.js",
248
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js check-config-change",
269
249
  "statusMessage": "Validating configuration..."
270
250
  }
271
251
  ]
@@ -276,7 +256,7 @@
276
256
  "hooks": [
277
257
  {
278
258
  "type": "command",
279
- "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" session-cleanup.js",
259
+ "command": "node -e \"var r=process.env.CLAUDE_PLUGIN_ROOT||'',m=r.match(/^\\/([a-zA-Z])\\/(.*)/);if(m)r=m[1]+String.fromCharCode(58)+String.fromCharCode(92)+m[2];require(require('path').resolve(r,'scripts','run-hook.js'))\" hook-server-client.js session-cleanup",
280
260
  "statusMessage": "Cleaning up session..."
281
261
  }
282
262
  ]
@@ -159,5 +159,30 @@ async function main() {
159
159
  process.exit(0);
160
160
  }
161
161
 
162
+ /**
163
+ * handleHttp — hook-server.js interface.
164
+ * reqBody = { event, tool, data, planningDir, cache }
165
+ * Returns { additionalContext: "..." } or null. Never calls process.exit().
166
+ */
167
+ function handleHttp(reqBody) {
168
+ const planningDir = (reqBody && reqBody.planningDir) || findPlanningDir();
169
+ if (!planningDir) return null;
170
+
171
+ const configPath = path.join(planningDir, 'config.json');
172
+ if (!fs.existsSync(configPath)) return null;
173
+
174
+ const warnings = validateConfig(configPath);
175
+ if (warnings.length > 0) {
176
+ const msg = `\u26a0\ufe0f Config validation (${warnings.length} issue${warnings.length > 1 ? 's' : ''}):\n${warnings.map(w => ` - ${w}`).join('\n')}`;
177
+ logHook('check-config-change', 'ConfigChange', 'warn', { warnings });
178
+ logEvent('workflow', 'config-change', { warnings });
179
+ return { additionalContext: msg };
180
+ }
181
+
182
+ logHook('check-config-change', 'ConfigChange', 'ok', {});
183
+ logEvent('workflow', 'config-change', { status: 'valid' });
184
+ return null;
185
+ }
186
+
162
187
  if (require.main === module || process.argv[1] === __filename) main();
163
- module.exports = { validateConfig, findPlanningDir };
188
+ module.exports = { validateConfig, findPlanningDir, handleHttp };