おんがえしの blog

作ったプログラムと調べた技術情報

2026-W29

Obsidianデイリーノートの末尾に自動で追記できる CLIを作っている。oda (Obsidian Daily Appender)と名付けた。追記モードもあって|を入れるとそのまま入力できる。


英単語「一万語」習得法を読んだ。コロケーションの話がすごく面白かった。盛り上がって物書堂版の小学館 オックスフォード 英語コロケーション辞典を買ってしまった。後悔はしていない。大量のインプットと少量のアウトプットが重要らしくどこかで英文を書いて発散したい。


佐久間ANN0で紹介されていたチェアリングやってみたい。

チェアリングとは、軽量な折りたたみ椅子(アウトドアチェア)を野外に持ち出し、公園や河川敷などのお気に入りの場所に設置して、景色を眺めながらのんびりと過ごすアウトドア・アクティビティです。散歩の延長として準備や片付けの手間がなく、誰でも気軽に始められる点が魅力です。

magazine.cainz.com

git worktree と新玉ねぎ

つい最近まで、私は新玉ねぎと普通の玉ねぎを別の野菜だと思っていた。しかし調べてみると、実は両者の違いは「収穫後に乾燥処理をしているかどうか」だった。

「乾燥させていないだけ」という本質的な違いを知ると、新玉ねぎの水分が多い理由も日持ちしない理由もすべて腑に落ちる。新玉ねぎは冷蔵庫に入れないといけないのに、普通の玉ねぎは軒下で保存できる理由もよく分かった。水分をたっぷり含んだままのものは冷やして守るしかなく、しっかり乾燥させて茶色い鎧をまとったものは外気にも耐えられるのだ。 1

これと同じような体験がコンピュータ上でもあった。最近、1つのリポジトリから複数のブランチを同時に作業するために git worktree という機能について調べていた。git worktree add を使えば、元のリポジトリとは別のディレクトリに新しい作業ツリーを展開できる。これによって、メインの開発を進めながら、別のディレクトリでバグ修正や実験的な作業、レビュー用の環境を同時に開いておくことができる。

この機能を使ってみて、最初は「別のディレクトリでコミットしたら、どうやって元のリポジトリと同期するのだろう?」と疑問に思った。しかし、作られたディレクトリの中身を見て納得した。git worktree で作成したディレクトリには、通常の .git/ ディレクトリが存在せず、代わりにファイルとしての .git が一つ置かれているだけだったのだ。

実際のディレクトリ構造を見てみる

例えば、/path/to/previous-river というリポジトリで作業しているときに、並行して別の作業を行うためのワークツリーを作りたいとする。その場合、元のリポジトリ内で以下のようなコマンドを実行する。

> git worktree add ../previous-test
Preparing worktree (new branch 'previous-test')
HEAD is now at 024ee8c chore: Bump version to 1.3.0

一つ上の階層に previous-test という新しいディレクトリが作成される。このとき、作成された previous-test ディレクトリ直下の .git ファイルを開くと、以下のように元のリポジトリの場所を指し示すパスだけが格納されている。

gitdir: /path/to/previous-river/.git/worktrees/previous-test

一方で、元のリポジトリである previous-river の方はどうなっているかというと、.git/worktrees/ というディレクトリの中に新しく previous-test 用の管理フォルダが追加されている。この中には、新しい作業ツリーで選択されているブランチ(HEAD)やステージング状態(index)など、そのツリー固有の情報だけが個別に保存される。

> tree /f .git/worktrees/
/path/to/previous-river/.git/worktrees
├─previous-test
│  │  commondir
│  │  gitdir
│  │  HEAD
│  │  index
│  │  ORIG_HEAD
│  │
│  ├─logs
│  │      HEAD
│  │
│  └─refs

表面的な使い方より「仕組み」を知る

このように、新しく作られた側の .git ファイルが元のリポジトリを直接参照し、元リポジトリ側で個別状態を管理するため、新しいディレクトリ上でコミットを行うと、自動的に元のリポジトリに対してコミットの実体が書き込まれる仕組みになっている。リポジトリ全体の重いコピーを作るのではなく、ワーキングツリーだけを綺麗に分岐させているのだ。

