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

Zanei が記録するすべてのイベントは、ソースによらず 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（該当時。`value` は allowlist で安全と分類した非テキスト要素に限定し、不明な要素は `value: null`、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` には、認可された入力後に新たに増えた差分だけが入ります。認可には、同じアプリで、同じフォーカス要素の generation に対して打鍵またはペーストがあり、値変化通知のタイムスタンプがその入力から 3 秒以内である必要があります。1 つの認可が許す emit は最大 1 回で、使用時に消費されます。`text_content` も有効である必要があります。フィールドの全体値が `element.value` に保存されることはありません。

有効な認可のない値変化（アプリの不一致、フォーカス要素 generation の不一致、認可の期限切れを含む）はテキストとして記録しません。`data.text` は null となり、変化後の `value_len` だけを記録します。削除の場合も `text: null` です。音声入力は打鍵トリガーを伴わないため、そのテキストは記録されません。

### `input.key` の詳細

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

| `kind` | 意味 | `combo` | `text` | coalesce |
| --- | --- | --- | --- | --- |
| `text` | 印字可能文字の打鍵 | null | keyboard layout 型の入力ソースが直接生む文字（**opt-in のみ**）。keyboard input mode 型、入力ソース型が不明、または取得失敗時は 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 イベント）。core 側の coalesce バッファは pause・stop・batch flush 時に吐き出されます。collector 側の `ui.value` バッファはフォーカス変更時と collector 停止時に吐き出されます。

## `text_content` で変わるもの

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

| フィールド | 既定（`false`） | opt-in（`true`） |
| --- | --- | --- |
| `element.value` | 常に null | allowlist で安全と分類した非テキスト要素（ボタン、チェックボックス、ラジオボタン、スライダー、ポップアップボタン、メニュー項目、タブ、短い静的テキストなど）のみ記録。自由入力、secure、不明な要素は null |
| `input.key.text` | 常に null | keyboard layout 型の入力ソースが直接生む文字を記録（redaction 後）。keyboard input mode 型、入力ソース型が不明、または取得失敗時は null |
| `input.key.combo`（ショートカット） | **記録** | 記録 |
| `clipboard.*.text` / `size_bytes` | 常に null | 記録（redaction 後） |
| `ui.value.value_len` | 記録 | 記録 |
| `ui.value.data.text` | 常に null | 認可された入力によって増えた差分を記録（redaction 後）。同じアプリとフォーカス要素 generation に対し、入力から 3 秒以内に値変化の通知が届いた場合のみ。認可は emit 時に消費 |
| `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` イベント（アクセシビリティ由来）は記録されるため、プライベートウィンドウのページタイトルがタイトルとして残り得ます。避けるにはブラウザ自体を除外してください：`zanei 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 に収めるため出力を粗くする際には省略されます。
