Summary
The Console is shipping a guided "Let's build a new Actor!" wizard (use-case → language → best-match template → where the source lives). We want the same guided experience in the CLI, so that developers and AI agents are led through Actor creation, and so a user who starts in the Console can hit "Use locally" and continue seamlessly in the terminal.
This reshapes the existing apify create command rather than adding a new one.
Console wizard being mirrored
- What do you want to build? — Web scraper · API & data pipeline · AI agent · Skip (show all)
- Which language do you prefer? — JavaScript · TypeScript · Python · Other (bring-your-own runtime via Docker)
- Here's your best match — recommended template(s)
- Where will the source code live? — Apify · Connect GitHub/GitLab/Bitbucket (Apify creates the repo, builds on every push)
Bottom bar: "Use locally" (→ CLI) and "Create Actor" (→ Console).
Guiding principle
The wizard is an interactive flag-filler. Every step maps to exactly one flag. Humans answer prompts, agents pass flags, and the Console's "Use locally" button emits the identical apify create … line. No flag is wizard-only; no step lacks a flag.
This single rule gives us human, agent, and Console-handoff support from one surface.
Reshaped apify create wizard (order mirrors the Console)
apify create
→ Name your Actor [actorName arg]
→ What are you building? [-u, --use-case] web-scraping · api-pipeline · ai-agent · (skip = all)
→ Which language? [-l, --language] JavaScript · TypeScript · Python · Other (BYO Docker)
→ Here's your best match [-t, --template] recommended first; SKIP this prompt if the filter leaves exactly one
→ Where will the source live? [--source] Apify · GitHub · GitLab · Bitbucket
└─ (provider) → git connect flow
→ confirm / install
@inquirer/select per-choice description lines give us the Console's card subtitles (e.g. "Crawlee + Node.js. The most popular runtime on Apify.").
Flag surface
| Flag |
Values |
Notes |
[actorName] |
string |
exists (= directory) |
-u, --use-case |
web-scraping|api-pipeline|ai-agent |
new; filter; omit = all |
-l, --language |
javascript|typescript|python|other (aliases js, ts, docker) |
new; filter; other = BYO Docker, no dependency install |
-t, --template |
id |
exists; authoritative — overrides -u/-l, warn on mismatch |
--source |
apify|github|gitlab|bitbucket |
new; default apify; providers route to a connect URL |
--git-repo |
owner/name |
new; optional target repo name with a provider source |
--json |
— |
new; { dir, actorJsonPath, template, source, remote?, gitConnectUrl?, nextSteps[] } |
--yes |
— |
non-interactive confirm |
--origin |
console|cli |
new, hidden; Console "Use locally" sets console for funnel telemetry |
| existing |
--skip-dependency-install, --omit-optional-deps, --skip-git-init, --template-archive-url |
unchanged |
Three consumers, one command
- Human:
apify create, answer prompts.
- Agent:
apify create acme -u web-scraping -l python -t python-crawlee --source apify --yes --json. Discovers valid enums via apify templates ls --json (exposes useCases[] + recommended) — never scrapes --help.
- Console "Use locally": emits that exact line with
--origin console.
Git flow (--source <provider>) — resolved
The local scaffold is the source of truth; the Apify platform creates the repo from it, browser only for one-time provider auth.
1. collect choices
2. scaffold template → git init → initial commit ← local files exist immediately
3. ensure provider authorized → open browser to verify/authorize (one-time only)
4. Apify platform creates the repo on the connected provider,
creates the Actor (sourceType=GIT_REPO, gitRepoUrl), returns the remote URL
5. git remote add origin <url> → git push -u origin main
6. ✔ connected — Apify rebuilds on every push
- Provider-agnostic: the browser does the auth, so
--source github|gitlab|bitbucket just picks which connect URL to open — no per-provider code in the CLI.
- Agent-safe: provider already authorized + no TTY → steps 3–5 run fully non-interactively. Not authorized → emit
gitConnectUrl / nextSteps[] in --json and never block on a browser.
Notes & scope boundaries
- "Other" language = bring-your-own runtime via Docker. No
package.json/requirements.txt to seed — scaffold .actor/actor.json + Dockerfile + stubs only. useCwdProject resolves to Unknown, so create must take the no-install branch cleanly (git init still runs). Needs an other/docker template in the manifest (stopgap: a CLI built-in Dockerfile starter).
- "Import from Git" (Console's top-right button) = register an existing repo, not template scaffolding → tracked separately as
apify actor connect-git / apify import. Out of scope here.
Cross-team dependencies
Summary
The Console is shipping a guided "Let's build a new Actor!" wizard (use-case → language → best-match template → where the source lives). We want the same guided experience in the CLI, so that developers and AI agents are led through Actor creation, and so a user who starts in the Console can hit "Use locally" and continue seamlessly in the terminal.
This reshapes the existing
apify createcommand rather than adding a new one.Console wizard being mirrored
Bottom bar: "Use locally" (→ CLI) and "Create Actor" (→ Console).
Guiding principle
This single rule gives us human, agent, and Console-handoff support from one surface.
Reshaped
apify createwizard (order mirrors the Console)@inquirer/selectper-choicedescriptionlines give us the Console's card subtitles (e.g. "Crawlee + Node.js. The most popular runtime on Apify.").Flag surface
[actorName]-u, --use-caseweb-scraping|api-pipeline|ai-agent-l, --languagejavascript|typescript|python|other(aliasesjs,ts,docker)other= BYO Docker, no dependency install-t, --template-u/-l, warn on mismatch--sourceapify|github|gitlab|bitbucketapify; providers route to a connect URL--git-repoowner/name--json{ dir, actorJsonPath, template, source, remote?, gitConnectUrl?, nextSteps[] }--yes--originconsole|cliconsolefor funnel telemetry--skip-dependency-install,--omit-optional-deps,--skip-git-init,--template-archive-urlThree consumers, one command
apify create, answer prompts.apify create acme -u web-scraping -l python -t python-crawlee --source apify --yes --json. Discovers valid enums viaapify templates ls --json(exposesuseCases[]+recommended) — never scrapes--help.--origin console.Git flow (
--source <provider>) — resolvedThe local scaffold is the source of truth; the Apify platform creates the repo from it, browser only for one-time provider auth.
--source github|gitlab|bitbucketjust picks which connect URL to open — no per-provider code in the CLI.gitConnectUrl/nextSteps[]in--jsonand never block on a browser.Notes & scope boundaries
package.json/requirements.txtto seed — scaffold.actor/actor.json+Dockerfile+ stubs only.useCwdProjectresolves toUnknown, socreatemust take the no-install branch cleanly (git initstill runs). Needs another/docker template in the manifest (stopgap: a CLI built-in Dockerfile starter).apify actor connect-git/apify import. Out of scope here.Cross-team dependencies
@apify/actor-templates— adduseCases[]+recommendedper template, and another/Docker BYO template. (Steps 1 & 3 are data-driven off this; CLI hardcodes a use-case→template map as a stopgap until then.)backend/t-core-services) — "create git-backed Actor + create repo on the connected provider" call (step 4).