Skip to content

ID-147 {147.1} RESEARCH — Extend UI + Streamdown → Procurement-domain component/block mapping (UI foundation)

ID-147 {147.1} RESEARCH — Extend UI + Streamdown → Procurement UI mapping

Section titled “ID-147 {147.1} RESEARCH — Extend UI + Streamdown → Procurement UI mapping”

Type: RESEARCH ({N.1}). Baseline UI-foundation research for Task ID-147. Maps the external Extend UI design system (docs / components / blocks) and Streamdown (the streamed-markdown renderer) onto concrete Procurement-domain UI surfaces defined by the ratified ID-145 form-first PRODUCT/TECH pair. Feeds a potential UI spec-chain that gates ID-145.19 (item-page UI surfaces). It does not design or decide adoption — it catalogues, reconciles against in-tree reality, maps, and surfaces owner decisions.

Authored 12/07/2026, fresh Planner context. UK English throughout (DD/MM/YYYY, “colour”, “organisation”). Track: /procurement worktree (branch ca-s435-procurement-baseline). Ledger writes on MAIN only; not committed here.

Sources fetched & cited (not summarised from memory): https://ui.extend.ai/ui/docs, https://ui.extend.ai/ui/docs/components, https://ui.extend.ai/ui/blocks, https://streamdown.ai/, plus GitHub/npm licence confirmation for extend-hq/ui and vercel/streamdown (12/07/2026).


IN scope (this Task): a Procurement-domain baseline mapping only — Extend/Streamdown ⇒ the ID-145 form-first surfaces (item page, document viewers, citation UI, file upload, schema builder, layout, Q&A, dashboard).

OUT of scope (deliberate, named follow-on session): the wider-platform rollout — Intelligence, Product Guides, Sales Proposals, and the shared document / Q&A / citation surfaces those application types will also consume. Several Extend capabilities map far better onto that platform layer than onto Procurement v1 (flagged as “forward-platform candidates” in §4). Adopting Extend at the shared layer is a strategic decision for that follow-on session, not this one. This Task must not design that rollout, and must not let a platform-wide ambition inflate the Procurement baseline.


1. Executive finding (the reconciliation that reframes the brief)

Section titled “1. Executive finding (the reconciliation that reframes the brief)”

The dispatch brief stated “Extend UI is already used for the ID-117 unified diff viewers”. That premise is inaccurate and is the single most important correction this research makes.

  • Extend UI is ABSENT from the tree. package.json carries no @extend/extend-* dependency; there is no Extend import anywhere under components/; and components.json has no registries block (only style/aliases/iconLibrary), so the extend-hq/ui shadcn registry is not registered. Verified 12/07/2026.
  • What actually exists is a locked-but-unshipped decision: ID-117 (S380, Liam) locked extend-ui-kit as the substrate for the binary-diff leg, but ID-117 TECH itself records extend* / @extend ABSENT from package.json; components.json has no registries block … extend-hq/ui not yet registered” and carries the install as a {117.4} install slice (register the registry + add PDF/DOCX/XLSX viewers), not a landed fact.
  • The in-tree diff viewers (components/diff/unified-diff-container.tsx, components/diff/binary-diff-pane.tsx, components/item-detail/revision-diff-view.tsx) are custom, and ID-117 RESEARCH found no Extend component performs a doc-to-doc diff — its “Document Split Viewer” is a packet-splitter, so any binary version-diff is composed from two Extend file-viewers side-by-side, with PDF still served by the working react-pdf.

Consequence for ID-147: the mapping below treats Extend as a prospective, cherry-pickable registry whose first real arrival in-tree would be the ID-117 {117.4} install slice — a sequencing dependency for any Procurement adoption, not a given. Streamdown, by contrast, is genuinely adopted (Apache-2.0, DR-040) and already renders streamed content in-tree.


2a. Extend UI — licence & adoption model (decision-critical)