「.git ディレクトリが実体として存在しない」という本質的な構造さえ理解してしまえば、「コミットしたら元のリポジトリに反映されるのは当然だ」と自然に理解できる。

玉ねぎの乾燥処理も、git worktree の構造も、一見すると些細な違いに思える。しかし、表面的な使い方を丸暗記するより、こうした「本質的な違い」を理解する方がずっと応用が利く。

結局のところ、どんな分野でも「仕組みを理解する」ことこそが、新しい知識を自分の血肉にするための最短ルートなのだ。


本日の一曲: Same Thing (feat. Superorganism) / 星野源


  1. それじゃあ新玉ねぎを家で頑張って乾燥させれば普通の玉ねぎになるのか、とも思ったが、新玉ねぎには水分が多くて育ちの早い「早生(わせ)品種」などが使われていることが多く、そこまで単純な話ではないらしい。

ソフトウェアを作って、ドキュメントを書かせる:LLMによる技術ドキュメンテーションの自動化

ここ半年ほど、Previous Riverという Obsidian プラグインを作っていた。このプラグインは、フロントマターの previous プロパティを利用してノートの前後関係を自動認識し、スムーズな移動を実現するものだ。想定していなかったバグを直し、ノートが大量につながると移動が遅くなってしまう問題を最適化し、俯瞰するためにObsidianのcanvas形式で出力するなど、一通り欲しい機能が完成した。

一つのソフトウェアを「普段使いに不満がないレベル」まで磨き上げると、既存の資料を読むだけとは違う深い理解が得られる。しかし、このプロセスで得た知見を他者に共有するのは容易ではない。大量のコミットログを他人が読み解くことは稀であり、一方で、すでに理解した内容を改めて言語化する作業は開発者の意欲を削ぐ。

新規実装という楽しい活動に比べ、既知の情報の整理は優先度が下がりがちだ。Previous Riverのような小規模な開発であっても、きちんと技術ドキュメントをまとめようとすれば、少なくとも4件のドキュメント執筆が必要になることがわかった。 そこで、人間が嫌がるこの『再言語化』を LLM にやってもらうことにした。

ドキュメントの生成プロンプト

ソースコードプロジェクト内にdocs/jaフォルダを掘り、

  • LLMとの会話ログ (Antigravity の場合は右上の「Open Agent Manager」ボタンや Ctrl+E で開けるAgent Manager から探せる)
  • コミットログ
  • Obsidian に記録している作業ログ

を参照させながら、ドキュメントを書かせることにした。プロンプトは以下のような感じになった(大枠は LLM に考えてもらって見出しのタイトルなどは自分で書き直した)。

# Role
あなたは「Google Technical Writing」の原則を熟知した、シニア・ソフトウェアエンジニア兼テクニカルライターです。
コミットログ、ソースコード、または過去の対話ログから、無駄がなく、かつ設計意図が明確な技術ドキュメントを作成してください。

# Constraints (AIスロップの排除)
1. **情緒的表現の禁止**: 「開発者の葛藤」「~に悩みました」などの感情表現は避け、「設計上の課題」「トレードオフの検討」といった客観的事[]()実として記述してください。
2. **冗長な前置きの削除**: 「~について説明します」「ご存知のように」等の導入文は一切不要です。即、本題に入ってください。
3. **1文1アイデア**: 文は短く切り、能動態(~を実装した、~と定義した)を使用してください。
4. **構造化**: 箇条書き、比較表、Mermaid図解、コードブロックを適切に使い、スキャン(速読)可能な構成にしてください。

# Output Structure
以下の構成で出力してください。

1. **目的**: 何を解決するためのものか、1〜2文で記述。
2. **用語の定義**: 複雑な概念がある場合、図解の提案を含めて定義。
3. **設計方針**: 
   - 複数の候補からなぜその実装(または命名)を選んだのか。
   - 却下した案とその理由(表形式が望ましい)。
4. **実装**: 
   - 核心となるコードを抽出。
   - 実装上の工夫(エッジケース対策、安全性など)を簡潔に補足。
