# 自動起動仕様 (Autostart Specification)

## 1. 概要

OS にユーザーがログインしたタイミングで TelosDB を自動的に起動し、システムトレイで待機させる。ユーザーが手動で起動しなくても MCP サーバーや検索機能を利用可能にする。

```mermaid
flowchart LR
  subgraph ユーザー操作なし
    A[OS ログイン] --> B[TelosDB 自動起動]
    B --> C[トレイで待機]
    C --> D[MCP / 検索 利用可能]
  end
```

## 2. スコープ

| 項目 | 仕様 |
|------|------|
| **対応プラットフォーム** | Windows / macOS / Linux。Tauri 2 の対応 OS に準拠する。 |
| **トリガー** | ユーザーが OS に**ログイン（サインイン）**したとき。ロック画面からの解除やスリープ復帰では発火しない。 |
| **デフォルト** | **オフ**（`run_on_login: false`）。設定キーが存在しない場合（初回・アップデート後）もオフとして扱う。 |
| **起動後の挙動** | 自動起動時: `--minimized` 引数によりウィンドウを非表示にし、トレイのみで待機。手動起動時: 通常どおりウィンドウを表示。いずれもウィンドウを閉じるとトレイに常駐する。 |
| **設定の保存** | `settings.json`（Tauri AppData ディレクトリ）に永続化。フロント側は `localStorage`（キー `telosdb_settings`）にもキャッシュする。 |
| **対象エディション** | Community 版・Pro 版の両方で利用可能。エディション間に差異はない。 |

## 3. 技術構成

### 3.1 プラグイン

