Skip to content

[NO-TICKET] Restore a hosted builder's lost key with login, in the CLI's messages and the docs - #465

Merged
mariojgt merged 3 commits into
mainfrom
mariot/hosted-builder-lost-key-login
Oct 29, 2026
Merged

mariojgt merged 3 commits into
mainfrom
mariot/hosted-builder-lost-key-login

Conversation

@mariojgt

@mariojgt mariojgt commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

No ticket.

What changed

When a hosted builder's workspace (Lovable, Replit, Bolt and similar) loses its API key, or has it refused, agents are now told one thing: run login. The person approves one link and a new key is saved. Nobody types or pastes a key.

It is said in two places:

  1. The CLI's own messages. In a Lovable or Replit project, the missing-key and refused-key messages and login's output now say to run login, then scan, then publish again. They no longer offer PATCHSTACK_API_KEY.
  2. AGENT-INSTALL.md, for agents that read the docs.

Why

The published app of a hosted builder does not need the site key. It fetches rules and reports with the read-only credential bundled in its rules file. The workspace scan still needs the key, because the read-only credential cannot send a package list.

That key lives in .patchstackrc.local.json, which git ignores. A builder's workspace may not keep git-ignored files, so a scan a few hours after setup can find no key.

The CLI's message for that case offered two fixes: "Run npx @patchstack/connect login, or set PATCHSTACK_API_KEY." A keyless builder copy, which is also what a direct scan in that workspace runs as, printed "Set PATCHSTACK_API_KEY in the platform's environment". An agent that took the second option opened the builder's secrets form and asked the person for a key. Setup never shows the person the key, so they had nothing correct to paste. Patchstack refused whatever they entered, and the agent then sent them to the dashboard to make a new one.

Agents act on the error text they are looking at, not on docs they read at install time, so the docs alone did not stop it. That is why the CLI text changes too.

Two more traps sit after login itself:

  • A wrong secret keeps winning. PATCHSTACK_API_KEY (and PATCHSTACK_PULSE_AUTH) are read before .patchstackrc.local.json, so a bad value left in the workspace overrides the key login restores.
  • login replaces the key, and that also cancels the read-only credential the published app carries. The app needs a new one, which only reaches it with the next publish. login's output said to update "hosting", which in a builder sends the agent back to the secrets form.

Fix

CLI:

  • resolveConfig (src/config.ts) now carries the hosted builder the project belongs to (hostedBuilder), from the same detectHostedBuilder() check the environment label already used.
  • restoresKeyWithLogin() (src/client.ts) is true for a builder's project, unless a deploy platform identified itself. A Lovable app deployed through Vercel or Netlify keeps today's PATCHSTACK_API_KEY advice, because that platform's environment is where the key belongs there.
  • Where it is true:
    • authFailureMessage, missing key: run login in the builder's workspace, don't ask the person for a key, then scan and publish again;
    • authFailureMessage, refused key: the same, after removing any PATCHSTACK_API_KEY secret;
    • undeliveredReportLines (src/build-hook.ts): restore the key with login, don't add it as a secret;
    • postInputMap's skipped message: the workspace sends the map, and restores its key with login;
    • login (src/cli.ts): before approval, "the app has to be published again afterwards"; after it, "run scan, then publish again" instead of "update it in CI, hosting and other checkouts".
  • On every machine, login now also warns after approval when PATCHSTACK_API_KEY or PATCHSTACK_PULSE_AUTH is set, since either keeps the old key in use.
  • Everywhere else the messages are unchanged.

AGENT-INSTALL.md:

  • After setup (next to "Never ask the person to copy their API key into a builder's settings or secrets"): if a later scan says the key is missing or was not accepted, run login. Do not ask the person for the key.
  • "Recovering a lost credential — login": a builder's workspace losing the file is now one of the listed reasons to use it.
  • New "In a hosted builder" subsection under login:
    • login is the fix, and in a Lovable or Replit project the CLI's messages say so. PATCHSTACK_API_KEY, which they name elsewhere, is for CI and for hosts the person deploys to themselves.
    • Do not ask for the key, do not open the builder's secrets or environment settings, and do not send the person to the dashboard to create one.
    • Ask the person to remove an existing PATCHSTACK_API_KEY secret first.
    • After login, run scan, then ask the person to publish again.
  • "Consequences to tell the user about": in a builder there is nothing to update in its settings. Run scan so the new read-only credential goes into the guard's rules file, then publish again. Until then the live app cannot fetch new rules or report what it blocks.

