feat(web): copy the terminal selection with ctrl+c - #26

Merged
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut
Aug 14, 2026
Merged

feat(web): copy the terminal selection with ctrl+c#26
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut

Conversation

@rynfar

@rynfarrynfar commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Adopts upstream #5638. On non-mac, copying a terminal selection required Ctrl+Shift+C; plain Ctrl+C now copies too.

The interesting part: this does not break interrupt

Ctrl+C in a terminal is normally SIGINT, so rebinding it to copy is the kind of change that can quietly ruin your ability to stop a runaway process. I read this one specifically to check, and it's handled:

  • No selection → nothing intercepts. The copy path is gated on isTerminalCopyShortcut(event) && this.hasSelection(), so with nothing selected Ctrl+C falls straight through to the shell as SIGINT.
  • With a selection, one press copies and then clears the selection, so the nextCtrl+C reaches the shell. clearSelectionAfterCopy is set only for the plain non-mac chord.
  • Cmd+C and Ctrl+Shift+C stay copy-only and keep the selection, since neither is SIGINT.

The tradeoff is real and worth stating: with text selected, the first Ctrl+C copies instead of interrupting. The auto-clear keeps that to a single press.

The rest is browser-compatibility plumbing: plain Ctrl+C isn't preventDefaulted so the native copy event still fires, with a token-guarded deferred clipboard.writeText racing it for WebKit, which omits the keyboard copy event when there's no DOM selection. Ctrl+Shift+C has no native event at all (Chrome binds it to inspect), so that branch synthesises one via execCommand("copy"). There's also a contextMenuFallback path and one new IPC contract member.

Verification

  • vp test run over the 3 touched test files: 47 passed.
  • Typecheck on @t3tools/web and @t3tools/contracts: no errors.
  • vp lint on the changed files: clean.

Clean cherry-pick, no Pylon adaptation needed.

No browser pass. Clipboard behaviour differs across engines and this change leans on those differences deliberately — the WebKit race in particular is the sort of thing unit tests can't settle. Worth a real pass in Chrome and Safari before trusting it fully; say the word and I'll run one.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…#5638)
(cherry picked from commit 1add47b322ab1dfb5010bb363613650176b88088)
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for cd3b7cb.

This comment will update automatically after the next completed run.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Browser pass attempted — the change is not verifiable on this host

Ran the app on this branch against seeded data, opened the terminal drawer (ghostty canvas and Terminal input both mount fine with the change in place), and tried to exercise the copy gesture. Two findings, the second decisive:

1. Synthetic key events cannot drive this code path. The implementation deliberately relies on the browser's nativecopy event, and on the transient user activation that clipboard.writeText requires. Neither a synthetic KeyboardEvent nor a CDP-level key press produced a copy event that a document-level observer could see.

2. More fundamentally: this host is macOS, so the changed line never executes.navigator.platform is MacIntel, so isTerminalCopyShortcut takes the isMacPlatform branch and checks event.metaKey. The entire behavioural diff is on the other branch — event.ctrlKey && event.shiftKey becoming event.ctrlKey. A macOS browser cannot reach it regardless of clipboard mechanics.

So the honest position: verifying this needs a Windows or Linux browser. What the pass does establish is narrower but not worthless — the terminal surface still mounts and initialises correctly with the new copy listener attached, so there's no regression in setup, and the mac path is untouched by the diff.

The reasoning behind the change still reads correctly on inspection: the copy path is gated on hasSelection() so an empty selection falls through as SIGINT, and clearSelectionAfterCopy is set only for the plain non-mac chord so the next press interrupts. That is inspection, not execution.

@rynfar
rynfar merged commit f630ab0 into pylonAug 14, 2026
11 checks passed
@rynfar
rynfar deleted the feat/terminal-copy-shortcut branch August 14, 2026 19:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@UtkarshUsername
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(web): copy the terminal selection with ctrl+c - #26

Merged
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut
Aug 14, 2026
Merged

feat(web): copy the terminal selection with ctrl+c#26
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut

Conversation

@rynfar

@rynfarrynfar commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Adopts upstream #5638. On non-mac, copying a terminal selection required Ctrl+Shift+C; plain Ctrl+C now copies too.

The interesting part: this does not break interrupt

Ctrl+C in a terminal is normally SIGINT, so rebinding it to copy is the kind of change that can quietly ruin your ability to stop a runaway process. I read this one specifically to check, and it's handled:

  • No selection → nothing intercepts. The copy path is gated on isTerminalCopyShortcut(event) && this.hasSelection(), so with nothing selected Ctrl+C falls straight through to the shell as SIGINT.
  • With a selection, one press copies and then clears the selection, so the nextCtrl+C reaches the shell. clearSelectionAfterCopy is set only for the plain non-mac chord.
  • Cmd+C and Ctrl+Shift+C stay copy-only and keep the selection, since neither is SIGINT.

The tradeoff is real and worth stating: with text selected, the first Ctrl+C copies instead of interrupting. The auto-clear keeps that to a single press.

The rest is browser-compatibility plumbing: plain Ctrl+C isn't preventDefaulted so the native copy event still fires, with a token-guarded deferred clipboard.writeText racing it for WebKit, which omits the keyboard copy event when there's no DOM selection. Ctrl+Shift+C has no native event at all (Chrome binds it to inspect), so that branch synthesises one via execCommand("copy"). There's also a contextMenuFallback path and one new IPC contract member.

Verification

  • vp test run over the 3 touched test files: 47 passed.
  • Typecheck on @t3tools/web and @t3tools/contracts: no errors.
  • vp lint on the changed files: clean.

Clean cherry-pick, no Pylon adaptation needed.

No browser pass. Clipboard behaviour differs across engines and this change leans on those differences deliberately — the WebKit race in particular is the sort of thing unit tests can't settle. Worth a real pass in Chrome and Safari before trusting it fully; say the word and I'll run one.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…#5638)
(cherry picked from commit 1add47b322ab1dfb5010bb363613650176b88088)
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for cd3b7cb.

This comment will update automatically after the next completed run.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Browser pass attempted — the change is not verifiable on this host

Ran the app on this branch against seeded data, opened the terminal drawer (ghostty canvas and Terminal input both mount fine with the change in place), and tried to exercise the copy gesture. Two findings, the second decisive:

1. Synthetic key events cannot drive this code path. The implementation deliberately relies on the browser's nativecopy event, and on the transient user activation that clipboard.writeText requires. Neither a synthetic KeyboardEvent nor a CDP-level key press produced a copy event that a document-level observer could see.

2. More fundamentally: this host is macOS, so the changed line never executes.navigator.platform is MacIntel, so isTerminalCopyShortcut takes the isMacPlatform branch and checks event.metaKey. The entire behavioural diff is on the other branch — event.ctrlKey && event.shiftKey becoming event.ctrlKey. A macOS browser cannot reach it regardless of clipboard mechanics.

So the honest position: verifying this needs a Windows or Linux browser. What the pass does establish is narrower but not worthless — the terminal surface still mounts and initialises correctly with the new copy listener attached, so there's no regression in setup, and the mac path is untouched by the diff.

The reasoning behind the change still reads correctly on inspection: the copy path is gated on hasSelection() so an empty selection falls through as SIGINT, and clearSelectionAfterCopy is set only for the plain non-mac chord so the next press interrupts. That is inspection, not execution.

@rynfar
rynfar merged commit f630ab0 into pylonAug 14, 2026
11 checks passed
@rynfar
rynfar deleted the feat/terminal-copy-shortcut branch August 14, 2026 19:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@UtkarshUsername
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): copy the terminal selection with ctrl+c - #26

Merged
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut
Aug 14, 2026
Merged

feat(web): copy the terminal selection with ctrl+c#26
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut

Conversation

@rynfar

@rynfarrynfar commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Adopts upstream #5638. On non-mac, copying a terminal selection required Ctrl+Shift+C; plain Ctrl+C now copies too.

The interesting part: this does not break interrupt

Ctrl+C in a terminal is normally SIGINT, so rebinding it to copy is the kind of change that can quietly ruin your ability to stop a runaway process. I read this one specifically to check, and it's handled:

  • No selection → nothing intercepts. The copy path is gated on isTerminalCopyShortcut(event) && this.hasSelection(), so with nothing selected Ctrl+C falls straight through to the shell as SIGINT.
  • With a selection, one press copies and then clears the selection, so the nextCtrl+C reaches the shell. clearSelectionAfterCopy is set only for the plain non-mac chord.
  • Cmd+C and Ctrl+Shift+C stay copy-only and keep the selection, since neither is SIGINT.

The tradeoff is real and worth stating: with text selected, the first Ctrl+C copies instead of interrupting. The auto-clear keeps that to a single press.

The rest is browser-compatibility plumbing: plain Ctrl+C isn't preventDefaulted so the native copy event still fires, with a token-guarded deferred clipboard.writeText racing it for WebKit, which omits the keyboard copy event when there's no DOM selection. Ctrl+Shift+C has no native event at all (Chrome binds it to inspect), so that branch synthesises one via execCommand("copy"). There's also a contextMenuFallback path and one new IPC contract member.

Verification

  • vp test run over the 3 touched test files: 47 passed.
  • Typecheck on @t3tools/web and @t3tools/contracts: no errors.
  • vp lint on the changed files: clean.

Clean cherry-pick, no Pylon adaptation needed.

No browser pass. Clipboard behaviour differs across engines and this change leans on those differences deliberately — the WebKit race in particular is the sort of thing unit tests can't settle. Worth a real pass in Chrome and Safari before trusting it fully; say the word and I'll run one.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…#5638)
(cherry picked from commit 1add47b322ab1dfb5010bb363613650176b88088)
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for cd3b7cb.

This comment will update automatically after the next completed run.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Browser pass attempted — the change is not verifiable on this host

Ran the app on this branch against seeded data, opened the terminal drawer (ghostty canvas and Terminal input both mount fine with the change in place), and tried to exercise the copy gesture. Two findings, the second decisive:

1. Synthetic key events cannot drive this code path. The implementation deliberately relies on the browser's nativecopy event, and on the transient user activation that clipboard.writeText requires. Neither a synthetic KeyboardEvent nor a CDP-level key press produced a copy event that a document-level observer could see.

2. More fundamentally: this host is macOS, so the changed line never executes.navigator.platform is MacIntel, so isTerminalCopyShortcut takes the isMacPlatform branch and checks event.metaKey. The entire behavioural diff is on the other branch — event.ctrlKey && event.shiftKey becoming event.ctrlKey. A macOS browser cannot reach it regardless of clipboard mechanics.

So the honest position: verifying this needs a Windows or Linux browser. What the pass does establish is narrower but not worthless — the terminal surface still mounts and initialises correctly with the new copy listener attached, so there's no regression in setup, and the mac path is untouched by the diff.

The reasoning behind the change still reads correctly on inspection: the copy path is gated on hasSelection() so an empty selection falls through as SIGINT, and clearSelectionAfterCopy is set only for the plain non-mac chord so the next press interrupts. That is inspection, not execution.

@rynfar
rynfar merged commit f630ab0 into pylonAug 14, 2026
11 checks passed
@rynfar
rynfar deleted the feat/terminal-copy-shortcut branch August 14, 2026 19:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@UtkarshUsername
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): copy the terminal selection with ctrl+c - #26

Merged
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut
Aug 14, 2026
Merged

feat(web): copy the terminal selection with ctrl+c#26
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut

Conversation

@rynfar

@rynfarrynfar commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Adopts upstream #5638. On non-mac, copying a terminal selection required Ctrl+Shift+C; plain Ctrl+C now copies too.

The interesting part: this does not break interrupt

Ctrl+C in a terminal is normally SIGINT, so rebinding it to copy is the kind of change that can quietly ruin your ability to stop a runaway process. I read this one specifically to check, and it's handled:

  • No selection → nothing intercepts. The copy path is gated on isTerminalCopyShortcut(event) && this.hasSelection(), so with nothing selected Ctrl+C falls straight through to the shell as SIGINT.
  • With a selection, one press copies and then clears the selection, so the nextCtrl+C reaches the shell. clearSelectionAfterCopy is set only for the plain non-mac chord.
  • Cmd+C and Ctrl+Shift+C stay copy-only and keep the selection, since neither is SIGINT.

The tradeoff is real and worth stating: with text selected, the first Ctrl+C copies instead of interrupting. The auto-clear keeps that to a single press.

The rest is browser-compatibility plumbing: plain Ctrl+C isn't preventDefaulted so the native copy event still fires, with a token-guarded deferred clipboard.writeText racing it for WebKit, which omits the keyboard copy event when there's no DOM selection. Ctrl+Shift+C has no native event at all (Chrome binds it to inspect), so that branch synthesises one via execCommand("copy"). There's also a contextMenuFallback path and one new IPC contract member.

