devrail 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +273 -0
- package/dist/chunk-J22FFU7Z.js +575 -0
- package/dist/chunk-J22FFU7Z.js.map +1 -0
- package/dist/chunk-ZDEEHXE7.js +1298 -0
- package/dist/chunk-ZDEEHXE7.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1346 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +312 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/rules-XIWD4KI4.js +17 -0
- package/dist/rules-XIWD4KI4.js.map +1 -0
- package/package.json +88 -0
- package/templates/github-actions/vibeguard.yml +102 -0
- package/templates/gitlab-ci/vibeguard.yml +29 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/config.ts","../src/presets/node-api.ts","../src/presets/nextjs-app.ts","../src/presets/index.ts","../src/engine/config-loader.ts","../src/engine/rule-engine.ts","../src/engine/stack-detector.ts","../src/engine/baseline.ts","../src/engine/diff-mode.ts","../src/tools/base.ts","../src/tools/gitleaks.ts","../src/tools/semgrep.ts","../src/tools/osv-scanner.ts","../src/tools/builtin.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const RuleSeveritySchema = z.enum(['info', 'warn', 'error']);\nexport type RuleSeverity = z.infer<typeof RuleSeveritySchema>;\n\nexport const RuleScopeSchema = z.enum(['changed', 'all']);\nexport type RuleScope = z.infer<typeof RuleScopeSchema>;\n\nexport const LevelSchema = z.enum(['basic', 'standard', 'strict']);\nexport type Level = z.infer<typeof LevelSchema>;\n\nexport const PresetSchema = z.enum([\n 'node-api',\n 'nextjs-app',\n 'python-api',\n 'cli-tool',\n 'library',\n 'monorepo',\n]);\nexport type Preset = z.infer<typeof PresetSchema>;\n\nexport const RuleConfigSchema = z.object({\n enabled: z.boolean().default(true),\n severity: RuleSeveritySchema.optional(),\n autofix: z.boolean().optional(),\n blocking: z.boolean().optional(),\n scope: RuleScopeSchema.optional(),\n options: z.record(z.unknown()).optional(),\n});\nexport type RuleConfig = z.infer<typeof RuleConfigSchema>;\n\nexport const VibeGuardConfigSchema = z.object({\n preset: PresetSchema.optional(),\n level: LevelSchema.default('standard'),\n rules: z.record(z.union([z.boolean(), RuleConfigSchema])).optional(),\n include: z.array(z.string()).optional(),\n exclude: z.array(z.string()).optional(),\n ci: z\n .object({\n failOn: RuleSeveritySchema.default('error'),\n reportFormat: z.enum(['console', 'json', 'sarif']).default('console'),\n })\n .optional(),\n tools: z\n .object({\n eslint: z.boolean().default(true),\n semgrep: z.boolean().default(true),\n gitleaks: z.boolean().default(true),\n osvScanner: z.boolean().default(true),\n })\n .optional(),\n});\nexport type VibeGuardConfig = z.infer<typeof VibeGuardConfigSchema>;\n\nexport interface RuleDefinition {\n id: string;\n name: string;\n description: string;\n category: RuleCategory;\n severity: RuleSeverity;\n autofix: boolean;\n blocking: boolean;\n scope: RuleScope;\n tool: ToolType;\n docs: string;\n rationale: string;\n fix: string;\n examples?: {\n bad?: string;\n good?: string;\n };\n levels: {\n basic: boolean;\n standard: boolean;\n strict: boolean;\n };\n}\n\nexport type RuleCategory =\n | 'secrets'\n | 'deps'\n | 'security'\n | 'auth'\n | 'api'\n | 'sql'\n | 'tests'\n | 'logging'\n | 'code'\n | 'config';\n\nexport type ToolType =\n | 'eslint'\n | 'semgrep'\n | 'gitleaks'\n | 'osv-scanner'\n | 'vitest'\n | 'jest'\n | 'custom'\n | 'builtin';\n\nexport interface CheckResult {\n ruleId: string;\n severity: RuleSeverity;\n message: string;\n file?: string;\n line?: number;\n column?: number;\n endLine?: number;\n endColumn?: number;\n fix?: {\n description: string;\n replacement?: string;\n };\n}\n\nexport interface CheckReport {\n timestamp: string;\n duration: number;\n preset?: Preset;\n level: Level;\n summary: {\n total: number;\n errors: number;\n warnings: number;\n infos: number;\n fixed: number;\n };\n score: number;\n results: CheckResult[];\n tools: {\n name: string;\n version?: string;\n duration: number;\n results: number;\n }[];\n}\n","import type { Preset, Level } from '../types/index.js';\n\nexport interface PresetConfig {\n name: Preset;\n description: string;\n rules: Record<Level, string[]>;\n tools: string[];\n eslintExtends: string[];\n semgrepRules: string[];\n}\n\nexport const nodeApiPreset: PresetConfig = {\n name: 'node-api',\n description: 'Node.js API backend (Express, Fastify, Koa, etc.)',\n rules: {\n basic: [\n 'secrets.no-plaintext',\n 'secrets.no-env-commit',\n 'secrets.gitignore-required',\n 'deps.lockfile.required',\n 'deps.no-vulnerable',\n 'deps.no-typosquatting',\n 'security.cors.safe-default',\n 'security.no-eval',\n 'security.no-prototype-pollution',\n 'auth.no-weak-jwt',\n 'auth.no-hardcoded-credentials',\n 'api.no-sensitive-logging',\n 'sql.no-string-concat',\n 'tests.no-skipped',\n 'code.no-unused-vars',\n ],\n standard: [\n 'secrets.no-plaintext',\n 'secrets.no-env-commit',\n 'secrets.gitignore-required',\n 'deps.lockfile.required',\n 'deps.no-unpinned',\n 'deps.no-git-deps',\n 'deps.no-vulnerable',\n 'deps.no-typosquatting',\n 'security.headers.required',\n 'security.cors.safe-default',\n 'security.no-eval',\n 'security.no-unsafe-regex',\n 'security.no-prototype-pollution',\n 'auth.no-weak-jwt',\n 'auth.no-hardcoded-credentials',\n 'auth.session-secure',\n 'api.validation.required',\n 'api.no-sensitive-logging',\n 'sql.no-string-concat',\n 'tests.unit.required',\n 'tests.coverage.min-50',\n 'tests.no-skipped',\n 'logging.no-pii',\n 'logging.no-console',\n 'code.no-any',\n 'code.strict-mode',\n 'code.no-unused-vars',\n 'config.node-version',\n 'config.editor-config',\n ],\n strict: [\n 'secrets.no-plaintext',\n 'secrets.no-env-commit',\n 'secrets.gitignore-required',\n 'deps.lockfile.required',\n 'deps.no-unpinned',\n 'deps.no-git-deps',\n 'deps.no-vulnerable',\n 'deps.no-typosquatting',\n 'deps.license-check',\n 'security.headers.required',\n 'security.cors.safe-default',\n 'security.no-eval',\n 'security.no-unsafe-regex',\n 'security.no-prototype-pollution',\n 'auth.no-weak-jwt',\n 'auth.no-hardcoded-credentials',\n 'auth.session-secure',\n 'api.validation.required',\n 'api.rate-limiting',\n 'api.no-sensitive-logging',\n 'sql.no-string-concat',\n 'sql.no-raw-queries',\n 'tests.unit.required',\n 'tests.coverage.min-80',\n 'tests.no-skipped',\n 'logging.no-pii',\n 'logging.no-console',\n 'code.no-any',\n 'code.strict-mode',\n 'code.no-unused-vars',\n 'config.node-version',\n 'config.editor-config',\n ],\n },\n tools: ['eslint', 'semgrep', 'gitleaks', 'osv-scanner', 'vitest'],\n eslintExtends: [\n 'eslint:recommended',\n 'plugin:@typescript-eslint/recommended',\n 'plugin:security/recommended-legacy',\n ],\n semgrepRules: [\n 'p/javascript',\n 'p/typescript',\n 'p/nodejs',\n 'p/jwt',\n 'p/sql-injection',\n 'p/secrets',\n ],\n};\n","import type { Preset, Level } from '../types/index.js';\nimport type { PresetConfig } from './node-api.js';\n\nexport const nextjsAppPreset: PresetConfig = {\n name: 'nextjs-app',\n description: 'Next.js full-stack application',\n rules: {\n basic: [\n 'secrets.no-plaintext',\n 'secrets.no-env-commit',\n 'secrets.gitignore-required',\n 'deps.lockfile.required',\n 'deps.no-vulnerable',\n 'deps.no-typosquatting',\n 'security.cors.safe-default',\n 'security.no-eval',\n 'security.no-prototype-pollution',\n 'auth.no-weak-jwt',\n 'auth.no-hardcoded-credentials',\n 'api.no-sensitive-logging',\n 'sql.no-string-concat',\n 'tests.no-skipped',\n 'code.no-unused-vars',\n ],\n standard: [\n 'secrets.no-plaintext',\n 'secrets.no-env-commit',\n 'secrets.gitignore-required',\n 'deps.lockfile.required',\n 'deps.no-unpinned',\n 'deps.no-git-deps',\n 'deps.no-vulnerable',\n 'deps.no-typosquatting',\n 'security.headers.required',\n 'security.cors.safe-default',\n 'security.no-eval',\n 'security.no-unsafe-regex',\n 'security.no-prototype-pollution',\n 'auth.no-weak-jwt',\n 'auth.no-hardcoded-credentials',\n 'auth.session-secure',\n 'api.validation.required',\n 'api.no-sensitive-logging',\n 'sql.no-string-concat',\n 'tests.unit.required',\n 'tests.coverage.min-50',\n 'tests.no-skipped',\n 'logging.no-pii',\n 'logging.no-console',\n 'code.no-any',\n 'code.strict-mode',\n 'code.no-unused-vars',\n 'config.node-version',\n 'config.editor-config',\n ],\n strict: [\n 'secrets.no-plaintext',\n 'secrets.no-env-commit',\n 'secrets.gitignore-required',\n 'deps.lockfile.required',\n 'deps.no-unpinned',\n 'deps.no-git-deps',\n 'deps.no-vulnerable',\n 'deps.no-typosquatting',\n 'deps.license-check',\n 'security.headers.required',\n 'security.cors.safe-default',\n 'security.no-eval',\n 'security.no-unsafe-regex',\n 'security.no-prototype-pollution',\n 'auth.no-weak-jwt',\n 'auth.no-hardcoded-credentials',\n 'auth.session-secure',\n 'api.validation.required',\n 'api.rate-limiting',\n 'api.no-sensitive-logging',\n 'sql.no-string-concat',\n 'sql.no-raw-queries',\n 'tests.unit.required',\n 'tests.coverage.min-80',\n 'tests.no-skipped',\n 'logging.no-pii',\n 'logging.no-console',\n 'code.no-any',\n 'code.strict-mode',\n 'code.no-unused-vars',\n 'config.node-version',\n 'config.editor-config',\n ],\n },\n tools: ['eslint', 'semgrep', 'gitleaks', 'osv-scanner', 'vitest'],\n eslintExtends: [\n 'eslint:recommended',\n 'plugin:@typescript-eslint/recommended',\n 'plugin:security/recommended-legacy',\n 'next/core-web-vitals',\n ],\n semgrepRules: [\n 'p/javascript',\n 'p/typescript',\n 'p/nodejs',\n 'p/react',\n 'p/nextjs',\n 'p/jwt',\n 'p/sql-injection',\n 'p/secrets',\n ],\n};\n","import type { Preset } from '../types/index.js';\nimport type { PresetConfig } from './node-api.js';\nimport { nodeApiPreset } from './node-api.js';\nimport { nextjsAppPreset } from './nextjs-app.js';\n\nexport type { PresetConfig };\n\nexport const presets: Record<Preset, PresetConfig> = {\n 'node-api': nodeApiPreset,\n 'nextjs-app': nextjsAppPreset,\n 'python-api': nodeApiPreset, // TODO: implement\n 'cli-tool': nodeApiPreset, // TODO: implement\n library: nodeApiPreset, // TODO: implement\n monorepo: nodeApiPreset, // TODO: implement\n};\n\nexport function getPreset(name: Preset): PresetConfig {\n const preset = presets[name];\n if (!preset) {\n throw new Error(`Unknown preset: ${name}`);\n }\n return preset;\n}\n\nexport function listPresets(): Preset[] {\n return Object.keys(presets) as Preset[];\n}\n","import { cosmiconfig } from 'cosmiconfig';\nimport { z } from 'zod';\nimport { VibeGuardConfigSchema, type VibeGuardConfig } from '../types/index.js';\n\nconst explorer = cosmiconfig('vibeguard', {\n searchPlaces: [\n 'vibeguard.config.js',\n 'vibeguard.config.mjs',\n 'vibeguard.config.cjs',\n 'vibeguard.config.json',\n 'vibeguard.config.yaml',\n 'vibeguard.config.yml',\n '.vibeguardrc',\n '.vibeguardrc.json',\n '.vibeguardrc.yaml',\n '.vibeguardrc.yml',\n 'package.json',\n ],\n});\n\nexport interface LoadedConfig {\n config: VibeGuardConfig;\n filepath: string;\n isEmpty: boolean;\n}\n\nexport async function loadConfig(cwd: string = process.cwd()): Promise<LoadedConfig | null> {\n try {\n const result = await explorer.search(cwd);\n\n if (!result || result.isEmpty) {\n return null;\n }\n\n const validated = VibeGuardConfigSchema.parse(result.config);\n\n return {\n config: validated,\n filepath: result.filepath,\n isEmpty: false,\n };\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues.map((i) => ` - ${i.path.join('.')}: ${i.message}`).join('\\n');\n throw new Error(`Invalid vibeguard config:\\n${issues}`);\n }\n throw error;\n }\n}\n\nexport async function loadConfigFromFile(filepath: string): Promise<LoadedConfig> {\n const result = await explorer.load(filepath);\n\n if (!result || result.isEmpty) {\n throw new Error(`Config file is empty: ${filepath}`);\n }\n\n const validated = VibeGuardConfigSchema.parse(result.config);\n\n return {\n config: validated,\n filepath: result.filepath,\n isEmpty: false,\n };\n}\n\nexport function getDefaultConfig(): VibeGuardConfig {\n return {\n level: 'standard',\n ci: {\n failOn: 'error',\n reportFormat: 'console',\n },\n tools: {\n eslint: true,\n semgrep: true,\n gitleaks: true,\n osvScanner: true,\n },\n };\n}\n","import type {\n VibeGuardConfig,\n Level,\n RuleDefinition,\n CheckResult,\n RuleSeverity,\n RuleConfig,\n} from '../types/index.js';\nimport { rules, getRuleById } from '../rules/index.js';\nimport { getPreset } from '../presets/index.js';\n\nexport interface ResolvedRule {\n definition: RuleDefinition;\n severity: RuleSeverity;\n enabled: boolean;\n blocking: boolean;\n autofix: boolean;\n}\n\nexport function resolveRules(config: VibeGuardConfig): ResolvedRule[] {\n const level: Level = config.level ?? 'standard';\n let activeRuleIds: string[] = [];\n\n if (config.preset) {\n const preset = getPreset(config.preset);\n activeRuleIds = preset.rules[level] ?? [];\n } else {\n activeRuleIds = rules.filter((r) => r.levels[level]).map((r) => r.id);\n }\n\n const resolvedRules: ResolvedRule[] = [];\n\n for (const ruleId of activeRuleIds) {\n const definition = getRuleById(ruleId);\n if (!definition) continue;\n\n const ruleConfig = config.rules?.[ruleId];\n let enabled = true;\n let severity = definition.severity;\n let blocking = definition.blocking;\n let autofix = definition.autofix;\n\n if (typeof ruleConfig === 'boolean') {\n enabled = ruleConfig;\n } else if (ruleConfig) {\n enabled = ruleConfig.enabled ?? true;\n severity = ruleConfig.severity ?? severity;\n blocking = ruleConfig.blocking ?? blocking;\n autofix = ruleConfig.autofix ?? autofix;\n }\n\n if (enabled) {\n resolvedRules.push({\n definition,\n severity,\n enabled,\n blocking,\n autofix,\n });\n }\n }\n\n if (config.rules) {\n for (const [ruleId, ruleConfig] of Object.entries(config.rules)) {\n if (activeRuleIds.includes(ruleId)) continue;\n\n const definition = getRuleById(ruleId);\n if (!definition) continue;\n\n let enabled = true;\n if (typeof ruleConfig === 'boolean') {\n enabled = ruleConfig;\n } else {\n enabled = ruleConfig.enabled ?? true;\n }\n\n if (enabled) {\n resolvedRules.push({\n definition,\n severity:\n typeof ruleConfig === 'object' ? ruleConfig.severity ?? definition.severity : definition.severity,\n enabled,\n blocking:\n typeof ruleConfig === 'object' ? ruleConfig.blocking ?? definition.blocking : definition.blocking,\n autofix:\n typeof ruleConfig === 'object' ? ruleConfig.autofix ?? definition.autofix : definition.autofix,\n });\n }\n }\n }\n\n return resolvedRules;\n}\n\nexport function groupRulesByTool(resolvedRules: ResolvedRule[]): Map<string, ResolvedRule[]> {\n const grouped = new Map<string, ResolvedRule[]>();\n\n for (const rule of resolvedRules) {\n const tool = rule.definition.tool;\n const existing = grouped.get(tool) ?? [];\n existing.push(rule);\n grouped.set(tool, existing);\n }\n\n return grouped;\n}\n\nexport function calculateScore(results: CheckResult[]): number {\n if (results.length === 0) return 100;\n\n const weights = { error: 10, warn: 3, info: 1 };\n let totalPenalty = 0;\n\n for (const result of results) {\n totalPenalty += weights[result.severity] ?? 0;\n }\n\n const score = Math.max(0, 100 - totalPenalty);\n return Math.round(score);\n}\n\nexport function shouldFail(results: CheckResult[], failOn: RuleSeverity): boolean {\n const severityOrder: RuleSeverity[] = ['info', 'warn', 'error'];\n const failIndex = severityOrder.indexOf(failOn);\n\n return results.some((r) => severityOrder.indexOf(r.severity) >= failIndex);\n}\n","import { readFile, access, readdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Preset } from '../types/index.js';\n\nexport interface DetectedStack {\n preset: Preset;\n confidence: number;\n language: 'typescript' | 'javascript' | 'python' | 'unknown';\n framework?: string;\n packageManager?: 'npm' | 'yarn' | 'pnpm' | 'bun';\n hasTests: boolean;\n hasTypeScript: boolean;\n hasCi: boolean;\n issues: string[];\n}\n\nexport async function detectStack(cwd: string): Promise<DetectedStack> {\n const result: DetectedStack = {\n preset: 'node-api',\n confidence: 0,\n language: 'unknown',\n hasTests: false,\n hasTypeScript: false,\n hasCi: false,\n issues: [],\n };\n\n const files = await safeReadDir(cwd);\n\n // Detect package manager\n if (files.includes('package-lock.json')) {\n result.packageManager = 'npm';\n } else if (files.includes('yarn.lock')) {\n result.packageManager = 'yarn';\n } else if (files.includes('pnpm-lock.yaml')) {\n result.packageManager = 'pnpm';\n } else if (files.includes('bun.lockb')) {\n result.packageManager = 'bun';\n }\n\n // Detect TypeScript\n if (files.includes('tsconfig.json')) {\n result.hasTypeScript = true;\n result.language = 'typescript';\n }\n\n // Detect CI\n if (files.includes('.github')) {\n const githubFiles = await safeReadDir(join(cwd, '.github'));\n if (githubFiles.includes('workflows')) {\n result.hasCi = true;\n }\n }\n if (files.includes('.gitlab-ci.yml')) {\n result.hasCi = true;\n }\n\n // Detect tests\n const testIndicators = ['test', 'tests', '__tests__', 'spec', 'specs', 'vitest.config.ts', 'jest.config.js'];\n result.hasTests = testIndicators.some((t) => files.includes(t));\n\n // Detect framework from package.json\n if (files.includes('package.json')) {\n result.language = result.hasTypeScript ? 'typescript' : 'javascript';\n const pkg = await readPackageJson(cwd);\n\n if (pkg) {\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n // Next.js detection\n if (allDeps['next']) {\n result.preset = 'nextjs-app';\n result.framework = 'next.js';\n result.confidence = 95;\n }\n // Express/Fastify/Koa = node-api\n else if (allDeps['express'] || allDeps['fastify'] || allDeps['koa'] || allDeps['hono']) {\n result.preset = 'node-api';\n result.framework = allDeps['express']\n ? 'express'\n : allDeps['fastify']\n ? 'fastify'\n : allDeps['koa']\n ? 'koa'\n : 'hono';\n result.confidence = 90;\n }\n // Library detection (has main/exports, no framework)\n else if (pkg.main || pkg.exports) {\n result.preset = 'library';\n result.confidence = 70;\n }\n // Default to node-api\n else {\n result.preset = 'node-api';\n result.confidence = 50;\n }\n\n // Check for monorepo\n if (pkg.workspaces || files.includes('lerna.json') || files.includes('pnpm-workspace.yaml')) {\n result.preset = 'monorepo';\n result.confidence = 85;\n }\n }\n }\n\n // Python detection\n if (files.includes('requirements.txt') || files.includes('pyproject.toml') || files.includes('setup.py')) {\n result.language = 'python' as any;\n result.preset = 'python-api';\n result.confidence = 80;\n\n if (files.includes('pyproject.toml')) {\n const content = await safeReadFile(join(cwd, 'pyproject.toml'));\n if (content?.includes('fastapi')) {\n result.framework = 'fastapi';\n result.confidence = 95;\n } else if (content?.includes('django')) {\n result.framework = 'django';\n result.confidence = 95;\n } else if (content?.includes('flask')) {\n result.framework = 'flask';\n result.confidence = 95;\n }\n }\n }\n\n // Collect issues for \"wow moment\"\n await collectIssues(cwd, files, result);\n\n return result;\n}\n\nasync function collectIssues(cwd: string, files: string[], result: DetectedStack): Promise<void> {\n // Check for missing .gitignore\n if (!files.includes('.gitignore')) {\n result.issues.push('Missing .gitignore file');\n } else {\n const gitignore = await safeReadFile(join(cwd, '.gitignore'));\n if (gitignore && !gitignore.includes('.env')) {\n result.issues.push('.gitignore missing .env pattern');\n }\n }\n\n // Check for .env files that might be committed\n const envFiles = files.filter((f) => f.startsWith('.env') && !f.endsWith('.example'));\n if (envFiles.length > 0) {\n result.issues.push(`Potential secrets: ${envFiles.join(', ')}`);\n }\n\n // Check for lockfile\n if (result.language !== 'python' && !result.packageManager) {\n result.issues.push('No lockfile found (npm/yarn/pnpm)');\n }\n\n // Check for tests\n if (!result.hasTests) {\n result.issues.push('No test files detected');\n }\n\n // Check for TypeScript strict mode\n if (result.hasTypeScript) {\n const tsconfig = await safeReadFile(join(cwd, 'tsconfig.json'));\n if (tsconfig && !tsconfig.includes('\"strict\": true')) {\n result.issues.push('TypeScript strict mode not enabled');\n }\n }\n\n // Check for CI\n if (!result.hasCi) {\n result.issues.push('No CI/CD configuration found');\n }\n}\n\nasync function safeReadDir(path: string): Promise<string[]> {\n try {\n return await readdir(path);\n } catch {\n return [];\n }\n}\n\nasync function safeReadFile(path: string): Promise<string | null> {\n try {\n return await readFile(path, 'utf-8');\n } catch {\n return null;\n }\n}\n\nasync function readPackageJson(cwd: string): Promise<any> {\n try {\n const content = await readFile(join(cwd, 'package.json'), 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n","import { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { CheckResult } from '../types/index.js';\n\nexport interface BaselineEntry {\n ruleId: string;\n file?: string;\n line?: number;\n fingerprint: string;\n message: string;\n createdAt: string;\n}\n\nexport interface Baseline {\n version: string;\n createdAt: string;\n updatedAt: string;\n entries: BaselineEntry[];\n}\n\nconst BASELINE_VERSION = '1.0';\nconst DEFAULT_BASELINE_PATH = '.devrail/baseline.json';\n\nexport function createFingerprint(result: CheckResult): string {\n const content = [result.ruleId, result.file ?? '', result.message].join('|');\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\nexport async function loadBaseline(cwd: string, path?: string): Promise<Baseline | null> {\n const baselinePath = join(cwd, path ?? DEFAULT_BASELINE_PATH);\n\n try {\n const content = await readFile(baselinePath, 'utf-8');\n return JSON.parse(content) as Baseline;\n } catch {\n return null;\n }\n}\n\nexport async function saveBaseline(cwd: string, baseline: Baseline, path?: string): Promise<void> {\n const baselinePath = join(cwd, path ?? DEFAULT_BASELINE_PATH);\n\n await mkdir(dirname(baselinePath), { recursive: true });\n await writeFile(baselinePath, JSON.stringify(baseline, null, 2), 'utf-8');\n}\n\nexport function createBaseline(results: CheckResult[]): Baseline {\n const now = new Date().toISOString();\n\n return {\n version: BASELINE_VERSION,\n createdAt: now,\n updatedAt: now,\n entries: results.map((r) => ({\n ruleId: r.ruleId,\n file: r.file,\n line: r.line,\n fingerprint: createFingerprint(r),\n message: r.message,\n createdAt: now,\n })),\n };\n}\n\nexport function filterNewIssues(results: CheckResult[], baseline: Baseline | null): CheckResult[] {\n if (!baseline) {\n return results;\n }\n\n const baselineFingerprints = new Set(baseline.entries.map((e) => e.fingerprint));\n\n return results.filter((result) => {\n const fingerprint = createFingerprint(result);\n return !baselineFingerprints.has(fingerprint);\n });\n}\n\nexport function getBaselinedIssues(results: CheckResult[], baseline: Baseline | null): CheckResult[] {\n if (!baseline) {\n return [];\n }\n\n const baselineFingerprints = new Set(baseline.entries.map((e) => e.fingerprint));\n\n return results.filter((result) => {\n const fingerprint = createFingerprint(result);\n return baselineFingerprints.has(fingerprint);\n });\n}\n\nexport interface BaselineStats {\n total: number;\n new: number;\n baselined: number;\n fixed: number;\n}\n\nexport function getBaselineStats(\n results: CheckResult[],\n baseline: Baseline | null\n): BaselineStats {\n if (!baseline) {\n return {\n total: results.length,\n new: results.length,\n baselined: 0,\n fixed: 0,\n };\n }\n\n const currentFingerprints = new Set(results.map((r) => createFingerprint(r)));\n const baselineFingerprints = new Set(baseline.entries.map((e) => e.fingerprint));\n\n const newIssues = results.filter((r) => !baselineFingerprints.has(createFingerprint(r)));\n const baselinedIssues = results.filter((r) => baselineFingerprints.has(createFingerprint(r)));\n const fixedIssues = baseline.entries.filter((e) => !currentFingerprints.has(e.fingerprint));\n\n return {\n total: results.length,\n new: newIssues.length,\n baselined: baselinedIssues.length,\n fixed: fixedIssues.length,\n };\n}\n\nexport function updateBaseline(baseline: Baseline, results: CheckResult[]): Baseline {\n const now = new Date().toISOString();\n const currentFingerprints = new Set(results.map((r) => createFingerprint(r)));\n\n // Keep only entries that still exist\n const existingEntries = baseline.entries.filter((e) => currentFingerprints.has(e.fingerprint));\n\n // Add new entries\n const existingFingerprints = new Set(existingEntries.map((e) => e.fingerprint));\n const newEntries = results\n .filter((r) => !existingFingerprints.has(createFingerprint(r)))\n .map((r) => ({\n ruleId: r.ruleId,\n file: r.file,\n line: r.line,\n fingerprint: createFingerprint(r),\n message: r.message,\n createdAt: now,\n }));\n\n return {\n ...baseline,\n updatedAt: now,\n entries: [...existingEntries, ...newEntries],\n };\n}\n","import { execa } from 'execa';\n\nexport interface ChangedFile {\n path: string;\n status: 'added' | 'modified' | 'deleted' | 'renamed';\n}\n\nexport async function getChangedFiles(cwd: string, base?: string): Promise<ChangedFile[]> {\n try {\n // Try to get diff against base branch or HEAD\n const baseRef = base ?? await getDefaultBranch(cwd);\n const mergeBase = await getMergeBase(cwd, baseRef);\n\n const result = await execa('git', ['diff', '--name-status', mergeBase], {\n cwd,\n reject: false,\n });\n\n if (result.exitCode !== 0) {\n // Fallback to uncommitted changes\n return await getUncommittedChanges(cwd);\n }\n\n return parseGitDiff(result.stdout);\n } catch {\n // Not a git repo or git not available\n return [];\n }\n}\n\nexport async function getUncommittedChanges(cwd: string): Promise<ChangedFile[]> {\n try {\n // Get staged + unstaged changes\n const result = await execa('git', ['status', '--porcelain'], {\n cwd,\n reject: false,\n });\n\n if (result.exitCode !== 0) {\n return [];\n }\n\n return parseGitStatus(result.stdout);\n } catch {\n return [];\n }\n}\n\nexport async function getStagedFiles(cwd: string): Promise<ChangedFile[]> {\n try {\n const result = await execa('git', ['diff', '--name-status', '--cached'], {\n cwd,\n reject: false,\n });\n\n if (result.exitCode !== 0) {\n return [];\n }\n\n return parseGitDiff(result.stdout);\n } catch {\n return [];\n }\n}\n\nasync function getDefaultBranch(cwd: string): Promise<string> {\n try {\n // Try to get default branch from remote\n const result = await execa('git', ['remote', 'show', 'origin'], {\n cwd,\n reject: false,\n });\n\n const match = result.stdout.match(/HEAD branch: (.+)/);\n if (match) {\n return `origin/${match[1]}`;\n }\n } catch {\n // Ignore\n }\n\n // Fallback to common defaults\n try {\n await execa('git', ['rev-parse', '--verify', 'origin/main'], { cwd });\n return 'origin/main';\n } catch {\n try {\n await execa('git', ['rev-parse', '--verify', 'origin/master'], { cwd });\n return 'origin/master';\n } catch {\n return 'HEAD~1';\n }\n }\n}\n\nasync function getMergeBase(cwd: string, base: string): Promise<string> {\n try {\n const result = await execa('git', ['merge-base', 'HEAD', base], {\n cwd,\n reject: false,\n });\n\n if (result.exitCode === 0 && result.stdout.trim()) {\n return result.stdout.trim();\n }\n } catch {\n // Ignore\n }\n\n return base;\n}\n\nfunction parseGitDiff(output: string): ChangedFile[] {\n const files: ChangedFile[] = [];\n\n for (const line of output.split('\\n')) {\n if (!line.trim()) continue;\n\n const [status, ...pathParts] = line.split('\\t');\n const path = pathParts.join('\\t');\n\n if (!path) continue;\n\n let fileStatus: ChangedFile['status'];\n switch (status?.[0]) {\n case 'A':\n fileStatus = 'added';\n break;\n case 'M':\n fileStatus = 'modified';\n break;\n case 'D':\n fileStatus = 'deleted';\n break;\n case 'R':\n fileStatus = 'renamed';\n break;\n default:\n fileStatus = 'modified';\n }\n\n files.push({ path, status: fileStatus });\n }\n\n return files;\n}\n\nfunction parseGitStatus(output: string): ChangedFile[] {\n const files: ChangedFile[] = [];\n\n for (const line of output.split('\\n')) {\n if (!line.trim()) continue;\n\n const status = line.slice(0, 2);\n const path = line.slice(3);\n\n if (!path) continue;\n\n let fileStatus: ChangedFile['status'];\n if (status.includes('A') || status === '??') {\n fileStatus = 'added';\n } else if (status.includes('D')) {\n fileStatus = 'deleted';\n } else if (status.includes('R')) {\n fileStatus = 'renamed';\n } else {\n fileStatus = 'modified';\n }\n\n files.push({ path, status: fileStatus });\n }\n\n return files;\n}\n\nexport function filterResultsByFiles(\n results: Array<{ file?: string }>,\n changedFiles: ChangedFile[]\n): typeof results {\n const changedPaths = new Set(changedFiles.map((f) => f.path));\n\n return results.filter((r) => {\n if (!r.file) return true; // Keep results without file (general issues)\n return changedPaths.has(r.file);\n });\n}\n","import { execa, type ExecaError } from 'execa';\nimport type { CheckResult, RuleSeverity } from '../types/index.js';\n\nexport interface ToolRunner {\n name: string;\n isInstalled(): Promise<boolean>;\n getVersion(): Promise<string | null>;\n run(cwd: string, files?: string[]): Promise<CheckResult[]>;\n}\n\nexport async function checkCommand(command: string): Promise<boolean> {\n try {\n await execa('which', [command]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function runCommand(\n command: string,\n args: string[],\n cwd: string\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n try {\n const result = await execa(command, args, { cwd, reject: false });\n return {\n stdout: result.stdout as string,\n stderr: result.stderr as string,\n exitCode: result.exitCode ?? 0,\n };\n } catch (error) {\n const execaError = error as ExecaError;\n return {\n stdout: String(execaError.stdout ?? ''),\n stderr: String(execaError.stderr ?? ''),\n exitCode: typeof execaError.exitCode === 'number' ? execaError.exitCode : 1,\n };\n }\n}\n\nexport function parseSeverity(level: string): RuleSeverity {\n const normalized = level.toLowerCase();\n if (normalized === 'error' || normalized === 'high' || normalized === 'critical') {\n return 'error';\n }\n if (normalized === 'warning' || normalized === 'warn' || normalized === 'medium') {\n return 'warn';\n }\n return 'info';\n}\n","import type { ToolRunner } from './base.js';\nimport type { CheckResult } from '../types/index.js';\nimport { checkCommand, runCommand, parseSeverity } from './base.js';\n\ninterface GitleaksResult {\n Description: string;\n StartLine: number;\n EndLine: number;\n StartColumn: number;\n EndColumn: number;\n Match: string;\n Secret: string;\n File: string;\n Commit: string;\n Entropy: number;\n Author: string;\n Email: string;\n Date: string;\n Message: string;\n Tags: string[];\n RuleID: string;\n Fingerprint: string;\n}\n\nexport const gitleaksRunner: ToolRunner = {\n name: 'gitleaks',\n\n async isInstalled(): Promise<boolean> {\n return checkCommand('gitleaks');\n },\n\n async getVersion(): Promise<string | null> {\n const result = await runCommand('gitleaks', ['version'], process.cwd());\n if (result.exitCode === 0) {\n return result.stdout.trim();\n }\n return null;\n },\n\n async run(cwd: string, _files?: string[]): Promise<CheckResult[]> {\n const args = ['detect', '--source', cwd, '--report-format', 'json', '--report-path', '-', '--no-git'];\n\n const result = await runCommand('gitleaks', args, cwd);\n\n if (result.exitCode === 0) {\n return [];\n }\n\n try {\n const findings: GitleaksResult[] = JSON.parse(result.stdout || '[]');\n return findings.map((finding) => ({\n ruleId: `secrets.${finding.RuleID}`,\n severity: 'error' as const,\n message: `Secret detected: ${finding.Description}`,\n file: finding.File,\n line: finding.StartLine,\n column: finding.StartColumn,\n endLine: finding.EndLine,\n endColumn: finding.EndColumn,\n }));\n } catch {\n if (result.stdout.includes('no leaks found')) {\n return [];\n }\n return [\n {\n ruleId: 'secrets.no-plaintext',\n severity: 'error',\n message: `Gitleaks error: ${result.stderr || 'Unknown error'}`,\n },\n ];\n }\n },\n};\n","import type { ToolRunner } from './base.js';\nimport type { CheckResult } from '../types/index.js';\nimport { checkCommand, runCommand, parseSeverity } from './base.js';\n\ninterface SemgrepResult {\n results: Array<{\n check_id: string;\n path: string;\n start: { line: number; col: number };\n end: { line: number; col: number };\n extra: {\n message: string;\n severity: string;\n metadata?: {\n category?: string;\n cwe?: string[];\n owasp?: string[];\n };\n fix?: string;\n };\n }>;\n errors: Array<{\n message: string;\n level: string;\n }>;\n}\n\nexport const semgrepRunner: ToolRunner = {\n name: 'semgrep',\n\n async isInstalled(): Promise<boolean> {\n return checkCommand('semgrep');\n },\n\n async getVersion(): Promise<string | null> {\n const result = await runCommand('semgrep', ['--version'], process.cwd());\n if (result.exitCode === 0) {\n return result.stdout.trim();\n }\n return null;\n },\n\n async run(cwd: string, files?: string[]): Promise<CheckResult[]> {\n const args = [\n 'scan',\n '--json',\n '--config',\n 'auto',\n '--metrics',\n 'off',\n ];\n\n if (files && files.length > 0) {\n args.push(...files);\n } else {\n args.push(cwd);\n }\n\n const result = await runCommand('semgrep', args, cwd);\n\n try {\n const output: SemgrepResult = JSON.parse(result.stdout);\n const results: CheckResult[] = [];\n\n for (const finding of output.results) {\n results.push({\n ruleId: finding.check_id,\n severity: parseSeverity(finding.extra.severity),\n message: finding.extra.message,\n file: finding.path,\n line: finding.start.line,\n column: finding.start.col,\n endLine: finding.end.line,\n endColumn: finding.end.col,\n fix: finding.extra.fix\n ? { description: 'Apply suggested fix', replacement: finding.extra.fix }\n : undefined,\n });\n }\n\n return results;\n } catch {\n if (result.exitCode === 0) {\n return [];\n }\n return [\n {\n ruleId: 'semgrep.error',\n severity: 'error',\n message: `Semgrep error: ${result.stderr || 'Unknown error'}`,\n },\n ];\n }\n },\n};\n","import type { ToolRunner } from './base.js';\nimport type { CheckResult } from '../types/index.js';\nimport { checkCommand, runCommand, parseSeverity } from './base.js';\n\ninterface OsvResult {\n results: Array<{\n source: {\n path: string;\n type: string;\n };\n packages: Array<{\n package: {\n name: string;\n version: string;\n ecosystem: string;\n };\n vulnerabilities: Array<{\n id: string;\n summary: string;\n details: string;\n severity: Array<{\n type: string;\n score: string;\n }>;\n affected: Array<{\n ranges: Array<{\n type: string;\n events: Array<{ introduced?: string; fixed?: string }>;\n }>;\n }>;\n references: Array<{ type: string; url: string }>;\n }>;\n }>;\n }>;\n}\n\nexport const osvScannerRunner: ToolRunner = {\n name: 'osv-scanner',\n\n async isInstalled(): Promise<boolean> {\n return checkCommand('osv-scanner');\n },\n\n async getVersion(): Promise<string | null> {\n const result = await runCommand('osv-scanner', ['--version'], process.cwd());\n if (result.exitCode === 0) {\n return result.stdout.trim();\n }\n return null;\n },\n\n async run(cwd: string, _files?: string[]): Promise<CheckResult[]> {\n const args = ['--format', 'json', '--recursive', cwd];\n\n const result = await runCommand('osv-scanner', args, cwd);\n\n if (result.exitCode === 0 && !result.stdout.trim()) {\n return [];\n }\n\n try {\n const output: OsvResult = JSON.parse(result.stdout);\n const results: CheckResult[] = [];\n\n for (const source of output.results || []) {\n for (const pkg of source.packages || []) {\n for (const vuln of pkg.vulnerabilities || []) {\n const severity = vuln.severity?.[0]?.score;\n let severityLevel: 'error' | 'warn' | 'info' = 'warn';\n\n if (severity) {\n const score = parseFloat(severity);\n if (score >= 7.0) severityLevel = 'error';\n else if (score >= 4.0) severityLevel = 'warn';\n else severityLevel = 'info';\n }\n\n results.push({\n ruleId: `deps.vulnerability.${vuln.id}`,\n severity: severityLevel,\n message: `${pkg.package.name}@${pkg.package.version}: ${vuln.summary || vuln.id}`,\n file: source.source.path,\n });\n }\n }\n }\n\n return results;\n } catch {\n if (result.exitCode === 0) {\n return [];\n }\n return [\n {\n ruleId: 'deps.no-vulnerable',\n severity: 'error',\n message: `OSV Scanner error: ${result.stderr || 'Unknown error'}`,\n },\n ];\n }\n },\n};\n","import { readFile, access, readdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { CheckResult } from '../types/index.js';\n\nexport async function checkGitignore(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n const gitignorePath = join(cwd, '.gitignore');\n\n try {\n await access(gitignorePath);\n const content = await readFile(gitignorePath, 'utf-8');\n\n const requiredPatterns = ['.env', 'node_modules', '.env.local', '.env*.local'];\n const missingPatterns = requiredPatterns.filter(\n (pattern) => !content.includes(pattern)\n );\n\n if (missingPatterns.length > 0) {\n results.push({\n ruleId: 'secrets.gitignore-required',\n severity: 'warn',\n message: `.gitignore is missing patterns: ${missingPatterns.join(', ')}`,\n file: '.gitignore',\n fix: {\n description: `Add missing patterns to .gitignore`,\n replacement: missingPatterns.join('\\n'),\n },\n });\n }\n } catch {\n results.push({\n ruleId: 'secrets.gitignore-required',\n severity: 'warn',\n message: '.gitignore file not found',\n fix: {\n description: 'Create .gitignore with common patterns',\n },\n });\n }\n\n return results;\n}\n\nexport async function checkEnvFiles(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n try {\n const files = await readdir(cwd);\n const envFiles = files.filter(\n (f) => f.startsWith('.env') && !f.endsWith('.example') && !f.endsWith('.template')\n );\n\n const gitignorePath = join(cwd, '.gitignore');\n let gitignoreContent = '';\n try {\n gitignoreContent = await readFile(gitignorePath, 'utf-8');\n } catch {\n // No gitignore\n }\n\n for (const envFile of envFiles) {\n const isIgnored = gitignoreContent.includes(envFile) || gitignoreContent.includes('.env');\n if (!isIgnored) {\n results.push({\n ruleId: 'secrets.no-env-commit',\n severity: 'error',\n message: `${envFile} may be committed to git. Add it to .gitignore.`,\n file: envFile,\n fix: {\n description: `Add ${envFile} to .gitignore`,\n },\n });\n }\n }\n } catch {\n // Directory read error, skip\n }\n\n return results;\n}\n\nexport async function checkLockfile(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n const lockfiles = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb'];\n\n try {\n const files = await readdir(cwd);\n const hasLockfile = lockfiles.some((lf) => files.includes(lf));\n const hasPackageJson = files.includes('package.json');\n\n if (hasPackageJson && !hasLockfile) {\n results.push({\n ruleId: 'deps.lockfile.required',\n severity: 'error',\n message: 'No lockfile found. Run npm install, yarn, or pnpm install.',\n fix: {\n description: 'Generate lockfile by running package manager install',\n },\n });\n }\n } catch {\n // Skip\n }\n\n return results;\n}\n\nexport async function checkUnpinnedDeps(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n const packageJsonPath = join(cwd, 'package.json');\n\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n\n const checkDeps = (deps: Record<string, string> | undefined, type: string) => {\n if (!deps) return;\n for (const [name, version] of Object.entries(deps)) {\n if (version.startsWith('^') || version.startsWith('~') || version === '*' || version === 'latest') {\n results.push({\n ruleId: 'deps.no-unpinned',\n severity: 'warn',\n message: `${type} \"${name}\" has unpinned version: ${version}`,\n file: 'package.json',\n });\n }\n }\n };\n\n checkDeps(pkg.dependencies, 'Dependency');\n checkDeps(pkg.devDependencies, 'DevDependency');\n } catch {\n // Skip\n }\n\n return results;\n}\n\nexport async function checkGitDeps(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n const packageJsonPath = join(cwd, 'package.json');\n\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n\n const checkDeps = (deps: Record<string, string> | undefined) => {\n if (!deps) return;\n for (const [name, version] of Object.entries(deps)) {\n if (\n version.startsWith('git://') ||\n version.startsWith('git+') ||\n version.startsWith('github:') ||\n version.includes('github.com')\n ) {\n results.push({\n ruleId: 'deps.no-git-deps',\n severity: 'warn',\n message: `Dependency \"${name}\" uses git URL: ${version}`,\n file: 'package.json',\n });\n }\n }\n };\n\n checkDeps(pkg.dependencies);\n checkDeps(pkg.devDependencies);\n } catch {\n // Skip\n }\n\n return results;\n}\n\nexport async function checkTestsExist(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n try {\n const testPatterns = ['test', 'tests', '__tests__', 'spec', 'specs'];\n const files = await readdir(cwd);\n\n const hasTestDir = testPatterns.some((p) => files.includes(p));\n const hasTestFiles = files.some(\n (f) => f.endsWith('.test.ts') || f.endsWith('.test.js') || f.endsWith('.spec.ts') || f.endsWith('.spec.js')\n );\n\n if (!hasTestDir && !hasTestFiles) {\n results.push({\n ruleId: 'tests.unit.required',\n severity: 'warn',\n message: 'No test files or test directory found',\n });\n }\n } catch {\n // Skip\n }\n\n return results;\n}\n\nexport async function checkTsConfig(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n const tsconfigPath = join(cwd, 'tsconfig.json');\n\n try {\n const content = await readFile(tsconfigPath, 'utf-8');\n const tsconfig = JSON.parse(content);\n\n if (!tsconfig.compilerOptions?.strict) {\n results.push({\n ruleId: 'code.strict-mode',\n severity: 'warn',\n message: 'TypeScript strict mode is not enabled',\n file: 'tsconfig.json',\n fix: {\n description: 'Add \"strict\": true to compilerOptions',\n },\n });\n }\n } catch {\n // No tsconfig or parse error\n }\n\n return results;\n}\n\nexport async function checkNodeVersion(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n try {\n const files = await readdir(cwd);\n const hasNvmrc = files.includes('.nvmrc');\n const hasNodeVersion = files.includes('.node-version');\n\n let hasEngines = false;\n try {\n const pkgContent = await readFile(join(cwd, 'package.json'), 'utf-8');\n const pkg = JSON.parse(pkgContent);\n hasEngines = !!pkg.engines?.node;\n } catch {\n // No package.json\n }\n\n if (!hasNvmrc && !hasNodeVersion && !hasEngines) {\n results.push({\n ruleId: 'config.node-version',\n severity: 'info',\n message: 'Node.js version not specified (.nvmrc, .node-version, or engines.node)',\n fix: {\n description: 'Create .nvmrc or add engines.node to package.json',\n },\n });\n }\n } catch {\n // Skip\n }\n\n return results;\n}\n\nexport async function checkEditorConfig(cwd: string): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n try {\n await access(join(cwd, '.editorconfig'));\n } catch {\n results.push({\n ruleId: 'config.editor-config',\n severity: 'info',\n message: '.editorconfig not found',\n fix: {\n description: 'Create .editorconfig for consistent formatting',\n },\n });\n }\n\n return results;\n}\n\nexport async function runBuiltinChecks(cwd: string, ruleIds: string[]): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n const checks: Record<string, () => Promise<CheckResult[]>> = {\n 'secrets.gitignore-required': () => checkGitignore(cwd),\n 'secrets.no-env-commit': () => checkEnvFiles(cwd),\n 'deps.lockfile.required': () => checkLockfile(cwd),\n 'deps.no-unpinned': () => checkUnpinnedDeps(cwd),\n 'deps.no-git-deps': () => checkGitDeps(cwd),\n 'tests.unit.required': () => checkTestsExist(cwd),\n 'code.strict-mode': () => checkTsConfig(cwd),\n 'config.node-version': () => checkNodeVersion(cwd),\n 'config.editor-config': () => checkEditorConfig(cwd),\n };\n\n for (const ruleId of ruleIds) {\n const check = checks[ruleId];\n if (check) {\n const checkResults = await check();\n results.push(...checkResults);\n }\n }\n\n return results;\n}\n"],"mappings":"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","names":["z","z","readFile","join","execa","readFile","access","readdir","join"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|