@kb-labs/scaffold-core 2.29.0 → 2.30.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 +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -358,7 +358,8 @@ const permissions = ${permExpr};
|
|
|
358
358
|
|
|
359
359
|
const manifest = ${body} as const;
|
|
360
360
|
|
|
361
|
-
|
|
361
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
362
|
+
const withPermissions: typeof manifest & { permissions: any } = { ...manifest, permissions };
|
|
362
363
|
|
|
363
364
|
export default withPermissions;
|
|
364
365
|
`;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/loader/load-entity.ts","../src/resolver/resolve-blocks.ts","../src/render/eta-renderer.ts","../src/patch/apply-patch.ts","../src/writer/write-files.ts","../src/emit/emit-manifest.ts","../src/engine.ts","../src/doctor/scan.ts","../src/validators.ts"],"names":["parseYaml","readdir","join","readFile","stat","resolve","entries","relative","resolvePath"],"mappings":"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","file":"index.js","sourcesContent":["import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type {\n BlockDefinition,\n EntityDefinition,\n Variable,\n} from '@kb-labs/scaffold-contracts';\n\ninterface RawBlockYaml {\n id?: string;\n describe?: string;\n requires?: string[];\n conflicts?: string[];\n variables?: Variable[];\n manifestPatch?: string;\n snippets?: string;\n}\n\ninterface RawEntityYaml {\n id?: string;\n displayName?: string;\n description?: string;\n variables?: Variable[];\n defaults?: { blocks?: string[] };\n output?: string;\n manifestTarget?: string;\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function loadBlock(blockDir: string): Promise<BlockDefinition> {\n const blockYamlPath = join(blockDir, 'block.yaml');\n const raw = await readFile(blockYamlPath, 'utf8');\n const parsed = parseYaml(raw) as RawBlockYaml;\n\n if (!parsed.id) {\n throw new Error(`block.yaml at ${blockYamlPath} is missing \"id\"`);\n }\n\n const filesDir = join(blockDir, 'files');\n const manifestPatchFile =\n parsed.manifestPatch ?? 'manifest.patch.yaml';\n const snippetsFile = parsed.snippets ?? 'manifest.snippets.yaml';\n\n const manifestPatchPath = join(blockDir, manifestPatchFile);\n const snippetsPath = join(blockDir, snippetsFile);\n\n const [hasFiles, hasPatch, hasSnippets] = await Promise.all([\n pathExists(filesDir),\n pathExists(manifestPatchPath),\n pathExists(snippetsPath),\n ]);\n\n return {\n id: parsed.id,\n describe: parsed.describe ?? parsed.id,\n requires: parsed.requires,\n conflicts: parsed.conflicts,\n variables: parsed.variables,\n filesDir: hasFiles ? filesDir : blockDir,\n manifestPatch: hasPatch ? manifestPatchPath : undefined,\n snippetsPath: hasSnippets ? snippetsPath : undefined,\n };\n}\n\n/**\n * Load an entity definition from a templates directory.\n *\n * @param templatesRoot directory containing `<entity>/entity.yaml` and `<entity>/blocks/*`\n * @param entityId e.g. 'plugin', 'adapter'\n */\nexport async function loadEntity(\n templatesRoot: string,\n entityId: string,\n): Promise<EntityDefinition> {\n const entityDir = resolve(templatesRoot, entityId);\n const entityYamlPath = join(entityDir, 'entity.yaml');\n\n if (!(await pathExists(entityYamlPath))) {\n throw new Error(\n `Entity \"${entityId}\" not found: ${entityYamlPath} does not exist`,\n );\n }\n\n const raw = await readFile(entityYamlPath, 'utf8');\n const parsed = (parseYaml(raw) ?? {}) as RawEntityYaml;\n\n const id = parsed.id ?? entityId;\n const blocksDir = join(entityDir, 'blocks');\n const blocks: BlockDefinition[] = [];\n\n if (await pathExists(blocksDir)) {\n const entries = await readdir(blocksDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const blockDir = join(blocksDir, entry.name);\n if (!(await pathExists(join(blockDir, 'block.yaml')))) continue;\n blocks.push(await loadBlock(blockDir));\n }\n }\n\n return {\n id,\n displayName: parsed.displayName ?? id,\n description: parsed.description,\n variables: parsed.variables ?? [],\n blocks,\n defaults: parsed.defaults,\n output: parsed.output,\n manifestTarget: parsed.manifestTarget,\n };\n}\n\n/**\n * List entity ids available in the templates root (directories with `entity.yaml`).\n */\nexport async function listEntities(templatesRoot: string): Promise<string[]> {\n if (!(await pathExists(templatesRoot))) return [];\n const entries = await readdir(templatesRoot, { withFileTypes: true });\n const result: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (await pathExists(join(templatesRoot, entry.name, 'entity.yaml'))) {\n result.push(entry.name);\n }\n }\n return result.sort();\n}\n","import type { BlockDefinition } from '@kb-labs/scaffold-contracts';\n\nexport interface ResolveResult {\n /** Block ids in topological order (dependencies first). */\n ordered: string[];\n /** Full block definitions in the same order. */\n blocks: BlockDefinition[];\n}\n\n/**\n * Resolve a user-selected set of block ids into a topologically sorted list,\n * expanding `requires` and rejecting cycles or `conflicts` violations.\n */\nexport function resolveBlocks(\n all: BlockDefinition[],\n selected: string[],\n): ResolveResult {\n const byId = new Map<string, BlockDefinition>();\n for (const b of all) byId.set(b.id, b);\n\n const missing = selected.filter((id) => !byId.has(id));\n if (missing.length > 0) {\n throw new Error(`Unknown block(s): ${missing.join(', ')}`);\n }\n\n // Expand requires (BFS).\n const expanded = new Set<string>();\n const queue = [...selected];\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (expanded.has(id)) continue;\n expanded.add(id);\n const block = byId.get(id);\n if (!block) continue;\n for (const dep of block.requires ?? []) {\n if (!byId.has(dep)) {\n throw new Error(\n `Block \"${id}\" requires unknown block \"${dep}\"`,\n );\n }\n if (!expanded.has(dep)) queue.push(dep);\n }\n }\n\n // Conflict check against the final expanded set.\n for (const id of expanded) {\n const block = byId.get(id)!;\n for (const other of block.conflicts ?? []) {\n if (expanded.has(other)) {\n throw new Error(\n `Block \"${id}\" conflicts with \"${other}\" — both selected`,\n );\n }\n }\n }\n\n // Topological sort (Kahn's algorithm).\n const inDegree = new Map<string, number>();\n const edges = new Map<string, Set<string>>();\n for (const id of expanded) {\n inDegree.set(id, 0);\n edges.set(id, new Set());\n }\n for (const id of expanded) {\n const block = byId.get(id)!;\n for (const dep of block.requires ?? []) {\n if (!expanded.has(dep)) continue;\n edges.get(dep)!.add(id);\n inDegree.set(id, (inDegree.get(id) ?? 0) + 1);\n }\n }\n\n const ready: string[] = [];\n for (const [id, deg] of inDegree) if (deg === 0) ready.push(id);\n ready.sort();\n\n const ordered: string[] = [];\n while (ready.length > 0) {\n const id = ready.shift()!;\n ordered.push(id);\n for (const next of edges.get(id) ?? []) {\n const d = (inDegree.get(next) ?? 0) - 1;\n inDegree.set(next, d);\n if (d === 0) {\n ready.push(next);\n ready.sort();\n }\n }\n }\n\n if (ordered.length !== expanded.size) {\n throw new Error('Cycle detected in block requires graph');\n }\n\n return { ordered, blocks: ordered.map((id) => byId.get(id)!) };\n}\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { Eta } from 'eta';\nimport type {\n RenderContext,\n RenderedFile,\n} from '@kb-labs/scaffold-contracts';\n\nconst eta = new Eta({\n autoEscape: false,\n useWith: true,\n tags: ['<%', '%>'],\n});\n\nconst ETA_SUFFIX = '.eta';\n\n/**\n * Render a single template string through eta using the given context.\n */\nexport function renderString(template: string, ctx: RenderContext): string {\n return eta.renderString(template, ctx);\n}\n\nasync function walk(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const out: string[] = [];\n for (const entry of entries) {\n const p = join(dir, entry.name);\n if (entry.isDirectory()) {\n out.push(...(await walk(p)));\n } else if (entry.isFile()) {\n out.push(p);\n }\n }\n return out;\n}\n\nfunction renderPath(relPath: string, ctx: RenderContext): string {\n // Use simple __var__ substitution for path segments — eta's `<% %>`\n // tags are illegal on Windows and awkward on Unix.\n const substituted = relPath\n .replace(/__name__/g, ctx.name)\n .replace(/__scope__/g, ctx.scope.replace(/^@/, ''));\n return substituted.endsWith(ETA_SUFFIX)\n ? substituted.slice(0, -ETA_SUFFIX.length)\n : substituted;\n}\n\n/**\n * Render all files under `filesDir`. File bodies AND path segments go through\n * eta. A trailing `.eta` extension on the file name is stripped after render.\n *\n * Returned paths are relative to `filesDir`. The caller decides the output root.\n */\nconst SKIP_MARKER = '<!--@@scaffold:skip@@-->';\n\nexport async function renderFilesDir(\n filesDir: string,\n ctx: RenderContext,\n): Promise<RenderedFile[]> {\n const absolutes = await walk(filesDir);\n const rendered: RenderedFile[] = [];\n for (const abs of absolutes) {\n const rel = relative(filesDir, abs);\n const renderedRel = renderPath(rel, ctx);\n const raw = await readFile(abs, 'utf8');\n const body = abs.endsWith(ETA_SUFFIX)\n ? renderString(raw, ctx)\n : raw;\n\n // Templates can opt out of a given file by emitting a skip marker.\n // Useful for files that should only exist in some modes (e.g.\n // pnpm-workspace.yaml only for standalone mode).\n if (body.trim() === SKIP_MARKER) continue;\n\n const st = await stat(abs);\n rendered.push({\n path: renderedRel,\n contents: body,\n executable: (st.mode & 0o111) !== 0,\n });\n }\n return rendered;\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport type {\n ManifestPatch,\n ManifestSnippets,\n RenderContext,\n} from '@kb-labs/scaffold-contracts';\nimport { renderString } from '../render/eta-renderer.js';\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return (\n typeof v === 'object' &&\n v !== null &&\n !Array.isArray(v) &&\n Object.getPrototypeOf(v) === Object.prototype\n );\n}\n\nfunction mergeArrays(a: unknown[], b: unknown[]): unknown[] {\n const allObjects =\n a.every(isPlainObject) && b.every(isPlainObject) && a.length + b.length > 0;\n\n if (allObjects) {\n const keyOf = (x: Record<string, unknown>): string | null => {\n if (typeof x.id === 'string') return `id:${x.id}`;\n if (typeof x.name === 'string') return `name:${x.name}`;\n return null;\n };\n const allKeyed =\n a.every((x) => keyOf(x as Record<string, unknown>) !== null) &&\n b.every((x) => keyOf(x as Record<string, unknown>) !== null);\n\n if (allKeyed) {\n const byKey = new Map<string, Record<string, unknown>>();\n for (const item of [...a, ...b] as Record<string, unknown>[]) {\n const k = keyOf(item)!;\n const prev = byKey.get(k);\n byKey.set(k, prev ? deepMerge(prev, item) : item);\n }\n return [...byKey.values()];\n }\n }\n\n // Primitive or mixed: Set-dedupe where possible.\n const seen = new Set<string>();\n const out: unknown[] = [];\n for (const item of [...a, ...b]) {\n const key = JSON.stringify(item);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(item);\n }\n return out;\n}\n\nexport function deepMerge(\n target: Record<string, unknown>,\n patch: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = { ...target };\n for (const [key, value] of Object.entries(patch)) {\n const existing = out[key];\n if (isPlainObject(existing) && isPlainObject(value)) {\n out[key] = deepMerge(existing, value);\n } else if (Array.isArray(existing) && Array.isArray(value)) {\n out[key] = mergeArrays(existing, value);\n } else {\n out[key] = value;\n }\n }\n return out;\n}\n\n/**\n * Load a manifest.patch.yaml from disk, render it through eta with the\n * render context, parse as YAML, and return the resulting object.\n */\nexport async function loadPatch(\n path: string,\n ctx: RenderContext,\n): Promise<ManifestPatch> {\n const raw = await readFile(path, 'utf8');\n const rendered = renderString(raw, ctx);\n const parsed = parseYaml(rendered);\n if (parsed == null) return {};\n if (!isPlainObject(parsed)) {\n throw new Error(`Patch at ${path} must be a YAML object`);\n }\n return parsed;\n}\n\nexport async function loadSnippets(\n path: string,\n ctx: RenderContext,\n): Promise<ManifestSnippets> {\n const raw = await readFile(path, 'utf8');\n const rendered = renderString(raw, ctx);\n const parsed = parseYaml(rendered);\n if (parsed == null) return {};\n if (!isPlainObject(parsed)) {\n throw new Error(`Snippets at ${path} must be a YAML object`);\n }\n return parsed as ManifestSnippets;\n}\n\nexport function mergeSnippets(\n a: ManifestSnippets,\n b: ManifestSnippets,\n): ManifestSnippets {\n const mergedExtras: Record<string, string[]> = { ...(a.extras ?? {}) };\n for (const [k, v] of Object.entries(b.extras ?? {})) {\n mergedExtras[k] = dedupe([...(mergedExtras[k] ?? []), ...v]);\n }\n return {\n imports: dedupe([...(a.imports ?? []), ...(b.imports ?? [])]),\n permissions: dedupe([\n ...(a.permissions ?? []),\n ...(b.permissions ?? []),\n ]),\n extras: Object.keys(mergedExtras).length > 0 ? mergedExtras : undefined,\n };\n}\n\nfunction dedupe(items: string[]): string[] {\n return [...new Set(items)];\n}\n","import { mkdir, writeFile, chmod, stat, readdir, rm } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport type { RenderedFile } from '@kb-labs/scaffold-contracts';\n\nexport interface WriteOptions {\n outRoot: string;\n files: RenderedFile[];\n /** If set, wipe the root first. */\n force?: boolean;\n}\n\nexport interface TargetState {\n exists: boolean;\n empty: boolean;\n}\n\nexport async function inspectTarget(outRoot: string): Promise<TargetState> {\n try {\n const st = await stat(outRoot);\n if (!st.isDirectory()) return { exists: true, empty: false };\n const entries = await readdir(outRoot);\n return { exists: true, empty: entries.length === 0 };\n } catch {\n return { exists: false, empty: true };\n }\n}\n\n/**\n * Detect intra-batch path collisions. Two blocks writing the same path is a\n * configuration bug, not a merge case.\n */\nexport function detectCollisions(files: RenderedFile[]): string[] {\n const seen = new Map<string, number>();\n for (const f of files) {\n seen.set(f.path, (seen.get(f.path) ?? 0) + 1);\n }\n return [...seen.entries()]\n .filter(([, n]) => n > 1)\n .map(([p]) => p);\n}\n\n/**\n * Write the rendered file set to disk. If `force` is set and the root\n * exists, it is wiped first. Otherwise the caller is responsible for\n * ensuring the root is absent or empty — see `inspectTarget`.\n */\nexport async function writeFiles(opts: WriteOptions): Promise<void> {\n const { outRoot, files, force } = opts;\n const abs = resolve(outRoot);\n\n const collisions = detectCollisions(files);\n if (collisions.length > 0) {\n throw new Error(\n `Block path collisions detected: ${collisions.join(', ')}`,\n );\n }\n\n if (force) {\n await rm(abs, { recursive: true, force: true });\n }\n\n await mkdir(abs, { recursive: true });\n\n for (const file of files) {\n const target = join(abs, file.path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, file.contents, 'utf8');\n if (file.executable) {\n await chmod(target, 0o755);\n }\n }\n}\n\n/**\n * Produce a human-readable tree of the files that would be written.\n */\nexport function formatTree(files: RenderedFile[]): string {\n return files\n .map((f) => f.path)\n .sort()\n .map((p) => ` ${p}`)\n .join('\\n');\n}\n","import type {\n ManifestPatch,\n ManifestSnippets,\n} from '@kb-labs/scaffold-contracts';\n\n/**\n * Emit a TypeScript source file for the plugin V3 manifest.\n *\n * The manifest object is stringified as a JSON literal. A `permissions`\n * expression is assembled from `combinePermissions()` snippets contributed\n * by blocks and spread in alongside. Imports are deduped at the top.\n */\nexport function emitManifest(\n manifest: ManifestPatch,\n snippets: ManifestSnippets,\n): string {\n const importLines = [...(snippets.imports ?? [])];\n const hasCombine = importLines.some((l) =>\n /\\bcombinePermissions\\b/.test(l),\n );\n if (!hasCombine) {\n importLines.unshift(\n \"import { combinePermissions } from '@kb-labs/sdk';\",\n );\n }\n const importSet = new Set<string>(importLines);\n\n const permLines = snippets.permissions ?? [];\n const permExpr =\n permLines.length > 0\n ? `combinePermissions()\\n ${permLines.map((l) => `.${l}`).join('\\n ')}\\n .build()`\n : 'combinePermissions().build()';\n\n const body = JSON.stringify(manifest, null, 2);\n\n return `/**\n * V3 plugin manifest. Scaffolded by @kb-labs/scaffold.\n *\n * Edit freely — this is your plugin's public surface. Add commands by\n * appending to \\`cli.commands[]\\`, REST routes under \\`rest.routes[]\\`,\n * Studio pages under \\`studio\\`. Consult neighbouring plugins\n * (\\`plugins/commit\\`, \\`plugins/review\\`) for reference shapes.\n */\n${[...importSet].join('\\n')}\n\nconst permissions = ${permExpr};\n\nconst manifest = ${body} as const;\n\nconst withPermissions = { ...manifest, permissions };\n\nexport default withPermissions;\n`;\n}\n","import { join } from 'node:path';\nimport type {\n BlockDefinition,\n EntityDefinition,\n ManifestPatch,\n ManifestSnippets,\n RenderContext,\n RenderedFile,\n} from '@kb-labs/scaffold-contracts';\nimport { resolveBlocks } from './resolver/resolve-blocks.js';\nimport {\n renderFilesDir,\n renderString,\n} from './render/eta-renderer.js';\nimport {\n deepMerge,\n loadPatch,\n loadSnippets,\n mergeSnippets,\n} from './patch/apply-patch.js';\nimport { emitManifest } from './emit/emit-manifest.js';\n\nexport interface BuildInputs {\n entity: EntityDefinition;\n selectedBlockIds: string[];\n context: RenderContext;\n}\n\nexport interface BuildResult {\n blocks: BlockDefinition[];\n files: RenderedFile[];\n manifest: ManifestPatch;\n snippets: ManifestSnippets;\n outRoot: string;\n}\n\n/**\n * Compose the full render result from a resolved entity + user selections.\n *\n * Steps:\n * 1. Resolve & topo-sort blocks (expanding requires, checking conflicts).\n * 2. Render every block's `files/` directory into in-memory RenderedFile[].\n * 3. Fold manifest patches and snippets in topological order.\n * 4. Compute `outRoot` from `entity.output` (also eta-rendered).\n *\n * No disk writes happen here — call `writeFiles()` afterward.\n */\nexport async function build(inputs: BuildInputs): Promise<BuildResult> {\n const { entity, selectedBlockIds, context } = inputs;\n\n const resolved = resolveBlocks(entity.blocks, selectedBlockIds);\n\n const files: RenderedFile[] = [];\n let manifest: ManifestPatch = {};\n let snippets: ManifestSnippets = {};\n\n for (const block of resolved.blocks) {\n const blockFiles = await renderFilesDir(block.filesDir, context);\n files.push(...blockFiles);\n\n if (block.manifestPatch) {\n const patch = await loadPatch(block.manifestPatch, context);\n manifest = deepMerge(manifest, patch);\n }\n if (block.snippetsPath) {\n const s = await loadSnippets(block.snippetsPath, context);\n snippets = mergeSnippets(snippets, s);\n }\n }\n\n const outTemplate = entity.output ?? join('.kb', 'plugins', '<%= it.name %>');\n const outRoot = renderString(outTemplate, context);\n\n if (entity.manifestTarget) {\n const manifestTarget = renderString(entity.manifestTarget, context);\n files.push({\n path: manifestTarget,\n contents: emitManifest(manifest, snippets),\n });\n }\n\n return { blocks: resolved.blocks, files, manifest, snippets, outRoot };\n}\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, relative, resolve as resolvePath } from 'node:path';\n\nexport type Severity = 'info' | 'warn' | 'error';\n\nexport interface Finding {\n severity: Severity;\n package: string;\n message: string;\n}\n\nconst INTERNAL_IMPORT_RE =\n /from\\s+['\"](@kb-labs\\/(?:core-[a-z0-9-]+|platform-[a-z0-9-]+|core-platform(?:\\/[^'\"]+)?))['\"]/g;\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readJson(p: string): Promise<Record<string, unknown>> {\n const raw = await readFile(p, 'utf8');\n return JSON.parse(raw) as Record<string, unknown>;\n}\n\nasync function walkSources(dir: string): Promise<string[]> {\n const out: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === 'node_modules' || entry.name === 'dist') continue;\n const p = join(dir, entry.name);\n if (entry.isDirectory()) {\n out.push(...(await walkSources(p)));\n } else if (\n entry.isFile() &&\n (entry.name.endsWith('.ts') || entry.name.endsWith('.tsx'))\n ) {\n out.push(p);\n }\n }\n return out;\n}\n\n/**\n * Scan a single package directory (one that contains `package.json`).\n */\nexport async function scanPackage(pkgDir: string): Promise<Finding[]> {\n const findings: Finding[] = [];\n const pkgJsonPath = join(pkgDir, 'package.json');\n if (!(await exists(pkgJsonPath))) {\n return [\n {\n severity: 'error',\n package: pkgDir,\n message: 'missing package.json',\n },\n ];\n }\n const pkg = await readJson(pkgJsonPath);\n const pkgName = typeof pkg.name === 'string' ? pkg.name : pkgDir;\n\n const kb = pkg.kb as Record<string, unknown> | undefined;\n const isEntry = kb && typeof kb.manifest === 'string';\n\n if (isEntry) {\n const manifestPath = join(pkgDir, kb.manifest as string);\n if (!(await exists(manifestPath))) {\n findings.push({\n severity: 'warn',\n package: pkgName,\n message: `manifest not built: ${kb.manifest} missing (run pnpm build)`,\n });\n }\n }\n\n const deps = (pkg.dependencies ?? {}) as Record<string, string>;\n const devDeps = (pkg.devDependencies ?? {}) as Record<string, string>;\n\n if (isEntry && !deps['@kb-labs/sdk'] && !devDeps['@kb-labs/sdk']) {\n findings.push({\n severity: 'error',\n package: pkgName,\n message: '@kb-labs/sdk not listed as a dependency',\n });\n }\n\n const srcDir = join(pkgDir, 'src');\n if (await exists(srcDir)) {\n const sources = await walkSources(srcDir);\n const offenders = new Set<string>();\n for (const file of sources) {\n const raw = await readFile(file, 'utf8');\n for (const match of raw.matchAll(INTERNAL_IMPORT_RE)) {\n if (match[1]) offenders.add(match[1]);\n }\n }\n if (offenders.size > 0) {\n findings.push({\n severity: 'warn',\n package: pkgName,\n message: `imports internal KB Labs packages: ${[...offenders].join(', ')} — use @kb-labs/sdk instead`,\n });\n }\n }\n\n const tsconfigPath = join(pkgDir, 'tsconfig.json');\n if (await exists(tsconfigPath)) {\n const tsconfig = await readJson(tsconfigPath);\n const extendsField = tsconfig.extends;\n if (\n typeof extendsField !== 'string' ||\n !extendsField.includes('@kb-labs/devkit')\n ) {\n findings.push({\n severity: 'info',\n package: pkgName,\n message:\n 'tsconfig does not extend @kb-labs/devkit — custom configs may drift',\n });\n }\n }\n\n return findings;\n}\n\nexport interface ScanResult {\n findings: Finding[];\n packagesScanned: number;\n}\n\ninterface LockEntry {\n resolvedPath?: string;\n enabled?: boolean;\n}\n\ninterface MarketplaceLockShape {\n installed?: Record<string, LockEntry>;\n}\n\nasync function readLock(\n workspaceRoot: string,\n): Promise<MarketplaceLockShape | null> {\n const lockPath = join(workspaceRoot, '.kb', 'marketplace.lock');\n if (!(await exists(lockPath))) return null;\n try {\n const raw = await readFile(lockPath, 'utf8');\n return JSON.parse(raw) as MarketplaceLockShape;\n } catch {\n return null;\n }\n}\n\nasync function findEntryPackageDir(pkgDir: string): Promise<string | null> {\n // If pkgDir itself has a kb-manifest entry, it's already the entry package.\n const pkgJsonPath = join(pkgDir, 'package.json');\n if (await exists(pkgJsonPath)) {\n const pkg = (await readJson(pkgJsonPath)) as { kb?: { manifest?: string } };\n if (pkg.kb?.manifest) return pkgDir;\n }\n // Otherwise look in packages/*-entry.\n const packagesDir = join(pkgDir, 'packages');\n if (!(await exists(packagesDir))) return null;\n const entries = await readdir(packagesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (!entry.name.endsWith('-entry')) continue;\n const candidate = join(packagesDir, entry.name);\n if (await exists(join(candidate, 'package.json'))) return candidate;\n }\n return null;\n}\n\nexport interface ScanOptions {\n /**\n * Workspace root containing `.kb/marketplace.lock`. When provided, each\n * scaffolded plugin found is cross-checked against the lock — missing\n * entries surface as warnings so the user knows to `kb marketplace\n * plugins link` or rerun `kb scaffold`.\n */\n workspaceRoot?: string;\n}\n\n/**\n * Scan a root directory containing one or more plugin packages. A plugin\n * package has either:\n * - its own `package.json` at the root, or\n * - a `packages/` directory with child packages.\n *\n * When `opts.workspaceRoot` is given, also cross-checks every discovered\n * scaffolded plugin against `.kb/marketplace.lock`.\n */\nexport async function scanRoot(\n root: string,\n opts: ScanOptions = {},\n): Promise<ScanResult> {\n const findings: Finding[] = [];\n let packagesScanned = 0;\n\n async function visit(dir: string): Promise<void> {\n const pkgJson = join(dir, 'package.json');\n const packagesDir = join(dir, 'packages');\n if (await exists(pkgJson)) {\n findings.push(...(await scanPackage(dir)));\n packagesScanned += 1;\n }\n if (await exists(packagesDir)) {\n const entries = await readdir(packagesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) await visit(join(packagesDir, entry.name));\n }\n }\n }\n\n if (!(await exists(root))) {\n return {\n findings: [\n {\n severity: 'warn',\n package: root,\n message: 'scan root does not exist',\n },\n ],\n packagesScanned: 0,\n };\n }\n\n const entries = await readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) await visit(join(root, entry.name));\n }\n\n if (opts.workspaceRoot) {\n findings.push(...(await checkLockSync(root, opts.workspaceRoot)));\n }\n\n return { findings, packagesScanned };\n}\n\n/**\n * For each scaffolded plugin root under `scaffoldRoot`, verify that the\n * plugin's entry package is registered in `.kb/marketplace.lock`.\n *\n * Produces:\n * - warn \"plugin not registered in marketplace.lock (run `kb marketplace plugins link ...`)\"\n * - warn \"lock entry points elsewhere\"\n * - info \"plugin disabled in lock\"\n */\nasync function checkLockSync(\n scaffoldRoot: string,\n workspaceRoot: string,\n): Promise<Finding[]> {\n const out: Finding[] = [];\n const lock = await readLock(workspaceRoot);\n\n const entries = await readdir(scaffoldRoot, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const pluginDir = join(scaffoldRoot, entry.name);\n const entryPkgDir = await findEntryPackageDir(pluginDir);\n if (!entryPkgDir) continue;\n\n const pkg = (await readJson(join(entryPkgDir, 'package.json'))) as {\n name?: string;\n };\n const id = typeof pkg.name === 'string' ? pkg.name : entry.name;\n\n if (!lock || !lock.installed) {\n out.push({\n severity: 'warn',\n package: id,\n message:\n 'no .kb/marketplace.lock — scaffolded plugins will not be discovered until registered',\n });\n return out;\n }\n\n const lockEntry = lock.installed[id];\n if (!lockEntry) {\n const hint = relative(workspaceRoot, entryPkgDir);\n out.push({\n severity: 'warn',\n package: id,\n message: `not registered in marketplace.lock — run: kb marketplace plugins link ${hint}`,\n });\n continue;\n }\n\n if (lockEntry.enabled === false) {\n out.push({\n severity: 'info',\n package: id,\n message: 'registered but disabled in marketplace.lock',\n });\n }\n\n if (typeof lockEntry.resolvedPath === 'string') {\n const lockAbs = resolvePath(workspaceRoot, lockEntry.resolvedPath);\n if (lockAbs !== entryPkgDir) {\n out.push({\n severity: 'warn',\n package: id,\n message: `lock points at ${lockEntry.resolvedPath} but scaffolded package is at ${relative(workspaceRoot, entryPkgDir)}`,\n });\n }\n }\n }\n\n return out;\n}\n","const NAME_RE = /^[a-z][a-z0-9-]*$/;\nconst SCOPE_RE = /^@[a-z][a-z0-9-]*$/;\nconst SEMVER_RE = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/;\nconst IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\nconst RESERVED_NAMES = new Set([\n 'kb',\n 'core',\n 'sdk',\n 'test',\n 'tests',\n 'node_modules',\n 'dist',\n 'src',\n 'con',\n 'prn',\n 'nul',\n]);\n\nexport function validatePackageName(name: string): string | null {\n if (!name) return 'name is required';\n if (name.length > 214) return 'name must be <= 214 chars';\n if (!NAME_RE.test(name)) {\n return 'name must be lowercase, start with a letter, and contain only a-z 0-9 -';\n }\n if (RESERVED_NAMES.has(name)) return `name \"${name}\" is reserved`;\n return null;\n}\n\nexport function validateScope(scope: string): string | null {\n if (!scope) return null;\n if (!SCOPE_RE.test(scope)) {\n return 'scope must look like \"@acme\" (lowercase, starts with @, a-z 0-9 -)';\n }\n return null;\n}\n\nexport function validateSemver(v: string): string | null {\n return SEMVER_RE.test(v) ? null : 'expected semver (e.g. 1.2.3)';\n}\n\nexport function validateIdentifier(v: string): string | null {\n return IDENTIFIER_RE.test(v) ? null : 'expected a JS identifier';\n}\n\nexport function runValidator(\n kind: string,\n value: unknown,\n): string | null {\n if (typeof value !== 'string') return 'expected a string';\n switch (kind) {\n case 'npmName':\n return validatePackageName(value);\n case 'npmScope':\n return validateScope(value);\n case 'semver':\n return validateSemver(value);\n case 'identifier':\n return validateIdentifier(value);\n default:\n return null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/loader/load-entity.ts","../src/resolver/resolve-blocks.ts","../src/render/eta-renderer.ts","../src/patch/apply-patch.ts","../src/writer/write-files.ts","../src/emit/emit-manifest.ts","../src/engine.ts","../src/doctor/scan.ts","../src/validators.ts"],"names":["parseYaml","readdir","join","readFile","stat","resolve","entries","relative","resolvePath"],"mappings":"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","file":"index.js","sourcesContent":["import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type {\n BlockDefinition,\n EntityDefinition,\n Variable,\n} from '@kb-labs/scaffold-contracts';\n\ninterface RawBlockYaml {\n id?: string;\n describe?: string;\n requires?: string[];\n conflicts?: string[];\n variables?: Variable[];\n manifestPatch?: string;\n snippets?: string;\n}\n\ninterface RawEntityYaml {\n id?: string;\n displayName?: string;\n description?: string;\n variables?: Variable[];\n defaults?: { blocks?: string[] };\n output?: string;\n manifestTarget?: string;\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function loadBlock(blockDir: string): Promise<BlockDefinition> {\n const blockYamlPath = join(blockDir, 'block.yaml');\n const raw = await readFile(blockYamlPath, 'utf8');\n const parsed = parseYaml(raw) as RawBlockYaml;\n\n if (!parsed.id) {\n throw new Error(`block.yaml at ${blockYamlPath} is missing \"id\"`);\n }\n\n const filesDir = join(blockDir, 'files');\n const manifestPatchFile =\n parsed.manifestPatch ?? 'manifest.patch.yaml';\n const snippetsFile = parsed.snippets ?? 'manifest.snippets.yaml';\n\n const manifestPatchPath = join(blockDir, manifestPatchFile);\n const snippetsPath = join(blockDir, snippetsFile);\n\n const [hasFiles, hasPatch, hasSnippets] = await Promise.all([\n pathExists(filesDir),\n pathExists(manifestPatchPath),\n pathExists(snippetsPath),\n ]);\n\n return {\n id: parsed.id,\n describe: parsed.describe ?? parsed.id,\n requires: parsed.requires,\n conflicts: parsed.conflicts,\n variables: parsed.variables,\n filesDir: hasFiles ? filesDir : blockDir,\n manifestPatch: hasPatch ? manifestPatchPath : undefined,\n snippetsPath: hasSnippets ? snippetsPath : undefined,\n };\n}\n\n/**\n * Load an entity definition from a templates directory.\n *\n * @param templatesRoot directory containing `<entity>/entity.yaml` and `<entity>/blocks/*`\n * @param entityId e.g. 'plugin', 'adapter'\n */\nexport async function loadEntity(\n templatesRoot: string,\n entityId: string,\n): Promise<EntityDefinition> {\n const entityDir = resolve(templatesRoot, entityId);\n const entityYamlPath = join(entityDir, 'entity.yaml');\n\n if (!(await pathExists(entityYamlPath))) {\n throw new Error(\n `Entity \"${entityId}\" not found: ${entityYamlPath} does not exist`,\n );\n }\n\n const raw = await readFile(entityYamlPath, 'utf8');\n const parsed = (parseYaml(raw) ?? {}) as RawEntityYaml;\n\n const id = parsed.id ?? entityId;\n const blocksDir = join(entityDir, 'blocks');\n const blocks: BlockDefinition[] = [];\n\n if (await pathExists(blocksDir)) {\n const entries = await readdir(blocksDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const blockDir = join(blocksDir, entry.name);\n if (!(await pathExists(join(blockDir, 'block.yaml')))) continue;\n blocks.push(await loadBlock(blockDir));\n }\n }\n\n return {\n id,\n displayName: parsed.displayName ?? id,\n description: parsed.description,\n variables: parsed.variables ?? [],\n blocks,\n defaults: parsed.defaults,\n output: parsed.output,\n manifestTarget: parsed.manifestTarget,\n };\n}\n\n/**\n * List entity ids available in the templates root (directories with `entity.yaml`).\n */\nexport async function listEntities(templatesRoot: string): Promise<string[]> {\n if (!(await pathExists(templatesRoot))) return [];\n const entries = await readdir(templatesRoot, { withFileTypes: true });\n const result: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (await pathExists(join(templatesRoot, entry.name, 'entity.yaml'))) {\n result.push(entry.name);\n }\n }\n return result.sort();\n}\n","import type { BlockDefinition } from '@kb-labs/scaffold-contracts';\n\nexport interface ResolveResult {\n /** Block ids in topological order (dependencies first). */\n ordered: string[];\n /** Full block definitions in the same order. */\n blocks: BlockDefinition[];\n}\n\n/**\n * Resolve a user-selected set of block ids into a topologically sorted list,\n * expanding `requires` and rejecting cycles or `conflicts` violations.\n */\nexport function resolveBlocks(\n all: BlockDefinition[],\n selected: string[],\n): ResolveResult {\n const byId = new Map<string, BlockDefinition>();\n for (const b of all) byId.set(b.id, b);\n\n const missing = selected.filter((id) => !byId.has(id));\n if (missing.length > 0) {\n throw new Error(`Unknown block(s): ${missing.join(', ')}`);\n }\n\n // Expand requires (BFS).\n const expanded = new Set<string>();\n const queue = [...selected];\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (expanded.has(id)) continue;\n expanded.add(id);\n const block = byId.get(id);\n if (!block) continue;\n for (const dep of block.requires ?? []) {\n if (!byId.has(dep)) {\n throw new Error(\n `Block \"${id}\" requires unknown block \"${dep}\"`,\n );\n }\n if (!expanded.has(dep)) queue.push(dep);\n }\n }\n\n // Conflict check against the final expanded set.\n for (const id of expanded) {\n const block = byId.get(id)!;\n for (const other of block.conflicts ?? []) {\n if (expanded.has(other)) {\n throw new Error(\n `Block \"${id}\" conflicts with \"${other}\" — both selected`,\n );\n }\n }\n }\n\n // Topological sort (Kahn's algorithm).\n const inDegree = new Map<string, number>();\n const edges = new Map<string, Set<string>>();\n for (const id of expanded) {\n inDegree.set(id, 0);\n edges.set(id, new Set());\n }\n for (const id of expanded) {\n const block = byId.get(id)!;\n for (const dep of block.requires ?? []) {\n if (!expanded.has(dep)) continue;\n edges.get(dep)!.add(id);\n inDegree.set(id, (inDegree.get(id) ?? 0) + 1);\n }\n }\n\n const ready: string[] = [];\n for (const [id, deg] of inDegree) if (deg === 0) ready.push(id);\n ready.sort();\n\n const ordered: string[] = [];\n while (ready.length > 0) {\n const id = ready.shift()!;\n ordered.push(id);\n for (const next of edges.get(id) ?? []) {\n const d = (inDegree.get(next) ?? 0) - 1;\n inDegree.set(next, d);\n if (d === 0) {\n ready.push(next);\n ready.sort();\n }\n }\n }\n\n if (ordered.length !== expanded.size) {\n throw new Error('Cycle detected in block requires graph');\n }\n\n return { ordered, blocks: ordered.map((id) => byId.get(id)!) };\n}\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { Eta } from 'eta';\nimport type {\n RenderContext,\n RenderedFile,\n} from '@kb-labs/scaffold-contracts';\n\nconst eta = new Eta({\n autoEscape: false,\n useWith: true,\n tags: ['<%', '%>'],\n});\n\nconst ETA_SUFFIX = '.eta';\n\n/**\n * Render a single template string through eta using the given context.\n */\nexport function renderString(template: string, ctx: RenderContext): string {\n return eta.renderString(template, ctx);\n}\n\nasync function walk(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const out: string[] = [];\n for (const entry of entries) {\n const p = join(dir, entry.name);\n if (entry.isDirectory()) {\n out.push(...(await walk(p)));\n } else if (entry.isFile()) {\n out.push(p);\n }\n }\n return out;\n}\n\nfunction renderPath(relPath: string, ctx: RenderContext): string {\n // Use simple __var__ substitution for path segments — eta's `<% %>`\n // tags are illegal on Windows and awkward on Unix.\n const substituted = relPath\n .replace(/__name__/g, ctx.name)\n .replace(/__scope__/g, ctx.scope.replace(/^@/, ''));\n return substituted.endsWith(ETA_SUFFIX)\n ? substituted.slice(0, -ETA_SUFFIX.length)\n : substituted;\n}\n\n/**\n * Render all files under `filesDir`. File bodies AND path segments go through\n * eta. A trailing `.eta` extension on the file name is stripped after render.\n *\n * Returned paths are relative to `filesDir`. The caller decides the output root.\n */\nconst SKIP_MARKER = '<!--@@scaffold:skip@@-->';\n\nexport async function renderFilesDir(\n filesDir: string,\n ctx: RenderContext,\n): Promise<RenderedFile[]> {\n const absolutes = await walk(filesDir);\n const rendered: RenderedFile[] = [];\n for (const abs of absolutes) {\n const rel = relative(filesDir, abs);\n const renderedRel = renderPath(rel, ctx);\n const raw = await readFile(abs, 'utf8');\n const body = abs.endsWith(ETA_SUFFIX)\n ? renderString(raw, ctx)\n : raw;\n\n // Templates can opt out of a given file by emitting a skip marker.\n // Useful for files that should only exist in some modes (e.g.\n // pnpm-workspace.yaml only for standalone mode).\n if (body.trim() === SKIP_MARKER) continue;\n\n const st = await stat(abs);\n rendered.push({\n path: renderedRel,\n contents: body,\n executable: (st.mode & 0o111) !== 0,\n });\n }\n return rendered;\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport type {\n ManifestPatch,\n ManifestSnippets,\n RenderContext,\n} from '@kb-labs/scaffold-contracts';\nimport { renderString } from '../render/eta-renderer.js';\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return (\n typeof v === 'object' &&\n v !== null &&\n !Array.isArray(v) &&\n Object.getPrototypeOf(v) === Object.prototype\n );\n}\n\nfunction mergeArrays(a: unknown[], b: unknown[]): unknown[] {\n const allObjects =\n a.every(isPlainObject) && b.every(isPlainObject) && a.length + b.length > 0;\n\n if (allObjects) {\n const keyOf = (x: Record<string, unknown>): string | null => {\n if (typeof x.id === 'string') return `id:${x.id}`;\n if (typeof x.name === 'string') return `name:${x.name}`;\n return null;\n };\n const allKeyed =\n a.every((x) => keyOf(x as Record<string, unknown>) !== null) &&\n b.every((x) => keyOf(x as Record<string, unknown>) !== null);\n\n if (allKeyed) {\n const byKey = new Map<string, Record<string, unknown>>();\n for (const item of [...a, ...b] as Record<string, unknown>[]) {\n const k = keyOf(item)!;\n const prev = byKey.get(k);\n byKey.set(k, prev ? deepMerge(prev, item) : item);\n }\n return [...byKey.values()];\n }\n }\n\n // Primitive or mixed: Set-dedupe where possible.\n const seen = new Set<string>();\n const out: unknown[] = [];\n for (const item of [...a, ...b]) {\n const key = JSON.stringify(item);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(item);\n }\n return out;\n}\n\nexport function deepMerge(\n target: Record<string, unknown>,\n patch: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = { ...target };\n for (const [key, value] of Object.entries(patch)) {\n const existing = out[key];\n if (isPlainObject(existing) && isPlainObject(value)) {\n out[key] = deepMerge(existing, value);\n } else if (Array.isArray(existing) && Array.isArray(value)) {\n out[key] = mergeArrays(existing, value);\n } else {\n out[key] = value;\n }\n }\n return out;\n}\n\n/**\n * Load a manifest.patch.yaml from disk, render it through eta with the\n * render context, parse as YAML, and return the resulting object.\n */\nexport async function loadPatch(\n path: string,\n ctx: RenderContext,\n): Promise<ManifestPatch> {\n const raw = await readFile(path, 'utf8');\n const rendered = renderString(raw, ctx);\n const parsed = parseYaml(rendered);\n if (parsed == null) return {};\n if (!isPlainObject(parsed)) {\n throw new Error(`Patch at ${path} must be a YAML object`);\n }\n return parsed;\n}\n\nexport async function loadSnippets(\n path: string,\n ctx: RenderContext,\n): Promise<ManifestSnippets> {\n const raw = await readFile(path, 'utf8');\n const rendered = renderString(raw, ctx);\n const parsed = parseYaml(rendered);\n if (parsed == null) return {};\n if (!isPlainObject(parsed)) {\n throw new Error(`Snippets at ${path} must be a YAML object`);\n }\n return parsed as ManifestSnippets;\n}\n\nexport function mergeSnippets(\n a: ManifestSnippets,\n b: ManifestSnippets,\n): ManifestSnippets {\n const mergedExtras: Record<string, string[]> = { ...(a.extras ?? {}) };\n for (const [k, v] of Object.entries(b.extras ?? {})) {\n mergedExtras[k] = dedupe([...(mergedExtras[k] ?? []), ...v]);\n }\n return {\n imports: dedupe([...(a.imports ?? []), ...(b.imports ?? [])]),\n permissions: dedupe([\n ...(a.permissions ?? []),\n ...(b.permissions ?? []),\n ]),\n extras: Object.keys(mergedExtras).length > 0 ? mergedExtras : undefined,\n };\n}\n\nfunction dedupe(items: string[]): string[] {\n return [...new Set(items)];\n}\n","import { mkdir, writeFile, chmod, stat, readdir, rm } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport type { RenderedFile } from '@kb-labs/scaffold-contracts';\n\nexport interface WriteOptions {\n outRoot: string;\n files: RenderedFile[];\n /** If set, wipe the root first. */\n force?: boolean;\n}\n\nexport interface TargetState {\n exists: boolean;\n empty: boolean;\n}\n\nexport async function inspectTarget(outRoot: string): Promise<TargetState> {\n try {\n const st = await stat(outRoot);\n if (!st.isDirectory()) return { exists: true, empty: false };\n const entries = await readdir(outRoot);\n return { exists: true, empty: entries.length === 0 };\n } catch {\n return { exists: false, empty: true };\n }\n}\n\n/**\n * Detect intra-batch path collisions. Two blocks writing the same path is a\n * configuration bug, not a merge case.\n */\nexport function detectCollisions(files: RenderedFile[]): string[] {\n const seen = new Map<string, number>();\n for (const f of files) {\n seen.set(f.path, (seen.get(f.path) ?? 0) + 1);\n }\n return [...seen.entries()]\n .filter(([, n]) => n > 1)\n .map(([p]) => p);\n}\n\n/**\n * Write the rendered file set to disk. If `force` is set and the root\n * exists, it is wiped first. Otherwise the caller is responsible for\n * ensuring the root is absent or empty — see `inspectTarget`.\n */\nexport async function writeFiles(opts: WriteOptions): Promise<void> {\n const { outRoot, files, force } = opts;\n const abs = resolve(outRoot);\n\n const collisions = detectCollisions(files);\n if (collisions.length > 0) {\n throw new Error(\n `Block path collisions detected: ${collisions.join(', ')}`,\n );\n }\n\n if (force) {\n await rm(abs, { recursive: true, force: true });\n }\n\n await mkdir(abs, { recursive: true });\n\n for (const file of files) {\n const target = join(abs, file.path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, file.contents, 'utf8');\n if (file.executable) {\n await chmod(target, 0o755);\n }\n }\n}\n\n/**\n * Produce a human-readable tree of the files that would be written.\n */\nexport function formatTree(files: RenderedFile[]): string {\n return files\n .map((f) => f.path)\n .sort()\n .map((p) => ` ${p}`)\n .join('\\n');\n}\n","import type {\n ManifestPatch,\n ManifestSnippets,\n} from '@kb-labs/scaffold-contracts';\n\n/**\n * Emit a TypeScript source file for the plugin V3 manifest.\n *\n * The manifest object is stringified as a JSON literal. A `permissions`\n * expression is assembled from `combinePermissions()` snippets contributed\n * by blocks and spread in alongside. Imports are deduped at the top.\n */\nexport function emitManifest(\n manifest: ManifestPatch,\n snippets: ManifestSnippets,\n): string {\n const importLines = [...(snippets.imports ?? [])];\n const hasCombine = importLines.some((l) =>\n /\\bcombinePermissions\\b/.test(l),\n );\n if (!hasCombine) {\n importLines.unshift(\n \"import { combinePermissions } from '@kb-labs/sdk';\",\n );\n }\n const importSet = new Set<string>(importLines);\n\n const permLines = snippets.permissions ?? [];\n const permExpr =\n permLines.length > 0\n ? `combinePermissions()\\n ${permLines.map((l) => `.${l}`).join('\\n ')}\\n .build()`\n : 'combinePermissions().build()';\n\n const body = JSON.stringify(manifest, null, 2);\n\n return `/**\n * V3 plugin manifest. Scaffolded by @kb-labs/scaffold.\n *\n * Edit freely — this is your plugin's public surface. Add commands by\n * appending to \\`cli.commands[]\\`, REST routes under \\`rest.routes[]\\`,\n * Studio pages under \\`studio\\`. Consult neighbouring plugins\n * (\\`plugins/commit\\`, \\`plugins/review\\`) for reference shapes.\n */\n${[...importSet].join('\\n')}\n\nconst permissions = ${permExpr};\n\nconst manifest = ${body} as const;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst withPermissions: typeof manifest & { permissions: any } = { ...manifest, permissions };\n\nexport default withPermissions;\n`;\n}\n","import { join } from 'node:path';\nimport type {\n BlockDefinition,\n EntityDefinition,\n ManifestPatch,\n ManifestSnippets,\n RenderContext,\n RenderedFile,\n} from '@kb-labs/scaffold-contracts';\nimport { resolveBlocks } from './resolver/resolve-blocks.js';\nimport {\n renderFilesDir,\n renderString,\n} from './render/eta-renderer.js';\nimport {\n deepMerge,\n loadPatch,\n loadSnippets,\n mergeSnippets,\n} from './patch/apply-patch.js';\nimport { emitManifest } from './emit/emit-manifest.js';\n\nexport interface BuildInputs {\n entity: EntityDefinition;\n selectedBlockIds: string[];\n context: RenderContext;\n}\n\nexport interface BuildResult {\n blocks: BlockDefinition[];\n files: RenderedFile[];\n manifest: ManifestPatch;\n snippets: ManifestSnippets;\n outRoot: string;\n}\n\n/**\n * Compose the full render result from a resolved entity + user selections.\n *\n * Steps:\n * 1. Resolve & topo-sort blocks (expanding requires, checking conflicts).\n * 2. Render every block's `files/` directory into in-memory RenderedFile[].\n * 3. Fold manifest patches and snippets in topological order.\n * 4. Compute `outRoot` from `entity.output` (also eta-rendered).\n *\n * No disk writes happen here — call `writeFiles()` afterward.\n */\nexport async function build(inputs: BuildInputs): Promise<BuildResult> {\n const { entity, selectedBlockIds, context } = inputs;\n\n const resolved = resolveBlocks(entity.blocks, selectedBlockIds);\n\n const files: RenderedFile[] = [];\n let manifest: ManifestPatch = {};\n let snippets: ManifestSnippets = {};\n\n for (const block of resolved.blocks) {\n const blockFiles = await renderFilesDir(block.filesDir, context);\n files.push(...blockFiles);\n\n if (block.manifestPatch) {\n const patch = await loadPatch(block.manifestPatch, context);\n manifest = deepMerge(manifest, patch);\n }\n if (block.snippetsPath) {\n const s = await loadSnippets(block.snippetsPath, context);\n snippets = mergeSnippets(snippets, s);\n }\n }\n\n const outTemplate = entity.output ?? join('.kb', 'plugins', '<%= it.name %>');\n const outRoot = renderString(outTemplate, context);\n\n if (entity.manifestTarget) {\n const manifestTarget = renderString(entity.manifestTarget, context);\n files.push({\n path: manifestTarget,\n contents: emitManifest(manifest, snippets),\n });\n }\n\n return { blocks: resolved.blocks, files, manifest, snippets, outRoot };\n}\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, relative, resolve as resolvePath } from 'node:path';\n\nexport type Severity = 'info' | 'warn' | 'error';\n\nexport interface Finding {\n severity: Severity;\n package: string;\n message: string;\n}\n\nconst INTERNAL_IMPORT_RE =\n /from\\s+['\"](@kb-labs\\/(?:core-[a-z0-9-]+|platform-[a-z0-9-]+|core-platform(?:\\/[^'\"]+)?))['\"]/g;\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readJson(p: string): Promise<Record<string, unknown>> {\n const raw = await readFile(p, 'utf8');\n return JSON.parse(raw) as Record<string, unknown>;\n}\n\nasync function walkSources(dir: string): Promise<string[]> {\n const out: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === 'node_modules' || entry.name === 'dist') continue;\n const p = join(dir, entry.name);\n if (entry.isDirectory()) {\n out.push(...(await walkSources(p)));\n } else if (\n entry.isFile() &&\n (entry.name.endsWith('.ts') || entry.name.endsWith('.tsx'))\n ) {\n out.push(p);\n }\n }\n return out;\n}\n\n/**\n * Scan a single package directory (one that contains `package.json`).\n */\nexport async function scanPackage(pkgDir: string): Promise<Finding[]> {\n const findings: Finding[] = [];\n const pkgJsonPath = join(pkgDir, 'package.json');\n if (!(await exists(pkgJsonPath))) {\n return [\n {\n severity: 'error',\n package: pkgDir,\n message: 'missing package.json',\n },\n ];\n }\n const pkg = await readJson(pkgJsonPath);\n const pkgName = typeof pkg.name === 'string' ? pkg.name : pkgDir;\n\n const kb = pkg.kb as Record<string, unknown> | undefined;\n const isEntry = kb && typeof kb.manifest === 'string';\n\n if (isEntry) {\n const manifestPath = join(pkgDir, kb.manifest as string);\n if (!(await exists(manifestPath))) {\n findings.push({\n severity: 'warn',\n package: pkgName,\n message: `manifest not built: ${kb.manifest} missing (run pnpm build)`,\n });\n }\n }\n\n const deps = (pkg.dependencies ?? {}) as Record<string, string>;\n const devDeps = (pkg.devDependencies ?? {}) as Record<string, string>;\n\n if (isEntry && !deps['@kb-labs/sdk'] && !devDeps['@kb-labs/sdk']) {\n findings.push({\n severity: 'error',\n package: pkgName,\n message: '@kb-labs/sdk not listed as a dependency',\n });\n }\n\n const srcDir = join(pkgDir, 'src');\n if (await exists(srcDir)) {\n const sources = await walkSources(srcDir);\n const offenders = new Set<string>();\n for (const file of sources) {\n const raw = await readFile(file, 'utf8');\n for (const match of raw.matchAll(INTERNAL_IMPORT_RE)) {\n if (match[1]) offenders.add(match[1]);\n }\n }\n if (offenders.size > 0) {\n findings.push({\n severity: 'warn',\n package: pkgName,\n message: `imports internal KB Labs packages: ${[...offenders].join(', ')} — use @kb-labs/sdk instead`,\n });\n }\n }\n\n const tsconfigPath = join(pkgDir, 'tsconfig.json');\n if (await exists(tsconfigPath)) {\n const tsconfig = await readJson(tsconfigPath);\n const extendsField = tsconfig.extends;\n if (\n typeof extendsField !== 'string' ||\n !extendsField.includes('@kb-labs/devkit')\n ) {\n findings.push({\n severity: 'info',\n package: pkgName,\n message:\n 'tsconfig does not extend @kb-labs/devkit — custom configs may drift',\n });\n }\n }\n\n return findings;\n}\n\nexport interface ScanResult {\n findings: Finding[];\n packagesScanned: number;\n}\n\ninterface LockEntry {\n resolvedPath?: string;\n enabled?: boolean;\n}\n\ninterface MarketplaceLockShape {\n installed?: Record<string, LockEntry>;\n}\n\nasync function readLock(\n workspaceRoot: string,\n): Promise<MarketplaceLockShape | null> {\n const lockPath = join(workspaceRoot, '.kb', 'marketplace.lock');\n if (!(await exists(lockPath))) return null;\n try {\n const raw = await readFile(lockPath, 'utf8');\n return JSON.parse(raw) as MarketplaceLockShape;\n } catch {\n return null;\n }\n}\n\nasync function findEntryPackageDir(pkgDir: string): Promise<string | null> {\n // If pkgDir itself has a kb-manifest entry, it's already the entry package.\n const pkgJsonPath = join(pkgDir, 'package.json');\n if (await exists(pkgJsonPath)) {\n const pkg = (await readJson(pkgJsonPath)) as { kb?: { manifest?: string } };\n if (pkg.kb?.manifest) return pkgDir;\n }\n // Otherwise look in packages/*-entry.\n const packagesDir = join(pkgDir, 'packages');\n if (!(await exists(packagesDir))) return null;\n const entries = await readdir(packagesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (!entry.name.endsWith('-entry')) continue;\n const candidate = join(packagesDir, entry.name);\n if (await exists(join(candidate, 'package.json'))) return candidate;\n }\n return null;\n}\n\nexport interface ScanOptions {\n /**\n * Workspace root containing `.kb/marketplace.lock`. When provided, each\n * scaffolded plugin found is cross-checked against the lock — missing\n * entries surface as warnings so the user knows to `kb marketplace\n * plugins link` or rerun `kb scaffold`.\n */\n workspaceRoot?: string;\n}\n\n/**\n * Scan a root directory containing one or more plugin packages. A plugin\n * package has either:\n * - its own `package.json` at the root, or\n * - a `packages/` directory with child packages.\n *\n * When `opts.workspaceRoot` is given, also cross-checks every discovered\n * scaffolded plugin against `.kb/marketplace.lock`.\n */\nexport async function scanRoot(\n root: string,\n opts: ScanOptions = {},\n): Promise<ScanResult> {\n const findings: Finding[] = [];\n let packagesScanned = 0;\n\n async function visit(dir: string): Promise<void> {\n const pkgJson = join(dir, 'package.json');\n const packagesDir = join(dir, 'packages');\n if (await exists(pkgJson)) {\n findings.push(...(await scanPackage(dir)));\n packagesScanned += 1;\n }\n if (await exists(packagesDir)) {\n const entries = await readdir(packagesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) await visit(join(packagesDir, entry.name));\n }\n }\n }\n\n if (!(await exists(root))) {\n return {\n findings: [\n {\n severity: 'warn',\n package: root,\n message: 'scan root does not exist',\n },\n ],\n packagesScanned: 0,\n };\n }\n\n const entries = await readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) await visit(join(root, entry.name));\n }\n\n if (opts.workspaceRoot) {\n findings.push(...(await checkLockSync(root, opts.workspaceRoot)));\n }\n\n return { findings, packagesScanned };\n}\n\n/**\n * For each scaffolded plugin root under `scaffoldRoot`, verify that the\n * plugin's entry package is registered in `.kb/marketplace.lock`.\n *\n * Produces:\n * - warn \"plugin not registered in marketplace.lock (run `kb marketplace plugins link ...`)\"\n * - warn \"lock entry points elsewhere\"\n * - info \"plugin disabled in lock\"\n */\nasync function checkLockSync(\n scaffoldRoot: string,\n workspaceRoot: string,\n): Promise<Finding[]> {\n const out: Finding[] = [];\n const lock = await readLock(workspaceRoot);\n\n const entries = await readdir(scaffoldRoot, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const pluginDir = join(scaffoldRoot, entry.name);\n const entryPkgDir = await findEntryPackageDir(pluginDir);\n if (!entryPkgDir) continue;\n\n const pkg = (await readJson(join(entryPkgDir, 'package.json'))) as {\n name?: string;\n };\n const id = typeof pkg.name === 'string' ? pkg.name : entry.name;\n\n if (!lock || !lock.installed) {\n out.push({\n severity: 'warn',\n package: id,\n message:\n 'no .kb/marketplace.lock — scaffolded plugins will not be discovered until registered',\n });\n return out;\n }\n\n const lockEntry = lock.installed[id];\n if (!lockEntry) {\n const hint = relative(workspaceRoot, entryPkgDir);\n out.push({\n severity: 'warn',\n package: id,\n message: `not registered in marketplace.lock — run: kb marketplace plugins link ${hint}`,\n });\n continue;\n }\n\n if (lockEntry.enabled === false) {\n out.push({\n severity: 'info',\n package: id,\n message: 'registered but disabled in marketplace.lock',\n });\n }\n\n if (typeof lockEntry.resolvedPath === 'string') {\n const lockAbs = resolvePath(workspaceRoot, lockEntry.resolvedPath);\n if (lockAbs !== entryPkgDir) {\n out.push({\n severity: 'warn',\n package: id,\n message: `lock points at ${lockEntry.resolvedPath} but scaffolded package is at ${relative(workspaceRoot, entryPkgDir)}`,\n });\n }\n }\n }\n\n return out;\n}\n","const NAME_RE = /^[a-z][a-z0-9-]*$/;\nconst SCOPE_RE = /^@[a-z][a-z0-9-]*$/;\nconst SEMVER_RE = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/;\nconst IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\nconst RESERVED_NAMES = new Set([\n 'kb',\n 'core',\n 'sdk',\n 'test',\n 'tests',\n 'node_modules',\n 'dist',\n 'src',\n 'con',\n 'prn',\n 'nul',\n]);\n\nexport function validatePackageName(name: string): string | null {\n if (!name) return 'name is required';\n if (name.length > 214) return 'name must be <= 214 chars';\n if (!NAME_RE.test(name)) {\n return 'name must be lowercase, start with a letter, and contain only a-z 0-9 -';\n }\n if (RESERVED_NAMES.has(name)) return `name \"${name}\" is reserved`;\n return null;\n}\n\nexport function validateScope(scope: string): string | null {\n if (!scope) return null;\n if (!SCOPE_RE.test(scope)) {\n return 'scope must look like \"@acme\" (lowercase, starts with @, a-z 0-9 -)';\n }\n return null;\n}\n\nexport function validateSemver(v: string): string | null {\n return SEMVER_RE.test(v) ? null : 'expected semver (e.g. 1.2.3)';\n}\n\nexport function validateIdentifier(v: string): string | null {\n return IDENTIFIER_RE.test(v) ? null : 'expected a JS identifier';\n}\n\nexport function runValidator(\n kind: string,\n value: unknown,\n): string | null {\n if (typeof value !== 'string') return 'expected a string';\n switch (kind) {\n case 'npmName':\n return validatePackageName(value);\n case 'npmScope':\n return validateScope(value);\n case 'semver':\n return validateSemver(value);\n case 'identifier':\n return validateIdentifier(value);\n default:\n return null;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/scaffold-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.30.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Pure engine for the KB Labs scaffolder: loader, resolver, renderer, patch merger, writer.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"eta": "^3.5.0",
|
|
21
21
|
"yaml": "^2.6.1",
|
|
22
|
-
"@kb-labs/scaffold-contracts": "2.
|
|
22
|
+
"@kb-labs/scaffold-contracts": "2.30.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/node": "^24.3.3",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"tsup": "^8.5.0",
|
|
29
29
|
"typescript": "^5.6.3",
|
|
30
30
|
"vitest": "^3.2.4",
|
|
31
|
-
"@kb-labs/devkit": "2.
|
|
31
|
+
"@kb-labs/devkit": "2.30.0"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=20.0.0",
|