# フォルダ監視仕様 (Folder Monitor Specification)

## 1. 概要

ユーザーが指定したフォルダを監視し、ファイルの追加・削除・更新を検知して TelosDB のインデックスに自動的に反映する。監視は一方向（フォルダ → DB）で完結し、MCP クライアントは従来どおり検索や件数取得で現在の DB 状態を参照する。

```mermaid
flowchart LR
  A[監視フォルダ] -->|Create / Modify / Remove| B[notify + debouncer]
  B --> C{イベント種別}
  C -->|ファイル存在| D[取込パイプライン]
  C -->|ファイル不在| E[インデックス削除]
  D --> F[(TelosDB)]
  E --> F
```

## 2. スコープ

| 項目 | 仕様 |
|------|------|
| **対応プラットフォーム** | Windows / macOS / Linux。Tauri 2 の対応 OS に準拠する。 |
| **監視対象** | ユーザーが設定で指定する 1 つ以上のディレクトリパス。 |
| **監視の深さ** | 再帰監視（`RecursiveMode::Recursive`）。サブディレクトリも含む。 |
| **対象ファイル** | 拡張子でフィルタ。デフォルト: `txt`, `md`, `json`, `html`, `css`, `js`, `mjs`, `ts`, `rs`。設定で変更可能。 |
| **動作タイミング** | アプリ起動中の常時監視。設定でモニター先を空にすることで実質オフにできる。 |
| **デフォルト** | モニター先フォルダなし（`monitor_paths: []`）。 |
| **MCP との関係** | 能動的なプッシュ通知はしない。クライアントは `search_text` や `get_document_count` 等で現在状態をプルする。`list_categories` でカテゴリ一覧を取得し、`search_text` の `category` パラメータで絞り込み可能。 |
| **対象エディション** | Community 版・Pro 版の両方で利用可能。 |

## 3. 技術構成

### 3.1 監視ライブラリ

Rust の **`notify`** クレートと **`notify-debouncer-mini`** を使用する。

| 依存 | 用途 |
|------|------|
| `notify` | クロスプラットフォームのファイル監視。各 OS のネイティブ API を利用する。 |
| `notify-debouncer-mini` | 短時間の連続変更を 1 イベントに集約（デバウンス）。 |

### 3.2 プラットフォーム別バックエンド

`notify::recommended_watcher()` で OS に最適な実装を取得する。

| OS | ネイティブ API |
|----|---------------|
| Windows | ReadDirectoryChangesW |
| macOS | FSEvents |
| Linux | inotify |

### 3.3 デバウンス

`notify-debouncer-mini` で **2 秒間**のデバウンスを行う。エディタの自動保存や一括書き換えによる連続イベントを 1 回の処理にまとめる。

debouncer-mini は内部でスレッドを使いブロッキング受信するため、専用の std スレッドで動作させ、Tokio ランタイムの `Handle` を通じて async 側（DB 連携）と接続する。

### 3.4 アーキテクチャ

```mermaid
flowchart TB
  subgraph "std スレッド"
    W[notify Watcher] --> D[debouncer-mini]
    D --> CB[コールバック]
  end
  CB -->|"Handle.block_on()"| I[ingest_file_path / delete_document_by_path]
  I --> DB[(SQLite)]
  CFG[WatcherConfig via mpsc] --> W
```

- **`spawn_folder_watcher`**: 専用 std スレッドで監視ループを起動。`mpsc::Receiver<WatcherConfig>` から設定を受け取り、設定変更時にワッチャーを再起動する。
- **イベント処理**: debouncer-mini は `Any` / `AnyContinuous` のみ区別するため、パスがファイルとして存在すれば取り込み（Create/Modify）、存在しなければ削除（Remove）として処理する。

## 4. イベント処理

### 4.1 ファイル追加・更新

対象拡張子にマッチするファイルが検知された場合:

1. ファイルパスからカテゴリを解決（`category_map` でモニター先ディレクトリごとにカテゴリを紐付け）
2. `ingest_file_path()` でファイルを読み取り、チャンク分割・ベクトル化・`documents` / `items` / `vec_items` / FTS に登録
3. 既にインデックス済みの場合は再取り込み（更新）

### 4.2 ファイル削除

ファイルが存在しなくなった場合:

1. `delete_document_by_path()` で該当パスに紐づくドキュメントを `documents` から削除（関連 `items` / `vec_items` / FTS も連動削除）

### 4.3 拡張子フィルタ

`is_watched_file()` で対象拡張子にマッチするか判定する。大文字・小文字は区別しない。拡張子リストが空の場合はすべてのファイルを無視する。

