@standards-kit/conform 0.3.0 → 0.3.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 +0 -9
- package/dist/{chunk-YKKWXHYS.js → chunk-AJIWBLUQ.js} +2 -5
- package/dist/chunk-AJIWBLUQ.js.map +1 -0
- package/dist/{chunk-DXIYZR62.js → chunk-G5AS4QBP.js} +1 -1
- package/dist/{chunk-RHM53NLG.js → chunk-HMNRMNEA.js} +1 -1
- package/dist/{chunk-RHM53NLG.js.map → chunk-HMNRMNEA.js.map} +1 -1
- package/dist/{chunk-M7G73Q6P.js → chunk-T2PWT2B5.js} +1 -1
- package/dist/chunk-T2PWT2B5.js.map +1 -0
- package/dist/{chunk-FJZMUGYW.js → chunk-UU6OT5O3.js} +32 -6
- package/dist/chunk-UU6OT5O3.js.map +1 -0
- package/dist/{chunk-J5S6GRGW.js → chunk-XZERDHOH.js} +2 -2
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/utils.d.ts +2 -4
- package/dist/cli.js +16 -16
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +0 -9
- package/dist/core/index.d.ts +0 -1
- package/dist/{core-LFX2BFLG.js → core-SAQ5O5IL.js} +6 -16
- package/dist/{generate-D4MFMOHP.js → generate-4EY6VETG.js} +3 -3
- package/dist/{iam-YXMHK2MV.js → iam-ZV3RA3JZ.js} +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -10
- package/dist/index.js.map +1 -1
- package/dist/infra/checkers/index.d.ts +0 -4
- package/dist/infra/schemas.d.ts +1 -1
- package/dist/{infra-RFEWGWPW.js → infra-OWKYLH3J.js} +10 -10
- package/dist/infra-OWKYLH3J.js.map +1 -0
- package/dist/{manifest-7AIL2FK2.js → manifest-CL4QMZT6.js} +2 -2
- package/dist/mcp/standards/matcher.d.ts +0 -9
- package/dist/mcp/standards/parser.d.ts +0 -4
- package/dist/{mcp-T2JFU4E2.js → mcp-6PRCC6P6.js} +6 -6
- package/dist/mcp-6PRCC6P6.js.map +1 -0
- package/dist/process/index.d.ts +1 -1
- package/dist/process/scan/remote-fetcher.d.ts +0 -2
- package/dist/process/tools/index.d.ts +0 -1
- package/dist/projects/templates.d.ts +0 -4
- package/dist/{registry-J2LVW3M2.js → registry-QYUYWBMY.js} +3 -3
- package/dist/{s3-S4GXNR7H.js → s3-3DJX6X5S.js} +4 -4
- package/dist/{s3-53UELUWT.js → s3-6YMTP5VV.js} +4 -4
- package/dist/{scan-BZH5IR3Z.js → scan-5QKYVHI6.js} +5 -5
- package/dist/scan-5QKYVHI6.js.map +1 -0
- package/dist/{standards-ALMA4VIU.js → standards-EGSQSDOD.js} +3 -9
- package/dist/{sync-EGJ2CSYK.js → sync-QMZDAV44.js} +4 -4
- package/dist/validate/guidelines.d.ts +0 -14
- package/dist/validate/index.d.ts +1 -2
- package/dist/{validate-X4K2SHYT.js → validate-OGNSVZO5.js} +5 -6
- package/dist/validate-OGNSVZO5.js.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-FJZMUGYW.js.map +0 -1
- package/dist/chunk-M7G73Q6P.js.map +0 -1
- package/dist/chunk-YKKWXHYS.js.map +0 -1
- package/dist/infra-RFEWGWPW.js.map +0 -1
- package/dist/mcp-T2JFU4E2.js.map +0 -1
- package/dist/scan-BZH5IR3Z.js.map +0 -1
- package/dist/validate-X4K2SHYT.js.map +0 -1
- /package/dist/{chunk-DXIYZR62.js.map → chunk-G5AS4QBP.js.map} +0 -0
- /package/dist/{chunk-J5S6GRGW.js.map → chunk-XZERDHOH.js.map} +0 -0
- /package/dist/{core-LFX2BFLG.js.map → core-SAQ5O5IL.js.map} +0 -0
- /package/dist/{generate-D4MFMOHP.js.map → generate-4EY6VETG.js.map} +0 -0
- /package/dist/{iam-YXMHK2MV.js.map → iam-ZV3RA3JZ.js.map} +0 -0
- /package/dist/{manifest-7AIL2FK2.js.map → manifest-CL4QMZT6.js.map} +0 -0
- /package/dist/{registry-J2LVW3M2.js.map → registry-QYUYWBMY.js.map} +0 -0
- /package/dist/{s3-53UELUWT.js.map → s3-3DJX6X5S.js.map} +0 -0
- /package/dist/{s3-S4GXNR7H.js.map → s3-6YMTP5VV.js.map} +0 -0
- /package/dist/{standards-ALMA4VIU.js.map → standards-EGSQSDOD.js.map} +0 -0
- /package/dist/{sync-EGJ2CSYK.js.map → sync-QMZDAV44.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/validate/guidelines.ts","../src/validate/tier.ts","../src/validate/types.ts"],"sourcesContent":["/**\n * Validate guideline markdown files against the frontmatter schema\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport chalk from \"chalk\";\nimport matter from \"gray-matter\";\n\nimport { frontmatterSchema } from \"../mcp/standards/index.js\";\nimport { ExitCode } from \"../core/index.js\";\n\n/** Single file validation error */\ninterface GuidelineValidationError {\n file: string;\n errors: string[];\n}\n\n/** Overall validation result */\ninterface GuidelineValidationResult {\n valid: boolean;\n validCount: number;\n invalidCount: number;\n errors: GuidelineValidationError[];\n}\n\n/** Format text output for validation result */\nfunction formatTextOutput(result: GuidelineValidationResult): string {\n if (result.valid) {\n return chalk.green(`✓ All ${result.validCount} guideline(s) valid`);\n }\n const lines = [chalk.red(`✗ Found ${result.invalidCount} invalid guideline(s)`), \"\"];\n for (const err of result.errors) {\n lines.push(chalk.red(` ${err.file}:`));\n for (const e of err.errors) {\n lines.push(chalk.red(` - ${e}`));\n }\n }\n return lines.join(\"\\n\");\n}\n\n/** Validate a directory of guideline files */\nfunction validateGuidelinesDir(dirPath: string): GuidelineValidationResult {\n const files = fs.readdirSync(dirPath).filter((f) => f.endsWith(\".md\"));\n const result: GuidelineValidationResult = {\n valid: true,\n validCount: 0,\n invalidCount: 0,\n errors: [],\n };\n\n for (const file of files) {\n const filePath = path.join(dirPath, file);\n const content = fs.readFileSync(filePath, \"utf-8\");\n const { data } = matter(content);\n\n const parseResult = frontmatterSchema.safeParse(data);\n if (parseResult.success) {\n result.validCount++;\n } else {\n result.valid = false;\n result.invalidCount++;\n result.errors.push({\n file,\n errors: parseResult.error.issues.map((e) => `${e.path.join(\".\")}: ${e.message}`),\n });\n }\n }\n\n return result;\n}\n\n/** Output error and exit */\nfunction exitWithError(error: string, format: string): never {\n if (format === \"json\") {\n process.stdout.write(`${JSON.stringify({ valid: false, error }, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`✗ ${error}`));\n }\n process.exit(ExitCode.CONFIG_ERROR);\n}\n\n/** Resolve and validate directory path */\nfunction resolveAndValidatePath(dirPath: string, format: string): string {\n const resolvedPath = path.isAbsolute(dirPath) ? dirPath : path.resolve(process.cwd(), dirPath);\n\n if (!fs.existsSync(resolvedPath)) {\n exitWithError(`Path does not exist: ${resolvedPath}`, format);\n }\n\n const stats = fs.statSync(resolvedPath);\n if (!stats.isDirectory()) {\n exitWithError(`Path is not a directory: ${resolvedPath}`, format);\n }\n\n return resolvedPath;\n}\n\n/** Run the validate guidelines command */\nexport async function runValidateGuidelines(\n dirPath: string,\n options: { format: string }\n): Promise<void> {\n const resolvedPath = resolveAndValidatePath(dirPath, options.format);\n const result = validateGuidelinesDir(resolvedPath);\n\n if (options.format === \"json\") {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else {\n process.stdout.write(`${formatTextOutput(result)}\\n`);\n }\n\n process.exit(result.valid ? ExitCode.SUCCESS : ExitCode.CONFIG_ERROR);\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport TOML from \"@iarna/toml\";\nimport chalk from \"chalk\";\n\nimport { findConfigFile } from \"../core/index.js\";\nimport {\n type Tier,\n type TierSourceDetail,\n VALID_TIERS,\n type ValidateTierOptions,\n type ValidateTierResult,\n} from \"./types.js\";\n\n/** Default tier when not specified */\nconst DEFAULT_TIER: Tier = \"internal\";\n\n/** Extends section from standards.toml */\ninterface ExtendsConfig {\n registry?: string;\n rulesets?: string[];\n}\n\n/** Metadata section from standards.toml */\ninterface MetadataConfig {\n tier?: Tier;\n project?: string;\n organisation?: string;\n status?: string;\n}\n\n/** Raw standards.toml structure (just what we need) */\ninterface RawConfig {\n metadata?: MetadataConfig;\n extends?: ExtendsConfig;\n}\n\n/** Result of getTier with detailed info */\ninterface GetTierResult {\n tier: Tier;\n source: \"standards.toml\" | \"default\";\n sourceDetail: TierSourceDetail;\n invalidValue?: string;\n}\n\n/**\n * Load and parse standards.toml to get extends section\n */\nfunction loadExtendsConfig(configPath: string): ExtendsConfig | null {\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const parsed = TOML.parse(content) as RawConfig;\n return parsed.extends ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Load tier from standards.toml [metadata] section\n */\nfunction loadTierFromStandardsToml(configPath: string): GetTierResult {\n if (!fs.existsSync(configPath)) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (file not found)\",\n };\n }\n\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const parsed = TOML.parse(content) as RawConfig;\n\n if (!parsed.metadata) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (no metadata)\",\n };\n }\n\n if (parsed.metadata.tier === undefined) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (tier not specified)\",\n };\n }\n\n const tier = parsed.metadata.tier;\n\n // Check if tier value is valid\n if (!VALID_TIERS.includes(tier)) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (invalid value)\",\n invalidValue: String(tier),\n };\n }\n\n return { tier, source: \"standards.toml\", sourceDetail: \"standards.toml\" };\n } catch {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (file not found)\",\n };\n }\n}\n\n/**\n * Check if rulesets include a tier-matching ruleset\n */\nfunction findMatchingRulesets(rulesets: string[], tier: Tier): string[] {\n const suffix = `-${tier}`;\n return rulesets.filter((ruleset) => ruleset.endsWith(suffix));\n}\n\n/**\n * Resolve the config path from options\n */\nfunction resolveConfigPath(options: ValidateTierOptions): string | null {\n if (options.config) {\n const absolutePath = path.resolve(options.config);\n return fs.existsSync(absolutePath) ? absolutePath : null;\n }\n return findConfigFile();\n}\n\n/**\n * Create result for missing config\n */\nfunction createNotFoundResult(): ValidateTierResult {\n return {\n valid: false,\n tier: DEFAULT_TIER,\n tierSource: \"default\",\n tierSourceDetail: \"default (file not found)\",\n rulesets: [],\n expectedPattern: `*-${DEFAULT_TIER}`,\n matchedRulesets: [],\n error: \"No standards.toml found\",\n };\n}\n\n/** Options for building the result */\ninterface BuildResultOptions {\n tier: Tier;\n source: \"standards.toml\" | \"default\";\n sourceDetail: TierSourceDetail;\n rulesets: string[];\n matchedRulesets: string[];\n invalidTierValue?: string;\n hasEmptyRulesets?: boolean;\n registryUrl?: string;\n warnings?: string[];\n}\n\n/**\n * Build the validation result\n */\nfunction buildResult(options: BuildResultOptions): ValidateTierResult {\n const {\n tier,\n source,\n sourceDetail,\n rulesets,\n matchedRulesets,\n invalidTierValue,\n hasEmptyRulesets,\n registryUrl,\n } = options;\n const warnings: string[] = options.warnings ?? [];\n\n const expectedPattern = `*-${tier}`;\n const valid = rulesets.length === 0 || matchedRulesets.length > 0;\n\n // Add warning for invalid tier value\n if (invalidTierValue) {\n warnings.push(\n `Invalid tier '${invalidTierValue}' in standards.toml [metadata]. Valid values are: ${VALID_TIERS.join(\", \")}`\n );\n }\n\n // Add warning for empty rulesets with registry configured\n if (hasEmptyRulesets && registryUrl) {\n warnings.push(\n `[extends] is configured with registry '${registryUrl}' but rulesets is empty - no standards will be inherited`\n );\n }\n\n return {\n valid,\n tier,\n tierSource: source,\n tierSourceDetail: sourceDetail,\n rulesets,\n expectedPattern,\n matchedRulesets,\n error: valid\n ? undefined\n : `No ruleset matching pattern '${expectedPattern}' found. Rulesets: [${rulesets.join(\", \")}]`,\n invalidTierValue,\n hasEmptyRulesets,\n registryUrl,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\n/**\n * Validate that project tier matches its rulesets.\n * This is the programmatic API exported for library consumers.\n *\n * Tier is loaded from standards.toml [metadata].tier\n * Defaults to \"internal\" if not specified\n */\nexport function validateTierRuleset(options: ValidateTierOptions = {}): ValidateTierResult {\n const configPath = resolveConfigPath(options);\n if (!configPath) {\n return createNotFoundResult();\n }\n\n const tierResult = loadTierFromStandardsToml(configPath);\n\n const extendsConfig = loadExtendsConfig(configPath);\n const rulesets = extendsConfig?.rulesets ?? [];\n const matchedRulesets = rulesets.length > 0 ? findMatchingRulesets(rulesets, tierResult.tier) : [];\n\n // Detect empty rulesets with registry configured\n const hasEmptyRulesets = extendsConfig !== null && rulesets.length === 0;\n const registryUrl = extendsConfig?.registry;\n\n return buildResult({\n tier: tierResult.tier,\n source: tierResult.source,\n sourceDetail: tierResult.sourceDetail,\n rulesets,\n matchedRulesets,\n invalidTierValue: tierResult.invalidValue,\n hasEmptyRulesets,\n registryUrl,\n });\n}\n\n/** Format warnings section */\nfunction formatWarnings(warnings: string[] | undefined): string[] {\n if (!warnings || warnings.length === 0) {\n return [];\n }\n const lines = warnings.map((w) => chalk.yellow(`⚠ Warning: ${w}`));\n lines.push(\"\"); // Empty line after warnings\n return lines;\n}\n\n/** Format the rulesets message based on configuration */\nfunction formatRulesetsMessage(result: ValidateTierResult): string {\n if (result.matchedRulesets.length > 0) {\n return ` Matching rulesets: ${result.matchedRulesets.join(\", \")}`;\n }\n if (result.hasEmptyRulesets) {\n return \" No rulesets specified (no tier constraint)\";\n }\n return \" No extends configured (no tier constraint)\";\n}\n\n/** Format the failed validation section */\nfunction formatFailedValidation(result: ValidateTierResult, sourceDisplay: string): string[] {\n const lines = [\n chalk.red(\"✗ Tier validation failed\"),\n ` Tier: ${result.tier} (source: ${sourceDisplay})`,\n ` Expected pattern: ${result.expectedPattern}`,\n ` Rulesets: [${result.rulesets.join(\", \")}]`,\n ];\n if (result.error) {\n lines.push(chalk.red(` Error: ${result.error}`));\n }\n if (result.invalidTierValue) {\n lines.push(\"\");\n lines.push(\n chalk.cyan(\n ` Hint: Update standards.toml [metadata].tier to use a valid value: ${VALID_TIERS.join(\", \")}`\n )\n );\n }\n return lines;\n}\n\n/**\n * Format tier validation result as text\n */\nexport function formatTierResultText(result: ValidateTierResult): string {\n const lines: string[] = formatWarnings(result.warnings);\n const sourceDisplay = result.tierSourceDetail ?? result.tierSource;\n\n if (result.valid) {\n lines.push(chalk.green(\"✓ Tier validation passed\"));\n lines.push(` Tier: ${result.tier} (source: ${sourceDisplay})`);\n lines.push(formatRulesetsMessage(result));\n } else {\n lines.push(...formatFailedValidation(result, sourceDisplay));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format tier validation result as JSON\n */\nexport function formatTierResultJson(result: ValidateTierResult): string {\n return JSON.stringify(result, null, 2);\n}\n","/**\n * Valid project tiers\n */\nexport type Tier = \"production\" | \"internal\" | \"prototype\";\n\n/**\n * Valid tier values as a constant array for validation and export\n */\nexport const VALID_TIERS: readonly Tier[] = [\"production\", \"internal\", \"prototype\"];\n\n/**\n * Detailed tier source indicating why a default was used\n */\nexport type TierSourceDetail =\n | \"standards.toml\" // Tier was read from [metadata] section\n | \"default\" // Generic default (for backwards compatibility)\n | \"default (file not found)\" // standards.toml doesn't exist\n | \"default (no metadata)\" // standards.toml exists but no [metadata] section\n | \"default (tier not specified)\" // [metadata] exists but no tier key\n | \"default (invalid value)\"; // [metadata] has tier but value is invalid\n\n/**\n * Options for the tier validation command\n */\nexport interface ValidateTierOptions {\n /** Path to standards.toml config file */\n config?: string;\n /** Output format */\n format?: \"text\" | \"json\";\n}\n\n/**\n * Result of tier validation\n */\nexport interface ValidateTierResult {\n /** Whether validation passed */\n valid: boolean;\n /** Project tier from standards.toml [metadata] (defaults to \"internal\") */\n tier: Tier;\n /** Source of tier value */\n tierSource: \"standards.toml\" | \"default\";\n /** Detailed source of tier value with reason for default */\n tierSourceDetail?: TierSourceDetail;\n /** Rulesets from standards.toml extends section */\n rulesets: string[];\n /** Expected ruleset suffix pattern */\n expectedPattern: string;\n /** Matched rulesets (those that satisfy the tier requirement) */\n matchedRulesets: string[];\n /** Error message if invalid */\n error?: string;\n /** Invalid tier value that was rejected (for error messages) */\n invalidTierValue?: string;\n /** Whether extends is configured but has empty rulesets */\n hasEmptyRulesets?: boolean;\n /** Registry URL if extends is configured */\n registryUrl?: string;\n /** Warnings about configuration */\n warnings?: string[];\n}\n"],"mappings":"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","names":["fs","path","chalk","chalk"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standards-kit/conform",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Standards conformance checking - in-repo enforcement CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@types/js-yaml": "^4.0.9",
|
|
76
76
|
"@types/node": "^22.10.2",
|
|
77
|
-
"@vitest/coverage-v8": "^2.1.
|
|
77
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
78
78
|
"tsup": "^8.0.0",
|
|
79
79
|
"typescript": "^5.4.0",
|
|
80
80
|
"vitest": "^2.1.8"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/registry.ts","../src/core/loader.ts","../src/core/schema.ts"],"sourcesContent":[" \nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nimport * as toml from \"@iarna/toml\";\nimport { execa } from \"execa\";\n\nimport { CACHE, TIMEOUTS } from \"../constants.js\";\nimport { ConfigError } from \"./loader.js\";\nimport { type Config, configSchema } from \"./schema.js\";\n\n/** Authentication method for private registries */\ntype AuthMethod = \"token\" | \"ssh\" | \"none\";\n\ninterface RegistryLocation {\n type: \"github\" | \"local\";\n owner?: string;\n repo?: string;\n ref?: string;\n path: string;\n auth?: AuthMethod;\n}\n\n/**\n * Detect authentication method based on environment variables.\n * Priority: CONFORM_REGISTRY_TOKEN > GITHUB_TOKEN > SSH key detection > none\n */\nfunction detectAuthMethod(): AuthMethod {\n if (process.env.CONFORM_REGISTRY_TOKEN || process.env.GITHUB_TOKEN) {\n return \"token\";\n }\n // Check for SSH key - if SSH_AUTH_SOCK is set, SSH agent is available\n if (process.env.SSH_AUTH_SOCK) {\n return \"ssh\";\n }\n return \"none\";\n}\n\n/**\n * Get the authentication token from environment variables.\n */\nfunction getAuthToken(): string | undefined {\n return process.env.CONFORM_REGISTRY_TOKEN ?? process.env.GITHUB_TOKEN;\n}\n\n/**\n * Build the git URL for a GitHub repository based on auth method.\n */\nfunction buildGitHubUrl(owner: string, repo: string, auth: AuthMethod): string {\n switch (auth) {\n case \"ssh\":\n return `git@github.com:${owner}/${repo}.git`;\n case \"token\": {\n const token = getAuthToken();\n if (token) {\n return `https://x-access-token:${token}@github.com/${owner}/${repo}.git`;\n }\n // Fall back to regular HTTPS if no token found\n return `https://github.com/${owner}/${repo}.git`;\n }\n case \"none\":\n default:\n return `https://github.com/${owner}/${repo}.git`;\n }\n}\n\n/**\n * Parse explicit auth method from URL prefix.\n * Supports: github+ssh:, github+token:, github: (auto-detect)\n */\nfunction parseAuthFromUrl(url: string): { auth: AuthMethod | \"auto\"; rest: string } {\n if (url.startsWith(\"github+ssh:\")) {\n return { auth: \"ssh\", rest: url.slice(11) };\n }\n if (url.startsWith(\"github+token:\")) {\n return { auth: \"token\", rest: url.slice(13) };\n }\n if (url.startsWith(\"github:\")) {\n return { auth: \"auto\", rest: url.slice(7) };\n }\n throw new ConfigError(`Invalid GitHub registry URL: ${url}`);\n}\n\nfunction parseGitHubUrl(url: string): RegistryLocation {\n const { auth: explicitAuth, rest } = parseAuthFromUrl(url);\n const [repoPath, ref] = rest.split(\"@\");\n const [owner, repo] = repoPath.split(\"/\");\n\n if (!owner || !repo) {\n throw new ConfigError(\n `Invalid GitHub registry URL: ${url}. Expected format: github:owner/repo or github+ssh:owner/repo`\n );\n }\n\n const auth = explicitAuth === \"auto\" ? detectAuthMethod() : explicitAuth;\n\n return {\n type: \"github\",\n owner,\n repo,\n ref: ref || undefined,\n path: buildGitHubUrl(owner, repo, auth),\n auth,\n };\n}\n\nexport function parseRegistryUrl(url: string, configDir?: string): RegistryLocation {\n if (url.startsWith(\"github:\") || url.startsWith(\"github+\")) {\n return parseGitHubUrl(url);\n }\n\n const localPath = !path.isAbsolute(url) && configDir ? path.resolve(configDir, url) : url;\n return { type: \"local\", path: localPath };\n}\n\nasync function updateExistingRepo(repoDir: string, ref?: string): Promise<boolean> {\n try {\n if (ref) {\n await execa(\"git\", [\"fetch\", \"--all\"], { cwd: repoDir });\n await execa(\"git\", [\"checkout\", ref], { cwd: repoDir });\n } else {\n await execa(\"git\", [\"pull\", \"--ff-only\"], { cwd: repoDir });\n }\n return true;\n } catch {\n fs.rmSync(repoDir, { recursive: true, force: true });\n return false;\n }\n}\n\nasync function cloneRepo(location: RegistryLocation, repoDir: string): Promise<void> {\n const cacheDir = path.dirname(repoDir);\n fs.mkdirSync(cacheDir, { recursive: true });\n\n const cloneArgs = [\"clone\", \"--depth\", \"1\"];\n if (location.ref) {\n cloneArgs.push(\"--branch\", location.ref);\n }\n cloneArgs.push(location.path, repoDir);\n\n try {\n await execa(\"git\", cloneArgs, { timeout: TIMEOUTS.git });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes(\"timed out\")) {\n throw new ConfigError(`Registry clone timed out after ${TIMEOUTS.git / 1000} seconds: ${location.path}`);\n }\n throw new ConfigError(`Failed to clone registry: ${message}`);\n }\n}\n\nexport async function fetchRegistry(location: RegistryLocation): Promise<string> {\n if (location.type === \"local\") {\n if (!fs.existsSync(location.path)) {\n throw new ConfigError(`Registry not found: ${location.path}`);\n }\n return location.path;\n }\n\n const cacheDir = path.join(os.tmpdir(), CACHE.registryCacheDir);\n const repoDir = path.join(cacheDir, `${location.owner}-${location.repo}`);\n\n if (fs.existsSync(repoDir)) {\n await updateExistingRepo(repoDir, location.ref);\n }\n\n if (!fs.existsSync(repoDir)) {\n await cloneRepo(location, repoDir);\n }\n\n return repoDir;\n}\n\nexport function loadRuleset(registryDir: string, rulesetName: string): Config {\n const rulesetPath = path.join(registryDir, \"rulesets\", `${rulesetName}.toml`);\n\n if (!fs.existsSync(rulesetPath)) {\n throw new ConfigError(`Ruleset not found: ${rulesetName} (expected at ${rulesetPath})`);\n }\n\n const content = fs.readFileSync(rulesetPath, \"utf-8\");\n\n let parsed: unknown;\n try {\n parsed = toml.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new ConfigError(`Failed to parse ruleset ${rulesetName}: ${message}`);\n }\n\n const result = configSchema.safeParse(parsed);\n if (!result.success) {\n const errors = result.error.issues.map((e) => `${e.path.join(\".\")}: ${e.message}`).join(\", \");\n throw new ConfigError(`Invalid ruleset ${rulesetName}: ${errors}`);\n }\n\n return result.data;\n}\n\ntype CodeConfig = NonNullable<Config[\"code\"]>;\n\nfunction mergeToolConfig<T extends object>(base?: T, override?: T): T | undefined {\n if (!override) {\n return base;\n }\n return { ...base, ...override };\n}\n\nfunction mergeLinting(\n base: CodeConfig[\"linting\"],\n override: CodeConfig[\"linting\"]\n): CodeConfig[\"linting\"] {\n if (!override) {\n return base;\n }\n return {\n ...base,\n eslint: mergeToolConfig(base?.eslint, override.eslint),\n ruff: mergeToolConfig(base?.ruff, override.ruff),\n };\n}\n\nfunction mergeTypes(base: CodeConfig[\"types\"], override: CodeConfig[\"types\"]): CodeConfig[\"types\"] {\n if (!override) {\n return base;\n }\n return {\n ...base,\n tsc: mergeToolConfig(base?.tsc, override.tsc),\n ty: mergeToolConfig(base?.ty, override.ty),\n };\n}\n\nfunction mergeUnused(\n base: CodeConfig[\"unused\"],\n override: CodeConfig[\"unused\"]\n): CodeConfig[\"unused\"] {\n if (!override) {\n return base;\n }\n return {\n ...base,\n knip: mergeToolConfig(base?.knip, override.knip),\n vulture: mergeToolConfig(base?.vulture, override.vulture),\n };\n}\n\nfunction mergeSecurity(\n base: CodeConfig[\"security\"],\n override: CodeConfig[\"security\"]\n): CodeConfig[\"security\"] {\n if (!override) {\n return base;\n }\n return {\n ...base,\n secrets: mergeToolConfig(base?.secrets, override.secrets),\n pnpmaudit: mergeToolConfig(base?.pnpmaudit, override.pnpmaudit),\n pipaudit: mergeToolConfig(base?.pipaudit, override.pipaudit),\n };\n}\n\nfunction mergeNaming(\n base: CodeConfig[\"naming\"],\n override: CodeConfig[\"naming\"]\n): CodeConfig[\"naming\"] {\n if (!override) {\n return base;\n }\n // enabled has a default value from schema, so it's always defined after parsing\n return {\n enabled: override.enabled,\n rules: override.rules ?? base?.rules,\n };\n}\n\nfunction mergeQuality(\n base: CodeConfig[\"quality\"],\n override: CodeConfig[\"quality\"]\n): CodeConfig[\"quality\"] {\n if (!override) {\n return base;\n }\n return {\n ...base,\n \"disable-comments\": mergeToolConfig(base?.[\"disable-comments\"], override[\"disable-comments\"]),\n };\n}\n\nfunction mergeCodeSection(base: CodeConfig | undefined, override: CodeConfig): CodeConfig {\n return {\n linting: mergeLinting(base?.linting, override.linting),\n types: mergeTypes(base?.types, override.types),\n unused: mergeUnused(base?.unused, override.unused),\n coverage_run: mergeToolConfig(base?.coverage_run, override.coverage_run),\n security: mergeSecurity(base?.security, override.security),\n naming: mergeNaming(base?.naming, override.naming),\n quality: mergeQuality(base?.quality, override.quality),\n };\n}\n\ntype ProcessConfig = NonNullable<Config[\"process\"]>;\n\nfunction mergeHooksConfig(\n base: ProcessConfig[\"hooks\"],\n override: ProcessConfig[\"hooks\"]\n): ProcessConfig[\"hooks\"] {\n if (!override) {\n return base;\n }\n // enabled and require_husky have schema defaults, so they're always defined\n return {\n enabled: override.enabled,\n require_husky: override.require_husky,\n require_hooks: override.require_hooks ?? base?.require_hooks,\n commands: override.commands ?? base?.commands,\n };\n}\n\nfunction mergeCiConfig(\n base: ProcessConfig[\"ci\"],\n override: ProcessConfig[\"ci\"]\n): ProcessConfig[\"ci\"] {\n if (!override) {\n return base;\n }\n return {\n enabled: override.enabled,\n require_workflows: override.require_workflows ?? base?.require_workflows,\n jobs: override.jobs ?? base?.jobs,\n actions: override.actions ?? base?.actions,\n };\n}\n\nfunction mergeBranchesConfig(\n base: ProcessConfig[\"branches\"],\n override: ProcessConfig[\"branches\"]\n): ProcessConfig[\"branches\"] {\n if (!override) {\n return base;\n }\n return {\n enabled: override.enabled,\n require_issue: override.require_issue,\n pattern: override.pattern ?? base?.pattern,\n exclude: override.exclude ?? base?.exclude,\n issue_pattern: override.issue_pattern ?? base?.issue_pattern,\n };\n}\n\nfunction mergePrConfig(\n base: ProcessConfig[\"pr\"],\n override: ProcessConfig[\"pr\"]\n): ProcessConfig[\"pr\"] {\n if (!override) {\n return base;\n }\n return {\n enabled: override.enabled,\n require_issue: override.require_issue,\n max_files: override.max_files ?? base?.max_files,\n max_lines: override.max_lines ?? base?.max_lines,\n issue_keywords: override.issue_keywords ?? base?.issue_keywords,\n };\n}\n\nfunction mergeTicketsConfig(\n base: ProcessConfig[\"tickets\"],\n override: ProcessConfig[\"tickets\"]\n): ProcessConfig[\"tickets\"] {\n if (!override) {\n return base;\n }\n // require_in_commits and require_in_branch have schema defaults, so they're always defined after parsing\n return {\n enabled: override.enabled,\n pattern: override.pattern ?? base?.pattern,\n require_in_commits: override.require_in_commits,\n require_in_branch: override.require_in_branch,\n };\n}\n\nfunction mergeCoverageConfig(\n base: ProcessConfig[\"coverage\"],\n override: ProcessConfig[\"coverage\"]\n): ProcessConfig[\"coverage\"] {\n if (!override) {\n return base;\n }\n // enforce_in has schema default, so it's always defined after parsing\n return {\n enabled: override.enabled,\n min_threshold: override.min_threshold ?? base?.min_threshold,\n enforce_in: override.enforce_in,\n ci_workflow: override.ci_workflow ?? base?.ci_workflow,\n ci_job: override.ci_job ?? base?.ci_job,\n };\n}\n\nfunction mergeCommitsConfig(\n base: ProcessConfig[\"commits\"],\n override: ProcessConfig[\"commits\"]\n): ProcessConfig[\"commits\"] {\n if (!override) {\n return base;\n }\n // require_scope has schema default, so it's always defined after parsing\n return {\n enabled: override.enabled,\n pattern: override.pattern ?? base?.pattern,\n types: override.types ?? base?.types,\n require_scope: override.require_scope,\n max_subject_length: override.max_subject_length ?? base?.max_subject_length,\n };\n}\n\nfunction mergeChangesetsConfig(\n base: ProcessConfig[\"changesets\"],\n override: ProcessConfig[\"changesets\"]\n): ProcessConfig[\"changesets\"] {\n if (!override) {\n return base;\n }\n // validate_format and require_description have schema defaults, so they're always defined after parsing\n return {\n enabled: override.enabled,\n require_for_paths: override.require_for_paths ?? base?.require_for_paths,\n exclude_paths: override.exclude_paths ?? base?.exclude_paths,\n validate_format: override.validate_format,\n allowed_bump_types: override.allowed_bump_types ?? base?.allowed_bump_types,\n require_description: override.require_description,\n min_description_length: override.min_description_length ?? base?.min_description_length,\n };\n}\n\nfunction mergeRepoConfig(\n base: ProcessConfig[\"repo\"],\n override: ProcessConfig[\"repo\"]\n): ProcessConfig[\"repo\"] {\n if (!override) {\n return base;\n }\n // require_branch_protection and require_codeowners have schema defaults\n return {\n enabled: override.enabled,\n require_branch_protection: override.require_branch_protection,\n require_codeowners: override.require_codeowners,\n ruleset: override.ruleset ?? base?.ruleset,\n tag_protection: override.tag_protection ?? base?.tag_protection,\n };\n}\n\nfunction mergeBackupsConfig(\n base: ProcessConfig[\"backups\"],\n override: ProcessConfig[\"backups\"]\n): ProcessConfig[\"backups\"] {\n if (!override) {\n return base;\n }\n // max_age_hours has schema default\n return {\n enabled: override.enabled,\n bucket: override.bucket ?? base?.bucket,\n prefix: override.prefix ?? base?.prefix,\n max_age_hours: override.max_age_hours,\n region: override.region ?? base?.region,\n };\n}\n\nfunction mergeCodeownersConfig(\n base: ProcessConfig[\"codeowners\"],\n override: ProcessConfig[\"codeowners\"]\n): ProcessConfig[\"codeowners\"] {\n if (!override) {\n return base;\n }\n return {\n enabled: override.enabled,\n rules: override.rules ?? base?.rules,\n };\n}\n\n \nfunction mergeDocsConfig(\n base: ProcessConfig[\"docs\"],\n override: ProcessConfig[\"docs\"]\n): ProcessConfig[\"docs\"] {\n if (!override) {\n return base;\n }\n // Fields with schema defaults: enabled, path, enforcement, staleness_days\n return {\n enabled: override.enabled,\n path: override.path,\n enforcement: override.enforcement,\n allowlist: override.allowlist ?? base?.allowlist,\n max_files: override.max_files ?? base?.max_files,\n max_file_lines: override.max_file_lines ?? base?.max_file_lines,\n max_total_kb: override.max_total_kb ?? base?.max_total_kb,\n staleness_days: override.staleness_days,\n stale_mappings: override.stale_mappings ?? base?.stale_mappings,\n min_coverage: override.min_coverage ?? base?.min_coverage,\n coverage_paths: override.coverage_paths ?? base?.coverage_paths,\n exclude_patterns: override.exclude_patterns ?? base?.exclude_patterns,\n types: override.types ?? base?.types,\n };\n}\n\n \nfunction mergeProcessSection(\n base: ProcessConfig | undefined,\n override: ProcessConfig\n): ProcessConfig {\n return {\n hooks: mergeHooksConfig(base?.hooks, override.hooks),\n ci: mergeCiConfig(base?.ci, override.ci),\n branches: mergeBranchesConfig(base?.branches, override.branches),\n commits: mergeCommitsConfig(base?.commits, override.commits),\n changesets: mergeChangesetsConfig(base?.changesets, override.changesets),\n pr: mergePrConfig(base?.pr, override.pr),\n tickets: mergeTicketsConfig(base?.tickets, override.tickets),\n coverage: mergeCoverageConfig(base?.coverage, override.coverage),\n repo: mergeRepoConfig(base?.repo, override.repo),\n backups: mergeBackupsConfig(base?.backups, override.backups),\n codeowners: mergeCodeownersConfig(base?.codeowners, override.codeowners),\n docs: mergeDocsConfig(base?.docs, override.docs),\n };\n}\n\nexport function mergeConfigs(base: Config, override: Config): Config {\n const merged: Config = { ...base };\n\n if (override.code) {\n merged.code = mergeCodeSection(base.code, override.code);\n }\n\n if (override.process) {\n merged.process = mergeProcessSection(base.process, override.process);\n }\n\n if (override.infra) {\n merged.infra = override.infra;\n }\n\n if (override.monorepo) {\n merged.monorepo = override.monorepo;\n }\n\n return merged;\n}\n\nexport async function resolveExtends(config: Config, configDir: string): Promise<Config> {\n if (!config.extends) {\n return config;\n }\n\n const { registry, rulesets } = config.extends;\n const location = parseRegistryUrl(registry, configDir);\n const registryDir = await fetchRegistry(location);\n\n let mergedConfig: Config = {};\n for (const rulesetName of rulesets) {\n const ruleset = loadRuleset(registryDir, rulesetName);\n mergedConfig = mergeConfigs(mergedConfig, ruleset);\n }\n\n // Local config overrides registry config (include all domains)\n const localConfig: Config = {\n code: config.code,\n process: config.process,\n infra: config.infra,\n monorepo: config.monorepo,\n };\n return mergeConfigs(mergedConfig, localConfig);\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport TOML from \"@iarna/toml\";\n\nimport { resolveExtends } from \"./registry.js\";\nimport { type Config, configSchema, defaultConfig } from \"./schema.js\";\n\n/** Config file name */\nexport const CONFIG_FILE_NAME = \"standards.toml\";\n\ninterface LoadConfigResult {\n config: Config;\n configPath: string;\n}\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n\n/**\n * Check if a path is a broken symlink\n */\nfunction isBrokenSymlink(filePath: string): boolean {\n try {\n const stats = fs.lstatSync(filePath);\n if (stats.isSymbolicLink()) {\n // It's a symlink - check if target exists\n try {\n fs.statSync(filePath);\n return false; // Target exists, not broken\n } catch {\n return true; // Target doesn't exist, broken symlink\n }\n }\n return false; // Not a symlink\n } catch {\n return false; // Path doesn't exist at all\n }\n}\n\n/**\n * Find standards.toml by walking up the directory tree\n */\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = path.resolve(startDir);\n const root = path.parse(currentDir).root;\n\n while (currentDir !== root) {\n const configPath = path.join(currentDir, CONFIG_FILE_NAME);\n if (isBrokenSymlink(configPath)) {\n throw new ConfigError(`${CONFIG_FILE_NAME} exists but is a broken symlink: ${configPath}`);\n }\n if (fs.existsSync(configPath)) {\n return configPath;\n }\n currentDir = path.dirname(currentDir);\n }\n\n // Check root directory too\n const rootConfig = path.join(root, CONFIG_FILE_NAME);\n if (isBrokenSymlink(rootConfig)) {\n throw new ConfigError(`${CONFIG_FILE_NAME} exists but is a broken symlink: ${rootConfig}`);\n }\n return fs.existsSync(rootConfig) ? rootConfig : null;\n}\n\n/**\n * Resolve and validate config file path\n * Always returns an absolute path to ensure consistent behavior\n */\nfunction resolveConfigPath(configPath?: string): string {\n const resolved = configPath ?? findConfigFile();\n if (!resolved) {\n throw new ConfigError(`No ${CONFIG_FILE_NAME} found. Create one or specify --config path.`);\n }\n // Convert to absolute path for consistent behavior across tools\n const absolutePath = path.resolve(resolved);\n if (!fs.existsSync(absolutePath)) {\n throw new ConfigError(`Config file not found: ${resolved}`);\n }\n return absolutePath;\n}\n\n/**\n * Parse TOML file content\n */\nfunction parseTomlFile(filePath: string): unknown {\n try {\n const content = fs.readFileSync(filePath, \"utf-8\");\n return TOML.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n throw new ConfigError(`Failed to parse ${CONFIG_FILE_NAME}: ${message}`);\n }\n}\n\n/**\n * Validate config against schema\n */\nfunction validateConfig(rawConfig: unknown): Config {\n const result = configSchema.safeParse(rawConfig);\n if (!result.success) {\n const errors = result.error.issues\n .map((e) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\");\n throw new ConfigError(`Invalid ${CONFIG_FILE_NAME} configuration:\\n${errors}`);\n }\n return result.data;\n}\n\n/**\n * Load and parse standards.toml configuration (sync version without extends resolution)\n * Use loadConfigAsync for full extends support\n */\nexport function loadConfig(configPath?: string): LoadConfigResult {\n const resolvedPath = resolveConfigPath(configPath);\n const rawConfig = parseTomlFile(resolvedPath);\n const validatedConfig = validateConfig(rawConfig);\n const config = mergeWithDefaults(validatedConfig);\n return { config, configPath: resolvedPath };\n}\n\n/**\n * Load and parse standards.toml configuration with extends resolution\n */\nexport async function loadConfigAsync(configPath?: string): Promise<LoadConfigResult> {\n const resolvedPath = resolveConfigPath(configPath);\n const rawConfig = parseTomlFile(resolvedPath);\n const validatedConfig = validateConfig(rawConfig);\n\n // Resolve extends if present\n const configDir = path.dirname(resolvedPath);\n const resolvedConfig = await resolveExtends(validatedConfig, configDir);\n\n const config = mergeWithDefaults(resolvedConfig);\n return { config, configPath: resolvedPath };\n}\n\n/** Merge two optional objects, with right side taking precedence */\nfunction merge<T extends object>(a: T | undefined, b: T | undefined): T {\n return { ...a, ...b } as T;\n}\n\ntype CodeConfig = NonNullable<Config[\"code\"]>;\n\nfunction mergeLinting(c: Config, dc: Config): CodeConfig[\"linting\"] {\n const cl = c.code?.linting;\n const dl = dc.code?.linting;\n return { eslint: merge(dl?.eslint, cl?.eslint), ruff: merge(dl?.ruff, cl?.ruff) };\n}\n\nfunction mergeSecurity(c: Config, dc: Config): CodeConfig[\"security\"] {\n const cs = c.code?.security;\n const ds = dc.code?.security;\n return {\n secrets: merge(ds?.secrets, cs?.secrets),\n pnpmaudit: merge(ds?.pnpmaudit, cs?.pnpmaudit),\n pipaudit: merge(ds?.pipaudit, cs?.pipaudit),\n };\n}\n\nfunction mergeTypes(c: Config, dc: Config): CodeConfig[\"types\"] {\n return {\n tsc: merge(dc.code?.types?.tsc, c.code?.types?.tsc),\n ty: merge(dc.code?.types?.ty, c.code?.types?.ty),\n };\n}\n\nfunction mergeUnused(c: Config, dc: Config): CodeConfig[\"unused\"] {\n return {\n knip: merge(dc.code?.unused?.knip, c.code?.unused?.knip),\n vulture: merge(dc.code?.unused?.vulture, c.code?.unused?.vulture),\n };\n}\n\nfunction mergeCoverageRun(c: Config, dc: Config): CodeConfig[\"coverage_run\"] {\n return merge(dc.code?.coverage_run, c.code?.coverage_run);\n}\n\nfunction mergeNaming(c: Config, dc: Config): CodeConfig[\"naming\"] {\n const cn = c.code?.naming;\n const dn = dc.code?.naming;\n // For naming, we want to preserve the rules array from user config\n return {\n enabled: cn?.enabled ?? dn?.enabled ?? false,\n rules: cn?.rules ?? dn?.rules,\n };\n}\n\nfunction mergeQuality(c: Config, dc: Config): CodeConfig[\"quality\"] {\n const cq = c.code?.quality;\n const dq = dc.code?.quality;\n return {\n \"disable-comments\": merge(dq?.[\"disable-comments\"], cq?.[\"disable-comments\"]),\n };\n}\n\nfunction mergeCode(c: Config, dc: Config): CodeConfig {\n return {\n linting: mergeLinting(c, dc),\n types: mergeTypes(c, dc),\n unused: mergeUnused(c, dc),\n coverage_run: mergeCoverageRun(c, dc),\n security: mergeSecurity(c, dc),\n naming: mergeNaming(c, dc),\n quality: mergeQuality(c, dc),\n };\n}\n\ntype ProcessConfig = NonNullable<Config[\"process\"]>;\ntype HooksConfig = NonNullable<ProcessConfig[\"hooks\"]>;\ntype CiConfig = NonNullable<ProcessConfig[\"ci\"]>;\ntype BranchesConfig = NonNullable<ProcessConfig[\"branches\"]>;\ntype CommitsConfig = NonNullable<ProcessConfig[\"commits\"]>;\ntype ChangesetsConfig = NonNullable<ProcessConfig[\"changesets\"]>;\ntype PrConfig = NonNullable<ProcessConfig[\"pr\"]>;\ntype TicketsConfig = NonNullable<ProcessConfig[\"tickets\"]>;\ntype CoverageConfig = NonNullable<ProcessConfig[\"coverage\"]>;\ntype RepoConfig = NonNullable<ProcessConfig[\"repo\"]>;\ntype BackupsConfig = NonNullable<ProcessConfig[\"backups\"]>;\ntype CodeownersConfig = NonNullable<ProcessConfig[\"codeowners\"]>;\ntype DocsConfig = NonNullable<ProcessConfig[\"docs\"]>;\ntype ForbiddenFilesConfig = NonNullable<ProcessConfig[\"forbidden_files\"]>;\n\nconst defaultHooks: HooksConfig = { enabled: false, require_husky: true };\nconst defaultCi: CiConfig = { enabled: false };\nconst defaultBranches: BranchesConfig = { enabled: false, require_issue: false };\nconst defaultCommits: CommitsConfig = { enabled: false, require_scope: false };\nconst defaultChangesets: ChangesetsConfig = {\n enabled: false,\n validate_format: true,\n require_description: true,\n};\nconst defaultPr: PrConfig = { enabled: false, require_issue: false };\nconst defaultTickets: TicketsConfig = {\n enabled: false,\n require_in_commits: true,\n require_in_branch: false,\n};\nconst defaultCoverage: CoverageConfig = { enabled: false, enforce_in: \"config\" };\nconst defaultRepo: RepoConfig = {\n enabled: false,\n require_branch_protection: false,\n require_codeowners: false,\n};\nconst defaultBackups: BackupsConfig = { enabled: false, max_age_hours: 24 };\nconst defaultCodeowners: CodeownersConfig = { enabled: false };\nconst defaultDocs: DocsConfig = {\n enabled: false,\n path: \"docs/\",\n enforcement: \"warn\",\n staleness_days: 30,\n};\nconst defaultForbiddenFiles: ForbiddenFilesConfig = { enabled: false };\n\n/** Merge a single process config section with defaults */\nfunction mergeProcessSection<T>(defaultVal: T, dcVal: T | undefined, cVal: T | undefined): T {\n return { ...defaultVal, ...dcVal, ...cVal };\n}\n\nfunction mergeProcessHooks(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): HooksConfig {\n return mergeProcessSection(defaultHooks, dcp?.hooks, cp?.hooks);\n}\n\nfunction mergeProcessCi(cp: ProcessConfig | undefined, dcp: ProcessConfig | undefined): CiConfig {\n return mergeProcessSection(defaultCi, dcp?.ci, cp?.ci);\n}\n\nfunction mergeProcessBranches(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): BranchesConfig {\n return mergeProcessSection(defaultBranches, dcp?.branches, cp?.branches);\n}\n\nfunction mergeProcessCommits(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): CommitsConfig {\n return mergeProcessSection(defaultCommits, dcp?.commits, cp?.commits);\n}\n\nfunction mergeProcessChangesets(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): ChangesetsConfig {\n return mergeProcessSection(defaultChangesets, dcp?.changesets, cp?.changesets);\n}\n\nfunction mergeProcessPr(cp: ProcessConfig | undefined, dcp: ProcessConfig | undefined): PrConfig {\n return mergeProcessSection(defaultPr, dcp?.pr, cp?.pr);\n}\n\nfunction mergeProcessTickets(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): TicketsConfig {\n return mergeProcessSection(defaultTickets, dcp?.tickets, cp?.tickets);\n}\n\nfunction mergeProcessCoverage(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): CoverageConfig {\n return mergeProcessSection(defaultCoverage, dcp?.coverage, cp?.coverage);\n}\n\nfunction mergeProcessRepo(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): RepoConfig {\n return mergeProcessSection(defaultRepo, dcp?.repo, cp?.repo);\n}\n\nfunction mergeProcessBackups(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): BackupsConfig {\n return mergeProcessSection(defaultBackups, dcp?.backups, cp?.backups);\n}\n\nfunction mergeProcessCodeowners(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): CodeownersConfig {\n const cco = cp?.codeowners;\n const dco = dcp?.codeowners;\n // Merge rules arrays: registry rules + project rules (deduplicated by pattern)\n const registryRules = dco?.rules ?? [];\n const projectRules = cco?.rules ?? [];\n // Project rules can override registry rules for the same pattern\n const ruleMap = new Map<string, { pattern: string; owners: string[] }>();\n for (const rule of registryRules) {\n ruleMap.set(rule.pattern, rule);\n }\n for (const rule of projectRules) {\n ruleMap.set(rule.pattern, rule);\n }\n const mergedRules = Array.from(ruleMap.values());\n return {\n ...defaultCodeowners,\n ...dco,\n ...cco,\n rules: mergedRules.length > 0 ? mergedRules : undefined,\n };\n}\n\nfunction mergeProcessDocs(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): DocsConfig {\n return mergeProcessSection(defaultDocs, dcp?.docs, cp?.docs);\n}\n\nfunction mergeProcessForbiddenFiles(\n cp: ProcessConfig | undefined,\n dcp: ProcessConfig | undefined\n): ForbiddenFilesConfig {\n return mergeProcessSection(defaultForbiddenFiles, dcp?.forbidden_files, cp?.forbidden_files);\n}\n\nfunction mergeProcess(c: Config, dc: Config): ProcessConfig {\n return {\n hooks: mergeProcessHooks(c.process, dc.process),\n ci: mergeProcessCi(c.process, dc.process),\n branches: mergeProcessBranches(c.process, dc.process),\n commits: mergeProcessCommits(c.process, dc.process),\n changesets: mergeProcessChangesets(c.process, dc.process),\n pr: mergeProcessPr(c.process, dc.process),\n tickets: mergeProcessTickets(c.process, dc.process),\n coverage: mergeProcessCoverage(c.process, dc.process),\n repo: mergeProcessRepo(c.process, dc.process),\n backups: mergeProcessBackups(c.process, dc.process),\n codeowners: mergeProcessCodeowners(c.process, dc.process),\n docs: mergeProcessDocs(c.process, dc.process),\n forbidden_files: mergeProcessForbiddenFiles(c.process, dc.process),\n };\n}\n\n/**\n * Deep merge config with defaults\n */\nfunction mergeWithDefaults(config: Config): Config {\n return {\n code: mergeCode(config, defaultConfig),\n process: mergeProcess(config, defaultConfig),\n infra: {\n enabled: config.infra?.enabled ?? defaultConfig.infra?.enabled ?? false,\n manifest: config.infra?.manifest ?? defaultConfig.infra?.manifest ?? \"infra-manifest.json\",\n },\n monorepo: config.monorepo,\n };\n}\n\n/**\n * Get the project root directory (where standards.toml is located)\n */\nexport function getProjectRoot(configPath: string): string {\n return path.dirname(configPath);\n}\n\n/** Information about a config override */\nexport interface ConfigOverride {\n section: string;\n key: string;\n registryValue: string;\n projectValue: string;\n}\n\n/** Check if a project rule overrides a registry rule */\nfunction checkRuleOverride(\n projectRule: { pattern: string; owners: string[] },\n registryOwners: string[] | undefined\n): ConfigOverride | null {\n if (!registryOwners) {\n return null;\n }\n const registryStr = registryOwners.join(\" \");\n const projectStr = projectRule.owners.join(\" \");\n if (registryStr === projectStr) {\n return null;\n }\n return {\n section: \"process.codeowners.rules\",\n key: projectRule.pattern,\n registryValue: registryStr,\n projectValue: projectStr,\n };\n}\n\n/** Detect CODEOWNERS rule overrides between registry and project config */\nfunction detectCodeownersOverrides(\n registryConfig: Config | undefined,\n projectConfig: Config | undefined\n): ConfigOverride[] {\n const registryRules = registryConfig?.process?.codeowners?.rules ?? [];\n const projectRules = projectConfig?.process?.codeowners?.rules ?? [];\n const registryMap = new Map(registryRules.map((r) => [r.pattern, r.owners]));\n\n return projectRules\n .map((rule) => checkRuleOverride(rule, registryMap.get(rule.pattern)))\n .filter((o): o is ConfigOverride => o !== null);\n}\n\n/** Load registry config from extends */\nasync function loadRegistryConfig(\n extendsConfig: NonNullable<Config[\"extends\"]>,\n configDir: string\n): Promise<Config> {\n const registryModule = await import(\"./registry.js\");\n const loc = registryModule.parseRegistryUrl(extendsConfig.registry, configDir);\n const registryDir = await registryModule.fetchRegistry(loc);\n\n let config: Config = {};\n for (const name of extendsConfig.rulesets) {\n config = registryModule.mergeConfigs(config, registryModule.loadRuleset(registryDir, name));\n }\n return config;\n}\n\n/**\n * Load config and detect any overrides from registry\n * Returns both the merged config and information about overrides\n */\nexport async function loadConfigWithOverrides(\n configPath?: string\n): Promise<LoadConfigResult & { overrides: ConfigOverride[] }> {\n const resolvedPath = resolveConfigPath(configPath);\n const validatedConfig = validateConfig(parseTomlFile(resolvedPath));\n\n let overrides: ConfigOverride[] = [];\n if (validatedConfig.extends) {\n const registryConfig = await loadRegistryConfig(\n validatedConfig.extends,\n path.dirname(resolvedPath)\n );\n overrides = detectCodeownersOverrides(registryConfig, validatedConfig);\n }\n\n const { config, configPath: finalPath } = await loadConfigAsync(configPath);\n return { config, configPath: finalPath, overrides };\n}\n"," \nimport { minimatch } from \"minimatch\";\nimport { z } from \"zod\";\n\n/**\n * Count unclosed brackets and braces in a pattern, respecting escapes.\n */\nfunction countUnclosedDelimiters(pattern: string): { brackets: number; braces: number } {\n let brackets = 0;\n let braces = 0;\n for (let i = 0; i < pattern.length; i++) {\n if (pattern[i] === \"\\\\\" && i + 1 < pattern.length) {\n i++; // Skip escaped character\n continue;\n }\n switch (pattern[i]) {\n case \"[\":\n brackets++;\n break;\n case \"]\":\n if (brackets > 0) {\n brackets--;\n }\n break;\n case \"{\":\n braces++;\n break;\n case \"}\":\n if (braces > 0) {\n braces--;\n }\n break;\n }\n }\n return { brackets, braces };\n}\n\n/**\n * Validate that a string is a valid glob pattern.\n * Checks for balanced brackets/braces since minimatch is too lenient.\n */\nfunction isValidGlobPattern(pattern: string): { valid: boolean; error?: string } {\n if (pattern.length === 0) {\n return { valid: false, error: \"empty pattern\" };\n }\n\n const unclosed = countUnclosedDelimiters(pattern);\n if (unclosed.brackets > 0) {\n return { valid: false, error: \"unclosed bracket '['\" };\n }\n if (unclosed.braces > 0) {\n return { valid: false, error: \"unclosed brace '{'\" };\n }\n\n try {\n const result = minimatch.makeRe(pattern);\n return result === false ? { valid: false, error: \"invalid pattern syntax\" } : { valid: true };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Invalid glob pattern\";\n return { valid: false, error: message };\n }\n}\n\n/**\n * Zod schema for a valid glob pattern string\n */\nconst globPatternSchema = z.string().superRefine((pattern, ctx) => {\n const result = isValidGlobPattern(pattern);\n if (!result.valid) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid glob pattern: \"${pattern}\" - ${result.error}`,\n });\n }\n});\n\n/**\n * Zod schema for standards.toml configuration\n */\n\n// =============================================================================\n// ESLint Configuration\n// =============================================================================\n\n/** ESLint rule severity */\nconst eslintRuleSeverity = z.enum([\"off\", \"warn\", \"error\"]);\n\n/**\n * ESLint rule with options in TOML-friendly object format.\n * Example: { severity = \"error\", max = 10 }\n * The 'severity' key is required, all other keys are rule-specific options.\n */\nconst eslintRuleWithOptions = z\n .object({\n severity: eslintRuleSeverity,\n })\n .catchall(z.unknown()); // Allow any additional options (max, skipBlankLines, etc.)\n\n/**\n * ESLint rule value - can be:\n * - severity string: \"error\"\n * - object with severity and options: { severity: \"error\", max: 10 }\n */\nconst eslintRuleValue = z.union([eslintRuleSeverity, eslintRuleWithOptions]);\n\n/** ESLint rules configuration */\nconst eslintRulesSchema = z.record(z.string(), eslintRuleValue).optional();\n\n/** ESLint configuration */\nconst eslintConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(true),\n files: z.array(z.string()).optional(), // Glob patterns for files to lint\n ignore: z.array(z.string()).optional(), // Glob patterns to ignore\n \"max-warnings\": z.number().int().nonnegative().optional(), // Max warnings before failure\n rules: eslintRulesSchema, // Required rules for audit (verifies eslint.config.js)\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Ruff Configuration\n// =============================================================================\n\n/** Ruff lint configuration */\nconst ruffLintSchema = z\n .object({\n select: z.array(z.string()).optional(),\n ignore: z.array(z.string()).optional(),\n })\n .strict()\n .optional();\n\n/** Ruff configuration */\nconst ruffConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(true),\n \"line-length\": z.number().int().positive().optional(),\n lint: ruffLintSchema,\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n// =============================================================================\n// TypeScript Configuration\n// =============================================================================\n\n/** TypeScript compiler options that can be required via audit */\nconst tscCompilerOptionsSchema = z\n .object({\n strict: z.boolean().optional(),\n noImplicitAny: z.boolean().optional(),\n strictNullChecks: z.boolean().optional(),\n noUnusedLocals: z.boolean().optional(),\n noUnusedParameters: z.boolean().optional(),\n noImplicitReturns: z.boolean().optional(),\n noFallthroughCasesInSwitch: z.boolean().optional(),\n esModuleInterop: z.boolean().optional(),\n skipLibCheck: z.boolean().optional(),\n forceConsistentCasingInFileNames: z.boolean().optional(),\n })\n .strict()\n .optional();\n\n/** TypeScript compiler configuration */\nconst tscConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n require: tscCompilerOptionsSchema, // Required compiler options for audit\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n// =============================================================================\n// ty Configuration (Python Type Checking)\n// =============================================================================\n\n/** ty Python type checker configuration */\nconst tyConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Knip Configuration (Unused Code Detection)\n// =============================================================================\n\n/** Knip configuration */\nconst knipConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Vulture Configuration (Python Dead Code Detection)\n// =============================================================================\n\n/** Vulture configuration */\nconst vultureConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Coverage Run Configuration\n// =============================================================================\n\n/** Coverage run test runner type */\nconst coverageRunnerSchema = z.enum([\"vitest\", \"jest\", \"pytest\", \"auto\"]);\n\n/** Coverage run configuration - runs tests and verifies coverage threshold */\nconst coverageRunConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n min_threshold: z.number().int().min(0).max(100).optional().default(80), // Minimum coverage percentage\n runner: coverageRunnerSchema.optional().default(\"auto\"), // Test runner to use\n command: z.string().optional(), // Custom command to run tests with coverage\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Security Configuration\n// =============================================================================\n\n/** Secrets (Gitleaks) configuration */\nconst secretsConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n scan_mode: z\n .enum([\"branch\", \"files\", \"staged\", \"full\"])\n .optional()\n .default(\"branch\"), // branch: scan current branch commits, files: scan filesystem, staged: staged files only, full: entire git history\n base_branch: z.string().optional().default(\"main\"), // Branch to compare against for \"branch\" mode\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n/** pnpm audit configuration */\nconst pnpmauditConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n exclude_dev: z.boolean().optional().default(true),\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n/** pip-audit configuration */\nconst pipauditConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n dependencies: z.array(z.string()).optional(), // Custom dependency files for drift tracking\n })\n .strict()\n .optional();\n\n/** Code security configuration */\nconst codeSecuritySchema = z\n .object({\n secrets: secretsConfigSchema,\n pnpmaudit: pnpmauditConfigSchema,\n pipaudit: pipauditConfigSchema,\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Naming Conventions Configuration\n// =============================================================================\n\n/** Supported case types for naming conventions */\nconst caseTypeSchema = z.enum([\"kebab-case\", \"snake_case\", \"camelCase\", \"PascalCase\"]);\n\n/** Helper to validate no duplicate values in array */\nconst uniqueArraySchema = <T extends z.ZodTypeAny>(schema: T) =>\n z.array(schema).refine((arr) => new Set(arr).size === arr.length, {\n message: \"Duplicate values not allowed\",\n });\n\n/** Helper to validate no duplicate values in array with minimum length */\nconst uniqueArraySchemaMin1 = <T extends z.ZodTypeAny>(schema: T) =>\n z\n .array(schema)\n .min(1, \"At least one value is required\")\n .refine((arr) => new Set(arr).size === arr.length, {\n message: \"Duplicate values not allowed\",\n });\n\n/** Single naming rule */\nconst namingRuleSchema = z\n .object({\n extensions: uniqueArraySchemaMin1(z.string()), // e.g., [\"ts\", \"tsx\"] - no duplicates allowed, at least one required\n file_case: caseTypeSchema,\n folder_case: caseTypeSchema,\n exclude: z.array(z.string()).optional(), // Glob patterns to exclude, e.g., [\"tests/**\"]\n allow_dynamic_routes: z.boolean().optional(), // Allow Next.js/Remix dynamic route folders: [id], [...slug], (group)\n })\n .strict();\n\n/** Naming conventions configuration */\nconst namingConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n rules: z.array(namingRuleSchema).optional(),\n })\n .strict()\n .superRefine((data, ctx) => {\n if (!data.rules || data.rules.length <= 1) {\n return;\n }\n\n const extensionToRuleIndex = new Map<string, number>();\n for (let i = 0; i < data.rules.length; i++) {\n for (const ext of data.rules[i].extensions) {\n const existing = extensionToRuleIndex.get(ext);\n if (existing !== undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Extension \"${ext}\" appears in multiple naming rules (rules ${existing + 1} and ${i + 1}). Each extension can only appear in one rule.`,\n path: [\"rules\", i, \"extensions\"],\n });\n } else {\n extensionToRuleIndex.set(ext, i);\n }\n }\n }\n })\n .optional();\n\n// =============================================================================\n// Quality Configuration (Disable Comments Detection)\n// =============================================================================\n\n/** Disable comments configuration */\nconst disableCommentsConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n patterns: z.array(z.string()).optional(), // Override default patterns\n extensions: uniqueArraySchema(z.string()).optional(), // File extensions to scan - no duplicates allowed\n exclude: z.array(z.string()).optional(), // Glob patterns to exclude\n })\n .strict()\n .optional();\n\n/** Code quality configuration */\nconst codeQualitySchema = z\n .object({\n \"disable-comments\": disableCommentsConfigSchema,\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Code Domain Configuration\n// =============================================================================\n\n/** Code linting configuration */\nconst codeLintingSchema = z\n .object({\n eslint: eslintConfigSchema,\n ruff: ruffConfigSchema,\n })\n .strict()\n .optional();\n\n/** Code type checking configuration */\nconst codeTypesSchema = z\n .object({\n tsc: tscConfigSchema,\n ty: tyConfigSchema,\n })\n .strict()\n .optional();\n\n/** Code unused detection configuration */\nconst codeUnusedSchema = z\n .object({\n knip: knipConfigSchema,\n vulture: vultureConfigSchema,\n })\n .strict()\n .optional();\n\n/** Code domain configuration */\nconst codeSchema = z\n .object({\n linting: codeLintingSchema,\n types: codeTypesSchema,\n unused: codeUnusedSchema,\n coverage_run: coverageRunConfigSchema,\n security: codeSecuritySchema,\n naming: namingConfigSchema,\n quality: codeQualitySchema,\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Process Domain Configuration\n// =============================================================================\n\n/** Hook commands configuration - maps hook name to required commands */\nconst hookCommandsSchema = z.record(z.string(), z.array(z.string())).optional();\n\n/** Git hooks (husky) configuration */\nconst hooksConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n require_husky: z.boolean().optional().default(true), // Require .husky/ directory\n require_hooks: z.array(z.string()).optional(), // e.g., [\"pre-commit\", \"pre-push\"]\n commands: hookCommandsSchema, // e.g., { \"pre-commit\": [\"lint-staged\"] }\n protected_branches: z.array(z.string()).optional(), // e.g., [\"main\", \"master\"] - verify pre-push prevents direct pushes\n })\n .strict()\n .optional();\n\n/**\n * CI commands configuration value - can be:\n * - Array of strings: commands required anywhere in workflow\n * - Record mapping job names to arrays: commands required in specific jobs\n */\nconst ciCommandsValueSchema = z.union([\n z.array(z.string()), // Workflow-level: [\"cmd1\", \"cmd2\"]\n z.record(z.string(), z.array(z.string())), // Job-level: { jobName: [\"cmd1\"] }\n]);\n\n/** CI commands schema - maps workflow file to required commands */\nconst ciCommandsSchema = z.record(z.string(), ciCommandsValueSchema).optional();\n\n/** CI/CD workflows configuration */\nconst ciConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n require_workflows: z.array(z.string()).optional(), // e.g., [\"ci.yml\", \"release.yml\"]\n jobs: z.record(z.string(), z.array(z.string())).optional(), // e.g., { \"ci.yml\": [\"test\", \"lint\"] }\n actions: z.record(z.string(), z.array(z.string())).optional(), // e.g., { \"ci.yml\": [\"actions/checkout\"] }\n commands: ciCommandsSchema, // e.g., { \"ci.yml\": [\"conform code check\"] } or { \"ci.yml\": { \"test\": [\"npm test\"] } }\n })\n .strict()\n .optional();\n\n/** Branch naming configuration */\nconst branchesConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n pattern: z.string().optional(), // Regex pattern for branch names\n exclude: z.array(z.string()).optional(), // Branches to skip (e.g., [\"main\", \"master\"])\n require_issue: z.boolean().optional().default(false), // Require issue number in branch name\n issue_pattern: z.string().optional(), // Regex to extract issue number (default: captures number after type/)\n })\n .strict()\n .optional();\n\n/** Commit message format configuration */\nconst commitsConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n pattern: z.string().optional(), // Regex pattern for commit messages (e.g., conventional commits)\n types: z.array(z.string()).optional(), // Allowed commit types (e.g., [\"feat\", \"fix\", \"chore\"])\n require_scope: z.boolean().optional().default(false), // Require scope like feat(api): ...\n max_subject_length: z.number().int().positive().optional(), // Max length of subject line\n })\n .strict()\n .optional();\n\n/** Changeset bump type */\nconst changesetBumpTypeSchema = z.enum([\"patch\", \"minor\", \"major\"]);\n\n/** Changeset validation configuration */\nconst changesetsConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n require_for_paths: z.array(z.string()).optional(), // Glob patterns that require changesets (e.g., [\"src/**\"])\n exclude_paths: z.array(z.string()).optional(), // Paths that don't require changesets (e.g., [\"**/*.test.ts\"])\n validate_format: z.boolean().optional().default(true), // Validate changeset file format (frontmatter, description)\n allowed_bump_types: z.array(changesetBumpTypeSchema).optional(), // Restrict allowed bump types (e.g., [\"patch\", \"minor\"])\n require_description: z.boolean().optional().default(true), // Require non-empty description\n min_description_length: z.number().int().positive().optional(), // Minimum description length\n })\n .strict()\n .optional();\n\n/** PR configuration */\nconst prConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n max_files: z.number().int().positive().optional(), // Max files changed in PR\n max_lines: z.number().int().positive().optional(), // Max lines changed (additions + deletions)\n require_issue: z.boolean().optional().default(false), // Require issue reference in PR description\n issue_keywords: z.array(z.string()).optional(), // Keywords that link to issues (e.g., [\"Closes\", \"Fixes\", \"Resolves\"])\n exclude: z.array(globPatternSchema).optional(), // Glob patterns to exclude from size calculation (e.g., [\"*.lock\", \"**/*.snap\"])\n })\n .strict()\n .optional();\n\n/** Ticket reference validation configuration */\nconst ticketsConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n pattern: z.string().optional(), // Regex pattern for ticket IDs (e.g., \"^(ABC|XYZ)-[0-9]+\")\n require_in_commits: z.boolean().optional().default(true), // Require ticket in commit messages\n require_in_branch: z.boolean().optional().default(false), // Require ticket in branch name\n })\n .strict()\n .optional();\n\n/** Coverage enforcement mode */\nconst coverageEnforceInSchema = z.enum([\"ci\", \"config\", \"both\"]);\n\n/** Coverage enforcement configuration */\nconst coverageConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n min_threshold: z.number().int().min(0).max(100).optional(), // Minimum coverage percentage\n enforce_in: coverageEnforceInSchema.optional().default(\"config\"), // Where to verify coverage\n ci_workflow: z.string().optional(), // Workflow file to check (e.g., \"ci.yml\")\n ci_job: z.string().optional(), // Job name to check (e.g., \"test\")\n })\n .strict()\n .optional();\n\n/** Bypass actor type for GitHub Rulesets */\nconst bypassActorTypeSchema = z.enum([\n \"Integration\", // GitHub App\n \"OrganizationAdmin\", // Org admin role\n \"RepositoryRole\", // Repository role (1=read, 2=triage, 3=write, 4=maintain, 5=admin)\n \"Team\", // GitHub team\n \"DeployKey\", // Deploy key\n]);\n\n/** Bypass mode - when the actor can bypass */\nconst bypassModeSchema = z.enum([\n \"always\", // Can always bypass\n \"pull_request\", // Can bypass only via pull request\n]);\n\n/** Single bypass actor configuration */\nconst bypassActorSchema = z\n .object({\n actor_type: bypassActorTypeSchema,\n actor_id: z.number().int().positive().optional(), // Actor ID (required except for DeployKey)\n bypass_mode: bypassModeSchema.optional().default(\"always\"),\n })\n .strict();\n\n/** Ruleset configuration (uses GitHub Rulesets API) */\nconst rulesetConfigSchema = z\n .object({\n name: z.string().optional().default(\"Branch Protection\"), // Ruleset name in GitHub\n branch: z.string().optional().default(\"main\"), // Branch to check (default: main)\n enforcement: z.enum([\"active\", \"evaluate\", \"disabled\"]).optional().default(\"active\"), // Ruleset enforcement\n required_reviews: z.number().int().min(0).optional(), // Minimum required reviews\n dismiss_stale_reviews: z.boolean().optional(), // Dismiss stale reviews on new commits\n require_code_owner_reviews: z.boolean().optional(), // Require CODEOWNER review\n require_status_checks: z.array(z.string()).optional(), // Required status checks\n require_branches_up_to_date: z.boolean().optional(), // Require branch to be up to date\n require_signed_commits: z.boolean().optional(), // Require signed commits\n enforce_admins: z.boolean().optional(), // Enforce rules for admins (no bypass actors when true)\n bypass_actors: z.array(bypassActorSchema).optional(), // Actors that can bypass rules\n })\n .strict()\n .optional();\n\n/** Tag protection ruleset configuration */\nconst tagProtectionConfigSchema = z\n .object({\n patterns: z.array(z.string()).optional(), // Tag patterns to protect (e.g., [\"v*\"])\n prevent_deletion: z.boolean().optional().default(true), // Prevent tag deletion\n prevent_update: z.boolean().optional().default(true), // Prevent tag updates (force-push)\n })\n .strict()\n .optional();\n\n/** Repository settings configuration */\nconst repoConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n require_branch_protection: z.boolean().optional().default(false), // Check branch protection exists\n require_codeowners: z.boolean().optional().default(false), // Check CODEOWNERS file exists\n ruleset: rulesetConfigSchema, // GitHub Ruleset configuration\n tag_protection: tagProtectionConfigSchema, // Tag protection via GitHub rulesets\n })\n .strict()\n .optional();\n\n/** S3 backup verification configuration */\nconst backupsConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n bucket: z.string().optional(), // S3 bucket name\n prefix: z.string().optional(), // S3 key prefix\n max_age_hours: z.number().int().positive().optional().default(24), // Max age of most recent backup\n region: z.string().optional(), // AWS region (defaults to AWS_REGION env)\n })\n .strict()\n .optional();\n\n/** Single CODEOWNERS rule */\nconst codeownersRuleSchema = z\n .object({\n pattern: z.string(), // File pattern (e.g., \"/standards.toml\", \"*.js\", \"/src/api/*\")\n owners: z.array(z.string()), // Owner handles (e.g., [\"@user\", \"@org/team\"])\n })\n .strict();\n\n/** CODEOWNERS validation configuration */\nconst codeownersConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n rules: z.array(codeownersRuleSchema).optional(), // Required rules in CODEOWNERS\n })\n .strict()\n .optional();\n\n/** Doc type configuration - defines required sections and frontmatter per doc type */\nconst docsTypeConfigSchema = z\n .object({\n required_sections: z.array(z.string()).optional(), // e.g., [\"Overview\", \"Parameters\", \"Returns\", \"Examples\"]\n frontmatter: z.array(z.string()).optional(), // e.g., [\"title\", \"tracks\"]\n })\n .strict();\n\n/** Documentation enforcement mode */\nconst docsEnforcementSchema = z.enum([\"block\", \"warn\"]);\n\n/** Documentation governance configuration */\nconst docsConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n path: z.string().optional().default(\"docs/\"), // Documentation directory\n enforcement: docsEnforcementSchema.optional().default(\"warn\"), // \"block\" or \"warn\"\n allowlist: z.array(z.string()).optional(), // Markdown files allowed outside docs/, e.g., [\"README.md\", \"CLAUDE.md\"]\n max_files: z.number().int().positive().optional(), // Max markdown files in docs/\n max_file_lines: z.number().int().positive().optional(), // Max lines per markdown file\n max_total_kb: z.number().int().positive().optional(), // Max total size of docs/\n staleness_days: z.number().int().positive().optional().default(30), // Days before doc is considered stale\n stale_mappings: z.record(z.string(), z.string()).optional(), // Override doc-to-source mappings\n min_coverage: z.number().int().min(0).max(100).optional(), // Minimum API coverage percentage\n coverage_paths: z.array(z.string()).optional(), // Glob patterns for source files, e.g., [\"src/**/*.ts\"]\n exclude_patterns: z.array(z.string()).optional(), // Exclude from coverage, e.g., [\"**/*.test.ts\"]\n types: z.record(z.string(), docsTypeConfigSchema).optional(), // Per-type config, e.g., { api: {...}, guide: {...} }\n })\n .strict()\n .optional();\n\n// =============================================================================\n// MCP Configuration\n// =============================================================================\n\n/** MCP standards source configuration */\nconst mcpStandardsSchema = z\n .object({\n source: z\n .string()\n .optional()\n .describe(\n 'Standards repository source: \"github:owner/repo\", \"github:owner/repo@ref\", or local path'\n ),\n })\n .strict()\n .optional();\n\n/** MCP configuration */\nconst mcpSchema = z\n .object({\n standards: mcpStandardsSchema,\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Infra Domain Configuration\n// =============================================================================\n\n/** Infra domain configuration for AWS resource verification */\nconst infraSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n manifest: z.string().optional().default(\"infra-manifest.json\"), // Path to manifest file\n })\n .strict()\n .optional();\n\n/** Default ignore patterns for forbidden files scan */\nconst DEFAULT_FORBIDDEN_FILES_IGNORE = [\"**/node_modules/**\", \"**/.git/**\"];\n\n/** Forbidden files configuration - files that must NOT exist */\nconst forbiddenFilesConfigSchema = z\n .object({\n enabled: z.boolean().optional().default(false),\n files: z.array(globPatternSchema).optional(), // Glob patterns for files that must not exist (validated)\n ignore: z.array(globPatternSchema).optional(), // Glob patterns to ignore (validated, overrides defaults if provided)\n message: z.string().optional(), // Custom message explaining why these files are forbidden\n })\n .strict()\n .optional();\n\nexport { DEFAULT_FORBIDDEN_FILES_IGNORE };\n\n/** Process domain configuration */\nconst processSchema = z\n .object({\n hooks: hooksConfigSchema,\n ci: ciConfigSchema,\n branches: branchesConfigSchema,\n commits: commitsConfigSchema,\n changesets: changesetsConfigSchema,\n pr: prConfigSchema,\n tickets: ticketsConfigSchema,\n coverage: coverageConfigSchema,\n repo: repoConfigSchema,\n backups: backupsConfigSchema,\n codeowners: codeownersConfigSchema,\n docs: docsConfigSchema,\n forbidden_files: forbiddenFilesConfigSchema,\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Metadata Configuration\n// =============================================================================\n\n/** Repository tier for standards enforcement level */\nconst tierSchema = z.enum([\"production\", \"internal\", \"prototype\"]);\n\n/** Repository status indicating lifecycle phase */\nconst statusSchema = z.enum([\"active\", \"pre-release\", \"deprecated\"]);\n\n/** Metadata configuration for repository tier, project, organisation, and status */\nconst metadataSchema = z\n .object({\n tier: tierSchema,\n project: z.string().optional(),\n organisation: z.string().optional(),\n status: statusSchema.optional().default(\"active\"),\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Extends Configuration\n// =============================================================================\n\n/** Extends configuration for inheriting from registries */\nconst extendsSchema = z\n .object({\n registry: z.string(), // e.g., \"github:myorg/standards\" or local path\n rulesets: z.array(z.string()), // e.g., [\"base\", \"typescript\"]\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Monorepo Configuration\n// =============================================================================\n\n/** Monorepo project detection configuration */\nconst monorepoSchema = z\n .object({\n exclude: z.array(globPatternSchema).optional(), // Glob patterns to exclude from project detection\n })\n .strict()\n .optional();\n\n// =============================================================================\n// Full Configuration\n// =============================================================================\n\n/** Full standards.toml schema */\nexport const configSchema = z\n .object({\n metadata: metadataSchema,\n extends: extendsSchema,\n code: codeSchema,\n process: processSchema,\n infra: infraSchema,\n mcp: mcpSchema,\n monorepo: monorepoSchema,\n })\n .strict();\n\n/** Inferred TypeScript type from schema */\nexport type Config = z.infer<typeof configSchema>;\n\n/** Default configuration */\nexport const defaultConfig: Config = {\n code: {\n linting: {\n eslint: { enabled: false },\n ruff: { enabled: false },\n },\n types: {\n tsc: { enabled: false },\n ty: { enabled: false },\n },\n unused: {\n knip: { enabled: false },\n vulture: { enabled: false },\n },\n coverage_run: {\n enabled: false,\n min_threshold: 80,\n runner: \"auto\",\n },\n security: {\n secrets: { enabled: false, scan_mode: \"branch\", base_branch: \"main\" },\n pnpmaudit: { enabled: false, exclude_dev: true },\n pipaudit: { enabled: false },\n },\n naming: {\n enabled: false,\n },\n quality: {\n \"disable-comments\": { enabled: false },\n },\n },\n monorepo: {},\n process: {\n hooks: {\n enabled: false,\n require_husky: true,\n },\n ci: {\n enabled: false,\n },\n branches: {\n enabled: false,\n require_issue: false,\n },\n commits: {\n enabled: false,\n require_scope: false,\n },\n changesets: {\n enabled: false,\n validate_format: true,\n require_description: true,\n },\n pr: {\n enabled: false,\n require_issue: false,\n },\n tickets: {\n enabled: false,\n require_in_commits: true,\n require_in_branch: false,\n },\n coverage: {\n enabled: false,\n enforce_in: \"config\",\n },\n repo: {\n enabled: false,\n require_branch_protection: false,\n require_codeowners: false,\n },\n backups: {\n enabled: false,\n max_age_hours: 24,\n },\n codeowners: {\n enabled: false,\n },\n docs: {\n enabled: false,\n path: \"docs/\",\n enforcement: \"warn\",\n staleness_days: 30,\n },\n forbidden_files: {\n enabled: false,\n },\n },\n infra: {\n enabled: false,\n manifest: \"infra-manifest.json\",\n },\n mcp: {\n standards: {\n source: undefined,\n },\n },\n};\n"],"mappings":"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","names":["fs","path","mergeLinting","mergeTypes","mergeUnused","mergeSecurity","mergeNaming","mergeQuality","mergeProcessSection"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/infra/manifest.ts","../src/infra/arn.ts","../src/infra/gcp.ts","../src/infra/schemas.ts"],"sourcesContent":["/**\n * Manifest reader for infra scan\n *\n * Supports two formats:\n * 1. JSON: { \"project\": \"...\", \"resources\": [\"arn:...\", \"projects/...\"] }\n * 2. TXT: One resource per line, # for comments\n *\n * Resources can be:\n * - AWS ARNs: arn:aws:s3:::bucket-name\n * - GCP paths: projects/{project}/locations/{location}/services/{service}\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { isValidArn } from \"./arn.js\";\nimport { isValidGcpResource } from \"./gcp.js\";\nimport {\n isValidAccountKey,\n isLegacyManifestSchema,\n isMultiAccountManifestSchema,\n validateLegacyManifest,\n validateMultiAccountManifest,\n type AccountId,\n type LegacyManifest,\n type Manifest,\n type ManifestAccount,\n type MultiAccountManifest,\n} from \"./types.js\";\n\n/**\n * Check if a resource identifier is valid (AWS ARN or GCP path)\n */\nfunction isValidResource(resource: string): boolean {\n return isValidArn(resource) || isValidGcpResource(resource);\n}\n\n/**\n * Error thrown when manifest parsing fails\n */\nexport class ManifestError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ManifestError\";\n }\n}\n\n/**\n * Type guard: check if manifest is multi-account format (v2)\n */\nexport function isMultiAccountManifest(manifest: Manifest): manifest is MultiAccountManifest {\n return \"accounts\" in manifest && typeof manifest.accounts === \"object\";\n}\n\n/**\n * Type guard: check if manifest is legacy format (v1)\n */\nexport function isLegacyManifest(manifest: Manifest): manifest is LegacyManifest {\n return \"resources\" in manifest && Array.isArray(manifest.resources);\n}\n\n/**\n * Parse an account key (e.g., \"aws:111111111111\" or \"gcp:my-project\")\n *\n * @param key - The account key in format \"cloud:id\"\n * @returns Parsed AccountId or null if invalid\n */\nexport function parseAccountKey(key: string): AccountId | null {\n // Use schema validation first\n if (!isValidAccountKey(key)) {\n return null;\n }\n\n // Extract components (we know the format is valid from schema check)\n const colonIndex = key.indexOf(\":\");\n return {\n cloud: key.substring(0, colonIndex) as \"aws\" | \"gcp\",\n id: key.substring(colonIndex + 1),\n };\n}\n\n/**\n * Format an account key from cloud and id\n */\nexport function formatAccountKey(cloud: \"aws\" | \"gcp\", id: string): string {\n return `${cloud}:${id}`;\n}\n\n/**\n * Normalize a legacy manifest to multi-account format\n * This converts v1 manifests to v2 format for unified processing\n */\nexport function normalizeManifest(manifest: Manifest): MultiAccountManifest {\n if (isMultiAccountManifest(manifest)) {\n return manifest;\n }\n\n // Group resources by detected account\n const accounts: Record<string, ManifestAccount> = {};\n\n for (const resource of manifest.resources) {\n const accountKey = detectAccountFromResource(resource);\n if (accountKey in accounts) {\n accounts[accountKey].resources.push(resource);\n } else {\n accounts[accountKey] = { resources: [resource] };\n }\n }\n\n return {\n version: 2,\n project: manifest.project,\n accounts,\n };\n}\n\n/**\n * Detect the account key from a resource identifier\n * Extracts AWS account ID from ARN or GCP project from resource path\n */\nexport function detectAccountFromResource(resource: string): string {\n // Check for AWS ARN: arn:partition:service:region:account:resource\n if (resource.startsWith(\"arn:\")) {\n const parts = resource.split(\":\");\n if (parts.length >= 5) {\n const accountId = parts[4];\n // Some AWS resources (like S3 buckets) don't have account ID in the ARN\n if (accountId) {\n return formatAccountKey(\"aws\", accountId);\n }\n // For S3 buckets without account ID, use a placeholder\n return \"aws:unknown\";\n }\n }\n\n // Check for GCP resource path: projects/{project}/...\n const gcpRegex = /^projects\\/([^/]+)\\//;\n const gcpMatch = gcpRegex.exec(resource);\n if (gcpMatch) {\n return formatAccountKey(\"gcp\", gcpMatch[1]);\n }\n\n return \"unknown:unknown\";\n}\n\n/**\n * Get all resources from a manifest (flattened for v2 manifests)\n */\nexport function getAllResources(manifest: Manifest): string[] {\n if (isMultiAccountManifest(manifest)) {\n return Object.values(manifest.accounts).flatMap((account) => account.resources);\n }\n return manifest.resources;\n}\n\n/**\n * Read and parse a manifest file\n *\n * @param manifestPath - Path to the manifest file\n * @returns Parsed manifest with project name and resource ARNs\n */\nexport function readManifest(manifestPath: string): Manifest {\n if (!fs.existsSync(manifestPath)) {\n throw new ManifestError(`Manifest file not found: ${manifestPath}`);\n }\n\n const content = fs.readFileSync(manifestPath, \"utf-8\");\n const ext = path.extname(manifestPath).toLowerCase();\n\n if (ext === \".json\") {\n return parseJsonManifest(content, manifestPath);\n }\n\n if (ext === \".txt\") {\n return parseTxtManifest(content, manifestPath);\n }\n\n // Try JSON first, then TXT\n try {\n return parseJsonManifest(content, manifestPath);\n } catch {\n return parseTxtManifest(content, manifestPath);\n }\n}\n\n/**\n * Parse a JSON format manifest using Zod schema validation\n */\nfunction parseJsonManifest(content: string, manifestPath: string): Manifest {\n const data = parseJsonContent(content, manifestPath);\n\n // First validate basic structure\n if (!data || typeof data !== \"object\") {\n throw new ManifestError(`Manifest ${manifestPath} must be a JSON object`);\n }\n\n // Try multi-account (v2) format first using Zod schema\n if (isMultiAccountManifestSchema(data)) {\n return validateMultiAccountManifestWithResources(data, manifestPath);\n }\n\n // Try legacy (v1) format using Zod schema\n if (isLegacyManifestSchema(data)) {\n return validateLegacyManifestWithResources(data, manifestPath);\n }\n\n // Fallback to manual validation for better error messages\n return parseFallbackManifest(data as Record<string, unknown>, manifestPath);\n}\n\n/**\n * Fallback parser for manifests that don't match Zod schemas\n */\nfunction parseFallbackManifest(obj: Record<string, unknown>, manifestPath: string): Manifest {\n if (\"accounts\" in obj) {\n return parseMultiAccountManifestFallback(obj, manifestPath);\n }\n\n validateJsonStructure(obj, manifestPath);\n const resources = extractAndValidateResources(obj.resources as unknown[], manifestPath);\n const project = typeof obj.project === \"string\" ? obj.project : undefined;\n\n return { project, resources };\n}\n\n/**\n * Validate multi-account manifest and its resources\n */\nfunction validateMultiAccountManifestWithResources(\n data: unknown,\n manifestPath: string\n): MultiAccountManifest {\n try {\n const manifest = validateMultiAccountManifest(data);\n\n // Validate account keys and resources\n for (const [accountKey, account] of Object.entries(manifest.accounts)) {\n // Validate account key format (must be \"aws:xxx\" or \"gcp:xxx\")\n if (!isValidAccountKey(accountKey)) {\n throw new ManifestError(\n `Manifest ${manifestPath} has invalid account key: \"${accountKey}\". Expected format: \"aws:<account-id>\" or \"gcp:<project-id>\"`\n );\n }\n\n // Validate each resource is a valid ARN or GCP path\n const invalidResources = account.resources.filter((r) => !isValidResource(r));\n if (invalidResources.length > 0) {\n throw new ManifestError(\n `Manifest ${manifestPath} account \"${accountKey}\" contains invalid resources: ${invalidResources.join(\", \")}`\n );\n }\n }\n\n return manifest;\n } catch (error) {\n if (error instanceof ManifestError) {\n throw error;\n }\n // Convert Zod errors to ManifestError\n const message = error instanceof Error ? error.message : \"Unknown error\";\n throw new ManifestError(`Invalid manifest ${manifestPath}: ${message}`);\n }\n}\n\n/**\n * Validate legacy manifest and its resources\n */\nfunction validateLegacyManifestWithResources(\n data: unknown,\n manifestPath: string\n): LegacyManifest {\n try {\n const manifest = validateLegacyManifest(data);\n\n // Additionally validate each resource is a valid ARN or GCP path\n const invalidResources = manifest.resources.filter((r) => !isValidResource(r));\n if (invalidResources.length > 0) {\n throw new ManifestError(\n `Manifest ${manifestPath} contains invalid resources: ${invalidResources.join(\", \")}`\n );\n }\n\n return manifest;\n } catch (error) {\n if (error instanceof ManifestError) {\n throw error;\n }\n // Convert Zod errors to ManifestError\n const message = error instanceof Error ? error.message : \"Unknown error\";\n throw new ManifestError(`Invalid manifest ${manifestPath}: ${message}`);\n }\n}\n\n/**\n * Fallback parser for multi-account manifest with detailed error messages\n */\nfunction parseMultiAccountManifestFallback(\n obj: Record<string, unknown>,\n manifestPath: string\n): MultiAccountManifest {\n const accountsRaw = obj.accounts as Record<string, unknown>;\n const accounts: Record<string, ManifestAccount> = {};\n\n for (const [key, value] of Object.entries(accountsRaw)) {\n accounts[key] = parseAccountEntry(key, value, manifestPath);\n }\n\n const project = typeof obj.project === \"string\" ? obj.project : undefined;\n\n return { version: 2, project, accounts };\n}\n\n/**\n * Validate and parse a single account entry from manifest\n */\nfunction parseAccountEntry(\n key: string,\n value: unknown,\n manifestPath: string\n): ManifestAccount {\n const parsedKey = parseAccountKey(key);\n if (!parsedKey) {\n throw new ManifestError(\n `Manifest ${manifestPath} has invalid account key: \"${key}\". Expected format: \"aws:<account-id>\" or \"gcp:<project-id>\"`\n );\n }\n\n if (!value || typeof value !== \"object\") {\n throw new ManifestError(`Manifest ${manifestPath} account \"${key}\" must be an object`);\n }\n\n const accountObj = value as Record<string, unknown>;\n if (!Array.isArray(accountObj.resources)) {\n throw new ManifestError(`Manifest ${manifestPath} account \"${key}\" must have a \"resources\" array`);\n }\n\n const resources = extractAndValidateResources(accountObj.resources, manifestPath);\n const alias = typeof accountObj.alias === \"string\" ? accountObj.alias : undefined;\n\n return { alias, resources };\n}\n\nfunction parseJsonContent(content: string, manifestPath: string): unknown {\n try {\n return JSON.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n throw new ManifestError(`Invalid JSON in manifest ${manifestPath}: ${message}`);\n }\n}\n\nfunction validateJsonStructure(data: unknown, manifestPath: string): void {\n if (!data || typeof data !== \"object\") {\n throw new ManifestError(`Manifest ${manifestPath} must be a JSON object`);\n }\n\n const obj = data as Record<string, unknown>;\n if (!Array.isArray(obj.resources)) {\n throw new ManifestError(`Manifest ${manifestPath} must have a \"resources\" array`);\n }\n}\n\nfunction extractAndValidateResources(items: unknown[], manifestPath: string): string[] {\n const resources: string[] = [];\n const invalidResources: string[] = [];\n\n for (const item of items) {\n if (typeof item !== \"string\") {\n throw new ManifestError(\n `Manifest ${manifestPath} contains non-string resource: ${JSON.stringify(item)}`\n );\n }\n if (!isValidResource(item)) {\n invalidResources.push(item);\n } else {\n resources.push(item);\n }\n }\n\n if (invalidResources.length > 0) {\n throw new ManifestError(\n `Manifest ${manifestPath} contains invalid resources: ${invalidResources.join(\", \")}`\n );\n }\n\n return resources;\n}\n\n/**\n * Parse a TXT format manifest (one resource per line, # for comments)\n */\nfunction parseTxtManifest(content: string, manifestPath: string): Manifest {\n const lines = content.split(\"\\n\");\n const resources: string[] = [];\n const invalidResources: { line: number; value: string }[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Skip empty lines and comments\n if (!line || line.startsWith(\"#\")) {\n continue;\n }\n\n if (!isValidResource(line)) {\n invalidResources.push({ line: i + 1, value: line });\n } else {\n resources.push(line);\n }\n }\n\n if (invalidResources.length > 0) {\n const details = invalidResources.map((a) => `line ${a.line}: \"${a.value}\"`).join(\", \");\n throw new ManifestError(`Manifest ${manifestPath} contains invalid resources: ${details}`);\n }\n\n return { resources };\n}\n","/**\n * ARN parsing utilities\n *\n * ARN format: arn:partition:service:region:account-id:resource\n * or: arn:partition:service:region:account-id:resource-type/resource-id\n * or: arn:partition:service:region:account-id:resource-type:resource-id\n */\n\nimport type { ParsedArn } from \"./types.js\";\n\ninterface ResourceParts {\n resourceType: string;\n resourceId: string;\n}\n\n/**\n * Validate that a string is a valid ARN format\n */\nexport function isValidArn(arn: string): boolean {\n if (!arn.startsWith(\"arn:\")) {\n return false;\n }\n const parts = arn.split(\":\");\n // ARN must have at least 6 parts: arn:partition:service:region:account:resource\n return parts.length >= 6;\n}\n\n/**\n * Parse an ARN string into its components\n */\nexport function parseArn(arn: string): ParsedArn | null {\n if (!isValidArn(arn)) {\n return null;\n }\n\n const parts = arn.split(\":\");\n const [, partition, service, region, accountId, ...resourceParts] = parts;\n\n // Resource can contain colons, so we need to rejoin\n const resource = resourceParts.join(\":\");\n\n // Parse resource type and ID based on service-specific patterns\n const { resourceType, resourceId } = parseResource(service, resource);\n\n return {\n cloud: \"aws\" as const,\n partition,\n service,\n region,\n accountId,\n resourceType,\n resourceId,\n raw: arn,\n };\n}\n\n// Service-specific parsers\nconst serviceParsers: Record<string, (resource: string) => ResourceParts> = {\n s3: parseS3Resource,\n lambda: parseLambdaResource,\n dynamodb: parseDynamoDBResource,\n sqs: (resource) => ({ resourceType: \"queue\", resourceId: resource }),\n sns: (resource) => ({ resourceType: \"topic\", resourceId: resource }),\n iam: parseIAMResource,\n secretsmanager: parseSecretsManagerResource,\n logs: parseLogsResource,\n};\n\nfunction parseS3Resource(resource: string): ResourceParts {\n if (resource.includes(\"/\")) {\n const [bucket, ...keyParts] = resource.split(\"/\");\n return { resourceType: \"object\", resourceId: `${bucket}/${keyParts.join(\"/\")}` };\n }\n return { resourceType: \"bucket\", resourceId: resource };\n}\n\nfunction parseLambdaResource(resource: string): ResourceParts {\n if (resource.startsWith(\"function:\")) {\n const funcName = resource.slice(\"function:\".length);\n const colonIndex = funcName.indexOf(\":\");\n const resourceId = colonIndex !== -1 ? funcName.slice(0, colonIndex) : funcName;\n return { resourceType: \"function\", resourceId };\n }\n if (resource.startsWith(\"layer:\")) {\n const rest = resource.slice(\"layer:\".length);\n const colonIndex = rest.indexOf(\":\");\n const resourceId = colonIndex !== -1 ? rest.slice(0, colonIndex) : rest;\n return { resourceType: \"layer\", resourceId };\n }\n return { resourceType: \"function\", resourceId: resource };\n}\n\nfunction parseDynamoDBResource(resource: string): ResourceParts {\n if (resource.startsWith(\"table/\")) {\n const rest = resource.slice(\"table/\".length);\n const indexPos = rest.indexOf(\"/index/\");\n const resourceType = indexPos !== -1 ? \"index\" : \"table\";\n return { resourceType, resourceId: rest };\n }\n return { resourceType: \"table\", resourceId: resource };\n}\n\nfunction parseIAMResource(resource: string): ResourceParts {\n const prefixes = [\"role/\", \"user/\", \"policy/\"];\n for (const prefix of prefixes) {\n if (resource.startsWith(prefix)) {\n return {\n resourceType: prefix.slice(0, -1),\n resourceId: resource.slice(prefix.length),\n };\n }\n }\n const colonIndex = resource.indexOf(\":\");\n if (colonIndex !== -1) {\n return {\n resourceType: resource.slice(0, colonIndex),\n resourceId: resource.slice(colonIndex + 1),\n };\n }\n return { resourceType: \"\", resourceId: resource };\n}\n\nfunction parseSecretsManagerResource(resource: string): ResourceParts {\n if (resource.startsWith(\"secret:\")) {\n return { resourceType: \"secret\", resourceId: resource.slice(\"secret:\".length) };\n }\n return { resourceType: \"secret\", resourceId: resource };\n}\n\nfunction parseLogsResource(resource: string): ResourceParts {\n if (resource.startsWith(\"log-group:\")) {\n let logGroupName = resource.slice(\"log-group:\".length);\n if (logGroupName.endsWith(\":*\")) {\n logGroupName = logGroupName.slice(0, -2);\n }\n return { resourceType: \"log-group\", resourceId: logGroupName };\n }\n return { resourceType: \"log-group\", resourceId: resource };\n}\n\nfunction parseGenericResource(resource: string): ResourceParts {\n if (resource.includes(\"/\")) {\n const slashIndex = resource.indexOf(\"/\");\n return {\n resourceType: resource.slice(0, slashIndex),\n resourceId: resource.slice(slashIndex + 1),\n };\n }\n if (resource.includes(\":\")) {\n const colonIndex = resource.indexOf(\":\");\n return {\n resourceType: resource.slice(0, colonIndex),\n resourceId: resource.slice(colonIndex + 1),\n };\n }\n return { resourceType: \"\", resourceId: resource };\n}\n\n/**\n * Parse the resource portion of an ARN into type and ID\n */\nfunction parseResource(service: string, resource: string): ResourceParts {\n const parser = serviceParsers[service] as ((r: string) => ResourceParts) | undefined;\n return parser ? parser(resource) : parseGenericResource(resource);\n}\n","/**\n * GCP resource path parsing utilities\n *\n * GCP resource paths follow patterns like:\n * - projects/{project}/locations/{location}/services/{service} (Cloud Run)\n * - projects/{project}/serviceAccounts/{email} (IAM Service Accounts)\n * - projects/{project}/secrets/{secret} (Secret Manager)\n * - projects/{project}/locations/{location}/repositories/{repo} (Artifact Registry)\n */\n\nimport type { ParsedGcpResource } from \"./types.js\";\n\n/**\n * Validate that a string is a valid GCP resource path\n */\nexport function isValidGcpResource(path: string): boolean {\n return path.startsWith(\"projects/\") && path.split(\"/\").length >= 3;\n}\n\n/**\n * Parse a GCP resource path into its components\n */\nexport function parseGcpResource(path: string): ParsedGcpResource | null {\n if (!isValidGcpResource(path)) {\n return null;\n }\n\n const parts = path.split(\"/\");\n if (parts[0] !== \"projects\" || parts.length < 3) {\n return null;\n }\n\n const project = parts[1];\n const result = parseResourcePath(parts.slice(2), path, project);\n return result;\n}\n\n/**\n * Parse the resource-specific part of the path\n */\nfunction parseResourcePath(\n parts: string[],\n raw: string,\n project: string\n): ParsedGcpResource | null {\n // Service Accounts: projects/{project}/serviceAccounts/{email}\n if (parts[0] === \"serviceAccounts\" && parts.length >= 2) {\n return gcpResource({\n project,\n service: \"iam\",\n location: \"global\",\n resourceType: \"serviceAccounts\",\n resourceId: parts.slice(1).join(\"/\"),\n raw,\n });\n }\n\n // Secrets: projects/{project}/secrets/{secret}\n if (parts[0] === \"secrets\" && parts.length >= 2) {\n return gcpResource({\n project,\n service: \"secretmanager\",\n location: \"global\",\n resourceType: \"secrets\",\n resourceId: parts[1],\n raw,\n });\n }\n\n // Location-based resources\n if (parts[0] === \"locations\" && parts.length >= 4) {\n const location = parts[1];\n const resourceType = parts[2];\n const resourceId = parts.slice(3).join(\"/\");\n\n const service = getServiceFromResourceType(resourceType);\n return gcpResource({\n project,\n service,\n location,\n resourceType,\n resourceId,\n raw,\n });\n }\n\n // Unknown format\n return null;\n}\n\n/**\n * Map resource types to GCP service names\n */\nfunction getServiceFromResourceType(resourceType: string): string {\n const serviceMap: Record<string, string> = {\n services: \"run\",\n repositories: \"artifactregistry\",\n functions: \"cloudfunctions\",\n buckets: \"storage\",\n instances: \"compute\",\n clusters: \"container\",\n };\n return serviceMap[resourceType] ?? resourceType;\n}\n\ninterface GcpResourceParams {\n project: string;\n service: string;\n location: string;\n resourceType: string;\n resourceId: string;\n raw: string;\n}\n\n/**\n * Create a ParsedGcpResource object\n */\nfunction gcpResource(params: GcpResourceParams): ParsedGcpResource {\n return { cloud: \"gcp\", ...params };\n}\n","/**\n * Zod schemas for runtime validation of infra manifests and resources\n *\n * These schemas validate external inputs like manifest files,\n * stack exports, ARNs, and GCP resource paths at runtime.\n */\n\nimport { z } from \"zod\";\n\n// =============================================================================\n// Cloud Provider Types\n// =============================================================================\n\n/**\n * Cloud provider schema\n */\nexport const CloudProviderSchema = z.enum([\"aws\", \"gcp\"]);\nexport type CloudProvider = z.infer<typeof CloudProviderSchema>;\n\n/**\n * Account key schema - format: \"provider:accountId\"\n * Examples: \"aws:123456789012\", \"gcp:my-project-id\"\n */\nexport const AccountKeySchema = z\n .string()\n .regex(\n /^(aws|gcp):.+$/,\n \"Invalid account key format. Expected: provider:accountId (e.g., aws:123456789012, gcp:my-project)\"\n );\nexport type AccountKey = z.infer<typeof AccountKeySchema>;\n\n// =============================================================================\n// AWS Resource Schemas\n// =============================================================================\n\n/**\n * ARN schema - validates AWS ARN format\n *\n * Format: arn:partition:service:region:account-id:resource\n */\nexport const ArnSchema = z\n .string()\n .regex(\n /^arn:(aws|aws-cn|aws-us-gov):[a-z0-9-]+:[a-z0-9-]*:[0-9]*:.+$/,\n \"Invalid ARN format. Expected: arn:partition:service:region:account-id:resource\"\n );\nexport type Arn = z.infer<typeof ArnSchema>;\n\n/**\n * Parsed ARN schema - components extracted from an ARN\n */\nexport const ParsedArnSchema = z.object({\n /** Cloud provider (always \"aws\" for ARNs) */\n cloud: z.literal(\"aws\"),\n\n /** AWS partition (aws, aws-cn, aws-us-gov) */\n partition: z.string(),\n\n /** AWS service (s3, lambda, rds, etc.) */\n service: z.string(),\n\n /** AWS region (empty for global services like S3, IAM) */\n region: z.string(),\n\n /** AWS account ID (empty for S3 buckets) */\n accountId: z.string(),\n\n /** Resource type (e.g., function, table, bucket) */\n resourceType: z.string(),\n\n /** Resource name/identifier */\n resourceId: z.string(),\n\n /** Original ARN string */\n raw: z.string(),\n});\nexport type ParsedArn = z.infer<typeof ParsedArnSchema>;\n\n// =============================================================================\n// GCP Resource Schemas\n// =============================================================================\n\n/**\n * GCP resource path schema - validates GCP resource path format\n *\n * Examples:\n * - projects/my-project/locations/us-central1/functions/my-func\n * - projects/my-project/topics/my-topic\n * - projects/my-project/subscriptions/my-sub\n */\nexport const GcpResourcePathSchema = z\n .string()\n .regex(\n /^projects\\/[^/]+\\/.+$/,\n \"Invalid GCP resource path format. Expected: projects/{project-id}/...\"\n );\nexport type GcpResourcePath = z.infer<typeof GcpResourcePathSchema>;\n\n/**\n * Parsed GCP resource schema - components extracted from a GCP resource path\n */\nexport const ParsedGcpResourceSchema = z.object({\n /** Cloud provider (always \"gcp\" for GCP resources) */\n cloud: z.literal(\"gcp\"),\n\n /** GCP project ID */\n project: z.string(),\n\n /** GCP service (run, iam, secretmanager, artifactregistry, etc.) */\n service: z.string(),\n\n /** Location/region (us-central1, global, etc.) */\n location: z.string(),\n\n /** Resource type (services, serviceAccounts, secrets, repositories, etc.) */\n resourceType: z.string(),\n\n /** Resource name/ID */\n resourceId: z.string(),\n\n /** Original resource path */\n raw: z.string(),\n});\nexport type ParsedGcpResource = z.infer<typeof ParsedGcpResourceSchema>;\n\n/**\n * Generic resource identifier - can be AWS ARN or GCP resource path\n */\nexport const ResourceIdentifierSchema = z.union([ArnSchema, GcpResourcePathSchema]);\nexport type ResourceIdentifier = z.infer<typeof ResourceIdentifierSchema>;\n\n// =============================================================================\n// Account Types\n// =============================================================================\n\n/**\n * Account identifier schema - parsed from account key\n */\nexport const AccountIdSchema = z.object({\n /** Cloud provider */\n cloud: CloudProviderSchema,\n\n /** AWS account ID or GCP project ID */\n id: z.string(),\n});\nexport type AccountId = z.infer<typeof AccountIdSchema>;\n\n/**\n * Account entry in a multi-account manifest\n */\nexport const ManifestAccountSchema = z.object({\n /** Optional human-readable alias for this account */\n alias: z.string().optional(),\n\n /** List of resource identifiers (ARNs or GCP resource paths) */\n resources: z.array(z.string()),\n});\nexport type ManifestAccount = z.infer<typeof ManifestAccountSchema>;\n\n// =============================================================================\n// Manifest Schemas\n// =============================================================================\n\n/**\n * V2 Multi-account manifest schema\n *\n * Resources are grouped by cloud account (AWS account ID or GCP project ID)\n */\nexport const MultiAccountManifestSchema = z.object({\n /** Manifest version - must be 2 for multi-account format */\n version: z.literal(2),\n\n /** Optional project name */\n project: z.string().optional(),\n\n /** Resources grouped by account key (e.g., \"aws:123456789012\", \"gcp:my-project\") */\n accounts: z.record(z.string(), ManifestAccountSchema),\n});\nexport type MultiAccountManifest = z.infer<typeof MultiAccountManifestSchema>;\n\n/**\n * Legacy manifest schema (v1) - flat array of resources\n */\nexport const LegacyManifestSchema = z.object({\n /** Optional manifest version (1 or undefined for legacy) */\n version: z.literal(1).optional(),\n\n /** Optional project name */\n project: z.string().optional(),\n\n /** Flat list of resource identifiers */\n resources: z.array(z.string()),\n});\nexport type LegacyManifest = z.infer<typeof LegacyManifestSchema>;\n\n/**\n * Any manifest schema - accepts either v1 or v2 format\n */\nexport const ManifestSchema = z.union([MultiAccountManifestSchema, LegacyManifestSchema]);\nexport type Manifest = z.infer<typeof ManifestSchema>;\n\n// =============================================================================\n// Scan Result Schemas\n// =============================================================================\n\n/**\n * Result of checking a single resource\n */\nexport const ResourceCheckResultSchema = z.object({\n /** The resource ARN or GCP path */\n arn: z.string(),\n\n /** Whether the resource exists */\n exists: z.boolean(),\n\n /** Error message if check failed */\n error: z.string().optional(),\n\n /** Service name (e.g., s3, lambda, run) */\n service: z.string(),\n\n /** Resource type (e.g., bucket, function) */\n resourceType: z.string(),\n\n /** Resource identifier */\n resourceId: z.string(),\n});\nexport type ResourceCheckResult = z.infer<typeof ResourceCheckResultSchema>;\n\n/**\n * Scan summary statistics\n */\nexport const InfraScanSummarySchema = z.object({\n /** Total resources checked */\n total: z.number().int().nonnegative(),\n\n /** Resources that exist */\n found: z.number().int().nonnegative(),\n\n /** Resources that don't exist */\n missing: z.number().int().nonnegative(),\n\n /** Resources that couldn't be checked (errors) */\n errors: z.number().int().nonnegative(),\n});\nexport type InfraScanSummary = z.infer<typeof InfraScanSummarySchema>;\n\n/**\n * Per-account scan results\n */\nconst AccountScanResultSchema = z.object({\n /** Account alias if provided */\n alias: z.string().optional(),\n\n /** Individual resource check results */\n results: z.array(ResourceCheckResultSchema),\n\n /** Summary statistics for this account */\n summary: InfraScanSummarySchema,\n});\nexport type AccountScanResult = z.infer<typeof AccountScanResultSchema>;\n\n/**\n * Full infrastructure scan result\n */\nexport const InfraScanResultSchema = z.object({\n /** Path to the manifest file */\n manifest: z.string(),\n\n /** Project name */\n project: z.string().optional(),\n\n /** Individual resource check results */\n results: z.array(ResourceCheckResultSchema),\n\n /** Summary statistics */\n summary: InfraScanSummarySchema,\n\n /** Per-account results (only present for multi-account manifests) */\n accountResults: z.record(z.string(), AccountScanResultSchema).optional(),\n});\nexport type InfraScanResult = z.infer<typeof InfraScanResultSchema>;\n\n// =============================================================================\n// Scan Options Schemas\n// =============================================================================\n\n/**\n * Options for programmatic API\n */\nexport interface ScanInfraOptions {\n /** Path to manifest file */\n manifestPath?: string;\n\n /** Path to config file */\n configPath?: string;\n\n /** Filter to specific account (by alias or account key like \"aws:123\") */\n account?: string;\n}\n\n/**\n * Options for CLI handler\n */\nexport type RunInfraScanOptions = ScanInfraOptions & {\n /** Output format */\n format?: \"text\" | \"json\";\n};\n\n// =============================================================================\n// Pulumi Stack Export Schemas\n// =============================================================================\n\n/**\n * Pulumi resource in stack export\n */\nexport const PulumiResourceSchema = z.object({\n urn: z.string().optional(),\n type: z.string().optional(),\n inputs: z.record(z.string(), z.unknown()).optional(),\n outputs: z.record(z.string(), z.unknown()).optional(),\n});\nexport type PulumiResource = z.infer<typeof PulumiResourceSchema>;\n\n/**\n * Pulumi stack export schema (simplified)\n */\nexport const PulumiStackExportSchema = z.object({\n version: z.number().optional(),\n deployment: z\n .object({\n manifest: z\n .object({\n time: z.string().optional(),\n magic: z.string().optional(),\n version: z.string().optional(),\n })\n .optional(),\n resources: z.array(PulumiResourceSchema).optional(),\n })\n .optional(),\n});\nexport type PulumiStackExport = z.infer<typeof PulumiStackExportSchema>;\n\n// =============================================================================\n// Validation Functions\n// =============================================================================\n\n/**\n * Validate an ARN string\n * @throws ZodError if invalid\n */\nexport function validateArn(arn: string): Arn {\n return ArnSchema.parse(arn);\n}\n\n/**\n * Check if a string is a valid ARN format\n */\nexport function isValidArnFormat(arn: string): boolean {\n return ArnSchema.safeParse(arn).success;\n}\n\n/**\n * Validate a GCP resource path\n * @throws ZodError if invalid\n */\nexport function validateGcpResourcePath(path: string): GcpResourcePath {\n return GcpResourcePathSchema.parse(path);\n}\n\n/**\n * Check if a string is a valid GCP resource path\n */\nexport function isValidGcpResourcePath(path: string): boolean {\n return GcpResourcePathSchema.safeParse(path).success;\n}\n\n/**\n * Validate an account key string\n * @throws ZodError if invalid\n */\nexport function validateAccountKey(key: string): AccountKey {\n return AccountKeySchema.parse(key);\n}\n\n/**\n * Check if a string is a valid account key\n */\nexport function isValidAccountKey(key: string): boolean {\n return AccountKeySchema.safeParse(key).success;\n}\n\n/**\n * Validate a legacy (v1) manifest\n * @throws ZodError if invalid\n */\nexport function validateLegacyManifest(data: unknown): LegacyManifest {\n return LegacyManifestSchema.parse(data);\n}\n\n/**\n * Validate a multi-account (v2) manifest\n * @throws ZodError if invalid\n */\nexport function validateMultiAccountManifest(data: unknown): MultiAccountManifest {\n return MultiAccountManifestSchema.parse(data);\n}\n\n/**\n * Validate any manifest format (v1 or v2)\n * @throws ZodError if invalid\n */\nexport function validateManifest(data: unknown): Manifest {\n return ManifestSchema.parse(data);\n}\n\n/**\n * Check if data is a valid multi-account (v2) manifest\n */\nexport function isMultiAccountManifestSchema(data: unknown): data is MultiAccountManifest {\n return MultiAccountManifestSchema.safeParse(data).success;\n}\n\n/**\n * Check if data is a valid legacy (v1) manifest\n */\nexport function isLegacyManifestSchema(data: unknown): data is LegacyManifest {\n return LegacyManifestSchema.safeParse(data).success;\n}\n\n/**\n * Validate a Pulumi stack export\n * @throws ZodError if invalid\n */\nexport function validateStackExport(data: unknown): PulumiStackExport {\n return PulumiStackExportSchema.parse(data);\n}\n\n"],"mappings":"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","names":["path","path"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/standards/fetcher.ts","../src/mcp/standards/parser.ts","../src/mcp/standards/matcher.ts"],"sourcesContent":["/**\n * Fetches the standards repository from GitHub or local filesystem\n */\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { CACHE, STANDARDS_REPO, TIMEOUTS } from \"../../constants.js\";\n\nconst CACHE_DIR = path.join(os.tmpdir(), CACHE.standardsCacheDir);\n\n/** Parsed GitHub source */\ninterface GitHubSource {\n type: \"github\";\n owner: string;\n repo: string;\n ref?: string;\n}\n\n/** Parsed local source */\ninterface LocalSource {\n type: \"local\";\n path: string;\n}\n\n/** Parsed source type */\ntype ParsedSource = GitHubSource | LocalSource;\n\n/** Parse github:owner/repo[@ref] format */\nfunction parseGitHubSource(source: string): GitHubSource {\n const remainder = source.slice(7); // Remove \"github:\"\n const atIndex = remainder.indexOf(\"@\");\n const ownerRepo = atIndex !== -1 ? remainder.slice(0, atIndex) : remainder;\n const ref = atIndex !== -1 ? remainder.slice(atIndex + 1) : undefined;\n const slashIndex = ownerRepo.indexOf(\"/\");\n\n if (slashIndex === -1) {\n throw new StandardsError(`Invalid GitHub source format: ${source}. Expected github:owner/repo`);\n }\n\n const owner = ownerRepo.slice(0, slashIndex);\n const repo = ownerRepo.slice(slashIndex + 1);\n\n if (!owner || !repo) {\n throw new StandardsError(`Invalid GitHub source format: ${source}. Expected github:owner/repo`);\n }\n\n return { type: \"github\", owner, repo, ref };\n}\n\n/**\n * Parse a source string into owner/repo/ref or local path.\n * Formats:\n * - \"github:owner/repo\" - GitHub repository\n * - \"github:owner/repo@ref\" - GitHub with branch/tag\n * - Local filesystem path (absolute or relative)\n */\nfunction parseSource(source: string): ParsedSource {\n if (source.startsWith(\"github:\")) {\n return parseGitHubSource(source);\n }\n return { type: \"local\", path: source };\n}\n\n/** Error class for standards fetching failures */\nexport class StandardsError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"StandardsError\";\n }\n}\n\n/** Authentication method for GitHub */\ntype AuthMethod = \"token\" | \"ssh\" | \"none\";\n\n/**\n * Detect authentication method based on environment variables.\n * Priority: CM_REGISTRY_TOKEN > GITHUB_TOKEN > SSH key detection > none\n */\nfunction detectAuthMethod(): AuthMethod {\n if (process.env.CM_REGISTRY_TOKEN || process.env.GITHUB_TOKEN) {\n return \"token\";\n }\n if (process.env.SSH_AUTH_SOCK) {\n return \"ssh\";\n }\n return \"none\";\n}\n\n/**\n * Get the authentication token from environment variables.\n */\nfunction getAuthToken(): string | undefined {\n return process.env.CM_REGISTRY_TOKEN ?? process.env.GITHUB_TOKEN;\n}\n\n/**\n * Build the git URL for a repository based on auth method.\n */\nfunction buildGitHubUrl(auth: AuthMethod, owner: string, repo: string): string {\n switch (auth) {\n case \"ssh\":\n return `git@github.com:${owner}/${repo}.git`;\n case \"token\": {\n const token = getAuthToken();\n if (token) {\n return `https://x-access-token:${token}@github.com/${owner}/${repo}.git`;\n }\n return `https://github.com/${owner}/${repo}.git`;\n }\n case \"none\":\n default:\n return `https://github.com/${owner}/${repo}.git`;\n }\n}\n\n/**\n * Update an existing cloned repository.\n */\nasync function updateExistingRepo(repoDir: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"pull\", \"--ff-only\"], { cwd: repoDir, timeout: TIMEOUTS.git });\n return true;\n } catch {\n // If update fails, remove the directory so it will be re-cloned\n fs.rmSync(repoDir, { recursive: true, force: true });\n return false;\n }\n}\n\n/**\n * Clone a repository from GitHub.\n */\nasync function cloneRepo(repoDir: string, owner: string, repo: string, ref?: string): Promise<void> {\n fs.mkdirSync(CACHE_DIR, { recursive: true });\n\n const auth = detectAuthMethod();\n const url = buildGitHubUrl(auth, owner, repo);\n\n try {\n const args = [\"clone\", \"--depth\", \"1\"];\n if (ref) {\n args.push(\"--branch\", ref);\n }\n args.push(url, repoDir);\n\n await execa(\"git\", args, {\n timeout: TIMEOUTS.git,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes(\"timed out\")) {\n throw new StandardsError(`Standards repo clone timed out after ${TIMEOUTS.git / 1000} seconds`);\n }\n throw new StandardsError(`Failed to clone standards repo: ${message}`);\n }\n}\n\n/**\n * Fetch a GitHub repository, caching it locally.\n * Returns the path to the cached repository.\n */\nasync function fetchGitHubRepo(owner: string, repo: string, ref?: string): Promise<string> {\n const cacheKey = ref ? `${owner}-${repo}-${ref}` : `${owner}-${repo}`;\n const repoDir = path.join(CACHE_DIR, cacheKey);\n\n // If repo exists, try to update it\n if (fs.existsSync(repoDir)) {\n await updateExistingRepo(repoDir);\n }\n\n // Clone if it doesn't exist (either first time or after failed update)\n if (!fs.existsSync(repoDir)) {\n await cloneRepo(repoDir, owner, repo, ref);\n }\n\n return repoDir;\n}\n\n/**\n * Resolve a local source path to an absolute path.\n */\nfunction resolveLocalPath(localPath: string, basePath?: string): string {\n if (path.isAbsolute(localPath)) {\n return localPath;\n }\n const base = basePath ?? process.cwd();\n return path.resolve(base, localPath);\n}\n\n/**\n * Fetch the standards repository from a source string.\n * Supports:\n * - \"github:owner/repo\" - GitHub repository\n * - \"github:owner/repo@ref\" - GitHub with branch/tag\n * - Local filesystem path (absolute or relative)\n *\n * @param source - Source string to fetch from\n * @param basePath - Base path for resolving relative local paths (defaults to cwd)\n * @returns Path to the standards repository\n */\nexport async function fetchStandardsRepoFromSource(\n source: string,\n basePath?: string\n): Promise<string> {\n const parsed = parseSource(source);\n\n if (parsed.type === \"local\") {\n const resolvedPath = resolveLocalPath(parsed.path, basePath);\n if (!fs.existsSync(resolvedPath)) {\n throw new StandardsError(`Local standards path does not exist: ${resolvedPath}`);\n }\n return resolvedPath;\n }\n\n return fetchGitHubRepo(parsed.owner, parsed.repo, parsed.ref);\n}\n\n/**\n * Fetch the default standards repository, caching it locally.\n * Returns the path to the cached repository.\n */\nexport async function fetchStandardsRepo(): Promise<string> {\n return fetchGitHubRepo(STANDARDS_REPO.owner, STANDARDS_REPO.repo);\n}\n\n/**\n * Get the path to the guidelines directory.\n */\nexport function getGuidelinesDir(repoPath: string): string {\n return path.join(repoPath, \"guidelines\");\n}\n\n/**\n * Get the path to the rulesets directory.\n */\nexport function getRulesetsDir(repoPath: string): string {\n return path.join(repoPath, \"rulesets\");\n}\n","/**\n * Parser for guideline markdown files with YAML frontmatter\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport matter from \"gray-matter\";\nimport { z } from \"zod\";\n\nimport { type Guideline, type GuidelineListItem, type Ruleset } from \"./types.js\";\nimport { StandardsError } from \"./fetcher.js\";\n\n/** Zod schema for validating guideline frontmatter */\nexport const frontmatterSchema = z.object({\n id: z.string(),\n title: z.string(),\n category: z.string(),\n priority: z.number(),\n tags: z.array(z.string()),\n});\n\n/**\n * Parse a guideline markdown file content into a Guideline object.\n */\nexport function parseGuideline(fileContent: string, filename: string): Guideline {\n const { data, content } = matter(fileContent);\n\n const result = frontmatterSchema.safeParse(data);\n if (!result.success) {\n const errors = result.error.issues.map((e) => `${e.path.join(\".\")}: ${e.message}`).join(\", \");\n throw new StandardsError(`Invalid frontmatter in ${filename}: ${errors}`);\n }\n\n return {\n ...result.data,\n content: content.trim(),\n };\n}\n\n/**\n * Load all guidelines from a directory.\n */\nexport function loadAllGuidelines(guidelinesDir: string): Guideline[] {\n if (!fs.existsSync(guidelinesDir)) {\n throw new StandardsError(`Guidelines directory not found: ${guidelinesDir}`);\n }\n\n const files = fs.readdirSync(guidelinesDir).filter((f) => f.endsWith(\".md\"));\n const guidelines: Guideline[] = [];\n\n for (const file of files) {\n const filePath = path.join(guidelinesDir, file);\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n try {\n guidelines.push(parseGuideline(content, file));\n } catch (error) {\n // Skip files that fail to parse, log warning\n console.warn(`Warning: Failed to parse guideline ${file}: ${error}`);\n }\n }\n\n return guidelines;\n}\n\n/**\n * Load a single guideline by ID.\n */\nexport function loadGuideline(guidelinesDir: string, id: string): Guideline | null {\n const filePath = path.join(guidelinesDir, `${id}.md`);\n\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n return parseGuideline(content, `${id}.md`);\n}\n\n/**\n * Convert guidelines to list items (summary format).\n */\nexport function toListItems(guidelines: Guideline[]): GuidelineListItem[] {\n return guidelines.map((g) => ({\n id: g.id,\n title: g.title,\n tags: g.tags,\n category: g.category,\n }));\n}\n\n/**\n * Load a ruleset file by ID.\n */\nexport function loadRuleset(rulesetsDir: string, id: string): Ruleset | null {\n const filePath = path.join(rulesetsDir, `${id}.toml`);\n\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n return { id, content };\n}\n\n/**\n * List all available ruleset IDs.\n */\nexport function listRulesets(rulesetsDir: string): string[] {\n if (!fs.existsSync(rulesetsDir)) {\n return [];\n }\n\n return fs\n .readdirSync(rulesetsDir)\n .filter((f) => f.endsWith(\".toml\"))\n .map((f) => f.replace(\".toml\", \"\"));\n}\n","/**\n * Smart keyword matching logic for guidelines\n */\nimport { type Guideline, type MatchedGuideline } from \"./types.js\";\n\n/**\n * Parse a context string into keywords.\n * Extracts words, lowercases them, and removes duplicates.\n */\nexport function parseContext(context: string): string[] {\n const words = context\n .toLowerCase()\n .split(/[\\s,.\\-_/]+/)\n .filter((word) => word.length > 1);\n\n return [...new Set(words)];\n}\n\n/**\n * Score a guideline based on how many keywords match its tags.\n */\nexport function scoreGuideline(guideline: Guideline, keywords: string[]): number {\n const tags = new Set(guideline.tags.map((t) => t.toLowerCase()));\n let score = 0;\n\n for (const keyword of keywords) {\n if (tags.has(keyword)) {\n score++;\n }\n }\n\n // Also check if keyword appears in category or id\n const category = guideline.category.toLowerCase();\n const id = guideline.id.toLowerCase();\n\n for (const keyword of keywords) {\n if (category.includes(keyword) || id.includes(keyword)) {\n score += 0.5; // Partial match bonus\n }\n }\n\n return score;\n}\n\n/**\n * Match guidelines against a context string.\n * Returns guidelines sorted by score (descending) then priority (ascending).\n */\nexport function matchGuidelines(\n guidelines: Guideline[],\n context: string,\n limit?: number\n): MatchedGuideline[] {\n const keywords = parseContext(context);\n\n if (keywords.length === 0) {\n return [];\n }\n\n const scored = guidelines\n .map((guideline) => ({\n guideline,\n score: scoreGuideline(guideline, keywords),\n }))\n .filter((m) => m.score > 0);\n\n // Sort by score descending, then by priority ascending\n scored.sort((a, b) => {\n if (b.score !== a.score) {\n return b.score - a.score;\n }\n return a.guideline.priority - b.guideline.priority;\n });\n\n return limit ? scored.slice(0, limit) : scored;\n}\n\n/**\n * Compose matched guidelines into a single markdown document.\n */\nexport function composeGuidelines(matches: MatchedGuideline[]): string {\n if (matches.length === 0) {\n return \"No matching guidelines found for the given context.\";\n }\n\n const sections = matches.map((m) => {\n const { guideline } = m;\n return `# ${guideline.title}\\n\\n**Category:** ${guideline.category} | **Priority:** ${guideline.priority}\\n**Tags:** ${guideline.tags.join(\", \")}\\n\\n${guideline.content}`;\n });\n\n return sections.join(\"\\n\\n---\\n\\n\");\n}\n"],"mappings":"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","names":["fs","path"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/infra/index.ts","../src/infra/output.ts","../src/infra/checkers/index.ts","../src/infra/checkers/gcp/index.ts","../src/infra/scan.ts"],"sourcesContent":["/**\n * Infra scan module - Public API\n *\n * Provides functionality to verify AWS resources declared in a manifest actually exist.\n */\n\nimport * as path from \"node:path\";\n\nimport chalk from \"chalk\";\n\nimport { getProjectRoot, loadConfigAsync } from \"../core/index.js\";\nimport { ExitCode } from \"../core/index.js\";\n\nimport { ManifestError, readManifest } from \"./manifest.js\";\nimport { formatScan } from \"./output.js\";\nimport { scanManifest } from \"./scan.js\";\nimport type { InfraScanResult, RunInfraScanOptions, ScanInfraOptions } from \"./types.js\";\n\n// Re-export types\nexport type {\n AccountId,\n AccountScanResult,\n Arn,\n CloudProvider,\n GcpResourcePath,\n InfraScanResult,\n InfraScanSummary,\n LegacyManifest,\n Manifest,\n ManifestAccount,\n MultiAccountManifest,\n ParsedArn,\n ParsedGcpResource,\n PulumiResource,\n PulumiStackExport,\n ResourceCheckResult,\n ResourceIdentifier,\n ScanInfraOptions,\n} from \"./types.js\";\n\n// Re-export Zod schemas and validation functions for public API\nexport {\n // Schemas - for external consumers to validate manifests\n ArnSchema,\n AccountIdSchema,\n AccountKeySchema,\n CloudProviderSchema,\n GcpResourcePathSchema,\n InfraScanResultSchema,\n InfraScanSummarySchema,\n LegacyManifestSchema,\n ManifestAccountSchema,\n ManifestSchema,\n MultiAccountManifestSchema,\n ParsedArnSchema,\n ParsedGcpResourceSchema,\n PulumiResourceSchema,\n PulumiStackExportSchema,\n ResourceCheckResultSchema,\n ResourceIdentifierSchema,\n // Validation functions\n isValidArnFormat,\n isValidGcpResourcePath,\n isValidAccountKey,\n isMultiAccountManifestSchema,\n isLegacyManifestSchema,\n validateArn,\n validateGcpResourcePath,\n validateAccountKey,\n validateManifest,\n validateMultiAccountManifest,\n validateLegacyManifest,\n validateStackExport,\n} from \"./types.js\";\nexport {\n ManifestError,\n isMultiAccountManifest,\n isLegacyManifest,\n parseAccountKey,\n formatAccountKey,\n normalizeManifest,\n detectAccountFromResource,\n getAllResources,\n} from \"./manifest.js\";\nexport { parseArn, isValidArn } from \"./arn.js\";\nexport { parseGcpResource, isValidGcpResource } from \"./gcp.js\";\nexport { SUPPORTED_SERVICES, isSupportedService } from \"./checkers/index.js\";\nexport { SUPPORTED_GCP_SERVICES, isSupportedGcpService } from \"./checkers/gcp/index.js\";\n\n// Re-export generate functionality\nexport {\n DEFAULT_MANIFEST_NAME,\n generateManifestFromStdin,\n generateManifestFromFile,\n generateMultiAccountFromStdin,\n generateMultiAccountFromFile,\n generateWithMerge,\n mergeIntoManifest,\n parseStackExport,\n parseStackExportMultiAccount,\n readExistingManifest,\n writeManifest,\n type GenerateManifestOptions,\n} from \"./generate.js\";\n\n/**\n * Scan infrastructure resources declared in a manifest.\n *\n * This is the programmatic API for @standards-kit/drift integration.\n *\n * @param options - Options for the scan\n * @returns Scan result with all resource check results and summary\n *\n * @example\n * ```typescript\n * import { scanInfra } from \"@standards-kit/conform\";\n *\n * const result = await scanInfra({ manifestPath: \"./infra-manifest.json\" });\n * console.log(result.summary);\n * // { total: 5, found: 4, missing: 1, errors: 0 }\n * ```\n */\nexport async function scanInfra(options: ScanInfraOptions = {}): Promise<InfraScanResult> {\n const resolvedManifestPath = await resolveManifestPath(options);\n const manifest = readManifest(resolvedManifestPath);\n return scanManifest(manifest, resolvedManifestPath, { account: options.account });\n}\n\nasync function resolveManifestPath(options: ScanInfraOptions): Promise<string> {\n const { manifestPath, configPath } = options;\n\n if (manifestPath) {\n return path.isAbsolute(manifestPath)\n ? manifestPath\n : path.resolve(process.cwd(), manifestPath);\n }\n\n const { config, configPath: loadedConfigPath } = await loadConfigAsync(configPath);\n const projectRoot = getProjectRoot(loadedConfigPath);\n\n const infraConfig = config.infra;\n if (!infraConfig?.enabled) {\n throw new ManifestError(\"Infra scanning is not enabled in standards.toml\");\n }\n\n const manifestName = infraConfig.manifest;\n return path.resolve(projectRoot, manifestName);\n}\n\n/**\n * Run infra scan from CLI\n */\nexport async function runInfraScan(options: RunInfraScanOptions = {}): Promise<void> {\n const { format = \"text\", manifestPath, configPath, account } = options;\n\n try {\n const result = await scanInfra({ manifestPath, configPath, account });\n outputResult(result, format);\n } catch (error) {\n handleError(error, format);\n }\n}\n\nfunction outputResult(result: InfraScanResult, format: \"text\" | \"json\"): never {\n process.stdout.write(`${formatScan(result, format)}\\n`);\n\n if (result.summary.errors > 0) {\n process.exit(ExitCode.RUNTIME_ERROR);\n } else if (result.summary.missing > 0) {\n process.exit(ExitCode.VIOLATIONS_FOUND);\n } else {\n process.exit(ExitCode.SUCCESS);\n }\n}\n\nfunction handleError(error: unknown, format: \"text\" | \"json\"): never {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n const isConfigError = error instanceof ManifestError;\n\n if (format === \"json\") {\n process.stdout.write(`${JSON.stringify({ error: message }, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`Error: ${message}`));\n }\n\n process.exit(isConfigError ? ExitCode.CONFIG_ERROR : ExitCode.RUNTIME_ERROR);\n}\n\n/**\n * Options for CLI generate command\n */\nexport interface RunInfraGenerateOptions {\n /** Input file path (if not provided, reads from stdin) */\n input?: string;\n /** Output file path (defaults to infra-manifest.json) */\n output?: string;\n /** Project name override */\n project?: string;\n /** Output to stdout instead of file */\n stdout?: boolean;\n /** Account alias (e.g., \"prod-aws\") for multi-account manifests */\n account?: string;\n /** Explicit account ID (e.g., \"aws:111111111111\") */\n accountId?: string;\n /** Merge into existing manifest instead of overwriting */\n merge?: boolean;\n}\n\n/**\n * Run infra generate from CLI\n */\nexport async function runInfraGenerate(options: RunInfraGenerateOptions = {}): Promise<void> {\n const {\n generateWithMerge,\n writeManifest,\n DEFAULT_MANIFEST_NAME,\n } = await import(\"./generate.js\");\n const { getAllResources, isMultiAccountManifest } = await import(\"./manifest.js\");\n\n try {\n const manifest = await generateWithMerge(options.input, {\n project: options.project,\n output: options.output,\n account: options.account,\n accountId: options.accountId,\n merge: options.merge,\n });\n\n writeManifest(manifest, { output: options.output, stdout: options.stdout });\n\n if (!options.stdout) {\n const outputPath = options.output ?? DEFAULT_MANIFEST_NAME;\n const resourceCount = getAllResources(manifest).length;\n const accountCount = isMultiAccountManifest(manifest)\n ? Object.keys(manifest.accounts).length\n : 1;\n const accountLabel = accountCount === 1 ? \"account\" : \"accounts\";\n\n console.error(\n chalk.green(`✓ Generated ${outputPath} with ${resourceCount} resources across ${accountCount} ${accountLabel}`)\n );\n }\n\n process.exit(ExitCode.SUCCESS);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.error(chalk.red(`Error: ${message}`));\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n}\n","/**\n * Output formatters for infra scan results\n */\n\nimport chalk from \"chalk\";\n\nimport type { AccountScanResult, InfraScanResult, ResourceCheckResult } from \"./types.js\";\n\n/**\n * Format scan result as text output\n */\nfunction formatScanText(result: InfraScanResult): string {\n const lines: string[] = [];\n\n formatHeader(lines, result);\n\n // If we have account results, format by account\n if (result.accountResults && Object.keys(result.accountResults).length > 0) {\n formatAccountResults(lines, result.accountResults);\n formatOverallSummary(lines, result.summary);\n } else {\n // Legacy format - flat results\n formatResultsByStatus(lines, result.results);\n formatSummary(lines, result.summary);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction formatHeader(lines: string[], result: InfraScanResult): void {\n lines.push(chalk.bold(\"Infrastructure Scan Results\"));\n lines.push(`Manifest: ${result.manifest}`);\n if (result.project) {\n lines.push(`Project: ${result.project}`);\n }\n lines.push(\"\");\n}\n\nfunction formatResultsByStatus(lines: string[], results: ResourceCheckResult[]): void {\n const found = results.filter((r) => r.exists && !r.error);\n const missing = results.filter((r) => !r.exists && !r.error);\n const errors = results.filter((r) => r.error);\n\n formatResultSection(lines, found, {\n colorFn: chalk.green.bold,\n label: \"Found\",\n formatLine: formatFoundLine,\n });\n formatResultSection(lines, missing, {\n colorFn: chalk.red.bold,\n label: \"Missing\",\n formatLine: formatMissingLine,\n });\n formatResultSection(lines, errors, {\n colorFn: chalk.yellow.bold,\n label: \"Errors\",\n formatLine: formatErrorLine,\n });\n}\n\ninterface SectionConfig {\n colorFn: (s: string) => string;\n label: string;\n formatLine: (r: ResourceCheckResult) => string;\n}\n\nfunction formatResultSection(\n lines: string[],\n results: ResourceCheckResult[],\n config: SectionConfig\n): void {\n if (results.length === 0) {\n return;\n }\n lines.push(config.colorFn(`${config.label} (${results.length}):`));\n for (const r of results) {\n lines.push(config.formatLine(r));\n }\n lines.push(\"\");\n}\n\nfunction formatFoundLine(r: ResourceCheckResult): string {\n const icon = chalk.green(\"✓\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n return ` ${icon} ${resourceInfo}`;\n}\n\nfunction formatMissingLine(r: ResourceCheckResult): string {\n const icon = chalk.red(\"✗\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n return ` ${icon} ${resourceInfo}`;\n}\n\nfunction formatErrorLine(r: ResourceCheckResult): string {\n const icon = chalk.yellow(\"!\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n const errorText = r.error ?? \"Unknown error\";\n return ` ${icon} ${resourceInfo} - ${chalk.yellow(errorText)}`;\n}\n\nfunction formatSummary(\n lines: string[],\n summary: { total: number; found: number; missing: number; errors: number }\n): void {\n lines.push(chalk.bold(\"Summary:\"));\n lines.push(` Total: ${summary.total}`);\n lines.push(chalk.green(` Found: ${summary.found}`));\n lines.push(chalk.red(` Missing: ${summary.missing}`));\n if (summary.errors > 0) {\n lines.push(chalk.yellow(` Errors: ${summary.errors}`));\n }\n}\n\n/**\n * Format overall summary for multi-account manifests\n */\nfunction formatOverallSummary(\n lines: string[],\n summary: { total: number; found: number; missing: number; errors: number }\n): void {\n lines.push(chalk.bold(\"Overall Summary:\"));\n lines.push(` Total: ${summary.total}`);\n lines.push(chalk.green(` Found: ${summary.found}`));\n lines.push(chalk.red(` Missing: ${summary.missing}`));\n if (summary.errors > 0) {\n lines.push(chalk.yellow(` Errors: ${summary.errors}`));\n }\n}\n\n/**\n * Format results grouped by account\n */\nfunction formatAccountResults(\n lines: string[],\n accountResults: Record<string, AccountScanResult>\n): void {\n for (const [accountKey, account] of Object.entries(accountResults)) {\n const accountLabel = account.alias\n ? `${account.alias} (${accountKey})`\n : accountKey;\n\n lines.push(chalk.bold.cyan(`\\nAccount: ${accountLabel}`));\n lines.push(chalk.gray(\"─\".repeat(40)));\n\n // Format results for this account\n formatAccountResourceResults(lines, account.results);\n\n // Account-level summary\n const { summary } = account;\n const summaryParts: string[] = [];\n if (summary.found > 0) {\n summaryParts.push(chalk.green(`${summary.found} found`));\n }\n if (summary.missing > 0) {\n summaryParts.push(chalk.red(`${summary.missing} missing`));\n }\n if (summary.errors > 0) {\n summaryParts.push(chalk.yellow(`${summary.errors} errors`));\n }\n lines.push(` ${chalk.dim(\"Summary:\")} ${summaryParts.join(\", \")}`);\n }\n lines.push(\"\");\n}\n\n/**\n * Format resource results for a single account (inline style)\n */\nfunction formatAccountResourceResults(lines: string[], results: ResourceCheckResult[]): void {\n for (const r of results) {\n if (r.error) {\n const icon = chalk.yellow(\"!\");\n lines.push(` ${icon} ${r.arn} - ${chalk.yellow(r.error)}`);\n } else if (r.exists) {\n const icon = chalk.green(\"✓\");\n lines.push(` ${icon} ${r.arn}`);\n } else {\n const icon = chalk.red(\"✗\");\n lines.push(` ${icon} ${r.arn}`);\n }\n }\n}\n\n/**\n * Format scan result as JSON output\n */\nfunction formatScanJson(result: InfraScanResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Format scan result based on output format\n */\nexport function formatScan(result: InfraScanResult, format: \"text\" | \"json\"): string {\n return format === \"json\" ? formatScanJson(result) : formatScanText(result);\n}\n","/**\n * Checker registry with lazy loading\n *\n * Checkers are loaded on-demand to avoid loading all AWS SDK clients upfront.\n */\n\nimport type { ResourceChecker } from \"./types.js\";\n\n/**\n * Supported AWS services for resource checking\n */\nexport const SUPPORTED_SERVICES = [\n \"s3\",\n \"lambda\",\n \"dynamodb\",\n \"sqs\",\n \"sns\",\n \"iam\",\n \"secretsmanager\",\n \"logs\",\n \"ecs\",\n \"rds\",\n \"ec2\",\n \"elasticache\",\n \"elasticloadbalancing\",\n] as const;\n\nexport type SupportedService = (typeof SUPPORTED_SERVICES)[number];\n\n/**\n * Check if a service is supported\n */\nexport function isSupportedService(service: string): service is SupportedService {\n return SUPPORTED_SERVICES.includes(service as SupportedService);\n}\n\n/**\n * Factory functions for checkers (lazy-loaded)\n */\nconst checkerFactories: Record<SupportedService, () => Promise<ResourceChecker>> = {\n s3: async () => (await import(\"./s3.js\")).S3Checker,\n lambda: async () => (await import(\"./lambda.js\")).LambdaChecker,\n dynamodb: async () => (await import(\"./dynamodb.js\")).DynamoDBChecker,\n sqs: async () => (await import(\"./sqs.js\")).SQSChecker,\n sns: async () => (await import(\"./sns.js\")).SNSChecker,\n iam: async () => (await import(\"./iam.js\")).IAMChecker,\n secretsmanager: async () => (await import(\"./secretsmanager.js\")).SecretsManagerChecker,\n logs: async () => (await import(\"./cloudwatch.js\")).CloudWatchLogsChecker,\n ecs: async () => (await import(\"./ecs.js\")).ECSChecker,\n rds: async () => (await import(\"./rds.js\")).RDSChecker,\n ec2: async () => (await import(\"./ec2.js\")).EC2Checker,\n elasticache: async () => (await import(\"./elasticache.js\")).ElastiCacheChecker,\n elasticloadbalancing: async () => (await import(\"./elb.js\")).ELBChecker,\n};\n\n/**\n * Cache of loaded checkers\n */\nconst checkerCache = new Map<SupportedService, ResourceChecker>();\n\n/**\n * Get a checker for a service, loading it if necessary\n *\n * @param service - The AWS service name\n * @returns The checker instance, or undefined if the service is not supported\n */\nexport async function getChecker(service: string): Promise<ResourceChecker | undefined> {\n if (!isSupportedService(service)) {\n return undefined;\n }\n\n // Return cached checker if available\n const cached = checkerCache.get(service);\n if (cached) {\n return cached;\n }\n\n // Load and cache the checker\n const factory = checkerFactories[service];\n const checker = await factory();\n checkerCache.set(service, checker);\n\n return checker;\n}\n\n/**\n * Clear the checker cache (useful for testing)\n */\nexport function clearCheckerCache(): void {\n checkerCache.clear();\n}\n","/**\n * GCP checker registry with lazy loading\n */\n\nimport type { GcpResourceChecker } from \"../types.js\";\n\n/**\n * Supported GCP services for resource checking\n */\nexport const SUPPORTED_GCP_SERVICES = [\"run\", \"secretmanager\", \"artifactregistry\", \"iam\"] as const;\n\nexport type SupportedGcpService = (typeof SUPPORTED_GCP_SERVICES)[number];\n\n/**\n * Check if a GCP service is supported\n */\nexport function isSupportedGcpService(service: string): service is SupportedGcpService {\n return SUPPORTED_GCP_SERVICES.includes(service as SupportedGcpService);\n}\n\n/**\n * Factory functions for GCP checkers (lazy-loaded)\n */\nconst checkerFactories: Record<SupportedGcpService, () => Promise<GcpResourceChecker>> = {\n run: async () => (await import(\"./cloudrun.js\")).CloudRunChecker,\n secretmanager: async () => (await import(\"./secretmanager.js\")).SecretManagerChecker,\n artifactregistry: async () => (await import(\"./artifactregistry.js\")).ArtifactRegistryChecker,\n iam: async () => (await import(\"./iam.js\")).ServiceAccountChecker,\n};\n\n/**\n * Cache of loaded GCP checkers\n */\nconst checkerCache = new Map<SupportedGcpService, GcpResourceChecker>();\n\n/**\n * Get a GCP checker for a service, loading it if necessary\n */\nexport async function getGcpChecker(service: string): Promise<GcpResourceChecker | undefined> {\n if (!isSupportedGcpService(service)) {\n return undefined;\n }\n\n const cached = checkerCache.get(service);\n if (cached) {\n return cached;\n }\n\n const factory = checkerFactories[service];\n const checker = await factory();\n checkerCache.set(service, checker);\n\n return checker;\n}\n","/**\n * Scan logic for infra scan\n *\n * Orchestrates checking all resources in a manifest (AWS and GCP)\n */\n\nimport { CONCURRENCY } from \"../constants.js\";\nimport { isValidArn, parseArn } from \"./arn.js\";\nimport { getChecker, isSupportedService, SUPPORTED_SERVICES } from \"./checkers/index.js\";\nimport {\n getGcpChecker,\n isSupportedGcpService,\n SUPPORTED_GCP_SERVICES,\n} from \"./checkers/gcp/index.js\";\nimport { isValidGcpResource, parseGcpResource } from \"./gcp.js\";\nimport { getAllResources, isMultiAccountManifest } from \"./manifest.js\";\nimport type {\n AccountScanResult,\n InfraScanResult,\n InfraScanSummary,\n Manifest,\n MultiAccountManifest,\n ResourceCheckResult,\n} from \"./types.js\";\n\n/**\n * Options for scanning\n */\ninterface ScanOptions {\n /** Max number of parallel checks */\n concurrency?: number;\n /** Filter to specific account (by alias or account key) */\n account?: string;\n}\n\n/**\n * Scan all resources in a manifest\n *\n * @param manifest - The manifest containing resources to check\n * @param manifestPath - Path to the manifest file (for result metadata)\n * @param options - Scan options\n * @returns Scan result with all resource check results and summary\n */\nexport async function scanManifest(\n manifest: Manifest,\n manifestPath: string,\n options: ScanOptions = {}\n): Promise<InfraScanResult> {\n const concurrency = options.concurrency ?? CONCURRENCY.infraScan;\n\n // For multi-account manifests, scan by account\n if (isMultiAccountManifest(manifest)) {\n return scanMultiAccountManifest(manifest, manifestPath, options);\n }\n\n // Legacy manifest - simple flat scan\n const resources = getAllResources(manifest);\n const results = await checkResourcesWithConcurrency(resources, concurrency);\n const summary = calculateSummary(results);\n\n return {\n manifest: manifestPath,\n project: manifest.project,\n results,\n summary,\n };\n}\n\n/**\n * Scan a multi-account manifest\n */\nasync function scanMultiAccountManifest(\n manifest: MultiAccountManifest,\n manifestPath: string,\n options: ScanOptions = {}\n): Promise<InfraScanResult> {\n const concurrency = options.concurrency ?? CONCURRENCY.infraScan;\n const accountResults: Record<string, AccountScanResult> = {};\n const allResults: ResourceCheckResult[] = [];\n\n // Get accounts to scan (filter by account if specified)\n const accountsToScan = filterAccounts(manifest, options.account);\n\n for (const [accountKey, account] of Object.entries(accountsToScan)) {\n const results = await checkResourcesWithConcurrency(account.resources, concurrency);\n const summary = calculateSummary(results);\n\n accountResults[accountKey] = {\n alias: account.alias,\n results,\n summary,\n };\n\n allResults.push(...results);\n }\n\n // Calculate overall summary\n const overallSummary = calculateSummary(allResults);\n\n return {\n manifest: manifestPath,\n project: manifest.project,\n results: allResults,\n summary: overallSummary,\n accountResults,\n };\n}\n\n/**\n * Filter accounts based on account filter\n * Returns matching accounts or all accounts if no filter\n */\nfunction filterAccounts(\n manifest: MultiAccountManifest,\n accountFilter?: string\n): Record<string, { alias?: string; resources: string[] }> {\n if (!accountFilter) {\n return manifest.accounts;\n }\n\n // Check if filter is an account key (e.g., \"aws:123456\")\n if (accountFilter in manifest.accounts) {\n return { [accountFilter]: manifest.accounts[accountFilter] };\n }\n\n // Check if filter matches an alias\n for (const [key, account] of Object.entries(manifest.accounts)) {\n if (account.alias === accountFilter) {\n return { [key]: account };\n }\n }\n\n // No match found - return empty\n return {};\n}\n\n/**\n * Check resources with controlled concurrency using a simple batching approach\n */\nasync function checkResourcesWithConcurrency(\n arns: string[],\n concurrency: number\n): Promise<ResourceCheckResult[]> {\n const results: ResourceCheckResult[] = [];\n\n // Process in batches\n for (let i = 0; i < arns.length; i += concurrency) {\n const batch = arns.slice(i, i + concurrency);\n const batchResults = await Promise.all(batch.map((arn) => checkResource(arn)));\n results.push(...batchResults);\n }\n\n // Sort results to maintain consistent order (by ARN)\n results.sort((a, b) => a.arn.localeCompare(b.arn));\n\n return results;\n}\n\n/**\n * Check a single resource (AWS or GCP)\n */\nasync function checkResource(resource: string): Promise<ResourceCheckResult> {\n // Detect cloud provider and route to appropriate checker\n if (isValidArn(resource)) {\n return checkAwsResource(resource);\n }\n if (isValidGcpResource(resource)) {\n return checkGcpResource(resource);\n }\n\n return {\n arn: resource,\n exists: false,\n error: \"Invalid resource format (not a valid AWS ARN or GCP resource path)\",\n service: \"unknown\",\n resourceType: \"unknown\",\n resourceId: resource,\n };\n}\n\n/**\n * Check an AWS resource\n */\nasync function checkAwsResource(arn: string): Promise<ResourceCheckResult> {\n const parsed = parseArn(arn);\n if (!parsed) {\n return errorResult({ arn, error: \"Invalid ARN format\" });\n }\n\n if (!isSupportedService(parsed.service)) {\n const msg = `Unsupported AWS service: ${parsed.service}. Supported: ${SUPPORTED_SERVICES.join(\", \")}`;\n return errorResult({\n arn,\n error: msg,\n service: parsed.service,\n resourceType: parsed.resourceType,\n resourceId: parsed.resourceId,\n });\n }\n\n const checker = await getChecker(parsed.service);\n if (!checker) {\n return errorResult({ arn, error: `No checker for AWS service: ${parsed.service}`, service: parsed.service });\n }\n\n return checker.check(parsed);\n}\n\n/**\n * Check a GCP resource\n */\nasync function checkGcpResource(resource: string): Promise<ResourceCheckResult> {\n const parsed = parseGcpResource(resource);\n if (!parsed) {\n return errorResult({ arn: resource, error: \"Invalid GCP resource path format\" });\n }\n\n if (!isSupportedGcpService(parsed.service)) {\n const msg = `Unsupported GCP service: ${parsed.service}. Supported: ${SUPPORTED_GCP_SERVICES.join(\", \")}`;\n return errorResult({\n arn: resource,\n error: msg,\n service: parsed.service,\n resourceType: parsed.resourceType,\n resourceId: parsed.resourceId,\n });\n }\n\n const checker = await getGcpChecker(parsed.service);\n if (!checker) {\n return errorResult({ arn: resource, error: `No checker for GCP service: ${parsed.service}`, service: parsed.service });\n }\n\n return checker.check(parsed);\n}\n\ninterface ErrorResultParams {\n arn: string;\n error: string;\n service?: string;\n resourceType?: string;\n resourceId?: string;\n}\n\n/**\n * Create an error result\n */\nfunction errorResult(params: ErrorResultParams): ResourceCheckResult {\n const { arn, error, service = \"unknown\", resourceType = \"unknown\", resourceId = arn } = params;\n return { arn, exists: false, error, service, resourceType, resourceId };\n}\n\n/**\n * Calculate summary statistics from check results\n */\nfunction calculateSummary(results: ResourceCheckResult[]): InfraScanSummary {\n let found = 0;\n let missing = 0;\n let errors = 0;\n\n for (const result of results) {\n if (result.error) {\n errors++;\n } else if (result.exists) {\n found++;\n } else {\n missing++;\n }\n }\n\n return {\n total: results.length,\n found,\n missing,\n errors,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,YAAY,UAAU;AAEtB,OAAOA,YAAW;;;ACJlB,OAAO,WAAW;AAOlB,SAAS,eAAe,QAAiC;AACvD,QAAM,QAAkB,CAAC;AAEzB,eAAa,OAAO,MAAM;AAG1B,MAAI,OAAO,kBAAkB,OAAO,KAAK,OAAO,cAAc,EAAE,SAAS,GAAG;AAC1E,yBAAqB,OAAO,OAAO,cAAc;AACjD,yBAAqB,OAAO,OAAO,OAAO;AAAA,EAC5C,OAAO;AAEL,0BAAsB,OAAO,OAAO,OAAO;AAC3C,kBAAc,OAAO,OAAO,OAAO;AAAA,EACrC;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,aAAa,OAAiB,QAA+B;AACpE,QAAM,KAAK,MAAM,KAAK,6BAA6B,CAAC;AACpD,QAAM,KAAK,aAAa,OAAO,QAAQ,EAAE;AACzC,MAAI,OAAO,SAAS;AAClB,UAAM,KAAK,YAAY,OAAO,OAAO,EAAE;AAAA,EACzC;AACA,QAAM,KAAK,EAAE;AACf;AAEA,SAAS,sBAAsB,OAAiB,SAAsC;AACpF,QAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,KAAK;AACxD,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,EAAE,KAAK;AAC3D,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,KAAK;AAE5C,sBAAoB,OAAO,OAAO;AAAA,IAChC,SAAS,MAAM,MAAM;AAAA,IACrB,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AACD,sBAAoB,OAAO,SAAS;AAAA,IAClC,SAAS,MAAM,IAAI;AAAA,IACnB,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AACD,sBAAoB,OAAO,QAAQ;AAAA,IACjC,SAAS,MAAM,OAAO;AAAA,IACtB,OAAO;AAAA,IACP,YAAY;AAAA,EACd,CAAC;AACH;AAQA,SAAS,oBACP,OACA,SACA,QACM;AACN,MAAI,QAAQ,WAAW,GAAG;AACxB;AAAA,EACF;AACA,QAAM,KAAK,OAAO,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,MAAM,IAAI,CAAC;AACjE,aAAW,KAAK,SAAS;AACvB,UAAM,KAAK,OAAO,WAAW,CAAC,CAAC;AAAA,EACjC;AACA,QAAM,KAAK,EAAE;AACf;AAEA,SAAS,gBAAgB,GAAgC;AACvD,QAAM,OAAO,MAAM,MAAM,QAAG;AAC5B,QAAM,eAAe,GAAG,EAAE,OAAO,IAAI,EAAE,YAAY,IAAI,EAAE,UAAU;AACnE,SAAO,KAAK,IAAI,IAAI,YAAY;AAClC;AAEA,SAAS,kBAAkB,GAAgC;AACzD,QAAM,OAAO,MAAM,IAAI,QAAG;AAC1B,QAAM,eAAe,GAAG,EAAE,OAAO,IAAI,EAAE,YAAY,IAAI,EAAE,UAAU;AACnE,SAAO,KAAK,IAAI,IAAI,YAAY;AAClC;AAEA,SAAS,gBAAgB,GAAgC;AACvD,QAAM,OAAO,MAAM,OAAO,GAAG;AAC7B,QAAM,eAAe,GAAG,EAAE,OAAO,IAAI,EAAE,YAAY,IAAI,EAAE,UAAU;AACnE,QAAM,YAAY,EAAE,SAAS;AAC7B,SAAO,KAAK,IAAI,IAAI,YAAY,MAAM,MAAM,OAAO,SAAS,CAAC;AAC/D;AAEA,SAAS,cACP,OACA,SACM;AACN,QAAM,KAAK,MAAM,KAAK,UAAU,CAAC;AACjC,QAAM,KAAK,cAAc,QAAQ,KAAK,EAAE;AACxC,QAAM,KAAK,MAAM,MAAM,cAAc,QAAQ,KAAK,EAAE,CAAC;AACrD,QAAM,KAAK,MAAM,IAAI,cAAc,QAAQ,OAAO,EAAE,CAAC;AACrD,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,MAAM,OAAO,cAAc,QAAQ,MAAM,EAAE,CAAC;AAAA,EACzD;AACF;AAKA,SAAS,qBACP,OACA,SACM;AACN,QAAM,KAAK,MAAM,KAAK,kBAAkB,CAAC;AACzC,QAAM,KAAK,cAAc,QAAQ,KAAK,EAAE;AACxC,QAAM,KAAK,MAAM,MAAM,cAAc,QAAQ,KAAK,EAAE,CAAC;AACrD,QAAM,KAAK,MAAM,IAAI,cAAc,QAAQ,OAAO,EAAE,CAAC;AACrD,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,MAAM,OAAO,cAAc,QAAQ,MAAM,EAAE,CAAC;AAAA,EACzD;AACF;AAKA,SAAS,qBACP,OACA,gBACM;AACN,aAAW,CAAC,YAAY,OAAO,KAAK,OAAO,QAAQ,cAAc,GAAG;AAClE,UAAM,eAAe,QAAQ,QACzB,GAAG,QAAQ,KAAK,KAAK,UAAU,MAC/B;AAEJ,UAAM,KAAK,MAAM,KAAK,KAAK;AAAA,WAAc,YAAY,EAAE,CAAC;AACxD,UAAM,KAAK,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AAGrC,iCAA6B,OAAO,QAAQ,OAAO;AAGnD,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,eAAyB,CAAC;AAChC,QAAI,QAAQ,QAAQ,GAAG;AACrB,mBAAa,KAAK,MAAM,MAAM,GAAG,QAAQ,KAAK,QAAQ,CAAC;AAAA,IACzD;AACA,QAAI,QAAQ,UAAU,GAAG;AACvB,mBAAa,KAAK,MAAM,IAAI,GAAG,QAAQ,OAAO,UAAU,CAAC;AAAA,IAC3D;AACA,QAAI,QAAQ,SAAS,GAAG;AACtB,mBAAa,KAAK,MAAM,OAAO,GAAG,QAAQ,MAAM,SAAS,CAAC;AAAA,IAC5D;AACA,UAAM,KAAK,KAAK,MAAM,IAAI,UAAU,CAAC,IAAI,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,EACpE;AACA,QAAM,KAAK,EAAE;AACf;AAKA,SAAS,6BAA6B,OAAiB,SAAsC;AAC3F,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,OAAO;AACX,YAAM,OAAO,MAAM,OAAO,GAAG;AAC7B,YAAM,KAAK,KAAK,IAAI,IAAI,EAAE,GAAG,MAAM,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE;AAAA,IAC5D,WAAW,EAAE,QAAQ;AACnB,YAAM,OAAO,MAAM,MAAM,QAAG;AAC5B,YAAM,KAAK,KAAK,IAAI,IAAI,EAAE,GAAG,EAAE;AAAA,IACjC,OAAO;AACL,YAAM,OAAO,MAAM,IAAI,QAAG;AAC1B,YAAM,KAAK,KAAK,IAAI,IAAI,EAAE,GAAG,EAAE;AAAA,IACjC;AAAA,EACF;AACF;AAKA,SAAS,eAAe,QAAiC;AACvD,SAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AACvC;AAKO,SAAS,WAAW,QAAyB,QAAiC;AACnF,SAAO,WAAW,SAAS,eAAe,MAAM,IAAI,eAAe,MAAM;AAC3E;;;ACvLO,IAAM,qBAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOO,SAAS,mBAAmB,SAA8C;AAC/E,SAAO,mBAAmB,SAAS,OAA2B;AAChE;AAKA,IAAM,mBAA6E;AAAA,EACjF,IAAI,aAAa,MAAM,OAAO,kBAAS,GAAG;AAAA,EAC1C,QAAQ,aAAa,MAAM,OAAO,sBAAa,GAAG;AAAA,EAClD,UAAU,aAAa,MAAM,OAAO,wBAAe,GAAG;AAAA,EACtD,KAAK,aAAa,MAAM,OAAO,mBAAU,GAAG;AAAA,EAC5C,KAAK,aAAa,MAAM,OAAO,mBAAU,GAAG;AAAA,EAC5C,KAAK,aAAa,MAAM,OAAO,mBAAU,GAAG;AAAA,EAC5C,gBAAgB,aAAa,MAAM,OAAO,8BAAqB,GAAG;AAAA,EAClE,MAAM,aAAa,MAAM,OAAO,0BAAiB,GAAG;AAAA,EACpD,KAAK,aAAa,MAAM,OAAO,mBAAU,GAAG;AAAA,EAC5C,KAAK,aAAa,MAAM,OAAO,mBAAU,GAAG;AAAA,EAC5C,KAAK,aAAa,MAAM,OAAO,mBAAU,GAAG;AAAA,EAC5C,aAAa,aAAa,MAAM,OAAO,2BAAkB,GAAG;AAAA,EAC5D,sBAAsB,aAAa,MAAM,OAAO,mBAAU,GAAG;AAC/D;AAKA,IAAM,eAAe,oBAAI,IAAuC;AAQhE,eAAsB,WAAW,SAAuD;AACtF,MAAI,CAAC,mBAAmB,OAAO,GAAG;AAChC,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,aAAa,IAAI,OAAO;AACvC,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,iBAAiB,OAAO;AACxC,QAAM,UAAU,MAAM,QAAQ;AAC9B,eAAa,IAAI,SAAS,OAAO;AAEjC,SAAO;AACT;;;AC1EO,IAAM,yBAAyB,CAAC,OAAO,iBAAiB,oBAAoB,KAAK;AAOjF,SAAS,sBAAsB,SAAiD;AACrF,SAAO,uBAAuB,SAAS,OAA8B;AACvE;AAKA,IAAMC,oBAAmF;AAAA,EACvF,KAAK,aAAa,MAAM,OAAO,wBAAe,GAAG;AAAA,EACjD,eAAe,aAAa,MAAM,OAAO,6BAAoB,GAAG;AAAA,EAChE,kBAAkB,aAAa,MAAM,OAAO,gCAAuB,GAAG;AAAA,EACtE,KAAK,aAAa,MAAM,OAAO,mBAAU,GAAG;AAC9C;AAKA,IAAMC,gBAAe,oBAAI,IAA6C;AAKtE,eAAsB,cAAc,SAA0D;AAC5F,MAAI,CAAC,sBAAsB,OAAO,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,SAASA,cAAa,IAAI,OAAO;AACvC,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAEA,QAAM,UAAUD,kBAAiB,OAAO;AACxC,QAAM,UAAU,MAAM,QAAQ;AAC9B,EAAAC,cAAa,IAAI,SAAS,OAAO;AAEjC,SAAO;AACT;;;ACVA,eAAsB,aACpB,UACA,cACA,UAAuB,CAAC,GACE;AAC1B,QAAM,cAAc,QAAQ,eAAe,YAAY;AAGvD,MAAI,uBAAuB,QAAQ,GAAG;AACpC,WAAO,yBAAyB,UAAU,cAAc,OAAO;AAAA,EACjE;AAGA,QAAM,YAAY,gBAAgB,QAAQ;AAC1C,QAAM,UAAU,MAAM,8BAA8B,WAAW,WAAW;AAC1E,QAAM,UAAU,iBAAiB,OAAO;AAExC,SAAO;AAAA,IACL,UAAU;AAAA,IACV,SAAS,SAAS;AAAA,IAClB;AAAA,IACA;AAAA,EACF;AACF;AAKA,eAAe,yBACb,UACA,cACA,UAAuB,CAAC,GACE;AAC1B,QAAM,cAAc,QAAQ,eAAe,YAAY;AACvD,QAAM,iBAAoD,CAAC;AAC3D,QAAM,aAAoC,CAAC;AAG3C,QAAM,iBAAiB,eAAe,UAAU,QAAQ,OAAO;AAE/D,aAAW,CAAC,YAAY,OAAO,KAAK,OAAO,QAAQ,cAAc,GAAG;AAClE,UAAM,UAAU,MAAM,8BAA8B,QAAQ,WAAW,WAAW;AAClF,UAAM,UAAU,iBAAiB,OAAO;AAExC,mBAAe,UAAU,IAAI;AAAA,MAC3B,OAAO,QAAQ;AAAA,MACf;AAAA,MACA;AAAA,IACF;AAEA,eAAW,KAAK,GAAG,OAAO;AAAA,EAC5B;AAGA,QAAM,iBAAiB,iBAAiB,UAAU;AAElD,SAAO;AAAA,IACL,UAAU;AAAA,IACV,SAAS,SAAS;AAAA,IAClB,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA,EACF;AACF;AAMA,SAAS,eACP,UACA,eACyD;AACzD,MAAI,CAAC,eAAe;AAClB,WAAO,SAAS;AAAA,EAClB;AAGA,MAAI,iBAAiB,SAAS,UAAU;AACtC,WAAO,EAAE,CAAC,aAAa,GAAG,SAAS,SAAS,aAAa,EAAE;AAAA,EAC7D;AAGA,aAAW,CAAC,KAAK,OAAO,KAAK,OAAO,QAAQ,SAAS,QAAQ,GAAG;AAC9D,QAAI,QAAQ,UAAU,eAAe;AACnC,aAAO,EAAE,CAAC,GAAG,GAAG,QAAQ;AAAA,IAC1B;AAAA,EACF;AAGA,SAAO,CAAC;AACV;AAKA,eAAe,8BACb,MACA,aACgC;AAChC,QAAM,UAAiC,CAAC;AAGxC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,aAAa;AACjD,UAAM,QAAQ,KAAK,MAAM,GAAG,IAAI,WAAW;AAC3C,UAAM,eAAe,MAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,QAAQ,cAAc,GAAG,CAAC,CAAC;AAC7E,YAAQ,KAAK,GAAG,YAAY;AAAA,EAC9B;AAGA,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,cAAc,EAAE,GAAG,CAAC;AAEjD,SAAO;AACT;AAKA,eAAe,cAAc,UAAgD;AAE3E,MAAI,WAAW,QAAQ,GAAG;AACxB,WAAO,iBAAiB,QAAQ;AAAA,EAClC;AACA,MAAI,mBAAmB,QAAQ,GAAG;AAChC,WAAO,iBAAiB,QAAQ;AAAA,EAClC;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,cAAc;AAAA,IACd,YAAY;AAAA,EACd;AACF;AAKA,eAAe,iBAAiB,KAA2C;AACzE,QAAM,SAAS,SAAS,GAAG;AAC3B,MAAI,CAAC,QAAQ;AACX,WAAO,YAAY,EAAE,KAAK,OAAO,qBAAqB,CAAC;AAAA,EACzD;AAEA,MAAI,CAAC,mBAAmB,OAAO,OAAO,GAAG;AACvC,UAAM,MAAM,4BAA4B,OAAO,OAAO,gBAAgB,mBAAmB,KAAK,IAAI,CAAC;AACnG,WAAO,YAAY;AAAA,MACjB;AAAA,MACA,OAAO;AAAA,MACP,SAAS,OAAO;AAAA,MAChB,cAAc,OAAO;AAAA,MACrB,YAAY,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,MAAM,WAAW,OAAO,OAAO;AAC/C,MAAI,CAAC,SAAS;AACZ,WAAO,YAAY,EAAE,KAAK,OAAO,+BAA+B,OAAO,OAAO,IAAI,SAAS,OAAO,QAAQ,CAAC;AAAA,EAC7G;AAEA,SAAO,QAAQ,MAAM,MAAM;AAC7B;AAKA,eAAe,iBAAiB,UAAgD;AAC9E,QAAM,SAAS,iBAAiB,QAAQ;AACxC,MAAI,CAAC,QAAQ;AACX,WAAO,YAAY,EAAE,KAAK,UAAU,OAAO,mCAAmC,CAAC;AAAA,EACjF;AAEA,MAAI,CAAC,sBAAsB,OAAO,OAAO,GAAG;AAC1C,UAAM,MAAM,4BAA4B,OAAO,OAAO,gBAAgB,uBAAuB,KAAK,IAAI,CAAC;AACvG,WAAO,YAAY;AAAA,MACjB,KAAK;AAAA,MACL,OAAO;AAAA,MACP,SAAS,OAAO;AAAA,MAChB,cAAc,OAAO;AAAA,MACrB,YAAY,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,MAAM,cAAc,OAAO,OAAO;AAClD,MAAI,CAAC,SAAS;AACZ,WAAO,YAAY,EAAE,KAAK,UAAU,OAAO,+BAA+B,OAAO,OAAO,IAAI,SAAS,OAAO,QAAQ,CAAC;AAAA,EACvH;AAEA,SAAO,QAAQ,MAAM,MAAM;AAC7B;AAaA,SAAS,YAAY,QAAgD;AACnE,QAAM,EAAE,KAAK,OAAO,UAAU,WAAW,eAAe,WAAW,aAAa,IAAI,IAAI;AACxF,SAAO,EAAE,KAAK,QAAQ,OAAO,OAAO,SAAS,cAAc,WAAW;AACxE;AAKA,SAAS,iBAAiB,SAAkD;AAC1E,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,MAAI,SAAS;AAEb,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,OAAO;AAChB;AAAA,IACF,WAAW,OAAO,QAAQ;AACxB;AAAA,IACF,OAAO;AACL;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AJ1JA,eAAsB,UAAU,UAA4B,CAAC,GAA6B;AACxF,QAAM,uBAAuB,MAAM,oBAAoB,OAAO;AAC9D,QAAM,WAAW,aAAa,oBAAoB;AAClD,SAAO,aAAa,UAAU,sBAAsB,EAAE,SAAS,QAAQ,QAAQ,CAAC;AAClF;AAEA,eAAe,oBAAoB,SAA4C;AAC7E,QAAM,EAAE,cAAc,WAAW,IAAI;AAErC,MAAI,cAAc;AAChB,WAAY,gBAAW,YAAY,IAC/B,eACK,aAAQ,QAAQ,IAAI,GAAG,YAAY;AAAA,EAC9C;AAEA,QAAM,EAAE,QAAQ,YAAY,iBAAiB,IAAI,MAAM,gBAAgB,UAAU;AACjF,QAAM,cAAc,eAAe,gBAAgB;AAEnD,QAAM,cAAc,OAAO;AAC3B,MAAI,CAAC,aAAa,SAAS;AACzB,UAAM,IAAI,cAAc,iDAAiD;AAAA,EAC3E;AAEA,QAAM,eAAe,YAAY;AACjC,SAAY,aAAQ,aAAa,YAAY;AAC/C;AAKA,eAAsB,aAAa,UAA+B,CAAC,GAAkB;AACnF,QAAM,EAAE,SAAS,QAAQ,cAAc,YAAY,QAAQ,IAAI;AAE/D,MAAI;AACF,UAAM,SAAS,MAAM,UAAU,EAAE,cAAc,YAAY,QAAQ,CAAC;AACpE,iBAAa,QAAQ,MAAM;AAAA,EAC7B,SAAS,OAAO;AACd,gBAAY,OAAO,MAAM;AAAA,EAC3B;AACF;AAEA,SAAS,aAAa,QAAyB,QAAgC;AAC7E,UAAQ,OAAO,MAAM,GAAG,WAAW,QAAQ,MAAM,CAAC;AAAA,CAAI;AAEtD,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,YAAQ,KAAK,SAAS,aAAa;AAAA,EACrC,WAAW,OAAO,QAAQ,UAAU,GAAG;AACrC,YAAQ,KAAK,SAAS,gBAAgB;AAAA,EACxC,OAAO;AACL,YAAQ,KAAK,SAAS,OAAO;AAAA,EAC/B;AACF;AAEA,SAAS,YAAY,OAAgB,QAAgC;AACnE,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,QAAM,gBAAgB,iBAAiB;AAEvC,MAAI,WAAW,QAAQ;AACrB,YAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAE,OAAO,QAAQ,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EACzE,OAAO;AACL,YAAQ,MAAMC,OAAM,IAAI,UAAU,OAAO,EAAE,CAAC;AAAA,EAC9C;AAEA,UAAQ,KAAK,gBAAgB,SAAS,eAAe,SAAS,aAAa;AAC7E;AAyBA,eAAsB,iBAAiB,UAAmC,CAAC,GAAkB;AAC3F,QAAM;AAAA,IACJ,mBAAAC;AAAA,IACA,eAAAC;AAAA,IACA,uBAAAC;AAAA,EACF,IAAI,MAAM,OAAO,wBAAe;AAChC,QAAM,EAAE,iBAAAC,kBAAiB,wBAAAC,wBAAuB,IAAI,MAAM,OAAO,wBAAe;AAEhF,MAAI;AACF,UAAM,WAAW,MAAMJ,mBAAkB,QAAQ,OAAO;AAAA,MACtD,SAAS,QAAQ;AAAA,MACjB,QAAQ,QAAQ;AAAA,MAChB,SAAS,QAAQ;AAAA,MACjB,WAAW,QAAQ;AAAA,MACnB,OAAO,QAAQ;AAAA,IACjB,CAAC;AAED,IAAAC,eAAc,UAAU,EAAE,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,CAAC;AAE1E,QAAI,CAAC,QAAQ,QAAQ;AACnB,YAAM,aAAa,QAAQ,UAAUC;AACrC,YAAM,gBAAgBC,iBAAgB,QAAQ,EAAE;AAChD,YAAM,eAAeC,wBAAuB,QAAQ,IAChD,OAAO,KAAK,SAAS,QAAQ,EAAE,SAC/B;AACJ,YAAM,eAAe,iBAAiB,IAAI,YAAY;AAEtD,cAAQ;AAAA,QACNL,OAAM,MAAM,oBAAe,UAAU,SAAS,aAAa,qBAAqB,YAAY,IAAI,YAAY,EAAE;AAAA,MAChH;AAAA,IACF;AAEA,YAAQ,KAAK,SAAS,OAAO;AAAA,EAC/B,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAQ,MAAMA,OAAM,IAAI,UAAU,OAAO,EAAE,CAAC;AAC5C,YAAQ,KAAK,SAAS,aAAa;AAAA,EACrC;AACF;","names":["chalk","checkerFactories","checkerCache","chalk","generateWithMerge","writeManifest","DEFAULT_MANIFEST_NAME","getAllResources","isMultiAccountManifest"]}
|