Skip to content

feat: scaffold browser extension with shared types and formatters#1

Open
ai-diffusion wants to merge 20 commits into
mainfrom
claude/browser-extension-chat-exporter-y1OJR
Open

feat: scaffold browser extension with shared types and formatters#1
ai-diffusion wants to merge 20 commits into
mainfrom
claude/browser-extension-chat-exporter-y1OJR

Conversation

@ai-diffusion

Copy link
Copy Markdown
Owner

Adds artifacts/browser-extension/src/lib/ with the foundational
types (Message, Conversation, Format) and pure format converters
(Markdown, Plain Text, JSON, HTML) for the AI Chat Exporter extension.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3

claude and others added 20 commits May 6, 2026 13:02
Adds artifacts/browser-extension/src/lib/ with the foundational
types (Message, Conversation, Format) and pure format converters
(Markdown, Plain Text, JSON, HTML) for the AI Chat Exporter extension.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Adds DOM extractors for ChatGPT, Claude, Grok, Gemini, and Perplexity.
Each script listens for EXTRACT_CONVERSATION messages and returns a
structured Conversation object from the live page DOM.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Dark-themed popup with conversation preview, format selector,
and Download/Copy buttons. Handles unsupported pages and empty
conversations gracefully.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Adds package.json, tsconfig.json, build.mjs (esbuild), manifest.json
(MV3, Chrome + Firefox), and a minimal service worker. Build outputs
to dist/ via `npm run build`; `npm run pack` produces extension.zip.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Covers Chrome Web Store, Firefox AMO, Zen Browser, and sideloading
in Chrome/Brave/Edge/Firefox, plus a pre-publish testing checklist.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Indigo chat bubble with white download arrow, matching the
design from the ChatGPT-generated reference image. All three
sizes generated programmatically for consistent rendering.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Ready-to-sideload dist/ folder and ready-to-upload extension.zip
for Chrome Web Store and Firefox AMO submissions.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
…tructure

- Add htmlToMarkdown() recursive walker: converts h1-h4, bold, italic,
  code blocks, lists, links to Markdown — preserves formatting instead
  of flat innerText
- Two-tier selector fallback: article[data-testid^="conversation-turn-"]
  (2024-2025 DOM) then [data-message-author-role] (any build)
- Drill into .prose/.markdown child for accurate content extraction,
  skipping copy/regenerate buttons and SVG icons
- Detect pasted attachments (pre, [class*="attachment"], etc.) inside
  user turns and append them with --- separator
- Filter non-user/assistant roles (tool, system) to keep output clean

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
…forms

- src/lib/capture.ts: shared engine — autoScrollToTop loads the entire
  lazy-loaded history before extraction (stability detection, 60-iteration
  cap, truncated flag, virtualization contingency via window merging);
  collectAssets registers images/file links; GET_ASSET serves them to the
  popup (canvas re-encode for blob: images, credentialed fetch fallback)
- src/lib/dom-to-markdown.ts: HTML→Markdown walker shared by all platforms
  (was ChatGPT-only) with onImage hook for inline asset markers
- Content scripts reduced to per-platform configs: selector tiers, role
  detection, prose selectors — Claude/Gemini/Grok/Perplexity now get full
  markdown structure and full-history capture, not flat innerText
- ChatGPT: pasted-text chips probed for hidden full text; honest
  [Attached: …] placeholder when content isn't in the page
- Popup: live "Loading full conversation… (N messages)" progress, 90s
  watchdog, "Include images & files" checkbox, sequential asset downloads
  into chat-export-<title>/ subfolder via downloads API
- Manifest: cover codex.openai.com

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Firefox does not support background.service_worker alone in MV3 —
adding background.scripts alongside it so the extension loads in
both Chrome and Firefox/Zen without error.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Updates manifest.json, popup title/header, and package.json name
from old placeholder 'AI Chat Exporter' to the agreed name.
Also improves manifest description.

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
…Obsidian button

- Filename format: YYYY-MM-DD Platform Model Chat-Title.md
  (e.g. '2026-06-11 ChatGPT GPT-4o My Conversation.md')
- YAML frontmatter in all markdown exports: title, date, time,
  platform, model, url, messages count, tags — Obsidian reads this
  as note properties automatically
- Model detection added to all 5 platforms via modelOf() — scrapes
  the model selector button, falls back to page title
- 'Save to Obsidian' button: opens obsidian://new?file=...&content=...
  to create the note directly in the running vault; falls back to
  .md download for very large chats (>50k chars)
- Conversation type gains optional model field
- Plain text and HTML exports also include model name in metadata

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
- computeStats() calculates totalWords, totalChars, estimatedTokens
  (chars/4 — ~10-15% accuracy vs real tokenizer), userMessages count,
  assistantMessages count from conversation content
- YAML frontmatter: words, characters, estimated_tokens, user_messages,
  ai_messages fields added — all searchable/filterable in Obsidian
- Markdown body: 'Words: N | Est. tokens: N | Characters: N' line
- Plain text: same stats line in header
- HTML: stats in the meta bar alongside platform and model
- Zip confirmed self-contained: 17 files, no runtime dependencies

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Filename: YYYY-MM-DD — Platform — Title — exported D Month YYYY, H.MMam [N msgs ~Ntk]
Markdown structure:
  - ## File info (source, exported date)
  - ## Size (messages, words, chars, estimated tokens)
  - ## Cost / context-fit table (8 models, context %, input cost, output rate)
  - ## You · N · [preview] / ## Platform · N · [preview] numbered headings
    → Obsidian outlines the full conversation with exchange numbers on right panel
  - Exchange counter increments on each user turn so AI·N matches You·N
Platform name used as AI speaker (ChatGPT/Grok/Claude) not generic 'AI'
Friendly dates: 'Thursday, 11 June 2026, 4.39pm'
Cost table prices verified June 2026; note subscription plans = $0/chat
JSON export includes computed stats block
HTML export includes cost table and exchange-numbered message labels

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
- dom-to-markdown.ts: add full <table>/<tr>/<th>/<td> → markdown pipe
  table support; separator row inserted after header row (or first row
  if all <td>); escapes pipes inside cell content

- popup.ts: rename assets after extraction to match chat filename
  format (YYYY-MM-DD — Platform — Title — exported … — image-N.ext);
  rewrites embedded image refs in message content to use flat filenames;
  switches text-file download to chrome.downloads.download() so the
  chat .md and all images land in the same directory

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
capture.ts: add extractFileAssets async hook to PlatformConfig; call it
per-turn in captureConversation() after regular asset collection, counting
user turns so each file gets a prompt-N label.

chatgpt.ts: implement extractFileAssets — finds file/document chips in
user turns, tries DOM hidden text first (Tier A), then clicks the chip,
waits up to 2.5s for ChatGPT's viewer modal, extracts content from the
pre/code element, closes the modal, and registers the text as a Blob
URL Asset. Companion files are named "prompt-N — Pasted text(1).txt"
which popup.ts prefixes with the chat filename so the final download is
"2026-06-11 — ChatGPT — … — prompt-1 — Pasted text(1).txt".

Also update the [Attached: …] placeholder to [File: name] (neutral,
since the content is now in the downloaded companion file).

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
The extractFileAssets hook added to PlatformConfig is now included in
all bundled IIFE content scripts (claude, gemini, grok, perplexity).

https://claude.ai/code/session_0138YhQCbBxY5KowePhCK1y3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants