@openqa/cli 1.3.4 → 2.1.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 +203 -6
- package/dist/agent/brain/diff-analyzer.js +140 -0
- package/dist/agent/brain/diff-analyzer.js.map +1 -0
- package/dist/agent/brain/llm-cache.js +47 -0
- package/dist/agent/brain/llm-cache.js.map +1 -0
- package/dist/agent/brain/llm-resilience.js +252 -0
- package/dist/agent/brain/llm-resilience.js.map +1 -0
- package/dist/agent/config/index.js +588 -0
- package/dist/agent/config/index.js.map +1 -0
- package/dist/agent/coverage/index.js +74 -0
- package/dist/agent/coverage/index.js.map +1 -0
- package/dist/agent/export/index.js +158 -0
- package/dist/agent/export/index.js.map +1 -0
- package/dist/agent/index-v2.js +2795 -0
- package/dist/agent/index-v2.js.map +1 -0
- package/dist/agent/index.js +369 -105
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/logger.js +41 -0
- package/dist/agent/logger.js.map +1 -0
- package/dist/agent/metrics.js +39 -0
- package/dist/agent/metrics.js.map +1 -0
- package/dist/agent/notifications/index.js +106 -0
- package/dist/agent/notifications/index.js.map +1 -0
- package/dist/agent/openapi/spec.js +338 -0
- package/dist/agent/openapi/spec.js.map +1 -0
- package/dist/agent/tools/project-runner.js +481 -0
- package/dist/agent/tools/project-runner.js.map +1 -0
- package/dist/cli/config.html.js +454 -0
- package/dist/cli/daemon.js +8810 -0
- package/dist/cli/dashboard.html.js +1622 -0
- package/dist/cli/env-config.js +391 -0
- package/dist/cli/env-routes.js +820 -0
- package/dist/cli/env.html.js +679 -0
- package/dist/cli/index.js +5980 -1896
- package/dist/cli/kanban.html.js +577 -0
- package/dist/cli/routes.js +895 -0
- package/dist/cli/routes.js.map +1 -0
- package/dist/cli/server.js +5855 -1860
- package/dist/database/index.js +485 -60
- package/dist/database/index.js.map +1 -1
- package/dist/database/sqlite.js +281 -0
- package/dist/database/sqlite.js.map +1 -0
- package/install.sh +19 -10
- package/package.json +19 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../database/sqlite.ts","../../agent/index-v2.ts","../../database/index.ts","../../agent/logger.ts","../../agent/config/index.ts","../../agent/config/schema.ts","../../agent/config/saas-config.ts","../../agent/errors.ts","../../agent/brain/index.ts","../../agent/brain/llm-resilience.ts","../../agent/brain/llm-cache.ts","../../agent/metrics.ts","../../agent/tools/browser.ts","../../agent/webhooks/git-listener.ts","../../agent/tools/project-runner.ts","../../agent/notifications/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import Database from 'better-sqlite3';\nimport { mkdirSync } from 'fs';\nimport { dirname } from 'path';\nimport type { TestSession, Action, Bug, KanbanTicket } from './index.js';\n\nexport class OpenQASQLiteDatabase {\n private db: Database.Database;\n\n constructor(dbPath: string = './data/openqa.db') {\n mkdirSync(dirname(dbPath), { recursive: true });\n this.db = new Database(dbPath);\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.migrate();\n }\n\n private migrate(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS config (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS test_sessions (\n id TEXT PRIMARY KEY,\n started_at TEXT NOT NULL,\n ended_at TEXT,\n status TEXT NOT NULL DEFAULT 'running',\n total_actions INTEGER NOT NULL DEFAULT 0,\n bugs_found INTEGER NOT NULL DEFAULT 0,\n metadata TEXT\n );\n\n CREATE TABLE IF NOT EXISTS actions (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n type TEXT NOT NULL,\n description TEXT NOT NULL,\n input TEXT,\n output TEXT,\n screenshot_path TEXT,\n FOREIGN KEY (session_id) REFERENCES test_sessions(id)\n );\n\n CREATE TABLE IF NOT EXISTS bugs (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT NOT NULL,\n severity TEXT NOT NULL DEFAULT 'medium',\n status TEXT NOT NULL DEFAULT 'open',\n github_issue_url TEXT,\n screenshot_path TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (session_id) REFERENCES test_sessions(id)\n );\n\n CREATE TABLE IF NOT EXISTS kanban_tickets (\n id TEXT PRIMARY KEY,\n bug_id TEXT,\n title TEXT NOT NULL,\n description TEXT NOT NULL,\n priority TEXT NOT NULL DEFAULT 'medium',\n column TEXT NOT NULL DEFAULT 'backlog',\n tags TEXT,\n screenshot_url TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n `);\n }\n\n // ── Config ──\n\n async getConfig(key: string): Promise<string | null> {\n const row = this.db.prepare('SELECT value FROM config WHERE key = ?').get(key) as { value: string } | undefined;\n return row?.value ?? null;\n }\n\n async setConfig(key: string, value: string): Promise<void> {\n this.db.prepare('INSERT OR REPLACE INTO config (key, value) VALUES (?, ?)').run(key, value);\n }\n\n async getAllConfig(): Promise<Record<string, string>> {\n const rows = this.db.prepare('SELECT key, value FROM config').all() as Array<{ key: string; value: string }>;\n return Object.fromEntries(rows.map(r => [r.key, r.value]));\n }\n\n async clearAllConfig(): Promise<void> {\n this.db.prepare('DELETE FROM config').run();\n }\n\n // ── Sessions ──\n\n async createSession(id: string, metadata?: Record<string, unknown>): Promise<TestSession> {\n const session: TestSession = {\n id,\n started_at: new Date().toISOString(),\n status: 'running',\n total_actions: 0,\n bugs_found: 0,\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n };\n this.db.prepare(`\n INSERT INTO test_sessions (id, started_at, status, total_actions, bugs_found, metadata)\n VALUES (?, ?, ?, ?, ?, ?)\n `).run(session.id, session.started_at, session.status, session.total_actions, session.bugs_found, session.metadata ?? null);\n return session;\n }\n\n async getSession(id: string): Promise<TestSession | null> {\n return (this.db.prepare('SELECT * FROM test_sessions WHERE id = ?').get(id) as TestSession) ?? null;\n }\n\n async updateSession(id: string, updates: Partial<TestSession>): Promise<void> {\n const fields = Object.keys(updates).map(k => `${k} = ?`).join(', ');\n const values = [...Object.values(updates), id];\n this.db.prepare(`UPDATE test_sessions SET ${fields} WHERE id = ?`).run(...values);\n }\n\n async getRecentSessions(limit = 10): Promise<TestSession[]> {\n return this.db.prepare('SELECT * FROM test_sessions ORDER BY started_at DESC LIMIT ?').all(limit) as TestSession[];\n }\n\n // ── Actions ──\n\n async createAction(action: Omit<Action, 'id' | 'timestamp'>): Promise<Action> {\n const newAction: Action = {\n id: `action_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,\n timestamp: new Date().toISOString(),\n ...action,\n };\n this.db.prepare(`\n INSERT INTO actions (id, session_id, timestamp, type, description, input, output, screenshot_path)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n newAction.id, newAction.session_id, newAction.timestamp,\n newAction.type, newAction.description,\n newAction.input ?? null, newAction.output ?? null, newAction.screenshot_path ?? null,\n );\n return newAction;\n }\n\n async getSessionActions(sessionId: string): Promise<Action[]> {\n return this.db.prepare('SELECT * FROM actions WHERE session_id = ? ORDER BY timestamp DESC').all(sessionId) as Action[];\n }\n\n // ── Bugs ──\n\n async createBug(bug: Omit<Bug, 'id' | 'created_at' | 'updated_at'>): Promise<Bug> {\n const newBug: Bug = {\n id: `bug_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n ...bug,\n };\n this.db.prepare(`\n INSERT INTO bugs (id, session_id, title, description, severity, status, github_issue_url, screenshot_path, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n newBug.id, newBug.session_id, newBug.title, newBug.description,\n newBug.severity, newBug.status,\n newBug.github_issue_url ?? null, newBug.screenshot_path ?? null,\n newBug.created_at, newBug.updated_at,\n );\n return newBug;\n }\n\n async updateBug(id: string, updates: Partial<Bug>): Promise<void> {\n const patch = { ...updates, updated_at: new Date().toISOString() };\n const fields = Object.keys(patch).map(k => `${k} = ?`).join(', ');\n const values = [...Object.values(patch), id];\n this.db.prepare(`UPDATE bugs SET ${fields} WHERE id = ?`).run(...values);\n }\n\n async getAllBugs(): Promise<Bug[]> {\n return this.db.prepare('SELECT * FROM bugs ORDER BY created_at DESC').all() as Bug[];\n }\n\n async getBugsByStatus(status: Bug['status']): Promise<Bug[]> {\n return this.db.prepare('SELECT * FROM bugs WHERE status = ? ORDER BY created_at DESC').all(status) as Bug[];\n }\n\n // ── Kanban ──\n\n async createKanbanTicket(ticket: Omit<KanbanTicket, 'id' | 'created_at' | 'updated_at'>): Promise<KanbanTicket> {\n const newTicket: KanbanTicket = {\n id: `ticket_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n ...ticket,\n };\n this.db.prepare(`\n INSERT INTO kanban_tickets (id, bug_id, title, description, priority, column, tags, screenshot_url, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n newTicket.id, newTicket.bug_id ?? null, newTicket.title, newTicket.description,\n newTicket.priority, newTicket.column,\n newTicket.tags ?? null, newTicket.screenshot_url ?? null,\n newTicket.created_at, newTicket.updated_at,\n );\n return newTicket;\n }\n\n async updateKanbanTicket(id: string, updates: Partial<KanbanTicket>): Promise<void> {\n const patch = { ...updates, updated_at: new Date().toISOString() };\n const fields = Object.keys(patch).map(k => `\"${k}\" = ?`).join(', ');\n const values = [...Object.values(patch), id];\n this.db.prepare(`UPDATE kanban_tickets SET ${fields} WHERE id = ?`).run(...values);\n }\n\n async getKanbanTickets(): Promise<KanbanTicket[]> {\n return this.db.prepare('SELECT * FROM kanban_tickets ORDER BY created_at DESC').all() as KanbanTicket[];\n }\n\n async getKanbanTicketsByColumn(column: KanbanTicket['column']): Promise<KanbanTicket[]> {\n return this.db.prepare('SELECT * FROM kanban_tickets WHERE \"column\" = ? ORDER BY created_at DESC').all(column) as KanbanTicket[];\n }\n\n async deleteKanbanTicket(id: string): Promise<void> {\n this.db.prepare('DELETE FROM kanban_tickets WHERE id = ?').run(id);\n }\n\n // ── Storage / Cleanup ──\n\n async pruneOldSessions(maxAgeDays: number): Promise<{ sessionsRemoved: number; actionsRemoved: number }> {\n const cutoff = new Date(Date.now() - maxAgeDays * 86400000).toISOString();\n const oldSessions = this.db.prepare('SELECT id FROM test_sessions WHERE started_at < ?').all(cutoff) as Array<{ id: string }>;\n const ids = oldSessions.map(s => s.id);\n if (ids.length === 0) return { sessionsRemoved: 0, actionsRemoved: 0 };\n\n const placeholders = ids.map(() => '?').join(', ');\n const actionsResult = this.db.prepare(`DELETE FROM actions WHERE session_id IN (${placeholders})`).run(...ids);\n this.db.prepare(`DELETE FROM test_sessions WHERE id IN (${placeholders})`).run(...ids);\n\n return { sessionsRemoved: ids.length, actionsRemoved: actionsResult.changes };\n }\n\n async getStorageStats(): Promise<{ sessions: number; actions: number; bugs: number; tickets: number }> {\n const count = (table: string): number =>\n (this.db.prepare(`SELECT COUNT(*) as n FROM ${table}`).get() as { n: number }).n;\n return {\n sessions: count('test_sessions'),\n actions: count('actions'),\n bugs: count('bugs'),\n tickets: count('kanban_tickets'),\n };\n }\n\n // ── Compat helpers (used by daemon.ts) ──\n\n async getActiveAgents() {\n const sessions = await this.getRecentSessions(1);\n const current = sessions[0];\n const isRunning = current?.status === 'running';\n return [{\n name: 'Main Agent',\n status: isRunning ? 'running' : 'idle',\n purpose: 'Autonomous QA orchestration',\n performance: current ? Math.min(100, Math.round((current.total_actions / 100) * 100)) : 0,\n tasks: current?.total_actions ?? 0,\n }];\n }\n\n async getCurrentTasks() {\n const sessions = await this.getRecentSessions(1);\n if (!sessions[0]) return [];\n const actions = await this.getSessionActions(sessions[0].id);\n return actions.slice(0, 10).map((a, i) => ({\n id: a.id, name: a.type, status: i === 0 && sessions[0].status === 'running' ? 'running' : 'completed',\n progress: i === 0 && sessions[0].status === 'running' ? '65%' : '100%',\n agent: 'Main Agent', started_at: a.timestamp, result: a.output || a.description,\n }));\n }\n\n async getCurrentIssues() {\n const bugs = await this.getAllBugs();\n return bugs.slice(0, 10).map(b => ({\n id: b.id, title: b.title, description: b.description,\n severity: b.severity, status: b.status, discovered_at: b.created_at, agent: 'Main Agent',\n }));\n }\n\n async close(): Promise<void> {\n this.db.close();\n }\n}\n","import { EventEmitter } from 'events';\nimport { OpenQADatabase } from '../database/index.js';\nimport { logger } from './logger.js';\nimport { ConfigManager } from './config/index.js';\nimport { SaaSConfigManager, createQuickConfig } from './config/saas-config.js';\nimport { OpenQABrain, SaaSConfig, GeneratedTest, DynamicAgent } from './brain/index.js';\nimport { BrowserTools } from './tools/browser.js';\nimport { GitHubTools } from './tools/github.js';\nimport { KanbanTools } from './tools/kanban.js';\nimport { GitListener, GitEvent } from './webhooks/git-listener.js';\nimport { ProjectRunner, type ProjectStatus, type TestRunResult } from './tools/project-runner.js';\nimport { NotificationService } from './notifications/index.js';\n\nexport class OpenQAAgentV2 extends EventEmitter {\n private db: OpenQADatabase;\n private config: ConfigManager;\n private saasConfigManager: SaaSConfigManager;\n private brain: OpenQABrain | null = null;\n private browserTools: BrowserTools | null = null;\n private gitListener: GitListener | null = null;\n private projectRunner: ProjectRunner;\n private notifications: NotificationService | null = null;\n private sessionId: string = '';\n private isRunning: boolean = false;\n\n constructor(configPath?: string) {\n super();\n this.config = new ConfigManager(configPath);\n const cfg = this.config.getConfigSync();\n this.db = new OpenQADatabase(cfg.database?.path || undefined);\n this.saasConfigManager = new SaaSConfigManager(this.db);\n this.projectRunner = new ProjectRunner();\n\n // Forward project runner events\n for (const event of ['install-start', 'install-progress', 'install-complete', 'server-starting', 'server-ready', 'server-stopped', 'test-start', 'test-progress', 'test-complete']) {\n this.projectRunner.on(event, (data) => this.emit(event, data));\n }\n }\n\n /**\n * Configure the SaaS application to test\n * This is the main entry point for users\n */\n configureSaaS(config: {\n name: string;\n description: string;\n url: string;\n repoUrl?: string;\n localPath?: string;\n directives?: string[];\n auth?: {\n type: 'none' | 'basic' | 'oauth' | 'session';\n credentials?: { username: string; password: string };\n };\n }): SaaSConfig {\n const saasConfig: SaaSConfig = {\n name: config.name,\n description: config.description,\n url: config.url,\n repoUrl: config.repoUrl,\n localPath: config.localPath,\n directives: config.directives,\n authInfo: config.auth ? {\n type: config.auth.type,\n testCredentials: config.auth.credentials\n } : { type: 'none' }\n };\n\n return this.saasConfigManager.configure(saasConfig);\n }\n\n /**\n * Quick setup with minimal configuration\n */\n quickSetup(name: string, description: string, url: string): SaaSConfig {\n return this.saasConfigManager.configure(\n createQuickConfig(name, description, url)\n );\n }\n\n /**\n * Add a directive (instruction for the agent)\n */\n addDirective(directive: string) {\n this.saasConfigManager.addDirective(directive);\n }\n\n /**\n * Set repository URL for code analysis\n */\n setRepository(url: string) {\n this.saasConfigManager.setRepoUrl(url);\n }\n\n /**\n * Set local path for code analysis\n */\n setLocalPath(path: string) {\n this.saasConfigManager.setLocalPath(path);\n }\n\n /**\n * Initialize the brain and start analyzing\n */\n async initialize() {\n const saasConfig = this.saasConfigManager.getConfig();\n if (!saasConfig) {\n throw new Error('SaaS not configured. Call configureSaaS() first.');\n }\n\n const cfg = await this.config.getConfig();\n this.sessionId = `session_${Date.now()}`;\n\n await this.db.createSession(this.sessionId, {\n saas: saasConfig,\n started_at: new Date().toISOString()\n });\n\n // Set up notifications if configured\n if (cfg.notifications?.slack || cfg.notifications?.discord) {\n this.notifications = new NotificationService({\n slack: cfg.notifications.slack,\n discord: cfg.notifications.discord,\n });\n }\n\n this.brain = new OpenQABrain(\n this.db,\n {\n provider: cfg.llm.provider,\n apiKey: cfg.llm.apiKey || process.env.OPENAI_API_KEY || '',\n model: cfg.llm.model\n },\n saasConfig\n );\n\n this.browserTools = new BrowserTools(this.db, this.sessionId);\n\n const log = logger.child({ session: this.sessionId, app: saasConfig.name });\n\n // Forward brain events\n this.brain.on('test-generated', (test: GeneratedTest) => {\n this.emit('test-generated', test);\n log.info('Test generated', { name: test.name, type: test.type });\n });\n\n this.brain.on('agent-created', (agent: DynamicAgent) => {\n this.emit('agent-created', agent);\n log.info('Agent created', { name: agent.name });\n });\n\n this.brain.on('test-started', (test: GeneratedTest) => {\n this.emit('test-started', test);\n });\n\n this.brain.on('test-completed', (test: GeneratedTest) => {\n this.emit('test-completed', test);\n log.info('Test completed', { name: test.name, status: test.status });\n });\n\n this.brain.on('thinking', (thought: Record<string, unknown>) => {\n this.emit('thinking', thought);\n });\n\n this.brain.on('analysis-complete', (analysis: Record<string, unknown>) => {\n this.emit('analysis-complete', analysis);\n });\n\n this.brain.on('session-complete', (stats: Record<string, unknown>) => {\n this.emit('session-complete', stats);\n if (this.notifications) {\n this.notifications.notifySessionComplete({\n sessionId: this.sessionId,\n testsGenerated: Number(stats.testsGenerated ?? 0),\n agentsCreated: Number(stats.agentsCreated ?? 0),\n }).catch((e) => log.error('Notification failed', { error: e instanceof Error ? e.message : String(e) }));\n }\n });\n\n log.info('OpenQA initialized', {\n url: saasConfig.url,\n repoUrl: saasConfig.repoUrl,\n localPath: saasConfig.localPath,\n directives: saasConfig.directives?.length ?? 0,\n });\n }\n\n /**\n * Run the brain in autonomous mode\n * The agent will analyze, think, generate tests, and execute them\n */\n async runAutonomous(maxIterations: number = 10) {\n if (!this.brain) {\n await this.initialize();\n }\n\n this.isRunning = true;\n logger.info('Starting autonomous QA session', { session: this.sessionId });\n \n await this.brain!.runAutonomously(maxIterations);\n \n this.isRunning = false;\n }\n\n /**\n * Analyze the application and get suggestions\n */\n async analyze() {\n if (!this.brain) {\n await this.initialize();\n }\n\n return this.brain!.analyze();\n }\n\n /**\n * Generate a specific test\n */\n async generateTest(type: GeneratedTest['type'], target: string, context?: string) {\n if (!this.brain) {\n await this.initialize();\n }\n\n return this.brain!.generateTest(type, target, context);\n }\n\n /**\n * Create a custom agent for a specific purpose\n */\n async createAgent(purpose: string) {\n if (!this.brain) {\n await this.initialize();\n }\n\n return this.brain!.createDynamicAgent(purpose);\n }\n\n /**\n * Execute a generated test\n */\n async runTest(testId: string) {\n if (!this.brain) {\n throw new Error('Brain not initialized');\n }\n\n return this.brain.executeTest(testId);\n }\n\n /**\n * Start listening for Git events (merges, pipelines)\n */\n async startGitListener() {\n const cfg = await this.config.getConfig();\n const saasConfig = this.saasConfigManager.getConfig();\n\n if (cfg.github?.token && cfg.github?.owner && cfg.github?.repo) {\n this.gitListener = new GitListener({\n provider: 'github',\n token: cfg.github.token,\n owner: cfg.github.owner,\n repo: cfg.github.repo,\n branch: 'main',\n pollIntervalMs: 60000\n });\n\n this.gitListener.on('merge', async (event: GitEvent) => {\n logger.info('Merge detected', { branch: event.branch });\n this.emit('git-merge', event);\n \n // Run autonomous session on merge\n await this.runAutonomous();\n });\n\n this.gitListener.on('pipeline-success', async (event: GitEvent) => {\n logger.info('Pipeline success');\n this.emit('git-pipeline-success', event);\n \n // Run autonomous session on successful deploy\n await this.runAutonomous();\n });\n\n await this.gitListener.start();\n logger.info('Git listener started');\n }\n }\n\n /**\n * Setup a project: detect, install deps, optionally start dev server\n */\n async setupProject(repoPath: string, options?: { startServer?: boolean }): Promise<ProjectStatus> {\n const projectType = this.projectRunner.detectProjectType(repoPath);\n logger.info('Project detected', { language: projectType.language, framework: projectType.framework, packageManager: projectType.packageManager });\n\n await this.projectRunner.installDependencies(repoPath);\n logger.info('Dependencies installed');\n\n if (options?.startServer && projectType.devCommand) {\n const { url } = await this.projectRunner.startDevServer(repoPath);\n logger.info('Dev server ready', { url });\n }\n\n return this.projectRunner.getStatus();\n }\n\n /**\n * Run the project's existing test suite\n */\n async runProjectTests(repoPath: string): Promise<TestRunResult> {\n return this.projectRunner.runExistingTests(repoPath);\n }\n\n /**\n * Get project runner status\n */\n getProjectStatus(): ProjectStatus {\n return this.projectRunner.getStatus();\n }\n\n /**\n * Stop the agent\n */\n stop() {\n this.isRunning = false;\n\n if (this.gitListener) {\n this.gitListener.stop();\n this.gitListener = null;\n }\n\n if (this.browserTools) {\n this.browserTools.close();\n }\n\n this.projectRunner.cleanup();\n\n logger.info('OpenQA stopped');\n }\n\n /**\n * Get all generated tests\n */\n getTests(): GeneratedTest[] {\n return this.brain?.getGeneratedTests() || [];\n }\n\n /**\n * Get all created agents\n */\n getAgents(): DynamicAgent[] {\n return this.brain?.getDynamicAgents() || [];\n }\n\n /**\n * Get statistics\n */\n getStats() {\n return {\n isRunning: this.isRunning,\n sessionId: this.sessionId,\n saas: this.saasConfigManager.getConfig(),\n brain: this.brain?.getStats() || null,\n gitListenerActive: !!this.gitListener\n };\n }\n\n /**\n * Get the SaaS configuration\n */\n getSaaSConfig(): SaaSConfig | null {\n return this.saasConfigManager.getConfig();\n }\n\n /**\n * Check if configured\n */\n isConfigured(): boolean {\n return this.saasConfigManager.isConfigured();\n }\n}\n\n// Export for easy usage\nexport { SaaSConfig, GeneratedTest, DynamicAgent };\nexport type { ProjectStatus, TestRunResult };\n","import { Low } from 'lowdb';\nimport { JSONFile } from 'lowdb/node';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { mkdirSync, writeFileSync, readFileSync } from 'fs';\n\nexport { OpenQASQLiteDatabase } from './sqlite.js';\n\n/**\n * Factory — chooses SQLite for .db paths, LowDB for .json paths.\n */\nexport async function createDatabase(path: string): Promise<OpenQADatabase> {\n if (path.endsWith('.db')) {\n const { OpenQASQLiteDatabase } = await import('./sqlite.js');\n return new OpenQASQLiteDatabase(path) as unknown as OpenQADatabase;\n }\n return new OpenQADatabase(path);\n}\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface TestSession {\n id: string;\n started_at: string;\n ended_at?: string;\n status: 'running' | 'completed' | 'failed';\n total_actions: number;\n bugs_found: number;\n metadata?: string;\n}\n\nexport interface Action {\n id: string;\n session_id: string;\n timestamp: string;\n type: string;\n description: string;\n input?: string;\n output?: string;\n screenshot_path?: string;\n}\n\nexport interface Bug {\n id: string;\n session_id: string;\n title: string;\n description: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n status: 'open' | 'in-progress' | 'resolved' | 'closed';\n github_issue_url?: string;\n screenshot_path?: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface KanbanTicket {\n id: string;\n bug_id?: string;\n title: string;\n description: string;\n priority: 'low' | 'medium' | 'high' | 'critical';\n column: 'backlog' | 'to-do' | 'in-progress' | 'done';\n tags?: string;\n screenshot_url?: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface User {\n id: string;\n username: string;\n passwordHash: string;\n role: 'admin' | 'viewer';\n createdAt: string;\n updatedAt: string;\n}\n\ninterface DatabaseSchema {\n config: Record<string, string>;\n test_sessions: TestSession[];\n actions: Action[];\n bugs: Bug[];\n kanban_tickets: KanbanTicket[];\n users: User[];\n}\n\nexport class OpenQADatabase {\n private db: Low<DatabaseSchema> | null = null;\n\n constructor(private dbPath: string = './data/openqa.json') {\n this.initialize();\n }\n\n private initialize() {\n const dir = dirname(this.dbPath);\n mkdirSync(dir, { recursive: true });\n\n const adapter = new JSONFile<DatabaseSchema>(this.dbPath);\n this.db = new Low<DatabaseSchema>(adapter, {\n config: {},\n test_sessions: [],\n actions: [],\n bugs: [],\n kanban_tickets: [],\n users: [],\n });\n\n this.db.read();\n if (!this.db.data) {\n this.db.data = {\n config: {},\n test_sessions: [],\n actions: [],\n bugs: [],\n kanban_tickets: [],\n users: [],\n };\n this.db.write();\n }\n }\n\n private async ensureInitialized() {\n if (!this.db) {\n this.initialize();\n }\n await this.db!.read();\n // Auto-migrate: add any missing top-level arrays added in later versions\n let migrated = false;\n if (!this.db!.data.users) { this.db!.data.users = []; migrated = true; }\n if (migrated) await this.db!.write();\n }\n\n async getConfig(key: string): Promise<string | null> {\n await this.ensureInitialized();\n return this.db!.data.config[key] || null;\n }\n\n async setConfig(key: string, value: string) {\n await this.ensureInitialized();\n this.db!.data.config[key] = value;\n await this.db!.write();\n }\n\n async getAllConfig(): Promise<Record<string, string>> {\n await this.ensureInitialized();\n return this.db!.data.config;\n }\n\n async createSession(id: string, metadata?: Record<string, unknown>): Promise<TestSession> {\n await this.ensureInitialized();\n const session: TestSession = {\n id,\n started_at: new Date().toISOString(),\n status: 'running',\n total_actions: 0,\n bugs_found: 0,\n metadata: metadata ? JSON.stringify(metadata) : undefined\n };\n this.db!.data.test_sessions.push(session);\n await this.db!.write();\n return session;\n }\n\n async getSession(id: string): Promise<TestSession | null> {\n await this.ensureInitialized();\n return this.db!.data.test_sessions.find(s => s.id === id) || null;\n }\n\n async updateSession(id: string, updates: Partial<TestSession>) {\n await this.ensureInitialized();\n const index = this.db!.data.test_sessions.findIndex(s => s.id === id);\n if (index !== -1) {\n this.db!.data.test_sessions[index] = { ...this.db!.data.test_sessions[index], ...updates };\n await this.db!.write();\n }\n }\n\n async getRecentSessions(limit: number = 10): Promise<TestSession[]> {\n await this.ensureInitialized();\n return this.db!.data.test_sessions\n .sort((a, b) => new Date(b.started_at).getTime() - new Date(a.started_at).getTime())\n .slice(0, limit);\n }\n\n async createAction(action: Omit<Action, 'id' | 'timestamp'>): Promise<Action> {\n await this.ensureInitialized();\n const newAction: Action = {\n id: `action_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n timestamp: new Date().toISOString(),\n ...action\n };\n this.db!.data.actions.push(newAction);\n await this.db!.write();\n return newAction;\n }\n\n async getSessionActions(sessionId: string): Promise<Action[]> {\n await this.ensureInitialized();\n return this.db!.data.actions\n .filter(a => a.session_id === sessionId)\n .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());\n }\n\n async createBug(bug: Omit<Bug, 'id' | 'created_at' | 'updated_at'>): Promise<Bug> {\n await this.ensureInitialized();\n const newBug: Bug = {\n id: `bug_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n ...bug\n };\n this.db!.data.bugs.push(newBug);\n await this.db!.write();\n return newBug;\n }\n\n async updateBug(id: string, updates: Partial<Bug>) {\n await this.ensureInitialized();\n const index = this.db!.data.bugs.findIndex(b => b.id === id);\n if (index !== -1) {\n this.db!.data.bugs[index] = { \n ...this.db!.data.bugs[index], \n ...updates, \n updated_at: new Date().toISOString() \n };\n await this.db!.write();\n }\n }\n\n async getAllBugs(): Promise<Bug[]> {\n await this.ensureInitialized();\n return this.db!.data.bugs.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());\n }\n\n async getBugsByStatus(status: Bug['status']): Promise<Bug[]> {\n await this.ensureInitialized();\n return this.db!.data.bugs\n .filter(b => b.status === status)\n .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());\n }\n\n async createKanbanTicket(ticket: Omit<KanbanTicket, 'id' | 'created_at' | 'updated_at'>): Promise<KanbanTicket> {\n await this.ensureInitialized();\n const newTicket: KanbanTicket = {\n id: `ticket_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n ...ticket\n };\n this.db!.data.kanban_tickets.push(newTicket);\n await this.db!.write();\n return newTicket;\n }\n\n async updateKanbanTicket(id: string, updates: Partial<KanbanTicket>) {\n await this.ensureInitialized();\n const index = this.db!.data.kanban_tickets.findIndex(t => t.id === id);\n if (index !== -1) {\n this.db!.data.kanban_tickets[index] = { \n ...this.db!.data.kanban_tickets[index], \n ...updates, \n updated_at: new Date().toISOString() \n };\n await this.db!.write();\n }\n }\n\n async getKanbanTickets(): Promise<KanbanTicket[]> {\n await this.ensureInitialized();\n return this.db!.data.kanban_tickets.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());\n }\n\n async getKanbanTicketsByColumn(column: KanbanTicket['column']): Promise<KanbanTicket[]> {\n await this.ensureInitialized();\n return this.db!.data.kanban_tickets\n .filter(t => t.column === column)\n .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());\n }\n\n async deleteKanbanTicket(id: string): Promise<void> {\n await this.ensureInitialized();\n const index = this.db!.data.kanban_tickets.findIndex(t => t.id === id);\n if (index !== -1) {\n this.db!.data.kanban_tickets.splice(index, 1);\n await this.db!.write();\n }\n }\n\n async clearAllConfig() {\n await this.ensureInitialized();\n this.db!.data.config = {};\n await this.db!.write();\n }\n\n // Get real data methods - connected to actual database records\n\n async getActiveAgents() {\n await this.ensureInitialized();\n const sessions = await this.getRecentSessions(1);\n const currentSession = sessions[0];\n \n // Return real agent state based on session status\n const isRunning = currentSession?.status === 'running';\n const totalActions = currentSession?.total_actions || 0;\n \n // Main agent is always present\n const agents = [\n { \n name: 'Main Agent', \n status: isRunning ? 'running' : 'idle', \n purpose: 'Autonomous QA orchestration', \n performance: totalActions > 0 ? Math.min(100, Math.round((totalActions / 100) * 100)) : 0, \n tasks: totalActions \n }\n ];\n \n // Add dynamic agents based on actual session activity\n if (currentSession && totalActions > 0) {\n const actions = await this.getSessionActions(currentSession.id);\n \n // Group actions by type to determine which specialists are active\n const actionTypes = actions.reduce((acc: Record<string, number>, action) => {\n const type = action.type || 'unknown';\n acc[type] = (acc[type] || 0) + 1;\n return acc;\n }, {});\n \n // Add specialists based on actual action types\n if (actionTypes['navigate'] || actionTypes['click'] || actionTypes['screenshot']) {\n agents.push({\n name: 'Browser Specialist',\n status: isRunning ? 'running' : 'idle',\n purpose: 'UI navigation and interaction',\n performance: Math.round(((actionTypes['navigate'] || 0) + (actionTypes['click'] || 0)) / totalActions * 100),\n tasks: (actionTypes['navigate'] || 0) + (actionTypes['click'] || 0)\n });\n }\n \n if (actionTypes['api_call'] || actionTypes['request']) {\n agents.push({\n name: 'API Tester',\n status: isRunning ? 'running' : 'idle',\n purpose: 'API endpoint testing',\n performance: Math.round((actionTypes['api_call'] || actionTypes['request'] || 0) / totalActions * 100),\n tasks: actionTypes['api_call'] || actionTypes['request'] || 0\n });\n }\n \n if (actionTypes['auth'] || actionTypes['login']) {\n agents.push({\n name: 'Auth Specialist',\n status: isRunning ? 'running' : 'idle',\n purpose: 'Authentication testing',\n performance: Math.round((actionTypes['auth'] || actionTypes['login'] || 0) / totalActions * 100),\n tasks: actionTypes['auth'] || actionTypes['login'] || 0\n });\n }\n }\n \n return agents;\n }\n\n async getCurrentTasks() {\n await this.ensureInitialized();\n const sessions = await this.getRecentSessions(1);\n const currentSession = sessions[0];\n \n if (!currentSession) {\n return [];\n }\n\n // Get real actions from the session\n const actions = await this.getSessionActions(currentSession.id);\n \n // Convert recent actions to tasks\n const recentActions = actions.slice(-10).reverse();\n \n return recentActions.map((action, index) => ({\n id: action.id,\n name: action.type || 'Unknown Action',\n status: index === 0 && currentSession.status === 'running' ? 'running' : 'completed',\n progress: index === 0 && currentSession.status === 'running' ? '65%' : '100%',\n agent: 'Main Agent',\n started_at: action.timestamp,\n result: action.output || action.description || 'Completed'\n }));\n }\n\n async getCurrentIssues() {\n await this.ensureInitialized();\n \n // Get real bugs from the database\n const bugs = await this.getAllBugs();\n \n // Return actual bugs as issues\n return bugs.slice(0, 10).map(bug => ({\n id: bug.id,\n title: bug.title,\n description: bug.description,\n severity: bug.severity || 'medium',\n status: bug.status || 'open',\n discovered_at: bug.created_at,\n agent: 'Main Agent'\n }));\n }\n\n async pruneOldSessions(maxAgeDays: number): Promise<{ sessionsRemoved: number; actionsRemoved: number }> {\n await this.ensureInitialized();\n const cutoff = new Date(Date.now() - maxAgeDays * 86400000).toISOString();\n\n const oldSessions = this.db!.data.test_sessions.filter(s => s.started_at < cutoff);\n const oldSessionIds = new Set(oldSessions.map(s => s.id));\n\n const actionsBefore = this.db!.data.actions.length;\n this.db!.data.actions = this.db!.data.actions.filter(a => !oldSessionIds.has(a.session_id));\n const actionsRemoved = actionsBefore - this.db!.data.actions.length;\n\n this.db!.data.test_sessions = this.db!.data.test_sessions.filter(s => s.started_at >= cutoff);\n await this.db!.write();\n\n return { sessionsRemoved: oldSessions.length, actionsRemoved };\n }\n\n async getStorageStats(): Promise<{ sessions: number; actions: number; bugs: number; tickets: number }> {\n await this.ensureInitialized();\n return {\n sessions: this.db!.data.test_sessions.length,\n actions: this.db!.data.actions.length,\n bugs: this.db!.data.bugs.length,\n tickets: this.db!.data.kanban_tickets.length,\n };\n }\n\n // ── User management ──────────────────────────────────────────────────────────\n\n async countUsers(): Promise<number> {\n await this.ensureInitialized();\n return this.db!.data.users.length;\n }\n\n async findUserByUsername(username: string): Promise<User | null> {\n await this.ensureInitialized();\n return this.db!.data.users.find(u => u.username === username) ?? null;\n }\n\n async getUserById(id: string): Promise<User | null> {\n await this.ensureInitialized();\n return this.db!.data.users.find(u => u.id === id) ?? null;\n }\n\n async getAllUsers(): Promise<User[]> {\n await this.ensureInitialized();\n return [...this.db!.data.users];\n }\n\n async createUser(data: { username: string; passwordHash: string; role: User['role'] }): Promise<User> {\n await this.ensureInitialized();\n const now = new Date().toISOString();\n const user: User = {\n id: `user_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n username: data.username,\n passwordHash: data.passwordHash,\n role: data.role,\n createdAt: now,\n updatedAt: now,\n };\n this.db!.data.users.push(user);\n await this.db!.write();\n return user;\n }\n\n async updateUser(id: string, updates: Partial<Pick<User, 'passwordHash' | 'role'>>): Promise<void> {\n await this.ensureInitialized();\n const idx = this.db!.data.users.findIndex(u => u.id === id);\n if (idx !== -1) {\n this.db!.data.users[idx] = {\n ...this.db!.data.users[idx],\n ...updates,\n updatedAt: new Date().toISOString(),\n };\n await this.db!.write();\n }\n }\n\n async deleteUser(id: string): Promise<void> {\n await this.ensureInitialized();\n const idx = this.db!.data.users.findIndex(u => u.id === id);\n if (idx !== -1) {\n this.db!.data.users.splice(idx, 1);\n await this.db!.write();\n }\n }\n\n async close() {\n // LowDB doesn't need explicit closing\n }\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LEVELS: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\nconst MIN_LEVEL: LogLevel = (process.env.LOG_LEVEL as LogLevel) || 'info';\n\nfunction shouldLog(level: LogLevel): boolean {\n return LEVELS[level] >= LEVELS[MIN_LEVEL];\n}\n\nfunction format(level: LogLevel, message: string, context?: Record<string, unknown>): string {\n const entry: Record<string, unknown> = {\n ts: new Date().toISOString(),\n level,\n msg: message,\n ...context,\n };\n return JSON.stringify(entry);\n}\n\nexport const logger = {\n debug(message: string, context?: Record<string, unknown>) {\n if (shouldLog('debug')) process.stdout.write(format('debug', message, context) + '\\n');\n },\n info(message: string, context?: Record<string, unknown>) {\n if (shouldLog('info')) process.stdout.write(format('info', message, context) + '\\n');\n },\n warn(message: string, context?: Record<string, unknown>) {\n if (shouldLog('warn')) process.stderr.write(format('warn', message, context) + '\\n');\n },\n error(message: string, context?: Record<string, unknown>) {\n if (shouldLog('error')) process.stderr.write(format('error', message, context) + '\\n');\n },\n child(defaults: Record<string, unknown>) {\n return {\n debug: (msg: string, ctx?: Record<string, unknown>) => logger.debug(msg, { ...defaults, ...ctx }),\n info: (msg: string, ctx?: Record<string, unknown>) => logger.info(msg, { ...defaults, ...ctx }),\n warn: (msg: string, ctx?: Record<string, unknown>) => logger.warn(msg, { ...defaults, ...ctx }),\n error: (msg: string, ctx?: Record<string, unknown>) => logger.error(msg, { ...defaults, ...ctx }),\n };\n },\n};\n","import { config as dotenvConfig } from 'dotenv';\nimport { OpenQADatabase } from '../../database/index.js';\nimport { validateConfigSafe, type ValidatedOpenQAConfig } from './schema.js';\nimport { logger } from '../logger.js';\n\ndotenvConfig();\n\nexport type OpenQAConfig = ValidatedOpenQAConfig;\n\nexport class ConfigManager {\n private db: OpenQADatabase | null = null;\n private envConfig: OpenQAConfig;\n\n constructor(dbPath?: string) {\n // Don't initialize database in constructor to avoid async issues\n this.envConfig = this.loadFromEnv();\n }\n\n private loadFromEnv(): OpenQAConfig {\n const raw = {\n llm: {\n provider: process.env.LLM_PROVIDER || 'openai',\n apiKey: process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY,\n model: process.env.LLM_MODEL,\n baseUrl: process.env.OLLAMA_BASE_URL\n },\n saas: {\n url: process.env.SAAS_URL || '',\n authType: process.env.SAAS_AUTH_TYPE || 'none',\n username: process.env.SAAS_USERNAME,\n password: process.env.SAAS_PASSWORD\n },\n github: process.env.GITHUB_TOKEN ? {\n token: process.env.GITHUB_TOKEN,\n owner: process.env.GITHUB_OWNER || '',\n repo: process.env.GITHUB_REPO || ''\n } : undefined,\n agent: {\n intervalMs: parseInt(process.env.AGENT_INTERVAL_MS || '3600000'),\n maxIterations: parseInt(process.env.AGENT_MAX_ITERATIONS || '20'),\n autoStart: process.env.AGENT_AUTO_START === 'true'\n },\n web: {\n port: parseInt(process.env.WEB_PORT || '4242'),\n host: process.env.WEB_HOST || '0.0.0.0'\n },\n database: {\n path: process.env.DB_PATH || './data/openqa.db'\n },\n notifications: {\n slack: process.env.SLACK_WEBHOOK_URL,\n discord: process.env.DISCORD_WEBHOOK_URL\n }\n };\n\n const result = validateConfigSafe(raw);\n if (!result.success) {\n logger.warn('Config validation warnings', { errors: result.errors });\n // Return raw config with type assertion — Zod defaults won't apply but app can still start\n return raw as OpenQAConfig;\n }\n return result.data;\n }\n\n private getDB(): OpenQADatabase {\n if (!this.db) {\n this.db = new OpenQADatabase('./data/openqa.json');\n }\n return this.db;\n }\n\n async get(key: string): Promise<string | null> {\n const dbValue = await this.getDB().getConfig(key);\n if (dbValue) return dbValue;\n\n const keys = key.split('.');\n let value: unknown = this.envConfig;\n for (const k of keys) {\n if (value && typeof value === 'object') {\n value = (value as Record<string, unknown>)[k];\n } else {\n return null;\n }\n }\n return value != null ? String(value) : null;\n }\n\n async set(key: string, value: string) {\n await this.getDB().setConfig(key, value);\n }\n\n async getAll(): Promise<OpenQAConfig> {\n const dbConfig = await this.getDB().getAllConfig();\n const merged = { ...this.envConfig };\n\n for (const [key, value] of Object.entries(dbConfig)) {\n const keys = key.split('.');\n let obj: Record<string, unknown> = merged as unknown as Record<string, unknown>;\n for (let i = 0; i < keys.length - 1; i++) {\n if (!obj[keys[i]] || typeof obj[keys[i]] !== 'object') obj[keys[i]] = {};\n obj = obj[keys[i]] as Record<string, unknown>;\n }\n obj[keys[keys.length - 1]] = value;\n }\n\n return merged;\n }\n\n async getConfig(): Promise<OpenQAConfig> {\n return await this.getAll();\n }\n\n // Synchronous version that only uses env vars (no DB)\n getConfigSync(): OpenQAConfig {\n return this.envConfig;\n }\n}\n","import { z } from 'zod';\n\nexport const llmConfigSchema = z.object({\n provider: z.enum(['openai', 'anthropic', 'ollama']).default('openai'),\n apiKey: z.string().optional(),\n model: z.string().optional(),\n baseUrl: z.string().url().optional(),\n});\n\nexport const saasConfigSchema = z.object({\n url: z.string().default(''),\n authType: z.enum(['none', 'basic', 'bearer', 'session']).default('none'),\n username: z.string().optional(),\n password: z.string().optional(),\n});\n\nexport const githubConfigSchema = z.object({\n token: z.string().min(1, 'GITHUB_TOKEN is required when GitHub is configured'),\n owner: z.string().default(''),\n repo: z.string().default(''),\n});\n\nexport const agentConfigSchema = z.object({\n intervalMs: z.number().int().positive().default(3600000),\n maxIterations: z.number().int().positive().default(20),\n autoStart: z.boolean().default(false),\n});\n\nexport const webConfigSchema = z.object({\n port: z.number().int().min(1).max(65535).default(4242),\n host: z.string().default('0.0.0.0'),\n});\n\nexport const databaseConfigSchema = z.object({\n path: z.string().default('./data/openqa.db'),\n});\n\nexport const notificationsConfigSchema = z.object({\n slack: z.string().url().optional(),\n discord: z.string().url().optional(),\n});\n\nexport const openQAConfigSchema = z.object({\n llm: llmConfigSchema,\n saas: saasConfigSchema,\n github: githubConfigSchema.optional(),\n agent: agentConfigSchema,\n web: webConfigSchema,\n database: databaseConfigSchema,\n notifications: notificationsConfigSchema.optional(),\n});\n\nexport type ValidatedOpenQAConfig = z.infer<typeof openQAConfigSchema>;\n\n// SaaS application config (used by brain/SaaSConfigManager)\nexport const saasAppConfigSchema = z.object({\n name: z.string().min(1, 'SaaS application name is required'),\n description: z.string().min(1, 'SaaS application description is required'),\n url: z.string().url('SaaS application URL must be a valid URL'),\n repoUrl: z.string().url().optional(),\n localPath: z.string().optional(),\n techStack: z.array(z.string()).optional(),\n authInfo: z.object({\n type: z.enum(['none', 'basic', 'oauth', 'session']),\n testCredentials: z.object({\n username: z.string(),\n password: z.string(),\n }).optional(),\n }).optional(),\n directives: z.array(z.string()).optional(),\n});\n\nexport type ValidatedSaaSAppConfig = z.infer<typeof saasAppConfigSchema>;\n\nexport function validateSaaSAppConfig(config: unknown): ValidatedSaaSAppConfig {\n return saasAppConfigSchema.parse(config);\n}\n\nexport function validateSaaSAppConfigSafe(config: unknown): { success: true; data: ValidatedSaaSAppConfig } | { success: false; errors: string[] } {\n const result = saasAppConfigSchema.safeParse(config);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return {\n success: false,\n errors: result.error.issues.map(i => `${i.path.join('.')}: ${i.message}`),\n };\n}\n\nexport function validateConfig(config: unknown): ValidatedOpenQAConfig {\n return openQAConfigSchema.parse(config);\n}\n\nexport function validateConfigSafe(config: unknown): { success: true; data: ValidatedOpenQAConfig } | { success: false; errors: string[] } {\n const result = openQAConfigSchema.safeParse(config);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return {\n success: false,\n errors: result.error.issues.map(i => `${i.path.join('.')}: ${i.message}`),\n };\n}\n","import { SaaSConfig } from '../brain/index.js';\nimport { OpenQADatabase } from '../../database/index.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { validateSaaSAppConfigSafe } from './schema.js';\nimport { ConfigError } from '../errors.js';\n\nexport class SaaSConfigManager {\n private db: OpenQADatabase;\n private config: SaaSConfig | null = null;\n\n constructor(db: OpenQADatabase) {\n this.db = db;\n this.loadConfig();\n }\n\n private loadConfig() {\n // For now, use environment variables only\n // TODO: Implement async config loading when needed\n }\n\n private saveConfig() {\n // For now, use environment variables only\n // TODO: Implement async config saving when needed\n }\n\n configure(config: SaaSConfig): SaaSConfig {\n const result = validateSaaSAppConfigSafe(config);\n if (!result.success) {\n throw new ConfigError('Invalid SaaS configuration: ' + result.errors.join(', '));\n }\n\n this.config = {\n ...config,\n techStack: config.techStack || this.detectTechStack(config.localPath),\n directives: config.directives || []\n };\n this.saveConfig();\n return this.config;\n }\n\n private detectTechStack(localPath?: string): string[] {\n if (!localPath || !existsSync(localPath)) return [];\n\n const stack: string[] = [];\n\n try {\n const pkgPath = join(localPath, 'package.json');\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n if (deps['react']) stack.push('React');\n if (deps['vue']) stack.push('Vue');\n if (deps['svelte']) stack.push('Svelte');\n if (deps['angular']) stack.push('Angular');\n if (deps['next']) stack.push('Next.js');\n if (deps['nuxt']) stack.push('Nuxt');\n if (deps['express']) stack.push('Express');\n if (deps['fastify']) stack.push('Fastify');\n if (deps['nestjs'] || deps['@nestjs/core']) stack.push('NestJS');\n if (deps['prisma'] || deps['@prisma/client']) stack.push('Prisma');\n if (deps['mongoose']) stack.push('MongoDB');\n if (deps['pg'] || deps['postgres']) stack.push('PostgreSQL');\n if (deps['mysql'] || deps['mysql2']) stack.push('MySQL');\n if (deps['redis'] || deps['ioredis']) stack.push('Redis');\n if (deps['typescript']) stack.push('TypeScript');\n if (deps['tailwindcss']) stack.push('TailwindCSS');\n }\n\n if (existsSync(join(localPath, 'requirements.txt')) || existsSync(join(localPath, 'pyproject.toml'))) {\n stack.push('Python');\n }\n\n if (existsSync(join(localPath, 'go.mod'))) {\n stack.push('Go');\n }\n\n if (existsSync(join(localPath, 'Cargo.toml'))) {\n stack.push('Rust');\n }\n\n } catch (e) {\n }\n\n return stack;\n }\n\n getConfig(): SaaSConfig | null {\n return this.config;\n }\n\n addDirective(directive: string) {\n if (!this.config) return;\n if (!this.config.directives) this.config.directives = [];\n this.config.directives.push(directive);\n this.saveConfig();\n }\n\n removeDirective(index: number) {\n if (!this.config?.directives) return;\n this.config.directives.splice(index, 1);\n this.saveConfig();\n }\n\n updateDirectives(directives: string[]) {\n if (!this.config) return;\n this.config.directives = directives;\n this.saveConfig();\n }\n\n setRepoUrl(url: string) {\n if (!this.config) return;\n this.config.repoUrl = url;\n this.saveConfig();\n }\n\n setLocalPath(path: string) {\n if (!this.config) return;\n this.config.localPath = path;\n this.config.techStack = this.detectTechStack(path);\n this.saveConfig();\n }\n\n setAuthInfo(authInfo: SaaSConfig['authInfo']) {\n if (!this.config) return;\n this.config.authInfo = authInfo;\n this.saveConfig();\n }\n\n isConfigured(): boolean {\n return this.config !== null && !!this.config.name && !!this.config.url;\n }\n\n exportConfig(): string {\n return JSON.stringify(this.config, null, 2);\n }\n\n importConfig(json: string): SaaSConfig {\n const config = JSON.parse(json) as SaaSConfig;\n return this.configure(config);\n }\n}\n\nexport const DEFAULT_DIRECTIVES = [\n \"Test all forms for validation errors and edge cases\",\n \"Check for security vulnerabilities (XSS, SQL injection, CSRF)\",\n \"Verify authentication and authorization work correctly\",\n \"Test responsive design on mobile viewports\",\n \"Check for accessibility issues (WCAG compliance)\",\n \"Monitor console for JavaScript errors\",\n \"Test error handling and user feedback\",\n \"Verify all links work and navigation is correct\"\n];\n\nexport function createQuickConfig(\n name: string,\n description: string,\n url: string,\n options?: {\n repoUrl?: string;\n localPath?: string;\n directives?: string[];\n }\n): SaaSConfig {\n return {\n name,\n description,\n url,\n repoUrl: options?.repoUrl,\n localPath: options?.localPath,\n directives: options?.directives || DEFAULT_DIRECTIVES,\n authInfo: { type: 'none' }\n };\n}\n","// ─── Custom Error Classes for OpenQA ───\n\nexport class OpenQAError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = 'OpenQAError';\n this.code = code;\n }\n}\n\nexport class BrowserError extends OpenQAError {\n constructor(message: string, code = 'BROWSER_ERROR') {\n super(message, code);\n this.name = 'BrowserError';\n }\n}\n\nexport class ConfigError extends OpenQAError {\n constructor(message: string, code = 'CONFIG_ERROR') {\n super(message, code);\n this.name = 'ConfigError';\n }\n}\n\nexport class DatabaseError extends OpenQAError {\n constructor(message: string, code = 'DATABASE_ERROR') {\n super(message, code);\n this.name = 'DatabaseError';\n }\n}\n\nexport class GitError extends OpenQAError {\n constructor(message: string, code = 'GIT_ERROR') {\n super(message, code);\n this.name = 'GitError';\n }\n}\n\nexport class BrainError extends OpenQAError {\n constructor(message: string, code = 'BRAIN_ERROR') {\n super(message, code);\n this.name = 'BrainError';\n }\n}\n\nexport class ProjectRunnerError extends OpenQAError {\n constructor(message: string, code = 'PROJECT_RUNNER_ERROR') {\n super(message, code);\n this.name = 'ProjectRunnerError';\n }\n}\n\nexport function isOpenQAError(e: unknown): e is OpenQAError {\n return e instanceof OpenQAError;\n}\n\nexport function toSafeMessage(e: unknown): string {\n if (e instanceof Error) return e.message;\n if (typeof e === 'string') return e;\n return 'Unknown error';\n}\n","import { ReActAgent } from '@orka-js/agent';\nimport { EventEmitter } from 'events';\nimport { logger } from '../logger.js';\nimport { OpenQADatabase } from '../../database/index.js';\nimport { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { execSync } from 'child_process';\nimport { ResilientLLM } from './llm-resilience.js';\n\nexport interface SaaSConfig {\n name: string;\n description: string;\n url: string;\n repoUrl?: string;\n localPath?: string;\n techStack?: string[];\n authInfo?: {\n type: 'none' | 'basic' | 'oauth' | 'session';\n testCredentials?: { username: string; password: string };\n };\n directives?: string[];\n}\n\nexport interface GeneratedTest {\n id: string;\n name: string;\n type: 'unit' | 'functional' | 'regression' | 'e2e' | 'security' | 'performance';\n description: string;\n code: string;\n targetFile?: string;\n priority: number;\n status: 'pending' | 'running' | 'passed' | 'failed' | 'skipped';\n createdAt: Date;\n executedAt?: Date;\n result?: string;\n error?: string;\n}\n\nexport interface DynamicAgent {\n id: string;\n name: string;\n purpose: string;\n prompt: string;\n tools: string[];\n createdAt: Date;\n executionCount: number;\n successRate: number;\n}\n\nexport class OpenQABrain extends EventEmitter {\n private db: OpenQADatabase;\n private llm: ResilientLLM;\n private saasConfig: SaaSConfig;\n private generatedTests: Map<string, GeneratedTest> = new Map();\n private dynamicAgents: Map<string, DynamicAgent> = new Map();\n private workDir: string = './data/workspace';\n private testsDir: string = './data/generated-tests';\n\n constructor(\n db: OpenQADatabase,\n llmConfig: { provider: string; apiKey: string; model?: string; fallbackProvider?: string; fallbackApiKey?: string; fallbackModel?: string },\n saasConfig: SaaSConfig\n ) {\n super();\n this.db = db;\n this.saasConfig = saasConfig;\n\n this.llm = new ResilientLLM({\n provider: llmConfig.provider,\n apiKey: llmConfig.apiKey,\n model: llmConfig.model,\n fallbackProvider: llmConfig.fallbackProvider,\n fallbackApiKey: llmConfig.fallbackApiKey,\n fallbackModel: llmConfig.fallbackModel,\n });\n\n // Forward LLM resilience events\n for (const event of ['llm-retry', 'llm-fallback', 'llm-circuit-open', 'llm-circuit-half-open', 'llm-primary-failed']) {\n this.llm.on(event, (data) => this.emit(event, data));\n }\n\n mkdirSync(this.workDir, { recursive: true });\n mkdirSync(this.testsDir, { recursive: true });\n }\n\n async analyze(): Promise<{\n understanding: string;\n suggestedTests: string[];\n suggestedAgents: string[];\n risks: string[];\n }> {\n let codeContext = '';\n if (this.saasConfig.repoUrl || this.saasConfig.localPath) {\n codeContext = await this.analyzeCodebase();\n }\n\n const prompt = `You are OpenQA Brain, an autonomous QA system that thinks like a senior QA engineer.\n\n## SaaS Application to Test\n- **Name**: ${this.saasConfig.name}\n- **Description**: ${this.saasConfig.description}\n- **URL**: ${this.saasConfig.url}\n- **Tech Stack**: ${this.saasConfig.techStack?.join(', ') || 'Unknown'}\n- **Auth Type**: ${this.saasConfig.authInfo?.type || 'none'}\n\n## User Directives\n${this.saasConfig.directives?.map(d => `- ${d}`).join('\\n') || 'None specified'}\n\n${codeContext ? `## Code Analysis\\n${codeContext}` : ''}\n\n## Your Task\nAnalyze this application and provide:\n\n1. **Understanding**: A brief summary of what this application does and its critical paths\n2. **Suggested Tests**: List specific tests you would create (be concrete, not generic)\n3. **Suggested Agents**: Custom agents you would create for this specific app\n4. **Risks**: Potential issues or vulnerabilities to focus on\n\nThink deeply about what could go wrong with THIS specific application.\n\nRespond in JSON format:\n{\n \"understanding\": \"...\",\n \"suggestedTests\": [\"Test 1: ...\", \"Test 2: ...\"],\n \"suggestedAgents\": [\"Agent for X\", \"Agent for Y\"],\n \"risks\": [\"Risk 1\", \"Risk 2\"]\n}`;\n\n const response = await this.llm.generate(prompt);\n \n try {\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch (e: unknown) {\n logger.warn('Failed to parse analysis', { error: e instanceof Error ? e.message : String(e) });\n }\n\n return {\n understanding: response,\n suggestedTests: [],\n suggestedAgents: [],\n risks: []\n };\n }\n\n private async analyzeCodebase(): Promise<string> {\n let repoPath = this.saasConfig.localPath;\n\n if (this.saasConfig.repoUrl && !this.saasConfig.localPath) {\n repoPath = join(this.workDir, 'repo');\n \n if (!existsSync(repoPath)) {\n logger.info('Cloning repository', { url: this.saasConfig.repoUrl });\n try {\n execSync(`git clone --depth 1 ${this.saasConfig.repoUrl} ${repoPath}`, {\n stdio: 'pipe'\n });\n } catch (e) {\n logger.error('Failed to clone repository', { error: e instanceof Error ? e.message : String(e) });\n return '';\n }\n }\n }\n\n if (!repoPath || !existsSync(repoPath)) {\n return '';\n }\n\n const analysis: string[] = [];\n\n try {\n const packageJsonPath = join(repoPath, 'package.json');\n if (existsSync(packageJsonPath)) {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n analysis.push(`### Package Info`);\n analysis.push(`- Name: ${pkg.name}`);\n analysis.push(`- Dependencies: ${Object.keys(pkg.dependencies || {}).slice(0, 20).join(', ')}`);\n analysis.push(`- Scripts: ${Object.keys(pkg.scripts || {}).join(', ')}`);\n }\n\n const srcFiles = this.findFiles(repoPath, ['.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte'], 50);\n if (srcFiles.length > 0) {\n analysis.push(`\\n### Source Files (${srcFiles.length} found)`);\n srcFiles.slice(0, 20).forEach(f => {\n analysis.push(`- ${f.replace(repoPath, '')}`);\n });\n }\n\n const testFiles = this.findFiles(repoPath, ['.test.ts', '.test.js', '.spec.ts', '.spec.js'], 20);\n if (testFiles.length > 0) {\n analysis.push(`\\n### Existing Tests (${testFiles.length} found)`);\n testFiles.slice(0, 10).forEach(f => {\n analysis.push(`- ${f.replace(repoPath, '')}`);\n });\n }\n\n const routePatterns = ['routes', 'pages', 'views', 'controllers', 'api'];\n for (const pattern of routePatterns) {\n const routeDir = join(repoPath, 'src', pattern);\n if (existsSync(routeDir)) {\n const routes = this.findFiles(routeDir, ['.ts', '.tsx', '.js', '.jsx'], 20);\n if (routes.length > 0) {\n analysis.push(`\\n### Routes/Pages`);\n routes.forEach(f => {\n analysis.push(`- ${f.replace(repoPath, '')}`);\n });\n }\n break;\n }\n }\n\n } catch (e) {\n logger.error('Error analyzing codebase', { error: e instanceof Error ? e.message : String(e) });\n }\n\n return analysis.join('\\n');\n }\n\n private findFiles(dir: string, extensions: string[], limit: number): string[] {\n const results: string[] = [];\n \n try {\n const find = (d: string) => {\n if (results.length >= limit) return;\n \n const { readdirSync, statSync } = require('fs');\n const items = readdirSync(d);\n \n for (const item of items) {\n if (results.length >= limit) return;\n if (item.startsWith('.') || item === 'node_modules' || item === 'dist' || item === 'build') continue;\n \n const fullPath = join(d, item);\n const stat = statSync(fullPath);\n \n if (stat.isDirectory()) {\n find(fullPath);\n } else if (extensions.some(ext => item.endsWith(ext))) {\n results.push(fullPath);\n }\n }\n };\n \n find(dir);\n } catch (e) {\n }\n \n return results;\n }\n\n async generateTest(\n type: GeneratedTest['type'],\n target: string,\n context?: string\n ): Promise<GeneratedTest> {\n const prompt = `You are OpenQA, an autonomous QA engineer. Generate a ${type} test.\n\n## Application\n- **Name**: ${this.saasConfig.name}\n- **Description**: ${this.saasConfig.description}\n- **URL**: ${this.saasConfig.url}\n\n## Test Target\n${target}\n\n${context ? `## Additional Context\\n${context}` : ''}\n\n## Instructions\nGenerate a complete, runnable test. Use Playwright for E2E/functional tests.\n\nFor ${type} tests:\n${type === 'unit' ? '- Test isolated functions/components\\n- Mock dependencies\\n- Use Jest or Vitest syntax' : ''}\n${type === 'functional' ? '- Test user workflows\\n- Use Playwright\\n- Include assertions' : ''}\n${type === 'e2e' ? '- Test complete user journeys\\n- Use Playwright\\n- Handle auth if needed' : ''}\n${type === 'regression' ? '- Test previously broken functionality\\n- Verify bug fixes\\n- Include edge cases' : ''}\n${type === 'security' ? '- Test for vulnerabilities\\n- SQL injection, XSS, auth bypass\\n- Use safe payloads' : ''}\n${type === 'performance' ? '- Measure load times\\n- Check resource usage\\n- Set thresholds' : ''}\n\nRespond with JSON:\n{\n \"name\": \"descriptive test name\",\n \"description\": \"what this test verifies\",\n \"code\": \"// complete test code here\",\n \"priority\": 1-5\n}`;\n\n const response = await this.llm.generate(prompt);\n \n let testData = { name: target, description: '', code: '', priority: 3 };\n \n try {\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n testData = JSON.parse(jsonMatch[0]);\n }\n } catch (e) {\n testData.code = response;\n }\n\n const test: GeneratedTest = {\n id: `test_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n name: testData.name,\n type,\n description: testData.description,\n code: testData.code,\n priority: testData.priority,\n status: 'pending',\n createdAt: new Date()\n };\n\n this.generatedTests.set(test.id, test);\n this.saveTest(test);\n \n this.emit('test-generated', test);\n \n return test;\n }\n\n private saveTest(test: GeneratedTest) {\n const filename = `${test.type}_${test.id}.ts`;\n const filepath = join(this.testsDir, filename);\n \n const content = `/**\n * Generated by OpenQA\n * Type: ${test.type}\n * Name: ${test.name}\n * Description: ${test.description}\n * Created: ${test.createdAt.toISOString()}\n */\n\n${test.code}\n`;\n \n writeFileSync(filepath, content);\n test.targetFile = filepath;\n }\n\n async createDynamicAgent(purpose: string): Promise<DynamicAgent> {\n const prompt = `You are OpenQA Brain. Create a specialized testing agent.\n\n## Application Context\n- **Name**: ${this.saasConfig.name}\n- **Description**: ${this.saasConfig.description}\n- **URL**: ${this.saasConfig.url}\n\n## Agent Purpose\n${purpose}\n\n## Instructions\nDesign a specialized agent for this specific purpose. The agent should:\n1. Have a clear, focused mission\n2. Know exactly what to test\n3. Know how to report findings\n\nRespond with JSON:\n{\n \"name\": \"Agent Name\",\n \"purpose\": \"Clear purpose statement\",\n \"prompt\": \"Complete system prompt for this agent (be specific and detailed)\",\n \"tools\": [\"tool1\", \"tool2\"] // from: navigate, click, fill, screenshot, check_console, create_issue, create_ticket\n}`;\n\n const response = await this.llm.generate(prompt);\n \n let agentData: { name: string; purpose: string; prompt: string; tools: string[] } = { name: purpose, purpose, prompt: '', tools: [] };\n\n try {\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n agentData = JSON.parse(jsonMatch[0]);\n }\n } catch (_e: unknown) {\n agentData.prompt = response;\n }\n\n const agent: DynamicAgent = {\n id: `agent_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n name: agentData.name,\n purpose: agentData.purpose,\n prompt: agentData.prompt,\n tools: agentData.tools,\n createdAt: new Date(),\n executionCount: 0,\n successRate: 0\n };\n\n this.dynamicAgents.set(agent.id, agent);\n \n this.emit('agent-created', agent);\n \n return agent;\n }\n\n async executeTest(testId: string): Promise<GeneratedTest> {\n const test = this.generatedTests.get(testId);\n if (!test) throw new Error(`Test ${testId} not found`);\n\n test.status = 'running';\n test.executedAt = new Date();\n this.emit('test-started', test);\n\n try {\n if (test.targetFile && existsSync(test.targetFile)) {\n const result = execSync(`npx playwright test ${test.targetFile} --reporter=json`, {\n cwd: this.testsDir,\n stdio: 'pipe',\n timeout: 120000\n });\n \n test.status = 'passed';\n test.result = result.toString();\n } else {\n test.status = 'passed';\n test.result = 'Test code generated (execution skipped - no test runner configured)';\n }\n } catch (e: unknown) {\n test.status = 'failed';\n test.error = e instanceof Error ? e.message : String(e);\n }\n\n this.emit('test-completed', test);\n return test;\n }\n\n async think(): Promise<{\n decision: string;\n actions: Array<{ type: string; target: string; reason: string }>;\n }> {\n const recentTests = Array.from(this.generatedTests.values()).slice(-10);\n const recentAgents = Array.from(this.dynamicAgents.values()).slice(-5);\n\n const prompt = `You are OpenQA Brain, an autonomous QA system. Think about what to do next.\n\n## Application\n- **Name**: ${this.saasConfig.name}\n- **Description**: ${this.saasConfig.description}\n- **URL**: ${this.saasConfig.url}\n\n## User Directives\n${this.saasConfig.directives?.map(d => `- ${d}`).join('\\n') || 'None'}\n\n## Recent Tests (${recentTests.length})\n${recentTests.map(t => `- [${t.status}] ${t.type}: ${t.name}`).join('\\n') || 'None yet'}\n\n## Active Agents (${recentAgents.length})\n${recentAgents.map(a => `- ${a.name}: ${a.purpose}`).join('\\n') || 'None yet'}\n\n## Your Task\nDecide what to do next. Consider:\n1. What areas haven't been tested yet?\n2. Are there any failed tests that need investigation?\n3. Should you create new specialized agents?\n4. What tests would be most valuable right now?\n\nRespond with JSON:\n{\n \"decision\": \"Brief explanation of your reasoning\",\n \"actions\": [\n { \"type\": \"generate_test\", \"target\": \"what to test\", \"reason\": \"why\" },\n { \"type\": \"create_agent\", \"target\": \"agent purpose\", \"reason\": \"why\" },\n { \"type\": \"run_test\", \"target\": \"test_id\", \"reason\": \"why\" },\n { \"type\": \"analyze\", \"target\": \"what to analyze\", \"reason\": \"why\" }\n ]\n}`;\n\n const response = await this.llm.generate(prompt);\n\n try {\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch (e) {\n }\n\n return {\n decision: response,\n actions: []\n };\n }\n\n async runAutonomously(maxIterations: number = 10): Promise<void> {\n const log = logger.child({ app: this.saasConfig.name });\n log.info('Brain starting autonomous mode', { maxIterations });\n\n const analysis = await this.analyze();\n log.info('Analysis complete', { suggestedTests: analysis.suggestedTests.length });\n this.emit('analysis-complete', analysis);\n\n for (let i = 0; i < maxIterations; i++) {\n log.info('Iteration', { iteration: i + 1, maxIterations });\n\n const thought = await this.think();\n log.debug('Decision', { decision: thought.decision });\n this.emit('thinking', thought);\n\n for (const action of thought.actions) {\n log.debug('Action', { type: action.type, target: action.target });\n\n try {\n switch (action.type) {\n case 'generate_test':\n const testType = this.inferTestType(action.target);\n await this.generateTest(testType, action.target, action.reason);\n break;\n\n case 'create_agent':\n await this.createDynamicAgent(action.target);\n break;\n\n case 'run_test':\n if (this.generatedTests.has(action.target)) {\n await this.executeTest(action.target);\n }\n break;\n\n case 'analyze':\n break;\n }\n } catch (e: unknown) {\n log.error('Action failed', { type: action.type, error: e instanceof Error ? e.message : String(e) });\n }\n }\n\n if (thought.actions.length === 0) {\n log.info('No more actions needed');\n break;\n }\n\n await new Promise(resolve => setTimeout(resolve, 2000));\n }\n\n log.info('Autonomous session complete');\n this.emit('session-complete', {\n testsGenerated: this.generatedTests.size,\n agentsCreated: this.dynamicAgents.size\n });\n }\n\n private inferTestType(target: string): GeneratedTest['type'] {\n const lower = target.toLowerCase();\n if (lower.includes('security') || lower.includes('injection') || lower.includes('xss')) return 'security';\n if (lower.includes('performance') || lower.includes('load') || lower.includes('speed')) return 'performance';\n if (lower.includes('regression') || lower.includes('bug') || lower.includes('fix')) return 'regression';\n if (lower.includes('unit') || lower.includes('function') || lower.includes('component')) return 'unit';\n if (lower.includes('e2e') || lower.includes('journey') || lower.includes('flow')) return 'e2e';\n return 'functional';\n }\n\n getGeneratedTests(): GeneratedTest[] {\n return Array.from(this.generatedTests.values());\n }\n\n getDynamicAgents(): DynamicAgent[] {\n return Array.from(this.dynamicAgents.values());\n }\n\n getStats() {\n const tests = this.getGeneratedTests();\n return {\n totalTests: tests.length,\n passed: tests.filter(t => t.status === 'passed').length,\n failed: tests.filter(t => t.status === 'failed').length,\n pending: tests.filter(t => t.status === 'pending').length,\n agents: this.dynamicAgents.size,\n byType: {\n unit: tests.filter(t => t.type === 'unit').length,\n functional: tests.filter(t => t.type === 'functional').length,\n e2e: tests.filter(t => t.type === 'e2e').length,\n regression: tests.filter(t => t.type === 'regression').length,\n security: tests.filter(t => t.type === 'security').length,\n performance: tests.filter(t => t.type === 'performance').length\n }\n };\n }\n}\n","import { OpenAIAdapter } from '@orka-js/openai';\nimport { AnthropicAdapter } from '@orka-js/anthropic';\nimport type { LLMAdapter } from '@orka-js/core';\nimport { EventEmitter } from 'events';\nimport { BrainError } from '../errors.js';\nimport { LLMCache } from './llm-cache.js';\nimport { metrics } from '../metrics.js';\n\ninterface ResilientLLMConfig {\n provider: string;\n apiKey: string;\n model?: string;\n fallbackProvider?: string;\n fallbackApiKey?: string;\n fallbackModel?: string;\n maxRetries?: number;\n circuitThreshold?: number;\n circuitResetMs?: number;\n cacheTtlMs?: number;\n cacheMaxSize?: number;\n}\n\ninterface CircuitState {\n failures: number;\n lastFailure: number;\n isOpen: boolean;\n}\n\nexport class ResilientLLM extends EventEmitter {\n private config: ResilientLLMConfig;\n private circuit: CircuitState = { failures: 0, lastFailure: 0, isOpen: false };\n private maxRetries: number;\n private circuitThreshold: number;\n private circuitResetMs: number;\n private cache: LLMCache;\n\n constructor(config: ResilientLLMConfig) {\n super();\n this.config = config;\n this.maxRetries = config.maxRetries ?? 3;\n this.circuitThreshold = config.circuitThreshold ?? 5;\n this.circuitResetMs = config.circuitResetMs ?? 30000;\n this.cache = new LLMCache({\n ttlMs: config.cacheTtlMs,\n maxSize: config.cacheMaxSize,\n });\n }\n\n private createAdapter(provider: string, apiKey: string, model?: string): LLMAdapter {\n if (provider === 'anthropic') {\n return new AnthropicAdapter({\n apiKey,\n model: model || 'claude-3-5-sonnet-20241022',\n });\n }\n return new OpenAIAdapter({\n apiKey,\n model: model || 'gpt-4',\n });\n }\n\n private isCircuitOpen(): boolean {\n if (!this.circuit.isOpen) return false;\n // Check if enough time has passed to half-open\n if (Date.now() - this.circuit.lastFailure >= this.circuitResetMs) {\n this.circuit.isOpen = false;\n this.emit('llm-circuit-half-open', { provider: this.config.provider });\n return false;\n }\n return true;\n }\n\n private recordFailure() {\n this.circuit.failures++;\n this.circuit.lastFailure = Date.now();\n if (this.circuit.failures >= this.circuitThreshold) {\n this.circuit.isOpen = true;\n metrics.inc('llm_circuit_opens');\n this.emit('llm-circuit-open', {\n provider: this.config.provider,\n failures: this.circuit.failures,\n });\n }\n }\n\n private recordSuccess() {\n this.circuit.failures = 0;\n this.circuit.isOpen = false;\n }\n\n /** Generate text, returning the string content */\n async generate(prompt: string): Promise<string> {\n // Check cache first\n const cached = this.cache.get(prompt);\n if (cached !== null) {\n metrics.inc('llm_cache_hits');\n this.emit('llm-cache-hit', { promptLength: prompt.length });\n return cached;\n }\n\n metrics.inc('llm_calls');\n\n // Try primary provider (unless circuit is open)\n if (!this.isCircuitOpen()) {\n try {\n return await this.generateWithRetry(\n this.config.provider,\n this.config.apiKey,\n this.config.model,\n prompt,\n );\n } catch (e) {\n this.recordFailure();\n this.emit('llm-primary-failed', {\n provider: this.config.provider,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n // Try fallback provider\n if (this.config.fallbackProvider && this.config.fallbackApiKey) {\n try {\n metrics.inc('llm_fallbacks');\n this.emit('llm-fallback', {\n from: this.config.provider,\n to: this.config.fallbackProvider,\n });\n const result = await this.generateWithRetry(\n this.config.fallbackProvider,\n this.config.fallbackApiKey,\n this.config.fallbackModel,\n prompt,\n );\n this.cache.set(prompt, result);\n return result;\n } catch (e) {\n throw new BrainError(\n `Both LLM providers failed. Primary: ${this.config.provider}, Fallback: ${this.config.fallbackProvider}`,\n );\n }\n }\n\n throw new BrainError(\n `LLM provider ${this.config.provider} failed and no fallback is configured`,\n );\n }\n\n private async generateWithRetry(\n provider: string,\n apiKey: string,\n model: string | undefined,\n prompt: string,\n ): Promise<string> {\n const adapter = this.createAdapter(provider, apiKey, model);\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= this.maxRetries; attempt++) {\n try {\n const result = await adapter.generate(prompt);\n const text = result.content;\n this.recordSuccess();\n this.cache.set(prompt, text);\n return text;\n } catch (e) {\n lastError = e;\n if (attempt < this.maxRetries) {\n const delayMs = Math.pow(2, attempt - 1) * 1000; // 1s, 2s, 4s\n metrics.inc('llm_retries');\n this.emit('llm-retry', {\n provider,\n attempt,\n maxRetries: this.maxRetries,\n delayMs,\n error: e instanceof Error ? e.message : String(e),\n });\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n }\n }\n\n throw lastError;\n }\n\n getCircuitState(): { isOpen: boolean; failures: number } {\n return {\n isOpen: this.isCircuitOpen(),\n failures: this.circuit.failures,\n };\n }\n\n getCacheStats() {\n return this.cache.stats();\n }\n\n clearCache() {\n this.cache.clear();\n }\n}\n","import { createHash } from 'crypto';\n\ninterface CacheEntry {\n response: string;\n expiresAt: number;\n}\n\nexport class LLMCache {\n private store = new Map<string, CacheEntry>();\n private ttlMs: number;\n private maxSize: number;\n\n constructor(options?: { ttlMs?: number; maxSize?: number }) {\n this.ttlMs = options?.ttlMs ?? 3600000; // 1 hour\n this.maxSize = options?.maxSize ?? 500;\n }\n\n private key(prompt: string): string {\n return createHash('sha256').update(prompt).digest('hex');\n }\n\n get(prompt: string): string | null {\n const k = this.key(prompt);\n const entry = this.store.get(k);\n if (!entry) return null;\n if (Date.now() > entry.expiresAt) {\n this.store.delete(k);\n return null;\n }\n return entry.response;\n }\n\n set(prompt: string, response: string): void {\n if (this.store.size >= this.maxSize) {\n // Evict oldest entry\n const oldest = this.store.keys().next().value;\n if (oldest) this.store.delete(oldest);\n }\n this.store.set(this.key(prompt), {\n response,\n expiresAt: Date.now() + this.ttlMs,\n });\n }\n\n clear(): void {\n this.store.clear();\n }\n\n get size(): number {\n return this.store.size;\n }\n\n stats(): { size: number; ttlMs: number; maxSize: number } {\n return { size: this.store.size, ttlMs: this.ttlMs, maxSize: this.maxSize };\n }\n}\n","const startedAt = Date.now();\n\nconst counters: Record<string, number> = {\n llm_calls: 0,\n llm_cache_hits: 0,\n llm_retries: 0,\n llm_fallbacks: 0,\n llm_circuit_opens: 0,\n tests_generated: 0,\n tests_run: 0,\n tests_passed: 0,\n tests_failed: 0,\n bugs_found: 0,\n sessions_started: 0,\n ws_connections: 0,\n http_requests: 0,\n};\n\nexport const metrics = {\n inc(key: keyof typeof counters, by = 1) {\n if (key in counters) counters[key] += by;\n },\n\n snapshot() {\n const memMB = process.memoryUsage();\n return {\n uptimeSeconds: Math.floor((Date.now() - startedAt) / 1000),\n memory: {\n heapUsedMB: Math.round(memMB.heapUsed / 1024 / 1024),\n heapTotalMB: Math.round(memMB.heapTotal / 1024 / 1024),\n rssMB: Math.round(memMB.rss / 1024 / 1024),\n },\n counters: { ...counters },\n cacheHitRate: counters.llm_calls > 0\n ? Math.round((counters.llm_cache_hits / (counters.llm_calls + counters.llm_cache_hits)) * 100)\n : 0,\n };\n },\n};\n","import { chromium, Browser, Page } from 'playwright';\nimport { OpenQADatabase } from '../../database/index.js';\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\n\nexport class BrowserTools {\n private browser: Browser | null = null;\n private page: Page | null = null;\n private db: OpenQADatabase;\n private sessionId: string;\n private screenshotDir: string = './data/screenshots';\n\n constructor(db: OpenQADatabase, sessionId: string) {\n this.db = db;\n this.sessionId = sessionId;\n mkdirSync(this.screenshotDir, { recursive: true });\n }\n\n async initialize() {\n this.browser = await chromium.launch({ headless: true });\n const context = await this.browser.newContext({\n viewport: { width: 1920, height: 1080 },\n userAgent: 'OpenQA/1.0 (Automated Testing Agent)'\n });\n this.page = await context.newPage();\n }\n\n getTools() {\n return [\n {\n name: 'navigate_to_page',\n description: 'Navigate to a specific URL in the application',\n parameters: {\n type: 'object',\n properties: {\n url: { type: 'string', description: 'The URL to navigate to' }\n },\n required: ['url']\n },\n execute: async ({ url }: { url: string }) => {\n if (!this.page) await this.initialize();\n \n try {\n await this.page!.goto(url, { waitUntil: 'networkidle' });\n const title = await this.page!.title();\n \n this.db.createAction({\n session_id: this.sessionId,\n type: 'navigate',\n description: `Navigated to ${url}`,\n input: url,\n output: `Page title: ${title}`\n });\n \n return `Successfully navigated to ${url}. Page title: \"${title}\"`;\n } catch (error: unknown) {\n return `Failed to navigate: ${error instanceof Error ? error.message : String(error)}`;\n }\n }\n },\n {\n name: 'click_element',\n description: 'Click on an element using a CSS selector',\n parameters: {\n type: 'object',\n properties: {\n selector: { type: 'string', description: 'CSS selector of the element to click' }\n },\n required: ['selector']\n },\n execute: async ({ selector }: { selector: string }) => {\n if (!this.page) return 'Browser not initialized. Navigate to a page first.';\n \n try {\n await this.page.click(selector, { timeout: 5000 });\n \n this.db.createAction({\n session_id: this.sessionId,\n type: 'click',\n description: `Clicked element: ${selector}`,\n input: selector\n });\n \n return `Successfully clicked element: ${selector}`;\n } catch (error: unknown) {\n return `Failed to click element: ${error instanceof Error ? error.message : String(error)}`;\n }\n }\n },\n {\n name: 'fill_input',\n description: 'Fill an input field with text',\n parameters: {\n type: 'object',\n properties: {\n selector: { type: 'string', description: 'CSS selector of the input field' },\n text: { type: 'string', description: 'Text to fill in the input' }\n },\n required: ['selector', 'text']\n },\n execute: async ({ selector, text }: { selector: string; text: string }) => {\n if (!this.page) return 'Browser not initialized. Navigate to a page first.';\n \n try {\n await this.page.fill(selector, text);\n \n this.db.createAction({\n session_id: this.sessionId,\n type: 'fill',\n description: `Filled input ${selector}`,\n input: `${selector} = ${text}`\n });\n \n return `Successfully filled input ${selector} with text`;\n } catch (error: unknown) {\n return `Failed to fill input: ${error instanceof Error ? error.message : String(error)}`;\n }\n }\n },\n {\n name: 'take_screenshot',\n description: 'Take a screenshot of the current page for evidence',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Name for the screenshot file' }\n },\n required: ['name']\n },\n execute: async ({ name }: { name: string }) => {\n if (!this.page) return 'Browser not initialized. Navigate to a page first.';\n \n try {\n const filename = `${Date.now()}_${name}.png`;\n const path = join(this.screenshotDir, filename);\n await this.page.screenshot({ path, fullPage: true });\n \n this.db.createAction({\n session_id: this.sessionId,\n type: 'screenshot',\n description: `Screenshot: ${name}`,\n screenshot_path: path\n });\n \n return `Screenshot saved: ${path}`;\n } catch (error: unknown) {\n return `Failed to take screenshot: ${error instanceof Error ? error.message : String(error)}`;\n }\n }\n },\n {\n name: 'get_page_content',\n description: 'Get the text content of the current page',\n parameters: {\n type: 'object',\n properties: {}\n },\n execute: async () => {\n if (!this.page) return 'Browser not initialized. Navigate to a page first.';\n \n try {\n const content = await this.page.textContent('body');\n return content?.slice(0, 1000) || 'No content found';\n } catch (error: unknown) {\n return `Failed to get content: ${error instanceof Error ? error.message : String(error)}`;\n }\n }\n },\n {\n name: 'check_console_errors',\n description: 'Check for JavaScript console errors on the page',\n parameters: {\n type: 'object',\n properties: {}\n },\n execute: async () => {\n if (!this.page) return 'Browser not initialized. Navigate to a page first.';\n \n const errors: string[] = [];\n this.page.on('console', msg => {\n if (msg.type() === 'error') {\n errors.push(msg.text());\n }\n });\n \n await this.page.waitForTimeout(2000);\n \n if (errors.length > 0) {\n return `Found ${errors.length} console errors:\\n${errors.join('\\n')}`;\n }\n return 'No console errors detected';\n }\n }\n ];\n }\n\n async close() {\n if (this.browser) {\n await this.browser.close();\n this.browser = null;\n this.page = null;\n }\n }\n}\n","import { EventEmitter } from 'events';\nimport { Octokit } from '@octokit/rest';\nimport { logger } from '../logger.js';\n\nexport interface GitEvent {\n type: 'merge' | 'push' | 'pipeline_success' | 'pipeline_failure' | 'tag';\n provider: 'github' | 'gitlab';\n branch: string;\n commit: string;\n author: string;\n message: string;\n timestamp: Date;\n pipelineId?: string;\n pipelineStatus?: string;\n changedFiles?: string[];\n}\n\nexport interface GitListenerConfig {\n provider: 'github' | 'gitlab';\n token: string;\n owner: string;\n repo: string;\n branch?: string;\n pollIntervalMs?: number;\n gitlabUrl?: string;\n}\n\ninterface GitLabCommit {\n id: string;\n author_name: string;\n message: string;\n created_at: string;\n parent_ids?: string[];\n}\n\ninterface GitLabPipeline {\n id: number;\n status: string;\n ref: string;\n sha: string;\n created_at: string;\n updated_at: string;\n user?: {\n name: string;\n username: string;\n };\n}\n\ninterface GitLabWebhook {\n id: number;\n url: string;\n push_events: boolean;\n merge_requests_events: boolean;\n pipeline_events: boolean;\n}\n\nexport class GitListener extends EventEmitter {\n private config: GitListenerConfig;\n private octokit: Octokit | null = null;\n private lastCommitSha: string | null = null;\n private lastPipelineId: string | null = null;\n private pollInterval: NodeJS.Timeout | null = null;\n private isRunning: boolean = false;\n\n constructor(config: GitListenerConfig) {\n super();\n this.config = {\n branch: 'main',\n pollIntervalMs: 60000,\n gitlabUrl: 'https://gitlab.com',\n ...config\n };\n\n if (config.provider === 'github' && config.token) {\n this.octokit = new Octokit({ auth: config.token });\n }\n }\n\n async start() {\n if (this.isRunning) return;\n this.isRunning = true;\n\n logger.info('GitListener started', { provider: this.config.provider, owner: this.config.owner, repo: this.config.repo });\n \n await this.checkInitialState();\n \n this.pollInterval = setInterval(() => {\n this.poll().catch((e) => logger.error('Poll error', { error: e instanceof Error ? e.message : String(e) }));\n }, this.config.pollIntervalMs);\n }\n\n stop() {\n this.isRunning = false;\n if (this.pollInterval) {\n clearInterval(this.pollInterval);\n this.pollInterval = null;\n }\n logger.info('GitListener stopped');\n }\n\n private async checkInitialState() {\n try {\n if (this.config.provider === 'github') {\n await this.checkGitHubState();\n } else {\n await this.checkGitLabState();\n }\n } catch (error) {\n logger.error('Failed to check initial state', { error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n private async poll() {\n try {\n if (this.config.provider === 'github') {\n await this.pollGitHub();\n } else {\n await this.pollGitLab();\n }\n } catch (error) {\n logger.error('Poll error', { error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n private async checkGitHubState() {\n if (!this.octokit) return;\n\n const { data: commits } = await this.octokit.repos.listCommits({\n owner: this.config.owner,\n repo: this.config.repo,\n sha: this.config.branch,\n per_page: 1\n });\n\n if (commits.length > 0) {\n this.lastCommitSha = commits[0].sha;\n }\n\n try {\n const { data: runs } = await this.octokit.actions.listWorkflowRunsForRepo({\n owner: this.config.owner,\n repo: this.config.repo,\n branch: this.config.branch,\n per_page: 1\n });\n\n if (runs.workflow_runs.length > 0) {\n this.lastPipelineId = runs.workflow_runs[0].id.toString();\n }\n } catch {\n }\n }\n\n private async pollGitHub() {\n if (!this.octokit) return;\n\n const { data: commits } = await this.octokit.repos.listCommits({\n owner: this.config.owner,\n repo: this.config.repo,\n sha: this.config.branch,\n per_page: 5\n });\n\n for (const commit of commits) {\n if (this.lastCommitSha && commit.sha === this.lastCommitSha) break;\n\n const isMerge = commit.parents && commit.parents.length > 1;\n \n const event: GitEvent = {\n type: isMerge ? 'merge' : 'push',\n provider: 'github',\n branch: this.config.branch!,\n commit: commit.sha,\n author: commit.commit.author?.name || 'unknown',\n message: commit.commit.message,\n timestamp: new Date(commit.commit.author?.date || Date.now())\n };\n\n this.emit('git-event', event);\n \n if (isMerge) {\n this.emit('merge', event);\n logger.info('Merge detected', { branch: this.config.branch, sha: commit.sha.slice(0, 7) });\n }\n }\n\n if (commits.length > 0) {\n this.lastCommitSha = commits[0].sha;\n }\n\n try {\n const { data: runs } = await this.octokit.actions.listWorkflowRunsForRepo({\n owner: this.config.owner,\n repo: this.config.repo,\n branch: this.config.branch,\n per_page: 5\n });\n\n for (const run of runs.workflow_runs) {\n if (this.lastPipelineId && run.id.toString() === this.lastPipelineId) break;\n\n if (run.status === 'completed') {\n const event: GitEvent = {\n type: run.conclusion === 'success' ? 'pipeline_success' : 'pipeline_failure',\n provider: 'github',\n branch: this.config.branch!,\n commit: run.head_sha,\n author: run.actor?.login || 'unknown',\n message: run.name || '',\n timestamp: new Date(run.updated_at || Date.now()),\n pipelineId: run.id.toString(),\n pipelineStatus: run.conclusion || undefined\n };\n\n this.emit('git-event', event);\n \n if (run.conclusion === 'success') {\n this.emit('pipeline-success', event);\n logger.info('Pipeline success', { name: run.name, id: run.id });\n } else {\n this.emit('pipeline-failure', event);\n logger.warn('Pipeline failure', { name: run.name, id: run.id });\n }\n }\n }\n\n if (runs.workflow_runs.length > 0) {\n this.lastPipelineId = runs.workflow_runs[0].id.toString();\n }\n } catch {\n }\n }\n\n private async checkGitLabState() {\n const headers = { 'PRIVATE-TOKEN': this.config.token };\n const projectPath = encodeURIComponent(`${this.config.owner}/${this.config.repo}`);\n const baseUrl = this.config.gitlabUrl;\n\n try {\n const commitsRes = await fetch(\n `${baseUrl}/api/v4/projects/${projectPath}/repository/commits?ref_name=${this.config.branch}&per_page=1`,\n { headers }\n );\n const commits = await commitsRes.json() as GitLabCommit[];\n if (commits.length > 0) {\n this.lastCommitSha = commits[0].id;\n }\n\n const pipelinesRes = await fetch(\n `${baseUrl}/api/v4/projects/${projectPath}/pipelines?ref=${this.config.branch}&per_page=1`,\n { headers }\n );\n const pipelines = await pipelinesRes.json() as GitLabPipeline[];\n if (pipelines.length > 0) {\n this.lastPipelineId = pipelines[0].id.toString();\n }\n } catch (error) {\n logger.error('GitLab initial state error', { error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n private async pollGitLab() {\n const headers = { 'PRIVATE-TOKEN': this.config.token };\n const projectPath = encodeURIComponent(`${this.config.owner}/${this.config.repo}`);\n const baseUrl = this.config.gitlabUrl;\n\n try {\n const commitsRes = await fetch(\n `${baseUrl}/api/v4/projects/${projectPath}/repository/commits?ref_name=${this.config.branch}&per_page=5`,\n { headers }\n );\n const commits = await commitsRes.json() as GitLabCommit[];\n\n for (const commit of commits) {\n if (this.lastCommitSha && commit.id === this.lastCommitSha) break;\n\n const isMerge = commit.parent_ids && commit.parent_ids.length > 1;\n\n const event: GitEvent = {\n type: isMerge ? 'merge' : 'push',\n provider: 'gitlab',\n branch: this.config.branch!,\n commit: commit.id,\n author: commit.author_name,\n message: commit.message,\n timestamp: new Date(commit.created_at)\n };\n\n this.emit('git-event', event);\n \n if (isMerge) {\n this.emit('merge', event);\n logger.info('Merge detected', { branch: this.config.branch, id: commit.id.slice(0, 7) });\n }\n }\n\n if (commits.length > 0) {\n this.lastCommitSha = commits[0].id;\n }\n\n const pipelinesRes = await fetch(\n `${baseUrl}/api/v4/projects/${projectPath}/pipelines?ref=${this.config.branch}&per_page=5`,\n { headers }\n );\n const pipelines = await pipelinesRes.json() as GitLabPipeline[];\n\n for (const pipeline of pipelines) {\n if (this.lastPipelineId && pipeline.id.toString() === this.lastPipelineId) break;\n\n if (pipeline.status === 'success' || pipeline.status === 'failed') {\n const event: GitEvent = {\n type: pipeline.status === 'success' ? 'pipeline_success' : 'pipeline_failure',\n provider: 'gitlab',\n branch: this.config.branch!,\n commit: pipeline.sha,\n author: pipeline.user?.name || 'unknown',\n message: `Pipeline #${pipeline.id}`,\n timestamp: new Date(pipeline.updated_at),\n pipelineId: pipeline.id.toString(),\n pipelineStatus: pipeline.status\n };\n\n this.emit('git-event', event);\n \n if (pipeline.status === 'success') {\n this.emit('pipeline-success', event);\n logger.info('Pipeline success', { id: pipeline.id });\n } else {\n this.emit('pipeline-failure', event);\n logger.warn('Pipeline failure', { id: pipeline.id });\n }\n }\n }\n\n if (pipelines.length > 0) {\n this.lastPipelineId = pipelines[0].id.toString();\n }\n } catch (error) {\n logger.error('GitLab poll error', { error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n async setupWebhook(webhookUrl: string): Promise<string> {\n if (this.config.provider === 'github') {\n return this.setupGitHubWebhook(webhookUrl);\n } else {\n return this.setupGitLabWebhook(webhookUrl);\n }\n }\n\n private async setupGitHubWebhook(webhookUrl: string): Promise<string> {\n if (!this.octokit) throw new Error('GitHub not configured');\n\n const { data } = await this.octokit.repos.createWebhook({\n owner: this.config.owner,\n repo: this.config.repo,\n config: {\n url: webhookUrl,\n content_type: 'json'\n },\n events: ['push', 'pull_request', 'workflow_run']\n });\n\n return data.id.toString();\n }\n\n private async setupGitLabWebhook(webhookUrl: string): Promise<string> {\n const headers = { \n 'PRIVATE-TOKEN': this.config.token,\n 'Content-Type': 'application/json'\n };\n const projectPath = encodeURIComponent(`${this.config.owner}/${this.config.repo}`);\n\n const res = await fetch(\n `${this.config.gitlabUrl}/api/v4/projects/${projectPath}/hooks`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({\n url: webhookUrl,\n push_events: true,\n merge_requests_events: true,\n pipeline_events: true\n })\n }\n );\n\n const data = await res.json() as GitLabWebhook;\n return data.id.toString();\n }\n}\n","import { EventEmitter } from 'events';\nimport { spawn, ChildProcess } from 'child_process';\nimport { existsSync, readFileSync, statSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { ProjectRunnerError } from '../errors.js';\n\n/**\n * Resolve and validate a repo path — must be an existing directory.\n * Prevents path traversal by normalising before use.\n */\nfunction sanitizeRepoPath(inputPath: string): string {\n if (typeof inputPath !== 'string' || !inputPath.trim()) {\n throw new ProjectRunnerError('repoPath must be a non-empty string');\n }\n const resolved = resolve(inputPath);\n try {\n const stat = statSync(resolved);\n if (!stat.isDirectory()) {\n throw new ProjectRunnerError(`repoPath is not a directory: ${resolved}`);\n }\n } catch (err) {\n if (err instanceof ProjectRunnerError) throw err;\n throw new ProjectRunnerError(`repoPath does not exist: ${resolved}`);\n }\n return resolved;\n}\n\nexport interface ProjectType {\n language: 'node' | 'python' | 'go' | 'rust' | 'unknown';\n framework?: string;\n packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun' | 'pip' | 'cargo' | 'go' | 'unknown';\n scripts: Record<string, string>;\n testRunner?: string;\n devCommand?: string;\n buildCommand?: string;\n port?: number;\n}\n\nexport interface TestRunResult {\n runner: string;\n passed: number;\n failed: number;\n skipped: number;\n total: number;\n durationMs: number;\n raw: string;\n}\n\nexport interface ProjectStatus {\n repoPath: string;\n projectType: ProjectType | null;\n installed: boolean;\n serverRunning: boolean;\n serverUrl: string | null;\n serverPid: number | null;\n}\n\nexport class ProjectRunner extends EventEmitter {\n private serverProcess: ChildProcess | null = null;\n private serverUrl: string | null = null;\n private installed = false;\n private projectType: ProjectType | null = null;\n private repoPath: string | null = null;\n\n /**\n * Detect what kind of project lives at the given path\n */\n detectProjectType(repoPath: string): ProjectType {\n repoPath = sanitizeRepoPath(repoPath);\n\n // Node.js project\n const pkgPath = join(repoPath, 'package.json');\n if (existsSync(pkgPath)) {\n return this.detectNodeProject(repoPath, pkgPath);\n }\n\n // Python project\n if (existsSync(join(repoPath, 'requirements.txt')) || existsSync(join(repoPath, 'pyproject.toml'))) {\n return this.detectPythonProject(repoPath);\n }\n\n // Go project\n if (existsSync(join(repoPath, 'go.mod'))) {\n return {\n language: 'go',\n packageManager: 'go',\n scripts: {},\n testRunner: 'go test',\n devCommand: 'go run .',\n };\n }\n\n // Rust project\n if (existsSync(join(repoPath, 'Cargo.toml'))) {\n return {\n language: 'rust',\n packageManager: 'cargo',\n scripts: {},\n testRunner: 'cargo test',\n devCommand: 'cargo run',\n };\n }\n\n return { language: 'unknown', packageManager: 'unknown', scripts: {} };\n }\n\n private detectNodeProject(repoPath: string, pkgPath: string): ProjectType {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const scripts: Record<string, string> = pkg.scripts || {};\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n // Detect package manager\n let packageManager: ProjectType['packageManager'] = 'npm';\n if (existsSync(join(repoPath, 'pnpm-lock.yaml'))) packageManager = 'pnpm';\n else if (existsSync(join(repoPath, 'yarn.lock'))) packageManager = 'yarn';\n else if (existsSync(join(repoPath, 'bun.lockb'))) packageManager = 'bun';\n\n // Detect framework\n let framework: string | undefined;\n if (deps['next']) framework = 'next';\n else if (deps['nuxt']) framework = 'nuxt';\n else if (deps['@angular/core']) framework = 'angular';\n else if (deps['svelte'] || deps['@sveltejs/kit']) framework = 'svelte';\n else if (deps['vue']) framework = 'vue';\n else if (deps['react']) framework = 'react';\n else if (deps['express']) framework = 'express';\n else if (deps['fastify']) framework = 'fastify';\n else if (deps['@nestjs/core']) framework = 'nestjs';\n\n // Detect test runner\n let testRunner: string | undefined;\n if (deps['vitest']) testRunner = 'vitest';\n else if (deps['jest']) testRunner = 'jest';\n else if (deps['mocha']) testRunner = 'mocha';\n else if (deps['playwright'] || deps['@playwright/test']) testRunner = 'playwright';\n else if (deps['cypress']) testRunner = 'cypress';\n\n // Detect dev command\n let devCommand: string | undefined;\n if (scripts['dev']) devCommand = `${packageManager} run dev`;\n else if (scripts['start']) devCommand = `${packageManager} run start`;\n else if (scripts['serve']) devCommand = `${packageManager} run serve`;\n\n // Detect build command\n let buildCommand: string | undefined;\n if (scripts['build']) buildCommand = `${packageManager} run build`;\n\n // Detect port\n let port: number | undefined;\n const devScript = scripts['dev'] || scripts['start'] || '';\n const portMatch = devScript.match(/--port[= ](\\d+)|-p[= ]?(\\d+)/);\n if (portMatch) {\n port = parseInt(portMatch[1] || portMatch[2]);\n } else if (framework === 'next') {\n port = 3000;\n } else if (framework === 'nuxt' || framework === 'vue') {\n port = 3000;\n } else if (framework === 'angular') {\n port = 4200;\n } else if (framework === 'svelte') {\n port = 5173;\n } else if (framework === 'react') {\n port = 3000;\n }\n\n return {\n language: 'node',\n framework,\n packageManager,\n scripts,\n testRunner,\n devCommand,\n buildCommand,\n port,\n };\n }\n\n private detectPythonProject(repoPath: string): ProjectType {\n let testRunner: string | undefined;\n\n // Check for pytest in requirements\n const reqPath = join(repoPath, 'requirements.txt');\n if (existsSync(reqPath)) {\n const content = readFileSync(reqPath, 'utf-8');\n if (content.includes('pytest')) testRunner = 'pytest';\n }\n\n const pyprojectPath = join(repoPath, 'pyproject.toml');\n if (existsSync(pyprojectPath)) {\n const content = readFileSync(pyprojectPath, 'utf-8');\n if (content.includes('pytest')) testRunner = 'pytest';\n }\n\n return {\n language: 'python',\n packageManager: 'pip',\n scripts: {},\n testRunner: testRunner || 'pytest',\n devCommand: 'python -m flask run',\n };\n }\n\n /**\n * Install project dependencies\n */\n async installDependencies(repoPath: string): Promise<void> {\n repoPath = sanitizeRepoPath(repoPath);\n const projectType = this.detectProjectType(repoPath);\n this.projectType = projectType;\n this.repoPath = repoPath;\n\n let command: string;\n let args: string[];\n\n switch (projectType.packageManager) {\n case 'pnpm':\n command = 'pnpm'; args = ['install']; break;\n case 'yarn':\n command = 'yarn'; args = ['install']; break;\n case 'bun':\n command = 'bun'; args = ['install']; break;\n case 'npm':\n command = 'npm'; args = ['install']; break;\n case 'pip':\n command = 'pip'; args = ['install', '-r', 'requirements.txt']; break;\n case 'cargo':\n command = 'cargo'; args = ['build']; break;\n case 'go':\n command = 'go'; args = ['mod', 'download']; break;\n default:\n throw new ProjectRunnerError(`Unknown package manager: ${projectType.packageManager}`);\n }\n\n this.emit('install-start', { command, packageManager: projectType.packageManager });\n\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, {\n cwd: repoPath,\n stdio: 'pipe',\n timeout: 300000, // 5 min\n });\n\n let output = '';\n\n proc.stdout?.on('data', (data: Buffer) => {\n const text = data.toString();\n output += text;\n this.emit('install-progress', { text });\n });\n\n proc.stderr?.on('data', (data: Buffer) => {\n const text = data.toString();\n output += text;\n this.emit('install-progress', { text });\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n this.installed = true;\n this.emit('install-complete', { success: true });\n resolve();\n } else {\n const err = new ProjectRunnerError(\n `Install failed (exit code ${code}): ${output.slice(-500)}`,\n );\n this.emit('install-complete', { success: false, error: err.message });\n reject(err);\n }\n });\n\n proc.on('error', (err) => {\n reject(new ProjectRunnerError(`Failed to spawn ${command}: ${err.message}`));\n });\n });\n }\n\n /**\n * Start the project's dev server\n */\n async startDevServer(repoPath: string): Promise<{ url: string; pid: number }> {\n repoPath = sanitizeRepoPath(repoPath);\n const projectType = this.projectType || this.detectProjectType(repoPath);\n this.repoPath = repoPath;\n\n if (!projectType.devCommand) {\n throw new ProjectRunnerError('No dev command detected for this project');\n }\n\n const [cmd, ...args] = projectType.devCommand.split(' ');\n\n this.emit('server-starting', { command: projectType.devCommand });\n\n return new Promise((resolve, reject) => {\n const proc = spawn(cmd, args, {\n cwd: repoPath,\n stdio: 'pipe',\n detached: true,\n });\n\n this.serverProcess = proc;\n let resolved = false;\n\n const readyPatterns = [\n /ready on\\s+(https?:\\/\\/\\S+)/i,\n /listening on\\s+(https?:\\/\\/\\S+)/i,\n /started on\\s+(https?:\\/\\/\\S+)/i,\n /Local:\\s+(https?:\\/\\/\\S+)/i,\n /http:\\/\\/localhost:(\\d+)/,\n /http:\\/\\/127\\.0\\.0\\.1:(\\d+)/,\n /http:\\/\\/0\\.0\\.0\\.0:(\\d+)/,\n /ready in \\d+/i,\n /compiled successfully/i,\n ];\n\n const checkOutput = (text: string) => {\n if (resolved) return;\n\n for (const pattern of readyPatterns) {\n const match = text.match(pattern);\n if (match) {\n resolved = true;\n let url: string;\n\n if (match[1]?.startsWith('http')) {\n url = match[1];\n } else if (match[1]) {\n url = `http://localhost:${match[1]}`;\n } else if (projectType.port) {\n url = `http://localhost:${projectType.port}`;\n } else {\n url = 'http://localhost:3000';\n }\n\n this.serverUrl = url;\n this.emit('server-ready', { url, pid: proc.pid });\n resolve({ url, pid: proc.pid! });\n return;\n }\n }\n };\n\n proc.stdout?.on('data', (data: Buffer) => {\n checkOutput(data.toString());\n });\n\n proc.stderr?.on('data', (data: Buffer) => {\n checkOutput(data.toString());\n });\n\n proc.on('error', (err) => {\n if (!resolved) {\n reject(new ProjectRunnerError(`Failed to start dev server: ${err.message}`));\n }\n });\n\n proc.on('close', (code) => {\n if (!resolved) {\n reject(new ProjectRunnerError(`Dev server exited with code ${code}`));\n }\n });\n\n // Timeout: if no ready pattern matched after 60s, try probing the port\n setTimeout(async () => {\n if (resolved) return;\n\n const port = projectType.port || 3000;\n const candidatePorts = [port, 5173, 8080, 4200, 3001];\n\n for (const p of candidatePorts) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 2000);\n await fetch(`http://localhost:${p}`, { signal: controller.signal });\n clearTimeout(timeoutId);\n\n resolved = true;\n const url = `http://localhost:${p}`;\n this.serverUrl = url;\n this.emit('server-ready', { url, pid: proc.pid });\n resolve({ url, pid: proc.pid! });\n return;\n } catch {\n // Port not ready\n }\n }\n\n reject(new ProjectRunnerError('Dev server did not become ready within 60s'));\n }, 60000);\n });\n }\n\n /**\n * Run the project's existing test suite\n */\n async runExistingTests(repoPath: string): Promise<TestRunResult> {\n repoPath = sanitizeRepoPath(repoPath);\n const projectType = this.projectType || this.detectProjectType(repoPath);\n\n if (!projectType.testRunner) {\n throw new ProjectRunnerError('No test runner detected for this project');\n }\n\n let command: string;\n let args: string[];\n\n switch (projectType.testRunner) {\n case 'vitest':\n command = 'npx';\n args = ['vitest', 'run', '--reporter=json'];\n break;\n case 'jest':\n command = 'npx';\n args = ['jest', '--json', '--forceExit'];\n break;\n case 'mocha':\n command = 'npx';\n args = ['mocha', '--reporter', 'json'];\n break;\n case 'playwright':\n command = 'npx';\n args = ['playwright', 'test', '--reporter=json'];\n break;\n case 'pytest':\n command = 'python';\n args = ['-m', 'pytest', '--tb=short', '-q'];\n break;\n case 'go test':\n command = 'go';\n args = ['test', '-json', './...'];\n break;\n case 'cargo test':\n command = 'cargo';\n args = ['test', '--', '--format=json'];\n break;\n default:\n command = 'npx';\n args = [projectType.testRunner, '--json'];\n }\n\n this.emit('test-start', { runner: projectType.testRunner });\n\n const startTime = Date.now();\n\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, {\n cwd: repoPath,\n stdio: 'pipe',\n timeout: 300000,\n });\n\n let stdout = '';\n let stderr = '';\n\n proc.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString();\n this.emit('test-progress', { text: data.toString() });\n });\n\n proc.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n proc.on('close', (code) => {\n const durationMs = Date.now() - startTime;\n const raw = stdout + '\\n' + stderr;\n\n const result = this.parseTestResults(\n projectType.testRunner!,\n stdout,\n stderr,\n durationMs,\n );\n\n this.emit('test-complete', result);\n // Resolve even if tests fail — the result contains pass/fail info\n resolve(result);\n });\n\n proc.on('error', (err) => {\n reject(new ProjectRunnerError(`Failed to run tests: ${err.message}`));\n });\n });\n }\n\n private parseTestResults(\n runner: string,\n stdout: string,\n stderr: string,\n durationMs: number,\n ): TestRunResult {\n const raw = stdout + '\\n' + stderr;\n\n // Try JSON parsing for vitest/jest\n if (runner === 'vitest' || runner === 'jest') {\n try {\n const jsonMatch = stdout.match(/\\{[\\s\\S]*\"numPassedTests\"[\\s\\S]*\\}/);\n if (jsonMatch) {\n const json = JSON.parse(jsonMatch[0]);\n return {\n runner,\n passed: json.numPassedTests || 0,\n failed: json.numFailedTests || 0,\n skipped: json.numPendingTests || 0,\n total: json.numTotalTests || 0,\n durationMs,\n raw,\n };\n }\n } catch {\n // Fall through to regex parsing\n }\n }\n\n // Regex fallback: parse summary lines\n let passed = 0, failed = 0, skipped = 0;\n\n // \"Tests: X passed, Y failed, Z skipped, W total\"\n const summaryMatch = raw.match(/(\\d+)\\s*passed.*?(\\d+)\\s*failed/i);\n if (summaryMatch) {\n passed = parseInt(summaryMatch[1]);\n failed = parseInt(summaryMatch[2]);\n }\n\n const passedMatch = raw.match(/(\\d+)\\s*pass(?:ed|ing)/i);\n if (passedMatch && !summaryMatch) passed = parseInt(passedMatch[1]);\n\n const failedMatch = raw.match(/(\\d+)\\s*fail(?:ed|ing|ure)/i);\n if (failedMatch && !summaryMatch) failed = parseInt(failedMatch[1]);\n\n const skippedMatch = raw.match(/(\\d+)\\s*(?:skip(?:ped)?|pending|todo)/i);\n if (skippedMatch) skipped = parseInt(skippedMatch[1]);\n\n return {\n runner,\n passed,\n failed,\n skipped,\n total: passed + failed + skipped,\n durationMs,\n raw,\n };\n }\n\n /**\n * Stop the dev server and clean up\n */\n cleanup() {\n if (this.serverProcess) {\n // Kill the process group (detached)\n try {\n if (this.serverProcess.pid) {\n process.kill(-this.serverProcess.pid, 'SIGTERM');\n }\n } catch {\n // Process may already be dead\n try {\n this.serverProcess.kill('SIGTERM');\n } catch {\n // Ignore\n }\n }\n this.serverProcess = null;\n this.serverUrl = null;\n this.emit('server-stopped');\n }\n }\n\n getStatus(): ProjectStatus {\n return {\n repoPath: this.repoPath || '',\n projectType: this.projectType,\n installed: this.installed,\n serverRunning: this.serverProcess !== null && !this.serverProcess.killed,\n serverUrl: this.serverUrl,\n serverPid: this.serverProcess?.pid || null,\n };\n }\n}\n","import { Bug } from '../../database/index.js';\n\nexport interface NotificationConfig {\n slack?: string;\n discord?: string;\n}\n\nexport interface NotificationPayload {\n title: string;\n message: string;\n severity?: 'info' | 'warning' | 'error' | 'success';\n fields?: Array<{ name: string; value: string }>;\n}\n\nexport class NotificationService {\n constructor(private config: NotificationConfig) {}\n\n async notify(payload: NotificationPayload): Promise<void> {\n const promises: Promise<void>[] = [];\n\n if (this.config.slack) {\n promises.push(this.sendSlack(payload));\n }\n if (this.config.discord) {\n promises.push(this.sendDiscord(payload));\n }\n\n await Promise.allSettled(promises);\n }\n\n async notifyBug(bug: Bug): Promise<void> {\n const severityEmoji: Record<string, string> = {\n critical: '🔴', high: '🟠', medium: '🟡', low: '🟢',\n };\n\n await this.notify({\n title: `${severityEmoji[bug.severity] || '⚠️'} Bug Found: ${bug.title}`,\n message: bug.description,\n severity: bug.severity === 'critical' || bug.severity === 'high' ? 'error' : 'warning',\n fields: [\n { name: 'Severity', value: bug.severity },\n { name: 'Status', value: bug.status },\n ...(bug.github_issue_url ? [{ name: 'GitHub Issue', value: bug.github_issue_url }] : []),\n ],\n });\n }\n\n async notifySessionComplete(stats: { testsGenerated: number; agentsCreated: number; sessionId: string }): Promise<void> {\n await this.notify({\n title: '✅ OpenQA Session Complete',\n message: `Session ${stats.sessionId} finished.`,\n severity: 'success',\n fields: [\n { name: 'Tests Generated', value: String(stats.testsGenerated) },\n { name: 'Agents Created', value: String(stats.agentsCreated) },\n ],\n });\n }\n\n private async sendSlack(payload: NotificationPayload): Promise<void> {\n const colorMap: Record<string, string> = {\n info: '#36a64f', warning: '#ff9800', error: '#dc3545', success: '#28a745',\n };\n const color = colorMap[payload.severity || 'info'];\n\n const body = {\n attachments: [{\n color,\n title: payload.title,\n text: payload.message,\n fields: payload.fields?.map(f => ({ title: f.name, value: f.value, short: true })) || [],\n footer: 'OpenQA',\n ts: Math.floor(Date.now() / 1000),\n }],\n };\n\n const res = await fetch(this.config.slack!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(`Slack notification failed: ${res.status} ${res.statusText}`);\n }\n }\n\n private async sendDiscord(payload: NotificationPayload): Promise<void> {\n const colorMap: Record<string, number> = {\n info: 0x36a64f, warning: 0xff9800, error: 0xdc3545, success: 0x28a745,\n };\n const color = colorMap[payload.severity || 'info'];\n\n const body = {\n embeds: [{\n title: payload.title,\n description: payload.message,\n color,\n fields: payload.fields?.map(f => ({ name: f.name, value: f.value, inline: true })) || [],\n footer: { text: 'OpenQA' },\n timestamp: new Date().toISOString(),\n }],\n };\n\n const res = await fetch(this.config.discord!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n throw new Error(`Discord notification failed: ${res.status} ${res.statusText}`);\n }\n }\n\n isConfigured(): boolean {\n return !!(this.config.slack || this.config.discord);\n }\n}\n"],"mappings":"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","names":["EventEmitter","fileURLToPath","__filename","fileURLToPath","__dirname","readFileSync","join","join","readFileSync","path","EventEmitter","writeFileSync","readFileSync","existsSync","mkdirSync","join","resolve","EventEmitter","mkdirSync","join","existsSync","readFileSync","statSync","writeFileSync","resolve","mkdirSync","join","path","EventEmitter","EventEmitter","EventEmitter","existsSync","readFileSync","join","EventEmitter","join","existsSync","readFileSync","resolve","EventEmitter","path"]}
|