### 4.4 初期スキャン

モニター先が追加された際、既存ファイルを再帰走査し、未インデックスのもの（`get_document_id_by_path()` が `None` を返すもの）のみ取り込む。

## 5. 設定仕様

### 5.1 設定項目

| 項目 | キー | 型 | デフォルト |
|------|------|-----|----------|
| モニター先フォルダ | `monitor_paths` | `[{path: string, category: string}]` | `[]` |
| 取込対象拡張子 | `watch_extensions` | `string[]` | `["txt", "md", "json", "html", "css", "js", "mjs", "ts", "rs"]` |

`monitor_paths` はオブジェクト配列（`{path, category}`）形式。旧形式の文字列配列（`["path"]`）にも後方互換で対応する。

### 5.2 永続化

`settings.json`（Tauri AppData ディレクトリ）に永続化する。フロント側は `localStorage`（キー `telosdb_settings`）にもキャッシュする。

### 5.3 設定変更時の挙動

設定保存時に `WatcherConfig` を `mpsc` チャンネル経由でワッチャースレッドに送信し、ワッチャーを再起動する（監視パスの付け替え）。

## 6. UI 仕様

### 6.1 設定パネルの表示

設定パネルに「モニター先フォルダ」fieldset を表示する。

| 項目 | 仕様 |
|------|------|
| **配置** | 「ログイン時自動起動」fieldset の直下。 |
| **legend** | 「モニター先フォルダ」 |
| **フォルダ行** | パス入力欄 + カテゴリ名入力欄 + 削除ボタンの行を動的に追加・削除。 |
| **追加ボタン** | 「追加」ボタンクリックで Tauri のフォルダ選択ダイアログを表示し、選択パスを新規行に追加。 |
| **拡張子入力** | カンマ区切りのテキスト入力。空の場合はデフォルト拡張子を使用。 |

### 6.2 操作フロー

設定の反映は**保存ボタンのクリック時**に行う。保存時に `WatcherConfig` がワッチャースレッドに送信され、即座に監視が再起動する。

### 6.3 取込ステータス

ファイル取込中は `watch_ingestion_status`（`RwLock<String>`）に「取込中: ファイル名」を格納し、UI から参照可能にする。

## 7. テスト

| 種別 | 内容 |
|------|------|
| **単体テスト** | `is_watched_file()` の拡張子マッチ（大文字小文字、空リスト）。`watch.rs` 内の `#[cfg(test)]` で検証済み。 |
| **結合テスト** | イベント受信後に DB 連携（追加・更新・削除のハンドラ）が呼ばれることを検証。 |
| **手動テスト** | 監視対象フォルダにファイルを追加・編集・削除し、DB に反映されることを確認。デバウンス時間内の連続変更が 1 回にまとまることも確認。 |
| **UI / E2E** | 設定パネルで監視フォルダパスを指定し、保存できることを検証。 |

## 8. 制限事項

- ネットワーク FS（SMB/CIFS・NFS 等）ではネイティブ通知が発火しない場合がある。現在は `RecommendedWatcher` のみ使用しており、PollWatcher フォールバックは未実装。
- エディタによっては保存時に Remove + Create や複数 Modify が発生するが、デバウンスで吸収する。

## 9. 実装ファイル一覧

| ファイル | 役割 |
|----------|------|
| `src/backend/src/mcp/watch.rs` | フォルダ監視コア。`spawn_folder_watcher`、イベント処理、初期スキャン。 |
| `src/backend/src/mcp/types.rs` | `WatcherConfig` / `WatcherRestartSender` 型定義。 |
| `src/backend/src/mcp/mod.rs` | 起動時の `WatcherConfig` 構築と `spawn_folder_watcher` 呼び出し。 |
| `src/backend/src/mcp/handlers.rs` | 設定保存時の `WatcherConfig` 送信。 |
| `src/frontend/components/main-panel.js` | モニター先フォルダ UI（パス追加・カテゴリ・拡張子・保存）。 |

## 10. 外部リファレンス

- [notify](https://docs.rs/notify/latest/notify/) — Rust ファイル監視クレート
- [notify-debouncer-mini](https://docs.rs/notify-debouncer-mini/latest/notify_debouncer_mini/) — デバウンサー

## 11. 関連計画

- [cross_platform.md](../plans/cross_platform.md) — macOS / Linux での動作検証
- [folder_monitor_enhancements.md](../plans/folder_monitor_enhancements.md) — PollWatcher フォールバック、初期スキャン改善、権限エラー UI、パス正規化
