feat: Add copy-to-clipboard for AI markdown export - #2
Conversation
- Adds a Copy button next to AI Snapshot for quick paste into LLM chats - Reuses existing export worker/blob pipeline, just swaps download for clipboard write - Fixes a duplicate setExportButtonsState definition that was silently overriding button state logic
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Deployment failed with the following error: Learn More: https://vercel.com/docs/concepts/projects/project-configuration |
|
@fezan-dot is attempting to deploy a commit to the vinaypatel22's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Thanks for the PR. Could you please share screenshots or a short screen recording demonstrating the changes? I'd like to verify both the UI and the functionality before reviewing the code. |
code-snapshot-pr.mp4Here's a quick demo:
|
vinay-patel22
left a comment
There was a problem hiding this comment.
Issues Found - Blocking Review
1. Duplicate setExportButtonsState Method Definition
Looking at the diff in js/export-manager.js, the original setExportButtonsState method is moved but not consolidated. The final code contains two definitions of the same method:
// First definition: lines ~172-189 (inside copyToClipboard's scope)
setExportButtonsState(disabled) {
const hasExportFiles = this.filterManager.getExportFiles().length > 0;
// ... implementation
// Second definition: lines ~245-268 (moved to end, now deleted in diff)
// This one gets silently overriddenIssue: JavaScript silently uses the last-defined method. Only one works; the other is dead code. The PR description says this "fixed" a duplicate, but the diff shows it was moved, not removed.
Ask: Can you clarify what happened? Did you intend to remove one of these, or consolidate them? Please show both final definitions side-by-side so we can verify only one remains.
2. Missing Null-Safety on Blob Conversion
In copyToClipboard():
const text = await blob.text();
await navigator.clipboard.writeText(text);If blob.text() fails or returns null/undefined, navigator.clipboard.writeText(null) will silently fail or throw an uncaught error.
Suggestion:
const text = await blob.text();
if (!text) {
throw new Error("Failed to export content");
}
await navigator.clipboard.writeText(text);3. Inconsistent Timeout Delays
- Original
startExport()re-enables buttons after 1000ms:setTimeout(() => {...}, 1000) - New
copyToClipboard()re-enables buttons after 500ms:setTimeout(() => {...}, 500)
Why the difference? This should either:
- Use the same constant (preferred)
- Include a comment explaining why clipboard is faster
4. Unrelated Change to vercel.json
The PR removes "public": true from vercel.json. Since this is a privacy-focused tool, this change deserves explanation in the PR description. Is this intentional? If so, document the reason.
- Add null-safety check on blob.text() in copyToClipboard - Consolidate button re-enable delay into shared UI_CONSTANTS.BUTTON_REENABLE_DELAY_MS - Remove stray comment - Keep vercel.json public property removed
|
Thanks for the detailed review — addressed everything:
Also, re: the current failing Vercel check — that's now a different issue |
vinay-patel22
left a comment
There was a problem hiding this comment.
Please revert the changes made to vercel.json
|
Hi, I reverted the changes made to vercel.json you can check |
What
Adds a "Copy to Clipboard" button next to the AI Snapshot export, so the
markdown handoff can go straight into an LLM chat without a download → open → copy round trip.
Why
The AI export already targets LLM tools (per the README's ai-handoff focus),
but currently the only output is a file download. Copy-to-clipboard removes
a step for the most common use case.
Changes
js/export-manager.js: newcopyToClipboard(type)method, reuses theexisting
startExportWorkerpipeline and just writes the result to theclipboard instead of triggering a download
js/event-handlers.js: wires the new button's click eventindex.html: adds the Copy button next to AI SnapshotsetExportButtonsStatemethod definition that wassilently overriding the version handling the new button's disabled state
Testing
Tested locally via
npx serve ., in Chrome and Firefox: