Repository navigation
Correct stale code claims in the agent docs and the design system #286
Description
Problem
Four docs state facts that the code no longer matches. Most are about the chat composer. Agents and contributors follow these files, so a stale line leads to wrong changes.
Each row below comes from a code trace on 14ab7f9c1. Check it again before you edit. Rows that other issues already fix are left out. See Out of scope.
apps/webapp/src/components/chatroom/CLAUDE.md
| Line | The doc says | The code does |
|---|---|---|
| 18 | Edit and comment paths probe storage with ensureOutboundStorageReady(). |
Every composer mode probes there, before the early clear. persistChatMessage then skips its own probe for composer sends. |
| 66 | After submit, refocus the editor only if it was the active element. | On a phone or tablet, keepKeyboardAfterSubmit is true. The editor then refocuses unless the emoji panel or the link dialog is open. |
| 67 | onUpdate captures workspaceId, channelId, and isToolbarOpen in its closure. |
onUpdate reads draftCtxRef.current, which an effect keeps current. isToolbarOpen does not exist in the webapp source. |
| 69 | Text and HTML drafts live only in IndexedDB. | When IndexedDB fails to open, the draft store keeps drafts in a module-level Map. |
| 72 | The sign-in helper is the same entry as SignInToJoinChannel, and opens the shared SignInDialog. |
Nothing mounts SignInToJoinChannel. On a phone or tablet, the helper opens the SignInSheet bottom sheet. |
| 88 | attachments.cy.ts still clicks [data-testid="chat-media-filter"]. |
The click is still in the file, inside a test marked it.skip, so it never runs. |
| 105 | The mention popup is 98% of the surface, with 1% inset on each side. | WIDTH_RATIO = 0.99 gives 99% width and 0.5% inset. design-system.md already says 99%. |
| 110 | The send sanitizers remove data-id and data-type from spans, so mention taps need an allowlist change. |
The sanitizer config sets no ALLOW_DATA_ATTR (apps/webapp/src/utils/sanitizeContent.ts:3-20), and DOMPurify keeps data-* attributes by default. Mention spans keep data-id and data-type. Only class is removed. |
| 119 | The only passkey path is the background autofill on the email field. | Passkeys were removed on 2026-09-07. The email field sets autoComplete="username" with no webauthn token. |
apps/webapp/CLAUDE.md
| Line | The doc says | The code does |
|---|---|---|
| 121 | .mobileLayoutRoot tracks window.visualViewport through AppProviders resize and scroll listeners. |
AppProviders only calls useVisualViewportCssSync, which owns those listeners. |
| 137 | AppProviders resets the scroll when .mobileLayoutRoot is present. |
The reset lives in useVisualViewportCssSync, and it depends on the route mode. |
| 187 | Only useYdocAndProvider wires the three shared helpers. |
useYdocAndProvider imports only collabSession. It imports neither providerCollabStatus nor openInlineSignInDialog. Seven modules import providerCollabStatus directly. Nine import openInlineSignInDialog, including openComposerSignIn, PrivateDocumentGate, and PadTitle. |
| 299 | Document comments are messages.type = 'comment' rows with metadata.comment. |
metadata.comment always holds. A comment with an attachment gets text when it has a caption, and the media kind when it has none. CommentReference checks metadata.comment, not only the type. |
| 322 | The document id is in notification.channel_id, at 10-func-notifications.sql:655 and :667. |
The fact holds, but the lines are :657 and :669. |
extensions/CLAUDE.md
| Line | The doc says | The code does |
|---|---|---|
| 70 | The pad and the composer share the textarea shape inside a daisyUI .input wrapper. |
Only the pad uses the .input wrapper. The composer puts textarea classes on the field. |
| 71 | describeInternalDocumentLink returns { label, icon }. |
It also returns sublabel. |
| 73 | The desktop chip style .is-internal lives in document-styles.scss. |
The code adds is-internal, but the stylesheet styles .internal-link-chip and has no .is-internal rule. |
.cursor/docs/design-system.md
| Line | The doc says | The code does |
|---|---|---|
| 324, 337 | The TOC grip rows say "grip chrome unified" and "one chrome family". | AGENTS.md §Code Quality bans "chrome" for UI. Use "frame". |
| 477 | The mobile emoji picker override is at _mobile.scss:68. |
The em-emoji-picker block starts at _mobile.scss:83. |
| 624 | The input row is gap-1.5 px-3 py-2, with min-h-11 on mobile. |
On mobile the row is min-h-11 gap-1 px-3 py-2, so the mobile gap is gap-1. |
| 628 | The anon sign-in surface for SignInToJoinChannel is a live row. |
Nothing renders it. Signed-out users get the live composer. |
| 274, 416, 637 | The is-active recipe is at _toolbar.scss:27. |
It starts at _toolbar.scss:30. |
| 416 | The div.select title lock is at _toolbar.scss:50. |
It starts at _toolbar.scss:53. |
| 275 | The disabled hover rule is at _toolbar.scss:38. |
It starts at _toolbar.scss:41. |
| 645 | The desktop insert menu opens on hover, with a 100 ms close timer. | It opens on click or tap only. 345943d62 removed the hover timers. |
| 670 | The expanded emoji panel is min(70vh, 480px). |
It is 70% of the measured host column, capped at 480 px. |
One code line that should follow the doc
.cursor/docs/design-system.md:442 says a dialog card exits in 150 ms. The composer link dialog card reuses its 180 ms transition on exit (apps/webapp/src/components/chatroom/components/MessageComposer/components/ComposerLinkDialog/ComposerLinkModalShell.tsx:8-9). The file's own comment names MOTION_DIALOG_OUT_MS, which is 150.
Acceptance criteria
- Each doc line named in the tables states what the code column says. Every
file:linecite in an edited line points at the named code on the fix commit. - The composer link dialog card fades in over
MOTION_DIALOG_IN_MS(180 ms) and out overMOTION_DIALOG_OUT_MS(150 ms). A change to either constant changes the card timing. - No line in these four files uses "chrome" for UI.
-
bun run check:agent-docsreports no problem in the four files this issue edits. At14ab7f9c1the gate already fails onapps/hocuspocus.server/CLAUDE.md:101, which is outside this issue.
Agent Brief
Category: documentation
Summary: Make the listed rows in four docs match the code, and make the link dialog exit use the motion token.
Current behavior:
Twenty-six doc rows across four files describe code that has changed. The composer link dialog card exits in 180 ms. The design system says a dialog card exits in 150 ms.
Desired behavior:
Each row states what the code does today. The dialog exit uses the house motion token.
Key interfaces:
- The chatroom agent doc, the webapp agent doc, the extensions agent doc, and the design system.
MOTION_DIALOG_IN_MSandMOTION_DIALOG_OUT_MSin the motion tokens.
Out of scope
These rows are fixed by other issues:
- Chatroom agent doc line 63, full-tile retry: Refuse an oversized chat file when it is added, not after it fails #280.
- Chatroom agent doc line 70, post-send draft clear: Keep the unsent draft when the user edits a message #277.
- Chatroom agent doc line 73, the dead
disabledprop: Rename the composer ToolbarButton type prop, and drop two dead send props #271. - Chatroom agent doc line 78, the format toolbar subscription: Show active state in the mobile format grid #269.
- Chatroom agent doc lines 79 and 106, the Escape contract: Let the first Escape close only the mention picker or the link popover #268.
- Chatroom agent doc line 79, overlay exclusivity: Close the composer emoji panel when a voice recording starts #284.
- Chatroom agent doc line 89, per-key isolation: Stop chat drafts from dropping attachments or listing deleted uploads #267.
- Chatroom agent doc line 132, skeletons on a load error: Drop the composer and participants skeletons when the channel data load fails #283.
- Webapp agent doc line 107, the focus retry timing: Focus the requested chat composer when it appears #294, which changes that retry.
- Extensions agent doc line 68, the link dialog keyboard rule: Keep the keyboard state when the composer link dialog opens and cancels #285.
- Design system rows for phone touch targets: Give the phone composer's small controls a 44 px touch target #279. The
.chat_msg_containerrow: Remove dead chat composer code #274. - The own-send rise and pending rows (chatroom doc line 49, design system line 558). Send hand-off from the chat composer into the feed #263 changes that code, so it owns those lines.
Notes
These files are exempt from the sentence cap for their existing text. New and edited text follows the Simplified English rules in .cursor/skills/tech-writer/SKILL.md. Do not rewrite lines this issue does not name.
Activity
docs(webapp): match the chat docs and design system to the code