feat(cloud): open pre-filled Cloudflare token URL in browser - #61
Conversation
Cloudflare connect no longer routes through docs.polylane.com to create the API token. The CLI now builds the same pre-filled read-only token URL the console and docs use (duplicated from nominal's buildCloudflareTokenUrl, with a keep-in-sync note) and opens it directly in the browser; the ~13KB URL is never printed. Without a browser (--no-browser or declined), the flow prints tight in-terminal steps: the console's connect screen or the short dash.cloudflare.com deep link. Non-interactive runs keep requiring --token, with the hint now pointing at the console instead of the docs page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B7zxs3oUdsbbjhUnotue3H
There was a problem hiding this comment.
LGTM: in-flow Cloudflare token creation opens the pre-filled read-only URL straight into the browser, never prints it, and the no-browser/non-interactive fallbacks hold up.
Verified against the actual head (48fa04a2), not memory:
- Read the full diff hunk by hunk; grepped for callers/references of
buildCloudflareTokenUrl,cloudflareTokenStep, andopenBrowser— no other call sites, no dead code left behind from removing the oldsecretStep-based Cloudflare flow. - Confirmed the ~13KB pre-filled URL is only ever passed to
openBrowser()— neverprocess.stdout/stderr, nevernote(), never logged. Contrast withsecretStep, which does print itslinkvianote()— consistent with the PR body's claim about why it isn't reused here. readOnly: trueis unconditional (no flag re-enables a broader grant);toReadOnlyPermissionscorrectly downgrades edit→read, drops action-only grants (run/send/purge) that have no read equivalent, and dedupes — covered by the 5 new tests intest/cloudflare-token-url.test.ts, which I read for correctness rather than just trusting green.- The pre-existing
--read-onlyno-op and its 0.2.16 retirement comment are untouched by this diff (confirmed via the GitHub diff, not the shallow local clone) — no regression there. - Ran the full local procedure from
REVIEW.mdon a fresh clone of this head:npm ci,npm run codegen(live spec, 280 paths),npm run typecheck(clean),npm run lint(clean),npm run test→ 324/324 pass, 0 fail. Skipped the build/smoke leg perREVIEW.md's scoping rule since the diff touches onlysrc/commands/cloud/*.tsand a test file, notbuild.ts/codegen//skill/SKILL.md/packaging. - Independently checked the 3 check runs on this head via the GitHub API (Test & typecheck on 20.x/22.x/24.x) — all
completed/success.
Two non-blocking notes:
- Left an inline nit on the
openBrowser()call: if the browser spawn silently fails after the user opts in, there's no fallback text shown (by design, since the URL itself can never be printed) — a possible follow-up, not a blocker. - The PR description says "Full suite 329 pass"; the actual suite on this head is 324 tests / 324 pass (319 pre-existing + the 5 new ones here). All green either way, just flagging so the number doesn't propagate as-is.
Generated by Claude Code
There was a problem hiding this comment.
Auto-approved: Claude reviewed this PR and posted an LGTM verdict (see its review). A repo admin enabled this via the auto-approve workflow.
Generated by Claude Code
openBrowser is fire-and-forget and the pre-filled Cloudflare token URL must never be printed, so a silent spawn failure left the user at the paste prompt with no fallback. Always show the manual-steps note after the open attempt. Co-Authored-By: Claude <noreply@anthropic.com>
|
@claude please re-review: pushed 6fe3d08 addressing the review nit — the Cloudflare flow now always prints the manual token steps right after the browser-open attempt, so a silently failed spawn no longer dead-ends at the paste prompt. The PR body's test count is also corrected to 324. Typecheck, lint, and the full suite (324 pass) are clean locally on the new head. Generated by Claude Code |
Requested by boris · Slack thread
Before: connecting Cloudflare sent you to docs.polylane.com to click a token-creation link there, then back to the terminal to paste the result. After: the CLI opens Cloudflare's account API token screen directly in your browser, pre-filled with the read-only token — create it as-is and paste it; no docs visit anywhere in the flow.
This makes Cloudflare token creation happen in-flow, the same way
gh auth loginhands off to the browser.How: the CLI now carries the same
buildCloudflareTokenUrl()pre-filled-URL builder the console and docs use (duplicated fromcoreplanelabs/nominalapps/console/app/utils/cloudflare-token-url.ts, with a keep-in-sync header — the API doesn't serve this URL yet). The ~13KB URL is only ever handed toopenBrowser()and never printed. A newcloudflareTokenStepreplaces the genericsecretStep(which prints its link in the note, the confirm prompt, and the non-interactive hint): it offers to open the browser, and on--no-browseror a declined open prints tight in-terminal steps instead (the console's Connect > Cloudflare screen, which has the same pre-filled link, or the shortdash.cloudflare.com/?to=/:account/api-tokensdeep link). Non-interactive runs still require--token; the usage hint now points at the console instead of the docs page. True API minting was rejected: Cloudflare'sPOST /user/tokens(and the account-token equivalent) requires an existing token with token-create permission, so it would add a manual dashboard step instead of removing one.Read-only stays the only flavor, matching what both console connect surfaces send and what the flow already enforced (
readOnly: true).Tests: new
test/cloudflare-token-url.test.tscovers the URL shape, the read-only downgrade/dedup/drop rules, and the browser-only size. Full suite 324 pass; typecheck, lint, and build clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01B7zxs3oUdsbbjhUnotue3H
Generated by Claude Code