> ## Documentation Index
> Fetch the complete documentation index at: https://ccsafetynet.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI コマンドリファレンス

> CC Safety Net のすべての CLI コマンドをまとめたリファレンスです。status、doctor、logs、explain、rule、policy、install、update、uninstall、hook、gui、statusline の各オプションと終了時の挙動を示します。

CC Safety Net には、`cc-safety-net` という 1 つの CLI があります。`npx cc-safety-net` または `bunx cc-safety-net` で実行します。

適用処理は、`cc-safety-net install` が設定するプラグイン、拡張機能、hook を通して、エージェント内で動作します。CLI 自体をグローバルにインストールする必要はありません。`npx` または `bunx` は、ここで説明するコマンドの実行時に CLI を取得します。

このページは、コマンド、サブコマンド、オプション、終了動作をまとめたリファレンスです。初回実行の手順は[クイックスタート](/docs/ja/quickstart)、エージェントごとの設定は[インストール](/docs/ja/installation)を参照してください。

## コマンドの概要

CLI は 12 個のコマンドを登録します。次の順序は、`cc-safety-net --help` に表示される順序です。

| コマンド | 使用方法 | 動作 |
| - | - | - |
| [`status`](#status) | `status` | ランタイムが現在適用しているものを表示する |
| [`doctor`](#doctor) | `doctor [options]` | インストールと設定に対する診断検査を実行する |
| [`logs`](#logs) | `logs [options]` | hook が記録した監査ログエントリを表示する |
| [`explain`](#explain) | `explain [options] <command>` | コマンドの解析方法をトレースする |
| [`rule`](#rule) | `rule <subcommand>` | ルール設定、rulebook の設定元、transparent wrapper、宣言済みのコマンド用ツールを管理する |
| [`policy`](#policy) | `policy <subcommand>` | プロジェクトまたはユーザーのポリシー提案を検査して適用する |
| [`install`](#install) | `install [TARGET_FLAG]` | CC Safety Net をコーディングエージェント CLI にインストールする |
| [`update`](#update) | `update` | インストール済みのすべての連携を更新する |
| [`uninstall`](#uninstall) | `uninstall [TARGET_FLAG]` | CC Safety Net をコーディングエージェント CLI から削除する |
| [`hook`](#hook) | `hook INTEGRATION_FLAG` | エージェントのランタイム hook として動作し、標準入力から JSON を読み取る |
| [`gui`](#gui) | `gui [options]` | ローカルのポリシーエディター GUI を開く |
| [`statusline`](#statusline) | `statusline --claude-code` | シェル連携用の 1 行ステータスインジケーターを出力する |

`doctor` には別名 `--doctor` もあります。コマンド検索では大文字と小文字を区別しません。

<Note>
  `status` と `statusline` は異なる 2 つのコマンドです。`status` は人向けの複数行レポートを出力します。`statusline` はステータスバー向けに、絵文字インジケーターの正確に 1 行だけを出力します。
</Note>

## status

`status` は、「ランタイムが現在何を適用しているか」という 1 つの質問に答えます。保護を信頼する前に、保護が動作していることを最も速く確認する方法です。

```bash theme={"dark"}
npx cc-safety-net status
```

### 判定

先頭の判定は、次の 2 値のいずれかです。

| 判定 | 意味 |
| - | - |
| `ready` | ローダーエラー、警告、ポリシーのフォールバックなしで、ポリシースナップショットが正常に読み込まれた |
| `degraded` | スナップショットは読み込まれたが、ローダーエラー、警告、またはフォールバックポリシーがある。理由は `Not active` の下に表示される |

無効な Claude Code プラグインは、独自の判定ではなくなりました。その 1 つの連携に限定した、`Not active` リストの**最初の**項目として報告されます。

```text theme={"dark"}
plugin cc-safety-net@cc-marketplace is disabled in Claude Code; nothing is enforced in Claude Code until it is re-enabled. Other integrations are not affected.
```

Claude の設定ファイルがない、解析に失敗する、`enabledPlugins` がない、または `cc-safety-net@cc-marketplace` を `true` に設定していない場合、プラグインは無効と見なされます。この設定ファイルは、`CLAUDE_SETTINGS_PATH` が設定されていればその値、なければ Claude の設定ディレクトリ（`CLAUDE_CONFIG_DIR`、未設定なら `<home>/.claude`）にある `settings.json` です。検査の既定値は無効なので、読み取れない設定ファイルは、有効ではなく無効として扱われます。

判定はポリシースナップショットから取得され、設定から再導出されることはありません。プラグイン検査はその項目を追加するだけで、判定を変更しません。

### 出力

`status` は、判定行、整列した情報ブロック、確認または問題のリストを順に出力します。

| 行 | 値 |
| - | - |
| `Protection` | `destructive` と `secrets`。それぞれ `ok` または `OFF` として表示 |
| `Level` | 有効なレベル。`standard`、`strict`、`paranoid`、`custom` のいずれか。有効になっている破壊的コマンドのルールが、レベルから継承される状態と異なる場合は ` (customised)` が付く |
| `Rules` | `none active`、または有効なカスタムルール数を示す `<n> active` |
| `Policy` | ユーザーポリシーファイルのパス。`~` で短縮される |
| `Project` | プロジェクトポリシーファイルのパス。カレントディレクトリにある `.cc-safety-net/policy.json` がユーザーポリシーファイルではない場合に**のみ**出力される |
| `Worktree` | `relaxations active`。worktree モードが有効な場合に**のみ**出力される |

情報行は 1 行です。長い値は折り返さず、`…` で切り詰めます。

ユーザーの `.cc-safety-net/` があるディレクトリは 1 つだけです。ホームディレクトリ、または `CC_SAFETY_NET_HOME` が設定されている場合はその親ディレクトリです。そこで実行した場合、`<cwd>/.cc-safety-net/policy.json` はユーザーポリシーファイルそのものです。ローダーはこのファイルをユーザーポリシーとして 1 回だけ読み、プロジェクトポリシーは存在しないものとして扱います。そのため `status` に `Project` 行は出ず、`doctor` にも `Project policy deltas:` ブロックは出ません。比較では両方のパスを正規化するため、シンボリックリンク経由のホームディレクトリも一致します。たとえば FreeBSD は `/home` を `/usr/home` へのリンクとして提供しています。

プロジェクトポリシーがユーザーポリシーを緩めている場合は、情報ブロックの後に `Project policy` ブロックが続き、緩めたフィールドを 1 行ずつ示します。`CC_SAFETY_NET_PROJECT_TIGHTEN_ONLY` が設定されている場合、ブロックの見出しは `Project policy (ignored)` になります。[報告される緩和](/docs/ja/configuration/policy#reported-weakenings)を参照してください。

情報ブロックの後に、`status` は `Everything configured is active.`、または `Not active` セクションを出力します。後者には、問題ごとに折り返した項目があり、該当する場合はプラグイン無効の項目が最初、その後にスナップショット診断が続きます。最後に `Full report: cc-safety-net doctor` を出力します。

`NO_COLOR` が設定されている場合、または標準出力が端末でない場合、出力は ASCII のみになります。チェックマークとバツ印の代わりに `ok` / `OFF`、`·` の代わりに `-` を使い、先頭の盾のアイコンも付きません。

### 終了コード

<Note>
  判定が `degraded` の場合も含め、`status` は**常に `0` で終了します**。情報提供専用なので、スクリプトを失敗させません。問題でゼロ以外の終了コードが必要な場合は、`doctor` を使ってください。
</Note>

## doctor

`doctor` は、インストールと設定の完全な正常性検査を実行し、セクションに分けたレポートを出力します。

```bash theme={"dark"}
npx cc-safety-net doctor
bunx cc-safety-net doctor
```

| セクション | 説明 |
| - | - |
| Hook Integration | サポート対象の各エージェントの設定を確認する。Claude Code、Amp Code、Antigravity CLI、Codex、Cursor、DeepSeek Harness、Devin CLI、Factory Droid、Gemini CLI、GitHub Copilot CLI、Grok Build、Hermes Agent、Kimi Code、OpenClaw、OpenCode、Pi が対象 |
| Guard Engine Verification | ブロックが動作することを確認する合成セルフテストを実行する（`git reset --hard` と `rm -rf /` はブロック、`rm -rf ./node_modules` は許可） |
| Configuration | ユーザーとプロジェクトのルール設定を検証し、有効なルールを表示する |
| Environment | CC Safety Net の環境変数の状態を表示する |
| Effective Safety | 選択された preset、有効レベル、機能、ルールの override を表示する。継承されたルールを弱める override も含む。プロジェクトポリシーによる緩和は `Project policy deltas:` の下に表示される。`CC_SAFETY_NET_PROJECT_TIGHTEN_ONLY` が設定されている場合の見出しは `Project policy deltas (ignored):` |
| Findings | 診断された問題。それぞれに重大度と修正ヒントがある |
| Recent Activity | 過去 7 日間のブロックされたコマンドを要約する |
| System Info | 関連するすべてのツールのバージョンを表示する |
| Update Check | 新しいバージョンがあるかを確認する |

**オプション：**

| フラグ | 説明 |
| - | - |
| `--json` | 診断を JSON として出力する。バグレポートでの共有に使用できる |
| `--skip-update-check` | npm レジストリのバージョン検査をスキップする |
| `-h`, `--help` | ヘルプを表示する |

`doctor` は、`codex plugin list` から Codex の状態を読み取ります。CC Safety Net に一致する行に `installed, enabled` がある場合は `Detected` かつ `Configured` です。それ以外の `installed,` がある一致行は `Detected` かつ `Not configured` です。登録済みのマーケットプレイス行が `not installed` の場合は、無効ではなく `Not detected` です。

`Configured` になった Codex の行には、Hook Integration テーブルの下に信頼に関するリマインダーも表示されます。

```text theme={"dark"}
Warning (Codex): Codex runs only trusted hooks, and doctor cannot check trust. Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it.
```

`doctor` は hook が信頼済みかどうかを Codex に問い合わせません。そのため、このリマインダーは毎回表示されます。信頼設定が欠けていることを示すものではありません。Inspection は `Verified` のままで、finding も発生せず、終了コードも変わりません。`doctor --json` では、`hooks` の `codex` エントリの `errors` 配列に同じ文字列が入ります。

GitHub Copilot CLI では、`doctor` はプラグインの checkout 状態と hook の定義を確認します。インライン設定の優先順は、`<repo>/.github/copilot/settings.local.json`、`<repo>/.github/copilot/settings.json`、`<repo>/.claude/settings.local.json`、`<repo>/.claude/settings.json`、`$COPILOT_HOME/settings.json`、`$COPILOT_HOME/config.json` です（`COPILOT_HOME` の既定値は `~/.copilot`）。さらに、`<repo>/.github/hooks/*.json` と `$COPILOT_HOME/hooks/*.json` も調べます。`.claude` ファイルのエントリは、コマンドに `hook --copilot-cli` または `hook -cp` がある場合だけ対象です。Claude Code 用の hook だけでは対象になりません。インライン設定には GitHub Copilot CLI `1.0.8+`、ユーザー hook ファイルには `0.0.422+` が必要です。

Copilot のプラグインスイッチは、Copilot 自身の適用方法にあわせてエントリ単位で読み取ります。`enabledPlugins` の `cc-safety-net@cc-marketplace` に真偽値を設定している最初のリポジトリ側ファイルが結果を決めます。`doctor` は `disableAllHooks` と同じ順、つまり `<repo>/.github/copilot/settings.local.json`、`<repo>/.github/copilot/settings.json`、`<repo>/.claude/settings.local.json`、`<repo>/.claude/settings.json` の順に探します。どれも設定していなければ `$COPILOT_HOME/settings.json` が決めます。このスイッチについて `config.json` は読み取りません。したがって、リポジトリ側の `true` はユーザー側の `false` を打ち消します。プラグインの checkout があり、`$COPILOT_HOME/settings.json` が解析できない場合、`doctor` は `Not inspected` と報告します。ただし、リポジトリ側のファイルがすでにスイッチを決めているときは除きます。

スイッチで無効になった Copilot プラグインを `doctor` が `Not configured` と報告するのは、CC Safety Net の hook 設定がどれも有効でない場合だけです。hook ファイルまたはインラインの hook エントリがまだガードを実行している場合、`doctor` は方式を `hook config` として、そちらを報告します。Copilot は hook 設定をプラグインの hook とは別に読み込むためです。

`hooks.preToolUse` のエントリが対象になるのは、`type` がないか `command` のときです。Copilot は `type` がない場合を `command` として扱います。コマンドは `command`、`bash`、`powershell`、または `exec` と `args` を連結したものから読み取ります。`exec` は文字列、`args` は文字列の配列でなければなりません。これらの形に合わないファイルは `Invalid hook config <path>: hooks.preToolUse must be an array of hook objects`、そもそも解析できないファイルは `Failed to parse <path>: <reason>` と表示されます。

OpenCode 2.x を報告するホストでは、`doctor` は設定ファイルだけを見るわけではありません。読み込まれた設定に `cc-safety-net` のエントリがある場合、`doctor` はそのプラグインが有効化されたかどうかを OpenCode に問い合わせます。`opencode api integration.list` を実行してから `opencode api plugin.list` を実行し、どちらも `--param location[directory]=<dir>` を付け、30 秒の上限を設けます。`<dir>` は `doctor` を実行したディレクトリです。`integration.list` はホストのプラグイン有効化の完了を待ちますが、`plugin.list` は待ちません。

状態が `failed` の `cc-safety-net` の行があり、`active` の該当行がない場合、OpenCode は `Detected` かつ `Not configured` になり、`Error (OpenCode): OpenCode reports cc-safety-net failed: <the host's first error line>` が表示されます。`active` の行がある場合、行がない場合、出力がない場合、出力を解析できない場合は、いずれも設定から得た結果がそのまま残ります。そのため、リロードに失敗しても実行中のプラグインがそのまま残っていれば `Configured` のままです。この問い合わせは `cc-safety-net` のエントリがある場合にだけ実行されるので、エントリのない 2.x のユーザーに対しては行われません。OpenCode 1.x には `api` コマンドがないため、`doctor` は設定だけを読み取ります。

`doctor` が `1` で終了するのは、エンジンのセルフテストが失敗した場合と、Findings セクションに `error` 重大度の finding が 1 つでもある場合です。それ以外は `0` で終了します。警告は終了コードに影響しません。次の finding は `error` 重大度です。

* エージェント連携が設定されていません。
* hook の検査に失敗しました。
* ユーザーまたはプロジェクトのルール設定が無効です。
* policy、config、audit のいずれかのディレクトリが安全ではありません。現在のユーザーの所有ではない、グループまたはその他のユーザーに書き込み権限がある、シンボリックリンクである、ディレクトリではない、のいずれかに当てはまる状態を指します。

以前のバージョンが残した `rule.lock` ファイルまたは `cache` ディレクトリがあると、`info` 重大度の finding `config.v2-leftovers`（タイトルは `Rulebook lock and cache leftovers detected`）が発生します。ランタイムはどちらももう読み取りません。修正ヒントは ``Run `cc-safety-net rule sync` (add `--global` for user scope) to migrate them, then rerun doctor.`` です。`info` の finding は終了コードに影響しません。

レガシーのインライン形式のルール設定があると、`warning` 重大度の finding `config.legacy-ignored`（タイトルは `Legacy inline rule configs are ignored`）が発生します。`doctor` が調べるのは、実行したディレクトリの `.safety-net.json` と、CC Safety Net のホームディレクトリにある `config.json` です（`CC_SAFETY_NET_HOME` を設定していなければ `~/.cc-safety-net/config.json`）。詳細は `CC Safety Net no longer loads these files, so their rules enforce nothing: <paths>.`、修正ヒントは ``Run `cc-safety-net rule migrate` to convert them (add `--cleanup` to delete each file once it is converted), then rerun doctor.`` です。`doctor --json` は同じパスを、プロジェクトのファイルを先にして `legacyConfigs` に出力します。

一部の監査ログファイルを読み取れない場合、Recent Activity セクションの末尾に `Warning: <n> audit log sources could not be read; this summary is incomplete` が表示されます（1 件の場合は `source`）。これにより、操作が少ない週を完全なデータと誤認しません。

<span id="managed-hook-drift" />

### 管理対象 hook の設定ずれ

Cursor、Devin CLI、Factory Droid、Grok Build は、hook のエントリを手で編集できる設定ファイルに保持します。そのため `doctor` は、ディスク上のエントリと、インストールが書き込むエントリを比較します。ずれているエントリも、管理対象のエントリであることに変わりはありません。エージェントは `Configured` のままで、一致しなかった項目ごとに `Warning (<Agent>): <message>` を出力し、終了コードも変わりません。インストールを実行し直せば、エントリは書き直されます。

| エージェント | 警告 | ずれている箇所 |
| - | - | - |
| Cursor | `Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates` | `hooks.preToolUse` に管理対象のエントリが複数ある |
| Cursor | `Managed hook is missing "failClosed": true; reinstall to repair` | 最初の管理対象エントリの `failClosed` が `true` でない。この場合、hook が判定できなかった呼び出しを Cursor が許可してしまう |
| Cursor | `Managed hook "timeout" is not 30; reinstall to repair` | 最初の管理対象エントリの `timeout` が `30` でない |
| Devin CLI | `Managed hook has a "matcher" that narrows coverage; reinstall to repair` | 管理対象エントリの `matcher` が `""` でも `"*"` でもない |
| Devin CLI | `Managed hook "type" is not "command"; reinstall to repair` | 管理対象ハンドラーの `type` が `command` でない |
| Devin CLI | `Managed hook "timeout" is not 30; reinstall to repair` | 管理対象ハンドラーの `timeout` が `30` でない |
| Factory Droid | `Managed hook has a "commandRegex" that narrows coverage; reinstall to repair` | 管理対象エントリに `commandRegex` があり、その値が `""` でない |
| Factory Droid | `Managed hook has a "matcher" that narrows coverage; reinstall to repair` | 管理対象エントリの `matcher` が `""` でも `"*"` でもない |
| Factory Droid | `Managed hook "type" is not "command"; reinstall to repair` | 管理対象ハンドラーの `type` が `command` でない |
| Factory Droid | `Managed hook "timeout" is not 30; reinstall to repair` | 管理対象ハンドラーの `timeout` が `30` でない |
| Grok Build | `Managed hook has a "matcher" that narrows coverage; reinstall to repair` | 管理対象エントリの `matcher` が `""` でも `"*"` でもない。この 2 つは Grok Build がすべてに一致するものとして扱う書き方で、それ以外の値では一部のツール呼び出しが hook を通らなくなる |
| Grok Build | `Managed hook "type" is not "command"; reinstall to repair` | 管理対象ハンドラーの `type` が `command` でない |
| Grok Build | `Managed hook "timeout" is not 30; reinstall to repair` | 管理対象ハンドラーの `timeout` が `30` でない |

Antigravity CLI には、ずれの検査がありません。`doctor` は正規のエントリと比較するのではなく、コマンドのパターンで hook を照合します。そのため `Detected` かつ `Configured` と報告し、hook の定義に `enabled: false` がある場合は `Detected` かつ `Not configured` と報告します。

hook の設定ファイルをパースできない場合は、5 つとも結果が変わります。検出の段階で管理対象のエントリが見つからないため、そのエージェントは未設定として数えられ、Discovery、Configuration、Inspection の各列は `Unknown`、`Unknown`、`Failed` になります。メッセージも、警告ではなくエラーとして赤で表示されます。

* `Error (Antigravity CLI): Failed to parse Antigravity hooks config <path>: <reason>`
* `Error (Cursor): Failed to parse Cursor hooks config <path>: <reason>`
* `Error (Devin CLI): Failed to parse Devin CLI config <path>: <reason>`
* `Error (Factory Droid): Failed to parse Factory Droid hooks config <path>: <reason>`
* `Error (Grok Build): Failed to parse Grok Build hooks config <path>: <reason>`

いずれの場合も `<Agent> inspection failed` の finding が `error` 重大度で発生するため、`doctor` は `1` で終了します。

Devin CLI の設定ファイルがパースできても形式が合わない場合、`doctor` は同じ扱いをします。パースエラーの代わりに、次のいずれかのメッセージを出力します。

* `Devin CLI config <path> must be a JSON object`
* `Devin CLI config <path> "hooks" must be an object`
* `Devin CLI config <path> "hooks.PreToolUse" must be an array`

<span id="cursor-through-the-claude-code-plugin" />

### Claude Code プラグイン経由の Cursor

Claude Code プラグインには Cursor 用のプラグインマニフェストが入っているため、Cursor はこのプラグインから CC Safety Net を実行できます。`doctor` は、次の条件をすべて満たす場合にこの経路を数えます。

* Claude Code が `Configured` である。つまり `cc-safety-net@cc-marketplace` がインストール済みで、有効になっている。
* Claude Code の設定ディレクトリにある `plugins/installed_plugins.json` で、このプラグインの記録にユーザースコープのエントリがあり、`installPath` が入っている。
* `<installPath>/.cursor-plugin/plugin.json` をパースでき、その `hooks` フィールドが指すファイルが存在する。

Cursor が Claude Code プラグインを実行するのは、Claude Code プラグインをインポートする場合だけです。`doctor` はインポートしているかどうかを確認できないため、以下の 2 つのメッセージはどちらもそのことに触れています。

`install --cursor` の hook も設定されている場合、Cursor の方式は `hook config` のままで、`doctor` は次のように出力します。

```text theme={"dark"}
Warning (Cursor): The Claude Code plugin also runs this check in Cursor, so every tool call is checked twice. Cursor runs the Claude Code plugin only while it imports Claude Code plugins, which doctor cannot check. If Cursor runs it, run `cc-safety-net uninstall --cursor` to remove this hook.
```

`doctor` が hook を自動で削除することはありません。

プラグインが唯一の経路の場合、Cursor は `Detected`、`Configured`、`Verified` になります。`doctor --json` は方式として `Claude Code plugin` を、`configPath` としてマニフェストのパスを報告します。`doctor` の出力は次のとおりです。

```text theme={"dark"}
Warning (Cursor): Cursor runs the Claude Code plugin only while it imports Claude Code plugins, which doctor cannot check. If it stops, run `cc-safety-net install --cursor`.
```

どちらの警告も終了コードには影響しません。この経路が数えられている間は、パースできない `~/.cursor/hooks.json` も警告 `Warning (Cursor): Failed to parse Cursor hooks config <path>: <reason>` として表示され、`Cursor inspection failed` の finding は発生しません。

プラグインだけで保護されている Cursor には、`~/.cursor/hooks.json` に管理対象の hook がありません。[`update`](#update) はこの Cursor をスキップするため、hook を書き戻しません。対話形式のセレクターでは、install 時は `already installed`、uninstall 時は `not installed` と表示されます。`install --cursor` を実行すれば、hook は書き込まれます。

<span id="cursor-through-a-native-cursor-plugin" />

### ネイティブ Cursor プラグイン経由の Cursor

Cursor は、ネイティブ Cursor プラグインからも CC Safety Net を実行できます。このプラグインは、`cursor-agent` で個人マーケットプレイスとして Cursor アカウントに追加します。`install --cursor` がこの経路を設定することはなく、書き込むのは hook だけです。Cursor はマーケットプレイスのプラグインを追加時のコミットに固定するため、[`update`](#update) ではそのプラグインを最新に保てません。ただし、自分でインストールしたプラグインは `doctor` が報告します。

`doctor` がこのプラグインを数えるのは、`~/.cursor/plugins/cache/cc-safety-net/cc-safety-net` 配下のバージョンディレクトリに `.cache-complete` ファイルがある場合です。Cursor はこのファイルでダウンロードの完了を示します。この経路は [Claude Code プラグイン](#cursor-through-the-claude-code-plugin)経由よりも優先されます。両方そろっている場合、`doctor --json` は方式として `Cursor plugin` を、`configPath` としてそのバージョンディレクトリを報告します。

どのプラグインを有効にしているかは Cursor アカウント側の記録であり、`doctor` はこれを読み取れません。また Cursor はアンインストール後もプラグインのファイルを残すため、キャッシュディレクトリがあっても、プラグインがまだ動いている証拠にはなりません。以下の 2 つのメッセージは、どちらもこの 2 点に触れ、さらに `update` ではこのプラグインを更新できないことも伝えます。

`install --cursor` の hook も設定されている場合、Cursor の方式は `hook config` のままで、`doctor` は次のように出力します。

```text theme={"dark"}
Warning (Cursor): The Cursor plugin also runs this check, so every tool call is checked twice. Cursor records enabled plugins on your Cursor account, which doctor cannot check, and keeps a plugin's files after it is uninstalled. Cursor pins marketplace plugins to the commit they were added at, so `cc-safety-net update` cannot update this plugin, while the npx hook (`cc-safety-net install --cursor`) stays current. If the plugin is installed, run `cc-safety-net uninstall --cursor`, uninstall CC Safety Net from /plugins in cursor-agent, then run `cc-safety-net install --cursor`.
```

プラグインが唯一の経路の場合、Cursor は `Detected`、`Configured`、`Verified` になり、`doctor` は次のように出力します。

```text theme={"dark"}
Warning (Cursor): Cursor records enabled plugins on your Cursor account, which doctor cannot check, and keeps a plugin's files after it is uninstalled. Cursor pins marketplace plugins to the commit they were added at, so `cc-safety-net update` cannot update this plugin, while the npx hook (`cc-safety-net install --cursor`) stays current. If /plugins in cursor-agent does not list CC Safety Net as installed, run `cc-safety-net install --cursor`.
```

`doctor` がこの経路でしか数えていない Cursor は `update` の対象外です。そのため、`update` が npx hook を書き込むことはありません。対話形式のセレクターでは、install 時は `already installed` と表示され、uninstall 時は選択可能なままです。[`uninstall --cursor`](#uninstall) がマーケットプレイスも削除するからです。

キャッシュディレクトリが存在するのに一覧を取得できない場合、`doctor` はプラグインの有無を判断できません。設定済みの hook は `Configured` のままで、警告が 1 つ増えます。

```text theme={"dark"}
Warning (Cursor): Cannot read <home>/.cursor/plugins/cache/cc-safety-net/cc-safety-net, so doctor cannot tell whether the Cursor plugin also runs this check.
```

hook が設定されていない場合、Cursor の 3 つの列はすべて `Not inspected` になります。

### ホストごとの設定の場所

設定の場所を移動できるホストがいくつかあります。`doctor` は各ホストと同じ上書きルールに従うため、移動した設定でも見つけられます。

* **Claude Code**：`CLAUDE_CONFIG_DIR` が設定されていればその値、なければ `<home>/.claude` です。Claude Code 自身と同じく、値は `~` を展開せずそのまま使います。`install`、`update`、レガシープラグインの後始末、`status` と `statusline` の裏側で行う `enabledPlugins` の確認も、同じディレクトリを使います。
* **DeepSeek Harness**：`DSH_HOME` が設定されていれば `$DSH_HOME/profiles`、なければ `<home>/.dsh/profiles` です。値の先頭の `~` はホームディレクトリに展開されます。`doctor` は、その配下の各プロファイルディレクトリにある `package.json` を読み取ります。`node_modules` は対象外です。
* **Devin CLI**：`XDG_CONFIG_HOME` が設定されていて空でなければ `$XDG_CONFIG_HOME/devin`、それ以外は `<home>/.config/devin` です。Windows では `%APPDATA%\devin` で、`APPDATA` が未設定または空なら `<home>\AppData\Roaming\devin` です。ファイルはそこにある `config.json` で、値は `~` を展開せずそのまま使います。
* **Hermes Agent**：`HERMES_HOME` の親ディレクトリ名が `profiles` の場合、その値がそのまま Hermes のホームです。それ以外の場合、ルートは `HERMES_HOME`（未設定なら `<home>/.hermes`）で、ルートにある `active_profile` ファイルが `<root>/profiles/<name>` を選びます。この名前は前後の空白を取り除き、小文字に変換して使います。`active_profile` が空、`default`、ファイルなし、読み取り不能のいずれかであれば、ルートのままです。プラグインファイルは `<Hermes home>/plugins/cc-safety-net` に置かれます。
* **OpenClaw**：OpenClaw のホームは、`OPENCLAW_HOME` が設定されていて空でなければその値、それ以外は OS のホームです。先頭の `~` は OS のホームを基準に展開します。状態ディレクトリは `OPENCLAW_STATE_DIR`、なければ `OPENCLAW_CONFIG_PATH` があるディレクトリ、それもなければ `<OpenClaw home>/.openclaw` です。この 2 つの環境変数では、先頭の `~` を OpenClaw のホームを基準に展開します。
* **OpenCode**：2.x を報告するホストでは、`doctor` は `OPENCODE_CONFIG_DIR` だけを読み取ります。2.x は、この変数が設定されているとそのディレクトリしか読まないためです。それ以外のバージョンでは、そのディレクトリと XDG のディレクトリ（`$XDG_CONFIG_HOME/opencode`、なければ `<home>/.config/opencode`）の両方を読み取ります。1.x は常に XDG のディレクトリを読み込むためです。`OPENCODE_CONFIG_DIR` が空文字列の場合は未設定と同じ扱いです。`uninstall` は常に両方を読み取ります。
* **Pi**：`PI_CODING_AGENT_DIR` が設定されていればその値、なければ `<home>/.pi/agent` です。先頭の `~` はホームディレクトリを基準に展開し、ファイルはそこにある `settings.json` です。

`active_profile` が Hermes のプロファイル ID のパターンに合わない名前を指していても、実行は止まりません。Hermes Agent の行がそのエラーを報告し、`doctor` は他のホストを通常どおり検査します。

```text theme={"dark"}
Invalid Hermes profile name "<profile>" in <root>/active_profile; run `hermes profile use <name>` with a valid profile.
```

## logs

`logs` は、1 つの許可またはブロックされたコマンド判定を 1 レコードとして、[監査ログ](/docs/ja/reference/audit-log)を読み取ります。

```bash theme={"dark"}
npx cc-safety-net logs
npx cc-safety-net logs --suspect --since 7
npx cc-safety-net logs --id 3fa9c2d1a70e8b42
```

既定では、`logs` はすべてのプロジェクトについて、過去 30 日間の最新の**拒否** 20 件を出力します。許可判定も含めるには `--all` を指定します。

### フィルターとオプション

| フラグ | 引数 | 説明 |
| - | - | - |
| `--id` | `<id>` | 保持されている履歴から、16 文字の小文字 16 進数 ID を使って 1 エントリを検索する |
| `--limit` | `<n>` | 出力する最大エントリ数。既定値は `20` |
| `--since` | `<days>` | 指定した日数より新しいエントリだけを対象にする。既定値は `30`。上限は固定値ではなく設定済みの監査保持期間 |
| `--agent` | `<name>` | 記録されたエージェント ID と完全一致する。例は `claude-code` |
| `--rule` | `<ruleId>` | 記録されたルール ID と完全一致する |
| `--session` | `<id>` | 記録されたセッション ID と一致する |
| `--project` | `<path>` | プロジェクトディレクトリ、またはその下の任意のディレクトリと一致する |
| `--suspect` | | 誤検知に見える拒否だけを対象にする |
| `--all` | | 拒否に加えて `allow` エントリを含める |
| `--prune-legacy` | | レガシーのルートレベルログファイルを完全に削除する |
| `--dry-run` | | `--prune-legacy` と一緒に使い、削除対象を報告して何も削除しない |
| `--json` | | エントリを JSON として出力する |
| `-h`, `--help` | | ヘルプを表示する |

**`--suspect`** は、再確認する価値がある拒否に結果を絞ります。`failureStage` を持つ拒否（解析に失敗し、ガードが fail closed になったため、コマンドが危険だと証明されたわけではない）、または同じセッション内で同じコマンド署名が 2 回以上拒否された場合です。繰り返し回数は、`--limit` で出力を切り詰める前に、`--since` の期間全体で数えます。

**同時に使えない組み合わせ。** 次の 2 つは、明示的なメッセージと終了コード `1` で拒否されます。

* `--id` は、`--agent`、`--rule`、`--session`、`--project`、`--suspect`、`--since`、`--limit` と同時に使えません。
* `--prune-legacy` は、`--id`、`--agent`、`--rule`、`--session`、`--project`、`--suspect`、`--all`、`--since`、`--limit` と同時に使えません。一緒に使えるフラグは `--json` と `--dry-run` だけです。

`--dry-run` だけを指定することも拒否されます。`--dry-run requires --prune-legacy` を出力し、`1` で終了します。

認識しないオプションは `Unknown option for logs: <arg>` を出力し、`1` で終了します。

監査ログファイルを読み取れない場合、またはレコードが不正な場合、`logs` は標準エラー出力に 1 つの警告 `warning: <n> audit log sources could not be read; these results are incomplete` を出力します（1 件の場合は `source`）。標準出力と終了コードは変更しません。

### 機械可読出力

| 呼び出し | JSON 形式 |
| - | - |
| `logs --json` | 生の監査エントリの配列。フィルタリング、新しい順の並べ替え、`--limit` の適用後に 2 スペースでインデントされる |
| `logs --id <id> --json` | 0 または 1 エントリを持つ配列 |
| 監査ログディレクトリがない場合の `logs --json` | `[]` |
| `logs --prune-legacy --json` | 1 つのコンパクトオブジェクト：`{"removedFiles":n,"removedBytes":n,"failedFiles":n}` |
| `logs --prune-legacy --dry-run --json` | 1 つのコンパクトオブジェクト：`{"dryRun":true,"files":n,"bytes":n}` |

人向けの出力では、エントリごとに ID、タイムスタンプ、判定、エージェント、ルール ID、50 文字に切り詰めたコマンドを 1 行で出力します。完全なコマンドと異なるセグメントには `↳` が付きます。`--id` は、代わりにレコードのすべてのフィールドを含むラベル付き詳細ブロックを出力します。

### logs --prune-legacy

<Warning>
  `logs --prune-legacy` は、監査ルートにあるすべてのレガシーのルートレベル `*.jsonl` ファイルを**即時かつ元に戻せない形で**削除します。確認プロンプトも `--yes` もありません。削除対象を確認するには、先に `--dry-run` を追加してください。経過時間と内容は関係ありません。対象かどうかはファイルの場所だけで決まります。
</Warning>

ネストされたプロジェクトごとの監査ログには触れません。コマンドは実行後にそのことを表示します。すべての削除に成功すると `0`、いずれかのファイルを削除できないと `1` で終了します。削除対象がない状態で再度実行すると、何もしません。

`--dry-run` では何も削除しません。コマンドは `Would remove <n> legacy audit log files (<size>).`、または `No legacy audit log files found.` を出力し、次に `Nested v2 audit logs are not included.` を出力します。削除対象がある場合は、`Run the same command without --dry-run to delete them.` も出力します。常に `0` で終了します。`--json` と一緒に使うと、代わりに 1 つのコンパクトオブジェクト `{"dryRun":true,"files":n,"bytes":n}` を出力します。

レガシー配置と現在の配置の違いについては、[監査ログ](/docs/ja/reference/audit-log#log-layout)を参照してください。

## explain

`explain` は、CC Safety Net がコマンドを解析する方法を手順ごとにトレースします。コマンドがブロックまたは許可される理由、カスタムルールが適用される方法を確認するために使います。

```bash theme={"dark"}
npx cc-safety-net explain "git reset --hard"
bunx cc-safety-net explain "git reset --hard"
```

**オプション：**

| フラグ | 説明 |
| - | - |
| `--json` | 完全な解析結果を JSON として出力する |
| `--cwd <path>` | この作業ディレクトリから実行したものとして解析する |
| `-h`, `--help` | ヘルプを表示する |

`--` はフラグ解析を終了します。その後にあるすべてのものがコマンドです。残りの引数が 1 つなら、シェル演算子を維持するため、そのまま使います。複数の引数は再度引用します。

**例：**

```bash theme={"dark"}
npx cc-safety-net explain "rm -rf /"
npx cc-safety-net explain --json "git checkout -- file.txt"
npx cc-safety-net explain --cwd /tmp "git status"
```

オプションの解析に成功した後、`explain` はブロックと許可のどちらの結果でも `0` で終了します。終了コードではなく `result` フィールドを読んでください。`1` で終了するのは次の 2 つの場合です。1 つはオプションの検証です。

* 不明なオプションは `Unknown option for explain: <arg>` を出力します。値がない `--cwd` は `--cwd requires a value` を出力します。どちらの解析エラーにも `Usage: cc-safety-net explain [--json] [--cwd <path>] <command>` と `Pass -- before a command that starts with dashes.` が続き、`1` で終了します。
* 存在しない `--cwd` パスは `Error: --cwd path does not exist: <path>` を出力し、`1` で終了します。
* 空のコマンドは `Error: No command provided` と使用方法の行を出力し、`1` で終了します。

もう 1 つは解析の上限です。構造的なコマンド解析の上限、パス正規化の上限、ツール入力の走査上限のいずれかを使い切ったコマンドは、スタックトレースではなく 1 行のエラーメッセージを出力して `1` で終了します。`--json` では標準出力全体が 1 つのエラーオブジェクトになり、それ以外の場合はメッセージを標準エラー出力に書き出します。

```bash theme={"dark"}
npx cc-safety-net explain --json 'loop() { loop; }; loop'
```

```json theme={"dark"}
{"error":"Structural command analysis limit exceeded."}
```

最上位パーサーも同じ方法で `--` を処理します。最初の `--` で `--help` と `--version` の検索を停止します。そのため、`explain -- --help` はヘルプを出力せず、リテラルコマンド `--help` を explain します。

<Warning>
  explain の出力は、そのまま安全に共有できるとは限りません。入力したコマンド、解析後のトークン、ホームディレクトリを含む絶対パスがそのまま表示されます。Issue やチャットにトレースを貼り付ける前に、[explain トレース](/docs/ja/reference/explain-trace#before-you-share-a-trace)を確認してください。
</Warning>

`--json` が返す JSON のスキーマ、つまり `ExplainResult` のフィールドと `TraceStep` の全種類については、[explain トレースリファレンス](/docs/ja/reference/explain-trace)を参照してください。

## rule

`rule` は、ルール設定、rulebook の設定元、transparent wrapper、そして解析対象として宣言したコミュニティ製のシェルツールを管理します。このセクションではコマンドインターフェースを説明します。rulebook のスキーマ、ライフサイクル、override の意味については、[カスタムルール](/docs/ja/configuration/custom-rules)を参照してください。

サブコマンドなしで `rule` を実行すると、ヘルプを出力して `1` で終了します。`rule --help` は同じヘルプを出力して `0` で終了します。

**オプション：**

| フラグ | 説明 | 有効な対象 |
| - | - | - |
| `-g`, `--global` | プロジェクトスコープではなくユーザースコープのルール設定を使う | `list`、`migrate`、`tool` 以外のすべてのサブコマンド |
| `--project` | ユーザースコープではなくプロジェクトスコープのルール設定を使う | `tool add` と `tool remove` のみ |
| `--cleanup` | `rule migrate` が検証した後にレガシーファイルを削除する | `migrate` のみ |
| `--delete-source` | 削除時に、中身が `rulebook.json` だけのローカルの設定元ディレクトリも削除する | `remove` のみ |
| `--example` | 非アクティブなサンプル rulebook を作成する | `init` のみ |
| `--ref <ref>` | ブランチ、タグ、コミットを指定する | `add` のみ |
| `--only <rulebook...>` | リポジトリ内の指定した rulebook だけを追加する | `add` のみ |
| `--cwd-arg <name>` | 作業ディレクトリを渡す引数の名前を指定する | `tool add` のみ |
| `-h`, `--help` | ヘルプを表示する | すべて |

[`rule tool`](#rule-tool) は、既定のスコープがユーザー設定である唯一のサブコマンドです。そのため `--global` ではなく `--project` を受け取り、`--global` は `Unknown option for rule tool: --global` として拒否します。

ユーザーの `.cc-safety-net/` があるディレクトリでは、`<cwd>/.cc-safety-net/rules/rule.json` がユーザーのルール設定です。そのため、プロジェクトスコープに書き込むサブコマンドは、このディレクトリでの実行を拒否します。`--global` なしの `rule init`、`rule add`、`rule remove`、`rule update`、`rule sync`、`rule wrapper add`、`rule wrapper remove` は、何も書き込まないまま次のエラーを 1 行出力して `1` で終了します。

```text theme={"dark"}
<cwd>/.cc-safety-net/rules/rule.json is the user rule config, not a project rule config; use --global for the user scope, or run from a project directory
```

`rule tool add` と `rule tool remove` がこのディレクトリでの実行を拒否するのは `--project` を付けた場合だけで、修復方法にもそのフラグが示されます。

```text theme={"dark"}
<cwd>/.cc-safety-net/rules/rule.json is the user rule config, not a project rule config; drop --project for the user scope, or run from a project directory
```

読み取りの動作は変わりません。`rule list`、`rule wrapper list`、`rule tool list` はこのディレクトリでも動作し、`--global` を付けたサブコマンドも同じです。[`rule migrate`](#rule-migrate) には `--global` がなく、このディレクトリでの扱いも異なります。

`--check` は受け付けなくなりました。どのサブコマンドでも `Unknown option for rule: --check` として拒否されます。rulebook は毎回ディスクから読み込まれるため、`add` や `update` のドライランに意味を持たせるには、結局その候補を取得して検証するほかありません。オフラインでの検証には [`rule verify`](#rule-verify) を使います。

### rule init

現在のスコープにルール設定を作成します。ファイルが存在する場合は、`rules`、`overrides`、`transparent_wrappers`、`command_tools` を維持したまま、正規形式に書き換えます。キャッシュディレクトリは作成しません。`rule add`、`rule remove`、`rule wrapper add`、`rule migrate` も、ファイルを書き換えるときに同じフィールドを維持します。

```bash theme={"dark"}
npx -y cc-safety-net rule init
npx -y cc-safety-net rule init --global
```

`rule init` だけを実行すると、ルールを含まない**非アクティブ**な設定を書き込みます。`example-rules` という開始用 rulebook も書き込むには、`--example` を指定します。

```bash theme={"dark"}
npx -y cc-safety-net rule init --example
```

サンプル rulebook は、`example-rules/rulebook.json` が存在しない場合にのみ書き込まれます。設定から参照されないため、**非アクティブ**です。有効にするには、`rule add example-rules` で追加します。

書き込み後、`rule init` はガードと同じ方法でスコープを読み込みます。エラーがあれば出力して `1` で終了します。問題がなければ `Rule config initialized.` を出力して `0` で終了します。

### rule add

使用方法は `rule add [source] [--ref <ref>] [--only <rulebook...>]` です。設定元には 3 つの形式があります。`project-rules` のような裸のローカル名、`acme/safety-rules` のようなリポジトリ全体、`owner/repo#ref/<rulebook-name>` という正規形式で指定する単一の rulebook です。

**オプション：**

| フラグ | 説明 |
| - | - |
| `--ref <ref>` | ブランチ、タグ、コミットを指定する |
| `--only <rulebook...>` | リポジトリ内の指定した rulebook だけを追加する |
| `-g`, `--global` | ユーザースコープのルール設定を使う |
| `-h`, `--help` | ヘルプを表示する |

**例：**

```bash theme={"dark"}
cc-safety-net rule add project-rules
cc-safety-net rule add acme/safety-rules
cc-safety-net rule add acme/safety-rules --only aws gcloud
cc-safety-net rule add acme/safety-rules --ref v2 --only aws
cc-safety-net rule add --only terraform aws
```

設定元を指定せずに `--ref` または `--only` を渡すと、公式カタログの `cc-safety-net/rulebooks` が設定元になります。どちらのフラグもない `rule add` は `rule add requires a source (pass --only <rulebook...> to select from cc-safety-net/rulebooks)` を出力して `1` で終了します。そのため、公式 rulebook をすべて追加する場合は、これまでどおり `rule add cc-safety-net/rulebooks` と明示する必要があります。

他のサブコマンドと同様に、`-g` / `--global` でユーザースコープを選択します。

リポジトリを設定元に指定した場合、`rule add` は書き込みの前に ref をコミットへ解決し、そのコミット時点のリポジトリにある `.cc-safety-net/rules/<name>/rulebook.json` をすべて列挙します。`--only` がなければ、それらを名前順ですべて追加します。`--only` を指定すると、指定した順序で該当する rulebook だけを追加し、重複は無視します。リポジトリに存在しない名前を指定すると、追加は失敗します。

`--ref` と `--only` は `owner/repo` 形式の設定元にのみ指定できます。それ以外では `--ref can only select a ref for an owner/repo source: <source>` または `--only can only select rulebooks from an owner/repo source` を出力します。`--ref` を省略した場合、`rule add` はリポジトリの既定ブランチを使います。ref には `/` を含むセグメントを指定できるため、`--ref feature/rulebook-v2` は有効です。ref 全体が `^[A-Za-z0-9._-]+(?:/[A-Za-z0-9._-]+)*$` に一致する必要があり、一致しない場合は `--ref must use valid path segments: <ref>` を出力します。

`rule.json` には、指定した ref を含む正規形式 `owner/repo#ref/<rulebook-name>` が保存されます。`rule add` は解決されたコミットを出力しますが、保存はしません。

追加に成功すると、まず `Scope: project (<config dir>)` を出力します。`--global` を付けた場合は `Scope: user (<config dir>)` で、いずれも書き込んだ `rule.json` があるディレクトリを示します。この行がなければ、誤ったディレクトリで実行した追加も成功に見えてしまいます。失敗した追加は何も書き込んでおらず、スコープの行も出力しません。

リポジトリを追加した場合は、続けて次の順序で出力します。

* `Added <n> rulebooks from <source> at <ref>:`（1 件の場合は `rulebook`）に続けて、rulebook ごとに `  - <name>` の行
* 選択した rulebook のうち `rule.json` にすでにあったものについて `Rulebooks already configured from <source> at <ref>: <names>`
* `Vendored at <commit>.`。解決されたコミットを先頭 7 文字に短縮したもので、新しい設定元を 1 つ以上書き込んだ場合にのみ出力される
* 書き込んだファイルごとに 1 ブロック。新規ファイルは `Vendored <spec> (<version>)`、既存ファイルの更新は `Updated <spec> (<before> -> <after>)` に続けて、追加・削除・名前は同じで内容が変わったルールをそれぞれ `  + <rule>`、`  - <rule>`、`  ~ <rule>` の行で表示
* `Rule config updated.`、空行、`Active rulebooks (<n>):`。各エントリは `  - <name> <version> (<n> rules)` と `    Source: <spec>`

裸のローカル名または正規形式 `owner/repo#ref/<rulebook-name>` の設定元では、スコープの行はそのまま出力され、上記の最初の 3 項目は省かれます。リポジトリ追加で `Rule config updated.` が出る位置には、`Added rulebook source: <source>` が出力されます。

### rule remove

rulebook の設定元を削除して同期します。ローカルの設定元ディレクトリの中身が `rulebook.json` だけの場合に、そのディレクトリも削除するには `--delete-source` を追加します。

```bash theme={"dark"}
npx -y cc-safety-net rule remove project-rules
npx -y cc-safety-net rule remove project-rules --delete-source
```

`--delete-source` は、ディレクトリの中身が `rulebook.json` だけであることを 2 回確認します。1 回目は同期の前、2 回目は削除の直前です。その間の同期で、GitHub からの取得を待つことがあるためです。

* その間に別のプロセスがファイルを追加した場合、2 回目の確認が削除を拒否し、`Local rulebook source directory contains extra files: <dir>. delete manually if you really want to remove the directory.` を出力します。設定の変更はロールバックされて再同期されるため、削除しようとした設定元は元に戻ります。
* 削除は再帰的ではありません。検証済みの `rulebook.json` を削除してから、非再帰の `rmdir` でディレクトリ自体を削除します。unlink の後にファイルが追加されると `rmdir` が失敗し、そのファイルはそのまま残ります。削除されるのは rulebook ファイルだけです。
* 削除の時点でディレクトリがすでにない場合は、削除をスキップして成功として報告します。求められた最終状態に達しているためです。

### rule update

すべての設定元について、リモート rulebook を再取得して取り込みます。設定元を 1 つ指定した場合は、その設定元だけを対象にします。

```bash theme={"dark"}
npx -y cc-safety-net rule update
npx -y cc-safety-net rule update project-rules
```

実行のたびにブランチとタグの ref を解決し直すため、`main` や移動するタグを指している設定元は現在のコミットを取り込みます。ローカルの設定元には取得するものがありません。設定元はすべてレポートに現れますが、再取得されるのは選択した設定元だけで、残りはディスク上のファイルから読み込まれます。出力される変更ブロックは [`rule add`](#rule-add) と同じで、その後に `Rule config updated.` とアクティブな rulebook の一覧が続きます。

各設定元は独立して更新されます。取得や検証に失敗した設定元は、すでに取り込んである内容をそのまま保持し、`Failed to update <spec>: <message>` として報告されます。更新に成功した他の設定元は書き込まれます。1 つでも失敗した場合は `1`、それ以外は `0` で終了します。

例外はリソース制限による失敗です。GitHub の取得予算を使い切った実行は `Rule synchronization exceeds CC Safety Net's safe resource limits.` を出力して停止し、上限に達した設定元だけでなく、その実行に含まれるすべての設定元が失敗します。

### rule sync

<Warning>
  `rule sync` は非推奨です。rulebook はライブファイルであり、同期するものはありません。この実行は、以前のバージョンが書き込んだ `rule.lock` ファイルと `cache` ディレクトリをオフラインで移行し、その後どちらも削除します。
</Warning>

```bash theme={"dark"}
npx -y cc-safety-net rule sync
```

実行は必ず次の非推奨の通知から始まります。

```text theme={"dark"}
`cc-safety-net rule sync` is deprecated: rulebooks are live files that need no synchronization. This run only migrates the lock and cache an earlier version left behind.
```

ネットワークからは何も取得しません。記録されたダイジェストと一致するキャッシュのコピーは `<config-dir>/<name>/rulebook.json` に書き込まれ、`Vendored <spec> from the v2 cache.` として報告されます。書き込み先のファイルは存在するものの使用できない場合は、`Restored <spec> from the v2 cache over an invalid file.` になります。キャッシュから復元できない設定元については ``Could not migrate <spec> from the v2 cache. Run `cc-safety-net rule update <spec>` to vendor it.`` を出力します。ユーザースコープでは、このコマンドに ` --global` が付きます。最後の行は `Removed the v2 lock and cache under <dir>.` です。

移行するものがない場合は、`No v2 lock or cache leftovers found in <dir>; nothing to migrate.` を出力して `0` で終了します。これらのファイルが残っているのにスコープの `rule.json` が存在しないか読み取れない場合は、設定元の唯一の記録を失わないように移行を拒否し、`Cannot migrate: the rules config in <dir> is missing or unreadable while v2 leftovers remain. Restore rule.json, then re-run rule sync.` を出力して `1` で終了します。

`doctor` は、残っているこれらのファイルを `info` 重大度の finding `config.v2-leftovers` として報告します。

### rule list

ユーザースコープとプロジェクトスコープの両方について、有効な rulebook と解決済みの設定元を一覧表示します。

```bash theme={"dark"}
npx -y cc-safety-net rule list
```

`rule list` は両方のスコープを一度に読み取るため、`--global` は拒否されます。ポリシーの**エラー**がある場合だけ `1` で終了します。警告は出力されますが、終了コードは `0` です。

`Active rules` では、どのルールも `  Command:` の行と `  Reason:` の行を出力します。その間の行は、ルール自身の rulebook のバージョンによって変わります。バージョン 1 のルールは、サブコマンドを設定していれば `Command:` に `<command> <subcommand>` を表示し、ブロック対象の引数を `  Block args:` に表示します。`rulebook_version: 2` のルールは、`Command:` にコマンド名と `match.command_path` の語を並べて表示し、設定されているものだけ `  Any args:` と `  Exclude args:` を出力します。`Block args:` の行は出力しません。

```text theme={"dark"}
Active rules (1):
  - [project] infra/block-terraform-destroy
      Command: terraform apply
      Any args: -destroy, --destroy
      Exclude args: --dry-run
      Reason: Review a destroy plan first.
```

### rule wrapper

transparent wrapper を管理します。これは引数を別のコマンドへ渡すコマンドであり、CC Safety Net はラッパー自体ではなく内部のコマンドを解析します。

```bash theme={"dark"}
npx -y cc-safety-net rule wrapper list
npx -y cc-safety-net rule wrapper add rtk
npx -y cc-safety-net rule wrapper remove rtk
```

* 操作の指定は必須で、`add`、`remove`、`list` のいずれかでなければなりません。
* `wrapper list` は追加の引数を受け取りません。`Transparent wrappers: (none)` または番号付きリストを出力します。
* `wrapper add` と `wrapper remove` は、それぞれ正確に 1 つのコマンド名が必要です。
* ラッパー名は `^[a-zA-Z][a-zA-Z0-9_-]*$` に一致する必要があります。予約済みコマンドはラッパーとして登録できません。
* `add` は重複を除去し、`remove` はフィルタリングします。スコープは `-g` / `--global` に従います。

登録済みのラッパーは、[explain トレース](/docs/ja/reference/explain-trace)に `transparent-wrapper` のステップとして表示されます。

### rule tool

CC Safety Net に解析させたい、コミュニティ製のシェルツールを宣言します。連携は、宣言するまでプラグインのシェルツールを未知のツールとして振り分けるため、その `command` はパースされません。宣言すると実行時に何が変わるかは、[コミュニティ製のシェルツール](/docs/ja/configuration/custom-rules#community-shell-tools)を参照してください。

```bash theme={"dark"}
npx -y cc-safety-net rule tool list
npx -y cc-safety-net rule tool add ops_bash ops_run_background
npx -y cc-safety-net rule tool add ops_run_background --cwd-arg dir
npx -y cc-safety-net rule tool remove ops_bash --project
```

* 操作の指定は必須で、`add`、`remove`、`list` のいずれかでなければなりません。
* **既定はユーザースコープです。** そのため、フラグを付け忘れても、1 つのプロジェクトの外でツールが解析されなくなるのではなく、どこでも解析される状態になります。`--project` を付けるとプロジェクトの設定に書き込み、`--global` は拒否されます。
* `add` と `remove` は、それぞれ 1 つ以上の名前を受け取ります。1 回の実行で同じ名前を繰り返しても 1 つとして数え、`--cwd-arg` はその実行で指定したすべての名前に適用されます。
* すでに宣言されている名前を追加すると、そのエントリをその場で置き換えます。`--cwd-arg` を変更したり外したりするには、この方法を使います。`remove` は名前でフィルタリングし、その名前があったかどうかに関係なくファイルを書き込みます。

`add` は、1 つでも失敗すれば何も書き込みません。無効な名前と組み込みの名前はいずれも `Error: <message>` の形で赤字で出力され、コマンドは `1` で終了します。

| 名前 | メッセージ |
| - | - |
| 空、256 文字超、または空白文字か制御文字を含む | `"<name>" is not a tool name: non-empty, at most 256 characters, no whitespace or control characters.` |
| 同じ条件を満たさない `--cwd-arg` の値 | `"<name>" is not an argument name: non-empty, at most 256 characters, no whitespace or control characters.` |
| 1 つ以上の連携の組み込みシェルツール | `"bash" is a built-in shell tool of Claude Code, Codex, DeepSeek Harness, GitHub Copilot CLI, Kimi Code, OpenCode and Pi, and is already analyzed. Built-in tools cannot be declared.` |
| `read`、`Write`、`Grep`、`glob`、`apply_patch` などの組み込みファイルツール | `"<name>" is a built-in file tool, and is already analyzed. Built-in tools cannot be declared.` |

シェルツールのメッセージは、その名前を持つすべての連携をアルファベット順に列挙します。照合では大文字小文字と `-`、`_`、空白の区切りを無視するため、`Run-Shell-Command` は Gemini CLI の `run_shell_command` として拒否されます。検査の対象になるのは各連携のコマンド用ツールで、エージェントごとの一覧は[連携アーキテクチャ](/docs/ja/guides/integration-architecture)にあります。拒否するのは `add` だけなので、手作業で宣言された組み込みの名前も `rule tool remove bash` で削除できます。

`add` と `remove` は、名前ごとに 1 行を出力し、その後に、書き込んだファイルを示すスコープの行を 1 行出力します。

```text theme={"dark"}
Added command tool: ops_bash
Added command tool: ops_run_background (cwd argument: dir)
Scope: user (/Users/you/.cc-safety-net/rules/rule.json)
```

`tool list` は両方のスコープを読み取り、追加の引数を受け取りません。各エントリはスコープ付きで表示され、`Cwd argument:` の行は、それを宣言しているエントリにだけ表示されます。

```text theme={"dark"}
Command tools (3):
  - [user] ops_bash
  - [user] ops_run_background
      Cwd argument: cwd
  - [project] team_shell
```

何も宣言されていない場合は `Command tools: (none)` を出力します。ユーザー設定のディレクトリで実行した場合は、プロジェクトスコープが同じファイルを指すため、ユーザースコープを 1 回だけ列挙します。

パースできない `rule.json` があると、コマンドは処理を中止します。`tool list` は `<path>: Invalid JSON` を出力して `1` で終了します。`tool add` は `Invalid JSON` を出力して `1` で終了し、ファイルはそのまま残します。

使い方の誤りは、書き込みの前に `1` で終了します。操作を指定しない場合は `rule tool requires add, remove, or list`、その 3 つ以外を指定した場合は `Unknown rule tool action: <name>`、名前を指定しない場合は `rule tool add requires a tool name`（`remove` も同様）、`tool list` の後に引数を付けた場合は `Unexpected rule tool argument: <arg>`、その操作が受け付けないフラグを付けた場合は `Unknown option for rule tool list: --project` や `Unknown option for rule tool remove: --cwd-arg` になります。

### rule verify

レガシーパスとスキーマ種類の検出を含め、両方のスコープのルール設定ファイルを検証します。設定を手動で編集した後に使います。

```bash theme={"dark"}
npx -y cc-safety-net rule verify
```

すべて有効なら `0`、それ以外はゼロ以外で終了します。`command_tools` のエントリが組み込みのシェルツール名やファイルツール名を指している場合は、それを宣言しているスコープでエラーになり、[`rule tool add`](#rule-tool) が出力するものと同じメッセージで報告されます。

`rule verify` は純粋な検査ではなく、検証するファイルを変更することがあります。スコープの `rule.json` が正常に検証されても `$schema` キーがない場合、コマンドはそのファイルを書き換え、次の内容を最初のキーとして挿入します。

```json theme={"dark"}
"$schema": "https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json"
```

そして `Added $schema to user config.` または `Added $schema to project config.` を出力します。これは、ユーザースコープまたはプロジェクトスコープにある有効な rules-schema 設定でのみ動作します。レガシー設定またはエラーがある設定では動作しません。無効にするフラグはありません。書き換えはファイル全体を 2 スペースのインデントで再シリアライズします。そのため、CI では追跡対象ファイルに変更が残る場合があります。`rule verify` を読み取り専用にする必要がある場合は、先に `$schema` キーをコミットしてください。

### rule migrate

レガシーのインライン設定ファイル、プロジェクトの `.safety-net.json` とユーザーの `~/.cc-safety-net/config.json` を、rulebook 配置に変換します。

```bash theme={"dark"}
npx -y cc-safety-net rule migrate
npx -y cc-safety-net rule migrate --cleanup
```

`--cleanup` は、移行したルールの検証後にレガシーファイルを削除します。`migrate` は、`--global` と 2 つ目の位置引数を拒否します。

`--global` がないため、1 回の実行で両方のスコープを移行します。ユーザーの `.cc-safety-net/` があるディレクトリでは、`rule migrate` はプロジェクト側だけをスキップし、ユーザー側はそのまま移行して、次の 1 行を出力します。

```text theme={"dark"}
Skipped the project scope: <cwd>/.cc-safety-net/rules/rule.json is the user rule config, not a project rule config
```

スキップした側は成功として数えるため、終了コードはユーザー側の結果だけで決まります。

`doctor` は、移行していないレガシーファイルを `warning` 重大度の finding `config.legacy-ignored` として報告します。

### rule doc

rulebook の作成ガイドを標準出力に出力します。このガイドをエージェントにパイプで渡せば、rulebook の作成と検証を任せられます。

```bash theme={"dark"}
npx -y cc-safety-net rule doc
```

ガイドを出力した後、`rule doc` は npm レジストリに新しいバージョンがあるかを確認します。確認は 24 時間に 1 回までで、結果は `~/.cc-safety-net/update-check.json` にキャッシュされます。新しいバージョンがある場合は、標準エラー出力にちょうど 1 行だけ出力します。

```text theme={"dark"}
UPDATE_AVAILABLE: cc-safety-net v<latest> is available (running v<current>). Ask the user once whether to run `npx -y cc-safety-net@latest update`; continue the current task either way and do not raise this again.
```

ガイド自体は標準出力に出るため、パイプで渡す内容が混ざることはありません。同じバージョンについては 7 日間、再通知されません。この確認を完全に無効にするには `CC_SAFETY_NET_NO_UPDATE_CHECK` を設定します。レジストリへの問い合わせが失敗しても通知はされず、いずれの場合も終了コードは `0` のままです。

## policy

`policy` は、ポリシーの提案を検査して適用します。ポリシーファイルが持つフィールドと、それぞれの意味は[ポリシー](/docs/ja/configuration/policy)を参照してください。

| サブコマンド | 説明 |
| - | - |
| `check <file>` | ポリシー提案を検証して差分を出力する |
| `apply <file>` | ターミナルで確認してから提案を適用する |

**オプション：**

| フラグ | 説明 |
| - | - |
| `-g`, `--global` | プロジェクトポリシーではなくユーザースコープのポリシーを使う |
| `-h`, `--help` | ヘルプを表示する |

**例：**

```bash theme={"dark"}
cc-safety-net policy check proposal.json
cc-safety-net policy apply proposal.json
cc-safety-net policy apply proposal.json --global
```

対象は、プロジェクトの `.cc-safety-net/policy.json` です。`--global` を指定した場合はユーザーポリシーファイルになります。

ユーザーの `.cc-safety-net/` があるディレクトリでは、このプロジェクト側の対象がユーザーポリシーファイルそのものです。そのため `--global` なしの `policy check` と `policy apply` は、提案の読み取り、差分の出力、確認プロンプトのいずれにも進まずに実行を拒否します。次のエラーを 1 行出力して `1` で終了します。

```text theme={"dark"}
<cwd>/.cc-safety-net/policy.json is the user policy, not a project policy; use --global for the user scope, or run from a project directory
```

### 出力

どちらのサブコマンドも、`apply` が書き込む前に同じレポートを出力します。

```text theme={"dark"}
Scope: project (<path>)
Proposal: <file>
Effective policy (user + project merged):
Changes (<n>):
  <field>: <before> -> <after>
```

`--global` を指定した場合、1 行目は `Scope: user (<path>)` になります。プロジェクトスコープでは、ユーザーポリシーとプロジェクトファイルをマージした実効ポリシーについて、適用前と適用後を比較します。この差分は `Effective policy (user + project merged):` の見出しの下に並びます。設定したフィールドだけを持つ提案でも、セッションが実際に動作するレベルは変わります。そのため差分は、ファイル自体の内容ではなくその変化を報告します。`safety.level` を設定すれば実効レベルが下がるか上がり、設定しなければユーザーポリシーから継承したレベルに戻ります。ユーザースコープでは、ユーザーポリシーファイル自体を比較し、この見出しは出力しません。差分がない場合の出力は `No changes.` の 1 行だけです。片側に値がない行は `(unset)` と表示されます。

`check` は差分を出力した時点で終了し、終了コードは `0` です。

差分を出力する前に標準エラー出力へ書き出され、`1` で終了するエラーは次のとおりです。`Unknown option for policy: <arg>`、`Unknown policy subcommand: <name>`、`policy <subcommand> requires a file`、`Unexpected policy argument: <arg>`。監査設定はユーザースコープ専用のため、`audit` セクションを含むプロジェクト向けの提案も同じように拒否されます。

```text theme={"dark"}
<file>: audit settings are user scope only; remove the audit section from a project proposal
```

### 適用

`apply` は stdin と stdout の両方が TTY であることを要求します。TTY でない場合は、自分で実行するためのコマンドを出力して `1` で終了します。

```text theme={"dark"}
policy apply confirms interactively; run this yourself in a terminal:
  cc-safety-net policy apply <file>
```

`--global` を指定していた場合は、出力されるコマンドにも `--global` が付きます。

ターミナルでは、`apply` は `Apply this policy to <path>? [y/N] ` と確認します。確認とみなされるのは、大文字小文字を問わず `y` または `yes` だけです。それ以外は、プロンプトでの EOF も含めてすべて拒否として扱われ、`Cancelled; nothing was written.` を出力して `0` で終了します。確認して適用した場合はファイルを書き込み、`Policy applied: <path>` を出力して、同じく `0` で終了します。プロジェクトへの適用では、提案が設定しているフィールドだけが書き込まれます。省略したフィールドは、引き続きユーザーポリシーを継承します。

<Warning>
  `--yes` はなく、非対話モードもありません。提案を適用する方法は、ターミナルでプロンプトに答えることだけです。
</Warning>

エージェントが `policy apply` を実行した場合、ガードは intent `hard_stop` と次の理由で拒否します。

```text theme={"dark"}
Only the user may apply a policy proposal, because it rewrites the configuration CC Safety Net enforces. Ask them to run `cc-safety-net policy apply <file>` themselves in a terminal; you can run `cc-safety-net policy check <file>` to show them what it would change.
```

`policy check` は許可されたままです。エージェントは提案を作成し、その差分を提示するところまでは実行できます。

## install

`install` は、CC Safety Net をコーディングエージェント CLI にインストールします。ターゲットセットは CC Safety Net の連携カタログから取得されるため、GUI と `doctor` が使うリストと同じです。

エージェントごとの手順、インストール後の操作、レガシープラグイン ID の移行については、[インストール](/docs/ja/installation)を参照してください。

```bash theme={"dark"}
npx -y cc-safety-net install
npx -y cc-safety-net install --claude-code
```

### ターゲット

16 個のターゲットを使用できます。次の順序はインストールされる順序です。

| フラグ | エージェント | インストール方法 |
| - | - | - |
| `--amp` | Amp Code | amp CLI を使って、アカウントがホストする Amp Personal Plugins リポジトリに管理対象のプラグインを公開する |
| `--agy-cli` | Antigravity CLI | `~/.gemini/config/hooks.json` に hook エントリを書き込む |
| `--claude-code` | Claude Code | Claude Code 自身のプラグインマーケットプレイスコマンドを実行する |
| `--codex` | Codex | Codex 自身のプラグインマーケットプレイスコマンドを実行する |
| `--cursor` | Cursor | `~/.cursor/hooks.json` に hook エントリを書き込む |
| `--deepseek-harness` | DeepSeek Harness | マシン上の各プロファイルに対して `dsh plugin --profile <name> add cc-safety-net@<version>` を実行する。`web` プロファイルには `npx -y @deepseek-ai/dsh` 経由、`desktop` プロファイルにはデスクトップアプリ同梱の `dsh` 経由。`<version>` はインストーラー自身のバージョン。プロファイルの置き場所は `$DSH_HOME/profiles` または `~/.dsh/profiles` |
| `--devin` | Devin CLI | `~/.config/devin/config.json`（または `$XDG_CONFIG_HOME/devin/config.json`、Windows では `%APPDATA%\devin\config.json`）の `hooks.PreToolUse` に hook エントリを書き込む |
| `--droid` | Factory Droid | `~/.factory/hooks.json` の `PreToolUse` に hook エントリを書き込む |
| `--gemini-cli` | Gemini CLI | Gemini CLI の拡張機能インストールコマンドを実行する |
| `--copilot-cli` | GitHub Copilot CLI | Copilot CLI 自身のプラグインマーケットプレイスコマンドを実行する |
| `--grok-build` | Grok Build | `~/.grok/hooks/cc-safety-net.json`（または `$GROK_HOME/hooks/cc-safety-net.json`）に hook エントリを書き込む |
| `--hermes-agent` | Hermes Agent | `<Hermes home>/plugins/cc-safety-net` に管理対象 Python プラグインを書き込み、`hermes plugins enable` で有効にする。Hermes のホームは `$HERMES_HOME` または `~/.hermes` で、`active_profile` がプロファイルを指定していれば `profiles/<name>` に移る |
| `--kimi-code` | Kimi Code | ターミナルでは方式プロンプトの後に、`~/.kimi-code/config.toml`（または `$KIMI_CODE_HOME/config.toml`）に `[[hooks]]` ブロックを書き込む |
| `--openclaw` | OpenClaw | `openclaw plugins install <plugin dir> --force --accept-capabilities` を実行する。このコマンドがプラグインの有効化まで行う。OpenClaw 2026.8.1 以降が必要 |
| `--opencode` | OpenCode | OpenCode 自身のプラグインコマンドを実行する。1.x では `opencode plugin -g -f`、2.x では `opencode plugin add` と `opencode plugin update` |
| `--pi` | Pi | Pi のパッケージインストールを実行する |

### インストールの仕組み

CC Safety Net は、3 つのインストール方法を使います。

* **ネイティブのプラグインまたは拡張機能のコマンド**：Claude Code、Codex、DeepSeek Harness、GitHub Copilot CLI、Gemini CLI、OpenClaw、OpenCode、Pi。CC Safety Net はエージェント自身のプラグインマネージャーを実行し、置き換えられた古いプラグイン ID を削除します。DeepSeek Harness のインストールは、プロファイルごとに `dsh plugin ... add` を実行し、その後プロファイルのマニフェストを読み直します。ホストがバンドルをインストールしても有効にしていない場合は失敗します。OpenClaw のインストールは、その後に OpenClaw がプラグインを読み込み済みと報告することも確認し、OpenClaw Gateway の再起動を求めます。OpenCode 1.x のインストールは、キャッシュ済みパッケージのエントリを import し、呼び出し可能な `CCSafetyNetPlugin` を export することを確認します。2.x では `opencode plugin list` を読み取り、ソースが `cc-safety-net@latest` の `cc-safety-net` の行があることを要求します。どちらの確認も、失敗すればインストールは中止されます。そのまま進めると、OpenCode が何も読み込まず fail open になるためです。
* **設定ファイルへの書き込み**：Antigravity CLI、Cursor、Devin CLI、Factory Droid、Grok Build、Kimi Code。CC Safety Net がエージェントの設定を直接編集するのは、この 6 つだけです。
* **管理対象プラグイン成果物**：Amp Code と Hermes Agent。Amp のプラグインは、amp CLI を通じてアカウントのホスト型 Amp Personal Plugins リポジトリに公開されます（事前確認は `amp plugins repositories --json`）。そのため、インストールには amp CLI と `amp login` が必要です。公開されたプラグインは、Orb スレッドを含むすべての Amp セッションに適用されます。`~/.config/amp/plugins/cc-safety-net.ts` に管理対象のローカルコピーが残っているとパーソナルプラグインを覆い隠すため、インストール時に削除されます。変更後は Amp を再起動するか `plugins: reload` を実行します。Hermes Agent では、インストール時にプラグインをディスクに書き込んで `hermes plugins enable` も実行し、変更後に Hermes の再起動が必要です。

Antigravity CLI、Cursor、Devin CLI、Factory Droid、Grok Build、Kimi Code の設定ファイルへのインストールと、Hermes Agent へのインストールでは、何かを書き込む前に `npx` キャッシュから古い `cc-safety-net` を削除します。npm キャッシュの `_npx` ディレクトリ（`$npm_config_cache` が設定されている場合はその場所。それ以外は macOS と Linux で `~/.npm`、Windows で `%LOCALAPPDATA%\npm-cache`）の下にあり、`node_modules` が `cc-safety-net` を含むすべてのエントリを削除します。この 7 つの連携は `npx` で hook を実行するため、この処理により、新しくインストールした hook はキャッシュ済みのバージョンではなく最新版を解決します。

**Kimi Code には 2 つのインストール方式があります。** ターミナルで `install --kimi-code` を実行するか、ピッカーで Kimi Code を選択すると、単一選択プロンプトが開きます。グローバル hook を今インストールするか、代わりにネイティブ Kimi プラグインの手順を表示するかを選びます（Kimi Code 内で `/plugins install https://github.com/kenryu42/cc-safety-net/tree/plugin` を実行し、次に `/reload` を実行するか新しいセッションを開始します。信頼プロンプトの既定はキャンセルです）。プラグイン方式を選んでも何も書き込まれず、手順を表示するだけです。非対話セッションではプロンプトをスキップして、グローバル hook を直接インストールします。このプロンプトがプラグイン手順への唯一の経路であるため、グローバル hook が設定済みでも install 時の Kimi Code の行は選択可能なままで、`(global hook installed)` と表示されます。

### ターゲットの選択

* **フラグなしの対話型ターミナル：** 矢印キーを使う複数選択プロンプトが表示されます。各ターゲットの使用可否を調べます。そのため、エージェントがインストールされていない場合は `CLI not installed`、設定済みの場合は `already installed`、uninstall 時に未設定の場合は `not installed` と表示されます。Windows では、この使用可否の検査もインストール自体も npm の `.cmd` シムをシェル経由で解決するため、npm でインストールした CLI が `CLI not installed` と表示されることなく検出されます。使用可否の検査が 2 つあるターゲットは Cursor だけです。まず `cursor --version` を実行し、それが失敗したときにかぎり `cursor-agent --version` を実行します。そのため、`cursor` バイナリがなくスタンドアロンの `cursor-agent` CLI だけがあるマシンでも Cursor を選択できます。
* **ターゲットフラグあり：** 正確に 1 つのターゲットフラグを指定します。複数指定すると `Choose exactly one install|uninstall target:` の後に完全なフラグリストを表示します。不明な `-` 引数と余分な位置引数もエラーです。

セレクターのキーバインドはフッターに表示されます。install 時のフッターは次のとおりです。

```text theme={"dark"}
Space: select  Enter: confirm  u: update installed  Up/Down: move  q/Esc: cancel
```

`Space` は強調表示したターゲットの選択を切り替えます。`Enter` は確定します。何も選択されていない場合はターミナルベルを鳴らすだけです。`Up` / `Down` または `k` / `j` は、選択可能な行の間を移動します。install 時に `u`（または `U`）を押すとセレクターを終了して [`update`](#update) フローを実行します。uninstall のフッターにはこのキーがありません。`q` または `Esc` で終了すると、`Cancelled: nothing was installed.`（または `Cancelled: nothing was uninstalled.`）を出力し、`0` で終了します。終了は判定であり、失敗ではありません。一方、`Ctrl-C` は `SIGINT` を送出するため、通常の中断されたプログラムと同じ方法でプロセスが終了します。

選択したターゲットは、選択した順序ではなく、常にカタログのインストール順で実行されます。ターミナルでは、各ターゲットは `Installing <name> integration…` または `Uninstalling <name> integration…` というスピナーの後ろで実行され、スピナーが止まった後にレポートが表示されます。TTY でない場合、スピナーはありません。120 秒経っても終わらないホスト CLI のコマンドは強制終了され、失敗として報告されます。失敗すると、権限問題、パス不足、ディレクトリではないパス要素など、エラー固有のヒントとともに `1` で終了します。

## update

`update` は、インストール済みのすべての連携を更新します。新しい連携をインストールすることはありません。設定していないエージェントには触れません。

```bash theme={"dark"}
npx -y cc-safety-net@latest update
```

TTY で `update` を直接実行すると、インストールバナーを表示する前に検出を開始するため、バナーのアニメーション中にも検出が進みます。バナーの後も検出が続く場合は、`Checking installed integrations…` を表示します。`Enter` を押すとアニメーションをスキップできます。対話型の `install` セレクターで `u` を押して update を開始した場合、すでに表示したバナーを使い、2 つ目のバナーは表示しません。TTY でない場合、バナーとスピナーは表示しません。

ターゲットは、各エージェントの設定ファイルと状態ファイルを読み取って検出します。現在無効な場合でも、インストール済みと検出される連携が対象です。Amp Code は `amp plugins list` の出力によって対象になります。この出力は、`codex plugin list` と同じく 30 秒のタイムアウトで取得します。コールドラン時は checkout をネットワーク経由で更新するため、既定の 5 秒を超えることがあるからです。GitHub Copilot CLI は例外です。Copilot の `installed-plugins` ディレクトリに CC Safety Net プラグインの checkout がある場合だけ対象になります。無効状態と、何もインストールされていない kill-switch 状態を区別できず、update が install になることを防ぐためです。改名前の `safety-net@cc-marketplace` プラグイン ID を使うインストール（Claude Code、Codex、および GitHub Copilot CLI のプラグイン checkout `cc-marketplace/safety-net`）も検出されます。更新時に現在の ID へ移行し、レガシーコピーをベストエフォートで削除します。レガシーコピーの削除に失敗しても、ターゲットは失敗せず警告になります。`doctor` が [Claude Code プラグイン](#cursor-through-the-claude-code-plugin)または[ネイティブ Cursor プラグイン](#cursor-through-a-native-cursor-plugin)経由でしか数えていない Cursor は対象外です。そのため、`update` がこの Cursor に hook を書き込むことはありません。

すべてのターゲットは、1 つの `Updating <n> integration…` または `Updating <n> integrations…` スピナーの後ろで、`install` と同じ操作を並列に実行します。すべてのターゲットが完了した後、レポートを安定したカタログ順でまとめて出力します。メッセージだけが `Updated …` または `… up to date` に変わります。インストール時にエージェント自身の CLI を使うターゲットでは、先にベンダーバイナリを調べます。対象は Claude Code、Codex、GitHub Copilot CLI、Gemini CLI、Hermes Agent、OpenClaw、OpenCode、Pi です。バイナリがない場合は `<Agent> not found; skipped`（例は `Codex not found; skipped`）を出力して処理を続けます。設定ファイルを使うターゲット、つまり Antigravity CLI、Cursor、Devin CLI、Factory Droid、Grok Build、Kimi Code にはバイナリが不要で、常に更新されます。DeepSeek Harness もバイナリは調べません。更新では install を再実行し、プロファイルごとに `dsh` を動かします。デスクトップアプリが起動中の場合は失敗します。Amp Code には別途の検査は不要です。`amp plugins list` がパーソナルプラグインを表示する場合にのみ検出され、その更新は amp CLI を実行して現在の成果物を公開します。Claude Code、Codex、GitHub Copilot CLI では、登録済みのマーケットプレイスをプラグイン処理の前に更新します（例は `claude plugin marketplace update cc-marketplace`）。何もしない `add` に頼らないため、古いカタログ checkout が更新を失敗させることはありません。

並列処理の前に、キャッシュに依存するターゲット（Antigravity CLI、Cursor、Devin CLI、Factory Droid、Grok Build、Hermes Agent、Kimi Code）が 1 つでもある場合、`update` は `npx` キャッシュを 1 回消去します。消去に失敗した場合、そのキャッシュに依存するターゲットだけが失敗し、ほかのターゲットは実行を続けます。

`bunx` キャッシュの消去は無条件です。`bunx cc-safety-net` は連携ではなくユーザー自身が実行するものなので、対象の連携が 1 つも見つからない実行も含め、`update` は毎回このキャッシュから自分の `cc-safety-net` のエントリを消去します。

`bunx` は各パッケージを、OS の一時ディレクトリの下に `bunx-<uid>-<package>@<version-or-latest>` という名前でインストールします。消去の対象はこの名前で判定します。macOS と Linux では、自分の uid と一致するものだけが対象です。Windows では `%TEMP%` がユーザーごとに分かれているため、任意の数値 ID が対象になります。末尾の `@` があるため、`cc-safety-net-*` のような似た名前は対象になりません。実行中のプロセス自身のエントリは対象から除外されます。そのため、`bunx` から起動した `update` が自分のファイルを削除することはありません。除外されたエントリは、bun 自身のマニフェスト TTL によって再解決されます。消去に失敗した場合は、エラーを出力して `1` で終了します。

対象がない場合、`update` は ``No installed integrations found. Run `cc-safety-net install` to set one up.`` を出力して `0` で終了します。この実行が `1` で終了するのは、`bunx` キャッシュの消去に失敗した場合だけです。

npm レジストリに新しいリリースがある場合、`update` は最後にベストエフォートで次の案内を出力します。

```text theme={"dark"}
Update available: cc-safety-net <current> → <latest>. Update this CLI with your package manager, e.g. `npm i -g cc-safety-net@latest` for a global install.
```

この案内は、永続的にインストールした CLI に向けたものです。`npx` と `bunx` での実行は一時的なもので、上記のキャッシュ消去によってすでに最新版に更新されるため、レジストリの確認自体をスキップします。一時的な実行かどうかは、パスに `_npx` のセグメントがあるか、bun の実際のキャッシュ名 `bunx-<digits>-` に一致するセグメントがあるかで判定します。数字を伴わない `bunx-` を含むだけのパス（たとえば `/opt/bunx-tools`）は永続的なインストールとして扱われ、案内が出ます。確認に失敗した場合、オフラインの場合、開発ビルドの場合は、何も出力されず終了コードも変わりません。

`update` はターゲットフラグも引数も受け取りません。使用できるのは `-h` / `--help` だけです。ほかのオプションは `Unknown option for update: <flag>`、位置引数は `Unexpected argument for update: <arg>` を出力し、どちらも `1` で終了します。1 つのターゲットが失敗しても実行は止まりません。エラーは `install` と同じヒントとともに表示され、update は残りのターゲットを続行し、いずれかのターゲットが失敗していれば最後に `1` で終了します。それ以外の終了コードは `0` です。

対話型の `install` セレクターで `u` を押して、update フローへ移ることもできます。

## uninstall

`uninstall` は、`install` と同じ 16 個のターゲットフラグを受け取り、同じ選択ルールとターゲット順序を使います。

```bash theme={"dark"}
npx -y cc-safety-net uninstall
npx -y cc-safety-net uninstall --cursor
```

設定ファイルを使うターゲットでは、uninstall は CC Safety Net が管理するエントリだけを削除します。エントリは CC Safety Net 固有の hook コマンド文字列で照合され、ファイル内のほかのものは変更しません。

設定エントリ以外のものまで削除するターゲットは Cursor だけです。`~/.cursor/plugins/cache/cc-safety-net` または `~/.cursor/plugins/marketplaces/github.com/kenryu42/cc-safety-net` がある場合、`uninstall --cursor` は `cursor-agent plugin marketplace remove cc-safety-net` も実行し、その後どちらのディレクトリも削除します。出力に `No marketplace matches` を含む失敗は、すでに削除済みとして扱います。このとき、レポートには次の 2 行が追加されます。

```text theme={"dark"}
Removed the cc-safety-net marketplace from your Cursor account.
If /plugins in cursor-agent still lists CC Safety Net as installed, uninstall it there.
```

どちらのディレクトリもない場合、`uninstall --cursor` は `cursor-agent` コマンドを実行せず、hook のレポートだけを表示します。詳しくは[ネイティブ Cursor プラグイン経由の Cursor](#cursor-through-a-native-cursor-plugin)を参照してください。

## hook

`hook` は、CC Safety Net をエージェントのランタイム hook として実行します。エージェントの hook 入力を標準入力から JSON として読み取り、そのエージェントの拒否形式を出力します。通常は手動で実行しません。エージェントのプラグインまたは設定が接続します。保護の背後にあるコマンドです。

`hook` には正確に 1 つの連携フラグが必要です。フラグがない場合、または複数ある場合は、`hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code` とコマンドヘルプを表示し、`1` で終了します。

| フラグ | エージェント | hook イベント | レガシーフラグ |
| - | - | - | - |
| `-ac`, `--agy-cli` | Antigravity CLI | `PreToolUse` | 該当なし |
| `-cc`, `--coding-cli` | Coding CLI（Claude Code） | `PreToolUse` | `--claude-code`。最上位形式の `cc-safety-net -cc` と `cc-safety-net --claude-code` も含む |
| `-cx`, `--codex` | Codex | `PreToolUse` | 該当なし |
| `-cu`, `--cursor` | Cursor | `preToolUse` | 該当なし |
| `-dv`, `--devin` | Devin CLI | `PreToolUse` | 該当なし |
| `-fd`, `--droid` | Factory Droid | `PreToolUse` | 該当なし |
| `-gc`, `--gemini-cli` | Gemini CLI | `BeforeTool` | 最上位形式の `cc-safety-net -gc` と `cc-safety-net --gemini-cli` |
| `-cp`, `--copilot-cli` | GitHub Copilot CLI | `PreToolUse` | 最上位形式の `cc-safety-net -cp` と `cc-safety-net --copilot-cli` |
| `-gb`, `--grok-build` | Grok Build | `PreToolUse` | 該当なし |
| `-ha`, `--hermes-agent` | Hermes Agent | `pre_tool_call` | 該当なし |
| `-kc`, `--kimi-code` | Kimi Code | `PreToolUse` | 該当なし |

Coding CLI の hook だけは、許可と拒否以外の答えを返せます。Claude Code の `default`、`acceptEdits`、`plan` の permission mode では、standard レベルで検証できなかったコマンドに対して `hookSpecificOutput.permissionDecision: "ask"` を出力し、Claude Code がユーザーに確認します。それ以外のフラグと、それ以外の permission mode では拒否の形式を出力します。[Claude Code が拒否ではなく確認を求める場合](/docs/ja/guides/integration-architecture#when-claude-code-asks-instead-of-denying)を参照してください。

Amp Code、DeepSeek Harness、OpenClaw、OpenCode、Pi には、独自の `hook` フラグがありません。いずれも、プラグインまたは拡張機能として CC Safety Net をプロセス内に読み込みます。各エージェントの接続方法については、[連携アーキテクチャ](/docs/ja/guides/integration-architecture)を参照してください。

<Note>
  `hook install` または `hook uninstall` サブコマンドはありません。インストールは最上位の [`install`](#install) と [`uninstall`](#uninstall) コマンドが処理します。
</Note>

### Antigravity CLI エントリーポイント

`install --agy-cli` は、コマンド `npx -y cc-safety-net hook --agy-cli` を `~/.gemini/config/hooks.json` に書き込みます。Antigravity は `.gemini` ディレクトリを共有します。管理対象エントリの名前は `cc-safety-net` で、30 秒のタイムアウトを持つ `PreToolUse` のコマンド hook を登録します。install は、ファイルがない場合は作成し、無効な管理対象エントリがある場合は再度有効にし、それ以外は新しいエントリを追加します。uninstall は、コマンドが管理対象の文字列と一致するエントリだけを削除します。

実行時に、hook は Antigravity の `run_command` ツール呼び出しを読み、`conversationId` からセッション ID を取得し、`{ "decision": "deny", "reason": … }` で拒否します。

### Cursor エントリーポイント

`install --cursor` は、コマンド `npx -y cc-safety-net hook --cursor` を `~/.cursor/hooks.json` の `hooks.preToolUse` に書き込みます。`"version": 1` のドキュメントで、30 秒のタイムアウトと `failClosed: true` を設定します。インストーラーはドキュメントのバージョンと形式を検証し、認識できないものを書き換えず、説明付きエラーで失敗します。重複する管理対象エントリは 1 つにまとめられます。

Claude Code プラグインの Cursor 用マニフェストも同じフラグを使い、`node "${CURSOR_PLUGIN_ROOT}/dist/bin/cc-safety-net.js" hook --cursor` を実行します。詳しくは [Cursor のインストール](/docs/ja/installation#cursor-installation)を参照してください。

実行時、hook は Cursor の `Shell` ツール呼び出しを読み取り、`conversation_id` からセッション ID を取得して、`{ "permission": "deny", … }` または `{ "permission": "allow" }` を返します。Cursor の `working_directory` フィールドは、ワークスペースのルート内に収まっているかを検査されます。宣言されているのに値がない場合、またはワークスペースのルートの外を指す場合は fail closed になります。

Windows では、Cursor が `/C:/Users/you` のような VS Code の URI 形式でパスを渡します。そこで hook は、`workspace_roots`、`cwd`、`working_directory` を解決する前に、先頭の `/<drive-letter>:` の後ろに `/`、`\`、文字列の終端のいずれかが続く場合、その部分を `<drive-letter>:/` へ書き換えます。後ろに続く区切り文字も書き換えの対象に含まれます。そのため `/C:/Users/you` は `C:/Users/you`、`/C:\Users` は `C:/Users` として解決され、`/C:` だけならドライブのルート `C:/` になります。書き換わるのは先頭のこの部分だけで、ドライブレターの大文字小文字はそのままです。`/c/x` のような MSYS 形式のパス、POSIX パス、Windows 本来のドライブレター表記は変わりません。Windows 以外のプラットフォームでは、どのパスも書き換えません。

### Devin CLI エントリーポイント

`install --devin` は、コマンド `npx -y cc-safety-net hook --devin` を `~/.config/devin/config.json`（`XDG_CONFIG_HOME` が設定されている場合は `$XDG_CONFIG_HOME/devin/config.json`、Windows では `%APPDATA%\devin\config.json`）の `hooks.PreToolUse` に書き込みます。管理対象エントリは `{ "hooks": [{ "type": "command", "command": "npx -y cc-safety-net hook --devin", "timeout": 30 }] }` です。マッチャーがないため、すべてのツール呼び出しが hook に届きます。install は、ファイル内のほかのキー、ほかの hook イベント、管理対象外の `PreToolUse` エントリとハンドラーをそのまま残します。

既存ファイルの読み取りでは、`//` コメント、`/* */` コメント、末尾のカンマを取り除きます。Devin CLI が `config.json` でこれらを受け付けるためです。書き戻すのは通常の JSON なので、ファイルに残しておいたコメントは install の後には残りません。パースできないファイル、JSON オブジェクトでないファイル、`hooks` または `hooks.PreToolUse` の型が合わないファイルでは、install は何も書き込まず中止します。メッセージは[管理対象 hook の設定ずれ](#managed-hook-drift)に挙げたものです。uninstall は管理対象のハンドラーだけを取り除き、ファイルは残します。

実行時、hook は Devin CLI の `PreToolUse` の入力（`tool_name`、`tool_input`、`session_id`）を読み取ります。`hook_event_name` が `PreToolUse` でない入力は無視します。コマンドツールは `exec` だけで、そのシェルの方言は自動判定します。`write_to_process` の呼び出しも、`text_input` が空でない文字列であればシェルコマンドとして解析します。これにより、実行中のプロセスに入力したコマンドも対象になります。`bytes_input` だけを持つ `write_to_process` は、コマンド以外の呼び出しとして扱います。入力に `cwd` フィールドはないため、セッションのディレクトリは hook プロセス自身の作業ディレクトリです。正規化できないディレクトリは fail closed になります。拒否時は `{"decision": "block", "reason": …}` を返します。許可時は何も出力しないため、Devin CLI 自身の権限確認のプロンプトがそのまま働きます。

### Factory Droid エントリーポイント

`install --droid` は、コマンド `npx -y cc-safety-net hook --droid` を `~/.factory/hooks.json` の `PreToolUse` に書き込みます。管理対象エントリは `{ "hooks": [{ "type": "command", "command": "npx -y cc-safety-net hook --droid", "timeout": 30 }] }` です。マッチャーも `commandRegex` もないため、`Execute` だけでなくすべてのツール呼び出しが hook に届きます。`hooks.json` がまだない場合、install は `~/.factory/settings.json` の `hooks` オブジェクトを引き継いで新しいファイルを作るため、Factory Droid がすでにそこから読み込んでいる hook は新しいファイルにも残ります。install は、`hooks.json` 内のほかのキーと、管理対象外の `PreToolUse` エントリやハンドラーをそのまま残します。

認識できないファイルでは、install は何も書き込まず中止します。メッセージは `Failed to parse Factory Droid hooks config <path>: <reason>`、`Factory Droid hooks config <path> must be a JSON object`、`Factory Droid hooks config <path> "PreToolUse" must be an array` のいずれかです。

uninstall は管理対象のハンドラーだけを取り除きます。`hooks.json` を削除するのは、取り除いた結果 `PreToolUse` が空になり、`PreToolUse` がそのファイルの唯一のキーであり、かつ `~/.factory/settings.json` が存在しない場合だけです。その settings ファイルがある場合、uninstall は `hooks.json` を書き直します。ファイルを消すと、Factory Droid が `settings.json` の hook を再び読み込んでしまうためです。

実行時、hook は Factory Droid の `PreToolUse` の入力（`tool_name`、`tool_input`、`cwd`、`session_id`）を読み取ります。コマンドツールは `Execute` だけで、そのシェルの方言は自動判定します。セッションのディレクトリは入力の `cwd` で、入力に `cwd` がない場合は hook プロセス自身の作業ディレクトリです。正規化できないディレクトリは fail closed になります。拒否時は `hookSpecificOutput.permissionDecision: "deny"` を返し、理由は `permissionDecisionReason` に入ります。これは Coding CLI の hook と同じ出力形式です。許可時は何も出力しないため、Factory Droid 自身の権限確認のプロンプトがそのまま働きます。

### Grok Build エントリーポイント

`install --grok-build` は、コマンド `npx -y cc-safety-net hook --grok-build` を `~/.grok/hooks/cc-safety-net.json`（`GROK_HOME` が設定されている場合は `$GROK_HOME/hooks/cc-safety-net.json`）に書き込みます。30 秒のタイムアウトを持ち、マッチャーのない `PreToolUse` エントリです。そのため `run_terminal_command` だけでなく、すべてのツール呼び出しが hook に届きます。install が書き換えるのは管理対象のエントリだけです。管理対象外のエントリ、同じエントリ内の管理対象外のハンドラー、ほかの hook イベントはそのまま残ります。パースできないファイルは、正規の内容に修復します。Grok Build はパースできない hook ファイルを丸ごと読み飛ばすため、そのようなファイルが動作する管理対象外の hook を保持していることはないからです。uninstall は管理対象のハンドラーだけを取り除き、ファイルを削除するのは、ほかに何も残らない場合だけです。

実行時、hook は Grok Build の camelCase の入力（`toolName`、`toolInput`、`sessionId`、`cwd`、`workspaceRoot`）を読み取ります。コマンドツールは `run_terminal_command` だけで、そのシェルの方言は自動判定します。セッション ID は `sessionId` から取得し、Grok Build が読み取る唯一の形式である `{ "decision": "deny", "reason": … }` または `{ "decision": "allow" }` を返します。`toolInputTruncated: true` は fail closed になります。Grok Build はツール入力を 128 KB で切り詰めるため、切れたコマンドは解析できないからです。信頼するルートは `workspaceRoot` で、`workspaceRoot` がない場合は `cwd` です。`cwd` は、正規化した結果がそのルートの内側のディレクトリでなければなりません。`cwd` がない場合や空の場合は `.` として扱います。ルートを正規化できない場合、または `cwd` がルートの外を指す場合は fail closed になります。

## gui

`gui` は、ローカルのポリシーエディターを起動し、ブラウザーで開きます。ダッシュボードのビューと確認動作については、[ダッシュボード](/docs/ja/guides/dashboard)を参照してください。

```bash theme={"dark"}
npx cc-safety-net gui
npx cc-safety-net gui --no-open
```

### オプション

| フラグ | 説明 |
| - | - |
| `--no-open` | ブラウザーを起動せずにサーバーを起動し、URL を出力する |
| `-h`, `--help` | ヘルプを表示する |

`gui` が受け取る引数は `--no-open` だけです。ほかの引数は、オプションなら `Unknown option for gui: <arg>`、位置引数なら `Unexpected argument for gui: <arg>` というエラーを出力し、次に `Usage: cc-safety-net gui [--no-open]` を出力して `1` で終了します。

サーバーは常に先に起動し、フラグの有無に関係なく、URL は常に `CC Safety Net policy GUI: <url>` として出力されます。`--no-open` はブラウザーの起動だけを抑制します。ブラウザーの起動失敗は致命的ではありません。`gui` は手動で開く URL を出力し、サーバーは動作を続けます。

サーバーは `127.0.0.1` の一時ポートにバインドし、実行のたびに新しいトークンを生成します。そのため URL は `http://127.0.0.1:<port>/?token=<token>` のような形になります。すべてのリクエストにトークンが必要で、書き込みを伴うリクエストではヘッダーにもトークンを付ける必要があります。プロセスは、中断するまで動作し続けます。

## statusline

`statusline` は、エージェントのステータスバー向けに、CC Safety Net の現在の状態を絵文字インジケーターの 1 行として出力します。`--claude-code`（短縮形 `-cc`）が必要です。ない場合はエラーになり、ヘルプを表示して `1` で終了します。

```bash theme={"dark"}
bunx cc-safety-net statusline --claude-code
# -cc is the short form of --claude-code
bunx cc-safety-net statusline -cc
```

プラグインが無効な場合、この行は `🛡️ CC Safety Net ❌` になります。それ以外の場合はレベルを絵文字で表します。standard は `✅`、strict は `🔒`、paranoid は `👁️`、customised は `🔧` です。worktree の緩和が有効な場合は `🌳` が、プロジェクトポリシーによる緩和が適用されている場合は `🔻` が、ポリシーのスナップショットが degraded の場合は末尾に `⚠️` が付きます。`CC_SAFETY_NET_PROJECT_TIGHTEN_ONLY` で無視された緩和には `🔻` は付きません。

入力がパイプされると、`statusline` は標準入力を読み取ります。Claude Code の JSON ステータスペイロードは破棄します。それ以外のパイプされたテキストは維持し、`<stdin> | <status>` としてインジケーターの前に置きます。

`statusline` と [`status`](#status) は、同じポリシースナップショットと環境モードを使います。出力形式は異なります。ターミナルレポートには `status`、プログラムまたはステータスバーには `statusline` を使います。

設定手順と各インジケーターの意味については、[ステータスライン](/docs/ja/configuration/status-line)の設定ページを参照してください。

## グローバルオプション

いつでもインストール済みバージョンを確認し、使用方法を表示できます。`--version` の短縮形は `-V`、`--help` の短縮形は `-h` です。

```bash theme={"dark"}
npx cc-safety-net --version
npx cc-safety-net -V
npx cc-safety-net --help
npx cc-safety-net -h
```

特定のコマンドの使用方法を表示するには、`help <command>` または `<command> --help` を使います。

```bash theme={"dark"}
npx cc-safety-net help explain
npx cc-safety-net explain --help
npx cc-safety-net help doctor
```

認識しないコマンドは `Unknown command: <name>` を出力します。`-` で始まる場合は `Unknown option: <name>` を出力します。その後に `Run 'cc-safety-net --help' for usage.` を出力し、`1` で終了します。不明なコマンドに対する `help <name>` は、代わりに `Unknown command: <name>` と `Run 'cc-safety-net --help' for available commands.` を出力します。表示するヘルプテキストを含め、これらの失敗パスのメッセージはすべて標準エラー出力へ書き出されます。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.