@girardmedia/bootspring 2.0.13 → 2.0.15
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/cli/build.js +16 -75
- package/generators/templates/agents.template.js +16 -11
- package/generators/templates/build-planning.template.js +11 -11
- package/generators/templates/claude.template.js +26 -18
- package/mcp/contracts/mcp-contract.v1.json +1 -1
- package/mcp/tools/build-tool.js +8 -70
- package/package.json +1 -1
package/cli/build.js
CHANGED
|
@@ -249,87 +249,26 @@ async function buildNextTask(projectRoot, _args = {}) {
|
|
|
249
249
|
|
|
250
250
|
if (!nextTask) {
|
|
251
251
|
console.log(`${c.green}All tasks complete!${c.reset}`);
|
|
252
|
-
clearCurrentTask(projectRoot);
|
|
253
252
|
return;
|
|
254
253
|
}
|
|
255
254
|
|
|
256
255
|
// Mark task as in progress
|
|
257
256
|
buildState.updateProgress(projectRoot, nextTask.id, 'in_progress');
|
|
258
257
|
|
|
259
|
-
// Generate the task prompt
|
|
260
|
-
const prompt = generateTaskPrompt(nextTask, projectRoot);
|
|
261
|
-
|
|
262
|
-
// Write to CURRENT_TASK.md for Claude Code to read
|
|
263
|
-
const taskFile = writeCurrentTask(projectRoot, nextTask, prompt);
|
|
264
|
-
|
|
265
258
|
console.log(`
|
|
266
|
-
${c.green}${c.bold}✓ Task
|
|
259
|
+
${c.green}${c.bold}✓ Task ${nextTask.id} now in progress${c.reset}
|
|
267
260
|
|
|
268
261
|
${c.bold}Task:${c.reset} ${nextTask.title}
|
|
269
|
-
${c.bold}
|
|
262
|
+
${c.bold}Phase:${c.reset} ${nextTask.phase || 'MVP'}
|
|
263
|
+
${c.bold}Source:${c.reset} ${nextTask.source || 'PRD.md'}
|
|
270
264
|
|
|
271
265
|
${c.cyan}${c.bold}Tell Claude Code:${c.reset}
|
|
272
|
-
"Read planning/
|
|
266
|
+
"Read planning/TASK_QUEUE.md, find ${nextTask.id}, and implement it"
|
|
273
267
|
|
|
274
|
-
${c.dim}
|
|
268
|
+
${c.dim}When done, run: bootspring build done${c.reset}
|
|
275
269
|
`);
|
|
276
270
|
}
|
|
277
271
|
|
|
278
|
-
/**
|
|
279
|
-
* Write current task to planning/CURRENT_TASK.md
|
|
280
|
-
*/
|
|
281
|
-
function writeCurrentTask(projectRoot, task, prompt) {
|
|
282
|
-
const planningDir = path.join(projectRoot, 'planning');
|
|
283
|
-
if (!fs.existsSync(planningDir)) {
|
|
284
|
-
fs.mkdirSync(planningDir, { recursive: true });
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const taskFile = path.join(planningDir, 'CURRENT_TASK.md');
|
|
288
|
-
const content = `# Current Task
|
|
289
|
-
|
|
290
|
-
> This file is auto-generated by bootspring. Claude Code should read this and implement the task.
|
|
291
|
-
|
|
292
|
-
---
|
|
293
|
-
|
|
294
|
-
## ${task.title}
|
|
295
|
-
|
|
296
|
-
${prompt}
|
|
297
|
-
|
|
298
|
-
---
|
|
299
|
-
|
|
300
|
-
## When Complete
|
|
301
|
-
|
|
302
|
-
Run this command to mark the task done and get the next task:
|
|
303
|
-
|
|
304
|
-
\`\`\`bash
|
|
305
|
-
bootspring build done
|
|
306
|
-
\`\`\`
|
|
307
|
-
|
|
308
|
-
Or to skip this task:
|
|
309
|
-
|
|
310
|
-
\`\`\`bash
|
|
311
|
-
bootspring build skip
|
|
312
|
-
\`\`\`
|
|
313
|
-
|
|
314
|
-
---
|
|
315
|
-
|
|
316
|
-
*Task ID: ${task.id}*
|
|
317
|
-
*Generated: ${new Date().toISOString()}*
|
|
318
|
-
`;
|
|
319
|
-
|
|
320
|
-
fs.writeFileSync(taskFile, content);
|
|
321
|
-
return taskFile;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Clear the current task file
|
|
326
|
-
*/
|
|
327
|
-
function clearCurrentTask(projectRoot) {
|
|
328
|
-
const taskFile = path.join(projectRoot, 'planning', 'CURRENT_TASK.md');
|
|
329
|
-
if (fs.existsSync(taskFile)) {
|
|
330
|
-
fs.unlinkSync(taskFile);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
272
|
|
|
334
273
|
/**
|
|
335
274
|
* Generate a prompt for Claude Code to execute
|
|
@@ -400,23 +339,25 @@ async function markTaskDone(projectRoot, _args = {}) {
|
|
|
400
339
|
const nextTask = buildState.getNextTask(projectRoot);
|
|
401
340
|
|
|
402
341
|
if (nextTask) {
|
|
403
|
-
// Mark as in progress
|
|
342
|
+
// Mark as in progress
|
|
404
343
|
buildState.updateProgress(projectRoot, nextTask.id, 'in_progress');
|
|
405
|
-
const prompt = generateTaskPrompt(nextTask, projectRoot);
|
|
406
|
-
const taskFile = writeCurrentTask(projectRoot, nextTask, prompt);
|
|
407
344
|
|
|
408
345
|
console.log(`
|
|
409
|
-
${c.cyan}${c.bold}Next
|
|
410
|
-
${c.dim}File: ${path.relative(projectRoot, taskFile)}${c.reset}
|
|
346
|
+
${c.cyan}${c.bold}▶ Next: ${nextTask.title}${c.reset} (${nextTask.id})
|
|
411
347
|
|
|
412
|
-
${c.bold}Continue
|
|
348
|
+
${c.bold}Continue building:${c.reset} Read planning/TASK_QUEUE.md, implement ${nextTask.id}
|
|
349
|
+
${c.dim}Then run: bootspring build done${c.reset}
|
|
413
350
|
`);
|
|
414
351
|
} else {
|
|
415
|
-
clearCurrentTask(projectRoot);
|
|
416
352
|
console.log(`
|
|
417
|
-
${c.green}${c.bold}🎉
|
|
353
|
+
${c.green}${c.bold}🎉 MVP BUILD COMPLETE!${c.reset}
|
|
354
|
+
|
|
355
|
+
All ${stats.total} tasks finished. Your MVP is ready.
|
|
418
356
|
|
|
419
|
-
|
|
357
|
+
${c.bold}Next steps:${c.reset}
|
|
358
|
+
1. Review the generated code
|
|
359
|
+
2. Run tests: ${c.cyan}npm test${c.reset}
|
|
360
|
+
3. Deploy: ${c.cyan}bootspring deploy${c.reset}
|
|
420
361
|
`);
|
|
421
362
|
}
|
|
422
363
|
}
|
|
@@ -42,15 +42,20 @@ function generate(config) {
|
|
|
42
42
|
sections.push('');
|
|
43
43
|
|
|
44
44
|
// Task System
|
|
45
|
-
sections.push('##
|
|
45
|
+
sections.push('## Build Loop');
|
|
46
46
|
sections.push('');
|
|
47
|
-
sections.push('
|
|
47
|
+
sections.push('**Start building:**');
|
|
48
|
+
sections.push('```');
|
|
49
|
+
sections.push('bootspring build next');
|
|
50
|
+
sections.push('```');
|
|
51
|
+
sections.push('');
|
|
52
|
+
sections.push('This loops through all tasks:');
|
|
53
|
+
sections.push('1. Find in_progress task in `planning/TASK_QUEUE.md`');
|
|
54
|
+
sections.push('2. Implement following acceptance criteria');
|
|
55
|
+
sections.push('3. Run `bootspring build done`');
|
|
56
|
+
sections.push('4. Continue to next task (auto-queued)');
|
|
48
57
|
sections.push('');
|
|
49
|
-
sections.push('
|
|
50
|
-
sections.push('2. Implement the task following acceptance criteria');
|
|
51
|
-
sections.push('3. Run quality checks');
|
|
52
|
-
sections.push('4. Commit changes');
|
|
53
|
-
sections.push('5. Run `bootspring build done` to get the next task');
|
|
58
|
+
sections.push('**Keep looping until MVP complete.**');
|
|
54
59
|
sections.push('');
|
|
55
60
|
|
|
56
61
|
// Stack - Be specific about versions
|
|
@@ -129,7 +134,7 @@ function generatePlanningAgents(_config) {
|
|
|
129
134
|
|
|
130
135
|
sections.push('## Current Task');
|
|
131
136
|
sections.push('');
|
|
132
|
-
sections.push('
|
|
137
|
+
sections.push('Find the task with `status: in_progress` in `TASK_QUEUE.md`.');
|
|
133
138
|
sections.push('');
|
|
134
139
|
|
|
135
140
|
sections.push('## Commands');
|
|
@@ -145,16 +150,16 @@ function generatePlanningAgents(_config) {
|
|
|
145
150
|
sections.push('');
|
|
146
151
|
sections.push('| File | Purpose |');
|
|
147
152
|
sections.push('|------|---------|');
|
|
148
|
-
sections.push('| `
|
|
153
|
+
sections.push('| `TASK_QUEUE.md` | All tasks - find in_progress task |');
|
|
149
154
|
sections.push('| `TODO.md` | Full task checklist |');
|
|
150
155
|
sections.push('| `BUILD_STATE.json` | Build state (do not edit) |');
|
|
151
|
-
sections.push('| `
|
|
156
|
+
sections.push('| `TASK_QUEUE.md` | Ordered task queue |');
|
|
152
157
|
sections.push('| `CONTEXT.md` | Build context summary |');
|
|
153
158
|
sections.push('');
|
|
154
159
|
|
|
155
160
|
sections.push('## Workflow');
|
|
156
161
|
sections.push('');
|
|
157
|
-
sections.push('1.
|
|
162
|
+
sections.push('1. Find in_progress task in `TASK_QUEUE.md`');
|
|
158
163
|
sections.push('2. Implement in the main codebase (not here)');
|
|
159
164
|
sections.push('3. Ensure acceptance criteria met');
|
|
160
165
|
sections.push('4. Run `npm run lint && npm run test`');
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Generates planning artifacts for the autonomous build loop:
|
|
5
5
|
* - MASTER_PLAN.md - Vision + phases + progress tracker
|
|
6
6
|
* - TODO.md - Checkbox list by phase
|
|
7
|
-
* -
|
|
7
|
+
* - TASK_QUEUE.md - Ordered tasks with acceptance criteria
|
|
8
8
|
* - CONTEXT.md - Condensed context for AI iterations
|
|
9
9
|
*
|
|
10
10
|
* @package bootspring
|
|
@@ -44,9 +44,9 @@ function generateAll(projectRoot, docs, tasks, options = {}) {
|
|
|
44
44
|
fs.writeFileSync(todoPath, todo);
|
|
45
45
|
files.todo = todoPath;
|
|
46
46
|
|
|
47
|
-
// Generate
|
|
47
|
+
// Generate TASK_QUEUE.md
|
|
48
48
|
const queue = generateImplementationQueue(tasks, options);
|
|
49
|
-
const queuePath = path.join(planningDir, '
|
|
49
|
+
const queuePath = path.join(planningDir, 'TASK_QUEUE.md');
|
|
50
50
|
fs.writeFileSync(queuePath, queue);
|
|
51
51
|
files.implementationQueue = queuePath;
|
|
52
52
|
|
|
@@ -86,11 +86,11 @@ bootspring build status # View progress
|
|
|
86
86
|
|
|
87
87
|
## Current Task
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
Find the task with \`status: in_progress\` in \`TASK_QUEUE.md\`.
|
|
90
90
|
|
|
91
91
|
## Workflow
|
|
92
92
|
|
|
93
|
-
1.
|
|
93
|
+
1. Find in_progress task in \`TASK_QUEUE.md\`
|
|
94
94
|
2. Implement in the main codebase (not in this folder)
|
|
95
95
|
3. Ensure acceptance criteria are met
|
|
96
96
|
4. Run quality checks: \`npm run lint && npm run test\`
|
|
@@ -101,10 +101,10 @@ Read \`CURRENT_TASK.md\` for the task you should implement now.
|
|
|
101
101
|
|
|
102
102
|
| File | Purpose |
|
|
103
103
|
|------|---------|
|
|
104
|
-
| \`
|
|
104
|
+
| \`TASK_QUEUE.md\` | All tasks - find in_progress task |
|
|
105
105
|
| \`TODO.md\` | Full task checklist |
|
|
106
106
|
| \`BUILD_STATE.json\` | Build state (do not edit directly) |
|
|
107
|
-
| \`
|
|
107
|
+
| \`TASK_QUEUE.md\` | Ordered task queue |
|
|
108
108
|
| \`CONTEXT.md\` | Build context summary |
|
|
109
109
|
|
|
110
110
|
## Boundaries
|
|
@@ -301,10 +301,10 @@ function generateTodo(tasks, options = {}) {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
/**
|
|
304
|
-
* Generate
|
|
304
|
+
* Generate TASK_QUEUE.md
|
|
305
305
|
* @param {array} tasks - Extracted tasks
|
|
306
306
|
* @param {object} options - Options
|
|
307
|
-
* @returns {string}
|
|
307
|
+
* @returns {string} TASK_QUEUE.md content
|
|
308
308
|
*/
|
|
309
309
|
function generateImplementationQueue(tasks, options = {}) {
|
|
310
310
|
const projectName = options.projectName || 'Project';
|
|
@@ -642,9 +642,9 @@ function updateFromState(projectRoot, state) {
|
|
|
642
642
|
const todo = generateTodo(tasks, { projectName: state.projectName });
|
|
643
643
|
fs.writeFileSync(path.join(planningDir, 'TODO.md'), todo);
|
|
644
644
|
|
|
645
|
-
// Regenerate
|
|
645
|
+
// Regenerate TASK_QUEUE.md
|
|
646
646
|
const queue = generateImplementationQueue(tasks, { projectName: state.projectName });
|
|
647
|
-
fs.writeFileSync(path.join(planningDir, '
|
|
647
|
+
fs.writeFileSync(path.join(planningDir, 'TASK_QUEUE.md'), queue);
|
|
648
648
|
}
|
|
649
649
|
|
|
650
650
|
module.exports = {
|
|
@@ -32,7 +32,7 @@ function generate(config) {
|
|
|
32
32
|
sections.push('');
|
|
33
33
|
sections.push('### Before Writing ANY Code');
|
|
34
34
|
sections.push('1. Read `planning/MASTER_PLAN.md` - Overall vision and phases');
|
|
35
|
-
sections.push('2. Read `planning/
|
|
35
|
+
sections.push('2. Read `planning/TASK_QUEUE.md` - Your specific task');
|
|
36
36
|
sections.push('3. Read `planning/CONTEXT.md` - Current build context');
|
|
37
37
|
sections.push('4. Understand the acceptance criteria before implementing');
|
|
38
38
|
sections.push('');
|
|
@@ -52,11 +52,10 @@ function generate(config) {
|
|
|
52
52
|
sections.push('| File | Purpose | When to Read |');
|
|
53
53
|
sections.push('|------|---------|--------------|');
|
|
54
54
|
sections.push('| `MASTER_PLAN.md` | Overall vision, phases, success criteria | **Always read first** |');
|
|
55
|
-
sections.push('| `
|
|
55
|
+
sections.push('| `TASK_QUEUE.md` | All tasks with acceptance criteria, find current task by status | **Before each task** |');
|
|
56
56
|
sections.push('| `CONTEXT.md` | Current build context and decisions | Before each task |');
|
|
57
|
-
sections.push('| `IMPLEMENTATION_QUEUE.md` | Ordered list of all tasks | To understand scope |');
|
|
58
57
|
sections.push('| `TODO.md` | Checkbox task list | Update after completing |');
|
|
59
|
-
sections.push('| `BUILD_STATE.json` | Machine state
|
|
58
|
+
sections.push('| `BUILD_STATE.json` | Machine state - shows current task ID | Reference only |');
|
|
60
59
|
sections.push('');
|
|
61
60
|
sections.push('---');
|
|
62
61
|
sections.push('');
|
|
@@ -215,29 +214,38 @@ function generate(config) {
|
|
|
215
214
|
}
|
|
216
215
|
|
|
217
216
|
// Autonomous Build System
|
|
218
|
-
sections.push('##
|
|
217
|
+
sections.push('## Build Loop');
|
|
218
|
+
sections.push('');
|
|
219
|
+
sections.push('**To start building, run:**');
|
|
220
|
+
sections.push('');
|
|
221
|
+
sections.push('```');
|
|
222
|
+
sections.push('bootspring build next');
|
|
223
|
+
sections.push('```');
|
|
224
|
+
sections.push('');
|
|
225
|
+
sections.push('This starts an autonomous loop:');
|
|
219
226
|
sections.push('');
|
|
220
227
|
sections.push('```');
|
|
221
228
|
sections.push('┌─────────────────────────────────────────────────────────────┐');
|
|
222
|
-
sections.push('│
|
|
223
|
-
sections.push('│
|
|
224
|
-
sections.push('│
|
|
225
|
-
sections.push('│
|
|
226
|
-
sections.push('│
|
|
227
|
-
sections.push('│
|
|
228
|
-
sections.push('│
|
|
229
|
-
sections.push('│
|
|
230
|
-
sections.push('│
|
|
229
|
+
sections.push('│ bootspring build next │');
|
|
230
|
+
sections.push('│ ↓ │');
|
|
231
|
+
sections.push('│ Read planning/TASK_QUEUE.md → find in_progress task │');
|
|
232
|
+
sections.push('│ ↓ │');
|
|
233
|
+
sections.push('│ Implement task (meet acceptance criteria) │');
|
|
234
|
+
sections.push('│ ↓ │');
|
|
235
|
+
sections.push('│ bootspring build done │');
|
|
236
|
+
sections.push('│ ↓ │');
|
|
237
|
+
sections.push('│ [Auto-queues next task] → Continue implementing... │');
|
|
231
238
|
sections.push('└─────────────────────────────────────────────────────────────┘');
|
|
232
239
|
sections.push('```');
|
|
233
240
|
sections.push('');
|
|
241
|
+
sections.push('**Keep looping until all tasks are complete.**');
|
|
242
|
+
sections.push('');
|
|
234
243
|
sections.push('### Commands');
|
|
235
244
|
sections.push('');
|
|
236
245
|
sections.push('| Command | What it does |');
|
|
237
246
|
sections.push('|---------|--------------|');
|
|
238
|
-
sections.push('| `bootspring build` |
|
|
239
|
-
sections.push('| `bootspring build
|
|
240
|
-
sections.push('| `bootspring build done` | Mark complete, update state, load next |');
|
|
247
|
+
sections.push('| `bootspring build next` | **Start here** - queue next task |');
|
|
248
|
+
sections.push('| `bootspring build done` | Mark complete, auto-queue next |');
|
|
241
249
|
sections.push('| `bootspring build status` | View progress |');
|
|
242
250
|
sections.push('| `bootspring build skip` | Skip current task |');
|
|
243
251
|
sections.push('');
|
|
@@ -247,7 +255,7 @@ function generate(config) {
|
|
|
247
255
|
// Rules
|
|
248
256
|
sections.push('## Rules');
|
|
249
257
|
sections.push('');
|
|
250
|
-
sections.push('1. **Always read before coding** - No implementation without reading MASTER_PLAN.md and
|
|
258
|
+
sections.push('1. **Always read before coding** - No implementation without reading MASTER_PLAN.md and TASK_QUEUE.md');
|
|
251
259
|
sections.push('2. **Follow acceptance criteria exactly** - The task is not done until all criteria are met');
|
|
252
260
|
sections.push('3. **Update planning docs** - Check off TODO.md items, run `bootspring build done`');
|
|
253
261
|
sections.push('4. **One task at a time** - Complete current task before starting next');
|
package/mcp/tools/build-tool.js
CHANGED
|
@@ -271,9 +271,6 @@ function createHandler({ configModule }) {
|
|
|
271
271
|
// Mark as in progress
|
|
272
272
|
buildState.updateProgress(projectRoot, nextTask.id, 'in_progress');
|
|
273
273
|
|
|
274
|
-
// Write to CURRENT_TASK.md
|
|
275
|
-
writeCurrentTaskFile(projectRoot, nextTask);
|
|
276
|
-
|
|
277
274
|
return {
|
|
278
275
|
content: [{
|
|
279
276
|
type: 'text',
|
|
@@ -287,9 +284,9 @@ function createHandler({ configModule }) {
|
|
|
287
284
|
sourceSection: nextTask.sourceSection,
|
|
288
285
|
acceptanceCriteria: nextTask.acceptanceCriteria || []
|
|
289
286
|
},
|
|
290
|
-
file: 'planning/
|
|
287
|
+
file: 'planning/TASK_QUEUE.md',
|
|
291
288
|
instructions: [
|
|
292
|
-
|
|
289
|
+
`Find ${nextTask.id} in planning/TASK_QUEUE.md for full details`,
|
|
293
290
|
'Implement the task in the codebase',
|
|
294
291
|
'Ensure acceptance criteria are met',
|
|
295
292
|
'Run quality checks (lint, test)',
|
|
@@ -336,9 +333,6 @@ function createHandler({ configModule }) {
|
|
|
336
333
|
// Auto-queue next task
|
|
337
334
|
if (nextTask) {
|
|
338
335
|
buildState.updateProgress(projectRoot, nextTask.id, 'in_progress');
|
|
339
|
-
writeCurrentTaskFile(projectRoot, nextTask);
|
|
340
|
-
} else {
|
|
341
|
-
clearCurrentTaskFile(projectRoot);
|
|
342
336
|
}
|
|
343
337
|
|
|
344
338
|
return {
|
|
@@ -358,12 +352,13 @@ function createHandler({ configModule }) {
|
|
|
358
352
|
id: nextTask.id,
|
|
359
353
|
title: nextTask.title,
|
|
360
354
|
description: nextTask.description,
|
|
361
|
-
acceptanceCriteria: nextTask.acceptanceCriteria || []
|
|
355
|
+
acceptanceCriteria: nextTask.acceptanceCriteria || [],
|
|
356
|
+
file: 'planning/TASK_QUEUE.md'
|
|
362
357
|
} : null,
|
|
363
358
|
allComplete: !nextTask,
|
|
364
359
|
message: nextTask
|
|
365
|
-
?
|
|
366
|
-
: '
|
|
360
|
+
? `✓ Complete! Continue: implement ${nextTask.id} from planning/TASK_QUEUE.md`
|
|
361
|
+
: '🎉 MVP BUILD COMPLETE! All tasks finished.'
|
|
367
362
|
}, null, 2)
|
|
368
363
|
}]
|
|
369
364
|
};
|
|
@@ -402,7 +397,6 @@ function createHandler({ configModule }) {
|
|
|
402
397
|
|
|
403
398
|
if (nextTask) {
|
|
404
399
|
buildState.updateProgress(projectRoot, nextTask.id, 'in_progress');
|
|
405
|
-
writeCurrentTaskFile(projectRoot, nextTask);
|
|
406
400
|
}
|
|
407
401
|
|
|
408
402
|
return {
|
|
@@ -417,7 +411,8 @@ function createHandler({ configModule }) {
|
|
|
417
411
|
nextTask: nextTask ? {
|
|
418
412
|
id: nextTask.id,
|
|
419
413
|
title: nextTask.title,
|
|
420
|
-
description: nextTask.description
|
|
414
|
+
description: nextTask.description,
|
|
415
|
+
file: 'planning/TASK_QUEUE.md'
|
|
421
416
|
} : null,
|
|
422
417
|
message: nextTask
|
|
423
418
|
? `Skipped. Next: ${nextTask.title}`
|
|
@@ -441,63 +436,6 @@ function createHandler({ configModule }) {
|
|
|
441
436
|
};
|
|
442
437
|
}
|
|
443
438
|
|
|
444
|
-
/**
|
|
445
|
-
* Write task to planning/CURRENT_TASK.md
|
|
446
|
-
*/
|
|
447
|
-
function writeCurrentTaskFile(projectRoot, task) {
|
|
448
|
-
const planningDir = path.join(projectRoot, 'planning');
|
|
449
|
-
if (!fs.existsSync(planningDir)) {
|
|
450
|
-
fs.mkdirSync(planningDir, { recursive: true });
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
const content = `# Current Task
|
|
454
|
-
|
|
455
|
-
> Auto-generated by bootspring. Implement this task.
|
|
456
|
-
|
|
457
|
-
---
|
|
458
|
-
|
|
459
|
-
## ${task.title}
|
|
460
|
-
|
|
461
|
-
${task.description || ''}
|
|
462
|
-
|
|
463
|
-
${task.acceptanceCriteria?.length ? `### Acceptance Criteria
|
|
464
|
-
|
|
465
|
-
${task.acceptanceCriteria.map(ac => `- [ ] ${ac}`).join('\n')}
|
|
466
|
-
` : ''}
|
|
467
|
-
|
|
468
|
-
### Source
|
|
469
|
-
|
|
470
|
-
${task.source}${task.sourceSection ? ` - ${task.sourceSection}` : ''}
|
|
471
|
-
|
|
472
|
-
---
|
|
473
|
-
|
|
474
|
-
## Instructions
|
|
475
|
-
|
|
476
|
-
1. Implement the task as described above
|
|
477
|
-
2. Ensure all acceptance criteria are met
|
|
478
|
-
3. Run quality checks (lint, test)
|
|
479
|
-
4. Commit your changes
|
|
480
|
-
5. Mark complete with: \`bootspring build done\` or MCP action=done
|
|
481
|
-
|
|
482
|
-
---
|
|
483
|
-
|
|
484
|
-
*Task ID: ${task.id}*
|
|
485
|
-
*Generated: ${new Date().toISOString()}*
|
|
486
|
-
`;
|
|
487
|
-
|
|
488
|
-
fs.writeFileSync(path.join(planningDir, 'CURRENT_TASK.md'), content);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Clear CURRENT_TASK.md
|
|
493
|
-
*/
|
|
494
|
-
function clearCurrentTaskFile(projectRoot) {
|
|
495
|
-
const taskFile = path.join(projectRoot, 'planning', 'CURRENT_TASK.md');
|
|
496
|
-
if (fs.existsSync(taskFile)) {
|
|
497
|
-
fs.unlinkSync(taskFile);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
439
|
module.exports = {
|
|
502
440
|
getToolDefinition,
|
|
503
441
|
createHandler
|
package/package.json
CHANGED