Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Console login page: one primary hue, a leaner card, a quiet dev-admin sign-in and a footer #12600

Closed

Description

@objectstack-fleet

Source

Measured on objectui main 1b3b5b102, the console's /login at 1280 × 900, light and dark, zh-CN. apps/console/src/pages/auth/AuthLayout.tsx draws the brand mark with a hard-coded from-indigo-500 to-indigo-600 tile and an indigo glow, while the form's button (AUTH_PRIMARY_BUTTON_CLASS in packages/auth/src/authStyles.tsx) and every link take the theme's --primary, which this console resolves to blue: two accent hues on one screen, and the login page's accent is not the console's. Inside the card LoginForm (packages/auth/src/LoginForm.tsx) stacks a lock icon tile, the title "登录您的账户" and the line "输入您的邮箱和密码以继续" above a left-aligned form: three centred elements saying one thing, then a change of alignment. On a dev instance LoginPage.tsx renders the devSeedAdmin hint as an amber bordered banner above the card with the seed email and the password in clear text, heavier than the form it sits over. The page has no language switch, no environment or version mark and no legal links; the SSO buttons appear only when a provider is configured, which is right.

Target

The artboard "登录页 · A 精修居中版" (1280 × 820), in numbers:

  1. One accent. The brand mark's 36 px tile and the primary button use --primary; no indigo-* class remains in AuthLayout.tsx. The dot grid and the glow stay, the glow tinted from --primary at 10 %.
  2. One column, 400 px wide, centred: brand mark (36 px tile, 18 px / 600 product name) · 20 px gap · card · 20 px gap · footer.
  3. The card: 12 px radius, 1 px border, 28 px padding (20 px at the bottom). Title "欢迎回来" 20 px / 600, one line "登录后继续你的工作" 13 px muted. The lock tile and the two-line header retire; LoginForm takes a prop or slot that renders no header when the host supplies its own.
  4. When a provider is configured: one outline button per provider (40 px, 8 px radius, 14 px / 500, provider icon left), then a divider line reading "或使用邮箱" 12 px muted; without a provider neither renders.
  5. Fields: 13 px / 500 labels; 40 px inputs, 8 px radius, 14 px text; the password label row carries "忘记密码?" 12 px at the right; a show/hide toggle 28 px inside the password field. Primary button 40 px full width, 8 px radius, label "登录". Below it, centred 13 px: "还没有账户?注册" only when decideSignUpOffer answers form.
  6. Dev instance: the banner retires. The card's last row, under a dashed top border, reads "● 本地开发实例" 12 px muted at the left and a 28 px outline chip "以开发管理员登录" at the right that submits the seed credentials the server reported; the password is never printed. The row renders only when /auth/config reports devSeedAdmin.
  7. Footer, 12 px muted, two ends: left a locale switch "🌐 简体中文 ▾" (the existing LocaleSwitcher); right "隐私 · 条款" links (rendered only when the runtime config carries their URLs) and a mono pill with the product version and environment label (v18.0 · local), from the same config the preview badge reads.
  8. Dark theme: the same layout; the card on --card, the glow at the same 10 %.

File surface

