create-theokit 1.19.0 → 1.20.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/dist/cli.js
CHANGED
|
@@ -303,7 +303,12 @@ var SURFACE_CONFIG = {
|
|
|
303
303
|
lowlight: "^3.0.0"
|
|
304
304
|
},
|
|
305
305
|
devDeps: { tsx: "^4.19.0" },
|
|
306
|
-
scripts: {
|
|
306
|
+
scripts: {
|
|
307
|
+
dev: "tsx tui/main.tsx",
|
|
308
|
+
start: "tsx tui/main.tsx",
|
|
309
|
+
// A visual reference of every tool render state (pending/running/success/failed/…) — no agent needed.
|
|
310
|
+
"demo:tools": "tsx tui/tool-variations.tsx"
|
|
311
|
+
},
|
|
307
312
|
tsconfigInclude: [
|
|
308
313
|
"tui/**/*.ts",
|
|
309
314
|
"tui/**/*.tsx",
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/install.ts","../src/pkg-manager.ts","../src/preflight-node.ts","../src/prompts.ts","../src/scaffold-services.ts","../src/scaffold-surface.ts","../src/index.ts","../src/bare-transform.ts"],"sourcesContent":["import { execSync } from 'node:child_process'\nimport {\n readFileSync,\n writeFileSync,\n unlinkSync,\n mkdirSync,\n renameSync,\n existsSync,\n rmSync,\n} from 'node:fs'\nimport { resolve, join } from 'node:path'\n\nimport { runInstall } from './install.js'\nimport { detectPkgManager, type PkgManager } from './pkg-manager.js'\nimport { assertNodeVersion } from './preflight-node.js'\nimport { runPrompts, getDefaults, type ProjectOptions } from './prompts.js'\nimport { parseBackendFlags, scaffoldServices, type BackendKind } from './scaffold-services.js'\nimport { applySurface, parseSurfaceFlags, type SurfaceKind } from './scaffold-surface.js'\n\nimport { scaffold } from './index.js'\n\nconst VERSION = '0.8.0'\n\nfunction getFlag(args: string[], name: string): string | undefined {\n const flag = args.find((a) => a.startsWith(`--${name}=`))\n return flag ? flag.split('=')[1] : undefined\n}\n\nfunction hasFlag(args: string[], ...names: string[]): boolean {\n return names.some((n) => args.includes(`--${n}`) || args.includes(`-${n}`))\n}\n\nfunction showHelp(): void {\n console.log(`\n create-theokit v${VERSION}\n\n Usage: create-theokit <project-name> [options]\n\n Options:\n -h, --help Show this help message\n -v, --version Show version number\n --yes Use recommended defaults (skip prompts)\n --template=<name> Template to use (default: \"default\")\n --surface=<web|tui|desktop> App surface (default: \"web\") — tui (Ink) / desktop (Tauri)\n --bare Minimal app (no @theokit/* deps)\n --skip-install Scaffold files only, skip package install\n --disable-git Skip git init\n --use-npm Use npm as package manager\n --use-pnpm Use pnpm as package manager\n --use-yarn Use yarn as package manager\n --use-bun Use bun as package manager\n --import-alias=<alias> Import alias (default: \"@/*\")\n --example=<name|github-url> Bootstrap from a GitHub example\n --biome Use Biome instead of ESLint\n --agents-md Include AGENTS.md (default: true)\n\n Examples:\n npx create-theokit my-app --yes\n npx create-theokit my-app\n npx create-theokit my-app --bare --skip-install\n npx create-theokit my-app --surface=tui\n npx create-theokit my-app --surface=desktop\n npx create-theokit my-app --use-bun --biome\n npx create-theokit my-app --example=https://github.com/user/repo\n npx create-theokit my-app --import-alias=\"~/*\"\n`)\n}\n\nexport async function main(): Promise<void> {\n try {\n assertNodeVersion(process.version)\n } catch (err) {\n console.error('')\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n const args = process.argv.slice(2)\n\n // -h / --help\n if (hasFlag(args, 'h', 'help')) {\n showHelp()\n process.exit(0)\n }\n\n // -v / --version\n if (hasFlag(args, 'v', 'version')) {\n console.log(VERSION)\n process.exit(0)\n }\n\n const positionalArgs = args.filter((a) => !a.startsWith('--') && !a.startsWith('-'))\n const projectName = positionalArgs[0]\n\n if (!projectName) {\n showHelp()\n process.exit(1)\n }\n\n // Parse flags\n const templateName = getFlag(args, 'template') ?? 'default'\n const bare = hasFlag(args, 'bare')\n const skipInstall = hasFlag(args, 'skip-install')\n const useDefaults = hasFlag(args, 'yes')\n const disableGit = hasFlag(args, 'disable-git')\n const useBiome = hasFlag(args, 'biome')\n const exampleFlag = getFlag(args, 'example')\n const importAlias = getFlag(args, 'import-alias') ?? '@/*'\n\n // --use-npm/pnpm/yarn/bun override\n let pkgManagerOverride: PkgManager | undefined\n if (hasFlag(args, 'use-npm')) pkgManagerOverride = 'npm'\n else if (hasFlag(args, 'use-pnpm')) pkgManagerOverride = 'pnpm'\n else if (hasFlag(args, 'use-yarn')) pkgManagerOverride = 'yarn'\n else if (hasFlag(args, 'use-bun')) pkgManagerOverride = 'bun'\n\n let backends: BackendKind[] = []\n try {\n backends = parseBackendFlags(args)\n } catch (err) {\n console.error('')\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n let surface: SurfaceKind = 'web'\n try {\n surface = parseSurfaceFlags(args)\n } catch (err) {\n console.error('')\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n // --bare strips the agent deps; a tui/desktop surface needs them. Refuse the contradiction fail-fast.\n if (bare && surface !== 'web') {\n console.error(\n `\\n--bare cannot be combined with --surface=${surface} (the surface needs the agent deps).\\n`,\n )\n process.exit(1)\n }\n\n const targetDir = resolve(process.cwd(), projectName)\n\n // --example: clone from GitHub\n if (exampleFlag) {\n try {\n console.log(`\\nCloning example \"${exampleFlag}\" into ${projectName}...\\n`)\n cloneExample(exampleFlag, targetDir)\n const pkgManager = pkgManagerOverride ?? detectPkgManager()\n if (!skipInstall) {\n console.log(`Installing dependencies with ${pkgManager}...\\n`)\n runInstall(targetDir, pkgManager)\n }\n if (!disableGit) initGit(targetDir)\n console.log(`\\n ✓ Example cloned to ${targetDir}\\n`)\n console.log(` cd ${projectName}`)\n console.log(` ${pkgManager === 'npm' ? 'npm run' : pkgManager} dev\\n`)\n process.exit(0)\n } catch (err) {\n console.error(`\\n ✗ ${(err as Error).message}\\n`)\n process.exit(1)\n }\n }\n\n // Interactive prompts (skipped with --yes or --bare)\n let options: ProjectOptions\n if (useDefaults || bare) {\n options = getDefaults(projectName)\n if (useBiome) options.eslint = false // Biome replaces ESLint\n } else {\n options = await runPrompts(projectName)\n }\n\n try {\n const suffix = bare ? ' [--bare]' : ''\n const surfaceSuffix = surface !== 'web' ? ` [surface: ${surface}]` : ''\n const backendsSuffix = backends.length > 0 ? ` [+services: ${backends.join(', ')}]` : ''\n console.log(\n `\\nCreating TheoKit project \"${projectName}\" (template: ${templateName})${suffix}${surfaceSuffix}${backendsSuffix}...\\n`,\n )\n\n scaffold(targetDir, projectName, templateName, { bare })\n\n // M45 — apply the surface onto the scaffolded default (tui/desktop; web is a no-op).\n applySurfaceStep(targetDir, projectName, surface, options)\n\n // Post-scaffold: apply user options\n applyOptions(targetDir, options, { importAlias, useBiome })\n\n if (backends.length > 0) {\n scaffoldServices({ targetDir, projectName, backends })\n console.log(` ✓ Scaffolded ${String(backends.length)} service(s): ${backends.join(', ')}\\n`)\n }\n\n const pkgManager = pkgManagerOverride ?? detectPkgManager()\n if (skipInstall) {\n console.log(`Skipping install (--skip-install). Run \\`${pkgManager} install\\` manually.\\n`)\n } else {\n console.log(`Installing dependencies with ${pkgManager}...\\n`)\n runInstall(targetDir, pkgManager)\n }\n\n // git init (unless --disable-git)\n if (!disableGit) initGit(targetDir)\n\n console.log(`\\n ✓ Project created at ${targetDir}\\n`)\n console.log(' Next steps:\\n')\n console.log(` cd ${projectName}`)\n if (skipInstall) console.log(` ${pkgManager} install`)\n console.log(` ${pkgManager === 'npm' ? 'npm run' : pkgManager} dev\\n`)\n } catch (err) {\n console.error(`\\n ✗ ${(err as Error).message}\\n`)\n process.exit(1)\n }\n}\n\n// ── Post-scaffold transforms ──\n\n/**\n * M45 — apply the surface onto the scaffolded default (tui/desktop; web is a no-op). Rolls the whole\n * target dir back on failure (EC-4), exactly like --bare, and disables the web-only options a\n * tui/desktop app does not ship.\n */\nfunction applySurfaceStep(\n targetDir: string,\n projectName: string,\n surface: SurfaceKind,\n options: ProjectOptions,\n): void {\n if (surface === 'web') return\n try {\n applySurface({ targetDir, projectName, surface })\n } catch (err) {\n rmSync(targetDir, { recursive: true, force: true })\n const original = err instanceof Error ? err.message : String(err)\n throw new Error(`Scaffold rolled back: surface transform failed.\\nOriginal error: ${original}`)\n }\n options.tailwind = false\n options.srcDir = false\n}\n\ninterface ApplyOpts {\n importAlias: string\n useBiome: boolean\n}\n\nfunction applyOptions(targetDir: string, options: ProjectOptions, opts: ApplyOpts): void {\n const pkgPath = resolve(targetDir, 'package.json')\n\n // Biome: replace ESLint with Biome\n if (opts.useBiome) {\n const eslintPath = resolve(targetDir, 'eslint.config.mjs')\n if (existsSync(eslintPath)) unlinkSync(eslintPath)\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n delete pkg.devDependencies.eslint\n delete pkg.devDependencies['eslint-config-prettier']\n delete pkg.devDependencies['typescript-eslint']\n pkg.devDependencies['@biomejs/biome'] = '^1.9.0'\n pkg.scripts.lint = 'biome check .'\n pkg.scripts['lint:fix'] = 'biome check . --fix'\n pkg.scripts.format = 'biome format . --write'\n pkg.scripts['format:check'] = 'biome format .'\n writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\\n')\n\n // Write biome.json\n writeFileSync(\n resolve(targetDir, 'biome.json'),\n JSON.stringify(\n {\n $schema: 'https://biomejs.dev/schemas/1.9.0/schema.json',\n organizeImports: { enabled: true },\n linter: { enabled: true, rules: { recommended: true } },\n formatter: { enabled: true, indentStyle: 'space', indentWidth: 2, lineWidth: 100 },\n },\n null,\n 2,\n ) + '\\n',\n )\n } else if (!options.eslint) {\n // No linter\n const eslintPath = resolve(targetDir, 'eslint.config.mjs')\n if (existsSync(eslintPath)) unlinkSync(eslintPath)\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n delete pkg.scripts.lint\n delete pkg.scripts['lint:fix']\n delete pkg.devDependencies.eslint\n delete pkg.devDependencies['eslint-config-prettier']\n delete pkg.devDependencies['typescript-eslint']\n writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\\n')\n }\n\n // Tailwind\n if (options.tailwind) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n pkg.devDependencies = pkg.devDependencies ?? {}\n pkg.devDependencies.tailwindcss = '^4.0.0'\n pkg.devDependencies['@tailwindcss/vite'] = '^4.0.0'\n writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\\n')\n const cssDir = existsSync(resolve(targetDir, 'src/app')) ? 'src/app' : 'app'\n const cssPath = resolve(targetDir, `${cssDir}/globals.css`)\n const existing = existsSync(cssPath) ? readFileSync(cssPath, 'utf-8') : ''\n writeFileSync(cssPath, '@import \"tailwindcss\";\\n\\n' + existing)\n }\n\n // src/ directory\n if (options.srcDir) {\n const srcDir = resolve(targetDir, 'src')\n mkdirSync(srcDir, { recursive: true })\n for (const dir of ['app', 'server']) {\n const from = resolve(targetDir, dir)\n const to = resolve(srcDir, dir)\n if (existsSync(from)) renameSync(from, to)\n }\n // Move theo.config.ts into src/ for --src-dir mode\n const configFrom = resolve(targetDir, 'theo.config.ts')\n if (existsSync(configFrom)) renameSync(configFrom, resolve(srcDir, 'theo.config.ts'))\n // index.html stays at root — Vite expects it there\n\n const tscPath = resolve(targetDir, 'tsconfig.json')\n const tsc = JSON.parse(readFileSync(tscPath, 'utf-8'))\n tsc.compilerOptions.baseUrl = 'src'\n tsc.include = ['src/**/*.ts', 'src/**/*.tsx']\n writeFileSync(tscPath, JSON.stringify(tsc, null, 2) + '\\n')\n }\n\n // Import alias (custom or disabled)\n const tscPath = resolve(targetDir, 'tsconfig.json')\n const tsc = JSON.parse(readFileSync(tscPath, 'utf-8'))\n if (!options.aliases) {\n delete tsc.compilerOptions.baseUrl\n delete tsc.compilerOptions.paths\n } else if (opts.importAlias !== '@/*') {\n // Custom alias: replace @/* with user choice\n const prefix = opts.importAlias.replace('/*', '')\n tsc.compilerOptions.paths = {\n [`${prefix}/*`]: ['./*'],\n [`${prefix}/server/*`]: ['./server/*'],\n [`${prefix}/app/*`]: ['./app/*'],\n }\n }\n writeFileSync(tscPath, JSON.stringify(tsc, null, 2) + '\\n')\n\n // AGENTS.md\n if (!options.agentsMd) {\n const agentsPath = resolve(targetDir, 'AGENTS.md')\n if (existsSync(agentsPath)) unlinkSync(agentsPath)\n }\n}\n\n// ── Git init ──\n\nfunction initGit(targetDir: string): void {\n try {\n execSync('git init', { cwd: targetDir, stdio: 'ignore' })\n execSync('git add -A', { cwd: targetDir, stdio: 'ignore' })\n execSync('git commit -m \"Initial commit from create-theokit\" --no-verify', {\n cwd: targetDir,\n stdio: 'ignore',\n })\n } catch {\n // git not installed — silently skip\n }\n}\n\n// ── Example cloning ──\n\nfunction cloneExample(example: string, targetDir: string): void {\n const isUrl = example.startsWith('http://') || example.startsWith('https://')\n const repo = isUrl\n ? example\n : `https://github.com/usetheodev/theokit-examples/tree/main/${example}`\n\n if (isUrl) {\n // Full repo URL — shallow clone\n execSync(`git clone --depth 1 ${repo} ${targetDir}`, { stdio: 'inherit' })\n // Remove .git to let user init fresh\n rmSync(join(targetDir, '.git'), { recursive: true, force: true })\n } else {\n // Named example from theokit-examples repo — use degit pattern\n try {\n execSync(`npx --yes degit usetheodev/theokit-examples/${example} ${targetDir}`, {\n stdio: 'inherit',\n })\n } catch {\n throw new Error(\n `Example \"${example}\" not found. ` +\n `Browse available examples at https://github.com/usetheodev/theokit-examples`,\n )\n }\n }\n}\n\n// Auto-execute\nmain().catch((err: unknown) => {\n console.error(err)\n process.exit(1)\n})\n","import spawn from 'cross-spawn'\n\nimport type { PkgManager } from './pkg-manager.js'\n\nexport function runInstall(cwd: string, pkgManager: PkgManager): void {\n const result = spawn.sync(pkgManager, ['install'], {\n cwd,\n stdio: 'inherit',\n env: { ...process.env, NODE_ENV: 'development' },\n })\n\n if (result.status !== 0) {\n throw new Error(`Failed to install dependencies with ${pkgManager}`)\n }\n}\n","export type PkgManager = 'npm' | 'pnpm' | 'yarn' | 'bun'\n\nexport function detectPkgManager(): PkgManager {\n const ua = process.env.npm_config_user_agent ?? ''\n if (ua.startsWith('yarn')) return 'yarn'\n if (ua.startsWith('pnpm')) return 'pnpm'\n if (ua.startsWith('bun')) return 'bun'\n return 'npm'\n}\n","/**\n * Node version preflight for `create-theokit`.\n *\n * `@theokit/sdk` declares `engines.node: \">=22.12.0\"`. Users on older Node\n * hit cryptic `node:sqlite` / `better-sqlite3` ABI errors mid-chat without\n * any actionable diagnostic. This preflight runs at scaffold start, prints\n * a clear error, and exits before any FS write (ADR D4 of the plan).\n *\n * Zero-dep semver comparator — no `semver` package needed.\n */\n\n/** Minimum Node version required by `@theokit/sdk`. */\nexport const MIN_NODE_VERSION = '22.12.0'\n\n/**\n * Compare two semver strings (major.minor.patch). Strips leading `v` from\n * either side. Pre-release suffixes (e.g., `-rc.1`, `-nightly...`) are\n * parsed as the base patch — acceptable for a preflight (we're not gating\n * on exact pre-release ordering).\n *\n * Returns:\n * <0 when a < b\n * 0 when a == b\n * >0 when a > b\n */\nexport function compareSemver(a: string, b: string): number {\n const parse = (raw: string): [number, number, number] => {\n const stripped = raw.replace(/^v/, '').split('-')[0] ?? '0.0.0'\n const parts = stripped.split('.').map((s) => Number.parseInt(s, 10) || 0)\n return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0]\n }\n const [aMaj, aMin, aPat] = parse(a)\n const [bMaj, bMin, bPat] = parse(b)\n if (aMaj !== bMaj) return aMaj - bMaj\n if (aMin !== bMin) return aMin - bMin\n return aPat - bPat\n}\n\n/**\n * Throw with an actionable message if `currentRaw` is below `minimum`.\n * Default minimum is `MIN_NODE_VERSION` (22.12.0).\n *\n * Called as the first line of `create-theokit`'s `main` so the preflight\n * fires before any directory is written.\n */\nexport function assertNodeVersion(currentRaw: string, minimum: string = MIN_NODE_VERSION): void {\n const current = currentRaw.replace(/^v/, '')\n if (compareSemver(currentRaw, minimum) < 0) {\n throw new Error(\n `create-theokit requires Node ${minimum} or later (the @theokit/sdk peer engines floor).\\n` +\n ` Detected: Node ${current}\\n` +\n ` Fix: nvm install 22 && nvm use 22\\n` +\n ` (or your version manager equivalent — fnm, volta, asdf, nvs)\\n`,\n )\n }\n}\n","/**\n * Interactive prompts for create-theokit.\n * Skipped when --yes flag is passed (uses defaults).\n *\n * Uses Node.js readline (zero deps) — not inquirer/prompts.\n */\nimport { createInterface } from 'node:readline'\n\nexport interface ProjectOptions {\n projectName: string\n typescript: boolean\n eslint: boolean\n tailwind: boolean\n srcDir: boolean\n aliases: boolean\n agentsMd: boolean\n}\n\nconst DEFAULTS: Omit<ProjectOptions, 'projectName'> = {\n typescript: true,\n eslint: true,\n tailwind: true,\n srcDir: false,\n aliases: true,\n agentsMd: true,\n}\n\nasync function ask(rl: ReturnType<typeof createInterface>, question: string, defaultVal: boolean): Promise<boolean> {\n return new Promise((resolve) => {\n const suffix = defaultVal ? '(Y/n)' : '(y/N)'\n rl.question(` ${question} ${suffix} `, (answer) => {\n const a = answer.trim().toLowerCase()\n if (a === '') resolve(defaultVal)\n else resolve(a === 'y' || a === 'yes')\n })\n })\n}\n\nasync function askChoice(rl: ReturnType<typeof createInterface>, question: string, choices: string[], defaultIdx = 0): Promise<number> {\n return new Promise((resolve) => {\n console.log(` ${question}`)\n for (let i = 0; i < choices.length; i++) {\n const marker = i === defaultIdx ? '❯' : ' '\n console.log(` ${marker} ${choices[i]}`)\n }\n rl.question(' Choice (number): ', (answer) => {\n const n = parseInt(answer.trim(), 10)\n resolve(n >= 1 && n <= choices.length ? n - 1 : defaultIdx)\n })\n })\n}\n\nexport async function runPrompts(projectName: string): Promise<ProjectOptions> {\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n\n try {\n console.log('')\n const mode = await askChoice(rl, 'Would you like to use the recommended TheoKit defaults?', [\n 'Yes, use recommended defaults — TypeScript, ESLint, Tailwind CSS, AGENTS.md',\n 'No, customize settings',\n ], 0)\n\n if (mode === 0) {\n return { projectName, ...DEFAULTS }\n }\n\n const typescript = await ask(rl, 'Would you like to use TypeScript?', true)\n const eslint = await ask(rl, 'Would you like to use ESLint?', true)\n const tailwind = await ask(rl, 'Would you like to use Tailwind CSS?', true)\n const srcDir = await ask(rl, 'Would you like your code inside a `src/` directory?', false)\n const aliases = await ask(rl, 'Would you like to use import alias (@/*)?', true)\n const agentsMd = await ask(rl, 'Would you like to include AGENTS.md for coding agents?', true)\n\n return { projectName, typescript, eslint, tailwind, srcDir, aliases, agentsMd }\n } finally {\n rl.close()\n }\n}\n\nexport function getDefaults(projectName: string): ProjectOptions {\n return { projectName, ...DEFAULTS }\n}\n","/**\n * Build-time scaffold helper. All write paths derived from the trusted\n * targetDir (CLI argument, resolved absolute). Read paths are the\n * bundled service templates shipped with this package.\n */\n/**\n * Phase 4 — `--backend python|node` scaffolding (T4.1, T4.2).\n *\n * After the main TheoKit scaffold runs, this helper:\n * - Copies the requested service template(s) under `<target>/services/<name>/`\n * - Substitutes `{{name}}` in `.tmpl` files\n * - Renames `.tmpl` files to drop the suffix\n * - Injects services config into the user's `theo.config.ts`\n * - Injects `@hey-api/client-fetch` into the user's package.json (EC-10)\n */\nimport {\n cpSync,\n existsSync,\n readFileSync,\n readdirSync,\n statSync,\n writeFileSync,\n unlinkSync,\n} from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\n// node-only polyglot backend (decision 2026-06-17). Python scaffolding was\n// deferred — only the Node (Hono) sidecar template ships. Re-adding Python\n// requires restoring its template + an ADR with demand evidence.\nexport type BackendKind = 'node'\n\nconst VALID_BACKENDS = ['node'] as const\n\n/**\n * Parse `--backend node` (multi-value) from argv.\n *\n * Accepts:\n * --backend node\n * --backend=node\n *\n * Throws on unknown backend name (incl. `python`, which is not shipped).\n */\nexport function parseBackendFlags(args: string[]): BackendKind[] {\n const out: BackendKind[] = []\n for (let i = 0; i < args.length; i++) {\n const a = args[i] ?? ''\n let value: string | undefined\n if (a === '--backend') {\n value = args[i + 1]\n i++\n } else if (a.startsWith('--backend=')) {\n value = a.slice('--backend='.length)\n }\n if (value === undefined) continue\n if (!(VALID_BACKENDS as readonly string[]).includes(value)) {\n throw new Error(\n `unknown --backend value: '${value}'. Valid options: ${VALID_BACKENDS.join(', ')}.`,\n )\n }\n out.push(value as BackendKind)\n }\n return out\n}\n\nconst BACKEND_CONFIG: Record<\n BackendKind,\n {\n templateDir: string\n serviceName: string\n port: number\n proxy: string\n dev: string\n start: string\n }\n> = {\n node: {\n templateDir: 'agent-node',\n serviceName: 'worker',\n port: 8002,\n proxy: '/api/worker',\n dev: 'pnpm dev',\n start: 'pnpm start',\n },\n}\n\nfunction getServiceTemplateDir(kind: BackendKind): string {\n return resolve(__dirname, '../templates/services', BACKEND_CONFIG[kind].templateDir)\n}\n\nfunction substituteTmpls(dir: string, projectName: string): void {\n for (const entry of readdirSync(dir)) {\n const full = join(dir, entry)\n const stat = statSync(full)\n if (stat.isDirectory()) {\n substituteTmpls(full, projectName)\n continue\n }\n if (entry.endsWith('.tmpl')) {\n const content = readFileSync(full, 'utf-8').replace(/\\{\\{name\\}\\}/g, projectName)\n const dest = full.replace(/\\.tmpl$/, '')\n writeFileSync(dest, content)\n unlinkSync(full)\n }\n }\n}\n\ninterface ServiceEntry {\n runtime: BackendKind\n port: number\n proxy: string\n dev: string\n start: string\n}\n\n/**\n * Build the `services: {}` snippet to inject into `theo.config.ts`.\n * Returns the inner record literal — caller wraps in `services: { ... }`.\n */\nexport function buildServicesSnippet(selections: { name: string; entry: ServiceEntry }[]): string {\n if (selections.length === 0) return ''\n const blocks = selections.map(({ name, entry }) => {\n return ` ${name}: {\n runtime: '${entry.runtime}',\n port: ${String(entry.port)},\n proxy: '${entry.proxy}',\n dev: ${JSON.stringify(entry.dev)},\n start: ${JSON.stringify(entry.start)},\n },`\n })\n return ` services: {\\n${blocks.join('\\n')}\\n },\\n`\n}\n\n/**\n * Insert the services block into an existing `theo.config.ts`.\n * Strategy: find `defineConfig({` and append the services block before the closing brace.\n */\nexport function injectServicesIntoConfig(configSource: string, snippet: string): string {\n if (snippet.length === 0) return configSource\n if (configSource.includes('services:')) return configSource // already present\n\n // Match the LAST `}` before the closing of defineConfig({...})\n const re = /defineConfig\\(\\{([\\s\\S]*?)\\}\\)/m\n const match = re.exec(configSource)\n if (!match) return configSource\n\n const inner = match[1]\n // Strip trailing whitespace without backtracking-prone \\s+$ regex.\n let trimEnd = inner.length\n while (trimEnd > 0 && /\\s/.test(inner.charAt(trimEnd - 1))) {\n trimEnd--\n }\n const trimmed = inner.slice(0, trimEnd)\n const sep = trimmed.length > 0 && !trimmed.endsWith(',') ? ',\\n' : '\\n'\n const newInner = `${trimmed}${sep}${snippet}`\n return configSource.replace(re, `defineConfig({${newInner}})`)\n}\n\nexport function injectHeyApiDep(packageJsonSource: string): string {\n const pkg = JSON.parse(packageJsonSource) as {\n dependencies?: Record<string, string>\n }\n pkg.dependencies = pkg.dependencies ?? {}\n if (!('@hey-api/client-fetch' in pkg.dependencies)) {\n pkg.dependencies['@hey-api/client-fetch'] = '^0.6.0'\n }\n return JSON.stringify(pkg, null, 2) + '\\n'\n}\n\nexport interface ScaffoldServicesOptions {\n /** Target project directory (already scaffolded with the TS template). */\n targetDir: string\n /** Project name (substituted into .tmpl files). */\n projectName: string\n /** Which backends to scaffold. */\n backends: BackendKind[]\n}\n\nexport function scaffoldServices(options: ScaffoldServicesOptions): void {\n if (options.backends.length === 0) return\n\n const selections: { name: string; entry: ServiceEntry }[] = []\n\n for (const kind of options.backends) {\n const cfg = BACKEND_CONFIG[kind]\n const src = getServiceTemplateDir(kind)\n // Schema contract: dev/start commands run from `services/<serviceName>/` cwd\n // (services/schema/schema.ts line 35). The destination MUST equal serviceName\n // so the orchestrator's cwd resolution matches the on-disk directory.\n const dest = join(options.targetDir, 'services', cfg.serviceName)\n if (!existsSync(src)) {\n throw new Error(`service template not found: ${src}`)\n }\n cpSync(src, dest, { recursive: true })\n substituteTmpls(dest, options.projectName)\n\n selections.push({\n name: cfg.serviceName,\n entry: {\n runtime: kind,\n port: cfg.port,\n proxy: cfg.proxy,\n dev: cfg.dev,\n start: cfg.start,\n },\n })\n }\n\n // Inject services into theo.config.ts\n const configPath = join(options.targetDir, 'theo.config.ts')\n if (existsSync(configPath)) {\n const cfgSrc = readFileSync(configPath, 'utf-8')\n const snippet = buildServicesSnippet(selections)\n const updated = injectServicesIntoConfig(cfgSrc, snippet)\n if (updated !== cfgSrc) {\n writeFileSync(configPath, updated)\n }\n }\n\n // EC-10: inject @hey-api/client-fetch into user's package.json\n const pkgPath = join(options.targetDir, 'package.json')\n if (existsSync(pkgPath)) {\n const pkgSrc = readFileSync(pkgPath, 'utf-8')\n const updated = injectHeyApiDep(pkgSrc)\n writeFileSync(pkgPath, updated)\n }\n\n // Rename .gitignore for services if needed (none currently shipped, but reserved hook)\n}\n","import {\n cpSync,\n existsSync,\n readdirSync,\n readFileSync,\n rmSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n// ESM has no CJS `__dirname` global — derive it (mirrors src/index.ts + src/scaffold-services.ts). Without\n// this the published bundle throws `__dirname is not defined` at runtime (vitest provides the global, so the\n// unit tests never caught it — only running `npx create-theokit --surface tui` for real surfaced it).\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\n/**\n * M45 (ADR-0054) — `create-theokit --surface web|tui|desktop`.\n *\n * A FLAG-driven additive scaffold (mirrors `--backend` / `scaffoldServices`), NOT a new top-level\n * template (ADR-0023 default-only respected). `web` is the default (the existing web app — no-op).\n * `tui` / `desktop` copy a template fragment (`templates/surfaces/<kind>/`) onto the scaffolded default,\n * mutate `package.json` (drop web-only deps, add surface deps + scripts), and remove the web UI. Each\n * scaffolded surface consumes the agent via the M41/M42/M44 UNIFIED client (ADR-0054 D2), not the raw\n * seam. All Tauri/Ink boilerplate lives HERE in the scaffolder templates — framework core stays agnostic.\n */\nexport type SurfaceKind = 'web' | 'tui' | 'desktop'\n\nconst VALID_SURFACES = ['web', 'tui', 'desktop'] as const\n\n/**\n * Web-only deps dropped for the tui/desktop surfaces (they ship no web UI). `react-router` is NOT dropped\n * — `theokit` declares it a REQUIRED peer, so removing it breaks `npm install` (ERESOLVE). `ai` is NOT\n * dropped either: although the tui's RENDER is ai-free (`@theokit/tui` + `messagesToAgentEvents`), theokit's\n * in-process agent runtime (`streamAgentTurnInProcess` → the UIMessageStream protocol) imports `ai` at\n * RUNTIME, so every surface that runs an agent must keep it installed.\n */\nconst WEB_ONLY_DEPS = ['@theokit/ui', '@usetheo/ui', 'lucide-react'] as const\nconst WEB_ONLY_DEV_DEPS = ['tailwindcss', '@tailwindcss/vite', 'tailwindcss-animate'] as const\n/** Web UI files removed for the tui/desktop surfaces. */\nconst WEB_ONLY_FILES = ['app', 'index.html', 'tailwind.config.ts', 'postcss.config.js'] as const\n\ninterface SurfaceConfig {\n /** The template fragment dir under `templates/surfaces/`. */\n fragment: string\n /** Deps ADDED for this surface. */\n deps: Record<string, string>\n /** Dev deps ADDED for this surface. */\n devDeps: Record<string, string>\n /** Scripts SET for this surface (override the web dev/build). */\n scripts: Record<string, string>\n /** `tsconfig.json` `include` for this surface (the default's `app/**` is removed with the web UI). */\n tsconfigInclude: string[]\n}\n\nconst SURFACE_CONFIG: Record<Exclude<SurfaceKind, 'web'>, SurfaceConfig> = {\n tui: {\n fragment: 'tui',\n // `@theokit/tui` renders the conversation via `<AgentTimeline>` (Markdown + fenced code + collapsible\n // tool cards — the Claude-Code render), projected from `useAgent().thread` by the ai-free\n // `messagesToAgentEvents` (structural `UIMessageLike`) — so the TUI's own code + `@theokit/tui` never\n // import `ai`. `ai` is still declared because theokit's in-process agent runtime\n // (`streamAgentTurnInProcess` → the UIMessageStream protocol) imports it at RUNTIME. `ink@7` is the\n // React-19 line (ink@5 crashes on React 19 with `ReactCurrentOwner`; the default template pins react@19;\n // ink@6.0.0+ moved its peer to react>=19), matching @theokit/tui's own ink@^7.1.0 so the app's\n // `import 'ink'` dedupes to one React-19 ink. `figlet` (banner ASCII) + `lowlight` (code highlight) are\n // @theokit/tui PEERS the app relies on — declared so pnpm (which never auto-installs peers) resolves them.\n deps: {\n '@theokit/tui': '^0.37.0',\n ink: '^7.1.0',\n ai: '^7.0.0',\n figlet: '^1.7.0',\n lowlight: '^3.0.0',\n },\n devDeps: { tsx: '^4.19.0' },\n scripts: { dev: 'tsx tui/main.tsx', start: 'tsx tui/main.tsx' },\n tsconfigInclude: [\n 'tui/**/*.ts',\n 'tui/**/*.tsx',\n 'server/**/*.ts',\n 'agents/**/*.ts',\n 'shared/**/*.ts',\n ],\n },\n desktop: {\n fragment: 'desktop',\n // M47: the webview is a React app rendering with `@theokit/ui`, driven by `useAgent` over a\n // `ChannelTransport` whose source is `@theokit/tauri`'s `createTauriChannelSource`; the Node sidecar\n // runs the turn via `@theokit/tauri/sidecar`. `ai` = the UIMessageStream reader + UIMessage type (was\n // transitive via `@theokit/ui`, re-added explicitly here). react/react-dom are inherited from the default.\n // Same rich surface as the web default → same UI deps: `@usetheo/ui` (Button) + `lucide-react` (icons),\n // matching the web template's versions. `@theokit/ui` components self-style via the precompiled sheet.\n deps: {\n '@theokit/ui': '^1.0.0',\n '@usetheo/ui': '^0.26.0',\n '@theokit/tauri': '^0.1.1',\n 'lucide-react': '^0.469.0',\n ai: '^7.0.0',\n },\n devDeps: {\n tsx: '^4.19.0',\n '@tauri-apps/cli': '^2.0.0',\n vite: '^6.0.0',\n '@vitejs/plugin-react': '^4.3.0',\n },\n scripts: {\n dev: 'tauri dev',\n tauri: 'tauri',\n 'build:frontend': 'vite build frontend',\n // Generates the Tauri externalBin launcher (src-tauri/binaries/theo-sidecar-<triple>) the Rust\n // shell spawns. Wired into tauri.conf.json beforeDev/BuildCommand — regenerated each launch.\n 'build:sidecar': 'node scripts/build-sidecar.mjs',\n },\n tsconfigInclude: [\n 'sidecar/**/*.ts',\n 'frontend/src/**/*.ts',\n 'frontend/src/**/*.tsx',\n 'server/**/*.ts',\n 'agents/**/*.ts',\n 'shared/**/*.ts',\n ],\n },\n}\n\n/** Parse `--surface <kind>` / `--surface=<kind>`; default `web`. Fail-fast on an unknown value. */\nexport function parseSurfaceFlags(args: string[]): SurfaceKind {\n let surface: SurfaceKind = 'web'\n for (let i = 0; i < args.length; i++) {\n const a = args[i] ?? ''\n let value: string | undefined\n if (a === '--surface') {\n value = args[i + 1]\n i++\n } else if (a.startsWith('--surface=')) {\n value = a.slice('--surface='.length)\n }\n if (value === undefined) continue\n if (!(VALID_SURFACES as readonly string[]).includes(value)) {\n throw new Error(\n `unknown --surface value: '${value}'. Valid options: ${VALID_SURFACES.join(', ')}.`,\n )\n }\n surface = value as SurfaceKind\n }\n return surface\n}\n\n/** Locate the fragment dir shipped alongside the compiled scaffolder. */\nfunction getSurfaceFragmentDir(fragment: string): string {\n return resolve(__dirname, '../templates/surfaces', fragment)\n}\n\n/** Recursively substitute `{{name}}` in `.tmpl` files (mirrors scaffoldServices). */\nfunction substituteTmpls(dir: string, projectName: string): void {\n for (const entry of readdirSync(dir)) {\n const full = join(dir, entry)\n if (statSync(full).isDirectory()) {\n substituteTmpls(full, projectName)\n continue\n }\n if (entry.endsWith('.tmpl')) {\n const content = readFileSync(full, 'utf-8').replace(/\\{\\{name\\}\\}/g, projectName)\n writeFileSync(full.replace(/\\.tmpl$/, ''), content)\n unlinkSync(full)\n }\n }\n}\n\nexport interface ApplySurfaceOptions {\n targetDir: string\n projectName: string\n surface: SurfaceKind\n /** Test-only: force a failure to exercise the caller's rollback (mirrors --bare `_testForceError`). */\n _testForceError?: string\n}\n\ninterface PartialPackageJson {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n scripts?: Record<string, string>\n [key: string]: unknown\n}\n\n/**\n * Apply a surface onto a freshly-scaffolded default template. `web` is a no-op (the default IS web).\n * `tui`/`desktop` copy the fragment, drop web-only deps + UI, and add the surface's deps/scripts. Throws\n * on any failure so the CLI can roll the whole target dir back (EC-4), exactly like `--bare`.\n */\nexport function applySurface(options: ApplySurfaceOptions): void {\n if (options._testForceError !== undefined) {\n throw new Error(`Forced surface failure: ${options._testForceError}`)\n }\n if (options.surface === 'web') return\n\n const cfg = SURFACE_CONFIG[options.surface]\n const src = getSurfaceFragmentDir(cfg.fragment)\n if (!existsSync(src)) {\n throw new Error(`surface fragment not found: ${src}`)\n }\n\n // 1. Copy the fragment onto the target, then substitute {{name}}.\n cpSync(src, options.targetDir, { recursive: true })\n substituteTmpls(options.targetDir, options.projectName)\n\n // 2. Remove the web UI (a tui/desktop app ships no web surface).\n for (const rel of WEB_ONLY_FILES) {\n const p = join(options.targetDir, rel)\n if (existsSync(p)) rmSync(p, { recursive: true, force: true })\n }\n\n // 3. Mutate package.json: drop web-only deps, add surface deps + scripts.\n const pkgPath = join(options.targetDir, 'package.json')\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PartialPackageJson\n pkg.dependencies = { ...dropKeys(pkg.dependencies, WEB_ONLY_DEPS), ...cfg.deps }\n pkg.devDependencies = { ...dropKeys(pkg.devDependencies, WEB_ONLY_DEV_DEPS), ...cfg.devDeps }\n pkg.scripts = { ...(pkg.scripts ?? {}), ...cfg.scripts }\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`)\n }\n\n // 4. Point `tsconfig.json` `include` at the surface's source (the default's `app/**` went with the web\n // UI) — so `tsc` in the generated project type-checks the surface entry files (the unified-client wiring).\n const tsconfigPath = join(options.targetDir, 'tsconfig.json')\n if (existsSync(tsconfigPath)) {\n const tsconfig = JSON.parse(readFileSync(tsconfigPath, 'utf-8')) as { include?: string[] }\n tsconfig.include = cfg.tsconfigInclude\n writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\\n`)\n }\n}\n\n/** Return a copy of `record` without `keys` (no dynamic `delete` — filter-rebuild). */\nfunction dropKeys(\n record: Record<string, string> | undefined,\n keys: readonly string[],\n): Record<string, string> {\n return Object.fromEntries(Object.entries(record ?? {}).filter(([k]) => !keys.includes(k)))\n}\n","/**\n * `create-theokit` scaffold tool. All write paths are derived from the\n * user-supplied target directory (CLI argument, resolved to absolute).\n * Read paths are the bundled `templates/` shipped with this package.\n * Build-time tool — no HTTP input.\n */\nimport {\n existsSync,\n cpSync,\n readFileSync,\n writeFileSync,\n renameSync,\n unlinkSync,\n readdirSync,\n rmSync,\n statSync,\n} from 'node:fs'\nimport { resolve, join, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { applyBareTransform } from './bare-transform.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nfunction getTemplateDir(templateName = 'default'): string {\n return resolve(__dirname, '../templates', templateName)\n}\n\nfunction isValidProjectName(name: string): boolean {\n return /^[a-z0-9][a-z0-9._-]*$/.test(name)\n}\n\nexport interface ScaffoldOptions {\n bare?: boolean\n /** Test-only — force the bare transform to throw to validate EC-4 rollback. */\n _testForceTransformError?: string\n}\n\nexport function scaffold(\n targetDir: string,\n projectName: string,\n templateName = 'default',\n options: ScaffoldOptions = {},\n): void {\n // EC-4 + ADR D5: --bare only applies to default template\n if (options.bare && templateName !== 'default') {\n throw new Error(\n `--bare flag only applies to the default template; got \"${templateName}\". ` +\n `Use \\`npx create-theokit <name> --template=default --bare\\` or pick a different template.`,\n )\n }\n\n const templateDir = getTemplateDir(templateName)\n\n if (!existsSync(templateDir)) {\n throw new Error(`Template \"${templateName}\" not found. Available templates: default`)\n }\n\n // Bug #1 fix: \".\" means current directory — use dir basename as project name\n const resolvedName =\n projectName === '.' ? (resolve(targetDir).split('/').pop() ?? 'my-app') : projectName\n\n if (!isValidProjectName(resolvedName)) {\n throw new Error(\n `Invalid project name \"${resolvedName}\". ` +\n `Use lowercase letters, numbers, hyphens, and dots. Must start with a letter or number.`,\n )\n }\n\n if (existsSync(targetDir)) {\n const contents = readdirSync(targetDir)\n if (contents.length > 0) {\n throw new Error(`Directory \"${targetDir}\" is not empty. Please use an empty directory.`)\n }\n }\n\n cpSync(templateDir, targetDir, { recursive: true })\n\n const gitignoreSrc = join(targetDir, '_gitignore')\n const gitignoreDest = join(targetDir, '.gitignore')\n if (existsSync(gitignoreSrc)) {\n renameSync(gitignoreSrc, gitignoreDest)\n }\n\n // dot-claude/ → .claude/ (npm ignores dotfolders in published packages)\n const dotClaudeSrc = join(targetDir, 'dot-claude')\n const dotClaudeDest = join(targetDir, '.claude')\n if (existsSync(dotClaudeSrc)) {\n renameSync(dotClaudeSrc, dotClaudeDest)\n }\n\n // Apply {{name}} substitution to every `*.tmpl` file in the target dir.\n // Each `foo.tmpl` becomes `foo` with placeholders replaced. Walks only\n // the project root (deeper subfolders don't currently need templating).\n for (const entry of readdirSync(targetDir)) {\n if (!entry.endsWith('.tmpl')) continue\n const src = join(targetDir, entry)\n const stat = statSync(src)\n if (!stat.isFile()) continue\n const dst = join(targetDir, entry.slice(0, -'.tmpl'.length))\n const content = readFileSync(src, 'utf-8')\n const replaced = content.replace(/\\{\\{name\\}\\}/g, resolvedName)\n writeFileSync(dst, replaced)\n unlinkSync(src)\n }\n\n // T4.1 — Apply --bare transform with EC-4 atomic rollback\n if (options.bare) {\n try {\n applyBareTransform(targetDir, {\n _testForceError: options._testForceTransformError,\n })\n } catch (err) {\n // EC-4: roll back partial state\n rmSync(targetDir, { recursive: true, force: true })\n const original = err instanceof Error ? err.message : String(err)\n throw new Error(\n `Scaffold rolled back: bare transform failed. Check filesystem perms.\\nOriginal error: ${original}`,\n )\n }\n }\n}\n","/**\n * Scaffold transform. Mutates files inside the freshly-created target\n * directory whose absolute path is the function input. No HTTP input.\n */\n/**\n * T4.1 — `--bare` transformation.\n *\n * Applied AFTER the default template is copied. Removes:\n * - `@theokit/ui` from `package.json` dependencies (TheoUI bundled components)\n * - `@theokit/sdk` from `package.json` dependencies (agent SDK — see below)\n * - `@theokit/agents` from `package.json` dependencies (only agents/chat.ts used it)\n * - `app/page.tsx` agent-surface content (replaces with Hello Theo)\n * - `agents/chat.ts` (the demo agent — depends on the SDK + TheoUI page)\n * - `tailwind.config.ts` + `postcss.config.js` (Tailwind toolchain — only\n * needed by the @theokit/ui-driven default surface)\n * - tailwind* + postcss* from devDependencies (toolchain cleanup)\n *\n * Why SDK removal is in --bare:\n * `@theokit/sdk` is not yet on the public npm registry (operator-deferred\n * publish per macro roadmap item #3). A user running `npx create-theokit`\n * without `--bare` hits `npm install` → 404. The `--bare` path produces a\n * scaffold that ALWAYS works without registry dependencies — Hello Theo\n * with a clean structure to grow into.\n *\n * EC-4: callers MUST wrap this in try/catch + `rmSync` rollback so a partial\n * transform never leaves the target dir in a broken state.\n */\n\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, rmSync } from 'node:fs'\nimport { join } from 'node:path'\n\nconst HELLO_PAGE = `export default function Page() {\n return <h1>Hello Theo</h1>\n}\n`\n\n// --bare ships an unstyled shell: no @theokit/ui Header, no styles.css import. Replaces the default\n// layout (which composes components/Header.tsx + imports @theokit/ui, both dropped by --bare).\nconst BARE_LAYOUT = `import { Outlet } from 'react-router'\n\nexport default function RootLayout() {\n return <Outlet />\n}\n`\n\nexport interface BareTransformOptions {\n /** Test-only — force a synthetic write failure to validate rollback path. */\n _testForceError?: string\n}\n\nexport function applyBareTransform(targetDir: string, options: BareTransformOptions = {}): void {\n if (options._testForceError) {\n throw new Error(`Forced transform failure: ${options._testForceError}`)\n }\n\n // 1. Remove @theokit/ui + @theokit/sdk + tailwind toolchain from deps\n const pkgPath = join(targetDir, 'package.json')\n if (existsSync(pkgPath)) {\n interface PartialPackageJson {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n [key: string]: unknown\n }\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PartialPackageJson\n if (pkg.dependencies) {\n delete pkg.dependencies['@theokit/ui']\n // Drop SDK — operator-deferred npm publish (macro roadmap item #3).\n // Without removal, `npm install` hits 404 for any consumer outside\n // the workspace.\n delete pkg.dependencies['@theokit/sdk']\n // --bare removes the demo agent (agents/chat.ts), so its runtime dep\n // (@theokit/agents, imported only by that file) goes with it.\n delete pkg.dependencies['@theokit/agents']\n // lucide-react ships with the TheoUI surface; --bare doesn't render\n // any icons so it's safe to drop.\n delete pkg.dependencies['lucide-react']\n }\n if (pkg.devDependencies) {\n // Tailwind toolchain is only needed by the @theokit/ui-driven default\n // surface. --bare ships unstyled Hello Theo; no Tailwind required.\n delete pkg.devDependencies.tailwindcss\n delete pkg.devDependencies['tailwindcss-animate']\n delete pkg.devDependencies.postcss\n delete pkg.devDependencies.autoprefixer\n }\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`)\n }\n\n // 2. Replace app/page.tsx (Hello Theo) + app/layout.tsx (unstyled shell) — the defaults compose the chat\n // surface + import @theokit/ui, which --bare drops.\n const pagePath = join(targetDir, 'app/page.tsx')\n if (existsSync(pagePath)) {\n writeFileSync(pagePath, HELLO_PAGE)\n }\n const layoutPath = join(targetDir, 'app/layout.tsx')\n if (existsSync(layoutPath)) {\n writeFileSync(layoutPath, BARE_LAYOUT)\n }\n\n // 3. Remove the demo chat agent (the `agents/chat.ts` file + its TheoUI page)\n const chatPath = join(targetDir, 'agents/chat.ts')\n if (existsSync(chatPath)) {\n unlinkSync(chatPath)\n }\n\n // 3b. Remove the chat frontend surface — `app/{components,hooks,lib}/` (import @theokit/ui) + the\n // `app/about/` example route (part of the chat demo). The Hello-Theo page references none of them.\n // (The route surface — layout/page/error/… — is kept; page + layout are rewritten above.)\n for (const dir of ['app/components', 'app/hooks', 'app/lib', 'app/about']) {\n const p = join(targetDir, dir)\n if (existsSync(p)) rmSync(p, { recursive: true, force: true })\n }\n\n // 4. Remove tailwind + postcss config files (toolchain dropped from devDeps)\n const tailwindCfg = join(targetDir, 'tailwind.config.ts')\n if (existsSync(tailwindCfg)) {\n unlinkSync(tailwindCfg)\n }\n const postcssCfg = join(targetDir, 'postcss.config.js')\n if (existsSync(postcssCfg)) {\n unlinkSync(postcssCfg)\n }\n}\n"],"mappings":"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","names":["readFileSync","writeFileSync","unlinkSync","renameSync","existsSync","rmSync","resolve","join","resolve","cpSync","existsSync","readdirSync","readFileSync","statSync","unlinkSync","writeFileSync","dirname","join","resolve","fileURLToPath","__dirname","substituteTmpls","existsSync","cpSync","readFileSync","writeFileSync","unlinkSync","readdirSync","rmSync","statSync","resolve","join","dirname","fileURLToPath","existsSync","readFileSync","writeFileSync","unlinkSync","rmSync","join","__dirname","dirname","fileURLToPath","resolve","existsSync","readdirSync","cpSync","join","statSync","readFileSync","writeFileSync","unlinkSync","rmSync","resolve","rmSync","existsSync","unlinkSync","readFileSync","writeFileSync","renameSync","tscPath","tsc","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/install.ts","../src/pkg-manager.ts","../src/preflight-node.ts","../src/prompts.ts","../src/scaffold-services.ts","../src/scaffold-surface.ts","../src/index.ts","../src/bare-transform.ts"],"sourcesContent":["import { execSync } from 'node:child_process'\nimport {\n readFileSync,\n writeFileSync,\n unlinkSync,\n mkdirSync,\n renameSync,\n existsSync,\n rmSync,\n} from 'node:fs'\nimport { resolve, join } from 'node:path'\n\nimport { runInstall } from './install.js'\nimport { detectPkgManager, type PkgManager } from './pkg-manager.js'\nimport { assertNodeVersion } from './preflight-node.js'\nimport { runPrompts, getDefaults, type ProjectOptions } from './prompts.js'\nimport { parseBackendFlags, scaffoldServices, type BackendKind } from './scaffold-services.js'\nimport { applySurface, parseSurfaceFlags, type SurfaceKind } from './scaffold-surface.js'\n\nimport { scaffold } from './index.js'\n\nconst VERSION = '0.8.0'\n\nfunction getFlag(args: string[], name: string): string | undefined {\n const flag = args.find((a) => a.startsWith(`--${name}=`))\n return flag ? flag.split('=')[1] : undefined\n}\n\nfunction hasFlag(args: string[], ...names: string[]): boolean {\n return names.some((n) => args.includes(`--${n}`) || args.includes(`-${n}`))\n}\n\nfunction showHelp(): void {\n console.log(`\n create-theokit v${VERSION}\n\n Usage: create-theokit <project-name> [options]\n\n Options:\n -h, --help Show this help message\n -v, --version Show version number\n --yes Use recommended defaults (skip prompts)\n --template=<name> Template to use (default: \"default\")\n --surface=<web|tui|desktop> App surface (default: \"web\") — tui (Ink) / desktop (Tauri)\n --bare Minimal app (no @theokit/* deps)\n --skip-install Scaffold files only, skip package install\n --disable-git Skip git init\n --use-npm Use npm as package manager\n --use-pnpm Use pnpm as package manager\n --use-yarn Use yarn as package manager\n --use-bun Use bun as package manager\n --import-alias=<alias> Import alias (default: \"@/*\")\n --example=<name|github-url> Bootstrap from a GitHub example\n --biome Use Biome instead of ESLint\n --agents-md Include AGENTS.md (default: true)\n\n Examples:\n npx create-theokit my-app --yes\n npx create-theokit my-app\n npx create-theokit my-app --bare --skip-install\n npx create-theokit my-app --surface=tui\n npx create-theokit my-app --surface=desktop\n npx create-theokit my-app --use-bun --biome\n npx create-theokit my-app --example=https://github.com/user/repo\n npx create-theokit my-app --import-alias=\"~/*\"\n`)\n}\n\nexport async function main(): Promise<void> {\n try {\n assertNodeVersion(process.version)\n } catch (err) {\n console.error('')\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n const args = process.argv.slice(2)\n\n // -h / --help\n if (hasFlag(args, 'h', 'help')) {\n showHelp()\n process.exit(0)\n }\n\n // -v / --version\n if (hasFlag(args, 'v', 'version')) {\n console.log(VERSION)\n process.exit(0)\n }\n\n const positionalArgs = args.filter((a) => !a.startsWith('--') && !a.startsWith('-'))\n const projectName = positionalArgs[0]\n\n if (!projectName) {\n showHelp()\n process.exit(1)\n }\n\n // Parse flags\n const templateName = getFlag(args, 'template') ?? 'default'\n const bare = hasFlag(args, 'bare')\n const skipInstall = hasFlag(args, 'skip-install')\n const useDefaults = hasFlag(args, 'yes')\n const disableGit = hasFlag(args, 'disable-git')\n const useBiome = hasFlag(args, 'biome')\n const exampleFlag = getFlag(args, 'example')\n const importAlias = getFlag(args, 'import-alias') ?? '@/*'\n\n // --use-npm/pnpm/yarn/bun override\n let pkgManagerOverride: PkgManager | undefined\n if (hasFlag(args, 'use-npm')) pkgManagerOverride = 'npm'\n else if (hasFlag(args, 'use-pnpm')) pkgManagerOverride = 'pnpm'\n else if (hasFlag(args, 'use-yarn')) pkgManagerOverride = 'yarn'\n else if (hasFlag(args, 'use-bun')) pkgManagerOverride = 'bun'\n\n let backends: BackendKind[] = []\n try {\n backends = parseBackendFlags(args)\n } catch (err) {\n console.error('')\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n let surface: SurfaceKind = 'web'\n try {\n surface = parseSurfaceFlags(args)\n } catch (err) {\n console.error('')\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n // --bare strips the agent deps; a tui/desktop surface needs them. Refuse the contradiction fail-fast.\n if (bare && surface !== 'web') {\n console.error(\n `\\n--bare cannot be combined with --surface=${surface} (the surface needs the agent deps).\\n`,\n )\n process.exit(1)\n }\n\n const targetDir = resolve(process.cwd(), projectName)\n\n // --example: clone from GitHub\n if (exampleFlag) {\n try {\n console.log(`\\nCloning example \"${exampleFlag}\" into ${projectName}...\\n`)\n cloneExample(exampleFlag, targetDir)\n const pkgManager = pkgManagerOverride ?? detectPkgManager()\n if (!skipInstall) {\n console.log(`Installing dependencies with ${pkgManager}...\\n`)\n runInstall(targetDir, pkgManager)\n }\n if (!disableGit) initGit(targetDir)\n console.log(`\\n ✓ Example cloned to ${targetDir}\\n`)\n console.log(` cd ${projectName}`)\n console.log(` ${pkgManager === 'npm' ? 'npm run' : pkgManager} dev\\n`)\n process.exit(0)\n } catch (err) {\n console.error(`\\n ✗ ${(err as Error).message}\\n`)\n process.exit(1)\n }\n }\n\n // Interactive prompts (skipped with --yes or --bare)\n let options: ProjectOptions\n if (useDefaults || bare) {\n options = getDefaults(projectName)\n if (useBiome) options.eslint = false // Biome replaces ESLint\n } else {\n options = await runPrompts(projectName)\n }\n\n try {\n const suffix = bare ? ' [--bare]' : ''\n const surfaceSuffix = surface !== 'web' ? ` [surface: ${surface}]` : ''\n const backendsSuffix = backends.length > 0 ? ` [+services: ${backends.join(', ')}]` : ''\n console.log(\n `\\nCreating TheoKit project \"${projectName}\" (template: ${templateName})${suffix}${surfaceSuffix}${backendsSuffix}...\\n`,\n )\n\n scaffold(targetDir, projectName, templateName, { bare })\n\n // M45 — apply the surface onto the scaffolded default (tui/desktop; web is a no-op).\n applySurfaceStep(targetDir, projectName, surface, options)\n\n // Post-scaffold: apply user options\n applyOptions(targetDir, options, { importAlias, useBiome })\n\n if (backends.length > 0) {\n scaffoldServices({ targetDir, projectName, backends })\n console.log(` ✓ Scaffolded ${String(backends.length)} service(s): ${backends.join(', ')}\\n`)\n }\n\n const pkgManager = pkgManagerOverride ?? detectPkgManager()\n if (skipInstall) {\n console.log(`Skipping install (--skip-install). Run \\`${pkgManager} install\\` manually.\\n`)\n } else {\n console.log(`Installing dependencies with ${pkgManager}...\\n`)\n runInstall(targetDir, pkgManager)\n }\n\n // git init (unless --disable-git)\n if (!disableGit) initGit(targetDir)\n\n console.log(`\\n ✓ Project created at ${targetDir}\\n`)\n console.log(' Next steps:\\n')\n console.log(` cd ${projectName}`)\n if (skipInstall) console.log(` ${pkgManager} install`)\n console.log(` ${pkgManager === 'npm' ? 'npm run' : pkgManager} dev\\n`)\n } catch (err) {\n console.error(`\\n ✗ ${(err as Error).message}\\n`)\n process.exit(1)\n }\n}\n\n// ── Post-scaffold transforms ──\n\n/**\n * M45 — apply the surface onto the scaffolded default (tui/desktop; web is a no-op). Rolls the whole\n * target dir back on failure (EC-4), exactly like --bare, and disables the web-only options a\n * tui/desktop app does not ship.\n */\nfunction applySurfaceStep(\n targetDir: string,\n projectName: string,\n surface: SurfaceKind,\n options: ProjectOptions,\n): void {\n if (surface === 'web') return\n try {\n applySurface({ targetDir, projectName, surface })\n } catch (err) {\n rmSync(targetDir, { recursive: true, force: true })\n const original = err instanceof Error ? err.message : String(err)\n throw new Error(`Scaffold rolled back: surface transform failed.\\nOriginal error: ${original}`)\n }\n options.tailwind = false\n options.srcDir = false\n}\n\ninterface ApplyOpts {\n importAlias: string\n useBiome: boolean\n}\n\nfunction applyOptions(targetDir: string, options: ProjectOptions, opts: ApplyOpts): void {\n const pkgPath = resolve(targetDir, 'package.json')\n\n // Biome: replace ESLint with Biome\n if (opts.useBiome) {\n const eslintPath = resolve(targetDir, 'eslint.config.mjs')\n if (existsSync(eslintPath)) unlinkSync(eslintPath)\n\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n delete pkg.devDependencies.eslint\n delete pkg.devDependencies['eslint-config-prettier']\n delete pkg.devDependencies['typescript-eslint']\n pkg.devDependencies['@biomejs/biome'] = '^1.9.0'\n pkg.scripts.lint = 'biome check .'\n pkg.scripts['lint:fix'] = 'biome check . --fix'\n pkg.scripts.format = 'biome format . --write'\n pkg.scripts['format:check'] = 'biome format .'\n writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\\n')\n\n // Write biome.json\n writeFileSync(\n resolve(targetDir, 'biome.json'),\n JSON.stringify(\n {\n $schema: 'https://biomejs.dev/schemas/1.9.0/schema.json',\n organizeImports: { enabled: true },\n linter: { enabled: true, rules: { recommended: true } },\n formatter: { enabled: true, indentStyle: 'space', indentWidth: 2, lineWidth: 100 },\n },\n null,\n 2,\n ) + '\\n',\n )\n } else if (!options.eslint) {\n // No linter\n const eslintPath = resolve(targetDir, 'eslint.config.mjs')\n if (existsSync(eslintPath)) unlinkSync(eslintPath)\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n delete pkg.scripts.lint\n delete pkg.scripts['lint:fix']\n delete pkg.devDependencies.eslint\n delete pkg.devDependencies['eslint-config-prettier']\n delete pkg.devDependencies['typescript-eslint']\n writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\\n')\n }\n\n // Tailwind\n if (options.tailwind) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n pkg.devDependencies = pkg.devDependencies ?? {}\n pkg.devDependencies.tailwindcss = '^4.0.0'\n pkg.devDependencies['@tailwindcss/vite'] = '^4.0.0'\n writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\\n')\n const cssDir = existsSync(resolve(targetDir, 'src/app')) ? 'src/app' : 'app'\n const cssPath = resolve(targetDir, `${cssDir}/globals.css`)\n const existing = existsSync(cssPath) ? readFileSync(cssPath, 'utf-8') : ''\n writeFileSync(cssPath, '@import \"tailwindcss\";\\n\\n' + existing)\n }\n\n // src/ directory\n if (options.srcDir) {\n const srcDir = resolve(targetDir, 'src')\n mkdirSync(srcDir, { recursive: true })\n for (const dir of ['app', 'server']) {\n const from = resolve(targetDir, dir)\n const to = resolve(srcDir, dir)\n if (existsSync(from)) renameSync(from, to)\n }\n // Move theo.config.ts into src/ for --src-dir mode\n const configFrom = resolve(targetDir, 'theo.config.ts')\n if (existsSync(configFrom)) renameSync(configFrom, resolve(srcDir, 'theo.config.ts'))\n // index.html stays at root — Vite expects it there\n\n const tscPath = resolve(targetDir, 'tsconfig.json')\n const tsc = JSON.parse(readFileSync(tscPath, 'utf-8'))\n tsc.compilerOptions.baseUrl = 'src'\n tsc.include = ['src/**/*.ts', 'src/**/*.tsx']\n writeFileSync(tscPath, JSON.stringify(tsc, null, 2) + '\\n')\n }\n\n // Import alias (custom or disabled)\n const tscPath = resolve(targetDir, 'tsconfig.json')\n const tsc = JSON.parse(readFileSync(tscPath, 'utf-8'))\n if (!options.aliases) {\n delete tsc.compilerOptions.baseUrl\n delete tsc.compilerOptions.paths\n } else if (opts.importAlias !== '@/*') {\n // Custom alias: replace @/* with user choice\n const prefix = opts.importAlias.replace('/*', '')\n tsc.compilerOptions.paths = {\n [`${prefix}/*`]: ['./*'],\n [`${prefix}/server/*`]: ['./server/*'],\n [`${prefix}/app/*`]: ['./app/*'],\n }\n }\n writeFileSync(tscPath, JSON.stringify(tsc, null, 2) + '\\n')\n\n // AGENTS.md\n if (!options.agentsMd) {\n const agentsPath = resolve(targetDir, 'AGENTS.md')\n if (existsSync(agentsPath)) unlinkSync(agentsPath)\n }\n}\n\n// ── Git init ──\n\nfunction initGit(targetDir: string): void {\n try {\n execSync('git init', { cwd: targetDir, stdio: 'ignore' })\n execSync('git add -A', { cwd: targetDir, stdio: 'ignore' })\n execSync('git commit -m \"Initial commit from create-theokit\" --no-verify', {\n cwd: targetDir,\n stdio: 'ignore',\n })\n } catch {\n // git not installed — silently skip\n }\n}\n\n// ── Example cloning ──\n\nfunction cloneExample(example: string, targetDir: string): void {\n const isUrl = example.startsWith('http://') || example.startsWith('https://')\n const repo = isUrl\n ? example\n : `https://github.com/usetheodev/theokit-examples/tree/main/${example}`\n\n if (isUrl) {\n // Full repo URL — shallow clone\n execSync(`git clone --depth 1 ${repo} ${targetDir}`, { stdio: 'inherit' })\n // Remove .git to let user init fresh\n rmSync(join(targetDir, '.git'), { recursive: true, force: true })\n } else {\n // Named example from theokit-examples repo — use degit pattern\n try {\n execSync(`npx --yes degit usetheodev/theokit-examples/${example} ${targetDir}`, {\n stdio: 'inherit',\n })\n } catch {\n throw new Error(\n `Example \"${example}\" not found. ` +\n `Browse available examples at https://github.com/usetheodev/theokit-examples`,\n )\n }\n }\n}\n\n// Auto-execute\nmain().catch((err: unknown) => {\n console.error(err)\n process.exit(1)\n})\n","import spawn from 'cross-spawn'\n\nimport type { PkgManager } from './pkg-manager.js'\n\nexport function runInstall(cwd: string, pkgManager: PkgManager): void {\n const result = spawn.sync(pkgManager, ['install'], {\n cwd,\n stdio: 'inherit',\n env: { ...process.env, NODE_ENV: 'development' },\n })\n\n if (result.status !== 0) {\n throw new Error(`Failed to install dependencies with ${pkgManager}`)\n }\n}\n","export type PkgManager = 'npm' | 'pnpm' | 'yarn' | 'bun'\n\nexport function detectPkgManager(): PkgManager {\n const ua = process.env.npm_config_user_agent ?? ''\n if (ua.startsWith('yarn')) return 'yarn'\n if (ua.startsWith('pnpm')) return 'pnpm'\n if (ua.startsWith('bun')) return 'bun'\n return 'npm'\n}\n","/**\n * Node version preflight for `create-theokit`.\n *\n * `@theokit/sdk` declares `engines.node: \">=22.12.0\"`. Users on older Node\n * hit cryptic `node:sqlite` / `better-sqlite3` ABI errors mid-chat without\n * any actionable diagnostic. This preflight runs at scaffold start, prints\n * a clear error, and exits before any FS write (ADR D4 of the plan).\n *\n * Zero-dep semver comparator — no `semver` package needed.\n */\n\n/** Minimum Node version required by `@theokit/sdk`. */\nexport const MIN_NODE_VERSION = '22.12.0'\n\n/**\n * Compare two semver strings (major.minor.patch). Strips leading `v` from\n * either side. Pre-release suffixes (e.g., `-rc.1`, `-nightly...`) are\n * parsed as the base patch — acceptable for a preflight (we're not gating\n * on exact pre-release ordering).\n *\n * Returns:\n * <0 when a < b\n * 0 when a == b\n * >0 when a > b\n */\nexport function compareSemver(a: string, b: string): number {\n const parse = (raw: string): [number, number, number] => {\n const stripped = raw.replace(/^v/, '').split('-')[0] ?? '0.0.0'\n const parts = stripped.split('.').map((s) => Number.parseInt(s, 10) || 0)\n return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0]\n }\n const [aMaj, aMin, aPat] = parse(a)\n const [bMaj, bMin, bPat] = parse(b)\n if (aMaj !== bMaj) return aMaj - bMaj\n if (aMin !== bMin) return aMin - bMin\n return aPat - bPat\n}\n\n/**\n * Throw with an actionable message if `currentRaw` is below `minimum`.\n * Default minimum is `MIN_NODE_VERSION` (22.12.0).\n *\n * Called as the first line of `create-theokit`'s `main` so the preflight\n * fires before any directory is written.\n */\nexport function assertNodeVersion(currentRaw: string, minimum: string = MIN_NODE_VERSION): void {\n const current = currentRaw.replace(/^v/, '')\n if (compareSemver(currentRaw, minimum) < 0) {\n throw new Error(\n `create-theokit requires Node ${minimum} or later (the @theokit/sdk peer engines floor).\\n` +\n ` Detected: Node ${current}\\n` +\n ` Fix: nvm install 22 && nvm use 22\\n` +\n ` (or your version manager equivalent — fnm, volta, asdf, nvs)\\n`,\n )\n }\n}\n","/**\n * Interactive prompts for create-theokit.\n * Skipped when --yes flag is passed (uses defaults).\n *\n * Uses Node.js readline (zero deps) — not inquirer/prompts.\n */\nimport { createInterface } from 'node:readline'\n\nexport interface ProjectOptions {\n projectName: string\n typescript: boolean\n eslint: boolean\n tailwind: boolean\n srcDir: boolean\n aliases: boolean\n agentsMd: boolean\n}\n\nconst DEFAULTS: Omit<ProjectOptions, 'projectName'> = {\n typescript: true,\n eslint: true,\n tailwind: true,\n srcDir: false,\n aliases: true,\n agentsMd: true,\n}\n\nasync function ask(rl: ReturnType<typeof createInterface>, question: string, defaultVal: boolean): Promise<boolean> {\n return new Promise((resolve) => {\n const suffix = defaultVal ? '(Y/n)' : '(y/N)'\n rl.question(` ${question} ${suffix} `, (answer) => {\n const a = answer.trim().toLowerCase()\n if (a === '') resolve(defaultVal)\n else resolve(a === 'y' || a === 'yes')\n })\n })\n}\n\nasync function askChoice(rl: ReturnType<typeof createInterface>, question: string, choices: string[], defaultIdx = 0): Promise<number> {\n return new Promise((resolve) => {\n console.log(` ${question}`)\n for (let i = 0; i < choices.length; i++) {\n const marker = i === defaultIdx ? '❯' : ' '\n console.log(` ${marker} ${choices[i]}`)\n }\n rl.question(' Choice (number): ', (answer) => {\n const n = parseInt(answer.trim(), 10)\n resolve(n >= 1 && n <= choices.length ? n - 1 : defaultIdx)\n })\n })\n}\n\nexport async function runPrompts(projectName: string): Promise<ProjectOptions> {\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n\n try {\n console.log('')\n const mode = await askChoice(rl, 'Would you like to use the recommended TheoKit defaults?', [\n 'Yes, use recommended defaults — TypeScript, ESLint, Tailwind CSS, AGENTS.md',\n 'No, customize settings',\n ], 0)\n\n if (mode === 0) {\n return { projectName, ...DEFAULTS }\n }\n\n const typescript = await ask(rl, 'Would you like to use TypeScript?', true)\n const eslint = await ask(rl, 'Would you like to use ESLint?', true)\n const tailwind = await ask(rl, 'Would you like to use Tailwind CSS?', true)\n const srcDir = await ask(rl, 'Would you like your code inside a `src/` directory?', false)\n const aliases = await ask(rl, 'Would you like to use import alias (@/*)?', true)\n const agentsMd = await ask(rl, 'Would you like to include AGENTS.md for coding agents?', true)\n\n return { projectName, typescript, eslint, tailwind, srcDir, aliases, agentsMd }\n } finally {\n rl.close()\n }\n}\n\nexport function getDefaults(projectName: string): ProjectOptions {\n return { projectName, ...DEFAULTS }\n}\n","/**\n * Build-time scaffold helper. All write paths derived from the trusted\n * targetDir (CLI argument, resolved absolute). Read paths are the\n * bundled service templates shipped with this package.\n */\n/**\n * Phase 4 — `--backend python|node` scaffolding (T4.1, T4.2).\n *\n * After the main TheoKit scaffold runs, this helper:\n * - Copies the requested service template(s) under `<target>/services/<name>/`\n * - Substitutes `{{name}}` in `.tmpl` files\n * - Renames `.tmpl` files to drop the suffix\n * - Injects services config into the user's `theo.config.ts`\n * - Injects `@hey-api/client-fetch` into the user's package.json (EC-10)\n */\nimport {\n cpSync,\n existsSync,\n readFileSync,\n readdirSync,\n statSync,\n writeFileSync,\n unlinkSync,\n} from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\n// node-only polyglot backend (decision 2026-06-17). Python scaffolding was\n// deferred — only the Node (Hono) sidecar template ships. Re-adding Python\n// requires restoring its template + an ADR with demand evidence.\nexport type BackendKind = 'node'\n\nconst VALID_BACKENDS = ['node'] as const\n\n/**\n * Parse `--backend node` (multi-value) from argv.\n *\n * Accepts:\n * --backend node\n * --backend=node\n *\n * Throws on unknown backend name (incl. `python`, which is not shipped).\n */\nexport function parseBackendFlags(args: string[]): BackendKind[] {\n const out: BackendKind[] = []\n for (let i = 0; i < args.length; i++) {\n const a = args[i] ?? ''\n let value: string | undefined\n if (a === '--backend') {\n value = args[i + 1]\n i++\n } else if (a.startsWith('--backend=')) {\n value = a.slice('--backend='.length)\n }\n if (value === undefined) continue\n if (!(VALID_BACKENDS as readonly string[]).includes(value)) {\n throw new Error(\n `unknown --backend value: '${value}'. Valid options: ${VALID_BACKENDS.join(', ')}.`,\n )\n }\n out.push(value as BackendKind)\n }\n return out\n}\n\nconst BACKEND_CONFIG: Record<\n BackendKind,\n {\n templateDir: string\n serviceName: string\n port: number\n proxy: string\n dev: string\n start: string\n }\n> = {\n node: {\n templateDir: 'agent-node',\n serviceName: 'worker',\n port: 8002,\n proxy: '/api/worker',\n dev: 'pnpm dev',\n start: 'pnpm start',\n },\n}\n\nfunction getServiceTemplateDir(kind: BackendKind): string {\n return resolve(__dirname, '../templates/services', BACKEND_CONFIG[kind].templateDir)\n}\n\nfunction substituteTmpls(dir: string, projectName: string): void {\n for (const entry of readdirSync(dir)) {\n const full = join(dir, entry)\n const stat = statSync(full)\n if (stat.isDirectory()) {\n substituteTmpls(full, projectName)\n continue\n }\n if (entry.endsWith('.tmpl')) {\n const content = readFileSync(full, 'utf-8').replace(/\\{\\{name\\}\\}/g, projectName)\n const dest = full.replace(/\\.tmpl$/, '')\n writeFileSync(dest, content)\n unlinkSync(full)\n }\n }\n}\n\ninterface ServiceEntry {\n runtime: BackendKind\n port: number\n proxy: string\n dev: string\n start: string\n}\n\n/**\n * Build the `services: {}` snippet to inject into `theo.config.ts`.\n * Returns the inner record literal — caller wraps in `services: { ... }`.\n */\nexport function buildServicesSnippet(selections: { name: string; entry: ServiceEntry }[]): string {\n if (selections.length === 0) return ''\n const blocks = selections.map(({ name, entry }) => {\n return ` ${name}: {\n runtime: '${entry.runtime}',\n port: ${String(entry.port)},\n proxy: '${entry.proxy}',\n dev: ${JSON.stringify(entry.dev)},\n start: ${JSON.stringify(entry.start)},\n },`\n })\n return ` services: {\\n${blocks.join('\\n')}\\n },\\n`\n}\n\n/**\n * Insert the services block into an existing `theo.config.ts`.\n * Strategy: find `defineConfig({` and append the services block before the closing brace.\n */\nexport function injectServicesIntoConfig(configSource: string, snippet: string): string {\n if (snippet.length === 0) return configSource\n if (configSource.includes('services:')) return configSource // already present\n\n // Match the LAST `}` before the closing of defineConfig({...})\n const re = /defineConfig\\(\\{([\\s\\S]*?)\\}\\)/m\n const match = re.exec(configSource)\n if (!match) return configSource\n\n const inner = match[1]\n // Strip trailing whitespace without backtracking-prone \\s+$ regex.\n let trimEnd = inner.length\n while (trimEnd > 0 && /\\s/.test(inner.charAt(trimEnd - 1))) {\n trimEnd--\n }\n const trimmed = inner.slice(0, trimEnd)\n const sep = trimmed.length > 0 && !trimmed.endsWith(',') ? ',\\n' : '\\n'\n const newInner = `${trimmed}${sep}${snippet}`\n return configSource.replace(re, `defineConfig({${newInner}})`)\n}\n\nexport function injectHeyApiDep(packageJsonSource: string): string {\n const pkg = JSON.parse(packageJsonSource) as {\n dependencies?: Record<string, string>\n }\n pkg.dependencies = pkg.dependencies ?? {}\n if (!('@hey-api/client-fetch' in pkg.dependencies)) {\n pkg.dependencies['@hey-api/client-fetch'] = '^0.6.0'\n }\n return JSON.stringify(pkg, null, 2) + '\\n'\n}\n\nexport interface ScaffoldServicesOptions {\n /** Target project directory (already scaffolded with the TS template). */\n targetDir: string\n /** Project name (substituted into .tmpl files). */\n projectName: string\n /** Which backends to scaffold. */\n backends: BackendKind[]\n}\n\nexport function scaffoldServices(options: ScaffoldServicesOptions): void {\n if (options.backends.length === 0) return\n\n const selections: { name: string; entry: ServiceEntry }[] = []\n\n for (const kind of options.backends) {\n const cfg = BACKEND_CONFIG[kind]\n const src = getServiceTemplateDir(kind)\n // Schema contract: dev/start commands run from `services/<serviceName>/` cwd\n // (services/schema/schema.ts line 35). The destination MUST equal serviceName\n // so the orchestrator's cwd resolution matches the on-disk directory.\n const dest = join(options.targetDir, 'services', cfg.serviceName)\n if (!existsSync(src)) {\n throw new Error(`service template not found: ${src}`)\n }\n cpSync(src, dest, { recursive: true })\n substituteTmpls(dest, options.projectName)\n\n selections.push({\n name: cfg.serviceName,\n entry: {\n runtime: kind,\n port: cfg.port,\n proxy: cfg.proxy,\n dev: cfg.dev,\n start: cfg.start,\n },\n })\n }\n\n // Inject services into theo.config.ts\n const configPath = join(options.targetDir, 'theo.config.ts')\n if (existsSync(configPath)) {\n const cfgSrc = readFileSync(configPath, 'utf-8')\n const snippet = buildServicesSnippet(selections)\n const updated = injectServicesIntoConfig(cfgSrc, snippet)\n if (updated !== cfgSrc) {\n writeFileSync(configPath, updated)\n }\n }\n\n // EC-10: inject @hey-api/client-fetch into user's package.json\n const pkgPath = join(options.targetDir, 'package.json')\n if (existsSync(pkgPath)) {\n const pkgSrc = readFileSync(pkgPath, 'utf-8')\n const updated = injectHeyApiDep(pkgSrc)\n writeFileSync(pkgPath, updated)\n }\n\n // Rename .gitignore for services if needed (none currently shipped, but reserved hook)\n}\n","import {\n cpSync,\n existsSync,\n readdirSync,\n readFileSync,\n rmSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n// ESM has no CJS `__dirname` global — derive it (mirrors src/index.ts + src/scaffold-services.ts). Without\n// this the published bundle throws `__dirname is not defined` at runtime (vitest provides the global, so the\n// unit tests never caught it — only running `npx create-theokit --surface tui` for real surfaced it).\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\n/**\n * M45 (ADR-0054) — `create-theokit --surface web|tui|desktop`.\n *\n * A FLAG-driven additive scaffold (mirrors `--backend` / `scaffoldServices`), NOT a new top-level\n * template (ADR-0023 default-only respected). `web` is the default (the existing web app — no-op).\n * `tui` / `desktop` copy a template fragment (`templates/surfaces/<kind>/`) onto the scaffolded default,\n * mutate `package.json` (drop web-only deps, add surface deps + scripts), and remove the web UI. Each\n * scaffolded surface consumes the agent via the M41/M42/M44 UNIFIED client (ADR-0054 D2), not the raw\n * seam. All Tauri/Ink boilerplate lives HERE in the scaffolder templates — framework core stays agnostic.\n */\nexport type SurfaceKind = 'web' | 'tui' | 'desktop'\n\nconst VALID_SURFACES = ['web', 'tui', 'desktop'] as const\n\n/**\n * Web-only deps dropped for the tui/desktop surfaces (they ship no web UI). `react-router` is NOT dropped\n * — `theokit` declares it a REQUIRED peer, so removing it breaks `npm install` (ERESOLVE). `ai` is NOT\n * dropped either: although the tui's RENDER is ai-free (`@theokit/tui` + `messagesToAgentEvents`), theokit's\n * in-process agent runtime (`streamAgentTurnInProcess` → the UIMessageStream protocol) imports `ai` at\n * RUNTIME, so every surface that runs an agent must keep it installed.\n */\nconst WEB_ONLY_DEPS = ['@theokit/ui', '@usetheo/ui', 'lucide-react'] as const\nconst WEB_ONLY_DEV_DEPS = ['tailwindcss', '@tailwindcss/vite', 'tailwindcss-animate'] as const\n/** Web UI files removed for the tui/desktop surfaces. */\nconst WEB_ONLY_FILES = ['app', 'index.html', 'tailwind.config.ts', 'postcss.config.js'] as const\n\ninterface SurfaceConfig {\n /** The template fragment dir under `templates/surfaces/`. */\n fragment: string\n /** Deps ADDED for this surface. */\n deps: Record<string, string>\n /** Dev deps ADDED for this surface. */\n devDeps: Record<string, string>\n /** Scripts SET for this surface (override the web dev/build). */\n scripts: Record<string, string>\n /** `tsconfig.json` `include` for this surface (the default's `app/**` is removed with the web UI). */\n tsconfigInclude: string[]\n}\n\nconst SURFACE_CONFIG: Record<Exclude<SurfaceKind, 'web'>, SurfaceConfig> = {\n tui: {\n fragment: 'tui',\n // `@theokit/tui` renders the conversation via `<AgentTimeline>` (Markdown + fenced code + collapsible\n // tool cards — the Claude-Code render), projected from `useAgent().thread` by the ai-free\n // `messagesToAgentEvents` (structural `UIMessageLike`) — so the TUI's own code + `@theokit/tui` never\n // import `ai`. `ai` is still declared because theokit's in-process agent runtime\n // (`streamAgentTurnInProcess` → the UIMessageStream protocol) imports it at RUNTIME. `ink@7` is the\n // React-19 line (ink@5 crashes on React 19 with `ReactCurrentOwner`; the default template pins react@19;\n // ink@6.0.0+ moved its peer to react>=19), matching @theokit/tui's own ink@^7.1.0 so the app's\n // `import 'ink'` dedupes to one React-19 ink. `figlet` (banner ASCII) + `lowlight` (code highlight) are\n // @theokit/tui PEERS the app relies on — declared so pnpm (which never auto-installs peers) resolves them.\n deps: {\n '@theokit/tui': '^0.37.0',\n ink: '^7.1.0',\n ai: '^7.0.0',\n figlet: '^1.7.0',\n lowlight: '^3.0.0',\n },\n devDeps: { tsx: '^4.19.0' },\n scripts: {\n dev: 'tsx tui/main.tsx',\n start: 'tsx tui/main.tsx',\n // A visual reference of every tool render state (pending/running/success/failed/…) — no agent needed.\n 'demo:tools': 'tsx tui/tool-variations.tsx',\n },\n tsconfigInclude: [\n 'tui/**/*.ts',\n 'tui/**/*.tsx',\n 'server/**/*.ts',\n 'agents/**/*.ts',\n 'shared/**/*.ts',\n ],\n },\n desktop: {\n fragment: 'desktop',\n // M47: the webview is a React app rendering with `@theokit/ui`, driven by `useAgent` over a\n // `ChannelTransport` whose source is `@theokit/tauri`'s `createTauriChannelSource`; the Node sidecar\n // runs the turn via `@theokit/tauri/sidecar`. `ai` = the UIMessageStream reader + UIMessage type (was\n // transitive via `@theokit/ui`, re-added explicitly here). react/react-dom are inherited from the default.\n // Same rich surface as the web default → same UI deps: `@usetheo/ui` (Button) + `lucide-react` (icons),\n // matching the web template's versions. `@theokit/ui` components self-style via the precompiled sheet.\n deps: {\n '@theokit/ui': '^1.0.0',\n '@usetheo/ui': '^0.26.0',\n '@theokit/tauri': '^0.1.1',\n 'lucide-react': '^0.469.0',\n ai: '^7.0.0',\n },\n devDeps: {\n tsx: '^4.19.0',\n '@tauri-apps/cli': '^2.0.0',\n vite: '^6.0.0',\n '@vitejs/plugin-react': '^4.3.0',\n },\n scripts: {\n dev: 'tauri dev',\n tauri: 'tauri',\n 'build:frontend': 'vite build frontend',\n // Generates the Tauri externalBin launcher (src-tauri/binaries/theo-sidecar-<triple>) the Rust\n // shell spawns. Wired into tauri.conf.json beforeDev/BuildCommand — regenerated each launch.\n 'build:sidecar': 'node scripts/build-sidecar.mjs',\n },\n tsconfigInclude: [\n 'sidecar/**/*.ts',\n 'frontend/src/**/*.ts',\n 'frontend/src/**/*.tsx',\n 'server/**/*.ts',\n 'agents/**/*.ts',\n 'shared/**/*.ts',\n ],\n },\n}\n\n/** Parse `--surface <kind>` / `--surface=<kind>`; default `web`. Fail-fast on an unknown value. */\nexport function parseSurfaceFlags(args: string[]): SurfaceKind {\n let surface: SurfaceKind = 'web'\n for (let i = 0; i < args.length; i++) {\n const a = args[i] ?? ''\n let value: string | undefined\n if (a === '--surface') {\n value = args[i + 1]\n i++\n } else if (a.startsWith('--surface=')) {\n value = a.slice('--surface='.length)\n }\n if (value === undefined) continue\n if (!(VALID_SURFACES as readonly string[]).includes(value)) {\n throw new Error(\n `unknown --surface value: '${value}'. Valid options: ${VALID_SURFACES.join(', ')}.`,\n )\n }\n surface = value as SurfaceKind\n }\n return surface\n}\n\n/** Locate the fragment dir shipped alongside the compiled scaffolder. */\nfunction getSurfaceFragmentDir(fragment: string): string {\n return resolve(__dirname, '../templates/surfaces', fragment)\n}\n\n/** Recursively substitute `{{name}}` in `.tmpl` files (mirrors scaffoldServices). */\nfunction substituteTmpls(dir: string, projectName: string): void {\n for (const entry of readdirSync(dir)) {\n const full = join(dir, entry)\n if (statSync(full).isDirectory()) {\n substituteTmpls(full, projectName)\n continue\n }\n if (entry.endsWith('.tmpl')) {\n const content = readFileSync(full, 'utf-8').replace(/\\{\\{name\\}\\}/g, projectName)\n writeFileSync(full.replace(/\\.tmpl$/, ''), content)\n unlinkSync(full)\n }\n }\n}\n\nexport interface ApplySurfaceOptions {\n targetDir: string\n projectName: string\n surface: SurfaceKind\n /** Test-only: force a failure to exercise the caller's rollback (mirrors --bare `_testForceError`). */\n _testForceError?: string\n}\n\ninterface PartialPackageJson {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n scripts?: Record<string, string>\n [key: string]: unknown\n}\n\n/**\n * Apply a surface onto a freshly-scaffolded default template. `web` is a no-op (the default IS web).\n * `tui`/`desktop` copy the fragment, drop web-only deps + UI, and add the surface's deps/scripts. Throws\n * on any failure so the CLI can roll the whole target dir back (EC-4), exactly like `--bare`.\n */\nexport function applySurface(options: ApplySurfaceOptions): void {\n if (options._testForceError !== undefined) {\n throw new Error(`Forced surface failure: ${options._testForceError}`)\n }\n if (options.surface === 'web') return\n\n const cfg = SURFACE_CONFIG[options.surface]\n const src = getSurfaceFragmentDir(cfg.fragment)\n if (!existsSync(src)) {\n throw new Error(`surface fragment not found: ${src}`)\n }\n\n // 1. Copy the fragment onto the target, then substitute {{name}}.\n cpSync(src, options.targetDir, { recursive: true })\n substituteTmpls(options.targetDir, options.projectName)\n\n // 2. Remove the web UI (a tui/desktop app ships no web surface).\n for (const rel of WEB_ONLY_FILES) {\n const p = join(options.targetDir, rel)\n if (existsSync(p)) rmSync(p, { recursive: true, force: true })\n }\n\n // 3. Mutate package.json: drop web-only deps, add surface deps + scripts.\n const pkgPath = join(options.targetDir, 'package.json')\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PartialPackageJson\n pkg.dependencies = { ...dropKeys(pkg.dependencies, WEB_ONLY_DEPS), ...cfg.deps }\n pkg.devDependencies = { ...dropKeys(pkg.devDependencies, WEB_ONLY_DEV_DEPS), ...cfg.devDeps }\n pkg.scripts = { ...(pkg.scripts ?? {}), ...cfg.scripts }\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`)\n }\n\n // 4. Point `tsconfig.json` `include` at the surface's source (the default's `app/**` went with the web\n // UI) — so `tsc` in the generated project type-checks the surface entry files (the unified-client wiring).\n const tsconfigPath = join(options.targetDir, 'tsconfig.json')\n if (existsSync(tsconfigPath)) {\n const tsconfig = JSON.parse(readFileSync(tsconfigPath, 'utf-8')) as { include?: string[] }\n tsconfig.include = cfg.tsconfigInclude\n writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\\n`)\n }\n}\n\n/** Return a copy of `record` without `keys` (no dynamic `delete` — filter-rebuild). */\nfunction dropKeys(\n record: Record<string, string> | undefined,\n keys: readonly string[],\n): Record<string, string> {\n return Object.fromEntries(Object.entries(record ?? {}).filter(([k]) => !keys.includes(k)))\n}\n","/**\n * `create-theokit` scaffold tool. All write paths are derived from the\n * user-supplied target directory (CLI argument, resolved to absolute).\n * Read paths are the bundled `templates/` shipped with this package.\n * Build-time tool — no HTTP input.\n */\nimport {\n existsSync,\n cpSync,\n readFileSync,\n writeFileSync,\n renameSync,\n unlinkSync,\n readdirSync,\n rmSync,\n statSync,\n} from 'node:fs'\nimport { resolve, join, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { applyBareTransform } from './bare-transform.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nfunction getTemplateDir(templateName = 'default'): string {\n return resolve(__dirname, '../templates', templateName)\n}\n\nfunction isValidProjectName(name: string): boolean {\n return /^[a-z0-9][a-z0-9._-]*$/.test(name)\n}\n\nexport interface ScaffoldOptions {\n bare?: boolean\n /** Test-only — force the bare transform to throw to validate EC-4 rollback. */\n _testForceTransformError?: string\n}\n\nexport function scaffold(\n targetDir: string,\n projectName: string,\n templateName = 'default',\n options: ScaffoldOptions = {},\n): void {\n // EC-4 + ADR D5: --bare only applies to default template\n if (options.bare && templateName !== 'default') {\n throw new Error(\n `--bare flag only applies to the default template; got \"${templateName}\". ` +\n `Use \\`npx create-theokit <name> --template=default --bare\\` or pick a different template.`,\n )\n }\n\n const templateDir = getTemplateDir(templateName)\n\n if (!existsSync(templateDir)) {\n throw new Error(`Template \"${templateName}\" not found. Available templates: default`)\n }\n\n // Bug #1 fix: \".\" means current directory — use dir basename as project name\n const resolvedName =\n projectName === '.' ? (resolve(targetDir).split('/').pop() ?? 'my-app') : projectName\n\n if (!isValidProjectName(resolvedName)) {\n throw new Error(\n `Invalid project name \"${resolvedName}\". ` +\n `Use lowercase letters, numbers, hyphens, and dots. Must start with a letter or number.`,\n )\n }\n\n if (existsSync(targetDir)) {\n const contents = readdirSync(targetDir)\n if (contents.length > 0) {\n throw new Error(`Directory \"${targetDir}\" is not empty. Please use an empty directory.`)\n }\n }\n\n cpSync(templateDir, targetDir, { recursive: true })\n\n const gitignoreSrc = join(targetDir, '_gitignore')\n const gitignoreDest = join(targetDir, '.gitignore')\n if (existsSync(gitignoreSrc)) {\n renameSync(gitignoreSrc, gitignoreDest)\n }\n\n // dot-claude/ → .claude/ (npm ignores dotfolders in published packages)\n const dotClaudeSrc = join(targetDir, 'dot-claude')\n const dotClaudeDest = join(targetDir, '.claude')\n if (existsSync(dotClaudeSrc)) {\n renameSync(dotClaudeSrc, dotClaudeDest)\n }\n\n // Apply {{name}} substitution to every `*.tmpl` file in the target dir.\n // Each `foo.tmpl` becomes `foo` with placeholders replaced. Walks only\n // the project root (deeper subfolders don't currently need templating).\n for (const entry of readdirSync(targetDir)) {\n if (!entry.endsWith('.tmpl')) continue\n const src = join(targetDir, entry)\n const stat = statSync(src)\n if (!stat.isFile()) continue\n const dst = join(targetDir, entry.slice(0, -'.tmpl'.length))\n const content = readFileSync(src, 'utf-8')\n const replaced = content.replace(/\\{\\{name\\}\\}/g, resolvedName)\n writeFileSync(dst, replaced)\n unlinkSync(src)\n }\n\n // T4.1 — Apply --bare transform with EC-4 atomic rollback\n if (options.bare) {\n try {\n applyBareTransform(targetDir, {\n _testForceError: options._testForceTransformError,\n })\n } catch (err) {\n // EC-4: roll back partial state\n rmSync(targetDir, { recursive: true, force: true })\n const original = err instanceof Error ? err.message : String(err)\n throw new Error(\n `Scaffold rolled back: bare transform failed. Check filesystem perms.\\nOriginal error: ${original}`,\n )\n }\n }\n}\n","/**\n * Scaffold transform. Mutates files inside the freshly-created target\n * directory whose absolute path is the function input. No HTTP input.\n */\n/**\n * T4.1 — `--bare` transformation.\n *\n * Applied AFTER the default template is copied. Removes:\n * - `@theokit/ui` from `package.json` dependencies (TheoUI bundled components)\n * - `@theokit/sdk` from `package.json` dependencies (agent SDK — see below)\n * - `@theokit/agents` from `package.json` dependencies (only agents/chat.ts used it)\n * - `app/page.tsx` agent-surface content (replaces with Hello Theo)\n * - `agents/chat.ts` (the demo agent — depends on the SDK + TheoUI page)\n * - `tailwind.config.ts` + `postcss.config.js` (Tailwind toolchain — only\n * needed by the @theokit/ui-driven default surface)\n * - tailwind* + postcss* from devDependencies (toolchain cleanup)\n *\n * Why SDK removal is in --bare:\n * `@theokit/sdk` is not yet on the public npm registry (operator-deferred\n * publish per macro roadmap item #3). A user running `npx create-theokit`\n * without `--bare` hits `npm install` → 404. The `--bare` path produces a\n * scaffold that ALWAYS works without registry dependencies — Hello Theo\n * with a clean structure to grow into.\n *\n * EC-4: callers MUST wrap this in try/catch + `rmSync` rollback so a partial\n * transform never leaves the target dir in a broken state.\n */\n\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, rmSync } from 'node:fs'\nimport { join } from 'node:path'\n\nconst HELLO_PAGE = `export default function Page() {\n return <h1>Hello Theo</h1>\n}\n`\n\n// --bare ships an unstyled shell: no @theokit/ui Header, no styles.css import. Replaces the default\n// layout (which composes components/Header.tsx + imports @theokit/ui, both dropped by --bare).\nconst BARE_LAYOUT = `import { Outlet } from 'react-router'\n\nexport default function RootLayout() {\n return <Outlet />\n}\n`\n\nexport interface BareTransformOptions {\n /** Test-only — force a synthetic write failure to validate rollback path. */\n _testForceError?: string\n}\n\nexport function applyBareTransform(targetDir: string, options: BareTransformOptions = {}): void {\n if (options._testForceError) {\n throw new Error(`Forced transform failure: ${options._testForceError}`)\n }\n\n // 1. Remove @theokit/ui + @theokit/sdk + tailwind toolchain from deps\n const pkgPath = join(targetDir, 'package.json')\n if (existsSync(pkgPath)) {\n interface PartialPackageJson {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n [key: string]: unknown\n }\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as PartialPackageJson\n if (pkg.dependencies) {\n delete pkg.dependencies['@theokit/ui']\n // Drop SDK — operator-deferred npm publish (macro roadmap item #3).\n // Without removal, `npm install` hits 404 for any consumer outside\n // the workspace.\n delete pkg.dependencies['@theokit/sdk']\n // --bare removes the demo agent (agents/chat.ts), so its runtime dep\n // (@theokit/agents, imported only by that file) goes with it.\n delete pkg.dependencies['@theokit/agents']\n // lucide-react ships with the TheoUI surface; --bare doesn't render\n // any icons so it's safe to drop.\n delete pkg.dependencies['lucide-react']\n }\n if (pkg.devDependencies) {\n // Tailwind toolchain is only needed by the @theokit/ui-driven default\n // surface. --bare ships unstyled Hello Theo; no Tailwind required.\n delete pkg.devDependencies.tailwindcss\n delete pkg.devDependencies['tailwindcss-animate']\n delete pkg.devDependencies.postcss\n delete pkg.devDependencies.autoprefixer\n }\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`)\n }\n\n // 2. Replace app/page.tsx (Hello Theo) + app/layout.tsx (unstyled shell) — the defaults compose the chat\n // surface + import @theokit/ui, which --bare drops.\n const pagePath = join(targetDir, 'app/page.tsx')\n if (existsSync(pagePath)) {\n writeFileSync(pagePath, HELLO_PAGE)\n }\n const layoutPath = join(targetDir, 'app/layout.tsx')\n if (existsSync(layoutPath)) {\n writeFileSync(layoutPath, BARE_LAYOUT)\n }\n\n // 3. Remove the demo chat agent (the `agents/chat.ts` file + its TheoUI page)\n const chatPath = join(targetDir, 'agents/chat.ts')\n if (existsSync(chatPath)) {\n unlinkSync(chatPath)\n }\n\n // 3b. Remove the chat frontend surface — `app/{components,hooks,lib}/` (import @theokit/ui) + the\n // `app/about/` example route (part of the chat demo). The Hello-Theo page references none of them.\n // (The route surface — layout/page/error/… — is kept; page + layout are rewritten above.)\n for (const dir of ['app/components', 'app/hooks', 'app/lib', 'app/about']) {\n const p = join(targetDir, dir)\n if (existsSync(p)) rmSync(p, { recursive: true, force: true })\n }\n\n // 4. Remove tailwind + postcss config files (toolchain dropped from devDeps)\n const tailwindCfg = join(targetDir, 'tailwind.config.ts')\n if (existsSync(tailwindCfg)) {\n unlinkSync(tailwindCfg)\n }\n const postcssCfg = join(targetDir, 'postcss.config.js')\n if (existsSync(postcssCfg)) {\n unlinkSync(postcssCfg)\n }\n}\n"],"mappings":"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","names":["readFileSync","writeFileSync","unlinkSync","renameSync","existsSync","rmSync","resolve","join","resolve","cpSync","existsSync","readdirSync","readFileSync","statSync","unlinkSync","writeFileSync","dirname","join","resolve","fileURLToPath","__dirname","substituteTmpls","existsSync","cpSync","readFileSync","writeFileSync","unlinkSync","readdirSync","rmSync","statSync","resolve","join","dirname","fileURLToPath","existsSync","readFileSync","writeFileSync","unlinkSync","rmSync","join","__dirname","dirname","fileURLToPath","resolve","existsSync","readdirSync","cpSync","join","statSync","readFileSync","writeFileSync","unlinkSync","rmSync","resolve","rmSync","existsSync","unlinkSync","readFileSync","writeFileSync","renameSync","tscPath","tsc","join"]}
|
package/package.json
CHANGED
|
@@ -25,8 +25,15 @@ export const ACCENT = '#d97757'
|
|
|
25
25
|
export const THEME: TheoThemeProp = {
|
|
26
26
|
base: 'dark', // 'dark' · 'light' · 'no-color'
|
|
27
27
|
override: {
|
|
28
|
-
|
|
29
|
-
//
|
|
28
|
+
// Color is reserved for MEANING. The chrome — the assistant `⏺` bullet, the `>` prompt, and the input
|
|
29
|
+
// border — stays MONOCHROME (terminal default). Semantic colors (tool states: pending gray · running
|
|
30
|
+
// yellow · success green · failed red; and errors) keep their color. Set `accent: ACCENT` to tint the
|
|
31
|
+
// chrome, or give `role.*.prefix` a color name/hex to tint the bullets.
|
|
32
|
+
accent: '', // the input border (the banner uses ACCENT directly, so it always stays colored)
|
|
33
|
+
role: {
|
|
34
|
+
assistant: { prefix: '' }, // the assistant `⏺` bullet
|
|
35
|
+
user: { prefix: '' }, // the `>` prompt (conversation + input)
|
|
36
|
+
},
|
|
30
37
|
// toolStatus: { pending: { glyph: '○' }, success: { glyph: '●' }, failed: { glyph: '✗' } },
|
|
31
38
|
},
|
|
32
39
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A tiny visual reference — `npm run demo:tools` — showing every way the timeline renders a tool, so you
|
|
3
|
+
* can see the states (and your `tui/theme.ts` colors/glyphs) without driving a real agent. It feeds a
|
|
4
|
+
* synthetic conversation through the SAME `messagesToAgentEvents` → `<AgentTimeline>` path the real app
|
|
5
|
+
* uses, so what you see here is exactly what a live turn renders. Delete this file if you don't want it.
|
|
6
|
+
*/
|
|
7
|
+
import { Box, render, Text } from 'ink'
|
|
8
|
+
import { type ReactElement } from 'react'
|
|
9
|
+
import { AgentTimeline, messagesToAgentEvents, TheoTUIProvider, type UIMessageLike } from '@theokit/tui'
|
|
10
|
+
|
|
11
|
+
import { THEME } from './theme.js'
|
|
12
|
+
|
|
13
|
+
/** A one-part assistant message carrying a tool in a given ai-sdk state (the shape `useAgent().thread` holds). */
|
|
14
|
+
const tool = (name: string, state: string, extra: Record<string, unknown> = {}): UIMessageLike => ({
|
|
15
|
+
id: `t-${name}`,
|
|
16
|
+
role: 'assistant',
|
|
17
|
+
parts: [{ type: 'dynamic-tool', toolName: name, toolCallId: `c-${name}`, input: { q: 'demo' }, state, ...extra }],
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
/** One of each: a user turn, an assistant markdown turn, a thinking row, then every tool state. */
|
|
21
|
+
const THREAD: UIMessageLike[] = [
|
|
22
|
+
{ id: 'u1', role: 'user', parts: [{ type: 'text', text: 'show me every tool render state' }] },
|
|
23
|
+
{ id: 'a1', role: 'assistant', parts: [{ type: 'text', text: 'Here is **each** state the timeline renders:' }] },
|
|
24
|
+
{ id: 'think', role: 'assistant', parts: [{ type: 'reasoning', text: 'planning the demo…' }] },
|
|
25
|
+
tool('search', 'input-streaming'), // pending (gray)
|
|
26
|
+
tool('fetch_data', 'input-available'), // running (accent spinner)
|
|
27
|
+
tool('current_time', 'output-available', { output: 'Current time (Asia/Tokyo): 5:00 PM GMT+9' }), // success (green) + ⎿
|
|
28
|
+
tool('send_notification', 'output-available', {
|
|
29
|
+
output: '{"stdout":"📣 Notification sent","stderr":"","exitCode":0}',
|
|
30
|
+
}), // success — shell-envelope output
|
|
31
|
+
tool('weather', 'output-error', { errorText: 'Unknown city "Xyz" — try a valid city name.' }), // failed (red) + ⎿
|
|
32
|
+
tool('deploy', 'approval-requested', { approval: { id: 'c-deploy' } }), // approval-requested → pending
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
function Demo(): ReactElement {
|
|
36
|
+
return (
|
|
37
|
+
<TheoTUIProvider theme={THEME}>
|
|
38
|
+
<Box flexDirection="column" paddingX={1}>
|
|
39
|
+
<Text bold>Tool render variations — exactly how the timeline renders each state</Text>
|
|
40
|
+
<Text dimColor>pending · running · success · shell · failed · approval — Ctrl+C to exit</Text>
|
|
41
|
+
<Box marginTop={1}>
|
|
42
|
+
<AgentTimeline events={messagesToAgentEvents(THREAD)} />
|
|
43
|
+
</Box>
|
|
44
|
+
</Box>
|
|
45
|
+
</TheoTUIProvider>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
render(<Demo />)
|