@standards-kit/conform 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -9
- package/dist/{chunk-DXIYZR62.js → chunk-G5AS4QBP.js} +1 -1
- package/dist/{chunk-YKKWXHYS.js → chunk-HLF56NMK.js} +2 -5
- package/dist/chunk-HLF56NMK.js.map +1 -0
- package/dist/{chunk-RHM53NLG.js → chunk-RR4OEIAZ.js} +2 -2
- package/dist/{chunk-RHM53NLG.js.map → chunk-RR4OEIAZ.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-J5S6GRGW.js → chunk-XZERDHOH.js} +2 -2
- package/dist/{chunk-FJZMUGYW.js → chunk-ZKFWS3GU.js} +45 -13
- package/dist/chunk-ZKFWS3GU.js.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/utils.d.ts +2 -4
- package/dist/cli.js +55 -23
- package/dist/cli.js.map +1 -1
- package/dist/code/tools/base.d.ts +4 -2
- package/dist/constants.d.ts +0 -9
- package/dist/core/index.d.ts +0 -1
- package/dist/core/schema.d.ts +1 -0
- package/dist/{core-LFX2BFLG.js → core-HQ7WZCSW.js} +6 -16
- package/dist/{generate-D4MFMOHP.js → generate-4EY6VETG.js} +3 -3
- package/dist/{iam-YXMHK2MV.js → iam-363WGRLI.js} +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +47 -16
- 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-CHHXGSWU.js} +10 -10
- package/dist/infra-CHHXGSWU.js.map +1 -0
- package/dist/{manifest-7AIL2FK2.js → manifest-CL4QMZT6.js} +2 -2
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/standards/matcher.d.ts +0 -9
- package/dist/mcp/standards/parser.d.ts +0 -4
- package/dist/{mcp-DYQG6JEQ.js → mcp-RPYXEVCR.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/hooks.d.ts +3 -0
- package/dist/process/tools/index.d.ts +0 -1
- package/dist/projects/templates.d.ts +0 -4
- package/dist/{registry-J2LVW3M2.js → registry-7CTKYGKA.js} +3 -3
- package/dist/{s3-S4GXNR7H.js → s3-7GRZRXLA.js} +2 -2
- package/dist/{s3-53UELUWT.js → s3-MFBDXYQ5.js} +2 -2
- package/dist/{scan-BZH5IR3Z.js → scan-S5VYRCPC.js} +5 -5
- package/dist/scan-S5VYRCPC.js.map +1 -0
- package/dist/{standards-ALMA4VIU.js → standards-CASOIZJV.js} +3 -9
- package/dist/{sync-EGJ2CSYK.js → sync-PT6KT46K.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-WLVATJEZ.js} +5 -6
- package/dist/validate-WLVATJEZ.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-HQ7WZCSW.js.map} +0 -0
- /package/dist/{generate-D4MFMOHP.js.map → generate-4EY6VETG.js.map} +0 -0
- /package/dist/{iam-YXMHK2MV.js.map → iam-363WGRLI.js.map} +0 -0
- /package/dist/{manifest-7AIL2FK2.js.map → manifest-CL4QMZT6.js.map} +0 -0
- /package/dist/{mcp-DYQG6JEQ.js.map → mcp-RPYXEVCR.js.map} +0 -0
- /package/dist/{registry-J2LVW3M2.js.map → registry-7CTKYGKA.js.map} +0 -0
- /package/dist/{s3-53UELUWT.js.map → s3-7GRZRXLA.js.map} +0 -0
- /package/dist/{s3-S4GXNR7H.js.map → s3-MFBDXYQ5.js.map} +0 -0
- /package/dist/{standards-ALMA4VIU.js.map → standards-CASOIZJV.js.map} +0 -0
- /package/dist/{sync-EGJ2CSYK.js.map → sync-PT6KT46K.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-ZKFWS3GU.js";
|
|
65
65
|
import {
|
|
66
66
|
CONCURRENCY
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-RR4OEIAZ.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-7GRZRXLA.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-363WGRLI.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-CHHXGSWU.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
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Server for coding standards
|
|
3
3
|
*
|
|
4
|
-
* Provides tools for Claude to fetch and compose coding standards from
|
|
4
|
+
* Provides tools for Claude to fetch and compose coding standards from chrismlittle123/standards.
|
|
5
5
|
*/
|
|
6
6
|
export { createServer, startServer } from "./server.js";
|
|
7
7
|
export type { Guideline, GuidelineListItem, GuidelineFrontmatter, Ruleset } from "./standards/types.js";
|
|
@@ -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-HLF56NMK.js";
|
|
14
|
+
import "./chunk-G5AS4QBP.js";
|
|
15
15
|
import {
|
|
16
16
|
loadConfigAsync
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-ZKFWS3GU.js";
|
|
18
|
+
import "./chunk-RR4OEIAZ.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-RPYXEVCR.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 */
|
|
@@ -7,6 +7,7 @@ interface HooksConfig {
|
|
|
7
7
|
require_hooks?: string[];
|
|
8
8
|
commands?: Record<string, string[]>;
|
|
9
9
|
protected_branches?: string[];
|
|
10
|
+
templates?: Record<string, string>;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
13
|
* Git hooks validation runner.
|
|
@@ -31,6 +32,8 @@ export declare class HooksRunner extends BaseProcessToolRunner {
|
|
|
31
32
|
private createPrePushViolation;
|
|
32
33
|
/** Check if pre-push hook has branch detection */
|
|
33
34
|
private hasBranchDetection;
|
|
35
|
+
/** Check that hook files match expected template content */
|
|
36
|
+
private checkHookTemplates;
|
|
34
37
|
/** Check that pre-push hook prevents direct pushes to protected branches */
|
|
35
38
|
private checkProtectedBranches;
|
|
36
39
|
/** Run hooks 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-ZKFWS3GU.js";
|
|
8
|
+
import "./chunk-RR4OEIAZ.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-7CTKYGKA.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-O745CMWG.js";
|
|
4
4
|
import {
|
|
5
5
|
AWS_DEFAULTS
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RR4OEIAZ.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-7GRZRXLA.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AWS_DEFAULTS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RR4OEIAZ.js";
|
|
4
4
|
import {
|
|
5
5
|
createClientFactoryWithConfig
|
|
6
6
|
} from "./chunk-O745CMWG.js";
|
|
@@ -50,4 +50,4 @@ async function checkBucket(bucketName, region, arn) {
|
|
|
50
50
|
export {
|
|
51
51
|
S3Checker
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=s3-
|
|
53
|
+
//# sourceMappingURL=s3-MFBDXYQ5.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-ZKFWS3GU.js";
|
|
7
|
+
import "./chunk-RR4OEIAZ.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-HQ7WZCSW.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-S5VYRCPC.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-HLF56NMK.js";
|
|
16
|
+
import "./chunk-RR4OEIAZ.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-CASOIZJV.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-ZKFWS3GU.js";
|
|
6
|
+
import "./chunk-RR4OEIAZ.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-PT6KT46K.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-HLF56NMK.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-ZKFWS3GU.js";
|
|
10
|
+
import "./chunk-RR4OEIAZ.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-WLVATJEZ.js.map
|