@halecraft/verify 1.0.0 → 1.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/discovery.ts","../src/init/detect.ts","../src/init/generate.ts","../src/init/prompts.ts","../src/init/write.ts","../src/init/index.ts","../src/parsers/biome.ts","../src/parsers/generic.ts","../src/parsers/gotest.ts","../src/parsers/tsc.ts","../src/parsers/vitest.ts","../src/parsers/index.ts","../src/spinner.ts","../src/reporter.ts","../src/runner.ts","../src/index.ts"],"sourcesContent":["import { existsSync } from \"node:fs\"\nimport { join, resolve } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport type { VerificationNode, VerifyConfig, VerifyOptions } from \"./types.js\"\n\n/**\n * Helper function for defining config with type inference\n */\nexport function defineConfig(config: VerifyConfig): VerifyConfig {\n return config\n}\n\n/**\n * Helper function for defining a single verification task\n */\nexport function defineTask(task: VerificationNode): VerificationNode {\n return task\n}\n\n/**\n * Config file names to search for (in order of priority)\n */\nconst CONFIG_FILES = [\n \"verify.config.ts\",\n \"verify.config.mts\",\n \"verify.config.js\",\n \"verify.config.mjs\",\n]\n\n/**\n * Find config file in directory\n */\nexport function findConfigFile(cwd: string): string | null {\n for (const filename of CONFIG_FILES) {\n const filepath = join(cwd, filename)\n if (existsSync(filepath)) {\n return filepath\n }\n }\n return null\n}\n\n/**\n * Load config from file\n */\nexport async function loadConfig(\n configPath: string,\n): Promise<VerifyConfig | null> {\n const absolutePath = resolve(configPath)\n\n if (!existsSync(absolutePath)) {\n return null\n }\n\n // Use dynamic import with file URL for cross-platform compatibility\n const fileUrl = pathToFileURL(absolutePath).href\n const module = (await import(fileUrl)) as { default?: VerifyConfig }\n\n if (!module.default) {\n throw new Error(`Config file ${configPath} must have a default export`)\n }\n\n return module.default\n}\n\n/**\n * Load config from cwd or specified path\n */\nexport async function loadConfigFromCwd(\n cwd: string,\n configPath?: string,\n): Promise<VerifyConfig | null> {\n if (configPath) {\n return loadConfig(configPath)\n }\n\n const foundPath = findConfigFile(cwd)\n if (!foundPath) {\n return null\n }\n\n return loadConfig(foundPath)\n}\n\n/**\n * Helper type that requires all keys to be present but preserves original value types.\n * This is used to ensure mergeOptions handles all VerifyOptions properties.\n */\ntype AllKeys<T> = { [K in keyof Required<T>]: T[K] }\n\n/**\n * Merge options with defaults.\n *\n * NOTE: The `satisfies AllKeys<VerifyOptions>` ensures this function handles\n * all properties of VerifyOptions. If you add a new option to VerifyOptions,\n * TypeScript will error here until you add it to the return object.\n */\nexport function mergeOptions(\n configOptions?: VerifyOptions,\n cliOptions?: Partial<VerifyOptions>,\n): VerifyOptions {\n return {\n logs: cliOptions?.logs ?? configOptions?.logs ?? \"failed\",\n format: cliOptions?.format ?? configOptions?.format ?? \"human\",\n filter: cliOptions?.filter ?? configOptions?.filter,\n cwd: cliOptions?.cwd ?? configOptions?.cwd ?? process.cwd(),\n noColor: cliOptions?.noColor ?? configOptions?.noColor ?? false,\n topLevelOnly:\n cliOptions?.topLevelOnly ?? configOptions?.topLevelOnly ?? false,\n noTty: cliOptions?.noTty ?? configOptions?.noTty ?? false,\n } satisfies AllKeys<VerifyOptions>\n}\n","import { existsSync, readdirSync, statSync } from \"node:fs\"\nimport { join, relative } from \"node:path\"\nimport { findConfigFile, loadConfig } from \"./config.js\"\nimport type { PackageDiscoveryOptions, VerifyConfig } from \"./types.js\"\n\n/**\n * Discovered package with its config\n */\nexport interface DiscoveredPackage {\n /** Package name from package.json */\n name: string\n /** Relative path from root */\n path: string\n /** Absolute path */\n absolutePath: string\n /** Loaded verify config (if exists) */\n config: VerifyConfig | null\n}\n\n/**\n * Default glob patterns for package discovery\n */\nconst DEFAULT_PATTERNS = [\"packages/*\", \"apps/*\"]\n\n/**\n * Find directories matching patterns\n */\nfunction findMatchingDirs(rootDir: string, patterns: string[]): string[] {\n const results: string[] = []\n\n for (const pattern of patterns) {\n // Handle simple patterns like \"packages/*\"\n if (pattern.endsWith(\"/*\")) {\n const parentDir = pattern.slice(0, -2)\n const parentPath = join(rootDir, parentDir)\n\n if (existsSync(parentPath) && statSync(parentPath).isDirectory()) {\n const entries = readdirSync(parentPath)\n for (const entry of entries) {\n const entryPath = join(parentPath, entry)\n if (statSync(entryPath).isDirectory()) {\n results.push(entryPath)\n }\n }\n }\n } else {\n // Direct path\n const dirPath = join(rootDir, pattern)\n if (existsSync(dirPath) && statSync(dirPath).isDirectory()) {\n results.push(dirPath)\n }\n }\n }\n\n return results\n}\n\n/**\n * Read package name from package.json\n */\nfunction getPackageName(packageDir: string): string | null {\n const packageJsonPath = join(packageDir, \"package.json\")\n if (!existsSync(packageJsonPath)) {\n return null\n }\n\n try {\n const content = require(packageJsonPath) as { name?: string }\n return content.name ?? null\n } catch {\n return null\n }\n}\n\n/**\n * Discover packages in a monorepo\n */\nexport async function discoverPackages(\n rootDir: string,\n options: PackageDiscoveryOptions = {},\n): Promise<DiscoveredPackage[]> {\n const patterns = options.patterns ?? DEFAULT_PATTERNS\n const matchingDirs = findMatchingDirs(rootDir, patterns)\n\n const packages: DiscoveredPackage[] = []\n\n for (const dir of matchingDirs) {\n const name = getPackageName(dir)\n if (!name) continue // Skip directories without package.json\n\n // Check filter\n if (options.filter && options.filter.length > 0) {\n const matches = options.filter.some(\n f =>\n name === f || name.includes(f) || relative(rootDir, dir).includes(f),\n )\n if (!matches) continue\n }\n\n // Try to load verify config\n const configPath = findConfigFile(dir)\n const config = configPath ? await loadConfig(configPath) : null\n\n packages.push({\n name,\n path: relative(rootDir, dir),\n absolutePath: dir,\n config,\n })\n }\n\n return packages\n}\n\n/**\n * Check if a package has changed (git-aware)\n * This is a placeholder - full implementation would use git diff\n */\nexport async function hasPackageChanged(\n _packagePath: string,\n _baseBranch = \"main\",\n): Promise<boolean> {\n // TODO: Implement git-aware change detection\n // For now, always return true (include all packages)\n return true\n}\n","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\n\n/**\n * A detected task candidate from package.json\n */\nexport interface DetectedTask {\n /** Suggested key for the task */\n key: string\n /** Human-readable name */\n name: string\n /** The npm script name that was detected */\n scriptName: string\n /** The command to run (optimized direct path when possible) */\n command: string\n /** Category for grouping (format, types, logic, build) */\n category: \"format\" | \"types\" | \"logic\" | \"build\" | \"other\"\n /** Parser to use for this task */\n parser?: string\n /**\n * Tasks that must pass for this task's failure to be reported.\n * Auto-populated based on category (types/logic/build depend on format).\n */\n reportingDependsOn?: string[]\n}\n\n/**\n * Tool detection patterns - maps script content to optimized commands\n */\ninterface ToolPattern {\n /** Regex to match in script content */\n pattern: RegExp\n /** Binary name in node_modules/.bin */\n binary: string\n /** Arguments to append (extracted from script or default) */\n getArgs: (match: RegExpMatchArray, scriptContent: string) => string\n /** Parser to use */\n parser?: string\n}\n\nconst TOOL_PATTERNS: ToolPattern[] = [\n // Biome\n {\n pattern: /\\bbiome\\s+(check|lint|format)/,\n binary: \"biome\",\n getArgs: (match, content) => {\n // Extract the full biome command with args\n const biomeMatch = content.match(/biome\\s+([^&|;]+)/)\n return biomeMatch ? biomeMatch[1].trim() : \"check .\"\n },\n parser: \"biome\",\n },\n // ESLint\n {\n pattern: /\\beslint\\b/,\n binary: \"eslint\",\n getArgs: (_, content) => {\n const eslintMatch = content.match(/eslint\\s+([^&|;]+)/)\n return eslintMatch ? eslintMatch[1].trim() : \".\"\n },\n },\n // Prettier\n {\n pattern: /\\bprettier\\b/,\n binary: \"prettier\",\n getArgs: (_, content) => {\n const prettierMatch = content.match(/prettier\\s+([^&|;]+)/)\n return prettierMatch ? prettierMatch[1].trim() : \"--check .\"\n },\n },\n // TypeScript\n {\n pattern: /\\btsc\\b/,\n binary: \"tsc\",\n getArgs: (_, content) => {\n const tscMatch = content.match(/tsc\\s+([^&|;]+)/)\n return tscMatch ? tscMatch[1].trim() : \"--noEmit\"\n },\n parser: \"tsc\",\n },\n // tsgo\n {\n pattern: /\\btsgo\\b/,\n binary: \"tsgo\",\n getArgs: (_, content) => {\n const tsgoMatch = content.match(/tsgo\\s+([^&|;]+)/)\n return tsgoMatch ? tsgoMatch[1].trim() : \"--noEmit\"\n },\n parser: \"tsc\",\n },\n // Vitest\n {\n pattern: /\\bvitest\\b/,\n binary: \"vitest\",\n getArgs: (_, content) => {\n // Check if it's watch mode or run mode\n if (content.includes(\"vitest run\")) return \"run\"\n if (content.includes(\"vitest watch\")) return \"run\" // Convert watch to run for verify\n return \"run\"\n },\n parser: \"vitest\",\n },\n // Jest\n {\n pattern: /\\bjest\\b/,\n binary: \"jest\",\n getArgs: () => \"\",\n },\n // Mocha\n {\n pattern: /\\bmocha\\b/,\n binary: \"mocha\",\n getArgs: () => \"\",\n },\n // tsup\n {\n pattern: /\\btsup\\b/,\n binary: \"tsup\",\n getArgs: (_, content) => {\n const tsupMatch = content.match(/tsup\\s+([^&|;]+)/)\n return tsupMatch ? tsupMatch[1].trim() : \"\"\n },\n },\n // esbuild\n {\n pattern: /\\besbuild\\b/,\n binary: \"esbuild\",\n getArgs: (_, content) => {\n const esbuildMatch = content.match(/esbuild\\s+([^&|;]+)/)\n return esbuildMatch ? esbuildMatch[1].trim() : \"\"\n },\n },\n]\n\n/**\n * Patterns to detect verification-related scripts by name\n */\nconst SCRIPT_NAME_PATTERNS: Array<{\n pattern: RegExp\n key: string\n name: string\n category: DetectedTask[\"category\"]\n}> = [\n // Format/Lint patterns\n {\n pattern: /^(lint|eslint|biome|prettier|format)$/i,\n key: \"format\",\n name: \"Format & Lint\",\n category: \"format\",\n },\n {\n pattern: /^(lint:fix|format:fix|fix)$/i,\n key: \"format\",\n name: \"Format & Lint\",\n category: \"format\",\n },\n {\n pattern: /^verify:format$/i,\n key: \"format\",\n name: \"Format\",\n category: \"format\",\n },\n\n // Type checking patterns\n {\n pattern: /^(typecheck|type-check|tsc|types|check-types)$/i,\n key: \"types\",\n name: \"Type Check\",\n category: \"types\",\n },\n {\n pattern: /^verify:types$/i,\n key: \"types\",\n name: \"Types\",\n category: \"types\",\n },\n\n // Test patterns\n {\n pattern: /^(test|tests|vitest|jest|mocha|ava)$/i,\n key: \"test\",\n name: \"Tests\",\n category: \"logic\",\n },\n {\n pattern: /^test:(unit|integration|e2e)$/i,\n key: \"test\",\n name: \"Tests\",\n category: \"logic\",\n },\n {\n pattern: /^verify:logic$/i,\n key: \"logic\",\n name: \"Logic Tests\",\n category: \"logic\",\n },\n\n // Build patterns\n {\n pattern: /^(build|compile)$/i,\n key: \"build\",\n name: \"Build\",\n category: \"build\",\n },\n]\n\n/**\n * Read and parse package.json from a directory\n */\nfunction readPackageJson(\n cwd: string,\n): { scripts?: Record<string, string> } | null {\n const packageJsonPath = join(cwd, \"package.json\")\n\n if (!existsSync(packageJsonPath)) {\n return null\n }\n\n try {\n const content = readFileSync(packageJsonPath, \"utf-8\")\n return JSON.parse(content) as { scripts?: Record<string, string> }\n } catch {\n return null\n }\n}\n\n/**\n * Check if a binary exists in node_modules/.bin\n */\nfunction binaryExists(cwd: string, binary: string): boolean {\n return existsSync(join(cwd, \"node_modules\", \".bin\", binary))\n}\n\n/**\n * Try to extract an optimized direct command from script content\n */\nfunction extractOptimizedCommand(\n cwd: string,\n scriptContent: string,\n): { command: string; parser?: string } | null {\n for (const tool of TOOL_PATTERNS) {\n const match = scriptContent.match(tool.pattern)\n if (match && binaryExists(cwd, tool.binary)) {\n const args = tool.getArgs(match, scriptContent)\n const command = args\n ? `./node_modules/.bin/${tool.binary} ${args}`\n : `./node_modules/.bin/${tool.binary}`\n return { command, parser: tool.parser }\n }\n }\n return null\n}\n\n/**\n * Detect verification tasks from package.json scripts\n */\nexport function detectFromPackageJson(cwd: string): DetectedTask[] {\n const pkg = readPackageJson(cwd)\n\n if (!pkg?.scripts) {\n return []\n }\n\n const detected: DetectedTask[] = []\n const seenKeys = new Set<string>()\n\n for (const [scriptName, scriptContent] of Object.entries(pkg.scripts)) {\n // Skip scripts that are just running other scripts (like \"verify\": \"run-s ...\")\n if (\n scriptContent.includes(\"run-s\") ||\n scriptContent.includes(\"run-p\") ||\n scriptContent.includes(\"npm-run-all\")\n ) {\n continue\n }\n\n // Check against detection patterns\n for (const { pattern, key, name, category } of SCRIPT_NAME_PATTERNS) {\n if (pattern.test(scriptName)) {\n // Avoid duplicates for the same key\n const uniqueKey = seenKeys.has(key) ? `${key}-${scriptName}` : key\n if (!seenKeys.has(uniqueKey)) {\n seenKeys.add(uniqueKey)\n\n // Try to extract optimized command\n const optimized = extractOptimizedCommand(cwd, scriptContent)\n\n detected.push({\n key: uniqueKey,\n name,\n scriptName,\n command: optimized?.command ?? `npm run ${scriptName}`,\n category,\n parser: optimized?.parser,\n })\n }\n break\n }\n }\n }\n\n // Sort by category priority: format -> types -> logic -> build -> other\n const categoryOrder: Record<DetectedTask[\"category\"], number> = {\n format: 0,\n types: 1,\n logic: 2,\n build: 3,\n other: 4,\n }\n\n detected.sort((a, b) => categoryOrder[a.category] - categoryOrder[b.category])\n\n // Add reportingDependsOn for non-format tasks if a format task exists\n // This reduces noise when a syntax error causes multiple tools to fail\n const hasFormatTask = detected.some(t => t.category === \"format\")\n if (hasFormatTask) {\n for (const task of detected) {\n if (task.category !== \"format\" && task.category !== \"other\") {\n task.reportingDependsOn = [\"format\"]\n }\n }\n }\n\n return detected\n}\n\n/**\n * Detect the package manager being used\n */\nexport function detectPackageManager(cwd: string): \"npm\" | \"pnpm\" | \"yarn\" {\n if (existsSync(join(cwd, \"pnpm-lock.yaml\"))) {\n return \"pnpm\"\n }\n if (existsSync(join(cwd, \"yarn.lock\"))) {\n return \"yarn\"\n }\n return \"npm\"\n}\n\n/**\n * Get the run command for a package manager\n */\nexport function getRunCommand(\n packageManager: \"npm\" | \"pnpm\" | \"yarn\",\n scriptName: string,\n): string {\n switch (packageManager) {\n case \"pnpm\":\n return `pnpm ${scriptName}`\n case \"yarn\":\n return `yarn ${scriptName}`\n default:\n return `npm run ${scriptName}`\n }\n}\n\n/**\n * Detect tasks with proper package manager commands\n * Uses optimized direct paths when possible, falls back to package manager\n */\nexport function detectTasks(cwd: string): DetectedTask[] {\n const packageManager = detectPackageManager(cwd)\n const tasks = detectFromPackageJson(cwd)\n\n // For tasks without optimized commands, use package manager\n return tasks.map(task => {\n // If command is already optimized (starts with ./), keep it\n if (task.command.startsWith(\"./\")) {\n return task\n }\n // Otherwise use package manager command\n return {\n ...task,\n command: getRunCommand(packageManager, task.scriptName),\n }\n })\n}\n","import type { DetectedTask } from \"./detect.js\"\n\n/**\n * Output format for the generated config\n */\nexport type OutputFormat = \"ts\" | \"mts\" | \"js\" | \"mjs\"\n\n/**\n * Determine output format from file path\n */\nexport function getOutputFormat(filePath: string): OutputFormat {\n if (filePath.endsWith(\".mts\")) return \"mts\"\n if (filePath.endsWith(\".mjs\")) return \"mjs\"\n if (filePath.endsWith(\".js\")) return \"js\"\n return \"ts\" // Default to TypeScript\n}\n\n/**\n * Generate the import statement based on format\n */\nfunction generateImport(format: OutputFormat): string {\n // All formats use ESM import syntax\n return `import { defineConfig } from \"@halecraft/verify\"`\n}\n\n/**\n * Generate a task object as a string\n */\nfunction generateTask(task: DetectedTask, indent: string): string {\n const parts = [`key: \"${task.key}\"`, `run: \"${task.command}\"`]\n if (task.parser) {\n parts.push(`parser: \"${task.parser}\"`)\n }\n if (task.reportingDependsOn && task.reportingDependsOn.length > 0) {\n const deps = task.reportingDependsOn.map(d => `\"${d}\"`).join(\", \")\n parts.push(`reportingDependsOn: [${deps}]`)\n }\n return `${indent}{ ${parts.join(\", \")} }`\n}\n\n/**\n * Generate the skeleton config when no tasks are detected\n */\nfunction generateSkeleton(format: OutputFormat): string {\n const importStatement = generateImport(format)\n\n return `${importStatement}\n\nexport default defineConfig({\n tasks: [\n // Add your verification tasks here\n // Example:\n // { key: \"format\", run: \"pnpm lint\" },\n // { key: \"types\", run: \"pnpm typecheck\" },\n // { key: \"test\", run: \"pnpm test\" },\n ],\n})\n`\n}\n\n/**\n * Generate config content from selected tasks\n */\nexport function generateConfigContent(\n tasks: DetectedTask[],\n format: OutputFormat,\n): string {\n // If no tasks, generate skeleton\n if (tasks.length === 0) {\n return generateSkeleton(format)\n }\n\n const importStatement = generateImport(format)\n const indent = \" \"\n\n // Group tasks by category for better organization\n const taskLines = tasks.map(task => generateTask(task, indent))\n\n return `${importStatement}\n\nexport default defineConfig({\n tasks: [\n${taskLines.join(\",\\n\")},\n ],\n})\n`\n}\n\n/**\n * Get the default config filename\n */\nexport function getDefaultConfigPath(): string {\n return \"verify.config.ts\"\n}\n","import type { DetectedTask } from \"./detect.js\"\n\n/**\n * Options for the prompt flow\n */\nexport interface PromptOptions {\n /** Skip interactive prompts and auto-accept all */\n yes: boolean\n /** Whether we're in a TTY environment */\n isTTY: boolean\n}\n\n/**\n * Result of the prompt flow\n */\nexport interface PromptResult {\n /** Selected tasks */\n tasks: DetectedTask[]\n /** Whether the user cancelled */\n cancelled: boolean\n}\n\n/**\n * Check if we should skip prompts\n */\nexport function shouldSkipPrompts(options: PromptOptions): boolean {\n return options.yes || !options.isTTY\n}\n\n/**\n * Run the interactive task selection prompt\n */\nexport async function promptForTasks(\n detectedTasks: DetectedTask[],\n options: PromptOptions,\n): Promise<PromptResult> {\n // If no tasks detected, return empty (will use skeleton)\n if (detectedTasks.length === 0) {\n if (!shouldSkipPrompts(options)) {\n console.log(\n \"\\n⚠️ No verification scripts detected in package.json.\\n A skeleton config will be created.\\n\",\n )\n }\n return { tasks: [], cancelled: false }\n }\n\n // If skipping prompts, return all detected tasks\n if (shouldSkipPrompts(options)) {\n console.log(`\\n✓ Auto-selecting ${detectedTasks.length} detected task(s)\\n`)\n return { tasks: detectedTasks, cancelled: false }\n }\n\n // Dynamic import of @inquirer/prompts to avoid loading it when not needed\n try {\n const { checkbox } = await import(\"@inquirer/prompts\")\n\n console.log(\"\\n🔍 Detected verification scripts in package.json:\\n\")\n\n const choices = detectedTasks.map(task => ({\n name: `${task.name} (${task.command})`,\n value: task,\n checked: true, // Pre-select all by default\n }))\n\n const selected = await checkbox<DetectedTask>({\n message: \"Select tasks to include in your config:\",\n choices,\n instructions: false,\n })\n\n if (selected.length === 0) {\n console.log(\n \"\\n⚠️ No tasks selected. A skeleton config will be created.\\n\",\n )\n }\n\n return { tasks: selected, cancelled: false }\n } catch (error) {\n // Handle Ctrl+C or other cancellation\n if (\n error instanceof Error &&\n (error.message.includes(\"User force closed\") ||\n error.name === \"ExitPromptError\")\n ) {\n return { tasks: [], cancelled: true }\n }\n throw error\n }\n}\n","import { existsSync, writeFileSync } from \"node:fs\"\nimport { resolve } from \"node:path\"\nimport type { DetectedTask } from \"./detect.js\"\n\n/**\n * Result of checking if a file exists\n */\nexport interface FileCheckResult {\n exists: boolean\n path: string\n}\n\n/**\n * Check if the config file already exists\n */\nexport function checkConfigExists(\n cwd: string,\n configPath: string,\n): FileCheckResult {\n const absolutePath = resolve(cwd, configPath)\n return {\n exists: existsSync(absolutePath),\n path: absolutePath,\n }\n}\n\n/**\n * Write the config file\n */\nexport function writeConfigFile(\n cwd: string,\n configPath: string,\n content: string,\n): void {\n const absolutePath = resolve(cwd, configPath)\n writeFileSync(absolutePath, content, \"utf-8\")\n}\n\n/**\n * Print warning about existing file\n */\nexport function printExistsWarning(path: string): void {\n console.error(`\\n⚠️ Config file already exists: ${path}`)\n console.error(\" Use --force to overwrite.\\n\")\n}\n\n/**\n * Options for success message\n */\nexport interface SuccessOptions {\n /** Path to the created config file */\n configPath: string\n /** Tasks that were configured */\n tasks: DetectedTask[]\n /** Whether optimized commands were used */\n hasOptimizedCommands: boolean\n /** Script names that can potentially be removed */\n removableScripts: string[]\n}\n\n/**\n * Print success message with educational notes\n */\nexport function printSuccess(options: SuccessOptions): void {\n const { configPath, tasks, hasOptimizedCommands, removableScripts } = options\n\n console.log(`\\n✅ Created ${configPath}`)\n console.log(\"\")\n\n // Quick start\n console.log(\" Quick start:\")\n console.log(\" $ verify # Run all verifications\")\n console.log(\" $ verify --top-level # Show only top-level tasks\")\n console.log(\" $ verify format # Run only 'format' task\")\n console.log(\"\")\n\n // Performance note if optimized commands were used\n if (hasOptimizedCommands) {\n console.log(\n \" ⚡ Performance: Using direct tool paths for faster execution\",\n )\n console.log(\n \" (avoids ~250ms overhead per command from package manager)\",\n )\n console.log(\"\")\n }\n\n // Cleanup suggestion if there are removable scripts\n if (removableScripts.length > 0) {\n console.log(\" 💡 Optional cleanup:\")\n console.log(\n \" You can remove these scripts from package.json if you only\",\n )\n console.log(\" run them via 'verify' (keeps package.json cleaner):\")\n for (const script of removableScripts) {\n console.log(` - \"${script}\"`)\n }\n console.log(\"\")\n }\n\n // Parser note if parsers were detected\n const tasksWithParsers = tasks.filter(t => t.parser)\n if (tasksWithParsers.length > 0) {\n console.log(\" 📊 Rich output: Parsers detected for detailed summaries:\")\n for (const task of tasksWithParsers) {\n console.log(` - ${task.key}: ${task.parser}`)\n }\n console.log(\"\")\n }\n\n console.log(\" 📖 Docs: https://github.com/halecraft/verify\")\n console.log(\"\")\n}\n","import { detectTasks } from \"./detect.js\"\nimport {\n generateConfigContent,\n getDefaultConfigPath,\n getOutputFormat,\n} from \"./generate.js\"\nimport { promptForTasks, shouldSkipPrompts } from \"./prompts.js\"\nimport {\n checkConfigExists,\n printExistsWarning,\n printSuccess,\n writeConfigFile,\n} from \"./write.js\"\n\n/**\n * Options for the init command\n */\nexport interface InitOptions {\n /** Custom config output path */\n config?: string\n /** Force overwrite existing file */\n force: boolean\n /** Skip interactive prompts */\n yes: boolean\n /** Working directory */\n cwd: string\n}\n\n/**\n * Result of the init command\n */\nexport interface InitResult {\n /** Whether init succeeded */\n success: boolean\n /** Path to the created config file (if successful) */\n configPath?: string\n /** Error message (if failed) */\n error?: string\n}\n\n/**\n * Run the init command\n */\nexport async function runInit(options: InitOptions): Promise<InitResult> {\n const configPath = options.config ?? getDefaultConfigPath()\n const format = getOutputFormat(configPath)\n\n // Check if file already exists\n const fileCheck = checkConfigExists(options.cwd, configPath)\n if (fileCheck.exists && !options.force) {\n printExistsWarning(fileCheck.path)\n return {\n success: false,\n error: \"Config file already exists. Use --force to overwrite.\",\n }\n }\n\n // Detect tasks from package.json\n const detectedTasks = detectTasks(options.cwd)\n\n // Determine if we should skip prompts\n const isTTY = process.stdout.isTTY ?? false\n const promptOptions = {\n yes: options.yes,\n isTTY,\n }\n\n // If not skipping prompts, show what we're doing\n if (!shouldSkipPrompts(promptOptions)) {\n console.log(\"\\n🚀 Initializing @halecraft/verify config...\\n\")\n }\n\n // Run interactive prompts (or auto-select)\n const promptResult = await promptForTasks(detectedTasks, promptOptions)\n\n if (promptResult.cancelled) {\n console.log(\"\\n❌ Cancelled.\\n\")\n return {\n success: false,\n error: \"User cancelled\",\n }\n }\n\n // Generate config content\n const content = generateConfigContent(promptResult.tasks, format)\n\n // Determine if optimized commands were used\n const hasOptimizedCommands = promptResult.tasks.some(t =>\n t.command.startsWith(\"./node_modules/.bin/\"),\n )\n\n // Determine which scripts could be removed (those that were detected and optimized)\n const removableScripts = promptResult.tasks\n .filter(t => t.command.startsWith(\"./node_modules/.bin/\"))\n .map(t => t.scriptName)\n\n // Write the file\n try {\n writeConfigFile(options.cwd, configPath, content)\n printSuccess({\n configPath,\n tasks: promptResult.tasks,\n hasOptimizedCommands,\n removableScripts,\n })\n return {\n success: true,\n configPath,\n }\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Failed to write config file\"\n console.error(`\\n❌ Error: ${message}\\n`)\n return {\n success: false,\n error: message,\n }\n }\n}\n\n// Re-export types and utilities\nexport type { DetectedTask } from \"./detect.js\"\nexport { detectTasks } from \"./detect.js\"\nexport type { OutputFormat } from \"./generate.js\"\nexport { generateConfigContent, getOutputFormat } from \"./generate.js\"\n","import type { OutputParser, ParsedResult } from \"../types.js\"\n\n/**\n * Parser for Biome linter/formatter output\n * Extracts issue counts and file counts from biome check output\n */\nexport const biomeParser: OutputParser = {\n id: \"biome\",\n parse(output: string, exitCode: number): ParsedResult | null {\n // Extract file count from \"Checked N files in Xms\"\n const filesMatch = output.match(\n /Checked\\s+(\\d+)\\s+files?\\s+in\\s+[\\d.]+(?:ms|s)/i,\n )\n const fileCount = filesMatch\n ? Number.parseInt(filesMatch[1], 10)\n : undefined\n\n // Check for warnings in output like \"Found 1 warning.\"\n const warningMatch = output.match(/Found\\s+(\\d+)\\s+warning/i)\n const warnings = warningMatch ? Number.parseInt(warningMatch[1], 10) : 0\n\n if (exitCode === 0) {\n const filesPart = fileCount ? `passed ${fileCount} files` : \"passed\"\n const warningSuffix =\n warnings > 0 ? `, ${warnings} warning${warnings === 1 ? \"\" : \"s\"}` : \"\"\n return {\n summary: `${filesPart}${warningSuffix}`,\n metrics: { errors: 0, warnings, total: fileCount },\n }\n }\n\n // Biome outputs something like \"Found 5 errors and 2 warnings\"\n // or individual diagnostics\n const summaryMatch = output.match(\n /Found\\s+(\\d+)\\s+error(?:s)?(?:\\s+and\\s+(\\d+)\\s+warning(?:s)?)?/i,\n )\n\n if (summaryMatch) {\n const errors = Number.parseInt(summaryMatch[1], 10)\n const parsedWarnings = summaryMatch[2]\n ? Number.parseInt(summaryMatch[2], 10)\n : warnings\n\n const fileSuffix = fileCount ? ` in ${fileCount} files` : \"\"\n return {\n summary: `${errors} error${errors === 1 ? \"\" : \"s\"}${parsedWarnings > 0 ? `, ${parsedWarnings} warning${parsedWarnings === 1 ? \"\" : \"s\"}` : \"\"}${fileSuffix}`,\n metrics: { errors, warnings: parsedWarnings, total: fileCount },\n }\n }\n\n // Count individual error markers if no summary found\n // Biome uses \"error\" prefix for diagnostics\n const errorLines = output.match(/^\\s*error\\[/gm)\n const warningLines = output.match(/^\\s*warning\\[/gm)\n\n const errors = errorLines ? errorLines.length : 0\n const countedWarnings = warningLines ? warningLines.length : warnings\n\n if (errors > 0 || countedWarnings > 0) {\n const fileSuffix = fileCount ? ` in ${fileCount} files` : \"\"\n return {\n summary: `${errors} error${errors === 1 ? \"\" : \"s\"}${countedWarnings > 0 ? `, ${countedWarnings} warning${countedWarnings === 1 ? \"\" : \"s\"}` : \"\"}${fileSuffix}`,\n metrics: { errors, warnings: countedWarnings, total: fileCount },\n }\n }\n\n // No errors found but still have file count\n if (fileCount) {\n return {\n summary: `passed ${fileCount} files`,\n metrics: { errors: 0, warnings: 0, total: fileCount },\n }\n }\n\n return null\n },\n}\n","import type { ParsedResult } from \"../types.js\"\n\n/**\n * Generic fallback parser - just reports exit code\n * This parser always returns a result (never null)\n */\nexport const genericParser = {\n id: \"generic\",\n parse(_output: string, exitCode: number): ParsedResult {\n return {\n summary: exitCode === 0 ? \"passed\" : `failed (exit code ${exitCode})`,\n }\n },\n} as const\n","import type { OutputParser, ParsedResult } from \"../types.js\"\n\n/**\n * Parser for Go test output\n * Counts packages passed/failed from go test output\n */\nexport const gotestParser: OutputParser = {\n id: \"gotest\",\n parse(output: string, exitCode: number): ParsedResult | null {\n // Match \"ok\" and \"FAIL\" lines for packages\n // ok github.com/user/pkg 0.123s\n // FAIL github.com/user/pkg 0.456s\n const okMatches = output.match(/^ok\\s+\\S+/gm)\n const failMatches = output.match(/^FAIL\\s+\\S+/gm)\n\n const passed = okMatches ? okMatches.length : 0\n const failed = failMatches ? failMatches.length : 0\n const total = passed + failed\n\n if (total === 0) {\n // Try to detect \"no test files\" case\n if (output.includes(\"no test files\")) {\n return {\n summary: \"no test files\",\n metrics: { passed: 0, failed: 0, total: 0 },\n }\n }\n return null\n }\n\n // Extract total duration if present\n // \"PASS\" or \"FAIL\" at the end with duration\n const durationMatch = output.match(/(?:PASS|FAIL)\\s*$[\\s\\S]*?(\\d+\\.?\\d*s)/m)\n const duration = durationMatch ? durationMatch[1] : undefined\n\n if (exitCode === 0) {\n return {\n summary: `${passed} package${passed === 1 ? \"\" : \"s\"} passed${duration ? ` in ${duration}` : \"\"}`,\n metrics: { passed, failed: 0, total: passed, duration },\n }\n }\n\n return {\n summary: `${failed}/${total} package${total === 1 ? \"\" : \"s\"} failed`,\n metrics: { passed, failed, total, duration },\n }\n },\n}\n","import type { OutputParser, ParsedResult } from \"../types.js\"\n\n/**\n * Parser for TypeScript compiler (tsc/tsgo) output\n * Counts type errors and extracts diagnostics info\n */\nexport const tscParser: OutputParser = {\n id: \"tsc\",\n parse(output: string, exitCode: number): ParsedResult | null {\n // Extract file count from diagnostics output: \"Files: 277\"\n const filesMatch = output.match(/^Files:\\s+(\\d+)/m)\n const fileCount = filesMatch\n ? Number.parseInt(filesMatch[1], 10)\n : undefined\n\n if (exitCode === 0) {\n const filesPart = fileCount ? `passed ${fileCount} files` : \"passed\"\n return {\n summary: filesPart,\n metrics: { errors: 0, total: fileCount },\n }\n }\n\n // Count error lines: \"src/file.ts(10,5): error TS2345: ...\"\n const errorMatches = output.match(/error TS\\d+:/g)\n const errorCount = errorMatches ? errorMatches.length : 0\n\n if (errorCount === 0) {\n // No recognizable errors but still failed\n return null\n }\n\n const fileSuffix = fileCount ? ` in ${fileCount} files` : \"\"\n return {\n summary: `${errorCount} type error${errorCount === 1 ? \"\" : \"s\"}${fileSuffix}`,\n metrics: { errors: errorCount, total: fileCount },\n }\n },\n}\n","import type { OutputParser, ParsedResult } from \"../types.js\"\n\n/**\n * Strip ANSI escape codes from string\n */\nfunction stripAnsi(str: string): string {\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape codes use control characters\n return str.replace(/\\x1b\\[[0-9;]*m/g, \"\")\n}\n\n/**\n * Parser for vitest output\n * Extracts test counts from vitest summary\n */\nexport const vitestParser: OutputParser = {\n id: \"vitest\",\n parse(output: string, exitCode: number): ParsedResult | null {\n // Strip ANSI codes for reliable parsing\n const cleanOutput = stripAnsi(output)\n\n // Match: \"Tests 26 passed (26)\" with flexible whitespace\n // Vitest v4 format: \" Tests 26 passed (26)\"\n const testsMatch = cleanOutput.match(/Tests\\s+(\\d+)\\s+passed\\s*\\((\\d+)\\)/m)\n\n // Match: \"Duration 192ms\" or \"Duration 1.72s\"\n const durationMatch = cleanOutput.match(/Duration\\s+([\\d.]+(?:ms|s))\\b/m)\n\n if (!testsMatch) {\n return null\n }\n\n const passed = Number.parseInt(testsMatch[1], 10)\n const total = Number.parseInt(testsMatch[2], 10)\n const duration = durationMatch ? durationMatch[1] : undefined\n\n // Don't include duration in summary - the reporter adds wall-clock time\n return {\n summary:\n exitCode === 0\n ? `passed ${passed}/${total} tests`\n : `passed ${passed}/${total} tests (some failed)`,\n metrics: {\n passed,\n total,\n failed: total - passed,\n duration,\n },\n }\n },\n}\n","import type { OutputParser, ParsedResult } from \"../types.js\"\nimport { biomeParser } from \"./biome.js\"\nimport { genericParser } from \"./generic.js\"\nimport { gotestParser } from \"./gotest.js\"\nimport { tscParser } from \"./tsc.js\"\nimport { vitestParser } from \"./vitest.js\"\n\n/**\n * Registry for output parsers\n */\nexport class ParserRegistry {\n private parsers = new Map<string, OutputParser>()\n\n constructor() {\n // Register built-in parsers\n this.register(genericParser)\n this.register(vitestParser)\n this.register(tscParser)\n this.register(biomeParser)\n this.register(gotestParser)\n }\n\n /**\n * Register a custom parser\n */\n register(parser: OutputParser): void {\n this.parsers.set(parser.id, parser)\n }\n\n /**\n * Get a parser by ID\n */\n get(id: string): OutputParser | undefined {\n return this.parsers.get(id)\n }\n\n /**\n * Auto-detect parser based on command\n */\n detectParser(cmd: string): string {\n const cmdLower = cmd.toLowerCase()\n\n if (cmdLower.includes(\"vitest\") || cmdLower.includes(\"jest\")) {\n return \"vitest\"\n }\n if (cmdLower.includes(\"tsc\") || cmdLower.includes(\"tsgo\")) {\n return \"tsc\"\n }\n if (cmdLower.includes(\"biome\") || cmdLower.includes(\"eslint\")) {\n return \"biome\"\n }\n if (\n cmdLower.includes(\"go test\") ||\n (cmdLower.includes(\"go\") && cmdLower.includes(\"test\"))\n ) {\n return \"gotest\"\n }\n\n return \"generic\"\n }\n\n /**\n * Parse output using the specified or auto-detected parser\n */\n parse(\n output: string,\n exitCode: number,\n parserId?: string,\n cmd?: string,\n ): ParsedResult {\n const id = parserId ?? (cmd ? this.detectParser(cmd) : \"generic\")\n const parser = this.parsers.get(id) ?? genericParser\n\n const result = parser.parse(output, exitCode)\n if (result) {\n return result\n }\n\n // Fallback to generic if parser returns null\n // genericParser.parse always returns a result, never null\n const fallback = genericParser.parse(output, exitCode)\n if (!fallback) {\n throw new Error(\"genericParser unexpectedly returned null\")\n }\n return fallback\n }\n}\n\n// Default registry instance\nexport const defaultRegistry = new ParserRegistry()\n\n// Re-export individual parsers\nexport { biomeParser } from \"./biome.js\"\nexport { genericParser } from \"./generic.js\"\nexport { gotestParser } from \"./gotest.js\"\nexport { tscParser } from \"./tsc.js\"\nexport { vitestParser } from \"./vitest.js\"\n","/**\n * Arc spinner frames for terminal animation\n */\nconst SPINNER_FRAMES = [\"◜\", \"◠\", \"◝\", \"◞\", \"◡\", \"◟\"]\n\n/**\n * Spinner animation interval in milliseconds\n */\nconst SPINNER_INTERVAL = 80\n\n/**\n * Manages spinner animation for terminal output\n */\nexport class SpinnerManager {\n private frames = SPINNER_FRAMES\n private frameIndex = 0\n private interval: ReturnType<typeof setInterval> | null = null\n\n /**\n * Start the spinner animation\n * @param onTick - Callback called on each frame update\n */\n start(onTick: () => void): void {\n if (this.interval) return\n\n this.interval = setInterval(() => {\n this.frameIndex = (this.frameIndex + 1) % this.frames.length\n onTick()\n }, SPINNER_INTERVAL)\n }\n\n /**\n * Stop the spinner animation\n */\n stop(): void {\n if (this.interval) {\n clearInterval(this.interval)\n this.interval = null\n }\n }\n\n /**\n * Get the current spinner frame character\n */\n getFrame(): string {\n return this.frames[this.frameIndex]\n }\n\n /**\n * Check if spinner is currently running\n */\n isRunning(): boolean {\n return this.interval !== null\n }\n}\n","import { SpinnerManager } from \"./spinner.js\"\nimport type {\n TaskResult,\n VerificationNode,\n VerifyOptions,\n VerifyResult,\n} from \"./types.js\"\n\n/**\n * ANSI color codes\n */\nconst ansi = {\n reset: \"\\u001b[0m\",\n dim: \"\\u001b[2m\",\n red: \"\\u001b[31m\",\n green: \"\\u001b[32m\",\n yellow: \"\\u001b[33m\",\n cyan: \"\\u001b[36m\",\n bold: \"\\u001b[1m\",\n}\n\n/**\n * ANSI cursor control codes\n */\nconst cursor = {\n hide: \"\\u001b[?25l\",\n show: \"\\u001b[?25h\",\n moveUp: (n: number) => `\\u001b[${n}A`,\n moveToStart: \"\\u001b[0G\",\n clearLine: \"\\u001b[2K\",\n}\n\n/**\n * Reporter interface\n */\nexport interface Reporter {\n /** Called before any tasks start - initialize display */\n onStart?(tasks: VerificationNode[]): void\n /** Called when a task starts */\n onTaskStart(path: string, key: string): void\n /** Called when a task completes */\n onTaskComplete(result: TaskResult): void\n /** Called when all tasks complete - cleanup display */\n onFinish?(): void\n /** Called to output task logs */\n outputLogs(results: TaskResult[], logsMode: \"all\" | \"failed\" | \"none\"): void\n /** Called to output final summary */\n outputSummary(result: VerifyResult): void\n}\n\n/**\n * Check if colors should be enabled\n */\nfunction shouldUseColors(options: VerifyOptions): boolean {\n if (options.noColor) return false\n if (options.format === \"json\") return false\n if (!process.stdout.isTTY) return false\n if (\"NO_COLOR\" in process.env) return false\n if (process.env.TERM === \"dumb\") return false\n return true\n}\n\n/**\n * Base Reporter - common functionality for all reporters\n */\nexport abstract class BaseReporter implements Reporter {\n protected colorEnabled: boolean\n protected stream: NodeJS.WriteStream\n protected taskDepths: Map<string, number> = new Map()\n\n constructor(options: VerifyOptions = {}) {\n this.colorEnabled = shouldUseColors(options)\n this.stream = options.format === \"json\" ? process.stderr : process.stdout\n }\n\n /**\n * Apply ANSI color code to string (if colors enabled)\n */\n protected c(code: string, s: string): string {\n return this.colorEnabled ? `${code}${s}${ansi.reset}` : s\n }\n\n /**\n * Get success mark (✓ or OK)\n */\n protected okMark(): string {\n return this.colorEnabled ? this.c(ansi.green, \"✓\") : \"OK\"\n }\n\n /**\n * Get failure mark (✗ or FAIL)\n */\n protected failMark(): string {\n return this.colorEnabled ? this.c(ansi.red, \"✗\") : \"FAIL\"\n }\n\n /**\n * Get suppressed mark (⊘ or SUPPRESSED)\n */\n protected suppressedMark(): string {\n return this.colorEnabled ? this.c(ansi.yellow, \"⊘\") : \"SUPPRESSED\"\n }\n\n /**\n * Get arrow symbol (→ or ->)\n */\n protected arrow(): string {\n return this.colorEnabled ? this.c(ansi.cyan, \"→\") : \"->\"\n }\n\n /**\n * Get indentation string for a given depth\n */\n protected getIndent(depth: number): string {\n return \" \".repeat(depth)\n }\n\n /**\n * Get task depth from path\n */\n protected getTaskDepth(path: string): number {\n return this.taskDepths.get(path) ?? 0\n }\n\n /**\n * Recursively collect task depths from verification tree\n */\n protected collectTaskDepths(\n nodes: VerificationNode[],\n parentPath: string,\n depth: number,\n ): void {\n for (const node of nodes) {\n const path = parentPath ? `${parentPath}:${node.key}` : node.key\n this.taskDepths.set(path, depth)\n\n if (node.children) {\n this.collectTaskDepths(node.children, path, depth + 1)\n }\n }\n }\n\n /**\n * Extract summary from task result\n */\n protected extractSummary(result: TaskResult): string {\n // Use the parsed summary from summaryLine (strip the \"key: \" prefix if present)\n // The parsers already format summaries nicely with file counts, test counts, etc.\n if (result.summaryLine) {\n const colonIndex = result.summaryLine.indexOf(\": \")\n if (colonIndex !== -1) {\n return result.summaryLine.slice(colonIndex + 2)\n }\n return result.summaryLine\n }\n\n return result.ok ? \"passed\" : \"failed\"\n }\n\n /**\n * Flatten nested task results into a single array\n */\n protected flattenResults(results: TaskResult[]): TaskResult[] {\n const flat: TaskResult[] = []\n for (const r of results) {\n flat.push(r)\n if (r.children) {\n flat.push(...this.flattenResults(r.children))\n }\n }\n return flat\n }\n\n /**\n * Output task logs\n */\n outputLogs(results: TaskResult[], logsMode: \"all\" | \"failed\" | \"none\"): void {\n if (logsMode === \"none\") return\n\n const flatResults = this.flattenResults(results)\n\n for (const r of flatResults) {\n if (r.children) continue\n if (logsMode === \"failed\" && r.ok) continue\n // Skip suppressed tasks - their output is hidden to reduce noise\n if (r.suppressed) continue\n\n const status = r.ok ? this.c(ansi.green, \"OK\") : this.c(ansi.red, \"FAIL\")\n\n this.stream.write(\n `\\n${this.c(ansi.bold, \"====\")} ${this.c(ansi.bold, r.path.toUpperCase())} ${status} ${this.c(ansi.bold, \"====\")}\\n`,\n )\n this.stream.write(r.output || \"(no output)\\n\")\n }\n }\n\n /**\n * Output final summary\n */\n outputSummary(result: VerifyResult): void {\n const finalMessage = result.ok\n ? this.c(ansi.green, \"\\n== verification: All correct ==\")\n : this.c(ansi.red, \"\\n== verification: Failed ==\")\n this.stream.write(`${finalMessage}\\n`)\n }\n\n // Abstract methods that subclasses must implement\n abstract onStart(tasks: VerificationNode[]): void\n abstract onTaskStart(path: string, key: string): void\n abstract onTaskComplete(result: TaskResult): void\n abstract onFinish(): void\n}\n\n/**\n * Task state for live dashboard\n */\ninterface TaskState {\n key: string\n path: string\n depth: number\n status: \"pending\" | \"running\" | \"completed\"\n result?: TaskResult\n}\n\n/**\n * Live Dashboard Reporter - animated in-place updates for TTY\n */\nexport class LiveDashboardReporter extends BaseReporter {\n private topLevelOnly: boolean\n private tasks: Map<string, TaskState> = new Map()\n private taskOrder: string[] = []\n private spinner: SpinnerManager\n private lineCount = 0\n\n constructor(options: VerifyOptions = {}) {\n super(options)\n this.topLevelOnly = options.topLevelOnly ?? false\n this.spinner = new SpinnerManager()\n\n // Handle Ctrl+C to restore cursor\n const cleanup = () => {\n this.spinner.stop()\n this.stream.write(cursor.show)\n process.exit(130)\n }\n process.on(\"SIGINT\", cleanup)\n process.on(\"SIGTERM\", cleanup)\n }\n\n /**\n * Initialize task list from verification nodes\n */\n onStart(tasks: VerificationNode[]): void {\n this.collectTasks(tasks, \"\", 0)\n this.stream.write(cursor.hide)\n this.spinner.start(() => this.redraw())\n }\n\n /**\n * Recursively collect tasks from verification tree\n */\n private collectTasks(\n nodes: VerificationNode[],\n parentPath: string,\n depth: number,\n ): void {\n for (const node of nodes) {\n const path = parentPath ? `${parentPath}:${node.key}` : node.key\n this.tasks.set(path, {\n key: node.key,\n path,\n depth,\n status: \"pending\",\n })\n this.taskOrder.push(path)\n // Also store in base class for consistency\n this.taskDepths.set(path, depth)\n\n if (node.children) {\n this.collectTasks(node.children, path, depth + 1)\n }\n }\n }\n\n /**\n * Get display key - shows :key for nested, key for root\n */\n private getDisplayKey(task: TaskState): string {\n if (task.depth === 0) {\n return task.key\n }\n return `:${task.key}`\n }\n\n /**\n * Check if task should be displayed based on topLevelOnly flag\n */\n private shouldDisplay(task: TaskState): boolean {\n if (this.topLevelOnly) return task.depth === 0\n return true\n }\n\n /**\n * Format a single task line\n */\n private formatLine(task: TaskState): string {\n const indent = this.getIndent(task.depth)\n const displayKey = this.getDisplayKey(task)\n\n if (task.status === \"running\") {\n const spinnerChar = this.c(ansi.dim, `(${this.spinner.getFrame()})`)\n return `${indent}${this.arrow()} verifying ${this.c(ansi.bold, displayKey)} ${spinnerChar}`\n }\n\n if (task.status === \"completed\" && task.result) {\n const duration = this.c(ansi.dim, `${task.result.durationMs}ms`)\n\n // Handle suppressed tasks\n if (task.result.suppressed) {\n const reason = task.result.suppressedBy\n ? `${task.result.suppressedBy} failed`\n : \"dependency failed\"\n return `${indent}${this.suppressedMark()} suppressed ${this.c(ansi.bold, displayKey)} ${this.c(ansi.dim, `(${reason}, ${duration})`)}`\n }\n\n const summary = this.extractSummary(task.result)\n\n if (task.result.ok) {\n return ` ${indent}${this.okMark()} verified ${this.c(ansi.bold, displayKey)} ${this.c(ansi.dim, `(${summary}, ${duration})`)}`\n }\n return `${indent}${this.failMark()} failed ${this.c(ansi.bold, displayKey)} ${this.c(ansi.dim, `(${summary}, ${duration})`)}`\n }\n\n // Pending - don't show\n return \"\"\n }\n\n /**\n * Redraw all visible task lines\n */\n private redraw(): void {\n // Move cursor up to overwrite previous lines\n if (this.lineCount > 0) {\n this.stream.write(cursor.moveUp(this.lineCount))\n }\n\n // Build new output\n const lines: string[] = []\n for (const path of this.taskOrder) {\n const task = this.tasks.get(path)\n if (!task) continue\n if (!this.shouldDisplay(task)) continue\n if (task.status === \"pending\") continue\n\n const line = this.formatLine(task)\n if (line) {\n lines.push(line)\n }\n }\n\n // Write lines with clear\n for (const line of lines) {\n this.stream.write(`${cursor.clearLine}${cursor.moveToStart}${line}\\n`)\n }\n\n this.lineCount = lines.length\n }\n\n onTaskStart(path: string, _key: string): void {\n const task = this.tasks.get(path)\n if (task) {\n task.status = \"running\"\n }\n // Redraw happens on spinner tick\n }\n\n onTaskComplete(result: TaskResult): void {\n const task = this.tasks.get(result.path)\n if (task) {\n task.status = \"completed\"\n task.result = result\n }\n // Redraw happens on spinner tick, but do one now for immediate feedback\n this.redraw()\n }\n\n onFinish(): void {\n this.spinner.stop()\n this.redraw() // Final redraw\n this.stream.write(cursor.show)\n }\n}\n\n/**\n * Sequential Reporter - line-by-line output for non-TTY\n * No indentation since parallel execution means output order doesn't reflect hierarchy\n */\nexport class SequentialReporter extends BaseReporter {\n private topLevelOnly: boolean\n\n constructor(options: VerifyOptions = {}) {\n super(options)\n this.topLevelOnly = options.topLevelOnly ?? false\n }\n\n onStart(tasks: VerificationNode[]): void {\n // Collect task depths from the config tree\n this.collectTaskDepths(tasks, \"\", 0)\n }\n\n /**\n * Check if task should be displayed based on topLevelOnly flag\n */\n private shouldDisplay(path: string): boolean {\n if (this.topLevelOnly) return this.getTaskDepth(path) === 0\n return true\n }\n\n onTaskStart(path: string, _key: string): void {\n if (!this.shouldDisplay(path)) return\n this.stream.write(`${this.arrow()} verifying ${this.c(ansi.bold, path)}\\n`)\n }\n\n onTaskComplete(result: TaskResult): void {\n if (!this.shouldDisplay(result.path)) return\n const duration = this.c(ansi.dim, `${result.durationMs}ms`)\n\n // Handle suppressed tasks\n if (result.suppressed) {\n const reason = result.suppressedBy\n ? `${result.suppressedBy} failed`\n : \"dependency failed\"\n this.stream.write(\n `${this.suppressedMark()} suppressed ${this.c(ansi.bold, result.path)} ${this.c(ansi.dim, `(${reason}, ${duration})`)}\\n`,\n )\n return\n }\n\n const mark = result.ok ? this.okMark() : this.failMark()\n const verb = result.ok ? \"verified\" : \"failed\"\n const summary = this.extractSummary(result)\n this.stream.write(\n `${mark} ${verb} ${this.c(ansi.bold, result.path)} ${this.c(ansi.dim, `(${summary}, ${duration})`)}\\n`,\n )\n }\n\n onFinish(): void {\n // No cleanup needed for sequential output\n }\n}\n\n/**\n * JSON Reporter - machine-readable output\n */\nexport class JSONReporter implements Reporter {\n onStart(_tasks: VerificationNode[]): void {\n // No output during execution in JSON mode\n }\n\n onTaskStart(_path: string, _key: string): void {\n // No output during execution in JSON mode\n }\n\n onTaskComplete(_result: TaskResult): void {\n // No output during execution in JSON mode\n }\n\n onFinish(): void {\n // No cleanup needed for JSON output\n }\n\n outputLogs(\n _results: TaskResult[],\n _logsMode: \"all\" | \"failed\" | \"none\",\n ): void {\n // Logs are included in the JSON output\n }\n\n outputSummary(result: VerifyResult): void {\n const summary = {\n ok: result.ok,\n startedAt: result.startedAt,\n finishedAt: result.finishedAt,\n durationMs: result.durationMs,\n tasks: this.serializeTasks(result.tasks),\n }\n\n process.stdout.write(`${JSON.stringify(summary)}\\n`)\n }\n\n private serializeTasks(tasks: TaskResult[]): Array<{\n key: string\n path: string\n ok: boolean\n code: number\n durationMs: number\n summaryLine: string\n suppressed?: boolean\n suppressedBy?: string\n children?: ReturnType<JSONReporter[\"serializeTasks\"]>\n }> {\n return tasks.map(t => ({\n key: t.key,\n path: t.path,\n ok: t.ok,\n code: t.code,\n durationMs: t.durationMs,\n summaryLine: t.summaryLine,\n ...(t.suppressed ? { suppressed: t.suppressed } : {}),\n ...(t.suppressedBy ? { suppressedBy: t.suppressedBy } : {}),\n ...(t.children ? { children: this.serializeTasks(t.children) } : {}),\n }))\n }\n}\n\n/**\n * Quiet Reporter - minimal output (summary only)\n */\nexport class QuietReporter extends BaseReporter {\n onStart(_tasks: VerificationNode[]): void {\n // No output\n }\n\n onTaskStart(_path: string, _key: string): void {\n // No output\n }\n\n onTaskComplete(_result: TaskResult): void {\n // No output\n }\n\n onFinish(): void {\n // No cleanup needed\n }\n\n outputLogs(\n _results: TaskResult[],\n _logsMode: \"all\" | \"failed\" | \"none\",\n ): void {\n // No logs in quiet mode\n }\n\n outputSummary(result: VerifyResult): void {\n const message = result.ok\n ? this.c(ansi.green, \"✓ All verifications passed\")\n : this.c(ansi.red, \"✗ Some verifications failed\")\n process.stdout.write(`${message}\\n`)\n }\n}\n\n/**\n * Create appropriate reporter based on options\n */\nexport function createReporter(options: VerifyOptions): Reporter {\n if (options.format === \"json\") {\n return new JSONReporter()\n }\n\n // Use LiveDashboardReporter for TTY (unless --no-tty is set)\n if (process.stdout.isTTY && !options.noTty) {\n return new LiveDashboardReporter(options)\n }\n\n return new SequentialReporter(options)\n}\n\n// Keep TTYReporter as alias for backwards compatibility\nexport { SequentialReporter as TTYReporter }\n","import { type ChildProcess, spawn } from \"node:child_process\"\nimport treeKill from \"tree-kill\"\nimport { defaultRegistry, type ParserRegistry } from \"./parsers/index.js\"\nimport type {\n ParsedResult,\n TaskResult,\n VerificationCommand,\n VerificationNode,\n VerifyOptions,\n VerifyResult,\n} from \"./types.js\"\n\n/**\n * Normalize command to VerificationCommand format\n */\nfunction normalizeCommand(\n run: VerificationCommand | string | [string, string[]],\n): VerificationCommand {\n if (typeof run === \"string\") {\n // Parse string command: \"pnpm verify:format\" -> { cmd: \"pnpm\", args: [\"verify:format\"] }\n const parts = run.split(/\\s+/)\n return {\n cmd: parts[0],\n args: parts.slice(1),\n }\n }\n\n if (Array.isArray(run)) {\n return {\n cmd: run[0],\n args: run[1],\n }\n }\n\n return run\n}\n\n/**\n * Tracks reporting dependencies between tasks and coordinates result emission.\n * Allows tasks to wait for their dependencies to complete before emitting results,\n * and determines if a task's failure should be suppressed.\n * Also handles early termination by killing dependent processes when a dependency fails.\n */\nexport class ReportingDependencyTracker {\n /** Map of task path/key to their results */\n private results: Map<string, TaskResult> = new Map()\n\n /** Map of task path/key to waiters (callbacks to resolve when result is available) */\n private waiters: Map<string, Array<() => void>> = new Map()\n\n /** Map of task path to its key (for key-based lookups) */\n private pathToKey: Map<string, string> = new Map()\n\n /** Map of task key to its path (for key-based lookups) */\n private keyToPath: Map<string, string> = new Map()\n\n /** Map of task path to its reportingDependsOn array */\n private dependencies: Map<string, string[]> = new Map()\n\n /** Reverse map: task path → list of tasks that depend on it */\n private reverseDeps: Map<string, string[]> = new Map()\n\n /** Map of task path to its running ChildProcess */\n private processes: Map<string, ChildProcess> = new Map()\n\n /** Set of task paths that have been killed */\n private killedPaths: Set<string> = new Set()\n\n /**\n * Initialize the tracker with all tasks from the verification tree.\n * Also validates for circular dependencies and builds reverse dependency map.\n */\n initialize(nodes: VerificationNode[], parentPath = \"\"): void {\n for (const node of nodes) {\n const path = parentPath ? `${parentPath}:${node.key}` : node.key\n this.pathToKey.set(path, node.key)\n this.keyToPath.set(node.key, path)\n\n if (node.reportingDependsOn && node.reportingDependsOn.length > 0) {\n this.dependencies.set(path, node.reportingDependsOn)\n }\n\n if (node.children) {\n this.initialize(node.children, path)\n }\n }\n\n // Only validate cycles and build reverse deps once at the root level\n if (parentPath === \"\") {\n this.validateNoCycles()\n this.buildReverseDeps()\n }\n }\n\n /**\n * Build reverse dependency map (task → tasks that depend on it)\n */\n private buildReverseDeps(): void {\n for (const [path, deps] of this.dependencies.entries()) {\n for (const dep of deps) {\n const resolvedDep = this.resolveDependency(dep)\n if (resolvedDep) {\n const existing = this.reverseDeps.get(resolvedDep) ?? []\n existing.push(path)\n this.reverseDeps.set(resolvedDep, existing)\n }\n }\n }\n }\n\n /**\n * Validate that there are no circular dependencies using DFS with coloring.\n * Throws an error with the cycle path if a cycle is detected.\n */\n private validateNoCycles(): void {\n const WHITE = 0 // Not visited\n const GRAY = 1 // Currently visiting (in stack)\n const BLACK = 2 // Fully visited\n\n const colors = new Map<string, number>()\n const parent = new Map<string, string>()\n\n // Initialize all nodes as white\n for (const path of this.pathToKey.keys()) {\n colors.set(path, WHITE)\n }\n\n const dfs = (path: string): string | null => {\n colors.set(path, GRAY)\n\n const deps = this.dependencies.get(path) ?? []\n for (const dep of deps) {\n const depPath = this.resolveDependency(dep)\n if (!depPath) continue // Unknown dependency, skip\n\n const color = colors.get(depPath) ?? WHITE\n\n if (color === GRAY) {\n // Found a cycle - reconstruct the path\n const cycle: string[] = [depPath]\n let current = path\n while (current !== depPath) {\n cycle.unshift(current)\n current = parent.get(current) ?? \"\"\n }\n cycle.unshift(depPath)\n return cycle.join(\" → \")\n }\n\n if (color === WHITE) {\n parent.set(depPath, path)\n const cyclePath = dfs(depPath)\n if (cyclePath) return cyclePath\n }\n }\n\n colors.set(path, BLACK)\n return null\n }\n\n for (const path of this.pathToKey.keys()) {\n if (colors.get(path) === WHITE) {\n const cyclePath = dfs(path)\n if (cyclePath) {\n throw new Error(\n `Circular reporting dependency detected: ${cyclePath}`,\n )\n }\n }\n }\n }\n\n /**\n * Resolve a dependency identifier to a task path.\n * Tries exact path match first, then key match.\n */\n private resolveDependency(dep: string): string | null {\n // Try exact path match first\n if (this.pathToKey.has(dep)) {\n return dep\n }\n\n // Try key match\n if (this.keyToPath.has(dep)) {\n return this.keyToPath.get(dep) ?? null\n }\n\n return null\n }\n\n /**\n * Record a task result and notify any waiters.\n * If the task failed, kills all dependent processes for early termination.\n */\n recordResult(result: TaskResult): void {\n // Store by path\n this.results.set(result.path, result)\n\n // If this task failed, kill all dependent processes\n if (!result.ok) {\n this.killDependents(result.path)\n }\n\n // Notify waiters for this path\n const pathWaiters = this.waiters.get(result.path) ?? []\n for (const waiter of pathWaiters) {\n waiter()\n }\n this.waiters.delete(result.path)\n\n // Also notify waiters for the key (if different from path)\n const key = result.key\n if (key !== result.path) {\n const keyWaiters = this.waiters.get(key) ?? []\n for (const waiter of keyWaiters) {\n waiter()\n }\n this.waiters.delete(key)\n }\n }\n\n /**\n * Wait for all dependencies of a task to complete.\n */\n async waitForDependencies(path: string): Promise<void> {\n const deps = this.dependencies.get(path)\n if (!deps || deps.length === 0) {\n return\n }\n\n const waitPromises = deps.map(dep => this.waitForResult(dep))\n await Promise.all(waitPromises)\n }\n\n /**\n * Wait for a specific task result to be available.\n */\n private waitForResult(pathOrKey: string): Promise<void> {\n // Check if result already exists\n const resolvedPath = this.resolveDependency(pathOrKey)\n if (resolvedPath && this.results.has(resolvedPath)) {\n return Promise.resolve()\n }\n\n // Also check by the original identifier\n if (this.results.has(pathOrKey)) {\n return Promise.resolve()\n }\n\n // Register a waiter\n return new Promise<void>(resolve => {\n const waiters = this.waiters.get(pathOrKey) ?? []\n waiters.push(resolve)\n this.waiters.set(pathOrKey, waiters)\n })\n }\n\n /**\n * Check if any dependency of a task has failed.\n * Returns the path of the first failed dependency, or null if all passed.\n */\n getFailedDependency(path: string): string | null {\n const deps = this.dependencies.get(path)\n if (!deps || deps.length === 0) {\n return null\n }\n\n for (const dep of deps) {\n const resolvedPath = this.resolveDependency(dep)\n if (!resolvedPath) continue\n\n const result = this.results.get(resolvedPath)\n if (result && !result.ok) {\n return resolvedPath\n }\n }\n\n return null\n }\n\n /**\n * Check if a task has any reporting dependencies.\n */\n hasDependencies(path: string): boolean {\n const deps = this.dependencies.get(path)\n return deps !== undefined && deps.length > 0\n }\n\n /**\n * Register a running process for a task.\n */\n registerProcess(path: string, proc: ChildProcess): void {\n this.processes.set(path, proc)\n }\n\n /**\n * Unregister a process (called when it completes naturally).\n */\n unregisterProcess(path: string): void {\n this.processes.delete(path)\n }\n\n /**\n * Check if a task was killed.\n */\n wasKilled(path: string): boolean {\n return this.killedPaths.has(path)\n }\n\n /**\n * Kill all processes that depend on the failed task.\n * Called when a task fails to terminate dependent tasks early.\n */\n killDependents(failedPath: string): void {\n const dependents = this.reverseDeps.get(failedPath) ?? []\n\n for (const depPath of dependents) {\n const proc = this.processes.get(depPath)\n if (proc?.pid) {\n this.killedPaths.add(depPath)\n // Use tree-kill to kill the process and all its children\n treeKill(proc.pid, \"SIGTERM\", err => {\n if (err) {\n // Process may have already exited, ignore errors\n }\n })\n }\n }\n }\n}\n\n/**\n * Execute a single command and capture output.\n * Optionally registers the process with a tracker for early termination support.\n */\nasync function executeCommand(\n command: VerificationCommand,\n cwd: string,\n tracker?: ReportingDependencyTracker,\n path?: string,\n): Promise<{\n code: number\n output: string\n durationMs: number\n killed: boolean\n}> {\n const start = Date.now()\n\n return new Promise(resolve => {\n const proc = spawn(command.cmd, command.args, {\n shell: process.platform === \"win32\",\n cwd: command.cwd ?? cwd,\n env: { ...process.env, NO_COLOR: \"1\", ...command.env },\n })\n\n // Register process for early termination\n if (tracker && path) {\n tracker.registerProcess(path, proc)\n }\n\n let output = \"\"\n\n proc.stdout.on(\"data\", (data: Buffer) => {\n output += data.toString()\n })\n\n proc.stderr.on(\"data\", (data: Buffer) => {\n output += data.toString()\n })\n\n proc.on(\"close\", (code, signal) => {\n // Unregister process\n if (tracker && path) {\n tracker.unregisterProcess(path)\n }\n\n const durationMs = Date.now() - start\n // Check if process was killed (SIGTERM = 15, exit code 143 = 128 + 15)\n const killed =\n signal === \"SIGTERM\" ||\n code === 143 ||\n (tracker?.wasKilled(path ?? \"\") ?? false)\n\n resolve({\n code: code ?? 1,\n output,\n durationMs,\n killed,\n })\n })\n\n proc.on(\"error\", err => {\n // Unregister process\n if (tracker && path) {\n tracker.unregisterProcess(path)\n }\n\n const durationMs = Date.now() - start\n resolve({\n code: 1,\n output: `Failed to execute command: ${err.message}`,\n durationMs,\n killed: false,\n })\n })\n })\n}\n\n/**\n * Build full path for a node\n */\nfunction buildPath(parentPath: string, key: string): string {\n return parentPath ? `${parentPath}:${key}` : key\n}\n\n/**\n * Check if a path matches the filter\n */\nfunction matchesFilter(path: string, filters?: string[]): boolean {\n if (!filters || filters.length === 0) {\n return true\n }\n\n return filters.some(filter => {\n // Exact match or prefix match\n return path === filter || path.startsWith(`${filter}:`)\n })\n}\n\n/**\n * Check if any descendant matches the filter\n */\nfunction hasMatchingDescendant(\n node: VerificationNode,\n parentPath: string,\n filters?: string[],\n): boolean {\n const path = buildPath(parentPath, node.key)\n\n if (matchesFilter(path, filters)) {\n return true\n }\n\n if (node.children) {\n return node.children.some(child =>\n hasMatchingDescendant(child, path, filters),\n )\n }\n\n return false\n}\n\nexport interface RunnerCallbacks {\n onTaskStart?: (path: string, key: string) => void\n onTaskComplete?: (result: TaskResult) => void\n}\n\n/**\n * Verification runner\n */\nexport class VerificationRunner {\n private registry: ParserRegistry\n private options: VerifyOptions\n private callbacks: RunnerCallbacks\n private dependencyTracker: ReportingDependencyTracker\n\n constructor(\n options: VerifyOptions = {},\n registry: ParserRegistry = defaultRegistry,\n callbacks: RunnerCallbacks = {},\n ) {\n this.options = options\n this.registry = registry\n this.callbacks = callbacks\n this.dependencyTracker = new ReportingDependencyTracker()\n }\n\n /**\n * Run all verification tasks\n */\n async run(tasks: VerificationNode[]): Promise<VerifyResult> {\n const startedAt = new Date().toISOString()\n const wallStart = Date.now()\n\n // Initialize dependency tracker with all tasks (validates cycles)\n this.dependencyTracker.initialize(tasks)\n\n const results = await this.runNodes(tasks, \"\")\n\n const finishedAt = new Date().toISOString()\n const durationMs = Date.now() - wallStart\n\n const allOk = results.every(r => r.ok)\n\n return {\n ok: allOk,\n startedAt,\n finishedAt,\n durationMs,\n tasks: results,\n }\n }\n\n /**\n * Run a list of nodes with the appropriate strategy\n */\n private async runNodes(\n nodes: VerificationNode[],\n parentPath: string,\n strategy: \"parallel\" | \"sequential\" | \"fail-fast\" = \"parallel\",\n ): Promise<TaskResult[]> {\n // Filter nodes based on filter option\n const filteredNodes = nodes.filter(node =>\n hasMatchingDescendant(node, parentPath, this.options.filter),\n )\n\n if (filteredNodes.length === 0) {\n return []\n }\n\n switch (strategy) {\n case \"parallel\":\n return Promise.all(\n filteredNodes.map(node => this.runNode(node, parentPath)),\n )\n\n case \"sequential\": {\n const results: TaskResult[] = []\n for (const node of filteredNodes) {\n results.push(await this.runNode(node, parentPath))\n }\n return results\n }\n\n case \"fail-fast\": {\n const results: TaskResult[] = []\n for (const node of filteredNodes) {\n const result = await this.runNode(node, parentPath)\n results.push(result)\n if (!result.ok) {\n break\n }\n }\n return results\n }\n }\n }\n\n /**\n * Run a single node (leaf or group)\n */\n private async runNode(\n node: VerificationNode,\n parentPath: string,\n ): Promise<TaskResult> {\n const path = buildPath(parentPath, node.key)\n\n // Notify start\n this.callbacks.onTaskStart?.(path, node.key)\n\n // If this is a group node (has children), run children\n if (node.children && node.children.length > 0) {\n const start = Date.now()\n const childResults = await this.runNodes(\n node.children,\n path,\n node.strategy ?? \"parallel\",\n )\n const durationMs = Date.now() - start\n\n const allOk = childResults.every(r => r.ok || r.suppressed)\n\n // Propagate suppressed status from children to parent\n const allSuppressed =\n childResults.length > 0 && childResults.every(r => r.suppressed)\n const anySuppressed = childResults.some(r => r.suppressed)\n\n const result: TaskResult = {\n key: node.key,\n path,\n ok: allOk,\n code: allOk ? 0 : 1,\n durationMs,\n output: \"\",\n summaryLine: allOk\n ? (node.successLabel ?? `${node.key}: all passed`)\n : (node.failureLabel ?? `${node.key}: some failed`),\n children: childResults,\n }\n\n // If all children are suppressed, parent is also suppressed\n if (allSuppressed) {\n result.suppressed = true\n result.suppressedBy = childResults[0].suppressedBy\n } else if (anySuppressed && !allOk) {\n // Mixed: some suppressed, some failed - don't suppress parent\n // The parent shows as failed with the actual failures visible\n }\n\n // Record result in tracker before emitting\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n\n // Leaf node - execute command\n if (!node.run) {\n const result: TaskResult = {\n key: node.key,\n path,\n ok: true,\n code: 0,\n durationMs: 0,\n output: \"\",\n summaryLine: `${node.key}: no command specified`,\n }\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n\n const command = normalizeCommand(node.run)\n const cwd = this.options.cwd ?? process.cwd()\n\n // Pass tracker and path for early termination support\n const { code, output, durationMs, killed } = await executeCommand(\n command,\n cwd,\n this.dependencyTracker,\n path,\n )\n\n const ok = code === 0\n\n // If process was killed, mark as suppressed immediately\n if (killed) {\n // Wait for dependencies to get the failed dependency path\n await this.dependencyTracker.waitForDependencies(path)\n const failedDep = this.dependencyTracker.getFailedDependency(path)\n\n const result: TaskResult = {\n key: node.key,\n path,\n ok: false,\n code,\n durationMs,\n output,\n summaryLine: `${node.key}: terminated`,\n suppressed: true,\n suppressedBy: failedDep ?? \"unknown\",\n }\n\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n\n // Parse output\n const cmdString = `${command.cmd} ${command.args.join(\" \")}`\n const parsed: ParsedResult = this.registry.parse(\n output,\n code,\n node.parser,\n cmdString,\n )\n\n // Build summary line\n let summaryLine: string\n if (ok) {\n summaryLine = node.successLabel\n ? `${node.key}: ${node.successLabel}`\n : `${node.key}: ${parsed.summary}`\n } else {\n summaryLine = node.failureLabel\n ? `${node.key}: ${node.failureLabel}`\n : `${node.key}: ${parsed.summary}`\n }\n\n let result: TaskResult = {\n key: node.key,\n path,\n ok,\n code,\n durationMs,\n output,\n summaryLine,\n metrics: parsed.metrics,\n }\n\n // If this task has reporting dependencies, wait for them and check for suppression\n if (this.dependencyTracker.hasDependencies(path)) {\n await this.dependencyTracker.waitForDependencies(path)\n\n // Check if any dependency failed - if so, suppress this task's failure\n if (!ok) {\n const failedDep = this.dependencyTracker.getFailedDependency(path)\n if (failedDep) {\n result = {\n ...result,\n suppressed: true,\n suppressedBy: failedDep,\n }\n }\n }\n }\n\n // Record result in tracker before emitting\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n}\n","// Types\n\n// Config helpers\nexport {\n defineConfig,\n defineTask,\n findConfigFile,\n loadConfig,\n loadConfigFromCwd,\n mergeOptions,\n} from \"./config.js\"\n// Discovery\nexport {\n type DiscoveredPackage,\n discoverPackages,\n hasPackageChanged,\n} from \"./discovery.js\"\n// Init\nexport {\n type DetectedTask,\n detectTasks,\n generateConfigContent,\n type InitOptions,\n type InitResult,\n type OutputFormat,\n runInit,\n} from \"./init/index.js\"\n// Parsers\nexport {\n biomeParser,\n defaultRegistry,\n genericParser,\n gotestParser,\n ParserRegistry,\n tscParser,\n vitestParser,\n} from \"./parsers/index.js\"\n\n// Reporter\nexport {\n createReporter,\n JSONReporter,\n LiveDashboardReporter,\n QuietReporter,\n type Reporter,\n SequentialReporter,\n TTYReporter,\n} from \"./reporter.js\"\n// Runner\nexport { type RunnerCallbacks, VerificationRunner } from \"./runner.js\"\nexport type {\n ExecutionStrategy,\n OutputParser,\n PackageDiscoveryOptions,\n ParsedResult,\n TaskResult,\n VerificationCommand,\n VerificationNode,\n VerifyConfig,\n VerifyOptions,\n VerifyResult,\n} from \"./types.js\"\n\nimport { loadConfigFromCwd, mergeOptions } from \"./config.js\"\nimport { createReporter } from \"./reporter.js\"\nimport { VerificationRunner } from \"./runner.js\"\n// Main verify function\nimport type { VerifyConfig, VerifyOptions, VerifyResult } from \"./types.js\"\n\n/**\n * Run verification with the given config and options\n */\nexport async function verify(\n config: VerifyConfig,\n cliOptions?: Partial<VerifyOptions>,\n): Promise<VerifyResult> {\n const options = mergeOptions(config.options, cliOptions)\n const reporter = createReporter(options)\n\n // Initialize reporter with task list (for live dashboard)\n reporter.onStart?.(config.tasks)\n\n const runner = new VerificationRunner(options, undefined, {\n onTaskStart: (path, key) => reporter.onTaskStart(path, key),\n onTaskComplete: result => reporter.onTaskComplete(result),\n })\n\n const result = await runner.run(config.tasks)\n\n // Cleanup reporter (stop spinner, restore cursor)\n reporter.onFinish?.()\n\n reporter.outputLogs(result.tasks, options.logs ?? \"failed\")\n reporter.outputSummary(result)\n\n return result\n}\n\n/**\n * Run verification from config file in cwd\n */\nexport async function verifyFromConfig(\n cwd: string = process.cwd(),\n cliOptions?: Partial<VerifyOptions>,\n): Promise<VerifyResult> {\n const config = await loadConfigFromCwd(cwd, cliOptions?.cwd)\n\n if (!config) {\n throw new Error(\n `No verify config found in ${cwd}. Create a verify.config.ts file.`,\n )\n }\n\n return verify(config, { ...cliOptions, cwd })\n}\n"],"mappings":"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","names":["existsSync","join","join","existsSync","existsSync","join","existsSync","resolve","errors","resolve","durationMs","result","result"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/discovery.ts","../src/schemas/package-json.ts","../src/filter.ts","../src/tree.ts","../src/init/detect.ts","../src/init/generate.ts","../src/init/prompts.ts","../src/init/write.ts","../src/init/index.ts","../src/parsers/biome.ts","../src/parsers/generic.ts","../src/parsers/gotest.ts","../src/parsers/tsc.ts","../src/parsers/vitest.ts","../src/parsers/index.ts","../src/spinner.ts","../src/reporter.ts","../src/runner.ts","../src/dependency-tracker.ts","../src/index.ts"],"sourcesContent":["import { existsSync } from \"node:fs\"\nimport { join, resolve } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport { z } from \"zod\"\nimport type { VerificationNode, VerifyConfig, VerifyOptions } from \"./types.js\"\n\n/**\n * Error thrown when config validation fails\n */\nexport class ConfigError extends Error {\n constructor(\n message: string,\n public readonly configPath?: string,\n ) {\n super(message)\n this.name = \"ConfigError\"\n }\n}\n\n/**\n * Zod schema for VerificationCommand\n */\nconst VerificationCommandSchema = z.object({\n cmd: z.string(),\n args: z.array(z.string()),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n timeout: z.number().positive().optional(),\n})\n\n/**\n * Zod schema for VerificationNode (recursive)\n */\nconst VerificationNodeSchema: z.ZodType<VerificationNode> = z.lazy(() =>\n z.object({\n key: z\n .string()\n .min(1, \"Task key cannot be empty\")\n .refine(key => !key.includes(\":\"), {\n message: \"Task key cannot contain ':' (reserved for paths)\",\n }),\n name: z.string().optional(),\n run: z.union([z.string(), VerificationCommandSchema]).optional(),\n children: z.array(VerificationNodeSchema).optional(),\n strategy: z.enum([\"parallel\", \"sequential\", \"fail-fast\"]).optional(),\n parser: z.string().optional(),\n successLabel: z.string().optional(),\n failureLabel: z.string().optional(),\n reportingDependsOn: z.array(z.string()).optional(),\n timeout: z.number().positive().optional(),\n }),\n) as z.ZodType<VerificationNode>\n\n/**\n * Zod schema for VerifyOptions\n */\nconst VerifyOptionsSchema = z.object({\n logs: z.enum([\"all\", \"failed\", \"none\"]).optional(),\n format: z.enum([\"human\", \"json\"]).optional(),\n filter: z.array(z.string()).optional(),\n cwd: z.string().optional(),\n noColor: z.boolean().optional(),\n topLevelOnly: z.boolean().optional(),\n noTty: z.boolean().optional(),\n})\n\n/**\n * Zod schema for PackageDiscoveryOptions\n */\nconst PackageDiscoveryOptionsSchema = z.object({\n patterns: z.array(z.string()).optional(),\n filter: z.array(z.string()).optional(),\n changed: z.boolean().optional(),\n})\n\n/**\n * Zod schema for VerifyConfig\n */\nconst VerifyConfigSchema = z.object({\n tasks: z.array(VerificationNodeSchema),\n packages: PackageDiscoveryOptionsSchema.optional(),\n options: VerifyOptionsSchema.optional(),\n})\n\n/**\n * Validate a config object and return typed result\n */\nexport function validateConfig(\n value: unknown,\n configPath?: string,\n): VerifyConfig {\n const result = VerifyConfigSchema.safeParse(value)\n\n if (!result.success) {\n const errors = result.error.issues.map(issue => {\n const path = issue.path.join(\".\")\n return path ? `${path}: ${issue.message}` : issue.message\n })\n throw new ConfigError(\n `Invalid config:\\n - ${errors.join(\"\\n - \")}`,\n configPath,\n )\n }\n\n return result.data\n}\n\n/**\n * Helper function for defining config with type inference\n */\nexport function defineConfig(config: VerifyConfig): VerifyConfig {\n return config\n}\n\n/**\n * Helper function for defining a single verification task\n */\nexport function defineTask(task: VerificationNode): VerificationNode {\n return task\n}\n\n/**\n * Config file names to search for (in order of priority)\n */\nconst CONFIG_FILES = [\n \"verify.config.ts\",\n \"verify.config.mts\",\n \"verify.config.js\",\n \"verify.config.mjs\",\n]\n\n/**\n * Find config file in directory\n */\nexport function findConfigFile(cwd: string): string | null {\n for (const filename of CONFIG_FILES) {\n const filepath = join(cwd, filename)\n if (existsSync(filepath)) {\n return filepath\n }\n }\n return null\n}\n\n/**\n * Load config from file\n */\nexport async function loadConfig(\n configPath: string,\n): Promise<VerifyConfig | null> {\n const absolutePath = resolve(configPath)\n\n if (!existsSync(absolutePath)) {\n return null\n }\n\n // Use dynamic import with file URL for cross-platform compatibility\n const fileUrl = pathToFileURL(absolutePath).href\n const module = (await import(fileUrl)) as { default?: unknown }\n\n if (!module.default) {\n throw new ConfigError(`Config file must have a default export`, configPath)\n }\n\n // Validate the config using zod\n return validateConfig(module.default, configPath)\n}\n\n/**\n * Load config from cwd or specified path\n */\nexport async function loadConfigFromCwd(\n cwd: string,\n configPath?: string,\n): Promise<VerifyConfig | null> {\n if (configPath) {\n return loadConfig(configPath)\n }\n\n const foundPath = findConfigFile(cwd)\n if (!foundPath) {\n return null\n }\n\n return loadConfig(foundPath)\n}\n\n/**\n * Helper type that requires all keys to be present but preserves original value types.\n * This is used to ensure mergeOptions handles all VerifyOptions properties.\n */\ntype AllKeys<T> = { [K in keyof Required<T>]: T[K] }\n\n/**\n * Merge options with defaults.\n *\n * NOTE: The `satisfies AllKeys<VerifyOptions>` ensures this function handles\n * all properties of VerifyOptions. If you add a new option to VerifyOptions,\n * TypeScript will error here until you add it to the return object.\n */\nexport function mergeOptions(\n configOptions?: VerifyOptions,\n cliOptions?: Partial<VerifyOptions>,\n): VerifyOptions {\n return {\n logs: cliOptions?.logs ?? configOptions?.logs ?? \"failed\",\n format: cliOptions?.format ?? configOptions?.format ?? \"human\",\n filter: cliOptions?.filter ?? configOptions?.filter,\n cwd: cliOptions?.cwd ?? configOptions?.cwd ?? process.cwd(),\n noColor: cliOptions?.noColor ?? configOptions?.noColor ?? false,\n topLevelOnly:\n cliOptions?.topLevelOnly ?? configOptions?.topLevelOnly ?? false,\n noTty: cliOptions?.noTty ?? configOptions?.noTty ?? false,\n } satisfies AllKeys<VerifyOptions>\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\"\nimport { join, relative } from \"node:path\"\nimport { findConfigFile, loadConfig } from \"./config.js\"\nimport { parsePackageJson } from \"./schemas/package-json.js\"\nimport type { PackageDiscoveryOptions, VerifyConfig } from \"./types.js\"\n\n/**\n * Discovered package with its config\n */\nexport interface DiscoveredPackage {\n /** Package name from package.json */\n name: string\n /** Relative path from root */\n path: string\n /** Absolute path */\n absolutePath: string\n /** Loaded verify config (if exists) */\n config: VerifyConfig | null\n}\n\n/**\n * Default glob patterns for package discovery\n */\nconst DEFAULT_PATTERNS = [\"packages/*\", \"apps/*\"]\n\n/**\n * Find directories matching patterns\n */\nfunction findMatchingDirs(rootDir: string, patterns: string[]): string[] {\n const results: string[] = []\n\n for (const pattern of patterns) {\n // Handle simple patterns like \"packages/*\"\n if (pattern.endsWith(\"/*\")) {\n const parentDir = pattern.slice(0, -2)\n const parentPath = join(rootDir, parentDir)\n\n if (existsSync(parentPath) && statSync(parentPath).isDirectory()) {\n const entries = readdirSync(parentPath)\n for (const entry of entries) {\n const entryPath = join(parentPath, entry)\n if (statSync(entryPath).isDirectory()) {\n results.push(entryPath)\n }\n }\n }\n } else {\n // Direct path\n const dirPath = join(rootDir, pattern)\n if (existsSync(dirPath) && statSync(dirPath).isDirectory()) {\n results.push(dirPath)\n }\n }\n }\n\n return results\n}\n\n/**\n * Read package name from package.json\n */\nfunction getPackageName(packageDir: string): string | null {\n const packageJsonPath = join(packageDir, \"package.json\")\n if (!existsSync(packageJsonPath)) {\n return null\n }\n\n try {\n const content = readFileSync(packageJsonPath, \"utf-8\")\n const parsed = parsePackageJson(content)\n return parsed?.name ?? null\n } catch {\n // File read error\n return null\n }\n}\n\n/**\n * Discover packages in a monorepo\n */\nexport async function discoverPackages(\n rootDir: string,\n options: PackageDiscoveryOptions = {},\n): Promise<DiscoveredPackage[]> {\n const patterns = options.patterns ?? DEFAULT_PATTERNS\n const matchingDirs = findMatchingDirs(rootDir, patterns)\n\n const packages: DiscoveredPackage[] = []\n\n for (const dir of matchingDirs) {\n const name = getPackageName(dir)\n if (!name) continue // Skip directories without package.json\n\n // Check filter\n if (options.filter && options.filter.length > 0) {\n const matches = options.filter.some(\n f =>\n name === f || name.includes(f) || relative(rootDir, dir).includes(f),\n )\n if (!matches) continue\n }\n\n // Try to load verify config\n const configPath = findConfigFile(dir)\n const config = configPath ? await loadConfig(configPath) : null\n\n packages.push({\n name,\n path: relative(rootDir, dir),\n absolutePath: dir,\n config,\n })\n }\n\n return packages\n}\n\n/**\n * Check if a package has changed (git-aware)\n * This is a placeholder - full implementation would use git diff\n */\nexport async function hasPackageChanged(\n _packagePath: string,\n _baseBranch = \"main\",\n): Promise<boolean> {\n // TODO: Implement git-aware change detection\n // For now, always return true (include all packages)\n return true\n}\n","import { z } from \"zod\"\n\n/**\n * Minimal zod schema for package.json\n * Only validates the fields we actually use\n */\nexport const PackageJsonSchema = z\n .object({\n name: z.string().optional(),\n scripts: z.record(z.string(), z.string()).optional(),\n })\n .passthrough() // Allow other fields we don't care about\n\n/**\n * Typed result from parsing package.json\n */\nexport type PackageJson = z.infer<typeof PackageJsonSchema>\n\n/**\n * Parse package.json content safely\n * Returns null if parsing fails (invalid JSON or schema mismatch)\n */\nexport function parsePackageJson(content: string): PackageJson | null {\n try {\n const parsed: unknown = JSON.parse(content)\n const result = PackageJsonSchema.safeParse(parsed)\n return result.success ? result.data : null\n } catch {\n // JSON parse error\n return null\n }\n}\n","import leven from \"leven\"\nimport { collectPaths, PATH_SEPARATOR } from \"./tree.js\"\nimport type { VerificationNode } from \"./types.js\"\n\n/**\n * Result of resolving a filter to a valid task path\n */\nexport interface ResolvedFilter {\n /** The original filter string provided by the user */\n original: string\n /** The resolved full task path */\n resolved: string\n /** Whether this was resolved via child shortcut (e.g., \"tsc\" → \"types:tsc\") */\n wasShortcut: boolean\n}\n\n/**\n * Error thrown when a task filter doesn't match any existing task\n */\nexport class TaskNotFoundError extends Error {\n readonly exitCode = 2\n\n constructor(\n public readonly filter: string,\n public readonly suggestion: string | undefined,\n public readonly availableTasks: string[],\n ) {\n super(buildErrorMessage(filter, suggestion, availableTasks))\n this.name = \"TaskNotFoundError\"\n }\n}\n\n/**\n * Error thrown when a task filter matches multiple tasks ambiguously\n */\nexport class AmbiguousTaskError extends Error {\n readonly exitCode = 2\n\n constructor(\n public readonly filter: string,\n public readonly matches: string[],\n ) {\n super(buildAmbiguousErrorMessage(filter, matches))\n this.name = \"AmbiguousTaskError\"\n }\n}\n\n/**\n * Build error message for task not found\n */\nfunction buildErrorMessage(\n filter: string,\n suggestion: string | undefined,\n availableTasks: string[],\n): string {\n let message = `Task \"${filter}\" not found.`\n\n if (suggestion) {\n message += `\\n\\nDid you mean \"${suggestion}\"?`\n }\n\n message += \"\\n\\nAvailable tasks:\"\n for (const task of availableTasks) {\n message += `\\n ${task}`\n }\n\n return message\n}\n\n/**\n * Build error message for ambiguous task\n */\nfunction buildAmbiguousErrorMessage(filter: string, matches: string[]): string {\n let message = `Task \"${filter}\" is ambiguous.`\n message += \"\\n\\nMatches multiple tasks:\"\n for (const match of matches) {\n message += `\\n ${match}`\n }\n return message\n}\n\n/**\n * Find the single best suggestion using Levenshtein distance.\n * Returns undefined if no good match (distance > threshold).\n */\nexport function findBestSuggestion(\n availablePaths: string[],\n invalidFilter: string,\n): string | undefined {\n let bestPath: string | undefined\n let bestDistance = Number.POSITIVE_INFINITY\n\n // Threshold: distance <= 2 for short names, or <= length/3 for longer\n const threshold = Math.max(2, Math.floor(invalidFilter.length / 3))\n\n for (const path of availablePaths) {\n // Check against full path\n const distance = leven(invalidFilter, path)\n if (distance < bestDistance && distance <= threshold) {\n bestDistance = distance\n bestPath = path\n }\n\n // Also check against just the last segment (child key)\n const lastSegment = path.split(PATH_SEPARATOR).pop()\n if (lastSegment && lastSegment !== path) {\n const segmentDistance = leven(invalidFilter, lastSegment)\n if (segmentDistance < bestDistance && segmentDistance <= threshold) {\n bestDistance = segmentDistance\n bestPath = path\n }\n }\n }\n\n return bestPath\n}\n\n/**\n * Resolve a single filter to a valid task path.\n * Returns the resolved filter or throws an error.\n */\nfunction resolveFilter(\n filter: string,\n availablePaths: string[],\n): ResolvedFilter {\n // 1. Exact match - filter matches a path exactly\n if (availablePaths.includes(filter)) {\n return { original: filter, resolved: filter, wasShortcut: false }\n }\n\n // 2. Prefix match - filter is a prefix of paths (e.g., \"types\" matches \"types:tsc\")\n const prefixMatches = availablePaths.filter(\n path => path === filter || path.startsWith(`${filter}${PATH_SEPARATOR}`),\n )\n if (prefixMatches.length > 0) {\n // If the filter itself is a valid path (parent node), use it\n // The runner will handle running children\n return { original: filter, resolved: filter, wasShortcut: false }\n }\n\n // 3. Child shortcut - filter matches the last segment of path(s)\n const childMatches = availablePaths.filter(path => {\n const lastSegment = path.split(PATH_SEPARATOR).pop()\n return lastSegment === filter\n })\n\n if (childMatches.length === 1) {\n // Unambiguous child match\n return {\n original: filter,\n resolved: childMatches[0],\n wasShortcut: true,\n }\n }\n\n if (childMatches.length > 1) {\n // Ambiguous - multiple paths end with this key\n throw new AmbiguousTaskError(filter, childMatches)\n }\n\n // 4. No match - find suggestion and throw error\n const suggestion = findBestSuggestion(availablePaths, filter)\n throw new TaskNotFoundError(filter, suggestion, availablePaths)\n}\n\n/**\n * Resolve and validate all filters before running any tasks.\n * Fails fast on first invalid filter.\n *\n * @param nodes - The verification task tree\n * @param filters - User-provided filter strings\n * @returns Array of resolved filters\n * @throws TaskNotFoundError if a filter doesn't match any task\n * @throws AmbiguousTaskError if a filter matches multiple tasks\n */\nexport function resolveFilters(\n nodes: VerificationNode[],\n filters: string[],\n): ResolvedFilter[] {\n const availablePaths = collectPaths(nodes)\n const resolved: ResolvedFilter[] = []\n\n for (const filter of filters) {\n resolved.push(resolveFilter(filter, availablePaths))\n }\n\n return resolved\n}\n","import type { VerificationNode } from \"./types.js\"\n\n/**\n * Path separator used in task paths\n */\nexport const PATH_SEPARATOR = \":\"\n\n/**\n * Build a task path from parent path and key\n */\nexport function buildTaskPath(parentPath: string, key: string): string {\n return parentPath ? `${parentPath}${PATH_SEPARATOR}${key}` : key\n}\n\n/**\n * Visitor function called for each node during tree traversal\n */\nexport type NodeVisitor = (\n node: VerificationNode,\n path: string,\n depth: number,\n) => void\n\n/**\n * Walk all nodes in a verification tree in depth-first order\n *\n * @param nodes - The nodes to walk\n * @param visitor - Function called for each node with (node, path, depth)\n * @param parentPath - Parent path prefix (used for recursion)\n * @param depth - Current depth (used for recursion)\n */\nexport function walkNodes(\n nodes: VerificationNode[],\n visitor: NodeVisitor,\n parentPath = \"\",\n depth = 0,\n): void {\n for (const node of nodes) {\n const path = buildTaskPath(parentPath, node.key)\n visitor(node, path, depth)\n if (node.children) {\n walkNodes(node.children, visitor, path, depth + 1)\n }\n }\n}\n\n/**\n * Collect all task paths from a verification tree\n */\nexport function collectPaths(nodes: VerificationNode[]): string[] {\n const paths: string[] = []\n walkNodes(nodes, (_node, path) => {\n paths.push(path)\n })\n return paths\n}\n","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport { type PackageJson, parsePackageJson } from \"../schemas/package-json.js\"\n\n/**\n * A detected task candidate from package.json\n */\nexport interface DetectedTask {\n /** Suggested key for the task */\n key: string\n /** Human-readable name */\n name: string\n /** The npm script name that was detected */\n scriptName: string\n /** The command to run (optimized direct path when possible) */\n command: string\n /** Category for grouping (format, types, logic, build) */\n category: \"format\" | \"types\" | \"logic\" | \"build\" | \"other\"\n /** Parser to use for this task */\n parser?: string\n /**\n * Tasks that must pass for this task's failure to be reported.\n * Auto-populated based on category (types/logic/build depend on format).\n */\n reportingDependsOn?: string[]\n}\n\n/**\n * Tool detection patterns - maps script content to optimized commands\n */\ninterface ToolPattern {\n /** Regex to match in script content */\n pattern: RegExp\n /** Binary name in node_modules/.bin */\n binary: string\n /** Arguments to append (extracted from script or default) */\n getArgs: (match: RegExpMatchArray, scriptContent: string) => string\n /** Parser to use */\n parser?: string\n}\n\nconst TOOL_PATTERNS: ToolPattern[] = [\n // Biome\n {\n pattern: /\\bbiome\\s+(check|lint|format)/,\n binary: \"biome\",\n getArgs: (match, content) => {\n // Extract the full biome command with args\n const biomeMatch = content.match(/biome\\s+([^&|;]+)/)\n return biomeMatch ? biomeMatch[1].trim() : \"check .\"\n },\n parser: \"biome\",\n },\n // ESLint\n {\n pattern: /\\beslint\\b/,\n binary: \"eslint\",\n getArgs: (_, content) => {\n const eslintMatch = content.match(/eslint\\s+([^&|;]+)/)\n return eslintMatch ? eslintMatch[1].trim() : \".\"\n },\n },\n // Prettier\n {\n pattern: /\\bprettier\\b/,\n binary: \"prettier\",\n getArgs: (_, content) => {\n const prettierMatch = content.match(/prettier\\s+([^&|;]+)/)\n return prettierMatch ? prettierMatch[1].trim() : \"--check .\"\n },\n },\n // TypeScript\n {\n pattern: /\\btsc\\b/,\n binary: \"tsc\",\n getArgs: (_, content) => {\n const tscMatch = content.match(/tsc\\s+([^&|;]+)/)\n return tscMatch ? tscMatch[1].trim() : \"--noEmit\"\n },\n parser: \"tsc\",\n },\n // tsgo\n {\n pattern: /\\btsgo\\b/,\n binary: \"tsgo\",\n getArgs: (_, content) => {\n const tsgoMatch = content.match(/tsgo\\s+([^&|;]+)/)\n return tsgoMatch ? tsgoMatch[1].trim() : \"--noEmit\"\n },\n parser: \"tsc\",\n },\n // Vitest\n {\n pattern: /\\bvitest\\b/,\n binary: \"vitest\",\n getArgs: (_, content) => {\n // Check if it's watch mode or run mode\n if (content.includes(\"vitest run\")) return \"run\"\n if (content.includes(\"vitest watch\")) return \"run\" // Convert watch to run for verify\n return \"run\"\n },\n parser: \"vitest\",\n },\n // Jest\n {\n pattern: /\\bjest\\b/,\n binary: \"jest\",\n getArgs: () => \"\",\n },\n // Mocha\n {\n pattern: /\\bmocha\\b/,\n binary: \"mocha\",\n getArgs: () => \"\",\n },\n // tsup\n {\n pattern: /\\btsup\\b/,\n binary: \"tsup\",\n getArgs: (_, content) => {\n const tsupMatch = content.match(/tsup\\s+([^&|;]+)/)\n return tsupMatch ? tsupMatch[1].trim() : \"\"\n },\n },\n // esbuild\n {\n pattern: /\\besbuild\\b/,\n binary: \"esbuild\",\n getArgs: (_, content) => {\n const esbuildMatch = content.match(/esbuild\\s+([^&|;]+)/)\n return esbuildMatch ? esbuildMatch[1].trim() : \"\"\n },\n },\n]\n\n/**\n * Patterns to detect verification-related scripts by name\n */\nconst SCRIPT_NAME_PATTERNS: Array<{\n pattern: RegExp\n key: string\n name: string\n category: DetectedTask[\"category\"]\n}> = [\n // Format/Lint patterns\n {\n pattern: /^(lint|eslint|biome|prettier|format)$/i,\n key: \"format\",\n name: \"Format & Lint\",\n category: \"format\",\n },\n {\n pattern: /^(lint:fix|format:fix|fix)$/i,\n key: \"format\",\n name: \"Format & Lint\",\n category: \"format\",\n },\n {\n pattern: /^verify:format$/i,\n key: \"format\",\n name: \"Format\",\n category: \"format\",\n },\n\n // Type checking patterns\n {\n pattern: /^(typecheck|type-check|tsc|types|check-types)$/i,\n key: \"types\",\n name: \"Type Check\",\n category: \"types\",\n },\n {\n pattern: /^verify:types$/i,\n key: \"types\",\n name: \"Types\",\n category: \"types\",\n },\n\n // Test patterns\n {\n pattern: /^(test|tests|vitest|jest|mocha|ava)$/i,\n key: \"test\",\n name: \"Tests\",\n category: \"logic\",\n },\n {\n pattern: /^test:(unit|integration|e2e)$/i,\n key: \"test\",\n name: \"Tests\",\n category: \"logic\",\n },\n {\n pattern: /^verify:logic$/i,\n key: \"logic\",\n name: \"Logic Tests\",\n category: \"logic\",\n },\n\n // Build patterns\n {\n pattern: /^(build|compile)$/i,\n key: \"build\",\n name: \"Build\",\n category: \"build\",\n },\n]\n\n/**\n * Read and parse package.json from a directory\n */\nfunction readPackageJson(cwd: string): PackageJson | null {\n const packageJsonPath = join(cwd, \"package.json\")\n\n if (!existsSync(packageJsonPath)) {\n return null\n }\n\n try {\n const content = readFileSync(packageJsonPath, \"utf-8\")\n return parsePackageJson(content)\n } catch {\n return null\n }\n}\n\n/**\n * Check if a binary exists in node_modules/.bin\n */\nfunction binaryExists(cwd: string, binary: string): boolean {\n return existsSync(join(cwd, \"node_modules\", \".bin\", binary))\n}\n\n/**\n * Try to extract an optimized direct command from script content\n */\nfunction extractOptimizedCommand(\n cwd: string,\n scriptContent: string,\n): { command: string; parser?: string } | null {\n for (const tool of TOOL_PATTERNS) {\n const match = scriptContent.match(tool.pattern)\n if (match && binaryExists(cwd, tool.binary)) {\n const args = tool.getArgs(match, scriptContent)\n const command = args\n ? `./node_modules/.bin/${tool.binary} ${args}`\n : `./node_modules/.bin/${tool.binary}`\n return { command, parser: tool.parser }\n }\n }\n return null\n}\n\n/**\n * Detect verification tasks from package.json scripts\n */\nexport function detectFromPackageJson(cwd: string): DetectedTask[] {\n const pkg = readPackageJson(cwd)\n\n if (!pkg?.scripts) {\n return []\n }\n\n const detected: DetectedTask[] = []\n const seenKeys = new Set<string>()\n\n for (const [scriptName, scriptContent] of Object.entries(pkg.scripts)) {\n // Skip scripts that are just running other scripts (like \"verify\": \"run-s ...\")\n if (\n scriptContent.includes(\"run-s\") ||\n scriptContent.includes(\"run-p\") ||\n scriptContent.includes(\"npm-run-all\")\n ) {\n continue\n }\n\n // Check against detection patterns\n for (const { pattern, key, name, category } of SCRIPT_NAME_PATTERNS) {\n if (pattern.test(scriptName)) {\n // Avoid duplicates for the same key\n const uniqueKey = seenKeys.has(key) ? `${key}-${scriptName}` : key\n if (!seenKeys.has(uniqueKey)) {\n seenKeys.add(uniqueKey)\n\n // Try to extract optimized command\n const optimized = extractOptimizedCommand(cwd, scriptContent)\n\n detected.push({\n key: uniqueKey,\n name,\n scriptName,\n command: optimized?.command ?? `npm run ${scriptName}`,\n category,\n parser: optimized?.parser,\n })\n }\n break\n }\n }\n }\n\n // Sort by category priority: format -> types -> logic -> build -> other\n const categoryOrder: Record<DetectedTask[\"category\"], number> = {\n format: 0,\n types: 1,\n logic: 2,\n build: 3,\n other: 4,\n }\n\n detected.sort((a, b) => categoryOrder[a.category] - categoryOrder[b.category])\n\n // Add reportingDependsOn for non-format tasks if a format task exists\n // This reduces noise when a syntax error causes multiple tools to fail\n const hasFormatTask = detected.some(t => t.category === \"format\")\n if (hasFormatTask) {\n for (const task of detected) {\n if (task.category !== \"format\" && task.category !== \"other\") {\n task.reportingDependsOn = [\"format\"]\n }\n }\n }\n\n return detected\n}\n\n/**\n * Detect the package manager being used\n */\nexport function detectPackageManager(cwd: string): \"npm\" | \"pnpm\" | \"yarn\" {\n if (existsSync(join(cwd, \"pnpm-lock.yaml\"))) {\n return \"pnpm\"\n }\n if (existsSync(join(cwd, \"yarn.lock\"))) {\n return \"yarn\"\n }\n return \"npm\"\n}\n\n/**\n * Get the run command for a package manager\n */\nexport function getRunCommand(\n packageManager: \"npm\" | \"pnpm\" | \"yarn\",\n scriptName: string,\n): string {\n switch (packageManager) {\n case \"pnpm\":\n return `pnpm ${scriptName}`\n case \"yarn\":\n return `yarn ${scriptName}`\n default:\n return `npm run ${scriptName}`\n }\n}\n\n/**\n * Detect tasks with proper package manager commands\n * Uses optimized direct paths when possible, falls back to package manager\n */\nexport function detectTasks(cwd: string): DetectedTask[] {\n const packageManager = detectPackageManager(cwd)\n const tasks = detectFromPackageJson(cwd)\n\n // For tasks without optimized commands, use package manager\n return tasks.map(task => {\n // If command is already optimized (starts with ./), keep it\n if (task.command.startsWith(\"./\")) {\n return task\n }\n // Otherwise use package manager command\n return {\n ...task,\n command: getRunCommand(packageManager, task.scriptName),\n }\n })\n}\n","import type { DetectedTask } from \"./detect.js\"\n\n/**\n * Output format for the generated config\n */\nexport type OutputFormat = \"ts\" | \"mts\" | \"js\" | \"mjs\"\n\n/**\n * Determine output format from file path\n */\nexport function getOutputFormat(filePath: string): OutputFormat {\n if (filePath.endsWith(\".mts\")) return \"mts\"\n if (filePath.endsWith(\".mjs\")) return \"mjs\"\n if (filePath.endsWith(\".js\")) return \"js\"\n return \"ts\" // Default to TypeScript\n}\n\n/**\n * Generate the import statement based on format\n */\nfunction generateImport(format: OutputFormat): string {\n // All formats use ESM import syntax\n return `import { defineConfig } from \"@halecraft/verify\"`\n}\n\n/**\n * Generate a task object as a string\n */\nfunction generateTask(task: DetectedTask, indent: string): string {\n const parts = [`key: \"${task.key}\"`, `run: \"${task.command}\"`]\n if (task.parser) {\n parts.push(`parser: \"${task.parser}\"`)\n }\n if (task.reportingDependsOn && task.reportingDependsOn.length > 0) {\n const deps = task.reportingDependsOn.map(d => `\"${d}\"`).join(\", \")\n parts.push(`reportingDependsOn: [${deps}]`)\n }\n return `${indent}{ ${parts.join(\", \")} }`\n}\n\n/**\n * Generate the skeleton config when no tasks are detected\n */\nfunction generateSkeleton(format: OutputFormat): string {\n const importStatement = generateImport(format)\n\n return `${importStatement}\n\nexport default defineConfig({\n tasks: [\n // Add your verification tasks here\n // Example:\n // { key: \"format\", run: \"pnpm lint\" },\n // { key: \"types\", run: \"pnpm typecheck\" },\n // { key: \"test\", run: \"pnpm test\" },\n ],\n})\n`\n}\n\n/**\n * Generate config content from selected tasks\n */\nexport function generateConfigContent(\n tasks: DetectedTask[],\n format: OutputFormat,\n): string {\n // If no tasks, generate skeleton\n if (tasks.length === 0) {\n return generateSkeleton(format)\n }\n\n const importStatement = generateImport(format)\n const indent = \" \"\n\n // Group tasks by category for better organization\n const taskLines = tasks.map(task => generateTask(task, indent))\n\n return `${importStatement}\n\nexport default defineConfig({\n tasks: [\n${taskLines.join(\",\\n\")},\n ],\n})\n`\n}\n\n/**\n * Get the default config filename\n */\nexport function getDefaultConfigPath(): string {\n return \"verify.config.ts\"\n}\n","import type { DetectedTask } from \"./detect.js\"\n\n/**\n * Options for the prompt flow\n */\nexport interface PromptOptions {\n /** Skip interactive prompts and auto-accept all */\n yes: boolean\n /** Whether we're in a TTY environment */\n isTTY: boolean\n}\n\n/**\n * Result of the prompt flow\n */\nexport interface PromptResult {\n /** Selected tasks */\n tasks: DetectedTask[]\n /** Whether the user cancelled */\n cancelled: boolean\n}\n\n/**\n * Check if we should skip prompts\n */\nexport function shouldSkipPrompts(options: PromptOptions): boolean {\n return options.yes || !options.isTTY\n}\n\n/**\n * Run the interactive task selection prompt\n */\nexport async function promptForTasks(\n detectedTasks: DetectedTask[],\n options: PromptOptions,\n): Promise<PromptResult> {\n // If no tasks detected, return empty (will use skeleton)\n if (detectedTasks.length === 0) {\n if (!shouldSkipPrompts(options)) {\n console.log(\n \"\\n⚠️ No verification scripts detected in package.json.\\n A skeleton config will be created.\\n\",\n )\n }\n return { tasks: [], cancelled: false }\n }\n\n // If skipping prompts, return all detected tasks\n if (shouldSkipPrompts(options)) {\n console.log(`\\n✓ Auto-selecting ${detectedTasks.length} detected task(s)\\n`)\n return { tasks: detectedTasks, cancelled: false }\n }\n\n // Dynamic import of @inquirer/prompts to avoid loading it when not needed\n try {\n const { checkbox } = await import(\"@inquirer/prompts\")\n\n console.log(\"\\n🔍 Detected verification scripts in package.json:\\n\")\n\n const choices = detectedTasks.map(task => ({\n name: `${task.name} (${task.command})`,\n value: task,\n checked: true, // Pre-select all by default\n }))\n\n const selected = await checkbox<DetectedTask>({\n message: \"Select tasks to include in your config:\",\n choices,\n instructions: false,\n })\n\n if (selected.length === 0) {\n console.log(\n \"\\n⚠️ No tasks selected. A skeleton config will be created.\\n\",\n )\n }\n\n return { tasks: selected, cancelled: false }\n } catch (error) {\n // Handle Ctrl+C or other cancellation\n if (\n error instanceof Error &&\n (error.message.includes(\"User force closed\") ||\n error.name === \"ExitPromptError\")\n ) {\n return { tasks: [], cancelled: true }\n }\n throw error\n }\n}\n","import { existsSync, writeFileSync } from \"node:fs\"\nimport { resolve } from \"node:path\"\nimport type { DetectedTask } from \"./detect.js\"\n\n/**\n * Result of checking if a file exists\n */\nexport interface FileCheckResult {\n exists: boolean\n path: string\n}\n\n/**\n * Check if the config file already exists\n */\nexport function checkConfigExists(\n cwd: string,\n configPath: string,\n): FileCheckResult {\n const absolutePath = resolve(cwd, configPath)\n return {\n exists: existsSync(absolutePath),\n path: absolutePath,\n }\n}\n\n/**\n * Write the config file\n */\nexport function writeConfigFile(\n cwd: string,\n configPath: string,\n content: string,\n): void {\n const absolutePath = resolve(cwd, configPath)\n writeFileSync(absolutePath, content, \"utf-8\")\n}\n\n/**\n * Print warning about existing file\n */\nexport function printExistsWarning(path: string): void {\n console.error(`\\n⚠️ Config file already exists: ${path}`)\n console.error(\" Use --force to overwrite.\\n\")\n}\n\n/**\n * Options for success message\n */\nexport interface SuccessOptions {\n /** Path to the created config file */\n configPath: string\n /** Tasks that were configured */\n tasks: DetectedTask[]\n /** Whether optimized commands were used */\n hasOptimizedCommands: boolean\n /** Script names that can potentially be removed */\n removableScripts: string[]\n}\n\n/**\n * Print success message with educational notes\n */\nexport function printSuccess(options: SuccessOptions): void {\n const { configPath, tasks, hasOptimizedCommands, removableScripts } = options\n\n console.log(`\\n✅ Created ${configPath}`)\n console.log(\"\")\n\n // Quick start\n console.log(\" Quick start:\")\n console.log(\" $ verify # Run all verifications\")\n console.log(\" $ verify --top-level # Show only top-level tasks\")\n console.log(\" $ verify format # Run only 'format' task\")\n console.log(\"\")\n\n // Performance note if optimized commands were used\n if (hasOptimizedCommands) {\n console.log(\n \" ⚡ Performance: Using direct tool paths for faster execution\",\n )\n console.log(\n \" (avoids ~250ms overhead per command from package manager)\",\n )\n console.log(\"\")\n }\n\n // Cleanup suggestion if there are removable scripts\n if (removableScripts.length > 0) {\n console.log(\" 💡 Optional cleanup:\")\n console.log(\n \" You can remove these scripts from package.json if you only\",\n )\n console.log(\" run them via 'verify' (keeps package.json cleaner):\")\n for (const script of removableScripts) {\n console.log(` - \"${script}\"`)\n }\n console.log(\"\")\n }\n\n // Parser note if parsers were detected\n const tasksWithParsers = tasks.filter(t => t.parser)\n if (tasksWithParsers.length > 0) {\n console.log(\" 📊 Rich output: Parsers detected for detailed summaries:\")\n for (const task of tasksWithParsers) {\n console.log(` - ${task.key}: ${task.parser}`)\n }\n console.log(\"\")\n }\n\n console.log(\" 📖 Docs: https://github.com/halecraft/verify\")\n console.log(\"\")\n}\n","import { detectTasks } from \"./detect.js\"\nimport {\n generateConfigContent,\n getDefaultConfigPath,\n getOutputFormat,\n} from \"./generate.js\"\nimport { promptForTasks, shouldSkipPrompts } from \"./prompts.js\"\nimport {\n checkConfigExists,\n printExistsWarning,\n printSuccess,\n writeConfigFile,\n} from \"./write.js\"\n\n/**\n * Options for the init command\n */\nexport interface InitOptions {\n /** Custom config output path */\n config?: string\n /** Force overwrite existing file */\n force: boolean\n /** Skip interactive prompts */\n yes: boolean\n /** Working directory */\n cwd: string\n}\n\n/**\n * Result of the init command\n */\nexport interface InitResult {\n /** Whether init succeeded */\n success: boolean\n /** Path to the created config file (if successful) */\n configPath?: string\n /** Error message (if failed) */\n error?: string\n}\n\n/**\n * Run the init command\n */\nexport async function runInit(options: InitOptions): Promise<InitResult> {\n const configPath = options.config ?? getDefaultConfigPath()\n const format = getOutputFormat(configPath)\n\n // Check if file already exists\n const fileCheck = checkConfigExists(options.cwd, configPath)\n if (fileCheck.exists && !options.force) {\n printExistsWarning(fileCheck.path)\n return {\n success: false,\n error: \"Config file already exists. Use --force to overwrite.\",\n }\n }\n\n // Detect tasks from package.json\n const detectedTasks = detectTasks(options.cwd)\n\n // Determine if we should skip prompts\n const isTTY = process.stdout.isTTY ?? false\n const promptOptions = {\n yes: options.yes,\n isTTY,\n }\n\n // If not skipping prompts, show what we're doing\n if (!shouldSkipPrompts(promptOptions)) {\n console.log(\"\\n🚀 Initializing @halecraft/verify config...\\n\")\n }\n\n // Run interactive prompts (or auto-select)\n const promptResult = await promptForTasks(detectedTasks, promptOptions)\n\n if (promptResult.cancelled) {\n console.log(\"\\n❌ Cancelled.\\n\")\n return {\n success: false,\n error: \"User cancelled\",\n }\n }\n\n // Generate config content\n const content = generateConfigContent(promptResult.tasks, format)\n\n // Determine if optimized commands were used\n const hasOptimizedCommands = promptResult.tasks.some(t =>\n t.command.startsWith(\"./node_modules/.bin/\"),\n )\n\n // Determine which scripts could be removed (those that were detected and optimized)\n const removableScripts = promptResult.tasks\n .filter(t => t.command.startsWith(\"./node_modules/.bin/\"))\n .map(t => t.scriptName)\n\n // Write the file\n try {\n writeConfigFile(options.cwd, configPath, content)\n printSuccess({\n configPath,\n tasks: promptResult.tasks,\n hasOptimizedCommands,\n removableScripts,\n })\n return {\n success: true,\n configPath,\n }\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Failed to write config file\"\n console.error(`\\n❌ Error: ${message}\\n`)\n return {\n success: false,\n error: message,\n }\n }\n}\n\n// Re-export types and utilities\nexport type { DetectedTask } from \"./detect.js\"\nexport { detectTasks } from \"./detect.js\"\nexport type { OutputFormat } from \"./generate.js\"\nexport { generateConfigContent, getOutputFormat } from \"./generate.js\"\n","import type { OutputParser, ParsedResult } from \"../types.js\"\n\n/**\n * Parser for Biome linter/formatter output\n * Extracts issue counts and file counts from biome check output\n */\nexport const biomeParser: OutputParser = {\n id: \"biome\",\n parse(output: string, exitCode: number): ParsedResult | null {\n // Extract file count from \"Checked N files in Xms\"\n const filesMatch = output.match(\n /Checked\\s+(\\d+)\\s+files?\\s+in\\s+[\\d.]+(?:ms|s)/i,\n )\n const fileCount = filesMatch\n ? Number.parseInt(filesMatch[1], 10)\n : undefined\n\n // Check for warnings in output like \"Found 1 warning.\"\n const warningMatch = output.match(/Found\\s+(\\d+)\\s+warning/i)\n const warnings = warningMatch ? Number.parseInt(warningMatch[1], 10) : 0\n\n if (exitCode === 0) {\n const filesPart = fileCount ? `passed ${fileCount} files` : \"passed\"\n const warningSuffix =\n warnings > 0 ? `, ${warnings} warning${warnings === 1 ? \"\" : \"s\"}` : \"\"\n return {\n summary: `${filesPart}${warningSuffix}`,\n metrics: { errors: 0, warnings, total: fileCount },\n }\n }\n\n // Biome outputs something like \"Found 5 errors and 2 warnings\"\n // or individual diagnostics\n const summaryMatch = output.match(\n /Found\\s+(\\d+)\\s+error(?:s)?(?:\\s+and\\s+(\\d+)\\s+warning(?:s)?)?/i,\n )\n\n if (summaryMatch) {\n const errors = Number.parseInt(summaryMatch[1], 10)\n const parsedWarnings = summaryMatch[2]\n ? Number.parseInt(summaryMatch[2], 10)\n : warnings\n\n const fileSuffix = fileCount ? ` in ${fileCount} files` : \"\"\n return {\n summary: `${errors} error${errors === 1 ? \"\" : \"s\"}${parsedWarnings > 0 ? `, ${parsedWarnings} warning${parsedWarnings === 1 ? \"\" : \"s\"}` : \"\"}${fileSuffix}`,\n metrics: { errors, warnings: parsedWarnings, total: fileCount },\n }\n }\n\n // Count individual error markers if no summary found\n // Biome uses \"error\" prefix for diagnostics\n const errorLines = output.match(/^\\s*error\\[/gm)\n const warningLines = output.match(/^\\s*warning\\[/gm)\n\n const errors = errorLines ? errorLines.length : 0\n const countedWarnings = warningLines ? warningLines.length : warnings\n\n if (errors > 0 || countedWarnings > 0) {\n const fileSuffix = fileCount ? ` in ${fileCount} files` : \"\"\n return {\n summary: `${errors} error${errors === 1 ? \"\" : \"s\"}${countedWarnings > 0 ? `, ${countedWarnings} warning${countedWarnings === 1 ? \"\" : \"s\"}` : \"\"}${fileSuffix}`,\n metrics: { errors, warnings: countedWarnings, total: fileCount },\n }\n }\n\n // No errors found but still have file count\n if (fileCount) {\n return {\n summary: `passed ${fileCount} files`,\n metrics: { errors: 0, warnings: 0, total: fileCount },\n }\n }\n\n return null\n },\n}\n","import type { ParsedResult } from \"../types.js\"\n\n/**\n * Generic fallback parser - just reports exit code\n * This parser always returns a result (never null)\n */\nexport const genericParser = {\n id: \"generic\",\n parse(_output: string, exitCode: number): ParsedResult {\n return {\n summary: exitCode === 0 ? \"passed\" : `failed (exit code ${exitCode})`,\n }\n },\n} as const\n","import type { OutputParser, ParsedResult } from \"../types.js\"\n\n/**\n * Parser for Go test output\n * Counts packages passed/failed from go test output\n */\nexport const gotestParser: OutputParser = {\n id: \"gotest\",\n parse(output: string, exitCode: number): ParsedResult | null {\n // Match \"ok\" and \"FAIL\" lines for packages\n // ok github.com/user/pkg 0.123s\n // FAIL github.com/user/pkg 0.456s\n const okMatches = output.match(/^ok\\s+\\S+/gm)\n const failMatches = output.match(/^FAIL\\s+\\S+/gm)\n\n const passed = okMatches ? okMatches.length : 0\n const failed = failMatches ? failMatches.length : 0\n const total = passed + failed\n\n if (total === 0) {\n // Try to detect \"no test files\" case\n if (output.includes(\"no test files\")) {\n return {\n summary: \"no test files\",\n metrics: { passed: 0, failed: 0, total: 0 },\n }\n }\n return null\n }\n\n // Extract total duration if present\n // \"PASS\" or \"FAIL\" at the end with duration\n const durationMatch = output.match(/(?:PASS|FAIL)\\s*$[\\s\\S]*?(\\d+\\.?\\d*s)/m)\n const duration = durationMatch ? durationMatch[1] : undefined\n\n if (exitCode === 0) {\n return {\n summary: `${passed} package${passed === 1 ? \"\" : \"s\"} passed${duration ? ` in ${duration}` : \"\"}`,\n metrics: { passed, failed: 0, total: passed, duration },\n }\n }\n\n return {\n summary: `${failed}/${total} package${total === 1 ? \"\" : \"s\"} failed`,\n metrics: { passed, failed, total, duration },\n }\n },\n}\n","import type { OutputParser, ParsedResult } from \"../types.js\"\n\n/**\n * Parser for TypeScript compiler (tsc/tsgo) output\n * Counts type errors and extracts diagnostics info\n */\nexport const tscParser: OutputParser = {\n id: \"tsc\",\n parse(output: string, exitCode: number): ParsedResult | null {\n // Extract file count from diagnostics output: \"Files: 277\"\n const filesMatch = output.match(/^Files:\\s+(\\d+)/m)\n const fileCount = filesMatch\n ? Number.parseInt(filesMatch[1], 10)\n : undefined\n\n if (exitCode === 0) {\n const filesPart = fileCount ? `passed ${fileCount} files` : \"passed\"\n return {\n summary: filesPart,\n metrics: { errors: 0, total: fileCount },\n }\n }\n\n // Count error lines: \"src/file.ts(10,5): error TS2345: ...\"\n const errorMatches = output.match(/error TS\\d+:/g)\n const errorCount = errorMatches ? errorMatches.length : 0\n\n if (errorCount === 0) {\n // No recognizable errors but still failed\n return null\n }\n\n const fileSuffix = fileCount ? ` in ${fileCount} files` : \"\"\n return {\n summary: `${errorCount} type error${errorCount === 1 ? \"\" : \"s\"}${fileSuffix}`,\n metrics: { errors: errorCount, total: fileCount },\n }\n },\n}\n","import type { OutputParser, ParsedResult } from \"../types.js\"\n\n/**\n * Strip ANSI escape codes from string\n */\nfunction stripAnsi(str: string): string {\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape codes use control characters\n return str.replace(/\\x1b\\[[0-9;]*m/g, \"\")\n}\n\n/**\n * Parser for vitest output\n * Extracts test counts from vitest summary\n */\nexport const vitestParser: OutputParser = {\n id: \"vitest\",\n parse(output: string, exitCode: number): ParsedResult | null {\n // Strip ANSI codes for reliable parsing\n const cleanOutput = stripAnsi(output)\n\n // Match: \"Tests 26 passed (26)\" with flexible whitespace\n // Vitest v4 format: \" Tests 26 passed (26)\"\n const testsMatch = cleanOutput.match(/Tests\\s+(\\d+)\\s+passed\\s*\\((\\d+)\\)/m)\n\n // Match: \"Duration 192ms\" or \"Duration 1.72s\"\n const durationMatch = cleanOutput.match(/Duration\\s+([\\d.]+(?:ms|s))\\b/m)\n\n if (!testsMatch) {\n return null\n }\n\n const passed = Number.parseInt(testsMatch[1], 10)\n const total = Number.parseInt(testsMatch[2], 10)\n const duration = durationMatch ? durationMatch[1] : undefined\n\n // Don't include duration in summary - the reporter adds wall-clock time\n return {\n summary:\n exitCode === 0\n ? `passed ${passed}/${total} tests`\n : `passed ${passed}/${total} tests (some failed)`,\n metrics: {\n passed,\n total,\n failed: total - passed,\n duration,\n },\n }\n },\n}\n","import type { OutputParser, ParsedResult } from \"../types.js\"\nimport { biomeParser } from \"./biome.js\"\nimport { genericParser } from \"./generic.js\"\nimport { gotestParser } from \"./gotest.js\"\nimport { tscParser } from \"./tsc.js\"\nimport { vitestParser } from \"./vitest.js\"\n\n/**\n * Parser ID constants for type-safe parser references.\n * Use these instead of magic strings when specifying parsers in config.\n *\n * @example\n * ```typescript\n * import { parsers } from \"@halecraft/verify\"\n *\n * export default defineConfig({\n * tasks: [\n * { key: \"test\", run: \"vitest run\", parser: parsers.vitest },\n * ],\n * })\n * ```\n */\nexport const parsers = {\n /** Vitest/Jest test runner output parser */\n vitest: \"vitest\",\n /** TypeScript compiler (tsc/tsgo) output parser */\n tsc: \"tsc\",\n /** Biome/ESLint linter output parser */\n biome: \"biome\",\n /** Go test runner output parser */\n gotest: \"gotest\",\n /** Generic fallback parser */\n generic: \"generic\",\n} as const\n\n/** Type for valid parser IDs */\nexport type ParserId = (typeof parsers)[keyof typeof parsers]\n\n/**\n * Registry for output parsers\n */\nexport class ParserRegistry {\n private parsers = new Map<string, OutputParser>()\n\n constructor() {\n // Register built-in parsers\n this.register(genericParser)\n this.register(vitestParser)\n this.register(tscParser)\n this.register(biomeParser)\n this.register(gotestParser)\n }\n\n /**\n * Register a custom parser\n */\n register(parser: OutputParser): void {\n this.parsers.set(parser.id, parser)\n }\n\n /**\n * Get a parser by ID\n */\n get(id: string): OutputParser | undefined {\n return this.parsers.get(id)\n }\n\n /**\n * Auto-detect parser based on command\n */\n detectParser(cmd: string): ParserId {\n const cmdLower = cmd.toLowerCase()\n\n if (cmdLower.includes(\"vitest\") || cmdLower.includes(\"jest\")) {\n return parsers.vitest\n }\n if (cmdLower.includes(\"tsc\") || cmdLower.includes(\"tsgo\")) {\n return parsers.tsc\n }\n if (cmdLower.includes(\"biome\") || cmdLower.includes(\"eslint\")) {\n return parsers.biome\n }\n if (\n cmdLower.includes(\"go test\") ||\n (cmdLower.includes(\"go\") && cmdLower.includes(\"test\"))\n ) {\n return parsers.gotest\n }\n\n return parsers.generic\n }\n\n /**\n * Parse output using the specified or auto-detected parser\n */\n parse(\n output: string,\n exitCode: number,\n parserId?: string,\n cmd?: string,\n ): ParsedResult {\n const id = parserId ?? (cmd ? this.detectParser(cmd) : parsers.generic)\n const parser = this.parsers.get(id) ?? genericParser\n\n const result = parser.parse(output, exitCode)\n if (result) {\n return result\n }\n\n // Fallback to generic if parser returns null\n // genericParser.parse always returns a result, never null\n const fallback = genericParser.parse(output, exitCode)\n if (!fallback) {\n throw new Error(\"genericParser unexpectedly returned null\")\n }\n return fallback\n }\n}\n\n// Default registry instance\nexport const defaultRegistry = new ParserRegistry()\n\n// Re-export individual parsers\nexport { biomeParser } from \"./biome.js\"\nexport { genericParser } from \"./generic.js\"\nexport { gotestParser } from \"./gotest.js\"\nexport { tscParser } from \"./tsc.js\"\nexport { vitestParser } from \"./vitest.js\"\n","/**\n * Arc spinner frames for terminal animation\n */\nconst SPINNER_FRAMES = [\"◜\", \"◠\", \"◝\", \"◞\", \"◡\", \"◟\"]\n\n/**\n * Spinner animation interval in milliseconds\n */\nconst SPINNER_INTERVAL = 80\n\n/**\n * Manages spinner animation for terminal output\n */\nexport class SpinnerManager {\n private frames = SPINNER_FRAMES\n private frameIndex = 0\n private interval: ReturnType<typeof setInterval> | null = null\n\n /**\n * Start the spinner animation\n * @param onTick - Callback called on each frame update\n */\n start(onTick: () => void): void {\n if (this.interval) return\n\n this.interval = setInterval(() => {\n this.frameIndex = (this.frameIndex + 1) % this.frames.length\n onTick()\n }, SPINNER_INTERVAL)\n }\n\n /**\n * Stop the spinner animation\n */\n stop(): void {\n if (this.interval) {\n clearInterval(this.interval)\n this.interval = null\n }\n }\n\n /**\n * Get the current spinner frame character\n */\n getFrame(): string {\n return this.frames[this.frameIndex]\n }\n\n /**\n * Check if spinner is currently running\n */\n isRunning(): boolean {\n return this.interval !== null\n }\n}\n","import { SpinnerManager } from \"./spinner.js\"\nimport { walkNodes } from \"./tree.js\"\nimport type {\n TaskResult,\n VerificationNode,\n VerifyOptions,\n VerifyResult,\n} from \"./types.js\"\n\n/**\n * ANSI color codes\n */\nconst ansi = {\n reset: \"\\u001b[0m\",\n dim: \"\\u001b[2m\",\n red: \"\\u001b[31m\",\n green: \"\\u001b[32m\",\n yellow: \"\\u001b[33m\",\n cyan: \"\\u001b[36m\",\n bold: \"\\u001b[1m\",\n}\n\n/**\n * ANSI cursor control codes\n */\nconst cursor = {\n hide: \"\\u001b[?25l\",\n show: \"\\u001b[?25h\",\n moveUp: (n: number) => `\\u001b[${n}A`,\n moveToStart: \"\\u001b[0G\",\n clearLine: \"\\u001b[2K\",\n}\n\n/**\n * Reporter interface\n */\nexport interface Reporter {\n /** Called before any tasks start - initialize display */\n onStart?(tasks: VerificationNode[]): void\n /** Called when a task starts */\n onTaskStart(path: string, key: string): void\n /** Called when a task completes */\n onTaskComplete(result: TaskResult): void\n /** Called when all tasks complete - cleanup display */\n onFinish?(): void\n /** Called to output task logs */\n outputLogs(results: TaskResult[], logsMode: \"all\" | \"failed\" | \"none\"): void\n /** Called to output final summary */\n outputSummary(result: VerifyResult): void\n}\n\n/**\n * Check if colors should be enabled\n */\nfunction shouldUseColors(options: VerifyOptions): boolean {\n if (options.noColor) return false\n if (options.format === \"json\") return false\n if (!process.stdout.isTTY) return false\n if (\"NO_COLOR\" in process.env) return false\n if (process.env.TERM === \"dumb\") return false\n return true\n}\n\n/**\n * Base Reporter - common functionality for all reporters\n */\nexport abstract class BaseReporter implements Reporter {\n protected colorEnabled: boolean\n protected stream: NodeJS.WriteStream\n protected taskDepths: Map<string, number> = new Map()\n\n constructor(options: VerifyOptions = {}) {\n this.colorEnabled = shouldUseColors(options)\n this.stream = options.format === \"json\" ? process.stderr : process.stdout\n }\n\n /**\n * Apply ANSI color code to string (if colors enabled)\n */\n protected c(code: string, s: string): string {\n return this.colorEnabled ? `${code}${s}${ansi.reset}` : s\n }\n\n /**\n * Get success mark (✓ or OK)\n */\n protected okMark(): string {\n return this.colorEnabled ? this.c(ansi.green, \"✓\") : \"OK\"\n }\n\n /**\n * Get failure mark (✗ or FAIL)\n */\n protected failMark(): string {\n return this.colorEnabled ? this.c(ansi.red, \"✗\") : \"FAIL\"\n }\n\n /**\n * Get suppressed mark (⊘ or SUPPRESSED)\n */\n protected suppressedMark(): string {\n return this.colorEnabled ? this.c(ansi.yellow, \"⊘\") : \"SUPPRESSED\"\n }\n\n /**\n * Get arrow symbol (→ or ->)\n */\n protected arrow(): string {\n return this.colorEnabled ? this.c(ansi.cyan, \"→\") : \"->\"\n }\n\n /**\n * Get indentation string for a given depth\n */\n protected getIndent(depth: number): string {\n return \" \".repeat(depth)\n }\n\n /**\n * Get task depth from path\n */\n protected getTaskDepth(path: string): number {\n return this.taskDepths.get(path) ?? 0\n }\n\n /**\n * Collect task depths from verification tree using walkNodes\n */\n protected collectTaskDepths(nodes: VerificationNode[]): void {\n walkNodes(nodes, (_node, path, depth) => {\n this.taskDepths.set(path, depth)\n })\n }\n\n /**\n * Extract summary from task result\n */\n protected extractSummary(result: TaskResult): string {\n // Use the parsed summary from summaryLine (strip the \"key: \" prefix if present)\n // The parsers already format summaries nicely with file counts, test counts, etc.\n if (result.summaryLine) {\n const colonIndex = result.summaryLine.indexOf(\": \")\n if (colonIndex !== -1) {\n return result.summaryLine.slice(colonIndex + 2)\n }\n return result.summaryLine\n }\n\n return result.ok ? \"passed\" : \"failed\"\n }\n\n /**\n * Flatten nested task results into a single array\n */\n protected flattenResults(results: TaskResult[]): TaskResult[] {\n const flat: TaskResult[] = []\n for (const r of results) {\n flat.push(r)\n if (r.children) {\n flat.push(...this.flattenResults(r.children))\n }\n }\n return flat\n }\n\n /**\n * Output task logs\n */\n outputLogs(results: TaskResult[], logsMode: \"all\" | \"failed\" | \"none\"): void {\n if (logsMode === \"none\") return\n\n const flatResults = this.flattenResults(results)\n\n for (const r of flatResults) {\n if (r.children) continue\n if (logsMode === \"failed\" && r.ok) continue\n // Skip suppressed tasks - their output is hidden to reduce noise\n if (r.suppressed) continue\n\n const status = r.ok ? this.c(ansi.green, \"OK\") : this.c(ansi.red, \"FAIL\")\n\n this.stream.write(\n `\\n${this.c(ansi.bold, \"====\")} ${this.c(ansi.bold, r.path.toUpperCase())} ${status} ${this.c(ansi.bold, \"====\")}\\n`,\n )\n this.stream.write(r.output || \"(no output)\\n\")\n }\n }\n\n /**\n * Output final summary\n */\n outputSummary(result: VerifyResult): void {\n const finalMessage = result.ok\n ? this.c(ansi.green, \"\\n== verification: All correct ==\")\n : this.c(ansi.red, \"\\n== verification: Failed ==\")\n this.stream.write(`${finalMessage}\\n`)\n }\n\n // Abstract methods that subclasses must implement\n abstract onStart(tasks: VerificationNode[]): void\n abstract onTaskStart(path: string, key: string): void\n abstract onTaskComplete(result: TaskResult): void\n abstract onFinish(): void\n}\n\n/**\n * Task state for live dashboard\n */\ninterface TaskState {\n key: string\n path: string\n depth: number\n status: \"pending\" | \"running\" | \"completed\"\n result?: TaskResult\n}\n\n/**\n * Live Dashboard Reporter - animated in-place updates for TTY\n */\nexport class LiveDashboardReporter extends BaseReporter {\n private topLevelOnly: boolean\n private tasks: Map<string, TaskState> = new Map()\n private taskOrder: string[] = []\n private spinner: SpinnerManager\n private lineCount = 0\n\n constructor(options: VerifyOptions = {}) {\n super(options)\n this.topLevelOnly = options.topLevelOnly ?? false\n this.spinner = new SpinnerManager()\n\n // Handle Ctrl+C to restore cursor\n const cleanup = () => {\n this.spinner.stop()\n this.stream.write(cursor.show)\n process.exit(130)\n }\n process.on(\"SIGINT\", cleanup)\n process.on(\"SIGTERM\", cleanup)\n }\n\n /**\n * Initialize task list from verification nodes\n */\n onStart(tasks: VerificationNode[]): void {\n this.collectTasks(tasks)\n this.stream.write(cursor.hide)\n this.spinner.start(() => this.redraw())\n }\n\n /**\n * Collect tasks from verification tree using walkNodes\n */\n private collectTasks(nodes: VerificationNode[]): void {\n walkNodes(nodes, (node, path, depth) => {\n this.tasks.set(path, {\n key: node.key,\n path,\n depth,\n status: \"pending\",\n })\n this.taskOrder.push(path)\n // Also store in base class for consistency\n this.taskDepths.set(path, depth)\n })\n }\n\n /**\n * Get display key - shows :key for nested, key for root\n */\n private getDisplayKey(task: TaskState): string {\n if (task.depth === 0) {\n return task.key\n }\n return `:${task.key}`\n }\n\n /**\n * Check if task should be displayed based on topLevelOnly flag\n */\n private shouldDisplay(task: TaskState): boolean {\n if (this.topLevelOnly) return task.depth === 0\n return true\n }\n\n /**\n * Format a single task line\n */\n private formatLine(task: TaskState): string {\n const indent = this.getIndent(task.depth)\n const displayKey = this.getDisplayKey(task)\n\n if (task.status === \"running\") {\n const spinnerChar = this.c(ansi.dim, `(${this.spinner.getFrame()})`)\n return `${indent}${this.arrow()} verifying ${this.c(ansi.bold, displayKey)} ${spinnerChar}`\n }\n\n if (task.status === \"completed\" && task.result) {\n const duration = this.c(ansi.dim, `${task.result.durationMs}ms`)\n\n // Handle suppressed tasks\n if (task.result.suppressed) {\n const reason = task.result.suppressedBy\n ? `${task.result.suppressedBy} failed`\n : \"dependency failed\"\n return `${indent}${this.suppressedMark()} suppressed ${this.c(ansi.bold, displayKey)} ${this.c(ansi.dim, `(${reason}, ${duration})`)}`\n }\n\n const summary = this.extractSummary(task.result)\n\n if (task.result.ok) {\n return `${indent}${this.okMark()} verified ${this.c(ansi.bold, displayKey)} ${this.c(ansi.dim, `(${summary}, ${duration})`)}`\n }\n return `${indent}${this.failMark()} failed ${this.c(ansi.bold, displayKey)} ${this.c(ansi.dim, `(${summary}, ${duration})`)}`\n }\n\n // Pending - don't show\n return \"\"\n }\n\n /**\n * Redraw all visible task lines\n */\n private redraw(): void {\n // Move cursor up to overwrite previous lines\n if (this.lineCount > 0) {\n this.stream.write(cursor.moveUp(this.lineCount))\n }\n\n // Build new output\n const lines: string[] = []\n for (const path of this.taskOrder) {\n const task = this.tasks.get(path)\n if (!task) continue\n if (!this.shouldDisplay(task)) continue\n if (task.status === \"pending\") continue\n\n const line = this.formatLine(task)\n if (line) {\n lines.push(line)\n }\n }\n\n // Write lines with clear\n for (const line of lines) {\n this.stream.write(`${cursor.clearLine}${cursor.moveToStart}${line}\\n`)\n }\n\n this.lineCount = lines.length\n }\n\n onTaskStart(path: string, _key: string): void {\n const task = this.tasks.get(path)\n if (task) {\n task.status = \"running\"\n }\n // Redraw happens on spinner tick\n }\n\n onTaskComplete(result: TaskResult): void {\n const task = this.tasks.get(result.path)\n if (task) {\n task.status = \"completed\"\n task.result = result\n }\n // Redraw happens on spinner tick, but do one now for immediate feedback\n this.redraw()\n }\n\n onFinish(): void {\n this.spinner.stop()\n this.redraw() // Final redraw\n this.stream.write(cursor.show)\n }\n}\n\n/**\n * Sequential Reporter - line-by-line output for non-TTY\n * No indentation since parallel execution means output order doesn't reflect hierarchy\n */\nexport class SequentialReporter extends BaseReporter {\n private topLevelOnly: boolean\n\n constructor(options: VerifyOptions = {}) {\n super(options)\n this.topLevelOnly = options.topLevelOnly ?? false\n }\n\n onStart(tasks: VerificationNode[]): void {\n // Collect task depths from the config tree\n this.collectTaskDepths(tasks)\n }\n\n /**\n * Check if task should be displayed based on topLevelOnly flag\n */\n private shouldDisplay(path: string): boolean {\n if (this.topLevelOnly) return this.getTaskDepth(path) === 0\n return true\n }\n\n onTaskStart(path: string, _key: string): void {\n if (!this.shouldDisplay(path)) return\n this.stream.write(`${this.arrow()} verifying ${this.c(ansi.bold, path)}\\n`)\n }\n\n onTaskComplete(result: TaskResult): void {\n if (!this.shouldDisplay(result.path)) return\n const duration = this.c(ansi.dim, `${result.durationMs}ms`)\n\n // Handle suppressed tasks\n if (result.suppressed) {\n const reason = result.suppressedBy\n ? `${result.suppressedBy} failed`\n : \"dependency failed\"\n this.stream.write(\n `${this.suppressedMark()} suppressed ${this.c(ansi.bold, result.path)} ${this.c(ansi.dim, `(${reason}, ${duration})`)}\\n`,\n )\n return\n }\n\n const summary = this.extractSummary(result)\n // Align output: \"⊘ suppressed\" is the longest at 12 chars\n // \"✓ verified\" = 12 chars (mark + 3 spaces + verified)\n // \"✗ failed\" = 12 chars (mark + 5 spaces + failed)\n if (result.ok) {\n this.stream.write(\n `${this.okMark()} verified ${this.c(ansi.bold, result.path)} ${this.c(ansi.dim, `(${summary}, ${duration})`)}\\n`,\n )\n } else {\n this.stream.write(\n `${this.failMark()} failed ${this.c(ansi.bold, result.path)} ${this.c(ansi.dim, `(${summary}, ${duration})`)}\\n`,\n )\n }\n }\n\n onFinish(): void {\n // No cleanup needed for sequential output\n }\n}\n\n/**\n * JSON Reporter - machine-readable output\n */\nexport class JSONReporter implements Reporter {\n onStart(_tasks: VerificationNode[]): void {\n // No output during execution in JSON mode\n }\n\n onTaskStart(_path: string, _key: string): void {\n // No output during execution in JSON mode\n }\n\n onTaskComplete(_result: TaskResult): void {\n // No output during execution in JSON mode\n }\n\n onFinish(): void {\n // No cleanup needed for JSON output\n }\n\n outputLogs(\n _results: TaskResult[],\n _logsMode: \"all\" | \"failed\" | \"none\",\n ): void {\n // Logs are included in the JSON output\n }\n\n outputSummary(result: VerifyResult): void {\n const summary = {\n ok: result.ok,\n startedAt: result.startedAt,\n finishedAt: result.finishedAt,\n durationMs: result.durationMs,\n tasks: this.serializeTasks(result.tasks),\n }\n\n process.stdout.write(`${JSON.stringify(summary)}\\n`)\n }\n\n private serializeTasks(tasks: TaskResult[]): Array<{\n key: string\n path: string\n ok: boolean\n code: number\n durationMs: number\n summaryLine: string\n suppressed?: boolean\n suppressedBy?: string\n children?: ReturnType<JSONReporter[\"serializeTasks\"]>\n }> {\n return tasks.map(t => ({\n key: t.key,\n path: t.path,\n ok: t.ok,\n code: t.code,\n durationMs: t.durationMs,\n summaryLine: t.summaryLine,\n ...(t.suppressed ? { suppressed: t.suppressed } : {}),\n ...(t.suppressedBy ? { suppressedBy: t.suppressedBy } : {}),\n ...(t.children ? { children: this.serializeTasks(t.children) } : {}),\n }))\n }\n}\n\n/**\n * Quiet Reporter - minimal output (summary only)\n */\nexport class QuietReporter extends BaseReporter {\n onStart(_tasks: VerificationNode[]): void {\n // No output\n }\n\n onTaskStart(_path: string, _key: string): void {\n // No output\n }\n\n onTaskComplete(_result: TaskResult): void {\n // No output\n }\n\n onFinish(): void {\n // No cleanup needed\n }\n\n outputLogs(\n _results: TaskResult[],\n _logsMode: \"all\" | \"failed\" | \"none\",\n ): void {\n // No logs in quiet mode\n }\n\n outputSummary(result: VerifyResult): void {\n const message = result.ok\n ? this.c(ansi.green, \"✓ All verifications passed\")\n : this.c(ansi.red, \"✗ Some verifications failed\")\n process.stdout.write(`${message}\\n`)\n }\n}\n\n/**\n * Create appropriate reporter based on options\n */\nexport function createReporter(options: VerifyOptions): Reporter {\n if (options.format === \"json\") {\n return new JSONReporter()\n }\n\n // Use LiveDashboardReporter for TTY (unless --no-tty is set)\n if (process.stdout.isTTY && !options.noTty) {\n return new LiveDashboardReporter(options)\n }\n\n return new SequentialReporter(options)\n}\n\n// Keep TTYReporter as alias for backwards compatibility\nexport { SequentialReporter as TTYReporter }\n","import { spawn } from \"node:child_process\"\nimport treeKill from \"tree-kill\"\nimport { ReportingDependencyTracker } from \"./dependency-tracker.js\"\nimport { defaultRegistry, type ParserRegistry } from \"./parsers/index.js\"\nimport { buildTaskPath } from \"./tree.js\"\nimport type {\n ParsedResult,\n TaskResult,\n VerificationCommand,\n VerificationNode,\n VerifyOptions,\n VerifyResult,\n} from \"./types.js\"\n\n// Re-export for backwards compatibility\nexport { ReportingDependencyTracker } from \"./dependency-tracker.js\"\n\n/**\n * Internal command representation that supports shell strings\n */\ninterface InternalCommand {\n /** The command/binary to run (or full shell command if shell is true) */\n cmd: string\n /** Arguments to pass to the command (empty if shell is true) */\n args: string[]\n /** Working directory (defaults to cwd) */\n cwd?: string\n /** Environment variables to set */\n env?: Record<string, string>\n /** Whether to run through shell (true for string commands) */\n shell: boolean\n /** Timeout in milliseconds */\n timeout?: number\n}\n\n/**\n * Normalize command to internal format\n * String commands use shell: true to properly handle quotes and special characters\n */\nfunction normalizeCommand(\n run: VerificationCommand | string,\n nodeTimeout?: number,\n): InternalCommand {\n if (typeof run === \"string\") {\n // Use shell to handle the command string - this properly handles quotes,\n // environment variables, pipes, and other shell features\n return {\n cmd: run,\n args: [],\n shell: true,\n timeout: nodeTimeout,\n }\n }\n\n return {\n ...run,\n shell: false,\n // Command-level timeout takes precedence over node-level timeout\n timeout: run.timeout ?? nodeTimeout,\n }\n}\n\n/**\n * Execute a single command and capture output.\n * Optionally registers the process with a tracker for early termination support.\n */\nasync function executeCommand(\n command: InternalCommand,\n cwd: string,\n tracker?: ReportingDependencyTracker,\n path?: string,\n): Promise<{\n code: number\n output: string\n durationMs: number\n killed: boolean\n timedOut: boolean\n}> {\n const start = Date.now()\n\n return new Promise(resolve => {\n // Use shell: true for string commands (to handle quotes, pipes, etc.)\n // or on Windows for all commands\n const useShell = command.shell || process.platform === \"win32\"\n\n const proc = spawn(command.cmd, command.args, {\n shell: useShell,\n cwd: command.cwd ?? cwd,\n env: { ...process.env, NO_COLOR: \"1\", ...command.env },\n })\n\n // Register process for early termination\n if (tracker && path) {\n tracker.registerProcess(path, proc)\n }\n\n let output = \"\"\n let timedOut = false\n let timeoutId: ReturnType<typeof setTimeout> | undefined\n\n // Set up timeout if configured\n if (command.timeout && proc.pid) {\n const pid = proc.pid // Capture pid to avoid non-null assertion in callback\n timeoutId = setTimeout(() => {\n timedOut = true\n // Use tree-kill to kill the process and all its children\n treeKill(pid, \"SIGTERM\", err => {\n if (err) {\n // Process may have already exited, ignore errors\n }\n })\n }, command.timeout)\n }\n\n proc.stdout.on(\"data\", (data: Buffer) => {\n output += data.toString()\n })\n\n proc.stderr.on(\"data\", (data: Buffer) => {\n output += data.toString()\n })\n\n proc.on(\"close\", (code, signal) => {\n // Clear timeout if set\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n\n // Unregister process\n if (tracker && path) {\n tracker.unregisterProcess(path)\n }\n\n const durationMs = Date.now() - start\n // Check if process was killed (SIGTERM = 15, exit code 143 = 128 + 15)\n const killed =\n signal === \"SIGTERM\" ||\n code === 143 ||\n (tracker?.wasKilled(path ?? \"\") ?? false)\n\n resolve({\n code: code ?? 1,\n output,\n durationMs,\n killed: killed && !timedOut, // Don't mark as killed if it was a timeout\n timedOut,\n })\n })\n\n proc.on(\"error\", err => {\n // Clear timeout if set\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n\n // Unregister process\n if (tracker && path) {\n tracker.unregisterProcess(path)\n }\n\n const durationMs = Date.now() - start\n resolve({\n code: 1,\n output: `Failed to execute command: ${err.message}`,\n durationMs,\n killed: false,\n timedOut: false,\n })\n })\n })\n}\n\n/**\n * Check if a path matches the filter\n */\nfunction matchesFilter(path: string, filters?: string[]): boolean {\n if (!filters || filters.length === 0) {\n return true\n }\n\n return filters.some(filter => {\n // Exact match or prefix match\n return path === filter || path.startsWith(`${filter}:`)\n })\n}\n\n/**\n * Check if any descendant matches the filter\n */\nfunction hasMatchingDescendant(\n node: VerificationNode,\n parentPath: string,\n filters?: string[],\n): boolean {\n const path = buildTaskPath(parentPath, node.key)\n\n if (matchesFilter(path, filters)) {\n return true\n }\n\n if (node.children) {\n return node.children.some(child =>\n hasMatchingDescendant(child, path, filters),\n )\n }\n\n return false\n}\n\nexport interface RunnerCallbacks {\n onTaskStart?: (path: string, key: string) => void\n onTaskComplete?: (result: TaskResult) => void\n}\n\n/**\n * Verification runner\n */\nexport class VerificationRunner {\n private registry: ParserRegistry\n private options: VerifyOptions\n private callbacks: RunnerCallbacks\n private dependencyTracker: ReportingDependencyTracker\n\n constructor(\n options: VerifyOptions = {},\n registry: ParserRegistry = defaultRegistry,\n callbacks: RunnerCallbacks = {},\n ) {\n this.options = options\n this.registry = registry\n this.callbacks = callbacks\n this.dependencyTracker = new ReportingDependencyTracker()\n }\n\n /**\n * Run all verification tasks\n */\n async run(tasks: VerificationNode[]): Promise<VerifyResult> {\n const startedAt = new Date().toISOString()\n const wallStart = Date.now()\n\n // Initialize dependency tracker with all tasks (validates cycles)\n this.dependencyTracker.initialize(tasks)\n\n const results = await this.runNodes(tasks, \"\")\n\n const finishedAt = new Date().toISOString()\n const durationMs = Date.now() - wallStart\n\n const allOk = results.every(r => r.ok)\n\n return {\n ok: allOk,\n startedAt,\n finishedAt,\n durationMs,\n tasks: results,\n }\n }\n\n /**\n * Run a list of nodes with the appropriate strategy\n */\n private async runNodes(\n nodes: VerificationNode[],\n parentPath: string,\n strategy: \"parallel\" | \"sequential\" | \"fail-fast\" = \"parallel\",\n ): Promise<TaskResult[]> {\n // Filter nodes based on filter option\n const filteredNodes = nodes.filter(node =>\n hasMatchingDescendant(node, parentPath, this.options.filter),\n )\n\n if (filteredNodes.length === 0) {\n return []\n }\n\n switch (strategy) {\n case \"parallel\":\n return Promise.all(\n filteredNodes.map(node => this.runNode(node, parentPath)),\n )\n\n case \"sequential\": {\n const results: TaskResult[] = []\n for (const node of filteredNodes) {\n results.push(await this.runNode(node, parentPath))\n }\n return results\n }\n\n case \"fail-fast\": {\n const results: TaskResult[] = []\n for (const node of filteredNodes) {\n const result = await this.runNode(node, parentPath)\n results.push(result)\n if (!result.ok) {\n break\n }\n }\n return results\n }\n }\n }\n\n /**\n * Run a single node (leaf or group)\n */\n private async runNode(\n node: VerificationNode,\n parentPath: string,\n ): Promise<TaskResult> {\n const path = buildTaskPath(parentPath, node.key)\n\n // Mark this task as active (will run) so dependencies know about it\n this.dependencyTracker.markActive(path)\n\n // Notify start\n this.callbacks.onTaskStart?.(path, node.key)\n\n // If this is a group node (has children), run children\n if (node.children && node.children.length > 0) {\n const start = Date.now()\n const childResults = await this.runNodes(\n node.children,\n path,\n node.strategy ?? \"parallel\",\n )\n const durationMs = Date.now() - start\n\n const allOk = childResults.every(r => r.ok || r.suppressed)\n\n // Propagate suppressed status from children to parent\n const allSuppressed =\n childResults.length > 0 && childResults.every(r => r.suppressed)\n const anySuppressed = childResults.some(r => r.suppressed)\n\n const result: TaskResult = {\n key: node.key,\n path,\n ok: allOk,\n code: allOk ? 0 : 1,\n durationMs,\n output: \"\",\n summaryLine: allOk\n ? (node.successLabel ?? `${node.key}: all passed`)\n : (node.failureLabel ?? `${node.key}: some failed`),\n children: childResults,\n }\n\n // If all children are suppressed, parent is also suppressed\n if (allSuppressed) {\n result.suppressed = true\n result.suppressedBy = childResults[0].suppressedBy\n } else if (anySuppressed && !allOk) {\n // Mixed: some suppressed, some failed - don't suppress parent\n // The parent shows as failed with the actual failures visible\n }\n\n // Record result in tracker before emitting\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n\n // Leaf node - execute command\n if (!node.run) {\n const result: TaskResult = {\n key: node.key,\n path,\n ok: true,\n code: 0,\n durationMs: 0,\n output: \"\",\n summaryLine: `${node.key}: no command specified`,\n }\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n\n const command = normalizeCommand(node.run, node.timeout)\n const cwd = this.options.cwd ?? process.cwd()\n\n // Pass tracker and path for early termination support\n const { code, output, durationMs, killed, timedOut } = await executeCommand(\n command,\n cwd,\n this.dependencyTracker,\n path,\n )\n\n const ok = code === 0\n\n // If process timed out, mark as failed with timeout info\n if (timedOut) {\n const result: TaskResult = {\n key: node.key,\n path,\n ok: false,\n code,\n durationMs,\n output,\n summaryLine: `${node.key}: timed out after ${command.timeout}ms`,\n timedOut: true,\n }\n\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n\n // If process was killed (by dependency failure), mark as suppressed\n if (killed) {\n // Wait for dependencies to get the failed dependency path\n await this.dependencyTracker.waitForDependencies(path)\n const failedDep = this.dependencyTracker.getFailedDependency(path)\n\n const result: TaskResult = {\n key: node.key,\n path,\n ok: false,\n code,\n durationMs,\n output,\n summaryLine: `${node.key}: terminated`,\n suppressed: true,\n suppressedBy: failedDep ?? \"unknown\",\n }\n\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n\n // Parse output - for shell commands, cmd is the full command string\n const cmdString = command.shell\n ? command.cmd\n : `${command.cmd} ${command.args.join(\" \")}`\n const parsed: ParsedResult = this.registry.parse(\n output,\n code,\n node.parser,\n cmdString,\n )\n\n // Build summary line\n let summaryLine: string\n if (ok) {\n summaryLine = node.successLabel\n ? `${node.key}: ${node.successLabel}`\n : `${node.key}: ${parsed.summary}`\n } else {\n summaryLine = node.failureLabel\n ? `${node.key}: ${node.failureLabel}`\n : `${node.key}: ${parsed.summary}`\n }\n\n let result: TaskResult = {\n key: node.key,\n path,\n ok,\n code,\n durationMs,\n output,\n summaryLine,\n metrics: parsed.metrics,\n }\n\n // If this task has reporting dependencies, wait for them and check for suppression\n if (this.dependencyTracker.hasDependencies(path)) {\n await this.dependencyTracker.waitForDependencies(path)\n\n // Check if any dependency failed - if so, suppress this task's failure\n if (!ok) {\n const failedDep = this.dependencyTracker.getFailedDependency(path)\n if (failedDep) {\n result = {\n ...result,\n suppressed: true,\n suppressedBy: failedDep,\n }\n }\n }\n }\n\n // Record result in tracker before emitting\n this.dependencyTracker.recordResult(result)\n this.callbacks.onTaskComplete?.(result)\n return result\n }\n}\n","import type { ChildProcess } from \"node:child_process\"\nimport treeKill from \"tree-kill\"\nimport { walkNodes } from \"./tree.js\"\nimport type { TaskResult, VerificationNode } from \"./types.js\"\n\n/**\n * Tracks reporting dependencies between tasks and coordinates result emission.\n * Allows tasks to wait for their dependencies to complete before emitting results,\n * and determines if a task's failure should be suppressed.\n * Also handles early termination by killing dependent processes when a dependency fails.\n */\nexport class ReportingDependencyTracker {\n /** Map of task path/key to their results */\n private results: Map<string, TaskResult> = new Map()\n\n /** Map of task path/key to waiters (callbacks to resolve when result is available) */\n private waiters: Map<string, Array<() => void>> = new Map()\n\n /** Map of task path to its key (for key-based lookups) */\n private pathToKey: Map<string, string> = new Map()\n\n /** Map of task key to its path (for key-based lookups) */\n private keyToPath: Map<string, string> = new Map()\n\n /** Map of task path to its reportingDependsOn array */\n private dependencies: Map<string, string[]> = new Map()\n\n /** Reverse map: task path → list of tasks that depend on it */\n private reverseDeps: Map<string, string[]> = new Map()\n\n /** Map of task path to its running ChildProcess */\n private processes: Map<string, ChildProcess> = new Map()\n\n /** Set of task paths that have been killed */\n private killedPaths: Set<string> = new Set()\n\n /** Set of task paths that will actually run (based on filter) */\n private activePaths: Set<string> = new Set()\n\n /**\n * Initialize the tracker with all tasks from the verification tree.\n * Also validates for circular dependencies and builds reverse dependency map.\n */\n initialize(nodes: VerificationNode[]): void {\n walkNodes(nodes, (node, path) => {\n this.pathToKey.set(path, node.key)\n this.keyToPath.set(node.key, path)\n\n if (node.reportingDependsOn && node.reportingDependsOn.length > 0) {\n this.dependencies.set(path, node.reportingDependsOn)\n }\n })\n\n this.validateNoCycles()\n this.buildReverseDeps()\n }\n\n /**\n * Build reverse dependency map (task → tasks that depend on it)\n */\n private buildReverseDeps(): void {\n for (const [path, deps] of this.dependencies.entries()) {\n for (const dep of deps) {\n const resolvedDep = this.resolveDependency(dep)\n if (resolvedDep) {\n const existing = this.reverseDeps.get(resolvedDep) ?? []\n existing.push(path)\n this.reverseDeps.set(resolvedDep, existing)\n }\n }\n }\n }\n\n /**\n * Validate that there are no circular dependencies using DFS with coloring.\n * Throws an error with the cycle path if a cycle is detected.\n */\n private validateNoCycles(): void {\n const WHITE = 0 // Not visited\n const GRAY = 1 // Currently visiting (in stack)\n const BLACK = 2 // Fully visited\n\n const colors = new Map<string, number>()\n const parent = new Map<string, string>()\n\n // Initialize all nodes as white\n for (const path of this.pathToKey.keys()) {\n colors.set(path, WHITE)\n }\n\n const dfs = (path: string): string | null => {\n colors.set(path, GRAY)\n\n const deps = this.dependencies.get(path) ?? []\n for (const dep of deps) {\n const depPath = this.resolveDependency(dep)\n if (!depPath) continue // Unknown dependency, skip\n\n const color = colors.get(depPath) ?? WHITE\n\n if (color === GRAY) {\n // Found a cycle - reconstruct the path\n const cycle: string[] = [depPath]\n let current = path\n while (current !== depPath) {\n cycle.unshift(current)\n current = parent.get(current) ?? \"\"\n }\n cycle.unshift(depPath)\n return cycle.join(\" → \")\n }\n\n if (color === WHITE) {\n parent.set(depPath, path)\n const cyclePath = dfs(depPath)\n if (cyclePath) return cyclePath\n }\n }\n\n colors.set(path, BLACK)\n return null\n }\n\n for (const path of this.pathToKey.keys()) {\n if (colors.get(path) === WHITE) {\n const cyclePath = dfs(path)\n if (cyclePath) {\n throw new Error(\n `Circular reporting dependency detected: ${cyclePath}`,\n )\n }\n }\n }\n }\n\n /**\n * Resolve a dependency identifier to a task path.\n * Tries exact path match first, then key match.\n */\n private resolveDependency(dep: string): string | null {\n // Try exact path match first\n if (this.pathToKey.has(dep)) {\n return dep\n }\n\n // Try key match\n if (this.keyToPath.has(dep)) {\n return this.keyToPath.get(dep) ?? null\n }\n\n return null\n }\n\n /**\n * Record a task result and notify any waiters.\n * If the task failed, kills all dependent processes for early termination.\n */\n recordResult(result: TaskResult): void {\n // Store by path\n this.results.set(result.path, result)\n\n // If this task failed, kill all dependent processes\n if (!result.ok) {\n this.killDependents(result.path)\n }\n\n // Notify waiters for this path\n const pathWaiters = this.waiters.get(result.path) ?? []\n for (const waiter of pathWaiters) {\n waiter()\n }\n this.waiters.delete(result.path)\n\n // Also notify waiters for the key (if different from path)\n const key = result.key\n if (key !== result.path) {\n const keyWaiters = this.waiters.get(key) ?? []\n for (const waiter of keyWaiters) {\n waiter()\n }\n this.waiters.delete(key)\n }\n }\n\n /**\n * Mark a task as active (will actually run).\n * Called before running each task to track which tasks are in the execution set.\n */\n markActive(path: string): void {\n this.activePaths.add(path)\n }\n\n /**\n * Check if a dependency is active (will run).\n * If not active, we shouldn't wait for it.\n */\n private isDependencyActive(dep: string): boolean {\n const resolvedPath = this.resolveDependency(dep)\n if (!resolvedPath) {\n return false\n }\n return this.activePaths.has(resolvedPath)\n }\n\n /**\n * Wait for all dependencies of a task to complete.\n * Only waits for dependencies that are actually active (will run).\n */\n async waitForDependencies(path: string): Promise<void> {\n const deps = this.dependencies.get(path)\n if (!deps || deps.length === 0) {\n return\n }\n\n // Only wait for dependencies that are active (will run)\n const activeDeps = deps.filter(dep => this.isDependencyActive(dep))\n const waitPromises = activeDeps.map(dep => this.waitForResult(dep))\n await Promise.all(waitPromises)\n }\n\n /**\n * Wait for a specific task result to be available.\n */\n private waitForResult(pathOrKey: string): Promise<void> {\n // Check if result already exists\n const resolvedPath = this.resolveDependency(pathOrKey)\n if (resolvedPath && this.results.has(resolvedPath)) {\n return Promise.resolve()\n }\n\n // Also check by the original identifier\n if (this.results.has(pathOrKey)) {\n return Promise.resolve()\n }\n\n // Register a waiter\n return new Promise<void>(resolve => {\n const waiters = this.waiters.get(pathOrKey) ?? []\n waiters.push(resolve)\n this.waiters.set(pathOrKey, waiters)\n })\n }\n\n /**\n * Check if any dependency of a task has failed.\n * Returns the path of the first failed dependency, or null if all passed.\n */\n getFailedDependency(path: string): string | null {\n const deps = this.dependencies.get(path)\n if (!deps || deps.length === 0) {\n return null\n }\n\n for (const dep of deps) {\n const resolvedPath = this.resolveDependency(dep)\n if (!resolvedPath) continue\n\n const result = this.results.get(resolvedPath)\n if (result && !result.ok) {\n return resolvedPath\n }\n }\n\n return null\n }\n\n /**\n * Check if a task has any reporting dependencies.\n */\n hasDependencies(path: string): boolean {\n const deps = this.dependencies.get(path)\n return deps !== undefined && deps.length > 0\n }\n\n /**\n * Register a running process for a task.\n */\n registerProcess(path: string, proc: ChildProcess): void {\n this.processes.set(path, proc)\n }\n\n /**\n * Unregister a process (called when it completes naturally).\n */\n unregisterProcess(path: string): void {\n this.processes.delete(path)\n }\n\n /**\n * Check if a task was killed.\n */\n wasKilled(path: string): boolean {\n return this.killedPaths.has(path)\n }\n\n /**\n * Kill all processes that depend on the failed task.\n * Called when a task fails to terminate dependent tasks early.\n */\n killDependents(failedPath: string): void {\n const dependents = this.reverseDeps.get(failedPath) ?? []\n\n for (const depPath of dependents) {\n const proc = this.processes.get(depPath)\n if (proc?.pid) {\n this.killedPaths.add(depPath)\n // Use tree-kill to kill the process and all its children\n treeKill(proc.pid, \"SIGTERM\", err => {\n if (err) {\n // Process may have already exited, ignore errors\n }\n })\n }\n }\n }\n}\n","// Types\n\n// Config helpers\nexport {\n ConfigError,\n defineConfig,\n defineTask,\n findConfigFile,\n loadConfig,\n loadConfigFromCwd,\n mergeOptions,\n validateConfig,\n} from \"./config.js\"\n// Discovery\nexport {\n type DiscoveredPackage,\n discoverPackages,\n hasPackageChanged,\n} from \"./discovery.js\"\n// Filter validation\nexport {\n AmbiguousTaskError,\n findBestSuggestion,\n type ResolvedFilter,\n resolveFilters,\n TaskNotFoundError,\n} from \"./filter.js\"\n// Init\nexport {\n type DetectedTask,\n detectTasks,\n generateConfigContent,\n type InitOptions,\n type InitResult,\n type OutputFormat,\n runInit,\n} from \"./init/index.js\"\n// Parsers\nexport {\n biomeParser,\n defaultRegistry,\n genericParser,\n gotestParser,\n type ParserId,\n ParserRegistry,\n parsers,\n tscParser,\n vitestParser,\n} from \"./parsers/index.js\"\n\n// Reporter\nexport {\n createReporter,\n JSONReporter,\n LiveDashboardReporter,\n QuietReporter,\n type Reporter,\n SequentialReporter,\n TTYReporter,\n} from \"./reporter.js\"\n// Runner\nexport { type RunnerCallbacks, VerificationRunner } from \"./runner.js\"\n// Tree utilities\nexport {\n buildTaskPath,\n collectPaths,\n type NodeVisitor,\n PATH_SEPARATOR,\n walkNodes,\n} from \"./tree.js\"\nexport type {\n ExecutionStrategy,\n OutputParser,\n PackageDiscoveryOptions,\n ParsedResult,\n TaskResult,\n VerificationCommand,\n VerificationNode,\n VerifyConfig,\n VerifyOptions,\n VerifyResult,\n} from \"./types.js\"\n\nimport { loadConfigFromCwd, mergeOptions } from \"./config.js\"\nimport { resolveFilters } from \"./filter.js\"\nimport { createReporter } from \"./reporter.js\"\nimport { VerificationRunner } from \"./runner.js\"\n// Main verify function\nimport type { VerifyConfig, VerifyOptions, VerifyResult } from \"./types.js\"\n\n/**\n * Run verification with the given config and options\n */\nexport async function verify(\n config: VerifyConfig,\n cliOptions?: Partial<VerifyOptions>,\n): Promise<VerifyResult> {\n const options = mergeOptions(config.options, cliOptions)\n\n // VALIDATION PHASE - fail fast before any execution\n if (options.filter && options.filter.length > 0) {\n const resolved = resolveFilters(config.tasks, options.filter)\n\n // Log info messages for any shortcuts used\n for (const r of resolved) {\n if (r.wasShortcut) {\n console.error(`→ Resolving \"${r.original}\" to \"${r.resolved}\"`)\n }\n }\n\n // Update options with resolved filters\n options.filter = resolved.map(r => r.resolved)\n }\n\n // EXECUTION PHASE - only runs if validation passed\n const reporter = createReporter(options)\n\n // Initialize reporter with task list (for live dashboard)\n reporter.onStart?.(config.tasks)\n\n const runner = new VerificationRunner(options, undefined, {\n onTaskStart: (path, key) => reporter.onTaskStart(path, key),\n onTaskComplete: result => reporter.onTaskComplete(result),\n })\n\n const result = await runner.run(config.tasks)\n\n // Cleanup reporter (stop spinner, restore cursor)\n reporter.onFinish?.()\n\n reporter.outputLogs(result.tasks, options.logs ?? \"failed\")\n reporter.outputSummary(result)\n\n return result\n}\n\n/**\n * Run verification from config file in cwd\n */\nexport async function verifyFromConfig(\n cwd: string = process.cwd(),\n cliOptions?: Partial<VerifyOptions>,\n): Promise<VerifyResult> {\n const config = await loadConfigFromCwd(cwd, cliOptions?.cwd)\n\n if (!config) {\n throw new Error(\n `No verify config found in ${cwd}. Create a verify.config.ts file.`,\n )\n }\n\n return verify(config, { ...cliOptions, cwd })\n}\n"],"mappings":"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","names":["existsSync","join","z","join","existsSync","existsSync","readFileSync","join","join","existsSync","readFileSync","existsSync","resolve","errors","treeKill","resolve","resolve","treeKill","durationMs","result","result"]}