ブログ

技術やプロダクト開発に関する知見を発信しています

Engineering

Renovateの参照差し替え先の変更をgh apiで楽をする

Renovateプリセットの参照先差し替えで、Org配下のリポジトリ群に同じ修正PRを冪等に投げるBashスクリプトを、`git clone`を一度もせずに`gh api`だけで書きました。GitHub Contents APIとGit Refs APIの組み合わせ、再実行を前提にした冪等性の4箇所、macOSとLinuxで動く`mktemp`テンプレートまでをまとめます。

Engineering

RenovateのOnboarding PRを毎回手作業で書き換えるのをやめた

Renovateが立てる初回Onboarding PRには、`<org>/renovate-config/default.json`を置けば組織プリセットへの`extends`が自動で差し込まれる仕組みがソースコード側にあります。コメントを残せる`default.json5`を選ぶとこの自動検出が空振りするため、Mend-hostedの`org-inherited-config.json`で`onboardingConfig`を明示的に上書きして、Onboarding PRをそのままマージできる状態に揃えました。

Engineering

「no drag hooks」と書いた Framis に drag hook を後から入れた

Framis の product vision には「No drag hooks, no edge snapping」と明記していました。それでも Window を drag で動かすたびにホットキーで Arrange Mode に入り直すのが面倒になり、drag 中に修飾キー (既定 Control) を押すと overlay が出る動線を後付けで入れました。"opt-in only" を保つための `DragScrollMonitor` の State machine、Hold/Toggle の使い分け、修飾キー判定で気をつけた点を扱います。

Engineering

Chimrの「5分前通知」を秒単位で正確に出すために2段階タイマーにした

Chimr のカレンダー予定の「N分前通知」を秒精度で出すために、30秒おきの periodic scan と直近120秒以内の予定に対する one-shot timer の2段階構成に切り替えました。なぜ periodic だけだと精度が出ないか、なぜ one-shot を全件分仕込まないか、システムスリープ復帰と App Nap への対応までまとめます。

Engineering

ChimrのMCPセットアップを手で書かせないために --mcp-install と --mcp-config を足した

Chimr を Claude Code や Claude Desktop の MCP サーバーとして使うときの設定を、ユーザーに手で書いてもらう前提から、Chimr 自身が `claude mcp add` コマンドや JSON を吐く前提に切り替えました。`--mcp-install` `--mcp-config` `--mcp` の3つの CLI フラグの実装と、bundle path を `CommandLine.arguments[0]` から取る判断をまとめます。

Engineering

Cloudflare Pages で llms.txt が文字化けしたので _headers で charset を書いた

Cloudflare Pages は配信ファイルの拡張子から `Content-Type` を推測しますが、`text/plain` などには `charset` が付きません。`public/_headers` で `/llms.txt` `/robots.txt` `/sitemap.xml` `/docs/*.md` などに `charset=utf-8` を明示して、日本語の文字化けを直した手順をまとめます。

Engineering

Zone → Window 方式のウィンドウマネージャー Framis を作っている

既存の macOS ウィンドウマネージャー (Rectangle / Magnet / Moom / Raycast / AeroSpace / yabai) は、いずれも「Window を選んでから Zone を指定する」方式です。複数のウィンドウを持つアプリで「どの Window か」を狙うのが面倒で、Zone を先に選んで Window を割り当てる「Zone → Window」方式の Framis を作っています。Arrange Mode の作りと、App Store ではなく GitHub Releases で配る前提の話をまとめます。

Engineering

Vigilare の macOS と iOS で共有するコアを VigilareKit に切り出した

Vigilare は macOS と iOS の両方を同じ Apple Reminders 連携と同じタスク管理ロジックで動かしています。共通する部分を VigilareKit という Swift Package に切り出して、Models / Stores / Services / UseCases / ViewModels / DesignSystem を共有し、Views だけプラットフォーム別に持つ構造にしました。何を共有して何を別物にしたか、判断の軸を扱います。

Engineering

Vigilare の iOS 版を作っている

macOS で動かしている Vigilare の核は「Apple Reminders を常時最前面のフローティングウィンドウで出しっぱなしにする」ことです。iOS にはこの前提が成立しないため、同じ Apple Reminders 連携を別物の体験として組み直しました。検討した代替案、別物として組むと決めた判断の軸、いまどこまで動いているかを扱います。

Engineering

RenovateでCloudflare Workers SDKのパッケージをグルーピングする

Cloudflare Workers SDKはモノレポで管理されていますが、Renovateのデフォルト設定ではパッケージごとに個別のPRが作られます。wrangler、@cloudflare/vite-plugin、miniflareを1つのPRにまとめるpackageRulesの設定と、monorepo presetへの提案で浮上したimmortal PRs問題を紹介します。