@flight-framework/cli 0.1.0 → 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/README.md CHANGED
@@ -123,6 +123,76 @@ flight create my-app --ui solid --features forms,auth,i18n
123
123
  | `--no-git` | Skip git initialization |
124
124
  | `--install` | Install dependencies (default: true) |
125
125
  | `--no-install` | Skip dependency installation |
126
+ | `--raw` | Create raw project (100% Web Standards, zero dependencies) |
127
+ | `--empty` | Create empty project (just package.json) |
128
+ | `--minimal` | Create minimal project (single server file) |
129
+
130
+ ### Toolbox Mode (Zero Lock-in)
131
+
132
+ Start with the minimum and add what you need:
133
+
134
+ ```bash
135
+ # Raw project - 100% Web Standards, ZERO dependencies
136
+ # Works on Bun, Deno, Node 22+, Cloudflare Workers
137
+ flight create my-app --raw
138
+
139
+ # Empty project - just package.json
140
+ flight create my-app --empty
141
+
142
+ # Minimal project - single server file with Flight
143
+ flight create my-app --minimal
144
+
145
+ # Then add packages as needed
146
+ cd my-app
147
+ flight add http
148
+ flight add db
149
+ flight add cache
150
+ ```
151
+
152
+ The `--raw` mode generates code with **zero Flight dependencies**. You can run it on any runtime and add Flight packages later if you want.
153
+
154
+ ---
155
+
156
+ ## Adding Packages
157
+
158
+ Add Flight packages to an existing project:
159
+
160
+ ```bash
161
+ flight add [package]
162
+ ```
163
+
164
+ ### Available Packages
165
+
166
+ | Package | Description |
167
+ |---------|-------------|
168
+ | `http` | HTTP server with routing and middleware |
169
+ | `core` | File-based routing and configuration |
170
+ | `db` | Database abstraction layer |
171
+ | `cache` | Caching with multiple adapters |
172
+ | `auth` | Authentication adapters |
173
+ | `forms` | Type-safe form handling |
174
+ | `i18n` | Internationalization |
175
+ | `seo` | SEO utilities |
176
+ | `image` | Image optimization |
177
+ | `email` | Email sending |
178
+ | `realtime` | WebSocket and real-time features |
179
+ | `helpers` | Optional helper utilities |
180
+
181
+ ### Examples
182
+
183
+ ```bash
184
+ # Add HTTP server
185
+ flight add http
186
+
187
+ # Add database support
188
+ flight add db
189
+
190
+ # Add authentication
191
+ flight add auth
192
+
193
+ # See all packages
194
+ flight add
195
+ ```
126
196
 
127
197
  ---
128
198
 
package/dist/bin.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",
@@ -221,6 +236,277 @@ function copyDirWithTemplates(srcDir, destDir, vars) {
221
236
  }
222
237
  }
223
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
+ }
224
510
 
225
511
  // src/commands/dev.ts
226
512
  import { resolve as resolve2, join as join2 } from "path";
@@ -1310,25 +1596,234 @@ async function typesGenerateCommand(options = {}) {
1310
1596
  }
1311
1597
  }
1312
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
+
1313
1807
  // src/index.ts
1314
1808
  var cli = cac("flight");
1315
1809
  var LOGO = `
1316
- ${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")}
1317
- ${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")}
1318
- ${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 ")}
1319
- ${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 ")}
1320
- ${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 ")}
1321
- ${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 ")}
1322
1816
 
1323
- ${pc5.dim("The Agnostic Full-Stack Framework")}
1324
- ${pc5.dim("Maximum Flexibility. Zero Lock-in.")}
1817
+ ${pc6.dim("The Agnostic Full-Stack Framework")}
1818
+ ${pc6.dim("Maximum Flexibility. Zero Lock-in.")}
1325
1819
  `;
1326
1820
  function printLogo() {
1327
1821
  console.log(LOGO);
1328
1822
  }
1329
1823
  cli.version(VERSION);
1330
1824
  cli.help();
1331
- 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 }).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);
1332
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);
1333
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);
1334
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);
@@ -1342,7 +1837,7 @@ function run() {
1342
1837
  }
1343
1838
  cli.runMatchedCommand();
1344
1839
  } catch (error) {
1345
- console.error(pc5.red("Error:"), error instanceof Error ? error.message : error);
1840
+ console.error(pc6.red("Error:"), error instanceof Error ? error.message : error);
1346
1841
  process.exit(1);
1347
1842
  }
1348
1843
  }