apps/console/src/pages/auth/AuthLayout.tsx, apps/console/src/pages/auth/LoginPage.tsx (dev row, footer), packages/auth/src/LoginForm.tsx and authStyles.tsx (header slot, button class), packages/app-shell/src/console/auth/* where DefaultLoginPage shares the decision, packages/i18n/src/locales/*.ts (new strings in every locale), tests beside each.

Acceptance

  1. Tests: no indigo class in AuthLayout.tsx; the dev row renders only with devSeedAdmin and never contains the password string; the sign-in button submits the seed email through the same signIn path and lands on /home; SSO buttons absent without a provider.
  2. Screenshots at 1280 px, light and dark, with and without devSeedAdmin, in the PR text as measurements (the files stay out of main).
  3. pnpm --filter @object-ui/auth test, pnpm --filter @object-ui/app-shell test, the console's auth page tests green; pnpm check:i18n green.

Constraints

  • The product name and logo stay server-driven (getProductName, getLogoUrl); no vendor name hard-coded.
  • The ?redirect=, SSO hand-off and server-unreachable behaviours of LoginPage.tsx do not change.
  • Tailwind utilities and theme tokens only.

Evidence

The artboards, as static HTML and 1280 px PNG renders, live on the temporary branch claude/console-home-login-design-20261016 of objectstack-ai/objectui (commit c4dfb417a, never merged; the maintainer ruled that design files and screenshots do not enter main). Files: Login.png · Login.html.

Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff from the 2026-10-16 review of the console login page and home page with the maintainer, on objectui main 1b3b5b102 and HotCRM 63db83e2. The maintainer approved the artboards in that session, verbatim: 「同意设计稿,创建任务」.

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:identityLogin and identity — sign-up, sessions, organization membership, SSO
    and removed on Oct 16, 2026
  2. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (priority:p2; artboard "登录页 · A 精修居中版", approved by the maintainer in the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff)
    Session: session_01JZnppgHRp4sREcouhkQYDB
    Account: sunhaolin
    Branch: claude/issue-12600-login-page-refine
    Worktree: objectui-issue-12600
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: apps/console/src/pages/auth/AuthLayout.tsx, apps/console/src/pages/auth/LoginPage.tsx, packages/auth/src/LoginForm.tsx, packages/auth/src/authStyles.tsx, packages/app-shell/src/console/auth/* (only where DefaultLoginPage shares the decision), packages/i18n/src/locales/*.ts, tests beside each, and changesets for the touched packages (stop on breach; explain in the report).
    Container & model: M, mode:subagent, model: opus (default tier)
    Clause-②: yes
    Clause-② reason: LoginForm is exported from @object-ui/auth with LoginFormProps, and the card asks for a prop or slot that suppresses its header, which is an additive change to a published prop surface. The seat's TIER_DEFAULT review comes before ready.
    Responsibility: n/a — not a defect card
    Thread-read: none
    Serial constraints cleared: no open PR touches apps/console/src/pages/auth/, packages/auth/src/ or packages/app-shell/src/console/auth/ (scanned every open objectui PR's file list), and no in-flight claim names them. Sibling cards objectui#12601, #12602, #12604 and #12605 touch none of these files.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · takeover of claim 6207340447 (the claimant's session ran out of tokens mid-build)
    Release: claim 6207340447 · session session_01JZnppgHRp4sREcouhkQYDB · account sunhaolin · reason: the claimant is unreachable (token exhaustion; no PR, no os-dev-report) · destination: this claim, same branch, same declarations
    Provenance: the maintainer · in session session_011K9g23W67dy2zwnyzaoB6o, the /pm-dispatch UI seat 1 summons, read 2026-10-16T06:35Z · verbatim: 「前任没有token了,他的任务开发了一半你要接着处理。」
    Session: session_011K9g23W67dy2zwnyzaoB6o
    Account: os-tesla
    Branch: claude/issue-12600-login-page-refine
    Worktree: objectui-issue-12600
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: as claim 6207340447 declared (apps/console/src/pages/auth/, packages/auth/src/LoginForm.tsx and authStyles.tsx, packages/app-shell/src/console/auth/LoginPage.tsx, packages/i18n/src/locales/*.ts, tests beside each, changesets), plus packages/i18n/src/__tests__/residue-namespaces-3546.test.tsx, which the pushed tip already touches (stop on breach; explain in the report).
    Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui over the tip's 23 paths: no path-derived mandate)
    Clause-②: yes
    Clause-② reason: carried unchanged from 6207340447: LoginForm is exported from @object-ui/auth with LoginFormProps, and the card asks for a prop or slot that suppresses its header, an additive change to a published prop surface. The seat's TIER_DEFAULT review comes before ready.
    Responsibility: n/a — not a defect card
    Thread-read: 6207340447
    Serial constraints cleared: the only open objectui PR besides dependabot and the release PR is #12630 (Studio automations rail), whose files are disjoint; the in-flight branches of objectui#12603, #12611, #12612, #12617, #12620, #12621 and #12626 touch none of this surface. objectui#12601 also adds keys to packages/i18n/src/locales/*.ts: ordinary concurrency, the second lander resolves.
    Resume-from: claude/issue-12600-login-page-refine@9603dd321819dbca99542de069262610385d7212

    Handover record. Last pushed sha 9603dd3218 (2026-10-16T04:00:29Z), four commits on base 33fbc861d2: the feature (6a585d1), the tests (a723731), four changesets (42ed089) and an i18n anchor-test fix (9603dd3). No PR and no report exist. Everything on the branch is UNVERIFIED: the resuming dev reads every commit, merges origin/main, re-runs every gate and the screenshots the acceptance names, and opens the draft PR.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12600,
      "status": "done",
      "branch": "claude/issue-12600-login-page-refine",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12640",
      "session": "session_011K9g23W67dy2zwnyzaoB6o",
      "premise_still_valid": true,
      "summary": "Resumed the dead run's branch (inherited tip 9603dd3), merged origin/main 63d00da (8e22590), re-read all four inherited commits hunk by hunk and kept them: one --primary accent with an isolate fix that finally shows the dot grid and glow, the 400 px column and card with its own header via LoginForm's new optional hideHeader, a 28 px password reveal toggle, the dev-admin row (chip signs in through useAuth().signIn and never renders the password), the footer with LocaleSwitcher and the spec-declared features.privacyUrl / features.termsUrl links, and DefaultLoginPage's toggle labels. Fixed in 8065049: retired the two locale keys the banner's removal orphaned (auth.login.devAdminHint.body and .dismiss, all ten packs, i18n changeset reworded) and added pins that the chip's sign-in hands over exactly as a typed one (same landing, safe ?redirect=, SSO authorize replay, the typed SSO hand-off pinned too since nothing pinned it). No version/environment pill: the runtime config the preview badge reads carries no version or display environment, so nothing is invented.",
      "tests": "All at 8065049 through os-verify-lock. (1) pnpm exec vitest run --maxWorkers=2 packages/auth/ packages/app-shell/src/console/auth/ packages/app-shell/src/__tests__/product-neutral-renderer.ratchet.test.ts apps/console/src/pages/auth/ apps/console/src/__tests__/i18nAfterSignIn-12034.test.tsx → 'Test Files  57 passed (57)', 'Tests  477 passed (477)'. (2) pnpm exec vitest run --maxWorkers=2 packages/i18n/ → 'Test Files  83 passed (83)', 'Tests  1321 passed | 13 skipped (1334)' (skips = describe.runIf(DRIVEN) time-zone legs, untouched). (3) Closure build pnpm --workspace-concurrency=2 --filter '@object-ui/console^...' build (35 packages) VERDICT command-exit 0; type-check for @object-ui/auth, @object-ui/i18n, @object-ui/app-shell, @object-ui/console each echoed 'tsc --noEmit' + its test project, VERDICT command-exit 0 each; console type-check passes hideHeader/showPasswordText/hidePasswordText which the pre-change declaration refuses, so it read the rebuilt .d.ts. (4) H1 before/after: @object-ui/auth built with merge-base LoginForm.tsx+authStyles.tsx restored under a trap (restore verified by blob hash == HEAD) and at HEAD; dist/LoginForm.d.ts diff: LoginFormProps gains exactly hideHeader?: boolean (before: onSuccess onError registerUrl forgotPasswordUrl title description icon linkComponent labels errorMessages hideIcon), LoginFormLabels gains exactly showPasswordText?, hidePasswordText?; nothing removed; authStyles literal-typed constants change with their values. (5) Ablations via objectstack scripts/ablation-replace.mjs (anchor hit, blob changed, restore blob == HEAD and git diff HEAD empty each time; tests read src through vitest aliases, no build leg): password into chip title → 3/10 red incl. 'never puts the password in the DOM'; row without devSeedAdmin → 1/10 red 'renders no row without devSeedAdmin'; chip signIn replaced by no-op → 5/10 red incl. 'signs in with the reported email and password' and the landing/redirect/SSO pins; LoginForm ignores hideHeader → 3/14 red (auth + console header pins); tile back to bg-indigo-500 → 2/8 red. All red as predicted. First spelling of the password ablation kept its anchor inside the replacement; ablation-replace refused it as a no-op (no test ran) and it was re-run with the attribute spelling.",
      "gates": "Local, hand-derived (objectui has no dispatch-gates.mjs, so no --ran reconciliation), all at 8065049, exit codes captured before any pipe: check:i18n-keys 0, check:i18n-drift 0 ('Every changed en value was followed by all nine translation packs.'), check:i18n-dead-keys 0 (no auth.login entry left; the inherited tip listed devAdminHint.body/.dismiss as confirmed), check:changeset-claims 0, changeset:check 0, check:test-path-roots 0, check:new-line-citations 0 ('0 new citation(s)'), node scripts/check-changeset-presence.mjs 0 (4 changesets for 4 released packages), eslint --no-inline-config over the 19 changed ts/tsx files 0 errors / 4 warnings all on lines unchanged from main, control-byte scan no hits. Declared narrowing: full packages/app-shell/ (1435 test files) and full apps/console/ suites not run locally; CI runs them. CI on PR head 8065049 at report time (one read, not polled): Changeset Fixed Group Check success, Changeset Bump Policy success, label success, dependabot skipped, Test (coverage) skipped; in_progress: Test (shard 1..16/16), Type Check, Lint, Build & E2E, Build Docs, Repo Gates, Test (dist pins), Changeset Declaration, Changeset Claim Re-read, Changeset Overwrite Report, Bundle Analysis, Governed Surface Queue Guard, Line Citation Gate, Live E2E (informational).",
      "mcp_calls": "0",
      "api_writes": "2 relay strokes — (1) fleet-write pr_create: POST /repos/objectstack-ai/objectstack/dispatches executing POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12640/assignees ['os-tesla'], read-back 14406 bytes sent = stored; (2) this os-dev-report: POST /repos/objectstack-ai/objectui/issues/12600/comments via post-stamped.mjs. Plus git push x2 (8e22590, 8065049; not REST). Zero label writes.",
      "open_questions": [
        {
          "question": "Radii: in this console --radius is 0.875rem and --radius-xl 1rem, so the theme-token radii the inherited code uses compute to 14 px (fields, button, chip) and 16 px (card) instead of the artboard's 8 px and 12 px. Keep the theme tokens or pin the artboard pixels?",
          "options": [
            "A keep theme tokens (rounded-lg / rounded-xl): the page follows the console's own radius scale and a host theme that rescales --radius rescales it; costs a pixel mismatch with the artboard",
            "B pin arbitrary pixels (rounded-[8px] / rounded-[12px]) on the login card, fields and button: matches the artboard exactly; the shared auth styles then stop following --radius on every auth form and in DefaultLoginPage"
          ],
          "recommendation": "A, because the card's constraint is 'Tailwind utilities and theme tokens only' and the rest of the console draws at the same scale; the seat's browser reading is where a visible mismatch would show"
        }
      ],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — no version/environment pill: AppShellRuntimeConfig (packages/app-shell/src/runtime-config.ts, produced by objectstack RuntimeConfigPlugin) carries branding.stage and no product version or display environment; the only 'environment' is telemetry.clientErrorReporting.environment, an error-reporting tag present only with a DSN",
        "carrier: none · noted, not filed — the locale switch is the existing icon-only LocaleSwitcher, not the artboard's labelled '🌐 简体中文 ▾'; a labelled variant changes app-shell's published component, outside the declared surface",
        "carrier: domain:ui seat browser reading · noted, not filed — SocialSignInButtons (outside the declared surface) draws provider buttons rounded-md (12 px here, not 8 px) and its divider label on bg-background, which is not --card in this console (light 240 24% 97% vs white): a likely visible patch behind the divider label on the card when a provider is configured; read from source, not reproduced in a browser",
        "carrier: none · noted, not filed — zh auth.login.orText stays '或使用邮箱继续' (artboard '或使用邮箱'); the wording matches the register page and the existing social-label locale tests pin it",
        "carrier: none · noted, not filed — AuthPublicConfig.features (packages/auth/src/types.ts) declares the spec's tenancyPosture and audiencePosture but not termsUrl/privacyUrl from PUBLIC_AUTH_CONFIG_NON_FLAG_KEYS; the page reads them through a narrowing cast, as it already did for devSeedAdmin",
        "carrier: none · noted, not filed — a browser that dismissed the retired banner keeps an os.console.devAdminHintDismissed localStorage entry nobody reads"
      ],
      "deviations": [
        "the first 'git push -u' probe answered 'Everything up-to-date' (the branch already existed), so the write route was proven by the merge push 9603dd3..8e22590",
        "the local merge commit was redone once before any push (reset to the inherited tip, re-merged 63d00da) to carry the model-free trailer pair; nothing pushed was rewritten",
        "commit trailers use the model-free pair AGENTS.md prescribes, not the harness reminder's model-named Co-Authored-By line",
        "local test scope narrowed as declared in tests/gates; CI runs the full farm",
        "the ablation step waited about 37 minutes in the verify-lock queue behind objectui-issue-12616's full packages/app-shell/ run (alive and progressing throughout); waited in-turn with lock-free work in between",
        "NOT MEASURED: screenshots, reason: the seat takes one shared browser reading for the resumed cards at review, before ACCEPT (carrier: domain:ui seat 1)",
        "packages/auth/README.md not edited: it lists no LoginForm prop (not even hideIcon), and content/docs has no LoginForm page"
      ],
      "files_changed": [
        ".changeset/12600-app-shell-login-toggle.md",
        ".changeset/12600-auth-login-form.md",
        ".changeset/12600-console-login-page.md",
        ".changeset/12600-i18n-login-strings.md",
        "apps/console/src/pages/auth/AuthLayout.tsx",
        "apps/console/src/pages/auth/LoginPage.tsx",
        "apps/console/src/pages/auth/__tests__/LoginPage.dev-admin-hint.test.tsx",
        "apps/console/src/pages/auth/__tests__/LoginPage.layout-12600.test.tsx",
        "packages/app-shell/src/console/auth/LoginPage.tsx",
        "packages/auth/src/LoginForm.tsx",
        "packages/auth/src/__tests__/LoginForm.hideHeader-12600.test.tsx",
        "packages/auth/src/authStyles.tsx",
        "packages/i18n/src/__tests__/residue-namespaces-3546.test.tsx",
        "packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts"
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #12640 comment 6211536966 · contract review 6211524118 (TIER_DEFAULT PASS) · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T08:37Z


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T08:51Z

    • Merged: PR feat(console): the login page takes one primary hue, a leaner card, a quiet dev-admin row and a footer (objectui#12600) #12640 landed through the merge queue as main 8ed7e5a8fb. Its one parent is 07b0632496, which is objectui#12616's landing, and it is an ancestor of origin/main.
    • Verified by content: on origin/main, all 23 files of the PR are blob-identical to the reviewed head 8065049bdb. Positive control: hideHeader appears in packages/auth/src/LoginForm.tsx on origin/main (4 hits).
    • Card: closed completed by Fixes #12600. This note precedes the strip of pm:dispatched.
    • Records: contract review 6211524118 (TIER_DEFAULT PASS), ACCEPT 6211536966 (with the live login reading), evidence at claude/issue-12616-evidence 0283cbc, under evidence/12600/.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:identityLogin and identity — sign-up, sessions, organization membership, SSOdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions