ブログ
RSS技術やプロダクト開発に関する知見を発信しています
Claude Codeに書かせたSVGをsipsでラスタライズして自分で目視させる
Claude CodeにSVGで図を描かせる手法は既にありますが、書かせた図が実際にどう見えるかは書いた本人が確認していません。macOS同梱のsipsでPNGに変換し、そのPNGをエージェント自身に読ませて確認させる運用と、sipsが黙って落とす属性の実例をまとめます。
EventKitのcalendar(withIdentifier:)はcalendars(for:)と食い違うことがある
VigilareのMCPツールでlist_idを指定してもリマインダーが絞り込まれないことがある不具合を修正しました。原因はEventKitの2つのカレンダー取得APIが食い違う場合があり、片方だけがnilを返す状況でエラーなく「全カレンダー」へフォールバックしていたことです。
satoriの禁則処理とフォント収録範囲を自前のロジックで直した
satoriはCSSのlineBreakを実装しておらず、Noto Sans JPの収録範囲もメタデータ通りではありませんでした。OGP画像で実際に起きた2つの見落としと、それぞれを自前のロジックで直した記録です。
Claude Codeを任意の使用率で止めるガードを作っている
Claude Codeのrate_limitsはstatusLineにしか渡らず、実行を止められるhookには渡ってきません。この非対称をstate fileで橋渡しし、5時間枠・週次枠を任意のパーセンテージで止めるガードを試作した記録です。
Claude Codeのsandboxが1Password SSHエージェントのUnixソケットを塞ぎ署名が失敗する
Claude Codeのsandboxed Bashから1Password SSH鍵で署名付きコミットを実行すると失敗します。原因はUnixソケット接続の遮断で、sandboxを無効化しなくてもallowUnixSockets設定でソケットパスだけを許可すれば解決します。
来店できない会社の営業時間をマークアップしていた
labee.jpの全ページにLocalBusinessの構造化データを出していましたが、営業時間も対応エリアもページのどこにも表示していませんでした。Googleのポリシーが禁じている状態です。schema.orgの定義まで戻って、型ごと消した記録です。
macOSはWi-Fi Awareの公開APIをまだ開放していない
iPhoneとiPadの間はWi-Fi Aware(NAN)のPublisher/Subscriberで実際に接続でき、往復遅延も実測できました。一方macOS 26のSDKでは WACapabilities.supportedFeatures のようなAPI宣言そのものが利用不可とマークされていて、公開APIの型チェックの時点で先に進めません。実機で確かめた公開SDKの境界を扱います。
LazyVStackの行高推定が収束せずCPU100%でハングしたのでしきい値でVStackに切り替えた
Vigilareで一部の環境だけ再現するCPU100%ハングを、実機のCPUサンプルをもとに仮説をひとつずつ検証しながら追い詰めました。行き着いた先はSwiftUIのLazyVStackが不均一な行の高さを推定する処理が収束しなくなるというフレームワーク側の挙動で、行数にしきい値を設けてVStackへ切り替える形で回避しています。
MCPのレスポンスをMarkdownからTOONに変えたら、ツールの説明文まで書き直すことになった
Vigilare・Chimr・PortusのMCPサーバーで、ツールのレスポンスをMarkdownからTOONへ変えました。nilをnullとして書かないと表形式が崩れること、Markdownの表を前提に書いたツールの説明文を直すことになったこと、Markdownを残したVigilareでは同じ修正を2箇所に入れ続けていることを書きます。
SwiftUIの画面遷移でメインスレッドが20秒ハングしたのでsampleで実測して直した
タスク管理アプリVigilareで、詳細画面から一覧へ戻る操作がメインスレッドを20秒以上ハングさせていました。macOSのハングレポートとsampleコマンドで実測した原因は、LazyVStackに渡すForEachのデータソースが描画のたびに新しい配列で作り直されていたことでした。原因の特定から、他の画面に同じ設計ミスがないか確認するまでの調査記録です。
VOICEVOXをApple containerで動かしたらCPUが4コアしか使われていなかったので割り当てを増やした
Mac で常駐の VOICEVOX サーバーを Apple container で動かしたら、デフォルトでコンテナに 4 CPU しか割り当てられず、合成速度を本来の 4.5 分の 1 に落としていました。M5 Max での実測を交えて、cpus と cpu_num_threads を両方詰める設定を紹介します。
Apple Foundation Models で意図分解を4層に積み直したら 3B モデルのクセが見えた
macOS 26 の Apple Foundation Models で自然言語アシスタントを試作する中で、1-pass の Guided Generation を「意図 → 動詞/条件 → 詳細」の4層に再帰分解し直しました。3B オンデバイスモデルの hallucination は instructions では消えず、Swift 側の post-validation で span 単位に潰しています。
GitHub Pages は Unpublish しても設定が残るので棚卸しでは DELETE API まで叩く
移行元リポジトリの GitHub Pages を片付けたとき、Settings から Unpublish しただけでは Pages 設定オブジェクトが残り、`GET /repos/{owner}/{repo}/pages` が 200 を返し続けることに気づきました。Unpublish と Delete の違い、`status: null` の読み方、棚卸しで漏れを出さないために `gh api -X DELETE` まで踏み込む判断をまとめます。
@AppStorage のキー衝突を User Script Sandboxing 有効のままビルドで検知する
SwiftUI の @AppStorage は同じキーを別の型で共有してもコンパイラが咎めません。Bookil の開発中ブランチで踏んだキー衝突を題材に、型安全ラッパーや SwiftLint では塞げない理由と、Xcode の User Script Sandboxing を有効に保ったまま Pre-action と Run Script の役割分担でビルドを失敗させる仕組みを書きます。
PDFの表紙サムネイル生成をMediaBoxからCropBoxに揃え直した
書籍リーダー Bookil の開発中ブランチで、一部の PDF だけ表紙サムネイルが見開き(横長)になっていた問題を直しています。原因は印刷入稿由来の PDF が持つ MediaBox と CropBox の差をサムネイル生成側が考慮していなかったこと。修正の判断と、crop≠media な fixture をコードで生成して回帰テストにする方法を扱います。
Bookilで漫画の見開きをページ送りで読ませたくて描画を作り直している
iOS の PDFKit は「ページ送り」と「見開き表示」を同時に成立させられません。書籍リーダー Bookil で見開きの読み心地を作りたかった結果、描画層を自前で持つ方針に振って今もその開発を進めています。PDFKit の制約と、判断の軸を扱います。
プロダクトサイト群を 1 つの pnpm workspace に集約した
複数のプロダクトサイトを別リポジトリで運用していたところを、`sites/` と `packages/` の2層構成を持つ単一の pnpm workspace モノレポに集約しました。catalog で依存バージョンを揃え、共有パッケージはロジックと構造だけを渡してデザインは各サイトに残す設計、仮移植のサイトを抱えたまま動かす運用までを扱います。
GitHub Actions の workflow を 4 項目で安全側に倒した
org 配下の workflow を `defaults.run.shell: bash`、`actions/checkout` の `persist-credentials: false`、サードパーティアクションの SHA pin、`permissions` 最小化の4項目で揃えた経緯と、`git push` を含む `release.yml` や `submodules: true` を併用する workflow で「適用しない」を選んだ判断軸を記録します。
gh search code のインデックスは遅延する
Renovateプリセットの旧ファイル削除前に `gh search code` で参照残存を確認したら、マージ済みの新参照がまだヒットしてくれませんでした。コード検索インデックスの遅延に気づいた経緯と、Contents API でファイル本文を直接取得して実体検証する手順、検索ベース API への向き合い方を扱います。
Claude Codeのコミットメッセージ生成が遅いのでツール呼び出しをゼロにした
Claude Codeスキルの動的コンテキスト注入でgit diffを事前に本文へ埋め込み、サブエージェントの推論パスを3回から1回に減らした手順を紹介します。
