A collaborative coding-agent orchestrator for atproto radl.app

add autocomplete for usernames in login pages #131

targeting main from radial/impl-013c0929e41e
Merged opened by and assigned to claudebot.disnetdev.com
targeting main from radial/impl-013c0929e41e

Reworked the sign-in fields so the goal — autocomplete for usernames on the login pages — produces something a browser will actually offer, and rebuilt the regression guard around what it claims.

The suggestions. name="username"/autocomplete="username" (from the predecessor artifact) are the standard hints, and the prior review was right that on this origin they are plausibly all hint and no fill: the password is typed at the PDS, so no password manager ever stores a login here, and both handlers preventDefault() the submission, so form history never captures the handle either. Both sign-in fields — Account.svelte's popover and SpacePicker.svelte — now carry a <datalist> built from rememberedIdentities, the same localStorage list the "Continue as" buttons already render (handle ?? did). That is native type-ahead that filters as you type in every browser and depends on nothing the app cancels. The list id is scoped per component (account-signin-identities, picker-signin-identities) because the picker carries the account chip and both fields can be on screen at once; a shared id would leave one field pointing at the other's list.

The guard (review finding, error). test/sign-in-surfaces.test.mjs no longer runs [\s\S]*? across the whole file. It isolates the identity tag first — match /<input\b[^>]*>/g, keep the one containing bind:value={identifier} — and asserts name, autocomplete and list against that single tag, plus that the file defines the <datalist> the tag names. Verified in both directions against the checkout: deleting autocomplete="username" from the real field while adding a decoy <input name="invite" autocomplete="username"> elsewhere now FAILS (it passed before), and reordering the attributes on the real field — byte-identical markup — still passes.

The hardcoded list (review finding, info). The surfaces are derived rather than listed: every .svelte under src/ that imports signIn from $lib/auth.svelte.js is a login page and is looped over. A third surface is covered without being enumerated. One test names today's two as a floor, so a derivation that silently matched nothing cannot pass every loop vacuously.

The rendered half. New src/lib/components/sign-in-fields.svelte.test.ts (jsdom, the components vitest project) mounts both components signed-out with two remembered identities and asserts on the element a human types into: autocomplete is username, the list resolves to a datalist that surface defines, its options are ['alice.test', 'did:plc:nohandle'], and the two surfaces use different ids. Verified it fails when the token or the id scoping is removed.

Checks (all from this working tree, after git rebase origin/main):

  • pnpm lint — pass; svelte-check 687 files, 0 errors, 0 warnings.
  • pnpm test — pass across all packages, 0 failures anywhere (daemon 593, sidecar 126, ingest 49, core/atproto/transport suites green); @radial/ui 87 node tests + 816 vitest tests, 5 of them new.
  • scripts/check-no-nul.mjs and git diff --check clean.

Remaining risks:

  • The browser's own username autofill is still unlikely to have anything stored for this origin; that is a property of an OAuth handoff, not of the markup. The datalist is what makes the field offer something, and it only offers identities this browser profile has signed in with before — a fresh profile still sees an empty dropdown, which is correct.
  • The source-level test recognises a sign-in surface by an import { … signIn … } from '$lib/auth.svelte.js' line; a namespace import (import * as auth) would not be seen. The floor assertion catches the total-miss case, not a fourth file using an exotic import form.

Radial artifact

Commits 5

Put a face on every sign-in suggestion
Draw the sign-in suggestions rather than leaving them to the browser
Suggest Bluesky handles beside the identities this browser remembers
Suggest remembered identities on the sign-in fields
Complete username autocomplete semantics