Verification

  • vp test run over the 3 touched test files: 47 passed.
  • Typecheck on @t3tools/web and @t3tools/contracts: no errors.
  • vp lint on the changed files: clean.

Clean cherry-pick, no Pylon adaptation needed.

No browser pass. Clipboard behaviour differs across engines and this change leans on those differences deliberately — the WebKit race in particular is the sort of thing unit tests can't settle. Worth a real pass in Chrome and Safari before trusting it fully; say the word and I'll run one.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…#5638)
(cherry picked from commit 1add47b322ab1dfb5010bb363613650176b88088)
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for cd3b7cb.

This comment will update automatically after the next completed run.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Browser pass attempted — the change is not verifiable on this host

Ran the app on this branch against seeded data, opened the terminal drawer (ghostty canvas and Terminal input both mount fine with the change in place), and tried to exercise the copy gesture. Two findings, the second decisive:

1. Synthetic key events cannot drive this code path. The implementation deliberately relies on the browser's nativecopy event, and on the transient user activation that clipboard.writeText requires. Neither a synthetic KeyboardEvent nor a CDP-level key press produced a copy event that a document-level observer could see.

2. More fundamentally: this host is macOS, so the changed line never executes.navigator.platform is MacIntel, so isTerminalCopyShortcut takes the isMacPlatform branch and checks event.metaKey. The entire behavioural diff is on the other branch — event.ctrlKey && event.shiftKey becoming event.ctrlKey. A macOS browser cannot reach it regardless of clipboard mechanics.

So the honest position: verifying this needs a Windows or Linux browser. What the pass does establish is narrower but not worthless — the terminal surface still mounts and initialises correctly with the new copy listener attached, so there's no regression in setup, and the mac path is untouched by the diff.

The reasoning behind the change still reads correctly on inspection: the copy path is gated on hasSelection() so an empty selection falls through as SIGINT, and clearSelectionAfterCopy is set only for the plain non-mac chord so the next press interrupts. That is inspection, not execution.

@rynfar
rynfar merged commit f630ab0 into pylonAug 14, 2026
11 checks passed
@rynfar
rynfar deleted the feat/terminal-copy-shortcut branch August 14, 2026 19:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@UtkarshUsername
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(web): copy the terminal selection with ctrl+c - #26

Merged
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut
Aug 14, 2026
Merged

feat(web): copy the terminal selection with ctrl+c#26
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut

Conversation

@rynfar

@rynfarrynfar commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Adopts upstream #5638. On non-mac, copying a terminal selection required Ctrl+Shift+C; plain Ctrl+C now copies too.

The interesting part: this does not break interrupt

Ctrl+C in a terminal is normally SIGINT, so rebinding it to copy is the kind of change that can quietly ruin your ability to stop a runaway process. I read this one specifically to check, and it's handled:

  • No selection → nothing intercepts. The copy path is gated on isTerminalCopyShortcut(event) && this.hasSelection(), so with nothing selected Ctrl+C falls straight through to the shell as SIGINT.
  • With a selection, one press copies and then clears the selection, so the nextCtrl+C reaches the shell. clearSelectionAfterCopy is set only for the plain non-mac chord.
  • Cmd+C and Ctrl+Shift+C stay copy-only and keep the selection, since neither is SIGINT.

The tradeoff is real and worth stating: with text selected, the first Ctrl+C copies instead of interrupting. The auto-clear keeps that to a single press.

The rest is browser-compatibility plumbing: plain Ctrl+C isn't preventDefaulted so the native copy event still fires, with a token-guarded deferred clipboard.writeText racing it for WebKit, which omits the keyboard copy event when there's no DOM selection. Ctrl+Shift+C has no native event at all (Chrome binds it to inspect), so that branch synthesises one via execCommand("copy"). There's also a contextMenuFallback path and one new IPC contract member.

Verification

  • vp test run over the 3 touched test files: 47 passed.
  • Typecheck on @t3tools/web and @t3tools/contracts: no errors.
  • vp lint on the changed files: clean.

Clean cherry-pick, no Pylon adaptation needed.

No browser pass. Clipboard behaviour differs across engines and this change leans on those differences deliberately — the WebKit race in particular is the sort of thing unit tests can't settle. Worth a real pass in Chrome and Safari before trusting it fully; say the word and I'll run one.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…#5638)
(cherry picked from commit 1add47b322ab1dfb5010bb363613650176b88088)
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for cd3b7cb.

