assuremind 1.0.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/CONTRIBUTING.md +254 -0
- package/LICENSE +21 -0
- package/README.md +367 -0
- package/dist/cli/index.js +14933 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.mts +2950 -0
- package/dist/index.d.ts +2950 -0
- package/dist/index.js +1628 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1525 -0
- package/dist/index.mjs.map +1 -0
- package/docs/CLI-REFERENCE.md +312 -0
- package/docs/GETTING-STARTED.md +378 -0
- package/docs/STUDIO.md +390 -0
- package/package.json +118 -0
- package/templates/AUTOMIND.md +275 -0
- package/templates/autotest.config.ts +25 -0
- package/templates/docs/CLI-REFERENCE.md +413 -0
- package/templates/docs/GETTING-STARTED.md +417 -0
- package/templates/docs/STUDIO.md +625 -0
- package/templates/env.example +112 -0
- package/templates/env.minimal +103 -0
- package/templates/gitignore +17 -0
- package/templates/global-variables.json +5 -0
- package/ui/dist/assets/index-CdtAorWT.js +819 -0
- package/ui/dist/assets/index-KjpMCzao.css +1 -0
- package/ui/dist/favicon.svg +36 -0
- package/ui/dist/index.html +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types/config.ts","../src/storage/suite-store.ts","../src/types/suite.ts","../src/utils/errors.ts","../src/utils/logger.ts","../src/utils/sanitize.ts","../src/storage/utils.ts","../src/storage/case-store.ts","../src/storage/variable-store.ts","../src/types/variable.ts","../src/storage/config-store.ts","../src/storage/result-store.ts","../src/types/run.ts","../src/storage/healing-store.ts","../src/types/healing.ts","../src/utils/hash.ts","../src/utils/env.ts"],"sourcesContent":["import type { AutotestConfig } from './types/config.js';\r\nimport { AutotestConfigSchema, DEFAULT_CONFIG } from './types/config.js';\r\n\r\n/**\r\n * defineConfig — type-safe helper for autotest.config.ts.\r\n * Validates the config at definition time and returns it unchanged.\r\n * Usage: export default defineConfig({ baseUrl: '...', ... })\r\n */\r\nexport function defineConfig(config: Partial<AutotestConfig>): AutotestConfig {\r\n const merged = { ...DEFAULT_CONFIG, ...config };\r\n const result = AutotestConfigSchema.safeParse(merged);\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new Error(`Invalid assuremind config:\\n${issues}`);\r\n }\r\n return result.data;\r\n}\r\n\r\n// Public types\r\nexport type {\r\n AutotestConfig,\r\n HealingConfig,\r\n ReportingConfig,\r\n BrowserName,\r\n ScreenshotMode,\r\n VideoMode,\r\n TraceMode,\r\n} from './types/config.js';\r\n\r\nexport type {\r\n TestSuite,\r\n TestCase,\r\n TestStep,\r\n Priority,\r\n GenerationStrategy,\r\n} from './types/suite.js';\r\n\r\nexport type {\r\n RunResult,\r\n SuiteResult,\r\n TestCaseResult,\r\n StepResult,\r\n RunStatus,\r\n RunConfig,\r\n} from './types/run.js';\r\n\r\nexport type {\r\n HealingEvent,\r\n HealingReport,\r\n HealingDecision,\r\n HealingStatus,\r\n HealingStrategy,\r\n StepFailure,\r\n} from './types/healing.js';\r\n\r\nexport type {\r\n VariableStore,\r\n VariableValue,\r\n SecretVariable,\r\n ResolvedVariables,\r\n} from './types/variable.js';\r\n\r\nexport type {\r\n AIProvider,\r\n PageContext,\r\n GenerationResult,\r\n GeneratedSuite,\r\n GeneratedCase,\r\n GeneratedStep,\r\n RouterStats,\r\n} from './types/ai.js';\r\n\r\n// Storage API (for programmatic use)\r\nexport * from './storage/index.js';\r\n\r\n// Utilities\r\nexport { createChildLogger, logger } from './utils/logger.js';\r\nexport {\r\n AssuremindError,\r\n ProviderError,\r\n ExecutionError,\r\n ConfigError,\r\n ValidationError,\r\n HealingError,\r\n StorageError,\r\n isAssuremindError,\r\n formatError,\r\n} from './utils/errors.js';\r\nexport { sanitizeGeneratedCode, toSlug, redactSecrets } from './utils/sanitize.js';\r\nexport { generateCacheKey, normalizeUrl, sha256 } from './utils/hash.js';\r\nexport { validateEnv, clearEnvCache, tryGetEnv } from './utils/env.js';\r\n","import { z } from 'zod';\r\n\r\nexport const ScreenshotModeSchema = z.enum(['off', 'on', 'only-on-failure']);\r\nexport const VideoModeSchema = z.enum(['off', 'on', 'on-first-retry', 'retain-on-failure']);\r\nexport const TraceModeSchema = z.enum(['off', 'on', 'on-first-retry', 'retain-on-failure']);\r\nexport const BrowserNameSchema = z.enum(['chromium', 'firefox', 'webkit']);\r\n\r\n/**\r\n * Page-load wait strategy applied after every navigation / action.\r\n * commit — wait only until the first network response (fastest)\r\n * domcontentloaded — wait until DOMContentLoaded fires (recommended default)\r\n * load — wait until the load event fires\r\n * networkidle — wait until no network activity for 500 ms (slowest, most stable)\r\n */\r\nexport const PageLoadStrategySchema = z.enum(['commit', 'domcontentloaded', 'load', 'networkidle']);\r\nexport const EnvironmentSchema = z.enum(['dev', 'stage', 'test', 'prod']);\r\nexport type Environment = z.infer<typeof EnvironmentSchema>;\r\n\r\nexport const EnvironmentUrlsSchema = z.object({\r\n dev: z.string().url().or(z.literal('')).default(''),\r\n stage: z.string().url().or(z.literal('')).default(''),\r\n test: z.string().url().or(z.literal('')).default(''),\r\n prod: z.string().url().or(z.literal('')).default(''),\r\n});\r\nexport type EnvironmentUrls = z.infer<typeof EnvironmentUrlsSchema>;\r\n\r\nexport type ScreenshotMode = z.infer<typeof ScreenshotModeSchema>;\r\nexport type VideoMode = z.infer<typeof VideoModeSchema>;\r\nexport type TraceMode = z.infer<typeof TraceModeSchema>;\r\nexport type BrowserName = z.infer<typeof BrowserNameSchema>;\r\nexport type PageLoadStrategy = z.infer<typeof PageLoadStrategySchema>;\r\n\r\nexport const HealingConfigSchema = z.object({\r\n enabled: z.boolean(),\r\n maxLevel: z.number().int().min(1).max(6),\r\n dailyBudget: z.number().positive(),\r\n autoPR: z.boolean(),\r\n});\r\n\r\nexport const ReportingConfigSchema = z.object({\r\n allure: z.boolean(),\r\n html: z.boolean(),\r\n json: z.boolean(),\r\n});\r\n\r\nexport const ViewportSchema = z.object({\r\n width: z.number().int().positive(),\r\n height: z.number().int().positive(),\r\n});\r\nexport type Viewport = z.infer<typeof ViewportSchema>;\r\n\r\nexport const EnvironmentProfileSchema = z.object({\r\n name: z.string().min(1),\r\n environment: EnvironmentSchema,\r\n baseUrl: z.string().url(),\r\n browsers: z.array(BrowserNameSchema).min(1),\r\n headless: z.boolean().optional(),\r\n});\r\n\r\nexport type EnvironmentProfile = z.infer<typeof EnvironmentProfileSchema>;\r\n\r\nexport const AutotestConfigSchema = z.object({\r\n baseUrl: z.string().url(),\r\n environment: EnvironmentSchema.default('stage'),\r\n environmentUrls: EnvironmentUrlsSchema.default({\r\n dev: '',\r\n stage: '',\r\n test: '',\r\n prod: '',\r\n }),\r\n browsers: z.array(BrowserNameSchema).min(1),\r\n headless: z.boolean(),\r\n viewport: ViewportSchema.default({ width: 1280, height: 720 }),\r\n timeout: z.number().int().positive(),\r\n retries: z.number().int().min(0),\r\n parallel: z.number().int().positive(),\r\n pageLoad: PageLoadStrategySchema.default('domcontentloaded'),\r\n screenshot: ScreenshotModeSchema,\r\n video: VideoModeSchema,\r\n trace: TraceModeSchema,\r\n healing: HealingConfigSchema,\r\n reporting: ReportingConfigSchema,\r\n studioPort: z.number().int().min(1024).max(65535),\r\n profiles: z.array(EnvironmentProfileSchema).default([]),\r\n activeProfile: z.string().optional(),\r\n /** Playwright device descriptor name for emulation (e.g. 'iPhone 15 Pro'). */\r\n device: z.string().optional(),\r\n});\r\n\r\nexport type HealingConfig = z.infer<typeof HealingConfigSchema>;\r\nexport type ReportingConfig = z.infer<typeof ReportingConfigSchema>;\r\nexport type AutotestConfig = z.infer<typeof AutotestConfigSchema>;\r\n\r\nexport const DEFAULT_CONFIG: AutotestConfig = {\r\n baseUrl: 'http://localhost:3000',\r\n environment: 'stage',\r\n environmentUrls: {\r\n dev: '',\r\n stage: 'http://localhost:3000',\r\n test: '',\r\n prod: '',\r\n },\r\n browsers: ['chromium'],\r\n headless: true,\r\n viewport: { width: 1280, height: 720 },\r\n timeout: 30000,\r\n retries: 1,\r\n parallel: 1,\r\n pageLoad: 'domcontentloaded',\r\n screenshot: 'only-on-failure',\r\n video: 'off',\r\n trace: 'on-first-retry',\r\n healing: {\r\n enabled: true,\r\n maxLevel: 5,\r\n dailyBudget: 5.0,\r\n autoPR: false,\r\n },\r\n reporting: {\r\n allure: true,\r\n html: true,\r\n json: true,\r\n },\r\n studioPort: 4400,\r\n profiles: [],\r\n};\r\n","import path from 'path';\r\nimport fs from 'fs-extra';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { TestSuite, TestSuiteSchema, type SuiteType } from '../types/suite.js';\r\nimport { StorageError, ValidationError } from '../utils/errors.js';\r\nimport { createChildLogger } from '../utils/logger.js';\r\nimport { toSlug } from '../utils/sanitize.js';\r\nimport { atomicWriteJson, readJson } from './utils.js';\r\n\r\nconst logger = createChildLogger('suite-store');\r\n\r\nconst SUITE_FILE = 'suite.json';\r\n\r\n/**\r\n * Reads a suite.json from the given suite directory.\r\n */\r\nexport async function readSuite(suiteDir: string): Promise<TestSuite> {\r\n const filePath = path.join(suiteDir, SUITE_FILE);\r\n\r\n if (!(await fs.pathExists(filePath))) {\r\n throw new StorageError(\r\n `Suite file not found at \"${filePath}\". ` +\r\n `Ensure the suite directory exists and contains a suite.json file.`,\r\n filePath,\r\n 'SUITE_NOT_FOUND',\r\n );\r\n }\r\n\r\n const raw = await readJson(filePath);\r\n const result = TestSuiteSchema.safeParse(raw);\r\n\r\n if (!result.success) {\r\n const issues = result.error.issues.map((i) => ` • ${i.path.join('.')}: ${i.message}`).join('\\n');\r\n throw new ValidationError(\r\n `Invalid suite.json at \"${filePath}\":\\n${issues}`,\r\n 'suite',\r\n 'INVALID_SUITE',\r\n );\r\n }\r\n\r\n // Infer type from folder path if not explicitly set in suite.json\r\n // (Zod .default('ui') always fills the value, so check the raw JSON instead)\r\n const rawObj = raw as Record<string, unknown>;\r\n if (!rawObj.type) {\r\n const parentDir = path.basename(path.dirname(suiteDir));\r\n if (parentDir === 'api') result.data.type = 'api';\r\n else if (parentDir === 'audit') result.data.type = 'audit';\r\n else if (parentDir === 'performance') result.data.type = 'audit'; // backward compat: performance dir → audit type\r\n else result.data.type = 'ui';\r\n }\r\n\r\n return result.data;\r\n}\r\n\r\n/**\r\n * Writes a suite.json atomically to the given suite directory.\r\n */\r\nexport async function writeSuite(suiteDir: string, suite: TestSuite): Promise<void> {\r\n await fs.ensureDir(suiteDir);\r\n const filePath = path.join(suiteDir, SUITE_FILE);\r\n\r\n const result = TestSuiteSchema.safeParse(suite);\r\n if (!result.success) {\r\n const issues = result.error.issues.map((i) => ` • ${i.path.join('.')}: ${i.message}`).join('\\n');\r\n throw new ValidationError(\r\n `Cannot write invalid suite to \"${filePath}\":\\n${issues}`,\r\n 'suite',\r\n 'INVALID_SUITE',\r\n );\r\n }\r\n\r\n await atomicWriteJson(filePath, result.data);\r\n logger.debug({ suiteId: suite.id, path: filePath }, 'Suite written');\r\n}\r\n\r\n/**\r\n * Creates a new suite directory and writes its suite.json.\r\n * Returns both the directory path and the generated suite ID.\r\n */\r\nexport async function createSuite(\r\n testsDir: string,\r\n suite: Omit<TestSuite, 'id' | 'createdAt' | 'updatedAt'>,\r\n): Promise<{ suiteDir: string; suiteId: string }> {\r\n const now = new Date().toISOString();\r\n const suiteType: SuiteType = suite.type ?? 'ui';\r\n const newSuite: TestSuite = {\r\n ...suite,\r\n type: suiteType,\r\n id: uuidv4(),\r\n createdAt: now,\r\n updatedAt: now,\r\n };\r\n\r\n const targetDir = path.join(testsDir, suiteType);\r\n const suiteDir = path.join(targetDir, toSlug(newSuite.name));\r\n if (await fs.pathExists(path.join(suiteDir, SUITE_FILE))) {\r\n throw new StorageError(\r\n `Suite directory already exists at \"${suiteDir}\". ` +\r\n `Choose a different name or delete the existing suite first.`,\r\n suiteDir,\r\n 'SUITE_ALREADY_EXISTS',\r\n );\r\n }\r\n\r\n await writeSuite(suiteDir, newSuite);\r\n logger.info({ suiteId: newSuite.id, path: suiteDir }, 'Suite created');\r\n return { suiteDir, suiteId: newSuite.id };\r\n}\r\n\r\n/**\r\n * Updates an existing suite (merges partial fields, updates updatedAt).\r\n */\r\nexport async function updateSuite(\r\n suiteDir: string,\r\n updates: Partial<Omit<TestSuite, 'id' | 'createdAt'>>,\r\n): Promise<TestSuite> {\r\n const existing = await readSuite(suiteDir);\r\n const updated: TestSuite = {\r\n ...existing,\r\n ...updates,\r\n id: existing.id,\r\n createdAt: existing.createdAt,\r\n updatedAt: new Date().toISOString(),\r\n };\r\n await writeSuite(suiteDir, updated);\r\n return updated;\r\n}\r\n\r\n/**\r\n * Deletes a suite directory and all its contents.\r\n */\r\nexport async function deleteSuite(suiteDir: string): Promise<void> {\r\n if (!(await fs.pathExists(suiteDir))) {\r\n throw new StorageError(\r\n `Suite directory not found at \"${suiteDir}\".`,\r\n suiteDir,\r\n 'SUITE_NOT_FOUND',\r\n );\r\n }\r\n await fs.remove(suiteDir);\r\n logger.info({ path: suiteDir }, 'Suite deleted');\r\n}\r\n\r\n/**\r\n * Lists all suite directories under testsDir.\r\n * Scans: testsDir/ui/, testsDir/api/, testsDir/performance/, and testsDir/ (legacy root).\r\n */\r\nexport async function listSuiteDirs(testsDir: string): Promise<string[]> {\r\n const suiteDirs: string[] = [];\r\n const searchDirs = [\r\n path.join(testsDir, 'ui'),\r\n path.join(testsDir, 'api'),\r\n path.join(testsDir, 'audit'),\r\n path.join(testsDir, 'performance'), // legacy: keep scanning for backward compat\r\n testsDir, // legacy: suites at root level\r\n ];\r\n\r\n for (const baseDir of searchDirs) {\r\n if (!(await fs.pathExists(baseDir))) continue;\r\n const entries = await fs.readdir(baseDir, { withFileTypes: true });\r\n for (const entry of entries) {\r\n if (!entry.isDirectory()) continue;\r\n // Skip the ui/, api/, and performance/ subdirs themselves when scanning root\r\n if (baseDir === testsDir && (entry.name === 'ui' || entry.name === 'api' || entry.name === 'audit' || entry.name === 'performance')) continue;\r\n const suiteFile = path.join(baseDir, entry.name, SUITE_FILE);\r\n if (await fs.pathExists(suiteFile)) {\r\n suiteDirs.push(path.join(baseDir, entry.name));\r\n }\r\n }\r\n }\r\n\r\n return suiteDirs;\r\n}\r\n\r\n/**\r\n * Moves a suite between ui/ and api/ folders when type changes.\r\n */\r\nexport async function moveSuiteType(\r\n testsDir: string,\r\n suiteDir: string,\r\n newType: SuiteType,\r\n): Promise<string> {\r\n const suite = await readSuite(suiteDir);\r\n const suiteDirName = path.basename(suiteDir);\r\n const newParent = path.join(testsDir, newType);\r\n const newSuiteDir = path.join(newParent, suiteDirName);\r\n\r\n if (suiteDir === newSuiteDir) return suiteDir; // already in correct folder\r\n\r\n await fs.ensureDir(newParent);\r\n if (await fs.pathExists(newSuiteDir)) {\r\n throw new StorageError(\r\n `Cannot move suite — \"${newSuiteDir}\" already exists.`,\r\n newSuiteDir,\r\n 'SUITE_ALREADY_EXISTS',\r\n );\r\n }\r\n\r\n await fs.move(suiteDir, newSuiteDir);\r\n // Update type in suite.json\r\n await updateSuite(newSuiteDir, { type: newType });\r\n logger.info({ suiteId: suite.id, from: suiteDir, to: newSuiteDir }, 'Suite moved');\r\n return newSuiteDir;\r\n}\r\n\r\n/**\r\n * Finds the suite directory for a given suite UUID.\r\n * Scans all suite dirs and returns the one whose suite.json has the matching id.\r\n * Returns null if not found.\r\n */\r\nexport async function findSuiteDirById(testsDir: string, id: string): Promise<string | null> {\r\n const dirs = await listSuiteDirs(testsDir);\r\n for (const dir of dirs) {\r\n try {\r\n const suite = await readSuite(dir);\r\n if (suite.id === id) return dir;\r\n } catch {\r\n // skip malformed suites\r\n }\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Reads all suites from testsDir.\r\n */\r\nexport async function listSuites(testsDir: string): Promise<TestSuite[]> {\r\n const dirs = await listSuiteDirs(testsDir);\r\n const suites: TestSuite[] = [];\r\n\r\n for (const dir of dirs) {\r\n try {\r\n suites.push(await readSuite(dir));\r\n } catch (err) {\r\n logger.warn({ path: dir, err }, 'Failed to read suite — skipping');\r\n }\r\n }\r\n\r\n return suites;\r\n}\r\n\r\n/**\r\n * Reads all suites with their case counts (lightweight — counts files, doesn't parse).\r\n */\r\nexport async function listSuitesWithCounts(testsDir: string): Promise<(TestSuite & { caseCount: number })[]> {\r\n const dirs = await listSuiteDirs(testsDir);\r\n const suites: (TestSuite & { caseCount: number })[] = [];\r\n\r\n for (const dir of dirs) {\r\n try {\r\n const suite = await readSuite(dir);\r\n const entries = await fs.readdir(dir, { withFileTypes: true });\r\n const caseCount = entries.filter((e) => e.isFile() && e.name.endsWith('.test.json')).length;\r\n suites.push({ ...suite, caseCount });\r\n } catch (err) {\r\n logger.warn({ path: dir, err }, 'Failed to read suite — skipping');\r\n }\r\n }\r\n\r\n return suites;\r\n}\r\n","import { z } from 'zod';\r\n\r\nexport type Priority = 'critical' | 'high' | 'medium' | 'low';\r\nexport type GenerationStrategy = 'template' | 'cache' | 'batch' | 'fast' | 'primary';\r\n\r\nexport const TestStepSchema = z.object({\r\n id: z.string().min(1),\r\n order: z.number().int().positive(),\r\n instruction: z.string().min(1),\r\n generatedCode: z.string(),\r\n strategy: z.enum(['template', 'cache', 'batch', 'fast', 'primary']),\r\n stepType: z.enum(['ui', 'api', 'mock']).default('ui'),\r\n lastHealed: z.string().nullable(),\r\n timeout: z.number().int().positive().optional(),\r\n retries: z.number().int().min(0).optional(),\r\n mockUrl: z.string().optional(),\r\n mockResponse: z.string().optional(),\r\n mockStatus: z.number().int().optional(),\r\n runAudit: z.boolean().optional(), // Mark this step as a Lighthouse audit checkpoint\r\n});\r\n\r\nexport const DataSourceSchema = z.object({\r\n type: z.enum(['inline', 'json-file', 'csv-file']),\r\n path: z.string().optional(),\r\n data: z.array(z.record(z.string())).optional(),\r\n}).optional();\r\n\r\nconst CaseHookStepSchema = z.object({\r\n id: z.string(),\r\n instruction: z.string(),\r\n generatedCode: z.string().default(''),\r\n order: z.number().int().default(0),\r\n});\r\n\r\nconst CaseHooksSchema = z.object({\r\n before: z.array(CaseHookStepSchema).default([]),\r\n after: z.array(CaseHookStepSchema).default([]),\r\n}).default({ before: [], after: [] });\r\n\r\nexport type CaseHookStep = z.infer<typeof CaseHookStepSchema>;\r\nexport type CaseHooks = z.infer<typeof CaseHooksSchema>;\r\n\r\nexport const TestCaseSchema = z.object({\r\n id: z.string().min(1),\r\n name: z.string().min(1),\r\n description: z.string(),\r\n tags: z.array(z.string()),\r\n priority: z.enum(['critical', 'high', 'medium', 'low']),\r\n timeout: z.number().int().positive().optional(),\r\n dataSource: DataSourceSchema,\r\n steps: z.array(TestStepSchema),\r\n caseHooks: CaseHooksSchema,\r\n lighthouseCategories: z.array(z.enum(['performance', 'accessibility', 'seo']))\r\n .default(['performance', 'accessibility', 'seo']),\r\n createdAt: z.string().datetime(),\r\n updatedAt: z.string().datetime(),\r\n});\r\n\r\nexport type SuiteType = 'ui' | 'api' | 'audit' | 'performance';\r\n\r\nexport const TestSuiteSchema = z.object({\r\n id: z.string().min(1),\r\n name: z.string().min(1),\r\n description: z.string(),\r\n tags: z.array(z.string()),\r\n type: z.enum(['ui', 'api', 'audit', 'performance']).default('ui'),\r\n timeout: z.number().int().positive().optional(),\r\n createdAt: z.string().datetime(),\r\n updatedAt: z.string().datetime(),\r\n});\r\n\r\n// ─── Suite Hooks (before_all / before_each / after_each / after_all) ─────────\r\n\r\nexport const HookTypeEnum = z.enum(['before_all', 'before_each', 'after_each', 'after_all']);\r\nexport type HookType = z.infer<typeof HookTypeEnum>;\r\n\r\nexport const SuiteHooksSchema = z.object({\r\n before_all: z.array(TestStepSchema).default([]),\r\n before_each: z.array(TestStepSchema).default([]),\r\n after_each: z.array(TestStepSchema).default([]),\r\n after_all: z.array(TestStepSchema).default([]),\r\n});\r\n\r\nexport type TestStep = z.infer<typeof TestStepSchema>;\r\nexport type TestCase = z.infer<typeof TestCaseSchema>;\r\nexport type TestSuite = z.infer<typeof TestSuiteSchema>;\r\nexport type SuiteHooks = z.infer<typeof SuiteHooksSchema>;\r\n","export class AssuremindError extends Error {\r\n public readonly code: string;\r\n\r\n constructor(message: string, code: string) {\r\n super(message);\r\n this.name = 'AssuremindError';\r\n this.code = code;\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n\r\nexport class ProviderError extends AssuremindError {\r\n public readonly provider: string;\r\n\r\n constructor(message: string, provider: string, code = 'PROVIDER_ERROR') {\r\n super(message, code);\r\n this.name = 'ProviderError';\r\n this.provider = provider;\r\n }\r\n}\r\n\r\nexport class ExecutionError extends AssuremindError {\r\n public readonly stepId: string;\r\n\r\n constructor(message: string, stepId: string, code = 'EXECUTION_ERROR') {\r\n super(message, code);\r\n this.name = 'ExecutionError';\r\n this.stepId = stepId;\r\n }\r\n}\r\n\r\nexport class ConfigError extends AssuremindError {\r\n constructor(message: string, code = 'CONFIG_ERROR') {\r\n super(message, code);\r\n this.name = 'ConfigError';\r\n }\r\n}\r\n\r\nexport class ValidationError extends AssuremindError {\r\n public readonly field?: string;\r\n\r\n constructor(message: string, field?: string, code = 'VALIDATION_ERROR') {\r\n super(message, code);\r\n this.name = 'ValidationError';\r\n this.field = field;\r\n }\r\n}\r\n\r\nexport class HealingError extends AssuremindError {\r\n public readonly level: number;\r\n\r\n constructor(message: string, level: number, code = 'HEALING_ERROR') {\r\n super(message, code);\r\n this.name = 'HealingError';\r\n this.level = level;\r\n }\r\n}\r\n\r\nexport class StorageError extends AssuremindError {\r\n public readonly path: string;\r\n\r\n constructor(message: string, path: string, code = 'STORAGE_ERROR') {\r\n super(message, code);\r\n this.name = 'StorageError';\r\n this.path = path;\r\n }\r\n}\r\n\r\nexport function isAssuremindError(error: unknown): error is AssuremindError {\r\n return error instanceof AssuremindError;\r\n}\r\n\r\nexport function formatError(error: unknown): string {\r\n if (error instanceof AssuremindError) {\r\n return `[${error.code}] ${error.message}`;\r\n }\r\n if (error instanceof Error) {\r\n return error.message;\r\n }\r\n return String(error);\r\n}\r\n","import pino from 'pino';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\n\r\nconst isDevelopment = process.env['NODE_ENV'] !== 'production';\r\n\r\nconst transport = isDevelopment\r\n ? {\r\n target: 'pino-pretty',\r\n options: {\r\n colorize: true,\r\n translateTime: 'HH:MM:ss',\r\n ignore: 'pid,hostname',\r\n messageFormat: '[assuremind] {msg}',\r\n },\r\n }\r\n : undefined;\r\n\r\nexport const logger = pino(\r\n {\r\n level: process.env['LOG_LEVEL'] ?? 'info',\r\n base: { name: 'assuremind' },\r\n },\r\n transport ? pino.transport(transport) : undefined,\r\n);\r\n\r\nexport type Logger = typeof logger;\r\n\r\nexport function createChildLogger(component: string): pino.Logger {\r\n return logger.child({ component });\r\n}\r\n\r\n// ─── Per-run file logging ─────────────────────────────────────────────────────\r\n\r\n/**\r\n * Creates a per-run log file and returns a writable stream + file path.\r\n * All log entries during the run are written to this file in addition to console.\r\n */\r\nexport interface RunLogHandle {\r\n logFilePath: string;\r\n write: (entry: string) => void;\r\n close: () => void;\r\n}\r\n\r\nexport async function createRunLogFile(rootDir: string, runId: string): Promise<RunLogHandle> {\r\n const logsDir = path.join(rootDir, 'results', 'logs');\r\n await fs.ensureDir(logsDir);\r\n const logFilePath = path.join(logsDir, `run-${runId}.log`);\r\n const stream = fs.createWriteStream(logFilePath, { flags: 'a', encoding: 'utf-8' });\r\n\r\n // Write header\r\n stream.write(`=== AutoMind Test Run: ${runId} ===\\n`);\r\n stream.write(`Started: ${new Date().toISOString()}\\n`);\r\n stream.write('='.repeat(60) + '\\n\\n');\r\n\r\n return {\r\n logFilePath,\r\n write: (entry: string) => {\r\n stream.write(entry + '\\n');\r\n },\r\n close: () => {\r\n stream.write('\\n' + '='.repeat(60) + '\\n');\r\n stream.write(`Completed: ${new Date().toISOString()}\\n`);\r\n stream.end();\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Creates a pino destination that writes to both console and a run log file.\r\n * Returns a child logger that tees to the file.\r\n */\r\nexport function createRunLogger(runLogHandle: RunLogHandle): pino.Logger {\r\n const runLogger = pino(\r\n {\r\n level: process.env['LOG_LEVEL'] ?? 'info',\r\n base: { name: 'assuremind' },\r\n timestamp: pino.stdTimeFunctions.isoTime,\r\n },\r\n {\r\n write(msg: string) {\r\n // Write to the run log file (plain JSON line)\r\n runLogHandle.write(msg.trim());\r\n },\r\n },\r\n );\r\n return runLogger;\r\n}\r\n","import { ValidationError } from './errors.js';\r\n\r\n/**\r\n * Strips markdown code fences from AI-generated code responses.\r\n * Handles ```typescript, ```ts, ```javascript, ```js, and plain ``` blocks.\r\n */\r\nexport function stripCodeFences(raw: string): string {\r\n const fencePattern = /^```(?:typescript|javascript|ts|js)?\\n?([\\s\\S]*?)```\\s*$/m;\r\n const match = raw.match(fencePattern);\r\n if (match?.[1] !== undefined) {\r\n return match[1].trim();\r\n }\r\n return raw.trim();\r\n}\r\n\r\n/**\r\n * Robustly extracts the first complete JSON object `{...}` or array `[...]`\r\n * from an AI response that may have preamble text, markdown fences, or\r\n * trailing explanation. Works even when models ignore \"return only JSON\" instructions.\r\n *\r\n * Returns the extracted JSON string, or the original input if no block is found.\r\n */\r\nexport function extractJsonBlock(raw: string): string {\r\n // First try stripping code fences\r\n const stripped = stripCodeFences(raw);\r\n\r\n // If already valid JSON, return as-is\r\n try { JSON.parse(stripped); return stripped; } catch { /* continue */ }\r\n\r\n // Find the first '{' or '[' and extract the matching closing bracket\r\n const firstObj = stripped.indexOf('{');\r\n const firstArr = stripped.indexOf('[');\r\n const start = firstObj === -1 ? firstArr\r\n : firstArr === -1 ? firstObj\r\n : Math.min(firstObj, firstArr);\r\n\r\n if (start === -1) return stripped;\r\n\r\n const opener = stripped[start];\r\n const closer = opener === '{' ? '}' : ']';\r\n let depth = 0;\r\n let inString = false;\r\n let escape = false;\r\n\r\n for (let i = start; i < stripped.length; i++) {\r\n const ch = stripped[i];\r\n if (escape) { escape = false; continue; }\r\n if (ch === '\\\\' && inString) { escape = true; continue; }\r\n if (ch === '\"') { inString = !inString; continue; }\r\n if (inString) continue;\r\n if (ch === opener) depth++;\r\n else if (ch === closer) {\r\n depth--;\r\n if (depth === 0) return stripped.slice(start, i + 1);\r\n }\r\n }\r\n\r\n // Didn't find matching close — return from start to end (truncated, let repair handle it)\r\n return stripped.slice(start);\r\n}\r\n\r\n/**\r\n * Forbidden globals that must not appear in generated code.\r\n * Generated code runs inside `new Function('page', 'context', 'expect', code)`,\r\n * so only page, context, and expect are available anyway — but we validate\r\n * defensively to catch prompt-injection attempts.\r\n */\r\nconst FORBIDDEN_PATTERNS: ReadonlyArray<RegExp> = [\r\n /\\brequire\\s*\\(/,\r\n /\\bimport\\s*\\(/,\r\n /\\bprocess\\b/,\r\n /\\bchild_process\\b/,\r\n /\\bexec\\s*\\(/,\r\n /\\bspawn\\s*\\(/,\r\n /\\beval\\s*\\(/,\r\n /\\bFunction\\s*\\(/,\r\n /\\b__dirname\\b/,\r\n /\\b__filename\\b/,\r\n /\\bglobal\\b/,\r\n /\\bwindow\\.location\\.href\\s*=/,\r\n /\\bdocument\\.cookie\\b/,\r\n /\\blocalStorage\\b/,\r\n /\\bsessionStorage\\b/,\r\n /\\bIndexedDB\\b/,\r\n /\\bXMLHttpRequest\\b/,\r\n /\\bfetch\\s*\\(/,\r\n /\\bWebSocket\\s*\\(/,\r\n];\r\n\r\n/**\r\n * Validates that generated code is safe to execute.\r\n * Throws a ValidationError if forbidden patterns are detected.\r\n */\r\nexport function validateGeneratedCode(code: string): void {\r\n for (const pattern of FORBIDDEN_PATTERNS) {\r\n if (pattern.test(code)) {\r\n throw new ValidationError(\r\n `Generated code contains forbidden pattern: ${pattern.source}. ` +\r\n `This may be a prompt injection attempt. Please regenerate the step.`,\r\n 'generatedCode',\r\n 'UNSAFE_CODE',\r\n );\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Removes known Playwright anti-patterns from any generated code.\r\n * Exported so smart-router can apply it to template + cache hits too.\r\n *\r\n * Patterns removed:\r\n * 1. `.or(locator).first()` / `.or(locator).last()` / `.or(locator)`\r\n * AI models often chain .or() when unsure; we always prefer a single locator.\r\n * Handles one level of nested parens which covers all getBy* calls.\r\n *\r\n * 2. Standalone `.first()` / `.last()` after any locator (not method chaining)\r\n * e.g. page.getByRole('button', { name: '...' }).first().click()\r\n * → page.getByRole('button', { name: '...' }).click()\r\n */\r\n/**\r\n * Post-processes AI-generated code to fix incorrect selector choices.\r\n *\r\n * Rule: if the instruction says \"...button...\" and the code uses\r\n * page.getByText('X').click() or page.getByText(\"X\").click()\r\n * rewrite to:\r\n * page.getByRole('button', { name: 'X' }).click()\r\n *\r\n * This is a deterministic fallback for when the AI ignores prompt rules.\r\n */\r\nexport function fixButtonSelectors(instruction: string, code: string): string {\r\n const mentionsButton = /\\bbutton\\b/i.test(instruction);\r\n if (!mentionsButton) return code;\r\n\r\n // Match getByText('Name') or getByText(\"Name\") followed by .click()\r\n return code.replace(\r\n /page\\.getByText\\((['\"])(.*?)\\1\\)\\.click\\(\\)/g,\r\n (_match, _q, name: string) => `page.getByRole('button', { name: '${name}' }).click()`,\r\n );\r\n}\r\n\r\nexport function fixAntiPatterns(code: string): string {\r\n let result = code;\r\n\r\n // Remove .or(anyLocator) chains (with optional trailing .first()/.last())\r\n // Regex handles one level of nested parens: covers page.getByRole('btn', { name: 'x' })\r\n result = result.replace(\r\n /\\.or\\((?:[^()]*|\\([^()]*\\))*\\)(?:\\.(?:first|last)\\(\\))?/g,\r\n '',\r\n );\r\n\r\n // Remove leftover .first() / .last() that directly precede .click()/.fill()/etc.\r\n // i.e. locator.first().click() → locator.click()\r\n result = result.replace(/\\.(?:first|last)\\(\\)(?=\\.\\w)/g, '');\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Sanitizes AI-generated code: strips fences, removes anti-patterns,\r\n * trims whitespace, and validates against forbidden patterns.\r\n */\r\nexport function sanitizeGeneratedCode(raw: string): string {\r\n const stripped = stripCodeFences(raw);\r\n\r\n if (!stripped) {\r\n throw new ValidationError(\r\n 'AI returned an empty code response. Please try regenerating.',\r\n 'generatedCode',\r\n 'EMPTY_CODE',\r\n );\r\n }\r\n\r\n const fixed = fixAntiPatterns(stripped);\r\n validateGeneratedCode(fixed);\r\n return fixed;\r\n}\r\n\r\n/**\r\n * Sanitizes a string for safe use as a filename component.\r\n * Replaces whitespace and special chars with hyphens, lowercases.\r\n */\r\nexport function toSlug(input: string): string {\r\n return input\r\n .toLowerCase()\r\n .trim()\r\n .replace(/[^a-z0-9]+/g, '-')\r\n .replace(/^-+|-+$/g, '');\r\n}\r\n\r\n/**\r\n * Redacts secret variable values from a string so they never appear in logs.\r\n */\r\nexport function redactSecrets(\r\n text: string,\r\n secrets: ReadonlyArray<string>,\r\n): string {\r\n let result = text;\r\n for (const secret of secrets) {\r\n if (secret.length > 0) {\r\n result = result.replaceAll(secret, '[REDACTED]');\r\n }\r\n }\r\n return result;\r\n}\r\n","import path from 'path';\r\nimport fs from 'fs-extra';\r\nimport { StorageError } from '../utils/errors.js';\r\n\r\n/**\r\n * Atomically writes JSON to a file using a temp file + rename pattern.\r\n * This ensures the file is never left in a partially-written state.\r\n */\r\nexport async function atomicWriteJson(filePath: string, data: unknown): Promise<void> {\r\n const dir = path.dirname(filePath);\r\n await fs.ensureDir(dir);\r\n\r\n const tmpPath = `${filePath}.${process.pid}.tmp`;\r\n try {\r\n await fs.writeJson(tmpPath, data, { spaces: 2 });\r\n await fs.rename(tmpPath, filePath);\r\n } catch (err) {\r\n // Clean up temp file on failure\r\n await fs.remove(tmpPath).catch(() => undefined);\r\n throw new StorageError(\r\n `Failed to write file \"${filePath}\": ${err instanceof Error ? err.message : String(err)}`,\r\n filePath,\r\n 'WRITE_FAILED',\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Reads and parses a JSON file, returning the parsed value.\r\n * Throws a StorageError if the file cannot be read or parsed.\r\n */\r\nexport async function readJson(filePath: string): Promise<unknown> {\r\n try {\r\n return await fs.readJson(filePath);\r\n } catch (err) {\r\n throw new StorageError(\r\n `Failed to read JSON file \"${filePath}\": ${err instanceof Error ? err.message : String(err)}`,\r\n filePath,\r\n 'READ_FAILED',\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Reads a plain text file. Throws StorageError on failure.\r\n */\r\nexport async function readText(filePath: string): Promise<string> {\r\n try {\r\n return await fs.readFile(filePath, 'utf8');\r\n } catch (err) {\r\n throw new StorageError(\r\n `Failed to read file \"${filePath}\": ${err instanceof Error ? err.message : String(err)}`,\r\n filePath,\r\n 'READ_FAILED',\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Atomically writes plain text to a file.\r\n */\r\nexport async function atomicWriteText(filePath: string, content: string): Promise<void> {\r\n const dir = path.dirname(filePath);\r\n await fs.ensureDir(dir);\r\n\r\n const tmpPath = `${filePath}.${process.pid}.tmp`;\r\n try {\r\n await fs.writeFile(tmpPath, content, 'utf8');\r\n await fs.rename(tmpPath, filePath);\r\n } catch (err) {\r\n await fs.remove(tmpPath).catch(() => undefined);\r\n throw new StorageError(\r\n `Failed to write file \"${filePath}\": ${err instanceof Error ? err.message : String(err)}`,\r\n filePath,\r\n 'WRITE_FAILED',\r\n );\r\n }\r\n}\r\n","import path from 'path';\r\nimport fs from 'fs-extra';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { TestCase, TestCaseSchema } from '../types/suite.js';\r\nimport { StorageError, ValidationError } from '../utils/errors.js';\r\nimport { createChildLogger } from '../utils/logger.js';\r\nimport { toSlug } from '../utils/sanitize.js';\r\nimport { atomicWriteJson, readJson } from './utils.js';\r\n\r\nconst logger = createChildLogger('case-store');\r\n\r\nconst CASE_EXTENSION = '.test.json';\r\n\r\n/**\r\n * Reads a .test.json file from the given path.\r\n */\r\nexport async function readCase(casePath: string): Promise<TestCase> {\r\n if (!(await fs.pathExists(casePath))) {\r\n throw new StorageError(\r\n `Test case file not found at \"${casePath}\".`,\r\n casePath,\r\n 'CASE_NOT_FOUND',\r\n );\r\n }\r\n\r\n const raw = await readJson(casePath);\r\n const result = TestCaseSchema.safeParse(raw);\r\n\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Invalid test case file at \"${casePath}\":\\n${issues}`,\r\n 'case',\r\n 'INVALID_CASE',\r\n );\r\n }\r\n\r\n return result.data;\r\n}\r\n\r\n/**\r\n * Writes a TestCase atomically to the given path.\r\n */\r\nexport async function writeCase(casePath: string, testCase: TestCase): Promise<void> {\r\n const result = TestCaseSchema.safeParse(testCase);\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Cannot write invalid test case to \"${casePath}\":\\n${issues}`,\r\n 'case',\r\n 'INVALID_CASE',\r\n );\r\n }\r\n\r\n await atomicWriteJson(casePath, result.data);\r\n logger.debug({ caseId: testCase.id, path: casePath }, 'Test case written');\r\n}\r\n\r\n/**\r\n * Creates a new .test.json file in the given suite directory.\r\n * Returns the path to the created file.\r\n */\r\nexport async function createCase(\r\n suiteDir: string,\r\n testCase: Omit<TestCase, 'id' | 'createdAt' | 'updatedAt'>,\r\n): Promise<string> {\r\n const now = new Date().toISOString();\r\n const newCase: TestCase = {\r\n ...testCase,\r\n id: uuidv4(),\r\n createdAt: now,\r\n updatedAt: now,\r\n };\r\n\r\n const casePath = path.join(suiteDir, `${toSlug(newCase.name)}${CASE_EXTENSION}`);\r\n await writeCase(casePath, newCase);\r\n logger.info({ caseId: newCase.id, path: casePath }, 'Test case created');\r\n return casePath;\r\n}\r\n\r\n/**\r\n * Updates an existing test case (merges partial fields, bumps updatedAt).\r\n */\r\nexport async function updateCase(\r\n casePath: string,\r\n updates: Partial<Omit<TestCase, 'id' | 'createdAt'>>,\r\n): Promise<TestCase> {\r\n const existing = await readCase(casePath);\r\n const updated: TestCase = {\r\n ...existing,\r\n ...updates,\r\n id: existing.id,\r\n createdAt: existing.createdAt,\r\n updatedAt: new Date().toISOString(),\r\n };\r\n await writeCase(casePath, updated);\r\n return updated;\r\n}\r\n\r\n/**\r\n * Deletes a .test.json file.\r\n */\r\nexport async function deleteCase(casePath: string): Promise<void> {\r\n if (!(await fs.pathExists(casePath))) {\r\n throw new StorageError(\r\n `Test case file not found at \"${casePath}\".`,\r\n casePath,\r\n 'CASE_NOT_FOUND',\r\n );\r\n }\r\n await fs.remove(casePath);\r\n logger.info({ path: casePath }, 'Test case deleted');\r\n}\r\n\r\n/**\r\n * Lists all .test.json file paths within a suite directory.\r\n */\r\nexport async function listCasePaths(suiteDir: string): Promise<string[]> {\r\n if (!(await fs.pathExists(suiteDir))) return [];\r\n\r\n const entries = await fs.readdir(suiteDir, { withFileTypes: true });\r\n return entries\r\n .filter((e) => e.isFile() && e.name.endsWith(CASE_EXTENSION))\r\n .map((e) => path.join(suiteDir, e.name));\r\n}\r\n\r\n/**\r\n * Reads all test cases from a suite directory.\r\n */\r\nexport async function listCases(suiteDir: string): Promise<TestCase[]> {\r\n const paths = await listCasePaths(suiteDir);\r\n const cases: TestCase[] = [];\r\n\r\n for (const casePath of paths) {\r\n try {\r\n cases.push(await readCase(casePath));\r\n } catch (err) {\r\n logger.warn({ path: casePath, err }, 'Failed to read test case — skipping');\r\n }\r\n }\r\n\r\n return cases.sort((a, b) => a.name.localeCompare(b.name));\r\n}\r\n\r\n/**\r\n * Returns the .test.json path for a case given its suite directory and case name.\r\n */\r\nexport function getCasePath(suiteDir: string, caseName: string): string {\r\n return path.join(suiteDir, `${toSlug(caseName)}${CASE_EXTENSION}`);\r\n}\r\n\r\n/**\r\n * Finds the .test.json file path for a case by its UUID.\r\n * Scans all case files in suiteDir and returns the path whose id matches.\r\n * Returns null if not found.\r\n */\r\nexport async function findCasePathById(suiteDir: string, id: string): Promise<string | null> {\r\n const paths = await listCasePaths(suiteDir);\r\n for (const casePath of paths) {\r\n try {\r\n const tc = await readCase(casePath);\r\n if (tc.id === id) return casePath;\r\n } catch {\r\n // skip malformed files\r\n }\r\n }\r\n return null;\r\n}\r\n","import path from 'path';\r\nimport fs from 'fs-extra';\r\nimport { VariableStore, VariableStoreSchema, ResolvedVariables, resolveVariableValue } from '../types/variable.js';\r\nimport { StorageError, ValidationError } from '../utils/errors.js';\r\nimport { createChildLogger } from '../utils/logger.js';\r\nimport { atomicWriteJson, readJson } from './utils.js';\r\n\r\nconst logger = createChildLogger('variable-store');\r\n\r\nconst VARIABLES_DIR = 'variables';\r\nconst GLOBAL_FILE = 'global.json';\r\n\r\nfunction envFileName(env: string): string {\r\n return `${env}.env.json`;\r\n}\r\n\r\n/**\r\n * Reads a variables JSON file from disk and validates its shape.\r\n */\r\nexport async function readVariables(filePath: string): Promise<VariableStore> {\r\n if (!(await fs.pathExists(filePath))) {\r\n return {};\r\n }\r\n\r\n const raw = await readJson(filePath);\r\n const result = VariableStoreSchema.safeParse(raw);\r\n\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Invalid variables file at \"${filePath}\":\\n${issues}`,\r\n 'variables',\r\n 'INVALID_VARIABLES',\r\n );\r\n }\r\n\r\n return result.data;\r\n}\r\n\r\n/**\r\n * Writes a variables file atomically.\r\n */\r\nexport async function writeVariables(filePath: string, store: VariableStore): Promise<void> {\r\n const result = VariableStoreSchema.safeParse(store);\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Cannot write invalid variables to \"${filePath}\":\\n${issues}`,\r\n 'variables',\r\n 'INVALID_VARIABLES',\r\n );\r\n }\r\n await atomicWriteJson(filePath, result.data);\r\n logger.debug({ path: filePath }, 'Variables written');\r\n}\r\n\r\n/**\r\n * Reads the global variables file.\r\n */\r\nexport async function readGlobalVariables(rootDir: string): Promise<VariableStore> {\r\n const filePath = path.join(rootDir, VARIABLES_DIR, GLOBAL_FILE);\r\n return readVariables(filePath);\r\n}\r\n\r\n/**\r\n * Reads environment-specific variables (e.g. dev, staging, prod).\r\n */\r\nexport async function readEnvVariables(rootDir: string, env: string): Promise<VariableStore> {\r\n const filePath = path.join(rootDir, VARIABLES_DIR, envFileName(env));\r\n return readVariables(filePath);\r\n}\r\n\r\n/**\r\n * Merges global + env-specific variables, resolving all values to strings.\r\n * Environment variables override global variables.\r\n * Secrets are resolved to their plain values (never sent to AI — caller must redact).\r\n */\r\nexport async function resolveVariables(rootDir: string, env?: string): Promise<ResolvedVariables> {\r\n const global = await readGlobalVariables(rootDir);\r\n const envSpecific = env ? await readEnvVariables(rootDir, env) : {};\r\n\r\n const merged: VariableStore = { ...global, ...envSpecific };\r\n const resolved: ResolvedVariables = {};\r\n\r\n for (const [key, value] of Object.entries(merged)) {\r\n resolved[key] = resolveVariableValue(value);\r\n }\r\n\r\n return resolved;\r\n}\r\n\r\n/**\r\n * Sets a variable in the global variables file.\r\n */\r\nexport async function setGlobalVariable(\r\n rootDir: string,\r\n key: string,\r\n value: VariableStore[string],\r\n): Promise<void> {\r\n const filePath = path.join(rootDir, VARIABLES_DIR, GLOBAL_FILE);\r\n await fs.ensureDir(path.dirname(filePath));\r\n const existing = await readVariables(filePath);\r\n existing[key] = value;\r\n await writeVariables(filePath, existing);\r\n}\r\n\r\n/**\r\n * Deletes a variable from the global variables file.\r\n */\r\nexport async function deleteGlobalVariable(rootDir: string, key: string): Promise<void> {\r\n const filePath = path.join(rootDir, VARIABLES_DIR, GLOBAL_FILE);\r\n const existing = await readVariables(filePath);\r\n if (!(key in existing)) {\r\n throw new StorageError(\r\n `Variable \"${key}\" not found in global variables.`,\r\n filePath,\r\n 'VARIABLE_NOT_FOUND',\r\n );\r\n }\r\n delete existing[key];\r\n await writeVariables(filePath, existing);\r\n}\r\n\r\n/**\r\n * Lists all available variable files (global + env-specific).\r\n */\r\nexport async function listVariableFiles(rootDir: string): Promise<string[]> {\r\n const dir = path.join(rootDir, VARIABLES_DIR);\r\n if (!(await fs.pathExists(dir))) return [];\r\n\r\n const entries = await fs.readdir(dir, { withFileTypes: true });\r\n return entries\r\n .filter((e) => e.isFile() && e.name.endsWith('.json'))\r\n .map((e) => path.join(dir, e.name));\r\n}\r\n","import { z } from 'zod';\r\n\r\nexport const SecretVariableSchema = z.object({\r\n value: z.string(),\r\n secret: z.literal(true),\r\n});\r\n\r\nexport const VariableValueSchema = z.union([z.string(), SecretVariableSchema]);\r\n\r\nexport const VariableStoreSchema = z.record(z.string(), VariableValueSchema);\r\n\r\nexport type SecretVariable = z.infer<typeof SecretVariableSchema>;\r\nexport type VariableValue = z.infer<typeof VariableValueSchema>;\r\nexport type VariableStore = z.infer<typeof VariableStoreSchema>;\r\n\r\nexport interface ResolvedVariables {\r\n [key: string]: string;\r\n}\r\n\r\nexport function isSecretVariable(value: VariableValue): value is SecretVariable {\r\n return typeof value === 'object' && value.secret === true;\r\n}\r\n\r\nexport function resolveVariableValue(value: VariableValue): string {\r\n if (isSecretVariable(value)) {\r\n return value.value;\r\n }\r\n return value;\r\n}\r\n","import path from 'path';\r\nimport fs from 'fs-extra';\r\nimport { AutotestConfig, AutotestConfigSchema, DEFAULT_CONFIG } from '../types/config.js';\r\nimport { ConfigError, ValidationError } from '../utils/errors.js';\r\nimport { createChildLogger } from '../utils/logger.js';\r\nimport { atomicWriteJson, atomicWriteText, readJson } from './utils.js';\r\n\r\nconst logger = createChildLogger('config-store');\r\n\r\n/** Runtime config is stored as JSON for reliable loading without TS compilation. */\r\nconst CONFIG_JSON = 'autotest.config.json';\r\n/** Human-readable TypeScript config kept in sync with the JSON. */\r\nconst CONFIG_TS = 'autotest.config.ts';\r\n\r\n/**\r\n * Reads the runtime config from autotest.config.json.\r\n * Falls back to DEFAULT_CONFIG if the file does not exist.\r\n */\r\nexport async function readConfig(rootDir: string): Promise<AutotestConfig> {\r\n const jsonPath = path.join(rootDir, CONFIG_JSON);\r\n\r\n if (!(await fs.pathExists(jsonPath))) {\r\n logger.debug({ rootDir }, 'No autotest.config.json found — using defaults');\r\n return DEFAULT_CONFIG;\r\n }\r\n\r\n const raw = await readJson(jsonPath);\r\n const result = AutotestConfigSchema.safeParse(raw);\r\n\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Invalid autotest.config.json at \"${jsonPath}\":\\n${issues}\\n\\n` +\r\n `How to fix: Run \"npx assuremind init\" to reset to defaults, ` +\r\n `or manually correct the file using autotest.config.ts as reference.`,\r\n 'config',\r\n 'INVALID_CONFIG',\r\n );\r\n }\r\n\r\n return result.data;\r\n}\r\n\r\n/**\r\n * Writes the config atomically to autotest.config.json\r\n * and regenerates the human-readable autotest.config.ts.\r\n */\r\nexport async function writeConfig(rootDir: string, config: AutotestConfig): Promise<void> {\r\n const result = AutotestConfigSchema.safeParse(config);\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Cannot write invalid config:\\n${issues}`,\r\n 'config',\r\n 'INVALID_CONFIG',\r\n );\r\n }\r\n\r\n const jsonPath = path.join(rootDir, CONFIG_JSON);\r\n await atomicWriteJson(jsonPath, result.data);\r\n\r\n const tsPath = path.join(rootDir, CONFIG_TS);\r\n await atomicWriteText(tsPath, generateConfigTs(result.data));\r\n\r\n logger.info({ rootDir }, 'Config saved');\r\n}\r\n\r\n/**\r\n * Updates specific config fields (merges, validates, and writes).\r\n */\r\nexport async function updateConfig(\r\n rootDir: string,\r\n updates: Partial<AutotestConfig>,\r\n): Promise<AutotestConfig> {\r\n const current = await readConfig(rootDir);\r\n const merged: AutotestConfig = {\r\n ...current,\r\n ...updates,\r\n healing: { ...current.healing, ...(updates.healing ?? {}) },\r\n reporting: { ...current.reporting, ...(updates.reporting ?? {}) },\r\n environmentUrls: { ...current.environmentUrls, ...(updates.environmentUrls ?? {}) },\r\n };\r\n await writeConfig(rootDir, merged);\r\n return merged;\r\n}\r\n\r\n/**\r\n * Checks whether a config exists in the given directory.\r\n */\r\nexport async function configExists(rootDir: string): Promise<boolean> {\r\n const jsonPath = path.join(rootDir, CONFIG_JSON);\r\n const tsPath = path.join(rootDir, CONFIG_TS);\r\n return (await fs.pathExists(jsonPath)) || (await fs.pathExists(tsPath));\r\n}\r\n\r\n/**\r\n * Validates the config and throws a ConfigError with actionable message if invalid.\r\n */\r\nexport async function validateConfig(rootDir: string): Promise<void> {\r\n const config = await readConfig(rootDir);\r\n\r\n if (!config.baseUrl) {\r\n throw new ConfigError(\r\n 'baseUrl is required in autotest.config.ts. ' +\r\n 'Set it to your application URL, e.g. \"http://localhost:3000\".',\r\n 'CONFIG_BASE_URL_MISSING',\r\n );\r\n }\r\n\r\n logger.debug({ config }, 'Config validated successfully');\r\n}\r\n\r\n/**\r\n * Generates the human-readable autotest.config.ts content from a config object.\r\n */\r\nfunction generateConfigTs(config: AutotestConfig): string {\r\n return `import { defineConfig } from 'assuremind';\r\n\r\nexport default defineConfig({\r\n baseUrl: '${config.baseUrl}',\r\n browsers: ${JSON.stringify(config.browsers)},\r\n headless: ${config.headless},\r\n timeout: ${config.timeout},\r\n retries: ${config.retries},\r\n parallel: ${config.parallel},\r\n screenshot: '${config.screenshot}',\r\n video: '${config.video}',\r\n trace: '${config.trace}',\r\n healing: {\r\n enabled: ${config.healing.enabled},\r\n maxLevel: ${config.healing.maxLevel},\r\n dailyBudget: ${config.healing.dailyBudget},\r\n autoPR: ${config.healing.autoPR},\r\n },\r\n reporting: {\r\n allure: ${config.reporting.allure},\r\n html: ${config.reporting.html},\r\n json: ${config.reporting.json},\r\n },\r\n studioPort: ${config.studioPort},\r\n});\r\n`;\r\n}\r\n","import path from 'path';\r\nimport fs from 'fs-extra';\r\nimport { RunResult, RunResultSchema } from '../types/run.js';\r\nimport { StorageError, ValidationError } from '../utils/errors.js';\r\nimport { createChildLogger } from '../utils/logger.js';\r\nimport { atomicWriteJson, readJson } from './utils.js';\r\n\r\nconst logger = createChildLogger('result-store');\r\n\r\nconst RESULTS_DIR = 'results';\r\nconst RUNS_DIR = 'runs';\r\n\r\nfunction runFilePath(resultsDir: string, runId: string): string {\r\n return path.join(resultsDir, RUNS_DIR, `${runId}.json`);\r\n}\r\n\r\n/**\r\n * Saves a run result to results/runs/{runId}.json.\r\n */\r\nexport async function writeResult(rootDir: string, result: RunResult): Promise<void> {\r\n const schema = RunResultSchema.safeParse(result);\r\n if (!schema.success) {\r\n const issues = schema.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Cannot write invalid run result:\\n${issues}`,\r\n 'result',\r\n 'INVALID_RESULT',\r\n );\r\n }\r\n\r\n const filePath = runFilePath(path.join(rootDir, RESULTS_DIR), result.runId);\r\n await atomicWriteJson(filePath, schema.data);\r\n logger.info({ runId: result.runId, status: result.status }, 'Run result saved');\r\n}\r\n\r\n/**\r\n * Reads a run result by runId.\r\n */\r\nexport async function readResult(rootDir: string, runId: string): Promise<RunResult> {\r\n const filePath = runFilePath(path.join(rootDir, RESULTS_DIR), runId);\r\n\r\n if (!(await fs.pathExists(filePath))) {\r\n throw new StorageError(\r\n `Run result not found for runId \"${runId}\".`,\r\n filePath,\r\n 'RESULT_NOT_FOUND',\r\n );\r\n }\r\n\r\n const raw = await readJson(filePath);\r\n const result = RunResultSchema.safeParse(raw);\r\n\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Invalid run result at \"${filePath}\":\\n${issues}`,\r\n 'result',\r\n 'INVALID_RESULT',\r\n );\r\n }\r\n\r\n return result.data;\r\n}\r\n\r\n/**\r\n * Lists all run result IDs, sorted newest-first.\r\n */\r\nexport async function listResultIds(rootDir: string): Promise<string[]> {\r\n const runsDir = path.join(rootDir, RESULTS_DIR, RUNS_DIR);\r\n if (!(await fs.pathExists(runsDir))) return [];\r\n\r\n const entries = await fs.readdir(runsDir, { withFileTypes: true });\r\n const ids = entries\r\n .filter((e) => e.isFile() && e.name.endsWith('.json'))\r\n .map((e) => e.name.replace('.json', ''));\r\n\r\n // Sort newest-first by reading mtime\r\n const withStats = await Promise.all(\r\n ids.map(async (id) => {\r\n const stat = await fs.stat(path.join(runsDir, `${id}.json`));\r\n return { id, mtime: stat.mtimeMs };\r\n }),\r\n );\r\n\r\n return withStats.sort((a, b) => b.mtime - a.mtime).map((x) => x.id);\r\n}\r\n\r\n/**\r\n * Lists run results (metadata only — no step details) for dashboard display.\r\n */\r\nexport async function listResults(\r\n rootDir: string,\r\n limit = 20,\r\n): Promise<(Pick<RunResult, 'runId' | 'status' | 'environment' | 'startedAt' | 'finishedAt' | 'totalTests' | 'passed' | 'failed' | 'skipped' | 'duration'> & { suiteIds: string[] })[]> {\r\n const ids = await listResultIds(rootDir);\r\n const results = [];\r\n\r\n for (const id of ids.slice(0, limit)) {\r\n try {\r\n const result = await readResult(rootDir, id);\r\n results.push({\r\n runId: result.runId,\r\n status: result.status,\r\n environment: result.environment,\r\n startedAt: result.startedAt,\r\n finishedAt: result.finishedAt,\r\n totalTests: result.totalTests,\r\n passed: result.passed,\r\n failed: result.failed,\r\n skipped: result.skipped,\r\n duration: result.duration,\r\n suiteIds: result.suites.map((s) => s.suiteId),\r\n });\r\n } catch (err) {\r\n logger.warn({ runId: id, err }, 'Failed to read run result — skipping');\r\n }\r\n }\r\n\r\n return results;\r\n}\r\n\r\n/**\r\n * Deletes a run result file.\r\n */\r\nexport async function deleteResult(rootDir: string, runId: string): Promise<void> {\r\n const filePath = runFilePath(path.join(rootDir, RESULTS_DIR), runId);\r\n if (!(await fs.pathExists(filePath))) {\r\n throw new StorageError(\r\n `Run result not found for runId \"${runId}\".`,\r\n filePath,\r\n 'RESULT_NOT_FOUND',\r\n );\r\n }\r\n await fs.remove(filePath);\r\n logger.info({ runId }, 'Run result deleted');\r\n}\r\n\r\n/**\r\n * Returns the screenshots directory path for a run.\r\n */\r\nexport function screenshotsDir(rootDir: string): string {\r\n return path.join(rootDir, RESULTS_DIR, 'screenshots');\r\n}\r\n\r\n/**\r\n * Returns the videos directory path.\r\n */\r\nexport function videosDir(rootDir: string): string {\r\n return path.join(rootDir, RESULTS_DIR, 'videos');\r\n}\r\n\r\n/**\r\n * Returns the traces directory path.\r\n */\r\nexport function tracesDir(rootDir: string): string {\r\n return path.join(rootDir, RESULTS_DIR, 'traces');\r\n}\r\n","import { z } from 'zod';\r\n\r\nexport const RunStatusSchema = z.enum(['pending', 'running', 'passed', 'failed', 'skipped']);\r\nexport type RunStatus = z.infer<typeof RunStatusSchema>;\r\n\r\nexport interface RunConfig {\r\n all?: boolean;\r\n type?: string; // Filter suites by suite type (ui, api, audit, performance)\r\n suite?: string;\r\n tag?: string;\r\n test?: string;\r\n browsers?: string[];\r\n env?: string;\r\n parallel?: number;\r\n headed?: boolean;\r\n ci?: boolean;\r\n reporter?: string[];\r\n noHealing?: boolean;\r\n screenshot?: 'off' | 'on' | 'only-on-failure';\r\n video?: 'off' | 'on' | 'on-first-retry' | 'retain-on-failure';\r\n trace?: 'off' | 'on' | 'on-first-retry' | 'retain-on-failure';\r\n /** Playwright device descriptor name (e.g. 'iPhone 15 Pro') — undefined = no emulation. */\r\n device?: string;\r\n}\r\n\r\nexport const ApiRequestSchema = z.object({\r\n method: z.string(),\r\n url: z.string(),\r\n headers: z.record(z.string()).optional(),\r\n body: z.string().optional(),\r\n}).optional();\r\n\r\nexport const ApiResponseSchema = z.object({\r\n status: z.number(),\r\n statusText: z.string(),\r\n headers: z.record(z.string()).optional(),\r\n body: z.string().optional(),\r\n duration: z.number(),\r\n}).optional();\r\n\r\n// Helper: accept number | null | undefined, always store as number | undefined\r\nconst optionalNum = z.number().nullish().transform((v) => v ?? undefined);\r\n\r\n// Individual Lighthouse audit result (pass / partial / fail / not-applicable)\r\nexport const AuditItemSchema = z.object({\r\n id: z.string(),\r\n title: z.string(),\r\n passed: z.boolean(), // true = score === 1\r\n partial: z.boolean().optional(), // true = 0 < score < 1 (needs work)\r\n na: z.boolean().optional(), // true = score === null (not applicable)\r\n});\r\nexport type AuditItem = z.infer<typeof AuditItemSchema>;\r\n\r\nexport const PageLoadMetricSchema = z.object({\r\n url: z.string(),\r\n stepIndex: z.number().int(),\r\n stepInstruction: z.string(),\r\n score: optionalNum, // Performance score 0-100 (pre-multiplied in runner)\r\n a11yScore: optionalNum, // Accessibility score 0-100 (pre-multiplied in runner)\r\n seoScore: optionalNum, // SEO score 0-100 (pre-multiplied in runner)\r\n fcp: optionalNum, // First Contentful Paint (ms)\r\n lcp: optionalNum, // Largest Contentful Paint (ms)\r\n cls: optionalNum, // Cumulative Layout Shift (score)\r\n ttfb: optionalNum, // Time to First Byte (ms)\r\n tbt: optionalNum, // Total Blocking Time (ms)\r\n si: optionalNum, // Speed Index (ms)\r\n tti: optionalNum, // Time to Interactive (ms)\r\n inp: optionalNum, // Interaction to Next Paint (ms)\r\n // Individual audit items for Accessibility and SEO categories\r\n a11yAudits: z.array(AuditItemSchema).optional(),\r\n seoAudits: z.array(AuditItemSchema).optional(),\r\n lighthouseError: z.string().optional(),\r\n});\r\nexport type PageLoadMetric = z.infer<typeof PageLoadMetricSchema>;\r\n\r\nexport const StepResultSchema = z.object({\r\n stepId: z.string(),\r\n instruction: z.string(),\r\n status: RunStatusSchema,\r\n code: z.string(),\r\n error: z.string().optional(),\r\n duration: z.number(),\r\n screenshotPath: z.string().optional(),\r\n healed: z.boolean().optional(),\r\n healedCode: z.string().optional(),\r\n stepType: z.enum(['ui', 'api', 'mock']).optional(),\r\n apiRequest: ApiRequestSchema,\r\n apiResponse: ApiResponseSchema,\r\n navigatedToUrl: z.string().optional(),\r\n auditUrl: z.string().optional(), // URL captured when step has runAudit=true (may not have navigated)\r\n});\r\n\r\nexport const TestCaseResultSchema = z.object({\r\n caseId: z.string(),\r\n caseName: z.string(),\r\n status: RunStatusSchema,\r\n steps: z.array(StepResultSchema),\r\n duration: z.number(),\r\n browser: z.string(),\r\n /** Playwright device descriptor used for this case (undefined = no emulation). */\r\n device: z.string().optional(),\r\n startedAt: z.string().datetime(),\r\n finishedAt: z.string().datetime(),\r\n videoPath: z.string().optional(),\r\n tracePath: z.string().optional(),\r\n dataRowIndex: z.number().int().optional(),\r\n dataRow: z.record(z.string()).optional(),\r\n pageLoads: z.array(PageLoadMetricSchema).default([]),\r\n});\r\n\r\nexport const SuiteResultSchema = z.object({\r\n suiteId: z.string(),\r\n suiteName: z.string(),\r\n suiteType: z.enum(['ui', 'api', 'audit', 'performance']).optional(),\r\n status: RunStatusSchema,\r\n cases: z.array(TestCaseResultSchema),\r\n duration: z.number(),\r\n browser: z.string(),\r\n startedAt: z.string().datetime(),\r\n finishedAt: z.string().datetime(),\r\n});\r\n\r\nexport const RunResultSchema = z.object({\r\n runId: z.string(),\r\n status: RunStatusSchema,\r\n environment: z.string().optional(),\r\n suites: z.array(SuiteResultSchema),\r\n duration: z.number(),\r\n startedAt: z.string().datetime(),\r\n finishedAt: z.string().datetime(),\r\n totalTests: z.number().int(),\r\n passed: z.number().int(),\r\n failed: z.number().int(),\r\n skipped: z.number().int(),\r\n logFilePath: z.string().optional(),\r\n});\r\n\r\nexport type StepResult = z.infer<typeof StepResultSchema>;\r\nexport type TestCaseResult = z.infer<typeof TestCaseResultSchema>;\r\nexport type SuiteResult = z.infer<typeof SuiteResultSchema>;\r\nexport type RunResult = z.infer<typeof RunResultSchema>;\r\n","import path from 'path';\r\nimport fs from 'fs-extra';\r\nimport { HealingEvent, HealingEventSchema, HealingReport, HealingReportSchema } from '../types/healing.js';\r\nimport { StorageError, ValidationError } from '../utils/errors.js';\r\nimport { createChildLogger } from '../utils/logger.js';\r\nimport { atomicWriteJson, readJson } from './utils.js';\r\n\r\nconst logger = createChildLogger('healing-store');\r\n\r\nconst HEALING_DIR = path.join('results', 'healing');\r\nconst PENDING_FILE = 'pending.json';\r\nconst REPORT_PREFIX = 'healing-report-';\r\n\r\nfunction reportFilePath(healingDir: string, runId: string): string {\r\n return path.join(healingDir, `${REPORT_PREFIX}${runId}.json`);\r\n}\r\n\r\nfunction pendingFilePath(healingDir: string): string {\r\n return path.join(healingDir, PENDING_FILE);\r\n}\r\n\r\n/**\r\n * Saves a complete healing report for a run.\r\n */\r\nexport async function writeHealingReport(\r\n rootDir: string,\r\n report: HealingReport,\r\n): Promise<void> {\r\n const schema = HealingReportSchema.safeParse(report);\r\n if (!schema.success) {\r\n const issues = schema.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Cannot write invalid healing report:\\n${issues}`,\r\n 'healingReport',\r\n 'INVALID_HEALING_REPORT',\r\n );\r\n }\r\n\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n const filePath = reportFilePath(healingDir, report.runId);\r\n await atomicWriteJson(filePath, schema.data);\r\n logger.info({ runId: report.runId, totalHeals: report.totalHeals }, 'Healing report saved');\r\n}\r\n\r\n/**\r\n * Reads a healing report for a specific run.\r\n */\r\nexport async function readHealingReport(rootDir: string, runId: string): Promise<HealingReport> {\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n const filePath = reportFilePath(healingDir, runId);\r\n\r\n if (!(await fs.pathExists(filePath))) {\r\n throw new StorageError(\r\n `Healing report not found for runId \"${runId}\".`,\r\n filePath,\r\n 'HEALING_REPORT_NOT_FOUND',\r\n );\r\n }\r\n\r\n const raw = await readJson(filePath);\r\n const result = HealingReportSchema.safeParse(raw);\r\n if (!result.success) {\r\n const issues = result.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ValidationError(\r\n `Invalid healing report at \"${filePath}\":\\n${issues}`,\r\n 'healingReport',\r\n 'INVALID_HEALING_REPORT',\r\n );\r\n }\r\n return result.data;\r\n}\r\n\r\n/**\r\n * Reads all pending healing events across all runs.\r\n */\r\nexport async function readPendingEvents(rootDir: string): Promise<HealingEvent[]> {\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n const filePath = pendingFilePath(healingDir);\r\n if (!(await fs.pathExists(filePath))) return [];\r\n\r\n const raw = await readJson(filePath);\r\n const result = HealingEventSchema.array().safeParse(raw);\r\n if (!result.success) {\r\n logger.warn({ path: filePath }, 'Pending healing file is malformed — resetting');\r\n return [];\r\n }\r\n return result.data;\r\n}\r\n\r\nconst MAX_HEALING_EVENTS = 50;\r\n\r\n/**\r\n * Priority order for auto-pruning when the cap is exceeded.\r\n * Lower index = deleted first.\r\n */\r\nconst PRUNE_PRIORITY: HealingEvent['status'][] = ['pending', 'rejected', 'accepted'];\r\n\r\n/**\r\n * Trims events to MAX_HEALING_EVENTS, removing by PRUNE_PRIORITY (oldest first\r\n * within the same status group) until the list fits.\r\n */\r\nfunction pruneToLimit(events: HealingEvent[]): HealingEvent[] {\r\n if (events.length <= MAX_HEALING_EVENTS) return events;\r\n\r\n // Build a mutable copy sorted so oldest entries of lower-priority statuses come first\r\n const byPriority = [...events].sort((a, b) => {\r\n const pa = PRUNE_PRIORITY.indexOf(a.status);\r\n const pb = PRUNE_PRIORITY.indexOf(b.status);\r\n if (pa !== pb) return pa - pb; // lower priority (pending) first\r\n return a.timestamp < b.timestamp ? -1 : 1; // oldest first within same status\r\n });\r\n\r\n const excess = events.length - MAX_HEALING_EVENTS;\r\n const toDelete = new Set(byPriority.slice(0, excess).map((e) => e.id));\r\n\r\n logger.info(\r\n { excess, deleted: toDelete.size },\r\n 'Auto-pruning healing events to enforce cap',\r\n );\r\n\r\n return events.filter((e) => !toDelete.has(e.id));\r\n}\r\n\r\n/**\r\n * Appends a new healing event to the pending list, then enforces the 50-event cap.\r\n */\r\nexport async function appendPendingEvent(rootDir: string, event: HealingEvent): Promise<void> {\r\n const schema = HealingEventSchema.safeParse(event);\r\n if (!schema.success) {\r\n throw new ValidationError(\r\n `Invalid healing event: ${schema.error.message}`,\r\n 'healingEvent',\r\n 'INVALID_HEALING_EVENT',\r\n );\r\n }\r\n\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n await fs.ensureDir(healingDir);\r\n\r\n const existing = await readPendingEvents(rootDir);\r\n existing.push(schema.data);\r\n await atomicWriteJson(pendingFilePath(healingDir), pruneToLimit(existing));\r\n}\r\n\r\n/**\r\n * Accepts a pending healing event: updates status and persists.\r\n */\r\nexport async function acceptHealingEvent(rootDir: string, eventId: string): Promise<HealingEvent> {\r\n const pending = await readPendingEvents(rootDir);\r\n const idx = pending.findIndex((e) => e.id === eventId);\r\n\r\n if (idx === -1) {\r\n throw new StorageError(\r\n `Healing event \"${eventId}\" not found in pending list.`,\r\n eventId,\r\n 'HEALING_EVENT_NOT_FOUND',\r\n );\r\n }\r\n\r\n pending[idx] = {\r\n ...pending[idx],\r\n status: 'accepted',\r\n acceptedAt: new Date().toISOString(),\r\n } as HealingEvent;\r\n\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n await atomicWriteJson(pendingFilePath(healingDir), pending);\r\n logger.info({ eventId }, 'Healing event accepted');\r\n\r\n return pending[idx];\r\n}\r\n\r\n/**\r\n * Rejects a pending healing event.\r\n */\r\nexport async function rejectHealingEvent(rootDir: string, eventId: string): Promise<HealingEvent> {\r\n const pending = await readPendingEvents(rootDir);\r\n const idx = pending.findIndex((e) => e.id === eventId);\r\n\r\n if (idx === -1) {\r\n throw new StorageError(\r\n `Healing event \"${eventId}\" not found in pending list.`,\r\n eventId,\r\n 'HEALING_EVENT_NOT_FOUND',\r\n );\r\n }\r\n\r\n pending[idx] = {\r\n ...pending[idx],\r\n status: 'rejected',\r\n rejectedAt: new Date().toISOString(),\r\n } as HealingEvent;\r\n\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n await atomicWriteJson(pendingFilePath(healingDir), pending);\r\n logger.info({ eventId }, 'Healing event rejected');\r\n\r\n return pending[idx];\r\n}\r\n\r\n/**\r\n * Deletes a single healing event by ID.\r\n */\r\nexport async function deleteHealingEvent(rootDir: string, eventId: string): Promise<void> {\r\n const events = await readPendingEvents(rootDir);\r\n const filtered = events.filter((e) => e.id !== eventId);\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n await atomicWriteJson(pendingFilePath(healingDir), filtered);\r\n logger.info({ eventId }, 'Healing event deleted');\r\n}\r\n\r\n/**\r\n * Deletes multiple healing events by their IDs.\r\n * Returns the number of events actually deleted.\r\n */\r\nexport async function deleteHealingEvents(rootDir: string, eventIds: string[]): Promise<number> {\r\n const events = await readPendingEvents(rootDir);\r\n const idSet = new Set(eventIds);\r\n const filtered = events.filter((e) => !idSet.has(e.id));\r\n const deleted = events.length - filtered.length;\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n await atomicWriteJson(pendingFilePath(healingDir), filtered);\r\n logger.info({ count: deleted }, 'Healing events bulk-deleted');\r\n return deleted;\r\n}\r\n\r\n/**\r\n * Deletes ALL healing events.\r\n * Returns the number of events deleted.\r\n */\r\nexport async function clearAllHealingEvents(rootDir: string): Promise<number> {\r\n const events = await readPendingEvents(rootDir);\r\n const count = events.length;\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n await atomicWriteJson(pendingFilePath(healingDir), []);\r\n logger.info({ count }, 'All healing events cleared');\r\n return count;\r\n}\r\n\r\n/**\r\n * Removes accepted and rejected events older than retentionDays from the pending file.\r\n */\r\nexport async function pruneResolvedEvents(\r\n rootDir: string,\r\n retentionDays = 30,\r\n): Promise<number> {\r\n const pending = await readPendingEvents(rootDir);\r\n const cutoff = Date.now() - retentionDays * 24 * 60 * 60 * 1000;\r\n const before = pending.length;\r\n\r\n const kept = pending.filter((e) => {\r\n if (e.status === 'pending') return true;\r\n const resolvedAt = e.acceptedAt ?? e.rejectedAt;\r\n if (!resolvedAt) return true;\r\n return new Date(resolvedAt).getTime() > cutoff;\r\n });\r\n\r\n if (kept.length < before) {\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n await atomicWriteJson(pendingFilePath(healingDir), kept);\r\n }\r\n\r\n return before - kept.length;\r\n}\r\n\r\n/**\r\n * Returns summary statistics for the healing store.\r\n */\r\nexport async function getHealingStats(rootDir: string): Promise<{\r\n pending: number;\r\n accepted: number;\r\n rejected: number;\r\n total: number;\r\n}> {\r\n const events = await readPendingEvents(rootDir);\r\n const pending = events.filter((e) => e.status === 'pending').length;\r\n const accepted = events.filter((e) => e.status === 'accepted').length;\r\n const rejected = events.filter((e) => e.status === 'rejected').length;\r\n return { pending, accepted, rejected, total: events.length };\r\n}\r\n\r\n/**\r\n * Lists all healing report runIds (newest-first by mtime).\r\n */\r\nexport async function listHealingReportIds(rootDir: string): Promise<string[]> {\r\n const healingDir = path.join(rootDir, HEALING_DIR);\r\n if (!(await fs.pathExists(healingDir))) return [];\r\n\r\n const entries = await fs.readdir(healingDir, { withFileTypes: true });\r\n const ids = entries\r\n .filter((e) => e.isFile() && e.name.startsWith(REPORT_PREFIX) && e.name.endsWith('.json'))\r\n .map((e) => e.name.slice(REPORT_PREFIX.length, -'.json'.length));\r\n\r\n const withStats = await Promise.all(\r\n ids.map(async (id) => {\r\n const stat = await fs.stat(path.join(healingDir, `${REPORT_PREFIX}${id}.json`));\r\n return { id, mtime: stat.mtimeMs };\r\n }),\r\n );\r\n\r\n return withStats.sort((a, b) => b.mtime - a.mtime).map((x) => x.id);\r\n}\r\n","import { z } from 'zod';\r\n\r\nexport const HealingStatusSchema = z.enum(['pending', 'accepted', 'rejected']);\r\nexport const HealingStrategySchema = z.enum([\r\n 'retry',\r\n 'regenerate',\r\n 'multi-selector',\r\n 'visual',\r\n 'decompose',\r\n 'manual',\r\n]);\r\n\r\nexport type HealingStatus = z.infer<typeof HealingStatusSchema>;\r\nexport type HealingStrategy = z.infer<typeof HealingStrategySchema>;\r\n\r\nexport const HealingEventSchema = z.object({\r\n id: z.string(),\r\n runId: z.string(),\r\n suiteId: z.string(),\r\n caseId: z.string(),\r\n stepId: z.string(),\r\n stepInstruction: z.string(),\r\n failedCode: z.string(),\r\n healedCode: z.string(),\r\n error: z.string(),\r\n strategy: HealingStrategySchema,\r\n level: z.number().int().min(1).max(6),\r\n status: HealingStatusSchema,\r\n pageUrl: z.string(),\r\n timestamp: z.string().datetime(),\r\n acceptedAt: z.string().datetime().optional(),\r\n rejectedAt: z.string().datetime().optional(),\r\n});\r\n\r\nexport const HealingReportSchema = z.object({\r\n runId: z.string(),\r\n generatedAt: z.string().datetime(),\r\n totalHeals: z.number().int(),\r\n accepted: z.number().int(),\r\n rejected: z.number().int(),\r\n pending: z.number().int(),\r\n events: z.array(HealingEventSchema),\r\n});\r\n\r\nexport type HealingEvent = z.infer<typeof HealingEventSchema>;\r\nexport type HealingReport = z.infer<typeof HealingReportSchema>;\r\n\r\nexport interface HealingDecision {\r\n heal: boolean;\r\n strategy?: 'individual' | 'batch';\r\n reason: string;\r\n}\r\n\r\nexport type FailureKind = 'assertion' | 'infra';\r\n\r\nexport interface StepFailure {\r\n stepId: string;\r\n instruction: string;\r\n error: string;\r\n pageUrl: string;\r\n failedCode: string;\r\n failureKind: FailureKind;\r\n}\r\n","import { createHash } from 'crypto';\r\n\r\nexport function sha256(input: string): string {\r\n return createHash('sha256').update(input, 'utf8').digest('hex');\r\n}\r\n\r\nexport function md5(input: string): string {\r\n return createHash('md5').update(input, 'utf8').digest('hex');\r\n}\r\n\r\n/**\r\n * Normalises a URL by replacing dynamic path segments (IDs) with wildcards.\r\n * Example: /users/123/edit becomes /users/{star}/edit\r\n * Example: /posts/abc-def/comments becomes /posts/{star}/comments\r\n */\r\nexport function normalizeUrl(url: string): string {\r\n try {\r\n const parsed = new URL(url);\r\n const normalizedPath = parsed.pathname\r\n .split('/')\r\n .map((segment) => {\r\n // Numeric IDs\r\n if (/^\\d+$/.test(segment)) return '*';\r\n // UUIDs\r\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(segment)) {\r\n return '*';\r\n }\r\n // Slugs that look like IDs (alphanumeric + dashes, 8+ chars)\r\n if (/^[a-z0-9-]{8,}$/i.test(segment) && /-/.test(segment)) return '*';\r\n return segment;\r\n })\r\n .join('/');\r\n return normalizedPath;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n\r\n/**\r\n * Generates a short cache key from an instruction and URL.\r\n * Key = first 16 chars of sha256(normalizedInstruction|urlPattern)\r\n */\r\nexport function generateCacheKey(instruction: string, url: string): string {\r\n const normalizedInstruction = instruction.toLowerCase().replace(/\\s+/g, ' ').trim();\r\n const urlPattern = normalizeUrl(url);\r\n return sha256(`${normalizedInstruction}|${urlPattern}`).slice(0, 16);\r\n}\r\n","import { config as loadDotenv } from 'dotenv';\r\nimport { z } from 'zod';\r\nimport { ConfigError } from './errors.js';\r\n\r\nloadDotenv();\r\n\r\nconst AI_PROVIDERS = [\r\n 'anthropic',\r\n 'openai',\r\n 'google',\r\n 'azure-openai',\r\n 'bedrock',\r\n 'deepseek',\r\n 'groq',\r\n 'together',\r\n 'qwen',\r\n 'perplexity',\r\n 'ollama',\r\n 'custom',\r\n] as const;\r\n\r\nexport type AIProviderName = (typeof AI_PROVIDERS)[number];\r\n\r\nconst BaseEnvSchema = z.object({\r\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\r\n LOG_LEVEL: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'),\r\n AI_PROVIDER: z.enum(AI_PROVIDERS),\r\n AI_TIERED_ENABLED: z\r\n .string()\r\n .transform((v) => v === 'true')\r\n .default('false'),\r\n AI_TIERED_FAST_PROVIDER: z.enum(AI_PROVIDERS).optional(),\r\n AI_TIERED_FAST_MODEL: z.string().optional(),\r\n AI_TIMEOUT: z.coerce.number().int().positive().default(30),\r\n AI_MAX_RETRIES: z.coerce.number().int().min(0).max(10).default(2),\r\n});\r\n\r\nconst AnthropicEnvSchema = z.object({\r\n ANTHROPIC_API_KEY: z.string().min(1),\r\n ANTHROPIC_MODEL: z.string().default('claude-sonnet-4-20250514'),\r\n});\r\n\r\nconst OpenAIEnvSchema = z.object({\r\n OPENAI_API_KEY: z.string().min(1),\r\n OPENAI_MODEL: z.string().default('gpt-4o'),\r\n});\r\n\r\nconst GoogleEnvSchema = z.object({\r\n GOOGLE_API_KEY: z.string().min(1),\r\n GOOGLE_MODEL: z.string().default('gemini-2.5-pro'),\r\n});\r\n\r\nconst AzureOpenAIEnvSchema = z.object({\r\n AZURE_OPENAI_API_KEY: z.string().min(1),\r\n AZURE_OPENAI_ENDPOINT: z.string().url(),\r\n AZURE_OPENAI_DEPLOYMENT: z.string().min(1),\r\n AZURE_OPENAI_API_VERSION: z.string().default('2024-10-21'),\r\n});\r\n\r\nconst BedrockEnvSchema = z.object({\r\n AWS_ACCESS_KEY_ID: z.string().min(1),\r\n AWS_SECRET_ACCESS_KEY: z.string().min(1),\r\n AWS_SESSION_TOKEN: z.string().optional(),\r\n AWS_REGION: z.string().default('us-east-1'),\r\n BEDROCK_MODEL: z.string().default('anthropic.claude-sonnet-4-20250514-v1:0'),\r\n});\r\n\r\nconst DeepSeekEnvSchema = z.object({\r\n DEEPSEEK_API_KEY: z.string().min(1),\r\n DEEPSEEK_MODEL: z.string().default('deepseek-chat'),\r\n});\r\n\r\nconst GroqEnvSchema = z.object({\r\n GROQ_API_KEY: z.string().min(1),\r\n GROQ_MODEL: z.string().default('llama-3.3-70b-versatile'),\r\n});\r\n\r\nconst TogetherEnvSchema = z.object({\r\n TOGETHER_API_KEY: z.string().min(1),\r\n TOGETHER_MODEL: z.string().default('meta-llama/Llama-3.3-70B-Instruct-Turbo'),\r\n});\r\n\r\nconst QwenEnvSchema = z.object({\r\n QWEN_API_KEY: z.string().min(1),\r\n QWEN_BASE_URL: z.string().url().default('https://dashscope-intl.aliyuncs.com/compatible-mode/v1'),\r\n QWEN_MODEL: z.string().default('qwen-max'),\r\n});\r\n\r\nconst PerplexityEnvSchema = z.object({\r\n PERPLEXITY_API_KEY: z.string().min(1),\r\n PERPLEXITY_MODEL: z.string().default('sonar-pro'),\r\n});\r\n\r\nconst OllamaEnvSchema = z.object({\r\n OLLAMA_BASE_URL: z.string().url().default('http://localhost:11434'),\r\n OLLAMA_MODEL: z.string().default('llama3.3'),\r\n});\r\n\r\nconst CustomEnvSchema = z.object({\r\n CUSTOM_API_KEY: z.string().min(1),\r\n CUSTOM_BASE_URL: z.string().url(),\r\n CUSTOM_MODEL: z.string().min(1),\r\n});\r\n\r\nconst PROVIDER_SCHEMAS: Record<AIProviderName, z.ZodObject<z.ZodRawShape>> = {\r\n anthropic: AnthropicEnvSchema,\r\n openai: OpenAIEnvSchema,\r\n google: GoogleEnvSchema,\r\n 'azure-openai': AzureOpenAIEnvSchema,\r\n bedrock: BedrockEnvSchema,\r\n deepseek: DeepSeekEnvSchema,\r\n groq: GroqEnvSchema,\r\n together: TogetherEnvSchema,\r\n qwen: QwenEnvSchema,\r\n perplexity: PerplexityEnvSchema,\r\n ollama: OllamaEnvSchema,\r\n custom: CustomEnvSchema,\r\n};\r\n\r\nexport type BaseEnv = z.infer<typeof BaseEnvSchema>;\r\nexport type ValidatedEnv = BaseEnv & Record<string, unknown>;\r\n\r\nlet _cachedEnv: ValidatedEnv | null = null;\r\n\r\n/**\r\n * Loads and validates the environment for the configured AI provider.\r\n * Throws a ConfigError with actionable message if validation fails.\r\n * Result is cached after first call.\r\n */\r\nexport function validateEnv(): ValidatedEnv {\r\n if (_cachedEnv !== null) return _cachedEnv;\r\n\r\n const baseResult = BaseEnvSchema.safeParse(process.env);\r\n if (!baseResult.success) {\r\n const issues = baseResult.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ConfigError(\r\n `Missing or invalid environment variables:\\n${issues}\\n\\n` +\r\n `How to fix: Copy .env.example to .env and fill in your AI provider credentials.`,\r\n 'ENV_VALIDATION_FAILED',\r\n );\r\n }\r\n\r\n const providerName = baseResult.data.AI_PROVIDER;\r\n const providerSchema = PROVIDER_SCHEMAS[providerName];\r\n const providerResult = providerSchema.safeParse(process.env);\r\n\r\n if (!providerResult.success) {\r\n const issues = providerResult.error.issues\r\n .map((i) => ` • ${i.path.join('.')}: ${i.message}`)\r\n .join('\\n');\r\n throw new ConfigError(\r\n `Provider \"${providerName}\" is missing required environment variables:\\n${issues}\\n\\n` +\r\n `How to fix: Check .env.example for the ${providerName} section and add the required keys to .env.`,\r\n 'PROVIDER_ENV_MISSING',\r\n );\r\n }\r\n\r\n const merged: ValidatedEnv = {\r\n ...baseResult.data,\r\n ...(providerResult.data as Record<string, unknown>),\r\n };\r\n _cachedEnv = merged;\r\n\r\n return _cachedEnv;\r\n}\r\n\r\n/** Clears the cached env — used in tests to reset state between test cases. */\r\nexport function clearEnvCache(): void {\r\n _cachedEnv = null;\r\n}\r\n\r\n/** Returns the validated env without throwing — for non-critical reads. */\r\nexport function tryGetEnv(): ValidatedEnv | null {\r\n try {\r\n return validateEnv();\r\n } catch {\r\n return null;\r\n }\r\n}\r\n"],"mappings":"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","names":["import_path","import_fs_extra","import_zod","path","pino","import_fs_extra","path","fs","path","fs","logger","path","fs","uuidv4","logger","fs","import_path","import_fs_extra","import_uuid","logger","fs","uuidv4","path","import_path","import_fs_extra","import_zod","logger","fs","path","import_path","import_fs_extra","logger","path","fs","import_path","import_fs_extra","import_zod","logger","path","fs","import_path","import_fs_extra","import_zod","logger","path","fs","path","fs","import_zod","loadDotenv"]}
|