ensemble-claude 0.3.1__py3-none-any.whl → 0.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ensemble/__init__.py +1 -1
- ensemble/cli.py +2 -0
- ensemble/commands/_issue_impl.py +150 -0
- ensemble/commands/_launch_impl.py +172 -47
- ensemble/commands/issue.py +36 -0
- ensemble/git_utils.py +157 -0
- ensemble/issue_provider.py +97 -0
- ensemble/providers/__init__.py +5 -0
- ensemble/providers/github.py +103 -0
- ensemble/templates/agents/conductor.md +64 -10
- ensemble/templates/agents/dispatch.md +128 -14
- ensemble/templates/agents/worker.md +55 -0
- ensemble/templates/commands/go-issue.md +157 -0
- ensemble/templates/commands/go.md +19 -4
- ensemble/templates/scripts/launch.sh +97 -58
- ensemble/templates/scripts/pane-setup.sh +103 -30
- {ensemble_claude-0.3.1.dist-info → ensemble_claude-0.4.1.dist-info}/METADATA +8 -5
- {ensemble_claude-0.3.1.dist-info → ensemble_claude-0.4.1.dist-info}/RECORD +21 -14
- {ensemble_claude-0.3.1.dist-info → ensemble_claude-0.4.1.dist-info}/WHEEL +0 -0
- {ensemble_claude-0.3.1.dist-info → ensemble_claude-0.4.1.dist-info}/entry_points.txt +0 -0
- {ensemble_claude-0.3.1.dist-info → ensemble_claude-0.4.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
GitHubのIssueを取得し、/goコマンドで実装を開始する。
|
|
4
|
+
Issue一覧から選択するか、番号を直接指定できる。
|
|
5
|
+
mainブランチから作業ブランチを作成し、完了後はPR作成を確認する。
|
|
6
|
+
|
|
7
|
+
使用例:
|
|
8
|
+
/go-issue - Issue一覧から選択
|
|
9
|
+
/go-issue 123 - Issue #123を直接指定
|
|
10
|
+
/go-issue --url <URL> - URLでIssueを指定
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
以下のワークフローでIssueベースの開発を行います。
|
|
14
|
+
|
|
15
|
+
## 入力
|
|
16
|
+
|
|
17
|
+
$ARGUMENTS
|
|
18
|
+
|
|
19
|
+
## ワークフロー
|
|
20
|
+
|
|
21
|
+
### Step 1: Issue取得
|
|
22
|
+
|
|
23
|
+
1. **引数の解析**:
|
|
24
|
+
- 引数なし → Issue一覧を取得して表示
|
|
25
|
+
- 番号あり → その番号のIssueを直接取得
|
|
26
|
+
- `--url` → URLからIssueを取得
|
|
27
|
+
|
|
28
|
+
2. **Issue一覧の場合** (`gh issue list --json number,title,body,url,state,labels`):
|
|
29
|
+
- 0件: 「オープンなIssueがありません」で終了
|
|
30
|
+
- 1件: 確認後に自動選択
|
|
31
|
+
- 2件以上: 番号付きリストで表示し、ユーザーに選択させる
|
|
32
|
+
|
|
33
|
+
表示例:
|
|
34
|
+
```
|
|
35
|
+
オープンなIssue一覧:
|
|
36
|
+
|
|
37
|
+
1. #42 [bug] ログイン時にエラーが発生する
|
|
38
|
+
2. #38 [feature] ダークモード対応
|
|
39
|
+
3. #35 [docs] READMEの更新
|
|
40
|
+
|
|
41
|
+
実装するIssueの番号を入力してください (1-3):
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
3. **Issue詳細の確認**:
|
|
45
|
+
- タイトル、本文、ラベルを表示
|
|
46
|
+
- 「このIssueで作業を開始しますか?」と確認
|
|
47
|
+
|
|
48
|
+
### Step 2: ブランチ作成
|
|
49
|
+
|
|
50
|
+
1. **現在の状態確認**:
|
|
51
|
+
```bash
|
|
52
|
+
git status --porcelain
|
|
53
|
+
```
|
|
54
|
+
- 未コミットの変更がある場合は警告し、続行するか確認
|
|
55
|
+
|
|
56
|
+
2. **mainブランチに移動して最新化**:
|
|
57
|
+
```bash
|
|
58
|
+
git checkout main
|
|
59
|
+
git pull origin main
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
3. **作業ブランチを作成**:
|
|
63
|
+
```bash
|
|
64
|
+
git checkout -b issue/<番号>-<slug>
|
|
65
|
+
```
|
|
66
|
+
例: `issue/42-fix-login-bug`
|
|
67
|
+
|
|
68
|
+
4. **作成完了を報告**:
|
|
69
|
+
```
|
|
70
|
+
ブランチ 'issue/42-fix-login-bug' を作成しました。
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Step 3: /goコマンドに委譲
|
|
74
|
+
|
|
75
|
+
以下の形式でタスクを構築し、/goコマンドの処理を実行する:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
## Issue #<番号>: <タイトル>
|
|
79
|
+
|
|
80
|
+
### 説明
|
|
81
|
+
<Issue本文>
|
|
82
|
+
|
|
83
|
+
### ラベル
|
|
84
|
+
<ラベル一覧>
|
|
85
|
+
|
|
86
|
+
### 完了条件
|
|
87
|
+
- このIssueで要求された機能/修正を実装する
|
|
88
|
+
- テストを追加する(必要に応じて)
|
|
89
|
+
- コードレビューに通るコードを書く
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**注意**: `/go`コマンドのskillを呼び出すのではなく、このコマンド内でConductorとして計画・実行を行う。
|
|
93
|
+
|
|
94
|
+
### Step 4: PR作成確認
|
|
95
|
+
|
|
96
|
+
実装完了後:
|
|
97
|
+
|
|
98
|
+
1. **変更のサマリーを表示**:
|
|
99
|
+
```bash
|
|
100
|
+
git diff main --stat
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
2. **PR作成の確認**:
|
|
104
|
+
```
|
|
105
|
+
実装が完了しました。Pull Requestを作成しますか?
|
|
106
|
+
|
|
107
|
+
[Y] 作成する
|
|
108
|
+
[N] 後で作成する
|
|
109
|
+
[E] コミットメッセージを編集してから作成
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
3. **PR作成** (Yの場合):
|
|
113
|
+
```bash
|
|
114
|
+
gh pr create --title "Fix: <Issueタイトル>" --body "Closes #<番号>
|
|
115
|
+
|
|
116
|
+
## 変更内容
|
|
117
|
+
<自動生成されたサマリー>
|
|
118
|
+
|
|
119
|
+
## テスト
|
|
120
|
+
- [ ] 単体テスト追加
|
|
121
|
+
- [ ] 手動テスト実施
|
|
122
|
+
"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
4. **PR URLを表示**:
|
|
126
|
+
```
|
|
127
|
+
Pull Request を作成しました:
|
|
128
|
+
https://github.com/owner/repo/pull/XX
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## プロバイダー対応
|
|
132
|
+
|
|
133
|
+
現在対応しているプロバイダー:
|
|
134
|
+
- **GitHub** (`gh` CLI): 完全対応
|
|
135
|
+
- **GitLab** (`glab` CLI): 今後対応予定
|
|
136
|
+
|
|
137
|
+
プロバイダーは自動検出する:
|
|
138
|
+
1. `gh` コマンドが利用可能 → GitHub
|
|
139
|
+
2. `glab` コマンドが利用可能 → GitLab
|
|
140
|
+
3. どちらも利用不可 → エラー
|
|
141
|
+
|
|
142
|
+
## エラーハンドリング
|
|
143
|
+
|
|
144
|
+
| 状況 | 対応 |
|
|
145
|
+
|------|------|
|
|
146
|
+
| `gh`/`glab` 未インストール | インストール方法を案内して終了 |
|
|
147
|
+
| リポジトリ外で実行 | 「Gitリポジトリで実行してください」 |
|
|
148
|
+
| オープンなIssueなし | 「オープンなIssueがありません」で終了 |
|
|
149
|
+
| 指定番号のIssueなし | 「Issue #XX は見つかりませんでした」 |
|
|
150
|
+
| ブランチ作成失敗 | エラー詳細を表示、手動での対応を案内 |
|
|
151
|
+
| PR作成失敗 | エラー詳細を表示、`gh pr create`コマンドを案内 |
|
|
152
|
+
|
|
153
|
+
## 注意事項
|
|
154
|
+
|
|
155
|
+
- Conductorは自分でコードを書かず、適切なエージェントに委譲する
|
|
156
|
+
- Issue本文が曖昧な場合は、ユーザーに追加情報を求める
|
|
157
|
+
- 大規模なIssueはサブタスクに分解することを提案する
|
|
@@ -49,10 +49,10 @@ $ARGUMENTS
|
|
|
49
49
|
|
|
50
50
|
3. パターンに応じて実行:
|
|
51
51
|
|
|
52
|
-
**パターンA
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
52
|
+
**パターンA(単一Worker)**:
|
|
53
|
+
- Dispatch経由でWorker1つで実行
|
|
54
|
+
- Conductorは計画・判断・委譲のみ
|
|
55
|
+
- 軽量タスクでも設計思想を遵守
|
|
56
56
|
|
|
57
57
|
**パターンB(shogun方式)**:
|
|
58
58
|
1. `queue/conductor/dispatch-instruction.yaml` に指示を書く
|
|
@@ -69,6 +69,21 @@ $ARGUMENTS
|
|
|
69
69
|
|
|
70
70
|
4. 実行中は `status/dashboard.md` を都度更新(Dispatchが担当)
|
|
71
71
|
|
|
72
|
+
### 完了待機(全パターン共通)
|
|
73
|
+
|
|
74
|
+
Dispatchへの委譲後、ポーリングで完了を待機:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# 完了待機(30秒間隔)
|
|
78
|
+
while [ ! -f "queue/reports/completion-summary.yaml" ]; do
|
|
79
|
+
sleep 30
|
|
80
|
+
done
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
完了検知後:
|
|
84
|
+
1. completion-summary.yaml を読み込み
|
|
85
|
+
2. Phase 3(レビュー)へ進む
|
|
86
|
+
|
|
72
87
|
### Phase 3: レビュー
|
|
73
88
|
|
|
74
89
|
5. 全サブタスク完了後、並列レビューを実行:
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# scripts/launch.sh
|
|
3
|
-
# Ensemble
|
|
4
|
-
# 構成:
|
|
3
|
+
# Ensembleの2セッションtmux環境を起動する
|
|
4
|
+
# 構成: 2つの独立したセッション(conductor専用 + workers)
|
|
5
|
+
#
|
|
6
|
+
# これにより、2つのターミナルウィンドウで同時に監視できる
|
|
5
7
|
#
|
|
6
8
|
# 注意: ペインIDを使用することで、ユーザーのtmux設定(pane-base-index等)に
|
|
7
9
|
# 依存せずに動作する
|
|
8
10
|
|
|
9
11
|
set -euo pipefail
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
SESSION_BASE="${SESSION_BASE:-ensemble}"
|
|
14
|
+
SESSION_CONDUCTOR="${SESSION_BASE}-conductor"
|
|
15
|
+
SESSION_WORKERS="${SESSION_BASE}-workers"
|
|
12
16
|
PROJECT_DIR="${PROJECT_DIR:-$(pwd)}"
|
|
13
17
|
LOG_DIR="$PROJECT_DIR/logs"
|
|
14
18
|
QUEUE_DIR="$PROJECT_DIR/queue"
|
|
@@ -19,12 +23,16 @@ echo "Launching Ensemble..."
|
|
|
19
23
|
mkdir -p "$LOG_DIR"
|
|
20
24
|
|
|
21
25
|
# キューディレクトリ作成
|
|
22
|
-
mkdir -p "$QUEUE_DIR/tasks" "$QUEUE_DIR/processing" "$QUEUE_DIR/reports" "$QUEUE_DIR/ack"
|
|
26
|
+
mkdir -p "$QUEUE_DIR/tasks" "$QUEUE_DIR/processing" "$QUEUE_DIR/reports" "$QUEUE_DIR/ack" "$QUEUE_DIR/conductor"
|
|
23
27
|
|
|
24
28
|
# 既存セッションがあれば削除
|
|
25
|
-
if tmux has-session -t "$
|
|
26
|
-
echo "Killing existing session..."
|
|
27
|
-
tmux kill-session -t "$
|
|
29
|
+
if tmux has-session -t "$SESSION_CONDUCTOR" 2>/dev/null; then
|
|
30
|
+
echo "Killing existing conductor session..."
|
|
31
|
+
tmux kill-session -t "$SESSION_CONDUCTOR"
|
|
32
|
+
fi
|
|
33
|
+
if tmux has-session -t "$SESSION_WORKERS" 2>/dev/null; then
|
|
34
|
+
echo "Killing existing workers session..."
|
|
35
|
+
tmux kill-session -t "$SESSION_WORKERS"
|
|
28
36
|
fi
|
|
29
37
|
|
|
30
38
|
# キューのクリーンアップ(新しいセッションはクリーンスタート)
|
|
@@ -38,43 +46,29 @@ rm -f "$QUEUE_DIR/ack/"*.ack 2>/dev/null || true
|
|
|
38
46
|
echo "$(date -Iseconds) Session started, queue cleaned" >> "$LOG_DIR/ensemble-$(date +%Y%m%d).log"
|
|
39
47
|
|
|
40
48
|
# === レイアウト ===
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
# |
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
#
|
|
50
|
-
echo "Creating session..."
|
|
51
|
-
tmux new-session -d -s "$SESSION" -n "main" -c "$PROJECT_DIR"
|
|
52
|
-
|
|
53
|
-
# 最初のペインのIDを取得(これがconductorになる)
|
|
54
|
-
CONDUCTOR_PANE=$(tmux list-panes -t "$SESSION:main" -F '#{pane_id}')
|
|
55
|
-
echo " Conductor pane: $CONDUCTOR_PANE"
|
|
56
|
-
|
|
57
|
-
# 2. 左右に分割(左65% : 右35%)
|
|
58
|
-
tmux split-window -h -t "$CONDUCTOR_PANE" -c "$PROJECT_DIR" -l 35%
|
|
59
|
-
|
|
60
|
-
# 新しく作成されたペインのIDを取得(これがdashboardになる)
|
|
61
|
-
DASHBOARD_PANE=$(tmux list-panes -t "$SESSION:main" -F '#{pane_id}' | grep -v "$CONDUCTOR_PANE")
|
|
62
|
-
echo " Dashboard pane: $DASHBOARD_PANE"
|
|
49
|
+
# セッション1: conductor
|
|
50
|
+
# +------------------+------------------+
|
|
51
|
+
# | Conductor | dashboard |
|
|
52
|
+
# +------------------+------------------+
|
|
53
|
+
#
|
|
54
|
+
# セッション2: workers
|
|
55
|
+
# +------------------+------------------+
|
|
56
|
+
# | dispatch | worker-area |
|
|
57
|
+
# +------------------+------------------+
|
|
63
58
|
|
|
64
|
-
#
|
|
65
|
-
|
|
59
|
+
# === セッション1: Conductor ===
|
|
60
|
+
echo "Creating conductor session..."
|
|
61
|
+
tmux new-session -d -s "$SESSION_CONDUCTOR" -n "main" -c "$PROJECT_DIR"
|
|
66
62
|
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
echo " Dispatch pane: $DISPATCH_PANE"
|
|
63
|
+
# conductorペインのIDを取得
|
|
64
|
+
CONDUCTOR_PANE=$(tmux list-panes -t "$SESSION_CONDUCTOR:main" -F '#{pane_id}')
|
|
65
|
+
echo " Conductor pane: $CONDUCTOR_PANE"
|
|
71
66
|
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
67
|
+
# 左右に分割(左60% : 右40%)- 右側はdashboard
|
|
68
|
+
# split-windowは新しいペインIDを返すので、それを直接キャプチャする
|
|
69
|
+
DASHBOARD_PANE=$(tmux split-window -h -t "$CONDUCTOR_PANE" -c "$PROJECT_DIR" -l 40% -P -F '#{pane_id}')
|
|
70
|
+
echo " Dashboard pane: $DASHBOARD_PANE"
|
|
76
71
|
|
|
77
|
-
# 4. 各ペインでコマンド起動(2回分割方式)
|
|
78
72
|
# conductor (--agent でエージェント定義をロード)
|
|
79
73
|
echo "Starting Conductor (Opus, no thinking)..."
|
|
80
74
|
tmux send-keys -t "$CONDUCTOR_PANE" \
|
|
@@ -82,9 +76,36 @@ tmux send-keys -t "$CONDUCTOR_PANE" \
|
|
|
82
76
|
sleep 1
|
|
83
77
|
tmux send-keys -t "$CONDUCTOR_PANE" Enter
|
|
84
78
|
|
|
79
|
+
# dashboard
|
|
80
|
+
echo "Starting Dashboard monitor (in conductor session)..."
|
|
81
|
+
tmux send-keys -t "$DASHBOARD_PANE" \
|
|
82
|
+
"watch -n 5 cat status/dashboard.md"
|
|
83
|
+
sleep 1
|
|
84
|
+
tmux send-keys -t "$DASHBOARD_PANE" Enter
|
|
85
|
+
|
|
86
|
+
# conductorペインを選択
|
|
87
|
+
tmux select-pane -t "$CONDUCTOR_PANE"
|
|
88
|
+
|
|
85
89
|
# フレンドリーファイア防止
|
|
86
90
|
sleep 3
|
|
87
91
|
|
|
92
|
+
# === セッション2: Workers ===
|
|
93
|
+
echo "Creating workers session..."
|
|
94
|
+
tmux new-session -d -s "$SESSION_WORKERS" -n "main" -c "$PROJECT_DIR"
|
|
95
|
+
|
|
96
|
+
# 最初のペインのIDを取得(これがdispatchになる)
|
|
97
|
+
DISPATCH_PANE=$(tmux list-panes -t "$SESSION_WORKERS:main" -F '#{pane_id}')
|
|
98
|
+
echo " Dispatch pane: $DISPATCH_PANE"
|
|
99
|
+
|
|
100
|
+
# 左右に分割(左60% : 右40%)- 右側はワーカー用
|
|
101
|
+
# split-windowは新しいペインIDを返すので、それを直接キャプチャする
|
|
102
|
+
WORKER_AREA_PANE=$(tmux split-window -h -t "$DISPATCH_PANE" -c "$PROJECT_DIR" -l 40% -P -F '#{pane_id}')
|
|
103
|
+
echo " Worker area pane: $WORKER_AREA_PANE"
|
|
104
|
+
|
|
105
|
+
# 現在の状態:
|
|
106
|
+
# DISPATCH_PANE: dispatch (左、フルハイト)
|
|
107
|
+
# WORKER_AREA_PANE: ワーカー用プレースホルダー (右、フルハイト)
|
|
108
|
+
|
|
88
109
|
# dispatch (--agent でエージェント定義をロード)
|
|
89
110
|
echo "Starting Dispatch (Sonnet)..."
|
|
90
111
|
tmux send-keys -t "$DISPATCH_PANE" \
|
|
@@ -95,23 +116,33 @@ tmux send-keys -t "$DISPATCH_PANE" Enter
|
|
|
95
116
|
# フレンドリーファイア防止
|
|
96
117
|
sleep 3
|
|
97
118
|
|
|
98
|
-
#
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
"watch -n 5 cat status/dashboard.md"
|
|
119
|
+
# 右側のプレースホルダーにメッセージ表示
|
|
120
|
+
tmux send-keys -t "$WORKER_AREA_PANE" \
|
|
121
|
+
"echo '=== Worker Area ===' && echo 'Run: ./scripts/pane-setup.sh [count]' && echo 'to add workers here.'"
|
|
102
122
|
sleep 1
|
|
103
|
-
tmux send-keys -t "$
|
|
123
|
+
tmux send-keys -t "$WORKER_AREA_PANE" Enter
|
|
104
124
|
|
|
105
|
-
#
|
|
106
|
-
tmux select-pane -t "$
|
|
125
|
+
# dispatchペインを選択
|
|
126
|
+
tmux select-pane -t "$DISPATCH_PANE"
|
|
107
127
|
|
|
108
128
|
# ペインIDをファイルに保存(他のスクリプトから参照可能に)
|
|
109
129
|
mkdir -p "$PROJECT_DIR/.ensemble"
|
|
110
130
|
cat > "$PROJECT_DIR/.ensemble/panes.env" << EOF
|
|
111
131
|
# Ensemble pane IDs (auto-generated)
|
|
132
|
+
# Session names
|
|
133
|
+
CONDUCTOR_SESSION=$SESSION_CONDUCTOR
|
|
134
|
+
WORKERS_SESSION=$SESSION_WORKERS
|
|
135
|
+
|
|
136
|
+
# Pane IDs (use these with tmux send-keys -t)
|
|
112
137
|
CONDUCTOR_PANE=$CONDUCTOR_PANE
|
|
113
138
|
DISPATCH_PANE=$DISPATCH_PANE
|
|
114
139
|
DASHBOARD_PANE=$DASHBOARD_PANE
|
|
140
|
+
WORKER_AREA_PANE=$WORKER_AREA_PANE
|
|
141
|
+
|
|
142
|
+
# Usage examples:
|
|
143
|
+
# source .ensemble/panes.env
|
|
144
|
+
# tmux send-keys -t "\$CONDUCTOR_PANE" 'message' Enter
|
|
145
|
+
# tmux send-keys -t "\$DISPATCH_PANE" 'message' Enter
|
|
115
146
|
EOF
|
|
116
147
|
|
|
117
148
|
echo ""
|
|
@@ -119,19 +150,27 @@ echo "=========================================="
|
|
|
119
150
|
echo " Ensemble launched successfully!"
|
|
120
151
|
echo "=========================================="
|
|
121
152
|
echo ""
|
|
122
|
-
echo "
|
|
123
|
-
echo "
|
|
124
|
-
echo "
|
|
125
|
-
echo "
|
|
126
|
-
echo "
|
|
127
|
-
echo "
|
|
128
|
-
echo "
|
|
153
|
+
echo "Two separate tmux sessions created!"
|
|
154
|
+
echo ""
|
|
155
|
+
echo "Session 1: $SESSION_CONDUCTOR"
|
|
156
|
+
echo " +------------------+------------------+"
|
|
157
|
+
echo " | Conductor | dashboard |"
|
|
158
|
+
echo " +------------------+------------------+"
|
|
159
|
+
echo ""
|
|
160
|
+
echo "Session 2: $SESSION_WORKERS"
|
|
161
|
+
echo " +------------------+------------------+"
|
|
162
|
+
echo " | dispatch | worker-area |"
|
|
163
|
+
echo " +------------------+------------------+"
|
|
129
164
|
echo ""
|
|
130
165
|
echo "Panes:"
|
|
131
|
-
echo " - $CONDUCTOR_PANE
|
|
132
|
-
echo " - $
|
|
133
|
-
echo " - $
|
|
166
|
+
echo " - $CONDUCTOR_PANE : Conductor (Opus, no thinking)"
|
|
167
|
+
echo " - $DASHBOARD_PANE : Dashboard monitor"
|
|
168
|
+
echo " - $DISPATCH_PANE : Dispatch (Sonnet)"
|
|
169
|
+
echo " - $WORKER_AREA_PANE : Worker area (placeholder)"
|
|
170
|
+
echo ""
|
|
171
|
+
echo "To view both simultaneously, open two terminal windows:"
|
|
172
|
+
echo " Terminal 1: tmux attach -t $SESSION_CONDUCTOR"
|
|
173
|
+
echo " Terminal 2: tmux attach -t $SESSION_WORKERS"
|
|
134
174
|
echo ""
|
|
135
175
|
echo "Add workers: ./scripts/pane-setup.sh [count]"
|
|
136
|
-
echo "To attach: tmux attach-session -t $SESSION"
|
|
137
176
|
echo ""
|
|
@@ -1,31 +1,44 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# scripts/pane-setup.sh
|
|
3
|
-
#
|
|
3
|
+
# ワーカーペインをensemble-workers:mainウィンドウの右側に追加する
|
|
4
4
|
# フレンドリーファイア防止のため3秒間隔で起動
|
|
5
5
|
#
|
|
6
6
|
# 注意: ペインIDを使用することで、ユーザーのtmux設定(pane-base-index等)に
|
|
7
7
|
# 依存せずに動作する
|
|
8
8
|
#
|
|
9
|
-
#
|
|
9
|
+
# 初期レイアウト (launch.sh後):
|
|
10
|
+
# Session: ensemble-workers, Window: main
|
|
11
|
+
# +------------------+------------------+
|
|
12
|
+
# | dispatch | worker-area |
|
|
13
|
+
# +------------------+------------------+
|
|
14
|
+
#
|
|
15
|
+
# Worker 1追加後:
|
|
16
|
+
# +------------------+------------------+
|
|
17
|
+
# | dispatch | worker-1 |
|
|
18
|
+
# +------------------+------------------+
|
|
19
|
+
#
|
|
20
|
+
# Worker 2追加後:
|
|
10
21
|
# +------------------+----------+
|
|
11
|
-
# |
|
|
12
|
-
# |
|
|
13
|
-
#
|
|
14
|
-
# | dispatch | |
|
|
22
|
+
# | | worker-1 |
|
|
23
|
+
# | dispatch +----------+
|
|
24
|
+
# | | worker-2 |
|
|
15
25
|
# +------------------+----------+
|
|
16
26
|
#
|
|
17
|
-
#
|
|
27
|
+
# Worker 4追加後:
|
|
18
28
|
# +------------------+----------+
|
|
19
|
-
# |
|
|
29
|
+
# | | worker-1 |
|
|
30
|
+
# | +----------+
|
|
31
|
+
# | dispatch | worker-2 |
|
|
32
|
+
# | +----------+
|
|
33
|
+
# | | worker-3 |
|
|
20
34
|
# | +----------+
|
|
21
|
-
#
|
|
22
|
-
# | dispatch +----------+
|
|
23
|
-
# | | dashboard|
|
|
35
|
+
# | | worker-4 |
|
|
24
36
|
# +------------------+----------+
|
|
25
37
|
|
|
26
38
|
set -euo pipefail
|
|
27
39
|
|
|
28
|
-
|
|
40
|
+
CONDUCTOR_SESSION="${CONDUCTOR_SESSION:-ensemble-conductor}"
|
|
41
|
+
WORKERS_SESSION="${WORKERS_SESSION:-ensemble-workers}"
|
|
29
42
|
PROJECT_DIR="${PROJECT_DIR:-$(pwd)}"
|
|
30
43
|
WORKER_COUNT="${1:-2}" # デフォルト2ワーカー
|
|
31
44
|
PANES_FILE="$PROJECT_DIR/.ensemble/panes.env"
|
|
@@ -44,35 +57,52 @@ else
|
|
|
44
57
|
exit 1
|
|
45
58
|
fi
|
|
46
59
|
|
|
47
|
-
echo "Adding $WORKER_COUNT worker panes..."
|
|
48
|
-
echo " Using dashboard pane: $DASHBOARD_PANE"
|
|
60
|
+
echo "Adding $WORKER_COUNT worker panes to ensemble-workers:main window..."
|
|
49
61
|
|
|
50
|
-
# mainウィンドウを選択
|
|
51
|
-
tmux select-window -t "$
|
|
62
|
+
# ensemble-workersセッションのmainウィンドウを選択
|
|
63
|
+
tmux select-window -t "$WORKERS_SESSION:main"
|
|
52
64
|
|
|
53
65
|
# ワーカーペインIDを格納する配列
|
|
54
66
|
declare -a WORKER_PANES=()
|
|
55
67
|
|
|
56
68
|
# 現在のペインID一覧を取得(後で新しいペインを特定するため)
|
|
57
69
|
get_all_pane_ids() {
|
|
58
|
-
tmux list-panes -t "$
|
|
70
|
+
tmux list-panes -t "$WORKERS_SESSION:main" -F '#{pane_id}'
|
|
59
71
|
}
|
|
60
72
|
|
|
73
|
+
# 最初のワーカーはWORKER_AREA_PANEを使用(プレースホルダーを置き換え)
|
|
74
|
+
if [ -n "${WORKER_AREA_PANE:-}" ]; then
|
|
75
|
+
FIRST_WORKER_PANE="$WORKER_AREA_PANE"
|
|
76
|
+
else
|
|
77
|
+
# WORKER_AREA_PANEがない場合は、右側のペインを探す(dispatchでないペイン)
|
|
78
|
+
FIRST_WORKER_PANE=$(tmux list-panes -t "$WORKERS_SESSION:main" -F '#{pane_id}' | \
|
|
79
|
+
grep -v "$DISPATCH_PANE" | head -1)
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
echo " First worker will use pane: $FIRST_WORKER_PANE"
|
|
83
|
+
|
|
61
84
|
for i in $(seq 1 "$WORKER_COUNT"); do
|
|
62
85
|
echo "Starting worker-$i..."
|
|
63
86
|
|
|
64
|
-
|
|
65
|
-
|
|
87
|
+
if [ "$i" -eq 1 ]; then
|
|
88
|
+
# 最初のワーカーはプレースホルダーペインを使用
|
|
89
|
+
NEW_PANE="$FIRST_WORKER_PANE"
|
|
90
|
+
else
|
|
91
|
+
# 2番目以降は右側のペインを分割
|
|
92
|
+
# 分割前のペインID一覧
|
|
93
|
+
BEFORE_PANES=$(get_all_pane_ids)
|
|
66
94
|
|
|
67
|
-
|
|
68
|
-
|
|
95
|
+
# 前のワーカーペインを下に分割
|
|
96
|
+
PREV_PANE="${WORKER_PANES[$((i - 2))]}"
|
|
97
|
+
tmux split-window -v -t "$PREV_PANE" -c "$PROJECT_DIR"
|
|
69
98
|
|
|
70
|
-
|
|
71
|
-
|
|
99
|
+
# フレンドリーファイア防止
|
|
100
|
+
sleep 2
|
|
72
101
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
102
|
+
# 分割後のペインID一覧から新しいペインを特定
|
|
103
|
+
AFTER_PANES=$(get_all_pane_ids)
|
|
104
|
+
NEW_PANE=$(comm -13 <(echo "$BEFORE_PANES" | sort) <(echo "$AFTER_PANES" | sort))
|
|
105
|
+
fi
|
|
76
106
|
|
|
77
107
|
echo " Worker-$i pane: $NEW_PANE"
|
|
78
108
|
WORKER_PANES+=("$NEW_PANE")
|
|
@@ -83,21 +113,32 @@ for i in $(seq 1 "$WORKER_COUNT"); do
|
|
|
83
113
|
"export WORKER_ID=$i && claude --agent worker --dangerously-skip-permissions"
|
|
84
114
|
sleep 1
|
|
85
115
|
tmux send-keys -t "$NEW_PANE" Enter
|
|
116
|
+
|
|
117
|
+
# フレンドリーファイア防止(最初以外)
|
|
118
|
+
if [ "$i" -lt "$WORKER_COUNT" ]; then
|
|
119
|
+
sleep 3
|
|
120
|
+
fi
|
|
86
121
|
done
|
|
87
122
|
|
|
88
123
|
# 全ワーカーのClaude起動完了を待つ(各ワーカー約10秒)
|
|
89
124
|
echo "Waiting for all workers to initialize..."
|
|
90
125
|
sleep $((WORKER_COUNT * 10))
|
|
91
126
|
|
|
92
|
-
# Conductor
|
|
127
|
+
# Conductorセッションのmainウィンドウに戻り、フォーカス
|
|
128
|
+
tmux select-window -t "$CONDUCTOR_SESSION:main"
|
|
93
129
|
tmux select-pane -t "$CONDUCTOR_PANE"
|
|
94
130
|
|
|
95
131
|
# panes.env を更新(ワーカーペインIDを追加)
|
|
96
132
|
{
|
|
97
133
|
echo "# Ensemble pane IDs (auto-generated)"
|
|
134
|
+
echo "# Session names"
|
|
135
|
+
echo "CONDUCTOR_SESSION=$CONDUCTOR_SESSION"
|
|
136
|
+
echo "WORKERS_SESSION=$WORKERS_SESSION"
|
|
137
|
+
echo ""
|
|
138
|
+
echo "# Pane IDs"
|
|
98
139
|
echo "CONDUCTOR_PANE=$CONDUCTOR_PANE"
|
|
99
140
|
echo "DISPATCH_PANE=$DISPATCH_PANE"
|
|
100
|
-
echo "
|
|
141
|
+
echo "WORKER_AREA_PANE=${WORKER_AREA_PANE:-}"
|
|
101
142
|
for idx in "${!WORKER_PANES[@]}"; do
|
|
102
143
|
echo "WORKER_$((idx + 1))_PANE=${WORKER_PANES[$idx]}"
|
|
103
144
|
done
|
|
@@ -107,5 +148,37 @@ tmux select-pane -t "$CONDUCTOR_PANE"
|
|
|
107
148
|
echo ""
|
|
108
149
|
echo "Worker panes added: $WORKER_COUNT workers (ready for tasks)"
|
|
109
150
|
echo ""
|
|
110
|
-
echo "
|
|
111
|
-
|
|
151
|
+
echo "Layout (ensemble-workers:main window):"
|
|
152
|
+
if [ "$WORKER_COUNT" -eq 1 ]; then
|
|
153
|
+
echo " +------------------+------------------+"
|
|
154
|
+
echo " | dispatch | worker-1 |"
|
|
155
|
+
echo " +------------------+------------------+"
|
|
156
|
+
elif [ "$WORKER_COUNT" -eq 2 ]; then
|
|
157
|
+
echo " +------------------+----------+"
|
|
158
|
+
echo " | | worker-1 |"
|
|
159
|
+
echo " | dispatch +----------+"
|
|
160
|
+
echo " | | worker-2 |"
|
|
161
|
+
echo " +------------------+----------+"
|
|
162
|
+
else
|
|
163
|
+
echo " +------------------+----------+"
|
|
164
|
+
echo " | | worker-1 |"
|
|
165
|
+
echo " | +----------+"
|
|
166
|
+
echo " | dispatch | worker-2 |"
|
|
167
|
+
echo " | +----------+"
|
|
168
|
+
if [ "$WORKER_COUNT" -ge 3 ]; then
|
|
169
|
+
echo " | | worker-3 |"
|
|
170
|
+
echo " | +----------+"
|
|
171
|
+
fi
|
|
172
|
+
if [ "$WORKER_COUNT" -ge 4 ]; then
|
|
173
|
+
echo " | | worker-4 |"
|
|
174
|
+
echo " +------------------+----------+"
|
|
175
|
+
else
|
|
176
|
+
echo " +------------------+----------+"
|
|
177
|
+
fi
|
|
178
|
+
fi
|
|
179
|
+
echo ""
|
|
180
|
+
echo "Current panes in ensemble-workers:main window:"
|
|
181
|
+
tmux list-panes -t "$WORKERS_SESSION:main" -F " #{pane_id}: #{pane_width}x#{pane_height}"
|
|
182
|
+
echo ""
|
|
183
|
+
echo "Switch to workers window: tmux attach -t $WORKERS_SESSION"
|
|
184
|
+
echo ""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ensemble-claude
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: AI Orchestration Tool for Claude Code - Multi-agent orchestration for complex development tasks
|
|
5
5
|
Project-URL: Homepage, https://github.com/ChikaKakazu/ensemble
|
|
6
6
|
Project-URL: Documentation, https://github.com/ChikaKakazu/ensemble#readme
|
|
@@ -87,10 +87,13 @@ pip install -e .
|
|
|
87
87
|
# 1. Initialize Ensemble in your project
|
|
88
88
|
ensemble init
|
|
89
89
|
|
|
90
|
-
# 2. Launch the tmux
|
|
90
|
+
# 2. Launch the tmux sessions (2 separate sessions)
|
|
91
91
|
ensemble launch
|
|
92
92
|
|
|
93
|
-
# 3.
|
|
93
|
+
# 3. Open another terminal to view workers session
|
|
94
|
+
tmux attach -t ensemble-workers
|
|
95
|
+
|
|
96
|
+
# 4. Run a task in the Conductor session
|
|
94
97
|
/go implement user authentication
|
|
95
98
|
|
|
96
99
|
# Light workflow (minimal cost)
|
|
@@ -103,8 +106,8 @@ ensemble launch
|
|
|
103
106
|
|---------|-------------|
|
|
104
107
|
| `ensemble init` | Initialize Ensemble in current project |
|
|
105
108
|
| `ensemble init --full` | Also copy agent/command definitions locally |
|
|
106
|
-
| `ensemble launch` | Start tmux
|
|
107
|
-
| `ensemble launch --no-attach` | Start
|
|
109
|
+
| `ensemble launch` | Start 2 tmux sessions (conductor + workers) |
|
|
110
|
+
| `ensemble launch --no-attach` | Start sessions without attaching |
|
|
108
111
|
| `ensemble --version` | Show version |
|
|
109
112
|
|
|
110
113
|
## Requirements
|