Products
Desktop App2026

Recon

Word文書のための「意味がわかる」バージョン管理システム。GitがWordで役に立たない理由を正面から解決し、rsidやレイアウトの揺れを無視して、段落・画像・スタイルといった文書上の意味的変化だけを差分として見せるデスクトップアプリ。

RustTauriTypeScriptReactOOXMLVersion Control
Recon

Recon

Wordの「何が変わったか」を、人間が読める形で。

Office文書のための、意味的差分に特化したローカルファースト・バージョン管理システム。


ひとことで言うと

Recon は「Word文書版のGit」ではありません。 Gitをそのままdocxに被せると、現実には何も嬉しくないからです。

.docxgit diff にかけたことがある人なら分かります。返ってくるのは「バイナリファイルが変わりました」という一行か、ZIPを展開した先の解読不能なXMLの洪水です。本文を一文字直しただけでも、Wordが内部に振り直す rsid(リビジョンID)やレイアウトキャッシュのせいで、差分は無関係なノイズで埋め尽くされます。「結局どこを直したんだっけ?」が分からない。 これが、文書管理がいつまでもメール添付と 最終版_v2_本当に最終.docx から抜け出せない理由です。

Reconは、この問題を真正面から解きます。.docx がZIP化されたOpen XMLパッケージであることに着目し、その内部構造を解析して「文書の意味モデル(semantic projection)」を生成。モデル同士を比較することで、rsidやフォント環境の揺れを完全に無視し、「段落が変わった」「画像が差し替わった」「見出しスタイルの定義が変わった」という、人間が意味として理解できる変化だけを抽出して見せます。


どんな意識で作ったか — 3つの設計上の約束

このプロジェクトは機能の寄せ集めではなく、揺るがせにしない3つの約束を軸に組み上げています。便利機能はここから生えてくるだけで、核はこの3つです。

1. 差分の単位は「XMLの行」ではなく「文書上の意味的変化」

世のdiffツールは要素レベル・行レベルの変化をそのまま吐き出します。Reconは違います。低レベルの構造差分(ProjectionChange)を一旦生成し、それを change mapper が「段落が変更された」「画像が挿入された」といった**意味的なイベント(ChangeEvent)**へ翻訳します。ユーザーが見るのは常に後者です。

recon diff HEAD~1 report.docx

body/paragraph[3]   paragraph_modified  (text changed)
body/paragraph[7]   image_inserted
styles/Heading1     style_definition_changed

「7行目の w:rPr の子要素が…」ではなく、「7段落目に画像が入った」と言ってくれる。これがReconの全てです。

2. 「保存しただけ」の変化を、絶対に差分に出さない

Wordはファイルを開いて閉じるだけで rsidparaIdlastRenderedPageBreak、リビジョンカウント、タイムスタンプを書き換えます。これらはWord起源で・不安定な情報、つまり「誰かが意図して変えたものではない」変化です。

Reconはこれらを読みません。raw XMLを正規化(書き換え)するのではなく、意味モデルを生成する段階で不要情報を最初から取り込まない(exclusion方式)。だから「保存しただけのファイル」は、差分ゼロとして正しく扱われます。ノイズと戦うのではなく、ノイズを構造的に発生させない設計です。

3. 復元は、バイト単位で元に戻ることを保証する

意味モデルはあくまで再生成可能なキャッシュです。Reconが唯一の正本として扱うのは、コミット時に保存した**オリジナルのバイト列(original blob)**だけ。

復元時は必ず sha256(復元ファイル) == 保存時のhash を検証してから書き出します。埋め込み画像も含めて完全再現。コミットの書き込みも blob保存 → fsync → manifestのatomic rename という順序を必須とし、「コミットはあるのに中身が無い」という壊れ方が構造的に起きないようにしています。文書管理ツールにとって、これは妥協できない一線です。


どんな課題を解決するのか

