Add Copy Draft, Markdown, and Word export for Gary's AI outputs
From the PR description
Summary
Adds three export actions below every Gary assistant response so U.S. lawyers can move drafts into Word, email, or their own templates in one click:
- Copy Draft - clipboard copy with HTML + Markdown payloads so a paste into Word preserves headings and bullets. Plain‑English status message: "Draft copied. Review before using."
- Download Markdown - saves a
.mdfile with a safe filename likecontract-review-draft-2026-05-19.md, wrapped with a short title block (matter name, Saved Legal Task name, generated date) and an attorney‑review reminder. - Download Word Draft - saves a
.docxvia the already‑installeddocxpackage; preserves headings, paragraphs, bullets, and simple GFM tables; ends with the short footer "Draft generated by Gary for attorney review."
Buttons appear under every non‑streaming assistant message in both the standalone assistant chat and the per‑matter chat. Exports include only the assistant's prose - internal events, tool calls, IDs, and annotations are intentionally excluded. Attorney‑review framing is preserved in every export.
Files changed
frontend/src/lib/exportDraft.ts(new) - pure helpers:sanitizeFilenamePart,buildFilename,buildMarkdownHeader,wrapDraftAsMarkdown,copyDraftToClipboard,downloadDraftAsMarkdown,downloadDraftAsDocx,markdownToBasicHtml. The DOCX path uses a small Markdown → docx converter so we don't pull in extra deps.frontend/src/lib/exportDraft.test.ts(new) - focused tests for filename safety, header content, attorney‑review reminder, no API‑key/internal‑ID leakage, and clipboard failure messaging.frontend/src/app/components/assistant/AssistantMessage.tsx- replaces the icon‑only copy button with the Copy Draft / Download Markdown / Download Word Draft action row plus a polite status line.frontend/src/app/components/assistant/ChatView.tsx- threads optionalmatterNamethrough and derivestaskTitlefrom the preceding user message's workflow.frontend/src/app/(pages)/projects/[id]/assistant/chat/[chatId]/page.tsx- same wiring inside the per‑matter chat, withproject?.nameasmatterName.docs/US_LAWYER_SETUP_GUIDE.md- new "Copying or Downloading Drafts" section explaining each action and the review checklist.docs/US_TERMINOLOGY_MAP.md- added Copy Draft / Download Markdown / Download Word Draft / "Draft for attorney review" entries.
Attorney‑review framing
Every exported draft (Markdown and Word) starts with:
Attorney Review Required: Draft for attorney review. Do not rely on this output without verifying the facts, law, citations, and strategy.
DOCX exports also end with a centered italic footer: "Draft generated by Gary for attorney review."
Tests
bun run frontend/src/lib/exportDraft.test.ts- 11/11 pass. Covers safe filenames, header text, attorney‑review line, no leakage ofsk-,api_key,bearer,document_id,version_id,edit_id,supabase, etc., noWorkflow Templatelegacy wording, and a friendly fallback when clipboard isn't available.bun run frontend/src/app/components/workflows/builtinWorkflows.test.ts- still passes.
Validation
- Backend:
bun run build- clean. - Frontend:
bun run build- TypeScript compilation succeeds (Finished TypeScript in 14.0s). The build then fails during Next.js static prerendering of/account/modelswithError: supabaseUrl is required.- that's the expected codespace failure mode because no Supabase env vars are configured here, and is unrelated to these changes. - Frontend:
bun run lint- same number of errors before and after the change (43); the new files contribute zero new lint errors or warnings.
What was deferred
- A formal template editor - kept the format labels (General Draft, Legal Memo, Demand Letter, Review Checklist, Chronology) as an internal
DraftFormatenum on the helpers, but didn't surface a picker UI yet; the goal was to keep this PR focused. - Saving exports back into the matter as documents - out of scope; lawyers can re‑upload if they want a copy stored.
Test plan
- Run a Saved Legal Task (e.g. Contract Review) on a sample document and confirm the three buttons appear under the response.
- Copy Draft → paste into Word; confirm headings, bullets, bold survive and the attorney‑review reminder is present.
- Download Markdown → confirm filename matches
<matter>-<task>-draft-YYYY-MM-DD.mdand contents include the header block. - Download Word Draft → open in Microsoft Word; confirm the title, attorney‑review reminder, body, and footer note render.
- Try the actions on a chat with no matter (standalone) and confirm the header gracefully omits the Matter line.
- Confirm the failure copy reads sensibly if you simulate clipboard denial in DevTools.
https://claude.ai/code/session_01LNzU9cGoR4SsYXon8H7aJZ
Generated by Claude Code
Our analysis
Add Copy, Markdown, and Word export actions to Gary's assistant responses — read the full analysis →
Think the analysis missed something the PR description covers?
Commits in this PR (2)
| SHA | Subject | Author | Date | |
|---|---|---|---|---|
b4345deb | feat: add Copy Draft, Markdown, and Word export for AI outputs | Claude | 2026-05-19 | ↗ GitHub |
commit bodyAdds three export actions below every Gary assistant response so U.S. lawyers can move drafts into Word, email, or their own templates in one click: - "Copy Draft" - clipboard copy with HTML + Markdown payloads so paste into Word preserves headings and bullets; plain-English status text. - "Download Markdown" - `.md` file with safe filename like `contract-review-draft-2026-05-19.md`, wrapped with a short title block (matter, Saved Legal Task, date) and an attorney-review reminder. - "Download Word Draft" - `.docx` via the already-installed `docx` package; preserves headings, paragraphs, bullets, and simple GFM tables; ends with a short footer note. Helpers live in `frontend/src/lib/exportDraft.ts` and are reused by both the standalone assistant chat and the per-matter chat. Exports include only the assistant's prose - internal events, tool calls, IDs, and annotations are intentionally excluded. Adds focused tests in `exportDraft.test.ts` covering filename safety, header content, attorney-review reminder, no API-key/internal-ID leakage, and clipboard failure messaging. Updates the U.S. lawyer setup guide with a "Copying or Downloading Drafts" section, and extends the terminology map. | ||||
347a4240 | fix: hide export row on very short replies; clarify no-scrub invariant | Claude | 2026-05-19 | ↗ GitHub |
commit body- AssistantMessage: only render Copy Draft / Download Markdown / Download Word Draft when the assistant's prose is at least 200 characters. Tiny conversational replies like "Done." or "I need more information." stay uncluttered. - exportDraft: document explicitly that the wrapper preserves AI content verbatim and never scrubs or redacts. The invariant we guard is the inverse - nothing the wrapper adds should introduce credential-shaped tokens. - exportDraft.test: add a positive test confirming that legitimate legal text discussing "API key" rotation or "Bearer token" authentication is preserved unchanged in the export. | ||||
Capture this PR into my fork
Download a Markdown prompt that tells Claude how to port every
commit in this PR into your working tree. Run it via
claude -p < capture-pull-1.md from
inside the repo you want the changes in.