npm package: @plant004/karajan
Description: Issue-driven development orchestration framework
Latest version: 0.1.2

# Karajan

イシュー駆動開発（Issue Driven Development）オーケストレーションフレームワーク。GitHub の Issue を起点に、AI エージェント（Claude Code）が自動的にコードを実装・レビュー・マージするまでの一連のフローを管理します。

## 概要

```
GitHub Issue
    │
    ├─ (karajan:spec ラベル付与)
    │       ↓
    │   [Karajan Dispatcher]
    │       ↓
    │   [Specifier Agent]  ← Claude Code
    │       │  仕様レビュー・詳細化+karajan:task 付与(オプション、デフォルトで有効)
    │       ├─ シンプルな要件: Issue本文を詳細仕様・受け入れ条件付きに更新
    │       └─ 複雑な要件: Sub Issue自動作成 
    │
    └─ (karajan:task ラベル付与)
            ↓
        [Karajan Dispatcher]
            ↓
        [Developer Agent]  ← Claude Code
            │  実装 → コミット → PR作成
            ↓
        [Karajan Dispatcher]
            ↓
        [Reviewer Agent]   ← Claude Code
            │  レビュー → OK: マージ(オプション、デフォルトで有効) / NG: 修正依頼Issue作成
            ↓
        (繰り返し、最大 maxChainCount 回)
```

## 機能

- **Webhook 受信**: GitHub の `issues` / `pull_request` イベントを受信
- **IP 検証**: GitHub Meta API の CIDRレンジによるホワイトリスト（`"github"` / `"disabled"` / カスタムCIDR）
- **レート制限**: 固定ウィンドウ方式（デフォルト 60 req/min）
- **署名検証**: HMAC-SHA256 による Webhook 署名検証
- **並行制御**: `maxConcurrency` / `maxQueueLength` によるキュー管理
- **タスクキュー照会 API**: REST API でキューの状態（実行中・待機中・保留中）をリアルタイムに参照可能
- **タスクキュー操作 API**: REST API でキュー内のタスクキャンセルや、キューのサスペンド/レジュームを実行可能
- **キュー管理 Web UI**: ブラウザから `GET /ui` でアクセスできる管理ダッシュボード（Karajan Queue Dashboard）
- **API ドキュメント**: `GET /api/docs` で Swagger UI、`GET /api/docs/openapi.json` で OpenAPI JSON スキーマを参照可能
- **ループ検出**: 連鎖カウント（`<!-- karajan:chain-count:N -->`）によるエスカレーション
- **依存関係解決**: Issue body の `Depends on #N` 記法で依存Issueがクローズされるまでタスクを自動遅延
- **グレースフルシャットダウン**: SIGTERM/SIGINT 受信時に安全に停止
- **Usage チェック**: 生成AIの利用状況を定期確認し、上限到達時にキュー処理を自動保留・再開
- **Spec レビュー**: `karajan:spec` ラベル付きIssueを専用エージェントがレビューし仕様を整理
- **Bot 署名**: AI生成コンテンツにボット識別フッターを自動付与

## 必要環境

