feat: shared tab system, universal markdown code blocks, subtle scrollbars#10003
Conversation
…le scrollbar Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying windmill with
|
| Latest commit: |
f0e8b20
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://6e299aea.windmill.pages.dev |
| Branch Preview URL: | https://glm-improve-session.windmill.pages.dev |
The session preview tabs were bespoke markup; converge them onto the same DraggableTabs component the raw-app editor uses, gaining drag-reorder and keyboard nav. The active tab keeps its breadcrumb/router picker via a new tabAccessory snippet, and tabs persist their new order. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an afterTabs snippet to DraggableTabs that renders inside the scroll row after the tabs (unlike trailing, which stays pinned outside it), and move the session preview "+" there so it sits next to the last tab. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dary/50 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d chat Extract ScrollableX's hover-revealed scrollbar styling into a global .scrollbar-subtle utility (both axes, size via --wm-scrollbar-size), have ScrollableX consume it, and apply it to the AI chat message list so the chat scrollbar matches the tabs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…own fences, Tailwind ScrollableX - HighlightCode: keep the subtle CopyButton + surface chip behind buttonsOnHover so the ~20 non-markdown callers keep the original light copy Button. - MarkdownCodeBlock: unlabeled/unknown fences render as plaintext instead of being mis-colored as TypeScript; added common language aliases (ts/js/py/...) so real languages still highlight. - ScrollableX: replace the custom <style> block with Tailwind overflow classes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Guilhem-lm's task in 2m 11s —— View job cc @Guilhem-lm Mergeable, but should ideally address nits: Reviewed the full diff against FindingsP2 — In Notes (non-blocking)
AGENTS.md compliance
Test coverageFrontend-only change with no new pure-logic utility of the kind that carries a sibling Manual verification worth doing before merge: on a script/flow/resource markdown description and an App Markdown component, confirm labeled fences highlight, unlabeled/unknown fences render plain, and hover-copy + subtle scrollbar work — and check a |
Pi ReviewGood to merge SummaryThis is a well-structured frontend polish PR that introduces shared primitives ( Test coverage
FindingsP2 —
|
Codex Reviewcc @Guilhem-lm Found 1 issue:
Test coverage Frontend component changes generally do not require component tests here. The main automated gap is the new pure Manual verification should include the Troubleshoot Flow tutorial through the “Explore the tabs” step and confirm the driver highlight attaches to the tab row. I could not run frontend checks locally: |
- MarkdownCodeBlock: drop 'powershell' from the sql group so it renders plaintext instead of SQL-colored (no powershell highlighter in the map). - sessionPreviewTabs.test.ts: cover reorder (reorders+persists, ignores unknown ids / keeps omitted at end, no-op when unchanged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lector hook codex-review: removing scrollbar-hidden broke the tutorial's '.border-b.flex .flex-row.whitespace-nowrap.scrollbar-hidden.mx-auto' selector. The class is inert on the non-scrolling row (ScrollableX owns the scroll) but is kept as the tutorial's stable hook. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
I've now completed a thorough review of all 16 changed files. All three findings from prior reviews (Claude's Pi ReviewGood to merge Prior findings resolvedAll three findings from earlier reviews are addressed in the current diff:
Diff reviewThe 16-file change is clean and self-contained:
AGENTS.md compliance
Test coverageFrontend pure-logic — Manual verification — the kitchen_sink additions already give a manual harness for the markdown code blocks (real |
Codex Reviewcc @Guilhem-lm Found 1 issue:
Test coverage Frontend-only change. The new |
As the universal pre renderer, MarkdownCodeBlock also handles sanitized raw HTML <pre>text</pre> from rehypeRaw, where the text is a direct child of <pre> (no <code>). Fall back to that text child so raw pre content isn't dropped to an empty block. Kitchen-sink sample gains a raw <pre> case. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
I've completed a thorough review of all 16 changed files. All four prior findings are resolved in the current diff, and I find no new issues. Pi ReviewGood to merge Prior findings resolvedAll four findings from earlier reviews are addressed in the current code:
Diff reviewThe 16-file change is clean and self-contained:
AGENTS.md compliance
Test coverageFrontend pure-logic — Manual verification — the kitchen_sink additions exercise the real chat render path and DraggableTabs scrollbar with overflow tabs. The PR author's test plan in the description covers all user-facing touchpoints. No additional manual scenarios are needed beyond what's already covered. |
Codex ReviewGood to merge No issues found. Checked for bugs, security, performance regressions, and AGENTS.md compliance. Test coverageFrontend: the PR adds focused tests for the new pure Manual verification still needed before merge: exercise markdown/code blocks in chat and shared markdown surfaces, plus session preview tab dragging/closing/opening in the browser, and confirm the subtle scrollbars render correctly. I did not run tests or Playwright because this was a read-only review request. |
Summary
A batch of frontend polish across the AI chat, markdown rendering, and tab strips, unified around two new shared primitives (
MarkdownCodeBlock, a.scrollbar-subtleutility) and the existingDraggableTabs:GfmMarkdown/AppMarkdownsurface, not just the two AI-chat renderers.DraggableTabscomponent the raw-app editor uses (drag-reorder, keyboard nav, close), keeping its active-tab breadcrumb/router picker..scrollbar-subtleutility (thin, hover-revealed thumb) shared by the tab strips, code blocks,Tabs/TabsV2headers, and the AI chat message list — replacing a broken melt scrollbar and the chunky native ones.Markdown code blocks
MarkdownCodeBlock.svelte— chat-agnosticsvelte-exmarkdownprerenderer: highlighted panel (bg-surface-secondary, rounded,text-xs), hover-revealed copy button on abg-surfacechip, subtle horizontal scrollbar. Apply button + mermaid are opt-in props (default off) so untrusted markdown never executes mermaid. Recognized fence languages (incl. common aliases likets/js/py) are highlighted; unlabeled/unknown fences render as plaintext rather than being mis-colored as TypeScript.markdownPlugins.ts— added{ renderer: { pre: MarkdownCodeBlock } }to the shared chain. Language read from thelanguage-*classrehypeSanitizepreserves; code highlighted as escaped text (no new XSS surface).CodeDisplay.svelte(chat) — slimmed to a thin wrapper delegating toMarkdownCodeBlock, adding the Apply button + mermaid.HighlightCode.svelte— the subtleCopyButton-on-a-surface-chip is opt-in viabuttonsOnHover(set by the markdown/chat renderer only); the ~20 other callers keep the original light copyButton. Also gains optionalcustomScrollbarX.Scope note: markdown sinks that bypass the shared chain (
DisplayResult,AiSkillsSettings, the chat "Thinking" block) intentionally keep plain code blocks.Tabs
DraggableTabs.svelte— newtabAccessorysnippet (per-tab, e.g. the session's active-tab picker; a click on it stops propagation so it doesn't re-select the tab) andafterTabssnippet (rendered inside the scroll row after the last tab, e.g. a "+" button — vstrailing, which stays pinned outside). Now consumesScrollableX.sessions/+page.svelte— bespoke tab markup replaced withDraggableTabs; active-tab router picker →tabAccessorychevron, "+" new-tab →afterTabs(right after the last tab). Tab stripbg-surface-secondary/50; preview-bar buttons (collapse / open-in-workspace / fullscreen) are hover-only background. (AdoptingDraggableTabsrestyles the active tab to itsbg-surface-tertiary— an intended consequence of sharing the component.)sessionPreviewTabs.svelte.ts— newreorder(orderedIds)method (with persistence) for drag-reorder.Tabs.svelte/TabsV2.svelte— header rows useScrollableXfor the subtle scrollbar.Scrollbars
.scrollbar-subtleutility (app.css) — thin, hover-revealed rounded thumb on both axes, thickness via--wm-scrollbar-size, out-specifying the app-wide*::-webkit-scrollbar.ScrollableX.svelte— native horizontal scroll (Tailwindoverflow-x-auto) consuming.scrollbar-subtle, replacing melt'screateScrollArea(whose thumb never tracked scroll position).AIChatDisplay.svelte— the chat message list uses.scrollbar-subtleso it matches the tabs.Screenshots
Universal markdown (
GfmMarkdown) — highlighted with hover copy button:AI chat code blocks:
Sessions — preview tabs on the shared DraggableTabs (active "Runs ⌄" with picker, "+" after last tab, subtle chat scrollbar):
Test plan
Markdowncomponent with a code block → labeled highlight, unlabeled render plain, hover copy, subtle scrollbar, copy worksHighlightCodecaller (editor bar, log panel, script/run page) → copy button unchanged (light Button)Tabs/TabsV2header overflow shows the subtle scrollbar🤖 Generated with Claude Code