@flight-framework/cli 0.0.16 → 0.2.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.
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
8
8
 
9
9
  // src/index.ts
10
10
  import { cac } from "cac";
11
- import pc5 from "picocolors";
11
+ import pc6 from "picocolors";
12
12
 
13
13
  // src/version.ts
14
14
  var VERSION = "0.0.1";
@@ -61,6 +61,21 @@ async function createCommand(name, options) {
61
61
  console.log(pc.red("Project creation cancelled."));
62
62
  return;
63
63
  }
64
+ if (options.raw) {
65
+ const projectPath2 = resolve(process.cwd(), projectName);
66
+ createRawProject(projectPath2, projectName, options);
67
+ return;
68
+ }
69
+ if (options.empty) {
70
+ const projectPath2 = resolve(process.cwd(), projectName);
71
+ createEmptyProject(projectPath2, projectName, options);
72
+ return;
73
+ }
74
+ if (options.minimal) {
75
+ const projectPath2 = resolve(process.cwd(), projectName);
76
+ createMinimalProject(projectPath2, projectName, options);
77
+ return;
78
+ }
64
79
  if (!uiFramework) {
65
80
  const response = await prompts({
66
81
  type: "select",
@@ -75,6 +90,9 @@ async function createCommand(name, options) {
75
90
  console.log(pc.red("Project creation cancelled."));
76
91
  return;
77
92
  }
93
+ let useCase = options.useCase;
94
+ const useCaseDir = join(TEMPLATES_DIR, "use-cases", useCase || "");
95
+ const isUseCase = useCase && existsSync(useCaseDir);
78
96
  let bundler = options.bundler;
79
97
  if (!bundler) {
80
98
  const response = await prompts({
@@ -110,8 +128,12 @@ async function createCommand(name, options) {
110
128
  Creating project in ${projectPath}...
111
129
  `));
112
130
  try {
113
- copyTemplate(projectPath, uiFramework, bundler, projectName);
114
- console.log(pc.green("\u2713") + " Project structure created");
131
+ if (isUseCase && useCase) {
132
+ copyUseCaseTemplate(projectPath, useCase, projectName);
133
+ } else {
134
+ copyTemplate(projectPath, uiFramework, bundler, projectName);
135
+ }
136
+ console.log(pc.green("[OK]") + " Project structure created");
115
137
  if (options.git) {
116
138
  try {
117
139
  execSync("git init", { cwd: projectPath, stdio: "ignore" });
@@ -179,6 +201,15 @@ function copyTemplate(projectPath, ui, bundler, projectName) {
179
201
  unlinkSync(gitignoreSrc);
180
202
  }
181
203
  }
204
+ function copyUseCaseTemplate(projectPath, useCase, projectName) {
205
+ const useCaseDir = join(TEMPLATES_DIR, "use-cases", useCase);
206
+ mkdirSync(projectPath, { recursive: true });
207
+ const vars = {
208
+ "{{PROJECT_NAME}}": projectName,
209
+ "{{USE_CASE}}": useCase
210
+ };
211
+ copyDirWithTemplates(useCaseDir, projectPath, vars);
212
+ }
182
213
  function copyDirWithTemplates(srcDir, destDir, vars) {
183
214
  if (!existsSync(srcDir)) return;
184
215
  const entries = readdirSync(srcDir, { withFileTypes: true });
@@ -205,6 +236,277 @@ function copyDirWithTemplates(srcDir, destDir, vars) {
205
236
  }
206
237
  }
207
238
  }
239
+ function createRawProject(projectPath, projectName, options) {
240
+ mkdirSync(projectPath, { recursive: true });
241
+ const packageJson = {
242
+ name: projectName,
243
+ version: "0.0.1",
244
+ type: "module",
245
+ scripts: {
246
+ // Works with Bun, Node 22+, or Deno
247
+ "dev": "node --watch server.js",
248
+ "dev:bun": "bun --watch server.js",
249
+ "dev:deno": "deno run --allow-net server.js",
250
+ "start": "node server.js"
251
+ },
252
+ dependencies: {},
253
+ devDependencies: {}
254
+ };
255
+ writeFileSync(
256
+ join(projectPath, "package.json"),
257
+ JSON.stringify(packageJson, null, 2)
258
+ );
259
+ const serverCode = `/**
260
+ * ${projectName}
261
+ *
262
+ * 100% Web Standards server. Zero dependencies. Zero lock-in.
263
+ * Works on: Bun, Deno, Node 22+, Cloudflare Workers
264
+ *
265
+ * Run:
266
+ * bun server.js
267
+ * deno run --allow-net server.js
268
+ * node server.js (Node 22+)
269
+ */
270
+
271
+ /**
272
+ * Handle incoming requests using Web Standard APIs
273
+ * @param {Request} request
274
+ * @returns {Response}
275
+ */
276
+ function handleRequest(request) {
277
+ const url = new URL(request.url);
278
+ const method = request.method;
279
+
280
+ // Router
281
+ if (method === 'GET' && url.pathname === '/') {
282
+ return Response.json({
283
+ message: 'Hello World!',
284
+ runtime: detectRuntime(),
285
+ docs: 'https://flight.dev/docs/quickstart-http',
286
+ });
287
+ }
288
+
289
+ if (method === 'GET' && url.pathname === '/health') {
290
+ return Response.json({
291
+ status: 'ok',
292
+ timestamp: Date.now(),
293
+ });
294
+ }
295
+
296
+ if (method === 'GET' && url.pathname.startsWith('/api/')) {
297
+ return Response.json({
298
+ path: url.pathname,
299
+ query: Object.fromEntries(url.searchParams),
300
+ });
301
+ }
302
+
303
+ // 404
304
+ return Response.json(
305
+ { error: 'Not Found', path: url.pathname },
306
+ { status: 404 }
307
+ );
308
+ }
309
+
310
+ /**
311
+ * Detect which runtime we're running on
312
+ */
313
+ function detectRuntime() {
314
+ if (typeof Bun !== 'undefined') return 'bun';
315
+ if (typeof Deno !== 'undefined') return 'deno';
316
+ return 'node';
317
+ }
318
+
319
+ // Export for different runtimes
320
+ const port = process.env.PORT || 3000;
321
+
322
+ // Bun / Cloudflare Workers style
323
+ export default {
324
+ port,
325
+ fetch: handleRequest,
326
+ };
327
+
328
+ // Also start server for Node.js
329
+ if (detectRuntime() === 'node') {
330
+ const { serve } = await import('node:http');
331
+ serve({ port }, (req, res) => {
332
+ const url = 'http://localhost' + req.url;
333
+ const request = new Request(url, { method: req.method });
334
+ handleRequest(request).then(response => {
335
+ res.writeHead(response.status, Object.fromEntries(response.headers));
336
+ response.text().then(body => res.end(body));
337
+ });
338
+ });
339
+ console.log(\`Server running at http://localhost:\${port}\`);
340
+ }
341
+ `;
342
+ writeFileSync(join(projectPath, "server.js"), serverCode);
343
+ if (options.git) {
344
+ writeFileSync(
345
+ join(projectPath, ".gitignore"),
346
+ "node_modules\ndist\n.env\n.env.local\n"
347
+ );
348
+ try {
349
+ execSync("git init", { cwd: projectPath, stdio: "ignore" });
350
+ } catch {
351
+ }
352
+ }
353
+ console.log(`
354
+ ${pc.green("[OK] Raw project created!")}
355
+
356
+ ${pc.bold("ZERO dependencies. ZERO lock-in. 100% Web Standards.")}
357
+
358
+ ${pc.cyan("Run with any runtime:")}
359
+
360
+ ${pc.dim("# Bun (fastest)")}
361
+ bun server.js
362
+
363
+ ${pc.dim("# Deno")}
364
+ deno run --allow-net server.js
365
+
366
+ ${pc.dim("# Node.js 22+")}
367
+ node server.js
368
+
369
+ ${pc.dim("Want to add Flight later? Just run:")}
370
+ flight add http ${pc.dim("# HTTP server with routing")}
371
+ flight add db ${pc.dim("# Database abstraction")}
372
+ flight add cache ${pc.dim("# Caching layer")}
373
+
374
+ ${pc.dim("Path:")} ${projectPath}
375
+ `);
376
+ }
377
+ function createEmptyProject(projectPath, projectName, options) {
378
+ mkdirSync(projectPath, { recursive: true });
379
+ const packageJson = {
380
+ name: projectName,
381
+ version: "0.0.1",
382
+ type: "module",
383
+ scripts: {
384
+ dev: "node server.js"
385
+ },
386
+ dependencies: {},
387
+ devDependencies: {}
388
+ };
389
+ writeFileSync(
390
+ join(projectPath, "package.json"),
391
+ JSON.stringify(packageJson, null, 2)
392
+ );
393
+ if (options.git) {
394
+ writeFileSync(
395
+ join(projectPath, ".gitignore"),
396
+ "node_modules\ndist\n.env\n.env.local\n"
397
+ );
398
+ try {
399
+ execSync("git init", { cwd: projectPath, stdio: "ignore" });
400
+ } catch {
401
+ }
402
+ }
403
+ console.log(`
404
+ ${pc.green("[OK] Empty project created!")}
405
+
406
+ ${pc.cyan("Your project is a blank canvas.")} Add what you need:
407
+
408
+ ${pc.dim("# HTTP server")}
409
+ npm install @flight-framework/http
410
+
411
+ ${pc.dim("# Database")}
412
+ npm install @flight-framework/db
413
+
414
+ ${pc.dim("# Cache")}
415
+ npm install @flight-framework/cache
416
+
417
+ ${pc.dim("# Authentication")}
418
+ npm install @flight-framework/auth
419
+
420
+ ${pc.dim("Path:")} ${projectPath}
421
+ `);
422
+ }
423
+ function createMinimalProject(projectPath, projectName, options) {
424
+ mkdirSync(projectPath, { recursive: true });
425
+ const packageJson = {
426
+ name: projectName,
427
+ version: "0.0.1",
428
+ type: "module",
429
+ scripts: {
430
+ dev: "node --watch server.js",
431
+ start: "node server.js"
432
+ },
433
+ dependencies: {
434
+ "@flight-framework/http": "^0.0.1"
435
+ }
436
+ };
437
+ writeFileSync(
438
+ join(projectPath, "package.json"),
439
+ JSON.stringify(packageJson, null, 2)
440
+ );
441
+ const serverCode = `/**
442
+ * ${projectName} - Built with Flight
443
+ *
444
+ * This is a minimal Flight server. Add more as you need.
445
+ * Run: npm run dev
446
+ */
447
+
448
+ import { createServer } from '@flight-framework/http';
449
+
450
+ const app = createServer();
451
+
452
+ // Your routes
453
+ app.get('/', (c) => c.json({
454
+ message: 'Hello from Flight!',
455
+ docs: 'https://flight.dev/docs/quickstart-http'
456
+ }));
457
+
458
+ app.get('/health', (c) => c.json({
459
+ status: 'ok',
460
+ timestamp: Date.now()
461
+ }));
462
+
463
+ // Start server
464
+ const port = process.env.PORT || 3000;
465
+ console.log(\`Server running at http://localhost:\${port}\`);
466
+
467
+ export default { port, fetch: app.fetch };
468
+ `;
469
+ writeFileSync(join(projectPath, "server.js"), serverCode);
470
+ if (options.git) {
471
+ writeFileSync(
472
+ join(projectPath, ".gitignore"),
473
+ "node_modules\ndist\n.env\n.env.local\n"
474
+ );
475
+ try {
476
+ execSync("git init", { cwd: projectPath, stdio: "ignore" });
477
+ } catch {
478
+ }
479
+ }
480
+ if (options.install) {
481
+ console.log(pc.dim("\\nInstalling dependencies...\\n"));
482
+ try {
483
+ const pm = detectPackageManager();
484
+ execSync(`${pm} install`, { cwd: projectPath, stdio: "inherit" });
485
+ } catch {
486
+ }
487
+ }
488
+ console.log(`
489
+ ${pc.green("[OK] Minimal project created!")}
490
+
491
+ ${pc.cyan("Next steps:")}
492
+
493
+ ${pc.dim("$")} cd ${projectName}
494
+ ${pc.dim("$")} ${options.install ? "" : "npm install && "}npm run dev
495
+
496
+ ${pc.dim("Add more features as needed:")}
497
+
498
+ ${pc.dim("# File-based routing")}
499
+ npm install @flight-framework/core
500
+
501
+ ${pc.dim("# Database")}
502
+ npm install @flight-framework/db pg
503
+
504
+ ${pc.dim("# Caching")}
505
+ npm install @flight-framework/cache
506
+
507
+ ${pc.cyan("Happy flying!")}
508
+ `);
509
+ }
208
510
 
209
511
  // src/commands/dev.ts
210
512
  import { resolve as resolve2, join as join2 } from "path";
@@ -1294,25 +1596,234 @@ async function typesGenerateCommand(options = {}) {
1294
1596
  }
1295
1597
  }
1296
1598
 
1599
+ // src/commands/add.ts
1600
+ import { existsSync as existsSync6 } from "fs";
1601
+ import { join as join5 } from "path";
1602
+ import { execSync as execSync2 } from "child_process";
1603
+ import pc5 from "picocolors";
1604
+ var PACKAGES = {
1605
+ // Core
1606
+ "http": {
1607
+ name: "@flight-framework/http",
1608
+ description: "HTTP server with routing and middleware",
1609
+ category: "core"
1610
+ },
1611
+ "core": {
1612
+ name: "@flight-framework/core",
1613
+ description: "File-based routing and configuration",
1614
+ category: "core"
1615
+ },
1616
+ // Data
1617
+ "db": {
1618
+ name: "@flight-framework/db",
1619
+ description: "Database abstraction layer",
1620
+ category: "data",
1621
+ drivers: ["pg", "@libsql/client", "@neondatabase/serverless", "@supabase/supabase-js"]
1622
+ },
1623
+ "cache": {
1624
+ name: "@flight-framework/cache",
1625
+ description: "Caching with multiple adapters",
1626
+ category: "data"
1627
+ },
1628
+ // Auth
1629
+ "auth": {
1630
+ name: "@flight-framework/auth",
1631
+ description: "Authentication adapters",
1632
+ category: "auth"
1633
+ },
1634
+ // Frontend
1635
+ "forms": {
1636
+ name: "@flight-framework/forms",
1637
+ description: "Type-safe form handling",
1638
+ category: "frontend"
1639
+ },
1640
+ "i18n": {
1641
+ name: "@flight-framework/i18n",
1642
+ description: "Internationalization",
1643
+ category: "frontend"
1644
+ },
1645
+ "seo": {
1646
+ name: "@flight-framework/seo",
1647
+ description: "SEO utilities",
1648
+ category: "frontend"
1649
+ },
1650
+ "image": {
1651
+ name: "@flight-framework/image",
1652
+ description: "Image optimization",
1653
+ category: "frontend"
1654
+ },
1655
+ // Communication
1656
+ "email": {
1657
+ name: "@flight-framework/email",
1658
+ description: "Email sending",
1659
+ category: "communication"
1660
+ },
1661
+ "realtime": {
1662
+ name: "@flight-framework/realtime",
1663
+ description: "WebSocket and real-time features",
1664
+ category: "communication"
1665
+ },
1666
+ // Deployment
1667
+ "helpers": {
1668
+ name: "@flight-framework/helpers",
1669
+ description: "Optional helper utilities (detection, suggestions)",
1670
+ category: "utilities"
1671
+ }
1672
+ };
1673
+ async function addCommand(packageName) {
1674
+ const cwd = process.cwd();
1675
+ if (!existsSync6(join5(cwd, "package.json"))) {
1676
+ console.log(pc5.red("No package.json found. Run this command from your project directory."));
1677
+ process.exit(1);
1678
+ }
1679
+ if (!packageName) {
1680
+ showAvailablePackages();
1681
+ return;
1682
+ }
1683
+ const pkg = PACKAGES[packageName];
1684
+ if (!pkg) {
1685
+ console.log(pc5.red(`Unknown package: ${packageName}`));
1686
+ console.log(pc5.dim("Run `flight add` to see available packages."));
1687
+ process.exit(1);
1688
+ }
1689
+ console.log(`
1690
+ ${pc5.cyan("Adding")} ${pc5.bold(pkg.name)}...`);
1691
+ console.log(pc5.dim(pkg.description));
1692
+ console.log();
1693
+ const pm = detectPackageManager2();
1694
+ try {
1695
+ const installCmd = pm === "npm" ? "npm install" : `${pm} add`;
1696
+ execSync2(`${installCmd} ${pkg.name}`, { cwd, stdio: "inherit" });
1697
+ console.log(`
1698
+ ${pc5.green("[OK]")} ${pkg.name} added successfully!`);
1699
+ showNextSteps(packageName, pkg);
1700
+ } catch (error) {
1701
+ console.log(pc5.red(`
1702
+ Failed to install ${pkg.name}`));
1703
+ process.exit(1);
1704
+ }
1705
+ }
1706
+ function detectPackageManager2() {
1707
+ const cwd = process.cwd();
1708
+ if (existsSync6(join5(cwd, "pnpm-lock.yaml"))) return "pnpm";
1709
+ if (existsSync6(join5(cwd, "yarn.lock"))) return "yarn";
1710
+ if (existsSync6(join5(cwd, "bun.lockb"))) return "bun";
1711
+ return "npm";
1712
+ }
1713
+ function showAvailablePackages() {
1714
+ console.log(`
1715
+ ${pc5.cyan("Available Flight packages:")}
1716
+
1717
+ ${pc5.bold("Core")}
1718
+ ${pc5.green("http")} ${pc5.dim("HTTP server with routing and middleware")}
1719
+ ${pc5.green("core")} ${pc5.dim("File-based routing and configuration")}
1720
+
1721
+ ${pc5.bold("Data")}
1722
+ ${pc5.green("db")} ${pc5.dim("Database abstraction layer")}
1723
+ ${pc5.green("cache")} ${pc5.dim("Caching with multiple adapters")}
1724
+
1725
+ ${pc5.bold("Auth")}
1726
+ ${pc5.green("auth")} ${pc5.dim("Authentication adapters")}
1727
+
1728
+ ${pc5.bold("Frontend")}
1729
+ ${pc5.green("forms")} ${pc5.dim("Type-safe form handling")}
1730
+ ${pc5.green("i18n")} ${pc5.dim("Internationalization")}
1731
+ ${pc5.green("seo")} ${pc5.dim("SEO utilities")}
1732
+ ${pc5.green("image")} ${pc5.dim("Image optimization")}
1733
+
1734
+ ${pc5.bold("Communication")}
1735
+ ${pc5.green("email")} ${pc5.dim("Email sending")}
1736
+ ${pc5.green("realtime")} ${pc5.dim("WebSocket and real-time features")}
1737
+
1738
+ ${pc5.bold("Utilities")}
1739
+ ${pc5.green("helpers")} ${pc5.dim("Optional helper utilities")}
1740
+
1741
+ ${pc5.cyan("Usage:")}
1742
+ flight add http
1743
+ flight add db
1744
+ flight add auth
1745
+ `);
1746
+ }
1747
+ function showNextSteps(packageName, pkg) {
1748
+ const examples = {
1749
+ "http": `
1750
+ ${pc5.cyan("Quick example:")}
1751
+
1752
+ import { createServer } from '@flight-framework/http';
1753
+
1754
+ const app = createServer();
1755
+ app.get('/', (c) => c.json({ hello: 'world' }));
1756
+
1757
+ export default { port: 3000, fetch: app.fetch };
1758
+ `,
1759
+ "db": `
1760
+ ${pc5.cyan("Quick example:")}
1761
+
1762
+ import { createDb } from '@flight-framework/db';
1763
+ import { postgres } from '@flight-framework/db/postgres';
1764
+
1765
+ const db = createDb(postgres({ connectionString: process.env.DATABASE_URL }));
1766
+ const users = await db.query('SELECT * FROM users');
1767
+
1768
+ ${pc5.dim("You may also need a driver:")}
1769
+ npm install pg ${pc5.dim("# PostgreSQL")}
1770
+ npm install @libsql/client ${pc5.dim("# Turso/SQLite")}
1771
+ npm install @neondatabase/serverless ${pc5.dim("# Neon")}
1772
+ `,
1773
+ "cache": `
1774
+ ${pc5.cyan("Quick example:")}
1775
+
1776
+ import { createCache, lru } from '@flight-framework/cache';
1777
+
1778
+ const cache = createCache(lru({ max: 1000 }));
1779
+ await cache.set('key', { data: 'value' });
1780
+ const value = await cache.get('key');
1781
+ `,
1782
+ "auth": `
1783
+ ${pc5.cyan("Quick example:")}
1784
+
1785
+ import { createAuth } from '@flight-framework/auth';
1786
+ import { betterAuth } from '@flight-framework/auth/better-auth';
1787
+
1788
+ const auth = createAuth(betterAuth({ db }));
1789
+ const user = await auth.getUser(request);
1790
+ `,
1791
+ "forms": `
1792
+ ${pc5.cyan("Quick example:")}
1793
+
1794
+ import { createForm } from '@flight-framework/forms';
1795
+ import { zodAdapter } from '@flight-framework/forms/adapters/zod';
1796
+
1797
+ const form = createForm({ schema: zodAdapter(schema) });
1798
+ const result = form.validate(data);
1799
+ `
1800
+ };
1801
+ if (examples[packageName]) {
1802
+ console.log(examples[packageName]);
1803
+ }
1804
+ console.log(`${pc5.dim("Docs:")} https://flight.dev/docs/packages/${packageName}`);
1805
+ }
1806
+
1297
1807
  // src/index.ts
1298
1808
  var cli = cac("flight");
1299
1809
  var LOGO = `
1300
- ${pc5.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
1301
- ${pc5.cyan(" \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D")}
1302
- ${pc5.cyan(" \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
1303
- ${pc5.cyan(" \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
1304
- ${pc5.cyan(" \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 ")}
1305
- ${pc5.cyan(" \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ")}
1810
+ ${pc6.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
1811
+ ${pc6.cyan(" \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D")}
1812
+ ${pc6.cyan(" \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
1813
+ ${pc6.cyan(" \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
1814
+ ${pc6.cyan(" \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 ")}
1815
+ ${pc6.cyan(" \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ")}
1306
1816
 
1307
- ${pc5.dim("The Agnostic Full-Stack Framework")}
1308
- ${pc5.dim("Maximum Flexibility. Zero Lock-in.")}
1817
+ ${pc6.dim("The Agnostic Full-Stack Framework")}
1818
+ ${pc6.dim("Maximum Flexibility. Zero Lock-in.")}
1309
1819
  `;
1310
1820
  function printLogo() {
1311
1821
  console.log(LOGO);
1312
1822
  }
1313
1823
  cli.version(VERSION);
1314
1824
  cli.help();
1315
- cli.command("create [name]", "Create a new Flight project").option("-t, --template <template>", "Project template to use", { default: "basic" }).option("--ui <framework>", "UI framework (react, vue, svelte, solid, vanilla)").option("--ts", "Use TypeScript", { default: true }).option("--git", "Initialize git repository", { default: true }).option("--install", "Install dependencies", { default: true }).action(createCommand);
1825
+ cli.command("create [name]", "Create a new Flight project").option("-t, --template <template>", "Project template to use", { default: "basic" }).option("--ui <framework>", "UI framework (react, vue, svelte, solid, vanilla)").option("--use-case <useCase>", "Use-case template (blog, ecommerce, saas, api, docs)").option("--ts", "Use TypeScript", { default: true }).option("--git", "Initialize git repository", { default: true }).option("--install", "Install dependencies", { default: true }).option("--raw", "Create raw project (100% Web Standards, zero dependencies)").option("--empty", "Create empty project (just package.json)").option("--minimal", "Create minimal project (single server file with Flight)").action(createCommand);
1826
+ cli.command("add [package]", "Add a Flight package to your project").action(addCommand);
1316
1827
  cli.command("dev", "Start development server").option("-p, --port <port>", "Port to listen on").option("-h, --host <host>", "Host to bind to").option("--open", "Open browser on start").option("--https", "Enable HTTPS").option("--ssr", "Enable Server-Side Rendering").action(devCommand);
1317
1828
  cli.command("build", "Build for production").option("--outDir <dir>", "Output directory").option("--sourcemap", "Generate source maps").option("--minify", "Minify output", { default: true }).action(buildCommand);
1318
1829
  cli.command("preview", "Preview production build").option("-p, --port <port>", "Port to listen on").option("-h, --host <host>", "Host to bind to").option("--open", "Open browser on start").action(previewCommand);
@@ -1326,7 +1837,7 @@ function run() {
1326
1837
  }
1327
1838
  cli.runMatchedCommand();
1328
1839
  } catch (error) {
1329
- console.error(pc5.red("Error:"), error instanceof Error ? error.message : error);
1840
+ console.error(pc6.red("Error:"), error instanceof Error ? error.message : error);
1330
1841
  process.exit(1);
1331
1842
  }
1332
1843
  }