githubnext/chopinPublic

Let's compose rich plans together

Show Chat research status with the document research card #341

MergedMaggieAppletonmerged 3 commits intomainfromrefs/pull/341/head
  1. MA

    ## Why

    After Start, the Chat research card kept its "Research suggestion" heading and showed the raw stage enum ("Research searching", "Research queued"), sometimes stepping backwards, with no progress or Cancel. The document card for the same request already had a designed vocabulary ("Searching sources", track, Cancel/Retry). The two surfaces read like two products. The document card also set the whole multi-line brief in bold.

    ## What changed

    - Accepted offers in Chat render the document's `ResearchCard` (one vocabulary, one motion): stage words, 5-step track, sources found, Cancel while active, Retry when failed, ready title and summary that opens the report. The card aligns with the message text column. - Before the request is readable, the card shows the brief as "Waiting to start" instead of "Loading research…". Resume / Retry link check stay as a quiet row under the card. - An active request's stage never steps backwards in Chat (`forwardStage`); terminal and retried stages always show. - Document and Chat cards: the brief is regular weight, clamped to two lines with Show more / Show less. Report titles stay semibold. - A card that changes state in this session settles in (200 ms opacity/translate, reduced-motion off).

    No server changes.

    ## Screenshots

    Searching, before / after ![searching](https://github.com/user-attachments/assets/ae02664c-f19c-4e0d-9a19-6afc1498958b)

    Failed, before / after ![failed](https://github.com/user-attachments/assets/e7c6164d-add0-47bf-bde5-973eb60585d6)

    Ready, before / after ![ready](https://github.com/user-attachments/assets/d27bc1c8-2a48-4cad-9b5f-bfe90701e7f5)

    Phone width ![phone](https://github.com/user-attachments/assets/f927867f-3a20-47b4-b9e5-a442ac96e64b)

    Rendered from the real `Transcript` with a scripted research store (this instance cannot run web research).

    ## Testing

    - `bun test apps/web/src/chat` — 162 pass - `bun test packages/editor/src/widgets/research` — 30 pass - `bun --bun node_modules/@playwright/test/cli.js test --config e2e/source/playwright.config.ts research-offers.native.ts --timeout 300000` — 5 pass (updated for the new vocabulary) - `bun run ci`, `bun run types` — pass - `e2e/research-offers-ui.e2e.ts` ready-state assertions updated; relying on CI browser integration (local E2E suspended)

    🤖 Generated with [Claude Code](https://claude.com/claude-code)

  2. MaggieAppletonreferenced this in Condense the Chat research suggestion card #348last month on GitHub

  3. MA
    Author

    **Review:** Looks good

    Checked in the real app: #348's head on a fake-GitHub server with the fake Planner and fake Jev, `CONVERSATION_PLAN=on`. Port 8797 was taken by the 8795 reference server, so the fake MCP ran on 8897 through a local, uncommitted fixture change. I started research from Chat through the real offer flow. With this harness, web search fails within about a second. Running ("Waiting to start" → "Searching sources", with Cancel and the track) and failed (with Retry) are real-app states. Ready could not be reached; it is covered only by the updated e2e and the author's scripted screenshots.

    What works: - The Chat card is the document `ResearchCard`. Next to the document card for the same request (failed state), they read as one family: same indicator, stage words, callout, and Retry. The only difference is the document's remove ×. - Retry from Chat works: 200, then "Searching sources" with Cancel. - The Chat card settles in over about 200 ms with opacity and translate, and is turned off for reduced motion. - At phone width (390) the failed card fits the message column. The brief clamps to two lines with Show more. - CI is green: container, e2e, and format/lint/types/tests. Locally, `bun run ci`, `bun run types`, and `bun test apps/web/src/chat packages/editor/src/widgets/research` (192 pass) all pass.

    Findings (none blocking): 1. **A disabled "Resume" row flashes on every Start.** `apps/web/src/chat/research-offer.tsx`, `AcceptedResearch`: while the link is `pending`, `canResume` is true, so a disabled "Resume" button renders under the card for about 100–180 ms (seen in frame captures) until the link becomes `linked`. The layout jumps when the row leaves. Suggest showing Resume only for `unlinked` or an exhausted error, not `pending`. This is a Chat-only change, so it belongs here. 2. **Cancel could not be confirmed.** Both Cancel attempts (one clicked right after Retry) got `409 {"error":"research workspace is not ready"}`. The card then stacked "Research could not be cancelled." above the real failure. With this harness the job may already have failed by then, so this may only be a race. It still means Cancel shows in "Waiting to start" while the server may refuse it. Suggest clearing `actionError` from a cancel when the request reaches a terminal stage. Please also confirm a successful Cancel against a slower job. 3. **`forwardStage` writes a ref during render.** `shown.current = stage` in render. It works and is idempotent. The ref also isn't reset if `id` changes; that's harmless today because one offer maps to one request. 4. **Show more has no focus style.** `packages/editor/src/styles.css`, `.plan-research-more` has no `:focus-visible` style beyond the browser default. Its `margin-block-start: 0.125rem` is a raw value, though the token check passes.

    Document card (top) and Chat card (bottom) for the same failed request: ![family](https://github.com/user-attachments/assets/a2a15aa9-f9a2-402a-9487-77cd2f74bc62)

    Frames 0–350 ms after Start, showing the disabled Resume row in frames 2 and 3: ![resume flash](https://github.com/user-attachments/assets/66f20ada-bdb5-4bdc-bedc-0b662e504ae6)

  4. MA
    Author

    Addressed in 2c98b5eb: 1. Resume now shows for `unlinked` straight away, and for `pending` only after the link has stayed pending for 1.5 s. That removes the flash after Start but still offers Resume for a request that is really stuck; the seeded pending e2e relies on that. 2. If the server refuses a cancel because the request is not ready yet, Chat retries it up to 3 times, 600 ms apart. If it still fails, the message is the quieter "Research could not be cancelled yet.", and it clears once the request reaches a terminal stage. 3. The displayed stage now lives in state, keyed by request id, and is updated with React's adjust-state-during-render pattern. Render no longer writes a ref. 4. `.plan-research-more` has a `:focus-visible` ring from the focus-ring tokens and uses `calc(var(--spacing) * 0.5)` for its margin. Also updated the stale "Research accepted" assertion in `research-offers-ui.e2e.ts`, which only runs with `E2E_RESEARCH_OFFERS=1`.

  5. MA
    Author

    Follow-up in bc36c2e9: `focus.test.ts` requires focus outlines to come from the theme, so I removed my `:focus-visible` outline. Show more now gets the theme's standard ring, keeps its colour change on focus, and has a small radius so the ring fits. CI is green.

  6. MaggieAppletonhead-ref-force-pushed 640c1f60f05blast month on GitHub

  7. MaggieAppletonmerged f2d383a2057clast month on GitHub

  8. MaggieAppletonclosedlast month on GitHub

  9. MaggieAppletonhead-ref-deletedlast month on GitHub