feat: Enhance provider components with detailed documentation and comments
- Added comprehensive comments and JSDoc-style documentation to NotificationProvider, ThemeProvider, UserProvider, and WebsiteThemeProvider for better clarity and maintainability. - Improved type definitions in index.ts for better code understanding and usage. - Introduced Docker support with Dockerfiles for various services including AI server, signaling server, and browser-use service. - Created a docker-compose.yml file to orchestrate multiple services including PostgreSQL, AI, scraper, and frontend. - Added a startup guide (startup.txt) for setting up the CRM environment on Ubuntu with Docker. - Included a .dockerignore file to exclude unnecessary files from Docker builds.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
// ── Module Generator ─────────────────────────────────────────────────
|
||||
// Generates missing internal modules from templates.
|
||||
// Supports built-in templates and custom .setup-templates/ directory.
|
||||
// Part of the self-healing setup pipeline — invoked when tsc reports
|
||||
// TS2307 errors for @/ imports that don't exist yet.
|
||||
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
@@ -12,6 +14,7 @@ const SETUP_TEMPLATES_DIR = path.join(ROOT, ".setup-templates");
|
||||
const REGISTRY_PATH = path.join(SETUP_TEMPLATES_DIR, "registry.json");
|
||||
const TEMPLATES_DIR = path.join(SETUP_TEMPLATES_DIR, "templates");
|
||||
|
||||
/** Maps internal import paths (e.g. "data/stickers") to their template file and optional params. */
|
||||
export interface TemplateRegistry {
|
||||
[importPath: string]: {
|
||||
template: string;
|
||||
@@ -20,6 +23,7 @@ export interface TemplateRegistry {
|
||||
};
|
||||
}
|
||||
|
||||
/** Result of a single module generation attempt. */
|
||||
export interface GenerationResult {
|
||||
success: boolean;
|
||||
filePath: string;
|
||||
@@ -28,18 +32,21 @@ export interface GenerationResult {
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/** Maps glob patterns (e.g. "@/hooks/*") to fallback template file names. */
|
||||
export interface FallbackRegistry {
|
||||
[pattern: string]: string;
|
||||
}
|
||||
|
||||
/** Load the template registry from .setup-templates/registry.json */
|
||||
/** Load the template registry from .setup-templates/registry.json, merging with built-in templates. */
|
||||
export function loadRegistry(): { templates: TemplateRegistry; fallbacks: FallbackRegistry } {
|
||||
// Built-in mappings for the most commonly imported modules
|
||||
const builtInTemplates: TemplateRegistry = {
|
||||
"data/stickers": { template: "stickers.ts" },
|
||||
"data/constants": { template: "constants.ts" },
|
||||
"lib/utils": { template: "utils.ts" },
|
||||
"types/index": { template: "types-index.ts", params: { inferFromUsage: true } },
|
||||
};
|
||||
// Directory-level catch-all fallbacks for unknown imports
|
||||
const builtInFallbacks: FallbackRegistry = {
|
||||
"@/data/*": "data-generic.ts",
|
||||
"@/lib/*": "lib-generic.ts",
|
||||
@@ -49,6 +56,7 @@ export function loadRegistry(): { templates: TemplateRegistry; fallbacks: Fallba
|
||||
"@/utils/*": "utils-generic.ts",
|
||||
};
|
||||
|
||||
// Merge in any custom templates from the .setup-templates directory
|
||||
try {
|
||||
if (fs.existsSync(REGISTRY_PATH)) {
|
||||
const content = fs.readFileSync(REGISTRY_PATH, "utf-8");
|
||||
@@ -64,10 +72,10 @@ export function loadRegistry(): { templates: TemplateRegistry; fallbacks: Fallba
|
||||
return { templates: builtInTemplates, fallbacks: builtInFallbacks };
|
||||
}
|
||||
|
||||
/** Match an internal path against fallback patterns */
|
||||
/** Match an internal path (e.g. "data/stickers") against glob fallback patterns. Converts glob to regex internally. */
|
||||
export function matchFallback(internalPath: string, fallbacks: FallbackRegistry): string | undefined {
|
||||
for (const [pattern, template] of Object.entries(fallbacks)) {
|
||||
// Convert glob pattern to regex
|
||||
// Convert glob pattern (e.g. "@/hooks/*") to a regular expression
|
||||
const regexStr = "^" + pattern
|
||||
.replace(/\//g, "\\/")
|
||||
.replace(/\./g, "\\.")
|
||||
@@ -82,7 +90,7 @@ export function matchFallback(internalPath: string, fallbacks: FallbackRegistry)
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Render a template with parameters */
|
||||
/** Render a template string by replacing {{ paramName }} placeholders with actual values. */
|
||||
function renderTemplate(templateContent: string, params: Record<string, unknown> = {}): string {
|
||||
let result = templateContent;
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
@@ -92,7 +100,7 @@ function renderTemplate(templateContent: string, params: Record<string, unknown>
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Get template content - first from custom templates dir, then built-in */
|
||||
/** Get template content — first tries the custom .setup-templates/templates dir, then falls back to built-in embedded templates. */
|
||||
function getTemplateContent(templateName: string): string {
|
||||
// Check custom templates first
|
||||
const customPath = path.join(TEMPLATES_DIR, templateName);
|
||||
@@ -100,7 +108,7 @@ function getTemplateContent(templateName: string): string {
|
||||
return fs.readFileSync(customPath, "utf-8");
|
||||
}
|
||||
|
||||
// Built-in templates (embedded)
|
||||
// Built-in templates (embedded in the script — no external file needed)
|
||||
const builtInTemplates: Record<string, string> = {
|
||||
"stickers.ts": `// ── Sticker Packs ─────────────────────────────────────────────────
|
||||
// Auto-generated by self-healing setup. Edit .setup-templates/templates/stickers.ts to customize.
|
||||
@@ -312,16 +320,16 @@ export interface DashboardStats {
|
||||
return builtInTemplates[templateName] || "";
|
||||
}
|
||||
|
||||
/** Generate a single missing module */
|
||||
/** Generate a single missing module: resolve template, render parameters, write to src/. */
|
||||
export function generateModule(
|
||||
internalPath: string,
|
||||
templates: TemplateRegistry,
|
||||
fallbacks: FallbackRegistry
|
||||
): GenerationResult {
|
||||
// Look up exact template first, then fall back to directory-level glob patterns
|
||||
let entry = templates[internalPath];
|
||||
let templateFile = entry?.template;
|
||||
|
||||
// Try fallback patterns
|
||||
if (!entry) {
|
||||
const fallbackTemplate = matchFallback(internalPath, fallbacks);
|
||||
if (fallbackTemplate) {
|
||||
@@ -349,10 +357,11 @@ export function generateModule(
|
||||
};
|
||||
}
|
||||
|
||||
// Replace template parameter placeholders with actual values
|
||||
const rendered = renderTemplate(templateContent, entry.params || {});
|
||||
const filePath = path.join(ROOT, "src", internalPath + (internalPath.endsWith(".ts") ? "" : ".ts"));
|
||||
|
||||
// Ensure directory exists
|
||||
// Ensure directory exists before writing
|
||||
const dir = path.dirname(filePath);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
@@ -377,7 +386,7 @@ export function generateModule(
|
||||
}
|
||||
}
|
||||
|
||||
/** Generate all missing modules for a list of internal paths */
|
||||
/** Generate all missing modules for a list of internal paths, logging each result. */
|
||||
export function generateAll(internalPaths: string[]): GenerationResult[] {
|
||||
const { templates, fallbacks } = loadRegistry();
|
||||
const results: GenerationResult[] = [];
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Parses `tsc --noEmit` or `npm run build` output to extract
|
||||
// "Module not found: Can't resolve '@/path/to/module'" errors.
|
||||
// Returns actionable missing module info for the generator.
|
||||
// Used by both setup.mjs (self-heal) and code-repair-agent.mjs.
|
||||
|
||||
export interface MissingModule {
|
||||
/** The import path that failed, e.g. "@/data/stickers" */
|
||||
@@ -20,7 +21,7 @@ export interface MissingModule {
|
||||
internalPath?: string;
|
||||
}
|
||||
|
||||
/** Parse TypeScript compiler output for missing module errors */
|
||||
/** Parse TypeScript compiler output for missing module errors (TS2307 + webpack-style "Can't resolve"). */
|
||||
export function parseMissingModules(tscOutput: string): MissingModule[] {
|
||||
const results: MissingModule[] = [];
|
||||
|
||||
@@ -74,12 +75,12 @@ export function parseMissingModules(tscOutput: string): MissingModule[] {
|
||||
});
|
||||
}
|
||||
|
||||
/** Filter to only internal (@/...) modules we can auto-generate */
|
||||
/** Filter to only internal (@/... or ~/...) modules we can auto-generate from templates. */
|
||||
export function filterGeneratable(modules: MissingModule[]): MissingModule[] {
|
||||
return modules.filter((m) => m.isInternal && m.internalPath);
|
||||
}
|
||||
|
||||
/** Group missing modules by internal path */
|
||||
/** Group missing modules by their normalized internal path (deduplicates same module imported from multiple files). */
|
||||
export function groupByInternalPath(modules: MissingModule[]): Map<string, MissingModule[]> {
|
||||
const groups = new Map<string, MissingModule[]>();
|
||||
for (const m of modules) {
|
||||
|
||||
Reference in New Issue
Block a user