mycontext-cli 2.0.26 → 2.0.28
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 +36 -355
- package/dist/agents/implementations/CodeGenSubAgent.d.ts.map +1 -1
- package/dist/agents/implementations/CodeGenSubAgent.js +67 -14
- package/dist/agents/implementations/CodeGenSubAgent.js.map +1 -1
- package/dist/agents/implementations/DesignPipelineAgent.d.ts +80 -0
- package/dist/agents/implementations/DesignPipelineAgent.d.ts.map +1 -0
- package/dist/agents/implementations/DesignPipelineAgent.js +1406 -0
- package/dist/agents/implementations/DesignPipelineAgent.js.map +1 -0
- package/dist/agents/implementations/FeatureAssemblyAgent.d.ts +67 -0
- package/dist/agents/implementations/FeatureAssemblyAgent.d.ts.map +1 -0
- package/dist/agents/implementations/FeatureAssemblyAgent.js +564 -0
- package/dist/agents/implementations/FeatureAssemblyAgent.js.map +1 -0
- package/dist/agents/implementations/PromptConstructorAgent.d.ts +10 -0
- package/dist/agents/implementations/PromptConstructorAgent.d.ts.map +1 -1
- package/dist/agents/implementations/PromptConstructorAgent.js +172 -12
- package/dist/agents/implementations/PromptConstructorAgent.js.map +1 -1
- package/dist/agents/implementations/RoleBasedGenerator.d.ts +52 -0
- package/dist/agents/implementations/RoleBasedGenerator.d.ts.map +1 -0
- package/dist/agents/implementations/RoleBasedGenerator.js +370 -0
- package/dist/agents/implementations/RoleBasedGenerator.js.map +1 -0
- package/dist/cli.js +65 -0
- package/dist/cli.js.map +1 -1
- package/dist/clients/ClaudeSDKClient.d.ts +48 -0
- package/dist/clients/ClaudeSDKClient.d.ts.map +1 -0
- package/dist/clients/ClaudeSDKClient.js +158 -0
- package/dist/clients/ClaudeSDKClient.js.map +1 -0
- package/dist/clients/MyContextAIClient.d.ts +73 -0
- package/dist/clients/MyContextAIClient.d.ts.map +1 -0
- package/dist/clients/MyContextAIClient.js +280 -0
- package/dist/clients/MyContextAIClient.js.map +1 -0
- package/dist/clients/ProviderChain.d.ts +87 -0
- package/dist/clients/ProviderChain.d.ts.map +1 -0
- package/dist/clients/ProviderChain.js +246 -0
- package/dist/clients/ProviderChain.js.map +1 -0
- package/dist/clients/XAIClient.d.ts +48 -0
- package/dist/clients/XAIClient.d.ts.map +1 -0
- package/dist/clients/XAIClient.js +152 -0
- package/dist/clients/XAIClient.js.map +1 -0
- package/dist/commands/assemble-features.d.ts +40 -0
- package/dist/commands/assemble-features.d.ts.map +1 -0
- package/dist/commands/assemble-features.js +383 -0
- package/dist/commands/assemble-features.js.map +1 -0
- package/dist/commands/clone-starter.d.ts +32 -0
- package/dist/commands/clone-starter.d.ts.map +1 -0
- package/dist/commands/clone-starter.js +218 -0
- package/dist/commands/clone-starter.js.map +1 -0
- package/dist/commands/design-analyze.d.ts +46 -0
- package/dist/commands/design-analyze.d.ts.map +1 -0
- package/dist/commands/design-analyze.js +232 -0
- package/dist/commands/design-analyze.js.map +1 -0
- package/dist/commands/generate-components.d.ts +1 -0
- package/dist/commands/generate-components.d.ts.map +1 -1
- package/dist/commands/generate-components.js +42 -9
- package/dist/commands/generate-components.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +34 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/setup-complete.d.ts.map +1 -1
- package/dist/commands/setup-complete.js +38 -2
- package/dist/commands/setup-complete.js.map +1 -1
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +86 -7
- package/dist/commands/workflow.js.map +1 -1
- package/dist/config/intent-dictionary.json +3700 -0
- package/dist/package.json +3 -1
- package/dist/services/IntentEnricher.d.ts +61 -0
- package/dist/services/IntentEnricher.d.ts.map +1 -0
- package/dist/services/IntentEnricher.js +318 -0
- package/dist/services/IntentEnricher.js.map +1 -0
- package/dist/services/IntentValidator.d.ts +114 -0
- package/dist/services/IntentValidator.d.ts.map +1 -0
- package/dist/services/IntentValidator.js +680 -0
- package/dist/services/IntentValidator.js.map +1 -0
- package/dist/types/design-pipeline.d.ts +300 -0
- package/dist/types/design-pipeline.d.ts.map +1 -0
- package/dist/types/design-pipeline.js +9 -0
- package/dist/types/design-pipeline.js.map +1 -0
- package/dist/types/feature-bundle.d.ts +239 -0
- package/dist/types/feature-bundle.d.ts.map +1 -0
- package/dist/types/feature-bundle.js +9 -0
- package/dist/types/feature-bundle.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/intent-dictionary.d.ts +525 -0
- package/dist/types/intent-dictionary.d.ts.map +1 -0
- package/dist/types/intent-dictionary.js +11 -0
- package/dist/types/intent-dictionary.js.map +1 -0
- package/dist/types/role-permissions.d.ts +167 -0
- package/dist/types/role-permissions.d.ts.map +1 -0
- package/dist/types/role-permissions.js +9 -0
- package/dist/types/role-permissions.js.map +1 -0
- package/dist/utils/contextEnricher.d.ts +41 -0
- package/dist/utils/contextEnricher.d.ts.map +1 -0
- package/dist/utils/contextEnricher.js +327 -0
- package/dist/utils/contextEnricher.js.map +1 -0
- package/dist/utils/designFallbacks.d.ts +48 -0
- package/dist/utils/designFallbacks.d.ts.map +1 -0
- package/dist/utils/designFallbacks.js +885 -0
- package/dist/utils/designFallbacks.js.map +1 -0
- package/dist/utils/designManifestManager.d.ts +89 -0
- package/dist/utils/designManifestManager.d.ts.map +1 -0
- package/dist/utils/designManifestManager.js +533 -0
- package/dist/utils/designManifestManager.js.map +1 -0
- package/dist/utils/designPipelineStateManager.d.ts +63 -0
- package/dist/utils/designPipelineStateManager.d.ts.map +1 -0
- package/dist/utils/designPipelineStateManager.js +174 -0
- package/dist/utils/designPipelineStateManager.js.map +1 -0
- package/dist/utils/envExampleGenerator.d.ts.map +1 -1
- package/dist/utils/envExampleGenerator.js +35 -171
- package/dist/utils/envExampleGenerator.js.map +1 -1
- package/dist/utils/featureBundleManager.d.ts +90 -0
- package/dist/utils/featureBundleManager.d.ts.map +1 -0
- package/dist/utils/featureBundleManager.js +340 -0
- package/dist/utils/featureBundleManager.js.map +1 -0
- package/dist/utils/githubCloner.d.ts +93 -0
- package/dist/utils/githubCloner.d.ts.map +1 -0
- package/dist/utils/githubCloner.js +305 -0
- package/dist/utils/githubCloner.js.map +1 -0
- package/dist/utils/rolePermissionMapper.d.ts +89 -0
- package/dist/utils/rolePermissionMapper.d.ts.map +1 -0
- package/dist/utils/rolePermissionMapper.js +337 -0
- package/dist/utils/rolePermissionMapper.js.map +1 -0
- package/dist/utils/unifiedDesignContextLoader.d.ts +76 -0
- package/dist/utils/unifiedDesignContextLoader.d.ts.map +1 -0
- package/dist/utils/unifiedDesignContextLoader.js +344 -0
- package/dist/utils/unifiedDesignContextLoader.js.map +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,1406 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DesignPipelineAgent = void 0;
|
|
7
|
+
const hybridAIClient_1 = require("../../utils/hybridAIClient");
|
|
8
|
+
const fileSystem_1 = require("../../utils/fileSystem");
|
|
9
|
+
const designPipelineStateManager_1 = require("../../utils/designPipelineStateManager");
|
|
10
|
+
const IntentValidator_1 = require("../../services/IntentValidator");
|
|
11
|
+
const IntentEnricher_1 = require("../../services/IntentEnricher");
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
/**
|
|
14
|
+
* DesignPipelineAgent
|
|
15
|
+
*
|
|
16
|
+
* Implements an 8-phase design reasoning pipeline as a SubAgent.
|
|
17
|
+
* Each phase has AI generation with rule-based fallbacks for model-agnostic reliability.
|
|
18
|
+
*/
|
|
19
|
+
class DesignPipelineAgent {
|
|
20
|
+
constructor(projectPath = process.cwd()) {
|
|
21
|
+
this.name = "DesignPipelineAgent";
|
|
22
|
+
this.description = "RICH design reasoning pipeline that generates rich visual context for component generation";
|
|
23
|
+
this.personality = "methodical, design-focused, context-aware, systematic";
|
|
24
|
+
this.llmProvider = "hybrid";
|
|
25
|
+
this.expertise = [
|
|
26
|
+
"design system creation",
|
|
27
|
+
"visual reasoning",
|
|
28
|
+
"user experience analysis",
|
|
29
|
+
"component architecture",
|
|
30
|
+
"design token generation",
|
|
31
|
+
"aesthetic synthesis",
|
|
32
|
+
];
|
|
33
|
+
this.fallbacks = new Map();
|
|
34
|
+
this.ai = new hybridAIClient_1.HybridAIClient();
|
|
35
|
+
this.fs = new fileSystem_1.FileSystemManager();
|
|
36
|
+
this.stateManager = new designPipelineStateManager_1.DesignPipelineStateManager(projectPath);
|
|
37
|
+
this.initializeFallbacks();
|
|
38
|
+
}
|
|
39
|
+
async run(input, resumeFromState = false) {
|
|
40
|
+
console.log(chalk_1.default.blue("🎨 Starting mycontext Design Pipeline..."));
|
|
41
|
+
const startTime = Date.now();
|
|
42
|
+
const warnings = [];
|
|
43
|
+
const errors = [];
|
|
44
|
+
const fallbacksUsed = [];
|
|
45
|
+
// Load existing state if resuming
|
|
46
|
+
let existingState = null;
|
|
47
|
+
let completedPhases = [];
|
|
48
|
+
let partialResults = {};
|
|
49
|
+
if (resumeFromState) {
|
|
50
|
+
existingState = await this.stateManager.loadState();
|
|
51
|
+
if (existingState) {
|
|
52
|
+
completedPhases = existingState.completedPhases;
|
|
53
|
+
partialResults = existingState.partialResults;
|
|
54
|
+
console.log(chalk_1.default.blue(`🔄 Resuming from Phase ${existingState.failedPhase || existingState.currentPhase}...`));
|
|
55
|
+
console.log(chalk_1.default.gray(` Completed phases: ${completedPhases.join(", ")}`));
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.log(chalk_1.default.yellow("⚠️ No resumable state found, starting fresh"));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
// Phase 1: Parse PRD into Functional Summary
|
|
63
|
+
if (!completedPhases.includes(1)) {
|
|
64
|
+
console.log(chalk_1.default.gray(" Phase 1: Parsing PRD..."));
|
|
65
|
+
const functionalSummary = await this.executePhaseWithErrorHandling(1, () => this.parsePRD(input.prd, input.project_path), partialResults);
|
|
66
|
+
partialResults.functionalSummary = functionalSummary;
|
|
67
|
+
completedPhases.push(1);
|
|
68
|
+
await this.saveProgress(1, completedPhases, partialResults);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.log(chalk_1.default.gray(" Phase 1: Using cached result..."));
|
|
72
|
+
partialResults.functionalSummary = partialResults.functionalSummary;
|
|
73
|
+
}
|
|
74
|
+
// Phase 2: Classify Project Scope
|
|
75
|
+
if (!completedPhases.includes(2)) {
|
|
76
|
+
console.log(chalk_1.default.gray(" Phase 2: Classifying scope..."));
|
|
77
|
+
const projectScope = await this.executePhaseWithErrorHandling(2, () => this.classifyScope(partialResults.functionalSummary), partialResults);
|
|
78
|
+
partialResults.projectScope = projectScope;
|
|
79
|
+
completedPhases.push(2);
|
|
80
|
+
await this.saveProgress(2, completedPhases, partialResults);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.log(chalk_1.default.gray(" Phase 2: Using cached result..."));
|
|
84
|
+
partialResults.projectScope = partialResults.projectScope;
|
|
85
|
+
}
|
|
86
|
+
// Phase 3: Detect Missing Context
|
|
87
|
+
if (!completedPhases.includes(3)) {
|
|
88
|
+
console.log(chalk_1.default.gray(" Phase 3: Detecting context gaps..."));
|
|
89
|
+
const contextGaps = await this.executePhaseWithErrorHandling(3, () => this.detectGaps(input, partialResults.functionalSummary), partialResults);
|
|
90
|
+
partialResults.contextGaps = contextGaps;
|
|
91
|
+
completedPhases.push(3);
|
|
92
|
+
await this.saveProgress(3, completedPhases, partialResults);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
console.log(chalk_1.default.gray(" Phase 3: Using cached result..."));
|
|
96
|
+
partialResults.contextGaps = partialResults.contextGaps;
|
|
97
|
+
}
|
|
98
|
+
// Phase 3.5: Validate & Enrich UI Intents (NEW)
|
|
99
|
+
if (!completedPhases.includes(3.5)) {
|
|
100
|
+
console.log(chalk_1.default.gray(" Phase 3.5: Validating UI intents..."));
|
|
101
|
+
const intentValidation = await this.executePhaseWithErrorHandling(3.5, () => this.validateIntents(input, partialResults.functionalSummary), partialResults);
|
|
102
|
+
partialResults.intentValidation = intentValidation;
|
|
103
|
+
completedPhases.push(3.5);
|
|
104
|
+
await this.saveProgress(3.5, completedPhases, partialResults);
|
|
105
|
+
// If confidence is too low, prompt for clarifications
|
|
106
|
+
if (intentValidation.confidence_score < 0.7) {
|
|
107
|
+
console.log(chalk_1.default.yellow(`⚠️ Low confidence (${(intentValidation.confidence_score * 100).toFixed(0)}%) - some intents may need clarification`));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
console.log(chalk_1.default.gray(" Phase 3.5: Using cached result..."));
|
|
112
|
+
partialResults.intentValidation = partialResults.intentValidation;
|
|
113
|
+
}
|
|
114
|
+
// Phase 4: Generate Design Brief
|
|
115
|
+
if (!completedPhases.includes(4)) {
|
|
116
|
+
console.log(chalk_1.default.gray(" Phase 4: Creating design brief..."));
|
|
117
|
+
const designBrief = await this.executePhaseWithErrorHandling(4, () => this.generateDesignBrief(partialResults.functionalSummary, partialResults.contextGaps), partialResults);
|
|
118
|
+
partialResults.designBrief = designBrief;
|
|
119
|
+
completedPhases.push(4);
|
|
120
|
+
await this.saveProgress(4, completedPhases, partialResults);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
console.log(chalk_1.default.gray(" Phase 4: Using cached result..."));
|
|
124
|
+
partialResults.designBrief = partialResults.designBrief;
|
|
125
|
+
}
|
|
126
|
+
// Phase 5: Build Visual System
|
|
127
|
+
if (!completedPhases.includes(5)) {
|
|
128
|
+
console.log(chalk_1.default.gray(" Phase 5: Building visual system..."));
|
|
129
|
+
const visualSystem = await this.executePhaseWithErrorHandling(5, () => this.buildVisualSystem(partialResults.designBrief, partialResults.functionalSummary), partialResults);
|
|
130
|
+
partialResults.visualSystem = visualSystem;
|
|
131
|
+
completedPhases.push(5);
|
|
132
|
+
await this.saveProgress(5, completedPhases, partialResults);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
console.log(chalk_1.default.gray(" Phase 5: Using cached result..."));
|
|
136
|
+
partialResults.visualSystem = partialResults.visualSystem;
|
|
137
|
+
}
|
|
138
|
+
// Phase 6: Define Component Hierarchy
|
|
139
|
+
if (!completedPhases.includes(6)) {
|
|
140
|
+
console.log(chalk_1.default.gray(" Phase 6: Defining component hierarchy..."));
|
|
141
|
+
const componentHierarchy = await this.executePhaseWithErrorHandling(6, () => this.defineHierarchy(partialResults.functionalSummary, partialResults.designBrief, partialResults.intentValidation?.enriched_intents), partialResults);
|
|
142
|
+
partialResults.componentHierarchy = componentHierarchy;
|
|
143
|
+
completedPhases.push(6);
|
|
144
|
+
await this.saveProgress(6, completedPhases, partialResults);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
console.log(chalk_1.default.gray(" Phase 6: Using cached result..."));
|
|
148
|
+
partialResults.componentHierarchy = partialResults.componentHierarchy;
|
|
149
|
+
}
|
|
150
|
+
// Phase 7: Plan Implementation
|
|
151
|
+
if (!completedPhases.includes(7)) {
|
|
152
|
+
console.log(chalk_1.default.gray(" Phase 7: Planning implementation..."));
|
|
153
|
+
const implementationPlan = await this.executePhaseWithErrorHandling(7, () => this.planImplementation(partialResults.functionalSummary, partialResults.componentHierarchy), partialResults);
|
|
154
|
+
partialResults.implementationPlan = implementationPlan;
|
|
155
|
+
completedPhases.push(7);
|
|
156
|
+
await this.saveProgress(7, completedPhases, partialResults);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
console.log(chalk_1.default.gray(" Phase 7: Using cached result..."));
|
|
160
|
+
partialResults.implementationPlan = partialResults.implementationPlan;
|
|
161
|
+
}
|
|
162
|
+
// Phase 8: Synthesize Design Intent
|
|
163
|
+
if (!completedPhases.includes(8)) {
|
|
164
|
+
console.log(chalk_1.default.gray(" Phase 8: Synthesizing design intent..."));
|
|
165
|
+
const designIntent = await this.executePhaseWithErrorHandling(8, () => this.synthesizeIntent(partialResults.designBrief, partialResults.visualSystem, partialResults.functionalSummary), partialResults);
|
|
166
|
+
partialResults.designIntent = designIntent;
|
|
167
|
+
completedPhases.push(8);
|
|
168
|
+
await this.saveProgress(8, completedPhases, partialResults);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
console.log(chalk_1.default.gray(" Phase 8: Using cached result..."));
|
|
172
|
+
partialResults.designIntent = partialResults.designIntent;
|
|
173
|
+
}
|
|
174
|
+
// Create complete manifest
|
|
175
|
+
const manifest = {
|
|
176
|
+
version: "1.0.0",
|
|
177
|
+
generated_at: new Date().toISOString(),
|
|
178
|
+
project_name: partialResults.functionalSummary.app_name,
|
|
179
|
+
phases: {
|
|
180
|
+
functional_summary: partialResults.functionalSummary,
|
|
181
|
+
project_scope: partialResults.projectScope,
|
|
182
|
+
context_gaps: partialResults.contextGaps,
|
|
183
|
+
design_brief: partialResults.designBrief,
|
|
184
|
+
visual_system: partialResults.visualSystem,
|
|
185
|
+
component_hierarchy: partialResults.componentHierarchy,
|
|
186
|
+
implementation_plan: partialResults.implementationPlan,
|
|
187
|
+
design_intent: partialResults.designIntent,
|
|
188
|
+
},
|
|
189
|
+
metadata: {
|
|
190
|
+
ai_model_used: "hybrid",
|
|
191
|
+
confidence_scores: this.calculateConfidenceScores(),
|
|
192
|
+
fallbacks_used: fallbacksUsed,
|
|
193
|
+
generation_time_ms: Date.now() - startTime,
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
// Clear state file on successful completion
|
|
197
|
+
await this.stateManager.clearState();
|
|
198
|
+
console.log(chalk_1.default.green("✅ Design pipeline completed successfully"));
|
|
199
|
+
console.log(chalk_1.default.gray(` Generated in ${Date.now() - startTime}ms`));
|
|
200
|
+
console.log(chalk_1.default.gray(` Design anchors: ${partialResults.designIntent.design_anchors.join(", ")}`));
|
|
201
|
+
return {
|
|
202
|
+
manifest,
|
|
203
|
+
success: true,
|
|
204
|
+
warnings,
|
|
205
|
+
errors,
|
|
206
|
+
fallbacks_used: fallbacksUsed,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
console.error(chalk_1.default.red("❌ Design pipeline failed:"), error);
|
|
211
|
+
return {
|
|
212
|
+
manifest: this.createEmptyManifest(input.project_path),
|
|
213
|
+
success: false,
|
|
214
|
+
warnings,
|
|
215
|
+
errors: [
|
|
216
|
+
...errors,
|
|
217
|
+
error instanceof Error ? error.message : String(error),
|
|
218
|
+
],
|
|
219
|
+
fallbacks_used: fallbacksUsed,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// ERROR HANDLING AND STATE MANAGEMENT
|
|
225
|
+
// ============================================================================
|
|
226
|
+
/**
|
|
227
|
+
* Execute a phase with comprehensive error handling
|
|
228
|
+
*/
|
|
229
|
+
async executePhaseWithErrorHandling(phaseNumber, phaseFunction, partialResults) {
|
|
230
|
+
try {
|
|
231
|
+
return await phaseFunction();
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
const failureType = this.detectFailureType(error);
|
|
235
|
+
// Save failure state
|
|
236
|
+
await this.stateManager.saveState({
|
|
237
|
+
currentPhase: phaseNumber,
|
|
238
|
+
completedPhases: Object.keys(partialResults).map(() => phaseNumber - 1),
|
|
239
|
+
failedPhase: phaseNumber,
|
|
240
|
+
failureReason: failureType,
|
|
241
|
+
partialResults,
|
|
242
|
+
projectPath: process.cwd(),
|
|
243
|
+
timestamp: new Date(),
|
|
244
|
+
});
|
|
245
|
+
// Show comprehensive guidance
|
|
246
|
+
this.showRecoveryGuidance(phaseNumber, failureType);
|
|
247
|
+
// Throw to stop execution
|
|
248
|
+
throw new Error(`Pipeline halted at Phase ${phaseNumber}: ${failureType}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Save progress after each successful phase
|
|
253
|
+
*/
|
|
254
|
+
async saveProgress(currentPhase, completedPhases, partialResults) {
|
|
255
|
+
await this.stateManager.saveState({
|
|
256
|
+
currentPhase: currentPhase + 1,
|
|
257
|
+
completedPhases,
|
|
258
|
+
partialResults,
|
|
259
|
+
projectPath: process.cwd(),
|
|
260
|
+
timestamp: new Date(),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Detect the type of failure from error
|
|
265
|
+
*/
|
|
266
|
+
detectFailureType(error) {
|
|
267
|
+
const errorMessage = error?.message?.toLowerCase() || "";
|
|
268
|
+
const errorCode = error?.status || error?.code;
|
|
269
|
+
if (errorCode === 429 || errorMessage.includes("rate limit")) {
|
|
270
|
+
return "Rate limit exceeded";
|
|
271
|
+
}
|
|
272
|
+
else if (errorMessage.includes("timeout") || errorCode === "TIMEOUT") {
|
|
273
|
+
return "Request timeout";
|
|
274
|
+
}
|
|
275
|
+
else if (errorCode === 401 ||
|
|
276
|
+
errorCode === 403 ||
|
|
277
|
+
errorMessage.includes("invalid key") ||
|
|
278
|
+
errorMessage.includes("unauthorized")) {
|
|
279
|
+
return "API key error";
|
|
280
|
+
}
|
|
281
|
+
else if (errorMessage.includes("network") ||
|
|
282
|
+
errorMessage.includes("connection")) {
|
|
283
|
+
return "Network error";
|
|
284
|
+
}
|
|
285
|
+
else if (errorMessage.includes("quota") ||
|
|
286
|
+
errorMessage.includes("limit")) {
|
|
287
|
+
return "Quota exceeded";
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
return "Unknown error";
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Show comprehensive recovery guidance
|
|
295
|
+
*/
|
|
296
|
+
showRecoveryGuidance(failedPhase, failureType) {
|
|
297
|
+
console.log(chalk_1.default.red("\n❌ Design Pipeline Halted"));
|
|
298
|
+
console.log(chalk_1.default.yellow(`\n⚠️ Phase ${failedPhase} failed: ${failureType}`));
|
|
299
|
+
// Show completed phases
|
|
300
|
+
console.log(chalk_1.default.green("\n✅ Completed Phases:"));
|
|
301
|
+
for (let i = 1; i < failedPhase; i++) {
|
|
302
|
+
console.log(chalk_1.default.gray(` Phase ${i}: ${this.getPhaseName(i)}`));
|
|
303
|
+
}
|
|
304
|
+
// Show failure-specific guidance
|
|
305
|
+
if (failureType.includes("Rate limit")) {
|
|
306
|
+
console.log(chalk_1.default.blue("\n🕐 Rate Limit Detected:"));
|
|
307
|
+
console.log(chalk_1.default.gray(" • Wait 60-120 seconds for rate limits to reset"));
|
|
308
|
+
console.log(chalk_1.default.gray(" • Or switch to a different AI provider"));
|
|
309
|
+
console.log(chalk_1.default.gray(" • Check your API usage limits"));
|
|
310
|
+
}
|
|
311
|
+
else if (failureType.includes("timeout")) {
|
|
312
|
+
console.log(chalk_1.default.blue("\n⏱️ Timeout Detected:"));
|
|
313
|
+
console.log(chalk_1.default.gray(" • The request took too long to complete"));
|
|
314
|
+
console.log(chalk_1.default.gray(" • Try again with a different AI provider"));
|
|
315
|
+
console.log(chalk_1.default.gray(" • Check your internet connection"));
|
|
316
|
+
}
|
|
317
|
+
else if (failureType.includes("API key")) {
|
|
318
|
+
console.log(chalk_1.default.blue("\n🔑 API Key Error:"));
|
|
319
|
+
console.log(chalk_1.default.gray(" • Check your API key configuration"));
|
|
320
|
+
console.log(chalk_1.default.gray(" • Verify the key has sufficient permissions"));
|
|
321
|
+
console.log(chalk_1.default.gray(" • Try a different AI provider"));
|
|
322
|
+
}
|
|
323
|
+
else if (failureType.includes("Network")) {
|
|
324
|
+
console.log(chalk_1.default.blue("\n🌐 Network Error:"));
|
|
325
|
+
console.log(chalk_1.default.gray(" • Check your internet connection"));
|
|
326
|
+
console.log(chalk_1.default.gray(" • Try again in a few moments"));
|
|
327
|
+
console.log(chalk_1.default.gray(" • Verify your network settings"));
|
|
328
|
+
}
|
|
329
|
+
else if (failureType.includes("Quota")) {
|
|
330
|
+
console.log(chalk_1.default.blue("\n📊 Quota Exceeded:"));
|
|
331
|
+
console.log(chalk_1.default.gray(" • You have exceeded your API quota"));
|
|
332
|
+
console.log(chalk_1.default.gray(" • Wait for quota reset or upgrade your plan"));
|
|
333
|
+
console.log(chalk_1.default.gray(" • Try a different AI provider"));
|
|
334
|
+
}
|
|
335
|
+
// Show resume command
|
|
336
|
+
console.log(chalk_1.default.blue("\n🔄 To Resume:"));
|
|
337
|
+
console.log(chalk_1.default.white(" mycontext design analyze --resume"));
|
|
338
|
+
// Show alternative options
|
|
339
|
+
console.log(chalk_1.default.blue("\n🔧 Alternative Options:"));
|
|
340
|
+
console.log(chalk_1.default.gray(" 1. Switch AI provider: Set XAI_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY"));
|
|
341
|
+
console.log(chalk_1.default.gray(" 2. Start fresh: mycontext design analyze --regenerate"));
|
|
342
|
+
console.log(chalk_1.default.gray(" 3. Check status: mycontext design summary"));
|
|
343
|
+
console.log(chalk_1.default.gray(" 4. View state: mycontext design validate"));
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Get human-readable phase name
|
|
347
|
+
*/
|
|
348
|
+
getPhaseName(phaseNumber) {
|
|
349
|
+
const phaseNames = {
|
|
350
|
+
1: "Parse PRD",
|
|
351
|
+
2: "Classify Scope",
|
|
352
|
+
3: "Detect Context Gaps",
|
|
353
|
+
4: "Create Design Brief",
|
|
354
|
+
5: "Build Visual System",
|
|
355
|
+
6: "Define Component Hierarchy",
|
|
356
|
+
7: "Plan Implementation",
|
|
357
|
+
8: "Synthesize Design Intent",
|
|
358
|
+
};
|
|
359
|
+
return (phaseNames[phaseNumber] ||
|
|
360
|
+
`Phase ${phaseNumber}`);
|
|
361
|
+
}
|
|
362
|
+
// ============================================================================
|
|
363
|
+
// PHASE 1: PRD PARSING
|
|
364
|
+
// ============================================================================
|
|
365
|
+
async parsePRD(prd, projectPath) {
|
|
366
|
+
const prompt = `
|
|
367
|
+
You are a product analyst. Parse this PRD into a structured functional summary.
|
|
368
|
+
|
|
369
|
+
PRD:
|
|
370
|
+
${prd}
|
|
371
|
+
|
|
372
|
+
Output JSON with this exact structure:
|
|
373
|
+
{
|
|
374
|
+
"app_name": "string",
|
|
375
|
+
"core_purpose": "string",
|
|
376
|
+
"key_features": ["feature1", "feature2"],
|
|
377
|
+
"primary_user_actions": ["action1", "action2"],
|
|
378
|
+
"platform": "string",
|
|
379
|
+
"technical_requirements": ["req1", "req2"],
|
|
380
|
+
"complexity_level": "low|medium|high",
|
|
381
|
+
"user_personas": ["persona1", "persona2"],
|
|
382
|
+
"business_goals": ["goal1", "goal2"],
|
|
383
|
+
"success_metrics": ["metric1", "metric2"]
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
Focus on extracting the core essence and user value proposition.`;
|
|
387
|
+
try {
|
|
388
|
+
const response = await this.ai.generateText(prompt, {
|
|
389
|
+
temperature: 0.3,
|
|
390
|
+
maxTokens: 1000,
|
|
391
|
+
});
|
|
392
|
+
const parsed = JSON.parse(response.text);
|
|
393
|
+
return this.validateFunctionalSummary(parsed);
|
|
394
|
+
}
|
|
395
|
+
catch (error) {
|
|
396
|
+
console.log(chalk_1.default.yellow(" ⚠️ AI parsing failed, using rule-based extraction"));
|
|
397
|
+
return this.extractFunctionalSummaryFromPRD(prd);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
extractFunctionalSummaryFromPRD(prd) {
|
|
401
|
+
// Rule-based extraction as fallback
|
|
402
|
+
const lines = prd.split("\n");
|
|
403
|
+
const appName = this.extractAppName(prd);
|
|
404
|
+
const features = this.extractFeatures(prd);
|
|
405
|
+
const purpose = this.extractPurpose(prd);
|
|
406
|
+
return {
|
|
407
|
+
app_name: appName,
|
|
408
|
+
core_purpose: purpose,
|
|
409
|
+
key_features: features,
|
|
410
|
+
primary_user_actions: this.extractUserActions(prd),
|
|
411
|
+
platform: this.inferPlatform(prd),
|
|
412
|
+
technical_requirements: this.extractTechnicalRequirements(prd),
|
|
413
|
+
complexity_level: this.assessComplexity(features.length),
|
|
414
|
+
user_personas: this.extractPersonas(prd),
|
|
415
|
+
business_goals: this.extractBusinessGoals(prd),
|
|
416
|
+
success_metrics: this.extractSuccessMetrics(prd),
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
// ============================================================================
|
|
420
|
+
// PHASE 2: SCOPE CLASSIFICATION
|
|
421
|
+
// ============================================================================
|
|
422
|
+
async classifyScope(summary) {
|
|
423
|
+
const prompt = `
|
|
424
|
+
Classify this project's build scope based on the functional summary.
|
|
425
|
+
|
|
426
|
+
Summary: ${JSON.stringify(summary, null, 2)}
|
|
427
|
+
|
|
428
|
+
Options:
|
|
429
|
+
- single_component: One reusable component
|
|
430
|
+
- ui_page: Single page/screen with multiple components
|
|
431
|
+
- full_app: Multi-screen application
|
|
432
|
+
|
|
433
|
+
Return JSON:
|
|
434
|
+
{
|
|
435
|
+
"build_scope": "single_component|ui_page|full_app",
|
|
436
|
+
"reason": "explanation",
|
|
437
|
+
"expected_outputs": ["wireframes", "design tokens", "app structure"],
|
|
438
|
+
"estimated_screens": number,
|
|
439
|
+
"estimated_components": number,
|
|
440
|
+
"development_phases": ["phase1", "phase2"],
|
|
441
|
+
"technical_complexity": "simple|moderate|complex"
|
|
442
|
+
}`;
|
|
443
|
+
try {
|
|
444
|
+
const response = await this.ai.generateText(prompt, {
|
|
445
|
+
temperature: 0.2,
|
|
446
|
+
maxTokens: 500,
|
|
447
|
+
});
|
|
448
|
+
return JSON.parse(response.text);
|
|
449
|
+
}
|
|
450
|
+
catch (error) {
|
|
451
|
+
return this.classifyScopeByRules(summary);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
classifyScopeByRules(summary) {
|
|
455
|
+
const featureCount = summary.key_features.length;
|
|
456
|
+
const hasMultipleScreens = summary.primary_user_actions.length > 3;
|
|
457
|
+
let buildScope;
|
|
458
|
+
if (featureCount <= 2 && !hasMultipleScreens) {
|
|
459
|
+
buildScope = "single_component";
|
|
460
|
+
}
|
|
461
|
+
else if (featureCount <= 5 && summary.complexity_level !== "high") {
|
|
462
|
+
buildScope = "ui_page";
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
buildScope = "full_app";
|
|
466
|
+
}
|
|
467
|
+
return {
|
|
468
|
+
build_scope: buildScope,
|
|
469
|
+
reason: `Based on ${featureCount} features and ${summary.complexity_level} complexity`,
|
|
470
|
+
expected_outputs: buildScope === "full_app"
|
|
471
|
+
? [
|
|
472
|
+
"design brief",
|
|
473
|
+
"color palette",
|
|
474
|
+
"component hierarchy",
|
|
475
|
+
"screen wireframes",
|
|
476
|
+
]
|
|
477
|
+
: ["design tokens", "component specs"],
|
|
478
|
+
estimated_screens: buildScope === "full_app" ? Math.max(3, featureCount) : 1,
|
|
479
|
+
estimated_components: Math.max(5, featureCount * 2),
|
|
480
|
+
development_phases: buildScope === "full_app"
|
|
481
|
+
? ["Foundation", "Core Features", "Polish"]
|
|
482
|
+
: ["Design", "Implementation"],
|
|
483
|
+
technical_complexity: summary.complexity_level,
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
// ============================================================================
|
|
487
|
+
// PHASE 3: CONTEXT GAP DETECTION
|
|
488
|
+
// ============================================================================
|
|
489
|
+
async detectGaps(input, summary) {
|
|
490
|
+
const missing = [];
|
|
491
|
+
const hasBranding = !!input.branding && input.branding.length > 50;
|
|
492
|
+
const hasTypes = !!input.types && input.types.length > 50;
|
|
493
|
+
const hasComponentList = !!input.component_list && input.component_list.length > 50;
|
|
494
|
+
if (!hasBranding)
|
|
495
|
+
missing.push("visual direction", "brand personality", "color palette");
|
|
496
|
+
if (!hasTypes)
|
|
497
|
+
missing.push("data structures", "type definitions");
|
|
498
|
+
if (!hasComponentList)
|
|
499
|
+
missing.push("component specifications", "UI patterns");
|
|
500
|
+
missing.push("tone guidance", "accessibility requirements", "interaction patterns");
|
|
501
|
+
return {
|
|
502
|
+
missing,
|
|
503
|
+
recommended_next_action: missing.length > 3
|
|
504
|
+
? "Generate comprehensive design brief with AI assistance"
|
|
505
|
+
: "Proceed with existing context and fill gaps during design generation",
|
|
506
|
+
visual_direction_needed: !hasBranding,
|
|
507
|
+
tone_guidance_needed: true,
|
|
508
|
+
accessibility_requirements: [
|
|
509
|
+
"WCAG 2.1 AA compliance",
|
|
510
|
+
"keyboard navigation",
|
|
511
|
+
"screen reader support",
|
|
512
|
+
],
|
|
513
|
+
interaction_patterns: [
|
|
514
|
+
"hover states",
|
|
515
|
+
"loading states",
|
|
516
|
+
"error handling",
|
|
517
|
+
],
|
|
518
|
+
brand_consistency: hasBranding
|
|
519
|
+
? []
|
|
520
|
+
: ["color usage", "typography", "spacing"],
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
// ============================================================================
|
|
524
|
+
// PHASE 4: DESIGN BRIEF GENERATION
|
|
525
|
+
// ============================================================================
|
|
526
|
+
async generateDesignBrief(summary, gaps) {
|
|
527
|
+
const prompt = `
|
|
528
|
+
Create a design inspiration brief for this project.
|
|
529
|
+
|
|
530
|
+
Project: ${summary.app_name}
|
|
531
|
+
Purpose: ${summary.core_purpose}
|
|
532
|
+
Features: ${summary.key_features.join(", ")}
|
|
533
|
+
Platform: ${summary.platform}
|
|
534
|
+
Complexity: ${summary.complexity_level}
|
|
535
|
+
|
|
536
|
+
Missing context: ${gaps.missing.join(", ")}
|
|
537
|
+
|
|
538
|
+
Generate 3 distinct visual directions, then blend the best elements.
|
|
539
|
+
|
|
540
|
+
Output JSON:
|
|
541
|
+
{
|
|
542
|
+
"theme": "dark|light|mixed",
|
|
543
|
+
"inspiration_sources": [
|
|
544
|
+
{"name": "Brand", "style": "description", "reasoning": "why it fits"}
|
|
545
|
+
],
|
|
546
|
+
"blended_style": "How you'd merge these styles",
|
|
547
|
+
"primary_color": "#hex",
|
|
548
|
+
"support_colors": ["#hex1", "#hex2"],
|
|
549
|
+
"typography": {"heading": "font", "body": "font", "mono": "font"},
|
|
550
|
+
"ui_principles": ["principle1", "principle2"],
|
|
551
|
+
"motion_style": "description",
|
|
552
|
+
"personality_keywords": ["word1", "word2"],
|
|
553
|
+
"emotional_tone": "description",
|
|
554
|
+
"target_audience": "description",
|
|
555
|
+
"accessibility_focus": ["focus1", "focus2"]
|
|
556
|
+
}`;
|
|
557
|
+
try {
|
|
558
|
+
const response = await this.ai.generateText(prompt, {
|
|
559
|
+
temperature: 0.7,
|
|
560
|
+
maxTokens: 1500,
|
|
561
|
+
});
|
|
562
|
+
return JSON.parse(response.text);
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
return this.generateDesignBriefByRules(summary);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
generateDesignBriefByRules(summary) {
|
|
569
|
+
const isDataFocused = summary.key_features.some((f) => f.toLowerCase().includes("dashboard") ||
|
|
570
|
+
f.toLowerCase().includes("analytics"));
|
|
571
|
+
const isConsumer = summary.key_features.some((f) => f.toLowerCase().includes("social") ||
|
|
572
|
+
f.toLowerCase().includes("community"));
|
|
573
|
+
const theme = isDataFocused ? "dark" : "light";
|
|
574
|
+
const primaryColor = isConsumer ? "#3B82F6" : "#6366F1";
|
|
575
|
+
return {
|
|
576
|
+
theme,
|
|
577
|
+
inspiration_sources: [
|
|
578
|
+
{ name: "Modern SaaS", style: "clean, professional, data-focused" },
|
|
579
|
+
{ name: "Material Design", style: "accessible, consistent, intuitive" },
|
|
580
|
+
{ name: "Tailwind UI", style: "utility-first, component-based" },
|
|
581
|
+
],
|
|
582
|
+
blended_style: "Clean, modern interface with strong visual hierarchy and consistent spacing",
|
|
583
|
+
primary_color: primaryColor,
|
|
584
|
+
support_colors: ["#F8FAFC", "#1E293B", "#64748B", "#E2E8F0"],
|
|
585
|
+
typography: {
|
|
586
|
+
heading: "Inter",
|
|
587
|
+
body: "Inter",
|
|
588
|
+
mono: "JetBrains Mono",
|
|
589
|
+
},
|
|
590
|
+
ui_principles: ["clarity", "consistency", "accessibility", "performance"],
|
|
591
|
+
motion_style: "smooth, purposeful transitions with easing",
|
|
592
|
+
personality_keywords: ["professional", "clean", "intuitive", "reliable"],
|
|
593
|
+
emotional_tone: "confident and approachable",
|
|
594
|
+
target_audience: summary.user_personas?.[0] || "professional users",
|
|
595
|
+
accessibility_focus: [
|
|
596
|
+
"high contrast",
|
|
597
|
+
"keyboard navigation",
|
|
598
|
+
"screen reader support",
|
|
599
|
+
],
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
// ============================================================================
|
|
603
|
+
// PHASE 5: VISUAL SYSTEM GENERATION
|
|
604
|
+
// ============================================================================
|
|
605
|
+
async buildVisualSystem(brief, summary) {
|
|
606
|
+
const prompt = `
|
|
607
|
+
Create a complete design token system based on this design brief.
|
|
608
|
+
|
|
609
|
+
Brief: ${JSON.stringify(brief, null, 2)}
|
|
610
|
+
|
|
611
|
+
Generate a comprehensive visual system with colors, typography, spacing, shadows, and motion.
|
|
612
|
+
|
|
613
|
+
Output JSON:
|
|
614
|
+
{
|
|
615
|
+
"colors": {
|
|
616
|
+
"primary": "#hex",
|
|
617
|
+
"secondary": "#hex",
|
|
618
|
+
"accent": "#hex",
|
|
619
|
+
"background": "#hex",
|
|
620
|
+
"surface": "#hex",
|
|
621
|
+
"text": "#hex",
|
|
622
|
+
"text_muted": "#hex",
|
|
623
|
+
"border": "#hex",
|
|
624
|
+
"success": "#hex",
|
|
625
|
+
"warning": "#hex",
|
|
626
|
+
"error": "#hex",
|
|
627
|
+
"info": "#hex"
|
|
628
|
+
},
|
|
629
|
+
"typography": {
|
|
630
|
+
"font_families": {"heading": "font", "body": "font", "mono": "font"},
|
|
631
|
+
"scale": {"xs": "12px", "sm": "14px", "md": "16px", "lg": "18px", "xl": "20px", "2xl": "24px", "3xl": "30px", "4xl": "36px"},
|
|
632
|
+
"weights": {"normal": "400", "medium": "500", "semibold": "600", "bold": "700"}
|
|
633
|
+
},
|
|
634
|
+
"spacing": {"xs": "4px", "sm": "8px", "md": "16px", "lg": "24px", "xl": "32px", "2xl": "48px", "3xl": "64px", "4xl": "96px"},
|
|
635
|
+
"radii": {"none": "0px", "sm": "4px", "md": "8px", "lg": "12px", "xl": "16px", "full": "9999px"},
|
|
636
|
+
"shadows": {"sm": "0 1px 2px rgba(0,0,0,0.05)", "md": "0 4px 6px rgba(0,0,0,0.1)", "lg": "0 10px 15px rgba(0,0,0,0.1)", "xl": "0 20px 25px rgba(0,0,0,0.1)"},
|
|
637
|
+
"motion": {"duration": {"fast": "150ms", "normal": "300ms", "slow": "500ms"}, "easing": {"linear": "linear", "ease_in": "cubic-bezier(0.4,0,1,1)", "ease_out": "cubic-bezier(0,0,0.2,1)", "ease_in_out": "cubic-bezier(0.4,0,0.2,1)"}},
|
|
638
|
+
"breakpoints": {"sm": "640px", "md": "768px", "lg": "1024px", "xl": "1280px"}
|
|
639
|
+
}`;
|
|
640
|
+
try {
|
|
641
|
+
const response = await this.ai.generateText(prompt, {
|
|
642
|
+
temperature: 0.4,
|
|
643
|
+
maxTokens: 2000,
|
|
644
|
+
});
|
|
645
|
+
return JSON.parse(response.text);
|
|
646
|
+
}
|
|
647
|
+
catch (error) {
|
|
648
|
+
return this.generateVisualSystemByRules(brief);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
generateVisualSystemByRules(brief) {
|
|
652
|
+
const isDark = brief.theme === "dark";
|
|
653
|
+
const baseColors = isDark
|
|
654
|
+
? {
|
|
655
|
+
bg: "#0F172A",
|
|
656
|
+
surface: "#1E293B",
|
|
657
|
+
text: "#F8FAFC",
|
|
658
|
+
textMuted: "#94A3B8",
|
|
659
|
+
}
|
|
660
|
+
: {
|
|
661
|
+
bg: "#FFFFFF",
|
|
662
|
+
surface: "#F8FAFC",
|
|
663
|
+
text: "#0F172A",
|
|
664
|
+
textMuted: "#64748B",
|
|
665
|
+
};
|
|
666
|
+
return {
|
|
667
|
+
colors: {
|
|
668
|
+
primary: brief.primary_color,
|
|
669
|
+
secondary: brief.support_colors[1] || "#64748B",
|
|
670
|
+
accent: brief.support_colors[2] || "#3B82F6",
|
|
671
|
+
background: baseColors.bg,
|
|
672
|
+
surface: baseColors.surface,
|
|
673
|
+
text: baseColors.text,
|
|
674
|
+
text_muted: baseColors.textMuted,
|
|
675
|
+
border: isDark ? "#334155" : "#E2E8F0",
|
|
676
|
+
success: "#10B981",
|
|
677
|
+
warning: "#F59E0B",
|
|
678
|
+
error: "#EF4444",
|
|
679
|
+
info: "#3B82F6",
|
|
680
|
+
},
|
|
681
|
+
typography: {
|
|
682
|
+
font_families: {
|
|
683
|
+
heading: brief.typography.heading,
|
|
684
|
+
body: brief.typography.body,
|
|
685
|
+
mono: brief.typography.mono || "JetBrains Mono",
|
|
686
|
+
},
|
|
687
|
+
scale: {
|
|
688
|
+
xs: "12px",
|
|
689
|
+
sm: "14px",
|
|
690
|
+
md: "16px",
|
|
691
|
+
lg: "18px",
|
|
692
|
+
xl: "20px",
|
|
693
|
+
"2xl": "24px",
|
|
694
|
+
"3xl": "30px",
|
|
695
|
+
"4xl": "36px",
|
|
696
|
+
},
|
|
697
|
+
weights: { normal: "400", medium: "500", semibold: "600", bold: "700" },
|
|
698
|
+
},
|
|
699
|
+
spacing: {
|
|
700
|
+
xs: "4px",
|
|
701
|
+
sm: "8px",
|
|
702
|
+
md: "16px",
|
|
703
|
+
lg: "24px",
|
|
704
|
+
xl: "32px",
|
|
705
|
+
"2xl": "48px",
|
|
706
|
+
"3xl": "64px",
|
|
707
|
+
"4xl": "96px",
|
|
708
|
+
},
|
|
709
|
+
radii: {
|
|
710
|
+
none: "0px",
|
|
711
|
+
sm: "4px",
|
|
712
|
+
md: "8px",
|
|
713
|
+
lg: "12px",
|
|
714
|
+
xl: "16px",
|
|
715
|
+
full: "9999px",
|
|
716
|
+
},
|
|
717
|
+
shadows: {
|
|
718
|
+
sm: "0 1px 2px rgba(0,0,0,0.05)",
|
|
719
|
+
md: "0 4px 6px rgba(0,0,0,0.1)",
|
|
720
|
+
lg: "0 10px 15px rgba(0,0,0,0.1)",
|
|
721
|
+
xl: "0 20px 25px rgba(0,0,0,0.1)",
|
|
722
|
+
},
|
|
723
|
+
motion: {
|
|
724
|
+
duration: { fast: "150ms", normal: "300ms", slow: "500ms" },
|
|
725
|
+
easing: {
|
|
726
|
+
linear: "linear",
|
|
727
|
+
ease_in: "cubic-bezier(0.4,0,1,1)",
|
|
728
|
+
ease_out: "cubic-bezier(0,0,0.2,1)",
|
|
729
|
+
ease_in_out: "cubic-bezier(0.4,0,0.2,1)",
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
breakpoints: { sm: "640px", md: "768px", lg: "1024px", xl: "1280px" },
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
// ============================================================================
|
|
736
|
+
// PHASE 6: COMPONENT HIERARCHY
|
|
737
|
+
// ============================================================================
|
|
738
|
+
async defineHierarchy(summary, brief, enrichedIntents) {
|
|
739
|
+
// Build intent context for the prompt
|
|
740
|
+
let intentContext = "";
|
|
741
|
+
if (enrichedIntents && enrichedIntents.length > 0) {
|
|
742
|
+
intentContext = `
|
|
743
|
+
|
|
744
|
+
VALIDATED UI INTENTS:
|
|
745
|
+
${enrichedIntents
|
|
746
|
+
.map((intent) => `
|
|
747
|
+
- ${intent.canonical_intent}: ${intent.original_description}
|
|
748
|
+
Components: ${intent.shadcn_components.join(", ")}
|
|
749
|
+
Pattern: ${intent.design_pattern.name}
|
|
750
|
+
Confidence: ${(intent.confidence * 100).toFixed(0)}%
|
|
751
|
+
`)
|
|
752
|
+
.join("")}
|
|
753
|
+
|
|
754
|
+
Use these validated intents to inform component design and ensure consistency.`;
|
|
755
|
+
}
|
|
756
|
+
const prompt = `
|
|
757
|
+
Define the component hierarchy for this project.
|
|
758
|
+
|
|
759
|
+
Project: ${summary.app_name}
|
|
760
|
+
Features: ${summary.key_features.join(", ")}
|
|
761
|
+
User Actions: ${summary.primary_user_actions.join(", ")}
|
|
762
|
+
Platform: ${summary.platform}
|
|
763
|
+
|
|
764
|
+
Design Principles: ${brief.ui_principles.join(", ")}${intentContext}
|
|
765
|
+
|
|
766
|
+
Create screens and components needed to implement this app.
|
|
767
|
+
|
|
768
|
+
Output JSON:
|
|
769
|
+
{
|
|
770
|
+
"screens": [
|
|
771
|
+
{"name": "ScreenName", "description": "purpose", "purpose": "user goal", "components": ["Component1", "Component2"], "layout_type": "single_column|multi_column|grid|dashboard|modal", "navigation_flow": ["next_screen"], "user_journey_position": "entry|main|secondary|exit"}
|
|
772
|
+
],
|
|
773
|
+
"components": [
|
|
774
|
+
{"name": "ComponentName", "description": "purpose", "type": "layout|form|display|navigation|feedback|overlay", "props": [{"name": "prop", "type": "string", "required": true, "description": "purpose"}], "interactions": ["click", "hover"], "states": ["loading", "error"], "accessibility_requirements": ["aria-label"], "responsive_behavior": "description", "related_components": ["OtherComponent"]}
|
|
775
|
+
],
|
|
776
|
+
"design_patterns": ["pattern1", "pattern2"],
|
|
777
|
+
"interaction_flows": ["flow1", "flow2"],
|
|
778
|
+
"state_management": ["local", "global"],
|
|
779
|
+
"data_flow": ["description"]
|
|
780
|
+
}`;
|
|
781
|
+
try {
|
|
782
|
+
const response = await this.ai.generateText(prompt, {
|
|
783
|
+
temperature: 0.5,
|
|
784
|
+
maxTokens: 2000,
|
|
785
|
+
});
|
|
786
|
+
return JSON.parse(response.text);
|
|
787
|
+
}
|
|
788
|
+
catch (error) {
|
|
789
|
+
return this.defineHierarchyByRules(summary);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
defineHierarchyByRules(summary) {
|
|
793
|
+
const screens = this.generateScreensFromFeatures(summary.key_features);
|
|
794
|
+
const components = this.generateComponentsFromActions(summary.primary_user_actions);
|
|
795
|
+
return {
|
|
796
|
+
screens,
|
|
797
|
+
components,
|
|
798
|
+
design_patterns: [
|
|
799
|
+
"card-based layout",
|
|
800
|
+
"progressive disclosure",
|
|
801
|
+
"responsive grid",
|
|
802
|
+
],
|
|
803
|
+
interaction_flows: [
|
|
804
|
+
"user onboarding",
|
|
805
|
+
"primary task completion",
|
|
806
|
+
"error recovery",
|
|
807
|
+
],
|
|
808
|
+
state_management: ["React hooks", "local storage", "context API"],
|
|
809
|
+
data_flow: ["Unidirectional data flow with props and callbacks"],
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
// ============================================================================
|
|
813
|
+
// PHASE 7: IMPLEMENTATION PLAN
|
|
814
|
+
// ============================================================================
|
|
815
|
+
async planImplementation(summary, hierarchy) {
|
|
816
|
+
const prompt = `
|
|
817
|
+
Create an implementation plan for this project.
|
|
818
|
+
|
|
819
|
+
Project: ${summary.app_name}
|
|
820
|
+
Platform: ${summary.platform}
|
|
821
|
+
Screens: ${hierarchy.screens.length}
|
|
822
|
+
Components: ${hierarchy.components.length}
|
|
823
|
+
Complexity: ${summary.complexity_level}
|
|
824
|
+
|
|
825
|
+
Output JSON:
|
|
826
|
+
{
|
|
827
|
+
"framework": "Next.js|React|Vue|Svelte",
|
|
828
|
+
"pages": ["page1", "page2"],
|
|
829
|
+
"state_management": "useState|Redux|Zustand|Context",
|
|
830
|
+
"build_requirements": ["requirement1", "requirement2"],
|
|
831
|
+
"data_persistence": "localStorage|IndexedDB|API|Database",
|
|
832
|
+
"notifications": "Web Push|Email|In-app",
|
|
833
|
+
"authentication": "JWT|OAuth|Magic Link",
|
|
834
|
+
"api_integration": "REST|GraphQL|tRPC",
|
|
835
|
+
"deployment_strategy": "Vercel|Netlify|AWS|Docker",
|
|
836
|
+
"performance_optimizations": ["optimization1", "optimization2"],
|
|
837
|
+
"accessibility_implementation": ["WCAG compliance", "keyboard navigation"],
|
|
838
|
+
"testing_strategy": ["unit tests", "integration tests", "e2e tests"],
|
|
839
|
+
"monitoring_analytics": ["Google Analytics", "Sentry", "Custom metrics"]
|
|
840
|
+
}`;
|
|
841
|
+
try {
|
|
842
|
+
const response = await this.ai.generateText(prompt, {
|
|
843
|
+
temperature: 0.3,
|
|
844
|
+
maxTokens: 1000,
|
|
845
|
+
});
|
|
846
|
+
return JSON.parse(response.text);
|
|
847
|
+
}
|
|
848
|
+
catch (error) {
|
|
849
|
+
return this.planImplementationByRules(summary, hierarchy);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
planImplementationByRules(summary, hierarchy) {
|
|
853
|
+
const isComplex = summary.complexity_level === "high";
|
|
854
|
+
const isMobile = summary.platform.toLowerCase().includes("mobile");
|
|
855
|
+
return {
|
|
856
|
+
framework: "Next.js",
|
|
857
|
+
pages: hierarchy.screens.map((s) => s.name.toLowerCase().replace(/\s+/g, "-")),
|
|
858
|
+
state_management: isComplex ? "Zustand" : "useState + Context",
|
|
859
|
+
build_requirements: [
|
|
860
|
+
"TypeScript",
|
|
861
|
+
"Tailwind CSS",
|
|
862
|
+
"shadcn/ui",
|
|
863
|
+
isMobile ? "PWA manifest" : "SEO optimization",
|
|
864
|
+
],
|
|
865
|
+
data_persistence: isComplex ? "API + Database" : "localStorage",
|
|
866
|
+
notifications: isMobile ? "Web Push" : "In-app",
|
|
867
|
+
authentication: isComplex ? "NextAuth.js" : "Simple JWT",
|
|
868
|
+
api_integration: isComplex ? "tRPC" : "REST",
|
|
869
|
+
deployment_strategy: "Vercel",
|
|
870
|
+
performance_optimizations: [
|
|
871
|
+
"Image optimization",
|
|
872
|
+
"Code splitting",
|
|
873
|
+
"Lazy loading",
|
|
874
|
+
"Bundle analysis",
|
|
875
|
+
],
|
|
876
|
+
accessibility_implementation: [
|
|
877
|
+
"WCAG 2.1 AA compliance",
|
|
878
|
+
"Keyboard navigation",
|
|
879
|
+
"Screen reader support",
|
|
880
|
+
"Color contrast validation",
|
|
881
|
+
],
|
|
882
|
+
testing_strategy: [
|
|
883
|
+
"Jest unit tests",
|
|
884
|
+
"React Testing Library",
|
|
885
|
+
"Playwright e2e tests",
|
|
886
|
+
],
|
|
887
|
+
monitoring_analytics: ["Vercel Analytics", "Sentry error tracking"],
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
// ============================================================================
|
|
891
|
+
// PHASE 8: DESIGN INTENT SYNTHESIS
|
|
892
|
+
// ============================================================================
|
|
893
|
+
async synthesizeIntent(brief, visualSystem, summary) {
|
|
894
|
+
const prompt = `
|
|
895
|
+
Synthesize the complete design intent for this project.
|
|
896
|
+
|
|
897
|
+
Design Brief: ${JSON.stringify(brief, null, 2)}
|
|
898
|
+
Visual System: ${JSON.stringify(visualSystem.colors, null, 2)}
|
|
899
|
+
Project: ${summary.app_name} - ${summary.core_purpose}
|
|
900
|
+
|
|
901
|
+
Create a final design philosophy that guides all design decisions.
|
|
902
|
+
|
|
903
|
+
Output JSON:
|
|
904
|
+
{
|
|
905
|
+
"visual_philosophy": "One paragraph describing the overall design approach",
|
|
906
|
+
"design_anchors": ["principle1", "principle2", "principle3"],
|
|
907
|
+
"user_experience_goals": ["goal1", "goal2"],
|
|
908
|
+
"brand_alignment": "How design aligns with brand values",
|
|
909
|
+
"technical_constraints": ["constraint1", "constraint2"],
|
|
910
|
+
"scalability_considerations": ["consideration1", "consideration2"],
|
|
911
|
+
"maintenance_guidelines": ["guideline1", "guideline2"],
|
|
912
|
+
"success_criteria": ["criteria1", "criteria2"]
|
|
913
|
+
}`;
|
|
914
|
+
try {
|
|
915
|
+
const response = await this.ai.generateText(prompt, {
|
|
916
|
+
temperature: 0.6,
|
|
917
|
+
maxTokens: 800,
|
|
918
|
+
});
|
|
919
|
+
return JSON.parse(response.text);
|
|
920
|
+
}
|
|
921
|
+
catch (error) {
|
|
922
|
+
return this.synthesizeIntentByRules(brief, summary);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
synthesizeIntentByRules(brief, summary) {
|
|
926
|
+
return {
|
|
927
|
+
visual_philosophy: `${summary.app_name} embodies a ${brief.personality_keywords.join(", ")} design approach that prioritizes ${brief.ui_principles.join(", ")} to create an ${brief.emotional_tone} user experience.`,
|
|
928
|
+
design_anchors: brief.ui_principles.slice(0, 3),
|
|
929
|
+
user_experience_goals: [
|
|
930
|
+
"Intuitive navigation and task completion",
|
|
931
|
+
"Accessible and inclusive design",
|
|
932
|
+
"Consistent and predictable interactions",
|
|
933
|
+
],
|
|
934
|
+
brand_alignment: `Design reflects ${brief.personality_keywords.join(", ")} values through ${brief.primary_color} primary color and ${brief.typography.heading} typography.`,
|
|
935
|
+
technical_constraints: [
|
|
936
|
+
"Mobile-first responsive design",
|
|
937
|
+
"Performance optimization",
|
|
938
|
+
"Cross-browser compatibility",
|
|
939
|
+
],
|
|
940
|
+
scalability_considerations: [
|
|
941
|
+
"Component reusability",
|
|
942
|
+
"Design token consistency",
|
|
943
|
+
"Modular architecture",
|
|
944
|
+
],
|
|
945
|
+
maintenance_guidelines: [
|
|
946
|
+
"Follow established design patterns",
|
|
947
|
+
"Maintain design token usage",
|
|
948
|
+
"Regular accessibility audits",
|
|
949
|
+
],
|
|
950
|
+
success_criteria: [
|
|
951
|
+
"User task completion rate > 90%",
|
|
952
|
+
"Accessibility score > 95",
|
|
953
|
+
"Performance score > 90",
|
|
954
|
+
],
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
// ============================================================================
|
|
958
|
+
// HELPER METHODS
|
|
959
|
+
// ============================================================================
|
|
960
|
+
initializeFallbacks() {
|
|
961
|
+
this.fallbacks.set("extractAppName", (prd) => ({
|
|
962
|
+
success: true,
|
|
963
|
+
data: this.extractAppName(prd),
|
|
964
|
+
confidence: 0.8,
|
|
965
|
+
method: "rule_based",
|
|
966
|
+
warnings: [],
|
|
967
|
+
}));
|
|
968
|
+
}
|
|
969
|
+
extractAppName(prd) {
|
|
970
|
+
const titleMatch = prd.match(/#\s*(.+)/);
|
|
971
|
+
if (titleMatch)
|
|
972
|
+
return titleMatch[1]?.trim() || "MyApp";
|
|
973
|
+
const firstLine = prd.split("\n")[0];
|
|
974
|
+
return firstLine?.replace(/[#*]/g, "").trim() || "MyApp";
|
|
975
|
+
}
|
|
976
|
+
extractFeatures(prd) {
|
|
977
|
+
const features = [];
|
|
978
|
+
const lines = prd.split("\n");
|
|
979
|
+
for (const line of lines) {
|
|
980
|
+
if (line.includes("feature") ||
|
|
981
|
+
line.includes("functionality") ||
|
|
982
|
+
line.includes("capability")) {
|
|
983
|
+
const cleanLine = line.replace(/[-*•]\s*/, "").trim();
|
|
984
|
+
if (cleanLine.length > 5)
|
|
985
|
+
features.push(cleanLine);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
return features.length > 0
|
|
989
|
+
? features
|
|
990
|
+
: ["User interface", "Data management"];
|
|
991
|
+
}
|
|
992
|
+
extractPurpose(prd) {
|
|
993
|
+
const purposeMatch = prd.match(/purpose[:\s]+(.+)/i);
|
|
994
|
+
if (purposeMatch)
|
|
995
|
+
return purposeMatch[1]?.trim() || "Application for user needs";
|
|
996
|
+
const firstParagraph = prd.split("\n\n")[0];
|
|
997
|
+
return (firstParagraph?.replace(/[#*]/g, "").trim() ||
|
|
998
|
+
"Application for user needs");
|
|
999
|
+
}
|
|
1000
|
+
extractUserActions(prd) {
|
|
1001
|
+
const actions = [];
|
|
1002
|
+
const actionKeywords = [
|
|
1003
|
+
"click",
|
|
1004
|
+
"select",
|
|
1005
|
+
"input",
|
|
1006
|
+
"submit",
|
|
1007
|
+
"view",
|
|
1008
|
+
"create",
|
|
1009
|
+
"edit",
|
|
1010
|
+
"delete",
|
|
1011
|
+
];
|
|
1012
|
+
for (const keyword of actionKeywords) {
|
|
1013
|
+
if (prd.toLowerCase().includes(keyword)) {
|
|
1014
|
+
actions.push(keyword.charAt(0).toUpperCase() + keyword.slice(1));
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
return actions.length > 0
|
|
1018
|
+
? actions
|
|
1019
|
+
: ["View content", "Interact with interface"];
|
|
1020
|
+
}
|
|
1021
|
+
inferPlatform(prd) {
|
|
1022
|
+
const lowerPrd = prd.toLowerCase();
|
|
1023
|
+
if (lowerPrd.includes("mobile") || lowerPrd.includes("app"))
|
|
1024
|
+
return "Mobile PWA";
|
|
1025
|
+
if (lowerPrd.includes("dashboard") || lowerPrd.includes("admin"))
|
|
1026
|
+
return "Web Dashboard";
|
|
1027
|
+
return "Web Application";
|
|
1028
|
+
}
|
|
1029
|
+
extractTechnicalRequirements(prd) {
|
|
1030
|
+
const requirements = [];
|
|
1031
|
+
const techKeywords = [
|
|
1032
|
+
"api",
|
|
1033
|
+
"database",
|
|
1034
|
+
"auth",
|
|
1035
|
+
"responsive",
|
|
1036
|
+
"pwa",
|
|
1037
|
+
"offline",
|
|
1038
|
+
];
|
|
1039
|
+
for (const keyword of techKeywords) {
|
|
1040
|
+
if (prd.toLowerCase().includes(keyword)) {
|
|
1041
|
+
requirements.push(keyword.toUpperCase());
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
return requirements.length > 0
|
|
1045
|
+
? requirements
|
|
1046
|
+
: ["Responsive Design", "Modern Browser Support"];
|
|
1047
|
+
}
|
|
1048
|
+
assessComplexity(featureCount) {
|
|
1049
|
+
if (featureCount <= 3)
|
|
1050
|
+
return "low";
|
|
1051
|
+
if (featureCount <= 6)
|
|
1052
|
+
return "medium";
|
|
1053
|
+
return "high";
|
|
1054
|
+
}
|
|
1055
|
+
extractPersonas(prd) {
|
|
1056
|
+
const personas = [];
|
|
1057
|
+
const personaKeywords = [
|
|
1058
|
+
"user",
|
|
1059
|
+
"customer",
|
|
1060
|
+
"admin",
|
|
1061
|
+
"manager",
|
|
1062
|
+
"developer",
|
|
1063
|
+
];
|
|
1064
|
+
for (const keyword of personaKeywords) {
|
|
1065
|
+
if (prd.toLowerCase().includes(keyword)) {
|
|
1066
|
+
personas.push(keyword.charAt(0).toUpperCase() + keyword.slice(1));
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
return personas.length > 0 ? personas : ["End User"];
|
|
1070
|
+
}
|
|
1071
|
+
extractBusinessGoals(prd) {
|
|
1072
|
+
return ["User engagement", "Task completion", "User satisfaction"];
|
|
1073
|
+
}
|
|
1074
|
+
extractSuccessMetrics(prd) {
|
|
1075
|
+
return ["User adoption", "Task completion rate", "User satisfaction score"];
|
|
1076
|
+
}
|
|
1077
|
+
generateScreensFromFeatures(features) {
|
|
1078
|
+
const screens = [
|
|
1079
|
+
{
|
|
1080
|
+
name: "Home",
|
|
1081
|
+
description: "Main landing screen",
|
|
1082
|
+
purpose: "Provide overview and navigation",
|
|
1083
|
+
components: ["Header", "Navigation", "ContentArea"],
|
|
1084
|
+
layout_type: "single_column",
|
|
1085
|
+
navigation_flow: ["Settings"],
|
|
1086
|
+
user_journey_position: "entry",
|
|
1087
|
+
},
|
|
1088
|
+
];
|
|
1089
|
+
if (features.some((f) => f.toLowerCase().includes("dashboard"))) {
|
|
1090
|
+
const dashboardScreen = {
|
|
1091
|
+
name: "Dashboard",
|
|
1092
|
+
description: "Data overview and analytics",
|
|
1093
|
+
purpose: "Display key metrics and insights",
|
|
1094
|
+
components: ["MetricsCard", "Chart", "DataTable"],
|
|
1095
|
+
layout_type: "dashboard",
|
|
1096
|
+
navigation_flow: ["Home", "Details"],
|
|
1097
|
+
user_journey_position: "main",
|
|
1098
|
+
};
|
|
1099
|
+
screens.push(dashboardScreen);
|
|
1100
|
+
}
|
|
1101
|
+
return screens;
|
|
1102
|
+
}
|
|
1103
|
+
generateComponentsFromActions(actions) {
|
|
1104
|
+
const components = [
|
|
1105
|
+
{
|
|
1106
|
+
name: "Button",
|
|
1107
|
+
description: "Primary action button",
|
|
1108
|
+
type: "form",
|
|
1109
|
+
props: [
|
|
1110
|
+
{
|
|
1111
|
+
name: "children",
|
|
1112
|
+
type: "ReactNode",
|
|
1113
|
+
required: true,
|
|
1114
|
+
description: "Button content",
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
name: "onClick",
|
|
1118
|
+
type: "() => void",
|
|
1119
|
+
required: true,
|
|
1120
|
+
description: "Click handler",
|
|
1121
|
+
},
|
|
1122
|
+
],
|
|
1123
|
+
interactions: ["click", "hover"],
|
|
1124
|
+
states: ["default", "loading", "disabled"],
|
|
1125
|
+
accessibility_requirements: ["aria-label", "keyboard navigation"],
|
|
1126
|
+
responsive_behavior: "Maintains size across breakpoints",
|
|
1127
|
+
related_components: ["IconButton", "LinkButton"],
|
|
1128
|
+
},
|
|
1129
|
+
];
|
|
1130
|
+
if (actions.some((a) => a.toLowerCase().includes("input"))) {
|
|
1131
|
+
components.push({
|
|
1132
|
+
name: "Input",
|
|
1133
|
+
description: "Text input field",
|
|
1134
|
+
type: "form",
|
|
1135
|
+
props: [
|
|
1136
|
+
{
|
|
1137
|
+
name: "value",
|
|
1138
|
+
type: "string",
|
|
1139
|
+
required: true,
|
|
1140
|
+
description: "Input value",
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
name: "onChange",
|
|
1144
|
+
type: "(value: string) => void",
|
|
1145
|
+
required: true,
|
|
1146
|
+
description: "Change handler",
|
|
1147
|
+
},
|
|
1148
|
+
],
|
|
1149
|
+
interactions: ["focus", "blur", "input"],
|
|
1150
|
+
states: ["default", "focused", "error", "disabled"],
|
|
1151
|
+
accessibility_requirements: ["aria-label", "aria-invalid"],
|
|
1152
|
+
responsive_behavior: "Full width on mobile",
|
|
1153
|
+
related_components: ["TextArea", "Select"],
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
return components;
|
|
1157
|
+
}
|
|
1158
|
+
validateFunctionalSummary(data) {
|
|
1159
|
+
return {
|
|
1160
|
+
app_name: data.app_name || "MyApp",
|
|
1161
|
+
core_purpose: data.core_purpose || "Application purpose",
|
|
1162
|
+
key_features: Array.isArray(data.key_features)
|
|
1163
|
+
? data.key_features
|
|
1164
|
+
: ["Feature 1"],
|
|
1165
|
+
primary_user_actions: Array.isArray(data.primary_user_actions)
|
|
1166
|
+
? data.primary_user_actions
|
|
1167
|
+
: ["Action 1"],
|
|
1168
|
+
platform: data.platform || "Web Application",
|
|
1169
|
+
technical_requirements: Array.isArray(data.technical_requirements)
|
|
1170
|
+
? data.technical_requirements
|
|
1171
|
+
: ["Requirement 1"],
|
|
1172
|
+
complexity_level: ["low", "medium", "high"].includes(data.complexity_level)
|
|
1173
|
+
? data.complexity_level
|
|
1174
|
+
: "medium",
|
|
1175
|
+
user_personas: Array.isArray(data.user_personas)
|
|
1176
|
+
? data.user_personas
|
|
1177
|
+
: undefined,
|
|
1178
|
+
business_goals: Array.isArray(data.business_goals)
|
|
1179
|
+
? data.business_goals
|
|
1180
|
+
: undefined,
|
|
1181
|
+
success_metrics: Array.isArray(data.success_metrics)
|
|
1182
|
+
? data.success_metrics
|
|
1183
|
+
: undefined,
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
calculateConfidenceScores() {
|
|
1187
|
+
return {
|
|
1188
|
+
functional_summary: 0.9,
|
|
1189
|
+
project_scope: 0.8,
|
|
1190
|
+
context_gaps: 0.7,
|
|
1191
|
+
design_brief: 0.8,
|
|
1192
|
+
visual_system: 0.9,
|
|
1193
|
+
component_hierarchy: 0.8,
|
|
1194
|
+
implementation_plan: 0.7,
|
|
1195
|
+
design_intent: 0.8,
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
createEmptyManifest(projectPath) {
|
|
1199
|
+
return {
|
|
1200
|
+
version: "1.0.0",
|
|
1201
|
+
generated_at: new Date().toISOString(),
|
|
1202
|
+
project_name: "Unknown Project",
|
|
1203
|
+
phases: {
|
|
1204
|
+
functional_summary: {
|
|
1205
|
+
app_name: "Unknown App",
|
|
1206
|
+
core_purpose: "Unknown purpose",
|
|
1207
|
+
key_features: [],
|
|
1208
|
+
primary_user_actions: [],
|
|
1209
|
+
platform: "Web",
|
|
1210
|
+
technical_requirements: [],
|
|
1211
|
+
complexity_level: "medium",
|
|
1212
|
+
},
|
|
1213
|
+
project_scope: {
|
|
1214
|
+
build_scope: "full_app",
|
|
1215
|
+
reason: "Default fallback",
|
|
1216
|
+
expected_outputs: [],
|
|
1217
|
+
},
|
|
1218
|
+
context_gaps: {
|
|
1219
|
+
missing: [],
|
|
1220
|
+
recommended_next_action: "Manual review required",
|
|
1221
|
+
},
|
|
1222
|
+
design_brief: {
|
|
1223
|
+
theme: "light",
|
|
1224
|
+
inspiration_sources: [],
|
|
1225
|
+
blended_style: "Default style",
|
|
1226
|
+
primary_color: "#3B82F6",
|
|
1227
|
+
support_colors: [],
|
|
1228
|
+
typography: { heading: "Inter", body: "Inter" },
|
|
1229
|
+
ui_principles: [],
|
|
1230
|
+
motion_style: "smooth",
|
|
1231
|
+
personality_keywords: [],
|
|
1232
|
+
emotional_tone: "neutral",
|
|
1233
|
+
target_audience: "general",
|
|
1234
|
+
},
|
|
1235
|
+
visual_system: {
|
|
1236
|
+
colors: {
|
|
1237
|
+
primary: "#3B82F6",
|
|
1238
|
+
background: "#FFFFFF",
|
|
1239
|
+
surface: "#F8FAFC",
|
|
1240
|
+
text: "#0F172A",
|
|
1241
|
+
text_muted: "#64748B",
|
|
1242
|
+
},
|
|
1243
|
+
typography: {
|
|
1244
|
+
font_families: {
|
|
1245
|
+
heading: "Inter",
|
|
1246
|
+
body: "Inter",
|
|
1247
|
+
mono: "JetBrains Mono",
|
|
1248
|
+
},
|
|
1249
|
+
scale: {
|
|
1250
|
+
xs: "12px",
|
|
1251
|
+
sm: "14px",
|
|
1252
|
+
md: "16px",
|
|
1253
|
+
lg: "18px",
|
|
1254
|
+
xl: "20px",
|
|
1255
|
+
"2xl": "24px",
|
|
1256
|
+
"3xl": "30px",
|
|
1257
|
+
"4xl": "36px",
|
|
1258
|
+
},
|
|
1259
|
+
weights: {
|
|
1260
|
+
normal: "400",
|
|
1261
|
+
medium: "500",
|
|
1262
|
+
semibold: "600",
|
|
1263
|
+
bold: "700",
|
|
1264
|
+
},
|
|
1265
|
+
},
|
|
1266
|
+
spacing: {
|
|
1267
|
+
xs: "4px",
|
|
1268
|
+
sm: "8px",
|
|
1269
|
+
md: "16px",
|
|
1270
|
+
lg: "24px",
|
|
1271
|
+
xl: "32px",
|
|
1272
|
+
"2xl": "48px",
|
|
1273
|
+
"3xl": "64px",
|
|
1274
|
+
"4xl": "96px",
|
|
1275
|
+
},
|
|
1276
|
+
radii: {
|
|
1277
|
+
none: "0px",
|
|
1278
|
+
sm: "4px",
|
|
1279
|
+
md: "8px",
|
|
1280
|
+
lg: "12px",
|
|
1281
|
+
xl: "16px",
|
|
1282
|
+
full: "9999px",
|
|
1283
|
+
},
|
|
1284
|
+
shadows: {
|
|
1285
|
+
sm: "0 1px 2px rgba(0,0,0,0.05)",
|
|
1286
|
+
md: "0 4px 6px rgba(0,0,0,0.1)",
|
|
1287
|
+
lg: "0 10px 15px rgba(0,0,0,0.1)",
|
|
1288
|
+
xl: "0 20px 25px rgba(0,0,0,0.1)",
|
|
1289
|
+
},
|
|
1290
|
+
motion: {
|
|
1291
|
+
duration: { fast: "150ms", normal: "300ms", slow: "500ms" },
|
|
1292
|
+
easing: {
|
|
1293
|
+
linear: "linear",
|
|
1294
|
+
ease_in: "cubic-bezier(0.4,0,1,1)",
|
|
1295
|
+
ease_out: "cubic-bezier(0,0,0.2,1)",
|
|
1296
|
+
ease_in_out: "cubic-bezier(0.4,0,0.2,1)",
|
|
1297
|
+
},
|
|
1298
|
+
},
|
|
1299
|
+
breakpoints: { sm: "640px", md: "768px", lg: "1024px", xl: "1280px" },
|
|
1300
|
+
},
|
|
1301
|
+
component_hierarchy: {
|
|
1302
|
+
screens: [],
|
|
1303
|
+
components: [],
|
|
1304
|
+
design_patterns: [],
|
|
1305
|
+
interaction_flows: [],
|
|
1306
|
+
state_management: [],
|
|
1307
|
+
data_flow: [],
|
|
1308
|
+
},
|
|
1309
|
+
implementation_plan: {
|
|
1310
|
+
framework: "Next.js",
|
|
1311
|
+
pages: [],
|
|
1312
|
+
state_management: "useState",
|
|
1313
|
+
build_requirements: [],
|
|
1314
|
+
data_persistence: "localStorage",
|
|
1315
|
+
performance_optimizations: [],
|
|
1316
|
+
accessibility_implementation: [],
|
|
1317
|
+
testing_strategy: [],
|
|
1318
|
+
},
|
|
1319
|
+
design_intent: {
|
|
1320
|
+
visual_philosophy: "Clean and functional design",
|
|
1321
|
+
design_anchors: ["clarity", "consistency", "accessibility"],
|
|
1322
|
+
user_experience_goals: [],
|
|
1323
|
+
brand_alignment: "Neutral brand alignment",
|
|
1324
|
+
technical_constraints: [],
|
|
1325
|
+
scalability_considerations: [],
|
|
1326
|
+
maintenance_guidelines: [],
|
|
1327
|
+
success_criteria: [],
|
|
1328
|
+
},
|
|
1329
|
+
},
|
|
1330
|
+
metadata: {
|
|
1331
|
+
confidence_scores: {},
|
|
1332
|
+
fallbacks_used: ["all_phases"],
|
|
1333
|
+
generation_time_ms: 0,
|
|
1334
|
+
},
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
// ============================================================================
|
|
1338
|
+
// INTENT VALIDATION (Phase 3.5)
|
|
1339
|
+
// ============================================================================
|
|
1340
|
+
/**
|
|
1341
|
+
* Validate UI intents from PRD and context files
|
|
1342
|
+
*/
|
|
1343
|
+
async validateIntents(input, summary) {
|
|
1344
|
+
try {
|
|
1345
|
+
console.log(chalk_1.default.blue("🔍 Validating UI intents..."));
|
|
1346
|
+
const intentValidator = new IntentValidator_1.IntentValidator();
|
|
1347
|
+
const validationReport = await intentValidator.validateContextFiles(input.prd, input.types || "", input.branding || "");
|
|
1348
|
+
console.log(chalk_1.default.gray(` Found ${validationReport.validated_intents.length} validated intents`));
|
|
1349
|
+
console.log(chalk_1.default.gray(` Confidence: ${(validationReport.confidence_score * 100).toFixed(0)}%`));
|
|
1350
|
+
if (validationReport.ambiguous_intents.length > 0) {
|
|
1351
|
+
console.log(chalk_1.default.yellow(` ⚠️ ${validationReport.ambiguous_intents.length} ambiguous intents detected`));
|
|
1352
|
+
}
|
|
1353
|
+
if (validationReport.unknown_intents.length > 0) {
|
|
1354
|
+
console.log(chalk_1.default.yellow(` ❓ ${validationReport.unknown_intents.length} unknown intents detected`));
|
|
1355
|
+
}
|
|
1356
|
+
// Enrich validated intents into component specifications
|
|
1357
|
+
const intentEnricher = new IntentEnricher_1.IntentEnricher();
|
|
1358
|
+
const enrichedIntents = await intentEnricher.enrichComponentDefinitions(summary, validationReport);
|
|
1359
|
+
console.log(chalk_1.default.green(`✅ Intent validation complete - ${enrichedIntents.length} component specs generated`));
|
|
1360
|
+
return {
|
|
1361
|
+
validation_report: validationReport,
|
|
1362
|
+
enriched_intents: enrichedIntents,
|
|
1363
|
+
confidence_score: validationReport.confidence_score,
|
|
1364
|
+
needs_clarification: validationReport.confidence_score < 0.7,
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
catch (error) {
|
|
1368
|
+
console.error(chalk_1.default.red("❌ Intent validation failed:"), error);
|
|
1369
|
+
// Return fallback result
|
|
1370
|
+
return {
|
|
1371
|
+
validation_report: {
|
|
1372
|
+
validated_intents: [],
|
|
1373
|
+
ambiguous_intents: [],
|
|
1374
|
+
unknown_intents: [],
|
|
1375
|
+
confidence_score: 0,
|
|
1376
|
+
clarifications_needed: [],
|
|
1377
|
+
},
|
|
1378
|
+
enriched_intents: [],
|
|
1379
|
+
confidence_score: 0,
|
|
1380
|
+
needs_clarification: false,
|
|
1381
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
// ============================================================================
|
|
1386
|
+
// SUBAGENT INTERFACE IMPLEMENTATION
|
|
1387
|
+
// ============================================================================
|
|
1388
|
+
async validate(input) {
|
|
1389
|
+
return !!(input.prd && input.prd.length > 10 && input.project_path);
|
|
1390
|
+
}
|
|
1391
|
+
async cleanup() {
|
|
1392
|
+
// No cleanup needed
|
|
1393
|
+
}
|
|
1394
|
+
async getStatus() {
|
|
1395
|
+
return {
|
|
1396
|
+
name: this.name,
|
|
1397
|
+
status: "idle",
|
|
1398
|
+
lastRun: undefined,
|
|
1399
|
+
executionTime: 0,
|
|
1400
|
+
errorCount: 0,
|
|
1401
|
+
successCount: 0,
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
exports.DesignPipelineAgent = DesignPipelineAgent;
|
|
1406
|
+
//# sourceMappingURL=DesignPipelineAgent.js.map
|