aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/prototypes/panel-widget-gallery.html34
-rw-r--r--todo.org6
2 files changed, 20 insertions, 20 deletions
diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html
index e64ddd3..007b4cd 100644
--- a/docs/prototypes/panel-widget-gallery.html
+++ b/docs/prototypes/panel-widget-gallery.html
@@ -1079,34 +1079,30 @@ function GVexport(){
if(v!=='off') rows.push(' "'+l.closest('.card').id.slice(5)+'": "'+v+'"');});
return '{\n'+rows.join(',\n')+'\n}';
}
-/* Surface the export as a selected textarea. This deliberately does NOT try to
- reach the clipboard, because on this setup (Chrome 150, native Wayland, no
- clipboard manager) neither clipboard path works from a file:// page:
+/* Hand the export over selected, and let the reader press Ctrl+C themselves.
+ The page deliberately never tries to copy on their behalf, because from a
+ file:// origin neither programmatic path works here (Chrome 150, 2026-07-16):
- navigator.clipboard.writeText rejects NotAllowedError, "Write permission
denied" — a file origin can't hold the clipboard-write permission.
- - document.execCommand('copy') returns TRUE and writes an empty string. The
- clipboard ends up owned, advertising text/plain, serving nothing. Chrome
- sets the PRIMARY selection but not CLIPBOARD; a hand-typed Ctrl+C in the
- page behaves the same way, so it is not specific to execCommand.
- JS can't detect any of this — readText is denied too — so claiming "copied"
- would be a lie the code cannot check. Selecting the text is the one thing
- that reliably works: a selection IS the X/Wayland PRIMARY selection, readable
- with `wl-paste --primary`. Verified twice against the live browser.
- The blur teardown is safe: Chrome keeps serving PRIMARY after the textarea is
- gone (observed — the export read back fine both times, each after switching
- away from the browser, which is what fires the blur). So the selection does
- NOT have to stay on screen to survive; the handler only avoids leaving a
- textarea sitting on the page. What does clobber PRIMARY is selecting text
- anywhere else, which no handler here can prevent. */
+ - execCommand('copy') returns TRUE and writes nothing. Worse than failing,
+ because the return value invites the page to claim success it didn't have.
+ A hand-typed Ctrl+C works fine, so this is specific to a page copying on the
+ user's behalf, NOT a broken clipboard: a Wayland-set clipboard crosses to X11
+ and Emacs reads it correctly (sentinel-verified). Selecting the text is
+ therefore the whole job — the user's own copy is the one that works, and it
+ lands in the real clipboard where every app can reach it.
+ Do NOT "improve" this by reading the X/Wayland PRIMARY selection instead:
+ PRIMARY holds whatever was last selected ANYWHERE, so it silently returns
+ unrelated content (it produced a private SMS while this was being built). */
function gvCopy(btn){
- const flash=m=>{btn.textContent=m;setTimeout(()=>btn.textContent='copy for source',2200);};
+ const flash=m=>{btn.textContent=m;setTimeout(()=>btn.textContent='copy for source',2600);};
const ta=document.createElement('textarea');
ta.value=GVexport();
ta.style.cssText='position:fixed;left:12px;bottom:12px;z-index:70;width:320px;height:170px;'+
'font:12px ui-monospace,monospace;background:#14120f;color:#e8dcc0;border:1px solid #7d5c16;'+
'border-radius:4px;padding:6px';
document.body.appendChild(ta); ta.select();
- flash('selected ▸');
+ flash('press Ctrl+C ▸');
ta.addEventListener('blur',()=>ta.remove());
}
/* index tally: recounts every card lamp; setV calls it on every state change.
diff --git a/todo.org b/todo.org
index 9c779e5..83ed2e6 100644
--- a/todo.org
+++ b/todo.org
@@ -117,7 +117,11 @@ Craig walks all 109 cards; the lamps are his (click cycles off → amber → gre
Runs as a *joint loop* (Craig, 2026-07-16): he walks a batch of 10-15 and reports card numbers + what's wrong; Claude fixes them in one pass, gates on the three probes, he reloads and re-walks. The lamps track progress only — they never recorded *what* was wrong with a card, so the defects live in this task body as they surface.
-Statuses bake into the gallery source (=VSTATUS=, top of the lamp section) *periodically*, not once at completion as originally planned — localStorage is per-profile and dies with a cache clear, so at 8 cards baking is free and at 60 it's the difference between a record and a bad afternoon. Craig clicks "copy for source" under the index tally; Claude reads it off the clipboard (=wl-paste=, or =wl-paste --primary= when the clipboard path is refused) and pastes it into =VSTATUS=. Precedence is localStorage → VSTATUS → off, so the live walk wins on the machine doing it and the baked record fills in on a fresh profile, after a clear, or on velox. Covered by =tests/gallery-probes/probe-vstatus.mjs=.
+Statuses bake into the gallery source (=VSTATUS=, top of the lamp section) *periodically*, not once at completion as originally planned — localStorage is per-profile and dies with a cache clear, so at 8 cards baking is free and at 60 it's the difference between a record and a bad afternoon. Craig clicks "copy for source" under the index tally and pastes the block into the chat; the agent pastes it into =VSTATUS=. Precedence is localStorage → VSTATUS → off, so the live walk wins on the machine doing it and the baked record fills in on a fresh profile, after a clear, or on velox. Covered by =tests/gallery-probes/probe-vstatus.mjs=.
+
+*The page can't copy for you; you press Ctrl+C* (settled 2026-07-16). Clicking "copy for source" drops the export into a selected textarea at the bottom-left of the page. Ctrl+C it and paste it into the chat. From a =file://= origin Chrome refuses both programmatic copy paths — =navigator.clipboard.writeText= rejects NotAllowedError, and =execCommand('copy')= returns *true while writing nothing*, which is worse because the page then claims a success it never had. A hand-typed Ctrl+C works fine, so nothing about the clipboard is broken: a Wayland-set clipboard crosses to X11 and Emacs reads it correctly (sentinel-verified against =gui-get-selection=).
+
+*And the agent doesn't fetch it.* Never read the export with =wl-paste --primary=: PRIMARY holds whatever was last selected anywhere, so a blind read returns unrelated content (it surfaced a private SMS during this session). Craig pastes; the agent doesn't reach for it.
Progress: 8 green + 2 amber (R07, R52) of 109, baked 2026-07-16.
*** 2026-07-16 Thu @ 08:11:18 -0500 Ran the classification brainstorm — two empty cells and a missing axis