5. **ユースケース**: そのコードが具体的にどう使われるか、実用的な例を提示。
6. **コミットログへのリンク**: git commit log から、関連するコミットログを追記。コミットハッシュにはgithubのURLをリンク。

# Instruction
以下の情報を元に、技術ドキュメントを作成してください。
[ここにソースコード、コミットログ、または会話ログを貼り付ける]

極力AIスロップを排除できるようにプロンプトは調整している。デフォルトのLLMに書かせると『〜の重要性は言うまでもありません』といった情緒的なポエムが混じり、技術文書として読みにくくなる。「Google Technical Writing」の原則をプロンプトに入れるとドキュメントのベースの質が上がるのでよく使っている。

生成されたドキュメント

  1. Previous River の基本機能とプロパティ操作
  2. Previous River の同一チェイン判定アルゴリズム
  3. Previous River の末端ノート探索の最適化
  4. Previous River の Canvas Export 機能の設計と実装

Previous Riverの開発における主要な技術トピックを網羅した。これらのドキュメントは、他のプラグイン開発においても有用なリファレンスとなる。例えば、大量のバックリンクを高速に取得する手法は「末端ノート探索の最適化」に、Canvas形式のデータ出力手法は「Canvas Export機能の設計と実装」に詳述している。構造化された知見は、人間だけでなくLLMが技術コンテキストを正しく把握する上でも効果を発揮するであろう。

ドキュメントの見た目はこんな感じ。mermaid の形式の図などは Gemini が勝手に記述してくれた。

例えば、Canvas Export 機能の解説では、以下のようなMermaid図解が自動生成された。

graph LR
  Root[Root Note] --> N1[Note 1]
  N1 --> N2[Note 2]
  N1 --> N3[Note 3]
  
  subgraph 孤立した循環ループ
    C1[Cycle A] --> C2[Cycle B]
    C2 --> C1
  end

まとめ

従来は、大人数で開発される価値の高いソフトウェア以外は、成果物とソースコード、最低限のユーザーマニュアルの提供に留まることが多かった。しかし、技術ドキュメントを成果物に含めることで、類似ツールを開発する者に対し、設計思想という異なる側面から貢献できる。これは執筆者自身の理解を深化させるプロセスでもある。ソフトウェア本体がいずれ動作しなくなっても、ドキュメントは独立した知見として存続する。技術ドキュメントを残すことで開発成果の寿命を延ばすことができる。

自らソフトウェアを開発し、ある程度の段階でLLMにドキュメントを生成させるワークフローは、極めて有用に感じた。


(宣伝)Obsidian を使っている人は是非 Previous River もお試しください。定例ミーティングの議事録や日報、1on1の記録など、定期的に発生するメモに対して前後関係を設定することで、過去の履歴を数珠つなぎに辿れて大変便利です。

Previous River 0.3.0 をリリースしました:パフォーマンスの改善

Obsidianに previous プロパティで前後関係を設定して、ショートカットキーで移動できるプラグイン Previous River の v0.3.0 をリリースしました。

前回リリースの変更点はこちらです。

ongaeshi.hatenablog.com

今回のアップデートでは、主に動作パフォーマンスを改善しています。

0.3.0の変更点:検索処理の最適化

数万件ほど previous プロパティがつながったノート群があると、これまでのバージョンでは「最後のノート」へジャンプする処理の計算量が増加し、UIが一時的にフリーズする課題がありました。

v0.3.0 では、内部の探索処理を以下のように見直しました。

  • find-last-note の処理速度改善: 移動経路を辿る処理を見直し、計算量 O(1) でアクセス可能なリバースキャッシュを構築しました。これにより、ノート数が多いVaultでもUIをフリーズさせることなく「最後のノート」へ移動できます。
  • getNextNotes の最適化: 前後のノートを行き来する際に呼ばれる探索処理(getNextNotes)を、resolvedLinksを使用する効率的なループ処理に変更しました。

これらの変更により、ツェッテルカステン(Zettelkasten)の実践や定期的なログの連結など、ノート同士の繋がりが多い環境での動作を安定させました。