This comment will update automatically after the next completed run.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Browser pass attempted — the change is not verifiable on this host

Ran the app on this branch against seeded data, opened the terminal drawer (ghostty canvas and Terminal input both mount fine with the change in place), and tried to exercise the copy gesture. Two findings, the second decisive:

1. Synthetic key events cannot drive this code path. The implementation deliberately relies on the browser's nativecopy event, and on the transient user activation that clipboard.writeText requires. Neither a synthetic KeyboardEvent nor a CDP-level key press produced a copy event that a document-level observer could see.

2. More fundamentally: this host is macOS, so the changed line never executes.navigator.platform is MacIntel, so isTerminalCopyShortcut takes the isMacPlatform branch and checks event.metaKey. The entire behavioural diff is on the other branch — event.ctrlKey && event.shiftKey becoming event.ctrlKey. A macOS browser cannot reach it regardless of clipboard mechanics.

So the honest position: verifying this needs a Windows or Linux browser. What the pass does establish is narrower but not worthless — the terminal surface still mounts and initialises correctly with the new copy listener attached, so there's no regression in setup, and the mac path is untouched by the diff.

The reasoning behind the change still reads correctly on inspection: the copy path is gated on hasSelection() so an empty selection falls through as SIGINT, and clearSelectionAfterCopy is set only for the plain non-mac chord so the next press interrupts. That is inspection, not execution.

@rynfar
rynfar merged commit f630ab0 into pylonAug 14, 2026
11 checks passed
@rynfar
rynfar deleted the feat/terminal-copy-shortcut branch August 14, 2026 19:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@UtkarshUsername
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): copy the terminal selection with ctrl+c - #26

Merged
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut
Aug 14, 2026
Merged

feat(web): copy the terminal selection with ctrl+c#26
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut

Conversation

@rynfar

@rynfarrynfar commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Adopts upstream #5638. On non-mac, copying a terminal selection required Ctrl+Shift+C; plain Ctrl+C now copies too.

The interesting part: this does not break interrupt

Ctrl+C in a terminal is normally SIGINT, so rebinding it to copy is the kind of change that can quietly ruin your ability to stop a runaway process. I read this one specifically to check, and it's handled:

  • No selection → nothing intercepts. The copy path is gated on isTerminalCopyShortcut(event) && this.hasSelection(), so with nothing selected Ctrl+C falls straight through to the shell as SIGINT.
  • With a selection, one press copies and then clears the selection, so the nextCtrl+C reaches the shell. clearSelectionAfterCopy is set only for the plain non-mac chord.
  • Cmd+C and Ctrl+Shift+C stay copy-only and keep the selection, since neither is SIGINT.

The tradeoff is real and worth stating: with text selected, the first Ctrl+C copies instead of interrupting. The auto-clear keeps that to a single press.

The rest is browser-compatibility plumbing: plain Ctrl+C isn't preventDefaulted so the native copy event still fires, with a token-guarded deferred clipboard.writeText racing it for WebKit, which omits the keyboard copy event when there's no DOM selection. Ctrl+Shift+C has no native event at all (Chrome binds it to inspect), so that branch synthesises one via execCommand("copy"). There's also a contextMenuFallback path and one new IPC contract member.

Verification

  • vp test run over the 3 touched test files: 47 passed.
  • Typecheck on @t3tools/web and @t3tools/contracts: no errors.
  • vp lint on the changed files: clean.

Clean cherry-pick, no Pylon adaptation needed.

No browser pass. Clipboard behaviour differs across engines and this change leans on those differences deliberately — the WebKit race in particular is the sort of thing unit tests can't settle. Worth a real pass in Chrome and Safari before trusting it fully; say the word and I'll run one.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…#5638)
(cherry picked from commit 1add47b322ab1dfb5010bb363613650176b88088)
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for cd3b7cb.

This comment will update automatically after the next completed run.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Browser pass attempted — the change is not verifiable on this host

Ran the app on this branch against seeded data, opened the terminal drawer (ghostty canvas and Terminal input both mount fine with the change in place), and tried to exercise the copy gesture. Two findings, the second decisive:

1. Synthetic key events cannot drive this code path. The implementation deliberately relies on the browser's nativecopy event, and on the transient user activation that clipboard.writeText requires. Neither a synthetic KeyboardEvent nor a CDP-level key press produced a copy event that a document-level observer could see.

