create-theokit 1.0.16 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/cli.js +247 -94
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +8 -7
  4. package/templates/default/agents/chat.ts +7 -7
  5. package/templates/default/app/page.test.tsx +36 -0
  6. package/templates/default/app/page.tsx +36 -116
  7. package/templates/default/dot-claude/skills/theokit-agents/SKILL.md +3 -3
  8. package/templates/default/package.json.tmpl +5 -2
  9. package/templates/default/server/routes/health.ts +5 -5
  10. package/templates/default/theo.config.ts +2 -2
  11. package/templates/default/tsconfig.json +3 -1
  12. package/templates/surfaces/desktop/README-surface.md.tmpl +31 -0
  13. package/templates/surfaces/desktop/frontend/index.html.tmpl +39 -0
  14. package/templates/surfaces/desktop/frontend/src/main.ts +84 -0
  15. package/templates/surfaces/desktop/frontend/vite.config.ts +12 -0
  16. package/templates/surfaces/desktop/sidecar/sidecar-core.ts +37 -0
  17. package/templates/surfaces/desktop/sidecar/sidecar.ts +51 -0
  18. package/templates/surfaces/desktop/src-tauri/Cargo.toml.tmpl +16 -0
  19. package/templates/surfaces/desktop/src-tauri/build.rs +3 -0
  20. package/templates/surfaces/desktop/src-tauri/capabilities/default.json +14 -0
  21. package/templates/surfaces/desktop/src-tauri/src/lib.rs +82 -0
  22. package/templates/surfaces/desktop/src-tauri/src/main.rs +6 -0
  23. package/templates/surfaces/desktop/src-tauri/tauri.conf.json.tmpl +30 -0
  24. package/templates/surfaces/tui/README-surface.md.tmpl +26 -0
  25. package/templates/surfaces/tui/tui/App.tsx.tmpl +64 -0
  26. package/templates/surfaces/tui/tui/main.tsx.tmpl +14 -0
  27. package/LICENSE +0 -201
package/dist/cli.js CHANGED
@@ -3,15 +3,15 @@
3
3
  // src/cli.ts
4
4
  import { execSync } from "child_process";
5
5
  import {
6
- readFileSync as readFileSync4,
7
- writeFileSync as writeFileSync4,
8
- unlinkSync as unlinkSync4,
6
+ readFileSync as readFileSync5,
7
+ writeFileSync as writeFileSync5,
8
+ unlinkSync as unlinkSync5,
9
9
  mkdirSync,
10
10
  renameSync as renameSync2,
11
- existsSync as existsSync4,
12
- rmSync as rmSync2
11
+ existsSync as existsSync5,
12
+ rmSync as rmSync3
13
13
  } from "fs";
14
- import { resolve as resolve3, join as join4 } from "path";
14
+ import { resolve as resolve4, join as join5 } from "path";
15
15
 
16
16
  // src/install.ts
17
17
  import spawn from "cross-spawn";
@@ -73,17 +73,17 @@ var DEFAULTS = {
73
73
  agentsMd: true
74
74
  };
