@@ -344,13 +344,20 @@ export declare namespace create {
344344 usage ?: Usage < args , options > [ ] | undefined
345345 /** Zod schema for middleware variables. Keys define variable names, schemas define types and defaults. */
346346 vars ?: vars | undefined
347+ /**
348+ * Opts into receiving `--dry-run` invocations. When `true`, `run()` is called with `c.dryRun = true`
349+ * instead of the framework returning a schema-derived preview.
350+ */
351+ dryRun ?: true | undefined
347352 /** The root command handler. When provided, creates a leaf CLI with no subcommands. */
348353 run ?:
349354 | ( ( context : {
350355 /** Whether the consumer is an agent (stdout is not a TTY). */
351356 agent : boolean
352357 /** Positional arguments. */
353358 args : InferOutput < args >
359+ /** Whether this is a dry-run invocation. Only `true` when the command sets `dryRun: true`. */
360+ dryRun : boolean
354361 /** Parsed environment variables. */
355362 env : InferOutput < env >
356363 /** Return an error result with optional CTAs. */
@@ -429,6 +436,7 @@ async function serveImpl(
429436
430437 const {
431438 verbose,
439+ dryRun,
432440 format : formatFlag ,
433441 formatExplicit,
434442 filterOutput,
@@ -1142,6 +1150,7 @@ async function serveImpl(
11421150 const mwCtx : MiddlewareContext = {
11431151 agent : ! human ,
11441152 command : path ,
1153+ dryRun,
11451154 env : cliEnv ,
11461155 error : errorFn ,
11471156 format,
@@ -1217,6 +1226,7 @@ async function serveImpl(
12171226 const result = await Command . execute ( command , {
12181227 agent : ! human ,
12191228 argv : rest ,
1229+ dryRun,
12201230 env : options . envSchema ,
12211231 envSource : options . env ,
12221232 format,
@@ -1258,6 +1268,7 @@ async function serveImpl(
12581268 meta : {
12591269 command : path ,
12601270 duration,
1271+ ...( result . dryRun ? { dryRun : true } : undefined ) ,
12611272 ...( cta ? { cta } : undefined ) ,
12621273 } ,
12631274 } )
@@ -1302,6 +1313,8 @@ async function serveImpl(
13021313/** @internal Options for fetchImpl. */
13031314declare namespace fetchImpl {
13041315 type Options = {
1316+ /** Whether this is a dry-run invocation. */
1317+ dryRun ?: boolean | undefined
13051318 /** CLI-level env schema. */
13061319 envSchema ?: z . ZodObject < any > | undefined
13071320 /** Group-level middleware collected during command resolution. */
@@ -1391,6 +1404,7 @@ async function fetchImpl(
13911404 options : fetchImpl . Options = { } ,
13921405) : Promise < Response > {
13931406 const start = performance . now ( )
1407+ if ( req . headers . get ( 'x-dry-run' ) === 'true' ) options = { ...options , dryRun : true }
13941408
13951409 const url = new URL ( req . url )
13961410 const segments = url . pathname . split ( '/' ) . filter ( Boolean )
@@ -1542,6 +1556,7 @@ async function executeCommand(
15421556 const result = await Command . execute ( command , {
15431557 agent : true ,
15441558 argv : rest ,
1559+ dryRun : options . dryRun ,
15451560 env : options . envSchema ,
15461561 format : 'json' ,
15471562 formatExplicit : true ,
@@ -1627,6 +1642,7 @@ async function executeCommand(
16271642 meta : {
16281643 command : path ,
16291644 duration,
1645+ ...( result . dryRun ? { dryRun : true } : undefined ) ,
16301646 ...( cta ? { cta } : undefined ) ,
16311647 } ,
16321648 } ,
@@ -1794,6 +1810,7 @@ declare namespace serveImpl {
17941810/** @internal Extracts built-in flags (--verbose, --format, --json, --llms, --help, --version) from argv. */
17951811function extractBuiltinFlags ( argv : string [ ] ) {
17961812 let verbose = false
1813+ let dryRun = false
17971814 let llms = false
17981815 let llmsFull = false
17991816 let mcp = false
@@ -1811,6 +1828,7 @@ function extractBuiltinFlags(argv: string[]) {
18111828 for ( let i = 0 ; i < argv . length ; i ++ ) {
18121829 const token = argv [ i ] !
18131830 if ( token === '--verbose' ) verbose = true
1831+ else if ( token === '--dry-run' ) dryRun = true
18141832 else if ( token === '--llms' ) llms = true
18151833 else if ( token === '--llms-full' ) llmsFull = true
18161834 else if ( token === '--mcp' ) mcp = true
@@ -1839,6 +1857,7 @@ function extractBuiltinFlags(argv: string[]) {
18391857
18401858 return {
18411859 verbose,
1860+ dryRun,
18421861 format,
18431862 formatExplicit,
18441863 filterOutput,
@@ -2517,6 +2536,14 @@ type CommandDefinition<
25172536 * @default 'all'
25182537 */
25192538 outputPolicy ?: OutputPolicy | undefined
2539+ /**
2540+ * Opts into receiving `--dry-run` invocations. When `true`, `run()` is called with `c.dryRun = true`
2541+ * instead of the framework returning a schema-derived preview. Use this for commands that need custom
2542+ * dry-run logic (e.g. showing which files would be deleted, which repos would be synced).
2543+ *
2544+ * When not set, `--dry-run` returns a preview of parsed inputs and the output schema without calling `run()`.
2545+ */
2546+ dryRun ?: true | undefined
25202547 /** Middleware that runs only for this command, after root and group middleware. */
25212548 middleware ?: MiddlewareHandler < vars , cliEnv > [ ] | undefined
25222549 /** Alternative usage patterns shown in help output. */
@@ -2527,6 +2554,8 @@ type CommandDefinition<
25272554 agent : boolean
25282555 /** Positional arguments. */
25292556 args : InferOutput < args >
2557+ /** Whether this is a dry-run invocation. Only `true` when the command sets `dryRun: true`. */
2558+ dryRun : boolean
25302559 /** Parsed environment variables. */
25312560 env : InferOutput < env >
25322561 /** Return an error result with optional CTAs. */
0 commit comments