---
title: イベントリファレンス
description: イベント型タクソノミー、全イベント共通の JSON エンベロープ、ブラウザ別の URL 捕捉対応。
---

Tadoru が記録するすべてのイベントは、ソースによらず OS 非依存の JSON エンベロープを共有します。この安定スキーマがプロジェクトのコア資産です — 捕捉バックエンドは OS ごとに変わっても、ツールが消費する形は変わりません。

## イベントエンベロープ

生出力（`query --format jsonl`・`record`・`export`）では 1 行 1 イベント（NDJSON）：

```json
{
  "v": 1,
  "id": "evt_01J...",
  "ts": "2026-08-16T12:34:56.789Z",
  "mono_ns": 128374651234,
  "source": "macos.ax",
  "type": "window.focus",
  "app":    { "name": "Safari", "bundle_id": "com.apple.Safari", "pid": 501 },
  "window": { "title": "Design doc", "id": 42 },
  "element":{ "role": "AXButton", "title": "Send", "value": null },
  "data":   { },
  "redaction": { "applied": true, "rules": ["email"] }
}
```

| フィールド | 説明 |
| --- | --- |
| `v` | エンベロープのスキーマバージョン（現在 `1`） |
| `id` | ULID ベースのイベント ID。一意かつ時刻順ソート可能 |
| `ts` | 実時刻タイムスタンプ（RFC3339、ミリ秒精度） |
| `mono_ns` | 単調時計（ナノ秒）— 実時刻が変わっても順序が保証される |
| `source` | 捕捉バックエンド。例：`macos.ax`・`macos.workspace`・`macos.eventtap`・`macos.applescript` |
| `type` | イベント型（[タクソノミー](#イベント型タクソノミー)参照） |
| `app` | アプリ名・バンドル ID・PID |
| `window` | ウィンドウタイトルと ID（該当時） |
| `element` | UI 要素の role/title/value（該当時。secure field は決して現れない） |
| `data` | 型固有ペイロード。例：`browser.navigate` の `url` / `tab_title` / `mode` |
| `redaction` | このイベントに適用された redaction ルール（`email` / `credit_card` / `token`）の有無と内訳。secure field は捕捉前に除外されるため redaction の痕跡は残りません |

このエンベロープは機械可読な JSON Schema としても公開されています：[`/schema/event.schema.json`](/schema/event.schema.json)。全露出面が共有する単一契約であり、Rust コアの型はこのファイルとの一致をテストで担保されます。

## イベント型タクソノミー

現在のイベント型です。**権限**列は、その型の捕捉に必要な macOS 権限を示します（[権限ガイド](/ja/guides/permissions)参照）。

| 型 | ソース | 記録内容 | 権限 |
| --- | --- | --- | --- |
| `app.activate` | `macos.workspace` | 前面アプリの切替 | 不要 |
| `app.launch` / `app.terminate` | `macos.workspace` | アプリの起動 / 終了 | 不要 |
| `window.focus` | `macos.ax` | フォーカスウィンドウの変更 | アクセシビリティ |
| `window.title` | `macos.ax` | タイトルの変化 | アクセシビリティ |
| `ui.focus` | `macos.ax` | フォーカス UI 要素の変更 | アクセシビリティ |
| `ui.click` | `macos.ax` | UI 要素へのクリック | アクセシビリティ（+ 入力監視） |
| `ui.value` | `macos.ax` | 要素値の変化。新たに増えた入力内容のみ opt-in で記録し、自由入力の全体値は記録しない | アクセシビリティ |
| `input.key` | `macos.eventtap` | キー / ショートカット。既定は「入力の事実 + フィールド種別」。内容は opt-in | 入力監視 |
| `input.scroll` | `macos.eventtap` | スクロール | 入力監視 |
| `browser.navigate` | `macos.applescript` | URL / タブの変化。**現在は Chrome のみ**。incognito は常に除外 | オートメーション |
| `clipboard.copy` / `clipboard.paste` | `macos.eventtap` | クリップボード操作。内容は opt-in | 入力監視 |

`--types` フィルタでは末尾ワイルドカードでファミリー全体を選べます：`browser.*`・`ui.*` など。

`type` は意図的に **open set**（closed enum ではない）です。将来のプラットフォームやバージョンはバージョン番号を上げずに型を追加でき、consumer は未知の型をエラーにせずスキップする必要があります。

## 型別ペイロード

各型が `data` に何を持つか、およびエンベロープの `window` / `element` の有無（✓ = あり、— = null）。規範的な定義は [JSON Schema](/schema/event.schema.json) の型別条件にあります。

| 型 | `window` | `element` | `data` |
| --- | --- | --- | --- |
| `app.activate` | ✓ | — | `prev_bundle_id` — 直前の前面アプリ。初回は null |
| `app.launch` / `app.terminate` | — | — | 空 |
| `window.focus` | ✓ | — | 空（フォーカス先はエンベロープ側） |
| `window.title` | ✓ | — | `prev_title` — 変化後のタイトルはエンベロープ側 |
| `ui.focus` | ✓ | ✓ | `field_kind` |
| `ui.click` | ✓ | ✓ | `button`（`left`/`right`/`other`）、`click_count` |
| `ui.value` | ✓ | ✓ | `field_kind`、`value_len`、`text`。`text` は入力直後に増えた差分、または null。自由入力フィールドでは `element.value` は記録されない |
| `input.key` | ✓ | — | `kind`、`modifiers`、`count`、`combo`、`text`、`field_kind`（詳細は下記） |
| `input.scroll` | ✓ | — | `direction`、`amount`、`count` — coalesce 済み合計 |
| `browser.navigate` | ✓ | — | `url`、`tab_title`、`mode`（常に `"normal"`）、`transition`（`navigate`/`tab_switch`/null） |
| `clipboard.copy` | ✓ | — | `content_kind`（`text`/`image`/`file`/`other`）、`size_bytes`、`text` |
| `clipboard.paste` | ✓ | — | `copy` と同じ + ペースト先の `field_kind` |

`field_kind` はフォーカス中の入力フィールドの種別です：`text` / `search` / `url` / `email` / `number` / `other`、テキスト系要素にフォーカスがなければ null。`password` という値は存在しません — secure field はイベントが存在する前に除外されます。

### `ui.value` の詳細

自由入力フィールドの `data.text` には、入力前の値と collector の debounce 窓が閉じた時点の値を比較し、新たに増えた差分だけが入ります。記録されるのは `text_content` が有効で、打鍵またはペーストから 3 秒以内に値が変化した場合だけです。フィールドの全体値が `element.value` に保存されることはありません。

直前に打鍵もペーストもない値変化は表示内容の変化として扱い、`data.text` は null、変化後の `value_len` だけを記録します。削除の場合も `text: null` です。音声入力は打鍵トリガーを伴わないため、そのテキストは記録されません。

### `input.key` の詳細

「既定は入力の事実 + フィールド種別、内容は opt-in」の正確な形：

| `kind` | 意味 | `combo` | `text` | coalesce |
| --- | --- | --- | --- | --- |
| `text` | 印字可能文字の打鍵 | null | IME を経ない打鍵が直接生む文字（**opt-in のみ**）。IME 有効時は null | する |
| `shortcut` | 修飾キー付き（`cmd+s` 等） | **常に記録** | null | しない |
| `navigation` | 矢印・PageUp/Down・Home/End・Tab | null | null | する |
| `delete` | Backspace / Delete | null | null | する |
| `other` | Esc・F キー・メディアキー | null | null | しない |

ショートカットは「内容」ではなく「操作」なので、`combo` は opt-in なしで記録されます。保存・コミット・タブ切替などタイムラインの主要な材料です。

## coalesce の保証

イベントはストアに届く前に coalesce されるため、consumer がキー連打やスクロールの洪水を生で見ることはありません：

| 対象 | グループ化キー | 窓 | 結果 |
| --- | --- | --- | --- |
| `input.key`（`text`/`navigation`/`delete`） | app + window + `field_kind` + `kind` | 間隔 ≤ 2s | 1 イベントに集約。`count` 合算、`text` 連結（opt-in 時） |
| `input.scroll` | app + window + `direction` | 間隔 ≤ 1s | `amount`・`count` を合算 |
| `window.title` | window | 500ms debounce | 最後のタイトルのみ emit |
| `ui.value` | フォーカス要素 | collector 側の 1s debounce | 最終値について 1 イベントを emit。`text` は入力前の基準値から最終値までに増えた差分 |

ショートカットと `ui.click` は coalesce しません（1 操作 = 1 イベント）。coalesce バッファは pause・stop・batch flush 時に必ず吐き出されます — イベントは失われません。

## `text_content` で変わるもの

opt-in なのは「内容」（打った・コピーした文字列）だけです。「操作の事実」（ショートカット・クリック・URL・タイトル）は既定で記録されます：

| フィールド | 既定（`false`） | opt-in（`true`） |
| --- | --- | --- |
| `element.value` | 常に null | 非テキストのコントロール（ボタン・チェックボックス・スライダー）のみ記録。自由入力フィールドでは常に null |
| `input.key.text` | 常に null | IME を経ない打鍵が直接生む文字を記録（redaction 後）。IME 有効時は null |
| `input.key.combo`（ショートカット） | **記録** | 記録 |
| `clipboard.*.text` / `size_bytes` | 常に null | 記録（redaction 後） |
| `ui.value.value_len` | 記録 | 記録 |
| `ui.value.data.text` | 常に null | 新たに増えた入力差分を記録（redaction 後）。直前に打鍵もペーストもない変化は null |
| `window.title` / `tab_title` / `url` | 記録（redaction 後） | 記録 |

## スキーマのバージョニング

- **追加的変更**（フィールド追加・型追加・source 追加）では `v` を上げません。consumer は未知フィールドを無視し、未知の型をスキップする必要があります。
- **破壊的変更**（削除・改名・意味変更）では `v` を上げ、ストアのマイグレーションを伴います。

## ブラウザの URL 捕捉

`browser.navigate`（URL 捕捉）は**現在 Chrome のみ**対応します。理由はプライバシー保証です：Chromium は AppleScript でウィンドウのモード（`normal` / `incognito`）を決定的に返すため、「**incognito ウィンドウは URL 捕捉から常に除外**」という強い約束を、設定ノブなしで置けます。

| ブラウザ | URL 捕捉（現在） | プライベートウィンドウ |
| --- | --- | --- |
| **Google Chrome** | ✅ 対応 | `mode` で incognito を確実判定 → 常に除外 |
| Brave / Edge / Vivaldi（Chromium 系） | ❌ 非対応 — collector は Chrome の bundle ID でのみ起動します | URL 捕捉自体がないため、プライベートウィンドウの扱いも発生しません |
| **Safari** | ❌ 非対応 | プライベート判定プロパティなし。メニュー差分ヒューリスティックは脆いため意図的に不採用 |
| **Firefox** | ❌ 非対応 | AppleScript に URL 取得 API が存在しない |
| **Arc** | ❌ 非対応（要検証） | Chromium 系だが AppleScript 対応が限定的 |

:::warning[正直な注意点]
incognito 除外がカバーするのは **URL 捕捉**です。URL 捕捉に非対応のブラウザでも — そして Chrome の incognito ウィンドウ自体も — 他のアプリと同様に `window.title` イベント（アクセシビリティ由来）は記録されます — プライベートウィンドウのページタイトルがタイトルとして残り得ます。完全に避けるにはブラウザ自体を除外してください：`tadoru filter exclude-app`（[フィルタ](/ja/guides/filters)参照）。
:::

Safari / Firefox 対応は、本当に信頼できるプライベートモード判定手段が用意できた場合にのみ将来検討します。

## データの 2 層

- **生イベント層** — 完全・機械可読。`query`・`record`・`export` が返すもの。
- **タイムライン層** — 人間 / LLM 可読。セッション分割・重複除去・coalesce・token budget 付き serialize。[`timeline`](/ja/reference/cli#timeline) と [`get_timeline`](/ja/reference/mcp#get_timeline) が返すもの。

タイムラインの各セッションは背後の生イベントへの `event_ids` 逆参照を持ちます。含まれるのは JSON 形式（`--format json`）のみで、token budget に収めるため出力を粗くする際には省略されます。
