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:
@@ -28,19 +28,23 @@ import { createRequire } from "node:module"
|
||||
const SELF = dirname(fileURLToPath(import.meta.url))
|
||||
const _require = createRequire(import.meta.url)
|
||||
const ROOT = resolve(SELF, "..")
|
||||
// Ollama endpoint and model can be overridden via environment variables
|
||||
const OLLAMA_HOST = process.env.OLLAMA_HOST || "http://localhost:11434"
|
||||
const MODEL = process.env.REPAIR_MODEL || "qwen2.5-coder:1.5b-base"
|
||||
// Safety limits: max repair iterations, minimum AI confidence to auto-apply, escalation timeout
|
||||
const MAX_ITERATIONS = 5
|
||||
const CONFIDENCE_THRESHOLD = 0.7
|
||||
const ESCALATION_TIMEOUT_MS = 30 * 60 * 1000 // 30 min
|
||||
|
||||
// ── Helpers ────────────────────────────────────────────────────────
|
||||
|
||||
/** Log a message with a level-based prefix for visual scanning of output. */
|
||||
function log(msg, level = "info") {
|
||||
const prefix = level === "error" ? "✗" : level === "warn" ? "⚠" : "✓"
|
||||
console.log(` ${prefix} [repair] ${msg}`)
|
||||
}
|
||||
|
||||
/** Run `npx tsc --noEmit` and return the output (success or failure). */
|
||||
function runTsc() {
|
||||
try {
|
||||
const out = execSync("npx tsc --noEmit", { stdio: "pipe", timeout: 60000, cwd: ROOT })
|
||||
@@ -50,6 +54,7 @@ function runTsc() {
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse TypeScript compiler output into structured error objects with file, line, column, and message. */
|
||||
function parseErrors(output) {
|
||||
const errors = []
|
||||
// Match: src/file.ts(line,col): error TSxxxx: message
|
||||
@@ -66,6 +71,7 @@ function parseErrors(output) {
|
||||
return errors
|
||||
}
|
||||
|
||||
/** Read source file lines surrounding the error, returning a snippet with context line offset. */
|
||||
function readContext(filePath, errorLine, contextLines = 20) {
|
||||
try {
|
||||
const lines = readFileSync(filePath, "utf-8").split("\n")
|
||||
@@ -83,6 +89,7 @@ function readContext(filePath, errorLine, contextLines = 20) {
|
||||
|
||||
// ── Ollama Integration ─────────────────────────────────────────────
|
||||
|
||||
/** Send a repair prompt to the Ollama model and return the raw response text. */
|
||||
async function queryOllama(prompt) {
|
||||
const response = await fetch(`${OLLAMA_HOST}/api/generate`, {
|
||||
method: "POST",
|
||||
@@ -99,6 +106,7 @@ async function queryOllama(prompt) {
|
||||
return data.response || ""
|
||||
}
|
||||
|
||||
/** Build a structured prompt for the AI model, including file path, error message, and surrounding code context. */
|
||||
function buildRepairPrompt(filePath, errorMessage, codeContext) {
|
||||
return `You are a TypeScript repair agent. Fix the following error.
|
||||
|
||||
@@ -122,6 +130,7 @@ Rules:
|
||||
- If you cannot determine a fix, set confidence to 0`
|
||||
}
|
||||
|
||||
/** Parse the AI's JSON response (handles optional markdown fences around the JSON block). */
|
||||
function parseFixResponse(text) {
|
||||
try {
|
||||
// Extract JSON from response (it might have markdown fences)
|
||||
@@ -133,6 +142,7 @@ function parseFixResponse(text) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Apply a fix suggestion to disk, returning success/failure and a backup of the original content. */
|
||||
function applyFix(filePath, fixSuggestion) {
|
||||
if (!fixSuggestion || !fixSuggestion.fix) return { applied: false, reason: "No fix suggestion" }
|
||||
|
||||
@@ -147,8 +157,8 @@ function applyFix(filePath, fixSuggestion) {
|
||||
|
||||
// ── Breaking Change Escalation ─────────────────────────────────────
|
||||
|
||||
/** Heuristic check: if any fix touches imports, exports, or deletions, consider it a breaking change. */
|
||||
function isBreakingChange(errors, fixes) {
|
||||
// Heuristic: if fix touches import structure or exports, it's breaking
|
||||
for (const fix of fixes) {
|
||||
if (!fix || !fix.fix) continue
|
||||
if (fix.fix.includes("export ") || fix.fix.includes("import ") || fix.fix.includes("delete ")) {
|
||||
@@ -158,6 +168,7 @@ function isBreakingChange(errors, fixes) {
|
||||
return false
|
||||
}
|
||||
|
||||
/** Log the breaking change, wait for the escalation timeout, then auto-apply. */
|
||||
async function escalateBreakingChange(errors, fixes) {
|
||||
const logFile = resolve(ROOT, "repair-escalation.log")
|
||||
const timestamp = new Date().toISOString()
|
||||
@@ -181,6 +192,7 @@ async function escalateBreakingChange(errors, fixes) {
|
||||
|
||||
// ── Git Auto-Commit ────────────────────────────────────────────────
|
||||
|
||||
/** Git commit all changes with a [bot]-prefixed message. Returns false on failure (non-blocking). */
|
||||
function gitCommit(message) {
|
||||
try {
|
||||
execSync("git add -A", { stdio: "pipe", cwd: ROOT })
|
||||
@@ -195,6 +207,7 @@ function gitCommit(message) {
|
||||
|
||||
// ── Main Repair Loop ───────────────────────────────────────────────
|
||||
|
||||
/** Single pass: run tsc, parse errors, ask AI for fixes, apply them, and verify. Returns result summary. */
|
||||
async function repairOnce(doCommit = false) {
|
||||
log("Running build check...")
|
||||
const build = runTsc()
|
||||
@@ -276,6 +289,7 @@ async function repairOnce(doCommit = false) {
|
||||
return { fixed: remainingErrors.length === 0, errors: remainingErrors, fixes }
|
||||
}
|
||||
|
||||
/** Run up to maxIterations repair passes, stopping once all errors are resolved or no progress is made. */
|
||||
async function repairLoop(maxIterations = MAX_ITERATIONS, doCommit = false) {
|
||||
for (let i = 0; i < maxIterations; i++) {
|
||||
log(`=== Repair iteration ${i + 1}/${maxIterations} ===`)
|
||||
@@ -293,8 +307,10 @@ async function repairLoop(maxIterations = MAX_ITERATIONS, doCommit = false) {
|
||||
|
||||
// ── Watch Mode ─────────────────────────────────────────────────────
|
||||
|
||||
/** Watch mode: monitor src/ for file changes and auto-repair errors. Falls back to polling if chokidar is unavailable. */
|
||||
function watchMode() {
|
||||
log("Watch mode active — monitoring src/ for changes...", "info")
|
||||
// Try loading chokidar; if not installed, fall back to simple interval polling
|
||||
const chokidar = (() => {
|
||||
try {
|
||||
return _require("chokidar")
|
||||
|
||||
Reference in New Issue
Block a user