aerocoding 0.1.15 → 0.1.16

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
@@ -4,7 +4,7 @@
4
4
  import { Command } from "commander";
5
5
 
6
6
  // src/commands/login.ts
7
- import chalk4 from "chalk";
7
+ import chalk3 from "chalk";
8
8
 
9
9
  // src/auth/device-flow.ts
10
10
  import axios from "axios";
@@ -139,7 +139,6 @@ var DeviceFlow = class {
139
139
  // src/auth/token-manager.ts
140
140
  import { Entry } from "@napi-rs/keyring";
141
141
  import { createClient } from "@supabase/supabase-js";
142
- import chalk2 from "chalk";
143
142
  var SERVICE_NAME = "aerocoding-cli";
144
143
  var SUPABASE_URL = "https://peqpttkvdpjgmduzacwl.supabase.co";
145
144
  var SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBlcXB0dGt2ZHBqZ21kdXphY3dsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQyNjUxNzMsImV4cCI6MjA3OTg0MTE3M30.WAzqgZusGoOEHxidfHc1e4daBglG4DJG5LOXbqldWQA";
@@ -182,12 +181,10 @@ var TokenManager = class {
182
181
  return null;
183
182
  }
184
183
  if (this.isTokenExpired(accessToken)) {
185
- console.log(chalk2.yellow("\u23F1\uFE0F Token expired, refreshing..."));
186
184
  accessToken = await this.refreshTokens();
187
185
  }
188
186
  return accessToken;
189
- } catch (error) {
190
- console.error(chalk2.red("Failed to get access token:"), error);
187
+ } catch {
191
188
  return null;
192
189
  }
193
190
  }
@@ -208,12 +205,10 @@ var TokenManager = class {
208
205
  }
209
206
  setPassword(SERVICE_NAME, "access_token", data.session.access_token);
210
207
  setPassword(SERVICE_NAME, "refresh_token", data.session.refresh_token);
211
- console.log(chalk2.green("Token refreshed successfully"));
212
208
  return data.session.access_token;
213
- } catch (error) {
214
- console.error(chalk2.red("Token refresh failed. Please login again."));
209
+ } catch {
215
210
  await this.logout();
216
- throw error;
211
+ return null;
217
212
  }
218
213
  }
219
214
  /**
@@ -235,14 +230,9 @@ var TokenManager = class {
235
230
  * Save tokens and user metadata after successful login
236
231
  */
237
232
  async saveTokens(accessToken, refreshToken, user) {
238
- try {
239
- setPassword(SERVICE_NAME, "access_token", accessToken);
240
- setPassword(SERVICE_NAME, "refresh_token", refreshToken);
241
- setPassword(SERVICE_NAME, "user_metadata", JSON.stringify(user));
242
- } catch (error) {
243
- console.error(chalk2.red("Failed to save tokens:"), error);
244
- throw error;
245
- }
233
+ setPassword(SERVICE_NAME, "access_token", accessToken);
234
+ setPassword(SERVICE_NAME, "refresh_token", refreshToken);
235
+ setPassword(SERVICE_NAME, "user_metadata", JSON.stringify(user));
246
236
  }
247
237
  /**
248
238
  * Get stored user metadata
@@ -364,6 +354,43 @@ var ApiClient = class {
364
354
  const response = await this.client.post("/api/generate/estimate", payload);
365
355
  return response.data.data;
366
356
  }
357
+ // ============================================
358
+ // Template Registry API
359
+ // ============================================
360
+ /**
361
+ * Search templates with filters
362
+ */
363
+ async getTemplates(filter = {}) {
364
+ const params = new URLSearchParams();
365
+ if (filter.category) params.set("category", filter.category);
366
+ if (filter.language) params.set("language", filter.language);
367
+ if (filter.framework) params.set("framework", filter.framework);
368
+ if (filter.tier) params.set("tier", filter.tier);
369
+ if (filter.tags?.length) params.set("tags", filter.tags.join(","));
370
+ const response = await this.client.get(`/api/templates?${params.toString()}`);
371
+ return response.data;
372
+ }
373
+ /**
374
+ * Get full template by ID (includes layers and feature flags)
375
+ */
376
+ async getTemplate(id) {
377
+ const response = await this.client.get(`/api/templates/${id}?full=true`);
378
+ return response.data.template;
379
+ }
380
+ /**
381
+ * Get template combinations (backend + frontend pairs)
382
+ */
383
+ async getTemplateCombinations() {
384
+ const response = await this.client.get("/api/templates/combinations");
385
+ return response.data.combinations;
386
+ }
387
+ /**
388
+ * Get templates compatible with a given template
389
+ */
390
+ async getCompatibleTemplates(templateId) {
391
+ const response = await this.client.get(`/api/templates/${templateId}?compatible=true`);
392
+ return response.data.compatible || [];
393
+ }
367
394
  };
368
395
 
369
396
  // src/commands/_shared/create-api-client.ts
@@ -376,31 +403,31 @@ function createApiClientWithAutoLogout(accessToken, tokenManager) {
376
403
  }
377
404
 
378
405
  // src/commands/_shared/unauthorized.ts