75
75
  async function ask(rl, question, defaultVal) {
76
- return new Promise((resolve4) => {
76
+ return new Promise((resolve5) => {
77
77
  const suffix = defaultVal ? "(Y/n)" : "(y/N)";
78
78
  rl.question(` ${question} ${suffix} `, (answer) => {
79
79
  const a = answer.trim().toLowerCase();
80
- if (a === "") resolve4(defaultVal);
81
- else resolve4(a === "y" || a === "yes");
80
+ if (a === "") resolve5(defaultVal);
81
+ else resolve5(a === "y" || a === "yes");
82
82
  });
83
83
  });
84
84
  }
85
85
  async function askChoice(rl, question, choices, defaultIdx = 0) {
86
- return new Promise((resolve4) => {
86
+ return new Promise((resolve5) => {
87
87
  console.log(` ${question}`);
88
88
  for (let i = 0; i < choices.length; i++) {
89
89
  const marker = i === defaultIdx ? "\u276F" : " ";
@@ -91,7 +91,7 @@ async function askChoice(rl, question, choices, defaultIdx = 0) {
91
91
  }
92
92
  rl.question(" Choice (number): ", (answer) => {
93
93
  const n = parseInt(answer.trim(), 10);
94
- resolve4(n >= 1 && n <= choices.length ? n - 1 : defaultIdx);
94
+ resolve5(n >= 1 && n <= choices.length ? n - 1 : defaultIdx);
95
95
  });
96
96
  });
97
97
  }
@@ -133,7 +133,7 @@ import {
133
133
  } from "fs";
134
134
  import { dirname, join, resolve } from "path";
135
135
  import { fileURLToPath } from "url";
136
- var __dirname = dirname(fileURLToPath(import.meta.url));
136
+ var __dirname2 = dirname(fileURLToPath(import.meta.url));
137
137
  var VALID_BACKENDS = ["node"];
138
138
  function parseBackendFlags(args) {
139
139
  const out = [];
@@ -167,7 +167,7 @@ var BACKEND_CONFIG = {
167
167
  }
168
168
  };
169
169
  function getServiceTemplateDir(kind) {
170
- return resolve(__dirname, "../templates/services", BACKEND_CONFIG[kind].templateDir);
170
+ return resolve(__dirname2, "../templates/services", BACKEND_CONFIG[kind].templateDir);
171
171
  }
172
172
  function substituteTmpls(dir, projectName) {
173
173
  for (const entry of readdirSync(dir)) {
@@ -265,24 +265,143 @@ function scaffoldServices(options) {
265
265
  }
266
266
  }
267
267
 
268
- // src/index.ts
268
+ // src/scaffold-surface.ts
269
269
  import {
270
- existsSync as existsSync3,
271
270
  cpSync as cpSync2,
272
- readFileSync as readFileSync3,
273
- writeFileSync as writeFileSync3,
274
- renameSync,
275
- unlinkSync as unlinkSync3,
271
+ existsSync as existsSync2,
276
272
  readdirSync as readdirSync2,
273
+ readFileSync as readFileSync2,
277
274
  rmSync,
278
- statSync as statSync2
275
+ statSync as statSync2,
276
+ unlinkSync as unlinkSync2,
277
+ writeFileSync as writeFileSync2
278
+ } from "fs";
279
+ import { join as join2, resolve as resolve2 } from "path";
280
+ var VALID_SURFACES = ["web", "tui", "desktop"];
281
+ var WEB_ONLY_DEPS = ["@theokit/ui", "@usetheo/ui", "lucide-react", "react-router"];
282
+ var WEB_ONLY_DEV_DEPS = ["tailwindcss", "@tailwindcss/vite", "tailwindcss-animate"];
283
+ var WEB_ONLY_FILES = ["app", "index.html", "tailwind.config.ts", "postcss.config.js"];
284
+ var SURFACE_CONFIG = {
285
+ tui: {
286
+ fragment: "tui",
287
+ deps: { ink: "^5.1.0" },
288
+ devDeps: { tsx: "^4.19.0" },
289
+ scripts: { dev: "tsx tui/main.tsx", start: "tsx tui/main.tsx" },
290
+ tsconfigInclude: ["tui/**/*.ts", "tui/**/*.tsx", "server/**/*.ts", "agents/**/*.ts"]
291
+ },
292
+ desktop: {
293
+ fragment: "desktop",
294
+ // The webview consumes the agent via `createAgentClient` from the React-FREE `theokit/client/core`
295
+ // (M44). It is bundled by Vite; the sidecar runs via tsx.
296
+ deps: {},
297
+ devDeps: { tsx: "^4.19.0", "@tauri-apps/cli": "^2.0.0", vite: "^6.0.0" },
298
+ scripts: {
299
+ dev: "tauri dev",
300
+ tauri: "tauri",
301
+ "build:frontend": "vite build frontend",
302
+ "build:sidecar": 'tsx --version >/dev/null && echo "sidecar runs via tsx (see src-tauri/tauri.conf.json)"'
303
+ },
304
+ tsconfigInclude: [
305
+ "sidecar/**/*.ts",
306
+ "frontend/src/**/*.ts",
307
+ "server/**/*.ts",
308
+ "agents/**/*.ts"
309
+ ]
310
+ }
311
+ };
312
+ function parseSurfaceFlags(args) {
313
+ let surface = "web";
314
+ for (let i = 0; i < args.length; i++) {
315
+ const a = args[i] ?? "";
316
+ let value;
317
+ if (a === "--surface") {
318
+ value = args[i + 1];
319
+ i++;
320
+ } else if (a.startsWith("--surface=")) {
321
+ value = a.slice("--surface=".length);
322
+ }
323
+ if (value === void 0) continue;
324
+ if (!VALID_SURFACES.includes(value)) {
325
+ throw new Error(
326
+ `unknown --surface value: '${value}'. Valid options: ${VALID_SURFACES.join(", ")}.`
327
+ );
328
+ }
329
+ surface = value;
330
+ }
331
+ return surface;
332
+ }
333
+ function getSurfaceFragmentDir(fragment) {
334
+ return resolve2(__dirname, "../templates/surfaces", fragment);
335
+ }
336
+ function substituteTmpls2(dir, projectName) {
337
+ for (const entry of readdirSync2(dir)) {
338
+ const full = join2(dir, entry);
339
+ if (statSync2(full).isDirectory()) {
340
+ substituteTmpls2(full, projectName);
341
+ continue;
342
+ }
343
+ if (entry.endsWith(".tmpl")) {
344
+ const content = readFileSync2(full, "utf-8").replace(/\{\{name\}\}/g, projectName);
345
+ writeFileSync2(full.replace(/\.tmpl$/, ""), content);
346
+ unlinkSync2(full);
347
+ }
348
+ }
349
+ }
350
+ function applySurface(options) {
351
+ if (options._testForceError !== void 0) {
352
+ throw new Error(`Forced surface failure: ${options._testForceError}`);
353
+ }
354
+ if (options.surface === "web") return;
355
+ const cfg = SURFACE_CONFIG[options.surface];
356
+ const src = getSurfaceFragmentDir(cfg.fragment);
357
+ if (!existsSync2(src)) {
358
+ throw new Error(`surface fragment not found: ${src}`);
359
+ }
360
+ cpSync2(src, options.targetDir, { recursive: true });
361
+ substituteTmpls2(options.targetDir, options.projectName);
362
+ for (const rel of WEB_ONLY_FILES) {
363
+ const p = join2(options.targetDir, rel);
364
+ if (existsSync2(p)) rmSync(p, { recursive: true, force: true });
365
+ }
366
+ const pkgPath = join2(options.targetDir, "package.json");
367
+ if (existsSync2(pkgPath)) {
368
+ const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
369
+ pkg.dependencies = { ...dropKeys(pkg.dependencies, WEB_ONLY_DEPS), ...cfg.deps };
370
+ pkg.devDependencies = { ...dropKeys(pkg.devDependencies, WEB_ONLY_DEV_DEPS), ...cfg.devDeps };
371
+ pkg.scripts = { ...pkg.scripts ?? {}, ...cfg.scripts };
372
+ writeFileSync2(pkgPath, `${JSON.stringify(pkg, null, 2)}
373
+ `);
374
+ }
375
+ const tsconfigPath = join2(options.targetDir, "tsconfig.json");
376
+ if (existsSync2(tsconfigPath)) {
377
+ const tsconfig = JSON.parse(readFileSync2(tsconfigPath, "utf-8"));
378
+ tsconfig.include = cfg.tsconfigInclude;
379
+ writeFileSync2(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
380
+ `);
381
+ }
382
+ }
383
+ function dropKeys(record, keys) {
384
+ return Object.fromEntries(Object.entries(record ?? {}).filter(([k]) => !keys.includes(k)));
385
+ }
386
+
387
+ // src/index.ts
388
+ import {
389
+ existsSync as existsSync4,
390
+ cpSync as cpSync3,
391
+ readFileSync as readFileSync4,
392
+ writeFileSync as writeFileSync4,
393
+ renameSync,
394
+ unlinkSync as unlinkSync4,
395
+ readdirSync as readdirSync3,
396
+ rmSync as rmSync2,
397
+ statSync as statSync3
279
398
  } from "fs";
280
- import { resolve as resolve2, join as join3, dirname as dirname2 } from "path";
399
+ import { resolve as resolve3, join as join4, dirname as dirname2 } from "path";
281
400
  import { fileURLToPath as fileURLToPath2 } from "url";
282
401
 
283
402
  // src/bare-transform.ts
284
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2 } from "fs";
285
- import { join as join2 } from "path";
403
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, unlinkSync as unlinkSync3 } from "fs";
404
+ import { join as join3 } from "path";
286
405
  var HELLO_PAGE = `export default function Page() {
287
406
  return <h1>Hello Theo</h1>
288
407
  }
@@ -291,9 +410,9 @@ function applyBareTransform(targetDir, options = {}) {
291
410
  if (options._testForceError) {
292
411
  throw new Error(`Forced transform failure: ${options._testForceError}`);
293
412
  }
294
- const pkgPath = join2(targetDir, "package.json");
295
- if (existsSync2(pkgPath)) {
296
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
413
+ const pkgPath = join3(targetDir, "package.json");
414
+ if (existsSync3(pkgPath)) {
415
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
297
416
  if (pkg.dependencies) {
298
417
  delete pkg.dependencies["@theokit/ui"];
299
418
  delete pkg.dependencies["@theokit/sdk"];
@@ -306,31 +425,31 @@ function applyBareTransform(targetDir, options = {}) {
306
425
  delete pkg.devDependencies.postcss;
307
426
  delete pkg.devDependencies.autoprefixer;
308
427
  }
309
- writeFileSync2(pkgPath, `${JSON.stringify(pkg, null, 2)}
428
+ writeFileSync3(pkgPath, `${JSON.stringify(pkg, null, 2)}
310
429
  `);
311
430
  }
312
- const pagePath = join2(targetDir, "app/page.tsx");
313
- if (existsSync2(pagePath)) {
314
- writeFileSync2(pagePath, HELLO_PAGE);
431
+ const pagePath = join3(targetDir, "app/page.tsx");
432
+ if (existsSync3(pagePath)) {
433
+ writeFileSync3(pagePath, HELLO_PAGE);
315
434
  }
316
- const chatPath = join2(targetDir, "agents/chat.ts");
317
- if (existsSync2(chatPath)) {
318
- unlinkSync2(chatPath);
435
+ const chatPath = join3(targetDir, "agents/chat.ts");
436
+ if (existsSync3(chatPath)) {
437
+ unlinkSync3(chatPath);
319
438
  }
320
- const tailwindCfg = join2(targetDir, "tailwind.config.ts");
321
- if (existsSync2(tailwindCfg)) {
322
- unlinkSync2(tailwindCfg);
439
+ const tailwindCfg = join3(targetDir, "tailwind.config.ts");
440
+ if (existsSync3(tailwindCfg)) {
441
+ unlinkSync3(tailwindCfg);
323
442
  }
324
- const postcssCfg = join2(targetDir, "postcss.config.js");
325
- if (existsSync2(postcssCfg)) {
326
- unlinkSync2(postcssCfg);
443
+ const postcssCfg = join3(targetDir, "postcss.config.js");
444
+ if (existsSync3(postcssCfg)) {
445
+ unlinkSync3(postcssCfg);
327
446
  }
328
447
  }
329
448
 
330
449
  // src/index.ts
331
- var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
450
+ var __dirname3 = dirname2(fileURLToPath2(import.meta.url));
332
451
  function getTemplateDir(templateName = "default") {
333
- return resolve2(__dirname2, "../templates", templateName);
452
+ return resolve3(__dirname3, "../templates", templateName);
334
453
  }
335
454
  function isValidProjectName(name) {
336
455
  return /^[a-z0-9][a-z0-9._-]*$/.test(name);
@@ -342,42 +461,42 @@ function scaffold(targetDir, projectName, templateName = "default", options = {}
342
461
  );
343
462
  }
344
463
  const templateDir = getTemplateDir(templateName);
345
- if (!existsSync3(templateDir)) {
464
+ if (!existsSync4(templateDir)) {
346
465
  throw new Error(`Template "${templateName}" not found. Available templates: default`);
347
466
  }
348
- const resolvedName = projectName === "." ? resolve2(targetDir).split("/").pop() ?? "my-app" : projectName;
467
+ const resolvedName = projectName === "." ? resolve3(targetDir).split("/").pop() ?? "my-app" : projectName;
349
468
  if (!isValidProjectName(resolvedName)) {
350
469
  throw new Error(
351
470
  `Invalid project name "${resolvedName}". Use lowercase letters, numbers, hyphens, and dots. Must start with a letter or number.`
352
471
  );
353
472
  }
354
- if (existsSync3(targetDir)) {
355
- const contents = readdirSync2(targetDir);
473
+ if (existsSync4(targetDir)) {
474
+ const contents = readdirSync3(targetDir);
356
475
  if (contents.length > 0) {
357
476
  throw new Error(`Directory "${targetDir}" is not empty. Please use an empty directory.`);
358
477
  }
359
478
  }
360
- cpSync2(templateDir, targetDir, { recursive: true });
361
- const gitignoreSrc = join3(targetDir, "_gitignore");
362
- const gitignoreDest = join3(targetDir, ".gitignore");
363
- if (existsSync3(gitignoreSrc)) {
479
+ cpSync3(templateDir, targetDir, { recursive: true });
480
+ const gitignoreSrc = join4(targetDir, "_gitignore");
481
+ const gitignoreDest = join4(targetDir, ".gitignore");
482
+ if (existsSync4(gitignoreSrc)) {
364
483
  renameSync(gitignoreSrc, gitignoreDest);
365
484
  }
366
- const dotClaudeSrc = join3(targetDir, "dot-claude");
367
- const dotClaudeDest = join3(targetDir, ".claude");
368
- if (existsSync3(dotClaudeSrc)) {
485
+ const dotClaudeSrc = join4(targetDir, "dot-claude");
486
+ const dotClaudeDest = join4(targetDir, ".claude");
487
+ if (existsSync4(dotClaudeSrc)) {
369
488
  renameSync(dotClaudeSrc, dotClaudeDest);
370
489
  }
371
- for (const entry of readdirSync2(targetDir)) {
490
+ for (const entry of readdirSync3(targetDir)) {
372
491
  if (!entry.endsWith(".tmpl")) continue;
373
- const src = join3(targetDir, entry);
374
- const stat = statSync2(src);
492
+ const src = join4(targetDir, entry);
493
+ const stat = statSync3(src);
375
494
  if (!stat.isFile()) continue;
376
- const dst = join3(targetDir, entry.slice(0, -".tmpl".length));
377
- const content = readFileSync3(src, "utf-8");
495
+ const dst = join4(targetDir, entry.slice(0, -".tmpl".length));
496
+ const content = readFileSync4(src, "utf-8");
378
497
  const replaced = content.replace(/\{\{name\}\}/g, resolvedName);
379
- writeFileSync3(dst, replaced);
380
- unlinkSync3(src);
498
+ writeFileSync4(dst, replaced);
499
+ unlinkSync4(src);
381
500
  }
382
501
  if (options.bare) {
383
502
  try {
@@ -385,7 +504,7 @@ function scaffold(targetDir, projectName, templateName = "default", options = {}
385
504
  _testForceError: options._testForceTransformError
386
505
  });
387
506
  } catch (err) {
388
- rmSync(targetDir, { recursive: true, force: true });
507
+ rmSync2(targetDir, { recursive: true, force: true });
389
508
  const original = err instanceof Error ? err.message : String(err);
390
509
  throw new Error(
391
510
  `Scaffold rolled back: bare transform failed. Check filesystem perms.
@@ -415,6 +534,7 @@ function showHelp() {
415
534
  -v, --version Show version number
416
535
  --yes Use recommended defaults (skip prompts)
417
536
  --template=<name> Template to use (default: "default")
537
+ --surface=<web|tui|desktop> App surface (default: "web") \u2014 tui (Ink) / desktop (Tauri)
418
538
  --bare Minimal app (no @theokit/* deps)
419
539
  --skip-install Scaffold files only, skip package install
420
540
  --disable-git Skip git init
@@ -431,6 +551,8 @@ function showHelp() {
431
551
  npx create-theokit my-app --yes
432
552
  npx create-theokit my-app
433
553
  npx create-theokit my-app --bare --skip-install
554
+ npx create-theokit my-app --surface=tui
555
+ npx create-theokit my-app --surface=desktop
434
556
  npx create-theokit my-app --use-bun --biome
435
557
  npx create-theokit my-app --example=https://github.com/user/repo
436
558
  npx create-theokit my-app --import-alias="~/*"
@@ -480,7 +602,23 @@ async function main() {
480
602
  console.error(err instanceof Error ? err.message : String(err));
481
603
  process.exit(1);
482
604
  }
483
- const targetDir = resolve3(process.cwd(), projectName);
605
+ let surface = "web";
606
+ try {
607
+ surface = parseSurfaceFlags(args);
608
+ } catch (err) {
609
+ console.error("");
610
+ console.error(err instanceof Error ? err.message : String(err));
611
+ process.exit(1);
612
+ }
613
+ if (bare && surface !== "web") {
614
+ console.error(
615
+ `
616
+ --bare cannot be combined with --surface=${surface} (the surface needs the agent deps).
617
+ `
618
+ );
619
+ process.exit(1);
620
+ }
621
+ const targetDir = resolve4(process.cwd(), projectName);
484
622
  if (exampleFlag) {
485
623
  try {
486
624
  console.log(`
@@ -517,13 +655,15 @@ Cloning example "${exampleFlag}" into ${projectName}...
517
655
  }
518
656
  try {
519
657
  const suffix = bare ? " [--bare]" : "";
658
+ const surfaceSuffix = surface !== "web" ? ` [surface: ${surface}]` : "";
520
659
  const backendsSuffix = backends.length > 0 ? ` [+services: ${backends.join(", ")}]` : "";
521
660
  console.log(
522
661
  `
523
- Creating TheoKit project "${projectName}" (template: ${templateName})${suffix}${backendsSuffix}...
662
+ Creating TheoKit project "${projectName}" (template: ${templateName})${suffix}${surfaceSuffix}${backendsSuffix}...
524
663
  `
525
664
  );
526
665
  scaffold(targetDir, projectName, templateName, { bare });
666
+ applySurfaceStep(targetDir, projectName, surface, options);
527
667
  applyOptions(targetDir, options, { importAlias, useBiome });
528
668
  if (backends.length > 0) {
529
669
  scaffoldServices({ targetDir, projectName, backends });
@@ -555,12 +695,25 @@ Creating TheoKit project "${projectName}" (template: ${templateName})${suffix}${
555
695
  process.exit(1);
556
696
  }
557
697
  }
698
+ function applySurfaceStep(targetDir, projectName, surface, options) {
699
+ if (surface === "web") return;
700
+ try {
701
+ applySurface({ targetDir, projectName, surface });
702
+ } catch (err) {
703
+ rmSync3(targetDir, { recursive: true, force: true });
704
+ const original = err instanceof Error ? err.message : String(err);
705
+ throw new Error(`Scaffold rolled back: surface transform failed.
706
+ Original error: ${original}`);
707
+ }
708
+ options.tailwind = false;
709
+ options.srcDir = false;
710
+ }
558
711
  function applyOptions(targetDir, options, opts) {
559
- const pkgPath = resolve3(targetDir, "package.json");
712
+ const pkgPath = resolve4(targetDir, "package.json");
560
713
  if (opts.useBiome) {
561
- const eslintPath = resolve3(targetDir, "eslint.config.mjs");
562
- if (existsSync4(eslintPath)) unlinkSync4(eslintPath);
563
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
714
+ const eslintPath = resolve4(targetDir, "eslint.config.mjs");
715
+ if (existsSync5(eslintPath)) unlinkSync5(eslintPath);
716
+ const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
564
717
  delete pkg.devDependencies.eslint;
565
718
  delete pkg.devDependencies["eslint-config-prettier"];
566
719
  delete pkg.devDependencies["typescript-eslint"];
@@ -569,9 +722,9 @@ function applyOptions(targetDir, options, opts) {
569
722
  pkg.scripts["lint:fix"] = "biome check . --fix";
570
723
  pkg.scripts.format = "biome format . --write";
571
724
  pkg.scripts["format:check"] = "biome format .";
572
- writeFileSync4(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
573
- writeFileSync4(
574
- resolve3(targetDir, "biome.json"),
725
+ writeFileSync5(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
726
+ writeFileSync5(
727
+ resolve4(targetDir, "biome.json"),
575
728
  JSON.stringify(
576
729
  {
577
730
  $schema: "https://biomejs.dev/schemas/1.9.0/schema.json",
@@ -584,45 +737,45 @@ function applyOptions(targetDir, options, opts) {
584
737
  ) + "\n"
585
738
  );
586
739
  } else if (!options.eslint) {
587
- const eslintPath = resolve3(targetDir, "eslint.config.mjs");
588
- if (existsSync4(eslintPath)) unlinkSync4(eslintPath);
589
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
740
+ const eslintPath = resolve4(targetDir, "eslint.config.mjs");
741
+ if (existsSync5(eslintPath)) unlinkSync5(eslintPath);
742
+ const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
590
743
  delete pkg.scripts.lint;
591
744
  delete pkg.scripts["lint:fix"];
592
745
  delete pkg.devDependencies.eslint;
593
746
  delete pkg.devDependencies["eslint-config-prettier"];
594
747
  delete pkg.devDependencies["typescript-eslint"];
595
- writeFileSync4(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
748
+ writeFileSync5(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
596
749
  }
597
750
  if (options.tailwind) {
598
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
751
+ const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
599
752
  pkg.devDependencies = pkg.devDependencies ?? {};
600
753
  pkg.devDependencies.tailwindcss = "^4.0.0";
601
754
  pkg.devDependencies["@tailwindcss/vite"] = "^4.0.0";
602
- writeFileSync4(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
603
- const cssDir = existsSync4(resolve3(targetDir, "src/app")) ? "src/app" : "app";
604
- const cssPath = resolve3(targetDir, `${cssDir}/globals.css`);
605
- const existing = existsSync4(cssPath) ? readFileSync4(cssPath, "utf-8") : "";
606
- writeFileSync4(cssPath, '@import "tailwindcss";\n\n' + existing);
755
+ writeFileSync5(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
756
+ const cssDir = existsSync5(resolve4(targetDir, "src/app")) ? "src/app" : "app";
757
+ const cssPath = resolve4(targetDir, `${cssDir}/globals.css`);
758
+ const existing = existsSync5(cssPath) ? readFileSync5(cssPath, "utf-8") : "";
759
+ writeFileSync5(cssPath, '@import "tailwindcss";\n\n' + existing);
607
760
  }
608
761
  if (options.srcDir) {
609
- const srcDir = resolve3(targetDir, "src");
762
+ const srcDir = resolve4(targetDir, "src");
610
763
  mkdirSync(srcDir, { recursive: true });
611
764
  for (const dir of ["app", "server"]) {
612
- const from = resolve3(targetDir, dir);
613
- const to = resolve3(srcDir, dir);
614
- if (existsSync4(from)) renameSync2(from, to);
765
+ const from = resolve4(targetDir, dir);
766
+ const to = resolve4(srcDir, dir);
767
+ if (existsSync5(from)) renameSync2(from, to);
615
768
  }
616
- const configFrom = resolve3(targetDir, "theo.config.ts");
617
- if (existsSync4(configFrom)) renameSync2(configFrom, resolve3(srcDir, "theo.config.ts"));
618
- const tscPath2 = resolve3(targetDir, "tsconfig.json");
619
- const tsc2 = JSON.parse(readFileSync4(tscPath2, "utf-8"));
769
+ const configFrom = resolve4(targetDir, "theo.config.ts");
770
+ if (existsSync5(configFrom)) renameSync2(configFrom, resolve4(srcDir, "theo.config.ts"));
771
+ const tscPath2 = resolve4(targetDir, "tsconfig.json");
772
+ const tsc2 = JSON.parse(readFileSync5(tscPath2, "utf-8"));
620
773
  tsc2.compilerOptions.baseUrl = "src";
621
774
  tsc2.include = ["src/**/*.ts", "src/**/*.tsx"];
622
- writeFileSync4(tscPath2, JSON.stringify(tsc2, null, 2) + "\n");
775
+ writeFileSync5(tscPath2, JSON.stringify(tsc2, null, 2) + "\n");
623
776
  }
624
- const tscPath = resolve3(targetDir, "tsconfig.json");
625
- const tsc = JSON.parse(readFileSync4(tscPath, "utf-8"));
777
+ const tscPath = resolve4(targetDir, "tsconfig.json");
778
+ const tsc = JSON.parse(readFileSync5(tscPath, "utf-8"));
626
779
  if (!options.aliases) {
627
780
  delete tsc.compilerOptions.baseUrl;
628
781
  delete tsc.compilerOptions.paths;
@@ -634,10 +787,10 @@ function applyOptions(targetDir, options, opts) {
634
787
  [`${prefix}/app/*`]: ["./app/*"]
635
788
  };
636
789
  }
637
- writeFileSync4(tscPath, JSON.stringify(tsc, null, 2) + "\n");
790
+ writeFileSync5(tscPath, JSON.stringify(tsc, null, 2) + "\n");
638
791
  if (!options.agentsMd) {
639
- const agentsPath = resolve3(targetDir, "AGENTS.md");
640
- if (existsSync4(agentsPath)) unlinkSync4(agentsPath);
792
+ const agentsPath = resolve4(targetDir, "AGENTS.md");
793
+ if (existsSync5(agentsPath)) unlinkSync5(agentsPath);
641
794
  }
642
795
  }
643
796
  function initGit(targetDir) {
@@ -656,7 +809,7 @@ function cloneExample(example, targetDir) {
656
809
  const repo = isUrl ? example : `https://github.com/usetheodev/theokit-examples/tree/main/${example}`;
657
810
  if (isUrl) {
658
811
  execSync(`git clone --depth 1 ${repo} ${targetDir}`, { stdio: "inherit" });
659
- rmSync2(join4(targetDir, ".git"), { recursive: true, force: true });
812
+ rmSync3(join5(targetDir, ".git"), { recursive: true, force: true });
660
813
  } else {
661
814
  try {
662
815
  execSync(`npx --yes degit usetheodev/theokit-examples/${example} ${targetDir}`, {