Section titled “2a. Extend UI — licence & adoption model (decision-critical)”
AttributeFindingSource
LicenceMIT — free for commercial + non-commercial usegithub.com/extend-hq/ui; extend.ai/resources/extend-ui-kit (12/07/2026)
Positioning”Open source React component library for building document processing interfaces” — preview, navigate, search, compare, review the files that power document workflows (PDF/DOCX/Excel/CSV)ui.extend.ai/ui/docs
Distribution / install modelshadcn component registry — components are COPIED INTO your project as source (npx shadcn@latest add @extend/<component>), then adapted. Not an npm runtime dependency.ui.extend.ai; ID-117 RESEARCH §5 (verified S384)
Base primitivesCoss UI (buttons, tooltips, selects, popovers, dialogs, menus)ui.extend.ai/ui/docs
IconsHugeiconsui.extend.ai/ui/docs
FrameworkReact; shadcn-registry ⇒ Tailwind + CSS-variable theming (cssVariables)inferred from shadcn-registry model + Coss UI

Adoption verdict (Extend): licence is a green light (MIT, copy-in source, no runtime dependency, no account/API-key). The friction is architectural fit, not licensing — see the Warm Meridian reconciliation in §5.

2b. Extend UI — component inventory (15; ui.extend.ai/ui/docs/components)

Section titled “2b. Extend UI — component inventory (15; ui.extend.ai/ui/docs/components)”
#ComponentPurpose (one line)
1PDF ViewerDisplay and interact with PDF documents
2DOCX ViewerView Word documents (client-side)
3DOCX Editor (experimental)Edit Word documents
4Excel ViewerDisplay spreadsheet files
5Excel Editor (experimental)Modify spreadsheet content
6CSV ViewerView comma/tab-separated data
7File UploadAccept file submissions from users
8File System (Finder)Browse/select files from a directory structure
9Bounding Box CitationsMark & reference specific document regions (spatial citation overlay)
10Schema BuilderCreate & configure data structures (schema/JSON authoring)
11File ThumbnailGenerate preview images for files
12Layout BlocksOrganise UI elements spatially (compose viewer workflows)
13E-SignatureCapture digital signatures
14Document SplitsDivide documents into sections / packet-split
15Document Viewer SidebarNavigation panel for document viewing

2c. Extend UI — blocks inventory (ui.extend.ai/ui/blocks)

Section titled “2c. Extend UI — blocks inventory (ui.extend.ai/ui/blocks)”

Blocks are composed workflows built from the components above. Enumerated: Layout Blocks (“composed PDF viewer workflows built from layout blocks, signing fields, and document splits”), PDF Dropzone (upload PDFs), Excel Editor, DOCX Editor Block (experimental), Bounding Box Citations, File System (Finder), E-Signature, Document Splits.

Owner-flagged coverage check. The owner specifically called out document-type viewers, citation bounding-boxes, file upload/system, schema builder, layout blocks. Extend covers all of these as components (viewers 1–6, Bounding Box Citations 9, File Upload/System 7–8/PDF Dropzone, Schema Builder 10, Layout Blocks 12). Schema Builder appears in the components inventory but NOT in the blocks inventory — it is a lower-maturity primitive than the document viewers, which matters for the Path-C catalogue mapping (§3, §4).

2d. Streamdown — capability & licence catalogue (streamdown.ai)

Section titled “2d. Streamdown — capability & licence catalogue (streamdown.ai)”
AttributeFindingSource
LicenceApache-2.0 (note: not MIT)github.com/vercel/streamdown; npm (12/07/2026)
MakerVercel (AI SDK ecosystem)vercel.com/changelog/introducing-streamdown
What it isMarkdown renderer purpose-built for streaming AI output; a drop-in replacement for react-markdownstreamdown.ai; GitHub
Streaming edgeParses unterminated/partial markdown (unclosed code/bold) for clean mid-stream render; streaming caret indicator; isAnimating propstreamdown.ai
Feature setShiki syntax highlighting (line numbers, copy/download), KaTeX math, Mermaid diagrams (fullscreen), GFM (tables, task-lists, strikethrough, autolinks); Tailwind typographystreamdown.ai
SecurityHardening blocks images & links from unexpected origins; link-safety modal shows full URL before navigation (rehype-harden, bundled by default)streamdown.ai
In-treestreamdown@^2.5.0 present and used (see §3)package.json:123

Adoption verdict (Streamdown): already ratified and adopted (DR-040), Apache-2.0, in-tree at ^2.5.0. No new adoption decision needed — the only ID-147 question is which Procurement surfaces are “new” enough to trigger the DR-040 “new surfaces first” rule (§3, OQ-4).


