import { Alepha, AlephaError, Async, KIND, Primitive, Static, TObject, TSchema, TString } from "alepha";
import { ConsoleColorProvider } from "alepha/logger";
import { FileSystemProvider, ShellProvider } from "alepha/system";
import * as fs from "node:fs/promises";
import { glob } from "node:fs/promises";
import { DateTimeProvider } from "alepha/datetime";
//#region ../../src/command/errors/CommandError.d.ts
declare class CommandError extends AlephaError {
  readonly name = "CommandError";
}
//#endregion
//#region ../../src/command/helpers/Asker.d.ts
interface AskOptions<T extends TSchema = TString> {
  /**
   * Response schema expected.
   *
   * Recommended schemas:
   * - z.text() - for free text input
   * - z.number() - for numeric input
   * - z.boolean() - for yes/no input (accepts "true", "false", "1", "0")
   * - z.enum(["option1", "option2"]) - for predefined options
   *
   * You can use schema.default to provide a default value.
   *
   * @example
   * ```ts
   * ask("What is your name?", { schema: z.text({ default: "John Doe" }) })
   * ```
   *
   * @default TString
   */
  schema?: T;
  /**
   * Custom validation function.
   * Throws an AlephaError in case of validation failure.
   */
  validate?: (value: Static<T>) => void;
}
interface AskMethod {
  <T extends TSchema = TString>(question: string, options?: AskOptions<T>): Promise<Static<T>>;
  permission: (question: string) => Promise<boolean>;
  intro: (title: string) => void;
  outro: (message: string) => void;
}
/**
 * Reads interactive input from the terminal using plain readline prompts.
 *
 * One straightforward code path: questions are printed through the logger
 * and answers are read with Node's `readline`. No raw-mode cursor control,
 * no ANSI framing — output stays greppable and works the same in a TTY,
 * under CI, or when piped.
 */
declare class Asker {
  protected readonly log: import("alepha/logger").Logger;
  readonly ask: AskMethod;
  protected readonly alepha: Alepha;
  constructor();
  protected createAskMethod(): AskMethod;
  protected prompt<T extends TSchema = TString>(question: string, options: AskOptions<T>): Promise<Static<T>>;
  protected createPromptInterface(): import("node:readline/promises").Interface;
}
//#endregion
//#region ../../src/command/helpers/EnvUtils.d.ts
declare class EnvUtils {
  protected readonly log: import("alepha/logger").Logger;
  protected readonly fs: FileSystemProvider;
  /**
   * Load environment variables from .env files into process.env.
   *
   * Variables that already exist in process.env are NOT overwritten,
   * matching the standard dotenv convention where the shell environment
   * takes precedence over .env file values.
   *
   * By default, it loads from ".env" and ".env.local".
   * You can specify additional files to load, e.g. [".env", ".env.production"].
   */
  loadEnv(root: string, files?: string[]): Promise<void>;
  /**
   * Parse environment variables from .env files without mutating process.env.
   *
   * Returns a merged record from all files (later files override earlier ones).
   * For each file, also tries the `.local` variant (e.g. `.env.production.local`).
   */
  parseEnv(root: string, files?: string[]): Promise<Record<string, string>>;
}
//#endregion
//#region ../../src/command/helpers/Runner.d.ts
type Task = {
  name: string;
  handler: () => any;
};
interface Timer {
  name: string;
  duration: string;
}
interface RunOptions {
  /**
   * Rename the command for logging purposes.
   */
  alias?: string;
  /**
   * Root directory to execute the command in.
   */
  root?: string;
}
interface RunnerMethod {
  (cmd: string | Task | Array<string | Task>, options?: RunOptions | (() => any)): Promise<string>;
  rm: (glob: string | string[], options?: RunOptions) => Promise<string>;
  cp: (source: string, dest: string, options?: RunOptions) => Promise<string>;
  /**
   * Ends the runner and prints a summary of executed tasks.
   *
   * > This is automatically called at the end of command execution.
   * > But can be called manually if needed to print more stuff before the command ends.
   */
  end: () => void;
}
/**
 * Runs CLI tasks (shell commands or functions) and logs their lifecycle.
 *
 * Output is intentionally plain and verbose: every task logs a
 * `Starting …` / `Finished … after Ns` line through the standard logger,
 * and shelled commands **stream** their stdout/stderr straight to the
 * terminal (`capture: false`) so tool output — `vite build` warnings,
 * Biome diagnostics, nested `alepha` subcommands — is visible live.
 */
declare class Runner {
  protected readonly log: import("alepha/logger").Logger;
  protected readonly dateTime: DateTimeProvider;
  protected timers: Timer[];
  protected readonly startTime: number;
  protected readonly alepha: Alepha;
  protected readonly shell: ShellProvider;
  readonly run: RunnerMethod;
  constructor();
  /**
   * Start a new command session.
   *
   * Retained for API compatibility (the CLI calls it before each command);
   * task lifecycle is now logged statelessly, so there is nothing to reset.
   */
  startCommand(_cliName: string, _commandName: string): void;
  protected createRunMethod(): RunnerMethod;
  protected exec(cmd: string, opts?: {
    root?: string;
  }): Promise<string>;
  /**
   * Executes one or more tasks.
   *
   * @param task - A single task or an array of tasks to run in parallel.
   */
  protected execute(task: Task | Task[]): Promise<string>;
  /**
   * Prints a summary of all executed tasks and their durations.
   */
  end(): void;
  protected executeTask(task: Task): Promise<string>;
}
//#endregion
//#region ../../src/command/primitives/$command.d.ts
/**
 * Declares a CLI command.
 *
 * This primitive allows you to define a command, its flags, and its handler
 * within your Alepha application structure.
 */
declare const $command: {
  <T extends TObject, A extends TSchema, E extends TObject>(options: CommandPrimitiveOptions<T, A, E>): CommandPrimitive<T, A, E>;
  [KIND]: typeof CommandPrimitive;
};
interface CommandPrimitiveOptions<T extends TObject, A extends TSchema, E extends TObject = TObject> {
  /**
   * The handler function to execute when the command is matched.
   *
   * For parent commands with children, the handler is called when:
   * - The parent command is invoked without a subcommand
   * - The parent command is invoked with --help (to show available subcommands)
   */
  handler: (args: CommandHandlerArgs<T, A, E>) => Async<void>;
  /**
   * The name of the command. If omitted, the property key is used.
   *
   * An empty string "" denotes the root command.
   */
  name?: string;
  /**
   * A short description of the command, shown in the help message.
   */
  description?: string;
  /**
   * An array of alternative names for the command.
   */
  aliases?: string[];
  /**
   * A TypeBox object schema defining the flags for the command.
   */
  flags?: T;
  /**
   * A TypeBox object schema defining required environment variables.
   *
   * Environment variables are validated before the handler runs (fail fast).
   * They are displayed in the help output under "Env:" section.
   *
   * @example
   * ```ts
   * $command({
   *   env: z.object({
   *     VERCEL_TOKEN: z.text({ description: "Vercel API token" }),
   *     VERCEL_ORG_ID: z.text({ description: "Organization ID" }).optional(),
   *   }),
   *   handler: async ({ env }) => {
   *     // env.VERCEL_TOKEN is typed & guaranteed to exist
   *     console.log(env.VERCEL_TOKEN);
   *   }
   * })
   * ```
   */
  env?: E;
  /**
   * An optional TypeBox schema defining the arguments for the command.
   *
   * @example
   * args: z.text()
   * my-cli command <arg1: string>
   *
   * args: z.text().optional()
   * my-cli command [arg1: string]
   *
   * args: z.tuple([z.text(), z.number()])
   * my-cli command <arg1: string> <arg2: number>
   *
   * args: z.tuple([z.text(), z.number().optional()])
   * my-cli command <arg1: string> [arg2: number]
   */
  args?: A;
  /**
   * Marks this command as the root command.
   * Equivalent to setting name to an empty string "".
   */
  root?: boolean;
  /**
   * Run this command's handler BEFORE the specified target command.
   *
   * Pre-hooks are not listed in help and cannot be called directly.
   * They receive the same parsed flags and args as the target command.
   *
   * @example
   * ```ts
   * class BuildCommands {
   *   prebuild = $command({
   *     pre: "build",
   *     handler: async ({ run }) => {
   *       await run("cleaning dist folder...", () => fs.rm("dist"));
   *     }
   *   });
   *
   *   build = $command({
   *     name: "build",
   *     handler: async () => { ... }
   *   });
   * }
   * ```
   */
  pre?: string;
  /**
   * Run this command's handler AFTER the specified target command.
   *
   * Post-hooks are not listed in help and cannot be called directly.
   * They receive the same parsed flags and args as the target command.
   *
   * @example
   * ```ts
   * class BuildCommands {
   *   build = $command({
   *     name: "build",
   *     handler: async () => { ... }
   *   });
   *
   *   postbuild = $command({
   *     post: "build",
   *     handler: async ({ run }) => {
   *       await run("generating checksums...", generateChecksums);
   *     }
   *   });
   * }
   * ```
   */
  post?: string;
  /**
   * If true, this command will be hidden from the help output.
   */
  hide?: boolean;
  /**
   * Adds a `--mode, -m` flag to load environment files.
   *
   * When enabled:
   * - Loads `.env` and `.env.local` by default
   * - With `--mode production`, also loads `.env.production` and `.env.production.local`
   * - The mode value is exposed in the handler as `mode: string | undefined`
   *
   * Set to `true` to enable with no default, or a string to set a default mode.
   *
   * This follows Vite's environment loading convention.
   * @see https://vite.dev/guide/env-and-mode
   *
   * @example
   * ```ts
   * // No default mode
   * build = $command({
   *   mode: true,
   *   handler: async ({ mode }) => {
   *     console.log(`Building for ${mode ?? 'development'}...`);
   *   }
   * });
   *
   * // Default mode "production"
   * deploy = $command({
   *   mode: "production",
   *   handler: async ({ mode }) => {
   *     console.log(`Deploying for ${mode}...`); // always defined
   *   }
   * });
   * ```
   *
   * Usage:
   * - `cli build` - loads .env (mode = undefined)
   * - `cli build --mode production` - loads .env and .env.production
   * - `cli deploy` - loads .env and .env.production (default mode)
   * - `cli deploy --mode staging` - loads .env and .env.staging
   */
  mode?: boolean | string;
  /**
   * Child commands (subcommands) for this command.
   *
   * When children are defined, the command becomes a parent command that
   * can be invoked with space-separated subcommands:
   *
   * @example
   * ```ts
   * class DeployCommands {
   *   // Subcommands
   *   vercel = $command({
   *     description: "Deploy to Vercel",
   *     handler: async () => { ... }
   *   });
   *
   *   cloudflare = $command({
   *     description: "Deploy to Cloudflare",
   *     handler: async () => { ... }
   *   });
   *
   *   // Parent command with children
   *   deploy = $command({
   *     description: "Deploy the application",
   *     children: [this.vercel, this.cloudflare],
   *     handler: async () => {
   *       // Called when "deploy" is invoked without subcommand
   *       console.log("Available: deploy vercel, deploy cloudflare");
   *     }
   *   });
   * }
   * ```
   *
   * This allows CLI usage like:
   * - `cli deploy vercel` - runs the vercel subcommand
   * - `cli deploy cloudflare` - runs the cloudflare subcommand
   * - `cli deploy` - runs the parent handler (shows available subcommands)
   * - `cli deploy --help` - shows help with all available subcommands
   */
  children?: CommandPrimitive<any, any>[];
}
declare class CommandPrimitive<T extends TObject = TObject, A extends TSchema = TSchema, E extends TObject = TObject> extends Primitive<CommandPrimitiveOptions<T, A, E>> {
  readonly flags: T | import("zod").ZodObject<{}, import("zod/v4/core").$strip>;
  readonly env: E | import("zod").ZodObject<{}, import("zod/v4/core").$strip>;
  readonly aliases: string[];
  protected onInit(): void;
  get name(): string;
  /**
   * Get the child commands (subcommands) for this command.
   */
  get children(): CommandPrimitive<any, any>[];
  /**
   * Check if this command has child commands (is a parent command).
   */
  get hasChildren(): boolean;
  /**
   * Find a child command by name or alias.
   */
  findChild(name: string): CommandPrimitive<any, any> | undefined;
}
interface CommandHandlerArgs<T extends TObject, A extends TSchema = TSchema, E extends TObject = TObject> {
  flags: Static<T>;
  args: A extends TSchema ? Static<A> : Array<string>;
  env: Static<E>;
  run: RunnerMethod;
  ask: AskMethod;
  glob: typeof glob;
  fs: typeof fs;
  /**
   * The root directory where the command is executed.
   */
  root: string;
  /**
   * Display help for the current command.
   *
   * Useful for parent commands with children to show available subcommands
   * when invoked without a specific subcommand.
   *
   * @example
   * ```ts
   * deploy = $command({
   *   children: [this.vercel, this.cloudflare],
   *   handler: async ({ help }) => {
   *     help(); // Shows available subcommands
   *   }
   * });
   * ```
   */
  help: () => void;
  /**
   * The current execution mode (e.g., "development", "production", "staging").
   *
   * Use --mode flag to set this value when running the command.
   */
  mode?: string;
}
//#endregion
//#region ../../src/command/providers/CliProvider.d.ts
declare const envSchema: import("zod").ZodObject<{
  CLI_NAME: import("zod").ZodString;
  CLI_DESCRIPTION: import("zod").ZodString;
}, import("zod/v4/core").$strip>;
declare module "alepha" {
  interface Env extends Partial<Static<typeof envSchema>> {}
}
/**
 * CLI provider configuration atom
 */
