@kurotako/cli 0.2.2 → 0.3.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,25 @@
1
1
  # @kurotako/cli
2
2
 
3
+ ## 0.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [147a177]
8
+ - @kurotako/core@0.4.0
9
+ - @kurotako/config@0.2.1
10
+
11
+ ## 0.3.0
12
+
13
+ ### Minor Changes
14
+
15
+ - fba5a64: Add `tako init --package-base [--packages-dir <dir>]`, which scaffolds the `tsconfig.base.json` and `tsup.config.base.ts` that mode `package` requires, without overwriting existing files. `@kurotako/core` exports the two templates (`PACKAGE_TSCONFIG_BASE`, `PACKAGE_TSUP_CONFIG_BASE`).
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [fba5a64]
20
+ - Updated dependencies [fba5a64]
21
+ - @kurotako/core@0.3.1
22
+
3
23
  ## 0.2.2
4
24
 
5
25
  ### Patch Changes
package/README.md CHANGED
@@ -21,6 +21,7 @@ Needs **Node.js >= 24**; runs unmodified on Node and Bun.
21
21
 
22
22
  ```text
23
23
  tako init [--config <path>] [--force] [--monorepo | --no-monorepo]
24
+ tako init --package-base [--packages-dir <dir>]
24
25
  tako generate [--config <path>] [--watch] [--dry-run]
25
26
  tako validate [--config <path>]
26
27
  tako check [--config <path>]
package/dist/bin/tako.js CHANGED
@@ -528,6 +528,10 @@ import { existsSync as existsSync3, readFileSync } from "fs";
528
528
  import { mkdir, writeFile } from "fs/promises";
529
529
  import { dirname, relative as relative3, resolve as resolve2 } from "path";
530
530
  import { CONFIG_TEMPLATE, CONFIG_TEMPLATE_MONOREPO } from "@kurotako/config";
531
+ import {
532
+ PACKAGE_TSCONFIG_BASE,
533
+ PACKAGE_TSUP_CONFIG_BASE
534
+ } from "@kurotako/core";
531
535
  import { defineCommand as defineCommand3 } from "citty";
532
536
  function detectMonorepo(startDir) {
533
537
  let dir = resolve2(startDir);
@@ -554,10 +558,33 @@ function detectMonorepo(startDir) {
554
558
  dir = parent;
555
559
  }
556
560
  }
561
+ var TSUP_BASE_EXTENSIONS = [".ts", ".js", ".mjs", ".cjs"];
562
+ async function scaffoldPackageBase(packagesDir, reporter, cwd) {
563
+ const workspaceRoot = dirname(resolve2(cwd, packagesDir));
564
+ const shown = (path2) => relative3(cwd, path2) || path2;
565
+ const tsconfig = resolve2(workspaceRoot, "tsconfig.base.json");
566
+ const tsup = resolve2(workspaceRoot, "tsup.config.base.ts");
567
+ const tsupExisting = TSUP_BASE_EXTENSIONS.map(
568
+ (ext) => resolve2(workspaceRoot, `tsup.config.base${ext}`)
569
+ ).find((path2) => existsSync3(path2));
570
+ await mkdir(workspaceRoot, { recursive: true });
571
+ if (existsSync3(tsconfig)) {
572
+ reporter.info(`kept existing ${shown(tsconfig)}`);
573
+ } else {
574
+ await writeFile(tsconfig, PACKAGE_TSCONFIG_BASE, "utf8");
575
+ reporter.info(`created ${shown(tsconfig)}`);
576
+ }
577
+ if (tsupExisting) {
578
+ reporter.info(`kept existing ${shown(tsupExisting)}`);
579
+ } else {
580
+ await writeFile(tsup, PACKAGE_TSUP_CONFIG_BASE, "utf8");
581
+ reporter.info(`created ${shown(tsup)}`);
582
+ }
583
+ }
557
584
  var initCommand = defineCommand3({
558
585
  meta: {
559
586
  name: "init",
560
- description: "create a tako.config.ts in the current directory"
587
+ description: "create a tako.config.ts in the current directory, or with --package-base the workspace files mode 'package' requires"
561
588
  },
562
589
  args: {
563
590
  ...sharedArgs,
@@ -570,11 +597,25 @@ var initCommand = defineCommand3({
570
597
  type: "boolean",
571
598
  description: "write the monorepo config layout (auto-detected from workspaces when unset)",
572
599
  default: void 0
600
+ },
601
+ "package-base": {
602
+ type: "boolean",
603
+ description: "instead of the config, create tsconfig.base.json and tsup.config.base.ts (mode 'package') one level above --packages-dir; never overwrites",
604
+ default: false
605
+ },
606
+ "packages-dir": {
607
+ type: "string",
608
+ description: "the output 'packagesDir' for --package-base",
609
+ default: "./packages"
573
610
  }
574
611
  },
575
612
  run: async ({ args }) => {
576
613
  const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });
577
614
  const cwd = process.cwd();
615
+ if (args["package-base"]) {
616
+ await scaffoldPackageBase(String(args["packages-dir"]), reporter, cwd);
617
+ return;
618
+ }
578
619
  const target = args.config ? resolve2(cwd, args.config) : resolve2(cwd, "tako.config.ts");
579
620
  if (existsSync3(target) && !args.force) {
580
621
  throw new ConfigExistsError(target);
@@ -811,7 +852,7 @@ var validateCommand = defineCommand5({
811
852
  });
812
853
 
813
854
  // src/cli.ts
814
- var VERSION = true ? "0.2.2" : "0.0.0-dev";
855
+ var VERSION = true ? "0.3.1" : "0.0.0-dev";
815
856
  var subCommands = {
816
857
  init: initCommand,
817
858
  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/_archives/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/_archives/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 {\n PACKAGE_TSCONFIG_BASE,\n PACKAGE_TSUP_CONFIG_BASE,\n} from '@kurotako/core';\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\nconst TSUP_BASE_EXTENSIONS = ['.ts', '.js', '.mjs', '.cjs'];\n\n/**\n * Scaffold the two files mode `package` requires one level above `packagesDir`.\n * Never overwrites: a file that already exists (any `tsup.config.base.*`\n * extension) is reported and left untouched.\n */\nasync function scaffoldPackageBase(\n packagesDir: string,\n reporter: ConsoleReporter,\n cwd: string,\n): Promise<void> {\n const workspaceRoot = dirname(resolve(cwd, packagesDir));\n const shown = (path: string) => relative(cwd, path) || path;\n const tsconfig = resolve(workspaceRoot, 'tsconfig.base.json');\n const tsup = resolve(workspaceRoot, 'tsup.config.base.ts');\n const tsupExisting = TSUP_BASE_EXTENSIONS.map((ext) =>\n resolve(workspaceRoot, `tsup.config.base${ext}`),\n ).find((path) => existsSync(path));\n\n await mkdir(workspaceRoot, { recursive: true });\n if (existsSync(tsconfig)) {\n reporter.info(`kept existing ${shown(tsconfig)}`);\n } else {\n await writeFile(tsconfig, PACKAGE_TSCONFIG_BASE, 'utf8');\n reporter.info(`created ${shown(tsconfig)}`);\n }\n if (tsupExisting) {\n reporter.info(`kept existing ${shown(tsupExisting)}`);\n } else {\n await writeFile(tsup, PACKAGE_TSUP_CONFIG_BASE, 'utf8');\n reporter.info(`created ${shown(tsup)}`);\n }\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description:\n \"create a tako.config.ts in the current directory, or with --package-base the workspace files mode 'package' requires\",\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 'package-base': {\n type: 'boolean',\n description:\n \"instead of the config, create tsconfig.base.json and tsup.config.base.ts (mode 'package') one level above --packages-dir; never overwrites\",\n default: false,\n },\n 'packages-dir': {\n type: 'string',\n description: \"the output 'packagesDir' for --package-base\",\n default: './packages',\n },\n },\n run: async ({ args }) => {\n const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });\n const cwd = process.cwd();\n if (args['package-base']) {\n await scaffoldPackageBase(String(args['packages-dir']), reporter, cwd);\n return;\n }\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/_archives/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/_archives/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","path","relative","defineCommand","existsSync","readFileSync","dirname","resolve","defineCommand","readFileSync","dirname","path","resolve","existsSync","dirname","readFileSync","require","defineCommand","defineCommand","defineCommand","defineCommand","TakoError"]}
package/dist/index.cjs CHANGED
@@ -45,7 +45,7 @@ __export(index_exports, {
45
45
  module.exports = __toCommonJS(index_exports);
46
46
 
47
47
  // src/cli.ts
48
- var import_core6 = require("@kurotako/core");
48
+ var import_core7 = require("@kurotako/core");
49
49
  var import_citty6 = require("citty");
50
50
 
51
51
  // src/commands/check.ts
@@ -570,6 +570,7 @@ var import_node_fs3 = require("fs");
570
570
  var import_promises2 = require("fs/promises");
571
571
  var import_node_path5 = require("path");
572
572
  var import_config4 = require("@kurotako/config");
573
+ var import_core6 = require("@kurotako/core");
573
574
  var import_citty3 = require("citty");
574
575
  function detectMonorepo(startDir) {
575
576
  let dir = (0, import_node_path5.resolve)(startDir);
@@ -596,10 +597,33 @@ function detectMonorepo(startDir) {
596
597
  dir = parent;
597
598
  }
598
599
  }
600
+ var TSUP_BASE_EXTENSIONS = [".ts", ".js", ".mjs", ".cjs"];
601
+ async function scaffoldPackageBase(packagesDir, reporter, cwd) {
602
+ const workspaceRoot = (0, import_node_path5.dirname)((0, import_node_path5.resolve)(cwd, packagesDir));
603
+ const shown = (path2) => (0, import_node_path5.relative)(cwd, path2) || path2;
604
+ const tsconfig = (0, import_node_path5.resolve)(workspaceRoot, "tsconfig.base.json");
605
+ const tsup = (0, import_node_path5.resolve)(workspaceRoot, "tsup.config.base.ts");
606
+ const tsupExisting = TSUP_BASE_EXTENSIONS.map(
607
+ (ext) => (0, import_node_path5.resolve)(workspaceRoot, `tsup.config.base${ext}`)
608
+ ).find((path2) => (0, import_node_fs3.existsSync)(path2));
609
+ await (0, import_promises2.mkdir)(workspaceRoot, { recursive: true });
610
+ if ((0, import_node_fs3.existsSync)(tsconfig)) {
611
+ reporter.info(`kept existing ${shown(tsconfig)}`);
612
+ } else {
613
+ await (0, import_promises2.writeFile)(tsconfig, import_core6.PACKAGE_TSCONFIG_BASE, "utf8");
614
+ reporter.info(`created ${shown(tsconfig)}`);
615
+ }
616
+ if (tsupExisting) {
617
+ reporter.info(`kept existing ${shown(tsupExisting)}`);
618
+ } else {
619
+ await (0, import_promises2.writeFile)(tsup, import_core6.PACKAGE_TSUP_CONFIG_BASE, "utf8");
620
+ reporter.info(`created ${shown(tsup)}`);
621
+ }
622
+ }
599
623
  var initCommand = (0, import_citty3.defineCommand)({
600
624
  meta: {
601
625
  name: "init",
602
- description: "create a tako.config.ts in the current directory"
626
+ description: "create a tako.config.ts in the current directory, or with --package-base the workspace files mode 'package' requires"
603
627
  },
604
628
  args: {
605
629
  ...sharedArgs,
@@ -612,11 +636,25 @@ var initCommand = (0, import_citty3.defineCommand)({
612
636
  type: "boolean",
613
637
  description: "write the monorepo config layout (auto-detected from workspaces when unset)",
614
638
  default: void 0
639
+ },
640
+ "package-base": {
641
+ type: "boolean",
642
+ description: "instead of the config, create tsconfig.base.json and tsup.config.base.ts (mode 'package') one level above --packages-dir; never overwrites",
643
+ default: false
644
+ },
645
+ "packages-dir": {
646
+ type: "string",
647
+ description: "the output 'packagesDir' for --package-base",
648
+ default: "./packages"
615
649
  }
616
650
  },
617
651
  run: async ({ args }) => {
618
652
  const reporter = new ConsoleReporter({ debug: Boolean(args.debug) });
619
653
  const cwd = process.cwd();
654
+ if (args["package-base"]) {
655
+ await scaffoldPackageBase(String(args["packages-dir"]), reporter, cwd);
656
+ return;
657
+ }
620
658
  const target = args.config ? (0, import_node_path5.resolve)(cwd, args.config) : (0, import_node_path5.resolve)(cwd, "tako.config.ts");
621
659
  if ((0, import_node_fs3.existsSync)(target) && !args.force) {
622
660
  throw new ConfigExistsError(target);
@@ -853,7 +891,7 @@ var validateCommand = (0, import_citty5.defineCommand)({
853
891
  });
854
892
 
855
893
  // src/cli.ts
856
- var VERSION = true ? "0.2.2" : "0.0.0-dev";
894
+ var VERSION = true ? "0.3.1" : "0.0.0-dev";
857
895
  var subCommands = {
858
896
  init: initCommand,
859
897
  generate: generateCommand,
@@ -901,7 +939,7 @@ async function runCli(argv, options = {}) {
901
939
  await (0, import_citty6.runCommand)(main, { rawArgs: argv });
902
940
  process.exitCode ??= 0;
903
941
  } catch (error) {
904
- if (error instanceof import_core6.TakoError) {
942
+ if (error instanceof import_core7.TakoError) {
905
943
  reporter.error(renderError(error));
906
944
  process.exitCode = 1;
907
945
  } else if (error instanceof Error && error.name === "CLIError") {