@codebakers/mcp 5.2.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/INSTALL.md +221 -0
- package/LICENSE +21 -0
- package/README.md +412 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +236 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +526 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/analyze-mockups.d.ts +18 -0
- package/dist/tools/analyze-mockups.d.ts.map +1 -0
- package/dist/tools/analyze-mockups.js +497 -0
- package/dist/tools/analyze-mockups.js.map +1 -0
- package/dist/tools/autonomous-build.d.ts +19 -0
- package/dist/tools/autonomous-build.d.ts.map +1 -0
- package/dist/tools/autonomous-build.js +287 -0
- package/dist/tools/autonomous-build.js.map +1 -0
- package/dist/tools/check-gate.d.ts +21 -0
- package/dist/tools/check-gate.d.ts.map +1 -0
- package/dist/tools/check-gate.js +446 -0
- package/dist/tools/check-gate.js.map +1 -0
- package/dist/tools/check-scope.d.ts +22 -0
- package/dist/tools/check-scope.d.ts.map +1 -0
- package/dist/tools/check-scope.js +251 -0
- package/dist/tools/check-scope.js.map +1 -0
- package/dist/tools/deploy-vercel.d.ts +18 -0
- package/dist/tools/deploy-vercel.d.ts.map +1 -0
- package/dist/tools/deploy-vercel.js +178 -0
- package/dist/tools/deploy-vercel.js.map +1 -0
- package/dist/tools/diagnose-error.d.ts +20 -0
- package/dist/tools/diagnose-error.d.ts.map +1 -0
- package/dist/tools/diagnose-error.js +351 -0
- package/dist/tools/diagnose-error.js.map +1 -0
- package/dist/tools/enforce-feature.d.ts +25 -0
- package/dist/tools/enforce-feature.d.ts.map +1 -0
- package/dist/tools/enforce-feature.js +387 -0
- package/dist/tools/enforce-feature.js.map +1 -0
- package/dist/tools/execute-atomic-unit.d.ts +23 -0
- package/dist/tools/execute-atomic-unit.d.ts.map +1 -0
- package/dist/tools/execute-atomic-unit.js +107 -0
- package/dist/tools/execute-atomic-unit.js.map +1 -0
- package/dist/tools/fix-commit.d.ts +23 -0
- package/dist/tools/fix-commit.d.ts.map +1 -0
- package/dist/tools/fix-commit.js +213 -0
- package/dist/tools/fix-commit.js.map +1 -0
- package/dist/tools/fix-mockups.d.ts +21 -0
- package/dist/tools/fix-mockups.d.ts.map +1 -0
- package/dist/tools/fix-mockups.js +595 -0
- package/dist/tools/fix-mockups.js.map +1 -0
- package/dist/tools/generate-api-route.d.ts +18 -0
- package/dist/tools/generate-api-route.d.ts.map +1 -0
- package/dist/tools/generate-api-route.js +212 -0
- package/dist/tools/generate-api-route.js.map +1 -0
- package/dist/tools/generate-chatbot.d.ts +20 -0
- package/dist/tools/generate-chatbot.d.ts.map +1 -0
- package/dist/tools/generate-chatbot.js +555 -0
- package/dist/tools/generate-chatbot.js.map +1 -0
- package/dist/tools/generate-component.d.ts +18 -0
- package/dist/tools/generate-component.d.ts.map +1 -0
- package/dist/tools/generate-component.js +159 -0
- package/dist/tools/generate-component.js.map +1 -0
- package/dist/tools/generate-docs.d.ts +21 -0
- package/dist/tools/generate-docs.d.ts.map +1 -0
- package/dist/tools/generate-docs.js +782 -0
- package/dist/tools/generate-docs.js.map +1 -0
- package/dist/tools/generate-e2e-tests.d.ts +12 -0
- package/dist/tools/generate-e2e-tests.d.ts.map +1 -0
- package/dist/tools/generate-e2e-tests.js +37 -0
- package/dist/tools/generate-e2e-tests.js.map +1 -0
- package/dist/tools/generate-migration.d.ts +21 -0
- package/dist/tools/generate-migration.d.ts.map +1 -0
- package/dist/tools/generate-migration.js +94 -0
- package/dist/tools/generate-migration.js.map +1 -0
- package/dist/tools/generate-schema.d.ts +18 -0
- package/dist/tools/generate-schema.d.ts.map +1 -0
- package/dist/tools/generate-schema.js +422 -0
- package/dist/tools/generate-schema.js.map +1 -0
- package/dist/tools/generate-spec.d.ts +18 -0
- package/dist/tools/generate-spec.d.ts.map +1 -0
- package/dist/tools/generate-spec.js +446 -0
- package/dist/tools/generate-spec.js.map +1 -0
- package/dist/tools/generate-store-contracts.d.ts +17 -0
- package/dist/tools/generate-store-contracts.d.ts.map +1 -0
- package/dist/tools/generate-store-contracts.js +356 -0
- package/dist/tools/generate-store-contracts.js.map +1 -0
- package/dist/tools/generate-store.d.ts +16 -0
- package/dist/tools/generate-store.d.ts.map +1 -0
- package/dist/tools/generate-store.js +166 -0
- package/dist/tools/generate-store.js.map +1 -0
- package/dist/tools/generate-unit-tests.d.ts +14 -0
- package/dist/tools/generate-unit-tests.d.ts.map +1 -0
- package/dist/tools/generate-unit-tests.js +85 -0
- package/dist/tools/generate-unit-tests.js.map +1 -0
- package/dist/tools/get-context.d.ts +35 -0
- package/dist/tools/get-context.d.ts.map +1 -0
- package/dist/tools/get-context.js +367 -0
- package/dist/tools/get-context.js.map +1 -0
- package/dist/tools/init-session.d.ts +22 -0
- package/dist/tools/init-session.d.ts.map +1 -0
- package/dist/tools/init-session.js +232 -0
- package/dist/tools/init-session.js.map +1 -0
- package/dist/tools/map-dependencies.d.ts +25 -0
- package/dist/tools/map-dependencies.d.ts.map +1 -0
- package/dist/tools/map-dependencies.js +480 -0
- package/dist/tools/map-dependencies.js.map +1 -0
- package/dist/tools/optimize-performance.d.ts +18 -0
- package/dist/tools/optimize-performance.d.ts.map +1 -0
- package/dist/tools/optimize-performance.js +285 -0
- package/dist/tools/optimize-performance.js.map +1 -0
- package/dist/tools/run-interview.d.ts +23 -0
- package/dist/tools/run-interview.d.ts.map +1 -0
- package/dist/tools/run-interview.js +371 -0
- package/dist/tools/run-interview.js.map +1 -0
- package/dist/tools/run-tests.d.ts +12 -0
- package/dist/tools/run-tests.d.ts.map +1 -0
- package/dist/tools/run-tests.js +30 -0
- package/dist/tools/run-tests.js.map +1 -0
- package/dist/tools/scan-security.d.ts +19 -0
- package/dist/tools/scan-security.d.ts.map +1 -0
- package/dist/tools/scan-security.js +358 -0
- package/dist/tools/scan-security.js.map +1 -0
- package/dist/tools/validate-accessibility.d.ts +18 -0
- package/dist/tools/validate-accessibility.d.ts.map +1 -0
- package/dist/tools/validate-accessibility.js +251 -0
- package/dist/tools/validate-accessibility.js.map +1 -0
- package/dist/tools/validate-mockups.d.ts +21 -0
- package/dist/tools/validate-mockups.d.ts.map +1 -0
- package/dist/tools/validate-mockups.js +433 -0
- package/dist/tools/validate-mockups.js.map +1 -0
- package/dist/tools/verify-completeness.d.ts +13 -0
- package/dist/tools/verify-completeness.d.ts.map +1 -0
- package/dist/tools/verify-completeness.js +68 -0
- package/dist/tools/verify-completeness.js.map +1 -0
- package/dist/tools/verify-mockups.d.ts +14 -0
- package/dist/tools/verify-mockups.d.ts.map +1 -0
- package/dist/tools/verify-mockups.js +85 -0
- package/dist/tools/verify-mockups.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,782 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codebakers_generate_docs
|
|
3
|
+
*
|
|
4
|
+
* Documentation Generator - Beautiful HTML Docs
|
|
5
|
+
*
|
|
6
|
+
* Generates complete documentation:
|
|
7
|
+
* - Quick start guide
|
|
8
|
+
* - API reference
|
|
9
|
+
* - Component documentation
|
|
10
|
+
* - Architecture overview
|
|
11
|
+
* - Setup instructions
|
|
12
|
+
* - Beautiful HTML output with navigation
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'fs/promises';
|
|
15
|
+
import * as path from 'path';
|
|
16
|
+
export async function generateDocs(args = {}) {
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
const { include_api = true, include_components = true, output_dir = 'docs' } = args;
|
|
19
|
+
console.error('🍞 CodeBakers: Generating Documentation');
|
|
20
|
+
try {
|
|
21
|
+
const outputPath = path.join(cwd, output_dir);
|
|
22
|
+
await fs.mkdir(outputPath, { recursive: true });
|
|
23
|
+
const sections = [];
|
|
24
|
+
// Section 1: Quick Start Guide
|
|
25
|
+
console.error('[1/5] Generating quick start guide...');
|
|
26
|
+
const quickStart = await generateQuickStart(cwd);
|
|
27
|
+
await writeDocFile(outputPath, 'quick-start.html', quickStart);
|
|
28
|
+
sections.push('Quick Start');
|
|
29
|
+
// Section 2: Setup Instructions
|
|
30
|
+
console.error('[2/5] Generating setup instructions...');
|
|
31
|
+
const setup = await generateSetupGuide(cwd);
|
|
32
|
+
await writeDocFile(outputPath, 'setup.html', setup);
|
|
33
|
+
sections.push('Setup');
|
|
34
|
+
// Section 3: Architecture Overview
|
|
35
|
+
console.error('[3/5] Generating architecture overview...');
|
|
36
|
+
const architecture = await generateArchitecture(cwd);
|
|
37
|
+
await writeDocFile(outputPath, 'architecture.html', architecture);
|
|
38
|
+
sections.push('Architecture');
|
|
39
|
+
// Section 4: API Reference
|
|
40
|
+
if (include_api) {
|
|
41
|
+
console.error('[4/5] Generating API reference...');
|
|
42
|
+
const api = await generateAPIReference(cwd);
|
|
43
|
+
await writeDocFile(outputPath, 'api-reference.html', api);
|
|
44
|
+
sections.push('API Reference');
|
|
45
|
+
}
|
|
46
|
+
// Section 5: Component Docs
|
|
47
|
+
if (include_components) {
|
|
48
|
+
console.error('[5/5] Generating component documentation...');
|
|
49
|
+
const components = await generateComponentDocs(cwd);
|
|
50
|
+
await writeDocFile(outputPath, 'components.html', components);
|
|
51
|
+
sections.push('Components');
|
|
52
|
+
}
|
|
53
|
+
// Generate index page
|
|
54
|
+
const index = generateIndexPage(sections);
|
|
55
|
+
await writeDocFile(outputPath, 'index.html', index);
|
|
56
|
+
// Copy CSS
|
|
57
|
+
await writeCSSFile(outputPath);
|
|
58
|
+
return generateDocsReport(outputPath, sections);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
return `🍞 CodeBakers: Documentation Generation Failed\n\nError: ${error instanceof Error ? error.message : String(error)}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async function generateQuickStart(cwd) {
|
|
65
|
+
// Read project-profile.md if exists
|
|
66
|
+
let projectName = 'Your App';
|
|
67
|
+
let projectType = '';
|
|
68
|
+
try {
|
|
69
|
+
const profilePath = path.join(cwd, 'project-profile.md');
|
|
70
|
+
const profile = await fs.readFile(profilePath, 'utf-8');
|
|
71
|
+
const nameMatch = profile.match(/name:\s*(.+)/i);
|
|
72
|
+
if (nameMatch)
|
|
73
|
+
projectName = nameMatch[1].trim();
|
|
74
|
+
const typeMatch = profile.match(/type:\s*(.+)/i);
|
|
75
|
+
if (typeMatch)
|
|
76
|
+
projectType = typeMatch[1].trim();
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// project-profile.md doesn't exist
|
|
80
|
+
}
|
|
81
|
+
const content = `
|
|
82
|
+
<h1>Quick Start Guide</h1>
|
|
83
|
+
|
|
84
|
+
<h2>Get Started in 5 Minutes</h2>
|
|
85
|
+
|
|
86
|
+
<h3>1. Clone and Install</h3>
|
|
87
|
+
<pre><code class="language-bash">git clone [repository-url]
|
|
88
|
+
cd ${projectName.toLowerCase().replace(/\s+/g, '-')}
|
|
89
|
+
pnpm install</code></pre>
|
|
90
|
+
|
|
91
|
+
<h3>2. Setup Environment</h3>
|
|
92
|
+
<pre><code class="language-bash"># Copy environment template
|
|
93
|
+
cp .env.example .env
|
|
94
|
+
|
|
95
|
+
# Add your credentials (see Setup guide for details)
|
|
96
|
+
# Required: SUPABASE_URL, SUPABASE_ANON_KEY
|
|
97
|
+
</code></pre>
|
|
98
|
+
|
|
99
|
+
<h3>3. Run Development Server</h3>
|
|
100
|
+
<pre><code class="language-bash">pnpm dev</code></pre>
|
|
101
|
+
|
|
102
|
+
<p>Open <a href="http://localhost:3000">http://localhost:3000</a> in your browser.</p>
|
|
103
|
+
|
|
104
|
+
<h3>4. Run Tests</h3>
|
|
105
|
+
<pre><code class="language-bash"># Unit tests
|
|
106
|
+
pnpm test
|
|
107
|
+
|
|
108
|
+
# E2E tests
|
|
109
|
+
pnpm test:e2e</code></pre>
|
|
110
|
+
|
|
111
|
+
<h3>5. Build for Production</h3>
|
|
112
|
+
<pre><code class="language-bash">pnpm build
|
|
113
|
+
pnpm start</code></pre>
|
|
114
|
+
|
|
115
|
+
<h2>What's Next?</h2>
|
|
116
|
+
|
|
117
|
+
<ul>
|
|
118
|
+
<li><a href="setup.html">Complete Setup Guide</a> - Environment variables and credentials</li>
|
|
119
|
+
<li><a href="architecture.html">Architecture Overview</a> - How the app works</li>
|
|
120
|
+
<li><a href="api-reference.html">API Reference</a> - Backend endpoints</li>
|
|
121
|
+
<li><a href="components.html">Components</a> - UI component library</li>
|
|
122
|
+
</ul>
|
|
123
|
+
|
|
124
|
+
<div class="callout callout-success">
|
|
125
|
+
<h4>🎉 You're Ready!</h4>
|
|
126
|
+
<p>Your app is now running. Start exploring the codebase or jump into development.</p>
|
|
127
|
+
</div>
|
|
128
|
+
`;
|
|
129
|
+
return wrapInTemplate('Quick Start', content);
|
|
130
|
+
}
|
|
131
|
+
async function generateSetupGuide(cwd) {
|
|
132
|
+
// Read CREDENTIALS-NEEDED.md if exists
|
|
133
|
+
let credentials = 'No external credentials required.';
|
|
134
|
+
try {
|
|
135
|
+
const credsPath = path.join(cwd, '.codebakers', 'CREDENTIALS-NEEDED.md');
|
|
136
|
+
credentials = await fs.readFile(credsPath, 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// CREDENTIALS-NEEDED.md doesn't exist
|
|
140
|
+
}
|
|
141
|
+
const content = `
|
|
142
|
+
<h1>Setup Guide</h1>
|
|
143
|
+
|
|
144
|
+
<h2>Prerequisites</h2>
|
|
145
|
+
|
|
146
|
+
<ul>
|
|
147
|
+
<li>Node.js 18+ (<code>node --version</code>)</li>
|
|
148
|
+
<li>pnpm (<code>npm install -g pnpm</code>)</li>
|
|
149
|
+
<li>Git</li>
|
|
150
|
+
<li>Supabase account (free tier works)</li>
|
|
151
|
+
</ul>
|
|
152
|
+
|
|
153
|
+
<h2>Installation Steps</h2>
|
|
154
|
+
|
|
155
|
+
<h3>Step 1: Install Dependencies</h3>
|
|
156
|
+
<pre><code class="language-bash">pnpm install</code></pre>
|
|
157
|
+
|
|
158
|
+
<h3>Step 2: Setup Supabase</h3>
|
|
159
|
+
|
|
160
|
+
<ol>
|
|
161
|
+
<li>Create project at <a href="https://supabase.com/dashboard">supabase.com/dashboard</a></li>
|
|
162
|
+
<li>Copy <strong>Project URL</strong> and <strong>anon key</strong> from Settings → API</li>
|
|
163
|
+
<li>Run migrations: <code>pnpm supabase:migrate</code></li>
|
|
164
|
+
</ol>
|
|
165
|
+
|
|
166
|
+
<h3>Step 3: Environment Variables</h3>
|
|
167
|
+
|
|
168
|
+
<pre><code class="language-bash"># .env
|
|
169
|
+
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
170
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
171
|
+
</code></pre>
|
|
172
|
+
|
|
173
|
+
<h2>External Services</h2>
|
|
174
|
+
|
|
175
|
+
<div class="credentials-section">
|
|
176
|
+
${credentials.includes('No external') ? '<p>No external credentials required.</p>' : `<pre>${credentials}</pre>`}
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<h2>Verification</h2>
|
|
180
|
+
|
|
181
|
+
<p>Verify everything works:</p>
|
|
182
|
+
|
|
183
|
+
<pre><code class="language-bash"># Type check
|
|
184
|
+
pnpm type-check
|
|
185
|
+
|
|
186
|
+
# Run tests
|
|
187
|
+
pnpm test
|
|
188
|
+
|
|
189
|
+
# Start dev server
|
|
190
|
+
pnpm dev</code></pre>
|
|
191
|
+
|
|
192
|
+
<div class="callout callout-info">
|
|
193
|
+
<h4>Need Help?</h4>
|
|
194
|
+
<p>Check <a href="https://github.com/your-repo/issues">GitHub Issues</a> or the main documentation.</p>
|
|
195
|
+
</div>
|
|
196
|
+
`;
|
|
197
|
+
return wrapInTemplate('Setup Guide', content);
|
|
198
|
+
}
|
|
199
|
+
async function generateArchitecture(cwd) {
|
|
200
|
+
// Read BRAIN.md if exists
|
|
201
|
+
let brainContent = '';
|
|
202
|
+
try {
|
|
203
|
+
const brainPath = path.join(cwd, '.codebakers', 'BRAIN.md');
|
|
204
|
+
brainContent = await fs.readFile(brainPath, 'utf-8');
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// BRAIN.md doesn't exist
|
|
208
|
+
}
|
|
209
|
+
const content = `
|
|
210
|
+
<h1>Architecture Overview</h1>
|
|
211
|
+
|
|
212
|
+
<h2>Tech Stack</h2>
|
|
213
|
+
|
|
214
|
+
<table>
|
|
215
|
+
<tr>
|
|
216
|
+
<th>Layer</th>
|
|
217
|
+
<th>Technology</th>
|
|
218
|
+
<th>Purpose</th>
|
|
219
|
+
</tr>
|
|
220
|
+
<tr>
|
|
221
|
+
<td>Frontend</td>
|
|
222
|
+
<td>Next.js 14 (App Router)</td>
|
|
223
|
+
<td>React framework with SSR/SSG</td>
|
|
224
|
+
</tr>
|
|
225
|
+
<tr>
|
|
226
|
+
<td>Backend</td>
|
|
227
|
+
<td>Next.js API Routes</td>
|
|
228
|
+
<td>Server-side endpoints</td>
|
|
229
|
+
</tr>
|
|
230
|
+
<tr>
|
|
231
|
+
<td>Database</td>
|
|
232
|
+
<td>Supabase (PostgreSQL)</td>
|
|
233
|
+
<td>Data persistence + Auth</td>
|
|
234
|
+
</tr>
|
|
235
|
+
<tr>
|
|
236
|
+
<td>State</td>
|
|
237
|
+
<td>Zustand</td>
|
|
238
|
+
<td>Client-side state management</td>
|
|
239
|
+
</tr>
|
|
240
|
+
<tr>
|
|
241
|
+
<td>Styling</td>
|
|
242
|
+
<td>Tailwind CSS</td>
|
|
243
|
+
<td>Utility-first CSS</td>
|
|
244
|
+
</tr>
|
|
245
|
+
<tr>
|
|
246
|
+
<td>Testing</td>
|
|
247
|
+
<td>Vitest + Playwright</td>
|
|
248
|
+
<td>Unit + E2E tests</td>
|
|
249
|
+
</tr>
|
|
250
|
+
</table>
|
|
251
|
+
|
|
252
|
+
<h2>Folder Structure</h2>
|
|
253
|
+
|
|
254
|
+
<pre><code>src/
|
|
255
|
+
├── app/ # Next.js App Router
|
|
256
|
+
│ ├── (routes)/ # Page routes
|
|
257
|
+
│ ├── api/ # API endpoints
|
|
258
|
+
│ └── layout.tsx # Root layout
|
|
259
|
+
├── components/ # React components
|
|
260
|
+
│ ├── ui/ # UI primitives
|
|
261
|
+
│ └── features/ # Feature components
|
|
262
|
+
├── stores/ # Zustand stores
|
|
263
|
+
├── lib/ # Utilities and helpers
|
|
264
|
+
└── types/ # TypeScript types
|
|
265
|
+
|
|
266
|
+
supabase/
|
|
267
|
+
└── migrations/ # Database migrations
|
|
268
|
+
|
|
269
|
+
tests/
|
|
270
|
+
├── unit/ # Vitest unit tests
|
|
271
|
+
└── e2e/ # Playwright E2E tests
|
|
272
|
+
</code></pre>
|
|
273
|
+
|
|
274
|
+
<h2>Data Flow</h2>
|
|
275
|
+
|
|
276
|
+
<ol>
|
|
277
|
+
<li><strong>User Action</strong> → Component event handler</li>
|
|
278
|
+
<li><strong>Store Method</strong> → Calls API route</li>
|
|
279
|
+
<li><strong>API Route</strong> → Validates auth, queries Supabase</li>
|
|
280
|
+
<li><strong>Database</strong> → Returns data</li>
|
|
281
|
+
<li><strong>Store Update</strong> → Updates state + dependent stores</li>
|
|
282
|
+
<li><strong>React Re-render</strong> → UI reflects new state</li>
|
|
283
|
+
</ol>
|
|
284
|
+
|
|
285
|
+
<h2>Key Principles</h2>
|
|
286
|
+
|
|
287
|
+
<ul>
|
|
288
|
+
<li><strong>Security First:</strong> All queries filter by <code>user_id</code></li>
|
|
289
|
+
<li><strong>Type Safety:</strong> TypeScript strict mode everywhere</li>
|
|
290
|
+
<li><strong>Dependency Awareness:</strong> Mutations update all affected stores</li>
|
|
291
|
+
<li><strong>Error Handling:</strong> All components have loading/error/empty/success states</li>
|
|
292
|
+
<li><strong>Testing:</strong> Every feature has unit + E2E tests</li>
|
|
293
|
+
</ul>
|
|
294
|
+
|
|
295
|
+
${brainContent ? `<h2>Project Context</h2><pre>${brainContent.slice(0, 1000)}</pre>` : ''}
|
|
296
|
+
`;
|
|
297
|
+
return wrapInTemplate('Architecture', content);
|
|
298
|
+
}
|
|
299
|
+
async function generateAPIReference(cwd) {
|
|
300
|
+
const apiRoutes = await findAPIRoutes(cwd);
|
|
301
|
+
let routesList = '';
|
|
302
|
+
if (apiRoutes.length === 0) {
|
|
303
|
+
routesList = '<p>No API routes found.</p>';
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
for (const route of apiRoutes) {
|
|
307
|
+
routesList += `
|
|
308
|
+
<div class="api-route">
|
|
309
|
+
<h3>${route.method} ${route.path}</h3>
|
|
310
|
+
<p><strong>File:</strong> <code>${route.file}</code></p>
|
|
311
|
+
<p><strong>Description:</strong> ${route.description}</p>
|
|
312
|
+
</div>
|
|
313
|
+
`;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const content = `
|
|
317
|
+
<h1>API Reference</h1>
|
|
318
|
+
|
|
319
|
+
<h2>API Endpoints</h2>
|
|
320
|
+
|
|
321
|
+
${routesList}
|
|
322
|
+
|
|
323
|
+
<h2>Authentication</h2>
|
|
324
|
+
|
|
325
|
+
<p>All API routes require authentication via Supabase session:</p>
|
|
326
|
+
|
|
327
|
+
<pre><code class="language-typescript">const supabase = createServerClient();
|
|
328
|
+
const { data: { user }, error } = await supabase.auth.getUser();
|
|
329
|
+
|
|
330
|
+
if (!user) {
|
|
331
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
332
|
+
}</code></pre>
|
|
333
|
+
|
|
334
|
+
<h2>Error Responses</h2>
|
|
335
|
+
|
|
336
|
+
<table>
|
|
337
|
+
<tr>
|
|
338
|
+
<th>Status</th>
|
|
339
|
+
<th>Meaning</th>
|
|
340
|
+
</tr>
|
|
341
|
+
<tr>
|
|
342
|
+
<td>200</td>
|
|
343
|
+
<td>Success</td>
|
|
344
|
+
</tr>
|
|
345
|
+
<tr>
|
|
346
|
+
<td>400</td>
|
|
347
|
+
<td>Bad Request (validation error)</td>
|
|
348
|
+
</tr>
|
|
349
|
+
<tr>
|
|
350
|
+
<td>401</td>
|
|
351
|
+
<td>Unauthorized (not logged in)</td>
|
|
352
|
+
</tr>
|
|
353
|
+
<tr>
|
|
354
|
+
<td>403</td>
|
|
355
|
+
<td>Forbidden (no permission)</td>
|
|
356
|
+
</tr>
|
|
357
|
+
<tr>
|
|
358
|
+
<td>404</td>
|
|
359
|
+
<td>Not Found</td>
|
|
360
|
+
</tr>
|
|
361
|
+
<tr>
|
|
362
|
+
<td>500</td>
|
|
363
|
+
<td>Internal Server Error</td>
|
|
364
|
+
</tr>
|
|
365
|
+
</table>
|
|
366
|
+
`;
|
|
367
|
+
return wrapInTemplate('API Reference', content);
|
|
368
|
+
}
|
|
369
|
+
async function findAPIRoutes(cwd) {
|
|
370
|
+
const routes = [];
|
|
371
|
+
const apiDir = path.join(cwd, 'src', 'app', 'api');
|
|
372
|
+
try {
|
|
373
|
+
await scanAPIDirectory(apiDir, '', routes);
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
// API directory doesn't exist
|
|
377
|
+
}
|
|
378
|
+
return routes;
|
|
379
|
+
}
|
|
380
|
+
async function scanAPIDirectory(dir, routePath, routes) {
|
|
381
|
+
try {
|
|
382
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
383
|
+
for (const entry of entries) {
|
|
384
|
+
const fullPath = path.join(dir, entry.name);
|
|
385
|
+
if (entry.isDirectory()) {
|
|
386
|
+
const newPath = entry.name.startsWith('[') && entry.name.endsWith(']')
|
|
387
|
+
? `${routePath}/{${entry.name.slice(1, -1)}}`
|
|
388
|
+
: `${routePath}/${entry.name}`;
|
|
389
|
+
await scanAPIDirectory(fullPath, newPath, routes);
|
|
390
|
+
}
|
|
391
|
+
else if (entry.name === 'route.ts' || entry.name === 'route.js') {
|
|
392
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
393
|
+
// Detect methods
|
|
394
|
+
const methods = [];
|
|
395
|
+
if (content.includes('export async function GET'))
|
|
396
|
+
methods.push('GET');
|
|
397
|
+
if (content.includes('export async function POST'))
|
|
398
|
+
methods.push('POST');
|
|
399
|
+
if (content.includes('export async function PUT'))
|
|
400
|
+
methods.push('PUT');
|
|
401
|
+
if (content.includes('export async function PATCH'))
|
|
402
|
+
methods.push('PATCH');
|
|
403
|
+
if (content.includes('export async function DELETE'))
|
|
404
|
+
methods.push('DELETE');
|
|
405
|
+
for (const method of methods) {
|
|
406
|
+
routes.push({
|
|
407
|
+
method,
|
|
408
|
+
path: `/api${routePath}`,
|
|
409
|
+
file: fullPath,
|
|
410
|
+
description: `${method} operation for ${routePath.split('/').pop() || 'resource'}`
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
// Directory doesn't exist
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async function generateComponentDocs(cwd) {
|
|
421
|
+
const components = await findComponents(cwd);
|
|
422
|
+
let componentsList = '';
|
|
423
|
+
if (components.length === 0) {
|
|
424
|
+
componentsList = '<p>No components found.</p>';
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
for (const component of components) {
|
|
428
|
+
componentsList += `
|
|
429
|
+
<div class="component-doc">
|
|
430
|
+
<h3>${component.name}</h3>
|
|
431
|
+
<p><strong>File:</strong> <code>${component.file}</code></p>
|
|
432
|
+
<p><strong>Props:</strong> ${component.props.join(', ') || 'None'}</p>
|
|
433
|
+
</div>
|
|
434
|
+
`;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
const content = `
|
|
438
|
+
<h1>Component Documentation</h1>
|
|
439
|
+
|
|
440
|
+
<h2>UI Components</h2>
|
|
441
|
+
|
|
442
|
+
${componentsList}
|
|
443
|
+
|
|
444
|
+
<h2>Component Structure</h2>
|
|
445
|
+
|
|
446
|
+
<p>All components follow the same pattern:</p>
|
|
447
|
+
|
|
448
|
+
<pre><code class="language-typescript">// States
|
|
449
|
+
if (loading) return <SkeletonLoader />;
|
|
450
|
+
if (error) return <ErrorMessage error={error} />;
|
|
451
|
+
if (data.length === 0) return <EmptyState />;
|
|
452
|
+
return <SuccessView data={data} />;
|
|
453
|
+
</code></pre>
|
|
454
|
+
`;
|
|
455
|
+
return wrapInTemplate('Components', content);
|
|
456
|
+
}
|
|
457
|
+
async function findComponents(cwd) {
|
|
458
|
+
const components = [];
|
|
459
|
+
const componentsDir = path.join(cwd, 'src', 'components');
|
|
460
|
+
try {
|
|
461
|
+
const files = await fs.readdir(componentsDir);
|
|
462
|
+
for (const file of files) {
|
|
463
|
+
if (file.endsWith('.tsx') || file.endsWith('.jsx')) {
|
|
464
|
+
const filePath = path.join(componentsDir, file);
|
|
465
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
466
|
+
// Extract component name
|
|
467
|
+
const match = content.match(/export\s+(?:default\s+)?function\s+(\w+)/);
|
|
468
|
+
const name = match ? match[1] : file.replace(/\.(tsx|jsx)$/, '');
|
|
469
|
+
// Extract props (simple detection)
|
|
470
|
+
const propsMatch = content.match(/interface\s+\w+Props\s*{([^}]+)}/);
|
|
471
|
+
const props = propsMatch
|
|
472
|
+
? propsMatch[1].split('\n').map(l => l.trim()).filter(l => l && !l.startsWith('//')).map(l => l.split(':')[0].trim())
|
|
473
|
+
: [];
|
|
474
|
+
components.push({ name, file, props });
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
catch {
|
|
479
|
+
// Components directory doesn't exist
|
|
480
|
+
}
|
|
481
|
+
return components;
|
|
482
|
+
}
|
|
483
|
+
function generateIndexPage(sections) {
|
|
484
|
+
const sectionLinks = sections.map(s => {
|
|
485
|
+
const filename = s.toLowerCase().replace(/\s+/g, '-') + '.html';
|
|
486
|
+
return `<li><a href="${filename}">${s}</a></li>`;
|
|
487
|
+
}).join('\n');
|
|
488
|
+
const content = `
|
|
489
|
+
<h1>📚 Documentation</h1>
|
|
490
|
+
|
|
491
|
+
<p>Welcome to the complete documentation for this application.</p>
|
|
492
|
+
|
|
493
|
+
<h2>Sections</h2>
|
|
494
|
+
|
|
495
|
+
<ul class="nav-list">
|
|
496
|
+
${sectionLinks}
|
|
497
|
+
</ul>
|
|
498
|
+
|
|
499
|
+
<div class="callout callout-success">
|
|
500
|
+
<h4>🚀 New to the project?</h4>
|
|
501
|
+
<p>Start with the <a href="quick-start.html">Quick Start Guide</a></p>
|
|
502
|
+
</div>
|
|
503
|
+
`;
|
|
504
|
+
return wrapInTemplate('Documentation', content);
|
|
505
|
+
}
|
|
506
|
+
function wrapInTemplate(title, content) {
|
|
507
|
+
return `<!DOCTYPE html>
|
|
508
|
+
<html lang="en">
|
|
509
|
+
<head>
|
|
510
|
+
<meta charset="UTF-8">
|
|
511
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
512
|
+
<title>${title} - Documentation</title>
|
|
513
|
+
<link rel="stylesheet" href="styles.css">
|
|
514
|
+
</head>
|
|
515
|
+
<body>
|
|
516
|
+
<nav class="sidebar">
|
|
517
|
+
<h2>📚 Docs</h2>
|
|
518
|
+
<ul>
|
|
519
|
+
<li><a href="index.html">Home</a></li>
|
|
520
|
+
<li><a href="quick-start.html">Quick Start</a></li>
|
|
521
|
+
<li><a href="setup.html">Setup</a></li>
|
|
522
|
+
<li><a href="architecture.html">Architecture</a></li>
|
|
523
|
+
<li><a href="api-reference.html">API Reference</a></li>
|
|
524
|
+
<li><a href="components.html">Components</a></li>
|
|
525
|
+
</ul>
|
|
526
|
+
</nav>
|
|
527
|
+
<main class="content">
|
|
528
|
+
${content}
|
|
529
|
+
<footer>
|
|
530
|
+
<p>Generated by CodeBakers v5.2.0 • ${new Date().toLocaleDateString()}</p>
|
|
531
|
+
</footer>
|
|
532
|
+
</main>
|
|
533
|
+
</body>
|
|
534
|
+
</html>`;
|
|
535
|
+
}
|
|
536
|
+
async function writeDocFile(outputPath, filename, content) {
|
|
537
|
+
const filePath = path.join(outputPath, filename);
|
|
538
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
539
|
+
}
|
|
540
|
+
async function writeCSSFile(outputPath) {
|
|
541
|
+
const css = `
|
|
542
|
+
* {
|
|
543
|
+
margin: 0;
|
|
544
|
+
padding: 0;
|
|
545
|
+
box-sizing: border-box;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
body {
|
|
549
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
550
|
+
line-height: 1.6;
|
|
551
|
+
color: #333;
|
|
552
|
+
display: flex;
|
|
553
|
+
min-height: 100vh;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
.sidebar {
|
|
557
|
+
width: 250px;
|
|
558
|
+
background: #2c3e50;
|
|
559
|
+
color: white;
|
|
560
|
+
padding: 2rem 1.5rem;
|
|
561
|
+
position: fixed;
|
|
562
|
+
height: 100vh;
|
|
563
|
+
overflow-y: auto;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.sidebar h2 {
|
|
567
|
+
margin-bottom: 1.5rem;
|
|
568
|
+
font-size: 1.5rem;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
.sidebar ul {
|
|
572
|
+
list-style: none;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.sidebar li {
|
|
576
|
+
margin-bottom: 0.5rem;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.sidebar a {
|
|
580
|
+
color: #ecf0f1;
|
|
581
|
+
text-decoration: none;
|
|
582
|
+
display: block;
|
|
583
|
+
padding: 0.5rem;
|
|
584
|
+
border-radius: 4px;
|
|
585
|
+
transition: background 0.2s;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
.sidebar a:hover {
|
|
589
|
+
background: #34495e;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.content {
|
|
593
|
+
margin-left: 250px;
|
|
594
|
+
padding: 3rem;
|
|
595
|
+
flex: 1;
|
|
596
|
+
max-width: 900px;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
h1 {
|
|
600
|
+
font-size: 2.5rem;
|
|
601
|
+
margin-bottom: 1.5rem;
|
|
602
|
+
color: #2c3e50;
|
|
603
|
+
border-bottom: 3px solid #3498db;
|
|
604
|
+
padding-bottom: 0.5rem;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
h2 {
|
|
608
|
+
font-size: 2rem;
|
|
609
|
+
margin: 2rem 0 1rem;
|
|
610
|
+
color: #34495e;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
h3 {
|
|
614
|
+
font-size: 1.5rem;
|
|
615
|
+
margin: 1.5rem 0 1rem;
|
|
616
|
+
color: #555;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
h4 {
|
|
620
|
+
font-size: 1.2rem;
|
|
621
|
+
margin: 1rem 0 0.5rem;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
p {
|
|
625
|
+
margin-bottom: 1rem;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
a {
|
|
629
|
+
color: #3498db;
|
|
630
|
+
text-decoration: none;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
a:hover {
|
|
634
|
+
text-decoration: underline;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
pre {
|
|
638
|
+
background: #f5f5f5;
|
|
639
|
+
border: 1px solid #ddd;
|
|
640
|
+
border-radius: 4px;
|
|
641
|
+
padding: 1rem;
|
|
642
|
+
overflow-x: auto;
|
|
643
|
+
margin: 1rem 0;
|
|
644
|
+
font-size: 0.9rem;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
code {
|
|
648
|
+
background: #f5f5f5;
|
|
649
|
+
padding: 0.2rem 0.4rem;
|
|
650
|
+
border-radius: 3px;
|
|
651
|
+
font-family: 'Courier New', monospace;
|
|
652
|
+
font-size: 0.9em;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
pre code {
|
|
656
|
+
background: none;
|
|
657
|
+
padding: 0;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
table {
|
|
661
|
+
width: 100%;
|
|
662
|
+
border-collapse: collapse;
|
|
663
|
+
margin: 1.5rem 0;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
th, td {
|
|
667
|
+
padding: 0.75rem;
|
|
668
|
+
text-align: left;
|
|
669
|
+
border-bottom: 1px solid #ddd;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
th {
|
|
673
|
+
background: #f5f5f5;
|
|
674
|
+
font-weight: 600;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
ul, ol {
|
|
678
|
+
margin: 1rem 0 1rem 2rem;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
li {
|
|
682
|
+
margin-bottom: 0.5rem;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
.nav-list {
|
|
686
|
+
list-style: none;
|
|
687
|
+
margin: 1rem 0;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.nav-list li {
|
|
691
|
+
margin-bottom: 1rem;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
.nav-list a {
|
|
695
|
+
display: block;
|
|
696
|
+
padding: 1rem;
|
|
697
|
+
background: #f5f5f5;
|
|
698
|
+
border-left: 4px solid #3498db;
|
|
699
|
+
border-radius: 4px;
|
|
700
|
+
transition: all 0.2s;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
.nav-list a:hover {
|
|
704
|
+
background: #e8f4f8;
|
|
705
|
+
transform: translateX(5px);
|
|
706
|
+
text-decoration: none;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.callout {
|
|
710
|
+
padding: 1rem 1.5rem;
|
|
711
|
+
border-radius: 4px;
|
|
712
|
+
margin: 1.5rem 0;
|
|
713
|
+
border-left: 4px solid;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
.callout-success {
|
|
717
|
+
background: #d4edda;
|
|
718
|
+
border-color: #28a745;
|
|
719
|
+
color: #155724;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
.callout-info {
|
|
723
|
+
background: #d1ecf1;
|
|
724
|
+
border-color: #17a2b8;
|
|
725
|
+
color: #0c5460;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.api-route, .component-doc {
|
|
729
|
+
background: #f9f9f9;
|
|
730
|
+
padding: 1.5rem;
|
|
731
|
+
border-radius: 4px;
|
|
732
|
+
margin-bottom: 1.5rem;
|
|
733
|
+
border-left: 4px solid #3498db;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
footer {
|
|
737
|
+
margin-top: 4rem;
|
|
738
|
+
padding-top: 2rem;
|
|
739
|
+
border-top: 1px solid #ddd;
|
|
740
|
+
color: #777;
|
|
741
|
+
font-size: 0.9rem;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
@media (max-width: 768px) {
|
|
745
|
+
.sidebar {
|
|
746
|
+
width: 100%;
|
|
747
|
+
position: static;
|
|
748
|
+
height: auto;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.content {
|
|
752
|
+
margin-left: 0;
|
|
753
|
+
padding: 1.5rem;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
`;
|
|
757
|
+
await fs.writeFile(path.join(outputPath, 'styles.css'), css, 'utf-8');
|
|
758
|
+
}
|
|
759
|
+
function generateDocsReport(outputPath, sections) {
|
|
760
|
+
let report = `🍞 CodeBakers: Documentation Generated\n\n`;
|
|
761
|
+
report += `✅ **Output:** ${outputPath}/\n\n`;
|
|
762
|
+
report += `## Generated Pages\n\n`;
|
|
763
|
+
report += `- index.html (Home)\n`;
|
|
764
|
+
for (const section of sections) {
|
|
765
|
+
report += `- ${section.toLowerCase().replace(/\s+/g, '-')}.html\n`;
|
|
766
|
+
}
|
|
767
|
+
report += `\n`;
|
|
768
|
+
report += `## View Documentation\n\n`;
|
|
769
|
+
report += `Open in browser:\n`;
|
|
770
|
+
report += `\`\`\`\n`;
|
|
771
|
+
report += `open ${outputPath}/index.html\n`;
|
|
772
|
+
report += `\`\`\`\n\n`;
|
|
773
|
+
report += `Or serve with:\n`;
|
|
774
|
+
report += `\`\`\`\n`;
|
|
775
|
+
report += `cd ${outputPath}\n`;
|
|
776
|
+
report += `python -m http.server 8000\n`;
|
|
777
|
+
report += `\`\`\`\n\n`;
|
|
778
|
+
report += `Then visit: http://localhost:8000\n\n`;
|
|
779
|
+
report += `📚 Beautiful, navigable documentation ready!\n`;
|
|
780
|
+
return report;
|
|
781
|
+
}
|
|
782
|
+
//# sourceMappingURL=generate-docs.js.map
|