2. More fundamentally: this host is macOS, so the changed line never executes.navigator.platform is MacIntel, so isTerminalCopyShortcut takes the isMacPlatform branch and checks event.metaKey. The entire behavioural diff is on the other branch — event.ctrlKey && event.shiftKey becoming event.ctrlKey. A macOS browser cannot reach it regardless of clipboard mechanics.

So the honest position: verifying this needs a Windows or Linux browser. What the pass does establish is narrower but not worthless — the terminal surface still mounts and initialises correctly with the new copy listener attached, so there's no regression in setup, and the mac path is untouched by the diff.

The reasoning behind the change still reads correctly on inspection: the copy path is gated on hasSelection() so an empty selection falls through as SIGINT, and clearSelectionAfterCopy is set only for the plain non-mac chord so the next press interrupts. That is inspection, not execution.

@rynfar
rynfar merged commit f630ab0 into pylonAug 14, 2026
11 checks passed
@rynfar
rynfar deleted the feat/terminal-copy-shortcut branch August 14, 2026 19:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@UtkarshUsername
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): copy the terminal selection with ctrl+c - #26

Merged
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut
Aug 14, 2026
Merged

feat(web): copy the terminal selection with ctrl+c#26
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut

Conversation

@rynfar

@rynfarrynfar commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Adopts upstream #5638. On non-mac, copying a terminal selection required Ctrl+Shift+C; plain Ctrl+C now copies too.

The interesting part: this does not break interrupt

Ctrl+C in a terminal is normally SIGINT, so rebinding it to copy is the kind of change that can quietly ruin your ability to stop a runaway process. I read this one specifically to check, and it's handled:

  • No selection → nothing intercepts. The copy path is gated on isTerminalCopyShortcut(event) && this.hasSelection(), so with nothing selected Ctrl+C falls straight through to the shell as SIGINT.
  • With a selection, one press copies and then clears the selection, so the nextCtrl+C reaches the shell. clearSelectionAfterCopy is set only for the plain non-mac chord.
  • Cmd+C and Ctrl+Shift+C stay copy-only and keep the selection, since neither is SIGINT.

The tradeoff is real and worth stating: with text selected, the first Ctrl+C copies instead of interrupting. The auto-clear keeps that to a single press.

The rest is browser-compatibility plumbing: plain Ctrl+C isn't preventDefaulted so the native copy event still fires, with a token-guarded deferred clipboard.writeText racing it for WebKit, which omits the keyboard copy event when there's no DOM selection. Ctrl+Shift+C has no native event at all (Chrome binds it to inspect), so that branch synthesises one via execCommand("copy"). There's also a contextMenuFallback path and one new IPC contract member.

Verification

  • vp test run over the 3 touched test files: 47 passed.
  • Typecheck on @t3tools/web and @t3tools/contracts: no errors.
  • vp lint on the changed files: clean.

Clean cherry-pick, no Pylon adaptation needed.

No browser pass. Clipboard behaviour differs across engines and this change leans on those differences deliberately — the WebKit race in particular is the sort of thing unit tests can't settle. Worth a real pass in Chrome and Safari before trusting it fully; say the word and I'll run one.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…#5638)
(cherry picked from commit 1add47b322ab1dfb5010bb363613650176b88088)
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for cd3b7cb.

This comment will update automatically after the next completed run.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Browser pass attempted — the change is not verifiable on this host

Ran the app on this branch against seeded data, opened the terminal drawer (ghostty canvas and Terminal input both mount fine with the change in place), and tried to exercise the copy gesture. Two findings, the second decisive:

1. Synthetic key events cannot drive this code path. The implementation deliberately relies on the browser's nativecopy event, and on the transient user activation that clipboard.writeText requires. Neither a synthetic KeyboardEvent nor a CDP-level key press produced a copy event that a document-level observer could see.

2. More fundamentally: this host is macOS, so the changed line never executes.navigator.platform is MacIntel, so isTerminalCopyShortcut takes the isMacPlatform branch and checks event.metaKey. The entire behavioural diff is on the other branch — event.ctrlKey && event.shiftKey becoming event.ctrlKey. A macOS browser cannot reach it regardless of clipboard mechanics.

So the honest position: verifying this needs a Windows or Linux browser. What the pass does establish is narrower but not worthless — the terminal surface still mounts and initialises correctly with the new copy listener attached, so there's no regression in setup, and the mac path is untouched by the diff.

