Skip to content

feat(console): Home offers Connect an AI Assistant until the person has connected one; the first-run checklist gains its row - #31236

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-l2jntk
Nov 7, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-l2jntk

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread

Fixes #30895

Clause-②: yes (widening)
Metadata-protocol: none

维护者速读

What changes

  • Home card (console/home/ConnectAssistantCard.tsx, mounted in HomePage.tsx under the recovery-password reminder, in both the empty and the full Home). For every signed-in person: "Work here from your AI assistant", one sentence that they can look up and change their records from Claude, Doubao and similar assistants, always as themselves, and one button, Connect an AI Assistant, which opens the page. It is drawn only when all of these hold:
    • the served Account app carries the page (MCP turned on);
    • the person has not closed it on this browser;
    • useConnectedAccess answered that they have connected nothing: no authorized assistant and no API key that still works.
      While the read is out, or when it fails, the card stays away rather than offering a connection the person may already have. A dismissed card reads nothing.
  • Dismissal (connectAssistantCardGate.ts). Measured before adding anything: Home keeps no server-side preference; its two existing dismissible items (the recovery-password reminder and the first-run checklist) remember a dismissal in the browser's localStorage. The card does the same, keyed by the person (os:home:connect-assistant-dismissed:USER), so one person's dismissal on a shared browser does not hide it for the next.
  • First-run checklist row (FirstRunChecklist.tsx, row 7, connect_assistant). "Connect an AI assistant": done once this administrator has authorized an assistant or holds an API key that still works, read from those records, never from a click; links to the page ("Connect" / "View"). Left out, like the other rows, when its state cannot be read, and left out where MCP is turned off. The read starts only once the checklist itself is going to draw, so a member's Home asks nothing for it.
  • One read, reused (connectedAccess.ts). Both use useConnectedAccess from PR feat(console): Connect an AI Assistant names the connected assistant and its last call; plain-words page subtitle #31198; no second copy. It gains { enabled } so a caller that will not draw (a dismissed card, a member's checklist) costs no request, and an adapter without the auth client is now a failed read instead of a throw out of the effect.
  • One path rule (connectAssistantPath.ts, new). The avatar menu's "does the Account app carry the page, and what is its address" logic moves out of AppHeader.tsx unchanged, and the avatar item, the Home card and the checklist row all read it.
  • @object-ui/app-shell now exports useConnectedAccess (with its types) and connectAssistantPath, for the console's checklist.
  • Language packs, all eleven: home.connectAssistant.title, body, action, dismiss and console.firstRunChecklist.connectAssistant.title, todo, done, action added; nothing reworded or removed. zh-Hant regenerated with gen:zh-hant.
  • Changeset .changeset/30895-home-connect-assistant.md (@object-ui/app-shell, @object-ui/i18n, @object-ui/console: patch).

Why

The card's Expected 2 ("Home shows a dismissible card … hidden once dismissed or once the person has connected one") and Expected 3 ("the administrator's first-run checklist on Home gains a row for it. Its done state is read from a real record … never from a click"). Expected 1, 4 and 5 landed in PR #30935; 2 and 3 waited for the "has connected" read, which PR #31198 built.

Tests

  • ConnectAssistantCard-30895.test.tsx, 9 cases, real router, real data bus and the real hook (only the adapter, the person and the served apps are stubbed): §1 nothing connected (only a revoked and an expired key) shows the card, and clicking its button lands on the Connect route; it reads only the person's own keys; §2 an authorized assistant, or a key that still works: no card; §3 while the read is out, or when it fails: no card; §4 the close button hides it, a later mount stays hidden and reads nothing, another person on the same browser still sees it; §5 no page in the Account app: no card and no read; §6 a key minted while it is shown (the data bus) takes it away.
  • FirstRunChecklist.test.tsx, 7 new cases on the real settings client: not done with nothing connected (link to /apps/account/page/connect_agent, "0 of 7 done"); done from an authorized assistant; done from a working API key; clicking the row's link writes nothing and leaves it not done; a failed read leaves the row out; MCP off leaves the row out and reads nothing; a member reads nothing of it.
  • Ablations (one-off, scripts/ablation-replace.mjs, restored blob equal to HEAD each time): showing the card while connected (|| access.connected removed) turned three cases red (3 failed, 6 passed); ignoring the stored dismissal turned §4 red (1 failed, 8 passed); a checklist row that is never done (const done = false) turned two cases red (2 failed, 15 passed).

