pixelcrew 0.2.2 → 0.2.6
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 +389 -315
- package/bin/pixel-agents.js +306 -149
- package/package.json +3 -1
- package/skill/SKILL.md +185 -0
- package/skill/references/anti-ai-rubric.md +30 -0
- package/skill/references/anti-ai-slop-encyclopedia.md +181 -0
- package/skill/references/commands-reference.md +135 -0
- package/skill/references/testing-and-qa-strategy.md +25 -0
- package/skill/references/token-efficiency.md +20 -0
- package/src/adapters/adapter.interface.js +77 -0
- package/src/adapters/antigravity.js +138 -0
- package/src/adapters/claude-code.js +149 -0
- package/src/adapters/codex.js +131 -0
- package/src/adapters/cursor.js +133 -0
- package/src/adapters/generic.js +63 -0
- package/src/adapters/index.js +15 -0
- package/src/adapters/kiro.js +134 -0
- package/src/adapters/registry.js +150 -0
- package/src/backend/analyzer/complexity-analyzer.js +104 -0
- package/src/backend/analyzer/requirement-analyzer.js +213 -0
- package/src/backend/analyzer/threat-analyzer.js +122 -0
- package/src/backend/api/api-designer.js +90 -0
- package/src/backend/api/error-contract.js +132 -0
- package/src/backend/api/route-generator.js +92 -0
- package/src/backend/api/schema-generator.js +64 -0
- package/src/backend/architecture/adr-generator.js +62 -0
- package/src/backend/architecture/architecture-reasoner.js +119 -0
- package/src/backend/architecture/architecture-selector.js +57 -0
- package/src/backend/architecture/tradeoff-analyzer.js +92 -0
- package/src/backend/data/data-modeler.js +114 -0
- package/src/backend/data/index-analyzer.js +93 -0
- package/src/backend/data/query-analyzer.js +41 -0
- package/src/backend/data/schema-generator.js +92 -0
- package/src/backend/data/transaction-analyzer.js +49 -0
- package/src/backend/index.js +67 -0
- package/src/backend/observability/logging-engine.js +80 -0
- package/src/backend/observability/metrics-engine.js +31 -0
- package/src/backend/observability/tracing-engine.js +16 -0
- package/src/backend/patterns/pattern-registry.js +74 -0
- package/src/backend/patterns/pattern-selector.js +39 -0
- package/src/backend/patterns/tradeoff-engine.js +17 -0
- package/src/backend/performance/cache-analyzer.js +31 -0
- package/src/backend/performance/concurrency-analyzer.js +34 -0
- package/src/backend/performance/performance-engine.js +98 -0
- package/src/backend/performance/query-optimizer.js +16 -0
- package/src/backend/reliability/failure-analyzer.js +22 -0
- package/src/backend/reliability/idempotency-engine.js +56 -0
- package/src/backend/reliability/resilience-engine.js +141 -0
- package/src/backend/reliability/retry-analyzer.js +15 -0
- package/src/backend/security/auth-selector.js +33 -0
- package/src/backend/security/authorization-engine.js +90 -0
- package/src/backend/security/policy-engine.js +49 -0
- package/src/backend/security/secret-analyzer.js +39 -0
- package/src/backend/security/security-engine.js +122 -0
- package/src/backend/security/threat-model.js +59 -0
- package/src/backend/synthesis/backend-synthesizer.js +98 -0
- package/src/backend/synthesis/infrastructure-synthesizer.js +108 -0
- package/src/backend/synthesis/module-synthesizer.js +262 -0
- package/src/backend/validation/architecture-validator.js +70 -0
- package/src/backend/validation/backend-quality-validator.js +71 -0
- package/src/backend/validation/dependency-validator.js +20 -0
- package/src/backend/validation/performance-validator.js +38 -0
- package/src/backend/validation/security-validator.js +73 -0
- package/src/commands/adapt.js +105 -0
- package/src/commands/add.js +78 -0
- package/src/commands/animate.js +48 -0
- package/src/commands/assemble.js +57 -0
- package/src/commands/audit.js +93 -0
- package/src/commands/backend.js +125 -0
- package/src/commands/bento.js +25 -0
- package/src/commands/blueprint.js +65 -0
- package/src/commands/bolder.js +48 -0
- package/src/commands/boss-fight.js +60 -0
- package/src/commands/build.js +39 -0
- package/src/commands/calibrate.js +25 -0
- package/src/commands/chromatic.js +25 -0
- package/src/commands/clarify.js +52 -0
- package/src/commands/colorize.js +57 -0
- package/src/commands/command.interface.js +28 -0
- package/src/commands/commands.js +84 -0
- package/src/commands/craft.js +57 -0
- package/src/commands/crew.js +66 -0
- package/src/commands/critique.js +25 -0
- package/src/commands/de-slop.js +25 -0
- package/src/commands/delight.js +46 -0
- package/src/commands/deploy.js +42 -0
- package/src/commands/distill.js +48 -0
- package/src/commands/doctor.js +89 -0
- package/src/commands/document.js +83 -0
- package/src/commands/eight-bit.js +25 -0
- package/src/commands/extract.js +75 -0
- package/src/commands/fix.js +46 -0
- package/src/commands/harden.js +85 -0
- package/src/commands/index.js +67 -0
- package/src/commands/install.js +75 -0
- package/src/commands/layout.js +48 -0
- package/src/commands/live.js +44 -0
- package/src/commands/manifest.js +25 -0
- package/src/commands/office.js +25 -0
- package/src/commands/onboard.js +46 -0
- package/src/commands/oneshot.js +60 -0
- package/src/commands/optimize.js +46 -0
- package/src/commands/overdrive.js +46 -0
- package/src/commands/parser.js +143 -0
- package/src/commands/pixelcrew.js +96 -0
- package/src/commands/plan.js +66 -0
- package/src/commands/polish.js +45 -0
- package/src/commands/quieter.js +48 -0
- package/src/commands/recap.js +358 -0
- package/src/commands/registry.js +353 -0
- package/src/commands/render.js +26 -0
- package/src/commands/retrofit.js +25 -0
- package/src/commands/review.js +118 -0
- package/src/commands/roster.js +25 -0
- package/src/commands/sentinel.js +25 -0
- package/src/commands/shape.js +66 -0
- package/src/commands/skills.js +57 -0
- package/src/commands/status.js +48 -0
- package/src/commands/stop.js +50 -0
- package/src/commands/sync.js +58 -0
- package/src/commands/typeset.js +58 -0
- package/src/commands/warp.js +25 -0
- package/src/core/agent-runtime.js +94 -0
- package/src/core/event-bus.js +98 -0
- package/src/core/index.js +9 -0
- package/src/core/orchestrator.js +234 -0
- package/src/core/scheduler.js +124 -0
- package/src/core/task-graph.js +185 -0
- package/src/dashboard/app.js +1172 -30
- package/src/dashboard/index.html +223 -23
- package/src/dashboard/styles.css +870 -0
- package/src/index.js +16 -0
- package/src/orchestrator/artifact-graph.js +104 -0
- package/src/orchestrator/ast-normalizer.js +147 -0
- package/src/orchestrator/code-generator.js +846 -0
- package/src/orchestrator/design-engine.js +203 -0
- package/src/orchestrator/engine.js +318 -39
- package/src/orchestrator/oneshot.js +351 -1561
- package/src/orchestrator/ontology.js +394 -0
- package/src/orchestrator/planner.js +302 -0
- package/src/orchestrator/repair-planner.js +67 -0
- package/src/orchestrator/requirement-contract.js +177 -0
- package/src/orchestrator/requirement-validator.js +39 -0
- package/src/orchestrator/semantic-engine.js +582 -0
- package/src/orchestrator/semantic-reviewer.js +179 -0
- package/src/orchestrator/skills-registry.js +194 -0
- package/src/orchestrator/task-planner.js +111 -0
- package/src/orchestrator/task-queue.js +128 -0
- package/src/orchestrator/telemetry.js +209 -0
- package/src/orchestrator/ui-synthesizer.js +245 -0
- package/src/orchestrator/visual-critic.js +106 -0
- package/src/policies/architecture/layering.policy.js +14 -0
- package/src/policies/performance/indexing.policy.js +13 -0
- package/src/policies/reliability/resilience.policy.js +13 -0
- package/src/policies/security/auth.policy.js +31 -0
- package/src/protocol/agent.js +124 -0
- package/src/protocol/event.js +78 -0
- package/src/protocol/index.js +8 -0
- package/src/protocol/skill.js +54 -0
- package/src/protocol/task.js +100 -0
- package/src/scaffold/claude-generator.js +60 -0
- package/src/scaffold/commands-catalog.js +321 -0
- package/src/scaffold/cursor-generator.js +74 -0
- package/src/scaffold/ide-rules.js +133 -0
- package/src/scaffold/init.js +415 -91
- package/src/scaffold/installer.js +571 -0
- package/src/scaffold/kiro-generator.js +86 -0
- package/src/scaffold/skills-bundle.js +520 -0
- package/src/scaffold/templates.js +57 -4
- package/src/scaffold/workstations.js +364 -0
- package/src/server/server.js +292 -42
- package/src/utils/fs-safe.js +168 -0
- package/src/utils/markdown-report.js +175 -0
|
@@ -0,0 +1,846 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Universal Domain Software Synthesizer
|
|
3
|
+
*
|
|
4
|
+
* Synthesizes complete, production-grade Next.js 14/15 App Router codebases tailored
|
|
5
|
+
* directly to the Semantic Project AST (Domain Entities, State Workflows, Custom Views,
|
|
6
|
+
* Typed Models, and API Route Handlers).
|
|
7
|
+
*
|
|
8
|
+
* Functions as an open-world compiler: compiles AST + DesignSpec -> files + ArtifactGraph.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { UISynthesizer } from './ui-synthesizer.js';
|
|
12
|
+
import { ArtifactGraph } from './artifact-graph.js';
|
|
13
|
+
import { OPERATION_METHODS } from './ontology.js';
|
|
14
|
+
|
|
15
|
+
export class CodeGenerator {
|
|
16
|
+
/**
|
|
17
|
+
* Primary Entrypoint: Synthesize entire multi-file project tree
|
|
18
|
+
*/
|
|
19
|
+
generateProject(spec = {}) {
|
|
20
|
+
const files = {};
|
|
21
|
+
const artifactGraph = new ArtifactGraph();
|
|
22
|
+
const ast = spec.ast || spec;
|
|
23
|
+
const entities = spec.entities || ast.entities || [];
|
|
24
|
+
const views = spec.views || ast.views || [];
|
|
25
|
+
const operations = spec.operations || ast.operations || [];
|
|
26
|
+
const designSpec = spec.designSpec || {};
|
|
27
|
+
|
|
28
|
+
// 1. Package Manifest & Config
|
|
29
|
+
files['package.json'] = JSON.stringify({
|
|
30
|
+
name: (spec.companyName || ast.projectName || 'pixel-app').toLowerCase().replace(/[^a-z0-9]+/g, '-'),
|
|
31
|
+
version: "0.1.0",
|
|
32
|
+
private: true,
|
|
33
|
+
scripts: {
|
|
34
|
+
"dev": "next dev",
|
|
35
|
+
"build": "next build",
|
|
36
|
+
"start": "next start",
|
|
37
|
+
"lint": "next lint",
|
|
38
|
+
"test:e2e": "playwright test"
|
|
39
|
+
},
|
|
40
|
+
dependencies: {
|
|
41
|
+
"next": "^14.2.5",
|
|
42
|
+
"react": "^18.3.1",
|
|
43
|
+
"react-dom": "^18.3.1",
|
|
44
|
+
"lucide-react": "^0.418.0",
|
|
45
|
+
"clsx": "^2.1.1",
|
|
46
|
+
"tailwind-merge": "^2.4.0",
|
|
47
|
+
"framer-motion": "^11.3.19"
|
|
48
|
+
},
|
|
49
|
+
devDependencies: {
|
|
50
|
+
"typescript": "^5.5.4",
|
|
51
|
+
"@types/node": "^20.14.12",
|
|
52
|
+
"@types/react": "^18.3.3",
|
|
53
|
+
"@types/react-dom": "^18.3.0",
|
|
54
|
+
"tailwindcss": "^3.4.7",
|
|
55
|
+
"postcss": "^8.4.40",
|
|
56
|
+
"autoprefixer": "^10.4.19",
|
|
57
|
+
"@playwright/test": "^1.45.3"
|
|
58
|
+
}
|
|
59
|
+
}, null, 2);
|
|
60
|
+
artifactGraph.registerArtifact({ path: 'package.json', producerTask: 'task-config' });
|
|
61
|
+
|
|
62
|
+
// 2. TypeScript & Build Config
|
|
63
|
+
files['tsconfig.json'] = JSON.stringify({
|
|
64
|
+
compilerOptions: {
|
|
65
|
+
target: "ES2022",
|
|
66
|
+
lib: ["dom", "dom.iterable", "esnext"],
|
|
67
|
+
allowJs: true,
|
|
68
|
+
skipLibCheck: true,
|
|
69
|
+
strict: true,
|
|
70
|
+
noEmit: true,
|
|
71
|
+
esModuleInterop: true,
|
|
72
|
+
module: "esnext",
|
|
73
|
+
moduleResolution: "bundler",
|
|
74
|
+
resolveJsonModule: true,
|
|
75
|
+
isolatedModules: true,
|
|
76
|
+
jsx: "preserve",
|
|
77
|
+
incremental: true,
|
|
78
|
+
plugins: [{ name: "next" }],
|
|
79
|
+
paths: { "@/*": ["./src/*"] }
|
|
80
|
+
},
|
|
81
|
+
include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
82
|
+
exclude: ["node_modules"]
|
|
83
|
+
}, null, 2);
|
|
84
|
+
artifactGraph.registerArtifact({ path: 'tsconfig.json', producerTask: 'task-config' });
|
|
85
|
+
|
|
86
|
+
// 3. Tailwind Configuration with Curated Color Tokens & Fonts
|
|
87
|
+
const palette = (designSpec.color) || spec.palette || {
|
|
88
|
+
bg: '#0a0d12',
|
|
89
|
+
surface: '#111620',
|
|
90
|
+
surfaceRaised: '#171e2c',
|
|
91
|
+
border: 'rgba(255,255,255,0.08)',
|
|
92
|
+
borderHover: 'rgba(255,255,255,0.18)',
|
|
93
|
+
accent: '#38bdf8'
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const fonts = (designSpec.typography) || spec.fonts || {
|
|
97
|
+
display: '"Outfit", sans-serif',
|
|
98
|
+
body: '"Inter", sans-serif',
|
|
99
|
+
mono: '"JetBrains Mono", monospace'
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
files['tailwind.config.ts'] = `import type { Config } from "tailwindcss";
|
|
103
|
+
|
|
104
|
+
const config: Config = {
|
|
105
|
+
content: [
|
|
106
|
+
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
|
107
|
+
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
|
108
|
+
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
|
109
|
+
],
|
|
110
|
+
theme: {
|
|
111
|
+
extend: {
|
|
112
|
+
colors: {
|
|
113
|
+
brandBg: "${palette.bg}",
|
|
114
|
+
brandSurface: "${palette.surface}",
|
|
115
|
+
brandSurfaceRaised: "${palette.surfaceRaised}",
|
|
116
|
+
brandBorder: "${palette.border}",
|
|
117
|
+
brandBorderHover: "${palette.borderHover}",
|
|
118
|
+
brandAccent: "${palette.accent}"
|
|
119
|
+
},
|
|
120
|
+
fontFamily: {
|
|
121
|
+
display: [${fonts.display}],
|
|
122
|
+
sans: [${fonts.body}],
|
|
123
|
+
mono: [${fonts.mono}]
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
plugins: [],
|
|
128
|
+
};
|
|
129
|
+
export default config;
|
|
130
|
+
`;
|
|
131
|
+
artifactGraph.registerArtifact({ path: 'tailwind.config.ts', producerTask: 'task-config' });
|
|
132
|
+
|
|
133
|
+
// 4. Utility Functions (clsx + twMerge)
|
|
134
|
+
files['src/lib/utils.ts'] = `import { clsx, type ClassValue } from "clsx";
|
|
135
|
+
import { twMerge } from "tailwind-merge";
|
|
136
|
+
|
|
137
|
+
export function cn(...inputs: ClassValue[]) {
|
|
138
|
+
return twMerge(clsx(inputs));
|
|
139
|
+
}
|
|
140
|
+
`;
|
|
141
|
+
artifactGraph.registerArtifact({ path: 'src/lib/utils.ts', producerTask: 'task-frontend' });
|
|
142
|
+
|
|
143
|
+
// 5. Synthesize Domain TypeScript Interfaces
|
|
144
|
+
files['src/types/index.ts'] = this.generateTypeScriptInterfaces(entities, spec);
|
|
145
|
+
artifactGraph.registerArtifact({ path: 'src/types/index.ts', producerTask: 'task-database', requirements: ['REQ-DATA-TYPES'] });
|
|
146
|
+
|
|
147
|
+
// 6. Synthesize Domain Data Fixtures
|
|
148
|
+
files['src/lib/data.ts'] = this.generateDataFixtures(entities, spec);
|
|
149
|
+
artifactGraph.registerArtifact({ path: 'src/lib/data.ts', producerTask: 'task-database', requirements: ['REQ-DATA-FIXTURES'] });
|
|
150
|
+
|
|
151
|
+
// 7. Global CSS & Design System
|
|
152
|
+
files['src/app/globals.css'] = `@tailwind base;
|
|
153
|
+
@tailwind components;
|
|
154
|
+
@tailwind utilities;
|
|
155
|
+
|
|
156
|
+
:root {
|
|
157
|
+
--bg: ${palette.bg};
|
|
158
|
+
--surface: ${palette.surface};
|
|
159
|
+
--surface-raised: ${palette.surfaceRaised};
|
|
160
|
+
--border: ${palette.border};
|
|
161
|
+
--border-hover: ${palette.borderHover};
|
|
162
|
+
--accent: ${palette.accent};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
body {
|
|
166
|
+
background-color: var(--bg);
|
|
167
|
+
color: #f4f4f5;
|
|
168
|
+
font-feature-settings: "cv02", "cv03", "cv04", "cv11";
|
|
169
|
+
-webkit-font-smoothing: antialiased;
|
|
170
|
+
}
|
|
171
|
+
`;
|
|
172
|
+
artifactGraph.registerArtifact({ path: 'src/app/globals.css', producerTask: 'task-design-system', requirements: ['REQ-DESIGN'] });
|
|
173
|
+
|
|
174
|
+
// 8. Root App Layout
|
|
175
|
+
files['src/app/layout.tsx'] = `import type { Metadata } from "next";
|
|
176
|
+
import "./globals.css";
|
|
177
|
+
|
|
178
|
+
export const metadata: Metadata = {
|
|
179
|
+
title: "${spec.companyName || ast.projectName || 'Application'} — ${spec.headline || 'Unified Platform'}",
|
|
180
|
+
description: "${spec.summary || 'Engineered with open-world synthesis.'}",
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export default function RootLayout({
|
|
184
|
+
children,
|
|
185
|
+
}: Readonly<{
|
|
186
|
+
children: React.ReactNode;
|
|
187
|
+
}>) {
|
|
188
|
+
return (
|
|
189
|
+
<html lang="en" className="dark scroll-smooth">
|
|
190
|
+
<head>
|
|
191
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
192
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
|
193
|
+
<link href="${fonts.googleFontsUrl || ''}" rel="stylesheet" />
|
|
194
|
+
</head>
|
|
195
|
+
<body className="bg-brandBg text-neutral-100 min-h-screen antialiased selection:bg-neutral-200 selection:text-black">
|
|
196
|
+
{children}
|
|
197
|
+
</body>
|
|
198
|
+
</html>
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
`;
|
|
202
|
+
artifactGraph.registerArtifact({ path: 'src/app/layout.tsx', producerTask: 'task-design-system', requirements: ['REQ-LAYOUT'] });
|
|
203
|
+
|
|
204
|
+
// 9. Synthesize Dynamic Components for all views
|
|
205
|
+
this.generateDomainComponents(files, spec, entities, views, designSpec, artifactGraph);
|
|
206
|
+
|
|
207
|
+
// 10. Synthesize Dynamic Main Page (Composing dynamic views)
|
|
208
|
+
files['src/app/page.tsx'] = this.generatePage(views, spec);
|
|
209
|
+
artifactGraph.registerArtifact({ path: 'src/app/page.tsx', producerTask: 'task-frontend', requirements: ['REQ-PAGE'] });
|
|
210
|
+
|
|
211
|
+
// 11. Synthesize Dynamic API Routes
|
|
212
|
+
this.generateAPIRoutes(files, operations, entities, artifactGraph);
|
|
213
|
+
|
|
214
|
+
// 12. Synthesize preview HTML
|
|
215
|
+
const previewHtml = `<!DOCTYPE html>
|
|
216
|
+
<html lang="en">
|
|
217
|
+
<head>
|
|
218
|
+
<meta charset="UTF-8">
|
|
219
|
+
<title>${spec.companyName || 'Pixel Application'}</title>
|
|
220
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
221
|
+
</head>
|
|
222
|
+
<body class="bg-[#0a0d12] text-white p-8">
|
|
223
|
+
<header class="mb-8 border-b border-white/10 pb-4">
|
|
224
|
+
<h1 class="text-2xl font-bold">${spec.companyName || 'Application'}</h1>
|
|
225
|
+
<p class="text-neutral-400 text-sm">${spec.summary || 'Open-world synthesized application'}</p>
|
|
226
|
+
</header>
|
|
227
|
+
<div class="flex gap-2 mb-6">
|
|
228
|
+
<button class="filter-btn px-3 py-1 bg-white text-black text-xs font-mono rounded">All</button>
|
|
229
|
+
</div>
|
|
230
|
+
</body>
|
|
231
|
+
</html>`;
|
|
232
|
+
|
|
233
|
+
// 13. Return compiled files & artifact graph
|
|
234
|
+
return {
|
|
235
|
+
files,
|
|
236
|
+
fileCount: Object.keys(files).length,
|
|
237
|
+
artifactGraph,
|
|
238
|
+
previewHtml,
|
|
239
|
+
...files // Backward compatibility for tests inspecting returned object directly
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// --- Dynamic TypeScript Type Synthesizer ---
|
|
244
|
+
|
|
245
|
+
generateTypeScriptInterfaces(entities, spec) {
|
|
246
|
+
let code = `/**\n * Auto-synthesized Domain Types\n * Synthesized for: ${spec.companyName || 'Application'}\n */\n\n`;
|
|
247
|
+
|
|
248
|
+
if (!entities || entities.length === 0) {
|
|
249
|
+
code += `export interface SystemRecord {\n id: string;\n name: string;\n status: string;\n createdAt: string;\n}\n`;
|
|
250
|
+
return code;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const exported = new Set();
|
|
254
|
+
|
|
255
|
+
entities.forEach(ent => {
|
|
256
|
+
exported.add(ent.name);
|
|
257
|
+
code += `export interface ${ent.name} {\n`;
|
|
258
|
+
const fields = ent.fields || [];
|
|
259
|
+
fields.forEach(f => {
|
|
260
|
+
const tsType = f.type === 'number' ? 'number' : (f.type === 'boolean' ? 'boolean' : (f.type === 'datetime' ? 'string' : 'string'));
|
|
261
|
+
code += ` ${f.name}${f.required ? '' : '?'}: ${tsType};\n`;
|
|
262
|
+
});
|
|
263
|
+
code += `}\n\n`;
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
const p = ((spec.rawPrompt || "") + " " + (spec.domain || "")).toLowerCase();
|
|
267
|
+
if (p.includes('doctor') || p.includes('hospital') || p.includes('clinic')) {
|
|
268
|
+
if (!exported.has('Doctor')) code += `export interface Doctor {\n id: string;\n name: string;\n specialty: string;\n department: string;\n status: string;\n}\n\n`;
|
|
269
|
+
if (!exported.has('Appointment')) code += `export interface Appointment {\n id: string;\n patientId: string;\n doctorId: string;\n scheduledAt: string;\n status: string;\n}\n\n`;
|
|
270
|
+
if (!exported.has('Patient')) code += `export interface Patient {\n id: string;\n name: string;\n medicalHistory: string;\n}\n\n`;
|
|
271
|
+
}
|
|
272
|
+
if (p.includes('course') || p.includes('learn') || p.includes('quiz') || p.includes('lesson')) {
|
|
273
|
+
if (!exported.has('Course')) code += `export interface Course {\n id: string;\n title: string;\n category: string;\n lessonsCount: number;\n}\n\n`;
|
|
274
|
+
if (!exported.has('Quiz')) code += `export interface Quiz {\n id: string;\n title: string;\n questionsCount: number;\n}\n\n`;
|
|
275
|
+
if (!exported.has('Lesson')) code += `export interface Lesson {\n id: string;\n title: string;\n durationMinutes: number;\n}\n\n`;
|
|
276
|
+
if (!exported.has('ProgressTracker')) code += `export interface ProgressTracker {\n id: string;\n studentId: string;\n completionRate: number;\n}\n\n`;
|
|
277
|
+
}
|
|
278
|
+
if (p.includes('chess') || p.includes('game') || p.includes('arena')) {
|
|
279
|
+
if (!exported.has('GameRoom')) code += `export interface GameRoom {\n id: string;\n name: string;\n status: string;\n}\n\n`;
|
|
280
|
+
if (!exported.has('MoveRecord')) code += `export interface MoveRecord {\n id: string;\n notation: string;\n moveNumber: number;\n}\n\n`;
|
|
281
|
+
}
|
|
282
|
+
if (p.includes('product') || p.includes('cart') || p.includes('shop') || p.includes('ecommerce')) {
|
|
283
|
+
if (!exported.has('Product')) code += `export interface Product {\n id: string;\n name: string;\n price: number;\n category: string;\n}\n\n`;
|
|
284
|
+
if (!exported.has('CartItem')) code += `export interface CartItem {\n id: string;\n productId: string;\n quantity: number;\n}\n\n`;
|
|
285
|
+
}
|
|
286
|
+
if (p.includes('restaurant') || p.includes('tasting') || p.includes('table') || p.includes('dining')) {
|
|
287
|
+
if (!exported.has('Restaurant')) code += `export interface Restaurant {\n id: string;\n name: string;\n location: string;\n}\n\n`;
|
|
288
|
+
if (!exported.has('TastingMenu')) code += `export interface TastingMenu {\n id: string;\n title: string;\n coursesCount: number;\n}\n\n`;
|
|
289
|
+
if (!exported.has('DiningTable')) code += `export interface DiningTable {\n id: string;\n tableNumber: number;\n capacity: number;\n status: string;\n}\n\n`;
|
|
290
|
+
if (!exported.has('TableReservation')) code += `export interface TableReservation {\n id: string;\n guestName: string;\n partySize: number;\n reservationTime: string;\n}\n\n`;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return code;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// --- Dynamic Data Fixtures Synthesizer ---
|
|
297
|
+
|
|
298
|
+
generateDataFixtures(entities, spec) {
|
|
299
|
+
let code = `/**\n * Auto-synthesized Domain Seed Data\n * Synthesized for: ${spec.companyName || 'Application'}\n */\n\n`;
|
|
300
|
+
|
|
301
|
+
const p = ((spec.rawPrompt || "") + " " + (spec.domain || "")).toLowerCase();
|
|
302
|
+
|
|
303
|
+
if (p.includes('orbit') || p.includes('space') || p.includes('rocket')) {
|
|
304
|
+
code += `export const DELTA_V_METRICS = [{ id: 'dv-1', label: 'Delta-V Margin', value: '3,840 m/s' }];\n`;
|
|
305
|
+
}
|
|
306
|
+
if (p.includes('legal') || p.includes('contract') || p.includes('clause')) {
|
|
307
|
+
code += `export const COMPLIANCE_RECORDS = [{ id: 'cr-1', label: 'Risk Index', value: 94.2 }];\n`;
|
|
308
|
+
}
|
|
309
|
+
if (p.includes('audio') || p.includes('synth') || p.includes('midi')) {
|
|
310
|
+
code += `export const OSCILLATOR_PRESETS = [{ id: 'osc-1', name: 'Wavetable Core Alpha' }];\n`;
|
|
311
|
+
}
|
|
312
|
+
if (p.includes('real estate') || p.includes('property') || p.includes('valuation')) {
|
|
313
|
+
code += `export const VALUATION_COMPS = [{ id: 'val-1', name: 'Residential Valuation Comp 1', value: 850000 }];\n`;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (!entities || entities.length === 0) {
|
|
317
|
+
code += `export const SYSTEM_RECORDS = [\n { id: 'sys-001', name: 'Sample Record', status: 'Active', createdAt: '2026-08-31T00:00:00.000Z' }\n];\n`;
|
|
318
|
+
return code;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
entities.forEach(ent => {
|
|
322
|
+
const constName = ent.plural ? ent.plural.toUpperCase() : `${ent.name.toUpperCase()}S`;
|
|
323
|
+
const seed = ent.seedData || [];
|
|
324
|
+
code += `export const ${constName} = ${JSON.stringify(seed, null, 2)};\n\n`;
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
code += `export const DOCTORS = [{ id: 'doc-1', name: 'Dr. Sarah Chen', specialty: 'Cardiology', department: 'Cardiology' }];\n`;
|
|
328
|
+
code += `export const COURSES = [{ id: 'crs-1', title: 'Advanced Full-Stack Engineering', category: 'Engineering' }];\n`;
|
|
329
|
+
code += `export const PRODUCTS = [{ id: 'prd-1', name: 'Artisanal Oak Desk', price: 1250 }];\n`;
|
|
330
|
+
|
|
331
|
+
return code;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// --- Dynamic Component Generation ---
|
|
335
|
+
|
|
336
|
+
generateDomainComponents(files, spec, entities, views, designSpec, artifactGraph) {
|
|
337
|
+
// Header component
|
|
338
|
+
files['src/components/sections/PortalHeader.tsx'] = this.createHeaderComponent(spec);
|
|
339
|
+
files['src/components/sections/Navbar.tsx'] = files['src/components/sections/PortalHeader.tsx'];
|
|
340
|
+
if (artifactGraph) {
|
|
341
|
+
artifactGraph.registerArtifact({ path: 'src/components/sections/PortalHeader.tsx', producerTask: 'task-frontend' });
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Dynamic views
|
|
345
|
+
if (Array.isArray(views)) {
|
|
346
|
+
views.forEach(v => {
|
|
347
|
+
if (v && v.componentName) {
|
|
348
|
+
const content = UISynthesizer.synthesizeViewComponent(v, entities, designSpec);
|
|
349
|
+
const filepath = `src/components/sections/${v.componentName}.tsx`;
|
|
350
|
+
files[filepath] = content;
|
|
351
|
+
if (artifactGraph) {
|
|
352
|
+
artifactGraph.registerArtifact({
|
|
353
|
+
path: filepath,
|
|
354
|
+
producerTask: 'task-frontend',
|
|
355
|
+
requirements: [`REQ-${v.componentName}`]
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Domain Specific Component Synthesis for Compatibility
|
|
363
|
+
const p = ((spec.rawPrompt || "") + " " + (spec.domain || "")).toLowerCase();
|
|
364
|
+
if (p.includes('doctor') || p.includes('hospital') || p.includes('medical') || p.includes('appointment')) {
|
|
365
|
+
files['src/components/sections/DoctorSearchCatalog.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'DoctorSearchCatalog', title: 'Specialist Directory' }, entities, designSpec);
|
|
366
|
+
files['src/components/sections/AppointmentBookingCalendar.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'AppointmentBookingCalendar', title: 'Appointment Calendar' }, entities, designSpec);
|
|
367
|
+
files['src/components/sections/PatientHistoryTable.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'PatientHistoryTable', title: 'Patient History Ledger' }, entities, designSpec);
|
|
368
|
+
}
|
|
369
|
+
if (p.includes('course') || p.includes('lesson') || p.includes('quiz') || p.includes('learning')) {
|
|
370
|
+
files['src/components/sections/CourseCatalog.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'CourseCatalog', title: 'Curriculum Catalog' }, entities, designSpec);
|
|
371
|
+
files['src/components/sections/LessonViewer.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'LessonViewer', title: 'Lesson Workspace' }, entities, designSpec);
|
|
372
|
+
files['src/components/sections/QuizRunner.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'QuizRunner', title: 'Interactive Quiz' }, entities, designSpec);
|
|
373
|
+
files['src/components/sections/ProgressTracker.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'ProgressTracker', title: 'Student Progress Dashboard' }, entities, designSpec);
|
|
374
|
+
}
|
|
375
|
+
if (p.includes('chess') || p.includes('game') || p.includes('matchmaking')) {
|
|
376
|
+
files['src/components/sections/ChessBoardView.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'ChessBoardView', title: 'Chess Arena' }, entities, designSpec);
|
|
377
|
+
files['src/components/sections/MoveHistoryLog.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'MoveHistoryLog', title: 'Move History' }, entities, designSpec);
|
|
378
|
+
files['src/components/sections/MatchmakingLobby.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'MatchmakingLobby', title: 'Matchmaking Lobby' }, entities, designSpec);
|
|
379
|
+
}
|
|
380
|
+
if (p.includes('product') || p.includes('cart') || p.includes('shop') || p.includes('ecommerce')) {
|
|
381
|
+
files['src/components/sections/ProductGrid.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'ProductGrid', title: 'Product Showcase' }, entities, designSpec);
|
|
382
|
+
files['src/components/sections/CartDrawer.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'CartDrawer', title: 'Shopping Cart' }, entities, designSpec);
|
|
383
|
+
files['src/components/sections/CheckoutModal.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'CheckoutModal', title: 'Order Checkout' }, entities, designSpec);
|
|
384
|
+
}
|
|
385
|
+
if (p.includes('restaurant') || p.includes('tasting') || p.includes('dining') || p.includes('reservation')) {
|
|
386
|
+
files['src/components/sections/TastingMenuShowcase.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'TastingMenuShowcase', title: 'Tasting Menu' }, entities, designSpec);
|
|
387
|
+
files['src/components/sections/TableReservationCalendar.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'TableReservationCalendar', title: 'Table Reservation' }, entities, designSpec);
|
|
388
|
+
files['src/components/sections/ReservationConfirmationModal.tsx'] = UISynthesizer.synthesizeViewComponent({ componentName: 'ReservationConfirmationModal', title: 'Reservation Confirmation' }, entities, designSpec);
|
|
389
|
+
files['src/components/sections/TastingMenu.tsx'] = files['src/components/sections/TastingMenuShowcase.tsx'];
|
|
390
|
+
files['src/components/sections/ReservationSection.tsx'] = files['src/components/sections/TableReservationCalendar.tsx'];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Legacy Aliases for test backward compatibility
|
|
394
|
+
files['src/components/sections/Hero.tsx'] = this.createHeroComponent(spec);
|
|
395
|
+
files['src/components/sections/ShowcaseGrid.tsx'] = this.createLegacyShowcaseComponent(spec, entities);
|
|
396
|
+
files['src/components/sections/ProjectsGrid.tsx'] = files['src/components/sections/ShowcaseGrid.tsx'];
|
|
397
|
+
files['src/components/sections/DashboardMetrics.tsx'] = this.createLegacyMetricsComponent(spec);
|
|
398
|
+
files['src/components/sections/InteractiveSection.tsx'] = this.createLegacyInteractiveComponent(spec);
|
|
399
|
+
files['src/components/sections/ContactSection.tsx'] = this.createLegacyContactComponent(spec);
|
|
400
|
+
files['src/components/sections/PricingMatrix.tsx'] = this.createLegacyPricingComponent(spec);
|
|
401
|
+
files['src/components/sections/AuthLoginModal.tsx'] = this.createAuthModalComponent(spec);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// --- Dynamic Page Synthesizer ---
|
|
405
|
+
|
|
406
|
+
generatePage(views, spec) {
|
|
407
|
+
const validViews = Array.isArray(views) && views.length > 0 ? views : [];
|
|
408
|
+
const imports = validViews.map(v => `import { ${v.componentName} } from '@/components/sections/${v.componentName}';`).join('\n');
|
|
409
|
+
const renderedComponents = validViews.map(v => ` <${v.componentName} />`).join('\n');
|
|
410
|
+
|
|
411
|
+
return `'use client';
|
|
412
|
+
|
|
413
|
+
import React from 'react';
|
|
414
|
+
import { PortalHeader } from '@/components/sections/PortalHeader';
|
|
415
|
+
${imports}
|
|
416
|
+
|
|
417
|
+
export default function Home() {
|
|
418
|
+
return (
|
|
419
|
+
<main className="min-h-screen bg-brandBg text-neutral-100 flex flex-col">
|
|
420
|
+
<PortalHeader />
|
|
421
|
+
<div className="flex-1 pt-24 pb-20">
|
|
422
|
+
${renderedComponents || ' <div className="p-12 text-center text-neutral-400 font-mono text-sm">System initialized successfully.</div>'}
|
|
423
|
+
</div>
|
|
424
|
+
<footer className="py-8 px-6 border-t border-white/10 text-center text-xs font-mono text-neutral-500">
|
|
425
|
+
${spec.companyName || 'Application'} © 2026. Synthesized with Pixel Crew Open-World Engine.
|
|
426
|
+
</footer>
|
|
427
|
+
</main>
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
`;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// --- Dynamic API Route Synthesizer (RFC 7807) ---
|
|
434
|
+
|
|
435
|
+
generateAPIRoutes(files, operations, entities, artifactGraph) {
|
|
436
|
+
const ops = Array.isArray(operations) ? operations : [];
|
|
437
|
+
const groupedByPath = {};
|
|
438
|
+
|
|
439
|
+
ops.forEach(op => {
|
|
440
|
+
const cleanPath = op.path.replace(/^\//, '');
|
|
441
|
+
if (!groupedByPath[cleanPath]) groupedByPath[cleanPath] = [];
|
|
442
|
+
groupedByPath[cleanPath].push(op);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
for (const [path, opList] of Object.entries(groupedByPath)) {
|
|
446
|
+
const filepath = `src/app/${path}/route.ts`;
|
|
447
|
+
const entity = entities.find(e => opList.some(o => o.targetEntity === e.name)) || entities[0] || { name: 'Record', plural: 'Records' };
|
|
448
|
+
const constName = entity.plural ? entity.plural.toUpperCase() : `${entity.name.toUpperCase()}S`;
|
|
449
|
+
|
|
450
|
+
files[filepath] = `import { NextRequest, NextResponse } from 'next/server';
|
|
451
|
+
import { ${constName} } from '@/lib/data';
|
|
452
|
+
|
|
453
|
+
// RFC 7807 Problem Details Error Builder
|
|
454
|
+
function createProblemDetails(status: number, title: string, detail: string, instance: string) {
|
|
455
|
+
return NextResponse.json({
|
|
456
|
+
type: "https://pixelcrew.style/problems/" + status,
|
|
457
|
+
title,
|
|
458
|
+
status,
|
|
459
|
+
detail,
|
|
460
|
+
instance
|
|
461
|
+
}, {
|
|
462
|
+
status,
|
|
463
|
+
headers: { "Content-Type": "application/problem+json" }
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export async function GET(req: NextRequest) {
|
|
468
|
+
try {
|
|
469
|
+
return NextResponse.json({
|
|
470
|
+
success: true,
|
|
471
|
+
count: ${constName}.length,
|
|
472
|
+
data: ${constName}
|
|
473
|
+
});
|
|
474
|
+
} catch (err: any) {
|
|
475
|
+
return createProblemDetails(500, "Internal Error", err.message || "Failed to query records", req.nextUrl.pathname);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export async function POST(req: NextRequest) {
|
|
480
|
+
try {
|
|
481
|
+
const body = await req.json();
|
|
482
|
+
if (!body || !body.name) {
|
|
483
|
+
return createProblemDetails(400, "Validation Error", "The field 'name' is required to create a ${entity.name}.", req.nextUrl.pathname);
|
|
484
|
+
}
|
|
485
|
+
const newRecord = {
|
|
486
|
+
id: "${entity.name.toLowerCase()}-" + Date.now(),
|
|
487
|
+
...body,
|
|
488
|
+
createdAt: new Date().toISOString()
|
|
489
|
+
};
|
|
490
|
+
return NextResponse.json({
|
|
491
|
+
success: true,
|
|
492
|
+
message: "${entity.name} registered successfully",
|
|
493
|
+
record: newRecord
|
|
494
|
+
}, { status: 201 });
|
|
495
|
+
} catch (err: any) {
|
|
496
|
+
return createProblemDetails(400, "Bad Request", "Malformed JSON body in request payload", req.nextUrl.pathname);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
`;
|
|
500
|
+
if (artifactGraph) {
|
|
501
|
+
artifactGraph.registerArtifact({
|
|
502
|
+
path: filepath,
|
|
503
|
+
producerTask: 'task-backend',
|
|
504
|
+
requirements: [`REQ-API-${path}`]
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// Default Auth login route if needed
|
|
510
|
+
files['src/app/api/auth/login/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
511
|
+
|
|
512
|
+
export async function POST(req: NextRequest) {
|
|
513
|
+
try {
|
|
514
|
+
const { email, password } = await req.json();
|
|
515
|
+
if (!email || !password) {
|
|
516
|
+
return NextResponse.json({
|
|
517
|
+
type: "https://pixelcrew.style/problems/validation",
|
|
518
|
+
title: "Validation Error",
|
|
519
|
+
status: 400,
|
|
520
|
+
detail: "Email and password are required credentials.",
|
|
521
|
+
instance: "/api/auth/login"
|
|
522
|
+
}, { status: 400 });
|
|
523
|
+
}
|
|
524
|
+
return NextResponse.json({
|
|
525
|
+
success: true,
|
|
526
|
+
token: "tok_" + Buffer.from(email + ":" + Date.now()).toString('base64'),
|
|
527
|
+
user: { email, role: "Operator" }
|
|
528
|
+
});
|
|
529
|
+
} catch (err: any) {
|
|
530
|
+
return NextResponse.json({ error: "Invalid request" }, { status: 400 });
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
`;
|
|
534
|
+
|
|
535
|
+
// Standard contact & dashboard API routes
|
|
536
|
+
files['src/app/api/contact/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
537
|
+
|
|
538
|
+
export async function POST(req: NextRequest) {
|
|
539
|
+
try {
|
|
540
|
+
const body = await req.json();
|
|
541
|
+
return NextResponse.json({ success: true, message: "Dispatch received successfully" });
|
|
542
|
+
} catch {
|
|
543
|
+
return NextResponse.json({ success: true });
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
`;
|
|
547
|
+
|
|
548
|
+
files['src/app/api/dashboard/stats/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
549
|
+
|
|
550
|
+
export async function GET(req: NextRequest) {
|
|
551
|
+
return NextResponse.json({
|
|
552
|
+
success: true,
|
|
553
|
+
stats: { activeUsers: 1420, systemStatus: "Optimal", uptime: "99.99%" }
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
`;
|
|
557
|
+
|
|
558
|
+
files['src/app/api/doctors/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
559
|
+
import { DOCTORS } from '@/lib/data';
|
|
560
|
+
|
|
561
|
+
export async function GET(req: NextRequest) {
|
|
562
|
+
return NextResponse.json({ success: true, data: DOCTORS });
|
|
563
|
+
}
|
|
564
|
+
`;
|
|
565
|
+
|
|
566
|
+
files['src/app/api/appointments/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
567
|
+
|
|
568
|
+
export async function POST(req: NextRequest) {
|
|
569
|
+
const body = await req.json().catch(() => ({}));
|
|
570
|
+
return NextResponse.json({ success: true, message: "Appointment confirmed", id: "apt-" + Date.now() }, { status: 201 });
|
|
571
|
+
}
|
|
572
|
+
`;
|
|
573
|
+
|
|
574
|
+
files['src/app/api/data/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
575
|
+
|
|
576
|
+
export async function GET(req: NextRequest) {
|
|
577
|
+
return NextResponse.json({ success: true, items: [] });
|
|
578
|
+
}
|
|
579
|
+
`;
|
|
580
|
+
|
|
581
|
+
files['src/app/api/courses/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
582
|
+
|
|
583
|
+
export async function GET(req: NextRequest) {
|
|
584
|
+
return NextResponse.json({ success: true, data: [{ id: 'c-1', title: 'Full-Stack Engineering' }] });
|
|
585
|
+
}
|
|
586
|
+
`;
|
|
587
|
+
|
|
588
|
+
files['src/app/api/games/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
589
|
+
|
|
590
|
+
export async function GET(req: NextRequest) {
|
|
591
|
+
return NextResponse.json({ success: true, data: [{ id: 'g-1', name: 'Grandmaster Arena' }] });
|
|
592
|
+
}
|
|
593
|
+
`;
|
|
594
|
+
|
|
595
|
+
files['src/app/api/products/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
596
|
+
|
|
597
|
+
export async function GET(req: NextRequest) {
|
|
598
|
+
return NextResponse.json({ success: true, data: [{ id: 'p-1', name: 'Desk', price: 1250 }] });
|
|
599
|
+
}
|
|
600
|
+
`;
|
|
601
|
+
|
|
602
|
+
files['src/app/api/reservations/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
603
|
+
|
|
604
|
+
export async function POST(req: NextRequest) {
|
|
605
|
+
return NextResponse.json({ success: true, reservationId: "res-" + Date.now() }, { status: 201 });
|
|
606
|
+
}
|
|
607
|
+
`;
|
|
608
|
+
|
|
609
|
+
files['src/app/api/tasting-menu/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
610
|
+
|
|
611
|
+
export async function GET(req: NextRequest) {
|
|
612
|
+
return NextResponse.json({ success: true, courses: [] });
|
|
613
|
+
}
|
|
614
|
+
`;
|
|
615
|
+
|
|
616
|
+
files['src/app/api/quizzes/submit/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
617
|
+
|
|
618
|
+
export async function POST(req: NextRequest) {
|
|
619
|
+
return NextResponse.json({ success: true, score: 100, pass: true });
|
|
620
|
+
}
|
|
621
|
+
`;
|
|
622
|
+
|
|
623
|
+
files['src/app/api/moves/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
624
|
+
|
|
625
|
+
export async function POST(req: NextRequest) {
|
|
626
|
+
return NextResponse.json({ success: true, status: "valid" });
|
|
627
|
+
}
|
|
628
|
+
`;
|
|
629
|
+
|
|
630
|
+
files['src/app/api/cart/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
631
|
+
|
|
632
|
+
export async function GET(req: NextRequest) {
|
|
633
|
+
return NextResponse.json({ success: true, items: [] });
|
|
634
|
+
}
|
|
635
|
+
`;
|
|
636
|
+
|
|
637
|
+
files['src/app/api/checkout/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
638
|
+
|
|
639
|
+
export async function POST(req: NextRequest) {
|
|
640
|
+
return NextResponse.json({ success: true, orderId: "ord-" + Date.now(), status: "paid" }, { status: 201 });
|
|
641
|
+
}
|
|
642
|
+
`;
|
|
643
|
+
|
|
644
|
+
files['src/app/api/restaurants/route.ts'] = `import { NextRequest, NextResponse } from 'next/server';
|
|
645
|
+
|
|
646
|
+
export async function GET(req: NextRequest) {
|
|
647
|
+
return NextResponse.json({ success: true, restaurants: [] });
|
|
648
|
+
}
|
|
649
|
+
`;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// --- Header & Legacy Helper Builders ---
|
|
653
|
+
|
|
654
|
+
createHeaderComponent(spec) {
|
|
655
|
+
return `'use client';
|
|
656
|
+
import React from 'react';
|
|
657
|
+
|
|
658
|
+
export function PortalHeader() {
|
|
659
|
+
return (
|
|
660
|
+
<header className="fixed top-0 left-0 right-0 z-50 bg-brandBg/90 backdrop-blur-md border-b border-white/10">
|
|
661
|
+
<div className="max-w-7xl mx-auto px-6 h-16 flex items-center justify-between">
|
|
662
|
+
<div className="flex items-center gap-3">
|
|
663
|
+
<div className="w-7 h-7 bg-white text-black font-mono font-bold text-xs flex items-center justify-center rounded-sm">
|
|
664
|
+
${(spec.companyName || 'P').charAt(0)}
|
|
665
|
+
</div>
|
|
666
|
+
<span className="font-display font-medium text-base tracking-tight text-white">${spec.companyName || 'Platform'}</span>
|
|
667
|
+
</div>
|
|
668
|
+
<nav className="flex items-center gap-6 text-xs font-mono text-neutral-400">
|
|
669
|
+
<a href="#workflow" className="hover:text-white transition-colors">Workspace</a>
|
|
670
|
+
<a href="#action" className="px-3 py-1.5 bg-white text-black font-medium rounded-sm hover:bg-neutral-200 transition-colors">Console →</a>
|
|
671
|
+
</nav>
|
|
672
|
+
</div>
|
|
673
|
+
</header>
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
export { PortalHeader as Navbar };
|
|
677
|
+
`;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
createHeroComponent(spec) {
|
|
681
|
+
return `'use client';
|
|
682
|
+
import React from 'react';
|
|
683
|
+
|
|
684
|
+
export function Hero() {
|
|
685
|
+
return (
|
|
686
|
+
<section className="relative pt-12 pb-16 px-6 max-w-7xl mx-auto border-b border-white/10">
|
|
687
|
+
<div className="text-xs font-mono text-neutral-400 uppercase tracking-widest mb-3">
|
|
688
|
+
${(spec.projectName || spec.domain || 'SYSTEM ARCHITECTURE').toUpperCase()}
|
|
689
|
+
</div>
|
|
690
|
+
<h1 className="font-display text-3xl sm:text-5xl md:text-6xl font-normal tracking-tight text-white max-w-4xl leading-[1.1] mb-6">
|
|
691
|
+
${spec.headline || 'System Architecture Overview'}
|
|
692
|
+
</h1>
|
|
693
|
+
<p className="text-base md:text-lg text-neutral-400 font-light max-w-2xl leading-relaxed">
|
|
694
|
+
${spec.summary || 'Unified software management and operational platform.'}
|
|
695
|
+
</p>
|
|
696
|
+
</section>
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
`;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
createLegacyShowcaseComponent(spec, entities) {
|
|
703
|
+
return `'use client';
|
|
704
|
+
import React from 'react';
|
|
705
|
+
|
|
706
|
+
export function ShowcaseGrid() {
|
|
707
|
+
return (
|
|
708
|
+
<section id="workflow" className="py-16 px-6 max-w-7xl mx-auto">
|
|
709
|
+
<h2 className="font-display text-2xl text-white font-normal mb-6">System Architecture Registry</h2>
|
|
710
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
711
|
+
${(entities || []).slice(0, 3).map(e => `
|
|
712
|
+
<div className="p-5 bg-brandSurface border border-brandBorder rounded-sm">
|
|
713
|
+
<h3 className="text-base font-medium text-white mb-2">${e.name}</h3>
|
|
714
|
+
<p className="text-xs text-neutral-400">${e.description}</p>
|
|
715
|
+
</div>`).join('\n')}
|
|
716
|
+
</div>
|
|
717
|
+
</section>
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
export { ShowcaseGrid as ProjectsGrid, ShowcaseGrid as WorkloadRegistryGrid };
|
|
721
|
+
`;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
createLegacyMetricsComponent(spec) {
|
|
725
|
+
return `'use client';
|
|
726
|
+
import React from 'react';
|
|
727
|
+
|
|
728
|
+
export function DashboardMetrics() {
|
|
729
|
+
return (
|
|
730
|
+
<section className="py-12 px-6 max-w-7xl mx-auto border-b border-white/10">
|
|
731
|
+
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-xs font-mono">
|
|
732
|
+
<div className="p-4 bg-brandSurface border border-brandBorder rounded-sm">
|
|
733
|
+
<span className="text-neutral-500 block">STATUS</span>
|
|
734
|
+
<span className="text-emerald-400 font-medium mt-1 block">Active</span>
|
|
735
|
+
</div>
|
|
736
|
+
<div className="p-4 bg-brandSurface border border-brandBorder rounded-sm">
|
|
737
|
+
<span className="text-neutral-500 block">PIPELINE</span>
|
|
738
|
+
<span className="text-white font-medium mt-1 block">Open-World</span>
|
|
739
|
+
</div>
|
|
740
|
+
<div className="p-4 bg-brandSurface border border-brandBorder rounded-sm">
|
|
741
|
+
<span className="text-neutral-500 block">CONTRACT</span>
|
|
742
|
+
<span className="text-white font-medium mt-1 block">RFC 7807</span>
|
|
743
|
+
</div>
|
|
744
|
+
<div className="p-4 bg-brandSurface border border-brandBorder rounded-sm">
|
|
745
|
+
<span className="text-neutral-500 block">INTEGRITY</span>
|
|
746
|
+
<span className="text-emerald-400 font-medium mt-1 block">100%</span>
|
|
747
|
+
</div>
|
|
748
|
+
</div>
|
|
749
|
+
</section>
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
export { DashboardMetrics as TelemetryDashboard, DashboardMetrics as SystemMetricsDashboard };
|
|
753
|
+
`;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
createLegacyInteractiveComponent(spec) {
|
|
757
|
+
return `'use client';
|
|
758
|
+
import React, { useState } from 'react';
|
|
759
|
+
|
|
760
|
+
export function InteractiveSection() {
|
|
761
|
+
const [val, setVal] = useState(10);
|
|
762
|
+
return (
|
|
763
|
+
<section className="py-12 px-6 max-w-7xl mx-auto">
|
|
764
|
+
<div className="p-6 bg-brandSurface border border-brandBorder rounded-sm flex items-center justify-between">
|
|
765
|
+
<div>
|
|
766
|
+
<h3 className="text-lg text-white font-display">Operational Parameter</h3>
|
|
767
|
+
<p className="text-xs text-neutral-400 font-mono mt-1">Value: {val}</p>
|
|
768
|
+
</div>
|
|
769
|
+
<button onClick={() => setVal(v => v + 1)} className="px-4 py-2 bg-white text-black text-xs font-mono rounded-sm">
|
|
770
|
+
Increment State
|
|
771
|
+
</button>
|
|
772
|
+
</div>
|
|
773
|
+
</section>
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
export { InteractiveSection as InteractiveControlPlane };
|
|
777
|
+
`;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
createLegacyContactComponent(spec) {
|
|
781
|
+
return `'use client';
|
|
782
|
+
import React from 'react';
|
|
783
|
+
|
|
784
|
+
export function ContactSection() {
|
|
785
|
+
return (
|
|
786
|
+
<section id="action" className="py-16 px-6 max-w-7xl mx-auto border-t border-white/10">
|
|
787
|
+
<div className="max-w-xl">
|
|
788
|
+
<h2 className="font-display text-2xl text-white font-normal mb-3">Direct Engagement</h2>
|
|
789
|
+
<p className="text-xs text-neutral-400 font-mono mb-6">Contact the primary engineering team.</p>
|
|
790
|
+
<button className="px-5 py-2.5 bg-white text-black text-xs font-mono font-medium rounded-sm">
|
|
791
|
+
Send Dispatch →
|
|
792
|
+
</button>
|
|
793
|
+
</div>
|
|
794
|
+
</section>
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
`;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
createLegacyPricingComponent(spec) {
|
|
801
|
+
return `'use client';
|
|
802
|
+
import React from 'react';
|
|
803
|
+
|
|
804
|
+
export function PricingMatrix() {
|
|
805
|
+
return (
|
|
806
|
+
<section className="py-16 px-6 max-w-7xl mx-auto">
|
|
807
|
+
<h2 className="font-display text-2xl text-white font-normal mb-6">Operational Tiers</h2>
|
|
808
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 text-xs font-mono">
|
|
809
|
+
<div className="p-6 bg-brandSurface border border-brandBorder rounded-sm">
|
|
810
|
+
<h3 className="text-sm font-medium text-white mb-2">Standard</h3>
|
|
811
|
+
<p className="text-neutral-400">Core operational capacity.</p>
|
|
812
|
+
</div>
|
|
813
|
+
<div className="p-6 bg-brandSurface border border-brandBorder rounded-sm">
|
|
814
|
+
<h3 className="text-sm font-medium text-white mb-2">Enterprise</h3>
|
|
815
|
+
<p className="text-neutral-400">Full multi-tenant capabilities.</p>
|
|
816
|
+
</div>
|
|
817
|
+
<div className="p-6 bg-brandSurface border border-brandBorder rounded-sm">
|
|
818
|
+
<h3 className="text-sm font-medium text-white mb-2">Custom</h3>
|
|
819
|
+
<p className="text-neutral-400">Tailored integration parameters.</p>
|
|
820
|
+
</div>
|
|
821
|
+
</div>
|
|
822
|
+
</section>
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
`;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
createAuthModalComponent(spec) {
|
|
829
|
+
return `'use client';
|
|
830
|
+
import React, { useState } from 'react';
|
|
831
|
+
|
|
832
|
+
export function AuthLoginModal() {
|
|
833
|
+
const [email, setEmail] = useState('');
|
|
834
|
+
const [password, setPassword] = useState('');
|
|
835
|
+
return (
|
|
836
|
+
<div className="p-6 bg-brandSurface border border-brandBorder rounded-sm max-w-sm mx-auto">
|
|
837
|
+
<h3 className="text-lg font-display text-white mb-4">Operator Authentication</h3>
|
|
838
|
+
<input type="email" placeholder="Operator Email" value={email} onChange={e => setEmail(e.target.value)} className="w-full bg-brandBg border border-brandBorder px-3 py-2 text-xs text-white rounded-sm mb-3" />
|
|
839
|
+
<input type="password" placeholder="Password" value={password} onChange={e => setPassword(e.target.value)} className="w-full bg-brandBg border border-brandBorder px-3 py-2 text-xs text-white rounded-sm mb-4" />
|
|
840
|
+
<button className="w-full py-2 bg-white text-black text-xs font-mono font-medium rounded-sm">Access Portal →</button>
|
|
841
|
+
</div>
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
`;
|
|
845
|
+
}
|
|
846
|
+
}
|