379
- import chalk3 from "chalk";
406
+ import chalk2 from "chalk";
380
407
  async function handleUnauthorized(tokenManager) {
381
408
  await tokenManager.logout();
382
409
  console.error(
383
- chalk3.yellow(
410
+ chalk2.yellow(
384
411
  " Your session is invalid or expired. You have been logged out."
385
412
  )
386
413
  );
387
- console.error(chalk3.gray(" Run 'aerocoding login' to authenticate."));
414
+ console.error(chalk2.gray(" Run 'aerocoding login' to authenticate."));
388
415
  process.exit(1);
389
416
  }
390
417
 
391
418
  // src/commands/login.ts
392
419
  async function loginCommand() {
393
- console.log(chalk4.bold("\nAeroCoding CLI Login\n"));
420
+ console.log(chalk3.bold("\nAeroCoding CLI Login\n"));
394
421
  const tokenManager = new TokenManager();
395
422
  const existingToken = await tokenManager.getAccessToken();
396
423
  if (existingToken) {
397
424
  const metadata = await tokenManager.getUserMetadata();
398
425
  console.log(
399
- chalk4.yellow("Already logged in as:"),
400
- chalk4.white(metadata?.email || "unknown")
426
+ chalk3.yellow("Already logged in as:"),
427
+ chalk3.white(metadata?.email || "unknown")
401
428
  );
402
429
  console.log(
403
- chalk4.gray(
430
+ chalk3.gray(
404
431
  " Run 'aerocoding logout' to login with a different account\n"
405
432
  )
406
433
  );
@@ -430,13 +457,13 @@ async function loginCommand() {
430
457
  });
431
458
  console.log("");
432
459
  console.log(
433
- chalk4.green("Successfully logged in as:"),
434
- chalk4.white(user.email)
460
+ chalk3.green("Successfully logged in as:"),
461
+ chalk3.white(user.email)
435
462
  );
436
- console.log(chalk4.gray(" Run 'aerocoding whoami' to verify\n"));
463
+ console.log(chalk3.gray(" Run 'aerocoding whoami' to verify\n"));
437
464
  } catch (error) {
438
465
  console.error(
439
- chalk4.red("\nLogin failed:"),
466
+ chalk3.red("\nLogin failed:"),
440
467
  error.message || "Unknown error"
441
468
  );
442
469
  process.exit(1);
@@ -444,42 +471,42 @@ async function loginCommand() {
444
471
  }
445
472
 
446
473
  // src/commands/logout.ts
447
- import chalk5 from "chalk";
474
+ import chalk4 from "chalk";
448
475
  async function logoutCommand() {
449
476
  const tokenManager = new TokenManager();
450
477
  const metadata = await tokenManager.getUserMetadata();
451
478
  if (!metadata) {
452
- console.log(chalk5.yellow("Not logged in"));
479
+ console.log(chalk4.yellow("Not logged in"));
453
480
  return;
454
481
  }
455
482
  const email = metadata.email;
456
483
  await tokenManager.logout();
457
- console.log(chalk5.green("Logged out successfully"));
458
- console.log(chalk5.gray(` Cleared credentials for ${email}
484
+ console.log(chalk4.green("Logged out successfully"));
485
+ console.log(chalk4.gray(` Cleared credentials for ${email}
459
486
  `));
460
487
  }
461
488
 
462
489
  // src/commands/whoami.ts
463
- import chalk6 from "chalk";
490
+ import chalk5 from "chalk";
464
491
  async function whoamiCommand() {
465
492
  const tokenManager = new TokenManager();
466
493
  const token = await tokenManager.getAccessToken();
467
494
  if (!token) {
468
- console.log(chalk6.red("Not logged in"));
469
- console.log(chalk6.gray(" Run 'aerocoding login' to authenticate\n"));
495
+ console.log(chalk5.red("Not logged in"));
496
+ console.log(chalk5.gray(" Run 'aerocoding login' to authenticate\n"));
470
497
  return;
471
498
  }
472
499
  try {
473
500
  const apiClient = createApiClientWithAutoLogout(token, tokenManager);
474
501
  const user = await apiClient.getCurrentUser();
475
502
  console.log("");
476
- console.log(chalk6.white("Logged in as:"), chalk6.cyan.bold(user.email));
503
+ console.log(chalk5.white("Logged in as:"), chalk5.cyan.bold(user.email));
477
504
  if (user.name) {
478
- console.log(chalk6.gray(" Name:"), user.name);
505
+ console.log(chalk5.gray(" Name:"), user.name);
479
506
  }
480
507
  console.log("");
481
508
  } catch (error) {
482
- console.error(chalk6.red("Failed to get user info"));
509
+ console.error(chalk5.red("Failed to get user info"));
483
510
  if (error.response?.status === 401) {
484
511
  await handleUnauthorized(tokenManager);
485
512
  }
@@ -488,13 +515,13 @@ async function whoamiCommand() {
488
515
  }
489
516
 
490
517
  // src/commands/generate.ts
491
- import chalk9 from "chalk";
518
+ import chalk8 from "chalk";
492
519
  import ora2 from "ora";
493
520
 
494
521
  // src/utils/file-writer.ts
495
522
  import fs from "fs/promises";
496
523
  import path from "path";
497
- import chalk7 from "chalk";
524
+ import chalk6 from "chalk";
498
525
  function isPathSafe(outputDir, filePath) {
499
526
  const resolvedOutput = path.resolve(outputDir);
500
527
  const resolvedFile = path.resolve(outputDir, filePath);
@@ -504,10 +531,10 @@ async function writeGeneratedFiles(files, outputDir) {
504
531
  for (const file of files) {
505
532
  if (!isPathSafe(outputDir, file.path)) {
506
533
  console.error(
507
- chalk7.red(` Skipping unsafe path: ${file.path}`)
534
+ chalk6.red(` Skipping unsafe path: ${file.path}`)
508
535
  );
509
536
  console.error(
510
- chalk7.gray(` Path traversal detected - file path must be within output directory`)
537
+ chalk6.gray(` Path traversal detected - file path must be within output directory`)
511
538
  );
512
539
  continue;
513
540
  }
@@ -516,24 +543,24 @@ async function writeGeneratedFiles(files, outputDir) {
516
543
  try {
517
544
  await fs.mkdir(dir, { recursive: true });
518
545
  await fs.writeFile(fullPath, file.content, "utf-8");
519
- console.log(chalk7.gray(` ${file.path}`));
546
+ console.log(chalk6.gray(` ${file.path}`));
520
547
  } catch (error) {
521
- console.error(chalk7.red(` Failed to write ${file.path}`));
522
- console.error(chalk7.gray(` ${error.message}`));
548
+ console.error(chalk6.red(` Failed to write ${file.path}`));
549
+ console.error(chalk6.gray(` ${error.message}`));
523
550
  }
524
551
  }
525
552
  }
526
553
 
527
554
  // src/utils/prompt.ts
528
555
  import readline from "readline";
529
- import chalk8 from "chalk";
556
+ import chalk7 from "chalk";
530
557
  function promptConfirm(message) {
531
558
  return new Promise((resolve) => {
532
559
  const rl = readline.createInterface({
533
560
  input: process.stdin,
534
561
  output: process.stdout
535
562
  });
536
- rl.question(chalk8.yellow(`${message} [Y/n] `), (answer) => {
563
+ rl.question(chalk7.yellow(`${message} [Y/n] `), (answer) => {
537
564
  rl.close();
538
565
  const normalized = answer.trim().toLowerCase();
539
566
  resolve(normalized !== "n" && normalized !== "no");
@@ -645,16 +672,16 @@ async function generateCommand(options) {
645
672
  const tokenManager = new TokenManager();
646
673
  const token = await tokenManager.getAccessToken();
647
674
  if (!token) {
648
- console.log(chalk9.red("\n Not authenticated"));
649
- console.log(chalk9.gray(" Run 'aerocoding login' to get started\n"));
675
+ console.log(chalk8.red("\n Not authenticated"));
676
+ console.log(chalk8.gray(" Run 'aerocoding login' to get started\n"));
650
677
  process.exit(1);
651
678
  }
652
679
  const config = await loadConfig();
653
680
  const projectId = options.project || config?.project;
654
681
  if (!projectId) {
655
- console.log(chalk9.red("\n Project ID required"));
656
- console.log(chalk9.gray(" Run 'aerocoding init' to create a config file"));
657
- console.log(chalk9.gray(" Or use --project <id> to specify a project\n"));
682
+ console.log(chalk8.red("\n Project ID required"));
683
+ console.log(chalk8.gray(" Run 'aerocoding init' to create a config file"));
684
+ console.log(chalk8.gray(" Or use --project <id> to specify a project\n"));
658
685
  process.exit(1);
659
686
  }
660
687
  const targets = options.targets || buildTargetsFromConfig(config);
@@ -673,7 +700,7 @@ async function generateCommand(options) {
673
700
  let spinner2 = ora2({ text: "Fetching project...", color: "cyan" }).start();
674
701
  try {
675
702
  const project = await apiClient.getProject(projectId);
676
- spinner2.succeed(chalk9.gray(`Project: ${project.name}`));
703
+ spinner2.succeed(chalk8.gray(`Project: ${project.name}`));
677
704
  spinner2 = ora2({ text: "Checking credits...", color: "cyan" }).start();
678
705
  const credits = await apiClient.getCreditUsage(project.organizationId);
679
706
  let estimate = null;
@@ -691,29 +718,29 @@ async function generateCommand(options) {
691
718
  });
692
719
  } catch {
693
720
  }
694
- spinner2.succeed(chalk9.gray(`Credits: ${credits.remaining} / ${credits.limit} available`));
721
+ spinner2.succeed(chalk8.gray(`Credits: ${credits.remaining} / ${credits.limit} available`));
695
722
  if (estimate && estimate.entities === 0) {
696
- console.log(chalk9.yellow("\n \u26A0 No entities found in this project."));
697
- console.log(chalk9.gray(" Create entities in the diagram editor and save (Ctrl+S) before generating.\n"));
723
+ console.log(chalk8.yellow("\n \u26A0 No entities found in this project."));
724
+ console.log(chalk8.gray(" Create entities in the diagram editor and save (Ctrl+S) before generating.\n"));
698
725
  process.exit(1);
699
726
  }
700
727
  const hasEnoughCredits = estimate ? credits.remaining >= estimate.estimatedCredits : true;
701
728
  console.log("");
702
- console.log(chalk9.bold(" Generation Summary"));
703
- console.log(chalk9.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
704
- console.log(chalk9.gray(" Project:"), chalk9.white(project.name));
729
+ console.log(chalk8.bold(" Generation Summary"));
730
+ console.log(chalk8.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
731
+ console.log(chalk8.gray(" Project:"), chalk8.white(project.name));
705
732
  if (config) {
706
- console.log(chalk9.gray(" Config:"), chalk9.cyan(".aerocodingrc.json"));
733
+ console.log(chalk8.gray(" Config:"), chalk8.cyan(".aerocodingrc.json"));
707
734
  }
708
735
  console.log(
709
- chalk9.gray(" Targets:"),
710
- chalk9.cyan(targets.length > 0 ? targets.join(", ") : "default")
736
+ chalk8.gray(" Targets:"),
737
+ chalk8.cyan(targets.length > 0 ? targets.join(", ") : "default")
711
738
  );
712
739
  if (backendPreset) {
713
- console.log(chalk9.gray(" Backend Preset:"), chalk9.cyan(backendPreset));
740
+ console.log(chalk8.gray(" Backend Preset:"), chalk8.cyan(backendPreset));
714
741
  }
715
742
  if (frontendPreset) {
716
- console.log(chalk9.gray(" Frontend Preset:"), chalk9.cyan(frontendPreset));
743
+ console.log(chalk8.gray(" Frontend Preset:"), chalk8.cyan(frontendPreset));
717
744
  }
718
745
  const disabledOptions = [];
719
746
  if (!includeValidations) disabledOptions.push("validations");
@@ -722,40 +749,40 @@ async function generateCommand(options) {
722
749
  if (!includeLogging) disabledOptions.push("logging");
723
750
  if (!includeTesting) disabledOptions.push("testing");
724
751
  if (disabledOptions.length > 0) {
725
- console.log(chalk9.gray(" Disabled:"), chalk9.yellow(disabledOptions.join(", ")));
752
+ console.log(chalk8.gray(" Disabled:"), chalk8.yellow(disabledOptions.join(", ")));
726
753
  }
727
754
  if (validationLib) {
728
- console.log(chalk9.gray(" Validation Lib:"), chalk9.cyan(validationLib));
755
+ console.log(chalk8.gray(" Validation Lib:"), chalk8.cyan(validationLib));
729
756
  }
730
757
  if (estimate) {
731
- console.log(chalk9.gray(" Entities:"), chalk9.cyan(estimate.entities));
732
- console.log(chalk9.gray(" Files:"), chalk9.cyan(estimate.totalFiles));
758
+ console.log(chalk8.gray(" Entities:"), chalk8.cyan(estimate.entities));
759
+ console.log(chalk8.gray(" Files:"), chalk8.cyan(estimate.totalFiles));
733
760
  }
734
761
  console.log("");
735
- console.log(chalk9.bold(" Credits"));
736
- console.log(chalk9.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
762
+ console.log(chalk8.bold(" Credits"));
763
+ console.log(chalk8.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
737
764
  if (estimate) {
738
765
  console.log(
739
- chalk9.white(" Cost:"),
740
- hasEnoughCredits ? chalk9.bold.yellow(`${estimate.estimatedCredits} credits`) : chalk9.bold.red(`${estimate.estimatedCredits} credits`)
766
+ chalk8.white(" Cost:"),
767
+ hasEnoughCredits ? chalk8.bold.yellow(`${estimate.estimatedCredits} credits`) : chalk8.bold.red(`${estimate.estimatedCredits} credits`)
741
768
  );
742
769
  }
743
770
  console.log(
744
- chalk9.white(" Available:"),
745
- hasEnoughCredits ? chalk9.bold.green(`${credits.remaining} credits`) : chalk9.bold.red(`${credits.remaining} credits (insufficient)`)
771
+ chalk8.white(" Available:"),
772
+ hasEnoughCredits ? chalk8.bold.green(`${credits.remaining} credits`) : chalk8.bold.red(`${credits.remaining} credits (insufficient)`)
746
773
  );
747
- console.log(chalk9.gray(" Output:"), chalk9.cyan(output));
774
+ console.log(chalk8.gray(" Output:"), chalk8.cyan(output));
748
775
  console.log("");
749
776
  if (!hasEnoughCredits && estimate) {
750
- console.log(chalk9.red(" \u26A0 Not enough credits for this generation."));
751
- console.log(chalk9.gray(` Need ${estimate.estimatedCredits - credits.remaining} more credits.
777
+ console.log(chalk8.red(" \u26A0 Not enough credits for this generation."));
778
+ console.log(chalk8.gray(` Need ${estimate.estimatedCredits - credits.remaining} more credits.
752
779
  `));
753
780
  process.exit(1);
754
781
  }
755
782
  if (!options.yes) {
756
783
  const confirmed = await promptConfirm(" Proceed with generation?");
757
784
  if (!confirmed) {
758
- console.log(chalk9.yellow("\n Generation cancelled\n"));
785
+ console.log(chalk8.yellow("\n Generation cancelled\n"));
759
786
  process.exit(0);
760
787
  }
761
788
  }
@@ -778,66 +805,61 @@ async function generateCommand(options) {
778
805
  validationLib
779
806
  }
780
807
  });
781
- spinner2.succeed(chalk9.green("Code generated successfully!"));
808
+ spinner2.succeed(chalk8.green("Code generated successfully!"));
782
809
  console.log("");
783
- console.log(chalk9.bold(" Results"));
784
- console.log(chalk9.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
785
- console.log(chalk9.gray(" Files:"), chalk9.cyan(result.stats.totalFiles));
786
- console.log(chalk9.gray(" Entities:"), chalk9.cyan(result.stats.totalEntities));
810
+ console.log(chalk8.bold(" Results"));
811
+ console.log(chalk8.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
812
+ console.log(chalk8.gray(" Files:"), chalk8.cyan(result.stats.totalFiles));
813
+ console.log(chalk8.gray(" Entities:"), chalk8.cyan(result.stats.totalEntities));
787
814
  console.log(
788
- chalk9.gray(" Languages:"),
789
- chalk9.cyan(result.stats.languages.join(", "))
815
+ chalk8.gray(" Languages:"),
816
+ chalk8.cyan(result.stats.languages.join(", "))
790
817
  );
791
818
  if (result.creditsUsed !== void 0) {
792
819
  console.log("");
793
- console.log(chalk9.bold(" Credits"));
794
- console.log(chalk9.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
795
- console.log(chalk9.gray(" Used:"), chalk9.yellow(result.creditsUsed));
820
+ console.log(chalk8.bold(" Credits"));
821
+ console.log(chalk8.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
822
+ console.log(chalk8.gray(" Used:"), chalk8.yellow(result.creditsUsed));
796
823
  console.log(
797
- chalk9.gray(" Remaining:"),
798
- result.creditsRemaining !== void 0 && result.creditsRemaining > 50 ? chalk9.green(result.creditsRemaining) : chalk9.yellow(result.creditsRemaining)
824
+ chalk8.gray(" Remaining:"),
825
+ result.creditsRemaining !== void 0 && result.creditsRemaining > 50 ? chalk8.green(result.creditsRemaining) : chalk8.yellow(result.creditsRemaining)
799
826
  );
800
827
  }
801
828
  if (result.warnings && result.warnings.length > 0) {
802
829
  console.log("");
803
- console.log(chalk9.yellow(" Warnings:"));
830
+ console.log(chalk8.yellow(" Warnings:"));
804
831
  for (const warning of result.warnings) {
805
- console.log(chalk9.yellow(` - ${warning}`));
832
+ console.log(chalk8.yellow(` - ${warning}`));
806
833
  }
807
834
  }
808
835
  console.log("");
809
836
  await writeGeneratedFiles(result.files, output);
810
- console.log(chalk9.green(` Files written to ${chalk9.white(output)}`));
837
+ console.log(chalk8.green(` Files written to ${chalk8.white(output)}`));
811
838
  console.log("");
812
839
  } catch (error) {
813
- spinner2.fail(chalk9.red("Generation failed"));
814
- console.log(chalk9.gray(`
815
- Error: ${error.response?.status || error.code || "unknown"}`));
816
- if (error.response?.data) {
817
- console.log(chalk9.gray(` Details: ${JSON.stringify(error.response.data)}`));
818
- }
840
+ spinner2.fail(chalk8.red("Generation failed"));
819
841
  if (error.response?.status === 401) {
820
842
  await handleUnauthorized(tokenManager);
821
843
  } else if (error.response?.status === 403) {
822
- console.log(chalk9.yellow("\n You don't have permission to access this project."));
823
- console.log(chalk9.gray(" Check if you're part of the organization.\n"));
844
+ console.log(chalk8.yellow("\n You don't have permission to access this project."));
845
+ console.log(chalk8.gray(" Check if you're part of the organization.\n"));
824
846
  } else if (error.response?.status === 404) {
825
- console.log(chalk9.yellow("\n Project not found."));
826
- console.log(chalk9.gray(" Check if the project ID is correct.\n"));
847
+ console.log(chalk8.yellow("\n Project not found."));
848
+ console.log(chalk8.gray(" Check if the project ID is correct.\n"));
827
849
  } else if (error.response?.status === 429) {
828
850
  const data = error.response.data;
829
- console.log(chalk9.red("\n Insufficient credits"));
851
+ console.log(chalk8.red("\n Insufficient credits"));
830
852
  if (data.requiredCredits) {
831
- console.log(chalk9.yellow(` Required: ${data.requiredCredits} credits`));
853
+ console.log(chalk8.yellow(` Required: ${data.requiredCredits} credits`));
832
854
  }
833
- console.log(chalk9.yellow(` Available: ${data.remaining ?? 0} credits`));
834
- console.log(chalk9.gray("\n Upgrade your plan or wait for credit reset.\n"));
855
+ console.log(chalk8.yellow(` Available: ${data.remaining ?? 0} credits`));
856
+ console.log(chalk8.gray("\n Upgrade your plan or wait for credit reset.\n"));
835
857
  } else if (error.response?.data?.message) {
836
- console.log(chalk9.red(`
858
+ console.log(chalk8.red(`
837
859
  ${error.response.data.message}
838
860
  `));
839
861
  } else {
840
- console.log(chalk9.red(`
862
+ console.log(chalk8.red(`
841
863
  ${error.message}
842
864
  `));
843
865
  }
@@ -847,9 +869,9 @@ async function generateCommand(options) {
847
869
 
848
870
  // src/commands/init.ts
849
871
  import * as p from "@clack/prompts";
850
- import chalk10 from "chalk";
872
+ import chalk9 from "chalk";
851
873
  async function initCommand(options) {
852
- p.intro(chalk10.bgCyan.black(" AeroCoding CLI "));
874
+ p.intro(chalk9.bgCyan.black(" AeroCoding CLI "));
853
875
  if (!options.force && await configExists()) {
854
876
  const overwrite = await p.confirm({
855
877
  message: "Config file already exists. Overwrite?",
@@ -963,32 +985,35 @@ async function initCommand(options) {
963
985
  };
964
986
  if (selectedTargets.includes("backend") && project.backendFramework) {
965
987
  const archSpinner = p.spinner();
966
- archSpinner.start("Loading backend architectures...");
967
- const architectures = await apiClient.getArchitectures(project.backendFramework);
968
- archSpinner.stop("Architectures loaded");
969
- if (architectures.length > 0) {
988
+ archSpinner.start("Loading backend templates...");
989
+ const templateResult = await apiClient.getTemplates({
990
+ category: "backend",
991
+ language: project.backendFramework
992
+ });
993
+ archSpinner.stop("Templates loaded");
994
+ if (templateResult.templates.length > 0) {
970
995
  const preset = await p.select({
971
- message: "Backend architecture",
972
- options: architectures.map((arch) => ({
973
- value: arch.id,
974
- label: arch.name,
975
- hint: arch.description
996
+ message: "Backend template",
997
+ options: templateResult.templates.map((tmpl) => ({
998
+ value: tmpl.id,
999
+ label: tmpl.name,
1000
+ hint: tmpl.description || `${tmpl.tier} tier`
976
1001
  }))
977
1002
  });
978
1003
  if (p.isCancel(preset)) {
979
1004
  p.cancel("Operation cancelled.");
980
1005
  process.exit(0);
981
1006
  }
982
- const selectedArch = architectures.find((a) => a.id === preset);
983
- if (selectedArch && selectedArch.layers.length > 0) {
1007
+ const fullTemplate = await apiClient.getTemplate(preset);
1008
+ if (fullTemplate.layers && fullTemplate.layers.length > 0) {
984
1009
  const layers = await p.multiselect({
985
1010
  message: "Select backend layers to include",
986
- options: selectedArch.layers.map((layer) => ({
1011
+ options: fullTemplate.layers.map((layer) => ({
987
1012
  value: layer.id,
988
1013
  label: layer.name,
989
1014
  hint: layer.category
990
1015
  })),
991
- initialValues: selectedArch.layers.map((l) => l.id)
1016
+ initialValues: fullTemplate.layers.filter((l) => l.enabled).map((l) => l.id)
992
1017
  });
993
1018
  if (p.isCancel(layers)) {
994
1019
  p.cancel("Operation cancelled.");
@@ -1008,32 +1033,35 @@ async function initCommand(options) {
1008
1033
  }
1009
1034
  if (selectedTargets.includes("frontend") && project.frontendFramework) {
1010
1035
  const archSpinner = p.spinner();
1011
- archSpinner.start("Loading frontend architectures...");
1012
- const architectures = await apiClient.getArchitectures(project.frontendFramework);
1013
- archSpinner.stop("Architectures loaded");
1014
- if (architectures.length > 0) {
1036
+ archSpinner.start("Loading frontend templates...");
1037
+ const templateResult = await apiClient.getTemplates({
1038
+ category: "frontend",
1039
+ framework: project.frontendFramework
1040
+ });
1041
+ archSpinner.stop("Templates loaded");
1042
+ if (templateResult.templates.length > 0) {
1015
1043
  const preset = await p.select({
1016
- message: "Frontend architecture",
1017
- options: architectures.map((arch) => ({
1018
- value: arch.id,
1019
- label: arch.name,
1020
- hint: arch.description
1044
+ message: "Frontend template",
1045
+ options: templateResult.templates.map((tmpl) => ({
1046
+ value: tmpl.id,
1047
+ label: tmpl.name,
1048
+ hint: tmpl.description || `${tmpl.tier} tier`
1021
1049
  }))
1022
1050
  });
1023
1051
  if (p.isCancel(preset)) {
1024
1052
  p.cancel("Operation cancelled.");
1025
1053
  process.exit(0);
1026
1054
  }
1027
- const selectedArch = architectures.find((a) => a.id === preset);
1028
- if (selectedArch && selectedArch.layers.length > 0) {
1055
+ const fullTemplate = await apiClient.getTemplate(preset);
1056
+ if (fullTemplate.layers && fullTemplate.layers.length > 0) {
1029
1057
  const layers = await p.multiselect({
1030
1058
  message: "Select frontend layers to include",
1031
- options: selectedArch.layers.map((layer) => ({
1059
+ options: fullTemplate.layers.map((layer) => ({
1032
1060
  value: layer.id,
1033
1061
  label: layer.name,
1034
1062
  hint: layer.category
1035
1063
  })),
1036
- initialValues: selectedArch.layers.map((l) => l.id)
1064
+ initialValues: fullTemplate.layers.filter((l) => l.enabled).map((l) => l.id)
1037
1065
  });
1038
1066
  if (p.isCancel(layers)) {
1039
1067
  p.cancel("Operation cancelled.");
@@ -1089,7 +1117,7 @@ async function initCommand(options) {
1089
1117
  config.output = output;
1090
1118
  await saveConfig(config);
1091
1119
  p.outro(
1092
- chalk10.green("Config saved to .aerocodingrc.json") + "\n\n" + chalk10.gray(" Run ") + chalk10.cyan("aerocoding generate") + chalk10.gray(" to generate code!")
1120
+ chalk9.green("Config saved to .aerocodingrc.json") + "\n\n" + chalk9.gray(" Run ") + chalk9.cyan("aerocoding generate") + chalk9.gray(" to generate code!")
1093
1121
  );
1094
1122
  } catch (error) {
1095
1123
  if (error.response?.status === 401) {
@@ -1104,20 +1132,20 @@ async function initCommand(options) {
1104
1132
  }
1105
1133
 
1106
1134
  // src/commands/pull.ts
1107
- import chalk11 from "chalk";
1135
+ import chalk10 from "chalk";
1108
1136
  async function pullCommand(options) {
1109
- console.log(chalk11.yellow("Command not yet implemented"));
1137
+ console.log(chalk10.yellow("Command not yet implemented"));
1110
1138
  if (options.project) {
1111
- console.log(chalk11.gray(` Requested project: ${options.project}`));
1139
+ console.log(chalk10.gray(` Requested project: ${options.project}`));
1112
1140
  }
1113
- console.log(chalk11.gray(" Coming soon in v0.2.0\n"));
1141
+ console.log(chalk10.gray(" Coming soon in v0.2.0\n"));
1114
1142
  }
1115
1143
 
1116
1144
  // src/commands/status.ts
1117
- import chalk12 from "chalk";
1145
+ import chalk11 from "chalk";
1118
1146
  async function statusCommand() {
1119
- console.log(chalk12.yellow("Command not yet implemented"));
1120
- console.log(chalk12.gray(" Coming soon in v0.2.0\n"));
1147
+ console.log(chalk11.yellow("Command not yet implemented"));
1148
+ console.log(chalk11.gray(" Coming soon in v0.2.0\n"));
1121
1149
  }
1122
1150
 
1123
1151
  // src/index.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/login.ts","../src/auth/device-flow.ts","../src/auth/token-manager.ts","../src/api/client.ts","../src/commands/_shared/create-api-client.ts","../src/commands/_shared/unauthorized.ts","../src/commands/logout.ts","../src/commands/whoami.ts","../src/commands/generate.ts","../src/utils/file-writer.ts","../src/utils/prompt.ts","../src/config/loader.ts","../src/config/schema.ts","../src/commands/init.ts","../src/commands/pull.ts","../src/commands/status.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Command } from \"commander\";\r\nimport { loginCommand } from \"./commands/login.js\";\r\nimport { logoutCommand } from \"./commands/logout.js\";\r\nimport { whoamiCommand } from \"./commands/whoami.js\";\r\nimport { generateCommand } from \"./commands/generate.js\";\r\nimport { initCommand } from \"./commands/init.js\";\r\nimport { pullCommand } from \"./commands/pull.js\";\r\nimport { statusCommand } from \"./commands/status.js\";\r\nimport \"dotenv/config\";\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name(\"aerocoding\")\r\n .description(\"AeroCoding CLI - Generate production-ready code from UML diagrams\")\r\n .version(\"0.1.15\");\r\n\r\n// ============================================\r\n// Authentication Commands\r\n// ============================================\r\n\r\nprogram\r\n .command(\"login\")\r\n .description(\"Authenticate with AeroCoding\")\r\n .action(loginCommand);\r\n\r\nprogram\r\n .command(\"logout\")\r\n .description(\"Logout and clear stored credentials\")\r\n .action(logoutCommand);\r\n\r\nprogram\r\n .command(\"whoami\")\r\n .description(\"Show current authenticated user\")\r\n .action(whoamiCommand);\r\n\r\n// ============================================\r\n// Project Commands\r\n// ============================================\r\n\r\nprogram\r\n .command(\"init\")\r\n .description(\"Initialize AeroCoding in current directory\")\r\n .option(\"-p, --project <id>\", \"Project ID (skip selection)\")\r\n .option(\"-f, --force\", \"Overwrite existing config without asking\")\r\n .action(initCommand);\r\n\r\nprogram\r\n .command(\"pull\")\r\n .description(\"Pull schema from cloud\")\r\n .option(\"-p, --project <id>\", \"Project ID\")\r\n .action(pullCommand);\r\n\r\nprogram\r\n .command(\"status\")\r\n .description(\"Show local schema status\")\r\n .action(statusCommand);\r\n\r\n// ============================================\r\n// Generation Commands\r\n// ============================================\r\n\r\nprogram\r\n .command(\"generate\")\r\n .alias(\"gen\")\r\n .description(\"Generate code from schema\")\r\n // Identification\r\n .option(\"-p, --project <id>\", \"Project ID\")\r\n .option(\"-t, --targets <targets...>\", \"Generation targets (e.g., dotnet-entity)\")\r\n .option(\"-e, --entities <entities...>\", \"Filter by entity names\")\r\n .option(\"-o, --output <dir>\", \"Output directory\", \"./.aerocoding\")\r\n // Presets & Layers\r\n .option(\"--backend-preset <preset>\", \"Backend architecture preset\")\r\n .option(\"--frontend-preset <preset>\", \"Frontend architecture preset\")\r\n .option(\"--backend-layers <layers...>\", \"Backend layers to generate\")\r\n .option(\"--frontend-layers <layers...>\", \"Frontend layers to generate\")\r\n // Code style toggles (optimistic defaults - all enabled by default)\r\n .option(\"--no-validations\", \"Exclude validations\")\r\n .option(\"--no-comments\", \"Exclude comments\")\r\n .option(\"--no-annotations\", \"Exclude annotations\")\r\n .option(\"--no-logging\", \"Exclude logging statements\")\r\n .option(\"--no-testing\", \"Exclude test files\")\r\n // Validation library (framework-agnostic)\r\n .option(\"--validation-lib <framework>\", \"Validation library (e.g., fluentvalidation, zod, formz)\")\r\n // Control\r\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\r\n .action(generateCommand);\r\n\r\n// ============================================\r\n// Parse and Execute\r\n// ============================================\r\n\r\nprogram.parse();\r\n","import chalk from \"chalk\";\r\nimport { DeviceFlow } from \"../auth/device-flow.js\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\nimport { createApiClientWithAutoLogout } from \"./_shared/create-api-client.js\";\r\nimport { handleUnauthorized } from \"./_shared/unauthorized.js\";\r\n\r\n/**\r\n * Login Command\r\n *\r\n * Authenticates user via OAuth Device Flow\r\n * Stores tokens securely in OS credential manager\r\n */\r\nexport async function loginCommand() {\r\n console.log(chalk.bold(\"\\nAeroCoding CLI Login\\n\"));\r\n\r\n const tokenManager = new TokenManager();\r\n\r\n // Check if already logged in\r\n const existingToken = await tokenManager.getAccessToken();\r\n if (existingToken) {\r\n const metadata = await tokenManager.getUserMetadata();\r\n console.log(\r\n chalk.yellow(\"Already logged in as:\"),\r\n chalk.white(metadata?.email || \"unknown\")\r\n );\r\n console.log(\r\n chalk.gray(\r\n \" Run 'aerocoding logout' to login with a different account\\n\"\r\n )\r\n );\r\n return;\r\n }\r\n\r\n try {\r\n // Initiate device flow\r\n const deviceFlow = new DeviceFlow();\r\n const tokens = await deviceFlow.initiateAuth();\r\n\r\n // Get user info\r\n const apiClient = createApiClientWithAutoLogout(\r\n tokens.access_token,\r\n tokenManager\r\n );\r\n let user;\r\n try {\r\n user = await apiClient.getCurrentUser();\r\n } catch (error: any) {\r\n if (error.response?.status === 401) {\r\n await handleUnauthorized(tokenManager);\r\n }\r\n throw error;\r\n }\r\n\r\n // Save tokens\r\n await tokenManager.saveTokens(tokens.access_token, tokens.refresh_token, {\r\n id: user.id,\r\n email: user.email,\r\n name: user.name || undefined,\r\n tier: user.tier,\r\n });\r\n\r\n console.log(\"\");\r\n console.log(\r\n chalk.green(\"Successfully logged in as:\"),\r\n chalk.white(user.email)\r\n );\r\n console.log(chalk.gray(\" Run 'aerocoding whoami' to verify\\n\"));\r\n } catch (error: any) {\r\n console.error(\r\n chalk.red(\"\\nLogin failed:\"),\r\n error.message || \"Unknown error\"\r\n );\r\n process.exit(1);\r\n }\r\n}\r\n","import axios from \"axios\";\r\nimport chalk from \"chalk\";\r\nimport ora from \"ora\";\r\nimport open from \"open\";\r\n\r\nconst API_URL = process.env.API_URL || \"https://aerocoding.dev\";\r\nconst MAX_POLL_TIME = 15 * 60 * 1000; // 15 minutes\r\n\r\ninterface DeviceAuthResponse {\r\n device_code: string;\r\n user_code: string;\r\n confirmation_code: string;\r\n verification_uri: string;\r\n verification_uri_complete: string;\r\n expires_in: number;\r\n interval: number;\r\n}\r\n\r\ninterface TokenResponse {\r\n access_token: string;\r\n refresh_token: string;\r\n token_type: string;\r\n expires_in: number;\r\n}\r\n\r\n/**\r\n * DeviceFlow\r\n *\r\n * Implements OAuth 2.0 Device Authorization Grant (RFC 8628)\r\n * Used for CLI authentication without browser-based redirects\r\n */\r\nexport class DeviceFlow {\r\n /**\r\n * Initiate the complete device authorization flow\r\n */\r\n async initiateAuth(): Promise<TokenResponse> {\r\n // Step 1: Request device code\r\n const deviceAuth = await this.requestDeviceCode();\r\n\r\n // Step 2: Display user code and open browser\r\n this.displayUserCode(deviceAuth);\r\n await this.openBrowser(deviceAuth.verification_uri);\r\n\r\n // Step 3: Poll for authorization\r\n const tokens = await this.pollForToken(deviceAuth);\r\n\r\n return tokens;\r\n }\r\n\r\n /**\r\n * Step 1: Request device code from server\r\n */\r\n private async requestDeviceCode(): Promise<DeviceAuthResponse> {\r\n try {\r\n const response = await axios.post(`${API_URL}/api/device/authorize`, {\r\n client_id: \"aerocoding-cli\",\r\n scope: \"generate:code projects:read\",\r\n });\r\n\r\n return response.data;\r\n } catch (error: any) {\r\n console.error(chalk.red(\"Failed to initiate device authorization\"));\r\n if (error.response) {\r\n console.error(\r\n chalk.red(`Error: ${error.response.data.error_description}`)\r\n );\r\n }\r\n throw new Error(\"Failed to initiate device authorization\");\r\n }\r\n }\r\n\r\n /**\r\n * Step 2: Display user code and instructions\r\n */\r\n private displayUserCode(auth: DeviceAuthResponse): void {\r\n console.log(\"\\n\");\r\n console.log(chalk.cyan(\"━\".repeat(60)));\r\n console.log(chalk.bold.white(\" AeroCoding CLI - Device Activation\"));\r\n console.log(chalk.cyan(\"━\".repeat(60)));\r\n console.log(\"\");\r\n console.log(chalk.white(\" 1. Open this URL in your browser:\"));\r\n console.log(chalk.cyan.bold(` ${auth.verification_uri}`));\r\n console.log(\"\");\r\n console.log(chalk.white(\" 2. Enter this code:\"));\r\n console.log(chalk.green.bold(` ${auth.user_code}`));\r\n console.log(\"\");\r\n console.log(\r\n chalk.gray(` Code expires in ${auth.expires_in / 60} minutes`)\r\n );\r\n console.log(chalk.cyan(\"━\".repeat(60)));\r\n console.log(\"\");\r\n }\r\n\r\n /**\r\n * Step 2.5: Open browser automatically\r\n */\r\n private async openBrowser(url: string): Promise<void> {\r\n try {\r\n await open(url);\r\n console.log(chalk.gray(\" Opening browser...\"));\r\n } catch {\r\n console.log(chalk.yellow(\" Could not open browser automatically\"));\r\n console.log(chalk.gray(\" Please open the URL manually\\n\"));\r\n }\r\n }\r\n\r\n /**\r\n * Step 3: Poll for token\r\n */\r\n private async pollForToken(auth: DeviceAuthResponse): Promise<TokenResponse> {\r\n const spinner = ora({\r\n text: \"Waiting for authorization...\",\r\n color: \"cyan\",\r\n }).start();\r\n\r\n const startTime = Date.now();\r\n let currentInterval = auth.interval * 1000;\r\n\r\n while (true) {\r\n // Check timeout\r\n if (Date.now() - startTime > MAX_POLL_TIME) {\r\n spinner.fail(chalk.red(\"Authorization timeout\"));\r\n throw new Error(\"Device authorization timed out\");\r\n }\r\n\r\n try {\r\n const response = await axios.post(`${API_URL}/api/device/token`, {\r\n device_code: auth.device_code,\r\n client_id: \"aerocoding-cli\",\r\n });\r\n\r\n spinner.succeed(chalk.green(\"Successfully authenticated!\"));\r\n return response.data;\r\n } catch (error: any) {\r\n const errorCode = error.response?.data?.error;\r\n const errorDescription = error.response?.data?.error_description;\r\n\r\n if (errorCode === \"authorization_pending\") {\r\n // Keep polling\r\n await this.sleep(currentInterval);\r\n continue;\r\n }\r\n\r\n if (errorCode === \"slow_down\") {\r\n // Increase poll interval by 5 seconds\r\n currentInterval += 5000;\r\n spinner.text = \"Polling... (slowed down to avoid spam)\";\r\n await this.sleep(currentInterval);\r\n continue;\r\n }\r\n\r\n if (errorCode === \"expired_token\") {\r\n spinner.fail(chalk.red(\"Authorization code expired\"));\r\n throw new Error(\"Device code expired. Please try again.\");\r\n }\r\n\r\n if (errorCode === \"access_denied\") {\r\n spinner.fail(chalk.red(\"Authorization denied\"));\r\n throw new Error(\"You denied the authorization request\");\r\n }\r\n\r\n // Unknown error\r\n spinner.fail(chalk.red(\"Authorization failed\"));\r\n console.error(\r\n chalk.red(`Error: ${errorDescription || \"Unknown error\"}`)\r\n );\r\n throw new Error(errorDescription || \"Unknown error\");\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Helper: Sleep for specified milliseconds\r\n */\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n }\r\n}\r\n","import { Entry } from \"@napi-rs/keyring\";\r\nimport { createClient, SupabaseClient } from \"@supabase/supabase-js\";\r\nimport chalk from \"chalk\";\r\n\r\nconst SERVICE_NAME = \"aerocoding-cli\";\r\n\r\n// Public Supabase credentials (anon key is safe to expose)\r\nconst SUPABASE_URL = \"https://peqpttkvdpjgmduzacwl.supabase.co\";\r\nconst SUPABASE_ANON_KEY = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBlcXB0dGt2ZHBqZ21kdXphY3dsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQyNjUxNzMsImV4cCI6MjA3OTg0MTE3M30.WAzqgZusGoOEHxidfHc1e4daBglG4DJG5LOXbqldWQA\";\r\n\r\ninterface UserMetadata {\r\n id: string;\r\n email: string;\r\n name?: string;\r\n tier?: string;\r\n}\r\n\r\n/**\r\n * Helper functions for keyring operations using Entry class\r\n */\r\nfunction getPassword(service: string, account: string): string | null {\r\n try {\r\n const entry = new Entry(service, account);\r\n return entry.getPassword();\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction setPassword(service: string, account: string, password: string): void {\r\n const entry = new Entry(service, account);\r\n entry.setPassword(password);\r\n}\r\n\r\nfunction deletePassword(service: string, account: string): void {\r\n try {\r\n const entry = new Entry(service, account);\r\n entry.deletePassword();\r\n } catch {\r\n // Ignore if entry doesn't exist\r\n }\r\n}\r\n\r\n/**\r\n * TokenManager\r\n *\r\n * Manages secure storage and automatic refresh of authentication tokens\r\n * Uses OS-level credential managers (Keychain/Credential Manager/Secret Service)\r\n */\r\nexport class TokenManager {\r\n private supabase: SupabaseClient;\r\n\r\n constructor() {\r\n this.supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {\r\n auth: {\r\n autoRefreshToken: false,\r\n persistSession: false,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Get access token, automatically refreshing if expired\r\n */\r\n async getAccessToken(): Promise<string | null> {\r\n try {\r\n let accessToken = getPassword(SERVICE_NAME, \"access_token\");\r\n\r\n if (!accessToken) {\r\n return null;\r\n }\r\n\r\n // Check if expired\r\n if (this.isTokenExpired(accessToken)) {\r\n console.log(chalk.yellow(\"⏱️ Token expired, refreshing...\"));\r\n accessToken = await this.refreshTokens();\r\n }\r\n\r\n return accessToken;\r\n } catch (error) {\r\n console.error(chalk.red(\"Failed to get access token:\"), error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Refresh tokens using stored refresh token\r\n */\r\n private async refreshTokens(): Promise<string | null> {\r\n try {\r\n const refreshToken = getPassword(SERVICE_NAME, \"refresh_token\");\r\n\r\n if (!refreshToken) {\r\n throw new Error(\"No refresh token available\");\r\n }\r\n\r\n const { data, error } = await this.supabase.auth.refreshSession({\r\n refresh_token: refreshToken,\r\n });\r\n\r\n if (error || !data.session) {\r\n throw new Error(\"Failed to refresh session\");\r\n }\r\n\r\n // Store new tokens (single-use refresh token rotation)\r\n setPassword(SERVICE_NAME, \"access_token\", data.session.access_token);\r\n setPassword(SERVICE_NAME, \"refresh_token\", data.session.refresh_token);\r\n\r\n console.log(chalk.green(\"Token refreshed successfully\"));\r\n\r\n return data.session.access_token;\r\n } catch (error) {\r\n console.error(chalk.red(\"Token refresh failed. Please login again.\"));\r\n await this.logout();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Check if JWT token is expired (or expires in < 5 min)\r\n */\r\n private isTokenExpired(token: string): boolean {\r\n try {\r\n const payload = JSON.parse(\r\n Buffer.from(token.split(\".\")[1]!, \"base64\").toString()\r\n );\r\n const expiresAt = payload.exp * 1000;\r\n const now = Date.now();\r\n\r\n // Refresh 5 minutes before expiration\r\n return expiresAt - now < 5 * 60 * 1000;\r\n } catch {\r\n return true; // Treat invalid tokens as expired\r\n }\r\n }\r\n\r\n /**\r\n * Save tokens and user metadata after successful login\r\n */\r\n async saveTokens(\r\n accessToken: string,\r\n refreshToken: string,\r\n user: UserMetadata\r\n ): Promise<void> {\r\n try {\r\n setPassword(SERVICE_NAME, \"access_token\", accessToken);\r\n setPassword(SERVICE_NAME, \"refresh_token\", refreshToken);\r\n setPassword(SERVICE_NAME, \"user_metadata\", JSON.stringify(user));\r\n } catch (error) {\r\n console.error(chalk.red(\"Failed to save tokens:\"), error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get stored user metadata\r\n */\r\n async getUserMetadata(): Promise<UserMetadata | null> {\r\n try {\r\n const metadata = getPassword(SERVICE_NAME, \"user_metadata\");\r\n return metadata ? JSON.parse(metadata) : null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Logout - clear all stored credentials\r\n */\r\n async logout(): Promise<void> {\r\n try {\r\n deletePassword(SERVICE_NAME, \"access_token\");\r\n deletePassword(SERVICE_NAME, \"refresh_token\");\r\n deletePassword(SERVICE_NAME, \"user_metadata\");\r\n } catch (error) {\r\n // Ignore errors during logout\r\n }\r\n }\r\n\r\n /**\r\n * Check if user is currently authenticated\r\n */\r\n async isAuthenticated(): Promise<boolean> {\r\n const token = await this.getAccessToken();\r\n return token !== null;\r\n }\r\n}\r\n","import axios, { AxiosInstance } from \"axios\";\r\n\r\n// Production API URL (can be overridden via API_URL env for local dev)\r\nconst API_URL = process.env.API_URL || \"https://aerocoding.dev\";\r\n\r\ninterface User {\r\n id: string;\r\n email: string;\r\n name: string | null;\r\n tier: string;\r\n}\r\n\r\ninterface Organization {\r\n id: string;\r\n name: string;\r\n slug: string;\r\n planTier: string;\r\n}\r\n\r\ninterface Project {\r\n id: string;\r\n name: string;\r\n slug: string;\r\n schema: any;\r\n organizationId: string;\r\n backendFramework?: string;\r\n frontendFramework?: string;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\ninterface GeneratePayload {\r\n projectId: string;\r\n targets: string[];\r\n options?: {\r\n includeValidations?: boolean;\r\n includeComments?: boolean;\r\n includeAnnotations?: boolean;\r\n includeLogging?: boolean;\r\n includeTesting?: boolean;\r\n outputDir?: string;\r\n backendPreset?: string;\r\n frontendPreset?: string;\r\n backendLayers?: string[];\r\n frontendLayers?: string[];\r\n validationLib?: string;\r\n };\r\n}\r\n\r\ninterface GeneratedFile {\r\n path: string;\r\n content: string;\r\n language: string;\r\n entityId?: string;\r\n}\r\n\r\ninterface GenerateResult {\r\n files: GeneratedFile[];\r\n stats: {\r\n totalFiles: number;\r\n totalEntities: number;\r\n languages: string[];\r\n };\r\n cliCommand?: string;\r\n warnings?: string[];\r\n creditsUsed?: number;\r\n creditsRemaining?: number;\r\n}\r\n\r\ninterface CreditUsage {\r\n used: number;\r\n limit: number;\r\n bonusCredits: number;\r\n remaining: number;\r\n}\r\n\r\ninterface ArchitectureLayer {\r\n id: string;\r\n name: string;\r\n category: string;\r\n description?: string;\r\n}\r\n\r\ninterface Architecture {\r\n id: string;\r\n name: string;\r\n description: string;\r\n layers: ArchitectureLayer[];\r\n}\r\n\r\ninterface CreditEstimate {\r\n estimatedCredits: number;\r\n totalFiles: number;\r\n files: string[];\r\n entities: number;\r\n}\r\n\r\ninterface EstimatePayload {\r\n projectId: string;\r\n targets: string[];\r\n options?: {\r\n outputDir?: string;\r\n backendPreset?: string;\r\n frontendPreset?: string;\r\n backendLayers?: string[];\r\n frontendLayers?: string[];\r\n };\r\n}\r\n\r\n/**\r\n * ApiClient\r\n *\r\n * Authenticated HTTP client for AeroCoding API\r\n * All requests include Bearer token authentication\r\n */\r\nexport class ApiClient {\r\n private client: AxiosInstance;\r\n\r\n constructor(\r\n accessToken: string,\r\n options?: {\r\n onUnauthorized?: () => Promise<void> | void;\r\n }\r\n ) {\r\n this.client = axios.create({\r\n baseURL: API_URL,\r\n headers: {\r\n Authorization: `Bearer ${accessToken}`,\r\n \"Content-Type\": \"application/json\",\r\n \"X-Requested-With\": \"XMLHttpRequest\", // Required for CSRF validation bypass\r\n },\r\n timeout: 30000, // 30 seconds\r\n });\r\n\r\n this.client.interceptors.response.use(\r\n (response) => response,\r\n async (error) => {\r\n if (error?.response?.status === 401) {\r\n await options?.onUnauthorized?.();\r\n }\r\n\r\n return Promise.reject(error);\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Get current authenticated user\r\n */\r\n async getCurrentUser(): Promise<User> {\r\n const response = await this.client.get(\"/api/user/me\");\r\n return response.data;\r\n }\r\n\r\n /**\r\n * List user's organizations\r\n */\r\n async listOrganizations(): Promise<Organization[]> {\r\n const response = await this.client.get(\"/api/organizations\");\r\n return response.data;\r\n }\r\n\r\n /**\r\n * List user's projects\r\n */\r\n async listProjects(organizationId?: string): Promise<Project[]> {\r\n const response = await this.client.get(\"/api/projects\", {\r\n params: { organizationId },\r\n });\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Get project by ID\r\n */\r\n async getProject(projectId: string): Promise<Project> {\r\n const response = await this.client.get(`/api/projects/${projectId}`);\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Generate code from project schema\r\n */\r\n async generateCode(payload: GeneratePayload): Promise<GenerateResult> {\r\n const response = await this.client.post(\"/api/generate\", payload);\r\n return response.data.data;\r\n }\r\n\r\n /**\r\n * Get credit usage for organization\r\n */\r\n async getCreditUsage(organizationId: string): Promise<CreditUsage> {\r\n const response = await this.client.get(\"/api/credits/usage\", {\r\n params: { organizationId },\r\n });\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Get available architectures for a framework\r\n */\r\n async getArchitectures(framework: string): Promise<Architecture[]> {\r\n const response = await this.client.get(\"/api/architectures\", {\r\n params: { framework },\r\n });\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Estimate credit cost for a generation request\r\n */\r\n async estimateCreditCost(payload: EstimatePayload): Promise<CreditEstimate> {\r\n const response = await this.client.post(\"/api/generate/estimate\", payload);\r\n return response.data.data;\r\n }\r\n}\r\n","import { ApiClient } from \"../../api/client.js\";\r\nimport { TokenManager } from \"../../auth/token-manager.js\";\r\n\r\nexport function createApiClientWithAutoLogout(\r\n accessToken: string,\r\n tokenManager: TokenManager\r\n): ApiClient {\r\n return new ApiClient(accessToken, {\r\n onUnauthorized: async () => {\r\n await tokenManager.logout();\r\n },\r\n });\r\n}\r\n","import chalk from \"chalk\";\r\nimport { TokenManager } from \"../../auth/token-manager.js\";\r\n\r\nexport async function handleUnauthorized(\r\n tokenManager: TokenManager\r\n): Promise<never> {\r\n await tokenManager.logout();\r\n\r\n console.error(\r\n chalk.yellow(\r\n \" Your session is invalid or expired. You have been logged out.\"\r\n )\r\n );\r\n console.error(chalk.gray(\" Run 'aerocoding login' to authenticate.\"));\r\n\r\n process.exit(1);\r\n}\r\n","import chalk from \"chalk\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\n\r\n/**\r\n * Logout Command\r\n *\r\n * Clears stored credentials from OS credential manager\r\n */\r\nexport async function logoutCommand() {\r\n const tokenManager = new TokenManager();\r\n\r\n const metadata = await tokenManager.getUserMetadata();\r\n if (!metadata) {\r\n console.log(chalk.yellow(\"Not logged in\"));\r\n return;\r\n }\r\n\r\n const email = metadata.email;\r\n\r\n await tokenManager.logout();\r\n\r\n console.log(chalk.green(\"Logged out successfully\"));\r\n console.log(chalk.gray(` Cleared credentials for ${email}\\n`));\r\n}\r\n","import chalk from \"chalk\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\nimport { createApiClientWithAutoLogout } from \"./_shared/create-api-client.js\";\r\nimport { handleUnauthorized } from \"./_shared/unauthorized.js\";\r\n\r\n/**\r\n * Whoami Command\r\n *\r\n * Shows current authenticated user information\r\n */\r\nexport async function whoamiCommand() {\r\n const tokenManager = new TokenManager();\r\n const token = await tokenManager.getAccessToken();\r\n\r\n if (!token) {\r\n console.log(chalk.red(\"Not logged in\"));\r\n console.log(chalk.gray(\" Run 'aerocoding login' to authenticate\\n\"));\r\n return;\r\n }\r\n\r\n try {\r\n const apiClient = createApiClientWithAutoLogout(token, tokenManager);\r\n const user = await apiClient.getCurrentUser();\r\n\r\n console.log(\"\");\r\n console.log(chalk.white(\"Logged in as:\"), chalk.cyan.bold(user.email));\r\n if (user.name) {\r\n console.log(chalk.gray(\" Name:\"), user.name);\r\n }\r\n console.log(\"\");\r\n } catch (error: any) {\r\n console.error(chalk.red(\"Failed to get user info\"));\r\n if (error.response?.status === 401) {\r\n await handleUnauthorized(tokenManager);\r\n }\r\n process.exit(1);\r\n }\r\n}\r\n","import chalk from \"chalk\";\r\nimport ora from \"ora\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\nimport { createApiClientWithAutoLogout } from \"./_shared/create-api-client.js\";\r\nimport { handleUnauthorized } from \"./_shared/unauthorized.js\";\r\nimport { writeGeneratedFiles } from \"../utils/file-writer.js\";\r\nimport { promptConfirm } from \"../utils/prompt.js\";\r\nimport { loadConfig } from \"../config/loader.js\";\r\nimport type { AerocodingConfig } from \"../config/schema.js\";\r\n\r\n/**\r\n * Map preset name to generator target\r\n * Presets follow naming convention: {architecture}-{language}-{variant}\r\n * e.g., \"clean-architecture-dotnet-complete\" → \"dotnet-entity\"\r\n */\r\nfunction mapPresetToTarget(preset: string): string | null {\r\n const presetLower = preset.toLowerCase();\r\n\r\n // .NET presets\r\n if (presetLower.includes(\"dotnet\") || presetLower.includes(\"aspnet\") || presetLower.includes(\"csharp\")) {\r\n return \"dotnet-entity\";\r\n }\r\n\r\n // Dart/Flutter presets\r\n if (presetLower.includes(\"dart\") || presetLower.includes(\"flutter\")) {\r\n return \"dart-entity\";\r\n }\r\n\r\n // TypeScript presets\r\n if (presetLower.includes(\"typescript\") || presetLower.includes(\"nextjs\") || presetLower.includes(\"react\")) {\r\n return \"typescript-interface\";\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Build targets array from config file\r\n * Maps backend/frontend presets to appropriate target types\r\n */\r\nfunction buildTargetsFromConfig(config: AerocodingConfig | null): string[] {\r\n if (!config) return [];\r\n\r\n const targets: string[] = [];\r\n\r\n // Add backend targets based on preset\r\n if (config.backend?.preset) {\r\n const target = mapPresetToTarget(config.backend.preset);\r\n if (target) {\r\n targets.push(target);\r\n }\r\n }\r\n\r\n // Add frontend targets based on preset\r\n if (config.frontend?.preset) {\r\n const target = mapPresetToTarget(config.frontend.preset);\r\n if (target) {\r\n targets.push(target);\r\n }\r\n }\r\n\r\n return targets;\r\n}\r\n\r\ninterface GenerateOptions {\r\n project?: string;\r\n targets?: string[];\r\n entities?: string[];\r\n output: string;\r\n // Presets\r\n backendPreset?: string;\r\n frontendPreset?: string;\r\n backendLayers?: string[];\r\n frontendLayers?: string[];\r\n // Style toggles (commander inverts for --no-X, all default to true)\r\n validations?: boolean;\r\n comments?: boolean;\r\n annotations?: boolean;\r\n logging?: boolean;\r\n testing?: boolean;\r\n // Validation library (framework-agnostic)\r\n validationLib?: string;\r\n // Control\r\n yes?: boolean;\r\n}\r\n\r\n/**\r\n * Generate Command\r\n *\r\n * Generates code from project schema via API\r\n * Consumes credits based on generated files and entity complexity\r\n *\r\n * Config file (.aerocodingrc.json) provides defaults, CLI args override\r\n */\r\nexport async function generateCommand(options: GenerateOptions) {\r\n // 1. Check authentication\r\n const tokenManager = new TokenManager();\r\n const token = await tokenManager.getAccessToken();\r\n\r\n if (!token) {\r\n console.log(chalk.red(\"\\n Not authenticated\"));\r\n console.log(chalk.gray(\" Run 'aerocoding login' to get started\\n\"));\r\n process.exit(1);\r\n }\r\n\r\n // 2. Load config file (optional)\r\n const config = await loadConfig();\r\n\r\n // 3. Merge config with CLI options (CLI overrides config)\r\n const projectId = options.project || config?.project;\r\n\r\n if (!projectId) {\r\n console.log(chalk.red(\"\\n Project ID required\"));\r\n console.log(chalk.gray(\" Run 'aerocoding init' to create a config file\"));\r\n console.log(chalk.gray(\" Or use --project <id> to specify a project\\n\"));\r\n process.exit(1);\r\n }\r\n\r\n // Build targets from config if not provided via CLI\r\n const targets = options.targets || buildTargetsFromConfig(config);\r\n\r\n // Merge other options with config defaults\r\n const output = options.output || config?.output || \"./.aerocoding\";\r\n const backendPreset = options.backendPreset || config?.backend?.preset;\r\n const frontendPreset = options.frontendPreset || config?.frontend?.preset;\r\n const backendLayers = options.backendLayers || config?.backend?.layers;\r\n const frontendLayers = options.frontendLayers || config?.frontend?.layers;\r\n const validationLib = options.validationLib || config?.libraries?.validation;\r\n\r\n // Style options: CLI --no-X overrides config, config overrides default (true)\r\n const includeValidations = options.validations ?? config?.codeStyle?.includeValidations ?? true;\r\n const includeComments = options.comments ?? config?.codeStyle?.includeComments ?? true;\r\n const includeAnnotations = options.annotations ?? config?.codeStyle?.includeAnnotations ?? true;\r\n const includeLogging = options.logging ?? config?.codeStyle?.includeLogging ?? true;\r\n const includeTesting = options.testing ?? config?.codeStyle?.includeTesting ?? true;\r\n\r\n const apiClient = createApiClientWithAutoLogout(token, tokenManager);\r\n\r\n let spinner = ora({ text: \"Fetching project...\", color: \"cyan\" }).start();\r\n\r\n try {\r\n // 4. Fetch project to get organizationId\r\n const project = await apiClient.getProject(projectId);\r\n spinner.succeed(chalk.gray(`Project: ${project.name}`));\r\n\r\n // 5. Fetch credit usage and estimate cost in parallel\r\n spinner = ora({ text: \"Checking credits...\", color: \"cyan\" }).start();\r\n\r\n const credits = await apiClient.getCreditUsage(project.organizationId);\r\n\r\n // Try to get cost estimate (may fail if endpoint not deployed yet)\r\n let estimate: { estimatedCredits: number; totalFiles: number; entities: number } | null = null;\r\n try {\r\n estimate = await apiClient.estimateCreditCost({\r\n projectId,\r\n targets,\r\n options: {\r\n outputDir: output,\r\n backendPreset,\r\n frontendPreset,\r\n backendLayers,\r\n frontendLayers,\r\n },\r\n });\r\n } catch {\r\n // Estimate endpoint may not be available yet - continue without estimate\r\n }\r\n\r\n spinner.succeed(chalk.gray(`Credits: ${credits.remaining} / ${credits.limit} available`));\r\n\r\n // Check if project has entities (required for generation)\r\n if (estimate && estimate.entities === 0) {\r\n console.log(chalk.yellow(\"\\n ⚠ No entities found in this project.\"));\r\n console.log(chalk.gray(\" Create entities in the diagram editor and save (Ctrl+S) before generating.\\n\"));\r\n process.exit(1);\r\n }\r\n\r\n // Check if enough credits before showing summary (skip if no estimate)\r\n const hasEnoughCredits = estimate ? credits.remaining >= estimate.estimatedCredits : true;\r\n\r\n // 6. Show summary\r\n console.log(\"\");\r\n console.log(chalk.bold(\" Generation Summary\"));\r\n console.log(chalk.gray(\" ─────────────────────────────────\"));\r\n console.log(chalk.gray(\" Project:\"), chalk.white(project.name));\r\n if (config) {\r\n console.log(chalk.gray(\" Config:\"), chalk.cyan(\".aerocodingrc.json\"));\r\n }\r\n console.log(\r\n chalk.gray(\" Targets:\"),\r\n chalk.cyan(targets.length > 0 ? targets.join(\", \") : \"default\")\r\n );\r\n\r\n if (backendPreset) {\r\n console.log(chalk.gray(\" Backend Preset:\"), chalk.cyan(backendPreset));\r\n }\r\n if (frontendPreset) {\r\n console.log(chalk.gray(\" Frontend Preset:\"), chalk.cyan(frontendPreset));\r\n }\r\n\r\n // Show style options if different from defaults (all default to true)\r\n const disabledOptions: string[] = [];\r\n if (!includeValidations) disabledOptions.push(\"validations\");\r\n if (!includeComments) disabledOptions.push(\"comments\");\r\n if (!includeAnnotations) disabledOptions.push(\"annotations\");\r\n if (!includeLogging) disabledOptions.push(\"logging\");\r\n if (!includeTesting) disabledOptions.push(\"testing\");\r\n\r\n if (disabledOptions.length > 0) {\r\n console.log(chalk.gray(\" Disabled:\"), chalk.yellow(disabledOptions.join(\", \")));\r\n }\r\n\r\n if (validationLib) {\r\n console.log(chalk.gray(\" Validation Lib:\"), chalk.cyan(validationLib));\r\n }\r\n\r\n // Show estimate info (if available)\r\n if (estimate) {\r\n console.log(chalk.gray(\" Entities:\"), chalk.cyan(estimate.entities));\r\n console.log(chalk.gray(\" Files:\"), chalk.cyan(estimate.totalFiles));\r\n }\r\n\r\n console.log(\"\");\r\n console.log(chalk.bold(\" Credits\"));\r\n console.log(chalk.gray(\" ─────────────────────────────────\"));\r\n if (estimate) {\r\n console.log(\r\n chalk.white(\" Cost:\"),\r\n hasEnoughCredits\r\n ? chalk.bold.yellow(`${estimate.estimatedCredits} credits`)\r\n : chalk.bold.red(`${estimate.estimatedCredits} credits`)\r\n );\r\n }\r\n console.log(\r\n chalk.white(\" Available:\"),\r\n hasEnoughCredits\r\n ? chalk.bold.green(`${credits.remaining} credits`)\r\n : chalk.bold.red(`${credits.remaining} credits (insufficient)`)\r\n );\r\n console.log(chalk.gray(\" Output:\"), chalk.cyan(output));\r\n console.log(\"\");\r\n\r\n // Warn if not enough credits\r\n if (!hasEnoughCredits && estimate) {\r\n console.log(chalk.red(\" ⚠ Not enough credits for this generation.\"));\r\n console.log(chalk.gray(` Need ${estimate.estimatedCredits - credits.remaining} more credits.\\n`));\r\n process.exit(1);\r\n }\r\n\r\n // 7. Confirmation (unless --yes)\r\n if (!options.yes) {\r\n const confirmed = await promptConfirm(\" Proceed with generation?\");\r\n if (!confirmed) {\r\n console.log(chalk.yellow(\"\\n Generation cancelled\\n\"));\r\n process.exit(0);\r\n }\r\n }\r\n\r\n // 8. Call API\r\n console.log(\"\");\r\n spinner = ora({ text: \"Generating code...\", color: \"cyan\" }).start();\r\n\r\n const result = await apiClient.generateCode({\r\n projectId,\r\n targets,\r\n options: {\r\n includeValidations,\r\n includeComments,\r\n includeAnnotations,\r\n includeLogging,\r\n includeTesting,\r\n outputDir: output,\r\n backendPreset,\r\n frontendPreset,\r\n backendLayers,\r\n frontendLayers,\r\n validationLib,\r\n },\r\n });\r\n\r\n spinner.succeed(chalk.green(\"Code generated successfully!\"));\r\n\r\n // 9. Show results with credits\r\n console.log(\"\");\r\n console.log(chalk.bold(\" Results\"));\r\n console.log(chalk.gray(\" ─────────────────────────────────\"));\r\n console.log(chalk.gray(\" Files:\"), chalk.cyan(result.stats.totalFiles));\r\n console.log(chalk.gray(\" Entities:\"), chalk.cyan(result.stats.totalEntities));\r\n console.log(\r\n chalk.gray(\" Languages:\"),\r\n chalk.cyan(result.stats.languages.join(\", \"))\r\n );\r\n\r\n if (result.creditsUsed !== undefined) {\r\n console.log(\"\");\r\n console.log(chalk.bold(\" Credits\"));\r\n console.log(chalk.gray(\" ─────────────────────────────────\"));\r\n console.log(chalk.gray(\" Used:\"), chalk.yellow(result.creditsUsed));\r\n console.log(\r\n chalk.gray(\" Remaining:\"),\r\n result.creditsRemaining !== undefined && result.creditsRemaining > 50\r\n ? chalk.green(result.creditsRemaining)\r\n : chalk.yellow(result.creditsRemaining)\r\n );\r\n }\r\n\r\n // Show warnings if any\r\n if (result.warnings && result.warnings.length > 0) {\r\n console.log(\"\");\r\n console.log(chalk.yellow(\" Warnings:\"));\r\n for (const warning of result.warnings) {\r\n console.log(chalk.yellow(` - ${warning}`));\r\n }\r\n }\r\n\r\n console.log(\"\");\r\n\r\n // 10. Write files to disk\r\n await writeGeneratedFiles(result.files, output);\r\n\r\n console.log(chalk.green(` Files written to ${chalk.white(output)}`));\r\n console.log(\"\");\r\n } catch (error: any) {\r\n spinner.fail(chalk.red(\"Generation failed\"));\r\n\r\n // Show error details for debugging\r\n console.log(chalk.gray(`\\n Error: ${error.response?.status || error.code || 'unknown'}`));\r\n if (error.response?.data) {\r\n console.log(chalk.gray(` Details: ${JSON.stringify(error.response.data)}`));\r\n }\r\n\r\n if (error.response?.status === 401) {\r\n await handleUnauthorized(tokenManager);\r\n } else if (error.response?.status === 403) {\r\n console.log(chalk.yellow(\"\\n You don't have permission to access this project.\"));\r\n console.log(chalk.gray(\" Check if you're part of the organization.\\n\"));\r\n } else if (error.response?.status === 404) {\r\n console.log(chalk.yellow(\"\\n Project not found.\"));\r\n console.log(chalk.gray(\" Check if the project ID is correct.\\n\"));\r\n } else if (error.response?.status === 429) {\r\n // Insufficient credits\r\n const data = error.response.data;\r\n console.log(chalk.red(\"\\n Insufficient credits\"));\r\n if (data.requiredCredits) {\r\n console.log(chalk.yellow(` Required: ${data.requiredCredits} credits`));\r\n }\r\n console.log(chalk.yellow(` Available: ${data.remaining ?? 0} credits`));\r\n console.log(chalk.gray(\"\\n Upgrade your plan or wait for credit reset.\\n\"));\r\n } else if (error.response?.data?.message) {\r\n console.log(chalk.red(`\\n ${error.response.data.message}\\n`));\r\n } else {\r\n console.log(chalk.red(`\\n ${error.message}\\n`));\r\n }\r\n\r\n process.exit(1);\r\n }\r\n}\r\n","import fs from \"fs/promises\";\r\nimport path from \"path\";\r\nimport chalk from \"chalk\";\r\n\r\ninterface GeneratedFile {\r\n path: string;\r\n content: string;\r\n language: string;\r\n entityId?: string;\r\n}\r\n\r\n/**\r\n * Validate that a file path is safe and doesn't escape the output directory.\r\n * SECURITY: Prevents path traversal attacks (e.g., ../../../etc/passwd)\r\n */\r\nfunction isPathSafe(outputDir: string, filePath: string): boolean {\r\n // Resolve both paths to absolute paths\r\n const resolvedOutput = path.resolve(outputDir);\r\n const resolvedFile = path.resolve(outputDir, filePath);\r\n\r\n // Check if the resolved file path starts with the output directory\r\n // Also ensure there's a path separator after the base to prevent\r\n // matching \"output\" when file is in \"output-malicious\"\r\n return (\r\n resolvedFile.startsWith(resolvedOutput + path.sep) ||\r\n resolvedFile === resolvedOutput\r\n );\r\n}\r\n\r\n/**\r\n * Write generated files to disk\r\n *\r\n * Creates directories as needed and writes files\r\n * Shows progress for each file\r\n */\r\nexport async function writeGeneratedFiles(\r\n files: GeneratedFile[],\r\n outputDir: string\r\n): Promise<void> {\r\n for (const file of files) {\r\n // SECURITY: Validate path doesn't escape output directory\r\n if (!isPathSafe(outputDir, file.path)) {\r\n console.error(\r\n chalk.red(` Skipping unsafe path: ${file.path}`)\r\n );\r\n console.error(\r\n chalk.gray(` Path traversal detected - file path must be within output directory`)\r\n );\r\n continue;\r\n }\r\n\r\n const fullPath = path.resolve(outputDir, file.path);\r\n const dir = path.dirname(fullPath);\r\n\r\n try {\r\n // Create directory if doesn't exist\r\n await fs.mkdir(dir, { recursive: true });\r\n\r\n // Write file\r\n await fs.writeFile(fullPath, file.content, \"utf-8\");\r\n\r\n console.log(chalk.gray(` ${file.path}`));\r\n } catch (error: any) {\r\n console.error(chalk.red(` Failed to write ${file.path}`));\r\n console.error(chalk.gray(` ${error.message}`));\r\n }\r\n }\r\n}\r\n","import readline from \"readline\";\r\nimport chalk from \"chalk\";\r\n\r\n/**\r\n * Prompt user for confirmation\r\n * Returns true if user confirms (Y/yes/enter), false if they decline (n/no)\r\n */\r\nexport function promptConfirm(message: string): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const rl = readline.createInterface({\r\n input: process.stdin,\r\n output: process.stdout,\r\n });\r\n\r\n rl.question(chalk.yellow(`${message} [Y/n] `), (answer) => {\r\n rl.close();\r\n const normalized = answer.trim().toLowerCase();\r\n // Empty input (just pressing Enter) means \"yes\"\r\n resolve(normalized !== \"n\" && normalized !== \"no\");\r\n });\r\n });\r\n}\r\n","import fs from \"fs/promises\";\r\nimport path from \"path\";\r\nimport { configSchema, CONFIG_FILENAME, type AerocodingConfig } from \"./schema.js\";\r\n\r\nexport async function loadConfig(\r\n dir: string = process.cwd()\r\n): Promise<AerocodingConfig | null> {\r\n const configPath = path.join(dir, CONFIG_FILENAME);\r\n\r\n try {\r\n const content = await fs.readFile(configPath, \"utf-8\");\r\n const parsed = JSON.parse(content);\r\n return configSchema.parse(parsed);\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\r\n return null;\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function saveConfig(\r\n config: AerocodingConfig,\r\n dir: string = process.cwd()\r\n): Promise<void> {\r\n const configPath = path.join(dir, CONFIG_FILENAME);\r\n const content = JSON.stringify(\r\n {\r\n $schema: \"https://aerocoding.dev/schemas/aerocodingrc.json\",\r\n ...config,\r\n },\r\n null,\r\n 2\r\n );\r\n await fs.writeFile(configPath, content, \"utf-8\");\r\n}\r\n\r\nexport async function configExists(dir: string = process.cwd()): Promise<boolean> {\r\n const configPath = path.join(dir, CONFIG_FILENAME);\r\n try {\r\n await fs.access(configPath);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport { type AerocodingConfig, CONFIG_FILENAME } from \"./schema.js\";\r\n","import { z } from \"zod\";\r\n\r\nexport const configSchema = z.object({\r\n $schema: z.string().optional(),\r\n project: z.string().uuid(),\r\n output: z.string().default(\"./.aerocoding\"),\r\n\r\n backend: z\r\n .object({\r\n preset: z.string(),\r\n layers: z.array(z.string()),\r\n })\r\n .optional(),\r\n\r\n frontend: z\r\n .object({\r\n preset: z.string(),\r\n layers: z.array(z.string()),\r\n })\r\n .optional(),\r\n\r\n codeStyle: z\r\n .object({\r\n includeValidations: z.boolean().default(true),\r\n includeComments: z.boolean().default(true),\r\n includeAnnotations: z.boolean().default(true),\r\n includeLogging: z.boolean().default(true),\r\n includeTesting: z.boolean().default(true),\r\n })\r\n .default({}),\r\n\r\n libraries: z\r\n .object({\r\n validation: z.string().optional(),\r\n logging: z.string().optional(),\r\n })\r\n .optional(),\r\n\r\n excludePatterns: z.array(z.string()).optional(),\r\n});\r\n\r\nexport type AerocodingConfig = z.infer<typeof configSchema>;\r\n\r\nexport const CONFIG_FILENAME = \".aerocodingrc.json\";\r\n","import * as p from \"@clack/prompts\";\r\nimport chalk from \"chalk\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\nimport { createApiClientWithAutoLogout } from \"./_shared/create-api-client.js\";\r\nimport { handleUnauthorized } from \"./_shared/unauthorized.js\";\r\nimport { saveConfig, configExists } from \"../config/loader.js\";\r\nimport type { AerocodingConfig } from \"../config/schema.js\";\r\n\r\ninterface InitOptions {\r\n project?: string;\r\n force?: boolean;\r\n}\r\n\r\n/**\r\n * Init Command\r\n *\r\n * Interactive wizard to initialize AeroCoding in current directory\r\n * Creates .aerocodingrc.json config file\r\n */\r\nexport async function initCommand(options: InitOptions) {\r\n p.intro(chalk.bgCyan.black(\" AeroCoding CLI \"));\r\n\r\n // Check if config already exists\r\n if (!options.force && (await configExists())) {\r\n const overwrite = await p.confirm({\r\n message: \"Config file already exists. Overwrite?\",\r\n initialValue: false,\r\n });\r\n\r\n if (p.isCancel(overwrite) || !overwrite) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n }\r\n\r\n // 1. Check authentication\r\n const tokenManager = new TokenManager();\r\n const token = await tokenManager.getAccessToken();\r\n\r\n if (!token) {\r\n p.cancel(\"Not logged in. Run 'aerocoding login' first.\");\r\n process.exit(1);\r\n }\r\n\r\n const apiClient = createApiClientWithAutoLogout(token, tokenManager);\r\n\r\n try {\r\n // 2. Select organization first\r\n const orgSpinner = p.spinner();\r\n orgSpinner.start(\"Loading organizations...\");\r\n\r\n const organizations = await apiClient.listOrganizations();\r\n orgSpinner.stop(\"Organizations loaded\");\r\n\r\n if (organizations.length === 0) {\r\n p.cancel(\"No organizations found. Create one on aerocoding.dev first.\");\r\n process.exit(1);\r\n }\r\n\r\n let organizationId: string;\r\n\r\n if (organizations.length === 1) {\r\n // Auto-select if only one org\r\n organizationId = organizations[0].id;\r\n p.log.info(`Organization: ${organizations[0].name}`);\r\n } else {\r\n const selectedOrg = await p.select({\r\n message: \"Select organization\",\r\n options: organizations.map((org) => ({\r\n value: org.id,\r\n label: org.name,\r\n hint: org.planTier.toUpperCase(),\r\n })),\r\n });\r\n\r\n if (p.isCancel(selectedOrg)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n organizationId = selectedOrg as string;\r\n }\r\n\r\n // 3. Select project from organization\r\n let projectId = options.project;\r\n\r\n if (!projectId) {\r\n const spinner = p.spinner();\r\n spinner.start(\"Loading projects...\");\r\n\r\n const projects = await apiClient.listProjects(organizationId);\r\n spinner.stop(\"Projects loaded\");\r\n\r\n if (projects.length === 0) {\r\n p.cancel(\"No projects in this organization. Create one on aerocoding.dev first.\");\r\n process.exit(1);\r\n }\r\n\r\n const selectedProject = await p.select({\r\n message: \"Select project\",\r\n options: projects.map((proj) => ({\r\n value: proj.id,\r\n label: proj.name,\r\n hint: [proj.backendFramework, proj.frontendFramework].filter(Boolean).join(\" + \"),\r\n })),\r\n });\r\n\r\n if (p.isCancel(selectedProject)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n projectId = selectedProject as string;\r\n }\r\n\r\n // 4. Fetch project details\r\n const spinner = p.spinner();\r\n spinner.start(\"Fetching project details...\");\r\n const project = await apiClient.getProject(projectId);\r\n spinner.stop(`Project: ${project.name}`);\r\n\r\n // Build target options based on project frameworks\r\n const targetOptions: { value: string; label: string }[] = [];\r\n if (project.backendFramework) {\r\n targetOptions.push({\r\n value: \"backend\",\r\n label: `Backend (${project.backendFramework})`,\r\n });\r\n }\r\n if (project.frontendFramework) {\r\n targetOptions.push({\r\n value: \"frontend\",\r\n label: `Frontend (${project.frontendFramework})`,\r\n });\r\n }\r\n\r\n if (targetOptions.length === 0) {\r\n p.cancel(\"Project has no frameworks configured. Update it on aerocoding.dev first.\");\r\n process.exit(1);\r\n }\r\n\r\n // 4. Select what to generate\r\n const targets = await p.multiselect({\r\n message: \"What do you want to generate?\",\r\n options: targetOptions,\r\n required: true,\r\n });\r\n\r\n if (p.isCancel(targets)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n const selectedTargets = targets as string[];\r\n\r\n // Initialize config\r\n const config: AerocodingConfig = {\r\n project: projectId,\r\n output: \"./.aerocoding\",\r\n codeStyle: {\r\n includeValidations: true,\r\n includeComments: true,\r\n includeAnnotations: true,\r\n includeLogging: true,\r\n includeTesting: true,\r\n },\r\n };\r\n\r\n // 5. Backend configuration\r\n if (selectedTargets.includes(\"backend\") && project.backendFramework) {\r\n const archSpinner = p.spinner();\r\n archSpinner.start(\"Loading backend architectures...\");\r\n const architectures = await apiClient.getArchitectures(project.backendFramework);\r\n archSpinner.stop(\"Architectures loaded\");\r\n\r\n if (architectures.length > 0) {\r\n const preset = await p.select({\r\n message: \"Backend architecture\",\r\n options: architectures.map((arch) => ({\r\n value: arch.id,\r\n label: arch.name,\r\n hint: arch.description,\r\n })),\r\n });\r\n\r\n if (p.isCancel(preset)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n const selectedArch = architectures.find((a) => a.id === preset);\r\n\r\n if (selectedArch && selectedArch.layers.length > 0) {\r\n const layers = await p.multiselect({\r\n message: \"Select backend layers to include\",\r\n options: selectedArch.layers.map((layer) => ({\r\n value: layer.id,\r\n label: layer.name,\r\n hint: layer.category,\r\n })),\r\n initialValues: selectedArch.layers.map((l) => l.id),\r\n });\r\n\r\n if (p.isCancel(layers)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n config.backend = {\r\n preset: preset as string,\r\n layers: layers as string[],\r\n };\r\n } else {\r\n config.backend = {\r\n preset: preset as string,\r\n layers: [],\r\n };\r\n }\r\n }\r\n }\r\n\r\n // 6. Frontend configuration\r\n if (selectedTargets.includes(\"frontend\") && project.frontendFramework) {\r\n const archSpinner = p.spinner();\r\n archSpinner.start(\"Loading frontend architectures...\");\r\n const architectures = await apiClient.getArchitectures(project.frontendFramework);\r\n archSpinner.stop(\"Architectures loaded\");\r\n\r\n if (architectures.length > 0) {\r\n const preset = await p.select({\r\n message: \"Frontend architecture\",\r\n options: architectures.map((arch) => ({\r\n value: arch.id,\r\n label: arch.name,\r\n hint: arch.description,\r\n })),\r\n });\r\n\r\n if (p.isCancel(preset)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n const selectedArch = architectures.find((a) => a.id === preset);\r\n\r\n if (selectedArch && selectedArch.layers.length > 0) {\r\n const layers = await p.multiselect({\r\n message: \"Select frontend layers to include\",\r\n options: selectedArch.layers.map((layer) => ({\r\n value: layer.id,\r\n label: layer.name,\r\n hint: layer.category,\r\n })),\r\n initialValues: selectedArch.layers.map((l) => l.id),\r\n });\r\n\r\n if (p.isCancel(layers)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n config.frontend = {\r\n preset: preset as string,\r\n layers: layers as string[],\r\n };\r\n } else {\r\n config.frontend = {\r\n preset: preset as string,\r\n layers: [],\r\n };\r\n }\r\n }\r\n }\r\n\r\n // 7. Code style options\r\n const codeStyleOptions = await p.multiselect({\r\n message: \"Code style options\",\r\n options: [\r\n { value: \"validations\", label: \"Include validations\", hint: \"Add validation rules\" },\r\n { value: \"comments\", label: \"Include comments\", hint: \"Add code documentation\" },\r\n { value: \"annotations\", label: \"Include annotations\", hint: \"Add decorators/attributes\" },\r\n { value: \"logging\", label: \"Include logging\", hint: \"Add log statements\" },\r\n { value: \"testing\", label: \"Include tests\", hint: \"Generate test files\" },\r\n ],\r\n initialValues: [\"validations\", \"comments\", \"annotations\", \"logging\", \"testing\"],\r\n });\r\n\r\n if (p.isCancel(codeStyleOptions)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n const selectedStyles = codeStyleOptions as string[];\r\n config.codeStyle = {\r\n includeValidations: selectedStyles.includes(\"validations\"),\r\n includeComments: selectedStyles.includes(\"comments\"),\r\n includeAnnotations: selectedStyles.includes(\"annotations\"),\r\n includeLogging: selectedStyles.includes(\"logging\"),\r\n includeTesting: selectedStyles.includes(\"testing\"),\r\n };\r\n\r\n // 8. Output directory\r\n const output = await p.text({\r\n message: \"Output directory\",\r\n initialValue: \"./.aerocoding\",\r\n validate: (value) => {\r\n if (!value) return \"Output directory is required\";\r\n return undefined;\r\n },\r\n });\r\n\r\n if (p.isCancel(output)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n config.output = output as string;\r\n\r\n // 9. Save config\r\n await saveConfig(config);\r\n\r\n p.outro(\r\n chalk.green(\"Config saved to .aerocodingrc.json\") +\r\n \"\\n\\n\" +\r\n chalk.gray(\" Run \") +\r\n chalk.cyan(\"aerocoding generate\") +\r\n chalk.gray(\" to generate code!\")\r\n );\r\n } catch (error: any) {\r\n if (error.response?.status === 401) {\r\n await handleUnauthorized(tokenManager);\r\n } else if (error.response?.data?.message) {\r\n p.cancel(error.response.data.message);\r\n } else {\r\n p.cancel(error.message || \"An unexpected error occurred\");\r\n }\r\n process.exit(1);\r\n }\r\n}\r\n","import chalk from \"chalk\";\r\n\r\ninterface PullOptions {\r\n project?: string;\r\n}\r\n\r\n/**\r\n * Pull Command (Stub)\r\n *\r\n * TODO: Pull schema from cloud\r\n * - Download project schema\r\n * - Save to .aerocoding/schema.json\r\n */\r\nexport async function pullCommand(options: PullOptions) {\r\n console.log(chalk.yellow(\"Command not yet implemented\"));\r\n if (options.project) {\r\n console.log(chalk.gray(` Requested project: ${options.project}`));\r\n }\r\n console.log(chalk.gray(\" Coming soon in v0.2.0\\n\"));\r\n}\r\n","import chalk from \"chalk\";\r\n\r\n/**\r\n * Status Command (Stub)\r\n *\r\n * TODO: Show local schema status\r\n * - Show current project\r\n * - Show schema stats\r\n * - Show sync status\r\n */\r\nexport async function statusCommand() {\r\n console.log(chalk.yellow(\"Command not yet implemented\"));\r\n console.log(chalk.gray(\" Coming soon in v0.2.0\\n\"));\r\n}\r\n"],"mappings":"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","names":["chalk","spinner","chalk","axios","API_URL","chalk","chalk","chalk","chalk","chalk","chalk","chalk","ora","chalk","chalk","fs","path","path","fs","chalk","spinner","ora","chalk","chalk","spinner","chalk","chalk"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/login.ts","../src/auth/device-flow.ts","../src/auth/token-manager.ts","../src/api/client.ts","../src/commands/_shared/create-api-client.ts","../src/commands/_shared/unauthorized.ts","../src/commands/logout.ts","../src/commands/whoami.ts","../src/commands/generate.ts","../src/utils/file-writer.ts","../src/utils/prompt.ts","../src/config/loader.ts","../src/config/schema.ts","../src/commands/init.ts","../src/commands/pull.ts","../src/commands/status.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Command } from \"commander\";\r\nimport { loginCommand } from \"./commands/login.js\";\r\nimport { logoutCommand } from \"./commands/logout.js\";\r\nimport { whoamiCommand } from \"./commands/whoami.js\";\r\nimport { generateCommand } from \"./commands/generate.js\";\r\nimport { initCommand } from \"./commands/init.js\";\r\nimport { pullCommand } from \"./commands/pull.js\";\r\nimport { statusCommand } from \"./commands/status.js\";\r\nimport \"dotenv/config\";\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name(\"aerocoding\")\r\n .description(\"AeroCoding CLI - Generate production-ready code from UML diagrams\")\r\n .version(\"0.1.15\");\r\n\r\n// ============================================\r\n// Authentication Commands\r\n// ============================================\r\n\r\nprogram\r\n .command(\"login\")\r\n .description(\"Authenticate with AeroCoding\")\r\n .action(loginCommand);\r\n\r\nprogram\r\n .command(\"logout\")\r\n .description(\"Logout and clear stored credentials\")\r\n .action(logoutCommand);\r\n\r\nprogram\r\n .command(\"whoami\")\r\n .description(\"Show current authenticated user\")\r\n .action(whoamiCommand);\r\n\r\n// ============================================\r\n// Project Commands\r\n// ============================================\r\n\r\nprogram\r\n .command(\"init\")\r\n .description(\"Initialize AeroCoding in current directory\")\r\n .option(\"-p, --project <id>\", \"Project ID (skip selection)\")\r\n .option(\"-f, --force\", \"Overwrite existing config without asking\")\r\n .action(initCommand);\r\n\r\nprogram\r\n .command(\"pull\")\r\n .description(\"Pull schema from cloud\")\r\n .option(\"-p, --project <id>\", \"Project ID\")\r\n .action(pullCommand);\r\n\r\nprogram\r\n .command(\"status\")\r\n .description(\"Show local schema status\")\r\n .action(statusCommand);\r\n\r\n// ============================================\r\n// Generation Commands\r\n// ============================================\r\n\r\nprogram\r\n .command(\"generate\")\r\n .alias(\"gen\")\r\n .description(\"Generate code from schema\")\r\n // Identification\r\n .option(\"-p, --project <id>\", \"Project ID\")\r\n .option(\"-t, --targets <targets...>\", \"Generation targets (e.g., dotnet-entity)\")\r\n .option(\"-e, --entities <entities...>\", \"Filter by entity names\")\r\n .option(\"-o, --output <dir>\", \"Output directory\", \"./.aerocoding\")\r\n // Presets & Layers\r\n .option(\"--backend-preset <preset>\", \"Backend architecture preset\")\r\n .option(\"--frontend-preset <preset>\", \"Frontend architecture preset\")\r\n .option(\"--backend-layers <layers...>\", \"Backend layers to generate\")\r\n .option(\"--frontend-layers <layers...>\", \"Frontend layers to generate\")\r\n // Code style toggles (optimistic defaults - all enabled by default)\r\n .option(\"--no-validations\", \"Exclude validations\")\r\n .option(\"--no-comments\", \"Exclude comments\")\r\n .option(\"--no-annotations\", \"Exclude annotations\")\r\n .option(\"--no-logging\", \"Exclude logging statements\")\r\n .option(\"--no-testing\", \"Exclude test files\")\r\n // Validation library (framework-agnostic)\r\n .option(\"--validation-lib <framework>\", \"Validation library (e.g., fluentvalidation, zod, formz)\")\r\n // Control\r\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\r\n .action(generateCommand);\r\n\r\n// ============================================\r\n// Parse and Execute\r\n// ============================================\r\n\r\nprogram.parse();\r\n","import chalk from \"chalk\";\r\nimport { DeviceFlow } from \"../auth/device-flow.js\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\nimport { createApiClientWithAutoLogout } from \"./_shared/create-api-client.js\";\r\nimport { handleUnauthorized } from \"./_shared/unauthorized.js\";\r\n\r\n/**\r\n * Login Command\r\n *\r\n * Authenticates user via OAuth Device Flow\r\n * Stores tokens securely in OS credential manager\r\n */\r\nexport async function loginCommand() {\r\n console.log(chalk.bold(\"\\nAeroCoding CLI Login\\n\"));\r\n\r\n const tokenManager = new TokenManager();\r\n\r\n // Check if already logged in\r\n const existingToken = await tokenManager.getAccessToken();\r\n if (existingToken) {\r\n const metadata = await tokenManager.getUserMetadata();\r\n console.log(\r\n chalk.yellow(\"Already logged in as:\"),\r\n chalk.white(metadata?.email || \"unknown\")\r\n );\r\n console.log(\r\n chalk.gray(\r\n \" Run 'aerocoding logout' to login with a different account\\n\"\r\n )\r\n );\r\n return;\r\n }\r\n\r\n try {\r\n // Initiate device flow\r\n const deviceFlow = new DeviceFlow();\r\n const tokens = await deviceFlow.initiateAuth();\r\n\r\n // Get user info\r\n const apiClient = createApiClientWithAutoLogout(\r\n tokens.access_token,\r\n tokenManager\r\n );\r\n let user;\r\n try {\r\n user = await apiClient.getCurrentUser();\r\n } catch (error: any) {\r\n if (error.response?.status === 401) {\r\n await handleUnauthorized(tokenManager);\r\n }\r\n throw error;\r\n }\r\n\r\n // Save tokens\r\n await tokenManager.saveTokens(tokens.access_token, tokens.refresh_token, {\r\n id: user.id,\r\n email: user.email,\r\n name: user.name || undefined,\r\n tier: user.tier,\r\n });\r\n\r\n console.log(\"\");\r\n console.log(\r\n chalk.green(\"Successfully logged in as:\"),\r\n chalk.white(user.email)\r\n );\r\n console.log(chalk.gray(\" Run 'aerocoding whoami' to verify\\n\"));\r\n } catch (error: any) {\r\n console.error(\r\n chalk.red(\"\\nLogin failed:\"),\r\n error.message || \"Unknown error\"\r\n );\r\n process.exit(1);\r\n }\r\n}\r\n","import axios from \"axios\";\r\nimport chalk from \"chalk\";\r\nimport ora from \"ora\";\r\nimport open from \"open\";\r\n\r\nconst API_URL = process.env.API_URL || \"https://aerocoding.dev\";\r\nconst MAX_POLL_TIME = 15 * 60 * 1000; // 15 minutes\r\n\r\ninterface DeviceAuthResponse {\r\n device_code: string;\r\n user_code: string;\r\n confirmation_code: string;\r\n verification_uri: string;\r\n verification_uri_complete: string;\r\n expires_in: number;\r\n interval: number;\r\n}\r\n\r\ninterface TokenResponse {\r\n access_token: string;\r\n refresh_token: string;\r\n token_type: string;\r\n expires_in: number;\r\n}\r\n\r\n/**\r\n * DeviceFlow\r\n *\r\n * Implements OAuth 2.0 Device Authorization Grant (RFC 8628)\r\n * Used for CLI authentication without browser-based redirects\r\n */\r\nexport class DeviceFlow {\r\n /**\r\n * Initiate the complete device authorization flow\r\n */\r\n async initiateAuth(): Promise<TokenResponse> {\r\n // Step 1: Request device code\r\n const deviceAuth = await this.requestDeviceCode();\r\n\r\n // Step 2: Display user code and open browser\r\n this.displayUserCode(deviceAuth);\r\n await this.openBrowser(deviceAuth.verification_uri);\r\n\r\n // Step 3: Poll for authorization\r\n const tokens = await this.pollForToken(deviceAuth);\r\n\r\n return tokens;\r\n }\r\n\r\n /**\r\n * Step 1: Request device code from server\r\n */\r\n private async requestDeviceCode(): Promise<DeviceAuthResponse> {\r\n try {\r\n const response = await axios.post(`${API_URL}/api/device/authorize`, {\r\n client_id: \"aerocoding-cli\",\r\n scope: \"generate:code projects:read\",\r\n });\r\n\r\n return response.data;\r\n } catch (error: any) {\r\n console.error(chalk.red(\"Failed to initiate device authorization\"));\r\n if (error.response) {\r\n console.error(\r\n chalk.red(`Error: ${error.response.data.error_description}`)\r\n );\r\n }\r\n throw new Error(\"Failed to initiate device authorization\");\r\n }\r\n }\r\n\r\n /**\r\n * Step 2: Display user code and instructions\r\n */\r\n private displayUserCode(auth: DeviceAuthResponse): void {\r\n console.log(\"\\n\");\r\n console.log(chalk.cyan(\"━\".repeat(60)));\r\n console.log(chalk.bold.white(\" AeroCoding CLI - Device Activation\"));\r\n console.log(chalk.cyan(\"━\".repeat(60)));\r\n console.log(\"\");\r\n console.log(chalk.white(\" 1. Open this URL in your browser:\"));\r\n console.log(chalk.cyan.bold(` ${auth.verification_uri}`));\r\n console.log(\"\");\r\n console.log(chalk.white(\" 2. Enter this code:\"));\r\n console.log(chalk.green.bold(` ${auth.user_code}`));\r\n console.log(\"\");\r\n console.log(\r\n chalk.gray(` Code expires in ${auth.expires_in / 60} minutes`)\r\n );\r\n console.log(chalk.cyan(\"━\".repeat(60)));\r\n console.log(\"\");\r\n }\r\n\r\n /**\r\n * Step 2.5: Open browser automatically\r\n */\r\n private async openBrowser(url: string): Promise<void> {\r\n try {\r\n await open(url);\r\n console.log(chalk.gray(\" Opening browser...\"));\r\n } catch {\r\n console.log(chalk.yellow(\" Could not open browser automatically\"));\r\n console.log(chalk.gray(\" Please open the URL manually\\n\"));\r\n }\r\n }\r\n\r\n /**\r\n * Step 3: Poll for token\r\n */\r\n private async pollForToken(auth: DeviceAuthResponse): Promise<TokenResponse> {\r\n const spinner = ora({\r\n text: \"Waiting for authorization...\",\r\n color: \"cyan\",\r\n }).start();\r\n\r\n const startTime = Date.now();\r\n let currentInterval = auth.interval * 1000;\r\n\r\n while (true) {\r\n // Check timeout\r\n if (Date.now() - startTime > MAX_POLL_TIME) {\r\n spinner.fail(chalk.red(\"Authorization timeout\"));\r\n throw new Error(\"Device authorization timed out\");\r\n }\r\n\r\n try {\r\n const response = await axios.post(`${API_URL}/api/device/token`, {\r\n device_code: auth.device_code,\r\n client_id: \"aerocoding-cli\",\r\n });\r\n\r\n spinner.succeed(chalk.green(\"Successfully authenticated!\"));\r\n return response.data;\r\n } catch (error: any) {\r\n const errorCode = error.response?.data?.error;\r\n const errorDescription = error.response?.data?.error_description;\r\n\r\n if (errorCode === \"authorization_pending\") {\r\n // Keep polling\r\n await this.sleep(currentInterval);\r\n continue;\r\n }\r\n\r\n if (errorCode === \"slow_down\") {\r\n // Increase poll interval by 5 seconds\r\n currentInterval += 5000;\r\n spinner.text = \"Polling... (slowed down to avoid spam)\";\r\n await this.sleep(currentInterval);\r\n continue;\r\n }\r\n\r\n if (errorCode === \"expired_token\") {\r\n spinner.fail(chalk.red(\"Authorization code expired\"));\r\n throw new Error(\"Device code expired. Please try again.\");\r\n }\r\n\r\n if (errorCode === \"access_denied\") {\r\n spinner.fail(chalk.red(\"Authorization denied\"));\r\n throw new Error(\"You denied the authorization request\");\r\n }\r\n\r\n // Unknown error\r\n spinner.fail(chalk.red(\"Authorization failed\"));\r\n console.error(\r\n chalk.red(`Error: ${errorDescription || \"Unknown error\"}`)\r\n );\r\n throw new Error(errorDescription || \"Unknown error\");\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Helper: Sleep for specified milliseconds\r\n */\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n }\r\n}\r\n","import { Entry } from \"@napi-rs/keyring\";\r\nimport { createClient, SupabaseClient } from \"@supabase/supabase-js\";\r\n\r\nconst SERVICE_NAME = \"aerocoding-cli\";\r\n\r\n// Public Supabase credentials (anon key is safe to expose)\r\nconst SUPABASE_URL = \"https://peqpttkvdpjgmduzacwl.supabase.co\";\r\nconst SUPABASE_ANON_KEY = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBlcXB0dGt2ZHBqZ21kdXphY3dsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQyNjUxNzMsImV4cCI6MjA3OTg0MTE3M30.WAzqgZusGoOEHxidfHc1e4daBglG4DJG5LOXbqldWQA\";\r\n\r\ninterface UserMetadata {\r\n id: string;\r\n email: string;\r\n name?: string;\r\n tier?: string;\r\n}\r\n\r\n/**\r\n * Helper functions for keyring operations using Entry class\r\n */\r\nfunction getPassword(service: string, account: string): string | null {\r\n try {\r\n const entry = new Entry(service, account);\r\n return entry.getPassword();\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction setPassword(service: string, account: string, password: string): void {\r\n const entry = new Entry(service, account);\r\n entry.setPassword(password);\r\n}\r\n\r\nfunction deletePassword(service: string, account: string): void {\r\n try {\r\n const entry = new Entry(service, account);\r\n entry.deletePassword();\r\n } catch {\r\n // Ignore if entry doesn't exist\r\n }\r\n}\r\n\r\n/**\r\n * TokenManager\r\n *\r\n * Manages secure storage and automatic refresh of authentication tokens\r\n * Uses OS-level credential managers (Keychain/Credential Manager/Secret Service)\r\n */\r\nexport class TokenManager {\r\n private supabase: SupabaseClient;\r\n\r\n constructor() {\r\n this.supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {\r\n auth: {\r\n autoRefreshToken: false,\r\n persistSession: false,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Get access token, automatically refreshing if expired\r\n */\r\n async getAccessToken(): Promise<string | null> {\r\n try {\r\n let accessToken = getPassword(SERVICE_NAME, \"access_token\");\r\n\r\n if (!accessToken) {\r\n return null;\r\n }\r\n\r\n // Check if expired\r\n if (this.isTokenExpired(accessToken)) {\r\n accessToken = await this.refreshTokens();\r\n }\r\n\r\n return accessToken;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Refresh tokens using stored refresh token\r\n */\r\n private async refreshTokens(): Promise<string | null> {\r\n try {\r\n const refreshToken = getPassword(SERVICE_NAME, \"refresh_token\");\r\n\r\n if (!refreshToken) {\r\n throw new Error(\"No refresh token available\");\r\n }\r\n\r\n const { data, error } = await this.supabase.auth.refreshSession({\r\n refresh_token: refreshToken,\r\n });\r\n\r\n if (error || !data.session) {\r\n throw new Error(\"Failed to refresh session\");\r\n }\r\n\r\n // Store new tokens (single-use refresh token rotation)\r\n setPassword(SERVICE_NAME, \"access_token\", data.session.access_token);\r\n setPassword(SERVICE_NAME, \"refresh_token\", data.session.refresh_token);\r\n\r\n return data.session.access_token;\r\n } catch {\r\n await this.logout();\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Check if JWT token is expired (or expires in < 5 min)\r\n */\r\n private isTokenExpired(token: string): boolean {\r\n try {\r\n const payload = JSON.parse(\r\n Buffer.from(token.split(\".\")[1]!, \"base64\").toString()\r\n );\r\n const expiresAt = payload.exp * 1000;\r\n const now = Date.now();\r\n\r\n // Refresh 5 minutes before expiration\r\n return expiresAt - now < 5 * 60 * 1000;\r\n } catch {\r\n return true; // Treat invalid tokens as expired\r\n }\r\n }\r\n\r\n /**\r\n * Save tokens and user metadata after successful login\r\n */\r\n async saveTokens(\r\n accessToken: string,\r\n refreshToken: string,\r\n user: UserMetadata\r\n ): Promise<void> {\r\n setPassword(SERVICE_NAME, \"access_token\", accessToken);\r\n setPassword(SERVICE_NAME, \"refresh_token\", refreshToken);\r\n setPassword(SERVICE_NAME, \"user_metadata\", JSON.stringify(user));\r\n }\r\n\r\n /**\r\n * Get stored user metadata\r\n */\r\n async getUserMetadata(): Promise<UserMetadata | null> {\r\n try {\r\n const metadata = getPassword(SERVICE_NAME, \"user_metadata\");\r\n return metadata ? JSON.parse(metadata) : null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Logout - clear all stored credentials\r\n */\r\n async logout(): Promise<void> {\r\n try {\r\n deletePassword(SERVICE_NAME, \"access_token\");\r\n deletePassword(SERVICE_NAME, \"refresh_token\");\r\n deletePassword(SERVICE_NAME, \"user_metadata\");\r\n } catch (error) {\r\n // Ignore errors during logout\r\n }\r\n }\r\n\r\n /**\r\n * Check if user is currently authenticated\r\n */\r\n async isAuthenticated(): Promise<boolean> {\r\n const token = await this.getAccessToken();\r\n return token !== null;\r\n }\r\n}\r\n","import axios, { AxiosInstance } from \"axios\";\r\n\r\n// Production API URL (can be overridden via API_URL env for local dev)\r\nconst API_URL = process.env.API_URL || \"https://aerocoding.dev\";\r\n\r\ninterface User {\r\n id: string;\r\n email: string;\r\n name: string | null;\r\n tier: string;\r\n}\r\n\r\ninterface Organization {\r\n id: string;\r\n name: string;\r\n slug: string;\r\n planTier: string;\r\n}\r\n\r\ninterface Project {\r\n id: string;\r\n name: string;\r\n slug: string;\r\n schema: any;\r\n organizationId: string;\r\n backendFramework?: string;\r\n frontendFramework?: string;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\ninterface GeneratePayload {\r\n projectId: string;\r\n targets: string[];\r\n options?: {\r\n includeValidations?: boolean;\r\n includeComments?: boolean;\r\n includeAnnotations?: boolean;\r\n includeLogging?: boolean;\r\n includeTesting?: boolean;\r\n outputDir?: string;\r\n backendPreset?: string;\r\n frontendPreset?: string;\r\n backendLayers?: string[];\r\n frontendLayers?: string[];\r\n validationLib?: string;\r\n };\r\n}\r\n\r\ninterface GeneratedFile {\r\n path: string;\r\n content: string;\r\n language: string;\r\n entityId?: string;\r\n}\r\n\r\ninterface GenerateResult {\r\n files: GeneratedFile[];\r\n stats: {\r\n totalFiles: number;\r\n totalEntities: number;\r\n languages: string[];\r\n };\r\n cliCommand?: string;\r\n warnings?: string[];\r\n creditsUsed?: number;\r\n creditsRemaining?: number;\r\n}\r\n\r\ninterface CreditUsage {\r\n used: number;\r\n limit: number;\r\n bonusCredits: number;\r\n remaining: number;\r\n}\r\n\r\ninterface ArchitectureLayer {\r\n id: string;\r\n name: string;\r\n category: string;\r\n description?: string;\r\n}\r\n\r\ninterface Architecture {\r\n id: string;\r\n name: string;\r\n description: string;\r\n layers: ArchitectureLayer[];\r\n}\r\n\r\n// New Template Registry Types\r\ninterface TemplateMetadata {\r\n id: string;\r\n name: string;\r\n description: string;\r\n category: \"backend\" | \"frontend\" | \"database\" | \"infra\";\r\n language: string;\r\n framework: string;\r\n tier: \"starter\" | \"standard\" | \"enterprise\";\r\n tags: string[];\r\n version: string;\r\n author: string;\r\n isLegacy?: boolean;\r\n isOfficial?: boolean;\r\n isPremium?: boolean;\r\n}\r\n\r\ninterface TemplateLayer {\r\n id: string;\r\n name: string;\r\n description: string;\r\n category: string;\r\n enabled: boolean;\r\n}\r\n\r\ninterface TemplateFeatureFlag {\r\n id: string;\r\n name: string;\r\n label: string;\r\n description?: string;\r\n defaultValue: boolean;\r\n}\r\n\r\ninterface FullTemplate extends TemplateMetadata {\r\n layers: TemplateLayer[];\r\n featureFlags: TemplateFeatureFlag[];\r\n enabledModules: string[];\r\n}\r\n\r\ninterface TemplateFilter {\r\n category?: \"backend\" | \"frontend\" | \"database\" | \"infra\";\r\n language?: string;\r\n framework?: string;\r\n tier?: \"starter\" | \"standard\" | \"enterprise\";\r\n tags?: string[];\r\n}\r\n\r\ninterface TemplateSearchResult {\r\n templates: TemplateMetadata[];\r\n total: number;\r\n page: number;\r\n pageSize: number;\r\n}\r\n\r\ninterface TemplateCombination {\r\n id: string;\r\n name: string;\r\n description: string;\r\n backend: string;\r\n frontend: string;\r\n sharedTypes?: boolean;\r\n apiContract?: \"rest\" | \"graphql\" | \"grpc\";\r\n}\r\n\r\ninterface CreditEstimate {\r\n estimatedCredits: number;\r\n totalFiles: number;\r\n files: string[];\r\n entities: number;\r\n}\r\n\r\ninterface EstimatePayload {\r\n projectId: string;\r\n targets: string[];\r\n options?: {\r\n outputDir?: string;\r\n backendPreset?: string;\r\n frontendPreset?: string;\r\n backendLayers?: string[];\r\n frontendLayers?: string[];\r\n };\r\n}\r\n\r\n/**\r\n * ApiClient\r\n *\r\n * Authenticated HTTP client for AeroCoding API\r\n * All requests include Bearer token authentication\r\n */\r\nexport class ApiClient {\r\n private client: AxiosInstance;\r\n\r\n constructor(\r\n accessToken: string,\r\n options?: {\r\n onUnauthorized?: () => Promise<void> | void;\r\n }\r\n ) {\r\n this.client = axios.create({\r\n baseURL: API_URL,\r\n headers: {\r\n Authorization: `Bearer ${accessToken}`,\r\n \"Content-Type\": \"application/json\",\r\n \"X-Requested-With\": \"XMLHttpRequest\", // Required for CSRF validation bypass\r\n },\r\n timeout: 30000, // 30 seconds\r\n });\r\n\r\n this.client.interceptors.response.use(\r\n (response) => response,\r\n async (error) => {\r\n if (error?.response?.status === 401) {\r\n await options?.onUnauthorized?.();\r\n }\r\n\r\n return Promise.reject(error);\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Get current authenticated user\r\n */\r\n async getCurrentUser(): Promise<User> {\r\n const response = await this.client.get(\"/api/user/me\");\r\n return response.data;\r\n }\r\n\r\n /**\r\n * List user's organizations\r\n */\r\n async listOrganizations(): Promise<Organization[]> {\r\n const response = await this.client.get(\"/api/organizations\");\r\n return response.data;\r\n }\r\n\r\n /**\r\n * List user's projects\r\n */\r\n async listProjects(organizationId?: string): Promise<Project[]> {\r\n const response = await this.client.get(\"/api/projects\", {\r\n params: { organizationId },\r\n });\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Get project by ID\r\n */\r\n async getProject(projectId: string): Promise<Project> {\r\n const response = await this.client.get(`/api/projects/${projectId}`);\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Generate code from project schema\r\n */\r\n async generateCode(payload: GeneratePayload): Promise<GenerateResult> {\r\n const response = await this.client.post(\"/api/generate\", payload);\r\n return response.data.data;\r\n }\r\n\r\n /**\r\n * Get credit usage for organization\r\n */\r\n async getCreditUsage(organizationId: string): Promise<CreditUsage> {\r\n const response = await this.client.get(\"/api/credits/usage\", {\r\n params: { organizationId },\r\n });\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Get available architectures for a framework\r\n */\r\n async getArchitectures(framework: string): Promise<Architecture[]> {\r\n const response = await this.client.get(\"/api/architectures\", {\r\n params: { framework },\r\n });\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Estimate credit cost for a generation request\r\n */\r\n async estimateCreditCost(payload: EstimatePayload): Promise<CreditEstimate> {\r\n const response = await this.client.post(\"/api/generate/estimate\", payload);\r\n return response.data.data;\r\n }\r\n\r\n // ============================================\r\n // Template Registry API\r\n // ============================================\r\n\r\n /**\r\n * Search templates with filters\r\n */\r\n async getTemplates(filter: TemplateFilter = {}): Promise<TemplateSearchResult> {\r\n const params = new URLSearchParams();\r\n if (filter.category) params.set(\"category\", filter.category);\r\n if (filter.language) params.set(\"language\", filter.language);\r\n if (filter.framework) params.set(\"framework\", filter.framework);\r\n if (filter.tier) params.set(\"tier\", filter.tier);\r\n if (filter.tags?.length) params.set(\"tags\", filter.tags.join(\",\"));\r\n\r\n const response = await this.client.get(`/api/templates?${params.toString()}`);\r\n return response.data;\r\n }\r\n\r\n /**\r\n * Get full template by ID (includes layers and feature flags)\r\n */\r\n async getTemplate(id: string): Promise<FullTemplate> {\r\n const response = await this.client.get(`/api/templates/${id}?full=true`);\r\n return response.data.template;\r\n }\r\n\r\n /**\r\n * Get template combinations (backend + frontend pairs)\r\n */\r\n async getTemplateCombinations(): Promise<TemplateCombination[]> {\r\n const response = await this.client.get(\"/api/templates/combinations\");\r\n return response.data.combinations;\r\n }\r\n\r\n /**\r\n * Get templates compatible with a given template\r\n */\r\n async getCompatibleTemplates(templateId: string): Promise<TemplateMetadata[]> {\r\n const response = await this.client.get(`/api/templates/${templateId}?compatible=true`);\r\n return response.data.compatible || [];\r\n }\r\n}\r\n","import { ApiClient } from \"../../api/client.js\";\r\nimport { TokenManager } from \"../../auth/token-manager.js\";\r\n\r\nexport function createApiClientWithAutoLogout(\r\n accessToken: string,\r\n tokenManager: TokenManager\r\n): ApiClient {\r\n return new ApiClient(accessToken, {\r\n onUnauthorized: async () => {\r\n await tokenManager.logout();\r\n },\r\n });\r\n}\r\n","import chalk from \"chalk\";\r\nimport { TokenManager } from \"../../auth/token-manager.js\";\r\n\r\nexport async function handleUnauthorized(\r\n tokenManager: TokenManager\r\n): Promise<never> {\r\n await tokenManager.logout();\r\n\r\n console.error(\r\n chalk.yellow(\r\n \" Your session is invalid or expired. You have been logged out.\"\r\n )\r\n );\r\n console.error(chalk.gray(\" Run 'aerocoding login' to authenticate.\"));\r\n\r\n process.exit(1);\r\n}\r\n","import chalk from \"chalk\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\n\r\n/**\r\n * Logout Command\r\n *\r\n * Clears stored credentials from OS credential manager\r\n */\r\nexport async function logoutCommand() {\r\n const tokenManager = new TokenManager();\r\n\r\n const metadata = await tokenManager.getUserMetadata();\r\n if (!metadata) {\r\n console.log(chalk.yellow(\"Not logged in\"));\r\n return;\r\n }\r\n\r\n const email = metadata.email;\r\n\r\n await tokenManager.logout();\r\n\r\n console.log(chalk.green(\"Logged out successfully\"));\r\n console.log(chalk.gray(` Cleared credentials for ${email}\\n`));\r\n}\r\n","import chalk from \"chalk\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\nimport { createApiClientWithAutoLogout } from \"./_shared/create-api-client.js\";\r\nimport { handleUnauthorized } from \"./_shared/unauthorized.js\";\r\n\r\n/**\r\n * Whoami Command\r\n *\r\n * Shows current authenticated user information\r\n */\r\nexport async function whoamiCommand() {\r\n const tokenManager = new TokenManager();\r\n const token = await tokenManager.getAccessToken();\r\n\r\n if (!token) {\r\n console.log(chalk.red(\"Not logged in\"));\r\n console.log(chalk.gray(\" Run 'aerocoding login' to authenticate\\n\"));\r\n return;\r\n }\r\n\r\n try {\r\n const apiClient = createApiClientWithAutoLogout(token, tokenManager);\r\n const user = await apiClient.getCurrentUser();\r\n\r\n console.log(\"\");\r\n console.log(chalk.white(\"Logged in as:\"), chalk.cyan.bold(user.email));\r\n if (user.name) {\r\n console.log(chalk.gray(\" Name:\"), user.name);\r\n }\r\n console.log(\"\");\r\n } catch (error: any) {\r\n console.error(chalk.red(\"Failed to get user info\"));\r\n if (error.response?.status === 401) {\r\n await handleUnauthorized(tokenManager);\r\n }\r\n process.exit(1);\r\n }\r\n}\r\n","import chalk from \"chalk\";\r\nimport ora from \"ora\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\nimport { createApiClientWithAutoLogout } from \"./_shared/create-api-client.js\";\r\nimport { handleUnauthorized } from \"./_shared/unauthorized.js\";\r\nimport { writeGeneratedFiles } from \"../utils/file-writer.js\";\r\nimport { promptConfirm } from \"../utils/prompt.js\";\r\nimport { loadConfig } from \"../config/loader.js\";\r\nimport type { AerocodingConfig } from \"../config/schema.js\";\r\n\r\n/**\r\n * Map preset name to generator target\r\n * Presets follow naming convention: {architecture}-{language}-{variant}\r\n * e.g., \"clean-architecture-dotnet-complete\" → \"dotnet-entity\"\r\n */\r\nfunction mapPresetToTarget(preset: string): string | null {\r\n const presetLower = preset.toLowerCase();\r\n\r\n // .NET presets\r\n if (presetLower.includes(\"dotnet\") || presetLower.includes(\"aspnet\") || presetLower.includes(\"csharp\")) {\r\n return \"dotnet-entity\";\r\n }\r\n\r\n // Dart/Flutter presets\r\n if (presetLower.includes(\"dart\") || presetLower.includes(\"flutter\")) {\r\n return \"dart-entity\";\r\n }\r\n\r\n // TypeScript presets\r\n if (presetLower.includes(\"typescript\") || presetLower.includes(\"nextjs\") || presetLower.includes(\"react\")) {\r\n return \"typescript-interface\";\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Build targets array from config file\r\n * Maps backend/frontend presets to appropriate target types\r\n */\r\nfunction buildTargetsFromConfig(config: AerocodingConfig | null): string[] {\r\n if (!config) return [];\r\n\r\n const targets: string[] = [];\r\n\r\n // Add backend targets based on preset\r\n if (config.backend?.preset) {\r\n const target = mapPresetToTarget(config.backend.preset);\r\n if (target) {\r\n targets.push(target);\r\n }\r\n }\r\n\r\n // Add frontend targets based on preset\r\n if (config.frontend?.preset) {\r\n const target = mapPresetToTarget(config.frontend.preset);\r\n if (target) {\r\n targets.push(target);\r\n }\r\n }\r\n\r\n return targets;\r\n}\r\n\r\ninterface GenerateOptions {\r\n project?: string;\r\n targets?: string[];\r\n entities?: string[];\r\n output: string;\r\n // Presets\r\n backendPreset?: string;\r\n frontendPreset?: string;\r\n backendLayers?: string[];\r\n frontendLayers?: string[];\r\n // Style toggles (commander inverts for --no-X, all default to true)\r\n validations?: boolean;\r\n comments?: boolean;\r\n annotations?: boolean;\r\n logging?: boolean;\r\n testing?: boolean;\r\n // Validation library (framework-agnostic)\r\n validationLib?: string;\r\n // Control\r\n yes?: boolean;\r\n}\r\n\r\n/**\r\n * Generate Command\r\n *\r\n * Generates code from project schema via API\r\n * Consumes credits based on generated files and entity complexity\r\n *\r\n * Config file (.aerocodingrc.json) provides defaults, CLI args override\r\n */\r\nexport async function generateCommand(options: GenerateOptions) {\r\n // 1. Check authentication\r\n const tokenManager = new TokenManager();\r\n const token = await tokenManager.getAccessToken();\r\n\r\n if (!token) {\r\n console.log(chalk.red(\"\\n Not authenticated\"));\r\n console.log(chalk.gray(\" Run 'aerocoding login' to get started\\n\"));\r\n process.exit(1);\r\n }\r\n\r\n // 2. Load config file (optional)\r\n const config = await loadConfig();\r\n\r\n // 3. Merge config with CLI options (CLI overrides config)\r\n const projectId = options.project || config?.project;\r\n\r\n if (!projectId) {\r\n console.log(chalk.red(\"\\n Project ID required\"));\r\n console.log(chalk.gray(\" Run 'aerocoding init' to create a config file\"));\r\n console.log(chalk.gray(\" Or use --project <id> to specify a project\\n\"));\r\n process.exit(1);\r\n }\r\n\r\n // Build targets from config if not provided via CLI\r\n const targets = options.targets || buildTargetsFromConfig(config);\r\n\r\n // Merge other options with config defaults\r\n const output = options.output || config?.output || \"./.aerocoding\";\r\n const backendPreset = options.backendPreset || config?.backend?.preset;\r\n const frontendPreset = options.frontendPreset || config?.frontend?.preset;\r\n const backendLayers = options.backendLayers || config?.backend?.layers;\r\n const frontendLayers = options.frontendLayers || config?.frontend?.layers;\r\n const validationLib = options.validationLib || config?.libraries?.validation;\r\n\r\n // Style options: CLI --no-X overrides config, config overrides default (true)\r\n const includeValidations = options.validations ?? config?.codeStyle?.includeValidations ?? true;\r\n const includeComments = options.comments ?? config?.codeStyle?.includeComments ?? true;\r\n const includeAnnotations = options.annotations ?? config?.codeStyle?.includeAnnotations ?? true;\r\n const includeLogging = options.logging ?? config?.codeStyle?.includeLogging ?? true;\r\n const includeTesting = options.testing ?? config?.codeStyle?.includeTesting ?? true;\r\n\r\n const apiClient = createApiClientWithAutoLogout(token, tokenManager);\r\n\r\n let spinner = ora({ text: \"Fetching project...\", color: \"cyan\" }).start();\r\n\r\n try {\r\n // 4. Fetch project to get organizationId\r\n const project = await apiClient.getProject(projectId);\r\n spinner.succeed(chalk.gray(`Project: ${project.name}`));\r\n\r\n // 5. Fetch credit usage and estimate cost in parallel\r\n spinner = ora({ text: \"Checking credits...\", color: \"cyan\" }).start();\r\n\r\n const credits = await apiClient.getCreditUsage(project.organizationId);\r\n\r\n // Try to get cost estimate (may fail if endpoint not deployed yet)\r\n let estimate: { estimatedCredits: number; totalFiles: number; entities: number } | null = null;\r\n try {\r\n estimate = await apiClient.estimateCreditCost({\r\n projectId,\r\n targets,\r\n options: {\r\n outputDir: output,\r\n backendPreset,\r\n frontendPreset,\r\n backendLayers,\r\n frontendLayers,\r\n },\r\n });\r\n } catch {\r\n // Estimate endpoint may not be available yet - continue without estimate\r\n }\r\n\r\n spinner.succeed(chalk.gray(`Credits: ${credits.remaining} / ${credits.limit} available`));\r\n\r\n // Check if project has entities (required for generation)\r\n if (estimate && estimate.entities === 0) {\r\n console.log(chalk.yellow(\"\\n ⚠ No entities found in this project.\"));\r\n console.log(chalk.gray(\" Create entities in the diagram editor and save (Ctrl+S) before generating.\\n\"));\r\n process.exit(1);\r\n }\r\n\r\n // Check if enough credits before showing summary (skip if no estimate)\r\n const hasEnoughCredits = estimate ? credits.remaining >= estimate.estimatedCredits : true;\r\n\r\n // 6. Show summary\r\n console.log(\"\");\r\n console.log(chalk.bold(\" Generation Summary\"));\r\n console.log(chalk.gray(\" ─────────────────────────────────\"));\r\n console.log(chalk.gray(\" Project:\"), chalk.white(project.name));\r\n if (config) {\r\n console.log(chalk.gray(\" Config:\"), chalk.cyan(\".aerocodingrc.json\"));\r\n }\r\n console.log(\r\n chalk.gray(\" Targets:\"),\r\n chalk.cyan(targets.length > 0 ? targets.join(\", \") : \"default\")\r\n );\r\n\r\n if (backendPreset) {\r\n console.log(chalk.gray(\" Backend Preset:\"), chalk.cyan(backendPreset));\r\n }\r\n if (frontendPreset) {\r\n console.log(chalk.gray(\" Frontend Preset:\"), chalk.cyan(frontendPreset));\r\n }\r\n\r\n // Show style options if different from defaults (all default to true)\r\n const disabledOptions: string[] = [];\r\n if (!includeValidations) disabledOptions.push(\"validations\");\r\n if (!includeComments) disabledOptions.push(\"comments\");\r\n if (!includeAnnotations) disabledOptions.push(\"annotations\");\r\n if (!includeLogging) disabledOptions.push(\"logging\");\r\n if (!includeTesting) disabledOptions.push(\"testing\");\r\n\r\n if (disabledOptions.length > 0) {\r\n console.log(chalk.gray(\" Disabled:\"), chalk.yellow(disabledOptions.join(\", \")));\r\n }\r\n\r\n if (validationLib) {\r\n console.log(chalk.gray(\" Validation Lib:\"), chalk.cyan(validationLib));\r\n }\r\n\r\n // Show estimate info (if available)\r\n if (estimate) {\r\n console.log(chalk.gray(\" Entities:\"), chalk.cyan(estimate.entities));\r\n console.log(chalk.gray(\" Files:\"), chalk.cyan(estimate.totalFiles));\r\n }\r\n\r\n console.log(\"\");\r\n console.log(chalk.bold(\" Credits\"));\r\n console.log(chalk.gray(\" ─────────────────────────────────\"));\r\n if (estimate) {\r\n console.log(\r\n chalk.white(\" Cost:\"),\r\n hasEnoughCredits\r\n ? chalk.bold.yellow(`${estimate.estimatedCredits} credits`)\r\n : chalk.bold.red(`${estimate.estimatedCredits} credits`)\r\n );\r\n }\r\n console.log(\r\n chalk.white(\" Available:\"),\r\n hasEnoughCredits\r\n ? chalk.bold.green(`${credits.remaining} credits`)\r\n : chalk.bold.red(`${credits.remaining} credits (insufficient)`)\r\n );\r\n console.log(chalk.gray(\" Output:\"), chalk.cyan(output));\r\n console.log(\"\");\r\n\r\n // Warn if not enough credits\r\n if (!hasEnoughCredits && estimate) {\r\n console.log(chalk.red(\" ⚠ Not enough credits for this generation.\"));\r\n console.log(chalk.gray(` Need ${estimate.estimatedCredits - credits.remaining} more credits.\\n`));\r\n process.exit(1);\r\n }\r\n\r\n // 7. Confirmation (unless --yes)\r\n if (!options.yes) {\r\n const confirmed = await promptConfirm(\" Proceed with generation?\");\r\n if (!confirmed) {\r\n console.log(chalk.yellow(\"\\n Generation cancelled\\n\"));\r\n process.exit(0);\r\n }\r\n }\r\n\r\n // 8. Call API\r\n console.log(\"\");\r\n spinner = ora({ text: \"Generating code...\", color: \"cyan\" }).start();\r\n\r\n const result = await apiClient.generateCode({\r\n projectId,\r\n targets,\r\n options: {\r\n includeValidations,\r\n includeComments,\r\n includeAnnotations,\r\n includeLogging,\r\n includeTesting,\r\n outputDir: output,\r\n backendPreset,\r\n frontendPreset,\r\n backendLayers,\r\n frontendLayers,\r\n validationLib,\r\n },\r\n });\r\n\r\n spinner.succeed(chalk.green(\"Code generated successfully!\"));\r\n\r\n // 9. Show results with credits\r\n console.log(\"\");\r\n console.log(chalk.bold(\" Results\"));\r\n console.log(chalk.gray(\" ─────────────────────────────────\"));\r\n console.log(chalk.gray(\" Files:\"), chalk.cyan(result.stats.totalFiles));\r\n console.log(chalk.gray(\" Entities:\"), chalk.cyan(result.stats.totalEntities));\r\n console.log(\r\n chalk.gray(\" Languages:\"),\r\n chalk.cyan(result.stats.languages.join(\", \"))\r\n );\r\n\r\n if (result.creditsUsed !== undefined) {\r\n console.log(\"\");\r\n console.log(chalk.bold(\" Credits\"));\r\n console.log(chalk.gray(\" ─────────────────────────────────\"));\r\n console.log(chalk.gray(\" Used:\"), chalk.yellow(result.creditsUsed));\r\n console.log(\r\n chalk.gray(\" Remaining:\"),\r\n result.creditsRemaining !== undefined && result.creditsRemaining > 50\r\n ? chalk.green(result.creditsRemaining)\r\n : chalk.yellow(result.creditsRemaining)\r\n );\r\n }\r\n\r\n // Show warnings if any\r\n if (result.warnings && result.warnings.length > 0) {\r\n console.log(\"\");\r\n console.log(chalk.yellow(\" Warnings:\"));\r\n for (const warning of result.warnings) {\r\n console.log(chalk.yellow(` - ${warning}`));\r\n }\r\n }\r\n\r\n console.log(\"\");\r\n\r\n // 10. Write files to disk\r\n await writeGeneratedFiles(result.files, output);\r\n\r\n console.log(chalk.green(` Files written to ${chalk.white(output)}`));\r\n console.log(\"\");\r\n } catch (error: any) {\r\n spinner.fail(chalk.red(\"Generation failed\"));\r\n\r\n if (error.response?.status === 401) {\r\n await handleUnauthorized(tokenManager);\r\n } else if (error.response?.status === 403) {\r\n console.log(chalk.yellow(\"\\n You don't have permission to access this project.\"));\r\n console.log(chalk.gray(\" Check if you're part of the organization.\\n\"));\r\n } else if (error.response?.status === 404) {\r\n console.log(chalk.yellow(\"\\n Project not found.\"));\r\n console.log(chalk.gray(\" Check if the project ID is correct.\\n\"));\r\n } else if (error.response?.status === 429) {\r\n // Insufficient credits\r\n const data = error.response.data;\r\n console.log(chalk.red(\"\\n Insufficient credits\"));\r\n if (data.requiredCredits) {\r\n console.log(chalk.yellow(` Required: ${data.requiredCredits} credits`));\r\n }\r\n console.log(chalk.yellow(` Available: ${data.remaining ?? 0} credits`));\r\n console.log(chalk.gray(\"\\n Upgrade your plan or wait for credit reset.\\n\"));\r\n } else if (error.response?.data?.message) {\r\n console.log(chalk.red(`\\n ${error.response.data.message}\\n`));\r\n } else {\r\n console.log(chalk.red(`\\n ${error.message}\\n`));\r\n }\r\n\r\n process.exit(1);\r\n }\r\n}\r\n","import fs from \"fs/promises\";\r\nimport path from \"path\";\r\nimport chalk from \"chalk\";\r\n\r\ninterface GeneratedFile {\r\n path: string;\r\n content: string;\r\n language: string;\r\n entityId?: string;\r\n}\r\n\r\n/**\r\n * Validate that a file path is safe and doesn't escape the output directory.\r\n * SECURITY: Prevents path traversal attacks (e.g., ../../../etc/passwd)\r\n */\r\nfunction isPathSafe(outputDir: string, filePath: string): boolean {\r\n // Resolve both paths to absolute paths\r\n const resolvedOutput = path.resolve(outputDir);\r\n const resolvedFile = path.resolve(outputDir, filePath);\r\n\r\n // Check if the resolved file path starts with the output directory\r\n // Also ensure there's a path separator after the base to prevent\r\n // matching \"output\" when file is in \"output-malicious\"\r\n return (\r\n resolvedFile.startsWith(resolvedOutput + path.sep) ||\r\n resolvedFile === resolvedOutput\r\n );\r\n}\r\n\r\n/**\r\n * Write generated files to disk\r\n *\r\n * Creates directories as needed and writes files\r\n * Shows progress for each file\r\n */\r\nexport async function writeGeneratedFiles(\r\n files: GeneratedFile[],\r\n outputDir: string\r\n): Promise<void> {\r\n for (const file of files) {\r\n // SECURITY: Validate path doesn't escape output directory\r\n if (!isPathSafe(outputDir, file.path)) {\r\n console.error(\r\n chalk.red(` Skipping unsafe path: ${file.path}`)\r\n );\r\n console.error(\r\n chalk.gray(` Path traversal detected - file path must be within output directory`)\r\n );\r\n continue;\r\n }\r\n\r\n const fullPath = path.resolve(outputDir, file.path);\r\n const dir = path.dirname(fullPath);\r\n\r\n try {\r\n // Create directory if doesn't exist\r\n await fs.mkdir(dir, { recursive: true });\r\n\r\n // Write file\r\n await fs.writeFile(fullPath, file.content, \"utf-8\");\r\n\r\n console.log(chalk.gray(` ${file.path}`));\r\n } catch (error: any) {\r\n console.error(chalk.red(` Failed to write ${file.path}`));\r\n console.error(chalk.gray(` ${error.message}`));\r\n }\r\n }\r\n}\r\n","import readline from \"readline\";\r\nimport chalk from \"chalk\";\r\n\r\n/**\r\n * Prompt user for confirmation\r\n * Returns true if user confirms (Y/yes/enter), false if they decline (n/no)\r\n */\r\nexport function promptConfirm(message: string): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const rl = readline.createInterface({\r\n input: process.stdin,\r\n output: process.stdout,\r\n });\r\n\r\n rl.question(chalk.yellow(`${message} [Y/n] `), (answer) => {\r\n rl.close();\r\n const normalized = answer.trim().toLowerCase();\r\n // Empty input (just pressing Enter) means \"yes\"\r\n resolve(normalized !== \"n\" && normalized !== \"no\");\r\n });\r\n });\r\n}\r\n","import fs from \"fs/promises\";\r\nimport path from \"path\";\r\nimport { configSchema, CONFIG_FILENAME, type AerocodingConfig } from \"./schema.js\";\r\n\r\nexport async function loadConfig(\r\n dir: string = process.cwd()\r\n): Promise<AerocodingConfig | null> {\r\n const configPath = path.join(dir, CONFIG_FILENAME);\r\n\r\n try {\r\n const content = await fs.readFile(configPath, \"utf-8\");\r\n const parsed = JSON.parse(content);\r\n return configSchema.parse(parsed);\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\r\n return null;\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function saveConfig(\r\n config: AerocodingConfig,\r\n dir: string = process.cwd()\r\n): Promise<void> {\r\n const configPath = path.join(dir, CONFIG_FILENAME);\r\n const content = JSON.stringify(\r\n {\r\n $schema: \"https://aerocoding.dev/schemas/aerocodingrc.json\",\r\n ...config,\r\n },\r\n null,\r\n 2\r\n );\r\n await fs.writeFile(configPath, content, \"utf-8\");\r\n}\r\n\r\nexport async function configExists(dir: string = process.cwd()): Promise<boolean> {\r\n const configPath = path.join(dir, CONFIG_FILENAME);\r\n try {\r\n await fs.access(configPath);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport { type AerocodingConfig, CONFIG_FILENAME } from \"./schema.js\";\r\n","import { z } from \"zod\";\r\n\r\nexport const configSchema = z.object({\r\n $schema: z.string().optional(),\r\n project: z.string().uuid(),\r\n output: z.string().default(\"./.aerocoding\"),\r\n\r\n backend: z\r\n .object({\r\n preset: z.string(),\r\n layers: z.array(z.string()),\r\n })\r\n .optional(),\r\n\r\n frontend: z\r\n .object({\r\n preset: z.string(),\r\n layers: z.array(z.string()),\r\n })\r\n .optional(),\r\n\r\n codeStyle: z\r\n .object({\r\n includeValidations: z.boolean().default(true),\r\n includeComments: z.boolean().default(true),\r\n includeAnnotations: z.boolean().default(true),\r\n includeLogging: z.boolean().default(true),\r\n includeTesting: z.boolean().default(true),\r\n })\r\n .default({}),\r\n\r\n libraries: z\r\n .object({\r\n validation: z.string().optional(),\r\n logging: z.string().optional(),\r\n })\r\n .optional(),\r\n\r\n excludePatterns: z.array(z.string()).optional(),\r\n});\r\n\r\nexport type AerocodingConfig = z.infer<typeof configSchema>;\r\n\r\nexport const CONFIG_FILENAME = \".aerocodingrc.json\";\r\n","import * as p from \"@clack/prompts\";\r\nimport chalk from \"chalk\";\r\nimport { TokenManager } from \"../auth/token-manager.js\";\r\nimport { createApiClientWithAutoLogout } from \"./_shared/create-api-client.js\";\r\nimport { handleUnauthorized } from \"./_shared/unauthorized.js\";\r\nimport { saveConfig, configExists } from \"../config/loader.js\";\r\nimport type { AerocodingConfig } from \"../config/schema.js\";\r\n\r\ninterface InitOptions {\r\n project?: string;\r\n force?: boolean;\r\n}\r\n\r\n/**\r\n * Init Command\r\n *\r\n * Interactive wizard to initialize AeroCoding in current directory\r\n * Creates .aerocodingrc.json config file\r\n */\r\nexport async function initCommand(options: InitOptions) {\r\n p.intro(chalk.bgCyan.black(\" AeroCoding CLI \"));\r\n\r\n // Check if config already exists\r\n if (!options.force && (await configExists())) {\r\n const overwrite = await p.confirm({\r\n message: \"Config file already exists. Overwrite?\",\r\n initialValue: false,\r\n });\r\n\r\n if (p.isCancel(overwrite) || !overwrite) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n }\r\n\r\n // 1. Check authentication\r\n const tokenManager = new TokenManager();\r\n const token = await tokenManager.getAccessToken();\r\n\r\n if (!token) {\r\n p.cancel(\"Not logged in. Run 'aerocoding login' first.\");\r\n process.exit(1);\r\n }\r\n\r\n const apiClient = createApiClientWithAutoLogout(token, tokenManager);\r\n\r\n try {\r\n // 2. Select organization first\r\n const orgSpinner = p.spinner();\r\n orgSpinner.start(\"Loading organizations...\");\r\n\r\n const organizations = await apiClient.listOrganizations();\r\n orgSpinner.stop(\"Organizations loaded\");\r\n\r\n if (organizations.length === 0) {\r\n p.cancel(\"No organizations found. Create one on aerocoding.dev first.\");\r\n process.exit(1);\r\n }\r\n\r\n let organizationId: string;\r\n\r\n if (organizations.length === 1) {\r\n // Auto-select if only one org\r\n organizationId = organizations[0].id;\r\n p.log.info(`Organization: ${organizations[0].name}`);\r\n } else {\r\n const selectedOrg = await p.select({\r\n message: \"Select organization\",\r\n options: organizations.map((org) => ({\r\n value: org.id,\r\n label: org.name,\r\n hint: org.planTier.toUpperCase(),\r\n })),\r\n });\r\n\r\n if (p.isCancel(selectedOrg)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n organizationId = selectedOrg as string;\r\n }\r\n\r\n // 3. Select project from organization\r\n let projectId = options.project;\r\n\r\n if (!projectId) {\r\n const spinner = p.spinner();\r\n spinner.start(\"Loading projects...\");\r\n\r\n const projects = await apiClient.listProjects(organizationId);\r\n spinner.stop(\"Projects loaded\");\r\n\r\n if (projects.length === 0) {\r\n p.cancel(\"No projects in this organization. Create one on aerocoding.dev first.\");\r\n process.exit(1);\r\n }\r\n\r\n const selectedProject = await p.select({\r\n message: \"Select project\",\r\n options: projects.map((proj) => ({\r\n value: proj.id,\r\n label: proj.name,\r\n hint: [proj.backendFramework, proj.frontendFramework].filter(Boolean).join(\" + \"),\r\n })),\r\n });\r\n\r\n if (p.isCancel(selectedProject)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n projectId = selectedProject as string;\r\n }\r\n\r\n // 4. Fetch project details\r\n const spinner = p.spinner();\r\n spinner.start(\"Fetching project details...\");\r\n const project = await apiClient.getProject(projectId);\r\n spinner.stop(`Project: ${project.name}`);\r\n\r\n // Build target options based on project frameworks\r\n const targetOptions: { value: string; label: string }[] = [];\r\n if (project.backendFramework) {\r\n targetOptions.push({\r\n value: \"backend\",\r\n label: `Backend (${project.backendFramework})`,\r\n });\r\n }\r\n if (project.frontendFramework) {\r\n targetOptions.push({\r\n value: \"frontend\",\r\n label: `Frontend (${project.frontendFramework})`,\r\n });\r\n }\r\n\r\n if (targetOptions.length === 0) {\r\n p.cancel(\"Project has no frameworks configured. Update it on aerocoding.dev first.\");\r\n process.exit(1);\r\n }\r\n\r\n // 4. Select what to generate\r\n const targets = await p.multiselect({\r\n message: \"What do you want to generate?\",\r\n options: targetOptions,\r\n required: true,\r\n });\r\n\r\n if (p.isCancel(targets)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n const selectedTargets = targets as string[];\r\n\r\n // Initialize config\r\n const config: AerocodingConfig = {\r\n project: projectId,\r\n output: \"./.aerocoding\",\r\n codeStyle: {\r\n includeValidations: true,\r\n includeComments: true,\r\n includeAnnotations: true,\r\n includeLogging: true,\r\n includeTesting: true,\r\n },\r\n };\r\n\r\n // 5. Backend configuration\r\n if (selectedTargets.includes(\"backend\") && project.backendFramework) {\r\n const archSpinner = p.spinner();\r\n archSpinner.start(\"Loading backend templates...\");\r\n\r\n // Use new template registry API\r\n const templateResult = await apiClient.getTemplates({\r\n category: \"backend\",\r\n language: project.backendFramework,\r\n });\r\n archSpinner.stop(\"Templates loaded\");\r\n\r\n if (templateResult.templates.length > 0) {\r\n const preset = await p.select({\r\n message: \"Backend template\",\r\n options: templateResult.templates.map((tmpl) => ({\r\n value: tmpl.id,\r\n label: tmpl.name,\r\n hint: tmpl.description || `${tmpl.tier} tier`,\r\n })),\r\n });\r\n\r\n if (p.isCancel(preset)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n // Fetch full template with layers and feature flags\r\n const fullTemplate = await apiClient.getTemplate(preset as string);\r\n\r\n if (fullTemplate.layers && fullTemplate.layers.length > 0) {\r\n const layers = await p.multiselect({\r\n message: \"Select backend layers to include\",\r\n options: fullTemplate.layers.map((layer) => ({\r\n value: layer.id,\r\n label: layer.name,\r\n hint: layer.category,\r\n })),\r\n initialValues: fullTemplate.layers.filter((l) => l.enabled).map((l) => l.id),\r\n });\r\n\r\n if (p.isCancel(layers)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n config.backend = {\r\n preset: preset as string,\r\n layers: layers as string[],\r\n };\r\n } else {\r\n config.backend = {\r\n preset: preset as string,\r\n layers: [],\r\n };\r\n }\r\n }\r\n }\r\n\r\n // 6. Frontend configuration\r\n if (selectedTargets.includes(\"frontend\") && project.frontendFramework) {\r\n const archSpinner = p.spinner();\r\n archSpinner.start(\"Loading frontend templates...\");\r\n\r\n // Use new template registry API\r\n const templateResult = await apiClient.getTemplates({\r\n category: \"frontend\",\r\n framework: project.frontendFramework,\r\n });\r\n archSpinner.stop(\"Templates loaded\");\r\n\r\n if (templateResult.templates.length > 0) {\r\n const preset = await p.select({\r\n message: \"Frontend template\",\r\n options: templateResult.templates.map((tmpl) => ({\r\n value: tmpl.id,\r\n label: tmpl.name,\r\n hint: tmpl.description || `${tmpl.tier} tier`,\r\n })),\r\n });\r\n\r\n if (p.isCancel(preset)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n // Fetch full template with layers and feature flags\r\n const fullTemplate = await apiClient.getTemplate(preset as string);\r\n\r\n if (fullTemplate.layers && fullTemplate.layers.length > 0) {\r\n const layers = await p.multiselect({\r\n message: \"Select frontend layers to include\",\r\n options: fullTemplate.layers.map((layer) => ({\r\n value: layer.id,\r\n label: layer.name,\r\n hint: layer.category,\r\n })),\r\n initialValues: fullTemplate.layers.filter((l) => l.enabled).map((l) => l.id),\r\n });\r\n\r\n if (p.isCancel(layers)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n config.frontend = {\r\n preset: preset as string,\r\n layers: layers as string[],\r\n };\r\n } else {\r\n config.frontend = {\r\n preset: preset as string,\r\n layers: [],\r\n };\r\n }\r\n }\r\n }\r\n\r\n // 7. Code style options\r\n const codeStyleOptions = await p.multiselect({\r\n message: \"Code style options\",\r\n options: [\r\n { value: \"validations\", label: \"Include validations\", hint: \"Add validation rules\" },\r\n { value: \"comments\", label: \"Include comments\", hint: \"Add code documentation\" },\r\n { value: \"annotations\", label: \"Include annotations\", hint: \"Add decorators/attributes\" },\r\n { value: \"logging\", label: \"Include logging\", hint: \"Add log statements\" },\r\n { value: \"testing\", label: \"Include tests\", hint: \"Generate test files\" },\r\n ],\r\n initialValues: [\"validations\", \"comments\", \"annotations\", \"logging\", \"testing\"],\r\n });\r\n\r\n if (p.isCancel(codeStyleOptions)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n const selectedStyles = codeStyleOptions as string[];\r\n config.codeStyle = {\r\n includeValidations: selectedStyles.includes(\"validations\"),\r\n includeComments: selectedStyles.includes(\"comments\"),\r\n includeAnnotations: selectedStyles.includes(\"annotations\"),\r\n includeLogging: selectedStyles.includes(\"logging\"),\r\n includeTesting: selectedStyles.includes(\"testing\"),\r\n };\r\n\r\n // 8. Output directory\r\n const output = await p.text({\r\n message: \"Output directory\",\r\n initialValue: \"./.aerocoding\",\r\n validate: (value) => {\r\n if (!value) return \"Output directory is required\";\r\n return undefined;\r\n },\r\n });\r\n\r\n if (p.isCancel(output)) {\r\n p.cancel(\"Operation cancelled.\");\r\n process.exit(0);\r\n }\r\n\r\n config.output = output as string;\r\n\r\n // 9. Save config\r\n await saveConfig(config);\r\n\r\n p.outro(\r\n chalk.green(\"Config saved to .aerocodingrc.json\") +\r\n \"\\n\\n\" +\r\n chalk.gray(\" Run \") +\r\n chalk.cyan(\"aerocoding generate\") +\r\n chalk.gray(\" to generate code!\")\r\n );\r\n } catch (error: any) {\r\n if (error.response?.status === 401) {\r\n await handleUnauthorized(tokenManager);\r\n } else if (error.response?.data?.message) {\r\n p.cancel(error.response.data.message);\r\n } else {\r\n p.cancel(error.message || \"An unexpected error occurred\");\r\n }\r\n process.exit(1);\r\n }\r\n}\r\n","import chalk from \"chalk\";\r\n\r\ninterface PullOptions {\r\n project?: string;\r\n}\r\n\r\n/**\r\n * Pull Command (Stub)\r\n *\r\n * TODO: Pull schema from cloud\r\n * - Download project schema\r\n * - Save to .aerocoding/schema.json\r\n */\r\nexport async function pullCommand(options: PullOptions) {\r\n console.log(chalk.yellow(\"Command not yet implemented\"));\r\n if (options.project) {\r\n console.log(chalk.gray(` Requested project: ${options.project}`));\r\n }\r\n console.log(chalk.gray(\" Coming soon in v0.2.0\\n\"));\r\n}\r\n","import chalk from \"chalk\";\r\n\r\n/**\r\n * Status Command (Stub)\r\n *\r\n * TODO: Show local schema status\r\n * - Show current project\r\n * - Show schema stats\r\n * - Show sync status\r\n */\r\nexport async function statusCommand() {\r\n console.log(chalk.yellow(\"Command not yet implemented\"));\r\n console.log(chalk.gray(\" Coming soon in v0.2.0\\n\"));\r\n}\r\n"],"mappings":"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","names":["chalk","spinner","axios","API_URL","chalk","chalk","chalk","chalk","chalk","chalk","chalk","ora","chalk","chalk","fs","path","path","fs","chalk","spinner","ora","chalk","chalk","spinner","chalk","chalk"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aerocoding",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "AeroCoding CLI - Generate production-ready code from UML diagrams",
5
5
  "author": "AeroCoding Team",
6
6
  "license": "MIT",