@standards-kit/conform 0.3.1 → 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 +8 -9
- 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-DYQG6JEQ.js → mcp-6PRCC6P6.js} +5 -5
- 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/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/{mcp-DYQG6JEQ.js.map → mcp-6PRCC6P6.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
|
@@ -20,7 +20,3 @@ export declare function isSupportedService(service: string): service is Supporte
|
|
|
20
20
|
* @returns The checker instance, or undefined if the service is not supported
|
|
21
21
|
*/
|
|
22
22
|
export declare function getChecker(service: string): Promise<ResourceChecker | undefined>;
|
|
23
|
-
/**
|
|
24
|
-
* Clear the checker cache (useful for testing)
|
|
25
|
-
*/
|
|
26
|
-
export declare function clearCheckerCache(): void;
|
package/dist/infra/schemas.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type CloudProvider = z.infer<typeof CloudProviderSchema>;
|
|
|
18
18
|
* Examples: "aws:123456789012", "gcp:my-project-id"
|
|
19
19
|
*/
|
|
20
20
|
export declare const AccountKeySchema: z.ZodString;
|
|
21
|
-
|
|
21
|
+
type AccountKey = z.infer<typeof AccountKeySchema>;
|
|
22
22
|
/**
|
|
23
23
|
* ARN schema - validates AWS ARN format
|
|
24
24
|
*
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
parseStackExportMultiAccount,
|
|
11
11
|
readExistingManifest,
|
|
12
12
|
writeManifest
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XZERDHOH.js";
|
|
14
14
|
import {
|
|
15
15
|
AccountIdSchema,
|
|
16
16
|
AccountKeySchema,
|
|
@@ -54,17 +54,17 @@ import {
|
|
|
54
54
|
validateManifest,
|
|
55
55
|
validateMultiAccountManifest,
|
|
56
56
|
validateStackExport
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-T2PWT2B5.js";
|
|
58
58
|
import {
|
|
59
59
|
ExitCode
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-G5AS4QBP.js";
|
|
61
61
|
import {
|
|
62
62
|
getProjectRoot,
|
|
63
63
|
loadConfigAsync
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-UU6OT5O3.js";
|
|
65
65
|
import {
|
|
66
66
|
CONCURRENCY
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-HMNRMNEA.js";
|
|
68
68
|
|
|
69
69
|
// src/infra/index.ts
|
|
70
70
|
import * as path from "path";
|
|
@@ -219,12 +219,12 @@ function isSupportedService(service) {
|
|
|
219
219
|
return SUPPORTED_SERVICES.includes(service);
|
|
220
220
|
}
|
|
221
221
|
var checkerFactories = {
|
|
222
|
-
s3: async () => (await import("./s3-
|
|
222
|
+
s3: async () => (await import("./s3-6YMTP5VV.js")).S3Checker,
|
|
223
223
|
lambda: async () => (await import("./lambda-YTJOCYV5.js")).LambdaChecker,
|
|
224
224
|
dynamodb: async () => (await import("./dynamodb-HQH3IMAI.js")).DynamoDBChecker,
|
|
225
225
|
sqs: async () => (await import("./sqs-MHBW6UFC.js")).SQSChecker,
|
|
226
226
|
sns: async () => (await import("./sns-RV64OMK2.js")).SNSChecker,
|
|
227
|
-
iam: async () => (await import("./iam-
|
|
227
|
+
iam: async () => (await import("./iam-ZV3RA3JZ.js")).IAMChecker,
|
|
228
228
|
secretsmanager: async () => (await import("./secretsmanager-FJKTPIXI.js")).SecretsManagerChecker,
|
|
229
229
|
logs: async () => (await import("./cloudwatch-3LTDYG6G.js")).CloudWatchLogsChecker,
|
|
230
230
|
ecs: async () => (await import("./ecs-UHKCH5A7.js")).ECSChecker,
|
|
@@ -477,8 +477,8 @@ async function runInfraGenerate(options = {}) {
|
|
|
477
477
|
generateWithMerge: generateWithMerge2,
|
|
478
478
|
writeManifest: writeManifest2,
|
|
479
479
|
DEFAULT_MANIFEST_NAME: DEFAULT_MANIFEST_NAME2
|
|
480
|
-
} = await import("./generate-
|
|
481
|
-
const { getAllResources: getAllResources2, isMultiAccountManifest: isMultiAccountManifest2 } = await import("./manifest-
|
|
480
|
+
} = await import("./generate-4EY6VETG.js");
|
|
481
|
+
const { getAllResources: getAllResources2, isMultiAccountManifest: isMultiAccountManifest2 } = await import("./manifest-CL4QMZT6.js");
|
|
482
482
|
try {
|
|
483
483
|
const manifest = await generateWithMerge2(options.input, {
|
|
484
484
|
project: options.project,
|
|
@@ -565,4 +565,4 @@ export {
|
|
|
565
565
|
validateStackExport,
|
|
566
566
|
writeManifest
|
|
567
567
|
};
|
|
568
|
-
//# sourceMappingURL=infra-
|
|
568
|
+
//# sourceMappingURL=infra-OWKYLH3J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 */\nfunction _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":"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","names":["chalk","checkerFactories","checkerCache","chalk","generateWithMerge","writeManifest","DEFAULT_MANIFEST_NAME","getAllResources","isMultiAccountManifest"]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
normalizeManifest,
|
|
9
9
|
parseAccountKey,
|
|
10
10
|
readManifest
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-T2PWT2B5.js";
|
|
12
12
|
export {
|
|
13
13
|
ManifestError,
|
|
14
14
|
detectAccountFromResource,
|
|
@@ -20,4 +20,4 @@ export {
|
|
|
20
20
|
parseAccountKey,
|
|
21
21
|
readManifest
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=manifest-
|
|
23
|
+
//# sourceMappingURL=manifest-CL4QMZT6.js.map
|
|
@@ -2,15 +2,6 @@
|
|
|
2
2
|
* Smart keyword matching logic for guidelines
|
|
3
3
|
*/
|
|
4
4
|
import { type Guideline, type MatchedGuideline } from "./types.js";
|
|
5
|
-
/**
|
|
6
|
-
* Parse a context string into keywords.
|
|
7
|
-
* Extracts words, lowercases them, and removes duplicates.
|
|
8
|
-
*/
|
|
9
|
-
export declare function parseContext(context: string): string[];
|
|
10
|
-
/**
|
|
11
|
-
* Score a guideline based on how many keywords match its tags.
|
|
12
|
-
*/
|
|
13
|
-
export declare function scoreGuideline(guideline: Guideline, keywords: string[]): number;
|
|
14
5
|
/**
|
|
15
6
|
* Match guidelines against a context string.
|
|
16
7
|
* Returns guidelines sorted by score (descending) then priority (ascending).
|
|
@@ -8,10 +8,6 @@ export declare const frontmatterSchema: z.ZodObject<{
|
|
|
8
8
|
priority: z.ZodNumber;
|
|
9
9
|
tags: z.ZodArray<z.ZodString>;
|
|
10
10
|
}, z.core.$strip>;
|
|
11
|
-
/**
|
|
12
|
-
* Parse a guideline markdown file content into a Guideline object.
|
|
13
|
-
*/
|
|
14
|
-
export declare function parseGuideline(fileContent: string, filename: string): Guideline;
|
|
15
11
|
/**
|
|
16
12
|
* Load all guidelines from a directory.
|
|
17
13
|
*/
|
|
@@ -10,12 +10,12 @@ import {
|
|
|
10
10
|
loadRuleset,
|
|
11
11
|
matchGuidelines,
|
|
12
12
|
toListItems
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-AJIWBLUQ.js";
|
|
14
|
+
import "./chunk-G5AS4QBP.js";
|
|
15
15
|
import {
|
|
16
16
|
loadConfigAsync
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-UU6OT5O3.js";
|
|
18
|
+
import "./chunk-HMNRMNEA.js";
|
|
19
19
|
|
|
20
20
|
// src/mcp/server.ts
|
|
21
21
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -202,4 +202,4 @@ export {
|
|
|
202
202
|
createServer,
|
|
203
203
|
startServer
|
|
204
204
|
};
|
|
205
|
-
//# sourceMappingURL=mcp-
|
|
205
|
+
//# sourceMappingURL=mcp-6PRCC6P6.js.map
|
package/dist/process/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Config } from "../core/index.js";
|
|
2
2
|
import { type DomainResult } from "../core/index.js";
|
|
3
|
-
export {
|
|
3
|
+
export { HooksRunner } from "./tools/index.js";
|
|
4
4
|
/**
|
|
5
5
|
* Run all process checks based on configuration
|
|
6
6
|
*/
|
|
@@ -10,8 +10,6 @@ export declare function parseRepoString(repo: string): RemoteRepoInfo;
|
|
|
10
10
|
export declare function isGhAvailable(): Promise<boolean>;
|
|
11
11
|
/** Verify the repository exists and user has access */
|
|
12
12
|
export declare function verifyRepoAccess(repoInfo: RemoteRepoInfo): Promise<boolean>;
|
|
13
|
-
/** Check if a file exists in the remote repository via GitHub Contents API */
|
|
14
|
-
export declare function checkRemoteFileExists(repoInfo: RemoteRepoInfo, filePath: string): Promise<boolean>;
|
|
15
13
|
/** Batch check multiple files in a repository */
|
|
16
14
|
export declare function checkRemoteFiles(repoInfo: RemoteRepoInfo, configs: FileCheckConfig[]): Promise<FileCheckResult[]>;
|
|
17
15
|
/** Standard file checks for remote validation */
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import type { ProjectType } from "./types.js";
|
|
2
|
-
/** Get the default template for a project type */
|
|
3
|
-
export declare function getTemplate(type: ProjectType): string;
|
|
4
|
-
/** Get a template that extends from a registry */
|
|
5
|
-
export declare function getExtendsTemplate(registryPath: string, projectType: ProjectType): string;
|
|
6
2
|
/**
|
|
7
3
|
* Create a standards.toml file for a project.
|
|
8
4
|
* @returns true if file was created (or would be created in dry-run)
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
mergeConfigs,
|
|
5
5
|
parseRegistryUrl,
|
|
6
6
|
resolveExtends
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-UU6OT5O3.js";
|
|
8
|
+
import "./chunk-HMNRMNEA.js";
|
|
9
9
|
export {
|
|
10
10
|
fetchRegistry,
|
|
11
11
|
loadRuleset,
|
|
@@ -13,4 +13,4 @@ export {
|
|
|
13
13
|
parseRegistryUrl,
|
|
14
14
|
resolveExtends
|
|
15
15
|
};
|
|
16
|
-
//# sourceMappingURL=registry-
|
|
16
|
+
//# sourceMappingURL=registry-QYUYWBMY.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AWS_DEFAULTS
|
|
3
|
+
} from "./chunk-HMNRMNEA.js";
|
|
1
4
|
import {
|
|
2
5
|
createClientFactoryWithConfig
|
|
3
6
|
} from "./chunk-O745CMWG.js";
|
|
4
|
-
import {
|
|
5
|
-
AWS_DEFAULTS
|
|
6
|
-
} from "./chunk-RHM53NLG.js";
|
|
7
7
|
|
|
8
8
|
// src/infra/checkers/s3.ts
|
|
9
9
|
import { HeadBucketCommand, S3Client } from "@aws-sdk/client-s3";
|
|
@@ -50,4 +50,4 @@ async function checkBucket(bucketName, region, arn) {
|
|
|
50
50
|
export {
|
|
51
51
|
S3Checker
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=s3-
|
|
53
|
+
//# sourceMappingURL=s3-3DJX6X5S.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AWS_DEFAULTS
|
|
3
|
-
} from "./chunk-RHM53NLG.js";
|
|
4
1
|
import {
|
|
5
2
|
createClientFactoryWithConfig
|
|
6
3
|
} from "./chunk-O745CMWG.js";
|
|
4
|
+
import {
|
|
5
|
+
AWS_DEFAULTS
|
|
6
|
+
} from "./chunk-HMNRMNEA.js";
|
|
7
7
|
|
|
8
8
|
// src/infra/checkers/s3.ts
|
|
9
9
|
import { HeadBucketCommand, S3Client } from "@aws-sdk/client-s3";
|
|
@@ -50,4 +50,4 @@ async function checkBucket(bucketName, region, arn) {
|
|
|
50
50
|
export {
|
|
51
51
|
S3Checker
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=s3-
|
|
53
|
+
//# sourceMappingURL=s3-6YMTP5VV.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExitCode
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-G5AS4QBP.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfigAsync
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-UU6OT5O3.js";
|
|
7
|
+
import "./chunk-HMNRMNEA.js";
|
|
8
8
|
|
|
9
9
|
// src/process/scan/index.ts
|
|
10
10
|
import chalk from "chalk";
|
|
@@ -513,7 +513,7 @@ async function scanRepository(repo, config) {
|
|
|
513
513
|
return aggregateResults(repoInfo, [rulesetsResult, filesResult]);
|
|
514
514
|
}
|
|
515
515
|
async function validateProcess(options) {
|
|
516
|
-
const { loadConfigAsync: loadConfigAsync2 } = await import("./core-
|
|
516
|
+
const { loadConfigAsync: loadConfigAsync2 } = await import("./core-SAQ5O5IL.js");
|
|
517
517
|
const { config } = await loadConfigAsync2(options.config);
|
|
518
518
|
const result = await scanRepository(options.repo, config);
|
|
519
519
|
const fs = await import("fs");
|
|
@@ -591,4 +591,4 @@ export {
|
|
|
591
591
|
scanRepository,
|
|
592
592
|
validateProcess
|
|
593
593
|
};
|
|
594
|
-
//# sourceMappingURL=scan-
|
|
594
|
+
//# sourceMappingURL=scan-5QKYVHI6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/process/scan/index.ts","../src/process/scan/scanner.ts","../src/process/scan/remote-fetcher.ts","../src/process/scan/validators.ts"],"sourcesContent":["import chalk from \"chalk\";\n\nimport { loadConfigAsync } from \"../../core/index.js\";\nimport { ExitCode } from \"../../core/index.js\";\nimport { scanRepository } from \"./scanner.js\";\nimport { type ScanOptions, type ScanResult } from \"./types.js\";\n\n// Re-export public API types\nexport {\n type RemoteRepoInfo,\n type ScanOptions,\n type ScanResult,\n type ValidateProcessOptions,\n type ValidateProcessResult,\n} from \"./types.js\";\n\n// Re-export scanner\nexport { scanRepository, validateProcess } from \"./scanner.js\";\n\n/** Format scan result as text */\nfunction formatScanText(result: ScanResult): string {\n const lines: string[] = [];\n\n lines.push(`Repository: ${result.repoInfo.owner}/${result.repoInfo.repo}`);\n lines.push(\"\");\n\n for (const check of result.checks) {\n if (check.skipped) {\n lines.push(chalk.yellow(`⊘ ${check.name} (skipped: ${check.skipReason})`));\n } else if (check.passed) {\n lines.push(chalk.green(`✓ ${check.name}`));\n } else {\n lines.push(chalk.red(`✗ ${check.name}`));\n for (const violation of check.violations) {\n lines.push(chalk.red(` • ${violation.message}`));\n }\n }\n }\n\n lines.push(\"\");\n lines.push(\n `Summary: ${result.summary.passedChecks} passed, ` +\n `${result.summary.failedChecks} failed, ` +\n `${result.summary.skippedChecks} skipped`\n );\n\n return lines.join(\"\\n\");\n}\n\n/** Format scan result as JSON */\nfunction formatScanJson(result: ScanResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/** Run the scan command */\nexport async function runScan(options: ScanOptions): Promise<void> {\n try {\n const { config } = await loadConfigAsync(options.config);\n const result = await scanRepository(options.repo, config);\n\n const output = options.format === \"json\" ? formatScanJson(result) : formatScanText(result);\n\n process.stdout.write(`${output}\\n`);\n process.exit(result.passed ? ExitCode.SUCCESS : ExitCode.VIOLATIONS_FOUND);\n } catch (error) {\n if (options.format === \"json\") {\n const errorObj = {\n error: true,\n message: error instanceof Error ? error.message : String(error),\n code: (error as { code?: string }).code ?? \"UNKNOWN\",\n };\n process.stdout.write(`${JSON.stringify(errorObj, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));\n }\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n}\n","import { execa } from \"execa\";\n\nimport { type Config } from \"../../core/index.js\";\nimport { type CheckResult, ExitCode, type Violation } from \"../../core/index.js\";\nimport {\n checkRemoteFiles,\n isGhAvailable,\n parseRepoString,\n RemoteFetcherError,\n standardFileChecks,\n verifyRepoAccess,\n} from \"./remote-fetcher.js\";\nimport {\n type FileCheckConfig,\n type RemoteRepoInfo,\n type ScanResult,\n type ValidateProcessOptions,\n type ValidateProcessResult,\n} from \"./types.js\";\nimport { type RulesetResponse, validateRulesets } from \"./validators.js\";\n\n/** Fetch rulesets from GitHub API */\nasync function fetchRulesets(repoInfo: RemoteRepoInfo): Promise<RulesetResponse[]> {\n const result = await execa(\"gh\", [\"api\", `repos/${repoInfo.owner}/${repoInfo.repo}/rulesets`]);\n return JSON.parse(result.stdout) as RulesetResponse[];\n}\n\n/** Create a skipped check result */\nfunction createSkippedResult(\n name: string,\n rule: string,\n reason: string,\n duration: number\n): CheckResult {\n return { name, rule, passed: true, violations: [], skipped: true, skipReason: reason, duration };\n}\n\n/** Create an error check result */\nfunction createErrorResult(\n name: string,\n rule: string,\n message: string,\n duration: number\n): CheckResult {\n return {\n name,\n rule,\n passed: false,\n violations: [{ rule, tool: \"scan\", message, severity: \"error\" }],\n skipped: false,\n duration,\n };\n}\n\n/** Handle API errors for ruleset fetching */\nfunction handleRulesetError(\n error: unknown,\n repoConfig: NonNullable<Config[\"process\"]>[\"repo\"],\n elapsed: () => number\n): CheckResult {\n const msg = error instanceof Error ? error.message : String(error);\n\n if (msg.includes(\"403\") || msg.includes(\"Must have admin rights\")) {\n return createSkippedResult(\n \"Repository Settings\",\n \"process.repo\",\n \"Cannot check rulesets: insufficient permissions (requires admin access)\",\n elapsed()\n );\n }\n\n if (msg.includes(\"404\")) {\n const violations: Violation[] = [];\n if (repoConfig?.require_branch_protection) {\n violations.push({\n rule: \"process.repo.branch_protection\",\n tool: \"scan\",\n message: \"No branch protection rulesets configured\",\n severity: \"error\",\n });\n }\n return {\n name: \"Repository Settings\",\n rule: \"process.repo\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n }\n\n return createErrorResult(\n \"Repository Settings\",\n \"process.repo\",\n `Failed to check rulesets: ${msg}`,\n elapsed()\n );\n}\n\n/** Check repository rulesets and branch protection */\nasync function checkRulesets(repoInfo: RemoteRepoInfo, config: Config): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n const repoConfig = config.process?.repo;\n\n if (!repoConfig?.enabled) {\n return createSkippedResult(\n \"Repository Settings\",\n \"process.repo\",\n \"Repository settings check not enabled in config\",\n elapsed()\n );\n }\n\n try {\n const rulesets = await fetchRulesets(repoInfo);\n const violations = validateRulesets(rulesets, repoConfig);\n\n return {\n name: \"Repository Settings\",\n rule: \"process.repo\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n } catch (error) {\n return handleRulesetError(error, repoConfig, elapsed);\n }\n}\n\n/** Build file checks configuration from config */\nfunction buildFileChecks(config: Config): FileCheckConfig[] {\n const fileChecks: FileCheckConfig[] = [];\n\n if (config.process?.repo?.require_codeowners) {\n fileChecks.push({\n path: \"CODEOWNERS\",\n alternativePaths: [\".github/CODEOWNERS\", \"docs/CODEOWNERS\"],\n required: true,\n description: \"CODEOWNERS file for code review assignment\",\n });\n }\n\n fileChecks.push(\n ...standardFileChecks.filter((check) => !fileChecks.some((fc) => fc.path === check.path))\n );\n\n return fileChecks;\n}\n\n/** Convert file check results to violations */\nfunction fileResultsToViolations(\n results: { path: string; exists: boolean; checkedPaths: string[] }[],\n fileChecks: FileCheckConfig[]\n): Violation[] {\n const violations: Violation[] = [];\n\n for (const result of results) {\n const checkConfig = fileChecks.find((fc) => fc.path === result.path);\n if (!result.exists && checkConfig?.required) {\n violations.push({\n rule: `process.scan.files.${result.path.replace(/[./]/g, \"_\")}`,\n tool: \"scan\",\n message: `Required file not found: ${result.path} (checked: ${result.checkedPaths.join(\", \")})`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n}\n\n/** Check remote files for existence */\nasync function checkFiles(repoInfo: RemoteRepoInfo, config: Config): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n const fileChecks = buildFileChecks(config);\n\n if (fileChecks.length === 0) {\n return createSkippedResult(\n \"Repository Files\",\n \"process.scan.files\",\n \"No file checks configured\",\n elapsed()\n );\n }\n\n try {\n const results = await checkRemoteFiles(repoInfo, fileChecks);\n const violations = fileResultsToViolations(results, fileChecks);\n\n return {\n name: \"Repository Files\",\n rule: \"process.scan.files\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return createErrorResult(\n \"Repository Files\",\n \"process.scan.files\",\n `Failed to check files: ${msg}`,\n elapsed()\n );\n }\n}\n\n/** Aggregate check results into scan result */\nfunction aggregateResults(repoInfo: RemoteRepoInfo, checks: CheckResult[]): ScanResult {\n const violations = checks.flatMap((c) => c.violations);\n const passedChecks = checks.filter((c) => c.passed && !c.skipped).length;\n const failedChecks = checks.filter((c) => !c.passed && !c.skipped).length;\n const skippedChecks = checks.filter((c) => c.skipped).length;\n\n return {\n repoInfo,\n checks,\n violations,\n passed: failedChecks === 0,\n summary: { totalChecks: checks.length, passedChecks, failedChecks, skippedChecks },\n };\n}\n\n/** Run all remote scans for a repository */\nexport async function scanRepository(repo: string, config: Config): Promise<ScanResult> {\n const repoInfo = parseRepoString(repo);\n\n if (!(await isGhAvailable())) {\n throw new RemoteFetcherError(\n \"GitHub CLI (gh) not available. Install it from https://cli.github.com/\",\n \"NO_GH\"\n );\n }\n\n await verifyRepoAccess(repoInfo);\n\n const [rulesetsResult, filesResult] = await Promise.all([\n checkRulesets(repoInfo, config),\n checkFiles(repoInfo, config),\n ]);\n\n return aggregateResults(repoInfo, [rulesetsResult, filesResult]);\n}\n\n/** Programmatic API for validating remote process checks */\nexport async function validateProcess(\n options: ValidateProcessOptions\n): Promise<ValidateProcessResult> {\n const { loadConfigAsync } = await import(\"../../core/index.js\");\n const { config } = await loadConfigAsync(options.config);\n const result = await scanRepository(options.repo, config);\n\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n const { fileURLToPath } = await import(\"node:url\");\n\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const packageJsonPath = path.resolve(__dirname, \"..\", \"..\", \"..\", \"package.json\");\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\")) as { version: string };\n\n return {\n version: packageJson.version,\n repoInfo: result.repoInfo,\n domain: \"process\",\n checks: result.checks,\n summary: {\n totalChecks: result.summary.totalChecks,\n passedChecks: result.summary.passedChecks,\n failedChecks: result.summary.failedChecks,\n totalViolations: result.violations.length,\n exitCode: result.passed ? ExitCode.SUCCESS : ExitCode.VIOLATIONS_FOUND,\n },\n };\n}\n","import { execa } from \"execa\";\n\nimport { type FileCheckConfig, type FileCheckResult, type RemoteRepoInfo } from \"./types.js\";\n\n/** Error thrown when remote fetcher encounters an issue */\nexport class RemoteFetcherError extends Error {\n constructor(\n message: string,\n public readonly code: \"NO_GH\" | \"NO_REPO\" | \"NO_PERMISSION\" | \"API_ERROR\" | \"INVALID_REPO\"\n ) {\n super(message);\n this.name = \"RemoteFetcherError\";\n }\n}\n\n/** Parse owner/repo string into RemoteRepoInfo */\nexport function parseRepoString(repo: string): RemoteRepoInfo {\n const parts = repo.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new RemoteFetcherError(\n `Invalid repository format: \"${repo}\". Expected \"owner/repo\" format.`,\n \"INVALID_REPO\"\n );\n }\n return { owner: parts[0], repo: parts[1] };\n}\n\n/** Check if gh CLI is available */\nexport async function isGhAvailable(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Verify the repository exists and user has access */\nexport async function verifyRepoAccess(repoInfo: RemoteRepoInfo): Promise<boolean> {\n try {\n await execa(\"gh\", [\"api\", `repos/${repoInfo.owner}/${repoInfo.repo}`]);\n return true;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (errorMessage.includes(\"404\") || errorMessage.includes(\"Not Found\")) {\n throw new RemoteFetcherError(\n `Repository not found: ${repoInfo.owner}/${repoInfo.repo}`,\n \"NO_REPO\"\n );\n }\n\n if (errorMessage.includes(\"403\") || errorMessage.includes(\"401\")) {\n throw new RemoteFetcherError(\n `Cannot access repository: ${repoInfo.owner}/${repoInfo.repo}. Check your GITHUB_TOKEN permissions.`,\n \"NO_PERMISSION\"\n );\n }\n\n throw new RemoteFetcherError(\n `Failed to verify repository access: ${errorMessage}`,\n \"API_ERROR\"\n );\n }\n}\n\n/** Check if a file exists in the remote repository via GitHub Contents API */\nasync function checkRemoteFileExists(\n repoInfo: RemoteRepoInfo,\n filePath: string\n): Promise<boolean> {\n try {\n await execa(\"gh\", [\n \"api\",\n `repos/${repoInfo.owner}/${repoInfo.repo}/contents/${filePath}`,\n \"--silent\",\n ]);\n return true;\n } catch {\n // File doesn't exist or no access - both return false\n return false;\n }\n}\n\n/** Check multiple alternative paths for a file */\nasync function checkRemoteFileWithAlternatives(\n repoInfo: RemoteRepoInfo,\n config: FileCheckConfig\n): Promise<FileCheckResult> {\n const allPaths = [config.path, ...(config.alternativePaths ?? [])];\n\n for (const path of allPaths) {\n // Sequential check needed - stop on first match\n const exists = await checkRemoteFileExists(repoInfo, path);\n if (exists) {\n return { path: config.path, exists: true, checkedPaths: allPaths };\n }\n }\n\n return { path: config.path, exists: false, checkedPaths: allPaths };\n}\n\n/** Batch check multiple files in a repository */\nexport async function checkRemoteFiles(\n repoInfo: RemoteRepoInfo,\n configs: FileCheckConfig[]\n): Promise<FileCheckResult[]> {\n // Run checks in parallel for efficiency\n const results = await Promise.all(\n configs.map((config) => checkRemoteFileWithAlternatives(repoInfo, config))\n );\n return results;\n}\n\n/** Standard file checks for remote validation */\nexport const standardFileChecks: FileCheckConfig[] = [\n {\n path: \"CODEOWNERS\",\n alternativePaths: [\".github/CODEOWNERS\", \"docs/CODEOWNERS\"],\n required: false,\n description: \"CODEOWNERS file for code review assignment\",\n },\n {\n path: \".github/PULL_REQUEST_TEMPLATE.md\",\n alternativePaths: [\n \".github/pull_request_template.md\",\n \"PULL_REQUEST_TEMPLATE.md\",\n \"pull_request_template.md\",\n ],\n required: false,\n description: \"Pull request template\",\n },\n {\n path: \"README.md\",\n alternativePaths: [\"readme.md\", \"README\"],\n required: false,\n description: \"Repository README\",\n },\n {\n path: \".github/workflows\",\n required: false,\n description: \"GitHub Actions workflows directory\",\n },\n];\n","import { type Config } from \"../../core/index.js\";\nimport { type Violation } from \"../../core/index.js\";\n\n/** GitHub Ruleset response types */\ninterface RulesetBypassActor {\n actor_id: number | null;\n actor_type: string;\n bypass_mode: string;\n}\n\ninterface RulesetRule {\n type: string;\n parameters?: {\n required_approving_review_count?: number;\n dismiss_stale_reviews_on_push?: boolean;\n require_code_owner_review?: boolean;\n required_status_checks?: { context: string }[];\n strict_required_status_checks_policy?: boolean;\n };\n}\n\nexport interface RulesetResponse {\n id: number;\n name: string;\n target: string;\n enforcement: string;\n conditions?: { ref_name?: { include?: string[]; exclude?: string[] } };\n bypass_actors?: RulesetBypassActor[];\n rules?: RulesetRule[];\n}\n\ntype RulesetConfig = NonNullable<NonNullable<Config[\"process\"]>[\"repo\"]>[\"ruleset\"];\ntype TagProtectionConfig = NonNullable<NonNullable<Config[\"process\"]>[\"repo\"]>[\"tag_protection\"];\n\n/** Check if branch matches any of the include patterns */\nfunction matchesBranch(patterns: string[], branch: string): boolean {\n for (const pattern of patterns) {\n const cleanPattern = pattern.replace(/^refs\\/heads\\//, \"\");\n if (cleanPattern === branch) {\n return true;\n }\n if (cleanPattern === \"~DEFAULT_BRANCH\" && branch === \"main\") {\n return true;\n }\n if (cleanPattern === \"~ALL\") {\n return true;\n }\n if (cleanPattern.includes(\"*\")) {\n const regex = new RegExp(`^${cleanPattern.replace(/\\*/g, \".*\")}$`);\n if (regex.test(branch)) {\n return true;\n }\n }\n }\n return false;\n}\n\n/** Find branch ruleset matching the target branch */\nfunction findBranchRuleset(\n rulesets: RulesetResponse[],\n branch: string\n): RulesetResponse | undefined {\n return rulesets.find(\n (r) =>\n r.target === \"branch\" &&\n r.enforcement === \"active\" &&\n matchesBranch(r.conditions?.ref_name?.include ?? [], branch)\n );\n}\n\n/** Validate rulesets against config */\n \nexport function validateRulesets(\n rulesets: RulesetResponse[],\n repoConfig: NonNullable<Config[\"process\"]>[\"repo\"]\n): Violation[] {\n if (!repoConfig) {\n return [];\n }\n\n const violations: Violation[] = [];\n const rulesetConfig = repoConfig.ruleset;\n const branch = rulesetConfig?.branch ?? \"main\";\n const branchRuleset = findBranchRuleset(rulesets, branch);\n\n if (repoConfig.require_branch_protection && !branchRuleset) {\n violations.push({\n rule: \"process.repo.branch_protection\",\n tool: \"scan\",\n message: `Branch '${branch}' does not have a branch protection ruleset`,\n severity: \"error\",\n });\n }\n\n if (branchRuleset && rulesetConfig) {\n violations.push(...validateBranchRuleset(branchRuleset, rulesetConfig, branch));\n }\n\n if (repoConfig.tag_protection?.patterns?.length) {\n violations.push(...validateTagProtection(rulesets, repoConfig.tag_protection));\n }\n\n return violations;\n}\n\n/** Validate branch ruleset settings against config */\nfunction validateBranchRuleset(\n ruleset: RulesetResponse,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const rules = ruleset.rules ?? [];\n const prRule = rules.find((r) => r.type === \"pull_request\");\n const statusRule = rules.find((r) => r.type === \"required_status_checks\");\n\n violations.push(...validatePullRequestRule(prRule, config, branch));\n violations.push(...validateStatusChecksRule(statusRule, config, branch));\n violations.push(...validateSignedCommits(rules, config, branch));\n violations.push(...validateBypassActors(ruleset.bypass_actors ?? [], config, branch));\n\n return violations;\n}\n\n/** Validate pull request rule settings */\n \nfunction validatePullRequestRule(\n prRule: RulesetRule | undefined,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const params = prRule?.parameters;\n\n if (config.required_reviews !== undefined) {\n const actualReviews = params?.required_approving_review_count ?? 0;\n if (actualReviews < config.required_reviews) {\n violations.push({\n rule: \"process.repo.branch_protection.required_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' requires ${actualReviews} reviews, expected at least ${config.required_reviews}`,\n severity: \"error\",\n });\n }\n }\n\n if (config.dismiss_stale_reviews === true && !(params?.dismiss_stale_reviews_on_push ?? false)) {\n violations.push({\n rule: \"process.repo.branch_protection.dismiss_stale_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' does not dismiss stale reviews on new commits`,\n severity: \"error\",\n });\n }\n\n if (config.require_code_owner_reviews === true && !(params?.require_code_owner_review ?? false)) {\n violations.push({\n rule: \"process.repo.branch_protection.require_code_owner_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require code owner reviews`,\n severity: \"error\",\n });\n }\n\n return violations;\n}\n\n/** Validate status checks rule settings */\n \nfunction validateStatusChecksRule(\n statusRule: RulesetRule | undefined,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const params = statusRule?.parameters;\n\n if (config.require_status_checks && config.require_status_checks.length > 0) {\n const actualChecks = params?.required_status_checks?.map((c) => c.context) ?? [];\n const missingChecks = config.require_status_checks.filter(\n (check) => !actualChecks.includes(check)\n );\n if (missingChecks.length > 0) {\n violations.push({\n rule: \"process.repo.branch_protection.require_status_checks\",\n tool: \"scan\",\n message: `Branch '${branch}' missing required status checks: ${missingChecks.join(\", \")}`,\n severity: \"error\",\n });\n }\n }\n\n if (\n config.require_branches_up_to_date === true &&\n !(params?.strict_required_status_checks_policy ?? false)\n ) {\n violations.push({\n rule: \"process.repo.branch_protection.require_branches_up_to_date\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require branches to be up to date before merging`,\n severity: \"error\",\n });\n }\n\n return violations;\n}\n\n/** Validate signed commits requirement */\nfunction validateSignedCommits(\n rules: RulesetRule[],\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (config?.require_signed_commits !== true) {\n return [];\n }\n\n if (!rules.some((r) => r.type === \"required_signatures\")) {\n return [\n {\n rule: \"process.repo.branch_protection.require_signed_commits\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require signed commits`,\n severity: \"error\",\n },\n ];\n }\n\n return [];\n}\n\n/** Validate bypass actors configuration */\nfunction validateBypassActors(\n actualBypass: RulesetBypassActor[],\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (config?.enforce_admins !== true || actualBypass.length === 0) {\n return [];\n }\n\n return [\n {\n rule: \"process.repo.branch_protection.enforce_admins\",\n tool: \"scan\",\n message: `Branch '${branch}' has bypass actors configured but enforce_admins requires no bypasses`,\n severity: \"error\",\n },\n ];\n}\n\n/** Validate tag protection rulesets */\nfunction validateTagProtection(\n rulesets: RulesetResponse[],\n tagConfig: TagProtectionConfig\n): Violation[] {\n if (!tagConfig?.patterns?.length) {\n return [];\n }\n\n const violations: Violation[] = [];\n const tagRuleset = rulesets.find((r) => r.target === \"tag\" && r.enforcement === \"active\");\n\n if (!tagRuleset) {\n return [\n {\n rule: \"process.repo.tag_protection\",\n tool: \"scan\",\n message: \"No active tag protection ruleset found\",\n severity: \"error\",\n },\n ];\n }\n\n violations.push(...validateTagPatterns(tagConfig.patterns, tagRuleset));\n violations.push(...validateTagRules(tagConfig, tagRuleset.rules ?? []));\n\n return violations;\n}\n\n/** Validate tag patterns match */\nfunction validateTagPatterns(expectedPatterns: string[], tagRuleset: RulesetResponse): Violation[] {\n const expected = expectedPatterns.map((p) => `refs/tags/${p}`).sort();\n const actual = [...(tagRuleset.conditions?.ref_name?.include ?? [])].sort();\n\n if (expected.length === actual.length && expected.every((v, i) => v === actual[i])) {\n return [];\n }\n\n const found = actual.map((p) => p.replace(/^refs\\/tags\\//, \"\")).join(\", \");\n return [\n {\n rule: \"process.repo.tag_protection.patterns\",\n tool: \"scan\",\n message: `Tag protection patterns mismatch: expected [${expectedPatterns.join(\", \")}], found [${found}]`,\n severity: \"error\",\n },\n ];\n}\n\n/** Validate tag protection rules */\nfunction validateTagRules(tagConfig: TagProtectionConfig, rules: RulesetRule[]): Violation[] {\n if (!tagConfig) {\n return [];\n }\n\n const violations: Violation[] = [];\n\n if (tagConfig.prevent_deletion !== false && !rules.some((r) => r.type === \"deletion\")) {\n violations.push({\n rule: \"process.repo.tag_protection.prevent_deletion\",\n tool: \"scan\",\n message: \"Tag protection does not prevent deletion\",\n severity: \"error\",\n });\n }\n\n if (tagConfig.prevent_update !== false && !rules.some((r) => r.type === \"update\")) {\n violations.push({\n rule: \"process.repo.tag_protection.prevent_update\",\n tool: \"scan\",\n message: \"Tag protection does not prevent updates (force-push)\",\n severity: \"error\",\n });\n }\n\n return violations;\n}\n"],"mappings":"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","names":["execa","execa","loadConfigAsync"]}
|
|
@@ -11,12 +11,9 @@ import {
|
|
|
11
11
|
loadGuideline,
|
|
12
12
|
loadRuleset,
|
|
13
13
|
matchGuidelines,
|
|
14
|
-
parseContext,
|
|
15
|
-
parseGuideline,
|
|
16
|
-
scoreGuideline,
|
|
17
14
|
toListItems
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-AJIWBLUQ.js";
|
|
16
|
+
import "./chunk-HMNRMNEA.js";
|
|
20
17
|
export {
|
|
21
18
|
StandardsError,
|
|
22
19
|
composeGuidelines,
|
|
@@ -30,9 +27,6 @@ export {
|
|
|
30
27
|
loadGuideline,
|
|
31
28
|
loadRuleset,
|
|
32
29
|
matchGuidelines,
|
|
33
|
-
parseContext,
|
|
34
|
-
parseGuideline,
|
|
35
|
-
scoreGuideline,
|
|
36
30
|
toListItems
|
|
37
31
|
};
|
|
38
|
-
//# sourceMappingURL=standards-
|
|
32
|
+
//# sourceMappingURL=standards-EGSQSDOD.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-G5AS4QBP.js";
|
|
2
2
|
import {
|
|
3
3
|
getProjectRoot,
|
|
4
4
|
loadConfig
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-UU6OT5O3.js";
|
|
6
|
+
import "./chunk-HMNRMNEA.js";
|
|
7
7
|
|
|
8
8
|
// src/process/sync/applier.ts
|
|
9
9
|
import { execa } from "execa";
|
|
@@ -875,4 +875,4 @@ export {
|
|
|
875
875
|
runTagDiff,
|
|
876
876
|
runTagSync
|
|
877
877
|
};
|
|
878
|
-
//# sourceMappingURL=sync-
|
|
878
|
+
//# sourceMappingURL=sync-QMZDAV44.js.map
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
/** Single file validation error */
|
|
2
|
-
export interface GuidelineValidationError {
|
|
3
|
-
file: string;
|
|
4
|
-
errors: string[];
|
|
5
|
-
}
|
|
6
|
-
/** Overall validation result */
|
|
7
|
-
export interface GuidelineValidationResult {
|
|
8
|
-
valid: boolean;
|
|
9
|
-
validCount: number;
|
|
10
|
-
invalidCount: number;
|
|
11
|
-
errors: GuidelineValidationError[];
|
|
12
|
-
}
|
|
13
|
-
/** Validate a directory of guideline files */
|
|
14
|
-
export declare function validateGuidelinesDir(dirPath: string): GuidelineValidationResult;
|
|
15
1
|
/** Run the validate guidelines command */
|
|
16
2
|
export declare function runValidateGuidelines(dirPath: string, options: {
|
|
17
3
|
format: string;
|
package/dist/validate/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export { runValidateGuidelines
|
|
2
|
-
export type { GuidelineValidationError, GuidelineValidationResult } from "./guidelines.js";
|
|
1
|
+
export { runValidateGuidelines } from "./guidelines.js";
|
|
3
2
|
export { formatTierResultJson, formatTierResultText, validateTierRuleset } from "./tier.js";
|
|
4
3
|
export type { Tier, TierSourceDetail, ValidateTierOptions, ValidateTierResult, } from "./types.js";
|
|
5
4
|
export { VALID_TIERS } from "./types.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
frontmatterSchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AJIWBLUQ.js";
|
|
4
4
|
import {
|
|
5
5
|
ExitCode
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-G5AS4QBP.js";
|
|
7
7
|
import {
|
|
8
8
|
findConfigFile
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-UU6OT5O3.js";
|
|
10
|
+
import "./chunk-HMNRMNEA.js";
|
|
11
11
|
|
|
12
12
|
// src/validate/guidelines.ts
|
|
13
13
|
import * as fs from "fs";
|
|
@@ -290,7 +290,6 @@ export {
|
|
|
290
290
|
formatTierResultJson,
|
|
291
291
|
formatTierResultText,
|
|
292
292
|
runValidateGuidelines,
|
|
293
|
-
validateGuidelinesDir,
|
|
294
293
|
validateTierRuleset
|
|
295
294
|
};
|
|
296
|
-
//# sourceMappingURL=validate-
|
|
295
|
+
//# sourceMappingURL=validate-OGNSVZO5.js.map
|
|
@@ -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"]}
|