alepha 0.13.8 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/dist/api/audits/index.d.ts +418 -338
  2. package/dist/api/audits/index.d.ts.map +1 -0
  3. package/dist/api/files/index.d.ts +81 -1
  4. package/dist/api/files/index.d.ts.map +1 -0
  5. package/dist/api/jobs/index.d.ts +107 -27
  6. package/dist/api/jobs/index.d.ts.map +1 -0
  7. package/dist/api/notifications/index.d.ts +21 -1
  8. package/dist/api/notifications/index.d.ts.map +1 -0
  9. package/dist/api/parameters/index.d.ts +455 -8
  10. package/dist/api/parameters/index.d.ts.map +1 -0
  11. package/dist/api/users/index.d.ts +844 -840
  12. package/dist/api/users/index.d.ts.map +1 -0
  13. package/dist/api/verifications/index.d.ts.map +1 -0
  14. package/dist/batch/index.d.ts.map +1 -0
  15. package/dist/bucket/index.d.ts.map +1 -0
  16. package/dist/cache/core/index.d.ts.map +1 -0
  17. package/dist/cache/redis/index.d.ts.map +1 -0
  18. package/dist/cli/index.d.ts +254 -59
  19. package/dist/cli/index.d.ts.map +1 -0
  20. package/dist/cli/index.js +499 -127
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/command/index.d.ts +217 -10
  23. package/dist/command/index.d.ts.map +1 -0
  24. package/dist/command/index.js +350 -74
  25. package/dist/command/index.js.map +1 -1
  26. package/dist/core/index.browser.js +1334 -1318
  27. package/dist/core/index.browser.js.map +1 -1
  28. package/dist/core/index.d.ts +76 -72
  29. package/dist/core/index.d.ts.map +1 -0
  30. package/dist/core/index.js +1337 -1321
  31. package/dist/core/index.js.map +1 -1
  32. package/dist/core/index.native.js +1337 -1321
  33. package/dist/core/index.native.js.map +1 -1
  34. package/dist/datetime/index.d.ts.map +1 -0
  35. package/dist/email/index.d.ts.map +1 -0
  36. package/dist/fake/index.d.ts.map +1 -0
  37. package/dist/file/index.d.ts.map +1 -0
  38. package/dist/file/index.js.map +1 -1
  39. package/dist/lock/core/index.d.ts.map +1 -0
  40. package/dist/lock/redis/index.d.ts.map +1 -0
  41. package/dist/logger/index.d.ts +1 -0
  42. package/dist/logger/index.d.ts.map +1 -0
  43. package/dist/mcp/index.d.ts +820 -0
  44. package/dist/mcp/index.d.ts.map +1 -0
  45. package/dist/mcp/index.js +978 -0
  46. package/dist/mcp/index.js.map +1 -0
  47. package/dist/orm/index.d.ts +234 -107
  48. package/dist/orm/index.d.ts.map +1 -0
  49. package/dist/orm/index.js +376 -316
  50. package/dist/orm/index.js.map +1 -1
  51. package/dist/queue/core/index.d.ts +4 -4
  52. package/dist/queue/core/index.d.ts.map +1 -0
  53. package/dist/queue/redis/index.d.ts.map +1 -0
  54. package/dist/queue/redis/index.js +2 -4
  55. package/dist/queue/redis/index.js.map +1 -1
  56. package/dist/redis/index.d.ts +400 -29
  57. package/dist/redis/index.d.ts.map +1 -0
  58. package/dist/redis/index.js +412 -21
  59. package/dist/redis/index.js.map +1 -1
  60. package/dist/retry/index.d.ts.map +1 -0
  61. package/dist/router/index.d.ts.map +1 -0
  62. package/dist/scheduler/index.d.ts +6 -6
  63. package/dist/scheduler/index.d.ts.map +1 -0
  64. package/dist/security/index.d.ts +28 -28
  65. package/dist/security/index.d.ts.map +1 -0
  66. package/dist/server/auth/index.d.ts +155 -155
  67. package/dist/server/auth/index.d.ts.map +1 -0
  68. package/dist/server/cache/index.d.ts.map +1 -0
  69. package/dist/server/compress/index.d.ts.map +1 -0
  70. package/dist/server/cookies/index.d.ts.map +1 -0
  71. package/dist/server/core/index.d.ts +0 -1
  72. package/dist/server/core/index.d.ts.map +1 -0
  73. package/dist/server/core/index.js.map +1 -1
  74. package/dist/server/cors/index.d.ts.map +1 -0
  75. package/dist/server/health/index.d.ts +17 -17
  76. package/dist/server/health/index.d.ts.map +1 -0
  77. package/dist/server/helmet/index.d.ts +4 -1
  78. package/dist/server/helmet/index.d.ts.map +1 -0
  79. package/dist/server/links/index.d.ts +33 -33
  80. package/dist/server/links/index.d.ts.map +1 -0
  81. package/dist/server/metrics/index.d.ts.map +1 -0
  82. package/dist/server/multipart/index.d.ts.map +1 -0
  83. package/dist/server/multipart/index.js.map +1 -1
  84. package/dist/server/proxy/index.d.ts.map +1 -0
  85. package/dist/server/proxy/index.js.map +1 -1
  86. package/dist/server/rate-limit/index.d.ts.map +1 -0
  87. package/dist/server/security/index.d.ts +9 -9
  88. package/dist/server/security/index.d.ts.map +1 -0
  89. package/dist/server/static/index.d.ts.map +1 -0
  90. package/dist/server/swagger/index.d.ts.map +1 -0
  91. package/dist/sms/index.d.ts.map +1 -0
  92. package/dist/thread/index.d.ts.map +1 -0
  93. package/dist/topic/core/index.d.ts.map +1 -0
  94. package/dist/topic/redis/index.d.ts.map +1 -0
  95. package/dist/topic/redis/index.js +3 -3
  96. package/dist/topic/redis/index.js.map +1 -1
  97. package/dist/vite/index.d.ts +10 -2
  98. package/dist/vite/index.d.ts.map +1 -0
  99. package/dist/vite/index.js +45 -20
  100. package/dist/vite/index.js.map +1 -1
  101. package/dist/websocket/index.d.ts.map +1 -0
  102. package/package.json +9 -4
  103. package/src/cli/apps/AlephaCli.ts +10 -3
  104. package/src/cli/apps/AlephaPackageBuilderCli.ts +15 -8
  105. package/src/cli/assets/mainTs.ts +9 -10
  106. package/src/cli/atoms/changelogOptions.ts +45 -0
  107. package/src/cli/commands/ChangelogCommands.ts +259 -0
  108. package/src/cli/commands/DeployCommands.ts +118 -0
  109. package/src/cli/commands/DrizzleCommands.ts +230 -10
  110. package/src/cli/commands/ViteCommands.ts +47 -23
  111. package/src/cli/defineConfig.ts +15 -0
  112. package/src/cli/index.ts +3 -0
  113. package/src/cli/services/AlephaCliUtils.ts +10 -154
  114. package/src/cli/services/GitMessageParser.ts +77 -0
  115. package/src/command/helpers/EnvUtils.ts +37 -0
  116. package/src/command/index.ts +3 -1
  117. package/src/command/primitives/$command.ts +172 -6
  118. package/src/command/providers/CliProvider.ts +499 -95
  119. package/src/core/Alepha.ts +1 -1
  120. package/src/core/providers/SchemaValidator.ts +23 -1
  121. package/src/file/providers/NodeFileSystemProvider.ts +3 -1
  122. package/src/mcp/errors/McpError.ts +72 -0
  123. package/src/mcp/helpers/jsonrpc.ts +163 -0
  124. package/src/mcp/index.ts +132 -0
  125. package/src/mcp/interfaces/McpTypes.ts +248 -0
  126. package/src/mcp/primitives/$prompt.ts +188 -0
  127. package/src/mcp/primitives/$resource.ts +171 -0
  128. package/src/mcp/primitives/$tool.ts +285 -0
  129. package/src/mcp/providers/McpServerProvider.ts +382 -0
  130. package/src/mcp/transports/SseMcpTransport.ts +172 -0
  131. package/src/mcp/transports/StdioMcpTransport.ts +126 -0
  132. package/src/orm/index.ts +20 -4
  133. package/src/orm/interfaces/PgQueryWhere.ts +1 -26
  134. package/src/orm/providers/drivers/BunPostgresProvider.ts +225 -0
  135. package/src/orm/providers/drivers/BunSqliteProvider.ts +180 -0
  136. package/src/orm/providers/drivers/CloudflareD1Provider.ts +164 -0
  137. package/src/orm/providers/drivers/DatabaseProvider.ts +25 -0
  138. package/src/orm/providers/drivers/NodePostgresProvider.ts +0 -25
  139. package/src/orm/providers/drivers/NodeSqliteProvider.ts +3 -1
  140. package/src/orm/services/QueryManager.ts +10 -125
  141. package/src/queue/redis/providers/RedisQueueProvider.ts +2 -7
  142. package/src/redis/index.ts +65 -3
  143. package/src/redis/providers/BunRedisProvider.ts +304 -0
  144. package/src/redis/providers/BunRedisSubscriberProvider.ts +94 -0
  145. package/src/redis/providers/NodeRedisProvider.ts +280 -0
  146. package/src/redis/providers/NodeRedisSubscriberProvider.ts +94 -0
  147. package/src/redis/providers/RedisProvider.ts +134 -140
  148. package/src/redis/providers/RedisSubscriberProvider.ts +58 -49
  149. package/src/server/core/providers/BunHttpServerProvider.ts +0 -3
  150. package/src/server/core/providers/ServerBodyParserProvider.ts +3 -1
  151. package/src/server/core/providers/ServerProvider.ts +7 -4
  152. package/src/server/multipart/providers/ServerMultipartProvider.ts +3 -1
  153. package/src/server/proxy/providers/ServerProxyProvider.ts +1 -1
  154. package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
  155. package/src/vite/plugins/viteAlephaBuild.ts +8 -2
  156. package/src/vite/plugins/viteAlephaDev.ts +6 -2
  157. package/src/vite/tasks/buildServer.ts +2 -1
  158. package/src/vite/tasks/generateCloudflare.ts +43 -15
  159. package/src/vite/tasks/runAlepha.ts +1 -0
  160. package/src/orm/services/PgJsonQueryManager.ts +0 -511
