@lytjs/cli 5.0.6 → 6.5.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 (43) hide show
  1. package/dist/create.cjs +607 -0
  2. package/dist/create.cjs.map +1 -0
  3. package/dist/create.d.mts +2 -0
  4. package/dist/create.d.ts +2 -0
  5. package/dist/create.mjs +605 -0
  6. package/dist/create.mjs.map +1 -0
  7. package/dist/index.cjs +2212 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.d.mts +208 -0
  10. package/dist/index.d.ts +208 -0
  11. package/dist/index.mjs +1999 -886
  12. package/dist/index.mjs.map +1 -0
  13. package/dist/lyt.cjs +2212 -0
  14. package/dist/lyt.cjs.map +1 -0
  15. package/dist/lyt.d.mts +1 -0
  16. package/dist/lyt.d.ts +1 -0
  17. package/dist/lyt.mjs +2171 -0
  18. package/dist/lyt.mjs.map +1 -0
  19. package/lyt-cli.js +3 -0
  20. package/package.json +34 -31
  21. package/README.md +0 -227
  22. package/dist/bin/cli.cjs +0 -1058
  23. package/dist/bin/cli.js +0 -2
  24. package/dist/bin/cli.mjs +0 -1058
  25. package/dist/index.js +0 -1058
  26. package/dist/types/bin/cli.d.ts +0 -8
  27. package/dist/types/bin/cli.d.ts.map +0 -1
  28. package/dist/types/build.d.ts +0 -30
  29. package/dist/types/build.d.ts.map +0 -1
  30. package/dist/types/create.d.ts +0 -19
  31. package/dist/types/create.d.ts.map +0 -1
  32. package/dist/types/dev.d.ts +0 -24
  33. package/dist/types/dev.d.ts.map +0 -1
  34. package/dist/types/generate.d.ts +0 -14
  35. package/dist/types/generate.d.ts.map +0 -1
  36. package/dist/types/hmr.d.ts +0 -55
  37. package/dist/types/hmr.d.ts.map +0 -1
  38. package/dist/types/index.d.ts +0 -20
  39. package/dist/types/index.d.ts.map +0 -1
  40. package/dist/types/scaffold.d.ts +0 -67
  41. package/dist/types/scaffold.d.ts.map +0 -1
  42. package/dist/types/utils.d.ts +0 -92
  43. package/dist/types/utils.d.ts.map +0 -1
