generated from coulomb/repo-seed
Per-evidence-item export: click Export → Copy as Markdown / Copy as HTML writes a portable citation card to the clipboard. Cmd/Ctrl+Shift+C exports the active evidence as Markdown. - ADR-0007 locks the Markdown + HTML output formats. - New shared types: CitationCard, openContextUrl(), resolveSourceLabel(). - Engine renderers under src/engine/rendering/: renderCitationCardMarkdown, renderCitationCardHtml — snapshot-tested, escape-safe, BEM classes for HTML. - src/work/useExportEvidence.ts wires engine + renderers + clipboard. - EvidenceSidebar gains an Export popover per row + auto-dismissing toast. - E2E test (tests/integration/citation-card-export-e2e.dom.test.tsx) walks PRD scenario steps 10-11 and asserts the clipboard payload. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
173 lines
4.6 KiB
Markdown
173 lines
4.6 KiB
Markdown
---
|
|
id: CE-WP-0004
|
|
type: workplan
|
|
title: "Citation card export — Markdown and HTML renderers, sidebar export"
|
|
domain: citation_evidence
|
|
repo: citation-evidence
|
|
repo_id: a677c189-b4e2-4f2a-9e48-faa482c277e6
|
|
topic_slug: citation_evidence_mvp
|
|
topic_id: 96fa8e80-9f74-40f2-84cd-644e9747b9ec
|
|
state_hub_workstream_id: 539919a4-f876-42b7-a28c-1a754c333139
|
|
status: done
|
|
owner: Bernd
|
|
created: 2026-05-24
|
|
updated: 2026-05-25
|
|
depends_on_workplan: CE-WP-0002
|
|
spec_refs:
|
|
- wiki/ProductRequirementsDocument.md
|
|
- wiki/ArchitectureOverview.md
|
|
- wiki/SharedContracts.md
|
|
---
|
|
|
|
# CE-WP-0004 — Citation Card Export
|
|
|
|
The final step of the MVP scenario: turn an evidence item into a portable
|
|
Markdown or HTML citation card.
|
|
|
|
After this workplan, a user can:
|
|
|
|
1. Click "Export" on an evidence item in the sidebar.
|
|
2. Choose Markdown or HTML.
|
|
3. Get a clipboard-ready citation card with quote, source label,
|
|
commentary, and a link back to source context.
|
|
|
|
This workplan can run in parallel with CE-WP-0003 once CE-WP-0002 is done —
|
|
it touches different code paths.
|
|
|
|
## Dependency Order
|
|
|
|
```
|
|
T01 (CitationCard type + open-context URL convention)
|
|
└─ T02 (Markdown renderer)
|
|
└─ T03 (HTML renderer)
|
|
└─ T04 (sidebar Export button + copy-to-clipboard)
|
|
└─ T05 (E2E test of PRD scenario step 10)
|
|
```
|
|
|
|
---
|
|
|
|
## T01 — `CitationCard` type + open-context URL convention
|
|
|
|
```task
|
|
id: CE-WP-0004-T01
|
|
state_hub_task_id: c15369da-0c42-4b5b-9d8c-cb91b316850f
|
|
priority: high
|
|
status: done
|
|
```
|
|
|
|
Under `src/shared/`:
|
|
|
|
- `src/shared/citation-card.ts` — `CitationCard` per Architecture §4.7
|
|
- `src/shared/open-context-url.ts` — function `openContextUrl(annotationId)`
|
|
returning a URL of the form
|
|
`/viewer?document=<docId>&annotation=<annId>` (per Architecture §14.3)
|
|
|
|
The URL is the deep link that an exported card uses to reopen the source
|
|
context in this MVP. When persistence becomes real (post-MVP), the URL
|
|
scheme stays the same.
|
|
|
|
---
|
|
|
|
## T02 — Markdown citation card renderer
|
|
|
|
```task
|
|
id: CE-WP-0004-T02
|
|
state_hub_task_id: 4f94d27e-3727-4ad3-8f42-b0bb7ca74cb7
|
|
priority: high
|
|
status: done
|
|
depends_on: [T01]
|
|
```
|
|
|
|
Under `src/engine/rendering/`:
|
|
|
|
- `markdown.ts` — `renderCitationCardMarkdown(evidenceItem, document, annotation): string`
|
|
|
|
Output format (lock this in `docs/decisions/ADR-0007-citation-card-format.md`):
|
|
|
|
```markdown
|
|
> {quote}
|
|
|
|
— *{sourceLabel}* · [Open source]({openContextUrl})
|
|
|
|
{commentary}
|
|
```
|
|
|
|
Where `sourceLabel` is `document.title` if present, else the filename, else
|
|
the document URI.
|
|
|
|
Unit tests: snapshot a few rendered cards against fixtures.
|
|
|
|
---
|
|
|
|
## T03 — HTML citation card renderer
|
|
|
|
```task
|
|
id: CE-WP-0004-T03
|
|
state_hub_task_id: 40c1aa86-64a1-4216-9e33-29fddf9c4d62
|
|
priority: high
|
|
status: done
|
|
depends_on: [T01]
|
|
```
|
|
|
|
Under `src/engine/rendering/`:
|
|
|
|
- `html.ts` — `renderCitationCardHtml(evidenceItem, document, annotation): string`
|
|
|
|
Output: a single `<aside class="citation-card">` element with `<blockquote>`,
|
|
`<cite>`, `<a>` (open context), and `<div class="commentary">`. Inline
|
|
styles avoided — host page provides CSS. Sanitize commentary as plain text
|
|
(no raw HTML pass-through).
|
|
|
|
Web component `<citation-card>` from Architecture §14.2 is *not* in scope
|
|
here — it ships in a later workplan.
|
|
|
|
---
|
|
|
|
## T04 — Sidebar Export button + copy-to-clipboard
|
|
|
|
```task
|
|
id: CE-WP-0004-T04
|
|
state_hub_task_id: 0fa3c7e4-6868-4010-ade4-99a921ab0578
|
|
priority: medium
|
|
status: done
|
|
depends_on: [T02, T03]
|
|
```
|
|
|
|
Add to `src/work/EvidenceSidebar.tsx`:
|
|
|
|
- Per evidence item: an "Export" affordance (icon button or menu)
|
|
- On click: small popover with two buttons, "Copy as Markdown" and
|
|
"Copy as HTML"
|
|
- On click: render via T02/T03 and write to clipboard with the standard
|
|
`navigator.clipboard` API; show a transient confirmation toast
|
|
|
|
Keyboard shortcut `Cmd/Ctrl+Shift+C` exports the active evidence item as
|
|
Markdown (the most common action).
|
|
|
|
---
|
|
|
|
## T05 — E2E test of PRD scenario step 10
|
|
|
|
```task
|
|
id: CE-WP-0004-T05
|
|
state_hub_task_id: 8d1993b3-21a8-4be9-9ab1-29aa97e8301c
|
|
priority: medium
|
|
status: done
|
|
depends_on: [T04]
|
|
```
|
|
|
|
Extend the Playwright E2E:
|
|
|
|
10. After the earlier steps, click Export → Copy as Markdown on the saved
|
|
evidence item.
|
|
11. Read the clipboard; assert it contains the quote text, the document
|
|
title, the commentary, and a URL matching the
|
|
`/viewer?document=...&annotation=...` shape.
|
|
|
|
If this passes, MVP scenario steps 1-10 are all green and the
|
|
umbrella-first MVP is *done* for the first reference scenario from PRD §20.
|
|
|
|
The next workplan (post-MVP) would be `CE-WP-0005` to either extract the
|
|
first stable subsystem (likely `citation-engine`) into its own repo or to
|
|
add Markdown/HTML document support.
|