declare const cliOptions: import("alepha").Atom<import("zod").ZodObject<{
  name: import("zod").ZodOptional<import("zod").ZodString>;
  description: import("zod").ZodOptional<import("zod").ZodString>;
  argv: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
}, import("zod/v4/core").$strip>, "alepha.command.cli.options">;
type CliProviderOptions = Static<typeof cliOptions.schema>;
declare module "alepha" {
  interface State {
    [cliOptions.key]: CliProviderOptions;
  }
}
/**
 * CLI provider for parsing and executing commands.
 *
 * Handles:
 * - Command resolution (simple, nested, colon-notation)
 * - Flag and argument parsing
 * - Environment variable validation
 * - Help generation
 * - Pre/post command hooks
 *
 * @example
 * ```typescript
 * // Define a command
 * class MyCommands {
 *   build = $command({
 *     name: "build",
 *     description: "Build the project",
 *     flags: z.object({ watch: z.boolean().optional() }),
 *     handler: async ({ flags }) => { ... }
 *   });
 * }
 *
 * // CLI automatically discovers and executes commands
 * const alepha = Alepha.create().with(MyCommands);
 * ```
 */
declare class CliProvider {
  protected readonly env: {
    CLI_NAME: string;
    CLI_DESCRIPTION: string;
  };
  protected readonly alepha: Alepha;
  protected readonly log: import("alepha/logger").Logger;
  protected readonly color: ConsoleColorProvider;
  protected readonly runner: Runner;
  protected readonly asker: Asker;
  protected readonly envUtils: EnvUtils;
  protected readonly options: Readonly<{
    name?: string | undefined;
    description?: string | undefined;
    argv?: string[] | undefined;
  }>;
  protected get name(): string;
  protected get description(): string;
  protected get argv(): string[];
  /**
   * Global flags available to all commands.
   */
  protected readonly globalFlags: {
    help: {
      aliases: string[];
      description: string;
      schema: import("zod").ZodBoolean;
    };
    verbose: {
      aliases: string[];
      description: string;
      schema: import("zod").ZodBoolean;
    };
  };
  /**
   * Main entry point - resolves and executes the command from process.argv.
   * This is the production execution path with full lifecycle support.
   */
  protected readonly onReady: import("alepha").HookPrimitive<"ready">;
  /**
   * Execute a command with full lifecycle support.
   *
   * This is the production execution path that includes:
   * - Mode-based .env file loading
   * - Pre/post command hooks
   * - Runner session for pretty CLI output
   * - Alepha context wrapper for proper scoping
   *
   * @see run() for a lightweight test-only alternative
   */
  protected executeCommand(command: CommandPrimitive<TObject>, argv: string[], isRootCommand: boolean): Promise<void>;
  /**
   * Remove consumed command path arguments from argv (keeps flags and remaining args).
   */
  protected removeConsumedArgs(argv: string[], consumedArgs: string[]): string[];
  /**
   * Resolve a command from positional arguments.
   *
   * Supports:
   * 1. Space-separated subcommands: `deploy vercel` -> finds deploy command, then vercel child
   * 2. Colon notation (backwards compat): `deploy:vercel` -> finds command with name "deploy:vercel"
   * 3. Simple commands: `build` -> finds command with name "build"
   */
  protected resolveCommand(positionalArgs: string[]): {
    command: CommandPrimitive<TObject> | undefined;
    consumedArgs: string[];
  };
  /**
   * Get all registered commands in the application.
   */
  get commands(): CommandPrimitive<any>[];
  /**
   * Execute a command handler with given arguments.
   *
   * This is a **lightweight test helper** that directly invokes the command handler
   * without the full production lifecycle. It intentionally skips:
   * - Pre/post command hooks
   * - Runner session (pretty CLI output)
   * - Alepha context wrapper
   * - .env.{mode} file loading
   *
   * For production execution, the `onReady` hook uses `executeCommand()` which
   * provides the full lifecycle. Merging them would either make this method too
   * heavy for simple testing or require many optional parameters to toggle behaviors.
   *
   * @example
   * ```typescript
   * // In tests
   * const cli = alepha.inject(CliProvider);
   * const cmd = alepha.inject(InitCommand);
   *
   * await cli.run(cmd.init, "--agent --pm=yarn");
   * await cli.run(cmd.init, { argv: "--agent", root: "/project" });
   * ```
   */
  run<T extends TObject, A extends TSchema>(command: CommandPrimitive<T, A>, options?: string | string[] | {
    argv?: string | string[];
    root?: string;
  }): Promise<void>;
  /**
   * Find a command by name or alias
   */
  protected findCommand(name: string): CommandPrimitive<TObject> | undefined;
  /**
   * Find a top-level command by name or alias (excludes child commands)
   */
  protected findTopLevelCommand(name: string): CommandPrimitive<TObject> | undefined;
  /**
   * Find all pre-hooks for a command (commands named `pre{commandName}`)
   */
  protected findPreHooks(commandName: string): CommandPrimitive<TObject>[];
  /**
   * Find all post-hooks for a command (commands named `post{commandName}`)
   */
  protected findPostHooks(commandName: string): CommandPrimitive<TObject>[];
  /**
   * Get global flags (help only, root command flags are NOT global)
   */
  protected getAllGlobalFlags(): Record<string, {
    aliases: string[];
    description?: string;
    schema: TSchema;
  }>;
  /**
   * Read a schema's metadata (`title`, `description`, `aliases`, `alias`, …).
   *
   * Under zod these options live on the schema's `.meta()` registry rather than
   * as direct properties (typebox), and they sit on the INNER schema — so any
   * optional / nullable / default wrappers are peeled first.
   */
  protected schemaMeta(schema: TSchema | undefined): Record<string, any>;
  /**
   * Build flag definitions (key, aliases, description, schema) from a flags
   * object schema. Centralises the metadata reading so every call-site (parsing,
   * arg-splitting, help) extracts aliases/descriptions the same way.
   */
  protected extractFlagDefs(schema: TObject): Array<{
    key: string;
    aliases: string[];
    description?: string;
    schema: TSchema;
  }>;
  /**
   * Parse command flags from argv using the command's flag schema
   */
  protected parseCommandFlags(argv: string[], schema: TObject, options?: {
    modeEnabled?: boolean;
  }): Record<string, any>;
  /**
   * Parse and validate environment variables using the command's env schema
   */
  protected parseCommandEnv(schema: TObject, commandName: string): Record<string, any>;
  /**
   * Parse --mode or -m flag from argv for environment file loading
   */
  protected parseModeFlag(argv: string[]): string | undefined;
  /**
   * Load .env and .env.{mode} files into process.env
   */
  protected loadModeEnv(root: string, mode: string | undefined): Promise<void>;
  /**
   * Low-level flag parser - extracts flag values from argv based on definitions
   */
  protected parseFlags(argv: string[], flagDefs: {
    key: string;
    aliases: string[];
    schema: TSchema;
  }[], options?: {
    strict?: boolean;
  }): Record<string, any>;
  /**
   * Convert a raw flag value string into the value its schema expects.
   *
   * zod no longer coerces, so scalar values (number / integer / boolean) are
   * cast + validated via {@link parseArgumentValue} (same path as positional
   * args); object / array / record values are JSON-parsed. `schema` is expected
   * to already be unwrapped of optional/nullable/default.
   */
  protected castFlagValue(value: string, schema: TSchema, rawKey: string): any;
  /**
   * Get indices of argv elements consumed by flags (for separating args from flags)
   */
  protected getFlagConsumedIndices(argv: string[], flagDefs: {
    key: string;
    aliases: string[];
    schema: TSchema;
  }[]): Set<number>;
  protected parseCommandArgs(argv: string[], schema?: TSchema, isRootCommand?: boolean, flagSchema?: TObject): any;
  /**
   * Convert a string argument value to the appropriate type based on schema
   */
  protected parseArgumentValue(value: string, schema: TSchema): any;
  /**
   * Generate usage string for command arguments (e.g., "<path>" or "[path]")
   */
  protected generateArgsUsage(schema?: TSchema): string;
  /**
   * Get display type name for a schema (e.g., ": number", ": boolean")
   */
  protected getTypeName(schema: TSchema): string;
  /**
   * Print help for a specific command or general CLI help.
   *
   * @param command - If provided, shows help for this specific command.
   *                  If omitted, shows general CLI help with all commands.
   */
  printHelp(command?: CommandPrimitive<any>): void;
  /**
   * Generate colored usage string for command arguments (for help display)
   */
  protected generateColoredArgsUsage(schema?: TSchema): string;
  /**
   * Get the full command path (e.g., "deploy vercel" for a nested command)
   */
  protected getCommandPath(command: CommandPrimitive<any>): string;
  /**
   * Find the parent command of a nested command
   */
  protected findParentCommand(command: CommandPrimitive<any>): CommandPrimitive<any> | undefined;
  /**
   * Get top-level commands (commands that are not children of other commands)
   */
  protected getTopLevelCommands(): CommandPrimitive<any>[];
  /**
   * Calculate max display length for child commands (for help alignment)
   */
  protected getMaxChildCmdLength(children: CommandPrimitive<any>[]): number;
  /**
   * Calculate max display length for commands (for help alignment)
   */
  protected getMaxCmdLength(commands: CommandPrimitive[]): number;
  /**
   * Calculate max display length for flags (for help alignment)
   */
  protected getMaxFlagLength(flags: {
    aliases: string[];
  }[]): number;
  /**
   * Extract enum values from a schema if it represents an enum.
   * Returns undefined if the schema is not an enum.
   */
  protected getEnumValues(schema: TSchema): string[] | undefined;
  /**
   * Format flag description with enum values if applicable.
   */
  protected formatFlagDescription(description: string | undefined, schema: TSchema | undefined): string;
}
//#endregion
//#region ../../src/command/index.d.ts
/**
 * Declarative CLI command framework.
 *
 * **Features:**
 * - CLI command definitions
 * - Interactive CLI prompts (plain readline)
 * - Command execution with streamed, verbose output
 * - Environment variable utilities
 * - Schema validation for CLI arguments
 *
 * @module alepha.command
 */
declare const AlephaCommand: import("alepha").Service<import("alepha").Module>;
declare module "alepha" {
  interface StringOptions {
    /**
     * Additional aliases for the flags.
     *
     * @module alepha.command
     */
    aliases?: string[];
  }
}
//#endregion
export { $command, AlephaCommand, AskMethod, AskOptions, Asker, CliProvider, CliProviderOptions, CommandError, CommandHandlerArgs, CommandPrimitive, CommandPrimitiveOptions, EnvUtils, RunOptions, Runner, RunnerMethod, Task, cliOptions };
//# sourceMappingURL=index.d.ts.map