Verified

  • New tests, each failing with the builder check switched off:
    • tests/auth-failure-message.test.ts:
      • a Lovable project's missing and refused key messages name login and the republish, never PATCHSTACK_API_KEY as a fix;
      • a builder's project on a deploy platform that identified itself gets exactly today's message;
      • the map upload's skipped message points at login.
    • tests/build-hook.test.ts: a builder copy's lines point at login and no longer say to set PATCHSTACK_API_KEY; they still name where they looked.
    • tests/config.test.ts: hostedBuilder is read from the project's own package.json.
  • End to end with the built CLI in a synthetic Lovable project, against a local stub that refuses every key:
    • scan with no key prints the login steps and "do not add the key as a secret";
    • scan with a wrong PATCHSTACK_API_KEY prints "remove it first", then the login steps.
  • login end to end against a stub that approves at once:
    • in the Lovable project it prints the republish wording, and warns that the leftover PATCHSTACK_API_KEY is still in use;
    • in a plain project its output is unchanged.
  • Each claim in the docs was checked against the code. The variables outrank the key file in resolveConfig. persistApiKey writes the key file. A keyed scan re-syncs the rules file and its read-only credential through syncWorkspace.
  • Gates:
    • npm run typecheck, npm run build and capabilities:check are green.
    • Full npm test: 4656 passed, 7 skipped. One test failed: "keeps scan, setup and guide free of technical words" hit its 5 s timeout under full-suite load, and passes on its own (39/39 in tests/bin-invocation.test.ts).

Out of scope, worth a follow-up

  • Bolt and other builders. Only Lovable and Replit are detected from their packages, so on Bolt and similar builders the CLI text still offers PATCHSTACK_API_KEY and the docs carry the guidance alone.
  • The key will go missing again whenever the builder's workspace loses the file, and each login means a rescan and a republish. A lasting fix is for the read-only credential to also send the package list, the way it already sends detections, so the workspace never needs the key. That needs a SaaS change and a decision about who may update a site's package list.

Docs: AGENT-INSTALL.md updated, and the CLI's error text changes what agents read. The test fixture installs the published package, so a run now would audit the previous text. The hostile field test is owed after the release that carries this (node field-test/run.mjs --persona hostile --rounds 3), plus standard/lovable for doc accuracy.

🤖 Generated with Claude Code

A hosted builder's workspace may not keep the git-ignored key file, so a
later scan finds no key. AGENT-INSTALL.md now says to run `login` there,
never to ask the person for a key or open the builder's secrets form, to
remove a wrong PATCHSTACK_API_KEY secret first, and to scan and publish
again after approval because rotating retires the read-only credential
the published app carries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mariojgt

Copy link
Copy Markdown
Contributor Author

/review

@coderbuds

coderbuds Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

🎯 Elite quality (97%) — Consistently reroutes hosted-builder key recovery to login across docs, CLI, client, and build-hook messages.

📦 Small

🤖 Written by Claude Code — going by its own attribution. Unknown whether a person read it; agents can report that with the report-ai-usage tool.

See how your team is trending →

@mariojgt mariojgt closed this Oct 29, 2026
…ages

In a Lovable or Replit project, the messages for a missing or refused key
now say to run login in the builder's workspace, then scan and publish
again. They no longer offer PATCHSTACK_API_KEY, which sent agents to the
builder's secrets form to ask the person for a key they were never shown.

login's own output says the same there, and on any machine warns when
PATCHSTACK_API_KEY or PATCHSTACK_PULSE_AUTH is set, since either one is
read before the key login saves. A builder's project deployed through a
platform that identifies itself keeps the environment-variable advice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mariojgt mariojgt reopened this Oct 29, 2026
@mariojgt mariojgt changed the title [NO-TICKET] Tell agents in a hosted builder to recover a lost key with login [NO-TICKET] Restore a hosted builder's lost key with login, in the CLI's messages and the docs Oct 29, 2026
@mariojgt

Copy link
Copy Markdown
Contributor Author

/review

The builder messages no longer say "read-only credential", "git-ignored"
or "read before": the agent passes these on to the person, so they say
what happens instead (the live site keeps getting new protection rules,
the secret overrides the new key).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mariojgt
mariojgt merged commit fef0a73 into main Oct 29, 2026
23 checks passed
@mariojgt
mariojgt deleted the mariot/hosted-builder-lost-key-login branch October 29, 2026 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants