@forgespace/siza-gen 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -4
- package/dist/index.d.ts +63 -4
- package/dist/index.js +296 -89
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -38,13 +38,79 @@ const results = searchComponents('hero section');
|
|
|
38
38
|
const generator = GeneratorFactory.create('react');
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
## What's inside
|
|
42
|
+
|
|
43
|
+
| Module | Description |
|
|
44
|
+
| ------------- | ----------------------------------------------------------------- |
|
|
45
|
+
| `generators/` | React, Vue, Angular, Svelte, HTML code generators |
|
|
46
|
+
| `registry/` | 502 snippets — 357 component + 85 animation + 60 backend |
|
|
47
|
+
| `ml/` | Embeddings (all-MiniLM-L6-v2), quality scoring, training pipeline |
|
|
48
|
+
| `feedback/` | Self-learning loop, pattern promotion, feedback-boosted search |
|
|
49
|
+
| `quality/` | Anti-generic rules, diversity tracking |
|
|
50
|
+
| `artifacts/` | Generated artifact storage and learning loop |
|
|
51
|
+
|
|
52
|
+
## LLM Providers
|
|
53
|
+
|
|
54
|
+
Built-in multi-provider support with auto-fallback:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { createProviderWithFallback } from '@forgespace/siza-gen';
|
|
58
|
+
|
|
59
|
+
// Tries Ollama first (local), falls back to OpenAI/Anthropic/Gemini
|
|
60
|
+
const provider = await createProviderWithFallback();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Supports: **Ollama** (local), **OpenAI**, **Anthropic**, **Gemini** (via OpenAI
|
|
64
|
+
adapter).
|
|
65
|
+
|
|
66
|
+
## Brand Integration
|
|
67
|
+
|
|
68
|
+
Transform [branding-mcp](https://github.com/Forge-Space/branding-mcp) tokens
|
|
69
|
+
into design context:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { brandToDesignContext } from '@forgespace/siza-gen';
|
|
73
|
+
|
|
74
|
+
const designContext = brandToDesignContext(brandIdentity);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Python ML Sidecar
|
|
78
|
+
|
|
79
|
+
An optional Python FastAPI sidecar handles compute-intensive ML operations. When
|
|
80
|
+
unavailable, the system gracefully degrades to Transformers.js and heuristics.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cd python && pip install -e ".[dev]"
|
|
84
|
+
python -m uvicorn siza_ml.app:app --port 8100
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Or via npm:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm run sidecar:start # Launch Python sidecar
|
|
91
|
+
npm run sidecar:test # Run Python tests (41 tests)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Endpoint | Description |
|
|
95
|
+
| --------------------- | ------------------------------- |
|
|
96
|
+
| `POST /embed` | Sentence-transformer embeddings |
|
|
97
|
+
| `POST /embed/batch` | Batch embeddings |
|
|
98
|
+
| `POST /vector/search` | FAISS k-NN similarity search |
|
|
99
|
+
| `POST /score` | LLM-based quality scoring |
|
|
100
|
+
| `POST /enhance` | LLM-based prompt enhancement |
|
|
101
|
+
| `POST /train/start` | LoRA fine-tuning via PEFT |
|
|
102
|
+
| `GET /health` | Liveness check |
|
|
103
|
+
| `GET /metrics/report` | ML observability metrics |
|
|
104
|
+
|
|
105
|
+
**Fallback chain**: Python sidecar → Transformers.js/local LLM → heuristics.
|
|
106
|
+
|
|
41
107
|
## Development
|
|
42
108
|
|
|
43
109
|
```bash
|
|
44
|
-
npm install
|
|
45
|
-
npm
|
|
46
|
-
npm test
|
|
47
|
-
npm run
|
|
110
|
+
npm install && npm run build
|
|
111
|
+
npm test # 424 tests, 21 suites
|
|
112
|
+
npm run validate # lint + format + typecheck + test
|
|
113
|
+
npm run registry:stats # Report snippet counts
|
|
48
114
|
```
|
|
49
115
|
|
|
50
116
|
## License
|
package/dist/index.d.ts
CHANGED
|
@@ -174,11 +174,12 @@ declare function configureEmbeddings(overrides: Partial<IEmbeddingConfig>): void
|
|
|
174
174
|
declare function getEmbeddingConfig(): IEmbeddingConfig;
|
|
175
175
|
/**
|
|
176
176
|
* Generate an embedding vector for a single text string.
|
|
177
|
+
* Delegates to Python sidecar when available, falls back to Transformers.js.
|
|
177
178
|
*/
|
|
178
179
|
declare function embed(text: string): Promise<Float32Array>;
|
|
179
180
|
/**
|
|
180
181
|
* Generate embeddings for multiple texts in batch.
|
|
181
|
-
*
|
|
182
|
+
* Delegates to Python sidecar when available, falls back to Transformers.js.
|
|
182
183
|
*/
|
|
183
184
|
declare function embedBatch(texts: string[]): Promise<Float32Array[]>;
|
|
184
185
|
/**
|
|
@@ -459,10 +460,10 @@ declare function checkTrainingReadiness(adapter: AdapterType, modelId: ModelId,
|
|
|
459
460
|
*
|
|
460
461
|
* Returns the job ID for status tracking.
|
|
461
462
|
*/
|
|
462
|
-
declare function startTrainingJob(adapter: AdapterType, modelId: ModelId, db: Database.Database, config?: ILoRAConfig, trainingCommand?: string): {
|
|
463
|
+
declare function startTrainingJob(adapter: AdapterType, modelId: ModelId, db: Database.Database, config?: ILoRAConfig, trainingCommand?: string): Promise<{
|
|
463
464
|
jobId: number;
|
|
464
465
|
status: ITrainingStatus;
|
|
465
|
-
}
|
|
466
|
+
}>;
|
|
466
467
|
/**
|
|
467
468
|
* Cancel a running training job.
|
|
468
469
|
*/
|
|
@@ -764,6 +765,64 @@ interface ITrainingDataResult {
|
|
|
764
765
|
*/
|
|
765
766
|
declare function storeDesignLearning(analysis: IDesignAnalysis, generatedCode: string, componentName: string, framework: string, db: Database.Database): ITrainingDataResult;
|
|
766
767
|
|
|
768
|
+
declare function setSidecarUrl(url: string): void;
|
|
769
|
+
declare function getSidecarUrl(): string;
|
|
770
|
+
declare function isSidecarAvailable(): Promise<boolean>;
|
|
771
|
+
declare function resetAvailabilityCache(): void;
|
|
772
|
+
declare function sidecarEmbed(text: string): Promise<Float32Array>;
|
|
773
|
+
declare function sidecarEmbedBatch(texts: string[]): Promise<Float32Array[]>;
|
|
774
|
+
interface ISidecarScoreResult {
|
|
775
|
+
score: number;
|
|
776
|
+
confidence: number;
|
|
777
|
+
factors: Record<string, number>;
|
|
778
|
+
source: string;
|
|
779
|
+
}
|
|
780
|
+
declare function sidecarScoreQuality(prompt: string, code: string, componentType?: string, framework?: string): Promise<ISidecarScoreResult>;
|
|
781
|
+
interface ISidecarEnhanceResult {
|
|
782
|
+
enhanced: string;
|
|
783
|
+
additions: string[];
|
|
784
|
+
source: string;
|
|
785
|
+
}
|
|
786
|
+
declare function sidecarEnhancePrompt(prompt: string, context?: {
|
|
787
|
+
componentType?: string;
|
|
788
|
+
framework?: string;
|
|
789
|
+
style?: string;
|
|
790
|
+
mood?: string;
|
|
791
|
+
industry?: string;
|
|
792
|
+
}): Promise<ISidecarEnhanceResult>;
|
|
793
|
+
interface ISidecarVectorSearchResult {
|
|
794
|
+
id: string;
|
|
795
|
+
distance: number;
|
|
796
|
+
metadata?: Record<string, string>;
|
|
797
|
+
}
|
|
798
|
+
declare function sidecarVectorSearch(vector: Float32Array, topK?: number): Promise<ISidecarVectorSearchResult[]>;
|
|
799
|
+
declare function sidecarVectorIndex(vectors: {
|
|
800
|
+
id: string;
|
|
801
|
+
vector: Float32Array;
|
|
802
|
+
metadata?: Record<string, string>;
|
|
803
|
+
}[]): Promise<{
|
|
804
|
+
indexed: number;
|
|
805
|
+
}>;
|
|
806
|
+
interface ISidecarTrainingJob {
|
|
807
|
+
job_id: string;
|
|
808
|
+
status: string;
|
|
809
|
+
}
|
|
810
|
+
declare function sidecarStartTraining(adapterType: string, dataPath: string, config?: {
|
|
811
|
+
rank?: number;
|
|
812
|
+
epochs?: number;
|
|
813
|
+
learningRate?: number;
|
|
814
|
+
batchSize?: number;
|
|
815
|
+
}): Promise<ISidecarTrainingJob>;
|
|
816
|
+
declare function sidecarGetTrainingStatus(jobId: string): Promise<{
|
|
817
|
+
job_id: string;
|
|
818
|
+
status: string;
|
|
819
|
+
progress: number;
|
|
820
|
+
error?: string;
|
|
821
|
+
}>;
|
|
822
|
+
declare function sidecarCancelTraining(jobId: string): Promise<{
|
|
823
|
+
cancelled: boolean;
|
|
824
|
+
}>;
|
|
825
|
+
|
|
767
826
|
interface IDesignContext {
|
|
768
827
|
typography: {
|
|
769
828
|
fontFamily: string;
|
|
@@ -2510,4 +2569,4 @@ declare function isNetworkError(error: unknown): boolean;
|
|
|
2510
2569
|
*/
|
|
2511
2570
|
declare function retry<T>(fn: () => Promise<T>, maxAttempts?: number, delay?: number): Promise<T>;
|
|
2512
2571
|
|
|
2513
|
-
export { ANIMATION_PRESETS, type AdapterType, AngularGenerator, AnthropicProvider, type AppType, type Architecture, type ArtifactType, type BackendCategory, type BackendFramework, BaseGenerator, type BrandIdentityInput, COLOR_SYSTEMS, COMPONENT_LIBRARIES, type ComponentCategory, type ComponentLibrary, type ComponentLibraryId, type ComponentLibraryIntegration, type ComponentLibrarySetupOptions, type Config, DEFAULT_COLOR_SYSTEM, DEFAULT_CONTEXT, DEFAULT_DESIGN_CONTEXT, DEFAULT_FONT_PAIRING, DEFAULT_LORA_CONFIG, DEFAULT_MAX_TOKENS, DEFAULT_PRESET, DEFAULT_TEMPERATURE, DEFAULT_TIMEOUT_MS, type DeployTarget, FONT_PAIRINGS, type Framework, GeneratorFactory, HtmlGenerator, type IAccessibilityIssue, type IAccessibilityReport, type IArtifactQuery, type IBackendSnippet, ICON_LIBRARIES, type ICodePattern, type IComponentLibrary, type IComponentQuery, type IComponentSnippet, type IComponentStructure, type IConfigFile, type IDesignAnalysisResult, type IDesignContext, type IDirectoryStructure, type IEmbedding, type IEmbeddingConfig, type IEnhancedPrompt, type IEnhancementContext, type IExplicitFeedbackInput, type IFeedback, type IFigmaDesignToken, type IFigmaVariable, type IGeneratedArtifact, type IGeneratedFile, type IGeneration, type IImageAnalysis, type IImplicitSignal, type ILLMConfig, type ILLMGenerateOptions, type ILLMProvider, type ILLMResponse, type ILearningStats, type ILoRAConfig, type IModelPaths, INSPIRATION_SOURCES, type IPatternMatch, type IPresetConfig, type IProjectTemplate, type IPromptClassification, type IQualityScore, type IScaffoldOptions, type IScrapedPage, type IScreenElement, type ISearchResult, type ISimilarityResult, type IStyleContext, type IStyleRecommendation, type ITailwindMapping, type ITemplateSelectionCriteria, type ITrainingExample, type ITrainingStatus, type ITransition, type IValidationResult, type ImageType, type IndustryTag, LAYOUT_PATTERNS, type LLMProviderType, type ModelId, type MoodTag, OllamaProvider, OpenAIProvider, PRESETS, type PageTemplateType, type ProjectType, ReactGenerator, SPACING_SYSTEM, type Scale, type StateManagement$1 as StateManagement, SvelteGenerator, TYPE_SCALE, type VisualStyleId, VueGenerator, applyVisualStyle, brandToDesignContext, buildPromptEnhancerData, buildQualityScorerData, buildStyleRecommenderData, cancelTrainingJob, capitalize, checkTrainingReadiness, classifyPromptPair, classifyPromptText, cleanJsxSyntax, clearAllMicroInteractions, clearCompositions, clearHistory as clearDiversityHistory, clearRegistry, clearSessionCache, closeDatabase, composePageFromTemplate, composeSection, configureEmbeddings, configureModelDir, convertPathForFramework, convertStyleObjectToString, cosineSimilarity, createEmbedding, createError, createLogger, createProvider, createProviderWithFallback, createTrainingJob, customizeTemplate, deleteArtifact, deleteEmbeddings, designContextStore, detectOllama, embed, embedBatch, enhancePrompt, enhancePromptWithRAG, enhanceWithRules, ensureDirectories, ensurePatternsTable, escapeHtml, exportForAdapter, exportRawExamples, exportTrainingData, expressApiTemplate, extractDesignPatterns, extractSkeleton, feedbackBoostedSearch, findBestComposition, findSimilar, fingerprint, fullstackMonoTemplate, generateArtifactId, generateComponent, generateComponentFromLibrary, generateRandomId, getAdapterPath, getAggregateScore, getAllCompositions, getAllInteractions, getAllJobStatuses, getAllPacks, getAllSnippets, getAllTemplates, getAnimationsByCategory, getArtifact, getArtifactCount, getAvailableComponentLibraries, getAvailableComponentsForLibrary, getAvailablePatternsForLibrary, getAvailableTypes, getBaseDir, getBestMatch, getBestMatchWithFeedback, getByCategory, getByIndustry, getByMood, getColorSystem, getColorSystemsByMood, getComponentLibrariesForFramework, getComponentLibrary, getComposition, getConfig, getDatabase, getDefaultIconLibrary, getDiskUsage, getEmbedding, getEmbeddingConfig, getEmbeddingCount, getFallbackDesignReference, getFeedbackBoost, getFeedbackCount, getFeedbackStats, getFileExtension, getFileName, getFontPairing, getFontPairingsByMood, getInspirationByCategory, getInspirationByPriority, getInteractionsByCategory, getLatestJobStatus, getLayoutPattern, getLayoutPatternsByUseCase, getLearningStats, getMicroInteraction, getModelDownloadUrl, getModelPath, getModelPaths, getPack, getPatternStats, getPreset, getPrimaryDesignReference, getPromotablePatternsFromDb, getPromotionCandidates, getPromptEnhancerLLM, getQualityScorerLLM, getRecentArtifacts, getRecommendations, getRecommendedLibrary, getRegistrySize, getSimilarArtifacts, getSnippetById, getTemplate, getTopArtifacts, getTrainingDataPath, getTrainingSummary, getVariants, groupBy, hasEnoughData, hashSkeleton, htmlToJsxAttributes, includesCaseInsensitive, initializeBackendRegistry, initializeInteractions, initializeRegistry, injectAnimations, isAdapterAvailable, isArray, isDuplicateConsecutive, isFunction, isLikelyAccepted, isModelAvailable, isModelLoaded, isNetworkError, isNumber, isObject, isPromotable, isString, isTraining, isValidComponentName, isValidEmail, isValidHexColor, isValidProjectName, isValidUrl, jsxToHtml, jsxToHtmlAttributes, jsxToSvelte, listAdapters, listModels, listPresets, loadConfig, loadEmbeddings, logger, mergeStyles, needsEnhancement, nextAppTemplate, nextSaasTemplate, parseStyleString, pluralize, promotePattern, queryArtifacts, reactEventsToHtml, reactEventsToSvelte, reactSpaTemplate, recommendStyle, recordGeneration as recordDiversityGeneration, recordExplicitFeedback, recordGeneratedArtifact, recordGeneration$1 as recordGeneration, recordPattern, reduxToolkitPattern as reduxToolkitPatterns, registerComposition, registerInteraction, registerInteractions, registerPack, registerSnippet, registerSnippets, resetSchemaInit, retry, runPromotionCycle, safeJSONParse, sanitizeClassName, scoreQuality, scoreQualityWithRAG, searchBackendSnippets, searchComponents, searchPacks, selectTemplate, semanticSearch, setPromptEnhancerLLM, setQualityScorerLLM, setupComponentLibraryProject, sortBy, startTrainingJob, stateManagementPatterns, storeArtifact, storeDesignLearning, storeEmbedding, storeEmbeddings, suggestDiverseVariant, tanstackQueryPattern as tanstackQueryPatterns, templateList, templates, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, triggerPatternPromotion, truncate, unique, unloadModel, updateFeedbackScore, updateJobStatus, updateQualityScore, validateSnippet, validateSnippetStrict, writeJsonl, zustandPatterns };
|
|
2572
|
+
export { ANIMATION_PRESETS, type AdapterType, AngularGenerator, AnthropicProvider, type AppType, type Architecture, type ArtifactType, type BackendCategory, type BackendFramework, BaseGenerator, type BrandIdentityInput, COLOR_SYSTEMS, COMPONENT_LIBRARIES, type ComponentCategory, type ComponentLibrary, type ComponentLibraryId, type ComponentLibraryIntegration, type ComponentLibrarySetupOptions, type Config, DEFAULT_COLOR_SYSTEM, DEFAULT_CONTEXT, DEFAULT_DESIGN_CONTEXT, DEFAULT_FONT_PAIRING, DEFAULT_LORA_CONFIG, DEFAULT_MAX_TOKENS, DEFAULT_PRESET, DEFAULT_TEMPERATURE, DEFAULT_TIMEOUT_MS, type DeployTarget, FONT_PAIRINGS, type Framework, GeneratorFactory, HtmlGenerator, type IAccessibilityIssue, type IAccessibilityReport, type IArtifactQuery, type IBackendSnippet, ICON_LIBRARIES, type ICodePattern, type IComponentLibrary, type IComponentQuery, type IComponentSnippet, type IComponentStructure, type IConfigFile, type IDesignAnalysisResult, type IDesignContext, type IDirectoryStructure, type IEmbedding, type IEmbeddingConfig, type IEnhancedPrompt, type IEnhancementContext, type IExplicitFeedbackInput, type IFeedback, type IFigmaDesignToken, type IFigmaVariable, type IGeneratedArtifact, type IGeneratedFile, type IGeneration, type IImageAnalysis, type IImplicitSignal, type ILLMConfig, type ILLMGenerateOptions, type ILLMProvider, type ILLMResponse, type ILearningStats, type ILoRAConfig, type IModelPaths, INSPIRATION_SOURCES, type IPatternMatch, type IPresetConfig, type IProjectTemplate, type IPromptClassification, type IQualityScore, type IScaffoldOptions, type IScrapedPage, type IScreenElement, type ISearchResult, type ISidecarEnhanceResult, type ISidecarScoreResult, type ISidecarTrainingJob, type ISidecarVectorSearchResult, type ISimilarityResult, type IStyleContext, type IStyleRecommendation, type ITailwindMapping, type ITemplateSelectionCriteria, type ITrainingExample, type ITrainingStatus, type ITransition, type IValidationResult, type ImageType, type IndustryTag, LAYOUT_PATTERNS, type LLMProviderType, type ModelId, type MoodTag, OllamaProvider, OpenAIProvider, PRESETS, type PageTemplateType, type ProjectType, ReactGenerator, SPACING_SYSTEM, type Scale, type StateManagement$1 as StateManagement, SvelteGenerator, TYPE_SCALE, type VisualStyleId, VueGenerator, applyVisualStyle, brandToDesignContext, buildPromptEnhancerData, buildQualityScorerData, buildStyleRecommenderData, cancelTrainingJob, capitalize, checkTrainingReadiness, classifyPromptPair, classifyPromptText, cleanJsxSyntax, clearAllMicroInteractions, clearCompositions, clearHistory as clearDiversityHistory, clearRegistry, clearSessionCache, closeDatabase, composePageFromTemplate, composeSection, configureEmbeddings, configureModelDir, convertPathForFramework, convertStyleObjectToString, cosineSimilarity, createEmbedding, createError, createLogger, createProvider, createProviderWithFallback, createTrainingJob, customizeTemplate, deleteArtifact, deleteEmbeddings, designContextStore, detectOllama, embed, embedBatch, enhancePrompt, enhancePromptWithRAG, enhanceWithRules, ensureDirectories, ensurePatternsTable, escapeHtml, exportForAdapter, exportRawExamples, exportTrainingData, expressApiTemplate, extractDesignPatterns, extractSkeleton, feedbackBoostedSearch, findBestComposition, findSimilar, fingerprint, fullstackMonoTemplate, generateArtifactId, generateComponent, generateComponentFromLibrary, generateRandomId, getAdapterPath, getAggregateScore, getAllCompositions, getAllInteractions, getAllJobStatuses, getAllPacks, getAllSnippets, getAllTemplates, getAnimationsByCategory, getArtifact, getArtifactCount, getAvailableComponentLibraries, getAvailableComponentsForLibrary, getAvailablePatternsForLibrary, getAvailableTypes, getBaseDir, getBestMatch, getBestMatchWithFeedback, getByCategory, getByIndustry, getByMood, getColorSystem, getColorSystemsByMood, getComponentLibrariesForFramework, getComponentLibrary, getComposition, getConfig, getDatabase, getDefaultIconLibrary, getDiskUsage, getEmbedding, getEmbeddingConfig, getEmbeddingCount, getFallbackDesignReference, getFeedbackBoost, getFeedbackCount, getFeedbackStats, getFileExtension, getFileName, getFontPairing, getFontPairingsByMood, getInspirationByCategory, getInspirationByPriority, getInteractionsByCategory, getLatestJobStatus, getLayoutPattern, getLayoutPatternsByUseCase, getLearningStats, getMicroInteraction, getModelDownloadUrl, getModelPath, getModelPaths, getPack, getPatternStats, getPreset, getPrimaryDesignReference, getPromotablePatternsFromDb, getPromotionCandidates, getPromptEnhancerLLM, getQualityScorerLLM, getRecentArtifacts, getRecommendations, getRecommendedLibrary, getRegistrySize, getSidecarUrl, getSimilarArtifacts, getSnippetById, getTemplate, getTopArtifacts, getTrainingDataPath, getTrainingSummary, getVariants, groupBy, hasEnoughData, hashSkeleton, htmlToJsxAttributes, includesCaseInsensitive, initializeBackendRegistry, initializeInteractions, initializeRegistry, injectAnimations, isAdapterAvailable, isArray, isDuplicateConsecutive, isFunction, isLikelyAccepted, isModelAvailable, isModelLoaded, isNetworkError, isNumber, isObject, isPromotable, isSidecarAvailable, isString, isTraining, isValidComponentName, isValidEmail, isValidHexColor, isValidProjectName, isValidUrl, jsxToHtml, jsxToHtmlAttributes, jsxToSvelte, listAdapters, listModels, listPresets, loadConfig, loadEmbeddings, logger, mergeStyles, needsEnhancement, nextAppTemplate, nextSaasTemplate, parseStyleString, pluralize, promotePattern, queryArtifacts, reactEventsToHtml, reactEventsToSvelte, reactSpaTemplate, recommendStyle, recordGeneration as recordDiversityGeneration, recordExplicitFeedback, recordGeneratedArtifact, recordGeneration$1 as recordGeneration, recordPattern, reduxToolkitPattern as reduxToolkitPatterns, registerComposition, registerInteraction, registerInteractions, registerPack, registerSnippet, registerSnippets, resetAvailabilityCache, resetSchemaInit, retry, runPromotionCycle, safeJSONParse, sanitizeClassName, scoreQuality, scoreQualityWithRAG, searchBackendSnippets, searchComponents, searchPacks, selectTemplate, semanticSearch, setPromptEnhancerLLM, setQualityScorerLLM, setSidecarUrl, setupComponentLibraryProject, sidecarCancelTraining, sidecarEmbed, sidecarEmbedBatch, sidecarEnhancePrompt, sidecarGetTrainingStatus, sidecarScoreQuality, sidecarStartTraining, sidecarVectorIndex, sidecarVectorSearch, sortBy, startTrainingJob, stateManagementPatterns, storeArtifact, storeDesignLearning, storeEmbedding, storeEmbeddings, suggestDiverseVariant, tanstackQueryPattern as tanstackQueryPatterns, templateList, templates, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, triggerPatternPromotion, truncate, unique, unloadModel, updateFeedbackScore, updateJobStatus, updateQualityScore, validateSnippet, validateSnippetStrict, writeJsonl, zustandPatterns };
|
package/dist/index.js
CHANGED
|
@@ -4059,7 +4059,135 @@ async function createProviderWithFallback(config3) {
|
|
|
4059
4059
|
logger5.debug("No LLM provider available");
|
|
4060
4060
|
return null;
|
|
4061
4061
|
}
|
|
4062
|
-
|
|
4062
|
+
|
|
4063
|
+
// src/ml/sidecar-client.ts
|
|
4064
|
+
createLogger("sidecar-client");
|
|
4065
|
+
var sidecarUrl = "http://localhost:8100";
|
|
4066
|
+
var lastAvailabilityCheck = 0;
|
|
4067
|
+
var lastAvailabilityResult = false;
|
|
4068
|
+
var AVAILABILITY_CACHE_MS = 3e4;
|
|
4069
|
+
var REQUEST_TIMEOUT_MS = 5e3;
|
|
4070
|
+
function setSidecarUrl(url) {
|
|
4071
|
+
sidecarUrl = url;
|
|
4072
|
+
lastAvailabilityCheck = 0;
|
|
4073
|
+
lastAvailabilityResult = false;
|
|
4074
|
+
}
|
|
4075
|
+
function getSidecarUrl() {
|
|
4076
|
+
return sidecarUrl;
|
|
4077
|
+
}
|
|
4078
|
+
function decodeBase64Vector(b64) {
|
|
4079
|
+
const binary = atob(b64);
|
|
4080
|
+
const bytes = new Uint8Array(binary.length);
|
|
4081
|
+
for (let i = 0; i < binary.length; i++) {
|
|
4082
|
+
bytes[i] = binary.charCodeAt(i);
|
|
4083
|
+
}
|
|
4084
|
+
return new Float32Array(bytes.buffer);
|
|
4085
|
+
}
|
|
4086
|
+
async function sidecarFetch(path3, body, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
4087
|
+
const controller = new AbortController();
|
|
4088
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
4089
|
+
try {
|
|
4090
|
+
const resp = await fetch(`${sidecarUrl}${path3}`, {
|
|
4091
|
+
method: body ? "POST" : "GET",
|
|
4092
|
+
headers: body ? { "Content-Type": "application/json" } : void 0,
|
|
4093
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
4094
|
+
signal: controller.signal
|
|
4095
|
+
});
|
|
4096
|
+
if (!resp.ok) {
|
|
4097
|
+
throw new Error(`Sidecar ${path3}: ${resp.status} ${resp.statusText}`);
|
|
4098
|
+
}
|
|
4099
|
+
return await resp.json();
|
|
4100
|
+
} finally {
|
|
4101
|
+
clearTimeout(timer);
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
4104
|
+
async function isSidecarAvailable() {
|
|
4105
|
+
const now = Date.now();
|
|
4106
|
+
if (now - lastAvailabilityCheck < AVAILABILITY_CACHE_MS) {
|
|
4107
|
+
return lastAvailabilityResult;
|
|
4108
|
+
}
|
|
4109
|
+
try {
|
|
4110
|
+
const result = await sidecarFetch("/ready", void 0, 2e3);
|
|
4111
|
+
lastAvailabilityResult = result.ready;
|
|
4112
|
+
} catch {
|
|
4113
|
+
lastAvailabilityResult = false;
|
|
4114
|
+
}
|
|
4115
|
+
lastAvailabilityCheck = now;
|
|
4116
|
+
return lastAvailabilityResult;
|
|
4117
|
+
}
|
|
4118
|
+
function resetAvailabilityCache() {
|
|
4119
|
+
lastAvailabilityCheck = 0;
|
|
4120
|
+
lastAvailabilityResult = false;
|
|
4121
|
+
}
|
|
4122
|
+
async function sidecarEmbed(text) {
|
|
4123
|
+
const result = await sidecarFetch("/embed", { text });
|
|
4124
|
+
return decodeBase64Vector(result.vector);
|
|
4125
|
+
}
|
|
4126
|
+
async function sidecarEmbedBatch(texts) {
|
|
4127
|
+
const result = await sidecarFetch("/embed/batch", { texts });
|
|
4128
|
+
return result.vectors.map(decodeBase64Vector);
|
|
4129
|
+
}
|
|
4130
|
+
async function sidecarScoreQuality(prompt, code, componentType, framework) {
|
|
4131
|
+
return sidecarFetch(
|
|
4132
|
+
"/score",
|
|
4133
|
+
{
|
|
4134
|
+
prompt,
|
|
4135
|
+
code,
|
|
4136
|
+
component_type: componentType,
|
|
4137
|
+
framework
|
|
4138
|
+
},
|
|
4139
|
+
1e4
|
|
4140
|
+
);
|
|
4141
|
+
}
|
|
4142
|
+
async function sidecarEnhancePrompt(prompt, context) {
|
|
4143
|
+
return sidecarFetch(
|
|
4144
|
+
"/enhance",
|
|
4145
|
+
{
|
|
4146
|
+
prompt,
|
|
4147
|
+
component_type: context?.componentType,
|
|
4148
|
+
framework: context?.framework,
|
|
4149
|
+
style: context?.style,
|
|
4150
|
+
mood: context?.mood,
|
|
4151
|
+
industry: context?.industry
|
|
4152
|
+
},
|
|
4153
|
+
1e4
|
|
4154
|
+
);
|
|
4155
|
+
}
|
|
4156
|
+
async function sidecarVectorSearch(vector, topK = 5) {
|
|
4157
|
+
const b64 = Buffer.from(vector.buffer).toString("base64");
|
|
4158
|
+
return sidecarFetch("/vector/search", {
|
|
4159
|
+
vector: b64,
|
|
4160
|
+
top_k: topK
|
|
4161
|
+
});
|
|
4162
|
+
}
|
|
4163
|
+
async function sidecarVectorIndex(vectors) {
|
|
4164
|
+
const entries = vectors.map((v) => ({
|
|
4165
|
+
id: v.id,
|
|
4166
|
+
vector: Buffer.from(v.vector.buffer).toString("base64"),
|
|
4167
|
+
metadata: v.metadata
|
|
4168
|
+
}));
|
|
4169
|
+
return sidecarFetch("/vector/index", { entries });
|
|
4170
|
+
}
|
|
4171
|
+
async function sidecarStartTraining(adapterType, dataPath, config3) {
|
|
4172
|
+
return sidecarFetch(
|
|
4173
|
+
"/train/start",
|
|
4174
|
+
{
|
|
4175
|
+
adapter_type: adapterType,
|
|
4176
|
+
data_path: dataPath,
|
|
4177
|
+
config: config3
|
|
4178
|
+
},
|
|
4179
|
+
1e4
|
|
4180
|
+
);
|
|
4181
|
+
}
|
|
4182
|
+
async function sidecarGetTrainingStatus(jobId) {
|
|
4183
|
+
return sidecarFetch(`/train/status/${jobId}`);
|
|
4184
|
+
}
|
|
4185
|
+
async function sidecarCancelTraining(jobId) {
|
|
4186
|
+
return sidecarFetch(`/train/cancel/${jobId}`, {});
|
|
4187
|
+
}
|
|
4188
|
+
|
|
4189
|
+
// src/ml/embeddings.ts
|
|
4190
|
+
var logger7 = pino({ name: "ml-embeddings" });
|
|
4063
4191
|
var extractor = null;
|
|
4064
4192
|
var pipelineFn = null;
|
|
4065
4193
|
var DEFAULT_CONFIG = {
|
|
@@ -4087,20 +4215,27 @@ async function getExtractor() {
|
|
|
4087
4215
|
transformers.env.cacheDir = config.cacheDir;
|
|
4088
4216
|
}
|
|
4089
4217
|
}
|
|
4090
|
-
|
|
4218
|
+
logger7.info({ model: config.modelId, cache: config.cacheDir }, "Loading embedding model");
|
|
4091
4219
|
try {
|
|
4092
4220
|
extractor = await pipelineFn("feature-extraction", config.modelId, {
|
|
4093
4221
|
quantized: true
|
|
4094
4222
|
// Use quantized model for smaller size & faster CPU inference
|
|
4095
4223
|
});
|
|
4096
|
-
|
|
4224
|
+
logger7.info("Embedding model loaded");
|
|
4097
4225
|
return extractor;
|
|
4098
4226
|
} catch (err) {
|
|
4099
|
-
|
|
4227
|
+
logger7.error({ err, model: config.modelId }, "Failed to load embedding model");
|
|
4100
4228
|
throw new Error(`Failed to load embedding model: ${err}`);
|
|
4101
4229
|
}
|
|
4102
4230
|
}
|
|
4103
4231
|
async function embed(text) {
|
|
4232
|
+
try {
|
|
4233
|
+
if (await isSidecarAvailable()) {
|
|
4234
|
+
return await sidecarEmbed(text);
|
|
4235
|
+
}
|
|
4236
|
+
} catch (err) {
|
|
4237
|
+
logger7.debug({ err }, "Sidecar embed failed, falling back to Transformers.js");
|
|
4238
|
+
}
|
|
4104
4239
|
const ext = await getExtractor();
|
|
4105
4240
|
const output = await ext(text, { pooling: "mean", normalize: true });
|
|
4106
4241
|
if (output.data instanceof Float32Array) {
|
|
@@ -4110,6 +4245,13 @@ async function embed(text) {
|
|
|
4110
4245
|
}
|
|
4111
4246
|
async function embedBatch(texts) {
|
|
4112
4247
|
if (texts.length === 0) return [];
|
|
4248
|
+
try {
|
|
4249
|
+
if (await isSidecarAvailable()) {
|
|
4250
|
+
return await sidecarEmbedBatch(texts);
|
|
4251
|
+
}
|
|
4252
|
+
} catch (err) {
|
|
4253
|
+
logger7.debug({ err }, "Sidecar embedBatch failed, falling back");
|
|
4254
|
+
}
|
|
4113
4255
|
const ext = await getExtractor();
|
|
4114
4256
|
const results = [];
|
|
4115
4257
|
const BATCH_SIZE = 8;
|
|
@@ -4160,9 +4302,9 @@ function isModelLoaded() {
|
|
|
4160
4302
|
}
|
|
4161
4303
|
function unloadModel() {
|
|
4162
4304
|
extractor = null;
|
|
4163
|
-
|
|
4305
|
+
logger7.info("Embedding model unloaded");
|
|
4164
4306
|
}
|
|
4165
|
-
var
|
|
4307
|
+
var logger8 = pino({ name: "vector-index" });
|
|
4166
4308
|
var DIMENSIONS = 384;
|
|
4167
4309
|
var VSS_TABLE = "vss_embeddings";
|
|
4168
4310
|
var vssAvailable = false;
|
|
@@ -4177,11 +4319,11 @@ function initVectorIndex(db2) {
|
|
|
4177
4319
|
loadVss(db2);
|
|
4178
4320
|
db2.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${VSS_TABLE} USING vss0(vector(${DIMENSIONS}))`);
|
|
4179
4321
|
vssAvailable = true;
|
|
4180
|
-
|
|
4322
|
+
logger8.info("sqlite-vss loaded, vector index ready");
|
|
4181
4323
|
return true;
|
|
4182
4324
|
} catch (err) {
|
|
4183
4325
|
vssAvailable = false;
|
|
4184
|
-
|
|
4326
|
+
logger8.warn({ err }, "sqlite-vss unavailable, falling back to brute-force search");
|
|
4185
4327
|
return false;
|
|
4186
4328
|
}
|
|
4187
4329
|
}
|
|
@@ -4317,7 +4459,7 @@ function deleteEmbeddings(sourceType, db2) {
|
|
|
4317
4459
|
const result = db2.prepare("DELETE FROM embeddings WHERE source_type = ?").run(sourceType);
|
|
4318
4460
|
return result.changes;
|
|
4319
4461
|
}
|
|
4320
|
-
var
|
|
4462
|
+
var logger9 = pino({ name: "training-data-exporter" });
|
|
4321
4463
|
function exportRawExamples(db2, opts = {}) {
|
|
4322
4464
|
const minAbs = opts.minAbsScore ?? 0.3;
|
|
4323
4465
|
const limit = opts.limit ?? 1e4;
|
|
@@ -4386,7 +4528,7 @@ function writeJsonl(rows, filePath) {
|
|
|
4386
4528
|
const lines = rows.map((r) => JSON.stringify(r)).join("\n");
|
|
4387
4529
|
writeFileSync(filePath, `${lines}
|
|
4388
4530
|
`, "utf-8");
|
|
4389
|
-
|
|
4531
|
+
logger9.info({ path: filePath, rows: rows.length }, "Training data written");
|
|
4390
4532
|
return rows.length;
|
|
4391
4533
|
}
|
|
4392
4534
|
function exportForAdapter(adapter, db2, outputDir) {
|
|
@@ -4426,7 +4568,7 @@ function hasEnoughData(adapter, db2, includeSynthetic = false) {
|
|
|
4426
4568
|
const required = includeSynthetic ? syntheticThresholds[adapter] : feedbackThresholds[adapter];
|
|
4427
4569
|
return { ready: count >= required, count, required };
|
|
4428
4570
|
}
|
|
4429
|
-
var
|
|
4571
|
+
var logger10 = pino({ name: "model-manager" });
|
|
4430
4572
|
var DEFAULT_BASE_DIR = join(homedir(), ".uiforge");
|
|
4431
4573
|
var MODEL_REGISTRY = {
|
|
4432
4574
|
"qwen2.5-0.5b": {
|
|
@@ -4438,7 +4580,7 @@ var MODEL_REGISTRY = {
|
|
|
4438
4580
|
var _baseDir = DEFAULT_BASE_DIR;
|
|
4439
4581
|
function configureModelDir(baseDir) {
|
|
4440
4582
|
_baseDir = baseDir;
|
|
4441
|
-
|
|
4583
|
+
logger10.debug({ baseDir }, "Model directory configured");
|
|
4442
4584
|
}
|
|
4443
4585
|
function getBaseDir() {
|
|
4444
4586
|
return _baseDir;
|
|
@@ -4457,7 +4599,7 @@ function ensureDirectories() {
|
|
|
4457
4599
|
for (const dir of Object.values(paths)) {
|
|
4458
4600
|
if (!existsSync(dir)) {
|
|
4459
4601
|
mkdirSync(dir, { recursive: true });
|
|
4460
|
-
|
|
4602
|
+
logger10.debug({ dir }, "Created directory");
|
|
4461
4603
|
}
|
|
4462
4604
|
}
|
|
4463
4605
|
return paths;
|
|
@@ -4527,7 +4669,7 @@ function getDirectorySize(dir) {
|
|
|
4527
4669
|
}
|
|
4528
4670
|
return total;
|
|
4529
4671
|
}
|
|
4530
|
-
var
|
|
4672
|
+
var logger11 = pino({ name: "training-pipeline" });
|
|
4531
4673
|
var DEFAULT_LORA_CONFIG = {
|
|
4532
4674
|
rank: 8,
|
|
4533
4675
|
epochs: 3,
|
|
@@ -4602,7 +4744,7 @@ function checkTrainingReadiness(adapter, modelId, db2) {
|
|
|
4602
4744
|
}
|
|
4603
4745
|
return { ready: issues.length === 0, issues };
|
|
4604
4746
|
}
|
|
4605
|
-
function startTrainingJob(adapter, modelId, db2, config3 = DEFAULT_LORA_CONFIG, trainingCommand) {
|
|
4747
|
+
async function startTrainingJob(adapter, modelId, db2, config3 = DEFAULT_LORA_CONFIG, trainingCommand) {
|
|
4606
4748
|
const paths = ensureDirectories();
|
|
4607
4749
|
const { path: dataPath, count } = exportForAdapter(adapter, db2, paths.trainingData);
|
|
4608
4750
|
if (count === 0) {
|
|
@@ -4619,10 +4761,29 @@ function startTrainingJob(adapter, modelId, db2, config3 = DEFAULT_LORA_CONFIG,
|
|
|
4619
4761
|
};
|
|
4620
4762
|
}
|
|
4621
4763
|
const jobId = createTrainingJob(adapter, count, db2);
|
|
4764
|
+
try {
|
|
4765
|
+
if (await isSidecarAvailable()) {
|
|
4766
|
+
const sidecarJob = await sidecarStartTraining(adapter, dataPath, {
|
|
4767
|
+
rank: config3.rank,
|
|
4768
|
+
epochs: config3.epochs,
|
|
4769
|
+
learningRate: config3.learningRate,
|
|
4770
|
+
batchSize: config3.batchSize
|
|
4771
|
+
});
|
|
4772
|
+
updateJobStatus(jobId, "training", 10, db2);
|
|
4773
|
+
logger11.info({ adapter, jobId, sidecarJobId: sidecarJob.job_id }, "Training via sidecar");
|
|
4774
|
+
pollSidecarTraining(jobId, sidecarJob.job_id, adapter, db2);
|
|
4775
|
+
return {
|
|
4776
|
+
jobId,
|
|
4777
|
+
status: { adapter, status: "training", progress: 10, startedAt: Date.now() }
|
|
4778
|
+
};
|
|
4779
|
+
}
|
|
4780
|
+
} catch (err) {
|
|
4781
|
+
logger11.debug({ error: err.message }, "Sidecar training unavailable, falling back");
|
|
4782
|
+
}
|
|
4622
4783
|
const modelPath = getModelPath(modelId);
|
|
4623
4784
|
const adapterPath = getAdapterPath(adapter);
|
|
4624
4785
|
const cmd = trainingCommand ?? buildDefaultTrainingCommand(modelPath, dataPath, adapterPath, config3);
|
|
4625
|
-
|
|
4786
|
+
logger11.info({ adapter, jobId, count, modelId }, "Starting LoRA training job via child_process");
|
|
4626
4787
|
try {
|
|
4627
4788
|
const cmdParts = cmd.split(/\s+/);
|
|
4628
4789
|
const child = spawn(cmdParts[0], cmdParts.slice(1), {
|
|
@@ -4637,10 +4798,10 @@ function startTrainingJob(adapter, modelId, db2, config3 = DEFAULT_LORA_CONFIG,
|
|
|
4637
4798
|
if (progress !== null) {
|
|
4638
4799
|
updateJobStatus(jobId, "training", progress, db2);
|
|
4639
4800
|
}
|
|
4640
|
-
|
|
4801
|
+
logger11.debug({ adapter, line }, "Training output");
|
|
4641
4802
|
});
|
|
4642
4803
|
child.stderr?.on("data", (data) => {
|
|
4643
|
-
|
|
4804
|
+
logger11.warn({ adapter, stderr: data.toString().trim() }, "Training stderr");
|
|
4644
4805
|
});
|
|
4645
4806
|
child.on("close", (code) => {
|
|
4646
4807
|
activeJobs.delete(adapter);
|
|
@@ -4648,21 +4809,21 @@ function startTrainingJob(adapter, modelId, db2, config3 = DEFAULT_LORA_CONFIG,
|
|
|
4648
4809
|
try {
|
|
4649
4810
|
process.kill(-child.pid, "SIGTERM");
|
|
4650
4811
|
} catch (err) {
|
|
4651
|
-
|
|
4812
|
+
logger11.debug({ err }, "Process group already terminated");
|
|
4652
4813
|
}
|
|
4653
4814
|
}
|
|
4654
4815
|
if (code === 0 && existsSync(adapterPath)) {
|
|
4655
4816
|
updateJobStatus(jobId, "complete", 100, db2);
|
|
4656
|
-
|
|
4817
|
+
logger11.info({ adapter, jobId }, "Training completed successfully");
|
|
4657
4818
|
} else {
|
|
4658
4819
|
updateJobStatus(jobId, "failed", 0, db2, `Process exited with code ${code}`);
|
|
4659
|
-
|
|
4820
|
+
logger11.error({ adapter, jobId, code }, "Training failed");
|
|
4660
4821
|
}
|
|
4661
4822
|
});
|
|
4662
4823
|
child.on("error", (err) => {
|
|
4663
4824
|
activeJobs.delete(adapter);
|
|
4664
4825
|
updateJobStatus(jobId, "failed", 0, db2, err.message);
|
|
4665
|
-
|
|
4826
|
+
logger11.error({ adapter, jobId, error: err.message }, "Training process error");
|
|
4666
4827
|
});
|
|
4667
4828
|
child.unref();
|
|
4668
4829
|
} catch (err) {
|
|
@@ -4691,7 +4852,7 @@ function cancelTrainingJob(adapter, db2) {
|
|
|
4691
4852
|
updateJobStatus(row.id, "failed", 0, db2, "Cancelled by user");
|
|
4692
4853
|
}
|
|
4693
4854
|
}
|
|
4694
|
-
|
|
4855
|
+
logger11.info({ adapter }, "Training job cancelled");
|
|
4695
4856
|
return true;
|
|
4696
4857
|
} catch {
|
|
4697
4858
|
return false;
|
|
@@ -4709,6 +4870,21 @@ function getTrainingSummary(db2) {
|
|
|
4709
4870
|
activeCount: activeJobs.size
|
|
4710
4871
|
};
|
|
4711
4872
|
}
|
|
4873
|
+
function pollSidecarTraining(dbJobId, sidecarJobId, adapter, db2) {
|
|
4874
|
+
const interval = setInterval(async () => {
|
|
4875
|
+
try {
|
|
4876
|
+
const status = await sidecarGetTrainingStatus(sidecarJobId);
|
|
4877
|
+
updateJobStatus(dbJobId, status.status, status.progress, db2, status.error);
|
|
4878
|
+
if (status.status === "complete" || status.status === "failed" || status.status === "cancelled") {
|
|
4879
|
+
clearInterval(interval);
|
|
4880
|
+
}
|
|
4881
|
+
} catch {
|
|
4882
|
+
clearInterval(interval);
|
|
4883
|
+
updateJobStatus(dbJobId, "failed", 0, db2, "Lost connection to sidecar");
|
|
4884
|
+
}
|
|
4885
|
+
}, 5e3);
|
|
4886
|
+
interval.unref();
|
|
4887
|
+
}
|
|
4712
4888
|
function buildDefaultTrainingCommand(modelPath, dataPath, adapterPath, config3) {
|
|
4713
4889
|
return [
|
|
4714
4890
|
"llama-finetune",
|
|
@@ -4918,7 +5094,7 @@ function safeJSONParse(jsonString, defaultValue) {
|
|
|
4918
5094
|
}
|
|
4919
5095
|
|
|
4920
5096
|
// src/registry/database/store.ts
|
|
4921
|
-
var
|
|
5097
|
+
var logger12 = pino({ name: "design-references-db" });
|
|
4922
5098
|
var db = null;
|
|
4923
5099
|
function getDatabase(customPath) {
|
|
4924
5100
|
if (db) return db;
|
|
@@ -4934,7 +5110,7 @@ function getDatabase(customPath) {
|
|
|
4934
5110
|
db.pragma("synchronous = NORMAL");
|
|
4935
5111
|
db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)").run("schema_version", String(SCHEMA_VERSION));
|
|
4936
5112
|
initVectorIndex(db);
|
|
4937
|
-
|
|
5113
|
+
logger12.info({ dbPath: resolvedPath }, "Database opened/created");
|
|
4938
5114
|
return db;
|
|
4939
5115
|
}
|
|
4940
5116
|
function closeDatabase() {
|
|
@@ -5010,7 +5186,7 @@ function seedComponents(snippets2, database) {
|
|
|
5010
5186
|
d.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)").run("seed_count", String(snippets2.length));
|
|
5011
5187
|
});
|
|
5012
5188
|
seedAll();
|
|
5013
|
-
|
|
5189
|
+
logger12.info({ count: snippets2.length }, "Components seeded to database");
|
|
5014
5190
|
}
|
|
5015
5191
|
function hydrateSnippetsBatch(ids, d) {
|
|
5016
5192
|
if (ids.length === 0) return [];
|
|
@@ -5117,7 +5293,7 @@ function getDefaultDbPath() {
|
|
|
5117
5293
|
}
|
|
5118
5294
|
|
|
5119
5295
|
// src/ml/quality-scorer.ts
|
|
5120
|
-
var
|
|
5296
|
+
var logger13 = createLogger("quality-scorer");
|
|
5121
5297
|
var llmProvider = null;
|
|
5122
5298
|
function setQualityScorerLLM(provider) {
|
|
5123
5299
|
llmProvider = provider;
|
|
@@ -5128,12 +5304,29 @@ function getQualityScorerLLM() {
|
|
|
5128
5304
|
async function scoreQuality(prompt, generatedCode, params) {
|
|
5129
5305
|
const start = Date.now();
|
|
5130
5306
|
const heuristic = scoreWithHeuristics(prompt, generatedCode, params, start);
|
|
5307
|
+
try {
|
|
5308
|
+
if (await isSidecarAvailable()) {
|
|
5309
|
+
const result = await sidecarScoreQuality(prompt, generatedCode, params?.componentType, params?.framework);
|
|
5310
|
+
return blendScores(
|
|
5311
|
+
heuristic,
|
|
5312
|
+
{
|
|
5313
|
+
score: result.score,
|
|
5314
|
+
confidence: result.confidence,
|
|
5315
|
+
source: "model",
|
|
5316
|
+
latencyMs: Date.now() - start
|
|
5317
|
+
},
|
|
5318
|
+
start
|
|
5319
|
+
);
|
|
5320
|
+
}
|
|
5321
|
+
} catch (err) {
|
|
5322
|
+
logger13.debug({ error: err.message }, "Sidecar scoring failed");
|
|
5323
|
+
}
|
|
5131
5324
|
if (!llmProvider) return heuristic;
|
|
5132
5325
|
try {
|
|
5133
5326
|
const llmScore = await scoreWithLLM(prompt, generatedCode, params, start);
|
|
5134
5327
|
return blendScores(heuristic, llmScore, start);
|
|
5135
5328
|
} catch (err) {
|
|
5136
|
-
|
|
5329
|
+
logger13.debug({ error: err.message }, "LLM scoring failed, using heuristic");
|
|
5137
5330
|
return heuristic;
|
|
5138
5331
|
}
|
|
5139
5332
|
}
|
|
@@ -5335,7 +5528,7 @@ async function scoreQualityWithRAG(prompt, generatedCode, params) {
|
|
|
5335
5528
|
latencyMs: Date.now() - start
|
|
5336
5529
|
};
|
|
5337
5530
|
} catch (err) {
|
|
5338
|
-
|
|
5531
|
+
logger13.warn({ error: err.message }, "RAG quality scoring failed");
|
|
5339
5532
|
return baseScore;
|
|
5340
5533
|
}
|
|
5341
5534
|
}
|
|
@@ -5345,7 +5538,7 @@ async function isLikelyAccepted(prompt, generatedCode, params) {
|
|
|
5345
5538
|
}
|
|
5346
5539
|
|
|
5347
5540
|
// src/ml/prompt-enhancer.ts
|
|
5348
|
-
var
|
|
5541
|
+
var logger14 = createLogger("prompt-enhancer");
|
|
5349
5542
|
var llmProvider2 = null;
|
|
5350
5543
|
function setPromptEnhancerLLM(provider) {
|
|
5351
5544
|
llmProvider2 = provider;
|
|
@@ -5355,13 +5548,27 @@ function getPromptEnhancerLLM() {
|
|
|
5355
5548
|
}
|
|
5356
5549
|
async function enhancePrompt(prompt, context) {
|
|
5357
5550
|
const start = Date.now();
|
|
5551
|
+
try {
|
|
5552
|
+
if (await isSidecarAvailable()) {
|
|
5553
|
+
const result = await sidecarEnhancePrompt(prompt, context);
|
|
5554
|
+
return {
|
|
5555
|
+
enhanced: result.enhanced,
|
|
5556
|
+
original: prompt,
|
|
5557
|
+
source: result.source === "ollama" ? "model" : "rules",
|
|
5558
|
+
additions: result.additions,
|
|
5559
|
+
latencyMs: Date.now() - start
|
|
5560
|
+
};
|
|
5561
|
+
}
|
|
5562
|
+
} catch (err) {
|
|
5563
|
+
logger14.debug({ error: err.message }, "Sidecar enhancement failed");
|
|
5564
|
+
}
|
|
5358
5565
|
if (!llmProvider2) {
|
|
5359
5566
|
return enhanceWithRules(prompt, context, start);
|
|
5360
5567
|
}
|
|
5361
5568
|
try {
|
|
5362
5569
|
return await enhanceWithModel(prompt, context, start);
|
|
5363
5570
|
} catch (err) {
|
|
5364
|
-
|
|
5571
|
+
logger14.debug({ error: err.message }, "LLM enhancement failed, using rules");
|
|
5365
5572
|
return enhanceWithRules(prompt, context, start);
|
|
5366
5573
|
}
|
|
5367
5574
|
}
|
|
@@ -5452,7 +5659,7 @@ function enhanceWithRules(prompt, context, start = Date.now()) {
|
|
|
5452
5659
|
additions.push(...ragAdditions.additions);
|
|
5453
5660
|
}
|
|
5454
5661
|
} catch (err) {
|
|
5455
|
-
|
|
5662
|
+
logger14.debug({ error: err.message }, "RAG enhancement skipped");
|
|
5456
5663
|
}
|
|
5457
5664
|
return {
|
|
5458
5665
|
enhanced,
|
|
@@ -5513,7 +5720,7 @@ async function enhancePromptWithRAG(prompt, context) {
|
|
|
5513
5720
|
}
|
|
5514
5721
|
}
|
|
5515
5722
|
} catch (err) {
|
|
5516
|
-
|
|
5723
|
+
logger14.warn({ error: err.message }, "RAG enhancement failed");
|
|
5517
5724
|
}
|
|
5518
5725
|
return {
|
|
5519
5726
|
enhanced,
|
|
@@ -5574,7 +5781,7 @@ function addComponentHints(prompt, componentType, additions) {
|
|
|
5574
5781
|
}
|
|
5575
5782
|
return prompt;
|
|
5576
5783
|
}
|
|
5577
|
-
var
|
|
5784
|
+
var logger15 = pino({ name: "style-recommender" });
|
|
5578
5785
|
var INDUSTRY_STYLES = {
|
|
5579
5786
|
fintech: {
|
|
5580
5787
|
primaryColor: "#0F172A",
|
|
@@ -5678,7 +5885,7 @@ async function recommendStyle(prompt, context) {
|
|
|
5678
5885
|
try {
|
|
5679
5886
|
return await recommendWithRAG(prompt, context, db2);
|
|
5680
5887
|
} catch (err) {
|
|
5681
|
-
|
|
5888
|
+
logger15.warn({ error: err.message }, "RAG style recommendation failed, using heuristic");
|
|
5682
5889
|
}
|
|
5683
5890
|
}
|
|
5684
5891
|
return recommendWithHeuristic(prompt, context);
|
|
@@ -5925,7 +6132,7 @@ function extractMetadata(description, code) {
|
|
|
5925
6132
|
accessibilityNotes
|
|
5926
6133
|
};
|
|
5927
6134
|
}
|
|
5928
|
-
var
|
|
6135
|
+
var logger16 = pino({ name: "visual-styles" });
|
|
5929
6136
|
var styles = [];
|
|
5930
6137
|
var initialized = false;
|
|
5931
6138
|
function registerVisualStyle(style) {
|
|
@@ -5957,7 +6164,7 @@ function applyVisualStyle(snippet, style) {
|
|
|
5957
6164
|
}
|
|
5958
6165
|
}
|
|
5959
6166
|
if (droppedModifiers.length > 0) {
|
|
5960
|
-
|
|
6167
|
+
logger16.warn(
|
|
5961
6168
|
{ styleId: style.id, snippetId: snippet.id, droppedModifiers },
|
|
5962
6169
|
"Some style modifiers could not be applied - no matching role in snippet"
|
|
5963
6170
|
);
|
|
@@ -6143,7 +6350,7 @@ function initializeStyles() {
|
|
|
6143
6350
|
registerVisualStyle(style);
|
|
6144
6351
|
}
|
|
6145
6352
|
initialized = true;
|
|
6146
|
-
|
|
6353
|
+
logger16.debug("Visual styles initialized");
|
|
6147
6354
|
}
|
|
6148
6355
|
|
|
6149
6356
|
// src/registry/micro-interactions/entrance-fade.ts
|
|
@@ -7758,7 +7965,7 @@ function fingerprint(code) {
|
|
|
7758
7965
|
function isPromotable(pattern) {
|
|
7759
7966
|
return pattern.frequency >= 3 && pattern.avgScore > 0.5 && !pattern.promoted;
|
|
7760
7967
|
}
|
|
7761
|
-
var
|
|
7968
|
+
var logger17 = pino({ name: "feedback-tracker" });
|
|
7762
7969
|
var lastGeneration = /* @__PURE__ */ new Map();
|
|
7763
7970
|
function recordGeneration(gen, generatedCode, db2, promptContext) {
|
|
7764
7971
|
const codeHash = createHash("sha256").update(generatedCode).digest("hex").slice(0, 16);
|
|
@@ -7778,7 +7985,7 @@ function recordGeneration(gen, generatedCode, db2, promptContext) {
|
|
|
7778
7985
|
timestamp: Date.now()
|
|
7779
7986
|
};
|
|
7780
7987
|
storeFeedback(implicitFeedback, db2);
|
|
7781
|
-
|
|
7988
|
+
logger17.debug(
|
|
7782
7989
|
{ generationId: prev.id, score: implicitFeedback.score, signals: classification.signals.length },
|
|
7783
7990
|
"Implicit feedback recorded"
|
|
7784
7991
|
);
|
|
@@ -7803,7 +8010,7 @@ function recordExplicitFeedback(generationId, rating, db2, comment) {
|
|
|
7803
8010
|
timestamp: Date.now()
|
|
7804
8011
|
};
|
|
7805
8012
|
storeFeedback(feedback, db2);
|
|
7806
|
-
|
|
8013
|
+
logger17.info({ generationId, rating }, "Explicit feedback recorded");
|
|
7807
8014
|
return feedback;
|
|
7808
8015
|
}
|
|
7809
8016
|
function getAggregateScore(componentType, db2) {
|
|
@@ -7871,7 +8078,7 @@ function storeFeedback(feedback, db2) {
|
|
|
7871
8078
|
function upsertPattern(hash, skeleton, code, db2) {
|
|
7872
8079
|
const existing = db2.prepare("SELECT source_id FROM embeddings WHERE source_id = ? AND source_type = ?").get(hash, "description");
|
|
7873
8080
|
if (!existing) {
|
|
7874
|
-
|
|
8081
|
+
logger17.debug({ hash, skeleton }, "New code pattern detected");
|
|
7875
8082
|
}
|
|
7876
8083
|
}
|
|
7877
8084
|
function clearSessionCache() {
|
|
@@ -7952,7 +8159,7 @@ function getFeedbackBoost(componentType, db2) {
|
|
|
7952
8159
|
const boost = normalizedScore * FEEDBACK_BOOST_FACTOR;
|
|
7953
8160
|
return Math.max(0.7, Math.min(1.3, 1 + boost));
|
|
7954
8161
|
}
|
|
7955
|
-
var
|
|
8162
|
+
var logger18 = pino({ name: "pattern-promotion" });
|
|
7956
8163
|
var PATTERNS_TABLE = `
|
|
7957
8164
|
CREATE TABLE IF NOT EXISTS code_patterns (
|
|
7958
8165
|
id TEXT PRIMARY KEY,
|
|
@@ -8028,7 +8235,7 @@ function getPromotablePatternsFromDb(db2) {
|
|
|
8028
8235
|
}
|
|
8029
8236
|
function promotePattern(pattern, componentType, category, db2) {
|
|
8030
8237
|
if (!isPromotable(pattern)) {
|
|
8031
|
-
|
|
8238
|
+
logger18.debug({ patternId: pattern.id }, "Pattern not eligible for promotion");
|
|
8032
8239
|
return null;
|
|
8033
8240
|
}
|
|
8034
8241
|
const snippet = {
|
|
@@ -8067,13 +8274,13 @@ function promotePattern(pattern, componentType, category, db2) {
|
|
|
8067
8274
|
Math.floor(Date.now() / 1e3),
|
|
8068
8275
|
pattern.id
|
|
8069
8276
|
);
|
|
8070
|
-
|
|
8277
|
+
logger18.info(
|
|
8071
8278
|
{ patternId: pattern.id, snippetId: snippet.id, freq: pattern.frequency, score: pattern.avgScore },
|
|
8072
8279
|
"Pattern promoted to registry snippet"
|
|
8073
8280
|
);
|
|
8074
8281
|
return snippet;
|
|
8075
8282
|
} catch (err) {
|
|
8076
|
-
|
|
8283
|
+
logger18.error({ err, patternId: pattern.id }, "Failed to promote pattern");
|
|
8077
8284
|
return null;
|
|
8078
8285
|
}
|
|
8079
8286
|
}
|
|
@@ -8088,7 +8295,7 @@ function runPromotionCycle(db2) {
|
|
|
8088
8295
|
if (result) promoted++;
|
|
8089
8296
|
}
|
|
8090
8297
|
if (promoted > 0) {
|
|
8091
|
-
|
|
8298
|
+
logger18.info({ promoted, candidates: candidates.length }, "Promotion cycle complete");
|
|
8092
8299
|
}
|
|
8093
8300
|
return promoted;
|
|
8094
8301
|
}
|
|
@@ -8190,7 +8397,7 @@ function validateSnippetStrict(snippet) {
|
|
|
8190
8397
|
}
|
|
8191
8398
|
|
|
8192
8399
|
// src/registry/component-registry/index.ts
|
|
8193
|
-
var
|
|
8400
|
+
var logger19 = pino({ name: "component-registry" });
|
|
8194
8401
|
var registry = [];
|
|
8195
8402
|
var moodAffinities = {
|
|
8196
8403
|
bold: ["energetic", "premium"],
|
|
@@ -8208,27 +8415,27 @@ var moodAffinities = {
|
|
|
8208
8415
|
};
|
|
8209
8416
|
function registerSnippet(snippet) {
|
|
8210
8417
|
if (!snippet?.id || typeof snippet.id !== "string") {
|
|
8211
|
-
|
|
8418
|
+
logger19.warn({ snippet }, "Invalid snippet: missing or invalid id");
|
|
8212
8419
|
return;
|
|
8213
8420
|
}
|
|
8214
8421
|
if (!snippet.type || typeof snippet.type !== "string" || !snippet.type.trim()) {
|
|
8215
|
-
|
|
8422
|
+
logger19.warn({ snippet }, "Invalid snippet: missing or invalid type");
|
|
8216
8423
|
return;
|
|
8217
8424
|
}
|
|
8218
8425
|
if (!snippet.variant || typeof snippet.variant !== "string" || !snippet.variant.trim()) {
|
|
8219
|
-
|
|
8426
|
+
logger19.warn({ snippet }, "Invalid snippet: missing or invalid variant");
|
|
8220
8427
|
return;
|
|
8221
8428
|
}
|
|
8222
8429
|
if (!Array.isArray(snippet.tags)) {
|
|
8223
|
-
|
|
8430
|
+
logger19.warn({ snippet }, "Invalid snippet: tags must be an array");
|
|
8224
8431
|
return;
|
|
8225
8432
|
}
|
|
8226
8433
|
const validation = validateSnippet(snippet);
|
|
8227
8434
|
if (!validation.valid) {
|
|
8228
|
-
|
|
8435
|
+
logger19.warn({ id: snippet.id, errors: validation.errors }, "Snippet failed quality validation");
|
|
8229
8436
|
}
|
|
8230
8437
|
if (validation.warnings.length > 0) {
|
|
8231
|
-
|
|
8438
|
+
logger19.debug({ id: snippet.id, warnings: validation.warnings }, "Snippet quality warnings");
|
|
8232
8439
|
}
|
|
8233
8440
|
const normalized = {
|
|
8234
8441
|
...snippet,
|
|
@@ -8238,19 +8445,19 @@ function registerSnippet(snippet) {
|
|
|
8238
8445
|
};
|
|
8239
8446
|
const exists = registry.findIndex((s) => s.id === normalized.id);
|
|
8240
8447
|
if (exists >= 0) {
|
|
8241
|
-
|
|
8448
|
+
logger19.warn(
|
|
8242
8449
|
{ id: normalized.id, existingSource: registry[exists].name, newSource: normalized.name },
|
|
8243
8450
|
"Overwriting existing snippet with duplicate id"
|
|
8244
8451
|
);
|
|
8245
8452
|
registry[exists] = normalized;
|
|
8246
8453
|
} else {
|
|
8247
8454
|
registry.push(normalized);
|
|
8248
|
-
|
|
8455
|
+
logger19.debug({ id: normalized.id, name: normalized.name }, "Registered new snippet");
|
|
8249
8456
|
}
|
|
8250
8457
|
}
|
|
8251
8458
|
function clearRegistry() {
|
|
8252
8459
|
registry.length = 0;
|
|
8253
|
-
|
|
8460
|
+
logger19.debug("Registry cleared");
|
|
8254
8461
|
}
|
|
8255
8462
|
function registerSnippets(snippets2) {
|
|
8256
8463
|
for (const snippet of snippets2) {
|
|
@@ -8352,7 +8559,7 @@ function getByIndustry(industry) {
|
|
|
8352
8559
|
function applyVisualStyle2(snippet, styleId) {
|
|
8353
8560
|
const style = getVisualStyle(styleId);
|
|
8354
8561
|
if (!style) {
|
|
8355
|
-
|
|
8562
|
+
logger19.warn(
|
|
8356
8563
|
{ styleId, snippetId: snippet.id, snippetType: snippet.type },
|
|
8357
8564
|
"Visual style not found in applyVisualStyle, returning original snippet"
|
|
8358
8565
|
);
|
|
@@ -8381,7 +8588,7 @@ ${anim.keyframes}`;
|
|
|
8381
8588
|
} else {
|
|
8382
8589
|
const rootKey = "root" in newTailwindClasses ? "root" : "container" in newTailwindClasses ? "container" : keys[0];
|
|
8383
8590
|
if (rootKey !== "root" && rootKey !== "container") {
|
|
8384
|
-
|
|
8591
|
+
logger19.warn({ snippetId: snippet.id, animationIds, rootKey }, "No root/container key found, using first key");
|
|
8385
8592
|
}
|
|
8386
8593
|
newTailwindClasses[rootKey] = `${newTailwindClasses[rootKey]} ${additionalClasses.join(" ")}`.trim();
|
|
8387
8594
|
}
|
|
@@ -8438,7 +8645,7 @@ function getBestMatchWithFeedback(type, options, db2) {
|
|
|
8438
8645
|
return boosted[0].snippet;
|
|
8439
8646
|
}
|
|
8440
8647
|
} catch (err) {
|
|
8441
|
-
|
|
8648
|
+
logger19.error({ err, type }, "Failed to apply feedback boost, falling back to base search");
|
|
8442
8649
|
}
|
|
8443
8650
|
}
|
|
8444
8651
|
const results = searchComponents({
|
|
@@ -8457,13 +8664,13 @@ function triggerPatternPromotion(db2) {
|
|
|
8457
8664
|
const promoted = runPromotionCycle(db2);
|
|
8458
8665
|
return promoted;
|
|
8459
8666
|
} catch (err) {
|
|
8460
|
-
|
|
8667
|
+
logger19.warn({ error: err }, "Pattern promotion failed");
|
|
8461
8668
|
return 0;
|
|
8462
8669
|
}
|
|
8463
8670
|
}
|
|
8464
8671
|
|
|
8465
8672
|
// src/ml/design-to-training-data.ts
|
|
8466
|
-
var
|
|
8673
|
+
var logger20 = pino({ name: "design-to-training-data" });
|
|
8467
8674
|
function storeDesignLearning(analysis, generatedCode, componentName, framework, db2) {
|
|
8468
8675
|
const result = {
|
|
8469
8676
|
snippetsCreated: 0,
|
|
@@ -8478,12 +8685,12 @@ function storeDesignLearning(analysis, generatedCode, componentName, framework,
|
|
|
8478
8685
|
registerSnippet(snippet);
|
|
8479
8686
|
result.snippetsCreated++;
|
|
8480
8687
|
}
|
|
8481
|
-
|
|
8688
|
+
logger20.info(
|
|
8482
8689
|
{ count: snippets2.length, qualityScore: analysis.qualityScore },
|
|
8483
8690
|
"Component snippets created from design analysis"
|
|
8484
8691
|
);
|
|
8485
8692
|
} catch (err) {
|
|
8486
|
-
|
|
8693
|
+
logger20.error({ err }, "Failed to convert design to component snippets");
|
|
8487
8694
|
}
|
|
8488
8695
|
}
|
|
8489
8696
|
const feedbackEntries = generateFeedbackEntries(analysis, componentName, db2);
|
|
@@ -8491,7 +8698,7 @@ function storeDesignLearning(analysis, generatedCode, componentName, framework,
|
|
|
8491
8698
|
const patterns = detectAndStorePatterns(analysis, generatedCode, db2);
|
|
8492
8699
|
result.patternsDetected = patterns;
|
|
8493
8700
|
result.summary = generateSummary(analysis, result);
|
|
8494
|
-
|
|
8701
|
+
logger20.info(result, "Design learning stored successfully");
|
|
8495
8702
|
return result;
|
|
8496
8703
|
}
|
|
8497
8704
|
function convertToComponentSnippets(analysis, generatedCode, componentName, _framework) {
|
|
@@ -8566,7 +8773,7 @@ function generateFeedbackEntries(analysis, componentName, db2) {
|
|
|
8566
8773
|
);
|
|
8567
8774
|
count++;
|
|
8568
8775
|
}
|
|
8569
|
-
|
|
8776
|
+
logger20.info({ count, score }, "Feedback entries created from design analysis");
|
|
8570
8777
|
return count;
|
|
8571
8778
|
}
|
|
8572
8779
|
function detectAndStorePatterns(analysis, generatedCode, db2) {
|
|
@@ -8603,7 +8810,7 @@ function detectAndStorePatterns(analysis, generatedCode, db2) {
|
|
|
8603
8810
|
);
|
|
8604
8811
|
count++;
|
|
8605
8812
|
}
|
|
8606
|
-
|
|
8813
|
+
logger20.info({ count }, "Code patterns stored from design analysis");
|
|
8607
8814
|
return count;
|
|
8608
8815
|
}
|
|
8609
8816
|
function generateSummary(analysis, result) {
|
|
@@ -10904,7 +11111,7 @@ TODO: Implement HTML project generation.`
|
|
|
10904
11111
|
};
|
|
10905
11112
|
|
|
10906
11113
|
// src/generators/generator-factory.ts
|
|
10907
|
-
var
|
|
11114
|
+
var logger21 = createLogger("generator-factory");
|
|
10908
11115
|
var GeneratorFactory = class _GeneratorFactory {
|
|
10909
11116
|
static instance;
|
|
10910
11117
|
generators = /* @__PURE__ */ new Map();
|
|
@@ -10930,7 +11137,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
10930
11137
|
registerGenerator(framework, generatorClass) {
|
|
10931
11138
|
this.generators.set(framework, generatorClass);
|
|
10932
11139
|
this.instances.delete(framework);
|
|
10933
|
-
|
|
11140
|
+
logger21.info(`Registered generator for framework: ${framework}`);
|
|
10934
11141
|
}
|
|
10935
11142
|
/**
|
|
10936
11143
|
* Create a generator instance for the specified framework
|
|
@@ -10947,7 +11154,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
10947
11154
|
}
|
|
10948
11155
|
const instance = new GeneratorClass(framework);
|
|
10949
11156
|
this.instances.set(framework, instance);
|
|
10950
|
-
|
|
11157
|
+
logger21.info(`Created generator instance for framework: ${framework}`);
|
|
10951
11158
|
return instance;
|
|
10952
11159
|
}
|
|
10953
11160
|
/**
|
|
@@ -11017,7 +11224,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
11017
11224
|
*/
|
|
11018
11225
|
clearInstances() {
|
|
11019
11226
|
this.instances.clear();
|
|
11020
|
-
|
|
11227
|
+
logger21.info("Cleared all generator instances");
|
|
11021
11228
|
}
|
|
11022
11229
|
/**
|
|
11023
11230
|
* Clear instance for a specific framework
|
|
@@ -11025,7 +11232,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
11025
11232
|
*/
|
|
11026
11233
|
clearInstance(framework) {
|
|
11027
11234
|
this.instances.delete(framework);
|
|
11028
|
-
|
|
11235
|
+
logger21.info(`Cleared generator instance for framework: ${framework}`);
|
|
11029
11236
|
}
|
|
11030
11237
|
/**
|
|
11031
11238
|
* Unregister a generator
|
|
@@ -11034,7 +11241,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
11034
11241
|
unregisterGenerator(framework) {
|
|
11035
11242
|
this.generators.delete(framework);
|
|
11036
11243
|
this.instances.delete(framework);
|
|
11037
|
-
|
|
11244
|
+
logger21.info(`Unregistered generator for framework: ${framework}`);
|
|
11038
11245
|
}
|
|
11039
11246
|
/**
|
|
11040
11247
|
* Get default design context
|
|
@@ -11102,14 +11309,14 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
11102
11309
|
* Register default generators for all supported frameworks
|
|
11103
11310
|
*/
|
|
11104
11311
|
registerDefaultGenerators() {
|
|
11105
|
-
|
|
11312
|
+
logger21.info("Registering default generators");
|
|
11106
11313
|
this.registerGenerator("react", ReactGenerator);
|
|
11107
11314
|
this.registerGenerator("vue", VueGenerator);
|
|
11108
11315
|
this.registerGenerator("svelte", SvelteGenerator);
|
|
11109
11316
|
this.registerGenerator("angular", AngularGenerator);
|
|
11110
11317
|
this.registerGenerator("html", HtmlGenerator);
|
|
11111
11318
|
this.registerGenerator("nextjs", ReactGenerator);
|
|
11112
|
-
|
|
11319
|
+
logger21.info(`Registered ${this.getSupportedFrameworks().length} framework generators`);
|
|
11113
11320
|
}
|
|
11114
11321
|
};
|
|
11115
11322
|
function generateComponent(framework, componentType, props, designContext, componentLibrary) {
|
|
@@ -35041,7 +35248,7 @@ function initializePacks() {
|
|
|
35041
35248
|
registerPack(startupLandingPack);
|
|
35042
35249
|
registerPack(aiChatAppPack);
|
|
35043
35250
|
}
|
|
35044
|
-
var
|
|
35251
|
+
var logger22 = pino({ name: "registry-init" });
|
|
35045
35252
|
var initialized3 = false;
|
|
35046
35253
|
function initializeRegistry() {
|
|
35047
35254
|
if (initialized3) return;
|
|
@@ -35056,14 +35263,14 @@ function initializeRegistry() {
|
|
|
35056
35263
|
registerOrganisms();
|
|
35057
35264
|
const staticSnippets = getAllSnippets();
|
|
35058
35265
|
seedComponents(staticSnippets, db2);
|
|
35059
|
-
|
|
35266
|
+
logger22.info({ count: staticSnippets.length }, "Seeded DB from static files");
|
|
35060
35267
|
}
|
|
35061
35268
|
clearRegistry();
|
|
35062
35269
|
const dbSnippets = getAllComponents(db2);
|
|
35063
35270
|
registerSnippets(dbSnippets);
|
|
35064
|
-
|
|
35271
|
+
logger22.info({ count: dbSnippets.length }, "Loaded in-memory registry from DB");
|
|
35065
35272
|
} catch (err) {
|
|
35066
|
-
|
|
35273
|
+
logger22.warn({ err }, "DB unavailable, falling back to static files");
|
|
35067
35274
|
clearRegistry();
|
|
35068
35275
|
registerAtoms();
|
|
35069
35276
|
registerMolecules();
|
|
@@ -35072,12 +35279,12 @@ function initializeRegistry() {
|
|
|
35072
35279
|
try {
|
|
35073
35280
|
initializeCompositions();
|
|
35074
35281
|
} catch (err) {
|
|
35075
|
-
|
|
35282
|
+
logger22.warn({ err }, "Compositions init failed; page templates still work");
|
|
35076
35283
|
}
|
|
35077
35284
|
try {
|
|
35078
35285
|
initializePacks();
|
|
35079
35286
|
} catch (err) {
|
|
35080
|
-
|
|
35287
|
+
logger22.warn({ err }, "Packs init failed; template packs still available");
|
|
35081
35288
|
}
|
|
35082
35289
|
initialized3 = true;
|
|
35083
35290
|
}
|
|
@@ -38976,7 +39183,7 @@ var ARTIFACTS_SCHEMA = `
|
|
|
38976
39183
|
`;
|
|
38977
39184
|
|
|
38978
39185
|
// src/artifacts/artifact-store.ts
|
|
38979
|
-
var
|
|
39186
|
+
var logger23 = pino({ name: "artifact-store" });
|
|
38980
39187
|
var schemaInitialized = false;
|
|
38981
39188
|
function ensureSchema(db2) {
|
|
38982
39189
|
if (schemaInitialized) return;
|
|
@@ -39010,7 +39217,7 @@ function storeArtifact(artifact, db2) {
|
|
|
39010
39217
|
artifact.inspirationSources ? JSON.stringify(artifact.inspirationSources) : null,
|
|
39011
39218
|
artifact.createdAt
|
|
39012
39219
|
);
|
|
39013
|
-
|
|
39220
|
+
logger23.debug({ id: artifact.id, type: artifact.type }, "Artifact stored");
|
|
39014
39221
|
}
|
|
39015
39222
|
function getArtifact(id, db2) {
|
|
39016
39223
|
ensureSchema(db2);
|
|
@@ -39098,7 +39305,7 @@ function hydrateArtifact(row) {
|
|
|
39098
39305
|
createdAt: row.created_at
|
|
39099
39306
|
};
|
|
39100
39307
|
}
|
|
39101
|
-
var
|
|
39308
|
+
var logger24 = pino({ name: "learning-loop" });
|
|
39102
39309
|
var PROMOTION_QUALITY_THRESHOLD = 7;
|
|
39103
39310
|
var PROMOTION_FEEDBACK_THRESHOLD = 1;
|
|
39104
39311
|
var MIN_ARTIFACTS_FOR_STATS = 5;
|
|
@@ -39116,7 +39323,7 @@ function recordGeneratedArtifact(prompt, code, type, db2, options) {
|
|
|
39116
39323
|
createdAt: Date.now()
|
|
39117
39324
|
};
|
|
39118
39325
|
storeArtifact(artifact, db2);
|
|
39119
|
-
|
|
39326
|
+
logger24.info({ id: artifact.id, type }, "Generation recorded");
|
|
39120
39327
|
return artifact;
|
|
39121
39328
|
}
|
|
39122
39329
|
function getPromotionCandidates(db2) {
|
|
@@ -40837,7 +41044,7 @@ function applyDesignContextToPattern(content, designContext, customizations) {
|
|
|
40837
41044
|
}
|
|
40838
41045
|
|
|
40839
41046
|
// src/component-libraries/shadcn/index.ts
|
|
40840
|
-
var
|
|
41047
|
+
var logger25 = createLogger("shadcn");
|
|
40841
41048
|
function setupShadcnProject(options) {
|
|
40842
41049
|
const files = [];
|
|
40843
41050
|
const setupFiles = generateShadcnSetup(options.framework, options.projectName, void 0, []);
|
|
@@ -40852,7 +41059,7 @@ function setupShadcnProject(options) {
|
|
|
40852
41059
|
);
|
|
40853
41060
|
files.push(...componentFiles);
|
|
40854
41061
|
} catch (error) {
|
|
40855
|
-
|
|
41062
|
+
logger25.warn({ error }, `Failed to generate component ${componentName}:`);
|
|
40856
41063
|
}
|
|
40857
41064
|
});
|
|
40858
41065
|
}
|
|
@@ -40866,7 +41073,7 @@ function setupShadcnProject(options) {
|
|
|
40866
41073
|
);
|
|
40867
41074
|
files.push(...patternFiles);
|
|
40868
41075
|
} catch (error) {
|
|
40869
|
-
|
|
41076
|
+
logger25.warn({ error }, `Failed to generate pattern ${patternName}:`);
|
|
40870
41077
|
}
|
|
40871
41078
|
});
|
|
40872
41079
|
}
|
|
@@ -42415,6 +42622,6 @@ async function retry(fn, maxAttempts = 3, delay = 1e3) {
|
|
|
42415
42622
|
throw lastError;
|
|
42416
42623
|
}
|
|
42417
42624
|
|
|
42418
|
-
export { ANIMATION_PRESETS, AngularGenerator, AnthropicProvider, BaseGenerator, COLOR_SYSTEMS, COMPONENT_LIBRARIES, DEFAULT_COLOR_SYSTEM, DEFAULT_CONTEXT, DEFAULT_DESIGN_CONTEXT, DEFAULT_FONT_PAIRING, DEFAULT_LORA_CONFIG, DEFAULT_MAX_TOKENS, DEFAULT_PRESET, DEFAULT_TEMPERATURE, DEFAULT_TIMEOUT_MS, FONT_PAIRINGS, GeneratorFactory, HtmlGenerator, ICON_LIBRARIES, INSPIRATION_SOURCES, LAYOUT_PATTERNS, OllamaProvider, OpenAIProvider, PRESETS, ReactGenerator, SPACING_SYSTEM, SvelteGenerator, TYPE_SCALE, VueGenerator, applyVisualStyle2 as applyVisualStyle, brandToDesignContext, buildPromptEnhancerData, buildQualityScorerData, buildStyleRecommenderData, cancelTrainingJob, capitalize, checkTrainingReadiness, classifyPromptPair, classifyPromptText, cleanJsxSyntax, clearAllMicroInteractions, clearCompositions, clearHistory as clearDiversityHistory, clearRegistry, clearSessionCache, closeDatabase, composePageFromTemplate, composeSection, configureEmbeddings, configureModelDir, convertPathForFramework, convertStyleObjectToString, cosineSimilarity, createEmbedding, createError, createLogger, createProvider, createProviderWithFallback, createTrainingJob, customizeTemplate, deleteArtifact, deleteEmbeddings, designContextStore, detectOllama, embed, embedBatch, enhancePrompt, enhancePromptWithRAG, enhanceWithRules, ensureDirectories, ensurePatternsTable, escapeHtml, exportForAdapter, exportRawExamples, exportTrainingData, expressApiTemplate, extractDesignPatterns, extractSkeleton, feedbackBoostedSearch, findBestComposition, findSimilar, fingerprint, fullstackMonoTemplate, generateArtifactId, generateComponent, generateComponentFromLibrary, generateRandomId, getAdapterPath, getAggregateScore, getAllCompositions, getAllInteractions, getAllJobStatuses, getAllPacks, getAllSnippets, getAllTemplates, getAnimationsByCategory, getArtifact, getArtifactCount, getAvailableComponentLibraries, getAvailableComponentsForLibrary, getAvailablePatternsForLibrary, getAvailableTypes, getBaseDir, getBestMatch, getBestMatchWithFeedback, getByCategory, getByIndustry, getByMood, getColorSystem, getColorSystemsByMood, getComponentLibrariesForFramework, getComponentLibrary, getComposition, getConfig, getDatabase, getDefaultIconLibrary, getDiskUsage, getEmbedding, getEmbeddingConfig, getEmbeddingCount, getFallbackDesignReference, getFeedbackBoost, getFeedbackCount, getFeedbackStats, getFileExtension, getFileName, getFontPairing, getFontPairingsByMood, getInspirationByCategory, getInspirationByPriority, getInteractionsByCategory, getLatestJobStatus, getLayoutPattern, getLayoutPatternsByUseCase, getLearningStats, getMicroInteraction, getModelDownloadUrl, getModelPath, getModelPaths, getPack, getPatternStats, getPreset, getPrimaryDesignReference, getPromotablePatternsFromDb, getPromotionCandidates, getPromptEnhancerLLM, getQualityScorerLLM, getRecentArtifacts, getRecommendations, getRecommendedLibrary, getRegistrySize, getSimilarArtifacts, getSnippetById, getTemplate, getTopArtifacts, getTrainingDataPath, getTrainingSummary, getVariants, groupBy, hasEnoughData, hashSkeleton, htmlToJsxAttributes, includesCaseInsensitive, initializeBackendRegistry, initializeInteractions, initializeRegistry, injectAnimations, isAdapterAvailable, isArray, isDuplicateConsecutive, isFunction, isLikelyAccepted, isModelAvailable, isModelLoaded, isNetworkError, isNumber, isObject, isPromotable, isString, isTraining, isValidComponentName, isValidEmail, isValidHexColor, isValidProjectName, isValidUrl, jsxToHtml, jsxToHtmlAttributes, jsxToSvelte, listAdapters, listModels, listPresets, loadConfig, loadEmbeddings, logger, mergeStyles, needsEnhancement, nextAppTemplate, nextSaasTemplate, parseStyleString, pluralize, promotePattern, queryArtifacts, reactEventsToHtml, reactEventsToSvelte, reactSpaTemplate, recommendStyle, recordGeneration2 as recordDiversityGeneration, recordExplicitFeedback, recordGeneratedArtifact, recordGeneration, recordPattern, reduxToolkitPattern as reduxToolkitPatterns, registerComposition, registerInteraction, registerInteractions, registerPack, registerSnippet, registerSnippets, resetSchemaInit, retry, runPromotionCycle, safeJSONParse, sanitizeClassName, scoreQuality, scoreQualityWithRAG, searchBackendSnippets, searchComponents, searchPacks, selectTemplate, semanticSearch, setPromptEnhancerLLM, setQualityScorerLLM, setupComponentLibraryProject, sortBy, startTrainingJob, stateManagementPatterns, storeArtifact, storeDesignLearning, storeEmbedding, storeEmbeddings, suggestDiverseVariant, tanstackQueryPattern as tanstackQueryPatterns, templateList, templates2 as templates, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, triggerPatternPromotion, truncate, unique, unloadModel, updateFeedbackScore, updateJobStatus, updateQualityScore, validateSnippet, validateSnippetStrict, writeJsonl, zustandPatterns };
|
|
42625
|
+
export { ANIMATION_PRESETS, AngularGenerator, AnthropicProvider, BaseGenerator, COLOR_SYSTEMS, COMPONENT_LIBRARIES, DEFAULT_COLOR_SYSTEM, DEFAULT_CONTEXT, DEFAULT_DESIGN_CONTEXT, DEFAULT_FONT_PAIRING, DEFAULT_LORA_CONFIG, DEFAULT_MAX_TOKENS, DEFAULT_PRESET, DEFAULT_TEMPERATURE, DEFAULT_TIMEOUT_MS, FONT_PAIRINGS, GeneratorFactory, HtmlGenerator, ICON_LIBRARIES, INSPIRATION_SOURCES, LAYOUT_PATTERNS, OllamaProvider, OpenAIProvider, PRESETS, ReactGenerator, SPACING_SYSTEM, SvelteGenerator, TYPE_SCALE, VueGenerator, applyVisualStyle2 as applyVisualStyle, brandToDesignContext, buildPromptEnhancerData, buildQualityScorerData, buildStyleRecommenderData, cancelTrainingJob, capitalize, checkTrainingReadiness, classifyPromptPair, classifyPromptText, cleanJsxSyntax, clearAllMicroInteractions, clearCompositions, clearHistory as clearDiversityHistory, clearRegistry, clearSessionCache, closeDatabase, composePageFromTemplate, composeSection, configureEmbeddings, configureModelDir, convertPathForFramework, convertStyleObjectToString, cosineSimilarity, createEmbedding, createError, createLogger, createProvider, createProviderWithFallback, createTrainingJob, customizeTemplate, deleteArtifact, deleteEmbeddings, designContextStore, detectOllama, embed, embedBatch, enhancePrompt, enhancePromptWithRAG, enhanceWithRules, ensureDirectories, ensurePatternsTable, escapeHtml, exportForAdapter, exportRawExamples, exportTrainingData, expressApiTemplate, extractDesignPatterns, extractSkeleton, feedbackBoostedSearch, findBestComposition, findSimilar, fingerprint, fullstackMonoTemplate, generateArtifactId, generateComponent, generateComponentFromLibrary, generateRandomId, getAdapterPath, getAggregateScore, getAllCompositions, getAllInteractions, getAllJobStatuses, getAllPacks, getAllSnippets, getAllTemplates, getAnimationsByCategory, getArtifact, getArtifactCount, getAvailableComponentLibraries, getAvailableComponentsForLibrary, getAvailablePatternsForLibrary, getAvailableTypes, getBaseDir, getBestMatch, getBestMatchWithFeedback, getByCategory, getByIndustry, getByMood, getColorSystem, getColorSystemsByMood, getComponentLibrariesForFramework, getComponentLibrary, getComposition, getConfig, getDatabase, getDefaultIconLibrary, getDiskUsage, getEmbedding, getEmbeddingConfig, getEmbeddingCount, getFallbackDesignReference, getFeedbackBoost, getFeedbackCount, getFeedbackStats, getFileExtension, getFileName, getFontPairing, getFontPairingsByMood, getInspirationByCategory, getInspirationByPriority, getInteractionsByCategory, getLatestJobStatus, getLayoutPattern, getLayoutPatternsByUseCase, getLearningStats, getMicroInteraction, getModelDownloadUrl, getModelPath, getModelPaths, getPack, getPatternStats, getPreset, getPrimaryDesignReference, getPromotablePatternsFromDb, getPromotionCandidates, getPromptEnhancerLLM, getQualityScorerLLM, getRecentArtifacts, getRecommendations, getRecommendedLibrary, getRegistrySize, getSidecarUrl, getSimilarArtifacts, getSnippetById, getTemplate, getTopArtifacts, getTrainingDataPath, getTrainingSummary, getVariants, groupBy, hasEnoughData, hashSkeleton, htmlToJsxAttributes, includesCaseInsensitive, initializeBackendRegistry, initializeInteractions, initializeRegistry, injectAnimations, isAdapterAvailable, isArray, isDuplicateConsecutive, isFunction, isLikelyAccepted, isModelAvailable, isModelLoaded, isNetworkError, isNumber, isObject, isPromotable, isSidecarAvailable, isString, isTraining, isValidComponentName, isValidEmail, isValidHexColor, isValidProjectName, isValidUrl, jsxToHtml, jsxToHtmlAttributes, jsxToSvelte, listAdapters, listModels, listPresets, loadConfig, loadEmbeddings, logger, mergeStyles, needsEnhancement, nextAppTemplate, nextSaasTemplate, parseStyleString, pluralize, promotePattern, queryArtifacts, reactEventsToHtml, reactEventsToSvelte, reactSpaTemplate, recommendStyle, recordGeneration2 as recordDiversityGeneration, recordExplicitFeedback, recordGeneratedArtifact, recordGeneration, recordPattern, reduxToolkitPattern as reduxToolkitPatterns, registerComposition, registerInteraction, registerInteractions, registerPack, registerSnippet, registerSnippets, resetAvailabilityCache, resetSchemaInit, retry, runPromotionCycle, safeJSONParse, sanitizeClassName, scoreQuality, scoreQualityWithRAG, searchBackendSnippets, searchComponents, searchPacks, selectTemplate, semanticSearch, setPromptEnhancerLLM, setQualityScorerLLM, setSidecarUrl, setupComponentLibraryProject, sidecarCancelTraining, sidecarEmbed, sidecarEmbedBatch, sidecarEnhancePrompt, sidecarGetTrainingStatus, sidecarScoreQuality, sidecarStartTraining, sidecarVectorIndex, sidecarVectorSearch, sortBy, startTrainingJob, stateManagementPatterns, storeArtifact, storeDesignLearning, storeEmbedding, storeEmbeddings, suggestDiverseVariant, tanstackQueryPattern as tanstackQueryPatterns, templateList, templates2 as templates, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, triggerPatternPromotion, truncate, unique, unloadModel, updateFeedbackScore, updateJobStatus, updateQualityScore, validateSnippet, validateSnippetStrict, writeJsonl, zustandPatterns };
|
|
42419
42626
|
//# sourceMappingURL=index.js.map
|
|
42420
42627
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgespace/siza-gen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Siza AI generation engine — multi-framework code generation, component registry, and ML-powered quality scoring",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
"validate:tokens": "npx tsx src/scripts/check-semantic-tokens.ts",
|
|
29
29
|
"registry:stats": "npx tsx src/scripts/count-registry.ts",
|
|
30
30
|
"export:training": "npx tsx src/scripts/export-training-data.ts",
|
|
31
|
+
"seed:rules": "npx tsx src/scripts/seed-axe-core-rules.ts",
|
|
32
|
+
"ingest:hf": "npx tsx src/scripts/ingest-huggingface.ts",
|
|
33
|
+
"sidecar:start": "bash scripts/start-sidecar.sh",
|
|
34
|
+
"sidecar:test": "cd python && source .venv/bin/activate && python -m pytest tests/ -v",
|
|
35
|
+
"metrics:report": "curl -s http://localhost:8100/metrics/report | node -e \"process.stdin.resume();let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>console.log(JSON.stringify(JSON.parse(d),null,2)))\"",
|
|
31
36
|
"prepare": "husky install || true",
|
|
32
37
|
"prepublishOnly": "npm run build",
|
|
33
38
|
"prepack": "npm run build"
|