文書運用のリアルな悩み Reconの答え
最終版_v3_修正済、どれが本物?」 1ファイルで全履歴を保持。コミットで管理
「前のレビューから何が変わった?」 段落・画像・表・スタイル単位で意味的に提示
git diffがバイナリ扱いで使えない」 docx内部を解析し、人間が読める差分を生成
「開いて閉じただけで差分が出る」 rsid等のWord起源ノイズを構造的に無視
「うっかり上書き、前の版に戻したい」 hash検証付きで元のバイト列を完全復元

レポート、契約書、論文、仕様書 — 複数人で何度も推敲を重ねる文書ほど、「いつ・どこが・どう変わったか」が見えないことが致命的になります。Reconは、その「見えなさ」を解決対象に据えています。


何ができるのか

Reconは Tauri で作られたデスクトップアプリです。ワークスペース(フォルダ)を開くと、その中のOffice文書を自動で検出し、Git風の操作感で履歴管理できます。

  • ワークスペース管理 — フォルダを開くと .recon/ を作成し、追跡対象・未追跡の文書を一覧表示
  • Documents ビュー — 追跡中のdocxと、それぞれの変更ステータスを表示
  • Changes ビュー — HEADに対する文書の意味的変化を、その場でレンダリング表示
  • History ビュー — 選択した文書の保存済みバージョン履歴をたどる
  • In-Webview プレビュー — 差分の before / after を、姉妹プロジェクト [[docx-vellum]] によってWebView内で直接レンダリング
  • Git風CLIrecon add / commit / status / diff / log / restore をそのまま提供

GUIとCLIは同じコアを共有します。普段はGUIで眺め、自動化したくなったらCLIに降りる、という使い分けが自然にできます。


ひとつのシステム、3つのリポジトリ

Reconは責務をきれいに分離した3層構成です。それぞれが独立したリポジトリとして存在し、混ざりません。

担当 リポジトリ
GUI デスクトップUI・差分の可視化 Recon(本体)
Core VCSロジック・意味モデル生成・差分エンジン [[recon-cli]](Rust)
Render docxのブラウザ描画 [[docx-vellum]]

「diff結果を生成する」のはRustコアの責務、「before/afterを描画する」のはGUIとレンダラの責務。この境界を最初から引いたことで、各リポジトリが単体で進化できます。


技術的な裏側

  • アーキテクチャ — フロントエンドは React + TypeScript(Vite)、ネイティブ層は Tauri。重い文書処理はすべてRust側(Tauriコマンド)に委譲し、UIスレッドを止めない
  • Tauriコマンド境界init_workspace / list_documents / get_diff / create_version / restore_version など、フロントとコアのやり取りを明示的なコマンド契約として定義
  • 意味モデル — 本文をBlock列(段落 / 表 / セクション区切り)+ Inline列 + スタイルグラフ + メディアストアの複合グラフとして表現。各Blockがhashを持ち、Merkle構造で「変化のない部分の下層をスキップ」して高速に差分
  • 決定論的diff — fuzzy matchingを使わない。LCSは「変化していないアンカー」の生成にのみ使い、modified / added / deleted の判定は未マッチ領域に対して規則ベースで決定論的に行う
  • コンテンツアドレス・ストア — 同一画像はコミットをまたいで1回だけ保存。objects/ は一度書いたら上書き禁止(immutable)

なぜ作ったか

きっかけは単純で、**「Wordの差分が、どうしてこんなに見えないんだ」**という苛立ちでした。テキストファイルならGitで一瞬で分かることが、文書になった途端に不可能になる。多くの人が、ファイル名に日付とバージョンを書き足すという原始的な手段でこれを凌いでいます。

そこには「docxの中身は人間が読むためのものではない」という暗黙の諦めがあります。でも、docxはただのZIP + XMLです。構造を正しく読み、Word起源のノイズと意味のある変化を腑分けすれば、文書にも「ちゃんとした差分」が存在しうる。 Reconは、その仮説を最後まで実装し切ったプロジェクトです。

「速く動くもの」ではなく、復元がバイト単位で保証され、保存しただけでは差分が出ず、変化が意味として読める — 実際の文書運用に耐える状態まで設計したことが、このプロジェクトでいちばん大切にした点です。


Gitはテキストに強い。Reconは、文書に強い。