- Node.js 20+
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)（`claude` コマンドが PATH に存在すること）
- [GitHub CLI](https://cli.github.com/)(`gh` コマンド)
- GitHub Fine-grained PAT（スコープ: `issues: write`, `pull_requests: write`, `contents: write`, `webhooks: write`）

## インストール

```bash
npm install -g @plant004/karajan
```

## セットアップ

### 1. 環境変数の準備

```bash
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
```

### 2. セットアップコマンドを実行

#### インタラクティブモード（引数なし）

```bash
karajan setup
```

引数を省略して起動すると、対話形式でパラメータを入力できます。リポジトリ入力後に "Add another repository? [y/N]:" が表示され、複数リポジトリを追加できます。

#### 引数指定モード

```bash
karajan setup \
  --repos your-org/your-repo \
  --dispatcher-url https://your-server.example.com/webhook \
  [--port 3000] \
  [--merge-strategy squash] \
  [--force]
```

`--repos` には `owner/repo` 形式の他、SSH URL (`git@github.com:owner/repo.git`) や HTTPS URL (`https://github.com/owner/repo`) も指定できます。複数リポジトリを設定する場合はカンマ区切りで指定します：

```bash
karajan setup \
  --repos your-org/repo1,your-org/repo2 \
  --dispatcher-url https://your-server.example.com/webhook
```

このコマンドは以下を自動実行します：

1. **ラベル登録**: `karajan:task` / `karajan:review` / `karajan:escalation` / `karajan:spec` をリポジトリに作成
2. **Webhook 登録**: 指定 URL に GitHub Webhook を登録し、Secret を生成して `.env` に書き込む
3. **設定ファイル生成**: `karajan.config.yaml` と `.env.example` を生成
4. **`.gitignore` 更新**: 対象リポジトリの `.gitignore` に `.karajan/` を追記する（既に記載済みの場合はスキップ）

#### 設定ファイル指定モード（`--config`）

`karajan.config.yaml` が既に存在する場合、`--config` オプションを使うとリポジトリ情報やラベル設定をファイルから読み込んでセットアップを実行できます。設定ファイルの生成や `.gitignore` 更新はスキップされ、**ラベルとWebhookの登録のみ**を行います。Webhook URL を変更した場合や、ラベル設定を更新した後に適用し直す際に便利です。

```bash
karajan setup \
  --config karajan.config.yaml \
  --dispatcher-url https://your-server.example.com/webhook \
  [--force]
```

| オプション | 説明 |
|---|---|
| `--config` | 読み込む設定ファイルのパス |
| `--dispatcher-url` | GitHub Webhook の送信先 URL（必須） |
| `--force` | 既存の Webhook を削除して再作成する |

`--config` を指定した場合、`--repos` は不要です。リポジトリ一覧は設定ファイルの `repositories` セクションから読み込まれます。ラベル名やカラーも `labels` セクションの設定が反映されます。

#### KARAJAN_WEBHOOK_SECRET を手動で設定する場合

セットアップコマンドを使わず手動で Secret を用意する場合は、以下のいずれかで生成してください。

```bash
# Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

# openssl
openssl rand -hex 32
```

生成した値を `.env` に設定します。複数リポジトリを設定する場合はリポジトリごとに異なる Secret を用意することを推奨します。

```
# リポジトリが1つの場合
KARAJAN_WEBHOOK_SECRET=<生成した値>

# 複数リポジトリの場合（karajan setup が自動で番号付きキーを生成）
KARAJAN_WEBHOOK_SECRET_1=<1つ目のリポジトリの値>
KARAJAN_WEBHOOK_SECRET_2=<2つ目のリポジトリの値>
```

### 3. 設定ファイルを確認・編集

```yaml
# karajan.config.yaml
repositories:
  - provider: github
    owner: your-org
    name: your-repo
    baseBranch: main
    mergeStrategy: squash  # squash | merge | rebase
    webhookSecret: ${KARAJAN_WEBHOOK_SECRET}
  # 複数リポジトリを設定する場合は以下のように追記する
  # - provider: github
  #   owner: your-org
  #   name: another-repo
  #   webhookSecret: ${KARAJAN_WEBHOOK_SECRET_2}

dispatcher:
  port: 3000
  ipWhitelist: github
  rateLimitPerMinute: 60
  maxConcurrency: 3
  maxQueueLength: 10
  githubToken: ${GITHUB_TOKEN}
  # adminApiKey: "your-secret-api-key"  # 管理APIの認証キー（省略時は認証なし）

generativeAI:
  provider: claude-code
  claudeCode:
    model: claude-sonnet-4-6
    # エージェントのツール許可設定はフロントマター YAML（agents/frontmatter/）で管理します。
    # karajan agents install 実行時にエージェントファイルへ埋め込まれます。
  usageCheck:
    enabled: false           # 利用状況チェックを有効にするか（デフォルト: false）
    intervalSeconds: 60      # 確認間隔（秒）（デフォルト: 60）
    command: "ccusage blocks --active --json --token-limit max"  # 利用状況確認コマンド
    thresholdPercent: 0      # 残リクエスト率がこの値以下で保留（0-100、デフォルト: 0）

workDir: ./workdir           # エージェントの作業ディレクトリ（デフォルト: "./workdir"）

agents:
  developer:
    definition: agents/developer.md
    timeoutMinutes: 60
    maxRetries: 2
    retryBackoffSeconds: 30
    autoReview: true        # developerエージェント終了後に自動でreviewerを起動するか（デフォルト: true）
    # install:
    #   name: karajan-developer  # エージェントファイルの name（省略時: "karajan-developer"）
  reviewer:
    definition: agents/reviewer.md
    timeoutMinutes: 30
    maxRetries: 2
    retryBackoffSeconds: 30
    autoMerge: true         # approve後に自動mergeするか（デフォルト: true）
  specifier:                # karajan:spec ラベルで起動する仕様レビューエージェント
    definition: agents/specifier.md
    timeoutMinutes: 15
    maxRetries: 1
    retryBackoffSeconds: 30
    autoAssignTask: true    # Sub Issue作成時にkarajan:taskラベルを自動付与するか（デフォルト: true）

triggerPolicy:
  issues: labeled        # labeled | all
  pullRequests: labeled  # labeled | disabled

loopControl:
  maxChainCount: 3

labels:
  review: karajan:review     # PRレビュートリガー用ラベル
  escalation: karajan:escalation
  task: karajan:task
  spec: karajan:spec

botIdentity:
  name: karajan            # AI生成コンテンツに表示されるボット名
  # iconUrl: https://example.com/karajan-icon.png  # オプション: アバター画像URL

logging:
  level: info              # ログレベル: debug / info / warn / error（デフォルト: info）
  format: json             # ログフォーマット: json / pretty（デフォルト: json）
```

### 4. エージェントとスキルをインストール

エージェント定義ファイル（フロントマター付き）および GitHub 操作スキルを AI プロバイダーの所定ディレクトリへインストールします。

```bash
karajan agents install [--config karajan.config.yaml] [--scope user|project] [--output-dir <dir>] [--force] [--dry-run]
```

このコマンドは以下を同時にインストールします。

- **エージェントファイル** → `.claude/agents/karajan-*.md`（9ファイル）
- **スキルファイル** → `.claude/skills/github/SKILL.md`（GitHub操作スキル）

`--scope project` を指定すると、`karajan.config.yaml` の `repositories` に定義された全リポジトリへ GitHub API 経由で**1コミットで**直接コミットします（`GITHUB_TOKEN` が必要）。`--output-dir` を指定した場合はローカルのファイルシステムへ書き込みます。

| オプション | 説明 |
|---|---|
| `--config` | 設定ファイルのパス（デフォルト: `karajan.config.yaml`） |
| `--scope` | インストール先スコープ: `user`（`~/.claude/agents/` および `~/.claude/skills/` へローカル書き込み）/ `project`（GitHub API 経由で対象リポジトリの `.claude/agents/` `.claude/skills/` に直接コミット）（省略時: `user`） |
| `--output-dir` | インストール先を直接指定（`--scope` より優先） |
| `--force` | 既存ファイルを上書き |
| `--dry-run` | 実際には書き込まず内容をプレビュー表示 |

### 5. サーバーを起動

```bash
karajan start [--config karajan.config.yaml]
```

`--config` オプションで設定ファイルのパスを指定できます（デフォルト: `karajan.config.yaml`）。

## 使い方

### Issue から実装を開始する

1. GitHub でIssueを作成する
2. `karajan:task` ラベルを付与する
3. Karajan が自動的に Developer Agent を起動し、実装 → PR作成まで行う

### Spec レビューを行う

1. GitHub でIssueを作成する（機能仕様・要件の記述を想定）
2. `karajan:spec` ラベルを付与する
3. Karajan が Specifier Agent を起動し、Issue の仕様内容をレビューする
4. 要件がシンプルな場合: Issue 本文が詳細仕様・受け入れ条件を含む形式に更新される
5. 要件が複雑な場合（複数の独立した機能・実装ステップ間に依存関係がある等）: Specifier が Sub Issue を自動作成し、各 Sub Issue に `karajan:task` ラベルを付与することで Developer Agent が個別に実装を開始する。親 Issue はクローズされる

### Issue の依存関係を指定する

Issue body に `Depends on #N` と記述すると、Issue #N がクローズされるまでそのIssueのタスク実行が自動的に遅延されます。複数の依存を指定する場合は複数行に記述します。

```
Depends on #42
Depends on #43
```

すべての依存Issueがクローズされると、遅延されていたタスクが自動的にキューに投入されます。

### タスクキュー管理 API の認証

`karajan.config.yaml` の `dispatcher.adminApiKey` を設定すると、`/api/queue/*` エンドポイントへのアクセスに Bearer トークン認証が適用されます。

```yaml
dispatcher:
  adminApiKey: "your-secret-api-key"
```

認証が有効な場合、すべての `/api/queue/*` リクエストに `Authorization` ヘッダーが必要です。

```bash
curl -H "Authorization: Bearer your-secret-api-key" http://localhost:3000/api/queue/status
```

| 状況 | HTTPステータス |
|---|---|
| 正しいトークンを指定した場合 | リクエストを処理 |
| `Authorization` ヘッダーなし / `Bearer` 形式でない場合 | `401 Unauthorized` |
| トークンが一致しない場合 | `403 Forbidden` |

`adminApiKey` を設定しない場合は認証なしで動作しますが、起動時に警告ログが出力されます。`/health`、`/webhook`、および `/ui` エンドポイントは `adminApiKey` の設定に関わらず認証の影響を受けません。`/api/docs` および `/api/docs/openapi.json` は `/api/*` パターンに一致するため、`adminApiKey` を設定した場合は認証が必要です。

### キュー管理 Web UI を使う

Karajan が起動中であれば、ブラウザから `http://localhost:3000/ui` にアクセスすることで「Karajan Queue Dashboard」が表示されます。ヘッダーの API Key 入力欄に `adminApiKey` を入力して「保存」ボタンを押すと、セッション中は認証が維持されます。

`/ui` エンドポイントは `adminApiKey` が設定されている場合でも認証なしでアクセス可能です（API Key の入力はダッシュボード上で行います）。

ダッシュボードでは以下の情報が確認・操作できます。

- **キュー状態**: Running / Queued / Deferred のタスク件数カードと、キューが Active / Suspended のどちらの状態かを示すバッジ
- **タスク一覧**: 全タスクの state / taskId / agentType / repoKey / target / chainCount を表形式で表示
- **State フィルタ**: プルダウンで `all` / `running` / `queued` / `deferred` を切り替えてタスクを絞り込み
- **自動更新**: 10 秒間隔でキュー状態とタスク一覧が自動的に再取得される
- **タスクキャンセル**: `queued` / `deferred` 状態のタスク行にある「Cancel」ボタンをクリックし、確認ダイアログで承認するとそのタスクをキャンセルできる（`running` 状態のタスクはキャンセル不可）
- **キューのサスペンド/レジューム**: Actions パネルの「Suspend Queue」ボタンでキューを一時停止し、「Resume Queue」ボタンで再開できる。現在の状態に応じてボタンの有効/無効が自動的に切り替わる
- **エラー通知**: 操作失敗時はページ上部にトースト通知が表示され、3 秒後に自動的に消える

### タスクキューの状態を確認する

Karajan が起動中であれば、以下の REST API でタスクキューの現在の状態を参照できます。

#### `GET /api/queue/status`

実行中・待機中・保留中のタスク件数と、キューが保留状態かどうかを返します。

```bash
curl http://localhost:3000/api/queue/status
```

```json
{
  "running": 1,
  "queued": 2,
  "deferred": 0,
  "isSuspended": false
}
```

#### `GET /api/queue/tasks`

全タスクの一覧を返します。`state` クエリパラメータでフィルタリングできます。

| `state` の値 | 返却内容 |
|---|---|
| `all`（デフォルト） | running / queued / deferred 全タスク |
| `running` | 実行中タスクのみ |
| `queued` | 待機中タスクのみ |
| `deferred` | 依存関係待ちで保留中のタスクのみ |

```bash
# 全タスクを取得
curl http://localhost:3000/api/queue/tasks

# 実行中タスクのみ取得
curl http://localhost:3000/api/queue/tasks?state=running
```

不正な `state` 値を指定した場合は `400 Bad Request` が返されます。

### タスクキューを操作する

Karajan が起動中であれば、以下の REST API でタスクのキャンセルやキューのサスペンド/レジュームを行えます。

#### `DELETE /api/queue/tasks/:taskId`

指定した taskId の待機中（queued）または依存関係待ち（deferred）タスクをキャンセルします。

```bash
curl -X DELETE http://localhost:3000/api/queue/tasks/<taskId>
```

```json
{ "message": "Task cancelled", "taskId": "<taskId>" }
```

| 状況 | HTTPステータス |
|---|---|
| キャンセル成功（queued / deferred） | `200 OK` |
| 実行中タスクを指定した場合 | `409 Conflict` |
| 存在しない taskId を指定した場合 | `404 Not Found` |

> 実行中（running）のタスクはキャンセルできません。プロセスへの割り込みは行われません。

#### `POST /api/queue/suspend`

キューをサスペンドします。サスペンド中は新しいタスクがキューに追加されても実行が開始されません。

```bash
curl -X POST http://localhost:3000/api/queue/suspend
```

```json
{ "message": "Queue suspended" }
```

既にサスペンド済みの場合は `409 Conflict` が返されます。

#### `POST /api/queue/resume`

サスペンド中のキューを再開します。

```bash
curl -X POST http://localhost:3000/api/queue/resume
```

```json
{ "message": "Queue resumed" }
```

サスペンド状態でない場合は `409 Conflict` が返されます。

### API ドキュメントを参照する

Karajan が起動中であれば、以下のエンドポイントで API ドキュメントを参照できます。

#### `GET /api/docs`

Swagger UI をブラウザで表示します。

```bash
open http://localhost:3000/api/docs
```

#### `GET /api/docs/openapi.json`

OpenAPI 3.0 形式の JSON スキーマを返します。

```bash
curl http://localhost:3000/api/docs/openapi.json
```

```json
{
  "openapi": "3.0.0",
  "info": {
    "title": "Karajan Dispatcher API",
    "version": "0.1.1"
  },
  "servers": [{ "url": "/" }],
  ...
}
```

`adminApiKey` を設定している場合、これらのエンドポイントへのアクセスにも `Authorization` ヘッダーが必要です。

```bash
curl -H "Authorization: Bearer your-secret-api-key" http://localhost:3000/api/docs/openapi.json
```

### トリガーポリシーの設定

| 設定 | 値 | 動作 |
|---|---|---|
| `triggerPolicy.issues` | `labeled`（デフォルト） | `karajan:task` ラベル付きIssueのみ対象 |
| `triggerPolicy.issues` | `all` | 全Issueを対象 |
| `triggerPolicy.pullRequests` | `labeled`（デフォルト） | `karajan:review` ラベル付与時にレビュー起動 |
| `triggerPolicy.pullRequests` | `disabled` | PRのレビューエージェントを起動しない |

## エージェント定義・スキルのカスタマイズ

`karajan agents install` でインストールされたファイルを直接編集することで、エージェントの動作やスキルをカスタマイズできます。

- **user スコープ**: `~/.claude/agents/*.md` / `~/.claude/skills/github/SKILL.md`
- **project スコープ**: リポジトリの `.claude/agents/*.md` / `.claude/skills/github/SKILL.md`

インストール先には以下のファイルが配置されます。

```
~/.claude/                  # user スコープの場合
├── agents/
│   ├── karajan-developer.md          # 開発エージェント（サブエージェントをオーケストレート）
│   ├── karajan-dev-design.md         # 設計フェーズ（Issue分析・設計書作成）
│   ├── karajan-dev-red.md            # TDD Red フェーズ（必ず失敗するテスト作成）
│   ├── karajan-dev-implement.md      # 実装フェーズ（設計書に基づく実装）
│   ├── karajan-dev-green.md          # TDD Green フェーズ（全テスト通過）
│   ├── karajan-dev-refactor.md       # TDD Refactor フェーズ（コード整理・品質改善）
│   ├── karajan-dev-documentator.md   # ドキュメント更新フェーズ
│   ├── karajan-reviewer.md           # レビューエージェント
│   └── karajan-specifier.md          # 仕様レビューエージェント
└── skills/
    └── github/
        └── SKILL.md                  # GitHub操作スキル（Issue/PR/ブランチ/API操作）
```

**GitHub スキルについて**: エージェント定義では `gh` コマンドを直接記述する代わりに「GitHubのIssueを取得する」「GitHubにPull Requestを作成する」などの自然言語で GitHub 操作を指示しています。`github` スキルがインストールされていると、Claude Code がこれらの指示を自動的に `gh` CLI コマンドに変換して実行します。

> **注意**: `karajan agents install --force` を実行すると、インストール済みのエージェント・スキルファイルが上書きされます。カスタマイズした内容を保持したい場合は、再インストール前にバックアップしてください。

## エラーハンドリング

| 状況 | 動作 |
|---|---|
| Webhook 署名検証失敗 | `401 Unauthorized` |
| IP 検証失敗 | `403 Forbidden` |
| レート制限超過 | `429 Too Many Requests` |
| 同一Issue/PRの重複実行 | リクエスト破棄（ログ出力） |
| 依存Issueが未クローズ | `deferred` + 依存解決まで実行待機 |
| キュー超過 | `rejected` + 対象 Issue/PR にコメント |
| エージェントタイムアウト | SIGTERM → 5秒後 SIGKILL + エラーコメント |
| 一時的エラー（rate limit / network） | 指数バックオフでリトライ（最大2回） |
| 永続的エラー（認証失敗等） | 対象 Issue/PR にエラー詳細コメント |
| 連鎖回数上限到達 | `karajan:escalation` ラベル付与 + コメント |

## 設定リファレンス

### `repositories`

`repositories` は配列形式で1件以上設定します。各エントリには以下のフィールドを指定します。

| キー | デフォルト | 説明 |
|---|---|---|
| `provider` | — | `"github"` 固定 |
| `owner` | — | GitHub組織またはユーザー名 |
| `name` | — | リポジトリ名 |
| `cloneUrl` | 自動生成 | git clone URL（省略時: `git@github.com:${owner}/${name}.git`） |
| `baseBranch` | `"main"` | PRのベースブランチ |
| `mergeStrategy` | `"squash"` | マージ戦略（`squash` / `merge` / `rebase`） |
| `webhookSecret` | — | GitHub Webhook シークレット（環境変数推奨） |

### `dispatcher`

| キー | デフォルト | 説明 |
|---|---|---|
| `port` | `3000` | HTTPサーバーのポート |
| `ipWhitelist` | `"github"` | IP許可設定（`"github"` / `"disabled"` / CIDR配列） |
| `rateLimitPerMinute` | `60` | 1分間の最大リクエスト数 |
| `maxConcurrency` | `3` | 同時実行エージェント数の上限 |
| `maxQueueLength` | `10` | キューの最大長 |
| `githubToken` | — | GitHub PAT（環境変数推奨） |
| `adminApiKey` | — | 管理API（`/api/queue/*`）の認証キー。設定しない場合は認証なし（起動時に警告ログを出力） |

### `generativeAI`

| キー | デフォルト | 説明 |
|---|---|---|
| `provider` | — | `"claude-code"` 固定 |
| `claudeCode.model` | — | 使用するモデル名（例: `claude-sonnet-4-6`） |

> **注意**: エージェントに許可するツールは `agents/frontmatter/claude-code/*.yaml` で定義します。`karajan agents install` 実行時にエージェントファイルへ埋め込まれます。

### `generativeAI.usageCheck`

| キー | デフォルト | 説明 |
|---|---|---|
| `enabled` | `false` | 利用状況チェックを有効にするか |
| `intervalSeconds` | `60` | チェック間隔（秒） |
| `command` | `"ccusage blocks --active --json --token-limit max"` | 利用状況確認コマンド（JSON出力が必要） |
| `thresholdPercent` | `0` | 残リクエスト率がこの値以下でキュー処理を保留（0-100） |

### `workDir`

| キー | デフォルト | 説明 |
|---|---|---|
| `workDir` | `"./workdir"` | エージェントが使用する作業ディレクトリのパス |

### `branchTemplate`

| キー | デフォルト | 説明 |
|---|---|---|
| `branchTemplate` | — | 作成するブランチ名のテンプレート（省略時はデフォルト命名規則） |

### `agents.developer` / `agents.reviewer` / `agents.specifier`

| キー | デフォルト | 説明 |
|---|---|---|
| `definition` | — | エージェント定義ファイルのパス |
| `timeoutMinutes` | developer: `60`, reviewer: `30`, specifier: `15` | タイムアウト時間（分） |
| `maxRetries` | — | 最大リトライ回数 |
| `retryBackoffSeconds` | — | リトライ初期待機時間（秒） |
| `install.name` | `"karajan-{role}"` | `karajan agents install` で生成するエージェントファイルの `name`（省略時: `karajan-developer` / `karajan-reviewer` / `karajan-specifier`） |
| `autoReview` ※ | `true` | developerエージェント終了後に自動でreviewerを起動するか（`developer` のみ） |
| `autoAssignTask` ※ | `true` | Sub Issue作成時に `karajan:task` ラベルを自動付与するか（`specifier` のみ） |
| `autoMerge` ※ | `true` | approve後にPRを自動mergeするか（`reviewer` のみ） |

`specifier` は `karajan:spec` ラベル付きIssueで起動します。`autoAssignTask: false` を設定すると、Specifierが作成するSub Issueに `karajan:task` ラベルが付与されなくなります。

`autoReview: false` を設定すると、Developerはコードを実装してPRを作成するだけで、Reviewerエージェントを自動起動しません（手動レビューを前提とした運用向け）。

`autoMerge: false` を設定すると、Reviewerはレビュー承認のみ行い、mergeを実行しません（手動mergeを前提とした運用向け）。

### `labels`

| キー | デフォルト | 説明 |
|---|---|---|
| `task` | `"karajan:task"` | 開発タスクトリガー用ラベル |
| `review` | `"karajan:review"` | PRレビュートリガー用ラベル（Karajanが作成したPRに付与） |
| `escalation` | — | 連鎖上限到達時に付与するラベル |
| `spec` | `"karajan:spec"` | 仕様レビュートリガー用ラベル |
| `colors.review` | `"1D76DB"` | `review` ラベルの色（6桁16進数） |
| `colors.escalation` | `"D93F0B"` | `escalation` ラベルの色（6桁16進数） |
| `colors.task` | `"0E8A16"` | `task` ラベルの色（6桁16進数） |
| `colors.spec` | `"7057FF"` | `spec` ラベルの色（6桁16進数） |

### `botIdentity`

| キー | デフォルト | 説明 |
|---|---|---|
| `name` | `"karajan"` | AI生成コンテンツのフッターに表示されるボット名 |
| `iconUrl` | — | オプション: フッターに表示するアバター画像URL |

### `loopControl`

| キー | デフォルト | 説明 |
|---|---|---|
| `maxChainCount` | `3` | 開発→レビュー→修正の最大連鎖回数 |

### `logging`

| キー | デフォルト | 説明 |
|---|---|---|
| `level` | `"info"` | ログレベル（`"debug"` / `"info"` / `"warn"` / `"error"`）。`LOG_LEVEL` 環境変数が設定されている場合はそちらが優先される |
| `format` | `"json"` | ログフォーマット（`"json"` / `"pretty"`）。`"pretty"` の場合は `pino-pretty` を使用した人間可読な出力になる |

## 開発

```bash
# 依存インストール
npm install

# テスト実行
npm test

# ウォッチモード
npm run test:watch

# ビルド（tsup によるコンパイル + 難読化を一括実行）
npm run build

# リント
npm run lint
```

## アーキテクチャ

```
src/
├── index.ts                    # CLIエントリポイント (setup / start)
├── logger.ts                   # pino 構造化ログ
├── config/
│   ├── schema.ts               # Zod スキーマ・型定義
│   └── loader.ts               # YAML読み込み・環境変数解決
├── repository/
│   ├── types.ts                # Repository インターフェース・型
│   ├── github.ts               # GitHub実装 (Octokit)
│   └── botSignature.ts         # AI生成コンテンツへのBot署名付与
├── generativeAI/
│   ├── types.ts                # GenerativeAI インターフェース
│   ├── claudeCode.ts           # Claude Code 実装
│   └── factory.ts              # プロバイダー選択ファクトリー
├── dispatcher/
│   ├── types.ts                # AgentDispatch / AgentTask 型
│   ├── server.ts               # OpenAPIHono HTTPサーバー（Swagger UI / OpenAPI JSON 配信含む）
│   ├── webhookHandler.ts       # Webhookパイプライン
│   ├── eventRouter.ts          # イベントルーティング
│   ├── lockManager.ts          # 重複実行防止ロック
│   ├── queueManager.ts         # 並行数制御・FIFOキュー
│   ├── loopDetector.ts         # 連鎖回数抽出・エスカレーション判定
│   ├── dependencyParser.ts     # Issue依存関係（Depends on #N）パース
│   ├── templateEngine.ts       # プロンプトテンプレートエンジン
│   └── ui/
│       └── index.html          # キュー管理 Web UI（Karajan Queue Dashboard）
├── workspace/
│   └── worktreeManager.ts      # git worktree 管理
├── usageMonitor/
│   └── usageMonitor.ts         # 生成AI利用状況モニタリング・キュー保留制御
├── executor/
│   ├── retryPolicy.ts          # リトライ判定・バックオフ計算
│   └── processManager.ts       # エージェントプロセス管理
└── setup/
    ├── index.ts                # セットアップCLI
    ├── interactiveSetup.ts     # インタラクティブセットアップ（対話形式入力）
    ├── agentInstaller.ts       # エージェント・スキルファイルのインストール（GitHub API / ローカル）
    ├── labelRegistrar.ts       # ラベル登録
    ├── webhookRegistrar.ts     # Webhook登録
    ├── configGenerator.ts      # 設定ファイル生成
    └── gitignoreUpdater.ts     # .gitignore への .karajan/ 追記

agents/                         # エージェント定義テンプレート
├── frontmatter/claude-code/    # Claude Code 用フロントマター YAML
├── developer.md / reviewer.md / specifier.md
└── dev-*.md                    # サブエージェント定義

skills/                         # スキル定義
└── github/
    └── SKILL.md                # GitHub操作スキル（gh CLI ラッパー）

scripts/                        # ビルド補助スクリプト
├── obfuscate.mjs               # dist/index.js の難読化（npm run build 時に自動実行）
└── obfuscator.config.mjs       # 難読化オプション設定
```