@sienklogic/plan-build-run 2.19.1 → 2.19.2

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 (116) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/CLAUDE.md +29 -16
  3. package/README.md +3 -3
  4. package/dashboard/server/index.js +10 -1
  5. package/dashboard/server/routes/agents.js +23 -2
  6. package/dashboard/server/routes/health.js +7 -4
  7. package/dashboard/server/routes/telemetry.js +20 -1
  8. package/dashboard/server/services/planning-reader.js +3 -17
  9. package/package.json +1 -1
  10. package/plan-build-run/bin/config-schema.json +23 -145
  11. package/plugins/pbr/.claude-plugin/plugin.json +1 -1
  12. package/plugins/pbr/agents/advisor-researcher.md +1 -0
  13. package/plugins/pbr/agents/debugger.md +0 -4
  14. package/plugins/pbr/agents/researcher.md +0 -4
  15. package/plugins/pbr/agents/synthesizer.md +0 -4
  16. package/plugins/pbr/dist/check-config-change.js +0 -7
  17. package/plugins/pbr/dist/check-cross-plugin-sync.js +1 -1
  18. package/plugins/pbr/dist/check-plan-format.js +0 -32
  19. package/plugins/pbr/dist/check-roadmap-sync.js +15 -11
  20. package/plugins/pbr/dist/check-subagent-output.js +4 -60
  21. package/plugins/pbr/dist/check-summary-gate.js +3 -14
  22. package/plugins/pbr/dist/feedback-loop.js +12 -29
  23. package/plugins/pbr/dist/hook-server.js +58 -6
  24. package/plugins/pbr/dist/milestone-learnings.js +6 -56
  25. package/plugins/pbr/dist/pbr-tools.js +8 -91
  26. package/plugins/pbr/dist/post-bash-triage.js +5 -63
  27. package/plugins/pbr/dist/post-hoc.js +3 -52
  28. package/plugins/pbr/dist/post-write-dispatch.js +0 -36
  29. package/plugins/pbr/dist/pre-bash-dispatch.js +1 -7
  30. package/plugins/pbr/dist/pre-task-dispatch.js +0 -28
  31. package/plugins/pbr/dist/progress-tracker.js +2 -27
  32. package/plugins/pbr/dist/session-cleanup.js +1 -31
  33. package/plugins/pbr/dist/status-line.js +13 -11
  34. package/plugins/pbr/dist/suggest-compact.js +2 -10
  35. package/plugins/pbr/dist/validate-commit.js +8 -64
  36. package/plugins/pbr/dist/validate-task.js +0 -30
  37. package/plugins/pbr/references/config-reference.md +0 -96
  38. package/plugins/pbr/scripts/audit-checks/si-agent-hook-config-checks.js +2 -72
  39. package/plugins/pbr/scripts/audit-checks/workflow-compliance.js +5 -41
  40. package/plugins/pbr/scripts/check-config-change.js +0 -7
  41. package/plugins/pbr/scripts/check-cross-plugin-sync.js +1 -1
  42. package/plugins/pbr/scripts/check-plan-format.js +0 -32
  43. package/plugins/pbr/scripts/check-roadmap-sync.js +15 -11
  44. package/plugins/pbr/scripts/check-subagent-output.js +4 -60
  45. package/plugins/pbr/scripts/check-summary-gate.js +3 -14
  46. package/plugins/pbr/scripts/config-schema.json +16 -129
  47. package/plugins/pbr/scripts/feedback-loop.js +12 -29
  48. package/plugins/pbr/scripts/hook-server.js +58 -6
  49. package/plugins/pbr/scripts/lib/config.js +4 -11
  50. package/plugins/pbr/scripts/lib/contextual-help.js +5 -29
  51. package/plugins/pbr/scripts/lib/format-validators.js +1 -26
  52. package/plugins/pbr/scripts/lib/frontmatter.js +4 -4
  53. package/plugins/pbr/scripts/lib/gates/rich-agent-context.js +13 -19
  54. package/plugins/pbr/scripts/lib/health.js +4 -5
  55. package/plugins/pbr/scripts/lib/help.js +3 -54
  56. package/plugins/pbr/scripts/lib/phase.js +2 -4
  57. package/plugins/pbr/scripts/lib/pre-commit-checks.js +1 -1
  58. package/plugins/pbr/scripts/lib/pre-research.js +10 -17
  59. package/plugins/pbr/scripts/lib/roadmap.js +11 -35
  60. package/plugins/pbr/scripts/lib/smart-next-task.js +11 -20
  61. package/plugins/pbr/scripts/lib/spot-check.js +3 -106
  62. package/plugins/pbr/scripts/lib/state.js +25 -130
  63. package/plugins/pbr/scripts/lib/verify.js +56 -46
  64. package/plugins/pbr/scripts/milestone-learnings.js +6 -56
  65. package/plugins/pbr/scripts/pbr-tools.js +8 -91
  66. package/plugins/pbr/scripts/post-bash-triage.js +5 -63
  67. package/plugins/pbr/scripts/post-hoc.js +3 -52
  68. package/plugins/pbr/scripts/post-write-dispatch.js +0 -36
  69. package/plugins/pbr/scripts/pre-bash-dispatch.js +1 -7
  70. package/plugins/pbr/scripts/pre-task-dispatch.js +0 -28
  71. package/plugins/pbr/scripts/progress-tracker.js +2 -27
  72. package/plugins/pbr/scripts/session-cleanup.js +1 -31
  73. package/plugins/pbr/scripts/status-line.js +13 -11
  74. package/plugins/pbr/scripts/suggest-compact.js +2 -10
  75. package/plugins/pbr/scripts/test/state.test.js +5 -13
  76. package/plugins/pbr/scripts/validate-commit.js +8 -64
  77. package/plugins/pbr/scripts/validate-task.js +0 -30
  78. package/plugins/pbr/skills/begin/SKILL.md +1 -0
  79. package/plugins/pbr/skills/begin/templates/config.json.tmpl +0 -4
  80. package/plugins/pbr/skills/build/SKILL.md +6 -6
  81. package/plugins/pbr/skills/config/SKILL.md +1 -0
  82. package/plugins/pbr/skills/help/SKILL.md +1 -0
  83. package/plugins/pbr/skills/pause/SKILL.md +1 -0
  84. package/plugins/pbr/skills/profile-user/SKILL.md +1 -0
  85. package/plugins/pbr/skills/quick/SKILL.md +2 -1
  86. package/plugins/pbr/skills/resume/SKILL.md +1 -0
  87. package/plugins/pbr/skills/scan/SKILL.md +1 -0
  88. package/plugins/pbr/skills/setup/SKILL.md +1 -0
  89. package/plugins/pbr/skills/shared/state-update.md +2 -2
  90. package/plugins/pbr/skills/status/SKILL.md +1 -0
  91. package/plugins/pbr/references/behavioral-contexts.md +0 -53
  92. package/plugins/pbr/scripts/lib/autonomy.js +0 -91
  93. package/plugins/pbr/scripts/lib/circuit-state.js +0 -133
  94. package/plugins/pbr/scripts/lib/completion.js +0 -377
  95. package/plugins/pbr/scripts/lib/hypothesis-runner.js +0 -127
  96. package/plugins/pbr/scripts/lib/local-llm/client.js +0 -237
  97. package/plugins/pbr/scripts/lib/local-llm/health.js +0 -12
  98. package/plugins/pbr/scripts/lib/local-llm/index.js +0 -89
  99. package/plugins/pbr/scripts/lib/local-llm/metrics.js +0 -20
  100. package/plugins/pbr/scripts/lib/local-llm/operations/classify-artifact.js +0 -4
  101. package/plugins/pbr/scripts/lib/local-llm/operations/classify-commit.js +0 -4
  102. package/plugins/pbr/scripts/lib/local-llm/operations/classify-error.js +0 -4
  103. package/plugins/pbr/scripts/lib/local-llm/operations/classify-file-intent.js +0 -4
  104. package/plugins/pbr/scripts/lib/local-llm/operations/score-source.js +0 -72
  105. package/plugins/pbr/scripts/lib/local-llm/operations/summarize-context.js +0 -62
  106. package/plugins/pbr/scripts/lib/local-llm/operations/triage-test-output.js +0 -12
  107. package/plugins/pbr/scripts/lib/local-llm/operations/validate-task.js +0 -4
  108. package/plugins/pbr/scripts/lib/local-llm/router.js +0 -101
  109. package/plugins/pbr/scripts/lib/local-llm/shadow.js +0 -60
  110. package/plugins/pbr/scripts/lib/local-llm/threshold-tuner.js +0 -118
  111. package/plugins/pbr/scripts/lib/team-composer.js +0 -87
  112. package/plugins/pbr/scripts/lib/team-coordinator.js +0 -153
  113. package/plugins/pbr/scripts/lib/template.js +0 -222
  114. package/plugins/pbr/scripts/lib/test-cache.js +0 -54
  115. package/plugins/pbr/scripts/lib/trust-gate.js +0 -84
  116. package/plugins/pbr/scripts/lib/wiring-check.js +0 -196
@@ -24,7 +24,6 @@ const { logHook, getLogFilename: getHooksFilename, cleanOldHookLogs } = require(
24
24
  const { getLogFilename: getEventsFilename, cleanOldEventLogs } = require('./event-logger');
25
25
  const { tailLines, configLoad } = require('./pbr-tools');
26
26
  const { removeSessionDir, releaseSessionClaims } = require('./lib/core');
27
- const { readSessionMetrics, summarizeMetrics, formatSessionSummary } = require('./lib/local-llm/metrics');
28
27
  const { writeSnapshot } = require('./lib/snapshot-manager');
29
28
 
30
29
  function readStdin() {
@@ -492,35 +491,6 @@ function main() {
492
491
  }
493
492
  } catch (_e) { /* metrics display is best-effort */ }
494
493
 
495
- // Local LLM metrics summary (SessionEnd — sync reads only, never throws)
496
- let llmAdditionalContext = null;
497
- try {
498
- const sessionStartFile = path.join(planningDir, '.session-start');
499
- if (fs.existsSync(sessionStartFile)) {
500
- const sessionStartTime = fs.readFileSync(sessionStartFile, 'utf8').trim();
501
- const entries = readSessionMetrics(planningDir, sessionStartTime);
502
- if (entries.length > 0) {
503
- const summary = summarizeMetrics(entries);
504
- logHook('session-cleanup', 'SessionEnd', 'llm-metrics', {
505
- total_calls: summary.total_calls,
506
- fallback_count: summary.fallback_count,
507
- avg_latency_ms: summary.avg_latency_ms,
508
- tokens_saved: summary.tokens_saved,
509
- cost_saved_usd: summary.cost_saved_usd
510
- });
511
- if (summary.total_calls > 0) {
512
- let modelName = null;
513
- try {
514
- const rawConfig = configLoad(planningDir) || {};
515
- modelName = (rawConfig.local_llm && rawConfig.local_llm.model) || null;
516
- } catch (_e) { /* config read failure is non-fatal */ }
517
- llmAdditionalContext = formatSessionSummary(summary, modelName);
518
- }
519
- }
520
- // Clean up session-start file
521
- try { fs.unlinkSync(sessionStartFile); } catch (_e) { /* non-fatal */ }
522
- }
523
- } catch (_e) { /* metrics never crash the hook */ }
524
494
 
525
495
  // Surface compliance violations from this session
526
496
  let complianceContext = null;
@@ -568,7 +538,7 @@ function main() {
568
538
  // Snapshot failure must never crash SessionEnd
569
539
  }
570
540
 
571
- const combinedContext = [metricsContext, llmAdditionalContext, complianceContext].filter(Boolean).join('\n');
541
+ const combinedContext = [metricsContext, complianceContext].filter(Boolean).join('\n');
572
542
  if (combinedContext) {
573
543
  process.stdout.write(JSON.stringify({ additionalContext: combinedContext }) + '\n');
574
544
  }
@@ -16,6 +16,7 @@ const cp = require('child_process');
16
16
  const { logHook } = require('./hook-logger');
17
17
  const { configLoad } = require('./pbr-tools');
18
18
  const { resolveSessionPath } = require('./lib/core');
19
+ const { extractFrontmatter } = require('./lib/frontmatter');
19
20
  // ANSI color codes
20
21
  const c = {
21
22
  reset: '\x1b[0m',
@@ -542,26 +543,27 @@ function main() {
542
543
 
543
544
  /**
544
545
  * Parse YAML frontmatter from STATE.md content.
545
- * Returns an object with frontmatter fields, or null if no frontmatter.
546
+ * Thin adapter around canonical extractFrontmatter preserving null-on-missing
547
+ * and filtering out null/undefined string values for status-line display.
546
548
  */
547
- function parseFrontmatter(content) {
549
+ const parseFrontmatter = (content) => {
548
550
  if (!content.startsWith('---')) return null;
549
551
  const endIdx = content.indexOf('---', 3);
550
552
  if (endIdx === -1) return null;
551
- const fm = content.substring(3, endIdx);
553
+ const raw = extractFrontmatter(content);
552
554
  const result = {};
553
- for (const line of fm.split(/\r?\n/)) {
554
- const m = line.match(/^(\w[\w_]*):\s*"?([^"]*)"?\s*$/);
555
- if (m) {
556
- const val = m[2].trim();
557
- // Skip YAML nulls and empty values — they'd render as literal "null"
558
- if (val && val !== 'null' && val !== 'undefined') {
559
- result[m[1]] = val;
555
+ for (const [key, val] of Object.entries(raw)) {
556
+ if (typeof val === 'object') {
557
+ // Keep objects/arrays (non-empty)
558
+ if (Array.isArray(val) ? val.length > 0 : Object.keys(val).length > 0) {
559
+ result[key] = val;
560
560
  }
561
+ } else if (typeof val === 'string' && val && val !== 'null' && val !== 'undefined') {
562
+ result[key] = val;
561
563
  }
562
564
  }
563
565
  return result;
564
- }
566
+ };
565
567
 
566
568
  function buildStatusLine(content, ctxPercent, cfg, stdinData, planningDir) {
567
569
  const config = cfg || DEFAULTS;
@@ -9,7 +9,7 @@
9
9
  * fresh (<60s old). CRITICAL tier always emits; others use REMINDER_INTERVAL debounce.
10
10
  *
11
11
  * Fallback: when bridge is absent or stale, uses call-count threshold.
12
- * Counter stored in .planning/.compact-counter (JSON).
12
+ * Counter stored in .planning/.compact-counter (JSON) and .session.json.
13
13
  * Threshold configurable via config.json hooks.compactThreshold (default: 50).
14
14
  * Counter resets on SessionStart (via progress-tracker.js).
15
15
  *
@@ -281,15 +281,7 @@ function resetCounter(planningDir, sessionId) {
281
281
  sessionSave(planningDir, { compactCounter: { count: 0, lastSuggested: 0 } }, sessionId);
282
282
  } catch (_e) { /* best-effort */ }
283
283
 
284
- // Legacy: also delete .compact-counter file if present
285
- const counterPath = path.join(planningDir, '.compact-counter');
286
- try {
287
- if (fs.existsSync(counterPath)) {
288
- fs.unlinkSync(counterPath);
289
- }
290
- } catch (_e) {
291
- // Best-effort
292
- }
284
+ // .compact-counter cleanup removed -- legacy file no longer used
293
285
  }
294
286
 
295
287
  /**
@@ -66,19 +66,11 @@ describe('parseStateMd', () => {
66
66
  assert.strictEqual(crlfResult.plans_complete, lfResult.plans_complete);
67
67
  });
68
68
 
69
- it('parses legacy v1 format correctly', () => {
70
- // Suppress the deprecation warning to stderr
71
- const origWrite = process.stderr.write;
72
- process.stderr.write = () => true;
73
- try {
74
- const result = parseStateMd(STATE_V1);
75
- assert.strictEqual(result.format, 'legacy');
76
- assert.strictEqual(result.current_phase, 2);
77
- assert.strictEqual(result.status, 'planned');
78
- assert.strictEqual(result.progress, 20);
79
- } finally {
80
- process.stderr.write = origWrite;
81
- }
69
+ it('returns nulls for v1 format (no longer parsed)', () => {
70
+ const content = '# State\n\nPhase: 2 of 6\nStatus: built\nProgress: 33%\n';
71
+ const result = parseStateMd(content);
72
+ expect(result.format).toBe('frontmatter');
73
+ expect(result.current_phase).toBeNull();
82
74
  });
83
75
 
84
76
  it('returns defaults for empty content', () => {
@@ -26,8 +26,6 @@ const path = require('path');
26
26
  const { execSync } = require('child_process');
27
27
  const { logHook } = require('./hook-logger');
28
28
  const { logEvent } = require('./event-logger');
29
- const { resolveConfig } = require('./lib/local-llm/health');
30
- const { classifyCommit } = require('./lib/local-llm/operations/classify-commit');
31
29
 
32
30
  const VALID_TYPES = ['feat', 'fix', 'refactor', 'test', 'docs', 'chore', 'wip', 'revert', 'perf', 'ci', 'build'];
33
31
 
@@ -75,7 +73,13 @@ function checkAiCoAuthorResult(command, sessionId) {
75
73
 
76
74
  function checkSensitiveFilesResult(sessionId) {
77
75
  try {
78
- const output = execSync('git diff --cached --name-only', { encoding: 'utf8' });
76
+ let output;
77
+ try {
78
+ output = execSync('git diff --cached --name-only', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
79
+ } catch (_e) {
80
+ // git diff --cached fails during git tag or in --no-index contexts
81
+ return null;
82
+ }
79
83
  const files = output.trim().split('\n').filter(Boolean);
80
84
 
81
85
  const matched = files.filter((file) => {
@@ -157,58 +161,6 @@ function checkCommit(data) {
157
161
  return null;
158
162
  }
159
163
 
160
- /**
161
- * Load and resolve the local_llm config block from .planning/config.json.
162
- * Returns a resolved config (always safe to use — disabled by default on error).
163
- */
164
- function loadLocalLlmConfig(cwd) {
165
- try {
166
- const configPath = path.join(cwd || process.cwd(), '.planning', 'config.json');
167
- const parsed = JSON.parse(fs.readFileSync(configPath, 'utf8'));
168
- return resolveConfig(parsed.local_llm);
169
- } catch (_e) {
170
- return resolveConfig(undefined);
171
- }
172
- }
173
-
174
- /**
175
- * Async LLM enrichment for commit messages. Returns an advisory string or null.
176
- * Called after checkCommit passes (valid format) to provide semantic classification.
177
- *
178
- * @param {object} data - parsed hook data
179
- * @returns {Promise<string|null>}
180
- */
181
- async function enrichCommitLlm(data) {
182
- try {
183
- const command = data.tool_input?.command || '';
184
- const message = extractCommitMessage(command);
185
- if (!message) return null;
186
-
187
- const cwd = process.cwd();
188
- const llmConfig = loadLocalLlmConfig(cwd);
189
- const planningDir = path.join(cwd, '.planning');
190
-
191
- // Get staged files for scope validation
192
- let stagedFiles = [];
193
- try {
194
- const output = execSync('git diff --cached --name-only', { encoding: 'utf8' });
195
- stagedFiles = output.trim().split('\n').filter(Boolean);
196
- } catch (_e) {
197
- // Not in a git repo — skip staged files context
198
- }
199
-
200
- const llmResult = await classifyCommit(llmConfig, planningDir, message, stagedFiles, data.session_id);
201
- if (llmResult && llmResult.classification !== 'correct') {
202
- return 'LLM commit advisory: ' + llmResult.classification +
203
- ' (confidence: ' + (llmResult.confidence * 100).toFixed(0) + '%)';
204
- }
205
- return null;
206
- } catch (_llmErr) {
207
- // Never propagate LLM errors
208
- return null;
209
- }
210
- }
211
-
212
164
  function main() {
213
165
  let input = '';
214
166
 
@@ -223,14 +175,6 @@ function main() {
223
175
  process.exit(result.exitCode);
224
176
  }
225
177
 
226
- // LLM semantic classification — advisory only (after format validation passes)
227
- const llmAdvisory = await enrichCommitLlm(data);
228
- if (llmAdvisory) {
229
- process.stdout.write(JSON.stringify({
230
- additionalContext: '[pbr] ' + llmAdvisory
231
- }));
232
- }
233
-
234
178
  process.exit(0);
235
179
  } catch (_e) {
236
180
  // Parse error - don't block
@@ -267,5 +211,5 @@ function extractCommitMessage(command) {
267
211
  return null;
268
212
  }
269
213
 
270
- module.exports = { checkCommit, enrichCommitLlm };
214
+ module.exports = { checkCommit };
271
215
  if (require.main === module || process.argv[1] === __filename) { main(); }
@@ -20,8 +20,6 @@
20
20
  const fs = require('fs');
21
21
  const path = require('path');
22
22
  const { logHook } = require('./hook-logger');
23
- const { resolveConfig } = require('./lib/local-llm/health');
24
- const { validateTask: llmValidateTask } = require('./lib/local-llm/operations/validate-task');
25
23
  const { checkNonPbrAgent } = require('./enforce-pbr-workflow');
26
24
  const { KNOWN_AGENTS } = require('./lib/core');
27
25
 
@@ -39,21 +37,6 @@ const { checkDebuggerAdvisory, checkCheckpointManifest, checkActiveSkillIntegrit
39
37
  const { checkDocExistence } = require('./lib/gates/doc-existence');
40
38
  const { checkUserConfirmationGate } = require('./lib/gates/user-confirmation');
41
39
 
42
- /**
43
- * Load and resolve the local_llm config block from .planning/config.json.
44
- * Returns a resolved config (always safe to use — disabled by default on error).
45
- * @param {string} cwd - working directory to resolve .planning/config.json from
46
- */
47
- function loadLocalLlmConfig(cwd) {
48
- try {
49
- const configPath = path.join(cwd, '.planning', 'config.json');
50
- const parsed = JSON.parse(fs.readFileSync(configPath, 'utf8'));
51
- return resolveConfig(parsed.local_llm);
52
- } catch (_e) {
53
- return resolveConfig(undefined);
54
- }
55
- }
56
-
57
40
  const MAX_DESCRIPTION_LENGTH = 100;
58
41
 
59
42
  /**
@@ -264,19 +247,6 @@ function main() {
264
247
  if (nonPbrAgentResult) warnings.push(nonPbrAgentResult.output.additionalContext);
265
248
  if (planValGate && planValGate.warning) warnings.push(planValGate.warning);
266
249
 
267
- // LLM task coherence check — advisory only
268
- try {
269
- const llmCwd = process.env.PBR_PROJECT_ROOT || process.cwd();
270
- const llmConfig = loadLocalLlmConfig(llmCwd);
271
- const planningDir = path.join(llmCwd, '.planning');
272
- const llmResult = await llmValidateTask(llmConfig, planningDir, data.tool_input || {}, data.session_id);
273
- if (llmResult && !llmResult.coherent) {
274
- warnings.push('LLM task coherence advisory: ' + (llmResult.issue || 'Task description may not match intended operation.') + ' (confidence: ' + (llmResult.confidence * 100).toFixed(0) + '%)');
275
- }
276
- } catch (_llmErr) {
277
- // Never propagate LLM errors
278
- }
279
-
280
250
  if (warnings.length > 0) {
281
251
  for (const warning of warnings) {
282
252
  logHook('validate-task', 'PreToolUse', 'warn', { warning });
@@ -2,6 +2,7 @@
2
2
  name: begin
3
3
  description: "Start a new project. Deep questioning, research, requirements, and roadmap."
4
4
  allowed-tools: Read, Write, Bash, Glob, Grep, WebFetch, WebSearch, Task, AskUserQuestion
5
+ argument-hint: "[--auto]"
5
6
  ---
6
7
 
7
8
  **STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes ~7,600 tokens. Begin executing Step 1 immediately.**
@@ -378,7 +378,6 @@
378
378
  "debug.max_hypothesis_rounds: 1-20 — max hypothesis cycles for /pbr:debug",
379
379
  "depth_profiles: override built-in quick/standard/comprehensive defaults",
380
380
  "developer_profile: behavioral profiling from session history + prompt injection",
381
- "(DEPRECATED) local_llm: offload classification tasks to local Ollama instance — removed in v14.0",
382
381
  "prd.auto_extract: skip confirmation gate during PRD import",
383
382
  "spinner_tips: custom messages shown during agent execution",
384
383
  "status_line: status bar appearance (sections, branding, context bar)",
@@ -398,9 +397,6 @@
398
397
  "enabled": false,
399
398
  "inject_prompts": false
400
399
  },
401
- "local_llm": {
402
- "enabled": false
403
- },
404
400
  "prd": {
405
401
  "auto_extract": false
406
402
  },
@@ -749,13 +749,13 @@ For each plan that completed successfully in this wave:
749
749
 
750
750
  **Skip if** `features.security_scanning` is not `true` in `.planning/config.json`.
751
751
 
752
- Run an OWASP-style security scan over the files changed during this wave using the patterns in `plan-build-run/bin/lib/security-scan.cjs`.
752
+ Run an OWASP-style security scan over the files changed during this wave using the patterns in `plugins/pbr/scripts/lib/security-scan.js`.
753
753
 
754
754
  ```bash
755
755
  node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js security scan '{space-separated changed files}'
756
756
  ```
757
757
 
758
- (`scanFiles()` in `plan-build-run/bin/lib/security-scan.cjs`)
758
+ (`scanFiles()` in `plugins/pbr/scripts/lib/security-scan.js`)
759
759
 
760
760
  Display formatted findings:
761
761
 
@@ -763,7 +763,7 @@ Display formatted findings:
763
763
  node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js security format-findings '{scan-output-json}'
764
764
  ```
765
765
 
766
- (`formatFindings()` in `plan-build-run/bin/lib/security-scan.cjs`)
766
+ (`formatFindings()` in `plugins/pbr/scripts/lib/security-scan.js`)
767
767
 
768
768
  Output format:
769
769
  - If no findings: `✓ Security scan: clean`
@@ -782,13 +782,13 @@ HIGH-severity findings (hardcoded secrets, SQL injection, eval-of-user-input) re
782
782
 
783
783
  **Skip if** `features.regression_prevention` is not `true` in `.planning/config.json`.
784
784
 
785
- After each wave, identify which test files are relevant to the changed source files using `plan-build-run/bin/lib/test-selection.cjs`. Run only those tests instead of the full suite — this catches regressions early without the latency of a full test run.
785
+ After each wave, identify which test files are relevant to the changed source files using `plugins/pbr/scripts/lib/test-selection.js`. Run only those tests instead of the full suite — this catches regressions early without the latency of a full test run.
786
786
 
787
787
  ```bash
788
788
  node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js test-selection select '{space-separated changed files}'
789
789
  ```
790
790
 
791
- (`selectTests()` in `plan-build-run/bin/lib/test-selection.cjs`)
791
+ (`selectTests()` in `plugins/pbr/scripts/lib/test-selection.js`)
792
792
 
793
793
  Then format the test command:
794
794
 
@@ -796,7 +796,7 @@ Then format the test command:
796
796
  node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js test-selection format-command '{selection-output-json}'
797
797
  ```
798
798
 
799
- (`formatTestCommand()` in `plan-build-run/bin/lib/test-selection.cjs`)
799
+ (`formatTestCommand()` in `plugins/pbr/scripts/lib/test-selection.js`)
800
800
 
801
801
  Run the resulting command (e.g., `npm test -- tests/foo.test.js tests/bar.test.js`) via Bash. Display:
802
802
  - `✓ Smart tests ({N} files): all passed`
@@ -2,6 +2,7 @@
2
2
  name: config
3
3
  description: "Configure settings: depth, model profiles, features, git, and gates."
4
4
  allowed-tools: Read, Write, Bash, Glob, AskUserQuestion
5
+ argument-hint: "set <key> <value> | get <key> | list"
5
6
  ---
6
7
 
7
8
  **STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes ~7,600 tokens. Begin executing Step 1 immediately.**
@@ -2,6 +2,7 @@
2
2
  name: help
3
3
  description: "Command reference and workflow guide for Plan-Build-Run."
4
4
  allowed-tools: Read, Bash
5
+ argument-hint: "[command]"
5
6
  ---
6
7
 
7
8
  **STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes tokens. Begin executing Step 1 immediately.**
@@ -2,6 +2,7 @@
2
2
  name: pause
3
3
  description: "Save your current session state for later resumption."
4
4
  allowed-tools: Read, Write, Bash, Glob
5
+ argument-hint: "[reason]"
5
6
  ---
6
7
 
7
8
  **STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes ~7,600 tokens. Begin executing Step 1 immediately.**
@@ -2,6 +2,7 @@
2
2
  name: profile-user
3
3
  description: "Analyze Claude Code session history to generate a developer behavioral profile across 8 dimensions."
4
4
  allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
5
+ argument-hint: "[--sessions N]"
5
6
  ---
6
7
 
7
8
  **STOP -- DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes tokens. Begin executing Step 0 immediately.**
@@ -2,6 +2,7 @@
2
2
  name: quick
3
3
  description: "Execute an ad-hoc task with atomic commits. Skips full plan/review."
4
4
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, Task, AskUserQuestion
5
+ argument-hint: "<description> [--discuss] [--full]"
5
6
  ---
6
7
 
7
8
  **STOP -- DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes ~7,600 tokens. Begin executing Step 0 immediately.**
@@ -245,7 +246,7 @@ After the executor completes:
245
246
 
246
247
  2. **Generate post-hoc SUMMARY.md** (if `features.post_hoc_artifacts` is not `false`):
247
248
  ```bash
248
- node -e "const ph=require('./plan-build-run/bin/lib/post-hoc.cjs'); ph.generateSummary(process.argv[1], process.argv[2], {commitPattern: 'quick-{NNN}', description: '{description}'})" .planning ".planning/quick/{NNN}-{slug}"
249
+ node -e "const ph=require('./plugins/pbr/scripts/lib/post-hoc.js'); ph.generateSummary(process.argv[1], process.argv[2], {commitPattern: 'quick-{NNN}', description: '{description}'})" .planning ".planning/quick/{NNN}-{slug}"
249
250
  ```
250
251
  - If `features.post_hoc_artifacts` is `false`: skip SUMMARY.md generation
251
252
 
@@ -2,6 +2,7 @@
2
2
  name: resume
3
3
  description: "Pick up where you left off. Restores context and suggests next action."
4
4
  allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
5
+ argument-hint: "[--from <file>]"
5
6
  ---
6
7
 
7
8
  **STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes ~7,600 tokens. Begin executing Step 1 immediately.**
@@ -2,6 +2,7 @@
2
2
  name: scan
3
3
  description: "Analyze an existing codebase. Maps structure, architecture, conventions, and concerns."
4
4
  allowed-tools: Read, Write, Bash, Glob, Grep, Task, AskUserQuestion
5
+ argument-hint: "[--focus tech|arch|quality|concerns]"
5
6
  ---
6
7
 
7
8
  **STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes ~7,600 tokens. Begin executing Step 1 immediately.**
@@ -2,6 +2,7 @@
2
2
  name: setup
3
3
  description: "Reconfigure an existing Plan-Build-Run project (models, features, CLAUDE.md)."
4
4
  allowed-tools: Read, Write, Bash, Glob, AskUserQuestion
5
+ argument-hint: "[--models] [--features] [--hooks]"
5
6
  ---
6
7
 
7
8
  **STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes tokens. Begin executing Step 1 immediately.**
@@ -100,7 +100,7 @@ Resume file: {path or "None"}
100
100
 
101
101
  ## Size Limit Enforcement
102
102
 
103
- **Hard limit: 150 lines.** After every STATE.md write, check the line count. If over 150 lines, compact:
103
+ **Hard limit: 100 lines.** After every STATE.md write, check the line count. If over 100 lines, compact:
104
104
 
105
105
  1. **Collapse completed phase entries** to one-liners:
106
106
  ```
@@ -111,7 +111,7 @@ Resume file: {path or "None"}
111
111
  3. **Remove old session entries** -- keep only the current session's continuity data
112
112
  4. **Keep these always:** current phase detail, active blockers, core value statement, milestone info
113
113
 
114
- If still over 150 lines after compaction, the Accumulated Context section has grown too large. Move non-critical decisions to the phase's CONTEXT.md file.
114
+ If still over 100 lines after compaction, the Accumulated Context section has grown too large. Move non-critical decisions to the phase's CONTEXT.md file.
115
115
 
116
116
  ---
117
117
 
@@ -2,6 +2,7 @@
2
2
  name: status
3
3
  description: "Show current project status and suggest what to do next."
4
4
  allowed-tools: Read, Glob, Grep, Bash, AskUserQuestion
5
+ argument-hint: "[--json]"
5
6
  ---
6
7
 
7
8
  **STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes ~7,600 tokens. Begin executing Step 1 immediately.**
@@ -1,53 +0,0 @@
1
- # Behavioral Contexts
2
-
3
- PBR supports 3 behavioral context profiles that adjust agent behavior based on the current activity.
4
-
5
- ## Context Profiles
6
-
7
- | Context | Risk Tolerance | Verbosity | Focus | Use When |
8
- |---------|---------------|-----------|-------|----------|
9
- | `dev` | Medium | Low | Shipping code | Building features, executing plans |
10
- | `research` | Low | High | Thoroughness | Researching approaches, exploring options |
11
- | `review` | Very Low | Medium | Accuracy | Verifying work, reviewing code |
12
-
13
- ## How Contexts Affect Agents
14
-
15
- ### `dev` Context (default during execute-phase)
16
- - Executor: Focused, concise output, 3-attempt bug fix limit
17
- - Deviations: Log and continue for minor issues
18
- - Verification: Standard must_have checking
19
-
20
- ### `research` Context (default during plan-phase, research-phase)
21
- - Researcher: Exhaustive source checking, S0-S6 hierarchy enforced
22
- - Planner: Extra validation passes, dependency verification
23
- - Output: Detailed reasoning, cite sources
24
-
25
- ### `review` Context (default during verify-work)
26
- - Verifier: Strict must_have checking, severity-level reporting
27
- - Integration checker: Full CRUD flow verification
28
- - Output: Structured findings with severity levels
29
-
30
- ## Configuration
31
-
32
- Set in `.planning/config.json`:
33
- ```json
34
- {
35
- "behavioral_context": "auto"
36
- }
37
- ```
38
-
39
- Or override per-command via pbr-tools:
40
- ```bash
41
- node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js resolve-context --raw
42
- # Returns: {"context": "dev", "risk_tolerance": "medium", "verbosity": "low"}
43
- ```
44
-
45
- ## Automatic Context Selection
46
-
47
- When `behavioral_context` is not set or set to `"auto"` (default):
48
- - `/pbr:execute-phase` -> `dev`
49
- - `/pbr:plan-phase` -> `research`
50
- - `/pbr:research-phase` -> `research`
51
- - `/pbr:verify-work` -> `review`
52
- - `/pbr:quick` -> `dev`
53
- - All others -> `dev`
@@ -1,91 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * lib/autonomy.js — Progressive autonomy level resolver.
5
- *
6
- * Maps autonomy levels to concrete behavior flags that skills and agents
7
- * use to decide approval gates, UAT skipping, and retry behavior.
8
- *
9
- * Levels:
10
- * supervised — Human approves all actions
11
- * guided — AI acts, human reviews asynchronously
12
- * collaborative — AI handles routine, escalates novel
13
- * adaptive — AI adjusts own level per task confidence
14
- */
15
-
16
- /** All valid autonomy levels. */
17
- const AUTONOMY_LEVELS = ['supervised', 'guided', 'collaborative', 'adaptive'];
18
-
19
- /** Confidence thresholds for adaptive mode. */
20
- const ADAPTIVE_THRESHOLDS = {
21
- HIGH: 0.90,
22
- LOW: 0.70
23
- };
24
-
25
- /** Behavior preset for each static level. */
26
- const LEVEL_BEHAVIORS = {
27
- supervised: {
28
- requiresApproval: true,
29
- skipUAT: false,
30
- autoRetry: false
31
- },
32
- guided: {
33
- requiresApproval: false,
34
- skipUAT: true,
35
- autoRetry: false
36
- },
37
- collaborative: {
38
- requiresApproval: false,
39
- skipUAT: true,
40
- autoRetry: true
41
- }
42
- };
43
-
44
- /**
45
- * Resolve the autonomy behavior for a given level and task confidence.
46
- *
47
- * @param {string} [level] - Autonomy level (supervised/guided/collaborative/adaptive). Defaults to supervised.
48
- * @param {number} [taskConfidence=0.5] - Task confidence score 0-1 (used by adaptive mode).
49
- * @returns {{ requiresApproval: boolean, skipUAT: boolean, autoRetry: boolean, effectiveLevel: string }}
50
- */
51
- function resolveAutonomyBehavior(level, taskConfidence) {
52
- const confidence = typeof taskConfidence === 'number' ? taskConfidence : 0.5;
53
-
54
- // Adaptive: route based on confidence
55
- if (level === 'adaptive') {
56
- let effectiveLevel;
57
- if (confidence > ADAPTIVE_THRESHOLDS.HIGH) {
58
- effectiveLevel = 'collaborative';
59
- } else if (confidence < ADAPTIVE_THRESHOLDS.LOW) {
60
- effectiveLevel = 'supervised';
61
- } else {
62
- effectiveLevel = 'guided';
63
- }
64
- return {
65
- ...LEVEL_BEHAVIORS[effectiveLevel],
66
- effectiveLevel
67
- };
68
- }
69
-
70
- // Static levels (supervised, guided, collaborative)
71
- const behavior = LEVEL_BEHAVIORS[level];
72
- if (behavior) {
73
- return {
74
- ...behavior,
75
- effectiveLevel: level
76
- };
77
- }
78
-
79
- // Unknown or undefined level — default to supervised
80
- return {
81
- ...LEVEL_BEHAVIORS.supervised,
82
- effectiveLevel: 'supervised'
83
- };
84
- }
85
-
86
- module.exports = {
87
- resolveAutonomyBehavior,
88
- AUTONOMY_LEVELS,
89
- ADAPTIVE_THRESHOLDS,
90
- LEVEL_BEHAVIORS
91
- };