@kb-labs/policy-core 2.104.0 → 2.105.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/dist/cli/commands/check.js +7 -2
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/manifest.v3.json +162 -0
- package/package.json +18 -18
|
@@ -6,8 +6,13 @@ import semver from 'semver';
|
|
|
6
6
|
|
|
7
7
|
var __defProp = Object.defineProperty;
|
|
8
8
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
9
|
-
var __esm = (fn, res) => function __init() {
|
|
10
|
-
|
|
9
|
+
var __esm = (fn, res, err) => function __init() {
|
|
10
|
+
if (err) throw err[0];
|
|
11
|
+
try {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw err = [e], e;
|
|
15
|
+
}
|
|
11
16
|
};
|
|
12
17
|
var __export = (target, all) => {
|
|
13
18
|
for (var name in all)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/category-resolver.ts","../../../src/cli/commands/check.ts","../../../src/core/workspace-scanner.ts","../../../src/checks/sdk-only-deps.ts","../../../src/checks/boundary-check.ts","../../../src/checks/symbol-extractor.ts","../../../src/checks/api-compat-check.ts","../../../src/checks/no-rollback.ts","../../../src/core/policy-runner.ts"],"names":["path","fs","detectCategory","findPackageJsonPaths","passed"],"mappings":"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","file":"check.js","sourcesContent":["import type { CategoryResult, PolicyConfig } from '@kb-labs/policy-contracts';\n\n/**\n * Checks if a repo path matches a glob-like category path pattern.\n * Supports simple wildcards: \"plugins/*\" matches \"plugins/kb-labs-mind\".\n */\nfunction matchesPattern(repoPath: string, pattern: string): boolean {\n // Normalize trailing slashes\n const normalizedPath = repoPath.replace(/\\/$/, '');\n const normalizedPattern = pattern.replace(/\\/$/, '');\n\n if (normalizedPattern === normalizedPath) {return true;}\n\n // Handle wildcard: \"plugins/*\" → matches \"plugins/anything\"\n if (normalizedPattern.endsWith('/*')) {\n const prefix = normalizedPattern.slice(0, -2); // remove /*\n const pathPrefix = normalizedPath.split('/').slice(0, prefix.split('/').length).join('/');\n return pathPrefix === prefix;\n }\n\n // Exact prefix match with single segment after\n if (normalizedPattern.includes('*')) {\n const regexStr = normalizedPattern.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '[^/]+');\n return new RegExp(`^${regexStr}$`).test(normalizedPath);\n }\n\n return false;\n}\n\n/**\n * Detects the category for a given repo path based on the policies config.\n * Returns first matching category. If no match, returns category: null.\n */\nexport function detectCategory(repoPath: string, config: PolicyConfig): CategoryResult {\n for (const [categoryName, categoryConfig] of Object.entries(config.categories)) {\n for (const pattern of categoryConfig.paths) {\n if (matchesPattern(repoPath, pattern)) {\n return {\n path: repoPath,\n category: categoryName,\n rules: categoryConfig.rules,\n };\n }\n }\n }\n\n return {\n path: repoPath,\n category: null,\n rules: ['boundary-check'], // default fallback rule\n };\n}\n\n/**\n * Detects categories for multiple repo paths.\n */\nexport function detectCategories(repoPaths: string[], config: PolicyConfig): CategoryResult[] {\n return repoPaths.map((p) => detectCategory(p, config));\n}\n","import { defineCommand, useConfig, findRepoRoot, type PluginContextV3 } from '@kb-labs/sdk';\nimport { execSync } from 'node:child_process';\nimport type { PolicyConfig, CheckReport } from '@kb-labs/policy-contracts';\nimport { detectCategory } from '../../core/category-resolver.js';\nimport { runChecks } from '../../core/policy-runner.js';\n\ntype CheckInput = {\n path?: string;\n json?: boolean;\n};\n\ntype CheckResult = {\n exitCode: number;\n report: CheckReport;\n};\n\nexport default defineCommand({\n id: 'policy:check',\n description: 'Run policy checks for changed repos or a specific path. Exits with code 1 on violations.',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CheckInput): Promise<CheckResult> {\n const flags = (input as { flags?: CheckInput }).flags ?? input;\n const workspaceRoot = (await findRepoRoot(ctx.cwd)) ?? ctx.cwd;\n const policyConfig = await useConfig<PolicyConfig>();\n\n if (!policyConfig?.categories) {\n ctx.ui.error('No policies config found in .kb/kb.config.json (expected \"policies\" key)');\n const emptyReport: CheckReport = {\n passed: false,\n repos: [],\n summary: { total: 0, passed: 0, failed: 0, violations: 0 },\n };\n if (flags.json) {ctx.ui.json?.({ passed: false, error: 'No policies config' });}\n return { exitCode: 1, report: emptyReport };\n }\n\n const repoPaths = flags.path\n ? [flags.path]\n : detectChangedRepos(workspaceRoot);\n\n const repos = repoPaths.map((p) => detectCategory(p, policyConfig));\n\n // Warn about repos with no category\n for (const r of repos) {\n if (!r.category) {\n ctx.ui.warn?.(`Repo ${r.path} has no category — applying default rules: ${r.rules.join(', ')}`);\n }\n }\n\n const report = await runChecks(repos, policyConfig, workspaceRoot);\n\n if (flags.json) {\n ctx.ui.json?.(report);\n } else {\n renderHumanReport(ctx, report);\n }\n\n return { exitCode: report.passed ? 0 : 1, report };\n },\n },\n});\n\nfunction renderHumanReport(ctx: PluginContextV3, report: CheckReport): void {\n const lines: string[] = [];\n\n for (const repo of report.repos) {\n const cat = repo.category ?? '(no category)';\n lines.push(`\\n${repo.path} (category: ${cat})`);\n\n for (const violation of repo.violations) {\n lines.push(` ❌ ${violation.rule}`);\n lines.push(` ${violation.message}`);\n if (violation.detail) {lines.push(` → ${violation.detail}`);}\n }\n for (const passed of repo.passed) {\n lines.push(` ✅ ${passed}`);\n }\n }\n\n const { total, passed, failed, violations } = report.summary;\n const summaryLine = report.passed\n ? `✅ All ${total} repo(s) passed`\n : `❌ ${violations} violation(s) found in ${failed}/${total} repo(s) — pipeline blocked`;\n\n if (report.passed) {\n ctx.ui.success?.('Policy Check', {\n sections: [\n { header: 'Results', items: lines },\n { header: 'Summary', items: [`${passed}/${total} passed`] },\n ],\n });\n } else {\n ctx.ui.error(`Policy Check Failed\\n${lines.join('\\n')}\\n\\n${summaryLine}`);\n }\n}\n\nfunction detectChangedRepos(workspaceRoot: string): string[] {\n try {\n const output = execSync('git diff --name-only HEAD 2>/dev/null || git diff --name-only', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n timeout: 10000,\n });\n\n const repoSet = new Set<string>();\n for (const file of output.trim().split('\\n').filter(Boolean)) {\n const parts = file.split('/');\n if (parts.length >= 2) {\n const topDir = parts[0]!;\n const repoDir = parts[1]!;\n if (['platform', 'plugins', 'infra', 'templates', 'installer', 'sites'].includes(topDir)) {\n repoSet.add(`${topDir}/${repoDir}`);\n }\n }\n }\n return Array.from(repoSet);\n } catch {\n return [];\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig } from '@kb-labs/policy-contracts';\nimport { detectCategory } from './category-resolver.js';\n\ninterface PackageInfo {\n name: string;\n repoPath: string;\n category: string | null;\n packageJsonPath: string;\n}\n\n/**\n * Scans all packages in the workspace and returns a map of packageName → category.\n * Also returns full PackageInfo for more detailed lookups.\n */\nexport function buildPackageMap(\n workspaceRoot: string,\n config: PolicyConfig,\n): Map<string, string | null> {\n const packages = scanAllPackages(workspaceRoot, config);\n const map = new Map<string, string | null>();\n for (const pkg of packages) {\n map.set(pkg.name, pkg.category);\n }\n return map;\n}\n\n/**\n * Returns all packages in a specific repo (by repo path relative to workspaceRoot).\n */\nexport function getRepoPackageNames(workspaceRoot: string, repoPath: string): string[] {\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const names: string[] = [];\n\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {continue;}\n try {\n const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n if (json.name) {names.push(json.name);}\n } catch {\n // ignore invalid package.json\n }\n }\n }\n\n return names;\n}\n\nfunction scanAllPackages(workspaceRoot: string, config: PolicyConfig): PackageInfo[] {\n const results: PackageInfo[] = [];\n const topLevelDirs = ['platform', 'plugins', 'infra', 'templates', 'installer', 'sites'];\n\n for (const topDir of topLevelDirs) {\n const topDirPath = path.join(workspaceRoot, topDir);\n if (!fs.existsSync(topDirPath)) {continue;}\n\n for (const repoEntry of fs.readdirSync(topDirPath)) {\n const repoPath = path.join(topDirPath, repoEntry);\n const repoRelPath = `${topDir}/${repoEntry}`;\n\n // FIX 4 (MEDIUM): statSync can throw on broken symlinks, permission errors,\n // or race conditions where an entry disappears between readdirSync and statSync.\n // Skip the entry rather than letting the error propagate and abort the scan.\n let isDir: boolean;\n try {\n isDir = fs.statSync(repoPath).isDirectory();\n } catch {\n continue;\n }\n if (!isDir) {continue;}\n\n const categoryResult = detectCategory(repoRelPath, config);\n\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(repoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n\n for (const pkgEntry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, pkgEntry, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {continue;}\n\n try {\n const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n if (json.name) {\n results.push({\n name: json.name,\n repoPath: repoRelPath,\n category: categoryResult.category,\n packageJsonPath: pkgJsonPath,\n });\n }\n } catch {\n // ignore\n }\n }\n }\n }\n }\n\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport { getRepoPackageNames } from '../core/workspace-scanner.js';\n\n/**\n * Checks that all packages in the repo only depend on @kb-labs/sdk\n * and their own internal packages (within the same repo).\n */\nexport async function checkSdkOnlyDeps(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const internalPackageNames = new Set(getRepoPackageNames(workspaceRoot, repoPath));\n\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; dependencies?: Record<string, string> };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n const deps = Object.keys(json.dependencies ?? {});\n const packageName = json.name ?? path.basename(path.dirname(pkgJsonPath));\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n for (const dep of deps) {\n if (!dep.startsWith('@kb-labs/')) {continue;}\n if (dep === '@kb-labs/sdk') {continue;}\n if (internalPackageNames.has(dep)) {continue;}\n\n violations.push({\n rule: 'sdk-only-deps',\n severity: 'error',\n message: `${packageName} imports ${dep} directly`,\n package: packageName,\n detail: `Plugins must depend only on @kb-labs/sdk. Move needed types to SDK or use SDK re-exports.`,\n file: relPath,\n });\n }\n }\n\n return violations;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport { buildPackageMap, getRepoPackageNames } from '../core/workspace-scanner.js';\nimport { checkSdkOnlyDeps } from './sdk-only-deps.js';\n\n/**\n * Checks that packages only depend on packages from allowed categories.\n * If allowed contains \"sdk-only\", delegates to sdk-only-deps logic.\n */\nexport async function checkBoundary(\n repoPath: string,\n config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n\n // Find the category for this repo\n const { detectCategory } = await import('../core/category-resolver.js');\n const categoryResult = detectCategory(repoPath, config);\n const category = categoryResult.category;\n\n if (!category) {return violations;} // no category = no boundary config\n\n const boundaryRuleConfig = config.rules['boundary-check']?.config as\n | { allowed?: Record<string, string[]> }\n | undefined;\n const allowedCategories = boundaryRuleConfig?.allowed?.[category] ?? [];\n\n // If \"sdk-only\" is in allowed, delegate to sdk-only-deps\n if (allowedCategories.includes('sdk-only')) {\n return checkSdkOnlyDeps(repoPath, config, workspaceRoot);\n }\n\n const packageMap = buildPackageMap(workspaceRoot, config);\n const internalPackageNames = new Set(getRepoPackageNames(workspaceRoot, repoPath));\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n\n for (const pkgJsonPath of findPackageJsonPaths(absRepoPath)) {\n let json: { name?: string; dependencies?: Record<string, string> };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n const deps = Object.keys(json.dependencies ?? {});\n const packageName = json.name ?? path.basename(path.dirname(pkgJsonPath));\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n for (const dep of deps) {\n if (!dep.startsWith('@kb-labs/')) {continue;}\n if (internalPackageNames.has(dep)) {continue;} // own package = always ok\n\n const depCategory = packageMap.get(dep);\n if (depCategory === undefined || depCategory === null) {continue;} // unknown package, skip\n\n if (!allowedCategories.includes(depCategory)) {\n violations.push({\n rule: 'boundary-check',\n severity: 'error',\n message: `${packageName} depends on ${dep} (category: ${depCategory ?? 'unknown'})`,\n package: packageName,\n detail: `Category \"${category}\" may only depend on: ${allowedCategories.join(', ')}`,\n file: relPath,\n });\n }\n }\n }\n\n return violations;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","export interface SymbolExtractor {\n extract(dtsContent: string): Set<string>;\n}\n\n/**\n * Regex-based symbol extractor for .d.ts files.\n * Handles common export patterns. Interface allows future replacement with TS Compiler API.\n */\nexport class RegexSymbolExtractor implements SymbolExtractor {\n extract(dtsContent: string): Set<string> {\n const symbols = new Set<string>();\n\n // export function foo / export async function foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:async\\s+)?function\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export class Foo / export abstract class Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:abstract\\s+)?class\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export type Foo / export interface Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:type\\s+|interface\\s+)(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export const foo / export let foo / export var foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:const|let|var)\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export enum Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:const\\s+)?enum\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export { foo, bar as baz }\n for (const m of dtsContent.matchAll(/^export\\s+\\{([^}]+)\\}/gm)) {\n const entries = m[1]!.split(',').map((s) => s.trim());\n for (const entry of entries) {\n // Handle \"foo as bar\" — the exported name is \"bar\"\n const asMatch = entry.match(/\\w+\\s+as\\s+(\\w+)/);\n if (asMatch) {\n symbols.add(asMatch[1]!);\n } else {\n const nameMatch = entry.match(/^(\\w+)/);\n if (nameMatch) {symbols.add(nameMatch[1]!);}\n }\n }\n }\n\n // export default\n if (/^export\\s+default\\s+/m.test(dtsContent)) {\n symbols.add('default');\n }\n\n return symbols;\n }\n}\n\nexport const defaultSymbolExtractor: SymbolExtractor = new RegexSymbolExtractor();\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation, ApiSnapshot } from '@kb-labs/policy-contracts';\nimport { defaultSymbolExtractor } from './symbol-extractor.js';\n\nconst SNAPSHOTS_DIR = '.kb/api-snapshots';\n\n/**\n * Checks API backward compatibility by comparing exported symbols against a stored snapshot.\n * Also handles \"no-breaking-without-major\" rule (both rules map to this check).\n *\n * First run (no snapshot): warns and skips — does NOT auto-create a snapshot.\n * Use updateSnapshots() to create/refresh snapshots explicitly.\n */\nexport async function checkApiCompat(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n if (!json.name || !json.version) {continue;}\n\n const pkgName = json.name;\n const currentVersion = json.version;\n const snapshotPath = getSnapshotPath(workspaceRoot, pkgName);\n\n // Gather current exported symbols from dist/*.d.ts\n const pkgDir = path.dirname(pkgJsonPath);\n const currentSymbols = extractSymbolsFromDist(pkgDir);\n\n if (!fs.existsSync(snapshotPath)) {\n // FIX 2 (CRITICAL): removed the auto-saveSnapshot() call that was here.\n // checkApiCompat is a read-only check function; writing files as a side-effect\n // inside it violated the read/write separation and caused unexpected mutations\n // during dry-run / CI read-only policy checks.\n // Snapshots must be created explicitly via updateSnapshots().\n console.warn(\n `[policy] api-compat: No snapshot for ${pkgName} — run 'policy update-snapshots' to create one.`,\n );\n continue;\n }\n\n // Load snapshot and compare\n let snapshot: ApiSnapshot;\n try {\n snapshot = JSON.parse(fs.readFileSync(snapshotPath, 'utf-8'));\n } catch {\n console.warn(`[policy] api-compat: Could not read snapshot for ${pkgName}, skipping.`);\n continue;\n }\n\n const snapshotSymbols = new Set(snapshot.symbols);\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n const removed: string[] = [];\n for (const sym of snapshotSymbols) {\n if (!currentSymbols.has(sym)) {removed.push(sym);}\n }\n\n if (removed.length > 0) {\n // Check if major version bumped\n const currentMajor = parseMajor(currentVersion);\n const snapshotMajor = parseMajor(snapshot.version);\n\n if (currentMajor <= snapshotMajor) {\n violations.push({\n rule: 'api-compat-check',\n severity: 'error',\n message: `${pkgName} removed exported symbols without major version bump`,\n package: pkgName,\n detail: `Removed: ${removed.join(', ')}. Bump major version (current: ${currentVersion}, snapshot: ${snapshot.version}) or restore symbols.`,\n file: relPath,\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Creates or updates the API snapshot for all packages in a repo.\n */\nexport function updateSnapshots(repoPath: string, workspaceRoot: string): void {\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n if (!json.name || !json.version) {continue;}\n\n const pkgDir = path.dirname(pkgJsonPath);\n const symbols = extractSymbolsFromDist(pkgDir);\n const snapshotPath = getSnapshotPath(workspaceRoot, json.name);\n saveSnapshot(snapshotPath, json.name, json.version, symbols);\n console.log(`[policy] Saved snapshot for ${json.name} @ ${json.version} (${symbols.size} symbols)`);\n }\n}\n\nfunction extractSymbolsFromDist(pkgDir: string): Set<string> {\n const distDir = path.join(pkgDir, 'dist');\n const symbols = new Set<string>();\n\n if (!fs.existsSync(distDir)) {return symbols;}\n\n const dtsFiles = findDtsFiles(distDir);\n for (const dtsFile of dtsFiles) {\n const content = fs.readFileSync(dtsFile, 'utf-8');\n for (const sym of defaultSymbolExtractor.extract(content)) {\n symbols.add(sym);\n }\n }\n\n return symbols;\n}\n\nfunction findDtsFiles(dir: string): string[] {\n const results: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...findDtsFiles(fullPath));\n } else if (entry.name.endsWith('.d.ts')) {\n results.push(fullPath);\n }\n }\n return results;\n}\n\nfunction getSnapshotPath(workspaceRoot: string, packageName: string): string {\n const safeName = packageName.replace(/\\//g, '__').replace(/@/g, '');\n const snapshotsDir = path.join(workspaceRoot, SNAPSHOTS_DIR);\n if (!fs.existsSync(snapshotsDir)) {\n fs.mkdirSync(snapshotsDir, { recursive: true });\n }\n return path.join(snapshotsDir, `${safeName}.json`);\n}\n\nfunction saveSnapshot(snapshotPath: string, packageName: string, version: string, symbols: Set<string>): void {\n const snapshot: ApiSnapshot = {\n packageName,\n version,\n symbols: Array.from(symbols).sort(),\n extractedAt: new Date().toISOString(),\n };\n // FIX 5 (MEDIUM): guarded writeFileSync — a permission error or a full disk must\n // not crash the entire update run; log a warning and continue instead.\n try {\n fs.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2));\n } catch (err) {\n console.warn(`[policy] api-compat: Failed to write snapshot to ${snapshotPath}: ${(err as Error).message}`);\n }\n}\n\nfunction parseMajor(version: string): number {\n return parseInt(version.split('.')[0] ?? '0', 10);\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n// FIX 1 (CRITICAL): replaced execSync with spawnSync so packageName is passed as\n// a literal argument — never interpolated into a shell command string.\n// execSync with a template literal was vulnerable to shell injection if packageName\n// contained shell metacharacters (e.g. `$(cmd)`, backticks, semicolons).\nimport { spawnSync } from 'node:child_process';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport semver from 'semver';\n\n/**\n * Checks that the current version in package.json is not less than the published npm version.\n */\nexport async function checkNoRollback(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string; private?: boolean };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n if (!json.name || !json.version) {continue;}\n if (json.private) {continue;} // private packages are not published\n\n const packageName = json.name;\n const currentVersion = json.version;\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n const publishedVersion = getPublishedVersion(packageName);\n if (publishedVersion === null) {\n // Not published or npm unavailable — skip\n continue;\n }\n\n if (!semver.gte(currentVersion, publishedVersion)) {\n violations.push({\n rule: 'no-rollback',\n severity: 'error',\n message: `${packageName} version ${currentVersion} is less than published ${publishedVersion}`,\n package: packageName,\n detail: `Cannot decrease version once published to npm. Restore to ${publishedVersion} or higher.`,\n file: relPath,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Returns the published npm version for a package, or null if not published / offline.\n */\nfunction getPublishedVersion(packageName: string): string | null {\n // spawnSync receives packageName as a discrete argv element — the OS never\n // passes it through a shell, so metacharacters cannot be interpreted.\n const result = spawnSync('npm', ['show', packageName, 'version', '--silent'], {\n timeout: 10000,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n if (result.error || result.status !== 0) {return null;}\n return semver.valid(result.stdout.trim()) ?? null;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import type { CategoryResult, CheckReport, PolicyConfig, RepoCheckResult } from '@kb-labs/policy-contracts';\nimport { checkSdkOnlyDeps } from '../checks/sdk-only-deps.js';\nimport { checkBoundary } from '../checks/boundary-check.js';\nimport { checkApiCompat } from '../checks/api-compat-check.js';\nimport { checkNoRollback } from '../checks/no-rollback.js';\n\ntype CheckFn = (repoPath: string, config: PolicyConfig, workspaceRoot: string) => Promise<import('@kb-labs/policy-contracts').PolicyViolation[]>;\n\nconst RULE_CHECKS: Record<string, CheckFn> = {\n 'sdk-only-deps': checkSdkOnlyDeps,\n 'boundary-check': checkBoundary,\n 'no-breaking-without-major': checkApiCompat,\n 'no-rollback': checkNoRollback,\n 'api-compat-check': checkApiCompat,\n};\n\nexport async function runChecks(\n repos: CategoryResult[],\n config: PolicyConfig,\n workspaceRoot: string,\n): Promise<CheckReport> {\n const repoResults: RepoCheckResult[] = [];\n\n for (const repo of repos) {\n const violations = [];\n const passed: string[] = [];\n const rulesToRun = repo.rules;\n\n for (const rule of rulesToRun) {\n const checkFn = RULE_CHECKS[rule];\n if (!checkFn) {\n // Unknown rule — skip with warning\n console.warn(`[policy] Unknown rule: ${rule} (skipping)`);\n continue;\n }\n\n // FIX 3 (CRITICAL): wrap each rule execution individually so that an\n // unexpected throw from one check does not abort the remaining rules or\n // prevent the report from being built for this (and subsequent) repos.\n let ruleViolations: import('@kb-labs/policy-contracts').PolicyViolation[];\n try {\n ruleViolations = await checkFn(repo.path, config, workspaceRoot);\n } catch (err) {\n console.warn(`[policy] Rule '${rule}' threw an unexpected error (skipping): ${(err as Error).message}`);\n continue;\n }\n\n if (ruleViolations.length === 0) {\n passed.push(rule);\n } else {\n violations.push(...ruleViolations.map((v) => ({ ...v, rule })));\n }\n }\n\n repoResults.push({\n path: repo.path,\n category: repo.category,\n violations,\n passed,\n });\n }\n\n const totalViolations = repoResults.reduce((sum, r) => sum + r.violations.length, 0);\n const failedRepos = repoResults.filter((r) => r.violations.length > 0).length;\n\n return {\n passed: totalViolations === 0,\n repos: repoResults,\n summary: {\n total: repos.length,\n passed: repos.length - failedRepos,\n failed: failedRepos,\n violations: totalViolations,\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/category-resolver.ts","../../../src/cli/commands/check.ts","../../../src/core/workspace-scanner.ts","../../../src/checks/sdk-only-deps.ts","../../../src/checks/boundary-check.ts","../../../src/checks/symbol-extractor.ts","../../../src/checks/api-compat-check.ts","../../../src/checks/no-rollback.ts","../../../src/core/policy-runner.ts"],"names":["path","fs","detectCategory","findPackageJsonPaths","passed"],"mappings":"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","file":"check.js","sourcesContent":["import type { CategoryResult, PolicyConfig } from '@kb-labs/policy-contracts';\n\n/**\n * Checks if a repo path matches a glob-like category path pattern.\n * Supports simple wildcards: \"plugins/*\" matches \"plugins/kb-labs-mind\".\n */\nfunction matchesPattern(repoPath: string, pattern: string): boolean {\n // Normalize trailing slashes\n const normalizedPath = repoPath.replace(/\\/$/, '');\n const normalizedPattern = pattern.replace(/\\/$/, '');\n\n if (normalizedPattern === normalizedPath) {return true;}\n\n // Handle wildcard: \"plugins/*\" → matches \"plugins/anything\"\n if (normalizedPattern.endsWith('/*')) {\n const prefix = normalizedPattern.slice(0, -2); // remove /*\n const pathPrefix = normalizedPath.split('/').slice(0, prefix.split('/').length).join('/');\n return pathPrefix === prefix;\n }\n\n // Exact prefix match with single segment after\n if (normalizedPattern.includes('*')) {\n const regexStr = normalizedPattern.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '[^/]+');\n return new RegExp(`^${regexStr}$`).test(normalizedPath);\n }\n\n return false;\n}\n\n/**\n * Detects the category for a given repo path based on the policies config.\n * Returns first matching category. If no match, returns category: null.\n */\nexport function detectCategory(repoPath: string, config: PolicyConfig): CategoryResult {\n for (const [categoryName, categoryConfig] of Object.entries(config.categories)) {\n for (const pattern of categoryConfig.paths) {\n if (matchesPattern(repoPath, pattern)) {\n return {\n path: repoPath,\n category: categoryName,\n rules: categoryConfig.rules,\n };\n }\n }\n }\n\n return {\n path: repoPath,\n category: null,\n rules: ['boundary-check'], // default fallback rule\n };\n}\n\n/**\n * Detects categories for multiple repo paths.\n */\nexport function detectCategories(repoPaths: string[], config: PolicyConfig): CategoryResult[] {\n return repoPaths.map((p) => detectCategory(p, config));\n}\n","import { defineCommand, useConfig, findRepoRoot, type PluginContextV3 } from '@kb-labs/sdk';\nimport { execSync } from 'node:child_process';\nimport type { PolicyConfig, CheckReport } from '@kb-labs/policy-contracts';\nimport { detectCategory } from '../../core/category-resolver.js';\nimport { runChecks } from '../../core/policy-runner.js';\n\ntype CheckInput = {\n path?: string;\n json?: boolean;\n};\n\ntype CheckResult = {\n exitCode: number;\n report: CheckReport;\n};\n\nexport default defineCommand({\n id: 'policy:check',\n description: 'Run policy checks for changed repos or a specific path. Exits with code 1 on violations.',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CheckInput): Promise<CheckResult> {\n const flags = (input as { flags?: CheckInput }).flags ?? input;\n const workspaceRoot = (await findRepoRoot(ctx.cwd)) ?? ctx.cwd;\n const policyConfig = await useConfig<PolicyConfig>();\n\n if (!policyConfig?.categories) {\n ctx.ui.error('No policies config found in .kb/kb.config.json (expected \"policies\" key)');\n const emptyReport: CheckReport = {\n passed: false,\n repos: [],\n summary: { total: 0, passed: 0, failed: 0, violations: 0 },\n };\n if (flags.json) {ctx.ui.json?.({ passed: false, error: 'No policies config' });}\n return { exitCode: 1, report: emptyReport };\n }\n\n const repoPaths = flags.path\n ? [flags.path]\n : detectChangedRepos(workspaceRoot);\n\n const repos = repoPaths.map((p) => detectCategory(p, policyConfig));\n\n // Warn about repos with no category\n for (const r of repos) {\n if (!r.category) {\n ctx.ui.warn?.(`Repo ${r.path} has no category — applying default rules: ${r.rules.join(', ')}`);\n }\n }\n\n const report = await runChecks(repos, policyConfig, workspaceRoot);\n\n if (flags.json) {\n ctx.ui.json?.(report);\n } else {\n renderHumanReport(ctx, report);\n }\n\n return { exitCode: report.passed ? 0 : 1, report };\n },\n },\n});\n\nfunction renderHumanReport(ctx: PluginContextV3, report: CheckReport): void {\n const lines: string[] = [];\n\n for (const repo of report.repos) {\n const cat = repo.category ?? '(no category)';\n lines.push(`\\n${repo.path} (category: ${cat})`);\n\n for (const violation of repo.violations) {\n lines.push(` ❌ ${violation.rule}`);\n lines.push(` ${violation.message}`);\n if (violation.detail) {lines.push(` → ${violation.detail}`);}\n }\n for (const passed of repo.passed) {\n lines.push(` ✅ ${passed}`);\n }\n }\n\n const { total, passed, failed, violations } = report.summary;\n const summaryLine = report.passed\n ? `✅ All ${total} repo(s) passed`\n : `❌ ${violations} violation(s) found in ${failed}/${total} repo(s) — pipeline blocked`;\n\n if (report.passed) {\n ctx.ui.success?.('Policy Check', {\n sections: [\n { header: 'Results', items: lines },\n { header: 'Summary', items: [`${passed}/${total} passed`] },\n ],\n });\n } else {\n ctx.ui.error(`Policy Check Failed\\n${lines.join('\\n')}\\n\\n${summaryLine}`);\n }\n}\n\nfunction detectChangedRepos(workspaceRoot: string): string[] {\n try {\n const output = execSync('git diff --name-only HEAD 2>/dev/null || git diff --name-only', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n timeout: 10000,\n });\n\n const repoSet = new Set<string>();\n for (const file of output.trim().split('\\n').filter(Boolean)) {\n const parts = file.split('/');\n if (parts.length >= 2) {\n const topDir = parts[0]!;\n const repoDir = parts[1]!;\n if (['platform', 'plugins', 'infra', 'templates', 'installer', 'sites'].includes(topDir)) {\n repoSet.add(`${topDir}/${repoDir}`);\n }\n }\n }\n return Array.from(repoSet);\n } catch {\n return [];\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig } from '@kb-labs/policy-contracts';\nimport { detectCategory } from './category-resolver.js';\n\ninterface PackageInfo {\n name: string;\n repoPath: string;\n category: string | null;\n packageJsonPath: string;\n}\n\n/**\n * Scans all packages in the workspace and returns a map of packageName → category.\n * Also returns full PackageInfo for more detailed lookups.\n */\nexport function buildPackageMap(\n workspaceRoot: string,\n config: PolicyConfig,\n): Map<string, string | null> {\n const packages = scanAllPackages(workspaceRoot, config);\n const map = new Map<string, string | null>();\n for (const pkg of packages) {\n map.set(pkg.name, pkg.category);\n }\n return map;\n}\n\n/**\n * Returns all packages in a specific repo (by repo path relative to workspaceRoot).\n */\nexport function getRepoPackageNames(workspaceRoot: string, repoPath: string): string[] {\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const names: string[] = [];\n\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {continue;}\n try {\n const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n if (json.name) {names.push(json.name);}\n } catch {\n // ignore invalid package.json\n }\n }\n }\n\n return names;\n}\n\nfunction scanAllPackages(workspaceRoot: string, config: PolicyConfig): PackageInfo[] {\n const results: PackageInfo[] = [];\n const topLevelDirs = ['platform', 'plugins', 'infra', 'templates', 'installer', 'sites'];\n\n for (const topDir of topLevelDirs) {\n const topDirPath = path.join(workspaceRoot, topDir);\n if (!fs.existsSync(topDirPath)) {continue;}\n\n for (const repoEntry of fs.readdirSync(topDirPath)) {\n const repoPath = path.join(topDirPath, repoEntry);\n const repoRelPath = `${topDir}/${repoEntry}`;\n\n // FIX 4 (MEDIUM): statSync can throw on broken symlinks, permission errors,\n // or race conditions where an entry disappears between readdirSync and statSync.\n // Skip the entry rather than letting the error propagate and abort the scan.\n let isDir: boolean;\n try {\n isDir = fs.statSync(repoPath).isDirectory();\n } catch {\n continue;\n }\n if (!isDir) {continue;}\n\n const categoryResult = detectCategory(repoRelPath, config);\n\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(repoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n\n for (const pkgEntry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, pkgEntry, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {continue;}\n\n try {\n const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n if (json.name) {\n results.push({\n name: json.name,\n repoPath: repoRelPath,\n category: categoryResult.category,\n packageJsonPath: pkgJsonPath,\n });\n }\n } catch {\n // ignore\n }\n }\n }\n }\n }\n\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport { getRepoPackageNames } from '../core/workspace-scanner.js';\n\n/**\n * Checks that all packages in the repo only depend on @kb-labs/sdk\n * and their own internal packages (within the same repo).\n */\nexport async function checkSdkOnlyDeps(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const internalPackageNames = new Set(getRepoPackageNames(workspaceRoot, repoPath));\n\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; dependencies?: Record<string, string> };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n const deps = Object.keys(json.dependencies ?? {});\n const packageName = json.name ?? path.basename(path.dirname(pkgJsonPath));\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n for (const dep of deps) {\n if (!dep.startsWith('@kb-labs/')) {continue;}\n if (dep === '@kb-labs/sdk') {continue;}\n if (internalPackageNames.has(dep)) {continue;}\n\n violations.push({\n rule: 'sdk-only-deps',\n severity: 'error',\n message: `${packageName} imports ${dep} directly`,\n package: packageName,\n detail: `Plugins must depend only on @kb-labs/sdk. Move needed types to SDK or use SDK re-exports.`,\n file: relPath,\n });\n }\n }\n\n return violations;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport { buildPackageMap, getRepoPackageNames } from '../core/workspace-scanner.js';\nimport { checkSdkOnlyDeps } from './sdk-only-deps.js';\n\n/**\n * Checks that packages only depend on packages from allowed categories.\n * If allowed contains \"sdk-only\", delegates to sdk-only-deps logic.\n */\nexport async function checkBoundary(\n repoPath: string,\n config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n\n // Find the category for this repo\n const { detectCategory } = await import('../core/category-resolver.js');\n const categoryResult = detectCategory(repoPath, config);\n const category = categoryResult.category;\n\n if (!category) {return violations;} // no category = no boundary config\n\n const boundaryRuleConfig = config.rules['boundary-check']?.config as\n | { allowed?: Record<string, string[]> }\n | undefined;\n const allowedCategories = boundaryRuleConfig?.allowed?.[category] ?? [];\n\n // If \"sdk-only\" is in allowed, delegate to sdk-only-deps\n if (allowedCategories.includes('sdk-only')) {\n return checkSdkOnlyDeps(repoPath, config, workspaceRoot);\n }\n\n const packageMap = buildPackageMap(workspaceRoot, config);\n const internalPackageNames = new Set(getRepoPackageNames(workspaceRoot, repoPath));\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n\n for (const pkgJsonPath of findPackageJsonPaths(absRepoPath)) {\n let json: { name?: string; dependencies?: Record<string, string> };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n const deps = Object.keys(json.dependencies ?? {});\n const packageName = json.name ?? path.basename(path.dirname(pkgJsonPath));\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n for (const dep of deps) {\n if (!dep.startsWith('@kb-labs/')) {continue;}\n if (internalPackageNames.has(dep)) {continue;} // own package = always ok\n\n const depCategory = packageMap.get(dep);\n if (depCategory === undefined || depCategory === null) {continue;} // unknown package, skip\n\n if (!allowedCategories.includes(depCategory)) {\n violations.push({\n rule: 'boundary-check',\n severity: 'error',\n message: `${packageName} depends on ${dep} (category: ${depCategory ?? 'unknown'})`,\n package: packageName,\n detail: `Category \"${category}\" may only depend on: ${allowedCategories.join(', ')}`,\n file: relPath,\n });\n }\n }\n }\n\n return violations;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","export interface SymbolExtractor {\n extract(dtsContent: string): Set<string>;\n}\n\n/**\n * Regex-based symbol extractor for .d.ts files.\n * Handles common export patterns. Interface allows future replacement with TS Compiler API.\n */\nexport class RegexSymbolExtractor implements SymbolExtractor {\n extract(dtsContent: string): Set<string> {\n const symbols = new Set<string>();\n\n // export function foo / export async function foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:async\\s+)?function\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export class Foo / export abstract class Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:abstract\\s+)?class\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export type Foo / export interface Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:type\\s+|interface\\s+)(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export const foo / export let foo / export var foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:const|let|var)\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export enum Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:const\\s+)?enum\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export { foo, bar as baz }\n for (const m of dtsContent.matchAll(/^export\\s+\\{([^}]+)\\}/gm)) {\n const entries = m[1]!.split(',').map((s) => s.trim());\n for (const entry of entries) {\n // Handle \"foo as bar\" — the exported name is \"bar\"\n const asMatch = entry.match(/\\w+\\s+as\\s+(\\w+)/);\n if (asMatch) {\n symbols.add(asMatch[1]!);\n } else {\n const nameMatch = entry.match(/^(\\w+)/);\n if (nameMatch) {symbols.add(nameMatch[1]!);}\n }\n }\n }\n\n // export default\n if (/^export\\s+default\\s+/m.test(dtsContent)) {\n symbols.add('default');\n }\n\n return symbols;\n }\n}\n\nexport const defaultSymbolExtractor: SymbolExtractor = new RegexSymbolExtractor();\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation, ApiSnapshot } from '@kb-labs/policy-contracts';\nimport { defaultSymbolExtractor } from './symbol-extractor.js';\n\nconst SNAPSHOTS_DIR = '.kb/api-snapshots';\n\n/**\n * Checks API backward compatibility by comparing exported symbols against a stored snapshot.\n * Also handles \"no-breaking-without-major\" rule (both rules map to this check).\n *\n * First run (no snapshot): warns and skips — does NOT auto-create a snapshot.\n * Use updateSnapshots() to create/refresh snapshots explicitly.\n */\nexport async function checkApiCompat(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n if (!json.name || !json.version) {continue;}\n\n const pkgName = json.name;\n const currentVersion = json.version;\n const snapshotPath = getSnapshotPath(workspaceRoot, pkgName);\n\n // Gather current exported symbols from dist/*.d.ts\n const pkgDir = path.dirname(pkgJsonPath);\n const currentSymbols = extractSymbolsFromDist(pkgDir);\n\n if (!fs.existsSync(snapshotPath)) {\n // FIX 2 (CRITICAL): removed the auto-saveSnapshot() call that was here.\n // checkApiCompat is a read-only check function; writing files as a side-effect\n // inside it violated the read/write separation and caused unexpected mutations\n // during dry-run / CI read-only policy checks.\n // Snapshots must be created explicitly via updateSnapshots().\n console.warn(\n `[policy] api-compat: No snapshot for ${pkgName} — run 'policy update-snapshots' to create one.`,\n );\n continue;\n }\n\n // Load snapshot and compare\n let snapshot: ApiSnapshot;\n try {\n snapshot = JSON.parse(fs.readFileSync(snapshotPath, 'utf-8'));\n } catch {\n console.warn(`[policy] api-compat: Could not read snapshot for ${pkgName}, skipping.`);\n continue;\n }\n\n const snapshotSymbols = new Set(snapshot.symbols);\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n const removed: string[] = [];\n for (const sym of snapshotSymbols) {\n if (!currentSymbols.has(sym)) {removed.push(sym);}\n }\n\n if (removed.length > 0) {\n // Check if major version bumped\n const currentMajor = parseMajor(currentVersion);\n const snapshotMajor = parseMajor(snapshot.version);\n\n if (currentMajor <= snapshotMajor) {\n violations.push({\n rule: 'api-compat-check',\n severity: 'error',\n message: `${pkgName} removed exported symbols without major version bump`,\n package: pkgName,\n detail: `Removed: ${removed.join(', ')}. Bump major version (current: ${currentVersion}, snapshot: ${snapshot.version}) or restore symbols.`,\n file: relPath,\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Creates or updates the API snapshot for all packages in a repo.\n */\nexport function updateSnapshots(repoPath: string, workspaceRoot: string): void {\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n if (!json.name || !json.version) {continue;}\n\n const pkgDir = path.dirname(pkgJsonPath);\n const symbols = extractSymbolsFromDist(pkgDir);\n const snapshotPath = getSnapshotPath(workspaceRoot, json.name);\n saveSnapshot(snapshotPath, json.name, json.version, symbols);\n console.log(`[policy] Saved snapshot for ${json.name} @ ${json.version} (${symbols.size} symbols)`);\n }\n}\n\nfunction extractSymbolsFromDist(pkgDir: string): Set<string> {\n const distDir = path.join(pkgDir, 'dist');\n const symbols = new Set<string>();\n\n if (!fs.existsSync(distDir)) {return symbols;}\n\n const dtsFiles = findDtsFiles(distDir);\n for (const dtsFile of dtsFiles) {\n const content = fs.readFileSync(dtsFile, 'utf-8');\n for (const sym of defaultSymbolExtractor.extract(content)) {\n symbols.add(sym);\n }\n }\n\n return symbols;\n}\n\nfunction findDtsFiles(dir: string): string[] {\n const results: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...findDtsFiles(fullPath));\n } else if (entry.name.endsWith('.d.ts')) {\n results.push(fullPath);\n }\n }\n return results;\n}\n\nfunction getSnapshotPath(workspaceRoot: string, packageName: string): string {\n const safeName = packageName.replace(/\\//g, '__').replace(/@/g, '');\n const snapshotsDir = path.join(workspaceRoot, SNAPSHOTS_DIR);\n if (!fs.existsSync(snapshotsDir)) {\n fs.mkdirSync(snapshotsDir, { recursive: true });\n }\n return path.join(snapshotsDir, `${safeName}.json`);\n}\n\nfunction saveSnapshot(snapshotPath: string, packageName: string, version: string, symbols: Set<string>): void {\n const snapshot: ApiSnapshot = {\n packageName,\n version,\n symbols: Array.from(symbols).sort(),\n extractedAt: new Date().toISOString(),\n };\n // FIX 5 (MEDIUM): guarded writeFileSync — a permission error or a full disk must\n // not crash the entire update run; log a warning and continue instead.\n try {\n fs.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2));\n } catch (err) {\n console.warn(`[policy] api-compat: Failed to write snapshot to ${snapshotPath}: ${(err as Error).message}`);\n }\n}\n\nfunction parseMajor(version: string): number {\n return parseInt(version.split('.')[0] ?? '0', 10);\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n// FIX 1 (CRITICAL): replaced execSync with spawnSync so packageName is passed as\n// a literal argument — never interpolated into a shell command string.\n// execSync with a template literal was vulnerable to shell injection if packageName\n// contained shell metacharacters (e.g. `$(cmd)`, backticks, semicolons).\nimport { spawnSync } from 'node:child_process';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport semver from 'semver';\n\n/**\n * Checks that the current version in package.json is not less than the published npm version.\n */\nexport async function checkNoRollback(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string; private?: boolean };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n if (!json.name || !json.version) {continue;}\n if (json.private) {continue;} // private packages are not published\n\n const packageName = json.name;\n const currentVersion = json.version;\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n const publishedVersion = getPublishedVersion(packageName);\n if (publishedVersion === null) {\n // Not published or npm unavailable — skip\n continue;\n }\n\n if (!semver.gte(currentVersion, publishedVersion)) {\n violations.push({\n rule: 'no-rollback',\n severity: 'error',\n message: `${packageName} version ${currentVersion} is less than published ${publishedVersion}`,\n package: packageName,\n detail: `Cannot decrease version once published to npm. Restore to ${publishedVersion} or higher.`,\n file: relPath,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Returns the published npm version for a package, or null if not published / offline.\n */\nfunction getPublishedVersion(packageName: string): string | null {\n // spawnSync receives packageName as a discrete argv element — the OS never\n // passes it through a shell, so metacharacters cannot be interpreted.\n const result = spawnSync('npm', ['show', packageName, 'version', '--silent'], {\n timeout: 10000,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n if (result.error || result.status !== 0) {return null;}\n return semver.valid(result.stdout.trim()) ?? null;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import type { CategoryResult, CheckReport, PolicyConfig, RepoCheckResult } from '@kb-labs/policy-contracts';\nimport { checkSdkOnlyDeps } from '../checks/sdk-only-deps.js';\nimport { checkBoundary } from '../checks/boundary-check.js';\nimport { checkApiCompat } from '../checks/api-compat-check.js';\nimport { checkNoRollback } from '../checks/no-rollback.js';\n\ntype CheckFn = (repoPath: string, config: PolicyConfig, workspaceRoot: string) => Promise<import('@kb-labs/policy-contracts').PolicyViolation[]>;\n\nconst RULE_CHECKS: Record<string, CheckFn> = {\n 'sdk-only-deps': checkSdkOnlyDeps,\n 'boundary-check': checkBoundary,\n 'no-breaking-without-major': checkApiCompat,\n 'no-rollback': checkNoRollback,\n 'api-compat-check': checkApiCompat,\n};\n\nexport async function runChecks(\n repos: CategoryResult[],\n config: PolicyConfig,\n workspaceRoot: string,\n): Promise<CheckReport> {\n const repoResults: RepoCheckResult[] = [];\n\n for (const repo of repos) {\n const violations = [];\n const passed: string[] = [];\n const rulesToRun = repo.rules;\n\n for (const rule of rulesToRun) {\n const checkFn = RULE_CHECKS[rule];\n if (!checkFn) {\n // Unknown rule — skip with warning\n console.warn(`[policy] Unknown rule: ${rule} (skipping)`);\n continue;\n }\n\n // FIX 3 (CRITICAL): wrap each rule execution individually so that an\n // unexpected throw from one check does not abort the remaining rules or\n // prevent the report from being built for this (and subsequent) repos.\n let ruleViolations: import('@kb-labs/policy-contracts').PolicyViolation[];\n try {\n ruleViolations = await checkFn(repo.path, config, workspaceRoot);\n } catch (err) {\n console.warn(`[policy] Rule '${rule}' threw an unexpected error (skipping): ${(err as Error).message}`);\n continue;\n }\n\n if (ruleViolations.length === 0) {\n passed.push(rule);\n } else {\n violations.push(...ruleViolations.map((v) => ({ ...v, rule })));\n }\n }\n\n repoResults.push({\n path: repo.path,\n category: repo.category,\n violations,\n passed,\n });\n }\n\n const totalViolations = repoResults.reduce((sum, r) => sum + r.violations.length, 0);\n const failedRepos = repoResults.filter((r) => r.violations.length > 0).length;\n\n return {\n passed: totalViolations === 0,\n repos: repoResults,\n summary: {\n total: repos.length,\n passed: repos.length - failedRepos,\n failed: failedRepos,\n violations: totalViolations,\n },\n };\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,13 @@ import { combinePermissions, defineCommandFlags } from '@kb-labs/sdk';
|
|
|
6
6
|
|
|
7
7
|
var __defProp = Object.defineProperty;
|
|
8
8
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
9
|
-
var __esm = (fn, res) => function __init() {
|
|
10
|
-
|
|
9
|
+
var __esm = (fn, res, err) => function __init() {
|
|
10
|
+
if (err) throw err[0];
|
|
11
|
+
try {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw err = [e], e;
|
|
15
|
+
}
|
|
11
16
|
};
|
|
12
17
|
var __export = (target, all) => {
|
|
13
18
|
for (var name in all)
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/category-resolver.ts","../src/core/index.ts","../src/core/workspace-scanner.ts","../src/checks/sdk-only-deps.ts","../src/checks/boundary-check.ts","../src/checks/symbol-extractor.ts","../src/checks/api-compat-check.ts","../src/checks/no-rollback.ts","../src/core/policy-runner.ts","../src/manifest.v3.ts"],"names":["path","fs","detectCategory","findPackageJsonPaths"],"mappings":"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","file":"index.js","sourcesContent":["import type { CategoryResult, PolicyConfig } from '@kb-labs/policy-contracts';\n\n/**\n * Checks if a repo path matches a glob-like category path pattern.\n * Supports simple wildcards: \"plugins/*\" matches \"plugins/kb-labs-mind\".\n */\nfunction matchesPattern(repoPath: string, pattern: string): boolean {\n // Normalize trailing slashes\n const normalizedPath = repoPath.replace(/\\/$/, '');\n const normalizedPattern = pattern.replace(/\\/$/, '');\n\n if (normalizedPattern === normalizedPath) {return true;}\n\n // Handle wildcard: \"plugins/*\" → matches \"plugins/anything\"\n if (normalizedPattern.endsWith('/*')) {\n const prefix = normalizedPattern.slice(0, -2); // remove /*\n const pathPrefix = normalizedPath.split('/').slice(0, prefix.split('/').length).join('/');\n return pathPrefix === prefix;\n }\n\n // Exact prefix match with single segment after\n if (normalizedPattern.includes('*')) {\n const regexStr = normalizedPattern.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '[^/]+');\n return new RegExp(`^${regexStr}$`).test(normalizedPath);\n }\n\n return false;\n}\n\n/**\n * Detects the category for a given repo path based on the policies config.\n * Returns first matching category. If no match, returns category: null.\n */\nexport function detectCategory(repoPath: string, config: PolicyConfig): CategoryResult {\n for (const [categoryName, categoryConfig] of Object.entries(config.categories)) {\n for (const pattern of categoryConfig.paths) {\n if (matchesPattern(repoPath, pattern)) {\n return {\n path: repoPath,\n category: categoryName,\n rules: categoryConfig.rules,\n };\n }\n }\n }\n\n return {\n path: repoPath,\n category: null,\n rules: ['boundary-check'], // default fallback rule\n };\n}\n\n/**\n * Detects categories for multiple repo paths.\n */\nexport function detectCategories(repoPaths: string[], config: PolicyConfig): CategoryResult[] {\n return repoPaths.map((p) => detectCategory(p, config));\n}\n","export { detectCategory, detectCategories } from './category-resolver.js';\nexport { buildPackageMap, getRepoPackageNames } from './workspace-scanner.js';\nexport { runChecks } from './policy-runner.js';\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig } from '@kb-labs/policy-contracts';\nimport { detectCategory } from './category-resolver.js';\n\ninterface PackageInfo {\n name: string;\n repoPath: string;\n category: string | null;\n packageJsonPath: string;\n}\n\n/**\n * Scans all packages in the workspace and returns a map of packageName → category.\n * Also returns full PackageInfo for more detailed lookups.\n */\nexport function buildPackageMap(\n workspaceRoot: string,\n config: PolicyConfig,\n): Map<string, string | null> {\n const packages = scanAllPackages(workspaceRoot, config);\n const map = new Map<string, string | null>();\n for (const pkg of packages) {\n map.set(pkg.name, pkg.category);\n }\n return map;\n}\n\n/**\n * Returns all packages in a specific repo (by repo path relative to workspaceRoot).\n */\nexport function getRepoPackageNames(workspaceRoot: string, repoPath: string): string[] {\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const names: string[] = [];\n\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {continue;}\n try {\n const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n if (json.name) {names.push(json.name);}\n } catch {\n // ignore invalid package.json\n }\n }\n }\n\n return names;\n}\n\nfunction scanAllPackages(workspaceRoot: string, config: PolicyConfig): PackageInfo[] {\n const results: PackageInfo[] = [];\n const topLevelDirs = ['platform', 'plugins', 'infra', 'templates', 'installer', 'sites'];\n\n for (const topDir of topLevelDirs) {\n const topDirPath = path.join(workspaceRoot, topDir);\n if (!fs.existsSync(topDirPath)) {continue;}\n\n for (const repoEntry of fs.readdirSync(topDirPath)) {\n const repoPath = path.join(topDirPath, repoEntry);\n const repoRelPath = `${topDir}/${repoEntry}`;\n\n // FIX 4 (MEDIUM): statSync can throw on broken symlinks, permission errors,\n // or race conditions where an entry disappears between readdirSync and statSync.\n // Skip the entry rather than letting the error propagate and abort the scan.\n let isDir: boolean;\n try {\n isDir = fs.statSync(repoPath).isDirectory();\n } catch {\n continue;\n }\n if (!isDir) {continue;}\n\n const categoryResult = detectCategory(repoRelPath, config);\n\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(repoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n\n for (const pkgEntry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, pkgEntry, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {continue;}\n\n try {\n const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n if (json.name) {\n results.push({\n name: json.name,\n repoPath: repoRelPath,\n category: categoryResult.category,\n packageJsonPath: pkgJsonPath,\n });\n }\n } catch {\n // ignore\n }\n }\n }\n }\n }\n\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport { getRepoPackageNames } from '../core/workspace-scanner.js';\n\n/**\n * Checks that all packages in the repo only depend on @kb-labs/sdk\n * and their own internal packages (within the same repo).\n */\nexport async function checkSdkOnlyDeps(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const internalPackageNames = new Set(getRepoPackageNames(workspaceRoot, repoPath));\n\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; dependencies?: Record<string, string> };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n const deps = Object.keys(json.dependencies ?? {});\n const packageName = json.name ?? path.basename(path.dirname(pkgJsonPath));\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n for (const dep of deps) {\n if (!dep.startsWith('@kb-labs/')) {continue;}\n if (dep === '@kb-labs/sdk') {continue;}\n if (internalPackageNames.has(dep)) {continue;}\n\n violations.push({\n rule: 'sdk-only-deps',\n severity: 'error',\n message: `${packageName} imports ${dep} directly`,\n package: packageName,\n detail: `Plugins must depend only on @kb-labs/sdk. Move needed types to SDK or use SDK re-exports.`,\n file: relPath,\n });\n }\n }\n\n return violations;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport { buildPackageMap, getRepoPackageNames } from '../core/workspace-scanner.js';\nimport { checkSdkOnlyDeps } from './sdk-only-deps.js';\n\n/**\n * Checks that packages only depend on packages from allowed categories.\n * If allowed contains \"sdk-only\", delegates to sdk-only-deps logic.\n */\nexport async function checkBoundary(\n repoPath: string,\n config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n\n // Find the category for this repo\n const { detectCategory } = await import('../core/category-resolver.js');\n const categoryResult = detectCategory(repoPath, config);\n const category = categoryResult.category;\n\n if (!category) {return violations;} // no category = no boundary config\n\n const boundaryRuleConfig = config.rules['boundary-check']?.config as\n | { allowed?: Record<string, string[]> }\n | undefined;\n const allowedCategories = boundaryRuleConfig?.allowed?.[category] ?? [];\n\n // If \"sdk-only\" is in allowed, delegate to sdk-only-deps\n if (allowedCategories.includes('sdk-only')) {\n return checkSdkOnlyDeps(repoPath, config, workspaceRoot);\n }\n\n const packageMap = buildPackageMap(workspaceRoot, config);\n const internalPackageNames = new Set(getRepoPackageNames(workspaceRoot, repoPath));\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n\n for (const pkgJsonPath of findPackageJsonPaths(absRepoPath)) {\n let json: { name?: string; dependencies?: Record<string, string> };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n const deps = Object.keys(json.dependencies ?? {});\n const packageName = json.name ?? path.basename(path.dirname(pkgJsonPath));\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n for (const dep of deps) {\n if (!dep.startsWith('@kb-labs/')) {continue;}\n if (internalPackageNames.has(dep)) {continue;} // own package = always ok\n\n const depCategory = packageMap.get(dep);\n if (depCategory === undefined || depCategory === null) {continue;} // unknown package, skip\n\n if (!allowedCategories.includes(depCategory)) {\n violations.push({\n rule: 'boundary-check',\n severity: 'error',\n message: `${packageName} depends on ${dep} (category: ${depCategory ?? 'unknown'})`,\n package: packageName,\n detail: `Category \"${category}\" may only depend on: ${allowedCategories.join(', ')}`,\n file: relPath,\n });\n }\n }\n }\n\n return violations;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","export interface SymbolExtractor {\n extract(dtsContent: string): Set<string>;\n}\n\n/**\n * Regex-based symbol extractor for .d.ts files.\n * Handles common export patterns. Interface allows future replacement with TS Compiler API.\n */\nexport class RegexSymbolExtractor implements SymbolExtractor {\n extract(dtsContent: string): Set<string> {\n const symbols = new Set<string>();\n\n // export function foo / export async function foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:async\\s+)?function\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export class Foo / export abstract class Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:abstract\\s+)?class\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export type Foo / export interface Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:type\\s+|interface\\s+)(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export const foo / export let foo / export var foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:const|let|var)\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export enum Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:const\\s+)?enum\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export { foo, bar as baz }\n for (const m of dtsContent.matchAll(/^export\\s+\\{([^}]+)\\}/gm)) {\n const entries = m[1]!.split(',').map((s) => s.trim());\n for (const entry of entries) {\n // Handle \"foo as bar\" — the exported name is \"bar\"\n const asMatch = entry.match(/\\w+\\s+as\\s+(\\w+)/);\n if (asMatch) {\n symbols.add(asMatch[1]!);\n } else {\n const nameMatch = entry.match(/^(\\w+)/);\n if (nameMatch) {symbols.add(nameMatch[1]!);}\n }\n }\n }\n\n // export default\n if (/^export\\s+default\\s+/m.test(dtsContent)) {\n symbols.add('default');\n }\n\n return symbols;\n }\n}\n\nexport const defaultSymbolExtractor: SymbolExtractor = new RegexSymbolExtractor();\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation, ApiSnapshot } from '@kb-labs/policy-contracts';\nimport { defaultSymbolExtractor } from './symbol-extractor.js';\n\nconst SNAPSHOTS_DIR = '.kb/api-snapshots';\n\n/**\n * Checks API backward compatibility by comparing exported symbols against a stored snapshot.\n * Also handles \"no-breaking-without-major\" rule (both rules map to this check).\n *\n * First run (no snapshot): warns and skips — does NOT auto-create a snapshot.\n * Use updateSnapshots() to create/refresh snapshots explicitly.\n */\nexport async function checkApiCompat(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n if (!json.name || !json.version) {continue;}\n\n const pkgName = json.name;\n const currentVersion = json.version;\n const snapshotPath = getSnapshotPath(workspaceRoot, pkgName);\n\n // Gather current exported symbols from dist/*.d.ts\n const pkgDir = path.dirname(pkgJsonPath);\n const currentSymbols = extractSymbolsFromDist(pkgDir);\n\n if (!fs.existsSync(snapshotPath)) {\n // FIX 2 (CRITICAL): removed the auto-saveSnapshot() call that was here.\n // checkApiCompat is a read-only check function; writing files as a side-effect\n // inside it violated the read/write separation and caused unexpected mutations\n // during dry-run / CI read-only policy checks.\n // Snapshots must be created explicitly via updateSnapshots().\n console.warn(\n `[policy] api-compat: No snapshot for ${pkgName} — run 'policy update-snapshots' to create one.`,\n );\n continue;\n }\n\n // Load snapshot and compare\n let snapshot: ApiSnapshot;\n try {\n snapshot = JSON.parse(fs.readFileSync(snapshotPath, 'utf-8'));\n } catch {\n console.warn(`[policy] api-compat: Could not read snapshot for ${pkgName}, skipping.`);\n continue;\n }\n\n const snapshotSymbols = new Set(snapshot.symbols);\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n const removed: string[] = [];\n for (const sym of snapshotSymbols) {\n if (!currentSymbols.has(sym)) {removed.push(sym);}\n }\n\n if (removed.length > 0) {\n // Check if major version bumped\n const currentMajor = parseMajor(currentVersion);\n const snapshotMajor = parseMajor(snapshot.version);\n\n if (currentMajor <= snapshotMajor) {\n violations.push({\n rule: 'api-compat-check',\n severity: 'error',\n message: `${pkgName} removed exported symbols without major version bump`,\n package: pkgName,\n detail: `Removed: ${removed.join(', ')}. Bump major version (current: ${currentVersion}, snapshot: ${snapshot.version}) or restore symbols.`,\n file: relPath,\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Creates or updates the API snapshot for all packages in a repo.\n */\nexport function updateSnapshots(repoPath: string, workspaceRoot: string): void {\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n if (!json.name || !json.version) {continue;}\n\n const pkgDir = path.dirname(pkgJsonPath);\n const symbols = extractSymbolsFromDist(pkgDir);\n const snapshotPath = getSnapshotPath(workspaceRoot, json.name);\n saveSnapshot(snapshotPath, json.name, json.version, symbols);\n console.log(`[policy] Saved snapshot for ${json.name} @ ${json.version} (${symbols.size} symbols)`);\n }\n}\n\nfunction extractSymbolsFromDist(pkgDir: string): Set<string> {\n const distDir = path.join(pkgDir, 'dist');\n const symbols = new Set<string>();\n\n if (!fs.existsSync(distDir)) {return symbols;}\n\n const dtsFiles = findDtsFiles(distDir);\n for (const dtsFile of dtsFiles) {\n const content = fs.readFileSync(dtsFile, 'utf-8');\n for (const sym of defaultSymbolExtractor.extract(content)) {\n symbols.add(sym);\n }\n }\n\n return symbols;\n}\n\nfunction findDtsFiles(dir: string): string[] {\n const results: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...findDtsFiles(fullPath));\n } else if (entry.name.endsWith('.d.ts')) {\n results.push(fullPath);\n }\n }\n return results;\n}\n\nfunction getSnapshotPath(workspaceRoot: string, packageName: string): string {\n const safeName = packageName.replace(/\\//g, '__').replace(/@/g, '');\n const snapshotsDir = path.join(workspaceRoot, SNAPSHOTS_DIR);\n if (!fs.existsSync(snapshotsDir)) {\n fs.mkdirSync(snapshotsDir, { recursive: true });\n }\n return path.join(snapshotsDir, `${safeName}.json`);\n}\n\nfunction saveSnapshot(snapshotPath: string, packageName: string, version: string, symbols: Set<string>): void {\n const snapshot: ApiSnapshot = {\n packageName,\n version,\n symbols: Array.from(symbols).sort(),\n extractedAt: new Date().toISOString(),\n };\n // FIX 5 (MEDIUM): guarded writeFileSync — a permission error or a full disk must\n // not crash the entire update run; log a warning and continue instead.\n try {\n fs.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2));\n } catch (err) {\n console.warn(`[policy] api-compat: Failed to write snapshot to ${snapshotPath}: ${(err as Error).message}`);\n }\n}\n\nfunction parseMajor(version: string): number {\n return parseInt(version.split('.')[0] ?? '0', 10);\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n// FIX 1 (CRITICAL): replaced execSync with spawnSync so packageName is passed as\n// a literal argument — never interpolated into a shell command string.\n// execSync with a template literal was vulnerable to shell injection if packageName\n// contained shell metacharacters (e.g. `$(cmd)`, backticks, semicolons).\nimport { spawnSync } from 'node:child_process';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport semver from 'semver';\n\n/**\n * Checks that the current version in package.json is not less than the published npm version.\n */\nexport async function checkNoRollback(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string; private?: boolean };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n if (!json.name || !json.version) {continue;}\n if (json.private) {continue;} // private packages are not published\n\n const packageName = json.name;\n const currentVersion = json.version;\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n const publishedVersion = getPublishedVersion(packageName);\n if (publishedVersion === null) {\n // Not published or npm unavailable — skip\n continue;\n }\n\n if (!semver.gte(currentVersion, publishedVersion)) {\n violations.push({\n rule: 'no-rollback',\n severity: 'error',\n message: `${packageName} version ${currentVersion} is less than published ${publishedVersion}`,\n package: packageName,\n detail: `Cannot decrease version once published to npm. Restore to ${publishedVersion} or higher.`,\n file: relPath,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Returns the published npm version for a package, or null if not published / offline.\n */\nfunction getPublishedVersion(packageName: string): string | null {\n // spawnSync receives packageName as a discrete argv element — the OS never\n // passes it through a shell, so metacharacters cannot be interpreted.\n const result = spawnSync('npm', ['show', packageName, 'version', '--silent'], {\n timeout: 10000,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n if (result.error || result.status !== 0) {return null;}\n return semver.valid(result.stdout.trim()) ?? null;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import type { CategoryResult, CheckReport, PolicyConfig, RepoCheckResult } from '@kb-labs/policy-contracts';\nimport { checkSdkOnlyDeps } from '../checks/sdk-only-deps.js';\nimport { checkBoundary } from '../checks/boundary-check.js';\nimport { checkApiCompat } from '../checks/api-compat-check.js';\nimport { checkNoRollback } from '../checks/no-rollback.js';\n\ntype CheckFn = (repoPath: string, config: PolicyConfig, workspaceRoot: string) => Promise<import('@kb-labs/policy-contracts').PolicyViolation[]>;\n\nconst RULE_CHECKS: Record<string, CheckFn> = {\n 'sdk-only-deps': checkSdkOnlyDeps,\n 'boundary-check': checkBoundary,\n 'no-breaking-without-major': checkApiCompat,\n 'no-rollback': checkNoRollback,\n 'api-compat-check': checkApiCompat,\n};\n\nexport async function runChecks(\n repos: CategoryResult[],\n config: PolicyConfig,\n workspaceRoot: string,\n): Promise<CheckReport> {\n const repoResults: RepoCheckResult[] = [];\n\n for (const repo of repos) {\n const violations = [];\n const passed: string[] = [];\n const rulesToRun = repo.rules;\n\n for (const rule of rulesToRun) {\n const checkFn = RULE_CHECKS[rule];\n if (!checkFn) {\n // Unknown rule — skip with warning\n console.warn(`[policy] Unknown rule: ${rule} (skipping)`);\n continue;\n }\n\n // FIX 3 (CRITICAL): wrap each rule execution individually so that an\n // unexpected throw from one check does not abort the remaining rules or\n // prevent the report from being built for this (and subsequent) repos.\n let ruleViolations: import('@kb-labs/policy-contracts').PolicyViolation[];\n try {\n ruleViolations = await checkFn(repo.path, config, workspaceRoot);\n } catch (err) {\n console.warn(`[policy] Rule '${rule}' threw an unexpected error (skipping): ${(err as Error).message}`);\n continue;\n }\n\n if (ruleViolations.length === 0) {\n passed.push(rule);\n } else {\n violations.push(...ruleViolations.map((v) => ({ ...v, rule })));\n }\n }\n\n repoResults.push({\n path: repo.path,\n category: repo.category,\n violations,\n passed,\n });\n }\n\n const totalViolations = repoResults.reduce((sum, r) => sum + r.violations.length, 0);\n const failedRepos = repoResults.filter((r) => r.violations.length > 0).length;\n\n return {\n passed: totalViolations === 0,\n repos: repoResults,\n summary: {\n total: repos.length,\n passed: repos.length - failedRepos,\n failed: failedRepos,\n violations: totalViolations,\n },\n };\n}\n","import { defineCommandFlags, combinePermissions } from '@kb-labs/sdk';\n\nconst pluginPermissions = combinePermissions()\n .withFs({\n mode: 'read',\n allow: ['.', '.kb/api-snapshots/**'],\n })\n .withQuotas({\n timeoutMs: 60000,\n memoryMb: 256,\n })\n .build();\n\nconst detectPermissions = combinePermissions()\n .withFs({ mode: 'read', allow: ['.'] })\n .withQuotas({ timeoutMs: 15000, memoryMb: 128 })\n .build();\n\nconst checkPermissions = combinePermissions()\n .withFs({\n mode: 'read',\n allow: ['.', '.kb/api-snapshots/**'],\n })\n .withFs({\n mode: 'readWrite',\n allow: ['.kb/api-snapshots/**'],\n })\n .withQuotas({ timeoutMs: 60000, memoryMb: 256 })\n .build();\n\nconst snapshotPermissions = combinePermissions()\n .withFs({ mode: 'read', allow: ['.'] })\n .withFs({ mode: 'readWrite', allow: ['.kb/api-snapshots/**'] })\n .withQuotas({ timeoutMs: 30000, memoryMb: 128 })\n .build();\n\nexport const manifest = {\n schema: 'kb.plugin/3',\n id: '@kb-labs/policy',\n version: '0.1.0',\n\n configSection: 'policy',\n\n display: {\n name: 'Policy Enforcer',\n description: 'Enforce workspace development policies',\n tags: ['policy', 'governance', 'boundaries', 'sdk-only', 'api-compat'],\n },\n\n cli: {\n groupMeta: [\n { path: 'policy', describe: 'Policy enforcement commands' },\n ],\n commands: [\n {\n path: 'policy detect',\n describe: 'Detect policy category for changed or specified repos',\n operationType: 'analyze' as const,\n longDescription:\n 'Determines the category for repos based on git changes or a specified path, then resolves applicable policy rules.',\n\n handler: './cli/commands/detect.js#default',\n\n flags: defineCommandFlags({\n path: {\n type: 'string',\n description: 'Repo path to check (relative to workspace root). Defaults to git diff.',\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n }),\n\n permissions: detectPermissions,\n },\n {\n path: 'policy check',\n describe: 'Run policy checks for changed repos or a specific path',\n operationType: 'analyze' as const,\n longDescription:\n 'Runs all applicable policy rules for detected repos. Exits with code 1 on violations. Use in CI or pnpm done pipeline.',\n\n handler: './cli/commands/check.js#default',\n\n flags: defineCommandFlags({\n path: {\n type: 'string',\n description: 'Repo path to check (relative to workspace root). Defaults to git diff.',\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n }),\n\n permissions: checkPermissions,\n },\n {\n path: 'policy rules',\n describe: 'Show all configured policy rules and their categories',\n operationType: 'read' as const,\n\n handler: './cli/commands/rules.js#default',\n\n flags: defineCommandFlags({\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n }),\n\n permissions: detectPermissions,\n },\n {\n path: 'policy snapshot',\n describe: 'Create or update API snapshot for a repo (run after npm publish)',\n operationType: 'mutate' as const,\n longDescription:\n 'Extracts exported symbols from dist/*.d.ts files and saves them to .kb/api-snapshots/. Used by api-compat-check to detect breaking changes.',\n\n handler: './cli/commands/snapshot.js#default',\n\n flags: defineCommandFlags({\n path: {\n type: 'string',\n description: 'Repo path (relative to workspace root)',\n required: true,\n },\n }),\n\n permissions: snapshotPermissions,\n },\n ],\n },\n\n permissions: pluginPermissions,\n};\n\nexport default manifest;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/category-resolver.ts","../src/core/index.ts","../src/core/workspace-scanner.ts","../src/checks/sdk-only-deps.ts","../src/checks/boundary-check.ts","../src/checks/symbol-extractor.ts","../src/checks/api-compat-check.ts","../src/checks/no-rollback.ts","../src/core/policy-runner.ts","../src/manifest.v3.ts"],"names":["path","fs","detectCategory","findPackageJsonPaths"],"mappings":"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","file":"index.js","sourcesContent":["import type { CategoryResult, PolicyConfig } from '@kb-labs/policy-contracts';\n\n/**\n * Checks if a repo path matches a glob-like category path pattern.\n * Supports simple wildcards: \"plugins/*\" matches \"plugins/kb-labs-mind\".\n */\nfunction matchesPattern(repoPath: string, pattern: string): boolean {\n // Normalize trailing slashes\n const normalizedPath = repoPath.replace(/\\/$/, '');\n const normalizedPattern = pattern.replace(/\\/$/, '');\n\n if (normalizedPattern === normalizedPath) {return true;}\n\n // Handle wildcard: \"plugins/*\" → matches \"plugins/anything\"\n if (normalizedPattern.endsWith('/*')) {\n const prefix = normalizedPattern.slice(0, -2); // remove /*\n const pathPrefix = normalizedPath.split('/').slice(0, prefix.split('/').length).join('/');\n return pathPrefix === prefix;\n }\n\n // Exact prefix match with single segment after\n if (normalizedPattern.includes('*')) {\n const regexStr = normalizedPattern.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '[^/]+');\n return new RegExp(`^${regexStr}$`).test(normalizedPath);\n }\n\n return false;\n}\n\n/**\n * Detects the category for a given repo path based on the policies config.\n * Returns first matching category. If no match, returns category: null.\n */\nexport function detectCategory(repoPath: string, config: PolicyConfig): CategoryResult {\n for (const [categoryName, categoryConfig] of Object.entries(config.categories)) {\n for (const pattern of categoryConfig.paths) {\n if (matchesPattern(repoPath, pattern)) {\n return {\n path: repoPath,\n category: categoryName,\n rules: categoryConfig.rules,\n };\n }\n }\n }\n\n return {\n path: repoPath,\n category: null,\n rules: ['boundary-check'], // default fallback rule\n };\n}\n\n/**\n * Detects categories for multiple repo paths.\n */\nexport function detectCategories(repoPaths: string[], config: PolicyConfig): CategoryResult[] {\n return repoPaths.map((p) => detectCategory(p, config));\n}\n","export { detectCategory, detectCategories } from './category-resolver.js';\nexport { buildPackageMap, getRepoPackageNames } from './workspace-scanner.js';\nexport { runChecks } from './policy-runner.js';\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig } from '@kb-labs/policy-contracts';\nimport { detectCategory } from './category-resolver.js';\n\ninterface PackageInfo {\n name: string;\n repoPath: string;\n category: string | null;\n packageJsonPath: string;\n}\n\n/**\n * Scans all packages in the workspace and returns a map of packageName → category.\n * Also returns full PackageInfo for more detailed lookups.\n */\nexport function buildPackageMap(\n workspaceRoot: string,\n config: PolicyConfig,\n): Map<string, string | null> {\n const packages = scanAllPackages(workspaceRoot, config);\n const map = new Map<string, string | null>();\n for (const pkg of packages) {\n map.set(pkg.name, pkg.category);\n }\n return map;\n}\n\n/**\n * Returns all packages in a specific repo (by repo path relative to workspaceRoot).\n */\nexport function getRepoPackageNames(workspaceRoot: string, repoPath: string): string[] {\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const names: string[] = [];\n\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {continue;}\n try {\n const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n if (json.name) {names.push(json.name);}\n } catch {\n // ignore invalid package.json\n }\n }\n }\n\n return names;\n}\n\nfunction scanAllPackages(workspaceRoot: string, config: PolicyConfig): PackageInfo[] {\n const results: PackageInfo[] = [];\n const topLevelDirs = ['platform', 'plugins', 'infra', 'templates', 'installer', 'sites'];\n\n for (const topDir of topLevelDirs) {\n const topDirPath = path.join(workspaceRoot, topDir);\n if (!fs.existsSync(topDirPath)) {continue;}\n\n for (const repoEntry of fs.readdirSync(topDirPath)) {\n const repoPath = path.join(topDirPath, repoEntry);\n const repoRelPath = `${topDir}/${repoEntry}`;\n\n // FIX 4 (MEDIUM): statSync can throw on broken symlinks, permission errors,\n // or race conditions where an entry disappears between readdirSync and statSync.\n // Skip the entry rather than letting the error propagate and abort the scan.\n let isDir: boolean;\n try {\n isDir = fs.statSync(repoPath).isDirectory();\n } catch {\n continue;\n }\n if (!isDir) {continue;}\n\n const categoryResult = detectCategory(repoRelPath, config);\n\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(repoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n\n for (const pkgEntry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, pkgEntry, 'package.json');\n if (!fs.existsSync(pkgJsonPath)) {continue;}\n\n try {\n const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n if (json.name) {\n results.push({\n name: json.name,\n repoPath: repoRelPath,\n category: categoryResult.category,\n packageJsonPath: pkgJsonPath,\n });\n }\n } catch {\n // ignore\n }\n }\n }\n }\n }\n\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport { getRepoPackageNames } from '../core/workspace-scanner.js';\n\n/**\n * Checks that all packages in the repo only depend on @kb-labs/sdk\n * and their own internal packages (within the same repo).\n */\nexport async function checkSdkOnlyDeps(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const internalPackageNames = new Set(getRepoPackageNames(workspaceRoot, repoPath));\n\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; dependencies?: Record<string, string> };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n const deps = Object.keys(json.dependencies ?? {});\n const packageName = json.name ?? path.basename(path.dirname(pkgJsonPath));\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n for (const dep of deps) {\n if (!dep.startsWith('@kb-labs/')) {continue;}\n if (dep === '@kb-labs/sdk') {continue;}\n if (internalPackageNames.has(dep)) {continue;}\n\n violations.push({\n rule: 'sdk-only-deps',\n severity: 'error',\n message: `${packageName} imports ${dep} directly`,\n package: packageName,\n detail: `Plugins must depend only on @kb-labs/sdk. Move needed types to SDK or use SDK re-exports.`,\n file: relPath,\n });\n }\n }\n\n return violations;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport { buildPackageMap, getRepoPackageNames } from '../core/workspace-scanner.js';\nimport { checkSdkOnlyDeps } from './sdk-only-deps.js';\n\n/**\n * Checks that packages only depend on packages from allowed categories.\n * If allowed contains \"sdk-only\", delegates to sdk-only-deps logic.\n */\nexport async function checkBoundary(\n repoPath: string,\n config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n\n // Find the category for this repo\n const { detectCategory } = await import('../core/category-resolver.js');\n const categoryResult = detectCategory(repoPath, config);\n const category = categoryResult.category;\n\n if (!category) {return violations;} // no category = no boundary config\n\n const boundaryRuleConfig = config.rules['boundary-check']?.config as\n | { allowed?: Record<string, string[]> }\n | undefined;\n const allowedCategories = boundaryRuleConfig?.allowed?.[category] ?? [];\n\n // If \"sdk-only\" is in allowed, delegate to sdk-only-deps\n if (allowedCategories.includes('sdk-only')) {\n return checkSdkOnlyDeps(repoPath, config, workspaceRoot);\n }\n\n const packageMap = buildPackageMap(workspaceRoot, config);\n const internalPackageNames = new Set(getRepoPackageNames(workspaceRoot, repoPath));\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n\n for (const pkgJsonPath of findPackageJsonPaths(absRepoPath)) {\n let json: { name?: string; dependencies?: Record<string, string> };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n const deps = Object.keys(json.dependencies ?? {});\n const packageName = json.name ?? path.basename(path.dirname(pkgJsonPath));\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n for (const dep of deps) {\n if (!dep.startsWith('@kb-labs/')) {continue;}\n if (internalPackageNames.has(dep)) {continue;} // own package = always ok\n\n const depCategory = packageMap.get(dep);\n if (depCategory === undefined || depCategory === null) {continue;} // unknown package, skip\n\n if (!allowedCategories.includes(depCategory)) {\n violations.push({\n rule: 'boundary-check',\n severity: 'error',\n message: `${packageName} depends on ${dep} (category: ${depCategory ?? 'unknown'})`,\n package: packageName,\n detail: `Category \"${category}\" may only depend on: ${allowedCategories.join(', ')}`,\n file: relPath,\n });\n }\n }\n }\n\n return violations;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","export interface SymbolExtractor {\n extract(dtsContent: string): Set<string>;\n}\n\n/**\n * Regex-based symbol extractor for .d.ts files.\n * Handles common export patterns. Interface allows future replacement with TS Compiler API.\n */\nexport class RegexSymbolExtractor implements SymbolExtractor {\n extract(dtsContent: string): Set<string> {\n const symbols = new Set<string>();\n\n // export function foo / export async function foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:async\\s+)?function\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export class Foo / export abstract class Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:abstract\\s+)?class\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export type Foo / export interface Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:type\\s+|interface\\s+)(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export const foo / export let foo / export var foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:const|let|var)\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export enum Foo\n for (const m of dtsContent.matchAll(/^export\\s+(?:const\\s+)?enum\\s+(\\w+)/gm)) {\n symbols.add(m[1]!);\n }\n\n // export { foo, bar as baz }\n for (const m of dtsContent.matchAll(/^export\\s+\\{([^}]+)\\}/gm)) {\n const entries = m[1]!.split(',').map((s) => s.trim());\n for (const entry of entries) {\n // Handle \"foo as bar\" — the exported name is \"bar\"\n const asMatch = entry.match(/\\w+\\s+as\\s+(\\w+)/);\n if (asMatch) {\n symbols.add(asMatch[1]!);\n } else {\n const nameMatch = entry.match(/^(\\w+)/);\n if (nameMatch) {symbols.add(nameMatch[1]!);}\n }\n }\n }\n\n // export default\n if (/^export\\s+default\\s+/m.test(dtsContent)) {\n symbols.add('default');\n }\n\n return symbols;\n }\n}\n\nexport const defaultSymbolExtractor: SymbolExtractor = new RegexSymbolExtractor();\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { PolicyConfig, PolicyViolation, ApiSnapshot } from '@kb-labs/policy-contracts';\nimport { defaultSymbolExtractor } from './symbol-extractor.js';\n\nconst SNAPSHOTS_DIR = '.kb/api-snapshots';\n\n/**\n * Checks API backward compatibility by comparing exported symbols against a stored snapshot.\n * Also handles \"no-breaking-without-major\" rule (both rules map to this check).\n *\n * First run (no snapshot): warns and skips — does NOT auto-create a snapshot.\n * Use updateSnapshots() to create/refresh snapshots explicitly.\n */\nexport async function checkApiCompat(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n if (!json.name || !json.version) {continue;}\n\n const pkgName = json.name;\n const currentVersion = json.version;\n const snapshotPath = getSnapshotPath(workspaceRoot, pkgName);\n\n // Gather current exported symbols from dist/*.d.ts\n const pkgDir = path.dirname(pkgJsonPath);\n const currentSymbols = extractSymbolsFromDist(pkgDir);\n\n if (!fs.existsSync(snapshotPath)) {\n // FIX 2 (CRITICAL): removed the auto-saveSnapshot() call that was here.\n // checkApiCompat is a read-only check function; writing files as a side-effect\n // inside it violated the read/write separation and caused unexpected mutations\n // during dry-run / CI read-only policy checks.\n // Snapshots must be created explicitly via updateSnapshots().\n console.warn(\n `[policy] api-compat: No snapshot for ${pkgName} — run 'policy update-snapshots' to create one.`,\n );\n continue;\n }\n\n // Load snapshot and compare\n let snapshot: ApiSnapshot;\n try {\n snapshot = JSON.parse(fs.readFileSync(snapshotPath, 'utf-8'));\n } catch {\n console.warn(`[policy] api-compat: Could not read snapshot for ${pkgName}, skipping.`);\n continue;\n }\n\n const snapshotSymbols = new Set(snapshot.symbols);\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n const removed: string[] = [];\n for (const sym of snapshotSymbols) {\n if (!currentSymbols.has(sym)) {removed.push(sym);}\n }\n\n if (removed.length > 0) {\n // Check if major version bumped\n const currentMajor = parseMajor(currentVersion);\n const snapshotMajor = parseMajor(snapshot.version);\n\n if (currentMajor <= snapshotMajor) {\n violations.push({\n rule: 'api-compat-check',\n severity: 'error',\n message: `${pkgName} removed exported symbols without major version bump`,\n package: pkgName,\n detail: `Removed: ${removed.join(', ')}. Bump major version (current: ${currentVersion}, snapshot: ${snapshot.version}) or restore symbols.`,\n file: relPath,\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Creates or updates the API snapshot for all packages in a repo.\n */\nexport function updateSnapshots(repoPath: string, workspaceRoot: string): void {\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n if (!json.name || !json.version) {continue;}\n\n const pkgDir = path.dirname(pkgJsonPath);\n const symbols = extractSymbolsFromDist(pkgDir);\n const snapshotPath = getSnapshotPath(workspaceRoot, json.name);\n saveSnapshot(snapshotPath, json.name, json.version, symbols);\n console.log(`[policy] Saved snapshot for ${json.name} @ ${json.version} (${symbols.size} symbols)`);\n }\n}\n\nfunction extractSymbolsFromDist(pkgDir: string): Set<string> {\n const distDir = path.join(pkgDir, 'dist');\n const symbols = new Set<string>();\n\n if (!fs.existsSync(distDir)) {return symbols;}\n\n const dtsFiles = findDtsFiles(distDir);\n for (const dtsFile of dtsFiles) {\n const content = fs.readFileSync(dtsFile, 'utf-8');\n for (const sym of defaultSymbolExtractor.extract(content)) {\n symbols.add(sym);\n }\n }\n\n return symbols;\n}\n\nfunction findDtsFiles(dir: string): string[] {\n const results: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...findDtsFiles(fullPath));\n } else if (entry.name.endsWith('.d.ts')) {\n results.push(fullPath);\n }\n }\n return results;\n}\n\nfunction getSnapshotPath(workspaceRoot: string, packageName: string): string {\n const safeName = packageName.replace(/\\//g, '__').replace(/@/g, '');\n const snapshotsDir = path.join(workspaceRoot, SNAPSHOTS_DIR);\n if (!fs.existsSync(snapshotsDir)) {\n fs.mkdirSync(snapshotsDir, { recursive: true });\n }\n return path.join(snapshotsDir, `${safeName}.json`);\n}\n\nfunction saveSnapshot(snapshotPath: string, packageName: string, version: string, symbols: Set<string>): void {\n const snapshot: ApiSnapshot = {\n packageName,\n version,\n symbols: Array.from(symbols).sort(),\n extractedAt: new Date().toISOString(),\n };\n // FIX 5 (MEDIUM): guarded writeFileSync — a permission error or a full disk must\n // not crash the entire update run; log a warning and continue instead.\n try {\n fs.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2));\n } catch (err) {\n console.warn(`[policy] api-compat: Failed to write snapshot to ${snapshotPath}: ${(err as Error).message}`);\n }\n}\n\nfunction parseMajor(version: string): number {\n return parseInt(version.split('.')[0] ?? '0', 10);\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n// FIX 1 (CRITICAL): replaced execSync with spawnSync so packageName is passed as\n// a literal argument — never interpolated into a shell command string.\n// execSync with a template literal was vulnerable to shell injection if packageName\n// contained shell metacharacters (e.g. `$(cmd)`, backticks, semicolons).\nimport { spawnSync } from 'node:child_process';\nimport type { PolicyConfig, PolicyViolation } from '@kb-labs/policy-contracts';\nimport semver from 'semver';\n\n/**\n * Checks that the current version in package.json is not less than the published npm version.\n */\nexport async function checkNoRollback(\n repoPath: string,\n _config: PolicyConfig,\n workspaceRoot: string,\n): Promise<PolicyViolation[]> {\n const violations: PolicyViolation[] = [];\n const absRepoPath = path.resolve(workspaceRoot, repoPath);\n const packageJsonPaths = findPackageJsonPaths(absRepoPath);\n\n for (const pkgJsonPath of packageJsonPaths) {\n let json: { name?: string; version?: string; private?: boolean };\n try {\n json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n } catch {\n continue;\n }\n\n if (!json.name || !json.version) {continue;}\n if (json.private) {continue;} // private packages are not published\n\n const packageName = json.name;\n const currentVersion = json.version;\n const relPath = path.relative(workspaceRoot, pkgJsonPath);\n\n const publishedVersion = getPublishedVersion(packageName);\n if (publishedVersion === null) {\n // Not published or npm unavailable — skip\n continue;\n }\n\n if (!semver.gte(currentVersion, publishedVersion)) {\n violations.push({\n rule: 'no-rollback',\n severity: 'error',\n message: `${packageName} version ${currentVersion} is less than published ${publishedVersion}`,\n package: packageName,\n detail: `Cannot decrease version once published to npm. Restore to ${publishedVersion} or higher.`,\n file: relPath,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Returns the published npm version for a package, or null if not published / offline.\n */\nfunction getPublishedVersion(packageName: string): string | null {\n // spawnSync receives packageName as a discrete argv element — the OS never\n // passes it through a shell, so metacharacters cannot be interpreted.\n const result = spawnSync('npm', ['show', packageName, 'version', '--silent'], {\n timeout: 10000,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n if (result.error || result.status !== 0) {return null;}\n return semver.valid(result.stdout.trim()) ?? null;\n}\n\nfunction findPackageJsonPaths(absRepoPath: string): string[] {\n const results: string[] = [];\n for (const subdir of ['packages', 'apps']) {\n const subdirPath = path.join(absRepoPath, subdir);\n if (!fs.existsSync(subdirPath)) {continue;}\n for (const entry of fs.readdirSync(subdirPath)) {\n const pkgJsonPath = path.join(subdirPath, entry, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {results.push(pkgJsonPath);}\n }\n }\n return results;\n}\n","import type { CategoryResult, CheckReport, PolicyConfig, RepoCheckResult } from '@kb-labs/policy-contracts';\nimport { checkSdkOnlyDeps } from '../checks/sdk-only-deps.js';\nimport { checkBoundary } from '../checks/boundary-check.js';\nimport { checkApiCompat } from '../checks/api-compat-check.js';\nimport { checkNoRollback } from '../checks/no-rollback.js';\n\ntype CheckFn = (repoPath: string, config: PolicyConfig, workspaceRoot: string) => Promise<import('@kb-labs/policy-contracts').PolicyViolation[]>;\n\nconst RULE_CHECKS: Record<string, CheckFn> = {\n 'sdk-only-deps': checkSdkOnlyDeps,\n 'boundary-check': checkBoundary,\n 'no-breaking-without-major': checkApiCompat,\n 'no-rollback': checkNoRollback,\n 'api-compat-check': checkApiCompat,\n};\n\nexport async function runChecks(\n repos: CategoryResult[],\n config: PolicyConfig,\n workspaceRoot: string,\n): Promise<CheckReport> {\n const repoResults: RepoCheckResult[] = [];\n\n for (const repo of repos) {\n const violations = [];\n const passed: string[] = [];\n const rulesToRun = repo.rules;\n\n for (const rule of rulesToRun) {\n const checkFn = RULE_CHECKS[rule];\n if (!checkFn) {\n // Unknown rule — skip with warning\n console.warn(`[policy] Unknown rule: ${rule} (skipping)`);\n continue;\n }\n\n // FIX 3 (CRITICAL): wrap each rule execution individually so that an\n // unexpected throw from one check does not abort the remaining rules or\n // prevent the report from being built for this (and subsequent) repos.\n let ruleViolations: import('@kb-labs/policy-contracts').PolicyViolation[];\n try {\n ruleViolations = await checkFn(repo.path, config, workspaceRoot);\n } catch (err) {\n console.warn(`[policy] Rule '${rule}' threw an unexpected error (skipping): ${(err as Error).message}`);\n continue;\n }\n\n if (ruleViolations.length === 0) {\n passed.push(rule);\n } else {\n violations.push(...ruleViolations.map((v) => ({ ...v, rule })));\n }\n }\n\n repoResults.push({\n path: repo.path,\n category: repo.category,\n violations,\n passed,\n });\n }\n\n const totalViolations = repoResults.reduce((sum, r) => sum + r.violations.length, 0);\n const failedRepos = repoResults.filter((r) => r.violations.length > 0).length;\n\n return {\n passed: totalViolations === 0,\n repos: repoResults,\n summary: {\n total: repos.length,\n passed: repos.length - failedRepos,\n failed: failedRepos,\n violations: totalViolations,\n },\n };\n}\n","import { defineCommandFlags, combinePermissions } from '@kb-labs/sdk';\n\nconst pluginPermissions = combinePermissions()\n .withFs({\n mode: 'read',\n allow: ['.', '.kb/api-snapshots/**'],\n })\n .withQuotas({\n timeoutMs: 60000,\n memoryMb: 256,\n })\n .build();\n\nconst detectPermissions = combinePermissions()\n .withFs({ mode: 'read', allow: ['.'] })\n .withQuotas({ timeoutMs: 15000, memoryMb: 128 })\n .build();\n\nconst checkPermissions = combinePermissions()\n .withFs({\n mode: 'read',\n allow: ['.', '.kb/api-snapshots/**'],\n })\n .withFs({\n mode: 'readWrite',\n allow: ['.kb/api-snapshots/**'],\n })\n .withQuotas({ timeoutMs: 60000, memoryMb: 256 })\n .build();\n\nconst snapshotPermissions = combinePermissions()\n .withFs({ mode: 'read', allow: ['.'] })\n .withFs({ mode: 'readWrite', allow: ['.kb/api-snapshots/**'] })\n .withQuotas({ timeoutMs: 30000, memoryMb: 128 })\n .build();\n\nexport const manifest = {\n schema: 'kb.plugin/3',\n id: '@kb-labs/policy',\n version: '0.1.0',\n\n configSection: 'policy',\n\n display: {\n name: 'Policy Enforcer',\n description: 'Enforce workspace development policies',\n tags: ['policy', 'governance', 'boundaries', 'sdk-only', 'api-compat'],\n },\n\n cli: {\n groupMeta: [\n { path: 'policy', describe: 'Policy enforcement commands' },\n ],\n commands: [\n {\n path: 'policy detect',\n describe: 'Detect policy category for changed or specified repos',\n operationType: 'analyze' as const,\n longDescription:\n 'Determines the category for repos based on git changes or a specified path, then resolves applicable policy rules.',\n\n handler: './cli/commands/detect.js#default',\n\n flags: defineCommandFlags({\n path: {\n type: 'string',\n description: 'Repo path to check (relative to workspace root). Defaults to git diff.',\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n }),\n\n permissions: detectPermissions,\n },\n {\n path: 'policy check',\n describe: 'Run policy checks for changed repos or a specific path',\n operationType: 'analyze' as const,\n longDescription:\n 'Runs all applicable policy rules for detected repos. Exits with code 1 on violations. Use in CI or pnpm done pipeline.',\n\n handler: './cli/commands/check.js#default',\n\n flags: defineCommandFlags({\n path: {\n type: 'string',\n description: 'Repo path to check (relative to workspace root). Defaults to git diff.',\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n }),\n\n permissions: checkPermissions,\n },\n {\n path: 'policy rules',\n describe: 'Show all configured policy rules and their categories',\n operationType: 'read' as const,\n\n handler: './cli/commands/rules.js#default',\n\n flags: defineCommandFlags({\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n }),\n\n permissions: detectPermissions,\n },\n {\n path: 'policy snapshot',\n describe: 'Create or update API snapshot for a repo (run after npm publish)',\n operationType: 'mutate' as const,\n longDescription:\n 'Extracts exported symbols from dist/*.d.ts files and saves them to .kb/api-snapshots/. Used by api-compat-check to detect breaking changes.',\n\n handler: './cli/commands/snapshot.js#default',\n\n flags: defineCommandFlags({\n path: {\n type: 'string',\n description: 'Repo path (relative to workspace root)',\n required: true,\n },\n }),\n\n permissions: snapshotPermissions,\n },\n ],\n },\n\n permissions: pluginPermissions,\n};\n\nexport default manifest;\n"]}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "kb.plugin/3",
|
|
3
|
+
"id": "@kb-labs/policy",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"configSection": "policy",
|
|
6
|
+
"display": {
|
|
7
|
+
"name": "Policy Enforcer",
|
|
8
|
+
"description": "Enforce workspace development policies",
|
|
9
|
+
"tags": [
|
|
10
|
+
"policy",
|
|
11
|
+
"governance",
|
|
12
|
+
"boundaries",
|
|
13
|
+
"sdk-only",
|
|
14
|
+
"api-compat"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"cli": {
|
|
18
|
+
"groupMeta": [
|
|
19
|
+
{
|
|
20
|
+
"path": "policy",
|
|
21
|
+
"describe": "Policy enforcement commands"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"commands": [
|
|
25
|
+
{
|
|
26
|
+
"path": "policy detect",
|
|
27
|
+
"describe": "Detect policy category for changed or specified repos",
|
|
28
|
+
"operationType": "analyze",
|
|
29
|
+
"longDescription": "Determines the category for repos based on git changes or a specified path, then resolves applicable policy rules.",
|
|
30
|
+
"handler": "./cli/commands/detect.js#default",
|
|
31
|
+
"flags": [
|
|
32
|
+
{
|
|
33
|
+
"name": "path",
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "Repo path to check (relative to workspace root). Defaults to git diff."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "json",
|
|
39
|
+
"type": "boolean",
|
|
40
|
+
"default": false,
|
|
41
|
+
"description": "Output as JSON"
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"permissions": {
|
|
45
|
+
"fs": {
|
|
46
|
+
"read": [
|
|
47
|
+
"."
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"quotas": {
|
|
51
|
+
"timeoutMs": 15000,
|
|
52
|
+
"memoryMb": 128
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"path": "policy check",
|
|
58
|
+
"describe": "Run policy checks for changed repos or a specific path",
|
|
59
|
+
"operationType": "analyze",
|
|
60
|
+
"longDescription": "Runs all applicable policy rules for detected repos. Exits with code 1 on violations. Use in CI or pnpm done pipeline.",
|
|
61
|
+
"handler": "./cli/commands/check.js#default",
|
|
62
|
+
"flags": [
|
|
63
|
+
{
|
|
64
|
+
"name": "path",
|
|
65
|
+
"type": "string",
|
|
66
|
+
"description": "Repo path to check (relative to workspace root). Defaults to git diff."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "json",
|
|
70
|
+
"type": "boolean",
|
|
71
|
+
"default": false,
|
|
72
|
+
"description": "Output as JSON"
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"permissions": {
|
|
76
|
+
"fs": {
|
|
77
|
+
"read": [
|
|
78
|
+
".",
|
|
79
|
+
".kb/api-snapshots/**"
|
|
80
|
+
],
|
|
81
|
+
"write": [
|
|
82
|
+
".",
|
|
83
|
+
".kb/api-snapshots/**"
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
"quotas": {
|
|
87
|
+
"timeoutMs": 60000,
|
|
88
|
+
"memoryMb": 256
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"path": "policy rules",
|
|
94
|
+
"describe": "Show all configured policy rules and their categories",
|
|
95
|
+
"operationType": "read",
|
|
96
|
+
"handler": "./cli/commands/rules.js#default",
|
|
97
|
+
"flags": [
|
|
98
|
+
{
|
|
99
|
+
"name": "json",
|
|
100
|
+
"type": "boolean",
|
|
101
|
+
"default": false,
|
|
102
|
+
"description": "Output as JSON"
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"permissions": {
|
|
106
|
+
"fs": {
|
|
107
|
+
"read": [
|
|
108
|
+
"."
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
"quotas": {
|
|
112
|
+
"timeoutMs": 15000,
|
|
113
|
+
"memoryMb": 128
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"path": "policy snapshot",
|
|
119
|
+
"describe": "Create or update API snapshot for a repo (run after npm publish)",
|
|
120
|
+
"operationType": "mutate",
|
|
121
|
+
"longDescription": "Extracts exported symbols from dist/*.d.ts files and saves them to .kb/api-snapshots/. Used by api-compat-check to detect breaking changes.",
|
|
122
|
+
"handler": "./cli/commands/snapshot.js#default",
|
|
123
|
+
"flags": [
|
|
124
|
+
{
|
|
125
|
+
"name": "path",
|
|
126
|
+
"type": "string",
|
|
127
|
+
"description": "Repo path (relative to workspace root)",
|
|
128
|
+
"required": true
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
"permissions": {
|
|
132
|
+
"fs": {
|
|
133
|
+
"read": [
|
|
134
|
+
".",
|
|
135
|
+
".kb/api-snapshots/**"
|
|
136
|
+
],
|
|
137
|
+
"write": [
|
|
138
|
+
".",
|
|
139
|
+
".kb/api-snapshots/**"
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
"quotas": {
|
|
143
|
+
"timeoutMs": 30000,
|
|
144
|
+
"memoryMb": 128
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
},
|
|
150
|
+
"permissions": {
|
|
151
|
+
"fs": {
|
|
152
|
+
"read": [
|
|
153
|
+
".",
|
|
154
|
+
".kb/api-snapshots/**"
|
|
155
|
+
]
|
|
156
|
+
},
|
|
157
|
+
"quotas": {
|
|
158
|
+
"timeoutMs": 60000,
|
|
159
|
+
"memoryMb": 256
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/policy-core",
|
|
3
3
|
"description": "Core implementation for KB Labs policy plugin. Category resolver, policy runner, and checks.",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.105.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -20,20 +20,30 @@
|
|
|
20
20
|
"dist",
|
|
21
21
|
"README.md"
|
|
22
22
|
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup --config tsup.config.ts",
|
|
25
|
+
"clean": "rimraf dist",
|
|
26
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
27
|
+
"lint": "eslint src --ext .ts",
|
|
28
|
+
"lint:fix": "eslint . --fix",
|
|
29
|
+
"test": "vitest run --passWithNoTests",
|
|
30
|
+
"test:watch": "vitest",
|
|
31
|
+
"type-check": "tsc --noEmit"
|
|
32
|
+
},
|
|
23
33
|
"dependencies": {
|
|
34
|
+
"@kb-labs/policy-contracts": "^2.105.0",
|
|
35
|
+
"@kb-labs/sdk": "workspace:*",
|
|
24
36
|
"semver": "^7.6.3",
|
|
25
|
-
"zod": "^3.25.76"
|
|
26
|
-
"@kb-labs/sdk": "2.22.0",
|
|
27
|
-
"@kb-labs/policy-contracts": "2.104.0"
|
|
37
|
+
"zod": "^3.25.76"
|
|
28
38
|
},
|
|
29
39
|
"devDependencies": {
|
|
40
|
+
"@kb-labs/devkit": "workspace:*",
|
|
30
41
|
"@types/node": "^24.3.3",
|
|
31
42
|
"@types/semver": "^7.5.8",
|
|
32
43
|
"rimraf": "^6.0.1",
|
|
33
44
|
"tsup": "^8.5.0",
|
|
34
45
|
"typescript": "^5.6.3",
|
|
35
|
-
"vitest": "^3.2.6"
|
|
36
|
-
"@kb-labs/devkit": "2.104.0"
|
|
46
|
+
"vitest": "^3.2.6"
|
|
37
47
|
},
|
|
38
48
|
"engines": {
|
|
39
49
|
"node": ">=20.0.0",
|
|
@@ -42,15 +52,5 @@
|
|
|
42
52
|
"kb": {
|
|
43
53
|
"manifest": "./dist/manifest.v3.js"
|
|
44
54
|
},
|
|
45
|
-
"sideEffects": false
|
|
46
|
-
|
|
47
|
-
"build": "tsup --config tsup.config.ts",
|
|
48
|
-
"clean": "rimraf dist",
|
|
49
|
-
"dev": "tsup --config tsup.config.ts --watch",
|
|
50
|
-
"lint": "eslint src --ext .ts",
|
|
51
|
-
"lint:fix": "eslint . --fix",
|
|
52
|
-
"test": "vitest run --passWithNoTests",
|
|
53
|
-
"test:watch": "vitest",
|
|
54
|
-
"type-check": "tsc --noEmit"
|
|
55
|
-
}
|
|
56
|
-
}
|
|
55
|
+
"sideEffects": false
|
|
56
|
+
}
|