@girardmedia/bootspring 1.2.0 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/README.md +107 -14
  2. package/bin/bootspring.js +166 -27
  3. package/cli/agent.js +189 -17
  4. package/cli/analyze.js +499 -0
  5. package/cli/audit.js +557 -0
  6. package/cli/auth.js +495 -38
  7. package/cli/billing.js +302 -0
  8. package/cli/build.js +695 -0
  9. package/cli/business.js +109 -26
  10. package/cli/checkpoint-utils.js +168 -0
  11. package/cli/checkpoint.js +639 -0
  12. package/cli/cloud-sync.js +447 -0
  13. package/cli/content.js +198 -0
  14. package/cli/context.js +1 -1
  15. package/cli/deploy.js +543 -0
  16. package/cli/fundraise.js +112 -50
  17. package/cli/github-cmd.js +435 -0
  18. package/cli/health.js +477 -0
  19. package/cli/init.js +84 -13
  20. package/cli/legal.js +107 -95
  21. package/cli/log.js +2 -2
  22. package/cli/loop.js +976 -73
  23. package/cli/manager.js +711 -0
  24. package/cli/metrics.js +480 -0
  25. package/cli/monitor.js +812 -0
  26. package/cli/onboard.js +521 -0
  27. package/cli/orchestrator.js +12 -24
  28. package/cli/prd.js +594 -0
  29. package/cli/preseed-start.js +1483 -0
  30. package/cli/preseed.js +2302 -0
  31. package/cli/project.js +436 -0
  32. package/cli/quality.js +233 -0
  33. package/cli/security.js +913 -0
  34. package/cli/seed.js +1441 -5
  35. package/cli/skill.js +273 -211
  36. package/cli/suggest.js +989 -0
  37. package/cli/switch.js +453 -0
  38. package/cli/visualize.js +527 -0
  39. package/cli/watch.js +769 -0
  40. package/cli/workspace.js +607 -0
  41. package/core/analyze-workflow.js +1134 -0
  42. package/core/api-client.js +535 -22
  43. package/core/audit-workflow.js +1350 -0
  44. package/core/build-orchestrator.js +480 -0
  45. package/core/build-state.js +577 -0
  46. package/core/checkpoint-engine.js +408 -0
  47. package/core/config.js +1109 -26
  48. package/core/context-loader.js +21 -1
  49. package/core/deploy-workflow.js +836 -0
  50. package/core/entitlements.js +93 -22
  51. package/core/github-sync.js +610 -0
  52. package/core/index.js +8 -1
  53. package/core/ingest.js +1111 -0
  54. package/core/metrics-engine.js +768 -0
  55. package/core/onboard-workflow.js +1007 -0
  56. package/core/preseed-workflow.js +934 -0
  57. package/core/preseed.js +1617 -0
  58. package/core/project-context.js +325 -0
  59. package/core/project-state.js +694 -0
  60. package/core/r2-sync.js +583 -0
  61. package/core/scaffold.js +525 -7
  62. package/core/session.js +258 -0
  63. package/core/task-extractor.js +758 -0
  64. package/core/telemetry.js +28 -6
  65. package/core/tier-enforcement.js +737 -0
  66. package/core/utils.js +38 -14
  67. package/generators/questionnaire.js +15 -12
  68. package/generators/sections/ai.js +7 -7
  69. package/generators/sections/content.js +300 -0
  70. package/generators/sections/index.js +3 -0
  71. package/generators/sections/plugins.js +7 -6
  72. package/generators/templates/build-planning.template.js +596 -0
  73. package/generators/templates/content.template.js +819 -0
  74. package/generators/templates/index.js +2 -1
  75. package/hooks/git-autopilot.js +1250 -0
  76. package/hooks/index.js +9 -0
  77. package/intelligence/agent-collab.js +2057 -0
  78. package/intelligence/auto-suggest.js +634 -0
  79. package/intelligence/content-gen.js +1589 -0
  80. package/intelligence/cross-project.js +1647 -0
  81. package/intelligence/index.js +184 -0
  82. package/intelligence/learning/insights.json +517 -7
  83. package/intelligence/learning/pattern-learner.js +1008 -14
  84. package/intelligence/memory/decision-tracker.js +1431 -31
  85. package/intelligence/memory/decisions.jsonl +0 -0
  86. package/intelligence/orchestrator.js +2896 -1
  87. package/intelligence/prd.js +92 -1
  88. package/intelligence/recommendation-weights.json +14 -2
  89. package/intelligence/recommendations.js +463 -9
  90. package/intelligence/workflow-composer.js +1451 -0
  91. package/marketplace/index.d.ts +324 -0
  92. package/marketplace/index.js +1921 -0
  93. package/mcp/contracts/mcp-contract.v1.json +342 -4
  94. package/mcp/registry.js +680 -3
  95. package/mcp/response-formatter.js +23 -0
  96. package/mcp/tools/assist-tool.js +78 -4
  97. package/mcp/tools/autopilot-tool.js +408 -0
  98. package/mcp/tools/content-tool.js +571 -0
  99. package/mcp/tools/dashboard-tool.js +251 -5
  100. package/mcp/tools/mvp-tool.js +344 -0
  101. package/mcp/tools/plugin-tool.js +23 -1
  102. package/mcp/tools/prd-tool.js +579 -0
  103. package/mcp/tools/seed-tool.js +447 -0
  104. package/mcp/tools/skill-tool.js +43 -14
  105. package/mcp/tools/suggest-tool.js +147 -0
  106. package/package.json +15 -6
  107. package/agents/README.md +0 -93
  108. package/agents/ai-integration-expert/context.md +0 -386
  109. package/agents/api-expert/context.md +0 -416
  110. package/agents/architecture-expert/context.md +0 -454
  111. package/agents/auth-expert/context.md +0 -399
  112. package/agents/backend-expert/context.md +0 -483
  113. package/agents/business-strategy-expert/context.md +0 -180
  114. package/agents/code-review-expert/context.md +0 -365
  115. package/agents/competitive-analysis-expert/context.md +0 -239
  116. package/agents/data-modeling-expert/context.md +0 -352
  117. package/agents/database-expert/context.md +0 -250
  118. package/agents/devops-expert/context.md +0 -446
  119. package/agents/email-expert/context.md +0 -379
  120. package/agents/financial-expert/context.md +0 -213
  121. package/agents/frontend-expert/context.md +0 -364
  122. package/agents/fundraising-expert/context.md +0 -257
  123. package/agents/growth-expert/context.md +0 -249
  124. package/agents/index.js +0 -140
  125. package/agents/investor-relations-expert/context.md +0 -266
  126. package/agents/legal-expert/context.md +0 -284
  127. package/agents/marketing-expert/context.md +0 -236
  128. package/agents/monitoring-expert/context.md +0 -362
  129. package/agents/operations-expert/context.md +0 -279
  130. package/agents/partnerships-expert/context.md +0 -286
  131. package/agents/payment-expert/context.md +0 -340
  132. package/agents/performance-expert/context.md +0 -377
  133. package/agents/private-equity-expert/context.md +0 -246
  134. package/agents/railway-expert/context.md +0 -284
  135. package/agents/research-expert/context.md +0 -245
  136. package/agents/sales-expert/context.md +0 -241
  137. package/agents/security-expert/context.md +0 -343
  138. package/agents/testing-expert/context.md +0 -414
  139. package/agents/ui-ux-expert/context.md +0 -448
  140. package/agents/vercel-expert/context.md +0 -426
  141. package/skills/index.js +0 -787
  142. package/skills/patterns/README.md +0 -163
  143. package/skills/patterns/ai/agents.md +0 -281
  144. package/skills/patterns/ai/claude.md +0 -138
  145. package/skills/patterns/ai/embeddings.md +0 -150
  146. package/skills/patterns/ai/rag.md +0 -266
  147. package/skills/patterns/ai/streaming.md +0 -170
  148. package/skills/patterns/ai/structured-output.md +0 -162
  149. package/skills/patterns/ai/tools.md +0 -154
  150. package/skills/patterns/analytics/tracking.md +0 -220
  151. package/skills/patterns/api/errors.md +0 -296
  152. package/skills/patterns/api/graphql.md +0 -440
  153. package/skills/patterns/api/middleware.md +0 -279
  154. package/skills/patterns/api/openapi.md +0 -285
  155. package/skills/patterns/api/rate-limiting.md +0 -231
  156. package/skills/patterns/api/route-handler.md +0 -217
  157. package/skills/patterns/api/server-action.md +0 -249
  158. package/skills/patterns/api/versioning.md +0 -443
  159. package/skills/patterns/api/webhooks.md +0 -247
  160. package/skills/patterns/auth/clerk.md +0 -132
  161. package/skills/patterns/auth/mfa.md +0 -313
  162. package/skills/patterns/auth/nextauth.md +0 -140
  163. package/skills/patterns/auth/oauth.md +0 -237
  164. package/skills/patterns/auth/rbac.md +0 -152
  165. package/skills/patterns/auth/session-management.md +0 -367
  166. package/skills/patterns/auth/session.md +0 -120
  167. package/skills/patterns/database/audit.md +0 -177
  168. package/skills/patterns/database/migrations.md +0 -177
  169. package/skills/patterns/database/pagination.md +0 -230
  170. package/skills/patterns/database/pooling.md +0 -357
  171. package/skills/patterns/database/prisma.md +0 -180
  172. package/skills/patterns/database/relations.md +0 -187
  173. package/skills/patterns/database/seeding.md +0 -246
  174. package/skills/patterns/database/soft-delete.md +0 -153
  175. package/skills/patterns/database/transactions.md +0 -162
  176. package/skills/patterns/deployment/ci-cd.md +0 -231
  177. package/skills/patterns/deployment/docker.md +0 -188
  178. package/skills/patterns/deployment/monitoring.md +0 -387
  179. package/skills/patterns/deployment/vercel.md +0 -160
  180. package/skills/patterns/email/resend.md +0 -143
  181. package/skills/patterns/email/templates.md +0 -245
  182. package/skills/patterns/email/transactional.md +0 -503
  183. package/skills/patterns/email/verification.md +0 -176
  184. package/skills/patterns/files/download.md +0 -243
  185. package/skills/patterns/files/upload.md +0 -239
  186. package/skills/patterns/i18n/nextintl.md +0 -188
  187. package/skills/patterns/logging/structured.md +0 -292
  188. package/skills/patterns/notifications/email-queue.md +0 -248
  189. package/skills/patterns/notifications/push.md +0 -279
  190. package/skills/patterns/payments/checkout.md +0 -303
  191. package/skills/patterns/payments/invoices.md +0 -287
  192. package/skills/patterns/payments/portal.md +0 -245
  193. package/skills/patterns/payments/stripe.md +0 -272
  194. package/skills/patterns/payments/subscriptions.md +0 -300
  195. package/skills/patterns/payments/usage.md +0 -279
  196. package/skills/patterns/performance/caching.md +0 -276
  197. package/skills/patterns/performance/code-splitting.md +0 -233
  198. package/skills/patterns/performance/edge.md +0 -254
  199. package/skills/patterns/performance/isr.md +0 -266
  200. package/skills/patterns/performance/lazy-loading.md +0 -281
  201. package/skills/patterns/realtime/sse.md +0 -327
  202. package/skills/patterns/realtime/websockets.md +0 -336
  203. package/skills/patterns/search/filtering.md +0 -329
  204. package/skills/patterns/search/fulltext.md +0 -260
  205. package/skills/patterns/security/audit-logging.md +0 -444
  206. package/skills/patterns/security/csrf.md +0 -234
  207. package/skills/patterns/security/headers.md +0 -252
  208. package/skills/patterns/security/sanitization.md +0 -258
  209. package/skills/patterns/security/secrets.md +0 -261
  210. package/skills/patterns/security/validation.md +0 -268
  211. package/skills/patterns/security/xss.md +0 -229
  212. package/skills/patterns/seo/metadata.md +0 -252
  213. package/skills/patterns/state/context.md +0 -349
  214. package/skills/patterns/state/react-query.md +0 -313
  215. package/skills/patterns/state/url-state.md +0 -482
  216. package/skills/patterns/state/zustand.md +0 -262
  217. package/skills/patterns/testing/api.md +0 -259
  218. package/skills/patterns/testing/component.md +0 -233
  219. package/skills/patterns/testing/coverage.md +0 -207
  220. package/skills/patterns/testing/fixtures.md +0 -225
  221. package/skills/patterns/testing/integration.md +0 -436
  222. package/skills/patterns/testing/mocking.md +0 -177
  223. package/skills/patterns/testing/playwright.md +0 -162
  224. package/skills/patterns/testing/snapshot.md +0 -175
  225. package/skills/patterns/testing/vitest.md +0 -307
  226. package/skills/patterns/ui/accordions.md +0 -395
  227. package/skills/patterns/ui/cards.md +0 -299
  228. package/skills/patterns/ui/dropdowns.md +0 -476
  229. package/skills/patterns/ui/empty-states.md +0 -320
  230. package/skills/patterns/ui/forms.md +0 -405
  231. package/skills/patterns/ui/inputs.md +0 -319
  232. package/skills/patterns/ui/layouts.md +0 -282
  233. package/skills/patterns/ui/loading.md +0 -291
  234. package/skills/patterns/ui/modals.md +0 -338
  235. package/skills/patterns/ui/navigation.md +0 -374
  236. package/skills/patterns/ui/tables.md +0 -407
  237. package/skills/patterns/ui/toasts.md +0 -300
  238. package/skills/patterns/ui/tooltips.md +0 -396
  239. package/skills/patterns/utils/dates.md +0 -435
  240. package/skills/patterns/utils/errors.md +0 -451
  241. package/skills/patterns/utils/formatting.md +0 -345
  242. package/skills/patterns/utils/validation.md +0 -434
  243. package/templates/bootspring.config.js +0 -83
  244. package/templates/business/business-model-canvas.md +0 -246
  245. package/templates/business/business-plan.md +0 -266
  246. package/templates/business/competitive-analysis.md +0 -312
  247. package/templates/fundraising/data-room-checklist.md +0 -300
  248. package/templates/fundraising/investor-research.md +0 -243
  249. package/templates/fundraising/pitch-deck-outline.md +0 -253
  250. package/templates/legal/gdpr-checklist.md +0 -339
  251. package/templates/legal/privacy-policy.md +0 -285
  252. package/templates/legal/terms-of-service.md +0 -222
  253. package/templates/mcp.json +0 -9
@@ -0,0 +1,596 @@
1
+ /**
2
+ * Bootspring Build Planning Templates
3
+ *
4
+ * Generates planning artifacts for the autonomous build loop:
5
+ * - MASTER_PLAN.md - Vision + phases + progress tracker
6
+ * - TODO.md - Checkbox list by phase
7
+ * - IMPLEMENTATION_QUEUE.md - Ordered tasks with acceptance criteria
8
+ * - CONTEXT.md - Condensed context for AI iterations
9
+ *
10
+ * @package bootspring
11
+ * @module generators/templates/build-planning
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+
17
+ /**
18
+ * Generate all planning artifacts
19
+ * @param {string} projectRoot - Project root path
20
+ * @param {object} docs - Source documents
21
+ * @param {array} tasks - Extracted tasks
22
+ * @param {object} options - Generation options
23
+ * @returns {object} Generated file paths
24
+ */
25
+ function generateAll(projectRoot, docs, tasks, options = {}) {
26
+ const planningDir = path.join(projectRoot, 'planning');
27
+
28
+ // Ensure planning directory exists
29
+ if (!fs.existsSync(planningDir)) {
30
+ fs.mkdirSync(planningDir, { recursive: true });
31
+ }
32
+
33
+ const files = {};
34
+
35
+ // Generate MASTER_PLAN.md
36
+ const masterPlan = generateMasterPlan(docs, tasks, options);
37
+ const masterPlanPath = path.join(planningDir, 'MASTER_PLAN.md');
38
+ fs.writeFileSync(masterPlanPath, masterPlan);
39
+ files.masterPlan = masterPlanPath;
40
+
41
+ // Generate TODO.md
42
+ const todo = generateTodo(tasks, options);
43
+ const todoPath = path.join(planningDir, 'TODO.md');
44
+ fs.writeFileSync(todoPath, todo);
45
+ files.todo = todoPath;
46
+
47
+ // Generate IMPLEMENTATION_QUEUE.md
48
+ const queue = generateImplementationQueue(tasks, options);
49
+ const queuePath = path.join(planningDir, 'IMPLEMENTATION_QUEUE.md');
50
+ fs.writeFileSync(queuePath, queue);
51
+ files.implementationQueue = queuePath;
52
+
53
+ // Generate CONTEXT.md
54
+ const context = generateContext(docs, tasks, options);
55
+ const contextPath = path.join(planningDir, 'CONTEXT.md');
56
+ fs.writeFileSync(contextPath, context);
57
+ files.context = contextPath;
58
+
59
+ return files;
60
+ }
61
+
62
+ /**
63
+ * Generate MASTER_PLAN.md
64
+ * @param {object} docs - Source documents
65
+ * @param {array} tasks - Extracted tasks
66
+ * @param {object} options - Options
67
+ * @returns {string} MASTER_PLAN.md content
68
+ */
69
+ function generateMasterPlan(docs, tasks, options = {}) {
70
+ const projectName = options.projectName || 'Project';
71
+ const phases = groupByPhase(tasks);
72
+
73
+ let content = `# ${projectName} - Master Build Plan
74
+
75
+ > Generated by Bootspring Autonomous Build System
76
+ > Last Updated: ${new Date().toISOString().split('T')[0]}
77
+
78
+ ---
79
+
80
+ ## Overview
81
+
82
+ This master plan guides the autonomous build process from foundation to MVP completion.
83
+ Each phase contains specific tasks that will be executed sequentially by the build loop.
84
+
85
+ ---
86
+
87
+ ## Progress Tracker
88
+
89
+ | Phase | Status | Progress | Tasks |
90
+ |-------|--------|----------|-------|
91
+ `;
92
+
93
+ // Add phase progress rows
94
+ for (const [phaseName, phaseTasks] of Object.entries(phases)) {
95
+ const completed = phaseTasks.filter(t => t.status === 'completed').length;
96
+ const total = phaseTasks.length;
97
+ const percent = total > 0 ? Math.round((completed / total) * 100) : 0;
98
+ const status = completed === 0 ? 'Pending' :
99
+ completed === total ? 'Complete' : 'In Progress';
100
+
101
+ content += `| ${formatPhaseName(phaseName)} | ${status} | ${percent}% | ${completed}/${total} |\n`;
102
+ }
103
+
104
+ content += `
105
+ ---
106
+
107
+ ## Phases
108
+
109
+ `;
110
+
111
+ // Add phase details
112
+ for (const [phaseName, phaseTasks] of Object.entries(phases)) {
113
+ const icon = phaseName === 'foundation' ? '1' :
114
+ phaseName === 'mvp' ? '2' :
115
+ phaseName === 'launch' ? '3' : '4';
116
+
117
+ content += `### Phase ${icon}: ${formatPhaseName(phaseName)}
118
+
119
+ `;
120
+
121
+ // Group tasks by source
122
+ const bySource = {};
123
+ for (const task of phaseTasks) {
124
+ const source = task.source || 'Manual';
125
+ if (!bySource[source]) bySource[source] = [];
126
+ bySource[source].push(task);
127
+ }
128
+
129
+ for (const [source, sourceTasks] of Object.entries(bySource)) {
130
+ content += `**From ${source}:**\n`;
131
+ for (const task of sourceTasks) {
132
+ const checkbox = task.status === 'completed' ? '[x]' : '[ ]';
133
+ content += `- ${checkbox} ${task.title}\n`;
134
+ }
135
+ content += '\n';
136
+ }
137
+
138
+ content += '---\n\n';
139
+ }
140
+
141
+ // Add exit criteria
142
+ content += `## MVP Exit Criteria
143
+
144
+ The build loop will exit when:
145
+
146
+ 1. All MVP phase tasks are completed
147
+ 2. Quality gates pass (tests, lint, typecheck)
148
+ 3. Core user journeys are functional
149
+ 4. No critical bugs remain
150
+
151
+ ---
152
+
153
+ ## Build Commands
154
+
155
+ \`\`\`bash
156
+ # Start the build loop
157
+ bootspring seed build --loop
158
+
159
+ # Check progress
160
+ bootspring build status
161
+
162
+ # Pause the build
163
+ bootspring build pause
164
+
165
+ # Resume building
166
+ bootspring build resume
167
+
168
+ # View current task
169
+ bootspring build task
170
+ \`\`\`
171
+
172
+ ---
173
+
174
+ *Generated by [Bootspring](https://bootspring.com) Autonomous Build System*
175
+ `;
176
+
177
+ return content;
178
+ }
179
+
180
+ /**
181
+ * Generate TODO.md
182
+ * @param {array} tasks - Extracted tasks
183
+ * @param {object} options - Options
184
+ * @returns {string} TODO.md content
185
+ */
186
+ function generateTodo(tasks, options = {}) {
187
+ const phases = groupByPhase(tasks);
188
+ const projectName = options.projectName || 'Project';
189
+
190
+ let content = `# ${projectName} - Build Todo
191
+
192
+ > Checklist for autonomous build completion
193
+
194
+ ---
195
+
196
+ `;
197
+
198
+ for (const [phaseName, phaseTasks] of Object.entries(phases)) {
199
+ const completed = phaseTasks.filter(t => t.status === 'completed').length;
200
+ const total = phaseTasks.length;
201
+ const percent = total > 0 ? Math.round((completed / total) * 100) : 0;
202
+
203
+ content += `## ${formatPhaseName(phaseName)} (${percent}%)
204
+
205
+ `;
206
+
207
+ for (const task of phaseTasks) {
208
+ const checkbox = task.status === 'completed' ? '[x]' : '[ ]';
209
+ content += `- ${checkbox} ${task.title}\n`;
210
+
211
+ // Add acceptance criteria as sub-items
212
+ if (task.acceptanceCriteria && task.acceptanceCriteria.length > 0) {
213
+ for (const criteria of task.acceptanceCriteria.slice(0, 3)) {
214
+ const subCheckbox = task.status === 'completed' ? '[x]' : '[ ]';
215
+ content += ` - ${subCheckbox} ${criteria}\n`;
216
+ }
217
+ }
218
+ }
219
+
220
+ content += '\n---\n\n';
221
+ }
222
+
223
+ content += `## Progress Summary
224
+
225
+ | Metric | Value |
226
+ |--------|-------|
227
+ | Total Tasks | ${tasks.length} |
228
+ | Completed | ${tasks.filter(t => t.status === 'completed').length} |
229
+ | Remaining | ${tasks.filter(t => t.status === 'pending').length} |
230
+ | In Progress | ${tasks.filter(t => t.status === 'in_progress').length} |
231
+
232
+ ---
233
+
234
+ *Updated: ${new Date().toISOString()}*
235
+ `;
236
+
237
+ return content;
238
+ }
239
+
240
+ /**
241
+ * Generate IMPLEMENTATION_QUEUE.md
242
+ * @param {array} tasks - Extracted tasks
243
+ * @param {object} options - Options
244
+ * @returns {string} IMPLEMENTATION_QUEUE.md content
245
+ */
246
+ function generateImplementationQueue(tasks, options = {}) {
247
+ const projectName = options.projectName || 'Project';
248
+
249
+ let content = `# ${projectName} - Implementation Queue
250
+
251
+ > Ordered task queue for autonomous execution
252
+
253
+ ---
254
+
255
+ ## Queue Status
256
+
257
+ | Position | ID | Task | Phase | Complexity | Status |
258
+ |----------|----|----- |-------|------------|--------|
259
+ `;
260
+
261
+ tasks.forEach((task, index) => {
262
+ const statusIcon = task.status === 'completed' ? 'Done' :
263
+ task.status === 'in_progress' ? 'Active' :
264
+ task.status === 'blocked' ? 'Blocked' : 'Pending';
265
+
266
+ content += `| ${index + 1} | ${task.id} | ${truncate(task.title, 40)} | ${formatPhaseName(task.phase)} | ${task.estimatedComplexity || 'medium'} | ${statusIcon} |\n`;
267
+ });
268
+
269
+ content += `
270
+ ---
271
+
272
+ ## Task Details
273
+
274
+ `;
275
+
276
+ for (const task of tasks) {
277
+ content += `### ${task.id}: ${task.title}
278
+
279
+ **Phase:** ${formatPhaseName(task.phase)}
280
+ **Source:** ${task.source || 'Manual'} ${task.sourceSection ? `(${task.sourceSection})` : ''}
281
+ **Complexity:** ${task.estimatedComplexity || 'medium'}
282
+ **Status:** ${task.status || 'pending'}
283
+
284
+ `;
285
+
286
+ if (task.description) {
287
+ content += `**Description:**
288
+ ${task.description}
289
+
290
+ `;
291
+ }
292
+
293
+ if (task.acceptanceCriteria && task.acceptanceCriteria.length > 0) {
294
+ content += `**Acceptance Criteria:**
295
+ ${task.acceptanceCriteria.map(c => `- [ ] ${c}`).join('\n')}
296
+
297
+ `;
298
+ }
299
+
300
+ if (task.dependencies && task.dependencies.length > 0) {
301
+ content += `**Dependencies:** ${task.dependencies.join(', ')}
302
+
303
+ `;
304
+ }
305
+
306
+ content += '---\n\n';
307
+ }
308
+
309
+ content += `## Execution Guidelines
310
+
311
+ 1. **One Task at a Time** - Complete each task fully before moving on
312
+ 2. **Quality Gates** - Run tests, lint, and typecheck before marking complete
313
+ 3. **Commit Per Task** - Create meaningful commits for each completed task
314
+ 4. **Update Status** - Mark tasks complete in BUILD_STATE.json
315
+ 5. **Document Changes** - Update CLAUDE.md with new patterns/decisions
316
+
317
+ ---
318
+
319
+ *Generated by Bootspring*
320
+ `;
321
+
322
+ return content;
323
+ }
324
+
325
+ /**
326
+ * Generate CONTEXT.md
327
+ * @param {object} docs - Source documents
328
+ * @param {array} tasks - Extracted tasks
329
+ * @param {object} options - Options
330
+ * @returns {string} CONTEXT.md content
331
+ */
332
+ function generateContext(docs, tasks, options = {}) {
333
+ const projectName = options.projectName || 'Project';
334
+ const techStack = options.techStack || extractTechStack(docs);
335
+
336
+ let content = `# ${projectName} - Build Context
337
+
338
+ > Condensed context for AI build iterations
339
+ > Read this file at the start of each build task
340
+
341
+ ---
342
+
343
+ ## Project Identity
344
+
345
+ **Name:** ${projectName}
346
+ ${options.tagline ? `**Tagline:** ${options.tagline}` : ''}
347
+
348
+ ---
349
+
350
+ ## Tech Stack
351
+
352
+ | Component | Technology |
353
+ |-----------|------------|
354
+ | Framework | ${techStack.framework || 'Next.js'} |
355
+ | Language | ${techStack.language || 'TypeScript'} |
356
+ | Database | ${techStack.database || 'PostgreSQL'} |
357
+ | ORM | ${techStack.orm || 'Prisma'} |
358
+ | UI | ${techStack.uiLibrary || 'shadcn/ui'} |
359
+ | Styling | ${techStack.styling || 'Tailwind CSS'} |
360
+ | Auth | ${techStack.auth || 'Clerk'} |
361
+ | Hosting | ${techStack.hosting || 'Vercel'} |
362
+
363
+ ---
364
+
365
+ ## Current Build Status
366
+
367
+ **Phase:** ${options.currentPhase || 'MVP'}
368
+ **Tasks Remaining:** ${tasks.filter(t => t.status !== 'completed').length}
369
+ **Tasks Completed:** ${tasks.filter(t => t.status === 'completed').length}
370
+
371
+ ---
372
+
373
+ ## Key Decisions
374
+
375
+ `;
376
+
377
+ // Add any decisions from docs
378
+ if (docs.TECHNICAL_SPEC || docs.technical_spec) {
379
+ content += `### Architecture
380
+ - Use Server Components by default
381
+ - Prefer Server Actions over API routes for mutations
382
+ - Use Zod for input validation
383
+ - Never expose API keys to client
384
+
385
+ `;
386
+ }
387
+
388
+ content += `### Code Style
389
+ - TypeScript strict mode enabled
390
+ - ESLint + Prettier for formatting
391
+ - Conventional commits (feat:, fix:, docs:, refactor:)
392
+ - Keep files under 300 lines
393
+
394
+ ---
395
+
396
+ ## MVP Features
397
+
398
+ `;
399
+
400
+ // Extract unique MVP features
401
+ const mvpTasks = tasks.filter(t => t.phase === 'mvp');
402
+ const uniqueFeatures = [...new Set(mvpTasks.map(t => t.title))].slice(0, 10);
403
+
404
+ uniqueFeatures.forEach((feature, i) => {
405
+ content += `${i + 1}. ${feature}\n`;
406
+ });
407
+
408
+ content += `
409
+ ---
410
+
411
+ ## File Structure
412
+
413
+ \`\`\`
414
+ ${projectName.toLowerCase().replace(/\s+/g, '-')}/
415
+ ├── app/ # Next.js App Router
416
+ │ ├── (auth)/ # Auth pages
417
+ │ ├── (dashboard)/ # Main dashboard
418
+ │ ├── (marketing)/ # Landing pages
419
+ │ └── api/ # API routes
420
+ ├── components/
421
+ │ ├── ui/ # UI components
422
+ │ └── [feature]/ # Feature components
423
+ ├── lib/
424
+ │ ├── db.ts # Database client
425
+ │ ├── auth.ts # Auth utilities
426
+ │ └── utils.ts # Helpers
427
+ ├── prisma/
428
+ │ └── schema.prisma # Database schema
429
+ ├── planning/ # Build planning (this folder)
430
+ └── public/ # Static assets
431
+ \`\`\`
432
+
433
+ ---
434
+
435
+ ## Build Loop Rules
436
+
437
+ When executing a task:
438
+
439
+ 1. **Read CLAUDE.md** - Understand project patterns
440
+ 2. **Check BUILD_STATE.json** - Know current task and status
441
+ 3. **Implement ONE task** - Focus on the current task only
442
+ 4. **Run quality checks** - \`npm run lint && npm run test\`
443
+ 5. **Commit changes** - Use conventional commits
444
+ 6. **Update status** - Mark task complete in BUILD_STATE.json
445
+
446
+ ---
447
+
448
+ ## Exit Signals
449
+
450
+ Output these signals for loop control:
451
+
452
+ \`\`\`
453
+ <loop-status>TASK_COMPLETE</loop-status> # Task done successfully
454
+ <loop-status>TASK_BLOCKED</loop-status> # Cannot complete, needs help
455
+ <loop-status>ALL_COMPLETE</loop-status> # All MVP tasks done
456
+ EXIT_SIGNAL # Stop the loop
457
+ \`\`\`
458
+
459
+ ---
460
+
461
+ *This context is refreshed at the start of each build iteration*
462
+ `;
463
+
464
+ return content;
465
+ }
466
+
467
+ /**
468
+ * Group tasks by phase
469
+ * @param {array} tasks - Tasks to group
470
+ * @returns {object} Tasks grouped by phase
471
+ */
472
+ function groupByPhase(tasks) {
473
+ const phases = {
474
+ foundation: [],
475
+ mvp: [],
476
+ launch: [],
477
+ other: []
478
+ };
479
+
480
+ for (const task of tasks) {
481
+ const phase = task.phase || 'other';
482
+ if (phases[phase]) {
483
+ phases[phase].push(task);
484
+ } else {
485
+ phases.other.push(task);
486
+ }
487
+ }
488
+
489
+ // Remove empty phases
490
+ for (const [key, value] of Object.entries(phases)) {
491
+ if (value.length === 0) {
492
+ delete phases[key];
493
+ }
494
+ }
495
+
496
+ return phases;
497
+ }
498
+
499
+ /**
500
+ * Format phase name for display
501
+ * @param {string} phase - Phase name
502
+ * @returns {string} Formatted name
503
+ */
504
+ function formatPhaseName(phase) {
505
+ if (!phase) return 'Other';
506
+
507
+ const names = {
508
+ foundation: 'Foundation',
509
+ mvp: 'MVP',
510
+ launch: 'Launch',
511
+ other: 'Other'
512
+ };
513
+
514
+ return names[phase] || phase.charAt(0).toUpperCase() + phase.slice(1);
515
+ }
516
+
517
+ /**
518
+ * Truncate string to max length
519
+ * @param {string} str - String to truncate
520
+ * @param {number} maxLength - Maximum length
521
+ * @returns {string} Truncated string
522
+ */
523
+ function truncate(str, maxLength) {
524
+ if (!str) return '';
525
+ if (str.length <= maxLength) return str;
526
+ return str.slice(0, maxLength - 3) + '...';
527
+ }
528
+
529
+ /**
530
+ * Extract tech stack from docs
531
+ * @param {object} docs - Source documents
532
+ * @returns {object} Tech stack
533
+ */
534
+ function extractTechStack(docs) {
535
+ const techDoc = docs.TECHNICAL_SPEC || docs.technical_spec || '';
536
+ const seedDoc = docs.SEED || docs.seed || '';
537
+ const allDocs = techDoc + seedDoc;
538
+
539
+ const stack = {
540
+ framework: 'nextjs',
541
+ language: 'typescript',
542
+ database: 'postgresql',
543
+ orm: 'prisma',
544
+ uiLibrary: 'shadcn',
545
+ styling: 'tailwind',
546
+ auth: 'clerk',
547
+ hosting: 'vercel'
548
+ };
549
+
550
+ // Framework detection
551
+ if (allDocs.match(/Next\.?js/i)) stack.framework = 'Next.js';
552
+ else if (allDocs.match(/Remix/i)) stack.framework = 'Remix';
553
+ else if (allDocs.match(/Nuxt/i)) stack.framework = 'Nuxt';
554
+
555
+ // Database
556
+ if (allDocs.match(/Postgres|PostgreSQL/i)) stack.database = 'PostgreSQL';
557
+ else if (allDocs.match(/MongoDB/i)) stack.database = 'MongoDB';
558
+ else if (allDocs.match(/Supabase/i)) stack.database = 'Supabase';
559
+
560
+ // Auth
561
+ if (allDocs.match(/\bClerk\b/i)) stack.auth = 'Clerk';
562
+ else if (allDocs.match(/NextAuth|Auth\.js/i)) stack.auth = 'NextAuth';
563
+
564
+ return stack;
565
+ }
566
+
567
+ /**
568
+ * Update planning files with current state
569
+ * @param {string} projectRoot - Project root path
570
+ * @param {object} state - Current build state
571
+ */
572
+ function updateFromState(projectRoot, state) {
573
+ if (!state || !state.implementationQueue) return;
574
+
575
+ const tasks = state.implementationQueue;
576
+ const planningDir = path.join(projectRoot, 'planning');
577
+
578
+ // Regenerate TODO.md with current status
579
+ const todo = generateTodo(tasks, { projectName: state.projectName });
580
+ fs.writeFileSync(path.join(planningDir, 'TODO.md'), todo);
581
+
582
+ // Regenerate IMPLEMENTATION_QUEUE.md
583
+ const queue = generateImplementationQueue(tasks, { projectName: state.projectName });
584
+ fs.writeFileSync(path.join(planningDir, 'IMPLEMENTATION_QUEUE.md'), queue);
585
+ }
586
+
587
+ module.exports = {
588
+ generateAll,
589
+ generateMasterPlan,
590
+ generateTodo,
591
+ generateImplementationQueue,
592
+ generateContext,
593
+ groupByPhase,
594
+ formatPhaseName,
595
+ updateFromState
596
+ };