[tauri-plugin-autostart](https://github.com/tauri-apps/tauri-plugin-autostart) を使用する。

| 依存 | パッケージ | バージョン |
|------|-----------|-----------|
| Rust | `tauri-plugin-autostart` | `2.5.1` |
| JS | `@tauri-apps/plugin-autostart` | `^2.5.1` |

> Rust 側と JS 側のバージョンは揃えること。

### 3.2 プラットフォーム別の登録先

プラグインが各 OS のネイティブ機構を使って自動起動を登録する。

| OS | 登録先 |
|----|--------|
| Windows | レジストリ `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` |
| macOS | Launch Agent（`~/Library/LaunchAgents/` に plist を配置） |
| Linux | XDG Autostart（`~/.config/autostart/*.desktop`） |

```mermaid
flowchart TB
  subgraph プラットフォーム別の実体
    W[Windows: レジストリ Run]
    M[macOS: LaunchAgents]
    L[Linux: autostart .desktop]
  end
  P[tauri-plugin-autostart] --> W
  P --> M
  P --> L
  U[ユーザー: enable/disable] --> P
```

### 3.3 Rust 側プラグイン登録

`tauri::Builder` に以下を登録する:

```rust
.plugin(tauri_plugin_autostart::init(MacosLauncher::LaunchAgent, None))
```

### 3.4 Tauri capability

`capabilities/default.json` に以下の権限を追加する:

- `autostart:allow-enable`
- `autostart:allow-disable`
- `autostart:allow-is-enabled`

### 3.5 起動引数

プラグインの `Builder` で `.args([...])` を指定可能。自動起動時に `--minimized` を渡すことで、トレイのみ起動を実現する。

## 4. API

フロントエンドから利用する API は以下の 3 つ。

| 関数 | 説明 |
|------|------|
| `enable()` | 自動起動を有効にする（OS にエントリを登録）。 |
| `disable()` | 自動起動を無効にする（OS からエントリを削除）。 |
| `isEnabled()` | 現在 OS 上で自動起動が有効かどうかを返す。 |

## 5. 設定との連携

### 5.1 起動時の同期

アプリ起動時に保存済み設定と OS の実状態を同期する。

```mermaid
stateDiagram-v2
  [*] --> 設定ファイル読み込み
  設定ファイル読み込み --> スキップ: 読み込み失敗 (null)
  設定ファイル読み込み --> isEnabledチェック: 読み込み成功
  isEnabledチェック --> 同期: 設定値と isEnabled() が不一致
  isEnabledチェック --> 待機: 一致
  同期 --> enableまたはdisable
  enableまたはdisable --> 待機
  待機 --> ユーザーがトグル変更
  ユーザーがトグル変更 --> 保存してenable/disable
  保存してenable/disable --> 待機
```

| 条件 | 処理 |
|------|------|
| `loadSettingsFromFile()` が `null` を返した場合 | autostart 同期を**スキップ**する。デフォルト値 `run_on_login: false` で `disable()` を呼ぶと正常登録済みエントリを削除してしまうため。 |
| 設定値と `isEnabled()` が一致 | 何もしない。 |
| 設定値と `isEnabled()` が不一致 | 設定値に合わせて `enable()` または `disable()` を呼ぶ。 |

### 5.2 アップデート時のパス変更

再インストールで実行ファイルのパスが変わると、既存の Run キー等は無効になる。次回起動時の同期処理で設定がオンの場合は `enable()` を呼び直し、新しいパスで再登録する。

### 5.3 エラーハンドリング

- `enable()` / `disable()` が失敗した場合: `console.error` に出力し、UI にエラーメッセージを表示する。
- autostart 登録失敗時の保存メッセージ: 「保存しました（自動起動の登録に失敗しました。次回起動時に再試行します）」を 5 秒間表示する。

## 6. UI 仕様

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

設定パネルに「ログイン時自動起動」fieldset を表示する。

| 項目 | 仕様 |
|------|------|
| **コントロール** | チェックボックス（`<input type="checkbox">`）。既存の設定項目と統一。 |
| **配置** | 検索 fieldset の直下に独立した `<fieldset>` として配置。 |
| **legend** | 「ログイン時自動起動」 |
| **ラベル** | 「有効にする」 |
| **補足テキスト** | 「OS にサインインしたときに TelosDB を自動で起動します」 |
| **デフォルト** | オフ（`run_on_login: false`） |

### 6.2 HTML 構造

```html
<fieldset class="settings-fieldset">
  <legend>ログイン時自動起動</legend>
  <div class="setting-row">
    <label for="setting-run-on-login">有効にする</label>
    <input type="checkbox" id="setting-run-on-login"
           aria-describedby="setting-run-on-login-desc">
    <span id="setting-run-on-login-desc" class="setting-hint">
      OS にサインインしたときに TelosDB を自動で起動します
    </span>
  </div>
</fieldset>
```

### 6.3 操作フロー

設定の反映は**保存ボタンのクリック時**に行う。チェックボックスの操作だけでは `enable()` / `disable()` は呼ばれない。

```mermaid
flowchart LR
  subgraph 設定パネル
    A[設定ボタン] --> B[パネル開く]
    B --> C["loadSettingsFromFile()"]
    C --> D[フォームに反映]
    D --> E[ユーザーがチェックボックスを操作]
    E --> F[保存ボタンをクリック]
  end
  F --> G{"run_on_login?"}
  G -->|true| H["autostart.enable()"]
  G -->|false| I["autostart.disable()"]
  H --> J[settings.json に保存]
  I --> J
  J --> K[UI フィードバック表示]
```

### 6.4 表示値の更新タイミング

| タイミング | 挙動 |
|------------|------|
| **起動時** | `loadSettingsFromFile()` から `run_on_login` を読み、チェックボックスに反映。 |
| **設定パネルを開いたとき** | `loadSettingsFromFile()` を再取得してフォームに反映。`isEnabled()` で OS 実状態と照合し、不一致時は OS 側に合わせて表示を補正。 |
| **保存後** | 保存した値をフォームに再セットし、`localStorage` にもキャッシュ。 |

## 7. 注意事項

| 項目 | 内容 |
|------|------|
| **権限** | Windows の Run キーはユーザー単位。macOS の Launch Agent もユーザー単位。管理者権限は不要。 |
| **二重起動** | 別の方法（タスクスケジューラ等）で同じアプリを登録している場合、二重起動の可能性がある。プラグインは 1 エントリのみ登録する。 |
| **Community / Pro 共存** | 同一マシンに両方インストールし、両方で自動起動をオンにした場合はログイン時に両方起動する。 |
| **アンインストール時** | NSIS アンインストーラが Run キー / LaunchAgents / autostart エントリを削除することを確認する必要がある。 |
| **ヘッドレス起動** | `TELOS_HEADLESS=1` 環境変数でも `--minimized` と同様にトレイのみ起動が可能。 |

## 8. テスト

| 種別 | 内容 |
|------|------|
| **単体テスト** | Rust 側: `settings_default_has_run_on_login_false()` で初期値が `false` であることを検証（`src/backend/src/mcp/handlers.rs`）。 |
| **結合テスト** | 起動時の `loadSettingsFromFile()` → `isEnabled()` 比較 → 不一致時のみ同期、の一連フローを検証。 |
| **E2E テスト** | `tests/e2e/specs/settings-autostart.spec.js` で以下を検証: (1) チェックボックスの表示、(2) オンで保存→成功メッセージ表示、(3) パネル切替後もオン/オフが永続化。実行: `npx wdio run wdio.conf.js --spec tests/e2e/specs/settings-autostart.spec.js` |
| **手動テスト** | 自動起動をオンにし、OS ログアウト→ログイン（または再起動）で TelosDB が起動することを確認。オフの場合は起動しないことを確認。NSIS インストーラ版でも同様に確認する。 |

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

| ファイル | 役割 |
|----------|------|
| `src/backend/Cargo.toml` | Rust 依存: `tauri-plugin-autostart = "2.5.1"` |
| `package.json` | JS 依存: `@tauri-apps/plugin-autostart: ^2.5.1` |
| `src/backend/src/lib.rs` | Rust 側プラグイン登録、`get_app_settings` / `set_app_settings` コマンド |
| `src/backend/capabilities/default.json` | Tauri capability 権限設定 |
| `src/frontend/components/main-panel.js` | UI チェックボックス、起動時 `isEnabled()` 同期、保存時 `enable()` / `disable()` |
| `src/backend/src/mcp/handlers.rs` | MCP 経由の設定読み書き、`run_on_login` のデフォルト値 |
| `tests/e2e/specs/settings-autostart.spec.js` | E2E テスト |

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

- [tauri-plugin-autostart](https://github.com/tauri-apps/tauri-plugin-autostart) — 公式プラグイン
- [Tauri v2 Autostart プラグイン](https://v2.tauri.app/plugin/autostart/)

## 11. 関連計画

- [cross_platform.md](../plans/cross_platform.md) — macOS / Linux での動作検証、アンインストール時のエントリ残留確認

## 12. 修正履歴

### v0.3.3

初期実装のバグにより「自動起動がレジストリに登録されない（またはすぐ消える）」問題が発生し、以下を修正。

| 問題 | 修正 |
|------|------|
| `loadSettingsFromFile()` 失敗時にデフォルト値で `disable()` が走り、レジストリエントリが毎起動時に削除されていた | 読み込み失敗時は autostart 同期をスキップ |
| `isEnabled()` チェックなしに毎回 `enable()` / `disable()` を呼んでいた | `isEnabled()` で比較し不一致時のみ呼び出し |
| `enable()` / `disable()` のエラーが `catch(_){}` で握りつぶされていた | `console.error` 出力 + UI エラーメッセージ表示 |
| `Cargo.toml` のバージョンが `"2.0.0"` のまま（JS 側は `^2.5.1`） | `"2.5.1"` に更新 |
