発端
「スマホで動く、GitHub APIを使ったテキストエディタを作りたい」。そんな要望から、このプロジェクトは始まりました。
v1:パス指定エディタ
最初に考えたのは、Cloudflare Workers + GitHub OAuthという構成でした。ところが、そもそも自分がCloudflareのアカウントを持っていないことに、途中で気づきました。
そこでサーバーを立てない方向に転換します。GitHub OAuthではなく、Personal Access Token方式にして、既存の`braindump`リポジトリを間借りする形でGitHub Pagesにホスティングしました。
デプロイした直後、「認証がすぐ切れる」という問題が起きました。原因を追うと、認証周りの不具合ではなく、「401が返ってきた瞬間にトークンを消す」という実装そのものが原因でした。エラーへの対処として書いたコードが、次のエラーの原因になっていたわけです。
v2:禅モード(タイプライター)への転換
ある時、完成度の高い参考コード(「禅 – Zen Writer」)を見せてもらったことで、方針を全面的に転換することになりました。
「パスを指定して開く」型のエディタから、「新規投稿専用・カーソルを画面中央に固定して書き流す」型へ。ここから、実機でしか起きない不具合との戦いが始まります。
- `100vh`とiOS Safariのアドレスバーのズレ:画面の高さがアドレスバーの表示/非表示で変わってしまい、レイアウトが崩れる。`dvh`単位に変更して解消。
- 子要素の絶対配置が環境依存で崩れるバグ:`overflow:hidden`+`position:relative`の祖先の中で、子要素の絶対配置が特定の環境だけおかしくなる。`position:fixed`を直接指定し、初回に強制的に再レイアウトさせることで対処。
- `getComputedStyle().font`のズレ:フォントのショートハンドプロパティが``要素で正しく取得できず、文字幅の測定がズレる。個別プロパティを指定して測定するDOMミラー方式に変更。
こうした一つひとつの不具合を、都度原因を特定しながら潰していきました。並行して、機能も段階的に増やしていきます。
- フォーカスしている行を強調し、離れた行は距離に応じてフェードさせる演出
- 画面端まで来たら折り返し、右揃えで上段に積み上がっていく表示
- Enterキーで行を「持ち上げ」て、確定した履歴として残す
- Backspaceキーで直前の行に戻り、編集し直せる復元機能
v3:AI漢字変換
次の課題は、日本語入力でした。「入力内容が学習に使われるのでは」というプライバシー上の懸念がまずあり、そこを最初に確認しました。API経由であれば基本的に学習に使われないことを確かめた上で、Gemini APIを採用することにしました。
固有名詞の扱いは、方針が一度ぶれています。最初は変換対象から除外する方向で考えていたのですが、最終的には「個人情報を書き込まない前提のツールであり、目的はあくまで脳の排水である」という考えに立ち返り、固有名詞も変換対象に含めることにしました。
運用を始めると、Gemini API側のトラブルにも次々と当たりました。
- モデル廃止による404エラー
- 過負荷による429/500/503エラー
- 認証エラー
これらは、その都度エラーの種類を見極めながら、自動リトライ・自動復旧の仕組みに落とし込んでいきました。
途中で気づいたのは、「どうせAIが変換する前提のモードなら、IMEのかな漢字変換自体が邪魔になる」ということでした。最初は`compositionend`イベントのタイミングで漢字・カタカナを除去するフィルタを作っていたのですが、最終的には`lang=”en”`を指定してローマ字を直打ちする方式に切り替えました。IMEと戦うのをやめて、そもそも変換させない方向に倒したわけです。
投稿(⌘+Enter)には、必ずAI変換を前置する構造にしました。これによって、「変換されていない生のローマ字がそのままGitHubに残る」という事態を、仕組みとして防いでいます。
独立リポジトリ化
v1・v2・v3は、もともとソース管理用の`mynotebook`(プライベート)と、ホスティング用の`braindump`(雑多な既存ツールと同居)に間借りする形で存在していました。最終的に、これらを切り離して`plzsayyes3/zen-note`という専用リポジトリに統合しています。
—
| バージョン | 性格 | 主な機能 | |—|—|—| | v1 | 通常のエディタ | ファイルパス指定で開く/編集/保存、Markdownプレビュー | | v2 | 禅モード(タイプライター) | カーソル画面中央固定・横流れ・端で上段へ折り返し・Enterで行確定(持ち上げ)・Backspaceで直前行を編集し直せる・距離フェード演出 | | v3 | v2 + AI変換 | ローマ字/かな直打ち→投稿前にGemini APIで自然な漢字混じり表記へ自動変換、モデル廃止/過負荷への自動リトライ |
パス指定のエディタから始まったこのツールは、不具合を一つずつ潰し、方針を転換しながら、最終的に「思考をそのまま流し出す」ための道具になりました。なぜこういう設計にしたのか、その考え方については思想編に書きます。


コメント