@sienklogic/plan-build-run 2.23.0 → 2.26.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.
- package/CHANGELOG.md +66 -0
- package/README.md +62 -13
- package/dashboard/package.json +2 -2
- package/dashboard/public/css/layout.css +128 -21
- package/dashboard/public/css/status-colors.css +14 -2
- package/dashboard/public/css/tokens.css +36 -0
- package/dashboard/src/middleware/current-phase.js +2 -1
- package/dashboard/src/repositories/planning.repository.js +1 -11
- package/dashboard/src/routes/events.routes.js +49 -0
- package/dashboard/src/routes/pages.routes.js +367 -3
- package/dashboard/src/server.js +4 -0
- package/dashboard/src/services/audit.service.js +42 -0
- package/dashboard/src/services/config.service.js +140 -0
- package/dashboard/src/services/dashboard.service.js +153 -19
- package/dashboard/src/services/log.service.js +105 -0
- package/dashboard/src/services/notes.service.js +16 -0
- package/dashboard/src/services/phase.service.js +58 -9
- package/dashboard/src/services/requirements.service.js +130 -0
- package/dashboard/src/services/research.service.js +137 -0
- package/dashboard/src/services/roadmap.service.js +1 -11
- package/dashboard/src/services/todo.service.js +30 -0
- package/dashboard/src/utils/strip-bom.js +8 -0
- package/dashboard/src/views/audit-detail.ejs +5 -0
- package/dashboard/src/views/audits.ejs +5 -0
- package/dashboard/src/views/config.ejs +5 -0
- package/dashboard/src/views/logs.ejs +3 -0
- package/dashboard/src/views/note-detail.ejs +3 -0
- package/dashboard/src/views/partials/activity-feed.ejs +12 -0
- package/dashboard/src/views/partials/audit-detail-content.ejs +12 -0
- package/dashboard/src/views/partials/audits-content.ejs +34 -0
- package/dashboard/src/views/partials/config-content.ejs +196 -0
- package/dashboard/src/views/partials/dashboard-content.ejs +71 -46
- package/dashboard/src/views/partials/log-entries-content.ejs +17 -0
- package/dashboard/src/views/partials/logs-content.ejs +131 -0
- package/dashboard/src/views/partials/note-detail-content.ejs +22 -0
- package/dashboard/src/views/partials/notes-content.ejs +7 -1
- package/dashboard/src/views/partials/phase-content.ejs +181 -146
- package/dashboard/src/views/partials/phase-timeline.ejs +16 -0
- package/dashboard/src/views/partials/requirements-content.ejs +44 -0
- package/dashboard/src/views/partials/research-content.ejs +49 -0
- package/dashboard/src/views/partials/research-detail-content.ejs +23 -0
- package/dashboard/src/views/partials/sidebar.ejs +67 -22
- package/dashboard/src/views/partials/todos-content.ejs +13 -3
- package/dashboard/src/views/partials/todos-done-content.ejs +44 -0
- package/dashboard/src/views/requirements.ejs +3 -0
- package/dashboard/src/views/research-detail.ejs +3 -0
- package/dashboard/src/views/research.ejs +3 -0
- package/dashboard/src/views/todos-done.ejs +3 -0
- package/package.json +1 -1
- package/plugins/copilot-pbr/agents/dev-sync.agent.md +114 -0
- package/plugins/copilot-pbr/agents/integration-checker.agent.md +9 -2
- package/plugins/copilot-pbr/agents/planner.agent.md +19 -0
- package/plugins/copilot-pbr/agents/verifier.agent.md +22 -2
- package/plugins/copilot-pbr/hooks/hooks.json +12 -0
- package/plugins/copilot-pbr/plugin.json +1 -1
- package/plugins/copilot-pbr/references/plan-format.md +22 -0
- package/plugins/copilot-pbr/templates/INTEGRATION-REPORT.md.tmpl +18 -2
- package/plugins/copilot-pbr/templates/VERIFICATION-DETAIL.md.tmpl +2 -1
- package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor-pbr/agents/dev-sync.md +113 -0
- package/plugins/cursor-pbr/agents/integration-checker.md +9 -2
- package/plugins/cursor-pbr/agents/planner.md +19 -0
- package/plugins/cursor-pbr/agents/verifier.md +22 -2
- package/plugins/cursor-pbr/hooks/hooks.json +10 -0
- package/plugins/cursor-pbr/references/plan-format.md +22 -0
- package/plugins/cursor-pbr/templates/INTEGRATION-REPORT.md.tmpl +18 -2
- package/plugins/cursor-pbr/templates/VERIFICATION-DETAIL.md.tmpl +2 -1
- package/plugins/pbr/.claude-plugin/plugin.json +1 -1
- package/plugins/pbr/agents/dev-sync.md +120 -0
- package/plugins/pbr/agents/integration-checker.md +9 -2
- package/plugins/pbr/agents/planner.md +19 -0
- package/plugins/pbr/agents/verifier.md +22 -2
- package/plugins/pbr/hooks/hooks.json +10 -0
- package/plugins/pbr/references/plan-format.md +22 -0
- package/plugins/pbr/scripts/check-plan-format.js +2 -2
- package/plugins/pbr/scripts/check-subagent-output.js +2 -2
- package/plugins/pbr/scripts/config-schema.json +4 -1
- package/plugins/pbr/scripts/local-llm/health.js +4 -1
- package/plugins/pbr/scripts/local-llm/operations/classify-commit.js +68 -0
- package/plugins/pbr/scripts/local-llm/operations/classify-file-intent.js +73 -0
- package/plugins/pbr/scripts/local-llm/operations/triage-test-output.js +72 -0
- package/plugins/pbr/scripts/post-bash-triage.js +132 -0
- package/plugins/pbr/scripts/post-write-dispatch.js +44 -0
- package/plugins/pbr/scripts/pre-bash-dispatch.js +17 -11
- package/plugins/pbr/scripts/status-line.js +50 -5
- package/plugins/pbr/scripts/validate-commit.js +66 -2
- package/plugins/pbr/scripts/validate-task.js +1 -1
- package/plugins/pbr/templates/INTEGRATION-REPORT.md.tmpl +18 -2
- package/plugins/pbr/templates/VERIFICATION-DETAIL.md.tmpl +2 -1
- package/dashboard/src/views/coming-soon.ejs +0 -11
|
@@ -17,10 +17,13 @@
|
|
|
17
17
|
* 2 = invalid commit message format (blocks the tool)
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
const fs = require('fs');
|
|
20
21
|
const path = require('path');
|
|
21
22
|
const { execSync } = require('child_process');
|
|
22
23
|
const { logHook } = require('./hook-logger');
|
|
23
24
|
const { logEvent } = require('./event-logger');
|
|
25
|
+
const { resolveConfig } = require('./local-llm/health');
|
|
26
|
+
const { classifyCommit } = require('./local-llm/operations/classify-commit');
|
|
24
27
|
|
|
25
28
|
const VALID_TYPES = ['feat', 'fix', 'refactor', 'test', 'docs', 'chore', 'wip'];
|
|
26
29
|
|
|
@@ -149,12 +152,64 @@ function checkCommit(data) {
|
|
|
149
152
|
return null;
|
|
150
153
|
}
|
|
151
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Load and resolve the local_llm config block from .planning/config.json.
|
|
157
|
+
* Returns a resolved config (always safe to use — disabled by default on error).
|
|
158
|
+
*/
|
|
159
|
+
function loadLocalLlmConfig(cwd) {
|
|
160
|
+
try {
|
|
161
|
+
const configPath = path.join(cwd || process.cwd(), '.planning', 'config.json');
|
|
162
|
+
const parsed = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
163
|
+
return resolveConfig(parsed.local_llm);
|
|
164
|
+
} catch (_e) {
|
|
165
|
+
return resolveConfig(undefined);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Async LLM enrichment for commit messages. Returns an advisory string or null.
|
|
171
|
+
* Called after checkCommit passes (valid format) to provide semantic classification.
|
|
172
|
+
*
|
|
173
|
+
* @param {object} data - parsed hook data
|
|
174
|
+
* @returns {Promise<string|null>}
|
|
175
|
+
*/
|
|
176
|
+
async function enrichCommitLlm(data) {
|
|
177
|
+
try {
|
|
178
|
+
const command = data.tool_input?.command || '';
|
|
179
|
+
const message = extractCommitMessage(command);
|
|
180
|
+
if (!message) return null;
|
|
181
|
+
|
|
182
|
+
const cwd = process.cwd();
|
|
183
|
+
const llmConfig = loadLocalLlmConfig(cwd);
|
|
184
|
+
const planningDir = path.join(cwd, '.planning');
|
|
185
|
+
|
|
186
|
+
// Get staged files for scope validation
|
|
187
|
+
let stagedFiles = [];
|
|
188
|
+
try {
|
|
189
|
+
const output = execSync('git diff --cached --name-only', { encoding: 'utf8' });
|
|
190
|
+
stagedFiles = output.trim().split('\n').filter(Boolean);
|
|
191
|
+
} catch (_e) {
|
|
192
|
+
// Not in a git repo — skip staged files context
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const llmResult = await classifyCommit(llmConfig, planningDir, message, stagedFiles, data.session_id);
|
|
196
|
+
if (llmResult && llmResult.classification !== 'correct') {
|
|
197
|
+
return 'LLM commit advisory: ' + llmResult.classification +
|
|
198
|
+
' (confidence: ' + (llmResult.confidence * 100).toFixed(0) + '%)';
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
} catch (_llmErr) {
|
|
202
|
+
// Never propagate LLM errors
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
152
207
|
function main() {
|
|
153
208
|
let input = '';
|
|
154
209
|
|
|
155
210
|
process.stdin.setEncoding('utf8');
|
|
156
211
|
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
157
|
-
process.stdin.on('end', () => {
|
|
212
|
+
process.stdin.on('end', async () => {
|
|
158
213
|
try {
|
|
159
214
|
const data = JSON.parse(input);
|
|
160
215
|
const result = checkCommit(data);
|
|
@@ -162,6 +217,15 @@ function main() {
|
|
|
162
217
|
process.stdout.write(JSON.stringify(result.output));
|
|
163
218
|
process.exit(result.exitCode);
|
|
164
219
|
}
|
|
220
|
+
|
|
221
|
+
// LLM semantic classification — advisory only (after format validation passes)
|
|
222
|
+
const llmAdvisory = await enrichCommitLlm(data);
|
|
223
|
+
if (llmAdvisory) {
|
|
224
|
+
process.stdout.write(JSON.stringify({
|
|
225
|
+
additionalContext: '[pbr] ' + llmAdvisory
|
|
226
|
+
}));
|
|
227
|
+
}
|
|
228
|
+
|
|
165
229
|
process.exit(0);
|
|
166
230
|
} catch (_e) {
|
|
167
231
|
// Parse error - don't block
|
|
@@ -197,5 +261,5 @@ function extractCommitMessage(command) {
|
|
|
197
261
|
return null;
|
|
198
262
|
}
|
|
199
263
|
|
|
200
|
-
module.exports = { checkCommit };
|
|
264
|
+
module.exports = { checkCommit, enrichCommitLlm };
|
|
201
265
|
if (require.main === module || process.argv[1] === __filename) { main(); }
|
|
@@ -805,7 +805,7 @@ function main() {
|
|
|
805
805
|
try {
|
|
806
806
|
const llmConfig = loadLocalLlmConfig(process.cwd());
|
|
807
807
|
const planningDir = path.join(process.cwd(), '.planning');
|
|
808
|
-
const llmResult = await llmValidateTask(llmConfig, planningDir, data.tool_input || {},
|
|
808
|
+
const llmResult = await llmValidateTask(llmConfig, planningDir, data.tool_input || {}, data.session_id);
|
|
809
809
|
if (llmResult && !llmResult.coherent) {
|
|
810
810
|
warnings.push('LLM task coherence advisory: ' + (llmResult.issue || 'Task description may not match intended operation.') + ' (confidence: ' + (llmResult.confidence * 100).toFixed(0) + '%)');
|
|
811
811
|
}
|
|
@@ -111,7 +111,22 @@ Phase 03 (Core) ──provides──→ Phase 04 (Frontend)
|
|
|
111
111
|
### Flow 2: {Flow Name} - {STATUS}
|
|
112
112
|
...
|
|
113
113
|
|
|
114
|
-
## 5.
|
|
114
|
+
## 5. Data-Flow Propagation
|
|
115
|
+
|
|
116
|
+
### Cross-Boundary Data Flows
|
|
117
|
+
|
|
118
|
+
| Data Field | Source | Intermediate Steps | Destination | Status |
|
|
119
|
+
|------------|--------|-------------------|-------------|--------|
|
|
120
|
+
| {field name} | {origin, e.g., hook stdin `data.session_id`} | {module1:L12 → module2:L45} | {dest, e.g., metrics.jsonl `session_id`} | PROPAGATED |
|
|
121
|
+
| {field name} | {origin} | {module1:L12 → module2:L45} | {dest} | DATA_DROPPED |
|
|
122
|
+
|
|
123
|
+
### Data-Flow Issues
|
|
124
|
+
|
|
125
|
+
| Field | Dropped At | Available In Scope | Passed Instead | Fix |
|
|
126
|
+
|-------|-----------|-------------------|----------------|-----|
|
|
127
|
+
| {field} | {file:line} | `data.session_id` | `undefined` | Pass `data.session_id` |
|
|
128
|
+
|
|
129
|
+
## 6. Integration Issues Summary
|
|
115
130
|
|
|
116
131
|
### Critical Issues (system cannot function)
|
|
117
132
|
|
|
@@ -130,7 +145,7 @@ Phase 03 (Core) ──provides──→ Phase 04 (Frontend)
|
|
|
130
145
|
1. **{Issue}**: {description}
|
|
131
146
|
- Fix: {recommended action}
|
|
132
147
|
|
|
133
|
-
##
|
|
148
|
+
## 7. Integration Score
|
|
134
149
|
|
|
135
150
|
| Category | Items Checked | Passed | Failed | Score |
|
|
136
151
|
|----------|--------------|--------|--------|-------|
|
|
@@ -138,6 +153,7 @@ Phase 03 (Core) ──provides──→ Phase 04 (Frontend)
|
|
|
138
153
|
| API coverage | {n} | {n} | {n} | {%} |
|
|
139
154
|
| Auth protection | {n} | {n} | {n} | {%} |
|
|
140
155
|
| E2E flows | {n} | {n} | {n} | {%} |
|
|
156
|
+
| Data-flow propagation | {n} | {n} | {n} | {%} |
|
|
141
157
|
| **Overall** | {n} | {n} | {n} | **{%}** |
|
|
142
158
|
|
|
143
159
|
## Recommendations
|
|
@@ -53,8 +53,9 @@ anti_patterns:
|
|
|
53
53
|
|
|
54
54
|
| # | Link Description | Source | Target | Status | Evidence |
|
|
55
55
|
|---|-----------------|--------|--------|--------|----------|
|
|
56
|
-
| 1 | {what connects to what} | `{source_file}` | `{target_file}` | WIRED | Import at L12, called at L45 |
|
|
56
|
+
| 1 | {what connects to what} | `{source_file}` | `{target_file}` | WIRED | Import at L12, called at L45, args correct |
|
|
57
57
|
| 2 | {what connects to what} | `{source_file}` | `{target_file}` | BROKEN | Imported but never called |
|
|
58
|
+
| 3 | {what connects to what} | `{source_file}` | `{target_file}` | ARGS_WRONG | Called at L45 but passes undefined for sessionId (data.session_id in scope) |
|
|
58
59
|
|
|
59
60
|
## Gaps Found
|
|
60
61
|
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<%- include('partials/layout-top', { title: title, activePage: activePage }) %>
|
|
2
|
-
|
|
3
|
-
<h1><%= featureName %></h1>
|
|
4
|
-
<p>This feature is coming soon.</p>
|
|
5
|
-
<p>
|
|
6
|
-
The <strong><%= featureName %></strong> view is planned but not yet implemented.
|
|
7
|
-
Check back in a future phase.
|
|
8
|
-
</p>
|
|
9
|
-
<p><a href="/">Back to Dashboard</a></p>
|
|
10
|
-
|
|
11
|
-
<%- include('partials/layout-bottom') %>
|