@kurotako/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/logger.ts","../src/collect.ts","../src/filter.ts","../src/graph.ts","../src/merge.ts","../src/writer/banner.ts","../src/writer/tree.ts","../src/writer/barrel.ts","../src/writer/directory.ts","../src/writer/package.ts","../src/writer/peers.ts","../src/writer/pm.ts","../src/writer/index.ts","../src/run.ts"],"sourcesContent":["/**\n * `@kurotako/core` — the orchestrator. `run()` wires parsers and generators\n * through the dependency DAG: parse -> merge -> order -> generate -> collect ->\n * write. Single entry point; see `backlog/features/core-pipeline/technical.md`.\n */\nexport * from './errors.js';\nexport { childLogger, noopLogger } from './logger.js';\nexport { run } from './run.js';\nexport type * from './types.js';\nexport { applyBanner, BANNER, GITATTRIBUTES } from './writer/banner.js';\nexport { synthesizeRootBarrels } from './writer/barrel.js';\nexport type { PlannedFile, WriteInput, Writer } from './writer/index.js';\nexport {\n directoryWriter,\n packageWriter,\n selectWriter,\n} from './writer/index.js';\nexport { collectPeerDependencies } from './writer/peers.js';\nexport type { PackageManager } from './writer/pm.js';\nexport { resolvePackageManager, runInstall } from './writer/pm.js';\n","/**\n * `TakoError` hierarchy. Every failure in the pipeline is fail-fast and carries\n * enough context to name the offending source or generator. The CLI maps any\n * `TakoError` to a formatted message + non-zero exit; a non-`TakoError` throw is\n * a bug and surfaces as a stack trace.\n *\n * Error table: `backlog/features/core-pipeline/technical.md` §Error model.\n */\nimport type { IrIssue } from '@kurotako/ir';\n\nexport class TakoError extends Error {\n readonly code: string;\n\n constructor(code: string, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = new.target.name;\n this.code = code;\n }\n}\n\nexport class NamespaceMismatchError extends TakoError {\n readonly namespace: string;\n readonly returned: string;\n\n constructor(namespace: string, returned: string) {\n super(\n 'namespace_mismatch',\n `parser for namespace '${namespace}' returned a SourceIR with namespace '${returned}'`,\n );\n this.namespace = namespace;\n this.returned = returned;\n }\n}\n\nexport class IrValidationError extends TakoError {\n readonly issues: IrIssue[];\n readonly namespace?: string;\n\n constructor(issues: IrIssue[], namespace?: string) {\n const detail = issues\n .map((i) => `${i.path === '' ? '<root>' : i.path}: ${i.message}`)\n .join('; ');\n const where = namespace ? ` in namespace '${namespace}'` : '';\n super('ir_invalid', `invalid IR${where}: ${detail}`);\n this.issues = issues;\n this.namespace = namespace;\n }\n}\n\nexport class DuplicateNamespaceError extends TakoError {\n readonly namespace: string;\n\n constructor(namespace: string) {\n super(\n 'duplicate_namespace',\n `two sources claim the namespace '${namespace}'`,\n );\n this.namespace = namespace;\n }\n}\n\nexport class UnknownDependencyError extends TakoError {\n readonly generator: string;\n readonly missing: string;\n\n constructor(generator: string, missing: string) {\n super(\n 'unknown_dependency',\n `generator '${generator}' declares a hard dependency on '${missing}', which is not in the config`,\n );\n this.generator = generator;\n this.missing = missing;\n }\n}\n\nexport class InvalidDependencyError extends TakoError {\n readonly generator: string;\n readonly dependency: string;\n\n constructor(generator: string, dependency: string) {\n super(\n 'invalid_dependency',\n `generator '${generator}' lists '${dependency}' in both dependsOn and optionalDependsOn`,\n );\n this.generator = generator;\n this.dependency = dependency;\n }\n}\n\nexport class DependencyCycleError extends TakoError {\n readonly cycle: string[];\n\n constructor(cycle: string[]) {\n super(\n 'dependency_cycle',\n `the generator dependency graph has a cycle: ${cycle.join(' -> ')}`,\n );\n this.cycle = cycle;\n }\n}\n\nexport class OutputCollisionError extends TakoError {\n readonly path: string;\n readonly generators: [string, string];\n\n constructor(path: string, generators: [string, string], hint?: string) {\n super(\n 'output_collision',\n `generators '${generators[0]}' and '${generators[1]}' both emit '${path}'${\n hint ? `. ${hint}` : ''\n }`,\n );\n this.path = path;\n this.generators = generators;\n }\n}\n\nexport class InvalidOutputPathError extends TakoError {\n readonly path: string;\n readonly generator: string;\n\n constructor(path: string, generator: string) {\n super(\n 'invalid_output_path',\n `generator '${generator}' emits '${path}', which escapes the output root`,\n );\n this.path = path;\n this.generator = generator;\n }\n}\n\nexport class UnsupportedOutputModeError extends TakoError {\n readonly mode: string;\n\n constructor(mode: string) {\n super(\n 'unsupported_output_mode',\n `unsupported output mode '${mode}' (expected 'dir' or 'package')`,\n );\n this.mode = mode;\n }\n}\n\nexport class OutputPeerConflictError extends TakoError {\n readonly namespace: string;\n readonly package: string;\n readonly ranges: string[];\n readonly generators: string[];\n\n constructor(\n namespace: string,\n pkg: string,\n ranges: string[],\n generators: string[],\n ) {\n super(\n 'output_peer_conflict',\n `namespace '${namespace}': generators [${generators.join(', ')}] declare peer '${pkg}' with conflicting ranges [${ranges.join(', ')}]`,\n );\n this.namespace = namespace;\n this.package = pkg;\n this.ranges = ranges;\n this.generators = generators;\n }\n}\n\nexport class PackageBuildError extends TakoError {\n readonly namespace: string;\n\n constructor(namespace: string, options?: { cause?: unknown }) {\n super(\n 'package_build_error',\n `the build of the generated package for namespace '${namespace}' failed`,\n options,\n );\n this.namespace = namespace;\n }\n}\n\nconst MISSING_PACKAGE_WORKSPACE_FILE_GUIDANCE: Record<string, string> = {\n 'tsconfig.base.json': `Create '<workspaceRoot>/tsconfig.base.json':\n{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"skipLibCheck\": true\n }\n}\n\nUse these values as-is, no adjustment needed: in particular, keep\n\"moduleResolution\": \"bundler\" — 'node16'/'nodenext' would fail to compile\nthe extensionless \\`export * from './zod';\\` that tako's generated root\nbarrel always emits.`,\n 'tsup.config.base.{ts,js,mjs,cjs}': `Create '<workspaceRoot>/tsup.config.base.ts':\nimport type { Options } from 'tsup';\n\nexport const basePreset: Options = {\n entry: ['src/index.ts'],\n format: ['esm', 'cjs'],\n dts: { compilerOptions: { composite: false, incremental: false } },\n sourcemap: true,\n clean: true,\n target: 'node22',\n outDir: 'dist',\n};`,\n \"'typescript' (devDependency, needed for the .d.ts build)\": `Run, from '<workspaceRoot>':\n <your package manager> add -D typescript`,\n};\n\nexport class MissingPackageWorkspaceFilesError extends TakoError {\n readonly workspaceRoot: string;\n readonly missing: string[];\n\n constructor(workspaceRoot: string, missing: string[]) {\n const guidance = missing\n .map((item) => {\n const template = MISSING_PACKAGE_WORKSPACE_FILE_GUIDANCE[item];\n return template\n ? template.replaceAll('<workspaceRoot>', workspaceRoot)\n : item;\n })\n .join('\\n\\n');\n super(\n 'missing_package_workspace_files',\n `mode 'package' requires 'tsconfig.base.json' and 'tsup.config.base.{ts,js,mjs,cjs}' in '${workspaceRoot}' (one directory above 'packagesDir'); missing: ${missing.join(', ')}\\n\\n${guidance}`,\n );\n this.workspaceRoot = workspaceRoot;\n this.missing = missing;\n }\n}\n\nexport class OutputNotGeneratedError extends TakoError {\n readonly path: string;\n\n constructor(path: string) {\n super(\n 'output_not_generated',\n `refusing to wipe '${path}': it is non-empty and its package.json lacks the '\"//\": \"Generated by tako…\"' marker`,\n );\n this.path = path;\n }\n}\n\nexport class PackageInstallError extends TakoError {\n readonly pm: string;\n\n constructor(pm: string, options?: { cause?: unknown }) {\n super(\n 'package_install_error',\n `the '${pm} install' step for the generated packages exited non-zero`,\n options,\n );\n this.pm = pm;\n }\n}\n\nexport class DriverError extends TakoError {\n readonly role: 'parser' | 'generator';\n readonly driverName: string;\n readonly namespace?: string;\n\n constructor(\n role: 'parser' | 'generator',\n driverName: string,\n options?: { cause?: unknown; namespace?: string },\n ) {\n const where = options?.namespace\n ? ` (namespace '${options.namespace}')`\n : '';\n super(\n 'driver_error',\n `${role} '${driverName}'${where} threw during ${role === 'parser' ? 'parse' : 'generate'}`,\n options,\n );\n this.role = role;\n this.driverName = driverName;\n this.namespace = options?.namespace;\n }\n}\n\nexport class HookError extends TakoError {\n readonly hook: string;\n\n constructor(hook: string, options?: { cause?: unknown }) {\n super('hook_error', `the '${hook}' hook threw`, options);\n this.hook = hook;\n }\n}\n","/**\n * The no-op `Logger` default and a `childLogger` wrapper that merges a\n * `{ namespace }` / `{ generator }` tag into every call's `meta`.\n */\nimport type { Logger } from './types.js';\n\n/** Default logger: swallows everything. The CLI injects a real one. */\nexport const noopLogger: Logger = {\n debug() {},\n info() {},\n warn() {},\n error() {},\n};\n\nfunction mergeMeta(\n prefixMeta: Record<string, unknown>,\n meta: unknown,\n): unknown {\n if (meta === undefined) {\n return { ...prefixMeta };\n }\n if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {\n return { ...prefixMeta, ...(meta as Record<string, unknown>) };\n }\n return { ...prefixMeta, value: meta };\n}\n\n/**\n * Wrap `base` so every message carries `prefixMeta` (e.g. `{ namespace }` or\n * `{ generator }`) merged into its `meta` argument.\n */\nexport function childLogger(\n base: Logger,\n prefixMeta: Record<string, unknown>,\n): Logger {\n return {\n debug: (msg, meta) => base.debug(msg, mergeMeta(prefixMeta, meta)),\n info: (msg, meta) => base.info(msg, mergeMeta(prefixMeta, meta)),\n warn: (msg, meta) => base.warn(msg, mergeMeta(prefixMeta, meta)),\n error: (msg, meta) => base.error(msg, mergeMeta(prefixMeta, meta)),\n };\n}\n","/**\n * `mergeTrees` — aggregate every generator's virtual file tree into one sorted\n * list, rejecting paths that escape the output root and paths claimed by two\n * generators. The synthesized `<ns>/index.ts` barrel and the banner pass are\n * separate `run.ts` steps (added by output-modes); `mergeTrees` only aggregates\n * and detects collisions.\n */\nimport path from 'node:path';\nimport { InvalidOutputPathError, OutputCollisionError } from './errors.js';\nimport type { VirtualFile } from './types.js';\n\nexport interface GeneratorTree {\n generator: string;\n files: VirtualFile[];\n}\n\n/**\n * Normalize to a POSIX path relative to the root. Throws `InvalidOutputPathError`\n * for an absolute path or one that climbs above the root.\n */\nfunction normalizePath(rawPath: string, generator: string): string {\n const posix = rawPath.replace(/\\\\/g, '/');\n if (posix.startsWith('/')) {\n throw new InvalidOutputPathError(rawPath, generator);\n }\n const normalized = path.posix.normalize(posix);\n if (\n normalized === '..' ||\n normalized.startsWith('../') ||\n path.posix.isAbsolute(normalized)\n ) {\n throw new InvalidOutputPathError(rawPath, generator);\n }\n return normalized;\n}\n\nexport function mergeTrees(\n perGenerator: GeneratorTree[],\n opts?: { collisionHint?: string },\n): VirtualFile[] {\n const byPath = new Map<string, { generator: string; file: VirtualFile }>();\n\n for (const { generator, files } of perGenerator) {\n for (const file of files) {\n const normalized = normalizePath(file.path, generator);\n const existing = byPath.get(normalized);\n if (existing) {\n throw new OutputCollisionError(\n normalized,\n [existing.generator, generator],\n opts?.collisionHint,\n );\n }\n byPath.set(normalized, {\n generator,\n file: { path: normalized, content: file.content },\n });\n }\n }\n\n return [...byPath.values()]\n .map((entry) => entry.file)\n .sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n}\n","/**\n * `filterIR` — the namespace-filtered IR view handed to a generator. A deep\n * clone (`structuredClone`) so a misbehaving generator cannot mutate shared\n * state. Relations targeting an excluded namespace stay in the clone as-is:\n * `@kurotako/ir` treats an absent target namespace as informational and v1\n * drivers ignore cross-source relations.\n */\nimport type { IR, SourceIR } from '@kurotako/ir';\n\n/**\n * `undefined` namespaces => a clone of the whole IR. Otherwise => a clone\n * keeping only the requested keys in `ir.sources`, in the original key order. A\n * requested namespace absent from `ir.sources` is ignored (`filterIR` stays\n * total; config validity is config-system's job).\n */\nexport function filterIR(ir: IR, namespaces?: string[]): IR {\n const clone = structuredClone(ir);\n if (namespaces === undefined) {\n return clone;\n }\n\n const keep = new Set(namespaces);\n const sources: Record<string, SourceIR> = {};\n for (const [key, source] of Object.entries(clone.sources)) {\n if (keep.has(key)) {\n sources[key] = source;\n }\n }\n clone.sources = sources;\n return clone;\n}\n","/**\n * `generatorOrder` — deterministic topological sort of the generator dependency\n * graph (ADR-0002). `dependsOn` is a hard dependency (absent from the config =>\n * error); `optionalDependsOn` is soft (absent => the edge is dropped). Both\n * constrain order. Kahn's algorithm, ties broken by config declaration order.\n */\nimport {\n DependencyCycleError,\n InvalidDependencyError,\n UnknownDependencyError,\n} from './errors.js';\nimport type { GeneratorConfig } from './types.js';\n\nexport function generatorOrder(\n generators: Record<string, GeneratorConfig>,\n): string[] {\n const names = Object.keys(generators);\n const index = new Map(names.map((name, i) => [name, i]));\n\n // adjacency: dep -> dependents; indegree counts incoming hard+optional edges.\n const dependents = new Map<string, string[]>(names.map((n) => [n, []]));\n const indegree = new Map<string, number>(names.map((n) => [n, 0]));\n\n for (const name of names) {\n const cfg = generators[name];\n const hard = cfg?.generator.dependsOn ?? [];\n const optional = cfg?.generator.optionalDependsOn ?? [];\n\n const seen = new Set<string>();\n const addEdge = (dep: string) => {\n if (seen.has(dep)) {\n return;\n }\n seen.add(dep);\n dependents.get(dep)?.push(name);\n indegree.set(name, (indegree.get(name) ?? 0) + 1);\n };\n\n for (const dep of hard) {\n if (optional.includes(dep)) {\n throw new InvalidDependencyError(name, dep);\n }\n if (!index.has(dep)) {\n throw new UnknownDependencyError(name, dep);\n }\n addEdge(dep);\n }\n for (const dep of optional) {\n if (!index.has(dep)) {\n continue;\n }\n addEdge(dep);\n }\n }\n\n const byConfigOrder = (a: string, b: string) =>\n (index.get(a) ?? 0) - (index.get(b) ?? 0);\n\n const ready = names\n .filter((n) => (indegree.get(n) ?? 0) === 0)\n .sort(byConfigOrder);\n const order: string[] = [];\n\n while (ready.length > 0) {\n const node = ready.shift() as string;\n order.push(node);\n for (const dependent of dependents.get(node) ?? []) {\n const next = (indegree.get(dependent) ?? 0) - 1;\n indegree.set(dependent, next);\n if (next === 0) {\n ready.push(dependent);\n ready.sort(byConfigOrder);\n }\n }\n }\n\n if (order.length < names.length) {\n const remaining = new Set(names.filter((n) => !order.includes(n)));\n throw new DependencyCycleError(findCycle(remaining, dependents));\n }\n\n return order;\n}\n\n/**\n * Extract a readable cycle path from the residual subgraph. `dependents` maps\n * `dep -> [dependents]`; we walk that direction and report the loop we close.\n */\nfunction findCycle(\n nodes: Set<string>,\n dependents: Map<string, string[]>,\n): string[] {\n const stack: string[] = [];\n const onStack = new Set<string>();\n const visited = new Set<string>();\n\n const walk = (node: string): string[] | undefined => {\n stack.push(node);\n onStack.add(node);\n for (const next of dependents.get(node) ?? []) {\n if (!nodes.has(next)) {\n continue;\n }\n if (onStack.has(next)) {\n return [...stack.slice(stack.indexOf(next)), next];\n }\n if (!visited.has(next)) {\n const found = walk(next);\n if (found) {\n return found;\n }\n }\n }\n stack.pop();\n onStack.delete(node);\n visited.add(node);\n return undefined;\n };\n\n for (const node of nodes) {\n if (!visited.has(node)) {\n const found = walk(node);\n if (found) {\n return found;\n }\n }\n }\n return [...nodes];\n}\n","/**\n * `mergeSources` — turn the per-source `SourceIR`s produced by the parsers into\n * the single global `IR`. Merge and the duplicate-namespace policy are\n * orchestration concerns, left to this package by `@kurotako/ir`\n * (`ir-model/technical.md` §Out of scope here).\n */\n\nimport type { IR, SourceIR } from '@kurotako/ir';\nimport {\n assertIR,\n IR_VERSION,\n IrValidationError as IrModelValidationError,\n validateSourceIR,\n} from '@kurotako/ir';\nimport {\n DuplicateNamespaceError,\n IrValidationError,\n NamespaceMismatchError,\n} from './errors.js';\n\nexport interface MergeEntry {\n namespace: string;\n sourceIR: SourceIR;\n}\n\n/**\n * Build `{ irVersion, sources }` from `entries`, inserting each `SourceIR` under\n * its namespace in input order. Rejects a namespace mismatch, a per-source\n * validation failure, a duplicate namespace, and a post-merge cross-source\n * coherence failure.\n */\nexport function mergeSources(entries: MergeEntry[]): IR {\n const sources: Record<string, SourceIR> = {};\n\n for (const { namespace, sourceIR } of entries) {\n if (sourceIR.namespace !== namespace) {\n throw new NamespaceMismatchError(namespace, sourceIR.namespace);\n }\n\n const validation = validateSourceIR(sourceIR);\n if (!validation.ok) {\n throw new IrValidationError(validation.issues, namespace);\n }\n\n if (namespace in sources) {\n throw new DuplicateNamespaceError(namespace);\n }\n sources[namespace] = validation.value;\n }\n\n const ir: IR = { irVersion: IR_VERSION, sources };\n\n try {\n assertIR(ir);\n } catch (error) {\n if (error instanceof IrModelValidationError) {\n throw new IrValidationError(error.issues);\n }\n throw error;\n }\n\n return ir;\n}\n","/**\n * The generated-file banner. `run.ts` calls `applyBanner` once, after barrel\n * synthesis and before the writer, so every `.ts` file — generator output and\n * synthesized barrels alike — carries the marker. `.json` files have no comment\n * syntax: `packageWriter` sets a `\"//\"` key on `package.json` instead.\n *\n * Design: `backlog/features/output-modes/technical.md` §Banner.\n */\nimport type { VirtualFile } from '../types.js';\n\nexport const BANNER = '// Generated by tako. Do not edit.\\n';\nexport const GITATTRIBUTES = '* linguist-generated=true\\n';\n\n/** Basenames that take the comment-form banner despite a non-`.ts` extension. */\nconst COMMENTABLE_BASENAMES = new Set(['tsconfig.json']);\n\nfunction takesBanner(path: string): boolean {\n if (path.endsWith('.ts') || path.endsWith('.tsx')) {\n return true;\n }\n const basename = path.slice(path.lastIndexOf('/') + 1);\n return COMMENTABLE_BASENAMES.has(basename);\n}\n\n/**\n * Prepend `BANNER` to every `.ts` / `.tsx` file (and `tsconfig.json`). Pure,\n * and idempotent-safe: a file that already starts with the banner is left\n * untouched. `package.json` and other `.json` files pass through unchanged.\n */\nexport function applyBanner(files: VirtualFile[]): VirtualFile[] {\n return files.map((file) => {\n if (!takesBanner(file.path) || file.content.startsWith(BANNER)) {\n return file;\n }\n return { path: file.path, content: BANNER + file.content };\n });\n}\n","/**\n * Shared virtual-tree helpers for the writer layer. A generator owns the\n * `<namespace>/<generatorName>/` sub-tree; barrel synthesis and mode-B\n * packaging both need the namespace -> contributing-generators mapping.\n */\nimport type { VirtualFile } from '../types.js';\n\n/**\n * Map each namespace (first path segment) to the sorted list of generator\n * names (second path segment) that emitted at least one file under\n * `<namespace>/<generatorName>/`. Files with fewer than three segments (e.g. a\n * stray `<namespace>/index.ts`) contribute no generator name.\n */\nexport function contributingGenerators(\n files: VirtualFile[],\n): Map<string, string[]> {\n const acc = new Map<string, Set<string>>();\n for (const file of files) {\n const parts = file.path.split('/');\n if (parts.length < 3) {\n continue;\n }\n const [namespace, generator] = parts;\n if (!namespace || !generator) {\n continue;\n }\n let set = acc.get(namespace);\n if (!set) {\n set = new Set<string>();\n acc.set(namespace, set);\n }\n set.add(generator);\n }\n\n const out = new Map<string, string[]>();\n for (const [namespace, set] of acc) {\n out.set(namespace, [...set].sort());\n }\n return out;\n}\n","/**\n * Root-barrel synthesis. Each generator owns `<namespace>/<generatorName>/` and\n * emits its own barrel there; `tako` synthesizes `<namespace>/index.ts` so\n * `import … from '<scope>/<namespace>'` resolves regardless of how many\n * generators ran. Mode-independent — mode A and mode B both get the barrel.\n *\n * Design: `backlog/features/output-modes/technical.md` §New orchestration step.\n */\nimport type { GeneratorArtifact, Logger, VirtualFile } from '../types.js';\nimport { contributingGenerators } from './tree.js';\n\n/**\n * One `VirtualFile { path: '<ns>/index.ts' }` per namespace present in `files`,\n * its content one sorted `export * from './<generatorName>';` line per\n * generator that contributed a file under `<ns>/<generatorName>/`. A\n * single-generator namespace still gets a barrel.\n *\n * When `artifactsByGenerator` is supplied, `logger?.warn(...)` fires if the same\n * exported identifier appears in two contributing artifacts for one namespace\n * (an ambiguous star re-export TypeScript/ESM silently drops). Never throws.\n */\nexport function synthesizeRootBarrels(\n files: VirtualFile[],\n artifactsByGenerator?: Record<string, GeneratorArtifact>,\n logger?: Logger,\n): VirtualFile[] {\n const contributors = contributingGenerators(files);\n const barrels: VirtualFile[] = [];\n\n for (const namespace of [...contributors.keys()].sort()) {\n const generators = contributors.get(namespace) ?? [];\n if (artifactsByGenerator && logger) {\n warnAmbiguousReExports(\n namespace,\n generators,\n artifactsByGenerator,\n logger,\n );\n }\n const content = generators\n .map((name) => `export * from './${name}';\\n`)\n .join('');\n barrels.push({ path: `${namespace}/index.ts`, content });\n }\n\n return barrels;\n}\n\nfunction warnAmbiguousReExports(\n namespace: string,\n generators: string[],\n artifactsByGenerator: Record<string, GeneratorArtifact>,\n logger: Logger,\n): void {\n const owners = new Map<string, string[]>();\n\n for (const name of generators) {\n const artifact = artifactsByGenerator[name];\n if (!artifact) {\n continue;\n }\n const identifiers = new Set<string>();\n for (const [key, entity] of Object.entries(artifact.entities)) {\n const dot = key.indexOf('.');\n const entityNamespace = dot === -1 ? key : key.slice(0, dot);\n if (entityNamespace !== namespace) {\n continue;\n }\n for (const identifier of Object.values(entity.symbols)) {\n identifiers.add(identifier);\n }\n }\n for (const identifier of identifiers) {\n const list = owners.get(identifier) ?? [];\n list.push(name);\n owners.set(identifier, list);\n }\n }\n\n for (const [identifier, list] of owners) {\n if (list.length > 1) {\n const sorted = [...list].sort();\n logger.warn(\n `namespace '${namespace}': identifier '${identifier}' is re-exported by generators [${sorted.join(\n ', ',\n )}]; the ambiguous star re-export from '${namespace}/index.ts' will be dropped. Import it from a generator subpath instead.`,\n { namespace, identifier, generators: sorted },\n );\n }\n }\n}\n","/**\n * Mode A writer: `tako` is the exclusive owner of `output.dir` and wipes it\n * unconditionally before generation — no run marker, no path guard (accepted\n * risk, see `core-pipeline/technical.md` §Accepted risks). Disk access is\n * `node:fs/promises` only.\n *\n * `plan()` is the pure layout half (path + bytes, no disk I/O); `write()` is\n * `plan()` followed by the unconditional wipe + `writeFile` over the plan.\n */\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TakoError } from '../errors.js';\nimport type { PlannedFile, Writer } from './types.js';\n\nconst GITATTRIBUTES = '* linguist-generated=true\\n';\n\nfunction sortByPath<T extends { path: string }>(entries: T[]): T[] {\n return [...entries].sort((a, b) =>\n a.path < b.path ? -1 : a.path > b.path ? 1 : 0,\n );\n}\n\nexport const directoryWriter: Writer = {\n async plan({ files, output }) {\n if (!output.dir) {\n throw new TakoError(\n 'invalid_output_config',\n \"mode 'dir' requires 'output.dir'\",\n );\n }\n const dir = path.resolve(output.dir);\n\n const planned: PlannedFile[] = files.map((file) => ({\n path: path.join(dir, file.path),\n content: file.content,\n }));\n planned.push({\n path: path.join(dir, '.gitattributes'),\n content: GITATTRIBUTES,\n });\n\n return sortByPath(planned);\n },\n\n async write(input) {\n const planned = await this.plan(input);\n const dir = path.resolve(input.output.dir as string);\n\n await fs.rm(dir, { recursive: true, force: true });\n await fs.mkdir(dir, { recursive: true });\n\n for (const file of planned) {\n await fs.mkdir(path.dirname(file.path), { recursive: true });\n await fs.writeFile(file.path, file.content, 'utf8');\n }\n\n return planned.map((file) => file.path);\n },\n};\n","/**\n * Mode B writer: one npm package per namespace under `output.packagesDir`.\n * `packageWriter` writes the sources, synthesizes `package.json` /\n * `tsconfig.json` / `tsup.config.ts`, builds each package with a lazily loaded\n * `tsup`, then runs `<pm> install` once to link them.\n *\n * `tsup` is a `dependencies` of `@kurotako/core` but imported with\n * `await import('tsup')` so a mode-A run never resolves it.\n *\n * Design: `backlog/features/output-modes/technical.md` §`packageWriter` (mode B).\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport {\n MissingPackageWorkspaceFilesError,\n OutputNotGeneratedError,\n PackageBuildError,\n TakoError,\n} from '../errors.js';\nimport { noopLogger } from '../logger.js';\nimport type { VirtualFile } from '../types.js';\nimport { BANNER, GITATTRIBUTES } from './banner.js';\nimport { collectPeerDependencies } from './peers.js';\nimport { ancestors, resolvePackageManager, runInstall } from './pm.js';\nimport type { PlannedFile, WriteInput, Writer } from './types.js';\n\nconst MARKER = 'Generated by tako. Do not edit.';\n\ninterface PackageLayout {\n packagesDir: string;\n scopeSlug: string;\n /** Sorted. */\n namespaces: string[];\n /** Namespace -> sorted `src/<path>` entry list (for the tsup build). */\n entriesByNamespace: Map<string, string[]>;\n /** Sorted by `path`. */\n planned: PlannedFile[];\n}\n\n/**\n * The deterministic half of `packageWriter`: `<pkgDir>/src/…` (the `<ns>/`\n * prefix stripped) plus the synthesized `package.json` / `tsconfig.json` /\n * `tsup.config.ts` / `.gitattributes` and the `<packagesDir>/.gitattributes`.\n * No `dist/`, no `import('tsup')`, no `pm install`, no `fs` access.\n */\nfunction computePackageLayout({\n files,\n output,\n artifacts,\n}: WriteInput): PackageLayout {\n if (!output.packagesDir) {\n throw new TakoError(\n 'invalid_output_config',\n \"mode 'package' requires 'output.packagesDir'\",\n );\n }\n if (!output.scope) {\n throw new TakoError(\n 'invalid_output_config',\n \"mode 'package' requires 'output.scope'\",\n );\n }\n\n const packagesDir = path.resolve(output.packagesDir);\n const scope = output.scope;\n const scopeSlug = scope.replace(/^@/, '');\n const peersByNamespace = collectPeerDependencies(artifacts ?? {}, files);\n\n const byNamespace = new Map<string, VirtualFile[]>();\n for (const file of files) {\n const slash = file.path.indexOf('/');\n if (slash === -1) {\n continue;\n }\n const namespace = file.path.slice(0, slash);\n const rest = file.path.slice(slash + 1);\n const list = byNamespace.get(namespace) ?? [];\n list.push({ path: rest, content: file.content });\n byNamespace.set(namespace, list);\n }\n\n const namespaces = [...byNamespace.keys()].sort();\n const entriesByNamespace = new Map<string, string[]>();\n const planned: PlannedFile[] = [];\n\n for (const namespace of namespaces) {\n const sources = [...(byNamespace.get(namespace) ?? [])].sort((a, b) =>\n a.path < b.path ? -1 : a.path > b.path ? 1 : 0,\n );\n const pkgDir = path.join(packagesDir, `${scopeSlug}-${namespace}`);\n\n const entries: string[] = [];\n for (const src of sources) {\n planned.push({\n path: path.join(pkgDir, 'src', src.path),\n content: src.content,\n });\n entries.push(`src/${src.path}`);\n }\n\n planned.push({\n path: path.join(pkgDir, 'package.json'),\n content: buildPackageJson(\n scope,\n namespace,\n peersByNamespace[namespace] ?? {},\n ),\n });\n planned.push({\n path: path.join(pkgDir, 'tsconfig.json'),\n content: buildTsconfig(namespace),\n });\n\n const sortedEntries = entries.sort();\n entriesByNamespace.set(namespace, sortedEntries);\n planned.push({\n path: path.join(pkgDir, 'tsup.config.ts'),\n content: buildTsupConfig(sortedEntries),\n });\n planned.push({\n path: path.join(pkgDir, '.gitattributes'),\n content: GITATTRIBUTES,\n });\n }\n\n planned.push({\n path: path.join(packagesDir, '.gitattributes'),\n content: `${scopeSlug}-*/** linguist-generated=true\\n`,\n });\n\n planned.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n\n return { packagesDir, scopeSlug, namespaces, entriesByNamespace, planned };\n}\n\nexport const packageWriter: Writer = {\n async plan(input) {\n return computePackageLayout(input).planned;\n },\n\n async write({ files, output, artifacts, logger = noopLogger }) {\n const { packagesDir, scopeSlug, namespaces, entriesByNamespace, planned } =\n computePackageLayout({ files, output, artifacts, logger });\n assertWorkspaceBaseFiles(packagesDir);\n\n await fs.mkdir(packagesDir, { recursive: true });\n for (const namespace of namespaces) {\n await guardAndReset(path.join(packagesDir, `${scopeSlug}-${namespace}`));\n }\n\n const written: string[] = [];\n for (const file of planned) {\n await fs.mkdir(path.dirname(file.path), { recursive: true });\n await fs.writeFile(file.path, file.content, 'utf8');\n written.push(file.path);\n }\n\n await buildPackages(packagesDir, scopeSlug, namespaces, entriesByNamespace);\n\n const pm = resolvePackageManager({\n configured: output.packageManager,\n startDir: packagesDir,\n });\n if (pm) {\n await runInstall(pm, findWorkspaceRoot(packagesDir) ?? packagesDir);\n } else {\n logger.warn(\n \"could not resolve a package manager; run '<your package manager> install' in the workspace root to link the generated packages\",\n { packagesDir },\n );\n }\n\n return written.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n },\n};\n\nconst TSUP_CONFIG_BASE_EXTENSIONS = ['.ts', '.js', '.mjs', '.cjs'];\n\n/**\n * The generated `tsconfig.json` / `tsup.config.ts` reference `../../tsconfig.base.json`\n * / `../../tsup.config.base` (two levels up from `<pkgDir>`, i.e. one level up from\n * `packagesDir`). Failing fast here turns an opaque esbuild \"Could not resolve\" into\n * an actionable error naming exactly what's missing and where.\n */\nfunction assertWorkspaceBaseFiles(packagesDir: string): void {\n const workspaceRoot = path.dirname(packagesDir);\n const missing: string[] = [];\n\n if (!existsSync(path.join(workspaceRoot, 'tsconfig.base.json'))) {\n missing.push('tsconfig.base.json');\n }\n const hasTsupBase = TSUP_CONFIG_BASE_EXTENSIONS.some((ext) =>\n existsSync(path.join(workspaceRoot, `tsup.config.base${ext}`)),\n );\n if (!hasTsupBase) {\n missing.push('tsup.config.base.{ts,js,mjs,cjs}');\n }\n if (!isResolvableFrom('typescript', workspaceRoot)) {\n missing.push(\"'typescript' (devDependency, needed for the .d.ts build)\");\n }\n\n if (missing.length > 0) {\n throw new MissingPackageWorkspaceFilesError(workspaceRoot, missing);\n }\n}\n\nfunction isResolvableFrom(specifier: string, from: string): boolean {\n try {\n createRequire(path.join(from, 'noop.js')).resolve(specifier);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function guardAndReset(pkgDir: string): Promise<void> {\n let entries: string[];\n try {\n entries = await fs.readdir(pkgDir);\n } catch {\n entries = [];\n }\n\n if (entries.length > 0 && !hasGeneratedMarker(pkgDir)) {\n throw new OutputNotGeneratedError(pkgDir);\n }\n\n await fs.rm(pkgDir, { recursive: true, force: true });\n await fs.mkdir(pkgDir, { recursive: true });\n}\n\nfunction hasGeneratedMarker(pkgDir: string): boolean {\n try {\n const pkg = JSON.parse(\n readFileSync(path.join(pkgDir, 'package.json'), 'utf8'),\n ) as { '//'?: unknown };\n return (\n typeof pkg['//'] === 'string' && pkg['//'].startsWith('Generated by tako')\n );\n } catch {\n return false;\n }\n}\n\nasync function buildPackages(\n packagesDir: string,\n scopeSlug: string,\n namespaces: string[],\n entriesByNamespace: Map<string, string[]>,\n): Promise<void> {\n const { build } = await import('tsup');\n const originalCwd = process.cwd();\n try {\n for (const namespace of namespaces) {\n const pkgDir = path.join(packagesDir, `${scopeSlug}-${namespace}`);\n // Still needed: tsup/esbuild auto-detects `peerDependencies` (e.g. `zod`)\n // as external by reading the nearest `package.json`, which it locates\n // from `process.cwd()`.\n process.chdir(pkgDir);\n try {\n await build({\n // Config auto-discovery (cosmiconfig) is disabled: the pkgDir's own\n // tsup.config.ts exists for humans building the package standalone\n // later, but resolving it here — a TS file re-exporting\n // `../../tsup.config.base` — through tsup's config loader instead of\n // this programmatic call caused spurious \"Could not resolve\" entry\n // errors.\n config: false,\n // A relative `entry` array goes through tinyglobby, whose matches\n // esbuild then resolves against the cwd esbuild's service captured\n // at first use — *not* the cwd at this call, so it silently breaks\n // after the first `process.chdir()` in this loop. An absolute-path\n // entry *map* skips glob resolution entirely (tsup only runs\n // `fs.existsSync` on it) and keeps `dist/` mirroring `src/`.\n entry: Object.fromEntries(\n (entriesByNamespace.get(namespace) ?? []).map((entry) => [\n entry.replace(/^src\\//, '').replace(/\\.ts$/, ''),\n path.join(pkgDir, entry),\n ]),\n ),\n tsconfig: path.join(pkgDir, 'tsconfig.json'),\n format: ['esm', 'cjs'],\n dts: { compilerOptions: { composite: false, incremental: false } },\n outDir: path.join(pkgDir, 'dist'),\n silent: true,\n });\n } catch (cause) {\n throw new PackageBuildError(namespace, { cause });\n }\n }\n } finally {\n process.chdir(originalCwd);\n }\n}\n\nfunction findWorkspaceRoot(startDir: string): string | null {\n for (const dir of ancestors(startDir)) {\n if (existsSync(path.join(dir, 'pnpm-workspace.yaml'))) {\n return dir;\n }\n const pkgPath = path.join(dir, 'package.json');\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n workspaces?: unknown;\n };\n if (pkg.workspaces !== undefined) {\n return dir;\n }\n } catch {\n // keep walking\n }\n }\n }\n return null;\n}\n\nfunction buildPackageJson(\n scope: string,\n namespace: string,\n peerDependencies: Record<string, string>,\n): string {\n const pkg = {\n name: `${scope}/${namespace}`,\n version: '0.0.0',\n type: 'module',\n main: './dist/index.cjs',\n module: './dist/index.js',\n types: './dist/index.d.ts',\n exports: {\n '.': {\n types: './dist/index.d.ts',\n import: './dist/index.js',\n require: './dist/index.cjs',\n },\n './*': {\n types: './dist/*.d.ts',\n import: './dist/*.js',\n require: './dist/*.cjs',\n },\n },\n files: ['dist', 'src'],\n peerDependencies,\n sideEffects: false,\n scripts: { build: 'tsup' },\n '//': MARKER,\n };\n return `${JSON.stringify(pkg, null, 2)}\\n`;\n}\n\n/**\n * A generator's emitted imports use the artifact-reported, namespace-prefixed\n * module specifier verbatim (e.g. `pg/zod/User.schema`,\n * `generator-angular/technical.md` §Naming) — including across sub-trees within\n * the same namespace/package (`gen-angular` importing a `gen-zod` symbol). Mode\n * B collapses one namespace into one package with the `<ns>/` prefix stripped\n * from `src/` (step 3), so those bare specifiers only resolve if the package\n * self-references its own `<ns>/*` prefix back to `./src/*` — hence the\n * `paths` entry below, which both this file (for humans building the package\n * standalone) and the internal `tsup` build (`buildPackages`, same\n * `tsconfig.json` path) rely on.\n */\nfunction buildTsconfig(namespace: string): string {\n const body = JSON.stringify(\n {\n extends: '../../tsconfig.base.json',\n compilerOptions: {\n outDir: 'dist',\n paths: { [`${namespace}/*`]: ['./src/*'] },\n },\n include: ['src'],\n },\n null,\n 2,\n );\n return `${BANNER}${body}\\n`;\n}\n\nfunction buildTsupConfig(entries: string[]): string {\n const list = entries.map((entry) => ` '${entry}',`).join('\\n');\n return `${BANNER}import { basePreset } from '../../tsup.config.base';\n\nexport default {\n ...basePreset,\n entry: [\n${list}\n ],\n};\n`;\n}\n","/**\n * Peer-dependency aggregation for mode B. Each generated package (one per\n * namespace) declares the union of the `peerDependencies` of every generator\n * that contributed to it. The consuming app provides the runtime (`zod`,\n * `@angular/*`); the generated package must not drag a second copy.\n *\n * Design: `backlog/features/output-modes/technical.md` §`packageWriter` (mode B).\n */\nimport { OutputPeerConflictError } from '../errors.js';\nimport type { GeneratorArtifact, VirtualFile } from '../types.js';\nimport { contributingGenerators } from './tree.js';\n\n/**\n * Namespace -> (package -> semver range). Per namespace, union the\n * `peerDependencies` of every generator that emitted a file under\n * `<namespace>/<generatorName>/`. Identical ranges de-duplicate; the same\n * package with two different ranges from two generators throws\n * `OutputPeerConflictError` (fail-fast). Namespace and package keys are sorted.\n */\nexport function collectPeerDependencies(\n artifactsByGenerator: Record<string, GeneratorArtifact>,\n files: VirtualFile[],\n): Record<string, Record<string, string>> {\n const contributors = contributingGenerators(files);\n const result: Record<string, Record<string, string>> = {};\n\n for (const namespace of [...contributors.keys()].sort()) {\n const generators = contributors.get(namespace) ?? [];\n const merged = new Map<string, { range: string; generator: string }>();\n\n for (const generator of generators) {\n const peers = artifactsByGenerator[generator]?.peerDependencies;\n if (!peers) {\n continue;\n }\n for (const [pkg, range] of Object.entries(peers)) {\n const existing = merged.get(pkg);\n if (existing && existing.range !== range) {\n throw new OutputPeerConflictError(\n namespace,\n pkg,\n [existing.range, range],\n [existing.generator, generator],\n );\n }\n if (!existing) {\n merged.set(pkg, { range, generator });\n }\n }\n }\n\n const sorted: Record<string, string> = {};\n for (const pkg of [...merged.keys()].sort()) {\n const entry = merged.get(pkg);\n if (entry) {\n sorted[pkg] = entry.range;\n }\n }\n result[namespace] = sorted;\n }\n\n return result;\n}\n","/**\n * Package-manager resolution and the mode-B `install` step. `tako generate` in\n * mode B links the freshly generated packages by running `<pm> install` once.\n * When no package manager can be resolved, `tako` does not guess — it prints\n * the command for the user to run.\n *\n * Disk access via `node:fs` (sync, resolution is cheap and one-shot),\n * subprocess via `node:child_process` — no `Bun.*`.\n *\n * Design: `backlog/features/output-modes/technical.md` §Package manager.\n */\nimport { execFile } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\nimport { PackageInstallError } from '../errors.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport type PackageManager = 'bun' | 'pnpm' | 'yarn' | 'npm';\n\nconst PACKAGE_MANAGERS: readonly PackageManager[] = [\n 'bun',\n 'pnpm',\n 'yarn',\n 'npm',\n];\n\nconst LOCKFILES: readonly [string, PackageManager][] = [\n ['bun.lock', 'bun'],\n ['bun.lockb', 'bun'],\n ['pnpm-lock.yaml', 'pnpm'],\n ['yarn.lock', 'yarn'],\n ['package-lock.json', 'npm'],\n];\n\nfunction isPackageManager(value: string): value is PackageManager {\n return (PACKAGE_MANAGERS as readonly string[]).includes(value);\n}\n\nexport function* ancestors(startDir: string): Generator<string> {\n let dir = path.resolve(startDir);\n while (true) {\n yield dir;\n const parent = path.dirname(dir);\n if (parent === dir) {\n return;\n }\n dir = parent;\n }\n}\n\n/**\n * Resolve the package manager to run `install` with, in order:\n * 1. `configured` (from `output.packageManager`) — used verbatim;\n * 2. lockfile walk-up from `startDir` (`bun.lock` / `bun.lockb` -> `bun`,\n * `pnpm-lock.yaml` -> `pnpm`, `yarn.lock` -> `yarn`,\n * `package-lock.json` -> `npm`), stopping at a `.git` marker or the root;\n * 3. nearest ancestor `package.json` `packageManager` field (name before `@`);\n * 4. `null` — do not guess.\n */\nexport function resolvePackageManager(opts: {\n configured?: PackageManager;\n startDir: string;\n}): PackageManager | null {\n if (opts.configured) {\n return opts.configured;\n }\n\n for (const dir of ancestors(opts.startDir)) {\n for (const [file, pm] of LOCKFILES) {\n if (existsSync(path.join(dir, file))) {\n return pm;\n }\n }\n if (existsSync(path.join(dir, '.git'))) {\n break;\n }\n }\n\n for (const dir of ancestors(opts.startDir)) {\n const pkgPath = path.join(dir, 'package.json');\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n packageManager?: unknown;\n };\n if (typeof pkg.packageManager === 'string') {\n const name = pkg.packageManager.split('@')[0] ?? '';\n if (isPackageManager(name)) {\n return name;\n }\n }\n } catch {\n // Unreadable / malformed package.json — keep walking up.\n }\n }\n if (existsSync(path.join(dir, '.git'))) {\n break;\n }\n }\n\n return null;\n}\n\n/**\n * Run `<pm> install` in `cwd`. No `--frozen-lockfile` — the generated packages\n * are new, the lockfile must change. A non-zero exit becomes\n * `PackageInstallError { pm, cause }`.\n */\nexport async function runInstall(\n pm: PackageManager,\n cwd: string,\n): Promise<void> {\n try {\n await execFileAsync(pm, ['install'], { cwd });\n } catch (cause) {\n throw new PackageInstallError(pm, { cause });\n }\n}\n","/**\n * `selectWriter` — pick the writer for `output.mode`. `'dir'` or undefined =>\n * `directoryWriter`; `'package'` => `packageWriter`; anything else =>\n * `UnsupportedOutputModeError`.\n */\nimport { UnsupportedOutputModeError } from '../errors.js';\nimport type { OutputConfig } from '../types.js';\nimport { directoryWriter } from './directory.js';\nimport { packageWriter } from './package.js';\nimport type { Writer } from './types.js';\n\nexport { directoryWriter } from './directory.js';\nexport { packageWriter } from './package.js';\nexport type { PlannedFile, WriteInput, Writer } from './types.js';\n\nexport function selectWriter(output: OutputConfig): Writer {\n const mode = output.mode ?? 'dir';\n if (mode === 'dir') {\n return directoryWriter;\n }\n if (mode === 'package') {\n return packageWriter;\n }\n throw new UnsupportedOutputModeError(mode);\n}\n","/**\n * `run()` — the single public entry point. Sequential, fail-fast: parse ->\n * merge -> order -> generate -> collect -> write -> afterEmit. `opts.signal` is\n * checked at each step boundary; `opts.write === false` runs everything but\n * skips the Writer (basis of `--dry-run`). `opts.plan === true` also stops\n * before emission but calls `Writer.plan()` per output and returns the planned\n * tree as `RunResult.plan` — no disk I/O, no `afterEmit` (basis of `tako check`\n * / drift-guard); it wins over `opts.write`.\n *\n * Steps 5b/5c (synthesize root barrels, apply banner) are added to this file by\n * the output-modes feature; they are not part of the core-pipeline tasks.\n */\n\nimport type { GeneratorTree } from './collect.js';\nimport { mergeTrees } from './collect.js';\nimport { DriverError, HookError } from './errors.js';\nimport { filterIR } from './filter.js';\nimport { generatorOrder } from './graph.js';\nimport { childLogger, noopLogger } from './logger.js';\nimport type { MergeEntry } from './merge.js';\nimport { mergeSources } from './merge.js';\nimport type {\n GeneratorArtifact,\n OutputConfig,\n PlannedFile,\n ResolvedConfig,\n RunOptions,\n RunResult,\n VirtualFile,\n} from './types.js';\nimport { applyBanner } from './writer/banner.js';\nimport { synthesizeRootBarrels } from './writer/barrel.js';\nimport { selectWriter } from './writer/index.js';\n\nexport async function run(\n config: ResolvedConfig,\n opts?: RunOptions,\n): Promise<RunResult> {\n const logger = opts?.logger ?? noopLogger;\n const checkSignal = () => opts?.signal?.throwIfAborted();\n\n checkSignal();\n\n // 1. Parse — sorted-namespace order for determinism.\n const entries: MergeEntry[] = [];\n for (const namespace of Object.keys(config.sources).sort()) {\n checkSignal();\n const source = config.sources[namespace];\n if (!source) {\n continue;\n }\n const { parser } = source;\n const anchorDir = (await parser.anchor?.(config.rootDir)) ?? config.rootDir;\n const ctx = {\n namespace,\n cwd: config.rootDir,\n anchorDir,\n logger: childLogger(logger, { namespace }),\n };\n try {\n const sourceIR = await parser.parse(ctx);\n entries.push({ namespace, sourceIR });\n } catch (error) {\n if (error instanceof DriverError) {\n throw error;\n }\n throw new DriverError('parser', parser.name, { cause: error, namespace });\n }\n }\n\n // 2. Merge.\n checkSignal();\n const ir = mergeSources(entries);\n\n // 3. Order.\n checkSignal();\n const order = generatorOrder(config.generators);\n\n // 4. Generate.\n const artifacts: Record<string, GeneratorArtifact> = {};\n const perGenerator: GeneratorTree[] = [];\n for (const name of order) {\n checkSignal();\n const cfg = config.generators[name];\n if (!cfg) {\n continue;\n }\n const { generator } = cfg;\n const view = filterIR(ir, cfg.namespaces);\n\n const declared = [\n ...(generator.dependsOn ?? []),\n ...(generator.optionalDependsOn ?? []),\n ];\n const dependencies: Record<string, GeneratorArtifact> = {};\n for (const dep of declared) {\n const artifact = artifacts[dep];\n if (artifact) {\n dependencies[dep] = artifact;\n }\n }\n\n try {\n const out = await generator.generate({\n ir: view,\n dependencies,\n logger: childLogger(logger, { generator: name }),\n });\n artifacts[name] = out.artifact;\n perGenerator.push({ generator: name, files: out.files });\n } catch (error) {\n if (error instanceof DriverError) {\n throw error;\n }\n throw new DriverError('generator', generator.name, { cause: error });\n }\n }\n\n // 5. Collect.\n checkSignal();\n const collected = mergeTrees(perGenerator);\n\n // 5b. Synthesize the per-namespace root barrels and fold them into the tree.\n // A generator that emitted `<ns>/index.ts` itself now collides with the\n // synthesized file → OutputCollisionError pointing at the prefix rule.\n checkSignal();\n const barrels = synthesizeRootBarrels(collected, artifacts, logger);\n const merged = mergeTrees(\n [\n ...perGenerator,\n { generator: '<synthesized root barrel>', files: barrels },\n ],\n {\n collisionHint:\n \"each generator must emit under its own '<namespace>/<generatorName>/' sub-tree; '<namespace>/index.ts' is synthesized by tako\",\n },\n );\n\n // 5c. Prepend the generated-file banner once, covering generator output and\n // synthesized barrels alike.\n const files = applyBanner(merged);\n\n // The per-output tree: `collected` filtered to that output's generator subset,\n // with its own synthesized root barrels and the banner applied. Shared by the\n // write path (step 6) and the plan path (drift-guard).\n const outputTree = (output: OutputConfig): VirtualFile[] => {\n const names = new Set(output.generators ?? order);\n const filteredFiles = collected.filter((file) =>\n names.has(file.path.split('/')[1] ?? ''),\n );\n const outputBarrels = synthesizeRootBarrels(\n filteredFiles,\n artifacts,\n logger,\n );\n return applyBanner(\n mergeTrees([\n { generator: '<filtered>', files: filteredFiles },\n { generator: '<synthesized root barrel>', files: outputBarrels },\n ]),\n );\n };\n\n // 6a. Plan (drift-guard) — compute what a `generate` would write for every\n // output, without touching disk and without firing `afterEmit`. Wins over\n // `write`.\n if (opts?.plan === true) {\n const planned: PlannedFile[] = [];\n for (const output of config.outputs) {\n checkSignal();\n const writer = selectWriter(output);\n planned.push(\n ...(await writer.plan({\n files: outputTree(output),\n output,\n artifacts,\n logger,\n })),\n );\n }\n planned.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n return { ir, order, files, artifacts, written: [], plan: planned };\n }\n\n // 6. Write (unless disabled) — one writer call per `config.outputs` entry.\n const written: { output: OutputConfig; files: string[] }[] = [];\n if (opts?.write !== false) {\n for (const output of config.outputs) {\n checkSignal();\n const writer = selectWriter(output);\n const writtenPaths = await writer.write({\n files: outputTree(output),\n output,\n artifacts,\n logger,\n });\n written.push({ output, files: writtenPaths });\n\n // 7. afterEmit — once per output, right after that output is written.\n checkSignal();\n const outputDir =\n (output.mode === 'package' ? output.packagesDir : output.dir) ??\n config.rootDir;\n try {\n await config.hooks?.afterEmit?.({\n outputDir,\n files: writtenPaths,\n logger,\n });\n } catch (error) {\n throw new HookError('afterEmit', { cause: error });\n }\n }\n }\n\n return { ir, order, files, artifacts, written };\n}\n"],"mappings":"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","names":["path","path","IrModelValidationError","path","import_node_path","GITATTRIBUTES","path","fs","import_node_fs","import_promises","import_node_path","import_node_path","path","path","fs"]}
@@ -0,0 +1,435 @@
1
+ import { IrIssue, IR, SourceIR } from '@kurotako/ir';
2
+
3
+ /**
4
+ * `TakoError` hierarchy. Every failure in the pipeline is fail-fast and carries
5
+ * enough context to name the offending source or generator. The CLI maps any
6
+ * `TakoError` to a formatted message + non-zero exit; a non-`TakoError` throw is
7
+ * a bug and surfaces as a stack trace.
8
+ *
9
+ * Error table: `backlog/features/core-pipeline/technical.md` §Error model.
10
+ */
11
+
12
+ declare class TakoError extends Error {
13
+ readonly code: string;
14
+ constructor(code: string, message: string, options?: {
15
+ cause?: unknown;
16
+ });
17
+ }
18
+ declare class NamespaceMismatchError extends TakoError {
19
+ readonly namespace: string;
20
+ readonly returned: string;
21
+ constructor(namespace: string, returned: string);
22
+ }
23
+ declare class IrValidationError extends TakoError {
24
+ readonly issues: IrIssue[];
25
+ readonly namespace?: string;
26
+ constructor(issues: IrIssue[], namespace?: string);
27
+ }
28
+ declare class DuplicateNamespaceError extends TakoError {
29
+ readonly namespace: string;
30
+ constructor(namespace: string);
31
+ }
32
+ declare class UnknownDependencyError extends TakoError {
33
+ readonly generator: string;
34
+ readonly missing: string;
35
+ constructor(generator: string, missing: string);
36
+ }
37
+ declare class InvalidDependencyError extends TakoError {
38
+ readonly generator: string;
39
+ readonly dependency: string;
40
+ constructor(generator: string, dependency: string);
41
+ }
42
+ declare class DependencyCycleError extends TakoError {
43
+ readonly cycle: string[];
44
+ constructor(cycle: string[]);
45
+ }
46
+ declare class OutputCollisionError extends TakoError {
47
+ readonly path: string;
48
+ readonly generators: [string, string];
49
+ constructor(path: string, generators: [string, string], hint?: string);
50
+ }
51
+ declare class InvalidOutputPathError extends TakoError {
52
+ readonly path: string;
53
+ readonly generator: string;
54
+ constructor(path: string, generator: string);
55
+ }
56
+ declare class UnsupportedOutputModeError extends TakoError {
57
+ readonly mode: string;
58
+ constructor(mode: string);
59
+ }
60
+ declare class OutputPeerConflictError extends TakoError {
61
+ readonly namespace: string;
62
+ readonly package: string;
63
+ readonly ranges: string[];
64
+ readonly generators: string[];
65
+ constructor(namespace: string, pkg: string, ranges: string[], generators: string[]);
66
+ }
67
+ declare class PackageBuildError extends TakoError {
68
+ readonly namespace: string;
69
+ constructor(namespace: string, options?: {
70
+ cause?: unknown;
71
+ });
72
+ }
73
+ declare class MissingPackageWorkspaceFilesError extends TakoError {
74
+ readonly workspaceRoot: string;
75
+ readonly missing: string[];
76
+ constructor(workspaceRoot: string, missing: string[]);
77
+ }
78
+ declare class OutputNotGeneratedError extends TakoError {
79
+ readonly path: string;
80
+ constructor(path: string);
81
+ }
82
+ declare class PackageInstallError extends TakoError {
83
+ readonly pm: string;
84
+ constructor(pm: string, options?: {
85
+ cause?: unknown;
86
+ });
87
+ }
88
+ declare class DriverError extends TakoError {
89
+ readonly role: 'parser' | 'generator';
90
+ readonly driverName: string;
91
+ readonly namespace?: string;
92
+ constructor(role: 'parser' | 'generator', driverName: string, options?: {
93
+ cause?: unknown;
94
+ namespace?: string;
95
+ });
96
+ }
97
+ declare class HookError extends TakoError {
98
+ readonly hook: string;
99
+ constructor(hook: string, options?: {
100
+ cause?: unknown;
101
+ });
102
+ }
103
+
104
+ /**
105
+ * The Writer seam. `run()` aggregates a virtual tree and hands it to the writer
106
+ * selected by `output.mode`. Mode A (`directoryWriter`) and mode B
107
+ * (`packageWriter`) both live in this directory.
108
+ */
109
+
110
+ interface WriteInput {
111
+ files: VirtualFile[];
112
+ output: OutputConfig;
113
+ /**
114
+ * Generator short name -> artifact. Mode B reads `peerDependencies` from it;
115
+ * mode A ignores it. Optional so a bare `directoryWriter.write({ files,
116
+ * output })` call still type-checks.
117
+ */
118
+ artifacts?: Record<string, GeneratorArtifact>;
119
+ /** Mode B logs the manual install command here when no pm is resolved. */
120
+ logger?: Logger;
121
+ }
122
+ /**
123
+ * One file a `write()` would emit, resolved to its absolute on-disk path with
124
+ * the exact bytes it would serialise (banner already applied by the caller, as
125
+ * for `write`). `plan()` computes these without any disk I/O; `write()` is
126
+ * `plan()` plus materialisation, so the two never drift.
127
+ */
128
+ interface PlannedFile {
129
+ /** Absolute. */
130
+ path: string;
131
+ content: string;
132
+ }
133
+ interface Writer {
134
+ write(input: WriteInput): Promise<string[]>;
135
+ /**
136
+ * Same layout as `write()`, no disk I/O: the exact set of files `write()`
137
+ * would produce (mode B: `<pkgDir>/src/…` remap + synthesized manifest, but
138
+ * no `dist/`, no `pm install`).
139
+ */
140
+ plan(input: WriteInput): Promise<PlannedFile[]>;
141
+ }
142
+
143
+ /**
144
+ * Public type surface of `@kurotako/core`. Runtime-code free: every export here
145
+ * is a type or an interface. The orchestrator (`run.ts`), the error hierarchy
146
+ * (`errors.ts`) and the writer seam (`writer/`) build on these.
147
+ *
148
+ * Product decisions: `backlog/features/core-pipeline/technical.md`. The IR types
149
+ * come from `@kurotako/ir`; core owns config, driver contracts, contexts,
150
+ * artifacts, hooks, the logger and the `run()` option / result shapes.
151
+ */
152
+
153
+ /**
154
+ * Structured logger. Core ships a no-op default (`logger.ts`); the CLI injects a
155
+ * real one. Contexts receive a child logger tagged with the namespace /
156
+ * generator name.
157
+ */
158
+ interface Logger {
159
+ debug(msg: string, meta?: unknown): void;
160
+ info(msg: string, meta?: unknown): void;
161
+ warn(msg: string, meta?: unknown): void;
162
+ error(msg: string, meta?: unknown): void;
163
+ }
164
+ /**
165
+ * The already-resolved, already-validated configuration `run()` consumes.
166
+ * Construction, file format and driver-option validation belong to
167
+ * `@kurotako/config`; core only declares the shape it needs.
168
+ */
169
+ interface ResolvedConfig {
170
+ /**
171
+ * Absolute path of the directory holding the config file. Anchor for relative
172
+ * output paths and for `ParseContext.cwd`.
173
+ */
174
+ rootDir: string;
175
+ /** Key === namespace (ADR-0003). */
176
+ sources: Record<string, SourceConfig>;
177
+ /** Key === `Generator.name` (short name). */
178
+ generators: Record<string, GeneratorConfig>;
179
+ outputs: OutputConfig[];
180
+ hooks?: Hooks;
181
+ }
182
+ interface SourceConfig {
183
+ parser: Parser;
184
+ /** Opaque seam kept for `--emit` / debugging; core does not read it. */
185
+ options?: unknown;
186
+ }
187
+ interface GeneratorConfig {
188
+ generator: Generator;
189
+ /** Opaque seam kept for `--emit` / debugging; core does not read it. */
190
+ options?: unknown;
191
+ /** Restrict this generator to a subset of namespaces; default = all. */
192
+ namespaces?: string[];
193
+ }
194
+ interface OutputConfig {
195
+ /** Default `'dir'`. */
196
+ mode?: 'dir' | 'package';
197
+ /** Mode A; resolved absolute by config-system. */
198
+ dir?: string;
199
+ /** Mode B. */
200
+ packagesDir?: string;
201
+ /** Mode B (required for mode B — config-system enforces). */
202
+ scope?: string;
203
+ /** Mode B, optional — consumed by output-modes. */
204
+ packageManager?: 'bun' | 'pnpm' | 'yarn' | 'npm';
205
+ /** Restrict this destination to a subset of `config.generators`; default = all. */
206
+ generators?: string[];
207
+ }
208
+ interface Parser {
209
+ name: string;
210
+ parse(ctx: ParseContext): Promise<SourceIR> | SourceIR;
211
+ /**
212
+ * Metadata for `cli --watch` — the set of paths a watcher should observe.
213
+ * `run()` never calls it.
214
+ */
215
+ watchPaths?(ctx: ParseContext): string[] | Promise<string[]>;
216
+ /**
217
+ * The directory this source is anchored at, for toolchain-dependency
218
+ * resolution. Already curried (options bound). `run()` calls it before
219
+ * `parse()` and passes the result as `ParseContext.anchorDir`. Return
220
+ * `undefined` (or omit the hook) to anchor on `rootDir`. Must not throw for an
221
+ * ordinary "not found" case — a bad path is the parser's problem to surface
222
+ * during `parse()`.
223
+ */
224
+ anchor?(rootDir: string): string | undefined | Promise<string | undefined>;
225
+ }
226
+ interface ParseContext {
227
+ namespace: string;
228
+ /** Absolute; the config-file directory. Base for `options.schema` and output paths. */
229
+ cwd: string;
230
+ /**
231
+ * Absolute; the directory this source is anchored at — where its schema lives.
232
+ * A parser resolves the source's own toolchain dependencies (`@prisma/internals`
233
+ * and equivalents) from here, letting Node walk up `node_modules` to `cwd` and
234
+ * beyond. Absent (⇒ treat as `cwd`) when the parser declares no `anchor` hook.
235
+ */
236
+ anchorDir?: string;
237
+ logger: Logger;
238
+ }
239
+ interface Generator {
240
+ name: string;
241
+ /** Hard dependency: absent from the config => error. Constrains order. */
242
+ dependsOn?: string[];
243
+ /** Optional dependency: used if present, else ignored. Constrains order. */
244
+ optionalDependsOn?: string[];
245
+ generate(ctx: GenerateContext): Promise<GenOutput> | GenOutput;
246
+ }
247
+ interface GenerateContext {
248
+ /** Namespace-filtered deep clone of the merged IR. */
249
+ ir: IR;
250
+ /** Only declared deps (`dependsOn ∪ optionalDependsOn`) that actually ran. */
251
+ dependencies: Record<string, GeneratorArtifact>;
252
+ logger: Logger;
253
+ }
254
+ interface GenOutput {
255
+ files: VirtualFile[];
256
+ artifact: GeneratorArtifact;
257
+ }
258
+ interface VirtualFile {
259
+ /**
260
+ * POSIX, relative to the output root. The generator owns the
261
+ * `<namespace>/<generatorName>/` prefix (one sub-tree per generator; core
262
+ * synthesizes `<namespace>/index.ts`).
263
+ */
264
+ path: string;
265
+ content: string;
266
+ }
267
+ interface GeneratorArtifact {
268
+ /** Key === `${namespace}.${entity}`. */
269
+ entities: Record<string, EntitySymbols>;
270
+ /**
271
+ * Package -> semver range the emitted code imports. Mode B: core aggregates
272
+ * per namespace (output-modes).
273
+ */
274
+ peerDependencies?: Record<string, string>;
275
+ /** Generator-defined; the consumer casts to the producer's published type. */
276
+ extra?: unknown;
277
+ }
278
+ interface EntitySymbols {
279
+ /** Module specifier a sibling generator imports from. */
280
+ module: string;
281
+ /** Role -> exported identifier, e.g. `{ schema: "UserSchema", type: "User" }`. */
282
+ symbols: Record<string, string>;
283
+ }
284
+ interface Hooks {
285
+ afterEmit?(ctx: AfterEmitContext): Promise<void> | void;
286
+ }
287
+ interface AfterEmitContext {
288
+ /** Absolute; the directory the Writer just populated. */
289
+ outputDir: string;
290
+ /** Absolute paths actually written, sorted. */
291
+ files: string[];
292
+ logger: Logger;
293
+ }
294
+ interface RunOptions {
295
+ /** Default: no-op. */
296
+ logger?: Logger;
297
+ /** Cooperative cancellation between steps (watch mode). */
298
+ signal?: AbortSignal;
299
+ /** Default `true`; `false` => run everything, skip the Writer. */
300
+ write?: boolean;
301
+ /**
302
+ * Default `false`. `true` => run everything up to (not including) emission,
303
+ * then ask each output's Writer for the files a `generate` would write
304
+ * (absolute path + exact bytes) via `Writer.plan()`, returned as
305
+ * `RunResult.plan`. No disk I/O, `afterEmit` does not fire. Wins over
306
+ * `write`: `{ plan: true, write: true }` still writes nothing.
307
+ */
308
+ plan?: boolean;
309
+ }
310
+ interface RunResult {
311
+ /** Merged, validated IR (for `--emit-ir`, drift-guard). */
312
+ ir: IR;
313
+ /** Generator short names, in execution order. */
314
+ order: string[];
315
+ /** Aggregated virtual tree, sorted by path. */
316
+ files: VirtualFile[];
317
+ /** Generator short name -> its artifact. */
318
+ artifacts: Record<string, GeneratorArtifact>;
319
+ /** One entry per `config.outputs[]`, in order; `[]` when `write: false`. */
320
+ written: {
321
+ output: OutputConfig;
322
+ files: string[];
323
+ }[];
324
+ /**
325
+ * Present iff `opts.plan === true`: the files a fresh `generate` would write
326
+ * across every `config.outputs[]` entry, absolute paths, sorted by `path`.
327
+ * Basis of `tako check` (drift-guard).
328
+ */
329
+ plan?: PlannedFile[];
330
+ }
331
+
332
+ /**
333
+ * The no-op `Logger` default and a `childLogger` wrapper that merges a
334
+ * `{ namespace }` / `{ generator }` tag into every call's `meta`.
335
+ */
336
+
337
+ /** Default logger: swallows everything. The CLI injects a real one. */
338
+ declare const noopLogger: Logger;
339
+ /**
340
+ * Wrap `base` so every message carries `prefixMeta` (e.g. `{ namespace }` or
341
+ * `{ generator }`) merged into its `meta` argument.
342
+ */
343
+ declare function childLogger(base: Logger, prefixMeta: Record<string, unknown>): Logger;
344
+
345
+ /**
346
+ * `run()` — the single public entry point. Sequential, fail-fast: parse ->
347
+ * merge -> order -> generate -> collect -> write -> afterEmit. `opts.signal` is
348
+ * checked at each step boundary; `opts.write === false` runs everything but
349
+ * skips the Writer (basis of `--dry-run`). `opts.plan === true` also stops
350
+ * before emission but calls `Writer.plan()` per output and returns the planned
351
+ * tree as `RunResult.plan` — no disk I/O, no `afterEmit` (basis of `tako check`
352
+ * / drift-guard); it wins over `opts.write`.
353
+ *
354
+ * Steps 5b/5c (synthesize root barrels, apply banner) are added to this file by
355
+ * the output-modes feature; they are not part of the core-pipeline tasks.
356
+ */
357
+
358
+ declare function run(config: ResolvedConfig, opts?: RunOptions): Promise<RunResult>;
359
+
360
+ /**
361
+ * The generated-file banner. `run.ts` calls `applyBanner` once, after barrel
362
+ * synthesis and before the writer, so every `.ts` file — generator output and
363
+ * synthesized barrels alike — carries the marker. `.json` files have no comment
364
+ * syntax: `packageWriter` sets a `"//"` key on `package.json` instead.
365
+ *
366
+ * Design: `backlog/features/output-modes/technical.md` §Banner.
367
+ */
368
+
369
+ declare const BANNER = "// Generated by tako. Do not edit.\n";
370
+ declare const GITATTRIBUTES = "* linguist-generated=true\n";
371
+ /**
372
+ * Prepend `BANNER` to every `.ts` / `.tsx` file (and `tsconfig.json`). Pure,
373
+ * and idempotent-safe: a file that already starts with the banner is left
374
+ * untouched. `package.json` and other `.json` files pass through unchanged.
375
+ */
376
+ declare function applyBanner(files: VirtualFile[]): VirtualFile[];
377
+
378
+ /**
379
+ * Root-barrel synthesis. Each generator owns `<namespace>/<generatorName>/` and
380
+ * emits its own barrel there; `tako` synthesizes `<namespace>/index.ts` so
381
+ * `import … from '<scope>/<namespace>'` resolves regardless of how many
382
+ * generators ran. Mode-independent — mode A and mode B both get the barrel.
383
+ *
384
+ * Design: `backlog/features/output-modes/technical.md` §New orchestration step.
385
+ */
386
+
387
+ /**
388
+ * One `VirtualFile { path: '<ns>/index.ts' }` per namespace present in `files`,
389
+ * its content one sorted `export * from './<generatorName>';` line per
390
+ * generator that contributed a file under `<ns>/<generatorName>/`. A
391
+ * single-generator namespace still gets a barrel.
392
+ *
393
+ * When `artifactsByGenerator` is supplied, `logger?.warn(...)` fires if the same
394
+ * exported identifier appears in two contributing artifacts for one namespace
395
+ * (an ambiguous star re-export TypeScript/ESM silently drops). Never throws.
396
+ */
397
+ declare function synthesizeRootBarrels(files: VirtualFile[], artifactsByGenerator?: Record<string, GeneratorArtifact>, logger?: Logger): VirtualFile[];
398
+
399
+ declare const directoryWriter: Writer;
400
+
401
+ declare const packageWriter: Writer;
402
+
403
+ declare function selectWriter(output: OutputConfig): Writer;
404
+
405
+ /**
406
+ * Namespace -> (package -> semver range). Per namespace, union the
407
+ * `peerDependencies` of every generator that emitted a file under
408
+ * `<namespace>/<generatorName>/`. Identical ranges de-duplicate; the same
409
+ * package with two different ranges from two generators throws
410
+ * `OutputPeerConflictError` (fail-fast). Namespace and package keys are sorted.
411
+ */
412
+ declare function collectPeerDependencies(artifactsByGenerator: Record<string, GeneratorArtifact>, files: VirtualFile[]): Record<string, Record<string, string>>;
413
+
414
+ type PackageManager = 'bun' | 'pnpm' | 'yarn' | 'npm';
415
+ /**
416
+ * Resolve the package manager to run `install` with, in order:
417
+ * 1. `configured` (from `output.packageManager`) — used verbatim;
418
+ * 2. lockfile walk-up from `startDir` (`bun.lock` / `bun.lockb` -> `bun`,
419
+ * `pnpm-lock.yaml` -> `pnpm`, `yarn.lock` -> `yarn`,
420
+ * `package-lock.json` -> `npm`), stopping at a `.git` marker or the root;
421
+ * 3. nearest ancestor `package.json` `packageManager` field (name before `@`);
422
+ * 4. `null` — do not guess.
423
+ */
424
+ declare function resolvePackageManager(opts: {
425
+ configured?: PackageManager;
426
+ startDir: string;
427
+ }): PackageManager | null;
428
+ /**
429
+ * Run `<pm> install` in `cwd`. No `--frozen-lockfile` — the generated packages
430
+ * are new, the lockfile must change. A non-zero exit becomes
431
+ * `PackageInstallError { pm, cause }`.
432
+ */
433
+ declare function runInstall(pm: PackageManager, cwd: string): Promise<void>;
434
+
435
+ export { type AfterEmitContext, BANNER, DependencyCycleError, DriverError, DuplicateNamespaceError, type EntitySymbols, GITATTRIBUTES, type GenOutput, type GenerateContext, type Generator, type GeneratorArtifact, type GeneratorConfig, HookError, type Hooks, InvalidDependencyError, InvalidOutputPathError, IrValidationError, type Logger, MissingPackageWorkspaceFilesError, NamespaceMismatchError, OutputCollisionError, type OutputConfig, OutputNotGeneratedError, OutputPeerConflictError, PackageBuildError, PackageInstallError, type PackageManager, type ParseContext, type Parser, type PlannedFile, type ResolvedConfig, type RunOptions, type RunResult, type SourceConfig, TakoError, UnknownDependencyError, UnsupportedOutputModeError, type VirtualFile, type WriteInput, type Writer, applyBanner, childLogger, collectPeerDependencies, directoryWriter, noopLogger, packageWriter, resolvePackageManager, run, runInstall, selectWriter, synthesizeRootBarrels };