@kurotako/cli 0.2.0 → 0.2.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @kurotako/cli
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 6faab3b: Fix `tako outdated` always reporting the installed version as `unknown`:
8
+ `resolveInstalledVersion` was resolving `<name>/package.json`, a subpath
9
+ blocked by each package's `exports` field. It now walks the same
10
+ `node_modules` lookup path Node uses and reads the package's `package.json`
11
+ directly.
12
+
3
13
  ## 0.2.0
4
14
 
5
15
  ### Minor Changes
package/dist/bin/tako.js CHANGED
@@ -713,9 +713,15 @@ function collectKurotakoDependencies(packageJsonPath) {
713
713
  function resolveInstalledVersion(packageJsonPath, name) {
714
714
  try {
715
715
  const require2 = createRequire(packageJsonPath);
716
- const resolvedPath = require2.resolve(`${name}/package.json`);
717
- const pkg = JSON.parse(readFileSync3(resolvedPath, "utf8"));
718
- return pkg.version;
716
+ const searchPaths = require2.resolve.paths(name) ?? [];
717
+ for (const modulesDir of searchPaths) {
718
+ const candidate = resolve3(modulesDir, name, "package.json");
719
+ if (existsSync4(candidate)) {
720
+ const pkg = JSON.parse(readFileSync3(candidate, "utf8"));
721
+ return pkg.version;
722
+ }
723
+ }
724
+ return void 0;
719
725
  } catch {
720
726
  return void 0;
721
727
  }
@@ -805,7 +811,7 @@ var validateCommand = defineCommand5({
805
811
  });
806
812
 
807
813
  // src/cli.ts
808
- var VERSION = true ? "0.2.0" : "0.0.0-dev";
814
+ var VERSION = true ? "0.2.1" : "0.0.0-dev";
809
815
  var subCommands = {
810
816
  init: initCommand,
811
817
  generate: generateCommand,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli.ts","../../src/commands/check.ts","../../src/args.ts","../../src/diff.ts","../../src/reporter.ts","../../src/commands/generate.ts","../../src/watch.ts","../../src/errors.ts","../../src/commands/init.ts","../../src/commands/outdated.ts","../../src/version-check.ts","../../src/commands/validate.ts","../../src/bin/tako.ts"],"sourcesContent":["/**\n * `runCli()` — build the citty command tree, dispatch, map every `TakoError` to\n * a formatted message + exit 1. `--version` / `--help` are handled here (citty's\n * own handling lives in `runMain`, which hard-exits — not what a testable\n * `runCli` wants).\n *\n * `backlog/features/cli/technical.md` §Command surface, §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\nimport { type CommandDef, defineCommand, renderUsage, runCommand } from 'citty';\nimport { checkCommand } from './commands/check.js';\nimport { generateCommand } from './commands/generate.js';\nimport { initCommand } from './commands/init.js';\nimport { outdatedCommand } from './commands/outdated.js';\nimport { validateCommand } from './commands/validate.js';\nimport { renderError } from './errors.js';\nimport { ConsoleReporter } from './reporter.js';\nimport { checkForUpdate } from './version-check.js';\n\ndeclare const __TAKO_VERSION__: string;\nconst VERSION =\n typeof __TAKO_VERSION__ === 'string' ? __TAKO_VERSION__ : '0.0.0-dev';\n\nconst subCommands = {\n init: initCommand,\n generate: generateCommand,\n validate: validateCommand,\n check: checkCommand,\n outdated: outdatedCommand,\n};\n\nconst main = defineCommand({\n meta: {\n name: 'tako',\n version: VERSION,\n description: 'synchronise TypeScript schemas from data model to forms',\n },\n subCommands,\n});\n\nexport async function runCli(\n argv: string[],\n options: { currentVersion?: string } = {},\n): Promise<void> {\n const reporter = new ConsoleReporter({\n debug: argv.includes('--debug') || Boolean(process.env.TAKO_DEBUG),\n });\n\n if (argv.includes('--version') || argv.includes('-v')) {\n process.stdout.write(`${VERSION}\\n`);\n process.exitCode ??= 0;\n return;\n }\n\n if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {\n const sub = argv.find((a) => !a.startsWith('-'));\n const isSub = sub !== undefined && sub in subCommands;\n const cmd = (\n isSub ? subCommands[sub as keyof typeof subCommands] : main\n ) as CommandDef;\n process.stdout.write(\n `${await renderUsage(cmd, isSub ? (main as CommandDef) : undefined)}\\n`,\n );\n process.exitCode ??= 0;\n return;\n }\n\n const { notice, refresh } = checkForUpdate(options.currentVersion ?? VERSION);\n if (notice) {\n reporter.info(notice);\n }\n\n const controller = new AbortController();\n const refreshPromise = refresh?.(controller.signal).catch(() => {});\n\n try {\n await runCommand(main, { rawArgs: argv });\n process.exitCode ??= 0;\n } catch (error) {\n if (error instanceof TakoError) {\n reporter.error(renderError(error));\n process.exitCode = 1;\n } else if (error instanceof Error && error.name === 'CLIError') {\n // citty usage error (unknown command, missing argument, …).\n reporter.error(error.message);\n process.exitCode = 1;\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n process.exitCode = 1;\n }\n } finally {\n controller.abort();\n await refreshPromise;\n }\n}\n","/**\n * `tako check` — drift guard. Runs the pipeline in plan mode (no disk writes,\n * no `afterEmit`), then compares the planned tree against what is on disk.\n * Exit 0 when they match, exit 1 on any drift or any `TakoError` (the latter\n * via the top-level handler in `cli.ts`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §Command surface.\n */\nimport { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport { loadConfig } from '@kurotako/config';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport {\n comparePlanToDisk,\n type DriftEntry,\n ignoreBuildArtifacts,\n markedPackageDirs,\n} from '../diff.js';\nimport { ConsoleReporter } from '../reporter.js';\n\nexport const checkCommand = defineCommand({\n meta: {\n name: 'check',\n description:\n 'check the generated output on disk matches a fresh generate (drift guard)',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const { config } = await loadConfig({\n cwd,\n configPath: args.config || undefined,\n });\n const { plan = [] } = await run(config, { logger: reporter, plan: true });\n\n const roots: string[] = [];\n const ignores: ((absPath: string) => boolean)[] = [];\n\n for (const output of config.outputs) {\n if (output.mode === 'package') {\n ignores.push(ignoreBuildArtifacts);\n if (output.packagesDir) {\n roots.push(...(await markedPackageDirs(output.packagesDir)));\n }\n } else {\n const dir = output.dir;\n if (!dir) {\n continue;\n }\n if (!existsSync(dir)) {\n reporter.info(\n `output directory ${relative(config.rootDir, dir)} does not exist — run tako generate`,\n );\n process.exitCode = 1;\n return;\n }\n roots.push(dir);\n }\n }\n\n const ignore = (absPath: string): boolean =>\n ignores.some((fn) => fn(absPath));\n\n const drift = await comparePlanToDisk({\n plan,\n roots,\n ignore,\n rootDir: config.rootDir,\n });\n\n if (drift.length === 0) {\n reporter.info('output is in sync');\n process.exitCode ??= 0;\n return;\n }\n\n reporter.error(formatDrift(drift));\n process.exitCode = 1;\n },\n});\n\nfunction formatDrift(drift: DriftEntry[]): string {\n const width = Math.max(...drift.map((entry) => entry.kind.length));\n const lines = drift.map(\n (entry) => ` ${entry.kind.padEnd(width)} ${entry.path}`,\n );\n return [\n 'drift detected',\n '',\n ...lines,\n '',\n `${drift.length} files differ from a fresh generate. Run \\`tako generate\\`.`,\n ].join('\\n');\n}\n","/**\n * `sharedArgs` — the options every sub-command carries. citty has no\n * first-class global-option slot, so this object is spread into each command's\n * `args` (`backlog/features/cli/technical.md` §Global option).\n */\nimport type { ArgsDef } from 'citty';\n\nexport const sharedArgs = {\n config: {\n type: 'string',\n description: 'path to the tako config file (default: ./tako.config.ts)',\n },\n /** Hidden: not advertised, kept minimal. Enables `debug` reporter output. */\n debug: {\n type: 'boolean',\n default: false,\n },\n} as const satisfies ArgsDef;\n","/**\n * `comparePlanToDisk` — the in-memory comparison behind `tako check`. Takes the\n * `PlannedFile[]` a fresh `generate` would write (from `run({ plan: true })`)\n * and reports every way the tree on disk diverges from it: a planned file that\n * is absent (`missing`) or whose bytes differ (`modified`), and any file under\n * the scanned roots that no planned file claims (`orphan`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §The comparison.\n */\nimport { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PlannedFile } from '@kurotako/core';\n\nexport type DriftKind = 'modified' | 'missing' | 'orphan';\n\nexport interface DriftEntry {\n kind: DriftKind;\n /** Relative to `rootDir`, POSIX separators; a collapsed dir ends with `/`. */\n path: string;\n}\n\nexport interface ComparePlanToDiskArgs {\n plan: PlannedFile[];\n /** Directories walked for orphans (absolute). */\n roots: string[];\n /** Return `true` to exclude an absolute path from the orphan scan. */\n ignore: (absPath: string) => boolean;\n /** Anchor for the reported relative paths (the config-file directory). */\n rootDir: string;\n}\n\nfunction toPosix(rootDir: string, absPath: string): string {\n return path.relative(rootDir, absPath).split(path.sep).join('/');\n}\n\nexport async function comparePlanToDisk(\n args: ComparePlanToDiskArgs,\n): Promise<DriftEntry[]> {\n const { plan, roots, ignore, rootDir } = args;\n const plannedByPath = new Map(plan.map((f) => [path.resolve(f.path), f]));\n const entries: DriftEntry[] = [];\n\n // 1. Expected vs disk.\n for (const [absPath, file] of plannedByPath) {\n if (!existsSync(absPath)) {\n entries.push({ kind: 'missing', path: toPosix(rootDir, absPath) });\n continue;\n }\n const onDisk = await readFile(absPath, 'utf8');\n if (onDisk !== file.content) {\n entries.push({ kind: 'modified', path: toPosix(rootDir, absPath) });\n }\n }\n\n // 2. Orphan scan — a planned file lives under `dir` iff any planned absolute\n // path is `dir` itself or sits below it.\n const plannedPaths = [...plannedByPath.keys()];\n const hasPlannedUnder = (dir: string): boolean => {\n const prefix = `${dir}${path.sep}`;\n return plannedPaths.some((p) => p === dir || p.startsWith(prefix));\n };\n\n const seenRoots = new Set<string>();\n for (const root of roots) {\n const absRoot = path.resolve(root);\n if (seenRoots.has(absRoot) || !existsSync(absRoot)) {\n continue;\n }\n seenRoots.add(absRoot);\n await scan(absRoot);\n }\n\n async function scan(dir: string): Promise<void> {\n // A directory with no planned file underneath collapses to a single entry —\n // unless it holds nothing but ignored files (e.g. only `dist/`).\n if (!hasPlannedUnder(dir)) {\n if (await hasNonIgnoredFile(dir)) {\n entries.push({ kind: 'orphan', path: `${toPosix(rootDir, dir)}/` });\n }\n return;\n }\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isDirectory()) {\n await scan(abs);\n } else if (dirent.isFile() && !plannedByPath.has(abs)) {\n entries.push({ kind: 'orphan', path: toPosix(rootDir, abs) });\n }\n }\n }\n\n async function hasNonIgnoredFile(dir: string): Promise<boolean> {\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isFile()) {\n return true;\n }\n if (dirent.isDirectory() && (await hasNonIgnoredFile(abs))) {\n return true;\n }\n }\n return false;\n }\n\n entries.sort((a, b) =>\n a.path < b.path\n ? -1\n : a.path > b.path\n ? 1\n : a.kind < b.kind\n ? -1\n : a.kind > b.kind\n ? 1\n : 0,\n );\n return entries;\n}\n\n/** Rejects `dist/` and `node_modules/` anywhere in the path (mode B). */\nexport function ignoreBuildArtifacts(absPath: string): boolean {\n return /(^|[/\\\\])(dist|node_modules)([/\\\\]|$)/.test(absPath);\n}\n\n/**\n * Whether `<packagesDir>/<name>` looks like a directory `tako` generated: a\n * `package.json` whose `\"//\"` marker starts with `Generated by tako`.\n */\nexport async function hasGeneratedMarker(pkgDir: string): Promise<boolean> {\n try {\n const pkg = JSON.parse(\n await readFile(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\n/** Every immediate subdirectory of `packagesDir` carrying the tako marker. */\nexport async function markedPackageDirs(\n packagesDir: string,\n): Promise<string[]> {\n if (!existsSync(packagesDir)) {\n return [];\n }\n const out: string[] = [];\n for (const dirent of await readdir(packagesDir, { withFileTypes: true })) {\n if (!dirent.isDirectory()) {\n continue;\n }\n const abs = path.join(packagesDir, dirent.name);\n if (await hasGeneratedMarker(abs)) {\n out.push(abs);\n }\n }\n return out.sort();\n}\n","/**\n * `ConsoleReporter` — the `@kurotako/core` `Logger` the CLI injects into\n * `loadConfig()` / `run()`, plus the per-phase / summary output.\n *\n * Contract (`backlog/features/cli/technical.md` §Reporter):\n * - human output goes to **stderr**, `stdout` stays clean;\n * - `info` / `warn` / `error` shown by default; `debug` only with `--debug` /\n * `TAKO_DEBUG` (a hidden flag, not advertised);\n * - the human-readable message is always shown; the structured `meta` object is\n * printed only with `--debug` (a custom `Logger` still receives it in full),\n * so default output stays prose, not `key=value` noise;\n * - `tako ` prefix, level-coloured; colour auto-off when the stream is not a TTY\n * or `NO_COLOR` is set;\n * - `child(tag)` returns a `Logger` tagging every `meta` with `{ scope: tag }`.\n */\nimport { childLogger, type Logger } from '@kurotako/core';\n\ntype Level = 'debug' | 'info' | 'warn' | 'error';\n\n/** The slice of a writable stream the reporter needs (keeps tests trivial). */\nexport interface WriteStream {\n write(chunk: string): unknown;\n isTTY?: boolean;\n}\n\nexport interface ConsoleReporterOptions {\n /** Show `debug` output. Default: `false` unless `TAKO_DEBUG` is set. */\n debug?: boolean;\n /** Sink for human output. Default: `process.stderr`. */\n stream?: WriteStream;\n /** Force colour on/off. Default: auto (TTY and no `NO_COLOR`). */\n color?: boolean;\n}\n\nconst ESC = String.fromCharCode(27);\nconst ANSI: Record<Level, string> = {\n debug: `${ESC}[2m`, // dim\n info: `${ESC}[36m`, // cyan\n warn: `${ESC}[33m`, // yellow\n error: `${ESC}[31m`, // red\n};\nconst ANSI_RESET = `${ESC}[0m`;\n\nexport class ConsoleReporter implements Logger {\n private readonly stream: WriteStream;\n private readonly showDebug: boolean;\n private readonly color: boolean;\n\n constructor(options: ConsoleReporterOptions = {}) {\n this.stream = options.stream ?? process.stderr;\n this.showDebug = options.debug ?? Boolean(process.env.TAKO_DEBUG);\n this.color =\n options.color ??\n (Boolean(this.stream.isTTY) && process.env.NO_COLOR === undefined);\n }\n\n debug(msg: string, meta?: unknown): void {\n if (this.showDebug) {\n this.write('debug', msg, meta);\n }\n }\n\n info(msg: string, meta?: unknown): void {\n this.write('info', msg, meta);\n }\n\n warn(msg: string, meta?: unknown): void {\n this.write('warn', msg, meta);\n }\n\n error(msg: string, meta?: unknown): void {\n this.write('error', msg, meta);\n }\n\n /** A child `Logger` whose calls carry `{ scope: tag }` in `meta`. */\n child(tag: string): Logger {\n return childLogger(this, { scope: tag });\n }\n\n private write(level: Level, msg: string, meta?: unknown): void {\n const prefix = this.color ? `${ANSI[level]}tako${ANSI_RESET}` : 'tako';\n const detail =\n meta === undefined || !this.showDebug ? '' : ` ${formatMeta(meta)}`;\n this.stream.write(`${prefix} ${msg}${detail}\\n`);\n }\n}\n\nfunction formatMeta(meta: unknown): string {\n if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {\n return Object.entries(meta as Record<string, unknown>)\n .map(([k, v]) => `${k}=${stringify(v)}`)\n .join(' ');\n }\n return stringify(meta);\n}\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n","/**\n * `tako generate` — `loadConfig()` then `run()`. `--dry-run` runs everything but\n * skips the Writer; `--watch` hands off to the chokidar loop\n * (`backlog/features/cli/technical.md` §`tako generate`).\n */\nimport { relative } from 'node:path';\nimport { type LoadResult, loadConfig } from '@kurotako/config';\nimport type { OutputConfig, ResolvedConfig, RunResult } from '@kurotako/core';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { watchAndRun } from '../watch.js';\n\nexport interface LoadAndRunOptions {\n cwd: string;\n configPath?: string;\n write: boolean;\n signal?: AbortSignal;\n reporter: ConsoleReporter;\n}\n\nexport interface LoadAndRunResult {\n result: RunResult;\n config: ResolvedConfig;\n configFile: string;\n rootDir: string;\n}\n\n/** The directory named in the `wrote N files -> …` summary line, for one output. */\nexport function outputSummaryDir(\n output: OutputConfig,\n config: ResolvedConfig,\n): string {\n return output.mode === 'package'\n ? (output.packagesDir ?? config.rootDir)\n : (output.dir ?? config.rootDir);\n}\n\n/**\n * The shared body of `generate`, `validate` and each watch cycle: resolve +\n * load the config, then run the pipeline. `write: false` also skips the\n * `afterEmit` hook (`@kurotako/core` `run()`).\n */\nexport async function loadAndRun(\n opts: LoadAndRunOptions,\n): Promise<LoadAndRunResult> {\n const loaded: LoadResult = await loadConfig({\n cwd: opts.cwd,\n configPath: opts.configPath,\n });\n const result = await run(loaded.config, {\n logger: opts.reporter,\n write: opts.write,\n signal: opts.signal,\n });\n return {\n result,\n config: loaded.config,\n configFile: loaded.configFile,\n rootDir: loaded.rootDir,\n };\n}\n\nexport const generateCommand = defineCommand({\n meta: {\n name: 'generate',\n description: 'run the pipeline and write the generated code',\n },\n args: {\n ...sharedArgs,\n watch: {\n type: 'boolean',\n description: 'rebuild on every schema / config change',\n default: false,\n },\n 'dry-run': {\n type: 'boolean',\n description: 'run everything but write nothing',\n default: false,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n const configPath = args.config || undefined;\n\n if (args.watch) {\n await watchAndRun({ cwd, configPath, reporter });\n return;\n }\n\n const dryRun = Boolean(args['dry-run']);\n const { result, config } = await loadAndRun({\n cwd,\n configPath,\n write: !dryRun,\n reporter,\n });\n\n if (dryRun) {\n reporter.info(`dry run: ${result.files.length} files would be written`);\n return;\n }\n\n const dirs = config.outputs\n .map((output) => relative(cwd, outputSummaryDir(output, config)))\n .join(', ');\n reporter.info(`wrote ${result.files.length} files -> ${dirs}`);\n },\n});\n","/**\n * `tako generate --watch` — a chokidar loop around `loadConfig()` + `run()`.\n * Full regeneration on every change (no incremental). A 100 ms trailing\n * debounce coalesces bursts; a change mid-cycle aborts the in-flight `run()`\n * (via `RunOptions.signal`) and re-runs once it settles. `loadConfig` failures\n * are reported, not fatal — the watcher stays up on `tako.config.ts`.\n *\n * `backlog/features/cli/technical.md` §Watch mode.\n */\nimport { basename, resolve } from 'node:path';\nimport {\n type LoadResult,\n loadConfig as realLoadConfig,\n} from '@kurotako/config';\nimport { run as realRun, TakoError } from '@kurotako/core';\nimport chokidar from 'chokidar';\nimport { renderError } from './errors.js';\nimport type { ConsoleReporter } from './reporter.js';\n\n/** Minimal watcher seam so the loop is unit-testable without touching the fs. */\nexport interface Watcher {\n add(paths: string | readonly string[]): void;\n unwatch(paths: string | readonly string[]): void;\n on(handler: (event: string, path: string) => void): void;\n close(): Promise<void>;\n}\n\nexport interface WatchAndRunOptions {\n cwd: string;\n configPath?: string;\n reporter: ConsoleReporter;\n}\n\nexport interface WatchDeps {\n createWatcher: () => Watcher;\n loadConfig: typeof realLoadConfig;\n run: typeof realRun;\n debounceMs: number;\n}\n\nconst DEBOUNCE_MS = 100;\n\nfunction chokidarWatcher(): Watcher {\n const fsw = chokidar.watch([], {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 20 },\n });\n return {\n add: (paths) => fsw.add(paths as string | string[]),\n unwatch: (paths) => fsw.unwatch(paths as string | string[]),\n on: (handler) => {\n fsw.on('add', (p) => handler('add', p));\n fsw.on('change', (p) => handler('change', p));\n fsw.on('unlink', (p) => handler('unlink', p));\n },\n close: () => fsw.close(),\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError';\n}\n\n/**\n * Runs until `SIGINT` / `SIGTERM`, then closes the watcher and resolves so the\n * caller can exit 0. (The design doc types this `Promise<never>`; it resolves\n * on shutdown here purely so it stays testable.)\n */\nexport async function watchAndRun(\n opts: WatchAndRunOptions,\n deps: Partial<WatchDeps> = {},\n): Promise<void> {\n const { cwd, configPath, reporter } = opts;\n const createWatcher = deps.createWatcher ?? chokidarWatcher;\n const loadConfig = deps.loadConfig ?? realLoadConfig;\n const run = deps.run ?? realRun;\n const debounceMs = deps.debounceMs ?? DEBOUNCE_MS;\n\n const watcher = createWatcher();\n let watched = new Set<string>();\n let inFlight: AbortController | null = null;\n let queued = false;\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let reason = 'initial build';\n\n const guessedConfigFile = configPath\n ? resolve(cwd, configPath)\n : resolve(cwd, 'tako.config.ts');\n\n function applyWatchSet(desired: Set<string>): void {\n for (const path of desired) {\n if (!watched.has(path)) {\n watcher.add(path);\n }\n }\n for (const path of watched) {\n if (!desired.has(path)) {\n watcher.unwatch(path);\n }\n }\n watched = desired;\n }\n\n async function reconcileWatchSet(loaded: LoadResult): Promise<void> {\n const desired = new Set<string>([loaded.configFile]);\n for (const [namespace, source] of Object.entries(loaded.config.sources)) {\n const paths =\n (await source.parser.watchPaths?.({\n namespace,\n cwd: loaded.rootDir,\n logger: reporter,\n })) ?? [];\n for (const path of paths) {\n desired.add(resolve(loaded.rootDir, path));\n }\n }\n applyWatchSet(desired);\n }\n\n async function cycle(): Promise<void> {\n const why = reason;\n reporter.info(`--- rebuild (${why}) ---`);\n const ac = new AbortController();\n inFlight = ac;\n try {\n const loaded = await loadConfig({ cwd, configPath });\n await reconcileWatchSet(loaded);\n const result = await run(loaded.config, {\n logger: reporter,\n signal: ac.signal,\n write: true,\n });\n if (!ac.signal.aborted) {\n reporter.info(`wrote ${result.files.length} files`);\n }\n } catch (error) {\n if (isAbortError(error) || ac.signal.aborted) {\n // Superseded by a newer cycle — swallow.\n } else if (error instanceof TakoError) {\n reporter.error(renderError(error));\n // Keep watching at least the config file so a fix is picked up.\n applyWatchSet(new Set([...watched, guessedConfigFile]));\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n }\n } finally {\n inFlight = null;\n if (queued && !closed) {\n queued = false;\n await cycle();\n }\n }\n }\n\n function trigger(): void {\n if (inFlight) {\n queued = true;\n inFlight.abort();\n return;\n }\n void cycle();\n }\n\n function schedule(event: string, path: string): void {\n if (closed) {\n return;\n }\n reason = `${basename(path)} ${event === 'unlink' ? 'removed' : 'changed'}`;\n if (timer) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = null;\n trigger();\n }, debounceMs);\n }\n\n watcher.on(schedule);\n\n // Initial cycle: a failure is reported inside `cycle()`, never fatal.\n applyWatchSet(new Set([guessedConfigFile]));\n await cycle();\n reporter.info(`watching ${watched.size} paths`);\n\n await new Promise<void>((resolvePromise) => {\n const shutdown = () => {\n closed = true;\n if (timer) {\n clearTimeout(timer);\n }\n inFlight?.abort();\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n void watcher.close().finally(() => resolvePromise());\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n}\n","/**\n * CLI-owned error(s) and `renderError()` — the single formatter the top-level\n * handler in `cli.ts` uses for any `TakoError` (from `@kurotako/core`,\n * `@kurotako/config`, or this package).\n *\n * `backlog/features/cli/technical.md` §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\n\n/** `tako init` refuses to overwrite an existing config unless `--force`. */\nexport class ConfigExistsError extends TakoError {\n readonly path: string;\n\n constructor(path: string) {\n super(\n 'config_exists',\n `a config file already exists at '${path}' (pass --force to overwrite)`,\n );\n this.path = path;\n }\n}\n\ninterface Issue {\n path?: string;\n message?: string;\n}\n\n/**\n * `error [<code>]: <message>` plus any carried context on its own indented\n * lines: located issues (`ConfigShapeError`, `IrValidationError`,\n * `DriverOptionsError`), the offending driver / namespace (`DriverError`,\n * `UnknownNamespaceError`), the dependency cycle path (`DependencyCycleError`),\n * and the `cause` message of a wrapped failure.\n */\nexport function renderError(error: TakoError): string {\n const lines = [`error [${error.code}]: ${error.message}`];\n\n const issues = (error as { issues?: unknown }).issues;\n if (Array.isArray(issues)) {\n for (const issue of issues as Issue[]) {\n const at =\n issue.path === undefined || issue.path === '' ? '<root>' : issue.path;\n lines.push(` - ${at}: ${issue.message}`);\n }\n }\n\n const cycle = (error as { cycle?: unknown }).cycle;\n if (Array.isArray(cycle) && cycle.length > 0) {\n lines.push(` cycle: ${(cycle as string[]).join(' -> ')}`);\n }\n\n const driverName = (error as { driverName?: unknown }).driverName;\n if (typeof driverName === 'string') {\n const role = (error as { role?: unknown }).role;\n const namespace = (error as { namespace?: unknown }).namespace;\n const roleLabel = typeof role === 'string' ? role : 'driver';\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` ${roleLabel}: ${driverName}${where}`);\n } else {\n const generator = (error as { generator?: unknown }).generator;\n if (typeof generator === 'string') {\n const namespace = (error as { namespace?: unknown }).namespace;\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` generator: ${generator}${where}`);\n }\n }\n\n // Wrapped failures (`DriverError`, `HookError`, `ConfigLoadError`, …) carry the\n // real error in `cause`; core masks its type, so surface at least its message.\n const cause = error.cause;\n if (cause !== undefined && cause !== null) {\n const message = cause instanceof Error ? cause.message : String(cause);\n const code = cause instanceof TakoError ? ` [${cause.code}]` : '';\n lines.push(` cause${code}: ${message}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * `tako init` — write the commented `tako.config.ts` skeleton into the current\n * directory. No prompts, no schema auto-detection; refuses to overwrite unless\n * `--force` (`backlog/features/cli/technical.md` §`tako init`).\n *\n * `--monorepo` / `--no-monorepo` picks between `CONFIG_TEMPLATE` and\n * `CONFIG_TEMPLATE_MONOREPO`; unset, it auto-detects a workspace by walking up\n * for the nearest `package.json` (`workspaces` key, or a sibling\n * `pnpm-workspace.yaml`).\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative, resolve } from 'node:path';\nimport { CONFIG_TEMPLATE, CONFIG_TEMPLATE_MONOREPO } from '@kurotako/config';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConfigExistsError } from '../errors.js';\nimport { ConsoleReporter } from '../reporter.js';\n\n/**\n * Walk up from `startDir` to the first directory holding a `package.json`. A\n * workspace when that `package.json` has a `workspaces` key (array, or\n * `{ packages: [...] }`), or when a `pnpm-workspace.yaml` sits next to it.\n * Returns `false` when no `package.json` is found.\n */\nfunction detectMonorepo(startDir: string): boolean {\n let dir = resolve(startDir);\n while (true) {\n const pkgPath = resolve(dir, 'package.json');\n if (existsSync(pkgPath)) {\n if (existsSync(resolve(dir, 'pnpm-workspace.yaml'))) {\n return true;\n }\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n workspaces?: unknown;\n };\n const ws = pkg.workspaces;\n if (\n Array.isArray(ws) ||\n (typeof ws === 'object' &&\n ws !== null &&\n Array.isArray((ws as { packages?: unknown }).packages))\n ) {\n return true;\n }\n } catch {\n // Unreadable / invalid package.json: treat as not a workspace.\n }\n return false;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return false;\n }\n dir = parent;\n }\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'create a tako.config.ts in the current directory',\n },\n args: {\n ...sharedArgs,\n force: {\n type: 'boolean',\n description: 'overwrite an existing config file',\n default: false,\n },\n monorepo: {\n type: 'boolean',\n description:\n 'write the monorepo config layout (auto-detected from workspaces when unset)',\n default: undefined,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n // Unlike `loadConfig`, `init` never walks up: it always targets `cwd`.\n const target = args.config\n ? resolve(cwd, args.config)\n : resolve(cwd, 'tako.config.ts');\n\n if (existsSync(target) && !args.force) {\n throw new ConfigExistsError(target);\n }\n\n // citty leaves an unset boolean flag `undefined` (no `default`), so\n // `--monorepo` / `--no-monorepo` win and absence falls back to detection.\n const monorepo: boolean =\n typeof args.monorepo === 'boolean' ? args.monorepo : detectMonorepo(cwd);\n\n await mkdir(dirname(target), { recursive: true });\n await writeFile(\n target,\n monorepo ? CONFIG_TEMPLATE_MONOREPO : CONFIG_TEMPLATE,\n 'utf8',\n );\n\n const name = relative(cwd, target) || 'tako.config.ts';\n reporter.info(\n monorepo ? `created ${name} (monorepo layout)` : `created ${name}`,\n );\n },\n});\n","/**\n * `tako outdated` — on-demand check of the installed `@kurotako/*` packages\n * in the target project against the npm registry. Informational only, always\n * exits 0.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §`tako outdated`\n * command.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { compareVersions } from '../version-check.js';\n\ninterface PackageEntry {\n name: string;\n installed: string | undefined;\n latest: string | undefined;\n}\n\nfunction findProjectPackageJson(cwd: string): string | undefined {\n let dir = resolve(cwd);\n while (true) {\n const candidate = resolve(dir, 'package.json');\n if (existsSync(candidate)) {\n return candidate;\n }\n if (existsSync(resolve(dir, '.git'))) {\n return undefined;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return undefined;\n }\n dir = parent;\n }\n}\n\nfunction collectKurotakoDependencies(packageJsonPath: string): string[] {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n return [...names].filter((name) => name.startsWith('@kurotako/')).sort();\n}\n\nfunction resolveInstalledVersion(\n packageJsonPath: string,\n name: string,\n): string | undefined {\n try {\n const require = createRequire(packageJsonPath);\n const resolvedPath = require.resolve(`${name}/package.json`);\n const pkg = JSON.parse(readFileSync(resolvedPath, 'utf8')) as {\n version?: string;\n };\n return pkg.version;\n } catch {\n return undefined;\n }\n}\n\nasync function fetchLatestVersion(name: string): Promise<string | undefined> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${name}/latest`);\n if (!response.ok) {\n return undefined;\n }\n const body = (await response.json()) as { version?: unknown };\n return typeof body.version === 'string' ? body.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction formatTable(entries: PackageEntry[]): string {\n const rows = entries.map((entry) => ({\n name: entry.name,\n installed: entry.installed ?? 'unknown',\n latest: entry.latest ?? 'unknown',\n status:\n entry.installed === undefined || entry.latest === undefined\n ? 'unknown'\n : compareVersions(entry.latest, entry.installed) > 0\n ? 'outdated'\n : 'up to date',\n }));\n\n const widths = {\n name: Math.max(7, ...rows.map((r) => r.name.length)),\n installed: Math.max(9, ...rows.map((r) => r.installed.length)),\n latest: Math.max(6, ...rows.map((r) => r.latest.length)),\n };\n\n const header = ` ${'package'.padEnd(widths.name)} ${'installed'.padEnd(widths.installed)} ${'latest'.padEnd(widths.latest)} status`;\n const lines = rows.map(\n (r) =>\n ` ${r.name.padEnd(widths.name)} ${r.installed.padEnd(widths.installed)} ${r.latest.padEnd(widths.latest)} ${r.status}`,\n );\n\n return [header, ...lines].join('\\n');\n}\n\nexport const outdatedCommand = defineCommand({\n meta: {\n name: 'outdated',\n description:\n 'check installed @kurotako/* packages against the npm registry',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const packageJsonPath = findProjectPackageJson(cwd);\n if (!packageJsonPath) {\n reporter.error('no package.json found (searched up to the project root)');\n process.exitCode ??= 0;\n return;\n }\n\n const names = collectKurotakoDependencies(packageJsonPath);\n if (names.length === 0) {\n reporter.info('no @kurotako/* dependency found');\n process.exitCode ??= 0;\n return;\n }\n\n const entries: PackageEntry[] = await Promise.all(\n names.map(async (name) => ({\n name,\n installed: resolveInstalledVersion(packageJsonPath, name),\n latest: await fetchLatestVersion(name),\n })),\n );\n\n reporter.info(`tako outdated\\n${formatTable(entries)}`);\n process.exitCode ??= 0;\n },\n});\n","/**\n * Background version check for the `tako` binary — compares the installed\n * `kurotako` version against the npm registry, cached for 8h so most\n * invocations do not hit the network.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §Background version\n * check.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst REGISTRY_URL = 'https://registry.npmjs.org/kurotako/latest';\nconst TTL_MS = 8 * 60 * 60 * 1000;\n\nexport interface VersionCacheEntry {\n checkedAt: number;\n latestVersion: string;\n}\n\nexport function getCacheFilePath(): string {\n const base = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');\n return join(base, 'tako', 'version-check.json');\n}\n\nexport function readCache(): VersionCacheEntry | undefined {\n try {\n const raw = readFileSync(getCacheFilePath(), 'utf8');\n const parsed = JSON.parse(raw) as Partial<VersionCacheEntry>;\n if (\n typeof parsed.checkedAt === 'number' &&\n typeof parsed.latestVersion === 'string'\n ) {\n return {\n checkedAt: parsed.checkedAt,\n latestVersion: parsed.latestVersion,\n };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function writeCache(entry: VersionCacheEntry): void {\n const path = getCacheFilePath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(entry));\n}\n\nexport async function refreshLatestVersion(\n signal: AbortSignal,\n): Promise<string> {\n const response = await fetch(REGISTRY_URL, { signal });\n if (!response.ok) {\n throw new Error(`registry request failed with status ${response.status}`);\n }\n const body = (await response.json()) as { version?: unknown };\n if (typeof body.version !== 'string') {\n throw new Error('registry response is missing a version string');\n }\n return body.version;\n}\n\n/**\n * `-1` when `a` is older than `b`, `0` when equal, `1` when newer. Handles\n * `major.minor.patch` plus an optional `-prerelease` suffix (a release always\n * outranks a prerelease of the same `major.minor.patch`).\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const [aMajor, aMinor, aPatch, aPre] = splitVersion(a);\n const [bMajor, bMinor, bPatch, bPre] = splitVersion(b);\n\n if (aMajor !== bMajor) {\n return aMajor < bMajor ? -1 : 1;\n }\n if (aMinor !== bMinor) {\n return aMinor < bMinor ? -1 : 1;\n }\n if (aPatch !== bPatch) {\n return aPatch < bPatch ? -1 : 1;\n }\n\n if (aPre === bPre) {\n return 0;\n }\n if (aPre === undefined) {\n return 1;\n }\n if (bPre === undefined) {\n return -1;\n }\n return aPre < bPre ? -1 : 1;\n}\n\nfunction splitVersion(\n version: string,\n): [major: number, minor: number, patch: number, pre?: string] {\n const [core = '', ...rest] = version.split('-');\n const [major = 0, minor = 0, patch = 0] = core\n .split('.')\n .map((n) => Number.parseInt(n, 10) || 0);\n return [major, minor, patch, rest.length > 0 ? rest.join('-') : undefined];\n}\n\nexport interface CheckForUpdateResult {\n notice?: string;\n refresh?: (signal: AbortSignal) => Promise<void>;\n}\n\nexport function checkForUpdate(currentVersion: string): CheckForUpdateResult {\n const cache = readCache();\n const result: CheckForUpdateResult = {};\n\n if (cache && compareVersions(cache.latestVersion, currentVersion) > 0) {\n result.notice = `tako a new version of kurotako is available: ${currentVersion} → ${cache.latestVersion} (npm i kurotako@latest)`;\n }\n\n const isStale = cache === undefined || Date.now() - cache.checkedAt > TTL_MS;\n if (isStale) {\n result.refresh = async (signal: AbortSignal) => {\n const latestVersion = await refreshLatestVersion(signal);\n writeCache({ checkedAt: Date.now(), latestVersion });\n };\n }\n\n return result;\n}\n","/**\n * `tako validate` — the same checks as `generate` up to (not including)\n * emission. `loadConfig()` + `run({ write: false })`; any `TakoError` propagates\n * to the top-level handler and exits 1\n * (`backlog/features/cli/technical.md` §`tako validate`).\n */\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { loadAndRun } from './generate.js';\n\nexport const validateCommand = defineCommand({\n meta: {\n name: 'validate',\n description: 'check the config and schema without writing anything',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n await loadAndRun({\n cwd: process.cwd(),\n configPath: args.config || undefined,\n write: false,\n reporter,\n });\n reporter.info('config and schema are valid');\n },\n});\n","#!/usr/bin/env node\n/**\n * Executable entry. Thin: parse `process.argv` and delegate to `runCli()`,\n * which sets `process.exitCode`.\n */\nimport { runCli } from '../cli.js';\n\nawait runCli(process.argv.slice(2));\n"],"mappings":"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","names":["TakoError","defineCommand","existsSync","existsSync","relative","loadConfig","run","defineCommand","TakoError","path","loadConfig","run","path","TakoError","loadConfig","run","defineCommand","relative","existsSync","relative","resolve","defineCommand","resolve","existsSync","defineCommand","relative","existsSync","readFileSync","dirname","resolve","defineCommand","readFileSync","dirname","path","resolve","existsSync","dirname","readFileSync","require","defineCommand","defineCommand","defineCommand","defineCommand","TakoError"]}
1
+ {"version":3,"sources":["../../src/cli.ts","../../src/commands/check.ts","../../src/args.ts","../../src/diff.ts","../../src/reporter.ts","../../src/commands/generate.ts","../../src/watch.ts","../../src/errors.ts","../../src/commands/init.ts","../../src/commands/outdated.ts","../../src/version-check.ts","../../src/commands/validate.ts","../../src/bin/tako.ts"],"sourcesContent":["/**\n * `runCli()` — build the citty command tree, dispatch, map every `TakoError` to\n * a formatted message + exit 1. `--version` / `--help` are handled here (citty's\n * own handling lives in `runMain`, which hard-exits — not what a testable\n * `runCli` wants).\n *\n * `backlog/features/cli/technical.md` §Command surface, §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\nimport { type CommandDef, defineCommand, renderUsage, runCommand } from 'citty';\nimport { checkCommand } from './commands/check.js';\nimport { generateCommand } from './commands/generate.js';\nimport { initCommand } from './commands/init.js';\nimport { outdatedCommand } from './commands/outdated.js';\nimport { validateCommand } from './commands/validate.js';\nimport { renderError } from './errors.js';\nimport { ConsoleReporter } from './reporter.js';\nimport { checkForUpdate } from './version-check.js';\n\ndeclare const __TAKO_VERSION__: string;\nconst VERSION =\n typeof __TAKO_VERSION__ === 'string' ? __TAKO_VERSION__ : '0.0.0-dev';\n\nconst subCommands = {\n init: initCommand,\n generate: generateCommand,\n validate: validateCommand,\n check: checkCommand,\n outdated: outdatedCommand,\n};\n\nconst main = defineCommand({\n meta: {\n name: 'tako',\n version: VERSION,\n description: 'synchronise TypeScript schemas from data model to forms',\n },\n subCommands,\n});\n\nexport async function runCli(\n argv: string[],\n options: { currentVersion?: string } = {},\n): Promise<void> {\n const reporter = new ConsoleReporter({\n debug: argv.includes('--debug') || Boolean(process.env.TAKO_DEBUG),\n });\n\n if (argv.includes('--version') || argv.includes('-v')) {\n process.stdout.write(`${VERSION}\\n`);\n process.exitCode ??= 0;\n return;\n }\n\n if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {\n const sub = argv.find((a) => !a.startsWith('-'));\n const isSub = sub !== undefined && sub in subCommands;\n const cmd = (\n isSub ? subCommands[sub as keyof typeof subCommands] : main\n ) as CommandDef;\n process.stdout.write(\n `${await renderUsage(cmd, isSub ? (main as CommandDef) : undefined)}\\n`,\n );\n process.exitCode ??= 0;\n return;\n }\n\n const { notice, refresh } = checkForUpdate(options.currentVersion ?? VERSION);\n if (notice) {\n reporter.info(notice);\n }\n\n const controller = new AbortController();\n const refreshPromise = refresh?.(controller.signal).catch(() => {});\n\n try {\n await runCommand(main, { rawArgs: argv });\n process.exitCode ??= 0;\n } catch (error) {\n if (error instanceof TakoError) {\n reporter.error(renderError(error));\n process.exitCode = 1;\n } else if (error instanceof Error && error.name === 'CLIError') {\n // citty usage error (unknown command, missing argument, …).\n reporter.error(error.message);\n process.exitCode = 1;\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n process.exitCode = 1;\n }\n } finally {\n controller.abort();\n await refreshPromise;\n }\n}\n","/**\n * `tako check` — drift guard. Runs the pipeline in plan mode (no disk writes,\n * no `afterEmit`), then compares the planned tree against what is on disk.\n * Exit 0 when they match, exit 1 on any drift or any `TakoError` (the latter\n * via the top-level handler in `cli.ts`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §Command surface.\n */\nimport { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport { loadConfig } from '@kurotako/config';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport {\n comparePlanToDisk,\n type DriftEntry,\n ignoreBuildArtifacts,\n markedPackageDirs,\n} from '../diff.js';\nimport { ConsoleReporter } from '../reporter.js';\n\nexport const checkCommand = defineCommand({\n meta: {\n name: 'check',\n description:\n 'check the generated output on disk matches a fresh generate (drift guard)',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const { config } = await loadConfig({\n cwd,\n configPath: args.config || undefined,\n });\n const { plan = [] } = await run(config, { logger: reporter, plan: true });\n\n const roots: string[] = [];\n const ignores: ((absPath: string) => boolean)[] = [];\n\n for (const output of config.outputs) {\n if (output.mode === 'package') {\n ignores.push(ignoreBuildArtifacts);\n if (output.packagesDir) {\n roots.push(...(await markedPackageDirs(output.packagesDir)));\n }\n } else {\n const dir = output.dir;\n if (!dir) {\n continue;\n }\n if (!existsSync(dir)) {\n reporter.info(\n `output directory ${relative(config.rootDir, dir)} does not exist — run tako generate`,\n );\n process.exitCode = 1;\n return;\n }\n roots.push(dir);\n }\n }\n\n const ignore = (absPath: string): boolean =>\n ignores.some((fn) => fn(absPath));\n\n const drift = await comparePlanToDisk({\n plan,\n roots,\n ignore,\n rootDir: config.rootDir,\n });\n\n if (drift.length === 0) {\n reporter.info('output is in sync');\n process.exitCode ??= 0;\n return;\n }\n\n reporter.error(formatDrift(drift));\n process.exitCode = 1;\n },\n});\n\nfunction formatDrift(drift: DriftEntry[]): string {\n const width = Math.max(...drift.map((entry) => entry.kind.length));\n const lines = drift.map(\n (entry) => ` ${entry.kind.padEnd(width)} ${entry.path}`,\n );\n return [\n 'drift detected',\n '',\n ...lines,\n '',\n `${drift.length} files differ from a fresh generate. Run \\`tako generate\\`.`,\n ].join('\\n');\n}\n","/**\n * `sharedArgs` — the options every sub-command carries. citty has no\n * first-class global-option slot, so this object is spread into each command's\n * `args` (`backlog/features/cli/technical.md` §Global option).\n */\nimport type { ArgsDef } from 'citty';\n\nexport const sharedArgs = {\n config: {\n type: 'string',\n description: 'path to the tako config file (default: ./tako.config.ts)',\n },\n /** Hidden: not advertised, kept minimal. Enables `debug` reporter output. */\n debug: {\n type: 'boolean',\n default: false,\n },\n} as const satisfies ArgsDef;\n","/**\n * `comparePlanToDisk` — the in-memory comparison behind `tako check`. Takes the\n * `PlannedFile[]` a fresh `generate` would write (from `run({ plan: true })`)\n * and reports every way the tree on disk diverges from it: a planned file that\n * is absent (`missing`) or whose bytes differ (`modified`), and any file under\n * the scanned roots that no planned file claims (`orphan`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §The comparison.\n */\nimport { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PlannedFile } from '@kurotako/core';\n\nexport type DriftKind = 'modified' | 'missing' | 'orphan';\n\nexport interface DriftEntry {\n kind: DriftKind;\n /** Relative to `rootDir`, POSIX separators; a collapsed dir ends with `/`. */\n path: string;\n}\n\nexport interface ComparePlanToDiskArgs {\n plan: PlannedFile[];\n /** Directories walked for orphans (absolute). */\n roots: string[];\n /** Return `true` to exclude an absolute path from the orphan scan. */\n ignore: (absPath: string) => boolean;\n /** Anchor for the reported relative paths (the config-file directory). */\n rootDir: string;\n}\n\nfunction toPosix(rootDir: string, absPath: string): string {\n return path.relative(rootDir, absPath).split(path.sep).join('/');\n}\n\nexport async function comparePlanToDisk(\n args: ComparePlanToDiskArgs,\n): Promise<DriftEntry[]> {\n const { plan, roots, ignore, rootDir } = args;\n const plannedByPath = new Map(plan.map((f) => [path.resolve(f.path), f]));\n const entries: DriftEntry[] = [];\n\n // 1. Expected vs disk.\n for (const [absPath, file] of plannedByPath) {\n if (!existsSync(absPath)) {\n entries.push({ kind: 'missing', path: toPosix(rootDir, absPath) });\n continue;\n }\n const onDisk = await readFile(absPath, 'utf8');\n if (onDisk !== file.content) {\n entries.push({ kind: 'modified', path: toPosix(rootDir, absPath) });\n }\n }\n\n // 2. Orphan scan — a planned file lives under `dir` iff any planned absolute\n // path is `dir` itself or sits below it.\n const plannedPaths = [...plannedByPath.keys()];\n const hasPlannedUnder = (dir: string): boolean => {\n const prefix = `${dir}${path.sep}`;\n return plannedPaths.some((p) => p === dir || p.startsWith(prefix));\n };\n\n const seenRoots = new Set<string>();\n for (const root of roots) {\n const absRoot = path.resolve(root);\n if (seenRoots.has(absRoot) || !existsSync(absRoot)) {\n continue;\n }\n seenRoots.add(absRoot);\n await scan(absRoot);\n }\n\n async function scan(dir: string): Promise<void> {\n // A directory with no planned file underneath collapses to a single entry —\n // unless it holds nothing but ignored files (e.g. only `dist/`).\n if (!hasPlannedUnder(dir)) {\n if (await hasNonIgnoredFile(dir)) {\n entries.push({ kind: 'orphan', path: `${toPosix(rootDir, dir)}/` });\n }\n return;\n }\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isDirectory()) {\n await scan(abs);\n } else if (dirent.isFile() && !plannedByPath.has(abs)) {\n entries.push({ kind: 'orphan', path: toPosix(rootDir, abs) });\n }\n }\n }\n\n async function hasNonIgnoredFile(dir: string): Promise<boolean> {\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isFile()) {\n return true;\n }\n if (dirent.isDirectory() && (await hasNonIgnoredFile(abs))) {\n return true;\n }\n }\n return false;\n }\n\n entries.sort((a, b) =>\n a.path < b.path\n ? -1\n : a.path > b.path\n ? 1\n : a.kind < b.kind\n ? -1\n : a.kind > b.kind\n ? 1\n : 0,\n );\n return entries;\n}\n\n/** Rejects `dist/` and `node_modules/` anywhere in the path (mode B). */\nexport function ignoreBuildArtifacts(absPath: string): boolean {\n return /(^|[/\\\\])(dist|node_modules)([/\\\\]|$)/.test(absPath);\n}\n\n/**\n * Whether `<packagesDir>/<name>` looks like a directory `tako` generated: a\n * `package.json` whose `\"//\"` marker starts with `Generated by tako`.\n */\nexport async function hasGeneratedMarker(pkgDir: string): Promise<boolean> {\n try {\n const pkg = JSON.parse(\n await readFile(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\n/** Every immediate subdirectory of `packagesDir` carrying the tako marker. */\nexport async function markedPackageDirs(\n packagesDir: string,\n): Promise<string[]> {\n if (!existsSync(packagesDir)) {\n return [];\n }\n const out: string[] = [];\n for (const dirent of await readdir(packagesDir, { withFileTypes: true })) {\n if (!dirent.isDirectory()) {\n continue;\n }\n const abs = path.join(packagesDir, dirent.name);\n if (await hasGeneratedMarker(abs)) {\n out.push(abs);\n }\n }\n return out.sort();\n}\n","/**\n * `ConsoleReporter` — the `@kurotako/core` `Logger` the CLI injects into\n * `loadConfig()` / `run()`, plus the per-phase / summary output.\n *\n * Contract (`backlog/features/cli/technical.md` §Reporter):\n * - human output goes to **stderr**, `stdout` stays clean;\n * - `info` / `warn` / `error` shown by default; `debug` only with `--debug` /\n * `TAKO_DEBUG` (a hidden flag, not advertised);\n * - the human-readable message is always shown; the structured `meta` object is\n * printed only with `--debug` (a custom `Logger` still receives it in full),\n * so default output stays prose, not `key=value` noise;\n * - `tako ` prefix, level-coloured; colour auto-off when the stream is not a TTY\n * or `NO_COLOR` is set;\n * - `child(tag)` returns a `Logger` tagging every `meta` with `{ scope: tag }`.\n */\nimport { childLogger, type Logger } from '@kurotako/core';\n\ntype Level = 'debug' | 'info' | 'warn' | 'error';\n\n/** The slice of a writable stream the reporter needs (keeps tests trivial). */\nexport interface WriteStream {\n write(chunk: string): unknown;\n isTTY?: boolean;\n}\n\nexport interface ConsoleReporterOptions {\n /** Show `debug` output. Default: `false` unless `TAKO_DEBUG` is set. */\n debug?: boolean;\n /** Sink for human output. Default: `process.stderr`. */\n stream?: WriteStream;\n /** Force colour on/off. Default: auto (TTY and no `NO_COLOR`). */\n color?: boolean;\n}\n\nconst ESC = String.fromCharCode(27);\nconst ANSI: Record<Level, string> = {\n debug: `${ESC}[2m`, // dim\n info: `${ESC}[36m`, // cyan\n warn: `${ESC}[33m`, // yellow\n error: `${ESC}[31m`, // red\n};\nconst ANSI_RESET = `${ESC}[0m`;\n\nexport class ConsoleReporter implements Logger {\n private readonly stream: WriteStream;\n private readonly showDebug: boolean;\n private readonly color: boolean;\n\n constructor(options: ConsoleReporterOptions = {}) {\n this.stream = options.stream ?? process.stderr;\n this.showDebug = options.debug ?? Boolean(process.env.TAKO_DEBUG);\n this.color =\n options.color ??\n (Boolean(this.stream.isTTY) && process.env.NO_COLOR === undefined);\n }\n\n debug(msg: string, meta?: unknown): void {\n if (this.showDebug) {\n this.write('debug', msg, meta);\n }\n }\n\n info(msg: string, meta?: unknown): void {\n this.write('info', msg, meta);\n }\n\n warn(msg: string, meta?: unknown): void {\n this.write('warn', msg, meta);\n }\n\n error(msg: string, meta?: unknown): void {\n this.write('error', msg, meta);\n }\n\n /** A child `Logger` whose calls carry `{ scope: tag }` in `meta`. */\n child(tag: string): Logger {\n return childLogger(this, { scope: tag });\n }\n\n private write(level: Level, msg: string, meta?: unknown): void {\n const prefix = this.color ? `${ANSI[level]}tako${ANSI_RESET}` : 'tako';\n const detail =\n meta === undefined || !this.showDebug ? '' : ` ${formatMeta(meta)}`;\n this.stream.write(`${prefix} ${msg}${detail}\\n`);\n }\n}\n\nfunction formatMeta(meta: unknown): string {\n if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {\n return Object.entries(meta as Record<string, unknown>)\n .map(([k, v]) => `${k}=${stringify(v)}`)\n .join(' ');\n }\n return stringify(meta);\n}\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n","/**\n * `tako generate` — `loadConfig()` then `run()`. `--dry-run` runs everything but\n * skips the Writer; `--watch` hands off to the chokidar loop\n * (`backlog/features/cli/technical.md` §`tako generate`).\n */\nimport { relative } from 'node:path';\nimport { type LoadResult, loadConfig } from '@kurotako/config';\nimport type { OutputConfig, ResolvedConfig, RunResult } from '@kurotako/core';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { watchAndRun } from '../watch.js';\n\nexport interface LoadAndRunOptions {\n cwd: string;\n configPath?: string;\n write: boolean;\n signal?: AbortSignal;\n reporter: ConsoleReporter;\n}\n\nexport interface LoadAndRunResult {\n result: RunResult;\n config: ResolvedConfig;\n configFile: string;\n rootDir: string;\n}\n\n/** The directory named in the `wrote N files -> …` summary line, for one output. */\nexport function outputSummaryDir(\n output: OutputConfig,\n config: ResolvedConfig,\n): string {\n return output.mode === 'package'\n ? (output.packagesDir ?? config.rootDir)\n : (output.dir ?? config.rootDir);\n}\n\n/**\n * The shared body of `generate`, `validate` and each watch cycle: resolve +\n * load the config, then run the pipeline. `write: false` also skips the\n * `afterEmit` hook (`@kurotako/core` `run()`).\n */\nexport async function loadAndRun(\n opts: LoadAndRunOptions,\n): Promise<LoadAndRunResult> {\n const loaded: LoadResult = await loadConfig({\n cwd: opts.cwd,\n configPath: opts.configPath,\n });\n const result = await run(loaded.config, {\n logger: opts.reporter,\n write: opts.write,\n signal: opts.signal,\n });\n return {\n result,\n config: loaded.config,\n configFile: loaded.configFile,\n rootDir: loaded.rootDir,\n };\n}\n\nexport const generateCommand = defineCommand({\n meta: {\n name: 'generate',\n description: 'run the pipeline and write the generated code',\n },\n args: {\n ...sharedArgs,\n watch: {\n type: 'boolean',\n description: 'rebuild on every schema / config change',\n default: false,\n },\n 'dry-run': {\n type: 'boolean',\n description: 'run everything but write nothing',\n default: false,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n const configPath = args.config || undefined;\n\n if (args.watch) {\n await watchAndRun({ cwd, configPath, reporter });\n return;\n }\n\n const dryRun = Boolean(args['dry-run']);\n const { result, config } = await loadAndRun({\n cwd,\n configPath,\n write: !dryRun,\n reporter,\n });\n\n if (dryRun) {\n reporter.info(`dry run: ${result.files.length} files would be written`);\n return;\n }\n\n const dirs = config.outputs\n .map((output) => relative(cwd, outputSummaryDir(output, config)))\n .join(', ');\n reporter.info(`wrote ${result.files.length} files -> ${dirs}`);\n },\n});\n","/**\n * `tako generate --watch` — a chokidar loop around `loadConfig()` + `run()`.\n * Full regeneration on every change (no incremental). A 100 ms trailing\n * debounce coalesces bursts; a change mid-cycle aborts the in-flight `run()`\n * (via `RunOptions.signal`) and re-runs once it settles. `loadConfig` failures\n * are reported, not fatal — the watcher stays up on `tako.config.ts`.\n *\n * `backlog/features/cli/technical.md` §Watch mode.\n */\nimport { basename, resolve } from 'node:path';\nimport {\n type LoadResult,\n loadConfig as realLoadConfig,\n} from '@kurotako/config';\nimport { run as realRun, TakoError } from '@kurotako/core';\nimport chokidar from 'chokidar';\nimport { renderError } from './errors.js';\nimport type { ConsoleReporter } from './reporter.js';\n\n/** Minimal watcher seam so the loop is unit-testable without touching the fs. */\nexport interface Watcher {\n add(paths: string | readonly string[]): void;\n unwatch(paths: string | readonly string[]): void;\n on(handler: (event: string, path: string) => void): void;\n close(): Promise<void>;\n}\n\nexport interface WatchAndRunOptions {\n cwd: string;\n configPath?: string;\n reporter: ConsoleReporter;\n}\n\nexport interface WatchDeps {\n createWatcher: () => Watcher;\n loadConfig: typeof realLoadConfig;\n run: typeof realRun;\n debounceMs: number;\n}\n\nconst DEBOUNCE_MS = 100;\n\nfunction chokidarWatcher(): Watcher {\n const fsw = chokidar.watch([], {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 20 },\n });\n return {\n add: (paths) => fsw.add(paths as string | string[]),\n unwatch: (paths) => fsw.unwatch(paths as string | string[]),\n on: (handler) => {\n fsw.on('add', (p) => handler('add', p));\n fsw.on('change', (p) => handler('change', p));\n fsw.on('unlink', (p) => handler('unlink', p));\n },\n close: () => fsw.close(),\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError';\n}\n\n/**\n * Runs until `SIGINT` / `SIGTERM`, then closes the watcher and resolves so the\n * caller can exit 0. (The design doc types this `Promise<never>`; it resolves\n * on shutdown here purely so it stays testable.)\n */\nexport async function watchAndRun(\n opts: WatchAndRunOptions,\n deps: Partial<WatchDeps> = {},\n): Promise<void> {\n const { cwd, configPath, reporter } = opts;\n const createWatcher = deps.createWatcher ?? chokidarWatcher;\n const loadConfig = deps.loadConfig ?? realLoadConfig;\n const run = deps.run ?? realRun;\n const debounceMs = deps.debounceMs ?? DEBOUNCE_MS;\n\n const watcher = createWatcher();\n let watched = new Set<string>();\n let inFlight: AbortController | null = null;\n let queued = false;\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let reason = 'initial build';\n\n const guessedConfigFile = configPath\n ? resolve(cwd, configPath)\n : resolve(cwd, 'tako.config.ts');\n\n function applyWatchSet(desired: Set<string>): void {\n for (const path of desired) {\n if (!watched.has(path)) {\n watcher.add(path);\n }\n }\n for (const path of watched) {\n if (!desired.has(path)) {\n watcher.unwatch(path);\n }\n }\n watched = desired;\n }\n\n async function reconcileWatchSet(loaded: LoadResult): Promise<void> {\n const desired = new Set<string>([loaded.configFile]);\n for (const [namespace, source] of Object.entries(loaded.config.sources)) {\n const paths =\n (await source.parser.watchPaths?.({\n namespace,\n cwd: loaded.rootDir,\n logger: reporter,\n })) ?? [];\n for (const path of paths) {\n desired.add(resolve(loaded.rootDir, path));\n }\n }\n applyWatchSet(desired);\n }\n\n async function cycle(): Promise<void> {\n const why = reason;\n reporter.info(`--- rebuild (${why}) ---`);\n const ac = new AbortController();\n inFlight = ac;\n try {\n const loaded = await loadConfig({ cwd, configPath });\n await reconcileWatchSet(loaded);\n const result = await run(loaded.config, {\n logger: reporter,\n signal: ac.signal,\n write: true,\n });\n if (!ac.signal.aborted) {\n reporter.info(`wrote ${result.files.length} files`);\n }\n } catch (error) {\n if (isAbortError(error) || ac.signal.aborted) {\n // Superseded by a newer cycle — swallow.\n } else if (error instanceof TakoError) {\n reporter.error(renderError(error));\n // Keep watching at least the config file so a fix is picked up.\n applyWatchSet(new Set([...watched, guessedConfigFile]));\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n }\n } finally {\n inFlight = null;\n if (queued && !closed) {\n queued = false;\n await cycle();\n }\n }\n }\n\n function trigger(): void {\n if (inFlight) {\n queued = true;\n inFlight.abort();\n return;\n }\n void cycle();\n }\n\n function schedule(event: string, path: string): void {\n if (closed) {\n return;\n }\n reason = `${basename(path)} ${event === 'unlink' ? 'removed' : 'changed'}`;\n if (timer) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = null;\n trigger();\n }, debounceMs);\n }\n\n watcher.on(schedule);\n\n // Initial cycle: a failure is reported inside `cycle()`, never fatal.\n applyWatchSet(new Set([guessedConfigFile]));\n await cycle();\n reporter.info(`watching ${watched.size} paths`);\n\n await new Promise<void>((resolvePromise) => {\n const shutdown = () => {\n closed = true;\n if (timer) {\n clearTimeout(timer);\n }\n inFlight?.abort();\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n void watcher.close().finally(() => resolvePromise());\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n}\n","/**\n * CLI-owned error(s) and `renderError()` — the single formatter the top-level\n * handler in `cli.ts` uses for any `TakoError` (from `@kurotako/core`,\n * `@kurotako/config`, or this package).\n *\n * `backlog/features/cli/technical.md` §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\n\n/** `tako init` refuses to overwrite an existing config unless `--force`. */\nexport class ConfigExistsError extends TakoError {\n readonly path: string;\n\n constructor(path: string) {\n super(\n 'config_exists',\n `a config file already exists at '${path}' (pass --force to overwrite)`,\n );\n this.path = path;\n }\n}\n\ninterface Issue {\n path?: string;\n message?: string;\n}\n\n/**\n * `error [<code>]: <message>` plus any carried context on its own indented\n * lines: located issues (`ConfigShapeError`, `IrValidationError`,\n * `DriverOptionsError`), the offending driver / namespace (`DriverError`,\n * `UnknownNamespaceError`), the dependency cycle path (`DependencyCycleError`),\n * and the `cause` message of a wrapped failure.\n */\nexport function renderError(error: TakoError): string {\n const lines = [`error [${error.code}]: ${error.message}`];\n\n const issues = (error as { issues?: unknown }).issues;\n if (Array.isArray(issues)) {\n for (const issue of issues as Issue[]) {\n const at =\n issue.path === undefined || issue.path === '' ? '<root>' : issue.path;\n lines.push(` - ${at}: ${issue.message}`);\n }\n }\n\n const cycle = (error as { cycle?: unknown }).cycle;\n if (Array.isArray(cycle) && cycle.length > 0) {\n lines.push(` cycle: ${(cycle as string[]).join(' -> ')}`);\n }\n\n const driverName = (error as { driverName?: unknown }).driverName;\n if (typeof driverName === 'string') {\n const role = (error as { role?: unknown }).role;\n const namespace = (error as { namespace?: unknown }).namespace;\n const roleLabel = typeof role === 'string' ? role : 'driver';\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` ${roleLabel}: ${driverName}${where}`);\n } else {\n const generator = (error as { generator?: unknown }).generator;\n if (typeof generator === 'string') {\n const namespace = (error as { namespace?: unknown }).namespace;\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` generator: ${generator}${where}`);\n }\n }\n\n // Wrapped failures (`DriverError`, `HookError`, `ConfigLoadError`, …) carry the\n // real error in `cause`; core masks its type, so surface at least its message.\n const cause = error.cause;\n if (cause !== undefined && cause !== null) {\n const message = cause instanceof Error ? cause.message : String(cause);\n const code = cause instanceof TakoError ? ` [${cause.code}]` : '';\n lines.push(` cause${code}: ${message}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * `tako init` — write the commented `tako.config.ts` skeleton into the current\n * directory. No prompts, no schema auto-detection; refuses to overwrite unless\n * `--force` (`backlog/features/cli/technical.md` §`tako init`).\n *\n * `--monorepo` / `--no-monorepo` picks between `CONFIG_TEMPLATE` and\n * `CONFIG_TEMPLATE_MONOREPO`; unset, it auto-detects a workspace by walking up\n * for the nearest `package.json` (`workspaces` key, or a sibling\n * `pnpm-workspace.yaml`).\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative, resolve } from 'node:path';\nimport { CONFIG_TEMPLATE, CONFIG_TEMPLATE_MONOREPO } from '@kurotako/config';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConfigExistsError } from '../errors.js';\nimport { ConsoleReporter } from '../reporter.js';\n\n/**\n * Walk up from `startDir` to the first directory holding a `package.json`. A\n * workspace when that `package.json` has a `workspaces` key (array, or\n * `{ packages: [...] }`), or when a `pnpm-workspace.yaml` sits next to it.\n * Returns `false` when no `package.json` is found.\n */\nfunction detectMonorepo(startDir: string): boolean {\n let dir = resolve(startDir);\n while (true) {\n const pkgPath = resolve(dir, 'package.json');\n if (existsSync(pkgPath)) {\n if (existsSync(resolve(dir, 'pnpm-workspace.yaml'))) {\n return true;\n }\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n workspaces?: unknown;\n };\n const ws = pkg.workspaces;\n if (\n Array.isArray(ws) ||\n (typeof ws === 'object' &&\n ws !== null &&\n Array.isArray((ws as { packages?: unknown }).packages))\n ) {\n return true;\n }\n } catch {\n // Unreadable / invalid package.json: treat as not a workspace.\n }\n return false;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return false;\n }\n dir = parent;\n }\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'create a tako.config.ts in the current directory',\n },\n args: {\n ...sharedArgs,\n force: {\n type: 'boolean',\n description: 'overwrite an existing config file',\n default: false,\n },\n monorepo: {\n type: 'boolean',\n description:\n 'write the monorepo config layout (auto-detected from workspaces when unset)',\n default: undefined,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n // Unlike `loadConfig`, `init` never walks up: it always targets `cwd`.\n const target = args.config\n ? resolve(cwd, args.config)\n : resolve(cwd, 'tako.config.ts');\n\n if (existsSync(target) && !args.force) {\n throw new ConfigExistsError(target);\n }\n\n // citty leaves an unset boolean flag `undefined` (no `default`), so\n // `--monorepo` / `--no-monorepo` win and absence falls back to detection.\n const monorepo: boolean =\n typeof args.monorepo === 'boolean' ? args.monorepo : detectMonorepo(cwd);\n\n await mkdir(dirname(target), { recursive: true });\n await writeFile(\n target,\n monorepo ? CONFIG_TEMPLATE_MONOREPO : CONFIG_TEMPLATE,\n 'utf8',\n );\n\n const name = relative(cwd, target) || 'tako.config.ts';\n reporter.info(\n monorepo ? `created ${name} (monorepo layout)` : `created ${name}`,\n );\n },\n});\n","/**\n * `tako outdated` — on-demand check of the installed `@kurotako/*` packages\n * in the target project against the npm registry. Informational only, always\n * exits 0.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §`tako outdated`\n * command.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { compareVersions } from '../version-check.js';\n\ninterface PackageEntry {\n name: string;\n installed: string | undefined;\n latest: string | undefined;\n}\n\nfunction findProjectPackageJson(cwd: string): string | undefined {\n let dir = resolve(cwd);\n while (true) {\n const candidate = resolve(dir, 'package.json');\n if (existsSync(candidate)) {\n return candidate;\n }\n if (existsSync(resolve(dir, '.git'))) {\n return undefined;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return undefined;\n }\n dir = parent;\n }\n}\n\nfunction collectKurotakoDependencies(packageJsonPath: string): string[] {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n return [...names].filter((name) => name.startsWith('@kurotako/')).sort();\n}\n\nfunction resolveInstalledVersion(\n packageJsonPath: string,\n name: string,\n): string | undefined {\n try {\n const require = createRequire(packageJsonPath);\n // Packages only export their main entry point, not \"./package.json\"\n // (blocked by their `exports` field), so walk the same node_modules\n // lookup path Node would use and read the package.json directly instead\n // of going through module resolution.\n const searchPaths = require.resolve.paths(name) ?? [];\n for (const modulesDir of searchPaths) {\n const candidate = resolve(modulesDir, name, 'package.json');\n if (existsSync(candidate)) {\n const pkg = JSON.parse(readFileSync(candidate, 'utf8')) as {\n version?: string;\n };\n\n return pkg.version;\n }\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function fetchLatestVersion(name: string): Promise<string | undefined> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${name}/latest`);\n if (!response.ok) {\n return undefined;\n }\n const body = (await response.json()) as { version?: unknown };\n return typeof body.version === 'string' ? body.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction formatTable(entries: PackageEntry[]): string {\n const rows = entries.map((entry) => ({\n name: entry.name,\n installed: entry.installed ?? 'unknown',\n latest: entry.latest ?? 'unknown',\n status:\n entry.installed === undefined || entry.latest === undefined\n ? 'unknown'\n : compareVersions(entry.latest, entry.installed) > 0\n ? 'outdated'\n : 'up to date',\n }));\n\n const widths = {\n name: Math.max(7, ...rows.map((r) => r.name.length)),\n installed: Math.max(9, ...rows.map((r) => r.installed.length)),\n latest: Math.max(6, ...rows.map((r) => r.latest.length)),\n };\n\n const header = ` ${'package'.padEnd(widths.name)} ${'installed'.padEnd(widths.installed)} ${'latest'.padEnd(widths.latest)} status`;\n const lines = rows.map(\n (r) =>\n ` ${r.name.padEnd(widths.name)} ${r.installed.padEnd(widths.installed)} ${r.latest.padEnd(widths.latest)} ${r.status}`,\n );\n\n return [header, ...lines].join('\\n');\n}\n\nexport const outdatedCommand = defineCommand({\n meta: {\n name: 'outdated',\n description:\n 'check installed @kurotako/* packages against the npm registry',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const packageJsonPath = findProjectPackageJson(cwd);\n if (!packageJsonPath) {\n reporter.error('no package.json found (searched up to the project root)');\n process.exitCode ??= 0;\n return;\n }\n\n const names = collectKurotakoDependencies(packageJsonPath);\n if (names.length === 0) {\n reporter.info('no @kurotako/* dependency found');\n process.exitCode ??= 0;\n return;\n }\n\n const entries: PackageEntry[] = await Promise.all(\n names.map(async (name) => ({\n name,\n installed: resolveInstalledVersion(packageJsonPath, name),\n latest: await fetchLatestVersion(name),\n })),\n );\n\n reporter.info(`tako outdated\\n${formatTable(entries)}`);\n process.exitCode ??= 0;\n },\n});\n","/**\n * Background version check for the `tako` binary — compares the installed\n * `kurotako` version against the npm registry, cached for 8h so most\n * invocations do not hit the network.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §Background version\n * check.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst REGISTRY_URL = 'https://registry.npmjs.org/kurotako/latest';\nconst TTL_MS = 8 * 60 * 60 * 1000;\n\nexport interface VersionCacheEntry {\n checkedAt: number;\n latestVersion: string;\n}\n\nexport function getCacheFilePath(): string {\n const base = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');\n return join(base, 'tako', 'version-check.json');\n}\n\nexport function readCache(): VersionCacheEntry | undefined {\n try {\n const raw = readFileSync(getCacheFilePath(), 'utf8');\n const parsed = JSON.parse(raw) as Partial<VersionCacheEntry>;\n if (\n typeof parsed.checkedAt === 'number' &&\n typeof parsed.latestVersion === 'string'\n ) {\n return {\n checkedAt: parsed.checkedAt,\n latestVersion: parsed.latestVersion,\n };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function writeCache(entry: VersionCacheEntry): void {\n const path = getCacheFilePath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(entry));\n}\n\nexport async function refreshLatestVersion(\n signal: AbortSignal,\n): Promise<string> {\n const response = await fetch(REGISTRY_URL, { signal });\n if (!response.ok) {\n throw new Error(`registry request failed with status ${response.status}`);\n }\n const body = (await response.json()) as { version?: unknown };\n if (typeof body.version !== 'string') {\n throw new Error('registry response is missing a version string');\n }\n return body.version;\n}\n\n/**\n * `-1` when `a` is older than `b`, `0` when equal, `1` when newer. Handles\n * `major.minor.patch` plus an optional `-prerelease` suffix (a release always\n * outranks a prerelease of the same `major.minor.patch`).\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const [aMajor, aMinor, aPatch, aPre] = splitVersion(a);\n const [bMajor, bMinor, bPatch, bPre] = splitVersion(b);\n\n if (aMajor !== bMajor) {\n return aMajor < bMajor ? -1 : 1;\n }\n if (aMinor !== bMinor) {\n return aMinor < bMinor ? -1 : 1;\n }\n if (aPatch !== bPatch) {\n return aPatch < bPatch ? -1 : 1;\n }\n\n if (aPre === bPre) {\n return 0;\n }\n if (aPre === undefined) {\n return 1;\n }\n if (bPre === undefined) {\n return -1;\n }\n return aPre < bPre ? -1 : 1;\n}\n\nfunction splitVersion(\n version: string,\n): [major: number, minor: number, patch: number, pre?: string] {\n const [core = '', ...rest] = version.split('-');\n const [major = 0, minor = 0, patch = 0] = core\n .split('.')\n .map((n) => Number.parseInt(n, 10) || 0);\n return [major, minor, patch, rest.length > 0 ? rest.join('-') : undefined];\n}\n\nexport interface CheckForUpdateResult {\n notice?: string;\n refresh?: (signal: AbortSignal) => Promise<void>;\n}\n\nexport function checkForUpdate(currentVersion: string): CheckForUpdateResult {\n const cache = readCache();\n const result: CheckForUpdateResult = {};\n\n if (cache && compareVersions(cache.latestVersion, currentVersion) > 0) {\n result.notice = `tako a new version of kurotako is available: ${currentVersion} → ${cache.latestVersion} (npm i kurotako@latest)`;\n }\n\n const isStale = cache === undefined || Date.now() - cache.checkedAt > TTL_MS;\n if (isStale) {\n result.refresh = async (signal: AbortSignal) => {\n const latestVersion = await refreshLatestVersion(signal);\n writeCache({ checkedAt: Date.now(), latestVersion });\n };\n }\n\n return result;\n}\n","/**\n * `tako validate` — the same checks as `generate` up to (not including)\n * emission. `loadConfig()` + `run({ write: false })`; any `TakoError` propagates\n * to the top-level handler and exits 1\n * (`backlog/features/cli/technical.md` §`tako validate`).\n */\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { loadAndRun } from './generate.js';\n\nexport const validateCommand = defineCommand({\n meta: {\n name: 'validate',\n description: 'check the config and schema without writing anything',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n await loadAndRun({\n cwd: process.cwd(),\n configPath: args.config || undefined,\n write: false,\n reporter,\n });\n reporter.info('config and schema are valid');\n },\n});\n","#!/usr/bin/env node\n/**\n * Executable entry. Thin: parse `process.argv` and delegate to `runCli()`,\n * which sets `process.exitCode`.\n */\nimport { runCli } from '../cli.js';\n\nawait runCli(process.argv.slice(2));\n"],"mappings":"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","names":["TakoError","defineCommand","existsSync","existsSync","relative","loadConfig","run","defineCommand","TakoError","path","loadConfig","run","path","TakoError","loadConfig","run","defineCommand","relative","existsSync","relative","resolve","defineCommand","resolve","existsSync","defineCommand","relative","existsSync","readFileSync","dirname","resolve","defineCommand","readFileSync","dirname","path","resolve","existsSync","dirname","readFileSync","require","defineCommand","defineCommand","defineCommand","defineCommand","TakoError"]}
package/dist/index.cjs CHANGED
@@ -755,9 +755,15 @@ function collectKurotakoDependencies(packageJsonPath) {
755
755
  function resolveInstalledVersion(packageJsonPath, name) {
756
756
  try {
757
757
  const require2 = (0, import_node_module.createRequire)(packageJsonPath);
758
- const resolvedPath = require2.resolve(`${name}/package.json`);
759
- const pkg = JSON.parse((0, import_node_fs5.readFileSync)(resolvedPath, "utf8"));
760
- return pkg.version;
758
+ const searchPaths = require2.resolve.paths(name) ?? [];
759
+ for (const modulesDir of searchPaths) {
760
+ const candidate = (0, import_node_path7.resolve)(modulesDir, name, "package.json");
761
+ if ((0, import_node_fs5.existsSync)(candidate)) {
762
+ const pkg = JSON.parse((0, import_node_fs5.readFileSync)(candidate, "utf8"));
763
+ return pkg.version;
764
+ }
765
+ }
766
+ return void 0;
761
767
  } catch {
762
768
  return void 0;
763
769
  }
@@ -847,7 +853,7 @@ var validateCommand = (0, import_citty5.defineCommand)({
847
853
  });
848
854
 
849
855
  // src/cli.ts
850
- var VERSION = true ? "0.2.0" : "0.0.0-dev";
856
+ var VERSION = true ? "0.2.1" : "0.0.0-dev";
851
857
  var subCommands = {
852
858
  init: initCommand,
853
859
  generate: generateCommand,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/cli.ts","../src/commands/check.ts","../src/args.ts","../src/diff.ts","../src/reporter.ts","../src/commands/generate.ts","../src/watch.ts","../src/errors.ts","../src/commands/init.ts","../src/commands/outdated.ts","../src/version-check.ts","../src/commands/validate.ts"],"sourcesContent":["/**\n * `@kurotako/cli` — the `tako` binary. This barrel is the programmatic surface:\n * `runCli()` plus the reporter / error helpers, for embedders and tests.\n */\nexport { runCli } from './cli.js';\nexport {\n type ComparePlanToDiskArgs,\n comparePlanToDisk,\n type DriftEntry,\n type DriftKind,\n} from './diff.js';\nexport { ConfigExistsError, renderError } from './errors.js';\nexport { ConsoleReporter, type ConsoleReporterOptions } from './reporter.js';\nexport {\n type CheckForUpdateResult,\n checkForUpdate,\n compareVersions,\n getCacheFilePath,\n readCache,\n refreshLatestVersion,\n type VersionCacheEntry,\n writeCache,\n} from './version-check.js';\n","/**\n * `runCli()` — build the citty command tree, dispatch, map every `TakoError` to\n * a formatted message + exit 1. `--version` / `--help` are handled here (citty's\n * own handling lives in `runMain`, which hard-exits — not what a testable\n * `runCli` wants).\n *\n * `backlog/features/cli/technical.md` §Command surface, §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\nimport { type CommandDef, defineCommand, renderUsage, runCommand } from 'citty';\nimport { checkCommand } from './commands/check.js';\nimport { generateCommand } from './commands/generate.js';\nimport { initCommand } from './commands/init.js';\nimport { outdatedCommand } from './commands/outdated.js';\nimport { validateCommand } from './commands/validate.js';\nimport { renderError } from './errors.js';\nimport { ConsoleReporter } from './reporter.js';\nimport { checkForUpdate } from './version-check.js';\n\ndeclare const __TAKO_VERSION__: string;\nconst VERSION =\n typeof __TAKO_VERSION__ === 'string' ? __TAKO_VERSION__ : '0.0.0-dev';\n\nconst subCommands = {\n init: initCommand,\n generate: generateCommand,\n validate: validateCommand,\n check: checkCommand,\n outdated: outdatedCommand,\n};\n\nconst main = defineCommand({\n meta: {\n name: 'tako',\n version: VERSION,\n description: 'synchronise TypeScript schemas from data model to forms',\n },\n subCommands,\n});\n\nexport async function runCli(\n argv: string[],\n options: { currentVersion?: string } = {},\n): Promise<void> {\n const reporter = new ConsoleReporter({\n debug: argv.includes('--debug') || Boolean(process.env.TAKO_DEBUG),\n });\n\n if (argv.includes('--version') || argv.includes('-v')) {\n process.stdout.write(`${VERSION}\\n`);\n process.exitCode ??= 0;\n return;\n }\n\n if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {\n const sub = argv.find((a) => !a.startsWith('-'));\n const isSub = sub !== undefined && sub in subCommands;\n const cmd = (\n isSub ? subCommands[sub as keyof typeof subCommands] : main\n ) as CommandDef;\n process.stdout.write(\n `${await renderUsage(cmd, isSub ? (main as CommandDef) : undefined)}\\n`,\n );\n process.exitCode ??= 0;\n return;\n }\n\n const { notice, refresh } = checkForUpdate(options.currentVersion ?? VERSION);\n if (notice) {\n reporter.info(notice);\n }\n\n const controller = new AbortController();\n const refreshPromise = refresh?.(controller.signal).catch(() => {});\n\n try {\n await runCommand(main, { rawArgs: argv });\n process.exitCode ??= 0;\n } catch (error) {\n if (error instanceof TakoError) {\n reporter.error(renderError(error));\n process.exitCode = 1;\n } else if (error instanceof Error && error.name === 'CLIError') {\n // citty usage error (unknown command, missing argument, …).\n reporter.error(error.message);\n process.exitCode = 1;\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n process.exitCode = 1;\n }\n } finally {\n controller.abort();\n await refreshPromise;\n }\n}\n","/**\n * `tako check` — drift guard. Runs the pipeline in plan mode (no disk writes,\n * no `afterEmit`), then compares the planned tree against what is on disk.\n * Exit 0 when they match, exit 1 on any drift or any `TakoError` (the latter\n * via the top-level handler in `cli.ts`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §Command surface.\n */\nimport { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport { loadConfig } from '@kurotako/config';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport {\n comparePlanToDisk,\n type DriftEntry,\n ignoreBuildArtifacts,\n markedPackageDirs,\n} from '../diff.js';\nimport { ConsoleReporter } from '../reporter.js';\n\nexport const checkCommand = defineCommand({\n meta: {\n name: 'check',\n description:\n 'check the generated output on disk matches a fresh generate (drift guard)',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const { config } = await loadConfig({\n cwd,\n configPath: args.config || undefined,\n });\n const { plan = [] } = await run(config, { logger: reporter, plan: true });\n\n const roots: string[] = [];\n const ignores: ((absPath: string) => boolean)[] = [];\n\n for (const output of config.outputs) {\n if (output.mode === 'package') {\n ignores.push(ignoreBuildArtifacts);\n if (output.packagesDir) {\n roots.push(...(await markedPackageDirs(output.packagesDir)));\n }\n } else {\n const dir = output.dir;\n if (!dir) {\n continue;\n }\n if (!existsSync(dir)) {\n reporter.info(\n `output directory ${relative(config.rootDir, dir)} does not exist — run tako generate`,\n );\n process.exitCode = 1;\n return;\n }\n roots.push(dir);\n }\n }\n\n const ignore = (absPath: string): boolean =>\n ignores.some((fn) => fn(absPath));\n\n const drift = await comparePlanToDisk({\n plan,\n roots,\n ignore,\n rootDir: config.rootDir,\n });\n\n if (drift.length === 0) {\n reporter.info('output is in sync');\n process.exitCode ??= 0;\n return;\n }\n\n reporter.error(formatDrift(drift));\n process.exitCode = 1;\n },\n});\n\nfunction formatDrift(drift: DriftEntry[]): string {\n const width = Math.max(...drift.map((entry) => entry.kind.length));\n const lines = drift.map(\n (entry) => ` ${entry.kind.padEnd(width)} ${entry.path}`,\n );\n return [\n 'drift detected',\n '',\n ...lines,\n '',\n `${drift.length} files differ from a fresh generate. Run \\`tako generate\\`.`,\n ].join('\\n');\n}\n","/**\n * `sharedArgs` — the options every sub-command carries. citty has no\n * first-class global-option slot, so this object is spread into each command's\n * `args` (`backlog/features/cli/technical.md` §Global option).\n */\nimport type { ArgsDef } from 'citty';\n\nexport const sharedArgs = {\n config: {\n type: 'string',\n description: 'path to the tako config file (default: ./tako.config.ts)',\n },\n /** Hidden: not advertised, kept minimal. Enables `debug` reporter output. */\n debug: {\n type: 'boolean',\n default: false,\n },\n} as const satisfies ArgsDef;\n","/**\n * `comparePlanToDisk` — the in-memory comparison behind `tako check`. Takes the\n * `PlannedFile[]` a fresh `generate` would write (from `run({ plan: true })`)\n * and reports every way the tree on disk diverges from it: a planned file that\n * is absent (`missing`) or whose bytes differ (`modified`), and any file under\n * the scanned roots that no planned file claims (`orphan`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §The comparison.\n */\nimport { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PlannedFile } from '@kurotako/core';\n\nexport type DriftKind = 'modified' | 'missing' | 'orphan';\n\nexport interface DriftEntry {\n kind: DriftKind;\n /** Relative to `rootDir`, POSIX separators; a collapsed dir ends with `/`. */\n path: string;\n}\n\nexport interface ComparePlanToDiskArgs {\n plan: PlannedFile[];\n /** Directories walked for orphans (absolute). */\n roots: string[];\n /** Return `true` to exclude an absolute path from the orphan scan. */\n ignore: (absPath: string) => boolean;\n /** Anchor for the reported relative paths (the config-file directory). */\n rootDir: string;\n}\n\nfunction toPosix(rootDir: string, absPath: string): string {\n return path.relative(rootDir, absPath).split(path.sep).join('/');\n}\n\nexport async function comparePlanToDisk(\n args: ComparePlanToDiskArgs,\n): Promise<DriftEntry[]> {\n const { plan, roots, ignore, rootDir } = args;\n const plannedByPath = new Map(plan.map((f) => [path.resolve(f.path), f]));\n const entries: DriftEntry[] = [];\n\n // 1. Expected vs disk.\n for (const [absPath, file] of plannedByPath) {\n if (!existsSync(absPath)) {\n entries.push({ kind: 'missing', path: toPosix(rootDir, absPath) });\n continue;\n }\n const onDisk = await readFile(absPath, 'utf8');\n if (onDisk !== file.content) {\n entries.push({ kind: 'modified', path: toPosix(rootDir, absPath) });\n }\n }\n\n // 2. Orphan scan — a planned file lives under `dir` iff any planned absolute\n // path is `dir` itself or sits below it.\n const plannedPaths = [...plannedByPath.keys()];\n const hasPlannedUnder = (dir: string): boolean => {\n const prefix = `${dir}${path.sep}`;\n return plannedPaths.some((p) => p === dir || p.startsWith(prefix));\n };\n\n const seenRoots = new Set<string>();\n for (const root of roots) {\n const absRoot = path.resolve(root);\n if (seenRoots.has(absRoot) || !existsSync(absRoot)) {\n continue;\n }\n seenRoots.add(absRoot);\n await scan(absRoot);\n }\n\n async function scan(dir: string): Promise<void> {\n // A directory with no planned file underneath collapses to a single entry —\n // unless it holds nothing but ignored files (e.g. only `dist/`).\n if (!hasPlannedUnder(dir)) {\n if (await hasNonIgnoredFile(dir)) {\n entries.push({ kind: 'orphan', path: `${toPosix(rootDir, dir)}/` });\n }\n return;\n }\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isDirectory()) {\n await scan(abs);\n } else if (dirent.isFile() && !plannedByPath.has(abs)) {\n entries.push({ kind: 'orphan', path: toPosix(rootDir, abs) });\n }\n }\n }\n\n async function hasNonIgnoredFile(dir: string): Promise<boolean> {\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isFile()) {\n return true;\n }\n if (dirent.isDirectory() && (await hasNonIgnoredFile(abs))) {\n return true;\n }\n }\n return false;\n }\n\n entries.sort((a, b) =>\n a.path < b.path\n ? -1\n : a.path > b.path\n ? 1\n : a.kind < b.kind\n ? -1\n : a.kind > b.kind\n ? 1\n : 0,\n );\n return entries;\n}\n\n/** Rejects `dist/` and `node_modules/` anywhere in the path (mode B). */\nexport function ignoreBuildArtifacts(absPath: string): boolean {\n return /(^|[/\\\\])(dist|node_modules)([/\\\\]|$)/.test(absPath);\n}\n\n/**\n * Whether `<packagesDir>/<name>` looks like a directory `tako` generated: a\n * `package.json` whose `\"//\"` marker starts with `Generated by tako`.\n */\nexport async function hasGeneratedMarker(pkgDir: string): Promise<boolean> {\n try {\n const pkg = JSON.parse(\n await readFile(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\n/** Every immediate subdirectory of `packagesDir` carrying the tako marker. */\nexport async function markedPackageDirs(\n packagesDir: string,\n): Promise<string[]> {\n if (!existsSync(packagesDir)) {\n return [];\n }\n const out: string[] = [];\n for (const dirent of await readdir(packagesDir, { withFileTypes: true })) {\n if (!dirent.isDirectory()) {\n continue;\n }\n const abs = path.join(packagesDir, dirent.name);\n if (await hasGeneratedMarker(abs)) {\n out.push(abs);\n }\n }\n return out.sort();\n}\n","/**\n * `ConsoleReporter` — the `@kurotako/core` `Logger` the CLI injects into\n * `loadConfig()` / `run()`, plus the per-phase / summary output.\n *\n * Contract (`backlog/features/cli/technical.md` §Reporter):\n * - human output goes to **stderr**, `stdout` stays clean;\n * - `info` / `warn` / `error` shown by default; `debug` only with `--debug` /\n * `TAKO_DEBUG` (a hidden flag, not advertised);\n * - the human-readable message is always shown; the structured `meta` object is\n * printed only with `--debug` (a custom `Logger` still receives it in full),\n * so default output stays prose, not `key=value` noise;\n * - `tako ` prefix, level-coloured; colour auto-off when the stream is not a TTY\n * or `NO_COLOR` is set;\n * - `child(tag)` returns a `Logger` tagging every `meta` with `{ scope: tag }`.\n */\nimport { childLogger, type Logger } from '@kurotako/core';\n\ntype Level = 'debug' | 'info' | 'warn' | 'error';\n\n/** The slice of a writable stream the reporter needs (keeps tests trivial). */\nexport interface WriteStream {\n write(chunk: string): unknown;\n isTTY?: boolean;\n}\n\nexport interface ConsoleReporterOptions {\n /** Show `debug` output. Default: `false` unless `TAKO_DEBUG` is set. */\n debug?: boolean;\n /** Sink for human output. Default: `process.stderr`. */\n stream?: WriteStream;\n /** Force colour on/off. Default: auto (TTY and no `NO_COLOR`). */\n color?: boolean;\n}\n\nconst ESC = String.fromCharCode(27);\nconst ANSI: Record<Level, string> = {\n debug: `${ESC}[2m`, // dim\n info: `${ESC}[36m`, // cyan\n warn: `${ESC}[33m`, // yellow\n error: `${ESC}[31m`, // red\n};\nconst ANSI_RESET = `${ESC}[0m`;\n\nexport class ConsoleReporter implements Logger {\n private readonly stream: WriteStream;\n private readonly showDebug: boolean;\n private readonly color: boolean;\n\n constructor(options: ConsoleReporterOptions = {}) {\n this.stream = options.stream ?? process.stderr;\n this.showDebug = options.debug ?? Boolean(process.env.TAKO_DEBUG);\n this.color =\n options.color ??\n (Boolean(this.stream.isTTY) && process.env.NO_COLOR === undefined);\n }\n\n debug(msg: string, meta?: unknown): void {\n if (this.showDebug) {\n this.write('debug', msg, meta);\n }\n }\n\n info(msg: string, meta?: unknown): void {\n this.write('info', msg, meta);\n }\n\n warn(msg: string, meta?: unknown): void {\n this.write('warn', msg, meta);\n }\n\n error(msg: string, meta?: unknown): void {\n this.write('error', msg, meta);\n }\n\n /** A child `Logger` whose calls carry `{ scope: tag }` in `meta`. */\n child(tag: string): Logger {\n return childLogger(this, { scope: tag });\n }\n\n private write(level: Level, msg: string, meta?: unknown): void {\n const prefix = this.color ? `${ANSI[level]}tako${ANSI_RESET}` : 'tako';\n const detail =\n meta === undefined || !this.showDebug ? '' : ` ${formatMeta(meta)}`;\n this.stream.write(`${prefix} ${msg}${detail}\\n`);\n }\n}\n\nfunction formatMeta(meta: unknown): string {\n if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {\n return Object.entries(meta as Record<string, unknown>)\n .map(([k, v]) => `${k}=${stringify(v)}`)\n .join(' ');\n }\n return stringify(meta);\n}\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n","/**\n * `tako generate` — `loadConfig()` then `run()`. `--dry-run` runs everything but\n * skips the Writer; `--watch` hands off to the chokidar loop\n * (`backlog/features/cli/technical.md` §`tako generate`).\n */\nimport { relative } from 'node:path';\nimport { type LoadResult, loadConfig } from '@kurotako/config';\nimport type { OutputConfig, ResolvedConfig, RunResult } from '@kurotako/core';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { watchAndRun } from '../watch.js';\n\nexport interface LoadAndRunOptions {\n cwd: string;\n configPath?: string;\n write: boolean;\n signal?: AbortSignal;\n reporter: ConsoleReporter;\n}\n\nexport interface LoadAndRunResult {\n result: RunResult;\n config: ResolvedConfig;\n configFile: string;\n rootDir: string;\n}\n\n/** The directory named in the `wrote N files -> …` summary line, for one output. */\nexport function outputSummaryDir(\n output: OutputConfig,\n config: ResolvedConfig,\n): string {\n return output.mode === 'package'\n ? (output.packagesDir ?? config.rootDir)\n : (output.dir ?? config.rootDir);\n}\n\n/**\n * The shared body of `generate`, `validate` and each watch cycle: resolve +\n * load the config, then run the pipeline. `write: false` also skips the\n * `afterEmit` hook (`@kurotako/core` `run()`).\n */\nexport async function loadAndRun(\n opts: LoadAndRunOptions,\n): Promise<LoadAndRunResult> {\n const loaded: LoadResult = await loadConfig({\n cwd: opts.cwd,\n configPath: opts.configPath,\n });\n const result = await run(loaded.config, {\n logger: opts.reporter,\n write: opts.write,\n signal: opts.signal,\n });\n return {\n result,\n config: loaded.config,\n configFile: loaded.configFile,\n rootDir: loaded.rootDir,\n };\n}\n\nexport const generateCommand = defineCommand({\n meta: {\n name: 'generate',\n description: 'run the pipeline and write the generated code',\n },\n args: {\n ...sharedArgs,\n watch: {\n type: 'boolean',\n description: 'rebuild on every schema / config change',\n default: false,\n },\n 'dry-run': {\n type: 'boolean',\n description: 'run everything but write nothing',\n default: false,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n const configPath = args.config || undefined;\n\n if (args.watch) {\n await watchAndRun({ cwd, configPath, reporter });\n return;\n }\n\n const dryRun = Boolean(args['dry-run']);\n const { result, config } = await loadAndRun({\n cwd,\n configPath,\n write: !dryRun,\n reporter,\n });\n\n if (dryRun) {\n reporter.info(`dry run: ${result.files.length} files would be written`);\n return;\n }\n\n const dirs = config.outputs\n .map((output) => relative(cwd, outputSummaryDir(output, config)))\n .join(', ');\n reporter.info(`wrote ${result.files.length} files -> ${dirs}`);\n },\n});\n","/**\n * `tako generate --watch` — a chokidar loop around `loadConfig()` + `run()`.\n * Full regeneration on every change (no incremental). A 100 ms trailing\n * debounce coalesces bursts; a change mid-cycle aborts the in-flight `run()`\n * (via `RunOptions.signal`) and re-runs once it settles. `loadConfig` failures\n * are reported, not fatal — the watcher stays up on `tako.config.ts`.\n *\n * `backlog/features/cli/technical.md` §Watch mode.\n */\nimport { basename, resolve } from 'node:path';\nimport {\n type LoadResult,\n loadConfig as realLoadConfig,\n} from '@kurotako/config';\nimport { run as realRun, TakoError } from '@kurotako/core';\nimport chokidar from 'chokidar';\nimport { renderError } from './errors.js';\nimport type { ConsoleReporter } from './reporter.js';\n\n/** Minimal watcher seam so the loop is unit-testable without touching the fs. */\nexport interface Watcher {\n add(paths: string | readonly string[]): void;\n unwatch(paths: string | readonly string[]): void;\n on(handler: (event: string, path: string) => void): void;\n close(): Promise<void>;\n}\n\nexport interface WatchAndRunOptions {\n cwd: string;\n configPath?: string;\n reporter: ConsoleReporter;\n}\n\nexport interface WatchDeps {\n createWatcher: () => Watcher;\n loadConfig: typeof realLoadConfig;\n run: typeof realRun;\n debounceMs: number;\n}\n\nconst DEBOUNCE_MS = 100;\n\nfunction chokidarWatcher(): Watcher {\n const fsw = chokidar.watch([], {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 20 },\n });\n return {\n add: (paths) => fsw.add(paths as string | string[]),\n unwatch: (paths) => fsw.unwatch(paths as string | string[]),\n on: (handler) => {\n fsw.on('add', (p) => handler('add', p));\n fsw.on('change', (p) => handler('change', p));\n fsw.on('unlink', (p) => handler('unlink', p));\n },\n close: () => fsw.close(),\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError';\n}\n\n/**\n * Runs until `SIGINT` / `SIGTERM`, then closes the watcher and resolves so the\n * caller can exit 0. (The design doc types this `Promise<never>`; it resolves\n * on shutdown here purely so it stays testable.)\n */\nexport async function watchAndRun(\n opts: WatchAndRunOptions,\n deps: Partial<WatchDeps> = {},\n): Promise<void> {\n const { cwd, configPath, reporter } = opts;\n const createWatcher = deps.createWatcher ?? chokidarWatcher;\n const loadConfig = deps.loadConfig ?? realLoadConfig;\n const run = deps.run ?? realRun;\n const debounceMs = deps.debounceMs ?? DEBOUNCE_MS;\n\n const watcher = createWatcher();\n let watched = new Set<string>();\n let inFlight: AbortController | null = null;\n let queued = false;\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let reason = 'initial build';\n\n const guessedConfigFile = configPath\n ? resolve(cwd, configPath)\n : resolve(cwd, 'tako.config.ts');\n\n function applyWatchSet(desired: Set<string>): void {\n for (const path of desired) {\n if (!watched.has(path)) {\n watcher.add(path);\n }\n }\n for (const path of watched) {\n if (!desired.has(path)) {\n watcher.unwatch(path);\n }\n }\n watched = desired;\n }\n\n async function reconcileWatchSet(loaded: LoadResult): Promise<void> {\n const desired = new Set<string>([loaded.configFile]);\n for (const [namespace, source] of Object.entries(loaded.config.sources)) {\n const paths =\n (await source.parser.watchPaths?.({\n namespace,\n cwd: loaded.rootDir,\n logger: reporter,\n })) ?? [];\n for (const path of paths) {\n desired.add(resolve(loaded.rootDir, path));\n }\n }\n applyWatchSet(desired);\n }\n\n async function cycle(): Promise<void> {\n const why = reason;\n reporter.info(`--- rebuild (${why}) ---`);\n const ac = new AbortController();\n inFlight = ac;\n try {\n const loaded = await loadConfig({ cwd, configPath });\n await reconcileWatchSet(loaded);\n const result = await run(loaded.config, {\n logger: reporter,\n signal: ac.signal,\n write: true,\n });\n if (!ac.signal.aborted) {\n reporter.info(`wrote ${result.files.length} files`);\n }\n } catch (error) {\n if (isAbortError(error) || ac.signal.aborted) {\n // Superseded by a newer cycle — swallow.\n } else if (error instanceof TakoError) {\n reporter.error(renderError(error));\n // Keep watching at least the config file so a fix is picked up.\n applyWatchSet(new Set([...watched, guessedConfigFile]));\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n }\n } finally {\n inFlight = null;\n if (queued && !closed) {\n queued = false;\n await cycle();\n }\n }\n }\n\n function trigger(): void {\n if (inFlight) {\n queued = true;\n inFlight.abort();\n return;\n }\n void cycle();\n }\n\n function schedule(event: string, path: string): void {\n if (closed) {\n return;\n }\n reason = `${basename(path)} ${event === 'unlink' ? 'removed' : 'changed'}`;\n if (timer) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = null;\n trigger();\n }, debounceMs);\n }\n\n watcher.on(schedule);\n\n // Initial cycle: a failure is reported inside `cycle()`, never fatal.\n applyWatchSet(new Set([guessedConfigFile]));\n await cycle();\n reporter.info(`watching ${watched.size} paths`);\n\n await new Promise<void>((resolvePromise) => {\n const shutdown = () => {\n closed = true;\n if (timer) {\n clearTimeout(timer);\n }\n inFlight?.abort();\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n void watcher.close().finally(() => resolvePromise());\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n}\n","/**\n * CLI-owned error(s) and `renderError()` — the single formatter the top-level\n * handler in `cli.ts` uses for any `TakoError` (from `@kurotako/core`,\n * `@kurotako/config`, or this package).\n *\n * `backlog/features/cli/technical.md` §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\n\n/** `tako init` refuses to overwrite an existing config unless `--force`. */\nexport class ConfigExistsError extends TakoError {\n readonly path: string;\n\n constructor(path: string) {\n super(\n 'config_exists',\n `a config file already exists at '${path}' (pass --force to overwrite)`,\n );\n this.path = path;\n }\n}\n\ninterface Issue {\n path?: string;\n message?: string;\n}\n\n/**\n * `error [<code>]: <message>` plus any carried context on its own indented\n * lines: located issues (`ConfigShapeError`, `IrValidationError`,\n * `DriverOptionsError`), the offending driver / namespace (`DriverError`,\n * `UnknownNamespaceError`), the dependency cycle path (`DependencyCycleError`),\n * and the `cause` message of a wrapped failure.\n */\nexport function renderError(error: TakoError): string {\n const lines = [`error [${error.code}]: ${error.message}`];\n\n const issues = (error as { issues?: unknown }).issues;\n if (Array.isArray(issues)) {\n for (const issue of issues as Issue[]) {\n const at =\n issue.path === undefined || issue.path === '' ? '<root>' : issue.path;\n lines.push(` - ${at}: ${issue.message}`);\n }\n }\n\n const cycle = (error as { cycle?: unknown }).cycle;\n if (Array.isArray(cycle) && cycle.length > 0) {\n lines.push(` cycle: ${(cycle as string[]).join(' -> ')}`);\n }\n\n const driverName = (error as { driverName?: unknown }).driverName;\n if (typeof driverName === 'string') {\n const role = (error as { role?: unknown }).role;\n const namespace = (error as { namespace?: unknown }).namespace;\n const roleLabel = typeof role === 'string' ? role : 'driver';\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` ${roleLabel}: ${driverName}${where}`);\n } else {\n const generator = (error as { generator?: unknown }).generator;\n if (typeof generator === 'string') {\n const namespace = (error as { namespace?: unknown }).namespace;\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` generator: ${generator}${where}`);\n }\n }\n\n // Wrapped failures (`DriverError`, `HookError`, `ConfigLoadError`, …) carry the\n // real error in `cause`; core masks its type, so surface at least its message.\n const cause = error.cause;\n if (cause !== undefined && cause !== null) {\n const message = cause instanceof Error ? cause.message : String(cause);\n const code = cause instanceof TakoError ? ` [${cause.code}]` : '';\n lines.push(` cause${code}: ${message}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * `tako init` — write the commented `tako.config.ts` skeleton into the current\n * directory. No prompts, no schema auto-detection; refuses to overwrite unless\n * `--force` (`backlog/features/cli/technical.md` §`tako init`).\n *\n * `--monorepo` / `--no-monorepo` picks between `CONFIG_TEMPLATE` and\n * `CONFIG_TEMPLATE_MONOREPO`; unset, it auto-detects a workspace by walking up\n * for the nearest `package.json` (`workspaces` key, or a sibling\n * `pnpm-workspace.yaml`).\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative, resolve } from 'node:path';\nimport { CONFIG_TEMPLATE, CONFIG_TEMPLATE_MONOREPO } from '@kurotako/config';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConfigExistsError } from '../errors.js';\nimport { ConsoleReporter } from '../reporter.js';\n\n/**\n * Walk up from `startDir` to the first directory holding a `package.json`. A\n * workspace when that `package.json` has a `workspaces` key (array, or\n * `{ packages: [...] }`), or when a `pnpm-workspace.yaml` sits next to it.\n * Returns `false` when no `package.json` is found.\n */\nfunction detectMonorepo(startDir: string): boolean {\n let dir = resolve(startDir);\n while (true) {\n const pkgPath = resolve(dir, 'package.json');\n if (existsSync(pkgPath)) {\n if (existsSync(resolve(dir, 'pnpm-workspace.yaml'))) {\n return true;\n }\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n workspaces?: unknown;\n };\n const ws = pkg.workspaces;\n if (\n Array.isArray(ws) ||\n (typeof ws === 'object' &&\n ws !== null &&\n Array.isArray((ws as { packages?: unknown }).packages))\n ) {\n return true;\n }\n } catch {\n // Unreadable / invalid package.json: treat as not a workspace.\n }\n return false;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return false;\n }\n dir = parent;\n }\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'create a tako.config.ts in the current directory',\n },\n args: {\n ...sharedArgs,\n force: {\n type: 'boolean',\n description: 'overwrite an existing config file',\n default: false,\n },\n monorepo: {\n type: 'boolean',\n description:\n 'write the monorepo config layout (auto-detected from workspaces when unset)',\n default: undefined,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n // Unlike `loadConfig`, `init` never walks up: it always targets `cwd`.\n const target = args.config\n ? resolve(cwd, args.config)\n : resolve(cwd, 'tako.config.ts');\n\n if (existsSync(target) && !args.force) {\n throw new ConfigExistsError(target);\n }\n\n // citty leaves an unset boolean flag `undefined` (no `default`), so\n // `--monorepo` / `--no-monorepo` win and absence falls back to detection.\n const monorepo: boolean =\n typeof args.monorepo === 'boolean' ? args.monorepo : detectMonorepo(cwd);\n\n await mkdir(dirname(target), { recursive: true });\n await writeFile(\n target,\n monorepo ? CONFIG_TEMPLATE_MONOREPO : CONFIG_TEMPLATE,\n 'utf8',\n );\n\n const name = relative(cwd, target) || 'tako.config.ts';\n reporter.info(\n monorepo ? `created ${name} (monorepo layout)` : `created ${name}`,\n );\n },\n});\n","/**\n * `tako outdated` — on-demand check of the installed `@kurotako/*` packages\n * in the target project against the npm registry. Informational only, always\n * exits 0.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §`tako outdated`\n * command.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { compareVersions } from '../version-check.js';\n\ninterface PackageEntry {\n name: string;\n installed: string | undefined;\n latest: string | undefined;\n}\n\nfunction findProjectPackageJson(cwd: string): string | undefined {\n let dir = resolve(cwd);\n while (true) {\n const candidate = resolve(dir, 'package.json');\n if (existsSync(candidate)) {\n return candidate;\n }\n if (existsSync(resolve(dir, '.git'))) {\n return undefined;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return undefined;\n }\n dir = parent;\n }\n}\n\nfunction collectKurotakoDependencies(packageJsonPath: string): string[] {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n return [...names].filter((name) => name.startsWith('@kurotako/')).sort();\n}\n\nfunction resolveInstalledVersion(\n packageJsonPath: string,\n name: string,\n): string | undefined {\n try {\n const require = createRequire(packageJsonPath);\n const resolvedPath = require.resolve(`${name}/package.json`);\n const pkg = JSON.parse(readFileSync(resolvedPath, 'utf8')) as {\n version?: string;\n };\n return pkg.version;\n } catch {\n return undefined;\n }\n}\n\nasync function fetchLatestVersion(name: string): Promise<string | undefined> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${name}/latest`);\n if (!response.ok) {\n return undefined;\n }\n const body = (await response.json()) as { version?: unknown };\n return typeof body.version === 'string' ? body.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction formatTable(entries: PackageEntry[]): string {\n const rows = entries.map((entry) => ({\n name: entry.name,\n installed: entry.installed ?? 'unknown',\n latest: entry.latest ?? 'unknown',\n status:\n entry.installed === undefined || entry.latest === undefined\n ? 'unknown'\n : compareVersions(entry.latest, entry.installed) > 0\n ? 'outdated'\n : 'up to date',\n }));\n\n const widths = {\n name: Math.max(7, ...rows.map((r) => r.name.length)),\n installed: Math.max(9, ...rows.map((r) => r.installed.length)),\n latest: Math.max(6, ...rows.map((r) => r.latest.length)),\n };\n\n const header = ` ${'package'.padEnd(widths.name)} ${'installed'.padEnd(widths.installed)} ${'latest'.padEnd(widths.latest)} status`;\n const lines = rows.map(\n (r) =>\n ` ${r.name.padEnd(widths.name)} ${r.installed.padEnd(widths.installed)} ${r.latest.padEnd(widths.latest)} ${r.status}`,\n );\n\n return [header, ...lines].join('\\n');\n}\n\nexport const outdatedCommand = defineCommand({\n meta: {\n name: 'outdated',\n description:\n 'check installed @kurotako/* packages against the npm registry',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const packageJsonPath = findProjectPackageJson(cwd);\n if (!packageJsonPath) {\n reporter.error('no package.json found (searched up to the project root)');\n process.exitCode ??= 0;\n return;\n }\n\n const names = collectKurotakoDependencies(packageJsonPath);\n if (names.length === 0) {\n reporter.info('no @kurotako/* dependency found');\n process.exitCode ??= 0;\n return;\n }\n\n const entries: PackageEntry[] = await Promise.all(\n names.map(async (name) => ({\n name,\n installed: resolveInstalledVersion(packageJsonPath, name),\n latest: await fetchLatestVersion(name),\n })),\n );\n\n reporter.info(`tako outdated\\n${formatTable(entries)}`);\n process.exitCode ??= 0;\n },\n});\n","/**\n * Background version check for the `tako` binary — compares the installed\n * `kurotako` version against the npm registry, cached for 8h so most\n * invocations do not hit the network.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §Background version\n * check.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst REGISTRY_URL = 'https://registry.npmjs.org/kurotako/latest';\nconst TTL_MS = 8 * 60 * 60 * 1000;\n\nexport interface VersionCacheEntry {\n checkedAt: number;\n latestVersion: string;\n}\n\nexport function getCacheFilePath(): string {\n const base = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');\n return join(base, 'tako', 'version-check.json');\n}\n\nexport function readCache(): VersionCacheEntry | undefined {\n try {\n const raw = readFileSync(getCacheFilePath(), 'utf8');\n const parsed = JSON.parse(raw) as Partial<VersionCacheEntry>;\n if (\n typeof parsed.checkedAt === 'number' &&\n typeof parsed.latestVersion === 'string'\n ) {\n return {\n checkedAt: parsed.checkedAt,\n latestVersion: parsed.latestVersion,\n };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function writeCache(entry: VersionCacheEntry): void {\n const path = getCacheFilePath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(entry));\n}\n\nexport async function refreshLatestVersion(\n signal: AbortSignal,\n): Promise<string> {\n const response = await fetch(REGISTRY_URL, { signal });\n if (!response.ok) {\n throw new Error(`registry request failed with status ${response.status}`);\n }\n const body = (await response.json()) as { version?: unknown };\n if (typeof body.version !== 'string') {\n throw new Error('registry response is missing a version string');\n }\n return body.version;\n}\n\n/**\n * `-1` when `a` is older than `b`, `0` when equal, `1` when newer. Handles\n * `major.minor.patch` plus an optional `-prerelease` suffix (a release always\n * outranks a prerelease of the same `major.minor.patch`).\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const [aMajor, aMinor, aPatch, aPre] = splitVersion(a);\n const [bMajor, bMinor, bPatch, bPre] = splitVersion(b);\n\n if (aMajor !== bMajor) {\n return aMajor < bMajor ? -1 : 1;\n }\n if (aMinor !== bMinor) {\n return aMinor < bMinor ? -1 : 1;\n }\n if (aPatch !== bPatch) {\n return aPatch < bPatch ? -1 : 1;\n }\n\n if (aPre === bPre) {\n return 0;\n }\n if (aPre === undefined) {\n return 1;\n }\n if (bPre === undefined) {\n return -1;\n }\n return aPre < bPre ? -1 : 1;\n}\n\nfunction splitVersion(\n version: string,\n): [major: number, minor: number, patch: number, pre?: string] {\n const [core = '', ...rest] = version.split('-');\n const [major = 0, minor = 0, patch = 0] = core\n .split('.')\n .map((n) => Number.parseInt(n, 10) || 0);\n return [major, minor, patch, rest.length > 0 ? rest.join('-') : undefined];\n}\n\nexport interface CheckForUpdateResult {\n notice?: string;\n refresh?: (signal: AbortSignal) => Promise<void>;\n}\n\nexport function checkForUpdate(currentVersion: string): CheckForUpdateResult {\n const cache = readCache();\n const result: CheckForUpdateResult = {};\n\n if (cache && compareVersions(cache.latestVersion, currentVersion) > 0) {\n result.notice = `tako a new version of kurotako is available: ${currentVersion} → ${cache.latestVersion} (npm i kurotako@latest)`;\n }\n\n const isStale = cache === undefined || Date.now() - cache.checkedAt > TTL_MS;\n if (isStale) {\n result.refresh = async (signal: AbortSignal) => {\n const latestVersion = await refreshLatestVersion(signal);\n writeCache({ checkedAt: Date.now(), latestVersion });\n };\n }\n\n return result;\n}\n","/**\n * `tako validate` — the same checks as `generate` up to (not including)\n * emission. `loadConfig()` + `run({ write: false })`; any `TakoError` propagates\n * to the top-level handler and exits 1\n * (`backlog/features/cli/technical.md` §`tako validate`).\n */\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { loadAndRun } from './generate.js';\n\nexport const validateCommand = defineCommand({\n meta: {\n name: 'validate',\n description: 'check the config and schema without writing anything',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n await loadAndRun({\n cwd: process.cwd(),\n configPath: args.config || undefined,\n write: false,\n reporter,\n });\n reporter.info('config and schema are valid');\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQA,IAAAA,eAA0B;AAC1B,IAAAC,gBAAwE;;;ACDxE,IAAAC,kBAA2B;AAC3B,IAAAC,oBAAyB;AACzB,oBAA2B;AAC3B,IAAAC,eAAoB;AACpB,mBAA8B;;;ACLvB,IAAM,aAAa;AAAA,EACxB,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;;;ACRA,qBAA2B;AAC3B,sBAAkC;AAClC,uBAAiB;AAqBjB,SAAS,QAAQ,SAAiB,SAAyB;AACzD,SAAO,iBAAAC,QAAK,SAAS,SAAS,OAAO,EAAE,MAAM,iBAAAA,QAAK,GAAG,EAAE,KAAK,GAAG;AACjE;AAEA,eAAsB,kBACpB,MACuB;AACvB,QAAM,EAAE,MAAM,OAAO,QAAQ,QAAQ,IAAI;AACzC,QAAM,gBAAgB,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,iBAAAA,QAAK,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;AACxE,QAAM,UAAwB,CAAC;AAG/B,aAAW,CAAC,SAAS,IAAI,KAAK,eAAe;AAC3C,QAAI,KAAC,2BAAW,OAAO,GAAG;AACxB,cAAQ,KAAK,EAAE,MAAM,WAAW,MAAM,QAAQ,SAAS,OAAO,EAAE,CAAC;AACjE;AAAA,IACF;AACA,UAAM,SAAS,UAAM,0BAAS,SAAS,MAAM;AAC7C,QAAI,WAAW,KAAK,SAAS;AAC3B,cAAQ,KAAK,EAAE,MAAM,YAAY,MAAM,QAAQ,SAAS,OAAO,EAAE,CAAC;AAAA,IACpE;AAAA,EACF;AAIA,QAAM,eAAe,CAAC,GAAG,cAAc,KAAK,CAAC;AAC7C,QAAM,kBAAkB,CAAC,QAAyB;AAChD,UAAM,SAAS,GAAG,GAAG,GAAG,iBAAAA,QAAK,GAAG;AAChC,WAAO,aAAa,KAAK,CAAC,MAAM,MAAM,OAAO,EAAE,WAAW,MAAM,CAAC;AAAA,EACnE;AAEA,QAAM,YAAY,oBAAI,IAAY;AAClC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,iBAAAA,QAAK,QAAQ,IAAI;AACjC,QAAI,UAAU,IAAI,OAAO,KAAK,KAAC,2BAAW,OAAO,GAAG;AAClD;AAAA,IACF;AACA,cAAU,IAAI,OAAO;AACrB,UAAM,KAAK,OAAO;AAAA,EACpB;AAEA,iBAAe,KAAK,KAA4B;AAG9C,QAAI,CAAC,gBAAgB,GAAG,GAAG;AACzB,UAAI,MAAM,kBAAkB,GAAG,GAAG;AAChC,gBAAQ,KAAK,EAAE,MAAM,UAAU,MAAM,GAAG,QAAQ,SAAS,GAAG,CAAC,IAAI,CAAC;AAAA,MACpE;AACA;AAAA,IACF;AACA,eAAW,UAAU,UAAM,yBAAQ,KAAK,EAAE,eAAe,KAAK,CAAC,GAAG;AAChE,YAAM,MAAM,iBAAAA,QAAK,KAAK,KAAK,OAAO,IAAI;AACtC,UAAI,OAAO,GAAG,GAAG;AACf;AAAA,MACF;AACA,UAAI,OAAO,YAAY,GAAG;AACxB,cAAM,KAAK,GAAG;AAAA,MAChB,WAAW,OAAO,OAAO,KAAK,CAAC,cAAc,IAAI,GAAG,GAAG;AACrD,gBAAQ,KAAK,EAAE,MAAM,UAAU,MAAM,QAAQ,SAAS,GAAG,EAAE,CAAC;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAEA,iBAAe,kBAAkB,KAA+B;AAC9D,eAAW,UAAU,UAAM,yBAAQ,KAAK,EAAE,eAAe,KAAK,CAAC,GAAG;AAChE,YAAM,MAAM,iBAAAA,QAAK,KAAK,KAAK,OAAO,IAAI;AACtC,UAAI,OAAO,GAAG,GAAG;AACf;AAAA,MACF;AACA,UAAI,OAAO,OAAO,GAAG;AACnB,eAAO;AAAA,MACT;AACA,UAAI,OAAO,YAAY,KAAM,MAAM,kBAAkB,GAAG,GAAI;AAC1D,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,UAAQ;AAAA,IAAK,CAAC,GAAG,MACf,EAAE,OAAO,EAAE,OACP,KACA,EAAE,OAAO,EAAE,OACT,IACA,EAAE,OAAO,EAAE,OACT,KACA,EAAE,OAAO,EAAE,OACT,IACA;AAAA,EACZ;AACA,SAAO;AACT;AAGO,SAAS,qBAAqB,SAA0B;AAC7D,SAAO,wCAAwC,KAAK,OAAO;AAC7D;AAMA,eAAsB,mBAAmB,QAAkC;AACzE,MAAI;AACF,UAAM,MAAM,KAAK;AAAA,MACf,UAAM,0BAAS,iBAAAA,QAAK,KAAK,QAAQ,cAAc,GAAG,MAAM;AAAA,IAC1D;AACA,WACE,OAAO,IAAI,IAAI,MAAM,YAAY,IAAI,IAAI,EAAE,WAAW,mBAAmB;AAAA,EAE7E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,kBACpB,aACmB;AACnB,MAAI,KAAC,2BAAW,WAAW,GAAG;AAC5B,WAAO,CAAC;AAAA,EACV;AACA,QAAM,MAAgB,CAAC;AACvB,aAAW,UAAU,UAAM,yBAAQ,aAAa,EAAE,eAAe,KAAK,CAAC,GAAG;AACxE,QAAI,CAAC,OAAO,YAAY,GAAG;AACzB;AAAA,IACF;AACA,UAAM,MAAM,iBAAAA,QAAK,KAAK,aAAa,OAAO,IAAI;AAC9C,QAAI,MAAM,mBAAmB,GAAG,GAAG;AACjC,UAAI,KAAK,GAAG;AAAA,IACd;AAAA,EACF;AACA,SAAO,IAAI,KAAK;AAClB;;;ACtJA,kBAAyC;AAmBzC,IAAM,MAAM,OAAO,aAAa,EAAE;AAClC,IAAM,OAA8B;AAAA,EAClC,OAAO,GAAG,GAAG;AAAA;AAAA,EACb,MAAM,GAAG,GAAG;AAAA;AAAA,EACZ,MAAM,GAAG,GAAG;AAAA;AAAA,EACZ,OAAO,GAAG,GAAG;AAAA;AACf;AACA,IAAM,aAAa,GAAG,GAAG;AAElB,IAAM,kBAAN,MAAwC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,UAAkC,CAAC,GAAG;AAChD,SAAK,SAAS,QAAQ,UAAU,QAAQ;AACxC,SAAK,YAAY,QAAQ,SAAS,QAAQ,QAAQ,IAAI,UAAU;AAChE,SAAK,QACH,QAAQ,UACP,QAAQ,KAAK,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAa;AAAA,EAC5D;AAAA,EAEA,MAAM,KAAa,MAAsB;AACvC,QAAI,KAAK,WAAW;AAClB,WAAK,MAAM,SAAS,KAAK,IAAI;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,KAAK,KAAa,MAAsB;AACtC,SAAK,MAAM,QAAQ,KAAK,IAAI;AAAA,EAC9B;AAAA,EAEA,KAAK,KAAa,MAAsB;AACtC,SAAK,MAAM,QAAQ,KAAK,IAAI;AAAA,EAC9B;AAAA,EAEA,MAAM,KAAa,MAAsB;AACvC,SAAK,MAAM,SAAS,KAAK,IAAI;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAM,KAAqB;AACzB,eAAO,yBAAY,MAAM,EAAE,OAAO,IAAI,CAAC;AAAA,EACzC;AAAA,EAEQ,MAAM,OAAc,KAAa,MAAsB;AAC7D,UAAM,SAAS,KAAK,QAAQ,GAAG,KAAK,KAAK,CAAC,OAAO,UAAU,KAAK;AAChE,UAAM,SACJ,SAAS,UAAa,CAAC,KAAK,YAAY,KAAK,IAAI,WAAW,IAAI,CAAC;AACnE,SAAK,OAAO,MAAM,GAAG,MAAM,IAAI,GAAG,GAAG,MAAM;AAAA,CAAI;AAAA,EACjD;AACF;AAEA,SAAS,WAAW,MAAuB;AACzC,MAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AACrE,WAAO,OAAO,QAAQ,IAA+B,EAClD,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,CAAC,EAAE,EACtC,KAAK,GAAG;AAAA,EACb;AACA,SAAO,UAAU,IAAI;AACvB;AAEA,SAAS,UAAU,OAAwB;AACzC,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,MAAI;AACF,WAAO,KAAK,UAAU,KAAK,KAAK,OAAO,KAAK;AAAA,EAC9C,QAAQ;AACN,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;;;AHnFO,IAAM,mBAAe,4BAAc;AAAA,EACxC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM,EAAE,GAAG,WAAW;AAAA,EACtB,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,WAAW,IAAI,gBAAgB,EAAE,OAAO,QAAQ,KAAK,KAAK,EAAE,CAAC;AACnE,UAAM,MAAM,QAAQ,IAAI;AAExB,UAAM,EAAE,OAAO,IAAI,UAAM,0BAAW;AAAA,MAClC;AAAA,MACA,YAAY,KAAK,UAAU;AAAA,IAC7B,CAAC;AACD,UAAM,EAAE,OAAO,CAAC,EAAE,IAAI,UAAM,kBAAI,QAAQ,EAAE,QAAQ,UAAU,MAAM,KAAK,CAAC;AAExE,UAAM,QAAkB,CAAC;AACzB,UAAM,UAA4C,CAAC;AAEnD,eAAW,UAAU,OAAO,SAAS;AACnC,UAAI,OAAO,SAAS,WAAW;AAC7B,gBAAQ,KAAK,oBAAoB;AACjC,YAAI,OAAO,aAAa;AACtB,gBAAM,KAAK,GAAI,MAAM,kBAAkB,OAAO,WAAW,CAAE;AAAA,QAC7D;AAAA,MACF,OAAO;AACL,cAAM,MAAM,OAAO;AACnB,YAAI,CAAC,KAAK;AACR;AAAA,QACF;AACA,YAAI,KAAC,4BAAW,GAAG,GAAG;AACpB,mBAAS;AAAA,YACP,wBAAoB,4BAAS,OAAO,SAAS,GAAG,CAAC;AAAA,UACnD;AACA,kBAAQ,WAAW;AACnB;AAAA,QACF;AACA,cAAM,KAAK,GAAG;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,SAAS,CAAC,YACd,QAAQ,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;AAElC,UAAM,QAAQ,MAAM,kBAAkB;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,OAAO;AAAA,IAClB,CAAC;AAED,QAAI,MAAM,WAAW,GAAG;AACtB,eAAS,KAAK,mBAAmB;AACjC,cAAQ,aAAa;AACrB;AAAA,IACF;AAEA,aAAS,MAAM,YAAY,KAAK,CAAC;AACjC,YAAQ,WAAW;AAAA,EACrB;AACF,CAAC;AAED,SAAS,YAAY,OAA6B;AAChD,QAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,MAAM,KAAK,MAAM,CAAC;AACjE,QAAM,QAAQ,MAAM;AAAA,IAClB,CAAC,UAAU,KAAK,MAAM,KAAK,OAAO,KAAK,CAAC,KAAK,MAAM,IAAI;AAAA,EACzD;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA,GAAG,MAAM,MAAM;AAAA,EACjB,EAAE,KAAK,IAAI;AACb;;;AI5FA,IAAAC,oBAAyB;AACzB,IAAAC,iBAA4C;AAE5C,IAAAC,eAAoB;AACpB,IAAAC,gBAA8B;;;ACA9B,IAAAC,oBAAkC;AAClC,IAAAC,iBAGO;AACP,IAAAC,eAA0C;AAC1C,sBAAqB;;;ACRrB,IAAAC,eAA0B;AAGnB,IAAM,oBAAN,cAAgC,uBAAU;AAAA,EACtC;AAAA,EAET,YAAYC,OAAc;AACxB;AAAA,MACE;AAAA,MACA,oCAAoCA,KAAI;AAAA,IAC1C;AACA,SAAK,OAAOA;AAAA,EACd;AACF;AAcO,SAAS,YAAY,OAA0B;AACpD,QAAM,QAAQ,CAAC,UAAU,MAAM,IAAI,MAAM,MAAM,OAAO,EAAE;AAExD,QAAM,SAAU,MAA+B;AAC/C,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,eAAW,SAAS,QAAmB;AACrC,YAAM,KACJ,MAAM,SAAS,UAAa,MAAM,SAAS,KAAK,WAAW,MAAM;AACnE,YAAM,KAAK,OAAO,EAAE,KAAK,MAAM,OAAO,EAAE;AAAA,IAC1C;AAAA,EACF;AAEA,QAAM,QAAS,MAA8B;AAC7C,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,GAAG;AAC5C,UAAM,KAAK,YAAa,MAAmB,KAAK,MAAM,CAAC,EAAE;AAAA,EAC3D;AAEA,QAAM,aAAc,MAAmC;AACvD,MAAI,OAAO,eAAe,UAAU;AAClC,UAAM,OAAQ,MAA6B;AAC3C,UAAM,YAAa,MAAkC;AACrD,UAAM,YAAY,OAAO,SAAS,WAAW,OAAO;AACpD,UAAM,QACJ,OAAO,cAAc,WAAW,gBAAgB,SAAS,OAAO;AAClE,UAAM,KAAK,KAAK,SAAS,KAAK,UAAU,GAAG,KAAK,EAAE;AAAA,EACpD,OAAO;AACL,UAAM,YAAa,MAAkC;AACrD,QAAI,OAAO,cAAc,UAAU;AACjC,YAAM,YAAa,MAAkC;AACrD,YAAM,QACJ,OAAO,cAAc,WAAW,gBAAgB,SAAS,OAAO;AAClE,YAAM,KAAK,gBAAgB,SAAS,GAAG,KAAK,EAAE;AAAA,IAChD;AAAA,EACF;AAIA,QAAM,QAAQ,MAAM;AACpB,MAAI,UAAU,UAAa,UAAU,MAAM;AACzC,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAM,OAAO,iBAAiB,yBAAY,KAAK,MAAM,IAAI,MAAM;AAC/D,UAAM,KAAK,UAAU,IAAI,KAAK,OAAO,EAAE;AAAA,EACzC;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ADvCA,IAAM,cAAc;AAEpB,SAAS,kBAA2B;AAClC,QAAM,MAAM,gBAAAC,QAAS,MAAM,CAAC,GAAG;AAAA,IAC7B,eAAe;AAAA,IACf,kBAAkB,EAAE,oBAAoB,KAAK,cAAc,GAAG;AAAA,EAChE,CAAC;AACD,SAAO;AAAA,IACL,KAAK,CAAC,UAAU,IAAI,IAAI,KAA0B;AAAA,IAClD,SAAS,CAAC,UAAU,IAAI,QAAQ,KAA0B;AAAA,IAC1D,IAAI,CAAC,YAAY;AACf,UAAI,GAAG,OAAO,CAAC,MAAM,QAAQ,OAAO,CAAC,CAAC;AACtC,UAAI,GAAG,UAAU,CAAC,MAAM,QAAQ,UAAU,CAAC,CAAC;AAC5C,UAAI,GAAG,UAAU,CAAC,MAAM,QAAQ,UAAU,CAAC,CAAC;AAAA,IAC9C;AAAA,IACA,OAAO,MAAM,IAAI,MAAM;AAAA,EACzB;AACF;AAEA,SAAS,aAAa,OAAyB;AAC7C,SAAO,iBAAiB,SAAS,MAAM,SAAS;AAClD;AAOA,eAAsB,YACpB,MACA,OAA2B,CAAC,GACb;AACf,QAAM,EAAE,KAAK,YAAY,SAAS,IAAI;AACtC,QAAM,gBAAgB,KAAK,iBAAiB;AAC5C,QAAMC,cAAa,KAAK,cAAc,eAAAC;AACtC,QAAMC,OAAM,KAAK,OAAO,aAAAC;AACxB,QAAM,aAAa,KAAK,cAAc;AAEtC,QAAM,UAAU,cAAc;AAC9B,MAAI,UAAU,oBAAI,IAAY;AAC9B,MAAI,WAAmC;AACvC,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,QAA8C;AAClD,MAAI,SAAS;AAEb,QAAM,oBAAoB,iBACtB,2BAAQ,KAAK,UAAU,QACvB,2BAAQ,KAAK,gBAAgB;AAEjC,WAAS,cAAc,SAA4B;AACjD,eAAWC,SAAQ,SAAS;AAC1B,UAAI,CAAC,QAAQ,IAAIA,KAAI,GAAG;AACtB,gBAAQ,IAAIA,KAAI;AAAA,MAClB;AAAA,IACF;AACA,eAAWA,SAAQ,SAAS;AAC1B,UAAI,CAAC,QAAQ,IAAIA,KAAI,GAAG;AACtB,gBAAQ,QAAQA,KAAI;AAAA,MACtB;AAAA,IACF;AACA,cAAU;AAAA,EACZ;AAEA,iBAAe,kBAAkB,QAAmC;AAClE,UAAM,UAAU,oBAAI,IAAY,CAAC,OAAO,UAAU,CAAC;AACnD,eAAW,CAAC,WAAW,MAAM,KAAK,OAAO,QAAQ,OAAO,OAAO,OAAO,GAAG;AACvE,YAAM,QACH,MAAM,OAAO,OAAO,aAAa;AAAA,QAChC;AAAA,QACA,KAAK,OAAO;AAAA,QACZ,QAAQ;AAAA,MACV,CAAC,KAAM,CAAC;AACV,iBAAWA,SAAQ,OAAO;AACxB,gBAAQ,QAAI,2BAAQ,OAAO,SAASA,KAAI,CAAC;AAAA,MAC3C;AAAA,IACF;AACA,kBAAc,OAAO;AAAA,EACvB;AAEA,iBAAe,QAAuB;AACpC,UAAM,MAAM;AACZ,aAAS,KAAK,gBAAgB,GAAG,OAAO;AACxC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW;AACX,QAAI;AACF,YAAM,SAAS,MAAMJ,YAAW,EAAE,KAAK,WAAW,CAAC;AACnD,YAAM,kBAAkB,MAAM;AAC9B,YAAM,SAAS,MAAME,KAAI,OAAO,QAAQ;AAAA,QACtC,QAAQ;AAAA,QACR,QAAQ,GAAG;AAAA,QACX,OAAO;AAAA,MACT,CAAC;AACD,UAAI,CAAC,GAAG,OAAO,SAAS;AACtB,iBAAS,KAAK,SAAS,OAAO,MAAM,MAAM,QAAQ;AAAA,MACpD;AAAA,IACF,SAAS,OAAO;AACd,UAAI,aAAa,KAAK,KAAK,GAAG,OAAO,SAAS;AAAA,MAE9C,WAAW,iBAAiB,wBAAW;AACrC,iBAAS,MAAM,YAAY,KAAK,CAAC;AAEjC,sBAAc,oBAAI,IAAI,CAAC,GAAG,SAAS,iBAAiB,CAAC,CAAC;AAAA,MACxD,OAAO;AACL,iBAAS,MAAM,iCAAiC;AAChD,gBAAQ,MAAM,KAAK;AAAA,MACrB;AAAA,IACF,UAAE;AACA,iBAAW;AACX,UAAI,UAAU,CAAC,QAAQ;AACrB,iBAAS;AACT,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,WAAS,UAAgB;AACvB,QAAI,UAAU;AACZ,eAAS;AACT,eAAS,MAAM;AACf;AAAA,IACF;AACA,SAAK,MAAM;AAAA,EACb;AAEA,WAAS,SAAS,OAAeE,OAAoB;AACnD,QAAI,QAAQ;AACV;AAAA,IACF;AACA,aAAS,OAAG,4BAASA,KAAI,CAAC,IAAI,UAAU,WAAW,YAAY,SAAS;AACxE,QAAI,OAAO;AACT,mBAAa,KAAK;AAAA,IACpB;AACA,YAAQ,WAAW,MAAM;AACvB,cAAQ;AACR,cAAQ;AAAA,IACV,GAAG,UAAU;AAAA,EACf;AAEA,UAAQ,GAAG,QAAQ;AAGnB,gBAAc,oBAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAC1C,QAAM,MAAM;AACZ,WAAS,KAAK,YAAY,QAAQ,IAAI,QAAQ;AAE9C,QAAM,IAAI,QAAc,CAAC,mBAAmB;AAC1C,UAAM,WAAW,MAAM;AACrB,eAAS;AACT,UAAI,OAAO;AACT,qBAAa,KAAK;AAAA,MACpB;AACA,gBAAU,MAAM;AAChB,cAAQ,IAAI,UAAU,QAAQ;AAC9B,cAAQ,IAAI,WAAW,QAAQ;AAC/B,WAAK,QAAQ,MAAM,EAAE,QAAQ,MAAM,eAAe,CAAC;AAAA,IACrD;AACA,YAAQ,GAAG,UAAU,QAAQ;AAC7B,YAAQ,GAAG,WAAW,QAAQ;AAAA,EAChC,CAAC;AACH;;;AD1KO,SAAS,iBACd,QACA,QACQ;AACR,SAAO,OAAO,SAAS,YAClB,OAAO,eAAe,OAAO,UAC7B,OAAO,OAAO,OAAO;AAC5B;AAOA,eAAsB,WACpB,MAC2B;AAC3B,QAAM,SAAqB,UAAM,2BAAW;AAAA,IAC1C,KAAK,KAAK;AAAA,IACV,YAAY,KAAK;AAAA,EACnB,CAAC;AACD,QAAM,SAAS,UAAM,kBAAI,OAAO,QAAQ;AAAA,IACtC,QAAQ,KAAK;AAAA,IACb,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,EACf,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,OAAO;AAAA,IACf,YAAY,OAAO;AAAA,IACnB,SAAS,OAAO;AAAA,EAClB;AACF;AAEO,IAAM,sBAAkB,6BAAc;AAAA,EAC3C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,GAAG;AAAA,IACH,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,WAAW;AAAA,MACT,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,WAAW,IAAI,gBAAgB,EAAE,OAAO,QAAQ,KAAK,KAAK,EAAE,CAAC;AACnE,UAAM,MAAM,QAAQ,IAAI;AACxB,UAAM,aAAa,KAAK,UAAU;AAElC,QAAI,KAAK,OAAO;AACd,YAAM,YAAY,EAAE,KAAK,YAAY,SAAS,CAAC;AAC/C;AAAA,IACF;AAEA,UAAM,SAAS,QAAQ,KAAK,SAAS,CAAC;AACtC,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,WAAW;AAAA,MAC1C;AAAA,MACA;AAAA,MACA,OAAO,CAAC;AAAA,MACR;AAAA,IACF,CAAC;AAED,QAAI,QAAQ;AACV,eAAS,KAAK,YAAY,OAAO,MAAM,MAAM,yBAAyB;AACtE;AAAA,IACF;AAEA,UAAM,OAAO,OAAO,QACjB,IAAI,CAAC,eAAW,4BAAS,KAAK,iBAAiB,QAAQ,MAAM,CAAC,CAAC,EAC/D,KAAK,IAAI;AACZ,aAAS,KAAK,SAAS,OAAO,MAAM,MAAM,aAAa,IAAI,EAAE;AAAA,EAC/D;AACF,CAAC;;;AGpGD,IAAAC,kBAAyC;AACzC,IAAAC,mBAAiC;AACjC,IAAAC,oBAA2C;AAC3C,IAAAC,iBAA0D;AAC1D,IAAAC,gBAA8B;AAW9B,SAAS,eAAe,UAA2B;AACjD,MAAI,UAAM,2BAAQ,QAAQ;AAC1B,SAAO,MAAM;AACX,UAAM,cAAU,2BAAQ,KAAK,cAAc;AAC3C,YAAI,4BAAW,OAAO,GAAG;AACvB,cAAI,gCAAW,2BAAQ,KAAK,qBAAqB,CAAC,GAAG;AACnD,eAAO;AAAA,MACT;AACA,UAAI;AACF,cAAM,MAAM,KAAK,UAAM,8BAAa,SAAS,MAAM,CAAC;AAGpD,cAAM,KAAK,IAAI;AACf,YACE,MAAM,QAAQ,EAAE,KACf,OAAO,OAAO,YACb,OAAO,QACP,MAAM,QAAS,GAA8B,QAAQ,GACvD;AACA,iBAAO;AAAA,QACT;AAAA,MACF,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT;AACA,UAAM,aAAS,2BAAQ,GAAG;AAC1B,QAAI,WAAW,KAAK;AAClB,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEO,IAAM,kBAAc,6BAAc;AAAA,EACvC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,GAAG;AAAA,IACH,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aACE;AAAA,MACF,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,WAAW,IAAI,gBAAgB,EAAE,OAAO,QAAQ,KAAK,KAAK,EAAE,CAAC;AACnE,UAAM,MAAM,QAAQ,IAAI;AAExB,UAAM,SAAS,KAAK,aAChB,2BAAQ,KAAK,KAAK,MAAM,QACxB,2BAAQ,KAAK,gBAAgB;AAEjC,YAAI,4BAAW,MAAM,KAAK,CAAC,KAAK,OAAO;AACrC,YAAM,IAAI,kBAAkB,MAAM;AAAA,IACpC;AAIA,UAAM,WACJ,OAAO,KAAK,aAAa,YAAY,KAAK,WAAW,eAAe,GAAG;AAEzE,cAAM,4BAAM,2BAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,cAAM;AAAA,MACJ;AAAA,MACA,WAAW,0CAA2B;AAAA,MACtC;AAAA,IACF;AAEA,UAAM,WAAO,4BAAS,KAAK,MAAM,KAAK;AACtC,aAAS;AAAA,MACP,WAAW,WAAW,IAAI,uBAAuB,WAAW,IAAI;AAAA,IAClE;AAAA,EACF;AACF,CAAC;;;AClGD,IAAAC,kBAAyC;AACzC,yBAA8B;AAC9B,IAAAC,oBAAiC;AACjC,IAAAC,gBAA8B;;;ACH9B,IAAAC,kBAAuD;AACvD,qBAAwB;AACxB,IAAAC,oBAA8B;AAE9B,IAAM,eAAe;AACrB,IAAM,SAAS,IAAI,KAAK,KAAK;AAOtB,SAAS,mBAA2B;AACzC,QAAM,OAAO,QAAQ,IAAI,sBAAkB,4BAAK,wBAAQ,GAAG,QAAQ;AACnE,aAAO,wBAAK,MAAM,QAAQ,oBAAoB;AAChD;AAEO,SAAS,YAA2C;AACzD,MAAI;AACF,UAAM,UAAM,8BAAa,iBAAiB,GAAG,MAAM;AACnD,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QACE,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,kBAAkB,UAChC;AACA,aAAO;AAAA,QACL,WAAW,OAAO;AAAA,QAClB,eAAe,OAAO;AAAA,MACxB;AAAA,IACF;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,WAAW,OAAgC;AACzD,QAAMC,QAAO,iBAAiB;AAC9B,qCAAU,2BAAQA,KAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,qCAAcA,OAAM,KAAK,UAAU,KAAK,CAAC;AAC3C;AAEA,eAAsB,qBACpB,QACiB;AACjB,QAAM,WAAW,MAAM,MAAM,cAAc,EAAE,OAAO,CAAC;AACrD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,uCAAuC,SAAS,MAAM,EAAE;AAAA,EAC1E;AACA,QAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,MAAI,OAAO,KAAK,YAAY,UAAU;AACpC,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACA,SAAO,KAAK;AACd;AAOO,SAAS,gBAAgB,GAAW,GAAuB;AAChE,QAAM,CAAC,QAAQ,QAAQ,QAAQ,IAAI,IAAI,aAAa,CAAC;AACrD,QAAM,CAAC,QAAQ,QAAQ,QAAQ,IAAI,IAAI,aAAa,CAAC;AAErD,MAAI,WAAW,QAAQ;AACrB,WAAO,SAAS,SAAS,KAAK;AAAA,EAChC;AACA,MAAI,WAAW,QAAQ;AACrB,WAAO,SAAS,SAAS,KAAK;AAAA,EAChC;AACA,MAAI,WAAW,QAAQ;AACrB,WAAO,SAAS,SAAS,KAAK;AAAA,EAChC;AAEA,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,EACT;AACA,MAAI,SAAS,QAAW;AACtB,WAAO;AAAA,EACT;AACA,MAAI,SAAS,QAAW;AACtB,WAAO;AAAA,EACT;AACA,SAAO,OAAO,OAAO,KAAK;AAC5B;AAEA,SAAS,aACP,SAC6D;AAC7D,QAAM,CAAC,OAAO,IAAI,GAAG,IAAI,IAAI,QAAQ,MAAM,GAAG;AAC9C,QAAM,CAAC,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC,IAAI,KACvC,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,OAAO,SAAS,GAAG,EAAE,KAAK,CAAC;AACzC,SAAO,CAAC,OAAO,OAAO,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK,GAAG,IAAI,MAAS;AAC3E;AAOO,SAAS,eAAe,gBAA8C;AAC3E,QAAM,QAAQ,UAAU;AACxB,QAAM,SAA+B,CAAC;AAEtC,MAAI,SAAS,gBAAgB,MAAM,eAAe,cAAc,IAAI,GAAG;AACrE,WAAO,SAAS,gDAAgD,cAAc,WAAM,MAAM,aAAa;AAAA,EACzG;AAEA,QAAM,UAAU,UAAU,UAAa,KAAK,IAAI,IAAI,MAAM,YAAY;AACtE,MAAI,SAAS;AACX,WAAO,UAAU,OAAO,WAAwB;AAC9C,YAAM,gBAAgB,MAAM,qBAAqB,MAAM;AACvD,iBAAW,EAAE,WAAW,KAAK,IAAI,GAAG,cAAc,CAAC;AAAA,IACrD;AAAA,EACF;AAEA,SAAO;AACT;;;ADzGA,SAAS,uBAAuB,KAAiC;AAC/D,MAAI,UAAM,2BAAQ,GAAG;AACrB,SAAO,MAAM;AACX,UAAM,gBAAY,2BAAQ,KAAK,cAAc;AAC7C,YAAI,4BAAW,SAAS,GAAG;AACzB,aAAO;AAAA,IACT;AACA,YAAI,gCAAW,2BAAQ,KAAK,MAAM,CAAC,GAAG;AACpC,aAAO;AAAA,IACT;AACA,UAAM,aAAS,2BAAQ,GAAG;AAC1B,QAAI,WAAW,KAAK;AAClB,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEA,SAAS,4BAA4B,iBAAmC;AACtE,QAAM,MAAM,KAAK,UAAM,8BAAa,iBAAiB,MAAM,CAAC;AAI5D,QAAM,QAAQ,oBAAI,IAAI;AAAA,IACpB,GAAG,OAAO,KAAK,IAAI,gBAAgB,CAAC,CAAC;AAAA,IACrC,GAAG,OAAO,KAAK,IAAI,mBAAmB,CAAC,CAAC;AAAA,EAC1C,CAAC;AACD,SAAO,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,SAAS,KAAK,WAAW,YAAY,CAAC,EAAE,KAAK;AACzE;AAEA,SAAS,wBACP,iBACA,MACoB;AACpB,MAAI;AACF,UAAMC,eAAU,kCAAc,eAAe;AAC7C,UAAM,eAAeA,SAAQ,QAAQ,GAAG,IAAI,eAAe;AAC3D,UAAM,MAAM,KAAK,UAAM,8BAAa,cAAc,MAAM,CAAC;AAGzD,WAAO,IAAI;AAAA,EACb,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,mBAAmB,MAA2C;AAC3E,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,8BAA8B,IAAI,SAAS;AACxE,QAAI,CAAC,SAAS,IAAI;AAChB,aAAO;AAAA,IACT;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU;AAAA,EAC3D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,SAAiC;AACpD,QAAM,OAAO,QAAQ,IAAI,CAAC,WAAW;AAAA,IACnC,MAAM,MAAM;AAAA,IACZ,WAAW,MAAM,aAAa;AAAA,IAC9B,QAAQ,MAAM,UAAU;AAAA,IACxB,QACE,MAAM,cAAc,UAAa,MAAM,WAAW,SAC9C,YACA,gBAAgB,MAAM,QAAQ,MAAM,SAAS,IAAI,IAC/C,aACA;AAAA,EACV,EAAE;AAEF,QAAM,SAAS;AAAA,IACb,MAAM,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AAAA,IACnD,WAAW,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,UAAU,MAAM,CAAC;AAAA,IAC7D,QAAQ,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,MAAM,CAAC;AAAA,EACzD;AAEA,QAAM,SAAS,KAAK,UAAU,OAAO,OAAO,IAAI,CAAC,KAAK,YAAY,OAAO,OAAO,SAAS,CAAC,KAAK,SAAS,OAAO,OAAO,MAAM,CAAC;AAC7H,QAAM,QAAQ,KAAK;AAAA,IACjB,CAAC,MACC,KAAK,EAAE,KAAK,OAAO,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,OAAO,OAAO,SAAS,CAAC,KAAK,EAAE,OAAO,OAAO,OAAO,MAAM,CAAC,KAAK,EAAE,MAAM;AAAA,EAC5H;AAEA,SAAO,CAAC,QAAQ,GAAG,KAAK,EAAE,KAAK,IAAI;AACrC;AAEO,IAAM,sBAAkB,6BAAc;AAAA,EAC3C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM,EAAE,GAAG,WAAW;AAAA,EACtB,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,WAAW,IAAI,gBAAgB,EAAE,OAAO,QAAQ,KAAK,KAAK,EAAE,CAAC;AACnE,UAAM,MAAM,QAAQ,IAAI;AAExB,UAAM,kBAAkB,uBAAuB,GAAG;AAClD,QAAI,CAAC,iBAAiB;AACpB,eAAS,MAAM,yDAAyD;AACxE,cAAQ,aAAa;AACrB;AAAA,IACF;AAEA,UAAM,QAAQ,4BAA4B,eAAe;AACzD,QAAI,MAAM,WAAW,GAAG;AACtB,eAAS,KAAK,iCAAiC;AAC/C,cAAQ,aAAa;AACrB;AAAA,IACF;AAEA,UAAM,UAA0B,MAAM,QAAQ;AAAA,MAC5C,MAAM,IAAI,OAAO,UAAU;AAAA,QACzB;AAAA,QACA,WAAW,wBAAwB,iBAAiB,IAAI;AAAA,QACxD,QAAQ,MAAM,mBAAmB,IAAI;AAAA,MACvC,EAAE;AAAA,IACJ;AAEA,aAAS,KAAK;AAAA,EAAkB,YAAY,OAAO,CAAC,EAAE;AACtD,YAAQ,aAAa;AAAA,EACvB;AACF,CAAC;;;AE5ID,IAAAC,gBAA8B;AAKvB,IAAM,sBAAkB,6BAAc;AAAA,EAC3C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM,EAAE,GAAG,WAAW;AAAA,EACtB,KAAK,OAAO,EAAE,KAAK,MAAM;AACvB,UAAM,WAAW,IAAI,gBAAgB,EAAE,OAAO,QAAQ,KAAK,KAAK,EAAE,CAAC;AACnE,UAAM,WAAW;AAAA,MACf,KAAK,QAAQ,IAAI;AAAA,MACjB,YAAY,KAAK,UAAU;AAAA,MAC3B,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AACD,aAAS,KAAK,6BAA6B;AAAA,EAC7C;AACF,CAAC;;;AXPD,IAAM,UACJ,OAAuC,UAAmB;AAE5D,IAAM,cAAc;AAAA,EAClB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AACZ;AAEA,IAAM,WAAO,6BAAc;AAAA,EACzB,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAAA,EACA;AACF,CAAC;AAED,eAAsB,OACpB,MACA,UAAuC,CAAC,GACzB;AACf,QAAM,WAAW,IAAI,gBAAgB;AAAA,IACnC,OAAO,KAAK,SAAS,SAAS,KAAK,QAAQ,QAAQ,IAAI,UAAU;AAAA,EACnE,CAAC;AAED,MAAI,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,IAAI,GAAG;AACrD,YAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AACnC,YAAQ,aAAa;AACrB;AAAA,EACF;AAEA,MAAI,KAAK,WAAW,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI,GAAG;AACvE,UAAM,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAC/C,UAAM,QAAQ,QAAQ,UAAa,OAAO;AAC1C,UAAM,MACJ,QAAQ,YAAY,GAA+B,IAAI;AAEzD,YAAQ,OAAO;AAAA,MACb,GAAG,UAAM,2BAAY,KAAK,QAAS,OAAsB,MAAS,CAAC;AAAA;AAAA,IACrE;AACA,YAAQ,aAAa;AACrB;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,QAAQ,IAAI,eAAe,QAAQ,kBAAkB,OAAO;AAC5E,MAAI,QAAQ;AACV,aAAS,KAAK,MAAM;AAAA,EACtB;AAEA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,iBAAiB,UAAU,WAAW,MAAM,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AAElE,MAAI;AACF,cAAM,0BAAW,MAAM,EAAE,SAAS,KAAK,CAAC;AACxC,YAAQ,aAAa;AAAA,EACvB,SAAS,OAAO;AACd,QAAI,iBAAiB,wBAAW;AAC9B,eAAS,MAAM,YAAY,KAAK,CAAC;AACjC,cAAQ,WAAW;AAAA,IACrB,WAAW,iBAAiB,SAAS,MAAM,SAAS,YAAY;AAE9D,eAAS,MAAM,MAAM,OAAO;AAC5B,cAAQ,WAAW;AAAA,IACrB,OAAO;AACL,eAAS,MAAM,iCAAiC;AAChD,cAAQ,MAAM,KAAK;AACnB,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,UAAE;AACA,eAAW,MAAM;AACjB,UAAM;AAAA,EACR;AACF;","names":["import_core","import_citty","import_node_fs","import_node_path","import_core","path","import_node_path","import_config","import_core","import_citty","import_node_path","import_config","import_core","import_core","path","chokidar","loadConfig","realLoadConfig","run","realRun","path","import_node_fs","import_promises","import_node_path","import_config","import_citty","import_node_fs","import_node_path","import_citty","import_node_fs","import_node_path","path","require","import_citty"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/cli.ts","../src/commands/check.ts","../src/args.ts","../src/diff.ts","../src/reporter.ts","../src/commands/generate.ts","../src/watch.ts","../src/errors.ts","../src/commands/init.ts","../src/commands/outdated.ts","../src/version-check.ts","../src/commands/validate.ts"],"sourcesContent":["/**\n * `@kurotako/cli` — the `tako` binary. This barrel is the programmatic surface:\n * `runCli()` plus the reporter / error helpers, for embedders and tests.\n */\nexport { runCli } from './cli.js';\nexport {\n type ComparePlanToDiskArgs,\n comparePlanToDisk,\n type DriftEntry,\n type DriftKind,\n} from './diff.js';\nexport { ConfigExistsError, renderError } from './errors.js';\nexport { ConsoleReporter, type ConsoleReporterOptions } from './reporter.js';\nexport {\n type CheckForUpdateResult,\n checkForUpdate,\n compareVersions,\n getCacheFilePath,\n readCache,\n refreshLatestVersion,\n type VersionCacheEntry,\n writeCache,\n} from './version-check.js';\n","/**\n * `runCli()` — build the citty command tree, dispatch, map every `TakoError` to\n * a formatted message + exit 1. `--version` / `--help` are handled here (citty's\n * own handling lives in `runMain`, which hard-exits — not what a testable\n * `runCli` wants).\n *\n * `backlog/features/cli/technical.md` §Command surface, §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\nimport { type CommandDef, defineCommand, renderUsage, runCommand } from 'citty';\nimport { checkCommand } from './commands/check.js';\nimport { generateCommand } from './commands/generate.js';\nimport { initCommand } from './commands/init.js';\nimport { outdatedCommand } from './commands/outdated.js';\nimport { validateCommand } from './commands/validate.js';\nimport { renderError } from './errors.js';\nimport { ConsoleReporter } from './reporter.js';\nimport { checkForUpdate } from './version-check.js';\n\ndeclare const __TAKO_VERSION__: string;\nconst VERSION =\n typeof __TAKO_VERSION__ === 'string' ? __TAKO_VERSION__ : '0.0.0-dev';\n\nconst subCommands = {\n init: initCommand,\n generate: generateCommand,\n validate: validateCommand,\n check: checkCommand,\n outdated: outdatedCommand,\n};\n\nconst main = defineCommand({\n meta: {\n name: 'tako',\n version: VERSION,\n description: 'synchronise TypeScript schemas from data model to forms',\n },\n subCommands,\n});\n\nexport async function runCli(\n argv: string[],\n options: { currentVersion?: string } = {},\n): Promise<void> {\n const reporter = new ConsoleReporter({\n debug: argv.includes('--debug') || Boolean(process.env.TAKO_DEBUG),\n });\n\n if (argv.includes('--version') || argv.includes('-v')) {\n process.stdout.write(`${VERSION}\\n`);\n process.exitCode ??= 0;\n return;\n }\n\n if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {\n const sub = argv.find((a) => !a.startsWith('-'));\n const isSub = sub !== undefined && sub in subCommands;\n const cmd = (\n isSub ? subCommands[sub as keyof typeof subCommands] : main\n ) as CommandDef;\n process.stdout.write(\n `${await renderUsage(cmd, isSub ? (main as CommandDef) : undefined)}\\n`,\n );\n process.exitCode ??= 0;\n return;\n }\n\n const { notice, refresh } = checkForUpdate(options.currentVersion ?? VERSION);\n if (notice) {\n reporter.info(notice);\n }\n\n const controller = new AbortController();\n const refreshPromise = refresh?.(controller.signal).catch(() => {});\n\n try {\n await runCommand(main, { rawArgs: argv });\n process.exitCode ??= 0;\n } catch (error) {\n if (error instanceof TakoError) {\n reporter.error(renderError(error));\n process.exitCode = 1;\n } else if (error instanceof Error && error.name === 'CLIError') {\n // citty usage error (unknown command, missing argument, …).\n reporter.error(error.message);\n process.exitCode = 1;\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n process.exitCode = 1;\n }\n } finally {\n controller.abort();\n await refreshPromise;\n }\n}\n","/**\n * `tako check` — drift guard. Runs the pipeline in plan mode (no disk writes,\n * no `afterEmit`), then compares the planned tree against what is on disk.\n * Exit 0 when they match, exit 1 on any drift or any `TakoError` (the latter\n * via the top-level handler in `cli.ts`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §Command surface.\n */\nimport { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport { loadConfig } from '@kurotako/config';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport {\n comparePlanToDisk,\n type DriftEntry,\n ignoreBuildArtifacts,\n markedPackageDirs,\n} from '../diff.js';\nimport { ConsoleReporter } from '../reporter.js';\n\nexport const checkCommand = defineCommand({\n meta: {\n name: 'check',\n description:\n 'check the generated output on disk matches a fresh generate (drift guard)',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const { config } = await loadConfig({\n cwd,\n configPath: args.config || undefined,\n });\n const { plan = [] } = await run(config, { logger: reporter, plan: true });\n\n const roots: string[] = [];\n const ignores: ((absPath: string) => boolean)[] = [];\n\n for (const output of config.outputs) {\n if (output.mode === 'package') {\n ignores.push(ignoreBuildArtifacts);\n if (output.packagesDir) {\n roots.push(...(await markedPackageDirs(output.packagesDir)));\n }\n } else {\n const dir = output.dir;\n if (!dir) {\n continue;\n }\n if (!existsSync(dir)) {\n reporter.info(\n `output directory ${relative(config.rootDir, dir)} does not exist — run tako generate`,\n );\n process.exitCode = 1;\n return;\n }\n roots.push(dir);\n }\n }\n\n const ignore = (absPath: string): boolean =>\n ignores.some((fn) => fn(absPath));\n\n const drift = await comparePlanToDisk({\n plan,\n roots,\n ignore,\n rootDir: config.rootDir,\n });\n\n if (drift.length === 0) {\n reporter.info('output is in sync');\n process.exitCode ??= 0;\n return;\n }\n\n reporter.error(formatDrift(drift));\n process.exitCode = 1;\n },\n});\n\nfunction formatDrift(drift: DriftEntry[]): string {\n const width = Math.max(...drift.map((entry) => entry.kind.length));\n const lines = drift.map(\n (entry) => ` ${entry.kind.padEnd(width)} ${entry.path}`,\n );\n return [\n 'drift detected',\n '',\n ...lines,\n '',\n `${drift.length} files differ from a fresh generate. Run \\`tako generate\\`.`,\n ].join('\\n');\n}\n","/**\n * `sharedArgs` — the options every sub-command carries. citty has no\n * first-class global-option slot, so this object is spread into each command's\n * `args` (`backlog/features/cli/technical.md` §Global option).\n */\nimport type { ArgsDef } from 'citty';\n\nexport const sharedArgs = {\n config: {\n type: 'string',\n description: 'path to the tako config file (default: ./tako.config.ts)',\n },\n /** Hidden: not advertised, kept minimal. Enables `debug` reporter output. */\n debug: {\n type: 'boolean',\n default: false,\n },\n} as const satisfies ArgsDef;\n","/**\n * `comparePlanToDisk` — the in-memory comparison behind `tako check`. Takes the\n * `PlannedFile[]` a fresh `generate` would write (from `run({ plan: true })`)\n * and reports every way the tree on disk diverges from it: a planned file that\n * is absent (`missing`) or whose bytes differ (`modified`), and any file under\n * the scanned roots that no planned file claims (`orphan`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §The comparison.\n */\nimport { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PlannedFile } from '@kurotako/core';\n\nexport type DriftKind = 'modified' | 'missing' | 'orphan';\n\nexport interface DriftEntry {\n kind: DriftKind;\n /** Relative to `rootDir`, POSIX separators; a collapsed dir ends with `/`. */\n path: string;\n}\n\nexport interface ComparePlanToDiskArgs {\n plan: PlannedFile[];\n /** Directories walked for orphans (absolute). */\n roots: string[];\n /** Return `true` to exclude an absolute path from the orphan scan. */\n ignore: (absPath: string) => boolean;\n /** Anchor for the reported relative paths (the config-file directory). */\n rootDir: string;\n}\n\nfunction toPosix(rootDir: string, absPath: string): string {\n return path.relative(rootDir, absPath).split(path.sep).join('/');\n}\n\nexport async function comparePlanToDisk(\n args: ComparePlanToDiskArgs,\n): Promise<DriftEntry[]> {\n const { plan, roots, ignore, rootDir } = args;\n const plannedByPath = new Map(plan.map((f) => [path.resolve(f.path), f]));\n const entries: DriftEntry[] = [];\n\n // 1. Expected vs disk.\n for (const [absPath, file] of plannedByPath) {\n if (!existsSync(absPath)) {\n entries.push({ kind: 'missing', path: toPosix(rootDir, absPath) });\n continue;\n }\n const onDisk = await readFile(absPath, 'utf8');\n if (onDisk !== file.content) {\n entries.push({ kind: 'modified', path: toPosix(rootDir, absPath) });\n }\n }\n\n // 2. Orphan scan — a planned file lives under `dir` iff any planned absolute\n // path is `dir` itself or sits below it.\n const plannedPaths = [...plannedByPath.keys()];\n const hasPlannedUnder = (dir: string): boolean => {\n const prefix = `${dir}${path.sep}`;\n return plannedPaths.some((p) => p === dir || p.startsWith(prefix));\n };\n\n const seenRoots = new Set<string>();\n for (const root of roots) {\n const absRoot = path.resolve(root);\n if (seenRoots.has(absRoot) || !existsSync(absRoot)) {\n continue;\n }\n seenRoots.add(absRoot);\n await scan(absRoot);\n }\n\n async function scan(dir: string): Promise<void> {\n // A directory with no planned file underneath collapses to a single entry —\n // unless it holds nothing but ignored files (e.g. only `dist/`).\n if (!hasPlannedUnder(dir)) {\n if (await hasNonIgnoredFile(dir)) {\n entries.push({ kind: 'orphan', path: `${toPosix(rootDir, dir)}/` });\n }\n return;\n }\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isDirectory()) {\n await scan(abs);\n } else if (dirent.isFile() && !plannedByPath.has(abs)) {\n entries.push({ kind: 'orphan', path: toPosix(rootDir, abs) });\n }\n }\n }\n\n async function hasNonIgnoredFile(dir: string): Promise<boolean> {\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isFile()) {\n return true;\n }\n if (dirent.isDirectory() && (await hasNonIgnoredFile(abs))) {\n return true;\n }\n }\n return false;\n }\n\n entries.sort((a, b) =>\n a.path < b.path\n ? -1\n : a.path > b.path\n ? 1\n : a.kind < b.kind\n ? -1\n : a.kind > b.kind\n ? 1\n : 0,\n );\n return entries;\n}\n\n/** Rejects `dist/` and `node_modules/` anywhere in the path (mode B). */\nexport function ignoreBuildArtifacts(absPath: string): boolean {\n return /(^|[/\\\\])(dist|node_modules)([/\\\\]|$)/.test(absPath);\n}\n\n/**\n * Whether `<packagesDir>/<name>` looks like a directory `tako` generated: a\n * `package.json` whose `\"//\"` marker starts with `Generated by tako`.\n */\nexport async function hasGeneratedMarker(pkgDir: string): Promise<boolean> {\n try {\n const pkg = JSON.parse(\n await readFile(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\n/** Every immediate subdirectory of `packagesDir` carrying the tako marker. */\nexport async function markedPackageDirs(\n packagesDir: string,\n): Promise<string[]> {\n if (!existsSync(packagesDir)) {\n return [];\n }\n const out: string[] = [];\n for (const dirent of await readdir(packagesDir, { withFileTypes: true })) {\n if (!dirent.isDirectory()) {\n continue;\n }\n const abs = path.join(packagesDir, dirent.name);\n if (await hasGeneratedMarker(abs)) {\n out.push(abs);\n }\n }\n return out.sort();\n}\n","/**\n * `ConsoleReporter` — the `@kurotako/core` `Logger` the CLI injects into\n * `loadConfig()` / `run()`, plus the per-phase / summary output.\n *\n * Contract (`backlog/features/cli/technical.md` §Reporter):\n * - human output goes to **stderr**, `stdout` stays clean;\n * - `info` / `warn` / `error` shown by default; `debug` only with `--debug` /\n * `TAKO_DEBUG` (a hidden flag, not advertised);\n * - the human-readable message is always shown; the structured `meta` object is\n * printed only with `--debug` (a custom `Logger` still receives it in full),\n * so default output stays prose, not `key=value` noise;\n * - `tako ` prefix, level-coloured; colour auto-off when the stream is not a TTY\n * or `NO_COLOR` is set;\n * - `child(tag)` returns a `Logger` tagging every `meta` with `{ scope: tag }`.\n */\nimport { childLogger, type Logger } from '@kurotako/core';\n\ntype Level = 'debug' | 'info' | 'warn' | 'error';\n\n/** The slice of a writable stream the reporter needs (keeps tests trivial). */\nexport interface WriteStream {\n write(chunk: string): unknown;\n isTTY?: boolean;\n}\n\nexport interface ConsoleReporterOptions {\n /** Show `debug` output. Default: `false` unless `TAKO_DEBUG` is set. */\n debug?: boolean;\n /** Sink for human output. Default: `process.stderr`. */\n stream?: WriteStream;\n /** Force colour on/off. Default: auto (TTY and no `NO_COLOR`). */\n color?: boolean;\n}\n\nconst ESC = String.fromCharCode(27);\nconst ANSI: Record<Level, string> = {\n debug: `${ESC}[2m`, // dim\n info: `${ESC}[36m`, // cyan\n warn: `${ESC}[33m`, // yellow\n error: `${ESC}[31m`, // red\n};\nconst ANSI_RESET = `${ESC}[0m`;\n\nexport class ConsoleReporter implements Logger {\n private readonly stream: WriteStream;\n private readonly showDebug: boolean;\n private readonly color: boolean;\n\n constructor(options: ConsoleReporterOptions = {}) {\n this.stream = options.stream ?? process.stderr;\n this.showDebug = options.debug ?? Boolean(process.env.TAKO_DEBUG);\n this.color =\n options.color ??\n (Boolean(this.stream.isTTY) && process.env.NO_COLOR === undefined);\n }\n\n debug(msg: string, meta?: unknown): void {\n if (this.showDebug) {\n this.write('debug', msg, meta);\n }\n }\n\n info(msg: string, meta?: unknown): void {\n this.write('info', msg, meta);\n }\n\n warn(msg: string, meta?: unknown): void {\n this.write('warn', msg, meta);\n }\n\n error(msg: string, meta?: unknown): void {\n this.write('error', msg, meta);\n }\n\n /** A child `Logger` whose calls carry `{ scope: tag }` in `meta`. */\n child(tag: string): Logger {\n return childLogger(this, { scope: tag });\n }\n\n private write(level: Level, msg: string, meta?: unknown): void {\n const prefix = this.color ? `${ANSI[level]}tako${ANSI_RESET}` : 'tako';\n const detail =\n meta === undefined || !this.showDebug ? '' : ` ${formatMeta(meta)}`;\n this.stream.write(`${prefix} ${msg}${detail}\\n`);\n }\n}\n\nfunction formatMeta(meta: unknown): string {\n if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {\n return Object.entries(meta as Record<string, unknown>)\n .map(([k, v]) => `${k}=${stringify(v)}`)\n .join(' ');\n }\n return stringify(meta);\n}\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n","/**\n * `tako generate` — `loadConfig()` then `run()`. `--dry-run` runs everything but\n * skips the Writer; `--watch` hands off to the chokidar loop\n * (`backlog/features/cli/technical.md` §`tako generate`).\n */\nimport { relative } from 'node:path';\nimport { type LoadResult, loadConfig } from '@kurotako/config';\nimport type { OutputConfig, ResolvedConfig, RunResult } from '@kurotako/core';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { watchAndRun } from '../watch.js';\n\nexport interface LoadAndRunOptions {\n cwd: string;\n configPath?: string;\n write: boolean;\n signal?: AbortSignal;\n reporter: ConsoleReporter;\n}\n\nexport interface LoadAndRunResult {\n result: RunResult;\n config: ResolvedConfig;\n configFile: string;\n rootDir: string;\n}\n\n/** The directory named in the `wrote N files -> …` summary line, for one output. */\nexport function outputSummaryDir(\n output: OutputConfig,\n config: ResolvedConfig,\n): string {\n return output.mode === 'package'\n ? (output.packagesDir ?? config.rootDir)\n : (output.dir ?? config.rootDir);\n}\n\n/**\n * The shared body of `generate`, `validate` and each watch cycle: resolve +\n * load the config, then run the pipeline. `write: false` also skips the\n * `afterEmit` hook (`@kurotako/core` `run()`).\n */\nexport async function loadAndRun(\n opts: LoadAndRunOptions,\n): Promise<LoadAndRunResult> {\n const loaded: LoadResult = await loadConfig({\n cwd: opts.cwd,\n configPath: opts.configPath,\n });\n const result = await run(loaded.config, {\n logger: opts.reporter,\n write: opts.write,\n signal: opts.signal,\n });\n return {\n result,\n config: loaded.config,\n configFile: loaded.configFile,\n rootDir: loaded.rootDir,\n };\n}\n\nexport const generateCommand = defineCommand({\n meta: {\n name: 'generate',\n description: 'run the pipeline and write the generated code',\n },\n args: {\n ...sharedArgs,\n watch: {\n type: 'boolean',\n description: 'rebuild on every schema / config change',\n default: false,\n },\n 'dry-run': {\n type: 'boolean',\n description: 'run everything but write nothing',\n default: false,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n const configPath = args.config || undefined;\n\n if (args.watch) {\n await watchAndRun({ cwd, configPath, reporter });\n return;\n }\n\n const dryRun = Boolean(args['dry-run']);\n const { result, config } = await loadAndRun({\n cwd,\n configPath,\n write: !dryRun,\n reporter,\n });\n\n if (dryRun) {\n reporter.info(`dry run: ${result.files.length} files would be written`);\n return;\n }\n\n const dirs = config.outputs\n .map((output) => relative(cwd, outputSummaryDir(output, config)))\n .join(', ');\n reporter.info(`wrote ${result.files.length} files -> ${dirs}`);\n },\n});\n","/**\n * `tako generate --watch` — a chokidar loop around `loadConfig()` + `run()`.\n * Full regeneration on every change (no incremental). A 100 ms trailing\n * debounce coalesces bursts; a change mid-cycle aborts the in-flight `run()`\n * (via `RunOptions.signal`) and re-runs once it settles. `loadConfig` failures\n * are reported, not fatal — the watcher stays up on `tako.config.ts`.\n *\n * `backlog/features/cli/technical.md` §Watch mode.\n */\nimport { basename, resolve } from 'node:path';\nimport {\n type LoadResult,\n loadConfig as realLoadConfig,\n} from '@kurotako/config';\nimport { run as realRun, TakoError } from '@kurotako/core';\nimport chokidar from 'chokidar';\nimport { renderError } from './errors.js';\nimport type { ConsoleReporter } from './reporter.js';\n\n/** Minimal watcher seam so the loop is unit-testable without touching the fs. */\nexport interface Watcher {\n add(paths: string | readonly string[]): void;\n unwatch(paths: string | readonly string[]): void;\n on(handler: (event: string, path: string) => void): void;\n close(): Promise<void>;\n}\n\nexport interface WatchAndRunOptions {\n cwd: string;\n configPath?: string;\n reporter: ConsoleReporter;\n}\n\nexport interface WatchDeps {\n createWatcher: () => Watcher;\n loadConfig: typeof realLoadConfig;\n run: typeof realRun;\n debounceMs: number;\n}\n\nconst DEBOUNCE_MS = 100;\n\nfunction chokidarWatcher(): Watcher {\n const fsw = chokidar.watch([], {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 20 },\n });\n return {\n add: (paths) => fsw.add(paths as string | string[]),\n unwatch: (paths) => fsw.unwatch(paths as string | string[]),\n on: (handler) => {\n fsw.on('add', (p) => handler('add', p));\n fsw.on('change', (p) => handler('change', p));\n fsw.on('unlink', (p) => handler('unlink', p));\n },\n close: () => fsw.close(),\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError';\n}\n\n/**\n * Runs until `SIGINT` / `SIGTERM`, then closes the watcher and resolves so the\n * caller can exit 0. (The design doc types this `Promise<never>`; it resolves\n * on shutdown here purely so it stays testable.)\n */\nexport async function watchAndRun(\n opts: WatchAndRunOptions,\n deps: Partial<WatchDeps> = {},\n): Promise<void> {\n const { cwd, configPath, reporter } = opts;\n const createWatcher = deps.createWatcher ?? chokidarWatcher;\n const loadConfig = deps.loadConfig ?? realLoadConfig;\n const run = deps.run ?? realRun;\n const debounceMs = deps.debounceMs ?? DEBOUNCE_MS;\n\n const watcher = createWatcher();\n let watched = new Set<string>();\n let inFlight: AbortController | null = null;\n let queued = false;\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let reason = 'initial build';\n\n const guessedConfigFile = configPath\n ? resolve(cwd, configPath)\n : resolve(cwd, 'tako.config.ts');\n\n function applyWatchSet(desired: Set<string>): void {\n for (const path of desired) {\n if (!watched.has(path)) {\n watcher.add(path);\n }\n }\n for (const path of watched) {\n if (!desired.has(path)) {\n watcher.unwatch(path);\n }\n }\n watched = desired;\n }\n\n async function reconcileWatchSet(loaded: LoadResult): Promise<void> {\n const desired = new Set<string>([loaded.configFile]);\n for (const [namespace, source] of Object.entries(loaded.config.sources)) {\n const paths =\n (await source.parser.watchPaths?.({\n namespace,\n cwd: loaded.rootDir,\n logger: reporter,\n })) ?? [];\n for (const path of paths) {\n desired.add(resolve(loaded.rootDir, path));\n }\n }\n applyWatchSet(desired);\n }\n\n async function cycle(): Promise<void> {\n const why = reason;\n reporter.info(`--- rebuild (${why}) ---`);\n const ac = new AbortController();\n inFlight = ac;\n try {\n const loaded = await loadConfig({ cwd, configPath });\n await reconcileWatchSet(loaded);\n const result = await run(loaded.config, {\n logger: reporter,\n signal: ac.signal,\n write: true,\n });\n if (!ac.signal.aborted) {\n reporter.info(`wrote ${result.files.length} files`);\n }\n } catch (error) {\n if (isAbortError(error) || ac.signal.aborted) {\n // Superseded by a newer cycle — swallow.\n } else if (error instanceof TakoError) {\n reporter.error(renderError(error));\n // Keep watching at least the config file so a fix is picked up.\n applyWatchSet(new Set([...watched, guessedConfigFile]));\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n }\n } finally {\n inFlight = null;\n if (queued && !closed) {\n queued = false;\n await cycle();\n }\n }\n }\n\n function trigger(): void {\n if (inFlight) {\n queued = true;\n inFlight.abort();\n return;\n }\n void cycle();\n }\n\n function schedule(event: string, path: string): void {\n if (closed) {\n return;\n }\n reason = `${basename(path)} ${event === 'unlink' ? 'removed' : 'changed'}`;\n if (timer) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = null;\n trigger();\n }, debounceMs);\n }\n\n watcher.on(schedule);\n\n // Initial cycle: a failure is reported inside `cycle()`, never fatal.\n applyWatchSet(new Set([guessedConfigFile]));\n await cycle();\n reporter.info(`watching ${watched.size} paths`);\n\n await new Promise<void>((resolvePromise) => {\n const shutdown = () => {\n closed = true;\n if (timer) {\n clearTimeout(timer);\n }\n inFlight?.abort();\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n void watcher.close().finally(() => resolvePromise());\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n}\n","/**\n * CLI-owned error(s) and `renderError()` — the single formatter the top-level\n * handler in `cli.ts` uses for any `TakoError` (from `@kurotako/core`,\n * `@kurotako/config`, or this package).\n *\n * `backlog/features/cli/technical.md` §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\n\n/** `tako init` refuses to overwrite an existing config unless `--force`. */\nexport class ConfigExistsError extends TakoError {\n readonly path: string;\n\n constructor(path: string) {\n super(\n 'config_exists',\n `a config file already exists at '${path}' (pass --force to overwrite)`,\n );\n this.path = path;\n }\n}\n\ninterface Issue {\n path?: string;\n message?: string;\n}\n\n/**\n * `error [<code>]: <message>` plus any carried context on its own indented\n * lines: located issues (`ConfigShapeError`, `IrValidationError`,\n * `DriverOptionsError`), the offending driver / namespace (`DriverError`,\n * `UnknownNamespaceError`), the dependency cycle path (`DependencyCycleError`),\n * and the `cause` message of a wrapped failure.\n */\nexport function renderError(error: TakoError): string {\n const lines = [`error [${error.code}]: ${error.message}`];\n\n const issues = (error as { issues?: unknown }).issues;\n if (Array.isArray(issues)) {\n for (const issue of issues as Issue[]) {\n const at =\n issue.path === undefined || issue.path === '' ? '<root>' : issue.path;\n lines.push(` - ${at}: ${issue.message}`);\n }\n }\n\n const cycle = (error as { cycle?: unknown }).cycle;\n if (Array.isArray(cycle) && cycle.length > 0) {\n lines.push(` cycle: ${(cycle as string[]).join(' -> ')}`);\n }\n\n const driverName = (error as { driverName?: unknown }).driverName;\n if (typeof driverName === 'string') {\n const role = (error as { role?: unknown }).role;\n const namespace = (error as { namespace?: unknown }).namespace;\n const roleLabel = typeof role === 'string' ? role : 'driver';\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` ${roleLabel}: ${driverName}${where}`);\n } else {\n const generator = (error as { generator?: unknown }).generator;\n if (typeof generator === 'string') {\n const namespace = (error as { namespace?: unknown }).namespace;\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` generator: ${generator}${where}`);\n }\n }\n\n // Wrapped failures (`DriverError`, `HookError`, `ConfigLoadError`, …) carry the\n // real error in `cause`; core masks its type, so surface at least its message.\n const cause = error.cause;\n if (cause !== undefined && cause !== null) {\n const message = cause instanceof Error ? cause.message : String(cause);\n const code = cause instanceof TakoError ? ` [${cause.code}]` : '';\n lines.push(` cause${code}: ${message}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * `tako init` — write the commented `tako.config.ts` skeleton into the current\n * directory. No prompts, no schema auto-detection; refuses to overwrite unless\n * `--force` (`backlog/features/cli/technical.md` §`tako init`).\n *\n * `--monorepo` / `--no-monorepo` picks between `CONFIG_TEMPLATE` and\n * `CONFIG_TEMPLATE_MONOREPO`; unset, it auto-detects a workspace by walking up\n * for the nearest `package.json` (`workspaces` key, or a sibling\n * `pnpm-workspace.yaml`).\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative, resolve } from 'node:path';\nimport { CONFIG_TEMPLATE, CONFIG_TEMPLATE_MONOREPO } from '@kurotako/config';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConfigExistsError } from '../errors.js';\nimport { ConsoleReporter } from '../reporter.js';\n\n/**\n * Walk up from `startDir` to the first directory holding a `package.json`. A\n * workspace when that `package.json` has a `workspaces` key (array, or\n * `{ packages: [...] }`), or when a `pnpm-workspace.yaml` sits next to it.\n * Returns `false` when no `package.json` is found.\n */\nfunction detectMonorepo(startDir: string): boolean {\n let dir = resolve(startDir);\n while (true) {\n const pkgPath = resolve(dir, 'package.json');\n if (existsSync(pkgPath)) {\n if (existsSync(resolve(dir, 'pnpm-workspace.yaml'))) {\n return true;\n }\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n workspaces?: unknown;\n };\n const ws = pkg.workspaces;\n if (\n Array.isArray(ws) ||\n (typeof ws === 'object' &&\n ws !== null &&\n Array.isArray((ws as { packages?: unknown }).packages))\n ) {\n return true;\n }\n } catch {\n // Unreadable / invalid package.json: treat as not a workspace.\n }\n return false;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return false;\n }\n dir = parent;\n }\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'create a tako.config.ts in the current directory',\n },\n args: {\n ...sharedArgs,\n force: {\n type: 'boolean',\n description: 'overwrite an existing config file',\n default: false,\n },\n monorepo: {\n type: 'boolean',\n description:\n 'write the monorepo config layout (auto-detected from workspaces when unset)',\n default: undefined,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n // Unlike `loadConfig`, `init` never walks up: it always targets `cwd`.\n const target = args.config\n ? resolve(cwd, args.config)\n : resolve(cwd, 'tako.config.ts');\n\n if (existsSync(target) && !args.force) {\n throw new ConfigExistsError(target);\n }\n\n // citty leaves an unset boolean flag `undefined` (no `default`), so\n // `--monorepo` / `--no-monorepo` win and absence falls back to detection.\n const monorepo: boolean =\n typeof args.monorepo === 'boolean' ? args.monorepo : detectMonorepo(cwd);\n\n await mkdir(dirname(target), { recursive: true });\n await writeFile(\n target,\n monorepo ? CONFIG_TEMPLATE_MONOREPO : CONFIG_TEMPLATE,\n 'utf8',\n );\n\n const name = relative(cwd, target) || 'tako.config.ts';\n reporter.info(\n monorepo ? `created ${name} (monorepo layout)` : `created ${name}`,\n );\n },\n});\n","/**\n * `tako outdated` — on-demand check of the installed `@kurotako/*` packages\n * in the target project against the npm registry. Informational only, always\n * exits 0.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §`tako outdated`\n * command.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { compareVersions } from '../version-check.js';\n\ninterface PackageEntry {\n name: string;\n installed: string | undefined;\n latest: string | undefined;\n}\n\nfunction findProjectPackageJson(cwd: string): string | undefined {\n let dir = resolve(cwd);\n while (true) {\n const candidate = resolve(dir, 'package.json');\n if (existsSync(candidate)) {\n return candidate;\n }\n if (existsSync(resolve(dir, '.git'))) {\n return undefined;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return undefined;\n }\n dir = parent;\n }\n}\n\nfunction collectKurotakoDependencies(packageJsonPath: string): string[] {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n return [...names].filter((name) => name.startsWith('@kurotako/')).sort();\n}\n\nfunction resolveInstalledVersion(\n packageJsonPath: string,\n name: string,\n): string | undefined {\n try {\n const require = createRequire(packageJsonPath);\n // Packages only export their main entry point, not \"./package.json\"\n // (blocked by their `exports` field), so walk the same node_modules\n // lookup path Node would use and read the package.json directly instead\n // of going through module resolution.\n const searchPaths = require.resolve.paths(name) ?? [];\n for (const modulesDir of searchPaths) {\n const candidate = resolve(modulesDir, name, 'package.json');\n if (existsSync(candidate)) {\n const pkg = JSON.parse(readFileSync(candidate, 'utf8')) as {\n version?: string;\n };\n\n return pkg.version;\n }\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function fetchLatestVersion(name: string): Promise<string | undefined> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${name}/latest`);\n if (!response.ok) {\n return undefined;\n }\n const body = (await response.json()) as { version?: unknown };\n return typeof body.version === 'string' ? body.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction formatTable(entries: PackageEntry[]): string {\n const rows = entries.map((entry) => ({\n name: entry.name,\n installed: entry.installed ?? 'unknown',\n latest: entry.latest ?? 'unknown',\n status:\n entry.installed === undefined || entry.latest === undefined\n ? 'unknown'\n : compareVersions(entry.latest, entry.installed) > 0\n ? 'outdated'\n : 'up to date',\n }));\n\n const widths = {\n name: Math.max(7, ...rows.map((r) => r.name.length)),\n installed: Math.max(9, ...rows.map((r) => r.installed.length)),\n latest: Math.max(6, ...rows.map((r) => r.latest.length)),\n };\n\n const header = ` ${'package'.padEnd(widths.name)} ${'installed'.padEnd(widths.installed)} ${'latest'.padEnd(widths.latest)} status`;\n const lines = rows.map(\n (r) =>\n ` ${r.name.padEnd(widths.name)} ${r.installed.padEnd(widths.installed)} ${r.latest.padEnd(widths.latest)} ${r.status}`,\n );\n\n return [header, ...lines].join('\\n');\n}\n\nexport const outdatedCommand = defineCommand({\n meta: {\n name: 'outdated',\n description:\n 'check installed @kurotako/* packages against the npm registry',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const packageJsonPath = findProjectPackageJson(cwd);\n if (!packageJsonPath) {\n reporter.error('no package.json found (searched up to the project root)');\n process.exitCode ??= 0;\n return;\n }\n\n const names = collectKurotakoDependencies(packageJsonPath);\n if (names.length === 0) {\n reporter.info('no @kurotako/* dependency found');\n process.exitCode ??= 0;\n return;\n }\n\n const entries: PackageEntry[] = await Promise.all(\n names.map(async (name) => ({\n name,\n installed: resolveInstalledVersion(packageJsonPath, name),\n latest: await fetchLatestVersion(name),\n })),\n );\n\n reporter.info(`tako outdated\\n${formatTable(entries)}`);\n process.exitCode ??= 0;\n },\n});\n","/**\n * Background version check for the `tako` binary — compares the installed\n * `kurotako` version against the npm registry, cached for 8h so most\n * invocations do not hit the network.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §Background version\n * check.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst REGISTRY_URL = 'https://registry.npmjs.org/kurotako/latest';\nconst TTL_MS = 8 * 60 * 60 * 1000;\n\nexport interface VersionCacheEntry {\n checkedAt: number;\n latestVersion: string;\n}\n\nexport function getCacheFilePath(): string {\n const base = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');\n return join(base, 'tako', 'version-check.json');\n}\n\nexport function readCache(): VersionCacheEntry | undefined {\n try {\n const raw = readFileSync(getCacheFilePath(), 'utf8');\n const parsed = JSON.parse(raw) as Partial<VersionCacheEntry>;\n if (\n typeof parsed.checkedAt === 'number' &&\n typeof parsed.latestVersion === 'string'\n ) {\n return {\n checkedAt: parsed.checkedAt,\n latestVersion: parsed.latestVersion,\n };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function writeCache(entry: VersionCacheEntry): void {\n const path = getCacheFilePath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(entry));\n}\n\nexport async function refreshLatestVersion(\n signal: AbortSignal,\n): Promise<string> {\n const response = await fetch(REGISTRY_URL, { signal });\n if (!response.ok) {\n throw new Error(`registry request failed with status ${response.status}`);\n }\n const body = (await response.json()) as { version?: unknown };\n if (typeof body.version !== 'string') {\n throw new Error('registry response is missing a version string');\n }\n return body.version;\n}\n\n/**\n * `-1` when `a` is older than `b`, `0` when equal, `1` when newer. Handles\n * `major.minor.patch` plus an optional `-prerelease` suffix (a release always\n * outranks a prerelease of the same `major.minor.patch`).\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const [aMajor, aMinor, aPatch, aPre] = splitVersion(a);\n const [bMajor, bMinor, bPatch, bPre] = splitVersion(b);\n\n if (aMajor !== bMajor) {\n return aMajor < bMajor ? -1 : 1;\n }\n if (aMinor !== bMinor) {\n return aMinor < bMinor ? -1 : 1;\n }\n if (aPatch !== bPatch) {\n return aPatch < bPatch ? -1 : 1;\n }\n\n if (aPre === bPre) {\n return 0;\n }\n if (aPre === undefined) {\n return 1;\n }\n if (bPre === undefined) {\n return -1;\n }\n return aPre < bPre ? -1 : 1;\n}\n\nfunction splitVersion(\n version: string,\n): [major: number, minor: number, patch: number, pre?: string] {\n const [core = '', ...rest] = version.split('-');\n const [major = 0, minor = 0, patch = 0] = core\n .split('.')\n .map((n) => Number.parseInt(n, 10) || 0);\n return [major, minor, patch, rest.length > 0 ? rest.join('-') : undefined];\n}\n\nexport interface CheckForUpdateResult {\n notice?: string;\n refresh?: (signal: AbortSignal) => Promise<void>;\n}\n\nexport function checkForUpdate(currentVersion: string): CheckForUpdateResult {\n const cache = readCache();\n const result: CheckForUpdateResult = {};\n\n if (cache && compareVersions(cache.latestVersion, currentVersion) > 0) {\n result.notice = `tako a new version of kurotako is available: ${currentVersion} → ${cache.latestVersion} (npm i kurotako@latest)`;\n }\n\n const isStale = cache === undefined || Date.now() - cache.checkedAt > TTL_MS;\n if (isStale) {\n result.refresh = async (signal: AbortSignal) => {\n const latestVersion = await refreshLatestVersion(signal);\n writeCache({ checkedAt: Date.now(), latestVersion });\n };\n }\n\n return result;\n}\n","/**\n * `tako validate` — the same checks as `generate` up to (not including)\n * emission. `loadConfig()` + `run({ write: false })`; any `TakoError` propagates\n * to the top-level handler and exits 1\n * (`backlog/features/cli/technical.md` §`tako validate`).\n */\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { loadAndRun } from './generate.js';\n\nexport const validateCommand = defineCommand({\n meta: {\n name: 'validate',\n description: 'check the config and schema without writing anything',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n await loadAndRun({\n cwd: process.cwd(),\n configPath: args.config || undefined,\n write: false,\n reporter,\n });\n reporter.info('config and schema are valid');\n },\n});\n"],"mappings":"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","names":["import_core","import_citty","import_node_fs","import_node_path","import_core","path","import_node_path","import_config","import_core","import_citty","import_node_path","import_config","import_core","import_core","path","chokidar","loadConfig","realLoadConfig","run","realRun","path","import_node_fs","import_promises","import_node_path","import_config","import_citty","import_node_fs","import_node_path","import_citty","import_node_fs","import_node_path","path","require","import_citty"]}
package/dist/index.js CHANGED
@@ -711,9 +711,15 @@ function collectKurotakoDependencies(packageJsonPath) {
711
711
  function resolveInstalledVersion(packageJsonPath, name) {
712
712
  try {
713
713
  const require2 = createRequire(packageJsonPath);
714
- const resolvedPath = require2.resolve(`${name}/package.json`);
715
- const pkg = JSON.parse(readFileSync3(resolvedPath, "utf8"));
716
- return pkg.version;
714
+ const searchPaths = require2.resolve.paths(name) ?? [];
715
+ for (const modulesDir of searchPaths) {
716
+ const candidate = resolve3(modulesDir, name, "package.json");
717
+ if (existsSync4(candidate)) {
718
+ const pkg = JSON.parse(readFileSync3(candidate, "utf8"));
719
+ return pkg.version;
720
+ }
721
+ }
722
+ return void 0;
717
723
  } catch {
718
724
  return void 0;
719
725
  }
@@ -803,7 +809,7 @@ var validateCommand = defineCommand5({
803
809
  });
804
810
 
805
811
  // src/cli.ts
806
- var VERSION = true ? "0.2.0" : "0.0.0-dev";
812
+ var VERSION = true ? "0.2.1" : "0.0.0-dev";
807
813
  var subCommands = {
808
814
  init: initCommand,
809
815
  generate: generateCommand,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/check.ts","../src/args.ts","../src/diff.ts","../src/reporter.ts","../src/commands/generate.ts","../src/watch.ts","../src/errors.ts","../src/commands/init.ts","../src/commands/outdated.ts","../src/version-check.ts","../src/commands/validate.ts"],"sourcesContent":["/**\n * `runCli()` — build the citty command tree, dispatch, map every `TakoError` to\n * a formatted message + exit 1. `--version` / `--help` are handled here (citty's\n * own handling lives in `runMain`, which hard-exits — not what a testable\n * `runCli` wants).\n *\n * `backlog/features/cli/technical.md` §Command surface, §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\nimport { type CommandDef, defineCommand, renderUsage, runCommand } from 'citty';\nimport { checkCommand } from './commands/check.js';\nimport { generateCommand } from './commands/generate.js';\nimport { initCommand } from './commands/init.js';\nimport { outdatedCommand } from './commands/outdated.js';\nimport { validateCommand } from './commands/validate.js';\nimport { renderError } from './errors.js';\nimport { ConsoleReporter } from './reporter.js';\nimport { checkForUpdate } from './version-check.js';\n\ndeclare const __TAKO_VERSION__: string;\nconst VERSION =\n typeof __TAKO_VERSION__ === 'string' ? __TAKO_VERSION__ : '0.0.0-dev';\n\nconst subCommands = {\n init: initCommand,\n generate: generateCommand,\n validate: validateCommand,\n check: checkCommand,\n outdated: outdatedCommand,\n};\n\nconst main = defineCommand({\n meta: {\n name: 'tako',\n version: VERSION,\n description: 'synchronise TypeScript schemas from data model to forms',\n },\n subCommands,\n});\n\nexport async function runCli(\n argv: string[],\n options: { currentVersion?: string } = {},\n): Promise<void> {\n const reporter = new ConsoleReporter({\n debug: argv.includes('--debug') || Boolean(process.env.TAKO_DEBUG),\n });\n\n if (argv.includes('--version') || argv.includes('-v')) {\n process.stdout.write(`${VERSION}\\n`);\n process.exitCode ??= 0;\n return;\n }\n\n if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {\n const sub = argv.find((a) => !a.startsWith('-'));\n const isSub = sub !== undefined && sub in subCommands;\n const cmd = (\n isSub ? subCommands[sub as keyof typeof subCommands] : main\n ) as CommandDef;\n process.stdout.write(\n `${await renderUsage(cmd, isSub ? (main as CommandDef) : undefined)}\\n`,\n );\n process.exitCode ??= 0;\n return;\n }\n\n const { notice, refresh } = checkForUpdate(options.currentVersion ?? VERSION);\n if (notice) {\n reporter.info(notice);\n }\n\n const controller = new AbortController();\n const refreshPromise = refresh?.(controller.signal).catch(() => {});\n\n try {\n await runCommand(main, { rawArgs: argv });\n process.exitCode ??= 0;\n } catch (error) {\n if (error instanceof TakoError) {\n reporter.error(renderError(error));\n process.exitCode = 1;\n } else if (error instanceof Error && error.name === 'CLIError') {\n // citty usage error (unknown command, missing argument, …).\n reporter.error(error.message);\n process.exitCode = 1;\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n process.exitCode = 1;\n }\n } finally {\n controller.abort();\n await refreshPromise;\n }\n}\n","/**\n * `tako check` — drift guard. Runs the pipeline in plan mode (no disk writes,\n * no `afterEmit`), then compares the planned tree against what is on disk.\n * Exit 0 when they match, exit 1 on any drift or any `TakoError` (the latter\n * via the top-level handler in `cli.ts`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §Command surface.\n */\nimport { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport { loadConfig } from '@kurotako/config';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport {\n comparePlanToDisk,\n type DriftEntry,\n ignoreBuildArtifacts,\n markedPackageDirs,\n} from '../diff.js';\nimport { ConsoleReporter } from '../reporter.js';\n\nexport const checkCommand = defineCommand({\n meta: {\n name: 'check',\n description:\n 'check the generated output on disk matches a fresh generate (drift guard)',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const { config } = await loadConfig({\n cwd,\n configPath: args.config || undefined,\n });\n const { plan = [] } = await run(config, { logger: reporter, plan: true });\n\n const roots: string[] = [];\n const ignores: ((absPath: string) => boolean)[] = [];\n\n for (const output of config.outputs) {\n if (output.mode === 'package') {\n ignores.push(ignoreBuildArtifacts);\n if (output.packagesDir) {\n roots.push(...(await markedPackageDirs(output.packagesDir)));\n }\n } else {\n const dir = output.dir;\n if (!dir) {\n continue;\n }\n if (!existsSync(dir)) {\n reporter.info(\n `output directory ${relative(config.rootDir, dir)} does not exist — run tako generate`,\n );\n process.exitCode = 1;\n return;\n }\n roots.push(dir);\n }\n }\n\n const ignore = (absPath: string): boolean =>\n ignores.some((fn) => fn(absPath));\n\n const drift = await comparePlanToDisk({\n plan,\n roots,\n ignore,\n rootDir: config.rootDir,\n });\n\n if (drift.length === 0) {\n reporter.info('output is in sync');\n process.exitCode ??= 0;\n return;\n }\n\n reporter.error(formatDrift(drift));\n process.exitCode = 1;\n },\n});\n\nfunction formatDrift(drift: DriftEntry[]): string {\n const width = Math.max(...drift.map((entry) => entry.kind.length));\n const lines = drift.map(\n (entry) => ` ${entry.kind.padEnd(width)} ${entry.path}`,\n );\n return [\n 'drift detected',\n '',\n ...lines,\n '',\n `${drift.length} files differ from a fresh generate. Run \\`tako generate\\`.`,\n ].join('\\n');\n}\n","/**\n * `sharedArgs` — the options every sub-command carries. citty has no\n * first-class global-option slot, so this object is spread into each command's\n * `args` (`backlog/features/cli/technical.md` §Global option).\n */\nimport type { ArgsDef } from 'citty';\n\nexport const sharedArgs = {\n config: {\n type: 'string',\n description: 'path to the tako config file (default: ./tako.config.ts)',\n },\n /** Hidden: not advertised, kept minimal. Enables `debug` reporter output. */\n debug: {\n type: 'boolean',\n default: false,\n },\n} as const satisfies ArgsDef;\n","/**\n * `comparePlanToDisk` — the in-memory comparison behind `tako check`. Takes the\n * `PlannedFile[]` a fresh `generate` would write (from `run({ plan: true })`)\n * and reports every way the tree on disk diverges from it: a planned file that\n * is absent (`missing`) or whose bytes differ (`modified`), and any file under\n * the scanned roots that no planned file claims (`orphan`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §The comparison.\n */\nimport { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PlannedFile } from '@kurotako/core';\n\nexport type DriftKind = 'modified' | 'missing' | 'orphan';\n\nexport interface DriftEntry {\n kind: DriftKind;\n /** Relative to `rootDir`, POSIX separators; a collapsed dir ends with `/`. */\n path: string;\n}\n\nexport interface ComparePlanToDiskArgs {\n plan: PlannedFile[];\n /** Directories walked for orphans (absolute). */\n roots: string[];\n /** Return `true` to exclude an absolute path from the orphan scan. */\n ignore: (absPath: string) => boolean;\n /** Anchor for the reported relative paths (the config-file directory). */\n rootDir: string;\n}\n\nfunction toPosix(rootDir: string, absPath: string): string {\n return path.relative(rootDir, absPath).split(path.sep).join('/');\n}\n\nexport async function comparePlanToDisk(\n args: ComparePlanToDiskArgs,\n): Promise<DriftEntry[]> {\n const { plan, roots, ignore, rootDir } = args;\n const plannedByPath = new Map(plan.map((f) => [path.resolve(f.path), f]));\n const entries: DriftEntry[] = [];\n\n // 1. Expected vs disk.\n for (const [absPath, file] of plannedByPath) {\n if (!existsSync(absPath)) {\n entries.push({ kind: 'missing', path: toPosix(rootDir, absPath) });\n continue;\n }\n const onDisk = await readFile(absPath, 'utf8');\n if (onDisk !== file.content) {\n entries.push({ kind: 'modified', path: toPosix(rootDir, absPath) });\n }\n }\n\n // 2. Orphan scan — a planned file lives under `dir` iff any planned absolute\n // path is `dir` itself or sits below it.\n const plannedPaths = [...plannedByPath.keys()];\n const hasPlannedUnder = (dir: string): boolean => {\n const prefix = `${dir}${path.sep}`;\n return plannedPaths.some((p) => p === dir || p.startsWith(prefix));\n };\n\n const seenRoots = new Set<string>();\n for (const root of roots) {\n const absRoot = path.resolve(root);\n if (seenRoots.has(absRoot) || !existsSync(absRoot)) {\n continue;\n }\n seenRoots.add(absRoot);\n await scan(absRoot);\n }\n\n async function scan(dir: string): Promise<void> {\n // A directory with no planned file underneath collapses to a single entry —\n // unless it holds nothing but ignored files (e.g. only `dist/`).\n if (!hasPlannedUnder(dir)) {\n if (await hasNonIgnoredFile(dir)) {\n entries.push({ kind: 'orphan', path: `${toPosix(rootDir, dir)}/` });\n }\n return;\n }\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isDirectory()) {\n await scan(abs);\n } else if (dirent.isFile() && !plannedByPath.has(abs)) {\n entries.push({ kind: 'orphan', path: toPosix(rootDir, abs) });\n }\n }\n }\n\n async function hasNonIgnoredFile(dir: string): Promise<boolean> {\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isFile()) {\n return true;\n }\n if (dirent.isDirectory() && (await hasNonIgnoredFile(abs))) {\n return true;\n }\n }\n return false;\n }\n\n entries.sort((a, b) =>\n a.path < b.path\n ? -1\n : a.path > b.path\n ? 1\n : a.kind < b.kind\n ? -1\n : a.kind > b.kind\n ? 1\n : 0,\n );\n return entries;\n}\n\n/** Rejects `dist/` and `node_modules/` anywhere in the path (mode B). */\nexport function ignoreBuildArtifacts(absPath: string): boolean {\n return /(^|[/\\\\])(dist|node_modules)([/\\\\]|$)/.test(absPath);\n}\n\n/**\n * Whether `<packagesDir>/<name>` looks like a directory `tako` generated: a\n * `package.json` whose `\"//\"` marker starts with `Generated by tako`.\n */\nexport async function hasGeneratedMarker(pkgDir: string): Promise<boolean> {\n try {\n const pkg = JSON.parse(\n await readFile(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\n/** Every immediate subdirectory of `packagesDir` carrying the tako marker. */\nexport async function markedPackageDirs(\n packagesDir: string,\n): Promise<string[]> {\n if (!existsSync(packagesDir)) {\n return [];\n }\n const out: string[] = [];\n for (const dirent of await readdir(packagesDir, { withFileTypes: true })) {\n if (!dirent.isDirectory()) {\n continue;\n }\n const abs = path.join(packagesDir, dirent.name);\n if (await hasGeneratedMarker(abs)) {\n out.push(abs);\n }\n }\n return out.sort();\n}\n","/**\n * `ConsoleReporter` — the `@kurotako/core` `Logger` the CLI injects into\n * `loadConfig()` / `run()`, plus the per-phase / summary output.\n *\n * Contract (`backlog/features/cli/technical.md` §Reporter):\n * - human output goes to **stderr**, `stdout` stays clean;\n * - `info` / `warn` / `error` shown by default; `debug` only with `--debug` /\n * `TAKO_DEBUG` (a hidden flag, not advertised);\n * - the human-readable message is always shown; the structured `meta` object is\n * printed only with `--debug` (a custom `Logger` still receives it in full),\n * so default output stays prose, not `key=value` noise;\n * - `tako ` prefix, level-coloured; colour auto-off when the stream is not a TTY\n * or `NO_COLOR` is set;\n * - `child(tag)` returns a `Logger` tagging every `meta` with `{ scope: tag }`.\n */\nimport { childLogger, type Logger } from '@kurotako/core';\n\ntype Level = 'debug' | 'info' | 'warn' | 'error';\n\n/** The slice of a writable stream the reporter needs (keeps tests trivial). */\nexport interface WriteStream {\n write(chunk: string): unknown;\n isTTY?: boolean;\n}\n\nexport interface ConsoleReporterOptions {\n /** Show `debug` output. Default: `false` unless `TAKO_DEBUG` is set. */\n debug?: boolean;\n /** Sink for human output. Default: `process.stderr`. */\n stream?: WriteStream;\n /** Force colour on/off. Default: auto (TTY and no `NO_COLOR`). */\n color?: boolean;\n}\n\nconst ESC = String.fromCharCode(27);\nconst ANSI: Record<Level, string> = {\n debug: `${ESC}[2m`, // dim\n info: `${ESC}[36m`, // cyan\n warn: `${ESC}[33m`, // yellow\n error: `${ESC}[31m`, // red\n};\nconst ANSI_RESET = `${ESC}[0m`;\n\nexport class ConsoleReporter implements Logger {\n private readonly stream: WriteStream;\n private readonly showDebug: boolean;\n private readonly color: boolean;\n\n constructor(options: ConsoleReporterOptions = {}) {\n this.stream = options.stream ?? process.stderr;\n this.showDebug = options.debug ?? Boolean(process.env.TAKO_DEBUG);\n this.color =\n options.color ??\n (Boolean(this.stream.isTTY) && process.env.NO_COLOR === undefined);\n }\n\n debug(msg: string, meta?: unknown): void {\n if (this.showDebug) {\n this.write('debug', msg, meta);\n }\n }\n\n info(msg: string, meta?: unknown): void {\n this.write('info', msg, meta);\n }\n\n warn(msg: string, meta?: unknown): void {\n this.write('warn', msg, meta);\n }\n\n error(msg: string, meta?: unknown): void {\n this.write('error', msg, meta);\n }\n\n /** A child `Logger` whose calls carry `{ scope: tag }` in `meta`. */\n child(tag: string): Logger {\n return childLogger(this, { scope: tag });\n }\n\n private write(level: Level, msg: string, meta?: unknown): void {\n const prefix = this.color ? `${ANSI[level]}tako${ANSI_RESET}` : 'tako';\n const detail =\n meta === undefined || !this.showDebug ? '' : ` ${formatMeta(meta)}`;\n this.stream.write(`${prefix} ${msg}${detail}\\n`);\n }\n}\n\nfunction formatMeta(meta: unknown): string {\n if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {\n return Object.entries(meta as Record<string, unknown>)\n .map(([k, v]) => `${k}=${stringify(v)}`)\n .join(' ');\n }\n return stringify(meta);\n}\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n","/**\n * `tako generate` — `loadConfig()` then `run()`. `--dry-run` runs everything but\n * skips the Writer; `--watch` hands off to the chokidar loop\n * (`backlog/features/cli/technical.md` §`tako generate`).\n */\nimport { relative } from 'node:path';\nimport { type LoadResult, loadConfig } from '@kurotako/config';\nimport type { OutputConfig, ResolvedConfig, RunResult } from '@kurotako/core';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { watchAndRun } from '../watch.js';\n\nexport interface LoadAndRunOptions {\n cwd: string;\n configPath?: string;\n write: boolean;\n signal?: AbortSignal;\n reporter: ConsoleReporter;\n}\n\nexport interface LoadAndRunResult {\n result: RunResult;\n config: ResolvedConfig;\n configFile: string;\n rootDir: string;\n}\n\n/** The directory named in the `wrote N files -> …` summary line, for one output. */\nexport function outputSummaryDir(\n output: OutputConfig,\n config: ResolvedConfig,\n): string {\n return output.mode === 'package'\n ? (output.packagesDir ?? config.rootDir)\n : (output.dir ?? config.rootDir);\n}\n\n/**\n * The shared body of `generate`, `validate` and each watch cycle: resolve +\n * load the config, then run the pipeline. `write: false` also skips the\n * `afterEmit` hook (`@kurotako/core` `run()`).\n */\nexport async function loadAndRun(\n opts: LoadAndRunOptions,\n): Promise<LoadAndRunResult> {\n const loaded: LoadResult = await loadConfig({\n cwd: opts.cwd,\n configPath: opts.configPath,\n });\n const result = await run(loaded.config, {\n logger: opts.reporter,\n write: opts.write,\n signal: opts.signal,\n });\n return {\n result,\n config: loaded.config,\n configFile: loaded.configFile,\n rootDir: loaded.rootDir,\n };\n}\n\nexport const generateCommand = defineCommand({\n meta: {\n name: 'generate',\n description: 'run the pipeline and write the generated code',\n },\n args: {\n ...sharedArgs,\n watch: {\n type: 'boolean',\n description: 'rebuild on every schema / config change',\n default: false,\n },\n 'dry-run': {\n type: 'boolean',\n description: 'run everything but write nothing',\n default: false,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n const configPath = args.config || undefined;\n\n if (args.watch) {\n await watchAndRun({ cwd, configPath, reporter });\n return;\n }\n\n const dryRun = Boolean(args['dry-run']);\n const { result, config } = await loadAndRun({\n cwd,\n configPath,\n write: !dryRun,\n reporter,\n });\n\n if (dryRun) {\n reporter.info(`dry run: ${result.files.length} files would be written`);\n return;\n }\n\n const dirs = config.outputs\n .map((output) => relative(cwd, outputSummaryDir(output, config)))\n .join(', ');\n reporter.info(`wrote ${result.files.length} files -> ${dirs}`);\n },\n});\n","/**\n * `tako generate --watch` — a chokidar loop around `loadConfig()` + `run()`.\n * Full regeneration on every change (no incremental). A 100 ms trailing\n * debounce coalesces bursts; a change mid-cycle aborts the in-flight `run()`\n * (via `RunOptions.signal`) and re-runs once it settles. `loadConfig` failures\n * are reported, not fatal — the watcher stays up on `tako.config.ts`.\n *\n * `backlog/features/cli/technical.md` §Watch mode.\n */\nimport { basename, resolve } from 'node:path';\nimport {\n type LoadResult,\n loadConfig as realLoadConfig,\n} from '@kurotako/config';\nimport { run as realRun, TakoError } from '@kurotako/core';\nimport chokidar from 'chokidar';\nimport { renderError } from './errors.js';\nimport type { ConsoleReporter } from './reporter.js';\n\n/** Minimal watcher seam so the loop is unit-testable without touching the fs. */\nexport interface Watcher {\n add(paths: string | readonly string[]): void;\n unwatch(paths: string | readonly string[]): void;\n on(handler: (event: string, path: string) => void): void;\n close(): Promise<void>;\n}\n\nexport interface WatchAndRunOptions {\n cwd: string;\n configPath?: string;\n reporter: ConsoleReporter;\n}\n\nexport interface WatchDeps {\n createWatcher: () => Watcher;\n loadConfig: typeof realLoadConfig;\n run: typeof realRun;\n debounceMs: number;\n}\n\nconst DEBOUNCE_MS = 100;\n\nfunction chokidarWatcher(): Watcher {\n const fsw = chokidar.watch([], {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 20 },\n });\n return {\n add: (paths) => fsw.add(paths as string | string[]),\n unwatch: (paths) => fsw.unwatch(paths as string | string[]),\n on: (handler) => {\n fsw.on('add', (p) => handler('add', p));\n fsw.on('change', (p) => handler('change', p));\n fsw.on('unlink', (p) => handler('unlink', p));\n },\n close: () => fsw.close(),\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError';\n}\n\n/**\n * Runs until `SIGINT` / `SIGTERM`, then closes the watcher and resolves so the\n * caller can exit 0. (The design doc types this `Promise<never>`; it resolves\n * on shutdown here purely so it stays testable.)\n */\nexport async function watchAndRun(\n opts: WatchAndRunOptions,\n deps: Partial<WatchDeps> = {},\n): Promise<void> {\n const { cwd, configPath, reporter } = opts;\n const createWatcher = deps.createWatcher ?? chokidarWatcher;\n const loadConfig = deps.loadConfig ?? realLoadConfig;\n const run = deps.run ?? realRun;\n const debounceMs = deps.debounceMs ?? DEBOUNCE_MS;\n\n const watcher = createWatcher();\n let watched = new Set<string>();\n let inFlight: AbortController | null = null;\n let queued = false;\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let reason = 'initial build';\n\n const guessedConfigFile = configPath\n ? resolve(cwd, configPath)\n : resolve(cwd, 'tako.config.ts');\n\n function applyWatchSet(desired: Set<string>): void {\n for (const path of desired) {\n if (!watched.has(path)) {\n watcher.add(path);\n }\n }\n for (const path of watched) {\n if (!desired.has(path)) {\n watcher.unwatch(path);\n }\n }\n watched = desired;\n }\n\n async function reconcileWatchSet(loaded: LoadResult): Promise<void> {\n const desired = new Set<string>([loaded.configFile]);\n for (const [namespace, source] of Object.entries(loaded.config.sources)) {\n const paths =\n (await source.parser.watchPaths?.({\n namespace,\n cwd: loaded.rootDir,\n logger: reporter,\n })) ?? [];\n for (const path of paths) {\n desired.add(resolve(loaded.rootDir, path));\n }\n }\n applyWatchSet(desired);\n }\n\n async function cycle(): Promise<void> {\n const why = reason;\n reporter.info(`--- rebuild (${why}) ---`);\n const ac = new AbortController();\n inFlight = ac;\n try {\n const loaded = await loadConfig({ cwd, configPath });\n await reconcileWatchSet(loaded);\n const result = await run(loaded.config, {\n logger: reporter,\n signal: ac.signal,\n write: true,\n });\n if (!ac.signal.aborted) {\n reporter.info(`wrote ${result.files.length} files`);\n }\n } catch (error) {\n if (isAbortError(error) || ac.signal.aborted) {\n // Superseded by a newer cycle — swallow.\n } else if (error instanceof TakoError) {\n reporter.error(renderError(error));\n // Keep watching at least the config file so a fix is picked up.\n applyWatchSet(new Set([...watched, guessedConfigFile]));\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n }\n } finally {\n inFlight = null;\n if (queued && !closed) {\n queued = false;\n await cycle();\n }\n }\n }\n\n function trigger(): void {\n if (inFlight) {\n queued = true;\n inFlight.abort();\n return;\n }\n void cycle();\n }\n\n function schedule(event: string, path: string): void {\n if (closed) {\n return;\n }\n reason = `${basename(path)} ${event === 'unlink' ? 'removed' : 'changed'}`;\n if (timer) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = null;\n trigger();\n }, debounceMs);\n }\n\n watcher.on(schedule);\n\n // Initial cycle: a failure is reported inside `cycle()`, never fatal.\n applyWatchSet(new Set([guessedConfigFile]));\n await cycle();\n reporter.info(`watching ${watched.size} paths`);\n\n await new Promise<void>((resolvePromise) => {\n const shutdown = () => {\n closed = true;\n if (timer) {\n clearTimeout(timer);\n }\n inFlight?.abort();\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n void watcher.close().finally(() => resolvePromise());\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n}\n","/**\n * CLI-owned error(s) and `renderError()` — the single formatter the top-level\n * handler in `cli.ts` uses for any `TakoError` (from `@kurotako/core`,\n * `@kurotako/config`, or this package).\n *\n * `backlog/features/cli/technical.md` §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\n\n/** `tako init` refuses to overwrite an existing config unless `--force`. */\nexport class ConfigExistsError extends TakoError {\n readonly path: string;\n\n constructor(path: string) {\n super(\n 'config_exists',\n `a config file already exists at '${path}' (pass --force to overwrite)`,\n );\n this.path = path;\n }\n}\n\ninterface Issue {\n path?: string;\n message?: string;\n}\n\n/**\n * `error [<code>]: <message>` plus any carried context on its own indented\n * lines: located issues (`ConfigShapeError`, `IrValidationError`,\n * `DriverOptionsError`), the offending driver / namespace (`DriverError`,\n * `UnknownNamespaceError`), the dependency cycle path (`DependencyCycleError`),\n * and the `cause` message of a wrapped failure.\n */\nexport function renderError(error: TakoError): string {\n const lines = [`error [${error.code}]: ${error.message}`];\n\n const issues = (error as { issues?: unknown }).issues;\n if (Array.isArray(issues)) {\n for (const issue of issues as Issue[]) {\n const at =\n issue.path === undefined || issue.path === '' ? '<root>' : issue.path;\n lines.push(` - ${at}: ${issue.message}`);\n }\n }\n\n const cycle = (error as { cycle?: unknown }).cycle;\n if (Array.isArray(cycle) && cycle.length > 0) {\n lines.push(` cycle: ${(cycle as string[]).join(' -> ')}`);\n }\n\n const driverName = (error as { driverName?: unknown }).driverName;\n if (typeof driverName === 'string') {\n const role = (error as { role?: unknown }).role;\n const namespace = (error as { namespace?: unknown }).namespace;\n const roleLabel = typeof role === 'string' ? role : 'driver';\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` ${roleLabel}: ${driverName}${where}`);\n } else {\n const generator = (error as { generator?: unknown }).generator;\n if (typeof generator === 'string') {\n const namespace = (error as { namespace?: unknown }).namespace;\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` generator: ${generator}${where}`);\n }\n }\n\n // Wrapped failures (`DriverError`, `HookError`, `ConfigLoadError`, …) carry the\n // real error in `cause`; core masks its type, so surface at least its message.\n const cause = error.cause;\n if (cause !== undefined && cause !== null) {\n const message = cause instanceof Error ? cause.message : String(cause);\n const code = cause instanceof TakoError ? ` [${cause.code}]` : '';\n lines.push(` cause${code}: ${message}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * `tako init` — write the commented `tako.config.ts` skeleton into the current\n * directory. No prompts, no schema auto-detection; refuses to overwrite unless\n * `--force` (`backlog/features/cli/technical.md` §`tako init`).\n *\n * `--monorepo` / `--no-monorepo` picks between `CONFIG_TEMPLATE` and\n * `CONFIG_TEMPLATE_MONOREPO`; unset, it auto-detects a workspace by walking up\n * for the nearest `package.json` (`workspaces` key, or a sibling\n * `pnpm-workspace.yaml`).\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative, resolve } from 'node:path';\nimport { CONFIG_TEMPLATE, CONFIG_TEMPLATE_MONOREPO } from '@kurotako/config';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConfigExistsError } from '../errors.js';\nimport { ConsoleReporter } from '../reporter.js';\n\n/**\n * Walk up from `startDir` to the first directory holding a `package.json`. A\n * workspace when that `package.json` has a `workspaces` key (array, or\n * `{ packages: [...] }`), or when a `pnpm-workspace.yaml` sits next to it.\n * Returns `false` when no `package.json` is found.\n */\nfunction detectMonorepo(startDir: string): boolean {\n let dir = resolve(startDir);\n while (true) {\n const pkgPath = resolve(dir, 'package.json');\n if (existsSync(pkgPath)) {\n if (existsSync(resolve(dir, 'pnpm-workspace.yaml'))) {\n return true;\n }\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n workspaces?: unknown;\n };\n const ws = pkg.workspaces;\n if (\n Array.isArray(ws) ||\n (typeof ws === 'object' &&\n ws !== null &&\n Array.isArray((ws as { packages?: unknown }).packages))\n ) {\n return true;\n }\n } catch {\n // Unreadable / invalid package.json: treat as not a workspace.\n }\n return false;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return false;\n }\n dir = parent;\n }\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'create a tako.config.ts in the current directory',\n },\n args: {\n ...sharedArgs,\n force: {\n type: 'boolean',\n description: 'overwrite an existing config file',\n default: false,\n },\n monorepo: {\n type: 'boolean',\n description:\n 'write the monorepo config layout (auto-detected from workspaces when unset)',\n default: undefined,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n // Unlike `loadConfig`, `init` never walks up: it always targets `cwd`.\n const target = args.config\n ? resolve(cwd, args.config)\n : resolve(cwd, 'tako.config.ts');\n\n if (existsSync(target) && !args.force) {\n throw new ConfigExistsError(target);\n }\n\n // citty leaves an unset boolean flag `undefined` (no `default`), so\n // `--monorepo` / `--no-monorepo` win and absence falls back to detection.\n const monorepo: boolean =\n typeof args.monorepo === 'boolean' ? args.monorepo : detectMonorepo(cwd);\n\n await mkdir(dirname(target), { recursive: true });\n await writeFile(\n target,\n monorepo ? CONFIG_TEMPLATE_MONOREPO : CONFIG_TEMPLATE,\n 'utf8',\n );\n\n const name = relative(cwd, target) || 'tako.config.ts';\n reporter.info(\n monorepo ? `created ${name} (monorepo layout)` : `created ${name}`,\n );\n },\n});\n","/**\n * `tako outdated` — on-demand check of the installed `@kurotako/*` packages\n * in the target project against the npm registry. Informational only, always\n * exits 0.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §`tako outdated`\n * command.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { compareVersions } from '../version-check.js';\n\ninterface PackageEntry {\n name: string;\n installed: string | undefined;\n latest: string | undefined;\n}\n\nfunction findProjectPackageJson(cwd: string): string | undefined {\n let dir = resolve(cwd);\n while (true) {\n const candidate = resolve(dir, 'package.json');\n if (existsSync(candidate)) {\n return candidate;\n }\n if (existsSync(resolve(dir, '.git'))) {\n return undefined;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return undefined;\n }\n dir = parent;\n }\n}\n\nfunction collectKurotakoDependencies(packageJsonPath: string): string[] {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n return [...names].filter((name) => name.startsWith('@kurotako/')).sort();\n}\n\nfunction resolveInstalledVersion(\n packageJsonPath: string,\n name: string,\n): string | undefined {\n try {\n const require = createRequire(packageJsonPath);\n const resolvedPath = require.resolve(`${name}/package.json`);\n const pkg = JSON.parse(readFileSync(resolvedPath, 'utf8')) as {\n version?: string;\n };\n return pkg.version;\n } catch {\n return undefined;\n }\n}\n\nasync function fetchLatestVersion(name: string): Promise<string | undefined> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${name}/latest`);\n if (!response.ok) {\n return undefined;\n }\n const body = (await response.json()) as { version?: unknown };\n return typeof body.version === 'string' ? body.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction formatTable(entries: PackageEntry[]): string {\n const rows = entries.map((entry) => ({\n name: entry.name,\n installed: entry.installed ?? 'unknown',\n latest: entry.latest ?? 'unknown',\n status:\n entry.installed === undefined || entry.latest === undefined\n ? 'unknown'\n : compareVersions(entry.latest, entry.installed) > 0\n ? 'outdated'\n : 'up to date',\n }));\n\n const widths = {\n name: Math.max(7, ...rows.map((r) => r.name.length)),\n installed: Math.max(9, ...rows.map((r) => r.installed.length)),\n latest: Math.max(6, ...rows.map((r) => r.latest.length)),\n };\n\n const header = ` ${'package'.padEnd(widths.name)} ${'installed'.padEnd(widths.installed)} ${'latest'.padEnd(widths.latest)} status`;\n const lines = rows.map(\n (r) =>\n ` ${r.name.padEnd(widths.name)} ${r.installed.padEnd(widths.installed)} ${r.latest.padEnd(widths.latest)} ${r.status}`,\n );\n\n return [header, ...lines].join('\\n');\n}\n\nexport const outdatedCommand = defineCommand({\n meta: {\n name: 'outdated',\n description:\n 'check installed @kurotako/* packages against the npm registry',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const packageJsonPath = findProjectPackageJson(cwd);\n if (!packageJsonPath) {\n reporter.error('no package.json found (searched up to the project root)');\n process.exitCode ??= 0;\n return;\n }\n\n const names = collectKurotakoDependencies(packageJsonPath);\n if (names.length === 0) {\n reporter.info('no @kurotako/* dependency found');\n process.exitCode ??= 0;\n return;\n }\n\n const entries: PackageEntry[] = await Promise.all(\n names.map(async (name) => ({\n name,\n installed: resolveInstalledVersion(packageJsonPath, name),\n latest: await fetchLatestVersion(name),\n })),\n );\n\n reporter.info(`tako outdated\\n${formatTable(entries)}`);\n process.exitCode ??= 0;\n },\n});\n","/**\n * Background version check for the `tako` binary — compares the installed\n * `kurotako` version against the npm registry, cached for 8h so most\n * invocations do not hit the network.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §Background version\n * check.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst REGISTRY_URL = 'https://registry.npmjs.org/kurotako/latest';\nconst TTL_MS = 8 * 60 * 60 * 1000;\n\nexport interface VersionCacheEntry {\n checkedAt: number;\n latestVersion: string;\n}\n\nexport function getCacheFilePath(): string {\n const base = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');\n return join(base, 'tako', 'version-check.json');\n}\n\nexport function readCache(): VersionCacheEntry | undefined {\n try {\n const raw = readFileSync(getCacheFilePath(), 'utf8');\n const parsed = JSON.parse(raw) as Partial<VersionCacheEntry>;\n if (\n typeof parsed.checkedAt === 'number' &&\n typeof parsed.latestVersion === 'string'\n ) {\n return {\n checkedAt: parsed.checkedAt,\n latestVersion: parsed.latestVersion,\n };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function writeCache(entry: VersionCacheEntry): void {\n const path = getCacheFilePath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(entry));\n}\n\nexport async function refreshLatestVersion(\n signal: AbortSignal,\n): Promise<string> {\n const response = await fetch(REGISTRY_URL, { signal });\n if (!response.ok) {\n throw new Error(`registry request failed with status ${response.status}`);\n }\n const body = (await response.json()) as { version?: unknown };\n if (typeof body.version !== 'string') {\n throw new Error('registry response is missing a version string');\n }\n return body.version;\n}\n\n/**\n * `-1` when `a` is older than `b`, `0` when equal, `1` when newer. Handles\n * `major.minor.patch` plus an optional `-prerelease` suffix (a release always\n * outranks a prerelease of the same `major.minor.patch`).\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const [aMajor, aMinor, aPatch, aPre] = splitVersion(a);\n const [bMajor, bMinor, bPatch, bPre] = splitVersion(b);\n\n if (aMajor !== bMajor) {\n return aMajor < bMajor ? -1 : 1;\n }\n if (aMinor !== bMinor) {\n return aMinor < bMinor ? -1 : 1;\n }\n if (aPatch !== bPatch) {\n return aPatch < bPatch ? -1 : 1;\n }\n\n if (aPre === bPre) {\n return 0;\n }\n if (aPre === undefined) {\n return 1;\n }\n if (bPre === undefined) {\n return -1;\n }\n return aPre < bPre ? -1 : 1;\n}\n\nfunction splitVersion(\n version: string,\n): [major: number, minor: number, patch: number, pre?: string] {\n const [core = '', ...rest] = version.split('-');\n const [major = 0, minor = 0, patch = 0] = core\n .split('.')\n .map((n) => Number.parseInt(n, 10) || 0);\n return [major, minor, patch, rest.length > 0 ? rest.join('-') : undefined];\n}\n\nexport interface CheckForUpdateResult {\n notice?: string;\n refresh?: (signal: AbortSignal) => Promise<void>;\n}\n\nexport function checkForUpdate(currentVersion: string): CheckForUpdateResult {\n const cache = readCache();\n const result: CheckForUpdateResult = {};\n\n if (cache && compareVersions(cache.latestVersion, currentVersion) > 0) {\n result.notice = `tako a new version of kurotako is available: ${currentVersion} → ${cache.latestVersion} (npm i kurotako@latest)`;\n }\n\n const isStale = cache === undefined || Date.now() - cache.checkedAt > TTL_MS;\n if (isStale) {\n result.refresh = async (signal: AbortSignal) => {\n const latestVersion = await refreshLatestVersion(signal);\n writeCache({ checkedAt: Date.now(), latestVersion });\n };\n }\n\n return result;\n}\n","/**\n * `tako validate` — the same checks as `generate` up to (not including)\n * emission. `loadConfig()` + `run({ write: false })`; any `TakoError` propagates\n * to the top-level handler and exits 1\n * (`backlog/features/cli/technical.md` §`tako validate`).\n */\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { loadAndRun } from './generate.js';\n\nexport const validateCommand = defineCommand({\n meta: {\n name: 'validate',\n description: 'check the config and schema without writing anything',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n await loadAndRun({\n cwd: process.cwd(),\n configPath: args.config || undefined,\n write: false,\n reporter,\n });\n reporter.info('config and schema are valid');\n },\n});\n"],"mappings":"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","names":["TakoError","defineCommand","existsSync","existsSync","relative","loadConfig","run","defineCommand","TakoError","path","loadConfig","run","path","TakoError","loadConfig","run","defineCommand","relative","existsSync","relative","resolve","defineCommand","resolve","existsSync","defineCommand","relative","existsSync","readFileSync","dirname","resolve","defineCommand","readFileSync","dirname","path","resolve","existsSync","dirname","readFileSync","require","defineCommand","defineCommand","defineCommand","defineCommand","TakoError"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/check.ts","../src/args.ts","../src/diff.ts","../src/reporter.ts","../src/commands/generate.ts","../src/watch.ts","../src/errors.ts","../src/commands/init.ts","../src/commands/outdated.ts","../src/version-check.ts","../src/commands/validate.ts"],"sourcesContent":["/**\n * `runCli()` — build the citty command tree, dispatch, map every `TakoError` to\n * a formatted message + exit 1. `--version` / `--help` are handled here (citty's\n * own handling lives in `runMain`, which hard-exits — not what a testable\n * `runCli` wants).\n *\n * `backlog/features/cli/technical.md` §Command surface, §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\nimport { type CommandDef, defineCommand, renderUsage, runCommand } from 'citty';\nimport { checkCommand } from './commands/check.js';\nimport { generateCommand } from './commands/generate.js';\nimport { initCommand } from './commands/init.js';\nimport { outdatedCommand } from './commands/outdated.js';\nimport { validateCommand } from './commands/validate.js';\nimport { renderError } from './errors.js';\nimport { ConsoleReporter } from './reporter.js';\nimport { checkForUpdate } from './version-check.js';\n\ndeclare const __TAKO_VERSION__: string;\nconst VERSION =\n typeof __TAKO_VERSION__ === 'string' ? __TAKO_VERSION__ : '0.0.0-dev';\n\nconst subCommands = {\n init: initCommand,\n generate: generateCommand,\n validate: validateCommand,\n check: checkCommand,\n outdated: outdatedCommand,\n};\n\nconst main = defineCommand({\n meta: {\n name: 'tako',\n version: VERSION,\n description: 'synchronise TypeScript schemas from data model to forms',\n },\n subCommands,\n});\n\nexport async function runCli(\n argv: string[],\n options: { currentVersion?: string } = {},\n): Promise<void> {\n const reporter = new ConsoleReporter({\n debug: argv.includes('--debug') || Boolean(process.env.TAKO_DEBUG),\n });\n\n if (argv.includes('--version') || argv.includes('-v')) {\n process.stdout.write(`${VERSION}\\n`);\n process.exitCode ??= 0;\n return;\n }\n\n if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {\n const sub = argv.find((a) => !a.startsWith('-'));\n const isSub = sub !== undefined && sub in subCommands;\n const cmd = (\n isSub ? subCommands[sub as keyof typeof subCommands] : main\n ) as CommandDef;\n process.stdout.write(\n `${await renderUsage(cmd, isSub ? (main as CommandDef) : undefined)}\\n`,\n );\n process.exitCode ??= 0;\n return;\n }\n\n const { notice, refresh } = checkForUpdate(options.currentVersion ?? VERSION);\n if (notice) {\n reporter.info(notice);\n }\n\n const controller = new AbortController();\n const refreshPromise = refresh?.(controller.signal).catch(() => {});\n\n try {\n await runCommand(main, { rawArgs: argv });\n process.exitCode ??= 0;\n } catch (error) {\n if (error instanceof TakoError) {\n reporter.error(renderError(error));\n process.exitCode = 1;\n } else if (error instanceof Error && error.name === 'CLIError') {\n // citty usage error (unknown command, missing argument, …).\n reporter.error(error.message);\n process.exitCode = 1;\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n process.exitCode = 1;\n }\n } finally {\n controller.abort();\n await refreshPromise;\n }\n}\n","/**\n * `tako check` — drift guard. Runs the pipeline in plan mode (no disk writes,\n * no `afterEmit`), then compares the planned tree against what is on disk.\n * Exit 0 when they match, exit 1 on any drift or any `TakoError` (the latter\n * via the top-level handler in `cli.ts`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §Command surface.\n */\nimport { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport { loadConfig } from '@kurotako/config';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport {\n comparePlanToDisk,\n type DriftEntry,\n ignoreBuildArtifacts,\n markedPackageDirs,\n} from '../diff.js';\nimport { ConsoleReporter } from '../reporter.js';\n\nexport const checkCommand = defineCommand({\n meta: {\n name: 'check',\n description:\n 'check the generated output on disk matches a fresh generate (drift guard)',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const { config } = await loadConfig({\n cwd,\n configPath: args.config || undefined,\n });\n const { plan = [] } = await run(config, { logger: reporter, plan: true });\n\n const roots: string[] = [];\n const ignores: ((absPath: string) => boolean)[] = [];\n\n for (const output of config.outputs) {\n if (output.mode === 'package') {\n ignores.push(ignoreBuildArtifacts);\n if (output.packagesDir) {\n roots.push(...(await markedPackageDirs(output.packagesDir)));\n }\n } else {\n const dir = output.dir;\n if (!dir) {\n continue;\n }\n if (!existsSync(dir)) {\n reporter.info(\n `output directory ${relative(config.rootDir, dir)} does not exist — run tako generate`,\n );\n process.exitCode = 1;\n return;\n }\n roots.push(dir);\n }\n }\n\n const ignore = (absPath: string): boolean =>\n ignores.some((fn) => fn(absPath));\n\n const drift = await comparePlanToDisk({\n plan,\n roots,\n ignore,\n rootDir: config.rootDir,\n });\n\n if (drift.length === 0) {\n reporter.info('output is in sync');\n process.exitCode ??= 0;\n return;\n }\n\n reporter.error(formatDrift(drift));\n process.exitCode = 1;\n },\n});\n\nfunction formatDrift(drift: DriftEntry[]): string {\n const width = Math.max(...drift.map((entry) => entry.kind.length));\n const lines = drift.map(\n (entry) => ` ${entry.kind.padEnd(width)} ${entry.path}`,\n );\n return [\n 'drift detected',\n '',\n ...lines,\n '',\n `${drift.length} files differ from a fresh generate. Run \\`tako generate\\`.`,\n ].join('\\n');\n}\n","/**\n * `sharedArgs` — the options every sub-command carries. citty has no\n * first-class global-option slot, so this object is spread into each command's\n * `args` (`backlog/features/cli/technical.md` §Global option).\n */\nimport type { ArgsDef } from 'citty';\n\nexport const sharedArgs = {\n config: {\n type: 'string',\n description: 'path to the tako config file (default: ./tako.config.ts)',\n },\n /** Hidden: not advertised, kept minimal. Enables `debug` reporter output. */\n debug: {\n type: 'boolean',\n default: false,\n },\n} as const satisfies ArgsDef;\n","/**\n * `comparePlanToDisk` — the in-memory comparison behind `tako check`. Takes the\n * `PlannedFile[]` a fresh `generate` would write (from `run({ plan: true })`)\n * and reports every way the tree on disk diverges from it: a planned file that\n * is absent (`missing`) or whose bytes differ (`modified`), and any file under\n * the scanned roots that no planned file claims (`orphan`).\n *\n * Design: `backlog/features/drift-guard/technical.md` §The comparison.\n */\nimport { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PlannedFile } from '@kurotako/core';\n\nexport type DriftKind = 'modified' | 'missing' | 'orphan';\n\nexport interface DriftEntry {\n kind: DriftKind;\n /** Relative to `rootDir`, POSIX separators; a collapsed dir ends with `/`. */\n path: string;\n}\n\nexport interface ComparePlanToDiskArgs {\n plan: PlannedFile[];\n /** Directories walked for orphans (absolute). */\n roots: string[];\n /** Return `true` to exclude an absolute path from the orphan scan. */\n ignore: (absPath: string) => boolean;\n /** Anchor for the reported relative paths (the config-file directory). */\n rootDir: string;\n}\n\nfunction toPosix(rootDir: string, absPath: string): string {\n return path.relative(rootDir, absPath).split(path.sep).join('/');\n}\n\nexport async function comparePlanToDisk(\n args: ComparePlanToDiskArgs,\n): Promise<DriftEntry[]> {\n const { plan, roots, ignore, rootDir } = args;\n const plannedByPath = new Map(plan.map((f) => [path.resolve(f.path), f]));\n const entries: DriftEntry[] = [];\n\n // 1. Expected vs disk.\n for (const [absPath, file] of plannedByPath) {\n if (!existsSync(absPath)) {\n entries.push({ kind: 'missing', path: toPosix(rootDir, absPath) });\n continue;\n }\n const onDisk = await readFile(absPath, 'utf8');\n if (onDisk !== file.content) {\n entries.push({ kind: 'modified', path: toPosix(rootDir, absPath) });\n }\n }\n\n // 2. Orphan scan — a planned file lives under `dir` iff any planned absolute\n // path is `dir` itself or sits below it.\n const plannedPaths = [...plannedByPath.keys()];\n const hasPlannedUnder = (dir: string): boolean => {\n const prefix = `${dir}${path.sep}`;\n return plannedPaths.some((p) => p === dir || p.startsWith(prefix));\n };\n\n const seenRoots = new Set<string>();\n for (const root of roots) {\n const absRoot = path.resolve(root);\n if (seenRoots.has(absRoot) || !existsSync(absRoot)) {\n continue;\n }\n seenRoots.add(absRoot);\n await scan(absRoot);\n }\n\n async function scan(dir: string): Promise<void> {\n // A directory with no planned file underneath collapses to a single entry —\n // unless it holds nothing but ignored files (e.g. only `dist/`).\n if (!hasPlannedUnder(dir)) {\n if (await hasNonIgnoredFile(dir)) {\n entries.push({ kind: 'orphan', path: `${toPosix(rootDir, dir)}/` });\n }\n return;\n }\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isDirectory()) {\n await scan(abs);\n } else if (dirent.isFile() && !plannedByPath.has(abs)) {\n entries.push({ kind: 'orphan', path: toPosix(rootDir, abs) });\n }\n }\n }\n\n async function hasNonIgnoredFile(dir: string): Promise<boolean> {\n for (const dirent of await readdir(dir, { withFileTypes: true })) {\n const abs = path.join(dir, dirent.name);\n if (ignore(abs)) {\n continue;\n }\n if (dirent.isFile()) {\n return true;\n }\n if (dirent.isDirectory() && (await hasNonIgnoredFile(abs))) {\n return true;\n }\n }\n return false;\n }\n\n entries.sort((a, b) =>\n a.path < b.path\n ? -1\n : a.path > b.path\n ? 1\n : a.kind < b.kind\n ? -1\n : a.kind > b.kind\n ? 1\n : 0,\n );\n return entries;\n}\n\n/** Rejects `dist/` and `node_modules/` anywhere in the path (mode B). */\nexport function ignoreBuildArtifacts(absPath: string): boolean {\n return /(^|[/\\\\])(dist|node_modules)([/\\\\]|$)/.test(absPath);\n}\n\n/**\n * Whether `<packagesDir>/<name>` looks like a directory `tako` generated: a\n * `package.json` whose `\"//\"` marker starts with `Generated by tako`.\n */\nexport async function hasGeneratedMarker(pkgDir: string): Promise<boolean> {\n try {\n const pkg = JSON.parse(\n await readFile(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\n/** Every immediate subdirectory of `packagesDir` carrying the tako marker. */\nexport async function markedPackageDirs(\n packagesDir: string,\n): Promise<string[]> {\n if (!existsSync(packagesDir)) {\n return [];\n }\n const out: string[] = [];\n for (const dirent of await readdir(packagesDir, { withFileTypes: true })) {\n if (!dirent.isDirectory()) {\n continue;\n }\n const abs = path.join(packagesDir, dirent.name);\n if (await hasGeneratedMarker(abs)) {\n out.push(abs);\n }\n }\n return out.sort();\n}\n","/**\n * `ConsoleReporter` — the `@kurotako/core` `Logger` the CLI injects into\n * `loadConfig()` / `run()`, plus the per-phase / summary output.\n *\n * Contract (`backlog/features/cli/technical.md` §Reporter):\n * - human output goes to **stderr**, `stdout` stays clean;\n * - `info` / `warn` / `error` shown by default; `debug` only with `--debug` /\n * `TAKO_DEBUG` (a hidden flag, not advertised);\n * - the human-readable message is always shown; the structured `meta` object is\n * printed only with `--debug` (a custom `Logger` still receives it in full),\n * so default output stays prose, not `key=value` noise;\n * - `tako ` prefix, level-coloured; colour auto-off when the stream is not a TTY\n * or `NO_COLOR` is set;\n * - `child(tag)` returns a `Logger` tagging every `meta` with `{ scope: tag }`.\n */\nimport { childLogger, type Logger } from '@kurotako/core';\n\ntype Level = 'debug' | 'info' | 'warn' | 'error';\n\n/** The slice of a writable stream the reporter needs (keeps tests trivial). */\nexport interface WriteStream {\n write(chunk: string): unknown;\n isTTY?: boolean;\n}\n\nexport interface ConsoleReporterOptions {\n /** Show `debug` output. Default: `false` unless `TAKO_DEBUG` is set. */\n debug?: boolean;\n /** Sink for human output. Default: `process.stderr`. */\n stream?: WriteStream;\n /** Force colour on/off. Default: auto (TTY and no `NO_COLOR`). */\n color?: boolean;\n}\n\nconst ESC = String.fromCharCode(27);\nconst ANSI: Record<Level, string> = {\n debug: `${ESC}[2m`, // dim\n info: `${ESC}[36m`, // cyan\n warn: `${ESC}[33m`, // yellow\n error: `${ESC}[31m`, // red\n};\nconst ANSI_RESET = `${ESC}[0m`;\n\nexport class ConsoleReporter implements Logger {\n private readonly stream: WriteStream;\n private readonly showDebug: boolean;\n private readonly color: boolean;\n\n constructor(options: ConsoleReporterOptions = {}) {\n this.stream = options.stream ?? process.stderr;\n this.showDebug = options.debug ?? Boolean(process.env.TAKO_DEBUG);\n this.color =\n options.color ??\n (Boolean(this.stream.isTTY) && process.env.NO_COLOR === undefined);\n }\n\n debug(msg: string, meta?: unknown): void {\n if (this.showDebug) {\n this.write('debug', msg, meta);\n }\n }\n\n info(msg: string, meta?: unknown): void {\n this.write('info', msg, meta);\n }\n\n warn(msg: string, meta?: unknown): void {\n this.write('warn', msg, meta);\n }\n\n error(msg: string, meta?: unknown): void {\n this.write('error', msg, meta);\n }\n\n /** A child `Logger` whose calls carry `{ scope: tag }` in `meta`. */\n child(tag: string): Logger {\n return childLogger(this, { scope: tag });\n }\n\n private write(level: Level, msg: string, meta?: unknown): void {\n const prefix = this.color ? `${ANSI[level]}tako${ANSI_RESET}` : 'tako';\n const detail =\n meta === undefined || !this.showDebug ? '' : ` ${formatMeta(meta)}`;\n this.stream.write(`${prefix} ${msg}${detail}\\n`);\n }\n}\n\nfunction formatMeta(meta: unknown): string {\n if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {\n return Object.entries(meta as Record<string, unknown>)\n .map(([k, v]) => `${k}=${stringify(v)}`)\n .join(' ');\n }\n return stringify(meta);\n}\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n","/**\n * `tako generate` — `loadConfig()` then `run()`. `--dry-run` runs everything but\n * skips the Writer; `--watch` hands off to the chokidar loop\n * (`backlog/features/cli/technical.md` §`tako generate`).\n */\nimport { relative } from 'node:path';\nimport { type LoadResult, loadConfig } from '@kurotako/config';\nimport type { OutputConfig, ResolvedConfig, RunResult } from '@kurotako/core';\nimport { run } from '@kurotako/core';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { watchAndRun } from '../watch.js';\n\nexport interface LoadAndRunOptions {\n cwd: string;\n configPath?: string;\n write: boolean;\n signal?: AbortSignal;\n reporter: ConsoleReporter;\n}\n\nexport interface LoadAndRunResult {\n result: RunResult;\n config: ResolvedConfig;\n configFile: string;\n rootDir: string;\n}\n\n/** The directory named in the `wrote N files -> …` summary line, for one output. */\nexport function outputSummaryDir(\n output: OutputConfig,\n config: ResolvedConfig,\n): string {\n return output.mode === 'package'\n ? (output.packagesDir ?? config.rootDir)\n : (output.dir ?? config.rootDir);\n}\n\n/**\n * The shared body of `generate`, `validate` and each watch cycle: resolve +\n * load the config, then run the pipeline. `write: false` also skips the\n * `afterEmit` hook (`@kurotako/core` `run()`).\n */\nexport async function loadAndRun(\n opts: LoadAndRunOptions,\n): Promise<LoadAndRunResult> {\n const loaded: LoadResult = await loadConfig({\n cwd: opts.cwd,\n configPath: opts.configPath,\n });\n const result = await run(loaded.config, {\n logger: opts.reporter,\n write: opts.write,\n signal: opts.signal,\n });\n return {\n result,\n config: loaded.config,\n configFile: loaded.configFile,\n rootDir: loaded.rootDir,\n };\n}\n\nexport const generateCommand = defineCommand({\n meta: {\n name: 'generate',\n description: 'run the pipeline and write the generated code',\n },\n args: {\n ...sharedArgs,\n watch: {\n type: 'boolean',\n description: 'rebuild on every schema / config change',\n default: false,\n },\n 'dry-run': {\n type: 'boolean',\n description: 'run everything but write nothing',\n default: false,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n const configPath = args.config || undefined;\n\n if (args.watch) {\n await watchAndRun({ cwd, configPath, reporter });\n return;\n }\n\n const dryRun = Boolean(args['dry-run']);\n const { result, config } = await loadAndRun({\n cwd,\n configPath,\n write: !dryRun,\n reporter,\n });\n\n if (dryRun) {\n reporter.info(`dry run: ${result.files.length} files would be written`);\n return;\n }\n\n const dirs = config.outputs\n .map((output) => relative(cwd, outputSummaryDir(output, config)))\n .join(', ');\n reporter.info(`wrote ${result.files.length} files -> ${dirs}`);\n },\n});\n","/**\n * `tako generate --watch` — a chokidar loop around `loadConfig()` + `run()`.\n * Full regeneration on every change (no incremental). A 100 ms trailing\n * debounce coalesces bursts; a change mid-cycle aborts the in-flight `run()`\n * (via `RunOptions.signal`) and re-runs once it settles. `loadConfig` failures\n * are reported, not fatal — the watcher stays up on `tako.config.ts`.\n *\n * `backlog/features/cli/technical.md` §Watch mode.\n */\nimport { basename, resolve } from 'node:path';\nimport {\n type LoadResult,\n loadConfig as realLoadConfig,\n} from '@kurotako/config';\nimport { run as realRun, TakoError } from '@kurotako/core';\nimport chokidar from 'chokidar';\nimport { renderError } from './errors.js';\nimport type { ConsoleReporter } from './reporter.js';\n\n/** Minimal watcher seam so the loop is unit-testable without touching the fs. */\nexport interface Watcher {\n add(paths: string | readonly string[]): void;\n unwatch(paths: string | readonly string[]): void;\n on(handler: (event: string, path: string) => void): void;\n close(): Promise<void>;\n}\n\nexport interface WatchAndRunOptions {\n cwd: string;\n configPath?: string;\n reporter: ConsoleReporter;\n}\n\nexport interface WatchDeps {\n createWatcher: () => Watcher;\n loadConfig: typeof realLoadConfig;\n run: typeof realRun;\n debounceMs: number;\n}\n\nconst DEBOUNCE_MS = 100;\n\nfunction chokidarWatcher(): Watcher {\n const fsw = chokidar.watch([], {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 20 },\n });\n return {\n add: (paths) => fsw.add(paths as string | string[]),\n unwatch: (paths) => fsw.unwatch(paths as string | string[]),\n on: (handler) => {\n fsw.on('add', (p) => handler('add', p));\n fsw.on('change', (p) => handler('change', p));\n fsw.on('unlink', (p) => handler('unlink', p));\n },\n close: () => fsw.close(),\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError';\n}\n\n/**\n * Runs until `SIGINT` / `SIGTERM`, then closes the watcher and resolves so the\n * caller can exit 0. (The design doc types this `Promise<never>`; it resolves\n * on shutdown here purely so it stays testable.)\n */\nexport async function watchAndRun(\n opts: WatchAndRunOptions,\n deps: Partial<WatchDeps> = {},\n): Promise<void> {\n const { cwd, configPath, reporter } = opts;\n const createWatcher = deps.createWatcher ?? chokidarWatcher;\n const loadConfig = deps.loadConfig ?? realLoadConfig;\n const run = deps.run ?? realRun;\n const debounceMs = deps.debounceMs ?? DEBOUNCE_MS;\n\n const watcher = createWatcher();\n let watched = new Set<string>();\n let inFlight: AbortController | null = null;\n let queued = false;\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let reason = 'initial build';\n\n const guessedConfigFile = configPath\n ? resolve(cwd, configPath)\n : resolve(cwd, 'tako.config.ts');\n\n function applyWatchSet(desired: Set<string>): void {\n for (const path of desired) {\n if (!watched.has(path)) {\n watcher.add(path);\n }\n }\n for (const path of watched) {\n if (!desired.has(path)) {\n watcher.unwatch(path);\n }\n }\n watched = desired;\n }\n\n async function reconcileWatchSet(loaded: LoadResult): Promise<void> {\n const desired = new Set<string>([loaded.configFile]);\n for (const [namespace, source] of Object.entries(loaded.config.sources)) {\n const paths =\n (await source.parser.watchPaths?.({\n namespace,\n cwd: loaded.rootDir,\n logger: reporter,\n })) ?? [];\n for (const path of paths) {\n desired.add(resolve(loaded.rootDir, path));\n }\n }\n applyWatchSet(desired);\n }\n\n async function cycle(): Promise<void> {\n const why = reason;\n reporter.info(`--- rebuild (${why}) ---`);\n const ac = new AbortController();\n inFlight = ac;\n try {\n const loaded = await loadConfig({ cwd, configPath });\n await reconcileWatchSet(loaded);\n const result = await run(loaded.config, {\n logger: reporter,\n signal: ac.signal,\n write: true,\n });\n if (!ac.signal.aborted) {\n reporter.info(`wrote ${result.files.length} files`);\n }\n } catch (error) {\n if (isAbortError(error) || ac.signal.aborted) {\n // Superseded by a newer cycle — swallow.\n } else if (error instanceof TakoError) {\n reporter.error(renderError(error));\n // Keep watching at least the config file so a fix is picked up.\n applyWatchSet(new Set([...watched, guessedConfigFile]));\n } else {\n reporter.error('internal error (this is a bug):');\n console.error(error);\n }\n } finally {\n inFlight = null;\n if (queued && !closed) {\n queued = false;\n await cycle();\n }\n }\n }\n\n function trigger(): void {\n if (inFlight) {\n queued = true;\n inFlight.abort();\n return;\n }\n void cycle();\n }\n\n function schedule(event: string, path: string): void {\n if (closed) {\n return;\n }\n reason = `${basename(path)} ${event === 'unlink' ? 'removed' : 'changed'}`;\n if (timer) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n timer = null;\n trigger();\n }, debounceMs);\n }\n\n watcher.on(schedule);\n\n // Initial cycle: a failure is reported inside `cycle()`, never fatal.\n applyWatchSet(new Set([guessedConfigFile]));\n await cycle();\n reporter.info(`watching ${watched.size} paths`);\n\n await new Promise<void>((resolvePromise) => {\n const shutdown = () => {\n closed = true;\n if (timer) {\n clearTimeout(timer);\n }\n inFlight?.abort();\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n void watcher.close().finally(() => resolvePromise());\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n}\n","/**\n * CLI-owned error(s) and `renderError()` — the single formatter the top-level\n * handler in `cli.ts` uses for any `TakoError` (from `@kurotako/core`,\n * `@kurotako/config`, or this package).\n *\n * `backlog/features/cli/technical.md` §Errors and exit codes.\n */\nimport { TakoError } from '@kurotako/core';\n\n/** `tako init` refuses to overwrite an existing config unless `--force`. */\nexport class ConfigExistsError extends TakoError {\n readonly path: string;\n\n constructor(path: string) {\n super(\n 'config_exists',\n `a config file already exists at '${path}' (pass --force to overwrite)`,\n );\n this.path = path;\n }\n}\n\ninterface Issue {\n path?: string;\n message?: string;\n}\n\n/**\n * `error [<code>]: <message>` plus any carried context on its own indented\n * lines: located issues (`ConfigShapeError`, `IrValidationError`,\n * `DriverOptionsError`), the offending driver / namespace (`DriverError`,\n * `UnknownNamespaceError`), the dependency cycle path (`DependencyCycleError`),\n * and the `cause` message of a wrapped failure.\n */\nexport function renderError(error: TakoError): string {\n const lines = [`error [${error.code}]: ${error.message}`];\n\n const issues = (error as { issues?: unknown }).issues;\n if (Array.isArray(issues)) {\n for (const issue of issues as Issue[]) {\n const at =\n issue.path === undefined || issue.path === '' ? '<root>' : issue.path;\n lines.push(` - ${at}: ${issue.message}`);\n }\n }\n\n const cycle = (error as { cycle?: unknown }).cycle;\n if (Array.isArray(cycle) && cycle.length > 0) {\n lines.push(` cycle: ${(cycle as string[]).join(' -> ')}`);\n }\n\n const driverName = (error as { driverName?: unknown }).driverName;\n if (typeof driverName === 'string') {\n const role = (error as { role?: unknown }).role;\n const namespace = (error as { namespace?: unknown }).namespace;\n const roleLabel = typeof role === 'string' ? role : 'driver';\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` ${roleLabel}: ${driverName}${where}`);\n } else {\n const generator = (error as { generator?: unknown }).generator;\n if (typeof generator === 'string') {\n const namespace = (error as { namespace?: unknown }).namespace;\n const where =\n typeof namespace === 'string' ? ` (namespace '${namespace}')` : '';\n lines.push(` generator: ${generator}${where}`);\n }\n }\n\n // Wrapped failures (`DriverError`, `HookError`, `ConfigLoadError`, …) carry the\n // real error in `cause`; core masks its type, so surface at least its message.\n const cause = error.cause;\n if (cause !== undefined && cause !== null) {\n const message = cause instanceof Error ? cause.message : String(cause);\n const code = cause instanceof TakoError ? ` [${cause.code}]` : '';\n lines.push(` cause${code}: ${message}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * `tako init` — write the commented `tako.config.ts` skeleton into the current\n * directory. No prompts, no schema auto-detection; refuses to overwrite unless\n * `--force` (`backlog/features/cli/technical.md` §`tako init`).\n *\n * `--monorepo` / `--no-monorepo` picks between `CONFIG_TEMPLATE` and\n * `CONFIG_TEMPLATE_MONOREPO`; unset, it auto-detects a workspace by walking up\n * for the nearest `package.json` (`workspaces` key, or a sibling\n * `pnpm-workspace.yaml`).\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative, resolve } from 'node:path';\nimport { CONFIG_TEMPLATE, CONFIG_TEMPLATE_MONOREPO } from '@kurotako/config';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConfigExistsError } from '../errors.js';\nimport { ConsoleReporter } from '../reporter.js';\n\n/**\n * Walk up from `startDir` to the first directory holding a `package.json`. A\n * workspace when that `package.json` has a `workspaces` key (array, or\n * `{ packages: [...] }`), or when a `pnpm-workspace.yaml` sits next to it.\n * Returns `false` when no `package.json` is found.\n */\nfunction detectMonorepo(startDir: string): boolean {\n let dir = resolve(startDir);\n while (true) {\n const pkgPath = resolve(dir, 'package.json');\n if (existsSync(pkgPath)) {\n if (existsSync(resolve(dir, 'pnpm-workspace.yaml'))) {\n return true;\n }\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n workspaces?: unknown;\n };\n const ws = pkg.workspaces;\n if (\n Array.isArray(ws) ||\n (typeof ws === 'object' &&\n ws !== null &&\n Array.isArray((ws as { packages?: unknown }).packages))\n ) {\n return true;\n }\n } catch {\n // Unreadable / invalid package.json: treat as not a workspace.\n }\n return false;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return false;\n }\n dir = parent;\n }\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'create a tako.config.ts in the current directory',\n },\n args: {\n ...sharedArgs,\n force: {\n type: 'boolean',\n description: 'overwrite an existing config file',\n default: false,\n },\n monorepo: {\n type: 'boolean',\n description:\n 'write the monorepo config layout (auto-detected from workspaces when unset)',\n default: undefined,\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n // Unlike `loadConfig`, `init` never walks up: it always targets `cwd`.\n const target = args.config\n ? resolve(cwd, args.config)\n : resolve(cwd, 'tako.config.ts');\n\n if (existsSync(target) && !args.force) {\n throw new ConfigExistsError(target);\n }\n\n // citty leaves an unset boolean flag `undefined` (no `default`), so\n // `--monorepo` / `--no-monorepo` win and absence falls back to detection.\n const monorepo: boolean =\n typeof args.monorepo === 'boolean' ? args.monorepo : detectMonorepo(cwd);\n\n await mkdir(dirname(target), { recursive: true });\n await writeFile(\n target,\n monorepo ? CONFIG_TEMPLATE_MONOREPO : CONFIG_TEMPLATE,\n 'utf8',\n );\n\n const name = relative(cwd, target) || 'tako.config.ts';\n reporter.info(\n monorepo ? `created ${name} (monorepo layout)` : `created ${name}`,\n );\n },\n});\n","/**\n * `tako outdated` — on-demand check of the installed `@kurotako/*` packages\n * in the target project against the npm registry. Informational only, always\n * exits 0.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §`tako outdated`\n * command.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { compareVersions } from '../version-check.js';\n\ninterface PackageEntry {\n name: string;\n installed: string | undefined;\n latest: string | undefined;\n}\n\nfunction findProjectPackageJson(cwd: string): string | undefined {\n let dir = resolve(cwd);\n while (true) {\n const candidate = resolve(dir, 'package.json');\n if (existsSync(candidate)) {\n return candidate;\n }\n if (existsSync(resolve(dir, '.git'))) {\n return undefined;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return undefined;\n }\n dir = parent;\n }\n}\n\nfunction collectKurotakoDependencies(packageJsonPath: string): string[] {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const names = new Set([\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ]);\n return [...names].filter((name) => name.startsWith('@kurotako/')).sort();\n}\n\nfunction resolveInstalledVersion(\n packageJsonPath: string,\n name: string,\n): string | undefined {\n try {\n const require = createRequire(packageJsonPath);\n // Packages only export their main entry point, not \"./package.json\"\n // (blocked by their `exports` field), so walk the same node_modules\n // lookup path Node would use and read the package.json directly instead\n // of going through module resolution.\n const searchPaths = require.resolve.paths(name) ?? [];\n for (const modulesDir of searchPaths) {\n const candidate = resolve(modulesDir, name, 'package.json');\n if (existsSync(candidate)) {\n const pkg = JSON.parse(readFileSync(candidate, 'utf8')) as {\n version?: string;\n };\n\n return pkg.version;\n }\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function fetchLatestVersion(name: string): Promise<string | undefined> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${name}/latest`);\n if (!response.ok) {\n return undefined;\n }\n const body = (await response.json()) as { version?: unknown };\n return typeof body.version === 'string' ? body.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction formatTable(entries: PackageEntry[]): string {\n const rows = entries.map((entry) => ({\n name: entry.name,\n installed: entry.installed ?? 'unknown',\n latest: entry.latest ?? 'unknown',\n status:\n entry.installed === undefined || entry.latest === undefined\n ? 'unknown'\n : compareVersions(entry.latest, entry.installed) > 0\n ? 'outdated'\n : 'up to date',\n }));\n\n const widths = {\n name: Math.max(7, ...rows.map((r) => r.name.length)),\n installed: Math.max(9, ...rows.map((r) => r.installed.length)),\n latest: Math.max(6, ...rows.map((r) => r.latest.length)),\n };\n\n const header = ` ${'package'.padEnd(widths.name)} ${'installed'.padEnd(widths.installed)} ${'latest'.padEnd(widths.latest)} status`;\n const lines = rows.map(\n (r) =>\n ` ${r.name.padEnd(widths.name)} ${r.installed.padEnd(widths.installed)} ${r.latest.padEnd(widths.latest)} ${r.status}`,\n );\n\n return [header, ...lines].join('\\n');\n}\n\nexport const outdatedCommand = defineCommand({\n meta: {\n name: 'outdated',\n description:\n 'check installed @kurotako/* packages against the npm registry',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n\n const packageJsonPath = findProjectPackageJson(cwd);\n if (!packageJsonPath) {\n reporter.error('no package.json found (searched up to the project root)');\n process.exitCode ??= 0;\n return;\n }\n\n const names = collectKurotakoDependencies(packageJsonPath);\n if (names.length === 0) {\n reporter.info('no @kurotako/* dependency found');\n process.exitCode ??= 0;\n return;\n }\n\n const entries: PackageEntry[] = await Promise.all(\n names.map(async (name) => ({\n name,\n installed: resolveInstalledVersion(packageJsonPath, name),\n latest: await fetchLatestVersion(name),\n })),\n );\n\n reporter.info(`tako outdated\\n${formatTable(entries)}`);\n process.exitCode ??= 0;\n },\n});\n","/**\n * Background version check for the `tako` binary — compares the installed\n * `kurotako` version against the npm registry, cached for 8h so most\n * invocations do not hit the network.\n *\n * Design: `backlog/features/cli-self-update/technical.md` §Background version\n * check.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst REGISTRY_URL = 'https://registry.npmjs.org/kurotako/latest';\nconst TTL_MS = 8 * 60 * 60 * 1000;\n\nexport interface VersionCacheEntry {\n checkedAt: number;\n latestVersion: string;\n}\n\nexport function getCacheFilePath(): string {\n const base = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');\n return join(base, 'tako', 'version-check.json');\n}\n\nexport function readCache(): VersionCacheEntry | undefined {\n try {\n const raw = readFileSync(getCacheFilePath(), 'utf8');\n const parsed = JSON.parse(raw) as Partial<VersionCacheEntry>;\n if (\n typeof parsed.checkedAt === 'number' &&\n typeof parsed.latestVersion === 'string'\n ) {\n return {\n checkedAt: parsed.checkedAt,\n latestVersion: parsed.latestVersion,\n };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function writeCache(entry: VersionCacheEntry): void {\n const path = getCacheFilePath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(entry));\n}\n\nexport async function refreshLatestVersion(\n signal: AbortSignal,\n): Promise<string> {\n const response = await fetch(REGISTRY_URL, { signal });\n if (!response.ok) {\n throw new Error(`registry request failed with status ${response.status}`);\n }\n const body = (await response.json()) as { version?: unknown };\n if (typeof body.version !== 'string') {\n throw new Error('registry response is missing a version string');\n }\n return body.version;\n}\n\n/**\n * `-1` when `a` is older than `b`, `0` when equal, `1` when newer. Handles\n * `major.minor.patch` plus an optional `-prerelease` suffix (a release always\n * outranks a prerelease of the same `major.minor.patch`).\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const [aMajor, aMinor, aPatch, aPre] = splitVersion(a);\n const [bMajor, bMinor, bPatch, bPre] = splitVersion(b);\n\n if (aMajor !== bMajor) {\n return aMajor < bMajor ? -1 : 1;\n }\n if (aMinor !== bMinor) {\n return aMinor < bMinor ? -1 : 1;\n }\n if (aPatch !== bPatch) {\n return aPatch < bPatch ? -1 : 1;\n }\n\n if (aPre === bPre) {\n return 0;\n }\n if (aPre === undefined) {\n return 1;\n }\n if (bPre === undefined) {\n return -1;\n }\n return aPre < bPre ? -1 : 1;\n}\n\nfunction splitVersion(\n version: string,\n): [major: number, minor: number, patch: number, pre?: string] {\n const [core = '', ...rest] = version.split('-');\n const [major = 0, minor = 0, patch = 0] = core\n .split('.')\n .map((n) => Number.parseInt(n, 10) || 0);\n return [major, minor, patch, rest.length > 0 ? rest.join('-') : undefined];\n}\n\nexport interface CheckForUpdateResult {\n notice?: string;\n refresh?: (signal: AbortSignal) => Promise<void>;\n}\n\nexport function checkForUpdate(currentVersion: string): CheckForUpdateResult {\n const cache = readCache();\n const result: CheckForUpdateResult = {};\n\n if (cache && compareVersions(cache.latestVersion, currentVersion) > 0) {\n result.notice = `tako a new version of kurotako is available: ${currentVersion} → ${cache.latestVersion} (npm i kurotako@latest)`;\n }\n\n const isStale = cache === undefined || Date.now() - cache.checkedAt > TTL_MS;\n if (isStale) {\n result.refresh = async (signal: AbortSignal) => {\n const latestVersion = await refreshLatestVersion(signal);\n writeCache({ checkedAt: Date.now(), latestVersion });\n };\n }\n\n return result;\n}\n","/**\n * `tako validate` — the same checks as `generate` up to (not including)\n * emission. `loadConfig()` + `run({ write: false })`; any `TakoError` propagates\n * to the top-level handler and exits 1\n * (`backlog/features/cli/technical.md` §`tako validate`).\n */\nimport { defineCommand } from 'citty';\nimport { sharedArgs } from '../args.js';\nimport { ConsoleReporter } from '../reporter.js';\nimport { loadAndRun } from './generate.js';\n\nexport const validateCommand = defineCommand({\n meta: {\n name: 'validate',\n description: 'check the config and schema without writing anything',\n },\n args: { ...sharedArgs },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n await loadAndRun({\n cwd: process.cwd(),\n configPath: args.config || undefined,\n write: false,\n reporter,\n });\n reporter.info('config and schema are valid');\n },\n});\n"],"mappings":"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","names":["TakoError","defineCommand","existsSync","existsSync","relative","loadConfig","run","defineCommand","TakoError","path","loadConfig","run","path","TakoError","loadConfig","run","defineCommand","relative","existsSync","relative","resolve","defineCommand","resolve","existsSync","defineCommand","relative","existsSync","readFileSync","dirname","resolve","defineCommand","readFileSync","dirname","path","resolve","existsSync","dirname","readFileSync","require","defineCommand","defineCommand","defineCommand","defineCommand","TakoError"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurotako/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "The tako command-line interface for kurotako.",
5
5
  "keywords": [
6
6
  "kurotako",
@@ -56,8 +56,8 @@
56
56
  "citty": "0.2.2"
57
57
  },
58
58
  "devDependencies": {
59
- "@kurotako/gen-typescript": "^0.3.3",
60
- "@kurotako/gen-zod": "^0.3.4",
59
+ "@kurotako/gen-typescript": "^0.3.4",
60
+ "@kurotako/gen-zod": "^0.3.5",
61
61
  "@kurotako/parser-prisma": "^0.2.3"
62
62
  }
63
63
  }