Address review findings: - Summaries no longer return the raw blocker walk. A shared helper (server/src/services/issue-status-presentation.ts) returns only state, reason and counts; a sampled blocker identifier stays only when the actor can read that blocker. Blocker titles and IDs never leave the route. - Search results and case work tasks return the same glyph-only blocker state for blocked tasks. - The chat "task created" card and coordinator created-task links keep displayStatus, externalConversationState and blockerAttention from their producers, so their chips/glyphs match the task pane. - Tests drive the real producers (taskCreatedItems, summaries-backed links, search service, cases route) and cover a private blocker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@paperclipai/ui
Published static assets for the Paperclip board UI.
What gets published
The npm package contains the production build under dist/. It does not ship the UI source tree or workspace-only dependencies.
Storybook
Storybook config, stories, and fixtures live under ui/storybook/.
pnpm --filter @paperclipai/ui storybook
pnpm --filter @paperclipai/ui build-storybook
Typical use
Install the package, then serve or copy the built files from node_modules/@paperclipai/ui/dist.
Editor dependency identity
Keep the root and workspace overrides for @codemirror/state,
@codemirror/view, and @lezer/common aligned. CodeMirror requires shared
extension identity, while Lezer parsers and syntax highlighters require shared
NodeProp IDs. Multiple Lezer copies can crash code-block highlighting with
tags is not iterable. src/lib/codemirror-single-instance.test.ts checks the
installed dependency graph and highlights sample code through the editor's real
language dependencies. GitHub Actions owns regeneration of pnpm-lock.yaml.