@@ -2,10 +2,11 @@ import { $atom, $env, $hook, $inject, $module, $use, Alepha, AlephaError, KIND,
2
2
  import { stdin, stdout } from "node:process";
3
3
  import { createInterface } from "node:readline/promises";
4
4
  import { $logger } from "alepha/logger";
5
+ import * as fs from "node:fs/promises";
6
+ import { cp, glob, readFile, rm } from "node:fs/promises";
7
+ import { join } from "node:path";
5
8
  import { DateTimeProvider } from "alepha/datetime";
6
9
  import { exec } from "node:child_process";
7
- import * as fs from "node:fs/promises";
8
- import { cp, glob, rm } from "node:fs/promises";
9
10
 
10
11
  //#region ../../src/command/helpers/Asker.ts
11
12
  var Asker = class {
@@ -60,6 +61,35 @@ var Asker = class {
60
61
  }
61
62
  };
62
63
 
64
+ //#endregion
65
+ //#region ../../src/command/helpers/EnvUtils.ts
66
+ var EnvUtils = class {
67
+ log = $logger();
68
+ /**
69
+ * Load environment variables from .env files into process.env.
70
+ * By default, it loads from ".env" and ".env.local".
71
+ * You can specify additional files to load, e.g. [".env", ".env.production"].
72
+ */
73
+ async loadEnv(root, files = [".env"]) {
74
+ for (const it of files) for (const file of [it, `${it}.local`]) {
75
+ const envPath = join(root, file);
76
+ try {
77
+ const lines = (await readFile(envPath, "utf8")).split("\n");
78
+ for (const line of lines) {
79
+ const [key, ...rest] = line.split("=");
80
+ if (key) {
81
+ const value = rest.join("=");
82
+ process.env[key.trim()] = value.trim();
83
+ }
84
+ }
85
+ this.log.debug(`Loaded environment variables from ${envPath}`);
86
+ } catch {
87
+ this.log.debug(`No ${file} file found at ${envPath}, skipping load.`);
88
+ }
89
+ }
90
+ }
91
+ };
92
+
63
93
  //#endregion
64
94
  //#region ../../src/command/helpers/PrettyPrint.ts
65
95
  var PrettyPrint = class {
@@ -358,6 +388,7 @@ var Runner = class {
358
388
  const $command = (options) => createPrimitive(CommandPrimitive, options);
359
389
  var CommandPrimitive = class extends Primitive {
360
390
  flags = this.options.flags ?? t.object({});
391
+ env = this.options.env ?? t.object({});
361
392
  aliases = this.options.aliases ?? [];
362
393
  onInit() {
363
394
  if (this.options.pre || this.options.post) this.options.hide ??= true;
@@ -368,6 +399,24 @@ var CommandPrimitive = class extends Primitive {
368
399
  if (this.options.post) return `post${this.options.post}`;
369
400
  return this.options.name ?? `${this.config.propertyKey}`;
370
401
  }
402
+ /**
403
+ * Get the child commands (subcommands) for this command.
404
+ */
405
+ get children() {
406
+ return this.options.children ?? [];
407
+ }
408
+ /**
409
+ * Check if this command has child commands (is a parent command).
410
+ */
411
+ get hasChildren() {
412
+ return this.children.length > 0;
413
+ }
414
+ /**
415
+ * Find a child command by name or alias.
416
+ */
417
+ findChild(name) {
418
+ return this.children.find((child) => child.name === name || child.aliases.includes(name));
419
+ }
371
420
  };
372
421
  $command[KIND] = CommandPrimitive;
373
422
 
@@ -401,6 +450,7 @@ var CliProvider = class {
401
450
  log = $logger();
402
451
  runner = $inject(Runner);
403
452
  asker = $inject(Asker);
453
+ envUtils = $inject(EnvUtils);
404
454
  options = $use(cliOptions);
405
455
  get name() {
406
456
  return this.options.name || this.env.CLI_NAME;
@@ -420,8 +470,8 @@ var CliProvider = class {
420
470
  on: "ready",
421
471
  handler: async () => {
422
472
  const argv = [...this.argv];
423
- const commandName = argv.find((arg) => !arg.startsWith("-")) ?? "";
424
- let command = this.findCommand(commandName);
473
+ const positionalArgs = argv.filter((arg) => !arg.startsWith("-"));
474
+ const { command, consumedArgs } = this.resolveCommand(positionalArgs);
425
475
  if (this.parseFlags(argv, Object.entries(this.getAllGlobalFlags()).map(([key, value]) => ({
426
476
  key,
427
477
  ...value
@@ -431,49 +481,124 @@ var CliProvider = class {
431
481
  }
432
482
  if (!command) {
433
483
  const rootCommand = this.findCommand("");
434
- if (rootCommand?.options.args) command = rootCommand;
435
- else {
436
- if (commandName !== "") {
437
- this.log.error(`Unknown command: '${commandName}'`);
438
- this.printHelp();
439
- }
484
+ const commandName = positionalArgs[0] ?? "";
485
+ if (commandName !== "" && !rootCommand?.options.args) {
486
+ this.log.error(`Unknown command: '${commandName}'`);
487
+ this.printHelp();
440
488
  return;
441
489
  }
442
- }
443
- const commandFlags = this.parseCommandFlags(argv, command.flags);
444
- const commandArgs = this.parseCommandArgs(argv, command.options.args, command.name === "");
445
- await this.alepha.context.run(async () => {
446
- this.log.debug(`Executing command '${command.name}'...`, {
447
- flags: commandFlags,
448
- args: commandArgs
449
- });
450
- const runner = this.runner;
451
- runner.startCommand(this.name, command.name);
452
- const args = {
453
- flags: commandFlags,
454
- args: commandArgs,
455
- run: runner.run,
456
- ask: this.asker.ask,
457
- fs,
458
- glob,
459
- root: process.cwd()
460
- };
461
- const preHooks = this.findPreHooks(command.name);
462
- for (const hook of preHooks) {
463
- this.log.debug(`Executing pre-hook for '${command.name}'...`);
464
- await hook.options.handler(args);
465
- }
466
- await command.options.handler(args);
467
- const postHooks = this.findPostHooks(command.name);
468
- for (const hook of postHooks) {
469
- this.log.debug(`Executing post-hook for '${command.name}'...`);
470
- await hook.options.handler(args);
490
+ if (rootCommand) {
491
+ await this.executeCommand(rootCommand, argv, true);
492
+ return;
471
493
  }
472
- if (command.options.summary !== false) runner.summary();
473
- this.log.debug(`Command '${command.name}' executed successfully.`);
474
- });
494
+ return;
495
+ }
496
+ const remainingArgv = this.removeConsumedArgs(argv, consumedArgs);
497
+ await this.executeCommand(command, remainingArgv, true);
475
498
  }
476
499
  });
500
+ /**
501
+ * Execute a command with the given argv.
502
+ */
503
+ async executeCommand(command, argv, isRootCommand) {
504
+ const root = process.cwd();
505
+ let modeValue;
506
+ if (command.options.mode) {
507
+ modeValue = this.parseModeFlag(argv);
508
+ if (modeValue === void 0 && typeof command.options.mode === "string") modeValue = command.options.mode;
509
+ await this.loadModeEnv(root, modeValue);
510
+ }
511
+ const commandFlags = this.parseCommandFlags(argv, command.flags);
512
+ const commandArgs = this.parseCommandArgs(argv, command.options.args, isRootCommand, command.flags);
513
+ const commandEnv = this.parseCommandEnv(command.env, command.name);
514
+ await this.alepha.context.run(async () => {
515
+ this.log.debug(`Executing command '${command.name}'...`, {
516
+ flags: commandFlags,
517
+ args: commandArgs,
518
+ mode: modeValue
519
+ });
520
+ const runner = this.runner;
521
+ runner.startCommand(this.name, command.name);
522
+ const args = {
523
+ flags: commandFlags,
524
+ args: commandArgs,
525
+ env: commandEnv,
526
+ run: runner.run,
527
+ ask: this.asker.ask,
528
+ fs,
529
+ glob,
530
+ root,
531
+ help: () => this.printHelp(command),
532
+ mode: modeValue
533
+ };
534
+ const preHooks = this.findPreHooks(command.name);
535
+ for (const hook of preHooks) {
536
+ this.log.debug(`Executing pre-hook for '${command.name}'...`);
537
+ await hook.options.handler(args);
538
+ }
539
+ await command.options.handler(args);
540
+ const postHooks = this.findPostHooks(command.name);
541
+ for (const hook of postHooks) {
542
+ this.log.debug(`Executing post-hook for '${command.name}'...`);
543
+ await hook.options.handler(args);
544
+ }
545
+ if (command.options.summary !== false) runner.summary();
546
+ this.log.debug(`Command '${command.name}' executed successfully.`);
547
+ });
548
+ }
549
+ /**
550
+ * Remove consumed command path arguments from argv.
551
+ */
552
+ removeConsumedArgs(argv, consumedArgs) {
553
+ const result = [];
554
+ let consumedIndex = 0;
555
+ for (const arg of argv) if (arg.startsWith("-")) result.push(arg);
556
+ else if (consumedIndex < consumedArgs.length && arg === consumedArgs[consumedIndex]) consumedIndex++;
557
+ else result.push(arg);
558
+ return result;
559
+ }
560
+ /**
561
+ * Resolve a command from positional arguments.
562
+ *
563
+ * Supports:
564
+ * 1. Space-separated subcommands: `deploy vercel` -> finds deploy command, then vercel child
565
+ * 2. Colon notation (backwards compat): `deploy:vercel` -> finds command with name "deploy:vercel"
566
+ * 3. Simple commands: `build` -> finds command with name "build"
567
+ */
568
+ resolveCommand(positionalArgs) {
569
+ if (positionalArgs.length === 0) return {
570
+ command: void 0,
571
+ consumedArgs: []
572
+ };
573
+ const firstArg = positionalArgs[0];
574
+ if (firstArg.includes(":")) {
575
+ const command = this.findCommand(firstArg);
576
+ if (command) return {
577
+ command,
578
+ consumedArgs: [firstArg]
579
+ };
580
+ }
581
+ let currentCommand = this.findCommand(firstArg);
582
+ const consumedArgs = [];
583
+ if (!currentCommand) return {
584
+ command: void 0,
585
+ consumedArgs: []
586
+ };
587
+ consumedArgs.push(firstArg);
588
+ for (let i = 1; i < positionalArgs.length; i++) {
589
+ const arg = positionalArgs[i];
590
+ if (!currentCommand.hasChildren) break;
591
+ const childCommand = currentCommand.findChild(arg);
592
+ if (childCommand) {
593
+ currentCommand = childCommand;
594
+ consumedArgs.push(arg);
595
+ } else break;
596
+ }
597
+ return {
598
+ command: currentCommand,
599
+ consumedArgs
600
+ };
601
+ }
477
602
  get commands() {
478
603
  return this.alepha.primitives($command);
479
604
  }
@@ -493,17 +618,10 @@ var CliProvider = class {
493
618
  return this.commands.filter((cmd) => cmd.name === `post${commandName}`);
494
619
  }
495
620
  /**
496
- * Get all global flags including those from the root command (name === "")
621
+ * Get global flags (help only, root command flags are NOT global).
497
622
  */
498
623
  getAllGlobalFlags() {
499
- const rootCommand = this.commands.find((cmd) => cmd.name === "");
500
- const allGlobalFlags = { ...this.globalFlags };
501
- if (rootCommand) for (const [key, value] of Object.entries(rootCommand.flags.properties)) allGlobalFlags[key] = {
502
- aliases: [key, ...value.aliases ?? (value.alias ? [value.alias] : void 0) ?? []],
503
- description: value.description,
504
- schema: value
505
- };
506
- return allGlobalFlags;
624
+ return { ...this.globalFlags };
507
625
  }
508
626
  parseCommandFlags(argv, schema) {
509
627
  const flagDefs = Object.entries(schema.properties).map(([key, value]) => ({
@@ -524,11 +642,57 @@ var CliProvider = class {
524
642
  throw error;
525
643
  }
526
644
  }
645
+ parseCommandEnv(schema, commandName) {
646
+ const result = {};
647
+ const missing = [];
648
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
649
+ const value = process.env[key];
650
+ if (value !== void 0) result[key] = value;
651
+ else if (t.schema.isOptional(propSchema)) {
652
+ if ("default" in propSchema) result[key] = propSchema.default;
653
+ } else missing.push(key);
654
+ }
655
+ if (missing.length > 0) {
656
+ const vars = missing.join(", ");
657
+ throw new CommandError(`Missing required environment variable${missing.length > 1 ? "s" : ""}: ${vars}`);
658
+ }
659
+ try {
660
+ return this.alepha.codec.decode(schema, result);
661
+ } catch (error) {
662
+ if (error instanceof TypeBoxError) throw new CommandError(`Invalid environment variable: ${error.cause.instancePath || "env"} ${error.cause.message}`);
663
+ throw error;
664
+ }
665
+ }
666
+ /**
667
+ * Parse --mode or -m flag from argv.
668
+ */
669
+ parseModeFlag(argv) {
670
+ for (let i = 0; i < argv.length; i++) {
671
+ const arg = argv[i];
672
+ if (arg.startsWith("--mode=") || arg.startsWith("-m=")) return arg.split("=")[1];
673
+ if (arg === "--mode" || arg === "-m") {
674
+ const nextArg = argv[i + 1];
675
+ if (nextArg && !nextArg.startsWith("-")) return nextArg;
676
+ throw new CommandError("Flag --mode requires a value.");
677
+ }
678
+ }
679
+ }
680
+ /**
681
+ * Load environment files based on mode.
682
+ */
683
+ async loadModeEnv(root, mode) {
684
+ const envFiles = [".env"];
685
+ if (mode) envFiles.push(`.env.${mode}`);
686
+ this.log.debug(`Loading env files: ${envFiles.join(", ")}`);
687
+ await this.envUtils.loadEnv(root, envFiles);
688
+ }
527
689
  parseFlags(argv, flagDefs) {
528
690
  const result = {};
529
- for (const arg of argv.filter((a) => a.startsWith("-"))) {
691
+ for (let i = 0; i < argv.length; i++) {
692
+ const arg = argv[i];
693
+ if (!arg.startsWith("-")) continue;
530
694
  const [rawKey, ...valueParts] = arg.replace(/^-{1,2}/, "").split("=");
531
- const value = valueParts.join("=");
695
+ let value = valueParts.join("=");
532
696
  const def = flagDefs.find((d) => d.aliases.includes(rawKey));
533
697
  if (!def) continue;
534
698
  if (t.schema.isBoolean(def.schema)) result[def.key] = true;
@@ -538,13 +702,50 @@ var CliProvider = class {
538
702
  } catch {
539
703
  throw new CommandError(`Invalid JSON value for flag --${rawKey}`);
540
704
  }
541
- else throw new CommandError(`Flag --${rawKey} requires a value.`);
705
+ else {
706
+ const nextArg = argv[i + 1];
707
+ if (nextArg && !nextArg.startsWith("-")) {
708
+ value = nextArg;
709
+ try {
710
+ if (t.schema.isObject(def.schema) || t.schema.isArray(def.schema)) result[def.key] = JSON.parse(value);
711
+ else result[def.key] = value;
712
+ } catch {
713
+ throw new CommandError(`Invalid JSON value for flag --${rawKey}`);
714
+ }
715
+ } else throw new CommandError(`Flag --${rawKey} requires a value.`);
716
+ }
542
717
  }
543
718
  return result;
544
719
  }
545
- parseCommandArgs(argv, schema, isRootCommand = false) {
720
+ /**
721
+ * Get indices of argv elements that are consumed by flags (including space-separated values).
722
+ */
723
+ getFlagConsumedIndices(argv, flagDefs) {
724
+ const consumed = /* @__PURE__ */ new Set();
725
+ for (let i = 0; i < argv.length; i++) {
726
+ const arg = argv[i];
727
+ if (!arg.startsWith("-")) continue;
728
+ consumed.add(i);
729
+ const [rawKey, ...valueParts] = arg.replace(/^-{1,2}/, "").split("=");
730
+ const hasEqualValue = valueParts.length > 0;
731
+ const def = flagDefs.find((d) => d.aliases.includes(rawKey));
732
+ if (!def) continue;
733
+ if (!t.schema.isBoolean(def.schema) && !hasEqualValue) {
734
+ const nextArg = argv[i + 1];
735
+ if (nextArg && !nextArg.startsWith("-")) consumed.add(i + 1);
736
+ }
737
+ }
738
+ return consumed;
739
+ }
740
+ parseCommandArgs(argv, schema, isRootCommand = false, flagSchema) {
546
741
  if (!schema) return;
547
- const positionalArgs = argv.filter((arg) => !arg.startsWith("-"));
742
+ const flagDefs = flagSchema ? Object.entries(flagSchema.properties).map(([key, value]) => ({
743
+ key,
744
+ aliases: [key, ...value.aliases ?? (value.alias ? [value.alias] : void 0) ?? []],
745
+ schema: value
746
+ })) : [];
747
+ const consumedIndices = this.getFlagConsumedIndices(argv, flagDefs);
748
+ const positionalArgs = argv.filter((arg, idx) => !arg.startsWith("-") && !consumedIndices.has(idx));
548
749
  const argsOnly = isRootCommand ? positionalArgs : positionalArgs.slice(1);
549
750
  try {
550
751
  if (t.schema.isOptional(schema)) {
@@ -612,42 +813,80 @@ var CliProvider = class {
612
813
  const cliName = this.name || "cli";
613
814
  this.log.info("");
614
815
  if (command?.name) {
615
- const argsUsage = this.generateArgsUsage(command.options.args);
616
- const usage = `${cliName} ${command.name}${argsUsage}`.trim();
816
+ const hasChildren = command.hasChildren;
817
+ const argsUsage = hasChildren ? " <command>" : this.generateArgsUsage(command.options.args);
818
+ const usage = `${cliName} ${this.getCommandPath(command)}${argsUsage}`.trim();
617
819
  this.log.info(`Usage: \`${usage}\``);
618
820
  if (command.options.description) {
619
821
  this.log.info(``);
620
822
  this.log.info(`\t${command.options.description}`);
621
823
  }
824
+ if (hasChildren) {
825
+ this.log.info("");
826
+ this.log.info("Commands:");
827
+ const maxSubCmdLength = this.getMaxChildCmdLength(command.children);
828
+ for (const child of command.children) {
829
+ if (child.options.hide) continue;
830
+ const childArgsUsage = this.generateArgsUsage(child.options.args);
831
+ const fullCmdStr = `${[child.name, ...child.aliases].join(", ")}${childArgsUsage}`;
832
+ this.log.info(` ${cliName} ${command.name} ${fullCmdStr.padEnd(maxSubCmdLength)} # ${child.options.description ?? ""}`);
833
+ }
834
+ }
622
835
  this.log.info("");
623
836
  this.log.info("Flags:");
624
- const flags = [...Object.entries(command.flags.properties).map(([key, value]) => ({
625
- key,
626
- schema: value,
627
- aliases: value.alias ?? [key],
628
- description: value.description
629
- })), ...Object.entries(this.getAllGlobalFlags()).map(([key, value]) => ({
630
- key,
631
- ...value
632
- }))];
837
+ const flags = [
838
+ ...Object.entries(command.flags.properties).map(([key, value]) => ({
839
+ key,
840
+ schema: value,
841
+ aliases: value.alias ?? [key],
842
+ description: value.description
843
+ })),
844
+ ...command.options.mode ? [{
845
+ key: "mode",
846
+ aliases: ["m", "mode"],
847
+ description: typeof command.options.mode === "string" ? `Environment mode - loads .env.{mode} (default: ${command.options.mode})` : "Environment mode (e.g., production, staging) - loads .env.{mode}"
848
+ }] : [],
849
+ ...Object.entries(this.getAllGlobalFlags()).map(([key, value]) => ({
850
+ key,
851
+ ...value
852
+ }))
853
+ ];
633
854
  const maxFlagLength = this.getMaxFlagLength(flags);
634
855
  for (const { aliases, description } of flags) {
635
856
  const flagStr = (Array.isArray(aliases) ? aliases : [aliases]).map((a) => a.length === 1 ? `-${a}` : `--${a}`).join(", ");
636
857
  this.log.info(` ${flagStr.padEnd(maxFlagLength)} # ${description ?? ""}`);
637
858
  }
859
+ const envVars = Object.entries(command.env.properties);
860
+ if (envVars.length > 0) {
861
+ this.log.info("");
862
+ this.log.info("Env:");
863
+ const maxEnvLength = Math.max(...envVars.map(([key]) => key.length));
864
+ for (const [key, schema] of envVars) {
865
+ const isOptional = t.schema.isOptional(schema);
866
+ const description = schema.description ?? "";
867
+ const optionalStr = isOptional ? " (optional)" : "";
868
+ this.log.info(` ${key.padEnd(maxEnvLength)} # ${description}${optionalStr}`);
869
+ }
870
+ }
638
871
  } else {
639
872
  this.log.info(this.description || "Available commands:");
640
873
  this.log.info("");
641
874
  this.log.info("Commands:");
642
- const maxCmdLength = this.getMaxCmdLength(this.commands);
643
- for (const command$1 of this.commands) {
875
+ const topLevelCommands = this.getTopLevelCommands();
876
+ const maxCmdLength = this.getMaxCmdLength(topLevelCommands);
877
+ for (const command$1 of topLevelCommands) {
644
878
  if (command$1.name === "" || command$1.options.hide) continue;
645
- const fullCmdStr = `${[command$1.name, ...command$1.aliases].join(", ")}${this.generateArgsUsage(command$1.options.args)}`;
879
+ const fullCmdStr = `${[command$1.name, ...command$1.aliases].join(", ")}${command$1.hasChildren ? " <command>" : this.generateArgsUsage(command$1.options.args)}`;
646
880
  this.log.info(` ${cliName} ${fullCmdStr.padEnd(maxCmdLength)} # ${command$1.options.description ?? ""}`);
647
881
  }
648
882
  this.log.info("");
649
883
  this.log.info("Flags:");
650
- const globalFlags = Object.values(this.getAllGlobalFlags());
884
+ const rootCommand = this.commands.find((cmd) => cmd.name === "");
885
+ const globalFlags = [...rootCommand ? Object.entries(rootCommand.flags.properties).map(([key, value]) => ({
886
+ key,
887
+ aliases: [key, ...value.aliases ?? (value.alias ? [value.alias] : void 0) ?? []],
888
+ description: value.description
889
+ })) : [], ...Object.values(this.getAllGlobalFlags())];
651
890
  const maxFlagLength = this.getMaxFlagLength(globalFlags);
652
891
  for (const { aliases, description } of globalFlags) {
653
892
  const flagStr = aliases.map((a) => a.length === 1 ? `-${a}` : `--${a}`).join(", ");
@@ -656,9 +895,45 @@ var CliProvider = class {
656
895
  }
657
896
  this.log.info("");
658
897
  }
898
+ /**
899
+ * Get the full command path (e.g., "deploy vercel" for a child command).
900
+ */
901
+ getCommandPath(command) {
902
+ const path = [command.name];
903
+ let current = command;
904
+ while (true) {
905
+ const parent = this.findParentCommand(current);
906
+ if (!parent) break;
907
+ path.unshift(parent.name);
908
+ current = parent;
909
+ }
910
+ return path.join(" ");
911
+ }
912
+ /**
913
+ * Find the parent command of a given command.
914
+ */
915
+ findParentCommand(command) {
916
+ for (const cmd of this.commands) if (cmd.children.includes(command)) return cmd;
917
+ }
918
+ /**
919
+ * Get top-level commands (commands that are not children of other commands).
920
+ */
921
+ getTopLevelCommands() {
922
+ const allChildren = /* @__PURE__ */ new Set();
923
+ for (const command of this.commands) for (const child of command.children) allChildren.add(child);
924
+ return this.commands.filter((cmd) => !allChildren.has(cmd));
925
+ }
926
+ /**
927
+ * Get max length for child command display.
928
+ */
929
+ getMaxChildCmdLength(children) {
930
+ return Math.max(...children.filter((c) => !c.options.hide).map((c) => {
931
+ return `${[c.name, ...c.aliases].join(", ")}${this.generateArgsUsage(c.options.args)}`.length;
932
+ }), 0);
933
+ }
659
934
  getMaxCmdLength(commands) {
660
935
  return Math.max(...commands.filter((c) => !c.options.hide && c.name !== "").map((c) => {
661
- return `${[c.name, ...c.aliases].join(", ")}${this.generateArgsUsage(c.options.args)}`.length;
936
+ return `${[c.name, ...c.aliases].join(", ")}${c.hasChildren ? " <command>" : this.generateArgsUsage(c.options.args)}`.length;
662
937
  }));
663
938
  }
664
939
  getMaxFlagLength(flags) {
@@ -686,10 +961,11 @@ const AlephaCommand = $module({
686
961
  CliProvider,
687
962
  Runner,
688
963
  Asker,
689
- PrettyPrint
964
+ PrettyPrint,
965
+ EnvUtils
690
966
  ]
691
967
  });
692
968
 
693
969
  //#endregion
694
- export { $command, AlephaCommand, Asker, CliProvider, CommandError, CommandPrimitive, PrettyPrint, Runner, cliOptions };
970
+ export { $command, AlephaCommand, Asker, CliProvider, CommandError, CommandPrimitive, EnvUtils, PrettyPrint, Runner, cliOptions };
695
971
  //# sourceMappingURL=index.js.map