harness
宣言的ハーネス管理ツール — AI コーディングエージェント(Claude Code、Codex など)の skills と hooks をプロジェクトごとに管理します。
概要
AI エージェントのスキルをグローバルに管理するのはプロジェクトごとの要件に合わず、うまくいきません。例えば React プロジェクトにだけ適用したいスキルや、特定のフレームワークを使っているときだけ有効にしたいフックなど、プロジェクトの実態に応じた管理が必要です。
harness は manifest ファイルにスキルを宣言的に記述し、エージェントがプロジェクトの実態(package.json の依存関係など)を見て condition を評価し、必要なスキルとフックを自動で適用する仕組みを提供します。
一度下した判断は .harness-decisions.json に記録されるため、次回以降は再評価なしで即時適用できます。
特徴
- manifest でスキルを一元管理 —
~/.config/harness/manifest.json にスキルとプロファイルを宣言的に記述
- condition による自動評価 — プロジェクトの実態をエージェントが確認し、各スキル・プロファイルの適用要否を判断
- 判断記録(
.harness-decisions.json) — 一度の判断結果をプロジェクトルートに保存し、以降の実行で再利用
- try で一時利用 — ファイルシステムに何も残さず、セッション内だけでスキルを試せる
- Claude Code プラグイン + npx skills の両対応 — 好みのインストール方法を選択可能
インストール
Claude Code プラグイン(推奨)
マーケットプレイスを追加し、プラグインをインストールします:
claude plugin marketplace add myuon/harness
claude plugin install harness@myuon-harness
インストール後、プラグインをリロードしてプロジェクトにスキルを適用:
/reload-plugins
/harness:install
プラグインの更新
harness の新しいバージョンがリリースされたら、以下のコマンドで更新できます:
claude plugin marketplace update myuon-harness
claude plugin update harness@myuon-harness
更新後、セッション内で /reload-plugins を実行すると反映されます。
npx skills
すべてのスキルを一括インストールする場合:
npx skills add myuon/harness --all -y
特定のスキルのみインストールする場合:
npx skills add myuon/harness --skill install
npx skills add myuon/harness --skill try
使い方
| コマンド | 説明 |
|---|
/harness:install | manifest を読み condition 評価 → スキル適用 → 判断記録 |
/harness:try <source> <skill> | 一時的に SKILL.md を読み込み(インストールなし) |
/harness:add <source> <skill> | manifest にスキルを追加(condition はエージェントが自動提案) |
/harness:list | manifest の内容を表示 |
/harness:sync | インストール済みスキルと manifest を比較し、未登録のものがあれば追加を提案 |
manifest フォーマット
manifest は ~/.config/harness/manifest.json に配置します。
{
"skills": {
"commit": {
"source": "myuon/agent-skills",
"condition": "always",
"scope": "global"
},
"react-no-useeffect": {
"source": "myuon/agent-skills",
"condition": "React を使っているプロジェクト"
}
},
"profiles": {
"expo": {
"condition": "Expo(React Native)を使っているプロジェクト",
"skills": {
"expo-router": {
"source": "myuon/agent-skills",
"scope": "project"
},
"react-native-style": {
"source": "myuon/agent-skills",
"scope": "project"
}
},
"hooks": [
{
"event": "PostToolUse",
"matcher": "Edit",
"command": "npx expo lint --fix $CLAUDE_FILE_PATH"
}
]
},
"react": {
"condition": "React を使っているプロジェクト",
"hooks": [
{
"event": "PostToolUse",
"matcher": "Edit",
"command": "npx eslint --fix $CLAUDE_FILE_PATH"
}
]
}
}
}
フィールド説明
skills
| フィールド | 説明 |
|---|
source | スキルが配置されている GitHub リポジトリ(owner/repo 形式) |
condition | 適用条件。"always" で常に適用、自然言語でプロジェクトの条件を記述することも可能 |
scope | インストール先。"global" でグローバル、"project"(デフォルト)でプロジェクトローカル。省略時は "project" |
profiles
プロファイルはスキルのセットとフックをまとめたものです。
| フィールド | 説明 |
|---|
condition | プロファイルを適用する条件(自然言語で記述) |
skills | プロファイルに含まれるスキルのマップ(省略可)。condition が apply: true の場合にまとめてインストールされる |
skills.<name>.source | スキルが配置されている GitHub リポジトリ(owner/repo 形式) |
skills.<name>.scope | インストール先。"global" または "project"(デフォルト) |
hooks | 適用するフックのリスト |
hooks[].event | フックを発火するイベント(例: PostToolUse, PreToolUse) |
hooks[].matcher | フックを適用するツール名(例: Edit, Bash) |
hooks[].command | 実行するコマンド |
settings | .claude/settings.json に適用する設定のキー/バリューマップ(省略可) |
settings.allowedTools | 許可するツール名の配列(既存値とマージ) |
settings.customInstructions | カスタム指示文字列(既存値に追記、マーカーで管理) |
Settings 管理
プロファイルと settings
プロファイルに settings フィールドを追加することで、.claude/settings.json の設定をプロファイル単位で宣言的に管理できます。
{
"profiles": {
"react": {
"condition": "React を使っているプロジェクト",
"hooks": [
{
"event": "PostToolUse",
"matcher": "Edit",
"command": "npx eslint --fix $CLAUDE_FILE_PATH"
}
],
"settings": {
"allowedTools": ["Edit", "Write", "Bash"],
"customInstructions": "React のベストプラクティスに従うこと"
}
},
"python": {
"condition": "Python プロジェクト",
"settings": {
"allowedTools": ["Edit", "Write", "Bash"],
"customInstructions": "PEP 8 に従うこと"
}
}
}
}
allowedTools のマージ
allowedTools は配列のマージ(union)で処理されます。既存の値を上書きするのではなく、重複なしで追加されます。
例えば既存の allowedTools が ["Read"] の場合、プロファイルの allowedTools: ["Edit", "Write"] を適用すると ["Read", "Edit", "Write"] になります。
harness が追加したツールは .harness-decisions.json の profiles.<name>.addedTools で追跡されます。
customInstructions のマーカー管理
customInstructions はマーカーで囲んで追記されます: