@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.
- package/CHANGELOG.md +39 -0
- package/CLAUDE.md +29 -16
- package/README.md +3 -3
- package/dashboard/server/index.js +10 -1
- package/dashboard/server/routes/agents.js +23 -2
- package/dashboard/server/routes/health.js +7 -4
- package/dashboard/server/routes/telemetry.js +20 -1
- package/dashboard/server/services/planning-reader.js +3 -17
- package/package.json +1 -1
- package/plan-build-run/bin/config-schema.json +23 -145
- package/plugins/pbr/.claude-plugin/plugin.json +1 -1
- package/plugins/pbr/agents/advisor-researcher.md +1 -0
- package/plugins/pbr/agents/debugger.md +0 -4
- package/plugins/pbr/agents/researcher.md +0 -4
- package/plugins/pbr/agents/synthesizer.md +0 -4
- package/plugins/pbr/dist/check-config-change.js +0 -7
- package/plugins/pbr/dist/check-cross-plugin-sync.js +1 -1
- package/plugins/pbr/dist/check-plan-format.js +0 -32
- package/plugins/pbr/dist/check-roadmap-sync.js +15 -11
- package/plugins/pbr/dist/check-subagent-output.js +4 -60
- package/plugins/pbr/dist/check-summary-gate.js +3 -14
- package/plugins/pbr/dist/feedback-loop.js +12 -29
- package/plugins/pbr/dist/hook-server.js +58 -6
- package/plugins/pbr/dist/milestone-learnings.js +6 -56
- package/plugins/pbr/dist/pbr-tools.js +8 -91
- package/plugins/pbr/dist/post-bash-triage.js +5 -63
- package/plugins/pbr/dist/post-hoc.js +3 -52
- package/plugins/pbr/dist/post-write-dispatch.js +0 -36
- package/plugins/pbr/dist/pre-bash-dispatch.js +1 -7
- package/plugins/pbr/dist/pre-task-dispatch.js +0 -28
- package/plugins/pbr/dist/progress-tracker.js +2 -27
- package/plugins/pbr/dist/session-cleanup.js +1 -31
- package/plugins/pbr/dist/status-line.js +13 -11
- package/plugins/pbr/dist/suggest-compact.js +2 -10
- package/plugins/pbr/dist/validate-commit.js +8 -64
- package/plugins/pbr/dist/validate-task.js +0 -30
- package/plugins/pbr/references/config-reference.md +0 -96
- package/plugins/pbr/scripts/audit-checks/si-agent-hook-config-checks.js +2 -72
- package/plugins/pbr/scripts/audit-checks/workflow-compliance.js +5 -41
- package/plugins/pbr/scripts/check-config-change.js +0 -7
- package/plugins/pbr/scripts/check-cross-plugin-sync.js +1 -1
- package/plugins/pbr/scripts/check-plan-format.js +0 -32
- package/plugins/pbr/scripts/check-roadmap-sync.js +15 -11
- package/plugins/pbr/scripts/check-subagent-output.js +4 -60
- package/plugins/pbr/scripts/check-summary-gate.js +3 -14
- package/plugins/pbr/scripts/config-schema.json +16 -129
- package/plugins/pbr/scripts/feedback-loop.js +12 -29
- package/plugins/pbr/scripts/hook-server.js +58 -6
- package/plugins/pbr/scripts/lib/config.js +4 -11
- package/plugins/pbr/scripts/lib/contextual-help.js +5 -29
- package/plugins/pbr/scripts/lib/format-validators.js +1 -26
- package/plugins/pbr/scripts/lib/frontmatter.js +4 -4
- package/plugins/pbr/scripts/lib/gates/rich-agent-context.js +13 -19
- package/plugins/pbr/scripts/lib/health.js +4 -5
- package/plugins/pbr/scripts/lib/help.js +3 -54
- package/plugins/pbr/scripts/lib/phase.js +2 -4
- package/plugins/pbr/scripts/lib/pre-commit-checks.js +1 -1
- package/plugins/pbr/scripts/lib/pre-research.js +10 -17
- package/plugins/pbr/scripts/lib/roadmap.js +11 -35
- package/plugins/pbr/scripts/lib/smart-next-task.js +11 -20
- package/plugins/pbr/scripts/lib/spot-check.js +3 -106
- package/plugins/pbr/scripts/lib/state.js +25 -130
- package/plugins/pbr/scripts/lib/verify.js +56 -46
- package/plugins/pbr/scripts/milestone-learnings.js +6 -56
- package/plugins/pbr/scripts/pbr-tools.js +8 -91
- package/plugins/pbr/scripts/post-bash-triage.js +5 -63
- package/plugins/pbr/scripts/post-hoc.js +3 -52
- package/plugins/pbr/scripts/post-write-dispatch.js +0 -36
- package/plugins/pbr/scripts/pre-bash-dispatch.js +1 -7
- package/plugins/pbr/scripts/pre-task-dispatch.js +0 -28
- package/plugins/pbr/scripts/progress-tracker.js +2 -27
- package/plugins/pbr/scripts/session-cleanup.js +1 -31
- package/plugins/pbr/scripts/status-line.js +13 -11
- package/plugins/pbr/scripts/suggest-compact.js +2 -10
- package/plugins/pbr/scripts/test/state.test.js +5 -13
- package/plugins/pbr/scripts/validate-commit.js +8 -64
- package/plugins/pbr/scripts/validate-task.js +0 -30
- package/plugins/pbr/skills/begin/SKILL.md +1 -0
- package/plugins/pbr/skills/begin/templates/config.json.tmpl +0 -4
- package/plugins/pbr/skills/build/SKILL.md +6 -6
- package/plugins/pbr/skills/config/SKILL.md +1 -0
- package/plugins/pbr/skills/help/SKILL.md +1 -0
- package/plugins/pbr/skills/pause/SKILL.md +1 -0
- package/plugins/pbr/skills/profile-user/SKILL.md +1 -0
- package/plugins/pbr/skills/quick/SKILL.md +2 -1
- package/plugins/pbr/skills/resume/SKILL.md +1 -0
- package/plugins/pbr/skills/scan/SKILL.md +1 -0
- package/plugins/pbr/skills/setup/SKILL.md +1 -0
- package/plugins/pbr/skills/shared/state-update.md +2 -2
- package/plugins/pbr/skills/status/SKILL.md +1 -0
- package/plugins/pbr/references/behavioral-contexts.md +0 -53
- package/plugins/pbr/scripts/lib/autonomy.js +0 -91
- package/plugins/pbr/scripts/lib/circuit-state.js +0 -133
- package/plugins/pbr/scripts/lib/completion.js +0 -377
- package/plugins/pbr/scripts/lib/hypothesis-runner.js +0 -127
- package/plugins/pbr/scripts/lib/local-llm/client.js +0 -237
- package/plugins/pbr/scripts/lib/local-llm/health.js +0 -12
- package/plugins/pbr/scripts/lib/local-llm/index.js +0 -89
- package/plugins/pbr/scripts/lib/local-llm/metrics.js +0 -20
- package/plugins/pbr/scripts/lib/local-llm/operations/classify-artifact.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/operations/classify-commit.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/operations/classify-error.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/operations/classify-file-intent.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/operations/score-source.js +0 -72
- package/plugins/pbr/scripts/lib/local-llm/operations/summarize-context.js +0 -62
- package/plugins/pbr/scripts/lib/local-llm/operations/triage-test-output.js +0 -12
- package/plugins/pbr/scripts/lib/local-llm/operations/validate-task.js +0 -4
- package/plugins/pbr/scripts/lib/local-llm/router.js +0 -101
- package/plugins/pbr/scripts/lib/local-llm/shadow.js +0 -60
- package/plugins/pbr/scripts/lib/local-llm/threshold-tuner.js +0 -118
- package/plugins/pbr/scripts/lib/team-composer.js +0 -87
- package/plugins/pbr/scripts/lib/team-coordinator.js +0 -153
- package/plugins/pbr/scripts/lib/template.js +0 -222
- package/plugins/pbr/scripts/lib/test-cache.js +0 -54
- package/plugins/pbr/scripts/lib/trust-gate.js +0 -84
- 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,
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
553
|
+
const raw = extractFrontmatter(content);
|
|
552
554
|
const result = {};
|
|
553
|
-
for (const
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
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
|
-
//
|
|
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('
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
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
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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('./
|
|
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:
|
|
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
|
|
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
|
-
};
|