Acceptance notes

  • Both the card and the row for an administrator. The card is for everyone and the row is the administrator's checklist, so an administrator who has connected nothing sees both. On their Home each reads the two records once (two reads more than a member).
  • An API key counts as connected, as the card says ("an authorization or an API key the person holds"); a revoked or expired key does not.
  • File surface: layout/AppHeader.tsx and index.ts are outside the claim's listed files. AppHeader only gives up its copy of the path rule to connectAssistantPath.ts (21 lines out, 4 in, behaviour unchanged, its tests pass); index.ts adds the two exports the console needs.
  • Clause-②: yes (widening): eight new catalogue keys per published @object-ui/i18n pack, and two new exports from @object-ui/app-shell (a private package); nothing removed.

Verification

Live, showcase on this branch (Vite console against it), admin and member, en and zh
  • Administrator, en, nothing connected: Home shows the card ("Work here from your AI assistant … Connect an AI Assistant") and the checklist row "Connect an AI assistant" not done ("2 of 7 done"); the card's button opened /apps/com.objectstack.account/page/connect_agent.
  • Administrator after minting an API key (POST /api/v1/keys): no card; the row is done ("An AI assistant or API key of yours is connected.", "View"), "3 of 7 done". In zh the same row reads 「连接 AI 助手 / 你已连接了 AI 助手或 API 密钥。/ 查看」, 「已完成 3/7」.
  • Member (created with admin/create-user, password changed), zh, nothing connected: the card 「在 AI 助手里使用本系统 … 连接 AI 助手」, no checklist. Closing it removed it; after a reload it stayed hidden.
  • The server was the showcase built from the earlier base of this thread, with this branch's console; the change is console-only.
