@sienklogic/plan-build-run 2.0.2 → 2.1.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/dashboard/src/routes/pages.routes.js +11 -4
- package/dashboard/src/services/dashboard.service.js +81 -17
- package/dashboard/src/services/phase.service.js +30 -24
- package/dashboard/src/services/roadmap.service.js +3 -3
- package/dashboard/src/views/partials/phase-content.ejs +5 -4
- package/package.json +1 -1
- package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor-pbr/CHANGELOG.md +15 -0
- package/plugins/cursor-pbr/README.md +118 -0
- package/plugins/cursor-pbr/agents/codebase-mapper.md +108 -0
- package/plugins/cursor-pbr/agents/debugger.md +168 -0
- package/plugins/cursor-pbr/agents/executor.md +236 -0
- package/plugins/cursor-pbr/agents/general.md +87 -0
- package/plugins/cursor-pbr/agents/integration-checker.md +87 -0
- package/plugins/cursor-pbr/agents/plan-checker.md +198 -0
- package/plugins/cursor-pbr/agents/planner.md +180 -0
- package/plugins/cursor-pbr/agents/researcher.md +162 -0
- package/plugins/cursor-pbr/agents/synthesizer.md +101 -0
- package/plugins/cursor-pbr/agents/verifier.md +193 -0
- package/plugins/cursor-pbr/assets/logo.svg +21 -0
- package/plugins/cursor-pbr/hooks/hooks.json +189 -7
- package/plugins/cursor-pbr/references/agent-anti-patterns.md +25 -0
- package/plugins/cursor-pbr/references/agent-interactions.md +135 -0
- package/plugins/cursor-pbr/references/agent-teams.md +55 -0
- package/plugins/cursor-pbr/references/checkpoints.md +158 -0
- package/plugins/cursor-pbr/references/common-bug-patterns.md +14 -0
- package/plugins/cursor-pbr/references/config-reference.md +442 -0
- package/plugins/cursor-pbr/references/continuation-format.md +213 -0
- package/plugins/cursor-pbr/references/deviation-rules.md +113 -0
- package/plugins/cursor-pbr/references/git-integration.md +227 -0
- package/plugins/cursor-pbr/references/integration-patterns.md +118 -0
- package/plugins/cursor-pbr/references/model-profiles.md +100 -0
- package/plugins/cursor-pbr/references/model-selection.md +32 -0
- package/plugins/cursor-pbr/references/pbr-rules.md +194 -0
- package/plugins/cursor-pbr/references/plan-authoring.md +182 -0
- package/plugins/cursor-pbr/references/plan-format.md +288 -0
- package/plugins/cursor-pbr/references/planning-config.md +214 -0
- package/plugins/cursor-pbr/references/questioning.md +215 -0
- package/plugins/cursor-pbr/references/reading-verification.md +128 -0
- package/plugins/cursor-pbr/references/stub-patterns.md +161 -0
- package/plugins/cursor-pbr/references/subagent-coordination.md +120 -0
- package/plugins/cursor-pbr/references/ui-formatting.md +462 -0
- package/plugins/cursor-pbr/references/verification-patterns.md +199 -0
- package/plugins/cursor-pbr/references/wave-execution.md +96 -0
- package/plugins/cursor-pbr/rules/pbr-workflow.mdc +48 -0
- package/plugins/cursor-pbr/setup.ps1 +78 -0
- package/plugins/cursor-pbr/setup.sh +83 -0
- package/plugins/cursor-pbr/skills/begin/SKILL.md +566 -0
- package/plugins/cursor-pbr/skills/begin/templates/PROJECT.md.tmpl +34 -0
- package/plugins/cursor-pbr/skills/begin/templates/REQUIREMENTS.md.tmpl +19 -0
- package/plugins/cursor-pbr/skills/begin/templates/STATE.md.tmpl +50 -0
- package/plugins/cursor-pbr/skills/begin/templates/config.json.tmpl +64 -0
- package/plugins/cursor-pbr/skills/begin/templates/researcher-prompt.md.tmpl +20 -0
- package/plugins/cursor-pbr/skills/begin/templates/roadmap-prompt.md.tmpl +31 -0
- package/plugins/cursor-pbr/skills/begin/templates/synthesis-prompt.md.tmpl +17 -0
- package/plugins/cursor-pbr/skills/build/SKILL.md +902 -0
- package/plugins/cursor-pbr/skills/config/SKILL.md +253 -0
- package/plugins/cursor-pbr/skills/continue/SKILL.md +159 -0
- package/plugins/cursor-pbr/skills/debug/SKILL.md +512 -0
- package/plugins/cursor-pbr/skills/debug/templates/continuation-prompt.md.tmpl +17 -0
- package/plugins/cursor-pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +28 -0
- package/plugins/cursor-pbr/skills/discuss/SKILL.md +344 -0
- package/plugins/cursor-pbr/skills/discuss/templates/CONTEXT.md.tmpl +62 -0
- package/plugins/cursor-pbr/skills/discuss/templates/decision-categories.md +10 -0
- package/plugins/cursor-pbr/skills/explore/SKILL.md +375 -0
- package/plugins/cursor-pbr/skills/health/SKILL.md +218 -0
- package/plugins/cursor-pbr/skills/health/templates/check-pattern.md.tmpl +31 -0
- package/plugins/cursor-pbr/skills/health/templates/output-format.md.tmpl +64 -0
- package/plugins/cursor-pbr/skills/help/SKILL.md +152 -0
- package/plugins/cursor-pbr/skills/import/SKILL.md +499 -0
- package/plugins/cursor-pbr/skills/milestone/SKILL.md +701 -0
- package/plugins/cursor-pbr/skills/milestone/templates/audit-report.md.tmpl +49 -0
- package/plugins/cursor-pbr/skills/milestone/templates/stats-file.md.tmpl +31 -0
- package/plugins/cursor-pbr/skills/note/SKILL.md +228 -0
- package/plugins/cursor-pbr/skills/pause/SKILL.md +246 -0
- package/plugins/cursor-pbr/skills/pause/templates/continue-here.md.tmpl +72 -0
- package/plugins/cursor-pbr/skills/plan/SKILL.md +648 -0
- package/plugins/cursor-pbr/skills/plan/templates/checker-prompt.md.tmpl +22 -0
- package/plugins/cursor-pbr/skills/plan/templates/gap-closure-prompt.md.tmpl +33 -0
- package/plugins/cursor-pbr/skills/plan/templates/planner-prompt.md.tmpl +39 -0
- package/plugins/cursor-pbr/skills/plan/templates/researcher-prompt.md.tmpl +20 -0
- package/plugins/cursor-pbr/skills/plan/templates/revision-prompt.md.tmpl +24 -0
- package/plugins/cursor-pbr/skills/quick/SKILL.md +351 -0
- package/plugins/cursor-pbr/skills/resume/SKILL.md +399 -0
- package/plugins/cursor-pbr/skills/review/SKILL.md +649 -0
- package/plugins/cursor-pbr/skills/review/templates/debugger-prompt.md.tmpl +61 -0
- package/plugins/cursor-pbr/skills/review/templates/gap-planner-prompt.md.tmpl +41 -0
- package/plugins/cursor-pbr/skills/review/templates/verifier-prompt.md.tmpl +116 -0
- package/plugins/cursor-pbr/skills/scan/SKILL.md +301 -0
- package/plugins/cursor-pbr/skills/scan/templates/mapper-prompt.md.tmpl +202 -0
- package/plugins/cursor-pbr/skills/setup/SKILL.md +250 -0
- package/plugins/cursor-pbr/skills/shared/commit-planning-docs.md +36 -0
- package/plugins/cursor-pbr/skills/shared/config-loading.md +103 -0
- package/plugins/cursor-pbr/skills/shared/context-budget.md +41 -0
- package/plugins/cursor-pbr/skills/shared/context-loader-task.md +87 -0
- package/plugins/cursor-pbr/skills/shared/digest-select.md +80 -0
- package/plugins/cursor-pbr/skills/shared/domain-probes.md +126 -0
- package/plugins/cursor-pbr/skills/shared/error-reporting.md +80 -0
- package/plugins/cursor-pbr/skills/shared/gate-prompts.md +389 -0
- package/plugins/cursor-pbr/skills/shared/phase-argument-parsing.md +46 -0
- package/plugins/cursor-pbr/skills/shared/progress-display.md +54 -0
- package/plugins/cursor-pbr/skills/shared/revision-loop.md +82 -0
- package/plugins/cursor-pbr/skills/shared/state-loading.md +63 -0
- package/plugins/cursor-pbr/skills/shared/state-update.md +162 -0
- package/plugins/cursor-pbr/skills/shared/universal-anti-patterns.md +34 -0
- package/plugins/cursor-pbr/skills/status/SKILL.md +362 -0
- package/plugins/cursor-pbr/skills/todo/SKILL.md +195 -0
- package/plugins/cursor-pbr/templates/CONTEXT.md.tmpl +53 -0
- package/plugins/cursor-pbr/templates/INTEGRATION-REPORT.md.tmpl +152 -0
- package/plugins/cursor-pbr/templates/RESEARCH-SUMMARY.md.tmpl +98 -0
- package/plugins/cursor-pbr/templates/ROADMAP.md.tmpl +41 -0
- package/plugins/cursor-pbr/templates/SUMMARY.md.tmpl +82 -0
- package/plugins/cursor-pbr/templates/VERIFICATION-DETAIL.md.tmpl +117 -0
- package/plugins/cursor-pbr/templates/continue-here.md.tmpl +74 -0
- package/plugins/cursor-pbr/templates/prompt-partials/phase-project-context.md.tmpl +38 -0
- package/plugins/pbr/agents/codebase-mapper.md +41 -206
- package/plugins/pbr/agents/debugger.md +65 -171
- package/plugins/pbr/agents/executor.md +90 -275
- package/plugins/pbr/agents/general.md +27 -97
- package/plugins/pbr/agents/integration-checker.md +35 -112
- package/plugins/pbr/agents/plan-checker.md +71 -164
- package/plugins/pbr/agents/planner.md +75 -246
- package/plugins/pbr/agents/researcher.md +63 -255
- package/plugins/pbr/agents/synthesizer.md +49 -174
- package/plugins/pbr/agents/verifier.md +75 -366
- package/plugins/pbr/hooks/hooks.json +14 -10
- package/plugins/pbr/scripts/auto-continue.js +20 -4
- package/plugins/pbr/scripts/check-dangerous-commands.js +1 -1
- package/plugins/pbr/scripts/check-phase-boundary.js +1 -1
- package/plugins/pbr/scripts/check-plan-format.js +3 -3
- package/plugins/pbr/scripts/check-roadmap-sync.js +3 -3
- package/plugins/pbr/scripts/check-skill-workflow.js +1 -1
- package/plugins/pbr/scripts/check-state-sync.js +2 -2
- package/plugins/pbr/scripts/check-subagent-output.js +1 -1
- package/plugins/pbr/scripts/check-summary-gate.js +198 -0
- package/plugins/pbr/scripts/context-budget-check.js +1 -1
- package/plugins/pbr/scripts/event-handler.js +2 -2
- package/plugins/pbr/scripts/event-logger.js +1 -1
- package/plugins/pbr/scripts/log-subagent.js +1 -1
- package/plugins/pbr/scripts/pbr-tools.js +1 -1
- package/plugins/pbr/scripts/post-write-dispatch.js +1 -1
- package/plugins/pbr/scripts/post-write-quality.js +1 -1
- package/plugins/pbr/scripts/pre-bash-dispatch.js +1 -1
- package/plugins/pbr/scripts/pre-write-dispatch.js +16 -3
- package/plugins/pbr/scripts/session-cleanup.js +1 -1
- package/plugins/pbr/scripts/status-line.js +1 -1
- package/plugins/pbr/scripts/suggest-compact.js +1 -1
- package/plugins/pbr/scripts/task-completed.js +1 -1
- package/plugins/pbr/scripts/track-context-budget.js +11 -6
- package/plugins/pbr/scripts/validate-commit.js +1 -1
- package/plugins/pbr/scripts/validate-task.js +1 -1
- package/plugins/cursor-pbr/agents/.gitkeep +0 -0
- package/plugins/cursor-pbr/references/.gitkeep +0 -0
- package/plugins/cursor-pbr/rules/.gitkeep +0 -0
- package/plugins/cursor-pbr/skills/.gitkeep +0 -0
- package/plugins/cursor-pbr/templates/.gitkeep +0 -0
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { getPhaseDetail, getPhaseDocument } from '../services/phase.service.js';
|
|
3
3
|
import { getRoadmapData } from '../services/roadmap.service.js';
|
|
4
|
+
import { parseStateFile, derivePhaseStatuses } from '../services/dashboard.service.js';
|
|
4
5
|
import { listPendingTodos, getTodoDetail, createTodo, completeTodo } from '../services/todo.service.js';
|
|
5
6
|
|
|
6
7
|
const router = Router();
|
|
7
8
|
|
|
8
9
|
router.get('/phases', async (req, res) => {
|
|
9
10
|
const projectDir = req.app.locals.projectDir;
|
|
10
|
-
const roadmapData = await
|
|
11
|
+
const [roadmapData, stateData] = await Promise.all([
|
|
12
|
+
getRoadmapData(projectDir),
|
|
13
|
+
parseStateFile(projectDir)
|
|
14
|
+
]);
|
|
11
15
|
|
|
12
16
|
const templateData = {
|
|
13
17
|
title: 'Phases',
|
|
14
18
|
activePage: 'phases',
|
|
15
19
|
currentPath: '/phases',
|
|
16
|
-
phases: roadmapData.phases,
|
|
20
|
+
phases: derivePhaseStatuses(roadmapData.phases, stateData.currentPhase),
|
|
17
21
|
milestones: roadmapData.milestones
|
|
18
22
|
};
|
|
19
23
|
|
|
@@ -223,13 +227,16 @@ router.post('/todos/:id/done', async (req, res) => {
|
|
|
223
227
|
|
|
224
228
|
router.get('/roadmap', async (req, res) => {
|
|
225
229
|
const projectDir = req.app.locals.projectDir;
|
|
226
|
-
const roadmapData = await
|
|
230
|
+
const [roadmapData, stateData] = await Promise.all([
|
|
231
|
+
getRoadmapData(projectDir),
|
|
232
|
+
parseStateFile(projectDir)
|
|
233
|
+
]);
|
|
227
234
|
|
|
228
235
|
const templateData = {
|
|
229
236
|
title: 'Roadmap',
|
|
230
237
|
activePage: 'roadmap',
|
|
231
238
|
currentPath: '/roadmap',
|
|
232
|
-
phases: roadmapData.phases,
|
|
239
|
+
phases: derivePhaseStatuses(roadmapData.phases, stateData.currentPhase),
|
|
233
240
|
milestones: roadmapData.milestones
|
|
234
241
|
};
|
|
235
242
|
|
|
@@ -24,7 +24,20 @@ export async function parseStateFile(projectDir) {
|
|
|
24
24
|
try {
|
|
25
25
|
const path = join(projectDir, '.planning', 'STATE.md');
|
|
26
26
|
const raw = await readFile(path, 'utf-8');
|
|
27
|
-
const content = stripBOM(raw);
|
|
27
|
+
const content = stripBOM(raw).replace(/\r\n/g, '\n');
|
|
28
|
+
|
|
29
|
+
// Parse YAML frontmatter if present (STATE.md v2 format)
|
|
30
|
+
let frontmatter = {};
|
|
31
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
32
|
+
if (fmMatch) {
|
|
33
|
+
for (const line of fmMatch[1].split('\n')) {
|
|
34
|
+
const kv = line.match(/^(\w+):\s*(.+)/);
|
|
35
|
+
if (kv) {
|
|
36
|
+
const val = kv[2].trim().replace(/^"(.*)"$/, '$1');
|
|
37
|
+
frontmatter[kv[1]] = val;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
28
41
|
|
|
29
42
|
// Extract project name from **Current focus:** line
|
|
30
43
|
let projectName = 'Unknown Project';
|
|
@@ -76,13 +89,23 @@ export async function parseStateFile(projectDir) {
|
|
|
76
89
|
progress = Math.ceil((currentPhaseId / totalPhases) * 100);
|
|
77
90
|
}
|
|
78
91
|
|
|
92
|
+
// Determine phase status from frontmatter or body text
|
|
93
|
+
// "built", "verified", "complete" all mean the current phase is done
|
|
94
|
+
const fmStatus = (frontmatter.status || '').toLowerCase();
|
|
95
|
+
const phaseStatus = ['built', 'verified', 'complete', 'reviewed'].includes(fmStatus)
|
|
96
|
+
? 'complete'
|
|
97
|
+
: ['building', 'planning', 'planned', 'in-progress'].includes(fmStatus)
|
|
98
|
+
? 'in-progress'
|
|
99
|
+
: fmStatus || 'unknown';
|
|
100
|
+
|
|
79
101
|
return {
|
|
80
102
|
projectName,
|
|
81
103
|
currentPhase: {
|
|
82
104
|
id: currentPhaseId,
|
|
83
105
|
total: totalPhases,
|
|
84
106
|
name: phaseName,
|
|
85
|
-
planStatus
|
|
107
|
+
planStatus,
|
|
108
|
+
status: phaseStatus
|
|
86
109
|
},
|
|
87
110
|
lastActivity: {
|
|
88
111
|
date: activityDate,
|
|
@@ -94,7 +117,7 @@ export async function parseStateFile(projectDir) {
|
|
|
94
117
|
if (error.code === 'ENOENT') {
|
|
95
118
|
return {
|
|
96
119
|
projectName: 'Unknown Project',
|
|
97
|
-
currentPhase: { id: 0, total: 0, name: 'Not Started', planStatus: 'N/A' },
|
|
120
|
+
currentPhase: { id: 0, total: 0, name: 'Not Started', planStatus: 'N/A', status: 'unknown' },
|
|
98
121
|
lastActivity: { date: '', description: 'No activity recorded' },
|
|
99
122
|
progress: 0
|
|
100
123
|
};
|
|
@@ -132,7 +155,7 @@ export async function parseRoadmapFile(projectDir) {
|
|
|
132
155
|
|
|
133
156
|
// 2. Parse descriptions from Phase Details: "### Phase NN: Name\n**Goal**: ..."
|
|
134
157
|
const goalMap = new Map();
|
|
135
|
-
const goalRegex = /### Phase (\d+):\s*(.+)\n\*\*Goal
|
|
158
|
+
const goalRegex = /### Phase (\d+):\s*(.+)\n\*\*Goal:?\*\*:?\s*(.+)/g;
|
|
136
159
|
for (const match of content.matchAll(goalRegex)) {
|
|
137
160
|
goalMap.set(parseInt(match[1], 10), match[3].trim());
|
|
138
161
|
}
|
|
@@ -158,11 +181,28 @@ export async function parseRoadmapFile(projectDir) {
|
|
|
158
181
|
progressPhases.push({ id, name, description, status });
|
|
159
182
|
}
|
|
160
183
|
|
|
161
|
-
//
|
|
184
|
+
// 4. Parse H3 Phase Details: "### Phase N: Name\n**Goal:** ..."
|
|
185
|
+
const h3Phases = [];
|
|
186
|
+
const h3Regex = /### Phase (\d+):\s*(.+)\n\*\*Goal\*?\*?:?\*?\*?\s*(.+)/g;
|
|
187
|
+
for (const match of content.matchAll(h3Regex)) {
|
|
188
|
+
const id = parseInt(match[1], 10);
|
|
189
|
+
const name = match[2].trim();
|
|
190
|
+
const description = match[3].trim();
|
|
191
|
+
// Check checkbox map for status, default to not-started
|
|
192
|
+
const cbInfo = checkboxMap.get(id);
|
|
193
|
+
h3Phases.push({
|
|
194
|
+
id,
|
|
195
|
+
name,
|
|
196
|
+
description,
|
|
197
|
+
status: cbInfo?.status || 'not-started'
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Use Progress table if available, then checkbox list, then H3 headings
|
|
162
202
|
let phases;
|
|
163
203
|
if (progressPhases.length > 0) {
|
|
164
204
|
phases = progressPhases;
|
|
165
|
-
} else {
|
|
205
|
+
} else if (checkboxMap.size > 0) {
|
|
166
206
|
phases = [...checkboxMap.entries()]
|
|
167
207
|
.map(([id, info]) => ({
|
|
168
208
|
id,
|
|
@@ -171,6 +211,8 @@ export async function parseRoadmapFile(projectDir) {
|
|
|
171
211
|
status: info.status
|
|
172
212
|
}))
|
|
173
213
|
.sort((a, b) => a.id - b.id);
|
|
214
|
+
} else {
|
|
215
|
+
phases = h3Phases.sort((a, b) => a.id - b.id);
|
|
174
216
|
}
|
|
175
217
|
|
|
176
218
|
const completed = phases.filter(p => p.status === 'complete').length;
|
|
@@ -193,23 +235,45 @@ export async function parseRoadmapFile(projectDir) {
|
|
|
193
235
|
* @param {string} projectDir - Absolute path to the project root
|
|
194
236
|
* @returns {Promise<{projectName: string, currentPhase: object, lastActivity: object, progress: number, phases: Array}>}
|
|
195
237
|
*/
|
|
238
|
+
/**
|
|
239
|
+
* Derive phase statuses by combining roadmap phases with STATE.md context.
|
|
240
|
+
* Phases before the current phase are marked complete.
|
|
241
|
+
* The current phase gets its status from STATE.md.
|
|
242
|
+
* Phases after the current phase keep their roadmap status (typically not-started).
|
|
243
|
+
*
|
|
244
|
+
* @param {Array} phases - Raw phases from parseRoadmapFile
|
|
245
|
+
* @param {{id: number, status: string}} currentPhase - Current phase from parseStateFile
|
|
246
|
+
* @returns {Array} Phases with derived statuses
|
|
247
|
+
*/
|
|
248
|
+
export function derivePhaseStatuses(phases, currentPhase) {
|
|
249
|
+
const currentId = currentPhase.id;
|
|
250
|
+
const currentStatus = currentPhase.status || 'unknown';
|
|
251
|
+
return phases.map(phase => {
|
|
252
|
+
// If the roadmap already has explicit status (from progress table/checkboxes), keep it
|
|
253
|
+
if (phase.status === 'complete') return phase;
|
|
254
|
+
|
|
255
|
+
if (phase.id < currentId) {
|
|
256
|
+
return { ...phase, status: 'complete' };
|
|
257
|
+
}
|
|
258
|
+
if (phase.id === currentId) {
|
|
259
|
+
return { ...phase, status: currentStatus === 'complete' ? 'complete' : 'in-progress' };
|
|
260
|
+
}
|
|
261
|
+
return phase;
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
196
265
|
export async function getDashboardData(projectDir) {
|
|
197
266
|
const [stateData, roadmapData] = await Promise.all([
|
|
198
267
|
parseStateFile(projectDir),
|
|
199
268
|
parseRoadmapFile(projectDir)
|
|
200
269
|
]);
|
|
201
270
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}));
|
|
209
|
-
|
|
210
|
-
// Prefer roadmap progress if phases exist, otherwise use state progress
|
|
211
|
-
const progress = roadmapData.phases.length > 0
|
|
212
|
-
? roadmapData.progress
|
|
271
|
+
const phases = derivePhaseStatuses(roadmapData.phases, stateData.currentPhase);
|
|
272
|
+
|
|
273
|
+
// Recalculate progress from derived phase statuses
|
|
274
|
+
const completedPhases = phases.filter(p => p.status === 'complete').length;
|
|
275
|
+
const progress = phases.length > 0
|
|
276
|
+
? Math.ceil((completedPhases / phases.length) * 100)
|
|
213
277
|
: stateData.progress;
|
|
214
278
|
|
|
215
279
|
return {
|
|
@@ -109,16 +109,19 @@ export async function getPhaseDetail(projectDir, phaseId) {
|
|
|
109
109
|
const phaseFiles = await readdir(phaseFullPath);
|
|
110
110
|
|
|
111
111
|
// Filter and sort PLAN.md files
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
// Supports both naming conventions:
|
|
113
|
+
// - NN-NN-PLAN.md (plan ID embedded in filename)
|
|
114
|
+
// - PLAN.md (single plan per phase, ID derived from phase directory)
|
|
115
|
+
const planRegex = /^(?:\d{2}-\d{2}-)?PLAN\.md$/;
|
|
114
116
|
const planFiles = phaseFiles
|
|
115
117
|
.filter(f => planRegex.test(f))
|
|
116
118
|
.sort();
|
|
117
119
|
|
|
118
120
|
// Build summary paths and read them in parallel
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const
|
|
121
|
+
// Derive planId from filename (NN-NN-PLAN.md) or phase directory (PLAN.md -> NN-01)
|
|
122
|
+
const summaryPaths = planFiles.map((planFile, index) => {
|
|
123
|
+
const idMatch = planFile.match(/^(\d{2}-\d{2})-PLAN\.md$/);
|
|
124
|
+
const planId = idMatch ? idMatch[1] : `${phaseId.padStart(2, '0')}-${String(index + 1).padStart(2, '0')}`;
|
|
122
125
|
return { planId, planFile, summaryPath: join(phaseFullPath, `SUMMARY-${planId}.md`) };
|
|
123
126
|
});
|
|
124
127
|
|
|
@@ -196,25 +199,28 @@ export async function getPhaseDocument(projectDir, phaseId, planId, docType) {
|
|
|
196
199
|
const phaseName = formatPhaseName(phaseDir.name);
|
|
197
200
|
const phaseFullPath = join(phasesDir, phaseDir.name);
|
|
198
201
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
// Try plan ID-prefixed filename first, then fall back to plain PLAN.md
|
|
203
|
+
// Supports both "01-01-PLAN.md" and "PLAN.md" naming conventions
|
|
204
|
+
const fileNames = docType === 'plan'
|
|
205
|
+
? [`${planId}-PLAN.md`, 'PLAN.md']
|
|
206
|
+
: [`SUMMARY-${planId}.md`];
|
|
202
207
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
208
|
+
for (const fileName of fileNames) {
|
|
209
|
+
const filePath = validatePath(phaseFullPath, fileName);
|
|
210
|
+
try {
|
|
211
|
+
const doc = await readMarkdownFile(filePath);
|
|
212
|
+
return {
|
|
213
|
+
phaseId,
|
|
214
|
+
planId,
|
|
215
|
+
docType,
|
|
216
|
+
phaseName,
|
|
217
|
+
frontmatter: doc.frontmatter,
|
|
218
|
+
html: doc.html
|
|
219
|
+
};
|
|
220
|
+
} catch (error) {
|
|
221
|
+
if (error.code === 'ENOENT') continue;
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
219
224
|
}
|
|
225
|
+
return null;
|
|
220
226
|
}
|
|
@@ -35,7 +35,7 @@ async function countPlansForPhase(projectDir, phaseId) {
|
|
|
35
35
|
if (!phaseDir) return 0;
|
|
36
36
|
|
|
37
37
|
const phaseFiles = await readdir(join(phasesDir, phaseDir.name));
|
|
38
|
-
return phaseFiles.filter(f =>
|
|
38
|
+
return phaseFiles.filter(f => /^(?:\d{2}-\d{2}-)?PLAN\.md$/.test(f)).length;
|
|
39
39
|
} catch (err) {
|
|
40
40
|
if (err.code === 'ENOENT') return 0;
|
|
41
41
|
throw err;
|
|
@@ -52,7 +52,7 @@ function extractAllDependencies(roadmapContent) {
|
|
|
52
52
|
const dependencyMap = new Map();
|
|
53
53
|
|
|
54
54
|
// Match Phase Details sections: "### Phase NN: ..." followed by "**Depends on**: ..."
|
|
55
|
-
const sectionRegex = /### Phase (\d+):[\s\S]*?\*\*Depends on
|
|
55
|
+
const sectionRegex = /### Phase (\d+):[\s\S]*?\*\*Depends on:?\*\*:?\s*([^\n]+)/g;
|
|
56
56
|
let match;
|
|
57
57
|
|
|
58
58
|
while ((match = sectionRegex.exec(roadmapContent)) !== null) {
|
|
@@ -92,7 +92,7 @@ function extractMilestones(roadmapContent) {
|
|
|
92
92
|
const projectTitle = titleMatch ? titleMatch[1].trim() : 'Project';
|
|
93
93
|
|
|
94
94
|
// Parse explicit milestones: "## Milestone: Name\n\n**Goal:** ...\n**Phases:** N - M"
|
|
95
|
-
const milestoneRegex = /## Milestone:\s*(.+)\n
|
|
95
|
+
const milestoneRegex = /## Milestone:\s*(.+)\n+\*\*Goal:?\*\*:?\s*(.+)\n\*\*Phases:?\*\*:?\s*(\d+)\s*-\s*(\d+)/g;
|
|
96
96
|
const explicit = [];
|
|
97
97
|
for (const match of roadmapContent.matchAll(milestoneRegex)) {
|
|
98
98
|
explicit.push({
|
|
@@ -10,14 +10,15 @@
|
|
|
10
10
|
</header>
|
|
11
11
|
<%
|
|
12
12
|
// Map verification status to CSS status-badge data-status values
|
|
13
|
+
var vStatus = verification.status || verification.verdict || 'unknown';
|
|
13
14
|
var verificationCssStatus = 'not-started';
|
|
14
|
-
if (
|
|
15
|
-
else if (
|
|
16
|
-
else if (
|
|
15
|
+
if (vStatus === 'passed') verificationCssStatus = 'complete';
|
|
16
|
+
else if (vStatus === 'failed') verificationCssStatus = 'blocked';
|
|
17
|
+
else if (vStatus === 'partial') verificationCssStatus = 'in-progress';
|
|
17
18
|
%>
|
|
18
19
|
<p>
|
|
19
20
|
<span class="status-badge" data-status="<%= verificationCssStatus %>">
|
|
20
|
-
<%=
|
|
21
|
+
<%= vStatus.toUpperCase() %>
|
|
21
22
|
</span>
|
|
22
23
|
<% if (verification.verified) { %>
|
|
23
24
|
Verified: <%= new Date(verification.verified).toLocaleString() %>
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"homepage": "https://github.com/SienkLogic/plan-build-run",
|
|
12
12
|
"repository": "https://github.com/SienkLogic/plan-build-run",
|
|
13
13
|
"license": "MIT",
|
|
14
|
-
"logo": "assets/logo.
|
|
14
|
+
"logo": "../assets/logo.svg",
|
|
15
15
|
"keywords": ["cursor", "context-engineering", "development-workflow", "subagent-delegation"],
|
|
16
16
|
"category": "developer-tools",
|
|
17
17
|
"tags": ["planning", "workflow", "structured-development", "context-management"],
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v2.0.0 (2026-02-19)
|
|
4
|
+
|
|
5
|
+
Initial release of Plan-Build-Run for Cursor.
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- 21 skills covering the full development lifecycle: begin, plan, build, review, debug, and more
|
|
10
|
+
- 10 specialized agents with fresh context windows for delegation without context rot
|
|
11
|
+
- Shared hook scripts with the Claude Code plugin for consistent behavior
|
|
12
|
+
- Cross-plugin compatibility: shared `.planning/` state directory works with both Cursor and Claude Code
|
|
13
|
+
- File-based state management with structured planning, execution, and verification phases
|
|
14
|
+
- Atomic commits with deviation handling and self-verification
|
|
15
|
+
- Goal-backward verification ensuring builds match plans
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Plan-Build-Run for Cursor
|
|
2
|
+
|
|
3
|
+
A structured development workflow plugin for Cursor that solves context rot through disciplined subagent delegation, file-based state, and goal-backward verification.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Automated Setup (Recommended)
|
|
8
|
+
|
|
9
|
+
The setup script creates symlinks from your project's `.cursor/` directory to the PBR plugin, so rules and agents are discovered automatically by Cursor.
|
|
10
|
+
|
|
11
|
+
**macOS / Linux:**
|
|
12
|
+
```bash
|
|
13
|
+
cd /path/to/your/project
|
|
14
|
+
bash /path/to/plan-build-run/plugins/cursor-pbr/setup.sh
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Windows (PowerShell):**
|
|
18
|
+
```powershell
|
|
19
|
+
cd C:\path\to\your\project
|
|
20
|
+
powershell -ExecutionPolicy Bypass -File C:\path\to\plan-build-run\plugins\cursor-pbr\setup.ps1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This installs:
|
|
24
|
+
- `.cursor/rules/pbr-workflow.mdc` — Workflow rules (auto-loaded when `.planning/` exists)
|
|
25
|
+
- `.cursor/agents/*.md` — 10 specialized agent definitions
|
|
26
|
+
|
|
27
|
+
### Manual Setup
|
|
28
|
+
|
|
29
|
+
If you prefer not to use the setup script:
|
|
30
|
+
|
|
31
|
+
1. Copy or symlink `rules/pbr-workflow.mdc` into your project's `.cursor/rules/` directory
|
|
32
|
+
2. Copy or symlink all files from `agents/` into your project's `.cursor/agents/` directory
|
|
33
|
+
3. Skills (in `skills/`) are prompt templates — paste a skill's `SKILL.md` content into Cursor chat to invoke it, or reference the skill directory if Cursor supports skill discovery
|
|
34
|
+
|
|
35
|
+
### Uninstall
|
|
36
|
+
|
|
37
|
+
Remove the symlinks created by setup:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
rm .cursor/rules/pbr-workflow.mdc
|
|
41
|
+
rm .cursor/agents/*.md # only PBR agent files
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
The core workflow follows four steps per phase:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
/pbr:begin — Define your project: requirements, research, roadmap
|
|
50
|
+
/pbr:plan 1 — Create a detailed plan for phase 1
|
|
51
|
+
/pbr:build 1 — Execute the plan with atomic commits
|
|
52
|
+
/pbr:review 1 — Verify the build matched the plan
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Repeat `plan` / `build` / `review` for each phase in your roadmap.
|
|
56
|
+
|
|
57
|
+
## Skills (21)
|
|
58
|
+
|
|
59
|
+
| Skill | Description |
|
|
60
|
+
|-------|-------------|
|
|
61
|
+
| begin | Start a new project. Deep questioning, research, requirements, and roadmap. |
|
|
62
|
+
| build | Execute all plans in a phase. Spawns agents to build in parallel, commits atomically. |
|
|
63
|
+
| config | Configure settings: depth, model profiles, features, git, and gates. |
|
|
64
|
+
| continue | Execute the next logical step automatically. No prompts, no decisions. |
|
|
65
|
+
| debug | Systematic debugging with hypothesis testing. Persistent across sessions. |
|
|
66
|
+
| discuss | Talk through a phase before planning. Identifies gray areas and captures decisions. |
|
|
67
|
+
| explore | Explore ideas, think through approaches, and route insights to the right artifacts. |
|
|
68
|
+
| health | Check planning directory integrity. Find and fix corrupted state. |
|
|
69
|
+
| help | Command reference and workflow guide. |
|
|
70
|
+
| import | Import external plans. Validates context, detects conflicts, generates PLAN.md. |
|
|
71
|
+
| milestone | Manage milestones: new, complete, audit, gaps. |
|
|
72
|
+
| note | Zero-friction idea capture. Append, list, or promote notes to todos. |
|
|
73
|
+
| pause | Save your current session state for later resumption. |
|
|
74
|
+
| plan | Create a detailed plan for a phase. Research, plan, and verify before building. |
|
|
75
|
+
| quick | Execute an ad-hoc task with atomic commits. Skips full plan/review. |
|
|
76
|
+
| resume | Pick up where you left off. Restores context and suggests next action. |
|
|
77
|
+
| review | Verify the build matched the plan. Automated checks plus walkthrough. |
|
|
78
|
+
| scan | Analyze an existing codebase. Maps structure, architecture, conventions, and concerns. |
|
|
79
|
+
| setup | Onboarding wizard. Initialize project, select models, verify setup. |
|
|
80
|
+
| status | Show current project status and suggest what to do next. |
|
|
81
|
+
| todo | File-based persistent todos. Add, list, complete — survives sessions. |
|
|
82
|
+
|
|
83
|
+
Skills live in `skills/{name}/SKILL.md`. Each is a self-contained prompt that can be pasted into Cursor chat or invoked as a slash command if Cursor discovers the plugin manifest.
|
|
84
|
+
|
|
85
|
+
## Agents (10)
|
|
86
|
+
|
|
87
|
+
| Agent | Description |
|
|
88
|
+
|-------|-------------|
|
|
89
|
+
| codebase-mapper | Explores codebases and writes structured analysis across four focus areas. |
|
|
90
|
+
| debugger | Systematic debugging using scientific method with hypothesis testing and evidence tracking. |
|
|
91
|
+
| executor | Executes plan tasks with atomic commits, deviation handling, and self-verification. |
|
|
92
|
+
| general | Lightweight agent for ad-hoc tasks that don't fit specialized roles. |
|
|
93
|
+
| integration-checker | Cross-phase integration and E2E flow verification. |
|
|
94
|
+
| plan-checker | Verifies plans will achieve phase goals before execution via goal-backward analysis. |
|
|
95
|
+
| planner | Creates executable phase plans with task breakdown, dependency analysis, and wave assignment. |
|
|
96
|
+
| researcher | Unified research agent for project domains and implementation approaches. |
|
|
97
|
+
| synthesizer | Fast synthesis of multiple research outputs into coherent recommendations. |
|
|
98
|
+
| verifier | Goal-backward phase verification against the real codebase. |
|
|
99
|
+
|
|
100
|
+
## Configuration
|
|
101
|
+
|
|
102
|
+
Plan-Build-Run stores all state in a `.planning/` directory at your project root:
|
|
103
|
+
|
|
104
|
+
- `.planning/config.json` — Workflow settings (~62 properties across 12 keys)
|
|
105
|
+
- `.planning/STATE.md` — Current position and status
|
|
106
|
+
- `.planning/ROADMAP.md` — Phase structure, goals, and dependencies
|
|
107
|
+
- `.planning/phases/NN-slug/` — Per-phase plans, summaries, and verification reports
|
|
108
|
+
|
|
109
|
+
Run `/pbr:config` to interactively adjust settings like depth, model profiles, and gate behavior.
|
|
110
|
+
|
|
111
|
+
## Cross-Plugin Compatibility
|
|
112
|
+
|
|
113
|
+
This plugin works alongside the Claude Code version of Plan-Build-Run. Both plugins share the same `.planning/` directory and file formats, so you can switch between Cursor and Claude Code without losing state. Hook scripts under `plugins/pbr/scripts/` are shared between both plugins via relative paths.
|
|
114
|
+
|
|
115
|
+
## Links
|
|
116
|
+
|
|
117
|
+
- Repository: [https://github.com/SienkLogic/plan-build-run](https://github.com/SienkLogic/plan-build-run)
|
|
118
|
+
- License: MIT
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codebase-mapper
|
|
3
|
+
description: "Explores existing codebases and writes structured analysis documents. Four focus areas: tech, arch, quality, concerns."
|
|
4
|
+
model: sonnet
|
|
5
|
+
readonly: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Plan-Build-Run Codebase Mapper
|
|
9
|
+
|
|
10
|
+
You are **codebase-mapper**, the codebase analysis agent for the Plan-Build-Run development system. You explore existing codebases and produce structured documentation that helps other agents (and humans) understand the project's technology stack, architecture, conventions, and concerns.
|
|
11
|
+
|
|
12
|
+
## Core Philosophy
|
|
13
|
+
|
|
14
|
+
- **Document quality over brevity.** Be thorough. Other agents depend on your analysis for accurate planning and execution.
|
|
15
|
+
- **Always include file paths.** Every claim must reference the actual code location. Never say "the config file" — say "`tsconfig.json` at project root" or "`src/config/database.ts`".
|
|
16
|
+
- **Write current state only.** No temporal language ("recently added", "will be changed", "was refactored"). Document WHAT IS, not what was or will be.
|
|
17
|
+
- **Be prescriptive, not descriptive.** When documenting conventions: "Use this pattern" not "This pattern exists."
|
|
18
|
+
- **Evidence-based.** Read the actual files. Don't guess from file names or directory structures.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
### Forbidden Files
|
|
23
|
+
|
|
24
|
+
When exploring, NEVER commit or recommend committing:
|
|
25
|
+
- `.env` files (except `.env.example` or `.env.template`)
|
|
26
|
+
- `*.key`, `*.pem`, `*.pfx`, `*.p12` — private keys and certificates
|
|
27
|
+
- Files containing `credential` or `secret` in their name
|
|
28
|
+
- `*.keystore`, `*.jks` — Java keystores
|
|
29
|
+
- `id_rsa`, `id_ed25519` — SSH keys
|
|
30
|
+
|
|
31
|
+
If encountered, note in CONCERNS.md under "Security Considerations" but do NOT include contents.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Focus Areas
|
|
36
|
+
|
|
37
|
+
You receive ONE focus area per invocation. All output is written to `.planning/codebase/` (create if needed). **Do NOT commit** — the orchestrator handles commits.
|
|
38
|
+
|
|
39
|
+
| Focus | Output Files | Templates |
|
|
40
|
+
|-------|-------------|-----------|
|
|
41
|
+
| `tech` | STACK.md, INTEGRATIONS.md | `templates/codebase/STACK.md.tmpl`, `templates/codebase/INTEGRATIONS.md.tmpl` |
|
|
42
|
+
| `arch` | ARCHITECTURE.md, STRUCTURE.md | `templates/codebase/ARCHITECTURE.md.tmpl`, `templates/codebase/STRUCTURE.md.tmpl` |
|
|
43
|
+
| `quality` | CONVENTIONS.md, TESTING.md | `templates/codebase/CONVENTIONS.md.tmpl`, `templates/codebase/TESTING.md.tmpl` |
|
|
44
|
+
| `concerns` | CONCERNS.md | `templates/codebase/CONCERNS.md.tmpl` |
|
|
45
|
+
|
|
46
|
+
Read the relevant `.tmpl` file(s) and fill in all placeholder fields with data from your analysis.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Exploration Process
|
|
51
|
+
|
|
52
|
+
> **Cross-platform**: Use Glob, Read, and Grep tools — not Bash `ls`, `find`, or `cat`. Bash file commands fail on Windows.
|
|
53
|
+
|
|
54
|
+
1. **Orientation** — Glob for source files, config files, docs, Docker, CI/CD to understand project shape.
|
|
55
|
+
2. **Deep Inspection** — Read 5-10+ key files per focus area (package.json, configs, entry points, core modules).
|
|
56
|
+
3. **Pattern Recognition** — Identify repeated conventions across the codebase.
|
|
57
|
+
4. **Write Documentation** — Write to `.planning/codebase/` using the templates. Write documents as you go to manage context.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Output Budget
|
|
62
|
+
|
|
63
|
+
| Artifact | Target | Hard Limit |
|
|
64
|
+
|----------|--------|------------|
|
|
65
|
+
| STACK.md | ≤ 800 tokens | 1,200 tokens |
|
|
66
|
+
| INTEGRATIONS.md | ≤ 600 tokens | 1,000 tokens |
|
|
67
|
+
| ARCHITECTURE.md | ≤ 1,000 tokens | 1,500 tokens |
|
|
68
|
+
| STRUCTURE.md | ≤ 600 tokens | 1,000 tokens |
|
|
69
|
+
| CONVENTIONS.md | ≤ 800 tokens | 1,200 tokens |
|
|
70
|
+
| TESTING.md | ≤ 600 tokens | 1,000 tokens |
|
|
71
|
+
| CONCERNS.md | ≤ 600 tokens | 1,000 tokens |
|
|
72
|
+
| Total per focus area (2 docs) | ≤ 1,400 tokens | 2,200 tokens |
|
|
73
|
+
|
|
74
|
+
**Guidance**: Tables over prose. Version numbers and file paths are the high-value data — skip explanations of what well-known tools do. The planner reads these documents to make decisions; give it decision-relevant facts, not tutorials.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Quality Standards
|
|
79
|
+
|
|
80
|
+
1. Every claim must reference actual file paths (with line numbers when possible)
|
|
81
|
+
2. Verify versions from package.json/lock files, not from memory
|
|
82
|
+
3. Read at least 5-10 key files per focus area — file names lie, check source
|
|
83
|
+
4. Include actual code examples from the codebase, not generic examples
|
|
84
|
+
5. Stop before 50% context usage — write documents incrementally
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Universal Anti-Patterns
|
|
89
|
+
|
|
90
|
+
1. DO NOT guess or assume — read actual files for evidence
|
|
91
|
+
2. DO NOT trust SUMMARY.md or other agent claims without verifying codebase
|
|
92
|
+
3. DO NOT use vague language — be specific and evidence-based
|
|
93
|
+
4. DO NOT present training knowledge as verified fact
|
|
94
|
+
5. DO NOT exceed your role — recommend the correct agent if task doesn't fit
|
|
95
|
+
6. DO NOT modify files outside your designated scope
|
|
96
|
+
7. DO NOT add features or scope not requested — log to deferred
|
|
97
|
+
8. DO NOT skip steps in your protocol, even for "obvious" cases
|
|
98
|
+
9. DO NOT contradict locked decisions in CONTEXT.md
|
|
99
|
+
10. DO NOT implement deferred ideas from CONTEXT.md
|
|
100
|
+
11. DO NOT consume more than 50% context before producing output
|
|
101
|
+
12. DO NOT read agent .md files from agents/ — auto-loaded via subagent_type
|
|
102
|
+
|
|
103
|
+
Additionally for this agent:
|
|
104
|
+
|
|
105
|
+
1. DO NOT guess technology versions — read package.json or equivalent
|
|
106
|
+
2. DO NOT use temporal language ("recently added", "old code")
|
|
107
|
+
3. DO NOT produce generic documentation — every claim must reference this specific codebase
|
|
108
|
+
4. DO NOT commit the output — the orchestrator handles commits
|