10万件のノート群がつながった状態でも1瞬で末尾のノートに移動できるようになりました。

インストール方法

現在は先行公開版のため、BRAT(Beta Reviewer's Auto-update Tool)経由でインストールします。手順は以下の通りです。

  1. Obsidianの設定から コミュニティプラグイン を開き、BRAT をインストールします。
  2. コマンドパレットを開き、BRAT: Add a beta plugin for testing を選択します。
  3. リポジトリURLの入力欄に以下を入力します。 https://github.com/ongaeshi/previous-river
  4. コミュニティプラグイン の一覧から Previous River を有効化します。

まとめ

Previous River v0.3.0 では、ノート数が多い環境でのパフォーマンス改善を行いました。日常のメモや議事録、思考プロセスを連続した流れとして管理するツールとして活用いただけます。

利用中のユーザーはアップデートを、新規ユーザーはBRAT経由でのインストールをお試しください。

Obsidianのノートを「数珠つなぎ」にしてサクサク移動できる Previous River をリリースしました

Obsidianをはじめとするネットワーク型のメモアプリは、ノート同士をリンクで自由に繋げる「グラフ構造」が最大の強みです。

しかし、長期間使っていると、どうしても解決したい悩みが出てきました。それは、「関連するノート同士を、一本の線のようにサクサク行き来したい」という欲求です。

日記の連なり、定期的に発生するログ、あるいは思考が発展していくプロセス。これらは本来「点」ではなく、連続した「流れ(線)」です。 サイドバーのバックリンクから該当するノートを目視で探したり、フォルダツリーから次のファイルを探したりするのは、思考の大きなノイズになります。

そこで、ノートのつながりを「川のようにつなげる」プラグイン、Previous River を作りました。

Previous River デモ

Previous River でできること

使い方はシンプルです。 フロントマター(YAML)に previous: "[[前のノート]]" と書くだけ。

これだけで、ショートカットキーを使って「前のノート」と、バックリンクから自動判定された「次のノート」へ一瞬で移動できるようになります。

  • 直感的なキーボード操作: 移動機能にショートカットを割り振ることで、前後のノートをブラウザの「戻る・進む」のように高速に行き来できます。
  • 自動で「次」が繋がる: 「次のノート」を明示的に指定する必要はありません。「前のノート」からリンクを張れば、システムが自動的に「次のノート」を認識します。さらにシリーズの「先頭」「末尾」への一発ジャンプも可能です。
  • プロパティベース: previous プロパティを使うので、Obsidian標準の機能と相性が良く、データのポータビリティも高いです。

具体的な活用シーン:ノートが「線」になると何が変わるか

Previous River は、バラバラのノート群を「一連の文脈を持った流れ」として捉え直すためのツールです。

1. 定期的なログ(献立・通院・議事録)を繋げる

毎週の献立、通院記録、定例会議の議事録などを「数珠つなぎ」にすると、過去の情報へのアクセスが劇的に便利になります。

ノートの日付や保存フォルダが離れていても問題ありません。同じ種類のノートを線で繋ぐだけで、次のような過去の文脈を即座に引き出せます。

  • 前回の診察で話した内容
  • 前回決まったアクションアイテム

2. ウィークリーノートもデイリーノートのように移動する

デイリーノートは標準機能や他のプラグインで「前日」「翌日」に移動できますが、ウィークリーノートやマンスリーノートの移動は意外と面倒です。 Previous River で先週のノートを previous に指定しておけば、ショートカット一発で「先週のタスクはどうだったか」「来週の展望は」と、週単位・月単位の文脈をスムーズに往復できます。

3. ツェッテルカステン(Zettelkasten)の思考を整理する

Zettelkastenメソッドで作成した「永久保存メモ(Permanent Notes)」を、思考の発展順(関連の近いもの順)に並べていくのにも最適です。 フォルダという階層構造に頼らず、思考の近さに従ってノートを連ねていくことができます。

ノートの「並び替え」が自由自在に(v0.2.0新機能)

今回のアップデート(v0.2.0)で、ノートの「順序」を操作する強力なコマンド群を追加しました。これにより、手動でYAMLを書き換えるプロセスの大部分を自動化できます。

  • Insert note: 選択したノートを、現在のシーケンス(流れ)の途中に「新しい知見」としてスッと差し込みます。前後のリンクは自動でつなぎ直されます。
  • Insert note to first / last: ノートをシリーズの「最初」や「最後」へ一発で移動させます。
  • Detach note: previous プロパティをリセットし、そのノートを現在の流れから切り離します。

インストール方法

現在は先行公開版のため、BRAT(Beta Reviewer's Auto-update Tool)経由でインストールします。手順は以下の通りです。

  1. Obsidianの設定から コミュニティプラグイン を開き、BRAT をインストールします。
  2. コマンドパレットを開き、BRAT: Add a beta plugin for testing を選択します。
  3. リポジトリURLの入力欄に以下を入力します。 https://github.com/ongaeshi/previous-river
  4. コミュニティプラグイン の一覧から Previous River を有効化します。

まとめ

私は過去の議事録や献立表を辿る際、前後のノートそれぞれに手動でリンクを設定する作業にストレスを感じていました。このプラグインは、その課題を解決するために開発しました。

「リンク」は点のつながりですが、「シーケンス(順序)」は文脈のつながりです。 思考がどのように移り変わっていったのか、その「川の流れ」を遡る体験をぜひみなさまも実感してください。

もし「便利そう!」「こういうのが欲しかった」と思っていただけたら、はてなブックマークやGitHubでのスターをいただけると今後の開発の大きな励みになります!

Previous River - GitHub

2026年のサブスク見直し結果

年に一度クレジットカードの明細を見直して、今入っているサブスクリプションを再確認している。不要そうなものがあれば解約したり、プランを縮小したりしている。一番大切なのは月の合計支払額を確認することです。

Google AI Pro

https://gemini.google/jp/subscriptions/

年末のセールで年払い(29,000円→14,500円)で契約。Gemini, Antigravity, Notebook LM などがすべて使えてこの価格は、家でAI系の機能を試す環境として破格。Gemini はこの1年前とは比べものにならないくらい賢くなった。

14500/12=1208円。

Obsidian Sync

https://obsidian.md/sync

無いと一番困るサービス。Sync Plus だったけど、運用見直しで同期したい vault を1つにまとめられたので Sync Standard にした。デイリーノートはモバイルで書く方が多くて、PCを開いたときにgitにもコミットしてバックアップする運用になっている。年払いで月4$。

7793/12=649円。

Obsidian Publish

https://obsidian.md/publish

書いたものをさっと公開するのに最速。今は til 置き場としての使い方がメイン。年払いで月8$。

14746/12=1230円。

朝日新聞

https://digital.asahi.com/subscribe/

インプレッションお化けに壊されていない情報源が1つ欲しかったので、年末の3ヶ月無料期間(だったかな?そんな感じのキャンペーン)のときに入ってそのまま続けている。調査報道系の記事がとても有用で、1つのニュースに対する情報の深さが無料で見られる範囲とは比べものにならない。スタンダードコースなので 1980円。今の購読量だと 980円の月50本のコースにしたが長く続けられそう。 → 980円にした。

980円。

Radiko Premium

https://radiko.jp/premium

エリアフリー。一度見直しのときに解約してみたんだけど、なんだかんだ聞きたいことが多かったので再入会。以前はタイムフリー的な使い方がメインだったけど、最近は FM802 という大阪の放送局が自分の趣味に合うことが分かったので、聞きたい音楽が決まらないときに流してる。

385円。

ATOK Passport

https://atok.com/index.html

改悪。月330円のベーシックプランが無くなってしまい、強制的にプレミアムプランに移行せざるをえなくなった、、。せめて年額で割引してくれればいいのにそれも無し。2種類の支払いプランとは?変換の精度は気に入っているのだがiOS版のATOKは使い勝手が微妙で使っていないので、移行先を探してみようかな。

660円。

Cloudflare(ドメイン取得)

https://www.cloudflare.com/ja-jp/products/registrar/

Obsidian Publish で独自ドメインを使うときに Cloudflare だと簡単だったとちょうど更新タイミングだったので移管。.me だとドメイン自体の値段はそこまで変わらないのだが更新料金などがかからないので今のところ安く感じている。(来年どうなるかは分からない)

2745/12=228.75円。

Spotify Premium

https://www.spotify.com/jp/premium/

安定。レコメンドやプレイリストのできがよい。年末のSpotifyまとめが嬉しい。

Duo で契約しているので実質 1480/2=740円。

iCloud+

https://support.apple.com/ja-jp/108047

本体データバックアップしたいので50GBで契約。50GBまでは破格に安い。

150円。

ufret

https://www.ufret.jp/

かんぷれという楽器を演奏するときにお世話になっている。集中的に弾きたいときに広告無しプランに入っている。

580円。(optional)

まとめ

計算結果

1208 + 649 + 1230 + 385 + 740 + 980 + 660 + 150 + 228.75 = 6230.75円

年6231円。なかなかバランスよく入れているのではないだろうか?来年 Google AI Pro の半額がなくなっても 7439 円なので、それでも許容範囲かなという印象。逆に言うと、AI系のサブスク2個は今の自分の利用量を考えると予算オーバーしてしまう感じ。今年は Claude や Codex を試したいときは重量課金でやることにする。

来年の見直し候補としては Obsidian Publish と ATOK Passport 辺り。Obsidian Publish は使いやすいのだけど、ブログははてなブログで書いているのもあり、自分のちょうどいい使い勝手をまだ決められていない(はてなブログProに入るのもありなのだろうか?)。ATOK Passport は変換精度には満足しているけど、PC版しか使っていないのでベーシックプランがなくなってプレミアムプランしか選択できなくなったのは大分不満がある。他によいIMEを見つけたら試してみようと思う。

文章は「理解したこと」を書くものだと思っていたが、書きながら理解してもよかった

文章を書くとき、まず何について書くか題材を決める。それによって書きやすかったり書きにくかったりする。最悪の場合は執筆自体が止まってしまう。自分の執筆能力は一旦置いておくとすると、この違いは設定した題材によって起きることになる。

書きやすさに影響を与えそうなパラメータとしては「その題材についての理解度」と「その題材で書くことへのモチベーション」が重要そうだが、どちらが高いものを選ぶのがよいだろか?

結論としては、自分が今1番文章で表現してみたいもの、執筆を通して考えてみたいものを選ぶとよい。大切なのは書くことに対するモチベーションの高い題材を選ぶことだ。

田中泰延氏の『読みたいことを、書けばいい』で書かれているように、あるいはオードリーの若林氏が『青天』を執筆した経緯についてラジオで語ったときのように、そこに「どうしてもこれを形にしたい」という強い個人的動機があるかどうかが、苦しい執筆作業を支えてくれる。他人の目を気にした「正解」を書こうとすると筆はどんどん重くなっていく。

小川哲氏の『言語化するための小説思考』から得た最大の収穫は、「書いている途中で新しい発見があってもよい」ということだった。

これまで、文章は「理解したことをまとめる場所」だと思い込んでいた。しかし、その題材に対する強い動機があれば、完全に理解できていない話題であっても、書く過程を通じて理解を深め、見つけた面白いものをきちんと拾い上げていくことができる。そのような発想は今までしてきたことが無かったが、確かに過去に満足度の高い文書を書けたときは、書き始める前の自分では到底書けなかったようなものが書けたときだったような気がする。

振り返ってみると、これはプログラミングの世界では至極当たり前の話だ。自分がすでに作れるものをもう一度作るのは単なる作業に過ぎない。自分の能力を少し超えた課題に挑むからこそ、新しい発見があり、そこで得た知識をもとにさらに改善を加えることで、過去の自分には作れなかったものが作れるようになっていく。執筆もこれと同じなのではないか。

結局のところ、私は「文章を書く」という行為を少し舐めていたのかもしれない。せっかく外に向けて発信するならば、単なる作業ではなく、自分自身がやりがいを感じ、発見を得られるような題材を書いていこうと思う。