Local tests and gates
  • pnpm --dir ui exec vitest run packages/app-shell/src/console/home/ packages/app-shell/src/console/connect/ packages/app-shell/src/layout/ apps/console/src/pages/settings/ packages/i18n/ on head 68ff0b2: 318 files passed, 3263 tests passed, 13 skipped.
  • type-check for @object-ui/app-shell, @object-ui/i18n and @object-ui/console: exit 0 (after building the console's dependency closure). eslint on the touched files: 0 errors; the new files carry no warnings.
  • node scripts/pm/dispatch-gates.mjs --commands derived 38 families on head 68ff0b2; all 38 exit 0, --ran reconciliation: 38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN (includes pnpm --dir ui exec vitest run scripts/ and node scripts/check-sdui-manifest.mjs).

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (No spec change.)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; eslint on the touched files passes (the repo-wide pnpm lint is CI's).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: n/a.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FEkQ5pMhSEyeAKtt6btsBe


Generated by Claude Code

…as connected one; the first-run checklist gains its row

Co-Authored-By: Claude <noreply@anthropic.com>
…row, through the real router and data bus

Co-Authored-By: Claude <noreply@anthropic.com>
… of any

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the size/l label Nov 7, 2026
@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 7, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr

Contract review

Served-tier: TIER_DEFAULT
Head-sha: 68ff0b24d8f7246075ba39a7b6b46023b68ff439
Local-runs: none

The lane seat's own review of record, owed by the Clause-②: yes (widening) declaration alone (face declaration). No path of the diff is a published schema (packages/spec untouched) or a governed path.

① Derived judgments

  • @object-ui/i18n (published) gains eight keys in each of the eleven locale packs (ui/packages/i18n/src/locales/*.ts, +12/-0 each): home.connectAssistant.title, body, action, dismiss and console.firstRunChecklist.connectAssistant.title, todo, done, action. No key is removed or reworded. A widening: Clause-②: yes (widening) is RIGHT.
  • @object-ui/app-shell is private: true: the new exports useConnectedAccess, ConnectedAccess, ConnectedEntry and connectAssistantPath are not published surface. useConnectedAccess gains an optional { enabled } argument (default true, so the Connect page's existing call is unchanged), and an adapter without the auth client now reads as failed instead of throwing out of the effect.
  • @object-ui/console changes only FirstRunChecklist.tsx (a new row) and its test; no export changes.
  • Metadata-protocol: none is RIGHT: Home card and checklist row read existing records (sys_oauth_consent through oauth.authorizedClients.list(), sys_api_key); no metadata an author writes changes.
  • Accept sets: no door changes. The row's done state is read from those records, never from a click, and a row or card whose read is out or failed is not drawn, so a failed read is never shown as "nothing connected".

② Semver level

  • patch on @object-ui/i18n, @object-ui/app-shell and @object-ui/console, with both declaration lines on the PR body and the changeset: RIGHT under ruling A.

③ Boundary flags

  • layout/AppHeader.tsx gives its copy of the connect-page path rule to the new connectAssistantPath.ts (one rule, three readers), outside the claimed file list. Accepted: same feature, behaviour unchanged, its tests pass per the dev.
  • The changeset also bumps @object-ui/console, because the checklist row lives there. Accepted.
  • One "has connected" read: Home card and checklist row both call useConnectedAccess, the read Connect an Agent never says what an assistant can do once connected, or whether the connection worked #30898 built; no second copy.
  • The claim said Clause-②: no; it is amended on the card to yes (widening) (as measured).
  • open_questions: none.

Implemented-by: claude/project-thread-l2jntk
Reviewed-by: session_01FEkQ5nLA7wiVY5YWjT9Svr

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr

席位核对 · ACCEPT · 2026-11-07T19:34Z · head 68ff0b24d8f7246075ba39a7b6b46023b68ff439

Seat domain:ui#1 reviewed the diff of its own dispatch (claim 6709202999 on #30895 with amendment 6711870961, card thread session_01FEkQ5pMhSEyeAKtt6btsBe, report 6711843941). Read against GitHub, not the report.

  1. Shape: 22 files, +694 / -29. Home draws ConnectAssistantCard for a signed-in person only when the served Account app carries the Connect page (connectAssistantPath), the person has not hidden it on this browser (connectAssistantCardGate, a per-person localStorage key), and useConnectedAccess answered ready with nothing connected; a pending or failed read draws nothing. The administrator's first-run checklist gains a connect_assistant row whose done state is that same read (an authorization or a working API key), never a click, left out when unreadable or MCP is off. useConnectedAccess gains { enabled } (default true) and turns a missing auth client into a failed read; AppHeader.tsx reads its path from the one connectAssistantPath rule. Eight keys in all eleven @object-ui/i18n packs. Body says Fixes #30895; no other closing keyword.
  2. Premise: Connect an Agent never says what an assistant can do once connected, or whether the connection worked #30898 (PR feat(console): Connect an AI Assistant names the connected assistant and its last call; plain-words page subtitle #31198) built the one "has connected" read on main; this PR reuses it in both new readers, with no second copy.
  3. Gates / check-runs: 55 runs on this head, 44 success, 11 skipped, 0 red. Dev: 38/38 derived gates exit 0 with 0 NOT-MEASURED and 0 UNRUN, targeted vitest 318 files / 3263 passed, type-check for app-shell, i18n and console exit 0. mergeable_state clean.
  4. Accepted deviations / notes: AppHeader.tsx outside the claimed surface (one path rule, behaviour unchanged); the changeset also bumps @object-ui/console, where the row lives; useConnectedAccess's { enabled } and failed-read change. All three are in the PR body.
  5. Out of scope / Skills-docs: Metadata-protocol: none; no packages/spec/src path, so Skills-docs: is not owed. Nothing filed.
  6. Landing: check-governed-merges --pr 31236: not governed, 723 changed lines, so no human approval owed. Clause-②: yes (widening) (eight added i18n keys per pack): its TIER_DEFAULT review is PASS on this head (6711875180). Changeset patch for @object-ui/app-shell, @object-ui/i18n and @object-ui/console. Landing on the maintainer's standing words 「按照 pm-dispatch 规则复核过的都授权」 (2026-10-25T11:35Z) and 「你应该使用 pm-dispatch 技能审核和落地pr」 (2026-11-07T16:59Z). Relay pr_ready, then automerge_enable. On merge Connect an Agent is buried in Setup and in a collapsed Account group; put it where each person looks, and call it Connect an AI Assistant #30895 closes by Fixes; the seat removes pm:dispatched.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 7, 2026 19:35
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 7, 2026 19:35
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 7, 2026
Merged via the queue into main with commit a0b40f2 Nov 7, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-l2jntk branch November 7, 2026 20:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Connect an Agent is buried in Setup and in a collapsed Account group; put it where each person looks, and call it Connect an AI Assistant

1 participant