From 39bd5b7e48e3c501b964bd208df10a4a1772859d Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:23:23 -0400 Subject: [PATCH 1/2] feat: hidden `firecrawl create agent` command Wires a hidden `firecrawl create ` command tree into the root CLI. Only the `agent` kind is registered today; it delegates to `npx -y firecrawl-agent-cli create` with full flag passthrough so the agent repo remains the single source of truth for templates. The command is hidden from --help until `firecrawl-agent-cli` is on npm. Flip to visible by removing `{ hidden: true }` in index.ts. Surface: firecrawl create agent [name] [-t next|express|library] firecrawl create agent [name] --provider

--model firecrawl create agent [name] --api-key --key anthropic=sk-... firecrawl create agent [name] --from user/repo --- src/commands/create.ts | 149 +++++++++++++++++++++++++++++++++++++++++ src/index.ts | 6 ++ 2 files changed, 155 insertions(+) create mode 100644 src/commands/create.ts diff --git a/src/commands/create.ts b/src/commands/create.ts new file mode 100644 index 000000000..0b753f332 --- /dev/null +++ b/src/commands/create.ts @@ -0,0 +1,149 @@ +/** + * `firecrawl create` command — scaffolds Firecrawl starter projects. + * + * Hidden from --help until `firecrawl-agent-cli` is published to npm. + * Once visible, the command tree will grow to include additional kinds + * (scrape, browser, ai, app). For now, `agent` is the only kind. + * + * Implementation is a thin delegator: `firecrawl create agent ...` execs + * `npx -y firecrawl-agent-cli create ...` and passes all flags through. + * This avoids vendoring the scaffold code in the root CLI; the agent repo + * remains the single source of truth for templates and the manifest. + */ + +import { Command } from 'commander'; +import { spawn } from 'child_process'; + +/** npm package name of the Firecrawl Agent CLI (bin: `firecrawl-agent`). */ +const AGENT_CLI_PACKAGE = 'firecrawl-agent-cli'; + +/** + * Execute `npx -y create ...` with inherited stdio so + * the agent CLI's interactive prompts render in the user's terminal. + * Resolves with the child exit code; callers forward it to `process.exit`. + */ +function runAgentCli(args: string[]): Promise { + const npx = process.platform === 'win32' ? 'npx.cmd' : 'npx'; + return new Promise((resolve) => { + const child = spawn(npx, ['-y', AGENT_CLI_PACKAGE, 'create', ...args], { + stdio: 'inherit', + env: process.env, + }); + child.on('exit', (code) => resolve(code ?? 1)); + child.on('error', (err) => { + console.error( + `\nFailed to launch ${AGENT_CLI_PACKAGE} via npx:`, + err.message + ); + console.error( + `\n Install it directly and retry: npm install -g ${AGENT_CLI_PACKAGE}\n` + ); + resolve(1); + }); + }); +} + +function collect(val: string, acc: string[]): string[] { + acc.push(val); + return acc; +} + +/** + * Build the `agent` subcommand. Flag surface mirrors `firecrawl-agent create` + * exactly — anything the downstream CLI accepts is passed through verbatim. + */ +function createAgentSubcommand(): Command { + return new Command('agent') + .description( + 'Scaffold a Firecrawl Agent project (defaults to the Next.js template)' + ) + .argument('[project-name]', 'Project directory name') + .option( + '-t, --template ', + 'Template variant (next, express, library)', + 'next' + ) + .option( + '--provider ', + 'Orchestrator model provider (anthropic, openai, google, gateway, custom-openai)' + ) + .option('--model ', 'Orchestrator model ID') + .option( + '--sub-agent-provider ', + 'Sub-agent model provider (defaults to orchestrator)' + ) + .option( + '--sub-agent-model ', + 'Sub-agent model ID (defaults to orchestrator)' + ) + .option( + '--from ', + 'External repo (user/repo) or local path with agent-manifest.json' + ) + .option('--api-key ', 'Firecrawl API key') + .option( + '--key ', + 'Provider API key (repeatable, e.g. --key anthropic=sk-...)', + collect, + [] + ) + .option('--skip-install', 'Skip npm install') + .allowUnknownOption() // Forward future flags without requiring a CLI update + .action( + async ( + projectName: string | undefined, + options: Record, + cmd: Command + ) => { + const args: string[] = []; + if (projectName) args.push(projectName); + + // Pass through known options. Commander camelCases hyphenated flags, + // so we map back to the CLI-facing kebab-case form. + const flagMap: Array<[string, string]> = [ + ['template', '-t'], + ['provider', '--provider'], + ['model', '--model'], + ['subAgentProvider', '--sub-agent-provider'], + ['subAgentModel', '--sub-agent-model'], + ['from', '--from'], + ['apiKey', '--api-key'], + ]; + for (const [optKey, flag] of flagMap) { + const val = options[optKey]; + if (typeof val === 'string' && val.length > 0) args.push(flag, val); + } + + // --key is repeatable + const keys = options.key; + if (Array.isArray(keys)) { + for (const k of keys) { + if (typeof k === 'string' && k.length > 0) args.push('--key', k); + } + } + + if (options.skipInstall) args.push('--skip-install'); + + // Forward any unknown/forward-compatible options verbatim. + const passthrough = cmd.args.slice(projectName ? 1 : 0); + for (const extra of passthrough) args.push(extra); + + const code = await runAgentCli(args); + if (code !== 0) process.exit(code); + } + ); +} + +/** + * Top-level `firecrawl create` command. For now it only wires the `agent` + * subcommand; future kinds (scrape, browser, ai, app) register here. + */ +export function createCreateCommand(): Command { + const cmd = new Command('create').description( + 'Scaffold a Firecrawl starter project' + ); + + cmd.addCommand(createAgentSubcommand()); + + return cmd; +} diff --git a/src/index.ts b/src/index.ts index 3e4dbd6b0..1faec0138 100644 --- a/src/index.ts +++ b/src/index.ts @@ -50,6 +50,7 @@ import { createCodexCommand, createOpenCodeCommand, } from './commands/experimental'; +import { createCreateCommand } from './commands/create'; // Initialize global configuration from environment variables initializeConfig(); @@ -1191,6 +1192,11 @@ program.addCommand(createInteractCommand()); // Hidden: deprecated browser command (still works, just not in --help) program.addCommand(createBrowserCommand(), { hidden: true }); +// Hidden: `firecrawl create ` — scaffolds Firecrawl starter projects. +// Undocumented until `firecrawl-agent-cli` is published to npm; flip to +// visible by removing `{ hidden: true }`. +program.addCommand(createCreateCommand(), { hidden: true }); + // Experimental: download, AI workflow commands const experimental = new Command('experimental') .description('Experimental commands (download, AI workflows)') From fa0b3002099f4e3fcc81a2f1f18798bc6074707a Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:31:03 -0400 Subject: [PATCH 2/2] bump version to 1.15.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4627b2b73..d375599ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firecrawl-cli", - "version": "1.14.9", + "version": "1.15.0", "description": "Command-line interface for Firecrawl. Scrape, crawl, and extract data from any website directly from your terminal.", "main": "dist/index.js", "bin": {