Skip to content

feat(extension): Download All Conversations — enumerate + walk + progress UI (Closes #54, #60, #63)#200

Merged
martymcenroe merged 3 commits into
mainfrom
feat/batch-download-walk
Jul 9, 2026
Merged

feat(extension): Download All Conversations — enumerate + walk + progress UI (Closes #54, #60, #63)#200
martymcenroe merged 3 commits into
mainfrom
feat/batch-download-walk

Conversation

@martymcenroe

Copy link
Copy Markdown
Owner

What

Adds the end-to-end Download All Conversations walk to the existing Clio extension — no API, it reuses the DOM extractor so it captures rendered artifacts the site API cannot.

Builds on the ledger DB (already on main). The batch worker reuses the existing extractor unmodified.

Tests

fake-indexeddb + jsdom. Worker + seedQueue (8), enumeration against real captured DOM (17), storage (10). Full suite: 319 passing.

Verification

Load unpacked and click Download All on claude.ai; browser-side timing/enumeration tuning to follow as a fast-follow.

Closes #54
Closes #60
Closes #63

martymcenroe and others added 3 commits July 9, 2026 09:09
…ract, zip, download (part of #60)

extensions/src/archive.js: the walk. runBatch() drains the ledger queue one
conversation at a time; processOne() navigates a worker tab to the conversation,
runs Clio's EXISTING content.js extractor (the same {action:'extract'} the single
button uses — a rendered-DOM extraction that captures artifacts the site API
cannot), builds the current-design ZIP (conversation.json + images/), downloads
it, and records success/failure in the ledger. Fail-open per conversation;
pause/cancel via a control object; resume-safe (idempotent queue).

Loop + step take injected deps so the logic is unit-tested (7 tests) with the
browser glue mocked. UI wiring, SW orchestration, and enumeration follow.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…table (part of #54)

extensions/src/enumerate.js: collectConversations() reads every conversation row
from the live DOM (deduped, per-site); enumerateAll() scrolls the list until it
stops growing — the list lazy-loads more from the server as you reach the bottom,
so it keeps scrolling until the count is stable across several settle cycles.
Pure DOM, no API. Handles Claude (both data-row-key buttons and /chat/ anchors)
and Gemini; ChatGPT pending its list DOM.

collectConversations() unit-tested against the real captured sidebar DOM: 32
Claude + 53 Gemini conversations, correct ids/urls/titles.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…o-end (part of #60, #63)

Adds the clickable batch-download to the existing extension:
- popup.html/js: a 'Download All Conversations' button that opens the archive
  page for the current site.
- archive.html + archive-page.js: a persistent progress page that opens a
  background worker tab, enumerates the full list in it (enumerate.js via
  chrome.scripting), seeds the ledger queue, then runs the worker (archive.js)
  which drives the same tab through each conversation — live progress with
  pause / resume / cancel.
- archive.js: worker hardened for real tabs (re-inject content script if a
  navigation dropped it) + seedQueue(); reuses content.js's existing extractor,
  createZip, and chrome.downloads.
- manifest: version 1.4.1 -> 1.5.0. No new permissions (scripting + host cover
  the worker-tab driving).

319 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

@cerberus-az cerberus-az Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved: all required checks passed. 🤖

@martymcenroe
martymcenroe merged commit 4d3b029 into main Jul 9, 2026
2 checks passed
@martymcenroe
martymcenroe deleted the feat/batch-download-walk branch July 9, 2026 22:01
martymcenroe added a commit that referenced this pull request Jul 9, 2026
…e button label (#203)

First browser run of Download-All (#200) surfaced three bugs, diagnosed from the
extension's own run report:

- Enumeration returned only ~33 (Claude's sidebar caps at recent conversations),
  not the full archive. Now reads the complete conversation index (enumerateFull)
  so every conversation is walked; content is still DOM-extracted per conversation.
- 10/33 'Missing selectors: messages' failures were a fixed-1.5s wait firing
  before the conversation rendered. navigateAndExtract now retries with growing
  delays until messages render (empty conversations still surface after retries).
- The Pause button rendered blank — the button CSS set background but no text
  color, so the label used the UA default. Added an explicit color.

Manifest 1.5.1 -> 1.5.2. Per-conversation streaming downloads retained (bounded
memory; no giant in-memory ZIP). 319 tests pass.

No-Issue: same-session fixes from the first browser test of the #200 walk

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant