@kb-labs/devlink-core 2.119.0-canary.f8394d5fd → 2.119.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/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/npm/index.ts","../src/discovery/index.ts","../src/plan/index.ts","../src/apply/index.ts","../src/state/index.ts","../src/backup/index.ts","../src/workspace-yaml/index.ts","../src/diagnostics/index.ts"],"names":["yaml","existsSync","readFileSync","relative","dirname","join","writeFileSync","mkdirSync","readdirSync","resolve"],"mappings":"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","file":"index.js","sourcesContent":["import { spawnSync } from 'child_process';\nimport { useCache } from '@kb-labs/sdk';\n\n/** Default TTL: 24 hours */\nconst DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Returns the latest published version of a package on npm, or null if not published.\n * Results are cached via useCache() with the given TTL.\n */\nexport async function getLatestNpmVersion(\n packageName: string,\n ttlMs = DEFAULT_TTL_MS\n): Promise<string | null> {\n const cacheKey = `devlink:npm-version:${packageName}`;\n const cache = useCache();\n\n if (cache) {\n const cached = await cache.get<string | null>(cacheKey);\n // cache.get returns null for missing keys — only return if explicitly cached\n if (cached !== null && cached !== undefined) {return cached;}\n }\n\n let version: string | null;\n // spawnSync passes packageName as a discrete argv element — the OS never\n // interprets it as a shell command, preventing command injection.\n const proc = spawnSync('npm', ['view', packageName, 'version', '--json'], {\n encoding: 'utf-8',\n timeout: 10_000,\n });\n if (proc.error || proc.status !== 0 || !proc.stdout?.trim()) {\n version = null;\n } else {\n try {\n // npm view returns a JSON string like \"1.4.0\" (with quotes)\n version = JSON.parse(proc.stdout.trim()) as string;\n } catch {\n version = null;\n }\n }\n\n if (cache) {\n await cache.set(cacheKey, version, ttlMs);\n }\n\n return version;\n}\n\n/**\n * Checks if a package exists on the npm registry.\n * Results are cached via useCache() with the given TTL.\n */\nexport async function isPublishedOnNpm(\n packageName: string,\n ttlMs = DEFAULT_TTL_MS\n): Promise<boolean> {\n return (await getLatestNpmVersion(packageName, ttlMs)) !== null;\n}\n\n/**\n * Filters a list of package names to only those published on npm.\n * Runs checks concurrently.\n */\nexport async function filterPublishedPackages(\n packageNames: string[],\n ttlMs = DEFAULT_TTL_MS\n): Promise<Set<string>> {\n const results = await Promise.all(\n packageNames.map(async name => ({\n name,\n published: await isPublishedOnNpm(name, ttlMs),\n }))\n );\n\n return new Set(results.filter(r => r.published).map(r => r.name));\n}\n","import { readFileSync, existsSync, readdirSync } from 'fs';\nimport { join, relative, dirname } from 'path';\nimport yaml from 'js-yaml';\nimport { discoverSubRepoPaths } from '@kb-labs/sdk';\nimport type { PackageMap, PackageEntry, DevlinkMode } from '@kb-labs/devlink-contracts';\nimport { getLatestNpmVersion } from '../npm/index.js';\n\ninterface PnpmWorkspace {\n packages?: string[];\n}\n\ninterface PackageJson {\n name?: string;\n version?: string;\n private?: boolean;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\n/** Monorepo info discovered on disk */\nexport interface MonorepoInfo {\n /** Dir name e.g. kb-labs-core */\n name: string;\n /** Absolute path to the monorepo root */\n rootPath: string;\n /** All package.json paths within the monorepo */\n packagePaths: string[];\n /** pnpm-workspace.yaml content */\n workspacePackages: string[];\n}\n\n/**\n * Discovers all submodule repos via .gitmodules (layout-agnostic).\n * Includes both monorepos (with pnpm-workspace.yaml) and standalone packages.\n */\nexport function discoverMonorepos(rootDir: string): MonorepoInfo[] {\n const subRepoPaths = discoverSubRepoPaths(rootDir);\n const monorepos: MonorepoInfo[] = [];\n\n for (const repoPath of subRepoPaths) {\n const repoName = repoPath.split('/').pop() ?? repoPath;\n const hasWorkspace = existsSync(join(repoPath, 'pnpm-workspace.yaml'));\n\n if (hasWorkspace) {\n // Monorepo: scan all package.json files\n const packagePaths = findPackageJsonFiles(repoPath);\n const repoWorkspace = yaml.load(\n readFileSync(join(repoPath, 'pnpm-workspace.yaml'), 'utf-8')\n ) as PnpmWorkspace;\n\n // Only keep intra-repo patterns (not cross-repo paths starting with ../)\n // Cross-repo paths are computed fresh each run — keeping stale ones causes\n // exponential growth where each run re-expands previously generated paths.\n const intraPatterns = (repoWorkspace.packages ?? []).filter(\n p => !p.startsWith('../') && !p.startsWith('..\\\\')\n );\n\n monorepos.push({\n name: repoName,\n rootPath: repoPath,\n packagePaths,\n workspacePackages: intraPatterns,\n });\n } else {\n // Standalone package (e.g. devkit): treat root package.json as sole package\n const rootPkgPath = join(repoPath, 'package.json');\n if (existsSync(rootPkgPath)) {\n monorepos.push({\n name: repoName,\n rootPath: repoPath,\n packagePaths: [rootPkgPath],\n workspacePackages: [],\n });\n }\n }\n }\n\n return monorepos;\n}\n\n/**\n * Builds a PackageMap: packageName → { linkPath, npmVersion, monorepo }.\n * Scans all packages in all monorepos and collects their name/version.\n *\n * linkPath is relative to the root kb-labs/ dir (so it can be used as link:../path).\n */\nexport function buildPackageMap(monorepos: MonorepoInfo[], rootDir: string): PackageMap {\n const map: PackageMap = {};\n\n for (const monorepo of monorepos) {\n for (const pkgPath of monorepo.packagePaths) {\n if (!existsSync(pkgPath)) {continue;}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {\n continue;\n }\n\n if (!pkg.name || !pkg.version) {continue;}\n // Only include @kb-labs/* packages (or non-scoped kb-labs-* packages)\n if (!pkg.name.startsWith('@kb-labs/') && !pkg.name.startsWith('kb-labs-')) {continue;}\n\n const pkgDir = dirname(pkgPath);\n const linkPath = relative(rootDir, pkgDir);\n\n const entry: PackageEntry = {\n name: pkg.name,\n linkPath,\n npmVersion: `^${pkg.version}`,\n monorepo: monorepo.name,\n private: pkg.private ?? false,\n };\n\n map[pkg.name] = entry;\n }\n }\n\n return map;\n}\n\n/**\n * Async version of buildPackageMap that verifies each package exists on npm.\n * For 'local' mode skips the npm check and returns all packages found on disk.\n * For 'npm'/'auto'/undefined filters out packages not published to the registry.\n */\nexport async function buildPackageMapFiltered(\n monorepos: MonorepoInfo[],\n rootDir: string,\n ttlMs?: number,\n mode?: DevlinkMode\n): Promise<PackageMap> {\n const rawMap = buildPackageMap(monorepos, rootDir);\n // local mode: disk has priority, no npm check needed\n if (mode === 'local') {return rawMap;}\n const packageNames = Object.keys(rawMap);\n // Fetch latest published versions concurrently\n const versionResults = await Promise.all(\n packageNames.map(async name => ({\n name,\n version: await getLatestNpmVersion(name, ttlMs),\n }))\n );\n const filtered: PackageMap = {};\n for (const { name, version } of versionResults) {\n if (version !== null) {\n filtered[name] = { ...rawMap[name]!, npmVersion: `^${version}` };\n }\n }\n return filtered;\n}\n\n/**\n * Determines the current linking mode of cross-repo dependencies in a package.json.\n * Returns counts of link:, npm, workspace: references for @kb-labs/* deps.\n */\nexport function analyzePackageDeps(\n pkgPath: string,\n packageMap: PackageMap\n): { linkCount: number; npmCount: number; workspaceCount: number; unknownCount: number } {\n let linkCount = 0;\n let npmCount = 0;\n let workspaceCount = 0;\n let unknownCount = 0;\n\n if (!existsSync(pkgPath)) {return { linkCount, npmCount, workspaceCount, unknownCount };}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {\n return { linkCount, npmCount, workspaceCount, unknownCount };\n }\n\n const sections = [pkg.dependencies, pkg.devDependencies, pkg.peerDependencies];\n for (const section of sections) {\n if (!section) {continue;}\n for (const [depName, depValue] of Object.entries(section)) {\n if (!packageMap[depName]) {continue;} // Not a cross-repo dep\n if (depValue.startsWith('link:')) {\n linkCount++;\n } else if (depValue.startsWith('workspace:')) {\n workspaceCount++;\n } else if (depValue.startsWith('^') || depValue.startsWith('~') || /^\\d/.test(depValue)) {\n npmCount++;\n } else {\n unknownCount++;\n }\n }\n }\n\n return { linkCount, npmCount, workspaceCount, unknownCount };\n}\n\n/**\n * Finds all package.json files within a monorepo (excludes node_modules, dist).\n */\nfunction findPackageJsonFiles(repoRoot: string): string[] {\n const results: string[] = [];\n\n function walk(dir: string, depth = 0) {\n if (depth > 4) {return;}\n\n let entries: import('fs').Dirent<string>[];\n try {\n entries = readdirSync(dir, { withFileTypes: true, encoding: 'utf-8' });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git') {continue;}\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n walk(full, depth + 1);\n } else if (entry.name === 'package.json') {\n results.push(full);\n }\n }\n }\n\n walk(repoRoot);\n return results;\n}\n\n/**\n * Determines which MonorepoInfo a package.json belongs to.\n * Uses rootPath prefix matching.\n */\nexport function resolvePackageMonorepo(\n pkgPath: string,\n monorepos: MonorepoInfo[]\n): MonorepoInfo | null {\n for (const mono of monorepos) {\n if (pkgPath.startsWith(mono.rootPath + '/') || pkgPath === join(mono.rootPath, 'package.json')) {\n return mono;\n }\n }\n return null;\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { relative, dirname, resolve } from 'path';\nimport type {\n DevlinkMode,\n DevlinkPlan,\n DevlinkPlanItem,\n PackageEntry,\n PackageMap,\n} from '@kb-labs/devlink-contracts';\nimport type { MonorepoInfo } from '../discovery/index.js';\nimport { resolvePackageMonorepo } from '../discovery/index.js';\n\ntype DepSection = 'dependencies' | 'devDependencies' | 'peerDependencies';\n\ninterface PackageJson {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\n/**\n * Builds a DevlinkPlan — all package.json changes needed for the target mode.\n */\nexport function buildPlan(\n mode: DevlinkMode,\n packageMap: PackageMap,\n monorepos: MonorepoInfo[],\n rootDir: string,\n options: { scopedRepos?: string[] } = {}\n): DevlinkPlan {\n const items: DevlinkPlanItem[] = [];\n const filteredMonorepos = options.scopedRepos?.length\n ? monorepos.filter(m => options.scopedRepos!.includes(m.name))\n : monorepos;\n\n for (const monorepo of filteredMonorepos) {\n for (const pkgPath of monorepo.packagePaths) {\n if (!existsSync(pkgPath)) {continue;}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {\n continue;\n }\n\n const sections: DepSection[] = ['dependencies', 'devDependencies', 'peerDependencies'];\n for (const section of sections) {\n const deps = pkg[section];\n if (!deps) {continue;}\n\n for (const [depName, currentValue] of Object.entries(deps)) {\n const entry = packageMap[depName];\n if (!entry) {continue;} // Not a cross-repo dep\n\n // Skip bare * — ambiguous wildcard, not a versioned dep we manage\n if (currentValue === '*') {continue;}\n\n // workspace:* — only skip if intra-repo (same monorepo handles it via pnpm)\n // Cross-repo workspace:* must be converted to link: or ^version\n if (currentValue.startsWith('workspace:')) {\n const consumerMono = resolvePackageMonorepo(pkgPath, monorepos);\n if (consumerMono && consumerMono.name === entry.monorepo) {continue;}\n }\n\n const targetValue = getTargetValue(mode, entry, pkgPath, rootDir);\n if (targetValue === currentValue) {continue;} // Already correct\n\n items.push({\n packageJsonPath: pkgPath,\n packageJsonRel: relative(rootDir, pkgPath),\n monorepo: monorepo.name,\n depName,\n from: currentValue,\n to: targetValue,\n section,\n });\n }\n }\n }\n }\n\n return {\n mode,\n items,\n timestamp: new Date().toISOString(),\n ...(options.scopedRepos?.length ? { scopedRepos: options.scopedRepos } : {}),\n };\n}\n\n/**\n * Computes the target value for a dependency based on mode.\n * Private packages always stay as link: (not published to npm).\n */\nfunction getTargetValue(\n mode: DevlinkMode,\n entry: PackageEntry,\n fromPackageJson: string,\n rootDir: string\n): string {\n // npm mode: use ^version, but private packages stay as link: (not on npm)\n if (mode === 'npm' && !entry.private) {\n return entry.npmVersion;\n }\n\n // local, auto, or private in npm mode: use link: path\n const fromDir = dirname(fromPackageJson);\n const targetDir = resolve(rootDir, entry.linkPath);\n const relPath = relative(fromDir, targetDir);\n const normalized = relPath.startsWith('.') ? relPath : `./${relPath}`;\n return `link:${normalized}`;\n}\n\n/**\n * Returns a human-readable description of a plan item change.\n */\nexport function describeChange(item: DevlinkPlanItem): string {\n return `${item.depName}: ${item.from} → ${item.to}`;\n}\n\n/**\n * Groups plan items by monorepo for display purposes.\n */\nexport function groupByMonorepo(items: DevlinkPlanItem[]): Map<string, DevlinkPlanItem[]> {\n const groups = new Map<string, DevlinkPlanItem[]>();\n for (const item of items) {\n if (!groups.has(item.monorepo)) {groups.set(item.monorepo, []);}\n groups.get(item.monorepo)!.push(item);\n }\n return groups;\n}\n","import { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { execSync } from 'child_process';\nimport type { DevlinkPlan } from '@kb-labs/devlink-contracts';\n\ntype DepSection = 'dependencies' | 'devDependencies' | 'peerDependencies';\n\ninterface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n [key: string]: unknown;\n}\n\nexport interface ApplyOptions {\n dryRun?: boolean;\n}\n\nexport interface ApplyResult {\n applied: number;\n skipped: number;\n errors: Array<{ file: string; error: string }>;\n}\n\n/**\n * Applies a DevlinkPlan to package.json files on disk.\n * Groups changes by file to minimize I/O operations.\n */\nexport async function applyPlan(plan: DevlinkPlan, options: ApplyOptions = {}): Promise<ApplyResult> {\n const { dryRun = false } = options;\n\n // Group items by packageJsonPath\n const byFile = new Map<string, typeof plan.items>();\n for (const item of plan.items) {\n if (!byFile.has(item.packageJsonPath)) {byFile.set(item.packageJsonPath, []);}\n byFile.get(item.packageJsonPath)!.push(item);\n }\n\n let applied = 0;\n let skipped = 0;\n const errors: ApplyResult['errors'] = [];\n\n for (const [filePath, items] of byFile.entries()) {\n if (!existsSync(filePath)) {\n skipped++;\n continue;\n }\n\n if (dryRun) {\n applied += items.length;\n continue;\n }\n\n try {\n const raw = readFileSync(filePath, 'utf-8');\n const pkg = JSON.parse(raw) as PackageJson;\n\n for (const item of items) {\n const section = pkg[item.section as DepSection];\n if (section && item.depName in section) {\n section[item.depName] = item.to;\n applied++;\n } else {\n skipped++;\n }\n }\n\n // Write back with same trailing newline and 2-space indent\n const trailingNewline = raw.endsWith('\\n') ? '\\n' : '';\n writeFileSync(filePath, JSON.stringify(pkg, null, 2) + trailingNewline, 'utf-8');\n } catch (err) {\n errors.push({ file: filePath, error: String(err) });\n }\n }\n\n return { applied, skipped, errors };\n}\n\n/**\n * Checks if the given directory has uncommitted git changes.\n * Returns a list of modified files, or empty array if clean.\n */\nexport function checkGitDirty(repoPath: string): string[] {\n try {\n const output = execSync('git status --porcelain', {\n cwd: repoPath,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return output\n .split('\\n')\n .filter(Boolean)\n .map(line => line.slice(3).trim());\n } catch {\n return []; // Not a git repo or git not available\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport type { DevlinkState, DevlinkPlan } from '@kb-labs/devlink-contracts';\n\nconst DEFAULT_STATE: DevlinkState = {\n currentMode: null,\n lastApplied: null,\n frozenAt: null,\n};\n\nfunction getStatePath(rootDir: string): string {\n return join(rootDir, '.kb', 'devlink', 'state.json');\n}\n\nfunction getLockPath(rootDir: string): string {\n return join(rootDir, '.kb', 'devlink', 'lock.json');\n}\n\nfunction ensureDir(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\n// ─── State ────────────────────────────────────────────────────────────────────\n\nexport function loadState(rootDir: string): DevlinkState {\n const statePath = getStatePath(rootDir);\n if (!existsSync(statePath)) {return { ...DEFAULT_STATE };}\n\n try {\n return JSON.parse(readFileSync(statePath, 'utf-8')) as DevlinkState;\n } catch {\n return { ...DEFAULT_STATE };\n }\n}\n\nexport function saveState(rootDir: string, state: DevlinkState): void {\n const statePath = getStatePath(rootDir);\n ensureDir(statePath);\n writeFileSync(statePath, JSON.stringify(state, null, 2) + '\\n', 'utf-8');\n}\n\n// ─── Lock / Freeze ────────────────────────────────────────────────────────────\n\nexport interface LockFile {\n frozenAt: string;\n plan: DevlinkPlan;\n}\n\nexport function freeze(rootDir: string, currentPlan: DevlinkPlan): LockFile {\n const lock: LockFile = {\n frozenAt: new Date().toISOString(),\n plan: currentPlan,\n };\n\n const lockPath = getLockPath(rootDir);\n ensureDir(lockPath);\n writeFileSync(lockPath, JSON.stringify(lock, null, 2) + '\\n', 'utf-8');\n\n // Update state.frozenAt\n const state = loadState(rootDir);\n saveState(rootDir, { ...state, frozenAt: lock.frozenAt });\n\n return lock;\n}\n\nexport function loadLock(rootDir: string): LockFile | null {\n const lockPath = getLockPath(rootDir);\n if (!existsSync(lockPath)) {return null;}\n\n try {\n return JSON.parse(readFileSync(lockPath, 'utf-8')) as LockFile;\n } catch {\n return null;\n }\n}\n","import {\n readFileSync,\n writeFileSync,\n mkdirSync,\n existsSync,\n readdirSync,\n copyFileSync,\n rmSync,\n} from 'fs';\nimport { join, dirname } from 'path';\nimport type { DevlinkBackup, DevlinkMode } from '@kb-labs/devlink-contracts';\n\nfunction getBackupsDir(rootDir: string): string {\n return join(rootDir, '.kb', 'devlink', 'backups');\n}\n\nfunction getMetaPath(backupDir: string): string {\n return join(backupDir, 'meta.json');\n}\n\n/**\n * Creates a backup of given package.json files before a mutation.\n * Returns the backup metadata.\n */\nexport function createBackup(\n rootDir: string,\n filePaths: string[],\n description: string,\n currentMode: DevlinkMode | null\n): DevlinkBackup {\n const id = `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n const backupDir = join(getBackupsDir(rootDir), id);\n mkdirSync(backupDir, { recursive: true });\n\n const backedUpFiles: string[] = [];\n\n for (const filePath of filePaths) {\n if (!existsSync(filePath)) {continue;}\n\n // Flatten the path for storage: replace / with __ to keep it flat\n const safeName = filePath.replace(/\\//g, '__').replace(/:/g, '_');\n const destPath = join(backupDir, safeName);\n copyFileSync(filePath, destPath);\n backedUpFiles.push(filePath);\n }\n\n const meta: DevlinkBackup = {\n id,\n timestamp: new Date().toISOString(),\n description,\n files: backedUpFiles,\n modeAtBackup: currentMode,\n };\n\n writeFileSync(getMetaPath(backupDir), JSON.stringify(meta, null, 2) + '\\n', 'utf-8');\n\n // Auto-prune: keep only the 10 most recent backups\n pruneBackups(rootDir, 10);\n\n return meta;\n}\n\n/**\n * Lists all backups, sorted newest first.\n */\nexport function listBackups(rootDir: string): DevlinkBackup[] {\n const backupsDir = getBackupsDir(rootDir);\n if (!existsSync(backupsDir)) {return [];}\n\n const entries = readdirSync(backupsDir, { withFileTypes: true });\n const backups: DevlinkBackup[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {continue;}\n const metaPath = getMetaPath(join(backupsDir, entry.name));\n if (!existsSync(metaPath)) {continue;}\n\n try {\n const meta = JSON.parse(readFileSync(metaPath, 'utf-8')) as DevlinkBackup;\n backups.push(meta);\n } catch {\n // Skip corrupted backups\n }\n }\n\n return backups.sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n}\n\n/**\n * Returns the most recent backup, or null if none exist.\n */\nexport function getLastBackup(rootDir: string): DevlinkBackup | null {\n const backups = listBackups(rootDir);\n return backups[0] ?? null;\n}\n\n/**\n * Restores package.json files from a specific backup.\n */\nexport function restoreBackup(rootDir: string, backupId: string): { restored: number; errors: string[] } {\n const backupDir = join(getBackupsDir(rootDir), backupId);\n const metaPath = getMetaPath(backupDir);\n\n if (!existsSync(metaPath)) {\n throw new Error(`Backup ${backupId} not found`);\n }\n\n const meta = JSON.parse(readFileSync(metaPath, 'utf-8')) as DevlinkBackup;\n let restored = 0;\n const errors: string[] = [];\n\n for (const originalPath of meta.files) {\n const safeName = originalPath.replace(/\\//g, '__').replace(/:/g, '_');\n const srcPath = join(backupDir, safeName);\n\n if (!existsSync(srcPath)) {\n errors.push(`Backup file missing: ${safeName}`);\n continue;\n }\n\n try {\n mkdirSync(dirname(originalPath), { recursive: true });\n copyFileSync(srcPath, originalPath);\n restored++;\n } catch (err) {\n errors.push(`Failed to restore ${originalPath}: ${String(err)}`);\n }\n }\n\n return { restored, errors };\n}\n\n/**\n * Remove oldest backups beyond the retention limit.\n */\nexport function pruneBackups(rootDir: string, maxBackups = 10): number {\n const backups = listBackups(rootDir); // sorted newest first\n if (backups.length <= maxBackups) {return 0;}\n\n const backupsDir = getBackupsDir(rootDir);\n let pruned = 0;\n\n for (const old of backups.slice(maxBackups)) {\n const dir = join(backupsDir, old.id);\n try {\n rmSync(dir, { recursive: true, force: true });\n pruned++;\n } catch { /* skip */ }\n }\n\n return pruned;\n}\n","/**\n * Workspace YAML Manager\n *\n * Generates/updates pnpm-workspace.yaml in sub-repos to include\n * cross-repo paths needed for autonomous `cd sub-repo && pnpm install`.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { join, relative } from 'path';\nimport yaml from 'js-yaml';\nimport type { PackageMap } from '@kb-labs/devlink-contracts';\nimport type { MonorepoInfo } from '../discovery/index.js';\n\ninterface PnpmWorkspace {\n packages?: string[];\n}\n\ninterface PackageJson {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\nexport interface WorkspaceYamlUpdate {\n repoName: string;\n repoPath: string;\n added: string[];\n removed: string[];\n kept: string[];\n}\n\n/**\n * Update pnpm-workspace.yaml in all sub-repos to include correct cross-repo paths.\n *\n * For each sub-repo:\n * 1. Keep intra-repo patterns (packages/*, apps/*, etc.)\n * 2. Analyze which cross-repo packages are needed (from deps in all package.json)\n * 3. Compute correct relative paths to those packages\n * 4. Write updated workspace.yaml\n */\nexport function updateWorkspaceYamls(\n monorepos: MonorepoInfo[],\n packageMap: PackageMap,\n rootDir: string,\n options: { dryRun?: boolean } = {},\n): WorkspaceYamlUpdate[] {\n const updates: WorkspaceYamlUpdate[] = [];\n\n for (const mono of monorepos) {\n const wsPath = join(mono.rootPath, 'pnpm-workspace.yaml');\n\n // Skip repos without workspace yaml (standalone packages)\n if (!existsSync(wsPath)) {continue;}\n\n const update = updateOneWorkspaceYaml(mono, monorepos, packageMap, rootDir, options);\n if (update) {\n updates.push(update);\n }\n }\n\n return updates;\n}\n\nfunction updateOneWorkspaceYaml(\n mono: MonorepoInfo,\n allMonorepos: MonorepoInfo[],\n packageMap: PackageMap,\n rootDir: string,\n options: { dryRun?: boolean },\n): WorkspaceYamlUpdate | null {\n const wsPath = join(mono.rootPath, 'pnpm-workspace.yaml');\n\n // Read current workspace.yaml\n let workspace: PnpmWorkspace;\n try {\n workspace = yaml.load(readFileSync(wsPath, 'utf-8')) as PnpmWorkspace;\n } catch {\n return null;\n }\n\n const currentPatterns = workspace.packages ?? [];\n\n // Separate intra-repo patterns from cross-repo paths\n const intraPatterns: string[] = [];\n for (const pattern of currentPatterns) {\n // Intra-repo: doesn't start with ../ (relative to own root)\n if (!pattern.startsWith('../') && !pattern.startsWith('..\\\\')) {\n intraPatterns.push(pattern);\n }\n }\n\n // Find all cross-repo packages needed by this sub-repo\n const neededRepos = new Set<string>(); // monorepo names\n for (const pkgPath of mono.packagePaths) {\n if (!existsSync(pkgPath)) {continue;}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {continue;}\n\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n\n for (const depName of Object.keys(allDeps)) {\n const entry = packageMap[depName];\n if (!entry) {continue;}\n // Cross-repo dep: target is in a different monorepo\n if (entry.monorepo !== mono.name) {\n neededRepos.add(entry.monorepo);\n }\n }\n }\n\n // Compute cross-repo patterns\n const crossPatterns: string[] = [];\n for (const repoName of neededRepos) {\n const targetMono = allMonorepos.find(m => m.name === repoName);\n if (!targetMono) {continue;}\n\n const relPath = relative(mono.rootPath, targetMono.rootPath);\n\n if (targetMono.workspacePackages.length > 0) {\n // Monorepo: add patterns for its internal packages\n // e.g. \"../../infra/kb-labs-devkit\" for standalone\n // e.g. \"../../platform/kb-labs-core/packages/*\" for monorepos with packages/*\n for (const pattern of targetMono.workspacePackages) {\n crossPatterns.push(`${relPath}/${pattern}`);\n }\n } else {\n // Standalone: add direct path\n crossPatterns.push(relPath);\n }\n }\n\n // Sort and deduplicate\n crossPatterns.sort();\n const newPatterns = [...intraPatterns, ...crossPatterns];\n\n // Check if anything changed\n const oldSet = new Set(currentPatterns);\n const newSet = new Set(newPatterns);\n const added = crossPatterns.filter(p => !oldSet.has(p));\n const removed = currentPatterns.filter(p => p.startsWith('../') && !newSet.has(p));\n const kept = intraPatterns;\n\n if (added.length === 0 && removed.length === 0) {\n return null; // No changes needed\n }\n\n // Write updated workspace.yaml\n if (!options.dryRun) {\n const output: PnpmWorkspace = { packages: newPatterns };\n writeFileSync(wsPath, yaml.dump(output, { lineWidth: -1, quotingType: '\"' }), 'utf-8');\n }\n\n return {\n repoName: mono.name,\n repoPath: mono.rootPath,\n added,\n removed,\n kept,\n };\n}\n","/**\n * Diagnostics — detect broken deps, stale lockfiles, cross-repo workspace:* issues\n */\n\nimport { readFileSync, existsSync, statSync } from 'fs';\nimport { join, dirname, resolve } from 'path';\nimport type { DiagnosticIssue, PackageMap } from '@kb-labs/devlink-contracts';\nimport type { MonorepoInfo } from '../discovery/index.js';\nimport { resolvePackageMonorepo } from '../discovery/index.js';\n\ninterface PackageJson {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\n/**\n * Run all diagnostic checks across the monorepo.\n */\nexport function diagnose(\n monorepos: MonorepoInfo[],\n packageMap: PackageMap,\n rootDir: string,\n): DiagnosticIssue[] {\n const issues: DiagnosticIssue[] = [];\n\n for (const mono of monorepos) {\n for (const pkgPath of mono.packagePaths) {\n if (!existsSync(pkgPath)) {continue;}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {continue;}\n\n const sections = [pkg.dependencies, pkg.devDependencies, pkg.peerDependencies];\n for (const section of sections) {\n if (!section) {continue;}\n for (const [depName, depValue] of Object.entries(section)) {\n // Check broken link: paths\n if (depValue.startsWith('link:')) {\n const targetPath = resolve(dirname(pkgPath), depValue.slice(5));\n if (!existsSync(targetPath)) {\n issues.push({\n type: 'broken-link',\n severity: 'error',\n file: pkgPath,\n dep: depName,\n message: `${depName}: link:${depValue.slice(5)} → target does not exist`,\n fix: 'Run devlink switch --mode=local to recalculate paths',\n });\n }\n }\n\n // Check cross-repo workspace:*\n if (depValue.startsWith('workspace:') && packageMap[depName]) {\n const consumerMono = resolvePackageMonorepo(pkgPath, monorepos);\n const depMonorepo = packageMap[depName]!.monorepo;\n if (consumerMono && consumerMono.name !== depMonorepo) {\n issues.push({\n type: 'cross-repo-workspace',\n severity: 'warning',\n file: pkgPath,\n dep: depName,\n message: `${depName}: workspace:* crosses sub-repo boundary (${consumerMono.name} → ${depMonorepo})`,\n fix: 'Run devlink switch --mode=local to convert to link:',\n });\n }\n }\n }\n }\n }\n\n // Check stale lockfile\n checkStaleLockfile(mono, issues);\n }\n\n // Sort: errors first, then warnings\n issues.sort((a, b) => {\n if (a.severity !== b.severity) {return a.severity === 'error' ? -1 : 1;}\n return a.type.localeCompare(b.type);\n });\n\n return issues;\n}\n\n/**\n * Check if a sub-repo's lockfile is stale (older than any package.json).\n */\nfunction checkStaleLockfile(mono: MonorepoInfo, issues: DiagnosticIssue[]): void {\n const lockPath = join(mono.rootPath, 'pnpm-lock.yaml');\n if (!existsSync(lockPath)) {return;}\n\n let lockMtime: number;\n try {\n lockMtime = statSync(lockPath).mtimeMs;\n } catch {return;}\n\n for (const pkgPath of mono.packagePaths) {\n try {\n const pkgMtime = statSync(pkgPath).mtimeMs;\n if (pkgMtime > lockMtime) {\n issues.push({\n type: 'stale-lockfile',\n severity: 'warning',\n file: lockPath,\n message: `${mono.name}: pnpm-lock.yaml is older than ${pkgPath}`,\n fix: 'Delete lockfile and run pnpm install, or use devlink switch --install',\n });\n return; // One warning per repo is enough\n }\n } catch { /* skip */ }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../home/runner/work/kb-labs/kb-labs/plugins/devlink/core/src/npm/index.ts","../../home/runner/work/kb-labs/kb-labs/plugins/devlink/core/src/discovery/index.ts","../../home/runner/work/kb-labs/kb-labs/plugins/devlink/core/src/plan/index.ts","../../home/runner/work/kb-labs/kb-labs/plugins/devlink/core/src/apply/index.ts","../../home/runner/work/kb-labs/kb-labs/plugins/devlink/core/src/state/index.ts","../../home/runner/work/kb-labs/kb-labs/plugins/devlink/core/src/backup/index.ts","../../home/runner/work/kb-labs/kb-labs/plugins/devlink/core/src/workspace-yaml/index.ts","../../home/runner/work/kb-labs/kb-labs/plugins/devlink/core/src/diagnostics/index.ts"],"names":["yaml","existsSync","readFileSync","relative","dirname","join","writeFileSync","mkdirSync","readdirSync","resolve"],"mappings":"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","file":"index.js","sourcesContent":["import { spawnSync } from 'child_process';\nimport { useCache } from '@kb-labs/sdk';\n\n/** Default TTL: 24 hours */\nconst DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Returns the latest published version of a package on npm, or null if not published.\n * Results are cached via useCache() with the given TTL.\n */\nexport async function getLatestNpmVersion(\n packageName: string,\n ttlMs = DEFAULT_TTL_MS\n): Promise<string | null> {\n const cacheKey = `devlink:npm-version:${packageName}`;\n const cache = useCache();\n\n if (cache) {\n const cached = await cache.get<string | null>(cacheKey);\n // cache.get returns null for missing keys — only return if explicitly cached\n if (cached !== null && cached !== undefined) {return cached;}\n }\n\n let version: string | null;\n // spawnSync passes packageName as a discrete argv element — the OS never\n // interprets it as a shell command, preventing command injection.\n const proc = spawnSync('npm', ['view', packageName, 'version', '--json'], {\n encoding: 'utf-8',\n timeout: 10_000,\n });\n if (proc.error || proc.status !== 0 || !proc.stdout?.trim()) {\n version = null;\n } else {\n try {\n // npm view returns a JSON string like \"1.4.0\" (with quotes)\n version = JSON.parse(proc.stdout.trim()) as string;\n } catch {\n version = null;\n }\n }\n\n if (cache) {\n await cache.set(cacheKey, version, ttlMs);\n }\n\n return version;\n}\n\n/**\n * Checks if a package exists on the npm registry.\n * Results are cached via useCache() with the given TTL.\n */\nexport async function isPublishedOnNpm(\n packageName: string,\n ttlMs = DEFAULT_TTL_MS\n): Promise<boolean> {\n return (await getLatestNpmVersion(packageName, ttlMs)) !== null;\n}\n\n/**\n * Filters a list of package names to only those published on npm.\n * Runs checks concurrently.\n */\nexport async function filterPublishedPackages(\n packageNames: string[],\n ttlMs = DEFAULT_TTL_MS\n): Promise<Set<string>> {\n const results = await Promise.all(\n packageNames.map(async name => ({\n name,\n published: await isPublishedOnNpm(name, ttlMs),\n }))\n );\n\n return new Set(results.filter(r => r.published).map(r => r.name));\n}\n","import { readFileSync, existsSync, readdirSync } from 'fs';\nimport { join, relative, dirname } from 'path';\nimport yaml from 'js-yaml';\nimport { discoverSubRepoPaths } from '@kb-labs/sdk';\nimport type { PackageMap, PackageEntry, DevlinkMode } from '@kb-labs/devlink-contracts';\nimport { getLatestNpmVersion } from '../npm/index.js';\n\ninterface PnpmWorkspace {\n packages?: string[];\n}\n\ninterface PackageJson {\n name?: string;\n version?: string;\n private?: boolean;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\n/** Monorepo info discovered on disk */\nexport interface MonorepoInfo {\n /** Dir name e.g. kb-labs-core */\n name: string;\n /** Absolute path to the monorepo root */\n rootPath: string;\n /** All package.json paths within the monorepo */\n packagePaths: string[];\n /** pnpm-workspace.yaml content */\n workspacePackages: string[];\n}\n\n/**\n * Discovers all submodule repos via .gitmodules (layout-agnostic).\n * Includes both monorepos (with pnpm-workspace.yaml) and standalone packages.\n */\nexport function discoverMonorepos(rootDir: string): MonorepoInfo[] {\n const subRepoPaths = discoverSubRepoPaths(rootDir);\n const monorepos: MonorepoInfo[] = [];\n\n for (const repoPath of subRepoPaths) {\n const repoName = repoPath.split('/').pop() ?? repoPath;\n const hasWorkspace = existsSync(join(repoPath, 'pnpm-workspace.yaml'));\n\n if (hasWorkspace) {\n // Monorepo: scan all package.json files\n const packagePaths = findPackageJsonFiles(repoPath);\n const repoWorkspace = yaml.load(\n readFileSync(join(repoPath, 'pnpm-workspace.yaml'), 'utf-8')\n ) as PnpmWorkspace;\n\n // Only keep intra-repo patterns (not cross-repo paths starting with ../)\n // Cross-repo paths are computed fresh each run — keeping stale ones causes\n // exponential growth where each run re-expands previously generated paths.\n const intraPatterns = (repoWorkspace.packages ?? []).filter(\n p => !p.startsWith('../') && !p.startsWith('..\\\\')\n );\n\n monorepos.push({\n name: repoName,\n rootPath: repoPath,\n packagePaths,\n workspacePackages: intraPatterns,\n });\n } else {\n // Standalone package (e.g. devkit): treat root package.json as sole package\n const rootPkgPath = join(repoPath, 'package.json');\n if (existsSync(rootPkgPath)) {\n monorepos.push({\n name: repoName,\n rootPath: repoPath,\n packagePaths: [rootPkgPath],\n workspacePackages: [],\n });\n }\n }\n }\n\n return monorepos;\n}\n\n/**\n * Builds a PackageMap: packageName → { linkPath, npmVersion, monorepo }.\n * Scans all packages in all monorepos and collects their name/version.\n *\n * linkPath is relative to the root kb-labs/ dir (so it can be used as link:../path).\n */\nexport function buildPackageMap(monorepos: MonorepoInfo[], rootDir: string): PackageMap {\n const map: PackageMap = {};\n\n for (const monorepo of monorepos) {\n for (const pkgPath of monorepo.packagePaths) {\n if (!existsSync(pkgPath)) {continue;}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {\n continue;\n }\n\n if (!pkg.name || !pkg.version) {continue;}\n // Only include @kb-labs/* packages (or non-scoped kb-labs-* packages)\n if (!pkg.name.startsWith('@kb-labs/') && !pkg.name.startsWith('kb-labs-')) {continue;}\n\n const pkgDir = dirname(pkgPath);\n const linkPath = relative(rootDir, pkgDir);\n\n const entry: PackageEntry = {\n name: pkg.name,\n linkPath,\n npmVersion: `^${pkg.version}`,\n monorepo: monorepo.name,\n private: pkg.private ?? false,\n };\n\n map[pkg.name] = entry;\n }\n }\n\n return map;\n}\n\n/**\n * Async version of buildPackageMap that verifies each package exists on npm.\n * For 'local' mode skips the npm check and returns all packages found on disk.\n * For 'npm'/'auto'/undefined filters out packages not published to the registry.\n */\nexport async function buildPackageMapFiltered(\n monorepos: MonorepoInfo[],\n rootDir: string,\n ttlMs?: number,\n mode?: DevlinkMode\n): Promise<PackageMap> {\n const rawMap = buildPackageMap(monorepos, rootDir);\n // local mode: disk has priority, no npm check needed\n if (mode === 'local') {return rawMap;}\n const packageNames = Object.keys(rawMap);\n // Fetch latest published versions concurrently\n const versionResults = await Promise.all(\n packageNames.map(async name => ({\n name,\n version: await getLatestNpmVersion(name, ttlMs),\n }))\n );\n const filtered: PackageMap = {};\n for (const { name, version } of versionResults) {\n if (version !== null) {\n filtered[name] = { ...rawMap[name]!, npmVersion: `^${version}` };\n }\n }\n return filtered;\n}\n\n/**\n * Determines the current linking mode of cross-repo dependencies in a package.json.\n * Returns counts of link:, npm, workspace: references for @kb-labs/* deps.\n */\nexport function analyzePackageDeps(\n pkgPath: string,\n packageMap: PackageMap\n): { linkCount: number; npmCount: number; workspaceCount: number; unknownCount: number } {\n let linkCount = 0;\n let npmCount = 0;\n let workspaceCount = 0;\n let unknownCount = 0;\n\n if (!existsSync(pkgPath)) {return { linkCount, npmCount, workspaceCount, unknownCount };}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {\n return { linkCount, npmCount, workspaceCount, unknownCount };\n }\n\n const sections = [pkg.dependencies, pkg.devDependencies, pkg.peerDependencies];\n for (const section of sections) {\n if (!section) {continue;}\n for (const [depName, depValue] of Object.entries(section)) {\n if (!packageMap[depName]) {continue;} // Not a cross-repo dep\n if (depValue.startsWith('link:')) {\n linkCount++;\n } else if (depValue.startsWith('workspace:')) {\n workspaceCount++;\n } else if (depValue.startsWith('^') || depValue.startsWith('~') || /^\\d/.test(depValue)) {\n npmCount++;\n } else {\n unknownCount++;\n }\n }\n }\n\n return { linkCount, npmCount, workspaceCount, unknownCount };\n}\n\n/**\n * Finds all package.json files within a monorepo (excludes node_modules, dist).\n */\nfunction findPackageJsonFiles(repoRoot: string): string[] {\n const results: string[] = [];\n\n function walk(dir: string, depth = 0) {\n if (depth > 4) {return;}\n\n let entries: import('fs').Dirent<string>[];\n try {\n entries = readdirSync(dir, { withFileTypes: true, encoding: 'utf-8' });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git') {continue;}\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n walk(full, depth + 1);\n } else if (entry.name === 'package.json') {\n results.push(full);\n }\n }\n }\n\n walk(repoRoot);\n return results;\n}\n\n/**\n * Determines which MonorepoInfo a package.json belongs to.\n * Uses rootPath prefix matching.\n */\nexport function resolvePackageMonorepo(\n pkgPath: string,\n monorepos: MonorepoInfo[]\n): MonorepoInfo | null {\n for (const mono of monorepos) {\n if (pkgPath.startsWith(mono.rootPath + '/') || pkgPath === join(mono.rootPath, 'package.json')) {\n return mono;\n }\n }\n return null;\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { relative, dirname, resolve } from 'path';\nimport type {\n DevlinkMode,\n DevlinkPlan,\n DevlinkPlanItem,\n PackageEntry,\n PackageMap,\n} from '@kb-labs/devlink-contracts';\nimport type { MonorepoInfo } from '../discovery/index.js';\nimport { resolvePackageMonorepo } from '../discovery/index.js';\n\ntype DepSection = 'dependencies' | 'devDependencies' | 'peerDependencies';\n\ninterface PackageJson {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\n/**\n * Builds a DevlinkPlan — all package.json changes needed for the target mode.\n */\nexport function buildPlan(\n mode: DevlinkMode,\n packageMap: PackageMap,\n monorepos: MonorepoInfo[],\n rootDir: string,\n options: { scopedRepos?: string[] } = {}\n): DevlinkPlan {\n const items: DevlinkPlanItem[] = [];\n const filteredMonorepos = options.scopedRepos?.length\n ? monorepos.filter(m => options.scopedRepos!.includes(m.name))\n : monorepos;\n\n for (const monorepo of filteredMonorepos) {\n for (const pkgPath of monorepo.packagePaths) {\n if (!existsSync(pkgPath)) {continue;}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {\n continue;\n }\n\n const sections: DepSection[] = ['dependencies', 'devDependencies', 'peerDependencies'];\n for (const section of sections) {\n const deps = pkg[section];\n if (!deps) {continue;}\n\n for (const [depName, currentValue] of Object.entries(deps)) {\n const entry = packageMap[depName];\n if (!entry) {continue;} // Not a cross-repo dep\n\n // Skip bare * — ambiguous wildcard, not a versioned dep we manage\n if (currentValue === '*') {continue;}\n\n // workspace:* — only skip if intra-repo (same monorepo handles it via pnpm)\n // Cross-repo workspace:* must be converted to link: or ^version\n if (currentValue.startsWith('workspace:')) {\n const consumerMono = resolvePackageMonorepo(pkgPath, monorepos);\n if (consumerMono && consumerMono.name === entry.monorepo) {continue;}\n }\n\n const targetValue = getTargetValue(mode, entry, pkgPath, rootDir);\n if (targetValue === currentValue) {continue;} // Already correct\n\n items.push({\n packageJsonPath: pkgPath,\n packageJsonRel: relative(rootDir, pkgPath),\n monorepo: monorepo.name,\n depName,\n from: currentValue,\n to: targetValue,\n section,\n });\n }\n }\n }\n }\n\n return {\n mode,\n items,\n timestamp: new Date().toISOString(),\n ...(options.scopedRepos?.length ? { scopedRepos: options.scopedRepos } : {}),\n };\n}\n\n/**\n * Computes the target value for a dependency based on mode.\n * Private packages always stay as link: (not published to npm).\n */\nfunction getTargetValue(\n mode: DevlinkMode,\n entry: PackageEntry,\n fromPackageJson: string,\n rootDir: string\n): string {\n // npm mode: use ^version, but private packages stay as link: (not on npm)\n if (mode === 'npm' && !entry.private) {\n return entry.npmVersion;\n }\n\n // local, auto, or private in npm mode: use link: path\n const fromDir = dirname(fromPackageJson);\n const targetDir = resolve(rootDir, entry.linkPath);\n const relPath = relative(fromDir, targetDir);\n const normalized = relPath.startsWith('.') ? relPath : `./${relPath}`;\n return `link:${normalized}`;\n}\n\n/**\n * Returns a human-readable description of a plan item change.\n */\nexport function describeChange(item: DevlinkPlanItem): string {\n return `${item.depName}: ${item.from} → ${item.to}`;\n}\n\n/**\n * Groups plan items by monorepo for display purposes.\n */\nexport function groupByMonorepo(items: DevlinkPlanItem[]): Map<string, DevlinkPlanItem[]> {\n const groups = new Map<string, DevlinkPlanItem[]>();\n for (const item of items) {\n if (!groups.has(item.monorepo)) {groups.set(item.monorepo, []);}\n groups.get(item.monorepo)!.push(item);\n }\n return groups;\n}\n","import { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { execSync } from 'child_process';\nimport type { DevlinkPlan } from '@kb-labs/devlink-contracts';\n\ntype DepSection = 'dependencies' | 'devDependencies' | 'peerDependencies';\n\ninterface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n [key: string]: unknown;\n}\n\nexport interface ApplyOptions {\n dryRun?: boolean;\n}\n\nexport interface ApplyResult {\n applied: number;\n skipped: number;\n errors: Array<{ file: string; error: string }>;\n}\n\n/**\n * Applies a DevlinkPlan to package.json files on disk.\n * Groups changes by file to minimize I/O operations.\n */\nexport async function applyPlan(plan: DevlinkPlan, options: ApplyOptions = {}): Promise<ApplyResult> {\n const { dryRun = false } = options;\n\n // Group items by packageJsonPath\n const byFile = new Map<string, typeof plan.items>();\n for (const item of plan.items) {\n if (!byFile.has(item.packageJsonPath)) {byFile.set(item.packageJsonPath, []);}\n byFile.get(item.packageJsonPath)!.push(item);\n }\n\n let applied = 0;\n let skipped = 0;\n const errors: ApplyResult['errors'] = [];\n\n for (const [filePath, items] of byFile.entries()) {\n if (!existsSync(filePath)) {\n skipped++;\n continue;\n }\n\n if (dryRun) {\n applied += items.length;\n continue;\n }\n\n try {\n const raw = readFileSync(filePath, 'utf-8');\n const pkg = JSON.parse(raw) as PackageJson;\n\n for (const item of items) {\n const section = pkg[item.section as DepSection];\n if (section && item.depName in section) {\n section[item.depName] = item.to;\n applied++;\n } else {\n skipped++;\n }\n }\n\n // Write back with same trailing newline and 2-space indent\n const trailingNewline = raw.endsWith('\\n') ? '\\n' : '';\n writeFileSync(filePath, JSON.stringify(pkg, null, 2) + trailingNewline, 'utf-8');\n } catch (err) {\n errors.push({ file: filePath, error: String(err) });\n }\n }\n\n return { applied, skipped, errors };\n}\n\n/**\n * Checks if the given directory has uncommitted git changes.\n * Returns a list of modified files, or empty array if clean.\n */\nexport function checkGitDirty(repoPath: string): string[] {\n try {\n const output = execSync('git status --porcelain', {\n cwd: repoPath,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return output\n .split('\\n')\n .filter(Boolean)\n .map(line => line.slice(3).trim());\n } catch {\n return []; // Not a git repo or git not available\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport type { DevlinkState, DevlinkPlan } from '@kb-labs/devlink-contracts';\n\nconst DEFAULT_STATE: DevlinkState = {\n currentMode: null,\n lastApplied: null,\n frozenAt: null,\n};\n\nfunction getStatePath(rootDir: string): string {\n return join(rootDir, '.kb', 'devlink', 'state.json');\n}\n\nfunction getLockPath(rootDir: string): string {\n return join(rootDir, '.kb', 'devlink', 'lock.json');\n}\n\nfunction ensureDir(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\n// ─── State ────────────────────────────────────────────────────────────────────\n\nexport function loadState(rootDir: string): DevlinkState {\n const statePath = getStatePath(rootDir);\n if (!existsSync(statePath)) {return { ...DEFAULT_STATE };}\n\n try {\n return JSON.parse(readFileSync(statePath, 'utf-8')) as DevlinkState;\n } catch {\n return { ...DEFAULT_STATE };\n }\n}\n\nexport function saveState(rootDir: string, state: DevlinkState): void {\n const statePath = getStatePath(rootDir);\n ensureDir(statePath);\n writeFileSync(statePath, JSON.stringify(state, null, 2) + '\\n', 'utf-8');\n}\n\n// ─── Lock / Freeze ────────────────────────────────────────────────────────────\n\nexport interface LockFile {\n frozenAt: string;\n plan: DevlinkPlan;\n}\n\nexport function freeze(rootDir: string, currentPlan: DevlinkPlan): LockFile {\n const lock: LockFile = {\n frozenAt: new Date().toISOString(),\n plan: currentPlan,\n };\n\n const lockPath = getLockPath(rootDir);\n ensureDir(lockPath);\n writeFileSync(lockPath, JSON.stringify(lock, null, 2) + '\\n', 'utf-8');\n\n // Update state.frozenAt\n const state = loadState(rootDir);\n saveState(rootDir, { ...state, frozenAt: lock.frozenAt });\n\n return lock;\n}\n\nexport function loadLock(rootDir: string): LockFile | null {\n const lockPath = getLockPath(rootDir);\n if (!existsSync(lockPath)) {return null;}\n\n try {\n return JSON.parse(readFileSync(lockPath, 'utf-8')) as LockFile;\n } catch {\n return null;\n }\n}\n","import {\n readFileSync,\n writeFileSync,\n mkdirSync,\n existsSync,\n readdirSync,\n copyFileSync,\n rmSync,\n} from 'fs';\nimport { join, dirname } from 'path';\nimport type { DevlinkBackup, DevlinkMode } from '@kb-labs/devlink-contracts';\n\nfunction getBackupsDir(rootDir: string): string {\n return join(rootDir, '.kb', 'devlink', 'backups');\n}\n\nfunction getMetaPath(backupDir: string): string {\n return join(backupDir, 'meta.json');\n}\n\n/**\n * Creates a backup of given package.json files before a mutation.\n * Returns the backup metadata.\n */\nexport function createBackup(\n rootDir: string,\n filePaths: string[],\n description: string,\n currentMode: DevlinkMode | null\n): DevlinkBackup {\n const id = `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n const backupDir = join(getBackupsDir(rootDir), id);\n mkdirSync(backupDir, { recursive: true });\n\n const backedUpFiles: string[] = [];\n\n for (const filePath of filePaths) {\n if (!existsSync(filePath)) {continue;}\n\n // Flatten the path for storage: replace / with __ to keep it flat\n const safeName = filePath.replace(/\\//g, '__').replace(/:/g, '_');\n const destPath = join(backupDir, safeName);\n copyFileSync(filePath, destPath);\n backedUpFiles.push(filePath);\n }\n\n const meta: DevlinkBackup = {\n id,\n timestamp: new Date().toISOString(),\n description,\n files: backedUpFiles,\n modeAtBackup: currentMode,\n };\n\n writeFileSync(getMetaPath(backupDir), JSON.stringify(meta, null, 2) + '\\n', 'utf-8');\n\n // Auto-prune: keep only the 10 most recent backups\n pruneBackups(rootDir, 10);\n\n return meta;\n}\n\n/**\n * Lists all backups, sorted newest first.\n */\nexport function listBackups(rootDir: string): DevlinkBackup[] {\n const backupsDir = getBackupsDir(rootDir);\n if (!existsSync(backupsDir)) {return [];}\n\n const entries = readdirSync(backupsDir, { withFileTypes: true });\n const backups: DevlinkBackup[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {continue;}\n const metaPath = getMetaPath(join(backupsDir, entry.name));\n if (!existsSync(metaPath)) {continue;}\n\n try {\n const meta = JSON.parse(readFileSync(metaPath, 'utf-8')) as DevlinkBackup;\n backups.push(meta);\n } catch {\n // Skip corrupted backups\n }\n }\n\n return backups.sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n}\n\n/**\n * Returns the most recent backup, or null if none exist.\n */\nexport function getLastBackup(rootDir: string): DevlinkBackup | null {\n const backups = listBackups(rootDir);\n return backups[0] ?? null;\n}\n\n/**\n * Restores package.json files from a specific backup.\n */\nexport function restoreBackup(rootDir: string, backupId: string): { restored: number; errors: string[] } {\n const backupDir = join(getBackupsDir(rootDir), backupId);\n const metaPath = getMetaPath(backupDir);\n\n if (!existsSync(metaPath)) {\n throw new Error(`Backup ${backupId} not found`);\n }\n\n const meta = JSON.parse(readFileSync(metaPath, 'utf-8')) as DevlinkBackup;\n let restored = 0;\n const errors: string[] = [];\n\n for (const originalPath of meta.files) {\n const safeName = originalPath.replace(/\\//g, '__').replace(/:/g, '_');\n const srcPath = join(backupDir, safeName);\n\n if (!existsSync(srcPath)) {\n errors.push(`Backup file missing: ${safeName}`);\n continue;\n }\n\n try {\n mkdirSync(dirname(originalPath), { recursive: true });\n copyFileSync(srcPath, originalPath);\n restored++;\n } catch (err) {\n errors.push(`Failed to restore ${originalPath}: ${String(err)}`);\n }\n }\n\n return { restored, errors };\n}\n\n/**\n * Remove oldest backups beyond the retention limit.\n */\nexport function pruneBackups(rootDir: string, maxBackups = 10): number {\n const backups = listBackups(rootDir); // sorted newest first\n if (backups.length <= maxBackups) {return 0;}\n\n const backupsDir = getBackupsDir(rootDir);\n let pruned = 0;\n\n for (const old of backups.slice(maxBackups)) {\n const dir = join(backupsDir, old.id);\n try {\n rmSync(dir, { recursive: true, force: true });\n pruned++;\n } catch { /* skip */ }\n }\n\n return pruned;\n}\n","/**\n * Workspace YAML Manager\n *\n * Generates/updates pnpm-workspace.yaml in sub-repos to include\n * cross-repo paths needed for autonomous `cd sub-repo && pnpm install`.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { join, relative } from 'path';\nimport yaml from 'js-yaml';\nimport type { PackageMap } from '@kb-labs/devlink-contracts';\nimport type { MonorepoInfo } from '../discovery/index.js';\n\ninterface PnpmWorkspace {\n packages?: string[];\n}\n\ninterface PackageJson {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\nexport interface WorkspaceYamlUpdate {\n repoName: string;\n repoPath: string;\n added: string[];\n removed: string[];\n kept: string[];\n}\n\n/**\n * Update pnpm-workspace.yaml in all sub-repos to include correct cross-repo paths.\n *\n * For each sub-repo:\n * 1. Keep intra-repo patterns (packages/*, apps/*, etc.)\n * 2. Analyze which cross-repo packages are needed (from deps in all package.json)\n * 3. Compute correct relative paths to those packages\n * 4. Write updated workspace.yaml\n */\nexport function updateWorkspaceYamls(\n monorepos: MonorepoInfo[],\n packageMap: PackageMap,\n rootDir: string,\n options: { dryRun?: boolean } = {},\n): WorkspaceYamlUpdate[] {\n const updates: WorkspaceYamlUpdate[] = [];\n\n for (const mono of monorepos) {\n const wsPath = join(mono.rootPath, 'pnpm-workspace.yaml');\n\n // Skip repos without workspace yaml (standalone packages)\n if (!existsSync(wsPath)) {continue;}\n\n const update = updateOneWorkspaceYaml(mono, monorepos, packageMap, rootDir, options);\n if (update) {\n updates.push(update);\n }\n }\n\n return updates;\n}\n\nfunction updateOneWorkspaceYaml(\n mono: MonorepoInfo,\n allMonorepos: MonorepoInfo[],\n packageMap: PackageMap,\n rootDir: string,\n options: { dryRun?: boolean },\n): WorkspaceYamlUpdate | null {\n const wsPath = join(mono.rootPath, 'pnpm-workspace.yaml');\n\n // Read current workspace.yaml\n let workspace: PnpmWorkspace;\n try {\n workspace = yaml.load(readFileSync(wsPath, 'utf-8')) as PnpmWorkspace;\n } catch {\n return null;\n }\n\n const currentPatterns = workspace.packages ?? [];\n\n // Separate intra-repo patterns from cross-repo paths\n const intraPatterns: string[] = [];\n for (const pattern of currentPatterns) {\n // Intra-repo: doesn't start with ../ (relative to own root)\n if (!pattern.startsWith('../') && !pattern.startsWith('..\\\\')) {\n intraPatterns.push(pattern);\n }\n }\n\n // Find all cross-repo packages needed by this sub-repo\n const neededRepos = new Set<string>(); // monorepo names\n for (const pkgPath of mono.packagePaths) {\n if (!existsSync(pkgPath)) {continue;}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {continue;}\n\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n ...pkg.peerDependencies,\n };\n\n for (const depName of Object.keys(allDeps)) {\n const entry = packageMap[depName];\n if (!entry) {continue;}\n // Cross-repo dep: target is in a different monorepo\n if (entry.monorepo !== mono.name) {\n neededRepos.add(entry.monorepo);\n }\n }\n }\n\n // Compute cross-repo patterns\n const crossPatterns: string[] = [];\n for (const repoName of neededRepos) {\n const targetMono = allMonorepos.find(m => m.name === repoName);\n if (!targetMono) {continue;}\n\n const relPath = relative(mono.rootPath, targetMono.rootPath);\n\n if (targetMono.workspacePackages.length > 0) {\n // Monorepo: add patterns for its internal packages\n // e.g. \"../../infra/kb-labs-devkit\" for standalone\n // e.g. \"../../platform/kb-labs-core/packages/*\" for monorepos with packages/*\n for (const pattern of targetMono.workspacePackages) {\n crossPatterns.push(`${relPath}/${pattern}`);\n }\n } else {\n // Standalone: add direct path\n crossPatterns.push(relPath);\n }\n }\n\n // Sort and deduplicate\n crossPatterns.sort();\n const newPatterns = [...intraPatterns, ...crossPatterns];\n\n // Check if anything changed\n const oldSet = new Set(currentPatterns);\n const newSet = new Set(newPatterns);\n const added = crossPatterns.filter(p => !oldSet.has(p));\n const removed = currentPatterns.filter(p => p.startsWith('../') && !newSet.has(p));\n const kept = intraPatterns;\n\n if (added.length === 0 && removed.length === 0) {\n return null; // No changes needed\n }\n\n // Write updated workspace.yaml\n if (!options.dryRun) {\n const output: PnpmWorkspace = { packages: newPatterns };\n writeFileSync(wsPath, yaml.dump(output, { lineWidth: -1, quotingType: '\"' }), 'utf-8');\n }\n\n return {\n repoName: mono.name,\n repoPath: mono.rootPath,\n added,\n removed,\n kept,\n };\n}\n","/**\n * Diagnostics — detect broken deps, stale lockfiles, cross-repo workspace:* issues\n */\n\nimport { readFileSync, existsSync, statSync } from 'fs';\nimport { join, dirname, resolve } from 'path';\nimport type { DiagnosticIssue, PackageMap } from '@kb-labs/devlink-contracts';\nimport type { MonorepoInfo } from '../discovery/index.js';\nimport { resolvePackageMonorepo } from '../discovery/index.js';\n\ninterface PackageJson {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\n/**\n * Run all diagnostic checks across the monorepo.\n */\nexport function diagnose(\n monorepos: MonorepoInfo[],\n packageMap: PackageMap,\n rootDir: string,\n): DiagnosticIssue[] {\n const issues: DiagnosticIssue[] = [];\n\n for (const mono of monorepos) {\n for (const pkgPath of mono.packagePaths) {\n if (!existsSync(pkgPath)) {continue;}\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PackageJson;\n } catch {continue;}\n\n const sections = [pkg.dependencies, pkg.devDependencies, pkg.peerDependencies];\n for (const section of sections) {\n if (!section) {continue;}\n for (const [depName, depValue] of Object.entries(section)) {\n // Check broken link: paths\n if (depValue.startsWith('link:')) {\n const targetPath = resolve(dirname(pkgPath), depValue.slice(5));\n if (!existsSync(targetPath)) {\n issues.push({\n type: 'broken-link',\n severity: 'error',\n file: pkgPath,\n dep: depName,\n message: `${depName}: link:${depValue.slice(5)} → target does not exist`,\n fix: 'Run devlink switch --mode=local to recalculate paths',\n });\n }\n }\n\n // Check cross-repo workspace:*\n if (depValue.startsWith('workspace:') && packageMap[depName]) {\n const consumerMono = resolvePackageMonorepo(pkgPath, monorepos);\n const depMonorepo = packageMap[depName]!.monorepo;\n if (consumerMono && consumerMono.name !== depMonorepo) {\n issues.push({\n type: 'cross-repo-workspace',\n severity: 'warning',\n file: pkgPath,\n dep: depName,\n message: `${depName}: workspace:* crosses sub-repo boundary (${consumerMono.name} → ${depMonorepo})`,\n fix: 'Run devlink switch --mode=local to convert to link:',\n });\n }\n }\n }\n }\n }\n\n // Check stale lockfile\n checkStaleLockfile(mono, issues);\n }\n\n // Sort: errors first, then warnings\n issues.sort((a, b) => {\n if (a.severity !== b.severity) {return a.severity === 'error' ? -1 : 1;}\n return a.type.localeCompare(b.type);\n });\n\n return issues;\n}\n\n/**\n * Check if a sub-repo's lockfile is stale (older than any package.json).\n */\nfunction checkStaleLockfile(mono: MonorepoInfo, issues: DiagnosticIssue[]): void {\n const lockPath = join(mono.rootPath, 'pnpm-lock.yaml');\n if (!existsSync(lockPath)) {return;}\n\n let lockMtime: number;\n try {\n lockMtime = statSync(lockPath).mtimeMs;\n } catch {return;}\n\n for (const pkgPath of mono.packagePaths) {\n try {\n const pkgMtime = statSync(pkgPath).mtimeMs;\n if (pkgMtime > lockMtime) {\n issues.push({\n type: 'stale-lockfile',\n severity: 'warning',\n file: lockPath,\n message: `${mono.name}: pnpm-lock.yaml is older than ${pkgPath}`,\n fix: 'Delete lockfile and run pnpm install, or use devlink switch --install',\n });\n return; // One warning per repo is enough\n }\n } catch { /* skip */ }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/devlink-core",
|
|
3
3
|
"description": "Core business logic for DevLink plugin — discovery, plan, apply, state, backup.",
|
|
4
|
-
"version": "2.119.0
|
|
4
|
+
"version": "2.119.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"js-yaml": "^4.2.0",
|
|
21
21
|
"zod": "^3.25.76",
|
|
22
|
-
"@kb-labs/devlink-contracts": "2.119.0
|
|
22
|
+
"@kb-labs/devlink-contracts": "2.119.0",
|
|
23
23
|
"@kb-labs/sdk": "2.115.4"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"tsup": "^8.5.0",
|
|
31
31
|
"typescript": "^5.6.3",
|
|
32
32
|
"vitest": "^3.2.6",
|
|
33
|
-
"@kb-labs/devkit": "2.119.0
|
|
33
|
+
"@kb-labs/devkit": "2.119.0"
|
|
34
34
|
},
|
|
35
35
|
"engines": {
|
|
36
|
-
"node": ">=
|
|
36
|
+
"node": ">=24.0.0",
|
|
37
37
|
"pnpm": ">=9.0.0"
|
|
38
38
|
},
|
|
39
39
|
"sideEffects": false,
|