feat(create): machine-readable --json output and hidden --origin flag - #1280
Draft
l2ysho wants to merge 7 commits into
Conversation
- Enable --json on `apify create`: prints { dir, actorJsonPath, template,
source, nextSteps }. Progress/logs stay on stderr.
- Add hidden --origin console|cli flag for funnel telemetry (default cli).
- Extract buildNextSteps(), shared by the --json output and success message.
- templates ls: render the language label ("JavaScript") not the raw category.
Refs #1238
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…use-case-language-best-match-template' into pr1280-conflicts # Conflicts: # docs/reference.md
…match-template' into 1238-apify-create-machine-readable-json-origin
Child process output was inherited onto the CLI's own stdout, so `git init` and the dependency installer transcript landed ahead of the JSON payload. `apify create --json | jq` failed on every invocation that did not pass both --skip-git-init and --skip-dependency-install, including the bare --json call that agents and the Console "Clone locally" handoff actually make. Add keepStdoutClean() to route child stdout to stderr, latched by the command framework whenever --json is set, so it covers every command with enableJsonFlag rather than just this one call site. Also include postCreate in the payload: 9 templates set it and two (python-playwright, python-selenium) document hard prerequisites, so an agent following nextSteps alone ended up with a broken Actor. Add gitRepositoryInitialized so a failed git init is visible to machine callers. The tests searched for the JSON among other stdout lines, which tolerated the pollution; they now require stdout to be exactly the payload. --origin is asserted through telemetry instead of a duplicated payload check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@inquirer/core pipes to process.stdout unless handed a context, so every prompt wrote its UI escape sequences and the persisted answer line to stdout. That corrupts the payload of any command invoked with --json — reachable from `apify create` whenever the Actor name or template is omitted, and unconditionally when the target directory already exists. Prompts are UI, not command output, so route all five wrappers to stderr. Also give useSelectFromList its own errorMessageForStdin: it inherited the confirmation default and told users to pass --confirm/--no-confirm, flags that do not exist on any of the commands that use it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…match-template' into 1238-apify-create-machine-readable-json-origin
`--template` matched only the manifest `name`, but the new `--json` payload reports the template `id` — and 19 of 43 templates have `id !== name`, so the value the machine-readable output emits was rejected on round-trip. The `--help` example `--template js-crawlee-cheerio` was broken for the same reason. Resolve against either field. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1238. Stacked on #1278 (base = the
1236wizard branch); rebase onto master after that merges.Makes
apify createmachine-readable for agents and the Console "Clone locally" handoff.What changed
--jsononapify createprints a contract on stdout:{ "dir", "actorJsonPath", "template", "source": "apify", "nextSteps": [], "postCreate": null, "gitRepositoryInitialized": false }postCreateis non-null when the template needs extra setup beforeapify runworks (e.g.python-playwrightneedsplaywright install --with-deps) — 9 of 43 templates set it, and dropping it left agents with a broken Actor.gitRepositoryInitializedreports whethergit initactually succeeded, since the human-only warning isn't machine-readable.All progress/
info/warningoutput stays on stderr. On error: non-zero exit, message on stderr, no stdout.Hidden
--origin console|cliflag (defaultcli) → recorded increatetelemetry for the funnel.stdout hygiene — two things were writing to stdout ahead of the payload, so
apify create --json | jqfailed on any invocation that didn't pass both--skip-git-initand--skip-dependency-install(i.e. the bare call agents and Console actually make):git initand the whole dependency-installer transcript on our stdout.keepStdoutClean()now routes child stdout to stderr, latched by the command framework whenever--jsonis set — so it covers every command withenableJsonFlag, not just this call site.@inquirer/corepipes toprocess.stdoutunless handed a context, so any prompt wrote escape sequences and the answer line to stdout. All five prompt wrappers now render on stderr (separate commit — prompts are UI, not command output, and this is correct independent of--json).Small:
buildNextSteps()extracted (shared by--jsonand the success message);templates lsshowsJavaScriptinstead of rawjavascript;useSelectFromListno longer tells users to pass--confirm/--no-confirm, flags that don't exist on the commands that use it.Not in scope (deferred, per the epic)
--source/--git-repoand the git-connect flow → separate sub-issue. So the contract omitsremote/gitConnectUrland hardcodessource: "apify"(the only behavior today).--jsonwithout--templatein a non-TTY still prompts, then fails.useStdinsetshasData = truefor any non-TTY stdin, so the intended "pass the flags" guard effectively only fires underisCI. With the prompts moved off stdout this is now a loud failure rather than a corrupted payload, but making--jsonstrictly non-interactive is still a follow-up. Agents/Console always pass--template.templateisnullon the hidden--template-archive-urlpath (internal, for templates not yet in the manifest).nullis the honest value there; the documented consumers always pass--template.Tests
14
createtests + a newexectest covering the stdout redirect (mutation-checked: it fails ifkeepStdoutClean()is neutered). The--jsontests previously searched for the JSON among other stdout lines, which tolerated the pollution; they now require stdout to be exactly the payload.--originis asserted through telemetry rather than a duplicated payload check, and theclidefault is covered too.Verified end to end against the built CLI: bare
create --template project_cheerio_crawler_js --jsonyields pure parseable JSON on stdout with the full npm transcript andgit initon stderr.pnpm run test:local→ 405 passed. The 2[python]fixture failures are pre-existing and environmental (they need Python ≥ 3.11; confirmed identical on the untouched tree). build / lint / format clean; docs regenerated.🤖 Generated with Claude Code