workflow-agent-cli 2.23.0 → 2.23.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -15
- package/dist/{auto-fix-7WAESKYO.js → auto-fix-WGRYEFLJ.js} +2 -2
- package/dist/{chunk-IWFUJ2DS.js → chunk-DWHIY7R4.js} +20 -9
- package/dist/chunk-DWHIY7R4.js.map +1 -0
- package/dist/{chunk-D36IFZUZ.js → chunk-EHRI6BI6.js} +15 -4
- package/dist/chunk-EHRI6BI6.js.map +1 -0
- package/dist/{chunk-M6RHIUSM.js → chunk-K42R54II.js} +147 -54
- package/dist/chunk-K42R54II.js.map +1 -0
- package/dist/{chunk-XGS2VFBP.js → chunk-MBRMT5ZG.js} +865 -18
- package/dist/chunk-MBRMT5ZG.js.map +1 -0
- package/dist/{chunk-YELUGXOM.js → chunk-NPJJZHJG.js} +1 -1
- package/dist/chunk-NPJJZHJG.js.map +1 -0
- package/dist/{chunk-UWJ2ZGEI.js → chunk-OH6TK27N.js} +3 -3
- package/dist/{chunk-ZLDJ2OGO.js → chunk-WK7D2AVV.js} +11 -3
- package/dist/{chunk-ZLDJ2OGO.js.map → chunk-WK7D2AVV.js.map} +1 -1
- package/dist/cli/index.js +771 -285
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.js +2 -2
- package/dist/index.d.ts +87 -56
- package/dist/index.js +26 -10
- package/dist/scripts/postinstall.js +1 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/sync-HHQM3GKR.js +7 -0
- package/dist/validators/index.js +1 -1
- package/dist/verify-PA7R6FBJ.js +8 -0
- package/package.json +2 -2
- package/dist/chunk-3ADL5QDN.js +0 -396
- package/dist/chunk-3ADL5QDN.js.map +0 -1
- package/dist/chunk-D36IFZUZ.js.map +0 -1
- package/dist/chunk-IWFUJ2DS.js.map +0 -1
- package/dist/chunk-M6RHIUSM.js.map +0 -1
- package/dist/chunk-XGS2VFBP.js.map +0 -1
- package/dist/chunk-YELUGXOM.js.map +0 -1
- package/dist/sync-6T5TD4QS.js +0 -7
- package/dist/verify-TX6LFMI6.js +0 -8
- /package/dist/{auto-fix-7WAESKYO.js.map → auto-fix-WGRYEFLJ.js.map} +0 -0
- /package/dist/{chunk-UWJ2ZGEI.js.map → chunk-OH6TK27N.js.map} +0 -0
- /package/dist/{sync-6T5TD4QS.js.map → sync-HHQM3GKR.js.map} +0 -0
- /package/dist/{verify-TX6LFMI6.js.map → verify-PA7R6FBJ.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/sync.ts","../src/sync/registry-client.ts"],"sourcesContent":["/**\n * Unified Sync Command\n *\n * Orchestrates syncing of patterns and solutions with the registry.\n * Combines functionality from learn:sync and solution sync.\n *\n * Usage:\n * workflow sync # Interactive sync (prompts for direction)\n * workflow sync --push # Push local patterns to registry\n * workflow sync --pull # Pull patterns from registry\n * workflow sync --solutions # Include solution patterns\n * workflow sync --learn # Include learning patterns (default)\n * workflow sync --scopes # Sync custom scope packages\n * workflow sync --all # Sync everything\n * workflow sync --dry-run # Preview without syncing\n */\n\nimport * as p from \"@clack/prompts\";\nimport chalk from \"chalk\";\nimport {\n PatternStore,\n PatternAnonymizer,\n ContributorManager,\n type FixPattern,\n type Blueprint,\n type SolutionPattern,\n} from \"@hawkinside_out/workflow-improvement-tracker\";\nimport {\n RegistryClient,\n RateLimitedException,\n RegistryError,\n} from \"../../sync/registry-client.js\";\n\nexport interface UnifiedSyncOptions {\n push?: boolean;\n pull?: boolean;\n solutions?: boolean;\n learn?: boolean;\n scopes?: boolean;\n all?: boolean;\n dryRun?: boolean;\n enableSync?: boolean;\n disableSync?: boolean;\n includePrivate?: boolean;\n}\n\nfunction getWorkspacePath(): string {\n return process.cwd();\n}\n\n/**\n * Unified sync command that orchestrates all sync operations\n */\nexport async function syncCommand(options: UnifiedSyncOptions): Promise<void> {\n const cwd = getWorkspacePath();\n const contributorManager = new ContributorManager(cwd);\n\n p.intro(chalk.bgBlue(\" workflow sync \"));\n\n // Handle --enable-sync option\n if (options.enableSync) {\n const enableResult = await contributorManager.enableSync();\n if (enableResult.success) {\n console.log(chalk.green(\"\\n✅ Sync enabled!\"));\n console.log(chalk.dim(\" Your anonymized patterns can now be shared with the community.\\n\"));\n } else {\n console.log(chalk.red(`\\n❌ Failed to enable sync: ${enableResult.error}\\n`));\n process.exit(1);\n }\n // If only --enable-sync was passed, exit after enabling\n if (!options.push && !options.pull && !options.all && !options.solutions && !options.scopes) {\n p.outro(chalk.green(\"Sync enabled\"));\n return;\n }\n }\n\n // Handle --disable-sync option\n if (options.disableSync) {\n const disableResult = await contributorManager.disableSync();\n if (disableResult.success) {\n console.log(chalk.green(\"\\n✅ Sync disabled!\"));\n console.log(chalk.dim(\" Your patterns will no longer be shared.\\n\"));\n } else {\n console.log(chalk.red(`\\n❌ Failed to disable sync: ${disableResult.error}\\n`));\n process.exit(1);\n }\n p.outro(chalk.green(\"Sync disabled\"));\n return;\n }\n\n // Check if sync is enabled\n const config = await contributorManager.getConfig();\n if (!config.success || !config.data?.syncOptIn) {\n console.log(chalk.yellow(\"\\n⚠️ Sync is not enabled.\\n\"));\n console.log(chalk.dim(\" To enable sync, run:\"));\n console.log(chalk.dim(\" workflow learn config --enable-sync\\n\"));\n console.log(\n chalk.dim(\n \" This allows you to share anonymized patterns with the community.\",\n ),\n );\n p.outro(chalk.yellow(\"Sync not enabled\"));\n process.exit(0);\n }\n\n // Determine what to sync\n const syncLearn = options.learn || options.all || (!options.solutions && !options.scopes);\n const syncSolutions = options.solutions || options.all;\n const syncScopes = options.scopes || options.all;\n\n // Determine direction\n let direction: \"push\" | \"pull\" | \"both\" = \"both\";\n if (options.push && !options.pull) {\n direction = \"push\";\n } else if (options.pull && !options.push) {\n direction = \"pull\";\n } else if (!options.push && !options.pull) {\n // Interactive mode - ask user\n const choice = await p.select({\n message: \"Sync direction:\",\n options: [\n { value: \"push\", label: \"📤 Push - Upload local patterns to registry\" },\n { value: \"pull\", label: \"📥 Pull - Download patterns from registry\" },\n { value: \"both\", label: \"🔄 Both - Push then pull\" },\n ],\n });\n\n if (p.isCancel(choice)) {\n p.cancel(\"Sync cancelled\");\n process.exit(0);\n }\n direction = choice as \"push\" | \"pull\" | \"both\";\n }\n\n if (options.dryRun) {\n console.log(chalk.yellow(\"\\n📋 DRY-RUN MODE: No changes will be synced\\n\"));\n }\n\n // Show what will be synced\n console.log(chalk.cyan(\"\\n📦 Syncing:\"));\n if (syncLearn) console.log(chalk.dim(\" • Learning patterns (fixes, blueprints)\"));\n if (syncSolutions) console.log(chalk.dim(\" • Solution patterns\"));\n if (syncScopes) console.log(chalk.dim(\" • Custom scopes\"));\n console.log(chalk.dim(` • Direction: ${direction === \"both\" ? \"push + pull\" : direction}`));\n if (options.includePrivate) console.log(chalk.dim(\" • Including private patterns\"));\n console.log(\"\");\n\n const store = new PatternStore(cwd);\n await store.initialize();\n const anonymizer = new PatternAnonymizer();\n\n // Get patterns to sync\n // If --include-private is set, get all patterns; otherwise filter to public only\n const syncData = await store.getPatternsForSync();\n let fixes = syncData.fixes ?? [];\n let blueprints = syncData.blueprints ?? [];\n let solutions = syncData.solutions ?? [];\n\n // Get stats for all patterns to show why some might be excluded\n const stats = await store.getStats();\n const totalLocalFixes = stats.totalFixes;\n const totalLocalBlueprints = stats.totalBlueprints;\n const totalLocalSolutions = stats.totalSolutions;\n const privateFixes = stats.privateFixes;\n const privateBlueprints = stats.privateBlueprints;\n const privateSolutions = stats.privateSolutions;\n\n // If --include-private, we need to get all patterns including private ones\n if (options.includePrivate) {\n const allFixes = await store.listFixPatterns({ includeDeprecated: false });\n const allBlueprints = await store.listBlueprints({ includeDeprecated: false });\n const allSolutions = await store.listSolutions({ includeDeprecated: false });\n fixes = allFixes.data ?? [];\n blueprints = allBlueprints.data ?? [];\n solutions = allSolutions.data ?? [];\n }\n\n // Filter based on options\n const patternsToSync: Array<{\n pattern: FixPattern | Blueprint | SolutionPattern;\n type: \"fix\" | \"blueprint\" | \"solution\";\n originalId: string;\n }> = [];\n\n if (syncLearn) {\n const publicCount = fixes.length;\n const privateCount = privateFixes;\n \n if (options.includePrivate) {\n console.log(chalk.dim(` Found ${publicCount} fixes, ${blueprints.length} blueprints to sync (including private)`));\n } else if (publicCount === 0 && privateCount > 0) {\n console.log(chalk.yellow(` Found 0 fixes ready to sync (${privateCount} are private)`));\n console.log(chalk.dim(` Use --include-private to include them, or run 'workflow learn migrate --public'`));\n } else {\n console.log(chalk.dim(` Found ${publicCount} fixes, ${blueprints.length} blueprints ready to sync`));\n }\n\n for (const fix of fixes) {\n const result = anonymizer.anonymizeFixPattern(fix);\n if (result.success && result.data) {\n patternsToSync.push({\n pattern: result.data,\n type: \"fix\",\n originalId: fix.id,\n });\n }\n }\n\n for (const bp of blueprints) {\n const result = anonymizer.anonymizeBlueprint(bp);\n if (result.success && result.data) {\n patternsToSync.push({\n pattern: result.data,\n type: \"blueprint\",\n originalId: bp.id,\n });\n }\n }\n }\n\n if (syncSolutions) {\n const publicCount = solutions.length;\n const privateCount = privateSolutions;\n \n if (options.includePrivate) {\n console.log(chalk.dim(` Found ${publicCount} solutions to sync (including private)`));\n } else if (publicCount === 0 && privateCount > 0 && !options.dryRun) {\n console.log(chalk.yellow(` Found 0 solutions ready to sync (${privateCount} are private)`));\n \n // Prompt user to migrate solutions to public\n const shouldMigrate = await p.confirm({\n message: `Would you like to make your ${privateCount} solution(s) public for sync?`,\n });\n \n if (p.isCancel(shouldMigrate) || !shouldMigrate) {\n console.log(chalk.dim(` Skipping private solutions. Use --include-private to force include them.`));\n } else {\n // Migrate all private solutions to public\n const allSolutions = await store.listSolutions({ includeDeprecated: false });\n for (const sol of allSolutions.data ?? []) {\n if (sol.isPrivate) {\n const updated = { ...sol, isPrivate: false, updatedAt: new Date().toISOString() };\n await store.saveSolution(updated);\n solutions.push(updated);\n }\n }\n console.log(chalk.green(` ✓ Migrated ${privateCount} solutions to public`));\n }\n } else if (publicCount === 0 && privateCount > 0) {\n // Dry run mode - just show the message\n console.log(chalk.yellow(` Found 0 solutions ready to sync (${privateCount} are private)`));\n console.log(chalk.dim(` Use --include-private to include them, or run 'workflow solution migrate --public'`));\n } else if (publicCount === 0 && privateCount === 0) {\n // No solutions at all - check for validation errors\n const validationErrors = store.getValidationErrors();\n const solutionErrors = validationErrors.filter((e) => e.type === \"solution\");\n if (solutionErrors.length > 0) {\n console.log(chalk.yellow(` Found 0 solutions (${solutionErrors.length} failed schema validation)`));\n for (const err of solutionErrors) {\n console.log(chalk.dim(` • ${err.file}: ${err.error}`));\n if (err.details) {\n for (const detail of err.details.slice(0, 3)) {\n console.log(chalk.dim(` - ${detail}`));\n }\n if (err.details.length > 3) {\n console.log(chalk.dim(` ... and ${err.details.length - 3} more issues`));\n }\n }\n }\n } else {\n console.log(chalk.dim(` Found 0 solutions to sync`));\n }\n } else {\n console.log(chalk.dim(` Found ${publicCount} solutions ready to sync`));\n }\n\n for (const solution of solutions) {\n const result = anonymizer.anonymizeSolution(solution);\n if (result.success && result.data) {\n patternsToSync.push({\n pattern: result.data,\n type: \"solution\",\n originalId: solution.id,\n });\n }\n }\n }\n\n if (syncScopes) {\n // TODO: Implement scope sync when scope registry is available\n console.log(chalk.dim(\" Scope sync: Coming soon\"));\n }\n\n // PUSH operation\n if (direction === \"push\" || direction === \"both\") {\n console.log(chalk.cyan(\"\\n📤 Pushing patterns...\\n\"));\n\n if (patternsToSync.length === 0) {\n console.log(chalk.yellow(\" No patterns to push\\n\"));\n } else {\n const fixCount = patternsToSync.filter((p) => p.type === \"fix\").length;\n const bpCount = patternsToSync.filter((p) => p.type === \"blueprint\").length;\n const solutionCount = patternsToSync.filter((p) => p.type === \"solution\").length;\n\n console.log(\n chalk.dim(\n ` Ready to push: ${fixCount} fixes, ${bpCount} blueprints, ${solutionCount} solutions`,\n ),\n );\n\n if (options.dryRun) {\n console.log(chalk.yellow(\"\\n [DRY-RUN] Would push patterns to registry\"));\n } else {\n // Get contributor ID\n const contributorResult = await contributorManager.getOrCreateId();\n if (!contributorResult.success || !contributorResult.data) {\n console.log(chalk.red(\"\\n ❌ Failed to get contributor ID\"));\n process.exit(1);\n }\n\n // Push to registry\n const registryClient = new RegistryClient();\n\n try {\n console.log(chalk.dim(\"\\n Connecting to registry...\"));\n\n const pushResult = await registryClient.push(\n patternsToSync.map((p) => ({\n pattern: p.pattern,\n type: p.type,\n })),\n contributorResult.data,\n );\n\n // Mark pushed patterns as synced\n if (pushResult.pushed > 0) {\n const pushedFixIds = patternsToSync\n .filter((p) => p.type === \"fix\")\n .map((p) => p.originalId);\n const pushedBpIds = patternsToSync\n .filter((p) => p.type === \"blueprint\")\n .map((p) => p.originalId);\n const pushedSolutionIds = patternsToSync\n .filter((p) => p.type === \"solution\")\n .map((p) => p.originalId);\n\n if (pushedFixIds.length > 0) {\n await store.markAsSynced(pushedFixIds, \"fix\");\n }\n if (pushedBpIds.length > 0) {\n await store.markAsSynced(pushedBpIds, \"blueprint\");\n }\n if (pushedSolutionIds.length > 0) {\n await store.markAsSynced(pushedSolutionIds, \"solution\");\n }\n }\n\n console.log(\n chalk.green(`\\n ✅ Pushed ${pushResult.pushed} patterns to registry`),\n );\n\n if (pushResult.skipped > 0) {\n console.log(\n chalk.dim(` (${pushResult.skipped} already existed)`),\n );\n }\n\n if (pushResult.errors && pushResult.errors.length > 0) {\n console.log(chalk.yellow(`\\n ⚠️ Some patterns had errors:`));\n for (const err of pushResult.errors) {\n console.log(chalk.dim(` - ${err}`));\n }\n }\n\n console.log(\n chalk.dim(\n `\\n Rate limit: ${pushResult.rateLimit.remaining} patterns remaining this hour`,\n ),\n );\n } catch (error) {\n if (error instanceof RateLimitedException) {\n console.log(chalk.red(\"\\n ❌ Rate limit exceeded\"));\n console.log(\n chalk.dim(\n ` Try again in ${error.getTimeUntilReset()}`,\n ),\n );\n } else if (error instanceof RegistryError) {\n console.log(chalk.red(`\\n ❌ Registry error: ${error.message}`));\n } else {\n console.log(\n chalk.red(\n `\\n ❌ Failed to push: ${error instanceof Error ? error.message : String(error)}`,\n ),\n );\n }\n process.exit(1);\n }\n }\n }\n }\n\n // PULL operation\n if (direction === \"pull\" || direction === \"both\") {\n console.log(chalk.cyan(\"\\n📥 Pulling patterns from registry...\\n\"));\n\n if (options.dryRun) {\n console.log(chalk.yellow(\" [DRY-RUN] Would pull patterns from registry\"));\n } else {\n const registryClient = new RegistryClient();\n\n try {\n console.log(chalk.dim(\" Connecting to registry...\"));\n\n // Pull patterns based on sync options - need to call separately for each type\n const pullTypes: (\"fix\" | \"blueprint\" | \"solution\")[] = [];\n if (syncLearn) {\n pullTypes.push(\"fix\", \"blueprint\");\n }\n if (syncSolutions) {\n pullTypes.push(\"solution\");\n }\n\n let totalPatterns = 0;\n let savedCount = 0;\n const typeCounts: Record<string, number> = {};\n\n for (const pullType of pullTypes) {\n const pullResult = await registryClient.pull({\n type: pullType,\n });\n\n typeCounts[pullType] = pullResult.patterns.length;\n totalPatterns += pullResult.patterns.length;\n\n for (const pulled of pullResult.patterns) {\n try {\n if (pulled.type === \"fix\" && pulled.data) {\n const fixData = pulled.data as FixPattern;\n await store.saveFixPattern(fixData);\n console.log(chalk.dim(` ✓ ${fixData.name} (fix)`));\n savedCount++;\n } else if (pulled.type === \"blueprint\" && pulled.data) {\n const blueprintData = pulled.data as Blueprint;\n await store.saveBlueprint(blueprintData);\n console.log(chalk.dim(` ✓ ${blueprintData.name} (blueprint)`));\n savedCount++;\n } else if (pulled.type === \"solution\" && pulled.data) {\n const solutionData = pulled.data as SolutionPattern;\n await store.saveSolution(solutionData);\n console.log(chalk.dim(` ✓ ${solutionData.name} (solution)`));\n savedCount++;\n }\n } catch {\n // Pattern might already exist - silently skip\n }\n }\n }\n\n // Show registry stats\n if (syncSolutions && typeCounts[\"solution\"] !== undefined) {\n console.log(chalk.dim(` Registry has ${typeCounts[\"solution\"]} solution(s) available`));\n }\n if (syncLearn) {\n const fixCount = typeCounts[\"fix\"] ?? 0;\n const bpCount = typeCounts[\"blueprint\"] ?? 0;\n console.log(chalk.dim(` Registry has ${fixCount} fix(es), ${bpCount} blueprint(s) available`));\n }\n\n if (totalPatterns === 0) {\n console.log(chalk.dim(\" No new patterns to pull\"));\n } else {\n console.log(\n chalk.green(`\\n ✅ Pulled ${savedCount} new patterns from registry`),\n );\n if (savedCount < totalPatterns) {\n console.log(chalk.dim(` (${totalPatterns - savedCount} already existed locally)`));\n }\n }\n } catch (error) {\n if (error instanceof RateLimitedException) {\n console.log(chalk.red(\"\\n ❌ Rate limit exceeded\"));\n console.log(\n chalk.dim(\n ` Try again in ${error.getTimeUntilReset()}`,\n ),\n );\n } else if (error instanceof RegistryError) {\n console.log(chalk.red(`\\n ❌ Registry error: ${error.message}`));\n } else {\n console.log(\n chalk.red(\n `\\n ❌ Failed to pull: ${error instanceof Error ? error.message : String(error)}`,\n ),\n );\n }\n process.exit(1);\n }\n }\n }\n\n p.outro(chalk.green(\"Sync complete!\"));\n}\n","/**\n * Registry Client for pattern sync\n *\n * HTTP client for pushing patterns to and pulling patterns from\n * the community pattern registry.\n */\n\nimport type { FixPattern, Blueprint, SolutionPattern } from \"@hawkinside_out/workflow-improvement-tracker\";\n\n// Default registry URL\nconst DEFAULT_REGISTRY_URL = \"https://registry-api-rust.vercel.app\";\n\n/**\n * Pattern payload for push/pull operations\n */\nexport interface RegistryPattern {\n id: string;\n type: \"fix\" | \"blueprint\" | \"solution\";\n data: Record<string, unknown>;\n hash?: string;\n createdAt?: string;\n}\n\n/**\n * Push response from registry\n */\nexport interface PushResponse {\n status: \"ok\" | \"error\";\n pushed: number;\n skipped: number;\n errors?: string[];\n rateLimit: {\n remaining: number;\n resetAt: string | null;\n };\n}\n\n/**\n * Pull response from registry\n */\nexport interface PullResponse {\n patterns: RegistryPattern[];\n pagination: {\n offset: number;\n limit: number;\n total: number;\n hasMore: boolean;\n };\n}\n\n/**\n * Rate limit error details\n */\nexport interface RateLimitError {\n message: string;\n resetAt: string | null;\n remaining: number;\n}\n\n/**\n * Registry client options\n */\nexport interface RegistryClientOptions {\n /**\n * Base URL of the registry API\n * Defaults to https://patterns.workflow-agent.dev\n * Can be overridden via WORKFLOW_REGISTRY_URL env var\n */\n baseUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * Defaults to 30000 (30 seconds)\n */\n timeout?: number;\n\n /**\n * Number of retry attempts for failed requests\n * Defaults to 3\n */\n retries?: number;\n}\n\n/**\n * Registry Client\n *\n * Handles HTTP communication with the pattern registry API\n */\nexport class RegistryClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly retries: number;\n\n constructor(options: RegistryClientOptions = {}) {\n // Priority: options > env var > default\n this.baseUrl =\n options.baseUrl ||\n process.env.WORKFLOW_REGISTRY_URL ||\n DEFAULT_REGISTRY_URL;\n\n // Ensure no trailing slash\n this.baseUrl = this.baseUrl.replace(/\\/$/, \"\");\n\n this.timeout = options.timeout ?? 30000;\n this.retries = options.retries ?? 3;\n }\n\n /**\n * Push patterns to the registry\n *\n * @param patterns - Array of anonymized patterns to push\n * @param contributorId - Anonymous contributor ID\n * @returns Push result with count of pushed/skipped patterns\n * @throws Error if rate limited or push fails\n */\n async push(\n patterns: Array<{\n pattern: FixPattern | Blueprint | SolutionPattern;\n type: \"fix\" | \"blueprint\" | \"solution\";\n hash?: string;\n }>,\n contributorId: string,\n ): Promise<PushResponse> {\n const payload = {\n patterns: patterns.map((p) => ({\n id: p.pattern.id,\n type: p.type,\n data: p.pattern as unknown as Record<string, unknown>,\n hash: p.hash,\n })),\n };\n\n const response = await this.request<PushResponse>(\n \"/api/patterns/push\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-contributor-id\": contributorId,\n },\n body: JSON.stringify(payload),\n },\n );\n\n return response;\n }\n\n /**\n * Pull patterns from the registry\n *\n * @param options - Pull options\n * @returns Array of patterns from the registry\n */\n async pull(options: {\n type?: \"fix\" | \"blueprint\" | \"solution\";\n limit?: number;\n offset?: number;\n since?: string;\n } = {}): Promise<PullResponse> {\n const params = new URLSearchParams();\n\n if (options.type) {\n params.set(\"type\", options.type);\n }\n if (options.limit) {\n params.set(\"limit\", options.limit.toString());\n }\n if (options.offset) {\n params.set(\"offset\", options.offset.toString());\n }\n if (options.since) {\n params.set(\"since\", options.since);\n }\n\n const queryString = params.toString();\n const url = `/api/patterns/pull${queryString ? `?${queryString}` : \"\"}`;\n\n return this.request<PullResponse>(url, {\n method: \"GET\",\n });\n }\n\n /**\n * Get a single pattern by ID\n *\n * @param patternId - UUID of the pattern\n * @returns Pattern data or null if not found\n */\n async getPattern(patternId: string): Promise<RegistryPattern | null> {\n try {\n return await this.request<RegistryPattern>(`/api/patterns/${patternId}`, {\n method: \"GET\",\n });\n } catch (error) {\n if (error instanceof RegistryError && error.statusCode === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Check if the registry is available\n */\n async healthCheck(): Promise<boolean> {\n try {\n await this.request<{ status: string }>(\"/api/health\", {\n method: \"GET\",\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Make an HTTP request to the registry\n */\n private async request<T>(\n path: string,\n options: RequestInit,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= this.retries; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.status === 429) {\n // Rate limited\n const body = await response.json() as { message?: string; resetAt?: string | null; remaining?: number };\n throw new RateLimitedException(\n body.message || \"Rate limit exceeded\",\n body.resetAt ?? null,\n body.remaining ?? 0,\n );\n }\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({})) as { error?: string };\n throw new RegistryError(\n body.error || `Request failed with status ${response.status}`,\n response.status,\n body,\n );\n }\n\n return await response.json() as T;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry rate limit errors\n if (error instanceof RateLimitedException) {\n throw error;\n }\n\n // Don't retry on 4xx errors (except timeout)\n if (\n error instanceof RegistryError &&\n error.statusCode >= 400 &&\n error.statusCode < 500\n ) {\n throw error;\n }\n\n // Wait before retrying (exponential backoff)\n if (attempt < this.retries) {\n await new Promise((resolve) =>\n setTimeout(resolve, Math.pow(2, attempt) * 1000)\n );\n }\n }\n }\n\n throw lastError ?? new Error(\"Request failed after retries\");\n }\n}\n\n/**\n * Registry API error\n */\nexport class RegistryError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = \"RegistryError\";\n }\n}\n\n/**\n * Rate limit exceeded error\n */\nexport class RateLimitedException extends Error {\n constructor(\n message: string,\n public readonly resetAt: string | null,\n public readonly remaining: number,\n ) {\n super(message);\n this.name = \"RateLimitedException\";\n }\n\n /**\n * Get human-readable time until rate limit resets\n */\n getTimeUntilReset(): string {\n if (!this.resetAt) {\n return \"unknown\";\n }\n\n const resetTime = new Date(this.resetAt).getTime();\n const now = Date.now();\n const diffMs = resetTime - now;\n\n if (diffMs <= 0) {\n return \"now\";\n }\n\n const minutes = Math.ceil(diffMs / 60000);\n if (minutes < 60) {\n return `${minutes} minute${minutes === 1 ? \"\" : \"s\"}`;\n }\n\n const hours = Math.ceil(minutes / 60);\n return `${hours} hour${hours === 1 ? \"\" : \"s\"}`;\n }\n}\n"],"mappings":"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","names":["p","p"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/auto-setup.ts","../src/utils/git-repo.ts"],"sourcesContent":["/**\n * Auto-Setup Utilities\n *\n * Intelligent project setup that:\n * - Analyzes what a project has and needs\n * - Generates audit reports showing what will change\n * - MERGES with existing configs (improves, doesn't replace)\n * - Batches dependency installs for performance\n * - Supports monorepos with root + shared configs\n *\n * Works like a developer would: analyze first, then configure.\n */\n\nimport { existsSync } from \"fs\";\nimport { readFile, writeFile, mkdir } from \"fs/promises\";\nimport { join } from \"path\";\nimport { execa } from \"execa\";\nimport {\n detectPackageManager,\n isMonorepo,\n getPackageScripts,\n type PackageManager,\n} from \"./git-repo.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ProjectAnalysis {\n packageManager: PackageManager;\n isMonorepo: boolean;\n isTypeScript: boolean;\n framework: FrameworkType;\n existing: ExistingConfigs;\n scripts: ExistingScripts;\n setupPlans: SetupPlan[];\n}\n\nexport interface ExistingConfigs {\n typescript: boolean;\n eslint: boolean;\n eslintFlat: boolean;\n prettier: boolean;\n vitest: boolean;\n jest: boolean;\n husky: boolean;\n simpleGitHooks: boolean;\n githubActions: boolean;\n}\n\nexport interface ExistingScripts {\n build: boolean;\n test: boolean;\n lint: boolean;\n format: boolean;\n typecheck: boolean;\n verify: boolean;\n}\n\nexport interface SetupPlan {\n name: string;\n description: string;\n priority: \"high\" | \"medium\" | \"low\";\n changes: ConfigChange[];\n dependencies: string[];\n devDependencies: string[];\n}\n\nexport interface ConfigChange {\n type: \"add\" | \"modify\" | \"unchanged\";\n file: string;\n key?: string;\n oldValue?: unknown;\n newValue?: unknown;\n description: string;\n}\n\nexport interface SetupResult {\n success: boolean;\n name: string;\n message: string;\n filesCreated: string[];\n filesUpdated: string[];\n packagesInstalled: string[];\n}\n\nexport interface AuditReport {\n analysis: ProjectAnalysis;\n totalChanges: number;\n allDependencies: string[];\n allDevDependencies: string[];\n plans: SetupPlan[];\n}\n\nexport type FrameworkType =\n | \"nextjs\"\n | \"remix\"\n | \"react\"\n | \"vue\"\n | \"nuxt\"\n | \"svelte\"\n | \"node\"\n | \"express\"\n | \"hono\"\n | \"shopify\"\n | \"unknown\";\n\n// Package.json structure for type safety\ninterface PackageJson {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n \"simple-git-hooks\"?: Record<string, string>;\n \"lint-staged\"?: Record<string, string | string[]>;\n [key: string]: unknown;\n}\n\n// TSConfig structure\ninterface TSConfig {\n compilerOptions?: Record<string, unknown>;\n include?: string[];\n exclude?: string[];\n [key: string]: unknown;\n}\n\n// ============================================================================\n// Project Analysis\n// ============================================================================\n\n/**\n * Analyze a project to determine what setup is needed\n */\nexport async function analyzeProject(\n projectPath: string = process.cwd(),\n): Promise<ProjectAnalysis> {\n const packageManager = await detectPackageManager(projectPath);\n const mono = await isMonorepo(projectPath);\n const scripts = await getPackageScripts(projectPath);\n\n // Check for TypeScript\n const isTypeScript =\n existsSync(join(projectPath, \"tsconfig.json\")) ||\n existsSync(join(projectPath, \"src/index.ts\")) ||\n existsSync(join(projectPath, \"index.ts\"));\n\n // Detect framework\n const framework = await detectFramework(projectPath);\n\n // Check existing configs\n const existing: ExistingConfigs = {\n typescript: existsSync(join(projectPath, \"tsconfig.json\")),\n eslint:\n existsSync(join(projectPath, \"eslint.config.js\")) ||\n existsSync(join(projectPath, \"eslint.config.mjs\")) ||\n existsSync(join(projectPath, \".eslintrc.js\")) ||\n existsSync(join(projectPath, \".eslintrc.json\")) ||\n existsSync(join(projectPath, \".eslintrc\")),\n eslintFlat:\n existsSync(join(projectPath, \"eslint.config.js\")) ||\n existsSync(join(projectPath, \"eslint.config.mjs\")),\n prettier:\n existsSync(join(projectPath, \".prettierrc\")) ||\n existsSync(join(projectPath, \".prettierrc.json\")) ||\n existsSync(join(projectPath, \"prettier.config.js\")) ||\n existsSync(join(projectPath, \"prettier.config.mjs\")),\n vitest:\n existsSync(join(projectPath, \"vitest.config.ts\")) ||\n existsSync(join(projectPath, \"vitest.config.js\")),\n jest:\n existsSync(join(projectPath, \"jest.config.js\")) ||\n existsSync(join(projectPath, \"jest.config.ts\")),\n husky: existsSync(join(projectPath, \".husky\")),\n simpleGitHooks:\n existsSync(join(projectPath, \".git/hooks/pre-commit\")) ||\n (await hasSimpleGitHooksConfig(projectPath)),\n githubActions: existsSync(join(projectPath, \".github/workflows\")),\n };\n\n // Check existing scripts\n const existingScripts: ExistingScripts = {\n build: !!scripts.build,\n test: !!scripts.test,\n lint: !!scripts.lint,\n format: !!scripts.format,\n typecheck: !!scripts.typecheck,\n verify: !!scripts.verify,\n };\n\n // Generate setup plans\n const setupPlans = await generateSetupPlans(\n projectPath,\n packageManager,\n isTypeScript,\n framework,\n existing,\n existingScripts,\n mono,\n );\n\n return {\n packageManager,\n isMonorepo: mono,\n isTypeScript,\n framework,\n existing,\n scripts: existingScripts,\n setupPlans,\n };\n}\n\nasync function hasSimpleGitHooksConfig(projectPath: string): Promise<boolean> {\n try {\n const pkgPath = join(projectPath, \"package.json\");\n if (!existsSync(pkgPath)) return false;\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n return !!pkg[\"simple-git-hooks\"];\n } catch {\n return false;\n }\n}\n\n/**\n * Detect the framework used in the project\n */\nasync function detectFramework(projectPath: string): Promise<FrameworkType> {\n try {\n const pkgPath = join(projectPath, \"package.json\");\n if (!existsSync(pkgPath)) return \"unknown\";\n\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n // Shopify theme detection\n if (\n existsSync(join(projectPath, \"shopify.theme.toml\")) ||\n existsSync(join(projectPath, \"config/settings_schema.json\")) ||\n deps[\"@shopify/cli\"] ||\n deps[\"@shopify/theme\"]\n ) {\n return \"shopify\";\n }\n\n // Framework detection by dependencies\n if (deps.next) return \"nextjs\";\n if (deps[\"@remix-run/react\"]) return \"remix\";\n if (deps.nuxt) return \"nuxt\";\n if (deps.vue) return \"vue\";\n if (deps.svelte || deps[\"@sveltejs/kit\"]) return \"svelte\";\n if (deps.react && !deps.next) return \"react\";\n if (deps.hono) return \"hono\";\n if (deps.express) return \"express\";\n if (deps[\"@types/node\"] || pkg.type === \"module\") return \"node\";\n\n return \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\n// ============================================================================\n// Setup Plan Generation\n// ============================================================================\n\nasync function generateSetupPlans(\n projectPath: string,\n packageManager: PackageManager,\n isTypeScript: boolean,\n framework: FrameworkType,\n existing: ExistingConfigs,\n scripts: ExistingScripts,\n isMonorepo: boolean,\n): Promise<SetupPlan[]> {\n const plans: SetupPlan[] = [];\n\n // TypeScript setup/improvement\n if (isTypeScript) {\n plans.push(\n await planTypeScriptSetup(\n projectPath,\n framework,\n existing.typescript,\n isMonorepo,\n ),\n );\n }\n\n // ESLint setup/improvement\n plans.push(\n await planESLintSetup(projectPath, isTypeScript, framework, existing),\n );\n\n // Prettier setup/improvement\n plans.push(await planPrettierSetup(projectPath, existing.prettier));\n\n // Testing setup\n plans.push(\n await planTestingSetup(projectPath, isTypeScript, framework, existing),\n );\n\n // Build configuration (for non-framework TS projects)\n if (isTypeScript && ![\"nextjs\", \"remix\", \"nuxt\"].includes(framework)) {\n plans.push(await planBuildSetup(projectPath, scripts.build));\n }\n\n // Scripts setup\n plans.push(\n await planScriptsSetup(projectPath, isTypeScript, framework, scripts),\n );\n\n // Pre-commit hooks\n plans.push(await planHooksSetup(projectPath, existing));\n\n // GitHub Actions CI\n plans.push(\n await planCISetup(\n projectPath,\n packageManager,\n isTypeScript,\n framework,\n existing.githubActions,\n isMonorepo,\n ),\n );\n\n return plans;\n}\n\n// ============================================================================\n// Individual Plan Generators\n// ============================================================================\n\nasync function planTypeScriptSetup(\n projectPath: string,\n _framework: FrameworkType,\n hasExisting: boolean,\n isMonorepo: boolean,\n): Promise<SetupPlan> {\n const changes: ConfigChange[] = [];\n const devDeps: string[] = [];\n\n // Check if typescript is installed\n const pkg = await readPackageJson(projectPath);\n const deps = pkg.dependencies || {};\n const devDepsPkg = pkg.devDependencies || {};\n const allDeps = { ...deps, ...devDepsPkg };\n if (!allDeps.typescript) {\n devDeps.push(\"typescript\");\n }\n\n if (hasExisting) {\n // Audit existing config\n const tsconfig = await readTSConfig(join(projectPath, \"tsconfig.json\"));\n const opts = tsconfig.compilerOptions || {};\n\n // Recommend improvements\n if (!opts.strict) {\n changes.push({\n type: \"modify\",\n file: \"tsconfig.json\",\n key: \"compilerOptions.strict\",\n oldValue: opts.strict,\n newValue: true,\n description: \"Enable strict type checking\",\n });\n }\n if (!opts.skipLibCheck) {\n changes.push({\n type: \"modify\",\n file: \"tsconfig.json\",\n key: \"compilerOptions.skipLibCheck\",\n oldValue: opts.skipLibCheck,\n newValue: true,\n description:\n \"Skip type checking of declaration files for faster builds\",\n });\n }\n if (opts.target !== \"ES2022\" && opts.target !== \"ESNext\") {\n changes.push({\n type: \"modify\",\n file: \"tsconfig.json\",\n key: \"compilerOptions.target\",\n oldValue: opts.target,\n newValue: \"ES2022\",\n description: \"Use modern JavaScript target\",\n });\n }\n } else {\n changes.push({\n type: \"add\",\n file: isMonorepo ? \"tsconfig.base.json\" : \"tsconfig.json\",\n description: `Create TypeScript configuration${isMonorepo ? \" (shared base for monorepo)\" : \"\"}`,\n });\n }\n\n return {\n name: \"typescript\",\n description: hasExisting\n ? \"Improve TypeScript configuration\"\n : \"Set up TypeScript configuration\",\n priority: \"high\",\n changes,\n dependencies: [],\n devDependencies: devDeps,\n };\n}\n\nasync function planESLintSetup(\n projectPath: string,\n isTypeScript: boolean,\n framework: FrameworkType,\n existing: ExistingConfigs,\n): Promise<SetupPlan> {\n const changes: ConfigChange[] = [];\n const devDeps: string[] = [];\n\n const pkg = await readPackageJson(projectPath);\n const deps = pkg.dependencies || {};\n const devDepsPkg = pkg.devDependencies || {};\n const allDeps = { ...deps, ...devDepsPkg };\n\n // Core ESLint\n if (!allDeps.eslint) {\n devDeps.push(\"eslint\");\n }\n\n // TypeScript support\n if (isTypeScript) {\n if (!allDeps[\"@typescript-eslint/eslint-plugin\"]) {\n devDeps.push(\"@typescript-eslint/eslint-plugin\");\n }\n if (!allDeps[\"@typescript-eslint/parser\"]) {\n devDeps.push(\"@typescript-eslint/parser\");\n }\n if (!allDeps[\"typescript-eslint\"]) {\n devDeps.push(\"typescript-eslint\");\n }\n }\n\n // Framework-specific plugins\n if (framework === \"react\" || framework === \"nextjs\") {\n if (!allDeps[\"eslint-plugin-react\"]) devDeps.push(\"eslint-plugin-react\");\n if (!allDeps[\"eslint-plugin-react-hooks\"])\n devDeps.push(\"eslint-plugin-react-hooks\");\n }\n\n if (existing.eslint) {\n if (!existing.eslintFlat) {\n changes.push({\n type: \"modify\",\n file: \"eslint.config.mjs\",\n description: \"Migrate to ESLint 9 flat config format (recommended)\",\n });\n } else {\n changes.push({\n type: \"unchanged\",\n file: \"eslint.config.mjs\",\n description: \"ESLint flat config already exists\",\n });\n }\n } else {\n changes.push({\n type: \"add\",\n file: \"eslint.config.mjs\",\n description: \"Create ESLint configuration with TypeScript support\",\n });\n }\n\n return {\n name: \"eslint\",\n description: existing.eslint\n ? \"Audit ESLint configuration and dependencies\"\n : \"Set up ESLint for code linting\",\n priority: \"high\",\n changes,\n dependencies: [],\n devDependencies: devDeps,\n };\n}\n\nasync function planPrettierSetup(\n projectPath: string,\n hasExisting: boolean,\n): Promise<SetupPlan> {\n const changes: ConfigChange[] = [];\n const devDeps: string[] = [];\n\n const pkg = await readPackageJson(projectPath);\n const deps = pkg.dependencies || {};\n const devDepsPkg = pkg.devDependencies || {};\n const allDeps = { ...deps, ...devDepsPkg };\n\n if (!allDeps.prettier) {\n devDeps.push(\"prettier\");\n }\n\n if (hasExisting) {\n const prettierConfig = await readPrettierConfig(projectPath);\n // Check for recommended settings\n if (prettierConfig.printWidth === undefined) {\n changes.push({\n type: \"modify\",\n file: \".prettierrc\",\n key: \"printWidth\",\n newValue: 100,\n description: \"Add printWidth setting\",\n });\n }\n if (prettierConfig.trailingComma === undefined) {\n changes.push({\n type: \"modify\",\n file: \".prettierrc\",\n key: \"trailingComma\",\n newValue: \"es5\",\n description: \"Add trailing comma setting\",\n });\n }\n if (changes.length === 0) {\n changes.push({\n type: \"unchanged\",\n file: \".prettierrc\",\n description: \"Prettier configuration is complete\",\n });\n }\n } else {\n changes.push({\n type: \"add\",\n file: \".prettierrc\",\n description: \"Create Prettier configuration\",\n });\n changes.push({\n type: \"add\",\n file: \".prettierignore\",\n description: \"Create Prettier ignore file\",\n });\n }\n\n return {\n name: \"prettier\",\n description: hasExisting\n ? \"Audit Prettier configuration\"\n : \"Set up Prettier for code formatting\",\n priority: \"high\",\n changes,\n dependencies: [],\n devDependencies: devDeps,\n };\n}\n\nasync function planTestingSetup(\n projectPath: string,\n isTypeScript: boolean,\n framework: FrameworkType,\n existing: ExistingConfigs,\n): Promise<SetupPlan> {\n const changes: ConfigChange[] = [];\n const devDeps: string[] = [];\n\n const pkg = await readPackageJson(projectPath);\n const deps = pkg.dependencies || {};\n const devDepsPkg = pkg.devDependencies || {};\n const allDeps = { ...deps, ...devDepsPkg };\n\n // Respect existing Jest - don't force Vitest\n if (existing.jest) {\n changes.push({\n type: \"unchanged\",\n file: \"jest.config.*\",\n description: \"Jest configuration exists (preserving existing setup)\",\n });\n return {\n name: \"testing\",\n description: \"Jest testing already configured\",\n priority: \"high\",\n changes,\n dependencies: [],\n devDependencies: [],\n };\n }\n\n // Set up Vitest\n if (!allDeps.vitest) {\n devDeps.push(\"vitest\");\n }\n if (!allDeps[\"@vitest/coverage-v8\"]) {\n devDeps.push(\"@vitest/coverage-v8\");\n }\n\n // DOM testing for frontend frameworks\n if ([\"react\", \"nextjs\", \"vue\", \"nuxt\", \"svelte\"].includes(framework)) {\n if (!allDeps.jsdom) devDeps.push(\"jsdom\");\n if (framework === \"react\" || framework === \"nextjs\") {\n if (!allDeps[\"@testing-library/react\"])\n devDeps.push(\"@testing-library/react\");\n }\n }\n\n if (existing.vitest) {\n changes.push({\n type: \"unchanged\",\n file: `vitest.config.${isTypeScript ? \"ts\" : \"js\"}`,\n description: \"Vitest configuration already exists\",\n });\n } else {\n changes.push({\n type: \"add\",\n file: `vitest.config.${isTypeScript ? \"ts\" : \"js\"}`,\n description: \"Create Vitest configuration\",\n });\n }\n\n return {\n name: \"testing\",\n description: existing.vitest\n ? \"Audit Vitest dependencies\"\n : \"Set up Vitest for testing\",\n priority: \"high\",\n changes,\n dependencies: [],\n devDependencies: devDeps,\n };\n}\n\nasync function planBuildSetup(\n projectPath: string,\n hasBuildScript: boolean,\n): Promise<SetupPlan> {\n const changes: ConfigChange[] = [];\n const devDeps: string[] = [];\n\n const pkg = await readPackageJson(projectPath);\n const deps = pkg.dependencies || {};\n const devDepsPkg = pkg.devDependencies || {};\n const allDeps = { ...deps, ...devDepsPkg };\n\n if (hasBuildScript) {\n changes.push({\n type: \"unchanged\",\n file: \"package.json\",\n key: \"scripts.build\",\n description: \"Build script already configured\",\n });\n } else {\n if (!allDeps.tsup) {\n devDeps.push(\"tsup\");\n }\n changes.push({\n type: \"add\",\n file: \"tsup.config.ts\",\n description: \"Create tsup build configuration\",\n });\n }\n\n return {\n name: \"build\",\n description: hasBuildScript\n ? \"Build configuration exists\"\n : \"Set up tsup for TypeScript builds\",\n priority: \"medium\",\n changes,\n dependencies: [],\n devDependencies: devDeps,\n };\n}\n\nasync function planScriptsSetup(\n _projectPath: string,\n isTypeScript: boolean,\n _framework: FrameworkType,\n scripts: ExistingScripts,\n): Promise<SetupPlan> {\n const changes: ConfigChange[] = [];\n const scriptsToAdd: Record<string, string> = {};\n\n if (!scripts.lint) {\n scriptsToAdd.lint = \"eslint src\";\n changes.push({\n type: \"add\",\n file: \"package.json\",\n key: \"scripts.lint\",\n newValue: \"eslint src\",\n description: \"Add lint script\",\n });\n }\n\n if (!scripts.format) {\n scriptsToAdd.format = 'prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"';\n changes.push({\n type: \"add\",\n file: \"package.json\",\n key: \"scripts.format\",\n newValue: scriptsToAdd.format,\n description: \"Add format script\",\n });\n }\n\n if (isTypeScript && !scripts.typecheck) {\n scriptsToAdd.typecheck = \"tsc --noEmit\";\n changes.push({\n type: \"add\",\n file: \"package.json\",\n key: \"scripts.typecheck\",\n newValue: \"tsc --noEmit\",\n description: \"Add typecheck script\",\n });\n }\n\n if (!scripts.test) {\n scriptsToAdd.test = \"vitest run\";\n changes.push({\n type: \"add\",\n file: \"package.json\",\n key: \"scripts.test\",\n newValue: \"vitest run\",\n description: \"Add test script\",\n });\n }\n\n if (!scripts.verify) {\n scriptsToAdd.verify = \"workflow-agent verify\";\n changes.push({\n type: \"add\",\n file: \"package.json\",\n key: \"scripts.verify\",\n newValue: \"workflow-agent verify\",\n description: \"Add verify script\",\n });\n }\n\n if (Object.keys(scriptsToAdd).length === 0) {\n changes.push({\n type: \"unchanged\",\n file: \"package.json\",\n description: \"All standard scripts already configured\",\n });\n }\n\n return {\n name: \"scripts\",\n description: \"Configure npm scripts\",\n priority: \"medium\",\n changes,\n dependencies: [],\n devDependencies: [],\n };\n}\n\nasync function planHooksSetup(\n projectPath: string,\n existing: ExistingConfigs,\n): Promise<SetupPlan> {\n const changes: ConfigChange[] = [];\n const devDeps: string[] = [];\n\n const pkg = await readPackageJson(projectPath);\n const deps = pkg.dependencies || {};\n const devDepsPkg = pkg.devDependencies || {};\n const allDeps = { ...deps, ...devDepsPkg };\n\n // Prefer simple-git-hooks over husky\n if (!allDeps[\"simple-git-hooks\"]) {\n devDeps.push(\"simple-git-hooks\");\n }\n if (!allDeps[\"lint-staged\"]) {\n devDeps.push(\"lint-staged\");\n }\n\n if (existing.husky || existing.simpleGitHooks) {\n changes.push({\n type: \"modify\",\n file: \"package.json\",\n key: \"simple-git-hooks\",\n description: \"Ensure pre-commit hook configuration\",\n });\n } else {\n changes.push({\n type: \"add\",\n file: \"package.json\",\n key: \"simple-git-hooks\",\n newValue: { \"pre-commit\": \"npx lint-staged\" },\n description: \"Add pre-commit hook configuration\",\n });\n changes.push({\n type: \"add\",\n file: \"package.json\",\n key: \"lint-staged\",\n description: \"Add lint-staged configuration\",\n });\n }\n\n return {\n name: \"hooks\",\n description:\n existing.husky || existing.simpleGitHooks\n ? \"Audit pre-commit hooks\"\n : \"Set up pre-commit hooks\",\n priority: \"medium\",\n changes,\n dependencies: [],\n devDependencies: devDeps,\n };\n}\n\nasync function planCISetup(\n projectPath: string,\n _packageManager: PackageManager,\n _isTypeScript: boolean,\n _framework: FrameworkType,\n hasExisting: boolean,\n _isMonorepo: boolean,\n): Promise<SetupPlan> {\n const changes: ConfigChange[] = [];\n\n if (hasExisting) {\n // Check if ci.yml exists specifically\n if (existsSync(join(projectPath, \".github/workflows/ci.yml\"))) {\n changes.push({\n type: \"unchanged\",\n file: \".github/workflows/ci.yml\",\n description: \"CI workflow already exists\",\n });\n } else {\n changes.push({\n type: \"add\",\n file: \".github/workflows/ci.yml\",\n description: \"Add CI workflow (other workflows exist)\",\n });\n }\n } else {\n changes.push({\n type: \"add\",\n file: \".github/workflows/ci.yml\",\n description: \"Create GitHub Actions CI workflow\",\n });\n }\n\n return {\n name: \"ci\",\n description: hasExisting\n ? \"Audit CI configuration\"\n : \"Set up GitHub Actions CI\",\n priority: \"low\",\n changes,\n dependencies: [],\n devDependencies: [],\n };\n}\n\n// ============================================================================\n// Audit Report Generation\n// ============================================================================\n\n/**\n * Generate a comprehensive audit report\n */\nexport async function generateAuditReport(\n projectPath: string = process.cwd(),\n): Promise<AuditReport> {\n const analysis = await analyzeProject(projectPath);\n\n // Collect all dependencies across plans\n const allDeps = new Set<string>();\n const allDevDeps = new Set<string>();\n\n for (const plan of analysis.setupPlans) {\n plan.dependencies.forEach((d) => allDeps.add(d));\n plan.devDependencies.forEach((d) => allDevDeps.add(d));\n }\n\n // Count total changes\n const totalChanges = analysis.setupPlans.reduce(\n (sum, plan) =>\n sum + plan.changes.filter((c) => c.type !== \"unchanged\").length,\n 0,\n );\n\n return {\n analysis,\n totalChanges,\n allDependencies: Array.from(allDeps),\n allDevDependencies: Array.from(allDevDeps),\n plans: analysis.setupPlans,\n };\n}\n\n/**\n * Format audit report for console display\n */\nexport function formatAuditReport(report: AuditReport): string {\n const lines: string[] = [];\n\n lines.push(\"📋 Auto-Setup Audit Report\\n\");\n lines.push(`Framework: ${report.analysis.framework}`);\n lines.push(`Package Manager: ${report.analysis.packageManager}`);\n lines.push(`TypeScript: ${report.analysis.isTypeScript ? \"Yes\" : \"No\"}`);\n lines.push(`Monorepo: ${report.analysis.isMonorepo ? \"Yes\" : \"No\"}\\n`);\n\n for (const plan of report.plans) {\n const hasChanges = plan.changes.some((c) => c.type !== \"unchanged\");\n const icon = hasChanges ? \"🔧\" : \"✓\";\n lines.push(\n `${icon} ${plan.name.charAt(0).toUpperCase() + plan.name.slice(1)}`,\n );\n\n for (const change of plan.changes) {\n const symbol =\n change.type === \"add\" ? \"+\" : change.type === \"modify\" ? \"~\" : \"=\";\n\n let line = ` ${symbol} ${change.description}`;\n if (\n change.key &&\n change.oldValue !== undefined &&\n change.newValue !== undefined\n ) {\n line += ` (${String(change.oldValue)} → ${String(change.newValue)})`;\n }\n lines.push(line);\n }\n\n if (plan.devDependencies.length > 0) {\n lines.push(` 📦 Install: ${plan.devDependencies.join(\", \")}`);\n }\n lines.push(\"\");\n }\n\n if (report.allDevDependencies.length > 0) {\n lines.push(\"Dependencies to install (batched):\");\n const pm = report.analysis.packageManager;\n const cmd =\n pm === \"npm\" ? \"npm install\" : pm === \"yarn\" ? \"yarn add\" : `${pm} add`;\n lines.push(` ${cmd} -D ${report.allDevDependencies.join(\" \")}`);\n lines.push(\"\");\n }\n\n lines.push(`Total changes: ${report.totalChanges}`);\n\n return lines.join(\"\\n\");\n}\n\n// ============================================================================\n// Setup Execution\n// ============================================================================\n\n/**\n * Execute all setup plans\n */\nexport async function runAllSetups(\n projectPath: string = process.cwd(),\n onProgress?: (step: string, status: \"start\" | \"done\" | \"error\") => void,\n): Promise<SetupResult[]> {\n const report = await generateAuditReport(projectPath);\n const results: SetupResult[] = [];\n const filesCreated: string[] = [];\n const filesUpdated: string[] = [];\n\n // Step 1: Batch install all dependencies\n if (report.allDevDependencies.length > 0) {\n onProgress?.(\"Installing dependencies\", \"start\");\n try {\n await installDependencies(\n projectPath,\n report.analysis.packageManager,\n report.allDevDependencies,\n );\n onProgress?.(\"Installing dependencies\", \"done\");\n } catch (error) {\n onProgress?.(\"Installing dependencies\", \"error\");\n results.push({\n success: false,\n name: \"dependencies\",\n message: `Failed to install: ${error instanceof Error ? error.message : String(error)}`,\n filesCreated: [],\n filesUpdated: [],\n packagesInstalled: [],\n });\n return results;\n }\n }\n\n // Step 2: Apply each setup\n for (const plan of report.plans) {\n const hasChanges = plan.changes.some((c) => c.type !== \"unchanged\");\n if (!hasChanges && plan.devDependencies.length === 0) continue;\n\n onProgress?.(`Setting up ${plan.name}`, \"start\");\n\n try {\n const result = await applySetupPlan(projectPath, plan, report.analysis);\n results.push(result);\n filesCreated.push(...result.filesCreated);\n filesUpdated.push(...result.filesUpdated);\n onProgress?.(`Setting up ${plan.name}`, \"done\");\n } catch (error) {\n onProgress?.(`Setting up ${plan.name}`, \"error\");\n results.push({\n success: false,\n name: plan.name,\n message: `Failed: ${error instanceof Error ? error.message : String(error)}`,\n filesCreated: [],\n filesUpdated: [],\n packagesInstalled: [],\n });\n }\n }\n\n // Step 3: Initialize git hooks\n onProgress?.(\"Initializing git hooks\", \"start\");\n try {\n await execa(\"npx\", [\"simple-git-hooks\"], {\n cwd: projectPath,\n stdio: \"pipe\",\n });\n onProgress?.(\"Initializing git hooks\", \"done\");\n } catch {\n // May fail if not in a git repo\n onProgress?.(\"Initializing git hooks\", \"error\");\n }\n\n return results;\n}\n\nasync function installDependencies(\n projectPath: string,\n packageManager: PackageManager,\n packages: string[],\n): Promise<void> {\n if (packages.length === 0) return;\n\n const commands: Record<PackageManager, { cmd: string; args: string[] }> = {\n npm: { cmd: \"npm\", args: [\"install\", \"--save-dev\"] },\n pnpm: { cmd: \"pnpm\", args: [\"add\", \"-D\"] },\n yarn: { cmd: \"yarn\", args: [\"add\", \"-D\"] },\n bun: { cmd: \"bun\", args: [\"add\", \"-D\"] },\n };\n\n const { cmd, args } = commands[packageManager];\n await execa(cmd, [...args, ...packages], {\n cwd: projectPath,\n stdio: \"pipe\",\n });\n}\n\nasync function applySetupPlan(\n projectPath: string,\n plan: SetupPlan,\n analysis: ProjectAnalysis,\n): Promise<SetupResult> {\n const filesCreated: string[] = [];\n const filesUpdated: string[] = [];\n\n switch (plan.name) {\n case \"typescript\":\n await applyTypeScriptSetup(\n projectPath,\n analysis,\n filesCreated,\n filesUpdated,\n );\n break;\n case \"eslint\":\n await applyESLintSetup(projectPath, analysis, filesCreated, filesUpdated);\n break;\n case \"prettier\":\n await applyPrettierSetup(projectPath, filesCreated, filesUpdated);\n break;\n case \"testing\":\n await applyTestingSetup(\n projectPath,\n analysis,\n filesCreated,\n filesUpdated,\n );\n break;\n case \"build\":\n await applyBuildSetup(projectPath, filesCreated, filesUpdated);\n break;\n case \"scripts\":\n await applyScriptsSetup(projectPath, analysis, filesUpdated);\n break;\n case \"hooks\":\n await applyHooksSetup(projectPath, filesUpdated);\n break;\n case \"ci\":\n await applyCISetup(projectPath, analysis, filesCreated, filesUpdated);\n break;\n }\n\n return {\n success: true,\n name: plan.name,\n message: `${plan.name} configured successfully`,\n filesCreated,\n filesUpdated,\n packagesInstalled: plan.devDependencies,\n };\n}\n\n// ============================================================================\n// Setup Application Functions\n// ============================================================================\n\nasync function applyTypeScriptSetup(\n projectPath: string,\n analysis: ProjectAnalysis,\n filesCreated: string[],\n filesUpdated: string[],\n): Promise<void> {\n const configName = analysis.isMonorepo\n ? \"tsconfig.base.json\"\n : \"tsconfig.json\";\n const configPath = join(projectPath, configName);\n\n let tsconfig: Record<string, unknown> = {};\n\n if (existsSync(configPath)) {\n tsconfig = await readJsonFile(configPath);\n filesUpdated.push(configName);\n } else {\n filesCreated.push(configName);\n }\n\n // Ensure compilerOptions\n if (!tsconfig.compilerOptions) {\n tsconfig.compilerOptions = {};\n }\n const opts = tsconfig.compilerOptions as Record<string, unknown>;\n\n // Apply improvements (merge with existing)\n const improvements: Record<string, unknown> = {\n target: opts.target || \"ES2022\",\n module: opts.module || \"ESNext\",\n moduleResolution: opts.moduleResolution || \"bundler\",\n esModuleInterop: opts.esModuleInterop ?? true,\n strict: opts.strict ?? true,\n skipLibCheck: opts.skipLibCheck ?? true,\n resolveJsonModule: opts.resolveJsonModule ?? true,\n isolatedModules: opts.isolatedModules ?? true,\n declaration: opts.declaration ?? true,\n declarationMap: opts.declarationMap ?? true,\n sourceMap: opts.sourceMap ?? true,\n };\n\n // Framework-specific options\n const frameworkOpts = getFrameworkTsOptions(analysis.framework);\n\n tsconfig.compilerOptions = { ...opts, ...improvements, ...frameworkOpts };\n\n // Ensure include/exclude\n if (!tsconfig.include) {\n tsconfig.include = [\"src/**/*\"];\n }\n if (!tsconfig.exclude) {\n tsconfig.exclude = [\"node_modules\", \"dist\", \"coverage\"];\n }\n\n await writeFile(configPath, JSON.stringify(tsconfig, null, 2) + \"\\n\");\n}\n\nfunction getFrameworkTsOptions(\n framework: FrameworkType,\n): Record<string, unknown> {\n switch (framework) {\n case \"nextjs\":\n return {\n lib: [\"dom\", \"dom.iterable\", \"esnext\"],\n jsx: \"preserve\",\n incremental: true,\n plugins: [{ name: \"next\" }],\n };\n case \"react\":\n case \"remix\":\n return {\n lib: [\"dom\", \"dom.iterable\", \"esnext\"],\n jsx: \"react-jsx\",\n };\n case \"vue\":\n case \"nuxt\":\n return {\n lib: [\"esnext\", \"dom\"],\n jsx: \"preserve\",\n };\n default:\n return {};\n }\n}\n\nasync function applyESLintSetup(\n projectPath: string,\n analysis: ProjectAnalysis,\n filesCreated: string[],\n _filesUpdated: string[],\n): Promise<void> {\n // Only create new config if no flat config exists\n if (analysis.existing.eslintFlat) {\n return;\n }\n\n const configPath = join(projectPath, \"eslint.config.mjs\");\n const config = generateESLintFlatConfig(\n analysis.isTypeScript,\n analysis.framework,\n );\n\n await writeFile(configPath, config);\n filesCreated.push(\"eslint.config.mjs\");\n}\n\nfunction generateESLintFlatConfig(\n isTypeScript: boolean,\n framework: FrameworkType,\n): string {\n const imports: string[] = [];\n const configs: string[] = [];\n\n if (isTypeScript) {\n imports.push(`import tseslint from \"typescript-eslint\";`);\n }\n\n // Add react plugin import if needed\n if (framework === \"react\" || framework === \"nextjs\") {\n imports.push(`import react from \"eslint-plugin-react\";`);\n imports.push(`import reactHooks from \"eslint-plugin-react-hooks\";`);\n }\n\n // Base config\n if (isTypeScript) {\n configs.push(` ...tseslint.configs.recommended`);\n }\n\n configs.push(` {\n files: [\"**/*.${isTypeScript ? \"{ts,tsx}\" : \"{js,jsx}\"}\"],\n rules: {\n ${isTypeScript ? `\"@typescript-eslint/no-unused-vars\": [\"error\", { argsIgnorePattern: \"^_\" }],` : \"\"}\n \"no-console\": \"warn\",\n },\n }`);\n\n configs.push(` {\n ignores: [\"dist/\", \"node_modules/\", \"coverage/\", \".next/\", \"build/\"],\n }`);\n\n return `${imports.join(\"\\n\")}\n\nexport default [\n${configs.join(\",\\n\")}\n];\n`;\n}\n\nasync function applyPrettierSetup(\n projectPath: string,\n filesCreated: string[],\n filesUpdated: string[],\n): Promise<void> {\n const prettierPath = join(projectPath, \".prettierrc\");\n\n let config: Record<string, unknown> = {\n semi: true,\n singleQuote: false,\n tabWidth: 2,\n trailingComma: \"es5\",\n printWidth: 100,\n bracketSpacing: true,\n };\n\n if (existsSync(prettierPath)) {\n const existing = await readPrettierConfig(projectPath);\n config = { ...config, ...existing };\n filesUpdated.push(\".prettierrc\");\n } else {\n filesCreated.push(\".prettierrc\");\n }\n\n await writeFile(prettierPath, JSON.stringify(config, null, 2) + \"\\n\");\n\n // Create .prettierignore if it doesn't exist\n const ignorePath = join(projectPath, \".prettierignore\");\n if (!existsSync(ignorePath)) {\n const ignoreContent = `dist/\nnode_modules/\ncoverage/\n.next/\nbuild/\n*.min.js\npnpm-lock.yaml\npackage-lock.json\nyarn.lock\n`;\n await writeFile(ignorePath, ignoreContent);\n filesCreated.push(\".prettierignore\");\n }\n}\n\nasync function applyTestingSetup(\n projectPath: string,\n analysis: ProjectAnalysis,\n filesCreated: string[],\n _filesUpdated: string[],\n): Promise<void> {\n // Skip if jest exists or vitest already configured\n if (analysis.existing.jest || analysis.existing.vitest) {\n return;\n }\n\n const ext = analysis.isTypeScript ? \"ts\" : \"js\";\n const configPath = join(projectPath, `vitest.config.${ext}`);\n\n const environment = [\"react\", \"nextjs\", \"vue\", \"nuxt\", \"svelte\"].includes(\n analysis.framework,\n )\n ? \"jsdom\"\n : \"node\";\n\n const config = `import { defineConfig } from \"vitest/config\";\n\nexport default defineConfig({\n test: {\n globals: true,\n environment: \"${environment}\",\n coverage: {\n provider: \"v8\",\n reporter: [\"text\", \"json\", \"html\"],\n exclude: [\"node_modules/\", \"dist/\", \"**/*.test.${ext}\"],\n },\n include: [\"src/**/*.test.${ext}\", \"tests/**/*.test.${ext}\"],\n },\n});\n`;\n\n await writeFile(configPath, config);\n filesCreated.push(`vitest.config.${ext}`);\n}\n\nasync function applyBuildSetup(\n projectPath: string,\n filesCreated: string[],\n _filesUpdated: string[],\n): Promise<void> {\n const configPath = join(projectPath, \"tsup.config.ts\");\n\n if (existsSync(configPath)) {\n return;\n }\n\n const config = `import { defineConfig } from \"tsup\";\n\nexport default defineConfig({\n entry: [\"src/index.ts\"],\n format: [\"esm\"],\n dts: true,\n clean: true,\n sourcemap: true,\n});\n`;\n\n await writeFile(configPath, config);\n filesCreated.push(\"tsup.config.ts\");\n}\n\nasync function applyScriptsSetup(\n projectPath: string,\n analysis: ProjectAnalysis,\n filesUpdated: string[],\n): Promise<void> {\n const pkgPath = join(projectPath, \"package.json\");\n const pkg = await readPackageJson(projectPath);\n const scripts = pkg.scripts || {};\n\n // Add missing scripts (don't overwrite)\n const scriptsToAdd: Record<string, string> = {\n lint: \"eslint src\",\n \"lint:fix\": \"eslint src --fix\",\n format: 'prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"',\n \"format:check\": 'prettier --check \"src/**/*.{ts,tsx,js,jsx,json}\"',\n test: \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n verify: \"workflow-agent verify\",\n \"verify:fix\": \"workflow-agent verify --fix\",\n \"pre-commit\": \"workflow-agent verify --fix\",\n };\n\n if (analysis.isTypeScript) {\n scriptsToAdd.typecheck = \"tsc --noEmit\";\n }\n\n let added = false;\n for (const [name, cmd] of Object.entries(scriptsToAdd)) {\n if (!scripts[name]) {\n scripts[name] = cmd;\n added = true;\n }\n }\n\n if (added) {\n pkg.scripts = scripts;\n await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n filesUpdated.push(\"package.json\");\n }\n}\n\nasync function applyHooksSetup(\n projectPath: string,\n filesUpdated: string[],\n): Promise<void> {\n const pkgPath = join(projectPath, \"package.json\");\n const pkg = await readPackageJson(projectPath);\n\n // Add simple-git-hooks config\n if (!pkg[\"simple-git-hooks\"]) {\n pkg[\"simple-git-hooks\"] = {\n \"pre-commit\": \"npx lint-staged\",\n };\n }\n\n // Add lint-staged config\n if (!pkg[\"lint-staged\"]) {\n pkg[\"lint-staged\"] = {\n \"*.{ts,tsx,js,jsx}\": [\"eslint --fix\", \"prettier --write\"],\n \"*.{json,md,yml,yaml}\": [\"prettier --write\"],\n };\n }\n\n await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n filesUpdated.push(\"package.json\");\n}\n\nasync function applyCISetup(\n projectPath: string,\n analysis: ProjectAnalysis,\n filesCreated: string[],\n _filesUpdated: string[],\n): Promise<void> {\n const workflowsDir = join(projectPath, \".github/workflows\");\n await mkdir(workflowsDir, { recursive: true });\n\n const ciPath = join(workflowsDir, \"ci.yml\");\n\n if (existsSync(ciPath)) {\n return;\n }\n\n const workflow = generateCIWorkflow(\n analysis.packageManager,\n analysis.isTypeScript,\n analysis.framework,\n analysis.isMonorepo,\n );\n\n await writeFile(ciPath, workflow);\n filesCreated.push(\".github/workflows/ci.yml\");\n}\n\nfunction generateCIWorkflow(\n packageManager: PackageManager,\n isTypeScript: boolean,\n framework: FrameworkType,\n _isMonorepo: boolean,\n): string {\n const runCmd =\n packageManager === \"npm\"\n ? \"npm run\"\n : packageManager === \"yarn\"\n ? \"yarn\"\n : packageManager;\n const isPnpm = packageManager === \"pnpm\";\n\n return `name: CI\n\non:\n push:\n branches: [main, master]\n pull_request:\n branches: [main, master]\n\njobs:\n ci:\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: \"20\"\n${\n isPnpm\n ? `\n - name: Install pnpm\n uses: pnpm/action-setup@v4\n with:\n version: 9\n`\n : \"\"\n}\n - name: Install dependencies\n run: ${packageManager} install\n\n${\n isTypeScript\n ? ` - name: Type check\n run: ${runCmd} typecheck\n\n`\n : \"\"\n} - name: Lint\n run: ${runCmd} lint\n\n - name: Format check\n run: ${runCmd} format:check || true\n\n - name: Test\n run: ${runCmd} test\n${\n isTypeScript && ![\"nextjs\", \"remix\", \"nuxt\"].includes(framework)\n ? `\n - name: Build\n run: ${runCmd} build\n`\n : \"\"\n}`;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nasync function readPackageJson(projectPath: string): Promise<PackageJson> {\n const pkgPath = join(projectPath, \"package.json\");\n if (!existsSync(pkgPath)) {\n return {};\n }\n return JSON.parse(await readFile(pkgPath, \"utf-8\")) as PackageJson;\n}\n\nasync function readTSConfig(filePath: string): Promise<TSConfig> {\n if (!existsSync(filePath)) {\n return {};\n }\n return JSON.parse(await readFile(filePath, \"utf-8\")) as TSConfig;\n}\n\nasync function readJsonFile(\n filePath: string,\n): Promise<Record<string, unknown>> {\n if (!existsSync(filePath)) {\n return {};\n }\n return JSON.parse(await readFile(filePath, \"utf-8\"));\n}\n\nasync function readPrettierConfig(\n projectPath: string,\n): Promise<Record<string, unknown>> {\n const files = [\".prettierrc\", \".prettierrc.json\", \"prettier.config.js\"];\n\n for (const file of files) {\n const filePath = join(projectPath, file);\n if (existsSync(filePath)) {\n if (file.endsWith(\".js\")) {\n return {}; // Can't easily read JS config\n }\n try {\n return JSON.parse(await readFile(filePath, \"utf-8\"));\n } catch {\n return {};\n }\n }\n }\n\n return {};\n}\n","/**\n * Git repository utilities for detecting repository info,\n * package manager, monorepo setup, and GitHub remote\n */\n\nimport { execa } from \"execa\";\nimport { existsSync } from \"fs\";\nimport { readFile } from \"fs/promises\";\nimport { join } from \"path\";\n\nexport type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport interface GitHubInfo {\n owner: string;\n repo: string;\n}\n\nexport interface RepoInfo {\n isGitRepo: boolean;\n remoteUrl: string | null;\n isGitHub: boolean;\n github: GitHubInfo | null;\n defaultBranch: string | null;\n}\n\nexport interface ProjectInfo {\n packageManager: PackageManager;\n isMonorepo: boolean;\n hasLintScript: boolean;\n hasTypecheckScript: boolean;\n hasFormatScript: boolean;\n hasTestScript: boolean;\n hasBuildScript: boolean;\n}\n\n/**\n * Check if the current directory is a git repository\n */\nexport async function isGitRepo(\n projectPath: string = process.cwd(),\n): Promise<boolean> {\n try {\n await execa(\"git\", [\"rev-parse\", \"--git-dir\"], { cwd: projectPath });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get the git remote URL for origin\n */\nexport async function getGitRemoteUrl(\n projectPath: string = process.cwd(),\n): Promise<string | null> {\n try {\n const { stdout } = await execa(\"git\", [\"remote\", \"get-url\", \"origin\"], {\n cwd: projectPath,\n });\n return stdout.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if the remote URL is a GitHub repository\n */\nexport function isGitHubRemote(remoteUrl: string | null): boolean {\n if (!remoteUrl) return false;\n return remoteUrl.includes(\"github.com\");\n}\n\n/**\n * Parse GitHub owner and repo from remote URL\n * Supports both SSH (git@github.com:owner/repo.git) and HTTPS (https://github.com/owner/repo.git)\n */\nexport function parseGitHubUrl(remoteUrl: string | null): GitHubInfo | null {\n if (!remoteUrl || !isGitHubRemote(remoteUrl)) return null;\n\n // Match: git@github.com:owner/repo.git or https://github.com/owner/repo.git\n const match = remoteUrl.match(/github\\.com[:/]([^/]+)\\/([^/.]+)/);\n\n if (match) {\n return {\n owner: match[1],\n repo: match[2].replace(/\\.git$/, \"\"),\n };\n }\n\n return null;\n}\n\n/**\n * Get the default branch name\n */\nexport async function getDefaultBranch(\n projectPath: string = process.cwd(),\n): Promise<string | null> {\n try {\n // Try to get from remote\n const { stdout } = await execa(\n \"git\",\n [\"symbolic-ref\", \"refs/remotes/origin/HEAD\"],\n {\n cwd: projectPath,\n },\n );\n return stdout.trim().replace(\"refs/remotes/origin/\", \"\") || \"main\";\n } catch {\n // Fallback: try HEAD\n try {\n const { stdout } = await execa(\n \"git\",\n [\"rev-parse\", \"--abbrev-ref\", \"HEAD\"],\n {\n cwd: projectPath,\n },\n );\n return stdout.trim() || \"main\";\n } catch {\n return \"main\";\n }\n }\n}\n\n/**\n * Get comprehensive repository information\n */\nexport async function getRepoInfo(\n projectPath: string = process.cwd(),\n): Promise<RepoInfo> {\n const isRepo = await isGitRepo(projectPath);\n\n if (!isRepo) {\n return {\n isGitRepo: false,\n remoteUrl: null,\n isGitHub: false,\n github: null,\n defaultBranch: null,\n };\n }\n\n const remoteUrl = await getGitRemoteUrl(projectPath);\n const isGitHub = isGitHubRemote(remoteUrl);\n const github = parseGitHubUrl(remoteUrl);\n const defaultBranch = await getDefaultBranch(projectPath);\n\n return {\n isGitRepo: true,\n remoteUrl,\n isGitHub,\n github,\n defaultBranch,\n };\n}\n\n/**\n * Detect the package manager used in the project\n */\nexport async function detectPackageManager(\n projectPath: string = process.cwd(),\n): Promise<PackageManager> {\n // Check for lockfiles in order of preference\n if (existsSync(join(projectPath, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n }\n if (existsSync(join(projectPath, \"yarn.lock\"))) {\n return \"yarn\";\n }\n if (existsSync(join(projectPath, \"bun.lockb\"))) {\n return \"bun\";\n }\n if (existsSync(join(projectPath, \"package-lock.json\"))) {\n return \"npm\";\n }\n\n // Check packageManager field in package.json\n try {\n const pkgPath = join(projectPath, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n if (pkg.packageManager) {\n if (pkg.packageManager.startsWith(\"pnpm\")) return \"pnpm\";\n if (pkg.packageManager.startsWith(\"yarn\")) return \"yarn\";\n if (pkg.packageManager.startsWith(\"bun\")) return \"bun\";\n }\n }\n } catch {\n // Ignore parse errors\n }\n\n // Default to npm\n return \"npm\";\n}\n\n/**\n * Check if the project is a monorepo\n */\nexport async function isMonorepo(\n projectPath: string = process.cwd(),\n): Promise<boolean> {\n // Check for pnpm workspace\n if (existsSync(join(projectPath, \"pnpm-workspace.yaml\"))) {\n return true;\n }\n\n // Check for yarn/npm workspaces in package.json\n try {\n const pkgPath = join(projectPath, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n if (pkg.workspaces) {\n return true;\n }\n }\n } catch {\n // Ignore parse errors\n }\n\n // Check for lerna.json\n if (existsSync(join(projectPath, \"lerna.json\"))) {\n return true;\n }\n\n // Check for nx.json\n if (existsSync(join(projectPath, \"nx.json\"))) {\n return true;\n }\n\n // Check for turbo.json\n if (existsSync(join(projectPath, \"turbo.json\"))) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Get available scripts from package.json\n */\nexport async function getPackageScripts(\n projectPath: string = process.cwd(),\n): Promise<Record<string, string>> {\n try {\n const pkgPath = join(projectPath, \"package.json\");\n if (!existsSync(pkgPath)) {\n return {};\n }\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n return pkg.scripts || {};\n } catch {\n return {};\n }\n}\n\n/**\n * Get comprehensive project information\n */\nexport async function getProjectInfo(\n projectPath: string = process.cwd(),\n): Promise<ProjectInfo> {\n const packageManager = await detectPackageManager(projectPath);\n const monorepo = await isMonorepo(projectPath);\n const scripts = await getPackageScripts(projectPath);\n\n return {\n packageManager,\n isMonorepo: monorepo,\n hasLintScript: \"lint\" in scripts,\n hasTypecheckScript: \"typecheck\" in scripts || \"type-check\" in scripts,\n hasFormatScript: \"format\" in scripts || \"format:check\" in scripts,\n hasTestScript: \"test\" in scripts,\n hasBuildScript: \"build\" in scripts,\n };\n}\n\n/**\n * Get the install command for a package manager\n */\nexport function getInstallCommand(packageManager: PackageManager): string {\n switch (packageManager) {\n case \"pnpm\":\n return \"pnpm install --frozen-lockfile\";\n case \"yarn\":\n return \"yarn install --frozen-lockfile\";\n case \"bun\":\n return \"bun install --frozen-lockfile\";\n case \"npm\":\n default:\n return \"npm ci\";\n }\n}\n\n/**\n * Get the run command for a package manager (handles monorepo -r flag for pnpm)\n */\nexport function getRunCommand(\n packageManager: PackageManager,\n script: string,\n isMonorepo: boolean = false,\n): string {\n switch (packageManager) {\n case \"pnpm\":\n return isMonorepo ? `pnpm -r run ${script}` : `pnpm run ${script}`;\n case \"yarn\":\n return isMonorepo\n ? `yarn workspaces run ${script}`\n : `yarn run ${script}`;\n case \"bun\":\n return `bun run ${script}`;\n case \"npm\":\n default:\n return isMonorepo\n ? `npm run ${script} --workspaces --if-present`\n : `npm run ${script}`;\n }\n}\n"],"mappings":"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","names":["existsSync","readFile","join","execa","existsSync","join","readFile","isMonorepo","execa"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/auto-fix.ts","../src/config/schema.ts"],"sourcesContent":["/**\n * Configuration Auto-Fix Utilities\n *\n * Provides automatic resolution for common configuration validation errors\n * such as reserved scope names and short descriptions.\n */\n\nimport { writeFile, readFile } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { z } from \"zod\";\nimport { WorkflowConfigSchema } from \"./schema.js\";\n\n// Suggested replacements for reserved names\nconst RESERVED_NAME_REPLACEMENTS: Record<string, string> = {\n init: \"setup\",\n create: \"add\",\n build: \"compile\",\n test: \"testing\",\n config: \"settings\",\n docs: \"documentation\",\n ci: \"pipeline\",\n deps: \"dependencies\",\n};\n\nexport interface ConfigValidationIssue {\n path: string;\n code: string;\n message: string;\n currentValue?: unknown;\n suggestedFix?: {\n description: string;\n newValue: unknown;\n };\n}\n\nexport interface ConfigLoadResult {\n config: z.infer<typeof WorkflowConfigSchema> | null;\n rawConfig: unknown;\n configPath: string | null;\n issues: ConfigValidationIssue[];\n valid: boolean;\n}\n\nexport interface AutoFixResult {\n fixed: boolean;\n changes: string[];\n newConfig: unknown;\n}\n\n/**\n * Analyze a Zod error and generate fix suggestions\n */\nexport function analyzeValidationError(\n error: z.ZodError,\n rawConfig: unknown,\n): ConfigValidationIssue[] {\n const issues: ConfigValidationIssue[] = [];\n\n for (const err of error.errors) {\n const pathStr = err.path.join(\".\");\n const issue: ConfigValidationIssue = {\n path: pathStr,\n code: err.code,\n message: err.message,\n currentValue: getValueAtPath(rawConfig, err.path),\n };\n\n // Generate fix suggestions based on error type\n if (\n err.path.includes(\"description\") &&\n err.message.includes(\"at least 10 characters\")\n ) {\n const currentValue = issue.currentValue as string;\n issue.suggestedFix = {\n description: \"Extend description to meet minimum length\",\n newValue: padDescription(currentValue),\n };\n } else if (\n err.path.includes(\"name\") &&\n err.message.includes(\"reserved word\")\n ) {\n const currentValue = issue.currentValue as string;\n const replacement =\n RESERVED_NAME_REPLACEMENTS[currentValue] || `${currentValue}-scope`;\n issue.suggestedFix = {\n description: `Rename from \"${currentValue}\" to \"${replacement}\"`,\n newValue: replacement,\n };\n } else if (err.code === \"too_small\" && err.path.includes(\"description\")) {\n const currentValue = (issue.currentValue as string) || \"\";\n issue.suggestedFix = {\n description: \"Extend description to meet minimum length\",\n newValue: padDescription(currentValue),\n };\n }\n\n issues.push(issue);\n }\n\n return issues;\n}\n\n/**\n * Apply auto-fixes to a raw configuration object\n */\nexport function applyAutoFixes(\n rawConfig: unknown,\n issues: ConfigValidationIssue[],\n): AutoFixResult {\n const changes: string[] = [];\n // Deep clone the config\n const newConfig = JSON.parse(JSON.stringify(rawConfig));\n\n for (const issue of issues) {\n if (issue.suggestedFix) {\n const path = issue.path.split(\".\");\n setValueAtPath(newConfig, path, issue.suggestedFix.newValue);\n changes.push(\n `${issue.path}: ${issue.suggestedFix.description} (${JSON.stringify(issue.currentValue)} → ${JSON.stringify(issue.suggestedFix.newValue)})`,\n );\n }\n }\n\n return {\n fixed: changes.length > 0,\n changes,\n newConfig,\n };\n}\n\n/**\n * Write fixed configuration back to file\n */\nexport async function writeFixedConfig(\n configPath: string,\n config: unknown,\n): Promise<void> {\n const content = JSON.stringify(config, null, 2);\n await writeFile(configPath, content, \"utf-8\");\n}\n\n/**\n * Attempt to auto-fix a configuration file\n */\nexport async function autoFixConfigFile(\n cwd: string = process.cwd(),\n): Promise<{\n success: boolean;\n configPath: string | null;\n changes: string[];\n error?: string;\n}> {\n const configPaths = [\n \"workflow.config.json\",\n \".workflowrc.json\",\n \".workflowrc\",\n ];\n\n let configPath: string | null = null;\n for (const path of configPaths) {\n const fullPath = join(cwd, path);\n if (existsSync(fullPath)) {\n configPath = fullPath;\n break;\n }\n }\n\n if (!configPath) {\n return {\n success: false,\n configPath: null,\n changes: [],\n error: \"No JSON configuration file found to fix\",\n };\n }\n\n try {\n const content = await readFile(configPath, \"utf-8\");\n const rawConfig = JSON.parse(content);\n\n // Try to validate\n const result = WorkflowConfigSchema.safeParse(rawConfig);\n\n if (result.success) {\n return {\n success: true,\n configPath,\n changes: [],\n };\n }\n\n // Analyze and fix issues\n const issues = analyzeValidationError(result.error, rawConfig);\n const fixResult = applyAutoFixes(rawConfig, issues);\n\n if (!fixResult.fixed) {\n return {\n success: false,\n configPath,\n changes: [],\n error: \"No automatic fixes available for the validation errors\",\n };\n }\n\n // Validate the fixed config\n const fixedResult = WorkflowConfigSchema.safeParse(fixResult.newConfig);\n if (!fixedResult.success) {\n return {\n success: false,\n configPath,\n changes: fixResult.changes,\n error:\n \"Auto-fix applied but configuration still has validation errors\",\n };\n }\n\n // Write the fixed config\n await writeFixedConfig(configPath, fixResult.newConfig);\n\n return {\n success: true,\n configPath,\n changes: fixResult.changes,\n };\n } catch (error) {\n return {\n success: false,\n configPath,\n changes: [],\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n\n// Utility functions\n\nfunction padDescription(description: string): string {\n if (!description) {\n return \"Description for this scope\";\n }\n if (description.length >= 10) {\n return description;\n }\n // Pad with meaningful suffix based on what exists\n const suffixes = [\" changes\", \" updates\", \" work\", \" tasks\"];\n for (const suffix of suffixes) {\n if ((description + suffix).length >= 10) {\n return description + suffix;\n }\n }\n // Last resort: pad with generic text\n return description + \" related changes\";\n}\n\nfunction getValueAtPath(obj: unknown, path: (string | number)[]): unknown {\n let current: unknown = obj;\n for (const key of path) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n return current;\n}\n\nfunction setValueAtPath(obj: unknown, path: string[], value: unknown): void {\n let current: Record<string, unknown> = obj as Record<string, unknown>;\n for (let i = 0; i < path.length - 1; i++) {\n const key = path[i];\n if (current[key] === undefined) {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n current[path[path.length - 1]] = value;\n}\n","import { z } from \"zod\";\n\n// Reserved scope names that cannot be used\nconst RESERVED_SCOPE_NAMES = [\n \"init\",\n \"create\",\n \"build\",\n \"test\",\n \"config\",\n \"docs\",\n \"ci\",\n \"deps\",\n];\n\nexport const ScopeSchema = z.object({\n name: z\n .string()\n .min(1)\n .max(32, \"Scope name must be 32 characters or less\")\n .regex(\n /^[a-z0-9-]+$/,\n \"Scope name must be lowercase alphanumeric with hyphens\",\n )\n .refine((name) => !RESERVED_SCOPE_NAMES.includes(name), {\n message: `Scope name cannot be a reserved word: ${RESERVED_SCOPE_NAMES.join(\", \")}`,\n }),\n description: z\n .string()\n .min(10, \"Scope description must be at least 10 characters\"),\n emoji: z.string().optional(),\n category: z\n .enum([\n \"auth\",\n \"features\",\n \"infrastructure\",\n \"documentation\",\n \"testing\",\n \"performance\",\n \"other\",\n ])\n .optional(),\n});\n\nexport const BranchTypeSchema = z.enum([\n \"feature\",\n \"bugfix\",\n \"hotfix\",\n \"chore\",\n \"refactor\",\n \"docs\",\n \"test\",\n \"release\",\n]);\n\nexport const ConventionalTypeSchema = z.enum([\n \"feat\",\n \"fix\",\n \"refactor\",\n \"chore\",\n \"docs\",\n \"test\",\n \"perf\",\n \"style\",\n \"ci\",\n \"build\",\n \"revert\",\n]);\n\nexport const EnforcementLevelSchema = z.enum([\n \"strict\",\n \"advisory\",\n \"learning\",\n]);\n\nexport const AnalyticsConfigSchema = z.object({\n enabled: z.boolean().default(false),\n shareAnonymous: z.boolean().default(false),\n});\n\nexport const CIConfigSchema = z.object({\n provider: z.enum([\"github\", \"gitlab\", \"azure\"]).default(\"github\"),\n nodeVersions: z.array(z.string()).optional(),\n defaultBranch: z.string().default(\"main\"),\n checks: z\n .array(z.enum([\"lint\", \"typecheck\", \"format\", \"build\", \"test\"]))\n .optional(),\n});\n\nexport const HooksConfigSchema = z.object({\n preCommit: z.array(z.string()).optional(),\n commitMsg: z.array(z.string()).optional(),\n prePush: z.array(z.string()).optional(),\n});\n\nexport const GuidelinesConfigSchema = z.object({\n mandatoryTemplates: z.array(z.string()).optional(),\n optionalTemplates: z.array(z.string()).optional(),\n customTemplatesDir: z.string().optional(),\n additionalMandatory: z.array(z.string()).optional(),\n optionalOverrides: z.array(z.string()).optional(),\n});\n\nexport const AdvisoryDepthSchema = z.enum([\n \"executive\",\n \"quick\",\n \"standard\",\n \"comprehensive\",\n]);\n\nexport const AdvisoryQuestionSchema = z.object({\n category: z.string(),\n question: z.string(),\n context: z.string().optional(),\n priority: z.enum([\"high\", \"medium\", \"low\"]).optional(),\n});\n\nexport const AdvisoryConfigSchema = z.object({\n enabled: z.boolean().default(true),\n defaultDepth: AdvisoryDepthSchema.default(\"standard\"),\n outputDir: z.string().default(\"docs/advisory\"),\n customQuestions: z.array(AdvisoryQuestionSchema).optional(),\n riskThresholds: z\n .object({\n high: z.number().default(0.7),\n medium: z.number().default(0.4),\n low: z.number().default(0.2),\n })\n .optional(),\n categories: z\n .array(z.string())\n .default([\n \"Technology Decisions\",\n \"Package Utilization\",\n \"Platform Strategy\",\n \"Business Alignment\",\n \"Technical Debt\",\n \"Growth Opportunities\",\n ]),\n excludePatterns: z.array(z.string()).optional(),\n includeHealthMetrics: z.boolean().default(false),\n});\n\nexport const WorkflowConfigSchema = z.object({\n projectName: z.string().min(1),\n scopes: z.array(ScopeSchema).min(1),\n branchTypes: z.array(BranchTypeSchema).optional(),\n conventionalTypes: z.array(ConventionalTypeSchema).optional(),\n enforcement: EnforcementLevelSchema.default(\"strict\"),\n language: z.string().default(\"en\"),\n analytics: AnalyticsConfigSchema.optional(),\n adapter: z.string().optional(),\n syncRemote: z.string().optional(),\n ci: CIConfigSchema.optional(),\n hooks: HooksConfigSchema.optional(),\n guidelines: GuidelinesConfigSchema.optional(),\n advisory: AdvisoryConfigSchema.optional(),\n});\n\nexport type Scope = z.infer<typeof ScopeSchema>;\nexport type BranchType = z.infer<typeof BranchTypeSchema>;\nexport type ConventionalType = z.infer<typeof ConventionalTypeSchema>;\nexport type EnforcementLevel = z.infer<typeof EnforcementLevelSchema>;\nexport type AnalyticsConfig = z.infer<typeof AnalyticsConfigSchema>;\nexport type CIConfig = z.infer<typeof CIConfigSchema>;\nexport type HooksConfig = z.infer<typeof HooksConfigSchema>;\nexport type GuidelinesConfig = z.infer<typeof GuidelinesConfigSchema>;\nexport type AdvisoryDepth = z.infer<typeof AdvisoryDepthSchema>;\nexport type AdvisoryQuestion = z.infer<typeof AdvisoryQuestionSchema>;\nexport type AdvisoryConfig = z.infer<typeof AdvisoryConfigSchema>;\nexport type WorkflowConfig = z.infer<typeof WorkflowConfigSchema>;\n\nexport const defaultBranchTypes: BranchType[] = [\n \"feature\",\n \"bugfix\",\n \"hotfix\",\n \"chore\",\n \"refactor\",\n \"docs\",\n \"test\",\n];\n\nexport const defaultConventionalTypes: ConventionalType[] = [\n \"feat\",\n \"fix\",\n \"refactor\",\n \"chore\",\n \"docs\",\n \"test\",\n \"perf\",\n \"style\",\n];\n\n/**\n * Validates scope definitions for duplicates, description quality, and category values\n * @param scopes Array of scope definitions to validate\n * @returns Object with validation result and error messages\n */\nexport function validateScopeDefinitions(scopes: Scope[]): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n const seenNames = new Set<string>();\n\n for (const scope of scopes) {\n // Check for duplicate names\n if (seenNames.has(scope.name)) {\n errors.push(`Duplicate scope name: \"${scope.name}\"`);\n }\n seenNames.add(scope.name);\n\n // Validate using schema (this will catch min length, reserved names, etc.)\n const result = ScopeSchema.safeParse(scope);\n if (!result.success) {\n result.error.errors.forEach((err) => {\n errors.push(`Scope \"${scope.name}\": ${err.message}`);\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n"],"mappings":";AAOA,SAAS,WAAW,gBAAgB;AACpC,SAAS,kBAAkB;AAC3B,SAAS,YAAY;;;ACTrB,SAAS,SAAS;AAGlB,IAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,cAAc,EAAE,OAAO;AAAA,EAClC,MAAM,EACH,OAAO,EACP,IAAI,CAAC,EACL,IAAI,IAAI,0CAA0C,EAClD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,CAAC,SAAS,CAAC,qBAAqB,SAAS,IAAI,GAAG;AAAA,IACtD,SAAS,yCAAyC,qBAAqB,KAAK,IAAI,CAAC;AAAA,EACnF,CAAC;AAAA,EACH,aAAa,EACV,OAAO,EACP,IAAI,IAAI,kDAAkD;AAAA,EAC7D,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,UAAU,EACP,KAAK;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,EACA,SAAS;AACd,CAAC;AAEM,IAAM,mBAAmB,EAAE,KAAK;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,yBAAyB,EAAE,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,yBAAyB,EAAE,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAClC,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAC3C,CAAC;AAEM,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,UAAU,EAAE,KAAK,CAAC,UAAU,UAAU,OAAO,CAAC,EAAE,QAAQ,QAAQ;AAAA,EAChE,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC3C,eAAe,EAAE,OAAO,EAAE,QAAQ,MAAM;AAAA,EACxC,QAAQ,EACL,MAAM,EAAE,KAAK,CAAC,QAAQ,aAAa,UAAU,SAAS,MAAM,CAAC,CAAC,EAC9D,SAAS;AACd,CAAC;AAEM,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACxC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACxC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AACxC,CAAC;AAEM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACjD,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAChD,oBAAoB,EAAE,OAAO,EAAE,SAAS;AAAA,EACxC,qBAAqB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAClD,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAClD,CAAC;AAEM,IAAM,sBAAsB,EAAE,KAAK;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,UAAU,EAAE,OAAO;AAAA,EACnB,UAAU,EAAE,OAAO;AAAA,EACnB,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,UAAU,EAAE,KAAK,CAAC,QAAQ,UAAU,KAAK,CAAC,EAAE,SAAS;AACvD,CAAC;AAEM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,SAAS,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACjC,cAAc,oBAAoB,QAAQ,UAAU;AAAA,EACpD,WAAW,EAAE,OAAO,EAAE,QAAQ,eAAe;AAAA,EAC7C,iBAAiB,EAAE,MAAM,sBAAsB,EAAE,SAAS;AAAA,EAC1D,gBAAgB,EACb,OAAO;AAAA,IACN,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG;AAAA,IAC5B,QAAQ,EAAE,OAAO,EAAE,QAAQ,GAAG;AAAA,IAC9B,KAAK,EAAE,OAAO,EAAE,QAAQ,GAAG;AAAA,EAC7B,CAAC,EACA,SAAS;AAAA,EACZ,YAAY,EACT,MAAM,EAAE,OAAO,CAAC,EAChB,QAAQ;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACH,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC9C,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,KAAK;AACjD,CAAC;AAEM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,QAAQ,EAAE,MAAM,WAAW,EAAE,IAAI,CAAC;AAAA,EAClC,aAAa,EAAE,MAAM,gBAAgB,EAAE,SAAS;AAAA,EAChD,mBAAmB,EAAE,MAAM,sBAAsB,EAAE,SAAS;AAAA,EAC5D,aAAa,uBAAuB,QAAQ,QAAQ;AAAA,EACpD,UAAU,EAAE,OAAO,EAAE,QAAQ,IAAI;AAAA,EACjC,WAAW,sBAAsB,SAAS;AAAA,EAC1C,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,IAAI,eAAe,SAAS;AAAA,EAC5B,OAAO,kBAAkB,SAAS;AAAA,EAClC,YAAY,uBAAuB,SAAS;AAAA,EAC5C,UAAU,qBAAqB,SAAS;AAC1C,CAAC;AAyCM,SAAS,yBAAyB,QAGvC;AACA,QAAM,SAAmB,CAAC;AAC1B,QAAM,YAAY,oBAAI,IAAY;AAElC,aAAW,SAAS,QAAQ;AAE1B,QAAI,UAAU,IAAI,MAAM,IAAI,GAAG;AAC7B,aAAO,KAAK,0BAA0B,MAAM,IAAI,GAAG;AAAA,IACrD;AACA,cAAU,IAAI,MAAM,IAAI;AAGxB,UAAM,SAAS,YAAY,UAAU,KAAK;AAC1C,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,MAAM,OAAO,QAAQ,CAAC,QAAQ;AACnC,eAAO,KAAK,UAAU,MAAM,IAAI,MAAM,IAAI,OAAO,EAAE;AAAA,MACrD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,WAAW;AAAA,IACzB;AAAA,EACF;AACF;;;ADlNA,IAAM,6BAAqD;AAAA,EACzD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AACR;AA8BO,SAAS,uBACd,OACA,WACyB;AACzB,QAAM,SAAkC,CAAC;AAEzC,aAAW,OAAO,MAAM,QAAQ;AAC9B,UAAM,UAAU,IAAI,KAAK,KAAK,GAAG;AACjC,UAAM,QAA+B;AAAA,MACnC,MAAM;AAAA,MACN,MAAM,IAAI;AAAA,MACV,SAAS,IAAI;AAAA,MACb,cAAc,eAAe,WAAW,IAAI,IAAI;AAAA,IAClD;AAGA,QACE,IAAI,KAAK,SAAS,aAAa,KAC/B,IAAI,QAAQ,SAAS,wBAAwB,GAC7C;AACA,YAAM,eAAe,MAAM;AAC3B,YAAM,eAAe;AAAA,QACnB,aAAa;AAAA,QACb,UAAU,eAAe,YAAY;AAAA,MACvC;AAAA,IACF,WACE,IAAI,KAAK,SAAS,MAAM,KACxB,IAAI,QAAQ,SAAS,eAAe,GACpC;AACA,YAAM,eAAe,MAAM;AAC3B,YAAM,cACJ,2BAA2B,YAAY,KAAK,GAAG,YAAY;AAC7D,YAAM,eAAe;AAAA,QACnB,aAAa,gBAAgB,YAAY,SAAS,WAAW;AAAA,QAC7D,UAAU;AAAA,MACZ;AAAA,IACF,WAAW,IAAI,SAAS,eAAe,IAAI,KAAK,SAAS,aAAa,GAAG;AACvE,YAAM,eAAgB,MAAM,gBAA2B;AACvD,YAAM,eAAe;AAAA,QACnB,aAAa;AAAA,QACb,UAAU,eAAe,YAAY;AAAA,MACvC;AAAA,IACF;AAEA,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,SAAO;AACT;AAKO,SAAS,eACd,WACA,QACe;AACf,QAAM,UAAoB,CAAC;AAE3B,QAAM,YAAY,KAAK,MAAM,KAAK,UAAU,SAAS,CAAC;AAEtD,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,cAAc;AACtB,YAAM,OAAO,MAAM,KAAK,MAAM,GAAG;AACjC,qBAAe,WAAW,MAAM,MAAM,aAAa,QAAQ;AAC3D,cAAQ;AAAA,QACN,GAAG,MAAM,IAAI,KAAK,MAAM,aAAa,WAAW,KAAK,KAAK,UAAU,MAAM,YAAY,CAAC,WAAM,KAAK,UAAU,MAAM,aAAa,QAAQ,CAAC;AAAA,MAC1I;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ,SAAS;AAAA,IACxB;AAAA,IACA;AAAA,EACF;AACF;AAKA,eAAsB,iBACpB,YACA,QACe;AACf,QAAM,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC;AAC9C,QAAM,UAAU,YAAY,SAAS,OAAO;AAC9C;AAKA,eAAsB,kBACpB,MAAc,QAAQ,IAAI,GAMzB;AACD,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,aAA4B;AAChC,aAAW,QAAQ,aAAa;AAC9B,UAAM,WAAW,KAAK,KAAK,IAAI;AAC/B,QAAI,WAAW,QAAQ,GAAG;AACxB,mBAAa;AACb;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,MACL,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,SAAS,CAAC;AAAA,MACV,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,YAAY,OAAO;AAClD,UAAM,YAAY,KAAK,MAAM,OAAO;AAGpC,UAAM,SAAS,qBAAqB,UAAU,SAAS;AAEvD,QAAI,OAAO,SAAS;AAClB,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AAGA,UAAM,SAAS,uBAAuB,OAAO,OAAO,SAAS;AAC7D,UAAM,YAAY,eAAe,WAAW,MAAM;AAElD,QAAI,CAAC,UAAU,OAAO;AACpB,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA,SAAS,CAAC;AAAA,QACV,OAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAM,cAAc,qBAAqB,UAAU,UAAU,SAAS;AACtE,QAAI,CAAC,YAAY,SAAS;AACxB,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA,SAAS,UAAU;AAAA,QACnB,OACE;AAAA,MACJ;AAAA,IACF;AAGA,UAAM,iBAAiB,YAAY,UAAU,SAAS;AAEtD,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,SAAS,UAAU;AAAA,IACrB;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,SAAS,CAAC;AAAA,MACV,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAClD;AAAA,EACF;AACF;AAIA,SAAS,eAAe,aAA6B;AACnD,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AACA,MAAI,YAAY,UAAU,IAAI;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,CAAC,YAAY,YAAY,SAAS,QAAQ;AAC3D,aAAW,UAAU,UAAU;AAC7B,SAAK,cAAc,QAAQ,UAAU,IAAI;AACvC,aAAO,cAAc;AAAA,IACvB;AAAA,EACF;AAEA,SAAO,cAAc;AACvB;AAEA,SAAS,eAAe,KAAc,MAAoC;AACxE,MAAI,UAAmB;AACvB,aAAW,OAAO,MAAM;AACtB,QAAI,YAAY,QAAQ,YAAY,QAAW;AAC7C,aAAO;AAAA,IACT;AACA,cAAW,QAAoC,GAAG;AAAA,EACpD;AACA,SAAO;AACT;AAEA,SAAS,eAAe,KAAc,MAAgB,OAAsB;AAC1E,MAAI,UAAmC;AACvC,WAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;AACxC,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,QAAQ,GAAG,MAAM,QAAW;AAC9B,cAAQ,GAAG,IAAI,CAAC;AAAA,IAClB;AACA,cAAU,QAAQ,GAAG;AAAA,EACvB;AACA,UAAQ,KAAK,KAAK,SAAS,CAAC,CAAC,IAAI;AACnC;","names":[]}
|
package/dist/sync-6T5TD4QS.js
DELETED
package/dist/verify-TX6LFMI6.js
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|