import { PadroneProgress, PadroneRuntime } from "../core/runtime.mjs"; import { PadroneSchema } from "./schema.mjs"; import { FindDirectChild, FlattenCommands, FullCommandName, MaybePromise, OrAsync, OrAsyncMeta, PickCommandByName, PickCommandByPossibleCommands, PossibleCommands, RepathCommands, ReplaceOrAppendCommand, SafeString } from "../util/type-utils.mjs"; import { PadroneLogger } from "../extension/logger.mjs"; import { PadroneTracer } from "../extension/tracing.mjs"; import { PadroneMcpPreferences } from "../feature/mcp.mjs"; import { PadroneServePreferences } from "../feature/serve.mjs"; import { WrapConfig, WrapResult } from "../feature/wrap.mjs"; import { HelpPreferences } from "../output/help.mjs"; import { ExtractInterceptorContext, InterceptorFactory, InterceptorMeta, InterceptorRequiresCheck, InterceptorRequiresError, PadroneContextInterceptor, PadroneInterceptorFn } from "./interceptor.mjs"; import { AnyPadroneCommand, CommandTypesBase, GetArgsMeta, PadroneActionContext, PadroneCommand, PadroneCommandConfig, PadroneProgramMeta } from "./command.mjs"; import { PadroneCliPreferences, PadroneEvalPreferences, PadroneReplPreferences } from "./preferences.mjs"; import { GetArguments, MaybePromiseCommandResult, PadroneAPI, PadroneCommandResult, PadroneDrainResult, PadroneParseResult } from "./result.mjs"; import { StandardSchemaV1 } from "@standard-schema/spec"; import { Tool } from "ai"; //#region src/types/builder.d.ts /** * Helper type to set aliases on a command type. * Uses intersection to override just the aliases while preserving all other type information. */ type WithAliases = Omit & { aliases?: TAliases; '~types': Omit & { aliases: TAliases; }; }; /** * Resolves aliases for a command override: if new aliases are provided (non-empty), use them; * otherwise, preserve the existing command's aliases. */ type ResolvedAliases = TAliases extends [] ? FindDirectChild extends infer E extends AnyPadroneCommand ? E['~types']['aliases'] : [] : TAliases; /** * When TContext is `unknown` (no `.context()` called), context param is optional. * Otherwise it is required. */ type ContextParam = unknown extends TContext ? { context?: TContext; } : { context: TContext; }; /** Options for the `mount()` method. */ type MountOptions = { context: (ctx: TContext) => TNewContext; }; /** * Resolves the initial builder type for a `.command()` call. * If TNameNested already exists in TCommands, the builder starts pre-populated with that command's types. * Otherwise, a fresh builder with default types is used. */ type InitialCommandBuilder = [FindDirectChild] extends [never] ? PadroneBuilder, void, [], TParentArgs, false, TParentContext> : FindDirectChild extends infer E extends AnyPadroneCommand ? PadroneBuilder : PadroneBuilder, void, [], TParentArgs, false, TParentContext>; type AnyPadroneBuilder = InitialCommandBuilder; /** * Like InitialCommandBuilder but uses `any` for args in the fresh case. * Used as the default for TBuilder when no builderFn is provided. */ type DefaultCommandBuilder = [FindDirectChild] extends [never] ? PadroneBuilder : FindDirectChild extends infer E extends AnyPadroneCommand ? PadroneBuilder : PadroneBuilder; /** * Conditional type that returns either PadroneBuilder or PadroneProgram based on TReturn. * Used to avoid repetition in PadroneBuilderMethods return types. */ type BuilderOrProgram = TReturn extends 'builder' ? PadroneBuilder : PadroneProgram; /** * Base builder methods shared between PadroneBuilder and PadroneProgram. * These methods are used for defining command structure (arguments, action, subcommands). */ type PadroneBuilderMethods = { /** Apply a build-time extension that transforms this builder/program. @category Builder */extend: (extension: PadroneExtension, TResult>) => TResult; /** Register a runtime interceptor for lifecycle phases (parse, validate, execute, etc.). @category Builder */ intercept: { /** Context-providing interceptor — extends context type. Rejects if required context is not satisfied. */, TRes, any>>(interceptor: TInterceptor): InterceptorRequiresCheck extends true ? BuilderOrProgram> : InterceptorRequiresError; /** Plain interceptor — no context change. Rejects if required context is not satisfied. */ , TRes, any>>(interceptor: TInterceptor): InterceptorRequiresCheck extends true ? BuilderOrProgram : InterceptorRequiresError; /** Register an interceptor with static metadata and a factory function. Context is strongly typed. */ (meta: InterceptorMeta, factory: InterceptorFactory, TRes, TContext & TContextProvided>): BuilderOrProgram; }; /** Set command metadata like title, description, version, hidden, deprecated, etc. @category Builder */ configure: (config: PadroneCommandConfig) => BuilderOrProgram; /** Override the runtime adapter (process, IO, environment). @category Builder */ runtime: (runtime: PadroneRuntime) => BuilderOrProgram; /** Mark this command as async, forcing all return types to be `Promise`-wrapped. @category Builder */ async: () => BuilderOrProgram; /** * Declare or transform the user-defined context type for this command. * * - Without a callback: narrows the context type (type-only, no runtime transform). * - With a callback: transforms the parent/current context into a new type. Chainable — multiple calls compose. * * Interceptor-provided context (`TContextProvided`) is preserved across `.context()` calls. * @category Builder */ context: { (): BuilderOrProgram; (transform: (ctx: TContext) => TNewContext): BuilderOrProgram; }; /** Define the argument/option schema for this command. Accepts a Standard Schema or a function that extends the parent schema. @category Builder */ arguments: , TMeta extends GetArgsMeta = GetArgsMeta>(schema?: TNewArgs | ((parentSchema: TParentArgs) => TNewArgs), meta?: TMeta) => BuilderOrProgram, TMeta>, TContext, TContextProvided>; /** Set the handler function that runs when this command is executed. @category Builder */ action: (handler?: (args: StandardSchemaV1.InferOutput, ctx: PadroneActionContext, base: (args: StandardSchemaV1.InferOutput, ctx: PadroneActionContext) => TRes) => TNewRes) => BuilderOrProgram; /** Wrap an external CLI tool, delegating execution to a shell command. @category Builder */ wrap: (config: WrapConfig) => BuilderOrProgram, TCommands, TParentArgs, TAsync, TContext, TContextProvided>; /** Add or override a subcommand. Pass a builder function to define its schema, action, and nested commands. @category Builder */ command: { , TArgs, TCommands, TContext & TContextProvided>>(name: TNameNested | readonly [TNameNested, ...TAliases], builderFn?: (builder: InitialCommandBuilder, TArgs, TCommands, TContext & TContextProvided>) => TBuilder): BuilderOrProgram] : AnyPadroneCommand[] extends TCommands ? [WithAliases] : ReplaceOrAppendCommand>>, TParentArgs, TAsync, TContext, TContextProvided>; (name: TNameNested | readonly [TNameNested, ...TAliases], builderFn: ((builder: any) => TBuilder) & { '~contextRequires': (ctx: TReq) => void; }): TContext & TContextProvided extends TReq ? BuilderOrProgram] : AnyPadroneCommand[] extends TCommands ? [WithAliases] : ReplaceOrAppendCommand>>, TParentArgs, TAsync, TContext, TContextProvided> : DefineCommandRequiresError; (name: TNameNested | readonly [TNameNested, ...TAliases], builderFn?: (builder: any) => TBuilder): BuilderOrProgram] : AnyPadroneCommand[] extends TCommands ? [WithAliases] : ReplaceOrAppendCommand>>, TParentArgs, TAsync, TContext, TContextProvided>; }; /** Mount an existing program as a subcommand, optionally transforming the context. @category Builder */ mount: { (name: TNameNested | readonly [TNameNested, ...TAliases], program: TProgram): BuilderOrProgram, TProgram['~types']['command']['~types']['argsSchema'], TProgram['~types']['command']['~types']['result'], RepathCommands>>, [], TProgram['~types']['command']['~types']['async'], TContext & TContextProvided>, TAliases>] : AnyPadroneCommand[] extends TCommands ? [WithAliases, TProgram['~types']['command']['~types']['argsSchema'], TProgram['~types']['command']['~types']['result'], RepathCommands>>, [], TProgram['~types']['command']['~types']['async'], TContext & TContextProvided>, TAliases>] : ReplaceOrAppendCommand, TProgram['~types']['command']['~types']['argsSchema'], TProgram['~types']['command']['~types']['result'], RepathCommands>>, [], TProgram['~types']['command']['~types']['async'], TContext & TContextProvided>, ResolvedAliases>>, TParentArgs, TAsync, TContext, TContextProvided>; (name: TNameNested | readonly [TNameNested, ...TAliases], program: TProgram, options: MountOptions): BuilderOrProgram, TProgram['~types']['command']['~types']['argsSchema'], TProgram['~types']['command']['~types']['result'], RepathCommands>>, [], TProgram['~types']['command']['~types']['async'], TNewContext>, TAliases>] : AnyPadroneCommand[] extends TCommands ? [WithAliases, TProgram['~types']['command']['~types']['argsSchema'], TProgram['~types']['command']['~types']['result'], RepathCommands>>, [], TProgram['~types']['command']['~types']['async'], TNewContext>, TAliases>] : ReplaceOrAppendCommand, TProgram['~types']['command']['~types']['argsSchema'], TProgram['~types']['command']['~types']['result'], RepathCommands>>, [], TProgram['~types']['command']['~types']['async'], TNewContext>, ResolvedAliases>>, TParentArgs, TAsync, TContext, TContextProvided>; }; /** @deprecated Internal use only */ '~types': { programName: TProgramName; name: TName; parentName: TParentName; path: FullCommandName; aliases: []; argsSchema: TArgs; result: TRes; commands: TCommands; async: TAsync; context: TContext; contextProvided: TContextProvided; command: PadroneCommand; }; }; type PadroneBuilder, TRes = void, TCommands extends [...AnyPadroneCommand[]] = [], TParentArgs extends PadroneSchema = PadroneSchema, TAsync extends boolean = false, TContext = unknown, TContextProvided = unknown> = PadroneBuilderMethods; type PadroneProgram, TRes = void, TCommands extends [...AnyPadroneCommand[]] = [], TParentArgs extends PadroneSchema = PadroneSchema, TAsync extends boolean = false, TContext = unknown, TContextProvided = unknown> = PadroneBuilderMethods & { /** Execute a command by name with pre-validated args (skips parsing and validation). @category Execution */run: ], true, true>>(name: TCommand | SafeString, args: NoInfer], TCommand>>>, prefs?: ContextParam) => PadroneCommandResult], TCommand>>; /** Parse and execute a string input through the full interceptor pipeline. @category Execution */ eval: ], true, true>>(input: TCommand | SafeString, prefs?: PadroneEvalPreferences & ContextParam) => MaybePromiseCommandResult], TCommand>, PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>['~types']['async']>; /** Parse and execute from `process.argv` through the full interceptor pipeline. @category Execution */ cli: (prefs?: PadroneCliPreferences & ContextParam) => MaybePromiseCommandResult]>, TAsync>; /** Parse and validate input without executing the action. @category Execution */ parse: ], true, false>>(input?: TCommand | SafeString) => MaybePromise], TCommand>>, PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>['~types']['async']>; /** Serialize args back into a CLI string. @category Utility */ stringify: ], false, true>>(command?: TCommand | SafeString, args?: GetArguments<'out', PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>>) => string; /** Look up a command definition by name. @category Utility */ find: ], false, true>>(command: TFind | SafeString) => PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TFind> | undefined; /** Get a structured API representation of all commands. @category Utility */ api: () => PadroneAPI>; /** Start an interactive REPL session. @category Execution */ repl: (options?: PadroneReplPreferences]>>) => AsyncIterable]>>> & { drain: () => Promise]>>[]>>; }; /** Export as an AI SDK tool. @category Utility */ tool: () => Tool<{ command: string; }>; /** Generate help text for a command. @category Utility */ help: ], false, true>>(command?: TCommand, prefs?: HelpPreferences) => string; /** Generate shell completion script. @category Utility */ completion: (shell?: 'bash' | 'zsh' | 'fish' | 'powershell') => Promise; /** Start a Model Context Protocol server. @category Server */ mcp: (prefs?: PadroneMcpPreferences) => Promise; /** Start a REST HTTP server with OpenAPI docs. @category Server */ serve: (prefs?: PadroneServePreferences) => Promise; /** Read-only metadata about the program (name, version, description, commands, etc.). @category Utility */ info: PadroneProgramMeta; }; type AnyPadroneProgram = PadroneProgram; /** * A build-time extension that transforms a builder/program. * Extensions can add commands, arguments, interceptors, configure settings, etc. * * Use with `.extend(extension)`: * ```ts * const withAuth = (b) => b.arguments(authSchema).command('login', ...) * program.extend(withAuth) * ``` */ type PadroneExtension = (builder: TIn) => TOut; /** * Default context type for commands defined with `defineCommand()`. * Includes optional context properties provided by common extensions (logger, tracing, progress). * * Override globally via module augmentation to add your application's context: * ```ts * declare module 'padrone' { * interface DefineCommandContext { * db: Database; * } * } * ``` */ interface DefineCommandContext { logger?: PadroneLogger; tracing?: PadroneTracer; progress?: PadroneProgress; } /** Error brand returned by `.command()` when a `defineCommand.requires()` context requirement is not satisfied. */ type DefineCommandRequiresError = { readonly '~error': 'Required context not satisfied. Ensure required interceptors are registered on the program.'; }; /** * Type for a command builder callback used with `.command()`. * Use this when defining commands in separate files where full return type inference isn't needed. * * For full type preservation at the parent, use `defineCommand()` instead. * * @example * ```ts * // my-command.ts * export const myCommand: DefineCommand = (c) => * c.arguments(z.object({ name: z.string() })) * .action((args) => console.log(args.name)); * * // cli.ts * createPadrone('test').command('my-command', myCommand) * ``` */ type DefineCommand = (builder: PadroneBuilder, void, [], TParentArgs, false, TContext, DefineCommandContext>) => CommandTypesBase; /** * Builder returned by `defineCommand()` (no-arg form). * Call `.requires()` to declare context dependencies, then `.command()` to provide the builder callback. * * @example * ```ts * const adminCommand = defineCommand() * .requires<{ adminDb: AdminDB }>() * .define((c) => c.action((_args, ctx) => ctx.context.adminDb.query(...))); * ``` */ type DefineCommandBuilder = { /** Declare context types this command requires. Purely type-level — no runtime effect. */requires: () => DefineCommandBuilder void; }>; /** Provide the command builder callback. */ define: (fn: (builder: PadroneBuilder, void, [], any, false, TContext, TContextProvided>) => TOut) => typeof fn & TBrand; }; type DefaultArgs = Record | void; //#endregion export { AnyPadroneBuilder, AnyPadroneProgram, DefineCommand, DefineCommandBuilder, DefineCommandContext, DefineCommandRequiresError, PadroneBuilder, PadroneBuilderMethods, PadroneExtension, PadroneProgram }; //# sourceMappingURL=builder.d.mts.map