3. Existing in-tree usage (what the mapping must EXTEND, not duplicate)

Section titled “3. Existing in-tree usage (what the mapping must EXTEND, not duplicate)”

Markdown rendering is already split in-tree:

  • Streamdown (adopted, DR-040): components/okf/file-render-pane.tsx (ID-132 {132.32}, import { Streamdown } from 'streamdown'), with a bundled-rehype-harden link-safety compat shim lib/okf/prepare-streamdown-content.ts (normaliseInternalMdLinksForStreamdown) so internal relative links survive Streamdown’s default hardening pass.
  • react-markdown (incumbent, migrate-later): components/item-detail/content-renderer.tsx (the item-detail surface ID-145.19 will touch), components/okf/bundle-log.tsx, components/okf/concept-detail.tsx — all react-markdown + remark-gfm ^4.0.1.
  • DR-040 rule: “Any UI work that renders markdown uses Streamdown — starting with NEW surfaces … existing markdown-rendering instances migrated later as a follow-up (its own backlog item).” So new Procurement answer/content surfaces ⇒ Streamdown; the incumbent content-renderer.tsx migrates on the DR-040 sweep unless ID-145.19 chooses to fold it in.

Document/file processing stack is already substantial — and CUSTOM (no Extend):

CapabilityIn-tree todayNotes
PDF viewerreact-pdf ^10.4.1 + lib/pdf-worker + AnnotationLayer/TextLayer CSS in components/reader/pdf-document.tsx (lucide icons, semantic tokens, TanStack)Working client viewer; ID-117 keeps it for PDF
PDF generation@react-pdf/renderer ^4.5.1Server/doc-emit, distinct from viewing
DOCXdocx ^9.6.1, docx-preview ^0.3.7, mammoth ^1.12.0No first-class client DOCX viewer — the gap ID-117 named Extend to fill
XLSX/CSVxlsx ^0.18.5 (SheetJS)A parsing lib, not a rendered viewer component
PDF text extractionunpdf ^1.6.2Server extraction
Rich-text editor@tiptap/* 3.23.4 (+ markdown, tables)Existing authoring editor
shadcn primitivesfull components/ui/* (accordion, button, card, dialog, popover, select, tabs, tooltip, …); components.json: style:new-york, baseColor:neutral, cssVariables:true, iconLibrary:lucideDirect overlap with Extend’s Coss UI primitives (§5)

Citations (id-58) — the flagship data-model finding:

  • The citations table (ID-58, squash_baseline.sql:5459) is text-span-anchored: cited_text text + “Version-on-cite + span anchoring (D-S330-1)” (table COMMENT). It records quoted text and a span, not pixel/region bounding-box coordinates.
  • The q_a_pair cited-kind is DORMANT in v1 (bl-74); ID-145 BI-37 activates it.
  • The only citation UI in-tree is components/source-document-detail/document-citations-panel.tsx (ID-135 {135.16}) — a list grouped by cited_target_kind (Answers/References/Source documents/Concepts, text+icon labels, never colour-only), rendering 0 rows today until the extended-contract writers land. It is not a spatial overlay on a rendered document.

Code-intel orientation (binding, cited verbatim). gitnexus_query({repo:'canonical', query:"citation rendering document viewer bounding box highlight source span"}) returned no UI execution flows for spatial citation rendering — its top hits were pipeline-side citation-text-rendering (scripts/cocoindex_pipeline/producer/enrich.py:_render_citations_section, _annotate_raw_with_anchors), the diff surface (components/item-detail/revision-diff-view.tsx:WordInlineDiff), and the citation query keys (lib/query/query-keys.ts:citations / versions / derivedPairs). This corroborates that bounding-box citation rendering is greenfield in-tree: there is no existing spatial-overlay flow to extend, and the citation data leg is text-span, not coordinate-based.


4. Procurement mapping table (Extend / Streamdown → ID-145 surfaces)

Section titled “4. Procurement mapping table (Extend / Streamdown → ID-145 surfaces)”

Confidence legend — COVERED (in-tree already handles it; Extend optional), FIT (strong Extend/Streamdown match, net-new adoption), PARTIAL (Extend supplies the shell only / needs adaptation), BLOCKED (design fit but a data-model/dependency gap gates it), NONE (no Extend/Streamdown answer → net-new custom build).

Procurement surface (ID-145 BI)Extend component(s)/block(s)Streamdown?How it would be usedConfidence / gap
Document viewer — PDF (BI-16 documents)PDF Viewer (or keep react-pdf)Render uploaded form / tender PDFs on the item pageCOVEREDreact-pdf already works (ID-117 precedent); Extend PDF Viewer optional, adds nothing decisive
Document viewer — DOCX (BI-16)DOCX ViewerClient-render uploaded .docx forms (SQ/ITT often DOCX)FIT — fills a real in-tree gap; arrives via ID-117 {117.4} install
Document viewer — XLSX/CSV (BI-16)Excel Viewer, CSV ViewerRender spreadsheet-shaped tenders/price schedulesFITxlsx is a parser, not a viewer; Extend supplies the render
Multi-document item page (BI-16 documents list)Document Viewer Sidebar, File Thumbnail, Document SplitsNavigate an item’s form + tender-document set; split multi-form packetsPARTIAL / forward — useful once items carry many docs; overlaps custom shell
Citation UI on documents (BI-37; id-58)Bounding Box CitationsOverlay q_a_pair citation spans onto the rendered form/source docBLOCKED — id-58 stores text-spans, not pixel bboxes; Extend needs region coords. Flagship gap (§5, OQ-3)
File upload / manual form entry (BI-9, DR-014)File Upload, PDF Dropzone blockDropzone affordance for “upload a form → it is the item”PARTIAL — UI shell only; must reuse the hardened backend (magic-byte sniff, 50 MB cap, rate-limit) BI-9 mandates
Documents browse / finder (BI-16)File System (Finder)Browse an item’s / engagement’s documentsPARTIAL / forward — ID-135 browse is custom; low Procurement-v1 need
Fillable field structure (BI-20)Schema BuilderRepresent/inspect the per-field slot structure extracted from a blank formPARTIAL / uncertain — Schema Builder edits generic data structures; whether it fits form_template_* field/requirement shape needs a spike (§4, OQ-5). Note: component-only, not a block
Path-C requirement catalogue (BI-24)Schema Builder (candidate)Author/curate reusable requirement catalogue rowsPARTIAL / uncertain — same Schema Builder question; domain-specific catalogue may outgrow it
Fill → completed document (BI-22)DOCX Editor / Excel Editor (experimental), E-SignatureRender/emit the filled form artefact; sign where neededPARTIAL — editors are experimental; fill mechanism is a TECH/Claude-side R5 decision, not a UI adopt
Item page shell / layout (§C)Layout BlocksCompose state/deadline/questions/coverage/documents panelsPARTIAL — overlaps the in-tree shell + shipped cards (ProcurementFormsCard, ReadinessChecklist); leaf reuse at most
Streamed/drafted answer rendering (BI-40/41 draft-stream SSE)YESRender Claude-streamed answer markdown in the (secondary) drafting stack + manual-answer affordanceFIT — DR-040 “new surface”; Streamdown’s streaming caret + partial-parse is exactly this
Item content / question text markdown (BI-14)YES (new) / migrate (incumbent)New question/answer markdown → Streamdown; incumbent item-detail/content-renderer.tsx migrates on DR-040 sweepFIT — decision: fold the migration into ID-145.19 or defer (OQ-4)
Question list + per-question status (BI-14, BI-40 mixed states)List questions with drafted/approved/matched/empty statesNONE — custom (domain state model); no Extend/Streamdown answer
Retrieval / match surfaces (BI-34–36)Show question_matches; MCP-fed candidatesNONE — custom
Promotion / dedup gate (BI-38, Governance zone)Thin review/disposition queue over existing RPC + promote routeNONE — custom; composes existing backend
Workflow-state stepper + outcome (BI-13, BI-18)10-state stepper/badge, outcome capture (non-colour-only)NONE — custom (Warm Meridian)
Coverage / readiness (BI-15)Template-completion coverage + readiness thresholdsNONE — custom (existing ReadinessChecklist)
Dashboard (BI-30–33)(Layout Blocks, weak)Active list, win-rate + shortlist pass-rate, terminologyNONE — custom (charts/lists/RPCs)

5a. Procurement needs with NO Extend/Streamdown answer → net-new custom build

Section titled “5a. Procurement needs with NO Extend/Streamdown answer → net-new custom build”

The domain heart of ID-145 is not a document-processing problem, so most of the highest-value surfaces have no Extend/Streamdown match: the question list + per-question status model, the retrieval/match surfaces (BI-34–36), the promotion/dedup governance gate (BI-38), the 10-state workflow stepper + outcome capture (BI-13/18), coverage/readiness (BI-15), the auto-map review UI (BI-21), the manual-answer affordance for zero-candidate questions (BI-40), and the dashboard win-rate/shortlist surfaces (BI-30–33). These are custom Warm Meridian builds; Extend is irrelevant to them and Streamdown applies only to the answer-markdown they render.

5b. Extend/Streamdown capabilities with NO current Procurement consumer → forward-platform candidates

Section titled “5b. Extend/Streamdown capabilities with NO current Procurement consumer → forward-platform candidates”

Flagged for the out-of-scope follow-on (§0), not ID-145 v1:

  • E-Signature — no signing flow in Procurement v1.
  • DOCX/Excel Editor (experimental) — fill is Claude-side (R5); no in-app document editing.
  • Document Splits / packet-splitting — relevant to multi-form tender packets and the shared platform document layer; forward.
  • File System (Finder) — a browse surface ID-135 already owns custom.
  • Streamdown Mermaid / KaTeX — no diagram/math content in Procurement forms; these earn their keep on Intelligence / Product Guides content, not here.

Bounding Box Citations vs id-58 text-span citations. Extend’s Bounding Box Citations expects spatial region coordinates on a rendered document; id-58 stores cited_text + a text span, with q_a_pair dormant until BI-37 activates it. Rendering Extend bounding boxes therefore requires net-new plumbing — resolving a text span to on-page coordinates against the rendered document’s text layer (feasible on react-pdf’s TextLayer, non-trivial for DOCX/XLSX) or extending the citation write path to persist coordinates. Neither exists. A lower-cost alternative is text-anchored highlight on the existing react-pdf TextLayer, which matches the current data shape without Extend. This is an owner decision (OQ-3), and it is the clearest example of “attractive Extend component, blocked by the Procurement data model”.


6. Warm Meridian / theming reconciliation (gates cherry-pick vs wholesale)

Section titled “6. Warm Meridian / theming reconciliation (gates cherry-pick vs wholesale)”

Extend is a shadcn registry (Coss UI primitives, Hugeicons, Tailwind + CSS variables). The in-tree design system is Warm Meridian, itself shadcn-token-shaped:

  • Tokens reconcile at the semantic layer. Warm Meridian’s semantic tokens are bare shadcn (--background, --foreground, --primary, --border, …; see components/CLAUDE.md F3), and components.json sets cssVariables:true, baseColor:neutral. Extend’s shadcn CSS-variable model therefore maps onto Warm Meridian tokens — no fundamental clash at the colour-variable layer, provided vendored Extend source is re-pointed to the bare semantic tokens and never raw Tailwind colours (the project hard rule).
  • Two concrete conflicts to design around:
    1. Icons — Extend ships Hugeicons; in-tree is lucide (components.json iconLibrary:lucide; every component imports lucide-react). Vendored Extend components pull Hugeicons unless re-pointed — an adaptation cost per component.
    2. Primitive duplication — Extend is built on Coss UI (button, tooltip, select, popover, dialog, menu), which directly overlaps the in-tree components/ui/* shadcn set. Adopting Extend wholesale imports a second primitive layer; cherry-picking the document-specific components and re-wiring them to the existing components/ui/* primitives avoids the duplication (at a re-wire cost).

Reconciliation verdict: cherry-pick, don’t adopt wholesale. Take the document viewers / bounding-box / schema-builder that fill genuine gaps; re-theme them to Warm Meridian semantic tokens and re-point Hugeicons → lucide at vendor-in time; keep the in-tree shadcn primitives and react-pdf PDF viewer. This is consistent with ID-117’s own posture (Extend fills the DOCX/XLSX viewer gap; PDF stays on react-pdf).


7. Open questions (owner — Liam, non-dev — must decide before a UI spec-chain)

Section titled “7. Open questions (owner — Liam, non-dev — must decide before a UI spec-chain)”
  1. Cherry-pick vs wholesale (recommended: cherry-pick). Adopt only the Extend document components that fill real gaps (DOCX/Excel/CSV viewers, Bounding Box Citations, Schema Builder), re-themed to Warm Meridian + lucide — or adopt Extend wholesale and accept a duplicate Coss UI primitive layer + Hugeicons? (§6 recommends cherry-pick.)
  2. ID-117 sequencing dependency. Extend’s first real in-tree arrival is the ID-117 {117.4} install slice (register extend-hq/ui, add viewers). Is that slice shipped / scheduled? Any ID-145.19 Extend adoption depends on it — do we sequence ID-147’s UI spec-chain behind ID-117’s install, or does ID-147 own the first registry install itself?
  3. Bounding-box citations (data-model decision). Invest in deriving spatial coordinates from id-58 text-spans (net-new write-path/plumbing) to unlock Extend Bounding Box Citations — or ship text-anchored highlight on react-pdf’s TextLayer, matching the current text-span data shape without Extend? (§5c.)
  4. Streamdown on the item page (DR-040 trigger). New Procurement answer/content surfaces use Streamdown per DR-040 — but do we migrate the incumbent item-detail/content-renderer.tsx (react-markdown) as part of ID-145.19, or leave it to the separate DR-040 backlog sweep?
  5. Schema Builder fit (needs a spike). Does Extend’s generic Schema Builder actually fit the Procurement fillable field structure (BI-20) and/or the Path-C requirement catalogue (BI-24, form_template_requirements), or are these domain-specific enough to warrant a custom editor? Schema Builder is component-only (absent from the blocks inventory), i.e. lower-maturity than the viewers.
  6. Theming adaptation budget. Confirm acceptance of the per-component adaptation cost (re-theme to semantic tokens + Hugeicons → lucide) as the price of cherry-picking Extend, so an Executor is not surprised by it.

8. Empirical / verification block (12/07/2026)

Section titled “8. Empirical / verification block (12/07/2026)”

Per the pre-ratification empirical-verification discipline (external-library claims verified, not accepted from prose). This is a RESEARCH mapping, not an implementation spec citing load-bearing API signatures; the checks here verify adoption facts (in-tree presence, licence, install model), not per-symbol signatures.

ClaimMethodResult
streamdown present in-tree, pinnedpackage.json:123"streamdown": "^2.5.0"PRESENT
Streamdown in live usecomponents/okf/file-render-pane.tsx:37 import { Streamdown } from 'streamdown' + lib/okf/prepare-streamdown-content.ts shimPRESENT / in use
Streamdown licencegithub.com/vercel/streamdown + npmApache-2.0 (not MIT)
Extend UI present in-treegrep @extend/extend-* package.json (empty); no components/ import; components.json has no registries blockABSENT
Extend UI licence + install modelgithub.com/extend-hq/ui; extend.ai/resources/extend-ui-kit; ID-117 RESEARCH §5MIT, shadcn registry (copy-into-source)
id-58 citation shape (bbox vs span)squash_baseline.sql:5459 cited_text text + table COMMENT “span anchoring (D-S330-1)“TEXT-SPAN, no pixel-bbox → Extend bbox BLOCKED
Code-intel orientationgitnexus_query (citation/viewer/bbox) → no spatial-render flow; pipeline text-render + diff + query-keys onlygreenfield for spatial citation UI

No ABSENT/SIGNATURE_DRIFT blocker for the adopted dependency (Streamdown). Extend’s ABSENT status is expected and by design (unshipped registry), not a verification failure — its import-and-call verification belongs to the install slice (ID-117 {117.4} or an ID-147 UI spec-chain), and is called out as OQ-2.


End of RESEARCH — ID-147 {147.1}. Output: specs/id-147-extend-streamdown-ui-foundation/RESEARCH.md. Not committed here. This research recommends the mapping chain proceed as cherry-pick Extend document components (gated on the ID-117 install slice) + Streamdown for streamed/answer markdown per DR-040, with the bounding-box citation data-model gap (§5c / OQ-3) as the decision most likely to reshape scope.