@@ -0,0 +1,605 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readdirSync, mkdirSync, writeFileSync } from 'fs';
3
+ import { resolve, join, dirname } from 'path';
4
+ import { execSync } from 'child_process';
5
+
6
+ // src/utils/logger.ts
7
+ var colors = {
8
+ reset: "\x1B[0m",
9
+ bright: "\x1B[1m",
10
+ dim: "\x1B[2m",
11
+ red: "\x1B[31m",
12
+ green: "\x1B[32m",
13
+ yellow: "\x1B[33m",
14
+ blue: "\x1B[34m",
15
+ cyan: "\x1B[36m"
16
+ };
17
+ function colorize(text, color) {
18
+ if (!isColorSupported()) return text;
19
+ return `${colors[color]}${text}${colors.reset}`;
20
+ }
21
+ var logger = {
22
+ info(message) {
23
+ console.log(colorize("\u2139 ", "blue") + message);
24
+ },
25
+ success(message) {
26
+ console.log(colorize("\u2714 ", "green") + message);
27
+ },
28
+ warning(message) {
29
+ console.log(colorize("\u26A0 ", "yellow") + message);
30
+ },
31
+ error(message) {
32
+ console.error(colorize("\u2716 ", "red") + message);
33
+ },
34
+ dim(message) {
35
+ console.log(colorize(message, "dim"));
36
+ },
37
+ bold(message) {
38
+ return colorize(message, "bright");
39
+ }
40
+ };
41
+ function isColorSupported() {
42
+ return process.stdout.isTTY && process.env.NO_COLOR !== "1";
43
+ }
44
+ function ensureDir(dir) {
45
+ if (!existsSync(dir)) {
46
+ mkdirSync(dir, { recursive: true });
47
+ }
48
+ }
49
+ function writeFile(filePath, content) {
50
+ ensureDir(dirname(filePath));
51
+ writeFileSync(filePath, content, "utf-8");
52
+ }
53
+ function exists(path) {
54
+ return existsSync(path);
55
+ }
56
+ function isEmptyDir(dir) {
57
+ if (!existsSync(dir)) return true;
58
+ const files = readdirSync(dir);
59
+ return files.length === 0;
60
+ }
61
+ function detectPackageManager(cwd = process.cwd()) {
62
+ if (existsSync(join(cwd, "pnpm-lock.yaml"))) return "pnpm";
63
+ if (existsSync(join(cwd, "yarn.lock"))) return "yarn";
64
+ if (existsSync(join(cwd, "package-lock.json"))) return "npm";
65
+ try {
66
+ execSync("pnpm --version", { stdio: "ignore" });
67
+ return "pnpm";
68
+ } catch {
69
+ return "npm";
70
+ }
71
+ }
72
+ function getInstallCommand(pm) {
73
+ switch (pm) {
74
+ case "pnpm":
75
+ return "pnpm install";
76
+ case "yarn":
77
+ return "yarn";
78
+ case "npm":
79
+ return "npm install";
80
+ }
81
+ }
82
+ async function create(projectName, options = {}) {
83
+ {
84
+ logger.error("Please provide a project name.");
85
+ logger.info("Usage: lyt create <project-name>");
86
+ process.exit(1);
87
+ }
88
+ const targetDir = resolve(process.cwd(), projectName);
89
+ if (exists(targetDir) && !isEmptyDir(targetDir) && !options.force) {
90
+ logger.error(`Directory "${projectName}" already exists and is not empty.`);
91
+ logger.info("Use --force to overwrite.");
92
+ process.exit(1);
93
+ }
94
+ logger.info(`Creating a new LytJS project in ${targetDir}...`);
95
+ ensureDir(targetDir);
96
+ generateProjectFiles(targetDir, projectName, options.template || "default");
97
+ logger.info("Installing dependencies...");
98
+ const pm = detectPackageManager();
99
+ try {
100
+ execSync(getInstallCommand(pm), { cwd: targetDir, stdio: "inherit" });
101
+ logger.success("Dependencies installed successfully!");
102
+ } catch (_error) {
103
+ logger.warning("Failed to install dependencies automatically.");
104
+ logger.info(`Please run "${getInstallCommand(pm)}" manually.`);
105
+ }
106
+ logger.success(`Project "${projectName}" created successfully!`);
107
+ logger.info("");
108
+ logger.bold("Next steps:");
109
+ logger.info(` cd ${projectName}`);
110
+ logger.info(` ${pm === "npm" ? "npm run" : pm} dev`);
111
+ }
112
+ function generateProjectFiles(targetDir, projectName, template) {
113
+ const isMinimal = template === "minimal";
114
+ const isSsr = template === "ssr";
115
+ const isRouter = template === "router" || template === "full";
116
+ const isStore = template === "store" || template === "full";
117
+ const isFull = template === "full";
118
+ const packageJson = {
119
+ name: projectName,
120
+ version: "0.0.0",
121
+ type: "module",
122
+ scripts: {
123
+ dev: "vite",
124
+ build: "vite build",
125
+ preview: "vite preview"
126
+ },
127
+ dependencies: {
128
+ "@lytjs/core": "^6.0.0"
129
+ },
130
+ devDependencies: {
131
+ "@lytjs/plugin-vite": "^6.0.0",
132
+ "vite": "^5.0.0"
133
+ }
134
+ };
135
+ if (!isMinimal) {
136
+ packageJson.scripts.test = "vitest";
137
+ packageJson.devDependencies.vitest = "^1.0.0";
138
+ }
139
+ if (isSsr) {
140
+ packageJson.dependencies["@lytjs/server"] = "^6.0.0";
141
+ packageJson.scripts["build:client"] = "vite build --ssrManifest";
142
+ packageJson.scripts["build:server"] = "vite build --ssr src/entry-server.ts";
143
+ packageJson.scripts["build"] = "npm run build:client && npm run build:server";
144
+ packageJson.scripts["preview"] = "node server";
145
+ }
146
+ if (isRouter) {
147
+ packageJson.dependencies["@lytjs/router"] = "^1.0.0";
148
+ }
149
+ if (isStore) {
150
+ packageJson.dependencies["@lytjs/store"] = "^1.0.0";
151
+ }
152
+ if (isFull) {
153
+ packageJson.dependencies["@lytjs/ui"] = "^0.4.0";
154
+ }
155
+ writeFile(join(targetDir, "package.json"), JSON.stringify(packageJson, null, 2));
156
+ let viteConfig;
157
+ if (isSsr) {
158
+ viteConfig = `import { defineConfig } from 'vite';
159
+ import lytjs from '@lytjs/plugin-vite';
160
+
161
+ export default defineConfig({
162
+ plugins: [lytjs()],
163
+ build: {
164
+ ssrManifest: true,
165
+ },
166
+ });
167
+ `;
168
+ } else {
169
+ viteConfig = `import { defineConfig } from 'vite';
170
+ import lytjs from '@lytjs/plugin-vite';
171
+
172
+ export default defineConfig({
173
+ plugins: [lytjs()],
174
+ });
175
+ `;
176
+ }
177
+ writeFile(join(targetDir, "vite.config.ts"), viteConfig);
178
+ const indexHtml = `<!DOCTYPE html>
179
+ <html lang="en">
180
+ <head>
181
+ <meta charset="UTF-8" />
182
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
183
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
184
+ <title>${projectName}</title>
185
+ </head>
186
+ <body>
187
+ <div id="app"></div>
188
+ <script type="module" src="/src/main.ts"></script>
189
+ </body>
190
+ </html>
191
+ `;
192
+ writeFile(join(targetDir, "index.html"), indexHtml);
193
+ let mainTs;
194
+ if (isSsr) {
195
+ mainTs = `import { createApp } from '@lytjs/core';
196
+ import App from './App.lyt';
197
+ import { createSSRApp } from '@lytjs/server';
198
+ ${isRouter ? "import { createRouter, createWebHistory } from '@lytjs/router';" : ""}
199
+ ${isStore ? "import { createPinia } from '@lytjs/store';" : ""}
200
+
201
+ const app = createSSRApp(App);
202
+ ${isStore ? "app.use(createPinia());" : ""}
203
+ ${isRouter ? `
204
+ const router = createRouter({
205
+ history: createWebHistory(),
206
+ routes: [
207
+ { path: '/', component: () => import('./pages/Home.lyt') },
208
+ { path: '/about', component: () => import('./pages/About.lyt') },
209
+ ],
210
+ });
211
+ app.use(router);
212
+ ` : ""}
213
+ app.mount('#app');
214
+ `;
215
+ } else if (isRouter || isStore) {
216
+ mainTs = `import { createApp } from '@lytjs/core';
217
+ import App from './App.lyt';
218
+ ${isRouter ? "import { createRouter, createWebHistory } from '@lytjs/router';" : ""}
219
+ ${isStore ? "import { createPinia } from '@lytjs/store';" : ""}
220
+
221
+ const app = createApp(App);
222
+ ${isStore ? "app.use(createPinia());" : ""}
223
+ ${isRouter ? `
224
+ const router = createRouter({
225
+ history: createWebHistory(),
226
+ routes: [
227
+ { path: '/', component: () => import('./pages/Home.lyt') },
228
+ { path: '/about', component: () => import('./pages/About.lyt') },
229
+ ],
230
+ });
231
+ app.use(router);
232
+ ` : ""}
233
+ app.mount('#app');
234
+ `;
235
+ } else {
236
+ mainTs = `import { createApp } from '@lytjs/core';
237
+ import App from './App.lyt';
238
+
239
+ createApp(App).mount('#app');
240
+ `;
241
+ }
242
+ writeFile(join(targetDir, "src/main.ts"), mainTs);
243
+ let appLyt;
244
+ if (isMinimal) {
245
+ appLyt = `<template>
246
+ <div class="app">
247
+ <h1>{{ title }}</h1>
248
+ </div>
249
+ </template>
250
+
251
+ <script setup>
252
+ const title = 'Hello LytJS!';
253
+ </script>
254
+
255
+ <style scoped>
256
+ .app {
257
+ text-align: center;
258
+ }
259
+ </style>
260
+ `;
261
+ } else if (isRouter) {
262
+ appLyt = `<template>
263
+ <div class="app">
264
+ <nav class="nav">
265
+ <router-link to="/">Home</router-link>
266
+ <router-link to="/about">About</router-link>
267
+ </nav>
268
+ <router-view />
269
+ </div>
270
+ </template>
271
+
272
+ <script setup lang="ts">
273
+ import { RouterLink, RouterView } from '@lytjs/router';
274
+ </script>
275
+
276
+ <style scoped>
277
+ .app {
278
+ text-align: center;
279
+ padding: 2rem;
280
+ }
281
+
282
+ .nav {
283
+ margin-bottom: 2rem;
284
+ }
285
+
286
+ .nav a {
287
+ margin: 0 1rem;
288
+ color: #42b883;
289
+ text-decoration: none;
290
+ }
291
+
292
+ .nav a:hover {
293
+ text-decoration: underline;
294
+ }
295
+ </style>
296
+ `;
297
+ } else {
298
+ appLyt = `<template>
299
+ <div class="app">
300
+ <h1>{{ title }}</h1>
301
+ <p>Welcome to your LytJS app!</p>
302
+ </div>
303
+ </template>
304
+
305
+ <script setup>
306
+ const title = 'Hello LytJS!';
307
+ </script>
308
+
309
+ <style scoped>
310
+ .app {
311
+ text-align: center;
312
+ padding: 2rem;
313
+ }
314
+
315
+ h1 {
316
+ color: #42b883;
317
+ }
318
+ </style>
319
+ `;
320
+ }
321
+ writeFile(join(targetDir, "src/App.lyt"), appLyt);
322
+ if (isRouter) {
323
+ const homePage = `<template>
324
+ <div class="home">
325
+ <h1>Home</h1>
326
+ ${isStore ? `
327
+ <p>Count: {{ count }}</p>
328
+ <button @click="increment">Increment</button>
329
+ <button @click="decrement">Decrement</button>
330
+ ` : ""}
331
+ <p>Welcome to the Home page!</p>
332
+ </div>
333
+ </template>
334
+
335
+ <script setup lang="ts">
336
+ ${isStore ? `import { useCounterStore } from '../stores/counter';
337
+ const counterStore = useCounterStore();
338
+ const { count, increment, decrement } = counterStore;
339
+ ` : ""}
340
+ </script>
341
+
342
+ <style scoped>
343
+ .home {
344
+ padding: 1rem;
345
+ }
346
+ </style>
347
+ `;
348
+ ensureDir(join(targetDir, "src", "pages"));
349
+ writeFile(join(targetDir, "src", "pages", "Home.lyt"), homePage);
350
+ const aboutPage = `<template>
351
+ <div class="about">
352
+ <h1>About</h1>
353
+ <p>This is the About page!</p>
354
+ </div>
355
+ </template>
356
+
357
+ <script setup lang="ts">
358
+ </script>
359
+
360
+ <style scoped>
361
+ .about {
362
+ padding: 1rem;
363
+ }
364
+ </style>
365
+ `;
366
+ writeFile(join(targetDir, "src", "pages", "About.lyt"), aboutPage);
367
+ }
368
+ if (isStore) {
369
+ const counterStore = `import { defineStore } from '@lytjs/store';
370
+ import { signal, computed } from '@lytjs/reactivity';
371
+
372
+ export const useCounterStore = defineStore('counter', () => {
373
+ // State
374
+ const count = signal(0);
375
+
376
+ // Getters
377
+ const doubleCount = computed(() => count.value * 2);
378
+
379
+ // Actions
380
+ function increment() {
381
+ count.value++;
382
+ }
383
+
384
+ function decrement() {
385
+ count.value--;
386
+ }
387
+
388
+ function reset() {
389
+ count.value = 0;
390
+ }
391
+
392
+ return {
393
+ count,
394
+ doubleCount,
395
+ increment,
396
+ decrement,
397
+ reset,
398
+ };
399
+ });
400
+ `;
401
+ ensureDir(join(targetDir, "src", "stores"));
402
+ writeFile(join(targetDir, "src", "stores", "counter.ts"), counterStore);
403
+ }
404
+ if (isSsr) {
405
+ const entryServer = `import { createSSRApp, h } from '@lytjs/core';
406
+ import { renderToString } from '@lytjs/ssr';
407
+ import App from './App.lyt';
408
+
409
+ export async function render(url: string) {
410
+ const app = createSSRApp({
411
+ render() {
412
+ return h(App);
413
+ }
414
+ });
415
+
416
+ const html = await renderToString(app);
417
+ return html;
418
+ }
419
+ `;
420
+ writeFile(join(targetDir, "src/entry-server.ts"), entryServer);
421
+ const entryClient = `import { createApp } from '@lytjs/core';
422
+ import App from './App.lyt';
423
+
424
+ const app = createApp(App);
425
+ app.mount('#app');
426
+ `;
427
+ writeFile(join(targetDir, "src/entry-client.ts"), entryClient);
428
+ const serverTs = `/**
429
+ * LytJS SSR Server
430
+ *
431
+ * Complete SSR server with Vite dev server and production build support.
432
+ * Supports streaming SSR, route prefetching, and static file serving.
433
+ */
434
+
435
+ import fs from 'fs';
436
+ import path from 'path';
437
+ import { fileURLToPath } from 'url';
438
+ import http from 'http';
439
+
440
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
441
+ const isProduction = process.env.NODE_ENV === 'production';
442
+ const DIST_DIR = path.join(__dirname, 'dist');
443
+ const PORT = parseInt(process.env.PORT || '3000', 10);
444
+
445
+ interface RenderOptions {
446
+ url: string;
447
+ template: string;
448
+ manifest?: Record<string, string[]>;
449
+ }
450
+
451
+ async function renderPage({ url, template, manifest }: RenderOptions): Promise<string> {
452
+ let app: any;
453
+ let vite: any;
454
+
455
+ if (!isProduction) {
456
+ const { createServer: createViteServer } = await import('vite');
457
+ vite = await createViteServer({
458
+ server: { middlewareMode: true },
459
+ appType: 'custom',
460
+ });
461
+ app = (await vite.ssrLoadModule(path.join(__dirname, 'src/entry-server.ts'))).default;
462
+ } else {
463
+ app = (await import(path.join(DIST_DIR, 'server/entry-server.js'))).default;
464
+ }
465
+
466
+ const html = await app.render(url);
467
+ return template.replace('<!--app-html-->', html);
468
+ }
469
+
470
+ async function createServer() {
471
+ let vite: any;
472
+
473
+ // Load index.html template
474
+ let template: string;
475
+
476
+ if (!isProduction) {
477
+ const { createServer: createViteServer } = await import('vite');
478
+ vite = await createViteServer({
479
+ server: { middlewareMode: true },
480
+ appType: 'custom',
481
+ });
482
+ template = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf-8');
483
+ } else {
484
+ template = fs.readFileSync(path.join(DIST_DIR, 'client/index.html'), 'utf-8');
485
+ }
486
+
487
+ const server = http.createServer(async (req, res) => {
488
+ const url = req.url || '/';
489
+
490
+ try {
491
+ if (!isProduction && url.startsWith('/@')) {
492
+ // Vite dev server requests
493
+ return;
494
+ }
495
+
496
+ // Static assets
497
+ if (url.startsWith('/assets/') || url.endsWith('.js') || url.endsWith('.css')) {
498
+ const filePath = isProduction
499
+ ? path.join(DIST_DIR, 'client', url)
500
+ : path.join(__dirname, url);
501
+
502
+ if (fs.existsSync(filePath)) {
503
+ const ext = path.extname(filePath);
504
+ const contentType = ext === '.css' ? 'text/css' : 'application/javascript';
505
+ res.writeHead(200, { 'Content-Type': contentType });
506
+ res.end(fs.readFileSync(filePath));
507
+ return;
508
+ }
509
+ }
510
+
511
+ // SSR rendering
512
+ const html = await renderPage({
513
+ url,
514
+ template,
515
+ manifest: isProduction
516
+ ? JSON.parse(fs.readFileSync(path.join(DIST_DIR, 'client/ssr-manifest.json'), 'utf-8'))
517
+ : undefined
518
+ });
519
+
520
+ res.writeHead(200, { 'Content-Type': 'text/html' });
521
+ res.end(html);
522
+ } catch (err: any) {
523
+ if (!isProduction && vite) {
524
+ vite.ssrFixStacktrace(err);
525
+ }
526
+ console.error('SSR Error:', err);
527
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
528
+ res.end('Internal Server Error');
529
+ }
530
+ });
531
+
532
+ server.listen(PORT, () => {
533
+ console.log(\`LytJS SSR server running at http://localhost:\${PORT}\`);
534
+ console.log(\`Mode: \${isProduction ? 'Production' : 'Development'}\`);
535
+ });
536
+ }
537
+
538
+ createServer().catch(console.error);
539
+ `;
540
+ writeFile(join(targetDir, "server.ts"), serverTs);
541
+ }
542
+ const tsConfig = {
543
+ compilerOptions: {
544
+ target: "ES2020",
545
+ useDefineForClassFields: true,
546
+ module: "ESNext",
547
+ lib: ["ES2020", "DOM", "DOM.Iterable"],
548
+ skipLibCheck: true,
549
+ moduleResolution: "bundler",
550
+ allowImportingTsExtensions: true,
551
+ resolveJsonModule: true,
552
+ isolatedModules: true,
553
+ noEmit: true,
554
+ strict: true,
555
+ noUnusedLocals: true,
556
+ noUnusedParameters: true,
557
+ noFallthroughCasesInSwitch: true
558
+ },
559
+ include: ["src/**/*.ts", "src/**/*.lyt"],
560
+ references: [{ path: "./tsconfig.node.json" }]
561
+ };
562
+ writeFile(join(targetDir, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
563
+ const tsConfigNode = {
564
+ compilerOptions: {
565
+ composite: true,
566
+ skipLibCheck: true,
567
+ module: "ESNext",
568
+ moduleResolution: "bundler",
569
+ allowSyntheticDefaultImports: true
570
+ },
571
+ include: ["vite.config.ts"]
572
+ };
573
+ writeFile(join(targetDir, "tsconfig.node.json"), JSON.stringify(tsConfigNode, null, 2));
574
+ const gitignore = `# Logs
575
+ logs
576
+ *.log
577
+ npm-debug.log*
578
+ yarn-debug.log*
579
+ yarn-error.log*
580
+ pnpm-debug.log*
581
+ lerna-debug.log*
582
+
583
+ node_modules
584
+ dist
585
+ dist-ssr
586
+ *.local
587
+
588
+ # Editor directories and files
589
+ .vscode/*
590
+ !.vscode/extensions.json
591
+ .idea
592
+ .DS_Store
593
+ *.suo
594
+ *.ntvs*
595
+ *.njsproj
596
+ *.sln
597
+ *.sw?
598
+ `;
599
+ writeFile(join(targetDir, ".gitignore"), gitignore);
600
+ }
601
+
602
+ // src/create.ts
603
+ create().catch(console.error);
604
+ //# sourceMappingURL=create.mjs.map
605
+ //# sourceMappingURL=create.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/logger.ts","../src/utils/fs.ts","../src/utils/package.ts","../src/commands/create.ts","../src/create.ts"],"names":["existsSync","join","execSync"],"mappings":"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","file":"create.mjs","sourcesContent":["/**\r\n * @lytjs/cli - Logger utilities\r\n */\r\n\r\nconst colors = {\r\n reset: '\\x1b[0m',\r\n bright: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n red: '\\x1b[31m',\r\n green: '\\x1b[32m',\r\n yellow: '\\x1b[33m',\r\n blue: '\\x1b[34m',\r\n cyan: '\\x1b[36m',\r\n};\r\n\r\nfunction colorize(text: string, color: keyof typeof colors): string {\r\n if (!isColorSupported()) return text;\r\n return `${colors[color]}${text}${colors.reset}`;\r\n}\r\n\r\nexport const logger = {\r\n info(message: string): void {\r\n // eslint-disable-next-line no-console\r\n console.log(colorize('ℹ ', 'blue') + message);\r\n },\r\n \r\n success(message: string): void {\r\n // eslint-disable-next-line no-console\r\n console.log(colorize('✔ ', 'green') + message);\r\n },\r\n \r\n warning(message: string): void {\r\n // eslint-disable-next-line no-console\r\n console.log(colorize('⚠ ', 'yellow') + message);\r\n },\r\n \r\n error(message: string): void {\r\n console.error(colorize('✖ ', 'red') + message);\r\n },\r\n \r\n dim(message: string): void {\r\n // eslint-disable-next-line no-console\r\n console.log(colorize(message, 'dim'));\r\n },\r\n \r\n bold(message: string): string {\r\n return colorize(message, 'bright');\r\n },\r\n};\r\n\r\n/**\r\n * Check if terminal supports colors\r\n */\r\nexport function isColorSupported(): boolean {\r\n return process.stdout.isTTY && process.env.NO_COLOR !== '1';\r\n}\r\n","/**\r\n * @lytjs/cli - File system utilities\r\n */\r\n\r\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from 'fs';\r\nimport { join, dirname } from 'path';\r\n\r\n/**\r\n * Ensure directory exists (create if not)\r\n */\r\nexport function ensureDir(dir: string): void {\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n}\r\n\r\n/**\r\n * Write a file with content, creating parent directories if needed\r\n */\r\nexport function writeFile(filePath: string, content: string): void {\r\n ensureDir(dirname(filePath));\r\n writeFileSync(filePath, content, 'utf-8');\r\n}\r\n\r\n/**\r\n * Read a file as string\r\n */\r\nexport function readFile(filePath: string): string {\r\n return readFileSync(filePath, 'utf-8');\r\n}\r\n\r\n/**\r\n * Check if path exists\r\n */\r\nexport function exists(path: string): boolean {\r\n return existsSync(path);\r\n}\r\n\r\n/**\r\n * Copy directory recursively\r\n */\r\nexport function copyDir(src: string, dest: string): void {\r\n ensureDir(dest);\r\n const entries = readdirSync(src, { withFileTypes: true });\r\n \r\n for (const entry of entries) {\r\n const srcPath = join(src, entry.name);\r\n const destPath = join(dest, entry.name);\r\n \r\n if (entry.isDirectory()) {\r\n copyDir(srcPath, destPath);\r\n } else {\r\n writeFile(destPath, readFileSync(srcPath, 'utf-8'));\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Check if directory is empty\r\n */\r\nexport function isEmptyDir(dir: string): boolean {\r\n if (!existsSync(dir)) return true;\r\n const files = readdirSync(dir);\r\n return files.length === 0;\r\n}\r\n","/**\r\n * @lytjs/cli - Package manager utilities\r\n */\r\n\r\nimport { execSync } from 'child_process';\r\nimport { existsSync } from 'fs';\r\nimport { join } from 'path';\r\n\r\nexport type PackageManager = 'npm' | 'yarn' | 'pnpm';\r\n\r\n/**\r\n * Detect which package manager to use\r\n */\r\nexport function detectPackageManager(cwd: string = process.cwd()): PackageManager {\r\n // Check for lock files\r\n if (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\r\n if (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';\r\n if (existsSync(join(cwd, 'package-lock.json'))) return 'npm';\r\n \r\n // Default to pnpm if available\r\n try {\r\n execSync('pnpm --version', { stdio: 'ignore' });\r\n return 'pnpm';\r\n } catch {\r\n // Fall back to npm\r\n return 'npm';\r\n }\r\n}\r\n\r\n/**\r\n * Get install command for package manager\r\n */\r\nexport function getInstallCommand(pm: PackageManager): string {\r\n switch (pm) {\r\n case 'pnpm': return 'pnpm install';\r\n case 'yarn': return 'yarn';\r\n case 'npm': return 'npm install';\r\n }\r\n}\r\n\r\n/**\r\n * Get run command for package manager\r\n */\r\nexport function getRunCommand(pm: PackageManager, script: string): string {\r\n switch (pm) {\r\n case 'pnpm': return `pnpm run ${script}`;\r\n case 'yarn': return `yarn ${script}`;\r\n case 'npm': return `npm run ${script}`;\r\n }\r\n}\r\n\r\n/**\r\n * Get add dependency command\r\n */\r\nexport function getAddCommand(pm: PackageManager, dep: string, dev: boolean = false): string {\r\n const devFlag = dev ? ' -D' : '';\r\n switch (pm) {\r\n case 'pnpm': return `pnpm add${devFlag} ${dep}`;\r\n case 'yarn': return `yarn add${devFlag} ${dep}`;\r\n case 'npm': return `npm install${devFlag} ${dep}`;\r\n }\r\n}\r\n","/**\r\n * @lytjs/cli - create command\r\n *\r\n * Creates a new LytJS project from a template.\r\n */\r\n\r\nimport type { CreateOptions } from '../types';\r\nimport { logger } from '../utils/logger';\r\nimport { ensureDir, writeFile, exists, isEmptyDir } from '../utils/fs';\r\nimport { detectPackageManager, getInstallCommand } from '../utils/package';\r\nimport { join, resolve } from 'path';\r\nimport { execSync } from 'child_process';\r\n\r\nconst TEMPLATES = {\r\n default: 'Default template with TypeScript and Vite',\r\n minimal: 'Minimal template without extra dependencies',\r\n ssr: 'SSR-enabled template',\r\n router: 'Template with Router integration',\r\n store: 'Template with Store integration',\r\n full: 'Full-featured template with Router, Store, and UI components',\r\n};\r\n\r\n/**\r\n * Create a new LytJS project\r\n */\r\nexport async function create(projectName?: string, options: Partial<CreateOptions> = {}): Promise<void> {\r\n if (!projectName) {\r\n logger.error('Please provide a project name.');\r\n logger.info('Usage: lyt create <project-name>');\r\n process.exit(1);\r\n }\r\n const targetDir = resolve(process.cwd(), projectName);\r\n \r\n // Check if directory exists and is not empty\r\n if (exists(targetDir) && !isEmptyDir(targetDir) && !options.force) {\r\n logger.error(`Directory \"${projectName}\" already exists and is not empty.`);\r\n logger.info('Use --force to overwrite.');\r\n process.exit(1);\r\n }\r\n \r\n logger.info(`Creating a new LytJS project in ${targetDir}...`);\r\n \r\n // Create directory\r\n ensureDir(targetDir);\r\n \r\n // Generate project files\r\n generateProjectFiles(targetDir, projectName, options.template || 'default');\r\n \r\n // Install dependencies\r\n logger.info('Installing dependencies...');\r\n const pm = detectPackageManager();\r\n try {\r\n execSync(getInstallCommand(pm), { cwd: targetDir, stdio: 'inherit' });\r\n logger.success('Dependencies installed successfully!');\r\n } catch (_error) {\r\n logger.warning('Failed to install dependencies automatically.');\r\n logger.info(`Please run \"${getInstallCommand(pm)}\" manually.`);\r\n }\r\n \r\n // Print next steps\r\n logger.success(`Project \"${projectName}\" created successfully!`);\r\n logger.info('');\r\n logger.bold('Next steps:');\r\n logger.info(` cd ${projectName}`);\r\n logger.info(` ${pm === 'npm' ? 'npm run' : pm} dev`);\r\n}\r\n\r\n/**\r\n * Generate project files\r\n */\r\nfunction generateProjectFiles(targetDir: string, projectName: string, template: string): void {\r\n // Determine template-specific settings\r\n const isMinimal = template === 'minimal';\r\n const isSsr = template === 'ssr';\r\n const isRouter = template === 'router' || template === 'full';\r\n const isStore = template === 'store' || template === 'full';\r\n const isFull = template === 'full';\r\n\r\n // package.json - use explicit type to allow property access\r\n interface PackageJsonTemplate {\r\n name: string;\r\n version: string;\r\n type: string;\r\n scripts: Record<string, string>;\r\n dependencies: Record<string, string>;\r\n devDependencies: Record<string, string>;\r\n }\r\n\r\n const packageJson: PackageJsonTemplate = {\r\n name: projectName,\r\n version: '0.0.0',\r\n type: 'module',\r\n scripts: {\r\n dev: 'vite',\r\n build: 'vite build',\r\n preview: 'vite preview',\r\n },\r\n dependencies: {\r\n '@lytjs/core': '^6.0.0',\r\n },\r\n devDependencies: {\r\n '@lytjs/plugin-vite': '^6.0.0',\r\n 'vite': '^5.0.0',\r\n },\r\n };\r\n\r\n // Minimal template: no vitest, no test script\r\n if (!isMinimal) {\r\n packageJson.scripts.test = 'vitest';\r\n packageJson.devDependencies.vitest = '^1.0.0';\r\n }\r\n\r\n // SSR template: add @lytjs/server dependency\r\n if (isSsr) {\r\n packageJson.dependencies['@lytjs/server'] = '^6.0.0';\r\n packageJson.scripts['build:client'] = 'vite build --ssrManifest';\r\n packageJson.scripts['build:server'] = 'vite build --ssr src/entry-server.ts';\r\n packageJson.scripts['build'] = 'npm run build:client && npm run build:server';\r\n packageJson.scripts['preview'] = 'node server';\r\n }\r\n\r\n // Router template: add @lytjs/router\r\n if (isRouter) {\r\n packageJson.dependencies['@lytjs/router'] = '^1.0.0';\r\n }\r\n\r\n // Store template: add @lytjs/store\r\n if (isStore) {\r\n packageJson.dependencies['@lytjs/store'] = '^1.0.0';\r\n }\r\n\r\n // Full template: add @lytjs/ui\r\n if (isFull) {\r\n packageJson.dependencies['@lytjs/ui'] = '^0.4.0';\r\n }\r\n\r\n writeFile(join(targetDir, 'package.json'), JSON.stringify(packageJson, null, 2));\r\n\r\n // vite.config.ts\r\n let viteConfig: string;\r\n if (isSsr) {\r\n viteConfig = `import { defineConfig } from 'vite';\r\nimport lytjs from '@lytjs/plugin-vite';\r\n\r\nexport default defineConfig({\r\n plugins: [lytjs()],\r\n build: {\r\n ssrManifest: true,\r\n },\r\n});\r\n`;\r\n } else {\r\n viteConfig = `import { defineConfig } from 'vite';\r\nimport lytjs from '@lytjs/plugin-vite';\r\n\r\nexport default defineConfig({\r\n plugins: [lytjs()],\r\n});\r\n`;\r\n }\r\n writeFile(join(targetDir, 'vite.config.ts'), viteConfig);\r\n\r\n // index.html\r\n const indexHtml = `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n <title>${projectName}</title>\r\n </head>\r\n <body>\r\n <div id=\"app\"></div>\r\n <script type=\"module\" src=\"/src/main.ts\"></script>\r\n </body>\r\n</html>\r\n`;\r\n writeFile(join(targetDir, 'index.html'), indexHtml);\r\n\r\n // src/main.ts\r\n let mainTs: string;\r\n if (isSsr) {\r\n mainTs = `import { createApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\nimport { createSSRApp } from '@lytjs/server';\r\n${isRouter ? \"import { createRouter, createWebHistory } from '@lytjs/router';\" : ''}\r\n${isStore ? \"import { createPinia } from '@lytjs/store';\" : ''}\r\n\r\nconst app = createSSRApp(App);\r\n${isStore ? 'app.use(createPinia());' : ''}\r\n${isRouter ? `\r\nconst router = createRouter({\r\n history: createWebHistory(),\r\n routes: [\r\n { path: '/', component: () => import('./pages/Home.lyt') },\r\n { path: '/about', component: () => import('./pages/About.lyt') },\r\n ],\r\n});\r\napp.use(router);\r\n` : ''}\r\napp.mount('#app');\r\n`;\r\n } else if (isRouter || isStore) {\r\n mainTs = `import { createApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\n${isRouter ? \"import { createRouter, createWebHistory } from '@lytjs/router';\" : ''}\r\n${isStore ? \"import { createPinia } from '@lytjs/store';\" : ''}\r\n\r\nconst app = createApp(App);\r\n${isStore ? 'app.use(createPinia());' : ''}\r\n${isRouter ? `\r\nconst router = createRouter({\r\n history: createWebHistory(),\r\n routes: [\r\n { path: '/', component: () => import('./pages/Home.lyt') },\r\n { path: '/about', component: () => import('./pages/About.lyt') },\r\n ],\r\n});\r\napp.use(router);\r\n` : ''}\r\napp.mount('#app');\r\n`;\r\n } else {\r\n mainTs = `import { createApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\n\r\ncreateApp(App).mount('#app');\r\n`;\r\n }\r\n writeFile(join(targetDir, 'src/main.ts'), mainTs);\r\n\r\n // src/App.lyt\r\n let appLyt: string;\r\n if (isMinimal) {\r\n appLyt = `<template>\r\n <div class=\"app\">\r\n <h1>{{ title }}</h1>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nconst title = 'Hello LytJS!';\r\n</script>\r\n\r\n<style scoped>\r\n.app {\r\n text-align: center;\r\n}\r\n</style>\r\n`;\r\n } else if (isRouter) {\r\n appLyt = `<template>\r\n <div class=\"app\">\r\n <nav class=\"nav\">\r\n <router-link to=\"/\">Home</router-link>\r\n <router-link to=\"/about\">About</router-link>\r\n </nav>\r\n <router-view />\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { RouterLink, RouterView } from '@lytjs/router';\r\n</script>\r\n\r\n<style scoped>\r\n.app {\r\n text-align: center;\r\n padding: 2rem;\r\n}\r\n\r\n.nav {\r\n margin-bottom: 2rem;\r\n}\r\n\r\n.nav a {\r\n margin: 0 1rem;\r\n color: #42b883;\r\n text-decoration: none;\r\n}\r\n\r\n.nav a:hover {\r\n text-decoration: underline;\r\n}\r\n</style>\r\n`;\r\n } else {\r\n appLyt = `<template>\r\n <div class=\"app\">\r\n <h1>{{ title }}</h1>\r\n <p>Welcome to your LytJS app!</p>\r\n </div>\r\n</template>\r\n\r\n<script setup>\r\nconst title = 'Hello LytJS!';\r\n</script>\r\n\r\n<style scoped>\r\n.app {\r\n text-align: center;\r\n padding: 2rem;\r\n}\r\n\r\nh1 {\r\n color: #42b883;\r\n}\r\n</style>\r\n`;\r\n }\r\n writeFile(join(targetDir, 'src/App.lyt'), appLyt);\r\n\r\n // Router template: add pages and store\r\n if (isRouter) {\r\n // Home page\r\n const homePage = `<template>\r\n <div class=\"home\">\r\n <h1>Home</h1>\r\n ${isStore ? `\r\n <p>Count: {{ count }}</p>\r\n <button @click=\"increment\">Increment</button>\r\n <button @click=\"decrement\">Decrement</button>\r\n ` : ''}\r\n <p>Welcome to the Home page!</p>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n${isStore ? `import { useCounterStore } from '../stores/counter';\r\nconst counterStore = useCounterStore();\r\nconst { count, increment, decrement } = counterStore;\r\n` : ''}\r\n</script>\r\n\r\n<style scoped>\r\n.home {\r\n padding: 1rem;\r\n}\r\n</style>\r\n`;\r\n ensureDir(join(targetDir, 'src', 'pages'));\r\n writeFile(join(targetDir, 'src', 'pages', 'Home.lyt'), homePage);\r\n\r\n // About page\r\n const aboutPage = `<template>\r\n <div class=\"about\">\r\n <h1>About</h1>\r\n <p>This is the About page!</p>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n</script>\r\n\r\n<style scoped>\r\n.about {\r\n padding: 1rem;\r\n}\r\n</style>\r\n`;\r\n writeFile(join(targetDir, 'src', 'pages', 'About.lyt'), aboutPage);\r\n }\r\n\r\n // Store template: add example store\r\n if (isStore) {\r\n const counterStore = `import { defineStore } from '@lytjs/store';\r\nimport { signal, computed } from '@lytjs/reactivity';\r\n\r\nexport const useCounterStore = defineStore('counter', () => {\r\n // State\r\n const count = signal(0);\r\n\r\n // Getters\r\n const doubleCount = computed(() => count.value * 2);\r\n\r\n // Actions\r\n function increment() {\r\n count.value++;\r\n }\r\n\r\n function decrement() {\r\n count.value--;\r\n }\r\n\r\n function reset() {\r\n count.value = 0;\r\n }\r\n\r\n return {\r\n count,\r\n doubleCount,\r\n increment,\r\n decrement,\r\n reset,\r\n };\r\n});\r\n`;\r\n ensureDir(join(targetDir, 'src', 'stores'));\r\n writeFile(join(targetDir, 'src', 'stores', 'counter.ts'), counterStore);\r\n }\r\n\r\n // SSR-specific files\r\n if (isSsr) {\r\n // src/entry-server.ts\r\n const entryServer = `import { createSSRApp, h } from '@lytjs/core';\r\nimport { renderToString } from '@lytjs/ssr';\r\nimport App from './App.lyt';\r\n\r\nexport async function render(url: string) {\r\n const app = createSSRApp({\r\n render() {\r\n return h(App);\r\n }\r\n });\r\n\r\n const html = await renderToString(app);\r\n return html;\r\n}\r\n`;\r\n writeFile(join(targetDir, 'src/entry-server.ts'), entryServer);\r\n\r\n // src/entry-client.ts\r\n const entryClient = `import { createApp } from '@lytjs/core';\r\nimport App from './App.lyt';\r\n\r\nconst app = createApp(App);\r\napp.mount('#app');\r\n`;\r\n writeFile(join(targetDir, 'src/entry-client.ts'), entryClient);\r\n\r\n // server.ts - complete SSR server implementation\r\n const serverTs = `/**\r\n * LytJS SSR Server\r\n *\r\n * Complete SSR server with Vite dev server and production build support.\r\n * Supports streaming SSR, route prefetching, and static file serving.\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\nimport http from 'http';\r\n\r\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\r\nconst isProduction = process.env.NODE_ENV === 'production';\r\nconst DIST_DIR = path.join(__dirname, 'dist');\r\nconst PORT = parseInt(process.env.PORT || '3000', 10);\r\n\r\ninterface RenderOptions {\r\n url: string;\r\n template: string;\r\n manifest?: Record<string, string[]>;\r\n}\r\n\r\nasync function renderPage({ url, template, manifest }: RenderOptions): Promise<string> {\r\n let app: any;\r\n let vite: any;\r\n\r\n if (!isProduction) {\r\n const { createServer: createViteServer } = await import('vite');\r\n vite = await createViteServer({\r\n server: { middlewareMode: true },\r\n appType: 'custom',\r\n });\r\n app = (await vite.ssrLoadModule(path.join(__dirname, 'src/entry-server.ts'))).default;\r\n } else {\r\n app = (await import(path.join(DIST_DIR, 'server/entry-server.js'))).default;\r\n }\r\n\r\n const html = await app.render(url);\r\n return template.replace('<!--app-html-->', html);\r\n}\r\n\r\nasync function createServer() {\r\n let vite: any;\r\n\r\n // Load index.html template\r\n let template: string;\r\n\r\n if (!isProduction) {\r\n const { createServer: createViteServer } = await import('vite');\r\n vite = await createViteServer({\r\n server: { middlewareMode: true },\r\n appType: 'custom',\r\n });\r\n template = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf-8');\r\n } else {\r\n template = fs.readFileSync(path.join(DIST_DIR, 'client/index.html'), 'utf-8');\r\n }\r\n\r\n const server = http.createServer(async (req, res) => {\r\n const url = req.url || '/';\r\n\r\n try {\r\n if (!isProduction && url.startsWith('/@')) {\r\n // Vite dev server requests\r\n return;\r\n }\r\n\r\n // Static assets\r\n if (url.startsWith('/assets/') || url.endsWith('.js') || url.endsWith('.css')) {\r\n const filePath = isProduction\r\n ? path.join(DIST_DIR, 'client', url)\r\n : path.join(__dirname, url);\r\n\r\n if (fs.existsSync(filePath)) {\r\n const ext = path.extname(filePath);\r\n const contentType = ext === '.css' ? 'text/css' : 'application/javascript';\r\n res.writeHead(200, { 'Content-Type': contentType });\r\n res.end(fs.readFileSync(filePath));\r\n return;\r\n }\r\n }\r\n\r\n // SSR rendering\r\n const html = await renderPage({\r\n url,\r\n template,\r\n manifest: isProduction\r\n ? JSON.parse(fs.readFileSync(path.join(DIST_DIR, 'client/ssr-manifest.json'), 'utf-8'))\r\n : undefined\r\n });\r\n\r\n res.writeHead(200, { 'Content-Type': 'text/html' });\r\n res.end(html);\r\n } catch (err: any) {\r\n if (!isProduction && vite) {\r\n vite.ssrFixStacktrace(err);\r\n }\r\n console.error('SSR Error:', err);\r\n res.writeHead(500, { 'Content-Type': 'text/plain' });\r\n res.end('Internal Server Error');\r\n }\r\n });\r\n\r\n server.listen(PORT, () => {\r\n console.log(\\`LytJS SSR server running at http://localhost:\\${PORT}\\`);\r\n console.log(\\`Mode: \\${isProduction ? 'Production' : 'Development'}\\`);\r\n });\r\n}\r\n\r\ncreateServer().catch(console.error);\r\n`;\r\n writeFile(join(targetDir, 'server.ts'), serverTs);\r\n }\r\n\r\n // tsconfig.json\r\n const tsConfig = {\r\n compilerOptions: {\r\n target: 'ES2020',\r\n useDefineForClassFields: true,\r\n module: 'ESNext',\r\n lib: ['ES2020', 'DOM', 'DOM.Iterable'],\r\n skipLibCheck: true,\r\n moduleResolution: 'bundler',\r\n allowImportingTsExtensions: true,\r\n resolveJsonModule: true,\r\n isolatedModules: true,\r\n noEmit: true,\r\n strict: true,\r\n noUnusedLocals: true,\r\n noUnusedParameters: true,\r\n noFallthroughCasesInSwitch: true,\r\n },\r\n include: ['src/**/*.ts', 'src/**/*.lyt'],\r\n references: [{ path: './tsconfig.node.json' }],\r\n };\r\n writeFile(join(targetDir, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));\r\n\r\n // tsconfig.node.json\r\n const tsConfigNode = {\r\n compilerOptions: {\r\n composite: true,\r\n skipLibCheck: true,\r\n module: 'ESNext',\r\n moduleResolution: 'bundler',\r\n allowSyntheticDefaultImports: true,\r\n },\r\n include: ['vite.config.ts'],\r\n };\r\n writeFile(join(targetDir, 'tsconfig.node.json'), JSON.stringify(tsConfigNode, null, 2));\r\n\r\n // .gitignore\r\n const gitignore = `# Logs\r\nlogs\r\n*.log\r\nnpm-debug.log*\r\nyarn-debug.log*\r\nyarn-error.log*\r\npnpm-debug.log*\r\nlerna-debug.log*\r\n\r\nnode_modules\r\ndist\r\ndist-ssr\r\n*.local\r\n\r\n# Editor directories and files\r\n.vscode/*\r\n!.vscode/extensions.json\r\n.idea\r\n.DS_Store\r\n*.suo\r\n*.ntvs*\r\n*.njsproj\r\n*.sln\r\n*.sw?\r\n`;\r\n writeFile(join(targetDir, '.gitignore'), gitignore);\r\n}\r\n\r\n/**\r\n * List available templates\r\n */\r\nexport function listTemplates(): void {\r\n logger.bold('Available templates:');\r\n for (const [name, description] of Object.entries(TEMPLATES)) {\r\n logger.info(` ${name.padEnd(10)} - ${description}`);\r\n }\r\n}\r\n","import { create } from './commands/create';\r\n\r\ncreate().catch(console.error);"]}