The reasoning behind the change still reads correctly on inspection: the copy path is gated on hasSelection() so an empty selection falls through as SIGINT, and clearSelectionAfterCopy is set only for the plain non-mac chord so the next press interrupts. That is inspection, not execution.

@rynfar
rynfar merged commit f630ab0 into pylonAug 14, 2026
11 checks passed
@rynfar
rynfar deleted the feat/terminal-copy-shortcut branch August 14, 2026 19:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@UtkarshUsername
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(web): copy the terminal selection with ctrl+c - #26

Merged
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut
Aug 14, 2026
Merged

feat(web): copy the terminal selection with ctrl+c#26
rynfar merged 1 commit into
pylonfrom
feat/terminal-copy-shortcut

Conversation

@rynfar

@rynfarrynfar commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Adopts upstream #5638. On non-mac, copying a terminal selection required Ctrl+Shift+C; plain Ctrl+C now copies too.

The interesting part: this does not break interrupt

Ctrl+C in a terminal is normally SIGINT, so rebinding it to copy is the kind of change that can quietly ruin your ability to stop a runaway process. I read this one specifically to check, and it's handled:

  • No selection → nothing intercepts. The copy path is gated on isTerminalCopyShortcut(event) && this.hasSelection(), so with nothing selected Ctrl+C falls straight through to the shell as SIGINT.
  • With a selection, one press copies and then clears the selection, so the nextCtrl+C reaches the shell. clearSelectionAfterCopy is set only for the plain non-mac chord.
  • Cmd+C and Ctrl+Shift+C stay copy-only and keep the selection, since neither is SIGINT.

The tradeoff is real and worth stating: with text selected, the first Ctrl+C copies instead of interrupting. The auto-clear keeps that to a single press.

The rest is browser-compatibility plumbing: plain Ctrl+C isn't preventDefaulted so the native copy event still fires, with a token-guarded deferred clipboard.writeText racing it for WebKit, which omits the keyboard copy event when there's no DOM selection. Ctrl+Shift+C has no native event at all (Chrome binds it to inspect), so that branch synthesises one via execCommand("copy"). There's also a contextMenuFallback path and one new IPC contract member.

Verification

  • vp test run over the 3 touched test files: 47 passed.
  • Typecheck on @t3tools/web and @t3tools/contracts: no errors.
  • vp lint on the changed files: clean.

Clean cherry-pick, no Pylon adaptation needed.

No browser pass. Clipboard behaviour differs across engines and this change leans on those differences deliberately — the WebKit race in particular is the sort of thing unit tests can't settle. Worth a real pass in Chrome and Safari before trusting it fully; say the word and I'll run one.

Model: Claude Opus 5. Harness: Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…#5638)
(cherry picked from commit 1add47b322ab1dfb5010bb363613650176b88088)
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for cd3b7cb.

This comment will update automatically after the next completed run.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Browser pass attempted — the change is not verifiable on this host

Ran the app on this branch against seeded data, opened the terminal drawer (ghostty canvas and Terminal input both mount fine with the change in place), and tried to exercise the copy gesture. Two findings, the second decisive:

1. Synthetic key events cannot drive this code path. The implementation deliberately relies on the browser's nativecopy event, and on the transient user activation that clipboard.writeText requires. Neither a synthetic KeyboardEvent nor a CDP-level key press produced a copy event that a document-level observer could see.

2. More fundamentally: this host is macOS, so the changed line never executes.navigator.platform is MacIntel, so isTerminalCopyShortcut takes the isMacPlatform branch and checks event.metaKey. The entire behavioural diff is on the other branch — event.ctrlKey && event.shiftKey becoming event.ctrlKey. A macOS browser cannot reach it regardless of clipboard mechanics.

So the honest position: verifying this needs a Windows or Linux browser. What the pass does establish is narrower but not worthless — the terminal surface still mounts and initialises correctly with the new copy listener attached, so there's no regression in setup, and the mac path is untouched by the diff.

The reasoning behind the change still reads correctly on inspection: the copy path is gated on hasSelection() so an empty selection falls through as SIGINT, and clearSelectionAfterCopy is set only for the plain non-mac chord so the next press interrupts. That is inspection, not execution.

@rynfar
rynfar merged commit f630ab0 into pylonAug 14, 2026
11 checks passed
@rynfar
rynfar deleted the feat/terminal-copy-shortcut branch August 14, 2026 19:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@UtkarshUsername