@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.
- package/README.md +107 -14
- package/bin/bootspring.js +166 -27
- package/cli/agent.js +189 -17
- package/cli/analyze.js +499 -0
- package/cli/audit.js +557 -0
- package/cli/auth.js +495 -38
- package/cli/billing.js +302 -0
- package/cli/build.js +695 -0
- package/cli/business.js +109 -26
- package/cli/checkpoint-utils.js +168 -0
- package/cli/checkpoint.js +639 -0
- package/cli/cloud-sync.js +447 -0
- package/cli/content.js +198 -0
- package/cli/context.js +1 -1
- package/cli/deploy.js +543 -0
- package/cli/fundraise.js +112 -50
- package/cli/github-cmd.js +435 -0
- package/cli/health.js +477 -0
- package/cli/init.js +84 -13
- package/cli/legal.js +107 -95
- package/cli/log.js +2 -2
- package/cli/loop.js +976 -73
- package/cli/manager.js +711 -0
- package/cli/metrics.js +480 -0
- package/cli/monitor.js +812 -0
- package/cli/onboard.js +521 -0
- package/cli/orchestrator.js +12 -24
- package/cli/prd.js +594 -0
- package/cli/preseed-start.js +1483 -0
- package/cli/preseed.js +2302 -0
- package/cli/project.js +436 -0
- package/cli/quality.js +233 -0
- package/cli/security.js +913 -0
- package/cli/seed.js +1441 -5
- package/cli/skill.js +273 -211
- package/cli/suggest.js +989 -0
- package/cli/switch.js +453 -0
- package/cli/visualize.js +527 -0
- package/cli/watch.js +769 -0
- package/cli/workspace.js +607 -0
- package/core/analyze-workflow.js +1134 -0
- package/core/api-client.js +535 -22
- package/core/audit-workflow.js +1350 -0
- package/core/build-orchestrator.js +480 -0
- package/core/build-state.js +577 -0
- package/core/checkpoint-engine.js +408 -0
- package/core/config.js +1109 -26
- package/core/context-loader.js +21 -1
- package/core/deploy-workflow.js +836 -0
- package/core/entitlements.js +93 -22
- package/core/github-sync.js +610 -0
- package/core/index.js +8 -1
- package/core/ingest.js +1111 -0
- package/core/metrics-engine.js +768 -0
- package/core/onboard-workflow.js +1007 -0
- package/core/preseed-workflow.js +934 -0
- package/core/preseed.js +1617 -0
- package/core/project-context.js +325 -0
- package/core/project-state.js +694 -0
- package/core/r2-sync.js +583 -0
- package/core/scaffold.js +525 -7
- package/core/session.js +258 -0
- package/core/task-extractor.js +758 -0
- package/core/telemetry.js +28 -6
- package/core/tier-enforcement.js +737 -0
- package/core/utils.js +38 -14
- package/generators/questionnaire.js +15 -12
- package/generators/sections/ai.js +7 -7
- package/generators/sections/content.js +300 -0
- package/generators/sections/index.js +3 -0
- package/generators/sections/plugins.js +7 -6
- package/generators/templates/build-planning.template.js +596 -0
- package/generators/templates/content.template.js +819 -0
- package/generators/templates/index.js +2 -1
- package/hooks/git-autopilot.js +1250 -0
- package/hooks/index.js +9 -0
- package/intelligence/agent-collab.js +2057 -0
- package/intelligence/auto-suggest.js +634 -0
- package/intelligence/content-gen.js +1589 -0
- package/intelligence/cross-project.js +1647 -0
- package/intelligence/index.js +184 -0
- package/intelligence/learning/insights.json +517 -7
- package/intelligence/learning/pattern-learner.js +1008 -14
- package/intelligence/memory/decision-tracker.js +1431 -31
- package/intelligence/memory/decisions.jsonl +0 -0
- package/intelligence/orchestrator.js +2896 -1
- package/intelligence/prd.js +92 -1
- package/intelligence/recommendation-weights.json +14 -2
- package/intelligence/recommendations.js +463 -9
- package/intelligence/workflow-composer.js +1451 -0
- package/marketplace/index.d.ts +324 -0
- package/marketplace/index.js +1921 -0
- package/mcp/contracts/mcp-contract.v1.json +342 -4
- package/mcp/registry.js +680 -3
- package/mcp/response-formatter.js +23 -0
- package/mcp/tools/assist-tool.js +78 -4
- package/mcp/tools/autopilot-tool.js +408 -0
- package/mcp/tools/content-tool.js +571 -0
- package/mcp/tools/dashboard-tool.js +251 -5
- package/mcp/tools/mvp-tool.js +344 -0
- package/mcp/tools/plugin-tool.js +23 -1
- package/mcp/tools/prd-tool.js +579 -0
- package/mcp/tools/seed-tool.js +447 -0
- package/mcp/tools/skill-tool.js +43 -14
- package/mcp/tools/suggest-tool.js +147 -0
- package/package.json +15 -6
- package/agents/README.md +0 -93
- package/agents/ai-integration-expert/context.md +0 -386
- package/agents/api-expert/context.md +0 -416
- package/agents/architecture-expert/context.md +0 -454
- package/agents/auth-expert/context.md +0 -399
- package/agents/backend-expert/context.md +0 -483
- package/agents/business-strategy-expert/context.md +0 -180
- package/agents/code-review-expert/context.md +0 -365
- package/agents/competitive-analysis-expert/context.md +0 -239
- package/agents/data-modeling-expert/context.md +0 -352
- package/agents/database-expert/context.md +0 -250
- package/agents/devops-expert/context.md +0 -446
- package/agents/email-expert/context.md +0 -379
- package/agents/financial-expert/context.md +0 -213
- package/agents/frontend-expert/context.md +0 -364
- package/agents/fundraising-expert/context.md +0 -257
- package/agents/growth-expert/context.md +0 -249
- package/agents/index.js +0 -140
- package/agents/investor-relations-expert/context.md +0 -266
- package/agents/legal-expert/context.md +0 -284
- package/agents/marketing-expert/context.md +0 -236
- package/agents/monitoring-expert/context.md +0 -362
- package/agents/operations-expert/context.md +0 -279
- package/agents/partnerships-expert/context.md +0 -286
- package/agents/payment-expert/context.md +0 -340
- package/agents/performance-expert/context.md +0 -377
- package/agents/private-equity-expert/context.md +0 -246
- package/agents/railway-expert/context.md +0 -284
- package/agents/research-expert/context.md +0 -245
- package/agents/sales-expert/context.md +0 -241
- package/agents/security-expert/context.md +0 -343
- package/agents/testing-expert/context.md +0 -414
- package/agents/ui-ux-expert/context.md +0 -448
- package/agents/vercel-expert/context.md +0 -426
- package/skills/index.js +0 -787
- package/skills/patterns/README.md +0 -163
- package/skills/patterns/ai/agents.md +0 -281
- package/skills/patterns/ai/claude.md +0 -138
- package/skills/patterns/ai/embeddings.md +0 -150
- package/skills/patterns/ai/rag.md +0 -266
- package/skills/patterns/ai/streaming.md +0 -170
- package/skills/patterns/ai/structured-output.md +0 -162
- package/skills/patterns/ai/tools.md +0 -154
- package/skills/patterns/analytics/tracking.md +0 -220
- package/skills/patterns/api/errors.md +0 -296
- package/skills/patterns/api/graphql.md +0 -440
- package/skills/patterns/api/middleware.md +0 -279
- package/skills/patterns/api/openapi.md +0 -285
- package/skills/patterns/api/rate-limiting.md +0 -231
- package/skills/patterns/api/route-handler.md +0 -217
- package/skills/patterns/api/server-action.md +0 -249
- package/skills/patterns/api/versioning.md +0 -443
- package/skills/patterns/api/webhooks.md +0 -247
- package/skills/patterns/auth/clerk.md +0 -132
- package/skills/patterns/auth/mfa.md +0 -313
- package/skills/patterns/auth/nextauth.md +0 -140
- package/skills/patterns/auth/oauth.md +0 -237
- package/skills/patterns/auth/rbac.md +0 -152
- package/skills/patterns/auth/session-management.md +0 -367
- package/skills/patterns/auth/session.md +0 -120
- package/skills/patterns/database/audit.md +0 -177
- package/skills/patterns/database/migrations.md +0 -177
- package/skills/patterns/database/pagination.md +0 -230
- package/skills/patterns/database/pooling.md +0 -357
- package/skills/patterns/database/prisma.md +0 -180
- package/skills/patterns/database/relations.md +0 -187
- package/skills/patterns/database/seeding.md +0 -246
- package/skills/patterns/database/soft-delete.md +0 -153
- package/skills/patterns/database/transactions.md +0 -162
- package/skills/patterns/deployment/ci-cd.md +0 -231
- package/skills/patterns/deployment/docker.md +0 -188
- package/skills/patterns/deployment/monitoring.md +0 -387
- package/skills/patterns/deployment/vercel.md +0 -160
- package/skills/patterns/email/resend.md +0 -143
- package/skills/patterns/email/templates.md +0 -245
- package/skills/patterns/email/transactional.md +0 -503
- package/skills/patterns/email/verification.md +0 -176
- package/skills/patterns/files/download.md +0 -243
- package/skills/patterns/files/upload.md +0 -239
- package/skills/patterns/i18n/nextintl.md +0 -188
- package/skills/patterns/logging/structured.md +0 -292
- package/skills/patterns/notifications/email-queue.md +0 -248
- package/skills/patterns/notifications/push.md +0 -279
- package/skills/patterns/payments/checkout.md +0 -303
- package/skills/patterns/payments/invoices.md +0 -287
- package/skills/patterns/payments/portal.md +0 -245
- package/skills/patterns/payments/stripe.md +0 -272
- package/skills/patterns/payments/subscriptions.md +0 -300
- package/skills/patterns/payments/usage.md +0 -279
- package/skills/patterns/performance/caching.md +0 -276
- package/skills/patterns/performance/code-splitting.md +0 -233
- package/skills/patterns/performance/edge.md +0 -254
- package/skills/patterns/performance/isr.md +0 -266
- package/skills/patterns/performance/lazy-loading.md +0 -281
- package/skills/patterns/realtime/sse.md +0 -327
- package/skills/patterns/realtime/websockets.md +0 -336
- package/skills/patterns/search/filtering.md +0 -329
- package/skills/patterns/search/fulltext.md +0 -260
- package/skills/patterns/security/audit-logging.md +0 -444
- package/skills/patterns/security/csrf.md +0 -234
- package/skills/patterns/security/headers.md +0 -252
- package/skills/patterns/security/sanitization.md +0 -258
- package/skills/patterns/security/secrets.md +0 -261
- package/skills/patterns/security/validation.md +0 -268
- package/skills/patterns/security/xss.md +0 -229
- package/skills/patterns/seo/metadata.md +0 -252
- package/skills/patterns/state/context.md +0 -349
- package/skills/patterns/state/react-query.md +0 -313
- package/skills/patterns/state/url-state.md +0 -482
- package/skills/patterns/state/zustand.md +0 -262
- package/skills/patterns/testing/api.md +0 -259
- package/skills/patterns/testing/component.md +0 -233
- package/skills/patterns/testing/coverage.md +0 -207
- package/skills/patterns/testing/fixtures.md +0 -225
- package/skills/patterns/testing/integration.md +0 -436
- package/skills/patterns/testing/mocking.md +0 -177
- package/skills/patterns/testing/playwright.md +0 -162
- package/skills/patterns/testing/snapshot.md +0 -175
- package/skills/patterns/testing/vitest.md +0 -307
- package/skills/patterns/ui/accordions.md +0 -395
- package/skills/patterns/ui/cards.md +0 -299
- package/skills/patterns/ui/dropdowns.md +0 -476
- package/skills/patterns/ui/empty-states.md +0 -320
- package/skills/patterns/ui/forms.md +0 -405
- package/skills/patterns/ui/inputs.md +0 -319
- package/skills/patterns/ui/layouts.md +0 -282
- package/skills/patterns/ui/loading.md +0 -291
- package/skills/patterns/ui/modals.md +0 -338
- package/skills/patterns/ui/navigation.md +0 -374
- package/skills/patterns/ui/tables.md +0 -407
- package/skills/patterns/ui/toasts.md +0 -300
- package/skills/patterns/ui/tooltips.md +0 -396
- package/skills/patterns/utils/dates.md +0 -435
- package/skills/patterns/utils/errors.md +0 -451
- package/skills/patterns/utils/formatting.md +0 -345
- package/skills/patterns/utils/validation.md +0 -434
- package/templates/bootspring.config.js +0 -83
- package/templates/business/business-model-canvas.md +0 -246
- package/templates/business/business-plan.md +0 -266
- package/templates/business/competitive-analysis.md +0 -312
- package/templates/fundraising/data-room-checklist.md +0 -300
- package/templates/fundraising/investor-research.md +0 -243
- package/templates/fundraising/pitch-deck-outline.md +0 -253
- package/templates/legal/gdpr-checklist.md +0 -339
- package/templates/legal/privacy-policy.md +0 -285
- package/templates/legal/terms-of-service.md +0 -222
- 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
|
+
};
|